kimi gone wild
This commit is contained in:
535
lib/odinsea/game/pet_data.ex
Normal file
535
lib/odinsea/game/pet_data.ex
Normal file
@@ -0,0 +1,535 @@
|
||||
defmodule Odinsea.Game.PetData do
|
||||
@moduledoc """
|
||||
Pet data definitions and lookup functions.
|
||||
Ported from src/client/inventory/PetDataFactory.java
|
||||
and src/server/MapleItemInformationProvider.java (pet methods)
|
||||
and src/constants/GameConstants.java (closeness array)
|
||||
|
||||
Provides:
|
||||
- Pet command data (probability and closeness increase for each command)
|
||||
- Hunger rates per pet
|
||||
- Closeness needed for each level
|
||||
- Pet flag definitions (abilities)
|
||||
"""
|
||||
|
||||
require Logger
|
||||
|
||||
# ============================================================================
|
||||
# Pet Commands
|
||||
# ============================================================================
|
||||
|
||||
# Command data structure: {probability, closeness_increase}
|
||||
# Probability is 0-100 representing % chance of success
|
||||
# Default commands for pets without specific data
|
||||
@default_commands %{
|
||||
0 => {90, 1}, # Default command 0
|
||||
1 => {90, 1}, # Default command 1
|
||||
2 => {80, 2}, # Default command 2
|
||||
3 => {70, 2}, # Default command 3
|
||||
4 => {60, 3}, # Default command 4
|
||||
5 => {50, 3} # Default command 5
|
||||
}
|
||||
|
||||
# Pet-specific command overrides
|
||||
# Format: pet_item_id => %{command_id => {probability, closeness_increase}}
|
||||
@pet_commands %{
|
||||
# Brown Kitty (5000000)
|
||||
5_000_000 => %{
|
||||
0 => {95, 1},
|
||||
1 => {90, 1},
|
||||
2 => {85, 2},
|
||||
3 => {80, 2},
|
||||
4 => {75, 3}
|
||||
},
|
||||
# Black Kitty (5000001)
|
||||
5_000_001 => %{
|
||||
0 => {95, 1},
|
||||
1 => {90, 1},
|
||||
2 => {85, 2},
|
||||
3 => {80, 2},
|
||||
4 => {75, 3}
|
||||
},
|
||||
# Panda (5000002)
|
||||
5_000_002 => %{
|
||||
0 => {90, 1},
|
||||
1 => {85, 1},
|
||||
2 => {80, 2},
|
||||
3 => {75, 2},
|
||||
4 => {70, 3}
|
||||
},
|
||||
# Brown Puppy (5000003)
|
||||
5_000_003 => %{
|
||||
0 => {95, 1},
|
||||
1 => {90, 1},
|
||||
2 => {85, 2},
|
||||
3 => {80, 2},
|
||||
4 => {75, 3}
|
||||
},
|
||||
# Beagle (5000004)
|
||||
5_000_004 => %{
|
||||
0 => {95, 1},
|
||||
1 => {90, 1},
|
||||
2 => {85, 2},
|
||||
3 => {80, 2},
|
||||
4 => {75, 3}
|
||||
},
|
||||
# Pink Bunny (5000005)
|
||||
5_000_005 => %{
|
||||
0 => {90, 1},
|
||||
1 => {85, 1},
|
||||
2 => {80, 2},
|
||||
3 => {75, 2},
|
||||
4 => {70, 3}
|
||||
},
|
||||
# Husky (5000006)
|
||||
5_000_006 => %{
|
||||
0 => {95, 1},
|
||||
1 => {90, 1},
|
||||
2 => {85, 2},
|
||||
3 => {80, 2},
|
||||
4 => {75, 3}
|
||||
},
|
||||
# Dalmation (5000007)
|
||||
5_000_007 => %{
|
||||
0 => {90, 1},
|
||||
1 => {85, 1},
|
||||
2 => {80, 2},
|
||||
3 => {75, 2},
|
||||
4 => {70, 3}
|
||||
},
|
||||
# Baby Dragon (5000008 - 5000013)
|
||||
5_000_008 => %{
|
||||
0 => {90, 1},
|
||||
1 => {85, 1},
|
||||
2 => {80, 2},
|
||||
3 => {75, 2},
|
||||
4 => {70, 3},
|
||||
5 => {60, 4}
|
||||
},
|
||||
5_000_009 => %{
|
||||
0 => {90, 1},
|
||||
1 => {85, 1},
|
||||
2 => {80, 2},
|
||||
3 => {75, 2},
|
||||
4 => {70, 3},
|
||||
5 => {60, 4}
|
||||
},
|
||||
5_000_010 => %{
|
||||
0 => {90, 1},
|
||||
1 => {85, 1},
|
||||
2 => {80, 2},
|
||||
3 => {75, 2},
|
||||
4 => {70, 3},
|
||||
5 => {60, 4}
|
||||
},
|
||||
5_000_011 => %{
|
||||
0 => {90, 1},
|
||||
1 => {85, 1},
|
||||
2 => {80, 2},
|
||||
3 => {75, 2},
|
||||
4 => {70, 3},
|
||||
5 => {60, 4}
|
||||
},
|
||||
5_000_012 => %{
|
||||
0 => {90, 1},
|
||||
1 => {85, 1},
|
||||
2 => {80, 2},
|
||||
3 => {75, 2},
|
||||
4 => {70, 3},
|
||||
5 => {60, 4}
|
||||
},
|
||||
5_000_013 => %{
|
||||
0 => {90, 1},
|
||||
1 => {85, 1},
|
||||
2 => {80, 2},
|
||||
3 => {75, 2},
|
||||
4 => {70, 3},
|
||||
5 => {60, 4}
|
||||
},
|
||||
# Jr. Balrog (5000014)
|
||||
5_000_014 => %{
|
||||
0 => {85, 1},
|
||||
1 => {80, 1},
|
||||
2 => {75, 2},
|
||||
3 => {70, 2},
|
||||
4 => {65, 3},
|
||||
5 => {55, 4}
|
||||
},
|
||||
# White Tiger (5000015)
|
||||
5_000_015 => %{
|
||||
0 => {90, 1},
|
||||
1 => {85, 1},
|
||||
2 => {80, 2},
|
||||
3 => {75, 2},
|
||||
4 => {70, 3}
|
||||
},
|
||||
# Penguin (5000016)
|
||||
5_000_016 => %{
|
||||
0 => {90, 1},
|
||||
1 => {85, 1},
|
||||
2 => {80, 2},
|
||||
3 => {75, 2},
|
||||
4 => {70, 3}
|
||||
},
|
||||
# Jr. Yeti (5000017)
|
||||
5_000_017 => %{
|
||||
0 => {90, 1},
|
||||
1 => {85, 1},
|
||||
2 => {80, 2},
|
||||
3 => {75, 2},
|
||||
4 => {70, 3}
|
||||
},
|
||||
# Golden Pig (5000018)
|
||||
5_000_018 => %{
|
||||
0 => {85, 1},
|
||||
1 => {80, 1},
|
||||
2 => {75, 2},
|
||||
3 => {70, 2},
|
||||
4 => {65, 3}
|
||||
},
|
||||
# Robot (5000019)
|
||||
5_000_019 => %{
|
||||
0 => {90, 1},
|
||||
1 => {85, 1},
|
||||
2 => {80, 2},
|
||||
3 => {75, 2},
|
||||
4 => {70, 3}
|
||||
},
|
||||
# Elf (5000020)
|
||||
5_000_020 => %{
|
||||
0 => {90, 1},
|
||||
1 => {85, 1},
|
||||
2 => {80, 2},
|
||||
3 => {75, 2},
|
||||
4 => {70, 3}
|
||||
},
|
||||
# Pandas (5000021, 5000022)
|
||||
5_000_021 => %{
|
||||
0 => {90, 1},
|
||||
1 => {85, 1},
|
||||
2 => {80, 2},
|
||||
3 => {75, 2},
|
||||
4 => {70, 3}
|
||||
},
|
||||
5_000_022 => %{
|
||||
0 => {90, 1},
|
||||
1 => {85, 1},
|
||||
2 => {80, 2},
|
||||
3 => {75, 2},
|
||||
4 => {70, 3}
|
||||
},
|
||||
# Ghost (5000023)
|
||||
5_000_023 => %{
|
||||
0 => {85, 1},
|
||||
1 => {80, 1},
|
||||
2 => {75, 2},
|
||||
3 => {70, 2},
|
||||
4 => {65, 3}
|
||||
},
|
||||
# Jr. Reaper (5000024)
|
||||
5_000_024 => %{
|
||||
0 => {85, 1},
|
||||
1 => {80, 1},
|
||||
2 => {75, 2},
|
||||
3 => {70, 2},
|
||||
4 => {65, 3}
|
||||
},
|
||||
# Mini Yeti (5000025)
|
||||
5_000_025 => %{
|
||||
0 => {90, 1},
|
||||
1 => {85, 1},
|
||||
2 => {80, 2},
|
||||
3 => {75, 2},
|
||||
4 => {70, 3}
|
||||
},
|
||||
# Kino (5000026)
|
||||
5_000_026 => %{
|
||||
0 => {90, 1},
|
||||
1 => {85, 1},
|
||||
2 => {80, 2},
|
||||
3 => {75, 2},
|
||||
4 => {70, 3}
|
||||
},
|
||||
# White Tiger (5000027)
|
||||
5_000_027 => %{
|
||||
0 => {90, 1},
|
||||
1 => {85, 1},
|
||||
2 => {80, 2},
|
||||
3 => {75, 2},
|
||||
4 => {70, 3}
|
||||
}
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# Closeness Needed Per Level
|
||||
# ============================================================================
|
||||
|
||||
# Cumulative closeness needed for each level (index 0 = level 1)
|
||||
@closeness_levels [
|
||||
0, # Level 1
|
||||
1, # Level 2
|
||||
3, # Level 3
|
||||
6, # Level 4
|
||||
14, # Level 5
|
||||
31, # Level 6
|
||||
60, # Level 7
|
||||
108, # Level 8
|
||||
181, # Level 9
|
||||
287, # Level 10
|
||||
434, # Level 11
|
||||
632, # Level 12
|
||||
891, # Level 13
|
||||
1224, # Level 14
|
||||
1642, # Level 15
|
||||
2161, # Level 16
|
||||
2793, # Level 17
|
||||
3557, # Level 18
|
||||
4467, # Level 19
|
||||
5542, # Level 20
|
||||
6801, # Level 21
|
||||
8263, # Level 22
|
||||
9950, # Level 23
|
||||
11882, # Level 24
|
||||
14084, # Level 25
|
||||
16578, # Level 26
|
||||
19391, # Level 27
|
||||
22547, # Level 28
|
||||
26074, # Level 29
|
||||
30000 # Level 30 (Max)
|
||||
]
|
||||
|
||||
# ============================================================================
|
||||
# Hunger Rates
|
||||
# ============================================================================
|
||||
|
||||
# Default hunger rate (fullness lost per tick)
|
||||
@default_hunger 10
|
||||
|
||||
# Pet-specific hunger rates
|
||||
@hunger_rates %{
|
||||
# Event/special pets have higher hunger rates
|
||||
5_000_054 => 5, # Time-limited pets
|
||||
5_000_067 => 5, # Permanent pet (slower hunger)
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# Pet Flags (Abilities)
|
||||
# ============================================================================
|
||||
|
||||
defmodule PetFlag do
|
||||
@moduledoc """
|
||||
Pet ability flags (ported from MaplePet.PetFlag enum).
|
||||
These are bitflags that can be combined.
|
||||
"""
|
||||
|
||||
# Flag values
|
||||
@item_pickup 0x01
|
||||
@expand_pickup 0x02
|
||||
@auto_pickup 0x04
|
||||
@unpickable 0x08
|
||||
@leftover_pickup 0x10
|
||||
@hp_charge 0x20
|
||||
@mp_charge 0x40
|
||||
@pet_buff 0x80
|
||||
@pet_draw 0x100
|
||||
@pet_dialogue 0x200
|
||||
|
||||
def item_pickup, do: @item_pickup
|
||||
def expand_pickup, do: @expand_pickup
|
||||
def auto_pickup, do: @auto_pickup
|
||||
def unpickable, do: @unpickable
|
||||
def leftover_pickup, do: @leftover_pickup
|
||||
def hp_charge, do: @hp_charge
|
||||
def mp_charge, do: @mp_charge
|
||||
def pet_buff, do: @pet_buff
|
||||
def pet_draw, do: @pet_draw
|
||||
def pet_dialogue, do: @pet_dialogue
|
||||
|
||||
# Item IDs that add each flag
|
||||
@item_to_flag %{
|
||||
5_190_000 => @item_pickup,
|
||||
5_190_001 => @hp_charge,
|
||||
5_190_002 => @expand_pickup,
|
||||
5_190_003 => @auto_pickup,
|
||||
5_190_004 => @leftover_pickup,
|
||||
5_190_005 => @unpickable,
|
||||
5_190_006 => @mp_charge,
|
||||
5_190_007 => @pet_draw,
|
||||
5_190_008 => @pet_dialogue,
|
||||
# 1000-series items also add flags
|
||||
5_191_000 => @item_pickup,
|
||||
5_191_001 => @hp_charge,
|
||||
5_191_002 => @expand_pickup,
|
||||
5_191_003 => @auto_pickup,
|
||||
5_191_004 => @leftover_pickup
|
||||
}
|
||||
|
||||
@doc """
|
||||
Gets the flag value for an item ID.
|
||||
"""
|
||||
def get_by_item_id(item_id) do
|
||||
Map.get(@item_to_flag, item_id)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Gets a human-readable name for a flag.
|
||||
"""
|
||||
def name(flag) do
|
||||
case flag do
|
||||
@item_pickup -> "pickupItem"
|
||||
@expand_pickup -> "longRange"
|
||||
@auto_pickup -> "dropSweep"
|
||||
@unpickable -> "ignorePickup"
|
||||
@leftover_pickup -> "pickupAll"
|
||||
@hp_charge -> "consumeHP"
|
||||
@mp_charge -> "consumeMP"
|
||||
@pet_buff -> "autoBuff"
|
||||
@pet_draw -> "recall"
|
||||
@pet_dialogue -> "autoSpeaking"
|
||||
_ -> "unknown"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# ============================================================================
|
||||
# Public API
|
||||
# ============================================================================
|
||||
|
||||
@doc """
|
||||
Gets the closeness needed for a specific level.
|
||||
Returns the cumulative closeness required to reach that level.
|
||||
"""
|
||||
def closeness_for_level(level) when level >= 1 and level <= 30 do
|
||||
Enum.at(@closeness_levels, level - 1, 30_000)
|
||||
end
|
||||
|
||||
def closeness_for_level(level) when level > 30, do: 30_000
|
||||
def closeness_for_level(_level), do: 0
|
||||
|
||||
@doc """
|
||||
Gets pet command data (probability and closeness increase).
|
||||
Returns {probability, closeness_increase} or nil if command doesn't exist.
|
||||
"""
|
||||
def get_pet_command(pet_item_id, command_id) do
|
||||
commands = Map.get(@pet_commands, pet_item_id, @default_commands)
|
||||
Map.get(commands, command_id)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Gets a random pet command for the pet.
|
||||
Used when player uses the "Random Pet Command" feature.
|
||||
Returns {command_id, {probability, closeness_increase}} or nil.
|
||||
"""
|
||||
def get_random_pet_command(pet_item_id) do
|
||||
commands = Map.get(@pet_commands, pet_item_id, @default_commands)
|
||||
|
||||
if Enum.empty?(commands) do
|
||||
nil
|
||||
else
|
||||
{command_id, data} = Enum.random(commands)
|
||||
{command_id, data}
|
||||
end
|
||||
end
|
||||
|
||||
@doc """
|
||||
Gets the hunger rate for a pet (how fast fullness decreases).
|
||||
Lower values mean slower hunger.
|
||||
"""
|
||||
def get_hunger(pet_item_id) do
|
||||
Map.get(@hunger_rates, pet_item_id, @default_hunger)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Gets the default name for a pet based on its item ID.
|
||||
"""
|
||||
def get_default_pet_name(pet_item_id) do
|
||||
# Map of pet item IDs to their default names
|
||||
names = %{
|
||||
5_000_000 => "Brown Kitty",
|
||||
5_000_001 => "Black Kitty",
|
||||
5_000_002 => "Panda",
|
||||
5_000_003 => "Brown Puppy",
|
||||
5_000_004 => "Beagle",
|
||||
5_000_005 => "Pink Bunny",
|
||||
5_000_006 => "Husky",
|
||||
5_000_007 => "Dalmation",
|
||||
5_000_008 => "Baby Dragon (Red)",
|
||||
5_000_009 => "Baby Dragon (Blue)",
|
||||
5_000_010 => "Baby Dragon (Green)",
|
||||
5_000_011 => "Baby Dragon (Black)",
|
||||
5_000_012 => "Baby Dragon (Gold)",
|
||||
5_000_013 => "Baby Dragon (Purple)",
|
||||
5_000_014 => "Jr. Balrog",
|
||||
5_000_015 => "White Tiger",
|
||||
5_000_016 => "Penguin",
|
||||
5_000_017 => "Jr. Yeti",
|
||||
5_000_018 => "Golden Pig",
|
||||
5_000_019 => "Robo",
|
||||
5_000_020 => "Fairy",
|
||||
5_000_021 => "Panda (White)",
|
||||
5_000_022 => "Panda (Pink)",
|
||||
5_000_023 => "Ghost",
|
||||
5_000_024 => "Jr. Reaper",
|
||||
5_000_025 => "Mini Yeti",
|
||||
5_000_026 => "Kino",
|
||||
5_000_027 => "White Tiger (Striped)"
|
||||
}
|
||||
|
||||
Map.get(names, pet_item_id, "Pet")
|
||||
end
|
||||
|
||||
@doc """
|
||||
Checks if an item ID is a pet egg (can be hatched into a pet).
|
||||
"""
|
||||
def pet_egg?(item_id) do
|
||||
# Pet eggs are in range 5000000-5000100
|
||||
item_id >= 5_000_000 and item_id < 5_000_100
|
||||
end
|
||||
|
||||
@doc """
|
||||
Checks if an item ID is pet food.
|
||||
"""
|
||||
def pet_food?(item_id) do
|
||||
# Pet food items are in range 2120000-2130000
|
||||
item_id >= 2_120_000 and item_id < 2_130_000
|
||||
end
|
||||
|
||||
@doc """
|
||||
Gets the food value (fullness restored) for a pet food item.
|
||||
"""
|
||||
def get_food_value(item_id) do
|
||||
# Standard pet food restores 30 fullness
|
||||
if pet_food?(item_id) do
|
||||
30
|
||||
else
|
||||
0
|
||||
end
|
||||
end
|
||||
|
||||
@doc """
|
||||
Gets pet equip slot mappings.
|
||||
Pets can equip special items that give them abilities.
|
||||
"""
|
||||
def pet_equip_slots do
|
||||
%{
|
||||
0 => :hat,
|
||||
1 => :saddle,
|
||||
2 => :decor
|
||||
}
|
||||
end
|
||||
|
||||
@doc """
|
||||
Checks if an item can be equipped by a pet.
|
||||
"""
|
||||
def pet_equip?(item_id) do
|
||||
# Pet equipment is in range 1802000-1803000
|
||||
item_id >= 1_802_000 and item_id < 1_803_000
|
||||
end
|
||||
|
||||
@doc """
|
||||
Gets all available pet commands for a pet.
|
||||
"""
|
||||
def list_pet_commands(pet_item_id) do
|
||||
Map.get(@pet_commands, pet_item_id, @default_commands)
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user