This commit is contained in:
Christoph Oelckers 2016-09-02 00:44:10 +02:00
commit 7135a6909c
5 changed files with 52 additions and 26 deletions

View File

@ -1057,6 +1057,7 @@ public:
int skillrespawncount;
int TIDtoHate; // TID of things to hate (0 if none)
FNameNoInit Species; // For monster families
TObjPtr<AActor> alternative; // (Un)Morphed actors stored here. Those with the MF_UNMORPHED flag are the originals.
TObjPtr<AActor> tracer; // Thing being chased/attacked for tracers
TObjPtr<AActor> master; // Thing which spawned this one (prevents mutual attacks)
double Floorclip; // value to use for floor clipping

View File

@ -38,7 +38,7 @@ bool P_MorphPlayer (player_t *activator, player_t *p, PClassPlayerPawn *spawntyp
APlayerPawn *actor;
actor = p->mo;
if (actor == NULL)
if (actor == nullptr)
{
return false;
}
@ -55,7 +55,7 @@ bool P_MorphPlayer (player_t *activator, player_t *p, PClassPlayerPawn *spawntyp
if ((p->mo->GetClass() == spawntype)
&& (p->mo->PlayerFlags & PPF_CANSUPERMORPH)
&& (p->morphTics < (((duration) ? duration : MORPHTICS) - TICRATE))
&& (p->mo->FindInventory (RUNTIME_CLASS(APowerWeaponLevel2), true) == NULL))
&& (p->mo->FindInventory (RUNTIME_CLASS(APowerWeaponLevel2), true) == nullptr))
{ // Make a super chicken
p->mo->GiveInventoryType (RUNTIME_CLASS(APowerWeaponLevel2));
}
@ -65,7 +65,7 @@ bool P_MorphPlayer (player_t *activator, player_t *p, PClassPlayerPawn *spawntyp
{ // Dead players cannot morph
return false;
}
if (spawntype == NULL)
if (spawntype == nullptr)
{
return false;
}
@ -94,7 +94,8 @@ bool P_MorphPlayer (player_t *activator, player_t *p, PClassPlayerPawn *spawntyp
}
morphed->Angles.Yaw = actor->Angles.Yaw;
morphed->target = actor->target;
morphed->tracer = actor;
morphed->tracer = actor->tracer;
morphed->alternative = actor;
morphed->FriendPlayer = actor->FriendPlayer;
morphed->DesignatedTeam = actor->DesignatedTeam;
morphed->Score = actor->Score;
@ -113,7 +114,8 @@ bool P_MorphPlayer (player_t *activator, player_t *p, PClassPlayerPawn *spawntyp
morphed->flags2 |= actor->flags2 & MF2_FLY;
morphed->flags3 |= actor->flags3 & MF3_GHOST;
AActor *eflash = Spawn(((enter_flash) ? enter_flash : RUNTIME_CLASS(ATeleportFog)), actor->PosPlusZ(TELEFOGHEIGHT), ALLOW_REPLACE);
actor->player = NULL;
actor->player = nullptr;
actor->alternative = morphed;
actor->flags &= ~(MF_SOLID|MF_SHOOTABLE);
actor->flags |= MF_UNMORPHED;
actor->renderflags |= RF_INVISIBLE;
@ -129,7 +131,7 @@ bool P_MorphPlayer (player_t *activator, player_t *p, PClassPlayerPawn *spawntyp
p->Vel.X = p->Vel.Y = 0;
morphed->ObtainInventory (actor);
// Remove all armor
for (item = morphed->Inventory; item != NULL; )
for (item = morphed->Inventory; item != nullptr; )
{
AInventory *next = item->Inventory;
if (item->IsKindOf (RUNTIME_CLASS(AArmor)))
@ -182,7 +184,7 @@ bool P_UndoPlayerMorph (player_t *activator, player_t *player, int unmorphflag,
// because the level or game is ended while morphed,
// by the time it gets executed the morphed player
// pawn instance may have already been destroyed.
if (pmo == NULL || pmo->tracer == NULL)
if (pmo == nullptr || pmo->alternative == nullptr)
{
return false;
}
@ -197,7 +199,7 @@ bool P_UndoPlayerMorph (player_t *activator, player_t *player, int unmorphflag,
return false;
}
mo = barrier_cast<APlayerPawn *>(pmo->tracer);
mo = barrier_cast<APlayerPawn *>(pmo->alternative);
mo->SetOrigin (pmo->Pos(), false);
mo->flags |= MF_SOLID;
pmo->flags &= ~MF_SOLID;
@ -208,10 +210,14 @@ bool P_UndoPlayerMorph (player_t *activator, player_t *player, int unmorphflag,
player->morphTics = 2*TICRATE;
return false;
}
pmo->player = NULL;
// No longer using tracer as morph storage. That is what 'alternative' is for.
// If the tracer has changed on the morph, change the original too.
mo->target = pmo->target;
mo->tracer = pmo->tracer;
pmo->player = nullptr;
// Remove the morph power if the morph is being undone prematurely.
for (AInventory *item = pmo->Inventory, *next = NULL; item != NULL; item = next)
for (AInventory *item = pmo->Inventory, *next = nullptr; item != nullptr; item = next)
{
next = item->Inventory;
if (item->IsKindOf(RUNTIME_CLASS(APowerMorph)))
@ -252,10 +258,10 @@ bool P_UndoPlayerMorph (player_t *activator, player_t *player, int unmorphflag,
player->morphTics = 0;
player->MorphedPlayerClass = 0;
player->MorphStyle = 0;
player->MorphExitFlash = NULL;
player->MorphExitFlash = nullptr;
player->viewheight = mo->ViewHeight;
AInventory *level2 = mo->FindInventory (RUNTIME_CLASS(APowerWeaponLevel2), true);
if (level2 != NULL)
if (level2 != nullptr)
{
level2->Destroy ();
}
@ -310,31 +316,31 @@ bool P_UndoPlayerMorph (player_t *activator, player_t *player, int unmorphflag,
}
}
AActor *eflash = NULL;
if (exit_flash != NULL)
AActor *eflash = nullptr;
if (exit_flash != nullptr)
{
eflash = Spawn(exit_flash, pmo->Vec3Angle(20., mo->Angles.Yaw, TELEFOGHEIGHT), ALLOW_REPLACE);
if (eflash) eflash->target = mo;
}
mo->SetupWeaponSlots(); // Use original class's weapon slots.
beastweap = player->ReadyWeapon;
if (player->PremorphWeapon != NULL)
if (player->PremorphWeapon != nullptr)
{
player->PremorphWeapon->PostMorphWeapon ();
}
else
{
player->ReadyWeapon = player->PendingWeapon = NULL;
player->ReadyWeapon = player->PendingWeapon = nullptr;
}
if (correctweapon)
{ // Better "lose morphed weapon" semantics
PClassActor *morphweapon = PClass::FindActor(pmo->MorphWeapon);
if (morphweapon != NULL && morphweapon->IsDescendantOf(RUNTIME_CLASS(AWeapon)))
if (morphweapon != nullptr && morphweapon->IsDescendantOf(RUNTIME_CLASS(AWeapon)))
{
AWeapon *OriginalMorphWeapon = static_cast<AWeapon *>(mo->FindInventory (morphweapon));
if ((OriginalMorphWeapon != NULL) && (OriginalMorphWeapon->GivenAsMorphWeapon))
if ((OriginalMorphWeapon != nullptr) && (OriginalMorphWeapon->GivenAsMorphWeapon))
{ // You don't get to keep your morphed weapon.
if (OriginalMorphWeapon->SisterWeapon != NULL)
if (OriginalMorphWeapon->SisterWeapon != nullptr)
{
OriginalMorphWeapon->SisterWeapon->Destroy ();
}
@ -344,20 +350,21 @@ bool P_UndoPlayerMorph (player_t *activator, player_t *player, int unmorphflag,
}
else // old behaviour (not really useful now)
{ // Assumptions made here are no longer valid
if (beastweap != NULL)
if (beastweap != nullptr)
{ // You don't get to keep your morphed weapon.
if (beastweap->SisterWeapon != NULL)
if (beastweap->SisterWeapon != nullptr)
{
beastweap->SisterWeapon->Destroy ();
}
beastweap->Destroy ();
}
}
pmo->tracer = NULL;
mo->alternative = nullptr;
pmo->alternative = nullptr;
pmo->Destroy ();
// Restore playerclass armor to its normal amount.
AHexenArmor *hxarmor = mo->FindInventory<AHexenArmor>();
if (hxarmor != NULL)
if (hxarmor != nullptr)
{
hxarmor->Slots[4] = mo->GetClass()->HexenArmor[0];
}
@ -517,9 +524,9 @@ bool P_MorphedDeath(AActor *actor, AActor **morphed, int *morphedstyle, int *mor
(actor->player->morphTics) &&
(actor->player->MorphStyle & MORPH_UNDOBYDEATH) &&
(actor->player->mo) &&
(actor->player->mo->tracer))
(actor->player->mo->alternative))
{
AActor *realme = actor->player->mo->tracer;
AActor *realme = actor->player->mo->alternative;
int realstyle = actor->player->MorphStyle;
int realhealth = actor->health;
if (P_UndoPlayerMorph(actor->player, actor->player, 0, !!(actor->player->MorphStyle & MORPH_UNDOBYDEATHFORCED)))

View File

@ -4449,6 +4449,8 @@ enum EACSFunctions
-106 : KickFromGame(2),
*/
ACSF_CheckClass = 200,
// ZDaemon
ACSF_GetTeamScore = 19620, // (int team)
ACSF_SetTeamScore, // (int team, int value)
@ -6028,6 +6030,12 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound)
return false;
}
case ACSF_CheckClass:
{
const char *clsname = FBehavior::StaticLookupString(args[0]);
return !!PClass::FindActor(clsname);
}
default:
break;
}

View File

@ -389,6 +389,11 @@ void AActor::Serialize(FArchive &arc)
arc << SpriteRotation;
}
if (SaveVersion >= 4550)
{
arc << alternative;
}
{
FString tagstr;
if (arc.IsStoring() && Tag != NULL && Tag->Len() > 0) tagstr = *Tag;
@ -1806,6 +1811,11 @@ double P_XYMovement (AActor *mo, DVector2 scroll)
mo->Vel.X *= fac;
mo->Vel.Y *= fac;
}
const double VELOCITY_THRESHOLD = 5000; // don't let it move faster than this. Fixed point overflowed at 32768 but that's too much to make this safe.
if (mo->Vel.LengthSquared() >= VELOCITY_THRESHOLD*VELOCITY_THRESHOLD)
{
mo->Vel.MakeResize(VELOCITY_THRESHOLD);
}
move = mo->Vel;
// [RH] Carrying sectors didn't work with low speeds in BOOM. This is
// because BOOM relied on the speed being fast enough to accumulate

View File

@ -76,7 +76,7 @@ const char *GetVersionString();
// Use 4500 as the base git save version, since it's higher than the
// SVN revision ever got.
#define SAVEVER 4549
#define SAVEVER 4550
#define SAVEVERSTRINGIFY2(x) #x
#define SAVEVERSTRINGIFY(x) SAVEVERSTRINGIFY2(x)