mirror of
https://gitlab.com/ryandwyer/perfect-dark
synced 2026-07-11 14:08:37 -04:00
Remove support for hats
This commit is contained in:
+1
-2
@@ -101,7 +101,6 @@ void botReset(struct chrdata *chr, u8 respawning)
|
||||
chr->firecount[1] = 0;
|
||||
chr->weapons_held[0] = NULL;
|
||||
chr->weapons_held[1] = NULL;
|
||||
chr->weapons_held[2] = NULL;
|
||||
chr->liftaction = 0;
|
||||
chr->inlift = 0;
|
||||
chr->lift = NULL;
|
||||
@@ -463,7 +462,7 @@ bool botTestPropForPickup(struct prop *prop, struct chrdata *chr)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (func0f085194(obj) && obj->type != OBJTYPE_HAT) {
|
||||
if (func0f085194(obj)) {
|
||||
if (obj->flags & OBJFLAG_UNCOLLECTABLE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
+4
-92
@@ -1103,7 +1103,6 @@ void chrInit(struct prop *prop, u8 *ailist)
|
||||
chr->aimendcount = 0;
|
||||
chr->weapons_held[0] = NULL;
|
||||
chr->weapons_held[1] = NULL;
|
||||
chr->weapons_held[2] = NULL;
|
||||
chr->gunprop = NULL;
|
||||
chr->fireslots[0] = -1;
|
||||
chr->fireslots[1] = -1;
|
||||
@@ -2278,7 +2277,6 @@ s32 chrTick(struct prop *prop)
|
||||
struct chrdata *chr = prop->chr;
|
||||
struct model *model = chr->model;
|
||||
bool onscreen;
|
||||
bool hatvisible = true;
|
||||
s32 lvupdate240 = g_Vars.lvupdate240;
|
||||
struct prop *child;
|
||||
struct prop *next;
|
||||
@@ -2713,61 +2711,6 @@ s32 chrTick(struct prop *prop)
|
||||
chr0f022214(chr, child, fulltick);
|
||||
child = next;
|
||||
}
|
||||
|
||||
if (chr->weapons_held[2] != NULL) {
|
||||
s32 index;
|
||||
struct defaultobj *obj = chr->weapons_held[2]->obj;
|
||||
struct model *hatmodel = obj->model;
|
||||
|
||||
if (chr->headnum >= HEAD_SHAUN && chr->headnum <= HEAD_SHAUN) {
|
||||
struct coord hatpos = {0, 0, 0};
|
||||
f32 spe4;
|
||||
f32 spe0;
|
||||
f32 spdc;
|
||||
Mtxf sp9c;
|
||||
Mtxf sp5c;
|
||||
s32 hattype = hatGetType(chr->weapons_held[2]);
|
||||
u8 stack[0x0c];
|
||||
|
||||
index = chr->headnum - HEAD_SHAUN;
|
||||
|
||||
hatpos.x = var8007dae4[index][hattype].x * 21.3f;
|
||||
hatpos.y = var8007dae4[index][hattype].y * 21.3f;
|
||||
hatpos.z = var8007dae4[index][hattype].z * 21.3f;
|
||||
|
||||
spe4 = var8007dae4[index][hattype].unk0c;
|
||||
spe0 = var8007dae4[index][hattype].unk10;
|
||||
spdc = var8007dae4[index][hattype].unk14;
|
||||
|
||||
mtx4LoadTranslation(&hatpos, &sp9c);
|
||||
mtx00015e24(spe4, &sp9c);
|
||||
mtx00015e80(spe0, &sp9c);
|
||||
mtx00015edc(spdc, &sp9c);
|
||||
mtx00015be4(hatmodel->matrices, &sp9c, &sp5c);
|
||||
mtx4Copy(&sp5c, hatmodel->matrices);
|
||||
|
||||
if (hattype == HATTYPE_2) {
|
||||
hatvisible = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (model->filedata->skel == &g_SkelChr) {
|
||||
struct modelnode *headspotnode = modelGetPart(model->filedata, MODELPART_CHR_HEADSPOT);
|
||||
|
||||
if (headspotnode && headspotnode->type == MODELNODETYPE_HEADSPOT) {
|
||||
union modelrwdata *rwdata = modelGetNodeRwData(model, headspotnode);
|
||||
|
||||
if (rwdata->headspot.modelfiledata != NULL) {
|
||||
struct modelnode *hatnode = modelGetPart(rwdata->headspot.modelfiledata, MODELPART_HEAD_HAT);
|
||||
|
||||
if (hatnode != NULL) {
|
||||
union modelrwdata *hatrwdata = modelGetNodeRwData(model, hatnode);
|
||||
hatrwdata->toggle.visible = hatvisible;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Offscreen
|
||||
@@ -2808,8 +2751,7 @@ void chrDropConcealedItems(struct chrdata *chr)
|
||||
struct prop *prop = chr->prop->child;
|
||||
|
||||
while (prop) {
|
||||
if (prop != chr->weapons_held[2]
|
||||
&& prop != chr->weapons_held[1]
|
||||
if (prop != chr->weapons_held[1]
|
||||
&& prop != chr->weapons_held[0]
|
||||
&& (prop->obj->hidden & OBJHFLAG_EMBEDDED) == 0
|
||||
&& (prop->obj->flags & OBJFLAG_AIUNDROPPABLE) == 0) {
|
||||
@@ -2849,13 +2791,10 @@ void chrDropItemsForOwnerReap(struct chrdata *chr)
|
||||
struct prop *prop = chr->prop->child;
|
||||
|
||||
while (prop) {
|
||||
// If prop is not hat
|
||||
if (prop != chr->weapons_held[2]) {
|
||||
struct defaultobj *obj = prop->obj;
|
||||
struct defaultobj *obj = prop->obj;
|
||||
|
||||
if ((obj->flags & OBJFLAG_AIUNDROPPABLE) == 0) {
|
||||
objSetDropped(prop, DROPTYPE_OWNERREAP);
|
||||
}
|
||||
if ((obj->flags & OBJFLAG_AIUNDROPPABLE) == 0) {
|
||||
objSetDropped(prop, DROPTYPE_OWNERREAP);
|
||||
}
|
||||
|
||||
prop = prop->next;
|
||||
@@ -5194,33 +5133,6 @@ void chrHit(struct shotdata *shotdata, struct hit *hit)
|
||||
objSetDropped(hit->prop, DROPTYPE_DEFAULT);
|
||||
chr->hidden |= CHRHFLAG_00000001;
|
||||
}
|
||||
} else if (hit->hitpart == HITPART_HAT) {
|
||||
// Shot a chr's hat
|
||||
struct surfacetype *type;
|
||||
s32 index;
|
||||
|
||||
// Create decal depending on the hat's surface type
|
||||
if (hit->hitthing.texturenum < 0) {
|
||||
type = g_SurfaceTypes[0];
|
||||
} else {
|
||||
type = g_SurfaceTypes[g_Textures[hit->hitthing.texturenum].surfacetype];
|
||||
}
|
||||
|
||||
index = random() % type->numwallhittexes;
|
||||
|
||||
wallhitCreate(
|
||||
&hit->hitthing.unk00,
|
||||
&hit->hitthing.unk0c,
|
||||
&shotdata->gunpos,
|
||||
0,
|
||||
0,
|
||||
type->wallhittexes[index],
|
||||
1,
|
||||
chr->weapons_held[2],
|
||||
hit->mtxindex,
|
||||
0,
|
||||
g_Vars.currentplayer->prop->chr,
|
||||
0);
|
||||
} else {
|
||||
// Shot a chr in the flesh
|
||||
s32 race = CHRRACE(chr);
|
||||
|
||||
@@ -4553,28 +4553,6 @@ void chrDamage(struct chrdata *chr, f32 damage, struct coord *vector, struct gse
|
||||
}
|
||||
}
|
||||
|
||||
// Handle hat shots. This is left over from GE, as hats don't exist in PD
|
||||
if (damage > 0 && hitpart == HITPART_HAT && chr->weapons_held[2]) {
|
||||
s32 type = hatGetType(chr->weapons_held[2]);
|
||||
|
||||
if (type == HATTYPE_CLOTH) {
|
||||
// Hat remains on head and damages the chr (eg. Moonraker Elite)
|
||||
hitpart = HITPART_HEAD;
|
||||
} else if (type != HATTYPE_METAL) {
|
||||
// Normal hat
|
||||
damage = 0;
|
||||
objSetDropped(chr->weapons_held[2], DROPTYPE_HAT);
|
||||
chr->hidden |= CHRHFLAG_00000001;
|
||||
} else {
|
||||
// Metal helmets don't fall off and make a metallic chink noise when shot
|
||||
u16 sounds[] = { SFX_HIT_METAL_807B, SFX_HIT_METAL_8079, SFX_HATHIT_807C };
|
||||
damage = 0;
|
||||
|
||||
propsnd0f0939f8(NULL, chr->prop, sounds[random() % 3], -1,
|
||||
-1, 0, 0, 0, NULL, -1, NULL, -1, -1, -1, -1);
|
||||
}
|
||||
}
|
||||
|
||||
// Handle incrementing player shot count
|
||||
if (aprop && aprop->type == PROPTYPE_PLAYER && !explosion) {
|
||||
bool alreadydead = false;
|
||||
|
||||
@@ -1033,11 +1033,6 @@ bool aiDuplicateChr(s32 chrref, u8 *ailist, u32 spawnflags)
|
||||
propweaponSetDual(cloneweapon1, cloneweapon0);
|
||||
}
|
||||
|
||||
if (chr->weapons_held[2]) {
|
||||
struct defaultobj *obj = chr->weapons_held[2]->obj;
|
||||
hatCreateForChr(clone, obj->modelnum, 0);
|
||||
}
|
||||
|
||||
clone->flags = chr->flags;
|
||||
clone->flags2 = chr->flags2;
|
||||
clone->padpreset1 = chr->padpreset1;
|
||||
|
||||
+1
-208
@@ -82,13 +82,11 @@ struct weaponobj *g_Proxies[30];
|
||||
f32 g_GasReleaseTimerMax240;
|
||||
bool g_GasEnableDamage;
|
||||
s32 g_MaxWeaponSlots;
|
||||
s32 g_MaxHatSlots;
|
||||
s32 g_MaxAmmoCrates;
|
||||
s32 g_MaxDebrisSlots;
|
||||
s32 g_MaxProjectiles;
|
||||
s32 g_MaxEmbedments;
|
||||
struct weaponobj *g_WeaponSlots;
|
||||
struct hatobj *g_HatSlots;
|
||||
struct ammocrateobj *g_AmmoCrates;
|
||||
struct defaultobj *g_DebrisSlots;
|
||||
struct projectile *g_Projectiles;
|
||||
@@ -110,7 +108,6 @@ bool g_CountdownTimerRunning = false;
|
||||
f32 g_CountdownTimerValue60 = 0;
|
||||
u32 g_PlayersDetonatingMines = 0x00000000;
|
||||
s32 g_NextWeaponSlot = 0;
|
||||
s32 g_NextHatSlot = 0;
|
||||
struct linkliftdoorobj *g_LiftDoors = NULL;
|
||||
struct padlockeddoorobj *g_PadlockedDoors = NULL;
|
||||
struct safeitemobj *g_SafeItems = NULL;
|
||||
@@ -15048,10 +15045,6 @@ void objDetach(struct prop *prop)
|
||||
struct chrdata *chr = parent->chr;
|
||||
|
||||
if (chr) {
|
||||
if (prop == chr->weapons_held[2]) {
|
||||
chr->weapons_held[2] = NULL;
|
||||
}
|
||||
|
||||
if (prop == chr->weapons_held[HAND_RIGHT]) {
|
||||
chrSetFiring(chr, HAND_RIGHT, false);
|
||||
chr->weapons_held[HAND_RIGHT] = NULL;
|
||||
@@ -18081,7 +18074,7 @@ s32 objTestForPickup(struct prop *prop)
|
||||
return TICKOP_NONE;
|
||||
}
|
||||
|
||||
if (func0f085194(obj) && obj->type != OBJTYPE_HAT) {
|
||||
if (func0f085194(obj)) {
|
||||
if (obj->flags & OBJFLAG_UNCOLLECTABLE) {
|
||||
return TICKOP_NONE;
|
||||
}
|
||||
@@ -18402,118 +18395,6 @@ void modelFreeVertices(s32 vtxstoretype, struct model *model)
|
||||
}
|
||||
}
|
||||
|
||||
struct prop *hatApplyToChr(struct hatobj *hat, struct chrdata *chr, struct modelfiledata *filedata, struct prop *prop, struct model *model)
|
||||
{
|
||||
if (chr->model->filedata->skel == &g_SkelChr) {
|
||||
prop = objInit(&hat->base, filedata, prop, model);
|
||||
|
||||
if (prop && hat->base.model) {
|
||||
f32 scale = hat->base.extrascale * (1.0f / 256.0f);
|
||||
|
||||
modelSetScale(hat->base.model, scale * hat->base.model->scale);
|
||||
|
||||
hat->base.model->attachedtomodel = chr->model;
|
||||
hat->base.model->attachedtonode = modelGetPart(chr->model->filedata, MODELPART_CHR_0006);
|
||||
|
||||
propReparent(prop, chr->prop);
|
||||
|
||||
chr->weapons_held[2] = prop;
|
||||
}
|
||||
}
|
||||
|
||||
if (hat);
|
||||
|
||||
return prop;
|
||||
}
|
||||
|
||||
void hatLoadAndApplyToChr(struct hatobj *hat, struct chrdata *chr)
|
||||
{
|
||||
u32 stack;
|
||||
s32 modelnum = hat->base.modelnum;
|
||||
|
||||
setupLoadModeldef(modelnum);
|
||||
|
||||
hatApplyToChr(hat, chr, g_ModelStates[modelnum].filedata, NULL, NULL);
|
||||
}
|
||||
|
||||
void hatAssignToChr(struct hatobj *hat, struct chrdata *chr)
|
||||
{
|
||||
hatLoadAndApplyToChr(hat, chr);
|
||||
}
|
||||
|
||||
struct prop *hatCreateForChr(struct chrdata *chr, s32 modelnum, u32 flags)
|
||||
{
|
||||
struct modelfiledata *filedata;
|
||||
struct prop *prop;
|
||||
struct model *model;
|
||||
struct hatobj *obj;
|
||||
|
||||
setupLoadModeldef(modelnum);
|
||||
filedata = g_ModelStates[modelnum].filedata;
|
||||
prop = propAllocate();
|
||||
model = modelmgrInstantiateModelWithoutAnim(filedata);
|
||||
obj = hatCreate(prop == NULL, model == NULL, filedata);
|
||||
|
||||
if (prop == NULL) {
|
||||
prop = propAllocate();
|
||||
}
|
||||
|
||||
if (model == NULL) {
|
||||
model = modelmgrInstantiateModelWithoutAnim(filedata);
|
||||
}
|
||||
|
||||
if (obj && prop && model) {
|
||||
struct hatobj tmp = {
|
||||
256, // extrascale
|
||||
0, // hidden2
|
||||
OBJTYPE_HAT, // type
|
||||
0, // modelnum
|
||||
0, // pad
|
||||
OBJFLAG_ASSIGNEDTOCHR, // flags
|
||||
0, // flags2
|
||||
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
|
||||
};
|
||||
|
||||
*obj = tmp;
|
||||
|
||||
obj->base.modelnum = modelnum;
|
||||
obj->base.flags = flags | OBJFLAG_ASSIGNEDTOCHR;
|
||||
obj->base.pad = chr->chrnum;
|
||||
|
||||
prop = hatApplyToChr(obj, chr, filedata, prop, model);
|
||||
} else {
|
||||
if (model) {
|
||||
modelmgrFreeModel(model);
|
||||
}
|
||||
|
||||
if (prop) {
|
||||
propFree(prop);
|
||||
prop = NULL;
|
||||
}
|
||||
|
||||
if (obj) {
|
||||
obj->base.prop = NULL;
|
||||
obj->base.model = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return prop;
|
||||
}
|
||||
|
||||
struct weaponobj *weaponCreate(bool musthaveprop, bool musthavemodel, struct modelfiledata *filedata)
|
||||
{
|
||||
s32 i;
|
||||
@@ -18624,94 +18505,6 @@ struct weaponobj *func0f08a364(void)
|
||||
return weaponCreate(false, false, NULL);
|
||||
}
|
||||
|
||||
struct hatobj *hatCreate(bool musthaveprop, bool musthavemodel, struct modelfiledata *filedata)
|
||||
{
|
||||
s32 i;
|
||||
struct hatobj *tmp;
|
||||
struct hatobj *sp4c = NULL;
|
||||
struct hatobj *sp48 = NULL;
|
||||
s32 sp44 = -1;
|
||||
s32 sp40 = -1;
|
||||
s32 sp3c = -1;
|
||||
|
||||
for (i = g_NextHatSlot; true; ) {
|
||||
if (g_HatSlots[i].base.prop == NULL) {
|
||||
if (!musthaveprop && !musthavemodel) {
|
||||
sp44 = i;
|
||||
break;
|
||||
}
|
||||
} else if ((g_HatSlots[i].base.hidden & OBJHFLAG_PROJECTILE) == 0
|
||||
&& g_HatSlots[i].base.prop->parent == NULL
|
||||
&& (!musthavemodel || modelmgrCanSlotFitRwdata(g_HatSlots[i].base.model, filedata))) {
|
||||
if ((g_HatSlots[i].base.prop->flags & (PROPFLAG_ONTHISSCREENTHISTICK | PROPFLAG_ONANYSCREENTHISTICK | PROPFLAG_ONANYSCREENPREVTICK)) == 0 && sp40 < 0) {
|
||||
sp40 = i;
|
||||
}
|
||||
|
||||
if (sp3c < 0) {
|
||||
sp3c = i;
|
||||
}
|
||||
}
|
||||
|
||||
i = (i + 1) % g_MaxHatSlots;
|
||||
|
||||
if (i == g_NextHatSlot) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (sp44 >= 0) {
|
||||
g_NextHatSlot = (sp44 + 1) % g_MaxHatSlots;
|
||||
return &g_HatSlots[sp44];
|
||||
}
|
||||
|
||||
tmp = (struct hatobj *)setupFindObjForReuse(OBJTYPE_HAT, (struct defaultobj **)&sp4c, (struct defaultobj **)&sp48, musthaveprop, musthavemodel, filedata);
|
||||
|
||||
if (tmp) {
|
||||
return tmp;
|
||||
}
|
||||
|
||||
if (sp40 >= 0) {
|
||||
if (g_HatSlots[sp40].base.prop) {
|
||||
objFreePermanently(&g_HatSlots[sp40].base, true);
|
||||
}
|
||||
|
||||
g_NextHatSlot = (sp40 + 1) % g_MaxHatSlots;
|
||||
return &g_HatSlots[sp40];
|
||||
}
|
||||
|
||||
if (sp4c) {
|
||||
if (sp4c->base.prop) {
|
||||
objFreePermanently(&sp4c->base, true);
|
||||
}
|
||||
|
||||
return sp4c;
|
||||
}
|
||||
|
||||
if (sp3c >= 0) {
|
||||
if (g_HatSlots[sp3c].base.prop) {
|
||||
objFreePermanently(&g_HatSlots[sp3c].base, true);
|
||||
}
|
||||
|
||||
g_NextHatSlot = (sp3c + 1) % g_MaxHatSlots;
|
||||
return &g_HatSlots[sp3c];
|
||||
}
|
||||
|
||||
if (sp48) {
|
||||
if (sp48->base.prop) {
|
||||
objFreePermanently(&sp48->base, true);
|
||||
}
|
||||
|
||||
return sp48;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct hatobj *func0f08a6fc(void)
|
||||
{
|
||||
return hatCreate(false, false, NULL);
|
||||
}
|
||||
|
||||
struct ammocrateobj *ammocrateAllocate(void)
|
||||
{
|
||||
s32 i;
|
||||
|
||||
@@ -184,7 +184,6 @@ void propsReset(void)
|
||||
}
|
||||
|
||||
g_MaxWeaponSlots = 50;
|
||||
g_MaxHatSlots = 10;
|
||||
g_MaxAmmoCrates = 20;
|
||||
g_MaxDebrisSlots = 15;
|
||||
g_MaxProjectiles = IS4MB() ? 20 : 100;
|
||||
@@ -192,7 +191,6 @@ void propsReset(void)
|
||||
|
||||
if (g_Vars.stagenum >= STAGE_TITLE) {
|
||||
g_MaxWeaponSlots = 0;
|
||||
g_MaxHatSlots = 0;
|
||||
g_MaxAmmoCrates = 0;
|
||||
g_MaxDebrisSlots = 0;
|
||||
g_MaxProjectiles = 0;
|
||||
@@ -234,18 +232,6 @@ void propsReset(void)
|
||||
g_NextWeaponSlot = 0;
|
||||
}
|
||||
|
||||
if (g_MaxHatSlots == 0) {
|
||||
g_HatSlots = NULL;
|
||||
} else {
|
||||
g_HatSlots = mempAlloc(ALIGN16(g_MaxHatSlots * sizeof(struct hatobj)), MEMPOOL_STAGE);
|
||||
|
||||
for (i = 0; i < g_MaxHatSlots; i++) {
|
||||
g_HatSlots[i].base.prop = NULL;
|
||||
}
|
||||
|
||||
g_NextHatSlot = 0;
|
||||
}
|
||||
|
||||
if (g_MaxAmmoCrates == 0) {
|
||||
g_AmmoCrates = NULL;
|
||||
} else {
|
||||
@@ -754,19 +740,6 @@ void setupPlaceWeapon(struct weaponobj *weapon, s32 cmdindex)
|
||||
}
|
||||
}
|
||||
|
||||
void setupCreateHat(struct hatobj *hat, s32 cmdindex)
|
||||
{
|
||||
if (hat->base.flags & OBJFLAG_ASSIGNEDTOCHR) {
|
||||
struct chrdata *chr = chrFindByLiteralId(hat->base.pad);
|
||||
|
||||
if (chr && chr->prop && chr->model) {
|
||||
hatAssignToChr(hat, chr);
|
||||
}
|
||||
} else {
|
||||
setupCreateObject(&hat->base, cmdindex);
|
||||
}
|
||||
}
|
||||
|
||||
void setupCreateKey(struct keyobj *key, s32 cmdindex)
|
||||
{
|
||||
setupCreateObject(&key->base, cmdindex);
|
||||
@@ -1576,11 +1549,6 @@ void setupCreateProps(s32 stagenum)
|
||||
setupCreateKey((struct keyobj *)obj, index);
|
||||
}
|
||||
break;
|
||||
case OBJTYPE_HAT:
|
||||
if (withchrs && (obj->flags2 & diffflag) == 0) {
|
||||
setupCreateHat((struct hatobj *)obj, index);
|
||||
}
|
||||
break;
|
||||
case OBJTYPE_CCTV:
|
||||
if (withobjs && (obj->flags2 & diffflag) == 0) {
|
||||
setupCreateCctv((struct cctvobj *)obj, index);
|
||||
|
||||
Reference in New Issue
Block a user