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..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"}, @@ -7146,6 +7138,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/info.c b/src/info.c index 1f5b394ab..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 // --- @@ -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/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 c9a173616..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. @@ -3582,12 +3333,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_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; } 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; } 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) { 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_data.c b/src/r_data.c index d51c50639..e3933a950 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -648,44 +648,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 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; } // ========================================================================== 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) { diff --git a/src/r_things.c b/src/r_things.c index 299c2dac7..6fd153aaf 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -933,7 +933,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])); @@ -1271,7 +1271,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)