mirror of
https://github.com/exogen/t2-mapper.git
synced 2026-01-19 20:25:01 +00:00
318 lines
10 KiB
C#
318 lines
10 KiB
C#
|
|
// Roles
|
||
|
|
$TR2::role[0] = Goalie;
|
||
|
|
$TR2::role[1] = Defense;
|
||
|
|
$TR2::role[2] = Offense;
|
||
|
|
$TR2::numRoles = 3;
|
||
|
|
|
||
|
|
// For some reason the above "strings" convert to all lowercase
|
||
|
|
$TR2::roleText[Goalie] = "Goalie";
|
||
|
|
$TR2::roleText[Defense] = "Defense";
|
||
|
|
$TR2::roleText[Offense] = "Offense";
|
||
|
|
|
||
|
|
$TR2::roleMax[Goalie] = 1;
|
||
|
|
$TR2::roleMax[Defense] = 2;
|
||
|
|
$TR2::roleMax[Offense] = 10;
|
||
|
|
|
||
|
|
$TR2::roleArmor[Goalie] = Heavy;
|
||
|
|
$TR2::roleArmor[Defense] = Medium;
|
||
|
|
$TR2::roleArmor[Offense] = Light;
|
||
|
|
|
||
|
|
// Roles are automated via concentric circles around goals
|
||
|
|
$TR2::roleDistanceFromGoal[Goalie] = 70;
|
||
|
|
$TR2::roleDistanceFromGoal[Defense] = 350;
|
||
|
|
$TR2::roleDistanceFromGoal[Offense] = 10000;
|
||
|
|
|
||
|
|
// Number of ticks needed before changing to this role
|
||
|
|
$TR2::roleTicksNeeded[Goalie] = 0;
|
||
|
|
$TR2::roleTicksNeeded[Defense] = 0;
|
||
|
|
$TR2::roleTicksNeeded[Offense] = 0;
|
||
|
|
|
||
|
|
// Extra items for roles
|
||
|
|
$TR2::roleExtraItem[Goalie0] = TR2Shocklance;
|
||
|
|
$TR2::roleExtraItemCount[Goalie0] = 1;
|
||
|
|
$TR2::roleExtraItem[Goalie1] = TR2Mortar;
|
||
|
|
$TR2::roleExtraItemCount[Goalie1] = 1;
|
||
|
|
$TR2::roleExtraItem[Goalie2] = TR2MortarAmmo;
|
||
|
|
$TR2::roleExtraItemCount[Goalie2] = 99;
|
||
|
|
$TR2::roleNumExtraItems[Goalie] = 3;
|
||
|
|
|
||
|
|
$TR2::roleExtraItem[Defense0] = TR2Shocklance;
|
||
|
|
$TR2::roleExtraItemCount[Defense0] = 1;
|
||
|
|
$TR2::roleNumExtraItems[Defense] = 1;
|
||
|
|
|
||
|
|
$TR2::roleNumExtraItems[Offense] = 0;
|
||
|
|
|
||
|
|
function debugPrintRoles()
|
||
|
|
{
|
||
|
|
echo("**********************************ROLE PRINT");
|
||
|
|
}
|
||
|
|
|
||
|
|
function TR2Game::resetPlayerRoles(%game)
|
||
|
|
{
|
||
|
|
%count = ClientGroup.getCount();
|
||
|
|
for (%i = 0; %i < %count; %i++)
|
||
|
|
{
|
||
|
|
%cl = ClientGroup.getObject(%i);
|
||
|
|
%game.releaseRole(%cl);
|
||
|
|
}
|
||
|
|
|
||
|
|
for (%i=0; %i<$TR2::numRoles; %i++)
|
||
|
|
%game.initRole($TR2::Role[%i]);
|
||
|
|
}
|
||
|
|
|
||
|
|
function TR2Game::initRole(%game, %role)
|
||
|
|
{
|
||
|
|
$numPlayers[%role @ 1] = 0;
|
||
|
|
$numPlayers[%role @ 2] = 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
function TR2Game::validateRoles(%game)
|
||
|
|
{
|
||
|
|
// Recalculate role counts
|
||
|
|
%count = ClientGroup.getCount();
|
||
|
|
for (%i = 0; %i<$TR2::numRoles; %i++)
|
||
|
|
{
|
||
|
|
%role = $TR2::role[%i];
|
||
|
|
%newCount[1] = 0;
|
||
|
|
%newCount[2] = 0;
|
||
|
|
|
||
|
|
for (%j = 0; %j<%count; %j++)
|
||
|
|
{
|
||
|
|
%cl = ClientGroup.getObject(%j);
|
||
|
|
if (%cl.currentRole $= %role)
|
||
|
|
%newCount[%cl.team]++;
|
||
|
|
}
|
||
|
|
$numPlayers[%role @ 1] = %newCount[1];
|
||
|
|
$numPlayers[%role @ 2] = %newCount[2];
|
||
|
|
}
|
||
|
|
|
||
|
|
// Make sure that all players are in the armor they're supposed to be in
|
||
|
|
for (%i = 0; %i < %count; %i++)
|
||
|
|
{
|
||
|
|
%cl = ClientGroup.getObject(%i);
|
||
|
|
if (!isObject(%cl) || !isObject(%cl.player))
|
||
|
|
continue;
|
||
|
|
|
||
|
|
// If somehow the player is active, but has no role, set the outer role
|
||
|
|
if (%cl.currentRole $= "")
|
||
|
|
%game.assignOutermostRole(%cl);
|
||
|
|
|
||
|
|
// If for some reason that wasn't possible, skip this player
|
||
|
|
if (%cl.currentRole $= "")
|
||
|
|
continue;
|
||
|
|
|
||
|
|
%player = %cl.player;
|
||
|
|
%armor = "TR2" @ $TR2::roleArmor[%cl.currentRole] @ %cl.sex @ HumanArmor;
|
||
|
|
|
||
|
|
// Swap armors if necessary
|
||
|
|
if (%player.getDataBlock().getName() !$= %armor)
|
||
|
|
{
|
||
|
|
// Don't allow an armor change if the player recently did something that requires
|
||
|
|
// datablock access, such as impacting the terrain. There is a T2 UE bug related
|
||
|
|
// to concurrent datablock access.
|
||
|
|
%time = getSimTime();
|
||
|
|
if (%time - %player.delayRoleChangeTime <= $TR2::datablockRoleChangeDelay)
|
||
|
|
return false;
|
||
|
|
%damagePct = %player.getDamagePercent();
|
||
|
|
%energyPct = %player.getEnergyPercent();
|
||
|
|
%player.setDataBlock(%armor);
|
||
|
|
%player.setDamageLevel(%damagePct * %player.getDataBlock().maxDamage);
|
||
|
|
%player.setEnergyLevel(%energyPct * %player.getDataBlock().maxEnergy);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
function TR2Game::trySetRole(%game, %player, %role)
|
||
|
|
{
|
||
|
|
// Check concentric circles
|
||
|
|
if (!isObject(%player))
|
||
|
|
return false;
|
||
|
|
|
||
|
|
// Don't allow an armor change if the player recently did something that requires
|
||
|
|
// datablock access, such as impacting the terrain. There is a T2 UE bug related
|
||
|
|
// to concurrent datablock access.
|
||
|
|
%time = getSimTime();
|
||
|
|
if (%time - %player.delayRoleChangeTime <= $TR2::datablockRoleChangeDelay)
|
||
|
|
return false;
|
||
|
|
|
||
|
|
%position = %player.getPosition();
|
||
|
|
%distanceToGoal = VectorLen(VectorSub(%position, $teamGoalPosition[%player.team]));
|
||
|
|
|
||
|
|
if (%distanceToGoal > $TR2::roleDistanceFromGoal[%role])
|
||
|
|
{
|
||
|
|
%player.client.roleChangeTicks[%role] = 0;
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
// See if a change is even necessary
|
||
|
|
if (%player.client.currentRole $= %role)
|
||
|
|
{
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Make sure a spot is available
|
||
|
|
if ($numPlayers[%role @ %player.team] >= $TR2::roleMax[%role])
|
||
|
|
{
|
||
|
|
//echo("****ROLES: No slots left for " @ %role);
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
// Make sure enough time has been spent in this zone
|
||
|
|
if (%player.client.roleChangeTicks[%role] < $TR2::roleTicksNeeded[%role])
|
||
|
|
{
|
||
|
|
%player.client.roleChangeTicks[%role]++;
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
%team = %player.team;
|
||
|
|
|
||
|
|
|
||
|
|
// Change roles
|
||
|
|
// First release the old role, if applicable
|
||
|
|
if (%player.client.currentRole !$= "")
|
||
|
|
{
|
||
|
|
//echo("TEAM " @ %player.team @ " ROLE CHANGE: "
|
||
|
|
// @ %player.client.currentRole
|
||
|
|
// @ "(" @ $numPlayers[%player.client.currentRole @ %team] @ ") "
|
||
|
|
// @ " to "
|
||
|
|
// @ %role
|
||
|
|
// @ "(" @ $numPlayers[%role @ %team] @ ")"
|
||
|
|
//);
|
||
|
|
$numPlayers[%player.client.currentRole @ %team]--;
|
||
|
|
|
||
|
|
// Debug the decrement
|
||
|
|
if ($numPlayers[%player.client.currentRole @ %team] < 0)
|
||
|
|
{
|
||
|
|
echo("**ROLE CHANGE ERROR: negative role count");
|
||
|
|
$numPlayers[%player.client.currentRole @ %team] = 0;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// Now switch to the new role
|
||
|
|
$numPlayers[%role @ %team]++;
|
||
|
|
%newArmor = "TR2" @ $TR2::roleArmor[%role] @ %player.client.sex @ HumanArmor;
|
||
|
|
%player.client.roleChangeTicks[%role] = 0;
|
||
|
|
%player.setInvincible(false);
|
||
|
|
|
||
|
|
// Swap armors if necessary
|
||
|
|
if (%player.getDataBlock().getName() !$= %newArmor)
|
||
|
|
{
|
||
|
|
%damagePct = %player.getDamagePercent();
|
||
|
|
%energyPct = %player.getEnergyPercent();
|
||
|
|
//echo(" ROLE: " @ %damagePct @ " damage");
|
||
|
|
//echo(" ROLE: " @ %energyPct @ " energy");
|
||
|
|
//echo(" ROLE: pre-armorSwitchSched = " @ %player.armorSwitchSchedule);
|
||
|
|
%player.setDataBlock(%newArmor);
|
||
|
|
//echo(" ROLE: post-armorSwitchSched = " @ %player.armorSwitchSchedule);
|
||
|
|
%player.setDamageLevel(%damagePct * %player.getDataBlock().maxDamage);
|
||
|
|
%player.setEnergyLevel(%energyPct * %player.getDataBlock().maxEnergy);
|
||
|
|
}
|
||
|
|
%player.client.currentRole = %role;
|
||
|
|
|
||
|
|
// Equipment changes
|
||
|
|
%game.equipRoleWeapons(%player.client);
|
||
|
|
|
||
|
|
messageClient(%player.client, 'TR2ArmorChange', "\c3ROLE CHANGE: \c4" @ $TR2::roleText[%role] @ ".");
|
||
|
|
serverPlay3D(RoleChangeSound, %player.getPosition());
|
||
|
|
// Particle effect too?
|
||
|
|
//%newEmitter = new ParticleEmissionDummy(RoleChangeEffect) {
|
||
|
|
//position = %player.getTransform();
|
||
|
|
//rotation = "1 0 0 0";
|
||
|
|
//scale = "1 1 1";
|
||
|
|
//dataBlock = "defaultEmissionDummy";
|
||
|
|
//emitter = "RoleChangeEmitter";
|
||
|
|
//velocity = "1";
|
||
|
|
//};
|
||
|
|
//%newEmitter.schedule(800, "delete");
|
||
|
|
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
function TR2Game::updateRoles(%game)
|
||
|
|
{
|
||
|
|
%count = ClientGroup.getCount();
|
||
|
|
|
||
|
|
for (%i = 0; %i < %count; %i++)
|
||
|
|
{
|
||
|
|
%cl = ClientGroup.getObject(%i);
|
||
|
|
if (%cl $= "" || %cl.player == 0 || %cl.player $= "")
|
||
|
|
continue;
|
||
|
|
|
||
|
|
%done = false;
|
||
|
|
for (%j = 0; %j < $TR2::numRoles && !%done; %j++)
|
||
|
|
{
|
||
|
|
if (%game.trySetRole(%cl.player, $TR2::role[%j]))
|
||
|
|
%done = true;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
function TR2Game::equipRoleWeapons(%game, %client)
|
||
|
|
{
|
||
|
|
%player = %client.player;
|
||
|
|
|
||
|
|
// Get rid of existing extra weapon
|
||
|
|
for (%i=0; %i<%client.extraRoleItems; %i++)
|
||
|
|
{
|
||
|
|
%item = %client.extraRoleItem[%i];
|
||
|
|
|
||
|
|
// If the player is using the item we're about to take away, equip
|
||
|
|
// the disc launcher
|
||
|
|
%equippedWeapon = %player.getMountedImage($WeaponSlot).item;
|
||
|
|
if (%equippedWeapon $= %item)
|
||
|
|
%player.use(TR2Disc);
|
||
|
|
|
||
|
|
%player.setInventory(%item, 0);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Clear HUD
|
||
|
|
%client.setWeaponsHudItem(TR2Shocklance, 0, 0);
|
||
|
|
%client.setWeaponsHudItem(TR2Mortar, 0, 0);
|
||
|
|
|
||
|
|
// Equip role items
|
||
|
|
%client.extraRoleItems = $TR2::roleNumExtraItems[%client.currentRole];
|
||
|
|
for (%i=0; %i<%client.extraRoleItems; %i++)
|
||
|
|
{
|
||
|
|
%item = $TR2::roleExtraItem[%client.currentRole @ %i];
|
||
|
|
%roleItemAmount = $TR2::roleExtraItemCount[%client.currentRole @ %i];
|
||
|
|
|
||
|
|
// Hmm, this actually works, but it remembers that you
|
||
|
|
// lose your mortar ammo after a role switch. Get rid of it
|
||
|
|
// for now since there's unlimited mortar ammo anyway.
|
||
|
|
//if (%client.restockAmmo || %roleItemAmount == 1)
|
||
|
|
%itemAmount = %roleItemAmount;
|
||
|
|
//else
|
||
|
|
// %itemAmount = %client.lastRoleItemCount[%i];
|
||
|
|
%player.setInventory(%item, %itemAmount);
|
||
|
|
%client.extraRoleItem[%i] = %item;
|
||
|
|
%client.extraRoleItemCount[%i] = %itemAmount;
|
||
|
|
|
||
|
|
// Re-equip, if necessary
|
||
|
|
if (%item $= %equippedWeapon)
|
||
|
|
%player.use(%item);
|
||
|
|
}
|
||
|
|
//echo(" ROLE: weapons equipped.");
|
||
|
|
}
|
||
|
|
|
||
|
|
function TR2Game::releaseRole(%game, %client)
|
||
|
|
{
|
||
|
|
if (%client.currentRole $= "")
|
||
|
|
return;
|
||
|
|
|
||
|
|
//echo(" ROLE: client " @ %client @ " released " @ %client.currentRole);
|
||
|
|
|
||
|
|
$numPlayers[%client.currentRole @ %client.team]--;
|
||
|
|
%client.currentRole = "";
|
||
|
|
}
|
||
|
|
|
||
|
|
function TR2Game::assignOutermostRole(%game, %client)
|
||
|
|
{
|
||
|
|
//$role[%client.currentRole @ %client.team @ %i] = "";
|
||
|
|
//$numPlayers[%client.currentRole @ %client.team]--;
|
||
|
|
//%client.currentRole = $TR2::role[$TR2::numRoles-1];
|
||
|
|
//echo(" ROLE: assigning outermost");
|
||
|
|
%outerRole = $TR2::role[$TR2::numRoles-1];
|
||
|
|
if (%client.player > 0 && %client.currentRole !$= %outerRole)
|
||
|
|
%game.trySetRole(%client.player, %outerRole);
|
||
|
|
}
|
||
|
|
|