From a6a5821f04bff8a8204cfff10a501325710da2f1 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 12 May 2007 11:14:09 +0000 Subject: [PATCH] - Added a compatibility option to restore the original behavior of the Invisibility powerup. - Changed: Weapons are no longer checked for the EXTREMEDEATH and NOEXTREMEDEATH flags. For all damage related actions it will always be the projectile (or puff for hitscan attacks) that is treated as the damage inflictor. - Fixed: Hexen's fourth weapons made extreme death depend on the weapon the player is holding, not the projectile that did the kill. The WIF_EXTREME_DEATH flag no longer exists as a result. - Expanded PowerSpeed so that subclasses can be derived that alter the speed factor. - Added an MF5_USESPECIAL flag that allows using things to execute their specials. - added MF4_FORCERADIUSDMG flag so that exploding items can be created which are able to hurt boss monsters. - moved ML_BLOCK_PLAYERS to the value 0x4000 to bring it in line with Skulltag's implementation. SVN r530 (trunk) --- docs/rh-log.txt | 16 + src/actor.h | 3 +- src/d_main.cpp | 1 + src/d_player.h | 11 +- src/doomdata.h | 2 +- src/doomdef.h | 1 + src/g_hexen/a_clericholy.cpp | 4 +- src/g_hexen/a_fighterquietus.cpp | 3 +- src/g_hexen/a_magestaff.cpp | 3 +- src/g_level.cpp | 2 + src/g_shared/a_artifacts.cpp | 26 +- src/g_shared/a_artifacts.h | 3 +- src/g_shared/a_pickups.cpp | 18 + src/g_shared/a_pickups.h | 3 +- src/m_options.cpp | 1 + src/p_enemy.cpp | 4 +- src/p_interaction.cpp | 11 +- src/p_map.cpp | 8 +- src/p_teleport.cpp | 2 +- src/p_user.cpp | 9 +- src/thingdef.cpp | 173 ++++- zdoom.vcproj | 1248 +++++++++++++++--------------- 22 files changed, 876 insertions(+), 676 deletions(-) diff --git a/docs/rh-log.txt b/docs/rh-log.txt index 14b4faaeb..8552f09ae 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -1,3 +1,19 @@ +May 12, 2007 (Changes by Graf Zahl) +- Added a compatibility option to restore the original behavior of the Invisibility + powerup. +- Changed: Weapons are no longer checked for the EXTREMEDEATH and NOEXTREMEDEATH flags. + For all damage related actions it will always be the projectile (or puff for hitscan + attacks) that is treated as the damage inflictor. +- Fixed: Hexen's fourth weapons made extreme death depend on the weapon the player + is holding, not the projectile that did the kill. The WIF_EXTREME_DEATH flag + no longer exists as a result. +- Expanded PowerSpeed so that subclasses can be derived that alter the speed factor. +- Added an MF5_USESPECIAL flag that allows using things to execute their specials. +- added MF4_FORCERADIUSDMG flag so that exploding items can be created which + are able to hurt boss monsters. +- moved ML_BLOCK_PLAYERS to the value 0x4000 to bring it in line with Skulltag's + implementation. + May 9, 2007 (Changes by Graf Zahl) - added Skulltag's custom F1 help screen MAPINFO option. diff --git a/src/actor.h b/src/actor.h index b500236de..aa0065fdc 100644 --- a/src/actor.h +++ b/src/actor.h @@ -255,7 +255,7 @@ enum MF4_CANUSEWALLS = 0x00000200, // Can activate 'use' specials MF4_MISSILEMORE = 0x00000400, // increases the chance of a missile attack MF4_MISSILEEVENMORE = 0x00000800, // significantly increases the chance of a missile attack - // unused flag + MF4_FORCERADIUSDMG = 0x00001000, // if put on an object it will override MF3_NORADIUSDMG MF4_DONTFALL = 0x00002000, // Doesn't have NOGRAVITY disabled when dying. MF4_SEESDAGGERS = 0x00004000, // This actor can see you striking with a dagger MF4_INCOMBAT = 0x00008000, // Don't alert others when attacked by a dagger @@ -289,6 +289,7 @@ enum MF5_DEHEXPLOSION = 0x00000400, // Use the DEHACKED explosion options when this projectile explodes 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'. // --- mobj.renderflags --- diff --git a/src/d_main.cpp b/src/d_main.cpp index ee30a88e3..ec3369af4 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -400,6 +400,7 @@ CVAR (Flag, compat_dehhealth, compatflags, COMPATF_DEHHEALTH); CVAR (Flag, compat_trace, compatflags, COMPATF_TRACE); CVAR (Flag, compat_dropoff, compatflags, COMPATF_DROPOFF); CVAR (Flag, compat_boomscroll, compatflags, COMPATF_BOOMSCROLL); +CVAR (Flag, compat_invisibility,compatflags, COMPATF_INVISIBILITY); //========================================================================== // diff --git a/src/d_player.h b/src/d_player.h index df59b5569..951f50864 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -162,12 +162,11 @@ typedef enum CF_WEAPONREADY = 16384, // [RH] Weapon is in the ready state, so bob it when walking CF_TIMEFREEZE = 32768, // Player has an active time freezer CF_DRAIN = 65536, // Player owns a drain powerup - CF_SPEED = 0x20000, // Player owns a speed artifact - CF_REGENERATION = 0x40000, // Player owns a regeneration artifact - CF_HIGHJUMP = 0x80000, // more Skulltag flags. Implemetation not guaranteed though. ;) - CF_REFLECTION = 0x100000, - CF_PROSPERITY = 0x200000, - CF_DOUBLEFIRINGSPEED= 0x400000, + CF_REGENERATION = 0x20000, // Player owns a regeneration artifact + CF_HIGHJUMP = 0x40000, // more Skulltag flags. Implemetation not guaranteed though. ;) + CF_REFLECTION = 0x80000, + CF_PROSPERITY = 0x100000, + CF_DOUBLEFIRINGSPEED= 0x200000, } cheat_t; #define WPIECE1 1 diff --git a/src/doomdata.h b/src/doomdata.h index 0f3e875b4..bac559f85 100644 --- a/src/doomdata.h +++ b/src/doomdata.h @@ -151,6 +151,7 @@ static inline int GET_SPAC (int flags) // [RH] Monsters (as well as players) can active the line #define ML_MONSTERSCANACTIVATE 0x2000 +#define ML_BLOCK_PLAYERS 0x4000 // [RH] BOOM's ML_PASSUSE flag (conflicts with ML_REPEATSPECIAL) #define ML_PASSUSE_BOOM 0x0200 @@ -175,7 +176,6 @@ static inline int GET_SPAC (int flags) #define ML_BLOCK_FLOATERS 0x00040000 #define ML_CLIP_MIDTEX 0x00080000 // Automatic for every Strife line #define ML_WRAP_MIDTEX 0x00100000 -#define ML_BLOCK_PLAYERS 0x00200000 // Sector definition, from editing typedef struct diff --git a/src/doomdef.h b/src/doomdef.h index 125c27d02..d19d875c3 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -275,6 +275,7 @@ enum COMPATF_TRACE = 1 << 13, // Trace ignores lines with the same sector on both sides COMPATF_DROPOFF = 1 << 14, // Monsters cannot move when hanging over a dropoff COMPATF_BOOMSCROLL = 1 << 15, // Scrolling sectors are additive like in Boom + COMPATF_INVISIBILITY = 1 << 16, // Monsters can see semi-invisible players }; // phares 3/20/98: diff --git a/src/g_hexen/a_clericholy.cpp b/src/g_hexen/a_clericholy.cpp index 0276cc6b9..875061497 100644 --- a/src/g_hexen/a_clericholy.cpp +++ b/src/g_hexen/a_clericholy.cpp @@ -198,7 +198,7 @@ IMPLEMENT_ACTOR (ACWeapWraithverge, Hexen, -1, 0) PROP_SpawnState (0) PROP_Weapon_SelectionOrder (3000) - PROP_Weapon_Flags (WIF_PRIMARY_USES_BOTH | WIF_EXTREME_DEATH) + PROP_Weapon_Flags (WIF_PRIMARY_USES_BOTH) PROP_Weapon_AmmoUse1 (18) PROP_Weapon_AmmoUse2 (18) PROP_Weapon_AmmoGive1 (0) @@ -238,6 +238,7 @@ IMPLEMENT_ACTOR (AHolyMissile, Hexen, -1, 0) PROP_Damage (4) PROP_Flags (MF_NOBLOCKMAP|MF_NOGRAVITY|MF_DROPOFF|MF_MISSILE) PROP_Flags2 (MF2_NOTELEPORT) + PROP_Flags4 (MF4_EXTREMEDEATH) PROP_SpawnState (0) PROP_DeathState (4) @@ -322,6 +323,7 @@ IMPLEMENT_ACTOR (AHolySpirit, Hexen, -1, 0) PROP_Flags (MF_NOBLOCKMAP|MF_NOGRAVITY|MF_DROPOFF|MF_MISSILE) PROP_Flags2 (MF2_NOTELEPORT|MF2_RIP|MF2_IMPACT|MF2_PCROSS|MF2_SEEKERMISSILE) PROP_Flags3 (MF3_FOILINVUL|MF3_SKYEXPLODE|MF3_NOEXPLODEFLOOR|MF3_CANBLAST) + PROP_Flags4 (MF4_EXTREMEDEATH) PROP_RenderStyle (STYLE_Translucent) PROP_Alpha (HX_ALTSHADOW) diff --git a/src/g_hexen/a_fighterquietus.cpp b/src/g_hexen/a_fighterquietus.cpp index 12928be9d..cafd4106e 100644 --- a/src/g_hexen/a_fighterquietus.cpp +++ b/src/g_hexen/a_fighterquietus.cpp @@ -188,7 +188,7 @@ IMPLEMENT_ACTOR (AFWeapQuietus, Hexen, -1, 0) PROP_SpawnState (0) PROP_Weapon_SelectionOrder (2900) - PROP_Weapon_Flags (WIF_PRIMARY_USES_BOTH | WIF_EXTREME_DEATH) + PROP_Weapon_Flags (WIF_PRIMARY_USES_BOTH) PROP_Weapon_AmmoUse1 (14) PROP_Weapon_AmmoUse2 (14) PROP_Weapon_AmmoGive1 (0) @@ -242,6 +242,7 @@ IMPLEMENT_ACTOR (AFSwordMissile, Hexen, -1, 0) PROP_Damage (8) PROP_Flags (MF_NOBLOCKMAP|MF_NOGRAVITY|MF_DROPOFF|MF_MISSILE) PROP_Flags2 (MF2_NOTELEPORT|MF2_IMPACT|MF2_PCROSS) + PROP_Flags4 (MF4_EXTREMEDEATH) PROP_RenderStyle (STYLE_Add) PROP_SpawnState (S_FSWORD_MISSILE1) diff --git a/src/g_hexen/a_magestaff.cpp b/src/g_hexen/a_magestaff.cpp index 0c97c4e27..21c0dfe0d 100644 --- a/src/g_hexen/a_magestaff.cpp +++ b/src/g_hexen/a_magestaff.cpp @@ -218,7 +218,7 @@ IMPLEMENT_ACTOR (AMWeapBloodscourge, Hexen, -1, 0) PROP_SpawnState (0) PROP_Weapon_SelectionOrder (3100) - PROP_Weapon_Flags (WIF_PRIMARY_USES_BOTH | WIF_EXTREME_DEATH) + PROP_Weapon_Flags (WIF_PRIMARY_USES_BOTH) PROP_Weapon_AmmoUse1 (15) PROP_Weapon_AmmoUse2 (15) PROP_Weapon_UpState (S_MSTAFFUP) @@ -274,6 +274,7 @@ IMPLEMENT_ACTOR (AMageStaffFX2, Hexen, -1, 0) PROP_DamageType (NAME_Fire) PROP_Flags (MF_NOBLOCKMAP|MF_NOGRAVITY|MF_DROPOFF|MF_MISSILE) PROP_Flags2 (MF2_NOTELEPORT|MF2_IMPACT|MF2_PCROSS|MF2_SEEKERMISSILE) + PROP_Flags4 (MF4_EXTREMEDEATH) PROP_SpawnState (S_MSTAFF_FX2_1) PROP_DeathState (S_MSTAFF_FX2_X1) diff --git a/src/g_level.cpp b/src/g_level.cpp index 0cea81b59..ba6b046d4 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -281,6 +281,7 @@ static const char *MapInfoMapLevel[] = "compat_trace", "compat_dropoff", "compat_boomscroll", + "compat_invisibility", "bordertexture", "f1", // [RC] F1 help NULL @@ -415,6 +416,7 @@ MapHandlers[] = { MITYPE_COMPATFLAG, COMPATF_TRACE}, { MITYPE_COMPATFLAG, COMPATF_DROPOFF}, { MITYPE_COMPATFLAG, COMPATF_BOOMSCROLL}, + { MITYPE_COMPATFLAG, COMPATF_INVISIBILITY}, { MITYPE_LUMPNAME, lioffset(bordertexture), 0 }, { MITYPE_F1, lioffset(f1), 0, }, }; diff --git a/src/g_shared/a_artifacts.cpp b/src/g_shared/a_artifacts.cpp index edd72c8f5..479317ba0 100644 --- a/src/g_shared/a_artifacts.cpp +++ b/src/g_shared/a_artifacts.cpp @@ -1163,19 +1163,21 @@ void APlayerSpeedTrail::Tick () // Speed Powerup ------------------------------------------------------------- IMPLEMENT_STATELESS_ACTOR (APowerSpeed, Any, -1, 0) + PROP_SpeedFixed(3*FRACUNIT/2) PROP_Powerup_EffectTics (SPEEDTICS) PROP_Inventory_Icon ("SPBOOT0") END_DEFAULTS //=========================================================================== // -// APowerSpeed :: InitEffect +// APowerSpeed :: GetSpeedFactor // //=========================================================================== -void APowerSpeed::InitEffect () +fixed_t APowerSpeed ::GetSpeedFactor () { - Owner->player->cheats |= CF_SPEED; + if (Inventory != NULL) return FixedMul(Speed, Inventory->GetSpeedFactor()); + else return Speed; } //=========================================================================== @@ -1194,6 +1196,10 @@ void APowerSpeed::DoEffect () if (level.time & 1) return; + // check if another speed item is present to avoid multiple drawing of the speed trail. + if (Inventory != NULL && Inventory->GetSpeedFactor() > FRACUNIT) + return; + if (P_AproxDistance (Owner->momx, Owner->momy) <= 12*FRACUNIT) return; @@ -1219,20 +1225,6 @@ void APowerSpeed::DoEffect () } } -//=========================================================================== -// -// APowerSpeed :: EndEffect -// -//=========================================================================== - -void APowerSpeed::EndEffect () -{ - if (Owner != NULL && Owner->player != NULL) - { - Owner->player->cheats &= ~CF_SPEED; - } -} - // Minotaur (aka Dark Servant) powerup --------------------------------------- IMPLEMENT_STATELESS_ACTOR (APowerMinotaur, Any, -1, 0) diff --git a/src/g_shared/a_artifacts.h b/src/g_shared/a_artifacts.h index 027a4ce2c..404c08299 100644 --- a/src/g_shared/a_artifacts.h +++ b/src/g_shared/a_artifacts.h @@ -170,9 +170,8 @@ class APowerSpeed : public APowerup { DECLARE_STATELESS_ACTOR (APowerSpeed, APowerup) protected: - void InitEffect (); void DoEffect (); - void EndEffect (); + fixed_t GetSpeedFactor(); }; class APowerMinotaur : public APowerup diff --git a/src/g_shared/a_pickups.cpp b/src/g_shared/a_pickups.cpp index dec3fa83c..c5e4f86aa 100644 --- a/src/g_shared/a_pickups.cpp +++ b/src/g_shared/a_pickups.cpp @@ -783,6 +783,24 @@ void AInventory::ModifyDamage (int damage, FName damageType, int &newdamage, boo } } +//=========================================================================== +// +// AInventory :: GetSpeedFactor +// +//=========================================================================== + +fixed_t AInventory::GetSpeedFactor () +{ + if (Inventory != NULL) + { + return Inventory->GetSpeedFactor(); + } + else + { + return FRACUNIT; + } +} + //=========================================================================== // // AInventory :: AlterWeaponSprite diff --git a/src/g_shared/a_pickups.h b/src/g_shared/a_pickups.h index 69a561451..eba565499 100644 --- a/src/g_shared/a_pickups.h +++ b/src/g_shared/a_pickups.h @@ -153,6 +153,7 @@ public: virtual void AbsorbDamage (int damage, FName damageType, int &newdamage); virtual void ModifyDamage (int damage, FName damageType, int &newdamage, bool passive); + virtual fixed_t GetSpeedFactor(); virtual int AlterWeaponSprite (vissprite_t *vis); virtual PalEntry GetBlend (); @@ -265,7 +266,7 @@ enum WIF_ALT_USES_BOTH = 0x00000100, // alternate fire uses both ammo WIF_WIMPY_WEAPON = 0x00000200, // change away when ammo for another weapon is replenished WIF_POWERED_UP = 0x00000400, // this is a tome-of-power'ed version of its sister - WIF_EXTREME_DEATH = 0x00000800, // weapon always causes an extreme death + WIF_NO_AUTO_SWITCH = 0x00001000, // never switch to this weapon when it's picked up WIF_STAFF2_KICKBACK = 0x00002000, // the powered-up Heretic staff has special kickback diff --git a/src/m_options.cpp b/src/m_options.cpp index 2bdef69c4..62fa6c622 100644 --- a/src/m_options.cpp +++ b/src/m_options.cpp @@ -1024,6 +1024,7 @@ static menuitem_t CompatibilityItems[] = { { bitflag, "DEH health settings like Doom2.exe", {&compatflags}, {0}, {0}, {0}, {(value_t *)COMPATF_DEHHEALTH} }, { bitflag, "Self ref. sectors don't block shots", {&compatflags}, {0}, {0}, {0}, {(value_t *)COMPATF_TRACE} }, { bitflag, "Monsters get stuck over dropoffs", {&compatflags}, {0}, {0}, {0}, {(value_t *)COMPATF_DROPOFF} }, + { bitflag, "Monsters see invisible players", {&compatflags}, {0}, {0}, {0}, {(value_t *)COMPATF_INVISIBILITY} }, { bitflag, "Boom scrollers are additive", {&compatflags}, {0}, {0}, {0}, {(value_t *)COMPATF_BOOMSCROLL} }, { discrete, "Interpolate monster movement", {&nomonsterinterpolation}, {2.0}, {0.0}, {0.0}, {NoYes} }, diff --git a/src/p_enemy.cpp b/src/p_enemy.cpp index efe7bad17..c2ee1e4bf 100644 --- a/src/p_enemy.cpp +++ b/src/p_enemy.cpp @@ -1512,8 +1512,8 @@ bool P_LookForPlayers (AActor *actor, INTBOOL allaround) continue; // behind back } } - if (player->mo->RenderStyle == STYLE_Translucent || - player->mo->RenderStyle == STYLE_OptFuzzy) + if ((player->mo->flags & MF_SHADOW && !(i_compatflags & COMPATF_INVISIBILITY)) || + player->mo->flags3 & MF3_GHOST) { if ((P_AproxDistance (player->mo->x - actor->x, player->mo->y - actor->y) > 2*MELEERANGE) diff --git a/src/p_interaction.cpp b/src/p_interaction.cpp index b73836bf4..fd53f6282 100644 --- a/src/p_interaction.cpp +++ b/src/p_interaction.cpp @@ -629,8 +629,7 @@ void AActor::Die (AActor *source, AActor *inflictor) } if (diestate == NULL) { - int flags4 = !inflictor ? 0 : inflictor->player && inflictor->player->ReadyWeapon ? - inflictor->player->ReadyWeapon->flags4 : inflictor->flags4; + int flags4 = inflictor == NULL ? 0 : inflictor->flags4; int gibhealth = -abs(GetClass()->Meta.GetMetaInt (AMETA_GibHealth, gameinfo.gametype == GAME_Doom ? -GetDefault()->health : -GetDefault()->health/2)); @@ -904,7 +903,7 @@ void P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage // Handle passive damage modifiers (e.g. PowerProtection) if (target->Inventory != NULL) { - int olddam = damage; + int olddam = damage; target->Inventory->ModifyDamage(olddam, mod, damage, true); if (olddam != damage && damage <= 0) return; } @@ -1127,12 +1126,6 @@ void P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage source = source->tracer; } } - if (source && (source->player) && source->player->ReadyWeapon != NULL && - (source->player->ReadyWeapon->WeaponFlags & WIF_EXTREME_DEATH)) - { - // Always extreme death from fourth weapon - target->health = -target->GetDefault()->health * 3; - } target->Die (source, inflictor); return; } diff --git a/src/p_map.cpp b/src/p_map.cpp index 0433f92ff..4a94ca73f 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -3267,10 +3267,10 @@ bool PTR_UseTraverse (intercept_t *in) if (usething==in->d.thing) return true; // Check thing - // Check for puzzle item use - if (in->d.thing->special == USE_PUZZLE_ITEM_SPECIAL) + // Check for puzzle item use or USESPECIAL flag + if (in->d.thing->flags5 & MF5_USESPECIAL || in->d.thing->special == USE_PUZZLE_ITEM_SPECIAL) { - if (LineSpecials[USE_PUZZLE_ITEM_SPECIAL] (NULL, usething, false, + if (LineSpecials[in->d.thing->special] (NULL, usething, false, in->d.thing->args[0], in->d.thing->args[1], in->d.thing->args[2], in->d.thing->args[3], in->d.thing->args[4])) return false; @@ -3565,7 +3565,7 @@ bool PIT_RadiusAttack (AActor *thing) // Boss spider and cyborg and Heretic's ep >= 2 bosses // take no damage from concussion. - if (thing->flags3 & MF3_NORADIUSDMG) + if (thing->flags3 & MF3_NORADIUSDMG && !(bombspot->flags4 & MF4_FORCERADIUSDMG)) return true; if (!DamageSource && thing == bombsource) diff --git a/src/p_teleport.cpp b/src/p_teleport.cpp index 95e8ba868..272ea630f 100644 --- a/src/p_teleport.cpp +++ b/src/p_teleport.cpp @@ -306,7 +306,7 @@ bool P_Teleport (AActor *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle, if (thing->player && (useFog || !keepOrientation)) { // Freeze player for about .5 sec - if (!(thing->player->cheats & CF_SPEED)) + if (thing->Inventory == NULL || thing->Inventory->GetSpeedFactor() <= FRACUNIT) thing->reactiontime = 18; } if (thing->flags & MF_MISSILE) diff --git a/src/p_user.cpp b/src/p_user.cpp index 6b5955cc7..a3f756c31 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -1120,10 +1120,11 @@ void APlayerPawn::TweakSpeeds (int &forward, int &side) side = FixedMul (side, SideMove2); } - if ((player->cheats & CF_SPEED) && !player->morphTics) - { // Adjust for a player with a speed artifact - forward = (3*forward)>>1; - side = (3*side)>>1; + if (!player->morphTics && Inventory != NULL) + { + fixed_t factor = Inventory->GetSpeedFactor (); + forward = FixedMul(forward, factor); + side = FixedMul(side, factor); } } diff --git a/src/thingdef.cpp b/src/thingdef.cpp index 7b7e5c203..3e649ab7c 100644 --- a/src/thingdef.cpp +++ b/src/thingdef.cpp @@ -195,6 +195,7 @@ static flagdef ActorFlags[]= DEFINE_FLAG(MF4, CANUSEWALLS, AActor, flags4), DEFINE_FLAG(MF4, MISSILEMORE, AActor, flags4), DEFINE_FLAG(MF4, MISSILEEVENMORE, AActor, flags4), + DEFINE_FLAG(MF4, FORCERADIUSDMG, AActor, flags4), DEFINE_FLAG(MF4, DONTFALL, AActor, flags4), DEFINE_FLAG(MF4, SEESDAGGERS, AActor, flags4), DEFINE_FLAG(MF4, INCOMBAT, AActor, flags4), @@ -227,6 +228,7 @@ static flagdef ActorFlags[]= DEFINE_FLAG(MF5, DEHEXPLOSION, AActor, flags5), DEFINE_FLAG(MF5, PIERCEARMOR, AActor, flags5), DEFINE_FLAG(MF5, NOBLOODDECALS, AActor, flags5), + DEFINE_FLAG(MF5, USESPECIAL, AActor, flags5), // Effect flags DEFINE_FLAG(FX, VISIBILITYPULSE, AActor, effects), @@ -4467,12 +4469,181 @@ void ParseClass() } } + +bool ParseFunctionCall(Baggage &bag, FState & state) +{ + // Make the action name lowercase to satisfy the gperf hashers + strlwr (sc_String); + FString funcname = sc_String; + + int minreq=0; + memset(&state, 0, sizeof(state)); + if (DoSpecialFunctions(state, false, &minreq, bag)) + { + return true; + } + + PSymbol *sym = bag.Info->Class->Symbols.FindSymbol (FName(sc_String, true), true); + if (sym != NULL && sym->SymbolType == SYM_ActionFunction) + { + PSymbolActionFunction *afd = static_cast(sym); + state.Action = afd->Function; + if (!afd->Arguments.IsEmpty()) + { + const char *params = afd->Arguments.GetChars(); + int numparams = (int)afd->Arguments.Len(); + + int v; + + if (!islower(*params)) + { + SC_MustGetToken('('); + } + else + { + if (!SC_CheckToken('(')) + { + return true; + } + } + + int paramindex = PrepareStateParameters(&state, numparams); + int paramstart = paramindex; + bool varargs = params[numparams - 1] == '+'; + + if (varargs) + { + StateParameters[paramindex++] = 0; + } + + while (*params) + { + switch(*params) + { + case 'I': + case 'i': // Integer + SC_MustGetNumber(); + v=sc_Number; + break; + + case 'F': + case 'f': // Fixed point + SC_MustGetFloat(); + v=fixed_t(sc_Float*FRACUNIT); + break; + + + case 'S': + case 's': // Sound name + SC_MustGetString(); + v=S_FindSound(sc_String); + break; + + case 'M': + case 'm': // Actor name + case 'T': + case 't': // String + SC_MustGetString(); + v = (int)(sc_String[0] ? FName(sc_String) : NAME_None); + break; + + case 'L': + case 'l': // Jump label + + SC_ScriptError("You cannot use state jump calls in action functions (%s tries to call %s)\n", + funcname.GetChars(), afd->SymbolName.GetChars()); + break; + + case 'C': + case 'c': // Color + SC_MustGetString (); + if (SC_Compare("none")) + { + v = -1; + } + else + { + int c = V_GetColor (NULL, sc_String); + // 0 needs to be the default so we have to mark the color. + v = MAKEARGB(1, RPART(c), GPART(c), BPART(c)); + } + break; + + case 'X': + case 'x': + v = ParseExpression (false, bag.Info->Class); + break; + + case 'Y': + case 'y': + v = ParseExpression (true, bag.Info->Class); + break; + + default: + assert(false); + v = -1; + break; + } + StateParameters[paramindex++] = v; + params++; + if (varargs) + { + StateParameters[paramstart]++; + } + if (*params) + { + if (*params == '+') + { + if (SC_CheckString(")")) + { + return true; + } + params--; + v = 0; + StateParameters.Push(v); + } + else if ((islower(*params) || *params=='!') && SC_CheckString(")")) + { + return true; + } + SC_MustGetStringName (","); + } + } + SC_MustGetStringName(")"); + } + else + { + SC_MustGetString(); + if (SC_Compare("(")) + { + SC_ScriptError("You cannot pass parameters to '%s'\n",funcname.GetChars()); + } + SC_UnGet(); + } + return true; + } + return false; +} + void ParseActionFunction() { + FState state; + Baggage bag; + bag.Info=RUNTIME_CLASS(AActor)->ActorInfo; + // for now only void functions with no parameters SC_MustGetToken(TK_Void); SC_MustGetString(); FName funcname = sc_String; SC_MustGetToken('('); SC_MustGetToken(')'); -} \ No newline at end of file + SC_MustGetToken('{'); + // All this can do for the moment is parse a list of simple function calls, nothing more + while (SC_MustGetString(), sc_TokenType != '}'); + { + ParseFunctionCall(bag, state); + SC_MustGetToken(';'); + // Todo: Take the state's content and make a list of it. + } + +} diff --git a/zdoom.vcproj b/zdoom.vcproj index d9e4df07b..972b09ced 100644 --- a/zdoom.vcproj +++ b/zdoom.vcproj @@ -1,7 +1,7 @@ + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - @@ -2725,6 +2717,14 @@ GeneratePreprocessedFile="0" /> + + + @@ -2747,7 +2747,7 @@ /> + + + @@ -4768,16 +4778,6 @@ Outputs="$(IntDir)/$(InputName).obj" /> - - - @@ -4798,7 +4798,17 @@ + + + @@ -4812,16 +4822,6 @@ Outputs="$(IntDir)/$(InputName).obj" /> - - - @@ -4842,7 +4842,17 @@ + + + @@ -4856,16 +4866,6 @@ Outputs="$(IntDir)\$(InputName).obj" /> - - - @@ -4886,7 +4886,17 @@ + + + @@ -4900,16 +4910,6 @@ Outputs="$(IntDir)\$(InputName).obj" /> - - - @@ -4930,7 +4930,17 @@ + + + @@ -4944,16 +4954,6 @@ Outputs="$(IntDir)\$(InputName).obj" /> - - - @@ -5033,7 +5033,7 @@ /> - - - @@ -5380,6 +5372,14 @@ Outputs="$(IntDir)\$(InputName).obj" /> + + + + + + @@ -5606,14 +5614,6 @@ GeneratePreprocessedFile="0" /> - - - @@ -5635,7 +5635,7 @@ /> - - - @@ -9124,6 +9116,14 @@ AdditionalIncludeDirectories="src\win32;$(NoInherit)" /> + + + @@ -9298,7 +9298,7 @@ />