Interim commit - added basic AimTrainer logic but no time limit / scoring mechanism yet. Copied some of the Teleporter code from classic's MPB but don't need as much of the logic around available spawns

This commit is contained in:
loop 2025-10-12 15:04:51 +01:00
parent e9877b8104
commit 1e73ba4697
6 changed files with 989 additions and 2 deletions

View file

@ -0,0 +1,61 @@
datablock PlayerData(DermDummy) : LightMaleBiodermArmor {
canObserve = false;
groundImpactMinSpeed = 0.01;
minImpactSpeed = 5;
speedDamageScale = 0.004;
};
function resetDummyPosition(%this) {
%this.setTransform(%this.original_transform);
%this.setvelocity("0 0 0");
}
function DermDummy::damageObject(%data, %targetObject, %sourceObject, %position, %amount, %damageType) {
if (%sourceObject == 0) {
return;
}
echo("Damage object received: " @ %targetObject @ " from " @ %sourceObject);
cancel(%targetObject.resetter); // Avoid double resets
// 750 allows for the original splash damage to decay
// 500 results in a double reset because the dummy is hit by the original explosion twice
%targetObject.resetter = schedule(750, 0, "resetDummyPosition", %targetObject);
}
// function TSStatic::damageObject(%data, %targetObject, %sourceObject, %position, %amount, %damageType) {
// echo("Damage object received: " @ %targetObject.name);
// }
// function TSStatic::damage(%this, %sourceObject, %position, %amount, %damageType) {
// echo("wtf is this then: " @ %this @ " tgt " @ %sourceObject);
// }
function findAndReplacePlaceholders() {
// Replace placeholders in the aim training system
%trash = new SimSet();
for (%i = 0; %i < AimTrainLow.getCount(); %i += 1) {
if (AimTrainLow.getObject(%i).placeholder) {
%obj = AimTrainLow.getObject(%i);
echo("Replace : " @ %obj.getName());
%trans = %obj.getTransform();
%replace = new Player() {
datablock = "DermDummy";
};
AimTrainLow.add(%replace);
%replace.setName(%obj.getName());
%replace.setTransform(%trans);
%replace.original_transform = %trans;
%trash.add(%obj);
}
}
while (%trash.getCount() > 0) {
%obj = %trash.getObject(0);
%obj.delete();
}
%trash.delete();
}
// Don't replace placeholder entities in development mode
if ($DEVMODE == 0) {
findAndReplacePlaceholders();
}

View file

@ -0,0 +1,34 @@
// SkillSector game has a README.md, read that instead.
// author: loop
// date: 10/2025
// url: https://github.com/tribes2/SkillSector
// Allows you to modify AimTrain placeholder entities.
// Don't leave it on or AimTrain will be a bunch of statues that do nothing.
$DEVMODE = 1;
// thanks DarkTiger (you can prob list them all via datablockGroup.getCount(); and iterate them all and do echo %obj.getName();)
function dumpDatablockNames() {
for (%i = 0; %i < datablockgroup.getCount(); %i += 1) {
echo("Datablock " @ %i @ " named " @ datablockgroup.getObject(%i).getName());
}
}
// DEVMODE reload/test function
function ssrl() {
exec("scripts/SkillSectorGame.cs");
findAndReplacePlaceholders();
}
function dc() {
disconnect();
}
if ($DEVMODE) {
moveMap.bind(keyboard, "f5", disconnect);
}
// Load the various modes, datablocks and functions.
exec("scripts/SkillSectorTeleporter.cs");
exec("scripts/SkillSectorAimTrainer.cs");

View file

@ -0,0 +1,216 @@
// stolen from classic
datablock StaticShapeData(BankTeleporter): StaticShapeDamageProfile {
className = Station;
catagory = "Stations";
shapeFile = "station_teleport.dts";
maxDamage = 1.20;
destroyedLevel = 1.20;
disabledLevel = 0.84;
explosion = ShapeExplosion;
expDmgRadius = 10.0;
expDamage = 0.4;
expImpulse = 1500.0;
dynamicType = $TypeMasks::StationObjectType;
isShielded = true;
energyPerDamagePoint = 33;
maxEnergy = 250;
rechargeRate = 0.31;
humSound = StationVehicleHumSound;
// don't let these be damaged in Siege missions
noDamageInSiege = true;
cmdCategory = "Support";
cmdIcon = CMDVehicleStationIcon;
cmdMiniIconName = "commander/MiniIcons/com_vehicle_pad_inventory";
targetNameTag = 'MPB';
targetTypeTag = 'Teleport Station';
teleporter = 1;
};
//datablock ParticleData(mpbteleportparticle)
//datablock ParticleEmitterData(MPBTeleportEmitter)
function BankTeleporter::onCollision(%data, %obj, %collider) {
// Teleporters are generally one way in Skill Sector
// Teleporter entities are linked to 'spawn point' objects
if (%obj.disabled) {
messageClient(%collider.client, 'MsgStationDenied', '\c2Teleporter is recharging please stand by. ~wfx/powered/nexus_deny.wav');
return;
}
%collider.setVelocity("0 0 0");
%collider.disableMove = true;
%collider.startFade(1000, 0, true);
%collider.playAudio($ActivateThread, StationVehicleAcitvateSound);
%obj.disabled = 1;
%obj.setThreadDir($ActivateThread, 1);
%obj.playThread($ActivateThread, "activate");
%data.sparkEmitter(%obj);
%data.schedule(2000, "teleportout", %obj, %collider);
%data.schedule(4000, "teleportingDone", %obj, %collider);
}
// function BankTeleporter::onCollision(%data, %obj, %col)
// {
// if(%col.getDataBlock().className !$= "Armor" || %col.getState() $= "Dead" || %col.teleporting) {
// return;
// }
// if(isObject(%col)) {
// if(%obj.team == %col.client.team) {
// if(!%obj.isDisabled()) {
// if(%obj.isPowered()) {
// if(isObject(%obj.MPB) && %obj.MPB.fullyDeployed)
// {
// if(%obj.disabled == 0)
// {
// %col.lastWeapon = ( %col.getMountedImage($WeaponSlot) == 0 ) ? "" : %col.getMountedImage($WeaponSlot).item;
// %col.unmountImage($WeaponSlot);
// %pos = %obj.position;
// %col.setvelocity("0 0 0");
// %col.setMoveState(true);
// %rot = getWords(%col.getTransform(), 3, 6);
// %col.setTransform(getWord(%pos,0) @ " " @ getWord(%pos,1) @ " " @ getWord(%pos,2) + 0.6 @ " " @ %rot);
// %col.teleporting = 1;
// %col.startFade( 1000, 0, true );
// %col.playAudio($PlaySound, StationVehicleAcitvateSound);
// %obj.disabled = 1; // Disable the teleporter to more then one person at a time for a time.
// %obj.setThreadDir($ActivateThread, TRUE);
// %obj.playThread($ActivateThread, "activate");
// %data.sparkEmitter(%obj);
// %data.schedule(2000, "teleportout", %obj, %col);
// %data.schedule(4000, "teleportingDone", %obj, %col);
// }
// else
// messageClient(%col.client, 'MsgTeleportRecharging', '\c2Teleporter is recharging please stand by. ~wfx/powered/nexus_deny.wav');
// }
// else
// MessageClient(%col.client, "MsgNoMPB", 'MPB is not deployed.');
// }
// else
// messageClient(%col.client, 'MsgStationNoPower', '\c2Teleporter is not powered.');
// }
// else
// messageClient(%col.client, 'MsgStationDisabled', '\c2Teleporter is disabled.');
// }
// else
// messageClient(%col.client, 'MsgStationDenied', '\c2Access Denied -- Wrong team.~wfx/powered/station_denied.wav');
// }
// else
// return;
// }
function BankTeleporter::teleportOut(%data, %obj, %player) {
if(isObject(%obj.destination)) {
%player.setTransform(%obj.MPB.spawnPos[%index] @ " " @ getWords(%obj.MPB.getTransform(), 3, 6));
} else {
%player.teleporting = 0;
} else {
messageClient(%player.client, 'MsgTeleFailed', 'No Valid teleporting positions.');
%player.teleporting = 0;
}
%data.schedule(1000, "teleportIn", %player);
}
function BankTeleporter::teleportIn(%data, %player) {
%data.sparkEmitter(%player); // z0dd - ZOD, 4/24/02. teleport sparkles
%player.startFade(1000, 0, false );
%player.playAudio($PlaySound, StationVehicleDeactivateSound);
}
function BankTeleporter::reEnable(%data, %obj) {
%obj.disabled = 0;
}
function BankTeleporter::sparkEmitter(%data, %obj) {
if (isObject(%obj.teleportEmitter))
%obj.teleportEmitter.delete();
%obj.teleportEmitter = new ParticleEmissionDummy() {
position = %obj.position;
rotation = "1 0 0 0";
scale = "1 1 1";
dataBlock = defaultEmissionDummy;
emitter = "MPBTeleportEmitter";
velocity = "1";
};
MissionCleanup.add(%obj.teleportEmitter);
%obj.teleportEmitter.schedule(800, "delete");
if (isObject(%obj.teleEmitter))
%obj.teleEmitter.delete();
%obj.teleEmitter = new ParticleEmissionDummy() {
position = %obj.position;
rotation = "1 0 0 0";
scale = "1 1 1";
dataBlock = defaultEmissionDummy;
emitter = "FlyerJetEmitter";
velocity = "1";
};
MissionCleanup.add(%obj.teleEmitter);
%obj.teleEmitter.schedule(700, "delete");
}
function BankTeleporter::teleportingDone(%data, %obj, %player)
{
%player.setMoveState(false);
%player.teleporting = 0;
%player.station = "";
%data.reEnable(%obj);
if(%player.getMountedImage($WeaponSlot) == 0)
{
if(%player.inv[%player.lastWeapon])
%player.use(%player.lastWeapon);
else
%player.selectWeaponSlot( 0 );
}
}
//------------------------------------------------------------------------------------------
// Gets called from function MobileBaseVehicle::vehicleDeploy(%data, %obj, %player, %force).
// Passes this information to the MPBTeleporter::teleportOut function.
//------------------------------------------------------------------------------------------
function checkSpawnPos(%MPB, %radius)
{
for(%y = -1; %y < 1; %y += 0.25)
{
%xCount=0;
for(%x = -1; %x < 1; %x += 0.25)
{
$MPBSpawnPos[(%yCount * 8) + %xCount] = %x @ " " @ %y;
%xCount++;
}
%yCount++;
}
%count = -1;
for(%x = 0; %x < 64; %x++)
{
%pPos = getWords(%MPB.getTransform(), 0, 2);
%pPosX = getWord(%pPos, 0);
%pPosY = getWord(%pPos, 1);
%pPosZ = getWord(%pPos, 2);
%posX = %pPosX + ( getWord($MPBSpawnPos[%x],0) * %radius);
%posY = %pPosY + (getWord($MPBSpawnPos[%x],1) * %radius);
%terrHeight = getTerrainHeight(%posX @ " " @ %posY);
if(mAbs(%terrHeight - %pPosZ) < %radius )
{
%mask = $TypeMasks::VehicleObjectType | $TypeMasks::MoveableObjectType |
$TypeMasks::StaticShapeObjectType | $TypeMasks::StaticTSObjectType |
$TypeMasks::ForceFieldObjectType | $TypeMasks::ItemObjectType |
$TypeMasks::PlayerObjectType | $TypeMasks::TurretObjectType |
$TypeMasks::InteriorObjectType;
InitContainerRadiusSearch(%posX @ " " @ %posY @ " " @ %terrHeight, 2, %mask);
if(ContainerSearchNext() == 0)
%MPB.spawnPos[%count++] = %posX @ " " @ %posY @ " " @ %terrHeight;
}
}
%MPB.spawnPosCount = %count;
}