diff --git a/src/game/chr/chraicommands.c b/src/game/chr/chraicommands.c index 325dc013c..631bba7e0 100644 --- a/src/game/chr/chraicommands.c +++ b/src/game/chr/chraicommands.c @@ -2352,7 +2352,7 @@ bool aiDestroyObject(void) if (entity->modelnum == MODEL_ELVIS_SAUCER) { obj->flags = (obj->flags & ~OBJFLAG_00010000) | OBJFLAG_INVINCIBLE; explosionCreateSimple(entity->prop, &entity->prop->pos, entity->prop->rooms, EXPLOSIONTYPE_3, 0); - smokeCreateAtProp(entity->prop, SMOKETYPE_22); + smokeCreateAtProp(entity->prop, SMOKETYPE_UFO); } else { f32 damage = ((obj->maxdamage - obj->damage) + 1) / 250.0f; func0f0852ac(obj, damage, &obj->prop->pos, 0x22, -1); diff --git a/src/game/data/data_020df0.c b/src/game/data/data_020df0.c index 45b8be051..51e4e63ad 100644 --- a/src/game/data/data_020df0.c +++ b/src/game/data/data_020df0.c @@ -6275,35 +6275,35 @@ struct explosiontype g_ExplosionTypes[NUM_EXPLOSIONTYPES] = { // | | | | | | | | propagationrate // | | | | | | | | | flarespeed // | | | | | | | | | | smoketype - // | | | | | | | | | | | sound - // | | | | | | | | | | | | damage - // | | | | | | | | | | | | | - /*00*/ { 0.1, 0.1, 0, 0, 0.1, 0, 0, 1, 1, 1, SMOKETYPE_0, 0x0000, 0 }, - /*01*/ { 1, 1, 0, 0, 1, 0, 0, 30, 1, 1, SMOKETYPE_7, 0x0000, 0 }, - /*02*/ { 20, 20, 0, 0, 30, 50, 50, 40, 1, 3, SMOKETYPE_2, 0x8099, 0.125 }, - /*03*/ { 50, 50, 0, 0, 50, 100, 100, 45, 1, 4, SMOKETYPE_2, 0x809a, 0.5 }, - /*04*/ { 60, 80, 2, 0.6, 100, 130, 240, 60, 2, 5, SMOKETYPE_1, 0x809e, 1 }, - /*05*/ { 60, 120, 2, 0.6, 150, 160, 280, 60, 2, 5, SMOKETYPE_1, 0x809e, 2 }, - /*06*/ { 20, 20, 0, 0, 22, 40, 40, 60, 1, 3, SMOKETYPE_2, 0x8099, 0.5 }, - /*07*/ { 35, 40, 0, 0, 35, 70, 70, 60, 1, 4, SMOKETYPE_2, 0x809a, 1 }, - /*08*/ { 50, 80, 2, 0.6, 50, 100, 160, 60, 2, 5, SMOKETYPE_1, 0x809e, 2 }, - /*09*/ { 60, 120, 2, 0.6, 50, 130, 180, 60, 2, 5, SMOKETYPE_1, 0x809e, 2 }, - /*10*/ { 40, 40, 0.8, 0.5, 70, 80, 160, 80, 4, 5, SMOKETYPE_4, 0x80a0, 1 }, - /*11*/ { 50, 50, 1.2, 0.8, 100, 100, 200, 90, 1, 4, SMOKETYPE_4, 0x809e, 2 }, - /*12*/ { 70, 60, 2, 1.2, 150, 140, 280, 90, 2, 5, SMOKETYPE_5, 0x809e, 4 }, - /*13*/ { 80, 60, 4, 1.4, 200, 200, 400, 90, 2, 5, SMOKETYPE_6, 0x809f, 4 }, - /*14*/ { 50, 50, 0, 0, 120, 150, 300, 150, 4, 4, SMOKETYPE_4, 0x809f, 4 }, - /*15*/ { 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, SMOKETYPE_7, 0x809c, 0 }, - /*16*/ { 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, SMOKETYPE_7, 0x809c, 0 }, - /*17*/ { 80, 60, 10, 5, 1500, 2200, 3600, 500, 1, 2, SMOKETYPE_0, 0x80a5, 4 }, - /*18*/ { 80, 60, 3, 1, 300, 450, 640, 60, 1, 2, SMOKETYPE_0, 0x809f, 4 }, - /*19*/ { 90, 75, 2.5, 0.87, 250, 375, 600, 180, 2, 5, SMOKETYPE_6, 0x809f, 4 }, - /*20*/ { 160, 120, 6, 2, 600, 450, 640, 60, 1, 2, SMOKETYPE_0, 0x809f, 4 }, - /*21*/ { 40, 30, 2, 0.7, 100, 140, 270, 45, 2, 5, SMOKETYPE_4, 0x809f, 3.5 }, - /*22*/ { 20, 20, 0, 0, 30, 100, 200, 40, 1, 3, SMOKETYPE_2, 0x8099, 0.25 }, - /*23*/ { 100, 80, 4, 1.4, 210, 220, 500, 90, 2, 5, SMOKETYPE_6, 0x809f, 4 }, - /*24*/ { 80, 60, 4, 1.4, 500, 200, 400, 90, 2, 5, SMOKETYPE_6, 0x809f, 4 }, - /*25*/ { 640, 480, 32, 11.2, 1600, 1000, 1000, 180, 2, 5, SMOKETYPE_0, 0x80a4, 4 }, + // | | | | | | | | | | | sound + // | | | | | | | | | | | | damage + // | | | | | | | | | | | | | + /*00*/ { 0.1, 0.1, 0, 0, 0.1, 0, 0, 1, 1, 1, SMOKETYPE_NONE, 0x0000, 0 }, + /*01*/ { 1, 1, 0, 0, 1, 0, 0, 30, 1, 1, SMOKETYPE_BULLETIMPACT, 0x0000, 0 }, + /*02*/ { 20, 20, 0, 0, 30, 50, 50, 40, 1, 3, SMOKETYPE_MINI, 0x8099, 0.125 }, + /*03*/ { 50, 50, 0, 0, 50, 100, 100, 45, 1, 4, SMOKETYPE_MINI, 0x809a, 0.5 }, + /*04*/ { 60, 80, 2, 0.6, 100, 130, 240, 60, 2, 5, SMOKETYPE_ELECTRICAL, 0x809e, 1 }, + /*05*/ { 60, 120, 2, 0.6, 150, 160, 280, 60, 2, 5, SMOKETYPE_ELECTRICAL, 0x809e, 2 }, + /*06*/ { 20, 20, 0, 0, 22, 40, 40, 60, 1, 3, SMOKETYPE_MINI, 0x8099, 0.5 }, + /*07*/ { 35, 40, 0, 0, 35, 70, 70, 60, 1, 4, SMOKETYPE_MINI, 0x809a, 1 }, + /*08*/ { 50, 80, 2, 0.6, 50, 100, 160, 60, 2, 5, SMOKETYPE_ELECTRICAL, 0x809e, 2 }, + /*09*/ { 60, 120, 2, 0.6, 50, 130, 180, 60, 2, 5, SMOKETYPE_ELECTRICAL, 0x809e, 2 }, + /*10*/ { 40, 40, 0.8, 0.5, 70, 80, 160, 80, 4, 5, SMOKETYPE_SMALL, 0x80a0, 1 }, + /*11*/ { 50, 50, 1.2, 0.8, 100, 100, 200, 90, 1, 4, SMOKETYPE_SMALL, 0x809e, 2 }, + /*12*/ { 70, 60, 2, 1.2, 150, 140, 280, 90, 2, 5, SMOKETYPE_MEDIUM, 0x809e, 4 }, + /*13*/ { 80, 60, 4, 1.4, 200, 200, 400, 90, 2, 5, SMOKETYPE_LARGE, 0x809f, 4 }, + /*14*/ { 50, 50, 0, 0, 120, 150, 300, 150, 4, 4, SMOKETYPE_SMALL, 0x809f, 4 }, + /*15*/ { 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, SMOKETYPE_BULLETIMPACT, 0x809c, 0 }, + /*16*/ { 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, SMOKETYPE_BULLETIMPACT, 0x809c, 0 }, + /*17*/ { 80, 60, 10, 5, 1500, 2200, 3600, 500, 1, 2, SMOKETYPE_NONE, 0x80a5, 4 }, + /*18*/ { 80, 60, 3, 1, 300, 450, 640, 60, 1, 2, SMOKETYPE_NONE, 0x809f, 4 }, + /*19*/ { 90, 75, 2.5, 0.87, 250, 375, 600, 180, 2, 5, SMOKETYPE_LARGE, 0x809f, 4 }, + /*20*/ { 160, 120, 6, 2, 600, 450, 640, 60, 1, 2, SMOKETYPE_NONE, 0x809f, 4 }, + /*21*/ { 40, 30, 2, 0.7, 100, 140, 270, 45, 2, 5, SMOKETYPE_SMALL, 0x809f, 3.5 }, + /*22*/ { 20, 20, 0, 0, 30, 100, 200, 40, 1, 3, SMOKETYPE_MINI, 0x8099, 0.25 }, + /*23*/ { 100, 80, 4, 1.4, 210, 220, 500, 90, 2, 5, SMOKETYPE_LARGE, 0x809f, 4 }, + /*24*/ { 80, 60, 4, 1.4, 500, 200, 400, 90, 2, 5, SMOKETYPE_LARGE, 0x809f, 4 }, + /*25*/ { 640, 480, 32, 11.2, 1600, 1000, 1000, 180, 2, 5, SMOKETYPE_NONE, 0x80a4, 4 }, }; u32 var8007e930 = 0x00000000; @@ -6312,29 +6312,38 @@ u32 var8007e938 = 0x00000000; u32 var8007e93c = 0xffffffff; struct smoketype g_SmokeTypes[NUM_SMOKETYPES] = { - /*00*/ { 1, 60, 99, 0, 0, 0x80808000, 0.3, 120, 0.15, 0.3, 1 }, - /*01*/ { 220, 60, 45, 60, 0.02, 0x50506000, 0.3, 120, 0.15, 0.3, 1 }, - /*02*/ { 220, 60, 50, 20, 0.01, 0x80808000, 0.3, 120, 0.15, 0.3, 1 }, + // duration + // | fadespeed + // | | spreadspeed + // | | | size + // | | | | bgrotatespeed + // | | | | | colour + // | | | | | | fgrotatespeed + // | | | | | | | numclouds + // | | | | | | | | + /*00*/ { 1, 60, 99, 0, 0, 0x80808000, 0.3, 120, 0.15, 0.3, 1 }, // SMOKETYPE_NONE + /*01*/ { 220, 60, 45, 60, 0.02, 0x50506000, 0.3, 120, 0.15, 0.3, 1 }, // SMOKETYPE_ELECTRICAL + /*02*/ { 220, 60, 50, 20, 0.01, 0x80808000, 0.3, 120, 0.15, 0.3, 1 }, // SMOKETYPE_MINI /*03*/ { 280, 60, 120, 100, 0.01, 0xc0c0c000, 0.3, 120, 0.15, 0.3, 1 }, - /*04*/ { 280, 60, 60, 80, 0.02, 0x40404000, 0.3, 120, 0.15, 0.3, 1 }, - /*05*/ { 340, 60, 50, 190, 0.015, 0x40404000, 0.3, 120, 0.15, 0.3, 1 }, - /*06*/ { 380, 60, 70, 300, 0.01, 0x40404000, 0.3, 120, 0.15, 0.3, 1 }, + /*04*/ { 280, 60, 60, 80, 0.02, 0x40404000, 0.3, 120, 0.15, 0.3, 1 }, // SMOKETYPE_SMALL + /*05*/ { 340, 60, 50, 190, 0.015, 0x40404000, 0.3, 120, 0.15, 0.3, 1 }, // SMOKETYPE_MEDIUM + /*06*/ { 380, 60, 70, 300, 0.01, 0x40404000, 0.3, 120, 0.15, 0.3, 1 }, // SMOKETYPE_LARGE /*07*/ { 60, 60, 8, 15, 0.03, 0xffffff00, 0.3, 120, 0.15, 0.3, 1 }, - /*08*/ { 20, 1, 6, 30, 0.03, 0xffffff00, 2, 30, 0.15, 0.3, 1 }, - /*09*/ { 25, 1, 7, 16, 0.03, 0xe0e0e000, 3, 30, 0.15, 0.3, 1 }, + /*08*/ { 20, 1, 6, 30, 0.03, 0xffffff00, 2, 30, 0.15, 0.3, 1 }, // SMOKETYPE_ROCKETTAIL + /*09*/ { 25, 1, 7, 16, 0.03, 0xe0e0e000, 3, 30, 0.15, 0.3, 1 }, // SMOKETYPE_GRENADETAIL /*10*/ { 900, 60, 70, 900, 0.01, 0x40404000, 0.3, 180, 0.15, 0.3, 1 }, - /*11*/ { 20, 1, 6, 30, 0.03, 0x18204000, 2, 30, 0.15, 0.3, 1 }, + /*11*/ { 20, 1, 6, 30, 0.03, 0x18204000, 2, 30, 0.15, 0.3, 1 }, // SMOKETYPE_HOMINGTAIL /*12*/ { 50, 25, 7, 2, 0.03, 0xffffbf00, 0.3, 150, 0.15, 0.3, 1 }, - /*13*/ { 12, 15, 7, 5, 0.03, 0x66404000, 1, 18, 0.15, 0.3, 1 }, + /*13*/ { 12, 15, 7, 5, 0.03, 0x66404000, 1, 18, 0.15, 0.3, 1 }, // SMOKETYPE_SKCORPSE /*14*/ { 12, 15, 7, 5, 0.03, 0x66660000, 1, 18, 0.15, 0.3, 1 }, - /*15*/ { 50, 5, 5, 3, 0.03, 0xffffff00, 0.3, 150, 0, 0.45, 0 }, - /*16*/ { 50, 5, 6, 3, 0.03, 0xafffaf00, 0.3, 150, 0.09, 0.3, 0 }, - /*17*/ { 50, 5, 3, 3, 0.03, 0xffffff00, 0.3, 150, 0, 0.35, 0 }, - /*18*/ { 50, 5, 3, 3, 0.03, 0xaf8f6f00, 0.3, 150, 0.1, 0.3, 0 }, - /*19*/ { 50, 1, 2, 16, 0.03, 0xffff8000, 3, 30, 0.15, 0.3, 1 }, - /*20*/ { 180, 10, 8, 18, 0.06, 0xffffff00, 0.3, 0, 0.19, 0.07, 1 }, - /*21*/ { 220, 40, 45, 60, 0.02, 0x20202000, 0.3, 30, 1.5, 1.8, 6 }, - /*22*/ { 220, 5, 8, 60, 0.03, 0xaf8f6f00, 0.3, 30, 1.5, 0.3, 1 }, + /*15*/ { 50, 5, 5, 3, 0.03, 0xffffff00, 0.3, 150, 0, 0.45, 0 }, // SMOKETYPE_MUZZLE_PISTOL + /*16*/ { 50, 5, 6, 3, 0.03, 0xafffaf00, 0.3, 150, 0.09, 0.3, 0 }, // SMOKETYPE_MUZZLE_SHOTGUN + /*17*/ { 50, 5, 3, 3, 0.03, 0xffffff00, 0.3, 150, 0, 0.35, 0 }, // SMOKETYPE_MUZZLE_AUTOMATIC + /*18*/ { 50, 5, 3, 3, 0.03, 0xaf8f6f00, 0.3, 150, 0.1, 0.3, 0 }, // SMOKETYPE_MUZZLE_REAPER + /*19*/ { 50, 1, 2, 16, 0.03, 0xffff8000, 3, 30, 0.15, 0.3, 1 }, // SMOKETYPE_PINBALL + /*20*/ { 180, 10, 8, 18, 0.06, 0xffffff00, 0.3, 0, 0.19, 0.07, 1 }, // SMOKETYPE_WATER + /*21*/ { 220, 40, 45, 60, 0.02, 0x20202000, 0.3, 30, 1.5, 1.8, 6 }, // SMOKETYPE_DEBRIS + /*22*/ { 220, 5, 8, 60, 0.03, 0xaf8f6f00, 0.3, 30, 1.5, 0.3, 1 }, // SMOKETYPE_UFO }; u32 var8007ec7c = 0x00000000; diff --git a/src/game/smoke.c b/src/game/smoke.c index a68e2e540..9bc671de4 100644 --- a/src/game/smoke.c +++ b/src/game/smoke.c @@ -1154,6 +1154,76 @@ glabel smokeCreate /* f12e450: 27bd0030 */ addiu $sp,$sp,0x30 ); +// Mismatch because goal calculates g_Smokes[i].type an extra time while mine +// resuses an existing one. +//struct smoke *smokeCreate(struct coord *pos, s16 *rooms, s16 type) +//{ +// struct smoke *smoke = NULL; +// s32 playercount = PLAYERCOUNT(); +// s32 count = 0; +// s32 i; +// +// // 270 +// for (i = 0; i < g_NumSmokes; i++) { +// if (g_Smokes[i].prop == NULL) { +// smoke = &g_Smokes[i]; +// break; +// } +// +// // 2b0 +// if (playercount >= 2) { +// // Multiplayer - clear existing smoke if it's not any of the following +// if (g_Smokes[i].type != SMOKETYPE_BULLETIMPACT +// && g_Smokes[i].type != SMOKETYPE_ROCKETTAIL +// && g_Smokes[i].type != SMOKETYPE_HOMINGTAIL +// && g_Smokes[i].type != SMOKETYPE_GRENADETAIL) { +// g_Smokes[i].age = g_SmokeTypes[g_Smokes[i].type].duration; +// } +// } else { +// // 308 +// // 1 player - if creating muzzle smoke, remove the third bullet impact smoke +// if (type >= SMOKETYPE_MUZZLE_PISTOL && type <= SMOKETYPE_MUZZLE_REAPER) { +// if (g_Smokes[i].type == SMOKETYPE_BULLETIMPACT) { +// // 32c +// if (count == 3) { +// g_Smokes[i].age = g_SmokeTypes[g_Smokes[i].type].duration; +// } +// +// count++; +// } +// } +// } +// } +// +// // 360 +// if (smoke) { +// struct prop *prop = propAllocate(); +// +// if (prop) { +// prop->type = PROPTYPE_EFFECT; +// prop->smoke = smoke; +// prop->pos.x = pos->x; +// prop->pos.y = pos->y; +// prop->pos.z = pos->z; +// +// for (i = 0; rooms[i] != -1 && i < 7; i++) { +// prop->rooms[i] = rooms[i]; +// } +// +// prop->rooms[i] = -1; +// func0f060538(prop); +// propShow(prop); +// +// smoke->prop = prop; +// smoke->age = 0; +// smoke->type = type; +// smoke->srcprop = NULL; +// } +// } +// +// return smoke; +//} + bool func0f12e454(struct coord *pos, s16 *rooms, s16 type, u32 arg4) { struct smoke *smoke; @@ -1161,10 +1231,10 @@ bool func0f12e454(struct coord *pos, s16 *rooms, s16 type, u32 arg4) s32 j; for (i = 0; i < g_NumSmokes; i++) { - if (g_Smokes[i].active + if (g_Smokes[i].prop && g_Smokes[i].unk06_07 == arg4 - && g_Smokes[i].type >= SMOKETYPE_15 - && g_Smokes[i].type <= SMOKETYPE_18) { + && g_Smokes[i].type >= SMOKETYPE_MUZZLE_PISTOL + && g_Smokes[i].type <= SMOKETYPE_MUZZLE_REAPER) { bool fail = false; if (g_Smokes[i].age < g_SmokeTypes[g_Smokes[i].type].duration) { @@ -1203,13 +1273,13 @@ bool smokeCreateAtPropIfNecessary(struct prop *prop, struct coord *pos, s16 *roo s32 j; bool checksmokes = true; - if (type == SMOKETYPE_22) { + if (type == SMOKETYPE_UFO) { checksmokes = false; } if (checksmokes) { for (i = 0; i < g_NumSmokes; i++) { - if (g_Smokes[i].active && g_Smokes[i].prop == prop) { + if (g_Smokes[i].prop && g_Smokes[i].srcprop == prop) { bool fail = false; if (g_Smokes[i].age < g_SmokeTypes[g_Smokes[i].type].duration) { @@ -1230,7 +1300,7 @@ bool smokeCreateAtPropIfNecessary(struct prop *prop, struct coord *pos, s16 *roo smoke = smokeCreate(pos, rooms, type); if (smoke) { - smoke->prop = prop; + smoke->srcprop = prop; smoke->unk06_07 = arg4; return true; } @@ -1253,9 +1323,9 @@ void smokeClearForProp(struct prop *prop) s32 i; for (i = 0; i < g_NumSmokes; i++) { - if (g_Smokes[i].active && g_Smokes[i].prop == prop && g_Smokes[i].unk06_07 == false) { + if (g_Smokes[i].prop && g_Smokes[i].srcprop == prop && g_Smokes[i].unk06_07 == false) { g_Smokes[i].age = g_SmokeTypes[g_Smokes[i].type].duration; - g_Smokes[i].prop = NULL; + g_Smokes[i].srcprop = NULL; } } } diff --git a/src/include/constants.h b/src/include/constants.h index a112f945f..fb104ee39 100644 --- a/src/include/constants.h +++ b/src/include/constants.h @@ -2373,17 +2373,26 @@ #define SLOWMOTION_ON 1 #define SLOWMOTION_SMART 2 -#define SMOKETYPE_0 0 -#define SMOKETYPE_1 1 -#define SMOKETYPE_2 2 -#define SMOKETYPE_3 3 -#define SMOKETYPE_4 4 -#define SMOKETYPE_5 5 -#define SMOKETYPE_6 6 -#define SMOKETYPE_7 7 -#define SMOKETYPE_15 15 -#define SMOKETYPE_18 18 -#define SMOKETYPE_22 22 +#define SMOKETYPE_NONE 0 +#define SMOKETYPE_ELECTRICAL 1 // Dr Caroll, mainframes in Infiltration bunker +#define SMOKETYPE_MINI 2 // Phoenix, Laptop sentry +#define SMOKETYPE_3 3 +#define SMOKETYPE_SMALL 4 // SuperDragon grenades, some barrels and autoguns +#define SMOKETYPE_MEDIUM 5 // Maian SOS hoverbed +#define SMOKETYPE_LARGE 6 // Rockets, mines etc +#define SMOKETYPE_BULLETIMPACT 7 +#define SMOKETYPE_ROCKETTAIL 8 +#define SMOKETYPE_GRENADETAIL 9 +#define SMOKETYPE_HOMINGTAIL 11 +#define SMOKETYPE_SKCORPSE 13 +#define SMOKETYPE_MUZZLE_PISTOL 15 +#define SMOKETYPE_MUZZLE_SHOTGUN 16 +#define SMOKETYPE_MUZZLE_AUTOMATIC 17 +#define SMOKETYPE_MUZZLE_REAPER 18 +#define SMOKETYPE_PINBALL 19 // Grenade in proxy pinball mode +#define SMOKETYPE_WATER 20 // Splash effect in Chicago +#define SMOKETYPE_DEBRIS 21 // Crash site cockpit, Skedar Ruins outro +#define SMOKETYPE_UFO 22 // AF1 outro #define SOLOSTAGEINDEX_DEFECTION 0 #define SOLOSTAGEINDEX_INVESTIGATION 1 diff --git a/src/include/types.h b/src/include/types.h index 040cccadc..777cbf9c4 100644 --- a/src/include/types.h +++ b/src/include/types.h @@ -45,6 +45,7 @@ struct prop { struct doorobj *door; struct weaponobj *weapon; struct explosion *explosion; + struct smoke *smoke; }; /*0x08*/ struct coord pos; @@ -4580,13 +4581,13 @@ struct smokebit { }; struct smoke { - /*0x000*/ u32 active; + /*0x000*/ struct prop *prop; // Prop of the smoke itself /*0x004*/ s16 age; /*0x006*/ u16 type : 7; /*0x006*/ u16 unk06_07 : 1; /*0x007*/ u16 unk06_08 : 8; /*0x008*/ struct smokebit smokebits[10]; - /*0x198*/ struct prop *prop; + /*0x198*/ struct prop *srcprop; // Prop of the thing generating smoke }; struct textoverride {