IW4-Dump-Files/maps/_friendlyfire.gsc

359 lines
10 KiB
Plaintext

// 200 participation points are given to the player for killing an enemy
// 800 participation points are taken from the player for killing a friendly
// friendly damage removes points based on amount of damage done and distance
// a max of 1000 points is allowed
// the player will fail the mission when level.friendlyfire["min_participation"] is reached
#include maps\_utility;
main()
{
level.friendlyfire[ "min_participation" ] = -200; // when the player hit this number of participation points the mission is failed
level.friendlyfire[ "max_participation" ] = 1000; // the player will stop gaining participation points once this amount is earned
level.friendlyfire[ "enemy_kill_points" ] = 250; // this many participation points are earned for killing an enemy
level.friendlyfire[ "friend_kill_points" ] = -650; // participation point penalty for killing a friendly
level.friendlyfire[ "point_loss_interval" ] = 1.25; // amount of time a point lasts
level.player.participation = 0;
level.friendlyFireDisabled = 0;
level.friendlyFireDisabledForDestructible = 0;// don't ever set this, it's used internally only and shouldn't be set by your script
SetDvarIfUninitialized( "friendlyfire_dev_disabled", "0" );
common_scripts\utility::flag_init( "friendly_fire_warning" );
thread debug_friendlyfire();
thread participation_point_flattenOverTime();
}
debug_friendlyfire()
{
/#
SetDvarIfUninitialized( "debug_friendlyfire", "0" );
friendly_fire = NewHudElem();
friendly_fire.alignX = "right";
friendly_fire.alignY = "middle";
friendly_fire.x = 620;
friendly_fire.y = 100;
friendly_fire.fontScale = 2;
friendly_fire.alpha = 0;
for ( ;; )
{
if ( GetDebugDvar( "debug_friendlyfire" ) == "1" )
friendly_fire.alpha = 1;
else
friendly_fire.alpha = 0;
friendly_fire SetValue( level.player.participation );
wait 0.25;
}
#/
}
// every entity that influences friedly fire should run this thread (ai of both teams, vehicles of both teams)
friendly_fire_think( entity )
{
if ( !isdefined( entity ) )
return;
if ( !isdefined( entity.team ) )
entity.team = "allies";
if ( IsDefined( level.no_friendly_fire_penalty ) )
return;
// if the mission is failed from another entity running this function then end this one
level endon( "mission failed" );
// wait until this entity dies
level thread notifyDamage( entity );
level thread notifyDamageNotDone( entity );
level thread notifyDeath( entity );
for ( ;; )
{
if ( !isdefined( entity ) )
return;
if ( entity.health <= 0 )
return;
entity waittill( "friendlyfire_notify", damage, attacker, direction, point, method, weaponName );
if ( !isdefined( entity ) )
return;
// if we dont know who the attacker is we can't do much, so ignore it. This is seldom to happen, but not impossible
if ( !isdefined( attacker ) )
continue;
// check to see if the death was caused by the player or the players turret
bPlayersDamage = false;
if ( !isdefined( weaponName ) )
weaponName = entity.damageweapon;
if ( IsPlayer( attacker ) )
{
bPlayersDamage = true;
// player shot a red barrel or something similar and it blew up and damaged/killed this guy so just ignore it
if ( isdefined( weaponName ) && ( weaponName == "none" ) )
bPlayersDamage = false;
// code doesn't give the correct weaponname on damage and death notifies when on a turret, so we have to workaround it here
if ( attacker isUsingTurret() )
bPlayersDamage = true;
}
else
if ( ( IsDefined( attacker.code_classname ) ) && ( attacker.code_classname == "script_vehicle" ) )
{
owner = attacker GetVehicleOwner();
if ( ( IsDefined( owner ) ) && ( IsPlayer( owner ) ) )
bPlayersDamage = true;
}
// if the player didn't cause the damage then disregard
if ( !bPlayersDamage )
continue;
if ( !isdefined( entity.team ) )
continue;
same_team = entity.team == level.player.team;
civilianKilled = undefined;
if( level.script != "airport" )
civilianKilled = IsSubStr( entity.classname, "civilian" );
else
civilianKilled = false;
killed = damage == -1;
// if an enemy was killed then incriment the players participation score
if ( !same_team && !civilianKilled )
{
if ( killed )
{
level.player.participation += level.friendlyfire[ "enemy_kill_points" ];
participation_point_cap();
return;
}
continue;
}
//player killed/damaged a friendly
if ( IsDefined( entity.no_friendly_fire_penalty ) )
continue;
if ( ( method == "MOD_PROJECTILE_SPLASH" ) && ( IsDefined( level.no_friendly_fire_splash_damage ) ) )
continue;
// don't cause friendly fire from claymores because it's probably the AI's fault not the players
if ( IsDefined( weaponName ) && ( weaponName == "claymore" ) )
continue;
if ( killed )
{
level.player.participation += level.friendlyfire[ "friend_kill_points" ];
}
else
{
// friendly was damaged - figure out how many participation points to remove
level.player.participation -= damage;
}
participation_point_cap();
// dont fail the mission if death was caused by a grenade that was cooking durring an autosave
if ( check_grenade( entity, method ) && savecommit_afterGrenade() )
{
if ( killed )
return;
else
continue;
}
// fail the mission if the players participation has reached the minimum
friendly_fire_checkPoints( civilianKilled );
}
}
friendly_fire_checkPoints( civilianKilled )
{
if ( ( IsDefined( level.failOnFriendlyFire ) ) && ( level.failOnFriendlyFire ) )
{
level thread missionfail( civilianKilled );
return;
}
if ( level.friendlyFireDisabledForDestructible == 1 )
return;
if ( level.friendlyFireDisabled == 1 )
return;
if ( level.player.participation <= ( level.friendlyfire[ "min_participation" ] ) )
level thread missionfail( civilianKilled );
}
check_grenade( entity, method )
{
if ( !isdefined( entity ) )
return false;
// check if the entity was killed by a grenade
wasGrenade = false;
if ( ( IsDefined( entity.damageweapon ) ) && ( entity.damageweapon == "none" ) )
wasGrenade = true;
if ( ( IsDefined( method ) ) && ( method == "MOD_GRENADE_SPLASH" ) )
wasGrenade = true;
// if the entity was not killed by a grenade then exit
return wasGrenade;
}
savecommit_afterGrenade()
{
currentTime = GetTime();
if ( currentTime < 4500 )
{
PrintLn( "^3aborting friendly fire because the level just loaded and saved and could cause a autosave grenade loop" );
return true;
}
else
if ( ( currentTime - level.lastAutoSaveTime ) < 4500 )
{
PrintLn( "^3aborting friendly fire because it could be caused by an autosave grenade loop" );
return true;
}
return false;
}
participation_point_cap()
{
if ( level.player.participation > level.friendlyfire[ "max_participation" ] )
level.player.participation = level.friendlyfire[ "max_participation" ];
if ( level.player.participation < level.friendlyfire[ "min_participation" ] )
level.player.participation = level.friendlyfire[ "min_participation" ];
}
participation_point_flattenOverTime()
{
level endon( "mission failed" );
for ( ;; )
{
if ( level.player.participation > 0 )
{
level.player.participation--;
}
else if ( level.player.participation < 0 )
{
level.player.participation++;
}
wait level.friendlyfire[ "point_loss_interval" ];
}
}
TurnBackOn()
{
level.friendlyFireDisabled = 0;
}
TurnOff()
{
level.friendlyFireDisabled = 1;
}
missionfail( civilianKilled )
{
if ( !isdefined( civilianKilled ) )
civilianKilled = false;
if ( level.script == "airport" )
{
if ( civilianKilled )
return;
common_scripts\utility::flag_set( "friendly_fire_warning" );
return;
}
if ( GetDvar( "friendlyfire_dev_disabled" ) == "1" )
return;
level.player endon( "death" );
level endon( "mine death" );
level notify( "mission failed" );
level notify( "friendlyfire_mission_fail" );
waittillframeend;
SetSavedDvar( "hud_missionFailed", 1 );
if ( IsDefined( level.player.failingMission ) )
return;
if ( civilianKilled )
// You shot a civilian. Watch your fire!
SetDvar( "ui_deadquote", &"SCRIPT_MISSIONFAIL_CIVILIAN_KILLED" ); // You shot a civilian. Watch your fire!
else if ( IsDefined( level.custom_friendly_fire_message ) )
SetDvar( "ui_deadquote", level.custom_friendly_fire_message ); // friendly fire will not be tolerated
else if ( level.campaign == "british" )
// Friendly fire will not be tolerated!
SetDvar( "ui_deadquote", &"SCRIPT_MISSIONFAIL_KILLTEAM_BRITISH" ); // Friendly fire will not be tolerated!
else if ( level.campaign == "russian" )
// You are a traitor to the motherland!
SetDvar( "ui_deadquote", &"SCRIPT_MISSIONFAIL_KILLTEAM_RUSSIAN" ); // You are a traitor to the motherland!
else
// Friendly fire will not be tolerated!
SetDvar( "ui_deadquote", &"SCRIPT_MISSIONFAIL_KILLTEAM_AMERICAN" ); // Friendly fire will not be tolerated!
// shader if specified
if ( IsDefined( level.custom_friendly_fire_shader ) )
thread maps\_load::special_death_indicator_hudelement( level.custom_friendly_fire_shader, 64, 64, 0 );
//logString( "failed mission: Friendly fire" );
maps\_utility::missionFailedWrapper();
}
notifyDamage( entity )
{
level endon( "mission failed" );
entity endon( "death" );
for ( ;; )
{
entity waittill( "damage", damage, attacker, direction, point, method, modelName, tagName, partName, dFlags, weaponName );
entity notify( "friendlyfire_notify", damage, attacker, direction, point, method, weaponName );
}
}
notifyDamageNotDone( entity )
{
level endon( "mission failed" );
entity waittill( "damage_notdone", damage, attacker, direction, point, method );
entity notify( "friendlyfire_notify", -1, attacker, undefined, undefined, method );
}
notifyDeath( entity )
{
level endon( "mission failed" );
entity waittill( "death", attacker, method, weaponName );
entity notify( "friendlyfire_notify", -1, attacker, undefined, undefined, method, weaponName );
}
detectFriendlyFireOnEntity( entity )
{
/*
if ( !isdefined( entity ) )
return;
AssertEx( IsDefined( entity.team ), "You must set .team to allies or axis for an entity calling detectFriendlyFire()" );
entity SetCanDamage( true );
level thread friendly_fire_think( entity );
*/
}