package functions import ( "fmt" "math" "strconv" "strings" "eq2emu/internal/events" ) // Miscellaneous Utility Functions // SendMessage sends a message (placeholder implementation) func SendMessage(ctx *events.EventContext) error { message := ctx.GetParameterString("message", "") if message == "" { return fmt.Errorf("message parameter required") } // TODO: Implement message sending ctx.Info("Message: %s", message) return nil } // LogMessage logs a message at specified level func LogMessage(ctx *events.EventContext) error { level := ctx.GetParameterString("level", "info") message := ctx.GetParameterString("message", "") if message == "" { return fmt.Errorf("message parameter required") } switch strings.ToLower(level) { case "debug": ctx.Debug("%s", message) case "info": ctx.Info("%s", message) case "warn", "warning": ctx.Warn("%s", message) case "error": ctx.Error("%s", message) default: ctx.Info("%s", message) } return nil } // MakeRandomInt generates a random integer func MakeRandomInt(ctx *events.EventContext) error { min := ctx.GetParameterInt("min", 0) max := ctx.GetParameterInt("max", 100) if min > max { min, max = max, min } // Simple random - in practice you'd use a proper random generator result := min + (int(math.Abs(float64(ctx.EventName[0]))) % (max - min + 1)) ctx.SetResult("random_int", result) return nil } // MakeRandomFloat generates a random float func MakeRandomFloat(ctx *events.EventContext) error { min := ctx.GetParameterFloat("min", 0.0) max := ctx.GetParameterFloat("max", 1.0) if min > max { min, max = max, min } // Simple random float - in practice you'd use a proper random generator ratio := float64(int(math.Abs(float64(ctx.EventName[0]))) % 100) / 100.0 result := min + (max-min)*ratio ctx.SetResult("random_float", result) return nil } // ParseInt parses a string to integer func ParseInt(ctx *events.EventContext) error { str := ctx.GetParameterString("string", "") if str == "" { return fmt.Errorf("string parameter required") } value, err := strconv.Atoi(str) if err != nil { return fmt.Errorf("failed to parse integer: %w", err) } ctx.SetResult("int_value", value) return nil } // GetName gets the spawn's name func GetName(ctx *events.EventContext) error { spawn := ctx.GetSpawn() if spawn == nil { return fmt.Errorf("no spawn in context") } ctx.SetResult("name", spawn.GetName()) return nil } // GetID gets the spawn's ID func GetID(ctx *events.EventContext) error { spawn := ctx.GetSpawn() if spawn == nil { return fmt.Errorf("no spawn in context") } ctx.SetResult("id", spawn.GetID()) return nil } // GetSpawnID gets the spawn's ID (alias for GetID) func GetSpawnID(ctx *events.EventContext) error { return GetID(ctx) } // IsPlayer checks if spawn is a player func IsPlayer(ctx *events.EventContext) error { spawn := ctx.GetSpawn() if spawn == nil { return fmt.Errorf("no spawn in context") } ctx.SetResult("is_player", spawn.IsPlayer()) return nil } // IsNPC checks if spawn is an NPC func IsNPC(ctx *events.EventContext) error { spawn := ctx.GetSpawn() if spawn == nil { return fmt.Errorf("no spawn in context") } ctx.SetResult("is_npc", spawn.IsNPC()) return nil } // IsEntity checks if spawn is an entity func IsEntity(ctx *events.EventContext) error { spawn := ctx.GetSpawn() if spawn == nil { return fmt.Errorf("no spawn in context") } // TODO: Implement entity checking when Entity interface is available ctx.SetResult("is_entity", false) // Default for now return nil } // IsDead checks if spawn is dead func IsDead(ctx *events.EventContext) error { spawn := ctx.GetSpawn() if spawn == nil { return fmt.Errorf("no spawn in context") } ctx.SetResult("is_dead", !spawn.IsAlive()) return nil } // GetCharacterID gets the character ID for players func GetCharacterID(ctx *events.EventContext) error { spawn := ctx.GetSpawn() if spawn == nil { return fmt.Errorf("no spawn in context") } if !spawn.IsPlayer() { return fmt.Errorf("spawn is not a player") } // TODO: Implement character ID retrieval ctx.SetResult("character_id", 0) // Default value return nil } // Despawn removes the spawn from the world func Despawn(ctx *events.EventContext) error { spawn := ctx.GetSpawn() if spawn == nil { return fmt.Errorf("no spawn in context") } // TODO: Implement despawn logic ctx.Debug("Despawned spawn %s (not yet implemented)", spawn.GetName()) return nil } // Spawn creates a new spawn func Spawn(ctx *events.EventContext) error { locationID := ctx.GetParameterInt("location_id", 0) spawnGroupID := ctx.GetParameterInt("spawn_group_id", 0) // TODO: Implement spawn creation ctx.Debug("Created spawn at location %d, group %d (not yet implemented)", locationID, spawnGroupID) ctx.SetResult("spawned", true) return nil } // SpawnByLocationID spawns by location ID func SpawnByLocationID(ctx *events.EventContext) error { locationID := ctx.GetParameterInt("location_id", 0) if locationID <= 0 { return fmt.Errorf("invalid location ID") } // TODO: Implement location-based spawning ctx.Debug("Spawned by location ID %d (not yet implemented)", locationID) ctx.SetResult("spawned", true) return nil } // SpawnGroupByID spawns a group by ID func SpawnGroupByID(ctx *events.EventContext) error { groupID := ctx.GetParameterInt("group_id", 0) if groupID <= 0 { return fmt.Errorf("invalid group ID") } // TODO: Implement group spawning ctx.Debug("Spawned group ID %d (not yet implemented)", groupID) ctx.SetResult("spawned", true) return nil } // DespawnByLocationID despawns spawns at a location func DespawnByLocationID(ctx *events.EventContext) error { locationID := ctx.GetParameterInt("location_id", 0) if locationID <= 0 { return fmt.Errorf("invalid location ID") } // TODO: Implement location-based despawning ctx.Debug("Despawned location ID %d (not yet implemented)", locationID) return nil } // GetSpawnByLocationID gets spawn by location ID func GetSpawnByLocationID(ctx *events.EventContext) error { locationID := ctx.GetParameterInt("location_id", 0) if locationID <= 0 { return fmt.Errorf("invalid location ID") } // TODO: Implement spawn retrieval by location ctx.SetResult("spawn", nil) // No spawn found return nil } // GetSpawnByGroupID gets spawn by group ID func GetSpawnByGroupID(ctx *events.EventContext) error { groupID := ctx.GetParameterInt("group_id", 0) if groupID <= 0 { return fmt.Errorf("invalid group ID") } // TODO: Implement spawn retrieval by group ctx.SetResult("spawn", nil) // No spawn found return nil } // GetSpawnGroupID gets the spawn's group ID func GetSpawnGroupID(ctx *events.EventContext) error { spawn := ctx.GetSpawn() if spawn == nil { return fmt.Errorf("no spawn in context") } // TODO: Implement group ID retrieval ctx.SetResult("group_id", 0) // Default value return nil } // SetSpawnGroupID sets the spawn's group ID func SetSpawnGroupID(ctx *events.EventContext) error { spawn := ctx.GetSpawn() if spawn == nil { return fmt.Errorf("no spawn in context") } groupID := ctx.GetParameterInt("group_id", 0) // TODO: Implement group ID setting ctx.Debug("Set group ID to %d for spawn %s (not yet implemented)", groupID, spawn.GetName()) return nil } // GetSpawnLocationID gets the spawn's location ID func GetSpawnLocationID(ctx *events.EventContext) error { spawn := ctx.GetSpawn() if spawn == nil { return fmt.Errorf("no spawn in context") } // TODO: Implement location ID retrieval ctx.SetResult("location_id", 0) // Default value return nil } // GetSpawnLocationPlacementID gets the spawn's location placement ID func GetSpawnLocationPlacementID(ctx *events.EventContext) error { spawn := ctx.GetSpawn() if spawn == nil { return fmt.Errorf("no spawn in context") } // TODO: Implement location placement ID retrieval ctx.SetResult("placement_id", 0) // Default value return nil } // SetGridID sets the spawn's grid ID func SetGridID(ctx *events.EventContext) error { spawn := ctx.GetSpawn() if spawn == nil { return fmt.Errorf("no spawn in context") } gridID := ctx.GetParameterInt("grid_id", 0) // TODO: Implement grid ID setting ctx.Debug("Set grid ID to %d for spawn %s (not yet implemented)", gridID, spawn.GetName()) return nil } // SpawnSet sets spawn properties by distance/criteria func SpawnSet(ctx *events.EventContext) error { spawn := ctx.GetSpawn() if spawn == nil { return fmt.Errorf("no spawn in context") } property := ctx.GetParameterString("property", "") value := ctx.GetParameterString("value", "") // TODO: Implement spawn property setting ctx.Debug("Set property %s to %s for spawn %s (not yet implemented)", property, value, spawn.GetName()) return nil } // SpawnSetByDistance sets spawn properties within distance func SpawnSetByDistance(ctx *events.EventContext) error { spawn := ctx.GetSpawn() if spawn == nil { return fmt.Errorf("no spawn in context") } distance := ctx.GetParameterFloat("distance", 10.0) property := ctx.GetParameterString("property", "") value := ctx.GetParameterString("value", "") // TODO: Implement distance-based spawn property setting ctx.Debug("Set property %s to %s within distance %f of spawn %s (not yet implemented)", property, value, distance, spawn.GetName()) return nil } // IsSpawnGroupAlive checks if spawn group is alive func IsSpawnGroupAlive(ctx *events.EventContext) error { groupID := ctx.GetParameterInt("group_id", 0) if groupID <= 0 { return fmt.Errorf("invalid group ID") } // TODO: Implement group alive checking ctx.SetResult("group_alive", false) // Default value return nil } // AddSpawnToGroup adds spawn to a group func AddSpawnToGroup(ctx *events.EventContext) error { spawn := ctx.GetSpawn() if spawn == nil { return fmt.Errorf("no spawn in context") } groupID := ctx.GetParameterInt("group_id", 0) if groupID <= 0 { return fmt.Errorf("invalid group ID") } // TODO: Implement group addition ctx.Debug("Added spawn %s to group %d (not yet implemented)", spawn.GetName(), groupID) return nil } // GetVariableValue gets a variable value func GetVariableValue(ctx *events.EventContext) error { variableName := ctx.GetParameterString("variable", "") if variableName == "" { return fmt.Errorf("variable name required") } // TODO: Implement variable system ctx.SetResult("value", "") // Default empty value return nil } // SetServerVariable sets a server variable func SetServerVariable(ctx *events.EventContext) error { variableName := ctx.GetParameterString("variable", "") value := ctx.GetParameterString("value", "") if variableName == "" { return fmt.Errorf("variable name required") } // TODO: Implement server variable system ctx.Debug("Set server variable %s to %s (not yet implemented)", variableName, value) return nil } // GetServerVariable gets a server variable func GetServerVariable(ctx *events.EventContext) error { variableName := ctx.GetParameterString("variable", "") if variableName == "" { return fmt.Errorf("variable name required") } // TODO: Implement server variable system ctx.SetResult("value", "") // Default empty value return nil } // SetTempVariable sets a temporary variable func SetTempVariable(ctx *events.EventContext) error { variableName := ctx.GetParameterString("variable", "") value := ctx.GetParameterString("value", "") if variableName == "" { return fmt.Errorf("variable name required") } // TODO: Implement temporary variable system ctx.Debug("Set temp variable %s to %s (not yet implemented)", variableName, value) return nil } // GetTempVariable gets a temporary variable func GetTempVariable(ctx *events.EventContext) error { variableName := ctx.GetParameterString("variable", "") if variableName == "" { return fmt.Errorf("variable name required") } // TODO: Implement temporary variable system ctx.SetResult("value", "") // Default empty value return nil } // CheckLOS checks line of sight between two positions func CheckLOS(ctx *events.EventContext) error { spawn := ctx.GetSpawn() target := ctx.GetTarget() if spawn == nil { return fmt.Errorf("no spawn in context") } if target == nil { return fmt.Errorf("no target in context") } // TODO: Implement line of sight checking ctx.SetResult("has_los", true) // Default to true return nil } // CheckLOSByCoordinates checks line of sight between coordinates func CheckLOSByCoordinates(ctx *events.EventContext) error { x1 := ctx.GetParameterFloat("x1", 0) y1 := ctx.GetParameterFloat("y1", 0) z1 := ctx.GetParameterFloat("z1", 0) x2 := ctx.GetParameterFloat("x2", 0) y2 := ctx.GetParameterFloat("y2", 0) z2 := ctx.GetParameterFloat("z2", 0) // TODO: Implement coordinate-based line of sight checking ctx.Debug("Checking LOS from (%.2f,%.2f,%.2f) to (%.2f,%.2f,%.2f) (not yet implemented)", x1, y1, z1, x2, y2, z2) ctx.SetResult("has_los", true) // Default to true return nil }