Files
perfect_dark/src/game/mplayer/scenarios/hackthatmac.inc
T

793 lines
19 KiB
C++

/**
* 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.
*/
extern struct menudialogdef g_ExtGameOptionsMenuDialog;
#define HTM_NUM_TERMINALS 1
struct menuitem g_HtmOptionsMenuItems[] = {
{
MENUITEMTYPE_CHECKBOX,
0,
MENUITEMFLAG_LOCKABLEMINOR,
L_MPMENU_222, // "One-Hit Kills"
MPOPTION_ONEHITKILLS,
menuhandlerMpOneHitKills,
},
{
MENUITEMTYPE_DROPDOWN,
0,
MENUITEMFLAG_LOCKABLEMINOR,
L_MPMENU_223, // "Slow Motion"
0,
menuhandlerMpSlowMotion,
},
{
MENUITEMTYPE_CHECKBOX,
0,
MENUITEMFLAG_LOCKABLEMINOR,
L_MPMENU_224, // "Fast Movement"
MPOPTION_FASTMOVEMENT,
menuhandlerMpCheckboxOption,
},
{
MENUITEMTYPE_CHECKBOX,
0,
MENUITEMFLAG_LOCKABLEMINOR,
L_MPMENU_225, // "Display Team"
MPOPTION_DISPLAYTEAM,
menuhandlerMpDisplayTeam,
},
{
MENUITEMTYPE_CHECKBOX,
0,
MENUITEMFLAG_LOCKABLEMINOR,
L_MPMENU_226, // "No Radar"
MPOPTION_NORADAR,
menuhandlerMpCheckboxOption,
},
{
MENUITEMTYPE_CHECKBOX,
0,
MENUITEMFLAG_LOCKABLEMINOR,
L_MPMENU_227, // "No Auto-Aim"
MPOPTION_NOAUTOAIM,
menuhandlerMpCheckboxOption,
},
{
MENUITEMTYPE_CHECKBOX,
0,
MENUITEMFLAG_LOCKABLEMINOR,
L_OPTIONS_493, // "Kills Score"
MPOPTION_KILLSSCORE,
menuhandlerMpCheckboxOption,
},
{
MENUITEMTYPE_SEPARATOR,
0,
0,
0,
0,
NULL,
},
{
MENUITEMTYPE_CHECKBOX,
0,
MENUITEMFLAG_LOCKABLEMINOR,
L_MPMENU_231, // "Highlight Terminal"
MPOPTION_HTM_HIGHLIGHTTERMINAL,
menuhandlerMpCheckboxOption,
},
{
MENUITEMTYPE_CHECKBOX,
0,
MENUITEMFLAG_LOCKABLEMINOR,
L_MPMENU_238, // "Show on Radar"
MPOPTION_HTM_SHOWONRADAR,
menuhandlerMpCheckboxOption,
},
{
MENUITEMTYPE_SEPARATOR,
0,
0,
0,
0,
NULL,
},
{
MENUITEMTYPE_SELECTABLE,
0,
MENUITEMFLAG_SELECTABLE_CLOSESDIALOG,
L_MPMENU_239, // "Back"
0,
NULL,
},
{ MENUITEMTYPE_END },
};
struct menudialogdef g_HtmOptionsMenuDialog = {
MENUDIALOGTYPE_DEFAULT,
L_MPMENU_217, // "Hacker Options"
g_HtmOptionsMenuItems,
mpOptionsMenuDialog,
MENUDIALOGFLAG_MPLOCKABLE,
&g_ExtGameOptionsMenuDialog,
};
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_FALL | OBJFLAG_INVINCIBLE | OBJFLAG_FORCENOBOUNCE,
OBJFLAG2_IMMUNETOGUNFIRE | OBJFLAG2_IMMUNETOEXPLOSIONS,
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 = rngRandom() % count;
var800869ec = candidates[count];
var800869ec->hidden |= OBJHFLAG_DELETING;
var800869ec->hidden2 |= OBJH2FLAG_CANREGEN;
padnum = var800869ec->pad;
} else if (g_ScenarioData.htm.numpads > 0) {
padnum = g_ScenarioData.htm.padnums[rngRandom() % g_ScenarioData.htm.numpads];
} else {
padnum = 0;
}
g_HtmUplinkObj = template;
g_HtmUplinkObj.base.pad = padnum;
setupPlaceWeapon(&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 = rngRandom() % 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_FALL | OBJFLAG_INVINCIBLE | OBJFLAG_FORCENOBOUNCE,
OBJFLAG2_IMMUNETOGUNFIRE | OBJFLAG2_IMMUNETOEXPLOSIONS,
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 = TICKS(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) {
#if VERSION >= VERSION_JPN_FINAL
hudmsgCreateWithFlags(langGet(L_MPWEAPONS_018), HUDMSGTYPE_MPSCENARIO, HUDMSGFLAG_ONLYIFALIVE | HUDMSGFLAG_NOWRAP); // "Starting download."
#else
hudmsgCreateWithFlags(langGet(L_MPWEAPONS_018), HUDMSGTYPE_MPSCENARIO, HUDMSGFLAG_ONLYIFALIVE); // "Starting download."
#endif
psCreate(NULL, data->terminals[data->dlterminalnum].prop, SFX_01BF, -1,
-1, PSFLAG_REPEATING, PSFLAG2_MPPAUSABLE, PSTYPE_NONE, NULL, -1, NULL, -1, -1, -1, -1);
}
}
} else {
if (chr == NULL) {
#if VERSION >= VERSION_JPN_FINAL
hudmsgCreateWithFlags(langGet(L_MPWEAPONS_019), HUDMSGTYPE_MPSCENARIO, HUDMSGFLAG_ONLYIFALIVE | HUDMSGFLAG_NOWRAP); // "You need to use the Data Uplink."
#else
hudmsgCreateWithFlags(langGet(L_MPWEAPONS_019), HUDMSGTYPE_MPSCENARIO, HUDMSGFLAG_ONLYIFALIVE); // "You need to use the Data Uplink."
#endif
snd00010718(NULL, 0, AL_VOL_FULL, AL_PAN_CENTER, 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."
#if VERSION >= VERSION_JPN_FINAL
hudmsgCreateWithFlags(langGet(L_MPWEAPONS_017), HUDMSGTYPE_MPSCENARIO, HUDMSGFLAG_ONLYIFALIVE | HUDMSGFLAG_NOWRAP);
#else
hudmsgCreateWithFlags(langGet(L_MPWEAPONS_017), HUDMSGTYPE_MPSCENARIO, HUDMSGFLAG_ONLYIFALIVE);
#endif
psStopSound(data->terminals[data->dlterminalnum].prop, PSTYPE_GENERAL, 0xffff);
snd00010718(NULL, 0, AL_VOL_FULL, AL_PAN_CENTER, SFX_01CC, 1, 1, -1, 1);
}
data->dlterminalnum = -1;
data->dlplayernum = -1;
*time = 0;
} else {
*time += g_Vars.lvupdate240;
if (*time > 20 * TICKS(240)) {
data->numpoints[playernum]++;
data->playernuminrange = playernum;
if (chr == NULL) {
// "Download successful."
#if VERSION >= VERSION_JPN_FINAL
hudmsgCreateWithFlags(langGet(L_MPWEAPONS_016), HUDMSGTYPE_MPSCENARIO, HUDMSGFLAG_ONLYIFALIVE | HUDMSGFLAG_NOWRAP);
#else
hudmsgCreateWithFlags(langGet(L_MPWEAPONS_016), HUDMSGTYPE_MPSCENARIO, HUDMSGFLAG_ONLYIFALIVE);
#endif
psStopSound(data->terminals[data->dlterminalnum].prop, PSTYPE_GENERAL, 0xffff);
snd00010718(NULL, 0, AL_VOL_FULL, AL_PAN_CENTER, 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 / TICKS(4800.0f)));
gdl = text0f153628(gdl);
gdl = textSetPrimColour(gdl, 0x60000060);
gDPFillRectangle(gdl++, barleft, viewtop + 8, barright, viewtop + 16);
gdl = text0f153838(gdl);
gdl = textSetPrimColour(gdl, 0xc00000d0);
v1 = barleft + 1;
a0 = barleft;
while (v1 < s1) {
gDPFillRectangle(gdl++, a0, viewtop + 8, v1, viewtop + 16);
v1 += 2;
a0 += 2;
}
gdl = text0f153838(gdl);
gdl = text0f153780(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;
}