From 87383a32c6f198da5c65507330e5630fa9ace8c3 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 26 May 2007 10:50:32 +0000 Subject: [PATCH] - 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) --- docs/rh-log.txt | 19 ++++++++++++ src/actor.h | 1 + src/dobjtype.cpp | 1 + src/g_hexen/a_clericholy.cpp | 6 +++- src/g_hexen/a_heresiarch.cpp | 3 ++ src/info.h | 2 ++ src/infomacros.h | 4 +-- src/m_cheat.cpp | 2 ++ src/m_options.cpp | 1 - src/p_interaction.cpp | 14 ++++++++- src/p_map.cpp | 19 ++++++++---- src/thingdef.cpp | 20 ++++++++++++- src/v_font.cpp | 56 ++++++++++++++++++++++-------------- 13 files changed, 114 insertions(+), 34 deletions(-) diff --git a/docs/rh-log.txt b/docs/rh-log.txt index 05e6f846a..0901563ab 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -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. diff --git a/src/actor.h b/src/actor.h index aa0065fdc..7f96fba04 100644 --- a/src/actor.h +++ b/src/actor.h @@ -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 --- diff --git a/src/dobjtype.cpp b/src/dobjtype.cpp index fc3e092ff..ff4afc30c 100644 --- a/src/dobjtype.cpp +++ b/src/dobjtype.cpp @@ -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; diff --git a/src/g_hexen/a_clericholy.cpp b/src/g_hexen/a_clericholy.cpp index 875061497..e9b5c6ad0 100644 --- a/src/g_hexen/a_clericholy.cpp +++ b/src/g_hexen/a_clericholy.cpp @@ -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; } diff --git a/src/g_hexen/a_heresiarch.cpp b/src/g_hexen/a_heresiarch.cpp index cf3fad2d4..7a17c9860 100644 --- a/src/g_hexen/a_heresiarch.cpp +++ b/src/g_hexen/a_heresiarch.cpp @@ -717,7 +717,10 @@ void A_SorcBallOrbit(AActor *ball) actor = static_cast (ball); if (actor->target->health <= 0) + { actor->SetState (actor->FindState(NAME_Pain)); + return; + } baseangle = (angle_t)parent->special1; angle = baseangle + actor->AngleOffset; diff --git a/src/info.h b/src/info.h index e5d879e6e..cc1d13352 100644 --- a/src/info.h +++ b/src/info.h @@ -377,6 +377,7 @@ enum #endif typedef TMap DmgFactors; +typedef TMap 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 diff --git a/src/infomacros.h b/src/infomacros.h index 19c5a40cb..2925fd5a5 100644 --- a/src/infomacros.h +++ b/src/infomacros.h @@ -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 } diff --git a/src/m_cheat.cpp b/src/m_cheat.cpp index ae46a7d4d..57e0f93cb 100644 --- a/src/m_cheat.cpp +++ b/src/m_cheat.cpp @@ -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; diff --git a/src/m_options.cpp b/src/m_options.cpp index 01f2d398a..e9584e573 100644 --- a/src/m_options.cpp +++ b/src/m_options.cpp @@ -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"} }, diff --git a/src/p_interaction.cpp b/src/p_interaction.cpp index 6a7cbe655..1173744ae 100644 --- a/src/p_interaction.cpp +++ b/src/p_interaction.cpp @@ -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))) { diff --git a/src/p_map.cpp b/src/p_map.cpp index 17838c999..faa7c5c37 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -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, diff --git a/src/thingdef.cpp b/src/thingdef.cpp index 3e649ab7c..5735375f7 100644 --- a/src/thingdef.cpp +++ b/src/thingdef.cpp @@ -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; } diff --git a/src/v_font.cpp b/src/v_font.cpp index 74fd38fc6..c05d61f44 100644 --- a/src/v_font.cpp +++ b/src/v_font.cpp @@ -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 (); }