| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492 |
- //-----------------------------------------------------------------------------
- // Copyright (c) 2012 GarageGames, LLC
- //
- // Permission is hereby granted, free of charge, to any person obtaining a copy
- // of this software and associated documentation files (the "Software"), to
- // deal in the Software without restriction, including without limitation the
- // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- // sell copies of the Software, and to permit persons to whom the Software is
- // furnished to do so, subject to the following conditions:
- //
- // The above copyright notice and this permission notice shall be included in
- // all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- // IN THE SOFTWARE.
- //-----------------------------------------------------------------------------
- // Respawntime is the amount of time it takes for a static "auto-respawn"
- // turret to re-appear after it's been picked up. Any turret marked as "static"
- // is automaticlly respawned.
- $TurretShape::RespawnTime = 30 * 1000;
- // DestroyedFadeDelay is the how long a destroyed turret sticks around before it
- // fades out and is deleted.
- $TurretShape::DestroyedFadeDelay = 5 * 1000;
- // ----------------------------------------------------------------------------
- // TurretShapeData
- // ----------------------------------------------------------------------------
- function TurretShapeData::onAdd(%this, %obj)
- {
- %obj.setRechargeRate(%this.rechargeRate);
- %obj.setEnergyLevel(%this.MaxEnergy);
- %obj.setRepairRate(0);
- if (%obj.mountable || %obj.mountable $= "")
- %this.isMountable(%obj, true);
- else
- %this.isMountable(%obj, false);
- if (%this.nameTag !$= "")
- %obj.setShapeName(%this.nameTag);
- // Mount weapons
- for(%i = 0; %i < %this.numWeaponMountPoints; %i++)
- {
- // Handle inventory
- %obj.incInventory(%this.weapon[%i], 1);
- %obj.incInventory(%this.weaponAmmo[%i], %this.weaponAmmoAmount[%i]);
-
- // Mount the image
- %obj.mountImage(%this.weapon[%i].image, %i, %this.startLoaded);
- %obj.setImageGenericTrigger(%i, 0, false); // Used to indicate the turret is destroyed
- }
- if (%this.enterSequence !$= "")
- {
- %obj.entranceThread = 0;
- %obj.playThread(%obj.entranceThread, %this.enterSequence);
- %obj.pauseThread(%obj.entranceThread);
- }
- else
- {
- %obj.entranceThread = -1;
- }
- }
- function TurretShapeData::onRemove(%this, %obj)
- {
- //echo("\c4TurretShapeData::onRemove("@ %this.getName() @", "@ %obj.getClassName() @")");
- // if there are passengers/driver, kick them out
- for(%i = 0; %i < %this.numMountPoints; %i++)
- {
- if (%obj.getMountNodeObject(%i))
- {
- %passenger = %obj.getMountNodeObject(%i);
- %passenger.getDataBlock().doDismount(%passenger, true);
- }
- }
- }
- // This is on MissionGroup so it doesn't happen when the mission has ended
- function MissionGroup::respawnTurret(%this, %datablock, %className, %transform, %static, %respawn)
- {
- %turret = new (%className)()
- {
- datablock = %datablock;
- static = %static;
- respawn = %respawn;
- };
- %turret.setTransform(%transform);
- MissionGroup.add(%turret);
- return %turret;
- }
- // ----------------------------------------------------------------------------
- // TurretShapeData damage state
- // ----------------------------------------------------------------------------
- // This method is called by weapons fire
- function TurretShapeData::damage(%this, %turret, %sourceObject, %position, %damage, %damageType)
- {
- //echo("\TurretShapeData::damage(" @ %turret @ ", "@ %sourceObject @ ", " @ %position @ ", "@ %damage @ ", "@ %damageType @ ")");
- if (%turret.getState() $= "Dead")
- return;
- %turret.applyDamage(%damage);
- // Update the numerical Health HUD
- %mountedObject = %turret.getObjectMount();
- if (%mountedObject)
- %mountedObject.updateHealth();
- // Kill any occupants
- if (%turret.getState() $= "Dead")
- {
- for (%i = 0; %i < %this.numMountPoints; %i++)
- {
- %player = %turret.getMountNodeObject(%i);
- if (%player != 0)
- %player.killWithSource(%sourceObject, "InsideTurret");
- }
- }
- }
- function TurretShapeData::onDamage(%this, %obj, %delta)
- {
- // This method is invoked by the ShapeBase code whenever the
- // object's damage level changes.
- }
- function TurretShapeData::onDestroyed(%this, %obj, %lastState)
- {
- // This method is invoked by the ShapeBase code whenever the
- // object's damage state changes.
- // Fade out the destroyed object. Then schedule a return.
- %obj.startFade(1000, $TurretShape::DestroyedFadeDelay, true);
- %obj.schedule($TurretShape::DestroyedFadeDelay + 1000, "delete");
- if (%obj.doRespawn())
- {
- MissionGroup.schedule($TurretShape::RespawnTime, "respawnTurret", %this, %obj.getClassName(), %obj.getTransform(), true, true);
- }
- }
- function TurretShapeData::onDisabled(%this, %obj, %lastState)
- {
- // This method is invoked by the ShapeBase code whenever the
- // object's damage state changes.
- }
- function TurretShapeData::onEnabled(%this, %obj, %lastState)
- {
- // This method is invoked by the ShapeBase code whenever the
- // object's damage state changes.
- }
- // ----------------------------------------------------------------------------
- // TurretShapeData player mounting and dismounting
- // ----------------------------------------------------------------------------
- function TurretShapeData::isMountable(%this, %obj, %val)
- {
- %obj.mountable = %val;
- }
- function TurretShapeData::onMountObject(%this, %turret, %player, %node)
- {
- if (%turret.entranceThread >= 0)
- {
- %turret.setThreadDir(%turret.entranceThread, true);
- %turret.setThreadPosition(%turret.entranceThread, 0);
- %turret.playThread(%turret.entranceThread, "");
- }
- }
- function TurretShapeData::onUnmountObject(%this, %turret, %player)
- {
- if (%turret.entranceThread >= 0)
- {
- // Play the entrance thread backwards for an exit
- %turret.setThreadDir(%turret.entranceThread, false);
- %turret.setThreadPosition(%turret.entranceThread, 1);
- %turret.playThread(%turret.entranceThread, "");
- }
- }
- function TurretShapeData::mountPlayer(%this, %turret, %player)
- {
- //echo("\c4TurretShapeData::mountPlayer("@ %this.getName() @", "@ %turret @", "@ %player.client.nameBase @")");
- if (isObject(%turret) && %turret.getDamageState() !$= "Destroyed")
- {
- //%player.startFade(1000, 0, true);
- //%this.schedule(1000, "setMountTurret", %turret, %player);
- //%player.schedule(1500, "startFade", 1000, 0, false);
- %this.setMountTurret(%turret, %player);
- }
- }
- function TurretShapeData::setMountTurret(%this, %turret, %player)
- {
- //echo("\c4TurretShapeData::setMountTurret("@ %this.getName() @", "@ %turret @", "@ %player.client.nameBase @")");
- if (isObject(%turret) && %turret.getDamageState() !$= "Destroyed")
- {
- %node = %this.findEmptySeat(%turret, %player);
- if (%node >= 0)
- {
- //echo("\c4Mount Node: "@ %node);
- %turret.mountObject(%player, %node);
- //%player.playAudio(0, MountVehicleSound);
- %player.mVehicle = %turret;
- }
- }
- }
- function TurretShapeData::findEmptySeat(%this, %turret, %player)
- {
- //echo("\c4This turret has "@ %this.numMountPoints @" mount points.");
- for (%i = 0; %i < %this.numMountPoints; %i++)
- {
- %node = %turret.getMountNodeObject(%i);
- if (%node == 0)
- return %i;
- }
- return -1;
- }
- function TurretShapeData::switchSeats(%this, %turret, %player)
- {
- for (%i = 0; %i < %this.numMountPoints; %i++)
- {
- %node = %turret.getMountNodeObject(%i);
- if (%node == %player || %node > 0)
- continue;
- if (%node == 0)
- return %i;
- }
- return -1;
- }
- function TurretShapeData::onMount(%this, %turret, %player, %node)
- {
- //echo("\c4TurretShapeData::onMount("@ %this.getName() @", "@ %turret @", "@ %player.client.nameBase @")");
- %player.client.RefreshVehicleHud(%turret, %this.reticle, %this.zoomReticle);
- //%player.client.UpdateVehicleHealth(%turret);
- }
- function TurretShapeData::onUnmount(%this, %turret, %player, %node)
- {
- //echo("\c4TurretShapeData::onUnmount(" @ %this.getName() @ ", " @ %turret @ ", " @ %player.client.nameBase @ ")");
- %player.client.RefreshVehicleHud(0, "", "");
- }
- // ----------------------------------------------------------------------------
- // TurretShape damage
- // ----------------------------------------------------------------------------
- // This method is called by weapons fire
- function TurretShape::damage(%this, %sourceObject, %position, %damage, %damageType)
- {
- //echo("\TurretShape::damage(" @ %this @ ", "@ %sourceObject @ ", " @ %position @ ", "@ %damage @ ", "@ %damageType @ ")");
- %this.getDataBlock().damage(%this, %sourceObject, %position, %damage, %damageType);
- }
- // ----------------------------------------------------------------------------
- // TurretDamage
- // ----------------------------------------------------------------------------
- // Customized kill message for deaths caused by turrets
- function sendMsgClientKilled_TurretDamage( %msgType, %client, %sourceClient, %damLoc )
- {
- if ( %sourceClient $= "" ) // editor placed turret
- messageAll( %msgType, '%1 was shot down by a turret!', %client.playerName );
- else if ( %sourceClient == %client ) // own mine
- messageAll( %msgType, '%1 kill by his own turret!', %client.playerName );
- else // enemy placed mine
- messageAll( %msgType, '%1 was killed by a turret of %2!', %client.playerName, %sourceClient.playerName );
- }
- // ----------------------------------------------------------------------------
- // AITurretShapeData
- // ----------------------------------------------------------------------------
- function AITurretShapeData::onAdd(%this, %obj)
- {
- Parent::onAdd(%this, %obj);
- %obj.mountable = false;
- }
- // Player has thrown a deployable turret. This copies from ItemData::onThrow()
- function AITurretShapeData::onThrow(%this, %user, %amount)
- {
- // Remove the object from the inventory
- if (%amount $= "")
- %amount = 1;
- if (%this.maxInventory !$= "")
- if (%amount > %this.maxInventory)
- %amount = %this.maxInventory;
- if (!%amount)
- return 0;
- %user.decInventory(%this,%amount);
- // Construct the actual object in the world, and add it to
- // the mission group so it's cleaned up when the mission is
- // done. The turret's rotation matches the player's.
- %rot = %user.getEulerRotation();
- %obj = new AITurretShape()
- {
- datablock = %this;
- rotation = "0 0 1 " @ getWord(%rot, 2);
- count = 1;
- sourceObject = %user;
- client = %user.client;
- isAiControlled = true;
- };
- MissionGroup.add(%obj);
-
- // Let the turret know that we're a firend
- %obj.addToIgnoreList(%user);
- // We need to add this turret to a list on the client so that if we die,
- // the turret will still ignore our player.
- %client = %user.client;
- if (%client)
- {
- if (!%client.ownedTurrets)
- {
- %client.ownedTurrets = new SimSet();
- }
-
- // Go through the client's owned turret list. Make sure we're
- // a friend of every turret and every turret is a friend of ours.
- // Commence hugging!
- for (%i=0; %i<%client.ownedTurrets.getCount(); %i++)
- {
- %turret = %client.ownedTurrets.getObject(%i);
- %turret.addToIgnoreList(%obj);
- %obj.addToIgnoreList(%turret);
- }
-
- // Add ourselves to the client's owned list.
- %client.ownedTurrets.add(%obj);
- }
-
- return %obj;
- }
- function AITurretShapeData::onDestroyed(%this, %turret, %lastState)
- {
- // This method is invoked by the ShapeBase code whenever the
- // object's damage state changes.
- %turret.playAudio(0, TurretDestroyed);
- %turret.setAllGunsFiring(false);
- %turret.resetTarget();
- %turret.setTurretState( "Destroyed", true );
- // Set the weapons to destoryed
- for(%i = 0; %i < %this.numWeaponMountPoints; %i++)
- {
- %turret.setImageGenericTrigger(%i, 0, true);
- }
- Parent::onDestroyed(%this, %turret, %lastState);
- }
- function AITurretShapeData::OnScanning(%this, %turret)
- {
- //echo("AITurretShapeData::OnScanning: " SPC %this SPC %turret);
- %turret.startScanForTargets();
- %turret.playAudio(0, TurretScanningSound);
- }
- function AITurretShapeData::OnTarget(%this, %turret)
- {
- //echo("AITurretShapeData::OnTarget: " SPC %this SPC %turret);
- %turret.startTrackingTarget();
- %turret.playAudio(0, TargetAquiredSound);
- }
- function AITurretShapeData::OnNoTarget(%this, %turret)
- {
- //echo("AITurretShapeData::OnNoTarget: " SPC %this SPC %turret);
- %turret.setAllGunsFiring(false);
- %turret.recenterTurret();
- %turret.playAudio(0, TargetLostSound);
- }
- function AITurretShapeData::OnFiring(%this, %turret)
- {
- //echo("AITurretShapeData::OnFiring: " SPC %this SPC %turret);
- %turret.setAllGunsFiring(true);
- }
- function AITurretShapeData::OnThrown(%this, %turret)
- {
- //echo("AITurretShapeData::OnThrown: " SPC %this SPC %turret);
- %turret.playAudio(0, TurretThrown);
- }
- function AITurretShapeData::OnDeploy(%this, %turret)
- {
- //echo("AITurretShapeData::OnDeploy: " SPC %this SPC %turret);
- // Set the weapons to loaded
- for(%i = 0; %i < %this.numWeaponMountPoints; %i++)
- {
- %turret.setImageLoaded(%i, true);
- }
-
- %turret.playAudio(0, TurretActivatedSound);
- }
- // ----------------------------------------------------------------------------
- // Player deployable turret
- // ----------------------------------------------------------------------------
- // Cannot use the Weapon class for deployable turrets as it is already tied
- // to ItemData.
- function DeployableTurretWeapon::onUse(%this, %obj)
- {
- Weapon::onUse(%this, %obj);
- }
- function DeployableTurretWeapon::onPickup(%this, %obj, %shape, %amount)
- {
- Weapon::onPickup(%this, %obj, %shape, %amount);
- }
- function DeployableTurretWeapon::onInventory(%this, %obj, %amount)
- {
- if (%obj.client !$= "" && !%obj.isAiControlled)
- {
- %obj.client.setAmmoAmountHud( 1, %amount );
- }
- // Cycle weapons if we are out of ammo
- if ( !%amount && ( %slot = %obj.getMountSlot( %this.image ) ) != -1 )
- %obj.cycleWeapon( "prev" );
- }
- function DeployableTurretWeaponImage::onMount(%this, %obj, %slot)
- {
- // The turret doesn't use ammo from a player's perspective.
- %obj.setImageAmmo(%slot, true);
- %numTurrets = %obj.getInventory(%this.item);
-
- if (%obj.client !$= "" && !%obj.isAiControlled)
- %obj.client.RefreshWeaponHud( 1, %this.item.previewImage, %this.item.reticle, %this.item.zoomReticle, %numTurrets);
- }
- function DeployableTurretWeaponImage::onUnmount(%this, %obj, %slot)
- {
- if (%obj.client !$= "" && !%obj.isAiControlled)
- %obj.client.RefreshWeaponHud(0, "", "");
- }
- function DeployableTurretWeaponImage::onFire(%this, %obj, %slot)
- {
- //echo("\DeployableTurretWeaponImage::onFire( "@%this.getName()@", "@%obj.client.nameBase@", "@%slot@" )");
- // To fire a deployable turret is to throw it. Schedule the throw
- // so that it doesn't happen during this ShapeBaseImageData's state machine.
- // If we throw the last one then we end up unmounting while the state machine
- // is still being processed.
- %obj.schedule(0, "throw", %this.item);
- }
|