mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2024-11-24 05:01:41 +00:00
- Finally implemented code to keep some or all of your inventory intact when
respawning in coop. Now the new inventory code should finally be complete. :-) - Fixed: PROP_Inventory_PickupMessage was improperly defined for non-VC++ compilation. SVN r197 (trunk)
This commit is contained in:
parent
1bd6ac028b
commit
c87e2252ed
16 changed files with 231 additions and 77 deletions
|
@ -1,3 +1,9 @@
|
|||
June 17, 2006
|
||||
- Finally implemented code to keep some or all of your inventory intact when
|
||||
respawning in coop. Now the new inventory code should finally be complete. :-)
|
||||
- Fixed: PROP_Inventory_PickupMessage was improperly defined for non-VC++
|
||||
compilation.
|
||||
|
||||
June 17, 2006 (Changes by Graf Zahl)
|
||||
- Converted a_doomhealth.cpp to DECORATE.
|
||||
- Added a PickupMessage property to the internal actor parser, replaced
|
||||
|
|
|
@ -545,6 +545,9 @@ public:
|
|||
// Tries to give the actor some ammo.
|
||||
bool GiveAmmo (const PClass *type, int amount);
|
||||
|
||||
// Destroys all the inventory the actor is holding.
|
||||
void DestroyAllInventory ();
|
||||
|
||||
// Set the alphacolor field properly
|
||||
void SetShade (DWORD rgb);
|
||||
void SetShade (int r, int g, int b);
|
||||
|
|
|
@ -72,6 +72,8 @@ public:
|
|||
virtual void ActivateMorphWeapon ();
|
||||
virtual AWeapon *PickNewWeapon (const PClass *ammotype);
|
||||
virtual AWeapon *BestWeapon (const PClass *ammotype);
|
||||
virtual void GiveDeathmatchInventory ();
|
||||
virtual void FilterCoopRespawnInventory (APlayerPawn *oldplayer);
|
||||
|
||||
enum EInvulState
|
||||
{
|
||||
|
|
|
@ -221,6 +221,13 @@ enum
|
|||
DF_NO_FOV = 1 << 19, // Only let the arbitrator set FOV (for all players)
|
||||
DF_NO_COOP_WEAPON_SPAWN = 1 << 20, // Don't spawn multiplayer weapons in coop games
|
||||
DF_NO_CROUCH = 1 << 21, // Don't allow crouching
|
||||
DF_COOP_LOSE_INVENTORY = 1 << 22, // Lose all your old inventory when respawning in coop
|
||||
DF_COOP_LOSE_KEYS = 1 << 23, // Lose keys when respawning in coop
|
||||
DF_COOP_LOSE_WEAPONS = 1 << 24, // Lose weapons when respawning in coop
|
||||
DF_COOP_LOSE_ARMOR = 1 << 25, // Lose armor when respawning in coop
|
||||
DF_COOP_LOSE_POWERUPS = 1 << 26, // Lose powerups when respawning in coop
|
||||
DF_COOP_LOSE_AMMO = 1 << 27, // Lose ammo when respawning in coop
|
||||
DF_COOP_HALVE_AMMO = 1 << 28, // Lose half your ammo when respawning in coop (but not less than the normal starting amount)
|
||||
};
|
||||
|
||||
// [BC] More dmflags. w00p!
|
||||
|
|
|
@ -1374,27 +1374,18 @@ void G_DoReborn (int playernum, bool freshbot)
|
|||
{
|
||||
// respawn at the start
|
||||
int i;
|
||||
AInventory *oldInv;
|
||||
|
||||
// first disassociate the corpse
|
||||
if (players[playernum].mo)
|
||||
{
|
||||
oldInv = players[playernum].mo->Inventory;
|
||||
players[playernum].mo->Inventory = NULL;
|
||||
G_QueueBody (players[playernum].mo);
|
||||
players[playernum].mo->player = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
oldInv = NULL;
|
||||
}
|
||||
|
||||
// spawn at random spot if in death match
|
||||
if (deathmatch)
|
||||
{
|
||||
G_DeathMatchSpawnPlayer (playernum);
|
||||
if (players[playernum].mo == NULL)
|
||||
i = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1434,40 +1425,6 @@ void G_DoReborn (int playernum, bool freshbot)
|
|||
}
|
||||
P_SpawnPlayer (&playerstarts[playernum]);
|
||||
}
|
||||
|
||||
// Cooperative net-play, retain keys, weapons, and some ammo,
|
||||
// but throw the other inventory items away.
|
||||
if (!freshbot)
|
||||
{
|
||||
AInventory *probe = oldInv;
|
||||
|
||||
while (probe != NULL)
|
||||
{
|
||||
AInventory *next = probe->Inventory;
|
||||
if (probe->IsKindOf (RUNTIME_CLASS(AWeapon)))
|
||||
{
|
||||
// Keep weapons
|
||||
}
|
||||
else if (probe->IsKindOf (RUNTIME_CLASS(AKey)))
|
||||
{
|
||||
// Keep keys
|
||||
}
|
||||
else if (probe->IsKindOf (RUNTIME_CLASS(AAmmo)))
|
||||
{
|
||||
// Take away some ammo
|
||||
if (probe->Amount > 0)
|
||||
{
|
||||
probe->Amount = MAX(1, probe->Amount / 2);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Eliminate it
|
||||
probe->Destroy ();
|
||||
}
|
||||
probe = next;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -273,6 +273,19 @@ AInventory *APowerup::CreateTossable ()
|
|||
return NULL;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// APowerup :: OwnerDied
|
||||
//
|
||||
// Powerups don't last beyond death.
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void APowerup::OwnerDied ()
|
||||
{
|
||||
Destroy ();
|
||||
}
|
||||
|
||||
// Invulnerability Powerup ---------------------------------------------------
|
||||
|
||||
IMPLEMENT_STATELESS_ACTOR (APowerInvulnerable, Any, -1, 0)
|
||||
|
|
|
@ -30,6 +30,7 @@ public:
|
|||
virtual AInventory *CreateCopy (AActor *other);
|
||||
virtual AInventory *CreateTossable ();
|
||||
virtual void Serialize (FArchive &arc);
|
||||
virtual void OwnerDied ();
|
||||
virtual PalEntry GetBlend ();
|
||||
virtual bool DrawPowerup (int x, int y);
|
||||
|
||||
|
|
|
@ -529,6 +529,18 @@ void AInventory::Travelled ()
|
|||
{
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// AInventory :: OwnerDied
|
||||
//
|
||||
// Items receive this message when their owners die.
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void AInventory::OwnerDied ()
|
||||
{
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// AInventory :: HandlePickup
|
||||
|
|
|
@ -146,6 +146,7 @@ public:
|
|||
virtual bool HandlePickup (AInventory *item);
|
||||
virtual bool Use (bool pickup);
|
||||
virtual void Travelled ();
|
||||
virtual void OwnerDied ();
|
||||
|
||||
virtual void AbsorbDamage (int damage, int damageType, int &newdamage);
|
||||
virtual void AlterWeaponSprite (vissprite_t *vis);
|
||||
|
|
|
@ -209,7 +209,7 @@ public:
|
|||
#define PROP_Inventory_Icon(x) ADD_STRING_PROP(ADEF_Inventory_Icon,"\20",x)
|
||||
#define PROP_Obituary(x) ADD_STRING_PROP(ADEF_Obituary,"\21",x)
|
||||
#define PROP_HitObituary(x) ADD_STRING_PROP(ADEF_HitObituary,"\22",x)
|
||||
#define PROP_Inventory_PickupMessage(x) ADD_STRING_PROP(ADEF_Obituary,"\23",x)
|
||||
#define PROP_Inventory_PickupMessage(x) ADD_STRING_PROP(ADEF_Inventory_PickupMsg,"\23",x)
|
||||
|
||||
#define PROP_XScale(x) ADD_BYTE_PROP(ADEF_XScale,x)
|
||||
#define PROP_YScale(x) ADD_BYTE_PROP(ADEF_YScale,x)
|
||||
|
|
|
@ -294,7 +294,7 @@ void cht_DoCheat (player_t *player, int cheat)
|
|||
player->mo->height = player->mo->GetDefault()->height;
|
||||
player->mo->SetState (player->mo->SpawnState);
|
||||
player->mo->Translation = TRANSLATION(TRANSLATION_Players, BYTE(player-players));
|
||||
player->mo->GiveDefaultInventory();
|
||||
// player->mo->GiveDefaultInventory();
|
||||
P_SetPsprite(player, ps_weapon, player->ReadyWeapon->UpState);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -931,7 +931,7 @@ static menuitem_t DMFlagsItems[] = {
|
|||
{ bitflag, "Allow exit (DM)", {&dmflags}, {1}, {0}, {0}, {(value_t *)DF_NO_EXIT} },
|
||||
{ bitflag, "Barrels respawn (DM)", {&dmflags2}, {0}, {0}, {0}, {(value_t *)DF2_BARRELS_RESPAWN} },
|
||||
{ bitflag, "Respawn protection (DM)",{&dmflags2}, {0}, {0}, {0}, {(value_t *)DF2_YES_INVUL} },
|
||||
{ bitflag, "Drop weapons", {&dmflags2}, {0}, {0}, {0}, {(value_t *)DF2_YES_WEAPONDROP} },
|
||||
{ bitflag, "Drop weapon", {&dmflags2}, {0}, {0}, {0}, {(value_t *)DF2_YES_WEAPONDROP} },
|
||||
{ bitflag, "Infinite ammo", {&dmflags}, {0}, {0}, {0}, {(value_t *)DF_INFINITE_AMMO} },
|
||||
{ bitflag, "No monsters", {&dmflags}, {0}, {0}, {0}, {(value_t *)DF_NO_MONSTERS} },
|
||||
{ bitflag, "Monsters respawn", {&dmflags}, {0}, {0}, {0}, {(value_t *)DF_MONSTERS_RESPAWN} },
|
||||
|
@ -943,7 +943,16 @@ static menuitem_t DMFlagsItems[] = {
|
|||
{ bitflag, "Allow freelook", {&dmflags}, {1}, {0}, {0}, {(value_t *)DF_NO_FREELOOK} },
|
||||
{ bitflag, "Allow FOV", {&dmflags}, {1}, {0}, {0}, {(value_t *)DF_NO_FOV} },
|
||||
{ bitflag, "Allow BFG aiming", {&dmflags2}, {1}, {0}, {0}, {(value_t *)DF2_NO_FREEAIMBFG} },
|
||||
{ bitflag, "Multi. weapons in coop", {&dmflags}, {1}, {0}, {0}, {(value_t *)DF_NO_COOP_WEAPON_SPAWN} },
|
||||
{ redtext, " ", {NULL}, {0}, {0}, {0}, {NULL} },
|
||||
{ whitetext,"Cooperative Settings", {NULL}, {0}, {0}, {0}, {NULL} },
|
||||
{ bitflag, "Spawn multi. weapons", {&dmflags},{1}, {0}, {0}, {(value_t *)DF_NO_COOP_WEAPON_SPAWN} },
|
||||
{ bitflag, "Lose entire inventory",{&dmflags}, {0}, {0}, {0}, {(value_t *)DF_COOP_LOSE_INVENTORY} },
|
||||
{ bitflag, "Keep keys", {&dmflags}, {1}, {0}, {0}, {(value_t *)DF_COOP_LOSE_KEYS} },
|
||||
{ bitflag, "Keep weapons", {&dmflags}, {1}, {0}, {0}, {(value_t *)DF_COOP_LOSE_WEAPONS} },
|
||||
{ bitflag, "Keep armor", {&dmflags}, {1}, {0}, {0}, {(value_t *)DF_COOP_LOSE_ARMOR} },
|
||||
{ bitflag, "Keep powerups", {&dmflags}, {1}, {0}, {0}, {(value_t *)DF_COOP_LOSE_POWERUPS} },
|
||||
{ bitflag, "Keep ammo", {&dmflags}, {1}, {0}, {0}, {(value_t *)DF_COOP_LOSE_AMMO} },
|
||||
{ bitflag, "Lose half ammo", {&dmflags}, {0}, {0}, {0}, {(value_t *)DF_COOP_HALVE_AMMO} },
|
||||
};
|
||||
|
||||
static menu_t DMFlagsMenu =
|
||||
|
|
|
@ -334,6 +334,14 @@ void AActor::Die (AActor *source, AActor *inflictor)
|
|||
this->player->cheats&CF_PREDICTING?"predicting":"real");
|
||||
}
|
||||
|
||||
// [RH] Notify this actor's items.
|
||||
for (AInventory *item = Inventory; item != NULL; )
|
||||
{
|
||||
AInventory *next = item->Inventory;
|
||||
item->OwnerDied();
|
||||
item = next;
|
||||
}
|
||||
|
||||
if (flags & MF_MISSILE)
|
||||
{ // [RH] When missiles die, they just explode
|
||||
P_ExplodeMissile (this, NULL);
|
||||
|
|
|
@ -677,6 +677,20 @@ void AActor::RemoveInventory (AInventory *item)
|
|||
}
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// AActor :: DestroyAllInventory
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
void AActor::DestroyAllInventory ()
|
||||
{
|
||||
while (Inventory != NULL)
|
||||
{
|
||||
Inventory->Destroy ();
|
||||
}
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// AActor :: FirstInv
|
||||
|
@ -3203,12 +3217,7 @@ void AActor::Deactivate (AActor *activator)
|
|||
void AActor::Destroy ()
|
||||
{
|
||||
// [RH] Destroy any inventory this actor is carrying
|
||||
while (Inventory != NULL)
|
||||
{
|
||||
AInventory *item = Inventory;
|
||||
Inventory = item->Inventory;
|
||||
item->Destroy ();
|
||||
}
|
||||
DestroyAllInventory ();
|
||||
|
||||
// [RH] Unlink from tid chain
|
||||
RemoveFromHash ();
|
||||
|
@ -3220,7 +3229,7 @@ void AActor::Destroy ()
|
|||
// Delete all nodes on the current sector_list phares 3/16/98
|
||||
P_DelSector_List();
|
||||
|
||||
// stop any playing sound
|
||||
// Transform any playing sound into positioned, non-actor sounds.
|
||||
S_RelinkSound (this, NULL);
|
||||
|
||||
Super::Destroy ();
|
||||
|
@ -3425,24 +3434,18 @@ void P_SpawnPlayer (mapthing2_t *mthing, bool startenterscripts)
|
|||
P_SetupPsprites (p);
|
||||
}
|
||||
|
||||
// give all cards in death match mode
|
||||
if (deathmatch)
|
||||
{
|
||||
for (unsigned int i = 0; i < PClass::m_Types.Size(); ++i)
|
||||
{
|
||||
if (PClass::m_Types[i]->IsDescendantOf (RUNTIME_CLASS(AKey)))
|
||||
{
|
||||
AKey *key = (AKey *)GetDefaultByType (PClass::m_Types[i]);
|
||||
if (key->KeyNumber != 0)
|
||||
{
|
||||
key = static_cast<AKey *>(Spawn (PClass::m_Types[i], 0,0,0));
|
||||
if (!key->TryPickup (p->mo))
|
||||
{
|
||||
key->Destroy ();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
{ // Give all cards in death match mode.
|
||||
p->mo->GiveDeathmatchInventory ();
|
||||
}
|
||||
else if (multiplayer && state == PST_REBORN && oldactor != NULL)
|
||||
{ // Special inventory handling for respawning in coop
|
||||
p->mo->FilterCoopRespawnInventory (oldactor);
|
||||
}
|
||||
if (oldactor != NULL)
|
||||
{ // Remove any inventory left from the old actor. Coop handles
|
||||
// it above, but the other modes don't.
|
||||
oldactor->DestroyAllInventory();
|
||||
}
|
||||
|
||||
if (StatusBar != NULL && (playernum == consoleplayer || StatusBar->GetPlayer() == playernum))
|
||||
|
|
142
src/p_user.cpp
142
src/p_user.cpp
|
@ -38,6 +38,7 @@
|
|||
#include "p_effect.h"
|
||||
#include "s_sound.h"
|
||||
#include "a_sharedglobal.h"
|
||||
#include "a_keys.h"
|
||||
#include "statnums.h"
|
||||
#include "v_palette.h"
|
||||
#include "v_video.h"
|
||||
|
@ -46,6 +47,7 @@
|
|||
#include "sbar.h"
|
||||
#include "f_finale.h"
|
||||
#include "c_console.h"
|
||||
#include "doomdef.h"
|
||||
|
||||
static FRandom pr_healradius ("HealRadius");
|
||||
|
||||
|
@ -456,6 +458,141 @@ AWeapon *APlayerPawn::PickNewWeapon (const PClass *ammotype)
|
|||
return best;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// APlayerPawn :: GiveDeathmatchInventory
|
||||
//
|
||||
// Gives players items they should have in addition to their default
|
||||
// inventory when playing deathmatch. (i.e. all keys)
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void APlayerPawn::GiveDeathmatchInventory()
|
||||
{
|
||||
for (unsigned int i = 0; i < PClass::m_Types.Size(); ++i)
|
||||
{
|
||||
if (PClass::m_Types[i]->IsDescendantOf (RUNTIME_CLASS(AKey)))
|
||||
{
|
||||
AKey *key = (AKey *)GetDefaultByType (PClass::m_Types[i]);
|
||||
if (key->KeyNumber != 0)
|
||||
{
|
||||
key = static_cast<AKey *>(Spawn (PClass::m_Types[i], 0,0,0));
|
||||
if (!key->TryPickup (this))
|
||||
{
|
||||
key->Destroy ();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// APlayerPawn :: FilterCoopRespawnInventory
|
||||
//
|
||||
// When respawning in coop, this function is called to walk through the dead
|
||||
// player's inventory and modify it according to the current game flags so
|
||||
// that it can be transferred to the new live player. This player currently
|
||||
// has the default inventory, and the oldplayer has the inventory at the time
|
||||
// of death.
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void APlayerPawn::FilterCoopRespawnInventory (APlayerPawn *oldplayer)
|
||||
{
|
||||
AInventory *item, *next, *defitem;
|
||||
|
||||
// If we're losing everything, this is really simple.
|
||||
if (dmflags & DF_COOP_LOSE_INVENTORY)
|
||||
{
|
||||
oldplayer->DestroyAllInventory();
|
||||
return;
|
||||
}
|
||||
|
||||
// If we don't want to lose anything, then we don't need to bother checking
|
||||
// the old inventory.
|
||||
if (dmflags & (DF_COOP_LOSE_KEYS |
|
||||
DF_COOP_LOSE_WEAPONS |
|
||||
DF_COOP_LOSE_AMMO |
|
||||
DF_COOP_HALVE_AMMO |
|
||||
DF_COOP_LOSE_ARMOR |
|
||||
DF_COOP_LOSE_POWERUPS))
|
||||
{
|
||||
// Walk through the old player's inventory and destroy or modify
|
||||
// according to dmflags.
|
||||
for (item = oldplayer->Inventory; item != NULL; item = next)
|
||||
{
|
||||
next = item->Inventory;
|
||||
|
||||
// If this item is part of the default inventory, we never want
|
||||
// to destroy it, although we might want to copy the default
|
||||
// inventory amount.
|
||||
defitem = FindInventory (item->GetClass());
|
||||
|
||||
if ((dmflags & DF_COOP_LOSE_KEYS) &&
|
||||
defitem == NULL &&
|
||||
item->IsKindOf(RUNTIME_CLASS(AKey)))
|
||||
{
|
||||
item->Destroy();
|
||||
}
|
||||
else if ((dmflags & DF_COOP_LOSE_WEAPONS) &&
|
||||
defitem == NULL &&
|
||||
item->IsKindOf(RUNTIME_CLASS(AWeapon)))
|
||||
{
|
||||
item->Destroy();
|
||||
}
|
||||
else if ((dmflags & DF_COOP_LOSE_ARMOR) &&
|
||||
defitem == NULL &&
|
||||
item->IsKindOf(RUNTIME_CLASS(AArmor)))
|
||||
{
|
||||
item->Destroy();
|
||||
}
|
||||
else if ((dmflags & DF_COOP_LOSE_POWERUPS) &&
|
||||
defitem == NULL &&
|
||||
item->IsKindOf(RUNTIME_CLASS(APowerupGiver)))
|
||||
{
|
||||
item->Destroy();
|
||||
}
|
||||
else if ((dmflags & (DF_COOP_LOSE_AMMO | DF_COOP_HALVE_AMMO)) &&
|
||||
item->IsKindOf(RUNTIME_CLASS(AAmmo)))
|
||||
{
|
||||
if (defitem == NULL)
|
||||
{
|
||||
if (dmflags & DF_COOP_LOSE_AMMO)
|
||||
{
|
||||
// Do NOT destroy the ammo, because a weapon might reference it.
|
||||
item->Amount = 0;
|
||||
}
|
||||
else if (item->Amount > 1)
|
||||
{
|
||||
item->Amount /= 2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// When set to lose ammo, you get to keep all your starting ammo.
|
||||
// When set to halve ammo, you won't be left with less than your starting amount.
|
||||
if (dmflags & DF_COOP_LOSE_AMMO)
|
||||
{
|
||||
item->Amount = defitem->Amount;
|
||||
}
|
||||
else if (item->Amount > 1)
|
||||
{
|
||||
item->Amount = MAX(item->Amount / 2, defitem->Amount);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Now destroy the default inventory this player is holding and move
|
||||
// over the old player's remaining inventory.
|
||||
DestroyAllInventory();
|
||||
ObtainInventory (oldplayer);
|
||||
|
||||
player->ReadyWeapon = NULL;
|
||||
PickNewWeapon (NULL);
|
||||
}
|
||||
|
||||
const char *APlayerPawn::GetSoundClass ()
|
||||
{
|
||||
|
@ -559,11 +696,6 @@ void APlayerPawn::Die (AActor *source, AActor *inflictor)
|
|||
}
|
||||
}
|
||||
}
|
||||
// Kill the player's inventory
|
||||
while (Inventory != NULL)
|
||||
{
|
||||
Inventory->Destroy ();
|
||||
}
|
||||
if (!multiplayer && (level.flags & LEVEL_DEATHSLIDESHOW))
|
||||
{
|
||||
F_StartSlideshow ();
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Generated by re2c 0.10.3 on Sat May 27 10:44:26 2006 */
|
||||
/* Generated by re2c 0.10.3 on Wed Jun 14 22:02:31 2006 */
|
||||
#line 1 "scanner.re"
|
||||
#include <string.h>
|
||||
#include <malloc.h>
|
||||
|
|
Loading…
Reference in a new issue