diff --git a/docs/rh-log.txt b/docs/rh-log.txt index fa97f0278..a2f1546cd 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -1,3 +1,6 @@ +April 8, 2008 (Changes by Graf Zahl) +- Added Martin Howe's morph system enhancement. + April 7, 2008 (Changes by Graf Zahl) - Removed PT_EARLYOUT from P_PathTraverse because it wasn't used anywhere. - Rewrote BlockThingsIterator code not to use callbacks anymore. diff --git a/src/d_player.h b/src/d_player.h index f38c10a7b..c57434214 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -204,7 +204,7 @@ public: userinfo_t userinfo; // [RH] who is this? - const PClass *cls; // class of associated PlayerPawn + const PClass *cls; // class of associated PlayerPawn float DesiredFOV; // desired field of vision float FOV; // current field of vision @@ -254,6 +254,8 @@ public: pspdef_t psprites[NUMPSPRITES]; // view sprites (gun, etc) int morphTics; // player is a chicken/pig if > 0 BYTE MorphedPlayerClass; // [MH] (for SBARINFO) class # for this player instance when morphed + int MorphStyle; // which effects to apply for this player instance when morphed + const PClass *MorphExitFlash; // flash to apply when demorphing (cache of value given to P_MorphPlayer) AWeapon *PremorphWeapon; // ready weapon before morphing int chickenPeck; // chicken peck countdown int jumpTics; // delay the next jump for a moment diff --git a/src/g_heretic/a_hereticartifacts.cpp b/src/g_heretic/a_hereticartifacts.cpp index c3e61d8ce..7afce176e 100644 --- a/src/g_heretic/a_hereticartifacts.cpp +++ b/src/g_heretic/a_hereticartifacts.cpp @@ -34,7 +34,7 @@ bool AArtiTomeOfPower::Use (bool pickup) { if (Owner->player->morphTics) { // Attempt to undo chicken - if (P_UndoPlayerMorph (Owner->player) == false) + if (!P_UndoPlayerMorph (Owner->player)) { // Failed P_DamageMobj (Owner, NULL, NULL, 1000000, NAME_Telefrag); } @@ -42,6 +42,8 @@ bool AArtiTomeOfPower::Use (bool pickup) { // Succeeded Owner->player->morphTics = 0; Owner->player->MorphedPlayerClass = 0; + Owner->player->MorphStyle = 0; + Owner->player->MorphExitFlash = NULL; S_Sound (Owner, CHAN_VOICE, "*evillaugh", 1, ATTN_IDLE); } return true; diff --git a/src/g_hexen/a_pig.cpp b/src/g_hexen/a_pig.cpp index 76f948a0d..3b0378e7e 100644 --- a/src/g_hexen/a_pig.cpp +++ b/src/g_hexen/a_pig.cpp @@ -163,7 +163,7 @@ AT_GAME_SET(PigPlayer) void APigPlayer::MorphPlayerThink () { - if (player->morphTics&15) + if (player->morphTics & 15) { return; } diff --git a/src/g_shared/a_artifacts.cpp b/src/g_shared/a_artifacts.cpp index dcb926d9d..3ca43c84f 100644 --- a/src/g_shared/a_artifacts.cpp +++ b/src/g_shared/a_artifacts.cpp @@ -16,6 +16,7 @@ #include "m_random.h" #include "v_video.h" #include "templates.h" +#include "a_morph.h" static FRandom pr_torch ("Torch"); @@ -287,10 +288,27 @@ bool APowerup::HandlePickup (AInventory *item) AInventory *APowerup::CreateCopy (AActor *other) { + // Get the effective effect time. EffectTics = abs (EffectTics); + // Abuse the Owner field to tell the + // InitEffect method who started it; + // this should be cleared afterwards, + // as this powerup instance is not + // properly attached to anything yet. Owner = other; + // Actually activate the powerup. InitEffect (); - Owner = NULL; + // Clear the Owner field, unless it was + // changed by the activation, for example, + // if this instance is a morph powerup; + // the flag tells the caller that the + // ownership has changed so that they + // can properly handle the situation. + if (!(ItemFlags & IF_CREATECOPYMOVED)) + { + Owner = NULL; + } + // All done. return this; } @@ -1704,3 +1722,73 @@ void APowerHighJump::EndEffect( ) } } +// Morph powerup ------------------------------------------------------ + +IMPLEMENT_STATELESS_ACTOR( APowerMorph, Any, -1, 0 ) + PROP_Powerup_EffectTics( MORPHTICS ) +END_DEFAULTS + +//=========================================================================== +// +// APowerMorph :: Serialize +// +//=========================================================================== + +void APowerMorph::Serialize (FArchive &arc) +{ + Super::Serialize (arc); + arc << PlayerClass << MorphStyle << MorphFlash << UnMorphFlash; + arc << player; +} + +//=========================================================================== +// +// APowerMorph :: InitEffect +// +//=========================================================================== + +void APowerMorph::InitEffect( ) +{ + if (Owner != NULL && Owner->player != NULL && PlayerClass != NAME_None) + { + player_t *realplayer = Owner->player; // Remember the identity of the player + const PClass *morph_flash = PClass::FindClass (MorphFlash); + const PClass *unmorph_flash = PClass::FindClass (UnMorphFlash); + const PClass *player_class = PClass::FindClass (PlayerClass); + if (P_MorphPlayer(realplayer, player_class, -1/*INDEFINITELY*/, MorphStyle, morph_flash, unmorph_flash)) + { + Owner = realplayer->mo; // Replace the new owner in our owner; safe because we are not attached to anything yet + ItemFlags |= IF_CREATECOPYMOVED; // Let the caller know the "real" owner has changed (to the morphed actor) + player = realplayer; // Store the player identity (morphing clears the unmorphed actor's "player" field) + } + } +} + +//=========================================================================== +// +// APowerMorph :: EndEffect +// +//=========================================================================== + +void APowerMorph::EndEffect( ) +{ + if (Owner != NULL && player != NULL) + { + int savedMorphTics = player->morphTics; + P_UndoPlayerMorph (player); + if (player->morphTics /*failed*/) + { + // Transfer retry timeout + // to the powerup's timer. + EffectTics = player->morphTics; + // Reload negative morph tics; + // use actual value; it may + // be in use for animation. + player->morphTics = savedMorphTics; + } + else // unmorph succeeded + { + player = NULL; + } + } +} diff --git a/src/g_shared/a_artifacts.h b/src/g_shared/a_artifacts.h index 404c08299..21df07952 100644 --- a/src/g_shared/a_artifacts.h +++ b/src/g_shared/a_artifacts.h @@ -254,9 +254,20 @@ protected: void EndEffect( ); }; +class APowerMorph : public APowerup +{ + DECLARE_STATELESS_ACTOR( APowerMorph, APowerup ) +public: + void Serialize (FArchive &arc); + FNameNoInit PlayerClass, MorphFlash, UnMorphFlash; + int MorphStyle; - -class player_s; +protected: + void InitEffect (); + void EndEffect (); + // Variables + player_s *player; +}; #endif //__A_ARTIFACTS_H__ diff --git a/src/g_shared/a_morph.cpp b/src/g_shared/a_morph.cpp index e0812c7c9..0197c79f6 100644 --- a/src/g_shared/a_morph.cpp +++ b/src/g_shared/a_morph.cpp @@ -9,8 +9,7 @@ #include "m_random.h" #include "a_sharedglobal.h" #include "sbar.h" - -#define MORPHTICS (40*TICRATE) +#include "a_morph.h" static FRandom pr_morphmonst ("MorphMonster"); @@ -22,7 +21,7 @@ static FRandom pr_morphmonst ("MorphMonster"); // //--------------------------------------------------------------------------- -bool P_MorphPlayer (player_t *p, const PClass *spawntype) +bool P_MorphPlayer (player_t *p, const PClass *spawntype, int duration, int style, const PClass *enter_flash, const PClass *exit_flash) { AInventory *item; APlayerPawn *morphed; @@ -77,12 +76,12 @@ bool P_MorphPlayer (player_t *p, const PClass *spawntype) morphed->flags |= actor->flags & (MF_SHADOW|MF_NOGRAVITY); morphed->flags2 |= actor->flags2 & MF2_FLY; morphed->flags3 |= actor->flags3 & MF3_GHOST; - Spawn (actor->x, actor->y, actor->z + TELEFOGHEIGHT, ALLOW_REPLACE); + Spawn(((enter_flash) ? enter_flash : RUNTIME_CLASS(ATeleportFog)), actor->x, actor->y, actor->z + TELEFOGHEIGHT, ALLOW_REPLACE); actor->player = NULL; actor->flags &= ~(MF_SOLID|MF_SHOOTABLE); actor->flags |= MF_UNMORPHED; actor->renderflags |= RF_INVISIBLE; - p->morphTics = MORPHTICS; + p->morphTics = (duration) ? duration : MORPHTICS; // [MH] Used by SBARINFO to speed up face drawing p->MorphedPlayerClass = 0; @@ -94,7 +93,9 @@ bool P_MorphPlayer (player_t *p, const PClass *spawntype) break; } } - + + p->MorphStyle = style; + p->MorphExitFlash = (exit_flash) ? exit_flash : RUNTIME_CLASS(ATeleportFog); p->health = morphed->health; p->mo = morphed; p->momx = p->momy = 0; @@ -198,8 +199,12 @@ bool P_UndoPlayerMorph (player_t *player, bool force) mo->flags2 = (mo->flags2 & ~MF2_FLY) | (pmo->flags2 & MF2_FLY); mo->flags3 = (mo->flags3 & ~MF3_GHOST) | (pmo->flags3 & MF3_GHOST); + const PClass *exit_flash = player->MorphExitFlash; + player->morphTics = 0; player->MorphedPlayerClass = 0; + player->MorphStyle = 0; + player->MorphExitFlash = NULL; player->viewheight = mo->ViewHeight; AInventory *level2 = mo->FindInventory (RUNTIME_CLASS(APowerWeaponLevel2)); if (level2 != NULL) @@ -246,8 +251,7 @@ bool P_UndoPlayerMorph (player_t *player, bool force) } angle = mo->angle >> ANGLETOFINESHIFT; - Spawn (pmo->x + 20*finecosine[angle], - pmo->y + 20*finesine[angle], pmo->z + TELEFOGHEIGHT, ALLOW_REPLACE); + Spawn(exit_flash, pmo->x + 20*finecosine[angle], pmo->y + 20*finesine[angle], pmo->z + TELEFOGHEIGHT, ALLOW_REPLACE); beastweap = player->ReadyWeapon; if (player->PremorphWeapon != NULL) { @@ -284,7 +288,7 @@ bool P_UndoPlayerMorph (player_t *player, bool force) // //--------------------------------------------------------------------------- -bool P_MorphMonster (AActor *actor, const PClass *spawntype) +bool P_MorphMonster (AActor *actor, const PClass *spawntype, int duration, int style, const PClass *enter_flash, const PClass *exit_flash) { AMorphedMonster *morphed; @@ -304,7 +308,9 @@ bool P_MorphMonster (AActor *actor, const PClass *spawntype) morphed->alpha = actor->alpha; morphed->RenderStyle = actor->RenderStyle; - morphed->UnmorphTime = level.time + MORPHTICS + pr_morphmonst(); + morphed->UnmorphTime = level.time + ((duration) ? duration : MORPHTICS) + pr_morphmonst(); + morphed->MorphStyle = style; + morphed->MorphExitFlash = (exit_flash) ? exit_flash : RUNTIME_CLASS(ATeleportFog); morphed->FlagsSave = actor->flags & ~MF_JUSTHIT; //morphed->special = actor->special; //memcpy (morphed->args, actor->args, sizeof(actor->args)); @@ -321,7 +327,7 @@ bool P_MorphMonster (AActor *actor, const PClass *spawntype) actor->flags &= ~(MF_SOLID|MF_SHOOTABLE); actor->flags |= MF_UNMORPHED; actor->renderflags |= RF_INVISIBLE; - Spawn (actor->x, actor->y, actor->z + TELEFOGHEIGHT, ALLOW_REPLACE); + Spawn(((enter_flash) ? enter_flash : RUNTIME_CLASS(ATeleportFog)), actor->x, actor->y, actor->z + TELEFOGHEIGHT, ALLOW_REPLACE); return true; } @@ -375,8 +381,9 @@ bool P_UpdateMorphedMonster (AMorphedMonster *beast) actor->AddToHash (); beast->UnmorphedMe = NULL; DObject::StaticPointerSubstitution (beast, actor); + const PClass *exit_flash = beast->MorphExitFlash; beast->Destroy (); - Spawn (beast->x, beast->y, beast->z + TELEFOGHEIGHT, ALLOW_REPLACE); + Spawn(exit_flash, beast->x, beast->y, beast->z + TELEFOGHEIGHT, ALLOW_REPLACE); return true; } @@ -390,13 +397,17 @@ END_DEFAULTS int AMorphProjectile::DoSpecialDamage (AActor *target, int damage) { + const PClass *morph_flash = PClass::FindClass (MorphFlash); + const PClass *unmorph_flash = PClass::FindClass (UnMorphFlash); if (target->player) { - P_MorphPlayer (target->player, PClass::FindClass (PlayerClass)); + const PClass *player_class = PClass::FindClass (PlayerClass); + P_MorphPlayer (target->player, player_class, Duration, MorphStyle, morph_flash, unmorph_flash); } else { - P_MorphMonster (target, PClass::FindClass (MonsterClass)); + const PClass *monster_class = PClass::FindClass (MonsterClass); + P_MorphMonster (target, monster_class, Duration, MorphStyle, morph_flash, unmorph_flash); } return -1; } @@ -404,7 +415,7 @@ int AMorphProjectile::DoSpecialDamage (AActor *target, int damage) void AMorphProjectile::Serialize (FArchive &arc) { Super::Serialize (arc); - arc << PlayerClass << MonsterClass; + arc << PlayerClass << MonsterClass << Duration << MorphStyle << MorphFlash << UnMorphFlash; } @@ -423,7 +434,7 @@ END_DEFAULTS void AMorphedMonster::Serialize (FArchive &arc) { Super::Serialize (arc); - arc << UnmorphedMe << UnmorphTime << FlagsSave; + arc << UnmorphedMe << UnmorphTime << MorphStyle << MorphExitFlash << FlagsSave; } void AMorphedMonster::Destroy () diff --git a/src/g_shared/a_morph.h b/src/g_shared/a_morph.h new file mode 100644 index 000000000..891e71f8f --- /dev/null +++ b/src/g_shared/a_morph.h @@ -0,0 +1,36 @@ +#ifndef __A_MORPH__ +#define __A_MORPH__ + +#define MORPHTICS (40*TICRATE) +#define MAXMORPHHEALTH 30 + +// Morph style states how morphing affects health and +// other effects in the game; only valid for players. +// Default should be the old Heretic/HeXen behaviour, +// so the (int) value of MORPH_RAVEN *must* be zero. +enum +{ + MORPH_OLDEFFECTS = 0, // Default to old Heretic/HeXen behaviour unless flags given + MORPH_ADDSTAMINA = 1, // Power instead of curse (add stamina instead of limiting to health) + MORPH_FULLHEALTH = 2, // New health semantics (!POWER => MaxHealth of animal, POWER => Normal health behaviour) + MORPH_UNDOBYTOMEOFPOWER = 4, + MORPH_UNDOBYCHAOSDEVICE = 8, +}; + +class PClass; +class AActor; +class player_s; + +// +// A_MORPH +// +bool P_MorphPlayer (player_s *player, const PClass *morphclass, int duration = 0, int style = 0, + const PClass *enter_flash = NULL, const PClass *exit_flash = NULL); +bool P_UndoPlayerMorph (player_s *player, bool force = false); +bool P_MorphMonster (AActor *actor, const PClass *morphclass, int duration = 0, int style = 0, + const PClass *enter_flash = NULL, const PClass *exit_flash = NULL); +bool P_UpdateMorphedMonster (AActor *actor); + + + +#endif //__A_MORPH__ diff --git a/src/g_shared/a_pickups.cpp b/src/g_shared/a_pickups.cpp index 1e858c606..9412358b5 100644 --- a/src/g_shared/a_pickups.cpp +++ b/src/g_shared/a_pickups.cpp @@ -13,6 +13,7 @@ #include "gstrings.h" #include "templates.h" #include "a_strifeglobal.h" +#include "a_morph.h" static FRandom pr_restore ("RestorePos"); @@ -193,10 +194,25 @@ bool P_GiveBody (AActor *actor, int num) if (player != NULL) { max = static_cast(actor)->GetMaxHealth() + player->stamina; - if (player->morphTics) - { - max = MAXMORPHHEALTH; - } + // [MH] First step in predictable generic morph effects + if (player->morphTics) + { + if (player->MorphStyle & MORPH_FULLHEALTH) + { + if (!(player->MorphStyle & MORPH_ADDSTAMINA)) + { + max -= player->stamina; + } + } + else // old health behaviour + { + max = MAXMORPHHEALTH; + if (player->MorphStyle & MORPH_ADDSTAMINA) + { + max += player->stamina; + } + } + } // [RH] For Strife: A negative body sets you up with a percentage // of your full health. if (num < 0) @@ -1163,6 +1179,8 @@ void AInventory::GiveQuest (AActor *toucher) bool AInventory::TryPickup (AActor *toucher) { + AActor *newtoucher = toucher; // in case changed by the powerup + // If HandlePickup() returns true, it will set the IF_PICKUPGOOD flag // to indicate that this item has been picked up. If the item cannot be // picked up, then it leaves the flag cleared. @@ -1209,7 +1227,15 @@ bool AInventory::TryPickup (AActor *toucher) { return false; } - copy->AttachToOwner (toucher); + // Handle owner-changing powerups + if (copy->ItemFlags & IF_CREATECOPYMOVED) + { + newtoucher = copy->Owner; + copy->Owner = NULL; + copy->ItemFlags &= ~IF_CREATECOPYMOVED; + } + // Continue onwards with the rest + copy->AttachToOwner (newtoucher); if (ItemFlags & IF_AUTOACTIVATE) { if (copy->Use (true)) @@ -1223,7 +1249,7 @@ bool AInventory::TryPickup (AActor *toucher) } } - GiveQuest(toucher); + GiveQuest(newtoucher); return true; } @@ -1380,9 +1406,24 @@ bool AHealth::TryPickup (AActor *other) if (max == 0) { max = static_cast(other)->GetMaxHealth() + player->stamina; - if (player->morphTics) - { - max = MAXMORPHHEALTH; + // [MH] First step in predictable generic morph effects + if (player->morphTics) + { + if (player->MorphStyle & MORPH_FULLHEALTH) + { + if (!(player->MorphStyle & MORPH_ADDSTAMINA)) + { + max -= player->stamina; + } + } + else // old health behaviour + { + max = MAXMORPHHEALTH; + if (player->MorphStyle & MORPH_ADDSTAMINA) + { + max += player->stamina; + } + } } } if (player->health >= max) diff --git a/src/g_shared/a_pickups.h b/src/g_shared/a_pickups.h index ad0e3a652..e4d3b4928 100644 --- a/src/g_shared/a_pickups.h +++ b/src/g_shared/a_pickups.h @@ -96,6 +96,7 @@ enum IF_BIGPOWERUP = 1<<12, // Affected by RESPAWN_SUPER dmflag IF_KEEPDEPLETED = 1<<13, // Items with this flag are retained even when they run out. IF_IGNORESKILL = 1<<14, // Ignores any skill related multiplicators when giving this item. + IF_CREATECOPYMOVED = 1<<15 // CreateCopy changed the owner (copy's Owner field holds new owner). }; struct vissprite_t; @@ -210,7 +211,7 @@ public: int Kickback; fixed_t YAdjust; // For viewing the weapon fullscreen WORD UpSound, ReadySound; // Sounds when coming up and idle - const PClass *SisterWeaponType; // Another weapon to pick up with this one + const PClass *SisterWeaponType; // Another weapon to pick up with this one const PClass *ProjectileType; // Projectile used by primary attack const PClass *AltProjectileType; // Projectile used by alternate attack int SelectionOrder; // Lower-numbered weapons get picked first diff --git a/src/g_shared/a_sharedglobal.h b/src/g_shared/a_sharedglobal.h index ad662d037..a2d0884a2 100644 --- a/src/g_shared/a_sharedglobal.h +++ b/src/g_shared/a_sharedglobal.h @@ -11,14 +11,6 @@ struct side_t; extern void P_SpawnDirt (AActor *actor, fixed_t radius); -bool P_MorphPlayer (player_s *player); -bool P_UndoPlayerMorph (player_s *player, bool force); - -bool P_MorphMonster (AActor *actor, const PClass *morphClass); -bool P_UpdateMorphedMonster (AActor *actor); - - - class DBaseDecal : public DThinker { DECLARE_CLASS (DBaseDecal, DThinker) @@ -182,7 +174,8 @@ public: int DoSpecialDamage (AActor *target, int damage); void Serialize (FArchive &arc); - FNameNoInit PlayerClass, MonsterClass; + FNameNoInit PlayerClass, MonsterClass, MorphFlash, UnMorphFlash; + int Duration, MorphStyle; }; class AMorphedMonster : public AActor @@ -196,7 +189,8 @@ public: void Destroy (); TObjPtr UnmorphedMe; - int UnmorphTime; + int UnmorphTime, MorphStyle; + const PClass *MorphExitFlash; DWORD FlagsSave; }; diff --git a/src/p_local.h b/src/p_local.h index 5df3b61a5..22d7bda8f 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -27,12 +27,12 @@ #include "r_local.h" #endif +#include "a_morph.h" + #include #define STEEPSLOPE 46341 // [RH] Minimum floorplane.c value for walking -#define MAXMORPHHEALTH 30 - #define BONUSADD 6 // mapblocks are used to check movement @@ -61,7 +61,6 @@ #define BASETHRESHOLD 100 - // // P_PSPR // @@ -75,7 +74,6 @@ void P_DropWeapon (player_t* player); // void P_FallingDamage (AActor *ent); void P_PlayerThink (player_t *player); -bool P_UndoPlayerMorph (player_t *player, bool force=false); void P_PredictPlayer (player_t *player); void P_UnPredictPlayer (); @@ -430,11 +428,8 @@ extern FBlockNode** blocklinks; // for thing chains // P_INTER // void P_TouchSpecialThing (AActor *special, AActor *toucher); - void P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage, FName mod, int flags=0); - bool P_GiveBody (AActor *actor, int num); -bool P_MorphPlayer (player_t *player, const PClass *morphClass); void P_PoisonPlayer (player_t *player, AActor *poisoner, AActor *source, int poison); void P_PoisonDamage (player_t *player, AActor *source, int damage, bool playPainSound); diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 8bff17d99..493662c60 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -3643,6 +3643,8 @@ APlayerPawn *P_SpawnPlayer (mapthing2_t *mthing, bool tempplayer) p->bonuscount = 0; p->morphTics = 0; p->MorphedPlayerClass = 0; + p->MorphStyle = 0; + p->MorphExitFlash = NULL; p->extralight = 0; p->fixedcolormap = 0; p->viewheight = mobj->ViewHeight; diff --git a/src/p_user.cpp b/src/p_user.cpp index d7d218819..09aef7d9e 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -243,6 +243,8 @@ player_s::player_s() extralight(0), morphTics(0), MorphedPlayerClass(0), + MorphStyle(0), + MorphExitFlash(0), PremorphWeapon(0), chickenPeck(0), jumpTics(0), @@ -2417,6 +2419,8 @@ void player_s::Serialize (FArchive &arc) << fixedcolormap << morphTics << MorphedPlayerClass + << MorphStyle + << MorphExitFlash << PremorphWeapon << chickenPeck << jumpTics diff --git a/src/thingdef/thingdef_properties.cpp b/src/thingdef/thingdef_properties.cpp index ec878e8eb..123d90f10 100644 --- a/src/thingdef/thingdef_properties.cpp +++ b/src/thingdef/thingdef_properties.cpp @@ -69,6 +69,7 @@ #include "thingdef.h" #include "a_sharedglobal.h" #include "r_translate.h" +#include "a_morph.h" //========================================================================== // @@ -744,6 +745,39 @@ static bool CheckFloatParm(FScanner &sc) } } +// [MH] +static int ParseMorphStyle (FScanner &sc) +{ + static const char * morphstyles[]={ + "MRF_ADDSTAMINA", "MRF_FULLHEALTH", NULL}; + + static const int morphstyle_values[]={ + MORPH_ADDSTAMINA, MORPH_FULLHEALTH}; + + // May be given flags by number... + if (sc.CheckNumber()) + { + sc.MustGetNumber(); + return sc.Number; + } + + // ... else should be flags by name. + bool gotparen = sc.CheckString("("); + int style = 0; + do + { + sc.MustGetString(); + style |= morphstyle_values[sc.MustMatchString(morphstyles)]; + } + while (sc.CheckString("|")); + if (gotparen) + { + sc.MustGetStringName(")"); + } + + return style; +} + //========================================================================== // // Property parsers @@ -2448,6 +2482,15 @@ static void PlayerHexenArmor (FScanner &sc, APlayerPawn *defaults, Baggage &bag) } } +//========================================================================== +// +//========================================================================== +static void EggFXPlayerClass (FScanner &sc, AMorphProjectile *defaults, Baggage &bag) +{ + sc.MustGetString (); + defaults->PlayerClass = FName(sc.String); +} + //========================================================================== // //========================================================================== @@ -2460,12 +2503,73 @@ static void EggFXMonsterClass (FScanner &sc, AMorphProjectile *defaults, Baggage //========================================================================== // //========================================================================== -static void EggFXPlayerClass (FScanner &sc, AMorphProjectile *defaults, Baggage &bag) +static void EggFXDuration (FScanner &sc, AMorphProjectile *defaults, Baggage &bag) +{ + sc.MustGetNumber (); + defaults->Duration = sc.Number; +} + +//========================================================================== +// +//========================================================================== +static void EggFXMorphStyle (FScanner &sc, AMorphProjectile *defaults, Baggage &bag) +{ + defaults->MorphStyle = ParseMorphStyle(sc); +} + +//========================================================================== +// +//========================================================================== +static void EggFXMorphFlash (FScanner &sc, AMorphProjectile *defaults, Baggage &bag) +{ + sc.MustGetString (); + defaults->MorphFlash = FName(sc.String); +} + +//========================================================================== +// +//========================================================================== +static void EggFXUnMorphFlash (FScanner &sc, AMorphProjectile *defaults, Baggage &bag) +{ + sc.MustGetString (); + defaults->UnMorphFlash = FName(sc.String); +} + +//========================================================================== +// +//========================================================================== +static void PowerMorphPlayerClass (FScanner &sc, APowerMorph *defaults, Baggage &bag) { sc.MustGetString (); defaults->PlayerClass = FName(sc.String); } +//========================================================================== +// +//========================================================================== +static void PowerMorphMorphStyle (FScanner &sc, APowerMorph *defaults, Baggage &bag) +{ + defaults->MorphStyle = ParseMorphStyle(sc); +} + +//========================================================================== +// +//========================================================================== +static void PowerMorphMorphFlash (FScanner &sc, APowerMorph *defaults, Baggage &bag) +{ + sc.MustGetString (); + defaults->UnMorphFlash = FName(sc.String); +} + +//========================================================================== +// +//========================================================================== +static void PowerMorphUnMorphFlash (FScanner &sc, APowerMorph *defaults, Baggage &bag) +{ + sc.MustGetString (); + defaults->UnMorphFlash = FName(sc.String); +} + //========================================================================== // //========================================================================== @@ -2501,150 +2605,158 @@ static const ActorProps *APropSearch (const char *str, const ActorProps *props, #define apf ActorPropFunction static const ActorProps props[] = { - { "activesound", ActorActiveSound, RUNTIME_CLASS(AActor) }, - { "alpha", ActorAlpha, RUNTIME_CLASS(AActor) }, - { "ammo.backpackamount", (apf)AmmoBackpackAmount, RUNTIME_CLASS(AAmmo) }, - { "ammo.backpackmaxamount", (apf)AmmoBackpackMaxAmount, RUNTIME_CLASS(AAmmo) }, - { "ammo.dropamount", (apf)AmmoDropAmount, RUNTIME_CLASS(AAmmo) }, - { "args", ActorArgs, RUNTIME_CLASS(AActor) }, - { "armor.maxbonus", (apf)ArmorMaxBonus, RUNTIME_CLASS(ABasicArmorBonus) }, - { "armor.maxbonusmax", (apf)ArmorMaxBonusMax, RUNTIME_CLASS(ABasicArmorBonus) }, - { "armor.maxsaveamount", (apf)ArmorMaxSaveAmount, RUNTIME_CLASS(ABasicArmorBonus) }, - { "armor.saveamount", (apf)ArmorSaveAmount, RUNTIME_CLASS(AActor) }, - { "armor.savepercent", (apf)ArmorSavePercent, RUNTIME_CLASS(AActor) }, - { "attacksound", ActorAttackSound, RUNTIME_CLASS(AActor) }, - { "bloodcolor", ActorBloodColor, RUNTIME_CLASS(AActor) }, - { "bloodtype", ActorBloodType, RUNTIME_CLASS(AActor) }, - { "bouncecount", ActorBounceCount, RUNTIME_CLASS(AActor) }, - { "bouncefactor", ActorBounceFactor, RUNTIME_CLASS(AActor) }, - { "burn", ActorBurnState, RUNTIME_CLASS(AActor) }, - { "burnheight", ActorBurnHeight, RUNTIME_CLASS(AActor) }, - { "cameraheight", ActorCameraheight, RUNTIME_CLASS(AActor) }, - { "clearflags", ActorClearFlags, RUNTIME_CLASS(AActor) }, - { "conversationid", ActorConversationID, RUNTIME_CLASS(AActor) }, - { "crash", ActorCrashState, RUNTIME_CLASS(AActor) }, - { "crush", ActorCrushState, RUNTIME_CLASS(AActor) }, - { "damage", ActorDamage, RUNTIME_CLASS(AActor) }, - { "damagefactor", ActorDamageFactor, RUNTIME_CLASS(AActor) }, - { "damagetype", ActorDamageType, RUNTIME_CLASS(AActor) }, - { "death", ActorDeathState, RUNTIME_CLASS(AActor) }, - { "deathheight", ActorDeathHeight, RUNTIME_CLASS(AActor) }, - { "deathsound", ActorDeathSound, RUNTIME_CLASS(AActor) }, - { "decal", ActorDecal, RUNTIME_CLASS(AActor) }, - { "disintegrate", ActorDisintegrateState, RUNTIME_CLASS(AActor) }, - { "donthurtshooter", ActorDontHurtShooter, RUNTIME_CLASS(AActor) }, - { "dropitem", ActorDropItem, RUNTIME_CLASS(AActor) }, - { "explosiondamage", ActorExplosionDamage, RUNTIME_CLASS(AActor) }, - { "explosionradius", ActorExplosionRadius, RUNTIME_CLASS(AActor) }, - { "fastspeed", ActorFastSpeed, RUNTIME_CLASS(AActor) }, - { "floatspeed", ActorFloatSpeed, RUNTIME_CLASS(AActor) }, - { "game", ActorGame, RUNTIME_CLASS(AActor) }, - { "gibhealth", ActorGibHealth, RUNTIME_CLASS(AActor) }, - { "gravity", ActorGravity, RUNTIME_CLASS(AActor) }, - { "heal", ActorHealState, RUNTIME_CLASS(AActor) }, - { "health", ActorHealth, RUNTIME_CLASS(AActor) }, - { "health.lowmessage", (apf)HealthLowMessage, RUNTIME_CLASS(AHealth) }, - { "height", ActorHeight, RUNTIME_CLASS(AActor) }, - { "hitobituary", ActorHitObituary, RUNTIME_CLASS(AActor) }, - { "howlsound", ActorHowlSound, RUNTIME_CLASS(AActor) }, - { "ice", ActorIceState, RUNTIME_CLASS(AActor) }, - { "inventory.amount", (apf)InventoryAmount, RUNTIME_CLASS(AInventory) }, - { "inventory.defmaxamount", (apf)InventoryDefMaxAmount, RUNTIME_CLASS(AInventory) }, - { "inventory.givequest", (apf)InventoryGiveQuest, RUNTIME_CLASS(AInventory) }, - { "inventory.icon", (apf)InventoryIcon, RUNTIME_CLASS(AInventory) }, - { "inventory.maxamount", (apf)InventoryMaxAmount, RUNTIME_CLASS(AInventory) }, - { "inventory.pickupflash", (apf)InventoryPickupflash, RUNTIME_CLASS(AInventory) }, - { "inventory.pickupmessage", (apf)InventoryPickupmsg, RUNTIME_CLASS(AInventory) }, - { "inventory.pickupsound", (apf)InventoryPickupsound, RUNTIME_CLASS(AInventory) }, - { "inventory.respawntics", (apf)InventoryRespawntics, RUNTIME_CLASS(AInventory) }, - { "inventory.usesound", (apf)InventoryUsesound, RUNTIME_CLASS(AInventory) }, - { "mass", ActorMass, RUNTIME_CLASS(AActor) }, - { "maxdropoffheight", ActorMaxDropoffHeight, RUNTIME_CLASS(AActor) }, - { "maxstepheight", ActorMaxStepHeight, RUNTIME_CLASS(AActor) }, - { "maxtargetrange", ActorMaxTargetRange, RUNTIME_CLASS(AActor) }, - { "melee", ActorMeleeState, RUNTIME_CLASS(AActor) }, - { "meleedamage", ActorMeleeDamage, RUNTIME_CLASS(AActor) }, - { "meleerange", ActorMeleeRange, RUNTIME_CLASS(AActor) }, - { "meleesound", ActorMeleeSound, RUNTIME_CLASS(AActor) }, - { "meleethreshold", ActorMeleeThreshold, RUNTIME_CLASS(AActor) }, - { "minmissilechance", ActorMinMissileChance, RUNTIME_CLASS(AActor) }, - { "missile", ActorMissileState, RUNTIME_CLASS(AActor) }, - { "missileheight", ActorMissileHeight, RUNTIME_CLASS(AActor) }, - { "missiletype", ActorMissileType, RUNTIME_CLASS(AActor) }, - { "monster", ActorMonster, RUNTIME_CLASS(AActor) }, - { "morphprojectile.monsterclass",(apf)EggFXMonsterClass, RUNTIME_CLASS(AMorphProjectile) }, - { "morphprojectile.playerclass",(apf)EggFXPlayerClass, RUNTIME_CLASS(AMorphProjectile) }, - { "obituary", ActorObituary, RUNTIME_CLASS(AActor) }, - { "pain", ActorPainState, RUNTIME_CLASS(AActor) }, - { "painchance", ActorPainChance, RUNTIME_CLASS(AActor) }, - { "painsound", ActorPainSound, RUNTIME_CLASS(AActor) }, - { "player.attackzoffset", (apf)PlayerAttackZOffset, RUNTIME_CLASS(APlayerPawn) }, - { "player.colorrange", (apf)PlayerColorRange, RUNTIME_CLASS(APlayerPawn) }, - { "player.crouchsprite", (apf)PlayerCrouchSprite, RUNTIME_CLASS(APlayerPawn) }, - { "player.damagescreencolor", (apf)PlayerDmgScreenColor, RUNTIME_CLASS(APlayerPawn) }, - { "player.displayname", (apf)PlayerDisplayName, RUNTIME_CLASS(APlayerPawn) }, - { "player.face", (apf)PlayerFace, RUNTIME_CLASS(APlayerPawn) }, - { "player.forwardmove", (apf)PlayerForwardMove, RUNTIME_CLASS(APlayerPawn) }, - { "player.healradiustype", (apf)PlayerHealRadius, RUNTIME_CLASS(APlayerPawn) }, - { "player.hexenarmor", (apf)PlayerHexenArmor, RUNTIME_CLASS(APlayerPawn) }, - { "player.invulnerabilitymode", (apf)PlayerInvulMode, RUNTIME_CLASS(APlayerPawn) }, - { "player.jumpz", (apf)PlayerJumpZ, RUNTIME_CLASS(APlayerPawn) }, - { "player.maxhealth", (apf)PlayerMaxHealth, RUNTIME_CLASS(APlayerPawn) }, - { "player.morphweapon", (apf)PlayerMorphWeapon, RUNTIME_CLASS(APlayerPawn) }, - { "player.runhealth", (apf)PlayerRunHealth, RUNTIME_CLASS(APlayerPawn) }, - { "player.scoreicon", (apf)PlayerScoreIcon, RUNTIME_CLASS(APlayerPawn) }, - { "player.sidemove", (apf)PlayerSideMove, RUNTIME_CLASS(APlayerPawn) }, - { "player.soundclass", (apf)PlayerSoundClass, RUNTIME_CLASS(APlayerPawn) }, - { "player.spawnclass", (apf)PlayerSpawnClass, RUNTIME_CLASS(APlayerPawn) }, - { "player.startitem", (apf)PlayerStartItem, RUNTIME_CLASS(APlayerPawn) }, - { "player.viewheight", (apf)PlayerViewHeight, RUNTIME_CLASS(APlayerPawn) }, - { "poisondamage", ActorPoisonDamage, RUNTIME_CLASS(AActor) }, - { "powerup.color", (apf)PowerupColor, RUNTIME_CLASS(APowerupGiver) }, - { "powerup.duration", (apf)PowerupDuration, RUNTIME_CLASS(APowerupGiver) }, - { "powerup.mode", (apf)PowerupMode, RUNTIME_CLASS(APowerupGiver) }, - { "powerup.type", (apf)PowerupType, RUNTIME_CLASS(APowerupGiver) }, - { "projectile", ActorProjectile, RUNTIME_CLASS(AActor) }, - { "puzzleitem.failmessage", (apf)PuzzleitemFailMsg, RUNTIME_CLASS(APuzzleItem) }, - { "puzzleitem.number", (apf)PuzzleitemNumber, RUNTIME_CLASS(APuzzleItem) }, - { "radius", ActorRadius, RUNTIME_CLASS(AActor) }, - { "radiusdamagefactor", ActorRadiusDamageFactor, RUNTIME_CLASS(AActor) }, - { "raise", ActorRaiseState, RUNTIME_CLASS(AActor) }, - { "reactiontime", ActorReactionTime, RUNTIME_CLASS(AActor) }, - { "renderstyle", ActorRenderStyle, RUNTIME_CLASS(AActor) }, - { "scale", ActorScale, RUNTIME_CLASS(AActor) }, - { "see", ActorSeeState, RUNTIME_CLASS(AActor) }, - { "seesound", ActorSeeSound, RUNTIME_CLASS(AActor) }, - { "skip_super", ActorSkipSuper, RUNTIME_CLASS(AActor) }, - { "spawn", ActorSpawnState, RUNTIME_CLASS(AActor) }, - { "spawnid", ActorSpawnID, RUNTIME_CLASS(AActor) }, - { "speed", ActorSpeed, RUNTIME_CLASS(AActor) }, - { "states", ActorStates, RUNTIME_CLASS(AActor) }, - { "stencilcolor", ActorStencilColor, RUNTIME_CLASS(AActor) }, - { "tag", ActorTag, RUNTIME_CLASS(AActor) }, - { "translation", ActorTranslation, RUNTIME_CLASS(AActor) }, - { "vspeed", ActorVSpeed, RUNTIME_CLASS(AActor) }, - { "weapon.ammogive", (apf)WeaponAmmoGive1, RUNTIME_CLASS(AWeapon) }, - { "weapon.ammogive1", (apf)WeaponAmmoGive1, RUNTIME_CLASS(AWeapon) }, - { "weapon.ammogive2", (apf)WeaponAmmoGive2, RUNTIME_CLASS(AWeapon) }, - { "weapon.ammotype", (apf)WeaponAmmoType1, RUNTIME_CLASS(AWeapon) }, - { "weapon.ammotype1", (apf)WeaponAmmoType1, RUNTIME_CLASS(AWeapon) }, - { "weapon.ammotype2", (apf)WeaponAmmoType2, RUNTIME_CLASS(AWeapon) }, - { "weapon.ammouse", (apf)WeaponAmmoUse1, RUNTIME_CLASS(AWeapon) }, - { "weapon.ammouse1", (apf)WeaponAmmoUse1, RUNTIME_CLASS(AWeapon) }, - { "weapon.ammouse2", (apf)WeaponAmmoUse2, RUNTIME_CLASS(AWeapon) }, - { "weapon.kickback", (apf)WeaponKickback, RUNTIME_CLASS(AWeapon) }, - { "weapon.readysound", (apf)WeaponReadySound, RUNTIME_CLASS(AWeapon) }, - { "weapon.selectionorder", (apf)WeaponSelectionOrder, RUNTIME_CLASS(AWeapon) }, - { "weapon.sisterweapon", (apf)WeaponSisterWeapon, RUNTIME_CLASS(AWeapon) }, - { "weapon.upsound", (apf)WeaponUpSound, RUNTIME_CLASS(AWeapon) }, - { "weapon.yadjust", (apf)WeaponYAdjust, RUNTIME_CLASS(AWeapon) }, - { "weaponpiece.number", (apf)WPieceValue, RUNTIME_CLASS(AWeaponPiece) }, - { "weaponpiece.weapon", (apf)WPieceWeapon, RUNTIME_CLASS(AWeaponPiece) }, - { "wound", ActorWoundState, RUNTIME_CLASS(AActor) }, - { "woundhealth", ActorWoundHealth, RUNTIME_CLASS(AActor) }, - { "xdeath", ActorXDeathState, RUNTIME_CLASS(AActor) }, - { "xscale", ActorXScale, RUNTIME_CLASS(AActor) }, - { "yscale", ActorYScale, RUNTIME_CLASS(AActor) }, + { "activesound", ActorActiveSound, RUNTIME_CLASS(AActor) }, + { "alpha", ActorAlpha, RUNTIME_CLASS(AActor) }, + { "ammo.backpackamount", (apf)AmmoBackpackAmount, RUNTIME_CLASS(AAmmo) }, + { "ammo.backpackmaxamount", (apf)AmmoBackpackMaxAmount, RUNTIME_CLASS(AAmmo) }, + { "ammo.dropamount", (apf)AmmoDropAmount, RUNTIME_CLASS(AAmmo) }, + { "args", ActorArgs, RUNTIME_CLASS(AActor) }, + { "armor.maxbonus", (apf)ArmorMaxBonus, RUNTIME_CLASS(ABasicArmorBonus) }, + { "armor.maxbonusmax", (apf)ArmorMaxBonusMax, RUNTIME_CLASS(ABasicArmorBonus) }, + { "armor.maxsaveamount", (apf)ArmorMaxSaveAmount, RUNTIME_CLASS(ABasicArmorBonus) }, + { "armor.saveamount", (apf)ArmorSaveAmount, RUNTIME_CLASS(AActor) }, + { "armor.savepercent", (apf)ArmorSavePercent, RUNTIME_CLASS(AActor) }, + { "attacksound", ActorAttackSound, RUNTIME_CLASS(AActor) }, + { "bloodcolor", ActorBloodColor, RUNTIME_CLASS(AActor) }, + { "bloodtype", ActorBloodType, RUNTIME_CLASS(AActor) }, + { "bouncecount", ActorBounceCount, RUNTIME_CLASS(AActor) }, + { "bouncefactor", ActorBounceFactor, RUNTIME_CLASS(AActor) }, + { "burn", ActorBurnState, RUNTIME_CLASS(AActor) }, + { "burnheight", ActorBurnHeight, RUNTIME_CLASS(AActor) }, + { "cameraheight", ActorCameraheight, RUNTIME_CLASS(AActor) }, + { "clearflags", ActorClearFlags, RUNTIME_CLASS(AActor) }, + { "conversationid", ActorConversationID, RUNTIME_CLASS(AActor) }, + { "crash", ActorCrashState, RUNTIME_CLASS(AActor) }, + { "crush", ActorCrushState, RUNTIME_CLASS(AActor) }, + { "damage", ActorDamage, RUNTIME_CLASS(AActor) }, + { "damagefactor", ActorDamageFactor, RUNTIME_CLASS(AActor) }, + { "damagetype", ActorDamageType, RUNTIME_CLASS(AActor) }, + { "death", ActorDeathState, RUNTIME_CLASS(AActor) }, + { "deathheight", ActorDeathHeight, RUNTIME_CLASS(AActor) }, + { "deathsound", ActorDeathSound, RUNTIME_CLASS(AActor) }, + { "decal", ActorDecal, RUNTIME_CLASS(AActor) }, + { "disintegrate", ActorDisintegrateState, RUNTIME_CLASS(AActor) }, + { "donthurtshooter", ActorDontHurtShooter, RUNTIME_CLASS(AActor) }, + { "dropitem", ActorDropItem, RUNTIME_CLASS(AActor) }, + { "explosiondamage", ActorExplosionDamage, RUNTIME_CLASS(AActor) }, + { "explosionradius", ActorExplosionRadius, RUNTIME_CLASS(AActor) }, + { "fastspeed", ActorFastSpeed, RUNTIME_CLASS(AActor) }, + { "floatspeed", ActorFloatSpeed, RUNTIME_CLASS(AActor) }, + { "game", ActorGame, RUNTIME_CLASS(AActor) }, + { "gibhealth", ActorGibHealth, RUNTIME_CLASS(AActor) }, + { "gravity", ActorGravity, RUNTIME_CLASS(AActor) }, + { "heal", ActorHealState, RUNTIME_CLASS(AActor) }, + { "health", ActorHealth, RUNTIME_CLASS(AActor) }, + { "health.lowmessage", (apf)HealthLowMessage, RUNTIME_CLASS(AHealth) }, + { "height", ActorHeight, RUNTIME_CLASS(AActor) }, + { "hitobituary", ActorHitObituary, RUNTIME_CLASS(AActor) }, + { "howlsound", ActorHowlSound, RUNTIME_CLASS(AActor) }, + { "ice", ActorIceState, RUNTIME_CLASS(AActor) }, + { "inventory.amount", (apf)InventoryAmount, RUNTIME_CLASS(AInventory) }, + { "inventory.defmaxamount", (apf)InventoryDefMaxAmount, RUNTIME_CLASS(AInventory) }, + { "inventory.givequest", (apf)InventoryGiveQuest, RUNTIME_CLASS(AInventory) }, + { "inventory.icon", (apf)InventoryIcon, RUNTIME_CLASS(AInventory) }, + { "inventory.maxamount", (apf)InventoryMaxAmount, RUNTIME_CLASS(AInventory) }, + { "inventory.pickupflash", (apf)InventoryPickupflash, RUNTIME_CLASS(AInventory) }, + { "inventory.pickupmessage", (apf)InventoryPickupmsg, RUNTIME_CLASS(AInventory) }, + { "inventory.pickupsound", (apf)InventoryPickupsound, RUNTIME_CLASS(AInventory) }, + { "inventory.respawntics", (apf)InventoryRespawntics, RUNTIME_CLASS(AInventory) }, + { "inventory.usesound", (apf)InventoryUsesound, RUNTIME_CLASS(AInventory) }, + { "mass", ActorMass, RUNTIME_CLASS(AActor) }, + { "maxdropoffheight", ActorMaxDropoffHeight, RUNTIME_CLASS(AActor) }, + { "maxstepheight", ActorMaxStepHeight, RUNTIME_CLASS(AActor) }, + { "maxtargetrange", ActorMaxTargetRange, RUNTIME_CLASS(AActor) }, + { "melee", ActorMeleeState, RUNTIME_CLASS(AActor) }, + { "meleedamage", ActorMeleeDamage, RUNTIME_CLASS(AActor) }, + { "meleerange", ActorMeleeRange, RUNTIME_CLASS(AActor) }, + { "meleesound", ActorMeleeSound, RUNTIME_CLASS(AActor) }, + { "meleethreshold", ActorMeleeThreshold, RUNTIME_CLASS(AActor) }, + { "minmissilechance", ActorMinMissileChance, RUNTIME_CLASS(AActor) }, + { "missile", ActorMissileState, RUNTIME_CLASS(AActor) }, + { "missileheight", ActorMissileHeight, RUNTIME_CLASS(AActor) }, + { "missiletype", ActorMissileType, RUNTIME_CLASS(AActor) }, + { "monster", ActorMonster, RUNTIME_CLASS(AActor) }, + { "morphprojectile.duration", (apf)EggFXDuration, RUNTIME_CLASS(AMorphProjectile) }, + { "morphprojectile.monsterclass", (apf)EggFXMonsterClass, RUNTIME_CLASS(AMorphProjectile) }, + { "morphprojectile.morphflash", (apf)EggFXMorphFlash, RUNTIME_CLASS(AMorphProjectile) }, +// { "morphprojectile.morphstyle", (apf)EggFXMorphStyle, RUNTIME_CLASS(AMorphProjectile) }, + { "morphprojectile.playerclass", (apf)EggFXPlayerClass, RUNTIME_CLASS(AMorphProjectile) }, + { "morphprojectile.unmorphflash", (apf)EggFXUnMorphFlash, RUNTIME_CLASS(AMorphProjectile) }, + { "obituary", ActorObituary, RUNTIME_CLASS(AActor) }, + { "pain", ActorPainState, RUNTIME_CLASS(AActor) }, + { "painchance", ActorPainChance, RUNTIME_CLASS(AActor) }, + { "painsound", ActorPainSound, RUNTIME_CLASS(AActor) }, + { "player.attackzoffset", (apf)PlayerAttackZOffset, RUNTIME_CLASS(APlayerPawn) }, + { "player.colorrange", (apf)PlayerColorRange, RUNTIME_CLASS(APlayerPawn) }, + { "player.crouchsprite", (apf)PlayerCrouchSprite, RUNTIME_CLASS(APlayerPawn) }, + { "player.damagescreencolor", (apf)PlayerDmgScreenColor, RUNTIME_CLASS(APlayerPawn) }, + { "player.displayname", (apf)PlayerDisplayName, RUNTIME_CLASS(APlayerPawn) }, + { "player.face", (apf)PlayerFace, RUNTIME_CLASS(APlayerPawn) }, + { "player.forwardmove", (apf)PlayerForwardMove, RUNTIME_CLASS(APlayerPawn) }, + { "player.healradiustype", (apf)PlayerHealRadius, RUNTIME_CLASS(APlayerPawn) }, + { "player.hexenarmor", (apf)PlayerHexenArmor, RUNTIME_CLASS(APlayerPawn) }, + { "player.invulnerabilitymode", (apf)PlayerInvulMode, RUNTIME_CLASS(APlayerPawn) }, + { "player.jumpz", (apf)PlayerJumpZ, RUNTIME_CLASS(APlayerPawn) }, + { "player.maxhealth", (apf)PlayerMaxHealth, RUNTIME_CLASS(APlayerPawn) }, + { "player.morphweapon", (apf)PlayerMorphWeapon, RUNTIME_CLASS(APlayerPawn) }, + { "player.runhealth", (apf)PlayerRunHealth, RUNTIME_CLASS(APlayerPawn) }, + { "player.scoreicon", (apf)PlayerScoreIcon, RUNTIME_CLASS(APlayerPawn) }, + { "player.sidemove", (apf)PlayerSideMove, RUNTIME_CLASS(APlayerPawn) }, + { "player.soundclass", (apf)PlayerSoundClass, RUNTIME_CLASS(APlayerPawn) }, + { "player.spawnclass", (apf)PlayerSpawnClass, RUNTIME_CLASS(APlayerPawn) }, + { "player.startitem", (apf)PlayerStartItem, RUNTIME_CLASS(APlayerPawn) }, + { "player.viewheight", (apf)PlayerViewHeight, RUNTIME_CLASS(APlayerPawn) }, + { "poisondamage", ActorPoisonDamage, RUNTIME_CLASS(AActor) }, + { "powermorph.morphflash", (apf)PowerMorphMorphFlash, RUNTIME_CLASS(APowerMorph) }, + //{ "powermorph.morphstyle", (apf)PowerMorphMorphStyle, RUNTIME_CLASS(APowerMorph) }, + { "powermorph.playerclass", (apf)PowerMorphPlayerClass, RUNTIME_CLASS(APowerMorph) }, + { "powermorph.unmorphflash", (apf)PowerMorphUnMorphFlash, RUNTIME_CLASS(APowerMorph) }, + { "powerup.color", (apf)PowerupColor, RUNTIME_CLASS(APowerupGiver) }, + { "powerup.duration", (apf)PowerupDuration, RUNTIME_CLASS(APowerupGiver) }, + { "powerup.mode", (apf)PowerupMode, RUNTIME_CLASS(APowerupGiver) }, + { "powerup.type", (apf)PowerupType, RUNTIME_CLASS(APowerupGiver) }, + { "projectile", ActorProjectile, RUNTIME_CLASS(AActor) }, + { "puzzleitem.failmessage", (apf)PuzzleitemFailMsg, RUNTIME_CLASS(APuzzleItem) }, + { "puzzleitem.number", (apf)PuzzleitemNumber, RUNTIME_CLASS(APuzzleItem) }, + { "radius", ActorRadius, RUNTIME_CLASS(AActor) }, + { "radiusdamagefactor", ActorRadiusDamageFactor, RUNTIME_CLASS(AActor) }, + { "raise", ActorRaiseState, RUNTIME_CLASS(AActor) }, + { "reactiontime", ActorReactionTime, RUNTIME_CLASS(AActor) }, + { "renderstyle", ActorRenderStyle, RUNTIME_CLASS(AActor) }, + { "scale", ActorScale, RUNTIME_CLASS(AActor) }, + { "see", ActorSeeState, RUNTIME_CLASS(AActor) }, + { "seesound", ActorSeeSound, RUNTIME_CLASS(AActor) }, + { "skip_super", ActorSkipSuper, RUNTIME_CLASS(AActor) }, + { "spawn", ActorSpawnState, RUNTIME_CLASS(AActor) }, + { "spawnid", ActorSpawnID, RUNTIME_CLASS(AActor) }, + { "speed", ActorSpeed, RUNTIME_CLASS(AActor) }, + { "states", ActorStates, RUNTIME_CLASS(AActor) }, + { "stencilcolor", ActorStencilColor, RUNTIME_CLASS(AActor) }, + { "tag", ActorTag, RUNTIME_CLASS(AActor) }, + { "translation", ActorTranslation, RUNTIME_CLASS(AActor) }, + { "vspeed", ActorVSpeed, RUNTIME_CLASS(AActor) }, + { "weapon.ammogive", (apf)WeaponAmmoGive1, RUNTIME_CLASS(AWeapon) }, + { "weapon.ammogive1", (apf)WeaponAmmoGive1, RUNTIME_CLASS(AWeapon) }, + { "weapon.ammogive2", (apf)WeaponAmmoGive2, RUNTIME_CLASS(AWeapon) }, + { "weapon.ammotype", (apf)WeaponAmmoType1, RUNTIME_CLASS(AWeapon) }, + { "weapon.ammotype1", (apf)WeaponAmmoType1, RUNTIME_CLASS(AWeapon) }, + { "weapon.ammotype2", (apf)WeaponAmmoType2, RUNTIME_CLASS(AWeapon) }, + { "weapon.ammouse", (apf)WeaponAmmoUse1, RUNTIME_CLASS(AWeapon) }, + { "weapon.ammouse1", (apf)WeaponAmmoUse1, RUNTIME_CLASS(AWeapon) }, + { "weapon.ammouse2", (apf)WeaponAmmoUse2, RUNTIME_CLASS(AWeapon) }, + { "weapon.kickback", (apf)WeaponKickback, RUNTIME_CLASS(AWeapon) }, + { "weapon.readysound", (apf)WeaponReadySound, RUNTIME_CLASS(AWeapon) }, + { "weapon.selectionorder", (apf)WeaponSelectionOrder, RUNTIME_CLASS(AWeapon) }, + { "weapon.sisterweapon", (apf)WeaponSisterWeapon, RUNTIME_CLASS(AWeapon) }, + { "weapon.upsound", (apf)WeaponUpSound, RUNTIME_CLASS(AWeapon) }, + { "weapon.yadjust", (apf)WeaponYAdjust, RUNTIME_CLASS(AWeapon) }, + { "weaponpiece.number", (apf)WPieceValue, RUNTIME_CLASS(AWeaponPiece) }, + { "weaponpiece.weapon", (apf)WPieceWeapon, RUNTIME_CLASS(AWeaponPiece) }, + { "wound", ActorWoundState, RUNTIME_CLASS(AActor) }, + { "woundhealth", ActorWoundHealth, RUNTIME_CLASS(AActor) }, + { "xdeath", ActorXDeathState, RUNTIME_CLASS(AActor) }, + { "xscale", ActorXScale, RUNTIME_CLASS(AActor) }, + { "yscale", ActorYScale, RUNTIME_CLASS(AActor) }, // AWeapon:MinAmmo1 and 2 are never used so there is no point in adding them here! }; static const ActorProps *is_actorprop (const char *str) diff --git a/src/version.h b/src/version.h index 5d939fd3b..333e77cf8 100644 --- a/src/version.h +++ b/src/version.h @@ -75,7 +75,7 @@ // SAVESIG should match SAVEVER. // MINSAVEVER is the minimum level snapshot version that can be loaded. -#define MINSAVEVER 887 +#define MINSAVEVER 889 #if SVN_REVISION_NUMBER < MINSAVEVER // Never write a savegame with a version lower than what we need