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);
}
PalEntry GetBloodColor() const
{
return GetClass()->BloodColor;
}
// These also set CF_INTERPVIEW for players.
void SetPitch(DAngle p, bool interpolate, bool forceclamp = false);
void SetAngle(DAngle ang, bool interpolate);
@ -983,29 +978,42 @@ public:
// NOTE: The first member variable *must* be snext.
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 OldRenderPos;
DAngle SpriteAngle;
DAngle SpriteRotation;
DAngle VisibleStartAngle;
DAngle VisibleStartPitch;
DAngle VisibleEndAngle;
DAngle VisibleEndPitch;
DRotator Angles;
DVector3 Vel;
double Speed;
double FloatSpeed;
DVector2 Scale; // Scaling values; 1 is normal size
double Alpha; // Since P_CheckSight makes an alpha check this can't be a float. It has to be a double.
int sprite; // used to find patch_t and flip value
uint8_t frame; // sprite frame to draw
uint8_t effects; // [RH] see p_effect.h
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
ActorRenderFlags renderflags; // Different rendering flags
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 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
FBlockNode *BlockNode; // links in blocks (if needed)
@ -1019,7 +1027,6 @@ public:
int floorterrain;
struct sector_t *ceilingsector;
FTextureID ceilingpic; // contacted sec ceilingpic
double radius, Height; // for movement checking
double renderradius;
double projectilepassheight; // height for clipping projectile movement against this actor
@ -1036,13 +1043,6 @@ public:
int DamageVal;
VMFunction *DamageFunc;
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.
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> 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
int tid; // thing identifier
int special; // special
@ -1143,7 +1142,8 @@ public:
BYTE smokecounter;
BYTE FloatBobPhase;
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
FSoundIDNoInit SeeSound;

View file

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

View file

@ -665,7 +665,7 @@ void GLSprite::Process(AActor* thing, sector_t * sector, int thruportal)
bool isPicnumOverride = thing->picnum.isValid();
// 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;
}

View file

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

View file

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

View file

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

View file

@ -2580,8 +2580,7 @@ static bool InitSpawnedItem(AActor *self, AActor *mo, int flags)
else if (flags & SIXF_USEBLOODCOLOR)
{
// [XA] Use the spawning actor's BloodColor to translate the newly-spawned object.
PalEntry bloodcolor = self->GetBloodColor();
mo->Translation = TRANSLATION(TRANSLATION_Blood, bloodcolor.a);
mo->Translation = self->BloodTranslation;
}
}
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_PauseTime = 0;
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_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
floor->m_Crush = (!(usespecials & DFloor::stairUseSpecials) && speed == 4) ? 10 : -1; //jff 2/27/98 fix uninitialized crush field
floor->m_Hexencrush = false;
floor->m_Instant = false;
floor->m_ResetCount = reset; // [RH] Tics until reset (0 if never)
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_Sector = s2;
floor->m_Speed = slimespeed;
floor->m_Instant = false;
floor->m_Texture = s3->GetTexture(sector_t::floor);
floor->m_NewSpecial.Clear();
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_Sector = s1;
floor->m_Speed = pillarspeed;
floor->m_Instant = false;
height = s3->FindHighestFloorPoint (&spot);
floor->m_FloorDestDist = s1->floorplane.PointToDist (spot, height);
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 (attacker == nullptr) attacker = self; // world
if (attacker->player == nullptr) attacker = self; // for the message creation
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)
{
PalEntry bloodcolor = actor->GetBloodColor();
PalEntry bloodcolor = actor->BloodColor;
if (bloodcolor != 0)
{
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))
{
PalEntry bloodcolor = thing->GetBloodColor();
PClassActor *bloodcls = thing->GetBloodType();
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.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;
@ -6017,7 +6016,7 @@ void P_DoCrunch(AActor *thing, FChangePosition *cpos)
DAngle an = (M_Random() - 128) * (360./256);
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))

View file

@ -316,8 +316,8 @@ DEFINE_FIELD(AActor, RadiusDamageFactor)
DEFINE_FIELD(AActor, SelfDamageFactor)
DEFINE_FIELD(AActor, StealthAlpha)
DEFINE_FIELD(AActor, WoundHealth)
//DEFINE_FIELD(PClassActor, BloodColor)
DEFINE_FIELD(AActor, BloodColor)
DEFINE_FIELD(AActor, BloodTranslation)
//==========================================================================
//
@ -409,6 +409,8 @@ void AActor::Serialize(FSerializer &arc)
A("inventoryid", InventoryID)
A("floatbobphase", FloatBobPhase)
A("translation", Translation)
A("bloodcolor", BloodColor)
A("bloodtranslation", BloodTranslation)
A("seesound", SeeSound)
A("attacksound", AttackSound)
A("paimsound", PainSound)
@ -1338,7 +1340,7 @@ bool P_GiveBody(AActor *actor, int num, int max)
{
if (!(player->MorphStyle & MORPH_ADDSTAMINA))
{
max -= player->mo->stamina;
max -= player->mo->stamina + player->mo->BonusHealth;
}
}
else // old health behaviour
@ -1346,7 +1348,7 @@ bool P_GiveBody(AActor *actor, int num, int max)
max = MAXMORPHHEALTH;
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.
{
S_Sound (this, CHAN_BODY, "misc/fallingsplat", 1, ATTN_IDLE);
PalEntry bloodcolor = GetBloodColor();
if (bloodcolor!=0) Translation = TRANSLATION(TRANSLATION_Blood, bloodcolor.a);
Translation = BloodTranslation;
}
return false;
}
@ -1707,10 +1708,7 @@ bool AActor::Grind(bool items)
gib->Alpha = Alpha;
gib->Height = 0;
gib->radius = 0;
PalEntry bloodcolor = GetBloodColor();
if (bloodcolor != 0)
gib->Translation = TRANSLATION(TRANSLATION_Blood, bloodcolor.a);
gib->Translation = BloodTranslation;
}
S_Sound (this, CHAN_BODY, "misc/fallingsplat", 1, ATTN_IDLE);
}
@ -3510,7 +3508,7 @@ int AActor::GetMissileDamage (int mask, int add)
void AActor::Howl ()
{
FSoundID howl = IntVar(NAME_HowlSound);
FSoundID howl = SoundVar(NAME_HowlSound);
if (!S_IsActorPlayingSomething(this, CHAN_BODY, howl))
{
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)
{
AActor *th;
PalEntry bloodcolor = originator->GetBloodColor();
PClassActor *bloodcls = originator->GetBloodType();
DVector3 pos = pos1;
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;
}
// 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
@ -6135,7 +6132,7 @@ void P_SpawnBlood (const DVector3 &pos1, DAngle dir, int damage, AActor *origina
}
if (bloodtype >= 1)
P_DrawSplash2 (40, pos, dir, 2, bloodcolor);
P_DrawSplash2 (40, pos, dir, 2, originator->BloodColor);
}
DEFINE_ACTION_FUNCTION(AActor, SpawnBlood)
@ -6159,7 +6156,6 @@ DEFINE_ACTION_FUNCTION(AActor, SpawnBlood)
void P_BloodSplatter (const DVector3 &pos, AActor *originator, DAngle hitangle)
{
PalEntry bloodcolor = originator->GetBloodColor();
PClassActor *bloodcls = originator->GetBloodType(1);
int bloodtype = cl_bloodtype;
@ -6178,16 +6174,16 @@ void P_BloodSplatter (const DVector3 &pos, AActor *originator, DAngle hitangle)
mo->Vel.Z = 3;
// 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)
{
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)
{
PalEntry bloodcolor = originator->GetBloodColor();
PClassActor *bloodcls = originator->GetBloodType(2);
int bloodtype = cl_bloodtype;
@ -6220,16 +6215,16 @@ void P_BloodSplatter2 (const DVector3 &pos, AActor *originator, DAngle hitangle)
mo->target = originator;
// 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)
{
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)
{
PalEntry bloodcolor = bleeder->GetBloodColor();
PClassActor *bloodcls = bleeder->GetBloodType();
double xo = pr_ripperblood.Random2() / 16.;
@ -6281,16 +6275,16 @@ void P_RipperBlood (AActor *mo, AActor *bleeder)
th->tics += pr_ripperblood () & 3;
// 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)
{
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)
("maxhealth", MaxHealth, def->MaxHealth)
("bonushealth", BonusHealth, def->BonusHealth)
("runhealth", RunHealth, def->RunHealth)
("spawnmask", SpawnMask, def->SpawnMask)
("forwardmove1", ForwardMove1, def->ForwardMove1)
@ -1353,7 +1354,7 @@ const char *APlayerPawn::GetSoundClass() const
int APlayerPawn::GetMaxHealth(bool withupgrades) const
{
int ret = MaxHealth > 0? MaxHealth : ((i_compatflags&COMPATF_DEHHEALTH)? 100 : deh.MaxHealth);
if (withupgrades) ret += stamina;
if (withupgrades) ret += stamina + BonusHealth;
return ret;
}
@ -3346,6 +3347,7 @@ bool P_IsPlayerTotallyFrozen(const player_t *player)
DEFINE_FIELD(APlayerPawn, crouchsprite)
DEFINE_FIELD(APlayerPawn, MaxHealth)
DEFINE_FIELD(APlayerPawn, BonusHealth)
DEFINE_FIELD(APlayerPawn, MugShotMaxHealth)
DEFINE_FIELD(APlayerPawn, RunHealth)
DEFINE_FIELD(APlayerPawn, PlayerFlags)

View file

@ -218,8 +218,11 @@ bool FZipFile::Open(bool quiet)
char *dirptr = (char*)directory;
FZipLump *lump_p = Lumps;
// Check if all files have the same prefix so that this can be stripped out.
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++)
{
FZipCentralDirectoryInfo *zip_fh = (FZipCentralDirectoryInfo *)dirptr;
@ -251,6 +254,7 @@ bool FZipFile::Open(bool quiet)
!name.Compare("voxels/") ||
!name.Compare("colormaps/") ||
!name.Compare("acs/") ||
!name.Compare("maps/") ||
!name.Compare("voices/") ||
!name.Compare("patches/") ||
!name.Compare("graphics/") ||
@ -266,6 +270,23 @@ bool FZipFile::Open(bool quiet)
name0 = "";
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 codesize = 0;
int datasize = 0;
FILE *dump = nullptr;
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());
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;
}
@ -944,10 +947,11 @@ void FFunctionBuildList::Build()
}
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);
}
FScriptPosition::StrictErrors = false;
mItems.Clear();
mItems.ShrinkToFit();
FxAlloc.FreeAllBlocks();
}

View file

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

View file

@ -194,7 +194,8 @@ class Actor : Thinker native
native double SelfDamageFactor;
native double StealthAlpha;
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 HitObituary; // Player was killed by this actor in melee

View file

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

View file

@ -86,8 +86,36 @@ class Health : Inventory
}
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

View file

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

View file

@ -95,7 +95,7 @@ class Programmer : Actor
A_PlaySound("programmer/clank", CHAN_WEAPON);
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);
}