forked from Ports/goldeneye-pc-port
F10 pad slider persistence (D489), glass collision hull (D490), A/B input harnesses (1964 virtual pad, GE_INPUTSCRIPT, live one-pad launcher), adjacent global struct reads (D491), vibration percent, D441 complete pointer-width census with high-arena tier-1 build, fix batches 1-5 and an ABI warning ratchet, playtest verification of D493-D502. Refs: D489 D490 D491 D492-D502 D441
2162 lines
78 KiB
C
2162 lines
78 KiB
C
#include <ultra64.h>
|
|
#ifdef PORT
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#endif
|
|
#include <memp.h>
|
|
#include "game/mp_weapon.h"
|
|
#include "game/bondview_r.h"
|
|
#include "bg.h"
|
|
#include "bondview_r.h"
|
|
#include "chr.h"
|
|
#include "chrai.h"
|
|
#include "chraction.h"
|
|
#include "propobj.h"
|
|
#include "inititemslots.h"
|
|
#include "initobjects.h"
|
|
#include "initpathtablesomething.h"
|
|
#include "limits.h"
|
|
#include "loadobjectmodel.h"
|
|
#include "language.h"
|
|
#include "math_atan2f.h"
|
|
#include "matrixmath.h"
|
|
#include "mp_weapon.h"
|
|
#include "ob.h"
|
|
#include "objective.h"
|
|
#include "objective_status.h"
|
|
#include "objecthandler.h"
|
|
#include "player.h"
|
|
#include "prop.h"
|
|
#include "stan.h"
|
|
#include "model.h"
|
|
#include "token.h"
|
|
|
|
/**
|
|
* EU .bss 0x80068480
|
|
*/
|
|
ITEM_IDS lastmpweaponnum;
|
|
|
|
// redeclare with the element count so ARRAYCOUNT works in proplvreset2
|
|
extern ItemModelFileRecord PitemZ_entries[341];
|
|
|
|
// forward declarations
|
|
|
|
s32 load_proptype(PROPDEF_TYPE type);
|
|
void sub_GAME_7F001BD4(struct BoundPadRecord *pad, struct coord3d *arg1);
|
|
void domakedefaultobj(s32 arg0, ObjectRecord *arg1, s32 cmdindex);
|
|
void weaponAssignToHome(s32 arg0, WeaponObjRecord* weapon, s32 cmdindex);
|
|
void setupHat(s32 arg0, ObjectRecord* hat, s32 cmdindex);
|
|
void setupKey(s32 arg0, ObjectRecord* key, s32 cmdindex);
|
|
void setupCctv(s32 arg0, CCTVRecord *arg1, s32 cmdindex);
|
|
void setupAutogun(s32 stageID, AutogunRecord *autogun, s32 cmdindex);
|
|
void setupHangingMonitors(s32 arg0, ObjectRecord* rack, s32 cmdindex);
|
|
void setupSingleMonitor(s32 stageID, MonitorObjRecord *monitor, s32 cmdindex);
|
|
void setupMultiMonitor(s32 stageID, MultiMonitorObjRecord* monitor, s32 cmdindex);
|
|
void sub_GAME_7F00324C(struct BoundPadRecord *arg0, s32 *arg1, s32 *arg2, struct coord3d *arg3, struct coord3d *arg4);
|
|
void setupDoor(s32 arg0, struct DoorRecord *door, s32 arg2);
|
|
|
|
|
|
s32 load_proptype(PROPDEF_TYPE type)
|
|
{
|
|
PropDefHeaderRecord *propdef = (PropDefHeaderRecord *) g_CurrentSetup.propDefs;
|
|
s32 count = 0;
|
|
|
|
if (propdef != NULL)
|
|
{
|
|
while (propdef->type != PROPDEF_END)
|
|
{
|
|
if (propdef->type == (type & 0xFF))
|
|
{
|
|
count ++;
|
|
}
|
|
propdef = &propdef[sizepropdef((PropDefHeaderRecord* ) propdef)];
|
|
}
|
|
}
|
|
return count;
|
|
}
|
|
|
|
|
|
/**
|
|
* perfect dark padGetCentre (pad.c)
|
|
*
|
|
* NTSC address 0x7F001BD4.
|
|
*/
|
|
void sub_GAME_7F001BD4(struct BoundPadRecord *pad, struct coord3d *arg1)
|
|
{
|
|
struct coord3d normal;
|
|
f32 scale;
|
|
struct bbox bb;
|
|
f32 temp;
|
|
|
|
bb.zmax = pad->bbox.xmin;
|
|
bb.zmin = pad->bbox.xmax;
|
|
bb.ymax = pad->bbox.ymin;
|
|
bb.ymin = pad->bbox.ymax;
|
|
bb.xmax = pad->bbox.zmin;
|
|
bb.xmin = pad->bbox.zmax;
|
|
|
|
normal.f[0] = (pad->up.f[1] * pad->look.f[2]) - (pad->up.f[2] * pad->look.f[1]);
|
|
normal.f[1] = (pad->up.f[2] * pad->look.f[0]) - (pad->up.f[0] * pad->look.f[2]);
|
|
normal.f[2] = (pad->up.f[0] * pad->look.f[1]) - (pad->up.f[1] * pad->look.f[0]);
|
|
|
|
temp = (normal.f[0] * normal.f[0]) + (normal.f[1] * normal.f[1]) + (normal.f[2] * normal.f[2]);
|
|
scale = 1.0f / sqrtf(temp);
|
|
|
|
normal.f[0] *= scale;
|
|
normal.f[1] *= scale;
|
|
normal.f[2] *= scale;
|
|
|
|
arg1->f[0] = pad->pos.f[0] + (
|
|
(bb.zmax + bb.zmin) * normal.f[0] +
|
|
(bb.ymax + bb.ymin) * pad->up.f[0] +
|
|
(bb.xmax + bb.xmin) * pad->look.f[0]) * 0.5f;
|
|
|
|
arg1->f[1] = pad->pos.f[1] + (
|
|
(bb.zmax + bb.zmin) * normal.f[1] +
|
|
(bb.ymax + bb.ymin) * pad->up.f[1] +
|
|
(bb.xmax + bb.xmin) * pad->look.f[1]) * 0.5f;
|
|
|
|
arg1->f[2] = pad->pos.f[2] + (
|
|
(bb.zmax + bb.zmin) * normal.f[2] +
|
|
(bb.ymax + bb.ymin) * pad->up.f[2] +
|
|
(bb.xmax + bb.xmin) * pad->look.f[2]) * 0.5f;
|
|
|
|
}
|
|
|
|
/**
|
|
* NTSC address 0x7F001D9C.
|
|
*/
|
|
void domakedefaultobj(s32 arg0, ObjectRecord *arg1, s32 cmdindex)
|
|
{
|
|
s32 padding;
|
|
s32 spF0;
|
|
f32 var_f0;
|
|
struct coord3d spE0;
|
|
struct StandTile *spDC;
|
|
struct coord3d spD0;
|
|
StandTile *spCC;
|
|
Mtxf sp8C;
|
|
struct coord3d sp80;
|
|
struct PropRecord *var_v0;
|
|
f32 sp78;
|
|
s32 sp74;
|
|
struct BoundPadRecord *var_s0;
|
|
ChrRecord *sp6C;
|
|
ModelRoData_BoundingBoxRecord *temp_v0_3;
|
|
struct PadRecord *sp64;
|
|
struct PropRecord *sp60;
|
|
s32 padding2;
|
|
f32 sp58;
|
|
f32 sp54;
|
|
f32 sp50;
|
|
s32 padding3;
|
|
f32 sp48;
|
|
|
|
spF0 = arg1->obj;
|
|
var_s0 = NULL;
|
|
|
|
modelLoad(spF0);
|
|
|
|
sp78 = arg1->extrascale * 0.00390625f;
|
|
|
|
arg1->damage = *(s32*)&arg1->damage / 65536.0f;
|
|
|
|
if (getPlayerCount() >= 2)
|
|
{
|
|
sp74 = 1;
|
|
|
|
if ((get_scenario() == SCENARIO_TLD) && (arg1->obj == PROP_FLAG))
|
|
{
|
|
sp74 = 0;
|
|
}
|
|
else if ((get_scenario() == SCENARIO_MWTGG) && (arg1->obj == PROP_CHRGOLDEN))
|
|
{
|
|
sp74 = 0;
|
|
}
|
|
|
|
if (sp74 != 0)
|
|
{
|
|
arg1->state |= PROPSTATE_RESPAWN; // respawn enabled
|
|
}
|
|
}
|
|
|
|
if (arg1->flags & PROPFLAG_INSIDEANOTHEROBJ)
|
|
{
|
|
if (arg1->type == PROP_TYPE_SMOKE)
|
|
{
|
|
sub_GAME_7F051DD8(arg1, PitemZ_entries[spF0].header);
|
|
}
|
|
else
|
|
{
|
|
objInitWithModelDef(arg1, PitemZ_entries[spF0].header);
|
|
}
|
|
|
|
modelSetScale(arg1->model, arg1->model->scale * sp78);
|
|
}
|
|
else if (arg1->flags & PROPFLAG_ASSIGNEDTOCHR)
|
|
{
|
|
sp6C = chrFindByLiteralId(arg1->pad);
|
|
|
|
if ((sp6C != NULL) && (sp6C->prop != NULL) && (sp6C->model != NULL))
|
|
{
|
|
if (arg1->type == 8)
|
|
{
|
|
var_v0 = sub_GAME_7F051DD8(arg1, PitemZ_entries[spF0].header);
|
|
}
|
|
else
|
|
{
|
|
var_v0 = objInitWithModelDef(arg1, PitemZ_entries[spF0].header);
|
|
}
|
|
|
|
modelSetScale(arg1->model, arg1->model->scale * sp78);
|
|
chrpropReparent(var_v0, sp6C->prop);
|
|
}
|
|
#ifdef DEBUG
|
|
else
|
|
{
|
|
osSyncPrintf("domakedefaultobj: no chr number %d for obj number %d!\n",arg1->pad,cmdindex + 1);
|
|
}
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
if (isNotBoundPad(arg1->pad))
|
|
{
|
|
sp64 = &g_CurrentSetup.pads[arg1->pad];
|
|
|
|
matrix_4x4_set_basis_and_position_target(&sp8C, 0.0f, 0.0f, 0.0f, -sp64->look.f[0], -sp64->look.f[1], -sp64->look.f[2], sp64->up.f[0], sp64->up.f[1], sp64->up.f[2]);
|
|
|
|
spD0.f[0] = sp64->pos.f[0];
|
|
spD0.f[1] = sp64->pos.f[1];
|
|
spD0.f[2] = sp64->pos.f[2];
|
|
|
|
if (arg1->flags & PROPFLAG_ONSCREEN)
|
|
{
|
|
sp80.f[0] = sp64->pos.f[0];
|
|
sp80.f[1] = sp64->pos.f[1];
|
|
sp80.f[2] = sp64->pos.f[2];
|
|
}
|
|
else
|
|
{
|
|
// same as above?
|
|
|
|
sp80.f[0] = sp64->pos.f[0];
|
|
sp80.f[1] = sp64->pos.f[1];
|
|
sp80.f[2] = sp64->pos.f[2];
|
|
}
|
|
|
|
spCC = sp64->stan;
|
|
}
|
|
else
|
|
{
|
|
var_s0 = &g_CurrentSetup.boundpads[getBoundPadNum(arg1->pad)];
|
|
|
|
matrix_4x4_set_basis_and_position_target(&sp8C, 0.0f, 0.0f, 0.0f, -var_s0->look.f[0], -var_s0->look.f[1], -var_s0->look.f[2], var_s0->up.f[0], var_s0->up.f[1], var_s0->up.f[2]);
|
|
|
|
if (!(arg1->flags2 & PROPFLAG2_00000001))
|
|
{
|
|
sub_GAME_7F001BD4(var_s0, &spD0);
|
|
|
|
sp80.f[0] = spD0.f[0] + (var_s0->up.f[0] * ((var_s0->bbox.ymin - var_s0->bbox.ymax) * 0.5f));
|
|
sp80.f[1] = spD0.f[1] + (var_s0->up.f[1] * ((var_s0->bbox.ymin - var_s0->bbox.ymax) * 0.5f));
|
|
sp80.f[2] = spD0.f[2] + (var_s0->up.f[2] * ((var_s0->bbox.ymin - var_s0->bbox.ymax) * 0.5f));
|
|
|
|
spCC = var_s0->stan;
|
|
|
|
if (walkTilesBetweenPoints_NoCallback(&spCC, var_s0->pos.f[0], var_s0->pos.f[2], spD0.f[0], spD0.f[2]) == 0)
|
|
{
|
|
spD0.f[0] = var_s0->pos.f[0];
|
|
spD0.f[1] = var_s0->pos.f[1];
|
|
spD0.f[2] = var_s0->pos.f[2];
|
|
|
|
spCC = var_s0->stan;
|
|
|
|
if (!(arg1->flags & PROPFLAG_ONSCREEN) && !(arg1->flags & PROPFLAG_00001000))
|
|
{
|
|
// removed
|
|
#ifdef DEBUG
|
|
osSyncPrintf("object number %d not positioned correctly!\n",cmdindex + 1);
|
|
#endif
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
spD0.f[0] = var_s0->pos.f[0];
|
|
spD0.f[1] = var_s0->pos.f[1];
|
|
spD0.f[2] = var_s0->pos.f[2];
|
|
|
|
spCC = var_s0->stan;
|
|
|
|
sub_GAME_7F001BD4(var_s0, &sp80);
|
|
|
|
sp80.f[0] += (var_s0->bbox.ymin - var_s0->bbox.ymax) * 0.5f * var_s0->up.f[0];
|
|
sp80.f[1] += (var_s0->bbox.ymin - var_s0->bbox.ymax) * 0.5f * var_s0->up.f[1];
|
|
sp80.f[2] += (var_s0->bbox.ymin - var_s0->bbox.ymax) * 0.5f * var_s0->up.f[2];
|
|
}
|
|
}
|
|
|
|
if (getposstan(&spD0, spCC, 0.0f, &spE0, &spDC) != 0)
|
|
{
|
|
if (arg1->type == PROP_TYPE_SMOKE)
|
|
{
|
|
sp60 = sub_GAME_7F051DD8(arg1, PitemZ_entries[spF0].header);
|
|
}
|
|
else
|
|
{
|
|
sp60 = objInitWithAutoModel(arg1);
|
|
}
|
|
|
|
if (var_s0 != NULL)
|
|
{
|
|
temp_v0_3 = chrobjGetBboxFromObjectRecord(arg1);
|
|
if (temp_v0_3 != NULL)
|
|
{
|
|
sp58 = 1.0f;
|
|
sp54 = 1.0f;
|
|
sp50 = 1.0f;
|
|
|
|
if (arg1->flags & (PROPFLAG_00000010 | PROPFLAG_00000020))
|
|
{
|
|
if (temp_v0_3->Bounds.xmin < temp_v0_3->Bounds.xmax)
|
|
{
|
|
if (arg1->flags & PROPFLAG_ONSCREEN)
|
|
{
|
|
sp58 = (var_s0->bbox.xmax - var_s0->bbox.xmin) / ((temp_v0_3->Bounds.xmax - temp_v0_3->Bounds.xmin) * arg1->model->scale);
|
|
}
|
|
else
|
|
{
|
|
sp58 = (var_s0->bbox.xmax - var_s0->bbox.xmin) / ((temp_v0_3->Bounds.xmax - temp_v0_3->Bounds.xmin) * arg1->model->scale);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (arg1->flags & (PROPFLAG_00000010 | PROPFLAG_00000040))
|
|
{
|
|
if (temp_v0_3->Bounds.ymin < temp_v0_3->Bounds.ymax)
|
|
{
|
|
if (arg1->flags & PROPFLAG_ONSCREEN)
|
|
{
|
|
sp50 = (var_s0->bbox.zmax - var_s0->bbox.zmin) / ((temp_v0_3->Bounds.ymax - temp_v0_3->Bounds.ymin) * arg1->model->scale);
|
|
}
|
|
else
|
|
{
|
|
sp54 = (var_s0->bbox.ymax - var_s0->bbox.ymin) / ((temp_v0_3->Bounds.ymax - temp_v0_3->Bounds.ymin) * arg1->model->scale);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (arg1->flags & (PROPFLAG_00000010 | PROPFLAG_00000080))
|
|
{
|
|
if (temp_v0_3->Bounds.zmin < temp_v0_3->Bounds.zmax)
|
|
{
|
|
if (arg1->flags & PROPFLAG_ONSCREEN)
|
|
{
|
|
sp54 = (var_s0->bbox.ymax - var_s0->bbox.ymin) / ((temp_v0_3->Bounds.zmax - temp_v0_3->Bounds.zmin) * arg1->model->scale);
|
|
}
|
|
else
|
|
{
|
|
sp50 = (var_s0->bbox.zmax - var_s0->bbox.zmin) / ((temp_v0_3->Bounds.zmax - temp_v0_3->Bounds.zmin) * arg1->model->scale);
|
|
}
|
|
}
|
|
}
|
|
|
|
var_f0 = sp58;
|
|
|
|
if (sp54 < var_f0)
|
|
{
|
|
var_f0 = sp54;
|
|
}
|
|
|
|
if (sp50 < var_f0)
|
|
{
|
|
var_f0 = sp50;
|
|
}
|
|
|
|
sp48 = sp58;
|
|
|
|
if (sp58 < sp54)
|
|
{
|
|
sp48 = sp54;
|
|
}
|
|
|
|
if (sp48 < sp50)
|
|
{
|
|
sp48 = sp50;
|
|
}
|
|
|
|
if (arg1->flags & PROPFLAG_00000010)
|
|
{
|
|
sp50 = var_f0;
|
|
sp54 = var_f0;
|
|
sp58 = var_f0;
|
|
}
|
|
else
|
|
{
|
|
if (!(arg1->flags & PROPFLAG_00000020))
|
|
{
|
|
if (arg1->flags & PROPFLAG_ONSCREEN)
|
|
{
|
|
if (temp_v0_3->Bounds.xmax == temp_v0_3->Bounds.xmin)
|
|
{
|
|
sp58 = sp48;
|
|
}
|
|
}
|
|
else if (temp_v0_3->Bounds.xmax == temp_v0_3->Bounds.xmin)
|
|
{
|
|
sp58 = sp48;
|
|
}
|
|
}
|
|
|
|
if (!(arg1->flags & PROPFLAG_00000040))
|
|
{
|
|
if (arg1->flags & PROPFLAG_ONSCREEN)
|
|
{
|
|
if (temp_v0_3->Bounds.ymax == temp_v0_3->Bounds.ymin)
|
|
{
|
|
sp50 = sp48;
|
|
}
|
|
}
|
|
else if (temp_v0_3->Bounds.ymax == temp_v0_3->Bounds.ymin)
|
|
{
|
|
sp54 = sp48;
|
|
}
|
|
}
|
|
|
|
if (!(arg1->flags & PROPFLAG_00000080))
|
|
{
|
|
if (arg1->flags & PROPFLAG_ONSCREEN)
|
|
{
|
|
if (temp_v0_3->Bounds.zmax == temp_v0_3->Bounds.zmin)
|
|
{
|
|
sp54 = sp48;
|
|
}
|
|
}
|
|
else if (temp_v0_3->Bounds.zmax == temp_v0_3->Bounds.zmin)
|
|
{
|
|
sp50 = sp48;
|
|
}
|
|
}
|
|
}
|
|
|
|
sp58 /= sp48;
|
|
sp54 /= sp48;
|
|
sp50 /= sp48;
|
|
|
|
if ((sp58 <= 0.000001f) || (sp54 <= 0.000001f) || (sp50 <= 0.000001f))
|
|
{
|
|
#ifdef DEBUG
|
|
osSyncPrintf("Scale warning: object number %d has a small scale: %f,%f,%f\n",cmdindex +1, sp58,sp54,sp50);
|
|
#endif
|
|
sp50 = 1.0f;
|
|
sp54 = 1.0f;
|
|
sp58 = 1.0f;
|
|
}
|
|
|
|
matrix_column_1_scalar_multiply(sp58, sp8C.m[0]);
|
|
matrix_column_2_scalar_multiply(sp54, sp8C.m[0]);
|
|
matrix_column_3_scalar_multiply_2(sp50, sp8C.m[0]);
|
|
|
|
modelSetScale(arg1->model, arg1->model->scale * sp48);
|
|
}
|
|
}
|
|
|
|
modelSetScale(arg1->model, arg1->model->scale * sp78);
|
|
matrix_scalar_multiply(arg1->model->scale, sp8C.m[0]);
|
|
|
|
if (arg1->flags & PROPFLAG_ONSCREEN)
|
|
{
|
|
sub_GAME_7F040BA0(arg1, &spE0, &sp8C, spDC, &sp80);
|
|
}
|
|
else
|
|
{
|
|
sub_GAME_7F04088C(arg1, &spE0, &sp8C, spDC, &sp80);
|
|
}
|
|
|
|
setupUpdateObjectRoomPosition(arg1);
|
|
chrpropActivate(sp60);
|
|
chrpropEnable(sp60);
|
|
}
|
|
#ifdef DEBUG
|
|
else
|
|
{
|
|
osSyncPrintf("domakedefaultobj: prop obj number %d not reset!\n",cmdindex + 1);
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
|
|
/**
|
|
* NTSC address 0x7F002738.
|
|
* PAL address 0x7F002738.
|
|
*/
|
|
void weaponAssignToHome(s32 arg0, WeaponObjRecord* weapon, s32 cmdindex)
|
|
{
|
|
s32 padding;
|
|
bool hastoken;
|
|
ChrRecord* chr;
|
|
bool giveweapon;
|
|
s32 temp_a0;
|
|
struct s_mp_weapon_set* weapon_set;
|
|
|
|
if ((weapon->flags & PROPFLAG_ASSIGNEDTOCHR))
|
|
{
|
|
chr = chrFindByLiteralId(weapon->pad);
|
|
|
|
if (chr && chr->prop && chr->model)
|
|
{
|
|
if (cheatIsActive(CHEAT_ENEMY_ROCKETS))
|
|
{
|
|
switch ((s8)weapon->weaponnum)
|
|
{
|
|
case ITEM_KNIFE:
|
|
case ITEM_THROWKNIFE:
|
|
case ITEM_WPPK:
|
|
case ITEM_WPPKSIL:
|
|
case ITEM_TT33:
|
|
case ITEM_SKORPION:
|
|
case ITEM_AK47:
|
|
case ITEM_UZI:
|
|
case ITEM_MP5K:
|
|
case ITEM_MP5KSIL:
|
|
case ITEM_SPECTRE:
|
|
case ITEM_M16:
|
|
case ITEM_FNP90:
|
|
case ITEM_SHOTGUN:
|
|
case ITEM_AUTOSHOT:
|
|
case ITEM_SNIPERRIFLE:
|
|
case ITEM_RUGER:
|
|
case ITEM_GOLDENGUN:
|
|
case ITEM_SILVERWPPK:
|
|
case ITEM_GOLDWPPK:
|
|
case ITEM_LASER:
|
|
case ITEM_WATCHLASER:
|
|
case ITEM_REMOTEMINE:
|
|
case ITEM_TRIGGER:
|
|
case ITEM_TASER:
|
|
weapon->weaponnum = ITEM_ROCKETLAUNCH;
|
|
weapon->obj = PROP_CHRROCKETLAUNCH;
|
|
weapon->extrascale = 256;
|
|
break;
|
|
}
|
|
}
|
|
|
|
weaponLoadProjectileModels((s8)weapon->weaponnum);
|
|
sub_GAME_7F052030(weapon, chr);
|
|
}
|
|
#ifdef DEBUG
|
|
else
|
|
{
|
|
osSyncPrintf("domakeweaponobj: no chr number %d for obj number %d!\n",weapon->pad, cmdindex + 1);
|
|
}
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
hastoken = 1;
|
|
giveweapon = 1;
|
|
|
|
if (getPlayerCount() >= 2)
|
|
{
|
|
lastmpweaponnum = -1;
|
|
|
|
switch ((u8)weapon->weaponnum)
|
|
{
|
|
case ITEM_UNARMED + 0xF0:
|
|
case ITEM_FIST + 0xF0:
|
|
case ITEM_KNIFE + 0xF0:
|
|
case ITEM_THROWKNIFE + 0xF0:
|
|
case ITEM_WPPK + 0xF0:
|
|
case ITEM_WPPKSIL + 0xF0:
|
|
case ITEM_TT33 + 0xF0:
|
|
case ITEM_SKORPION + 0xF0:
|
|
weapon_set = getPtrMPWeaponSetData();
|
|
|
|
temp_a0 = (u8)weapon->weaponnum - 0xF0;
|
|
lastmpweaponnum = temp_a0;
|
|
|
|
weapon->weaponnum = weapon_set[temp_a0].itemID;
|
|
weapon->obj = weapon_set[temp_a0].propID;
|
|
#if defined(VERSION_EU)
|
|
weapon->extrascale = (weapon_set[temp_a0].size16);
|
|
#else
|
|
weapon->extrascale = (weapon_set[temp_a0].size * 256.0f);
|
|
#endif
|
|
|
|
giveweapon = weapon_set[temp_a0].allowpickup;
|
|
|
|
break;
|
|
|
|
case ITEM_TOKEN:
|
|
|
|
hastoken = 1;
|
|
giveweapon = 1;
|
|
|
|
if (get_scenario() != SCENARIO_TLD)
|
|
{
|
|
giveweapon = 0;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ((weapon->weaponnum != ITEM_UNARMED) && giveweapon)
|
|
{
|
|
weaponLoadProjectileModels(weapon->weaponnum);
|
|
domakedefaultobj(arg0, (struct ObjectRecord*)weapon, cmdindex);
|
|
}
|
|
}
|
|
}
|
|
|
|
//i should be object hat
|
|
void setupHat(s32 arg0, ObjectRecord* hat, s32 cmdindex)
|
|
{
|
|
if (hat->flags & PROPFLAG_ASSIGNEDTOCHR) {
|
|
ChrRecord* chr = chrFindByLiteralId(hat->pad);
|
|
if (chr && chr->prop && chr->model) {
|
|
hatAssignToChr(hat, chr);
|
|
}
|
|
#ifdef DEBUG
|
|
else
|
|
{
|
|
osSyncPrintf("domakehatobj: no chr number %d for obj number %d!\n",hat->pad, cmdindex + 1);
|
|
}
|
|
#endif
|
|
} else {
|
|
domakedefaultobj(arg0, hat, cmdindex);
|
|
}
|
|
}
|
|
|
|
//i should be object key
|
|
void setupKey(s32 arg0, ObjectRecord* key, s32 cmdindex)
|
|
{
|
|
domakedefaultobj(arg0, key, cmdindex);
|
|
}
|
|
|
|
|
|
/**
|
|
* NTSC address 0x7F002A3C.
|
|
*/
|
|
void setupCctv(s32 arg0, CCTVRecord *arg1, s32 cmdindex)
|
|
{
|
|
struct coord3d *temp_a2;
|
|
struct PadRecord *sp50;
|
|
struct coord3d sp44;
|
|
Mtxf *sp3C;
|
|
|
|
domakedefaultobj(arg0, (struct ObjectRecord*)arg1, cmdindex);
|
|
|
|
#ifdef PORT
|
|
/* D307 (M-201): on N64, CCTVRecord's own s32 `pad` @0x80 (the LOOK-AT
|
|
* pad) shadows the inherited ObjectRecord s16 `pad` @0x08 (the mount pad),
|
|
* so `arg1->pad` here is the look-at pad. The PC struct renames the
|
|
* duplicate to `lookpad` (GCC rejects duplicate members), which silently
|
|
* re-pointed these reads at the MOUNT pad: the look vector became the
|
|
* lens's own offset from its mount and every camera faced backwards.
|
|
* Read the correctly named field (A1 class: layout/naming only; PD's
|
|
* setupCreateCctv uses cctv->lookatpadnum for the same step). */
|
|
#define CCTV_LOOKPAD (arg1->lookpad)
|
|
#else
|
|
#define CCTV_LOOKPAD (arg1->pad)
|
|
#endif
|
|
if (CCTV_LOOKPAD >= 0)
|
|
{
|
|
temp_a2 = (struct coord3d*)arg1->model->obj->Switches[0]->Data;
|
|
|
|
if (isNotBoundPad(CCTV_LOOKPAD))
|
|
{
|
|
sp50 = &g_CurrentSetup.pads[CCTV_LOOKPAD];
|
|
}
|
|
else
|
|
{
|
|
sp50 = (struct PadRecord *)&g_CurrentSetup.boundpads[getBoundPadNum(CCTV_LOOKPAD)];
|
|
}
|
|
|
|
sp44.f[0] = temp_a2->f[0];
|
|
sp44.f[1] = temp_a2->f[1];
|
|
sp44.f[2] = temp_a2->f[2];
|
|
|
|
mtx4RotateVecInPlace(&arg1->mtx, &sp44);
|
|
|
|
sp3C = &arg1->unk84;
|
|
|
|
sp44.f[0] += arg1->prop->pos.f[0];
|
|
sp44.f[1] += arg1->prop->pos.f[1];
|
|
sp44.f[2] += arg1->prop->pos.f[2];
|
|
|
|
matrix_4x4_set_basis_and_position_target(sp3C, 0.0f, 0.0f, 0.0f, sp44.f[0] - sp50->pos.f[0], sp44.f[1] - sp50->pos.f[1], sp44.f[2] - sp50->pos.f[2], 0.0f, 1.0f, 0.0f);
|
|
matrix_scalar_multiply(arg1->model->scale, sp3C->m[0]);
|
|
|
|
if (arg1->convert_to_f32 == 0)
|
|
{
|
|
arg1->convert_to_f32 = 1;
|
|
arg1->unkCC = (*(s32*)&arg1->unkCC * M_TAU_F) / 65536.0f;
|
|
arg1->unkD0 = (*(s32*)&arg1->unkD0 * M_TAU_F) / 65536.0f;
|
|
arg1->unkDC = (*(s32*)&arg1->unkDC * M_TAU_F) / 65536.0f;
|
|
arg1->unkE8 = *(s32*)&arg1->unkE8;
|
|
}
|
|
|
|
arg1->unkD4 = 0;
|
|
arg1->unkD8 = 0.0f;
|
|
arg1->unkC8 = arg1->unkCC;
|
|
arg1->unkC4 = atan2f(sp44.f[0] - sp50->pos.f[0], sp44.f[2] - sp50->pos.f[2]);
|
|
arg1->timer = 0;
|
|
|
|
#ifdef PORT
|
|
/* D307 probe: dump every input + the derived orientation so a PC run
|
|
* can be compared word-for-word against a ROM decode of the same
|
|
* record (facing-backwards CCTV report). Env-gated, load-time only. */
|
|
if (getenv("GE_D307")) {
|
|
fprintf(stderr,
|
|
"D307: cctv cmd=%d obj=%d pad=%d bound=%d pos=(%.6g,%.6g,%.6g) "
|
|
"mtx=(%.6g,%.6g,%.6g %.6g,%.6g,%.6g %.6g,%.6g,%.6g) "
|
|
"sw=(%.6g,%.6g,%.6g) watch=(%.6g,%.6g,%.6g) padpos=(%.6g,%.6g,%.6g) "
|
|
"target=(%.6g,%.6g,%.6g) C4=%.6f CC=%.6f basis=(%.6g,%.6g,%.6g %.6g,%.6g,%.6g %.6g,%.6g,%.6g)\n",
|
|
cmdindex, arg1->obj, arg1->pad, !isNotBoundPad(arg1->pad),
|
|
arg1->prop->pos.f[0], arg1->prop->pos.f[1], arg1->prop->pos.f[2],
|
|
arg1->mtx.m[0][0], arg1->mtx.m[0][1], arg1->mtx.m[0][2],
|
|
arg1->mtx.m[1][0], arg1->mtx.m[1][1], arg1->mtx.m[1][2],
|
|
arg1->mtx.m[2][0], arg1->mtx.m[2][1], arg1->mtx.m[2][2],
|
|
temp_a2->f[0], temp_a2->f[1], temp_a2->f[2],
|
|
sp44.f[0], sp44.f[1], sp44.f[2],
|
|
sp50->pos.f[0], sp50->pos.f[1], sp50->pos.f[2],
|
|
sp44.f[0] - sp50->pos.f[0], sp44.f[1] - sp50->pos.f[1], sp44.f[2] - sp50->pos.f[2],
|
|
arg1->unkC4, arg1->unkCC,
|
|
sp3C->m[0][0], sp3C->m[0][1], sp3C->m[0][2],
|
|
sp3C->m[1][0], sp3C->m[1][1], sp3C->m[1][2],
|
|
sp3C->m[2][0], sp3C->m[2][1], sp3C->m[2][2]);
|
|
if (arg1->pad == 10018) {
|
|
for (int d307i = 16; d307i <= 24; d307i++) {
|
|
struct PadRecord *d307p = &g_CurrentSetup.boundpads[d307i];
|
|
fprintf(stderr, "D307: bpad[%d] ptr=%p pos=(%.6g,%.6g,%.6g)\n",
|
|
d307i, (void *)d307p,
|
|
d307p->pos.f[0], d307p->pos.f[1], d307p->pos.f[2]);
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
|
|
void setupAutogun(s32 stageID, AutogunRecord *autogun, s32 cmdindex)
|
|
{
|
|
s8 *beam;
|
|
|
|
domakedefaultobj(stageID, (ObjectRecord *) autogun, cmdindex);
|
|
|
|
#ifdef VERSION_EU
|
|
autogun->speed = ((*((s32 *) (&autogun->speed))) * 7.5398226f) / 65536.0f;
|
|
autogun->aimdist = ((*((s32 *) (&autogun->aimdist))) * 100.0f) / 65536.0f;
|
|
autogun->unk88 = ((*((s32 *) (&autogun->unk88))) * M_TAU_F) / 65536.0f;
|
|
autogun->unk8C = ((*((s32 *) (&autogun->unk8C))) * M_TAU_F) / 65536.0f;
|
|
#endif
|
|
|
|
autogun->unkAC = 0;
|
|
autogun->unkB8 = -1;
|
|
autogun->unkBC = -1;
|
|
autogun->unkC0 = -1;
|
|
autogun->unkC4 = 0;
|
|
autogun->unkC8 = 0;
|
|
autogun->unk90 = 0.0f;
|
|
autogun->unk94 = 0.0f;
|
|
autogun->rot_related = 0.0f;
|
|
autogun->unk9C = 0.0f;
|
|
autogun->unkA0 = 0.0f;
|
|
autogun->unk98 = 0.0f;
|
|
autogun->unkB0 = 0.0f;
|
|
autogun->unkB4 = 0.0f;
|
|
|
|
#ifndef VERSION_EU
|
|
autogun->speed = ((*((s32 *) (&autogun->speed))) * M_TAU_F) / 65536.0f;
|
|
autogun->aimdist = ((*((s32 *) (&autogun->aimdist))) * 100.0f) / 65536.0f;
|
|
autogun->unk88 = ((*((s32 *) (&autogun->unk88))) * M_TAU_F) / 65536.0f;
|
|
autogun->unk8C = ((*((s32 *) (&autogun->unk8C))) * M_TAU_F) / 65536.0f;
|
|
#endif
|
|
|
|
beam = mempAllocBytesInBank(0x30U, MEMPOOL_STAGE);
|
|
autogun->beam = beam;
|
|
*beam = -1;
|
|
|
|
autogun->is_active = FALSE;
|
|
autogun->unkD4 = 0.0f;
|
|
|
|
if (autogun->padID >= 0)
|
|
{
|
|
s32 stack1;
|
|
f32 xdiff;
|
|
f32 ydiff;
|
|
f32 zdiff;
|
|
PadRecord *pad;
|
|
PropRecord *prop;
|
|
|
|
if (autogun->padID < 0x2710)
|
|
{
|
|
if (1);
|
|
pad = &g_CurrentSetup.pads[autogun->padID];
|
|
}
|
|
else
|
|
{
|
|
pad = &g_CurrentSetup.boundpads[getBoundPadNum(autogun->padID)];
|
|
}
|
|
|
|
prop = autogun->prop;
|
|
|
|
xdiff = pad->pos.x - prop->pos.x;
|
|
ydiff = pad->pos.y - prop->pos.y;
|
|
zdiff = pad->pos.z - prop->pos.z;
|
|
|
|
autogun->rot_related = atan2f(xdiff, zdiff);
|
|
autogun->unk98 = atan2f(ydiff, sqrtf((xdiff * xdiff) + (zdiff * zdiff)));
|
|
}
|
|
}
|
|
|
|
|
|
//i should be object rack
|
|
void setupHangingMonitors(s32 arg0, ObjectRecord* rack, s32 cmdindex)
|
|
{
|
|
domakedefaultobj(arg0, rack, cmdindex);
|
|
}
|
|
|
|
|
|
void setupSingleMonitor(s32 stageID, MonitorObjRecord *monitor, s32 cmdindex)
|
|
{
|
|
MonitorRecord *record;
|
|
s32 unused;
|
|
s32 modelnum;
|
|
ObjectRecord *owner;
|
|
PropRecord *prop;
|
|
f32 scale;
|
|
|
|
monitor->Monitor = g_MonitorAnimController;
|
|
record = &monitor->Monitor;
|
|
monitorSetImageByNum(&monitor->Monitor, monitor->ImageNum);
|
|
|
|
if (monitor->pad < 0 && (monitor->flags & PROPFLAG_INSIDEANOTHEROBJ) == 0)
|
|
{
|
|
modelnum = monitor->obj;
|
|
owner = (struct ObjectRecord *)setupGetPtrToCommandByIndex(cmdindex + monitor->OwnerOffset);
|
|
|
|
modelLoad(modelnum);
|
|
|
|
scale = monitor->extrascale * (1.0f / 256.0f);
|
|
monitor->damage = *(s32*)&monitor->damage / M_U16_MAX_VALUE_F;
|
|
|
|
if (getPlayerCount() >= 2)
|
|
{
|
|
monitor->state |= PROPSTATE_RESPAWN;
|
|
}
|
|
|
|
prop = objInitWithAutoModel((ObjectRecord*)monitor);
|
|
monitor->embedment = embedmentAllocate();
|
|
|
|
if (prop && monitor->embedment)
|
|
{
|
|
monitor->runtime_bitflags |= RUNTIMEBITFLAG_EMBEDDED;
|
|
modelSetScale(monitor->model, monitor->model->scale * scale);
|
|
monitor->model->attachedto = owner->model;
|
|
|
|
if (monitor->OwnerPart == 0)
|
|
{
|
|
monitor->model->attachedto_objinst = owner->model->obj->Switches[0];
|
|
}
|
|
else if (monitor->OwnerPart == 1)
|
|
{
|
|
monitor->model->attachedto_objinst = owner->model->obj->Switches[1];
|
|
}
|
|
else if (monitor->OwnerPart == 2)
|
|
{
|
|
monitor->model->attachedto_objinst = owner->model->obj->Switches[2];
|
|
}
|
|
else
|
|
{
|
|
monitor->model->attachedto_objinst = owner->model->obj->Switches[3];;
|
|
}
|
|
|
|
chrpropReparent(prop, owner->prop);
|
|
matrix_4x4_set_rotation_around_x(0.36651915f, (Mtxf*)&monitor->embedment->matrix);
|
|
matrix_scalar_multiply(monitor->model->scale / owner->model->scale, (f32*)&monitor->embedment->matrix);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
domakedefaultobj(stageID, (ObjectRecord*)monitor, cmdindex);
|
|
}
|
|
|
|
if ((monitor->flags & PROPFLAG_MONITOR_RENDERPOSTBG) && monitor->prop)
|
|
{
|
|
monitor->prop->flags |= PROPFLAG_RENDERPOSTBG;
|
|
}
|
|
}
|
|
|
|
|
|
void setupMultiMonitor(s32 stageID, MultiMonitorObjRecord* monitor, s32 cmdindex)
|
|
{
|
|
monitor->Monitor[0] = g_MonitorAnimController;
|
|
monitorSetImageByNum(&monitor->Monitor[0], monitor->ImageNums[0]);
|
|
|
|
monitor->Monitor[1] = g_MonitorAnimController;
|
|
monitorSetImageByNum(&monitor->Monitor[1], monitor->ImageNums[1]);
|
|
|
|
monitor->Monitor[2] = g_MonitorAnimController;
|
|
monitorSetImageByNum(&monitor->Monitor[2], monitor->ImageNums[2]);
|
|
|
|
monitor->Monitor[3] = g_MonitorAnimController;
|
|
monitorSetImageByNum(&monitor->Monitor[3], monitor->ImageNums[3]);
|
|
|
|
domakedefaultobj(stageID, monitor, cmdindex);
|
|
}
|
|
|
|
void sub_GAME_7F00324C(struct BoundPadRecord *arg0, s32 *arg1, s32 *arg2, struct coord3d *arg3, struct coord3d *arg4)
|
|
{
|
|
StandTile *sp4C;
|
|
struct coord3d normal;
|
|
s32 padding;
|
|
struct coord3d center;
|
|
StandTile *sp2C;
|
|
f32 scale;
|
|
|
|
sub_GAME_7F001BD4(arg0, ¢er);
|
|
sp2C = (StandTile *)arg0->stan;
|
|
|
|
if (walkTilesBetweenPoints_NoCallback(&sp2C, arg0->pos.f[0], arg0->pos.f[2], center.f[0], center.f[2]) == 0)
|
|
{
|
|
sp2C = (StandTile *)arg0->stan;
|
|
center.f[0] = arg0->pos.f[0];
|
|
center.f[1] = arg0->pos.f[1];
|
|
center.f[2] = arg0->pos.f[2];
|
|
}
|
|
|
|
normal.f[0] = (arg0->up.f[1] * arg0->look.f[2]) - (arg0->up.f[2] * arg0->look.f[1]);
|
|
normal.f[1] = (arg0->up.f[2] * arg0->look.f[0]) - (arg0->up.f[0] * arg0->look.f[2]);
|
|
normal.f[2] = (arg0->up.f[0] * arg0->look.f[1]) - (arg0->up.f[1] * arg0->look.f[0]);
|
|
|
|
scale = 1.0f / sqrtf(((normal.f[0] * normal.f[0]) + (normal.f[1] * normal.f[1])) + (normal.f[2] * normal.f[2]));
|
|
sp4C = sp2C;
|
|
|
|
normal.f[0] *= scale;
|
|
normal.f[1] *= scale;
|
|
normal.f[2] *= scale;
|
|
|
|
arg3->f[0] = center.f[0] + (normal.f[0] * 50.0f);
|
|
arg3->f[1] = center.f[1];
|
|
arg3->f[2] = center.f[2] + (normal.f[2] * 50.0f);
|
|
|
|
|
|
walkTilesBetweenPoints_NoCallback(&sp4C, center.f[0], center.f[2], arg3->f[0], arg3->f[2]);
|
|
|
|
if (1);
|
|
|
|
*arg1 = (s32) sp4C->room;
|
|
sp4C = sp2C;
|
|
|
|
arg4->f[0] = center.f[0] - (normal.f[0] * 50.0f);
|
|
arg4->f[1] = center.f[1];
|
|
arg4->f[2] = center.f[2] - (normal.f[2] * 50.0f);
|
|
|
|
walkTilesBetweenPoints_NoCallback(&sp4C, center.f[0], center.f[2], arg4->f[0], arg4->f[2]);
|
|
|
|
if (1);
|
|
|
|
*arg2 = (s32) sp4C->room;
|
|
|
|
if (*arg2 == *arg1)
|
|
{
|
|
*arg2 = -1;
|
|
}
|
|
}
|
|
|
|
|
|
extern f32 g_DoorScale;
|
|
/**
|
|
*
|
|
* NTSC ADDRESS: 7F003480
|
|
* PAL ADDRESS: 7F0033F0
|
|
* Perfect Dark: void setupCreateDoor(struct doorobj *door, s32 cmdindex)
|
|
*/
|
|
void setupDoor(s32 arg0, struct DoorRecord *door, s32 arg2)
|
|
{
|
|
s32 padding; // no sp
|
|
s32 modelnum;
|
|
struct BoundPadRecord *pad;
|
|
StandTile *sp1C8_stan;
|
|
PropRecord *prop;
|
|
struct coord3d sp1B8;
|
|
s32 portalnum; //sp1b4
|
|
s32 sp1B0;
|
|
s32 sp1AC;
|
|
struct coord3d sp1A0;
|
|
struct coord3d sp194;
|
|
struct PortalMetric sp180;
|
|
struct ModelRoData_BoundingBoxRecord *temp_v0;
|
|
struct coord3d sp170;
|
|
StandTile *sp16C;
|
|
Mtxf sp12C;
|
|
f32 temp_f2; // no sp
|
|
ModelFileHeader *sp124;
|
|
struct coord3d sp118; /* compiler-managed */
|
|
StandTile *sp114_stan;
|
|
Mtxf spD4;
|
|
struct coord3d spC8;
|
|
Mtxf sp88;
|
|
struct coord3d sp7C;
|
|
struct bbox bb2;
|
|
f32 xscale;
|
|
f32 yscale;
|
|
f32 zscale;
|
|
f32 scale;
|
|
//StandTile *stan;
|
|
u8 *padding2;
|
|
|
|
modelnum = door->obj;
|
|
|
|
portalnum = -1;
|
|
sp1B0 = -1;
|
|
sp1AC = -1;
|
|
|
|
modelLoad(modelnum);
|
|
|
|
pad = &(g_CurrentSetup.boundpads[door->pad]);
|
|
|
|
if ((door->flags & PROPFLAG_CULL_BEHIND_DOOR) || (door->flags & PROPFLAG_NO_PORTAL_CLOSE))
|
|
{
|
|
sub_GAME_7F00324C(pad, &sp1B0, &sp1AC, &sp1A0, &sp194);
|
|
|
|
if ((door->flags & PROPFLAG_CULL_BEHIND_DOOR) && (sp1B0 >= 0) && (sp1AC >= 0))
|
|
{
|
|
portalnum = bgGetPortalBetweenRooms(sp1B0, sp1AC, &sp1A0, &sp194);
|
|
}
|
|
}
|
|
|
|
if (g_DoorScale != 1.0f)
|
|
{
|
|
if (portalnum >= 0)
|
|
{
|
|
sub_GAME_7F0B96CC(portalnum, &sp180);
|
|
sp180.min *= get_room_data_float2();
|
|
|
|
temp_f2 = (pad->pos.f[0] * sp180.normal.f[0]) + (pad->pos.f[1] * sp180.normal.f[1]) + (pad->pos.f[2] * sp180.normal.f[2]);
|
|
|
|
if (g_DoorScale < 1.0f)
|
|
{
|
|
temp_f2 = (temp_f2 - sp180.min) * (1.0f - g_DoorScale);
|
|
sp170.f[0] = pad->pos.f[0] - (sp180.normal.f[0] * temp_f2);
|
|
sp170.f[1] = pad->pos.f[1] - (sp180.normal.f[1] * temp_f2);
|
|
sp170.f[2] = pad->pos.f[2] - (sp180.normal.f[2] * temp_f2);
|
|
}
|
|
else
|
|
{
|
|
temp_f2 = (temp_f2 - sp180.min) * (g_DoorScale - 1.0f);
|
|
sp170.f[0] = pad->pos.f[0] + (sp180.normal.f[0] * temp_f2);
|
|
sp170.f[1] = pad->pos.f[1] + (sp180.normal.f[1] * temp_f2);
|
|
sp170.f[2] = pad->pos.f[2] + (sp180.normal.f[2] * temp_f2);
|
|
}
|
|
|
|
sp16C = pad->stan;
|
|
if (walkTilesBetweenPoints_NoCallback(&sp16C, pad->pos.f[0], pad->pos.f[2], sp170.f[0], sp170.f[2]) != 0)
|
|
{
|
|
pad->stan = sp16C;
|
|
pad->pos.f[0] = sp170.f[0];
|
|
pad->pos.f[1] = sp170.f[1];
|
|
pad->pos.f[2] = sp170.f[2];
|
|
pad->bbox.xmin *= g_DoorScale;
|
|
pad->bbox.xmax *= g_DoorScale;
|
|
}
|
|
#ifdef DEBUG
|
|
else
|
|
{
|
|
osSyncPrintf("volume for door object number %d did not have depth changed!\n",arg2 + 1);
|
|
}
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
pad->bbox.xmin *= g_DoorScale;
|
|
pad->bbox.xmax *= g_DoorScale;
|
|
}
|
|
}
|
|
|
|
if (getposstan(&pad->pos, pad->stan, 0.0f, &sp1B8, &sp1C8_stan) != 0)
|
|
{
|
|
matrix_4x4_set_basis_and_position_target(&sp12C, 0, 0, 0, -pad->look.f[0], -pad->look.f[1], -pad->look.f[2], pad->up.f[0], pad->up.f[1], pad->up.f[2]);
|
|
sp124 = PitemZ_entries[modelnum].header;
|
|
sp114_stan = sp1C8_stan;
|
|
|
|
bb2.zmax = pad->bbox.xmin;
|
|
bb2.zmin = pad->bbox.xmax; //78
|
|
bb2.ymax = pad->bbox.ymin; //74
|
|
bb2.ymin = pad->bbox.ymax; //70
|
|
bb2.xmax = pad->bbox.zmin; //6c
|
|
bb2.xmin = pad->bbox.zmax; //68
|
|
|
|
matrix_4x4_set_rotation_around_x(M_HALF_PI, &spD4);
|
|
matrix_4x4_set_rotation_around_z(M_HALF_PI, &sp88);
|
|
matrix_4x4_multiply_in_place(&sp88, &spD4);
|
|
matrix_4x4_multiply_in_place(&sp12C, &spD4);
|
|
sub_GAME_7F001BD4(pad, &sp118);
|
|
|
|
temp_v0 = (struct ModelRoData_BoundingBoxRecord *)sp124->RootNode->Child->Data;
|
|
|
|
xscale = (bb2.ymin - bb2.ymax) / (temp_v0->Bounds.xmax - temp_v0->Bounds.xmin);
|
|
yscale = (bb2.xmin - bb2.xmax) / (temp_v0->Bounds.ymax - temp_v0->Bounds.ymin);
|
|
zscale = (bb2.zmin - bb2.zmax) / (temp_v0->Bounds.zmax - temp_v0->Bounds.zmin);
|
|
|
|
if ((xscale <= 0.000001f) || (yscale <= 0.000001f) || (zscale <= 0.000001f))
|
|
{
|
|
#ifdef DEBUG
|
|
osSyncPrintf("Scale warning: door object number %d has a small scale: %f,%f,%f\n",arg2 +1, xscale,yscale,zscale);
|
|
#endif
|
|
xscale =
|
|
yscale =
|
|
zscale = 1.0f;
|
|
}
|
|
|
|
matrix_column_1_scalar_multiply(xscale, spD4.m[0]);
|
|
matrix_column_2_scalar_multiply(yscale, spD4.m[0]);
|
|
matrix_column_3_scalar_multiply_2(zscale, spD4.m[0]);
|
|
|
|
spC8.f[0] = sp118.f[0];
|
|
spC8.f[1] = sp118.f[1];
|
|
spC8.f[2] = sp118.f[2];
|
|
|
|
if (!(door->flags2 & 1))
|
|
{
|
|
if (walkTilesBetweenPoints_NoCallback(&sp114_stan, sp1B8.f[0], sp1B8.f[2], sp118.f[0], sp118.f[2]) != 0)
|
|
{
|
|
sp1C8_stan = sp114_stan;
|
|
}
|
|
else
|
|
{
|
|
sp118.f[0] = sp1B8.f[0];
|
|
sp118.f[2] = sp1B8.f[2];
|
|
|
|
if (!(door->flags & 0x1000)) // prop flag PROPFLAG_00001000 "Absolute Position"
|
|
{
|
|
#ifdef DEBUG
|
|
osSyncPrintf("door object number %d not positioned correctly!\n",arg2 +1);
|
|
#endif
|
|
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
sp118.f[0] = sp1B8.f[0];
|
|
sp118.f[1] = sp1B8.f[1];
|
|
sp118.f[2] = sp1B8.f[2];
|
|
}
|
|
|
|
if ((door->doorType == DOORTYPE_VERTICAL) || (door->doorType == DOORTYPE_FALLAWAY))
|
|
{
|
|
sp7C.f[0] = pad->look.f[0] * (bb2.xmin - bb2.xmax);
|
|
sp7C.f[1] = pad->look.f[1] * (bb2.xmin - bb2.xmax);
|
|
sp7C.f[2] = pad->look.f[2] * (bb2.xmin - bb2.xmax);
|
|
}
|
|
else
|
|
{
|
|
sp7C.f[0] = pad->up.f[0] * (bb2.ymax - bb2.ymin);
|
|
sp7C.f[1] = pad->up.f[1] * (bb2.ymax - bb2.ymin);
|
|
sp7C.f[2] = pad->up.f[2] * (bb2.ymax - bb2.ymin);
|
|
}
|
|
|
|
// These values are stored in the setup files as integers, but at
|
|
// runtime they are floats. Hence reading a "float" as an integer,
|
|
// converting it to a float and writing it back to the same property.
|
|
door->maxFrac = *(s32 *) &door->maxFrac / 65536.0f;
|
|
door->perimFrac = *(s32 *) &door->perimFrac / 65536.0f;
|
|
#if defined(VERSION_EU)
|
|
door->accel = (*(s32 *) &door->accel) * 1.2f / 65536.0f;
|
|
door->decel = (*(s32 *) &door->decel) * 1.2f / 65536.0f;
|
|
door->maxSpeed = (*(s32 *) &door->maxSpeed) * 1.2f / 65536.0f;
|
|
#else
|
|
door->accel = (*(s32 *) &door->accel) / 65536.0f;
|
|
door->decel = (*(s32 *) &door->decel) / 65536.0f;
|
|
door->maxSpeed = (*(s32 *) &door->maxSpeed) / 65536.0f;
|
|
#endif
|
|
|
|
prop = doorInit(door, &sp118, &spD4, sp1C8_stan, &sp7C, &spC8);
|
|
if (door->flags & PROPFLAG_CULL_BEHIND_DOOR)
|
|
{
|
|
door->portalNumber = portalnum;
|
|
if ((portalnum >= 0) && (door->openPosition == 0.0f))
|
|
{
|
|
doorDeactivatePortal(door);
|
|
}
|
|
#ifdef DEBUG
|
|
else
|
|
{
|
|
osSyncPrintf("No portal for door object number %d ",arg2 + 1);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
prop->rooms[0] = prop->stan->room;
|
|
chrpropRegisterRoom(prop, prop->stan->room);
|
|
prop->rooms[1] = 0xFFU;
|
|
prop->rooms[2] = 0xFFU;
|
|
|
|
if ((door->flags & PROPFLAG_CULL_BEHIND_DOOR) || (door->flags & PROPFLAG_NO_PORTAL_CLOSE))
|
|
{
|
|
if (sp1B0 != prop->stan->room)
|
|
{
|
|
if (sp1B0 >= 0)
|
|
{
|
|
prop->rooms[1] = sp1B0;
|
|
chrpropRegisterRoom(prop, sp1B0);
|
|
}
|
|
}
|
|
else if (sp1AC >= 0)
|
|
{
|
|
prop->rooms[1] = sp1AC;
|
|
chrpropRegisterRoom(prop, sp1AC);
|
|
}
|
|
|
|
if (prop->rooms[1] != 0xff && 1)
|
|
{
|
|
if (!prop->stan->room)
|
|
{
|
|
#ifdef DEBUG
|
|
osSyncPrintf("3 rooms for door object number %d\n",arg2 + 1);
|
|
#endif
|
|
}
|
|
|
|
}
|
|
#ifdef DEBUG
|
|
else
|
|
{
|
|
osSyncPrintf("No 2nd room for door object number %d\n",arg2 + 1);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
if (door->model != NULL)
|
|
{
|
|
scale = xscale;
|
|
|
|
if (scale < yscale)
|
|
{
|
|
scale = yscale;
|
|
}
|
|
|
|
if (scale < zscale)
|
|
{
|
|
scale = zscale;
|
|
}
|
|
|
|
modelSetScale(door->model, door->model->scale * scale);
|
|
}
|
|
|
|
chrpropActivate(prop);
|
|
chrpropEnable(prop);
|
|
|
|
if (door->linkedDoorOffset != 0)
|
|
{
|
|
door->linkedDoor = (struct DoorRecord *)setupGetPtrToCommandByIndex(door->linkedDoorOffset + arg2);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
door->prop = NULL;
|
|
#ifdef DEBUG
|
|
osSyncPrintf("proplvreset: prop door object number %d not reset!\n",arg2 + 1);
|
|
#endif
|
|
}
|
|
|
|
}
|
|
|
|
|
|
// Perfect Dark void setupLoadFiles(s32 stagenum)
|
|
void proplvreset2(enum LEVELID stageId)
|
|
{
|
|
ItemModelFileRecord *pitem;
|
|
s32 withchrs;
|
|
s32 withobjs;
|
|
|
|
withchrs = (((void *) tokenFind(1, "-nochr")) == NULL) && (((void *) tokenFind(1, "-noprop")) == NULL);
|
|
withobjs = (((void *) tokenFind(1, "-noobj")) == NULL) && (((void *) tokenFind(1, "-noprop")) == NULL);
|
|
|
|
g_DoorScale = 1.0f;
|
|
|
|
/**
|
|
* Mark every prop model as "not resident" so the model loads later in this function actually fetch data. Essentially
|
|
* RootNode is doubling as a loaded flag for function modelLoad().
|
|
*
|
|
* The last entry in the PitemZ_entries table is a terminator which is why 1 is subtracted from the loop length.
|
|
*/
|
|
for (pitem = PitemZ_entries; pitem < &PitemZ_entries[ARRAYCOUNT(PitemZ_entries) - 1]; pitem++)
|
|
{
|
|
pitem->header->RootNode = NULL;
|
|
}
|
|
|
|
if ((stageId <= (LEVELID_MAX + 1)) && setup_text_pointers[stageId])
|
|
{
|
|
char strResource[0x100] = ""; // Scratch buffer for synthesizing the setup file's name at runtime.
|
|
s32 numAnimatedObjects = 0;
|
|
s32 numObjects = 0;
|
|
s32 i1 = 0;
|
|
s32 i2 = 0;
|
|
s32 i3 = 0;
|
|
f32 roompos_1;
|
|
s32 i5 = 0;
|
|
s32 i8;
|
|
f32 roompos_2;
|
|
struct stagesetup *local_stage;
|
|
|
|
strResource[0] = setup_text_pointers[stageId][0]; // 'U' -> "U"
|
|
strResource[1] = 0; // Terminate so strcat has a valid string.
|
|
|
|
/**
|
|
* There are no slots for the mp stages in setup_text_pointers. The name is created
|
|
* by adding "mp_" after the "U" e.g. "Ump_setuparchZ"
|
|
*/
|
|
if (getPlayerCount() >= 2)
|
|
{
|
|
strcat(strResource, "mp_"); // -> "Ump_"
|
|
}
|
|
|
|
strcat(strResource, setup_text_pointers[stageId] + 1); // Add remaining text back U[mp_] + setupxxxZ
|
|
|
|
g_ptrStageSetupFile = _fileNameLoadToBank(strResource, FILELOADMETHOD_DEFAULT, 256, MEMPOOL_STAGE);
|
|
|
|
local_stage = g_ptrStageSetupFile;
|
|
langLoadToAddr(langGetLangBankIndexFromStagenum(stageId));
|
|
|
|
/**
|
|
* The setup file stores every internal reference as a byte offset from the start of the file,
|
|
* so rebase them all onto the RAM copy at local_stage.
|
|
*/
|
|
#ifdef PORT
|
|
g_CurrentSetup.pathwaypoints = (void *) (((uintptr_t) local_stage) + ((u32) local_stage->pathwaypoints));
|
|
#else
|
|
g_CurrentSetup.pathwaypoints = (void *) (((u32) local_stage) + ((u32) local_stage->pathwaypoints));
|
|
#endif
|
|
#ifdef PORT
|
|
g_CurrentSetup.waypointgroups = (void *) (((uintptr_t) local_stage) + ((u32) local_stage->waypointgroups));
|
|
#else
|
|
g_CurrentSetup.waypointgroups = (void *) (((u32) local_stage) + ((u32) local_stage->waypointgroups));
|
|
#endif
|
|
#ifdef PORT
|
|
g_CurrentSetup.intro = (void *) (((uintptr_t) local_stage) + ((u32) local_stage->intro));
|
|
#else
|
|
g_CurrentSetup.intro = (void *) (((u32) local_stage) + ((u32) local_stage->intro));
|
|
#endif
|
|
#ifdef PORT
|
|
g_CurrentSetup.propDefs = (void *) (((uintptr_t) local_stage) + ((u32) local_stage->propDefs));
|
|
#else
|
|
g_CurrentSetup.propDefs = (void *) (((u32) local_stage) + ((u32) local_stage->propDefs));
|
|
#endif
|
|
#ifdef PORT
|
|
g_CurrentSetup.patrolpaths = (void *) (((uintptr_t) local_stage) + ((u32) local_stage->patrolpaths));
|
|
#else
|
|
g_CurrentSetup.patrolpaths = (void *) (((u32) local_stage) + ((u32) local_stage->patrolpaths));
|
|
#endif
|
|
#ifdef PORT
|
|
g_CurrentSetup.ailists = (void *) (((uintptr_t) local_stage) + ((u32) local_stage->ailists));
|
|
#else
|
|
g_CurrentSetup.ailists = (void *) (((u32) local_stage) + ((u32) local_stage->ailists));
|
|
#endif
|
|
#ifdef PORT
|
|
g_CurrentSetup.pads = (void *) (((uintptr_t) local_stage) + ((u32) local_stage->pads));
|
|
#else
|
|
g_CurrentSetup.pads = (void *) (((u32) local_stage) + ((u32) local_stage->pads));
|
|
#endif
|
|
#ifdef PORT
|
|
g_CurrentSetup.boundpads = (void *) (((uintptr_t) local_stage) + ((u32) local_stage->boundpads));
|
|
#else
|
|
g_CurrentSetup.boundpads = (void *) (((u32) local_stage) + ((u32) local_stage->boundpads));
|
|
#endif
|
|
|
|
// Pad names and bound names are optional. An offset of 0 means absent.
|
|
if (local_stage->padnames != 0)
|
|
{
|
|
#ifdef PORT
|
|
g_CurrentSetup.padnames = (void *) (((uintptr_t) local_stage) + ((u32) local_stage->padnames));
|
|
#else
|
|
g_CurrentSetup.padnames = (void *) (((u32) local_stage) + ((u32) local_stage->padnames));
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
g_CurrentSetup.padnames = NULL;
|
|
}
|
|
|
|
if (local_stage->boundpadnames != 0)
|
|
{
|
|
#ifdef PORT
|
|
g_CurrentSetup.boundpadnames = (void *) (((uintptr_t) local_stage) + ((u32) local_stage->boundpadnames));
|
|
#else
|
|
g_CurrentSetup.boundpadnames = (void *) (((u32) local_stage) + ((u32) local_stage->boundpadnames));
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
g_CurrentSetup.boundpadnames = NULL;
|
|
}
|
|
|
|
if (g_CurrentSetup.pathwaypoints)
|
|
{
|
|
for (i1 = 0; g_CurrentSetup.pathwaypoints[i1].padID >= 0; i1++)
|
|
{
|
|
#ifdef PORT
|
|
g_CurrentSetup.pathwaypoints[i1].neighbours = (void *) (((u32) g_CurrentSetup.pathwaypoints[i1].neighbours) + ((uintptr_t) local_stage));
|
|
#else
|
|
g_CurrentSetup.pathwaypoints[i1].neighbours = (void *) (((u32) g_CurrentSetup.pathwaypoints[i1].neighbours) + ((u32) local_stage));
|
|
#endif
|
|
}
|
|
}
|
|
|
|
if (g_CurrentSetup.waypointgroups)
|
|
{
|
|
for (i2 = 0; g_CurrentSetup.waypointgroups[i2].neighbours; i2++)
|
|
{
|
|
#ifdef PORT
|
|
g_CurrentSetup.waypointgroups[i2].neighbours = (void *) (((u32) g_CurrentSetup.waypointgroups[i2].neighbours) + ((uintptr_t) local_stage));
|
|
#else
|
|
g_CurrentSetup.waypointgroups[i2].neighbours = (void *) (((u32) g_CurrentSetup.waypointgroups[i2].neighbours) + ((u32) local_stage));
|
|
#endif
|
|
#ifdef PORT
|
|
g_CurrentSetup.waypointgroups[i2].waypoints = (void *) (((u32) g_CurrentSetup.waypointgroups[i2].waypoints) + ((uintptr_t) local_stage));
|
|
#else
|
|
g_CurrentSetup.waypointgroups[i2].waypoints = (void *) (((u32) g_CurrentSetup.waypointgroups[i2].waypoints) + ((u32) local_stage));
|
|
#endif
|
|
}
|
|
}
|
|
|
|
// Convert ailist pointers a.k.a. Action Blocks from file-local to proper pointers
|
|
{
|
|
AIListRecord *ailists = g_CurrentSetup.ailists;
|
|
if (ailists)
|
|
{
|
|
for (i3 = 0; g_CurrentSetup.ailists[i3].ailist != 0; i3++)
|
|
{
|
|
#ifdef PORT
|
|
g_CurrentSetup.ailists[i3].ailist = (void *) (((u32) g_CurrentSetup.ailists[i3].ailist) + ((uintptr_t) local_stage));
|
|
#else
|
|
g_CurrentSetup.ailists[i3].ailist = (void *) (((u32) g_CurrentSetup.ailists[i3].ailist) + ((u32) local_stage));
|
|
#endif
|
|
}
|
|
}
|
|
}
|
|
|
|
if (g_CurrentSetup.patrolpaths)
|
|
{
|
|
for (i3 = 0; g_CurrentSetup.patrolpaths[i3].waypoints != NULL; i3++)
|
|
{
|
|
#ifdef PORT
|
|
g_CurrentSetup.patrolpaths[i3].waypoints = (void *) (((u32) g_CurrentSetup.patrolpaths[i3].waypoints) + ((uintptr_t) local_stage));
|
|
#else
|
|
g_CurrentSetup.patrolpaths[i3].waypoints = (void *) (((u32) g_CurrentSetup.patrolpaths[i3].waypoints) + ((u32) local_stage));
|
|
#endif
|
|
|
|
for (i5 = 0; g_CurrentSetup.patrolpaths[i3].waypoints[i5] >= 0; i5++)
|
|
{
|
|
// Empty
|
|
}
|
|
|
|
g_CurrentSetup.patrolpaths[i3].len = i5;
|
|
}
|
|
}
|
|
|
|
if (g_CurrentSetup.pads)
|
|
{
|
|
struct PadRecord *pad;
|
|
|
|
roompos_1 = get_room_data_float2();
|
|
pad = g_CurrentSetup.pads;
|
|
|
|
for (; pad->plink != NULL; pad++)
|
|
{
|
|
#ifdef PORT
|
|
pad->plink = (void *) (((uintptr_t) local_stage) + ((u32) pad->plink));
|
|
#else
|
|
pad->plink = (void *) (((u32) local_stage) + ((u32) pad->plink));
|
|
#endif
|
|
pad->pos.f[0] *= roompos_1;
|
|
pad->pos.f[1] *= roompos_1;
|
|
pad->pos.f[2] *= roompos_1;
|
|
|
|
|
|
#ifdef DEBUG
|
|
{
|
|
s32 sret = init_pathtable_something(pad, pad->plink, &pad->stan);
|
|
if (sret == 0)
|
|
{
|
|
osSyncPrintf("pad number %d has no stan! (%s)\n", (s32)(pad - g_CurrentSetup.pads), pad->plink);
|
|
}
|
|
else if (sret == 2)
|
|
{
|
|
osSyncPrintf("pad number %d changed stan from %s to %s\n", (s32)(pad - g_CurrentSetup.pads), pad->plink, GetStanName(pad->stan));
|
|
}
|
|
}
|
|
#else
|
|
init_pathtable_something(pad, pad->plink, &pad->stan);
|
|
#endif
|
|
|
|
if (1);
|
|
}
|
|
}
|
|
|
|
if (g_CurrentSetup.boundpads)
|
|
{
|
|
struct BoundPadRecord *vol;
|
|
|
|
roompos_2 = get_room_data_float2();
|
|
vol = g_CurrentSetup.boundpads;
|
|
|
|
for (; vol->plink != NULL; vol++)
|
|
{
|
|
/** Ugly matching hack.
|
|
* TODO: investigate if there's a way to get rid of this.
|
|
*/
|
|
if ((((u32) local_stage) ^ 0) + ((u32)vol->plink));
|
|
|
|
#ifdef PORT
|
|
vol->plink = (void *) (((uintptr_t) local_stage) + ((u32)vol->plink));
|
|
#else
|
|
vol->plink = (void *) (((u32) local_stage) + ((u32)vol->plink));
|
|
#endif
|
|
vol->pos.f[0] *= roompos_2;
|
|
vol->pos.f[1] *= roompos_2;
|
|
vol->pos.f[2] *= roompos_2;
|
|
vol->bbox.xmin *= roompos_2;
|
|
vol->bbox.xmax *= roompos_2;
|
|
vol->bbox.ymin *= roompos_2;
|
|
vol->bbox.ymax *= roompos_2;
|
|
vol->bbox.zmin *= roompos_2;
|
|
vol->bbox.zmax *= roompos_2;
|
|
|
|
#ifdef DEBUG
|
|
{
|
|
s32 sret = init_pathtable_something((struct PadRecord *) vol, vol->plink, &vol->stan);
|
|
if (sret == 0)
|
|
{
|
|
osSyncPrintf("vol number %d has no stan! (%s)\n", (s32)(vol - g_CurrentSetup.boundpads), vol->plink);
|
|
}
|
|
else if (sret == 2)
|
|
{
|
|
osSyncPrintf("vol number %d changed stan from %s to %s\n", (s32)(vol - g_CurrentSetup.boundpads), vol->plink, GetStanName(vol->stan));
|
|
}
|
|
}
|
|
#else
|
|
init_pathtable_something((struct PadRecord *) vol, vol->plink, &vol->stan);
|
|
#endif
|
|
|
|
if (1);
|
|
}
|
|
}
|
|
|
|
if (g_CurrentSetup.padnames)
|
|
{
|
|
for (i1 = 0; g_CurrentSetup.padnames[i1].p; i1++)
|
|
{
|
|
#ifdef PORT
|
|
g_CurrentSetup.padnames[i1].p = (void *) (((u32) g_CurrentSetup.padnames[i1].p) + ((uintptr_t) local_stage));
|
|
#else
|
|
g_CurrentSetup.padnames[i1].p = (void *) (((u32) g_CurrentSetup.padnames[i1].p) + ((u32) local_stage));
|
|
#endif
|
|
}
|
|
}
|
|
|
|
if (g_CurrentSetup.boundpadnames)
|
|
{
|
|
// Required for matching.
|
|
if (g_CurrentSetup.ailists && g_CurrentSetup.ailists);
|
|
|
|
for (i1 = 0; g_CurrentSetup.boundpadnames[i1].p; i1++)
|
|
{
|
|
#ifdef PORT
|
|
g_CurrentSetup.boundpadnames[i1].p = (void *) (((u32) g_CurrentSetup.boundpadnames[i1].p) + ((uintptr_t) local_stage));
|
|
#else
|
|
g_CurrentSetup.boundpadnames[i1].p = (void *) (((u32) g_CurrentSetup.boundpadnames[i1].p) + ((u32) local_stage));
|
|
#endif
|
|
}
|
|
}
|
|
|
|
// PD rejoins here
|
|
|
|
if (withchrs)
|
|
{
|
|
alloc_init_GUARDdata_entries(load_proptype(PROPDEF_GUARD));
|
|
numAnimatedObjects += load_proptype(PROPDEF_GUARD);
|
|
numObjects += load_proptype(PROPDEF_COLLECTABLE);
|
|
numObjects += load_proptype(PROPDEF_KEY);
|
|
numObjects += load_proptype(PROPDEF_HAT);
|
|
}
|
|
else
|
|
{
|
|
alloc_init_GUARDdata_entries(0); // chrmgrConfigure
|
|
}
|
|
|
|
if (withobjs)
|
|
{
|
|
// load std props for all stages
|
|
numObjects += load_proptype(PROPDEF_DOOR);
|
|
numObjects += load_proptype(PROPDEF_CCTV);
|
|
numObjects += load_proptype(PROPDEF_AUTOGUN);
|
|
numObjects += load_proptype(PROPDEF_RACK);
|
|
numObjects += load_proptype(PROPDEF_MONITOR);
|
|
numObjects += load_proptype(PROPDEF_MULTI_MONITOR);
|
|
numObjects += load_proptype(PROPDEF_ARMOUR);
|
|
numObjects += load_proptype(PROPDEF_PROP);
|
|
numObjects += load_proptype(PROPDEF_GLASS);
|
|
numObjects += load_proptype(PROPDEF_TINTED_GLASS);
|
|
numObjects += load_proptype(PROPDEF_SAFE);
|
|
numObjects += load_proptype(PROPDEF_UNK41);
|
|
numObjects += load_proptype(PROPDEF_GAS_RELEASING);
|
|
numObjects += load_proptype(PROPDEF_ALARM);
|
|
numObjects += load_proptype(PROPDEF_MAGAZINE);
|
|
numObjects += load_proptype(PROPDEF_AMMO);
|
|
numObjects += load_proptype(PROPDEF_VEHICHLE);
|
|
numObjects += load_proptype(PROPDEF_TANK);
|
|
numAnimatedObjects += load_proptype(PROPDEF_AIRCRAFT);
|
|
}
|
|
|
|
modelmgrAllocateModelSlots(numObjects);
|
|
modelmgrAllocateAnimModelSlots(numAnimatedObjects);
|
|
|
|
for (i8 = 0; i8 < getPlayerCount(); i8++)
|
|
{
|
|
set_cur_player(i8);
|
|
alloc_additional_item_slots(load_proptype(PROPDEF_LINK));
|
|
}
|
|
|
|
if (g_CurrentSetup.propDefs)
|
|
{
|
|
PropDefHeaderRecord *phead;
|
|
s32 flags;
|
|
s32 pdefIndex;
|
|
|
|
// per-difficulty "Don't Load" mask: PROPFLAG2_00000010/20/40 for Agent/Secret/00
|
|
flags = 1 << (lvlGetSelectedDifficulty() + 4);
|
|
|
|
/**
|
|
* Complete the skip loading mask started on the line above. Checks for:
|
|
* - don't load on 2 players
|
|
* - don't load on 3 players
|
|
* - don't load on 4 players
|
|
* - don't load in multiplayer
|
|
*/
|
|
if (getPlayerCount() >= 2)
|
|
{
|
|
flags |= 1 << (getPlayerCount() + 20);
|
|
}
|
|
|
|
phead = g_CurrentSetup.propDefs;
|
|
pdefIndex = 0;
|
|
|
|
while ((i1 = phead->type) != PROPDEF_END)
|
|
{
|
|
switch (phead->type)
|
|
{
|
|
case PROPDEF_GUARD_ATTRIBUTE:
|
|
{
|
|
GuardAttributeRecord *pdef_guarda;
|
|
u8 prob;
|
|
ChrRecord *chr;
|
|
pdef_guarda = (GuardAttributeRecord *) phead;
|
|
prob = (u8) pdef_guarda->GrenadeProb;
|
|
chr = chrFindByLiteralId(pdef_guarda->chrnum);
|
|
if ((chr && chr->prop) && chr->model)
|
|
{
|
|
chr->grenadeprob = prob;
|
|
}
|
|
#ifdef DEBUG
|
|
else
|
|
{
|
|
osSyncPrintf("grenade prob: no chr number %d for obj number %d! ", pdef_guarda->GrenadeProb, pdefIndex + 1);
|
|
}
|
|
#endif
|
|
break;
|
|
}
|
|
case PROPDEF_GUARD:
|
|
if (withchrs)
|
|
{
|
|
expand_09_characters(stageId, (struct GuardRecord *) phead, pdefIndex);
|
|
}
|
|
break;
|
|
case PROPDEF_DOOR:
|
|
if (withobjs && (!(((struct DoorRecord *) phead)->flags2 & flags)))
|
|
{
|
|
setupDoor(stageId, (struct DoorRecord *) phead, pdefIndex);
|
|
}
|
|
break;
|
|
case PROPDEF_DOOR_SCALE:
|
|
g_DoorScale = ((struct GlobalDoorScaleRecord *) phead)->Scale / M_U16_MAX_VALUE_F;
|
|
break;
|
|
case PROPDEF_COLLECTABLE:
|
|
if (withchrs && (!(((struct WeaponObjRecord *) phead)->flags2 & flags)))
|
|
{
|
|
weaponAssignToHome(stageId, (struct WeaponObjRecord *) phead, pdefIndex);
|
|
}
|
|
break;
|
|
case PROPDEF_KEY:
|
|
if (withchrs && (!(((struct KeyRecord *) phead)->flags2 & flags)))
|
|
{
|
|
setupKey(stageId, (struct ObjectRecord *) phead, pdefIndex);
|
|
}
|
|
break;
|
|
case PROPDEF_HAT:
|
|
if (withchrs && (!(((struct ObjectRecord *) phead)->flags2 & flags)))
|
|
{
|
|
setupHat(stageId, (struct ObjectRecord *) phead, pdefIndex);
|
|
}
|
|
break;
|
|
case PROPDEF_CCTV:
|
|
if (withobjs && (!(((struct CCTVRecord *) phead)->flags2 & flags)))
|
|
{
|
|
setupCctv(stageId, (struct CCTVRecord *) phead, pdefIndex);
|
|
}
|
|
break;
|
|
case PROPDEF_AUTOGUN:
|
|
if (withobjs && (!(((struct AutogunRecord *) phead)->flags2 & flags)))
|
|
{
|
|
setupAutogun(stageId, (struct AutogunRecord *) phead, pdefIndex);
|
|
}
|
|
break;
|
|
case PROPDEF_RACK:
|
|
if (withobjs && (!(((struct ObjectRecord *) phead)->flags2 & flags)))
|
|
{
|
|
setupHangingMonitors(stageId, (struct ObjectRecord *) phead, pdefIndex);
|
|
}
|
|
break;
|
|
case PROPDEF_MONITOR:
|
|
if (withobjs && (!(((struct MonitorObjRecord *) phead)->flags2 & flags)))
|
|
{
|
|
setupSingleMonitor(stageId, (struct MonitorObjRecord *) phead, pdefIndex);
|
|
}
|
|
break;
|
|
case PROPDEF_MULTI_MONITOR:
|
|
if (withobjs && (!(((struct MultiMonitorObjRecord *) phead)->flags2 & flags)))
|
|
{
|
|
setupMultiMonitor(stageId, (struct MultiMonitorObjRecord *) phead, pdefIndex);
|
|
}
|
|
break;
|
|
case PROPDEF_ARMOUR:
|
|
{
|
|
struct BodyArmourRecord *pdef_ba = (struct BodyArmourRecord *) phead;
|
|
#ifndef VERSION_US
|
|
if (withobjs && (((pdef_ba->flags2 & flags) == 0) || j_text_trigger)) // JP: armour setup also proceeds when j_text_trigger is set
|
|
#else
|
|
if (withobjs && ((pdef_ba->flags2 & flags) == 0))
|
|
#endif
|
|
{
|
|
pdef_ba->initialamount = (*((s32 *) (&pdef_ba->initialamount))) / M_U16_MAX_VALUE_F;
|
|
pdef_ba->amount = pdef_ba->initialamount;
|
|
domakedefaultobj(stageId, (struct ObjectRecord *) phead, pdefIndex);
|
|
}
|
|
break;
|
|
}
|
|
case PROPDEF_TINTED_GLASS:
|
|
{
|
|
if (withobjs && (!(((struct TintedGlassRecord *) phead)->flags2 & flags)))
|
|
{
|
|
if (((struct TintedGlassRecord *) phead)->flags & PROPFLAG_GLASS_HASPORTAL)
|
|
{
|
|
if (!(((struct TintedGlassRecord *) phead)->pad < 10000))
|
|
{
|
|
struct coord3d up;
|
|
struct coord3d up2;
|
|
BoundPadRecord *pad3d;
|
|
|
|
pad3d = &g_CurrentSetup.boundpads[((struct TintedGlassRecord *) phead)->pad - 10000];
|
|
sub_GAME_7F001BD4(pad3d, &up);
|
|
up2.x = (10.0f * pad3d->up.x) + up.x;
|
|
up2.y = (10.0f * pad3d->up.y) + up.y;
|
|
up2.z = (10.0f * pad3d->up.z) + up.z;
|
|
up.x -= 10.0f * pad3d->up.x;
|
|
up.y -= 10.0f * pad3d->up.y;
|
|
up.z -= 10.0f * pad3d->up.z;
|
|
|
|
((struct TintedGlassRecord *) phead)->portalnum = sub_GAME_7F0B9E04(&up, &up2);
|
|
((struct TintedGlassRecord *) phead)->unk90 = (*((s32 *) (&((struct TintedGlassRecord *) phead)->unk90))) / M_U16_MAX_VALUE_F;
|
|
}
|
|
}
|
|
domakedefaultobj(stageId, (struct ObjectRecord *) phead, pdefIndex);
|
|
}
|
|
break;
|
|
}
|
|
case PROPDEF_PROP:
|
|
case PROPDEF_ALARM:
|
|
case PROPDEF_MAGAZINE:
|
|
case PROPDEF_GAS_RELEASING:
|
|
case PROPDEF_UNK41:
|
|
case PROPDEF_GLASS:
|
|
case PROPDEF_SAFE:
|
|
if (withobjs && (!(((ObjectRecord *) phead)->flags2 & flags)))
|
|
{
|
|
domakedefaultobj(stageId, (struct ObjectRecord *) phead, pdefIndex);
|
|
}
|
|
break;
|
|
case PROPDEF_AMMO:
|
|
{
|
|
struct MultiAmmoCrateRecord *pdef_macr = (struct MultiAmmoCrateRecord *) phead;
|
|
s32 ammoqty = 1;
|
|
s32 i9;
|
|
|
|
if (getPlayerCount() >= 2)
|
|
{
|
|
struct s_mp_weapon_set *mpweapon = &getPtrMPWeaponSetData()[lastmpweaponnum];
|
|
|
|
ammoqty = mpweapon->ammoamount;
|
|
if (mpweapon->ammotype);
|
|
pdef_macr->slots[mpweapon->ammotype - 1].quantity = ammoqty;
|
|
}
|
|
|
|
if (((ammoqty > 0) && withobjs) && (!(pdef_macr->flags2 & flags)))
|
|
{
|
|
for (i9 = 0; i9 < AMMOTYPE_GLOBAL_MAX; i9++)
|
|
{
|
|
if ((pdef_macr->slots[i9].quantity > 0) && (pdef_macr->slots[i9].modelnum != 0xFFFF))
|
|
{
|
|
modelLoad(pdef_macr->slots[i9].modelnum);
|
|
}
|
|
}
|
|
|
|
domakedefaultobj(stageId, (struct ObjectRecord *) pdef_macr, pdefIndex);
|
|
}
|
|
break;
|
|
}
|
|
case PROPDEF_TANK:
|
|
if (withobjs && (!(((struct TankRecord *) phead)->flags2 & flags)))
|
|
{
|
|
struct TankRecord *pdef_tank = (struct TankRecord *) phead;
|
|
struct PropRecord *tank_prop;
|
|
|
|
s32 padding;
|
|
f32 stan_y = 0.0f;
|
|
s32 paddinggg[4];
|
|
|
|
weaponLoadProjectileModels(ITEM_TANKSHELLS);
|
|
domakedefaultobj(stageId, (struct ObjectRecord *) pdef_tank, pdefIndex);
|
|
pdef_tank->turret_vertical_angle = 0.0f;
|
|
pdef_tank->turret_orientation_angle = 0.0f;
|
|
pdef_tank->tank_orientation_angle = M_TAU_F - atan2f(pdef_tank->mtx.m[2][0], pdef_tank->mtx.m[2][2]);
|
|
tank_prop = pdef_tank->prop;
|
|
|
|
if (tank_prop)
|
|
{
|
|
stan_y = stanGetPositionYValue(tank_prop->stan, tank_prop->pos.f[0], tank_prop->pos.f[2]);
|
|
}
|
|
|
|
pdef_tank->stan_y = stan_y;
|
|
#ifdef VERSION_EU
|
|
pdef_tank->unkD0 = stan_y / 0.2004f; // EU-tuned constant
|
|
#else
|
|
pdef_tank->unkD0 = stan_y / 0.17000002f;
|
|
#endif
|
|
}
|
|
break;
|
|
case PROPDEF_VEHICHLE:
|
|
if (withobjs && (!(((struct VehichleRecord *) phead)->flags2 & flags)))
|
|
{
|
|
struct VehichleRecord *pdef_veh = (struct VehichleRecord *) phead;
|
|
|
|
domakedefaultobj(stageId, (struct ObjectRecord *) pdef_veh, pdefIndex);
|
|
|
|
if (pdef_veh->model != NULL)
|
|
{
|
|
if (pdef_veh->model->obj->Switches[5] != NULL)
|
|
{
|
|
modelGetNodeRwData(pdef_veh->model, pdef_veh->model->obj->Switches[5])->Raw.unk00 = (pdef_veh->flags & 0x10000000) == 0;
|
|
}
|
|
}
|
|
|
|
pdef_veh->speed = 0.0f;
|
|
pdef_veh->wheelxrot = 0.0f;
|
|
pdef_veh->wheelyrot = 0.0f;
|
|
pdef_veh->speedaim = 0.0f;
|
|
pdef_veh->turnrot60 = 0.0f;
|
|
pdef_veh->roty = 0.0f;
|
|
pdef_veh->speedtime60 = -1.0f;
|
|
pdef_veh->ailist = ailistFindById(pdef_veh->ailist);
|
|
pdef_veh->aioffset = 0;
|
|
pdef_veh->aireturnlist = -1;
|
|
pdef_veh->path = 0;
|
|
pdef_veh->nextstep = 0;
|
|
pdef_veh->Sound = 0;
|
|
}
|
|
break;
|
|
case PROPDEF_AIRCRAFT:
|
|
if (withobjs && (!(((struct AircraftRecord *) phead)->flags2 & flags)))
|
|
{
|
|
struct AircraftRecord *pdef_air = (struct AircraftRecord *) phead;
|
|
|
|
domakedefaultobj(stageId, (struct ObjectRecord *) pdef_air, pdefIndex);
|
|
pdef_air->speed = 0.0f;
|
|
pdef_air->speedaim = 0.0f;
|
|
pdef_air->rotoryrot = 0.0f;
|
|
pdef_air->rotaryspeed = 0.0f;
|
|
pdef_air->rotaryspeedaim = 0.0f;
|
|
pdef_air->yrot = 0.0f;
|
|
pdef_air->speedtime60 = -1.0f;
|
|
pdef_air->rotaryspeedtime = -1.0f;
|
|
pdef_air->ailist = ailistFindById(pdef_air->ailist);
|
|
pdef_air->aioffset = 0;
|
|
pdef_air->aireturnlist = -1;
|
|
pdef_air->nextstep = 0;
|
|
pdef_air->path = 0;
|
|
pdef_air->Sound = 0;
|
|
}
|
|
break;
|
|
case PROPDEF_TAG:
|
|
{
|
|
struct TagObjectRecord *pdef_tag;
|
|
struct ObjectRecord *taggedobj;
|
|
|
|
pdef_tag = (struct TagObjectRecord *) phead;
|
|
taggedobj = setupCommandGetObject(stageId, pdefIndex + ((s32) pdef_tag->OffsetToObj));
|
|
pdef_tag->TaggedObject = taggedobj;
|
|
|
|
if (taggedobj)
|
|
{
|
|
taggedobj->runtime_bitflags |= RUNTIMEBITFLAG_TAGGED;
|
|
}
|
|
|
|
set_parent_cur_tag_entry(pdef_tag);
|
|
break;
|
|
}
|
|
case PROPDEF_RENAME:
|
|
{
|
|
struct RenameObjectRecord *pdef_ren;
|
|
struct ObjectRecord *targetobj;
|
|
|
|
pdef_ren = (struct RenameObjectRecord *) phead;
|
|
i3 = pdef_ren->TagID + pdefIndex;
|
|
targetobj = setupCommandGetObject(stageId, i3);
|
|
pdef_ren->renobj = targetobj;
|
|
|
|
if (targetobj)
|
|
{
|
|
targetobj->runtime_bitflags |= RUNTIMEBITFLAG_DESTROYED;
|
|
}
|
|
|
|
bondinvAddTextOverride((struct textoverride *) pdef_ren);
|
|
break;
|
|
}
|
|
case PROPDEF_WATCH_MENU_OBJECTIVE_TEXT:
|
|
setup_briefing_text_entry_parent((struct setup_objective_text *) phead);
|
|
break;
|
|
case PROPDEF_CAMERAPOS:
|
|
{
|
|
struct CutsceneRecord *pdef_cam = (struct CutsceneRecord *) phead;
|
|
|
|
pdef_cam->pos.f[0] = (*((s32 *) (&pdef_cam->pos.f[0]))) / 100.0f;
|
|
pdef_cam->pos.f[1] = (*((s32 *) (&pdef_cam->pos.f[1]))) / 100.0f;
|
|
pdef_cam->pos.f[2] = (*((s32 *) (&pdef_cam->pos.f[2]))) / 100.0f;
|
|
pdef_cam->theta = (*((s32 *) (&pdef_cam->theta))) / M_U16_MAX_VALUE_F;
|
|
pdef_cam->verta = (*((s32 *) (&pdef_cam->verta))) / M_U16_MAX_VALUE_F;
|
|
break;
|
|
}
|
|
case PROPDEF_OBJECTIVE_START:
|
|
add_ptr_to_objective((struct objective_entry *) phead);
|
|
break;
|
|
case PROPDEF_OBJECTIVE_ENTER_ROOM:
|
|
set_parent_cur_obj_enter_room((struct criteria_roomentered *) phead);
|
|
break;
|
|
case PROPDEF_OBJECTIVE_DEPOSIT_OBJECT_IN_ROOM:
|
|
set_parent_cur_obj_deposited_in_room((struct criteria_deposit *) phead);
|
|
break;
|
|
case PROPDEF_OBJECTIVE_PHOTOGRAPH:
|
|
set_parent_cur_obj_photograph((struct criteria_picture *) phead);
|
|
break;
|
|
}
|
|
|
|
phead = (PropDefHeaderRecord *) (((u32 *) phead) + sizepropdef(phead));
|
|
pdefIndex++;
|
|
}
|
|
|
|
phead = g_CurrentSetup.propDefs;
|
|
pdefIndex = 0;
|
|
|
|
while (phead->type != PROPDEF_END)
|
|
{
|
|
switch (phead->type)
|
|
{
|
|
case PROPDEF_PROP:
|
|
case PROPDEF_KEY:
|
|
case PROPDEF_MAGAZINE:
|
|
case PROPDEF_COLLECTABLE:
|
|
case PROPDEF_MONITOR:
|
|
case PROPDEF_AMMO:
|
|
case PROPDEF_ARMOUR:
|
|
case PROPDEF_GAS_RELEASING:
|
|
case PROPDEF_UNK41:
|
|
case PROPDEF_GLASS:
|
|
case PROPDEF_SAFE:
|
|
case PROPDEF_TINTED_GLASS:
|
|
{
|
|
struct ObjectRecord *pdef_obj = (struct ObjectRecord *) phead;
|
|
|
|
if (pdef_obj->prop && (pdef_obj->flags & PROPFLAG_INSIDEANOTHEROBJ))
|
|
{
|
|
u32 offset = pdef_obj->pad;
|
|
struct ObjectRecord *inobj = setupCommandGetObject(stageId, offset + pdefIndex);
|
|
|
|
if (inobj && inobj->prop)
|
|
{
|
|
pdef_obj->runtime_bitflags |= RUNTIMEBITFLAG_HASOWNER;
|
|
modelSetScale(pdef_obj->model, pdef_obj->model->scale);
|
|
chrpropReparent(pdef_obj->prop, inobj->prop);
|
|
}
|
|
|
|
#ifdef DEBUG
|
|
//possibly wrong place
|
|
else
|
|
{
|
|
osSyncPrintf("inobj link not found for object number %d\n", pdefIndex + 1);
|
|
}
|
|
#endif
|
|
|
|
}
|
|
break;
|
|
}
|
|
case PROPDEF_LINK:
|
|
{
|
|
struct LinkRecord *pdef_link = (struct LinkRecord *) phead;
|
|
struct WeaponObjRecord *guna = (struct WeaponObjRecord *) setupGetPtrToCommandByIndex(pdef_link->Index1 + pdefIndex);
|
|
struct WeaponObjRecord *gunb = (struct WeaponObjRecord *) setupGetPtrToCommandByIndex(pdef_link->Index2 + pdefIndex);
|
|
|
|
if (guna && gunb)
|
|
{
|
|
if ((guna->type == PROPDEF_COLLECTABLE) && (gunb->type == PROPDEF_COLLECTABLE))
|
|
{
|
|
propweaponSetDual(guna, gunb);
|
|
}
|
|
#ifdef DEBUG
|
|
else
|
|
{
|
|
osSyncPrintf("link type wrong for doublegun object number %d\n", pdefIndex + 1);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
osSyncPrintf("link not found for doublegun object number %d\n", pdefIndex + 1);
|
|
#endif
|
|
|
|
}
|
|
|
|
break;
|
|
}
|
|
case PROPDEF_SWITCH:
|
|
{
|
|
struct LinkRecord *pdef_switch;
|
|
struct ObjectRecord *doorA;
|
|
struct ObjectRecord *doorB;
|
|
s32 index1;
|
|
s32 index2;
|
|
|
|
pdef_switch = (struct LinkRecord *) phead;
|
|
index1 = pdef_switch->Index1;
|
|
index2 = pdef_switch->Index2;
|
|
doorA = (struct ObjectRecord *) setupCommandGetObject(stageId, pdefIndex + index1);
|
|
doorB = (struct ObjectRecord *) setupGetPtrToCommandByIndex(pdefIndex + index2);
|
|
|
|
if ((((doorA && doorA->prop) && doorB) && (doorB->type == PROPDEF_DOOR)) && doorB->prop)
|
|
{
|
|
pdef_switch->first = doorA->prop;
|
|
pdef_switch->second = doorB->prop;
|
|
initSetLevelLoadPropSwitch(pdef_switch);
|
|
doorA->runtime_bitflags |= RUNTIMEBITFLAG_00000001; // linked door
|
|
}
|
|
|
|
#ifdef DEBUG
|
|
else
|
|
{
|
|
osSyncPrintf("doorlink object number %d not initialised\n", pdefIndex + 1);
|
|
}
|
|
#endif
|
|
|
|
break;
|
|
}
|
|
case PROPDEF_SAFE_ITEM:
|
|
{
|
|
s32 index1;
|
|
struct SafeObjectRecord *pdef_safe;
|
|
s32 index2;
|
|
s32 index3;
|
|
struct ObjectRecord *safe_item;
|
|
struct SafeRecord *safe;
|
|
struct DoorRecord *door;
|
|
|
|
pdef_safe = (struct SafeObjectRecord *) phead;
|
|
index1 = pdef_safe->Index1;
|
|
index2 = pdef_safe->Index2;
|
|
index3 = pdef_safe->Index3;
|
|
safe_item = setupCommandGetObject(stageId, pdefIndex + index1);
|
|
safe = (struct SafeRecord *) setupCommandGetObject(stageId, pdefIndex + index2);
|
|
door = (struct DoorRecord *) setupCommandGetObject(stageId, pdefIndex + index3);
|
|
|
|
if (((((((safe_item && safe_item->prop) && safe) && safe->prop) && (safe->type == PROPDEF_SAFE)) && door) && door->prop) && (door->type == PROPDEF_DOOR))
|
|
{
|
|
pdef_safe->item = safe_item;
|
|
pdef_safe->safe = safe;
|
|
pdef_safe->door = door;
|
|
initSetLevelLoadPropSafeItem((struct ObjectRecord *) pdef_safe);
|
|
safe_item->flags2 |= PROPFLAG2_LINKEDTOSAFE;
|
|
door->flags2 |= PROPFLAG2_LINKEDTOSAFE;
|
|
}
|
|
#ifdef DEBUG
|
|
else
|
|
{
|
|
osSyncPrintf("safelink object number %d not initialised\n", pdefIndex + 1);
|
|
}
|
|
#endif
|
|
break;
|
|
}
|
|
case PROPDEF_LOCK_DOOR:
|
|
{
|
|
struct LockDoorRecord *pdef_lock_door;
|
|
struct DoorRecord *door;
|
|
struct ObjectRecord *lock;
|
|
s32 index1;
|
|
s32 index2;
|
|
|
|
pdef_lock_door = (struct LockDoorRecord *) phead;
|
|
|
|
index1 = pdef_lock_door->Index1;
|
|
index2 = pdef_lock_door->Index2;
|
|
|
|
door = (struct DoorRecord *) setupCommandGetObject(stageId, pdefIndex + index1);
|
|
lock = setupCommandGetObject(stageId, pdefIndex + index2);
|
|
|
|
if ((((door && door->prop) && lock) && lock->prop) && (door->type == PROPDEF_DOOR))
|
|
{
|
|
pdef_lock_door->door = door;
|
|
pdef_lock_door->lock = lock;
|
|
initSetLevelLoadPropLockDoor(pdef_lock_door);
|
|
door->runtime_bitflags |= RUNTIMEBITFLAG_PADLOCKEDDOOR;
|
|
}
|
|
#ifdef DEBUG
|
|
else
|
|
{
|
|
osSyncPrintf("doorlock object number %d not initialised\n", pdefIndex + 1);
|
|
}
|
|
#endif
|
|
break;
|
|
}
|
|
}
|
|
|
|
phead = (PropDefHeaderRecord *) (((u32 *) phead) + sizepropdef(phead));
|
|
pdefIndex += 1;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
g_CurrentSetup.pathwaypoints = NULL;
|
|
g_CurrentSetup.waypointgroups = NULL;
|
|
g_CurrentSetup.intro = 0;
|
|
g_CurrentSetup.propDefs = 0;
|
|
g_CurrentSetup.patrolpaths = NULL;
|
|
g_CurrentSetup.ailists = NULL;
|
|
g_CurrentSetup.pads = NULL;
|
|
g_CurrentSetup.boundpads = NULL;
|
|
g_CurrentSetup.padnames = NULL;
|
|
g_CurrentSetup.boundpadnames = NULL;
|
|
alloc_init_GUARDdata_entries(0);
|
|
modelmgrAllocateModelSlots(0);
|
|
modelmgrAllocateAnimModelSlots(0);
|
|
}
|
|
|
|
alloc_false_GUARDdata_to_exec_global_action();
|
|
}
|