perfect_dark/src/game/activemenu/tick.c

405 lines
10 KiB
C

#include <ultra64.h>
#include "constants.h"
#include "game/activemenu/activemenu.h"
#include "game/game_01b0a0.h"
#include "game/game_097ba0.h"
#include "game/game_0b0fd0.h"
#include "game/inventory/inventory.h"
#include "game/game_127910.h"
#include "game/options.h"
#include "gvars/gvars.h"
#include "lib/controller.h"
#include "data.h"
#include "types.h"
void amTick(void)
{
s32 prevplayernum = g_Vars.currentplayernum;
s32 i;
for (i = 0; i < PLAYERCOUNT(); i++) {
setCurrentPlayerNum(i);
g_AmIndex = g_Vars.currentplayernum;
if (g_AmMenus[g_AmIndex].togglefunc) {
if (currentPlayerConsiderToggleGunFunction(60, false, 1) > 0) {
g_AmMenus[g_AmIndex].togglefunc = false;
}
} else {
// empty
}
if (g_Vars.normmplayerisrunning == false
&& invGetCount() != g_AmMenus[g_AmIndex].numitems) {
amAssignWeaponSlots();
}
if (g_Vars.currentplayer->activemenumode != AMMODE_CLOSED) {
s32 controlmode = optionsGetControlMode(g_Vars.currentplayerstats->mpindex);
s8 contpadnum = optionsGetContpadNum1(g_Vars.currentplayerstats->mpindex);
s32 numsamples = contGetNumSamples();
s32 j;
for (j = 0; j < numsamples; j++) {
s8 gotonextscreen = false;
s8 cstickx = contGetStickXOnSample(j, contpadnum);
s8 csticky = contGetStickYOnSample(j, contpadnum);
s8 absstickx;
s8 abssticky;
u16 buttonsstate = contGetButtonsOnSample(j, contpadnum, 0xffff);
u16 buttonspressed = contGetButtonsPressedOnSample(j, contpadnum, 0xffff);
bool stickpushed = false;
s32 slotnum;
bool stayopen;
bool toggle;
s32 row;
s32 column;
column = 1;
row = 1;
stayopen = false;
toggle = false;
g_AmMenus[g_AmIndex].allbots = false;
if (g_Vars.currentplayer->activemenumode == AMMODE_EDIT) {
buttonsstate = buttonsstate & A_BUTTON;
cstickx = 0;
csticky = 0;
buttonspressed = 0;
}
if (controlmode == CONTROLMODE_13 || controlmode == CONTROLMODE_14) {
if ((buttonsstate & R_TRIG) || (buttonsstate & L_TRIG)) {
stayopen = true;
}
if (buttonsstate & A_BUTTON) {
g_AmMenus[g_AmIndex].allbots = true;
}
} else {
if (buttonsstate & A_BUTTON) {
stayopen = true;
}
if ((buttonsstate & R_TRIG) || (buttonsstate & L_TRIG)) {
g_AmMenus[g_AmIndex].allbots = true;
}
}
// If entering allbots mode, save current screen
if (g_AmMenus[g_AmIndex].allbots
&& g_AmMenus[g_AmIndex].screenindex >= 2
&& g_AmMenus[g_AmIndex].origscreennum == 0) {
g_AmMenus[g_AmIndex].origscreennum = g_AmMenus[g_AmIndex].screenindex;
g_AmMenus[g_AmIndex].screenindex = 2;
amChangeScreen(0);
}
// If exiting allbots mode, return to original screen
if (!g_AmMenus[g_AmIndex].allbots
&& g_AmMenus[g_AmIndex].origscreennum) {
g_AmMenus[g_AmIndex].screenindex = g_AmMenus[g_AmIndex].origscreennum;
g_AmMenus[g_AmIndex].origscreennum = 0;
amChangeScreen(0);
}
if (buttonsstate & U_CBUTTONS) {
row = 0;
}
if (buttonsstate & D_CBUTTONS) {
row = 2;
}
if (buttonsstate & L_CBUTTONS) {
column = 0;
}
if (buttonsstate & R_CBUTTONS) {
column = 2;
}
if (buttonsstate & U_JPAD) {
row = 0;
}
if (buttonsstate & D_JPAD) {
row = 2;
}
if (buttonsstate & L_JPAD) {
column = 0;
}
if (buttonsstate & R_JPAD) {
column = 2;
}
if (controlmode == CONTROLMODE_23
|| controlmode == CONTROLMODE_24
|| controlmode == CONTROLMODE_22
|| controlmode == CONTROLMODE_21) {
s8 contpadnum2 = optionsGetContpadNum2(g_Vars.currentplayerstats->mpindex);
s8 cstickx2 = contGetStickXOnSample(j, contpadnum2);
s8 csticky2 = contGetStickYOnSample(j, contpadnum2);
u16 buttonsstate2 = contGetButtonsOnSample(j, contpadnum2, 0xffff);
u16 buttonspressed2 = contGetButtonsPressedOnSample(j, contpadnum2, 0xffff);
if (g_Vars.currentplayer->activemenumode == AMMODE_EDIT) {
buttonsstate2 = buttonsstate2 & A_BUTTON;
cstickx2 = 0;
csticky2 = 0;
buttonspressed2 = 0;
}
if (buttonsstate2 & A_BUTTON) {
stayopen = true;
}
if (buttonspressed2 & Z_TRIG) {
toggle = true;
}
if (buttonsstate2 & U_CBUTTONS) {
row = 0;
}
if (buttonsstate2 & D_CBUTTONS) {
row = 2;
}
if (buttonsstate2 & L_CBUTTONS) {
column = 0;
}
if (buttonsstate2 & R_CBUTTONS) {
column = 2;
}
if (buttonsstate2 & U_JPAD) {
row = 0;
}
if (buttonsstate2 & D_JPAD) {
row = 2;
}
if (buttonsstate2 & L_JPAD) {
column = 0;
}
if (buttonsstate2 & R_JPAD) {
column = 2;
}
absstickx = cstickx2 < 0 ? -cstickx2 : cstickx2;
abssticky = csticky2 < 0 ? -csticky2 : csticky2;
if (absstickx > 20 || abssticky > 20) {
if ((f32)abssticky / (f32)absstickx < 0.268f) {
row = 1;
column = cstickx2 < 0 ? 0 : 2;
} else if ((f32)absstickx / (f32)abssticky < 0.268f) {
column = 1;
row = csticky2 < 0 ? 2 : 0;
} else {
column = cstickx2 < 0 ? 0 : 2;
row = csticky2 < 0 ? 2 : 0;
}
stickpushed = true;
}
}
absstickx = cstickx < 0 ? -cstickx : cstickx;
abssticky = csticky < 0 ? -csticky : csticky;
if (absstickx > 20 || abssticky > 20) {
stickpushed = true;
if ((f32)abssticky / (f32)absstickx < 0.268f) {
column = cstickx < 0 ? 0 : 2;
row = 1;
} else if ((f32)absstickx / (f32)abssticky < 0.268f) {
column = 1;
row = csticky < 0 ? 2 : 0;
} else {
column = cstickx < 0 ? 0 : 2;
row = csticky < 0 ? 2 : 0;
}
}
if (g_Vars.currentplayer->isdead) {
stayopen = false;
}
if (g_Vars.lvupdate240 == 0) {
stayopen = false;
}
if (!stayopen &&
(g_Vars.currentplayer->activemenumode != AMMODE_EDIT || g_Menus[g_MpPlayerNum].curframe == NULL)) {
amClose();
break;
}
if (buttonspressed & Z_TRIG) {
toggle = true;
}
if (toggle) {
if (g_AmMenus[g_AmIndex].screenindex >= 2) {
if (g_Vars.numaibuddies && g_MissionConfig.iscoop) {
// Bot command screen, in coop with AI buddies
if (g_AmMenus[g_AmIndex].slotnum == 4) {
gotonextscreen = true;
} else {
amApply(g_AmMenus[g_AmIndex].slotnum);
}
} else {
// Bot command screen, in multiplayer
if (g_AmBotCommands[g_AmMenus[g_AmIndex].slotnum] == MPBOTCOMMAND_ATTACK) {
amOpenPickTarget();
} else if (g_AmMenus[g_AmIndex].allbots == false) {
gotonextscreen = true;
}
if (g_AmMenus[g_AmIndex].slotnum != 4) {
amApply(g_AmMenus[g_AmIndex].slotnum);
}
}
} else {
// Weapon or function screen
if (g_AmMenus[g_AmIndex].slotnum == 4) {
gotonextscreen = true;
} else {
amApply(g_AmMenus[g_AmIndex].slotnum);
}
}
}
if (gotonextscreen) {
amChangeScreen(gotonextscreen);
// If weapon has no functions, skip past function screen
if (g_AmMenus[g_AmIndex].screenindex == 1) {
struct weaponfunc *pri = weaponGetFunction(&g_Vars.currentplayer->hands[0].base, FUNC_PRIMARY);
struct weaponfunc *sec = weaponGetFunction(&g_Vars.currentplayer->hands[0].base, FUNC_SECONDARY);
if (!pri && !sec) {
amChangeScreen(gotonextscreen);
}
}
}
slotnum = column * 1 + row * 3;
if (g_Vars.currentplayer->activemenumode != AMMODE_EDIT) {
if (slotnum == 4) {
if (g_AmMenus[g_AmIndex].returntimer <= 0) {
g_AmMenus[g_AmIndex].returntimer = 0;
g_AmMenus[g_AmIndex].slotnum = slotnum;
} else {
g_AmMenus[g_AmIndex].returntimer--;
}
} else {
bool gotoslot = true;
char text[28];
u32 flags;
amGetSlotDetails(slotnum, &flags, text);
if (strcmp(text, "") == 0) {
gotoslot = false;
}
// If focusing a corner slot with C buttons or J pad,
// set a special timer for the release. The player is
// unlikely to release both C buttons on the same frame,
// so this gives a bit of grace and prevents accidental
// movement to a neighbouring slot.
if (g_AmMenus[g_AmIndex].slotnum != 4
&& !stickpushed
&&
(g_AmMenus[g_AmIndex].slotnum == 0
|| g_AmMenus[g_AmIndex].slotnum == 2
|| g_AmMenus[g_AmIndex].slotnum == 6
|| g_AmMenus[g_AmIndex].slotnum == 8)) {
if (slotnum != g_AmMenus[g_AmIndex].fromslotnum) {
g_AmMenus[g_AmIndex].cornertimer = 2;
g_AmMenus[g_AmIndex].fromslotnum = slotnum;
gotoslot = false;
}
if (g_AmMenus[g_AmIndex].cornertimer > 0 && gotoslot) {
gotoslot = false;
g_AmMenus[g_AmIndex].cornertimer--;
}
}
if (gotoslot) {
g_AmMenus[g_AmIndex].returntimer = 15;
g_AmMenus[g_AmIndex].slotnum = slotnum;
}
}
}
}
}
if (g_Vars.currentplayer->activemenumode != AMMODE_EDIT) {
s16 dist;
s16 dstradius;
if (g_AmMenus[g_AmIndex].dstx != -123) {
s16 dist;
// Update selection x/y values
g_AmMenus[g_AmIndex].selx = (g_AmMenus[g_AmIndex].selx + g_AmMenus[g_AmIndex].dstx) / 2;
g_AmMenus[g_AmIndex].sely = (g_AmMenus[g_AmIndex].sely + g_AmMenus[g_AmIndex].dsty) / 2;
dist = g_AmMenus[g_AmIndex].selx - g_AmMenus[g_AmIndex].dstx;
if (dist <= 1 && dist >= -1) {
g_AmMenus[g_AmIndex].selx = g_AmMenus[g_AmIndex].dstx;
}
dist = g_AmMenus[g_AmIndex].sely - g_AmMenus[g_AmIndex].dsty;
if (dist <= 1 && dist >= -1) {
g_AmMenus[g_AmIndex].sely = g_AmMenus[g_AmIndex].dsty;
}
}
// Update x radius (the expanding effect when a new screen is loaded)
dstradius = g_AmMenus[g_AmIndex].slotwidth + 5;
g_AmMenus[g_AmIndex].xradius = (g_AmMenus[g_AmIndex].xradius * 3 + dstradius) / 4;
dist = g_AmMenus[g_AmIndex].xradius - dstradius;
if (dist <= 1 && dist >= -1) {
g_AmMenus[g_AmIndex].xradius = dstradius;
}
// Update alpha of slots so they fade in
if (g_AmMenus[g_AmIndex].alphafrac < 1) {
g_AmMenus[g_AmIndex].alphafrac += g_Vars.lvupdate240f / 30.0f;
}
if (g_AmMenus[g_AmIndex].alphafrac > 1) {
g_AmMenus[g_AmIndex].alphafrac = 1;
}
// Make selection border pulsate
g_AmMenus[g_AmIndex].selpulse += g_Vars.lvupdate240f / 5.0f;
if (g_AmMenus[g_AmIndex].selpulse > 18.849555969238f) {
g_AmMenus[g_AmIndex].selpulse -= 18.849555969238f;
}
}
}
setCurrentPlayerNum(prevplayernum);
}