From 1d11a14f64a673c462ef98ab8abb6871b76077fa Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Mon, 7 Aug 2017 20:33:24 +0100 Subject: [PATCH 1/8] Getting polyobject flats to the equivalent functionality BEFORE I changed up how floor offsets worked. (Doesn't touch OGL, since they work perfectly there.) --- src/r_bsp.c | 45 +++++---------------------------------------- src/r_plane.c | 17 +++++++++++++++++ 2 files changed, 22 insertions(+), 40 deletions(-) diff --git a/src/r_bsp.c b/src/r_bsp.c index 4ce89f009..ad4975cde 100644 --- a/src/r_bsp.c +++ b/src/r_bsp.c @@ -1104,30 +1104,12 @@ static void R_Subsector(size_t num) && polysec->floorheight >= floorcenterz && (viewz < polysec->floorheight)) { - fixed_t xoff, yoff; - xoff = polysec->floor_xoffs; - yoff = polysec->floor_yoffs; - - if (po->angle != 0) { - angle_t fineshift = po->angle >> ANGLETOFINESHIFT; - - xoff -= FixedMul(FINECOSINE(fineshift), po->centerPt.x)+FixedMul(FINESINE(fineshift), po->centerPt.y); - yoff -= FixedMul(FINESINE(fineshift), po->centerPt.x)-FixedMul(FINECOSINE(fineshift), po->centerPt.y); - } else { - xoff -= po->centerPt.x; - yoff += po->centerPt.y; - } - light = R_GetPlaneLight(frontsector, polysec->floorheight, viewz < polysec->floorheight); light = 0; ffloor[numffloors].plane = R_FindPlane(polysec->floorheight, polysec->floorpic, - polysec->lightlevel, xoff, yoff, - polysec->floorpic_angle-po->angle, - NULL, - NULL -#ifdef POLYOBJECTS_PLANES - , po -#endif + polysec->lightlevel, polysec->floor_xoffs, polysec->floor_yoffs, + polysec->floorpic_angle-po->angle, + NULL, NULL, po #ifdef ESLOPE , NULL // will ffloors be slopable eventually? #endif @@ -1152,28 +1134,11 @@ static void R_Subsector(size_t num) && polysec->ceilingheight <= ceilingcenterz && (viewz > polysec->ceilingheight)) { - fixed_t xoff, yoff; - xoff = polysec->ceiling_xoffs; - yoff = polysec->ceiling_yoffs; - - if (po->angle != 0) { - angle_t fineshift = po->angle >> ANGLETOFINESHIFT; - - xoff -= FixedMul(FINECOSINE(fineshift), po->centerPt.x)+FixedMul(FINESINE(fineshift), po->centerPt.y); - yoff -= FixedMul(FINESINE(fineshift), po->centerPt.x)-FixedMul(FINECOSINE(fineshift), po->centerPt.y); - } else { - xoff -= po->centerPt.x; - yoff += po->centerPt.y; - } - light = R_GetPlaneLight(frontsector, polysec->ceilingheight, viewz < polysec->ceilingheight); light = 0; ffloor[numffloors].plane = R_FindPlane(polysec->ceilingheight, polysec->ceilingpic, - polysec->lightlevel, xoff, yoff, polysec->ceilingpic_angle-po->angle, - NULL, NULL -#ifdef POLYOBJECTS_PLANES - , po -#endif + polysec->lightlevel, polysec->ceiling_xoffs, polysec->ceiling_yoffs, polysec->ceilingpic_angle-po->angle, + NULL, NULL, po #ifdef ESLOPE , NULL // will ffloors be slopable eventually? #endif diff --git a/src/r_plane.c b/src/r_plane.c index cf7b679bb..670152eda 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -459,6 +459,23 @@ visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel, } } +#ifdef POLYOBJECTS_PLANES + if (polyobj) + { + if (polyobj->angle != 0) + { + angle_t fineshift = polyobj->angle >> ANGLETOFINESHIFT; + xoff -= FixedMul(FINECOSINE(fineshift), polyobj->centerPt.x)+FixedMul(FINESINE(fineshift), polyobj->centerPt.y); + yoff -= FixedMul(FINESINE(fineshift), polyobj->centerPt.x)-FixedMul(FINECOSINE(fineshift), polyobj->centerPt.y); + } + else + { + xoff -= polyobj->centerPt.x; + yoff += polyobj->centerPt.y; + } + } +#endif + // This appears to fix the Nimbus Ruins sky bug. if (picnum == skyflatnum && pfloor) { From a61be91523466a74930f75f7663cefb55ee1e6eb Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Mon, 7 Aug 2017 20:33:24 +0100 Subject: [PATCH 2/8] Add a new feature to MT_PARTICLEGEN, per Sphere's request - if you give the parameters line a backside, then the backside x offset controls the number of tics between particle spawn. (By default, it's 3.) --- src/info.c | 2 +- src/p_enemy.c | 4 ++-- src/p_mobj.c | 12 +++++++++--- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/info.c b/src/info.c index 1f5b394ab..61db2baf8 100644 --- a/src/info.c +++ b/src/info.c @@ -2581,7 +2581,7 @@ state_t states[NUMSTATES] = // Particle sprite {SPR_PRTL, FF_FULLBRIGHT|FF_TRANS70, 2*TICRATE, {NULL}, 0, 0, S_NULL}, // S_PARTICLE - {SPR_NULL, 0, 1, {A_ParticleSpawn}, 0, 0, S_PARTICLEGEN}, // S_PARTICLEGEN + {SPR_NULL, 0, 3, {A_ParticleSpawn}, 0, 0, S_PARTICLEGEN}, // S_PARTICLEGEN {SPR_SCOR, 0, 32, {A_ScoreRise}, 0, 0, S_NULL}, // S_SCRA - 100 {SPR_SCOR, 1, 32, {A_ScoreRise}, 0, 0, S_NULL}, // S_SCRB - 200 diff --git a/src/p_enemy.c b/src/p_enemy.c index c9a173616..77e140689 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -3582,12 +3582,12 @@ void A_ParticleSpawn(mobj_t *actor) spawn->tics = (tic_t)actor->health; spawn->flags2 |= (actor->flags2 & MF2_OBJECTFLIP); spawn->angle += P_RandomKey(36)*ANG10; // irrelevant for default objects but might make sense for some custom ones - if (spawn->frame & FF_ANIMATE) - spawn->frame += P_RandomKey(spawn->state->var1); actor->angle += actor->movedir; } + actor->angle += (angle_t)actor->movecount; + actor->tics = (tic_t)actor->reactiontime; } // Function: A_BunnyHop diff --git a/src/p_mobj.c b/src/p_mobj.c index 85c69fa73..f9d31eb31 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -10209,7 +10209,7 @@ domaceagain: case MT_PARTICLEGEN: { fixed_t radius, speed, bottomheight, topheight; - INT32 type, numdivisions, time, anglespeed; + INT32 type, numdivisions, time, anglespeed, ticcount; angle_t angledivision; INT32 line; const size_t mthingi = (size_t)(mthing - mapthings); @@ -10232,6 +10232,10 @@ domaceagain: bottomheight = lines[line].frontsector->floorheight; topheight = lines[line].frontsector->ceilingheight - mobjinfo[(mobjtype_t)type].height; + if (!lines[line].backsector + || (ticcount = (sides[lines[line].sidenum[1]].textureoffset >> FRACBITS)) < 1) + ticcount = states[S_PARTICLEGEN].tics; + numdivisions = (mthing->options >> ZSHIFT); if (numdivisions) @@ -10268,8 +10272,9 @@ domaceagain: "Numdivisions is %d\n" "Angledivision is %d\n" "Time is %d\n" - "Type is %d\n", - sizeu1(mthingi), radius, speed, anglespeed, numdivisions, angledivision, time, type); + "Type is %d\n" + "Tic seperation is %d\n", + sizeu1(mthingi), radius, speed, anglespeed, numdivisions, angledivision, time, type, ticcount); mobj->angle = 0; mobj->movefactor = speed; @@ -10279,6 +10284,7 @@ domaceagain: mobj->health = time; mobj->friction = radius; mobj->threshold = type; + mobj->reactiontime = ticcount; break; } From a3767fedaccd22150934a2fa85b5b93d81f10ce5 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Mon, 7 Aug 2017 20:33:24 +0100 Subject: [PATCH 3/8] Clean out code/update comments relating to TEXTUREn, TEXTURE (SOC), PNAMES, and ANIMATED. --- src/p_setup.c | 18 +++-------------- src/p_spec.c | 41 +++++---------------------------------- src/r_data.c | 53 ++++++++++++++++++++------------------------------- src/r_data.h | 2 +- src/r_defs.h | 2 +- 5 files changed, 31 insertions(+), 85 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 3bae9379e..ae3d9fe76 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -3082,7 +3082,6 @@ boolean P_AddWadFile(const char *wadfilename, char **firstmapname) INT16 firstmapreplaced = 0, num; char *name; lumpinfo_t *lumpinfo; - boolean texturechange = false; boolean replacedcurrentmap = false; if ((numlumps = W_LoadWadFile(wadfilename)) == INT16_MAX) @@ -3126,14 +3125,6 @@ boolean P_AddWadFile(const char *wadfilename, char **firstmapname) CONS_Debug(DBG_SETUP, "Music %.8s replaced\n", name); digmreplaces++; } -#if 0 - // - // search for texturechange replacements - // - else if (!memcmp(name, "TEXTURE1", 8) || !memcmp(name, "TEXTURE2", 8) - || !memcmp(name, "PNAMES", 6)) -#endif - texturechange = true; } if (!devparm && sreplaces) CONS_Printf(M_GetText("%s sounds replaced\n"), sizeu1(sreplaces)); @@ -3149,13 +3140,10 @@ boolean P_AddWadFile(const char *wadfilename, char **firstmapname) // Reload it all anyway, just in case they // added some textures but didn't insert a - // TEXTURE1/PNAMES/etc. list. - if (texturechange) // initialized in the sound check - R_LoadTextures(); // numtexture changes - else - R_FlushTextureCache(); // just reload it from file + // TEXTURES/etc. list. + R_LoadTextures(); // numtexture changes - // Reload ANIMATED / ANIMDEFS + // Reload ANIMDEFS P_InitPicAnims(); // Flush and reload HUD graphics diff --git a/src/p_spec.c b/src/p_spec.c index 8a3ac0748..3d3b22896 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -74,7 +74,7 @@ typedef struct #endif /** Animated texture definition. - * Used for ::harddefs and for loading an ANIMATED lump from a wad. + * Used for ::harddefs and for loading an ANIMDEFS lump from a wad. * * Animations are defined by the first and last frame (i.e., flat or texture). * The animation sequence uses all flats between the start and end entry, in @@ -125,7 +125,7 @@ static size_t maxanims; // P_InitPicAnims // /** Hardcoded animation sequences. - * Used if no ANIMATED lump is found in a loaded wad. + * Used if no ANIMDEFS lump is found in a loaded wad. */ static animdef_t harddefs[] = { @@ -244,48 +244,17 @@ void P_InitPicAnims(void) { // Init animation INT32 w; // WAD - UINT8 *animatedLump; - UINT8 *currentPos; size_t i; I_Assert(animdefs == NULL); - if (W_CheckNumForName("ANIMATED") != LUMPERROR || W_CheckNumForName("ANIMDEFS") != LUMPERROR) + if (W_CheckNumForName("ANIMDEFS") != LUMPERROR) { for (w = numwadfiles-1, maxanims = 0; w >= 0; w--) { - UINT16 animatedLumpNum; UINT16 animdefsLumpNum; - // Find ANIMATED lump in the WAD - animatedLumpNum = W_CheckNumForNamePwad("ANIMATED", w, 0); - if (animatedLumpNum != INT16_MAX) - { - animatedLump = (UINT8 *)W_CacheLumpNumPwad(w, animatedLumpNum, PU_STATIC); - - // Get the number of animations in the file - i = maxanims; - for (currentPos = animatedLump; *currentPos != UINT8_MAX; maxanims++, currentPos+=23); - - // Resize animdefs (or if it hasn't been created, create it) - animdefs = (animdef_t *)Z_Realloc(animdefs, sizeof(animdef_t)*(maxanims + 1), PU_STATIC, NULL); - // Sanity check it - if (!animdefs) - I_Error("Not enough free memory for ANIMATED data"); - - // Populate the new array - for (currentPos = animatedLump; *currentPos != UINT8_MAX; i++, currentPos+=23) - { - M_Memcpy(&(animdefs[i].istexture), currentPos, 1); // istexture, 1 byte - M_Memcpy(animdefs[i].endname, (currentPos + 1), 9); // endname, 9 bytes - M_Memcpy(animdefs[i].startname, (currentPos + 10), 9); // startname, 9 bytes - M_Memcpy(&(animdefs[i].speed), (currentPos + 19), 4); // speed, 4 bytes - } - - Z_Free(animatedLump); - } - - // Now find ANIMDEFS + // Find ANIMDEFS lump in the WAD animdefsLumpNum = W_CheckNumForNamePwad("ANIMDEFS", w, 0); if (animdefsLumpNum != INT16_MAX) P_ParseANIMDEFSLump(w, animdefsLumpNum); @@ -307,7 +276,7 @@ void P_InitPicAnims(void) anims = (anim_t *)malloc(sizeof (*anims)*(maxanims + 1)); if (!anims) - I_Error("Not enough free memory for ANIMATED data"); + I_Error("Not enough free memory for ANIMDEFS data"); lastanim = anims; for (i = 0; animdefs[i].istexture != -1; i++) diff --git a/src/r_data.c b/src/r_data.c index e33a12ec8..791d90d94 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -625,44 +625,33 @@ void R_LoadTextures(void) { patchlump = W_CacheLumpNumPwad((UINT16)w, texstart + j, PU_CACHE); - // Then, check the lump directly to see if it's a texture SOC, - // and if it is, load it using dehacked instead. - if (strstr((const char *)patchlump, "TEXTURE")) - { - CONS_Alert(CONS_WARNING, "%s is a Texture SOC.\n", W_CheckNameForNumPwad((UINT16)w,texstart+j)); - Z_Unlock(patchlump); - DEH_LoadDehackedLumpPwad((UINT16)w, texstart + j); - } - else - { - //CONS_Printf("\n\"%s\" is a single patch, dimensions %d x %d",W_CheckNameForNumPwad((UINT16)w,texstart+j),patchlump->width, patchlump->height); - texture = textures[i] = Z_Calloc(sizeof(texture_t) + sizeof(texpatch_t), PU_STATIC, NULL); + //CONS_Printf("\n\"%s\" is a single patch, dimensions %d x %d",W_CheckNameForNumPwad((UINT16)w,texstart+j),patchlump->width, patchlump->height); + texture = textures[i] = Z_Calloc(sizeof(texture_t) + sizeof(texpatch_t), PU_STATIC, NULL); - // Set texture properties. - M_Memcpy(texture->name, W_CheckNameForNumPwad((UINT16)w, texstart + j), sizeof(texture->name)); - texture->width = SHORT(patchlump->width); - texture->height = SHORT(patchlump->height); - texture->patchcount = 1; - texture->holes = false; - texture->flip = 0; + // Set texture properties. + M_Memcpy(texture->name, W_CheckNameForNumPwad((UINT16)w, texstart + j), sizeof(texture->name)); + texture->width = SHORT(patchlump->width); + texture->height = SHORT(patchlump->height); + texture->patchcount = 1; + texture->holes = false; + texture->flip = 0; - // Allocate information for the texture's patches. - patch = &texture->patches[0]; + // Allocate information for the texture's patches. + patch = &texture->patches[0]; - patch->originx = patch->originy = 0; - patch->wad = (UINT16)w; - patch->lump = texstart + j; - patch->flip = 0; + patch->originx = patch->originy = 0; + patch->wad = (UINT16)w; + patch->lump = texstart + j; + patch->flip = 0; - Z_Unlock(patchlump); + Z_Unlock(patchlump); - k = 1; - while (k << 1 <= texture->width) - k <<= 1; + k = 1; + while (k << 1 <= texture->width) + k <<= 1; - texturewidthmask[i] = k - 1; - textureheight[i] = texture->height << FRACBITS; - } + texturewidthmask[i] = k - 1; + textureheight[i] = texture->height << FRACBITS; } } } diff --git a/src/r_data.h b/src/r_data.h index 2d984c1c8..53bf27835 100644 --- a/src/r_data.h +++ b/src/r_data.h @@ -68,7 +68,7 @@ extern INT16 *hicolormaps; // remap high colors to high colors.. extern CV_PossibleValue_t Color_cons_t[]; -// Load TEXTURE1/TEXTURE2/PNAMES definitions, create lookup tables +// Load TEXTURES definitions, create lookup tables void R_LoadTextures(void); void R_FlushTextureCache(void); diff --git a/src/r_defs.h b/src/r_defs.h index 7744a12d8..7c8f2a73f 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -688,7 +688,7 @@ typedef enum // Patches. // A patch holds one or more columns. // Patches are used for sprites and all masked pictures, and we compose -// textures from the TEXTURE1 list of patches. +// textures from the TEXTURES list of patches. // // WARNING: this structure is cloned in GLPatch_t typedef struct From 1cab08e39f195a00b3690caef5debe7216466622 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Wed, 9 Aug 2017 20:56:31 +0100 Subject: [PATCH 4/8] * Add SH_PROTECTSPIKE as a shield flag, because I kinda wanted to when I originally made shields, and SUBARASHII's cactus shield vindicated my desires. * Tweaked the values of the shield constants slightly so that no base-game shield is made up of flags and only flags. --- src/d_player.h | 20 +++++++++++++++----- src/dehacked.c | 1 + src/p_inter.c | 32 ++++++++++++++++---------------- 3 files changed, 32 insertions(+), 21 deletions(-) diff --git a/src/d_player.h b/src/d_player.h index 4e4a53a08..f8b38ded9 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -181,6 +181,14 @@ typedef enum PA_RIDE } panim_t; +// +// All of the base srb2 shields are either a single constant, +// or use damagetype-protecting flags applied to a constant, +// or are the force shield (which does everything weirdly). +// +// Base flags by themselves aren't used so modders can make +// abstract, ability-less shields should they so choose. +// typedef enum { SH_NONE = 0, @@ -189,19 +197,21 @@ typedef enum SH_PROTECTFIRE = 0x400, SH_PROTECTWATER = 0x800, SH_PROTECTELECTRIC = 0x1000, + SH_PROTECTSPIKE = 0x2000, // cactus shield one day? thanks, subarashii + //SH_PROTECTNUKE = 0x4000, // intentionally no hardcoded defense against nukes // Indivisible shields SH_PITY = 1, // the world's most basic shield ever, given to players who suck at Match SH_WHIRLWIND, SH_ARMAGEDDON, - // normal shields that use flags - SH_ATTRACT = SH_PROTECTELECTRIC, - SH_ELEMENTAL = SH_PROTECTFIRE|SH_PROTECTWATER, + // Normal shields that use flags + SH_ATTRACT = SH_PITY|SH_PROTECTELECTRIC, + SH_ELEMENTAL = SH_PITY|SH_PROTECTFIRE|SH_PROTECTWATER, // Sonic 3 shields - SH_FLAMEAURA = SH_PROTECTFIRE, - SH_BUBBLEWRAP = SH_PROTECTWATER, + SH_FLAMEAURA = SH_PITY|SH_PROTECTFIRE, + SH_BUBBLEWRAP = SH_PITY|SH_PROTECTWATER, SH_THUNDERCOIN = SH_WHIRLWIND|SH_PROTECTELECTRIC, // The force shield uses the lower 8 bits to count how many extra hits are left. diff --git a/src/dehacked.c b/src/dehacked.c index 3a40b64a5..56f3014f1 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -7146,6 +7146,7 @@ struct { {"SH_PROTECTFIRE",SH_PROTECTFIRE}, {"SH_PROTECTWATER",SH_PROTECTWATER}, {"SH_PROTECTELECTRIC",SH_PROTECTELECTRIC}, + {"SH_PROTECTSPIKE",SH_PROTECTSPIKE}, // Indivisible shields {"SH_PITY",SH_PITY}, {"SH_WHIRLWIND",SH_WHIRLWIND}, diff --git a/src/p_inter.c b/src/p_inter.c index fc3bd080e..07165d2cc 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -414,13 +414,15 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) //////////////////////////////////////////////////////// if (special->type == MT_GSNAPPER && !(((player->powers[pw_carry] == CR_NIGHTSMODE) && (player->pflags & PF_DRILLING)) || player->powers[pw_invulnerability] || player->powers[pw_super] || elementalpierce) - && toucher->z < special->z + special->height && toucher->z + toucher->height > special->z) + && toucher->z < special->z + special->height && toucher->z + toucher->height > special->z + && !(player->powers[pw_shield] & SH_PROTECTSPIKE)) { // Can only hit snapper from above - P_DamageMobj(toucher, special, special, 1, 0); + P_DamageMobj(toucher, special, special, 1, DMG_SPIKE); } else if (special->type == MT_SHARP - && ((special->state == &states[special->info->xdeathstate]) || (toucher->z > special->z + special->height/2))) + && ((special->state == &states[special->info->xdeathstate]) || (toucher->z > special->z + special->height/2)) + && !(player->powers[pw_shield] & SH_PROTECTSPIKE)) { if (player->pflags & PF_BOUNCING) { @@ -428,7 +430,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) P_DoAbilityBounce(player, false); } else // Cannot hit sharp from above or when red and angry - P_DamageMobj(toucher, special, special, 1, 0); + P_DamageMobj(toucher, special, special, 1, DMG_SPIKE); } else if (((player->powers[pw_carry] == CR_NIGHTSMODE) && (player->pflags & PF_DRILLING)) || ((player->pflags & PF_JUMPED) && (!(player->pflags & PF_NOJUMPDAMAGE) || (player->charability == CA_TWINSPIN && player->panim == PA_ABILITY))) @@ -3164,18 +3166,16 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da switch (damagetype) { - case DMG_WATER: - if (player->powers[pw_shield] & SH_PROTECTWATER) - return false; // Invincible to water damage - break; - case DMG_FIRE: - if (player->powers[pw_shield] & SH_PROTECTFIRE) - return false; // Invincible to fire damage - break; - case DMG_ELECTRIC: - if (player->powers[pw_shield] & SH_PROTECTELECTRIC) - return false; // Invincible to electric damage - break; +#define DAMAGECASE(type)\ + case DMG_##type:\ + if (player->powers[pw_shield] & SH_PROTECT##type)\ + return false;\ + break + DAMAGECASE(WATER); + DAMAGECASE(FIRE); + DAMAGECASE(ELECTRIC); + DAMAGECASE(SPIKE); +#undef DAMAGECASE default: break; } From 8175e0836ea442a00ddd52d606e34a5d7e3b9296 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Wed, 9 Aug 2017 22:09:06 +0100 Subject: [PATCH 5/8] Remove all trace of harddefs, considering we use an ANIMDEFS lump in srb2.srb now. --- src/p_spec.c | 130 ++++++--------------------------------------------- 1 file changed, 13 insertions(+), 117 deletions(-) diff --git a/src/p_spec.c b/src/p_spec.c index 3d3b22896..2cad4fc90 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -74,7 +74,7 @@ typedef struct #endif /** Animated texture definition. - * Used for ::harddefs and for loading an ANIMDEFS lump from a wad. + * Used for loading an ANIMDEFS lump from a wad. * * Animations are defined by the first and last frame (i.e., flat or texture). * The animation sequence uses all flats between the start and end entry, in @@ -121,104 +121,6 @@ static anim_t *lastanim; static anim_t *anims = NULL; /// \todo free leak static size_t maxanims; -// -// P_InitPicAnims -// -/** Hardcoded animation sequences. - * Used if no ANIMDEFS lump is found in a loaded wad. - */ -static animdef_t harddefs[] = -{ - // flat animations. - {false, "LITEY3", "LITEY1", 4}, - {false, "FWATER16", "FWATER1", 4}, - {false, "BWATER16", "BWATER01", 4}, - {false, "LWATER16", "LWATER1", 4}, - {false, "WATER7", "WATER0", 4}, - {false, "LAVA4", "LAVA1", 8}, - {false, "DLAVA4", "DLAVA1", 8}, - {false, "RLAVA8", "RLAVA1", 8}, - {false, "LITER3", "LITER1", 8}, - {false, "SURF08", "SURF01", 4}, - - {false, "CHEMG16", "CHEMG01", 4}, // THZ Chemical gunk - {false, "GOOP16", "GOOP01", 4}, // Green chemical gunk - {false, "OIL16", "OIL01", 4}, // Oil - {false, "THZBOXF4", "THZBOXF1", 2}, // Moved up with the flats - {false, "ALTBOXF4", "ALTBOXF1", 2}, - - {false, "LITEB3", "LITEB1", 4}, - {false, "LITEN3", "LITEN1", 4}, - {false, "ACZRFL1H", "ACZRFL1A", 4}, - {false, "ACZRFL2H", "ACZRFL2A", 4}, - {false, "EGRIDF3", "EGRIDF1", 4}, - {false, "ERZFAN4", "ERZFAN1", 1}, - {false, "ERZFANR4", "ERZFANR1", 1}, - {false, "DISCO4", "DISCO1", 15}, - - // animated textures - {true, "GFALL4", "GFALL1", 2}, // Short waterfall - {true, "CFALL4", "CFALL1", 2}, // Long waterfall - {true, "TFALL4", "TFALL1", 2}, // THZ Chemical fall - {true, "AFALL4", "AFALL1", 2}, // Green Chemical fall - {true, "QFALL4", "QFALL1", 2}, // Quicksand fall - {true, "Q2FALL4", "Q2FALL1", 2}, - {true, "Q3FALL4", "Q3FALL1", 2}, - {true, "Q4FALL4", "Q4FALL1", 2}, - {true, "Q5FALL4", "Q5FALL1", 2}, - {true, "Q6FALL4", "Q6FALL1", 2}, - {true, "Q7FALL4", "Q7FALL1", 2}, - {true, "LFALL4", "LFALL1", 2}, - {true, "MFALL4", "MFALL1", 2}, - {true, "OFALL4", "OFALL1", 2}, - {true, "DLAVA4", "DLAVA1", 8}, - {true, "ERZLASA2", "ERZLASA1", 1}, - {true, "ERZLASB4", "ERZLASB1", 1}, - {true, "ERZLASC4", "ERZLASC1", 1}, - {true, "THZBOX04", "THZBOX01", 2}, - {true, "ALTBOX04", "ALTBOX01", 2}, - {true, "SFALL4", "SFALL1", 4}, // Lava fall - {true, "RVZFALL8", "RVZFALL1", 4}, - {true, "BFALL4", "BFALL1", 2}, // HPZ waterfall - {true, "GREYW3", "GREYW1", 4}, - {true, "BLUEW3", "BLUEW1", 4}, - {true, "COMP6", "COMP4", 4}, - {true, "RED3", "RED1", 4}, - {true, "YEL3", "YEL1", 4}, - {true, "ACWRFL1D", "ACWRFL1A", 1}, - {true, "ACWRFL2D", "ACWRFL2A", 1}, - {true, "ACWRFL3D", "ACWRFL3A", 1}, - {true, "ACWRFL4D", "ACWRFL4A", 1}, - {true, "ACWRP1D", "ACWRP1A", 1}, - {true, "ACWRP2D", "ACWRP2A", 1}, - {true, "ACZRP1D", "ACZRP1A", 1}, - {true, "ACZRP2D", "ACZRP2A", 1}, - {true, "OILFALL4", "OILFALL1", 2}, - {true, "SOLFALL4", "SOLFALL1", 2}, - {true, "DOWN1C", "DOWN1A", 4}, - {true, "DOWN2C", "DOWN2A", 4}, - {true, "DOWN3D", "DOWN3A", 4}, - {true, "DOWN4C", "DOWN4A", 4}, - {true, "DOWN5C", "DOWN5A", 4}, - {true, "UP1C", "UP1A", 4}, - {true, "UP2C", "UP2A", 4}, - {true, "UP3D", "UP3A", 4}, - {true, "UP4C", "UP4A", 4}, - {true, "UP5C", "UP5A", 4}, - {true, "EGRID3", "EGRID1", 4}, - {true, "ERFANW4", "ERFANW1", 1}, - {true, "ERFANX4", "ERFANX1", 1}, - {true, "DISCOD4", "DISCOD1", 15}, - {true, "DANCE4", "DANCE1", 8}, - {true, "SKY135", "SKY132", 2}, - {true, "APPLMS4", "APPLMS1", 2}, - {true, "APBOXW3", "APBOXW1", 2}, - {true, "ERZLAZC4", "ERZLAZC1", 4}, - - // End of line - { -1, "", "", 0}, -}; - // Animating line specials // Init animated textures @@ -232,7 +134,7 @@ void P_ParseAnimationDefintion(SINT8 istexture); /** Sets up texture and flat animations. * - * Converts an ::animdef_t array loaded from ::harddefs or a lump into + * Converts an ::animdef_t array loaded from a lump into * ::anim_t format. * * Issues an error if any animation cycles are invalid. @@ -248,9 +150,11 @@ void P_InitPicAnims(void) I_Assert(animdefs == NULL); + maxanims = 0; + if (W_CheckNumForName("ANIMDEFS") != LUMPERROR) { - for (w = numwadfiles-1, maxanims = 0; w >= 0; w--) + for (w = numwadfiles-1; w >= 0; w--) { UINT16 animdefsLumpNum; @@ -259,18 +163,14 @@ void P_InitPicAnims(void) if (animdefsLumpNum != INT16_MAX) P_ParseANIMDEFSLump(w, animdefsLumpNum); } - // Define the last one - animdefs[maxanims].istexture = -1; - strncpy(animdefs[maxanims].endname, "", 9); - strncpy(animdefs[maxanims].startname, "", 9); - animdefs[maxanims].speed = 0; - } - else - { - animdefs = harddefs; - for (maxanims = 0; animdefs[maxanims].istexture != -1; maxanims++); } + // Define the last one + animdefs[maxanims].istexture = -1; + strncpy(animdefs[maxanims].endname, "", 9); + strncpy(animdefs[maxanims].startname, "", 9); + animdefs[maxanims].speed = 0; + if (anims) free(anims); @@ -308,10 +208,7 @@ void P_InitPicAnims(void) animdefs[i].startname, animdefs[i].endname); } - if (animdefs == harddefs) - lastanim->speed = animdefs[i].speed; - else - lastanim->speed = LONG(animdefs[i].speed); + lastanim->speed = LONG(animdefs[i].speed); lastanim++; } lastanim->istexture = -1; @@ -319,8 +216,7 @@ void P_InitPicAnims(void) // Clear animdefs now that we're done with it. // We'll only be using anims from now on. - if (animdefs != harddefs) - Z_Free(animdefs); + Z_Free(animdefs); animdefs = NULL; } From 709a43d3be410d2032d4d3e127c47dc4d61936bb Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Wed, 9 Aug 2017 22:51:29 +0100 Subject: [PATCH 6/8] Fix that thing where you-know-who didn't have a lives icon. --- src/r_draw.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/r_draw.c b/src/r_draw.c index 30b60a0e0..24062a678 100644 --- a/src/r_draw.c +++ b/src/r_draw.c @@ -1155,7 +1155,7 @@ UINT8 R_GetColorByName(const char *name) for (color = 1; color < MAXSKINCOLORS; color++) if (!stricmp(Color_Names[color], name)) return color; - return 0; + return SKINCOLOR_GREEN; } UINT8 R_GetSuperColorByName(const char *name) @@ -1166,7 +1166,7 @@ UINT8 R_GetSuperColorByName(const char *name) for (color = 0; color < NUMSUPERCOLORS; color++) if (!stricmp(Color_Names[color + MAXSKINCOLORS], name)) return ((color*5) + MAXSKINCOLORS); - return 0; + return SKINCOLOR_SUPERGOLD1; } // ========================================================================== From a00deee20928511a2acce6ff2850eecef1ed41de Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Thu, 10 Aug 2017 13:57:09 +0100 Subject: [PATCH 7/8] * Combine all shield-giving functions into a single one, since they were practically identical anyways. * Expose P_SwitchShield(player, shieldnum) to Lua. --- src/dehacked.c | 10 +- src/info.c | 18 ++-- src/info.h | 10 +- src/lua_baselib.c | 13 +++ src/p_enemy.c | 265 ++-------------------------------------------- src/p_user.c | 12 ++- 6 files changed, 41 insertions(+), 287 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 56f3014f1..6affa302f 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -1739,7 +1739,6 @@ static actionpointer_t actionpointers[] = {{A_BossDeath}, "A_BOSSDEATH"}, {{A_CustomPower}, "A_CUSTOMPOWER"}, {{A_GiveWeapon}, "A_GIVEWEAPON"}, - {{A_RingShield}, "A_RINGSHIELD"}, {{A_RingBox}, "A_RINGBOX"}, {{A_Invincibility}, "A_INVINCIBILITY"}, {{A_SuperSneakers}, "A_SUPERSNEAKERS"}, @@ -1750,14 +1749,7 @@ static actionpointer_t actionpointers[] = {{A_BubbleCheck}, "A_BUBBLECHECK"}, {{A_AwardScore}, "A_AWARDSCORE"}, {{A_ExtraLife}, "A_EXTRALIFE"}, - {{A_BombShield}, "A_BOMBSHIELD"}, - {{A_JumpShield}, "A_JUMPSHIELD"}, - {{A_WaterShield}, "A_WATERSHIELD"}, - {{A_ForceShield}, "A_FORCESHIELD"}, - {{A_PityShield}, "A_PITYSHIELD"}, - {{A_FlameShield}, "A_FLAMESHIELD"}, - {{A_BubbleShield}, "A_BUBBLESHIELD"}, - {{A_ThunderShield}, "A_THUNDERSHIELD"}, + {{A_GiveShield}, "A_GIVESHIELD"}, {{A_GravityBox}, "A_GRAVITYBOX"}, {{A_ScoreRise}, "A_SCORERISE"}, {{A_ParticleSpawn}, "A_PARTICLESPAWN"}, diff --git a/src/info.c b/src/info.c index 61db2baf8..2d6c9a3d1 100644 --- a/src/info.c +++ b/src/info.c @@ -1679,22 +1679,22 @@ state_t states[NUMSTATES] = {SPR_TVRI, 2, 18, {A_RingBox}, 0, 0, S_NULL}, // S_RING_ICON2 {SPR_TVPI, FF_ANIMATE|2, 18, {NULL}, 3, 4, S_PITY_ICON2}, // S_PITY_ICON1 - {SPR_TVPI, 2, 18, {A_PityShield}, 0, 0, S_NULL}, // S_PITY_ICON2 + {SPR_TVPI, 2, 18, {A_GiveShield}, SH_PITY, 0, S_NULL}, // S_PITY_ICON2 {SPR_TVAT, FF_ANIMATE|2, 18, {NULL}, 3, 4, S_ATTRACT_ICON2}, // S_ATTRACT_ICON1 - {SPR_TVAT, 2, 18, {A_RingShield},0, 0, S_NULL}, // S_ATTRACT_ICON2 + {SPR_TVAT, 2, 18, {A_GiveShield}, SH_ATTRACT, 0, S_NULL}, // S_ATTRACT_ICON2 {SPR_TVFO, FF_ANIMATE|2, 18, {NULL}, 3, 4, S_FORCE_ICON2}, // S_FORCE_ICON1 - {SPR_TVFO, 2, 18, {A_ForceShield}, 1, 0, S_NULL}, // S_FORCE_ICON2 + {SPR_TVFO, 2, 18, {A_GiveShield}, SH_FORCE|1, 0, S_NULL}, // S_FORCE_ICON2 {SPR_TVAR, FF_ANIMATE|2, 18, {NULL}, 3, 4, S_ARMAGEDDON_ICON2}, // S_ARMAGEDDON_ICON1 - {SPR_TVAR, 2, 18, {A_BombShield}, 0, 0, S_NULL}, // S_ARMAGEDDON_ICON2 + {SPR_TVAR, 2, 18, {A_GiveShield}, SH_ARMAGEDDON, 0, S_NULL}, // S_ARMAGEDDON_ICON2 {SPR_TVWW, FF_ANIMATE|2, 18, {NULL}, 3, 4, S_WHIRLWIND_ICON2}, // S_WHIRLWIND_ICON1 - {SPR_TVWW, 2, 18, {A_JumpShield}, 0, 0, S_NULL}, // S_WHIRLWIND_ICON2 + {SPR_TVWW, 2, 18, {A_GiveShield}, SH_WHIRLWIND, 0, S_NULL}, // S_WHIRLWIND_ICON2 {SPR_TVEL, FF_ANIMATE|2, 18, {NULL}, 3, 4, S_ELEMENTAL_ICON2}, // S_ELEMENTAL_ICON1 - {SPR_TVEL, 2, 18, {A_WaterShield}, 0, 0, S_NULL}, // S_ELEMENTAL_ICON2 + {SPR_TVEL, 2, 18, {A_GiveShield}, SH_ELEMENTAL, 0, S_NULL}, // S_ELEMENTAL_ICON2 {SPR_TVSS, FF_ANIMATE|2, 18, {NULL}, 3, 4, S_SNEAKERS_ICON2}, // S_SNEAKERS_ICON1 {SPR_TVSS, 2, 18, {A_SuperSneakers}, 0, 0, S_NULL}, // S_SNEAKERS_ICON2 @@ -1724,13 +1724,13 @@ state_t states[NUMSTATES] = {SPR_TVTK, 2, 18, {A_AwardScore}, 0, 0, S_NULL}, // S_SCORE10K_ICON2 {SPR_TVFL, FF_ANIMATE|2, 18, {NULL}, 3, 4, S_FLAMEAURA_ICON2}, // S_FLAMEAURA_ICON1 - {SPR_TVFL, 2, 18, {A_FlameShield}, 0, 0, S_NULL}, // S_FLAMEAURA_ICON2 + {SPR_TVFL, 2, 18, {A_GiveShield}, SH_FLAMEAURA, 0, S_NULL}, // S_FLAMEAURA_ICON2 {SPR_TVBB, FF_ANIMATE|2, 18, {NULL}, 3, 4, S_BUBBLEWRAP_ICON2}, // S_BUBBLEWRAP_ICON1 - {SPR_TVBB, 2, 18, {A_BubbleShield}, 0, 0, S_NULL}, // S_BUBBLERWAP_ICON2 + {SPR_TVBB, 2, 18, {A_GiveShield}, SH_BUBBLEWRAP, 0, S_NULL}, // S_BUBBLERWAP_ICON2 {SPR_TVZP, FF_ANIMATE|2, 18, {NULL}, 3, 4, S_THUNDERCOIN_ICON2}, // S_THUNDERCOIN_ICON1 - {SPR_TVZP, 2, 18, {A_ThunderShield}, 0, 0, S_NULL}, // S_THUNDERCOIN_ICON2 + {SPR_TVZP, 2, 18, {A_GiveShield}, SH_THUNDERCOIN, 0, S_NULL}, // S_THUNDERCOIN_ICON2 // --- diff --git a/src/info.h b/src/info.h index 63a4d893f..cd79b12a9 100644 --- a/src/info.h +++ b/src/info.h @@ -40,8 +40,6 @@ void A_Scream(); void A_BossDeath(); void A_CustomPower(); // Use this for a custom power void A_GiveWeapon(); // Gives the player weapon(s) -void A_JumpShield(); // Obtained Jump Shield -void A_RingShield(); // Obtained Ring Shield void A_RingBox(); // Obtained Ring Box Tails void A_Invincibility(); // Obtained Invincibility Box void A_SuperSneakers(); // Obtained Super Sneakers Box @@ -52,13 +50,7 @@ void A_BubbleRise(); // Bubbles float to surface void A_BubbleCheck(); // Don't draw if not underwater void A_AwardScore(); void A_ExtraLife(); // Extra Life -void A_BombShield(); // Obtained Bomb Shield -void A_WaterShield(); // Obtained Water Shield -void A_ForceShield(); // Obtained Force Shield -void A_PityShield(); // Obtained Pity Shield. We're... sorry. -void A_FlameShield(); // Obtained Flame Shield -void A_BubbleShield(); // Obtained Bubble Shield -void A_ThunderShield(); // Obtained Thunder Shield +void A_GiveShield(); // Obtained Shield void A_GravityBox(); void A_ScoreRise(); // Rise the score logo void A_ParticleSpawn(); diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 93f2979fa..de379cdbb 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -1183,6 +1183,18 @@ static int lib_pTelekinesis(lua_State *L) return 0; } +static int lib_pSwitchShield(lua_State *L) +{ + player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); + UINT16 shield = luaL_checkinteger(L, 2); + NOHUD + INLEVEL + if (!player) + return LUA_ErrInvalid(L, "player_t"); + P_SwitchShield(player, shield); + return 0; +} + // P_MAP /////////// @@ -2445,6 +2457,7 @@ static luaL_Reg lib[] = { {"P_SpawnThokMobj",lib_pSpawnThokMobj}, {"P_SpawnSpinMobj",lib_pSpawnSpinMobj}, {"P_Telekinesis",lib_pTelekinesis}, + {"P_SwitchShield",lib_pSwitchShield}, // p_map {"P_CheckPosition",lib_pCheckPosition}, diff --git a/src/p_enemy.c b/src/p_enemy.c index 77e140689..7f080b43e 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -93,20 +93,12 @@ void A_Explode(mobj_t *actor); void A_BossDeath(mobj_t *actor); void A_CustomPower(mobj_t *actor); void A_GiveWeapon(mobj_t *actor); -void A_JumpShield(mobj_t *actor); -void A_RingShield(mobj_t *actor); void A_RingBox(mobj_t *actor); void A_Invincibility(mobj_t *actor); void A_SuperSneakers(mobj_t *actor); void A_AwardScore(mobj_t *actor); void A_ExtraLife(mobj_t *actor); -void A_BombShield(mobj_t *actor); -void A_WaterShield(mobj_t *actor); -void A_ForceShield(mobj_t *actor); -void A_PityShield(mobj_t *actor); -void A_FlameShield(mobj_t *actor); -void A_BubbleShield(mobj_t *actor); -void A_ThunderShield(mobj_t *actor); +void A_GiveShield(mobj_t *actor); void A_GravityBox(mobj_t *actor); void A_ScoreRise(mobj_t *actor); void A_ParticleSpawn(mobj_t *actor); @@ -3056,62 +3048,6 @@ void A_GiveWeapon(mobj_t *actor) S_StartSound(player->mo, actor->info->seesound); } -// Function: A_JumpShield -// -// Description: Awards the player a jump shield. -// -// var1 = unused -// var2 = unused -// -void A_JumpShield(mobj_t *actor) -{ - player_t *player; - -#ifdef HAVE_BLUA - if (LUA_CallAction("A_JumpShield", actor)) - return; -#endif - if (!actor->target || !actor->target->player) - { - CONS_Debug(DBG_GAMELOGIC, "Powerup has no target.\n"); - return; - } - - player = actor->target->player; - - P_SwitchShield(player, SH_WHIRLWIND); - - S_StartSound(player->mo, actor->info->seesound); -} - -// Function: A_RingShield -// -// Description: Awards the player a ring shield. -// -// var1 = unused -// var2 = unused -// -void A_RingShield(mobj_t *actor) -{ - player_t *player; - -#ifdef HAVE_BLUA - if (LUA_CallAction("A_RingShield", actor)) - return; -#endif - if (!actor->target || !actor->target->player) - { - CONS_Debug(DBG_GAMELOGIC, "Powerup has no target.\n"); - return; - } - - player = actor->target->player; - - P_SwitchShield(player, SH_ATTRACT); - - S_StartSound(player->mo, actor->info->seesound); -} - // Function: A_RingBox // // Description: Awards the player 10 rings. @@ -3285,19 +3221,20 @@ void A_ExtraLife(mobj_t *actor) P_PlayLivesJingle(player); } -// Function: A_BombShield +// Function: A_GiveShield // -// Description: Awards the player a bomb shield. +// Description: Awards the player a specified shield. // -// var1 = unused +// var1 = Shield type (make with SH_ constants) // var2 = unused // -void A_BombShield(mobj_t *actor) +void A_GiveShield(mobj_t *actor) { player_t *player; + UINT16 locvar1 = var1; #ifdef HAVE_BLUA - if (LUA_CallAction("A_BombShield", actor)) + if (LUA_CallAction("A_GiveShield", actor)) return; #endif if (!actor->target || !actor->target->player) @@ -3308,196 +3245,10 @@ void A_BombShield(mobj_t *actor) player = actor->target->player; - // If you already have a bomb shield, use it! - if ((player->powers[pw_shield] & SH_NOSTACK) == SH_ARMAGEDDON) - P_BlackOw(player); - - // Now we know for certain that we don't have a bomb shield, so add one. :3 - P_SwitchShield(player, SH_ARMAGEDDON); - + P_SwitchShield(player, locvar1); S_StartSound(player->mo, actor->info->seesound); } -// Function: A_WaterShield -// -// Description: Awards the player a water shield. -// -// var1 = unused -// var2 = unused -// -void A_WaterShield(mobj_t *actor) -{ - player_t *player; - -#ifdef HAVE_BLUA - if (LUA_CallAction("A_WaterShield", actor)) - return; -#endif - if (!actor->target || !actor->target->player) - { - CONS_Debug(DBG_GAMELOGIC, "Powerup has no target.\n"); - return; - } - - player = actor->target->player; - - P_SwitchShield(player, SH_ELEMENTAL); - - S_StartSound(player->mo, actor->info->seesound); -} - -// Function: A_ForceShield -// -// Description: Awards the player a force shield. -// -// var1 = Number of additional hitpoints to give -// var2 = unused -// -void A_ForceShield(mobj_t *actor) -{ - player_t *player; - INT32 locvar1 = var1; - -#ifdef HAVE_BLUA - if (LUA_CallAction("A_ForceShield", actor)) - return; -#endif - if (!actor->target || !actor->target->player) - { - CONS_Debug(DBG_GAMELOGIC, "Powerup has no target.\n"); - return; - } - - if (locvar1 & ~SH_FORCEHP) - { - CONS_Debug(DBG_GAMELOGIC, "Invalid number of additional hitpoints.\n"); - return; - } - - player = actor->target->player; - - P_SwitchShield(player, SH_FORCE|locvar1); - - S_StartSound(player->mo, actor->info->seesound); -} - -// Function: A_PityShield -// -// Description: Awards the player a pity shield. -// Because you fail it. -// Your skill is not enough. -// See you next time. -// Bye-bye. -// -// var1 = unused -// var2 = unused -// -void A_PityShield(mobj_t *actor) -{ - player_t *player; - -#ifdef HAVE_BLUA - if (LUA_CallAction("A_PityShield", actor)) - return; -#endif - if (!actor->target || !actor->target->player) - { - CONS_Debug(DBG_GAMELOGIC, "Powerup has no target.\n"); - return; - } - - player = actor->target->player; - - P_SwitchShield(player, SH_PITY); - - S_StartSound(player->mo, actor->info->seesound); -} - -// Function: A_FlameShield -// -// Description: Awards the player a flame shield. -// -// var1 = unused -// var2 = unused -// -void A_FlameShield(mobj_t *actor) -{ - player_t *player; - -#ifdef HAVE_BLUA - if (LUA_CallAction("A_FlameShield", actor)) - return; -#endif - if (!actor->target || !actor->target->player) - { - CONS_Debug(DBG_GAMELOGIC, "Powerup has no target.\n"); - return; - } - - player = actor->target->player; - - P_SwitchShield(player, SH_FLAMEAURA); - - S_StartSound(player->mo, actor->info->seesound); -} - -// Function: A_BubbleShield -// -// Description: Awards the player a bubble shield. -// -// var1 = unused -// var2 = unused -// -void A_BubbleShield(mobj_t *actor) -{ - player_t *player; - -#ifdef HAVE_BLUA - if (LUA_CallAction("A_BubbleShield", actor)) - return; -#endif - if (!actor->target || !actor->target->player) - { - CONS_Debug(DBG_GAMELOGIC, "Powerup has no target.\n"); - return; - } - - player = actor->target->player; - - P_SwitchShield(player, SH_BUBBLEWRAP); - - S_StartSound(player->mo, actor->info->seesound); -} - -// Function: A_ThunderShield -// -// Description: Awards the player a thunder shield. -// -// var1 = unused -// var2 = unused -// -void A_ThunderShield(mobj_t *actor) -{ - player_t *player; - -#ifdef HAVE_BLUA - if (LUA_CallAction("A_ThunderShield", actor)) - return; -#endif - if (!actor->target || !actor->target->player) - { - CONS_Debug(DBG_GAMELOGIC, "Powerup has no target.\n"); - return; - } - - player = actor->target->player; - - P_SwitchShield(player, SH_THUNDERCOIN); - - S_StartSound(player->mo, actor->info->seesound); -} - - // Function: A_GravityBox // // Description: Awards the player gravity boots. diff --git a/src/p_user.c b/src/p_user.c index eb8810acd..167e1eacb 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1473,9 +1473,15 @@ void P_SpawnShieldOrb(player_t *player) // void P_SwitchShield(player_t *player, UINT16 shieldtype) { - boolean donthavealready = (shieldtype & SH_FORCE) - ? (!(player->powers[pw_shield] & SH_FORCE) || (player->powers[pw_shield] & SH_FORCEHP) < (shieldtype & ~SH_FORCE)) - : ((player->powers[pw_shield] & SH_NOSTACK) != shieldtype); + boolean donthavealready; + + // If you already have a bomb shield, use it! + if ((shieldtype == SH_ARMAGEDDON) && (player->powers[pw_shield] & SH_NOSTACK) == SH_ARMAGEDDON) + P_BlackOw(player); + + donthavealready = (shieldtype & SH_FORCE) + ? (!(player->powers[pw_shield] & SH_FORCE) || (player->powers[pw_shield] & SH_FORCEHP) < (shieldtype & ~SH_FORCE)) + : ((player->powers[pw_shield] & SH_NOSTACK) != shieldtype); if (donthavealready) { From 6e79de3de87749f47d46adc4dda3e84368fad3b8 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Fri, 11 Aug 2017 16:00:45 +0100 Subject: [PATCH 8/8] Patched an out-of-bounds crash with papersprites in the least resource-intensive way I could find (xiscale not fitting perfectly into frac). This will have to do until papersprites get a make-over at some point. --- src/r_things.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/r_things.c b/src/r_things.c index 53dcc3314..42250e405 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -924,7 +924,7 @@ static void R_DrawVisSprite(vissprite_t *vis) texturecolumn = frac>>FRACBITS; if (texturecolumn < 0 || texturecolumn >= SHORT(patch->width)) - I_Error("R_DrawSpriteRange: bad texturecolumn"); + I_Error("R_DrawSpriteRange: bad texturecolumn at %d from end", vis->x2 - dc_x); column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[texturecolumn])); #else column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[frac>>FRACBITS])); @@ -1262,7 +1262,7 @@ static void R_ProjectSprite(mobj_t *thing) offset2 = FixedMul(spritecachedinfo[lump].width, this_scale); tx += FixedMul(offset2, ang_scale); - x2 = ((centerxfrac + FixedMul (tx,xscale)) >>FRACBITS) - 1; + x2 = ((centerxfrac + FixedMul (tx,xscale)) >> FRACBITS) - (papersprite ? 2 : 1); // off the left side if (x2 < 0)