diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 9b0a34f17..57bee95ed 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -1100,6 +1100,16 @@ static int lib_pPlayerWeaponAmmoBurst(lua_State *L) return 0; } +static int lib_pPlayerWeaponPanelOrAmmoBurst(lua_State *L) +{ + player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); + NOHUD + if (!player) + return LUA_ErrInvalid(L, "player_t"); + P_PlayerWeaponPanelOrAmmoBurst(player); + return 0; +} + static int lib_pPlayerEmeraldBurst(lua_State *L) { player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); @@ -1965,6 +1975,7 @@ static luaL_Reg lib[] = { {"P_PlayerRingBurst",lib_pPlayerRingBurst}, {"P_PlayerWeaponPanelBurst",lib_pPlayerWeaponPanelBurst}, {"P_PlayerWeaponAmmoBurst",lib_pPlayerWeaponAmmoBurst}, + {"P_PlayerWeaponPanelOrAmmoBurst", lib_pPlayerWeaponPanelOrAmmoBurst}, {"P_PlayerEmeraldBurst",lib_pPlayerEmeraldBurst}, {"P_PlayerFlagBurst",lib_pPlayerFlagBurst}, {"P_PlayRinglossSound",lib_pPlayRinglossSound}, diff --git a/src/p_inter.c b/src/p_inter.c index d305cfc83..97a8624c1 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -437,7 +437,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) { INT32 pindex = special->info->mass - (INT32)pw_infinityring; - player->powers[special->info->mass] += (UINT16)special->info->reactiontime; + player->powers[special->info->mass] += (UINT16)special->reactiontime; player->ringweapons |= 1 << (pindex-1); if (player->powers[special->info->mass] > rw_maximums[pindex]) @@ -3093,11 +3093,7 @@ void P_PlayerRingBurst(player_t *player, INT32 num_rings) P_PlayerEmeraldBurst(player, false); // Spill weapons first - if (player->ringweapons) - P_PlayerWeaponPanelBurst(player); - - // Spill the ammo - P_PlayerWeaponAmmoBurst(player); + P_PlayerWeaponPanelOrAmmoBurst(player); for (i = 0; i < num_rings; i++) { @@ -3354,6 +3350,75 @@ void P_PlayerWeaponAmmoBurst(player_t *player) } } +void P_PlayerWeaponPanelOrAmmoBurst(player_t *player) +{ + mobj_t *mo; + angle_t fa; + fixed_t ns; + INT32 i = 0; + fixed_t z; + + #define SETUP_DROP(thingtype) \ + z = player->mo->z; \ + if (player->mo->eflags & MFE_VERTICALFLIP) \ + z += player->mo->height - mobjinfo[thingtype].height; \ + fa = ((i*FINEANGLES/16) + (player->mo->angle>>ANGLETOFINESHIFT)) & FINEMASK; \ + ns = FixedMul(3*FRACUNIT, player->mo->scale); \ + + #define DROP_WEAPON(rwflag, pickup, ammo, power) \ + if (player->ringweapons & rwflag) \ + { \ + player->ringweapons &= ~rwflag; \ + SETUP_DROP(pickup) \ + mo = P_SpawnMobj(player->mo->x, player->mo->y, z, pickup); \ + mo->reactiontime = 0; \ + mo->flags2 |= MF2_DONTRESPAWN; \ + mo->flags &= ~(MF_NOGRAVITY|MF_NOCLIPHEIGHT); \ + P_SetTarget(&mo->target, player->mo); \ + mo->fuse = 12*TICRATE; \ + mo->destscale = player->mo->scale; \ + P_SetScale(mo, player->mo->scale); \ + mo->momx = FixedMul(FINECOSINE(fa),ns); \ + if (!(twodlevel || (player->mo->flags2 & MF2_TWOD))) \ + mo->momy = FixedMul(FINESINE(fa),ns); \ + P_SetObjectMomZ(mo, 4*FRACUNIT, false); \ + if (i & 1) \ + P_SetObjectMomZ(mo, 4*FRACUNIT, true); \ + ++i; \ + } \ + else if (player->powers[power] > 0) \ + { \ + SETUP_DROP(ammo) \ + mo = P_SpawnMobj(player->mo->x, player->mo->y, z, ammo); \ + mo->health = player->powers[power]; \ + mo->flags2 |= MF2_DONTRESPAWN; \ + mo->flags &= ~(MF_NOGRAVITY|MF_NOCLIPHEIGHT); \ + P_SetTarget(&mo->target, player->mo); \ + mo->fuse = 12*TICRATE; \ + mo->destscale = player->mo->scale; \ + P_SetScale(mo, player->mo->scale); \ + mo->momx = FixedMul(FINECOSINE(fa),ns); \ + if (!(twodlevel || (player->mo->flags2 & MF2_TWOD))) \ + mo->momy = FixedMul(FINESINE(fa),ns); \ + P_SetObjectMomZ(mo, 3*FRACUNIT, false); \ + if (i & 1) \ + P_SetObjectMomZ(mo, 3*FRACUNIT, true); \ + player->powers[power] = 0; \ + ++i; \ + } + + DROP_WEAPON(RW_BOUNCE, MT_BOUNCEPICKUP, MT_BOUNCERING, pw_bouncering); + DROP_WEAPON(RW_RAIL, MT_RAILPICKUP, MT_RAILRING, pw_railring); + DROP_WEAPON(RW_AUTO, MT_AUTOPICKUP, MT_AUTOMATICRING, pw_automaticring); + DROP_WEAPON(RW_EXPLODE, MT_EXPLODEPICKUP, MT_EXPLOSIONRING, pw_explosionring); + DROP_WEAPON(RW_SCATTER, MT_SCATTERPICKUP, MT_SCATTERRING, pw_scatterring); + DROP_WEAPON(RW_GRENADE, MT_GRENADEPICKUP, MT_GRENADERING, pw_grenadering); + DROP_WEAPON(0, 0, MT_INFINITYRING, pw_infinityring); + + #undef DROP_WEAPON + #undef SETUP_DROP +} + // // P_PlayerEmeraldBurst // diff --git a/src/p_local.h b/src/p_local.h index 1e0a9e2eb..337cc3663 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -371,6 +371,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget void P_PlayerRingBurst(player_t *player, INT32 num_rings); /// \todo better fit in p_user.c void P_PlayerWeaponPanelBurst(player_t *player); void P_PlayerWeaponAmmoBurst(player_t *player); +void P_PlayerWeaponPanelOrAmmoBurst(player_t *player); void P_PlayerEmeraldBurst(player_t *player, boolean toss); void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck);