From 460c400315778d3c5a614216c2b498f1afcaad4c Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 25 Nov 2018 01:12:45 +0100 Subject: [PATCH] - scriptified ApplyKickback. --- src/gi.cpp | 1 + src/p_interaction.cpp | 83 ++------------------- wadsrc/static/zscript.txt | 1 + wadsrc/static/zscript/actor_interaction.txt | 79 ++++++++++++++++++++ wadsrc/static/zscript/base.txt | 1 + wadsrc/static/zscript/constants.txt | 1 + 6 files changed, 88 insertions(+), 78 deletions(-) create mode 100644 wadsrc/static/zscript/actor_interaction.txt diff --git a/src/gi.cpp b/src/gi.cpp index 38aa76d1f3..45deb93ea0 100644 --- a/src/gi.cpp +++ b/src/gi.cpp @@ -62,6 +62,7 @@ DEFINE_FIELD_X(GameInfoStruct, gameinfo_t, statusscreen_coop) DEFINE_FIELD_X(GameInfoStruct, gameinfo_t, statusscreen_dm) DEFINE_FIELD_X(GameInfoStruct, gameinfo_t, mSliderColor) DEFINE_FIELD_X(GameInfoStruct, gameinfo_t, telefogheight) +DEFINE_FIELD_X(GameInfoStruct, gameinfo_t, defKickback) const char *GameNames[17] = diff --git a/src/p_interaction.cpp b/src/p_interaction.cpp index 33f131a4d2..fd7f53fbe4 100644 --- a/src/p_interaction.cpp +++ b/src/p_interaction.cpp @@ -68,7 +68,6 @@ FRandom pr_damagemobj ("ActorTakeDamage"); static FRandom pr_lightning ("LightningDamage"); static FRandom pr_poison ("PoisonDamage"); static FRandom pr_switcher ("SwitchTarget"); -static FRandom pr_kickbackdir ("KickbackDir"); CVAR (Bool, cl_showsprees, true, CVAR_ARCHIVE) CVAR (Bool, cl_showmultikills, true, CVAR_ARCHIVE) @@ -908,80 +907,6 @@ void P_AutoUseStrifeHealth (player_t *player) ================== */ -void ApplyKickback(AActor *target, AActor *inflictor, AActor *source, int damage, DAngle angle, FName mod, int flags) -{ - DAngle ang; - int kickback; - double thrust; - - if (inflictor && inflictor->projectileKickback) - kickback = inflictor->projectileKickback; - else if (!source || !source->player || !source->player->ReadyWeapon) - kickback = gameinfo.defKickback; - else - kickback = source->player->ReadyWeapon->Kickback; - - kickback = int(kickback * G_SkillProperty(SKILLP_KickbackFactor)); - if (kickback) - { - AActor *origin = (source && (flags & DMG_INFLICTOR_IS_PUFF)) ? source : inflictor; - - if (flags & DMG_USEANGLE) - { - ang = angle; - } - else if (origin->X() == target->X() && origin->Y() == target->Y()) - { - // If the origin and target are in exactly the same spot, choose a random direction. - // (Most likely cause is from telefragging somebody during spawning because they - // haven't moved from their spawn spot at all.) - ang = pr_kickbackdir.GenRand_Real2() * 360.; - } - else - { - ang = origin->AngleTo(target); - } - - thrust = mod == NAME_MDK ? 10 : 32; - if (target->Mass > 0) - { - thrust = clamp((damage * 0.125 * kickback) / target->Mass, 0., thrust); - } - - // Don't apply ultra-small damage thrust - if (thrust < 0.01) thrust = 0; - - // make fall forwards sometimes - if ((damage < 40) && (damage > target->health) - && (target->Z() - origin->Z() > 64) - && (pr_damagemobj() & 1) - // [RH] But only if not too fast and not flying - && thrust < 10 - && !(target->flags & MF_NOGRAVITY) - && (inflictor == NULL || !(inflictor->flags5 & MF5_NOFORWARDFALL)) - ) - { - ang += 180.; - thrust *= 4; - } - if (source && source->player && (flags & DMG_INFLICTOR_IS_PUFF) - && source->player->ReadyWeapon != NULL && - (source->player->ReadyWeapon->WeaponFlags & WIF_STAFF2_KICKBACK)) - { - // Staff power level 2 - target->Thrust(ang, 10); - if (!(target->flags & MF_NOGRAVITY)) - { - target->Vel.Z += 5.; - } - } - else - { - target->Thrust(ang, thrust); - } - } -} - static inline bool MustForcePain(AActor *target, AActor *inflictor) { return (inflictor && (inflictor->flags6 & MF6_FORCEPAIN)); @@ -997,9 +922,7 @@ static inline bool isFakePain(AActor *target, AActor *inflictor, int damage) // the damage was cancelled. static int DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage, FName mod, int flags, DAngle angle, bool& needevent) { - DAngle ang; player_t *player = NULL; - double thrust; int temp; int painchance = 0; FState * woundstate = NULL; @@ -1262,7 +1185,11 @@ static int DamageMobj (AActor *target, AActor *inflictor, AActor *source, int da && !(target->flags7 & MF7_DONTTHRUST) && (source == NULL || source->player == NULL || !(source->flags2 & MF2_NODMGTHRUST))) { - ApplyKickback(target, inflictor, source, damage, angle, mod, flags); + IFVIRTUALPTR(target, AActor, ApplyKickback) + { + VMValue params[] = { target, inflictor, source, damage, angle.Degrees, mod.GetIndex(), flags }; + VMCall(func, params, countof(params), nullptr, 0); + } } // [RH] Avoid friendly fire if enabled diff --git a/wadsrc/static/zscript.txt b/wadsrc/static/zscript.txt index 6c9df6c72c..d04f99ae0c 100644 --- a/wadsrc/static/zscript.txt +++ b/wadsrc/static/zscript.txt @@ -7,6 +7,7 @@ version "3.7" #include "zscript/actor.txt" #include "zscript/actor_attacks.txt" #include "zscript/actor_checks.txt" +#include "zscript/actor_interaction.txt" #include "zscript/events.txt" #include "zscript/destructible.txt" #include "zscript/level_compatibility.txt" diff --git a/wadsrc/static/zscript/actor_interaction.txt b/wadsrc/static/zscript/actor_interaction.txt new file mode 100644 index 0000000000..51c48deacf --- /dev/null +++ b/wadsrc/static/zscript/actor_interaction.txt @@ -0,0 +1,79 @@ +extend class Actor +{ + + virtual void ApplyKickback(Actor inflictor, Actor source, int damage, double angle, Name mod, int flags) + { + double ang; + int kickback; + double thrust; + + if (inflictor && inflictor.projectileKickback) + kickback = inflictor.projectileKickback; + else if (!source || !source.player || !source.player.ReadyWeapon) + kickback = gameinfo.defKickback; + else + kickback = source.player.ReadyWeapon.Kickback; + + kickback = int(kickback * G_SkillPropertyFloat(SKILLP_KickbackFactor)); + if (kickback) + { + Actor origin = (source && (flags & DMG_INFLICTOR_IS_PUFF)) ? source : inflictor; + + if (flags & DMG_USEANGLE) + { + ang = angle; + } + else if (origin.pos.xy == pos.xy) + { + // If the origin and target are in exactly the same spot, choose a random direction. + // (Most likely cause is from telefragging somebody during spawning because they + // haven't moved from their spawn spot at all.) + ang = frandom[Kickback](0., 360.); + } + else + { + ang = origin.AngleTo(self); + } + + thrust = mod == 'MDK' ? 10 : 32; + if (Mass > 0) + { + thrust = clamp((damage * 0.125 * kickback) / Mass, 0., thrust); + } + + // Don't apply ultra-small damage thrust + if (thrust < 0.01) thrust = 0; + + // make fall forwards sometimes + if ((damage < 40) && (damage > health) + && (pos.Z - origin.pos.Z > 64) + && (random[Kickback]() & 1) + // [RH] But only if not too fast and not flying + && thrust < 10 + && !bNoGravity + && !bNoForwardFall + && (inflictor == NULL || !inflictor.bNoForwardFall) + ) + { + ang += 180.; + thrust *= 4; + } + if (source && source.player && (flags & DMG_INFLICTOR_IS_PUFF) + && source.player.ReadyWeapon != NULL && (source.player.ReadyWeapon.bSTAFF2_KICKBACK)) + { + // Staff power level 2 + Thrust(10, ang); + if (!bNoGravity) + { + Vel.Z += 5.; + } + } + else + { + Thrust(thrust, ang); + } + } + } + + +} \ No newline at end of file diff --git a/wadsrc/static/zscript/base.txt b/wadsrc/static/zscript/base.txt index 67c1893cc8..9a8baf9906 100644 --- a/wadsrc/static/zscript/base.txt +++ b/wadsrc/static/zscript/base.txt @@ -367,6 +367,7 @@ struct GameInfoStruct native native bool intermissioncounter; native Name mSliderColor; native double telefogheight; + native int defKickback; } class Object native diff --git a/wadsrc/static/zscript/constants.txt b/wadsrc/static/zscript/constants.txt index 7931c40af3..9ea4375c69 100644 --- a/wadsrc/static/zscript/constants.txt +++ b/wadsrc/static/zscript/constants.txt @@ -1001,6 +1001,7 @@ enum EFSkillProperty // floating point properties SKILLP_Aggressiveness, SKILLP_MonsterHealth, SKILLP_FriendlyHealth, + SKILLP_KickbackFactor, }; enum EWeaponPos