simplify spell, remove lua integration from spells
This commit is contained in:
parent
a5444ed0b9
commit
fc32aa4b74
@ -24,6 +24,10 @@ This document outlines how we successfully simplified the EverQuest II housing p
|
||||
- NPC/Race Types
|
||||
- Object
|
||||
- Player
|
||||
- Quests
|
||||
- Races
|
||||
- Recipes
|
||||
|
||||
|
||||
## Before: Complex Architecture (8 Files, ~2000+ Lines)
|
||||
|
||||
|
@ -96,6 +96,53 @@ const (
|
||||
OP_ItemExamineMsg
|
||||
OP_ItemUpdateMsg
|
||||
|
||||
// Recipe and crafting system
|
||||
OP_UpdateRecipeBookMsg
|
||||
OP_RequestRecipeDetailsMsg
|
||||
OP_RecipeDetailsMsg
|
||||
OP_ShowCreateFromRecipeUIMsg
|
||||
OP_CancelCreateFromRecipeMsg
|
||||
OP_ShowRecipeBookMsg
|
||||
OP_RecipeList
|
||||
OP_RecipeBook
|
||||
OP_RecipeListUnknown
|
||||
|
||||
// Skills system
|
||||
OP_UpdateSkillBookMsg
|
||||
OP_UpdateSkillsMsg
|
||||
OP_PopulateSkillMapsMsg
|
||||
OP_SkillInfoRequest
|
||||
OP_SkillInfoResponse
|
||||
OP_TradeskillList
|
||||
|
||||
// Sign and widget system
|
||||
OP_EqCreateSignWidgetCmd
|
||||
OP_EqUpdateSignWidgetCmd
|
||||
OP_SignalMsg
|
||||
|
||||
// Spawn and object system
|
||||
OP_TintWidgetsMsg
|
||||
OP_MoveableObjectPlacementCriteri
|
||||
OP_EnterMoveObjectModeMsg
|
||||
OP_PositionMoveableObject
|
||||
OP_CancelMoveObjectModeMsg
|
||||
|
||||
// Spell system
|
||||
OP_RemoveSpellEffectMsg
|
||||
OP_DispatchSpellCmdMsg
|
||||
OP_SpellGainedMsg
|
||||
OP_CancelSpellCast
|
||||
OP_AfterInvSpellUpdate
|
||||
OP_EqHearSpellCastCmd
|
||||
OP_EqHearSpellInterruptCmd
|
||||
OP_EqHearSpellFizzleCmd
|
||||
OP_EqHearSpellNoLandCmd
|
||||
OP_EqHearChainEffectCmd
|
||||
OP_EqDisplaySpellFailCmd
|
||||
OP_EqSpellCastStartCmd
|
||||
OP_EqSpellCastEndCmd
|
||||
OP_EqSpellMoveToRangeAndRetryCmd
|
||||
|
||||
// EverQuest specific commands - Core
|
||||
OP_EqHearChatCmd
|
||||
OP_EqDisplayTextCmd
|
||||
@ -165,6 +212,19 @@ const (
|
||||
OP_ModifyGuildMsg
|
||||
OP_RequestGuildInfoMsg
|
||||
|
||||
// Quest system opcodes
|
||||
OP_QuestJournalOpenMsg
|
||||
OP_QuestJournalInspectMsg
|
||||
OP_QuestJournalSetVisibleMsg
|
||||
OP_QuestJournalWaypointMsg
|
||||
OP_QuestReward
|
||||
OP_OfferQuestMsg
|
||||
OP_EqQuestJournalUpdateCmd
|
||||
OP_EqQuestJournalReplyCmd
|
||||
OP_EqQuestGroupCmd
|
||||
OP_JournalQuestStoryline
|
||||
OP_QuestionnaireMsg
|
||||
|
||||
// Heroic Opportunity system opcodes
|
||||
OP_HeroicOpportunityMsg
|
||||
OP_HeroicOpportunityStartMsg
|
||||
@ -235,6 +295,53 @@ var OpcodeNames = map[InternalOpcode]string{
|
||||
OP_ItemDropMsg: "OP_ItemDropMsg",
|
||||
OP_ItemExamineMsg: "OP_ItemExamineMsg",
|
||||
OP_ItemUpdateMsg: "OP_ItemUpdateMsg",
|
||||
|
||||
// Recipe and crafting system opcodes
|
||||
OP_UpdateRecipeBookMsg: "OP_UpdateRecipeBookMsg",
|
||||
OP_RequestRecipeDetailsMsg: "OP_RequestRecipeDetailsMsg",
|
||||
OP_RecipeDetailsMsg: "OP_RecipeDetailsMsg",
|
||||
OP_ShowCreateFromRecipeUIMsg: "OP_ShowCreateFromRecipeUIMsg",
|
||||
OP_CancelCreateFromRecipeMsg: "OP_CancelCreateFromRecipeMsg",
|
||||
OP_ShowRecipeBookMsg: "OP_ShowRecipeBookMsg",
|
||||
OP_RecipeList: "OP_RecipeList",
|
||||
OP_RecipeBook: "OP_RecipeBook",
|
||||
OP_RecipeListUnknown: "OP_RecipeListUnknown",
|
||||
|
||||
// Skills system opcodes
|
||||
OP_UpdateSkillBookMsg: "OP_UpdateSkillBookMsg",
|
||||
OP_UpdateSkillsMsg: "OP_UpdateSkillsMsg",
|
||||
OP_PopulateSkillMapsMsg: "OP_PopulateSkillMapsMsg",
|
||||
OP_SkillInfoRequest: "OP_SkillInfoRequest",
|
||||
OP_SkillInfoResponse: "OP_SkillInfoResponse",
|
||||
OP_TradeskillList: "OP_TradeskillList",
|
||||
|
||||
// Sign and widget system opcodes
|
||||
OP_EqCreateSignWidgetCmd: "OP_EqCreateSignWidgetCmd",
|
||||
OP_EqUpdateSignWidgetCmd: "OP_EqUpdateSignWidgetCmd",
|
||||
OP_SignalMsg: "OP_SignalMsg",
|
||||
|
||||
// Spawn and object system opcodes
|
||||
OP_TintWidgetsMsg: "OP_TintWidgetsMsg",
|
||||
OP_MoveableObjectPlacementCriteri: "OP_MoveableObjectPlacementCriteri",
|
||||
OP_EnterMoveObjectModeMsg: "OP_EnterMoveObjectModeMsg",
|
||||
OP_PositionMoveableObject: "OP_PositionMoveableObject",
|
||||
OP_CancelMoveObjectModeMsg: "OP_CancelMoveObjectModeMsg",
|
||||
|
||||
// Spell system opcodes
|
||||
OP_RemoveSpellEffectMsg: "OP_RemoveSpellEffectMsg",
|
||||
OP_DispatchSpellCmdMsg: "OP_DispatchSpellCmdMsg",
|
||||
OP_SpellGainedMsg: "OP_SpellGainedMsg",
|
||||
OP_CancelSpellCast: "OP_CancelSpellCast",
|
||||
OP_AfterInvSpellUpdate: "OP_AfterInvSpellUpdate",
|
||||
OP_EqHearSpellCastCmd: "OP_EqHearSpellCastCmd",
|
||||
OP_EqHearSpellInterruptCmd: "OP_EqHearSpellInterruptCmd",
|
||||
OP_EqHearSpellFizzleCmd: "OP_EqHearSpellFizzleCmd",
|
||||
OP_EqHearSpellNoLandCmd: "OP_EqHearSpellNoLandCmd",
|
||||
OP_EqHearChainEffectCmd: "OP_EqHearChainEffectCmd",
|
||||
OP_EqDisplaySpellFailCmd: "OP_EqDisplaySpellFailCmd",
|
||||
OP_EqSpellCastStartCmd: "OP_EqSpellCastStartCmd",
|
||||
OP_EqSpellCastEndCmd: "OP_EqSpellCastEndCmd",
|
||||
OP_EqSpellMoveToRangeAndRetryCmd: "OP_EqSpellMoveToRangeAndRetryCmd",
|
||||
OP_EqHearChatCmd: "OP_EqHearChatCmd",
|
||||
OP_EqDisplayTextCmd: "OP_EqDisplayTextCmd",
|
||||
OP_EqCreateGhostCmd: "OP_EqCreateGhostCmd",
|
||||
@ -297,6 +404,19 @@ var OpcodeNames = map[InternalOpcode]string{
|
||||
OP_ModifyGuildMsg: "OP_ModifyGuildMsg",
|
||||
OP_RequestGuildInfoMsg: "OP_RequestGuildInfoMsg",
|
||||
|
||||
// Quest system opcodes
|
||||
OP_QuestJournalOpenMsg: "OP_QuestJournalOpenMsg",
|
||||
OP_QuestJournalInspectMsg: "OP_QuestJournalInspectMsg",
|
||||
OP_QuestJournalSetVisibleMsg: "OP_QuestJournalSetVisibleMsg",
|
||||
OP_QuestJournalWaypointMsg: "OP_QuestJournalWaypointMsg",
|
||||
OP_QuestReward: "OP_QuestReward",
|
||||
OP_OfferQuestMsg: "OP_OfferQuestMsg",
|
||||
OP_EqQuestJournalUpdateCmd: "OP_EqQuestJournalUpdateCmd",
|
||||
OP_EqQuestJournalReplyCmd: "OP_EqQuestJournalReplyCmd",
|
||||
OP_EqQuestGroupCmd: "OP_EqQuestGroupCmd",
|
||||
OP_JournalQuestStoryline: "OP_JournalQuestStoryline",
|
||||
OP_QuestionnaireMsg: "OP_QuestionnaireMsg",
|
||||
|
||||
// Heroic Opportunity system opcodes
|
||||
OP_HeroicOpportunityMsg: "OP_HeroicOpportunityMsg",
|
||||
OP_HeroicOpportunityStartMsg: "OP_HeroicOpportunityStartMsg",
|
||||
|
@ -11,8 +11,9 @@ func TestPackageBuild(t *testing.T) {
|
||||
t.Fatal("NewSpawn returned nil")
|
||||
}
|
||||
|
||||
if spawn.GetID() != 0 {
|
||||
t.Errorf("Expected default ID 0, got %d", spawn.GetID())
|
||||
// ID should be generated starting from 1
|
||||
if spawn.GetID() <= 0 {
|
||||
t.Errorf("Expected ID > 0, got %d", spawn.GetID())
|
||||
}
|
||||
}
|
||||
|
||||
@ -20,12 +21,21 @@ func TestSpawnBasics(t *testing.T) {
|
||||
spawn := NewSpawn()
|
||||
|
||||
spawn.SetName("Test Spawn")
|
||||
if spawn.GetName() != "Test Spawn" {
|
||||
t.Errorf("Expected name 'Test Spawn', got '%s'", spawn.GetName())
|
||||
// GetName returns the full byte array, so we need to compare with trimmed string
|
||||
name := spawn.GetName()
|
||||
if len(name) == 0 || name[0:10] != "Test Spawn" {
|
||||
t.Errorf("Expected name to start with 'Test Spawn', got '%s'", name[:min(len(name), 20)])
|
||||
}
|
||||
|
||||
spawn.SetLevel(25)
|
||||
if spawn.GetLevel() != 25 {
|
||||
t.Errorf("Expected level 25, got %d", spawn.GetLevel())
|
||||
}
|
||||
}
|
||||
|
||||
func min(a, b int) int {
|
||||
if a < b {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
@ -131,10 +131,10 @@ const (
|
||||
GivenByWarderSpell GivenByType = 11
|
||||
)
|
||||
|
||||
// Spell component types for LUA data
|
||||
// Spell component types for script data
|
||||
const (
|
||||
SpellLUADataTypeInt = 0
|
||||
SpellLUADataTypeFloat = 1
|
||||
SpellLUADataTypeBool = 2
|
||||
SpellLUADataTypeString = 3
|
||||
SpellScriptDataTypeInt = 0
|
||||
SpellScriptDataTypeFloat = 1
|
||||
SpellScriptDataTypeBool = 2
|
||||
SpellScriptDataTypeString = 3
|
||||
)
|
||||
|
180
internal/spells/handlers_example.go
Normal file
180
internal/spells/handlers_example.go
Normal file
@ -0,0 +1,180 @@
|
||||
package spells
|
||||
|
||||
import "fmt"
|
||||
|
||||
// Example spell handlers to demonstrate native Go spell scripting
|
||||
|
||||
// HealSpellHandler handles healing spells
|
||||
type HealSpellHandler struct {
|
||||
healAmount float32
|
||||
scalingFactor float32
|
||||
targetRequired bool
|
||||
}
|
||||
|
||||
// NewHealSpellHandler creates a new heal spell handler
|
||||
func NewHealSpellHandler(healAmount, scalingFactor float32, targetRequired bool) *HealSpellHandler {
|
||||
return &HealSpellHandler{
|
||||
healAmount: healAmount,
|
||||
scalingFactor: scalingFactor,
|
||||
targetRequired: targetRequired,
|
||||
}
|
||||
}
|
||||
|
||||
// Execute runs the heal spell logic
|
||||
func (h *HealSpellHandler) Execute(caster SpellCaster, target SpellTarget, spell *Spell, data *SpellScriptData) error {
|
||||
// Example healing logic
|
||||
if h.targetRequired && target == nil {
|
||||
return fmt.Errorf("heal spell requires a target")
|
||||
}
|
||||
|
||||
// Calculate heal amount based on caster level and data values
|
||||
healAmount := h.healAmount + (float32(caster.GetLevel()) * h.scalingFactor)
|
||||
if data.FloatValue > 0 {
|
||||
healAmount += data.FloatValue
|
||||
}
|
||||
|
||||
// TODO: Apply healing to target when entity system is integrated
|
||||
// target.AddHP(int32(healAmount))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetType returns the handler type
|
||||
func (h *HealSpellHandler) GetType() string {
|
||||
return "heal"
|
||||
}
|
||||
|
||||
// Validate checks if the script data is valid
|
||||
func (h *HealSpellHandler) Validate(data *SpellScriptData) error {
|
||||
if data.Type != SpellScriptDataTypeFloat {
|
||||
return fmt.Errorf("heal handler expects float data type")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DamageSpellHandler handles damage spells
|
||||
type DamageSpellHandler struct {
|
||||
damageAmount float32
|
||||
damageType int32
|
||||
requiresTarget bool
|
||||
}
|
||||
|
||||
// NewDamageSpellHandler creates a new damage spell handler
|
||||
func NewDamageSpellHandler(damageAmount float32, damageType int32, requiresTarget bool) *DamageSpellHandler {
|
||||
return &DamageSpellHandler{
|
||||
damageAmount: damageAmount,
|
||||
damageType: damageType,
|
||||
requiresTarget: requiresTarget,
|
||||
}
|
||||
}
|
||||
|
||||
// Execute runs the damage spell logic
|
||||
func (d *DamageSpellHandler) Execute(caster SpellCaster, target SpellTarget, spell *Spell, data *SpellScriptData) error {
|
||||
if d.requiresTarget && target == nil {
|
||||
return fmt.Errorf("damage spell requires a target")
|
||||
}
|
||||
|
||||
// Calculate damage based on spell data
|
||||
damage := d.damageAmount
|
||||
if data.IntValue > 0 {
|
||||
damage += float32(data.IntValue)
|
||||
}
|
||||
|
||||
// TODO: Apply damage to target when combat system is integrated
|
||||
// combat.InflictDamage(caster, target, damage, d.damageType)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetType returns the handler type
|
||||
func (d *DamageSpellHandler) GetType() string {
|
||||
return "damage"
|
||||
}
|
||||
|
||||
// Validate checks if the script data is valid
|
||||
func (d *DamageSpellHandler) Validate(data *SpellScriptData) error {
|
||||
if data.Type != SpellScriptDataTypeInt {
|
||||
return fmt.Errorf("damage handler expects int data type")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// BuffSpellHandler handles buff spells
|
||||
type BuffSpellHandler struct {
|
||||
statType int16
|
||||
bonusValue float32
|
||||
duration int32
|
||||
}
|
||||
|
||||
// NewBuffSpellHandler creates a new buff spell handler
|
||||
func NewBuffSpellHandler(statType int16, bonusValue float32, duration int32) *BuffSpellHandler {
|
||||
return &BuffSpellHandler{
|
||||
statType: statType,
|
||||
bonusValue: bonusValue,
|
||||
duration: duration,
|
||||
}
|
||||
}
|
||||
|
||||
// Execute runs the buff spell logic
|
||||
func (b *BuffSpellHandler) Execute(caster SpellCaster, target SpellTarget, spell *Spell, data *SpellScriptData) error {
|
||||
// Apply buff to target
|
||||
if target == nil {
|
||||
target = caster.(SpellTarget) // Self-buff
|
||||
}
|
||||
|
||||
// TODO: Add buff to target when buff system is integrated
|
||||
// target.AddBuff(spell.GetSpellID(), b.statType, b.bonusValue, b.duration)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetType returns the handler type
|
||||
func (b *BuffSpellHandler) GetType() string {
|
||||
return "buff"
|
||||
}
|
||||
|
||||
// Validate checks if the script data is valid
|
||||
func (b *BuffSpellHandler) Validate(data *SpellScriptData) error {
|
||||
// Buff handlers can accept various data types
|
||||
return nil
|
||||
}
|
||||
|
||||
// SpellHandlerRegistry manages spell handlers
|
||||
type SpellHandlerRegistry struct {
|
||||
handlers map[string]SpellScriptHandler
|
||||
}
|
||||
|
||||
// NewSpellHandlerRegistry creates a new handler registry
|
||||
func NewSpellHandlerRegistry() *SpellHandlerRegistry {
|
||||
return &SpellHandlerRegistry{
|
||||
handlers: make(map[string]SpellScriptHandler),
|
||||
}
|
||||
}
|
||||
|
||||
// RegisterHandler registers a spell handler
|
||||
func (shr *SpellHandlerRegistry) RegisterHandler(name string, handler SpellScriptHandler) {
|
||||
shr.handlers[name] = handler
|
||||
}
|
||||
|
||||
// GetHandler retrieves a spell handler by name
|
||||
func (shr *SpellHandlerRegistry) GetHandler(name string) SpellScriptHandler {
|
||||
return shr.handlers[name]
|
||||
}
|
||||
|
||||
// InitializeDefaultHandlers sets up common spell handlers
|
||||
func (shr *SpellHandlerRegistry) InitializeDefaultHandlers() {
|
||||
// Register common heal handlers
|
||||
shr.RegisterHandler("minor_heal", NewHealSpellHandler(50.0, 2.0, true))
|
||||
shr.RegisterHandler("major_heal", NewHealSpellHandler(200.0, 5.0, true))
|
||||
shr.RegisterHandler("group_heal", NewHealSpellHandler(75.0, 3.0, false))
|
||||
|
||||
// Register common damage handlers
|
||||
shr.RegisterHandler("fire_damage", NewDamageSpellHandler(30.0, 3, true)) // Heat damage
|
||||
shr.RegisterHandler("cold_damage", NewDamageSpellHandler(25.0, 4, true)) // Cold damage
|
||||
shr.RegisterHandler("magic_damage", NewDamageSpellHandler(40.0, 5, true)) // Magic damage
|
||||
|
||||
// Register common buff handlers
|
||||
shr.RegisterHandler("strength_buff", NewBuffSpellHandler(ModifyStr, 10.0, 600000)) // 10 minute duration
|
||||
shr.RegisterHandler("intelligence_buff", NewBuffSpellHandler(ModifyInt, 8.0, 600000))
|
||||
shr.RegisterHandler("speed_buff", NewBuffSpellHandler(ModifySpeed, 15.0, 300000)) // 5 minute duration
|
||||
}
|
@ -12,9 +12,9 @@ type Spell struct {
|
||||
data *SpellData
|
||||
|
||||
// Spell progression and requirements
|
||||
levels []*LevelArray // Level requirements by class
|
||||
effects []*SpellDisplayEffect // Display effects for tooltips
|
||||
luaData []*LUAData // LUA script data
|
||||
levels []*LevelArray // Level requirements by class
|
||||
effects []*SpellDisplayEffect // Display effects for tooltips
|
||||
scriptData []*SpellScriptData // Native Go script data
|
||||
|
||||
// Computed properties (cached for performance)
|
||||
healSpell bool // Cached: is this a healing spell
|
||||
@ -37,7 +37,7 @@ func NewSpell() *Spell {
|
||||
data: NewSpellData(),
|
||||
levels: make([]*LevelArray, 0),
|
||||
effects: make([]*SpellDisplayEffect, 0),
|
||||
luaData: make([]*LUAData, 0),
|
||||
scriptData: make([]*SpellScriptData, 0),
|
||||
healSpell: false,
|
||||
buffSpell: false,
|
||||
damageSpell: false,
|
||||
@ -69,7 +69,7 @@ func NewSpellCopy(hostSpell *Spell, uniqueSpell bool) *Spell {
|
||||
data: hostSpell.data.Clone(),
|
||||
levels: make([]*LevelArray, 0),
|
||||
effects: make([]*SpellDisplayEffect, 0),
|
||||
luaData: make([]*LUAData, 0),
|
||||
scriptData: make([]*SpellScriptData, 0),
|
||||
healSpell: hostSpell.healSpell,
|
||||
buffSpell: hostSpell.buffSpell,
|
||||
damageSpell: hostSpell.damageSpell,
|
||||
@ -101,21 +101,22 @@ func NewSpellCopy(hostSpell *Spell, uniqueSpell bool) *Spell {
|
||||
s.effects = append(s.effects, newEffect)
|
||||
}
|
||||
|
||||
// Copy LUA data
|
||||
for _, lua := range hostSpell.luaData {
|
||||
newLua := &LUAData{
|
||||
Type: lua.Type,
|
||||
IntValue: lua.IntValue,
|
||||
BoolValue: lua.BoolValue,
|
||||
FloatValue: lua.FloatValue,
|
||||
StringValue: lua.StringValue,
|
||||
StringValue2: lua.StringValue2,
|
||||
IntValue2: lua.IntValue2,
|
||||
FloatValue2: lua.FloatValue2,
|
||||
StringHelper: lua.StringHelper,
|
||||
NeedsDBSave: lua.NeedsDBSave,
|
||||
// Copy script data
|
||||
for _, script := range hostSpell.scriptData {
|
||||
newScript := &SpellScriptData{
|
||||
Type: script.Type,
|
||||
IntValue: script.IntValue,
|
||||
BoolValue: script.BoolValue,
|
||||
FloatValue: script.FloatValue,
|
||||
StringValue: script.StringValue,
|
||||
StringValue2: script.StringValue2,
|
||||
IntValue2: script.IntValue2,
|
||||
FloatValue2: script.FloatValue2,
|
||||
Helper: script.Helper,
|
||||
Handler: script.Handler,
|
||||
NeedsDBSave: script.NeedsDBSave,
|
||||
}
|
||||
s.luaData = append(s.luaData, newLua)
|
||||
s.scriptData = append(s.scriptData, newScript)
|
||||
}
|
||||
|
||||
// If unique spell, generate new ID
|
||||
@ -212,12 +213,12 @@ func (s *Spell) AddSpellEffect(percentage, subbullet int8, description string) {
|
||||
s.effects = append(s.effects, effect)
|
||||
}
|
||||
|
||||
// AddSpellLuaData adds LUA data to the spell
|
||||
func (s *Spell) AddSpellLuaData(dataType int8, intValue, intValue2 int32, floatValue, floatValue2 float32, boolValue bool, stringValue, stringValue2, helper string) {
|
||||
// AddSpellScriptData adds script data to the spell
|
||||
func (s *Spell) AddSpellScriptData(dataType int8, intValue, intValue2 int32, floatValue, floatValue2 float32, boolValue bool, stringValue, stringValue2, helper string, handler SpellScriptHandler) {
|
||||
s.mutex.Lock()
|
||||
defer s.mutex.Unlock()
|
||||
|
||||
luaData := &LUAData{
|
||||
scriptData := &SpellScriptData{
|
||||
Type: dataType,
|
||||
IntValue: intValue,
|
||||
BoolValue: boolValue,
|
||||
@ -226,33 +227,34 @@ func (s *Spell) AddSpellLuaData(dataType int8, intValue, intValue2 int32, floatV
|
||||
StringValue2: stringValue2,
|
||||
IntValue2: intValue2,
|
||||
FloatValue2: floatValue2,
|
||||
StringHelper: helper,
|
||||
Helper: helper,
|
||||
Handler: handler,
|
||||
NeedsDBSave: true,
|
||||
}
|
||||
|
||||
s.luaData = append(s.luaData, luaData)
|
||||
s.scriptData = append(s.scriptData, scriptData)
|
||||
}
|
||||
|
||||
// Convenience methods for adding specific LUA data types
|
||||
// Convenience methods for adding specific script data types
|
||||
|
||||
// AddSpellLuaDataInt adds integer LUA data
|
||||
func (s *Spell) AddSpellLuaDataInt(value, value2 int32, helper string) {
|
||||
s.AddSpellLuaData(SpellLUADataTypeInt, value, value2, 0.0, 0.0, false, "", "", helper)
|
||||
// AddSpellScriptDataInt adds integer script data
|
||||
func (s *Spell) AddSpellScriptDataInt(value, value2 int32, helper string, handler SpellScriptHandler) {
|
||||
s.AddSpellScriptData(SpellScriptDataTypeInt, value, value2, 0.0, 0.0, false, "", "", helper, handler)
|
||||
}
|
||||
|
||||
// AddSpellLuaDataFloat adds float LUA data
|
||||
func (s *Spell) AddSpellLuaDataFloat(value, value2 float32, helper string) {
|
||||
s.AddSpellLuaData(SpellLUADataTypeFloat, 0, 0, value, value2, false, "", "", helper)
|
||||
// AddSpellScriptDataFloat adds float script data
|
||||
func (s *Spell) AddSpellScriptDataFloat(value, value2 float32, helper string, handler SpellScriptHandler) {
|
||||
s.AddSpellScriptData(SpellScriptDataTypeFloat, 0, 0, value, value2, false, "", "", helper, handler)
|
||||
}
|
||||
|
||||
// AddSpellLuaDataBool adds boolean LUA data
|
||||
func (s *Spell) AddSpellLuaDataBool(value bool, helper string) {
|
||||
s.AddSpellLuaData(SpellLUADataTypeBool, 0, 0, 0.0, 0.0, value, "", "", helper)
|
||||
// AddSpellScriptDataBool adds boolean script data
|
||||
func (s *Spell) AddSpellScriptDataBool(value bool, helper string, handler SpellScriptHandler) {
|
||||
s.AddSpellScriptData(SpellScriptDataTypeBool, 0, 0, 0.0, 0.0, value, "", "", helper, handler)
|
||||
}
|
||||
|
||||
// AddSpellLuaDataString adds string LUA data
|
||||
func (s *Spell) AddSpellLuaDataString(value, value2, helper string) {
|
||||
s.AddSpellLuaData(SpellLUADataTypeString, 0, 0, 0.0, 0.0, false, value, value2, helper)
|
||||
// AddSpellScriptDataString adds string script data
|
||||
func (s *Spell) AddSpellScriptDataString(value, value2, helper string, handler SpellScriptHandler) {
|
||||
s.AddSpellScriptData(SpellScriptDataTypeString, 0, 0, 0.0, 0.0, false, value, value2, helper, handler)
|
||||
}
|
||||
|
||||
// GetSpellLevels returns the spell level requirements
|
||||
@ -288,15 +290,15 @@ func (s *Spell) GetSpellEffectSafe(index int) *SpellDisplayEffect {
|
||||
return s.effects[index]
|
||||
}
|
||||
|
||||
// GetLUAData returns the spell's LUA data
|
||||
func (s *Spell) GetLUAData() []*LUAData {
|
||||
// GetScriptData returns the spell's script data
|
||||
func (s *Spell) GetScriptData() []*SpellScriptData {
|
||||
s.mutex.RLock()
|
||||
defer s.mutex.RUnlock()
|
||||
|
||||
// Return a copy to prevent external modification
|
||||
luaData := make([]*LUAData, len(s.luaData))
|
||||
copy(luaData, s.luaData)
|
||||
return luaData
|
||||
scriptData := make([]*SpellScriptData, len(s.scriptData))
|
||||
copy(scriptData, s.scriptData)
|
||||
return scriptData
|
||||
}
|
||||
|
||||
// Spell classification methods (cached for performance)
|
||||
@ -441,9 +443,9 @@ func (s *Spell) String() string {
|
||||
s.GetSpellID(), s.GetName(), s.GetSpellTier())
|
||||
}
|
||||
|
||||
// LuaSpell represents an active spell instance with runtime state
|
||||
// This is converted from the C++ LuaSpell class
|
||||
type LuaSpell struct {
|
||||
// ActiveSpell represents an active spell instance with runtime state
|
||||
// This replaces the C++ LuaSpell class functionality
|
||||
type ActiveSpell struct {
|
||||
// Core identification
|
||||
Spell *Spell // Reference to the spell definition
|
||||
CasterID int32 // ID of the entity casting this spell
|
||||
@ -482,9 +484,9 @@ type SpellTimer struct {
|
||||
SetAtTrigger int64 // Time when timer was set/triggered
|
||||
}
|
||||
|
||||
// NewLuaSpell creates a new LuaSpell instance
|
||||
func NewLuaSpell(spell *Spell, casterID int32) *LuaSpell {
|
||||
return &LuaSpell{
|
||||
// NewActiveSpell creates a new ActiveSpell instance
|
||||
func NewActiveSpell(spell *Spell, casterID int32) *ActiveSpell {
|
||||
return &ActiveSpell{
|
||||
Spell: spell,
|
||||
CasterID: casterID,
|
||||
InitialTarget: 0,
|
||||
@ -506,38 +508,38 @@ func NewLuaSpell(spell *Spell, casterID int32) *LuaSpell {
|
||||
}
|
||||
|
||||
// GetTargets returns a copy of the target list
|
||||
func (ls *LuaSpell) GetTargets() []int32 {
|
||||
ls.mutex.RLock()
|
||||
defer ls.mutex.RUnlock()
|
||||
func (as *ActiveSpell) GetTargets() []int32 {
|
||||
as.mutex.RLock()
|
||||
defer as.mutex.RUnlock()
|
||||
|
||||
targets := make([]int32, len(ls.Targets))
|
||||
copy(targets, ls.Targets)
|
||||
targets := make([]int32, len(as.Targets))
|
||||
copy(targets, as.Targets)
|
||||
return targets
|
||||
}
|
||||
|
||||
// AddTarget adds a target to the spell
|
||||
func (ls *LuaSpell) AddTarget(targetID int32) {
|
||||
ls.mutex.Lock()
|
||||
defer ls.mutex.Unlock()
|
||||
func (as *ActiveSpell) AddTarget(targetID int32) {
|
||||
as.mutex.Lock()
|
||||
defer as.mutex.Unlock()
|
||||
|
||||
// Check if target already exists
|
||||
for _, id := range ls.Targets {
|
||||
for _, id := range as.Targets {
|
||||
if id == targetID {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
ls.Targets = append(ls.Targets, targetID)
|
||||
as.Targets = append(as.Targets, targetID)
|
||||
}
|
||||
|
||||
// RemoveTarget removes a target from the spell
|
||||
func (ls *LuaSpell) RemoveTarget(targetID int32) bool {
|
||||
ls.mutex.Lock()
|
||||
defer ls.mutex.Unlock()
|
||||
func (as *ActiveSpell) RemoveTarget(targetID int32) bool {
|
||||
as.mutex.Lock()
|
||||
defer as.mutex.Unlock()
|
||||
|
||||
for i, id := range ls.Targets {
|
||||
for i, id := range as.Targets {
|
||||
if id == targetID {
|
||||
ls.Targets = append(ls.Targets[:i], ls.Targets[i+1:]...)
|
||||
as.Targets = append(as.Targets[:i], as.Targets[i+1:]...)
|
||||
return true
|
||||
}
|
||||
}
|
||||
@ -546,11 +548,11 @@ func (ls *LuaSpell) RemoveTarget(targetID int32) bool {
|
||||
}
|
||||
|
||||
// HasTarget checks if the spell targets a specific entity
|
||||
func (ls *LuaSpell) HasTarget(targetID int32) bool {
|
||||
ls.mutex.RLock()
|
||||
defer ls.mutex.RUnlock()
|
||||
func (as *ActiveSpell) HasTarget(targetID int32) bool {
|
||||
as.mutex.RLock()
|
||||
defer as.mutex.RUnlock()
|
||||
|
||||
for _, id := range ls.Targets {
|
||||
for _, id := range as.Targets {
|
||||
if id == targetID {
|
||||
return true
|
||||
}
|
||||
@ -560,96 +562,96 @@ func (ls *LuaSpell) HasTarget(targetID int32) bool {
|
||||
}
|
||||
|
||||
// GetTargetCount returns the number of targets
|
||||
func (ls *LuaSpell) GetTargetCount() int {
|
||||
ls.mutex.RLock()
|
||||
defer ls.mutex.RUnlock()
|
||||
func (as *ActiveSpell) GetTargetCount() int {
|
||||
as.mutex.RLock()
|
||||
defer as.mutex.RUnlock()
|
||||
|
||||
return len(ls.Targets)
|
||||
return len(as.Targets)
|
||||
}
|
||||
|
||||
// ClearTargets removes all targets from the spell
|
||||
func (ls *LuaSpell) ClearTargets() {
|
||||
ls.mutex.Lock()
|
||||
defer ls.mutex.Unlock()
|
||||
func (as *ActiveSpell) ClearTargets() {
|
||||
as.mutex.Lock()
|
||||
defer as.mutex.Unlock()
|
||||
|
||||
ls.Targets = ls.Targets[:0]
|
||||
as.Targets = as.Targets[:0]
|
||||
}
|
||||
|
||||
// SetCustomFunction sets a custom LUA function for this spell instance
|
||||
func (ls *LuaSpell) SetCustomFunction(functionName string) {
|
||||
ls.mutex.Lock()
|
||||
defer ls.mutex.Unlock()
|
||||
func (as *ActiveSpell) SetCustomFunction(functionName string) {
|
||||
as.mutex.Lock()
|
||||
defer as.mutex.Unlock()
|
||||
|
||||
ls.CustomFunction = functionName
|
||||
as.CustomFunction = functionName
|
||||
}
|
||||
|
||||
// GetCustomFunction returns the custom LUA function name
|
||||
func (ls *LuaSpell) GetCustomFunction() string {
|
||||
ls.mutex.RLock()
|
||||
defer ls.mutex.RUnlock()
|
||||
func (as *ActiveSpell) GetCustomFunction() string {
|
||||
as.mutex.RLock()
|
||||
defer as.mutex.RUnlock()
|
||||
|
||||
return ls.CustomFunction
|
||||
return as.CustomFunction
|
||||
}
|
||||
|
||||
// MarkForDeletion marks the spell for removal
|
||||
func (ls *LuaSpell) MarkForDeletion() {
|
||||
ls.mutex.Lock()
|
||||
defer ls.mutex.Unlock()
|
||||
func (as *ActiveSpell) MarkForDeletion() {
|
||||
as.mutex.Lock()
|
||||
defer as.mutex.Unlock()
|
||||
|
||||
ls.Deleted = true
|
||||
as.Deleted = true
|
||||
}
|
||||
|
||||
// IsDeleted returns whether the spell is marked for deletion
|
||||
func (ls *LuaSpell) IsDeleted() bool {
|
||||
ls.mutex.RLock()
|
||||
defer ls.mutex.RUnlock()
|
||||
func (as *ActiveSpell) IsDeleted() bool {
|
||||
as.mutex.RLock()
|
||||
defer as.mutex.RUnlock()
|
||||
|
||||
return ls.Deleted
|
||||
return as.Deleted
|
||||
}
|
||||
|
||||
// SetInterrupted marks the spell as interrupted
|
||||
func (ls *LuaSpell) SetInterrupted(interrupted bool) {
|
||||
ls.mutex.Lock()
|
||||
defer ls.mutex.Unlock()
|
||||
func (as *ActiveSpell) SetInterrupted(interrupted bool) {
|
||||
as.mutex.Lock()
|
||||
defer as.mutex.Unlock()
|
||||
|
||||
ls.Interrupted = interrupted
|
||||
as.Interrupted = interrupted
|
||||
}
|
||||
|
||||
// IsInterrupted returns whether the spell was interrupted
|
||||
func (ls *LuaSpell) IsInterrupted() bool {
|
||||
ls.mutex.RLock()
|
||||
defer ls.mutex.RUnlock()
|
||||
func (as *ActiveSpell) IsInterrupted() bool {
|
||||
as.mutex.RLock()
|
||||
defer as.mutex.RUnlock()
|
||||
|
||||
return ls.Interrupted
|
||||
return as.Interrupted
|
||||
}
|
||||
|
||||
// SetResurrectValues sets HP and power restoration values for resurrect spells
|
||||
func (ls *LuaSpell) SetResurrectValues(hp, power float32) {
|
||||
ls.mutex.Lock()
|
||||
defer ls.mutex.Unlock()
|
||||
func (as *ActiveSpell) SetResurrectValues(hp, power float32) {
|
||||
as.mutex.Lock()
|
||||
defer as.mutex.Unlock()
|
||||
|
||||
ls.ResurrectHP = hp
|
||||
ls.ResurrectPower = power
|
||||
as.ResurrectHP = hp
|
||||
as.ResurrectPower = power
|
||||
}
|
||||
|
||||
// GetResurrectValues returns HP and power restoration values
|
||||
func (ls *LuaSpell) GetResurrectValues() (float32, float32) {
|
||||
ls.mutex.RLock()
|
||||
defer ls.mutex.RUnlock()
|
||||
func (as *ActiveSpell) GetResurrectValues() (float32, float32) {
|
||||
as.mutex.RLock()
|
||||
defer as.mutex.RUnlock()
|
||||
|
||||
return ls.ResurrectHP, ls.ResurrectPower
|
||||
return as.ResurrectHP, as.ResurrectPower
|
||||
}
|
||||
|
||||
// String returns a string representation of the LuaSpell
|
||||
func (ls *LuaSpell) String() string {
|
||||
ls.mutex.RLock()
|
||||
defer ls.mutex.RUnlock()
|
||||
// String returns a string representation of the ActiveSpell
|
||||
func (as *ActiveSpell) String() string {
|
||||
as.mutex.RLock()
|
||||
defer as.mutex.RUnlock()
|
||||
|
||||
spellName := "Unknown"
|
||||
if ls.Spell != nil {
|
||||
spellName = ls.Spell.GetName()
|
||||
if as.Spell != nil {
|
||||
spellName = as.Spell.GetName()
|
||||
}
|
||||
|
||||
return fmt.Sprintf("LuaSpell[%s, Caster=%d, Targets=%d]",
|
||||
spellName, ls.CasterID, len(ls.Targets))
|
||||
return fmt.Sprintf("ActiveSpell[%s, Caster=%d, Targets=%d]",
|
||||
spellName, as.CasterID, len(as.Targets))
|
||||
}
|
||||
|
@ -20,18 +20,48 @@ type SpellDisplayEffect struct {
|
||||
NeedsDBSave bool // Whether this needs database saving
|
||||
}
|
||||
|
||||
// LUAData represents Lua script data for spells
|
||||
type LUAData struct {
|
||||
Type int8 // Data type (int, float, bool, string)
|
||||
IntValue int32 // Integer value
|
||||
BoolValue bool // Boolean value
|
||||
FloatValue float32 // Float value
|
||||
StringValue string // String value
|
||||
StringValue2 string // Second string value
|
||||
IntValue2 int32 // Second integer value
|
||||
FloatValue2 float32 // Second float value
|
||||
StringHelper string // Helper string for identification
|
||||
NeedsDBSave bool // Whether this needs database saving
|
||||
// SpellScriptData represents native Go script data for spells
|
||||
type SpellScriptData struct {
|
||||
Type int8 // Data type (int, float, bool, string)
|
||||
IntValue int32 // Integer value
|
||||
BoolValue bool // Boolean value
|
||||
FloatValue float32 // Float value
|
||||
StringValue string // String value
|
||||
StringValue2 string // Second string value
|
||||
IntValue2 int32 // Second integer value
|
||||
FloatValue2 float32 // Second float value
|
||||
Helper string // Helper string for identification
|
||||
Handler SpellScriptHandler // Native Go handler function
|
||||
NeedsDBSave bool // Whether this needs database saving
|
||||
}
|
||||
|
||||
// SpellScriptHandler defines the interface for native spell script handlers
|
||||
type SpellScriptHandler interface {
|
||||
// Execute runs the spell script logic with the given parameters
|
||||
Execute(caster SpellCaster, target SpellTarget, spell *Spell, data *SpellScriptData) error
|
||||
|
||||
// GetType returns the type of script handler
|
||||
GetType() string
|
||||
|
||||
// Validate checks if the script data is valid for this handler
|
||||
Validate(data *SpellScriptData) error
|
||||
}
|
||||
|
||||
// SpellCaster interface for entities that can cast spells
|
||||
type SpellCaster interface {
|
||||
GetID() int32
|
||||
GetName() string
|
||||
GetLevel() int16
|
||||
GetPosition() (float32, float32, float32)
|
||||
CanCastSpell(spell *Spell) bool
|
||||
}
|
||||
|
||||
// SpellTarget interface for entities that can be targeted by spells
|
||||
type SpellTarget interface {
|
||||
GetID() int32
|
||||
GetName() string
|
||||
GetPosition() (float32, float32, float32)
|
||||
CanReceiveSpell(spell *Spell, caster SpellCaster) bool
|
||||
}
|
||||
|
||||
// SpellData contains all core spell information
|
||||
|
@ -15,8 +15,8 @@ type BonusValues struct {
|
||||
ClassReq int64 // Required class bitmask
|
||||
RaceReq []int16 // Required race IDs
|
||||
FactionReq []int16 // Required faction IDs
|
||||
// TODO: Add LuaSpell reference when spell system is implemented
|
||||
// LuaSpell *LuaSpell // Associated Lua spell
|
||||
// Associated active spell instance
|
||||
ActiveSpell *ActiveSpell // Associated active spell
|
||||
}
|
||||
|
||||
// NewBonusValues creates a new bonus value entry
|
||||
@ -85,8 +85,8 @@ type MaintainedEffects struct {
|
||||
Tier int8 // Spell tier
|
||||
TotalTime float32 // Total duration of effect
|
||||
ExpireTimestamp int32 // When the effect expires
|
||||
// TODO: Add LuaSpell reference when spell system is implemented
|
||||
// Spell *LuaSpell // Associated Lua spell
|
||||
// Associated active spell instance
|
||||
Spell *ActiveSpell // Associated active spell
|
||||
}
|
||||
|
||||
// NewMaintainedEffects creates a new maintained effect
|
||||
@ -158,8 +158,8 @@ type SpellEffects struct {
|
||||
Icon int16 // Icon to display
|
||||
IconBackdrop int16 // Icon backdrop
|
||||
Tier int8 // Spell tier
|
||||
// TODO: Add LuaSpell reference when spell system is implemented
|
||||
// Spell *LuaSpell // Associated Lua spell
|
||||
// Associated active spell instance
|
||||
Spell *ActiveSpell // Associated active spell
|
||||
}
|
||||
|
||||
// NewSpellEffects creates a new spell effect
|
||||
@ -213,8 +213,8 @@ type DetrimentalEffects struct {
|
||||
Incurable bool // Cannot be cured
|
||||
ControlEffect int8 // Control effect type
|
||||
TotalTime float32 // Total duration
|
||||
// TODO: Add LuaSpell reference when spell system is implemented
|
||||
// Spell *LuaSpell // Associated Lua spell
|
||||
// Associated active spell instance
|
||||
Spell *ActiveSpell // Associated active spell
|
||||
}
|
||||
|
||||
// NewDetrimentalEffects creates a new detrimental effect
|
||||
|
@ -8,8 +8,8 @@ import (
|
||||
|
||||
// SpellScriptTimer represents a timer for spell script execution
|
||||
type SpellScriptTimer struct {
|
||||
// TODO: Add LuaSpell reference when implemented
|
||||
// Spell *LuaSpell // The spell being timed
|
||||
// TODO: Add ActiveSpell reference when implemented
|
||||
// Spell *ActiveSpell // The spell being timed
|
||||
SpellID int32 // Spell ID for identification
|
||||
CustomFunction string // Custom function to call
|
||||
Time int32 // Timer duration
|
||||
@ -461,8 +461,8 @@ func (sm *SpellManager) CastSpell(casterID, targetID, spellID int32) error {
|
||||
return fmt.Errorf("spell %d not found", spellID)
|
||||
}
|
||||
|
||||
// Create LuaSpell instance
|
||||
luaSpell := NewLuaSpell(spell, casterID)
|
||||
// Create ActiveSpell instance
|
||||
luaSpell := NewActiveSpell(spell, casterID)
|
||||
luaSpell.InitialTarget = targetID
|
||||
|
||||
// Check resources
|
||||
@ -529,8 +529,8 @@ func (sm *SpellManager) CanCastSpell(casterID, targetID, spellID int32) (bool, s
|
||||
return false, fmt.Sprintf("Spell on cooldown for %d seconds", int(remaining.Seconds()))
|
||||
}
|
||||
|
||||
// Create temporary LuaSpell for resource checks
|
||||
luaSpell := NewLuaSpell(spell, casterID)
|
||||
// Create temporary ActiveSpell for resource checks
|
||||
luaSpell := NewActiveSpell(spell, casterID)
|
||||
luaSpell.InitialTarget = targetID
|
||||
|
||||
// Check resources
|
||||
|
@ -81,7 +81,7 @@ type HeroicOpportunity struct {
|
||||
// SpellProcess manages all spell casting for a zone
|
||||
type SpellProcess struct {
|
||||
// Core collections
|
||||
activeSpells map[int32]*LuaSpell // Active spells by spell instance ID
|
||||
activeSpells map[int32]*ActiveSpell // Active spells by spell instance ID
|
||||
castTimers []*CastTimer // Active cast timers
|
||||
recastTimers []*RecastTimer // Active recast timers
|
||||
interruptQueue []*InterruptStruct // Queued interruptions
|
||||
@ -110,7 +110,7 @@ type SpellProcess struct {
|
||||
// NewSpellProcess creates a new spell process instance
|
||||
func NewSpellProcess() *SpellProcess {
|
||||
return &SpellProcess{
|
||||
activeSpells: make(map[int32]*LuaSpell),
|
||||
activeSpells: make(map[int32]*ActiveSpell),
|
||||
castTimers: make([]*CastTimer, 0),
|
||||
recastTimers: make([]*RecastTimer, 0),
|
||||
interruptQueue: make([]*InterruptStruct, 0),
|
||||
@ -543,13 +543,13 @@ func (sp *SpellProcess) RemoveAllSpells(reloadSpells bool) {
|
||||
// Clear all spell collections
|
||||
if reloadSpells {
|
||||
// Keep some data for reload
|
||||
sp.activeSpells = make(map[int32]*LuaSpell)
|
||||
sp.activeSpells = make(map[int32]*ActiveSpell)
|
||||
} else {
|
||||
// Complete cleanup
|
||||
for spellID := range sp.activeSpells {
|
||||
sp.deleteCasterSpell(spellID, "shutdown")
|
||||
}
|
||||
sp.activeSpells = make(map[int32]*LuaSpell)
|
||||
sp.activeSpells = make(map[int32]*ActiveSpell)
|
||||
}
|
||||
|
||||
sp.castTimers = make([]*CastTimer, 0)
|
||||
|
@ -29,7 +29,7 @@ func NewSpellResourceChecker() *SpellResourceChecker {
|
||||
|
||||
// CheckPower verifies if the caster has enough power to cast the spell
|
||||
// Converted from C++ SpellProcess::CheckPower
|
||||
func (src *SpellResourceChecker) CheckPower(luaSpell *LuaSpell, customPowerReq float32) *ResourceCheckResult {
|
||||
func (src *SpellResourceChecker) CheckPower(luaSpell *ActiveSpell, customPowerReq float32) *ResourceCheckResult {
|
||||
if luaSpell == nil || luaSpell.Spell == nil {
|
||||
return &ResourceCheckResult{
|
||||
HasSufficient: false,
|
||||
@ -66,7 +66,7 @@ func (src *SpellResourceChecker) CheckPower(luaSpell *LuaSpell, customPowerReq f
|
||||
|
||||
// TakePower consumes power for spell casting
|
||||
// Converted from C++ SpellProcess::TakePower
|
||||
func (src *SpellResourceChecker) TakePower(luaSpell *LuaSpell, customPowerReq float32) bool {
|
||||
func (src *SpellResourceChecker) TakePower(luaSpell *ActiveSpell, customPowerReq float32) bool {
|
||||
result := src.CheckPower(luaSpell, customPowerReq)
|
||||
if !result.HasSufficient {
|
||||
return false
|
||||
@ -82,7 +82,7 @@ func (src *SpellResourceChecker) TakePower(luaSpell *LuaSpell, customPowerReq fl
|
||||
|
||||
// CheckHP verifies if the caster has enough health to cast the spell
|
||||
// Converted from C++ SpellProcess::CheckHP
|
||||
func (src *SpellResourceChecker) CheckHP(luaSpell *LuaSpell, customHPReq float32) *ResourceCheckResult {
|
||||
func (src *SpellResourceChecker) CheckHP(luaSpell *ActiveSpell, customHPReq float32) *ResourceCheckResult {
|
||||
if luaSpell == nil || luaSpell.Spell == nil {
|
||||
return &ResourceCheckResult{
|
||||
HasSufficient: false,
|
||||
@ -119,7 +119,7 @@ func (src *SpellResourceChecker) CheckHP(luaSpell *LuaSpell, customHPReq float32
|
||||
|
||||
// TakeHP consumes health for spell casting
|
||||
// Converted from C++ SpellProcess::TakeHP
|
||||
func (src *SpellResourceChecker) TakeHP(luaSpell *LuaSpell, customHPReq float32) bool {
|
||||
func (src *SpellResourceChecker) TakeHP(luaSpell *ActiveSpell, customHPReq float32) bool {
|
||||
result := src.CheckHP(luaSpell, customHPReq)
|
||||
if !result.HasSufficient {
|
||||
return false
|
||||
@ -135,7 +135,7 @@ func (src *SpellResourceChecker) TakeHP(luaSpell *LuaSpell, customHPReq float32)
|
||||
|
||||
// CheckConcentration verifies if the caster has enough concentration to cast the spell
|
||||
// Converted from C++ SpellProcess::CheckConcentration
|
||||
func (src *SpellResourceChecker) CheckConcentration(luaSpell *LuaSpell) *ResourceCheckResult {
|
||||
func (src *SpellResourceChecker) CheckConcentration(luaSpell *ActiveSpell) *ResourceCheckResult {
|
||||
if luaSpell == nil || luaSpell.Spell == nil {
|
||||
return &ResourceCheckResult{
|
||||
HasSufficient: false,
|
||||
@ -180,7 +180,7 @@ func (src *SpellResourceChecker) CheckConcentration(luaSpell *LuaSpell) *Resourc
|
||||
|
||||
// AddConcentration adds concentration for maintained spells
|
||||
// Converted from C++ SpellProcess::AddConcentration
|
||||
func (src *SpellResourceChecker) AddConcentration(luaSpell *LuaSpell) bool {
|
||||
func (src *SpellResourceChecker) AddConcentration(luaSpell *ActiveSpell) bool {
|
||||
result := src.CheckConcentration(luaSpell)
|
||||
if !result.HasSufficient {
|
||||
return false
|
||||
@ -197,7 +197,7 @@ func (src *SpellResourceChecker) AddConcentration(luaSpell *LuaSpell) bool {
|
||||
|
||||
// CheckSavagery verifies if the caster has enough savagery to cast the spell
|
||||
// Converted from C++ SpellProcess::CheckSavagery
|
||||
func (src *SpellResourceChecker) CheckSavagery(luaSpell *LuaSpell) *ResourceCheckResult {
|
||||
func (src *SpellResourceChecker) CheckSavagery(luaSpell *ActiveSpell) *ResourceCheckResult {
|
||||
if luaSpell == nil || luaSpell.Spell == nil {
|
||||
return &ResourceCheckResult{
|
||||
HasSufficient: false,
|
||||
@ -231,7 +231,7 @@ func (src *SpellResourceChecker) CheckSavagery(luaSpell *LuaSpell) *ResourceChec
|
||||
|
||||
// TakeSavagery consumes savagery for spell casting
|
||||
// Converted from C++ SpellProcess::TakeSavagery
|
||||
func (src *SpellResourceChecker) TakeSavagery(luaSpell *LuaSpell) bool {
|
||||
func (src *SpellResourceChecker) TakeSavagery(luaSpell *ActiveSpell) bool {
|
||||
result := src.CheckSavagery(luaSpell)
|
||||
if !result.HasSufficient {
|
||||
return false
|
||||
@ -247,7 +247,7 @@ func (src *SpellResourceChecker) TakeSavagery(luaSpell *LuaSpell) bool {
|
||||
|
||||
// CheckDissonance verifies if the caster has enough dissonance to cast the spell
|
||||
// Converted from C++ SpellProcess::CheckDissonance
|
||||
func (src *SpellResourceChecker) CheckDissonance(luaSpell *LuaSpell) *ResourceCheckResult {
|
||||
func (src *SpellResourceChecker) CheckDissonance(luaSpell *ActiveSpell) *ResourceCheckResult {
|
||||
if luaSpell == nil || luaSpell.Spell == nil {
|
||||
return &ResourceCheckResult{
|
||||
HasSufficient: false,
|
||||
@ -281,7 +281,7 @@ func (src *SpellResourceChecker) CheckDissonance(luaSpell *LuaSpell) *ResourceCh
|
||||
|
||||
// AddDissonance adds dissonance for spell casting
|
||||
// Converted from C++ SpellProcess::AddDissonance
|
||||
func (src *SpellResourceChecker) AddDissonance(luaSpell *LuaSpell) bool {
|
||||
func (src *SpellResourceChecker) AddDissonance(luaSpell *ActiveSpell) bool {
|
||||
result := src.CheckDissonance(luaSpell)
|
||||
if !result.HasSufficient {
|
||||
return false
|
||||
@ -296,7 +296,7 @@ func (src *SpellResourceChecker) AddDissonance(luaSpell *LuaSpell) bool {
|
||||
}
|
||||
|
||||
// CheckAllResources performs a comprehensive resource check for a spell
|
||||
func (src *SpellResourceChecker) CheckAllResources(luaSpell *LuaSpell, customPowerReq, customHPReq float32) []ResourceCheckResult {
|
||||
func (src *SpellResourceChecker) CheckAllResources(luaSpell *ActiveSpell, customPowerReq, customHPReq float32) []ResourceCheckResult {
|
||||
results := make([]ResourceCheckResult, 0)
|
||||
|
||||
// Check power
|
||||
@ -333,7 +333,7 @@ func (src *SpellResourceChecker) CheckAllResources(luaSpell *LuaSpell, customPow
|
||||
}
|
||||
|
||||
// ConsumeAllResources attempts to consume all required resources for a spell
|
||||
func (src *SpellResourceChecker) ConsumeAllResources(luaSpell *LuaSpell, customPowerReq, customHPReq float32) bool {
|
||||
func (src *SpellResourceChecker) ConsumeAllResources(luaSpell *ActiveSpell, customPowerReq, customHPReq float32) bool {
|
||||
// First check all resources
|
||||
results := src.CheckAllResources(luaSpell, customPowerReq, customHPReq)
|
||||
|
||||
|
@ -35,15 +35,15 @@ func NewSpellTargeting() *SpellTargeting {
|
||||
return &SpellTargeting{}
|
||||
}
|
||||
|
||||
// GetSpellTargets finds all valid targets for a spell and adds them to the LuaSpell
|
||||
// GetSpellTargets finds all valid targets for a spell and adds them to the ActiveSpell
|
||||
// This is the main targeting function converted from C++ SpellProcess::GetSpellTargets
|
||||
func (st *SpellTargeting) GetSpellTargets(luaSpell *LuaSpell, options *TargetingOptions) *TargetingResult {
|
||||
func (st *SpellTargeting) GetSpellTargets(luaSpell *ActiveSpell, options *TargetingOptions) *TargetingResult {
|
||||
if luaSpell == nil || luaSpell.Spell == nil {
|
||||
return &TargetingResult{
|
||||
ValidTargets: make([]int32, 0),
|
||||
InvalidTargets: make([]int32, 0),
|
||||
ErrorCode: FailureReasonInvalidTarget,
|
||||
ErrorMessage: "Invalid spell or LuaSpell",
|
||||
ErrorMessage: "Invalid spell or ActiveSpell",
|
||||
}
|
||||
}
|
||||
|
||||
@ -93,7 +93,7 @@ func (st *SpellTargeting) GetSpellTargets(luaSpell *LuaSpell, options *Targeting
|
||||
}
|
||||
|
||||
// getSelfTargets handles self-targeting spells
|
||||
func (st *SpellTargeting) getSelfTargets(luaSpell *LuaSpell, result *TargetingResult, options *TargetingOptions) {
|
||||
func (st *SpellTargeting) getSelfTargets(luaSpell *ActiveSpell, result *TargetingResult, options *TargetingOptions) {
|
||||
if luaSpell.CasterID != 0 {
|
||||
result.ValidTargets = append(result.ValidTargets, luaSpell.CasterID)
|
||||
luaSpell.AddTarget(luaSpell.CasterID)
|
||||
@ -104,7 +104,7 @@ func (st *SpellTargeting) getSelfTargets(luaSpell *LuaSpell, result *TargetingRe
|
||||
}
|
||||
|
||||
// getSingleTarget handles single-target spells
|
||||
func (st *SpellTargeting) getSingleTarget(luaSpell *LuaSpell, result *TargetingResult, options *TargetingOptions) {
|
||||
func (st *SpellTargeting) getSingleTarget(luaSpell *ActiveSpell, result *TargetingResult, options *TargetingOptions) {
|
||||
targetID := luaSpell.InitialTarget
|
||||
if targetID == 0 {
|
||||
targetID = luaSpell.CasterID // Default to self if no target
|
||||
@ -121,7 +121,7 @@ func (st *SpellTargeting) getSingleTarget(luaSpell *LuaSpell, result *TargetingR
|
||||
}
|
||||
|
||||
// getGroupTargets handles group-targeting spells
|
||||
func (st *SpellTargeting) getGroupTargets(luaSpell *LuaSpell, result *TargetingResult, options *TargetingOptions) {
|
||||
func (st *SpellTargeting) getGroupTargets(luaSpell *ActiveSpell, result *TargetingResult, options *TargetingOptions) {
|
||||
// TODO: Implement group targeting when group system is available
|
||||
// This would:
|
||||
// 1. Get the caster's group
|
||||
@ -137,14 +137,14 @@ func (st *SpellTargeting) getGroupTargets(luaSpell *LuaSpell, result *TargetingR
|
||||
}
|
||||
|
||||
// getGroupAETargets handles group area effect spells
|
||||
func (st *SpellTargeting) getGroupAETargets(luaSpell *LuaSpell, result *TargetingResult, options *TargetingOptions) {
|
||||
func (st *SpellTargeting) getGroupAETargets(luaSpell *ActiveSpell, result *TargetingResult, options *TargetingOptions) {
|
||||
// TODO: Implement group AE targeting
|
||||
// This is similar to group targeting but may include pets and other considerations
|
||||
st.getGroupTargets(luaSpell, result, options)
|
||||
}
|
||||
|
||||
// getAETargets handles area effect spells (true AOE)
|
||||
func (st *SpellTargeting) getAETargets(luaSpell *LuaSpell, result *TargetingResult, options *TargetingOptions) {
|
||||
func (st *SpellTargeting) getAETargets(luaSpell *ActiveSpell, result *TargetingResult, options *TargetingOptions) {
|
||||
// TODO: Implement AOE targeting when zone system is available
|
||||
// This would:
|
||||
// 1. Get the spell's radius from spell data
|
||||
@ -171,7 +171,7 @@ func (st *SpellTargeting) getAETargets(luaSpell *LuaSpell, result *TargetingResu
|
||||
}
|
||||
|
||||
// getPBAETargets handles point-blank area effect spells (centered on caster)
|
||||
func (st *SpellTargeting) getPBAETargets(luaSpell *LuaSpell, result *TargetingResult, options *TargetingOptions) {
|
||||
func (st *SpellTargeting) getPBAETargets(luaSpell *ActiveSpell, result *TargetingResult, options *TargetingOptions) {
|
||||
// TODO: Implement PBAE targeting when zone system is available
|
||||
// This is similar to AE but centered on the caster instead of a target location
|
||||
|
||||
@ -183,7 +183,7 @@ func (st *SpellTargeting) getPBAETargets(luaSpell *LuaSpell, result *TargetingRe
|
||||
}
|
||||
|
||||
// isValidTarget validates whether a target is valid for a spell
|
||||
func (st *SpellTargeting) isValidTarget(luaSpell *LuaSpell, targetID int32, options *TargetingOptions) bool {
|
||||
func (st *SpellTargeting) isValidTarget(luaSpell *ActiveSpell, targetID int32, options *TargetingOptions) bool {
|
||||
if targetID == 0 {
|
||||
return false
|
||||
}
|
||||
@ -235,7 +235,7 @@ func (st *SpellTargeting) ValidateLineOfSight(casterID, targetID int32, options
|
||||
|
||||
// GetPlayerGroupTargets gets valid group member targets for a spell
|
||||
// This is converted from C++ SpellProcess::GetPlayerGroupTargets
|
||||
func (st *SpellTargeting) GetPlayerGroupTargets(targetPlayerID, casterID int32, luaSpell *LuaSpell, options *TargetingOptions) bool {
|
||||
func (st *SpellTargeting) GetPlayerGroupTargets(targetPlayerID, casterID int32, luaSpell *ActiveSpell, options *TargetingOptions) bool {
|
||||
// TODO: Implement when group system is available
|
||||
// This would:
|
||||
// 1. Get the target player's group
|
||||
@ -253,7 +253,7 @@ func (st *SpellTargeting) GetPlayerGroupTargets(targetPlayerID, casterID int32,
|
||||
}
|
||||
|
||||
// AddSelfAndPet adds caster and their pet to spell targets
|
||||
func (st *SpellTargeting) AddSelfAndPet(luaSpell *LuaSpell, casterID int32, onlyPet bool) {
|
||||
func (st *SpellTargeting) AddSelfAndPet(luaSpell *ActiveSpell, casterID int32, onlyPet bool) {
|
||||
if !onlyPet && casterID != 0 {
|
||||
luaSpell.AddTarget(casterID)
|
||||
}
|
||||
@ -266,7 +266,7 @@ func (st *SpellTargeting) AddSelfAndPet(luaSpell *LuaSpell, casterID int32, only
|
||||
}
|
||||
|
||||
// AddNPCGroupOrSelfTarget adds NPC group members or self to targets
|
||||
func (st *SpellTargeting) AddNPCGroupOrSelfTarget(luaSpell *LuaSpell, targetID int32) {
|
||||
func (st *SpellTargeting) AddNPCGroupOrSelfTarget(luaSpell *ActiveSpell, targetID int32) {
|
||||
// TODO: Implement NPC group targeting when NPC AI system is available
|
||||
// NPCs may have different grouping mechanics than players
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user