etqw-sdk/base/script/vehicles/mcp.script

1204 lines
30 KiB
Plaintext

object vehicle_mcp : vehicle_base {
void preinit();
void init();
void destroy();
void syncFields();
void Idle();
void OnCollision( object traceObject, float velocity, vector mins, vector maxs );
void OnUpdateHud( entity p, float guiHandle );
void OnKilled( entity inflictor, entity attacker, float damage, vector dir, float location );
void OnRouteMaskWarningTimeout( vector newLocation, vector angles );
void OnUsed( entity user );
float OnActivate( entity p, float distance );
void vOnDeploy();
void vSetGoalMarker( entity _goalMarker );
void vSetPathTargets( vector startPos, vector endPos );
void vSetManualDeploy() { setTakesDamage( false ); }
void vCreateMission();
void vFreeMission();
void vCompleteMission();
entity GetDeployZone();
void DeployThread( entity deployer );
void CheckAutoDeploy( entity deployer );
boolean CanDeploy( entity p, boolean checkSpeed );
boolean CheckCriticalDamage( float healthPercent );
void OnPlayerEntered( entity p, float position );
void OnPlayerExited( entity p, float position );
void UpdateHealth( float oldHealth, float newHealth );
void vStartBoundsKillThread();
void BoundsKillThread();
void StopBoundsKillThread();
void DeployKillThread();
void PostSpawnSetup();
void OnPostMapSpawn();
void SetupCommandMapRadarIcon();
void InitRadarValues();
void FreeRadarValues();
void Deploy( entity deployer );
void OnDeployedChanged();
void OnDeliveredChanged();
void OnCanMoveChanged();
void SpinDish();
void OnWeaponSelected( entity p, float index );
float OnUpdateCrosshairInfo( entity p );
void CheckDeployToolip();
boolean vTargetLockDisabled();
boolean vFireScud( entity firer, entity target );
vector CalcFiringVelocity( vector targetPos, vector launchPos, float targetHeight );
void OnIsPrimaryObjectiveChanged();
void SetObjectiveIndicator();
void ClearObjectiveIndicator();
void UpdateObjectiveProgress();
void UpdateObjectiveThread();
void vMakePrimaryObjective( boolean value );
void SetObjectiveReminderTime( float time );
void vSetOwner( entity o );
void InitGoalTask();
void FreeGoalTask();
vector GetMissilePos();
void OnFireCountChanged();
float GetActivateCode( entity p, float distance );
boolean vCheckActionCode( entity p, float actionCode );
void DestructionVOThread();
string vGetObjectiveString() { return "mcpObjective"; }
float deployMask;
float deployThread;
boolean canMove;
boolean immobilized;
boolean isDeployed;
boolean delivered;
boolean vIsDeployed() { return isDeployed; }
boolean vIsPrimaryObjective() { return !isDeployed; }
void vOnContextDefend( entity p );
void vOnContextDestroy( entity p );
void SetupObjectiveIcon();
void FreeObjectiveIcon();
void FlashIconForTeam( entity team );
entity vGetSpectateEntity();
boolean vIsObjectiveComplete();
task missionTask;
float deployProficiency;
float commandMapRadarHandle;
float healthStartMoving;
float healthStopMoving;
float damagedToolTip;
float becameDeployableTime;
float canDeployToolTip;
float tooltipDamagedDriving;
float tooltipDamagedRepairing;
entity driver;
entity lastDriver;
float objectiveDistance;
vector objectiveLocation;
boolean isPrimaryObjective;
entity owner;
float nextObjectiveReminderTime;
entity goalMarker;
task goalTask;
task goalDefendTask;
float fireCount;
float destructionVOThread;
flashpoint_obj flashpoint;
float cmObjectiveIcon;
float cmObjectiveIconStrogg;
}
void vehicle_mcp::syncFields() {
syncBroadcast( "objectiveDistance" );
syncBroadcast( "objectiveLocation" );
syncBroadcast( "isDeployed" );
syncCallback( "isDeployed", "OnDeployedChanged" );
syncBroadcast( "delivered" );
syncCallback( "delivered", "OnDeliveredChanged" );
syncBroadcast( "canMove" );
syncBroadcast( "immobilized" );
syncCallback( "canMove", "OnCanMoveChanged" );
syncCallback( "immobilized", "OnCanMoveChanged" );
syncBroadcast( "fireCount" );
syncCallback( "fireCount", "OnFireCountChanged" );
}
void vehicle_mcp::preinit() {
preventDeployment( 1.f );
disableKnockback();
normallyHaveKnockback = false;
deployMask = sys.getDeployMask( getKey( "mask_deployment" ) );
commandMapRadarHandle = -1;
deployThread = -1;
deployProficiency = GetProficiency( getKey( "prof_deploy" ) );
healthStartMoving = getFloatKey( "health_start_moving" ) / 100;
healthStopMoving = getFloatKey( "health_stop_moving" ) / 100;
damagedToolTip = GetToolTip( getKey( "tt_damaged" ) );
canMove = true;
canDeployToolTip = GetToolTip( getKey( "tt_can_deploy" ) );
tooltipDamagedDriving = GetToolTip( getKey( "tt_damaged_driver" ) );
tooltipDamagedRepairing = GetToolTip( getKey( "tt_repaired_driver" ) );
setContents( CONTENTS_TRIGGER );
setGameTeam( sys.getTeam( getKey( "team" ) ) );
destructionVOThread = -1;
cmObjectiveIcon = -1;
cmObjectiveIconStrogg = -1;
}
void vehicle_mcp::PostSpawnSetup() {
sys.wait( 0.5f );
objManager.OnMCPSpawned( self );
}
void vehicle_mcp::OnPostMapSpawn() {
disablePart( "launcher_up" );
thread PostSpawnSetup();
}
void vehicle_mcp::vSetGoalMarker( entity _goalMarker ) {
goalMarker = _goalMarker;
}
void vehicle_mcp::vSetPathTargets( vector startPos, vector endPos ) {
objectiveLocation = endPos;
objectiveDistance = sys.vecLength( startPos - endPos );
}
void vehicle_mcp::vSetOwner( entity o ) {
owner = o;
}
void vehicle_mcp::InitGoalTask() {
if ( sys.isClient() ) {
return;
}
sys.assert( goalMarker != $null_entity );
if ( goalTask == $null ) {
float taskHandle = GetPlayerTask( getKey( "task_goal" ) );
if ( taskHandle != -1 ) {
goalTask = taskManager.allocEntityTask( taskHandle, goalMarker );
}
}
if ( goalDefendTask == $null ) {
float taskDefendHandle = GetPlayerTask( getKey( "task_goal_defend" ) );
if ( taskDefendHandle != -1 ) {
goalDefendTask = taskManager.allocEntityTask( taskDefendHandle, goalMarker );
}
}
}
void vehicle_mcp::FreeGoalTask() {
if ( goalTask != $null ) {
goalTask.free();
goalTask = $null;
}
if ( goalDefendTask != $null ) {
goalDefendTask.free();
goalDefendTask = $null;
}
}
void vehicle_mcp::OnIsPrimaryObjectiveChanged() {
ClearObjectiveIndicator();
if ( isPrimaryObjective ) {
SetObjectiveIndicator();
}
}
void vehicle_mcp::ClearObjectiveIndicator() {
sys.killThread( "UpdateObjectiveThread_" + getName() );
if ( sys.doClientSideStuff() ) {
sys.setGUIFloat( GUI_GLOBALS_HANDLE, "mcpObjective.active", 0.f );
}
}
void vehicle_mcp::SetObjectiveIndicator() {
UpdateObjectiveProgress();
thread UpdateObjectiveThread();
if ( sys.doClientSideStuff() ) {
sys.setGUIFloat( GUI_GLOBALS_HANDLE, "mcpObjective.active", 1.f );
sys.setGUIFloat( GUI_GLOBALS_HANDLE, "mcpObjective.disabled", 0.f );
sys.setGUIFloat( GUI_GLOBALS_HANDLE, "mcpObjective.progress", 0.f );
sys.setGUIFloat( GUI_GLOBALS_HANDLE, "mcpObjective.health", 1.0f );
}
}
void vehicle_mcp::vMakePrimaryObjective( boolean value ) {
isPrimaryObjective = value;
OnIsPrimaryObjectiveChanged();
}
void vehicle_mcp::SetObjectiveReminderTime( float time ) {
if ( time > nextObjectiveReminderTime ) {
nextObjectiveReminderTime = time;
}
}
void vehicle_mcp::UpdateHealth( float oldHealth, float newHealth ) {
VehicleBase_UpdateHealth( oldHealth, newHealth );
CheckCriticalDamage( newHealth );
if ( newHealth < 0 ) {
setHealth( 0 );
}
}
void vehicle_mcp::UpdateObjectiveThread() {
waitUntil( objManager.gameState == GS_GAMEON );
SetObjectiveReminderTime( sys.getTime() + OBJECTIVEMESSAGE_WAIT_TIME );
while ( true ) {
UpdateObjectiveProgress();
if ( !sys.isClient() ) {
if ( sys.getTime() >= nextObjectiveReminderTime ) {
if ( objManager.gameState == GS_GAMEON ) {
if ( !canMove ) {
objManager.PlaySound( gdfTeam.getKey( "snd_mcp_disabled" ), gdfTeam );
objManager.PlaySound( stroggTeam.getKey( "snd_mcp_disabled" ), stroggTeam );
} else {
if ( owner != $null_entity ) {
objManager.PlaySound( owner.getKey( "snd_reminder_strogg" ), stroggTeam );
objManager.PlaySound( owner.getKey( "snd_reminder_gdf" ), gdfTeam );
}
}
}
SetObjectiveReminderTime( sys.getTime() + OBJECTIVEMESSAGE_WAIT_TIME );
}
}
sys.waitFrame();
}
}
void vehicle_mcp::UpdateObjectiveProgress() {
if ( sys.doClientSideStuff() ) {
float a = getHealth() / getMaxHealth();
sys.setGUIFloat( GUI_GLOBALS_HANDLE, "mcpObjective.health", a );
float scale;
if ( objectiveDistance != 0.f ) {
scale = sys.vecLength( getWorldOrigin() - objectiveLocation ) / objectiveDistance;
if ( scale > 1.f ) {
scale = 1.f;
}
} else {
scale = 1.f;
}
boolean disabled = !canMove || isEMPed();
sys.setGUIFloat( GUI_GLOBALS_HANDLE, "mcpObjective.progress", 1.f - scale );
sys.setGUIFloat( GUI_GLOBALS_HANDLE, "mcpObjective.disabled", disabled );
}
}
void vehicle_mcp::InitRadarValues() {
FreeRadarValues();
float radarLayer = allocRadarLayer();
radarSetLayerRange( radarLayer, getFloatKey( "radar_range" ) );
radarSetLayerMask( radarLayer, getFloatKey( "mask" ) );
SetupCommandMapRadarIcon();
}
void vehicle_mcp::FreeRadarValues() {
freeLayers();
if ( commandMapRadarHandle != -1 ) {
sys.freeCMIcon( self, commandMapRadarHandle );
commandMapRadarHandle = -1;
}
}
void vehicle_mcp::SetupCommandMapRadarIcon() {
commandMapRadarHandle = sys.allocCMIcon( self, 100 );
sys.setCMIconSizeMode( commandMapRadarHandle, SM_WORLD );
//sys.setCMIconColor( commandMapRadarHandle, g_colorWhite, 0.25f );
//sys.setCMIconSides( commandMapRadarHandle, 24 );
//sys.setCMIconDrawMode( commandMapRadarHandle, DM_CIRCLE );
sys.setCMIconMaterial( commandMapRadarHandle, GetMaterial( getKey( "mtr_radar" ) ) );
sys.setCMIconUnknownMaterial( commandMapRadarHandle, GetMaterial( getKey( "mtr_radar" ) ) );
sys.setCMIconSize( commandMapRadarHandle, getFloatKey( "radar_range" ) );
sys.setCMIconUnknownSize( commandMapRadarHandle, getFloatKey( "radar_range" ) );
sys.setCMIconFlag( commandMapRadarHandle, CMF_TEAMONLY );
}
void vehicle_mcp::OnDeployedChanged() {
if ( isDeployed ) {
Deploy( $null_entity );
}
}
void vehicle_mcp::OnDeliveredChanged() {
if ( delivered ) {
vOnDeploy();
}
}
void vehicle_mcp::Deploy( entity deployer ) {
disableImpact();
kickPlayer( 0, 0 );
lock( 1.f );
freeze( 1.f );
disableSuspension( 1.f );
setTakesDamage( false );
playAnim( ANIMCHANNEL_ALL, "deploy" );
isDeployed = true;
// TODO: radius damage
disablePart( "launcher_down" );
enablePart( "launcher_up" );
if ( !sys.isClient() ) {
CheckAutoDeploy( deployer );
}
FreeObjectiveIcon();
thread SpinDish();
thread DeployKillThread();
}
void vehicle_mcp::init() {
setLightsEnabled( 0, false );
disableTimeout( 1.f );
setState( "Idle" );
}
void vehicle_mcp::destroy() {
vFreeMission();
FreeRadarValues();
FreeObjectiveIcon();
ClearObjectiveIndicator();
if ( flashpoint != $null ) {
delete flashpoint;
}
}
boolean vehicle_mcp::CanDeploy( entity p, boolean checkSpeed ) {
if ( objManager.gameState != GS_GAMEON ) {
return false;
}
float allowDeploy;
float absSpeedKPH;
vector up;
allowDeploy = sys.checkDeployMask( getAbsMins(), getAbsMaxs(), deployMask );
if ( allowDeploy != 1.f ) {
return false;
}
if ( !canMove ) {
return false;
}
if ( checkSpeed ) {
absSpeedKPH = sys.fabs( UPStoKPH( getLinearVelocity() * getWorldAxis( 0 ) ) );
if( absSpeedKPH > 2.f ) {
return false;
}
}
up = getWorldAxis( 2 );
if ( up_z < 0.985f ) {
return false;
}
if ( isDeployed ) {
return false;
}
if ( p != $null_entity ) {
if ( getEntityAllegiance( p ) != TA_FRIEND ) {
return false;
}
}
entity dz = GetDeployZone();
if ( dz == $null_entity ) {
return false;
}
if ( dz.getGameTeam() == getGameTeam() ) {
return false;
}
if ( !hasGroundContacts() ) {
return false;
}
return true;
}
entity vehicle_mcp::GetDeployZone() {
return sys.getTerritoryForPoint( getWorldOrigin(), $null_entity, 0, 0 );
}
void vehicle_mcp::DeployThread( entity deployer ) {
sys.wait( 3.f );
entity dz = GetDeployZone();
if ( dz != $null_entity ) {
if ( getGameTeam() != dz.getGameTeam() ) {
if ( deployProficiency != -1 ) {
deployer.giveProficiency( deployProficiency, 1.f, missionTask, "deploying mcp" );
}
sys.increaseStatInt( sys.allocStatInt( "total_objectives_completed" ), deployer.getEntityNumber(), 1 );
dz.vOnCaptured( deployer );
}
}
deployThread = -1;
}
void vehicle_mcp::CheckAutoDeploy( entity deployer ) {
if ( deployThread != -1 ) {
return;
}
deployThread = thread DeployThread( deployer );
}
void vehicle_mcp::Idle() {
float enterDeployZoneTime = -1.0f;
while( true ) {
sys.waitFrame();
CheckDeployToolip();
driver = getDriver();
if ( driver != $null_entity ) {
lastDriver = driver;
}
if ( destructionTime() != 0.0f ) {
if ( destructionVOThread == -1 ) {
if ( sys.doClientSideStuff() ) {
destructionVOThread = thread DestructionVOThread();
}
}
} else if ( destructionVOThread != -1 ) {
sys.terminate( destructionVOThread );
destructionVOThread = -1;
}
// check if it should auto-deploy
if ( !sys.isClient() && !isDeployed ) {
if ( driver != $null_entity ) {
if ( CanDeploy( driver, false ) ) {
float time = sys.getTime();
if ( enterDeployZoneTime < 0.0f ) {
enterDeployZoneTime = time;
}
if ( time - enterDeployZoneTime > 0.5f ) {
Deploy( driver );
}
} else {
enterDeployZoneTime = -1.0f;
}
} else {
enterDeployZoneTime = -1.0f;
}
}
}
}
void vehicle_mcp::OnCollision( object traceObject, float velocity, vector mins, vector maxs ) {
OnCollision_Base( traceObject, velocity, mins, maxs );
}
void vehicle_mcp::OnUpdateHud( entity p, float guiHandle ) {
entity driver = getDriver();
if ( driver == $null_entity ) {
return;
}
sys.setGUIFloat( GUI_GLOBALS_HANDLE, "mcpObjective.canDeploy", CanDeploy( driver, false ) );
}
void vehicle_mcp::SpinDish() {
float rotJoint = getJointHandle( "joint7" );
vector rotation;
sys.wait( 16.6f );
while( true ) {
sys.waitFrame();
if ( canMove ) {
rotation_z -= 180.0F * sys.getFrameTime();
setJointAngle( rotJoint, JOINTMOD_LOCAL, rotation );
}
}
}
boolean vehicle_mcp::CheckCriticalDamage( float healthPercent ) {
boolean oldCanMove = canMove;
if ( healthPercent <= healthStopMoving ) {
if ( canMove ) {
if ( driver != $null_entity ) {
driver.sendToolTip( tooltipDamagedDriving );
}
canMove = false;
}
} else if ( healthPercent >= healthStartMoving ) {
if ( !canMove ) {
if ( driver != $null_entity ) {
driver.sendToolTip( tooltipDamagedRepairing );
}
canMove = true;
}
}
if ( canMove != oldCanMove ) {
setWeaponDisabled( oldCanMove );
OnCanMoveChanged();
if ( canMove ) {
objManager.PlaySound( gdfTeam.getKey( "snd_mcp_repaired" ), gdfTeam );
objManager.PlaySound( stroggTeam.getKey( "snd_mcp_repaired" ), stroggTeam );
} else {
objManager.PlaySound( gdfTeam.getKey( "snd_mcp_disabled" ), gdfTeam );
objManager.PlaySound( stroggTeam.getKey( "snd_mcp_disabled" ), stroggTeam );
}
SetObjectiveReminderTime( sys.getTime() + OBJECTIVEMESSAGE_WAIT_TIME );
}
return canMove != oldCanMove;
}
void vehicle_mcp::OnPlayerEntered( entity p, float position ) {
OnPlayerEntered_Base( p, position );
// overwrite the default enter tooltip
if( !canMove ) {
p.sendToolTip( damagedToolTip );
}
float i;
entity ent;
if ( p == getDriver() ) {
entitiesOfCollection( "mcp_marker" );
float count = filterEntitiesByAllegiance( TA_FLAG_FRIEND, 1 );
for ( i = 0; i < count; i++ ) {
if ( !isDeployed ) {
ent = getBoundsCacheEntity( i );
ent.vOnShowOverlay( p );
}
}
if ( p == sys.getLocalViewPlayer() ) {
if ( position == 0 ) {
sys.setGUIFloat( GUI_GLOBALS_HANDLE, "vehicles.drivingMCP", 1 );
} else {
sys.setGUIFloat( GUI_GLOBALS_HANDLE, "vehicles.drivingMCP", 0 );
}
}
}
}
void vehicle_mcp::OnPlayerExited( entity p, float position ) {
if ( p == sys.getLocalViewPlayer() ) {
StopDecoyChargeThread();
sys.setGUIFloat( GUI_GLOBALS_HANDLE, "weapons.cooling", 0 );
sys.setGUIFloat( GUI_GLOBALS_HANDLE, "weapons.energySegments", 1 );
sys.setGUIFloat( GUI_GLOBALS_HANDLE, "gameHud.decoyChargeFraction", 1 );
sys.startSoundDirect( "", SND_VEHICLE_INTERIOR_LOWHEALTH );
playingKlaxon = false;
}
vCheckProficiency();
if ( p == sys.getLocalPlayer() ) {
CheckFireTeamInfo( true );
} else {
CheckFireTeamInfo( false );
}
float i;
entity ent;
entitiesOfCollection( "mcp_marker" );
float count = filterEntitiesByAllegiance( TA_FLAG_FRIEND, 1 );
for ( i = 0; i < count; i++ ) {
ent = getBoundsCacheEntity( i );
ent.vOnHideOverlay( p, self );
}
if ( p.isLocalPlayer() ) {
sys.setGUIFloat( GUI_GLOBALS_HANDLE, "vehicles.drivingMCP", 0 );
}
}
void vehicle_mcp::CheckDeployToolip() {
float success = CanDeploy( $null_entity, false );
if ( success ) {
if ( becameDeployableTime == 0 ) {
becameDeployableTime = sys.getTime();
}
} else {
becameDeployableTime = 0;
}
if ( becameDeployableTime != 0 && ( sys.getTime() - becameDeployableTime ) > 1.5f ) {
entity d = getDriver();
d.sendToolTip( canDeployToolTip );
}
}
boolean vehicle_mcp::vTargetLockDisabled() {
return !canMove || isBound();
}
void vehicle_mcp::OnKilled( entity inflictor, entity attacker, float damage, vector dir, float location ) {
// mcp is invincible, so don't do anything
// kickPlayer( -1, EF_KILL_PLAYERS );
}
void vehicle_mcp::OnUsed( entity user ) {
entity team = user.getGameTeam();
if ( team == $null_entity ) {
return;
}
if ( getEntityAllegiance( user ) != TA_ENEMY && user.getHealth() > 0 ) {
if ( isPlayerBanned( user ) ) {
float toolTipIndex = GetToolTip( getKey( "tt_player_banned" ) );
sys.broadcastToolTip( toolTipIndex, user, wstr_empty, wstr_empty, wstr_empty, wstr_empty );
return;
}
user.enter( self );
return;
}
}
float vehicle_mcp::OnUpdateCrosshairInfo( entity p ) {
if ( !sys.doClientSideStuff() ) {
return 1.f;
}
float allegiance = getEntityAllegiance( p );
vector color = GetAllegianceColor( allegiance );
float distance = chGetDistance();
float range = InchesToMetres( distance );
float health = getHealth();
vector immobilizedColor;
if ( allegiance == TA_ENEMY || allegiance == TA_FRIEND ) {
immobilizedColor = '1 1 0';
} else {
immobilizedColor = color;
}
float index;
chSetNumLines( 0 );
if ( p != $null_entity ) {
// see if theres a valid action to perform
float code = GetActivateCode( p, distance );
if ( code != AK_NONE && p.vHasActionItem( code ) ) {
index = chAddLine();
chSetLineMaterial( index, p.vGetActionIcon( code ) );
chSetLineType( index, CI_IMAGE );
chSetLineSize( index, 64, 64 );
chSetLineColor( index, g_colorWhite, 0.9f );
}
}
index = chAddLine();
if( canMove && !isEMPed() ) {
chSetLineTextIndex( index, crosshairName );
} else {
chSetLineTextIndex( index, sys.localizeString( "game/vec/mcp_immob" ) );
}
chSetLineColor( index, color, 1.f );
chSetLineType( index, CI_TEXT );
chSetLineSize( index, 0, 0 );
if ( !isDeployed ) {
index = chAddLine();
if( canMove && !isEMPed() ) {
chSetLineColor( index, color, 0.5f );
} else {
chSetLineColor( index, immobilizedColor, 0.5f );
}
chSetLineType( index, CI_BAR );
chSetLineFraction( index, health / getMaxHealth() );
chSetLineSize( index, 150, CROSSHAIR_INFO_BAR_HEIGHT );
}
if( range <= 100 ) {
if( getNumOccupiedPositions() > 0 ) {
index = chAddLine();
chSetLineText( index, getPassengerNames() );
chSetLineColor( index, color, 1.f );
chSetLineType( index, CI_TEXT );
chSetLineSize( index, 0, 0 );
}
index = chAddLine();
chSetLineText( index, G_BuildRangeStr( range ) );
chSetLineColor( index, color, 1.f );
chSetLineType( index, CI_TEXT );
chSetLineSize( index, 0, 0 );
}
return 1.f;
}
float vehicle_mcp::OnActivate( entity p, float distance ) {
if( !sys.isClient() ) {
if ( p == getDriver() ) {
if ( CanDeploy( p, false ) ) {
Deploy( p );
return 1.f;
}
}
}
return VehicleBase_OnActivate( p, distance );
}
void vehicle_mcp::OnWeaponSelected( entity p, float index ) {
if ( index == 0 ) {
FireDecoy( p );
} else if ( index == 1 ) {
selectVehicleWeapon( p, "gpmg" );
} else if ( index == 2 ) {
selectVehicleWeapon( p, "gatlinggun" );
}
}
boolean vehicle_mcp::vFireScud( entity firer, entity target ) {
if ( !canMove || !isDeployed ) {
return false;
}
vector missilePos = GetMissilePos();
vector firingVelocity = CalcFiringVelocity( target.getWorldOrigin(), missilePos, 8000 );
if ( firingVelocity != g_vectorZero && !sys.isClient() ) {
float entityDeclIndex = sys.getDeclType( "entityDef" );
float projectileIndex = sys.getDeclIndex( entityDeclIndex, getKey( "def_scud" ) );
entity missile = launchMissileSimple( firer, self, $null_entity, projectileIndex, -1, 0.f, missilePos, firingVelocity );
missile.vSetNewTarget( target );
// need to overwrite the game team, as if the owner switches team this will mess up objectives etc
missile.setGameTeam( getGameTeam() );
fireCount = fireCount + 1;
OnFireCountChanged();
}
objManager.CPrintEvent( g_locStr_Scud, $null );
return true;
}
vector vehicle_mcp::CalcFiringVelocity( vector targetPos, vector launchPos, float targetHeight ) {
vector targetDiff = targetPos - launchPos;
vector firingVelocity;
firingVelocity_x = 0;
firingVelocity_y = 0;
firingVelocity_z = sys.sqrt( 2 * 400 * targetHeight );
float upTime = firingVelocity_z / 400;
float downTime = ( 2 * ( targetDiff_z - targetHeight ) ) / -400;
if ( downTime < 0.f ) {
return g_vectorZero;
}
downTime = sys.sqrt( downTime );
float t1 = upTime + downTime;
vector temp = targetDiff;
temp_z = 0.f;
targetDiff = sys.vecNormalize( temp );
float diffX = sys.vecLength( temp );
firingVelocity = firingVelocity + ( ( diffX / t1 ) * targetDiff );
return firingVelocity;
}
void vehicle_mcp::vApplyEmpDamage( entity attacker, float time, float weaponTime ) {
ApplyEmpDamage_Base( attacker, 5.0f, 2.0f );
}
void vehicle_mcp::OnRouteMaskWarningTimeout( vector newLocation, vector angles ) {
if ( !isDeployed ) {
objManager.OnMCPDestroyed( self, newLocation, angles );
clearLastAttacker();
OnKilledRemove( $null_entity, $null_entity, 0.f, '0 0 1', -1.f );
}
}
void vehicle_mcp::vOnDeploy() {
delivered = true;
setTakesDamage( true );
if ( !sys.isClient() ) {
objManager.OnMCPDelivered( self );
}
StopBoundsKillThread();
if ( !isDeployed ) {
SetupObjectiveIcon();
}
}
void vehicle_mcp::StopBoundsKillThread() {
sys.killThread( "BoundsKillThread_" + getName() );
}
void vehicle_mcp::vStartBoundsKillThread() {
thread BoundsKillThread();
}
void vehicle_mcp::BoundsKillThread() {
float damageIndex = GetDamage( getKey( "dmg_crush" ) );
vector mins = getMins();
vector maxs = getMaxs();
while ( true ) {
if ( hasGroundContacts() ) {
break;
}
LocalBoundsDamage( mins, maxs, self, self, damageIndex );
sys.waitFrame();
}
}
void vehicle_mcp::DeployKillThread() {
float damageIndex = GetDamage( getKey( "dmg_crush" ) );
vector startPoint = '-240 -8 160';
vector endPoint = '-55 -110 400';
while ( isAnimating() ) {
LocalBoundsDamage( startPoint, endPoint, self, self, damageIndex );
sys.waitFrame();
}
}
void vehicle_mcp::vCreateMission() {
vFreeMission();
InitGoalTask();
missionTask = taskManager.allocEntityTask( GetPlayerTask( getKey( "task_escort" ) ), self );
}
void vehicle_mcp::vFreeMission() {
if ( missionTask != $null ) {
missionTask.free();
missionTask = $null;
}
FreeGoalTask();
}
void vehicle_mcp::vCompleteMission() {
if ( missionTask != $null ) {
missionTask.complete();
missionTask.free();
missionTask = $null;
}
FreeGoalTask();
}
void vehicle_mcp::OnCanMoveChanged() {
setImmobilized( !( canMove && !immobilized ) );
setTakesDamage( canMove );
if ( canMove ) {
InitRadarValues();
if ( !isDeployed ) {
playAnim( ANIMCHANNEL_ALL, "base" );
} else {
playAnim( ANIMCHANNEL_ALL, "deployed" );
}
} else {
FreeRadarValues();
if ( !isDeployed ) {
playAnim( ANIMCHANNEL_ALL, "undeployed_disabled" );
} else {
playAnim( ANIMCHANNEL_ALL, "disabled" );
}
}
}
vector vehicle_mcp::GetMissilePos() {
float launchJoint = getJointHandle( getKey( "joint_launch" ) );
if ( launchJoint != -1 ) {
return getJointPos( launchJoint );
}
sys.warning( "Unknown missile launch joint" );
return getWorldOrigin() + '0 0 256';
}
void vehicle_mcp::OnFireCountChanged() {
if ( fireCount > 0 ) {
vector missilePos = GetMissilePos();
playOriginEffect( "fx_scud_launch", "", missilePos, '1 0 0', false);
}
}
float vehicle_mcp::GetActivateCode( entity p, float distance ) {
if ( p.getViewingEntity() != p ) {
return AK_NONE;
}
if ( p.getHealth() <= 0 ) {
return AK_NONE;
}
if ( p.getProxyEntity() != $null_entity ) {
return AK_NONE;
}
float allegiance = getEntityAllegiance( p );
if ( allegiance == TA_FRIEND ) {
if ( distance < DISTANCE_FOR_ACTION ) {
if ( isInWater() < drownHeight ) {
float health = getHealth();
if ( health >= getMinDisplayHealth() && health < getMaxHealth() ) {
if ( p.vHasActionItem( AK_REPAIR ) ) {
return AK_REPAIR;
}
}
}
}
if ( distance < maxEnterDistance ) {
float spots = getNumPositions();
float usedSpots = getNumOccupiedPositions();
if ( isDeployed ) {
spots = spots - 1;
}
if ( spots - usedSpots > 0 ) {
return AK_USEVEHICLE;
}
}
}
return AK_NONE;
}
boolean vehicle_mcp::vCheckActionCode( entity p, float actionCode ) {
if ( getEntityAllegiance( p ) == TA_ENEMY ) {
if ( actionCode == AC_ENEMY_REPAIR ) {
return true;
}
return false;
}
if ( actionCode == AC_REPAIR ) {
if ( isInWater() < drownHeight ) {
float health = getHealth();
return ( health >= getMinDisplayHealth() ) && ( ( health < getMaxHealth() ) );
}
}
return false;
}
void vehicle_mcp::DestructionVOThread() {
player lPlayer = sys.getLocalPlayer();
sys.wait( 10.0f );
if ( getDriver() == lPlayer ) {
sys.startSoundDirect( getKey( "snd_vo_off_course_20" ), SND_PLAYER_VO );
}
sys.wait( 10.0f );
if ( getDriver() == lPlayer ) {
sys.startSoundDirect( getKey( "snd_vo_off_course_10" ), SND_PLAYER_VO );
}
destructionVOThread = -1;
}
void vehicle_mcp::vOnContextDefend( entity p ) {
player local = sys.getLocalViewPlayer();
if ( local == $null_entity || p == $null_entity ) {
return;
}
FlashIconForTeam( p.getGameTeam() );
}
void vehicle_mcp::vOnContextDestroy( entity p ) {
player local = sys.getLocalViewPlayer();
if ( local == $null_entity || p == $null_entity ) {
return;
}
FlashIconForTeam( p.getGameTeam() );
}
void vehicle_mcp::SetupObjectiveIcon() {
FreeObjectiveIcon();
float commandMapSize = getFloatKeyWithDefault( "icon_objective_size_cm", 16.f );
// gdf
cmObjectiveIcon = sys.allocCMIcon( self, getFloatKey( "icon_sort_objective_cm" ) );
sys.setCMIconDrawMode( cmObjectiveIcon, DM_ROTATED_MATERIAL );
sys.setCMIconSize( cmObjectiveIcon, commandMapSize );
sys.setCMIconColorMode( cmObjectiveIcon, CM_NORMAL );
sys.setCMIconMaterial( cmObjectiveIcon, GetMaterial( getKey( "mtr_commandmap_objective" ) ) );
sys.setCMIconFlag( cmObjectiveIcon, CMF_ALWAYSKNOWN );
sys.addCMIconRequirement( cmObjectiveIcon, "same_team == true" );
// strogg
cmObjectiveIconStrogg = sys.allocCMIcon( self, getFloatKey( "icon_sort_objective_cm" ) );
sys.setCMIconDrawMode( cmObjectiveIconStrogg, DM_ROTATED_MATERIAL );
sys.setCMIconSize( cmObjectiveIconStrogg, commandMapSize );
sys.setCMIconColorMode( cmObjectiveIconStrogg, CM_NORMAL );
sys.setCMIconMaterial( cmObjectiveIconStrogg, GetMaterial( getKey( "mtr_commandmap_objective" ) ) );
sys.setCMIconFlag( cmObjectiveIconStrogg, CMF_ALWAYSKNOWN );
sys.addCMIconRequirement( cmObjectiveIconStrogg, "same_team == false" );
sys.setCMIconFlag( commandMapHandle, CMF_ALWAYSKNOWN );
}
void vehicle_mcp::FreeObjectiveIcon() {
if ( cmObjectiveIcon != -1 ) {
sys.freeCMIcon( self, cmObjectiveIcon );
cmObjectiveIcon = -1;
}
if ( cmObjectiveIconStrogg != -1 ) {
sys.freeCMIcon( self, cmObjectiveIconStrogg );
cmObjectiveIconStrogg = -1;
}
sys.clearCMIconFlag( commandMapHandle, CMF_ALWAYSKNOWN );
}
void vehicle_mcp::FlashIconForTeam( entity team ) {
if ( team == stroggTeam ) {
sys.flashCMIcon( cmObjectiveIconStrogg, -1, 5, -1 );
} else {
sys.assert( team == gdfTeam );
sys.flashCMIcon( cmObjectiveIcon, -1, 5, -1 );
}
}
entity vehicle_mcp::vGetSpectateEntity() {
entity driver = getDriver();
if ( driver != $null_entity ) {
return driver;
}
float time = sys.getTime();
if ( lastRepairTime >= time - 0.5f ) {
return lastRepairer;
}
return $null_entity;
}
boolean vehicle_mcp::vIsObjectiveComplete() {
return isDeployed;
}