This commit is contained in:
Rachael Alexanderson 2017-03-02 18:13:33 -05:00
commit b3a69e1df8
20 changed files with 135 additions and 76 deletions

View file

@ -807,11 +807,6 @@ public:
return (flags & MF_COUNTKILL) && !(flags & MF_FRIENDLY); return (flags & MF_COUNTKILL) && !(flags & MF_FRIENDLY);
} }
PalEntry GetBloodColor() const
{
return GetClass()->BloodColor;
}
// These also set CF_INTERPVIEW for players. // These also set CF_INTERPVIEW for players.
void SetPitch(DAngle p, bool interpolate, bool forceclamp = false); void SetPitch(DAngle p, bool interpolate, bool forceclamp = false);
void SetAngle(DAngle ang, bool interpolate); void SetAngle(DAngle ang, bool interpolate);
@ -983,29 +978,42 @@ public:
// NOTE: The first member variable *must* be snext. // NOTE: The first member variable *must* be snext.
AActor *snext, **sprev; // links in sector (if needed) AActor *snext, **sprev; // links in sector (if needed)
DVector3 __Pos; // double underscores so that it won't get used by accident. Access to this should be exclusively through the designated access functions. DVector3 __Pos; // double underscores so that it won't get used by accident. Access to this should be exclusively through the designated access functions.
DVector3 OldRenderPos;
DAngle SpriteAngle; DAngle SpriteAngle;
DAngle SpriteRotation; DAngle SpriteRotation;
DAngle VisibleStartAngle;
DAngle VisibleStartPitch;
DAngle VisibleEndAngle;
DAngle VisibleEndPitch;
DRotator Angles; DRotator Angles;
DVector3 Vel; DVector2 Scale; // Scaling values; 1 is normal size
double Speed; double Alpha; // Since P_CheckSight makes an alpha check this can't be a float. It has to be a double.
double FloatSpeed;
int sprite; // used to find patch_t and flip value int sprite; // used to find patch_t and flip value
uint8_t frame; // sprite frame to draw uint8_t frame; // sprite frame to draw
uint8_t effects; // [RH] see p_effect.h uint8_t effects; // [RH] see p_effect.h
uint8_t fountaincolor; // Split out of 'effect' to have easier access. uint8_t fountaincolor; // Split out of 'effect' to have easier access.
DVector2 Scale; // Scaling values; 1 is normal size
FRenderStyle RenderStyle; // Style to draw this actor with FRenderStyle RenderStyle; // Style to draw this actor with
ActorRenderFlags renderflags; // Different rendering flags
FTextureID picnum; // Draw this instead of sprite if valid FTextureID picnum; // Draw this instead of sprite if valid
double Alpha; // Since P_CheckSight makes an alpha check this can't be a float. It has to be a double.
DWORD fillcolor; // Color to draw when STYLE_Shaded DWORD fillcolor; // Color to draw when STYLE_Shaded
DWORD Translation;
ActorRenderFlags renderflags; // Different rendering flags
ActorFlags flags;
ActorFlags2 flags2; // Heretic flags
ActorFlags3 flags3; // [RH] Hexen/Heretic actor-dependant behavior made flaggable
ActorFlags4 flags4; // [RH] Even more flags!
ActorFlags5 flags5; // OMG! We need another one.
ActorFlags6 flags6; // Shit! Where did all the flags go?
ActorFlags7 flags7; // WHO WANTS TO BET ON 8!?
double Floorclip; // value to use for floor clipping
double radius, Height; // for movement checking
DAngle VisibleStartAngle;
DAngle VisibleStartPitch;
DAngle VisibleEndAngle;
DAngle VisibleEndPitch;
DVector3 OldRenderPos;
DVector3 Vel;
double Speed;
double FloatSpeed;
// interaction info // interaction info
FBlockNode *BlockNode; // links in blocks (if needed) FBlockNode *BlockNode; // links in blocks (if needed)
@ -1019,7 +1027,6 @@ public:
int floorterrain; int floorterrain;
struct sector_t *ceilingsector; struct sector_t *ceilingsector;
FTextureID ceilingpic; // contacted sec ceilingpic FTextureID ceilingpic; // contacted sec ceilingpic
double radius, Height; // for movement checking
double renderradius; double renderradius;
double projectilepassheight; // height for clipping projectile movement against this actor double projectilepassheight; // height for clipping projectile movement against this actor
@ -1036,13 +1043,6 @@ public:
int DamageVal; int DamageVal;
VMFunction *DamageFunc; VMFunction *DamageFunc;
int projectileKickback; int projectileKickback;
ActorFlags flags;
ActorFlags2 flags2; // Heretic flags
ActorFlags3 flags3; // [RH] Hexen/Heretic actor-dependant behavior made flaggable
ActorFlags4 flags4; // [RH] Even more flags!
ActorFlags5 flags5; // OMG! We need another one.
ActorFlags6 flags6; // Shit! Where did all the flags go?
ActorFlags7 flags7; // WHO WANTS TO BET ON 8!?
// [BB] If 0, everybody can see the actor, if > 0, only members of team (VisibleToTeam-1) can see it. // [BB] If 0, everybody can see the actor, if > 0, only members of team (VisibleToTeam-1) can see it.
DWORD VisibleToTeam; DWORD VisibleToTeam;
@ -1080,7 +1080,6 @@ public:
TObjPtr<AActor> alternative; // (Un)Morphed actors stored here. Those with the MF_UNMORPHED flag are the originals. 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> tracer; // Thing being chased/attacked for tracers
TObjPtr<AActor> master; // Thing which spawned this one (prevents mutual attacks) TObjPtr<AActor> master; // Thing which spawned this one (prevents mutual attacks)
double Floorclip; // value to use for floor clipping
int tid; // thing identifier int tid; // thing identifier
int special; // special int special; // special
@ -1143,7 +1142,8 @@ public:
BYTE smokecounter; BYTE smokecounter;
BYTE FloatBobPhase; BYTE FloatBobPhase;
BYTE FriendPlayer; // [RH] Player # + 1 this friendly monster works for (so 0 is no player, 1 is player 0, etc) BYTE FriendPlayer; // [RH] Player # + 1 this friendly monster works for (so 0 is no player, 1 is player 0, etc)
DWORD Translation; PalEntry BloodColor;
DWORD BloodTranslation;
// [RH] Stuff that used to be part of an Actor Info // [RH] Stuff that used to be part of an Actor Info
FSoundIDNoInit SeeSound; FSoundIDNoInit SeeSound;

View file

@ -125,6 +125,8 @@ public:
int crouchsprite; int crouchsprite;
int MaxHealth; int MaxHealth;
int BonusHealth;
int MugShotMaxHealth; int MugShotMaxHealth;
int RunHealth; int RunHealth;
int PlayerFlags; int PlayerFlags;

View file

@ -665,7 +665,7 @@ void GLSprite::Process(AActor* thing, sector_t * sector, int thruportal)
bool isPicnumOverride = thing->picnum.isValid(); bool isPicnumOverride = thing->picnum.isValid();
// Don't waste time projecting sprites that are definitely not visible. // Don't waste time projecting sprites that are definitely not visible.
if ((thing->sprite == 0 && !isPicnumOverride) || !thing->IsVisibleToPlayer() || !thing->IsInsideVisibleAngles()) if ((thing->sprite == 0 && !isPicnumOverride) || !thing->IsVisibleToPlayer() || ((thing->renderflags & RF_MASKROTATION) && !thing->IsInsideVisibleAngles()))
{ {
return; return;
} }

View file

@ -295,7 +295,6 @@ void PClassActor::DeriveData(PClass *newclass)
PClassActor *newa = static_cast<PClassActor *>(newclass); PClassActor *newa = static_cast<PClassActor *>(newclass);
newa->DefaultStateUsage = DefaultStateUsage; newa->DefaultStateUsage = DefaultStateUsage;
newa->BloodColor = BloodColor;
newa->distancecheck = distancecheck; newa->distancecheck = distancecheck;
newa->DropItems = DropItems; newa->DropItems = DropItems;

View file

@ -290,8 +290,6 @@ public:
TArray<PClassActor *> VisibleToPlayerClass; TArray<PClassActor *> VisibleToPlayerClass;
PalEntry BloodColor; // Colorized blood
FDropItem *DropItems; FDropItem *DropItems;
FString SourceLumpName; FString SourceLumpName;
FIntCVar *distancecheck; FIntCVar *distancecheck;

View file

@ -1330,7 +1330,7 @@ static int CheckInventory (AActor *activator, const char *type, bool max)
if (max) if (max)
{ {
if (activator->IsKindOf (RUNTIME_CLASS (APlayerPawn))) if (activator->IsKindOf (RUNTIME_CLASS (APlayerPawn)))
return static_cast<APlayerPawn *>(activator)->MaxHealth; return static_cast<APlayerPawn *>(activator)->GetMaxHealth();
else else
return activator->SpawnHealth(); return activator->SpawnHealth();
} }
@ -3939,7 +3939,7 @@ int DLevelScript::GetActorProperty (int tid, int property)
case APROP_Dormant: return !!(actor->flags2 & MF2_DORMANT); case APROP_Dormant: return !!(actor->flags2 & MF2_DORMANT);
case APROP_SpawnHealth: if (actor->IsKindOf (RUNTIME_CLASS (APlayerPawn))) case APROP_SpawnHealth: if (actor->IsKindOf (RUNTIME_CLASS (APlayerPawn)))
{ {
return static_cast<APlayerPawn *>(actor)->MaxHealth; return static_cast<APlayerPawn *>(actor)->GetMaxHealth();
} }
else else
{ {

View file

@ -2580,8 +2580,7 @@ static bool InitSpawnedItem(AActor *self, AActor *mo, int flags)
else if (flags & SIXF_USEBLOODCOLOR) else if (flags & SIXF_USEBLOODCOLOR)
{ {
// [XA] Use the spawning actor's BloodColor to translate the newly-spawned object. // [XA] Use the spawning actor's BloodColor to translate the newly-spawned object.
PalEntry bloodcolor = self->GetBloodColor(); mo->Translation = self->BloodTranslation;
mo->Translation = TRANSLATION(TRANSLATION_Blood, bloodcolor.a);
} }
} }
if (flags & SIXF_TRANSFERPOINTERS) if (flags & SIXF_TRANSFERPOINTERS)

View file

@ -640,6 +640,7 @@ bool EV_BuildStairs (int tag, DFloor::EStair type, line_t *line,
floor->m_Delay = delay; floor->m_Delay = delay;
floor->m_PauseTime = 0; floor->m_PauseTime = 0;
floor->m_StepTime = floor->m_PerStepTime = persteptime; floor->m_StepTime = floor->m_PerStepTime = persteptime;
floor->m_Instant = false;
floor->m_Crush = (usespecials & DFloor::stairCrush) ? 10 : -1; //jff 2/27/98 fix uninitialized crush field floor->m_Crush = (usespecials & DFloor::stairCrush) ? 10 : -1; //jff 2/27/98 fix uninitialized crush field
floor->m_Hexencrush = false; floor->m_Hexencrush = false;
@ -755,6 +756,7 @@ bool EV_BuildStairs (int tag, DFloor::EStair type, line_t *line,
//jff 2/27/98 fix uninitialized crush field //jff 2/27/98 fix uninitialized crush field
floor->m_Crush = (!(usespecials & DFloor::stairUseSpecials) && speed == 4) ? 10 : -1; //jff 2/27/98 fix uninitialized crush field floor->m_Crush = (!(usespecials & DFloor::stairUseSpecials) && speed == 4) ? 10 : -1; //jff 2/27/98 fix uninitialized crush field
floor->m_Hexencrush = false; floor->m_Hexencrush = false;
floor->m_Instant = false;
floor->m_ResetCount = reset; // [RH] Tics until reset (0 if never) floor->m_ResetCount = reset; // [RH] Tics until reset (0 if never)
floor->m_OrgDist = sec->floorplane.fD(); // [RH] Height to reset to floor->m_OrgDist = sec->floorplane.fD(); // [RH] Height to reset to
} }
@ -817,6 +819,7 @@ bool EV_DoDonut (int tag, line_t *line, double pillarspeed, double slimespeed)
floor->m_Direction = 1; floor->m_Direction = 1;
floor->m_Sector = s2; floor->m_Sector = s2;
floor->m_Speed = slimespeed; floor->m_Speed = slimespeed;
floor->m_Instant = false;
floor->m_Texture = s3->GetTexture(sector_t::floor); floor->m_Texture = s3->GetTexture(sector_t::floor);
floor->m_NewSpecial.Clear(); floor->m_NewSpecial.Clear();
height = s3->FindHighestFloorPoint (&spot); height = s3->FindHighestFloorPoint (&spot);
@ -831,6 +834,7 @@ bool EV_DoDonut (int tag, line_t *line, double pillarspeed, double slimespeed)
floor->m_Direction = -1; floor->m_Direction = -1;
floor->m_Sector = s1; floor->m_Sector = s1;
floor->m_Speed = pillarspeed; floor->m_Speed = pillarspeed;
floor->m_Instant = false;
height = s3->FindHighestFloorPoint (&spot); height = s3->FindHighestFloorPoint (&spot);
floor->m_FloorDestDist = s1->floorplane.PointToDist (spot, height); floor->m_FloorDestDist = s1->floorplane.PointToDist (spot, height);
floor->StartFloorSound (); floor->StartFloorSound ();

View file

@ -253,6 +253,7 @@ void ClientObituary (AActor *self, AActor *inflictor, AActor *attacker, int dmgf
} }
} }
if (message == nullptr) message = messagename; // fallback to defaults if possible. if (message == nullptr) message = messagename; // fallback to defaults if possible.
if (attacker == nullptr) attacker = self; // world
if (attacker->player == nullptr) attacker = self; // for the message creation if (attacker->player == nullptr) attacker = self; // for the message creation
if (message != NULL && message[0] == '$') if (message != NULL && message[0] == '$')

View file

@ -4803,7 +4803,7 @@ void P_TraceBleed(int damage, const DVector3 &pos, AActor *actor, DAngle angle,
{ {
if (bleedtrace.HitType == TRACE_HitWall) if (bleedtrace.HitType == TRACE_HitWall)
{ {
PalEntry bloodcolor = actor->GetBloodColor(); PalEntry bloodcolor = actor->BloodColor;
if (bloodcolor != 0) if (bloodcolor != 0)
{ {
bloodcolor.r >>= 1; // the full color is too bright for blood decals bloodcolor.r >>= 1; // the full color is too bright for blood decals
@ -5994,7 +5994,6 @@ void P_DoCrunch(AActor *thing, FChangePosition *cpos)
{ {
if (!(thing->flags&MF_NOBLOOD)) if (!(thing->flags&MF_NOBLOOD))
{ {
PalEntry bloodcolor = thing->GetBloodColor();
PClassActor *bloodcls = thing->GetBloodType(); PClassActor *bloodcls = thing->GetBloodType();
P_TraceBleed (newdam > 0 ? newdam : cpos->crushchange, thing); P_TraceBleed (newdam > 0 ? newdam : cpos->crushchange, thing);
@ -6006,9 +6005,9 @@ void P_DoCrunch(AActor *thing, FChangePosition *cpos)
mo->Vel.X = pr_crunch.Random2() / 16.; mo->Vel.X = pr_crunch.Random2() / 16.;
mo->Vel.Y = pr_crunch.Random2() / 16.; mo->Vel.Y = pr_crunch.Random2() / 16.;
if (bloodcolor != 0 && !(mo->flags2 & MF2_DONTTRANSLATE)) if (thing->BloodTranslation != 0 && !(mo->flags2 & MF2_DONTTRANSLATE))
{ {
mo->Translation = TRANSLATION(TRANSLATION_Blood, bloodcolor.a); mo->Translation = thing->BloodTranslation;
} }
if (!(cl_bloodtype <= 1)) mo->renderflags |= RF_INVISIBLE; if (!(cl_bloodtype <= 1)) mo->renderflags |= RF_INVISIBLE;
@ -6017,7 +6016,7 @@ void P_DoCrunch(AActor *thing, FChangePosition *cpos)
DAngle an = (M_Random() - 128) * (360./256); DAngle an = (M_Random() - 128) * (360./256);
if (cl_bloodtype >= 1) if (cl_bloodtype >= 1)
{ {
P_DrawSplash2(32, thing->PosPlusZ(thing->Height/2), an, 2, bloodcolor); P_DrawSplash2(32, thing->PosPlusZ(thing->Height/2), an, 2, thing->BloodColor);
} }
} }
if (thing->CrushPainSound != 0 && !S_GetSoundPlayingInfo(thing, thing->CrushPainSound)) if (thing->CrushPainSound != 0 && !S_GetSoundPlayingInfo(thing, thing->CrushPainSound))

View file

@ -316,8 +316,8 @@ DEFINE_FIELD(AActor, RadiusDamageFactor)
DEFINE_FIELD(AActor, SelfDamageFactor) DEFINE_FIELD(AActor, SelfDamageFactor)
DEFINE_FIELD(AActor, StealthAlpha) DEFINE_FIELD(AActor, StealthAlpha)
DEFINE_FIELD(AActor, WoundHealth) DEFINE_FIELD(AActor, WoundHealth)
DEFINE_FIELD(AActor, BloodColor)
//DEFINE_FIELD(PClassActor, BloodColor) DEFINE_FIELD(AActor, BloodTranslation)
//========================================================================== //==========================================================================
// //
@ -409,6 +409,8 @@ void AActor::Serialize(FSerializer &arc)
A("inventoryid", InventoryID) A("inventoryid", InventoryID)
A("floatbobphase", FloatBobPhase) A("floatbobphase", FloatBobPhase)
A("translation", Translation) A("translation", Translation)
A("bloodcolor", BloodColor)
A("bloodtranslation", BloodTranslation)
A("seesound", SeeSound) A("seesound", SeeSound)
A("attacksound", AttackSound) A("attacksound", AttackSound)
A("paimsound", PainSound) A("paimsound", PainSound)
@ -1338,7 +1340,7 @@ bool P_GiveBody(AActor *actor, int num, int max)
{ {
if (!(player->MorphStyle & MORPH_ADDSTAMINA)) if (!(player->MorphStyle & MORPH_ADDSTAMINA))
{ {
max -= player->mo->stamina; max -= player->mo->stamina + player->mo->BonusHealth;
} }
} }
else // old health behaviour else // old health behaviour
@ -1346,7 +1348,7 @@ bool P_GiveBody(AActor *actor, int num, int max)
max = MAXMORPHHEALTH; max = MAXMORPHHEALTH;
if (player->MorphStyle & MORPH_ADDSTAMINA) if (player->MorphStyle & MORPH_ADDSTAMINA)
{ {
max += player->mo->stamina; max += player->mo->stamina + player->mo->BonusHealth;
} }
} }
} }
@ -1665,8 +1667,7 @@ bool AActor::Grind(bool items)
if (isgeneric) // Not a custom crush state, so colorize it appropriately. if (isgeneric) // Not a custom crush state, so colorize it appropriately.
{ {
S_Sound (this, CHAN_BODY, "misc/fallingsplat", 1, ATTN_IDLE); S_Sound (this, CHAN_BODY, "misc/fallingsplat", 1, ATTN_IDLE);
PalEntry bloodcolor = GetBloodColor(); Translation = BloodTranslation;
if (bloodcolor!=0) Translation = TRANSLATION(TRANSLATION_Blood, bloodcolor.a);
} }
return false; return false;
} }
@ -1707,10 +1708,7 @@ bool AActor::Grind(bool items)
gib->Alpha = Alpha; gib->Alpha = Alpha;
gib->Height = 0; gib->Height = 0;
gib->radius = 0; gib->radius = 0;
gib->Translation = BloodTranslation;
PalEntry bloodcolor = GetBloodColor();
if (bloodcolor != 0)
gib->Translation = TRANSLATION(TRANSLATION_Blood, bloodcolor.a);
} }
S_Sound (this, CHAN_BODY, "misc/fallingsplat", 1, ATTN_IDLE); S_Sound (this, CHAN_BODY, "misc/fallingsplat", 1, ATTN_IDLE);
} }
@ -3510,7 +3508,7 @@ int AActor::GetMissileDamage (int mask, int add)
void AActor::Howl () void AActor::Howl ()
{ {
FSoundID howl = IntVar(NAME_HowlSound); FSoundID howl = SoundVar(NAME_HowlSound);
if (!S_IsActorPlayingSomething(this, CHAN_BODY, howl)) if (!S_IsActorPlayingSomething(this, CHAN_BODY, howl))
{ {
S_Sound (this, CHAN_BODY, howl, 1, ATTN_NORM); S_Sound (this, CHAN_BODY, howl, 1, ATTN_NORM);
@ -6051,7 +6049,6 @@ DEFINE_ACTION_FUNCTION(AActor, SpawnPuff)
void P_SpawnBlood (const DVector3 &pos1, DAngle dir, int damage, AActor *originator) void P_SpawnBlood (const DVector3 &pos1, DAngle dir, int damage, AActor *originator)
{ {
AActor *th; AActor *th;
PalEntry bloodcolor = originator->GetBloodColor();
PClassActor *bloodcls = originator->GetBloodType(); PClassActor *bloodcls = originator->GetBloodType();
DVector3 pos = pos1; DVector3 pos = pos1;
pos.Z += pr_spawnblood.Random2() / 64.; pos.Z += pr_spawnblood.Random2() / 64.;
@ -6076,9 +6073,9 @@ void P_SpawnBlood (const DVector3 &pos1, DAngle dir, int damage, AActor *origina
th->tics = 1; th->tics = 1;
} }
// colorize the blood // colorize the blood
if (bloodcolor != 0 && !(th->flags2 & MF2_DONTTRANSLATE)) if (!(th->flags2 & MF2_DONTTRANSLATE))
{ {
th->Translation = TRANSLATION(TRANSLATION_Blood, bloodcolor.a); th->Translation = originator->BloodTranslation;
} }
// Moved out of the blood actor so that replacing blood is easier // Moved out of the blood actor so that replacing blood is easier
@ -6135,7 +6132,7 @@ void P_SpawnBlood (const DVector3 &pos1, DAngle dir, int damage, AActor *origina
} }
if (bloodtype >= 1) if (bloodtype >= 1)
P_DrawSplash2 (40, pos, dir, 2, bloodcolor); P_DrawSplash2 (40, pos, dir, 2, originator->BloodColor);
} }
DEFINE_ACTION_FUNCTION(AActor, SpawnBlood) DEFINE_ACTION_FUNCTION(AActor, SpawnBlood)
@ -6159,7 +6156,6 @@ DEFINE_ACTION_FUNCTION(AActor, SpawnBlood)
void P_BloodSplatter (const DVector3 &pos, AActor *originator, DAngle hitangle) void P_BloodSplatter (const DVector3 &pos, AActor *originator, DAngle hitangle)
{ {
PalEntry bloodcolor = originator->GetBloodColor();
PClassActor *bloodcls = originator->GetBloodType(1); PClassActor *bloodcls = originator->GetBloodType(1);
int bloodtype = cl_bloodtype; int bloodtype = cl_bloodtype;
@ -6178,16 +6174,16 @@ void P_BloodSplatter (const DVector3 &pos, AActor *originator, DAngle hitangle)
mo->Vel.Z = 3; mo->Vel.Z = 3;
// colorize the blood! // colorize the blood!
if (bloodcolor!=0 && !(mo->flags2 & MF2_DONTTRANSLATE)) if (!(mo->flags2 & MF2_DONTTRANSLATE))
{ {
mo->Translation = TRANSLATION(TRANSLATION_Blood, bloodcolor.a); mo->Translation = originator->BloodTranslation;
} }
if (!(bloodtype <= 1)) mo->renderflags |= RF_INVISIBLE; if (!(bloodtype <= 1)) mo->renderflags |= RF_INVISIBLE;
} }
if (bloodtype >= 1) if (bloodtype >= 1)
{ {
P_DrawSplash2 (40, pos, hitangle-180., 2, bloodcolor); P_DrawSplash2 (40, pos, hitangle-180., 2, originator->BloodColor);
} }
} }
@ -6199,7 +6195,6 @@ void P_BloodSplatter (const DVector3 &pos, AActor *originator, DAngle hitangle)
void P_BloodSplatter2 (const DVector3 &pos, AActor *originator, DAngle hitangle) void P_BloodSplatter2 (const DVector3 &pos, AActor *originator, DAngle hitangle)
{ {
PalEntry bloodcolor = originator->GetBloodColor();
PClassActor *bloodcls = originator->GetBloodType(2); PClassActor *bloodcls = originator->GetBloodType(2);
int bloodtype = cl_bloodtype; int bloodtype = cl_bloodtype;
@ -6220,16 +6215,16 @@ void P_BloodSplatter2 (const DVector3 &pos, AActor *originator, DAngle hitangle)
mo->target = originator; mo->target = originator;
// colorize the blood! // colorize the blood!
if (bloodcolor != 0 && !(mo->flags2 & MF2_DONTTRANSLATE)) if (!(mo->flags2 & MF2_DONTTRANSLATE))
{ {
mo->Translation = TRANSLATION(TRANSLATION_Blood, bloodcolor.a); mo->Translation = originator->BloodTranslation;
} }
if (!(bloodtype <= 1)) mo->renderflags |= RF_INVISIBLE; if (!(bloodtype <= 1)) mo->renderflags |= RF_INVISIBLE;
} }
if (bloodtype >= 1) if (bloodtype >= 1)
{ {
P_DrawSplash2(40, pos + add, hitangle - 180., 2, bloodcolor); P_DrawSplash2(40, pos + add, hitangle - 180., 2, originator->BloodColor);
} }
} }
@ -6255,7 +6250,6 @@ DEFINE_ACTION_FUNCTION(AActor, BloodSplatter)
void P_RipperBlood (AActor *mo, AActor *bleeder) void P_RipperBlood (AActor *mo, AActor *bleeder)
{ {
PalEntry bloodcolor = bleeder->GetBloodColor();
PClassActor *bloodcls = bleeder->GetBloodType(); PClassActor *bloodcls = bleeder->GetBloodType();
double xo = pr_ripperblood.Random2() / 16.; double xo = pr_ripperblood.Random2() / 16.;
@ -6281,16 +6275,16 @@ void P_RipperBlood (AActor *mo, AActor *bleeder)
th->tics += pr_ripperblood () & 3; th->tics += pr_ripperblood () & 3;
// colorize the blood! // colorize the blood!
if (bloodcolor!=0 && !(th->flags2 & MF2_DONTTRANSLATE)) if (!(th->flags2 & MF2_DONTTRANSLATE))
{ {
th->Translation = TRANSLATION(TRANSLATION_Blood, bloodcolor.a); th->Translation = bleeder->BloodTranslation;
} }
if (!(bloodtype <= 1)) th->renderflags |= RF_INVISIBLE; if (!(bloodtype <= 1)) th->renderflags |= RF_INVISIBLE;
} }
if (bloodtype >= 1) if (bloodtype >= 1)
{ {
P_DrawSplash2(28, pos, bleeder->AngleTo(mo) + 180., 0, bloodcolor); P_DrawSplash2(28, pos, bleeder->AngleTo(mo) + 180., 0, bleeder->BloodColor);
} }
} }

View file

@ -781,6 +781,7 @@ void APlayerPawn::Serialize(FSerializer &arc)
arc("jumpz", JumpZ, def->JumpZ) arc("jumpz", JumpZ, def->JumpZ)
("maxhealth", MaxHealth, def->MaxHealth) ("maxhealth", MaxHealth, def->MaxHealth)
("bonushealth", BonusHealth, def->BonusHealth)
("runhealth", RunHealth, def->RunHealth) ("runhealth", RunHealth, def->RunHealth)
("spawnmask", SpawnMask, def->SpawnMask) ("spawnmask", SpawnMask, def->SpawnMask)
("forwardmove1", ForwardMove1, def->ForwardMove1) ("forwardmove1", ForwardMove1, def->ForwardMove1)
@ -1353,7 +1354,7 @@ const char *APlayerPawn::GetSoundClass() const
int APlayerPawn::GetMaxHealth(bool withupgrades) const int APlayerPawn::GetMaxHealth(bool withupgrades) const
{ {
int ret = MaxHealth > 0? MaxHealth : ((i_compatflags&COMPATF_DEHHEALTH)? 100 : deh.MaxHealth); int ret = MaxHealth > 0? MaxHealth : ((i_compatflags&COMPATF_DEHHEALTH)? 100 : deh.MaxHealth);
if (withupgrades) ret += stamina; if (withupgrades) ret += stamina + BonusHealth;
return ret; return ret;
} }
@ -3346,6 +3347,7 @@ bool P_IsPlayerTotallyFrozen(const player_t *player)
DEFINE_FIELD(APlayerPawn, crouchsprite) DEFINE_FIELD(APlayerPawn, crouchsprite)
DEFINE_FIELD(APlayerPawn, MaxHealth) DEFINE_FIELD(APlayerPawn, MaxHealth)
DEFINE_FIELD(APlayerPawn, BonusHealth)
DEFINE_FIELD(APlayerPawn, MugShotMaxHealth) DEFINE_FIELD(APlayerPawn, MugShotMaxHealth)
DEFINE_FIELD(APlayerPawn, RunHealth) DEFINE_FIELD(APlayerPawn, RunHealth)
DEFINE_FIELD(APlayerPawn, PlayerFlags) DEFINE_FIELD(APlayerPawn, PlayerFlags)

View file

@ -218,8 +218,11 @@ bool FZipFile::Open(bool quiet)
char *dirptr = (char*)directory; char *dirptr = (char*)directory;
FZipLump *lump_p = Lumps; FZipLump *lump_p = Lumps;
// Check if all files have the same prefix so that this can be stripped out.
FString name0; FString name0;
bool foundspeciallump = false;
// Check if all files have the same prefix so that this can be stripped out.
// This will only be done if there is either a MAPINFO, ZMAPINFO or GAMEINFO lump in the subdirectory, denoting a ZDoom mod.
if (NumLumps > 1) for (DWORD i = 0; i < NumLumps; i++) if (NumLumps > 1) for (DWORD i = 0; i < NumLumps; i++)
{ {
FZipCentralDirectoryInfo *zip_fh = (FZipCentralDirectoryInfo *)dirptr; FZipCentralDirectoryInfo *zip_fh = (FZipCentralDirectoryInfo *)dirptr;
@ -251,6 +254,7 @@ bool FZipFile::Open(bool quiet)
!name.Compare("voxels/") || !name.Compare("voxels/") ||
!name.Compare("colormaps/") || !name.Compare("colormaps/") ||
!name.Compare("acs/") || !name.Compare("acs/") ||
!name.Compare("maps/") ||
!name.Compare("voices/") || !name.Compare("voices/") ||
!name.Compare("patches/") || !name.Compare("patches/") ||
!name.Compare("graphics/") || !name.Compare("graphics/") ||
@ -266,6 +270,23 @@ bool FZipFile::Open(bool quiet)
name0 = ""; name0 = "";
break; break;
} }
else if (!foundspeciallump)
{
// at least one of the more common definition lumps must be present.
if (name.IndexOf(name0 + "mapinfo") == 0) foundspeciallump = true;
else if (name.IndexOf(name0 + "zmapinfo") == 0) foundspeciallump = true;
else if (name.IndexOf(name0 + "gameinfo") == 0) foundspeciallump = true;
else if (name.IndexOf(name0 + "sndinfo") == 0) foundspeciallump = true;
else if (name.IndexOf(name0 + "sbarinfo") == 0) foundspeciallump = true;
else if (name.IndexOf(name0 + "menudef") == 0) foundspeciallump = true;
else if (name.IndexOf(name0 + "gldefs") == 0) foundspeciallump = true;
else if (name.IndexOf(name0 + "animdefs") == 0) foundspeciallump = true;
else if (name.IndexOf(name0 + "decorate.") == 0) foundspeciallump = true; // DECORATE is a common subdirectory name, so the check needs to be a bit different.
else if (name.Compare(name0 + "decorate") == 0) foundspeciallump = true;
else if (name.IndexOf(name0 + "zscript.") == 0) foundspeciallump = true; // same here.
else if (name.Compare(name0 + "zscript") == 0) foundspeciallump = true;
else if (name.Compare(name0 + "maps/") == 0) foundspeciallump = true;
}
} }
} }

View file

@ -846,6 +846,7 @@ void FFunctionBuildList::Build()
{ {
int errorcount = 0; int errorcount = 0;
int codesize = 0; int codesize = 0;
int datasize = 0;
FILE *dump = nullptr; FILE *dump = nullptr;
if (Args->CheckParm("-dumpdisasm")) dump = fopen("disasm.txt", "w"); if (Args->CheckParm("-dumpdisasm")) dump = fopen("disasm.txt", "w");
@ -927,6 +928,8 @@ void FFunctionBuildList::Build()
{ {
DumpFunction(dump, sfunc, item.PrintableName.GetChars(), (int)item.PrintableName.Len()); DumpFunction(dump, sfunc, item.PrintableName.GetChars(), (int)item.PrintableName.Len());
codesize += sfunc->CodeSize; codesize += sfunc->CodeSize;
datasize += sfunc->LineInfoCount * sizeof(FStatementInfo) + sfunc->ExtraSpace + sfunc->NumKonstD * sizeof(int) +
sfunc->NumKonstA * sizeof(void*) + sfunc->NumKonstF * sizeof(double) + sfunc->NumKonstS * sizeof(FString);
} }
sfunc->Unsafe = ctx.Unsafe; sfunc->Unsafe = ctx.Unsafe;
} }
@ -944,10 +947,11 @@ void FFunctionBuildList::Build()
} }
if (dump != nullptr) if (dump != nullptr)
{ {
fprintf(dump, "\n*************************************************************************\n%i code bytes\n", codesize * 4); fprintf(dump, "\n*************************************************************************\n%i code bytes\n%i data bytes", codesize * 4, datasize);
fclose(dump); fclose(dump);
} }
FScriptPosition::StrictErrors = false; FScriptPosition::StrictErrors = false;
mItems.Clear(); mItems.Clear();
mItems.ShrinkToFit();
FxAlloc.FreeAllBlocks(); FxAlloc.FreeAllBlocks();
} }

View file

@ -1053,10 +1053,9 @@ DEFINE_PROPERTY(bloodcolor, C, Actor)
{ {
PROP_COLOR_PARM(color, 0); PROP_COLOR_PARM(color, 0);
PalEntry pe = color; defaults->BloodColor = color;
pe.a = CreateBloodTranslation(pe); defaults->BloodColor.a = 255; // a should not be 0.
assert(info->IsKindOf(RUNTIME_CLASS(PClassActor))); defaults->BloodTranslation = TRANSLATION(TRANSLATION_Blood, CreateBloodTranslation(color));
static_cast<PClassActor *>(info)->BloodColor = pe;
} }
//========================================================================== //==========================================================================

View file

@ -194,7 +194,8 @@ class Actor : Thinker native
native double SelfDamageFactor; native double SelfDamageFactor;
native double StealthAlpha; native double StealthAlpha;
native int WoundHealth; // Health needed to enter wound state native int WoundHealth; // Health needed to enter wound state
//native color BloodColor; // won't be accessible for now because it needs refactoring to remove the 255-translations limit. native readonly color BloodColor;
native readonly int BloodTranslation;
meta String Obituary; // Player was killed by this actor meta String Obituary; // Player was killed by this actor
meta String HitObituary; // Player was killed by this actor in melee meta String HitObituary; // Player was killed by this actor in melee

View file

@ -1009,6 +1009,13 @@ enum ERaise
RF_NOCHECKPOSITION = 2 RF_NOCHECKPOSITION = 2
} }
enum eFogParm
{
FOGP_DENSITY = 0,
FOGP_OUTSIDEDENSITY = 1,
FOGP_SKYFOG = 2,
}
enum ETeleport enum ETeleport
{ {
TELF_DESTFOG = 1, TELF_DESTFOG = 1,

View file

@ -86,8 +86,36 @@ class Health : Inventory
} }
return false; return false;
} }
}
class MaxHealth : Health
{
//===========================================================================
//
// TryPickup
//
//===========================================================================
override bool TryPickup (in out Actor other)
{
bool success = false;
int savedAmount = MaxAmount;
let player = PlayerPawn(other);
MaxAmount = Health;
if (player)
{
if (player.BonusHealth < savedAmount)
{
player.BonusHealth = min(player.BonusHealth + Amount, savedAmount);
success = true;
}
MaxAmount += player.BonusHealth;
}
success |= Super.TryPickup(other);
MaxAmount = savedAmount;
if (success) GoAwayAndDie();
return success;
}
} }
class HealthPickup : Inventory class HealthPickup : Inventory

View file

@ -3,6 +3,7 @@ class PlayerPawn : Actor native
native int crouchsprite; native int crouchsprite;
native int MaxHealth; native int MaxHealth;
native int BonusHealth;
native int MugShotMaxHealth; native int MugShotMaxHealth;
native int RunHealth; native int RunHealth;
native int PlayerFlags; native int PlayerFlags;

View file

@ -95,7 +95,7 @@ class Programmer : Actor
A_PlaySound("programmer/clank", CHAN_WEAPON); A_PlaySound("programmer/clank", CHAN_WEAPON);
int damage = ((random[Programmer]() % 10) + 1) * 6; int damage = ((random[Programmer]() % 10) + 1) * 6;
int newdam = DamageMobj (self, self, damage, 'Melee'); int newdam = target.DamageMobj (self, self, damage, 'Melee');
target.TraceBleed (newdam > 0 ? newdam : damage, self); target.TraceBleed (newdam > 0 ? newdam : damage, self);
} }