380 lines
11 KiB
Elixir
380 lines
11 KiB
Elixir
defmodule Odinsea.Scripting.Behavior do
|
|
@moduledoc """
|
|
Behavior module defining callbacks for Odinsea game scripts.
|
|
|
|
This behavior is implemented by script modules that are dynamically
|
|
compiled from script files or created manually as Elixir modules.
|
|
|
|
The scripting system supports the following script types:
|
|
- NPC scripts (conversation/dialogue) - uses `cm` (conversation manager)
|
|
- Quest scripts - uses `qm` (quest manager)
|
|
- Portal scripts - uses `pi` (portal interaction)
|
|
- Reactor scripts - uses `rm` (reactor manager)
|
|
- Event scripts - uses `em` (event manager)
|
|
|
|
## Script Globals
|
|
|
|
When scripts are executed, they have access to these globals:
|
|
|
|
| Variable | Type | Description |
|
|
|----------|------|-------------|
|
|
| `cm` | `Odinsea.Scripting.PlayerAPI` | NPC conversation manager |
|
|
| `qm` | `Odinsea.Scripting.PlayerAPI` | Quest conversation manager |
|
|
| `pi` | `Odinsea.Scripting.PlayerAPI` | Portal interaction |
|
|
| `rm` | `Odinsea.Scripting.PlayerAPI` | Reactor actions |
|
|
| `em` | `Odinsea.Scripting.EventManager` | Event management |
|
|
| `eim` | `Odinsea.Scripting.EventInstance` | Event instance (for events) |
|
|
|
|
## Script Examples
|
|
|
|
### NPC Script (Elixir module)
|
|
|
|
defmodule Odinsea.Scripting.NPC.Script_1002001 do
|
|
@behaviour Odinsea.Scripting.Behavior
|
|
|
|
@impl true
|
|
def start(cm) do
|
|
Odinsea.Scripting.PlayerAPI.send_ok(cm, "Hello! I'm Cody. Nice to meet you!")
|
|
end
|
|
|
|
@impl true
|
|
def action(cm, _mode, _type, _selection) do
|
|
Odinsea.Scripting.PlayerAPI.dispose(cm)
|
|
end
|
|
end
|
|
|
|
### Portal Script (Elixir module)
|
|
|
|
defmodule Odinsea.Scripting.Portal.Script_08_xmas_st do
|
|
@behaviour Odinsea.Scripting.Behavior
|
|
|
|
@impl true
|
|
def enter(pi) do
|
|
# Portal logic here
|
|
:ok
|
|
end
|
|
end
|
|
|
|
### Event Script (Elixir module)
|
|
|
|
defmodule Odinsea.Scripting.Event.Boats do
|
|
@behaviour Odinsea.Scripting.Behavior
|
|
|
|
@impl true
|
|
def init(em) do
|
|
# Initialize event
|
|
schedule_new(em)
|
|
end
|
|
|
|
@impl true
|
|
def schedule(em, method_name, delay) do
|
|
# Handle scheduled callback
|
|
end
|
|
|
|
@impl true
|
|
def player_entry(eim, player) do
|
|
# Handle player entering event
|
|
end
|
|
end
|
|
"""
|
|
|
|
# ============================================================================
|
|
# NPC/Quest Script Callbacks
|
|
# ============================================================================
|
|
|
|
@doc """
|
|
Called when an NPC conversation starts.
|
|
|
|
## Parameters
|
|
- `api` - The conversation manager (`cm` for NPC, `qm` for quest)
|
|
"""
|
|
@callback start(api :: Odinsea.Scripting.PlayerAPI.t()) :: any()
|
|
|
|
@doc """
|
|
Called when a player responds to an NPC dialogue.
|
|
|
|
## Parameters
|
|
- `api` - The conversation manager
|
|
- `mode` - The mode byte (0 = cancel/end, 1 = next/yes)
|
|
- `type` - The type byte (usually 0)
|
|
- `selection` - The player's selection (for menus)
|
|
"""
|
|
@callback action(api :: Odinsea.Scripting.PlayerAPI.t(),
|
|
mode :: integer(),
|
|
type :: integer(),
|
|
selection :: integer()) :: any()
|
|
|
|
# ============================================================================
|
|
# Quest Script Callbacks (alternative to action for quest scripts)
|
|
# ============================================================================
|
|
|
|
@doc """
|
|
Called when a quest starts (alternative to `action` for quests).
|
|
"""
|
|
@callback quest_start(api :: Odinsea.Scripting.PlayerAPI.t(),
|
|
mode :: integer(),
|
|
type :: integer(),
|
|
selection :: integer()) :: any()
|
|
|
|
@doc """
|
|
Called when a quest ends/completes (alternative to `action` for quests).
|
|
"""
|
|
@callback quest_end(api :: Odinsea.Scripting.PlayerAPI.t(),
|
|
mode :: integer(),
|
|
type :: integer(),
|
|
selection :: integer()) :: any()
|
|
|
|
# ============================================================================
|
|
# Portal Script Callbacks
|
|
# ============================================================================
|
|
|
|
@doc """
|
|
Called when a player enters a scripted portal.
|
|
|
|
## Parameters
|
|
- `api` - The portal interaction manager
|
|
|
|
## Returns
|
|
- `:ok` - Portal handling successful
|
|
- `{:error, reason}` - Portal handling failed
|
|
"""
|
|
@callback enter(api :: Odinsea.Scripting.PlayerAPI.t()) :: :ok | {:error, term()}
|
|
|
|
# ============================================================================
|
|
# Reactor Script Callbacks
|
|
# ============================================================================
|
|
|
|
@doc """
|
|
Called when a reactor is activated/hit.
|
|
|
|
## Parameters
|
|
- `api` - The reactor action manager
|
|
"""
|
|
@callback act(api :: Odinsea.Scripting.PlayerAPI.t()) :: any()
|
|
|
|
# ============================================================================
|
|
# Event Script Callbacks
|
|
# ============================================================================
|
|
|
|
@doc """
|
|
Called when an event is initialized (after ChannelServer loads).
|
|
|
|
## Parameters
|
|
- `em` - The event manager
|
|
"""
|
|
@callback init(em :: Odinsea.Scripting.EventManager.t()) :: any()
|
|
|
|
@doc """
|
|
Called to set up an event instance.
|
|
|
|
## Parameters
|
|
- `em` - The event manager (or eim for some setups)
|
|
- `args` - Variable arguments depending on event type
|
|
"""
|
|
@callback setup(em :: Odinsea.Scripting.EventManager.t(), args :: term()) :: any()
|
|
|
|
@doc """
|
|
Called when a player enters an event instance.
|
|
|
|
## Parameters
|
|
- `eim` - The event instance manager
|
|
- `player` - The player character
|
|
"""
|
|
@callback player_entry(eim :: Odinsea.Scripting.EventInstance.t(),
|
|
player :: Odinsea.Game.Character.t()) :: any()
|
|
|
|
@doc """
|
|
Called when a player changes maps within an event.
|
|
|
|
## Parameters
|
|
- `eim` - The event instance manager
|
|
- `player` - The player character
|
|
- `map_id` - The new map ID
|
|
"""
|
|
@callback changed_map(eim :: Odinsea.Scripting.EventInstance.t(),
|
|
player :: Odinsea.Game.Character.t(),
|
|
map_id :: integer()) :: any()
|
|
|
|
@doc """
|
|
Called when an event times out.
|
|
|
|
## Parameters
|
|
- `eim` - The event instance manager
|
|
"""
|
|
@callback scheduled_timeout(eim :: Odinsea.Scripting.EventInstance.t()) :: any()
|
|
|
|
@doc """
|
|
Called when all monsters in an event are killed.
|
|
|
|
## Parameters
|
|
- `eim` - The event instance manager
|
|
"""
|
|
@callback all_monsters_dead(eim :: Odinsea.Scripting.EventInstance.t()) :: any()
|
|
|
|
@doc """
|
|
Called when a player dies in an event.
|
|
|
|
## Parameters
|
|
- `eim` - The event instance manager
|
|
- `player` - The player character
|
|
"""
|
|
@callback player_dead(eim :: Odinsea.Scripting.EventInstance.t(),
|
|
player :: Odinsea.Game.Character.t()) :: any()
|
|
|
|
@doc """
|
|
Called when a player is revived in an event.
|
|
|
|
## Parameters
|
|
- `eim` - The event instance manager
|
|
- `player` - The player character
|
|
|
|
## Returns
|
|
- `true` - Allow revive
|
|
- `false` - Deny revive
|
|
"""
|
|
@callback player_revive(eim :: Odinsea.Scripting.EventInstance.t(),
|
|
player :: Odinsea.Game.Character.t()) :: boolean()
|
|
|
|
@doc """
|
|
Called when a player disconnects from an event.
|
|
|
|
## Parameters
|
|
- `eim` - The event instance manager
|
|
- `player` - The player character
|
|
|
|
## Returns
|
|
- `0` - Deregister normally, dispose if no players left
|
|
- `x > 0` - Deregister, dispose if less than x players
|
|
- `x < 0` - Deregister, dispose if less than |x| players, boot all if leader
|
|
"""
|
|
@callback player_disconnected(eim :: Odinsea.Scripting.EventInstance.t(),
|
|
player :: Odinsea.Game.Character.t()) :: integer()
|
|
|
|
@doc """
|
|
Called when a monster is killed in an event.
|
|
|
|
## Parameters
|
|
- `eim` - The event instance manager
|
|
- `mob_id` - The monster ID
|
|
|
|
## Returns
|
|
- Points value for this monster kill
|
|
"""
|
|
@callback monster_value(eim :: Odinsea.Scripting.EventInstance.t(),
|
|
mob_id :: integer()) :: integer()
|
|
|
|
@doc """
|
|
Called when a player leaves the party in an event.
|
|
|
|
## Parameters
|
|
- `eim` - The event instance manager
|
|
- `player` - The player character
|
|
"""
|
|
@callback left_party(eim :: Odinsea.Scripting.EventInstance.t(),
|
|
player :: Odinsea.Game.Character.t()) :: any()
|
|
|
|
@doc """
|
|
Called when a party is disbanded in an event.
|
|
|
|
## Parameters
|
|
- `eim` - The event instance manager
|
|
"""
|
|
@callback disband_party(eim :: Odinsea.Scripting.EventInstance.t()) :: any()
|
|
|
|
@doc """
|
|
Called when a party quest is cleared.
|
|
|
|
## Parameters
|
|
- `eim` - The event instance manager
|
|
"""
|
|
@callback clear_pq(eim :: Odinsea.Scripting.EventInstance.t()) :: any()
|
|
|
|
@doc """
|
|
Called when a player is removed from an event.
|
|
|
|
## Parameters
|
|
- `eim` - The event instance manager
|
|
- `player` - The player character
|
|
"""
|
|
@callback player_exit(eim :: Odinsea.Scripting.EventInstance.t(),
|
|
player :: Odinsea.Game.Character.t()) :: any()
|
|
|
|
@doc """
|
|
Called for scheduled event methods.
|
|
|
|
## Parameters
|
|
- `em` - The event manager
|
|
- `method_name` - The name of the method to call
|
|
- `delay` - The delay in milliseconds
|
|
"""
|
|
@callback schedule(em :: Odinsea.Scripting.EventManager.t(),
|
|
method_name :: String.t(),
|
|
delay :: integer()) :: any()
|
|
|
|
@doc """
|
|
Called when an event's schedule is cancelled.
|
|
|
|
## Parameters
|
|
- `em` - The event manager
|
|
"""
|
|
@callback cancel_schedule(em :: Odinsea.Scripting.EventManager.t()) :: any()
|
|
|
|
@doc """
|
|
Called when a carnival party is registered.
|
|
|
|
## Parameters
|
|
- `eim` - The event instance manager
|
|
- `carnival_party` - The carnival party data
|
|
"""
|
|
@callback register_carnival_party(eim :: Odinsea.Scripting.EventInstance.t(),
|
|
carnival_party :: term()) :: any()
|
|
|
|
@doc """
|
|
Called when a player loads a map in an event.
|
|
|
|
## Parameters
|
|
- `eim` - The event instance manager
|
|
- `player` - The player character
|
|
"""
|
|
@callback on_map_load(eim :: Odinsea.Scripting.EventInstance.t(),
|
|
player :: Odinsea.Game.Character.t()) :: any()
|
|
|
|
# ============================================================================
|
|
# Optional Callbacks
|
|
# ============================================================================
|
|
|
|
@optional_callbacks [
|
|
# NPC/Quest callbacks
|
|
start: 1,
|
|
action: 4,
|
|
quest_start: 4,
|
|
quest_end: 4,
|
|
|
|
# Portal callbacks
|
|
enter: 1,
|
|
|
|
# Reactor callbacks
|
|
act: 1,
|
|
|
|
# Event callbacks
|
|
init: 1,
|
|
setup: 2,
|
|
player_entry: 2,
|
|
changed_map: 3,
|
|
scheduled_timeout: 1,
|
|
all_monsters_dead: 1,
|
|
player_dead: 2,
|
|
player_revive: 2,
|
|
player_disconnected: 2,
|
|
monster_value: 2,
|
|
left_party: 2,
|
|
disband_party: 1,
|
|
clear_pq: 1,
|
|
player_exit: 2,
|
|
schedule: 3,
|
|
cancel_schedule: 1,
|
|
register_carnival_party: 2,
|
|
on_map_load: 2
|
|
]
|
|
end
|