From 592b648c3ed8ce3dc3e55f68077c5eb3aac063f1 Mon Sep 17 00:00:00 2001 From: Evil Eye Date: Sat, 23 Aug 2025 21:56:38 +0200 Subject: [PATCH] Pass ammo to Hit handler by record id --- apps/openmw/mwlua/luamanagerimp.cpp | 2 +- apps/openmw/mwlua/types/actor.cpp | 19 +++++++++++++++---- files/data/scripts/omw/combat/local.lua | 6 +++--- 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/apps/openmw/mwlua/luamanagerimp.cpp b/apps/openmw/mwlua/luamanagerimp.cpp index 40ec9d93a9..0b760ccdf0 100644 --- a/apps/openmw/mwlua/luamanagerimp.cpp +++ b/apps/openmw/mwlua/luamanagerimp.cpp @@ -515,7 +515,7 @@ namespace MWLua if (!weapon.isEmpty()) data["weapon"] = LObject(weapon); if (!ammo.isEmpty()) - data["ammo"] = LObject(weapon); + data["ammo"] = ammo.getCellRef().getRefId().serializeText(); data["type"] = attackType; data["strength"] = attackStrength; data["damage"] = damageTable; diff --git a/apps/openmw/mwlua/types/actor.cpp b/apps/openmw/mwlua/types/actor.cpp index 8ce7473061..da3e610b2d 100644 --- a/apps/openmw/mwlua/types/actor.cpp +++ b/apps/openmw/mwlua/types/actor.cpp @@ -15,6 +15,7 @@ #include "apps/openmw/mwmechanics/drawstate.hpp" #include "apps/openmw/mwworld/class.hpp" #include "apps/openmw/mwworld/inventorystore.hpp" +#include "apps/openmw/mwworld/manualref.hpp" #include "apps/openmw/mwworld/worldmodel.hpp" #include "../localscripts.hpp" @@ -439,19 +440,29 @@ namespace MWLua else if (sourceTypeStr == "magic") sourceType = MWMechanics::DamageSourceType::Magical; sol::optional weapon = options.get>("weapon"); - sol::optional ammo = options.get>("ammo"); + std::string_view ammoId = options.get_or("ammo", {}); + ESM::RefId ammo = ESM::RefId::deserializeText(ammoId); context.mLuaManager->addAction( [self = Object(self), damages = std::move(damageCpp), - attacker = options.get>("attacker"), weapon = ammo ? ammo : weapon, + attacker = options.get>("attacker"), weapon, ammo, successful = options.get("successful"), sourceType = sourceType] { MWWorld::Ptr attackerPtr; MWWorld::Ptr weaponPtr; if (attacker) attackerPtr = attacker->ptr(); if (weapon) - weaponPtr = weapon->ptr(); - self.ptr().getClass().onHit(self.ptr(), damages, weaponPtr, attackerPtr, successful, sourceType); + weaponPtr = weapon->ptrOrEmpty(); + if (!ammo.empty()) + { + MWWorld::ManualRef projectileRef(*MWBase::Environment::get().getESMStore(), ammo); + weaponPtr = projectileRef.getPtr(); + self.ptr().getClass().onHit( + self.ptr(), damages, weaponPtr, attackerPtr, successful, sourceType); + } + else + self.ptr().getClass().onHit( + self.ptr(), damages, weaponPtr, attackerPtr, successful, sourceType); }, "HitAction"); }; diff --git a/files/data/scripts/omw/combat/local.lua b/files/data/scripts/omw/combat/local.lua index 504f10a1fd..7c688d6569 100644 --- a/files/data/scripts/omw/combat/local.lua +++ b/files/data/scripts/omw/combat/local.lua @@ -192,7 +192,7 @@ local function applyArmor(attack) I.SkillProgression.skillUsed(skillid, {useType = I.SkillProgression.SKILL_USE_TYPES.Armor_HitByOpponent}) end if item and Armor.objectIsInstance(item) then - local attackerIsUnarmedCreature = attack.attacker and not attack.weapon and Creature.objectIsInstance(attack.attacker) + local attackerIsUnarmedCreature = attack.attacker and not attack.weapon and not attack.ammo and Creature.objectIsInstance(attack.attacker) if settings:get('unarmedCreatureAttacksDamageArmor') or not attackerIsUnarmedCreature then core.sendGlobalEvent('ModifyItemCondition', { actor = self, item = item, amount = diff }) end @@ -307,7 +307,7 @@ end -- @field [parent=#AttackInfo] openmw.self#ATTACK_TYPE type (Optional) Attack variant if applicable. For melee attacks this represents chop vs thrust vs slash. For unarmed creatures this implies which of its 3 possible attacks were used. For other attacks this field can be ignored. -- @field [parent=#AttackInfo] openmw.types#Actor attacker (Optional) Attacking actor -- @field [parent=#AttackInfo] openmw.types#Weapon weapon (Optional) Attacking weapon --- @field [parent=#AttackInfo] openmw.types#Weapon ammo (Optional) Ammo +-- @field [parent=#AttackInfo] #string ammo (Optional) Ammo record ID -- @field [parent=#AttackInfo] openmw.util#Vector3 hitPos (Optional) Where on the victim the attack is landing. Used to spawn blood effects. Blood effects are skipped if nil. return { --- Basic combat interface @@ -330,7 +330,7 @@ return { interface = { --- Interface version -- @field [parent=#Combat] #number version - version = 0, + version = 1, --- Add new onHit handler for this actor -- If `handler(attack)` returns false, other handlers for