Browse Source

Import AOW2 source

tags/r189
Sean Baggaley 2 months ago
commit
b312db49f7
100 changed files with 23559 additions and 0 deletions
  1. 25
    0
      .gitattributes
  2. 9
    0
      .gitignore
  3. 264
    0
      src/acs_source/a_admin.acs
  4. 239
    0
      src/acs_source/a_armor.acs
  5. 141
    0
      src/acs_source/a_basehud.acs
  6. 438
    0
      src/acs_source/a_bases.acs
  7. 237
    0
      src/acs_source/a_botmarines.acs
  8. 40
    0
      src/acs_source/a_bots.acs
  9. 476
    0
      src/acs_source/a_classes.acs
  10. 456
    0
      src/acs_source/a_client.acs
  11. 541
    0
      src/acs_source/a_core.acs
  12. 930
    0
      src/acs_source/a_crate.acs
  13. 219
    0
      src/acs_source/a_credits.acs
  14. 150
    0
      src/acs_source/a_death.acs
  15. 486
    0
      src/acs_source/a_defs.acs
  16. 198
    0
      src/acs_source/a_donate.acs
  17. 720
    0
      src/acs_source/a_functions.acs
  18. 126
    0
      src/acs_source/a_gameconfig.acs
  19. 80
    0
      src/acs_source/a_hax.acs
  20. 369
    0
      src/acs_source/a_hud.acs
  21. 169
    0
      src/acs_source/a_items.acs
  22. 140
    0
      src/acs_source/a_jetpack.acs
  23. 59
    0
      src/acs_source/a_mapconfig.acs
  24. 607
    0
      src/acs_source/a_mechs.acs
  25. 650
    0
      src/acs_source/a_menu.acs
  26. 65
    0
      src/acs_source/a_menu_factory.acs
  27. 99
    0
      src/acs_source/a_menu_opendeck.acs
  28. 328
    0
      src/acs_source/a_menu_purchase.acs
  29. 51
    0
      src/acs_source/a_menu_research.acs
  30. 128
    0
      src/acs_source/a_menu_util.acs
  31. 241
    0
      src/acs_source/a_misc.acs
  32. 177
    0
      src/acs_source/a_netscripts.acs
  33. 154
    0
      src/acs_source/a_nukes.acs
  34. 39
    0
      src/acs_source/a_opendeck.acs
  35. 316
    0
      src/acs_source/a_preferences.acs
  36. 231
    0
      src/acs_source/a_printf.acs
  37. 72
    0
      src/acs_source/a_regen.acs
  38. 232
    0
      src/acs_source/a_repair.acs
  39. 72
    0
      src/acs_source/a_repfac.acs
  40. 194
    0
      src/acs_source/a_research.acs
  41. 163
    0
      src/acs_source/a_spawnroom.acs
  42. 243
    0
      src/acs_source/a_staticdata.acs
  43. 116
    0
      src/acs_source/a_stealth.acs
  44. 105
    0
      src/acs_source/a_suddendeath.acs
  45. 102
    0
      src/acs_source/a_surrender.acs
  46. 3
    0
      src/acs_source/a_svnrevision.acs
  47. 208
    0
      src/acs_source/a_sync.acs
  48. 155
    0
      src/acs_source/a_teambalance.acs
  49. 262
    0
      src/acs_source/a_teleporter.acs
  50. 77
    0
      src/acs_source/a_tiberium.acs
  51. 114
    0
      src/acs_source/a_timegun.acs
  52. 274
    0
      src/acs_source/a_tortoise.acs
  53. 158
    0
      src/acs_source/a_utildefs.acs
  54. 934
    0
      src/acs_source/a_utility.acs
  55. 240
    0
      src/acs_source/a_xp.acs
  56. 696
    0
      src/acs_source/aow2scrp.acs
  57. 41
    0
      src/actors/crucial/acsitems.txt
  58. 297
    0
      src/actors/crucial/armor.txt
  59. 163
    0
      src/actors/crucial/berserk.txt
  60. 215
    0
      src/actors/crucial/btos.txt
  61. 59
    0
      src/actors/crucial/constants.txt
  62. 279
    0
      src/actors/crucial/deadthings.txt
  63. 100
    0
      src/actors/crucial/gameconfig.txt
  64. 122
    0
      src/actors/crucial/infoitems.txt
  65. 372
    0
      src/actors/crucial/obelisk.txt
  66. 393
    0
      src/actors/crucial/player.txt
  67. 56
    0
      src/actors/crucial/puffs.txt
  68. 72
    0
      src/actors/crucial/skeletal.txt
  69. 317
    0
      src/actors/crucial/terminals.txt
  70. 44
    0
      src/actors/effects/PuffSpark.txt
  71. 1864
    0
      src/actors/effects/boiling.txt
  72. 148
    0
      src/actors/effects/casings.txt
  73. 380
    0
      src/actors/effects/debris.txt
  74. 93
    0
      src/actors/effects/explosiondebris.txt
  75. 266
    0
      src/actors/effects/explosions.txt
  76. 162
    0
      src/actors/effects/gibs.txt
  77. 69
    0
      src/actors/effects/gore.txt
  78. 708
    0
      src/actors/effects/ion.txt
  79. 71
    0
      src/actors/effects/laserchaingunlights.txt
  80. 24
    0
      src/actors/effects/misceffects.txt
  81. 132
    0
      src/actors/effects/muzzles.txt
  82. 462
    0
      src/actors/effects/nuke.txt
  83. 56
    0
      src/actors/effects/particles.txt
  84. 75
    0
      src/actors/effects/powerpad.txt
  85. 30
    0
      src/actors/effects/powerplantsmoke.txt
  86. 51
    0
      src/actors/effects/puffsmoke.txt
  87. 102
    0
      src/actors/effects/steam.txt
  88. 136
    0
      src/actors/items/armoritems.txt
  89. 66
    0
      src/actors/items/backpack.txt
  90. 422
    0
      src/actors/items/beacons.txt
  91. 61
    0
      src/actors/items/credits.txt
  92. 181
    0
      src/actors/items/medicationfield.txt
  93. 117
    0
      src/actors/items/opendeck.txt
  94. 299
    0
      src/actors/items/powerupcrate.txt
  95. 146
    0
      src/actors/items/proxymine.txt
  96. 194
    0
      src/actors/items/remotec4.txt
  97. 277
    0
      src/actors/items/secrets.txt
  98. 202
    0
      src/actors/items/tiberium.txt
  99. 217
    0
      src/actors/items/timedc4.txt
  100. 0
    0
      src/actors/marines/compensation.txt

+ 25
- 0
.gitattributes View File

@@ -0,0 +1,25 @@
# Auto detect text files and perform LF normalization
* text=auto

# Images
*.png binary
*.jpg binary
*.raw binary

# Sounds
*.ogg binary
*.spc binary
*.wav binary
*.vgm binary
*.nsf binary

# Doom stuff
*.lmp binary
*.wad binary
TEXTURE1* binary
PNAMES* binary
*.acs linguist-language=C

# JM build stuff
utilities/*.exe binary
utilities/*.acs linguist-vendored

+ 9
- 0
.gitignore View File

@@ -0,0 +1,9 @@
# Compiled ACS
*.o

# Doom Builder stuff
*.bak
*.dbs
*.backup1
*.backup2
*.backup3

+ 264
- 0
src/acs_source/a_admin.acs View File

@@ -0,0 +1,264 @@
// [SP] NOTICE: This is an administrator 'puke' script. USE WITH CARE! This can be abused very easily.
script SC_ADMIN_RCON (int Player,int Action) {
// [Dusk] {9/11/12} Since Zandronum now stupidly claims that the rcon user is a cheater,
// display a hudmessage showing the real nature of this script command. The only other
// option is a rather crude hack and I'd probably invoke a flamewar if I did that.
if (NetState == NETSTATE_Server) {
HudMessage (s:"This script is invoked from an RCON alias. ",
s:"An admin is probably doing cleanup work";
HUDMSG_PLAIN|HUDMSG_LOG, 12345, CR_GRAY, 0, 0, 0);
ClearHudMessage (12345);
}
SetActivator(3800 + Player);
switch(Action)
{
case 3:
if ( ThingCount(T_NONE,3800 + Player) == 0 ) {
Log(s:"Player #",d:Player,s:" not found!");
terminate;
}
if (PlayerIsBot (Player)) {
Log (s:"Player #", d:Player, s:" \"", n:Player+1, s:"\c-\" is a bot.");
terminate;
}
//Player_SetTeam(255);
SetPlayerProperty(0,1,1);
SetPlayerProperty(0,1,2);
SetPlayerProperty(0,1,3);
SetFont("BIGFONT");
HudMessageBold (n:0, s:"\c- becomes an \cGadministrator";
HUDMSG_FADEOUT, 1800+PlayerNumber(), CR_WHITE, 0.5, 0.45, 2.0, 1.0);
Log(s:"*** \caWARNING!\c- Game Master mode activated for ",n:Player+1,s:" \c-(IDX ",d:Player,s:") - this has been logged in the server console.");
Log(s:"*** To deactivate this mode, you (or target) must either spectate or call a_exit in console.");
Log(s:"*** Please don't abuse this! Do what you need to do, then exit this mode immediately.");
GiveInventory("AdministratorSwitch",1);
IsAdmin[Player] = true;
GiveInventory ("IsAdmin", 1);
break;
case 1:
if ( ThingCount(T_NONE,3800 + Player) == 0 )
{
Log(s:"Player ",d:Player,s:" not found!");
terminate;
}
if ( PlayerTeam() == 0 )
{
Log(s:"Player ",d:Player,s:" named ",n:0,s:" is already on Blue.");
terminate;
}
SetFont("BIGFONT");
HudMessage (n:Player, s:"\c- has been forced to\n\cKchange team\c- by an \cQadmin.";
HUDMSG_FADEOUT, 1800+PlayerNumber(), CR_GREEN, 0.5, 0.45, 2.0, 1.0);
Player_SetTeam(0);
Log(n:0,s:" forced to change to Blue by admin.");
delay(1);
Teleport(70);
GiveInventory("HasClass",1);
ACS_ExecuteAlways(95,0,0,0,0);
TakeInventory("IsRed",1);
GiveInventory("IsBlue",1);
StartTime[Player] = -0x7FFFFFFF;
break;
case 2:
if ( ThingCount(T_NONE,3800 + Player) == 0 )
{
Log(s:"Player ",d:Player,s:" not found!");
terminate;
}
if ( PlayerTeam() == 1 )
{
Log(s:"Player ",d:Player,s:" named ",n:0,s:" is already on Red.");
terminate;
}
SetFont("BIGFONT");
HudMessage (n:Player, s:"\c- has been forced to\n\cKchange team\c- by an \cQadmin.";
HUDMSG_FADEOUT, 1800+PlayerNumber(), CR_GREEN, 0.5, 0.45, 2.0, 1.0);
Player_SetTeam(1);
Log(n:0,s:" forced to change to Red by admin.");
delay(1);
Teleport(71);
GiveInventory("HasClass",1);
ACS_ExecuteAlways(95,0,0,0,0);
TakeInventory("IsBlue",1);
GiveInventory("IsRed",1);
StartTime[Player] = -0x7FFFFFFF;
break;
case 0:
switch(Player)
{
case 3:
Log(s:"Usage: gamemaster <IDX> (use 'playerinfo' to get IDX numbers)");
case 1:
Log(s:"Usage: forceblue <IDX> (use 'playerinfo' to get IDX numbers)");
case 2:
Log(s:"Usage: forcered <IDX> (use 'playerinfo' to get IDX numbers)");
default:
Log(s:"Please don't puke this script directly! Use the provided ccmd's - it's for your sanity's own good!");
}
default:
Log(s:"Unknown action!");
}
}
script SC_ADMIN_CLIENT (int Arg1, int Arg2, int Arg3) NET
{
if ( IsAdmin[PlayerNumber()] == false )
terminate;
switch(Arg1)
{
case 0:
// help!
break;
case 1:
// Warp
/*Spawn("TeleportDest",Arg2<<16,Arg3<<16,0,6003);
delay(1);
Teleport_NoFog(6003);
delay(1);
Thing_Remove(6003);*/
// [Dusk] this should be more reliable
SetActorPosition (0, arg2<<16, arg3<<16, 0, false);
break;
case 2:
// Teleport to spot
if (arg2 <= 0) {
HudMessage (s:"Usage: a_teleport <tid>\n",
s:"TIDs of interest:\n",
s:"1: blue base\t\t2: red base\n",
s:"70: blue spawn room\t71: red spawn room\n",
s:"108: blue wf hanger\t208: red wf hanger\n",
s:"110: blue mech room\t210: red mech room\n",
s:"111: blue res room\t211: red res room\n"; HUDMSG_PLAIN|HUDMSG_LOG, 9000, 0, 0, 0, 0);
HudMessage (s:""; HUDMSG_PLAIN, 9000, 0, 0, 0, 0.1);
terminate;
}
Teleport_NoFog(Arg2);
break;
case 3:
// Activate crate
ACS_ExecuteAlways (309, 0, Arg2, Arg3);
break;
case 4:
case 5:
break;
case 6:
// Toggle berserk
if (CheckInventory ("PowerBerserk")) {
TakeInventory ("PowerBerserk", 1);
delay (5);
TakeInventory ("PowerBerserkHue", 1);
delay (3);
GiveInventory ("RedHueRemover", 1);
} else {
GiveInventory ("BerserkSwitch", 1);
delay (5);
GiveInventory ("BerserkHue", 1);
}
break;
case 7:
// Instant resign
if(PlayerTeam() == TEAM_RED)
Teleport(71);
else
Teleport(70);
ACS_ExecuteAlways (95, 0);
break;
case 8:
// Give beacon item
GiveInventory("BeaconItem",1);
break;
case 9:
// Become Admin Player Again - or remove it
if (CheckInventory("PowerAdministrator")) {
TakeInventory("PowerAdministrator",1);
SetPlayerProperty(0,0,1);
SetPlayerProperty(0,0,2);
SetPlayerProperty(0,0,3);
} else {
GiveInventory("AdministratorSwitch",1);
SetPlayerProperty(0,1,1);
SetPlayerProperty(0,1,2);
SetPlayerProperty(0,1,3);
}
break;
case 10:
// Set Team
Player_SetTeam(Arg2);
if (Arg2 == TEAM_BLUE) {
TakeInventory("IsRed",1);
GiveInventory("IsBlue",1);
} else {
GiveInventory("IsRed",1);
TakeInventory("IsBlue",1);
}
break;
case 11:
// Give utility gun
GiveInventory ("RepairGun", 1);
GiveInventory ("UtilityGun", 1);
break;
case 12:
// Set speed
SetActorProperty(0, APROP_SPEED, 0.01 * Arg2);
break;
case 13:
// Admin pistol - rotate fire
if (CheckInventory ("AdminPistolRotation") == 2)
TakeInventory ("AdminPistolRotation", 2);
else
GiveInventory ("AdminPistolRotation", 1);
switch (CheckInventory ("AdminPistolRotation")) {
case 0:
HudMessage (s:"Normal mode";
HUDMSG_FADEOUT, 1800+PlayerNumber(), CR_WHITE, 0.5, 0.45, 1.0, 0.5);
break;
case 1:
HudMessage (s:"\cJRepair / Disarm mode";
HUDMSG_FADEOUT, 1800+PlayerNumber(), CR_WHITE, 0.5, 0.45, 1.0, 0.5);
break;
case 2:
HudMessage (s:"Deconstruction mode";
HUDMSG_FADEOUT, 1800+PlayerNumber(), CR_WHITE, 0.5, 0.45, 1.0, 0.5);
break;
}
break;
case 14:
// Open Deck
GiveInventory ("OpenDeck", 1);
break;
case 15:
// Notarget
SetActorProperty (0, APROP_NoTarget, !GetActorProperty (0, APROP_NoTarget));
break;
case 16:
// Exit admin mode
SetPlayerProperty (0, 0, 1);
SetPlayerProperty (0, 0, 2);
SetPlayerProperty (0, 0, 3);
SetActorProperty (0, APROP_NoTarget, 0);
SetFont("BIGFONT");
HudMessageBold (s:"Admin ", n:0, s:"\c- becomes a regular player again.";
HUDMSG_FADEOUT, 1800+PlayerNumber(), CR_WHITE, 0.5, 0.45, 2.0, 1.0);
Log (n:0, s:" (#", d:PlayerNumber(), s:") exits admin mode.");
IsAdmin[PlayerNumber()] = false;
ACS_ExecuteAlways (96, 0, 1-PlayerTeam()); // teleport to spawn room
delay (5);
ACS_ExecuteAlways (95, 0); // resign
break;
case 17:
// Set health
if (arg2 <= 0) break;
SetActorProperty (0, APROP_Health, Arg2);
break;
case 18:
// Fly
if (CheckInventory ("PowerFlight"))
TakeInventory ("PowerFlight", 1);
else
GiveInventory ("AdminFlight", 1);
break;
default:
Log(s:"Unknown action!");
}
}

+ 239
- 0
src/acs_source/a_armor.acs View File

@@ -0,0 +1,239 @@
// All Out War 2 armour manipulation scripts
// Credit to VoltlocK for originally creating the engine
// With modifications by the Omega Team

// You may use portions of this script in your project as long as you give credit where credit is
// due. Please don't be lame and just copy-paste any of this and call it your own. Thanks!

// What type is weak against what?
int ArmorWeaknesses[6] = {
ARMOD_NOCHANGE, // NOCHANGE
ARMOD_CHEM, // FIRE
ARMOD_FIRE, // CHEM
ARMOD_BULLET, // ENERGY
ARMOD_ENERGY, // EXPLO
ARMOD_EXPLO, // BULLET
};

function int GetArmorGrade (void) {
return GetPlayerArmorGrade (PlayerNumber ());
}

function int GetPlayerArmorGrade (int p) {
if (CheckActorInventory (3800 + p, "PowerGrade5Armor")) return 5;
if (CheckActorInventory (3800 + p, "PowerGrade4Armor")) return 4;
if (CheckActorInventory (3800 + p, "PowerGrade3Armor")) return 3;
if (CheckActorInventory (3800 + p, "PowerGrade2Armor")) return 2;
if (CheckActorInventory (3800 + p, "PowerGrade1Armor")) return 1;
if (CheckActorInventory (3800 + p, "PowerGradeNeg1Armor")) return -1;
return 0;
}

function int GetArmorModifier (void) {
return GetPlayerArmorModifier (PlayerNumber ());
}

function int GetPlayerArmorModifier (int p) {
if (CheckActorInventory (3800 + p, "PowerFireProof")) return ARMOD_FIRE;
if (CheckActorInventory (3800 + p, "PowerChemicalProof")) return ARMOD_CHEM;
if (CheckActorInventory (3800 + p, "PowerExplosiveResistance")) return ARMOD_EXPLO;
if (CheckActorInventory (3800 + p, "PowerEnergyResistance")) return ARMOD_ENERGY;
if (CheckActorInventory (3800 + p, "PowerBulletResistance")) return ARMOD_BULLET;
return 0;
}

// [Dusk] Set the armor grade and type
function void SetArmorGrade (int n, int mod) {
SetPlayerArmorGrade (PlayerNumber(), n, mod);
}

function void SetPlayerArmorGrade (int p, int n, int mod) {
int grade = GetPlayerArmorGrade (p);
if (n != NOCHANGE) {
if (mod & AGF_ADDITIVE) {
n += grade;
} else {
// armour upgrade
if (CheckActorInventory (3800 + p, "HasArmorUpgrade"))
n++;
}
if (n > 5) n = 5;
if (n < 0) {
// don't go to -1 with AGF_ADDITIVE
if (mod & AGF_ADDITIVE)
n = 0;
else
n = -1;
}
if ((mod & AGF_DONTSUBTRACT && n <= grade) || (mod & AGF_DONTADD && n >= grade))
return;
if (grade != n) {
SetActorInventory (3800 + p, "PowerGrade5Armor", 0);
SetActorInventory (3800 + p, "PowerGrade4Armor", 0);
SetActorInventory (3800 + p, "PowerGrade3Armor", 0);
SetActorInventory (3800 + p, "PowerGrade2Armor", 0);
SetActorInventory (3800 + p, "PowerGrade1Armor", 0);
SetActorInventory (3800 + p, "PowerGradeNeg1Armor", 0);
if (n == -1)
GiveActorInventory (3800 + p, "GradeNeg1Armor", 1);
else if (n > 0)
GiveActorInventory (3800 + p, strparam (s:"Grade", d:n, s:"Armor"), 1);
if (n == 5)
IntelMessage (strparam (n:p + 1, s:"\c- has \cKGrade 5 Armor!"), true);
}
}
// Rid the flags now
mod &= ~(AGF_ADDITIVE | AGF_DONTSUBTRACT | AGF_DONTADD);
// Give the armor type
if (mod != ARMOD_NOCHANGE) {
CheckAndRemove ("PowerFireProof");
CheckAndRemove ("PowerChemicalProof");
CheckAndRemove ("PowerBulletResistance");
CheckAndRemove ("PowerExplosiveResistance");
CheckAndRemove ("PowerEnergyResistance");
switch (mod) {
case ARMOD_FIRE:
GiveActorInventory (3800 + p, "FireProof", 1);
break;
case ARMOD_CHEM:
GiveActorInventory (3800 + p, "ChemicalProof", 1);
break;
case ARMOD_EXPLO:
GiveActorInventory (3800 + p, "ExplosiveResistance", 1);
break;
case ARMOD_ENERGY:
GiveActorInventory (3800 + p, "EnergyResistance", 1);
break;
case ARMOD_BULLET:
GiveActorInventory (3800 + p, "BulletResistance", 1);
break;
}
}
}

// for testing and decorate (ai marines, et al)
script SC_SETARMORGRADE (int grade, int mod)
SetArmorGrade (grade, mod);

// [Dusk] ARMOR DISPLAY COMMAND
// Argh! Data tables!
int ArmorNames[13] = {"PowerGrade1Armor", "PowerGrade2Armor", "PowerGrade3Armor", "PowerGrade4Armor", "PowerGrade5Armor",
"PowerGradeNeg1Armor", "PowerFireProof", "PowerChemicalProof", "PowerExplosiveResistance", "PowerEnergyResistance",
"PowerBulletResistance", "PowerChemicalResistance", "PowerGrade2ArmorFactoryPower"};
int ArmorValuesFist[13] = {0.9, 0.8, 0.7, 0.6, 0.5, 1.2,
1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.9};
int ArmorValuesBullet[13] = {0.9, 0.8, 0.7, 0.6, 0.5, 1.2,
1.0, 1.0, 1.0, 1.0, 0.5, 1.0, 0.9};
int ArmorValuesExplo[13] = {0.9, 0.8, 0.7, 0.6, 0.5, 1.2,
1.0, 1.0, 0.5, 2.0, 2.0, 1.0, 0.9};
int ArmorValuesAntiArmor[13] = {0.9, 0.8, 0.7, 0.6, 0.5, 1.2,
1.0, 1.0, 0.5, 2.0, 1.0, 1.0, 0.9};
int ArmorValuesFire[13] = {0.9, 0.8, 0.7, 0.6, 0.5, 1.2,
0.0, 2.0, 1.0, 1.0, 1.0, 2.0, 0.9};
int ArmorValuesChem[13] = {0.9, 0.8, 0.7, 0.6, 0.5, 1.2,
2.0, 0.0, 1.0, 1.0, 1.0, 0.5, 0.9};
int ArmorValuesEnergy[13] = {0.9, 0.8, 0.7, 0.6, 0.5, 1.2,
1.0, 1.0, 2.0, 0.5, 2.0, 1.0, 0.9};

script SC_CCMD_SHOWARMOR (void) NET CLIENTSIDE {
int fist, bullet, explo, antiarmor, fire, chem, energy;
if (CheckInventory ("IsMech")) {
// Mech damage factors
fist = 0.35;
bullet = 0.8;
explo = 1.35;
antiarmor = 2.0;
fire = 1.25;
chem = 1.75;
energy = 1.0;
} else {
// Infantry damage factors
fist = 1.0;
bullet = 1.0;
explo = 1.0;
antiarmor = 1.0;
fire = 1.0;
if (CheckInventory ("PowerBerserk"))
chem = 2.25;
else
chem = 1.0;
energy = 1.0;
}
for (int i = 0; i < 13; i++) {
if (CheckInventory (ArmorNames[i])) {
fist = FixedMul (fist, ArmorValuesFist[i]);
bullet = FixedMul (bullet, ArmorValuesBullet[i]);
explo = FixedMul (explo, ArmorValuesExplo[i]);
antiarmor = FixedMul (antiarmor, ArmorValuesAntiArmor[i]);
fire = FixedMul (fire, ArmorValuesFire[i]);
chem = FixedMul (chem, ArmorValuesChem[i]);
energy = FixedMul (energy, ArmorValuesEnergy[i]);
}
}
Log (s:"CURRENT DAMAGE FACTORS: \cJ", f:fist,
s:" \cU", f:bullet,
s:" \cG", f:fire,
s:" \cD", f:chem,
s:" \cN", f:energy,
s:" \cF", f:explo,
s:" \cI", f:antiarmor);
}

function void AddArmor (int n) {
SetArmorGrade (n, AGF_ADDITIVE | ARMOD_NOCHANGE);
}

function void AddPlayerArmor (int p, int n) {
SetPlayerArmorGrade (p, n, AGF_ADDITIVE | ARMOD_NOCHANGE);
}

// [Dusk] Armor type change script
script SC_ARMORITEMUSE (int modtype) {
GiveInventory ("IsChangingArmor", 1);
ACS_ExecuteAlways (SC_CL_ARMORPREDICT, 0, modtype);
int n = 5;
while (n > 0) {
if (GetHealth() <= 0)
terminate;
delay (35);
n--;
}
TakeInventory ("IsChangingArmor", 1);
ActivatorSound ("misc/armor_pkup", 127);
SetArmorGrade (NOCHANGE, modtype);
}

// [Dusk] Client-side progress prediction
script SC_CL_ARMORPREDICT (int modtype) CLIENTSIDE {
if (PlayerNumber() != consoleplayer)
terminate;
TakeInventory ("ArmorChangeProgress", 175);
int n = 175;
while (n > 0) {
if (GetHealth() <= 0)
terminate;
GiveInventory ("ArmorChangeProgress", 1);
delay (1);
n--;
}
TakeInventory ("ArmorChangeProgress", 175);
}

+ 141
- 0
src/acs_source/a_basehud.acs View File

@@ -0,0 +1,141 @@
// BUILDING HUD FUNCTIONALITY
function void CL_DisplayBuildingHud (void) {
SetHUDFont ();
// If we want no hud, clear it
if (GetCVar ("aow_cl_nohud")) {
ClearHudMessage (8850);
ClearHudMessage (8851);
ClearHudMessage (8852);
return;
}
int bluey = 0.52;
// [Dusk] {9/23/12} In smaller resolutions, we need to shove the blue
// team base HUD a bit up or it will overlap with the red one
if (GetCVar ("vid_defheight") <= 400)
bluey = 0.46;
HudMessageBold (s:ExistsBuilding (101), s:"Barracks\cc: ",
s:ColorCodeHealth(GetActorSpeed (101)), d:GetActorSpeed (101), s:"\cc%\n",
s:ExistsBuilding (103), s:"Refinery\cc: ",
s:ColorCodeHealth(GetActorSpeed (103)), d:GetActorSpeed (103), s:"\cc%\n",
s:ExistsBuilding (105), s:"Research Centre\cc: ",
s:ColorCodeHealth(GetActorSpeed (105)), d:GetActorSpeed (105), s:"\cc%\n",
s:ExistsBuilding (107), s:"War Factory\cc: ",
s:ColorCodeHealth(GetActorSpeed (107)), d:GetActorSpeed (107), s:"\cc%\n",
s:ExistsBuilding (114), s:"Obelisk of Light\cc: ",
s:ColorCodeHealth(GetActorSpeed (114)), d:GetActorSpeed (114), s:"\cc%\n",
s:ExistsBuildingGreen (109), s:"++", s:ExistsBuilding (109), s:"Repair Facility\cc: ",
s:ColorCodeHealth(GetActorSpeed (109)), d:GetActorSpeed (109), s:"\cc%\n",
s:ExistsBuildingGreen (903), s:"++", s:ExistsBuilding (903), s:"HP Regen\cc: ",
s:ColorCodeHealth(GetActorSpeed (903)), d:GetActorSpeed (903), s:"\cc%\n",
s:ExistsBuildingGreen (905), s:"++", s:ExistsBuilding (905), s:"Ammo Regen\cc: ",
s:ColorCodeHealth (GetActorSpeed (905)), d:GetActorSpeed (905), s:"\cc%\n",
s:ExistsBuildingGreen(901), s:"++", s:ExistsBuilding (901), s:"Mini Refinery\cc: ",
s:ColorCodeHealth(GetActorSpeed (901)), d:GetActorSpeed (901), s:"\cc%\n",
s:PortalLinkColor (TEAM_BLUE, 0), s:"++", s:PortalLinkColor (TEAM_BLUE, 1), s:"Teleporter\cc: ",
s:ColorCodeHealth(PortalHealth (TID_TELENODE_BLUE1)), d:PortalHealth (TID_TELENODE_BLUE1), s:"\cc% / ",
s:ColorCodeHealth(PortalHealth (TID_TELENODE_BLUE2)), d:PortalHealth (TID_TELENODE_BLUE2), s:"\cc%";
HUDMSG_PLAIN, 8850, CR_BLUE, 0.012, bluey, 0.0);
HudMessageBold (s:ExistsBuilding (201), s:"Barracks\cc: ",
s:ColorCodeHealth(GetActorSpeed (201)), d:GetActorSpeed (201), s:"\cc%\n",
s:ExistsBuilding (203), s:"Refinery\cc: ",
s:ColorCodeHealth(GetActorSpeed (203)), d:GetActorSpeed (203), s:"\cc%\n",
s:ExistsBuilding (205), s:"Research Centre\cc: ",
s:ColorCodeHealth(GetActorSpeed (205)), d:GetActorSpeed (205), s:"\cc%\n",
s:ExistsBuilding (207), s:"War Factory\cc: ",
s:ColorCodeHealth(GetActorSpeed (207)), d:GetActorSpeed (207), s:"\cc%\n",
s:ExistsBuilding (214), s:"Obelisk of Light\cc: ",
s:ColorCodeHealth(GetActorSpeed (214)), d:GetActorSpeed (214), s:"\cc%\n",
s:ExistsBuildingGreen (209), s:"++", s:ExistsBuilding (209), s:"Repair Facility\cc: ",
s:ColorCodeHealth(GetActorSpeed (209)), d:GetActorSpeed (209), s:"\cc%\n",
s:ExistsBuildingGreen (902), s:"++", s:ExistsBuilding (902), s:"HP Regen\cc: ",
s:ColorCodeHealth(GetActorSpeed (902)), d:GetActorSpeed (902), s:"\cc%\n",
s:ExistsBuildingGreen (904), s:"++", s:ExistsBuilding (904), s:"Ammo Regen\cc: ",
s:ColorCodeHealth (GetActorSpeed (904)), d:GetActorSpeed (904), s:"\cc%\n",
s:ExistsBuildingGreen(900), s:"++", s:ExistsBuilding (900), s:"Mini Refinery\cc: ",
s:ColorCodeHealth(GetActorSpeed (900)), d:GetActorSpeed (900), s:"\cc%\n",
s:PortalLinkColor (TEAM_RED, 0), s:"++", s:PortalLinkColor (TEAM_RED, 1), s:"Teleporter\cc: ",
s:ColorCodeHealth(PortalHealth (TID_TELENODE_RED1)), d:PortalHealth (TID_TELENODE_RED1), s:"\cc% / ",
s:ColorCodeHealth(PortalHealth (TID_TELENODE_RED2)), d:PortalHealth (TID_TELENODE_RED2), s:"\cc%";
HUDMSG_PLAIN, 8851, CR_RED, 0.012, 0.74, 0.0);
/*int bluelives = GetActorSpeed (TID_TICKETCOUNTER_BLUE);
int redlives = GetActorSpeed (TID_TICKETCOUNTER_RED);*/
int bluelives = Tickets[TEAM_BLUE];
int redlives = Tickets[TEAM_RED];
if (GetCVar ("aow_forcelivehud") || bluelives || redlives) {
int startlives = Config[CONFIG_STARTTICKETS][PEER_CLIENT];
SetFont ("SMALLFONT");
HudMessageBold (
s:"\cHLives\cC: ", s:FractionColor (bluelives, startlives), d:bluelives,
s:"\n\cGLives\cC: ", s:FractionColor (redlives, startlives), d:redlives;
HUDMSG_PLAIN, 8852, CR_BLUE, 0.012, 0.4, 0.0);
}
}

function int PortalHealth (int t) {
if (!ThingCount (T_NONE, t)) return 0;
int s = GetActorSpeed (t);
if (s < 0) return 0;
return s;
}

function str PortalLinkColor (int team, int teamcolor) {
int t1 = TID_TELENODE_BLUE1 + 2*team;
int t2 = TID_TELENODE_BLUE2 + 2*team;
int exists = ThingCount (T_NONE, t1) && ThingCount (T_NONE, t2);
if (exists) {
if (!teamcolor)
return "\cD";
if (team == TEAM_BLUE)
return "\cH";
return "\cG";
}
if (!teamcolor)
return "\cQ";
if (GetCVar ("aow_cl_confonthud"))
return "\cU";
return "\cM";
}

function str ColorCodeHealth(int Percentage)
{
if (Percentage == 100) // 100%
return "\cq";
else if (Percentage > 75) // healthy
return "\cd";
else if (Percentage > 50) // moderate
return "\cf";
else if (Percentage > 25) // low
return "\ci";
else if (Percentage > 0) // critical
return "\cr";
if (GetCVar ("aow_cl_confonthud"))
return "\cU";
return "\cM";
}

function str ExistsBuilding (int tid) {
if (GetActorSpeed (tid) > 0) {
if (tid <= 199 || (tid >= 900 && tid % 2 == 1))
return "\cH";
else
return "\cG";
}
if (GetCVar ("aow_cl_confonthud"))
return "\cU";
return "\cM";
}

function str ExistsBuildingGreen (int tid) {
if (GetActorSpeed (tid) > 0)
return "\cD";
return "\cQ";
}

+ 438
- 0
src/acs_source/a_bases.acs View File

@@ -0,0 +1,438 @@
// A building is hit!
script SC_BUILDINGDAMAGE (void) {
int what, team, found;
for (int i = 0; i < MAX_BUILDINGS * 2 && !found; i++) {
if (ActivatorTID() == BaseTIDs[i]) {
what = i / 2;
team = i % 2;
found = true;
}
}
if (!found)
terminate;
AwardBuildingDamage (what, team);
// Update the health to clients
SYNC_UpdateBuildingHealth (what, team);
}

#define SCORE_MIN_RATIO 0.0
#define SCORE_MAX_RATIO 1.5
#define SCORE_DENOMINATOR 450
function void AwardBuildingDamage (int what, int team) {
int tid = BaseTIDs[what*2 + team];
SetActivator (tid);
int lasthealth = RecordedBuildingHealths[what*2 + team];
int health = GetHealth ();
int spawnhealth = GetSpawnHealth ();
if (health < 0)
health = 0;
// Save the current health now.
RecordedBuildingHealths[what*2 + team] = GetHealth ();
SetActivatorToTarget (0); // target: building -> player
// The amount of points given is dependant on the health of the victim building.
int damagescored = (lasthealth - health) << 16;
int ratio = SCORE_MAX_RATIO - FixedMul ((SCORE_MAX_RATIO - SCORE_MIN_RATIO), ((health<<16) / spawnhealth));
damagescored = FixedMul (damagescored, ratio);
int points;
// Calculate points. Remainder goes to unawarded damage counter
if (damagescored >= 0) {
UnawardedDamage[PlayerNumber ()] += damagescored;
points = (UnawardedDamage[PlayerNumber ()] / SCORE_DENOMINATOR) >> 16;
}
UnawardedDamage[PlayerNumber ()] = FixedMod (UnawardedDamage[PlayerNumber ()], SCORE_DENOMINATOR<<16);
/*
print4f ("\cF%f \ch%f \cD%d \cG%f",
ratio, damagescored, points, UnawardedDamage[PlayerNumber ()]);
*/
// Award the player
if (points > 0) {
AddExperience (points * 25);
GiveCredits (points * 60);
Team_GivePoints (PlayerTeam (), points, false);
}
}

//---------------------------BLUE BARRACKS DEATH
script 101 (VOID)
{
Thing_Destroy(100,0);
Thing_Destroy(101,0);
ACS_ExecuteAlways(99, 0, TEAM_BLUE);
GotBarracks[TEAM_BLUE] = False;
// [Dusk] {9/10/12} Check MAPF_NODEFEVENTS before reddening anything.
if (!CheckMapFlags (MAPF_NoDefEvents)) {
SetLineTexture(1,SIDE_FRONT,TEXTURE_BOTTOM,"MCT2");
SetLineTexture(3,SIDE_FRONT,TEXTURE_MIDDLE,"MCT3");
ReddenSector (1);
ReddenSector (2);
}
SetFont("BIGFONT");
HudMessageBold(s:"The \chBlue Barracks\cd has been destroyed!!"; HUDMSG_FADEOUT, 0, CR_Green, 0.5, 0.7, 2.0, 1.0);
Log(n:0, s:" destroys Blue Barracks.");
AwardBuildingDamage (BUILDING_BARRACKS, TEAM_BLUE);
AwardBuildingDestruction (TEAM_RED, false);
SYNC_UpdateBuildingHealth (BUILDING_BARRACKS, TEAM_BLUE);
CallEvent (ACTION_DESTROY_BARRACKS, TEAM_BLUE);
}

//---------------------------BLUE REFINERY DEATH
script 102 (VOID)
{
Thing_Destroy(102,0);
Thing_Destroy(103,0);
ACS_ExecuteAlways(99, 0, TEAM_BLUE);
GotRefinery[TEAM_BLUE] = False;
if (!CheckMapFlags (MAPF_NoDefEvents)) {
SetLineTexture(5,SIDE_FRONT,TEXTURE_BOTTOM,"MCT2");
ReddenSector (5);
}
SetFont("BIGFONT");
HudMessageBold(s:"The \chBlue Refinery\cd has been destroyed!!"; HUDMSG_FADEOUT, 0, CR_Green, 0.5, 0.7, 2.0, 1.0);
Log(n:0, s:" destroys Blue Refinery.");
AwardBuildingDamage (BUILDING_REFINERY, TEAM_BLUE);
AwardBuildingDestruction (TEAM_RED, false);
SYNC_UpdateBuildingHealth (BUILDING_REFINERY, TEAM_BLUE);
CallEvent (ACTION_DESTROY_REFINERY, TEAM_BLUE);
}

//---------------------------BLUE POWERPLANT DEATH
script 103 (void) {
Thing_Destroy(104,0);
Thing_Remove(104);
Thing_Destroy(105,0);
ACS_ExecuteAlways(99, 0, TEAM_BLUE);
GotPlant[TEAM_BLUE] = False;
if (!CheckMapFlags (MAPF_NoDefEvents)) {
SetLineTexture(7,SIDE_FRONT,TEXTURE_BOTTOM,"MCT2");
SetLineTexture(3,SIDE_FRONT,TEXTURE_MIDDLE,"MCT3");
ReddenSector (7);
ReddenSector (2);
}
SetFont("BIGFONT");
HudMessageBold(s:"The \chBLUE Research Centre\cd has been destroyed!!";
HUDMSG_FADEOUT, 0, CR_Green, 0.5, 0.7, 2.0, 1.0);
Log(n:0, s:" destroys Blue Research Centre.");
AwardBuildingDestruction (TEAM_RED, false);
AwardBuildingDamage (BUILDING_RESCENTRE, TEAM_BLUE);
SYNC_UpdateBuildingHealth (BUILDING_RESCENTRE, TEAM_BLUE);
CallEvent (ACTION_DESTROY_PLANT, TEAM_BLUE);
}

//---------------------------BLUE WAR FACTORY DEATH
script 104 (VOID)
{
if (!GotFactory [TEAM_BLUE])
terminate;
Thing_Destroy(106,0);
Thing_Destroy(107,0);
ACS_ExecuteAlways(99, 0, TEAM_BLUE);
GotFactory[TEAM_BLUE] = False;
SetLineTexture(9,SIDE_FRONT,TEXTURE_BOTTOM,"MCT2");
if (!CheckMapFlags (MAPF_NoDefEvents)) {
ReddenSector (9);
ReddenSector (10);
}
SetFont("BIGFONT");
HudMessageBold(s:"The \chBlue WarFactory\cd has been destroyed!!"; HUDMSG_FADEOUT, 0, CR_Green, 0.5, 0.7, 2.0, 1.0);
Log(n:0, s:" destroys Blue War Factory.");
AwardBuildingDestruction (TEAM_RED, false);
AwardBuildingDamage (BUILDING_FACTORY, TEAM_BLUE);
SYNC_UpdateBuildingHealth (BUILDING_FACTORY, TEAM_BLUE);
CallEvent (ACTION_DESTROY_FACTORY, TEAM_BLUE);
}

//---------------------------BLUE REPAIR FACILITY DEATH
script 105 (VOID)
{
//Thing_Remove(109);
GotRepair[TEAM_BLUE] = False;
if (!CheckMapFlags (MAPF_NoDefEvents)) {
ReddenSector (13);
ReddenSector (14);
}
SetActorProperty(109,APROP_Health,0);
// SetFont("BIGFONT");
// HudMessageBold(s:"The \chBlue Repair Facility\cd has been destroyed!!";
// HUDMSG_FADEOUT, 0, CR_Green, 0.5, 0.7, 2.0, 1.0);
CallEvent (ACTION_DESTROY_REPAIR, TEAM_BLUE);
SetFont ("SMALLFONT");
IntelMessage (strparam (n:0, s:"\cJ has destroyed\cJ\nthe \cNBlue \cFRepair Facility!"), true);
Log(n:0, s:" destroys Blue Repair Facility.");
SYNC_UpdateBuildingHealth (BUILDING_REPAIR, TEAM_BLUE);
AwardBuildingDamage (BUILDING_REPAIR, TEAM_BLUE);
AwardBuildingDestruction (TEAM_RED, true);
}

//---------------------------BLUE OBELISK DEATH
script 114 (VOID)
{
Thing_Destroy(114,0);
Thing_Destroy(115,0);
ACS_ExecuteAlways(99, 0, TEAM_BLUE);
GotObelisk[TEAM_BLUE] = False;
if (!CheckMapFlags (MAPF_NoDefEvents)) {
ReddenSector (19);
SetLineTexture(11,SIDE_FRONT,TEXTURE_BOTTOM,"MCT2");
}
SetFont("BIGFONT");
HudMessageBold(s:"The \chBlue Obelisk\cd has been destroyed!!"; HUDMSG_FADEOUT, 0, CR_Green, 0.5, 0.7, 2.0, 1.0);
Log(n:0, s:" destroys Blue Obelisk.");
AwardBuildingDestruction (TEAM_RED, false);
SYNC_UpdateBuildingHealth (BUILDING_OBELISK, TEAM_BLUE);
AwardBuildingDamage (BUILDING_OBELISK, TEAM_BLUE);
CallEvent (ACTION_DESTROY_OBELISK, TEAM_BLUE);
}

//---------------------------RED BARRACKS DEATH
script 201 (VOID)
{
Thing_Destroy(200,0);
Thing_Destroy(201,0);
ACS_ExecuteAlways (99, 0, TEAM_RED);
GotBarracks[TEAM_RED] = False;
if (!CheckMapFlags (MAPF_NoDefEvents)) {
SetLineTexture(2,SIDE_FRONT,TEXTURE_BOTTOM,"MCT2");
SetLineTexture(4,SIDE_FRONT,TEXTURE_MIDDLE,"MCT3");
ReddenSector (3);
ReddenSector (4);
}
SetFont("BIGFONT");
HudMessageBold(s:"The \cgRED Barracks\cd has been destroyed!!"; HUDMSG_FADEOUT, 0, CR_Green, 0.5, 0.7, 2.0, 1.0);
Log(n:0, s:" destroys Red Barracks.");
AwardBuildingDestruction (TEAM_BLUE, false);
SYNC_UpdateBuildingHealth (BUILDING_BARRACKS, TEAM_RED);
AwardBuildingDamage (BUILDING_BARRACKS, TEAM_RED);
CallEvent (ACTION_DESTROY_BARRACKS, TEAM_RED);
}

//---------------------------RED REFINERY DEATH
script 202 (VOID)
{
Thing_Destroy(202,0);
Thing_Destroy(203,0);
ACS_ExecuteAlways(99, 0, TEAM_RED);
GotRefinery[TEAM_RED] = False;
if (!CheckMapFlags (MAPF_NoDefEvents)) {
SetLineTexture(6,SIDE_FRONT,TEXTURE_BOTTOM,"MCT2");
ReddenSector (6);
}
SetFont("BIGFONT");
HudMessageBold(s:"The \cgRed Refinery\cd has been destroyed!!"; HUDMSG_FADEOUT, 0, CR_Green, 0.5, 0.7, 2.0, 1.0);
Log(n:0, s:" destroys Red Refinery.");
AwardBuildingDestruction (TEAM_BLUE, false);
SYNC_UpdateBuildingHealth (BUILDING_REFINERY, TEAM_RED);
AwardBuildingDamage (BUILDING_REFINERY, TEAM_RED);
CallEvent (ACTION_DESTROY_REFINERY, TEAM_RED);
}

//---------------------------RED POWERPLANT DEATH
script 203 (VOID)
{
Thing_Destroy(204,0);
Thing_Destroy(205,0);
ACS_ExecuteAlways(99, 0, TEAM_RED);
GotPlant[TEAM_RED] = False;
if (!CheckMapFlags (MAPF_NoDefEvents)) {
SetLineTexture(8,SIDE_FRONT,TEXTURE_BOTTOM,"MCT2");
SetLineTexture(4,SIDE_FRONT,TEXTURE_MIDDLE,"MCT3");
ReddenSector (8);
ReddenSector (4);
}
SetFont("BIGFONT");
HudMessageBold(s:"The \cgRED Research Centre\cd has been destroyed!!";
HUDMSG_FADEOUT, 0, CR_Green, 0.5, 0.7, 2.0, 1.0);
Log(n:0, s:" destroys Red Research Centre.");
AwardBuildingDestruction (TEAM_BLUE, false);
SYNC_UpdateBuildingHealth (BUILDING_RESCENTRE, TEAM_RED);
AwardBuildingDamage (BUILDING_RESCENTRE, TEAM_RED);
CallEvent (ACTION_DESTROY_PLANT, TEAM_RED);
}

//---------------------------RED WAR FACTORY DEATH
script 204 (VOID)
{
if (!GotFactory [TEAM_RED])
terminate;
Thing_Destroy(206,0);
Thing_Destroy(207,0);
ACS_ExecuteAlways(99, 0, TEAM_RED);
GotFactory[TEAM_RED] = False;
SetLineTexture(10,SIDE_FRONT,TEXTURE_BOTTOM,"MCT2");
if (!CheckMapFlags (MAPF_NoDefEvents)) {
ReddenSector (11);
ReddenSector (12);
}
SYNC_UpdateBuildingHealth (BUILDING_FACTORY, TEAM_RED);
CallEvent (ACTION_DESTROY_FACTORY, TEAM_RED);
SetFont("BIGFONT");
HudMessageBold(s:"The \cgRed War Factory\cd has been destroyed!!";
HUDMSG_FADEOUT, 0, CR_Green, 0.5, 0.7, 2.0, 1.0);
Log(n:0, s:" destroys Red War Factory.");
AwardBuildingDestruction (TEAM_BLUE, false);
AwardBuildingDamage (BUILDING_FACTORY, TEAM_RED);
}

//---------------------------RED REPAIR FACILITY DEATH
script 205 (VOID) {
GotRepair[TEAM_RED] = False;
if (!CheckMapFlags (MAPF_NoDefEvents)) {
ReddenSector (15);
ReddenSector (16);
}
SetActorProperty(209,APROP_Health,0);
/*SetFont("BIGFONT");
HudMessageBold(s:"The \cgRed Repair Facility\cd has been destroyed!!";
HUDMSG_FADEOUT, 0, CR_Green, 0.5, 0.7, 2.0, 1.0);*/
CallEvent (ACTION_DESTROY_REPAIR, TEAM_RED);
SYNC_UpdateBuildingHealth (BUILDING_REPAIR, TEAM_RED);
SetFont ("SMALLFONT");
IntelMessage (strparam (n:0, s:"\cJ has destroyed\cJ\nthe \cARed \cFRepair Facility!"), true);
Log(n:0, s:" destroys Red Repair Facility.");
AwardBuildingDestruction (TEAM_BLUE, true);
AwardBuildingDamage (BUILDING_REPAIR, TEAM_RED);
}

//---------------------------RED OBELISK DEATH
script 214 (VOID)
{
Thing_Destroy(214,0);
Thing_Destroy(215,0);
ACS_ExecuteAlways(99, 0, TEAM_RED);
GotObelisk[TEAM_RED] = False;
if (!CheckMapFlags (MAPF_NoDefEvents)) {
ReddenSector (20);
SetLineTexture(12,SIDE_FRONT,TEXTURE_BOTTOM,"MCT2");
}
SetFont("BIGFONT");
HudMessageBold(s:"The \cgRed Obelisk\cd has been destroyed!!";
HUDMSG_FADEOUT, 0, CR_Green, 0.5, 0.7, 2.0, 1.0);
Log(n:0, s:" destroys Red Obelisk.");
AwardBuildingDestruction (TEAM_BLUE, false);
SYNC_UpdateBuildingHealth (BUILDING_OBELISK, TEAM_RED);
AwardBuildingDamage (BUILDING_OBELISK, TEAM_RED);
CallEvent (ACTION_DESTROY_OBELISK, TEAM_RED);
}

script 97 (int Structure, int Team) {
// stfu during degeneration
if (SuddenDeath && GetCVar ("aow_degeneration")) terminate;
if ( Timer() > LastAttackMessage+35*15 ) {
if(Structure == 1 && Team == 0)
AmbientSound("red/barracks",255);
if(Structure == 2 && Team == 0)
AmbientSound("red/refinery",255);
if(Structure == 3 && Team == 0)
AmbientSound("red/powerplant",255);
if(Structure == 4 && Team == 0)
AmbientSound("red/factory",255);
if(Structure == 6 && Team == 0)
AmbientSound("red/obelisk",255);
if(Structure == 1 && Team == 1)
AmbientSound("blue/barracks",255);
if(Structure == 2 && Team == 1)
AmbientSound("blue/refinery",255);
if(Structure == 3 && Team == 1)
AmbientSound("blue/powerplant",255);
if(Structure == 4 && Team == 1)
AmbientSound("blue/factory",255);
if(Structure == 6 && Team == 1)
AmbientSound("blue/obelisk",255);
LastAttackMessage = Timer();
}
}

script 99 (int team) NET CLIENTSIDE {
if (team == TEAM_RED) {
AmbientSound("red/destroyed",255);
AmbientSound("red/destroyed",255);
} else {
AmbientSound("blue/destroyed",255);
AmbientSound("blue/destroyed",255);
}
}

// =============================================================================
// [Dusk] BTOs call this to cause external damage, this way the attacker is
// properly rewarded for the damage done.
script 652 (int tid, int damage) {
SetActivatorToTarget (0);
Thing_Damage (tid, damage, 0);
}

// =============================================================================
function void AwardBuildingDestruction (int team, int small) {
// [Dusk] Is keeping the below block still a good idea?
int activator = ActivatorTID();
for (int k = 0; k < MAXPLAYERS; k++) {
if (PlayerInGame(k) && GetPlayerInfo(k,PLAYERINFO_TEAM) == Team) {
SetActivator(3800+k);
ACS_ExecuteAlways (318,0);
GiveCredits (500);
}
}
// Check the game-over conditions
ACS_ExecuteAlways (SC_GAMEOVER, 0, team, small);
}

// =============================================================================
// [Dusk] Calculate the amount of buildings still standing.
function int CalcBaseLeft (int team) {
return GotBarracks[team] +
GotFactory[team] +
GotObelisk[team] +
GotPlant[team] +
GotRefinery[team];
}

+ 237
- 0
src/acs_source/a_botmarines.acs View File

@@ -0,0 +1,237 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* All Out War 2 AI marine scripts
* Credit to VoltlocK for originally creating the engine
* With modifications by the Omega Team
*
* You may use portions of this script in your project as long as you give
* credit where credit is due. Please don't be lame and just copy-paste any
* of this and call it your own. Thanks!
*/

// ============================================================================
/* [Dusk] Get a free slot ID. Make sure you actually spawn one marine with the tid
* (and ONLY one) when you do this! Marines will, however, call this by
* themselves if you do not do so beforehand.
*/
function int AI_RequestID (void) {
// Find a free slot
for (int i = 0; Bots[i] && i < MAX_MARINES; i++);
if (i >= MAX_MARINES) {
// Uh oh.
Log (s:"AI_RequestID: Too many AI marines!");
return -1;
}
AIMarineCount++;
Bots[i] = true;
return i;
}

// ============================================================================
// [Dusk] Remove a marine from game
function bool AI_ClearMarine (int i) {
if (!Bots[i]) {
Log (s:"AI_ClearMarine: Marine ", d:i, s:" doesn't exist.");
return false;
}
AIMarineCount--;
Bots[i] = false;
// Send to Dismiss state if it's still alive. This makes it
// look like as if the marine teleports away from the game.
if (GetActorHealth (TID_MARINE + i) > 0)
SetActorState (TID_MARINE + i, "Dismiss");
// Clear the TID
Thing_ChangeTID (TID_MARINE + i, 0);
return true;
}

// ============================================================================
// [Dusk] Init a marine
script SC_MARINE_INIT (void) {
GiveInventory ("IsAIMarine", 1);
// If we haven't got an ID already, get one
if (ActivatorTID () == 0) {
int i = AI_RequestID ();
if (i != -1)
Thing_ChangeTID (0, TID_MARINE + i);
else
Thing_Remove (0);
}
// Set proper special
SetThingSpecial (0, ACS_ExecuteAlways, SC_MARINE_DEATH, 0, ActivatorTID () - TID_MARINE);
}

// ============================================================================
// ==== MARINE COMPENSATION
// [Dusk] There are clearly unbalanced teams, and the game has already started. Even despite
// we try balance teams via the switcher, surplus remains. Therefore, the weaker team is
// put on on compensation and give them AI marines. We keep doing this until teams are
// balanced out.
script SC_MARINE_COMENSATION OPEN {
while (true) {
delay (35 * 5);
if (!GetCVar ("aow_debugmarines") && (!CheckMinutes (5) || GetCVar ("aow_nocompensation")))
continue;
int n;
// Calculate AI marine needs
if (GetCVar ("aow_debugmarines") > 0) {
// Debug CVAR to override these counts.
AIMarines[TEAM_BLUE] = GetCVar ("aow_debugmarines");
AIMarines[TEAM_RED] = GetCVar ("aow_debugmarines");
} else {
int rc = GetTeamProperty (TEAM_RED, TPROP_NumPlayers);
int bc = GetTeamProperty (TEAM_BLUE, TPROP_NumPlayers);
if (rc > bc + 1 + (rc > 7) && bc != 0)
AIMarines[TEAM_BLUE] = rc - (bc + 1 + (rc > 7));
else if (AIMarines[TEAM_BLUE] > 0)
AIMarines[TEAM_BLUE] = 0;
if (bc > rc + 1 + (bc > 7) && rc != 0)
AIMarines[TEAM_RED] = bc - (rc + 1 + (bc > 7));
else if (AIMarines[TEAM_RED] > 0)
AIMarines[TEAM_RED] = 0;
}
// Make sure teams have the right amount of marines
for (int team = TEAM_BLUE; team <= TEAM_RED; team++) {
int AICount = 0;
int spottid;
str AIClass = "BlueRandomMarine";
if (team == TEAM_RED)
AIClass = "RedRandomMarine";
// Count how many AI marines the specified team has
for (int i = 0; i < MAX_MARINES; i++) {
if (!Bots[i])
continue;
if (CheckActorInventory (TID_MARINE + i, "IsRed") == team &&
CheckActorInventory (TID_MARINE + i, "IsCompensationMarine"))
{
AICount++;
}
}
// Determine initial spawn spot
if (team == TEAM_BLUE)
spottid = TID_REPAIR_BLUE;
else
spottid = TID_REPAIR_RED;
// Determine delta, which is counted marines minus assigned marines.
// If this is positive, there's too many marines, if negative, there's
// not enough.
int delta = AICount - AIMarines[team];
if (delta > 0) {
// Positive delta, too many AI marines - send one of them home
Log (s:"Compensation: Removing ", d:delta,
s:" marines from ", s:TeamNames[team], s:".");
for (i = 0; i < MAX_MARINES && delta > 0; i++) {
// Find a marine that we can send home.
if (!Bots[i])
continue; // free slot
if (!CheckActorInventory (TID_MARINE + i, "IsCompensationMarine"))
continue; // not compensation (e.g. marine beacon, don't touch them)
if (CheckActorInventory (TID_MARINE + i, "IsRed") != team)
continue; // wrong team
AI_ClearMarine (i);
delta--;
}
} else if (delta < 0) {
// Negative delta, team needs more marines.
Log (s:"Compensation: Adding ", d:-delta,
s:" marines to ", s:TeamNames[team], s:".");
while (AICount < AIMarines[team]) {
// Get a free ID
i = AI_RequestID ();
if (i == -1)
break; // no free IDs, can't do anything
int spawned = 0;
int tries = 5;
while (tries > 0 && !spawned) {
// Spawn the marine initially onto the repair facility
spawned = SpawnSpotForced (AIClass, spottid, TID_MARINE + i, 0);
if (spawned) {
AICount += spawned;
delay (1);
// Flag the marine as compensation
GiveActorInventory (TID_MARINE + i, "IsCompensationMarine", 1);
// Move the newly-spawned bot to a random spawn in the base, but
// only spawn fog at the destination. We don't want teleport fogs
// to randomly appear in the repair facility
TeleportOther (TID_MARINE + i, team+1, false);
SpawnSpotForced ("TeleportFog", TID_MARINE + i, 0, 0);
} else {
tries--;
}
delay (35);
}
if (!spawned) {
// Something's seriously wrong if we get here
Log (s:"WARNING: Couldn't spawn compensation marines to ", s:TeamNames[team],
s:"!\nSomething's going haywire here!");
terminate;
}
}
Log (s:"Done adding marines for ", s:TeamNames[team]);
}
}
}
}

// ============================================================================
// [Dusk] AI marine bounty
script SC_MARINE_DEATH (int i) {
// No matter what happened to the marine, the slot needs to
// be cleared now that it's dead. Save its team first,
// we can't get it after the slot is cleared.
int AITeam = CheckActorInventory (TID_MARINE + i, "IsRed");
AI_ClearMarine (i);
// Give the killer a bounty if he was an enemy player
if (PlayerNumber() != -1 && PlayerTeam() != AITeam) {
LocalAmbientSound ("game/boink", 127);
AddExperience (100);
GiveCredits (CreditFragAward);
TakeTickets (AITeam, 1);
Team_GivePoints (PlayerTeam(), 2, false);
}
}

// [Dusk] Dumps known information about AI marines. Not a lot here at the moment..
script SC_MARINE_STATS (void) {
for (int i = 0; i < MAX_MARINES; i++) {
if (!Bots[i]) {
Log (s:"Marine ", d:i, s:": -");
continue;
}
int compensation = "";
if (CheckActorInventory (TID_MARINE + i, "IsCompensationMarine"))
compensation = " (compensation)";
Log (s:"Marine ", d:i, s:": ", s:TeamNames[CheckActorInventory (TID_MARINE + i, "IsRed")], s:compensation);
}
}

+ 40
- 0
src/acs_source/a_bots.acs View File

@@ -0,0 +1,40 @@
// =============================================================================
// [Dusk] BOT SUPPORT

#define MAX_BOTCLASSES 16
int BotClasses[MAX_BOTCLASSES] = {
CLASS_Gunman,
CLASS_Minigunner,
CLASS_DoubleShotgunner,
CLASS_Flamer,
CLASS_Grenadier,
CLASS_GaussGunner,
CLASS_ChemWarrior,
CLASS_TiberiumAutorifleman,
CLASS_Artillery,
CLASS_ShockTrooper,
CLASS_Commando,
CLASS_LaserChaingunner,
CLASS_PlasmaGunner,
CLASS_CombustionGunner,
CLASS_Machinegunner,
CLASS_Shotgunner,
};

script SC_BotEnter ENTER {
if (!PlayerIsBot (PlayerNumber()))
terminate;
int i;
delay (35);
// Find a good class to take
do {
i = BotClasses[random (0, MAX_BOTCLASSES)];
delay (5);
} while (!PurchaseClass (i));
}

script SC_BotRespawn RESPAWN {
ACS_ExecuteAlways (SC_BotEnter, 0);
}

+ 476
- 0
src/acs_source/a_classes.acs View File

@@ -0,0 +1,476 @@
// All Out War 2 Class purchase scripts
// Credit to VoltlocK for originally creating AOW2
// With modifications by the Omega Team

// You may use portions of this script in your project as long as you give credit where credit is
// due. Please don't be lame and just copy-paste any of this and call it your own. Thanks!

// Add-on definitions
#define ADK_NAME 0
#define ADK_COST 1
#define ADK_ITEM 2
// --
#define MAX_ADDON_KEYS 3

#define MAX_ADDONS 7
int AddOns[MAX_ADDONS][MAX_ADDON_KEYS] = {
{"+1 Armor", 250, ITEM_ArmorUp},
{"Tiberium Autorifle", 300, ITEM_TibRifleWeak},
{"Combustion Autorifle", 300, ITEM_CombustRifleWeak},
{"Artillery Cannon", 550, ITEM_Artillery},
{"Chainsaw", 250, ITEM_Chainsaw},
{"Plasma Cannon", 1500, ITEM_PlasmaCannon},
{"Superweapon Beacon", 1750, ITEM_Beacon}
};

// =============================================================================
// [Dusk] Adds a class type. Holy SHIT what a long ass prototype.
/*
"Name of class", cost, speed, dependency,
armor, armor_mod,
frags, c4, enhanced, flags,
item0, item1, item2, item3, item4, item5
*/
function void AddClass (int token, str name, int cost, int speed,
int dep, int armor, int armod, int frags, int c4, int c4e, int flags,
int item0, int item1, int item2, int item3, int item4, int item5)
{
if (token < 0 || token >= NUMCLASSES) {
FatalError3f ("Invalid token %d for class `%s` (should be between [0 - %d], did you forget to update NUMCLASSES?)",
token, name, NUMCLASSES - 1);
}
Classes[token][CK_NAME] = name;
Classes[token][CK_COST] = cost;
Classes[token][CK_SPEED] = speed;
Classes[token][CK_DEPENDENCY] = dep;
Classes[token][CK_ARMOR] = armor;
Classes[token][CK_ARMOD] = armod;
Classes[token][CK_FRAGS] = frags;
Classes[token][CK_C4] = c4;
Classes[token][CK_ENHANCEDC4] = c4e;
Classes[token][CK_FLAGS] = flags;
Classes[token][CK_ITEM0] = item0;
Classes[token][CK_ITEM1] = item1;
Classes[token][CK_ITEM2] = item2;
Classes[token][CK_ITEM3] = item3;
Classes[token][CK_ITEM4] = item4;
Classes[token][CK_ITEM5] = item5;
}

// =============================================================================
// [Dusk] Tries to purchase a class for the player. Returns true if successful,
// if not, g_Error is set and the function returns false.
function bool PurchaseClass (int id) {
int cost = Classes[id][CK_COST];
// Check barracks
if (Classes[id][CK_DEPENDENCY] == DEP_BARRACKS) {
if (!CheckBarracks (PlayerTeam ())) {
g_Error = "Your barracks have been destroyed!";
return false;
}
}
// Check research centre
if (Classes[id][CK_DEPENDENCY] == DEP_CENTRE) {
if (!CheckPlant (PlayerTeam ())) {
g_Error = "Your research centre has been destroyed!";
return false;
}
}
// Check refinery
if (Classes[id][CK_DEPENDENCY] == DEP_REFINERY) {
if (!CheckRefinery (PlayerTeam ())) {
g_Error = "Your refinery has been destroyed!";
return false;
}
}
// If the class is a time cop, we need to check the limit
int max = GetCVar ("aow_maxtimecopsperteam");
if (Classes[id][CK_FLAGS] & CF_IsTimeCop && max > 0) {
if (TeamInvCount ("TimeGun", PlayerTeam()) >= max) {
g_Error = "Timecops at limit!";
return false;
}
}
// Must not have a class already
if (CheckInventory ("HasClass")) {
g_Error = "You must resign first!";
return false;
}
// Must afford it!
if (!CanAfford (cost)) {
g_Error = "You need more credits!";
return false;
}
TakeInventory ("PurchaseToken", 1);
SpendCredits (cost);
if (!SetClass (id, 0)) {
g_Error = "Couldn't set the class! Something's going nuts here!";
return false;
}
// Call an event script here
CallEvent (ACTION_ClassPurchase, id);
return true;
}

// =============================================================================
// [Dusk] Sets the player class
#define SCF_NOTELEPORT 1 // don't teleport the player to his base
#define SCF_NOBEEP 2 // no beep sound
#define SCF_SILENT 3 // stay shush
function int SetClass (int id, int scflags) {
// If we pass CLASS_None, we resign.
if (id == CLASS_None) {
SetActorProperty (0, APROP_DeathSound, "generic/death");
SetActorProperty (0, APROP_RenderStyle, STYLE_Normal);
SetActorProperty (0, APROP_Alpha, 1.0);
RefundCredits (-1, CheckInventory("Refunds"));
// First mark down the stuff that we wish to carry over the resign.
if (CheckInventory ("JumpjetSwitch"))
GiveInventory ("JumpjetDeactivate", 1);
if (CheckInventory ("PlasmaCannon"))
bool HasPlasma = True;
if (CheckInventory ("ArtilleryCannon"))
bool HasArtillery = True;
if (CheckInventory ("TiberiumAutorifleWeak"))
bool HasTiberiumAutorifle = True;
if (CheckInventory ("IonCannonBeacon") || CheckInventory("NuclearStrikeBeacon"))
bool HasSuperWeapon = True;
if (CheckInventory ("PowerIronCurtain"))
bool HasIronCurtain = True;
if (CheckInventory ("PowerBerserk"))
bool HasBerserk = True;
if (CheckInventory ("EagerBeaver"))
bool HasChainsaw = True;
if (CheckInventory ("BombPack"))
bool HasKamikaze = True;
if (CheckInventory ("PowerTimeGunFloat") || CheckInventory ("PowerTimeGunBoost") || CheckInventory ("IsTeleporting"))
bool HasTimeGunPositiveEffect = true;
if (CheckInventory ("PowerTimeGunWeaken") || CheckInventory ("PowerTimeGunSlow"))
bool HasTimeGunNegativeEffect = true;
if (CheckInventory ("IsInSpawnRoom"))
bool InSpawn = true;
if (CheckInventory ("InMenu"))
int MenuCount = CheckInventory ("InMenu");
SetPlayerProperty (0, 0, PROP_FLY);
SetPlayerProperty (0, 0, PROP_FROZEN);
ClearInventory ();
// If he was in the menu, re-activate it now.
if (MenuCount)
ActivateMenu (MENU_Purchase);
// Set the essentials
if (PlayerTeam() == TEAM_RED)
GiveInventory ("IsRed", 1);
else
GiveInventory ("IsBlue", 1);
GiveInventory ("Unarmed", 1);
SetWeapon ("Unarmed");
SetAmmoCapacity ("TimedC4Ammo", 1);
SetAmmoCapacity ("FragGrenadeAmmo", 1);
SetActorProperty (0, APROP_SPEED, 1.0);
SetHealth (GetSpawnHealth ());
SetActorProperty (0, APROP_RenderStyle, STYLE_Normal);
SetActorProperty (0, APROP_Alpha, 1.0);
SetInventory ("Credit", Credits[PlayerNumber()]);
SetInventory ("Experience", Experience[PlayerNumber()]);
GiveInventory ("IsInSpawnRoom", InSpawn);
// Restore the marked stuff
if (HasPlasma)
GiveItem (ITEM_PlasmaCannon, false);
if (HasArtillery)
GiveItem (ITEM_Artillery, false);
if (HasTiberiumAutorifle)
GiveItem (ITEM_TibRifleWeak, false);
GiveInventory ("GreenHueRemover", HasIronCurtain);
GiveInventory ("RedHueRemover", HasBerserk);
GiveInventory ("BeaconItem", HasSuperWeapon);
GiveInventory ("EagerBeaver", HasChainsaw);
GiveInventory ("NoMoreTerrorism", HasKamikaze);
GiveInventory ("DimGoldHueRemover", HasTimeGunPositiveEffect);
GiveInventory ("DimRedHueRemover", HasTimeGunNegativeEffect);
GiveInventory ("IsFemale", (GetPlayerInfo (PlayerNumber(), PLAYERINFO_GENDER) == 1));
GiveInventory ("IsAdmin", IsAdmin[PlayerNumber()]);
if (!(scflags & SCF_SILENT)) {
DisplayTick();
SetFont ("BIGFONT");
HudMessage(s:"You have resigned from your class.";
HUDMSG_FADEOUT, 1800+PlayerNumber(), CR_ORANGE, 0.5, 0.45, 2.0, 1.0);
Log (n:0, s:" resigns.");
TeamMessage (TMSG_RESIGN, 0, 0);
}
ACS_ExecuteAlways (97, 0);
RecountTimeCops ();
return true;
}
// =========================================================================
if (id < CLASS_None || id > NUMCLASSES) {
print1f ("SetClass: Tried to set an unknown class %d!", id);
return false;
}
bool silent = (scflags & SCF_SILENT);
int cflags = Classes[id][CK_FLAGS];
str name = Classes[id][CK_NAME];
// Display message to purchaser
if (!(scflags & SCF_NOBEEP | SCF_SILENT))
DisplayTick ();
SetFont ("BIGFONT");
HudMessage (s:"You are a \cf", s:name, s:"!";
HUDMSG_FADEOUT, 1800+PlayerNumber(), CR_GREEN, 0.5, 0.45, 2.0, 1.0);
// If the class is flagged as dangerous, also print a warning to others
if (cflags & CF_Warning) {
SetFont ("SMALLFONT");
if (PlayerTeam () == TEAM_RED)
IntelMessage (strparam (s:"\cGWarning: \cARed\cJ ", s:name, s:" in-field!"), true);
else
IntelMessage (strparam (s:"\cGWarning: \cNBlue\cJ ", s:name, s:" in-field!"), true);
}
// The essentials
GiveInventory ("HasClass", 1);
GiveInventory ("Refunds", Classes[id][CK_COST] / 2);
GiveInventory ("ClassID", id);
// Speed and armor
SetActorProperty (0, APROP_SPEED, Classes[id][CK_SPEED]);
SetArmorGrade (Classes[id][CK_ARMOR], Classes[id][CK_ARMOD]);
// Give a handgun unless undesired
if (!(cflags & CF_NoPistol))
GiveItem (ITEM_HANDGUN, false);
// C4
int c4 = Classes[id][CK_C4];
if (c4 > 0) {
SetInventory ("TimedC4", c4);
SetInventory ("TimedC4Count", c4);
}
// Frag grenades
SetFragGrenades (Classes[id][CK_FRAGS]);
// If the class is a sniper, flag as such
if (cflags & CF_IsSniper)
GiveInventory ("IsSniper", 1);
// If the class shouldn't use mechs, flag as such
if (cflags & CF_CantPilot)
GiveInventory ("CantMech", 1);
// If the class is flagged as a medic, they should get the regeneration
if (cflags & CF_IsMedic) {
GiveInventory ("IsMedic", 1);
ACS_ExecuteAlways (352, 0);
}
// If the class is counts as a time cop, the limit has to be
// recounted now.
if (cflags & CF_IsTimeCop)
RecountTimeCops ();
// If the class is flagged as a harvester, they should be able
// to collect Tiberium
if (cflags & CF_IsHarvester) {
GiveInventory ("IsHarvester", 1);
GiveInventory ("TiberiumProof", 1);
// Info message
if (!silent) {
SetFont ("BIGFONT");
HudMessage (s:"Pick-up \cDtiberium crystals \c-and";
HUDMSG_FADEOUT, 1840+PlayerNumber(), CR_GRAY, 0.5, 0.6, 2.0, 1.0);
HudMessage (s:"return them to your \cDrefinery \c-for \cQcash!";
HUDMSG_FADEOUT, 1880+PlayerNumber(), CR_GRAY, 0.5, 0.65, 2.0, 1.0);
}
}
// Certain classes do less damage than others.
if (cflags & CF_DamageDebuff)
GiveInventory ("Grade0Damage", 1);
// Stealth troopers have a specific death sound
if (cflags & CF_IsStealth)
SetActorProperty (0, APROP_DeathSound, "stealth/death");
// Tag the artillery soldier so it can have its fast reloading
if (id == CLASS_ARTILLERY)
GiveInventory ("IsArtillerySoldier", 1);
// Give the player the weapons and items.
for (int i = 0; i < 6; i++)
GiveItem (Classes[id][CK_ITEM0 + i], false);
// The weapon in the first slot is considered primary
// and the player will select it.
SetWeapon (Items[Classes[id][CK_ITEM0]][IK_ITEM0]);
// Check for rank for possible upgrades
ACS_ExecuteAlways (91, 0);
// Send the player to field unless undesired
if (!(scflags & SCF_NOTELEPORT)) {
ACS_ExecuteAlways (SC_DOTELEPORTTOFIELD, 0, 1-PlayerTeam ());
// Don't give spawn invul if aow_nospawninvul is set.
if (!GetCVar ("aow_nospawninvul"))
GiveInventory ("SpawnInvulnerability", 1);
}
// Give self-heal now. We give this last so that it is never selected automatically.
if (id != CLASS_SuicideBomber)
GiveInventory ("SelfHealItem", 1);
// Save the player speed for morph handling
PlayerSpeeds[PlayerNumber()] = Classes[id][CK_SPEED];
// Inform teammates of the class change
TeamMessage (TMSG_NEWCLASS, id, 0);
// Log it, unless offline
if (netstate != NETSTATE_Offline || PlayerTeam() != ConsoleTeam())
Log (n:0, s:" becomes ", s:Classes[id][CK_NAME]);
return true;
}

/* [Dusk] Class scripts. This is what
* remains of that old copy/paste nightmare :)
* These now just call the menu.
*/
// {9/10/12} Script 20 is NET w/ extra checks so it can be called from console.
script 20 (void) NET {
if (PlayerInGame (PlayerNumber ()) && CheckInventory ("IsInSpawnRoom"))
ActivateMenu (MENU_PURCHASE);
}

script 21 (void) ActivateMenu (MENU_PURCHASE);
script 22 (void) ActivateMenu (MENU_PURCHASE);
script 23 (void) ActivateMenu (MENU_PURCHASE);
script 24 (void) ActivateMenu (MENU_PURCHASE);
script 25 (void) ActivateMenu (MENU_PURCHASE);
script 26 (void) ActivateMenu (MENU_PURCHASE);
script 27 (void) ActivateMenu (MENU_PURCHASE);
script 28 (void) ActivateMenu (MENU_PURCHASE);
script 29 (void) ActivateMenu (MENU_PURCHASE);
script 33 (void) ActivateMenu (MENU_PURCHASE);
script 35 (void) ActivateMenu (MENU_PURCHASE);
script 38 (void) ActivateMenu (MENU_PURCHASE);
script 62 (void) ActivateMenu (MENU_PURCHASE);
script 40 (void) ActivateMenu (MENU_PURCHASE);
script 41 (void) ActivateMenu (MENU_PURCHASE);
script 42 (void) ActivateMenu (MENU_PURCHASE);
script 43 (void) ActivateMenu (MENU_PURCHASE);
script 44 (void) ActivateMenu (MENU_PURCHASE);
script 52 (void) ActivateMenu (MENU_PURCHASE);
script 53 (void) ActivateMenu (MENU_PURCHASE);
script 54 (void) ActivateMenu (MENU_PURCHASE);
script 60 (void) ActivateMenu (MENU_PURCHASE);
script 61 (void) ActivateMenu (MENU_PURCHASE);
script 57 (void) ActivateMenu (MENU_PURCHASE);
script 37 (void) ActivateMenu (MENU_PURCHASE);
script 49 (void) ActivateMenu (MENU_PURCHASE);
script 50 (void) ActivateMenu (MENU_PURCHASE);
script 51 (void) ActivateMenu (MENU_PURCHASE);
script 55 (void) ActivateMenu (MENU_PURCHASE);
script 56 (void) ActivateMenu (MENU_PURCHASE);
script 39 (void) ActivateMenu (MENU_PURCHASE);
script 34 (void) ActivateMenu (MENU_PURCHASE);
script 36 (void) ActivateMenu (MENU_PURCHASE);
script 63 (void) ActivateMenu (MENU_PURCHASE);
script 64 (void) ActivateMenu (MENU_PURCHASE);

// =============================================================================
// Instantly turn the player into a suicide bomber
script SC_BOMBPACKITEM (void) {
if (CheckWeapon ("BombPack"))
terminate;
SetClass (CLASS_None, SCF_SILENT);
SetClass (CLASS_SuicideBomber, SCF_SILENT);
SpawnSpotForced ("TeleportFog", 0, 0, 0);
SetFont ("BIGFONT");
HudMessage (s:"\cfYou are now a suicide bomber! Go blast 'em!";
HUDMSG_FADEOUT, 1800 + PlayerNumber(), CR_Untranslated, 0.5, 0.45, 2.0, 1.0);
}

// =============================================================================
function int GetClass (void) {
return GetPlayerClass (PlayerNumber ());
}

function int GetPlayerClass (int i) {
if (!PlayerInGame (i) || !CheckActorInventory (3800 + i, "HasClass"))
return CLASS_None;
return CheckActorInventory (3800 + i, "ClassID");
}

// ============================================================================
// Returns true if the given class can be bought, false if it can't
// This is just client-side prediction on the menu.
function int CheckClassAvailability (int id) {
int cost = Classes[id][CK_COST];
int ct = PlayerTeam ();
// Can't buy a class without resigning first
if (CheckInventory ("HasClass"))
return false;
// Check cost
if (CheckInventory ("Credit") < Classes[id][CK_COST])
return false;
// Check building dependencies
switch (Classes[id][CK_DEPENDENCY]) {
case DEP_BARRACKS:
if (!CheckBuilding (BUILDING_BARRACKS, ct))
return false;
break;
case DEP_CENTRE:
if (!CheckBuilding (BUILDING_RESCENTRE, ct))
return false;
break;
case DEP_REFINERY:
if (!CheckBuilding (BUILDING_REFINERY, ct))
return false;
break;
}
// Check timecop limit
int max = GetConfig (CONFIG_MAXTIMECOPS);
if (Classes[id][CK_FLAGS] & CF_IsTimeCop && max > 0)
if (TeamInvCount ("TimeGun", PlayerTeam()) >= max)
return false;
return true;
}

+ 456
- 0
src/acs_source/a_client.acs View File

@@ -0,0 +1,456 @@
// ************************************************
// [Dusk] Clientside code hub
script SC_CLIENT OPEN CLIENTSIDE {
// Store the local player number
consoleplayer = ConsolePlayerNumber ();
NetState |= NETSTATE_Client;
delay (5);
// Get outside the spawn room.
Puke (-SC_CL_SPECTATORTELEPORT);
delay (5);
ACS_ExecuteAlways (SC_CL_EFFECTS, 0);
ACS_ExecuteAlways (SC_CL_HUDINIT, 0);
// nothing to see here, folks
FixFuckedUpArrays ();
// Initialize stuff unless we did so already.
if (!(NetState & NETSTATE_Server)) {
InitClasses();
BuildMenuClasses ();
BuildMenuResearches ();
BuildMenuMechs ();
InitParticleFuserData ();
CR_InitCrateList ();
}
PR_InitPreferences ();
// [Dusk] Use consolecommand to make client-side CVARs show up properly
// Use CONFONT for HUD elements
if (GetCVar ("aow_cl_confonthud") <= 0)
ConsoleCommand ("set aow_cl_confonthud 0");
// Request information about the killer's health when we get fragged
if (GetCVar ("aow_cl_killerhealth") <= 0)
ConsoleCommand ("set aow_cl_killerhealth 0");
// Desired effect level (negative means less, positive means more, 0 means normal)
if (GetCVar ("aow_cl_fx") == 0)
ConsoleCommand ("set aow_cl_fx 0");
// Don't draw any HUD elements
if (GetCVar ("aow_cl_nohud") <= 0)
ConsoleCommand ("set aow_cl_nohud 0");
// Always use the radar (but it will only show teammates)
if (GetCVar ("aow_cl_alwaysradar") <= 0)
ConsoleCommand ("set aow_cl_alwaysradar 0");
// [Dusk] {9/15/12} Disables team log completely.
if (GetCVar ("aow_cl_noteamlog") <= 0)
ConsoleCommand ("set aow_cl_noteamlog 0");
// [Dusk] {10/4/12} CVAR to show team log on the screen.
// It takes a lot of screen space so I'm disabling it by default
if (GetCVAR ("aow_cl_fullteamlog") <= 0)
ConsoleCommand ("set aow_cl_fullteamlog 0");
// [Dusk] {10/27/12} How much to donate?
if (GetCVAR ("aow_cl_donateamount") <= 0)
ConsoleCommand ("set aow_cl_donateamount 100");
// [Dusk] Also archive them.
ArchiveCVAR ("aow_cl_confonthud");
ArchiveCVAR ("aow_cl_killerhealth");
ArchiveCVAR ("aow_cl_fx");
ArchiveCVAR ("aow_cl_nohud");
ArchiveCVAR ("aow_cl_alwaysradar");
ArchiveCVAR ("aow_noteamintel");
ArchiveCVAR ("aow_cl_fullteamlog");
ArchiveCVAR ("aow_cl_donateamount");
// [Dusk] {9/10/12} Activate the radar
ACS_Execute (SC_CL_RADAR, 0);
}

// =============================================================================
script SC_WHOAMI (void) NET CLIENTSIDE {
Log (s:"I am player ", d:consoleplayer, s:" named ", n:consoleplayer+1);
}

// =============================================================================
script SC_CL_EFFECTS (void) NET CLIENTSIDE {
int last_nohud = GetCVAR ("aow_cl_nohud");
int last_confonthud = GetCVAR ("aow_cl_confonthud");
int tid, targ;
int tick = 0;
while (1) {
// [Dusk] If HUD preferences have changed, refresh the HUD.
if (GetCVar ("aow_cl_nohud") != last_nohud ||
GetCVar ("aow_cl_confonthud") != last_confonthud)
{
last_nohud = GetCVar ("aow_cl_nohud");
last_nohud = GetCVar ("aow_cl_confonthud");
UpdateHUD ();
}
for (int i = 0; i < MAXPLAYERS; i++) {
tid = 3800+i;
// Display smoke on tib-carrying players
if (CheckActorInventory (tid, "TiberiumCrystal"))
SpawnSpotForced ("TiberiumChemSmokePlayer", tid, 0, GetActorAngle(tid)>>8);
// Flicker friendly stealths
int teammate = (GetPlayerInfo (i, PLAYERINFO_TEAM) == ConsoleTeam ()) || !PlayerInGame (consoleplayer);
if (teammate && i != consoleplayer && (CheckActorInventory (tid, "StealthMode") == 2)) {
SetActorProperty (tid, APROP_RenderStyle, STYLE_Translucent);
SetActorProperty (tid, APROP_Alpha, 0.6);
}
// Jetpack fire
if (CheckActorInventory (tid, "JetpackActive"))
SpawnSpotForced ("JumpjetFire", tid, 0, GetActorAngle (tid)>>8);
// Spawn invulnerability particles
if (CheckActorInventory (tid, "PowerSpawnInvulnerability") && i != consoleplayer)
ACS_ExecuteAlways (977, 0, 0, tid);
// Time gun boost particles
if ((CheckActorInventory (tid, "PowerTimeGunBoost") ||
CheckActorInventory (tid, "PowerTimeGunFloat") ||
CheckActorInventory (tid, "PowerTimeGunSpeed")) &&
i != consoleplayer)
ACS_ExecuteAlways (977, 0, 1, tid);
// negative effects
if ((CheckActorInventory (tid, "PowerTimeGunSlow") ||
CheckActorInventory (tid, "PowerTimeGunWeaken")) &&
i != consoleplayer)
ACS_ExecuteAlways (977, 0, 2, tid);
}
// If we're targeting a teammate tortoise, draw its passenger list
if (tick % 3 == 0) {
if (SetActivator (3800 + consoleplayer) && !CheckInventory ("IsMech")) {
targ = GetTargetInfo (TARGETINFO_TID);
teammate = (GetPlayerInfo (targ - 3800, PLAYERINFO_TEAM) == ConsoleTeam ()) || !PlayerInGame (consoleplayer);
if (targ != ActivatorTID() && CheckActorInventory (targ, "TortoiseWeapons") && teammate)
DrawTortoiseHUD (targ, 1.0);
}
}
tick++;
delay (5);
}
}

// =============================================================================
// Secondary script for client-side effects. All case-statements should last
// for *five tics* and five tics exact.
script SC_CL_EFFECTS2 (int a, int b) {
int i;
switch (a) {
case 0:
case 1:
case 2:
// Spawn invul particles
for (i = 0; i < 5; i++) {
switch (a) {
case 0:
SpawnSpotForced ("SpawnInvulnerabilityFX", b, 0, 0);
break;
case 1:
SpawnSpotForced ("TimeGunBoostFX", b, 0, 0);
break;
case 2:
SpawnSpotForced ("TimeGunSlowFX", b, 0, 0);
break;
}
delay (1);
}
}
}

// =============================================================================
// trail -> player
script SC_CL_EFFECTTRAIL (int type, int target) CLIENTSIDE {
switch (type) {
case 0:
// Shock rifle trail
SpawnTrail (0, target, "VoltageTrailFX", 32, 12, 0, 0, 0, -6.0, 6.0, 36.0);
break;
case 1:
// Bomb-squad gun (yellow)
SpawnTrail (0, target, "DisarmTrail", 8, 0, 0, 0, 0, 0, 5.0, 36.0);
break;
case 2:
// Heal gun (red)