TacoServer/LakRabbitGame.cs
2018-06-28 14:34:52 -04:00

2245 lines
72 KiB
C#

//-------------------------------------------------------------------
// Team Rabbit script
// -------------------------------------------------------------------
// DisplayName = LakRabbit
//--- GAME RULES BEGIN ---
//Spawn with your favorites and double ammunition
//Rabbit is invincible for 2 seconds upon grab
//No laser, no chain. Eat it Altimor.
//Sounds for regular & special hits
//Points based on difficulty, speed, and distance
//Duel Mode forces rabbit to fight and rewards for killing
//--- GAME RULES END ---
// Thanks for helping me test!
// maradona, pip, phantom jaguar, hilikus, the_ham, pip, wiggle, dragon, pancho villa, w/o, nectar and many others..
// v3.2 - Chocotaco April 2018
// Made spawning closer to the Rabbit 200>150
// Made Debrief font slightly larger
// Added flag updater code from CTF
// Took out Snipe and Chain Stats. Replaced them with more relevant stats.
// Added Unlimited DiscJump Variable.
//
// v3.1 9/11 Version
// Fixed Boundary walls
// Banned Certain types of weapons
//
// -2.17xxx points bug may be fixed.
// Fixed the Resetting... spam while toggling duel mode.
// Voting looks better (makes sense).
// No mysterious 'hoorah' when you get 100% mine on ground.
// Splash damage is based on how many are playing (more people less splash damage). Minimum 10% damage. No Splash is still votable.
// Heavies are easier to kill.
// Point adjustments.
// Flag wont just drop to the ground in duel mode. Basically, if you don't have enough upward momentum, it will be added to the flag so it can fly up.
// No 'duel kills' with missile special.
// Rabbit cannot disk jump in duel mode.
// DJ + Gren spam addressed again :)
// Throwing a hand nade removes invincibility.
// There is a minimum 'seconds per kill', to help with the 2 kills in 2 seconds scenario.
// Point maximum raised to 2000.
// Fixed No-Splash so you still take damage with direct hits on ground.
// Extra duel time for rabbit with No-Splash enabled and when it's 1on1 in duel mode.
// If you want to see the objective hud download LakRabbitObjHud.cs and put in /base/scripts/autoexec
//
// v3
// Code optimization and bug fixes.
// Mortars are enabled, but only do half damage. Mortars can get long-distance or MA points.
// Long-distance shots are a little easier to get.
// You get one free disk-jump at spawn (DJ does no damage to you), but lose it if you get the flag.
// 'Specials'. You'll know it when you see it ;)
// No damage taken from mines if you aren't in the air, and mine damage in general is greatly reduced.
// [Fix] You only get points with sniper if you have 50% energy.
// Extra points for snipe headshot, and it is displayed with sound (regular snipe w/points has no sound).
// Points show up as soon as you get them (don't have to respawn)
// Distance and speed is now taken from where you shot, not where you are when the projectile hits.
// Duel mode -- rabbit has to fight or blow up, and is awarded points for killing people quickly (votable on/off).
// Grid is 'bouncy' like TR2 (code from TR2 as well -- thanks) for players and flags, and you can no longer spawn out of bounds. <-- may help with oob flag/ghost/sticky corpse bugs
// Ground damage cut in half in duel mode, except for rabbit.
// Messed with MA flag-grab points again, and it now shows your speed and height.
// Points for hand grenades.
// Hand nades don't detonate mines in duel mode (thx mista).
// You can vote off splash damage. Mines and grenades may still damage you with splash, however, and you can still get long distance shot points.
// You get points from chaingun every 5 hits (less spam, better looking points). Firing a different weapon resets your accuracy and hits same as before.
// Shocklance points are based mostly on speed and height now, and your height is displayed.
// Objective hud fixed.
// Spawn a little closer to rabbit, and the rabbit waypoint is only shown if someone grabs flag and is far away from you.
// Removed old AI Rabbit stuff (less console spam).
// DJ + Gren spam abuse addressed. Good luck getting points this way...
// New debriefing information at the end of a map: score, kills, MAs, avg speed and distance, overall chain accuracy, percent of snipe and shock hits.
// Getting an MA with shocklance and sniper is now based on if -you- are in the air, not the opponent.
// Point limit reduced to 1500.
//
// v2
// On CTF maps (or maps with two or more flags) you can capture the flag for points when 6 people are playing. Only one flag can be in play at a time. Once capped, your flag gets returned and you immediately take the new flag.
// Mines are now available.
// Flag gets 'tossed' when carrier dies, no longer drops like a rock.
// Better messages, showing speed and distance. Distance bonuses are calculated into points; no multipliers.
// Spawn with full energy.
// MA flag-grab points are better calculated.
// Spawning has been redone so you spawn within a radius of 250m from either the rabbit or flag.
// Lots of new maps, all competition CTF maps, set up for LakRabbit (no generators, etc)
// Rabbit doesn't suffer the CG or Laser damage subtraction based on players.
// Point system revamped.
// 2500 point limit.
// Long-Distance disc and GL shots may give points (depending on difficulty of shot).
// Flag-skipping bug fixed.
// v1 - See game rules.
// Vars:
// $Host::ShowFlagIcon
// 0 - Don't show
// 1 - Scope when sensor visible
// 2 - Do not scope when sensor visible
//
// $Host::LakRabbitPubPro
// 0 - Disable LakPro features
// 1 - Enable LakPro features
//
// $Host::LakRabbitDuelMode
// 0 - Disable Duel Mode
// 1 - Enable Duel Mode
//
// $Host::LakRabbitNoSplashDamage
// 0 - Disable No Splash Dame
// 1 - Enable No Splash Damage
//
// $Host::ShowFlagTask
// 0 - Do not show flag task
// 1 - Show the flag when dropped as a task
//
// $Host::EnableLakUnlimitedDJ
// 0 - Players only get one DiscJump
// 1 - Show the flag when dropped as a task
//
package LakRabbitGame {
function Flag::objectiveInit(%data, %flag)
{
$flagStatus = "<At Home>";
%flag.carrier = "";
%flag.originalPosition = %flag.getTransform();
%flag.isHome = true;
%flag.rotate = true;
// ilys -- add the icon to the flag
if($Host::ShowFlagIcon == 1)
{
%flag.scopeWhenSensorVisible(false);
setTargetSensorGroup(%flag.getTarget(), $NonRabbitTeam);
setTargetRenderMask(%flag.getTarget(), getTargetRenderMask(%flag.getTarget()) | 0x2);
setTargetAlwaysVisMask(%flag.getTarget(), 0x7);
}
// create a waypoint to the flag's starting place
%flagWaypoint = new WayPoint()
{
position = %flag.position;
rotation = "1 0 0 0";
name = "Flag Home";
dataBlock = "WayPointMarker";
team = $NonRabbitTeam;
};
$AIRabbitFlag = %flag;
MissionCleanup.add(%flagWaypoint);
// -------------------------------------------------------------------------------------------
// z0dd - ZOD, 10/03/02. Use triggers for flags that are at home, hack for flag collision bug.
%flag.trigger = new Trigger()
{
dataBlock = flagTrigger;
polyhedron = "-0.6 0.6 0.1 1.2 0.0 0.0 0.0 -1.2 0.0 0.0 0.0 2.5";
position = %flag.position;
rotation = %flag.rotation;
};
MissionCleanup.add(%flag.trigger);
%flag.trigger.flag = %flag;
// -------------------------------------------------------------------------------------------
}
// AI consoel spam
function AIThrowObject(%object)
{
return;
}
function AIGrenadeThrown(%object)
{
return;
}
function AICorpseAdded(%corpse)
{
return;
}
// eat it ZP/Altimor
function ChaingunImage::onFire(%data,%obj,%slot){}
function SniperRifleImage::onFire(%data,%obj,%slot){}
function ShockLanceImage::onFire(%data, %obj, %slot)
{
%p = parent::onFire(%data,%obj,%slot);
%obj.client.totalShocks++;
%obj.setInvincible(false);
return %p;
}
function ShapeBaseImageData::onFire(%data, %obj, %slot)
{
if(%data.projectile $= ChaingunBullet)
$LakFired[%obj, ChaingunBullet, 0]++;
else
{
$LakFired[%obj, ChaingunBullet, 0] = 0;
$LakFired[%obj, ChaingunBullet, 1] = 0;
}
%p = parent::onFire(%data, %obj, %slot);
%p.shotFrom = %obj.getWorldBoxCenter();
%p.shotSpeed = getSpeed(%obj);
// borlak -- remove height from grenades to get rid of DJ + gren spam abuse
switch$(%data.projectile)
{
case BasicGrenade:
%p.shotFrom = setWord(%p.shotFrom, 2, getWord(%p.shotFrom,2) - getHeight(%obj));
}
return %p;
}
// borlak -- this is going to be one ugly hack, but I can't find where a non radius damage
// object calls damageObject on a -hit-, therefore cannot pass on the projectiles data to
// damageObject and get it's true origin of fire
function ProjectileData::onExplode(%data, %proj, %pos, %mod)
{
$lastObjExplode = %proj;
parent::onExplode(%data, %proj, %pos, %mod);
}
// this too...
function detonateGrenade(%obj)
{
%obj.shotSpeed = -1;
%obj.isHandNade = 1;
$lastObjExplode = %obj;
parent::detonateGrenade(%obj);
}
function GrenadeThrown::onThrow(%this, %gren)
{
%gren.sourceObject.setInvincible(false);
%gren.shotFrom = %gren.getWorldBoxCenter();
parent::onThrow(%this, %gren);
}
// borlak -- prevent getting hurt while knocked back (more fun)
function Armor::onImpact(%data, %playerObject, %collidedObject, %vec, %vecLen)
{
if(%playerObject.knockback)
return;
parent::onImpact(%data, %playerObject, %collidedObject, %vec, %vecLen);
}
// borlak -- ma testing and points
function Armor::damageObject(%data, %targetObject, %sourceObject, %position, %amount, %damageType, %momVec, %mineSC)
{
%distance = 0;
%energy = 0;
%velBonus = 0;
%sound = "";
%defaultSound = '~wfx/misc/bounty_bonus.wav';
%weapon = 0;
%points = 0;
%ma = 0;
%special = "";
%long = 0;
%accuracy = "";
%velstring = "";
%maxDamage = 0;
%percentDam = 0;
if(%targetObject.invincible || %targetObject.getState() $= "Dead")
return;
// rabbit can't DJ in duel mode
if(Game.duelMode && %targetObject.holdingFlag && %targetObject == %sourceObject
&& %damageType == $DamageType::Disc
&& getWord(%targetObject.getMuzzleVector(0),2) < -0.7
&& !TestForMA(%sourceObject, 5))
{
%sound = '~wfx/misc/missed.wav';
%amount = 2.0;
%targetObject.blowup();
}
// Zeph - PubPro no DJ
if(Game.PubPro && %targetObject == %sourceObject
&& %damageType == $DamageType::Disc
&& getWord(%targetObject.getMuzzleVector(0),2) < -0.7
&& !TestForMA(%sourceObject, 5))
{
%sound = '~wfx/misc/missed.wav';
%amount = 2.0;
%targetObject.blowup();
%targetObject.scriptKill();
}
// hurting yourself, check for free DJ
if( isObject(%sourceObject)
&& %sourceObject.getDataBlock().getClassName() $= "PlayerData"
&& %targetObject.client == %sourceObject.client)
{
if(%damageType == $DamageType::Disc && %sourceObject.freeDJ)
{
%amount = 0;
%sourceObject.freeDJ--;
}
}
%targetObject.lastDamageType = %damageType;
// borlak -- MA, long distance, mine and grenade points
if( isObject(%sourceObject)
&& %sourceObject.getDataBlock().getClassName() $= "PlayerData" && %targetObject.getDataBlock().getClassName() $= "PlayerData"
&& %targetObject.client.team != %sourceObject.client.team
&& %damageType)
{
$LakDamaged[%targetObject.client] = %sourceObject.client;
%targetObject.lastDamagedBy = %sourceObject;
%targetPosition = %targetObject.getWorldBoxCenter();
// borlak -- DJ + gren spam abuse, remove player height
if(%damageType == $DamageType::Grenade && !$lastObjExplode.isHandNade)
%targetPosition = setWord(%targetPosition, 2, getWord(%targetPosition,2) - getHeight(%targetObject));
if(%damageType == $DamageType::ShockLance || %damageType == $DamageType::Laser)
{
$lastObjExplode = 0;
%distance = VectorDist(%targetPosition, %sourceObject.getWorldBoxCenter());
%vel = getSpeed(%sourceObject);
}
else
{
%maxDamage = $lastObjExplode.getDataBlock().directDamage ? $lastObjExplode.getDataBlock().directDamage : $lastObjExplode.getDataBlock().indirectDamage;
%distance = VectorDist(%targetPosition, $lastObjExplode.shotFrom);
if($lastObjExplode.shotSpeed < 0)
%vel = getSpeed(%sourceObject);
else
%vel = $lastObjExplode.shotSpeed;
}
%percentDam = mFloor((%amount/%maxDamage)*100);
%energy = %sourceObject.getEnergyLevel()/%sourceObject.getDataBlock().maxEnergy;
%velTarget = getSpeed(%targetObject);
%distanceBonus = (mPow(%distance,1.35)/10)+1;
%longDistanceBonus = (mPow(%distance,1.10)/10)+1;
%velBonus = (mPow(%vel,1.125)/10)+1;
// for shock and laser, you get MA points if -you- are in the air not the opponent
if(%damageType == $DamageType::ShockLance || %damageType == $DamageType::Laser)
%ma = TestForMA(%sourceObject, 6);
else
%ma = TestForMA(%targetObject, 6);
// lower splash damage depending on how many people are playing.. duel mode only
if(Game.duelMode && %percentDam < 98 && $lastObjExplode && $lastObjExplode.getDataBlock().indirectDamage > 0)
{
%mult = 1-(ClientGroup.getCount()-1)/10;
if(%mult < 0.10)
%mult = 0.10;
%amount *= %sourceObject.holdingFlag ? 1 : %mult;
%maxDamage *= %sourceObject.holdingFlag ? 1 : %mult;
}
// no splash damage vote
if(Game.noSplashDamage && %percentDam < 98 && $lastObjExplode && !$lastObjExplode.isHandNade && %damageType != $DamageType::Mine)
%amount = 0.0;
if(%damageType == $DamageType::Laser && (%energy > 0.5 || %players > 7))
{
%players = (ClientGroup.getCount()-1)/1.5;
%points = (%distance/75)+1;
if(%ma)
%points *= 1.75;
if(%targetObject.client.headshot)
{
%sound = %defaultSound;
%special = " Headshot";
%points *= 1.75;
}
%sourceObject.client.totalSnipeHits++;
%weapon = "Snipe";
}
else if(%damageType == $DamageType::Bullet)
{
// doesn't matter if it's MA
%ma = 0;
%players = (ClientGroup.getCount()-1)/1.75;
$LakFired[%sourceObject, ChaingunBullet, 1]++;
if($LakFired[%sourceObject, ChaingunBullet, 1] % 5 == 0)
{
%accamount = mFloor(($LakFired[%sourceObject, ChaingunBullet, 1] / $LakFired[%sourceObject, ChaingunBullet, 0])*100);
%velBonus = 0;
%points = (%accamount/3)+1;
%accuracy = " [Accuracy:" @ %accamount @ "%]";
%sourceObject.client.totalChainAccuracy += %accamount;
%sourceObject.client.totalChainHits++;
}
%weapon = "Chaingun";
}
else if(%damageType == $DamageType::Disc)
{
if(%ma && %percentDam >= 98)
{
%points = %distanceBonus;
%sound = %defaultSound;
}
if(%percentDam >= 25 && !%ma && %distance >= 80 && %velTarget > 20)
{
%points = %longDistanceBonus;
%velBonus /= 2;
%long = 1;
%sound = %defaultSound;
}
// special knockback if you hit too close, max 15% chance (point blank).. 5% at 30meters, 1% chance for any MA
%chance = mFloor(15 - %distance/3);
if(%chance <= 0) %chance = 1;
if(%ma && getRandom(1,100) <= %chance)
{
if(%targetObject.holdingFlag)
Game.playerDroppedFlag(%targetObject);
if(%sourceObject.holdingFlag && Game.duelMode)
{
duelBonus(%sourceObject.client);
$LakDamaged[%targetObject.client] = 0;
}
// lower damage and make invincible to ground damage to make it a little more fun
%amount = 0.01;
%targetObject.setKnockback(true);
%targetObject.schedule(15000, "setKnockback", false);
%p = %targetObject.getWorldBoxCenter();
%muzzleVec = %sourceObject.getMuzzleVector(0);
%impulseVec = VectorScale(%muzzleVec, 25000);
%targetObject.applyImpulse(%p, %impulseVec);
%sound = '~wfx/misc/slapshot.wav';
}
%weapon = "Disc";
}
else if(%damageType == $DamageType::Grenade && $lastObjExplode.isHandNade)
{
if(%percentDam > 20)
{
%accuracy = " [Accuracy:" @ %percentDam @ "%]";
%points = (%percentDam/10)+1;
%velBonus = 0;
%sound = '~wfx/misc/coin.wav';
}
if(%percentDam >= 99)
{
%sound = '~wfx/misc/Cheer.wav';
%points *= 2.0;
}
if(%ma)
%points *= 1.5;
%weapon = "Hand-Nade";
}
else if(%damageType == $DamageType::Grenade)
{
if(Game.PubPro)
{
if(%ma && %percentDam >= 98)
{
%points = %distanceBonus;
%sound = %defaultSound;
}
if(%percentDam >= 25 && !%ma && %distance >= 80 && %velTarget > 20)
{
%points = %longDistanceBonus;
%velBonus /= 2;
%long = 1;
%sound = %defaultSound;
}
}
else
{
if(%ma && %percentDam >= 98)
{
%points = %distanceBonus/1.85;
%sound = %defaultSound;
}
if(%percentDam >= 25 && !%ma && %distance >= 100 && %velTarget > 30)
{
%points = %longDistanceBonus/1.85;
%velBonus /= 4;
%long = 1;
%sound = %defaultSound;
}
}
%weapon = "Grenade-Launcher";
}
else if(%damageType == $DamageType::Mortar)
{
if(%ma && %percentDam >= 98)
{
%points = %distanceBonus*2.66;
%sound = %defaultSound;
}
if(%percentDam >= 25 && !%ma && %distance >= 100 && %velTarget > 30)
{
%points = %longDistanceBonus;
%velBonus /= 2;
%long = 1;
%sound = %defaultSound;
}
if(!Game.duelMode)
%amount /= 2;
%weapon = "Mortar";
}
else if(%damageType == $DamageType::Mine)
{
%amount /= %amount > 0 ? 3 : 1;
if(%ma)
{
%accuracy = " [Accuracy:" @ %percentDam @ "%]";
%points = (%percentDam/7)+2;
%velBonus = 0;
%sound = '~wfx/misc/coin.wav';
if(%percentDam >= 99)
{
%sound = '~wfx/misc/Cheer.wav';
%points *= 2.0;
}
}
if(!%ma)
%amount = 0;
%weapon = "MINE";
}
else if(%damageType == $DamageType::ShockLance)
{
%height = getHeight(%sourceObject);
%heightBonus = (mPow(%height,1.20)/10)+1;
%velBonus /= 2;
%points = mFloor(%distance/2) + (%heightBonus);
%accuracy = " [Height:" @ %height @"m]";
// borlak -- check rear shocklance hit
%muzzlePos = %sourceObject.getMuzzlePoint(0);
%forwardVec = %targetObject.getForwardVector();
%objDir2D = getWord(%forwardVec, 0) @ " " @ getWord(%forwardVec,1) @ " " @ "0.0";
%objPos = %targetObject.getPosition();
%dif = VectorSub(%objPos, %muzzlePos);
%dif = getWord(%dif, 0) @ " " @ getWord(%dif, 1) @ " 0";
%dif = VectorNormalize(%dif);
%dot = VectorDot(%dif, %objDir2D);
if(%dot >= mCos(1.05))
{
if(%sourceObject.holdingFlag && TestForMA(%targetObject, 6))
{
%sourceObject.setCloaked(true);
if($host::dontcloakflag)
%sourceObject.holdingFlag.setCloaked(false);
}
%points *= 2;
%special = "-in-the-back";
}
if(%ma)
%points += 3;
%sound = %defaultSound;
%sourceObject.client.totalShockHits++;
%weapon = "ShockLance";
}
else if(%damageType == $DamageType::Blaster)
{
if(%ma)
{
%points = %distanceBonus/2;
%velBonus /= 2;
%sound = %defaultSound;
}
%weapon = "Blaster";
}
else if(%damageType == $DamageType::Plasma)
{
if(%ma && %percentDam >= 98)
{
%points = %distanceBonus/1.3+2;
%sound = %defaultSound;
}
if(%percentDam >= 25 && !%ma && %distance >= 40 && %velTarget > 30)
{
%points = %longDistanceBonus*1.5;
%velBonus /= 1.75;
%long = 1;
%sound = %defaultSound;
}
%weapon = "Plasma";
}
}
// borlak -- recalc score for hits
if( isObject(%sourceObject)
&& %sourceObject.getDataBlock().getClassName() $= "PlayerData" && %targetObject.getDataBlock().getClassName() $= "PlayerData"
&& %points)
{
%distance = mFloor(%distance);
%points += %velBonus;
%points = mFloor(%points);
%sourceObject.client.morepoints += %points;
if(%ma)
{
%sourceObject.client.mas++;
%sourceObject.client.totalSpeed += %vel;
%sourceObject.client.totalDistance += %distance;
%hitType = "Mid-Air ";
}
else if(%long)
%hitType = "Long-Distance ";
else
%hitType = "";
messageClient(%sourceObject.client,'msgPlrPointBonus', '\c4You receive %1 point%2! [%3%4%5] [Distance:%6m] [Speed:%7kph] %8',
%points, %points == 1 ? "" : "s",
%hitType,
%weapon,
%special !$= "" ? %special : "",
%distance,
%vel,
%accuracy);
messageAllExcept(%sourceObject.client, -1, 'msgRabbitPointBonus', '\c4%1 receives %2 point%3! [%4%5%6] [Distance:%7m] [Speed:%8kph] %9',
%sourceObject.client.name,
%points, %points == 1 ? "" : "s",
%hitType,
%weapon,
%special !$= "" ? %special : "",
%distance,
%vel,
%accuracy );
if(%sourceObject.holdingFlag && %points >= 75)
{
missileEveryone(%sourceObject);
%sound = '~wfx/Bonuses/horz_straipass2_heist.wav';
}
Game.recalcScore(%sourceObject.client);
}
// borlak -- make a sound when you hit someone
if(%sound $= "" && %sourceObject.client.team != %targetObject.client.team)
messageClient(%sourceObject.client,'MsgHitSound','~wfx/misc/diagnostic_beep.wav');
else if(%sound !$= "")
messageAll('msgSpecialHitSound', %sound);
// borlak -- rabbit should be able to kill heavies/mediums fast(er) in duel mode
if(%targetObject.client.armor $= "Heavy" || %targetObject.client.armor $= "Medium")
{
if(Game.duelMode && %targetObject != %sourceObject && %sourceObject.holdingFlag)
%amount *= 2;
else
%amount *= 1.5;
}
parent::damageObject(%data, %targetObject, %sourceObject, %position, %amount, %damageType, %momVec, %mineSC);
}
function deployMineCheck(%mineObj, %player)
{
// explode it vgc
schedule(2000, %mineObj, "explodeMine", %mineObj, true);
}
// thanks mista
function MineDeployed:: damageObject(%data, %targetObject, %sourceObject, %position, %amount, %damageType)
{
// NO NIFTY NADE/MINE SCRIPTS
if (Game.duelMode && %damageType == $DamageType::Grenade && $lastObjExplode.isHandNade)
return;
parent:: damageObject(%data, %targetObject, %sourceObject, %position, %amount, %damageType);
}
function MineDeployed::onThrow(%this, %mine, %thrower)
{
%mine.shotFrom = %mine.getWorldBoxCenter();
parent::onThrow(%this, %mine, %thrower);
}
function MineDeployed::onDestroyed(%data, %obj, %lastState)
{
%obj.shotFrom = %obj.getWorldBoxCenter();
%obj.shotSpeed = -1;
$lastObjExplode = %obj;
parent::onDestroyed(%data, %obj, %lastState);
}
function Player::maxInventory(%this, %data)
{
%max = ShapeBase::maxInventory(%this,%data) * 2;
if (%this.getInventory(AmmoPack))
%max += AmmoPack.max[%data.getName()];
return %max;
}
function Player::setKnockback(%this, %val)
{
%this.knockback = %val;
}
};
//exec the AI scripts
//exec("scripts/aiRabbit.cs");
$InvBanList[LakRabbit, "TurretOutdoorDeployable"] = 1;
$InvBanList[LakRabbit, "TurretIndoorDeployable"] = 1;
$InvBanList[LakRabbit, "ElfBarrelPack"] = 1;
$InvBanList[LakRabbit, "MortarBarrelPack"] = 1;
$InvBanList[LakRabbit, "PlasmaBarrelPack"] = 1;
$InvBanList[LakRabbit, "AABarrelPack"] = 1;
$InvBanList[LakRabbit, "MissileBarrelPack"] = 1;
$InvBanList[LakRabbit, "MissileLauncher"] = 1;
$InvBanList[LakRabbit, "MotionSensorDeployable"] = 1;
$InvBanList[LakRabbit, "PulseSensorDeployable"] = 1;
$InvBanList[LakRabbit, "ELFGun"] = 1;
$InvBanList[LakRabbit, "CameraGrenade"] = 1;
$InvBanList[LakRabbit, "FlareGrenade"] = 1;
$InvBanList[LakRabbit, "FlashGrenade"] = 1;
$InvBanList[LakRabbit, "ConcussionGrenade"] = 1;
// PubPro
$InvBanList[LakRabbit, "AmmoPack"] = 1;
$InvBanList[LakRabbit, "CloakingPack"] = 1;
$InvBanList[LakRabbit, "RepairPack"] = 1;
$InvBanList[LakRabbit, "SatchelCharge"] = 1;
$InvBanList[LakRabbit, "SensorJammerPack"] = 1;
$InvBanList[LakRabbit, "ShieldPack"] = 1;
$InvBanList[LakRabbit, "SniperRifle"] = 1;
$InvBanList[LakRabbit, "Chaingun"] = 1;
$InvBanList[LakRabbit, "GrenadeLauncher"] = $Host::LakRabbitPubPro;
$InvBanList[LakRabbit, "ShockLance"] = $Host::LakRabbitPubPro;
$InvBanList[LakRabbit, "Mortar"] = $Host::LakRabbitPubPro;
$InvBanList[LakRabbit, "Grenade"] = $Host::LakRabbitPubPro;
$InvBanList[LakRabbit, "Disc"] = 0;
$InvBanList[LakRabbit, "Plasma"] = 0;
$InvBanList[LakRabbit, "Blaster"] = 0;
$InvBanList[LakRabbit, "EnergyPack"] = 0;
$InvBanList[LakRabbit, "Mine"] = 0;
$InvBanList[LakRabbit, "TargetingLaser"] = 0;
// borlak functions
function TestForMA(%player, %distance)
{
%mask = $TypeMasks::StaticShapeObjectType | $TypeMasks::InteriorObjectType | $TypeMasks::TerrainObjectType;
%rayStart = %player.getWorldBoxCenter();
%rayEnd = getWord(%rayStart, 0) SPC getWord(%rayStart, 1) SPC getWord(%rayStart, 2) - %distance;
%ground = ContainerRayCast(%rayStart, %rayEnd, %mask, 0);
return !%ground;
}
function getSpeed(%obj)
{
return mFloor(VectorLen(%obj.getVelocity())*3.6);
}
function PlayingPlayers()
{
%players = 0;
for (%i = 0; %i < ClientGroup.getCount(); %i++)
{
%cl = ClientGroup.getObject(%i);
if(isObject(%cl.player) && %cl.player.team > 0)
%players++;
}
return %players;
}
function duelBonus(%client)
{
%client.duelSeconds += 12;
if(Game.noSplashDamage)
%client.duelSeconds += 5;
%client.duelKills++;
messageClient(%client, 'MsgDuelBonus', '\c4You now have %1 seconds to live.', %client.duelSeconds);
}
//for(%i = 0; %i < ClientGroup.getCount(); %i++){%target = ClientGroup.getObject(%i).player; if(%target.holdingFlag) missileEveryone(%target);}
// awards/tricks/fun things
function missileEveryone(%attacker)
{
for(%i = 0; %i < ClientGroup.getCount(); %i++)
{
%target = ClientGroup.getObject(%i);
if(!%target.player || %target.player == %attacker)
continue;
%p = ShapeBaseImageData::onFire(MissileLauncherImage,%attacker,0);
MissileSet.add(%p);
%p.setObjectTarget(%target.player);
%attacker.cantFire = "";
}
// make him invincible so he doesn't get killed and ruin the effect!
%attacker.setInvincible(true);
%attacker.schedule(5000, "setInvincible", false);
// give the rabbit some more duel seconds if it's duel mode..
if(Game.duelMode && %attacker.holdingFlag)
%attacker.client.duelSeconds += 15;
}
function killEveryone(%ignore, %message)
{
if(!%message)
messageAll('msgKillEveryone', 'Resetting...');
else
messageAll('msgKillEveryone', %message);
for(%i = 0; %i < ClientGroup.getCount(); %i++)
{
%target = ClientGroup.getObject(%i);
if(!%target.player || %target.player == %ignore)
continue;
%target.player.blowup();
%target.player.scriptKill();
}
}
function checkDuelTimer(%client)
{
%client.duelTimer = schedule(1000, 0, checkDuelTimer, %client);
if(PlayingPlayers() < 2)
return;
%client.duelSeconds--;
%client.duelSecondsCounted++;
if(%client.duelSeconds <= 0)
{
cancel(%client.duelTimer);
messageAll('MsgDuelTimeout', '\c2%1 failed to kill within the alloted time!~wfx/misc/whistle.wav', %client.name);
%client.player.blowup();
%client.player.scriptKill();
}
else
{
if(%client.duelSeconds == 10 || %client.duelSeconds == 5 || %client.duelSeconds <= 3)
{
%plural = (%client.duelSeconds != 1 ? 's' : "");
messageClient(%client, 'MsgDuelTimer', '\c4[Duel Mode] You have %1 second%2 to kill someone, or die!~wfx/misc/red_alert_short.wav', %client.duelSeconds, %plural);
}
}
}
function setFlagDeny(%client, %value)
{
%client.flagDeny = %value;
}
// new "modes" and voting functions
$VoteMessage["VoteDuelMode"] = "turn";
$VoteMessage["VoteSplashDamage"] = "turn";
$VoteMessage["VotePro"] = "turn";
function LakRabbitGame::sendGameVoteMenu( %game, %client, %key )
{
parent::sendGameVoteMenu( %game, %client, %key );
%isAdmin = ( %client.isAdmin || %client.isSuperAdmin );
if( %game.scheduleVote $= "" )
{
if(%isAdmin)
{
if(!Game.duelMode)
messageClient( %client, 'MsgVoteItem', "", %key, 'VoteDuelMode', 'enable duel mode', 'Duel Mode On' );
else
messageClient( %client, 'MsgVoteItem', "", %key, 'VoteDuelMode', 'disable duel mode', 'Duel Mode Off' );
if(!Game.noSplashDamage)
messageClient( %client, 'MsgVoteItem', "", %key, 'VoteSplashDamage', 'disable splash damage', 'Splash Damage Off' );
else
messageClient( %client, 'MsgVoteItem', "", %key, 'VoteSplashDamage', 'enable splash damage', 'Splash Damage On' );
// DeVast - PubPro votes
if(!Game.PubPro)
messageClient( %client, 'MsgVoteItem', "", %key, 'VotePro', 'enable Pro', 'Turn Pro On' );
else
messageClient( %client, 'MsgVoteItem', "", %key, 'VotePro', 'disable Pro', 'Turn Pro Off' );
}
else
{
if(!Game.duelMode)
messageClient( %client, 'MsgVoteItem', "", %key, 'VoteDuelMode', 'Duel Mode on', 'Vote to turn on Duel Mode' );
else
messageClient( %client, 'MsgVoteItem', "", %key, 'VoteDuelMode', 'Duel Mode off', 'Vote to turn off Duel Mode' );
if(!Game.noSplashDamage)
messageClient( %client, 'MsgVoteItem', "", %key, 'VoteSplashDamage', 'Splash Damage Off', 'Vote to turn Splash Damage Off' );
else
messageClient( %client, 'MsgVoteItem', "", %key, 'VoteSplashDamage', 'Splash Damage On', 'Vote to turn Splash Damage On' );
// DeVast - PubPro votes
if(!Game.PubPro)
messageClient( %client, 'MsgVoteItem', "", %key, 'VotePro', 'enable Pro', 'Turn Pro On' );
else
messageClient( %client, 'MsgVoteItem', "", %key, 'VotePro', 'disable Pro', 'Turn Pro Off' );
}
}
}
function LakRabbitGame::evalVote(%game, %typeName, %admin, %arg1, %arg2, %arg3, %arg4)
{
switch$ (%typeName)
{
case "voteDuelMode":
%game.voteDuelMode(%admin, %arg1, %arg2, %arg3, %arg4);
case "voteSplashDamage":
%game.voteSplashDamage(%admin, %arg1, %arg2, %arg3, %arg4);
case "VotePro":
%game.VotePro(%admin, %arg1, %arg2, %arg3, %arg4);
}
parent::evalVote(%game, %typeName, %admin, %arg1, %arg2, %arg3, %arg4);
}
// Zeph - PubPro voting
function LakRabbitGame::VotePro(%game, %admin, %arg1, %arg2, %arg3, %arg4)
{
if(%admin)
{
killeveryone();
if(%game.PubPro)
{
messageAll('MsgAdminForce', '\c2The Admin has disabled Pro.');
$InvBanList[LakRabbit, "GrenadeLauncher"] = 0;
$InvBanList[LakRabbit, "ShockLance"] = 0;
$InvBanList[LakRabbit, "Mortar"] = 0;
$InvBanList[LakRabbit, "Grenade"] = 0;
%game.PubPro = false;
}
else
{
messageAll('MsgAdminForce', '\c2The Admin has enabled Pro.');
$InvBanList[LakRabbit, "GrenadeLauncher"] = 1;
$InvBanList[LakRabbit, "ShockLance"] = 1;
$InvBanList[LakRabbit, "Mortar"] = 1;
$InvBanList[LakRabbit, "Grenade"] = 1;
%game.PubPro = true;
}
}
else
{
%totalVotes = %game.totalVotesFor + %game.totalVotesAgainst;
if(%totalVotes > 0 && (%game.totalVotesFor / ClientGroup.getCount()) > ($Host::VotePasspercent / 100))
{
killeveryone();
if(%game.PubPro)
{
messageAll('MsgVotePassed', '\c2PubPro Disabled.');
$InvBanList[LakRabbit, "GrenadeLauncher"] = 0;
$InvBanList[LakRabbit, "ShockLance"] = 0;
$InvBanList[LakRabbit, "Mortar"] = 0;
$InvBanList[LakRabbit, "Grenade"] = 0;
%game.PubPro = false;
}
else
{
messageAll('MsgVotePassed', '\c2PubPro Enabled.');
$InvBanList[LakRabbit, "GrenadeLauncher"] = 1;
$InvBanList[LakRabbit, "ShockLance"] = 1;
$InvBanList[LakRabbit, "Mortar"] = 1;
$InvBanList[LakRabbit, "Grenade"] = 1;
%game.PubPro = true;
}
}
else
messageAll('MsgVoteFailed', '\c2Mode change did not pass: %1 percent.', mFloor(%game.totalVotesFor/ClientGroup.getCount() * 100));
}
$Host::LakRabbitPubPro = %game.PubPro;
}
function LakRabbitGame::voteDuelMode(%game, %admin, %arg1, %arg2, %arg3, %arg4)
{
if(%admin)
{
killEveryone();
if(%game.duelMode)
{
messageAll('MsgAdminForce', '\c2The Admin has disabled Duel Mode.');
%game.duelMode = false;
}
else
{
messageAll('MsgAdminForce', '\c2The Admin has enabled Duel Mode.');
%game.duelMode = true;
}
}
else
{
%totalVotes = %game.totalVotesFor + %game.totalVotesAgainst;
if(%totalVotes > 0 && (%game.totalVotesFor / ClientGroup.getCount()) > ($Host::VotePasspercent / 100))
{
killEveryone();
if(%game.duelMode)
{
messageAll('MsgVotePassed', '\c2Duel Mode Disabled.');
%game.duelMode = false;
}
else
{
messageAll('MsgVotePassed', '\c2Duel Mode Enabled.');
%game.duelMode = true;
}
}
else
messageAll('MsgVoteFailed', '\c2Mode change did not pass: %1 percent.', mFloor(%game.totalVotesFor/ClientGroup.getCount() * 100));
}
// save
$Host::LakRabbitDuelMode = %game.duelMode;
}
function LakRabbitGame::voteSplashDamage(%game, %admin, %arg1, %arg2, %arg3, %arg4)
{
if(%admin)
{
if(%game.noSplashDamage)
{
messageAll('MsgAdminForce', '\c2The Admin has turned on Splash Damage.');
%game.noSplashDamage = false;
}
else
{
messageAll('MsgAdminForce', '\c2The Admin has turned off Splash Damage.');
%game.noSplashDamage = true;
}
}
else
{
%totalVotes = %game.totalVotesFor + %game.totalVotesAgainst;
if(%totalVotes > 0 && (%game.totalVotesFor / ClientGroup.getCount()) > ($Host::VotePasspercent / 100))
{
if(%game.noSplashDamage)
{
messageAll('MsgVotePassed', '\c2Splash Damage Turned On.');
%game.noSplashDamage = false;
}
else
{
messageAll('MsgVotePassed', '\c2Splash Damage Turned Off.');
%game.noSplashDamage = true;
}
}
else
messageAll('MsgVoteFailed', '\c2Mode change did not pass: %1 percent.', mFloor(%game.totalVotesFor/ClientGroup.getCount() * 100));
}
// save
$Host::LakRabbitNoSplashDamage = %game.noSplashDamage;
}
// new debriefing stuff
function LakRabbitGame::sendDebriefing( %game, %client )
{
messageClient( %client, 'MsgDebriefAddLine', "", '<spush><lmargin:0><color:00dc00><font:Arial:15>PLAYER<lmargin%%:23>SCORE<lmargin%%:34>KILLS<lmargin%%:44>MAS<lmargin%%:52>SPEED<lmargin%%:62>DIST<lmargin%%:70>TOT DIST<lmargin%%:80>SHOCK<lmargin%%:90>SL HITS<spop>' );
// %cl.name, %score, %kills, %mas, %avgSpeed, %avgDistance, %alltotdistance, %shockPercent, %totshockhits
// Scores:
%totscore = 0;
%totkills = 0;
%totmas = 0;
%totspeed = 0;
%totdistance = 0;
//%totchainacc = 0;
//%totsnipepercent= 0;
%totshockpercent= 0;
%speeds = 0;
%dists = 0;
//%chains = 0;
//%snipes = 0;
%shocks = 0;
%alltotdistance = 0;
%totshockhits = 0;
%count = $TeamRank[0, count];
for(%i = 0; %i < %count; %i++)
{
// Send the debrief line:
%cl = $TeamRank[0, %i];
if(%cl.score == 0) %score = 0;
else %score = %cl.score;
if(%cl.kills == 0) %kills = 0;
else %kills = %cl.kills;
if(%cl.mas == 0) %mas = 0;
else %mas = %cl.mas;
//if(%cl.totalSnipes == 0) %cl.totalSnipes = 1;
if(%cl.totalShocks == 0) %cl.totalShocks = 1;
if(%cl.totalSpeed == 0) %avgSpeed = 0;
else %avgSpeed = mFloor(%cl.totalSpeed/%cl.mas);
if(%cl.totalDistance == 0) %avgDistance = 0;
else %avgDistance = mFloor(%cl.totalDistance/%cl.mas);
//if(%cl.totalChainAccuracy == 0) %avgChainAcc = 0;
//else %avgChainAcc = mFloor(%cl.totalChainAccuracy/%cl.totalChainHits);
//if(%cl.totalSnipeHits == 0) %snipePercent = 0;
//else %snipePercent = mFloor(%cl.totalSnipeHits/%cl.totalSnipes*100);
if(%cl.totalShockHits == 0) %shockPercent = 0;
else %shockPercent = mFloor(%cl.totalShockHits/%cl.totalShocks*100);
if(%cl.totalDistance == 0) %othertotdistance = 0;
else %othertotdistance = mFloor(%cl.totalDistance);
if(%cl.totalShockHits == 0) %shockhits = 0;
else %shockhits = mFloor(%cl.totalShockHits);
messageClient( %client, 'MsgDebriefAddLine', "", '<lmargin:0><Font:Arial:14><clip%%:18> %1</clip><lmargin%%:23>%2<lmargin%%:34>%3<lmargin%%:44>%4<lmargin%%:52>%5<lmargin%%:62>%6<lmargin%%:70>%7<lmargin%%:80>%8%%<lmargin%%:90>%9',
%cl.name, %score, %kills, %mas, %avgSpeed, %avgDistance, %othertotdistance, %shockPercent, %shockhits);
if(%score) %totscore += %score;
if(%kills) %totkills += %kills;
if(%mas) %totmas += %mas;
if(%avgSpeed){ %totspeed += %avgSpeed; %speeds++; }
if(%avgDistance){ %totdistance += %avgDistance; %dists++; }
//if(%avgChainAcc){ %totchainacc += %avgChainAcc; %chains++; }
//if(%snipePercent){ %totsnipepercent += %snipePercent; %snipes++; }
if(%shockPercent){ %totshockpercent += %shockPercent; %shocks++; }
if(%othertotdistance){ %alltotdistance += %othertotdistance; }
if(%shockhits){ %totshockhits += %shockhits; }
}
messageClient( %client, 'MsgDebriefAddLine', "", '<spush><lmargin:0><Font:Arial:15><color:00FF7F>%1<lmargin%%:23>%2<lmargin%%:34>%3<lmargin%%:44>%4<lmargin%%:52>%5<lmargin%%:62>%6<lmargin%%:70>%7<lmargin%%:80>%8%%<lmargin%%:90>%9<spop>\n',
" Totals:", %totscore, %totkills, %totmas, mFloor(%totspeed/%speeds), mFloor(%totdistance/%dists), %alltotdistance, mFloor(%totshockpercent/%shocks), %totshockhits);
}
// regular game functions
function LakRabbitGame::setUpTeams(%game)
{
// Force the numTeams variable to one:
DefaultGame::setUpTeams(%game);
%game.numTeams = 1;
setSensorGroupCount(3);
//team damage should always be off for Rabbit
$teamDamage = 0;
//make all the sensor groups visible at all times
if (!Game.teamMode)
{
setSensorGroupAlwaysVisMask($NonRabbitTeam, 0xffffffff);
setSensorGroupAlwaysVisMask($RabbitTeam, 0xffffffff);
// non-rabbits can listen to the rabbit: all others can only listen to self
setSensorGroupListenMask($NonRabbitTeam, (1 << $RabbitTeam) | (1 << $NonRabbitTeam));
}
}
function LakRabbitGame::initGameVars(%game)
{
%game.playerBonusValue = 1;
%game.playerBonusTime = 3 * 1000;
%game.teamBonusValue = 3;
%game.teamBonusTime = 5 * 1000;
%game.flagReturnTime = 25 * 1000;
%game.waypointFrequency = 24000;
%game.waypointDuration = 6000;
%game.duelMode = $Host::LakRabbitDuelMode;
%game.PubPro = $Host::LakRabbitPubPro;
%game.noSplashDamage = $Host::LakRabbitNoSplashDamage;
}
$RabbitTeam = 2;
$NonRabbitTeam = 1;
// ----- These functions supercede those in DefaultGame.cs
function LakRabbitGame::allowsProtectedStatics(%game)
{
return true;
}
function LakRabbitGame::clientMissionDropReady(%game, %client)
{
messageClient(%client, 'MsgClientReady', "", %game.class);
messageClient(%client, 'MsgYourScoreIs', "", 0);
//messageClient(%client, 'MsgYourRankIs', "", -1);
messageClient(%client, 'MsgRabbitFlagStatus', "", $flagStatus);
messageClient(%client, 'MsgMissionDropInfo', '\c0You are in mission %1 (%2).', $MissionDisplayName, $MissionTypeDisplayName, $ServerName );
DefaultGame::clientMissionDropReady(%game,%client);
}
function LakRabbitGame::AIHasJoined(%game, %client)
{
//let everyone know the player has joined the game
//messageAllExcept(%client, -1, 'MsgClientJoinTeam', '%1 has joined the hunt.', %client.name, "", %client, $NonRabbitTeam);
}
function LakRabbitGame::clientJoinTeam( %game, %client, %team, %respawn )
{
%game.assignClientTeam( %client );
// Spawn the player:
%game.spawnPlayer( %client, %respawn );
%game.recalcScore( %client );
}
function LakRabbitGame::assignClientTeam(%game, %client)
{
// all players start on team 1
%client.team = $NonRabbitTeam;
// set player's skin pref here
setTargetSkin(%client.target, %client.skin);
if(%client.kills $= "")
%game.resetScore(%client);
// Let everybody know you are no longer an observer:
messageAll( 'MsgClientJoinTeam', '\c1%1 has joined the hunt.', %client.name, "", %client, %client.team );
updateCanListenState( %client );
}
function LakRabbitGame::playerSpawned(%game, %player)
{
//call the default stuff first...
DefaultGame::playerSpawned(%game, %player);
//find the rabbit
%clRabbit = -1;
for (%i = 0; %i < ClientGroup.getCount(); %i++)
{
%cl = ClientGroup.getObject(%i);
if (isObject(%cl.player) && isObject(%cl.player.holdingFlag))
{
%clRabbit = %cl;
break;
}
}
//now set a waypoint just for that client...
// ilys -- show client waypoint if not showing flag icon
if($Host::ShowFlagIcon == 0 && $Host::ShowFlagTask)
{
cancel(%player.client.waypointSchedule);
if (isObject(%clRabbit) && !%player.client.isAIControlled())
%player.client.waypointSchedule = %game.showRabbitWaypointClient(%clRabbit, %player.client);
}
// borlak -- start with favorites
if(!Game.PubPro) buyFavorites(%player.client);
// Zeph - PubPro weapons
else
{
%player.clearInventory();
%player.setInventory(Disc,1);
%player.setInventory(Blaster,1);
%player.setInventory(Plasma,1);
%player.setInventory(DiscAmmo,30);
%player.setInventory(PlasmaAmmo,80);
%player.setInventory(Mine,6);
%player.setInventory(RepairKit,1);
%player.setInventory(EnergyPack,1);
%player.use("Disc");
}
%player.schedule(250,"selectWeaponSlot", 0);
%player.setEnergyLevel(%player.getDatablock().maxEnergy);
if($Host::EnableLakUnlimitedDJ == 1)
%player.freeDJ = 999; // free diskjump
else
%player.freeDJ = 1; // free diskjump
}
// modified to spawn you near rabbit or flag
function LakRabbitGame::pickTeamSpawn(%game, %team)
{
//find the rabbit
%spawnNear = -1;
for (%i = 0; %i < ClientGroup.getCount(); %i++)
{
%cl = ClientGroup.getObject(%i);
if (isObject(%cl.player) && isObject(%cl.player.holdingFlag))
{
%spawnNear = %cl.player;
break;
}
}
if(!isObject(%spawnNear))
{
for (%i = 0; %i < Team0.getCount(); %i++)
{
%obj = Team0.getObject(%i);
if(%obj.dataBlock $= Flag)
{
%spawnNear = %obj;
if(!%obj.isHome)
break;
}
}
}
for(%i = 0; %i < 25; %i++)
{
%pos = %spawnNear.getWorldBoxCenter();
%randx = getWord(%pos,0)+getRandom(-150,150);
%randy = getWord(%pos,1)+getRandom(-150,150);
%mask = $TypeMasks::StaticShapeObjectType | $TypeMasks::InteriorObjectType | $TypeMasks::TerrainObjectType;
%rayStart = %randx SPC %randy SPC "1000";
%rayEnd = %randx SPC %randy SPC "-1000";
%ground = ContainerRayCast(%rayStart, %rayEnd, %mask, 0);
if(%ground)
{
%loc = getWord(%ground,1) SPC getWord(%ground,2) SPC getWord(%ground,3);
if(isOutOfBounds(%loc))
{
%ground = 0;
continue;
}
break;
}
}
if(%ground)
return %loc;
return "0 0 500";
}
function LakRabbitGame::pickPlayerSpawn(%game, %client, %respawn)
{
// borlak -- reset values at spawn
$LakDamaged[%client] = 0;
%client.duelSecondsCounted = 0;
%client.duelSeconds = 0;
%client.duelKills = 0;
%client.player.lastDamageType = 0;
%client.player.knockback = 0;
cancel(%client.duelTimer);
// all spawns come from team 1
return %game.pickTeamSpawn($NonRabbitTeam);
}
function LakRabbitGame::createPlayer(%game, %client, %spawnLoc, %respawn)
{
%client.team = $NonRabbitTeam;
DefaultGame::createPlayer(%game, %client, %spawnLoc, %respawn);
}
function LakRabbitGame::recalcScore(%game, %client)
{
//score is grabs + kills + (totalTime / 15 seconds);
%timeHoldingFlagMS = %client.flagTimeMS;
if (isObject(%client.player.holdingFlag))
%timeHoldingFlagMS += getSimTime() - %client.startTime;
if(Game.PubPro) %client.score = %client.flagGrabs + (%client.kills*5) + %client.morepoints + mFloor(%timeHoldingFlagMS / 2000);
else %client.score = %client.flagGrabs + %client.kills + %client.morepoints + mFloor(%timeHoldingFlagMS / 2000);
messageClient(%client, 'MsgYourScoreIs', "", %client.score);
%game.recalcTeamRanks(%client);
%game.checkScoreLimit(%client);
}
function LakRabbitGame::onClientDamaged(%game, %clVictim, %clAttacker, %damageType, %sourceObject)
{
//if the victim is the rabbit, and the attacker is not the rabbit, set the damage time...
if (isObject(%clAttacker) && %clAttacker != %clVictim)
{
if (%clVictim.team == $RabbitTeam)
%game.rabbitDamageTime = getSimTime();
}
//call the default
DefaultGame::onClientDamaged(%game, %clVictim, %clAttacker, %damageType, %sourceObject);
}
function LakRabbitGame::onClientKilled(%game, %clVictim, %clKiller, %damageType, %implement, %damageLoc)
{
// borlak - make sure victim isn't killer
if(%clKiller != %clVictim)
{
%clKiller.kills++;
%game.recalcScore(%clKiller);
if($LakDamaged[%clVictim])
%killer = $LakDamaged[%clVictim];
else
%killer = %clKiller;
if(Game.duelMode && %killer.player.holdingFlag && %damageType != $DamageType::Missile)
duelBonus(%killer);
}
// borlak -- flag bug fix
%clVictim.flagDeny = schedule(2500, 0, setFlagDeny, %clVictim, 0);
DefaultGame::onClientKilled(%game, %clVictim, %clKiller, %damageType, %implement, %damageLoc);
}
// z0dd - ZOD, 8/4/02: KineticPoet's flag updater code
function LakRabbitGame::updateFlagTransform(%game, %flag)
{
%flag.setTransform(%flag.getTransform());
%game.updateFlagThread[%flag] = %game.schedule(100, "updateFlagTransform", %flag);
}
function LakRabbitGame::playerDroppedFlag(%game, %player)
{
//set the flag status
%flag = %player.holdingFlag;
%player.holdingFlag = "";
%game.updateFlagTransform(%flag); // z0dd - ZOD, 8/4/02, Call to KineticPoet's flag updater
%flag.carrier = "";
$flagStatus = "<In the Field>";
%player.unmountImage($FlagSlot);
%flag.hide(false);
// ilys -- remove flag icon from player
if($Host::ShowFlagIcon == 1 || $Host::ShowFlagIcon == 2)
{
setTargetSensorGroup(%flag.getTarget(), $NonRabbitTeam);
%player.scopeWhenSensorVisible(false);
%target = %player.getTarget();
setTargetRenderMask(%target, getTargetRenderMask(%target) & ~0x2);
setTargetAlwaysVisMask(%target, (1 << getTargetSensorGroup(%target)));
}
if($Host::ShowFlagIcon == 1)
%flag.scopeWhenSensorVisible(true);
else if($Host::ShowFlagIcon == 2)
%flag.scopeWhenSensorVisible(false);
// borlak -- throw the flag, don't just drop it like dead weight
// v3.1 -- in duel mode, make flag bounce up always, even if player isn't moving.. more midair grabs
%flag.static = false;
%vec = (-1.0 + getRandom() * 2.0) SPC (-1.0 + getRandom() * 2.0) SPC getRandom();
%vec = vectorScale(%vec, 10);
%dot = vectorDot("0 0 1",%eye);
if (%dot < 0)
%dot = -%dot;
%vec = vectorAdd(%vec,vectorScale("0 0 12",1 - %dot));
%vec = vectorAdd(%vec,%player.getVelocity());
if(%game.duelMode && getWord(%vec,2) < 35)
%vec = getWord(%vec, 0) @ " " @ getWord(%vec, 1) @ " 35";
%pos = getBoxCenter(%player.getWorldBox());
%vec = vectorScale(%vec, 75);
%flag.setTransform(%pos);
%flag.applyImpulse(%pos,%vec);
%flag.setCollisionTimeout(%player);
// ilys -- hide waypoint if not showing flag icon
if($Host::ShowFlagIcon == 0 && $Host::ShowFlagTask)
{
cancel(%game.waypointSchedule);
%game.hideRabbitWaypoint(%player.client);
}
//set the client status
%player.client.flagTimeMS += getSimTime() - %player.client.startTime;
%player.client.team = $NonRabbitTeam;
%player.client.setSensorGroup($NonRabbitTeam);
setTargetSensorGroup(%player.getTarget(), $NonRabbitTeam);
messageAllExcept(%player.client, -1, 'MsgRabbitFlagDropped', '\c2%1 dropped the flag!~wfx/misc/flag_drop.wav', %player.client.name);
// if the player left the mission area, he's already been notified
if(!%player.outArea)
messageClient(%player.client, 'MsgRabbitFlagDropped', '\c2You dropped the flag!~wfx/misc/flag_drop.wav');
logEcho(%player.client.nameBase@" (pl "@%player@"/cl "@%player.client@") dropped flag");
%flag.returnThread = %game.schedule(%game.flagReturnTime, "returnFlag", %flag);
// z0dd - ZOD - SquirrelOfDeath, 10/02/02. Hack for flag collision bug.
%flag.searchSchedule = Game.schedule(10, "startFlagCollisionSearch", %flag);
// borlak -- timer fix and re-catch fix
%player.client.flagDeny = schedule(2500, 0, setFlagDeny, %player.client, 0);
cancel(%player.client.duelTimer);
// borlak -- give bonus for duel mode
if(%game.duelMode)
{
if(%player.lastDamageType == $DamageType::Suicide)
{
messageAll('MsgDuelBonus', '\c2%1 suicides and gets no points!', %player.client.name);
return;
}
%points = 0;
for(%i = 1; %i <= %player.client.duelKills; %i++)
%points += (%i*4);
%kills = (%player.client.duelKills*12)+12;
if(%kills <= 0) %kills = 1;
%seconds = %player.client.duelSecondsCounted;
if(%seconds < %player.duelKills*4)
%seconds = %player.duelKills*4;
%points *= %kills / %seconds;
%points = mFloor(%points);
%plural = (%points != 1 ? 's' : "");
%pluralP = (%player.client.duelKills != 1 ? 'people' : 'person');
%pluralSec = (%player.client.duelSecondsCounted != 1 ? 's' : "");
if(%player.client.duelKills == 0)
messageAll('MsgDuelBonus', '\c2%1 kills nobody and gets nothing! Better luck next time....', %player.client.name, %points, %plural, %player.client.duelKills, %player.client.duelSecondsCounted);
else
messageAll('MsgDuelBonus', '\c2%1 gets %2 bonus point%3 for killing %4 %5 in %6 second%7.', %player.client.name, %points, %plural, %player.client.duelKills, %pluralP, %player.client.duelSecondsCounted, %pluralSec);
%player.client.morepoints += %points;
%game.recalcScore(%player.client);
}
}
function LakRabbitGame::playerTouchFlag(%game, %player, %flag)
{
if(%player.getState() $= "Dead" || %player.client.flagDeny)
return;
// borlak - can't pick up flag until 2 ppl are on
if(PlayingPlayers() < 2)
{
//messageClient(%player.client, 'msgNoFlagWarning', "\c2You can't pick up the flag until another person joins." );
return;
}
// borlak -- flag capturing in CTF maps.. extra points.. rabbit mode only
if ((%flag.carrier $= "") && %player.holdingFlag && !%game.duelMode)
{
if(PlayingPlayers() < 6)
{
messageClient(%player.client, 'msgNoFlagWarning', "\c2You can't start capping until there are 6 players." );
return;
}
%points = mFloor((getSimTime() - %player.client.startTime)/2000);
if(%points < 10)
%points = 10; // minimum 10 points
messageAll('MsgRabbitFlagTaken', '\c4%1 gets %2 points for a capturing the flag!~wfx/misc/flipflop_lost.wav', %player.client.name, %points);
%player.client.flagTimeMS += getSimTime() - %player.client.startTime;
%game.resetFlag(%player.holdingFlag);
cancel(%game.updateFlagThread[%flag]); // z0dd - ZOD, 8/4/02. Cancel this flag's thread to KineticPoet's flag updater
}
// check if someone already has other flag.. only one flag can be in play.. also make sure you can only pick up flag that IS in play
%flagInPlay = 0;
for (%i = 0; %i < Team0.getCount(); %i++)
{
%obj = Team0.getObject(%i);
if(%obj.dataBlock $= Flag)
{
if(!%obj.isHome)
%flagInPlay = %obj;
if(!%obj.isHome && %obj.carrier)
{
messageClient(%player.client, 'msgNoFlagWarning', "\c2Only one flag may be in play.");
return;
}
}
}
if(%flagInPlay && %flag != %flagInPlay)
{
messageClient(%player.client, 'msgNoFlagWarning', "\c2You can only pick up the flag in play.");
return;
}
if(%flag.carrier $= "")
{
// borlak cancel flag search and remove free diskjump
cancel(%flag.searchSchedule);
%player.freeDJ = 0;
%flag.bounced = 0;
%player.client.startTime = getSimTime();
%player.holdingFlag = %flag;
%flag.carrier = %player;
%player.mountImage(FlagImage, $FlagSlot, true); //, $teamSkin[$RabbitTeam]);
cancel(%flag.returnThread);
%flag.hide(true);
// ilys -- add flag icon to player
if($Host::ShowFlagIcon == 1 || $Host::ShowFlagIcon == 2)
{
setTargetSensorGroup(%flag.getTarget(), $RabbitTeam);
%player.scopeWhenSensorVisible(true);
%target = %player.getTarget();
setTargetRenderMask(%target, getTargetRenderMask(%target) | 0x2);
setTargetAlwaysVisMask(%target, 0x7);
}
%flag.isHome = false;
$flagStatus = %client.name;
// borlak -- points for MA flag grabs
%mask = $TypeMasks::StaticShapeObjectType | $TypeMasks::InteriorObjectType | $TypeMasks::TerrainObjectType;
%rayStart = %player.getWorldBoxCenter();
%rayEnd = getWord(%rayStart, 0) SPC getWord(%rayStart, 1) SPC getWord(%rayStart, 2) - 5;
%ground = ContainerRayCast(%rayStart, %rayEnd, %mask, 0);
if(!%ground)
{
%points = mFloor((getSpeed(%player)/5.3) + (getHeight(%player)/2.3));
%points = %points > 5 ? %points : 5;
messageAll('MsgRabbitFlagTaken', '\c4%1 gets %2 points for a Mid-Air flag grab! [Speed:%3] [Height:%4]~wfx/misc/hunters_horde.wav', %player.client.name, %points, getSpeed(%player), getHeight(%player));
%player.client.morepoints += %points;
}
else
messageAll('MsgRabbitFlagTaken', '\c2%1 has taken the flag!~wfx/misc/flag_snatch.wav', %player.client.name);
logEcho(%player.client.nameBase@" (pl "@%player@"/cl "@%player.client@") took flag");
%player.client.team = $RabbitTeam;
%player.client.setSensorGroup($RabbitTeam);
setTargetSensorGroup(%player.getTarget(), $RabbitTeam);
//increase the score
%player.client.flagGrabs++;
%game.recalcScore(%player.client);
%game.schedule(5000, "RabbitFlagCheck", %player);
//show the rabbit waypoint
%game.rabbitDamageTime = 0;
// ilys -- waypoint if not showing flag icon
if($Host::ShowFlagIcon == 0 && $Host::ShowFlagTask)
{
cancel(%game.waypointSchedule);
%game.showRabbitWaypoint(%player.client);
}
// borlak - make rabbit invincible for 2 seconds ..
%player.setInvincible(true);
%player.schedule(2000, "setInvincible", false);
// duel mode
if(%game.duelMode)
{
%player.client.duelTimer = schedule(1000, 0, checkDuelTimer, %player.client);
%player.client.duelSeconds = 36 - (PlayingPlayers()*4);
if(PlayingPlayers() == 2 || %game.noSplashDamage)
%player.client.duelSeconds += 10;
if(%player.client.duelSeconds < 20)
%player.client.duelSeconds = 20;
%player.client.duelKills = 0;
}
}
}
function LakRabbitGame::rabbitFlagCheck(%game, %player)
{
// this function calculates the score for the rabbit. It must be done periodically
// since the rabbit's score is based on how long the flag has been in possession.
if((%player.holdingFlag != 0) && (%player.getState() !$= "Dead"))
{
%game.recalcScore(%player.client);
//reschedule this flagcheck for 5 seconds
%game.schedule(5000, "RabbitFlagCheck", %player);
}
}
function LakRabbitGame::returnFlag(%game, %flag)
{
messageAll('MsgRabbitFlagReturned', '\c2The flag was returned to its starting point.~wfx/misc/flag_return.wav');
logEcho("flag return (timeout)");
%game.resetFlag(%flag);
}
function LakRabbitGame::resetFlag(%game, %flag)
{
%flag.setVelocity("0 0 0");
%flag.setTransform(%flag.originalPosition);
%flag.isHome = true;
%flag.carrier = "";
$flagStatus = "<At Home>";
%flag.hide(false);
cancel(%flag.searchSchedule);
cancel(%game.updateFlagThread[%flag]); // z0dd - ZOD, 8/4/02. Cancel this flag's thread to KineticPoet's flag updater
}
// ----- These functions are native to Rabbit
function LakRabbitGame::timeLimitReached(%game)
{
logEcho("game over (timelimit)");
%game.gameOver();
cycleMissions();
}
function LakRabbitGame::scoreLimitReached(%game)
{
logEcho("game over (scorelimit)");
%game.gameOver();
cycleMissions();
}
function LakRabbitGame::checkScoreLimit(%game, %client)
{
%scoreLimit = MissionGroup.Rabbit_scoreLimit;
// default of 1200 if scoreLimit not defined (that's 1200 seconds worth - 20 minutes)
if(%scoreLimit $= "")
%scoreLimit = 2000;
if(%client.score >= %scoreLimit)
%game.scoreLimitReached();
}
function LakRabbitGame::gameOver(%game)
{
// z0dd - ZOD, 9/28/02. Hack for flag collision bug.
for(%f = 1; %f <= %game.numTeams; %f++)
{
cancel($TeamFlag[%f].searchSchedule);
}
//call the default
DefaultGame::gameOver(%game);
//send the message
messageAll('MsgGameOver', "Match has ended.~wvoice/announcer/ann.gameover.wav" );
cancel(%game.rabbitWaypointThread);
messageAll('MsgClearObjHud', "");
for(%i = 0; %i < ClientGroup.getCount(); %i++)
{
%client = ClientGroup.getObject(%i);
%game.resetScore(%client);
// ilys -- cancel waypoint if not showing flag icon
if($Host::ShowFlagIcon == 0 && $Host::ShowFlagTask)
cancel(%client.waypointSchedule);
cancel(%client.duelTimer);
}
// ilys -- cancel waypoint if not showing flag icon
if($Host::ShowFlagIcon == 0 && $Host::ShowFlagTask)
cancel(%game.waypointSchedule);
// borlak -- delete variables
deleteVariables("$LakFired*");
deleteVariables("$LakDamaged*");
}
function LakRabbitGame::resetScore(%game, %client)
{
%client.score = 0;
%client.kills = 0;
%client.deaths = 0;
%client.suicides = 0;
%client.flagGrabs = 0;
%client.flagTimeMS = 0;
%client.morepoints = 0;
// new debriefing stuff
%client.mas = 0;
%client.totalSpeed = 0;
%client.totalDistance = 0;
%client.totalChainAccuracy = 0;
%client.totalChainHits = 0;
%client.totalSnipeHits = 0;
%client.totalSnipes = 0;
%client.totalShockHits = 0;
%client.totalShocks = 0;
}
function LakRabbitGame::enterMissionArea(%game, %playerData, %player)
{
%player.client.outOfBounds = false;
messageClient(%player.client, 'EnterMissionArea', '\c1You are back in the mission area.');
logEcho(%player.client.nameBase@" (pl "@%player@"/cl "@%player.client@") entered mission area");
cancel(%player.alertThread);
}
// borlak -- TAKEN FROM TR2 -- thanks! :D
function plzBounceOffGrid(%obj, %bounceForce, %count)
{
%bounds = MissionArea.area;
%boundsWest = firstWord(%bounds);
%boundsNorth = getWord(%bounds, 1);
%boundsEast = %boundsWest + getWord(%bounds, 2);
%boundsSouth = %boundsNorth + getWord(%bounds, 3);
%shapePos = %obj.getPosition();
%shapex = firstWord(%shapePos);
%shapey = getWord(%shapePos, 1);
if( %shapex >= %boundsWest && %shapex <= %boundsEast && %shapey >= %boundsNorth && %shapey <= %boundsSouth) {
// we don't need to bounce at all
return;
}
if( %count == 8 ) {
// just kill this retard
%obj.scriptKill($DamageType::OutOfBounds);
return;
}
if (%bounceForce $= "")
%bounceForce = 65;
%oldVel = %obj.getVelocity();
%obj.setVelocity("0 0 0");
%vecx = firstWord(%oldVel);
%vecy = getWord(%oldVel, 1);
%vecz = getWord(%oldVel, 2);
// four cases, not two cases you fucktard kineticpoet
// no wonder the trives of vengrances failed
if(%shapex <= %boundsWest) {
%vecx = mAbs(%vecx);
}
else if(%shapex >= %boundsEast) {
%vecx = -mAbs(%vecx);
}
if(%shapey <= %boundsNorth) {
%vecy = mAbs(%vecy);
}
else if(%shapey >= %boundsSouth) {
%vecy = -mAbs(%vecy);
}
%vec = %vecx SPC %vecy SPC %vecz;
// If the object's speed was pretty slow, give it a boost
%oldSpeed = VectorLen(%oldVel);
if (%oldSpeed < 25)
{
%vec = VectorNormalize(%vec);
%vec = VectorScale(%vec, 25);
}
else
%vec = VectorScale(%vec, 1.15);
// apply the impulse to the object
//%obj.applyImpulse(%obj.getWorldBoxCenter(), %vec);
%obj.setVelocity(%vec);
// repeat this bounce 4 times per second. if we're oob for 2 seconds, take action
// don't do this with the flag because that has its own thread
if( %obj.dataBlock !$= "Flag" ) {
schedule(250, 0, plzBounceOffGrid, %obj, %bounceForce, %count + 1);
}
}
function isOutOfBounds(%position)
{
%shapePos = %position;
%shapex = firstWord(%shapePos);
%shapey = getWord(%shapePos, 1);
%bounds = MissionArea.area;
%boundsWest = firstWord(%bounds);
%boundsNorth = getWord(%bounds, 1);
%boundsEast = %boundsWest + getWord(%bounds, 2);
%boundsSouth = %boundsNorth + getWord(%bounds, 3);
return (%shapex < %boundsWest || %shapex > %boundsEast ||
%shapey < %boundsNorth || %shapey > %boundsSouth);
}
function getHeight(%this)
{
%z = getWord(%this.getPosition(), 2);
return mFloor((%z - getTerrainHeight(%this.getPosition())));
}
function LakRabbitGame::leaveMissionArea(%game, %playerData, %player)
{
plzBounceOffGrid(%player, 65);
}
// z0dd - ZOD, 10/02/02. Hack for flag collision bug.
// borlak -- stolen from classic
function LakRabbitGame::startFlagCollisionSearch(%game, %flag)
{
if(isOutOfBounds(%flag.getPosition()))
{
plzBounceOffGrid(%flag, 15);
%flag.bounced++;
if(%flag.bounced >= 25)
{
cancel(%flag.returnThread);
%game.returnFlag(%flag);
}
}
%flag.searchSchedule = %game.schedule(10, "startFlagCollisionSearch", %flag); // SquirrelOfDeath, 10/02/02. Moved from after the while loop
%pos = %flag.getWorldBoxCenter();
InitContainerRadiusSearch( %pos, 1.0, $TypeMasks::VehicleObjectType | $TypeMasks::CorpseObjectType | $TypeMasks::PlayerObjectType );
while((%found = containerSearchNext()) != 0)
{
%flag.getDataBlock().onCollision(%flag, %found);
// SquirrelOfDeath, 10/02/02. Removed break to catch all players possibly intersecting with flag
}
}
function LakRabbitGame::dropFlag(%game, %player)
{
//you can no longer throw the flag in Rabbit...
}
function LakRabbitGame::updateScoreHud(%game, %client, %tag)
{
//tricky stuff here... use two columns if we have more than 15 clients...
%numClients = $TeamRank[0, count];
if ( %numClients > $ScoreHudMaxVisible )
%numColumns = 2;
// Clear the header:
messageClient( %client, 'SetScoreHudHeader', "", "" );
// Send subheader:
if (%numColumns == 2)
messageClient(%client, 'SetScoreHudSubheader', "", '<tab:5,155,225,305,455,525>\tPLAYER\tSCORE\tTIME\tPLAYER\tSCORE\tTIME');
else
messageClient(%client, 'SetScoreHudSubheader', "", '<tab:15,235,335>\tPLAYER\tSCORE\tTIME');
//recalc the score for whoever is holding the flag
if (isObject($AIRabbitFlag.carrier))
%game.recalcScore($AIRabbitFlag.carrier.client);
%countMax = %numClients;
if ( %countMax > ( 2 * $ScoreHudMaxVisible ) )
{
if ( %countMax & 1 )
%countMax++;
%countMax = %countMax / 2;
}
else if ( %countMax > $ScoreHudMaxVisible )
%countMax = $ScoreHudMaxVisible;
for (%index = 0; %index < %countMax; %index++)
{
//get the client info
%col1Client = $TeamRank[0, %index];
%col1ClientScore = %col1Client.score $= "" ? 0 : %col1Client.score;
%col1Style = "";
if (isObject(%col1Client.player.holdingFlag))
{
%col1ClientTimeMS = %col1Client.flagTimeMS + getSimTime() - %col1Client.startTime;
%col1Style = "<color:00dc00>";
}
else
{
%col1ClientTimeMS = %col1Client.flagTimeMS;
if ( %col1Client == %client )
%col1Style = "<color:dcdcdc>";
}
if (%col1ClientTimeMS <= 0)
%col1ClientTime = "";
else
{
%minutes = mFloor(%col1ClientTimeMS / (60 * 1000));
if (%minutes <= 0)
%minutes = "0";
%seconds = mFloor(%col1ClientTimeMS / 1000) % 60;
if (%seconds < 10)
%seconds = "0" @ %seconds;
%col1ClientTime = %minutes @ ":" @ %seconds;
}
//see if we have two columns
if (%numColumns == 2)
{
%col2Client = "";
%col2ClientScore = "";
%col2ClientTime = "";
%col2Style = "";
//get the column 2 client info
%col2Index = %index + %countMax;
if (%col2Index < %numClients)
{
%col2Client = $TeamRank[0, %col2Index];
%col2ClientScore = %col2Client.score $= "" ? 0 : %col2Client.score;
if (isObject(%col2Client.player.holdingFlag))
{
%col2ClientTimeMS = %col2Client.flagTimeMS + getSimTime() - %col2Client.startTime;
%col2Style = "<color:00dc00>";
}
else
{
%col2ClientTimeMS = %col2Client.flagTimeMS;
if ( %col2Client == %client )
%col2Style = "<color:dcdcdc>";
}
if (%col2ClientTimeMS <= 0)
%col2ClientTime = "";
else
{
%minutes = mFloor(%col2ClientTimeMS / (60 * 1000));
if (%minutes <= 0)
%minutes = "0";
%seconds = mFloor(%col2ClientTimeMS / 1000) % 60;
if (%seconds < 10)
%seconds = "0" @ %seconds;
%col2ClientTime = %minutes @ ":" @ %seconds;
}
}
}
//if the client is not an observer, send the message
if (%client.team != 0)
{
if ( %numColumns == 2 )
messageClient( %client, 'SetLineHud', "", %tag, %index, '<tab:10><spush>%7\t<clip:150>%1</clip><rmargin:205><just:right>%2<rmargin:270><just:right>%3<spop><rmargin:505><lmargin:310>%8<just:left>%4<rmargin:505><just:right>%5<rmargin:570><just:right>%6',
%col1Client.name, %col1ClientScore, %col1ClientTime, %col2Client.name, %col2ClientScore, %col2ClientTime, %col1Style, %col2Style );
else
messageClient( %client, 'SetLineHud', "", %tag, %index, '<tab:20>%4\t<clip:200>%1</clip><rmargin:280><just:right>%2<rmargin:375><just:right>%3',
%col1Client.name, %col1ClientScore, %col1ClientTime, %col1Style );
}
//else for observers, create an anchor around the player name so they can be observed
else
{
if ( %numColumns == 2 )
{
//this is really crappy, but I need to save 1 tag - can only pass in up to %9, %10 doesn't work...
if (%col2Style $= "<color:00dc00>")
{
messageClient( %client, 'SetLineHud', "", %tag, %index, '<tab:10><spush>%7\t<clip:150><a:gamelink\t%8>%1</a></clip><rmargin:205><just:right>%2<rmargin:270><just:right>%3<spop><rmargin:505><lmargin:310><color:00dc00><just:left><clip:150><a:gamelink\t%9>%4</a></clip><rmargin:505><just:right>%5<rmargin:570><just:right>%6',
%col1Client.name, %col1ClientScore, %col1ClientTime,
%col2Client.name, %col2ClientScore, %col2ClientTime,
%col1Style, %col1Client, %col2Client );
}
else if (%col2Style $= "<color:dcdcdc>")
{
messageClient( %client, 'SetLineHud', "", %tag, %index, '<tab:10><spush>%7\t<clip:150><a:gamelink\t%8>%1</a></clip><rmargin:205><just:right>%2<rmargin:270><just:right>%3<spop><rmargin:505><lmargin:310><color:dcdcdc><just:left><clip:150><a:gamelink\t%9>%4</a></clip><rmargin:505><just:right>%5<rmargin:570><just:right>%6',
%col1Client.name, %col1ClientScore, %col1ClientTime,
%col2Client.name, %col2ClientScore, %col2ClientTime,
%col1Style, %col1Client, %col2Client );
}
else
{
messageClient( %client, 'SetLineHud', "", %tag, %index, '<tab:10><spush>%7\t<clip:150><a:gamelink\t%8>%1</a></clip><rmargin:205><just:right>%2<rmargin:270><just:right>%3<spop><rmargin:505><lmargin:310><just:left><clip:150><a:gamelink\t%9>%4</a></clip><rmargin:505><just:right>%5<rmargin:570><just:right>%6',
%col1Client.name, %col1ClientScore, %col1ClientTime,
%col2Client.name, %col2ClientScore, %col2ClientTime,
%col1Style, %col1Client, %col2Client );
}
}
else
messageClient( %client, 'SetLineHud', "", %tag, %index, '<tab:20>%4\t<clip:200><a:gamelink\t%5>%1</a></clip><rmargin:280><just:right>%2<rmargin:375><just:right>%3',
%col1Client.name, %col1ClientScore, %col1ClientTime, %col1Style, %col1Client );
}
}
// Tack on the list of observers:
%observerCount = 0;
for (%i = 0; %i < ClientGroup.getCount(); %i++)
{
%cl = ClientGroup.getObject(%i);
if (%cl.team == 0)
%observerCount++;
}
if (%observerCount > 0)
{
messageClient( %client, 'SetLineHud', "", %tag, %index, "");
%index++;
messageClient(%client, 'SetLineHud', "", %tag, %index, '<tab:10, 310><spush><font:Univers Condensed:22>\tOBSERVERS (%1)<rmargin:260><just:right>TIME<spop>', %observerCount);
%index++;
for (%i = 0; %i < ClientGroup.getCount(); %i++)
{
%cl = ClientGroup.getObject(%i);
//if this is an observer
if (%cl.team == 0)
{
%obsTime = getSimTime() - %cl.observerStartTime;
%obsTimeStr = %game.formatTime(%obsTime, false);
messageClient( %client, 'SetLineHud', "", %tag, %index, '<tab:20, 310>\t<clip:150>%1</clip><rmargin:260><just:right>%2',
%cl.name, %obsTimeStr );
%index++;
}
}
}
//clear the rest of Hud so we don't get old lines hanging around...
messageClient( %client, 'ClearHud', "", %tag, %index );
}
function LakRabbitGame::showRabbitWaypointClient(%game, %clRabbit, %client)
{
//make sure we have a rabbit
if (!isObject(%clRabbit) || !isObject(%clRabbit.player) || !isObject(%clRabbit.player.holdingFlag))
return;
//no waypoints for bots
if (%client.isAIControlled())
return;
//scope the client, then set the always vis mask...
%clRabbit.player.scopeToClient(%client);
%visMask = getSensorGroupAlwaysVisMask(%clRabbit.getSensorGroup());
%visMask |= (1 << %client.getSensorGroup());
setSensorGroupAlwaysVisMask(%clRabbit.getSensorGroup(), %visMask);
//now issue a command to kill the target
%client.setTargetId(%clRabbit.target);
commandToClient(%client, 'TaskInfo', %client, -1, false, "Kill the Rabbit!");
%client.sendTargetTo(%client, true);
//send the "waypoint is here sound"
messageClient(%client, 'MsgRabbitWaypoint', '~wfx/misc/target_waypoint.wav');
//and hide the waypoint
%client.waypointSchedule = %game.schedule(%game.waypointDuration, "hideRabbitWaypointClient", %clRabbit, %client);
}
function LakRabbitGame::hideRabbitWaypointClient(%game, %clRabbit, %client)
{
//no waypoints for bots
if (%client.isAIControlled())
return;
//unset the always vis mask...
%visMask = getSensorGroupAlwaysVisMask(%clRabbit.getSensorGroup());
%visMask &= ~(1 << %client.getSensorGroup());
setSensorGroupAlwaysVisMask(%clRabbit.getSensorGroup(), %visMask);
//kill the actually task...
removeClientTargetType(%client, "AssignedTask");
}
function LakRabbitGame::showRabbitWaypoint(%game, %clRabbit)
{
//make sure we have a rabbit
if (!isObject(%clRabbit) || !isObject(%clRabbit.player) || !isObject(%clRabbit.player.holdingFlag))
return;
//only show the rabbit waypoint if the rabbit hasn't been damaged within the frequency period
if (getSimTime() - %game.rabbitDamageTime < %game.waypointFrequency)
{
%game.waypointSchedule = %game.schedule(%game.waypointFrequency, "showRabbitWaypoint", %clRabbit);
return;
}
//loop through all the clients and flash a waypoint at the rabbits position
for (%i = 0; %i < ClientGroup.getCount(); %i++)
{
%cl = ClientGroup.getObject(%i);
if (%cl.isAIControlled() || %cl == %clRabbit || !%cl.player)
continue;
// borlak -- don't make waypoing if client is nearby (mess up aim)
%distance = VectorDist(%clRabbit.player.getWorldBoxCenter(), %cl.player.getWorldBoxCenter());
if(%distance < 100)
continue;
//scope the client, then set the always vis mask...
%clRabbit.player.scopeToClient(%cl);
%visMask = getSensorGroupAlwaysVisMask(%clRabbit.getSensorGroup());
%visMask |= (1 << %cl.getSensorGroup());
setSensorGroupAlwaysVisMask(%clRabbit.getSensorGroup(), %visMask);
//now issue a command to kill the target
%cl.setTargetId(%clRabbit.target);
commandToClient(%cl, 'TaskInfo', %cl, -1, false, "Kill the Rabbit!");
%cl.sendTargetTo(%cl, true);
//send the "waypoint is here sound"
messageClient(%cl, 'MsgRabbitWaypoint', '~wfx/misc/target_waypoint.wav');
}
//schedule the time to hide the waypoint
%game.waypointSchedule = %game.schedule(%game.waypointDuration, "hideRabbitWaypoint", %clRabbit);
}
function LakRabbitGame::hideRabbitWaypoint(%game, %clRabbit)
{
//make sure we have a valid client
if (!isObject(%clRabbit))
return;
//loop through all the clients and hide the waypoint
for (%i = 0; %i < ClientGroup.getCount(); %i++)
{
%cl = ClientGroup.getObject(%i);
if (%cl.isAIControlled())
continue;
//unset the always vis mask...
%visMask = getSensorGroupAlwaysVisMask(%clRabbit.getSensorGroup());
%visMask &= ~(1 << %cl.getSensorGroup());
setSensorGroupAlwaysVisMask(%clRabbit.getSensorGroup(), %visMask);
//kill the actually task...
removeClientTargetType(%cl, "AssignedTask");
}
//make sure we have a rabbit before scheduling the next showRabbitWaypoint...
if (isObject(%clRabbit.player) && isObject(%clRabbit.player.holdingFlag))
%game.waypointSchedule = %game.schedule(%game.waypointFrequency, "showRabbitWaypoint", %clRabbit);
}
function LakRabbitGame::updateKillScores(%game, %clVictim, %clKiller, %damageType, %implement)
{
if(%game.testTurretKill(%implement)) //check for turretkill before awarded a non client points for a kill
%game.awardScoreTurretKill(%clVictim, %implement);
else if (%game.testKill(%clVictim, %clKiller)) //verify victim was an enemy
{
%game.awardScoreKill(%clKiller);
%game.awardScoreDeath(%clVictim);
}
else
{
if (%game.testSuicide(%clVictim, %clKiller, %damageType)) //otherwise test for suicide
{
%game.awardScoreSuicide(%clVictim);
}
else
{
if (%game.testTeamKill(%clVictim, %clKiller)) //otherwise test for a teamkill
%game.awardScoreTeamKill(%clVictim, %clKiller);
}
}
}
function LakRabbitGame::applyConcussion(%game, %player)
{
// MES -- this won't do anything, the function LakRabbitGame::dropFlag is empty
%game.dropFlag( %player );
}