182 lines
6.6 KiB
Markdown

# EQ2Go Event System
A simplified event-driven system for handling game logic without the complexity of a full scripting engine.
## Overview
The event system provides:
- Simple event registration and execution
- Context-based parameter passing
- 100+ built-in EQ2 game functions organized by domain
- Thread-safe operations
- Minimal overhead
- Domain-specific function organization
## Basic Usage
```go
// Create event handler
handler := NewEventHandler()
// Register all EQ2 functions (100+ functions organized by domain)
err := functions.RegisterAllEQ2Functions(handler)
// Create context and execute event
ctx := NewEventContext(EventTypeSpawn, "SetCurrentHP", "heal_spell").
WithSpawn(player).
WithParameter("hp", 150.0)
err = handler.Execute(ctx)
```
## Event Context
The `EventContext` provides:
- Game objects: `Caster`, `Target`, `Spawn`, `Quest`
- Parameters: Type-safe parameter access
- Results: Return values from event functions
- Logging: Built-in debug/info/warn/error logging
### Fluent API
```go
ctx := NewEventContext(EventTypeSpell, "heal", "cast").
WithCaster(caster).
WithTarget(target).
WithParameter("spell_id", 123).
WithParameter("power_cost", 50)
```
### Parameter Access
```go
func MyEvent(ctx *EventContext) error {
spellID := ctx.GetParameterInt("spell_id", 0)
message := ctx.GetParameterString("message", "default")
amount := ctx.GetParameterFloat("amount", 0.0)
enabled := ctx.GetParameterBool("enabled", false)
// Set results
ctx.SetResult("damage_dealt", 150)
return nil
}
```
## Available EQ2 Functions
The system provides 100+ functions organized by domain:
### Health Domain (23 functions)
- **HP Management**: `SetCurrentHP`, `SetMaxHP`, `SetMaxHPBase`, `GetCurrentHP`, `GetMaxHP`, `GetMaxHPBase`
- **Power Management**: `SetCurrentPower`, `SetMaxPower`, `SetMaxPowerBase`, `GetCurrentPower`, `GetMaxPower`, `GetMaxPowerBase`
- **Modifiers**: `ModifyHP`, `ModifyPower`, `ModifyMaxHP`, `ModifyMaxPower`, `ModifyTotalHP`, `ModifyTotalPower`
- **Percentages**: `GetPCTOfHP`, `GetPCTOfPower`
- **Healing**: `SpellHeal`, `SpellHealPct`
- **State**: `IsAlive`
### Attributes Domain (24 functions)
- **Stats**: `SetInt`, `SetWis`, `SetSta`, `SetStr`, `SetAgi`, `GetInt`, `GetWis`, `GetSta`, `GetStr`, `GetAgi`
- **Base Stats**: `SetIntBase`, `SetWisBase`, `SetStaBase`, `SetStrBase`, `SetAgiBase`, `GetIntBase`, `GetWisBase`, `GetStaBase`, `GetStrBase`, `GetAgiBase`
- **Character Info**: `GetLevel`, `SetLevel`, `SetPlayerLevel`, `GetDifficulty`, `GetClass`, `SetClass`, `SetAdventureClass`
- **Classes**: `GetTradeskillClass`, `SetTradeskillClass`, `GetTradeskillLevel`, `SetTradeskillLevel`
- **Identity**: `GetRace`, `GetGender`, `GetModelType`, `SetModelType`, `GetDeity`, `SetDeity`, `GetAlignment`, `SetAlignment`
- **Bonuses**: `AddSpellBonus`, `RemoveSpellBonus`, `AddSkillBonus`, `RemoveSkillBonus`
### Movement Domain (27 functions)
- **Position**: `SetPosition`, `GetPosition`, `GetX`, `GetY`, `GetZ`, `GetHeading`, `SetHeading`
- **Original Position**: `GetOrigX`, `GetOrigY`, `GetOrigZ`
- **Distance & Facing**: `GetDistance`, `FaceTarget`
- **Speed**: `GetSpeed`, `SetSpeed`, `SetSpeedMultiplier`, `HasMoved`, `IsRunning`
- **Movement**: `MoveToLocation`, `ClearRunningLocations`, `SpawnMove`, `MovementLoopAdd`, `PauseMovement`, `StopMovement`
- **Mounts**: `SetMount`, `GetMount`, `SetMountColor`, `StartAutoMount`, `EndAutoMount`, `IsOnAutoMount`
- **Waypoints**: `AddWaypoint`, `RemoveWaypoint`, `SendWaypoints`
- **Transport**: `Evac`, `Bind`, `Gate`
### Combat Domain (36 functions)
- **Basic Combat**: `Attack`, `AddHate`, `ClearHate`, `GetMostHated`, `SetTarget`, `GetTarget`
- **Combat State**: `IsInCombat`, `SetInCombat`, `IsCasting`, `HasRecovered`
- **Damage**: `SpellDamage`, `SpellDamageExt`, `DamageSpawn`, `ProcDamage`, `ProcHate`
- **Effects**: `Knockback`, `Interrupt`
- **Processing**: `ProcessMelee`, `ProcessSpell`, `LastSpellAttackHit`
- **Positioning**: `IsBehind`, `IsFlanking`, `InFront`
- **Encounters**: `GetEncounterSize`, `GetEncounter`, `GetHateList`, `ClearEncounter`
- **AI**: `ClearRunback`, `Runback`, `GetRunbackDistance`, `CompareSpawns`
- **Life/Death**: `KillSpawn`, `KillSpawnByDistance`, `Resurrect`
- **Invulnerability**: `IsInvulnerable`, `SetInvulnerable`, `SetAttackable`
### Miscellaneous Domain (27 functions)
- **Messaging**: `SendMessage`, `LogMessage`
- **Utility**: `MakeRandomInt`, `MakeRandomFloat`, `ParseInt`
- **Identity**: `GetName`, `GetID`, `GetSpawnID`, `IsPlayer`, `IsNPC`, `IsEntity`, `IsDead`, `GetCharacterID`
- **Spawning**: `Despawn`, `Spawn`, `SpawnByLocationID`, `SpawnGroupByID`, `DespawnByLocationID`
- **Groups**: `GetSpawnByLocationID`, `GetSpawnByGroupID`, `GetSpawnGroupID`, `SetSpawnGroupID`, `AddSpawnToGroup`, `IsSpawnGroupAlive`
- **Location**: `GetSpawnLocationID`, `GetSpawnLocationPlacementID`, `SetGridID`
- **Spawn Management**: `SpawnSet`, `SpawnSetByDistance`
- **Variables**: `GetVariableValue`, `SetServerVariable`, `GetServerVariable`, `SetTempVariable`, `GetTempVariable`
- **Line of Sight**: `CheckLOS`, `CheckLOSByCoordinates`
## Function Organization
Access functions by domain using the `functions` package:
```go
import "eq2emu/internal/events/functions"
// Register all functions at once
handler := events.NewEventHandler()
err := functions.RegisterAllEQ2Functions(handler)
// Get functions organized by domain
domains := functions.GetFunctionsByDomain()
healthFunctions := domains["health"] // 23 functions
combatFunctions := domains["combat"] // 36 functions
movementFunctions := domains["movement"] // 27 functions
// ... etc
```
## Custom Events
```go
// Register custom event
handler.Register("my_custom_event", func(ctx *events.EventContext) error {
spawn := ctx.GetSpawn()
if spawn == nil {
return fmt.Errorf("no spawn provided")
}
// Custom logic here
ctx.Debug("Custom event executed for %s", spawn.GetName())
return nil
})
// Execute custom event
ctx := events.NewEventContext(events.EventTypeSpawn, "my_custom_event", "trigger").
WithSpawn(someSpawn)
err := handler.Execute(ctx)
```
## Event Types
- `EventTypeSpell` - Spell-related events
- `EventTypeSpawn` - Spawn-related events
- `EventTypeQuest` - Quest-related events
- `EventTypeCombat` - Combat-related events
- `EventTypeZone` - Zone-related events
- `EventTypeItem` - Item-related events
## Thread Safety
All operations are thread-safe:
- Event registration/unregistration
- Context parameter/result access
- Event execution
## Performance
The event system is designed for minimal overhead:
- No complex registry or statistics
- Direct function calls
- Simple context passing
- Optional timeout support