- Fixed: Resurrecting a player must set mo->special1 to 0 because it is used

as a counter by the Hexen fighter's fist weapon.
- Fixed: The Wraithwerge's spirits shouldn't attack friends.
- Fixed: The Heresiarch's balls must not adjust their z-position after the
  Heresiarch dies.
- Added damage type specific pain chances and an MF5_NOPAIN flag that can be used
  to suppress entering the pain state altogether.
- Changed font initialization so that you can define replacements for the default
  fonts in FONTDEFS.
- Removed the 'add a bot' menu option since bots are beyond repair and therefore
  mostly useless.
- Fixed: Hitscan attacks must always spawn a puff so that it and its properties
  can be used as damage inflictor.


SVN r534 (trunk)
This commit is contained in:
Christoph Oelckers 2007-05-26 10:50:32 +00:00
parent 73f96e1df6
commit 87383a32c6
13 changed files with 114 additions and 34 deletions

View file

@ -1,3 +1,22 @@
May 26, 2007 (Changes by Graf Zahl)
- Fixed: Resurrecting a player must set mo->special1 to 0 because it is used
as a counter by the Hexen fighter's fist weapon.
May 25, 2007 (Changes by Graf Zahl)
- Fixed: The Wraithwerge's spirits shouldn't attack friends.
- Fixed: The Heresiarch's balls must not adjust their z-position after the
Heresiarch dies.
May 24, 2007 (Changes by Graf Zahl)
- Added damage type specific pain chances and an MF5_NOPAIN flag that can be used
to suppress entering the pain state altogether.
- Changed font initialization so that you can define replacements for the default
fonts in FONTDEFS.
- Removed the 'add a bot' menu option since bots are beyond repair and therefore
mostly useless.
- Fixed: Hitscan attacks must always spawn a puff so that it and its properties
can be used as damage inflictor.
May 20, 2007 (Changes by Graf Zahl)
- Copied railgun sound fix from Skulltag.

View file

@ -290,6 +290,7 @@ enum
MF5_PIERCEARMOR = 0x00000800, // Armor doesn't protect against damage from this actor
MF5_NOBLOODDECALS = 0x00001000, // Actor bleeds but doesn't spawn blood decals
MF5_USESPECIAL = 0x00002000, // Actor executes its special when being 'used'.
MF5_NOPAIN = 0x00004000, // If set the pain state won't be entered
// --- mobj.renderflags ---

View file

@ -233,6 +233,7 @@ PClass *PClass::CreateDerivedClass (FName name, unsigned int size)
info->Replacee = NULL;
info->StateList = NULL;
info->DamageFactors = NULL;
info->PainChances = NULL;
m_RuntimeActors.Push (type);
}
return type;

View file

@ -396,11 +396,15 @@ bool AHolySpirit::IsOkayToAttack (AActor *link)
(link->player && link != target))
&& !(link->flags2&MF2_DORMANT))
{
if (target != NULL && link->IsFriend(target))
{
return false;
}
if (!(link->flags&MF_SHOOTABLE))
{
return false;
}
if (multiplayer && !deathmatch && link->player && target->player)
if (multiplayer && !deathmatch && link->player && target != NULL && target->player)
{
return false;
}

View file

@ -717,7 +717,10 @@ void A_SorcBallOrbit(AActor *ball)
actor = static_cast<ASorcBall *> (ball);
if (actor->target->health <= 0)
{
actor->SetState (actor->FindState(NAME_Pain));
return;
}
baseangle = (angle_t)parent->special1;
angle = baseangle + actor->AngleOffset;

View file

@ -377,6 +377,7 @@ enum
#endif
typedef TMap<FName, fixed_t> DmgFactors;
typedef TMap<FName, BYTE> PainChanceList;
struct FActorInfo
{
@ -408,6 +409,7 @@ struct FActorInfo
SWORD DoomEdNum;
FStateLabels * StateList;
DmgFactors *DamageFactors;
PainChanceList * PainChances;
#if _MSC_VER
// A 0-terminated list of default properties

View file

@ -80,7 +80,7 @@ typedef void (*voidfunc_)();
FActorInfo actor##ActorInfo = {
#define BEGIN_DEFAULTS_POST(actor,game,ednum,id) \
GAME_##game, id, ednum, NULL, NULL,
GAME_##game, id, ednum, NULL, NULL, NULL,
#ifdef WORDS_BIGENDIAN
#define END_DEFAULTS "\xED\x5E" };
@ -133,7 +133,7 @@ extern void ApplyActorDefault (int defnum, int dataint);
FActorInfo actor##ActorInfo = {
#define BEGIN_DEFAULTS_POST(actor,game,ednum,id) \
GAME_##game, id, ednum, NULL, NULL, actor##DefaultsConstructor }; \
GAME_##game, id, ednum, NULL, NULL, NULL, actor##DefaultsConstructor }; \
void actor##DefaultsConstructor() { \
#define END_DEFAULTS }

View file

@ -276,6 +276,8 @@ void cht_DoCheat (player_t *player, int cheat)
player->mo->flags4 = player->mo->GetDefault()->flags4;
player->mo->flags5 = player->mo->GetDefault()->flags5;
player->mo->height = player->mo->GetDefault()->height;
player->mo->special1 = 0; // required for the Hexen fighter's fist attack.
// This gets set by AActor::Die as flag for the wimpy death and must be reset here.
player->mo->SetState (player->mo->SpawnState);
player->mo->Translation = TRANSLATION(TRANSLATION_Players, BYTE(player-players));
player->mo->DamageType = NAME_None;

View file

@ -411,7 +411,6 @@ static menuitem_t ControlsItems[] =
{ whitetext,"Other", {NULL}, {0.0}, {0.0}, {0.0}, {NULL} },
{ control, "Toggle automap", {NULL}, {0.0}, {0.0}, {0.0}, {(value_t *)"togglemap"} },
{ control, "Chasecam", {NULL}, {0.0}, {0.0}, {0.0}, {(value_t *)"chase"} },
{ control, "Add a bot", {NULL}, {0.0}, {0.0}, {0.0}, {(value_t *)"addbot"} },
{ control, "Coop spy", {NULL}, {0.0}, {0.0}, {0.0}, {(value_t *)"spynext"} },
{ control, "Screenshot", {NULL}, {0.0}, {0.0}, {0.0}, {(value_t *)"screenshot"} },
{ control, "Open console", {NULL}, {0.0}, {0.0}, {0.0}, {(value_t *)"toggleconsole"} },

View file

@ -1141,7 +1141,19 @@ void P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage
return;
}
}
if ((pr_damagemobj() < target->PainChance) && !(target->flags & MF_SKULLFLY))
PainChanceList * pc = target->GetClass()->ActorInfo->PainChances;
int painchance = target->PainChance;
if (pc != NULL)
{
BYTE * ppc = pc->CheckKey(mod);
if (ppc != NULL)
{
painchance = *ppc;
}
}
if (!(target->flags5 & MF5_NOPAIN) && (pr_damagemobj() < painchance) && !(target->flags & MF_SKULLFLY))
{
if (inflictor && inflictor->IsKindOf (RUNTIME_CLASS(ALightning)))
{

View file

@ -2782,6 +2782,8 @@ void P_LineAttack (AActor *t1, angle_t angle, fixed_t distance,
angle_t srcangle = angle;
int srcpitch = pitch;
bool hitGhosts;
bool killPuff = false;
AActor *puff = NULL;
angle >>= ANGLETOFINESHIFT;
pitch = (angle_t)(pitch) >> ANGLETOFINESHIFT;
@ -2827,7 +2829,6 @@ void P_LineAttack (AActor *t1, angle_t angle, fixed_t distance,
else
{
fixed_t hitx = 0, hity = 0, hitz = 0;
AActor *puff = NULL;
if (trace.HitType != TRACE_HitActor)
{
@ -2917,12 +2918,18 @@ void P_LineAttack (AActor *t1, angle_t angle, fixed_t distance,
flags |= DMG_NO_ARMOR;
}
if (puff == NULL)
{
// Since the puff is the damage inflictor we need it here
// regardless of whether it is displayed or not.
puff = P_SpawnPuff (pufftype, hitx, hity, hitz, angle - ANG180, 2, true);
killPuff = true;
}
P_DamageMobj (trace.Actor, puff ? puff : t1, t1, damage, damageType, flags);
}
}
if (trace.CrossedWater)
{
bool killPuff = false;
if (puff == NULL)
{ // Spawn puff just to get a mass for the splash
@ -2930,12 +2937,12 @@ void P_LineAttack (AActor *t1, angle_t angle, fixed_t distance,
killPuff = true;
}
SpawnDeepSplash (t1, trace, puff, vx, vy, vz);
if (killPuff)
{
puff->Destroy();
}
}
}
if (killPuff && puff != NULL)
{
puff->Destroy();
}
}
void P_LineAttack (AActor *t1, angle_t angle, fixed_t distance,

View file

@ -229,6 +229,7 @@ static flagdef ActorFlags[]=
DEFINE_FLAG(MF5, PIERCEARMOR, AActor, flags5),
DEFINE_FLAG(MF5, NOBLOODDECALS, AActor, flags5),
DEFINE_FLAG(MF5, USESPECIAL, AActor, flags5),
DEFINE_FLAG(MF5, NOPAIN, AActor, flags5),
// Effect flags
DEFINE_FLAG(FX, VISIBILITYPULSE, AActor, effects),
@ -1181,6 +1182,12 @@ static FActorInfo * CreateNewActor(FActorInfo ** parentc, Baggage *bag)
info->DamageFactors = new DmgFactors;
*info->DamageFactors = *parent->ActorInfo->DamageFactors;
}
if (parent->ActorInfo->PainChances != NULL)
{
// copy pain chances from parent
info->PainChances = new PainChanceList;
*info->PainChances = *parent->ActorInfo->PainChances;
}
// Check for "replaces"
SC_MustGetString ();
@ -2552,7 +2559,18 @@ static void ActorReactionTime (AActor *defaults, Baggage &bag)
//==========================================================================
static void ActorPainChance (AActor *defaults, Baggage &bag)
{
SC_MustGetNumber();
if (!SC_CheckNumber())
{
FName painType;
if (SC_Compare("Normal")) painType = NAME_None;
else painType=sc_String;
SC_MustGetToken(',');
SC_MustGetNumber();
if (bag.Info->PainChances == NULL) bag.Info->PainChances=new PainChanceList;
(*bag.Info->PainChances)[painType] = (BYTE)sc_Number;
return;
}
defaults->PainChance=sc_Number;
}

View file

@ -1907,36 +1907,48 @@ EColorRange V_ParseFontColor (const BYTE *&color_value, int normalcolor, int bol
void V_InitFonts()
{
V_InitFontColors ();
V_InitCustomFonts ();
// load the heads-up font
if (Wads.CheckNumForName ("FONTA_S") >= 0)
if (!(SmallFont = FFont::FindFont("SmallFont")))
{
SmallFont = new FFont ("SmallFont", "FONTA%02u", HU_FONTSTART, HU_FONTSIZE, 1);
if (Wads.CheckNumForName ("FONTA_S") >= 0)
{
SmallFont = new FFont ("SmallFont", "FONTA%02u", HU_FONTSTART, HU_FONTSIZE, 1);
}
else
{
SmallFont = new FFont ("SmallFont", "STCFN%.3d", HU_FONTSTART, HU_FONTSIZE, HU_FONTSTART);
}
}
else
if (!(SmallFont2=FFont::FindFont("SmallFont2")))
{
SmallFont = new FFont ("SmallFont", "STCFN%.3d", HU_FONTSTART, HU_FONTSIZE, HU_FONTSTART);
if (Wads.CheckNumForName ("STBFN033", ns_graphics) >= 0)
{
SmallFont2 = new FFont ("SmallFont2", "STBFN%.3d", HU_FONTSTART, HU_FONTSIZE, HU_FONTSTART);
}
else
{
SmallFont2 = SmallFont;
}
}
if (Wads.CheckNumForName ("STBFN033", ns_graphics) >= 0)
if (!(BigFont=FFont::FindFont("BigFont")))
{
SmallFont2 = new FFont ("SmallFont2", "STBFN%.3d", HU_FONTSTART, HU_FONTSIZE, HU_FONTSTART);
if (gameinfo.gametype == GAME_Doom)
{
BigFont = new FSingleLumpFont ("BigFont", Wads.GetNumForName ("DBIGFONT"));
}
else if (gameinfo.gametype == GAME_Strife)
{
BigFont = new FSingleLumpFont ("BigFont", Wads.GetNumForName ("SBIGFONT"));
}
else
{
BigFont = new FFont ("BigFont", "FONTB%02u", HU_FONTSTART, HU_FONTSIZE, 1);
}
}
else
if (!(ConFont=FFont::FindFont("ConsoleFont")))
{
SmallFont2 = SmallFont;
ConFont = new FSingleLumpFont ("ConsoleFont", Wads.GetNumForName ("CONFONT"));
}
if (gameinfo.gametype == GAME_Doom)
{
BigFont = new FSingleLumpFont ("BigFont", Wads.GetNumForName ("DBIGFONT"));
}
else if (gameinfo.gametype == GAME_Strife)
{
BigFont = new FSingleLumpFont ("BigFont", Wads.GetNumForName ("SBIGFONT"));
}
else
{
BigFont = new FFont ("BigFont", "FONTB%02u", HU_FONTSTART, HU_FONTSIZE, 1);
}
ConFont = new FSingleLumpFont ("ConsoleFont", Wads.GetNumForName ("CONFONT"));
V_InitCustomFonts ();
}