Split scenarios into .inc files
This commit is contained in:
parent
df3c389b1c
commit
4167ec8c89
|
|
@ -1037,7 +1037,7 @@ u32 botPickupProp(struct prop *prop, struct chrdata *chr)
|
|||
if (weapon->weaponnum == WEAPON_BRIEFCASE2) {
|
||||
result = scenarioPickUpBriefcase(chr, prop);
|
||||
} else if (weapon->weaponnum == WEAPON_DATAUPLINK) {
|
||||
result = chrGiveUplink(chr, prop);
|
||||
result = scenarioPickUpUplink(chr, prop);
|
||||
} else {
|
||||
propPlayPickupSound(prop, weapon->weaponnum);
|
||||
qty = weaponGetPickupAmmoQty(weapon);
|
||||
|
|
@ -1361,7 +1361,7 @@ glabel var7f1b3480nb
|
|||
.NB0f18ab4c:
|
||||
/* f18ab4c: 14a10005 */ bne $a1,$at,.NB0f18ab64
|
||||
/* f18ab50: 02402025 */ or $a0,$s2,$zero
|
||||
/* f18ab54: 0fc60612 */ jal chrGiveUplink
|
||||
/* f18ab54: 0fc60612 */ jal scenarioPickUpUplink
|
||||
/* f18ab58: 8fa50080 */ lw $a1,0x80($sp)
|
||||
/* f18ab5c: 1000005b */ beqz $zero,.NB0f18accc
|
||||
/* f18ab60: 8fbf0054 */ lw $ra,0x54($sp)
|
||||
|
|
@ -3191,7 +3191,7 @@ glabel var7f1b8ef0
|
|||
/* f191f54: 8fbf0024 */ lw $ra,0x24($sp)
|
||||
/* f191f58: 51c00004 */ beqzl $t6,.L0f191f6c
|
||||
/* f191f5c: 8faf0058 */ lw $t7,0x58($sp)
|
||||
/* f191f60: 0fc615c8 */ jal scenarioCallback14
|
||||
/* f191f60: 0fc615c8 */ jal scenarioTickChr
|
||||
/* f191f64: 02202025 */ or $a0,$s1,$zero
|
||||
/* f191f68: 8faf0058 */ lw $t7,0x58($sp)
|
||||
.L0f191f6c:
|
||||
|
|
@ -3703,7 +3703,7 @@ glabel var7f1b8ef0
|
|||
/* f191f54: 8fbf0024 */ lw $ra,0x24($sp)
|
||||
/* f191f58: 51c00004 */ beqzl $t6,.L0f191f6c
|
||||
/* f191f5c: 8faf0058 */ lw $t7,0x58($sp)
|
||||
/* f191f60: 0fc615c8 */ jal scenarioCallback14
|
||||
/* f191f60: 0fc615c8 */ jal scenarioTickChr
|
||||
/* f191f64: 02202025 */ or $a0,$s1,$zero
|
||||
/* f191f68: 8faf0058 */ lw $t7,0x58($sp)
|
||||
.L0f191f6c:
|
||||
|
|
@ -3902,7 +3902,7 @@ glabel var7f1b8ef0
|
|||
//
|
||||
// if (g_Vars.lvframe60 >= 145) {
|
||||
// if (updateable) {
|
||||
// scenarioCallback14(chr);
|
||||
// scenarioTickChr(chr);
|
||||
// }
|
||||
//
|
||||
// if (updateable && !chrIsDead(chr)) {
|
||||
|
|
@ -7335,11 +7335,7 @@ s32 botGetNumOpponentsInHill(struct chrdata *chr)
|
|||
if (g_MpAllChrPtrs[i]->prop->rooms[0] == g_ScenarioData.koh.hillrooms[0]) {
|
||||
s32 mpindex = func0f18d074(i);
|
||||
|
||||
if (mpindex < 4) {
|
||||
loopmpchr = &g_PlayerConfigsArray[mpindex].base;
|
||||
} else {
|
||||
loopmpchr = &g_BotConfigsArray[mpindex - 4].base;
|
||||
}
|
||||
loopmpchr = MPCHR(mpindex);
|
||||
|
||||
if (loopmpchr->team != mpchr->team) {
|
||||
countsperteam[loopmpchr->team]++;
|
||||
|
|
|
|||
|
|
@ -1143,7 +1143,7 @@ void botinvDrop(struct chrdata *chr, s32 weaponnum, u8 dropall)
|
|||
objDrop(prop, true);
|
||||
|
||||
if (item->type_weap.weapon1 == WEAPON_BRIEFCASE2) {
|
||||
scenarioReleaseToken(chr, prop);
|
||||
scenarioHandleDroppedToken(chr, prop);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8347,7 +8347,7 @@ Gfx *chrRender(struct prop *prop, Gfx *gdl, bool withalpha)
|
|||
}
|
||||
|
||||
if (g_Vars.normmplayerisrunning) {
|
||||
speb = scenarioHighlight(prop, colour);
|
||||
speb = scenarioHighlightProp(prop, colour);
|
||||
}
|
||||
|
||||
if (!speb) {
|
||||
|
|
|
|||
|
|
@ -3641,7 +3641,7 @@ glabel var7f1a7dd4
|
|||
/* f004104: 27a50080 */ addiu $a1,$sp,0x80
|
||||
/* f004108: 27a6007c */ addiu $a2,$sp,0x7c
|
||||
/* f00410c: 27a70078 */ addiu $a3,$sp,0x78
|
||||
/* f004110: 0fc6192e */ jal scenarioCallback38
|
||||
/* f004110: 0fc6192e */ jal scenarioHighlightRoom
|
||||
/* f004114: afa20080 */ sw $v0,0x80($sp)
|
||||
/* f004118: 8fb80080 */ lw $t8,0x80($sp)
|
||||
/* f00411c: 8e790000 */ lw $t9,0x0($s3)
|
||||
|
|
@ -4471,7 +4471,7 @@ glabel var7f1a7dd4
|
|||
/* f003e4c: 27a50080 */ addiu $a1,$sp,0x80
|
||||
/* f003e50: 27a6007c */ addiu $a2,$sp,0x7c
|
||||
/* f003e54: 27a70078 */ addiu $a3,$sp,0x78
|
||||
/* f003e58: 0fc60248 */ jal scenarioCallback38
|
||||
/* f003e58: 0fc60248 */ jal scenarioHighlightRoom
|
||||
/* f003e5c: afa20080 */ sw $v0,0x80($sp)
|
||||
/* f003e60: 8fb90080 */ lw $t9,0x80($sp)
|
||||
/* f003e64: 8e680000 */ lw $t0,0x0($s3)
|
||||
|
|
@ -5085,7 +5085,7 @@ glabel var7f1a7ddc
|
|||
/* f004b7c: 27a70078 */ addiu $a3,$sp,0x78
|
||||
/* f004b80: afa9003c */ sw $t1,0x3c($sp)
|
||||
/* f004b84: afaa0040 */ sw $t2,0x40($sp)
|
||||
/* f004b88: 0fc6192e */ jal scenarioCallback38
|
||||
/* f004b88: 0fc6192e */ jal scenarioHighlightRoom
|
||||
/* f004b8c: afac0074 */ sw $t4,0x74($sp)
|
||||
/* f004b90: 3c1f8007 */ lui $ra,%hi(g_InCutscene)
|
||||
/* f004b94: 27ff0764 */ addiu $ra,$ra,%lo(g_InCutscene)
|
||||
|
|
|
|||
|
|
@ -2838,7 +2838,7 @@ void setupLoadFiles(s32 stagenum)
|
|||
total += setupCountCommandType(OBJTYPE_ESCASTEP);
|
||||
|
||||
if (g_Vars.normmplayerisrunning) {
|
||||
total += scenarioCallback08();
|
||||
total += scenarioNumProps();
|
||||
}
|
||||
|
||||
func0f011130(total, numchrs);
|
||||
|
|
@ -3480,7 +3480,7 @@ void setupParseObjects(s32 stagenum)
|
|||
}
|
||||
|
||||
if (g_Vars.normmplayerisrunning) {
|
||||
scenarioReset();
|
||||
scenarioInitProps();
|
||||
}
|
||||
|
||||
obj = (struct defaultobj *)g_StageSetup.props;
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
#include "game/training/training.h"
|
||||
#include "game/lang.h"
|
||||
#include "game/mplayer/mplayer.h"
|
||||
#include "game/mplayer/scenarios.h"
|
||||
#include "game/pad.h"
|
||||
#include "bss.h"
|
||||
#include "lib/dma.h"
|
||||
|
|
|
|||
|
|
@ -429,7 +429,7 @@ void lvInit(s32 stagenum)
|
|||
func0f011110();
|
||||
func0f0108d0();
|
||||
setupLoadFiles(stagenum);
|
||||
mpPrepareScenario();
|
||||
scenarioReset();
|
||||
gvarsInitProps();
|
||||
setupInit();
|
||||
func0f00b510();
|
||||
|
|
@ -815,7 +815,7 @@ glabel var7f1b1f44nc
|
|||
/* f162a94: 00000000 */ sll $zero,$zero,0x0
|
||||
/* f162a98: 0fc03a25 */ jal setupLoadFiles
|
||||
/* f162a9c: 8fa40020 */ lw $a0,0x20($sp)
|
||||
/* f162aa0: 0fc6019d */ jal mpPrepareScenario
|
||||
/* f162aa0: 0fc6019d */ jal scenarioReset
|
||||
/* f162aa4: 00000000 */ sll $zero,$zero,0x0
|
||||
/* f162aa8: 0fc02fbc */ jal gvarsInitProps
|
||||
/* f162aac: 00000000 */ sll $zero,$zero,0x0
|
||||
|
|
@ -2242,7 +2242,7 @@ glabel var7f1b8e7cpf
|
|||
/* f16ad40: 00000000 */ nop
|
||||
/* f16ad44: 0fc18ca3 */ jal propsTick
|
||||
/* f16ad48: 02202025 */ move $a0,$s1
|
||||
/* f16ad4c: 0fc619c9 */ jal scenarioCallback14
|
||||
/* f16ad4c: 0fc619c9 */ jal scenarioTickChr
|
||||
/* f16ad50: 00002025 */ move $a0,$zero
|
||||
/* f16ad54: 0fc18104 */ jal propsSort
|
||||
/* f16ad58: 00000000 */ nop
|
||||
|
|
@ -3655,7 +3655,7 @@ Gfx *lvRender(Gfx *gdl)
|
|||
roomsTick();
|
||||
func0f004314();
|
||||
propsTick(islastplayer);
|
||||
scenarioCallback14(NULL);
|
||||
scenarioTickChr(NULL);
|
||||
propsSort();
|
||||
autoaimTick();
|
||||
handsTickAttack();
|
||||
|
|
@ -4830,7 +4830,7 @@ glabel var7f1b1fd4nb
|
|||
/* f164a48: 00000000 */ sll $zero,$zero,0x0
|
||||
/* f164a4c: 0fc188ac */ jal propsTick
|
||||
/* f164a50: 02202025 */ or $a0,$s1,$zero
|
||||
/* f164a54: 0fc5ff30 */ jal scenarioCallback14
|
||||
/* f164a54: 0fc5ff30 */ jal scenarioTickChr
|
||||
/* f164a58: 00002025 */ or $a0,$zero,$zero
|
||||
/* f164a5c: 0fc17d1c */ jal propsSort
|
||||
/* f164a60: 00000000 */ sll $zero,$zero,0x0
|
||||
|
|
|
|||
|
|
@ -10879,11 +10879,7 @@ Gfx *menuRenderItemPlayerStats(Gfx *gdl, struct menurendercontext *context)
|
|||
s32 gap;
|
||||
s32 ypos = 0;
|
||||
|
||||
if (playernum < 4) {
|
||||
mpchr = &g_PlayerConfigsArray[playernum].base;
|
||||
} else {
|
||||
mpchr = &g_BotConfigsArray[playernum - 4].base;
|
||||
}
|
||||
mpchr = MPCHR(playernum);
|
||||
|
||||
gdl = func0f153628(gdl);
|
||||
|
||||
|
|
@ -11035,13 +11031,7 @@ Gfx *menuRenderItemPlayerStats(Gfx *gdl, struct menurendercontext *context)
|
|||
|
||||
for (i = 0; i < 12; i++) {
|
||||
if (g_MpSetup.chrslots & (1 << i)) {
|
||||
struct mpchrconfig *loopmpchr;
|
||||
|
||||
if (i < 4) {
|
||||
loopmpchr = &g_PlayerConfigsArray[i].base;
|
||||
} else {
|
||||
loopmpchr = &g_BotConfigsArray[i - 4].base;
|
||||
}
|
||||
struct mpchrconfig *loopmpchr = MPCHR(i);
|
||||
|
||||
if (i != playernum) {
|
||||
// Name
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ struct menudialog g_MpEndscreenSavePlayerMenuDialog;
|
|||
|
||||
s32 mpStatsForPlayerDropdownHandler(s32 operation, struct menuitem *item, union handlerdata *data)
|
||||
{
|
||||
char *name;
|
||||
struct mpchrconfig *mpchr;
|
||||
s32 v0;
|
||||
s32 v1;
|
||||
s32 a1;
|
||||
|
|
@ -50,14 +50,10 @@ s32 mpStatsForPlayerDropdownHandler(s32 operation, struct menuitem *item, union
|
|||
|
||||
for (a1 = 0; a1 < 12; a1++) {
|
||||
if (g_MpSetup.chrslots & (1 << a1)) {
|
||||
if (a1 < 4) {
|
||||
name = g_PlayerConfigsArray[a1].base.name;
|
||||
} else {
|
||||
name = g_BotConfigsArray[a1 - 4].base.name;
|
||||
}
|
||||
mpchr = MPCHR(a1);
|
||||
|
||||
if (v0 == data->list.value) {
|
||||
return (s32) name;
|
||||
return (s32) mpchr->name;
|
||||
}
|
||||
|
||||
v0++;
|
||||
|
|
@ -216,16 +212,10 @@ char *mpMenuTextWeaponDescription(struct menuitem *item)
|
|||
|
||||
char *mpMenuTitleStatsFor(struct menudialog *dialog)
|
||||
{
|
||||
char *name;
|
||||
|
||||
if (g_MpSelectedPlayersForStats[g_MpPlayerNum] < 4) {
|
||||
name = g_PlayerConfigsArray[g_MpSelectedPlayersForStats[g_MpPlayerNum]].base.name;
|
||||
} else {
|
||||
name = g_BotConfigsArray[g_MpSelectedPlayersForStats[g_MpPlayerNum] - 4].base.name;
|
||||
}
|
||||
struct mpchrconfig *mpchr = MPCHR(g_MpSelectedPlayersForStats[g_MpPlayerNum]);
|
||||
|
||||
// "Stats for %s"
|
||||
sprintf(g_StringPointer, langGet(L_MPMENU_280), name);
|
||||
sprintf(g_StringPointer, langGet(L_MPMENU_280), mpchr->name);
|
||||
return g_StringPointer;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -246,13 +246,7 @@ void mpInit(void)
|
|||
}
|
||||
|
||||
for (i = 0; i != 12; i++) {
|
||||
struct mpchrconfig *mpchr;
|
||||
|
||||
if (i < 4) {
|
||||
mpchr = &g_PlayerConfigsArray[i].base;
|
||||
} else {
|
||||
mpchr = &g_BotConfigsArray[i - 4].base;
|
||||
}
|
||||
struct mpchrconfig *mpchr = MPCHR(i);
|
||||
|
||||
func0f187838(mpchr);
|
||||
|
||||
|
|
@ -1121,11 +1115,7 @@ s32 mpCalculateTeamScore(s32 teamnum, s32 *result)
|
|||
|
||||
for (i = 0; i < 12; i++) {
|
||||
if (g_MpSetup.chrslots & (1 << i)) {
|
||||
if (i < 4) {
|
||||
mpchr = &g_PlayerConfigsArray[i].base;
|
||||
} else {
|
||||
mpchr = &g_BotConfigsArray[i - 4].base;
|
||||
}
|
||||
mpchr = MPCHR(i);
|
||||
|
||||
if (mpchr->team == teamnum) {
|
||||
scenarioCalculatePlayerScore(mpchr, i, &score, &deaths);
|
||||
|
|
@ -7217,11 +7207,7 @@ void mpFindUnusedHeadAndBody(u8 *mpheadnum, u8 *mpbodynum)
|
|||
|
||||
for (i = 0; i < 12; i++) {
|
||||
if (g_MpSetup.chrslots & (1 << i)) {
|
||||
if (i < 4) {
|
||||
mpchr = &g_PlayerConfigsArray[i].base;
|
||||
} else {
|
||||
mpchr = &g_BotConfigsArray[i - 4].base;
|
||||
}
|
||||
mpchr = MPCHR(i);
|
||||
|
||||
if (mpchr->mpheadnum == trympheadnum) {
|
||||
available = false;
|
||||
|
|
@ -7940,11 +7926,7 @@ struct mpchrconfig *mpGetChrConfigBySlotNum(s32 slot)
|
|||
for (i = 0; i < 12; i++) {
|
||||
if (g_MpSetup.chrslots & (1 << i)) {
|
||||
if (count == slot) {
|
||||
if (i < 4) {
|
||||
result = &g_PlayerConfigsArray[i].base;
|
||||
} else {
|
||||
result = &g_BotConfigsArray[i - 4].base;
|
||||
}
|
||||
result = MPCHR(i);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -8002,13 +7984,7 @@ u8 mpFindUnusedTeamNum(void)
|
|||
|
||||
for (i = 0; i < 12; i++) {
|
||||
if (g_MpSetup.chrslots & (1 << i)) {
|
||||
struct mpchrconfig *mpchr;
|
||||
|
||||
if (i < 4) {
|
||||
mpchr = &g_PlayerConfigsArray[i].base;
|
||||
} else {
|
||||
mpchr = &g_BotConfigsArray[i - 4].base;
|
||||
}
|
||||
struct mpchrconfig *mpchr = MPCHR(i);
|
||||
|
||||
if (mpchr->team == teamnum) {
|
||||
available = false;
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,437 @@
|
|||
/**
|
||||
* Capture the Case
|
||||
*
|
||||
* Each team has a base. The base is highlighted in their team colour and
|
||||
* contains a briefcase on the ground. Players must infiltrate another team's
|
||||
* base, collect their briefcase and then return it to their own.
|
||||
*
|
||||
* When a briefcase holder is killed, the briefcase is immediately returned to
|
||||
* the team's base.
|
||||
*
|
||||
* Players cannot score unless their briefcase is at the home base.
|
||||
*/
|
||||
|
||||
struct menuitem g_CtcOptionsMenuItems[] = {
|
||||
{ MENUITEMTYPE_CHECKBOX, 0, 0x00020000, L_MPMENU_222, MPOPTION_ONEHITKILLS, menuhandlerMpOneHitKills }, // "One-Hit Kills"
|
||||
{ MENUITEMTYPE_DROPDOWN, 0, 0x00020000, L_MPMENU_223, 0x00000000, menuhandlerMpSlowMotion }, // "Slow Motion"
|
||||
{ MENUITEMTYPE_CHECKBOX, 0, 0x00020000, L_MPMENU_224, MPOPTION_FASTMOVEMENT, menuhandlerMpCheckboxOption }, // "Fast Movement"
|
||||
{ MENUITEMTYPE_CHECKBOX, 0, 0x00020000, L_MPMENU_225, MPOPTION_DISPLAYTEAM, menuhandlerMpDisplayTeam }, // "Display Team"
|
||||
{ MENUITEMTYPE_CHECKBOX, 0, 0x00020000, L_MPMENU_226, MPOPTION_NORADAR, menuhandlerMpCheckboxOption }, // "No Radar"
|
||||
{ MENUITEMTYPE_CHECKBOX, 0, 0x00020000, L_MPMENU_227, MPOPTION_NOAUTOAIM, menuhandlerMpCheckboxOption }, // "No Auto-Aim"
|
||||
{ MENUITEMTYPE_CHECKBOX, 0, 0x00020000, L_OPTIONS_493, MPOPTION_KILLSSCORE, menuhandlerMpCheckboxOption }, // "Kills Score"
|
||||
{ MENUITEMTYPE_SEPARATOR, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
|
||||
{ MENUITEMTYPE_CHECKBOX, 0, 0x00020000, L_MPMENU_236, MPOPTION_CTC_SHOWONRADAR, menuhandlerMpCheckboxOption }, // "Show on Radar"
|
||||
{ MENUITEMTYPE_SEPARATOR, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
|
||||
{ MENUITEMTYPE_SELECTABLE, 0, 0x00000008, L_MPMENU_239, 0x00000000, NULL }, // "Back"
|
||||
{ MENUITEMTYPE_END, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
|
||||
};
|
||||
|
||||
struct menudialog g_CtcOptionsMenuDialog = {
|
||||
MENUDIALOGTYPE_DEFAULT,
|
||||
L_MPMENU_220, // "Capture Options"
|
||||
g_CtcOptionsMenuItems,
|
||||
mpOptionsMenuDialog,
|
||||
0x00000010,
|
||||
NULL,
|
||||
};
|
||||
|
||||
struct weaponobj g_CtcTokenObj0;
|
||||
struct weaponobj g_CtcTokenObj1;
|
||||
struct weaponobj g_CtcTokenObj2;
|
||||
struct weaponobj g_CtcTokenObj3;
|
||||
|
||||
void ctcInit(void)
|
||||
{
|
||||
s32 i, j, k;
|
||||
g_MpSetup.options |= MPOPTION_TEAMSENABLED;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
s32 j;
|
||||
g_ScenarioData.ctc.spawnpadsperteam[i].homepad = i;
|
||||
g_ScenarioData.ctc.spawnpadsperteam[i].numspawnpads = 0;
|
||||
|
||||
for (j = 0; j < 6; j++) {
|
||||
g_ScenarioData.ctc.spawnpadsperteam[i].spawnpads[j] = -1;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i != 4; i++) {
|
||||
g_ScenarioData.ctc.playercountsperteam[i] = 0;
|
||||
g_ScenarioData.ctc.teamindexes[i] = -1;
|
||||
}
|
||||
|
||||
for (k = 0; k < MAX_MPCHRS; k++) {
|
||||
if (g_MpSetup.chrslots & (1 << k)) {
|
||||
struct mpchrconfig *mpchr = MPCHR(k);
|
||||
|
||||
while (mpchr->team >= scenarioGetMaxTeams()) {
|
||||
mpchr->team -= scenarioGetMaxTeams();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
s32 ctcNumProps(void)
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
|
||||
void ctcTick(void)
|
||||
{
|
||||
// empty
|
||||
}
|
||||
|
||||
void ctcTickChr(struct chrdata *chr)
|
||||
{
|
||||
if (chr);
|
||||
}
|
||||
|
||||
void ctcInitProps(void)
|
||||
{
|
||||
struct mpchrconfig *mpchr;
|
||||
struct weaponobj *tmp;
|
||||
s32 mpindex;
|
||||
u32 stack;
|
||||
bool teamsdone[4];
|
||||
|
||||
struct weaponobj template = {
|
||||
256, // extrascale
|
||||
0, // hidden2
|
||||
OBJTYPE_WEAPON, // type
|
||||
MODEL_CHRBRIEFCASE, // modelnum
|
||||
0, // pad
|
||||
OBJFLAG_00000001 | OBJFLAG_INVINCIBLE | OBJFLAG_00400000,
|
||||
OBJFLAG2_IMMUNETOGUNFIRE | OBJFLAG2_00200000,
|
||||
0, // flags3
|
||||
NULL, // prop
|
||||
NULL, // model
|
||||
1, 0, 0, // realrot
|
||||
0, 1, 0,
|
||||
0, 0, 1,
|
||||
0, // hidden
|
||||
NULL, // geo
|
||||
NULL, // projectile
|
||||
0, // damage
|
||||
1000, // maxdamage
|
||||
0xff, 0xff, 0xff, 0x00, // shadecol
|
||||
0xff, 0xff, 0xff, 0x00, // nextcol
|
||||
0x0fff, // floorcol
|
||||
0, // tiles
|
||||
WEAPON_BRIEFCASE2, // weaponnum
|
||||
0, // unk5d
|
||||
0, // unk5e
|
||||
FUNC_PRIMARY, // gunfunc
|
||||
0, // fadeouttimer60
|
||||
-1, // dualweaponnum
|
||||
-1, // timer240
|
||||
NULL, // dualweapon
|
||||
};
|
||||
|
||||
s32 i;
|
||||
s32 j;
|
||||
s32 k;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
for (j = 0; j < 6; j++) {
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
teamsdone[i] = false;
|
||||
g_ScenarioData.ctc.playercountsperteam[i] = 0;
|
||||
}
|
||||
|
||||
for (i = 0; i != 4; i++) {
|
||||
do {
|
||||
g_ScenarioData.ctc.teamindexes[i] = random() % 4;
|
||||
} while (teamsdone[g_ScenarioData.ctc.teamindexes[i]]);
|
||||
|
||||
teamsdone[g_ScenarioData.ctc.teamindexes[i]] = true;
|
||||
}
|
||||
|
||||
for (k = 0; k < 12; k++) {
|
||||
if (g_MpSetup.chrslots & (1 << k)) {
|
||||
mpchr = MPCHR(k);
|
||||
|
||||
while (mpchr->team >= scenarioGetMaxTeams()) {
|
||||
mpchr->team -= scenarioGetMaxTeams();
|
||||
}
|
||||
|
||||
#if VERSION >= VERSION_NTSC_1_0
|
||||
mpindex = func0f18d0e8(k);
|
||||
|
||||
if (mpindex >= 0) {
|
||||
struct chrdata *chr = mpGetChrFromPlayerIndex(mpindex);
|
||||
|
||||
if (chr) {
|
||||
chr->team = 1 << mpchr->team;
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (func0f18d0e8(k) >= 0) {
|
||||
struct chrdata *chr = mpGetChrFromPlayerIndex(func0f18d0e8(k));
|
||||
|
||||
if (chr) {
|
||||
chr->team = 1 << mpchr->team;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
g_ScenarioData.ctc.playercountsperteam[mpchr->team]++;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (g_ScenarioData.ctc.playercountsperteam[i] == 0) {
|
||||
g_ScenarioData.ctc.teamindexes[i] = -1;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
// empty
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
g_ScenarioData.ctc.tokens[i] = NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
g_ScenarioData.ctc.baserooms[i] = -1;
|
||||
}
|
||||
|
||||
if (g_ScenarioData.ctc.playercountsperteam[0] != 0) {
|
||||
g_CtcTokenObj0 = template;
|
||||
tmp = &g_CtcTokenObj0;
|
||||
tmp->base.pad = g_ScenarioData.ctc.spawnpadsperteam[g_ScenarioData.ctc.teamindexes[0]].homepad;
|
||||
|
||||
weaponAssignToHome(tmp, 1000);
|
||||
|
||||
g_ScenarioData.ctc.tokens[0] = tmp->base.prop;
|
||||
|
||||
tmp->base.hidden2 &= ~OBJH2FLAG_CANREGEN;
|
||||
tmp->team = 0;
|
||||
|
||||
g_ScenarioData.ctc.baserooms[0] = g_ScenarioData.ctc.tokens[0]->rooms[0];
|
||||
}
|
||||
|
||||
if (g_ScenarioData.ctc.playercountsperteam[1] != 0) {
|
||||
g_CtcTokenObj1 = template;
|
||||
tmp = &g_CtcTokenObj1;
|
||||
tmp->base.pad = g_ScenarioData.ctc.spawnpadsperteam[g_ScenarioData.ctc.teamindexes[1]].homepad;
|
||||
|
||||
weaponAssignToHome(tmp, 1001);
|
||||
|
||||
g_ScenarioData.ctc.tokens[1] = tmp->base.prop;
|
||||
|
||||
tmp->base.hidden2 &= ~OBJH2FLAG_CANREGEN;
|
||||
tmp->team = 1;
|
||||
|
||||
g_ScenarioData.ctc.baserooms[1] = g_ScenarioData.ctc.tokens[1]->rooms[0];
|
||||
}
|
||||
|
||||
if (g_ScenarioData.ctc.playercountsperteam[2] != 0) {
|
||||
g_CtcTokenObj2 = template;
|
||||
tmp = &g_CtcTokenObj2;
|
||||
tmp->base.pad = g_ScenarioData.ctc.spawnpadsperteam[g_ScenarioData.ctc.teamindexes[2]].homepad;
|
||||
|
||||
weaponAssignToHome(tmp, 1002);
|
||||
|
||||
g_ScenarioData.ctc.tokens[2] = tmp->base.prop;
|
||||
|
||||
tmp->base.hidden2 &= ~OBJH2FLAG_CANREGEN;
|
||||
tmp->team = 2;
|
||||
|
||||
g_ScenarioData.ctc.baserooms[2] = g_ScenarioData.ctc.tokens[2]->rooms[0];
|
||||
}
|
||||
|
||||
if (g_ScenarioData.ctc.playercountsperteam[3] != 0) {
|
||||
g_CtcTokenObj3 = template;
|
||||
tmp = &g_CtcTokenObj3;
|
||||
tmp->base.pad = g_ScenarioData.ctc.spawnpadsperteam[g_ScenarioData.ctc.teamindexes[3]].homepad;
|
||||
|
||||
weaponAssignToHome(tmp, 1003);
|
||||
|
||||
g_ScenarioData.ctc.tokens[3] = tmp->base.prop;
|
||||
|
||||
tmp->base.hidden2 &= ~OBJH2FLAG_CANREGEN;
|
||||
tmp->team = 3;
|
||||
|
||||
g_ScenarioData.ctc.baserooms[3] = g_ScenarioData.ctc.tokens[3]->rooms[0];
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (g_ScenarioData.ctc.playercountsperteam[i] && g_ScenarioData.ctc.baserooms[i] != -1) {
|
||||
roomSetLighting(g_ScenarioData.ctc.baserooms[i], 5, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ctcCalculatePlayerScore(struct mpchrconfig *mpchr, s32 mpchrnum, s32 *score, s32 *deaths)
|
||||
{
|
||||
struct mpchrconfig *loopmpchr;
|
||||
s32 i;
|
||||
|
||||
*score = 0;
|
||||
*score += mpchr->numpoints * 3;
|
||||
|
||||
if (g_MpSetup.options & MPOPTION_KILLSSCORE) {
|
||||
for (i = 0; i != MAX_MPCHRS; i++) {
|
||||
if (i == mpchrnum) {
|
||||
*score -= mpchr->killcounts[i];
|
||||
} else {
|
||||
loopmpchr = MPCHR(i);
|
||||
|
||||
if (loopmpchr->team == mpchr->team) {
|
||||
*score -= mpchr->killcounts[i];
|
||||
} else {
|
||||
*score += mpchr->killcounts[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*deaths = mpchr->numdeaths;
|
||||
}
|
||||
|
||||
Gfx *ctcRadarExtra(Gfx *gdl)
|
||||
{
|
||||
if (g_MpSetup.options & MPOPTION_CTC_SHOWONRADAR) {
|
||||
s32 i;
|
||||
|
||||
for (i = 0; i < scenarioGetMaxTeams(); i++) {
|
||||
if (g_ScenarioData.ctc.tokens[i] &&
|
||||
g_ScenarioData.ctc.tokens[i]->type != PROPTYPE_CHR &&
|
||||
g_ScenarioData.ctc.tokens[i]->type != PROPTYPE_PLAYER) {
|
||||
struct coord dist;
|
||||
dist.x = g_ScenarioData.ctc.tokens[i]->pos.x - g_Vars.currentplayer->prop->pos.x;
|
||||
dist.y = g_ScenarioData.ctc.tokens[i]->pos.y - g_Vars.currentplayer->prop->pos.y;
|
||||
dist.z = g_ScenarioData.ctc.tokens[i]->pos.z - g_Vars.currentplayer->prop->pos.z;
|
||||
gdl = radarDrawDot(gdl, g_ScenarioData.ctc.tokens[i], &dist, g_TeamColours[i], 0, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return gdl;
|
||||
}
|
||||
|
||||
bool ctcRadarChr(Gfx **gdl, struct prop *prop)
|
||||
{
|
||||
s32 i;
|
||||
|
||||
if (g_MpSetup.options & MPOPTION_CTC_SHOWONRADAR) {
|
||||
for (i = 0; i < scenarioGetMaxTeams(); i++) {
|
||||
if (prop == g_ScenarioData.ctc.tokens[i] &&
|
||||
(g_ScenarioData.ctc.tokens[i]->type == PROPTYPE_CHR || g_ScenarioData.ctc.tokens[i]->type == PROPTYPE_PLAYER)) {
|
||||
struct coord dist;
|
||||
s32 colour = g_TeamColours[radarGetTeamIndex(prop->chr->team)];
|
||||
dist.x = g_ScenarioData.ctc.tokens[i]->pos.x - g_Vars.currentplayer->prop->pos.x;
|
||||
dist.y = g_ScenarioData.ctc.tokens[i]->pos.y - g_Vars.currentplayer->prop->pos.y;
|
||||
dist.z = g_ScenarioData.ctc.tokens[i]->pos.z - g_Vars.currentplayer->prop->pos.z;
|
||||
*gdl = radarDrawDot(*gdl, g_ScenarioData.ctc.tokens[i], &dist,
|
||||
g_TeamColours[i], colour, 1);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ctcHighlightProp(struct prop *prop, s32 *colour)
|
||||
{
|
||||
struct defaultobj *obj = prop->obj;
|
||||
|
||||
if (prop->type == PROPTYPE_OBJ || prop->type == PROPTYPE_WEAPON || prop->type == PROPTYPE_DOOR) {
|
||||
if (obj->type == OBJTYPE_WEAPON) {
|
||||
struct weaponobj *weapon = prop->weapon;
|
||||
|
||||
if (weapon->weaponnum == WEAPON_BRIEFCASE2) {
|
||||
u32 teamcolour = g_TeamColours[weapon->team];
|
||||
|
||||
colour[0] = teamcolour >> 24 & 0xff;
|
||||
colour[1] = teamcolour >> 16 & 0xff;
|
||||
colour[2] = teamcolour >> 8 & 0xff;
|
||||
colour[3] = 75;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void ctcAddPad(s32 *cmd)
|
||||
{
|
||||
s32 i;
|
||||
|
||||
if (cmd[0] == INTROCMD_CASE) {
|
||||
g_ScenarioData.ctc.spawnpadsperteam[cmd[1]].homepad = cmd[2];
|
||||
}
|
||||
|
||||
if (cmd[0] == INTROCMD_CASERESPAWN) {
|
||||
for (i = 0; i != ARRAYCOUNT(g_ScenarioData.ctc.spawnpadsperteam[cmd[1]].spawnpads); i++) {
|
||||
if (g_ScenarioData.ctc.spawnpadsperteam[cmd[1]].spawnpads[i] == -1) {
|
||||
g_ScenarioData.ctc.spawnpadsperteam[cmd[1]].spawnpads[i] = cmd[2];
|
||||
g_ScenarioData.ctc.spawnpadsperteam[cmd[1]].numspawnpads++;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool ctcChooseSpawnLocation(f32 arg0, struct coord *pos, s16 *rooms, struct prop *prop, f32 *arg4)
|
||||
{
|
||||
struct chrdata *chr = prop->chr;
|
||||
s32 index = radarGetTeamIndex(chr->team);
|
||||
|
||||
if (g_ScenarioData.ctc.spawnpadsperteam[g_ScenarioData.ctc.teamindexes[index]].numspawnpads > 0) {
|
||||
*arg4 = playerChooseSpawnLocation(arg0, pos, rooms, prop,
|
||||
g_ScenarioData.ctc.spawnpadsperteam[g_ScenarioData.ctc.teamindexes[index]].spawnpads,
|
||||
g_ScenarioData.ctc.spawnpadsperteam[g_ScenarioData.ctc.teamindexes[index]].numspawnpads);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
s32 ctcGetMaxTeams(void)
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
|
||||
bool ctcIsRoomHighlighted(s16 room)
|
||||
{
|
||||
s32 i;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (g_ScenarioData.ctc.baserooms[i] == room && g_ScenarioData.ctc.teamindexes[i] != -1) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void ctcHighlightRoom(s16 roomnum, s32 *arg1, s32 *arg2, s32 *arg3)
|
||||
{
|
||||
s32 i;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (g_ScenarioData.ctc.baserooms[i] == roomnum) {
|
||||
u32 colour = g_TeamColours[i];
|
||||
f32 a = *arg1;
|
||||
f32 b = *arg2;
|
||||
f32 c = *arg3;
|
||||
|
||||
a *= (s32)((colour >> 24 & 0xff) + 0xff) * (1.0f / 512.0f);
|
||||
b *= (s32)((colour >> 16 & 0xff) + 0xff) * (1.0f / 512.0f);
|
||||
c *= (s32)((colour >> 8 & 0xff) + 0xff) * (1.0f / 512.0f);
|
||||
|
||||
*arg1 = a;
|
||||
*arg2 = b;
|
||||
*arg3 = c;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
/**
|
||||
* Combat
|
||||
*
|
||||
* This is a general combat scenario.
|
||||
*
|
||||
* There are no callback functions or special logic.
|
||||
*/
|
||||
|
||||
struct menuitem g_MpCombatOptionsMenuItems[] = {
|
||||
{ MENUITEMTYPE_CHECKBOX, 0, 0x00020000, L_MPMENU_222, MPOPTION_ONEHITKILLS, menuhandlerMpOneHitKills }, // "One-Hit Kills"
|
||||
{ MENUITEMTYPE_DROPDOWN, 0, 0x00020000, L_MPMENU_223, 0x00000000, menuhandlerMpSlowMotion }, // "Slow Motion"
|
||||
{ MENUITEMTYPE_CHECKBOX, 0, 0x00020000, L_MPMENU_224, MPOPTION_FASTMOVEMENT, menuhandlerMpCheckboxOption }, // "Fast Movement"
|
||||
{ MENUITEMTYPE_CHECKBOX, 0, 0x00020000, L_MPMENU_225, MPOPTION_DISPLAYTEAM, menuhandlerMpDisplayTeam }, // "Display Team"
|
||||
{ MENUITEMTYPE_CHECKBOX, 0, 0x00020000, L_MPMENU_226, MPOPTION_NORADAR, menuhandlerMpCheckboxOption }, // "No Radar"
|
||||
{ MENUITEMTYPE_CHECKBOX, 0, 0x00020000, L_MPMENU_227, MPOPTION_NOAUTOAIM, menuhandlerMpCheckboxOption }, // "No Auto-Aim"
|
||||
{ MENUITEMTYPE_SEPARATOR, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
|
||||
{ MENUITEMTYPE_CHECKBOX, 0, 0x00020000, L_MPMENU_228, MPOPTION_NOPLAYERHIGHLIGHT, menuhandlerMpCheckboxOption }, // "No Player Highlight"
|
||||
{ MENUITEMTYPE_CHECKBOX, 0, 0x00020000, L_MPMENU_229, MPOPTION_NOPICKUPHIGHLIGHT, menuhandlerMpCheckboxOption }, // "No Pickup Highlight"
|
||||
{ MENUITEMTYPE_SEPARATOR, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
|
||||
{ MENUITEMTYPE_SELECTABLE, 0, 0x00000008, L_MPMENU_239, 0x00000000, NULL }, // "Back"
|
||||
{ MENUITEMTYPE_END, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
|
||||
};
|
||||
|
||||
struct menudialog g_MpCombatOptionsMenuDialog = {
|
||||
MENUDIALOGTYPE_DEFAULT,
|
||||
L_MPMENU_215, // "Combat Options"
|
||||
g_MpCombatOptionsMenuItems,
|
||||
mpOptionsMenuDialog,
|
||||
0x00000010,
|
||||
NULL,
|
||||
};
|
||||
|
|
@ -0,0 +1,690 @@
|
|||
/**
|
||||
* Hack that Mac (also known as Hacker Central)
|
||||
*
|
||||
* A data uplink and a terminal are spawned into a random location in the arena.
|
||||
* Players must pick up the data uplink then go to the terminal and download
|
||||
* data from it to score points. Each download takes 20 seconds and the player
|
||||
* cannot use weapons while uplinking.
|
||||
*/
|
||||
|
||||
#define HTM_NUM_TERMINALS 1
|
||||
|
||||
struct menuitem g_HtmOptionsMenuItems[] = {
|
||||
{ MENUITEMTYPE_CHECKBOX, 0, 0x00020000, L_MPMENU_222, MPOPTION_ONEHITKILLS, menuhandlerMpOneHitKills }, // "One-Hit Kills"
|
||||
{ MENUITEMTYPE_DROPDOWN, 0, 0x00020000, L_MPMENU_223, 0x00000000, menuhandlerMpSlowMotion }, // "Slow Motion"
|
||||
{ MENUITEMTYPE_CHECKBOX, 0, 0x00020000, L_MPMENU_224, MPOPTION_FASTMOVEMENT, menuhandlerMpCheckboxOption }, // "Fast Movement"
|
||||
{ MENUITEMTYPE_CHECKBOX, 0, 0x00020000, L_MPMENU_225, MPOPTION_DISPLAYTEAM, menuhandlerMpDisplayTeam }, // "Display Team"
|
||||
{ MENUITEMTYPE_CHECKBOX, 0, 0x00020000, L_MPMENU_226, MPOPTION_NORADAR, menuhandlerMpCheckboxOption }, // "No Radar"
|
||||
{ MENUITEMTYPE_CHECKBOX, 0, 0x00020000, L_MPMENU_227, MPOPTION_NOAUTOAIM, menuhandlerMpCheckboxOption }, // "No Auto-Aim"
|
||||
{ MENUITEMTYPE_CHECKBOX, 0, 0x00020000, L_OPTIONS_493, MPOPTION_KILLSSCORE, menuhandlerMpCheckboxOption }, // "Kills Score"
|
||||
{ MENUITEMTYPE_SEPARATOR, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
|
||||
{ MENUITEMTYPE_CHECKBOX, 0, 0x00020000, L_MPMENU_231, MPOPTION_HTM_HIGHLIGHTTERMINAL, menuhandlerMpCheckboxOption }, // "Highlight Terminal"
|
||||
{ MENUITEMTYPE_CHECKBOX, 0, 0x00020000, L_MPMENU_238, MPOPTION_HTM_SHOWONRADAR, menuhandlerMpCheckboxOption }, // "Show on Radar"
|
||||
{ MENUITEMTYPE_SEPARATOR, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
|
||||
{ MENUITEMTYPE_SELECTABLE, 0, 0x00000008, L_MPMENU_239, 0x00000000, NULL }, // "Back"
|
||||
{ MENUITEMTYPE_END, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
|
||||
};
|
||||
|
||||
struct menudialog g_HtmOptionsMenuDialog = {
|
||||
MENUDIALOGTYPE_DEFAULT,
|
||||
L_MPMENU_217, // "Hacker Options"
|
||||
g_HtmOptionsMenuItems,
|
||||
mpOptionsMenuDialog,
|
||||
0x00000010,
|
||||
NULL,
|
||||
};
|
||||
|
||||
struct weaponobj g_HtmUplinkObj;
|
||||
|
||||
void htmInit(void)
|
||||
{
|
||||
g_ScenarioData.htm.uplink = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add one for the data uplink.
|
||||
*/
|
||||
s32 htmNumProps(void)
|
||||
{
|
||||
return HTM_NUM_TERMINALS + 1;
|
||||
}
|
||||
|
||||
void htmAddPad(s16 padnum)
|
||||
{
|
||||
struct scenariodata_htm *data = &g_ScenarioData.htm;
|
||||
|
||||
#if VERSION >= VERSION_NTSC_1_0
|
||||
if (data->numpads < ARRAYCOUNT(g_ScenarioData.htm.padnums))
|
||||
#endif
|
||||
{
|
||||
osSyncPrintf("HackThatMacAddBankPad -> Adding New Pad %d - Pad Id = %d-> Saving Pad\n", data->numpads, padnum);
|
||||
|
||||
data->padnums[data->numpads] = padnum;
|
||||
data->numpads++;
|
||||
}
|
||||
}
|
||||
|
||||
void htmReset(void)
|
||||
{
|
||||
s32 i;
|
||||
|
||||
osSyncPrintf("HackThatMacReset -> Working\n");
|
||||
|
||||
g_ScenarioData.htm.numpads = 0;
|
||||
g_ScenarioData.htm.numterminals = 0;
|
||||
g_ScenarioData.htm.unk138 = 0;
|
||||
g_ScenarioData.htm.dlplayernum = -1;
|
||||
g_ScenarioData.htm.playernuminrange = -1;
|
||||
g_ScenarioData.htm.dlterminalnum = -1;
|
||||
g_ScenarioData.htm.unk140 = 0;
|
||||
|
||||
for (i = 0; i < ARRAYCOUNT(g_ScenarioData.htm.numpoints); i++) {
|
||||
g_ScenarioData.htm.numpoints[i] = 0;
|
||||
g_ScenarioData.htm.dltime240[i] = 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAYCOUNT(g_ScenarioData.htm.padnums); i++) {
|
||||
g_ScenarioData.htm.padnums[i] = -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < HTM_NUM_TERMINALS; i++) {
|
||||
g_ScenarioData.htm.terminals[i].unk00 = 0;
|
||||
g_ScenarioData.htm.terminals[i].prop = NULL;
|
||||
g_ScenarioData.htm.terminals[i].padnum = -1;
|
||||
g_ScenarioData.htm.terminals[i].team = 255;
|
||||
g_ScenarioData.htm.terminals[i].unk0b = 255;
|
||||
}
|
||||
}
|
||||
|
||||
void htbCreateUplink(void)
|
||||
{
|
||||
struct weaponobj template = {
|
||||
512, // extrascale
|
||||
0, // hidden2
|
||||
OBJTYPE_WEAPON, // type
|
||||
MODEL_CHRDATATHIEF, // modelnum
|
||||
0, // pad
|
||||
OBJFLAG_00000001 | OBJFLAG_INVINCIBLE | OBJFLAG_00400000,
|
||||
OBJFLAG2_IMMUNETOGUNFIRE | OBJFLAG2_00200000,
|
||||
0, // flags3
|
||||
NULL, // prop
|
||||
NULL, // model
|
||||
1, 0, 0, // realrot
|
||||
0, 1, 0,
|
||||
0, 0, 1,
|
||||
0, // hidden
|
||||
NULL, // geo
|
||||
NULL, // projectile
|
||||
0, // damage
|
||||
1000, // maxdamage
|
||||
0xff, 0xff, 0xff, 0x00, // shadecol
|
||||
0xff, 0xff, 0xff, 0x00, // nextcol
|
||||
0x0fff, // floorcol
|
||||
0, // tiles
|
||||
WEAPON_DATAUPLINK, // weaponnum
|
||||
0, // unk5d
|
||||
0, // unk5e
|
||||
FUNC_PRIMARY, // gunfunc
|
||||
0, // fadeouttimer60
|
||||
-1, // dualweaponnum
|
||||
-1, // timer240
|
||||
NULL, // dualweapon
|
||||
};
|
||||
|
||||
struct prop *prop = g_Vars.activeprops;
|
||||
struct defaultobj *obj;
|
||||
s32 padnum;
|
||||
s32 count = 0;
|
||||
struct defaultobj *candidates[20];
|
||||
|
||||
while (prop && count < 20) {
|
||||
#if VERSION >= VERSION_NTSC_1_0
|
||||
if (prop->type == PROPTYPE_OBJ)
|
||||
#endif
|
||||
{
|
||||
obj = prop->obj;
|
||||
|
||||
if (obj->type == OBJTYPE_MULTIAMMOCRATE) {
|
||||
candidates[count] = obj;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
prop = prop->next;
|
||||
}
|
||||
|
||||
if (count > 0) {
|
||||
count = random() % count;
|
||||
var800869ec = candidates[count];
|
||||
var800869ec->hidden |= OBJHFLAG_REAPABLE;
|
||||
var800869ec->hidden2 |= OBJH2FLAG_CANREGEN;
|
||||
padnum = var800869ec->pad;
|
||||
} else if (g_ScenarioData.htm.numpads > 0) {
|
||||
padnum = g_ScenarioData.htm.padnums[random() % g_ScenarioData.htm.numpads];
|
||||
} else {
|
||||
padnum = 0;
|
||||
}
|
||||
|
||||
g_HtmUplinkObj = template;
|
||||
g_HtmUplinkObj.base.pad = padnum;
|
||||
|
||||
weaponAssignToHome(&g_HtmUplinkObj, 999);
|
||||
|
||||
g_HtmUplinkObj.base.hidden2 &= ~OBJH2FLAG_CANREGEN;
|
||||
|
||||
g_ScenarioData.htm.uplink = g_HtmUplinkObj.base.prop;
|
||||
|
||||
if (g_ScenarioData.htm.uplink) {
|
||||
g_ScenarioData.htm.uplink->forcetick = true;
|
||||
}
|
||||
}
|
||||
|
||||
void htmInitProps(void)
|
||||
{
|
||||
struct scenariodata_htm *data = &g_ScenarioData.htm;
|
||||
struct prop *prop = g_Vars.activeprops;
|
||||
s32 i = 0;
|
||||
s32 rand;
|
||||
|
||||
osSyncPrintf("HackThatMacInitProps -> Start : %d Bank Pads\n", data->numterminals);
|
||||
|
||||
while (prop) {
|
||||
if (prop->type == PROPTYPE_OBJ) {
|
||||
struct defaultobj *obj = prop->obj;
|
||||
|
||||
if (obj->type == OBJTYPE_AMMOCRATE || obj->type == OBJTYPE_MULTIAMMOCRATE) {
|
||||
if (obj->modelnum == MODEL_MULTI_AMMO_CRATE) {
|
||||
osSyncPrintf("HackThatMacInitProps -> Adding prop %d (%x)\n", i, obj->pad);
|
||||
htmAddPad(obj->pad);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
prop = prop->next;
|
||||
i++;
|
||||
}
|
||||
|
||||
osSyncPrintf("HackThatMacInitProps -> Mid : %d Bank Pads\n", data->numpads);
|
||||
osSyncPrintf("HackThatMacInitProps -> Generating %d random box pads from %d in the bank\n", htmNumProps(), data->numpads);
|
||||
|
||||
data->numterminals = 0;
|
||||
|
||||
// @bug: This should be < htmNumProps() - 1 to account for the data uplink,
|
||||
// or just < HTM_NUM_TERMINALS. If HTM_NUM_TERMINALS is set to 7 then it
|
||||
// will overflow the array.
|
||||
while (data->numterminals < htmNumProps()) {
|
||||
s32 padnum;
|
||||
|
||||
do {
|
||||
rand = random() % data->numpads;
|
||||
padnum = data->padnums[rand];
|
||||
} while (padnum <= 0);
|
||||
|
||||
data->terminals[data->numterminals].padnum = padnum;
|
||||
data->numterminals++;
|
||||
data->padnums[rand] = -1;
|
||||
}
|
||||
|
||||
osSyncPrintf("HackThatMacInitProps -> %d/%d Random box pads generated - Listing\n", data->numterminals, htmNumProps());
|
||||
|
||||
for (i = 0; i < data->numterminals; i++) {
|
||||
osSyncPrintf("Pad %d -> Pad Id = %d\n", i, data->terminals[i].padnum);
|
||||
}
|
||||
|
||||
for (i = 0; i < HTM_NUM_TERMINALS; i++) {
|
||||
data->terminals[i].prop = scenarioCreateObj(MODEL_GOODPC, data->terminals[i].padnum, 0.2f,
|
||||
OBJFLAG_00000001 | OBJFLAG_INVINCIBLE | OBJFLAG_00400000,
|
||||
OBJFLAG2_IMMUNETOGUNFIRE | OBJFLAG2_00200000,
|
||||
OBJFLAG3_HTMTERMINAL | OBJFLAG3_INTERACTABLE);
|
||||
osSyncPrintf("HackThatMacInitProps -> Building and adding custom prop %d - Pad=%d, Ptr=%08x\n",
|
||||
i, data->terminals[i].padnum, data->terminals[i].prop);
|
||||
htbRemoveAmmoCrateAtPad(data->terminals[i].padnum);
|
||||
}
|
||||
|
||||
var800869ec = NULL;
|
||||
|
||||
htbCreateUplink();
|
||||
|
||||
osSyncPrintf("HackThatMacInitProps -> End\n");
|
||||
}
|
||||
|
||||
void htmTick(void)
|
||||
{
|
||||
u8 stack[8];
|
||||
s32 i;
|
||||
u32 prevplayernum = g_Vars.currentplayernum;
|
||||
struct prop *prop;
|
||||
|
||||
if (var800869ec && var800869ec->prop) {
|
||||
if (g_ScenarioData.htm.uplink == NULL || g_ScenarioData.htm.uplink->type != PROPTYPE_WEAPON) {
|
||||
var800869ec = NULL;
|
||||
} else {
|
||||
var800869ec->prop->timetoregen = PALDOWN(1200);
|
||||
}
|
||||
}
|
||||
|
||||
g_ScenarioData.htm.uplink = NULL;
|
||||
|
||||
// Check if uplink is on the ground
|
||||
prop = g_Vars.activeprops;
|
||||
|
||||
while (prop) {
|
||||
if (prop->type == PROPTYPE_WEAPON) {
|
||||
struct weaponobj *weapon = prop->weapon;
|
||||
|
||||
if (weapon->weaponnum == WEAPON_DATAUPLINK) {
|
||||
g_ScenarioData.htm.uplink = prop;
|
||||
}
|
||||
}
|
||||
|
||||
prop = prop->next;
|
||||
}
|
||||
|
||||
// Check if a player is holding it
|
||||
if (g_ScenarioData.htm.uplink == NULL) {
|
||||
for (i = 0; i < PLAYERCOUNT(); i++) {
|
||||
setCurrentPlayerNum(i);
|
||||
|
||||
if (invHasDataUplink()) {
|
||||
g_ScenarioData.htm.uplink = g_Vars.currentplayer->prop;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setCurrentPlayerNum(prevplayernum);
|
||||
|
||||
// Check if a simulant is holding it
|
||||
if (g_ScenarioData.htm.uplink == NULL) {
|
||||
for (i = PLAYERCOUNT(); i < g_MpNumChrs; i++) {
|
||||
if (g_MpAllChrPtrs[i]->aibot->hasuplink) {
|
||||
g_ScenarioData.htm.uplink = g_MpAllChrPtrs[i]->prop;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (g_ScenarioData.htm.uplink == NULL) {
|
||||
htbCreateUplink();
|
||||
}
|
||||
}
|
||||
|
||||
void htmTickChr(struct chrdata *chr)
|
||||
{
|
||||
struct scenariodata_htm *data = &g_ScenarioData.htm;
|
||||
bool hasuplink;
|
||||
s32 playernum;
|
||||
s32 i;
|
||||
s32 *time;
|
||||
|
||||
if (chr) {
|
||||
hasuplink = chr->aibot->hasuplink;
|
||||
playernum = mpPlayerGetIndex(chr);
|
||||
} else {
|
||||
hasuplink = invHasDataUplink() && bgunGetWeaponNum(HAND_RIGHT) == WEAPON_DATAUPLINK;
|
||||
playernum = g_Vars.currentplayernum;
|
||||
}
|
||||
|
||||
time = &data->dltime240[playernum];
|
||||
|
||||
for (i = 0; i < HTM_NUM_TERMINALS; i++) {
|
||||
if (data->terminals[i].prop) {
|
||||
struct prop *prop = data->terminals[i].prop;
|
||||
struct defaultobj *obj = prop->obj;
|
||||
s32 activatedbyplayernum = -1;
|
||||
|
||||
if (chr) {
|
||||
if (hasuplink) {
|
||||
activatedbyplayernum = playernum;
|
||||
}
|
||||
} else {
|
||||
if (obj->hidden & OBJHFLAG_ACTIVATED_BY_BOND) {
|
||||
activatedbyplayernum = (obj->hidden & 0xf0000000) >> 28;
|
||||
}
|
||||
}
|
||||
|
||||
if (playernum == activatedbyplayernum) {
|
||||
obj->hidden &= ~OBJHFLAG_ACTIVATED_BY_BOND;
|
||||
obj->hidden &= ~0xf0000000;
|
||||
|
||||
if (hasuplink) {
|
||||
if (data->dlterminalnum == -1) {
|
||||
data->dlterminalnum = i;
|
||||
data->dlplayernum = playernum;
|
||||
data->playernuminrange = playernum;
|
||||
*time = 0;
|
||||
|
||||
if (chr == NULL) {
|
||||
hudmsgCreateWithFlags(langGet(L_MPWEAPONS_018), HUDMSGTYPE_MPSCENARIO, HUDMSGFLAG_ONLYIFALIVE); // "Starting download."
|
||||
func0f0939f8(NULL, data->terminals[data->dlterminalnum].prop, SFX_01BF, -1,
|
||||
-1, 2, 2, 0, NULL, -1, NULL, -1, -1, -1, -1);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (chr == NULL) {
|
||||
hudmsgCreateWithFlags(langGet(L_MPWEAPONS_019), HUDMSGTYPE_MPSCENARIO, HUDMSGFLAG_ONLYIFALIVE); // "You need to use the Data Uplink."
|
||||
snd00010718(NULL, 0, 0x7fff, 0x40, SFX_01CC, 1, 1, -1, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (playernum == data->dlplayernum && data->dlterminalnum != -1) {
|
||||
struct coord *terminalpos = &data->terminals[data->dlterminalnum].prop->pos;
|
||||
f32 angle;
|
||||
f32 relangle;
|
||||
f32 rangexz;
|
||||
f32 rangey;
|
||||
struct coord *chrpos;
|
||||
struct coord dist;
|
||||
bool holdinguplink;
|
||||
|
||||
if (chr) {
|
||||
chrpos = &chr->prop->pos;
|
||||
angle = (M_BADTAU - chrGetInverseTheta(chr)) * 57.295776367188f;
|
||||
holdinguplink = chr->aibot->weaponnum == WEAPON_UNARMED;
|
||||
} else {
|
||||
chrpos = &g_Vars.currentplayer->prop->pos;
|
||||
angle = g_Vars.currentplayer->vv_theta;
|
||||
holdinguplink = bgunGetWeaponNum(HAND_RIGHT) == WEAPON_DATAUPLINK;
|
||||
}
|
||||
|
||||
dist.x = terminalpos->x - chrpos->x;
|
||||
dist.y = terminalpos->y - chrpos->y;
|
||||
dist.z = terminalpos->z - chrpos->z;
|
||||
|
||||
rangexz = sqrtf(dist.x * dist.x + dist.z * dist.z);
|
||||
|
||||
rangey = ABS(dist.y);
|
||||
|
||||
relangle = atan2f(dist.x, dist.z) * 57.295776367188f + angle;
|
||||
|
||||
while (relangle < 180) {
|
||||
relangle += 360;
|
||||
}
|
||||
|
||||
while (relangle > 180) {
|
||||
relangle -= 360;
|
||||
}
|
||||
|
||||
if (relangle > 0) {
|
||||
// empty
|
||||
} else {
|
||||
relangle = -relangle;
|
||||
}
|
||||
|
||||
osSyncPrintf("HTM : Player %d - Term Pos = (%d,%d,%d)", playernum, (s32)terminalpos->x, (s32)terminalpos->y, (s32)terminalpos->z);
|
||||
osSyncPrintf("HTM : Player %d - Play Pos = (%d,%d,%d)", playernum, (s32)chrpos->x, (s32)chrpos->y, (s32)chrpos->z);
|
||||
osSyncPrintf("HTM : Player %d - T/P Rel = (%d,%d,%d)", playernum, (s32)dist.x, (s32)dist.y, (s32)dist.z);
|
||||
|
||||
osSyncPrintf("HTM : Player %d - Range XZ = %d", playernum, rangexz);
|
||||
osSyncPrintf("HTM : Player %d - Range Y = %d", playernum, rangey);
|
||||
osSyncPrintf("HTM : Player %d - Angle XZ = %d", playernum, relangle);
|
||||
|
||||
if (rangexz > 250 || rangey > 200 || relangle > 45 || !holdinguplink) {
|
||||
if (rangexz < 250 && rangey < 200) {
|
||||
data->playernuminrange = playernum;
|
||||
} else {
|
||||
data->playernuminrange = -1;
|
||||
}
|
||||
|
||||
if (chr == NULL) {
|
||||
// "Connection broken."
|
||||
hudmsgCreateWithFlags(langGet(L_MPWEAPONS_017), HUDMSGTYPE_MPSCENARIO, HUDMSGFLAG_ONLYIFALIVE);
|
||||
func0f0926bc(data->terminals[data->dlterminalnum].prop, 1, 0xffff);
|
||||
snd00010718(NULL, 0, 0x7fff, 0x40, SFX_01CC, 1, 1, -1, 1);
|
||||
}
|
||||
|
||||
data->dlterminalnum = -1;
|
||||
data->dlplayernum = -1;
|
||||
*time = 0;
|
||||
} else {
|
||||
*time += g_Vars.lvupdate240;
|
||||
|
||||
if (*time > 20 * PALDOWN(240)) {
|
||||
data->numpoints[playernum]++;
|
||||
data->playernuminrange = playernum;
|
||||
|
||||
if (chr == NULL) {
|
||||
// "Download successful."
|
||||
hudmsgCreateWithFlags(langGet(L_MPWEAPONS_016), HUDMSGTYPE_MPSCENARIO, HUDMSGFLAG_ONLYIFALIVE);
|
||||
func0f0926bc(data->terminals[data->dlterminalnum].prop, 1, 0xffff);
|
||||
snd00010718(NULL, 0, 0x7fff, 0x40, SFX_01C1, 1, 1, -1, 1);
|
||||
}
|
||||
|
||||
data->dlterminalnum = -1;
|
||||
data->dlplayernum = -1;
|
||||
*time = 0;
|
||||
}
|
||||
}
|
||||
|
||||
osSyncPrintf("HTM : Player %d - Dwnld Plr=%d, Dwnld Prop=%d\n", playernum, data->playernuminrange, data->terminals[data->dlterminalnum].prop);
|
||||
osSyncPrintf("HTM : Player %d - Download Time = %d", playernum, *time);
|
||||
}
|
||||
}
|
||||
|
||||
Gfx *htmRenderHud(Gfx *gdl)
|
||||
{
|
||||
struct scenariodata_htm *data = &g_ScenarioData.htm;
|
||||
s32 dltime;
|
||||
s32 viewleft;
|
||||
s32 viewright;
|
||||
s32 viewtop;
|
||||
s32 a0;
|
||||
s32 a1;
|
||||
s32 barleft;
|
||||
s32 barright;
|
||||
s32 t1;
|
||||
s32 t6;
|
||||
s32 v1;
|
||||
s32 s1;
|
||||
|
||||
dltime = data->dltime240[g_Vars.currentplayernum];
|
||||
|
||||
if (data->dlterminalnum != -1 && g_Vars.currentplayernum == data->dlplayernum) {
|
||||
viewleft = viGetViewLeft();
|
||||
viewright = viGetViewLeft() + viGetViewWidth();
|
||||
viewtop = viGetViewTop();
|
||||
t6 = (viewleft + viewright) / 2;
|
||||
a1 = viGetViewWidth() / 3;
|
||||
barleft = t6 - a1 / 2;
|
||||
barright = t6 + a1 / 2;
|
||||
s1 = barleft + (s32) (a1 * (dltime / PALDOWN(4800.0f)));
|
||||
|
||||
gdl = func0f153628(gdl);
|
||||
gdl = gfxSetPrimColour(gdl, 0x60000060);
|
||||
|
||||
gDPFillRectangle(gdl++, barleft, viewtop + 8, barright, viewtop + 16);
|
||||
|
||||
gdl = func0f153838(gdl);
|
||||
gdl = gfxSetPrimColour(gdl, 0xc00000d0);
|
||||
|
||||
v1 = barleft + 1;
|
||||
a0 = barleft;
|
||||
|
||||
while (v1 < s1) {
|
||||
gDPFillRectangle(gdl++, a0, viewtop + 8, v1, viewtop + 16);
|
||||
v1 += 2;
|
||||
a0 += 2;
|
||||
}
|
||||
|
||||
gdl = func0f153838(gdl);
|
||||
gdl = func0f153780(gdl);
|
||||
}
|
||||
|
||||
return gdl;
|
||||
}
|
||||
|
||||
void htmCalculatePlayerScore(struct mpchrconfig *mpchr, s32 mpchrnum, s32 *score, s32 *deaths)
|
||||
{
|
||||
struct mpchrconfig *loopmpchr;
|
||||
s32 i;
|
||||
s32 index;
|
||||
|
||||
*score = 0;
|
||||
index = func0f18d0e8(mpchrnum);
|
||||
|
||||
if (index >= 0) {
|
||||
*score += g_ScenarioData.htm.numpoints[index] * 2;
|
||||
}
|
||||
|
||||
if (g_MpSetup.options & MPOPTION_KILLSSCORE) {
|
||||
for (i = 0; i != MAX_MPCHRS; i++) {
|
||||
if (i == mpchrnum) {
|
||||
*score -= mpchr->killcounts[i];
|
||||
} else if (g_MpSetup.options & MPOPTION_TEAMSENABLED) {
|
||||
loopmpchr = MPCHR(i);
|
||||
|
||||
if (loopmpchr->team == mpchr->team) {
|
||||
*score -= mpchr->killcounts[i];
|
||||
} else {
|
||||
*score += mpchr->killcounts[i];
|
||||
}
|
||||
} else {
|
||||
*score += mpchr->killcounts[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*deaths = mpchr->numdeaths;
|
||||
}
|
||||
|
||||
Gfx *htmRadarExtra(Gfx *gdl)
|
||||
{
|
||||
struct scenariodata_htm *data = &g_ScenarioData.htm;
|
||||
struct coord dist;
|
||||
s32 i;
|
||||
struct coord sp88;
|
||||
|
||||
// Red/green/blue/alpha as float and integer
|
||||
f32 rf;
|
||||
f32 gf;
|
||||
f32 bf;
|
||||
f32 af;
|
||||
|
||||
u32 ri;
|
||||
u32 gi;
|
||||
u32 bi;
|
||||
u32 ai;
|
||||
|
||||
if (g_MpSetup.options & MPOPTION_HTM_SHOWONRADAR) {
|
||||
// Show the uplink
|
||||
if (data->uplink && data->uplink->type != PROPTYPE_PLAYER && data->uplink->type != PROPTYPE_CHR) {
|
||||
dist.x = data->uplink->pos.x - g_Vars.currentplayer->prop->pos.x;
|
||||
dist.y = data->uplink->pos.y - g_Vars.currentplayer->prop->pos.y;
|
||||
dist.z = data->uplink->pos.z - g_Vars.currentplayer->prop->pos.z;
|
||||
|
||||
gdl = radarDrawDot(gdl, data->uplink, &dist, 0x00ff0000, 0x00000000, true);
|
||||
}
|
||||
|
||||
// Show the terminal
|
||||
for (i = 0; i < HTM_NUM_TERMINALS; i++) {
|
||||
if (data->terminals[i].prop) {
|
||||
sp88.x = data->terminals[i].prop->pos.x - g_Vars.currentplayer->prop->pos.x;
|
||||
sp88.y = data->terminals[i].prop->pos.y - g_Vars.currentplayer->prop->pos.y;
|
||||
sp88.z = data->terminals[i].prop->pos.z - g_Vars.currentplayer->prop->pos.z;
|
||||
|
||||
if (data->terminals[i].team == 255) {
|
||||
rf = 0;
|
||||
gf = 255;
|
||||
bf = 0;
|
||||
af = 0;
|
||||
} else if (g_MpSetup.options & MPOPTION_TEAMSENABLED) {
|
||||
u32 colour = g_TeamColours[radarGetTeamIndex(data->terminals[i].team)];
|
||||
rf = (colour >> 24) & 0xff;
|
||||
gf = ((colour >> 16) & 0xff);
|
||||
bf = ((colour >> 8) & 0xff);
|
||||
af = colour & 0xff;
|
||||
} else {
|
||||
rf = 0;
|
||||
gf = 255;
|
||||
bf = 0;
|
||||
af = 0;
|
||||
}
|
||||
|
||||
ri = rf;
|
||||
gi = gf;
|
||||
bi = bf;
|
||||
ai = af;
|
||||
|
||||
if (ri > 255) {
|
||||
ri = 255;
|
||||
}
|
||||
|
||||
if (gi > 255) {
|
||||
gi = 255;
|
||||
}
|
||||
|
||||
if (bi > 255) {
|
||||
bi = 255;
|
||||
}
|
||||
|
||||
if (ai > 255) {
|
||||
ai = 255;
|
||||
}
|
||||
|
||||
gdl = radarDrawDot(gdl, data->terminals[i].prop, &sp88,
|
||||
(ri << 24) | (gi << 16) | (bi << 8) | ai,
|
||||
0x00000000, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return gdl;
|
||||
}
|
||||
|
||||
bool htmRadarChr(Gfx **gdl, struct prop *prop)
|
||||
{
|
||||
if ((g_MpSetup.options & MPOPTION_HTM_SHOWONRADAR) && g_ScenarioData.htm.uplink) {
|
||||
if (prop == g_ScenarioData.htm.uplink &&
|
||||
(prop->type == PROPTYPE_PLAYER || prop->type == PROPTYPE_CHR)) {
|
||||
struct coord dist;
|
||||
dist.x = prop->pos.x - g_Vars.currentplayer->prop->pos.x;
|
||||
dist.y = prop->pos.y - g_Vars.currentplayer->prop->pos.y;
|
||||
dist.z = prop->pos.z - g_Vars.currentplayer->prop->pos.z;
|
||||
|
||||
if (g_MpSetup.options & MPOPTION_TEAMSENABLED) {
|
||||
u32 colour = g_TeamColours[radarGetTeamIndex(prop->chr->team)];
|
||||
*gdl = radarDrawDot(*gdl, g_ScenarioData.htm.uplink, &dist, colour, 0, 1);
|
||||
} else {
|
||||
*gdl = radarDrawDot(*gdl, g_ScenarioData.htm.uplink, &dist, 0x00ff0000, 0, 1);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool htmHighlightProp(struct prop *prop, s32 *colour)
|
||||
{
|
||||
if (g_MpSetup.options & MPOPTION_HTM_HIGHLIGHTTERMINAL) {
|
||||
bool highlight = false;
|
||||
|
||||
if (prop == g_ScenarioData.htm.uplink) {
|
||||
highlight = true;
|
||||
} else {
|
||||
s32 i;
|
||||
|
||||
for (i = 0; i < HTM_NUM_TERMINALS; i++) {
|
||||
if (g_ScenarioData.htm.terminals[i].prop == prop) {
|
||||
highlight = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (highlight) {
|
||||
colour[0] = 0;
|
||||
colour[1] = 0xff;
|
||||
colour[2] = 0;
|
||||
colour[3] = 0x40;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
@ -0,0 +1,434 @@
|
|||
/**
|
||||
* Hold the Briefcase
|
||||
*
|
||||
* A briefcase is spawned into a random location in the arena. Players must pick
|
||||
* up the briefcase and then stay alive for as long as possible. The player
|
||||
* scores a point every 30 seconds while the briefcase is held.
|
||||
*
|
||||
* While holding the briefcase, the player cannot pick up shields. The move
|
||||
* slightly slower but still have full access to their weaponry.
|
||||
*/
|
||||
|
||||
struct menuitem g_HtbOptionsMenuItems[] = {
|
||||
{ MENUITEMTYPE_CHECKBOX, 0, 0x00020000, L_MPMENU_222, MPOPTION_ONEHITKILLS, menuhandlerMpOneHitKills }, // "One-Hit Kills"
|
||||
{ MENUITEMTYPE_DROPDOWN, 0, 0x00020000, L_MPMENU_223, 0x00000000, menuhandlerMpSlowMotion }, // "Slow Motion"
|
||||
{ MENUITEMTYPE_CHECKBOX, 0, 0x00020000, L_MPMENU_224, MPOPTION_FASTMOVEMENT, menuhandlerMpCheckboxOption }, // "Fast Movement"
|
||||
{ MENUITEMTYPE_CHECKBOX, 0, 0x00020000, L_MPMENU_225, MPOPTION_DISPLAYTEAM, menuhandlerMpDisplayTeam }, // "Display Team"
|
||||
{ MENUITEMTYPE_CHECKBOX, 0, 0x00020000, L_MPMENU_226, MPOPTION_NORADAR, menuhandlerMpCheckboxOption }, // "No Radar"
|
||||
{ MENUITEMTYPE_CHECKBOX, 0, 0x00020000, L_MPMENU_227, MPOPTION_NOAUTOAIM, menuhandlerMpCheckboxOption }, // "No Auto-Aim"
|
||||
{ MENUITEMTYPE_CHECKBOX, 0, 0x00020000, L_OPTIONS_493, MPOPTION_KILLSSCORE, menuhandlerMpCheckboxOption }, // "Kills Score"
|
||||
{ MENUITEMTYPE_SEPARATOR, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
|
||||
{ MENUITEMTYPE_CHECKBOX, 0, 0x00020000, L_MPMENU_237, MPOPTION_HTB_HIGHLIGHTBRIEFCASE, menuhandlerMpCheckboxOption }, // "Highlight Briefcase"
|
||||
{ MENUITEMTYPE_CHECKBOX, 0, 0x00020000, L_MPMENU_238, MPOPTION_HTB_SHOWONRADAR, menuhandlerMpCheckboxOption }, // "Show on Radar"
|
||||
{ MENUITEMTYPE_SEPARATOR, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
|
||||
{ MENUITEMTYPE_SELECTABLE, 0, 0x00000008, L_MPMENU_239, 0x00000000, NULL }, // "Back"
|
||||
{ MENUITEMTYPE_END, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
|
||||
};
|
||||
|
||||
struct menudialog g_HtbOptionsMenuDialog = {
|
||||
MENUDIALOGTYPE_DEFAULT,
|
||||
L_MPMENU_216, // "Briefcase Options"
|
||||
g_HtbOptionsMenuItems,
|
||||
mpOptionsMenuDialog,
|
||||
0x00000010,
|
||||
NULL,
|
||||
};
|
||||
|
||||
struct defaultobj *var800869ec = NULL;
|
||||
|
||||
struct weaponobj g_HtbTokenObj;
|
||||
|
||||
void htbInit(void)
|
||||
{
|
||||
g_ScenarioData.htb.token = NULL;
|
||||
}
|
||||
|
||||
void htbAddPad(s16 padnum)
|
||||
{
|
||||
struct scenariodata_htb *data = &g_ScenarioData.htb;
|
||||
|
||||
#if VERSION >= VERSION_NTSC_1_0
|
||||
if (data->nextindex < ARRAYCOUNT(data->padnums))
|
||||
#endif
|
||||
{
|
||||
osSyncPrintf("CaptureTheBriefcaseAddBankPad -> Adding New Pad %d - Pad Id = %d-> Saving Pad\n", data->nextindex, padnum);
|
||||
|
||||
data->padnums[data->nextindex] = padnum;
|
||||
data->nextindex++;
|
||||
}
|
||||
}
|
||||
|
||||
s32 htbNumProps(void)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
void htbRemoveAmmoCrateAtPad(s16 padnum)
|
||||
{
|
||||
struct prop *prop = g_Vars.activeprops;
|
||||
|
||||
while (prop) {
|
||||
if (prop->type == PROPTYPE_OBJ) {
|
||||
struct defaultobj *obj = prop->obj;
|
||||
|
||||
if (obj->pad == padnum
|
||||
&& (obj->type == OBJTYPE_AMMOCRATE || obj->type == OBJTYPE_MULTIAMMOCRATE)
|
||||
&& obj->modelnum == MODEL_MULTI_AMMO_CRATE) {
|
||||
obj->hidden |= OBJHFLAG_REAPABLE;
|
||||
obj->hidden2 &= ~OBJH2FLAG_CANREGEN;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
prop = prop->next;
|
||||
}
|
||||
}
|
||||
|
||||
void htbReset(void)
|
||||
{
|
||||
s32 i;
|
||||
|
||||
g_ScenarioData.htb.nextindex = 0;
|
||||
|
||||
for (i = 0; i < ARRAYCOUNT(g_ScenarioData.htb.padnums); i++) {
|
||||
g_ScenarioData.htb.padnums[i] = -1;
|
||||
}
|
||||
}
|
||||
|
||||
void htbCreateToken(void)
|
||||
{
|
||||
struct weaponobj template = {
|
||||
256, // extrascale
|
||||
0, // hidden2
|
||||
OBJTYPE_WEAPON, // type
|
||||
MODEL_CHRBRIEFCASE, // modelnum
|
||||
0, // pad
|
||||
OBJFLAG_00000001 | OBJFLAG_INVINCIBLE | OBJFLAG_00400000,
|
||||
OBJFLAG2_IMMUNETOGUNFIRE | OBJFLAG2_00200000,
|
||||
0, // flags3
|
||||
NULL, // prop
|
||||
NULL, // model
|
||||
1, 0, 0, // realrot
|
||||
0, 1, 0,
|
||||
0, 0, 1,
|
||||
0, // hidden
|
||||
NULL, // geo
|
||||
NULL, // projectile
|
||||
0, // damage
|
||||
1000, // maxdamage
|
||||
0xff, 0xff, 0xff, 0x00, // shadecol
|
||||
0xff, 0xff, 0xff, 0x00, // nextcol
|
||||
0x0fff, // floorcol
|
||||
0, // tiles
|
||||
WEAPON_BRIEFCASE2, // weaponnum
|
||||
0, // unk5d
|
||||
0, // unk5e
|
||||
FUNC_PRIMARY, // gunfunc
|
||||
0, // fadeouttimer60
|
||||
-1, // dualweaponnum
|
||||
-1, // timer240
|
||||
NULL, // dualweapon
|
||||
};
|
||||
|
||||
struct prop *prop = g_Vars.activeprops;
|
||||
struct defaultobj *obj;
|
||||
s32 count = 0;
|
||||
struct defaultobj *candidates[20];
|
||||
|
||||
// Build a list of candidate objects to replace. Consider only ammocrates.
|
||||
// NTSC beta doesn't check the prop type, so it could potentially replace a
|
||||
// player, bot, explosion or smoke.
|
||||
while (prop && count < 20) {
|
||||
#if VERSION >= VERSION_NTSC_1_0
|
||||
if (prop->type == PROPTYPE_OBJ)
|
||||
#endif
|
||||
{
|
||||
obj = prop->obj;
|
||||
|
||||
if (obj->type == OBJTYPE_MULTIAMMOCRATE) {
|
||||
candidates[count] = obj;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
prop = prop->next;
|
||||
}
|
||||
|
||||
// Choose the candidate and remove it
|
||||
if (count > 0) {
|
||||
count = random() % count;
|
||||
var800869ec = candidates[count];
|
||||
g_ScenarioData.htb.tokenpad = var800869ec->pad;
|
||||
var800869ec->hidden |= OBJHFLAG_REAPABLE;
|
||||
var800869ec->hidden2 |= OBJH2FLAG_CANREGEN;
|
||||
} else if (g_ScenarioData.htb.nextindex > 0) {
|
||||
g_ScenarioData.htb.tokenpad = g_ScenarioData.htb.padnums[random() % g_ScenarioData.htb.nextindex];
|
||||
} else {
|
||||
g_ScenarioData.htb.tokenpad = 0;
|
||||
}
|
||||
|
||||
// Set up the token
|
||||
g_HtbTokenObj = template;
|
||||
g_HtbTokenObj.base.pad = g_ScenarioData.htb.tokenpad;
|
||||
|
||||
weaponAssignToHome(&g_HtbTokenObj, 999);
|
||||
|
||||
g_HtbTokenObj.base.hidden2 &= ~OBJH2FLAG_CANREGEN;
|
||||
|
||||
g_ScenarioData.htb.token = g_HtbTokenObj.base.prop;
|
||||
|
||||
if (g_ScenarioData.htb.token) {
|
||||
g_ScenarioData.htb.token->forcetick = true;
|
||||
}
|
||||
}
|
||||
|
||||
void htbInitProps(void)
|
||||
{
|
||||
var800869ec = NULL;
|
||||
htbCreateToken();
|
||||
}
|
||||
|
||||
void htbTick(void)
|
||||
{
|
||||
s32 i;
|
||||
u32 prevplayernum = g_Vars.currentplayernum;
|
||||
struct prop *prop;
|
||||
|
||||
if (var800869ec && var800869ec->prop) {
|
||||
if (g_ScenarioData.htb.token == NULL || g_ScenarioData.htb.token->type != PROPTYPE_WEAPON) {
|
||||
var800869ec = NULL;
|
||||
} else {
|
||||
var800869ec->prop->timetoregen = PALDOWN(1200);
|
||||
}
|
||||
}
|
||||
|
||||
g_ScenarioData.htb.token = NULL;
|
||||
|
||||
// Check if briefcase is on the ground
|
||||
prop = g_Vars.activeprops;
|
||||
|
||||
while (prop) {
|
||||
if (prop->type == PROPTYPE_WEAPON) {
|
||||
struct weaponobj *weapon = prop->weapon;
|
||||
|
||||
if (weapon->weaponnum == WEAPON_BRIEFCASE2) {
|
||||
g_ScenarioData.htb.token = prop;
|
||||
}
|
||||
}
|
||||
|
||||
prop = prop->next;
|
||||
}
|
||||
|
||||
// Check if a player is holding it
|
||||
if (g_ScenarioData.htb.token == NULL) {
|
||||
for (i = 0; i < PLAYERCOUNT(); i++) {
|
||||
setCurrentPlayerNum(i);
|
||||
|
||||
if (invHasBriefcase()) {
|
||||
g_ScenarioData.htb.token = g_Vars.currentplayer->prop;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setCurrentPlayerNum(prevplayernum);
|
||||
|
||||
// Check if a simulant is holding it
|
||||
if (g_ScenarioData.htb.token == NULL) {
|
||||
for (i = PLAYERCOUNT(); i < g_MpNumChrs; i++) {
|
||||
#if VERSION >= VERSION_NTSC_1_0
|
||||
if (g_MpAllChrPtrs[i]->prop && g_MpAllChrPtrs[i]->aibot->hasbriefcase)
|
||||
#else
|
||||
if (g_MpAllChrPtrs[i]->aibot->hasbriefcase)
|
||||
#endif
|
||||
{
|
||||
g_ScenarioData.htb.token = g_MpAllChrPtrs[i]->prop;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (g_ScenarioData.htb.token == NULL) {
|
||||
htbCreateToken();
|
||||
}
|
||||
|
||||
if (g_ScenarioData.htb.token == NULL) {
|
||||
g_ScenarioData.htb.pos.x = 0;
|
||||
g_ScenarioData.htb.pos.y = 0;
|
||||
g_ScenarioData.htb.pos.z = 0;
|
||||
} else {
|
||||
struct coord *pos = &g_ScenarioData.htb.pos;
|
||||
pos->x = g_ScenarioData.htb.token->pos.x;
|
||||
pos->y = g_ScenarioData.htb.token->pos.y;
|
||||
pos->z = g_ScenarioData.htb.token->pos.z;
|
||||
}
|
||||
}
|
||||
|
||||
void htbTickChr(struct chrdata *chr)
|
||||
{
|
||||
if (chr) {
|
||||
if (chr->aibot->hasbriefcase) {
|
||||
chr->aibot->unk0a0 += g_Vars.lvupdate240;
|
||||
|
||||
if (chr->aibot->unk0a0 >= PALDOWN(7200)) {
|
||||
sndStart(var80095200, SFX_MP_SCOREPOINT, NULL, -1, -1, -1, -1, -1);
|
||||
g_MpAllChrConfigPtrs[mpPlayerGetIndex(chr)]->numpoints++;
|
||||
chr->aibot->unk0a0 = 0;
|
||||
}
|
||||
} else {
|
||||
chr->aibot->unk0a0 = 0;
|
||||
}
|
||||
} else {
|
||||
if (invHasBriefcase()) {
|
||||
g_Vars.currentplayerstats->tokenheldtime += g_Vars.lvupdate240;
|
||||
|
||||
if (g_Vars.currentplayerstats->tokenheldtime >= PALDOWN(7200)) {
|
||||
sndStart(var80095200, SFX_MP_SCOREPOINT, NULL, -1, -1, -1, -1, -1);
|
||||
g_MpAllChrConfigPtrs[g_Vars.currentplayernum]->numpoints++;
|
||||
hudmsgCreateWithFlags(langGet(L_MPWEAPONS_024), HUDMSGTYPE_MPSCENARIO, HUDMSGFLAG_ONLYIFALIVE); // "1 Point!"
|
||||
g_Vars.currentplayerstats->tokenheldtime = 0;
|
||||
}
|
||||
} else {
|
||||
g_Vars.currentplayerstats->tokenheldtime = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @bug: In NTSC Final, the calculation of mins and subsequent subtraction from
|
||||
* time240 should use 60 * 240 instead of 30 * 240. This has no noticeable
|
||||
* effect unless the score duration is increased to above 30 seconds.
|
||||
*
|
||||
* PAL recognises that mins will always be 0 and simplifies the calculation.
|
||||
*/
|
||||
Gfx *htbRenderHud(Gfx *gdl)
|
||||
{
|
||||
s32 time240;
|
||||
s32 mins;
|
||||
s32 secs;
|
||||
s32 textwidth;
|
||||
s32 textheight;
|
||||
s32 x;
|
||||
s32 y;
|
||||
char text[64];
|
||||
|
||||
if (invHasBriefcase()) {
|
||||
x = viGetViewLeft() + viGetViewWidth() / 2;
|
||||
y = viGetViewTop() + 10;
|
||||
|
||||
#if VERSION >= VERSION_PAL_FINAL
|
||||
time240 = (30 * 200) - g_Vars.currentplayerstats->tokenheldtime;
|
||||
secs = (time240 + 199) / 200;
|
||||
sprintf(text, "%d:%02d", 0, secs);
|
||||
#else
|
||||
time240 = (30 * 240) - g_Vars.currentplayerstats->tokenheldtime;
|
||||
mins = time240 / (30 * 240);
|
||||
time240 -= (30 * 240) * mins;
|
||||
secs = (time240 + 239) / 240;
|
||||
sprintf(text, "%d:%02d", mins, secs);
|
||||
#endif
|
||||
|
||||
gdl = func0f153628(gdl);
|
||||
textMeasure(&textheight, &textwidth, text, g_CharsHandelGothicXs, g_FontHandelGothicXs, 0);
|
||||
|
||||
x -= textwidth / 2;
|
||||
textwidth += x;
|
||||
textheight += y;
|
||||
|
||||
#if VERSION >= VERSION_NTSC_1_0
|
||||
gdl = func0f153990(gdl, x, y, textwidth, textheight);
|
||||
gdl = textRender(gdl, &x, &y, text, g_CharsNumeric, g_FontNumeric, 0x00ff00a0, 0xa0, viGetWidth(), viGetHeight(), 0, 0);
|
||||
#else
|
||||
gdl = func0f153858(gdl, &x, &y, &textwidth, &textheight);
|
||||
gdl = textRender(gdl, &x, &y, text, g_CharsNumeric, g_FontNumeric, 0x00ff00a0, 0x88, viGetWidth(), viGetHeight(), 0, 0);
|
||||
#endif
|
||||
|
||||
gdl = func0f153780(gdl);
|
||||
}
|
||||
|
||||
return gdl;
|
||||
}
|
||||
|
||||
void htbCalculatePlayerScore(struct mpchrconfig *mpchr, s32 mpchrnum, s32 *score, s32 *deaths)
|
||||
{
|
||||
struct mpchrconfig *loopmpchr;
|
||||
s32 i;
|
||||
|
||||
*score = 0;
|
||||
*score += mpchr->numpoints;
|
||||
|
||||
if (g_MpSetup.options & MPOPTION_KILLSSCORE) {
|
||||
for (i = 0; i != MAX_MPCHRS; i++) {
|
||||
if (i == mpchrnum) {
|
||||
*score -= mpchr->killcounts[i];
|
||||
} else if (g_MpSetup.options & MPOPTION_TEAMSENABLED) {
|
||||
loopmpchr = MPCHR(i);
|
||||
|
||||
if (loopmpchr->team == mpchr->team) {
|
||||
*score -= mpchr->killcounts[i];
|
||||
} else {
|
||||
*score += mpchr->killcounts[i];
|
||||
}
|
||||
} else {
|
||||
*score += mpchr->killcounts[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*deaths = mpchr->numdeaths;
|
||||
}
|
||||
|
||||
Gfx *htbRadarExtra(Gfx *gdl)
|
||||
{
|
||||
if ((g_MpSetup.options & MPOPTION_HTB_SHOWONRADAR) &&
|
||||
g_ScenarioData.htb.token != NULL &&
|
||||
g_ScenarioData.htb.token->type != PROPTYPE_PLAYER &&
|
||||
g_ScenarioData.htb.token->type != PROPTYPE_CHR) {
|
||||
struct coord dist;
|
||||
dist.x = g_ScenarioData.htb.pos.x - g_Vars.currentplayer->prop->pos.x;
|
||||
dist.y = g_ScenarioData.htb.pos.y - g_Vars.currentplayer->prop->pos.y;
|
||||
dist.z = g_ScenarioData.htb.pos.z - g_Vars.currentplayer->prop->pos.z;
|
||||
gdl = radarDrawDot(gdl, g_ScenarioData.htb.token, &dist, 0x00ff0000, 0, 1);
|
||||
}
|
||||
|
||||
return gdl;
|
||||
}
|
||||
|
||||
bool htbRadarChr(Gfx **gdl, struct prop *prop)
|
||||
{
|
||||
if ((g_MpSetup.options & MPOPTION_HTB_SHOWONRADAR) &&
|
||||
g_ScenarioData.htb.token &&
|
||||
prop == g_ScenarioData.htb.token) {
|
||||
if (prop->type == PROPTYPE_PLAYER || prop->type == PROPTYPE_CHR) {
|
||||
struct coord dist;
|
||||
dist.x = prop->pos.x - g_Vars.currentplayer->prop->pos.x;
|
||||
dist.y = prop->pos.y - g_Vars.currentplayer->prop->pos.y;
|
||||
dist.z = prop->pos.z - g_Vars.currentplayer->prop->pos.z;
|
||||
|
||||
if (g_MpSetup.options & MPOPTION_TEAMSENABLED) {
|
||||
u32 colour = g_TeamColours[radarGetTeamIndex(prop->chr->team)];
|
||||
*gdl = radarDrawDot(*gdl, g_ScenarioData.htb.token, &dist, colour, 0, 1);
|
||||
} else {
|
||||
*gdl = radarDrawDot(*gdl, g_ScenarioData.htb.token, &dist, 0x00ff0000, 0, 1);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool htbHighlightProp(struct prop *prop, s32 *colour)
|
||||
{
|
||||
if ((g_MpSetup.options & MPOPTION_HTB_HIGHLIGHTBRIEFCASE) && prop == g_ScenarioData.htb.token) {
|
||||
colour[0] = 0;
|
||||
colour[1] = 0xff;
|
||||
colour[2] = 0;
|
||||
colour[3] = 0x40;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
@ -0,0 +1,571 @@
|
|||
/**
|
||||
* King of the Hill
|
||||
*
|
||||
* At the start of the match, a room is chosen as the "hill" and is highlighted
|
||||
* in green. When a player enters the hill it changes to their team colour.
|
||||
* If the player remains in the hill for the "mphilltime" (this is configurable)
|
||||
* then they score a point and a new room is chosen as the next hill.
|
||||
*
|
||||
* If a second team enters the hill then the timer is paused until the hill is
|
||||
* exclusive again. The enemy team must completely clear the hill of opposing
|
||||
* players before it is switched to their team.
|
||||
*
|
||||
* Points are awarded to each player in the hill at the time that it is won.
|
||||
*/
|
||||
|
||||
s32 menuhandlerMpHillTime(s32 operation, struct menuitem *item, union handlerdata *data)
|
||||
{
|
||||
switch (operation) {
|
||||
case MENUOP_GETSLIDER:
|
||||
data->slider.value = g_Vars.mphilltime;
|
||||
break;
|
||||
case MENUOP_SET:
|
||||
g_Vars.mphilltime = (u8)data->slider.value;
|
||||
break;
|
||||
case MENUOP_GETSLIDERLABEL:
|
||||
sprintf(data->slider.label, langGet(L_MPWEAPONS_023), data->slider.value + 10); // "%ds/Point"
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct menuitem g_KohOptionsMenuItems[] = {
|
||||
{ MENUITEMTYPE_CHECKBOX, 0, 0x00020000, L_MPMENU_222, MPOPTION_ONEHITKILLS, menuhandlerMpOneHitKills }, // "One-Hit Kills"
|
||||
{ MENUITEMTYPE_DROPDOWN, 0, 0x00020000, L_MPMENU_223, 0x00000000, menuhandlerMpSlowMotion }, // "Slow Motion"
|
||||
{ MENUITEMTYPE_CHECKBOX, 0, 0x00020000, L_MPMENU_224, MPOPTION_FASTMOVEMENT, menuhandlerMpCheckboxOption }, // "Fast Movement"
|
||||
{ MENUITEMTYPE_CHECKBOX, 0, 0x00020000, L_MPMENU_225, MPOPTION_DISPLAYTEAM, menuhandlerMpDisplayTeam }, // "Display Team"
|
||||
{ MENUITEMTYPE_CHECKBOX, 0, 0x00020000, L_MPMENU_226, MPOPTION_NORADAR, menuhandlerMpCheckboxOption }, // "No Radar"
|
||||
{ MENUITEMTYPE_CHECKBOX, 0, 0x00020000, L_MPMENU_227, MPOPTION_NOAUTOAIM, menuhandlerMpCheckboxOption }, // "No Auto-Aim"
|
||||
{ MENUITEMTYPE_CHECKBOX, 0, 0x00020000, L_OPTIONS_493, MPOPTION_KILLSSCORE, menuhandlerMpCheckboxOption }, // "Kills Score"
|
||||
{ MENUITEMTYPE_SEPARATOR, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
|
||||
{ MENUITEMTYPE_CHECKBOX, 0, 0x00020000, L_MPMENU_233, MPOPTION_KOH_HILLONRADAR, menuhandlerMpCheckboxOption }, // "Hill on Radar"
|
||||
{ MENUITEMTYPE_CHECKBOX, 0, 0x00020000, L_MPMENU_234, MPOPTION_KOH_MOBILEHILL, menuhandlerMpCheckboxOption }, // "Mobile Hill"
|
||||
{ MENUITEMTYPE_SLIDER, 0, 0x00020000, L_MPMENU_235, 0x0000006e, menuhandlerMpHillTime }, // "Time"
|
||||
{ MENUITEMTYPE_SEPARATOR, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
|
||||
{ MENUITEMTYPE_SELECTABLE, 0, 0x00000008, L_MPMENU_239, 0x00000000, NULL }, // "Back"
|
||||
{ MENUITEMTYPE_END, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
|
||||
};
|
||||
|
||||
struct menudialog g_KohOptionsMenuDialog = {
|
||||
MENUDIALOGTYPE_DEFAULT,
|
||||
L_MPMENU_219, // "Hill Options"
|
||||
g_KohOptionsMenuItems,
|
||||
mpOptionsMenuDialog,
|
||||
0x00000010,
|
||||
NULL,
|
||||
};
|
||||
|
||||
void kohReadSave(struct savebuffer *buffer)
|
||||
{
|
||||
g_Vars.mphilltime = savebufferReadBits(buffer, 8);
|
||||
}
|
||||
|
||||
void kohWriteSave(struct savebuffer *buffer)
|
||||
{
|
||||
savebufferOr(buffer, g_Vars.mphilltime, 8);
|
||||
}
|
||||
|
||||
void kohInit(void)
|
||||
{
|
||||
s32 i;
|
||||
|
||||
g_MpSetup.options |= MPOPTION_TEAMSENABLED;
|
||||
g_ScenarioData.koh.hillindex = -1;
|
||||
g_ScenarioData.koh.hillcount = 0;
|
||||
g_ScenarioData.koh.unk00 = 0;
|
||||
g_ScenarioData.koh.occupiedteam = -1;
|
||||
g_ScenarioData.koh.elapsed240 = 0;
|
||||
g_ScenarioData.koh.hillrooms[0] = -1;
|
||||
g_ScenarioData.koh.hillrooms[1] = -1;
|
||||
g_ScenarioData.koh.hillpos.x = 0;
|
||||
g_ScenarioData.koh.hillpos.y = 0;
|
||||
g_ScenarioData.koh.hillpos.z = 0;
|
||||
g_ScenarioData.koh.colourfracr = 0.25;
|
||||
g_ScenarioData.koh.colourfracg = 1;
|
||||
g_ScenarioData.koh.colourfracb = 0.25;
|
||||
|
||||
for (i = 0; i < 9; i++) {
|
||||
g_ScenarioData.koh.hillpads[i] = -1;
|
||||
}
|
||||
}
|
||||
|
||||
void kohInitProps(void)
|
||||
{
|
||||
s16 pad_id = 0;
|
||||
struct pad pad;
|
||||
|
||||
if (g_ScenarioData.koh.hillcount > 1) {
|
||||
g_ScenarioData.koh.hillindex = random() % g_ScenarioData.koh.hillcount;
|
||||
pad_id = g_ScenarioData.koh.hillpads[g_ScenarioData.koh.hillindex];
|
||||
} else {
|
||||
// @bug: If a stage setup file only has one hill, pad_id is not assigned
|
||||
// so it will always use the room that contains pad zero.
|
||||
g_ScenarioData.koh.hillindex = 0;
|
||||
}
|
||||
|
||||
padUnpack(pad_id, PADFIELD_POS | PADFIELD_ROOM, &pad);
|
||||
g_ScenarioData.koh.hillrooms[0] = pad.room;
|
||||
g_ScenarioData.koh.hillrooms[1] = -1;
|
||||
g_ScenarioData.koh.hillpos.x = pad.pos.x;
|
||||
g_ScenarioData.koh.hillpos.y = pad.pos.y;
|
||||
g_ScenarioData.koh.hillpos.z = pad.pos.z;
|
||||
g_ScenarioData.koh.hillpos.y = cd0002a36c(&g_ScenarioData.koh.hillpos, &g_ScenarioData.koh.hillrooms[0], 0, 0);
|
||||
g_ScenarioData.koh.movehill = false;
|
||||
roomSetLighting(g_ScenarioData.koh.hillrooms[0], LIGHTOP_5, 0, 0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* A match for this function has only been possible by making heavy reuse of
|
||||
* variables, but this impacts readability significantly.
|
||||
*
|
||||
* To make this code readable, constants have been used to map appropriate names
|
||||
* to the underlying variable.
|
||||
*/
|
||||
void kohTick(void)
|
||||
{
|
||||
s32 i;
|
||||
s32 hillteam;
|
||||
s32 s1;
|
||||
s32 s2;
|
||||
s32 numchrsinhill;
|
||||
s32 dualoccupancy;
|
||||
s32 s0;
|
||||
s32 previndex;
|
||||
f32 targetr;
|
||||
f32 targetg;
|
||||
f32 targetb;
|
||||
char text[64];
|
||||
s32 teamsinhill[8];
|
||||
struct pad pad;
|
||||
struct prop *chrsinhill[12];
|
||||
struct prop *prop;
|
||||
struct chrdata *chr;
|
||||
s32 padnum;
|
||||
s32 teamindex;
|
||||
|
||||
#define hillteam s0
|
||||
#define inhill s1
|
||||
#define mostchrs s1
|
||||
#define playernum1 s1
|
||||
#define prevplayernum1 s1
|
||||
#define numteamsinhill s2
|
||||
#define prevplayernum2 s2
|
||||
#define playernum2 s2
|
||||
|
||||
if (g_ScenarioData.koh.hillindex == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
dualoccupancy = 0;
|
||||
|
||||
if (g_ScenarioData.koh.movehill) {
|
||||
// The hill is moving, but first it needs to be returned to the natural
|
||||
// colour. This is done using a fade over several frames.
|
||||
g_ScenarioData.koh.occupiedteam = -1;
|
||||
g_ScenarioData.koh.elapsed240 = 0;
|
||||
|
||||
targetr = 1;
|
||||
targetg = 1;
|
||||
targetb = 1;
|
||||
|
||||
if (g_ScenarioData.koh.colourfracr >= .95f
|
||||
&& g_ScenarioData.koh.colourfracg >= .95f
|
||||
&& g_ScenarioData.koh.colourfracb >= .95f) {
|
||||
// The old hill is now "natural enough" to set it back to full
|
||||
// natural colour and actually choose a new hill.
|
||||
roomSetLighting(g_ScenarioData.koh.hillrooms[0], 0, 0, 0, 0);
|
||||
|
||||
// Choose the new hill. Note that hillcount refers to the number of
|
||||
// hill options, which is always >= 2.
|
||||
padnum = 0;
|
||||
|
||||
if (g_ScenarioData.koh.hillcount >= 2) {
|
||||
previndex = g_ScenarioData.koh.hillindex;
|
||||
|
||||
do {
|
||||
g_ScenarioData.koh.hillindex = random() % g_ScenarioData.koh.hillcount;
|
||||
} while (g_ScenarioData.koh.hillindex == previndex);
|
||||
|
||||
padnum = g_ScenarioData.koh.hillpads[g_ScenarioData.koh.hillindex];
|
||||
} else {
|
||||
g_ScenarioData.koh.hillindex = 0;
|
||||
}
|
||||
|
||||
padUnpack(padnum, PADFIELD_POS | PADFIELD_ROOM, &pad);
|
||||
|
||||
g_ScenarioData.koh.hillrooms[0] = pad.room;
|
||||
g_ScenarioData.koh.hillrooms[1] = -1;
|
||||
|
||||
g_ScenarioData.koh.hillpos.x = pad.pos.x;
|
||||
g_ScenarioData.koh.hillpos.y = pad.pos.y;
|
||||
g_ScenarioData.koh.hillpos.z = pad.pos.z;
|
||||
|
||||
g_ScenarioData.koh.hillpos.y = cd0002a36c(&g_ScenarioData.koh.hillpos, g_ScenarioData.koh.hillrooms, NULL, NULL);
|
||||
|
||||
roomSetLighting(g_ScenarioData.koh.hillrooms[0], 5, 0, 0, 0);
|
||||
|
||||
g_ScenarioData.koh.occupiedteam = -1;
|
||||
g_ScenarioData.koh.elapsed240 = 0;
|
||||
g_ScenarioData.koh.movehill = false;
|
||||
}
|
||||
} else {
|
||||
// The hill is not moving on this frame
|
||||
// Build an array of chr props who are in the hill
|
||||
numchrsinhill = 0;
|
||||
prop = g_Vars.activeprops;
|
||||
|
||||
while (prop) {
|
||||
if (prop->type == PROPTYPE_PLAYER || prop->type == PROPTYPE_CHR) {
|
||||
inhill = false;
|
||||
|
||||
if (prop->rooms[0] == g_ScenarioData.koh.hillrooms[0]) {
|
||||
inhill = true;
|
||||
}
|
||||
|
||||
if (inhill) {
|
||||
chr = prop->chr;
|
||||
|
||||
if (!chrIsDead(chr)) {
|
||||
chrsinhill[numchrsinhill] = prop;
|
||||
numchrsinhill++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
prop = prop->next;
|
||||
}
|
||||
|
||||
// Use the chrshillhill array to build an array of all teams who have
|
||||
// chrs in the hill. During development, this array likely stored a
|
||||
// count of that team's chrs but was later changed to just be 0 or 1
|
||||
// to denote if they have any chrs in the hill.
|
||||
for (s0 = 0; s0 < 8; s0++) {
|
||||
teamsinhill[s0] = 0;
|
||||
}
|
||||
|
||||
for (s0 = 0, numteamsinhill = 0; s0 < numchrsinhill; s0++) {
|
||||
chr = chrsinhill[s0]->chr;
|
||||
teamindex = radarGetTeamIndex(chr->team);
|
||||
|
||||
if (teamsinhill[teamindex] == 0) {
|
||||
numteamsinhill++;
|
||||
teamsinhill[teamindex] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (numteamsinhill == 0) {
|
||||
g_ScenarioData.koh.occupiedteam = -1;
|
||||
g_ScenarioData.koh.elapsed240 = 0;
|
||||
} else {
|
||||
if (numteamsinhill == 1) {
|
||||
// Set hillteam for later
|
||||
for (hillteam = 0; hillteam < 8; hillteam++) {
|
||||
if (teamsinhill[hillteam]) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// There are multiple teams in the hill.
|
||||
// This code attempts to filter the teamsinhill array to only
|
||||
// those which have the most chrs, but the teamsinhill array
|
||||
// only contains values 0 or 1 so it effectively does nothing.
|
||||
mostchrs = 0;
|
||||
|
||||
for (s0 = 0; s0 < 8; s0++) {
|
||||
if (teamsinhill[s0] > mostchrs) {
|
||||
mostchrs = teamsinhill[s0];
|
||||
}
|
||||
}
|
||||
|
||||
for (s0 = 0; s0 < 8; s0++) {
|
||||
if (teamsinhill[s0] != mostchrs) {
|
||||
teamsinhill[s0] = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Count the number of teams who are tied for the most chrs in
|
||||
// the hill. Or rather, because the teamsinhill array only
|
||||
// contains 0 or 1 values, this is just recounting the number of
|
||||
// teams who have presence in the hill.
|
||||
for (s0 = 0; s0 < 8; s0++) {
|
||||
if (teamsinhill[s0]) {
|
||||
dualoccupancy++;
|
||||
}
|
||||
}
|
||||
|
||||
dualoccupancy = dualoccupancy >= 2 ? true : false;
|
||||
|
||||
// Set the hillteam to whoever was holding it previously
|
||||
// so the hill remains the same colour
|
||||
for (hillteam = 0; hillteam < 8; hillteam++) {
|
||||
if (teamsinhill[hillteam] && hillteam == g_ScenarioData.koh.occupiedteam) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (hillteam == 8) {
|
||||
// This happens if the controlling team leaves the hill
|
||||
// and there are two other teams still in the hill.
|
||||
// The hill goes green until one team holds it exclusively.
|
||||
g_ScenarioData.koh.occupiedteam = -1;
|
||||
hillteam = -1;
|
||||
}
|
||||
}
|
||||
|
||||
// At this point we know there is a team in the hill on this frame.
|
||||
// So if these don't match then the hill is turning into a team
|
||||
// colour rather than going green.
|
||||
if (hillteam != g_ScenarioData.koh.occupiedteam) {
|
||||
sndStart(var80095200, SFX_MP_HILLENTERED, 0, -1, -1, -1, -1, -1);
|
||||
|
||||
g_ScenarioData.koh.occupiedteam = hillteam;
|
||||
g_ScenarioData.koh.elapsed240 = 0;
|
||||
|
||||
// "%has captured the Hill!"
|
||||
sprintf(text, langGet(L_MPWEAPONS_022), &g_BossFile.teamnames[hillteam]);
|
||||
|
||||
prevplayernum2 = g_Vars.currentplayernum;
|
||||
|
||||
for (playernum1 = 0; playernum1 < PLAYERCOUNT(); playernum1++) {
|
||||
setCurrentPlayerNum(playernum1);
|
||||
|
||||
chr = g_Vars.currentplayer->prop->chr;
|
||||
|
||||
if (radarGetTeamIndex(chr->team) == g_ScenarioData.koh.occupiedteam) {
|
||||
// "We have the Hill!"
|
||||
hudmsgCreateWithFlags(langGet(L_MPWEAPONS_021), HUDMSGTYPE_MPSCENARIO, HUDMSGFLAG_ONLYIFALIVE);
|
||||
} else {
|
||||
hudmsgCreateWithFlags(text, HUDMSGTYPE_MPSCENARIO, HUDMSGFLAG_ONLYIFALIVE);
|
||||
}
|
||||
}
|
||||
|
||||
setCurrentPlayerNum(prevplayernum2);
|
||||
} else {
|
||||
// A team is remaining in the hill.
|
||||
// Only tick the hill timer if they have exclusive occupancy.
|
||||
if (!dualoccupancy) {
|
||||
g_ScenarioData.koh.elapsed240 += g_Vars.lvupdate240;
|
||||
|
||||
if (g_ScenarioData.koh.elapsed240 >= g_Vars.mphilltime * PALDOWN(240) + PALDOWN(2400)) {
|
||||
// Scored a point
|
||||
sndStart(var80095200, SFX_MP_SCOREPOINT, 0, -1, -1, -1, -1, -1);
|
||||
|
||||
// @bug: There is no check for a chr being dead here.
|
||||
// If a player dies in the hill and waits on the
|
||||
// "press start" screen while their team mate scores the
|
||||
// hill, the dead player will always be awarded a point.
|
||||
for (playernum2 = 0; playernum2 < g_MpNumChrs; playernum2++) {
|
||||
if (radarGetTeamIndex(g_MpAllChrPtrs[playernum2]->team) == g_ScenarioData.koh.occupiedteam) {
|
||||
prop = g_MpAllChrPtrs[playernum2]->prop;
|
||||
|
||||
if (prop->rooms[0] == g_ScenarioData.koh.hillrooms[0]) {
|
||||
g_MpAllChrConfigPtrs[playernum2]->numpoints++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
prevplayernum1 = g_Vars.currentplayernum;
|
||||
|
||||
for (playernum2 = 0; playernum2 < g_MpNumChrs; playernum2++) {
|
||||
if (g_MpAllChrPtrs[playernum2]->aibot == NULL
|
||||
&& radarGetTeamIndex(g_MpAllChrPtrs[playernum2]->team) == g_ScenarioData.koh.occupiedteam) {
|
||||
setCurrentPlayerNum(playernum2);
|
||||
|
||||
// "King of the Hill!"
|
||||
hudmsgCreateWithFlags(langGet(L_MPWEAPONS_020), HUDMSGTYPE_MPSCENARIO, HUDMSGFLAG_ONLYIFALIVE);
|
||||
}
|
||||
}
|
||||
|
||||
setCurrentPlayerNum(prevplayernum1);
|
||||
|
||||
g_ScenarioData.koh.occupiedteam = -1;
|
||||
g_ScenarioData.koh.elapsed240 = 0;
|
||||
|
||||
if (g_MpSetup.options & MPOPTION_KOH_MOBILEHILL) {
|
||||
g_ScenarioData.koh.movehill = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate what colour the hill should tween towards
|
||||
if (g_ScenarioData.koh.occupiedteam == -1) {
|
||||
targetr = 0.25f;
|
||||
targetg = 1;
|
||||
targetb = 0.25f;
|
||||
} else {
|
||||
u32 colour = g_TeamColours[g_ScenarioData.koh.occupiedteam];
|
||||
targetr = ((s32)(colour >> 24 & 0xff) + 0xff) * (1.0f / 512.0f);
|
||||
targetg = ((s32)(colour >> 16 & 0xff) + 0xff) * (1.0f / 512.0f);
|
||||
targetb = ((s32)(colour >> 8 & 0xff) + 0xff) * (1.0f / 512.0f);
|
||||
}
|
||||
}
|
||||
|
||||
// Tween the colour components towards the target colour.
|
||||
// @bug: This increments using g_Vars.diffframe60, which is updated while
|
||||
// the game is paused. Because of this, if you pause as soon as a hill is
|
||||
// scored then the colour fade and selection of the new hill will happen
|
||||
// while paused.
|
||||
if (g_ScenarioData.koh.colourfracr != targetr) {
|
||||
for (i = 0; i < g_Vars.diffframe60; i++) {
|
||||
#if PAL
|
||||
g_ScenarioData.koh.colourfracr = 0.0597f * targetr + 0.9403f * g_ScenarioData.koh.colourfracr;
|
||||
#else
|
||||
g_ScenarioData.koh.colourfracr = 0.05f * targetr + 0.95f * g_ScenarioData.koh.colourfracr;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (g_ScenarioData.koh.colourfracg != targetg) {
|
||||
for (i = 0; i < g_Vars.diffframe60; i++) {
|
||||
#if PAL
|
||||
g_ScenarioData.koh.colourfracg = 0.0597f * targetg + 0.9403f * g_ScenarioData.koh.colourfracg;
|
||||
#else
|
||||
g_ScenarioData.koh.colourfracg = 0.05f * targetg + 0.95f * g_ScenarioData.koh.colourfracg;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (g_ScenarioData.koh.colourfracb != targetb) {
|
||||
for (i = 0; i < g_Vars.diffframe60; i++) {
|
||||
#if PAL
|
||||
g_ScenarioData.koh.colourfracb = 0.0597f * targetb + 0.9403f * g_ScenarioData.koh.colourfracb;
|
||||
#else
|
||||
g_ScenarioData.koh.colourfracb = 0.05f * targetb + 0.95f * g_ScenarioData.koh.colourfracb;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Gfx *kohRenderHud(Gfx *gdl)
|
||||
{
|
||||
s32 time240;
|
||||
s32 mins;
|
||||
s32 secs;
|
||||
s32 textwidth;
|
||||
s32 textheight;
|
||||
s32 x;
|
||||
s32 y;
|
||||
struct chrdata *chr = g_Vars.currentplayer->prop->chr;
|
||||
char text[64];
|
||||
|
||||
if (radarGetTeamIndex(chr->team) == g_ScenarioData.koh.occupiedteam && !g_ScenarioData.koh.movehill) {
|
||||
x = viGetViewLeft() + viGetViewWidth() / 2;
|
||||
y = viGetViewTop() + 10;
|
||||
|
||||
time240 = g_Vars.mphilltime * PALDOWN(240) - g_ScenarioData.koh.elapsed240;
|
||||
time240 += PAL ? 2199 : 2400;
|
||||
mins = time240 / PALDOWN(60 * 240);
|
||||
time240 -= PALDOWN(60 * 240) * mins;
|
||||
|
||||
#if PAL
|
||||
secs = time240 / PALDOWN(240);
|
||||
#else
|
||||
secs = (time240 + (PALDOWN(240) - 1)) / PALDOWN(240);
|
||||
#endif
|
||||
|
||||
if ((g_Vars.mphilltime * 60 + 600) / 3600) {
|
||||
sprintf(text, "%d:%02d", mins, secs);
|
||||
} else {
|
||||
sprintf(text, "%02d", secs);
|
||||
}
|
||||
|
||||
gdl = func0f153628(gdl);
|
||||
textMeasure(&textheight, &textwidth, text, g_CharsHandelGothicXs, g_FontHandelGothicXs, 0);
|
||||
|
||||
x -= textwidth / 2;
|
||||
textwidth += x;
|
||||
textheight += y;
|
||||
|
||||
#if VERSION >= VERSION_NTSC_1_0
|
||||
gdl = func0f153990(gdl, x, y, textwidth, textheight);
|
||||
gdl = textRender(gdl, &x, &y, text, g_CharsNumeric, g_FontNumeric, 0x00ff00a0, 0xa0, viGetWidth(), viGetHeight(), 0, 0);
|
||||
#else
|
||||
gdl = func0f153858(gdl, &x, &y, &textwidth, &textheight);
|
||||
gdl = textRender(gdl, &x, &y, text, g_CharsNumeric, g_FontNumeric, 0x00ff00a0, 0x88, viGetWidth(), viGetHeight(), 0, 0);
|
||||
#endif
|
||||
gdl = func0f153780(gdl);
|
||||
}
|
||||
|
||||
return gdl;
|
||||
}
|
||||
|
||||
void kohCalculatePlayerScore(struct mpchrconfig *mpchr, s32 mpchrnum, s32 *score, s32 *deaths)
|
||||
{
|
||||
struct mpchrconfig *loopmpchr;
|
||||
s32 i;
|
||||
|
||||
*score = 0;
|
||||
*score += mpchr->numpoints;
|
||||
|
||||
if (g_MpSetup.options & MPOPTION_KILLSSCORE) {
|
||||
for (i = 0; i != MAX_MPCHRS; i++) {
|
||||
if (i == mpchrnum) {
|
||||
*score -= mpchr->killcounts[i];
|
||||
} else {
|
||||
loopmpchr = MPCHR(i);
|
||||
|
||||
if (loopmpchr->team == mpchr->team) {
|
||||
*score -= mpchr->killcounts[i];
|
||||
} else {
|
||||
*score += mpchr->killcounts[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*deaths = mpchr->numdeaths;
|
||||
}
|
||||
|
||||
Gfx *kohRadarExtra(Gfx *gdl)
|
||||
{
|
||||
if (g_MpSetup.options & MPOPTION_KOH_HILLONRADAR && !g_ScenarioData.koh.movehill) {
|
||||
struct coord dist;
|
||||
u32 colour;
|
||||
dist.x = g_ScenarioData.koh.hillpos.x - g_Vars.currentplayer->prop->pos.x;
|
||||
dist.y = g_ScenarioData.koh.hillpos.y - g_Vars.currentplayer->prop->pos.y;
|
||||
dist.z = g_ScenarioData.koh.hillpos.z - g_Vars.currentplayer->prop->pos.z;
|
||||
|
||||
if (g_ScenarioData.koh.occupiedteam == -1) {
|
||||
colour = 0x00ff0000;
|
||||
} else {
|
||||
colour = g_TeamColours[g_ScenarioData.koh.occupiedteam];
|
||||
}
|
||||
|
||||
gdl = radarDrawDot(gdl, NULL, &dist, colour, 0, 1);
|
||||
}
|
||||
|
||||
return gdl;
|
||||
}
|
||||
|
||||
void kohAddHill(s32 *cmd)
|
||||
{
|
||||
if (g_ScenarioData.koh.hillcount < ARRAYCOUNT(g_ScenarioData.koh.hillpads)) {
|
||||
g_ScenarioData.koh.hillpads[g_ScenarioData.koh.hillcount] = cmd[1];
|
||||
g_ScenarioData.koh.hillcount++;
|
||||
}
|
||||
}
|
||||
|
||||
bool kohIsRoomHighlighted(s16 room)
|
||||
{
|
||||
return room == g_ScenarioData.koh.hillrooms[0];
|
||||
}
|
||||
|
||||
void kohHighlightRoom(s16 roomnum, s32 *arg1, s32 *arg2, s32 *arg3)
|
||||
{
|
||||
if (roomnum == g_ScenarioData.koh.hillrooms[0]) {
|
||||
f32 a = *arg1;
|
||||
f32 b = *arg2;
|
||||
f32 c = *arg3;
|
||||
|
||||
a *= g_ScenarioData.koh.colourfracr;
|
||||
b *= g_ScenarioData.koh.colourfracg;
|
||||
c *= g_ScenarioData.koh.colourfracb;
|
||||
|
||||
*arg1 = a;
|
||||
*arg2 = b;
|
||||
*arg3 = c;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,307 @@
|
|||
/**
|
||||
* Pop a Cap
|
||||
*
|
||||
* At the start of the match, a single player is randomly chosen as the victim.
|
||||
* Players must kill the victim in order to score, while the victim scores a
|
||||
* point for every 60 seconds they remain alive. Once killed, another player is
|
||||
* chosen as the victim.
|
||||
*/
|
||||
|
||||
struct menuitem g_PacOptionsMenuItems[] = {
|
||||
{ MENUITEMTYPE_CHECKBOX, 0, 0x00020000, L_MPMENU_222, MPOPTION_ONEHITKILLS, menuhandlerMpOneHitKills }, // "One-Hit Kills"
|
||||
{ MENUITEMTYPE_DROPDOWN, 0, 0x00020000, L_MPMENU_223, 0x00000000, menuhandlerMpSlowMotion }, // "Slow Motion"
|
||||
{ MENUITEMTYPE_CHECKBOX, 0, 0x00020000, L_MPMENU_224, MPOPTION_FASTMOVEMENT, menuhandlerMpCheckboxOption }, // "Fast Movement"
|
||||
{ MENUITEMTYPE_CHECKBOX, 0, 0x00020000, L_MPMENU_225, MPOPTION_DISPLAYTEAM, menuhandlerMpDisplayTeam }, // "Display Team"
|
||||
{ MENUITEMTYPE_CHECKBOX, 0, 0x00020000, L_MPMENU_226, MPOPTION_NORADAR, menuhandlerMpCheckboxOption }, // "No Radar"
|
||||
{ MENUITEMTYPE_CHECKBOX, 0, 0x00020000, L_MPMENU_227, MPOPTION_NOAUTOAIM, menuhandlerMpCheckboxOption }, // "No Auto-Aim"
|
||||
{ MENUITEMTYPE_CHECKBOX, 0, 0x00020000, L_OPTIONS_493, MPOPTION_KILLSSCORE, menuhandlerMpCheckboxOption }, // "Kills Score"
|
||||
{ MENUITEMTYPE_SEPARATOR, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
|
||||
{ MENUITEMTYPE_CHECKBOX, 0, 0x00020000, L_MPMENU_230, MPOPTION_PAC_HIGHLIGHTTARGET, menuhandlerMpCheckboxOption }, // "Highlight Target"
|
||||
{ MENUITEMTYPE_CHECKBOX, 0, 0x00020000, L_MPMENU_238, MPOPTION_PAC_SHOWONRADAR, menuhandlerMpCheckboxOption }, // "Show on Radar"
|
||||
{ MENUITEMTYPE_SEPARATOR, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
|
||||
{ MENUITEMTYPE_SELECTABLE, 0, 0x00000008, L_MPMENU_239, 0x00000000, NULL }, // "Back"
|
||||
{ MENUITEMTYPE_END, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
|
||||
};
|
||||
|
||||
struct menudialog g_PacOptionsMenuDialog = {
|
||||
MENUDIALOGTYPE_DEFAULT,
|
||||
L_MPMENU_218, // "Pop a Cap Options"
|
||||
g_PacOptionsMenuItems,
|
||||
mpOptionsMenuDialog,
|
||||
0x00000010,
|
||||
NULL,
|
||||
};
|
||||
|
||||
void pacReset(void)
|
||||
{
|
||||
s32 i;
|
||||
s32 j;
|
||||
struct scenariodata_pac *data = &g_ScenarioData.pac;
|
||||
|
||||
data->victimindex = -1;
|
||||
data->age240 = 0;
|
||||
|
||||
osSyncPrintf("PopACapReset -> num_mplayers=%d : Working\n", g_MpNumChrs);
|
||||
|
||||
for (i = 0; i != MAX_MPCHRS; i++) {
|
||||
data->killcounts[i] = 0;
|
||||
data->survivalcounts[i] = 0;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
|
||||
while (i < g_MpNumChrs) {
|
||||
bool isnew;
|
||||
s32 victimplayernum = random() % g_MpNumChrs;
|
||||
|
||||
for (j = 0, isnew = true; j < i; j++) {
|
||||
if (data->victims[j] == victimplayernum) {
|
||||
isnew = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (isnew) {
|
||||
data->victims[i] = victimplayernum;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
osSyncPrintf("PopACapReset -> Generated %d victims for this game : Listing\n", i);
|
||||
|
||||
for (j = 0; j < g_MpNumChrs; j++) {
|
||||
osSyncPrintf("PopACapReset -> Victim %d is player %d\n", j, data->victims[j]);
|
||||
}
|
||||
|
||||
osSyncPrintf("PopACapReset -> Done\n");
|
||||
}
|
||||
|
||||
void pacInit(void)
|
||||
{
|
||||
pacReset();
|
||||
}
|
||||
|
||||
void pacInitProps(void)
|
||||
{
|
||||
pacReset();
|
||||
}
|
||||
|
||||
bool pacHighlightProp(struct prop *prop, s32 *colour)
|
||||
{
|
||||
struct scenariodata_pac *data = &g_ScenarioData.pac;
|
||||
|
||||
if (g_MpSetup.options & MPOPTION_PAC_HIGHLIGHTTARGET
|
||||
&& (prop->type == PROPTYPE_PLAYER || prop->type == PROPTYPE_CHR)
|
||||
&& data->victimindex != -1
|
||||
&& prop->chr == g_MpAllChrPtrs[data->victims[data->victimindex]]) {
|
||||
colour[0] = 0;
|
||||
colour[1] = 0xff;
|
||||
colour[2] = 0;
|
||||
colour[3] = 0x40;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void pacApplyNextVictim(void)
|
||||
{
|
||||
struct scenariodata_pac *data = &g_ScenarioData.pac;
|
||||
s32 vplayernum;
|
||||
char text[64];
|
||||
s32 i;
|
||||
|
||||
data->victimindex++;
|
||||
|
||||
if (data->victimindex == g_MpNumChrs) {
|
||||
data->victimindex = 0;
|
||||
}
|
||||
|
||||
data->age240 = 0;
|
||||
|
||||
vplayernum = data->victims[data->victimindex];
|
||||
|
||||
for (i = 0; i < PLAYERCOUNT(); i++) {
|
||||
if (vplayernum == i) {
|
||||
sprintf(text, langGet(L_MPWEAPONS_013)); // "You are the victim!"
|
||||
} else if (scenarioChrsAreSameTeam(vplayernum, i)) {
|
||||
sprintf(text, langGet(L_MPWEAPONS_014), g_MpAllChrConfigPtrs[vplayernum]->name); // "Protect %s!"
|
||||
} else {
|
||||
sprintf(text, langGet(L_MPWEAPONS_015), g_MpAllChrConfigPtrs[vplayernum]->name); // "Get %s!"
|
||||
}
|
||||
|
||||
scenarioCreateHudmsg(i, text);
|
||||
}
|
||||
}
|
||||
|
||||
void pacHandleDeath(s32 aplayernum, s32 vplayernum)
|
||||
{
|
||||
struct scenariodata_pac *data = &g_ScenarioData.pac;
|
||||
|
||||
if (data->victimindex >= 0 && vplayernum == data->victims[data->victimindex]) {
|
||||
if (aplayernum != vplayernum) {
|
||||
if (aplayernum >= 0) {
|
||||
if (scenarioChrsAreSameTeam(aplayernum, vplayernum)) {
|
||||
scenarioCreateHudmsg(aplayernum, langGet(L_MPWEAPONS_008)); // "You're supposed to look"
|
||||
scenarioCreateHudmsg(aplayernum, langGet(L_MPWEAPONS_009)); // "after your friends!"
|
||||
} else {
|
||||
data->killcounts[aplayernum]++;
|
||||
scenarioCreateHudmsg(aplayernum, langGet(L_MPWEAPONS_010)); // "Well done!"
|
||||
scenarioCreateHudmsg(aplayernum, langGet(L_MPWEAPONS_011)); // "You popped a cap!"
|
||||
scenarioCreateHudmsg(aplayernum, langGet(L_MPWEAPONS_012)); // "Have 2 Points..."
|
||||
}
|
||||
}
|
||||
|
||||
pacApplyNextVictim();
|
||||
} else {
|
||||
#if VERSION >= VERSION_NTSC_1_0
|
||||
data->age240 = 0;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void pacTick(void)
|
||||
{
|
||||
struct scenariodata_pac *data = &g_ScenarioData.pac;
|
||||
|
||||
if (data->victimindex == -1) {
|
||||
pacApplyNextVictim();
|
||||
osSyncPrintf("PopACapTick : Current Victim = %d (Player %d)\n",
|
||||
data->victimindex, data->victims[data->victimindex]);
|
||||
}
|
||||
|
||||
if (data->victimindex >= 0) {
|
||||
#if VERSION >= VERSION_NTSC_1_0
|
||||
if (data->victims[data->victimindex] >= PLAYERCOUNT() ||
|
||||
g_Vars.players[data->victims[data->victimindex]]->isdead == false)
|
||||
#endif
|
||||
{
|
||||
data->age240 += g_Vars.lvupdate240;
|
||||
|
||||
if (data->age240 > (u32)PALDOWN(240 * 60)) {
|
||||
data->age240 = 0;
|
||||
data->survivalcounts[data->victims[data->victimindex]]++;
|
||||
scenarioCreateHudmsg(data->victims[data->victimindex], langGet(L_MPWEAPONS_007)); // "Have a point for living!"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Gfx *pacRenderHud(Gfx *gdl)
|
||||
{
|
||||
struct scenariodata_pac *data = &g_ScenarioData.pac;
|
||||
s32 time240;
|
||||
s32 mins;
|
||||
s32 secs;
|
||||
s32 textwidth;
|
||||
s32 textheight;
|
||||
s32 x;
|
||||
s32 y;
|
||||
char text[64];
|
||||
|
||||
#if VERSION >= VERSION_NTSC_1_0
|
||||
if (g_Vars.currentplayernum == data->victims[data->victimindex] && !g_Vars.currentplayer->isdead)
|
||||
#else
|
||||
if (g_Vars.currentplayernum == data->victims[data->victimindex])
|
||||
#endif
|
||||
{
|
||||
time240 = PALDOWN(60 * 240) - data->age240;
|
||||
x = viGetViewLeft() + viGetViewWidth() / 2;
|
||||
y = viGetViewTop() + 10;
|
||||
|
||||
if (time240 < 0) {
|
||||
time240 = 0;
|
||||
}
|
||||
|
||||
mins = time240 / PALDOWN(60 * 240);
|
||||
time240 -= PALDOWN(60 * 240) * mins;
|
||||
secs = (time240 + (PALDOWN(240) - 1)) / PALDOWN(240);
|
||||
sprintf(text, "%d:%02d", mins, secs);
|
||||
|
||||
gdl = func0f153628(gdl);
|
||||
textMeasure(&textheight, &textwidth, text, g_CharsHandelGothicXs, g_FontHandelGothicXs, 0);
|
||||
|
||||
x -= textwidth / 2;
|
||||
textwidth += x;
|
||||
textheight += y;
|
||||
|
||||
#if VERSION >= VERSION_NTSC_1_0
|
||||
gdl = func0f153990(gdl, x, y, textwidth, textheight);
|
||||
gdl = textRender(gdl, &x, &y, text, g_CharsNumeric, g_FontNumeric, 0x00ff00a0, 0xa0, viGetWidth(), viGetHeight(), 0, 0);
|
||||
#else
|
||||
gdl = func0f153858(gdl, &x, &y, &textwidth, &textheight);
|
||||
gdl = textRender(gdl, &x, &y, text, g_CharsNumeric, g_FontNumeric, 0x00ff00a0, 0x88, viGetWidth(), viGetHeight(), 0, 0);
|
||||
#endif
|
||||
gdl = func0f153780(gdl);
|
||||
}
|
||||
|
||||
return gdl;
|
||||
}
|
||||
|
||||
void pacCalculatePlayerScore(struct mpchrconfig *mpchr, s32 mpchrnum, s32 *score, s32 *arg3)
|
||||
{
|
||||
struct mpchrconfig *loopmpchr;
|
||||
s32 i;
|
||||
s32 index;
|
||||
|
||||
*score = 0;
|
||||
index = func0f18d0e8(mpchrnum);
|
||||
|
||||
if (index >= 0) {
|
||||
*score += g_ScenarioData.pac.killcounts[index] * 2;
|
||||
*score += g_ScenarioData.pac.survivalcounts[index];
|
||||
}
|
||||
|
||||
if (g_MpSetup.options & MPOPTION_KILLSSCORE) {
|
||||
for (i = 0; i != MAX_MPCHRS; i++) {
|
||||
if (i == mpchrnum) {
|
||||
*score -= mpchr->killcounts[i];
|
||||
} else if (g_MpSetup.options & MPOPTION_TEAMSENABLED) {
|
||||
loopmpchr = MPCHR(i);
|
||||
|
||||
if (loopmpchr->team == mpchr->team) {
|
||||
*score -= mpchr->killcounts[i];
|
||||
} else {
|
||||
*score += mpchr->killcounts[i];
|
||||
}
|
||||
} else {
|
||||
*score += mpchr->killcounts[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*arg3 = mpchr->numdeaths;
|
||||
}
|
||||
|
||||
Gfx *pacRadarExtra(Gfx *gdl)
|
||||
{
|
||||
return gdl;
|
||||
}
|
||||
|
||||
bool pacRadarChr(Gfx **gdl, struct prop *prop)
|
||||
{
|
||||
struct scenariodata_pac *data = &g_ScenarioData.pac;
|
||||
struct coord dist;
|
||||
|
||||
if ((g_MpSetup.options & MPOPTION_PAC_SHOWONRADAR) && data->victimindex >= 0) {
|
||||
struct prop *vprop = g_MpAllChrPtrs[data->victims[data->victimindex]]->prop;
|
||||
|
||||
if (vprop == prop) {
|
||||
dist.x = prop->pos.x - g_Vars.currentplayer->prop->pos.x;
|
||||
dist.y = prop->pos.y - g_Vars.currentplayer->prop->pos.y;
|
||||
dist.z = prop->pos.z - g_Vars.currentplayer->prop->pos.z;
|
||||
|
||||
if (g_MpSetup.options & MPOPTION_TEAMSENABLED) {
|
||||
u32 colour = g_TeamColours[radarGetTeamIndex(prop->chr->team)];
|
||||
*gdl = radarDrawDot(*gdl, vprop, &dist, colour, 0, 1);
|
||||
} else {
|
||||
*gdl = radarDrawDot(*gdl, vprop, &dist, 0x00ff0000, 0, 1);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
@ -6219,13 +6219,7 @@ s32 menuhandlerMpMaximumTeams(s32 operation, struct menuitem *item, union handle
|
|||
|
||||
for (i = 0; i != MAX_MPCHRS; i++) {
|
||||
if (g_MpSetup.chrslots & (1 << i)) {
|
||||
struct mpchrconfig *mpchr;
|
||||
|
||||
if (i < 4) {
|
||||
mpchr = &g_PlayerConfigsArray[i].base;
|
||||
} else {
|
||||
mpchr = &g_BotConfigsArray[i - 4].base;
|
||||
}
|
||||
struct mpchrconfig *mpchr = MPCHR(i);
|
||||
|
||||
mpchr->team = team++;
|
||||
|
||||
|
|
@ -6248,13 +6242,7 @@ s32 menuhandlerMpHumansVsSimulants(s32 operation, struct menuitem *item, union h
|
|||
|
||||
for (i = 0; i != MAX_MPCHRS; i++) {
|
||||
if (g_MpSetup.chrslots & (1 << i)) {
|
||||
struct mpchrconfig *mpchr;
|
||||
|
||||
if (i < 4) {
|
||||
mpchr = &g_PlayerConfigsArray[i].base;
|
||||
} else {
|
||||
mpchr = &g_BotConfigsArray[i - 4].base;
|
||||
}
|
||||
struct mpchrconfig *mpchr = MPCHR(i);
|
||||
|
||||
mpchr->team = i < 4 ? 0 : 1;
|
||||
}
|
||||
|
|
@ -6276,13 +6264,7 @@ s32 menuhandlerMpHumanSimulantPairs(s32 operation, struct menuitem *item, union
|
|||
|
||||
for (i = 0; i != MAX_MPCHRS; i++) {
|
||||
if (g_MpSetup.chrslots & (1 << i)) {
|
||||
struct mpchrconfig *mpchr;
|
||||
|
||||
if (i < 4) {
|
||||
mpchr = &g_PlayerConfigsArray[i].base;
|
||||
} else {
|
||||
mpchr = &g_BotConfigsArray[i - 4].base;
|
||||
}
|
||||
struct mpchrconfig *mpchr = MPCHR(i);
|
||||
|
||||
if (i < 4) {
|
||||
mpchr->team = team_ids[playerindex++];
|
||||
|
|
@ -8427,17 +8409,17 @@ glabel func0f17fa28
|
|||
/* f17fa68: 3c148008 */ lui $s4,%hi(g_MpChangeSimulantMenuDialog)
|
||||
/* f17fa6c: 3c158008 */ lui $s5,%hi(g_MpEditSimulantMenuDialog)
|
||||
/* f17fa70: 3c168008 */ lui $s6,%hi(g_MpCombatOptionsMenuDialog)
|
||||
/* f17fa74: 3c178008 */ lui $s7,%hi(g_MpBriefcaseOptionsMenuDialog)
|
||||
/* f17fa78: 3c1e8008 */ lui $s8,%hi(g_MpCaptureOptionsMenuDialog)
|
||||
/* f17fa7c: 3c098008 */ lui $t1,%hi(g_MpPopacapOptionsMenuDialog)
|
||||
/* f17fa80: 3c088008 */ lui $t0,%hi(g_MpHackerOptionsMenuDialog)
|
||||
/* f17fa84: 3c078008 */ lui $a3,%hi(g_MpHillOptionsMenuDialog)
|
||||
/* f17fa74: 3c178008 */ lui $s7,%hi(g_HtbOptionsMenuDialog)
|
||||
/* f17fa78: 3c1e8008 */ lui $s8,%hi(g_CtcOptionsMenuDialog)
|
||||
/* f17fa7c: 3c098008 */ lui $t1,%hi(g_PacOptionsMenuDialog)
|
||||
/* f17fa80: 3c088008 */ lui $t0,%hi(g_HtmOptionsMenuDialog)
|
||||
/* f17fa84: 3c078008 */ lui $a3,%hi(g_KohOptionsMenuDialog)
|
||||
/* f17fa88: afb00018 */ sw $s0,0x18($sp)
|
||||
/* f17fa8c: 24e76ce0 */ addiu $a3,$a3,%lo(g_MpHillOptionsMenuDialog)
|
||||
/* f17fa90: 25086dfc */ addiu $t0,$t0,%lo(g_MpHackerOptionsMenuDialog)
|
||||
/* f17fa94: 25296f80 */ addiu $t1,$t1,%lo(g_MpPopacapOptionsMenuDialog)
|
||||
/* f17fa98: 27de6b48 */ addiu $s8,$s8,%lo(g_MpCaptureOptionsMenuDialog)
|
||||
/* f17fa9c: 26f769d4 */ addiu $s7,$s7,%lo(g_MpBriefcaseOptionsMenuDialog)
|
||||
/* f17fa8c: 24e76ce0 */ addiu $a3,$a3,%lo(g_KohOptionsMenuDialog)
|
||||
/* f17fa90: 25086dfc */ addiu $t0,$t0,%lo(g_HtmOptionsMenuDialog)
|
||||
/* f17fa94: 25296f80 */ addiu $t1,$t1,%lo(g_PacOptionsMenuDialog)
|
||||
/* f17fa98: 27de6b48 */ addiu $s8,$s8,%lo(g_CtcOptionsMenuDialog)
|
||||
/* f17fa9c: 26f769d4 */ addiu $s7,$s7,%lo(g_HtbOptionsMenuDialog)
|
||||
/* f17faa0: 26d668b8 */ addiu $s6,$s6,%lo(g_MpCombatOptionsMenuDialog)
|
||||
/* f17faa4: 26b5592c */ addiu $s5,$s5,%lo(g_MpEditSimulantMenuDialog)
|
||||
/* f17faa8: 26945834 */ addiu $s4,$s4,%lo(g_MpChangeSimulantMenuDialog)
|
||||
|
|
@ -8558,14 +8540,14 @@ glabel func0f17fa28
|
|||
/* f17fc30: 00000000 */ nop
|
||||
/* f17fc34: 0fc3cdb7 */ jal menuPopDialog
|
||||
/* f17fc38: 00000000 */ nop
|
||||
/* f17fc3c: 3c078008 */ lui $a3,%hi(g_MpHillOptionsMenuDialog)
|
||||
/* f17fc40: 3c088008 */ lui $t0,%hi(g_MpHackerOptionsMenuDialog)
|
||||
/* f17fc44: 3c098008 */ lui $t1,%hi(g_MpPopacapOptionsMenuDialog)
|
||||
/* f17fc3c: 3c078008 */ lui $a3,%hi(g_KohOptionsMenuDialog)
|
||||
/* f17fc40: 3c088008 */ lui $t0,%hi(g_HtmOptionsMenuDialog)
|
||||
/* f17fc44: 3c098008 */ lui $t1,%hi(g_PacOptionsMenuDialog)
|
||||
/* f17fc48: 3c1f8007 */ lui $ra,%hi(g_MpPlayerNum)
|
||||
/* f17fc4c: 27ff1448 */ addiu $ra,$ra,%lo(g_MpPlayerNum)
|
||||
/* f17fc50: 25296f80 */ addiu $t1,$t1,%lo(g_MpPopacapOptionsMenuDialog)
|
||||
/* f17fc54: 25086dfc */ addiu $t0,$t0,%lo(g_MpHackerOptionsMenuDialog)
|
||||
/* f17fc58: 24e76ce0 */ addiu $a3,$a3,%lo(g_MpHillOptionsMenuDialog)
|
||||
/* f17fc50: 25296f80 */ addiu $t1,$t1,%lo(g_PacOptionsMenuDialog)
|
||||
/* f17fc54: 25086dfc */ addiu $t0,$t0,%lo(g_HtmOptionsMenuDialog)
|
||||
/* f17fc58: 24e76ce0 */ addiu $a3,$a3,%lo(g_KohOptionsMenuDialog)
|
||||
.L0f17fc5c:
|
||||
/* f17fc5c: 5200ffa7 */ beqzl $s0,.L0f17fafc
|
||||
/* f17fc60: 8fe20000 */ lw $v0,0x0($ra)
|
||||
|
|
|
|||
|
|
@ -178,11 +178,7 @@ void mpstatsRecordPlayerSuicide(void)
|
|||
time = getMissionTime();
|
||||
mpindex = g_Vars.currentplayerstats->mpindex;
|
||||
|
||||
if (mpindex < 4) {
|
||||
mpchr = &g_PlayerConfigsArray[mpindex].base;
|
||||
} else {
|
||||
mpchr = &g_BotConfigsArray[mpindex - 4].base;
|
||||
}
|
||||
mpchr = MPCHR(mpindex);
|
||||
|
||||
// Show HUD message
|
||||
// "Suicide count: %d"
|
||||
|
|
@ -238,7 +234,7 @@ void mpstatsRecordDeath(s32 aplayernum, s32 vplayernum)
|
|||
char text[256];
|
||||
|
||||
if (g_Vars.normmplayerisrunning && g_MpSetup.scenario == MPSCENARIO_POPACAP) {
|
||||
scenarioPacHandleDeath(aplayernum, vplayernum);
|
||||
pacHandleDeath(aplayernum, vplayernum);
|
||||
}
|
||||
|
||||
// Find attacker and victim mpchrs
|
||||
|
|
@ -246,11 +242,7 @@ void mpstatsRecordDeath(s32 aplayernum, s32 vplayernum)
|
|||
ampindex = func0f18d074(aplayernum);
|
||||
|
||||
if (ampindex >= 0) {
|
||||
if (ampindex < 4) {
|
||||
ampchr = &g_PlayerConfigsArray[ampindex].base;
|
||||
} else {
|
||||
ampchr = &g_BotConfigsArray[ampindex - 4].base;
|
||||
}
|
||||
ampchr = MPCHR(ampindex);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -258,11 +250,7 @@ void mpstatsRecordDeath(s32 aplayernum, s32 vplayernum)
|
|||
vmpindex = func0f18d074(vplayernum);
|
||||
|
||||
if (vmpindex >= 0) {
|
||||
if (vmpindex < 4) {
|
||||
vmpchr = &g_PlayerConfigsArray[vmpindex].base;
|
||||
} else {
|
||||
vmpchr = &g_BotConfigsArray[vmpindex - 4].base;
|
||||
}
|
||||
vmpchr = MPCHR(vmpindex);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3340,7 +3340,7 @@ glabel var7f1aa1d8
|
|||
/* f0692ac: 27a70050 */ addiu $a3,$sp,0x50
|
||||
/* f0692b0: 460a8481 */ sub.s $f18,$f16,$f10
|
||||
/* f0692b4: e7b2005c */ swc1 $f18,0x5c($sp)
|
||||
/* f0692b8: 0fc6192e */ jal scenarioCallback38
|
||||
/* f0692b8: 0fc6192e */ jal scenarioHighlightRoom
|
||||
/* f0692bc: 85c40028 */ lh $a0,0x28($t6)
|
||||
/* f0692c0: 920f0000 */ lbu $t7,0x0($s0)
|
||||
/* f0692c4: 8fb80058 */ lw $t8,0x58($sp)
|
||||
|
|
@ -3684,7 +3684,7 @@ glabel var7f1aa1d8
|
|||
/* f068518: 27a70050 */ addiu $a3,$sp,0x50
|
||||
/* f06851c: 460a8481 */ sub.s $f18,$f16,$f10
|
||||
/* f068520: e7b2005c */ swc1 $f18,0x5c($sp)
|
||||
/* f068524: 0fc60248 */ jal scenarioCallback38
|
||||
/* f068524: 0fc60248 */ jal scenarioHighlightRoom
|
||||
/* f068528: 85c40028 */ lh $a0,0x28($t6)
|
||||
/* f06852c: 920f0000 */ lbu $t7,0x0($s0)
|
||||
/* f068530: 8fb80058 */ lw $t8,0x58($sp)
|
||||
|
|
@ -52709,7 +52709,7 @@ glabel var7f1aa82c
|
|||
/* f0818b0: 8cca0318 */ lw $t2,0x318($a2)
|
||||
/* f0818b4: 51400006 */ beqzl $t2,.L0f0818d0
|
||||
/* f0818b8: 8cc20284 */ lw $v0,0x284($a2)
|
||||
/* f0818bc: 0fc61788 */ jal scenarioHighlight
|
||||
/* f0818bc: 0fc61788 */ jal scenarioHighlightProp
|
||||
/* f0818c0: 8fa400f8 */ lw $a0,0xf8($sp)
|
||||
/* f0818c4: 3c06800a */ lui $a2,%hi(g_Vars)
|
||||
/* f0818c8: 24c69fc0 */ addiu $a2,$a2,%lo(g_Vars)
|
||||
|
|
@ -53344,7 +53344,7 @@ glabel var7f1aa82c
|
|||
/* f0818b0: 8cca0318 */ lw $t2,0x318($a2)
|
||||
/* f0818b4: 51400006 */ beqzl $t2,.L0f0818d0
|
||||
/* f0818b8: 8cc20284 */ lw $v0,0x284($a2)
|
||||
/* f0818bc: 0fc61788 */ jal scenarioHighlight
|
||||
/* f0818bc: 0fc61788 */ jal scenarioHighlightProp
|
||||
/* f0818c0: 8fa400f8 */ lw $a0,0xf8($sp)
|
||||
/* f0818c4: 3c06800a */ lui $a2,%hi(g_Vars)
|
||||
/* f0818c8: 24c69fc0 */ addiu $a2,$a2,%lo(g_Vars)
|
||||
|
|
@ -53755,7 +53755,7 @@ glabel var7f1aa82c
|
|||
// }
|
||||
//
|
||||
// if (g_Vars.normmplayerisrunning) {
|
||||
// scenarioHighlight(prop, colour);
|
||||
// scenarioHighlightProp(prop, colour);
|
||||
// }
|
||||
//
|
||||
// if (g_Vars.currentplayer->visionmode == VISIONMODE_XRAY) {
|
||||
|
|
@ -61018,7 +61018,7 @@ bool propobjInteract(struct prop *prop)
|
|||
}
|
||||
|
||||
if (g_Vars.normmplayerisrunning) {
|
||||
scenarioHtmActivateUplink(g_Vars.currentplayer->prop->chr, prop);
|
||||
scenarioHandleActivatedProp(g_Vars.currentplayer->prop->chr, prop);
|
||||
} else {
|
||||
if (g_Vars.currentplayernum == g_Vars.coopplayernum) {
|
||||
obj->hidden |= OBJHFLAG_ACTIVATED_BY_COOP;
|
||||
|
|
@ -62731,7 +62731,7 @@ glabel var7f1aae70
|
|||
/* f088a94: 8d0f04cc */ lw $t7,0x4cc($t0)
|
||||
/* f088a98: 8c4c00bc */ lw $t4,0xbc($v0)
|
||||
/* f088a9c: 8fa500a0 */ lw $a1,0xa0($sp)
|
||||
/* f088aa0: 0fc61d04 */ jal chrGiveUplink
|
||||
/* f088aa0: 0fc61d04 */ jal scenarioPickUpUplink
|
||||
/* f088aa4: 8d840004 */ lw $a0,0x4($t4)
|
||||
/* f088aa8: 10400006 */ beqz $v0,.L0f088ac4
|
||||
/* f088aac: 00401825 */ or $v1,$v0,$zero
|
||||
|
|
@ -63378,7 +63378,7 @@ glabel var7f1aae70
|
|||
/* f088a94: 8d0f04cc */ lw $t7,0x4cc($t0)
|
||||
/* f088a98: 8c4c00bc */ lw $t4,0xbc($v0)
|
||||
/* f088a9c: 8fa500a0 */ lw $a1,0xa0($sp)
|
||||
/* f088aa0: 0fc61d04 */ jal chrGiveUplink
|
||||
/* f088aa0: 0fc61d04 */ jal scenarioPickUpUplink
|
||||
/* f088aa4: 8d840004 */ lw $a0,0x4($t4)
|
||||
/* f088aa8: 10400006 */ beqz $v0,.L0f088ac4
|
||||
/* f088aac: 00401825 */ or $v1,$v0,$zero
|
||||
|
|
@ -64025,7 +64025,7 @@ glabel var7f1aae70
|
|||
/* f088a94: 8d0f04cc */ lw $t7,0x4cc($t0)
|
||||
/* f088a98: 8c4c00bc */ lw $t4,0xbc($v0)
|
||||
/* f088a9c: 8fa500a0 */ lw $a1,0xa0($sp)
|
||||
/* f088aa0: 0fc61d04 */ jal chrGiveUplink
|
||||
/* f088aa0: 0fc61d04 */ jal scenarioPickUpUplink
|
||||
/* f088aa4: 8d840004 */ lw $a0,0x4($t4)
|
||||
/* f088aa8: 10400006 */ beqz $v0,.L0f088ac4
|
||||
/* f088aac: 00401825 */ or $v1,$v0,$zero
|
||||
|
|
@ -64500,7 +64500,7 @@ glabel var7f1aae70
|
|||
// }
|
||||
//
|
||||
// if (weapon->weaponnum == WEAPON_DATAUPLINK) {
|
||||
// result = chrGiveUplink(g_Vars.currentplayer->prop->chr, prop);
|
||||
// result = scenarioPickUpUplink(g_Vars.currentplayer->prop->chr, prop);
|
||||
//
|
||||
// if (result) {
|
||||
// weaponPlayPickupSound(weapon->weaponnum);
|
||||
|
|
@ -69892,7 +69892,7 @@ void weaponCreateForPlayerDrop(s32 weaponnum)
|
|||
objDrop(prop, true);
|
||||
|
||||
if (weaponnum == WEAPON_BRIEFCASE2) {
|
||||
scenarioReleaseToken(chr, prop);
|
||||
scenarioHandleDroppedToken(chr, prop);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -331,7 +331,7 @@ Gfx *radarRender(Gfx *gdl)
|
|||
if (i != playernum) {
|
||||
if (g_Vars.players[i]->isdead == false
|
||||
&& (g_Vars.players[i]->prop->chr->hidden & CHRHFLAG_CLOAKED) == 0
|
||||
&& scenarioRadar2(&gdl, g_Vars.players[i]->prop) == false) {
|
||||
&& scenarioRadarChr(&gdl, g_Vars.players[i]->prop) == false) {
|
||||
pos.x = g_Vars.players[i]->prop->pos.x - g_Vars.currentplayer->prop->pos.x;
|
||||
pos.y = g_Vars.players[i]->prop->pos.y - g_Vars.currentplayer->prop->pos.y;
|
||||
pos.z = g_Vars.players[i]->prop->pos.z - g_Vars.currentplayer->prop->pos.z;
|
||||
|
|
@ -372,7 +372,7 @@ Gfx *radarRender(Gfx *gdl)
|
|||
for (i = 0; i < g_BotCount; i++) {
|
||||
if (!chrIsDead(g_MpBotChrPtrs[i])
|
||||
&& (g_MpBotChrPtrs[i]->hidden & CHRHFLAG_CLOAKED) == 0
|
||||
&& scenarioRadar2(&gdl, g_MpBotChrPtrs[i]->prop) == false) {
|
||||
&& scenarioRadarChr(&gdl, g_MpBotChrPtrs[i]->prop) == false) {
|
||||
pos.x = g_MpBotChrPtrs[i]->prop->pos.x - g_Vars.currentplayer->prop->pos.x;
|
||||
pos.y = g_MpBotChrPtrs[i]->prop->pos.y - g_Vars.currentplayer->prop->pos.y;
|
||||
pos.z = g_MpBotChrPtrs[i]->prop->pos.z - g_Vars.currentplayer->prop->pos.z;
|
||||
|
|
@ -388,7 +388,7 @@ Gfx *radarRender(Gfx *gdl)
|
|||
}
|
||||
}
|
||||
|
||||
gdl = scenarioRadar(gdl);
|
||||
gdl = scenarioRadarExtra(gdl);
|
||||
|
||||
// Draw dots for r-tracked props
|
||||
if (g_Vars.currentplayer->devicesactive & ~g_Vars.currentplayer->devicesinhibit & DEVICE_RTRACKER) {
|
||||
|
|
@ -396,7 +396,7 @@ Gfx *radarRender(Gfx *gdl)
|
|||
}
|
||||
|
||||
// Draw dot for the current player
|
||||
if (scenarioRadar2(&gdl, g_Vars.currentplayer->prop) == 0) {
|
||||
if (scenarioRadarChr(&gdl, g_Vars.currentplayer->prop) == false) {
|
||||
pos.x = 0;
|
||||
pos.y = 0;
|
||||
pos.z = 0;
|
||||
|
|
|
|||
|
|
@ -489,12 +489,11 @@ extern struct menudialog g_MpQuickTeamGameSetupMenuDialog;
|
|||
extern struct menudialog g_MpQuickTeamMenuDialog;
|
||||
extern struct menudialog g_CombatSimulatorMenuDialog;
|
||||
extern struct menudialog g_MpCombatOptionsMenuDialog;
|
||||
extern struct menudialog g_MpBriefcaseOptionsMenuDialog;
|
||||
extern struct menudialog g_MpCaptureOptionsMenuDialog;
|
||||
extern struct menudialog g_MpHillOptionsMenuDialog;
|
||||
extern struct menudialog g_MpHackerOptionsMenuDialog;
|
||||
extern struct menudialog g_MpPopacapOptionsMenuDialog;
|
||||
extern struct mpscenariooverview g_MpScenarioOverviews[];
|
||||
extern struct menudialog g_HtbOptionsMenuDialog;
|
||||
extern struct menudialog g_CtcOptionsMenuDialog;
|
||||
extern struct menudialog g_KohOptionsMenuDialog;
|
||||
extern struct menudialog g_HtmOptionsMenuDialog;
|
||||
extern struct menudialog g_PacOptionsMenuDialog;
|
||||
extern struct menudialog g_MpScenarioMenuDialog;
|
||||
extern struct menudialog g_MpQuickTeamScenarioMenuDialog;
|
||||
extern s32 var80087260;
|
||||
|
|
|
|||
|
|
@ -7,55 +7,27 @@
|
|||
extern struct menudialog g_MpScenarioMenuDialog;
|
||||
extern struct menudialog g_MpQuickTeamScenarioMenuDialog;
|
||||
|
||||
void scenarioHtbInit(void);
|
||||
s32 scenarioHtbCallback08(void);
|
||||
void scenarioHtbReset(void);
|
||||
void scenarioHtbTick(void);
|
||||
void scenarioHtbCallback14(struct chrdata *chr);
|
||||
void scenarioHtbCalculatePlayerScore(struct mpchrconfig *mpchr, s32 mpchrnum, s32 *score, s32 *deaths);
|
||||
Gfx *scenarioHtbRadar(Gfx *gdl);
|
||||
bool scenarioHtbRadar2(Gfx **gdl, struct prop *prop);
|
||||
bool scenarioHtbHighlight(struct prop *prop, s32 *colour);
|
||||
void scenarioCtcInit(void);
|
||||
s32 scenarioCtcCallback08(void);
|
||||
void scenarioCtcTick(void);
|
||||
void scenarioCtcCallback14(struct chrdata *chr);
|
||||
void scenarioCtcCalculatePlayerScore(struct mpchrconfig *mpchr, s32 mpchrnum, s32 *score, s32 *deaths);
|
||||
Gfx *scenarioCtcRadar(Gfx *gdl);
|
||||
bool scenarioCtcRadar2(Gfx **gdl, struct prop *prop);
|
||||
bool scenarioCtcChooseSpawnLocation(f32 arg0, struct coord *pos, s16 *rooms, struct prop *prop, f32 *arg4);
|
||||
s32 scenarioCtcGetMaxTeams(void);
|
||||
bool scenarioCtcIsRoomHighlighted(s16 room);
|
||||
s32 menuhandlerMpHillTime(s32 operation, struct menuitem *item, union handlerdata *data);
|
||||
void scenarioKohReadSave(struct savebuffer *buffer);
|
||||
void scenarioKohWriteSave(struct savebuffer *buffer);
|
||||
void scenarioKohInit(void);
|
||||
void scenarioKohReset(void);
|
||||
void scenarioKohCalculatePlayerScore(struct mpchrconfig *mpchr, s32 mpchrnum, s32 *score, s32 *deaths);
|
||||
Gfx *scenarioKohRadar(Gfx *gdl);
|
||||
bool scenarioKohIsRoomHighlighted(s16 arg0);
|
||||
void scenarioHtmInit(void);
|
||||
s32 scenarioHtmCallback08(void);
|
||||
void scenarioHtmTick(void);
|
||||
void scenarioHtmCalculatePlayerScore(struct mpchrconfig *mpchr, s32 mpchrnum, s32 *score, s32 *deaths);
|
||||
bool scenarioHtmRadar2(Gfx **gdl, struct prop *prop);
|
||||
bool scenarioHtmHighlight(struct prop *prop, s32 *colour);
|
||||
void scenarioPacInit(void);
|
||||
void scenarioPacReset(void);
|
||||
void scenarioPacCalculatePlayerScore(struct mpchrconfig *mpchr, s32 mpchrnum, s32 *score, s32 *deaths);
|
||||
Gfx *scenarioPacRadar(Gfx *gdl);
|
||||
struct mpscenariooverview {
|
||||
u16 name;
|
||||
u16 shortname;
|
||||
u8 requirefeature;
|
||||
u8 teamonly;
|
||||
};
|
||||
|
||||
extern struct mpscenariooverview g_MpScenarioOverviews[6];
|
||||
|
||||
s32 menuhandlerMpOpenOptions(s32 operation, struct menuitem *item, union handlerdata *data);
|
||||
void scenarioReadSave(struct savebuffer *buffer);
|
||||
void scenarioWriteSave(struct savebuffer *buffer);
|
||||
void scenarioInit(void);
|
||||
s32 scenarioCallback08(void);
|
||||
void scenarioReset(void);
|
||||
s32 scenarioNumProps(void);
|
||||
void scenarioInitProps(void);
|
||||
void scenarioTick(void);
|
||||
void scenarioCallback14(struct chrdata *chr);
|
||||
Gfx *scenarioRadar(Gfx *gdl);
|
||||
bool scenarioRadar2(Gfx **gdl, struct prop *prop);
|
||||
void scenarioTickChr(struct chrdata *chr);
|
||||
Gfx *scenarioRadarExtra(Gfx *gdl);
|
||||
bool scenarioRadarChr(Gfx **gdl, struct prop *prop);
|
||||
f32 scenarioChooseSpawnLocation(f32 arg0, struct coord *pos, s16 *rooms, struct prop *prop);
|
||||
s32 scenarioGetMaxTeams(void);
|
||||
void scenarioCallback38(s16 arg0, s32 *arg1, s32 *arg2, s32 *arg3);
|
||||
void scenarioHighlightRoom(s16 room, s32 *arg1, s32 *arg2, s32 *arg3);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -73,49 +73,49 @@ s32 mpQuickTeamSimulantDifficultyHandler(s32 operation, struct menuitem *item, u
|
|||
u32 func0f17fa28(void);
|
||||
void func0f17fcb0(s32 silent);
|
||||
s32 menuhandlerMpSlowMotion(s32 operation, struct menuitem *item, union handlerdata *data);
|
||||
void mpHtbAddPad(s16 padnum);
|
||||
void scenarioHtmRemoveAmmoCrateAtPad(s16 padnum);
|
||||
void func0f180078(void);
|
||||
void scenarioHtbCreateToken(void);
|
||||
Gfx *scenarioHtbRenderHud(Gfx *gdl);
|
||||
void scenarioCtcReset(void);
|
||||
bool scenarioCtcHighlight(struct prop *prop, s32 *colour);
|
||||
void mpCtcAddPad(s32 *cmd);
|
||||
void scenarioCtcCallback38(s16 roomnum, s32 *arg1, s32 *arg2, s32 *arg3);
|
||||
void scenarioKohTick(void);
|
||||
Gfx *scenarioKohRenderHud(Gfx *gdl);
|
||||
void mpKohAddHill(s32 *cmd);
|
||||
void scenarioKohCallback38(s16 roomnum, s32 *arg1, s32 *arg2, s32 *arg3);
|
||||
void mpHtmAddPad(s16 padnum);
|
||||
void func0f182bf4(void);
|
||||
void scenarioHtmCreateUplink(void);
|
||||
void scenarioHtmReset(void);
|
||||
void scenarioHtmCallback14(struct chrdata *chr);
|
||||
Gfx *scenarioHtmRenderHud(Gfx *gdl);
|
||||
Gfx *scenarioHtmRadar(Gfx *gdl);
|
||||
void scenarioPacChooseVictims(void);
|
||||
bool scenarioPacHighlight(struct prop *prop, s32 *colour);
|
||||
void scenarioPacApplyNextVictim(void);
|
||||
void scenarioPacHandleDeath(s32 cplayernum, s32 vplayernum);
|
||||
void scenarioPacTick(void);
|
||||
Gfx *scenarioPacRenderHud(Gfx *gdl);
|
||||
bool scenarioPacRadar2(Gfx **gdl, struct prop *prop);
|
||||
void htbAddPad(s16 padnum);
|
||||
void htbRemoveAmmoCrateAtPad(s16 padnum);
|
||||
void htbReset(void);
|
||||
void htbCreateToken(void);
|
||||
Gfx *htbRenderHud(Gfx *gdl);
|
||||
void ctcInitProps(void);
|
||||
bool ctcHighlightProp(struct prop *prop, s32 *colour);
|
||||
void ctcAddPad(s32 *cmd);
|
||||
void ctcHighlightRoom(s16 roomnum, s32 *arg1, s32 *arg2, s32 *arg3);
|
||||
void kohTick(void);
|
||||
Gfx *kohRenderHud(Gfx *gdl);
|
||||
void kohAddHill(s32 *cmd);
|
||||
void kohHighlightRoom(s16 roomnum, s32 *arg1, s32 *arg2, s32 *arg3);
|
||||
void htmAddPad(s16 padnum);
|
||||
void htmReset(void);
|
||||
void htbCreateUplink(void);
|
||||
void htmInitProps(void);
|
||||
void htmTickChr(struct chrdata *chr);
|
||||
Gfx *htmRenderHud(Gfx *gdl);
|
||||
Gfx *htmRadarExtra(Gfx *gdl);
|
||||
void pacReset(void);
|
||||
bool pacHighlightProp(struct prop *prop, s32 *colour);
|
||||
void pacApplyNextVictim(void);
|
||||
void pacHandleDeath(s32 cplayernum, s32 vplayernum);
|
||||
void pacTick(void);
|
||||
Gfx *pacRenderHud(Gfx *gdl);
|
||||
bool pacRadarChr(Gfx **gdl, struct prop *prop);
|
||||
s32 mpOptionsMenuDialog(s32 operation, struct menudialog *dialog, union handlerdata *data);
|
||||
char *mpMenuTextScenarioShortName(struct menuitem *item);
|
||||
char *mpMenuTextScenarioName(struct menuitem *item);
|
||||
s32 scenarioScenarioMenuHandler(s32 operation, struct menuitem *item, union handlerdata *data);
|
||||
void mpCreateMatchStartHudmsgs(void);
|
||||
void scenarioCreateMatchStartHudmsgs(void);
|
||||
Gfx *scenarioRenderHud(Gfx *gdl);
|
||||
void scenarioCalculatePlayerScore(struct mpchrconfig *mpchr, s32 chrnum, s32 *arg2, s32 *arg3);
|
||||
bool scenarioHighlight(struct prop *prop, s32 *colour);
|
||||
void mpPrepareScenario(void);
|
||||
bool scenarioHighlightProp(struct prop *prop, s32 *colour);
|
||||
void scenarioReset(void);
|
||||
struct prop *scenarioCreateObj(s32 modelnum, s16 padnum, f32 arg2, u32 flags, u32 flags2, u32 flags3);
|
||||
void mpCreateScenarioHudmsg(s32 playernum, char *message);
|
||||
bool mpChrsAreSameTeam(s32 arg0, s32 arg1);
|
||||
void scenarioCreateHudmsg(s32 playernum, char *message);
|
||||
bool scenarioChrsAreSameTeam(s32 playernum1, s32 playernum2);
|
||||
s32 scenarioPickUpBriefcase(struct chrdata *chr, struct prop *prop);
|
||||
void scenarioReleaseToken(struct chrdata *chr, struct prop *prop);
|
||||
s32 chrGiveUplink(struct chrdata *chr, struct prop *prop);
|
||||
void scenarioHtmActivateUplink(struct chrdata *chr, struct prop *prop);
|
||||
void scenarioHandleDroppedToken(struct chrdata *chr, struct prop *prop);
|
||||
s32 scenarioPickUpUplink(struct chrdata *chr, struct prop *prop);
|
||||
void scenarioHandleActivatedProp(struct chrdata *chr, struct prop *prop);
|
||||
s32 menuhandlerMpDropOut(s32 operation, struct menuitem *item, union handlerdata *data);
|
||||
s32 menuhandlerMpTeamsLabel(s32 operation, struct menuitem *item, union handlerdata *data);
|
||||
s32 mpGetNumStages(void);
|
||||
|
|
|
|||
|
|
@ -4673,34 +4673,6 @@ struct savebuffer {
|
|||
u8 bytes[220];
|
||||
};
|
||||
|
||||
struct mpscenario {
|
||||
struct menudialog *optionsdialog;
|
||||
void (*initfunc)(void);
|
||||
s32 (*unk08)(void);
|
||||
void (*resetfunc)(void);
|
||||
void (*tickfunc)(void);
|
||||
void (*unk14)(struct chrdata *chr);
|
||||
Gfx *(*hudfunc)(Gfx *gdl);
|
||||
void (*calcscorefunc)(struct mpchrconfig *mpchr, s32 chrnum, s32 *score, s32 *deaths);
|
||||
Gfx *(*radarfunc)(Gfx *gdl);
|
||||
bool (*radar2func)(Gfx **gdl, struct prop *prop);
|
||||
bool (*highlightfunc)(struct prop *prop, s32 *colour);
|
||||
bool (*spawnfunc)(f32 arg0, struct coord *pos, s16 *rooms, struct prop *prop, f32 *arg4);
|
||||
s32 (*maxteamsfunc)(void);
|
||||
bool (*isroomhighlightedfunc)(s16 room);
|
||||
void (*unk38)(s16 arg0, s32 *arg1, s32 *arg2, s32 *arg3);
|
||||
void *unk3c;
|
||||
void (*readsavefunc)(struct savebuffer *buffer);
|
||||
void (*writesavefunc)(struct savebuffer *buffer);
|
||||
};
|
||||
|
||||
struct mpscenariooverview {
|
||||
u16 name;
|
||||
u16 shortname;
|
||||
u8 requirefeature;
|
||||
u8 teamonly;
|
||||
};
|
||||
|
||||
struct mparena {
|
||||
s16 stagenum;
|
||||
u8 requirefeature;
|
||||
|
|
@ -4768,8 +4740,8 @@ struct htmterminal {
|
|||
};
|
||||
|
||||
struct scenariodata_htm {
|
||||
/*0x800ac110*/ s16 nextindex;
|
||||
/*0x800ac112*/ s16 unk002;
|
||||
/*0x800ac110*/ s16 numpads;
|
||||
/*0x800ac112*/ s16 numterminals;
|
||||
/*0x800ac114*/ s16 padnums[60];
|
||||
/*0x800ac18c*/ struct htmterminal terminals[7]; // only the first element is used
|
||||
/*0x800ac1e0*/ s16 dlplayernum;
|
||||
|
|
@ -4780,6 +4752,7 @@ struct scenariodata_htm {
|
|||
/*0x800ac248*/ u32 unk138;
|
||||
/*0x800ac24c*/ struct prop *uplink;
|
||||
/*0x800ac250*/ u32 unk140;
|
||||
/*0x800ac250*/ u32 unk144;
|
||||
};
|
||||
|
||||
struct scenariodata_pac {
|
||||
|
|
@ -4787,8 +4760,8 @@ struct scenariodata_pac {
|
|||
u16 age240;
|
||||
s32 victimindex;
|
||||
s16 victims[12]; // shuffled list of player numbers
|
||||
s16 unk20[12];
|
||||
s16 wincounts[12]; // indexed by player num
|
||||
s16 killcounts[12]; // indexed by player num
|
||||
s16 survivalcounts[12]; // indexed by player num
|
||||
};
|
||||
|
||||
struct scenariodata_koh {
|
||||
|
|
|
|||
Loading…
Reference in New Issue