Self / ally arts cast on the hero when pointed at an enemy
Arts with launch type 2 (buffs, auras, heals) are only valid on allies or without a target; with an enemy under the cursor the game dropped the order. Orders of a player hero for such arts lose a non-ally target, which casts them on the hero. The launch type comes from the art definition tables (game/engine/arts.h, tools/arttable.mjs). Also: skill keys check the relocated taskbar slots (all 7), Ghidra data labels (g_ names in names.txt). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
dbc632750b
commit
30c93fc87e
9 files changed
+187
-10
No files matched your search
@@ -0,0 +1,48 @@
|
||||
#pragma once
|
||||
// Combat arts: the definition tables and how they are targeted.
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace game {
|
||||
|
||||
// How an art is launched (byte +0x3c of a g_spellDefs entry, +0x4c of a
|
||||
// g_combatMoveDefs entry; cCreature::IsValidArtTarget 0x51d680 switches on it).
|
||||
enum class LaunchType : uint8_t {
|
||||
Target0 = 0, // aimed (e.g. Feuerball)
|
||||
Enemy = 1, // aimed at an enemy (attacks, Blitzschlag)
|
||||
SelfOrAlly = 2, // buffs, auras, heals: an ally, or the caster without a target
|
||||
Ground = 3, // a point / area, summons
|
||||
Corpse = 4, // a dead ally (resurrection)
|
||||
AroundSelf = 5, // centred on the caster
|
||||
Unknown = 0xff,
|
||||
};
|
||||
|
||||
// SpellDef::Find (0x4d2150) / CombatMoveDef::Find (0x4d1930): the definition
|
||||
// entry of art `id` (spells: small ids, combat moves: 0x3e8+), or null.
|
||||
inline const uint8_t* FindSpellDef(uint16_t id) {
|
||||
using Fn = const uint8_t*(__cdecl*)(uint32_t);
|
||||
return reinterpret_cast<Fn>(0x004d2150)(id);
|
||||
}
|
||||
inline const uint8_t* FindCombatMoveDef(uint16_t id) {
|
||||
using Fn = const uint8_t*(__cdecl*)(uint32_t);
|
||||
return reinterpret_cast<Fn>(0x004d1930)(id);
|
||||
}
|
||||
|
||||
// The launch type of art `id`, looked up as cEngine::UpdateCursorPick does.
|
||||
inline LaunchType ArtLaunchType(uint16_t id) {
|
||||
if (const uint8_t* spell = FindSpellDef(id)) {
|
||||
return static_cast<LaunchType>(spell[0x3c]);
|
||||
}
|
||||
if (const uint8_t* move = FindCombatMoveDef(id)) {
|
||||
return static_cast<LaunchType>(move[0x4c]);
|
||||
}
|
||||
return LaunchType::Unknown;
|
||||
}
|
||||
|
||||
// cCreature::IsAlly (0x548f20): whether object `id` is an ally of `creature`.
|
||||
inline bool IsAlly(void* creature, uint32_t id) {
|
||||
using Fn = char(__fastcall*)(void*, void*, uint32_t);
|
||||
return reinterpret_cast<Fn>(0x00548f20)(creature, nullptr, id) != 0;
|
||||
}
|
||||
|
||||
} // namespace game
|
||||
Reference in new issue
Block a user