179 lines
4.1 KiB
Elixir
179 lines
4.1 KiB
Elixir
defmodule Odinsea.Game.Events do
|
|
@moduledoc """
|
|
Event type definitions and map IDs.
|
|
Ported from Java `server.events.MapleEventType`.
|
|
|
|
Each event type has associated map IDs where the event takes place.
|
|
"""
|
|
|
|
@typedoc "Event type atom"
|
|
@type t :: :coconut | :coke_play | :fitness | :ola_ola | :ox_quiz | :survival | :snowball
|
|
|
|
# ============================================================================
|
|
# Event Map IDs
|
|
# ============================================================================
|
|
|
|
@event_maps %{
|
|
# Coconut event - team-based coconut hitting
|
|
coconut: [109080000],
|
|
|
|
# Coke Play event (similar to coconut)
|
|
coke_play: [109080010],
|
|
|
|
# Fitness event - 4 stage obstacle course
|
|
fitness: [109040000, 109040001, 109040002, 109040003, 109040004],
|
|
|
|
# Ola Ola event - 3 stage portal guessing game
|
|
ola_ola: [109030001, 109030002, 109030003],
|
|
|
|
# OX Quiz event - True/False quiz
|
|
ox_quiz: [109020001],
|
|
|
|
# Survival event - Last man standing (2 maps)
|
|
survival: [809040000, 809040100],
|
|
|
|
# Snowball event - Team snowball rolling competition
|
|
snowball: [109060000]
|
|
}
|
|
|
|
@doc """
|
|
Returns all event types.
|
|
"""
|
|
def all do
|
|
Map.keys(@event_maps)
|
|
end
|
|
|
|
@doc """
|
|
Returns the map IDs for a given event type.
|
|
|
|
## Examples
|
|
|
|
iex> Odinsea.Game.Events.map_ids(:coconut)
|
|
[109080000]
|
|
|
|
iex> Odinsea.Game.Events.map_ids(:fitness)
|
|
[109040000, 109040001, 109040002, 109040003, 109040004]
|
|
"""
|
|
def map_ids(event_type) do
|
|
Map.get(@event_maps, event_type, [])
|
|
end
|
|
|
|
@doc """
|
|
Returns the entry map ID (first map) for an event type.
|
|
"""
|
|
def entry_map_id(event_type) do
|
|
case map_ids(event_type) do
|
|
[first | _] -> first
|
|
[] -> nil
|
|
end
|
|
end
|
|
|
|
@doc """
|
|
Gets an event type by string name (case-insensitive).
|
|
|
|
## Examples
|
|
|
|
iex> Odinsea.Game.Events.get_by_string("coconut")
|
|
:coconut
|
|
|
|
iex> Odinsea.Game.Events.get_by_string("OX_QUIZ")
|
|
:ox_quiz
|
|
|
|
iex> Odinsea.Game.Events.get_by_string("invalid")
|
|
nil
|
|
"""
|
|
def get_by_string(str) when is_binary(str) do
|
|
str = String.downcase(str)
|
|
|
|
Enum.find(all(), fn type ->
|
|
Atom.to_string(type) == str or
|
|
String.replace(Atom.to_string(type), "_", "") == str
|
|
end)
|
|
end
|
|
|
|
def get_by_string(_), do: nil
|
|
|
|
@doc """
|
|
Returns a human-readable name for the event type.
|
|
|
|
## Examples
|
|
|
|
iex> Odinsea.Game.Events.display_name(:coconut)
|
|
"Coconut"
|
|
|
|
iex> Odinsea.Game.Events.display_name(:ola_ola)
|
|
"Ola Ola"
|
|
"""
|
|
def display_name(event_type) do
|
|
event_type
|
|
|> Atom.to_string()
|
|
|> String.replace("_", " ")
|
|
|> String.split()
|
|
|> Enum.map(&String.capitalize/1)
|
|
|> Enum.join(" ")
|
|
end
|
|
|
|
@doc """
|
|
Returns the number of stages/maps for an event.
|
|
"""
|
|
def stage_count(event_type) do
|
|
length(map_ids(event_type))
|
|
end
|
|
|
|
@doc """
|
|
Checks if a map ID belongs to any event.
|
|
Returns the event type if found, nil otherwise.
|
|
"""
|
|
def event_for_map(map_id) when is_integer(map_id) do
|
|
Enum.find(all(), fn type ->
|
|
map_id in map_ids(type)
|
|
end)
|
|
end
|
|
|
|
def event_for_map(_), do: nil
|
|
|
|
@doc """
|
|
Checks if a map ID is the finish map (109050000).
|
|
"""
|
|
def finish_map?(109050000), do: true
|
|
def finish_map?(_), do: false
|
|
|
|
@doc """
|
|
Returns true if the event is a race-type event (timed).
|
|
"""
|
|
def race_event?(:fitness), do: true
|
|
def race_event?(:ola_ola), do: true
|
|
def race_event?(:survival), do: true
|
|
def race_event?(_), do: false
|
|
|
|
@doc """
|
|
Returns true if the event is team-based.
|
|
"""
|
|
def team_event?(:coconut), do: true
|
|
def team_event?(:snowball), do: true
|
|
def team_event?(_), do: false
|
|
|
|
@doc """
|
|
Returns true if the event has multiple stages.
|
|
"""
|
|
def multi_stage?(event_type) do
|
|
stage_count(event_type) > 1
|
|
end
|
|
|
|
@doc """
|
|
Returns the stage index for a map ID within an event.
|
|
Returns 0-based index or nil if not part of event.
|
|
"""
|
|
def stage_index(event_type, map_id) do
|
|
map_ids(event_type)
|
|
|> Enum.find_index(&(&1 == map_id))
|
|
end
|
|
|
|
@doc """
|
|
Returns all event data as a map.
|
|
"""
|
|
def all_event_data do
|
|
@event_maps
|
|
end
|
|
end
|