Merge branch 'Dev' into Stable

This commit is contained in:
ChocoTaco 2025-01-11 17:03:10 -05:00
commit f54aa1aabe
19 changed files with 16037 additions and 5581 deletions

View file

@ -442,94 +442,94 @@ addRotationMap("Crater71Lak", "Lakrabbit",1,0,6,-1);
//In Rotation
/////////////////////////////////////////////////////////////////////
addRotationMap("DangerousCrossingLT", "sctf",1,0,-1,-1);
addRotationMap("SmallCrossingLT", "sctf",1,0,-1,12);
addRotationMap("DireLT", "sctf",1,0,-1,-1);
addRotationMap("RoundTheMountainLT", "sctf",1,1,-1,-1);
addRotationMap("CirclesEdgeLT", "sctf",1,1,-1,-1);
addRotationMap("TenebrousCTF", "sctf",1,0,-1,-1);
addRotationMap("TheFray", "sctf",1,0,-1,-1);
addRotationMap("SignalLT", "sctf",1,0,-1,-1);
addRotationMap("S5_DamnationLT", "sctf",1,0,8,-1);
addRotationMap("S5_Icedance", "sctf",1,1,-1,-1);
addRotationMap("S5_Mordacity", "sctf",1,1,10,-1);
addRotationMap("S5_SilenusLT", "sctf",1,0,-1,-1);
addRotationMap("TWL2_CanyonCrusadeDeluxeLT", "sctf",1,1,-1,-1);
addRotationMap("TWL2_HildebrandLT", "sctf",1,1,-1,-1);
addRotationMap("TWL2_SkylightLT", "sctf",1,1,-1,-1);
addRotationMap("TWL_FeignLT", "sctf",1,0,-1,-1);
addRotationMap("TWL_RollercoasterLT", "sctf",1,0,-1,-1);
addRotationMap("TWL_StonehengeLT", "sctf",1,1,-1,-1);
addRotationMap("TWL_WilderZoneLT", "sctf",1,0,-1,-1);
addRotationMap("oasisintensity", "sctf",1,1,-1,10);
addRotationMap("berlard", "sctf",1,1,-1,-1);
addRotationMap("RaindanceLT", "sctf",1,0,-1,-1);
addRotationMap("SmallTimeLT", "sctf",1,0,-1,-1);
addRotationMap("ArenaDome", "sctf",1,1,-1,10);
addRotationMap("Bulwark", "sctf",1,1,-1,-1);
addRotationMap("Discord", "sctf",1,1,-1,-1);
addRotationMap("S5_MassiveLT", "sctf",1,0,-1,-1);
addRotationMap("Blink", "sctf",1,0,-1,-1);
addRotationMap("HillSideLT", "sctf",1,1,-1,10);
addRotationMap("IcePick", "sctf",1,1,-1,16);
addRotationMap("OsIrisLT", "sctf",1,0,-1,-1);
addRotationMap("GrassyKnoll", "sctf",1,1,-1,-1);
addRotationMap("TWL2_MuddySwamp", "sctf",1,0,8,-1);
addRotationMap("SandyRunLT", "sctf",1,0,-1,12);
addRotationMap("Sentry", "sctf",1,1,-1,-1);
addRotationMap("Cinerarium", "sctf",1,1,-1,-1);
addRotationMap("Exhumed", "sctf",1,1,-1,-1);
addRotationMap("S8_ZilchLT", "sctf",1,1,-1,-1);
addRotationMap("TWL_BeachBlitzLT", "sctf",1,0,-1,-1);
addRotationMap("FrozenHopeLT", "sctf",1,1,-1,-1);
//addRotationMap("Confusco", "sctf",1,0,6,-1);
addRotationMap("TWL2_JaggedClawLT", "sctf",1,1,-1,-1);
addRotationMap("DangerousCrossingLT", "LCTF",1,0,-1,-1);
addRotationMap("SmallCrossingLT", "LCTF",1,0,-1,12);
addRotationMap("DireLT", "LCTF",1,0,-1,-1);
addRotationMap("RoundTheMountainLT", "LCTF",1,1,-1,-1);
addRotationMap("CirclesEdgeLT", "LCTF",1,1,-1,-1);
addRotationMap("TenebrousCTF", "LCTF",1,0,-1,-1);
addRotationMap("TheFray", "LCTF",1,0,-1,-1);
addRotationMap("SignalLT", "LCTF",1,0,-1,-1);
addRotationMap("S5_DamnationLT", "LCTF",1,0,8,-1);
addRotationMap("S5_Icedance", "LCTF",1,1,-1,-1);
addRotationMap("S5_Mordacity", "LCTF",1,1,10,-1);
addRotationMap("S5_SilenusLT", "LCTF",1,0,-1,-1);
addRotationMap("TWL2_CanyonCrusadeDeluxeLT", "LCTF",1,1,-1,-1);
addRotationMap("TWL2_HildebrandLT", "LCTF",1,1,-1,-1);
addRotationMap("TWL2_SkylightLT", "LCTF",1,1,-1,-1);
addRotationMap("TWL_FeignLT", "LCTF",1,0,-1,-1);
addRotationMap("TWL_RollercoasterLT", "LCTF",1,0,-1,-1);
addRotationMap("TWL_StonehengeLT", "LCTF",1,1,-1,-1);
addRotationMap("TWL_WilderZoneLT", "LCTF",1,0,-1,-1);
addRotationMap("oasisintensity", "LCTF",1,1,-1,10);
addRotationMap("berlard", "LCTF",1,1,-1,-1);
addRotationMap("RaindanceLT", "LCTF",1,0,-1,-1);
addRotationMap("SmallTimeLT", "LCTF",1,0,-1,-1);
addRotationMap("ArenaDome", "LCTF",1,1,-1,10);
addRotationMap("Bulwark", "LCTF",1,1,-1,-1);
addRotationMap("Discord", "LCTF",1,1,-1,-1);
addRotationMap("S5_MassiveLT", "LCTF",1,0,-1,-1);
addRotationMap("Blink", "LCTF",1,0,-1,-1);
addRotationMap("HillSideLT", "LCTF",1,1,-1,10);
addRotationMap("IcePick", "LCTF",1,1,-1,16);
addRotationMap("OsIrisLT", "LCTF",1,0,-1,-1);
addRotationMap("GrassyKnoll", "LCTF",1,1,-1,-1);
addRotationMap("TWL2_MuddySwamp", "LCTF",1,0,8,-1);
addRotationMap("SandyRunLT", "LCTF",1,0,-1,12);
addRotationMap("Sentry", "LCTF",1,1,-1,-1);
addRotationMap("Cinerarium", "LCTF",1,1,-1,-1);
addRotationMap("Exhumed", "LCTF",1,1,-1,-1);
addRotationMap("S8_ZilchLT", "LCTF",1,1,-1,-1);
addRotationMap("TWL_BeachBlitzLT", "LCTF",1,0,-1,-1);
addRotationMap("FrozenHopeLT", "LCTF",1,1,-1,-1);
//addRotationMap("Confusco", "LCTF",1,0,6,-1);
addRotationMap("TWL2_JaggedClawLT", "LCTF",1,1,-1,-1);
//Voteable, But not in rotation
/////////////////////////////////////////////////////////////////////
addRotationMap("BeggarsRunLT", "sctf",1,0,-1,-1);
addRotationMap("S5_WoodymyrkLT", "sctf",1,0,-1,-1);
addRotationMap("S8_Opus", "sctf",1,0,-1,-1);
addRotationMap("TWL_DangerousCrossing", "sctf",1,0,-1,-1);
addRotationMap("BeggarsRunLT", "LCTF",1,0,-1,-1);
addRotationMap("S5_WoodymyrkLT", "LCTF",1,0,-1,-1);
addRotationMap("S8_Opus", "LCTF",1,0,-1,-1);
addRotationMap("TWL_DangerousCrossing", "LCTF",1,0,-1,-1);
//DMP Mappack
/////////////////////////////////////////////////////////////////////
addRotationMap("AttritionLT", "sctf",1,1,-1,-1);
addRotationMap("RushLT", "sctf",1,1,-1,-1);
addRotationMap("HillKingLT", "sctf",1,1,-1,-1);
addRotationMap("DMP_BastardForgeLT", "sctf",1,1,-1,-1);
addRotationMap("VanDamnedLT", "sctf",1,1,-1,-1);
addRotationMap("DMP_Paranoia", "sctf",1,0,-1,-1);
addRotationMap("DMP_Spincycle", "sctf",1,1,-1,-1);
addRotationMap("Ravine", "sctf",1,1,-1,-1);
// addRotationMap("DX_Badlands", "sctf",1,0,-1,-1);
// addRotationMap("DX_Desert", "sctf",1,0,-1,-1);
addRotationMap("DX_Ice", "sctf",1,1,-1,-1);
addRotationMap("PipeDreamLT", "sctf",1,0,-1,-1);
addRotationMap("DMP_LavaGods", "sctf",1,0,10,20);
addRotationMap("DMP_StarFallLT", "sctf",1,1,-1,-1);
addRotationMap("DMP_BunkeredLT", "sctf",1,1,-1,12);
addRotationMap("DMP_PariahLT", "sctf",1,1,-1,-1);
addRotationMap("AttritionLT", "LCTF",1,1,-1,-1);
addRotationMap("RushLT", "LCTF",1,1,-1,-1);
addRotationMap("HillKingLT", "LCTF",1,1,-1,-1);
addRotationMap("DMP_BastardForgeLT", "LCTF",1,1,-1,-1);
addRotationMap("VanDamnedLT", "LCTF",1,1,-1,-1);
addRotationMap("DMP_Paranoia", "LCTF",1,0,-1,-1);
addRotationMap("DMP_Spincycle", "LCTF",1,1,-1,-1);
addRotationMap("Ravine", "LCTF",1,1,-1,-1);
// addRotationMap("DX_Badlands", "LCTF",1,0,-1,-1);
// addRotationMap("DX_Desert", "LCTF",1,0,-1,-1);
addRotationMap("DX_Ice", "LCTF",1,1,-1,-1);
addRotationMap("PipeDreamLT", "LCTF",1,0,-1,-1);
addRotationMap("DMP_LavaGods", "LCTF",1,0,10,20);
addRotationMap("DMP_StarFallLT", "LCTF",1,1,-1,-1);
addRotationMap("DMP_BunkeredLT", "LCTF",1,1,-1,12);
addRotationMap("DMP_PariahLT", "LCTF",1,1,-1,-1);
//Not Voteable, Not in rotation
/////////////////////////////////////////////////////////////////////
//addRotationMap("SurrealLT", "sctf",1,0,-1,-1);
addRotationMap("DuelersDelight", "sctf",1,0,-1,12);
addRotationMap("SmallSpit", "sctf",1,1,-1,14);
addRotationMap("BonespurLT", "sctf",1,1,-1,14);
addRotationMap("Bridgepoint", "sctf",1,1,-1,14);
addRotationMap("NarcolepsyLT", "sctf",1,1,-1,14);
addRotationMap("WhiteDwarfDeluxeLT", "sctf",1,0,-1,14);
addRotationMap("ClusterUnFuct", "sctf",1,1,8,-1);
addRotationMap("OuterWilds", "sctf",1,1,-1,12);
addRotationMap("Drafts", "sctf",1,1,-1,12);
addRotationMap("DermCrossingDeluxeLT", "sctf",1,1,-1,-1);
addRotationMap("SuperiorWaterworks", "sctf",1,0,-1,12);
addRotationMap("FrozenForgeLT", "sctf",1,1,-1,20);
addRotationMap("TWL2_CelerityLT", "sctf",1,1,-1,20);
addRotationMap("El_Fin", "sctf",1,1,-1,14);
//addRotationMap("SurrealLT", "LCTF",1,0,-1,-1);
addRotationMap("DuelersDelight", "LCTF",1,0,-1,12);
addRotationMap("SmallSpit", "LCTF",1,1,-1,14);
addRotationMap("BonespurLT", "LCTF",1,1,-1,14);
addRotationMap("Bridgepoint", "LCTF",1,1,-1,14);
addRotationMap("NarcolepsyLT", "LCTF",1,1,-1,14);
addRotationMap("WhiteDwarfDeluxeLT", "LCTF",1,0,-1,14);
addRotationMap("ClusterUnFuct", "LCTF",1,1,8,-1);
addRotationMap("OuterWilds", "LCTF",1,1,-1,12);
addRotationMap("Drafts", "LCTF",1,1,-1,12);
addRotationMap("DermCrossingDeluxeLT", "LCTF",1,1,-1,-1);
addRotationMap("SuperiorWaterworks", "LCTF",1,0,-1,12);
addRotationMap("FrozenForgeLT", "LCTF",1,1,-1,20);
addRotationMap("TWL2_CelerityLT", "LCTF",1,1,-1,20);
addRotationMap("El_Fin", "LCTF",1,1,-1,14);
// _____ _ _ _ _

View file

@ -26,32 +26,30 @@ function setArmorDefaults(%armor)
$InvBanList[SCtF, "TurretOutdoorDeployable"] = 1;
$InvBanList[SCtF, "TurretIndoorDeployable"] = 1;
$InvBanList[SCtF, "EnergyPack"] = 0;
$InvBanList[SCtF, "RepairPack"] = 1;
$InvBanList[SCtF, "RepairPack"] = 0;
$InvBanList[SCtF, "SatchelCharge"] = 1;
$InvBanList[SCtF, "SensorJammerPack"] = 1;
$InvBanList[SCtF, "ShieldPack"] = 1;
$InvBanList[SCtF, "TargetingLaser"] = 0;
// Weapons
$InvBanList[SCtF, "Blaster"] = 0;
$InvBanList[SCtF, "Blaster"] = 1;
$InvBanList[SCtF, "Chaingun"] = 0;
$InvBanList[SCtF, "Disc"] = 0;
$InvBanList[SCtF, "ELFGun"] = 1;
$InvBanList[SCtF, "GrenadeLauncher"] = 0;
$InvBanList[SCtF, "MissileBarrelPack"] = 1;
$InvBanList[SCtF, "MissileLauncher"] = 1;
$InvBanList[SCtF, "Mortar"] = 1;
$InvBanList[SCtF, "Plasma"] = 1;
$InvBanList[SCtF, "SniperRifle"] = 1;
$InvBanList[SCtF, "ShockLance"] = 1;
// Misc
$InvBanList[SCtF, "Mine"] = 0;
$InvBanList[SCtF, "ConcussionGrenade"] = 0;
$InvBanList[SCtF, "ConcussionGrenade"] = 1;
$InvBanList[SCtF, "CameraGrenade"] = 1;
$InvBanList[SCtF, "FlareGrenade"] = 1;
$InvBanList[SCtF, "FlashGrenade"] = 1;
$InvBanList[SCtF, "Grenade"] = 0;
//Pro Mode
$InvBanList[SCtF, "ShockLance"] = $Host::SCtFProMode;
$InvBanList[SCtF, "Chaingun"] = $Host::SCtFProMode;
$InvBanList[SCtF, "Plasma"] = $Host::SCtFProMode;
case "Medium": // Set your servers Medium armor bans
// Packs
$InvBanList[SCtF, "TurretOutdoorDeployable"] = 1;

View file

@ -39,9 +39,8 @@ $Host::ClassicConnectLog = 1;
$Host::ClassicConnLogPath = "logs/Connect/Connect.log";
$Host::ClassicCycleMisTypes = 0;
$Host::ClassicDailyHardRestart = 0;
$Host::ClassicDailyHardRestartTime = "10\t00\tam";
$Host::ClassicDailyHardRestartTime = "6\t00\tam";
$Host::ClassicEchoChat = 0;
$Host::ClassicEvoStats = 1;
$Host::ClassicFairTeams = 1;
$Host::ClassicLimitArmors = 0;
$Host::ClassicLoadBlasterChanges = 0;
@ -69,7 +68,6 @@ $Host::ClassicRandomMisTypes = 0;
$Host::ClassicRestartTime = 12;
$Host::ClassicRotationCustom = 1;
$Host::ClassicRotationFile = "prefs/mapRotation.cs";
$Host::ClassicStatsType = 2;
$Host::ClassicSuperAdminPassword = "changeme";
$Host::ClassicSuppressTraversalRootError = 1;
$Host::ClassicTeamKillLog = 1;
@ -116,6 +114,7 @@ $Host::LakRabbitPubPro = 0;
$Host::LakRabbitShowFlagIcon = 1;
$Host::LakRabbitShowFlagTask = 0;
$Host::LakRabbitUnlimitedDJ = 1;
$Host::LCTFProMode = 0;
$Host::LoadingScreenUseDebrief = 1;
$Host::LoadScreenColor1 = "05edad";
$Host::LoadScreenColor2 = "29DEE7";
@ -160,7 +159,6 @@ $Host::PUGautoPassword = 0;
$Host::PUGPassword = "pickup";
$Host::PUGpasswordAlwaysOn = 0;
$Host::PureServer = 0;
$Host::SCtFProMode = 0;
$Host::ServerRules1 = "\c2if\c4(\c3%client.attitude \c4$= \c5\"fun\" \c4&& \c3%client.Llama_Grabs \c4< \c51\c4) {";
$Host::ServerRules2 = " \c1keepTeamsBalanced\c4(\c2%client\c4); \c1dontSwitch2WinningTeam(\c2%client\c4); }";
$Host::ServerRules3 = "\c2else if\c4(\c3%client.attitude \c4$= \c5\"too_serious\"\c4) {";

View file

@ -466,30 +466,6 @@ function CTFGame::playerTouchEnemyFlag(%game, %player, %flag)
if (%startStalemate)
%game.stalemateSchedule = %game.schedule(%game.stalemateTimeMS, beginStalemate);
if($Host::ClassicEvoStats)
{
$stats::grabs[%client]++;
if($stats::grabs[%client] > $stats::grabs_counter)
{
$stats::grabs_counter = $stats::grabs[%client];
$stats::grabs_client = getTaggedString(%client.name);
}
}
if($Host::ClassicEvoStats)
%game.totalFlagHeldTime[%flag] = getSimTime();
}
if($Host::ClassicEvoStats && !%player.flagStatsWait)
{
// get the grab speed
%grabspeed = mFloor(VectorLen(setWord(%player.getVelocity(), 2, 0)) * 3.6);
if(%grabspeed > $stats::MaxGrabSpeed || ($stats::MaxGrabSpeed $= ""))
{
$stats::MaxGrabSpeed = %grabspeed;
$stats::Grabber = getTaggedString(%client.name);
}
}
%flag.hide(true);
@ -552,7 +528,7 @@ function CTFGame::playerLostFlagTarget(%game, %player)
function CTFGame::updateFlagTransform(%game, %flag)
{
%flag.setTransform(%flag.getTransform());
%game.updateFlagThread[%flag] = %game.schedule(100, "updateFlagTransform", %flag);
%game.updateFlagThread[%flag] = %game.schedule(256, "updateFlagTransform", %flag);
}
//----------------------------------------------------------------------------------------
@ -566,8 +542,6 @@ function CTFGame::playerDroppedFlag(%game, %player)
%game.playerLostFlagTarget(%player);
if($Host::ClassicEvoStats)
%game.totalFlagHeldTime[%flag] = 0;
%player.holdingFlag = ""; //player isn't holding a flag anymore
%flag.carrier = ""; //flag isn't held anymore
@ -625,65 +599,6 @@ function CTFGame::flagCap(%game, %player)
%game.playerLostFlagTarget(%player);
if($Host::ClassicEvoStats)
{
%record = false;
%mincheck = false;
if($TotalTeamPlayerCount >= $Host::MinFlagRecordPlayerCount)
%mincheck = true;
if(%game.totalFlagHeldTime[%flag])
{
%held2 = getSimTime() - %game.totalFlagHeldTime[%flag];
%realtime = %game.formatTime(%held2, true);
%tm = %client.team;
if(%tm == 1 || %tm == 2)
{
if((%held2 < $flagstats::heldTeam[%tm]) || $flagstats::heldTeam[%tm] == 0)
{
if(%mincheck)
{
%prevheld2 = $flagstats::heldTeam[%tm];
$flagstats::heldTeam[%tm] = %held2;
$flagstats::realTeam[%tm] = %realTime;
$flagstats::nickTeam[%tm] = %client.nameBase;
}
%record = true;
}
}
if(%record == true)
{
if(%mincheck)
{
%fileOut = "stats/maps/classic/" @ $CurrentMissionType @ "/" @ $CurrentMission @ ".txt";
export("$flagstats::*", %fileOut, false);
if(%prevheld2)
%saved = "\c2Saved: \c3-" @ %game.formatTime(%prevheld2 - %held2, true) @ "\c2";
schedule(4000, 0, "messageAll", 'MsgCTFNewRecord', "\c2It's a new record! Time: \c3"@%realtime@"\c2 " @ %saved @ "~wfx/misc/hunters_horde.wav");
}
else
schedule(4000, 0, "messageClient", %client, '', "\c2New flag records are disabled until" SPC $Host::MinFlagRecordPlayerCount SPC "players.");
}
bottomprint(%client, "You captured the flag in" SPC %realTime SPC "seconds.", 10, 1);
$stats::caps[%client]++;
if($stats::caps[%client] > $stats::caps_counter)
{
$stats::caps_counter = $stats::caps[%client];
$stats::caps_client = getTaggedString(%client.name);
}
if(%held2 < $stats::fastestCap || !$stats::fastestCap)
{
$stats::fastestCap = %held2;
$stats::fastcap_time = %realTime;
$stats::fastcap_client = getTaggedString(%client.name);
}
}
}
//award points to player and team
%teamName = %game.getTeamName(%flag.team);
messageTeamExcept(%client, 'MsgCTFFlagCapped', '\c2%1 captured the %2 flag! (Held: %5)~wfx/misc/flag_capture.wav', %client.name, %teamName, %flag.team, %client.team, %held);
@ -864,7 +779,7 @@ function CTFGame::beginStalemate(%game)
{
messageAll( 'MsgStalemate', "\c3Anti turtle initialized. Flags will be returned to bases in " @ $Host::ClassicAntiTurtleTime @ " minutes.");
%game.turtleSchedule = %game.schedule($Host::ClassicAntiTurtleTime * 60000, "antiTurtle");
error(formatTimeString("HH:nn:ss") SPC "Anti-Turtle thread beginning now - ID:" SPC %game.turtleSchedule);
error(formatTimeString("HH:nn:ss") SPC "Anti-Turtle thread beginning now - ID:" SPC %game.turtleSchedule);
}
}
@ -1312,7 +1227,6 @@ function CTFGame::awardScoreFlagTouch(%game, %cl, %flag)
//tinman - needed to remove all game calls to "eval" for the PURE server...
%game.schedule(%game.TOUCH_DELAY_MS, resetDontScoreTimer, %team);
//schedule(%game.TOUCH_DELAY_MS, 0, eval, "$dontScoreTimer["@%team@"] = false;");
//schedule(%game.TOUCH_DELAY_MS, 0, eval, "$dontScoreTimer["@%team@"] = false;");
$TeamScore[%team] += %game.SCORE_PER_TEAM_FLAG_TOUCH;
messageAll('MsgTeamScoreIs', "", %team, $TeamScore[%team]);
@ -1793,9 +1707,6 @@ function CTFGame::boundaryLoseFlag(%game, %player)
%held = %game.formatTime(getSimTime() - %game.flagHeldTime[%flag], false); // z0dd - ZOD, 8/15/02. How long did player hold flag?
if($Host::ClassicEvoStats)
%game.totalFlagHeldTime[%flag] = 0;
%game.playerDroppedFlag(%player);
// now for the tricky part -- throwing the flag back into the mission area

View file

@ -838,6 +838,10 @@ function DMGame::sendGameVoteMenu(%game, %client, %key)
if(%game.scheduleVote $= "")
{
//echo(%client.ForceVote);
if(%client.ForceVote $= "skip_confirm")
return;
if(!%isAdmin || (%isAdmin && %client.ForceVote))
{
if(!$Host::DMSLOnlyMode)

2524
Classic/scripts/LCTFGame.cs Normal file

File diff suppressed because it is too large Load diff

View file

@ -1170,10 +1170,14 @@ function LakRabbitGame::sendGameVoteMenu( %game, %client, %key )
%isAdmin = ( %client.isAdmin || %client.isSuperAdmin );
if(!%client.canVote && !%isAdmin)
return;
return;
if( %game.scheduleVote $= "" )
{
//echo(%client.ForceVote);
if(%client.ForceVote $= "skip_confirm")
return;
if(!%isAdmin || (%isAdmin && %client.ForceVote))
{
if(!Game.duelMode)
@ -1727,7 +1731,7 @@ function LakRabbitGame::onClientKilled(%game, %clVictim, %clKiller, %damageType,
function LakRabbitGame::updateFlagTransform(%game, %flag)
{
%flag.setTransform(%flag.getTransform());
%game.updateFlagThread[%flag] = %game.schedule(100, "updateFlagTransform", %flag);
%game.updateFlagThread[%flag] = %game.schedule(256, "updateFlagTransform", %flag);
}
function LakRabbitGame::playerDroppedFlag(%game, %player)

724
Classic/scripts/SCtFGame.cs Executable file → Normal file
View file

@ -1,4 +1,4 @@
// DisplayName = LCTF
// DisplayName = Spawn CtF
//--- GAME RULES BEGIN ---
//Prevent enemy from capturing your flag
@ -263,170 +263,34 @@ package SCtFGame
cancel(%obj.lavaEnterThread);
}
function stationTrigger::onEnterTrigger(%data, %obj, %colObj)
{
//make sure it's a player object, and that that object is still alive
if(%colObj.getDataBlock().className !$= "Armor" || %colObj.getState() $= "Dead")
return;
// z0dd - ZOD, 7/13/02 Part of hack to keep people from mounting
// vehicles in disallowed armors.
if(%obj.station.getDataBlock().getName() !$= "StationVehicle")
%colObj.client.inInv = true;
%colObj.inStation = true;
commandToClient(%colObj.client,'setStationKeys', true);
if(Game.stationOnEnterTrigger(%data, %obj, %colObj))
{
//verify station.team is team associated and isn't on player's team
if((%obj.mainObj.team != %colObj.client.team) && (%obj.mainObj.team != 0))
{
//%obj.station.playAudio(2, StationAccessDeniedSound);
messageClient(%colObj.client, 'msgStationDenied', '\c2Access Denied -- Wrong team.~wfx/powered/station_denied.wav');
}
else if(%obj.disableObj.isDisabled())
{
//messageClient(%colObj.client, 'msgStationDisabled', '\c2Station is disabled.');
}
else if(!%obj.mainObj.isPowered())
{
messageClient(%colObj.client, 'msgStationNoPower', '\c2Station is not powered.');
}
else if(%obj.station.notDeployed)
{
messageClient(%colObj.client, 'msgStationNotDeployed', '\c2Station is not deployed.');
}
else if(%obj.station.triggeredBy $= "")
{
if(%obj.station.getDataBlock().setPlayersPosition(%obj.station, %obj, %colObj))
{
messageClient(%colObj.client, 'CloseHud', "", 'inventoryScreen');
commandToClient(%colObj.client, 'TogglePlayHuds', true);
%obj.station.triggeredBy = %colObj;
%obj.station.getDataBlock().stationTriggered(%obj.station, 1);
%colObj.station = %obj.station;
%colObj.lastWeapon = ( %colObj.getMountedImage($WeaponSlot) == 0 ) ? "" : %colObj.getMountedImage($WeaponSlot).item;
%colObj.unmountImage($WeaponSlot);
}
}
}
}
function deployMineCheck(%mineObj, %player)
{
// explode it vgc
schedule(2000, %mineObj, "explodeMine", %mineObj, true);
}
//Take out anything vehicle related
function Armor::damageObject(%data, %targetObject, %sourceObject, %position, %amount, %damageType, %momVec, %mineSC)
{
//error("Armor::damageObject( "@%data@", "@%targetObject@", "@%sourceObject@", "@%position@", "@%amount@", "@%damageType@", "@%momVec@" )");
if(%targetObject.invincible || %targetObject.getState() $= "Dead")
return;
%targetClient = %targetObject.getOwnerClient();
if(isObject(%mineSC))
%sourceClient = %mineSC;
else
%sourceClient = isObject(%sourceObject) ? %sourceObject.getOwnerClient() : 0;
%targetTeam = %targetClient.team;
// if the source object is a player object, player's don't have sensor groups
// if it's a turret, get the sensor group of the target
// if its a vehicle (of any type) use the sensor group
if (%sourceClient)
%sourceTeam = %sourceClient.getSensorGroup();
else if(%damageType == $DamageType::Suicide)
%sourceTeam = 0;
// if teamdamage is off, and both parties are on the same team
// (but are not the same person), apply no damage
if(!$teamDamage && (%targetClient != %sourceClient) && (%targetTeam == %sourceTeam))
return;
if(%targetObject.isShielded && %damageType != $DamageType::Blaster)
%amount = %data.checkShields(%targetObject, %position, %amount, %damageType);
if(%amount == 0)
return;
// Set the damage flash
%damageScale = %data.damageScale[%damageType];
if(%damageScale !$= "")
%amount *= %damageScale;
if(%damageType == $DamageType::Laser && $InvBanList[SctF, "SniperRifle"]) //banned
return;
%flash = %targetObject.getDamageFlash() + (%amount * 2);
if (%flash > 0.75)
%flash = 0.75;
// Teratos: Originally from Eolk? Mine+Disc tracking/death message support.
// No Schedules by DarkTiger Ver.2
%targetClient.mineDisc = false;
switch$(%damageType)
{
case $DamageType::Disc:
if((getSimTime() - %targetClient.mdcTime1) < 256)
%targetClient.mineDisc = true;
%targetClient.mdcTime2 = getSimTime();
case $DamageType::Mine:
if((getSimTime() - %targetClient.mdcTime2) < 256)
%targetClient.mineDisc = true;
%targetClient.mdcTime1 = getSimTime();
}
// -- End Mine+Disc insert.
%previousDamage = %targetObject.getDamagePercent();
%targetObject.setDamageFlash(%flash);
%targetObject.applyDamage(%amount);
Game.onClientDamaged(%targetClient, %sourceClient, %damageType, %sourceObject);
%targetClient.lastDamagedBy = %damagingClient;
%targetClient.lastDamaged = getSimTime();
//now call the "onKilled" function if the client was... you know...
if(%targetObject.getState() $= "Dead")
{
// where did this guy get it?
%damLoc = %targetObject.getDamageLocation(%position);
// should this guy be blown apart?
if( %damageType == $DamageType::Explosion ||
%damageType == $DamageType::Mortar ||
%damageType == $DamageType::SatchelCharge ||
%damageType == $DamageType::Missile )
{
if( %previousDamage >= 0.35 ) // only if <= 35 percent damage remaining
{
%targetObject.setMomentumVector(%momVec);
%targetObject.blowup();
}
}
// If we were killed, max out the flash
%targetObject.setDamageFlash(0.75);
%damLoc = %targetObject.getDamageLocation(%position);
Game.onClientKilled(%targetClient, %sourceClient, %damageType, %sourceObject, %damLoc);
}
else if ( %amount > 0.1 )
{
if( %targetObject.station $= "" && %targetObject.isCloaked() )
{
%targetObject.setCloaked( false );
%targetObject.reCloak = %targetObject.schedule( 500, "setCloaked", true );
}
playPain( %targetObject );
}
}
function ProjectileData::onCollision(%data, %projectile, %targetObject, %modifier, %position, %normal)
{
if(!isObject(%targetObject) && !isObject(%projectile.sourceObject))
return;
if(!(%targetObject.getType() & ($TypeMasks::StaticTSObjectType | $TypeMasks::InteriorObjectType |
$TypeMasks::TerrainObjectType | $TypeMasks::WaterObjectType)))
{
if(%projectile.sourceObject.team !$= %targetObject.team)
{
if(%targetObject.getDataBlock().getClassName() $= "PlayerData" && %data.getName() $= "DiscProjectile")
{
%mask = $TypeMasks::StaticShapeObjectType | $TypeMasks::InteriorObjectType | $TypeMasks::TerrainObjectType;
%start = %targetObject.getWorldBoxCenter();
%distance = mFloor(VectorDist(%start, %projectile.initialPosition));
%end = getWord(%start, 0) SPC getWord(%start, 1) SPC getWord(%start, 2) - 15;
%grounded = ContainerRayCast(%start, %end, %mask, 0);
if(!%grounded)
{
%projectile.sourceObject.client.scoreMidAir++;
messageClient(%projectile.sourceObject.client, 'MsgMidAir', '\c0You received a %1 point bonus for a successful mid air shot.', Game.SCORE_PER_MIDAIR, %data.radiusDamageType, %distance);
messageTeamExcept(%projectile.sourceObject.client, 'MsgMidAir', '\c5%1 hit a mid air shot.', %projectile.sourceObject.client.name, %data.radiusDamageType, %distance);
Game.recalcScore(%projectile.sourceObject.client);
}
}
}
Parent::onCollision(%data, %projectile, %targetObject, %modifier, %position, %normal);
}
}
};
/////////////////////////////////////////////////////////////////////////////////////////
@ -451,8 +315,6 @@ function SCtFGame::missionLoadDone(%game)
echo( "starting camp thread..." );
%game.campThread_1 = schedule( 1000, 0, "checkVehicleCamping", 1 );
%game.campThread_2 = schedule( 1000, 0, "checkVehicleCamping", 2 );
deleteNonSCtFObjects();
}
function SCtFGame::clientMissionDropReady(%game, %client)
@ -484,29 +346,10 @@ function SCtFGame::equip(%game, %player)
%player.client.clearBackpackIcon();
if(!%player.client.isAIControlled())
{
if( !$Host::SCtFProMode )
{
%player.setArmor($Sctf::Armor);
buyDeployableFavorites(%player.client);
%player.setEnergyLevel(%player.getDataBlock().maxEnergy);
%player.selectWeaponSlot( 0 );
}
else
{
%player.clearInventory();
%player.setInventory(Disc,1);
%player.setInventory(Shocklance,1);
%player.setInventory(GrenadeLauncher,1);
%player.setInventory(DiscAmmo, %player.getDataBlock().max[DiscAmmo]);
%player.setInventory(GrenadeLauncherAmmo, %player.getDataBlock().max[GrenadeLauncherAmmo]);
%player.setInventory(Grenade, %player.getDataBlock().max[Grenade]);
%player.setInventory(Mine, %player.getDataBlock().max[Mine]);
%player.setInventory(RepairKit,1);
%player.setInventory(EnergyPack,1);
%player.setInventory(TargetingLaser, 1);
%player.setInventory(Beacon, %player.getDataBlock().max[Beacon]);
%player.use("Disc");
}
%player.setArmor($Sctf::Armor);
buyDeployableFavorites(%player.client);
%player.setEnergyLevel(%player.getDataBlock().maxEnergy);
%player.selectWeaponSlot( 0 );
}
else
{
@ -603,7 +446,6 @@ function SCtFGame::gameOver(%game)
$TeamScore[%j] = 0;
}
/////////////////////////////////////////////////////////////////////////////////////////
// Flag Functions ///////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////
@ -671,6 +513,16 @@ function SCtFGame::playerTouchEnemyFlag(%game, %player, %flag)
%player.mountImage(FlagImage, $FlagSlot, true, %game.getTeamSkin(%flag.team));
%game.playerGotFlagTarget(%player);
//only cancel the return timer if the player is in bounds...
if(!%client.outOfBounds)
{
cancel($FlagReturnTimer[%flag]);
$FlagReturnTimer[%flag] = "";
}
%player.mountImage(FlagImage, $FlagSlot, true, %game.getTeamSkin(%flag.team));
%game.playerGotFlagTarget(%player);
//only cancel the return timer if the player is in bounds...
if (!%client.outOfBounds)
{
@ -693,32 +545,7 @@ function SCtFGame::playerTouchEnemyFlag(%game, %player, %flag)
if (%startStalemate)
%game.stalemateSchedule = %game.schedule(%game.stalemateTimeMS, beginStalemate);
if($Host::ClassicEvoStats)
{
$stats::grabs[%client]++;
if($stats::grabs[%client] > $stats::grabs_counter)
{
$stats::grabs_counter = $stats::grabs[%client];
$stats::grabs_client = getTaggedString(%client.name);
}
}
if($Host::ClassicEvoStats)
%game.totalFlagHeldTime[%flag] = getSimTime();
}
if($Host::ClassicEvoStats && !%player.flagStatsWait)
{
// get the grab speed
%grabspeed = mFloor(VectorLen(setWord(%player.getVelocity(), 2, 0)) * 3.6);
if(%grabspeed > $stats::MaxGrabSpeed || ($stats::MaxGrabSpeed $= ""))
{
$stats::MaxGrabSpeed = %grabspeed;
$stats::Grabber = getTaggedString(%client.name);
}
}
%flag.hide(true);
%flag.startFade(0, 0, false);
%flag.isHome = false;
@ -731,12 +558,12 @@ function SCtFGame::playerTouchEnemyFlag(%game, %player, %flag)
if(%grabspeed)
{
messageTeamExcept(%client, 'MsgCTFFlagTaken', '\c2Teammate %1 took the %2 flag. (Speed: %5Kph)~wfx/misc/flag_snatch.wav', %client.name, %teamName, %flag.team, %client.nameBase, %grabspeed);
messageTeam(%flag.team, 'MsgCTFFlagTaken', '\c2Your flag has been taken by %1! (Speed: %5Kph)~wfx/misc/flag_taken.wav',%client.name, 0, %flag.team, %client.nameBase, %grabspeed);
messageTeam(0, 'MsgCTFFlagTaken', '\c2%1 took the %2 flag. (Speed: %5Kph)~wfx/misc/flag_snatch.wav', %client.name, %teamName, %flag.team, %client.nameBase, %grabspeed);
messageClient(%client, 'MsgCTFFlagTaken', '\c2You took the %2 flag. (Speed: %5Kph)~wfx/misc/flag_snatch.wav', %client.name, %teamName, %flag.team, %client.nameBase, %grabspeed);
messageTeamExcept(%client, 'MsgCTFFlagTaken', '\c2Teammate %1 took the %2 flag. (Speed: %5Kph)~wfx/misc/flag_snatch.wav', %client.name, %teamName, %flag.team, %client.nameBase, %grabspeed);
messageTeam(%flag.team, 'MsgCTFFlagTaken', '\c2Your flag has been taken by %1! (Speed: %5Kph)~wfx/misc/flag_taken.wav',%client.name, 0, %flag.team, %client.nameBase, %grabspeed);
messageTeam(0, 'MsgCTFFlagTaken', '\c2%1 took the %2 flag. (Speed: %5Kph)~wfx/misc/flag_snatch.wav', %client.name, %teamName, %flag.team, %client.nameBase, %grabspeed);
messageClient(%client, 'MsgCTFFlagTaken', '\c2You took the %2 flag. (Speed: %5Kph)~wfx/misc/flag_snatch.wav', %client.name, %teamName, %flag.team, %client.nameBase, %grabspeed);
if(%grabspeed > 300)
if(%grabspeed > 300)
messageAll('', "~wfx/Bonuses/high-level4-blazing.wav");
}
else
@ -779,7 +606,7 @@ function SCtFGame::playerLostFlagTarget(%game, %player)
function SCtFGame::updateFlagTransform(%game, %flag)
{
%flag.setTransform(%flag.getTransform());
%game.updateFlagThread[%flag] = %game.schedule(100, "updateFlagTransform", %flag);
%game.updateFlagThread[%flag] = %game.schedule(256, "updateFlagTransform", %flag);
}
function SCtFGame::playerDroppedFlag(%game, %player)
@ -791,9 +618,6 @@ function SCtFGame::playerDroppedFlag(%game, %player)
%game.playerLostFlagTarget(%player);
if($Host::ClassicEvoStats)
%game.totalFlagHeldTime[%flag] = 0;
%player.holdingFlag = ""; //player isn't holding a flag anymore
%flag.carrier = ""; //flag isn't held anymore
$flagStatus[%flag.team] = "<In the Field>";
@ -849,66 +673,6 @@ function SCtFGame::flagCap(%game, %player)
%held = %game.formatTime(getSimTime() - %game.flagHeldTime[%flag], true); // z0dd - ZOD, 8/15/02. How long did player hold flag?
%game.playerLostFlagTarget(%player);
if($Host::ClassicEvoStats)
{
%record = false;
%mincheck = false;
if($TotalTeamPlayerCount >= $Host::MinFlagRecordPlayerCount)
%mincheck = true;
if(%game.totalFlagHeldTime[%flag])
{
%held2 = getSimTime() - %game.totalFlagHeldTime[%flag];
%realtime = %game.formatTime(%held2, true);
%tm = %client.team;
if(%tm == 1 || %tm == 2)
{
if((%held2 < $flagstats::heldTeam[%tm]) || $flagstats::heldTeam[%tm] == 0)
{
if(%mincheck)
{
%prevheld2 = $flagstats::heldTeam[%tm];
$flagstats::heldTeam[%tm] = %held2;
$flagstats::realTeam[%tm] = %realTime;
$flagstats::nickTeam[%tm] = %client.nameBase;
}
%record = true;
}
}
if(%record == true)
{
if(%mincheck)
{
%fileOut = "stats/maps/classic/" @ $CurrentMissionType @ "/" @ $CurrentMission @ ".txt";
export("$flagstats::*", %fileOut, false);
if(%prevheld2)
%saved = "\c2Saved: \c3-" @ %game.formatTime(%prevheld2 - %held2, true) @ "\c2";
schedule(4000, 0, "messageAll", 'MsgCTFNewRecord', "\c2It's a new record! Time: \c3"@%realtime@"\c2 " @ %saved @ "~wfx/misc/hunters_horde.wav");
}
else
schedule(4000, 0, "messageClient", %client, '', "\c2New flag records are disabled until" SPC $Host::MinFlagRecordPlayerCount SPC "players.");
}
bottomprint(%client, "You captured the flag in" SPC %realTime SPC "seconds.", 10, 1);
$stats::caps[%client]++;
if($stats::caps[%client] > $stats::caps_counter)
{
$stats::caps_counter = $stats::caps[%client];
$stats::caps_client = getTaggedString(%client.name);
}
if(%held2 < $stats::fastestCap || !$stats::fastestCap)
{
$stats::fastestCap = %held2;
$stats::fastcap_time = %realTime;
$stats::fastcap_client = getTaggedString(%client.name);
}
}
}
//award points to player and team
%teamName = %game.getTeamName(%flag.team);
messageTeamExcept(%client, 'MsgCTFFlagCapped', '\c2%1 captured the %2 flag! (Held: %5)~wfx/misc/flag_capture.wav', %client.name, %teamName, %flag.team, %client.team, %held);
@ -916,7 +680,7 @@ function SCtFGame::flagCap(%game, %player)
messageTeam(0, 'MsgCTFFlagCapped', '\c2%1 captured the %2 flag! (Held: %5)~wfx/misc/flag_capture.wav', %client.name, %teamName, %flag.team, %client.team, %held);
messageClient(%client, 'MsgCTFFlagCapped', '\c2You captured the %2 flag! (Held: %5)~wfx/misc/flag_capture.wav', %client.name, %teamName, %flag.team, %client.team, %held); // Yogi, 8/18/02. 3rd param changed 0 -> %client.name
logEcho(%client.nameBase@" (pl "@%player@"/cl "@%client@") capped team "@%client.team@" flag"@" (Held: "@%held@")");
logEcho(%client.nameBase@" (pl "@%player@"/cl "@%client@") capped team "@%client.team@" flag"@" (Held: "@%held@")"); // MP: 6/14/2011 The team is wrong, but the stats program auto-corrects it, so just leave as is
%player.holdingFlag = ""; //no longer holding it.
%player.unMountImage($FlagSlot);
%game.awardScoreFlagCap(%client, %flag);
@ -1083,7 +847,7 @@ function SCtFGame::beginStalemate(%game)
{
messageAll( 'MsgStalemate', "\c3Anti turtle initialized. Flags will be returned to bases in " @ $Host::ClassicAntiTurtleTime @ " minutes.");
%game.turtleSchedule = %game.schedule($Host::ClassicAntiTurtleTime * 60000, "antiTurtle");
error(formatTimeString("HH:nn:ss") SPC "Anti-Turtle thread beginning now - ID:" SPC %game.turtleSchedule);
error(formatTimeString("HH:nn:ss") SPC "Anti-Turtle thread beginning now - ID:" SPC %game.turtleSchedule);
}
}
@ -1095,7 +859,8 @@ function SCtFGame::endStalemate(%game)
cancel(%game.turtleSchedule);
}
function SCtFGame::antiTurtle(%game)
// z0dd - ZOD, 5/27/03. Anti-turtle function
function CTFGame::antiTurtle(%game)
{
if(isEventPending(%game.turtleSchedule))
cancel(%game.turtleSchedule);
@ -1121,7 +886,7 @@ function SCtFGame::flagReset(%game, %flag)
cancel(%game.updateFlagThread[%flag]); // z0dd - ZOD, 8/4/02. Cancel this flag's thread to KineticPoet's flag updater
//any time a flag is reset, kill the stalemate schedule
%game.endStalemate();
%game.endStalemate(%game);
//make sure if there's a player carrying it (probably one out of bounds...), it is stripped first
if (isObject(%flag.carrier))
@ -1161,6 +926,7 @@ function SCtFGame::flagReset(%game, %flag)
{
cancel(%flag.searchSchedule);
}
// --------------------------------------------------------------------------
}
function SCtFGame::notifyMineDeployed(%game, %mine)
@ -1425,7 +1191,7 @@ function SCtFGame::awardScoreFlagTouch(%game, %cl, %flag)
{
%flag.grabber = %cl;
%flag.grabber.flagGrabs++; //moved from awardScoreFlagCap to correctly count flaggrabs
%flag.grabber.flagGrabs++; //moved from awardScoreFlagCap to correctly count flaggrabs
%team = %cl.team;
if( $DontScoreTimer[%team] )
return;
@ -1434,7 +1200,6 @@ function SCtFGame::awardScoreFlagTouch(%game, %cl, %flag)
//tinman - needed to remove all game calls to "eval" for the PURE server...
%game.schedule(%game.TOUCH_DELAY_MS, resetDontScoreTimer, %team);
//schedule(%game.TOUCH_DELAY_MS, 0, eval, "$dontScoreTimer["@%team@"] = false;");
//schedule(%game.TOUCH_DELAY_MS, 0, eval, "$dontScoreTimer["@%team@"] = false;");
$TeamScore[%team] += %game.SCORE_PER_TEAM_FLAG_TOUCH;
messageAll('MsgTeamScoreIs', "", %team, $TeamScore[%team]);
@ -1465,8 +1230,6 @@ function SCtFGame::checkScoreLimit(%game, %team)
function SCtFGame::awardScoreFlagReturn(%game, %cl, %perc)
{
%cl.flagReturns++; //give flagreturn stat
if (%game.SCORE_PER_FLAG_RETURN != 0)
{
%pts = mfloor( %game.SCORE_PER_FLAG_RETURN * (%perc/100) );
@ -1907,9 +1670,6 @@ function SCtFGame::boundaryLoseFlag(%game, %player)
%held = %game.formatTime(getSimTime() - %game.flagHeldTime[%flag], false); // z0dd - ZOD, 8/15/02. How long did player hold flag?
if($Host::ClassicEvoStats)
%game.totalFlagHeldTime[%flag] = 0;
%game.playerDroppedFlag(%player);
// now for the tricky part -- throwing the flag back into the mission area
@ -2206,272 +1966,170 @@ function SCtFGame::startFlagCollisionSearch(%game, %flag)
// VOTING ///////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////
// function SCTFGame::sendGameVoteMenu(%game, %client, %key)
// {
// DefaultGame::sendGameVoteMenu(%game, %client, %key);
// if ( %game.scheduleVote $= "" )
// {
// if(%client.isAdmin)
// messageClient( %client, 'MsgVoteItem', "", %key, 'VoteAntiTurtleTime', 'change the anti turtle time to', 'Change Anti-Turtle time' );
// else
// messageClient( %client, 'MsgVoteItem', "", %key, 'VoteAntiTurtleTime', 'change the anti turtle time to', 'Vote Anti-Turtle time' );
// }
// }
// function SCTFGame::evalVote(%game, %typeName, %admin, %arg1, %arg2, %arg3, %arg4)
// {
// DefaultGame::evalVote(%game, %typeName, %admin, %arg1, %arg2, %arg3, %arg4);
// switch$ (%typeName)
// {
// case "voteAntiTurtleTime":
// %game.voteAntiTurtleTime(%admin, %arg1, %arg2, %arg3, %arg4);
// }
// }
// function SCTFGame::sendAntiTurtleTimeList( %game, %client, %key )
// {
// messageClient( %client, 'MsgVoteItem', "", %key, 6, "", '6 minutes' );
// messageClient( %client, 'MsgVoteItem', "", %key, 8, "", '8 minutes' );
// messageClient( %client, 'MsgVoteItem', "", %key, 10, "", '10 minutes' );
// messageClient( %client, 'MsgVoteItem', "", %key, 12, "", '12 minutes' );
// messageClient( %client, 'MsgVoteItem', "", %key, 14, "", '14 minutes' );
// messageClient( %client, 'MsgVoteItem', "", %key, 16, "", '16 minutes' );
// messageClient( %client, 'MsgVoteItem', "", %key, 18, "", '18 minutes' );
// messageClient( %client, 'MsgVoteItem', "", %key, 200, "", 'Disable Anti Turtle' );
// }
function SCtFGame::sendGameVoteMenu(%game, %client, %key)
{
parent::sendGameVoteMenu( %game, %client, %key );
%isAdmin = ( %client.isAdmin || %client.isSuperAdmin );
if(!%client.canVote && !%isAdmin)
return;
if(%game.scheduleVote $= "")
DefaultGame::sendGameVoteMenu(%game, %client, %key);
if ( %game.scheduleVote $= "" )
{
//echo(%client.ForceVote);
if(%client.ForceVote $= "skip_confirm")
return;
if(!%isAdmin || (%isAdmin && %client.ForceVote))
{
//messageClient( %client, 'MsgVoteItem', "", %key, 'VoteArmorClass', 'change the armor class to', 'Vote to change the Armor class' );
messageClient( %client, 'MsgVoteItem', "", %key, 'VoteArmorClass', 'change the armor class to', 'Vote to change the Armor class' );
//messageClient( %client, 'MsgVoteItem', "", %key, 'VoteAntiTurtleTime', 'change the anti turtle time to', 'Vote Anti-Turtle time' );
if(!$Host::SCtFProMode)
messageClient( %client, 'MsgVoteItem', "", %key, 'SCtFProMode', 'Enable Pro Mode (Disc, SL, GL Only)', 'Vote to enable Pro Mode (Disc, SL, GL Only)' );
else
messageClient( %client, 'MsgVoteItem', "", %key, 'SCtFProMode', 'Disable Pro Mode (Disc, SL, GL Only)', 'Vote to disable Pro Mode (Disc, SL, GL Only)' );
}
else
{
if(!$Host::SCtFProMode)
messageClient( %client, 'MsgVoteItem', "", %key, 'SCtFProMode', 'Enable Pro Mode (Disc, SL, GL Only)', 'Enable Pro Mode (Disc, SL, GL Only)' );
else
messageClient( %client, 'MsgVoteItem', "", %key, 'SCtFProMode', 'Disable Pro Mode (Disc, SL, GL Only)', 'Disable Pro Mode (Disc, SL, GL Only)' );
messageClient( %client, 'MsgVoteItem', "", %key, 'VoteArmorClass', 'change the armor class to', 'Change the Armor class' );
//messageClient( %client, 'MsgVoteItem', "", %key, 'VoteAntiTurtleTime', 'change the anti turtle time to', 'Change Anti-Turtle time' );
}
//messageClient( %client, 'MsgVoteItem', "", %key, 'VoteArmorClass', 'change the armor class to', 'Change the Armor class' );
//messageClient( %client, 'MsgVoteItem', "", %key, 'VoteAntiTurtleTime', 'change the anti turtle time to', 'Change Anti-Turtle time' );
}
}
//function SCtFGame::sendAntiTurtleTimeList( %game, %client, %key )
//{
// messageClient( %client, 'MsgVoteItem', "", %key, 6, "", '6 minutes' );
// messageClient( %client, 'MsgVoteItem', "", %key, 8, "", '8 minutes' );
// messageClient( %client, 'MsgVoteItem', "", %key, 10, "", '10 minutes' );
// messageClient( %client, 'MsgVoteItem', "", %key, 12, "", '12 minutes' );
// messageClient( %client, 'MsgVoteItem', "", %key, 14, "", '14 minutes' );
// messageClient( %client, 'MsgVoteItem', "", %key, 16, "", '16 minutes' );
// messageClient( %client, 'MsgVoteItem', "", %key, 18, "", '18 minutes' );
// messageClient( %client, 'MsgVoteItem', "", %key, 200, "", 'Disable Anti Turtle' );
//}
// function SCtFGame::sendAntiTurtleTimeList( %game, %client, %key )
// {
// messageClient( %client, 'MsgVoteItem', "", %key, 6, "", '6 minutes' );
// messageClient( %client, 'MsgVoteItem', "", %key, 8, "", '8 minutes' );
// messageClient( %client, 'MsgVoteItem', "", %key, 10, "", '10 minutes' );
// messageClient( %client, 'MsgVoteItem', "", %key, 12, "", '12 minutes' );
// messageClient( %client, 'MsgVoteItem', "", %key, 14, "", '14 minutes' );
// messageClient( %client, 'MsgVoteItem', "", %key, 16, "", '16 minutes' );
// messageClient( %client, 'MsgVoteItem', "", %key, 18, "", '18 minutes' );
// messageClient( %client, 'MsgVoteItem', "", %key, 200, "", 'Disable Anti Turtle' );
// }
//function SCtFGame::sendArmorClassList(%game, %client, %key)
//{
// messageClient( %client, 'MsgVoteItem', "", %key, "Light", "", 'Light Class' );
// messageClient( %client, 'MsgVoteItem', "", %key, "Medium", "", 'Medium Class' );
// messageClient( %client, 'MsgVoteItem', "", %key, "Heavy", "", 'Heavy Class' );
//}
function SCtFGame::sendArmorClassList(%game, %client, %key)
{
messageClient( %client, 'MsgVoteItem', "", %key, "Light", "", 'Light Class' );
messageClient( %client, 'MsgVoteItem', "", %key, "Medium", "", 'Medium Class' );
messageClient( %client, 'MsgVoteItem', "", %key, "Heavy", "", 'Heavy Class' );
}
//function serverCmdGetArmorClassList( %client, %key )
//{
// if ( isObject( Game ) )
// Game.sendArmorClassList( %client, %key );
//}
function serverCmdGetArmorClassList( %client, %key )
{
if ( isObject( Game ) )
Game.sendArmorClassList( %client, %key );
}
function SCtFGame::evalVote(%game, %typeName, %admin, %arg1, %arg2, %arg3, %arg4)
{
DefaultGame::evalVote(%game, %typeName, %admin, %arg1, %arg2, %arg3, %arg4);
switch$ (%typeName)
{
//case "voteAntiTurtleTime":
//%game.voteAntiTurtleTime(%admin, %arg1, %arg2, %arg3, %arg4);
//case "VoteArmorClass":
//%game.VoteArmorClass(%admin, %arg1, %arg2, %arg3, %arg4);
case "SCtFProMode":
%game.SCtFProMode(%admin, %arg1, %arg2, %arg3, %arg4);
case "voteAntiTurtleTime":
%game.voteAntiTurtleTime(%admin, %arg1, %arg2, %arg3, %arg4);
case "VoteArmorClass":
%game.VoteArmorClass(%admin, %arg1, %arg2, %arg3, %arg4);
}
parent::evalVote(%game, %typeName, %admin, %arg1, %arg2, %arg3, %arg4);
}
//function SCtFGame::voteAntiTurtleTime(%game, %admin, %newLimit)
//{
// if( %newLimit == 200 )
// %display = "disabled";
// else
// %display = %newLimit;
//
// %cause = "";
// if ( %admin )
// {
// messageAll('MsgAdminForce', '\c3%1\c2 set the anti-turtle time to %2.~wfx/misc/diagnostic_on.wav', $AdminCl.name, %display);
// $Host::ClassicAntiTurtleTime = %newLimit;
// %cause = "(admin)";
// }
// else
// {
// %totalVotes = %game.totalVotesFor + %game.totalVotesAgainst;
// if(%totalVotes > 0 && (%game.totalVotesFor / (ClientGroup.getCount() - $HostGameBotCount)) > ($Host::VotePasspercent / 100))
// {
// messageAll('MsgVotePassed', '\c2The anti-turtle time is set to %1.', %display);
// $Host::ClassicAntiTurtleTime = %newLimit;
// %cause = "(vote)";
// }
// else
// messageAll('MsgVoteFailed', '\c2The vote to change the anti-turtle time did not pass: %1 percent.', mFloor(%game.totalVotesFor/(ClientGroup.getCount() - $HostGameBotCount) * 100));
// }
// if(%cause !$= "")
// logEcho($AdminCl.name @ ": anti-turtle time set to "@%display SPC %cause, 1);
//}
// function SCtFGame::voteAntiTurtleTime(%game, %admin, %newLimit)
// {
// if( %newLimit == 200 )
// %display = "disabled";
// else
// %display = %newLimit;
//function SCtFGame::VoteArmorClass(%game, %admin, %newLimit)
//{
// %cause = "";
// if ( %admin )
// {
// messageAll('MsgAdminForce', '\c3%1\c2 set the armor class to %2.~wfx/misc/diagnostic_on.wav', $AdminCl.name, %newLimit);
// $Sctf::Armor = %newLimit;
// %cause = "(admin)";
// }
// else
// {
// %totalVotes = %game.totalVotesFor + %game.totalVotesAgainst;
// if(%totalVotes > 0 && (%game.totalVotesFor / (ClientGroup.getCount() - $HostGameBotCount)) > ($Host::VotePasspercent / 100))
// {
// messageAll('MsgVotePassed', '\c2The armor class was set to %1.', %newLimit);
// $Sctf::Armor = %newLimit;
// %cause = "(vote)";
// }
// else
// messageAll('MsgVoteFailed', '\c2The vote to change the armor class did not pass: %1 percent.', mFloor(%game.totalVotesFor/(ClientGroup.getCount() - $HostGameBotCount) * 100));
// }
// switch$ ( %newLimit )
// {
// case "Light":
// setArmorDefaults(%newLimit);
//
// case "Medium":
// setArmorDefaults(%newLimit);
//
// case "Heavy":
// setArmorDefaults(%newLimit);
// }
// if(%cause !$= "")
// logEcho($AdminCl.name @ ": armor class set to "@%display SPC %cause, 1);
//}
// %cause = "";
// if ( %admin )
// {
// messageAll('MsgAdminForce', '\c3%1\c2 set the anti-turtle time to %2.~wfx/misc/diagnostic_on.wav', $AdminCl.name, %display);
// $Host::ClassicAntiTurtleTime = %newLimit;
// %cause = "(admin)";
// }
// else
// {
// %totalVotes = %game.totalVotesFor + %game.totalVotesAgainst;
// if(%totalVotes > 0 && (%game.totalVotesFor / (ClientGroup.getCount() - $HostGameBotCount)) > ($Host::VotePasspercent / 100))
// {
// messageAll('MsgVotePassed', '\c2The anti-turtle time is set to %1.', %display);
// $Host::ClassicAntiTurtleTime = %newLimit;
// %cause = "(vote)";
// }
// else
// messageAll('MsgVoteFailed', '\c2The vote to change the anti-turtle time did not pass: %1 percent.', mFloor(%game.totalVotesFor/(ClientGroup.getCount() - $HostGameBotCount) * 100));
// }
// if(%cause !$= "")
// logEcho($AdminCl.name @ ": anti-turtle time set to "@%display SPC %cause, 1);
// }
//function serverCmdArmorDefaults(%client, %armor)
//{
// if(%client.isAdmin)
// {
// Game.VoteArmorClass(true, %armor);
// }
//}
//--------------------------------SCTFProMode--------------------------------
//
$VoteMessage["SCtFProMode"] = "turn";
$InvBanList[SCtF, "Chaingun"] = $Host::SCtFProMode;
$InvBanList[SCtF, "ShockLance"] = $Host::SCtFProMode;
$InvBanList[SCtF, "Plasma"] = $Host::SCtFProMode;
function SCtFGame::SCtFProMode(%game, %admin, %arg1, %arg2, %arg3, %arg4)
function SCtFGame::VoteArmorClass(%game, %admin, %newLimit)
{
if( $countdownStarted && $MatchStarted )
{
if(%admin)
{
killeveryone();
if($Host::SCtFProMode)
{
messageAll('MsgAdminForce', '\c2The Admin has disabled Pro Mode.');
$InvBanList[SCtF, "Chaingun"] = 0;
$InvBanList[SCtF, "ShockLance"] = 0;
$InvBanList[SCtF, "Plasma"] = 0;
$Host::SCtFProMode = false;
}
else
{
messageAll('MsgAdminForce', '\c2The Admin has enabled Pro Mode.');
$InvBanList[SCtF, "Chaingun"] = 1;
$InvBanList[SCtF, "ShockLance"] = 1;
$InvBanList[SCtF, "Plasma"] = 1;
$Host::SCtFProMode = true;
}
}
else
{
%totalVotes = %game.totalVotesFor + %game.totalVotesAgainst;
if(%totalVotes > 0 && (%game.totalVotesFor / ClientGroup.getCount()) > ($Host::VotePasspercent / 100))
{
killeveryone();
if($Host::SCtFProMode)
{
messageAll('MsgVotePassed', '\c2Pro Mode Disabled.');
$InvBanList[SCtF, "Chaingun"] = 0;
$InvBanList[SCtF, "ShockLance"] = 0;
$InvBanList[SCtF, "Plasma"] = 0;
$Host::SCtFProMode = false;
}
else
{
messageAll('MsgVotePassed', '\c2Pro Mode Enabled.');
$InvBanList[SCtF, "Chaingun"] = 1;
$InvBanList[SCtF, "ShockLance"] = 1;
$InvBanList[SCtF, "Plasma"] = 1;
$Host::SCtFProMode = true;
}
}
else
messageAll('MsgVoteFailed', '\c2Mode change did not pass: %1 percent.', mFloor(%game.totalVotesFor/ClientGroup.getCount() * 100));
}
}
}
// For voting to work properly - evo admin.ovl
//
// case "SCtFProMode":
// if( %isAdmin && !%client.ForceVote )
// {
// adminStartNewVote(%client, %typename, %arg1, %arg2, %arg3, %arg4);
// adminLog(%client, " has toggled " @ %arg1 @ " (" @ %arg2 @ ")");
// }
// else
// {
// if(Game.scheduleVote !$= "")
// {
// messageClient(%client, 'voteAlreadyRunning', '\c2A vote is already in progress.');
// return;
// }
// %actionMsg = ($Host::SCtFProMode ? "disable Pro mode" : "enable Pro mode");
// for(%idx = 0; %idx < ClientGroup.getCount(); %idx++)
// {
// %cl = ClientGroup.getObject(%idx);
// if(!%cl.isAIControlled())
// {
// messageClient(%cl, 'VoteStarted', '\c2%1 initiated a vote to %2.', %client.name, %actionMsg);
// %clientsVoting++;
// }
// }
// playerStartNewVote(%client, %typename, %arg1, %arg2, %arg3, %arg4, %clientsVoting);
// }
//AutoRemove assets, sensors, and turrets from non-LT maps
function deleteNonSCtFObjects()
{
%c = 0;
InitContainerRadiusSearch("0 0 0", 9999, $TypeMasks::ItemObjectType |
$TypeMasks::TurretObjectType | $TypeMasks::VehicleObjectType | $TypeMasks::StaticShapeObjectType); //For FF: $TypeMasks::ForceFieldObjectType
while ((%obj = containerSearchNext()) != 0)
%cause = "";
if ( %admin )
{
if(%obj.Datablock !$= "flag" && %obj.Datablock !$= "RepairKit" && %obj.Datablock !$= "RepairPatch" && %obj.Datablock !$= "ExteriorFlagStand" && %obj.Datablock !$= "InteriorFlagStand" && %obj.Datablock !$= "NexusBase") //Dont delete these...
messageAll('MsgAdminForce', '\c3%1\c2 set the armor class to %2.~wfx/misc/diagnostic_on.wav', $AdminCl.name, %newLimit);
$Sctf::Armor = %newLimit;
%cause = "(admin)";
}
else
{
%totalVotes = %game.totalVotesFor + %game.totalVotesAgainst;
if(%totalVotes > 0 && (%game.totalVotesFor / (ClientGroup.getCount() - $HostGameBotCount)) > ($Host::VotePasspercent / 100))
{
%deleteList[%c] = %obj;
%c++;
messageAll('MsgVotePassed', '\c2The armor class was set to %1.', %newLimit);
$Sctf::Armor = %newLimit;
%cause = "(vote)";
}
else
messageAll('MsgVoteFailed', '\c2The vote to change the armor class did not pass: %1 percent.', mFloor(%game.totalVotesFor/(ClientGroup.getCount() - $HostGameBotCount) * 100));
}
for(%i = 0; %i < %c; %i++)
switch$ ( %newLimit )
{
%deleteList[%i].delete();
}
case "Light":
setArmorDefaults(%newLimit);
//Delete all ForceField PhysicalZones (PZones)
// if(isObject(PZones))
// PZones.schedule(1500,"delete");
}
case "Medium":
setArmorDefaults(%newLimit);
case "Heavy":
setArmorDefaults(%newLimit);
}
if(%cause !$= "")
logEcho($AdminCl.name @ ": armor class set to "@%display SPC %cause, 1);
}
function serverCmdArmorDefaults(%client, %armor)
{
if(%client.isAdmin)
{
Game.VoteArmorClass(true, %armor);
}
}

99
Classic/scripts/aiLCTF.cs Normal file
View file

@ -0,0 +1,99 @@
//-----------------------------------------------
// AI functions for Spawn CtF >> LCTF
function LCTFGame::onAIRespawn(%game, %client)
{
//add the default task
if (! %client.defaultTasksAdded)
{
%client.defaultTasksAdded = true;
%client.addTask(AIEngageTask);
%client.addTask(AIPickupItemTask);
%client.addTask(AITauntCorpseTask);
%client.addtask(AIEngageTurretTask);
%client.addtask(AIDetectMineTask);
%client.addtask(AIDetectRemeqTask); // -- Lagg... ---- 1-9-2003
%client.addtask(AIPilotTask); // BotPilot: Josef "Werewolf" Jahn
}
}
function LCTFGame::AIInit(%game)
{
// load external objectives files
loadObjectives();
for (%i = 1; %i <= %game.numTeams; %i++)
{
if (!isObject($ObjectiveQ[%i]))
{
$ObjectiveQ[%i] = new AIObjectiveQ();
MissionCleanup.add($ObjectiveQ[%i]);
}
error("team " @ %i @ " objectives load...");
$ObjectiveQ[%i].clear();
AIInitObjectives(%i, %game);
}
//call the default AIInit() function
AIInit();
}
function LCTFGame::AIplayerCaptureFlipFlop(%game, %player, %flipFlop)
{
}
function LCTFGame::AIplayerTouchEnemyFlag(%game, %player, %flag)
{
}
function LCTFGame::AIplayerTouchOwnFlag(%game, %player, %flag)
{
}
function LCTFGame::AIflagCap(%game, %player, %flag)
{
//signal the flag cap event
AIRespondToEvent(%player.client, 'EnemyFlagCaptured', %player.client);
// MES - changed above line - did not pass args in correct order
}
function LCTFGame::AIplayerDroppedFlag(%game, %player, %flag)
{
}
function LCTFGame::AIflagReset(%game, %flag)
{
}
function LCTFGame::onAIDamaged(%game, %clVictim, %clAttacker, %damageType, %implement)
{
if (%clAttacker && %clAttacker != %clVictim && %clAttacker.team == %clVictim.team)
{
schedule(250, %clVictim, "AIPlayAnimSound", %clVictim, %clAttacker.player.getWorldBoxCenter(), "wrn.watchit", -1, -1, 0);
//clear the "lastDamageClient" tag so we don't turn on teammates... unless it's uberbob!
%clVictim.lastDamageClient = -1;
}
}
function LCTFGame::onAIKilledClient(%game, %clVictim, %clAttacker, %damageType, %implement)
{
if (%clVictim.team != %clAttacker.team)
DefaultGame::onAIKilledClient(%game, %clVictim, %clAttacker, %damageType, %implement);
}
function LCTFGame::onAIKilled(%game, %clVictim, %clAttacker, %damageType, %implement)
{
DefaultGame::onAIKilled(%game, %clVictim, %clAttacker, %damageType, %implement);
}
function LCTFGame::onAIFriendlyFire(%game, %clVictim, %clAttacker, %damageType, %implement)
{
if (%clAttacker && %clAttacker.team == %clVictim.team && %clAttacker != %clVictim && !%clVictim.isAIControlled())
{
// The Bot is only a little sorry:
if ( getRandom() > 0.9 )
AIMessageThread("ChatSorry", %clAttacker, %clVictim);
}
}

View file

@ -1,428 +0,0 @@
// Eolk - People like evo's stats a lot... so that's what we'll give them...
$weap_message[1] = "Blaster master";
$weap_message[2] = "Plasma roaster";
$weap_message[3] = "Chainwh0re";
$weap_message[4] = "Disc-O-maniac";
$weap_message[5] = "Grenade puppy";
$weap_message[6] = "Laser turret";
$weap_message[8] = "Mortar maniac";
$weap_message[9] = "Missile lamer";
$weap_message[10] = "Shocklance bee";
$weap_message[11] = "Mine mayhem";
$weap_message[13] = "Road killer";
// Extra Stats
$weap_message[31] = "Demoman";
$weap_message[21] = "Clamp Farmer";
$weap_message[22] = "Spike Farmer";
$weap_message[26] = "Shrike Gunner";
$weap_message[27] = "Tailgunner";
$weap_message[28] = "Bombardier";
$weap_message[29] = "Tank Gunner (chain)";
$weap_message[30] = "Tank Gunner (mortar)";
$weap_message[31] = "Satchel Punk";
$weap_message[50] = "Combo King (mine+disc)";
// Handlers
package EvoStatHandles
{
function Armor::damageObject(%data, %targetObject, %sourceObject, %position, %amount, %damageType, %momVec, %mineSC)
{
Parent::damageObject(%data, %targetObject, %sourceObject, %position, %amount, %damageType, %momVec, %mineSC);
// call the function
if($Host::ClassicEvoStats)
handleDamageStat(%data, %targetObject, %sourceObject, %position, %amount, %damageType, %momVec, %mineSC);
}
function DefaultGame::onClientKilled(%game, %clVictim, %clKiller, %damageType, %implement, %damageLocation)
{
Parent::onClientKilled(%game, %clVictim, %clKiller, %damageType, %implement, %damageLocation);
// call the function
if($Host::ClassicEvoStats)
handleKillStat(%game, %clVictim, %clKiller, %damageType, %implement, %damageLocation);
}
function ProjectileData::onCollision(%data, %projectile, %targetObject, %modifier, %position, %normal)
{
if(isObject(%targetObject)) // Console spam fix.
{
// call the function
if($Host::ClassicEvoStats)
handleMAStat(%data, %projectile, %targetObject, %modifier, %position, %normal);
}
Parent::onCollision( %data, %projectile, %targetObject, %modifier, %position, %normal );
}
};
// Prevent package from being activated if it is already
if (!isActivePackage(EvoStatHandles))
activatePackage(EvoStatHandles);
// handleDamageStat(%targetObject, %sourceObject, %position, %amount, %damageType)
// Info: Calcs: Damage and SnipeShot detection.
function handleDamageStat(%data, %targetObject, %sourceObject, %position, %amount, %damageType, %momVec, %mineSC)
{
// Reject damage that is not player initiated.
if(%damageType == 7 || %damageType == 12 || %damageType == 14 || %damageType == 24 || %damageType == 25 || %damageType == 33 || %damageType == 35 || %damageType == 36 || %damageType == 98 || %damageType == 99)
return;
// failsafe
if(!isObject(%sourceObject) || %sourceObject $= "" || !isObject(%targetObject) || %targetObject $= "")
return;
// don't count damage done to vehicles
if(%targetObject.isMounted())
return;
// Vehicle Impacts.
if(%damageType == 13){ // run down by vehicle
if(!(%attacker = %sourceObject.getControllingClient()) > 0){
return;
}
}
// Turrets.
else if(%sourceObject.getClassName() $= "Turret" || %sourceObject.getClassName() $= "VehicleTurret" || %sourceObject.getClassName() $= "FlyingVehicle" || %sourceObject.getClassName() $= "HoverVehicle"){
// Controlled
%attacker = %sourceObject.getControllingClient(); //is turret being controlled?
if(%attacker == 0){ // Not controlled.
// Owned
if(isObject(%sourceObject.owner)){
%attacker = %sourceObject.owner;
}
// Automated & no-owner.
else{
return;
}
}
} else { // Pretty much anything else.
%attacker = %sourceObject.client;
}
%victim = %targetObject.client;
// failsafe
if(%attacker $= "" || %victim $= "" || %attacker $= %victim)
return;
// check if it's a tk
if(Game.numTeams > 1 && %attacker.team $= %victim.team)
return;
// store the damage
if($Host::ClassicStatsType == 2)
{
// Teratos: Going to add mine+disc as a category...
// Teratos: Tracking only gets the second batch of damage, but we add 85% of that to make up for the first batch of damage (just a dumb estimate so damage numbers look realistic in post-game).
if(%victim.mineDisc) {
//$stats::weapon_damage[%attacker, 50] += %amount + (%amount * (%damageType == 11 ? 0.87 : 1.41)); // Mine accounts for more than disc.
$stats::weapon_damage[%attacker, 50] += %amount + $stats::last_minedisc[%attacker];
if($stats::weapon_damage[%attacker, 50] > $stats::weap_table[50])
{
$stats::weap_table[50] = $stats::weapon_damage[%attacker, 50];
$stats::client_weap_table[50] = getTaggedString(%attacker.name);
}
}
$stats::last_minedisc[%attacker] = %amount; // Track the last amount of damage so we can add it to the mine+disc.
// Teratos: END Mine+Disc Support.
$stats::weapon_damage[%attacker, %damageType] += %amount;
if($stats::weapon_damage[%attacker, %damageType] > $stats::weap_table[%damageType])
{
$stats::weap_table[%damageType] = $stats::weapon_damage[%attacker, %damageType];
$stats::client_weap_table[%damageType] = getTaggedString(%attacker.name);
}
}
// is it a laser damage?
if(%damageType == 6)
{
// i will consider only shots that have been fired with 60% of total energy
if(%sourceObject.getEnergyLevel() / %sourceObject.getDataBlock().maxEnergy < 0.6)
return;
%distance = mFloor(VectorDist(%position, %sourceObject.getWorldBoxCenter()));
// max distance for sniper (this is the only fix i could find)
// if(%distance > 1000)
// %distance = 1000;
// is it an headshot?
if(%victim.headshot)
{
%attacker.hs++;
if( ( %attacker.showMA $= "" ) || ( %attacker.showMA == 1 ) )
bottomPrint(%attacker, "HEADSHOT (" @ %attacker.hs @ ")! Distance is " @ %distance @ " meters.", 3);
logEcho(%attacker.nameBase @" (pl "@%attacker.player@"/cl "@%attacker@") headshot ("@%distance@")");
if(%attacker.hs > $stats::snipe_counter)
{
$stats::snipe_counter = %attacker.hs;
$stats::snipe_client = getTaggedString(%attacker.name);
}
if(%distance > $stats::snipe_maxdistance)
{
$stats::snipe_maxdistance = %distance;
$stats::snipe_maxdistanceclient = getTaggedString(%attacker.name);
}
}
else // no
{
if(%attacker.showMA $= "" || %attacker.showMA)
bottomPrint(%attacker, "HIT! Distance is " @ %distance @ " meters.", 3);
if(%distance > $stats::snipe_maxdistance)
{
$stats::snipe_maxdistance = %distance;
$stats::snipe_maxdistanceclient = getTaggedString(%attacker.name);
}
}
// this callback will allow players to autoscreenshot the shot
messageClient(%attacker, 'MsgSnipeShot', "", %distance);
}
}
// handleKillStat(%clVictim, %clKiller, %damageType, %implement)
// Info: Calcs: Kills, TeamKills, FC kills
function handleKillStat(%game, %clVictim, %clKiller, %damageType, %implement, %damageLocation)
{
if(%damageType == 13) // is a roadkill
%clKiller = %implement.getControllingClient();
if ( !isObject( %clVictim ) || !isObject( %clKiller ) )
return;
// failsafe
if(%clKiller $= "" || %clVictim $= "" || %clKiller $= %clVictim)
return;
// is it a tk?
if(%game.numTeams > 1 && %clKiller.team $= %clVictim.team)
{
$stats::tk[%clKiller]++;
if($stats::tk[%clKiller] > $stats::tk_counter)
{
$stats::tk_counter = $stats::tk[%clKiller];
$stats::tk_client = getTaggedString(%clKiller.name);
}
}
else // no
{
if($Host::ClassicStatsType == 1)
{
$stats::weapon_kills[%clKiller, %damageType]++;
if($stats::weapon_kills[%clKiller, %damageType] > $stats::weap_table[%damageType])
{
$stats::weap_table[%damageType] = $stats::weapon_kills[%clKiller, %damageType];
$stats::client_weap_table[%damageType] = getTaggedString(%clKiller.name);
}
}
// was the victim a fc?
if(%clVictim.plyrDiedHoldingFlag)
{
$stats::fckiller[%clKiller]++;
if($stats::fckiller[%clKiller] > $stats::fckiller_counter)
{
$stats::fckiller_counter = $stats::fckiller[%clKiller];
$stats::fckiller_client = getTaggedString(%clKiller.name);
}
}
}
}
// handleMAStat(%projectile, %targetObject, %position)
// Info: MA detection
function handleMAStat(%data, %projectile, %targetObject, %modifier, %position, %normal)
{
// failsafe
if(!isObject(%targetObject) || %targetObject $= "")
return;
// failsafe
if(!isObject(%projectile.sourceObject) || %projectile.sourceObject $= "")
return;
%victim = %targetObject.client;
%killer = %projectile.sourceObject.client;
// // Altair's method
// %distance = mFloor(VectorDist(%position, %projectile.sourceObject.getWorldBoxCenter()));
// // Evolution Method
%distance = mFloor(VectorDist(%position, %projectile.initialPosition));
// failsafe
if(%victim $= "" || %killer $= "")
return;
%projectileType = %data.getName() !$= "TR2DiscProjectile" ? %data.getName() : "DiscProjectile";
// only disc, plasma, or blaster
if(%projectileType !$= "DiscProjectile" && %projectileType !$= "PlasmaBolt" && %projectileType !$= "EnergyBolt")
return;
// is it a tk?
if(Game.numTeams > 1 && %killer.team $= %victim.team)
return;
// Eolk - changes to MA code
%position = %targetObject.getPosition();
%raycast = containerRaycast(%position, vectorAdd(%position, "0 0 -10"), $TypeMasks::ForceFieldObjectType | $TypeMasks::InteriorObjectType | $TypeMasks::StaticObjectType | $TypeMasks::TerrainObjectType, %targetObject);
if(!isObject(firstWord(%raycast))) // We've got something...
{
switch$(%projectileType)
{
case DiscProjectile:
%killer.midairs++;
if( ( %killer.showMA $= "" ) || ( %killer.showMA == 1 ) )
bottomPrint(%killer, "Midair Disk (" @ %killer.midairs @ ")! Distance is " @ %distance @ " meters.", 3);
// this callback will allow players to autoscreenshot the MA
messageClient(%killer, 'MsgMidAir', "", %distance);
logEcho(%killer.nameBase @" (pl "@%killer.player@"/cl "@%killer@") hit a midair disc shot ("@%distance@")");
if(%killer.midairs > $stats::ma_counter)
{
$stats::ma_counter = %killer.midairs;
$stats::ma_client = getTaggedString(%killer.name);
}
if(%distance > $stats::ma_maxdistance)
{
$stats::ma_maxdistance = %distance;
$stats::ma_maxdistanceclient = getTaggedString(%killer.name);
}
case PlasmaBolt:
%killer.PlaMA++;
if ( ( %killer.showMA $= "" ) || ( %killer.showMA == 1 ) )
bottomPrint(%killer, "Midair Plasma (" @ %killer.PlaMA @ ")! Distance is " @ %distance @ " meters.", 3);
// this callback will allow players to autoscreenshot the MA
messageClient(%killer, 'MsgPlasmaMidAir', "", %distance);
logEcho(%killer.nameBase @" (pl "@%killer.player@"/cl "@%killer@") hit a midair plasma shot ("@%distance@")");
if(%killer.PlaMA > $stats::PlaMA_counter)
{
$stats::PlaMA_counter = %killer.PlaMA;
$stats::PlaMA_client = getTaggedString(%killer.name);
}
if(%distance > $stats::PlaMA_maxdistance)
{
$stats::PlaMA_maxdistance = %distance;
$stats::PlaMA_maxdistanceclient = getTaggedString(%killer.name);
}
case EnergyBolt:
%killer.blaMA++;
if( ( %killer.showMA $= "" ) || ( %killer.showMA == 1 ) )
bottomPrint(%killer, "Midair Blaster (" @ %killer.blaMA @ ")! Distance is " @ %distance @ " meters.", 3);
// this callback will allow players to autoscreenshot the MA
messageClient(%killer, 'MsgBlasterMidAir', "", %distance);
logEcho(%killer.nameBase @" (pl "@%killer.player@"/cl "@%killer@") hit a midair blaster shot ("@%distance@")");
if(%killer.blaMA > $stats::BlaMA_counter)
{
$stats::BlaMA_counter = %killer.BlaMA;
$stats::BlaMA_client = getTaggedString(%killer.name);
}
if(%distance > $stats::BlaMA_maxdistance)
{
$stats::BlaMA_maxdistance = %distance;
$stats::BlaMA_maxdistanceclient = getTaggedString(%killer.name);
}
}
}
}
// sendEvoDebriefing(%client)
// Info: Send Evo stats to the debriefing page
function sendEvoDebriefing(%client)
{
// Eolk - Remove redundant checks
messageClient(%client, 'MsgDebriefAddLine', "", '\n<lmargin:0><spush><color:00dc00>%1 - %2<spop>', $MissionDisplayName, $MissionTypeDisplayName);
if($stats::MaxGrabSpeed || $stats::grabs_counter || $stats::fckiller_counter || $stats::caps_counter || $stats::fastestCap)
{
messageClient(%client, 'MsgDebriefAddLine', "", '\n<lmargin:0><spush><color:00dc00><font:univers condensed:18>FLAG STATS<spop>');
if($stats::fastestCap)
messageClient(%client, 'MsgDebriefAddLine', "", '<lmargin:0><spush><color:00dc00><clip%%:40><font:univers condensed:18> Fastest Cap</clip><lmargin%%:30><clip%%:60> %1</clip><lmargin%%:60><clip%%:40> %2</clip><spop>', $stats::fastcap_client, $stats::fastcap_time);
if($stats::MaxGrabSpeed)
messageClient(%client, 'MsgDebriefAddLine', "", '<lmargin:0><spush><color:00dc00><clip%%:40><font:univers condensed:18> Flaming Ass</clip><lmargin%%:30><clip%%:60> %1</clip><lmargin%%:60><clip%%:40> %2 Kph!</clip><spop>', $stats::Grabber, $stats::MaxGrabSpeed);
if($stats::caps_counter)
messageClient(%client, 'MsgDebriefAddLine', "", '<lmargin:0><spush><color:00dc00><clip%%:40><font:univers condensed:18> Cap Mastah</clip><lmargin%%:30><clip%%:60> %1</clip><lmargin%%:60><clip%%:40> %2</clip><spop>', $stats::caps_client, $stats::caps_counter);
if($stats::grabs_counter)
messageClient(%client, 'MsgDebriefAddLine', "", '<lmargin:0><spush><color:00dc00><clip%%:40><font:univers condensed:18> Grabz0r</clip><lmargin%%:30><clip%%:60> %1</clip><lmargin%%:60><clip%%:40> %2</clip><spop>', $stats::grabs_client, $stats::grabs_counter);
if($stats::fckiller_counter)
messageClient(%client, 'MsgDebriefAddLine', "", '<lmargin:0><spush><color:00dc00><clip%%:40><font:univers condensed:18> FC killer</clip><lmargin%%:30><clip%%:60> %1</clip><lmargin%%:60><clip%%:40> %2</clip><spop>', $stats::fckiller_client, $stats::fckiller_counter);
}
if($stats::BlaMA_counter || $stats::ma_counter || $stats::PlaMA_counter)
{
messageClient(%client, 'MsgDebriefAddLine', "", '\n<lmargin:0><spush><color:00dc00><font:univers condensed:18>MID AIR<lmargin%%:30>CHAMPION<lmargin%%:60>DISTANCE<spop>');
if($stats::ma_counter)
messageClient(%client, 'MsgDebriefAddLine', "", '<lmargin:0><spush><color:00dc00><clip%%:40><font:univers condensed:18> Disk</clip><lmargin%%:30><clip%%:60> %1 (%2)</clip><lmargin%%:60><clip%%:60> %3 (%4 mt)</clip><spop>', $stats::ma_client, $stats::ma_counter, $stats::ma_maxdistanceclient, $stats::ma_maxdistance);
if($stats::PlaMA_counter)
messageClient(%client, 'MsgDebriefAddLine', "", '<lmargin:0><spush><color:00dc00><clip%%:40><font:univers condensed:18> Plasma</clip><lmargin%%:30><clip%%:60> %1 (%2)</clip><lmargin%%:60><clip%%:60> %3 (%4 mt)</clip><spop>', $stats::PlaMA_client, $stats::PlaMA_counter, $stats::PlaMA_maxdistanceclient, $stats::PlaMA_maxdistance);
if($stats::BlaMA_counter)
messageClient(%client, 'MsgDebriefAddLine', "", '<lmargin:0><spush><color:00dc00><clip%%:40><font:univers condensed:18> Blaster</clip><lmargin%%:30><clip%%:60> %1 (%2)</clip><lmargin%%:60><clip%%:60> %3 (%4 mt)</clip><spop>', $stats::BlaMA_client, $stats::BlaMA_counter, $stats::BlaMA_maxdistanceclient, $stats::BlaMA_maxdistance);
}
if($stats::snipe_counter)
messageClient(%client, 'MsgDebriefAddLine', "", '\n<lmargin:0><spush><color:00dc00><font:univers condensed:18>Headhunter<lmargin%%:30> %1 (%2)!<spop>', $stats::snipe_client, $stats::snipe_counter);
if($stats::snipe_maxdistance)
{
%x = $stats::snipe_counter ? "" : "\n";
messageClient(%client, 'MsgDebriefAddLine', "", '%3<lmargin:0><spush><color:00dc00><font:univers condensed:18>Longest Snipeshot is %1 meters by %2<spop>', $stats::snipe_maxdistance, $stats::snipe_maxdistanceclient, %x);
}
for(%damageType = 1; %damageType < 51; %damageType++)
{
if(%damageType == 7 || %damageType == 12 || (%damageType > 13 && %damageType < 21) || %damageType == 23 || %damageType == 24 || %damageType == 25) {
continue;
}
if(%damageType > 31 && %damageType < 50) {
continue;
}
if($stats::weap_table[%damageType] > 0)
{
if($Host::ClassicStatsType == 2)
{
if(!%message)
{
messageClient(%client, 'MsgDebriefAddLine', "", '\n<lmargin:0><spush><color:00dc00><font:univers condensed:18>TYPE<lmargin%%:30>PLAYER<lmargin%%:60>TOTAL DAMAGE<spop>');
%message = 1;
}
messageClient(%client, 'MsgDebriefAddLine', "", '<lmargin:0><spush><color:00dc00><clip%%:40><font:univers condensed:18> %1</clip><lmargin%%:30><clip%%:60> %2</clip><lmargin%%:60><clip%%:40> %3</clip><spop>', $weap_message[%damageType], $stats::client_weap_table[%damageType], mFormatFloat($stats::weap_table[%damageType], "%.2f"));
}
else if($Host::ClassicStatsType == 1)
{
if(!%message)
{
messageClient(%client, 'MsgDebriefAddLine', "", '\n<lmargin:0><spush><color:00dc00><font:univers condensed:18>TYPE<lmargin%%:30>PLAYER<lmargin%%:60>KILLS<spop>');
%message = 1;
}
messageClient(%client, 'MsgDebriefAddLine', "", '<lmargin:0><spush><color:00dc00><clip%%:40><font:univers condensed:18> %1</clip><lmargin%%:30><clip%%:60> %2</clip><lmargin%%:60><clip%%:40> %3</clip><spop>', $weap_message[%damageType], $stats::client_weap_table[%damageType], $stats::weap_table[%damageType]);
}
}
}
if($stats::tk_counter)
messageClient(%client, 'MsgDebriefAddLine', "", '\n<lmargin:0><spush><color:00dc00><font:univers condensed:18>And the best teamkiller award goes to... %1 (%2)!<spop>', $stats::tk_client, $stats::tk_counter);
}

View file

@ -54,7 +54,7 @@ function GetTeamCounts(%game)
if(!$Host::TournamentMode)
{
if($CurrentMissionType $= "CTF") //No SCtF
if($CurrentMissionType $= "CTF") //No LCTF
NBRStatusNotify(%game); //Base Rape
if($CurrentMissionType $= "CTF" || $CurrentMissionType $= "DM")

View file

@ -49,10 +49,10 @@ function DefaultGame::sendGameVoteMenu(%game, %client, %key)
{
if(!$Host::TournamentMode)
messageClient(%client, 'MsgVoteItem', "", %key, 'VoteTournamentMode', 'change server to Tournament.', 'Vote Tournament Mode');
messageClient(%client, 'MsgVoteItem', "", %key, 'VoteChangeMission', 'change the mission to', 'Vote to Change the Mission');
messageClient(%client, 'MsgVoteItem', "", %key, 'VoteNextMission', 'set next mission to', 'Vote to Set the Next Mission');
messageClient(%client, 'MsgVoteItem', "", %key, 'VoteChangeTimeLimit', 'change the time limit', 'Vote to Change the Time Limit');
messageClient(%client, 'MsgVoteItem', "", %key, 'VoteSkipMission', 'skip the mission to', 'Vote to Skip Mission' );
messageClient(%client, 'MsgVoteItem', "", %key, 'VoteChangeMission', 'change the mission to', 'Vote to Change the Mission');
messageClient(%client, 'MsgVoteItem', "", %key, 'VoteNextMission', 'set next mission to', 'Vote to Set the Next Mission');
messageClient(%client, 'MsgVoteItem', "", %key, 'VoteChangeTimeLimit', 'change the time limit', 'Vote to Change the Time Limit');
messageClient(%client, 'MsgVoteItem', "", %key, 'VoteSkipMission', 'skip the mission to', 'Vote to Skip Mission' );
if(%multipleTeams)
{
if($teamDamage)
@ -63,6 +63,12 @@ function DefaultGame::sendGameVoteMenu(%game, %client, %key)
messageClient(%client, 'MsgVoteItem',"", %key, 'ForceVote', 'Cancel Force Vote', "Cancel 'Vote To...'");
return;
}
else if (%client.ForceVote $= "skip_confirm") //Skip mission Confirm cuz its so annoying
{
messageClient(%client, 'MsgVoteItem', "", %key, 'VoteSkipConfirm', 'Are you sure you want to Skip the Mission?','Are you sure you want to Skip the Mission?');
messageClient(%client, 'MsgVoteItem', "", %key, 'VoteSkipMission', 'Yes, Skip the Mission', 'Yes, Skip the Mission' );
return;
}
//Pass Stop Menu
if(%client.isAdmin && %game.scheduleVote !$= "")
@ -79,7 +85,7 @@ function DefaultGame::sendGameVoteMenu(%game, %client, %key)
{
switch$($CurrentMissionType)
{
case CTF or SCtF:
case CTF or SCtF or LCTF:
if($Host::TournamentMode)
%showTL = " - Time Limit:" SPC $Host::TimeLimit SPC "Minutes";
if($voteNext)
@ -191,7 +197,7 @@ function DefaultGame::sendGameVoteMenu(%game, %client, %key)
messageClient(%client, 'MsgVoteItem', "", %key, 'VoteSkipMission', 'skip the mission to', 'Vote to Skip Mission' );
}
else
messageClient(%client, 'MsgVoteItem', "", %key, 'VoteSkipMission', 'skip the mission to', 'Skip the Mission' );
messageClient(%client, 'MsgVoteItem', "", %key, 'VoteSkipConfirm', 'skip the mission to', 'Skip the Mission' );
//Admin Vote Menu
if(%client.isAdmin && $Host::AllowAdminVotes)
messageClient(%client, 'MsgVoteItem', "", %key, 'ForceVote', 'Vote to ...', 'Vote to ...');
@ -547,6 +553,15 @@ function serverCmdStartNewVote(%client, %typeName, %arg1, %arg2, %arg3, %arg4, %
%msg = %client.nameBase @ " initiated a vote to " @ ($FairTeams == 0 ? "enable" : "disable") @ " fair teams.";
}
case "VoteSkipConfirm":
if(%isAdmin && %client.ForceVote !$= "skip_confirm")
{
%client.ForceVote = "skip_confirm";
return;
}
else
%client.ForceVote = 0;
case "VoteSkipMission":
if((!%isAdmin && $Host::AllowPlayerVoteSkipMission) || (%isAdmin && %client.ForceVote))
{
@ -840,12 +855,12 @@ function serverCmdStartNewVote(%client, %typeName, %arg1, %arg2, %arg3, %arg4, %
%msg = %client.nameBase @ " initiated a vote to " @ (Game.DMSLOnlyMode == 0 ? "enable" : "disable") @ " shocklance only mode.";
//LCTF Stuff
case "SCtFProMode":
if(!$CurrentMissionType $= "sctf")
case "LCTFProMode":
if(!$CurrentMissionType $= "LCTF")
return;
if(!%isAdmin || (%isAdmin && %client.ForceVote))
%msg = %client.nameBase @ " initiated a vote to " @ (Game.SCtFProMode == 0 ? "enable" : "disable") @ " pro mode.";
%msg = %client.nameBase @ " initiated a vote to " @ (Game.LCTFProMode == 0 ? "enable" : "disable") @ " pro mode.";
case "showServerRules":
if (($Host::ServerRules[1] !$= "") && (!%client.CantView))

View file

@ -1,332 +0,0 @@
//$Host::dtBanlist = "prefs/dtBanlist.cs";
//$Host::KickBanTime = 20; is 20 Minutes
//$Host::BanTime = 43200; is One Month
//$Host::BanTime = 129600; is Three Months
//$Host::BanTime = 259200; is Six Months
//$Host::BanTime = 518400; is 1 year
//$Host::BanTime = 1000000; is Until you unban them (Forever)
//$Host::BanTime = BAN; is Until you unban them (Forever)
//$dtBanList::GUID3555379 = "DAY OF THE YEAR BANNED \t YEAR BANNED \t HOUR BANNED \t MINUTE BANNED \t TIME TO BE BANNED";
//$dtBanList::GUID3555379 = "4\t2021\t18\t31\t518400";
//TO UNBAN SOMEONE WITHOUT RESTARTING THE SERVER
//banList();in console
//unbanIndex(%index) %index is the number next to the players name from listBans();
//Example: unbanold(555555,"22.222.222.222"); put ip in quotes
$dtBanList::save =1;
package dtBan
{
//Keep track of gags (Disconnecting and Reconnecting)
function GameConnection::onDrop(%client, %reason)
{
%ip = %client.getAddress();
%ip = getSubStr(%ip, 3, strLen(%ip));
%ip = getSubStr(%ip, 0, strstr(%ip, ":"));
%ip = strReplace(%ip, ".", "_");
$chatGagged[%ip] = $chatGagged[%client.guid] = (%client.isGagged == 1); //save status of this
parent::onDrop(%client, %reason);
}
//Reapply the gag
function GameConnection::onConnect( %client, %name, %raceGender, %skin, %voice, %voicePitch )
{
parent::onConnect( %client, %name, %raceGender, %skin, %voice, %voicePitch );
%ip = %client.getAddress();
%ip = getSubStr(%ip, 3, strLen(%ip));
%ip = getSubStr(%ip, 0, strstr(%ip, ":"));
%ip = strReplace(%ip, ".", "_");
%client.isGagged = ($chatGagged[%ip] || $chatGagged[%client.guid]); //restore status
}
function ClassicLoadBanlist()
{
$ClassicPermaBans = 0;
if(isFile($Host::dtBanlist))
exec($Host::dtBanlist);
$ClassicWhitelists = 0;
exec($Host::ClassicWhitelist);
}
function BanList::add(%guid, %ipAddress, %time){
if(%time > 999999){
%time = "BAN";
}
%name = getClientBanName(%guid, %ipAddress);
if (%guid > 0){
$dtBanList::GUID[%guid] = dtBanMark() TAB %time TAB %name;
}
if (getSubStr(%ipAddress, 0, 3) $= "IP:"){
%bareIP = getSubStr(%ipAddress, 3, strLen(%ipAddress));
%bareIP = getSubStr(%bareIP, 0, strstr(%bareIP, ":"));
%bareIP = strReplace(%bareIP, ".", "_"); // variable access bug workaround
// add IP ban
$dtBanList::IP[%bareIP] = dtBanMark() TAB %time TAB %name;
}
%found = 0;
%eIndex = -1;
for (%i = 0; %i < 100; %i++){
if($dtBanList::NameList[%i] !$= ""){
if(getField($dtBanList::NameList[%i], 0) $= %name){
%found =1;
if(%guid > 0)
$dtBanList::NameList[%i] = setField($dtBanList::NameList[%i], 1, %guid);
if(getSubStr(%ipAddress, 0, 3) $= "IP:")
$dtBanList::NameList[%i] = setField($dtBanList::NameList[%i], 2, %bareIP);
break;
}
}
else if(%eIndex == -1){
%eIndex = %i;
}
}
if(!%found){
if($dtBanList::NameList[%eIndex] $= ""){
$dtBanList::NameList[%eIndex] = %name TAB %guid TAB %bareIP;
}
else{
error("Ban Index is not empty");
}
}
saveBanList();
}
function banList_checkIP(%client){
%ip = %client.getAddress();
%ip = getSubStr(%ip, 3, strLen(%ip));
%ip = getSubStr(%ip, 0, strstr(%ip, ":"));
%ip = strReplace(%ip, ".", "_");
%time = $dtBanList::IP[%ip];
if(getField(%time,4) $= "BAN")
return 1;
if (getFieldCount(%time) > 0){
%delta = getBanCount(getField(%time,0), getField(%time,1),getField(%time,2),getField(%time,3));
if (%delta < getField(%time,4))
return 1;
else{
for (%i = 0; %i < 100; %i++){
if($dtBanList::NameList[%i] !$= ""){
if(getField($dtBanList::NameList[%i], 1) $= %guid){
unbanIndex(%i);
break;
}
}
}
$dtBanList::IP[%ip] = "";
saveBanList();
}
}
return 0;
}
function banList_checkGUID(%guid){
%time = $dtBanList::GUID[%guid];
if(getField(%time,4) $= "BAN")
return 1;
if (getFieldCount(%time) > 0){
%delta = getBanCount(getField(%time,0), getField(%time,1),getField(%time,2),getField(%time,3));
if (%delta < getField(%time,4))
return 1;
else{
for (%i = 0; %i < 100; %i++){
if($dtBanList::NameList[%i] !$= ""){
if(getField($dtBanList::NameList[%i], 1) $= %guid){
unbanIndex(%i);
break;
}
}
}
$dtBanList::GUID[%guid] = "";
saveBanList();
}
}
return 0;
}
function CreateServer(%mission, %missionType)
{
parent::CreateServer(%mission, %missionType);
//Clean timed out bans at startup
schedule(10000,0,"banListClean",0);
}
};
if (!isActivePackage(dtBan)){
activatePackage(dtBan);
}
function saveBanList(){
if(!isEventPending($banEvent))
$banEvent = schedule(1000,0,"export","$dtBanList*", $Host::dtBanlist);
}
function getClientBanName(%guid, %ip){
%found = 0;
for (%i = 0; %i < ClientGroup.getCount(); %i++){
%client = ClientGroup.getObject(%i);
if(%guid > 0 && %client.guid $= %guid){
%found = 1;
break;
}
else if(%client.getAddress() $= %ip){
%found = 1;
break;
}
}
if(%found){
%authInfo = %client.getAuthInfo();
%realName = getField( %authInfo, 0 );
if(%realName !$= "")
%name = %realName;
else
%name = stripChars( detag( getTaggedString( %client.name ) ), "\cp\co\c6\c7\c8\c9\c0" );
return trim(%name);
}
return 0;
}
function getBanCount(%d, %year, %h, %n){
if(%d && %year && %h && %n){
%dif = formattimestring("yy") - %year;
%days += 365 * (%dif-1);
%days += 365 - %d;
%days += dtBanDay();
%ht = %nt = 0;
if(formattimestring("H") > %h){
%ht = formattimestring("H") - %h;
}
else if(formattimestring("H") < %h){
%ht = 24 - %h;
%ht = formattimestring("H")+ %ht;
}
if(formattimestring("n") > %n){
%nt = formattimestring("n") - %n;
}
else if(formattimestring("n") < %n){
%nt = 60 - %n;
%nt = formattimestring("n") + %nt;
}
return mfloor((%days * 1440) + (%ht*60) + %nt);
}
return 0;
//return mfloor((%days * 1440) + (%ht*60) + %nt) TAB (%days * 1440) TAB (%ht*60) TAB %nt;
}
function dtBanDay(){
%date = formattimestring("mm dd yy");
%m = getWord(%date,0);%d = getWord(%date,1);%y = getWord(%date,2);
%count = 0;
if(%y % 4 < 1){%days[2] = "29";}else{%days[2] = "28";} // leap year
%days[1] = "31";%days[3] = "31";
%days[4] = "30"; %days[5] = "31"; %days[6] = "30";
%days[7] = "31"; %days[8] = "31"; %days[9] = "30";
%days[10] = "31"; %days[11] = "30"; %days[12] = "31";
for(%i = 1; %i <= %m-1; %i++){
%count += %days[%i];
}
return %count + %d;
}
function dtBanMark(){
%date = formattimestring("mm dd yy");
%m = getWord(%date,0);%d = getWord(%date,1);%y = getWord(%date,2);
%count = 0;
if(%y % 4 < 1){%days[2] = "29";}else{%days[2] = "28";} // leap year
%days[1] = "31";%days[3] = "31";
%days[4] = "30"; %days[5] = "31"; %days[6] = "30";
%days[7] = "31"; %days[8] = "31"; %days[9] = "30";
%days[10] = "31"; %days[11] = "30"; %days[12] = "31";
for(%i = 1; %i <= %m-1; %i++){
%count += %days[%i];
}
return %count + %d TAB formattimestring("yy") TAB formattimestring("H") TAB formattimestring("n");
}
function banList(){
%found = 0;
for (%i = 0; %i < 100; %i++){
%fieldList = $dtBanList::NameList[%i];
if($dtBanList::NameList[%i] !$= ""){
%found = 1;
error("index:" @ %i SPC "Name:" @ getField(%fieldList,0) SPC "GUID:" @ getField(%fieldList,1) SPC "IP:" @ getField(%fieldList,2));
}
}
if(%found){
error("Use unbanIndex(%index); to unban user from the list ");
}
else{
error("No bans, see" SPC $Host::dtBanlist SPC "for older entries");
}
}
function unbanIndex(%index){
if( $dtBanList::NameList[%index] !$= ""){
%fieldList = $dtBanList::NameList[%index];
%name = getField(%fieldList, 0);
$dtBanList::NameList[%index] = "";
error("Name" SPC getField(%fieldList,0) SPC "UNBANNED");
%guid = getField(%fieldList,1);
if($dtBanList::GUID[%guid] !$= ""){
$dtBanList::GUID[%guid] = "";
error("GUID" SPC %guid SPC "UNBANNED");
}
%ip = getField(%fieldList,2);
if($dtBanList::IP[%ip] !$= ""){
$dtBanList::IP[%ip] = "";
error("IP" SPC %ip SPC "UNBANNED");
}
saveBanList();
return %name;
}
return -1;
}
//old method
function unbanold(%guid,%ip){
%ip = strReplace(%ip, ".", "_");
for (%i = 0; %i < 100; %i++){
if($dtBanList::NameList[%i] !$= ""){
if(getField($dtBanList::NameList[%i], 2) $= %ip || getField($dtBanList::NameList[%i], 1) $= %guid){
unbanIndex(%i);
return;
}
}
}
if($dtBanList::GUID[%guid] !$= ""){
$dtBanList::GUID[%guid] = "";
error("GUID" SPC %guid SPC "UNBANNED");
}
if($dtBanList::IP[%ip] !$= ""){
$dtBanList::IP[%ip] = "";
error("IP" SPC %ip SPC "UNBANNED");
}
saveBanList();
}
//Clean timed out bans at startup
function banListClean(){
%found = 0;
for (%i = 0; %i < 100; %i++){
%fieldList = $dtBanList::NameList[%i];
if($dtBanList::NameList[%i] !$= ""){
%guid = getField($dtBanList::NameList[%i], 1);
%ip = getField($dtBanList::NameList[%i], 2);
%time = $dtBanList::GUID[%guid];
%delta = getBanCount(getField(%time,0), getField(%time,1),getField(%time,2),getField(%time,3));
if (getField(%time,4) !$= "BAN" && %delta > getField(%time,4)){
$dtBanList::NameList[%i] = "";
$dtBanList::GUID[%guid] = "";
$dtBanList::IP[%ip] = "";
error("GUID" SPC %guid SPC "IP" SPC %ip SPC "UNBANNED");
}
}
}
saveBanList();
}

View file

@ -1,171 +1,108 @@
//Fixes for collision tunneling among other flag issues, note only works in classic ctf game types
//Fixes for collision tunneling and other issues, note only tested in classic
//Script By:DarkTiger
//V2.1
//v3.4 switch over to using SAT/OBB for hitbox detection accuracy, also heavy optimizations becuase of this change
//v3.3 - fixed ceiling deadstoping,fixed wall and ceiling tunneling $antiObjTunnel
//V3.2 - script refactor, removed flag sim in favor of just an offset on toss
$ftEnable = 1;//disables all
$limitFlagCalls = 1; // prevents frame perfect events witch can cause bad outcomes
$antiCeiling = 1; // note this is auto enabled with $boxStuckFix as it needs to check for this
$antiTerTunnel = 0;//prevents terrain tunneling keeps the flag above the terrain leave this off unless you think its a problem
$antiObjTunnel = 0;//prevents terrain and interior tunneling more thigns can be added see first part of DefaultGame::flagColTest
$antiFlagImpluse = 1000;//time out period to prevent explosions from effecting flags on drop/toss
$boxStuckFix = 1;
$boxStuckFix = 1;// enables flag offset, spawns the flag outside of the player to keep it from getting stuck
$flagOffset = 1;// how far to offset the flag 1m seems like it works 90% of the time
// adds initial update to setVelocity and setTransform to updates its parameters across clients
//enable $flagResetTime with setting it to 5000 if you disable a mempatch
//expermental flag static fix
//memPatch("60456c","11000018");//transform
memPatch("6040ff","01"); //setVelocity
$flagResetTime = 0;// 1000-5000 if you want this feature enabled, resets flag to stand in case of desync should not be needed
//best to leave these values alone unless you understand what the code is doing
$flagSimTime = 60;//note a higher the time, the larger the sweep scans will be
$flagSimTime = 64;//note a higher the time, the larger the sweep scans will be
$flagCheckRadius = 50;
$playerBoxA = "-0.6 -0.6 0";
$playerBoxB = "0.6 0.6 2.3";
$flagStuckTime = 1000;
$playerSizeBox = "1.2 1.2 2.3";
$flagBoxSize = "0.796666 0.139717 2.46029";
$flagSimRate = 30;
$tickDelay = 1; //delay the sim by 1 ticks in case its not needed
function flagSim(%flag,%player){
%bypassBoxCheck = 0;// debug sim
//%mass = 80;// not needed
%bounceFriction = 0.6;
%bounceElasticity = 0.2;
%drag = 0.5;
%simRate = $flagSimRate;
%timeFrame = mFloor(1000 / %simRate);
%dt = %timeFrame / 1000;
%Box2 = %flag.getWorldBox();
%Box1 = %player.getWorldBox();
if(!%flag.isHome && !isObject(%flag.carrier)){
if((boxIntersect(%Box1, %Box2) || %bypassBoxCheck) && vectorLen(%flag.finalVel) > 1 && %flag.countsim < 32){
%flag.setVelocity("0 0 0");// keep it zeroed out
%xform = %flag.getTransform();
%oldPos = getWords(%xform,0,2);// we dont use lastSimPos here as it will be fighting the engine too much instead we use it in the raycast
%flag.finalVel = vectorAdd(%flag.finalVel, "0 0" SPC (getGravity() * 1) * %dt);// engine adds its gravity so... prob not needed
%flag.finalVel = vectorSub(%flag.finalVel, vectorScale(%flag.finalVel, %drag * %dt));
%newPos = vectorAdd(%oldPos, vectorScale(%flag.finalVel,%dt));
%mask = $TypeMasks::InteriorObjectType | $TypeMasks::StaticTSObjectType | $TypeMasks::TerrainObjectType;//$TypeMasks::ForceFieldObjectType
%movRayB = containerRayCast(%flag.lastSimPos, %newPos, %mask, %flag);
%movRayT = containerRayCast(vectorAdd(%flag.lastSimPos,"0 0 2.4"), vectorAdd(%newPos,"0 0 2.4"), %mask, %flag);
if(%movRayB){
%hitRay = %movRayB;
}
if(%movRayT){
%hitRay = getWord(%movRayT,0) SPC %oldPos SPC getWords(%movRayT,4,6);
}
if(%hitRay){
%normal = getWords(%hitRay, 4, 6);
// Reflect the velocity around the surface normal
%reflectedVel = vectorSub(%flag.finalVel, vectorScale(%normal, vectorDot(%flag.finalVel, %normal) * 2.0));
// Calculate the tangent component for surface friction
%tangent = vectorSub(%reflectedVel, vectorScale(%normal, vectorDot(%reflectedVel, %normal)));
// Apply surface friction
%bounceVel = vectorSub(%reflectedVel, vectorScale(%tangent, %bounceFriction));
// Apply elasticity to modulate the speed of the bounce
%flag.finalVel = vectorScale(%bounceVel, %bounceElasticity);
// Adjust the new position to the point of impact plus a small offset along the normal
%newPos = vectorAdd(getWords(%hitRay, 1, 3), vectorScale(%normal, 0.05));
}
%flag.lastSimPos = %newPos;// we do this so theres no gaps in are sim other wise it could end up underground
%flag.setTransform(%newPos SPC getWords(%xform,3,6));
//%flag.setVelocity(%flag.finalVel);
%flag.countsim++;
schedule(%timeFrame,0,"flagSim",%flag,%player);
}
else{
//error("simCount" SPC %flag.countsim SPC vectorLen(%flag.finalVel));
if(vectorLen(%flag.finalVel) && %flag.countsim > 0){
%flag.setVelocity(%flag.finalVel);
}
}
}
}
function delayStartFlag(%obj,%this){
%obj.countsim = 0;
%obj.lastSimPos = %obj.getPosition();
%drag = 0.5;
%dt = mFloor(1000 / $flagSimRate) / 1000;
for(%i = 0; %i < $tickDelay; %i++){
%obj.finalVel = vectorSub(%obj.finalVel, vectorScale(%obj.finalVel, %drag * %dt));
}
flagSim(%obj,%this);
}
//0 = old AABB method uses fixed box size makes the player bit narrow
//1 = new OBB method uses perfect box intersection
//2 = AABB method but uses boundbox can make the player larger then it is given there direction
//3 = AABB fixed sizes uses $playerSizeBox and $flagBoxSize to do the box checking
$boxCollision = 1;// off is the old AABB method aka the old method
$flagColBypass = 0;//bypass all other collision methods other then this one
package flagFix{
//because the fade is 2000ms we can compensate the delayed reset not to mess with client timers
function Flag::onCollision(%data,%obj,%col){
if(!$flagColBypass){
parent::onCollision(%data,%obj,%col);
}
}
function ShapeBase::throwObject(%this,%obj){
parent::throwObject(%this,%obj);
%data = %obj.getDatablock();
if(%data.getName() $= "Flag"){
%fpos = %obj.getPosition();
if($ftEnable && %data.getName() $= "Flag"){
%tpos = %obj.getTransform();
%fpos = getWords(%tpos,0, 2);
%obj.dtLastPos = %fpos;
%vel = %obj.getVelocity();
%posOffset = VectorAdd(%fpos, VectorScale(VectorNormalize(%vel), 2));
if($boxStuckFix){
%obj.finalVel = %obj.getVelocity();
%upRay = containerRayCast(vectorAdd(%fpos,"0 0 0.1"), vectorAdd(%fpos,"0 0 2.5"), $TypeMasks::InteriorObjectType | $TypeMasks::StaticTSObjectType | $TypeMasks::ForceFieldObjectType, %obj);
if(%upRay){
%dist = vectorDist(%fpos,getWords(%upRay,1,3));
%obj.setTransform(vectorSub(%fpos,"0 0" SPC (2.6 - %dist)) SPC getWords(%obj.getTransform(), 3, 6));
error("Ceiling" SPC %dist);
}
%wallRay = containerRayCast(%fpos, VectorAdd(%fpos, VectorScale(%this.getForwardVector(), 2)), $TypeMasks::InteriorObjectType | $TypeMasks::StaticTSObjectType | $TypeMasks::ForceFieldObjectType, %obj);
if(!%wallRay){
schedule($tickDelay * mFloor(1000 / $flagSimRate),0,"delayStartFlag",%obj,%this);
}
}
else if($antiCeiling){
if($antiCeiling){//flag height 2.46029
//0.1 offset any fp errors with the flag position being at ground level, 2.4 offset flag height offset + some extra
%upRay = containerRayCast(vectorAdd(%fpos,"0 0 0.1"), vectorAdd(%fpos,"0 0 2.5"), $TypeMasks::InteriorObjectType | $TypeMasks::StaticTSObjectType | $TypeMasks::ForceFieldObjectType, %obj);
if(%upRay){
%dist = vectorDist(%fpos,getWords(%upRay,1,3));
%obj.setTransform(vectorSub(%fpos,"0 0" SPC (2.6 - %dist)) SPC getWords(%obj.getTransform(), 3, 6));
//error("bump2");
%obj.setTransform(vectorSub(%this.getPosition(),"0 0" SPC 0.3) SPC getWords(%this.getTransform(),3,6));
%obj.setVelocity(getWords(%vel,0,1) SPC 0);
}
}
}
}
if($boxStuckFix && !%upRay){
%wallMask = $TypeMasks::TerrainObjectType | $TypeMasks::InteriorObjectType | $TypeMasks::StaticObjectType | $TypeMasks::ForceFieldObjectType | $TypeMasks::VehicleObjectType;
%wallRay = containerRayCast(%fpos, %posOffset, %wallMask, %obj);
function CTFGame::startFlagCollisionSearch(%game, %flag){
parent::startFlagCollisionSearch(%game, %flag);
if((getSimTime() - %game.fcs) >= $flagSimTime && $ftEnable){
%game.flagColTest(%flag);
%game.fcs = getSimTime();
}
}
function SCtFGame::startFlagCollisionSearch(%game, %flag){
parent::startFlagCollisionSearch(%game, %flag);
if((getSimTime() - %game.fcs) >= $flagSimTime && $ftEnable){
%game.flagColTest(%flag);
%game.fcs = getSimTime();
}
}
%fwoPos = VectorAdd(%fpos, VectorScale(VectorNormalize(%vel), $flagOffset));
function PracticeCTFGame::startFlagCollisionSearch(%game, %flag){
parent::startFlagCollisionSearch(%game, %flag);
if((getSimTime() - %game.fcs) >= $flagSimTime && $ftEnable){
%game.flagColTest(%flag);
%game.fcs = getSimTime();
%upRay = containerRayCast(vectorAdd(%fwoPos,"0 0 0.1"), vectorAdd(%fwoPos,"0 0 2.5"), $TypeMasks::InteriorObjectType | $TypeMasks::StaticTSObjectType | $TypeMasks::ForceFieldObjectType, %obj);
if(!%wallRay){// make sure we dont end up in a wall
if(!%upRay){
%obj.setTransform(%fwoPos SPC getWords(%this.getTransform(),3,6));
%obj.dtLastPos = %fwoPos;
}
}
}
}
}
function CTFGame::startMatch(%game){
parent::startMatch(%game);
if(!isEventPending(Game.flagLoop)){
$TeamFlag[1].resetTime = 0;
$TeamFlag[2].resetTime = 0;
%game.atHomeFlagLoop();
}
%game.fcs = getSimTime();
}
function SCtFGame::startMatch(%game){
parent::startMatch(%game);
if(!isEventPending(Game.flagLoop)){
$TeamFlag[1].resetTime = 0;
$TeamFlag[2].resetTime = 0;
%game.atHomeFlagLoop();
}
%game.fcs = getSimTime();
}
function PracticeCTFGame::startMatch(%game){
parent::startMatch(%game);
if(!isEventPending(Game.flagLoop)){
$TeamFlag[1].resetTime = 0;
$TeamFlag[2].resetTime = 0;
%game.atHomeFlagLoop();
}
%game.fcs = getSimTime();
}
//prevents frame perfect flag touches witch can cause bad stuff to happen in ctf
@ -222,8 +159,7 @@ package flagFix{
function Flag::shouldApplyImpulse(%data, %obj){
%val = parent::shouldApplyImpulse(%data, %obj);
//error("meow");
if($antiFlagImpluse > 0 && %val && %obj.lastDropTime > 0){
if(%val && $antiFlagImpluse > 0 && %obj.lastDropTime > 0){
%time = getSimTime() - %obj.lastDropTime;
if(%time < $antiFlagImpluse){
%val = 0;
@ -233,38 +169,151 @@ package flagFix{
}
};
activatePackage(flagFix);
function DefaultGame::flagColTest(%game, %flag){
//flag ceiling check
%curPos = %flag.getWorldBoxCenter();
if( !%flag.isHome ){
if($antiTerTunnel){
// anti flag tunneling on terrain
if(%flag.lastUpdate > 0 && (getSimTime() - %flag.lastUpdate) < 128){//make sure are last position is current
%terRay = containerRayCast(%flag.dtLastPos, %curPos, $TypeMasks::TerrainObjectType, %flag);
if(%terRay){
%curPos = vectorAdd(getWords(%terRay,1,3), "0 0 0.5");
%flag.setTransform(%curPos SPC getWords(%flag.getTransform(), 3, 6));
function FlagCollision(%data,%obj,%col){
if($flagColBypass){
if (%col.getDataBlock().className $= Armor)
{
if (%col.isMounted())
return;
// z0dd - ZOD, 6/13/02. Touch the flag and your invincibility and cloaking goes away.
if(%col.station $= "" && %col.isCloaked())
{
if( %col.respawnCloakThread !$= "" )
{
Cancel(%col.respawnCloakThread);
%col.setCloaked( false );
%col.respawnCloakThread = "";
}
}
%flag.lastUpdate = getSimTime();
%flag.dtLastPos = %curPos;
if( %col.client > 0 )
{
%col.setInvincibleMode(0, 0.00);
%col.setInvincible( false );
}
// a player hit the flag
Game.playerTouchFlag(%col, %obj);
}
}
else{
%data.onCollision(%flag, %player);
}
}
function vectorMul(%a,%b){
%x = getWords(%a,0) * getWords(%b,0);
%y = getWords(%a,1) * getWords(%b,1);
%z = getWords(%a,2) * getWords(%b,2);
return %x SPC %y SPC %z;
}
function generateBoxData(){
%playerSize = $playerSizeBox; //"1.2 1.2 2.3";
%halfSize = vectorMul(%playerSize, "0.5 0.5 0");
$plrBoxMin = %minA = VectorSub("0 0 0", %halfSize);
$plrBoxMax = %maxA = getWords(%halfSize,0,1) SPC getWord(%playerSize,2);
$plrBox = %minA SPC %maxA;
%vSubA = vectorSub(%maxA, %minA);
%flagSize = $flagBoxSize;
%halfSize = vectorMul(%flagSize, "0.5 0.5 0");
$flagBoxMin = %minB = VectorSub("0 0 -0.1", %halfSize);
$flagBoxMax = %maxB = getWords(%halfSize,0,1) SPC getWord(%flagSize,2);
$flagBox = %minB SPC %maxB;
%vSubB = vectorSub(%maxB, %minB);
%box[0] = "0 0 0";
%box[1] = "1 0 0";
%box[2] = "0 1 0";
%box[3] = "1 1 0";
%box[4] = "0 0 1";
%box[5] = "1 0 1";
%box[6] = "0 1 1";
%box[7] = "1 1 1";
for(%i = 0; %i < 8; %i++){
$playerBoxData[%i] = vectorAdd(%minA, vectorMul(%vSubA, %box[%i]));
$flagBoxData[%i] = vectorAdd(%minB, vectorMul(%vSubB, %box[%i]));
}
}generateBoxData();
function vectorLerp(%point1, %point2, %t) {
return vectorAdd(%point1, vectorScale(vectorSub(%point2, %point1), %t));
}
function boxIntersectAABB(%plr, %flg, %lerpPos){
if($boxCollision == 2){
%a = %plr.getWorldBox();
%b = %flg.getWorldBox();
}
else if($boxCollision == 3){
%fpos = %flg.getPosition();
%a = vectorAdd($plrBoxMin, %lerpPos) SPC vectorAdd($plrBoxMax, %lerpPos);
%b = vectorAdd($flagBoxMin, %fpos) SPC vectorAdd($flagBoxMax, %fpos);
}
else{
%plrMinMax = %plr.getObjectBox();
%a = vectorAdd(getWords(%plrMinMax,0,2), %lerpPos) SPC vectorAdd(getWords(%plrMinMax,3,5), %lerpPos);
%b = %flg.getWorldBox();
}
return (getWord(%a, 0) <= getWord(%b, 3) && getWord(%a, 3) >= getWord(%b, 0)) &&
(getWord(%a, 1) <= getWord(%b, 4) && getWord(%a, 4) >= getWord(%b, 1)) &&
(getWord(%a, 2)<= getWord(%b, 5) && getWord(%a, 5) >= getWord(%b, 2));
}
function DefaultGame::flagColTest(%game, %flag, %rsTeam, %ext){
////////////////////////////////////////////////////////////////////////////////
//obj tunneling check
%flagPos = %flag.getPosition();
if(!%flag.isHome && $antiObjTunnel){
%fOffset =vectorAdd(%flagPos,"0 0 0.1");
%dist = vectorDist(%flag.dtLastPos, %fOffset);
if(%dist > 2.5){//2.5 is the rough flag height
%wallMask = $TypeMasks::TerrainObjectType | $TypeMasks::InteriorObjectType;
%terRay = containerRayCast(%flag.dtLastPos, %fOffset, %wallMask, %flag);
if(%terRay){
%flag.setTransform(%flag.dtLastPos SPC getWords(%flag.getTransform(), 3, 6));
}
else{
%flag.dtLastPos = %fOffset;
}
}
}
////////////////////////////////////////////////////////////////////////////////
//flag collision check
%Box2 = %flag.getWorldBox();
InitContainerRadiusSearch( %curPos, $flagCheckRadius, $TypeMasks::PlayerObjectType);
InitContainerRadiusSearch( %flagPos, $flagCheckRadius, $TypeMasks::PlayerObjectType);
while((%player = containerSearchNext()) != 0){
%playerPos = %player.getPosition();
if(%player.lastSim > 0 && (%player.getState() !$= "Dead")){// only check at speed
if((getSimTime() - %player.lastSim) <= 128){//make sure are last position is valid
%sweepCount = mFloor(vectorDist(%playerPos, %player.oldPos) + 1);
for(%i = 0; %i < %sweepCount; %i++){// sweep behind us to see if we should have hit something
%lerpPos = vectorLerp(%playerPos, %player.oldPos, (%i+1)/%sweepCount);//back sweep
%Box1 = vectorAdd($playerBoxA, %lerpPos) SPC vectorAdd($playerBoxB, %lerpPos);
if(boxIntersect(%Box1, %Box2)){
%flag.getDataBlock().onCollision(%flag, %player);
break;
if((%rsTeam && %flag.team != %player.team) || !%rsTeam || %player == %ext){
%flagDist = vectorDist(%flagPos, %playerPos);
if(%player.lastSim > 0 && (%player.getState() !$= "Dead")){// only check at speed
//%fdot = vectorDot(vectorNormalize(%player.getVelocity()),vectorNormalize(VectorSub(%flagPos, %playerPos)));
// %tickDist = vectorLen(%player.getVelocity()) * ($flagSimTime/1000);
%sweepCount = mFloor(vectorDist(%playerPos, %player.oldPos) + 1.5);
if((getSimTime() - %player.lastSim) <= 128 && %flagDist-2 < %sweepCount){//make sure are last position is valid
//error(%player SPC %flagDist SPC %sweepCount);
for(%i = 0; %i < %sweepCount; %i++){// sweep behind us to see if we should have hit something
%lerpPos = vectorLerp(%playerPos, %player.oldPos, %i/(%sweepCount-1));//back sweep
if($boxCollision == 1){
if(boxIntersect(%player, %flag, %lerpPos)){
//error("flag hit");
FlagCollision(%flag.getDataBlock(),%flag, %player);
break;
}
}
else{
if(boxIntersectAABB(%player, %flag, %lerpPos)){
//error("flag hit");
FlagCollision(%flag.getDataBlock(),%flag, %player);
break;
}
}
}
}
}
@ -272,26 +321,151 @@ function DefaultGame::flagColTest(%game, %flag){
%player.oldPos = %playerPos;
%player.lastSim = getSimTime();
}
}
function vectorLerp(%point1, %point2, %t) {
return vectorAdd(%point1, vectorScale(vectorSub(%point2, %point1), %t));
}
function boxIntersect(%a, %b){
return (getWord(%a, 0) <= getWord(%b, 3) && getWord(%a, 3) >= getWord(%b, 0)) &&
(getWord(%a, 1) <= getWord(%b, 4) && getWord(%a, 4) >= getWord(%b, 1)) &&
(getWord(%a, 2) <= getWord(%b, 5) && getWord(%a, 5) >= getWord(%b, 2));
//error("scan count" SPC %scanCount SPC %scanPlrCount);
}
function DefaultGame::atHomeFlagLoop(%game){
if($TeamFlag[1].isHome ){
%game.flagColTest($TeamFlag[1], 0);
if(isObject($TeamFlag[1]) && isObject($TeamFlag[2])){
if($flagResetTime > 0){
if(%game.flagResetTime > $flagResetTime){
if($TeamFlag[1].isHome){
$TeamFlag[1].setTransform($TeamFlag[1].originalPosition);
}
if($TeamFlag[2].isHome){
$TeamFlag[2].setTransform($TeamFlag[2].originalPosition);
}
%game.flagResetTime = 0;
}
%game.flagResetTime += $flagSimTime;
}
if($TeamFlag[1].isHome && $TeamFlag[2].isHome){//11
%game.flagColTest($TeamFlag[1],1,0);// only look at the other team
%game.flagColTest($TeamFlag[2],1,0);// only look at the other team
}
else if(!$TeamFlag[1].isHome && $TeamFlag[2].isHome){//01
if(isObject($TeamFlag[1].carrier)){// flag has been dropped
%game.flagColTest($TeamFlag[2],1, $TeamFlag[1].carrier); //scan for other team expect for are carrier
}
else{
%game.flagColTest($TeamFlag[1],0,0);// scan for everyone can touch it
%game.flagColTest($TeamFlag[2],1,0);// team 2 flag is still at home so only scan for the other team
}
}
else if($TeamFlag[1].isHome && !$TeamFlag[2].isHome){//10
if(isObject($TeamFlag[2].carrier)){// flag has been dropped
%game.flagColTest($TeamFlag[1],1, $TeamFlag[2].carrier); //scan for other team expect for are carrier
}
else{
%game.flagColTest($TeamFlag[1],1,0);// team 1 flag is still at home so only scan for the other team
%game.flagColTest($TeamFlag[2],0,0);// scan for everyone can touch it
}
}
else if(!$TeamFlag[1].isHome && !$TeamFlag[2].isHome){//00
if(!isObject($TeamFlag[1].carrier)){// flag has been dropped
%game.flagColTest($TeamFlag[1],0,0);// scan for everyone can touch it
}
if(!isObject($TeamFlag[2].carrier)){// flag has been dropped
%game.flagColTest($TeamFlag[2],0,0);// scan for everyone can touch it
}
}
}
if($TeamFlag[2].isHome){
%game.flagColTest($TeamFlag[2], 0);
}
%speed = ($HostGamePlayerCount - $HostGameBotCount > 0) ? $flagSimTime : 30000;
if(isObject(Game) && $missionRunning && $ftEnable)
if(isObject(Game) && $ftEnable){
%speed = ($HostGamePlayerCount - $HostGameBotCount > 0) ? $flagSimTime : 30000;
%game.flagLoop = %game.schedule(%speed, "atHomeFlagLoop");
}
}
function boxIntersect(%objA, %objB, %scanPos) {
// Retrieve the 8 corners of the box for both objects
%matrixA = %objA.getTransform();
if(getWordCount(%scanPos)){// need to check a postion other then default
%matrixA = %scanPos SPC getWords(%matrixA,3,6);
}
%matrixB = %objB.getTransform();
%cornerA[0] = MatrixMulPoint(%matrixA, "-0.6 -0.6 0");
%cornerA[1] = MatrixMulPoint(%matrixA, "0.6 -0.6 0");
%cornerA[2] = MatrixMulPoint(%matrixA, "-0.6 0.6 0");
%cornerA[3] = MatrixMulPoint(%matrixA, "0.6 0.6 0");
%cornerA[4] = MatrixMulPoint(%matrixA, "-0.6 -0.6 2.3");
%cornerA[5] = MatrixMulPoint(%matrixA, "0.6 -0.6 2.3");
%cornerA[6] = MatrixMulPoint(%matrixA, "-0.6 0.6 2.3");
%cornerA[7] = MatrixMulPoint(%matrixA, "0.6 0.6 2.3");
%cornerB[0] = MatrixMulPoint(%matrixB, "-0.398333 -0.0698583 -0.1");
%cornerB[1] = MatrixMulPoint(%matrixB, "0.398333 -0.0698583 -0.1");
%cornerB[2] = MatrixMulPoint(%matrixB, "-0.398333 0.0698587 -0.1");
%cornerB[3] = MatrixMulPoint(%matrixB, "0.398333 0.0698587 -0.1");
%cornerB[4] = MatrixMulPoint(%matrixB, "-0.398333 -0.0698583 2.46029");
%cornerB[5] = MatrixMulPoint(%matrixB, "0.398333 -0.0698583 2.46029");
%cornerB[6] = MatrixMulPoint(%matrixB, "-0.398333 0.0698587 2.46029");
%cornerB[7] = MatrixMulPoint(%matrixB, "0.398333 0.0698587 2.46029");
// Define the axes to test (these are the edges of both boxes)
%ax[0] = vectorNormalize(vectorSub(%cornerA[1], %cornerA[0]));//X cross forward and up
%ax[1] = vectorNormalize(vectorSub(%cornerA[2], %cornerA[0]));//Y forward vector
%ax[2] = "0 0 1";
%ax[3] = vectorNormalize(vectorSub(%cornerB[1], %cornerB[0]));//X cross forward and up
%ax[4] = vectorNormalize(vectorSub(%cornerB[2], %cornerB[0])); //Y forward vector
%ax[5] = "0 0 1";
// For each axis
for (%i = 0; %i < 6; %i++) {
%axis = %ax[%i];
// Project each corner of box A onto the axis
%minProjA = vectorDot(%cornerA[0], %axis);
%maxProjA = %minProjA;
for (%j = 1; %j < 8; %j++) {
%projA = vectorDot(%cornerA[%j], %axis);
%minProjA = (%projA < %minProjA) ? %projA : %minProjA;
%maxProjA = (%projA > %maxProjA) ? %projA : %maxProjA;
}
// Project each corner of box B onto the axis
%minProjB = vectorDot(%cornerB[0], %axis);
%maxProjB = %minProjB;
for (%j = 1; %j < 8; %j++) {
%projB = vectorDot(%cornerB[%j], %axis);
%minProjB = (%projB < %minProjB) ? %projB : %minProjB;
%maxProjB = (%projB > %maxProjB) ? %projB : %maxProjB;
}
// Check for overlap
if (%maxProjA < %minProjB || %maxProjB < %minProjA) {
return false; // No overlap on this axis, boxes do not intersect
}
}
return true; // Overlap on all axes, boxes intersect
}
function colFlagTest(){
%conObj = LocalClientConnection.player; //LocalClientConnection.getControlObject();
%flag1 = boxIntersect(%conObj,$TeamFlag[1]);
%flag2 = boxIntersect(%conObj,$TeamFlag[2]);
%flag1AABB = boxIntersectAABB(%conObj, $TeamFlag[1], %conObj.getPosition());
%flag2AABB = boxIntersectAABB(%conObj, $TeamFlag[2], %conObj.getPosition());
error("test" SPC "Flag 1" SPC %flag1 SPC "Flag 2" SPC %flag2);
error("test" SPC "Flag 1A" SPC %flag1AABB SPC "Flag 2A" SPC %flag2AABB);
bottomprint(%conObj.client, "FlagS" SPC %flag1 SPC "FlagI" SPC %flag2 SPC "FlagS AABB" SPC %flag1AABB SPC "FlagI AABB" SPC %flag2AABB, 5, 1);
}
function testFlagSpeed(%speed){
%player = LocalClientConnection.player;
%fvec = %player.getForwardVector();
%vel = vectorScale(%fvec,%speed);
%player.setVelocity(%vel);
}

View file

@ -191,10 +191,9 @@ function ALTsendModInfoToClient(%client)
%rapeppl = "<color:" @ $Host::LoadScreenColor1 @ ">Min No Base Rape: <color:" @ $Host::LoadScreenColor2 @ ">" @ $Host::NoBaseRapePlayerCount;
%turrets = "<color:" @ $Host::LoadScreenColor1 @ ">Min Turrets: <color:" @ $Host::LoadScreenColor2 @ ">" @ $Host::EnableTurretPlayerCount;
if($Host::ClassicEvoStats && $Host::ClassicStatsType > 0)
%stats = "<color:" @ $Host::LoadScreenColor1 @ ">Stats based on: <color:" @ $Host::LoadScreenColor2 @ ">" @ ($Host::ClassicStatsType == 1 ? "Kills" : "Damage");
if($dtStats::evoStyleDebrief)
%stats = "<color:" @ $Host::LoadScreenColor1 @ ">Stats based on: <color:" @ $Host::LoadScreenColor2 @ ">" @ "Kills & Damage";
%currentmis = "<color:" @ $Host::LoadScreenColor1 @ ">Current mission: <color:" @ $Host::LoadScreenColor2 @ ">" @ $MissionDisplayName @ " (" @ $MissionTypeDisplayName @ ")";
@ -410,8 +409,8 @@ function NORMALsendModInfoToClient(%client)
%turrets = "<color:" @ $Host::LoadScreenColor1 @ ">Min Turrets: <color:" @ $Host::LoadScreenColor2 @ ">" @ $Host::EnableTurretPlayerCount;
if($Host::ClassicEvoStats && $Host::ClassicStatsType > 0)
%stats = "<color:" @ $Host::LoadScreenColor1 @ ">Stats based on: <color:" @ $Host::LoadScreenColor2 @ ">" @ ($Host::ClassicStatsType == 1 ? "Kills" : "Damage");
if($dtStats::evoStyleDebrief)
%stats = "<color:" @ $Host::LoadScreenColor1 @ ">Stats based on: <color:" @ $Host::LoadScreenColor2 @ ">" @ "Kills & Damage";
//if($Evo::ETMMode && $ETMmode::CurrentMap <= $ETMmode::Counter)
//{

File diff suppressed because it is too large Load diff

View file

@ -771,9 +771,6 @@ function DefaultGame::sendDebriefing( %game, %client )
messageClient( %client, 'MsgDebriefAddLine', "", '<lmargin:0><clip%%:60> %1</clip><lmargin%%:60><clip%%:40> %2</clip>', %cl.name, %score);
}
}
if($Host::ClassicEvoStats && ($CurrentMissionType $= "CTF" || $CurrentMissionType $= "SCtF"))
sendEvoDebriefing(%client);
}
@ -1757,12 +1754,6 @@ function DefaultGame::clientMissionDropReady(%game, %client)
%client.observerStartTime = getSimTime();
commandToClient(%client, 'setHudMode', 'Observer');
%client.setControlObject( %client.camera );
//displayObserverHud( %client, 0 );
// Eolk - flag stats stuff
//updateObserverFlyHud(%client);
if($Host::ClassicEvoStats && ($CurrentMissionType $= "CTF" || $CurrentMissionType $= "SCtF"))
schedule(10000, %client, updateObserverFlyHud, %client);
}
if( !%observer )
@ -1783,17 +1774,6 @@ function DefaultGame::clientMissionDropReady(%game, %client)
%client.setControlObject( %client.player );
}
}
if( $Host::ClassicEvoStats && ($CurrentMissionType $= "CTF" || $CurrentMissionType $= "SCtF"))
{
%nickTeam1 = ($flagstats::heldTeam1 ? $flagstats::nickTeam1 : "N/A");
%realTeam1 = ($flagstats::heldTeam1 ? $flagstats::realTeam1 : "N/A");
%nickTeam2 = ($flagstats::heldTeam2 ? $flagstats::nickTeam2 : "N/A");
%realTeam2 = ($flagstats::heldTeam2 ? $flagstats::realTeam2 : "N/A");
BottomPrint(%client, "Best caps on " @ $CurrentMission @ ":\n" @ getTaggedString(%game.getTeamName(1)) @ ":" SPC %nickTeam1 @ " in " @ %realTeam1 @ " seconds\n" @ getTaggedString(%game.getTeamName(2)) @ ":" SPC %nickTeam2 @ " in " @ %realTeam2 @ " seconds", 20, 3);
}
}
else
{

View file

@ -145,6 +145,7 @@ function CreateServer(%mission, %missionType)
exec("scripts/defaultGame.cs");
exec("scripts/CTFGame.cs");
exec("scripts/SCtFGame.cs");
exec("scripts/LCTFGame.cs");
exec("scripts/PracticeCTFGame.cs");
exec("scripts/TeamHuntersGame.cs");
exec("scripts/SinglePlayerGame.cs");
@ -175,6 +176,7 @@ function CreateServer(%mission, %missionType)
(%type !$= PracticeCTFGame) &&
(%type !$= RabbitGame) &&
(%type !$= SCtFGame) &&
(%type !$= LCTFGame) &&
(%type !$= SiegeGame) &&
(%type !$= SinglePlayerGame) &&
(%type !$= TeamHuntersGame) &&
@ -1248,30 +1250,6 @@ function loadMission( %missionName, %missionType, %firstMission )
sendLoadInfoToClient( %client );
}
if($Host::ClassicEvoStats)
{
deleteVariables("$*stats::*");
if(%missionType $= "CTF" || %missionType $= "SCtF")
{
%fileIn = "stats/maps/classic/" @ %missionType @ "/" @ %missionName @ ".txt";
// Initialize the file if not exist
if(!isFile(%fileIn))
{
$flagstats::heldTeam1 = 0;
$flagstats::realTeam1 = 0;
$flagstats::nickTeam1 = 0;
$flagstats::heldTeam2 = 0;
$flagstats::realTeam2 = 0;
$flagstats::nickTeam2 = 0;
export("$flagstats::*", %fileIn, false);
}
exec(%fileIn);
}
}
// Eolk - Testing new stuff to make map rotation less stale.
if($CurrentMissionType !$= %missionType && !%firstMission)
deleteVariables("$MapPlayed*");

View file

@ -132,7 +132,7 @@ $Host::PUGautoPassword = 0; //Auto enable a password in tournament mode
$Host::PUGPassword = "pickup"; //PUG password, Auto or enable/disable thru admin menu
$Host::PUGpasswordAlwaysOn = 0; //If you want the pug password Always on
$Host::DMSLOnlyMode = 0; //Shocklance Only Mode for Deathmatch
$Host::SCtFProMode = 0; //Pro mode for LCTF
$Host::LCTFProMode = 0; //Pro mode for LCTF
$Host::LoadingScreenUseDebrief = 1; //Enable Debrief Style Loading screen; Gives you more lines and MOTD
$Host::LoadScreenColor1 = "05edad"; //Loading Screen color; First Column
$Host::LoadScreenColor2 = "29DEE7"; //Loading Screen color; Second Column
@ -164,8 +164,6 @@ $Host::ClassicMOTDLines = 3;
$Host::ClassicMOTDTime = 6;
$Host::ClassicRotationCustom = 1;
$Host::ClassicRotationFile = "prefs/mapRotation.cs";
$Host::ClassicEvoStats = 1; //See Evo stats at the end of the mission
$Host::ClassicStatsType = 2; //Evo stats, Damage or Kills
$Host::ClassicViralBanning = 1; //Ban ip and other accounts if a banned player trys to rejoin
$Host::ClassicWhitelist = "prefs/whitelist.cs";
$Host::ClassicSuppressTraversalRootError = 1; //Suppress console spam error on certain indoor maps