diff --git a/component-explorer/main.lua b/component-explorer/main.lua index 2925db9..c379a38 100644 --- a/component-explorer/main.lua +++ b/component-explorer/main.lua @@ -3,7 +3,9 @@ imgui = load_imgui({version="1.7.0", mod="Component Explorer"}) ---@module 'component-explorer.utils.ce_settings' local ce_settings = dofile_once("mods/component-explorer/utils/ce_settings.lua") + dofile_once("mods/component-explorer/lua_console.lua") + ---@module 'component-explorer.globals' local globals = dofile_once("mods/component-explorer/globals.lua") @@ -48,6 +50,14 @@ local herd_relation = dofile_once("mods/component-explorer/herd_relation.lua") ---@module 'component-explorer.cursor' local cursor = dofile_once("mods/component-explorer/cursor.lua") +---@module 'component-explorer.spawn_stuff' +local spawn_stuff = dofile_once("mods/component-explorer/spawn_stuff.lua") + +-- Not used here right now, but depends on grabbing a function that's only +-- supposed to be accessible during mod init. +---@module 'component-explorer.utils.file_util' +dofile_once("mods/component-explorer/utils/file_util.lua") + local last_frame_run = -1 local is_escape_paused = false @@ -110,9 +120,6 @@ function show_view_menu_items() _, console.open = imgui.MenuItem("Lua Console", sct("CTRL+SHIFT+L"), console.open) _, entity_list.open = imgui.MenuItem("Entity List", sct("CTRL+SHIFT+K"), entity_list.open) _, herd_relation.open = imgui.MenuItem("Herd Relation", "", herd_relation.open) - _, wiki_wands.open = imgui.MenuItem("Wiki Wands", "", wiki_wands.open) - _, file_viewer.open = imgui.MenuItem("File Viewer", sct("CTRL+SHIFT+F"), file_viewer.open) - _, translations.open = imgui.MenuItem("Translations", "", translations.open) local clicked clicked, entity_picker.open = imgui.MenuItem("Entity Picker...", sct("CTRL+SHIFT+E"), entity_picker.open) @@ -125,6 +132,12 @@ function show_view_menu_items() })) end + _, spawn_stuff.open = imgui.MenuItem("Spawn Stuff", "", spawn_stuff.open) + + _, wiki_wands.open = imgui.MenuItem("Wiki Wands", "", wiki_wands.open) + _, file_viewer.open = imgui.MenuItem("File Viewer", sct("CTRL+SHIFT+F"), file_viewer.open) + _, translations.open = imgui.MenuItem("Translations", "", translations.open) + _, cursor.config_open = imgui.MenuItem("Cursor Config", "", cursor.config_open) _, globals.open = imgui.MenuItem("Globals", "", globals.open) @@ -289,6 +302,10 @@ function update_ui(paused, current_frame_run) cursor.config_show() end + if spawn_stuff.open then + spawn_stuff.show() + end + if run_flags.open then run_flags.show() end diff --git a/component-explorer/spawn_data/README_MOD_DEVS.txt b/component-explorer/spawn_data/README_MOD_DEVS.txt new file mode 100644 index 0000000..baffaaf --- /dev/null +++ b/component-explorer/spawn_data/README_MOD_DEVS.txt @@ -0,0 +1,37 @@ +Hey mod developer! + +Your custom perks, spells, and materials should show up automatically. In the +case of materials, the origin is only deduced correctly when +`ModMaterialFilesGet()` is available. (Only on the beta at the time of writing +this). + +Creatures and items use a hardcoded list. See the items.lua and +creatures.lua file for the kind of data it contains. You can append to +this list in your mod if you want your things to show up in Component Explorer. + +This is what that would look like: + +```lua +-- File: mods//init.lua +ModLuaFileAppend( + "mods/component-explorer/spawn_data/creatures.lua", + "mods//files/ce_creatures.lua" +) +``` + +```lua +-- File: mods//files/ce_creatures.lua +local creatures = dofile_once("mods/component-explorer/spawn_data/creatures.lua") + +table.insert(creatures, + { + file="mods//files/animals/omega_hamis.xml", + herd="spider", + name="$animal_yourmod_omegahamis", + origin="", + tags="mortal,teleportable_NOT,friend,hittable_NOT" + }) +``` + +After adding that code into your mod, the creature should show up inside +Component Explorer. diff --git a/component-explorer/spawn_data/actions.lua b/component-explorer/spawn_data/actions.lua new file mode 100644 index 0000000..76b964a --- /dev/null +++ b/component-explorer/spawn_data/actions.lua @@ -0,0 +1,57 @@ +---@module 'component-explorer.utils.file_util' +local file_util = dofile_once("mods/component-explorer/utils/file_util.lua") + +dofile_once("data/scripts/gun/gun_enums.lua") + +local function register_origins(origin) + for _, action in ipairs(actions) do + if action.origin == nil then + action.origin = origin + end + end +end + +local original_do_mod_appends = do_mod_appends +do_mod_appends = function(appends_for) + if appends_for == "data/scripts/gun/gun_actions.lua" then + register_origins("Vanilla") + else + local mod_id = string.match(appends_for, "mods/([^/]*)") + register_origins(mod_id or "Unknown") + end + + original_do_mod_appends(appends_for) +end +dofile("data/scripts/gun/gun_actions.lua") +do_mod_appends = original_do_mod_appends + +local actions = actions + +for _, action in ipairs(actions) do + action.display_name = GameTextGetTranslatedOrNot(action.name) + action.display_description = GameTextGetTranslatedOrNot(action.description) +end + +local action_types = {} + +local gun_enums_source = file_util.ModTextFileGetContent("data/scripts/gun/gun_enums.lua") +for k, v in string.gmatch(gun_enums_source, "ACTION_TYPE_([%w_]+)%s*=%s*(%d+)") do + action_types[tonumber(v)] = k +end + +local unique_action_types = {} +for i=0,#action_types do + table.insert(unique_action_types, action_types[i]) +end + +---@param act integer +---@return string +local function action_type_to_name(act) + return action_types[act] +end + +return { + actions=actions, + unique_action_types=unique_action_types, + action_type_to_name=action_type_to_name, +} diff --git a/component-explorer/spawn_data/creatures.lua b/component-explorer/spawn_data/creatures.lua new file mode 100644 index 0000000..6961b0b --- /dev/null +++ b/component-explorer/spawn_data/creatures.lua @@ -0,0 +1,2193 @@ +return { + { + file="data/entities/animals/acidshooter.xml", + herd="slimes", + name="$animal_acidshooter", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying" + }, + { + file="data/entities/animals/acidshooter_weak.xml", + herd="slimes", + name="$animal_acidshooter", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying" + }, + { + file="data/entities/animals/alchemist.xml", + herd="orcs", + name="$animal_alchemist", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target" + }, + { + file="data/entities/animals/ant.xml", + herd="ant", + name="$animal_ant", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target" + }, + { + file="data/entities/animals/apparition/playerghost.xml", + herd="apparition", + name="$animal_playerghost", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying,glue_NOT" + }, + { + file="data/entities/animals/assassin.xml", + herd="robot", + name="$animal_assassin", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,robot" + }, + { + file="data/entities/animals/barfer.xml", + herd="mage", + name="$animal_barfer", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target" + }, + { + file="data/entities/animals/basebot_hidden.xml", + herd="robot", + name="$animal_hidden", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,robot" + }, + { + file="data/entities/animals/basebot_neutralizer.xml", + herd="robot", + name="$animal_neutralizer", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,robot" + }, + { + file="data/entities/animals/basebot_sentry.xml", + herd="robot", + name="$animal_sentry", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,robot" + }, + { + file="data/entities/animals/basebot_soldier.xml", + herd="robot", + name="$animal_soldier", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,robot" + }, + { + file="data/entities/animals/bat.xml", + herd="bat", + name="$animal_bat", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying" + }, + { + file="data/entities/animals/berserkspirit.xml", + herd="ghost", + name="$animal_berserkspirit", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying,glue_NOT" + }, + { + file="data/entities/animals/bigbat.xml", + herd="bat", + name="$animal_bigbat", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying" + }, + { + file="data/entities/animals/bigfirebug.xml", + herd="fly", + name="$animal_bigfirebug", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying" + }, + { + file="data/entities/animals/bigzombie.xml", + herd="zombie", + name="$animal_bigzombie", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,zombie" + }, + { + file="data/entities/animals/bigzombiehead.xml", + herd="zombie", + name="$animal_bigzombie", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,zombie,flying" + }, + { + file="data/entities/animals/bigzombietorso.xml", + herd="zombie", + name="$animal_bigzombie", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,zombie" + }, + { + file="data/entities/animals/blob.xml", + herd="slimes", + name="$animal_blob", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target" + }, + { + file="data/entities/animals/bloodcrystal_physics.xml", + herd="ghost", + name="$animal_bloodcrystal_physics", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying,glue_NOT" + }, + { + file="data/entities/animals/bloom.xml", + herd="flower", + name="$animal_bloom", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target" + }, + { + file="data/entities/animals/boss_alchemist/boss_alchemist.xml", + herd="mage", + name="$animal_boss_alchemist", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,glue_NOT,touchmagic_immunity,polymorphable_NOT,boss,miniboss,music_energy_100,necrobot_NOT,curse_NOT" + }, + { + file="data/entities/animals/boss_book/book_physics.xml", + herd="robot", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,glue_NOT,robot" + }, + { + file="data/entities/animals/boss_centipede/boss_centipede.xml", + herd="slimes", + name="$animal_boss_centipede", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,hittable,homing_target,glue_NOT,polymorphable_NOT,boss,necrobot_NOT,sampo_or_boss,boss_centipede" + }, + { + file="data/entities/animals/boss_centipede/boss_centipede_minion.xml", + herd="slimes", + name="$animal_boss_centipede_minion", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying,glue_NOT,boss_centipede_minion" + }, + { + file="data/entities/animals/boss_dragon.xml", + herd="boss_dragon", + name="$animal_boss_dragon", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,hittable,homing_target,glue_NOT,polymorphable_NOT,necrobot_NOT,boss_dragon" + }, + { + file="data/entities/animals/boss_fish/fish_giga.xml", + herd="eel", + name="$animal_fish_giga", + origin="Vanilla", + tags="mortal,teleportable_NOT,hittable,glue_NOT,touchmagic_immunity,polymorphable_NOT,necrobot_NOT,curse_NOT,hiteffect_enabled" + }, + { + file="data/entities/animals/boss_gate/gate_monster_a.xml", + herd="ghost", + name="$animal_gate_monster_a", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying,glue_NOT,necrobot_NOT,gate_monster" + }, + { + file="data/entities/animals/boss_gate/gate_monster_b.xml", + herd="ghost", + name="$animal_gate_monster_b", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying,glue_NOT,necrobot_NOT,gate_monster" + }, + { + file="data/entities/animals/boss_gate/gate_monster_c.xml", + herd="ghost", + name="$animal_gate_monster_c", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying,glue_NOT,necrobot_NOT,gate_monster" + }, + { + file="data/entities/animals/boss_gate/gate_monster_d.xml", + herd="ghost", + name="$animal_gate_monster_d", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying,glue_NOT,necrobot_NOT,gate_monster" + }, + { + file="data/entities/animals/boss_ghost/boss_ghost.xml", + herd="ghost_boss", + name="$animal_boss_ghost", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,hittable,glue_NOT,touchmagic_immunity,polymorphable_NOT,boss,miniboss,music_energy_100,necrobot_NOT,curse_NOT" + }, + { + file="data/entities/animals/boss_meat/boss_meat.xml", + herd="slimes", + name="$animal_boss_meat", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,glue_NOT,polymorphable_NOT,boss,miniboss,music_energy_100,necrobot_NOT" + }, + { + file="data/entities/animals/boss_pit/boss_pit.xml", + herd="boss_limbs", + name="$animal_boss_pit", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,glue_NOT,touchmagic_immunity,polymorphable_NOT,boss,miniboss,music_energy_100,necrobot_NOT,curse_NOT" + }, + { + file="data/entities/animals/boss_robot/boss_robot.xml", + herd="robot", + name="$animal_boss_robot", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,glue_NOT,polymorphable_NOT,boss,miniboss,music_energy_100,necrobot_NOT" + }, + { + file="data/entities/animals/boss_spirit/islandspirit.xml", + herd="ghost", + name="$animal_islandspirit", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,glue_NOT,touchmagic_immunity,polymorphable_NOT,boss,miniboss,music_energy_100,necrobot_NOT,curse_NOT,islandspirit" + }, + { + file="data/entities/animals/boss_wizard/boss_wizard.xml", + herd="mage", + name="$animal_boss_wizard", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,glue_NOT,touchmagic_immunity,polymorphable_NOT,boss,miniboss,music_energy_100,necrobot_NOT,boss_wizard" + }, + { + file="data/entities/animals/chest_leggy.xml", + herd="ghost", + name="$animal_lukki", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,hittable,homing_target,glue_NOT" + }, + { + file="data/entities/animals/chest_mimic.xml", + herd="ghost", + name="$animal_chest_mimic", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target" + }, + { + file="data/entities/animals/confusespirit.xml", + herd="ghost", + name="$animal_confusespirit", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying,glue_NOT" + }, + { + file="data/entities/animals/coward.xml", + herd="healer", + name="$animal_coward", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying" + }, + { + file="data/entities/animals/crypt/acidshooter.xml", + herd="slimes", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying" + }, + { + file="data/entities/animals/crypt/barfer.xml", + herd="mage", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target" + }, + { + file="data/entities/animals/crypt/crystal_physics.xml", + herd="ghost", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying,glue_NOT" + }, + { + file="data/entities/animals/crypt/enlightened_alchemist.xml", + herd="mage", + name="$animal_enlightened_alchemist", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target" + }, + { + file="data/entities/animals/crypt/failed_alchemist.xml", + herd="mage", + name="$animal_failed_alchemist", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target" + }, + { + file="data/entities/animals/crypt/maggot.xml", + herd="slimes", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target" + }, + { + file="data/entities/animals/crypt/necromancer.xml", + herd="mage", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying,polymorphable_NOT" + }, + { + file="data/entities/animals/crypt/phantom_a.xml", + herd="ghost", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying,glue_NOT" + }, + { + file="data/entities/animals/crypt/phantom_b.xml", + herd="ghost", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying,glue_NOT" + }, + { + file="data/entities/animals/crypt/skullfly.xml", + herd="ghost", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying" + }, + { + file="data/entities/animals/crypt/skullrat.xml", + herd="ghost", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying" + }, + { + file="data/entities/animals/crypt/tentacler.xml", + herd="slimes", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying" + }, + { + file="data/entities/animals/crypt/tentacler_small.xml", + herd="slimes", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying" + }, + { + file="data/entities/animals/crypt/thundermage.xml", + herd="mage", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,thundermage" + }, + { + file="data/entities/animals/crypt/wizard_dark.xml", + herd="mage", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target" + }, + { + file="data/entities/animals/crypt/wizard_neutral.xml", + herd="mage", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,polymorphable_NOT" + }, + { + file="data/entities/animals/crypt/wizard_poly.xml", + herd="mage", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,polymorphable_NOT" + }, + { + file="data/entities/animals/crypt/wizard_returner.xml", + herd="mage", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target" + }, + { + file="data/entities/animals/crypt/wizard_tele.xml", + herd="mage", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target" + }, + { + file="data/entities/animals/crypt/worm.xml", + herd="worm", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,hittable,homing_target,glue_NOT,worm" + }, + { + file="data/entities/animals/crypt/worm_skull.xml", + herd="ghost", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,hittable,homing_target,glue_NOT,worm,music_energy_000" + }, + { + file="data/entities/animals/crystal_physics.xml", + herd="ghost", + name="$animal_crystal_physics", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying,glue_NOT" + }, + { + file="data/entities/animals/darkghost.xml", + herd="ghost", + name="$animal_darkghost", + origin="Vanilla", + tags="mortal,enemy,hittable,glue_NOT" + }, + { + file="data/entities/animals/deer.xml", + herd="helpless", + name="$animal_deer", + origin="Vanilla", + tags="mortal,teleportable_NOT,hittable,homing_target,prey,helpless_animal" + }, + { + file="data/entities/animals/drone.xml", + herd="robot", + name="$animal_drone_physics", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,robot" + }, + { + file="data/entities/animals/drone_lasership.xml", + herd="robot", + name="$animal_drone_lasership", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,robot,drone_lasership" + }, + { + file="data/entities/animals/drone_physics.xml", + herd="robot", + name="$animal_drone_physics", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,glue_NOT,robot" + }, + { + file="data/entities/animals/drone_shield.xml", + herd="robot", + name="$animal_drone_shield", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,robot" + }, + { + file="data/entities/animals/drunk/miner.xml", + herd="orcs", + name="$animal_miner", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target" + }, + { + file="data/entities/animals/drunk/miner_chef.xml", + herd="orcs", + name="$animal_cook", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target" + }, + { + file="data/entities/animals/drunk/miner_fire.xml", + herd="orcs", + name="$animal_miner_fire", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target" + }, + { + file="data/entities/animals/drunk/miner_weak.xml", + herd="orcs", + name="$animal_miner", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target" + }, + { + file="data/entities/animals/drunk/scavenger_clusterbomb.xml", + herd="orcs", + name="$animal_scavenger_clusterbomb", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying" + }, + { + file="data/entities/animals/drunk/scavenger_glue.xml", + herd="orcs", + name="$animal_scavenger_glue", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying" + }, + { + file="data/entities/animals/drunk/scavenger_grenade.xml", + herd="orcs", + name="$animal_scavenger_grenade", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying" + }, + { + file="data/entities/animals/drunk/scavenger_heal.xml", + herd="healer", + name="$animal_scavenger_heal", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying" + }, + { + file="data/entities/animals/drunk/scavenger_invis.xml", + herd="healer", + name="$animal_scavenger_invis", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying" + }, + { + file="data/entities/animals/drunk/scavenger_leader.xml", + herd="orcs", + name="$animal_scavenger_leader", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying" + }, + { + file="data/entities/animals/drunk/scavenger_mine.xml", + herd="orcs", + name="$animal_scavenger_mine", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying" + }, + { + file="data/entities/animals/drunk/scavenger_poison.xml", + herd="orcs", + name="$animal_scavenger_poison", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying" + }, + { + file="data/entities/animals/drunk/scavenger_shield.xml", + herd="healer", + name="$animal_scavenger_shield", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying" + }, + { + file="data/entities/animals/drunk/scavenger_smg.xml", + herd="orcs", + name="$animal_scavenger_smg", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying" + }, + { + file="data/entities/animals/drunk/shotgunner.xml", + herd="orcs", + name="$animal_shotgunner", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target" + }, + { + file="data/entities/animals/drunk/shotgunner_weak.xml", + herd="orcs", + name="$animal_shotgunner", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target" + }, + { + file="data/entities/animals/drunk/sniper.xml", + herd="orcs", + name="$animal_sniper", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target" + }, + { + file="data/entities/animals/duck.xml", + herd="helpless", + name="$animal_duck", + origin="Vanilla", + tags="mortal,teleportable_NOT,hittable,homing_target,prey,helpless_animal" + }, + { + file="data/entities/animals/easter/sniper.xml", + herd="orcs", + name="$animal_sniper", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target" + }, + { + file="data/entities/animals/eel.xml", + herd="eel", + name="$animal_eel", + origin="Vanilla", + tags="mortal,enemy,hittable,homing_target,destruction_target,glue_NOT" + }, + { + file="data/entities/animals/elk.xml", + herd="helpless", + name="$animal_elk", + origin="Vanilla", + tags="mortal,teleportable_NOT,hittable,homing_target,prey,helpless_animal" + }, + { + file="data/entities/animals/enlightened_alchemist.xml", + herd="mage", + name="$animal_enlightened_alchemist", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target" + }, + { + file="data/entities/animals/ethereal_being.xml", + herd="ghost", + name="$animal_ethereal_being", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,hittable,glue_NOT,polymorphable_NOT,boss_ghost_helper" + }, + { + file="data/entities/animals/failed_alchemist.xml", + herd="mage", + name="$animal_failed_alchemist", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target" + }, + { + file="data/entities/animals/failed_alchemist_b.xml", + herd="mage", + name="$animal_failed_alchemist_b", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target" + }, + { + file="data/entities/animals/firebug.xml", + herd="fly", + name="$animal_firebug", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying" + }, + { + file="data/entities/animals/firemage.xml", + herd="mage", + name="$animal_firemage", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,firemage" + }, + { + file="data/entities/animals/firemage_weak.xml", + herd="mage", + name="$animal_firemage_weak", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,firemage" + }, + { + file="data/entities/animals/fireskull.xml", + herd="fire", + name="$animal_fireskull", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying" + }, + { + file="data/entities/animals/fireskull_weak.xml", + herd="fire", + name="$animal_fireskull", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying" + }, + { + file="data/entities/animals/fish.xml", + herd="helpless", + name="$animal_fish", + origin="Vanilla", + tags="mortal,hittable,prey,helpless_animal" + }, + { + file="data/entities/animals/fish_large.xml", + herd="helpless", + name="$animal_fish_large", + origin="Vanilla", + tags="mortal,hittable,prey,helpless_animal" + }, + { + file="data/entities/animals/flamer.xml", + herd="robot", + name="$animal_flamer", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,robot" + }, + { + file="data/entities/animals/fly.xml", + herd="fly", + name="$animal_fly", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying" + }, + { + file="data/entities/animals/friend.xml", + herd="orcs", + name="$animal_friend", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying,big_friend" + }, + { + file="data/entities/animals/frog.xml", + herd="slimes", + name="$animal_frog", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target" + }, + { + file="data/entities/animals/frog_big.xml", + herd="slimes", + name="$animal_frog_big", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target" + }, + { + file="data/entities/animals/fungus.xml", + herd="fungus", + name="$animal_fungus", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target" + }, + { + file="data/entities/animals/fungus_big.xml", + herd="fungus", + name="$animal_fungus_big", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target" + }, + { + file="data/entities/animals/fungus_giga.xml", + herd="fungus", + name="$animal_fungus_giga", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target" + }, + { + file="data/entities/animals/fungus_tiny.xml", + herd="fungus", + name="$animal_fungus_tiny", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,fungus_tiny_bad" + }, + { + file="data/entities/animals/gazer.xml", + herd="slimes", + name="$animal_gazer", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying" + }, + { + file="data/entities/animals/ghost.xml", + herd="ghost", + name="$animal_ghost", + origin="Vanilla", + tags="mortal,enemy,hittable,glue_NOT,music_energy_000_near" + }, + { + file="data/entities/animals/ghoul.xml", + herd="ghost", + name="$animal_ghoul", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target" + }, + { + file="data/entities/animals/giant.xml", + herd="giant", + name="$animal_giant", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target" + }, + { + file="data/entities/animals/giantshooter.xml", + herd="slimes", + name="$animal_giantshooter", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying" + }, + { + file="data/entities/animals/giantshooter_weak.xml", + herd="slimes", + name="$animal_giantshooter_weak", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying" + }, + { + file="data/entities/animals/goblin_bomb.xml", + herd="orcs", + name="$animal_goblin_bomb", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target" + }, + { + file="data/entities/animals/healerdrone_physics.xml", + herd="healer", + name="$animal_healerdrone_physics", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,glue_NOT,robot,healer" + }, + { + file="data/entities/animals/icemage.xml", + herd="mage", + name="$animal_icemage", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target" + }, + { + file="data/entities/animals/icer.xml", + herd="robot", + name="$animal_icer", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,robot" + }, + { + file="data/entities/animals/iceskull.xml", + herd="ice", + name="$animal_iceskull", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying" + }, + { + file="data/entities/animals/illusions/acidshooter.xml", + herd="ghost", + name="$animal_acidshooter", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying,glue_NOT" + }, + { + file="data/entities/animals/illusions/dark_alchemist.xml", + herd="ghost", + name="$animal_dark_alchemist", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target" + }, + { + file="data/entities/animals/illusions/enlightened_alchemist.xml", + herd="ghost", + name="$animal_enlightened_alchemist", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,glue_NOT" + }, + { + file="data/entities/animals/illusions/scavenger_grenade.xml", + herd="ghost", + name="$animal_scavenger_grenade", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying,glue_NOT" + }, + { + file="data/entities/animals/illusions/scavenger_mine.xml", + herd="ghost", + name="$animal_scavenger_mine", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying,glue_NOT" + }, + { + file="data/entities/animals/illusions/shaman.xml", + herd="ghost", + name="$animal_shaman", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,glue_NOT,shaman" + }, + { + file="data/entities/animals/illusions/shaman_wind.xml", + herd="ghost", + name="$animal_shaman_wind", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target" + }, + { + file="data/entities/animals/illusions/tank.xml", + herd="ghost", + name="$animal_tank", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,glue_NOT,robot" + }, + { + file="data/entities/animals/illusions/tentacler.xml", + herd="ghost", + name="$animal_tentacler", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying,glue_NOT" + }, + { + file="data/entities/animals/illusions/thundermage.xml", + herd="ghost", + name="$animal_thundermage", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,glue_NOT" + }, + { + file="data/entities/animals/illusions/wizard_swapper.xml", + herd="ghost", + name="$animal_wizard_swapper", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,glue_NOT" + }, + { + file="data/entities/animals/illusions/worm_big.xml", + herd="ghost", + name="$animal_worm_big", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,hittable,homing_target,glue_NOT,worm" + }, + { + file="data/entities/animals/lasershooter.xml", + herd="slimes", + name="$animal_lasershooter", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying" + }, + { + file="data/entities/animals/longleg.xml", + herd="spider", + name="$animal_longleg", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target" + }, + { + file="data/entities/animals/lukki/lukki.xml", + herd="slimes", + name="$animal_lukki", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,hittable,homing_target,glue_NOT,music_energy_100,lukki" + }, + { + file="data/entities/animals/lukki/lukki_creepy.xml", + herd="spider", + name="$animal_lukki_creepy", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,hittable,homing_target,glue_NOT,music_energy_100,lukki" + }, + { + file="data/entities/animals/lukki/lukki_creepy_long.xml", + herd="spider", + name="$animal_lukki_creepy_long", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,hittable,homing_target,glue_NOT,music_energy_100,lukki" + }, + { + file="data/entities/animals/lukki/lukki_dark.xml", + herd="spider", + name="$animal_lukki_dark", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,hittable,homing_target,glue_NOT,music_energy_100,lukki" + }, + { + file="data/entities/animals/lukki/lukki_longleg.xml", + herd="spider", + name="$animal_lukki_longleg", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,hittable,homing_target,glue_NOT,music_energy_100,lukki" + }, + { + file="data/entities/animals/lukki/lukki_tiny.xml", + herd="slimes", + name="$animal_lukki_tiny", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,hittable,homing_target,glue_NOT,music_energy_100,lukki" + }, + { + file="data/entities/animals/lurker.xml", + herd="slimes", + name="$animal_lurker", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying" + }, + { + file="data/entities/animals/maggot.xml", + herd="slimes", + name="$animal_maggot", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target" + }, + { + file="data/entities/animals/maggot_tiny/maggot_tiny.xml", + herd="boss_dragon", + name="$animal_maggot_tiny", + origin="Vanilla", + tags="teleportable_NOT,enemy,hittable,homing_target,glue_NOT,touchmagic_immunity,polymorphable_NOT,necrobot_NOT" + }, + { + file="data/entities/animals/meatmaggot.xml", + herd="worm", + name="$animal_meatmaggot", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,hittable,homing_target,glue_NOT,worm" + }, + { + file="data/entities/animals/mimic_physics.xml", + herd="ghost", + name="$animal_mimic_physics", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying,glue_NOT" + }, + { + file="data/entities/animals/miner.xml", + herd="orcs", + name="$animal_miner", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target" + }, + { + file="data/entities/animals/miner_chef.xml", + herd="orcs", + name="$animal_cook", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target" + }, + { + file="data/entities/animals/miner_fire.xml", + herd="orcs", + name="$animal_miner_fire", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target" + }, + { + file="data/entities/animals/miner_hell.xml", + herd="orcs", + name="$animal_miner_hell", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target" + }, + { + file="data/entities/animals/miner_santa.xml", + herd="orcs", + name="$animal_miner_santa", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target" + }, + { + file="data/entities/animals/miner_weak.xml", + herd="orcs", + name="$animal_miner", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target" + }, + { + file="data/entities/animals/miniblob.xml", + herd="slimes", + name="$animal_miniblob", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target" + }, + { + file="data/entities/animals/missilecrab.xml", + herd="robot", + name="$animal_missilecrab", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,robot" + }, + { + file="data/entities/animals/monk.xml", + herd="robot", + name="$animal_monk", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target" + }, + { + file="data/entities/animals/necrobot.xml", + herd="robot", + name="$animal_necrobot", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,robot,necrobot_NOT" + }, + { + file="data/entities/animals/necrobot_super.xml", + herd="robot", + name="$animal_necrobot_super", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,robot,necrobot_NOT" + }, + { + file="data/entities/animals/necromancer.xml", + herd="mage", + name="$animal_necromancer", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying,polymorphable_NOT" + }, + { + file="data/entities/animals/necromancer_shop.xml", + herd="mage", + name="$animal_necromancer_shop", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying,necromancer_shop,music_energy_100_near" + }, + { + file="data/entities/animals/necromancer_super.xml", + herd="mage", + name="$animal_necromancer_super", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying,polymorphable_NOT,necromancer_shop,music_energy_100_near,necromancer_super" + }, + { + file="data/entities/animals/parallel/alchemist/parallel_alchemist.xml", + herd="mage", + name="$animal_parallel_alchemist", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,touchmagic_immunity,polymorphable_NOT" + }, + { + file="data/entities/animals/parallel/tentacles/parallel_tentacles.xml", + herd="boss_limbs", + name="$animal_parallel_tentacles", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,glue_NOT,touchmagic_immunity,polymorphable_NOT" + }, + { + file="data/entities/animals/pebble_physics.xml", + herd="giant", + name="$animal_pebble", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,glue_NOT" + }, + { + file="data/entities/animals/phantom_a.xml", + herd="ghost", + name="$animal_phantom_a", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying,glue_NOT" + }, + { + file="data/entities/animals/phantom_b.xml", + herd="ghost", + name="$animal_phantom_b", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying,glue_NOT" + }, + { + file="data/entities/animals/playerghost.xml", + herd="apparition", + name="$animal_playerghost", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying,glue_NOT" + }, + { + file="data/entities/animals/rainforest/bloom.xml", + herd="flower", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target" + }, + { + file="data/entities/animals/rainforest/coward.xml", + herd="healer", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying" + }, + { + file="data/entities/animals/rainforest/flamer.xml", + herd="robot", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,robot" + }, + { + file="data/entities/animals/rainforest/fly.xml", + herd="fly", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying" + }, + { + file="data/entities/animals/rainforest/fungus.xml", + herd="fungus", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target" + }, + { + file="data/entities/animals/rainforest/scavenger_clusterbomb.xml", + herd="orcs", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying" + }, + { + file="data/entities/animals/rainforest/scavenger_grenade.xml", + herd="orcs", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying" + }, + { + file="data/entities/animals/rainforest/scavenger_heal.xml", + herd="healer", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying" + }, + { + file="data/entities/animals/rainforest/scavenger_leader.xml", + herd="orcs", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying" + }, + { + file="data/entities/animals/rainforest/scavenger_mine.xml", + herd="orcs", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying" + }, + { + file="data/entities/animals/rainforest/scavenger_poison.xml", + herd="orcs", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying" + }, + { + file="data/entities/animals/rainforest/scavenger_smg.xml", + herd="orcs", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying" + }, + { + file="data/entities/animals/rainforest/shooterflower.xml", + herd="flower", + origin="Vanilla", + tags="mortal,enemy,hittable,homing_target" + }, + { + file="data/entities/animals/rainforest/sniper.xml", + herd="orcs", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target" + }, + { + file="data/entities/animals/rat.xml", + herd="rat", + name="$animal_rat", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,rat" + }, + { + file="data/entities/animals/robobase/drone_lasership.xml", + herd="robot", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,robot,drone_lasership" + }, + { + file="data/entities/animals/robobase/drone_shield.xml", + herd="robot", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,robot" + }, + { + file="data/entities/animals/robobase/healerdrone_physics.xml", + herd="healer", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,glue_NOT,robot,healer" + }, + { + file="data/entities/animals/robobase/monk.xml", + herd="robot", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target" + }, + { + file="data/entities/animals/robobase/tank_super.xml", + herd="orcs", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,robot" + }, + { + file="data/entities/animals/robobase/turret_left.xml", + herd="orcs", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,robot" + }, + { + file="data/entities/animals/robobase/turret_right.xml", + herd="orcs", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,robot" + }, + { + file="data/entities/animals/roboguard.xml", + herd="robot", + name="$animal_roboguard", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,robot" + }, + { + file="data/entities/animals/roboguard_big.xml", + herd="robot", + name="$animal_piranha", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,robot" + }, + { + file="data/entities/animals/scavenger_clusterbomb.xml", + herd="orcs", + name="$animal_scavenger_clusterbomb", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying" + }, + { + file="data/entities/animals/scavenger_glue.xml", + herd="orcs", + name="$animal_scavenger_glue", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying" + }, + { + file="data/entities/animals/scavenger_grenade.xml", + herd="orcs", + name="$animal_scavenger_grenade", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying" + }, + { + file="data/entities/animals/scavenger_heal.xml", + herd="healer", + name="$animal_scavenger_heal", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying" + }, + { + file="data/entities/animals/scavenger_invis.xml", + herd="healer", + name="$animal_scavenger_invis", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying" + }, + { + file="data/entities/animals/scavenger_leader.xml", + herd="orcs", + name="$animal_scavenger_leader", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying" + }, + { + file="data/entities/animals/scavenger_mine.xml", + herd="orcs", + name="$animal_scavenger_mine", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying" + }, + { + file="data/entities/animals/scavenger_poison.xml", + herd="orcs", + name="$animal_scavenger_poison", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying" + }, + { + file="data/entities/animals/scavenger_shield.xml", + herd="healer", + name="$animal_scavenger_shield", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying" + }, + { + file="data/entities/animals/scavenger_smg.xml", + herd="orcs", + name="$animal_scavenger_smg", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying" + }, + { + file="data/entities/animals/scorpion.xml", + herd="helpless", + name="$animal_scorpion", + origin="Vanilla", + tags="mortal,teleportable_NOT,hittable,homing_target,prey,helpless_animal" + }, + { + file="data/entities/animals/shaman.xml", + herd="mage", + name="$animal_shaman", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,shaman" + }, + { + file="data/entities/animals/sheep.xml", + herd="helpless", + name="$animal_sheep", + origin="Vanilla", + tags="mortal,teleportable_NOT,hittable,homing_target,prey,helpless_animal,sheep" + }, + { + file="data/entities/animals/sheep_bat.xml", + herd="helpless", + name="$animal_sheep_bat", + origin="Vanilla", + tags="mortal,teleportable_NOT,hittable,homing_target,prey,helpless_animal,sheep" + }, + { + file="data/entities/animals/sheep_fly.xml", + herd="helpless", + name="$animal_sheep_fly", + origin="Vanilla", + tags="mortal,teleportable_NOT,hittable,homing_target,prey,helpless_animal,sheep" + }, + { + file="data/entities/animals/shooterflower.xml", + herd="flower", + name="$animal_shooterflower", + origin="Vanilla", + tags="mortal,enemy,hittable,homing_target" + }, + { + file="data/entities/animals/shotgunner.xml", + herd="orcs", + name="$animal_shotgunner", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target" + }, + { + file="data/entities/animals/shotgunner_hell.xml", + herd="orcs", + name="$animal_shotgunner_hell", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target" + }, + { + file="data/entities/animals/shotgunner_weak.xml", + herd="orcs", + name="$animal_shotgunner", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target" + }, + { + file="data/entities/animals/skullfly.xml", + herd="ghost", + name="$animal_skullfly", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying" + }, + { + file="data/entities/animals/skullrat.xml", + herd="ghost", + name="$animal_skullrat", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying" + }, + { + file="data/entities/animals/skycrystal_physics.xml", + herd="ghost", + name="$animal_skycrystal_physics", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying,glue_NOT" + }, + { + file="data/entities/animals/skygazer.xml", + herd="slimes", + name="$animal_skygazer", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying,polymorphable_NOT" + }, + { + file="data/entities/animals/slimeshooter.xml", + herd="slimes", + name="$animal_slimeshooter", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying" + }, + { + file="data/entities/animals/slimeshooter_nontoxic.xml", + herd="slimes", + name="$animal_slimeshooter", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying" + }, + { + file="data/entities/animals/slimeshooter_weak.xml", + herd="slimes", + name="$animal_slimeshooter", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying" + }, + { + file="data/entities/animals/slimespirit.xml", + herd="ghost", + name="$animal_slimespirit", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying,glue_NOT" + }, + { + file="data/entities/animals/sniper.xml", + herd="orcs", + name="$animal_sniper", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target" + }, + { + file="data/entities/animals/sniper_hell.xml", + herd="orcs", + name="$animal_sniper_hell", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target" + }, + { + file="data/entities/animals/spearbot.xml", + herd="robot", + name="$animal_spearbot", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,robot" + }, + { + file="data/entities/animals/special/minipit.xml", + herd="slimes", + name="$animal_minipit", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying,glue_NOT" + }, + { + file="data/entities/animals/spitmonster.xml", + herd="slimes", + name="$animal_spitmonster", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target" + }, + { + file="data/entities/animals/statue.xml", + herd="giant", + name="$animal_statue", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying" + }, + { + file="data/entities/animals/statue_physics.xml", + herd="ghost", + name="$animal_statue_physics", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying,glue_NOT" + }, + { + file="data/entities/animals/tank.xml", + herd="orcs", + name="$animal_tank", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,robot" + }, + { + file="data/entities/animals/tank_rocket.xml", + herd="orcs", + name="$animal_tank_rocket", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,robot" + }, + { + file="data/entities/animals/tank_super.xml", + herd="orcs", + name="$animal_tank", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,robot" + }, + { + file="data/entities/animals/tentacler.xml", + herd="slimes", + name="$animal_tentacler", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying" + }, + { + file="data/entities/animals/tentacler_small.xml", + herd="slimes", + name="$animal_tentacler_small", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying" + }, + { + file="data/entities/animals/the_end/bloodcrystal_physics.xml", + herd="ghost", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying,glue_NOT" + }, + { + file="data/entities/animals/the_end/gazer.xml", + herd="slimes", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying" + }, + { + file="data/entities/animals/the_end/skycrystal_physics.xml", + herd="ghost", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying,glue_NOT" + }, + { + file="data/entities/animals/the_end/skygazer.xml", + herd="slimes", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying,polymorphable_NOT" + }, + { + file="data/entities/animals/the_end/spearbot.xml", + herd="robot", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,robot" + }, + { + file="data/entities/animals/the_end/spitmonster.xml", + herd="slimes", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target" + }, + { + file="data/entities/animals/the_end/worm_end.xml", + herd="worm", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,hittable,homing_target,glue_NOT,worm" + }, + { + file="data/entities/animals/the_end/worm_skull.xml", + herd="ghost", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,hittable,homing_target,glue_NOT,worm,music_energy_000" + }, + { + file="data/entities/animals/thundermage.xml", + herd="mage", + name="$animal_thundermage", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,thundermage" + }, + { + file="data/entities/animals/thundermage_big.xml", + herd="mage", + name="$animal_thundermage_big", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,touchmagic_immunity,thundermage" + }, + { + file="data/entities/animals/thunderskull.xml", + herd="ice", + name="$animal_thunderskull", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying" + }, + { + file="data/entities/animals/turret_left.xml", + herd="orcs", + name="$animal_turret", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,robot" + }, + { + file="data/entities/animals/turret_right.xml", + herd="orcs", + name="$animal_turret", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,robot" + }, + { + file="data/entities/animals/ultimate_killer.xml", + herd="orcs", + name="$animal_ultimate_killer", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying,small_friend" + }, + { + file="data/entities/animals/vault/acidshooter.xml", + herd="slimes", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying" + }, + { + file="data/entities/animals/vault/assassin.xml", + herd="robot", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,robot" + }, + { + file="data/entities/animals/vault/bigzombie.xml", + herd="zombie", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,zombie" + }, + { + file="data/entities/animals/vault/blob.xml", + herd="slimes", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target" + }, + { + file="data/entities/animals/vault/coward.xml", + herd="healer", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying" + }, + { + file="data/entities/animals/vault/drone_physics.xml", + herd="robot", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,glue_NOT,robot" + }, + { + file="data/entities/animals/vault/firemage.xml", + herd="mage", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,firemage" + }, + { + file="data/entities/animals/vault/flamer.xml", + herd="robot", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,robot" + }, + { + file="data/entities/animals/vault/healerdrone_physics.xml", + herd="healer", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,glue_NOT,robot,healer" + }, + { + file="data/entities/animals/vault/icer.xml", + herd="robot", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,robot" + }, + { + file="data/entities/animals/vault/lasershooter.xml", + herd="slimes", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying" + }, + { + file="data/entities/animals/vault/maggot.xml", + herd="slimes", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target" + }, + { + file="data/entities/animals/vault/missilecrab.xml", + herd="robot", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,robot" + }, + { + file="data/entities/animals/vault/roboguard.xml", + herd="robot", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,robot" + }, + { + file="data/entities/animals/vault/scavenger_glue.xml", + herd="orcs", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying" + }, + { + file="data/entities/animals/vault/scavenger_grenade.xml", + herd="orcs", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying" + }, + { + file="data/entities/animals/vault/scavenger_heal.xml", + herd="healer", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying" + }, + { + file="data/entities/animals/vault/scavenger_leader.xml", + herd="orcs", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying" + }, + { + file="data/entities/animals/vault/scavenger_mine.xml", + herd="orcs", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying" + }, + { + file="data/entities/animals/vault/scavenger_smg.xml", + herd="orcs", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying" + }, + { + file="data/entities/animals/vault/sniper.xml", + herd="orcs", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target" + }, + { + file="data/entities/animals/vault/tank.xml", + herd="orcs", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,robot" + }, + { + file="data/entities/animals/vault/tank_rocket.xml", + herd="orcs", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,robot" + }, + { + file="data/entities/animals/vault/tank_super.xml", + herd="orcs", + name="$animal_tank", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,robot" + }, + { + file="data/entities/animals/vault/tentacler.xml", + herd="slimes", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying" + }, + { + file="data/entities/animals/vault/tentacler_small.xml", + herd="slimes", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying" + }, + { + file="data/entities/animals/vault/thundermage.xml", + herd="mage", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,thundermage" + }, + { + file="data/entities/animals/vault/thunderskull.xml", + herd="ice", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying" + }, + { + file="data/entities/animals/vault/turret_left.xml", + herd="orcs", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,robot" + }, + { + file="data/entities/animals/vault/turret_right.xml", + herd="orcs", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,robot" + }, + { + file="data/entities/animals/vault/wizard_dark.xml", + herd="mage", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target" + }, + { + file="data/entities/animals/wand_ghost.xml", + herd="ghost", + name="$animal_wand_ghost", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying,glue_NOT,wand_ghost" + }, + { + file="data/entities/animals/wand_ghost_charmed.xml", + herd="player", + name="$animal_wand_ghost", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying,glue_NOT,wand_ghost" + }, + { + file="data/entities/animals/wand_ghost_with_sampo.xml", + herd="player", + name="$animal_wand_ghost", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying,glue_NOT,this_is_sampo,wand_ghost" + }, + { + file="data/entities/animals/weakspirit.xml", + herd="ghost", + name="$animal_weakspirit", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying,glue_NOT" + }, + { + file="data/entities/animals/wizard_dark.xml", + herd="mage", + name="$animal_wizard_dark", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target" + }, + { + file="data/entities/animals/wizard_hearty.xml", + herd="mage", + name="$animal_wizard_hearty", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target" + }, + { + file="data/entities/animals/wizard_homing.xml", + herd="mage", + name="$animal_wizard_homing", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target" + }, + { + file="data/entities/animals/wizard_neutral.xml", + herd="mage", + name="$animal_wizard_neutral", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,polymorphable_NOT" + }, + { + file="data/entities/animals/wizard_poly.xml", + herd="mage", + name="$animal_wizard_poly", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,polymorphable_NOT" + }, + { + file="data/entities/animals/wizard_returner.xml", + herd="mage", + name="$animal_wizard_returner", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target" + }, + { + file="data/entities/animals/wizard_swapper.xml", + herd="mage_swapper", + name="$animal_wizard_swapper", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target" + }, + { + file="data/entities/animals/wizard_tele.xml", + herd="mage", + name="$animal_wizard_tele", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target" + }, + { + file="data/entities/animals/wizard_twitchy.xml", + herd="mage", + name="$animal_wizard_twitchy", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target" + }, + { + file="data/entities/animals/wizard_weaken.xml", + herd="mage", + name="$animal_wizard_weaken", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target" + }, + { + file="data/entities/animals/wolf.xml", + herd="wolf", + name="$animal_wolf", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target" + }, + { + file="data/entities/animals/worm.xml", + herd="worm", + name="$animal_worm", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,hittable,homing_target,glue_NOT,worm" + }, + { + file="data/entities/animals/worm_big.xml", + herd="worm", + name="$animal_worm_big", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,hittable,homing_target,glue_NOT,worm" + }, + { + file="data/entities/animals/worm_end.xml", + herd="worm", + name="$animal_worm_end", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,hittable,homing_target,glue_NOT,worm" + }, + { + file="data/entities/animals/worm_skull.xml", + herd="ghost", + name="$animal_worm_skull", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,hittable,homing_target,glue_NOT,worm,music_energy_000" + }, + { + file="data/entities/animals/worm_tiny.xml", + herd="worm", + name="$animal_worm_tiny", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,hittable,homing_target,glue_NOT,worm" + }, + { + file="data/entities/animals/wraith.xml", + herd="mage", + name="$animal_wraith", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying" + }, + { + file="data/entities/animals/wraith_glowing.xml", + herd="mage", + name="$animal_wraith_glowing", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying" + }, + { + file="data/entities/animals/wraith_storm.xml", + herd="mage", + name="$animal_wraith_storm", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying" + }, + { + file="data/entities/animals/zombie.xml", + herd="zombie", + name="$animal_zombie", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,zombie" + }, + { + file="data/entities/animals/zombie_weak.xml", + herd="zombie", + name="$animal_zombie", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,zombie" + }, + { + file="data/entities/buildings/arrowtrap_left.xml", + herd="trap", + origin="Vanilla", + tags="hittable,glue_NOT" + }, + { + file="data/entities/buildings/arrowtrap_right.xml", + herd="trap", + origin="Vanilla", + tags="hittable,glue_NOT" + }, + { + file="data/entities/buildings/darkghost_crystal.xml", + herd="ghost", + origin="Vanilla", + tags="mortal,hittable" + }, + { + file="data/entities/buildings/firebugnest.xml", + herd="nest", + origin="Vanilla", + tags="mortal,hittable,glue_NOT,nest,predator" + }, + { + file="data/entities/buildings/firetrap_left.xml", + herd="trap", + origin="Vanilla", + tags="hittable,glue_NOT" + }, + { + file="data/entities/buildings/firetrap_right.xml", + herd="trap", + origin="Vanilla", + tags="hittable,glue_NOT" + }, + { + file="data/entities/buildings/flynest.xml", + herd="nest", + origin="Vanilla", + tags="mortal,hittable,glue_NOT,nest,predator" + }, + { + file="data/entities/buildings/ghost_crystal.xml", + herd="ghost", + origin="Vanilla", + tags="mortal,hittable" + }, + { + file="data/entities/buildings/hpcrystal.xml", + herd="ghost", + name="$animal_hpcrystal", + origin="Vanilla", + tags="mortal,hittable" + }, + { + file="data/entities/buildings/snowcrystal.xml", + herd="ghost", + name="$animal_snowcrystal", + origin="Vanilla", + tags="mortal,hittable,glue_NOT" + }, + { + file="data/entities/buildings/spidernest.xml", + herd="nest", + origin="Vanilla", + tags="mortal,hittable,glue_NOT,nest,predator" + }, + { + file="data/entities/buildings/spittrap_left.xml", + herd="trap", + origin="Vanilla", + tags="hittable,glue_NOT" + }, + { + file="data/entities/buildings/spittrap_right.xml", + herd="trap", + origin="Vanilla", + tags="hittable,glue_NOT" + }, + { + file="data/entities/buildings/thundertrap_left.xml", + herd="trap", + origin="Vanilla", + tags="hittable,glue_NOT" + }, + { + file="data/entities/buildings/thundertrap_right.xml", + herd="trap", + origin="Vanilla", + tags="hittable,glue_NOT" + }, + { + file="data/entities/buildings/walleye.xml", + herd="ghost", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,glue_NOT,polymorphable_NOT,curse_NOT" + }, + { + file="data/entities/buildings/wallmouth.xml", + herd="ghost", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,glue_NOT,polymorphable_NOT,curse_NOT" + }, + { + file="data/entities/misc/fungus_projectile.xml", + herd="fungus", + name="$animal_fungus", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target" + }, + { + file="data/entities/misc/greed_curse/greed_ghost.xml", + herd="-1", + name="$animal_greed_ghost", + origin="Vanilla", + tags="teleportable_NOT,enemy,glue_NOT,polymorphable_NOT,greed_curse_ghost" + }, + { + file="data/entities/misc/homunculus.xml", + herd="player", + name="$animal_homunculus", + origin="Vanilla", + tags="mortal,teleportable_NOT,human,hittable,destruction_target,homunculus" + }, + { + file="data/entities/misc/magic/heart_fullhp.xml", + herd="boss_limbs", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,glue_NOT,touchmagic_immunity,polymorphable_NOT" + }, + { + file="data/entities/misc/perks/fungus.xml", + herd="player", + name="$animal_fungus_tiny_perk", + origin="Vanilla", + tags="mortal,teleportable_NOT,human,hittable,destruction_target,perk_fungus_tiny" + }, + { + file="data/entities/misc/perks/lukki_minion.xml", + herd="player", + name="$perk_lukki_minion", + origin="Vanilla", + tags="mortal,hittable,glue_NOT,lukki" + }, + { + file="data/entities/misc/perks/plague_rats_rat.xml", + herd="player", + name="$animal_rat", + origin="Vanilla", + tags="mortal,teleportable_NOT,human,hittable,destruction_target,rat,poopstone_immunity,plague_rat" + }, + { + file="data/entities/misc/player_drone.xml", + herd="player", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,robot" + }, + { + file="data/entities/misc/player_drone_clone.xml", + herd="player", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying,drone" + }, + { + file="data/entities/misc/tentacles.xml", + herd="slimes", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,human,hittable,homing_target,destruction_target,flying" + }, + { + file="data/entities/misc/worm_big_worm_rain.xml", + herd="worm", + name="$animal_worm_big", + origin="Vanilla", + tags="mortal,teleportable_NOT,enemy,hittable,homing_target,glue_NOT,worm" + } +} diff --git a/component-explorer/spawn_data/items.lua b/component-explorer/spawn_data/items.lua new file mode 100644 index 0000000..8bba7a2 --- /dev/null +++ b/component-explorer/spawn_data/items.lua @@ -0,0 +1,1307 @@ +return { + { + file="data/entities/animals/boss_alchemist/key.xml", + item_name="$item_key", + origin="Vanilla", + tags="teleportable_NOT,hittable,item_physics,alchemist_key" + }, + { + file="data/entities/animals/boss_centipede/rewards/gold_reward.xml", + item_name="$reward_gold_statue", + origin="Vanilla", + tags="teleportable_NOT" + }, + { + file="data/entities/animals/boss_centipede/rewards/reward_almostpacifist.xml", + item_name="$reward_almostpacifist", + origin="Vanilla", + tags="teleportable_NOT" + }, + { + file="data/entities/animals/boss_centipede/rewards/reward_clock.xml", + item_name="$reward_clock", + origin="Vanilla", + tags="teleportable_NOT" + }, + { + file="data/entities/animals/boss_centipede/rewards/reward_crown.xml", + item_name="$reward_crown", + origin="Vanilla", + tags="teleportable_NOT" + }, + { + file="data/entities/animals/boss_centipede/rewards/reward_dollar.xml", + item_name="$reward_dollar", + origin="Vanilla", + tags="teleportable_NOT" + }, + { + file="data/entities/animals/boss_centipede/rewards/reward_kicksonly.xml", + item_name="$reward_kicksonly", + origin="Vanilla", + tags="teleportable_NOT" + }, + { + file="data/entities/animals/boss_centipede/rewards/reward_minit.xml", + item_name="$reward_minit", + origin="Vanilla", + tags="teleportable_NOT" + }, + { + file="data/entities/animals/boss_centipede/rewards/reward_nohit.xml", + item_name="$reward_nohit", + origin="Vanilla", + tags="teleportable_NOT" + }, + { + file="data/entities/animals/boss_centipede/rewards/reward_nolla.xml", + item_name="$reward_nolla", + origin="Vanilla", + tags="teleportable_NOT" + }, + { + file="data/entities/animals/boss_centipede/rewards/reward_notinkeringofwands.xml", + item_name="$reward_notinkeringofwands", + origin="Vanilla", + tags="teleportable_NOT" + }, + { + file="data/entities/animals/boss_centipede/rewards/reward_nowands.xml", + item_name="$reward_nowands", + origin="Vanilla", + tags="teleportable_NOT" + }, + { + file="data/entities/animals/boss_centipede/rewards/reward_peace.xml", + item_name="$reward_peace", + origin="Vanilla", + tags="teleportable_NOT" + }, + { + file="data/entities/animals/boss_centipede/rewards/reward_sun.xml", + item_name="$reward_sun", + origin="Vanilla", + tags="teleportable_NOT" + }, + { + file="data/entities/animals/boss_centipede/sampo.xml", + item_name="$item_mcguffin_0", + origin="Vanilla", + tags="teleportable_NOT,sampo_or_boss,this_is_sampo" + }, + { + file="data/entities/base_item.xml", + origin="Vanilla", + tags="teleportable_NOT,item" + }, + { + file="data/entities/base_torch.xml", + origin="Vanilla", + tags="teleportable_NOT,prop,drillable,kickable,torch" + }, + { + file="data/entities/base_wand_physics.xml", + origin="Vanilla", + tags="teleportable_NOT" + }, + { + file="data/entities/buildings/chest_steel.xml", + item_name="$item_chest_treasure", + origin="Vanilla", + tags="teleportable_NOT,item_physics,chest" + }, + { + file="data/entities/buildings/endcrystal.xml", + item_name="Mystical Crystal Ball", + origin="Vanilla", + tags="" + }, + { + file="data/entities/items/books/base_book.xml", + item_name="$booktitle01", + origin="Vanilla", + tags="tablet" + }, + { + file="data/entities/items/books/base_forged.xml", + item_name="$booktitle01", + origin="Vanilla", + tags="tablet,forged_tablet" + }, + { + file="data/entities/items/books/book_00.xml", + item_name="$booktitle00", + origin="Vanilla", + tags="tablet,normal_tablet" + }, + { + file="data/entities/items/books/book_01.xml", + item_name="$booktitle01", + origin="Vanilla", + tags="tablet,normal_tablet" + }, + { + file="data/entities/items/books/book_02.xml", + item_name="$booktitle02", + origin="Vanilla", + tags="tablet,normal_tablet,forgeable" + }, + { + file="data/entities/items/books/book_03.xml", + item_name="$booktitle03", + origin="Vanilla", + tags="tablet,normal_tablet" + }, + { + file="data/entities/items/books/book_04.xml", + item_name="$booktitle04", + origin="Vanilla", + tags="tablet,normal_tablet,forgeable" + }, + { + file="data/entities/items/books/book_05.xml", + item_name="$booktitle05", + origin="Vanilla", + tags="tablet,normal_tablet,forgeable" + }, + { + file="data/entities/items/books/book_06.xml", + item_name="$booktitle06", + origin="Vanilla", + tags="tablet,normal_tablet,forgeable" + }, + { + file="data/entities/items/books/book_07.xml", + item_name="$booktitle07", + origin="Vanilla", + tags="tablet,normal_tablet,forgeable" + }, + { + file="data/entities/items/books/book_08.xml", + item_name="$booktitle08", + origin="Vanilla", + tags="tablet,normal_tablet,forgeable" + }, + { + file="data/entities/items/books/book_09.xml", + item_name="$booktitle09", + origin="Vanilla", + tags="tablet,normal_tablet,forgeable" + }, + { + file="data/entities/items/books/book_10.xml", + item_name="$booktitle10", + origin="Vanilla", + tags="tablet,normal_tablet,forgeable" + }, + { + file="data/entities/items/books/book_all_spells.xml", + item_name="$booktitle_allspells", + origin="Vanilla", + tags="tablet,normal_tablet" + }, + { + file="data/entities/items/books/book_bunker.xml", + item_name="$booktitle_fisher", + origin="Vanilla", + tags="scroll,tablet" + }, + { + file="data/entities/items/books/book_corpse.xml", + item_name="$booktitle_corpse", + origin="Vanilla", + tags="tablet,normal_tablet" + }, + { + file="data/entities/items/books/book_diamond.xml", + item_name="$item_book_diamond", + origin="Vanilla", + tags="scroll,tablet" + }, + { + file="data/entities/items/books/book_essences.xml", + item_name="$item_book_essences", + origin="Vanilla", + tags="scroll,tablet" + }, + { + file="data/entities/items/books/book_hint.xml", + item_name="$item_book_hint", + origin="Vanilla", + tags="scroll,tablet" + }, + { + file="data/entities/items/books/book_mestari.xml", + item_name="$booktitle_mestari", + origin="Vanilla", + tags="scroll,tablet" + }, + { + file="data/entities/items/books/book_moon.xml", + item_name="$item_book_moon", + origin="Vanilla", + tags="scroll,tablet" + }, + { + file="data/entities/items/books/book_music_a.xml", + item_name="$item_book_music", + origin="Vanilla", + tags="scroll,tablet" + }, + { + file="data/entities/items/books/book_music_b.xml", + item_name="$item_book_music_b", + origin="Vanilla", + tags="scroll,tablet" + }, + { + file="data/entities/items/books/book_music_c.xml", + item_name="$item_book_music_c", + origin="Vanilla", + tags="scroll,tablet" + }, + { + file="data/entities/items/books/book_robot.xml", + item_name="$item_book_robot", + origin="Vanilla", + tags="scroll,tablet" + }, + { + file="data/entities/items/books/book_s_a.xml", + item_name="$item_book_s_a", + origin="Vanilla", + tags="scroll,tablet" + }, + { + file="data/entities/items/books/book_s_b.xml", + item_name="$item_book_s_a", + origin="Vanilla", + tags="scroll,tablet" + }, + { + file="data/entities/items/books/book_s_c.xml", + item_name="$item_book_s_a", + origin="Vanilla", + tags="scroll,tablet" + }, + { + file="data/entities/items/books/book_s_d.xml", + item_name="$item_book_s_a", + origin="Vanilla", + tags="scroll,tablet" + }, + { + file="data/entities/items/books/book_s_e.xml", + item_name="$item_book_s_a", + origin="Vanilla", + tags="scroll,tablet" + }, + { + file="data/entities/items/books/book_tree.xml", + item_name="$booktitle_tree", + origin="Vanilla", + tags="tablet,normal_tablet" + }, + { + file="data/entities/items/easter/beer_bottle.xml", + item_name="$item_potion", + origin="Vanilla", + tags="teleportable_NOT,hittable", + ui_name="$item_kaljapullo" + }, + { + file="data/entities/items/easter/minit_watering.xml", + item_name="Potion", + origin="Vanilla", + tags="teleportable_NOT,hittable", + ui_name="Watering can" + }, + { + file="data/entities/items/flute.xml", + item_name="$item_ocarina", + origin="Vanilla", + tags="teleportable_NOT,item,wand" + }, + { + file="data/entities/items/kantele.xml", + item_name="$item_kantele", + origin="Vanilla", + tags="teleportable_NOT,item,wand,kantele" + }, + { + file="data/entities/items/leukaluu_kantele.xml", + item_name="$item_leukaluu_kantele", + origin="Vanilla", + tags="teleportable_NOT,item,wand" + }, + { + file="data/entities/items/orbs/orb_base.xml", + item_name="$item_orb", + origin="Vanilla", + tags="teleportable_NOT,hittable,polymorphable_NOT" + }, + { + file="data/entities/items/pickup/beamstone.xml", + item_name="$item_mega_beam_stone", + origin="Vanilla", + tags="teleportable_NOT,hittable,item_physics,item_pickup" + }, + { + file="data/entities/items/pickup/bloodmoney_10.xml", + item_name="$item_bloodmoney_10", + origin="Vanilla", + tags="item_physics,gold_nugget", + ui_name="$item_bloodmoney" + }, + { + file="data/entities/items/pickup/bloodmoney_1000.xml", + item_name="$item_bloodmoney_1000", + origin="Vanilla", + tags="item_physics,gold_nugget", + ui_name="$item_bloodmoney" + }, + { + file="data/entities/items/pickup/bloodmoney_10000.xml", + item_name="$item_bloodmoney_10000", + origin="Vanilla", + tags="item_physics,gold_nugget", + ui_name="$item_bloodmoney" + }, + { + file="data/entities/items/pickup/bloodmoney_200.xml", + item_name="$item_bloodmoney_200", + origin="Vanilla", + tags="item_physics,gold_nugget", + ui_name="$item_bloodmoney" + }, + { + file="data/entities/items/pickup/bloodmoney_200000.xml", + item_name="$item_bloodmoney_200000", + origin="Vanilla", + tags="item_physics,gold_nugget", + ui_name="$item_bloodmoney" + }, + { + file="data/entities/items/pickup/bloodmoney_50.xml", + item_name="$item_bloodmoney_50", + origin="Vanilla", + tags="item_physics,gold_nugget", + ui_name="$item_bloodmoney" + }, + { + file="data/entities/items/pickup/brimstone.xml", + item_name="$item_brimstone", + origin="Vanilla", + tags="teleportable_NOT,hittable,item_physics,item_pickup,brimstone" + }, + { + file="data/entities/items/pickup/broken_wand.xml", + item_name="$item_broken_wand", + origin="Vanilla", + tags="teleportable_NOT,hittable,item_physics,item_pickup,forgeable,broken_wand" + }, + { + file="data/entities/items/pickup/cape.xml", + item_name="Fire protection cape", + origin="Vanilla", + tags="teleportable_NOT", + ui_name="Cape upgrade" + }, + { + file="data/entities/items/pickup/chest_leggy.xml", + item_name="$item_chest_treasure", + origin="Vanilla", + tags="teleportable_NOT,item_physics,item_pickup,effectable_prop" + }, + { + file="data/entities/items/pickup/chest_random.xml", + item_name="$item_chest_treasure", + origin="Vanilla", + tags="teleportable_NOT,item_physics,item_pickup,chest,effectable_prop" + }, + { + file="data/entities/items/pickup/chest_random_super.xml", + item_name="$item_chest_treasure", + origin="Vanilla", + tags="teleportable_NOT,item_physics,item_pickup,chest,effectable_prop", + ui_name="$item_chest_treasure_super" + }, + { + file="data/entities/items/pickup/egg_fire.xml", + item_name="$item_egg_fire", + origin="Vanilla", + tags="teleportable_NOT,hittable,item_physics,item_pickup,egg_item" + }, + { + file="data/entities/items/pickup/egg_hollow.xml", + item_name="$item_egg_hollow", + origin="Vanilla", + tags="teleportable_NOT,hittable,item_physics,item_pickup,egg_item" + }, + { + file="data/entities/items/pickup/egg_monster.xml", + item_name="$item_egg", + origin="Vanilla", + tags="teleportable_NOT,hittable,item_physics,item_pickup,egg_item" + }, + { + file="data/entities/items/pickup/egg_purple.xml", + item_name="$item_egg_purple", + origin="Vanilla", + tags="teleportable_NOT,hittable,item_physics,item_pickup,egg_item" + }, + { + file="data/entities/items/pickup/egg_red.xml", + item_name="$item_egg", + origin="Vanilla", + tags="teleportable_NOT,hittable,item_physics,item_pickup,egg_item" + }, + { + file="data/entities/items/pickup/egg_slime.xml", + item_name="$item_egg_slime", + origin="Vanilla", + tags="teleportable_NOT,hittable,item_physics,item_pickup,egg_item" + }, + { + file="data/entities/items/pickup/egg_spiders.xml", + item_name="$item_egg_purple", + origin="Vanilla", + tags="teleportable_NOT,hittable,item_physics,item_pickup,egg_item" + }, + { + file="data/entities/items/pickup/egg_worm.xml", + item_name="$item_egg_worm", + origin="Vanilla", + tags="teleportable_NOT,hittable,item_physics,item_pickup,egg_item" + }, + { + file="data/entities/items/pickup/essence_air.xml", + item_name="$item_essence_air", + origin="Vanilla", + tags="teleportable_NOT,item_pickup,essence" + }, + { + file="data/entities/items/pickup/essence_alcohol.xml", + item_name="$item_essence_alcohol", + origin="Vanilla", + tags="teleportable_NOT,item_pickup,essence" + }, + { + file="data/entities/items/pickup/essence_fire.xml", + item_name="$item_essence_fire", + origin="Vanilla", + tags="teleportable_NOT,item_pickup,essence" + }, + { + file="data/entities/items/pickup/essence_laser.xml", + item_name="$item_essence_laser", + origin="Vanilla", + tags="teleportable_NOT,item_pickup,essence" + }, + { + file="data/entities/items/pickup/essence_water.xml", + item_name="$item_essence_water", + origin="Vanilla", + tags="teleportable_NOT,item_pickup,essence" + }, + { + file="data/entities/items/pickup/evil_eye.xml", + item_name="$item_evil_eye", + origin="Vanilla", + tags="teleportable_NOT,hittable,item_physics,item_pickup,evil_eye" + }, + { + file="data/entities/items/pickup/goldnugget.xml", + item_name="$item_goldnugget_10", + origin="Vanilla", + tags="item_physics,gold_nugget", + ui_name="$item_goldnugget" + }, + { + file="data/entities/items/pickup/goldnugget_10.xml", + item_name="$item_goldnugget_10", + origin="Vanilla", + tags="item_physics,gold_nugget", + ui_name="$item_goldnugget" + }, + { + file="data/entities/items/pickup/goldnugget_1000.xml", + item_name="$item_goldnugget_1000", + origin="Vanilla", + tags="item_physics,gold_nugget", + ui_name="$item_goldnugget" + }, + { + file="data/entities/items/pickup/goldnugget_10000.xml", + item_name="$item_goldnugget_10000", + origin="Vanilla", + tags="item_physics,gold_nugget", + ui_name="$item_goldnugget" + }, + { + file="data/entities/items/pickup/goldnugget_200.xml", + item_name="$item_goldnugget_200", + origin="Vanilla", + tags="item_physics,gold_nugget", + ui_name="$item_goldnugget" + }, + { + file="data/entities/items/pickup/goldnugget_200000.xml", + item_name="$item_goldnugget_200000", + origin="Vanilla", + tags="item_physics,gold_nugget", + ui_name="$item_goldnugget" + }, + { + file="data/entities/items/pickup/goldnugget_50.xml", + item_name="$item_goldnugget_50", + origin="Vanilla", + tags="item_physics,gold_nugget", + ui_name="$item_goldnugget" + }, + { + file="data/entities/items/pickup/gourd.xml", + item_name="$item_gourd", + origin="Vanilla", + tags="teleportable_NOT,hittable,item_physics,item_pickup,gourd" + }, + { + file="data/entities/items/pickup/greed_curse.xml", + item_name="$item_essence_greed", + origin="Vanilla", + tags="teleportable_NOT,item_pickup,essence" + }, + { + file="data/entities/items/pickup/heart.xml", + item_name="$item_heart", + origin="Vanilla", + tags="teleportable_NOT,hittable,item_pickup,drillable" + }, + { + file="data/entities/items/pickup/heart_better.xml", + item_name="$item_heart_better", + origin="Vanilla", + tags="teleportable_NOT,hittable,item_pickup,drillable" + }, + { + file="data/entities/items/pickup/heart_evil.xml", + item_name="$item_heart", + origin="Vanilla", + tags="teleportable_NOT,hittable,item_pickup,drillable" + }, + { + file="data/entities/items/pickup/heart_fullhp.xml", + item_name="$item_heart_fullhp", + origin="Vanilla", + tags="teleportable_NOT,hittable,item_pickup,drillable" + }, + { + file="data/entities/items/pickup/jar.xml", + item_name="$item_jar", + origin="Vanilla", + tags="teleportable_NOT,hittable,item_physics,item_pickup,potion" + }, + { + file="data/entities/items/pickup/moon.xml", + item_name="$item_moon", + origin="Vanilla", + tags="teleportable_NOT,hittable,item_pickup,moon_energy" + }, + { + file="data/entities/items/pickup/musicstone.xml", + item_name="$item_musicstone", + origin="Vanilla", + tags="teleportable_NOT,hittable,item_physics,item_pickup,moon_energy" + }, + { + file="data/entities/items/pickup/perk_reroll.xml", + item_name="$item_perk_reroll", + origin="Vanilla", + tags="teleportable_NOT,hittable,item,glue_NOT,perk_reroll_machine,item_shop" + }, + { + file="data/entities/items/pickup/physics_die.xml", + item_name="$item_die", + origin="Vanilla", + tags="teleportable_NOT,hittable,item_physics,item_pickup" + }, + { + file="data/entities/items/pickup/physics_gold_orb.xml", + item_name="$item_gold_orb", + origin="Vanilla", + tags="teleportable_NOT,hittable,item_physics,item_pickup" + }, + { + file="data/entities/items/pickup/physics_gold_orb_greed.xml", + item_name="$item_gold_orb_greed", + origin="Vanilla", + tags="teleportable_NOT,hittable,item_physics,item_pickup" + }, + { + file="data/entities/items/pickup/physics_greed_die.xml", + item_name="$item_greed_die", + origin="Vanilla", + tags="teleportable_NOT,hittable,item_physics,item_pickup" + }, + { + file="data/entities/items/pickup/poopstone.xml", + item_name="$item_kakka", + origin="Vanilla", + tags="teleportable_NOT,hittable,item_physics,item_pickup,poopstone" + }, + { + file="data/entities/items/pickup/potion.xml", + item_name="$item_potion", + origin="Vanilla", + tags="teleportable_NOT,hittable,item_physics,item_pickup,potion" + }, + { + file="data/entities/items/pickup/potion_aggressive.xml", + item_name="$item_potion", + origin="Vanilla", + tags="teleportable_NOT,hittable,item_physics,item_pickup,potion,projectile_item" + }, + { + file="data/entities/items/pickup/powder_stash.xml", + item_name="$item_powder_stash_3", + origin="Vanilla", + tags="teleportable_NOT,hittable,item_physics,item_pickup,powder_stash" + }, + { + file="data/entities/items/pickup/runestones/runestone_base.xml", + item_name="$item_runestone_slow", + origin="Vanilla", + tags="teleportable_NOT,item_physics,item_pickup" + }, + { + file="data/entities/items/pickup/runestones/runestone_disc.xml", + item_name="$item_runestone_disc", + origin="Vanilla", + tags="teleportable_NOT,item_physics,item_pickup" + }, + { + file="data/entities/items/pickup/runestones/runestone_fireball.xml", + item_name="$item_runestone_fireball", + origin="Vanilla", + tags="teleportable_NOT,item_physics,item_pickup" + }, + { + file="data/entities/items/pickup/runestones/runestone_laser.xml", + item_name="$item_runestone_laser", + origin="Vanilla", + tags="teleportable_NOT,item_physics,item_pickup" + }, + { + file="data/entities/items/pickup/runestones/runestone_lava.xml", + item_name="$item_runestone_lava", + origin="Vanilla", + tags="teleportable_NOT,item_physics,item_pickup" + }, + { + file="data/entities/items/pickup/runestones/runestone_metal.xml", + item_name="$item_runestone_metal", + origin="Vanilla", + tags="teleportable_NOT,item_physics,item_pickup" + }, + { + file="data/entities/items/pickup/runestones/runestone_null.xml", + item_name="$item_runestone_null", + origin="Vanilla", + tags="teleportable_NOT,item_physics,item_pickup" + }, + { + file="data/entities/items/pickup/runestones/runestone_slow.xml", + item_name="$item_runestone_slow", + origin="Vanilla", + tags="teleportable_NOT,item_physics,item_pickup" + }, + { + file="data/entities/items/pickup/safe_haven.xml", + item_name="$item_safe_haven", + origin="Vanilla", + tags="teleportable_NOT,hittable,item_physics" + }, + { + file="data/entities/items/pickup/spell_refresh.xml", + item_name="$item_spell_refresh", + origin="Vanilla", + tags="teleportable_NOT,hittable,item_pickup,drillable" + }, + { + file="data/entities/items/pickup/stonestone.xml", + item_name="$item_stonestone", + origin="Vanilla", + tags="teleportable_NOT,hittable,item_physics,item_pickup,stonestone" + }, + { + file="data/entities/items/pickup/summon_portal_broken.xml", + item_name="$action_broken_spell", + origin="Vanilla", + tags="teleportable_NOT,hittable,item_physics,item_pickup,forgeable,card_summon_portal_broken" + }, + { + file="data/entities/items/pickup/sun/sunseed.xml", + item_name="$item_sunseed", + origin="Vanilla", + tags="teleportable_NOT,hittable,item_physics,item_pickup,seed_a" + }, + { + file="data/entities/items/pickup/sun/sunstone.xml", + item_name="$item_seed_c", + origin="Vanilla", + tags="teleportable_NOT,hittable,item_physics,item_pickup,seed_b" + }, + { + file="data/entities/items/pickup/test/pouch.xml", + item_name="$item_potion", + origin="Vanilla", + tags="teleportable_NOT,hittable,item_physics" + }, + { + file="data/entities/items/pickup/test/pouch_static.xml", + item_name="$item_potion", + origin="Vanilla", + tags="teleportable_NOT,hittable,item_physics" + }, + { + file="data/entities/items/pickup/thunderstone.xml", + item_name="$item_thunderstone", + origin="Vanilla", + tags="teleportable_NOT,hittable,item_physics,item_pickup,thunderstone" + }, + { + file="data/entities/items/pickup/utility_box.xml", + item_name="$item_utility_box", + origin="Vanilla", + tags="teleportable_NOT,item_physics,item_pickup,effectable_prop,utility_box" + }, + { + file="data/entities/items/pickup/wandstone.xml", + item_name="$item_wandstone", + origin="Vanilla", + tags="teleportable_NOT,hittable,item_physics,item_pickup" + }, + { + file="data/entities/items/pickup/waterstone.xml", + item_name="$item_waterstone", + origin="Vanilla", + tags="teleportable_NOT,hittable,item_physics,item_pickup,waterstone" + }, + { + file="data/entities/items/starting_bomb_wand.xml", + item_name="bomb_wand", + origin="Vanilla", + tags="teleportable_NOT,item,wand" + }, + { + file="data/entities/items/starting_bomb_wand_rng.xml", + item_name="bomb_wand", + origin="Vanilla", + tags="teleportable_NOT,item,wand" + }, + { + file="data/entities/items/starting_bomb_wand_rng_daily.xml", + item_name="bomb_wand", + origin="Vanilla", + tags="teleportable_NOT,item,wand" + }, + { + file="data/entities/items/starting_wand.xml", + item_name="default_gun", + origin="Vanilla", + tags="teleportable_NOT,item,wand,sacred_wand,first_wand" + }, + { + file="data/entities/items/starting_wand_rng.xml", + item_name="default_gun", + origin="Vanilla", + tags="teleportable_NOT,item,wand" + }, + { + file="data/entities/items/starting_wand_rng_daily.xml", + item_name="default_gun", + origin="Vanilla", + tags="teleportable_NOT,item,wand" + }, + { + file="data/entities/items/wand_daily_01.xml", + origin="Vanilla", + tags="teleportable_NOT,item,wand" + }, + { + file="data/entities/items/wand_daily_02.xml", + origin="Vanilla", + tags="teleportable_NOT,item,wand" + }, + { + file="data/entities/items/wand_daily_03.xml", + origin="Vanilla", + tags="teleportable_NOT,item,wand" + }, + { + file="data/entities/items/wand_daily_04.xml", + origin="Vanilla", + tags="teleportable_NOT,item,wand" + }, + { + file="data/entities/items/wand_daily_05.xml", + origin="Vanilla", + tags="teleportable_NOT,item,wand" + }, + { + file="data/entities/items/wand_daily_06.xml", + origin="Vanilla", + tags="teleportable_NOT,item,wand" + }, + { + file="data/entities/items/wand_level_01.xml", + origin="Vanilla", + tags="teleportable_NOT,item,wand" + }, + { + file="data/entities/items/wand_level_01_better.xml", + origin="Vanilla", + tags="teleportable_NOT,item,wand" + }, + { + file="data/entities/items/wand_level_01_p.xml", + origin="Vanilla", + tags="teleportable_NOT,wand" + }, + { + file="data/entities/items/wand_level_02.xml", + origin="Vanilla", + tags="teleportable_NOT,item,wand" + }, + { + file="data/entities/items/wand_level_02_better.xml", + origin="Vanilla", + tags="teleportable_NOT,item,wand" + }, + { + file="data/entities/items/wand_level_02_p.xml", + origin="Vanilla", + tags="teleportable_NOT,wand" + }, + { + file="data/entities/items/wand_level_03.xml", + origin="Vanilla", + tags="teleportable_NOT,item,wand" + }, + { + file="data/entities/items/wand_level_03_better.xml", + origin="Vanilla", + tags="teleportable_NOT,item,wand" + }, + { + file="data/entities/items/wand_level_03_p.xml", + origin="Vanilla", + tags="teleportable_NOT,wand" + }, + { + file="data/entities/items/wand_level_04.xml", + origin="Vanilla", + tags="teleportable_NOT,item,wand" + }, + { + file="data/entities/items/wand_level_04_better.xml", + origin="Vanilla", + tags="teleportable_NOT,item,wand" + }, + { + file="data/entities/items/wand_level_04_p.xml", + origin="Vanilla", + tags="teleportable_NOT,wand" + }, + { + file="data/entities/items/wand_level_05.xml", + origin="Vanilla", + tags="teleportable_NOT,item,wand" + }, + { + file="data/entities/items/wand_level_05_better.xml", + origin="Vanilla", + tags="teleportable_NOT,item,wand" + }, + { + file="data/entities/items/wand_level_05_p.xml", + origin="Vanilla", + tags="teleportable_NOT,wand" + }, + { + file="data/entities/items/wand_level_06.xml", + origin="Vanilla", + tags="teleportable_NOT,item,wand" + }, + { + file="data/entities/items/wand_level_06_better.xml", + origin="Vanilla", + tags="teleportable_NOT,item,wand" + }, + { + file="data/entities/items/wand_level_06_p.xml", + origin="Vanilla", + tags="teleportable_NOT,wand" + }, + { + file="data/entities/items/wand_level_10.xml", + origin="Vanilla", + tags="teleportable_NOT,item,wand" + }, + { + file="data/entities/items/wand_petri.xml", + origin="Vanilla", + tags="teleportable_NOT,item,wand" + }, + { + file="data/entities/items/wand_unshuffle_01.xml", + origin="Vanilla", + tags="teleportable_NOT,item,wand" + }, + { + file="data/entities/items/wand_unshuffle_01_p.xml", + origin="Vanilla", + tags="teleportable_NOT,wand" + }, + { + file="data/entities/items/wand_unshuffle_02.xml", + origin="Vanilla", + tags="teleportable_NOT,item,wand" + }, + { + file="data/entities/items/wand_unshuffle_02_p.xml", + origin="Vanilla", + tags="teleportable_NOT,wand" + }, + { + file="data/entities/items/wand_unshuffle_03.xml", + origin="Vanilla", + tags="teleportable_NOT,item,wand" + }, + { + file="data/entities/items/wand_unshuffle_03_p.xml", + origin="Vanilla", + tags="teleportable_NOT,wand" + }, + { + file="data/entities/items/wand_unshuffle_04.xml", + origin="Vanilla", + tags="teleportable_NOT,item,wand" + }, + { + file="data/entities/items/wand_unshuffle_04_p.xml", + origin="Vanilla", + tags="teleportable_NOT,wand" + }, + { + file="data/entities/items/wand_unshuffle_05.xml", + origin="Vanilla", + tags="teleportable_NOT,item,wand" + }, + { + file="data/entities/items/wand_unshuffle_05_p.xml", + origin="Vanilla", + tags="teleportable_NOT,wand" + }, + { + file="data/entities/items/wand_unshuffle_06.xml", + origin="Vanilla", + tags="teleportable_NOT,item,wand" + }, + { + file="data/entities/items/wand_unshuffle_06_p.xml", + origin="Vanilla", + tags="teleportable_NOT,wand" + }, + { + file="data/entities/items/wand_unshuffle_10.xml", + origin="Vanilla", + tags="teleportable_NOT,item,wand" + }, + { + file="data/entities/items/wands/custom/digger_01.xml", + item_name="fire_wand", + origin="Vanilla", + tags="teleportable_NOT,item,wand" + }, + { + file="data/entities/items/wands/experimental/experimental_wand_1.xml", + item_name="$item_wand_experimental_1", + origin="Vanilla", + tags="teleportable_NOT,item,wand,wand_experimental" + }, + { + file="data/entities/items/wands/experimental/experimental_wand_2.xml", + item_name="$item_wand_experimental_2", + origin="Vanilla", + tags="teleportable_NOT,item,wand,wand_experimental" + }, + { + file="data/entities/items/wands/experimental/experimental_wand_3.xml", + item_name="$item_wand_experimental_1", + origin="Vanilla", + tags="teleportable_NOT,item,wand" + }, + { + file="data/entities/items/wands/experimental/experimental_wand_4.xml", + item_name="$item_chainsaw", + origin="Vanilla", + tags="teleportable_NOT,item,wand" + }, + { + file="data/entities/items/wands/level_01/base_wand_level_1.xml", + origin="Vanilla", + tags="teleportable_NOT,hittable,wand" + }, + { + file="data/entities/items/wands/level_01/wand_001.xml", + origin="Vanilla", + tags="teleportable_NOT,hittable,wand" + }, + { + file="data/entities/items/wands/level_01/wand_002.xml", + origin="Vanilla", + tags="teleportable_NOT,hittable,wand" + }, + { + file="data/entities/items/wands/level_01/wand_003.xml", + origin="Vanilla", + tags="teleportable_NOT,hittable,wand" + }, + { + file="data/entities/items/wands/level_01/wand_004.xml", + origin="Vanilla", + tags="teleportable_NOT,hittable,wand" + }, + { + file="data/entities/items/wands/level_01/wand_005.xml", + origin="Vanilla", + tags="teleportable_NOT,hittable,wand" + }, + { + file="data/entities/items/wands/level_01/wand_006.xml", + origin="Vanilla", + tags="teleportable_NOT,hittable,wand" + }, + { + file="data/entities/items/wands/level_01/wand_007.xml", + origin="Vanilla", + tags="teleportable_NOT,hittable,wand" + }, + { + file="data/entities/items/wands/level_01/wand_008.xml", + origin="Vanilla", + tags="teleportable_NOT,hittable,wand" + }, + { + file="data/entities/items/wands/level_01/wand_009.xml", + origin="Vanilla", + tags="teleportable_NOT,hittable,wand" + }, + { + file="data/entities/items/wands/level_01/wand_010.xml", + origin="Vanilla", + tags="teleportable_NOT,hittable,item,wand" + }, + { + file="data/entities/items/wands/level_01/wand_011.xml", + origin="Vanilla", + tags="teleportable_NOT,hittable,item,wand" + }, + { + file="data/entities/items/wands/level_01/wand_012.xml", + origin="Vanilla", + tags="teleportable_NOT,hittable,item,wand" + }, + { + file="data/entities/items/wands/level_01/wand_013.xml", + origin="Vanilla", + tags="teleportable_NOT,hittable,item,wand" + }, + { + file="data/entities/items/wands/level_01/wand_014.xml", + origin="Vanilla", + tags="teleportable_NOT,hittable,item,wand" + }, + { + file="data/entities/items/wands/level_01/wand_015.xml", + origin="Vanilla", + tags="teleportable_NOT,hittable,item,wand" + }, + { + file="data/entities/items/wands/level_01/wand_016.xml", + origin="Vanilla", + tags="teleportable_NOT,hittable,item,wand" + }, + { + file="data/entities/items/wands/level_01/wand_017.xml", + origin="Vanilla", + tags="teleportable_NOT,hittable,item,wand" + }, + { + file="data/entities/items/wands/wand_good/wand_good_1.xml", + item_name="$item_wand_good_1", + origin="Vanilla", + tags="teleportable_NOT,item,wand,wand_good" + }, + { + file="data/entities/items/wands/wand_good/wand_good_2.xml", + item_name="$item_wand_good_2", + origin="Vanilla", + tags="teleportable_NOT,item,wand,wand_good" + }, + { + file="data/entities/items/wands/wand_good/wand_good_3.xml", + item_name="$item_wand_good_3", + origin="Vanilla", + tags="teleportable_NOT,item,wand,wand_good" + }, + { file="data/entities/misc/test_bullet.xml", origin="Vanilla", tags="hittable" }, + { + file="data/entities/projectiles/cocktail.xml", + item_name="$item_cocktail", + origin="Vanilla", + tags="teleportable_NOT,hittable,projectile_item" + }, + { + file="data/scripts/streaming_integration/entities/chest_random.xml", + item_name="$item_chest_treasure", + origin="Vanilla", + tags="teleportable_NOT,item_physics,chest" + }, + { + file="data/scripts/streaming_integration/entities/spell_refresh.xml", + item_name="$item_spell_refresh", + origin="Vanilla", + tags="teleportable_NOT,hittable,drillable" + }, + { + file="data/scripts/streaming_integration/entities/wand_level_01.xml", + origin="Vanilla", + tags="teleportable_NOT,item,wand" + }, + { + file="data/scripts/streaming_integration/entities/wand_level_02.xml", + origin="Vanilla", + tags="teleportable_NOT,item,wand" + }, + { + file="data/scripts/streaming_integration/entities/wand_level_03.xml", + origin="Vanilla", + tags="teleportable_NOT,item,wand" + }, + { + file="mods/starting_loadouts/files/butcher/potion_berserk.xml", + item_name="$item_potion", + origin="starting_loadouts", + tags="teleportable_NOT,hittable,item_physics,potion" + }, + { + file="mods/starting_loadouts/files/butcher/potion_blood.xml", + item_name="$item_potion", + origin="starting_loadouts", + tags="teleportable_NOT,hittable,item_physics,potion" + }, + { + file="mods/starting_loadouts/files/butcher/wands/wand_1.xml", + item_name="butcher_wand", + origin="starting_loadouts", + tags="teleportable_NOT,item,wand" + }, + { + file="mods/starting_loadouts/files/butcher/wands/wand_2.xml", + item_name="butcher_wand", + origin="starting_loadouts", + tags="teleportable_NOT,item,wand" + }, + { + file="mods/starting_loadouts/files/eldritch/potion_teleport.xml", + item_name="$item_potion", + origin="starting_loadouts", + tags="teleportable_NOT,hittable,item_physics,potion" + }, + { + file="mods/starting_loadouts/files/eldritch/wands/wand_1.xml", + item_name="eldritch_wand", + origin="starting_loadouts", + tags="teleportable_NOT,item,wand" + }, + { + file="mods/starting_loadouts/files/eldritch/wands/wand_2.xml", + item_name="eldritch_wand", + origin="starting_loadouts", + tags="teleportable_NOT,item,wand" + }, + { + file="mods/starting_loadouts/files/eldritch/wands/wand_3.xml", + item_name="slime_wand", + origin="starting_loadouts", + tags="teleportable_NOT,item,wand" + }, + { + file="mods/starting_loadouts/files/fire/potion_fire.xml", + item_name="$item_potion", + origin="starting_loadouts", + tags="teleportable_NOT,hittable,item_physics,potion" + }, + { + file="mods/starting_loadouts/files/fire/wands/wand_1.xml", + item_name="fire_wand", + origin="starting_loadouts", + tags="teleportable_NOT,item,wand" + }, + { + file="mods/starting_loadouts/files/fire/wands/wand_2.xml", + item_name="fire_wand", + origin="starting_loadouts", + tags="teleportable_NOT,item,wand" + }, + { + file="mods/starting_loadouts/files/slime/potion_slime.xml", + item_name="$item_potion", + origin="starting_loadouts", + tags="teleportable_NOT,hittable,item_physics,potion" + }, + { + file="mods/starting_loadouts/files/slime/wands/wand_1.xml", + item_name="slime_wand", + origin="starting_loadouts", + tags="teleportable_NOT,item,wand" + }, + { + file="mods/starting_loadouts/files/slime/wands/wand_2.xml", + item_name="slime_wand", + origin="starting_loadouts", + tags="teleportable_NOT,item,wand" + }, + { + file="mods/starting_loadouts/files/slime/wands/wand_3.xml", + item_name="slime_wand", + origin="starting_loadouts", + tags="teleportable_NOT,item,wand" + }, + { + file="mods/starting_loadouts/files/summoner/wands/wand_1.xml", + item_name="summon_wand", + origin="starting_loadouts", + tags="teleportable_NOT,item,wand" + }, + { + file="mods/starting_loadouts/files/summoner/wands/wand_2.xml", + item_name="summon_wand", + origin="starting_loadouts", + tags="teleportable_NOT,item,wand" + }, + { + file="mods/starting_loadouts/files/thunder/wands/wand_1.xml", + item_name="thunder_wand", + origin="starting_loadouts", + tags="teleportable_NOT,item,wand" + }, + { + file="mods/starting_loadouts/files/thunder/wands/wand_2.xml", + item_name="thunder_wand", + origin="starting_loadouts", + tags="teleportable_NOT,item,wand" + } +} diff --git a/component-explorer/spawn_data/materials.lua b/component-explorer/spawn_data/materials.lua new file mode 100644 index 0000000..5ca4976 --- /dev/null +++ b/component-explorer/spawn_data/materials.lua @@ -0,0 +1,209 @@ +---@module 'component-explorer.utils.file_util' +local file_util = dofile_once("mods/component-explorer/utils/file_util.lua") + +---@module 'component-explorer.utils.copy' +local copy = dofile_once("mods/component-explorer/utils/copy.lua") + +---@module 'component-explorer.deps.nxml' +local nxml = dofile_once("mods/component-explorer/deps/nxml.lua") + +local materials_by_name = {} +local parent_pending = {} + +local function add_celldata_with_base(celldata, base, origin) + local mat = copy.shallow_copy(base) + + local copy_attr = function(attr, default) + local value = celldata.attr[attr] + if value then + mat[attr] = value + elseif mat[attr] == nil then + mat[attr] = default + end + end + + copy_attr("name") + mat.id = CellFactory_GetType(mat.name) + copy_attr("ui_name") + copy_attr("tags", "") + copy_attr("cell_type", "liquid") + copy_attr("liquid_sand") + copy_attr("liquid_static") + + if mat.cell_type == "fire" then + mat.material_type = "Fire" + elseif mat.cell_type == "gas" then + mat.material_type = "Gas" + elseif mat.cell_type == "solid" then + mat.material_type = "Solid" + elseif mat.cell_type == "liquid" then + if mat.liquid_static == "1" then + mat.material_type = "Static" + elseif mat.liquid_sand == "1" then + mat.material_type = "Powder" + else + mat.material_type = "Liquid" + end + end + + mat.display_name = mat.ui_name and GameTextGetTranslatedOrNot(mat.ui_name) + if mat.display_name == nil or mat.display_name == "" then + mat.display_name = mat.name + end + + mat.origin = origin + + materials_by_name[mat.name] = mat +end + +local function add_celldata(celldata, origin) + local mat_name = celldata.attr.name + + local base + if celldata.name == "CellDataChild" then + local parent_name = celldata.attr._parent + local parent = materials_by_name[parent_name] + if parent then + base = parent + else + parent_pending[parent_name] = parent_pending[parent_name] or {} + table.insert(parent_pending[parent_name], celldata) + return + end + elseif celldata.name == "CellData" then + base = {} + else + error("Unknown celldata type") + end + + add_celldata_with_base(celldata, base, origin) + + if parent_pending[mat_name] then + for _, child_celldata in ipairs(parent_pending[mat_name]) do + add_celldata(child_celldata, origin) + end + parent_pending[mat_name] = {} + end +end + +local function register_materials_file(materials_file, origin) + local celldatas = nxml.parse(file_util.ModTextFileGetContent(materials_file)) + + for _, child in ipairs(celldatas.children) do + if child.name == "CellData" or child.name == "CellDataChild" then + add_celldata(child, origin) + end + end + + for _, pending in pairs(parent_pending) do + for _, celldata in ipairs(pending) do + add_celldata_with_base(celldata, {}, origin) + end + end +end + +if ModMaterialsFileAdd then + -- ModMaterialsFileAdd available, we can use register_materials_file for + -- the vanilla materials file and modded ones. + for _, mat_file in ipairs(ModMaterialFilesGet()) do + local origin + if mat_file == "data/materials.xml" then + origin = "Vanilla" + else + origin = string.match(mat_file, "mods/([^/]*)") + end + register_materials_file(mat_file, origin or "Unknown") + end +else + -- ModMaterialsFileAdd not available, use register_materials_file for + -- vanilla and try to identify and register all modded materials. + register_materials_file("data/materials.xml", "Vanilla") + + local vanilla_mats = {} + for _, mat in pairs(materials_by_name) do + vanilla_mats[mat.id] = true + end + + local function mat_set(mat_ids) + local set = {} + for _, mat_name in ipairs(mat_ids) do + set[mat_name] = true + end + return set + end + local liquids = mat_set(CellFactory_GetAllLiquids(false, true)) + local liquids_and_statics = mat_set(CellFactory_GetAllLiquids(true, true)) + local powders = mat_set(CellFactory_GetAllSands(false, true)) + local powders_and_statics = mat_set(CellFactory_GetAllSands(false, true)) + local gases = mat_set(CellFactory_GetAllGases(true, true)) + local fires = mat_set(CellFactory_GetAllFires(true, true)) + local solids = mat_set(CellFactory_GetAllSolids(true, true)) + + local all_sets = { + liquids_and_statics, + powders_and_statics, + gases, + fires, + solids + } + + local full_set ={} + for _, set in ipairs(all_sets) do + for mat_name, _ in pairs(set) do + full_set[mat_name] = true + end + end + + local all_mat_names = {} + for mat_name, _ in pairs(full_set) do + table.insert(all_mat_names, mat_name) + end + table.sort(all_mat_names) + + for _, mat_name in ipairs(all_mat_names) do + local mat_id = CellFactory_GetType(mat_name) + if vanilla_mats[mat_id] then goto continue end + + local cell_type = + ((liquids_and_statics[mat_name] or powders_and_statics[mat_name]) and "liquid") + or (gases[mat_name] and "gas") + or (fires[mat_name] and "fire") + or (solids[mat_name] and "solid") + + local material_type = + (liquids[mat_name] and "Liquid") + or (powders[mat_name] and "Powder") + or (not liquids[mat_name] and (liquids_and_statics[mat_name] or powders_and_statics[mat_name]) and "Static") + or (gases[mat_name] and "Gas") + or (fires[mat_name] and "Fire") + or (solids[mat_name] and "Solid") + or "Uhmm" + + local mat = { + origin="Modded", + id=mat_id, + name=mat_name, + ui_name=CellFactory_GetUIName(mat_name), + tags=table.concat(CellFactory_GetTags(mat_id), ","), + cell_type=cell_type, + material_type=material_type, + } + + mat.display_name = mat.ui_name and GameTextGetTranslatedOrNot(mat.ui_name) + if mat.display_name == nil or mat.display_name == "" then + mat.display_name = mat.name + end + + materials_by_name[mat.name] = mat + + ::continue:: + end +end + +local materials = {} +for _, mat in pairs(materials_by_name) do + table.insert(materials, mat) +end +table.sort(materials, function(a, b) return a.id < b.id end) + +return materials diff --git a/component-explorer/spawn_data/perks.lua b/component-explorer/spawn_data/perks.lua new file mode 100644 index 0000000..0c40a31 --- /dev/null +++ b/component-explorer/spawn_data/perks.lua @@ -0,0 +1,32 @@ +dofile_once("data/scripts/perks/perk.lua") + +function register_origins(origin) + for _, perk in ipairs(perk_list) do + if perk.origin == nil then + perk.origin = origin + end + end +end + +local original_do_mod_appends = do_mod_appends +do_mod_appends = function(appends_for) + if appends_for == "data/scripts/perks/perk_list.lua" then + register_origins("Vanilla") + else + local mod_id = string.match(appends_for, "mods/([^/]*)") + register_origins(mod_id or "Unknown") + end + + original_do_mod_appends(appends_for) +end +dofile("data/scripts/perks/perk_list.lua") +do_mod_appends = original_do_mod_appends + +local perk_list = perk_list + +for _, perk in ipairs(perk_list) do + perk.display_name = GameTextGetTranslatedOrNot(perk.ui_name) + perk.display_description = GameTextGetTranslatedOrNot(perk.ui_description) +end + +return perk_list diff --git a/component-explorer/spawn_stuff.lua b/component-explorer/spawn_stuff.lua new file mode 100644 index 0000000..b227a6c --- /dev/null +++ b/component-explorer/spawn_stuff.lua @@ -0,0 +1,79 @@ +local spawn_stuff = {} + +spawn_stuff.open = false + +function spawn_stuff.show() + -- Loaded with a delay because these files need to use the translations + + ---@module 'component-explorer.spawn_stuff.creatures' + local creature_content = dofile_once("mods/component-explorer/spawn_stuff/creatures.lua") + + ---@module 'component-explorer.spawn_stuff.items' + local item_content = dofile_once("mods/component-explorer/spawn_stuff/items.lua") + + ---@module 'component-explorer.spawn_stuff.perks' + local perk_content = dofile_once("mods/component-explorer/spawn_stuff/perks.lua") + + ---@module 'component-explorer.spawn_stuff.spells' + local spell_content = dofile_once("mods/component-explorer/spawn_stuff/spells.lua") + + ---@module 'component-explorer.spawn_stuff.materials' + local material_content = dofile_once("mods/component-explorer/spawn_stuff/materials.lua") + + imgui.SetNextWindowSize(480, 200, imgui.Cond.FirstUseEver) + + local show + show, spawn_stuff.open = imgui.Begin("Spawn Stuff", spawn_stuff.open) + + if not show then + return + end + + if imgui.BeginTabBar("spawn_stuff") then + if imgui.BeginTabItem("Creatures") then + if imgui.BeginChild("#creatures_child") then + creature_content() + imgui.EndChild() + end + imgui.EndTabItem() + end + + if imgui.BeginTabItem("Items") then + if imgui.BeginChild("#items_child") then + item_content() + imgui.EndChild() + end + imgui.EndTabItem() + end + + if imgui.BeginTabItem("Perks") then + if imgui.BeginChild("#perks_child") then + perk_content() + imgui.EndChild() + end + imgui.EndTabItem() + end + + if imgui.BeginTabItem("Spells") then + if imgui.BeginChild("#spells_child") then + spell_content() + imgui.EndChild() + end + imgui.EndTabItem() + end + + if imgui.BeginTabItem("Materials") then + if imgui.BeginChild("#materials_child") then + material_content() + imgui.EndChild() + end + imgui.EndTabItem() + end + + imgui.EndTabBar() + end + + imgui.End() +end + +return spawn_stuff diff --git a/component-explorer/spawn_stuff/creatures.lua b/component-explorer/spawn_stuff/creatures.lua new file mode 100644 index 0000000..5949c28 --- /dev/null +++ b/component-explorer/spawn_stuff/creatures.lua @@ -0,0 +1,216 @@ +---@module 'component-explorer.spawn_data.creatures' +local creatures_ = dofile_once("mods/component-explorer/spawn_data/creatures.lua") + +---@module 'component-explorer.utils.copy' +local copy = dofile_once("mods/component-explorer/utils/copy.lua") + +---@module 'component-explorer.utils.strings' +local string_util = dofile_once("mods/component-explorer/utils/strings.lua") + +---@module 'component-explorer.cursor' +local cursor = dofile_once("mods/component-explorer/cursor.lua") + +---@module 'component-explorer.ui.ui_combo' +local ui_combo = dofile_once("mods/component-explorer/ui/ui_combo.lua") + +---@module 'component-explorer.utils.file_util' +local file_util = dofile_once("mods/component-explorer/utils/file_util.lua") + +local function get_enhanced_creatures() + local ret = {} + for _, c_ in ipairs(creatures_) do + local c = copy.shallow_copy(c_) + + if not file_util.text_file_exists(c.file) then + goto continue + end + + -- Add display_name attribute + if c.name then + c.display_name = GameTextGetTranslatedOrNot(c.name) + elseif c.statsname then + c.display_name = c.statsname + else + c.display_name = string.match(c.file, "[^/]*$") + end + + -- See if there's an animal_icon we can use if no img_path is set yet + if imgui.LoadImage and c.img_path == nil then + local file_name = string.match(c.file, "([^/]*)%.xml$") + local potential_img_path = "data/ui_gfx/animal_icons/" .. file_name .. ".png" + if imgui.LoadImage(potential_img_path) then + c.img_path = potential_img_path + end + end + + table.insert(ret, c) + ::continue:: + end + + table.sort(ret, function(a, b) return a.display_name < b.display_name end) + return ret +end + +local creatures = get_enhanced_creatures() + +local function get_unique_attrs(attr) + local set = {} + for _, c in ipairs(creatures) do + set[c[attr]] = true + end + + local ret = {} + for item, _ in pairs(set) do + table.insert(ret, item) + end + + table.sort(ret) + return ret +end + +local unique_herds = get_unique_attrs("herd") +local unique_origins = get_unique_attrs("origin") + +local filter_search = "" +---@type string? +local filter_herd = nil +---@type string? +local filter_origin = nil + +return function() + local _ + + imgui.SetNextItemWidth(200) + _, filter_search = imgui.InputText("Search", filter_search) + + imgui.SameLine() + imgui.SetNextItemWidth(150) + _, filter_herd = ui_combo.optional("Herd", unique_herds, filter_herd) + + if #unique_origins > 1 then + imgui.SameLine() + imgui.SetNextItemWidth(150) + _, filter_origin = ui_combo.optional("Origin", unique_origins, filter_origin) + end + + local filtered_creatures + + if filter_search == "" and filter_herd == nil and filter_origin == nil then + filtered_creatures = creatures + else + filtered_creatures = {} + for _, c in ipairs(creatures) do + if + (filter_search == "" or ( + string_util.ifind(c.display_name, filter_search, 1, true) or + (c.name and string_util.ifind(c.name, filter_search, 1, true)) or + (c.statsname and string_util.ifind(c.statsname, filter_search, 1, true)) or + string_util.ifind(c.tags, filter_search, 1, true) or + string_util.ifind(c.file, filter_search, 1, true) + )) + and (filter_herd == nil or c.herd == filter_herd) + and (filter_origin == nil or c.origin == filter_origin) + then + table.insert(filtered_creatures, c) + end + end + end + + if not imgui.BeginChild("table") then + return + end + + local column_count = 6 + + local has_image_support = imgui.LoadImage ~= nil + if has_image_support then + column_count = column_count + 1 + end + + local flags = bit.bor( + imgui.TableFlags.Resizable, + imgui.TableFlags.Hideable, + imgui.TableFlags.RowBg + ) + if imgui.BeginTable("creatures", column_count, flags) then + if has_image_support then + imgui.TableSetupColumn("img", imgui.TableColumnFlags.WidthFixed) + end + imgui.TableSetupColumn("Name") + imgui.TableSetupColumn("File") + imgui.TableSetupColumn("Tags", imgui.TableColumnFlags.DefaultHide) + imgui.TableSetupColumn("Herd", imgui.TableColumnFlags.WidthFixed) + imgui.TableSetupColumn("Origin", bit.bor(imgui.TableColumnFlags.DefaultHide, imgui.TableColumnFlags.WidthFixed)) + imgui.TableSetupColumn("Spawn", imgui.TableColumnFlags.WidthFixed) + imgui.TableHeadersRow() + + -- Keep all images loaded, not just the visible ones + if has_image_support then + local image_paths = {} + for _, c in ipairs(creatures) do + if c.img_path then + table.insert(image_paths, c.img_path) + end + end + -- Files are placed alphabetically in the data.wak, loading them in + -- that order is much faster. + table.sort(image_paths) + for _, path in ipairs(image_paths) do + imgui.LoadImage(path) + end + end + + local clipper = imgui.ListClipper.new() + clipper:Begin(#filtered_creatures) + while clipper:Step() do + for i=clipper.DisplayStart,clipper.DisplayEnd - 1 do + local c = filtered_creatures[i + 1] + imgui.PushID(c.file) + + if has_image_support then + imgui.TableNextColumn() + if c.img_path then + local img = imgui.LoadImage(c.img_path) + if img then + local style = imgui.GetStyle() + local image_size = imgui.GetTextLineHeight() + style.CellPadding_y * 2 + imgui.Image(img, image_size, image_size) + end + end + end + + imgui.TableNextColumn() + imgui.Text(c.display_name) + + imgui.TableNextColumn() + imgui.Text(c.file) + + imgui.TableNextColumn() + imgui.Text(c.tags) + + imgui.TableNextColumn() + imgui.Text(c.herd) + if imgui.IsItemHovered() and imgui.IsMouseReleased(imgui.MouseButton.Right) then + filter_herd = c.herd + end + + imgui.TableNextColumn() + imgui.Text(c.origin) + if #unique_origins > 1 and imgui.IsItemHovered() and imgui.IsMouseReleased(imgui.MouseButton.Right) then + filter_origin = c.origin + end + + imgui.TableNextColumn() + if imgui.SmallButton("Spawn") then + EntityLoad(c.file, cursor.pos()) + end + + imgui.PopID() + end + end + + imgui.EndTable() + end + + imgui.EndChild() +end diff --git a/component-explorer/spawn_stuff/items.lua b/component-explorer/spawn_stuff/items.lua new file mode 100644 index 0000000..f801eeb --- /dev/null +++ b/component-explorer/spawn_stuff/items.lua @@ -0,0 +1,154 @@ +---@module 'component-explorer.spawn_data.items' +local items_ = dofile_once("mods/component-explorer/spawn_data/items.lua") + +---@module 'component-explorer.utils.copy' +local copy = dofile_once("mods/component-explorer/utils/copy.lua") + +---@module 'component-explorer.utils.strings' +local string_util = dofile_once("mods/component-explorer/utils/strings.lua") + +---@module 'component-explorer.cursor' +local cursor = dofile_once("mods/component-explorer/cursor.lua") + +---@module 'component-explorer.ui.ui_combo' +local ui_combo = dofile_once("mods/component-explorer/ui/ui_combo.lua") + +---@module 'component-explorer.utils.file_util' +local file_util = dofile_once("mods/component-explorer/utils/file_util.lua") + +local function get_enhanced_items() + local ret = {} + for _, c_ in ipairs(items_) do + local c = copy.shallow_copy(c_) + + if not file_util.text_file_exists(c.file) then + goto continue + end + + local preferred_name = c.item_name or c.ui_name + if preferred_name then + c.display_name = GameTextGetTranslatedOrNot(preferred_name) + else + c.display_name = string.match(c.file, "[^/]*$") + end + + table.insert(ret, c) + ::continue:: + end + + table.sort(ret, function(a, b) return a.display_name < b.display_name end) + return ret +end + +local items = get_enhanced_items() + +local function get_unique_attrs(attr) + local set = {} + for _, c in ipairs(items) do + set[c[attr]] = true + end + + local ret = {} + for item, _ in pairs(set) do + table.insert(ret, item) + end + + table.sort(ret) + + return ret +end + +local unique_origins = get_unique_attrs("origin") + +local filter_search = "" +---@type string? +local filter_origin = nil + +return function() + local _ + + imgui.SetNextItemWidth(200) + _, filter_search = imgui.InputText("Search", filter_search) + + if #unique_origins > 1 then + imgui.SameLine() + imgui.SetNextItemWidth(150) + _, filter_origin = ui_combo.optional("Origin", unique_origins, filter_origin) + end + + local filtered_items + + if filter_search == "" and filter_origin == nil then + filtered_items = items + else + filtered_items = {} + for _, c in ipairs(items) do + if + (filter_search == "" or ( + string_util.ifind(c.display_name, filter_search, 1, true) or + (c.ui_name and string_util.ifind(c.ui_name, filter_search, 1, true)) or + string_util.ifind(c.tags, filter_search, 1, true) or + string_util.ifind(c.file, filter_search, 1, true) + )) + and (filter_origin == nil or c.origin == filter_origin) + then + table.insert(filtered_items, c) + end + end + end + + if not imgui.BeginChild("table") then + return + end + + local flags = bit.bor( + imgui.TableFlags.Resizable, + imgui.TableFlags.Hideable, + imgui.TableFlags.RowBg + ) + if imgui.BeginTable("items", 5, flags) then + imgui.TableSetupColumn("Name") + imgui.TableSetupColumn("File") + imgui.TableSetupColumn("Tags", imgui.TableColumnFlags.DefaultHide) + imgui.TableSetupColumn("Origin", bit.bor(imgui.TableColumnFlags.DefaultHide, imgui.TableColumnFlags.WidthFixed)) + imgui.TableSetupColumn("Spawn", imgui.TableColumnFlags.WidthFixed) + imgui.TableHeadersRow() + + local clipper = imgui.ListClipper.new() + clipper:Begin(#filtered_items) + + while clipper:Step() do + for i=clipper.DisplayStart,clipper.DisplayEnd - 1 do + local c = filtered_items[i + 1] + + imgui.PushID(c.file) + + imgui.TableNextColumn() + imgui.Text(c.display_name) + + imgui.TableNextColumn() + imgui.Text(c.file) + + imgui.TableNextColumn() + imgui.Text(c.tags) + + imgui.TableNextColumn() + imgui.Text(c.origin) + if #unique_origins > 1 and imgui.IsItemHovered() and imgui.IsMouseReleased(imgui.MouseButton.Right) then + filter_origin = c.origin + end + + imgui.TableNextColumn() + if imgui.SmallButton("Spawn") then + EntityLoad(c.file, cursor.pos()) + end + + imgui.PopID() + end + end + + imgui.EndTable() + end + + imgui.EndChild() +end diff --git a/component-explorer/spawn_stuff/materials.lua b/component-explorer/spawn_stuff/materials.lua new file mode 100644 index 0000000..4c25344 --- /dev/null +++ b/component-explorer/spawn_stuff/materials.lua @@ -0,0 +1,188 @@ +---@module 'component-explorer.utils.strings' +local string_util = dofile_once("mods/component-explorer/utils/strings.lua") + +---@module 'component-explorer.ui.ui_combo' +local ui_combo = dofile_once("mods/component-explorer/ui/ui_combo.lua") + +---@module 'component-explorer.utils.player_util' +local player_util = dofile_once("mods/component-explorer/utils/player_util.lua") + +---@module 'component-explorer.spawn_data.materials' +local materials = dofile_once("mods/component-explorer/spawn_data/materials.lua") + +local function get_unique_attrs(attr) + local set = {} + for _, mat in ipairs(materials) do + set[mat[attr]] = true + end + + local ret = {} + for item, _ in pairs(set) do + table.insert(ret, item) + end + + table.sort(ret) + return ret +end +local unique_origins = get_unique_attrs("origin") +local unique_material_types = get_unique_attrs("material_type") + +local function make_empty_stash(x, y) + local stash = EntityLoad("data/entities/items/pickup/powder_stash.xml", x, y) + while true do + local mat_id = GetMaterialInventoryMainMaterial(stash) + if mat_id == 0 then + return stash + end + AddMaterialInventoryMaterial(stash, CellFactory_GetName(mat_id), 0) + end +end + +---@param entity integer +---@return integer +local function container_matinv_size(entity) + local sucker_comp = EntityGetFirstComponentIncludingDisabled(entity, "MaterialSuckerComponent") + if sucker_comp then + return ComponentGetValue2(sucker_comp, "barrel_size") + end + + -- Fallback default + return 1000 +end + +local filter_search = "" +---@type string? +local filter_origin = nil +---@type string? +local filter_material_type = nil + +local container_options = {"Flask", "Pouch"} +local container_choice = nil + +local function mat_container_choice(mat) + if container_choice then return container_choice end + + if mat.material_type == "Powder" or mat.material_type == "Static" then + return "Pouch" + else + return "Flask" + end +end + +return function() + local _ + + imgui.SetNextItemWidth(200) + _, filter_search = imgui.InputText("Search", filter_search) + + imgui.SameLine() + imgui.SetNextItemWidth(150) + _, filter_material_type = ui_combo.optional("Material Type", unique_material_types, filter_material_type) + + if #unique_origins > 1 then + imgui.SameLine() + imgui.SetNextItemWidth(150) + _, filter_origin = ui_combo.optional("Origin", unique_origins, filter_origin) + end + + imgui.Separator() + + imgui.SetNextItemWidth(150) + _, container_choice = ui_combo.optional("Spawn Container", container_options, container_choice, "--Depends--") + if not imgui.BeginChild("table") then + return + end + + local filtered_materials + if filter_search == "" and filter_material_type == nil and filter_origin == nil then + filtered_materials = materials + else + filtered_materials = {} + for _, mat in ipairs(materials) do + if + (filter_search == "" or ( + string_util.ifind(mat.display_name, filter_search, 1, true) or + string_util.ifind(mat.name, filter_search, 1, true) or + string_util.ifind(mat.tags, filter_search, 1, true) + )) + and (filter_material_type == nil or mat.material_type == filter_material_type) + and (filter_origin == nil or mat.origin == filter_origin) + then + table.insert(filtered_materials, mat) + end + end + end + + local flags = bit.bor( + imgui.TableFlags.Resizable, + imgui.TableFlags.Hideable, + imgui.TableFlags.RowBg + ) + + if imgui.BeginTable("mats", 7, flags) then + imgui.TableSetupColumn("#", imgui.TableColumnFlags.WidthFixed) + imgui.TableSetupColumn("Display") + imgui.TableSetupColumn("Name", imgui.TableColumnFlags.DefaultHide) + imgui.TableSetupColumn("Tags", imgui.TableColumnFlags.DefaultHide) + imgui.TableSetupColumn("Type", imgui.TableColumnFlags.WidthFixed) + imgui.TableSetupColumn("Origin", imgui.TableColumnFlags.WidthFixed) + imgui.TableSetupColumn("Spawn", imgui.TableColumnFlags.WidthFixed) + imgui.TableHeadersRow() + + local clipper = imgui.ListClipper.new() + clipper:Begin(#filtered_materials) + + while clipper:Step() do + for i=clipper.DisplayStart,clipper.DisplayEnd - 1 do + local mat = filtered_materials[i + 1] + imgui.PushID(mat.name) + + imgui.TableNextColumn() + imgui.Text(tostring(mat.id)) + + imgui.TableNextColumn() + imgui.Text(mat.display_name) + + imgui.TableNextColumn() + imgui.Text(mat.name) + + imgui.TableNextColumn() + imgui.Text(mat.tags) + + imgui.TableNextColumn() + imgui.Text(mat.material_type) + if imgui.IsItemHovered() and imgui.IsMouseReleased(imgui.MouseButton.Right) then + filter_material_type = mat.material_type + end + + imgui.TableNextColumn() + imgui.Text(mat.origin) + if #unique_origins > 1 and imgui.IsItemHovered() and imgui.IsMouseReleased(imgui.MouseButton.Right) then + filter_origin = mat.origin + end + + imgui.TableNextColumn() + local mat_container = mat_container_choice(mat) + if imgui.SmallButton(mat_container) then + local player = player_util.get_player() + if player then + local x, y = EntityGetTransform(player) + local container + if mat_container == "Pouch" then + container = make_empty_stash(x, y) + else + container = EntityLoad("data/entities/items/pickup/potion_empty.xml", x, y) + end + AddMaterialInventoryMaterial(container, mat.name, container_matinv_size(container)) + end + end + + imgui.PopID() + end + end + + imgui.EndTable() + end + + imgui.EndChild() +end diff --git a/component-explorer/spawn_stuff/perks.lua b/component-explorer/spawn_stuff/perks.lua new file mode 100644 index 0000000..97c634a --- /dev/null +++ b/component-explorer/spawn_stuff/perks.lua @@ -0,0 +1,161 @@ +---@module 'component-explorer.utils.strings' +local string_util = dofile_once("mods/component-explorer/utils/strings.lua") + +---@module 'component-explorer.ui.ui_combo' +local ui_combo = dofile_once("mods/component-explorer/ui/ui_combo.lua") + +---@module 'component-explorer.utils.player_util' +local player_util = dofile_once("mods/component-explorer/utils/player_util.lua") + +---@module 'component-explorer.spawn_data.perks' +local perk_list = dofile_once("mods/component-explorer/spawn_data/perks.lua") + +local function get_unique_attrs(attr) + local set = {} + for _, perk in ipairs(perk_list) do + set[perk[attr]] = true + end + + local ret = {} + for item, _ in pairs(set) do + table.insert(ret, item) + end + + table.sort(ret) + return ret +end +local unique_origins = get_unique_attrs("origin") + + +local filter_search = "" +---@type string? +local filter_origin = nil + +return function() + local _ + + imgui.SetNextItemWidth(200) + _, filter_search = imgui.InputText("Search", filter_search) + + if #unique_origins > 1 then + imgui.SameLine() + imgui.SetNextItemWidth(150) + _, filter_origin = ui_combo.optional("Origin", unique_origins, filter_origin) + end + + local filtered_perks + if filter_search == "" and filter_origin == nil then + filtered_perks = perk_list + else + filtered_perks = {} + for _, perk in ipairs(perk_list) do + if + (filter_search == "" or ( + string_util.ifind(perk.id, filter_search, 1, true) or + string_util.ifind(perk.display_name, filter_search, 1, true) or + string_util.ifind(perk.display_description, filter_search, 1, true) + )) + and (filter_origin == nil or perk.origin == filter_origin) + then + table.insert(filtered_perks, perk) + end + end + end + + if not imgui.BeginChild("table") then return end + + local column_count = 4 + + local has_image_support = imgui.LoadImage ~= nil + if has_image_support then + column_count = column_count + 1 + end + + local flags = bit.bor( + imgui.TableFlags.Resizable, + imgui.TableFlags.Hideable, + imgui.TableFlags.RowBg + ) + + if imgui.BeginTable("perks", column_count, flags) then + if has_image_support then + imgui.TableSetupColumn("img", imgui.TableColumnFlags.WidthFixed) + end + imgui.TableSetupColumn("Name") + imgui.TableSetupColumn("ID") + imgui.TableSetupColumn("Origin", imgui.TableColumnFlags.WidthFixed) + imgui.TableSetupColumn("Spawn", imgui.TableColumnFlags.WidthFixed) + imgui.TableHeadersRow() + + if has_image_support then + local image_paths = {} + for _, p in ipairs(perk_list) do + if p.perk_icon then + table.insert(image_paths, p.perk_icon) + end + end + -- Files are placed alphabetically in the data.wak, loading them in + -- that order is much faster. + table.sort(image_paths) + for _, path in ipairs(image_paths) do + imgui.LoadImage(path) + end + end + + local clipper = imgui.ListClipper.new() + clipper:Begin(#filtered_perks) + + while clipper:Step() do + for i=clipper.DisplayStart,clipper.DisplayEnd - 1 do + local perk = filtered_perks[i + 1] + imgui.PushID(perk.id) + + if has_image_support then + imgui.TableNextColumn() + if perk.perk_icon then + local img = imgui.LoadImage(perk.perk_icon) + if img then + local style = imgui.GetStyle() + local image_size = imgui.GetTextLineHeight() + style.CellPadding_y * 2 + imgui.Image(img, image_size, image_size) + end + end + end + + imgui.TableNextColumn() + imgui.Text(perk.display_name) + + imgui.TableNextColumn() + imgui.Text(perk.id) + + imgui.TableNextColumn() + imgui.Text(perk.origin) + if #unique_origins > 1 and imgui.IsItemHovered() and imgui.IsMouseReleased(imgui.MouseButton.Right) then + filter_origin = perk.origin + end + + imgui.TableNextColumn() + if imgui.SmallButton("Equip") then + local player = player_util.get_player() + if player then + local success, result = pcall(function() + local x, y = EntityGetTransform(player) + local perk_entity = perk_spawn(x, y - 8, perk.id) + perk_pickup(perk_entity, player, nil, true, false) + end) + + if not success then + print_error("CE give perk error: " .. tostring(result)) + end + end + end + + imgui.PopID() + end + end + + imgui.EndTable() + end + + imgui.EndChild() +end diff --git a/component-explorer/spawn_stuff/spells.lua b/component-explorer/spawn_stuff/spells.lua new file mode 100644 index 0000000..46eae50 --- /dev/null +++ b/component-explorer/spawn_stuff/spells.lua @@ -0,0 +1,173 @@ +---@module 'component-explorer.utils.strings' +local string_util = dofile_once("mods/component-explorer/utils/strings.lua") + +---@module 'component-explorer.ui.ui_combo' +local ui_combo = dofile_once("mods/component-explorer/ui/ui_combo.lua") + +---@module 'component-explorer.utils.player_util' +local player_util = dofile_once("mods/component-explorer/utils/player_util.lua") + +---@module 'component-explorer.spawn_data.actions' +local actions_data = dofile_once("mods/component-explorer/spawn_data/actions.lua") +local actions = actions_data.actions +local unique_action_types = actions_data.unique_action_types +local action_type_to_name = actions_data.action_type_to_name + +local function get_unique_attrs(attr) + local set = {} + for _, action in ipairs(actions) do + set[action[attr]] = true + end + + local ret = {} + for item, _ in pairs(set) do + table.insert(ret, item) + end + + table.sort(ret) + return ret +end +local unique_origins = get_unique_attrs("origin") + +local filter_search = "" +---@type string? +local filter_origin = nil +---@type string? +local filter_action_type = nil + +return function() + local _ + + imgui.SetNextItemWidth(200) + _, filter_search = imgui.InputText("Search", filter_search) + + imgui.SameLine() + imgui.SetNextItemWidth(150) + _, filter_action_type = ui_combo.optional("Type", unique_action_types, filter_action_type) + + if #unique_origins > 1 then + imgui.SameLine() + imgui.SetNextItemWidth(150) + _, filter_origin = ui_combo.optional("Origin", unique_origins, filter_origin) + end + + local filtered_actions + if filter_search == "" and filter_origin == nil and filter_action_type == nil then + filtered_actions = actions + else + filtered_actions = {} + for _, action in ipairs(actions) do + if + (filter_search == "" or ( + string_util.ifind(action.id, filter_search, 1, true) or + string_util.ifind(action.display_name, filter_search, 1, true) or + string_util.ifind(action.display_description, filter_search, 1, true) + )) + and (filter_origin == nil or action.origin == filter_origin) + and (filter_action_type == nil or action_type_to_name(action.type) == filter_action_type) + then + table.insert(filtered_actions, action) + end + end + end + + if not imgui.BeginChild("table") then return end + + local column_count = 5 + + local has_image_support = imgui.LoadImage ~= nil + if has_image_support then + column_count = column_count + 1 + end + + local flags = bit.bor( + imgui.TableFlags.Resizable, + imgui.TableFlags.Hideable, + imgui.TableFlags.RowBg + ) + + if imgui.BeginTable("spells", column_count, flags) then + if has_image_support then + imgui.TableSetupColumn("img", imgui.TableColumnFlags.WidthFixed) + end + imgui.TableSetupColumn("Name") + imgui.TableSetupColumn("ID") + imgui.TableSetupColumn("Type", imgui.TableColumnFlags.WidthFixed) + imgui.TableSetupColumn("Origin", imgui.TableColumnFlags.WidthFixed) + imgui.TableSetupColumn("Spawn", imgui.TableColumnFlags.WidthFixed) + imgui.TableHeadersRow() + + if has_image_support then + local image_paths = {} + for _, p in ipairs(actions) do + if p.sprite then + table.insert(image_paths, p.sprite) + end + end + -- Files are placed alphabetically in the data.wak, loading them in + -- that order is much faster. + table.sort(image_paths) + for _, path in ipairs(image_paths) do + imgui.LoadImage(path) + end + end + + local clipper = imgui.ListClipper.new() + clipper:Begin(#filtered_actions) + + while clipper:Step() do + for i=clipper.DisplayStart,clipper.DisplayEnd - 1 do + local action = filtered_actions[i + 1] + imgui.PushID(action.id) + + if has_image_support then + imgui.TableNextColumn() + if action.sprite then + local img = imgui.LoadImage(action.sprite) + if img then + local style = imgui.GetStyle() + local image_size = imgui.GetTextLineHeight() + style.CellPadding_y * 2 + imgui.Image(img, image_size, image_size) + end + end + end + + imgui.TableNextColumn() + imgui.Text(action.display_name) + + imgui.TableNextColumn() + imgui.Text(action.id) + + imgui.TableNextColumn() + imgui.Text(action_type_to_name(action.type)) + + imgui.TableNextColumn() + imgui.Text(action.origin) + if #unique_origins > 1 and imgui.IsItemHovered() and imgui.IsMouseReleased(imgui.MouseButton.Right) then + filter_origin = action.origin + end + + imgui.TableNextColumn() + if imgui.SmallButton("Spawn") then + local player = player_util.get_player() + if player then + local success, result = pcall(function() + local x, y = EntityGetTransform(player) + CreateItemActionEntity(action.id, x, y) + end) + + if not success then + print_error("CE give action error: " .. tostring(result)) + end + end + end + + imgui.PopID() + end + end + + imgui.EndTable() + end + + imgui.EndChild() +end diff --git a/component-explorer/ui/ui_combo.lua b/component-explorer/ui/ui_combo.lua new file mode 100644 index 0000000..e5b40fa --- /dev/null +++ b/component-explorer/ui/ui_combo.lua @@ -0,0 +1,31 @@ +local ui_combo = {} + +---Combo list with an --All-- option that corresponds to nil. +---@param label string +---@param list string[] +---@param value string? +---@param default_name string? +---@return boolean +---@return string? +function ui_combo.optional(label, list, value, default_name) + default_name = default_name or "--All--" + local changed = false + if imgui.BeginCombo(label, value or default_name) then + if imgui.Selectable(default_name, value == nil) then + changed = true + value = nil + end + + for _, item in ipairs(list) do + if imgui.Selectable(item, value == item) then + changed = true + value = item + end + end + imgui.EndCombo() + end + + return changed, value +end + +return ui_combo diff --git a/component-explorer/utils/file_util.lua b/component-explorer/utils/file_util.lua new file mode 100644 index 0000000..679e517 --- /dev/null +++ b/component-explorer/utils/file_util.lua @@ -0,0 +1,61 @@ +local file_util = {} + +local ModDoesFileExist = ModDoesFileExist +local GuiGetImageDimensions = GuiGetImageDimensions +local ModTextFileGetContent = ModTextFileGetContent + +local exists_cache = {} + +if ModDoesFileExist then + ---@param path string + ---@return boolean + local function caching_does_file_exist(path) + local cached = exists_cache[path] + if cached ~= nil then + return cached + end + + local exists = ModDoesFileExist(path) + exists_cache[path] = exists + return exists + end + + file_util.image_file_exists = caching_does_file_exist + file_util.text_file_exists = caching_does_file_exist +else + local gui = GuiCreate() + ---@param path string + ---@return boolean + function file_util.image_file_exists(path) + local cached = exists_cache[path] + if cached ~= nil then + return cached + end + + GuiStartFrame(gui) + local w = GuiGetImageDimensions(gui, path) + local exists = w ~= 0 + + exists_cache[path] = exists + return exists + end + + ---@param path string + ---@return boolean + function file_util.text_file_exists(path) + local cached = exists_cache[path] + if cached ~= nil then + return cached + end + + local content = ModTextFileGetContent(path) + local exists = content ~= nil and content ~= "" + + exists_cache[path] = exists + return exists + end +end + +file_util.ModTextFileGetContent = ModTextFileGetContent + +return file_util