- scriptified G_PlayerFinishLevel.

Outside of SBARINFO this was the biggest remaining piece of code that referenced AInventory internals.
This commit is contained in:
Christoph Oelckers 2018-12-02 16:26:02 +01:00
commit ee08412e49
9 changed files with 168 additions and 128 deletions

View file

@ -1242,108 +1242,10 @@ void G_Ticker ()
void G_PlayerFinishLevel (int player, EFinishLevelType mode, int flags)
{
AInventory *item, *next;
player_t *p;
p = &players[player];
if (p->morphTics != 0)
{ // Undo morph
P_UnmorphActor(p->mo, p->mo, 0, true);
}
// Strip all current powers, unless moving in a hub and the power is okay to keep.
item = p->mo->Inventory;
auto ptype = PClass::FindActor(NAME_Powerup);
while (item != NULL)
IFVM(PlayerPawn, PlayerFinishLevel)
{
next = item->Inventory;
if (item->IsKindOf (ptype))
{
if (deathmatch || ((mode != FINISH_SameHub || !(item->ItemFlags & IF_HUBPOWER))
&& !(item->ItemFlags & IF_PERSISTENTPOWER))) // Keep persistent powers in non-deathmatch games
{
item->Destroy ();
}
}
item = next;
}
if (p->ReadyWeapon != NULL &&
p->ReadyWeapon->IntVar(NAME_WeaponFlags) & WIF_POWERED_UP &&
p->PendingWeapon == p->ReadyWeapon->PointerVar<AInventory>(NAME_SisterWeapon))
{
// Unselect powered up weapons if the unpowered counterpart is pending
p->ReadyWeapon=p->PendingWeapon;
}
// reset invisibility to default
if (p->mo->GetDefault()->flags & MF_SHADOW)
{
p->mo->flags |= MF_SHADOW;
}
else
{
p->mo->flags &= ~MF_SHADOW;
}
p->mo->RenderStyle = p->mo->GetDefault()->RenderStyle;
p->mo->Alpha = p->mo->GetDefault()->Alpha;
p->extralight = 0; // cancel gun flashes
p->fixedcolormap = NOFIXEDCOLORMAP; // cancel ir goggles
p->fixedlightlevel = -1;
p->damagecount = 0; // no palette changes
p->bonuscount = 0;
p->poisoncount = 0;
p->inventorytics = 0;
if (mode != FINISH_SameHub)
{
// Take away flight and keys (and anything else with IF_INTERHUBSTRIP set)
item = p->mo->Inventory;
while (item != NULL)
{
next = item->Inventory;
if (item->InterHubAmount < 1)
{
item->Destroy ();
}
item = next;
}
}
if (mode == FINISH_NoHub && !(level.flags2 & LEVEL2_KEEPFULLINVENTORY))
{ // Reduce all owned (visible) inventory to defined maximum interhub amount
TArray<AInventory*> todelete;
for (item = p->mo->Inventory; item != NULL; item = item->Inventory)
{
// If the player is carrying more samples of an item than allowed, reduce amount accordingly
if (item->ItemFlags & IF_INVBAR && item->Amount > item->InterHubAmount)
{
item->Amount = item->InterHubAmount;
if ((level.flags3 & LEVEL3_REMOVEITEMS) && !(item->ItemFlags & IF_UNDROPPABLE))
{
todelete.Push(item);
}
}
}
for (auto it : todelete)
{
if (!(it->ObjectFlags & OF_EuthanizeMe))
{
DepleteOrDestroy(item);
}
}
}
// Resets player health to default if not dead.
if ((flags & CHANGELEVEL_RESETHEALTH) && p->playerstate != PST_DEAD)
{
p->health = p->mo->health = p->mo->SpawnHealth();
}
// Clears the entire inventory and gives back the defaults for starting a game
if ((flags & CHANGELEVEL_RESETINVENTORY) && p->playerstate != PST_DEAD)
{
p->mo->ClearInventory();
p->mo->GiveDefaultInventory();
VMValue params[] = { players[player].mo, mode, flags };
VMCall(func, params, 3, nullptr, 0);
}
}

View file

@ -2254,6 +2254,8 @@ DEFINE_FIELD_BIT(FLevelLocals, flags2, nomonsters, LEVEL2_NOMONSTERS)
DEFINE_FIELD_BIT(FLevelLocals, flags2, frozen, LEVEL2_FROZEN)
DEFINE_FIELD_BIT(FLevelLocals, flags2, infinite_flight, LEVEL2_INFINITE_FLIGHT)
DEFINE_FIELD_BIT(FLevelLocals, flags2, no_dlg_freeze, LEVEL2_CONV_SINGLE_UNFREEZE)
DEFINE_FIELD_BIT(FLevelLocals, flags2, keepfullinventory, LEVEL2_KEEPFULLINVENTORY)
DEFINE_FIELD_BIT(FLevelLocals, flags3, removeitems, LEVEL3_REMOVEITEMS)
//==========================================================================
//

View file

@ -994,6 +994,7 @@ xx(SetMarineWeapon)
xx(SetMarineSprite)
xx(GiveInventory)
xx(TakeInventory)
xx(ClearInventory)
// Weapon member fields that need direct access
xx(Ammo1)

View file

@ -1723,30 +1723,6 @@ void P_WriteACSVars(FSerializer &arc)
//---- Inventory functions --------------------------------------//
//
//============================================================================
//
// ClearInventory
//
// Clears the inventory for one or more actors.
//
//============================================================================
static void ClearInventory (AActor *activator)
{
if (activator == NULL)
{
for (int i = 0; i < MAXPLAYERS; ++i)
{
if (playeringame[i])
players[i].mo->ClearInventory();
}
}
else
{
activator->ClearInventory();
}
}
//============================================================================
//
// DoUseInv
@ -9218,13 +9194,13 @@ scriptwait:
break;
case PCD_CLEARINVENTORY:
ClearInventory (activator);
ScriptUtil::Exec(NAME_ClearInventory, ScriptUtil::Pointer, activator, ScriptUtil::End);
break;
case PCD_CLEARACTORINVENTORY:
if (STACK(1) == 0)
{
ClearInventory(NULL);
ScriptUtil::Exec(NAME_ClearInventory, ScriptUtil::Pointer, nullptr, ScriptUtil::End);
}
else
{
@ -9232,7 +9208,7 @@ scriptwait:
AActor *actor;
for (actor = it.Next(); actor != NULL; actor = it.Next())
{
ClearInventory(actor);
ScriptUtil::Exec(NAME_ClearInventory, ScriptUtil::Pointer, actor , ScriptUtil::End);
}
}
sp--;