From 09896640359e20080ab5cc1883dcbd7928b7fb8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Hoguin?= Date: Sun, 13 Feb 2011 18:00:58 +0100 Subject: [PATCH] Cleanup area loading code. Remove myroom, mission and spaceport support. --- Makefile | 7 +- include/maps.hrl | 726 ----------------------------------------- include/missions.hrl | 4 - include/records.hrl | 2 +- src/egs_files.erl | 3 +- src/egs_quests_db.erl | 143 ++++---- src/psu/psu_game.erl | 156 ++------- src/psu/psu_parser.erl | 386 ---------------------- 8 files changed, 106 insertions(+), 1321 deletions(-) delete mode 100644 include/maps.hrl delete mode 100644 include/missions.hrl delete mode 100644 src/psu/psu_parser.erl diff --git a/Makefile b/Makefile index ff7e0f3..6f9fbd1 100644 --- a/Makefile +++ b/Makefile @@ -16,16 +16,11 @@ # You should have received a copy of the GNU Affero General Public License # along with EGS. If not, see . -all: clean missions server +all: server server: @./rebar compile -missions: - erlc src/psu/psu_parser.erl - erl -noshell -noinput -sname missions -pa ebin -run psu_parser run -run init stop - rm psu_parser.beam - clean: @./rebar clean rm -f erl_crash.dump diff --git a/include/maps.hrl b/include/maps.hrl deleted file mode 100644 index feea442..0000000 --- a/include/maps.hrl +++ /dev/null @@ -1,726 +0,0 @@ -%% @author Loïc Hoguin -%% @copyright 2010 Loïc Hoguin. -%% @doc Quests, zones, maps and counters definitions. -%% -%% This file is part of EGS. -%% -%% EGS is free software: you can redistribute it and/or modify -%% it under the terms of the GNU Affero General Public License as -%% published by the Free Software Foundation, either version 3 of the -%% License, or (at your option) any later version. -%% -%% EGS is distributed in the hope that it will be useful, -%% but WITHOUT ANY WARRANTY; without even the implied warranty of -%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -%% GNU Affero General Public License for more details. -%% -%% You should have received a copy of the GNU Affero General Public License -%% along with EGS. If not, see . - -%% EGS maps settings. - --define(QUESTS, [ - % Unsafe Passage - - {1000000, [{type, mission}, {file, "data/missions/unsafe-passage.1.c.quest.nbl"}, {start, [0, 1120, 0]}, {sets, 4}]}, - {1000001, [{type, mission}, {file, "data/missions/unsafe-passage.1.b.quest.nbl"}, {start, [0, 1120, 0]}, {sets, 4}]}, - {1000002, [{type, mission}, {file, "data/missions/unsafe-passage.1.a.quest.nbl"}, {start, [0, 1120, 0]}, {sets, 4}]}, - {1000003, [{type, mission}, {file, "data/missions/unsafe-passage.1.s.quest.nbl"}, {start, [0, 1120, 0]}, {sets, 4}]}, - {1000004, [{type, mission}, {file, "data/missions/unsafe-passage.1.s2.quest.nbl"}, {start, [0, 1120, 0]}, {sets, 4}]}, - - {1000010, [{type, mission}, {file, "data/missions/unsafe-passage.2.c.quest.nbl"}, {start, [0, 1121, 0]}, {sets, 4}]}, - {1000011, [{type, mission}, {file, "data/missions/unsafe-passage.2.b.quest.nbl"}, {start, [0, 1121, 0]}, {sets, 4}]}, - {1000012, [{type, mission}, {file, "data/missions/unsafe-passage.2.a.quest.nbl"}, {start, [0, 1121, 0]}, {sets, 4}]}, - {1000013, [{type, mission}, {file, "data/missions/unsafe-passage.2.s.quest.nbl"}, {start, [0, 1121, 0]}, {sets, 4}]}, - {1000014, [{type, mission}, {file, "data/missions/unsafe-passage.2.s2.quest.nbl"}, {start, [0, 1121, 0]}, {sets, 4}]}, - - {1000020, [{type, mission}, {file, "data/missions/unsafe-passage.3.c.quest.nbl"}, {start, [0, 1200, 0]}, {sets, 4}]}, - {1000021, [{type, mission}, {file, "data/missions/unsafe-passage.3.b.quest.nbl"}, {start, [0, 1200, 0]}, {sets, 4}]}, - {1000022, [{type, mission}, {file, "data/missions/unsafe-passage.3.a.quest.nbl"}, {start, [0, 1200, 0]}, {sets, 4}]}, - {1000023, [{type, mission}, {file, "data/missions/unsafe-passage.3.s.quest.nbl"}, {start, [0, 1200, 0]}, {sets, 4}]}, - {1000024, [{type, mission}, {file, "data/missions/unsafe-passage.3.s2.quest.nbl"}, {start, [0, 1200, 0]}, {sets, 4}]}, - - % Fight for Food - - {1000100, [{type, mission}, {file, "data/missions/fight-for-food.1.c.quest.nbl"}, {start, [0, 1200, 0]}, {sets, 4}]}, - {1000101, [{type, mission}, {file, "data/missions/fight-for-food.1.b.quest.nbl"}, {start, [0, 1200, 0]}, {sets, 4}]}, - %~ {1000102, [{type, mission}, {file, "data/missions/fight-for-food.1.a.quest.nbl"}, {start, [0, 1200, 0]}, {sets, 4}]}, - %~ {1000103, [{type, mission}, {file, "data/missions/fight-for-food.1.s.quest.nbl"}, {start, [0, 1200, 0]}, {sets, 4}]}, - {1000104, [{type, mission}, {file, "data/missions/fight-for-food.1.s2.quest.nbl"}, {start, [0, 1200, 0]}, {sets, 4}]}, - - {1000110, [{type, mission}, {file, "data/missions/fight-for-food.2.c.quest.nbl"}, {start, [0, 1301, 0]}, {sets, 4}]}, - %~ {1000111, [{type, mission}, {file, "data/missions/fight-for-food.2.b.quest.nbl"}, {start, [0, 1301, 0]}, {sets, 4}]}, - %~ {1000112, [{type, mission}, {file, "data/missions/fight-for-food.2.a.quest.nbl"}, {start, [0, 1301, 0]}, {sets, 4}]}, - %~ {1000113, [{type, mission}, {file, "data/missions/fight-for-food.2.s.quest.nbl"}, {start, [0, 1301, 0]}, {sets, 4}]}, - {1000114, [{type, mission}, {file, "data/missions/fight-for-food.2.s2.quest.nbl"}, {start, [0, 1301, 0]}, {sets, 4}]}, - - {1000120, [{type, mission}, {file, "data/missions/fight-for-food.3.c.quest.nbl"}, {start, [0, 1301, 0]}, {sets, 4}]}, - %~ {1000121, [{type, mission}, {file, "data/missions/fight-for-food.3.b.quest.nbl"}, {start, [0, 1301, 0]}, {sets, 4}]}, - {1000122, [{type, mission}, {file, "data/missions/fight-for-food.3.a.quest.nbl"}, {start, [0, 1301, 0]}, {sets, 4}]}, - %~ {1000123, [{type, mission}, {file, "data/missions/fight-for-food.3.s.quest.nbl"}, {start, [0, 1301, 0]}, {sets, 4}]}, - {1000124, [{type, mission}, {file, "data/missions/fight-for-food.3.s2.quest.nbl"}, {start, [0, 1301, 0]}, {sets, 4}]}, - - % Dark Satellite - - {1001000, [{type, mission}, {file, "data/missions/dark-satellite.1.c.quest.nbl"}, {start, [0, 101, 0]}, {sets, 4}]}, - {1001001, [{type, mission}, {file, "data/missions/dark-satellite.1.b.quest.nbl"}, {start, [0, 101, 0]}, {sets, 4}]}, - {1001002, [{type, mission}, {file, "data/missions/dark-satellite.1.a.quest.nbl"}, {start, [0, 101, 0]}, {sets, 4}]}, - %~ {1001003, [{type, mission}, {file, "data/missions/dark-satellite.1.s.quest.nbl"}, {start, [0, 101, 0]}, {sets, 4}]}, - {1001004, [{type, mission}, {file, "data/missions/dark-satellite.1.s2.quest.nbl"}, {start, [0, 101, 0]}, {sets, 4}]}, - {1001005, [{type, mission}, {file, "data/missions/dark-satellite.1.s3.quest.nbl"}, {start, [0, 101, 0]}, {sets, 4}]}, - - {1001010, [{type, mission}, {file, "data/missions/dark-satellite.2.c.quest.nbl"}, {start, [0, 102, 0]}, {sets, 4}]}, - {1001011, [{type, mission}, {file, "data/missions/dark-satellite.2.b.quest.nbl"}, {start, [0, 102, 0]}, {sets, 4}]}, - {1001012, [{type, mission}, {file, "data/missions/dark-satellite.2.a.quest.nbl"}, {start, [0, 102, 0]}, {sets, 4}]}, - {1001013, [{type, mission}, {file, "data/missions/dark-satellite.2.s.quest.nbl"}, {start, [0, 102, 0]}, {sets, 4}]}, - %~ {1001014, [{type, mission}, {file, "data/missions/dark-satellite.2.s2.quest.nbl"}, {start, [0, 102, 0]}, {sets, 4}]}, - %~ {1001015, [{type, mission}, {file, "data/missions/dark-satellite.2.s3.quest.nbl"}, {start, [0, 102, 0]}, {sets, 4}]}, - - {1001020, [{type, mission}, {file, "data/missions/dark-satellite.3.c.quest.nbl"}, {start, [0, 103, 0]}, {sets, 4}]}, - %~ {1001021, [{type, mission}, {file, "data/missions/dark-satellite.3.b.quest.nbl"}, {start, [0, 103, 0]}, {sets, 4}]}, - {1001022, [{type, mission}, {file, "data/missions/dark-satellite.3.a.quest.nbl"}, {start, [0, 103, 0]}, {sets, 4}]}, - %~ {1001023, [{type, mission}, {file, "data/missions/dark-satellite.3.s.quest.nbl"}, {start, [0, 103, 0]}, {sets, 4}]}, - {1001024, [{type, mission}, {file, "data/missions/dark-satellite.3.s2.quest.nbl"}, {start, [0, 103, 0]}, {sets, 4}]}, - {1001025, [{type, mission}, {file, "data/missions/dark-satellite.3.s3.quest.nbl"}, {start, [0, 103, 0]}, {sets, 4}]}, - - % Seed Awakening - - %~ {1001100, [{type, mission}, {file, "data/missions/seed-awakening.1.c.quest.nbl"}, {start, [0, 130, 0]}, {sets, 4}]}, - {1001101, [{type, mission}, {file, "data/missions/seed-awakening.1.b.quest.nbl"}, {start, [0, 130, 0]}, {sets, 4}]}, - {1001102, [{type, mission}, {file, "data/missions/seed-awakening.1.a.quest.nbl"}, {start, [0, 130, 0]}, {sets, 4}]}, - {1001103, [{type, mission}, {file, "data/missions/seed-awakening.1.s.quest.nbl"}, {start, [0, 130, 0]}, {sets, 4}]}, - {1001104, [{type, mission}, {file, "data/missions/seed-awakening.1.s2.quest.nbl"}, {start, [0, 130, 0]}, {sets, 4}]}, - {1001105, [{type, mission}, {file, "data/missions/seed-awakening.1.s3.quest.nbl"}, {start, [0, 130, 0]}, {sets, 4}]}, - - {1001110, [{type, mission}, {file, "data/missions/seed-awakening.2.c.quest.nbl"}, {start, [0, 112, 0]}, {sets, 4}]}, - {1001111, [{type, mission}, {file, "data/missions/seed-awakening.2.b.quest.nbl"}, {start, [0, 112, 0]}, {sets, 4}]}, - {1001112, [{type, mission}, {file, "data/missions/seed-awakening.2.a.quest.nbl"}, {start, [0, 112, 0]}, {sets, 4}]}, - %~ {1001113, [{type, mission}, {file, "data/missions/seed-awakening.2.s.quest.nbl"}, {start, [0, 112, 0]}, {sets, 4}]}, - {1001114, [{type, mission}, {file, "data/missions/seed-awakening.2.s2.quest.nbl"}, {start, [0, 112, 0]}, {sets, 4}]}, - {1001115, [{type, mission}, {file, "data/missions/seed-awakening.2.s3.quest.nbl"}, {start, [0, 112, 0]}, {sets, 4}]}, - - {1001120, [{type, mission}, {file, "data/missions/seed-awakening.3.c.quest.nbl"}, {start, [0, 113, 0]}, {sets, 4}]}, - %~ {1001121, [{type, mission}, {file, "data/missions/seed-awakening.3.b.quest.nbl"}, {start, [0, 113, 0]}, {sets, 4}]}, - %~ {1001122, [{type, mission}, {file, "data/missions/seed-awakening.3.a.quest.nbl"}, {start, [0, 113, 0]}, {sets, 4}]}, - %~ {1001123, [{type, mission}, {file, "data/missions/seed-awakening.3.s.quest.nbl"}, {start, [0, 113, 0]}, {sets, 4}]}, - {1001124, [{type, mission}, {file, "data/missions/seed-awakening.3.s2.quest.nbl"}, {start, [0, 113, 0]}, {sets, 4}]}, - {1001125, [{type, mission}, {file, "data/missions/seed-awakening.3.s3.quest.nbl"}, {start, [0, 113, 0]}, {sets, 4}]}, - - % True Darkness - - %~ {1001200, [{type, mission}, {file, "data/missions/true-darkness.1.c.quest.nbl"}, {start, [0, 130, 0]}, {sets, 4}]}, - %~ {1001201, [{type, mission}, {file, "data/missions/true-darkness.1.b.quest.nbl"}, {start, [0, 130, 0]}, {sets, 4}]}, - %~ {1001202, [{type, mission}, {file, "data/missions/true-darkness.1.a.quest.nbl"}, {start, [0, 130, 0]}, {sets, 4}]}, - %~ {1001203, [{type, mission}, {file, "data/missions/true-darkness.1.s.quest.nbl"}, {start, [0, 130, 0]}, {sets, 4}]}, - %~ {1001204, [{type, mission}, {file, "data/missions/true-darkness.1.s2.quest.nbl"}, {start, [0, 130, 0]}, {sets, 4}]}, - - {1001210, [{type, mission}, {file, "data/missions/true-darkness.2.c.quest.nbl"}, {start, [0, 131, 0]}, {sets, 4}]}, - %~ {1001211, [{type, mission}, {file, "data/missions/true-darkness.2.b.quest.nbl"}, {start, [0, 131, 0]}, {sets, 4}]}, - {1001212, [{type, mission}, {file, "data/missions/true-darkness.2.a.quest.nbl"}, {start, [0, 131, 0]}, {sets, 4}]}, - {1001213, [{type, mission}, {file, "data/missions/true-darkness.2.s.quest.nbl"}, {start, [0, 131, 0]}, {sets, 4}]}, - %~ {1001214, [{type, mission}, {file, "data/missions/true-darkness.2.s2.quest.nbl"}, {start, [0, 131, 0]}, {sets, 4}]}, - - {1001220, [{type, mission}, {file, "data/missions/true-darkness.3.c.quest.nbl"}, {start, [0, 802, 0]}, {sets, 4}]}, - {1001221, [{type, mission}, {file, "data/missions/true-darkness.3.b.quest.nbl"}, {start, [0, 802, 0]}, {sets, 4}]}, - {1001222, [{type, mission}, {file, "data/missions/true-darkness.3.a.quest.nbl"}, {start, [0, 802, 0]}, {sets, 4}]}, - %~ {1001223, [{type, mission}, {file, "data/missions/true-darkness.3.s.quest.nbl"}, {start, [0, 802, 0]}, {sets, 4}]}, - {1001224, [{type, mission}, {file, "data/missions/true-darkness.3.s2.quest.nbl"}, {start, [0, 802, 0]}, {sets, 4}]}, - - % The Black Nest - - {1003000, [{type, mission}, {file, "data/missions/black-nest.1.c.quest.nbl"}, {start, [0, 6301, 0]}, {sets, 4}]}, - {1003001, [{type, mission}, {file, "data/missions/black-nest.1.b.quest.nbl"}, {start, [0, 6301, 0]}, {sets, 4}]}, - {1003002, [{type, mission}, {file, "data/missions/black-nest.1.a.quest.nbl"}, {start, [0, 6301, 0]}, {sets, 4}]}, - {1003003, [{type, mission}, {file, "data/missions/black-nest.1.s.quest.nbl"}, {start, [0, 6301, 0]}, {sets, 4}]}, - {1003004, [{type, mission}, {file, "data/missions/black-nest.1.s2.quest.nbl"}, {start, [0, 6301, 0]}, {sets, 4}]}, - - {1003010, [{type, mission}, {file, "data/missions/black-nest.2.c.quest.nbl"}, {start, [0, 6303, 0]}, {sets, 4}]}, - %~ {1003011, [{type, mission}, {file, "data/missions/black-nest.2.b.quest.nbl"}, {start, [0, 6303, 0]}, {sets, 4}]}, - %~ {1003012, [{type, mission}, {file, "data/missions/black-nest.2.a.quest.nbl"}, {start, [0, 6303, 0]}, {sets, 4}]}, - %~ {1003013, [{type, mission}, {file, "data/missions/black-nest.2.s.quest.nbl"}, {start, [0, 6303, 0]}, {sets, 4}]}, - {1003014, [{type, mission}, {file, "data/missions/black-nest.2.s2.quest.nbl"}, {start, [0, 6303, 0]}, {sets, 4}]}, - - {1003020, [{type, mission}, {file, "data/missions/black-nest.3.c.quest.nbl"}, {start, [0, 6803, 0]}, {sets, 4}]}, - {1003021, [{type, mission}, {file, "data/missions/black-nest.3.b.quest.nbl"}, {start, [0, 6803, 0]}, {sets, 4}]}, - %~ {1003022, [{type, mission}, {file, "data/missions/black-nest.3.a.quest.nbl"}, {start, [0, 6803, 0]}, {sets, 4}]}, - {1003023, [{type, mission}, {file, "data/missions/black-nest.3.s.quest.nbl"}, {start, [0, 6803, 0]}, {sets, 4}]}, - %~ {1003024, [{type, mission}, {file, "data/missions/black-nest.3.s2.quest.nbl"}, {start, [0, 6803, 0]}, {sets, 4}]}, - - % The Dark God - - {1003100, [{type, mission}, {file, "data/missions/dark-god.1.c.quest.nbl"}, {start, [0, 6302, 0]}, {sets, 4}]}, - %~ {1003101, [{type, mission}, {file, "data/missions/dark-god.1.b.quest.nbl"}, {start, [0, 6302, 0]}, {sets, 4}]}, - {1003102, [{type, mission}, {file, "data/missions/dark-god.1.a.quest.nbl"}, {start, [0, 6302, 0]}, {sets, 4}]}, - {1003103, [{type, mission}, {file, "data/missions/dark-god.1.s.quest.nbl"}, {start, [0, 6302, 0]}, {sets, 4}]}, - {1003104, [{type, mission}, {file, "data/missions/dark-god.1.s2.quest.nbl"}, {start, [0, 6302, 0]}, {sets, 4}]}, - - {1003110, [{type, mission}, {file, "data/missions/dark-god.2.c.quest.nbl"}, {start, [0, 6304, 0]}, {sets, 4}]}, - {1003111, [{type, mission}, {file, "data/missions/dark-god.2.b.quest.nbl"}, {start, [0, 6304, 0]}, {sets, 4}]}, - {1003112, [{type, mission}, {file, "data/missions/dark-god.2.a.quest.nbl"}, {start, [0, 6304, 0]}, {sets, 4}]}, - {1003113, [{type, mission}, {file, "data/missions/dark-god.2.s.quest.nbl"}, {start, [0, 6304, 0]}, {sets, 4}]}, - {1003114, [{type, mission}, {file, "data/missions/dark-god.2.s2.quest.nbl"}, {start, [0, 6304, 0]}, {sets, 4}]}, - - {1003120, [{type, mission}, {file, "data/missions/dark-god.3.c.quest.nbl"}, {start, [0, 6302, 0]}, {sets, 4}]}, - {1003121, [{type, mission}, {file, "data/missions/dark-god.3.b.quest.nbl"}, {start, [0, 6302, 0]}, {sets, 4}]}, - {1003122, [{type, mission}, {file, "data/missions/dark-god.3.a.quest.nbl"}, {start, [0, 6302, 0]}, {sets, 4}]}, - {1003123, [{type, mission}, {file, "data/missions/dark-god.3.s.quest.nbl"}, {start, [0, 6302, 0]}, {sets, 4}]}, - {1003124, [{type, mission}, {file, "data/missions/dark-god.3.s2.quest.nbl"}, {start, [0, 6302, 0]}, {sets, 4}]}, - - % Phantom Ruins (Linear Line counter) - - %~ {1060300, [{type, mission}, {file, "data/missions/phantom-ruins.c.quest.nbl"}, {start, [0, 8002, 0]}, {sets, 3}]}, - {1060301, [{type, mission}, {file, "data/missions/phantom-ruins.b.quest.nbl"}, {start, [0, 8002, 0]}, {sets, 3}]}, - %~ {1060302, [{type, mission}, {file, "data/missions/phantom-ruins.a.quest.nbl"}, {start, [0, 8002, 0]}, {sets, 3}]}, - {1060303, [{type, mission}, {file, "data/missions/phantom-ruins.s.quest.nbl"}, {start, [0, 8002, 0]}, {sets, 3}]}, - - % Photon Eraser Return - - %~ {1070080, [{type, mission}, {file, "data/missions/photon-eraser-return.quest.nbl"}, {start, [0, 300, 0]}, {sets, 1}]}, - - % Dark Crystal Seeker - - {1070742, [{type, mission}, {file, "data/missions/dark-crystal-seeker.quest.nbl"}, {start, [0, 1002, 0]}, {sets, 1}]}, - - % MAG' - - {1072100, [{type, mission}, {file, "data/missions/mag-prime.c.quest.nbl"}, {start, [1, 5000, 0]}, {sets, 2}]}, - {1072101, [{type, mission}, {file, "data/missions/mag-prime.b.quest.nbl"}, {start, [1, 5000, 0]}, {sets, 2}]}, - {1072102, [{type, mission}, {file, "data/missions/mag-prime.a.quest.nbl"}, {start, [1, 5000, 0]}, {sets, 2}]}, - {1072103, [{type, mission}, {file, "data/missions/mag-prime.s.quest.nbl"}, {start, [1, 5000, 0]}, {sets, 2}]}, - {1072104, [{type, mission}, {file, "data/missions/mag-prime.s2.quest.nbl"}, {start, [1, 5000, 0]}, {sets, 2}]}, - - % Gifts from Beyond - - {1072300, [{type, mission}, {file, "data/missions/gifts-from-beyond-plus.quest.nbl"}, {start, [0, 300, 0]}, {sets, 1}]}, - - % Airboard Rally - - {1090700, [{type, mission}, {file, "data/missions/airboard-rally.quest.nbl"}, {start, [0, 800, 0]}, {sets, 1}]}, - - % Planetary lobbies - - {1100000, [{type, lobby}, {file, nofile}]}, - {1101000, [{type, lobby}, {file, nofile}]}, - {1102000, [{type, lobby}, {file, nofile}]}, - {1103000, [{type, lobby}, {file, nofile}]}, - - {1104000, [{type, spaceport}, {file, nofile}]}, - - % Tutorial - - {1106000, [{type, lobby}, {file, "data/tutorial/lobby.quest.nbl"}]}, - - % SEED-Form Purge - - {1113000, [{type, mission}, {file, "data/tutorial/seed-form-purge.hyuga.quest.nbl"}, {start, [0, 1121, 0]}, {sets, 1}]}, - {1113001, [{type, mission}, {file, "data/tutorial/seed-form-purge.maya.quest.nbl"}, {start, [0, 1121, 0]}, {sets, 1}]}, - {1113002, [{type, mission}, {file, "data/tutorial/seed-form-purge.lou.quest.nbl"}, {start, [0, 1121, 0]}, {sets, 1}]}, - {1113003, [{type, mission}, {file, "data/tutorial/seed-form-purge.leo.quest.nbl"}, {start, [0, 1121, 0]}, {sets, 1}]}, - - % My room - - {1120000, [{type, myroom}, {file, "data/rooms/test.quest.nbl"}]}, - - % Story Episode 2 - - {1131010, [{type, mission}, {file, "data/missions/ep2ch1.c.quest.nbl"}, {start, [0, 0, 0]}, {sets, 1}]}, - - %% Boss Tests. - {90120, [{type, mission}, {file, "data/missions/boss/lv1/alteraz/quest_ae.nbl"}, {start, [0, 100, 0]}, {sets, 1}]}, - {90130, [{type, mission}, {file, "data/missions/boss/lv1/rolei/quest_ae.nbl"}, {start, [0, 100, 0]}, {sets, 1}]}, - {90140, [{type, mission}, {file, "data/missions/boss/lv1/motherbrain/quest_ae.nbl"}, {start, [0, 100, 0]}, {sets, 1}]}, - {90150, [{type, mission}, {file, "data/missions/boss/lv1/falz1/quest_ae.nbl"}, {start, [0, 100, 0]}, {sets, 1}]}, - {90160, [{type, mission}, {file, "data/missions/boss/lv1/falz2/quest_ae.nbl"}, {start, [0, 100, 0]}, {sets, 1}]}, - - %% v1 Free Missions. - {110000, [{type, mission}, {file, "data/missions/v1/evacuation/quest_ae.nbl"}, {start, [0, 1130, 0]}, {sets, 1}]}, - {110010, [{type, mission}, {file, "data/missions/v1/annihilation/quest_ae.nbl"}, {start, [0, 1300, 0]}, {sets, 1}]}, - {110100, [{type, mission}, {file, "data/missions/v1/dark-satellite/quest_ae.nbl"}, {start, [0, 111, 0]}, {sets, 1}]}, - {111000, [{type, mission}, {file, "data/missions/v1/creature-discomfort/quest_ae.nbl"}, {start, [0, 101, 0]}, {sets, 1}]}, - {111010, [{type, mission}, {file, "data/missions/v1/burning-plains/quest_ae.nbl"}, {start, [0, 1120, 0]}, {sets, 1}]}, - {111020, [{type, mission}, {file, "data/missions/v1/mad-beasts/quest_ae.nbl"}, {start, [0, 1130, 0]}, {sets, 1}]}, - {111030, [{type, mission}, {file, "data/missions/v1/ruler-of-the-plains/quest_ae.nbl"}, {start, [0, 110, 0]}, {sets, 1}]}, - {111100, [{type, mission}, {file, "data/missions/v1/what-is-in-the-ruins/quest_ae.nbl"}, {start, [0, 1102, 0]}, {sets, 1}]}, - {111110, [{type, mission}, {file, "data/missions/v1/two-headed-sentinel/quest_ae.nbl"}, {start, [0, 1211, 0]}, {sets, 1}]}, - {111200, [{type, mission}, {file, "data/missions/v1/cargo-train-rescue/quest_ae.nbl"}, {start, [0, 105, 3]}, {sets, 1}]}, - {111300, [{type, mission}, {file, "data/missions/v1/endrum-underground/quest_ae.nbl"}, {start, [0, 110, 0]}, {sets, 1}]}, - {112000, [{type, mission}, {file, "data/missions/v1/mizuraki-devastation/quest_ae.nbl"}, {start, [0, 101, 0]}, {sets, 1}]}, - {112010, [{type, mission}, {file, "data/missions/v1/frozen-woods/quest_ae.nbl"}, {start, [0, 1111, 0]}, {sets, 1}]}, - {112020, [{type, mission}, {file, "data/missions/v1/demons-above/quest_ae.nbl"}, {start, [0, 3115, 0]}, {sets, 1}]}, - {112100, [{type, mission}, {file, "data/missions/v1/defend-islands/quest_ae.nbl"}, {start, [0, 3120, 0]}, {sets, 1}]}, - {112120, [{type, mission}, {file, "data/missions/v1/woodland-flames/quest_ae.nbl"}, {start, [0, 1220, 0]}, {sets, 1}]}, - {112200, [{type, mission}, {file, "data/missions/v1/grove-of-fanatics/quest_ae.nbl"}, {start, [0, 104, 0]}, {sets, 1}]}, - {112210, [{type, mission}, {file, "data/missions/v1/temple-of-ice/quest_ae.nbl"}, {start, [0, 1201, 0]}, {sets, 1}]}, - {113000, [{type, mission}, {file, "data/missions/v1/pandemonium/quest_ae.nbl"}, {start, [0, 3110, 0]}, {sets, 1}]}, - {113100, [{type, mission}, {file, "data/missions/v1/tunnel-infestation/quest_ae.nbl"}, {start, [0, 210, 0]}, {sets, 1}]}, - {113200, [{type, mission}, {file, "data/missions/v1/goliath-in-the-desert/quest_ae.nbl"}, {start, [0, 3120, 0]}, {sets, 1}]}, - {113230, [{type, mission}, {file, "data/missions/v1/absolute-zero/quest_ae.nbl"}, {start, [0, 1221, 0]}, {sets, 1}]}, - {113240, [{type, mission}, {file, "data/missions/v1/terror-in-the-desert/quest_ae.nbl"}, {start, [0, 4240, 0]}, {sets, 1}]} -]). - --define(ZONES, [ - % Unsafe Passage - - {[1000000, 0], [{file, "data/missions/unsafe-passage.1.c.zone.nbl"}, {sets, 4}]}, - {[1000001, 0], [{file, "data/missions/unsafe-passage.1.b.zone.nbl"}, {sets, 4}]}, - {[1000002, 0], [{file, "data/missions/unsafe-passage.1.a.zone.nbl"}, {sets, 4}]}, - {[1000003, 0], [{file, "data/missions/unsafe-passage.1.s.zone.nbl"}, {sets, 4}]}, - {[1000004, 0], [{file, "data/missions/unsafe-passage.1.s2.zone.nbl"}, {sets, 4}]}, - - {[1000010, 0], [{file, "data/missions/unsafe-passage.2.c.zone.nbl"}, {sets, 4}]}, - {[1000011, 0], [{file, "data/missions/unsafe-passage.2.b.zone.nbl"}, {sets, 4}]}, - {[1000012, 0], [{file, "data/missions/unsafe-passage.2.a.zone.nbl"}, {sets, 4}]}, - {[1000013, 0], [{file, "data/missions/unsafe-passage.2.s.zone.nbl"}, {sets, 4}]}, - {[1000014, 0], [{file, "data/missions/unsafe-passage.2.s2.zone.nbl"}, {sets, 4}]}, - - {[1000020, 0], [{file, "data/missions/unsafe-passage.3.c.zone.nbl"}, {sets, 4}]}, - {[1000021, 0], [{file, "data/missions/unsafe-passage.3.b.zone.nbl"}, {sets, 4}]}, - {[1000022, 0], [{file, "data/missions/unsafe-passage.3.a.zone.nbl"}, {sets, 4}]}, - {[1000023, 0], [{file, "data/missions/unsafe-passage.3.s.zone.nbl"}, {sets, 4}]}, - {[1000024, 0], [{file, "data/missions/unsafe-passage.3.s2.zone.nbl"}, {sets, 4}]}, - - % Fight for Food - - {[1000100, 0], [{file, "data/missions/fight-for-food.1.c.zone.nbl"}, {sets, 4}]}, - {[1000101, 0], [{file, "data/missions/fight-for-food.1.b.zone.nbl"}, {sets, 4}]}, - %~ {[1000102, 0], [{file, "data/missions/fight-for-food.1.a.zone.nbl"}, {sets, 4}]}, - %~ {[1000103, 0], [{file, "data/missions/fight-for-food.1.s.zone.nbl"}, {sets, 4}]}, - {[1000104, 0], [{file, "data/missions/fight-for-food.1.s2.zone.nbl"}, {sets, 4}]}, - - {[1000110, 0], [{file, "data/missions/fight-for-food.2.c.zone.nbl"}, {sets, 4}]}, - %~ {[1000111, 0], [{file, "data/missions/fight-for-food.2.b.zone.nbl"}, {sets, 4}]}, - %~ {[1000112, 0], [{file, "data/missions/fight-for-food.2.a.zone.nbl"}, {sets, 4}]}, - %~ {[1000113, 0], [{file, "data/missions/fight-for-food.2.s.zone.nbl"}, {sets, 4}]}, - {[1000114, 0], [{file, "data/missions/fight-for-food.2.s2.zone.nbl"}, {sets, 4}]}, - - {[1000120, 0], [{file, "data/missions/fight-for-food.3.c.zone.nbl"}, {sets, 4}]}, - %~ {[1000121, 0], [{file, "data/missions/fight-for-food.3.b.zone.nbl"}, {sets, 4}]}, - {[1000122, 0], [{file, "data/missions/fight-for-food.3.a.zone.nbl"}, {sets, 4}]}, - %~ {[1000123, 0], [{file, "data/missions/fight-for-food.3.s.zone.nbl"}, {sets, 4}]}, - {[1000124, 0], [{file, "data/missions/fight-for-food.3.s2.zone.nbl"}, {sets, 4}]}, - - % Dark Satellite - - {[1001000, 0], [{file, "data/missions/dark-satellite.1.c.zone.nbl"}, {sets, 4}]}, - {[1001001, 0], [{file, "data/missions/dark-satellite.1.b.zone.nbl"}, {sets, 4}]}, - {[1001002, 0], [{file, "data/missions/dark-satellite.1.a.zone.nbl"}, {sets, 4}]}, - %~ {[1001003, 0], [{file, "data/missions/dark-satellite.1.s.zone.nbl"}, {sets, 4}]}, - {[1001004, 0], [{file, "data/missions/dark-satellite.1.s2.zone.nbl"}, {sets, 4}]}, - {[1001005, 0], [{file, "data/missions/dark-satellite.1.s3.zone.nbl"}, {sets, 4}]}, - - {[1001010, 0], [{file, "data/missions/dark-satellite.2.c.zone.nbl"}, {sets, 4}]}, - {[1001011, 0], [{file, "data/missions/dark-satellite.2.b.zone.nbl"}, {sets, 4}]}, - {[1001012, 0], [{file, "data/missions/dark-satellite.2.a.zone.nbl"}, {sets, 4}]}, - {[1001013, 0], [{file, "data/missions/dark-satellite.2.s.zone.nbl"}, {sets, 4}]}, - %~ {[1001014, 0], [{file, "data/missions/dark-satellite.2.s2.zone.nbl"}, {sets, 4}]}, - %~ {[1001015, 0], [{file, "data/missions/dark-satellite.2.s3.zone.nbl"}, {sets, 4}]}, - - {[1001020, 0], [{file, "data/missions/dark-satellite.3.c.zone.nbl"}, {sets, 4}]}, - %~ {[1001021, 0], [{file, "data/missions/dark-satellite.3.b.zone.nbl"}, {sets, 4}]}, - {[1001022, 0], [{file, "data/missions/dark-satellite.3.a.zone.nbl"}, {sets, 4}]}, - %~ {[1001023, 0], [{file, "data/missions/dark-satellite.3.s.zone.nbl"}, {sets, 4}]}, - {[1001024, 0], [{file, "data/missions/dark-satellite.3.s2.zone.nbl"}, {sets, 4}]}, - {[1001025, 0], [{file, "data/missions/dark-satellite.3.s3.zone.nbl"}, {sets, 4}]}, - - % Seed Awakening - - %~ {[1001100, 0], [{file, "data/missions/seed-awakening.1.c.zone-0.nbl"}, {sets, 4}]}, - %~ {[1001100, 1], [{file, "data/missions/seed-awakening.1.c.zone-1.nbl"}, {sets, 1}]}, - {[1001101, 0], [{file, "data/missions/seed-awakening.1.b.zone-0.nbl"}, {sets, 4}]}, - {[1001101, 1], [{file, "data/missions/seed-awakening.1.b.zone-1.nbl"}, {sets, 1}]}, - {[1001102, 0], [{file, "data/missions/seed-awakening.1.a.zone-0.nbl"}, {sets, 4}]}, - {[1001102, 1], [{file, "data/missions/seed-awakening.1.a.zone-1.nbl"}, {sets, 1}]}, - {[1001103, 0], [{file, "data/missions/seed-awakening.1.s.zone-0.nbl"}, {sets, 4}]}, - {[1001103, 1], [{file, "data/missions/seed-awakening.1.s.zone-1.nbl"}, {sets, 1}]}, - {[1001103, 2], [{file, "data/missions/seed-awakening.1.s.zone-2.nbl"}, {sets, 1}]}, - {[1001104, 0], [{file, "data/missions/seed-awakening.1.s2.zone-0.nbl"}, {sets, 4}]}, - {[1001104, 1], [{file, "data/missions/seed-awakening.1.s2.zone-1.nbl"}, {sets, 1}]}, - {[1001104, 2], [{file, "data/missions/seed-awakening.1.s2.zone-2.nbl"}, {sets, 1}]}, - {[1001105, 0], [{file, "data/missions/seed-awakening.1.s3.zone-0.nbl"}, {sets, 4}]}, - {[1001105, 1], [{file, "data/missions/seed-awakening.1.s3.zone-1.nbl"}, {sets, 1}]}, - {[1001105, 2], [{file, "data/missions/seed-awakening.1.s3.zone-2.nbl"}, {sets, 1}]}, - - {[1001110, 0], [{file, "data/missions/seed-awakening.2.c.zone-0.nbl"}, {sets, 4}]}, - {[1001110, 1], [{file, "data/missions/seed-awakening.2.c.zone-1.nbl"}, {sets, 1}]}, - {[1001111, 0], [{file, "data/missions/seed-awakening.2.b.zone-0.nbl"}, {sets, 4}]}, - {[1001111, 1], [{file, "data/missions/seed-awakening.2.b.zone-1.nbl"}, {sets, 1}]}, - {[1001112, 0], [{file, "data/missions/seed-awakening.2.a.zone-0.nbl"}, {sets, 4}]}, - {[1001112, 1], [{file, "data/missions/seed-awakening.2.a.zone-1.nbl"}, {sets, 1}]}, - %~ {[1001113, 0], [{file, "data/missions/seed-awakening.2.s.zone-0.nbl"}, {sets, 4}]}, - %~ {[1001113, 1], [{file, "data/missions/seed-awakening.2.s.zone-1.nbl"}, {sets, 1}]}, - %~ {[1001113, 2], [{file, "data/missions/seed-awakening.2.s.zone-2.nbl"}, {sets, 1}]}, - {[1001114, 0], [{file, "data/missions/seed-awakening.2.s2.zone-0.nbl"}, {sets, 4}]}, - {[1001114, 1], [{file, "data/missions/seed-awakening.2.s2.zone-1.nbl"}, {sets, 1}]}, - {[1001114, 2], [{file, "data/missions/seed-awakening.2.s2.zone-2.nbl"}, {sets, 1}]}, - {[1001115, 0], [{file, "data/missions/seed-awakening.2.s3.zone-0.nbl"}, {sets, 4}]}, - {[1001115, 1], [{file, "data/missions/seed-awakening.2.s3.zone-1.nbl"}, {sets, 1}]}, - {[1001115, 2], [{file, "data/missions/seed-awakening.2.s3.zone-2.nbl"}, {sets, 1}]}, - - {[1001120, 0], [{file, "data/missions/seed-awakening.3.c.zone-0.nbl"}, {sets, 4}]}, - {[1001120, 1], [{file, "data/missions/seed-awakening.3.c.zone-1.nbl"}, {sets, 1}]}, - %~ {[1001121, 0], [{file, "data/missions/seed-awakening.3.b.zone-0.nbl"}, {sets, 4}]}, - %~ {[1001121, 1], [{file, "data/missions/seed-awakening.3.b.zone-1.nbl"}, {sets, 1}]}, - %~ {[1001122, 0], [{file, "data/missions/seed-awakening.3.a.zone-0.nbl"}, {sets, 4}]}, - %~ {[1001122, 1], [{file, "data/missions/seed-awakening.3.a.zone-1.nbl"}, {sets, 1}]}, - %~ {[1001123, 0], [{file, "data/missions/seed-awakening.3.s.zone-0.nbl"}, {sets, 4}]}, - %~ {[1001123, 1], [{file, "data/missions/seed-awakening.3.s.zone-1.nbl"}, {sets, 1}]}, - %~ {[1001123, 2], [{file, "data/missions/seed-awakening.3.s.zone-2.nbl"}, {sets, 1}]}, - {[1001124, 0], [{file, "data/missions/seed-awakening.3.s2.zone-0.nbl"}, {sets, 4}]}, - %~ {[1001124, 1], [{file, "data/missions/seed-awakening.3.s2.zone-1.nbl"}, {sets, 1}]}, - %~ {[1001124, 2], [{file, "data/missions/seed-awakening.3.s2.zone-2.nbl"}, {sets, 1}]}, - {[1001125, 0], [{file, "data/missions/seed-awakening.3.s3.zone-0.nbl"}, {sets, 4}]}, - {[1001125, 1], [{file, "data/missions/seed-awakening.3.s3.zone-1.nbl"}, {sets, 1}]}, - {[1001125, 2], [{file, "data/missions/seed-awakening.3.s3.zone-2.nbl"}, {sets, 1}]}, - - % True Darkness - - %~ {[1001200, 0], [{file, "data/missions/true-darkness.1.c.zone-0.nbl"}, {sets, 4}]}, - %~ {[1001200, 1], [{file, "data/missions/true-darkness.1.c.zone-1.nbl"}, {sets, 1}]}, - %~ {[1001201, 0], [{file, "data/missions/true-darkness.1.b.zone-0.nbl"}, {sets, 4}]}, - %~ {[1001201, 1], [{file, "data/missions/true-darkness.1.b.zone-1.nbl"}, {sets, 1}]}, - %~ {[1001202, 0], [{file, "data/missions/true-darkness.1.a.zone-0.nbl"}, {sets, 4}]}, - %~ {[1001202, 1], [{file, "data/missions/true-darkness.1.a.zone-1.nbl"}, {sets, 1}]}, - %~ {[1001203, 0], [{file, "data/missions/true-darkness.1.s.zone-0.nbl"}, {sets, 4}]}, - %~ {[1001203, 1], [{file, "data/missions/true-darkness.1.s.zone-1.nbl"}, {sets, 1}]}, - %~ {[1001204, 0], [{file, "data/missions/true-darkness.1.s2.zone-0.nbl"}, {sets, 4}]}, - %~ {[1001204, 1], [{file, "data/missions/true-darkness.1.s2.zone-1.nbl"}, {sets, 1}]}, - - {[1001210, 0], [{file, "data/missions/true-darkness.2.c.zone-0.nbl"}, {sets, 4}]}, - {[1001210, 1], [{file, "data/missions/true-darkness.2.c.zone-1.nbl"}, {sets, 1}]}, - %~ {[1001211, 0], [{file, "data/missions/true-darkness.2.b.zone-0.nbl"}, {sets, 4}]}, - %~ {[1001211, 1], [{file, "data/missions/true-darkness.2.b.zone-1.nbl"}, {sets, 1}]}, - {[1001212, 0], [{file, "data/missions/true-darkness.2.a.zone-0.nbl"}, {sets, 4}]}, - {[1001212, 1], [{file, "data/missions/true-darkness.2.a.zone-1.nbl"}, {sets, 1}]}, - {[1001213, 0], [{file, "data/missions/true-darkness.2.s.zone-0.nbl"}, {sets, 4}]}, - {[1001213, 1], [{file, "data/missions/true-darkness.2.s.zone-1.nbl"}, {sets, 1}]}, - %~ {[1001214, 0], [{file, "data/missions/true-darkness.2.s2.zone-0.nbl"}, {sets, 4}]}, - %~ {[1001214, 1], [{file, "data/missions/true-darkness.2.s2.zone-1.nbl"}, {sets, 1}]}, - - {[1001220, 0], [{file, "data/missions/true-darkness.3.c.zone-0.nbl"}, {sets, 4}]}, - {[1001220, 1], [{file, "data/missions/true-darkness.3.c.zone-1.nbl"}, {sets, 1}]}, - {[1001221, 0], [{file, "data/missions/true-darkness.3.b.zone-0.nbl"}, {sets, 4}]}, - {[1001221, 1], [{file, "data/missions/true-darkness.3.b.zone-1.nbl"}, {sets, 1}]}, - {[1001222, 0], [{file, "data/missions/true-darkness.3.a.zone-0.nbl"}, {sets, 4}]}, - {[1001222, 1], [{file, "data/missions/true-darkness.3.a.zone-1.nbl"}, {sets, 1}]}, - %~ {[1001223, 0], [{file, "data/missions/true-darkness.3.s.zone-0.nbl"}, {sets, 4}]}, - %~ {[1001223, 1], [{file, "data/missions/true-darkness.3.s.zone-1.nbl"}, {sets, 1}]}, - {[1001224, 0], [{file, "data/missions/true-darkness.3.s2.zone-0.nbl"}, {sets, 4}]}, - {[1001224, 1], [{file, "data/missions/true-darkness.3.s2.zone-1.nbl"}, {sets, 1}]}, - - % The Black Nest - - {[1003000, 0], [{file, "data/missions/black-nest.1.c.zone.nbl"}, {sets, 4}]}, - {[1003001, 0], [{file, "data/missions/black-nest.1.b.zone.nbl"}, {sets, 4}]}, - {[1003002, 0], [{file, "data/missions/black-nest.1.a.zone.nbl"}, {sets, 4}]}, - {[1003003, 0], [{file, "data/missions/black-nest.1.s.zone.nbl"}, {sets, 4}]}, - {[1003004, 0], [{file, "data/missions/black-nest.1.s2.zone.nbl"}, {sets, 4}]}, - - {[1003010, 0], [{file, "data/missions/black-nest.2.c.zone.nbl"}, {sets, 4}]}, - %~ {[1003011, 0], [{file, "data/missions/black-nest.2.b.zone.nbl"}, {sets, 4}]}, - %~ {[1003012, 0], [{file, "data/missions/black-nest.2.a.zone.nbl"}, {sets, 4}]}, - %~ {[1003013, 0], [{file, "data/missions/black-nest.2.s.zone.nbl"}, {sets, 4}]}, - {[1003014, 0], [{file, "data/missions/black-nest.2.s2.zone.nbl"}, {sets, 4}]}, - - {[1003020, 0], [{file, "data/missions/black-nest.3.c.zone.nbl"}, {sets, 4}]}, - {[1003021, 0], [{file, "data/missions/black-nest.3.b.zone.nbl"}, {sets, 4}]}, - %~ {[1003022, 0], [{file, "data/missions/black-nest.3.a.zone.nbl"}, {sets, 4}]}, - {[1003023, 0], [{file, "data/missions/black-nest.3.s.zone.nbl"}, {sets, 4}]}, - %~ {[1003024, 0], [{file, "data/missions/black-nest.3.s2.zone.nbl"}, {sets, 4}]}, - - % The Dark God - - {[1003100, 0], [{file, "data/missions/dark-god.1.c.zone-0.nbl"}, {sets, 4}]}, - {[1003100, 1], [{file, "data/missions/dark-god.1.c.zone-1.nbl"}, {sets, 1}]}, - %~ {[1003101, 0], [{file, "data/missions/dark-god.1.b.zone-0.nbl"}, {sets, 4}]}, - %~ {[1003101, 1], [{file, "data/missions/dark-god.1.b.zone-1.nbl"}, {sets, 1}]}, - {[1003102, 0], [{file, "data/missions/dark-god.1.a.zone-0.nbl"}, {sets, 4}]}, - %~ {[1003102, 1], [{file, "data/missions/dark-god.1.a.zone-1.nbl"}, {sets, 1}]}, - {[1003103, 0], [{file, "data/missions/dark-god.1.s.zone-0.nbl"}, {sets, 4}]}, - {[1003103, 1], [{file, "data/missions/dark-god.1.s.zone-1.nbl"}, {sets, 1}]}, - {[1003104, 0], [{file, "data/missions/dark-god.1.s2.zone-0.nbl"}, {sets, 4}]}, - {[1003104, 1], [{file, "data/missions/dark-god.1.s2.zone-1.nbl"}, {sets, 1}]}, - {[1003104, 2], [{file, "data/missions/dark-god.1.s2.zone-2.nbl"}, {sets, 1}]}, - - {[1003110, 0], [{file, "data/missions/dark-god.2.c.zone-0.nbl"}, {sets, 4}]}, - {[1003110, 1], [{file, "data/missions/dark-god.2.c.zone-1.nbl"}, {sets, 1}]}, - {[1003111, 0], [{file, "data/missions/dark-god.2.b.zone-0.nbl"}, {sets, 4}]}, - {[1003111, 1], [{file, "data/missions/dark-god.2.b.zone-1.nbl"}, {sets, 1}]}, - {[1003112, 0], [{file, "data/missions/dark-god.2.a.zone-0.nbl"}, {sets, 4}]}, - {[1003112, 1], [{file, "data/missions/dark-god.2.a.zone-1.nbl"}, {sets, 1}]}, - {[1003113, 0], [{file, "data/missions/dark-god.2.s.zone-0.nbl"}, {sets, 4}]}, - %~ {[1003113, 1], [{file, "data/missions/dark-god.2.s.zone-1.nbl"}, {sets, 1}]}, - {[1003114, 0], [{file, "data/missions/dark-god.2.s2.zone-0.nbl"}, {sets, 4}]}, - {[1003114, 1], [{file, "data/missions/dark-god.2.s2.zone-1.nbl"}, {sets, 1}]}, - {[1003114, 2], [{file, "data/missions/dark-god.2.s2.zone-2.nbl"}, {sets, 1}]}, - - {[1003120, 0], [{file, "data/missions/dark-god.3.c.zone-0.nbl"}, {sets, 4}]}, - {[1003120, 1], [{file, "data/missions/dark-god.3.c.zone-1.nbl"}, {sets, 1}]}, - {[1003121, 0], [{file, "data/missions/dark-god.3.b.zone-0.nbl"}, {sets, 4}]}, - {[1003121, 1], [{file, "data/missions/dark-god.3.b.zone-1.nbl"}, {sets, 1}]}, - {[1003122, 0], [{file, "data/missions/dark-god.3.a.zone-0.nbl"}, {sets, 4}]}, - {[1003122, 1], [{file, "data/missions/dark-god.3.a.zone-1.nbl"}, {sets, 1}]}, - {[1003123, 0], [{file, "data/missions/dark-god.3.s.zone-0.nbl"}, {sets, 4}]}, - {[1003123, 1], [{file, "data/missions/dark-god.3.s.zone-1.nbl"}, {sets, 1}]}, - {[1003124, 0], [{file, "data/missions/dark-god.3.s2.zone-0.nbl"}, {sets, 4}]}, - {[1003124, 1], [{file, "data/missions/dark-god.3.s2.zone-1.nbl"}, {sets, 1}]}, - {[1003124, 2], [{file, "data/missions/dark-god.3.s2.zone-2.nbl"}, {sets, 1}]}, - - % Phantom Ruins (Linear Line counter) - - %~ {[1060300, 0], [{file, "data/missions/phantom-ruins.c-0.zone.nbl"}, {sets, 3}]}, - %~ {[1060300, 1], [{file, "data/missions/phantom-ruins.c-1.zone.nbl"}, {sets, 1}]}, - {[1060301, 0], [{file, "data/missions/phantom-ruins.b-0.zone.nbl"}, {sets, 3}]}, - {[1060301, 1], [{file, "data/missions/phantom-ruins.b-1.zone.nbl"}, {sets, 1}]}, - %~ {[1060302, 0], [{file, "data/missions/phantom-ruins.a-0.zone.nbl"}, {sets, 3}]}, - %~ {[1060302, 1], [{file, "data/missions/phantom-ruins.a-1.zone.nbl"}, {sets, 1}]}, - {[1060303, 0], [{file, "data/missions/phantom-ruins.s-0.zone.nbl"}, {sets, 3}]}, - {[1060303, 1], [{file, "data/missions/phantom-ruins.s-1.zone.nbl"}, {sets, 1}]}, - - % Photon Eraser Return - - %~ {[1070080, 0], [{file, "data/missions/photon-eraser-return.zone.nbl"}, {sets, 1}]}, - - % Dark Crystal Seeker - - {[1070742, 0], [{file, "data/missions/dark-crystal-seeker.zone.nbl"}, {sets, 1}]}, - - % MAG' - - {[1072100, 1], [{file, "data/missions/mag-prime.c.zone-1.nbl"}, {sets, 1}]}, - {[1072100, 2], [{file, "data/missions/mag-prime.c.zone-2.nbl"}, {sets, 2}]}, - {[1072100, 3], [{file, "data/missions/mag-prime.c.zone-3.nbl"}, {sets, 1}]}, - {[1072101, 1], [{file, "data/missions/mag-prime.b.zone-1.nbl"}, {sets, 1}]}, - {[1072101, 2], [{file, "data/missions/mag-prime.b.zone-2.nbl"}, {sets, 2}]}, - %~ {[1072101, 3], [{file, "data/missions/mag-prime.b.zone-3.nbl"}, {sets, 1}]}, - {[1072102, 1], [{file, "data/missions/mag-prime.a.zone-1.nbl"}, {sets, 1}]}, - {[1072102, 2], [{file, "data/missions/mag-prime.a.zone-2.nbl"}, {sets, 2}]}, - {[1072102, 3], [{file, "data/missions/mag-prime.a.zone-3.nbl"}, {sets, 1}]}, - {[1072103, 1], [{file, "data/missions/mag-prime.s.zone-1.nbl"}, {sets, 1}]}, - {[1072103, 2], [{file, "data/missions/mag-prime.s.zone-2.nbl"}, {sets, 2}]}, - {[1072103, 3], [{file, "data/missions/mag-prime.s.zone-3.nbl"}, {sets, 1}]}, - {[1072104, 1], [{file, "data/missions/mag-prime.s2.zone-1.nbl"}, {sets, 1}]}, - {[1072104, 2], [{file, "data/missions/mag-prime.s2.zone-2.nbl"}, {sets, 2}]}, - {[1072104, 3], [{file, "data/missions/mag-prime.s2.zone-3.nbl"}, {sets, 1}]}, - - % Gifts from Beyond - - {[1072300, 0], [{file, "data/missions/gifts-from-beyond-plus.zone.nbl"}, {sets, 1}]}, - - % Airboard Rally - - {[1090700, 0], [{file, "data/missions/airboard-rally.zone.nbl"}, {sets, 1}]}, - - % Colony - - {[1100000, 0], [{file, nofile}]}, - {[1100000, 1], [{file, "data/lobby/colony.zone-1.nbl"}]}, - {[1100000, 2], [{file, "data/lobby/colony.zone-2.nbl"}]}, - {[1100000, 3], [{file, "data/lobby/colony.zone-3.nbl"}]}, - {[1100000, 4], [{file, "data/lobby/colony.zone-4.nbl"}]}, - {[1100000, 7], [{file, "data/lobby/colony.zone-7.nbl"}]}, - {[1100000,11], [{file, "data/lobby/colony.zone-11.nbl"}]}, - {[1100000,12], [{file, "data/lobby/colony.zone-12.nbl"}]}, - {[1100000,13], [{file, "data/lobby/colony.zone-13.nbl"}]}, - - % Parum - - {[1101000, 0], [{file, "data/lobby/parum.zone-0.nbl"}]}, - {[1101000, 1], [{file, "data/lobby/parum.zone-1.nbl"}]}, - {[1101000, 2], [{file, "data/lobby/parum.zone-2.nbl"}]}, - {[1101000, 3], [{file, "data/lobby/parum.zone-3.nbl"}]}, - {[1101000, 4], [{file, "data/lobby/parum.zone-4.nbl"}]}, - {[1101000, 5], [{file, "data/lobby/parum.zone-5.nbl"}]}, - {[1101000, 7], [{file, "data/lobby/parum.zone-7.nbl"}]}, - {[1101000,11], [{file, "data/lobby/parum.zone-11.nbl"}]}, - {[1101000,12], [{file, "data/lobby/parum.zone-12.nbl"}]}, - {[1101000,13], [{file, "data/lobby/parum.zone-13.nbl"}]}, - - % Neudaiz - - {[1102000, 0], [{file, "data/lobby/neudaiz.zone-0.nbl"}]}, - {[1102000, 1], [{file, "data/lobby/neudaiz.zone-1.nbl"}]}, - {[1102000, 2], [{file, "data/lobby/neudaiz.zone-2.nbl"}]}, - {[1102000, 3], [{file, "data/lobby/neudaiz.zone-3.nbl"}]}, - {[1102000, 4], [{file, "data/lobby/neudaiz.zone-4.nbl"}]}, - {[1102000, 7], [{file, "data/lobby/neudaiz.zone-7.nbl"}]}, - {[1102000,11], [{file, "data/lobby/neudaiz.zone-11.nbl"}]}, - {[1102000,12], [{file, "data/lobby/neudaiz.zone-12.nbl"}]}, - {[1102000,13], [{file, "data/lobby/neudaiz.zone-13.nbl"}]}, - - % Moatoob - - {[1103000, 0], [{file, "data/lobby/moatoob.zone-0.nbl"}]}, - {[1103000, 1], [{file, "data/lobby/moatoob.zone-1.nbl"}]}, - {[1103000, 3], [{file, "data/lobby/moatoob.zone-3.nbl"}]}, - {[1103000, 4], [{file, "data/lobby/moatoob.zone-4.nbl"}]}, - {[1103000, 5], [{file, "data/lobby/moatoob.zone-5.nbl"}]}, - {[1103000, 6], [{file, "data/lobby/moatoob.zone-6.nbl"}]}, - {[1103000, 7], [{file, "data/lobby/moatoob.zone-7.nbl"}]}, - {[1103000,11], [{file, "data/lobby/moatoob.zone-11.nbl"}]}, - {[1103000,12], [{file, "data/lobby/moatoob.zone-12.nbl"}]}, - {[1103000,13], [{file, "data/lobby/moatoob.zone-13.nbl"}]}, - - % Spaceport - - {[1104000, 0], [{file, "data/lobby/spaceport.zone.nbl"}]}, - - % Tutorial (colony) - - {[1106000, 0], [{file, "data/tutorial/lobby.zone-0.nbl"}]}, - {[1106000, 1], [{file, "data/tutorial/lobby.zone-1.nbl"}]}, - - % SEED-Form Purge - - {[1113000, 0], [{file, "data/tutorial/seed-form-purge.hyuga.zone.nbl"}, {sets, 1}]}, - {[1113001, 0], [{file, "data/tutorial/seed-form-purge.maya.zone.nbl"}, {sets, 1}]}, - {[1113002, 0], [{file, "data/tutorial/seed-form-purge.lou.zone.nbl"}, {sets, 1}]}, - {[1113003, 0], [{file, "data/tutorial/seed-form-purge.leo.zone.nbl"}, {sets, 1}]}, - - % My room - - {[1120000, 0], [{file, "data/rooms/test.zone.nbl"}]}, - - % Tutorial (my room) - - {[1120000,10], [{file, "data/tutorial/myroom.zone.nbl"}]}, - - % Story Episode 2 - - {[1131010,0], [{file, "data/missions/ep2ch1.c.zone-0.nbl"}]}, - {[1131010,1], [{file, "data/missions/ep2ch1.c.zone-1.nbl"}]}, - {[1131010,2], [{file, "data/missions/ep2ch1.c.zone-2.nbl"}]}, - {[1131010,3], [{file, "data/missions/ep2ch1.c.zone-3.nbl"}]}, - - %% Boss Tests. - {[90120, 0], [{file, "data/missions/boss/lv1/alteraz/zone00_ae.nbl"}, {sets, 1}]}, - {[90120, 1], [{file, "data/missions/boss/lv1/alteraz/zone01_ae.nbl"}, {sets, 1}]}, - {[90130, 0], [{file, "data/missions/boss/lv1/rolei/zone00_ae.nbl"}, {sets, 1}]}, - {[90130, 1], [{file, "data/missions/boss/lv1/rolei/zone01_ae.nbl"}, {sets, 1}]}, - {[90140, 0], [{file, "data/missions/boss/lv1/motherbrain/zone00_ae.nbl"}, {sets, 1}]}, - {[90140, 1], [{file, "data/missions/boss/lv1/motherbrain/zone01_ae.nbl"}, {sets, 1}]}, - {[90150, 0], [{file, "data/missions/boss/lv1/falz1/zone00_ae.nbl"}, {sets, 1}]}, - {[90150, 1], [{file, "data/missions/boss/lv1/falz1/zone01_ae.nbl"}, {sets, 1}]}, - {[90160, 0], [{file, "data/missions/boss/lv1/falz2/zone00_ae.nbl"}, {sets, 1}]}, - {[90160, 1], [{file, "data/missions/boss/lv1/falz2/zone01_ae.nbl"}, {sets, 1}]}, - - %% v1 Free Missions. - {[110000, 0], [{file, "data/missions/v1/evacuation/zone00_ae.nbl"}, {sets, 1}]}, - {[110010, 0], [{file, "data/missions/v1/annihilation/zone00_ae.nbl"}, {sets, 1}]}, - {[110100, 0], [{file, "data/missions/v1/dark-satellite/zone00_ae.nbl"}, {sets, 1}]}, - {[110100, 1], [{file, "data/missions/v1/dark-satellite/zone01_ae.nbl"}, {sets, 1}]}, - {[110100, 2], [{file, "data/missions/v1/dark-satellite/zone02_ae.nbl"}, {sets, 1}]}, - {[111000, 0], [{file, "data/missions/v1/creature-discomfort/zone00_ae.nbl"}, {sets, 1}]}, - {[111010, 0], [{file, "data/missions/v1/burning-plains/zone00_ae.nbl"}, {sets, 1}]}, - {[111020, 0], [{file, "data/missions/v1/mad-beasts/zone00_ae.nbl"}, {sets, 1}]}, - {[111030, 0], [{file, "data/missions/v1/ruler-of-the-plains/zone00_ae.nbl"}, {sets, 1}]}, - {[111030, 1], [{file, "data/missions/v1/ruler-of-the-plains/zone01_ae.nbl"}, {sets, 1}]}, - {[111100, 0], [{file, "data/missions/v1/what-is-in-the-ruins/zone00_ae.nbl"}, {sets, 1}]}, - {[111100, 1], [{file, "data/missions/v1/what-is-in-the-ruins/zone01_ae.nbl"}, {sets, 1}]}, - {[111110, 0], [{file, "data/missions/v1/two-headed-sentinel/zone00_ae.nbl"}, {sets, 1}]}, - {[111110, 1], [{file, "data/missions/v1/two-headed-sentinel/zone01_ae.nbl"}, {sets, 1}]}, - {[111200, 0], [{file, "data/missions/v1/cargo-train-rescue/zone00_ae.nbl"}, {sets, 1}]}, - {[111300, 0], [{file, "data/missions/v1/endrum-underground/zone00_ae.nbl"}, {sets, 1}]}, - {[111300, 1], [{file, "data/missions/v1/endrum-underground/zone01_ae.nbl"}, {sets, 1}]}, - {[112000, 0], [{file, "data/missions/v1/mizuraki-devastation/zone00_ae.nbl"}, {sets, 1}]}, - {[112010, 0], [{file, "data/missions/v1/frozen-woods/zone00_ae.nbl"}, {sets, 1}]}, - {[112020, 0], [{file, "data/missions/v1/demons-above/zone00_ae.nbl"}, {sets, 1}]}, - {[112020, 1], [{file, "data/missions/v1/demons-above/zone01_ae.nbl"}, {sets, 1}]}, - {[112100, 0], [{file, "data/missions/v1/defend-islands/zone00_ae.nbl"}, {sets, 1}]}, - {[112120, 0], [{file, "data/missions/v1/woodland-flames/zone00_ae.nbl"}, {sets, 1}]}, - {[112200, 0], [{file, "data/missions/v1/grove-of-fanatics/zone00_ae.nbl"}, {sets, 1}]}, - {[112200, 1], [{file, "data/missions/v1/grove-of-fanatics/zone01_ae.nbl"}, {sets, 1}]}, - {[112210, 0], [{file, "data/missions/v1/temple-of-ice/zone00_ae.nbl"}, {sets, 1}]}, - {[113000, 0], [{file, "data/missions/v1/pandemonium/zone00_ae.nbl"}, {sets, 1}]}, - {[113100, 0], [{file, "data/missions/v1/tunnel-infestation/zone00_ae.nbl"}, {sets, 1}]}, - {[113200, 0], [{file, "data/missions/v1/goliath-in-the-desert/zone00_ae.nbl"}, {sets, 1}]}, - {[113200, 1], [{file, "data/missions/v1/goliath-in-the-desert/zone01_ae.nbl"}, {sets, 1}]}, - {[113230, 0], [{file, "data/missions/v1/absolute-zero/zone00_ae.nbl"}, {sets, 1}]}, - {[113240, 0], [{file, "data/missions/v1/terror-in-the-desert/zone00_ae.nbl"}, {sets, 1}]}, - {[113240, 1], [{file, "data/missions/v1/terror-in-the-desert/zone01_ae.nbl"}, {sets, 1}]} -]). - --define(MAPS, [ - % Colony - - {[1100000, 1], [{name, "Colony 1st Floor"}]}, - {[1100000, 2], [{name, "Colony 2nd Floor"}]}, - {[1100000, 3], [{name, "Colony 3rd Floor"}]}, - {[1100000, 4], [{name, "Colony 4th Floor"}]}, - {[1100000, 5], [{name, "Colony GUARDIANS"}]}, - {[1100000, 100], [{name, "Colony 2nd, Grind Shop"}]}, - {[1100000, 100], [{name, "Colony 2nd, Synth Shop"}]}, - {[1100000, 100], [{name, "Colony 2nd, Decos Shop"}]}, - {[1100000, 101], [{name, "Colony 2nd, Items Shop"}]}, - {[1100000, 101], [{name, "Colony 2nd, Weapons Shop"}]}, - {[1100000, 101], [{name, "Colony 2nd, Armors Shop"}]}, - {[1100000, 102], [{name, "Colony 3rd, Lumilass"}]}, - {[1100000, 102], [{name, "Colony 3rd, Clothes Shop"}]}, - {[1100000, 102], [{name, "Colony 3rd, Parts Shop"}]}, - {[1100000, 103], [{name, "Colony Club"}]}, - {[1100000, 110], [{name, "Colony R&D"}]}, - {[1100000,9000], [{name, "Colony Aurorey"}]}, - {[1100000,9001], [{name, "Colony Transfer Terminal"}]}, - {[1100000,9010], [{name, "Colony Dallgun"}]}, - {[1100000,9102], [{name, "Colony HIVE"}]}, - {[1100000,9200], [{name, "Colony Rykros"}]}, - {[1100000,9202], [{name, "Colony Falz Memoria"}]}, - - % Parum - - {[1101000, 1], [{name, "Parum City Central"}]}, - {[1101000, 2], [{name, "Parum City West"}]}, - {[1101000, 3], [{name, "Parum City East"}]}, - {[1101000, 4], [{name, "Parum GUARDIANS"}]}, - {[1101000, 100], [{name, "Parum Synth Shop"}]}, - {[1101000, 100], [{name, "Parum Clothes Shop"}]}, - {[1101000, 100], [{name, "Parum Parts Shop"}]}, - {[1101000, 200], [{name, "Parum GRM"}]}, - {[1101000,9000], [{name, "Parum Raffon"}]}, - {[1101000,9010], [{name, "Parum Lakeshore"}]}, - {[1101000,9030], [{name, "Parum Waterfall"}]}, - {[1101000,9100], [{name, "Parum Denes"}]}, - {[1101000,9101], [{name, "Parum Underground"}]}, - {[1101000,9200], [{name, "Parum Beach"}]}, - {[1101000,9201], [{name, "Parum Rozenom"}]}, - {[1101000,9203], [{name, "Parum Subway"}]}, - {[1101000,9209], [{name, "Parum AMF"}]}, - - % Neudaiz - - {[1102000, 1], [{name, "Neudaiz City"}]}, - {[1102000, 3], [{name, "Neudaiz GUARDIANS"}]}, - {[1102000, 100], [{name, "Neudaiz Synth Shop"}]}, - {[1102000, 100], [{name, "Neudaiz Clothes Shop"}]}, - {[1102000, 100], [{name, "Neudaiz Parts Shop"}]}, - {[1102000, 200], [{name, "Neudaiz Yohmei"}]}, - {[1102000,9000], [{name, "Neudaiz Islands"}]}, - {[1102000,9010], [{name, "Neudaiz Relics"}]}, - {[1102000,9100], [{name, "Neudaiz Mizuraki"}]}, - {[1102000,9120], [{name, "Neudaiz Hot Springs"}]}, - {[1102000,9300], [{name, "Neudaiz Temple"}]}, - {[1102000,9301], [{name, "Neudaiz Pavilion"}]}, - {[1102000,9302], [{name, "Neudaiz Habirao"}]}, - {[1102000,9305], [{name, "Neudaiz Saguraki"}]}, - - % Moatoob - - {[1103000, 1], [{name, "Moatoob City"}]}, - {[1103000, 2], [{name, "Moatoob GUARDIANS"}]}, - {[1103000, 100], [{name, "Moatoob Parts Shop"}]}, - {[1103000, 100], [{name, "Moatoob Clothes Shop"}]}, - {[1103000, 100], [{name, "Moatoob Synth Shop"}]}, - {[1103000, 101], [{name, "Moatoob Pub"}]}, - {[1103000, 200], [{name, "Moatoob Tenora"}]}, - {[1103000,9010], [{name, "Moatoob Desert"}]}, - {[1103000,9030], [{name, "Moatoob Oasis"}]}, - {[1103000,9040], [{name, "Moatoob Glacier"}]}, - {[1103000,9101], [{name, "Moatoob Basin"}]}, - {[1103000,9202], [{name, "Moatoob Underground Lake"}]}, - {[1103000,9300], [{name, "Moatoob Casino"}]}, - {[1103000,9302], [{name, "Moatoob Il Cabo"}]}, - {[1103000,9304], [{name, "Moatoob Granigs"}]}, - - % Spaceports - - {[1104000,900], [{name, "Spaceport"}]} -]). diff --git a/include/missions.hrl b/include/missions.hrl deleted file mode 100644 index ac01bda..0000000 --- a/include/missions.hrl +++ /dev/null @@ -1,4 +0,0 @@ -%% This file is automatically generated by EGS. -%% Please do not edit it manually, as you would risk losing your changes. - --define(MISSIONS, []). diff --git a/include/records.hrl b/include/records.hrl index 5837855..52a9d67 100644 --- a/include/records.hrl +++ b/include/records.hrl @@ -65,7 +65,7 @@ uni :: integer(), instancepid :: pid(), partypid :: pid(), - areatype :: counter | mission | lobby | myroom | spaceport, + areatype :: counter | mission | lobby | myroom, area :: area(), entryid :: entryid(), pos = {0.0, 0.0, 0.0, 0.0} :: position(), diff --git a/src/egs_files.erl b/src/egs_files.erl index 04bf990..c82402e 100644 --- a/src/egs_files.erl +++ b/src/egs_files.erl @@ -62,8 +62,7 @@ load_counter_pack_quests([{_QuestID, Filename}|Tail], PosList, SizeList, Acc) -> load_counter_pack_quests(Tail, [Pos|PosList], [Size|SizeList], [File|Acc]). %% @doc Load a quest configuration file and return a quest.xnr binary along with its pointers array. -load_quest_xnr(ConfFilename) -> - {ok, Settings} = file:consult(ConfFilename), +load_quest_xnr(Settings) -> QuestID = proplists:get_value(questid, Settings), %% Temp flags. TmpFlagsList = proplists:get_value(temp_flags, Settings), diff --git a/src/egs_quests_db.erl b/src/egs_quests_db.erl index ef2c98c..370fa28 100644 --- a/src/egs_quests_db.erl +++ b/src/egs_quests_db.erl @@ -19,10 +19,10 @@ -module(egs_quests_db). -behavior(gen_server). --export([start_link/0, stop/0, quest/1, zone/2, reload/0]). %% API. +-export([start_link/0, stop/0, quest/1, zone/2, area_type/2, reload/0]). %% API. -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). %% gen_server. --record(state, {quests_bin=[], zones_bin=[]}). +-record(state, {quests=[], quests_bin=[], zones_bin=[]}). %% Use the module name for the server's name. -define(SERVER, ?MODULE). @@ -45,6 +45,9 @@ quest(QuestID) -> zone(QuestID, ZoneID) -> gen_server:call(?SERVER, {zone, QuestID, ZoneID}). +area_type(QuestID, ZoneID) -> + gen_server:call(?SERVER, {area_type, QuestID, ZoneID}). + %% @spec reload() -> ok reload() -> gen_server:cast(?SERVER, reload). @@ -54,13 +57,77 @@ reload() -> init([]) -> {ok, #state{}}. -handle_call({quest, QuestID}, _From, State=#state{quests_bin=Cache}) -> - {Quest, Cache2} = get_quest(QuestID, Cache), - {reply, Quest, State#state{quests_bin=Cache2}}; +%% @doc Return a quest information either from the cache or from the configuration file, +%% in which case it gets added to the cache for subsequent attempts. +handle_call({quest, QuestID}, _From, State=#state{quests=Cache, quests_bin=BinCache}) -> + case proplists:get_value(QuestID, BinCache) of + undefined -> + Dir = io_lib:format("priv/quests/~b/", [QuestID]), + ConfFilename = Dir ++ "quest.conf", + {ok, Settings} = file:consult(ConfFilename), + {QuestXnrData, QuestXnrPtrs} = egs_files:load_quest_xnr(Settings), + UnitTitleBinFiles = load_unit_title_bin_files(Dir, Settings), + Files = [{data, "quest.xnr", QuestXnrData, QuestXnrPtrs}], + Files2 = Files ++ case UnitTitleBinFiles of + ignore -> []; + _Any -> + TablePos = egs_files:nbl_padded_size(byte_size(QuestXnrData)), + TextSize = lists:sum([egs_files:nbl_padded_size(byte_size(D)) || {data, _F, D, _P} <- UnitTitleBinFiles]), + TablePos2 = TablePos + TextSize, + {UnitTitleTableRelData, UnitTitleTableRelPtrs} = egs_files:load_unit_title_table_rel(ConfFilename, TablePos2), + UnitTitleBinFiles ++ [{data, "unit_title_table.rel", UnitTitleTableRelData, UnitTitleTableRelPtrs}] + end, + QuestNbl = egs_files:nbl_pack([{files, Files2}]), + {reply, QuestNbl, State#state{quests=[{QuestID, Settings}|Cache], quests_bin=[{QuestID, QuestNbl}|BinCache]}}; + QuestNbl -> + {reply, QuestNbl, State} + end; -handle_call({zone, QuestID, ZoneID}, _From, State=#state{zones_bin=Cache}) -> - {Zone, Cache2} = get_zone(QuestID, ZoneID, Cache), - {reply, Zone, State#state{zones_bin=Cache2}}; +%% @doc Return a zone information either from the cache or from the configuration files. +%% @todo FilePos, text.bin, other sets, enemies. +handle_call({zone, QuestID, ZoneID}, _From, State=#state{quests=QuestsCache, zones_bin=BinCache}) -> + case proplists:get_value({QuestID, ZoneID}, BinCache) of + undefined -> + Dir = io_lib:format("priv/quests/~b/", [QuestID]), + ZoneDir = Dir ++ io_lib:format("zone-~b/", [ZoneID]), + QuestSettings = proplists:get_value(QuestID, QuestsCache), + Zones = proplists:get_value(zones, QuestSettings), + Zone = proplists:get_value(ZoneID, Zones), + AreaID = proplists:get_value(areaid, Zone), + Maps = proplists:get_value(maps, Zone), + FilePos = 0, %% @todo + {Set0, SetPtrs} = egs_files:load_set_rel(ZoneDir ++ io_lib:format("set_r~b.conf", [0]), AreaID, Maps, FilePos), + ScriptBin = egs_files:load_script_bin(ZoneDir ++ "script.es"), + ScriptBinSize = byte_size(ScriptBin), + ScriptBin2 = egs_prs:compress(ScriptBin), + ScriptBinSize2 = byte_size(ScriptBin2), + ScriptBin3 = << ScriptBinSize:32/little, ScriptBinSize2:32/little, 0:32, 1:32/little, 0:96, ScriptBin2/binary >>, + TextBin = egs_files:load_text_bin(ZoneDir ++ "text.bin.en_US.txt"), + ZoneNbl = egs_files:nbl_pack([{files, [ + {data, "set_r0.rel", Set0, SetPtrs}, + {data, "script.bin", ScriptBin3, []}, + {data, "text.bin", TextBin, []} + ]}]), + {reply, ZoneNbl, State#state{zones_bin=[{{QuestID, ZoneID}, ZoneNbl}|BinCache]}}; + ZoneNbl -> + {reply, ZoneNbl, State} + end; + +handle_call({area_type, QuestID, ZoneID}, _From, State=#state{quests=QuestsCache}) -> + {_, Quest} = lists:keyfind(QuestID, 1, QuestsCache), + {_, Zones} = lists:keyfind(zones, 1, Quest), + {_, Zone} = lists:keyfind(ZoneID, 1, Zones), + {_, AreaID} = lists:keyfind(areaid, 1, Zone), + AreaType = case AreaID of + 0 -> lobby; + 2 -> lobby; + 3 -> lobby; + 4 -> lobby; + 5 -> lobby; + 22 -> myroom; + _Any -> mission + end, + {reply, AreaType, State}; handle_call(stop, _From, State) -> {stop, normal, stopped, State}; @@ -85,65 +152,7 @@ code_change(_OldVsn, State, _Extra) -> %% Internal. -%% @doc Return a quest information either from the cache or from the configuration file, -%% in which case it gets added to the cache for subsequent attempts. -get_quest(QuestID, Cache) -> - case proplists:get_value(QuestID, Cache) of - undefined -> - Dir = io_lib:format("priv/quests/~b/", [QuestID]), - ConfFilename = Dir ++ "quest.conf", - {QuestXnrData, QuestXnrPtrs} = egs_files:load_quest_xnr(ConfFilename), - UnitTitleBinFiles = load_unit_title_bin_files(Dir, ConfFilename), - Files = [{data, "quest.xnr", QuestXnrData, QuestXnrPtrs}], - Files2 = Files ++ case UnitTitleBinFiles of - ignore -> []; - _Any -> - TablePos = egs_files:nbl_padded_size(byte_size(QuestXnrData)), - TextSize = lists:sum([egs_files:nbl_padded_size(byte_size(D)) || {data, _F, D, _P} <- UnitTitleBinFiles]), - TablePos2 = TablePos + TextSize, - {UnitTitleTableRelData, UnitTitleTableRelPtrs} = egs_files:load_unit_title_table_rel(ConfFilename, TablePos2), - UnitTitleBinFiles ++ [{data, "unit_title_table.rel", UnitTitleTableRelData, UnitTitleTableRelPtrs}] - end, - QuestNbl = egs_files:nbl_pack([{files, Files2}]), - Cache2 = [{QuestID, QuestNbl}|Cache], - {QuestNbl, Cache2}; - QuestNbl -> - {QuestNbl, Cache} - end. - -%% @doc Return a zone information either from the cache or from the configuration files. -%% @todo FilePos, text.bin, other sets, enemies. -get_zone(QuestID, ZoneID, Cache) -> - case proplists:get_value({QuestID, ZoneID}, Cache) of - undefined -> - Dir = io_lib:format("priv/quests/~b/", [QuestID]), - ZoneDir = Dir ++ io_lib:format("zone-~b/", [ZoneID]), - {ok, QuestSettings} = file:consult(Dir ++ "quest.conf"), - Zones = proplists:get_value(zones, QuestSettings), - Zone = proplists:get_value(ZoneID, Zones), - AreaID = proplists:get_value(areaid, Zone), - Maps = proplists:get_value(maps, Zone), - FilePos = 0, %% @todo - {Set0, SetPtrs} = egs_files:load_set_rel(ZoneDir ++ io_lib:format("set_r~b.conf", [0]), AreaID, Maps, FilePos), - ScriptBin = egs_files:load_script_bin(ZoneDir ++ "script.es"), - ScriptBinSize = byte_size(ScriptBin), - ScriptBin2 = egs_prs:compress(ScriptBin), - ScriptBinSize2 = byte_size(ScriptBin2), - ScriptBin3 = << ScriptBinSize:32/little, ScriptBinSize2:32/little, 0:32, 1:32/little, 0:96, ScriptBin2/binary >>, - TextBin = egs_files:load_text_bin(ZoneDir ++ "text.bin.en_US.txt"), - ZoneNbl = egs_files:nbl_pack([{files, [ - {data, "set_r0.rel", Set0, SetPtrs}, - {data, "script.bin", ScriptBin3, []}, - {data, "text.bin", TextBin, []} - ]}]), - Cache2 = [{{QuestID, ZoneID}, ZoneNbl}|Cache], - {ZoneNbl, Cache2}; - ZoneNbl -> - {ZoneNbl, Cache} - end. - -load_unit_title_bin_files(Dir, ConfFilename) -> - {ok, Settings} = file:consult(ConfFilename), +load_unit_title_bin_files(Dir, Settings) -> case proplists:get_value(notitles, Settings) of true -> ignore; _Any -> diff --git a/src/psu/psu_game.erl b/src/psu/psu_game.erl index 7d7bdd8..183427f 100644 --- a/src/psu/psu_game.erl +++ b/src/psu/psu_game.erl @@ -21,8 +21,6 @@ -compile(export_all). %% @todo Temporarily export all until send_xxxx functions are moved to psu_proto. -include("include/records.hrl"). --include("include/maps.hrl"). --include("include/missions.hrl"). %% @doc Load and send the character information to the client. %% @todo Move this whole function directly to psu_proto, probably. @@ -44,152 +42,56 @@ char_load(User, State) -> %% @doc Load the given map as a standard lobby. area_load(QuestID, ZoneID, MapID, EntryID, State) -> - {ok, OldUser} = egs_users:read(get(gid)), - [{type, AreaType}, {file, QuestFile}|MissionInfo] = proplists:get_value(QuestID, ?QUESTS, [{type, undefined}, {file, undefined}]), - QuestData = case QuestFile of - nofile -> egs_quests_db:quest(QuestID); - undefined -> undefined; - QFilename -> {ok, QD} = file:read_file(QFilename), QD - end, - [IsStart, RealZoneID, RealMapID, RealEntryID, NbSetsInQuest] = case AreaType of - mission -> - if ZoneID =:= 65535 -> - [{start, [TmpZoneID, TmpMapID, TmpEntryID]}, {sets, TmpNbSets}] = MissionInfo, - [true, TmpZoneID, TmpMapID, TmpEntryID, TmpNbSets]; - true -> [false, ZoneID, MapID, EntryID, ignored] - end; - myroom -> - if ZoneID =:= 0 -> - [false, 0, 423, EntryID, ignored]; - true -> [false, ZoneID, MapID, EntryID, ignored] - end; - _ -> - [false, ZoneID, MapID, EntryID, ignored] - end, - [{file, ZoneFile}|ZoneSetInfo] = proplists:get_value([QuestID, RealZoneID], ?ZONES, [{file, undefined}]), - ZoneData = case ZoneFile of - nofile -> egs_quests_db:zone(QuestID, ZoneID); - undefined -> undefined; - ZFilename -> {ok, ZD} = file:read_file(ZFilename), ZD - end, - NbSetsInZone = case ZoneSetInfo of [] -> 1; [{sets, TmpNbSetsInZone}] -> TmpNbSetsInZone end, - if AreaType =:= myroom -> - AreaName = "Your Room"; - true -> - [{name, AreaName}] = proplists:get_value([QuestID, RealMapID], ?MAPS, [{name, "dammy"}]) - end, - {InstancePid, SetID} = if IsStart =:= true -> % initialize the mission - Zones = proplists:get_value(QuestID, ?MISSIONS), - {ok, RetPid} = psu_instance:start_link(Zones), - RetSetID = crypto:rand_uniform(0, NbSetsInQuest), - {RetPid, RetSetID}; - true -> {OldUser#users.instancepid, OldUser#users.setid} - end, - User = OldUser#users{instancepid=InstancePid, areatype=AreaType, area={QuestID, RealZoneID, RealMapID}, entryid=RealEntryID}, - egs_users:write(User), - RealSetID = if SetID > NbSetsInZone - 1 -> NbSetsInZone - 1; true -> SetID end, - area_load(AreaType, IsStart, RealSetID, OldUser, User, QuestData, ZoneData, AreaName, State). - -area_load(AreaType, IsStart, SetID, OldUser, User, QuestData, ZoneData, AreaName, State) -> + {ok, OldUser} = egs_users:read(State#state.gid), {OldQuestID, OldZoneID, _OldMapID} = OldUser#users.area, - {QuestID, ZoneID, _MapID} = User#users.area, - QuestChange = if OldQuestID /= QuestID, QuestData /= undefined -> true; true -> false end, - if ZoneData =:= undefined -> - ZoneChange = false; - true -> - ZoneChange = if OldQuestID =:= QuestID, OldZoneID =:= ZoneID -> false; true -> true end - end, + QuestData = egs_quests_db:quest(QuestID), + QuestChange = OldQuestID /= QuestID, + ZoneData = egs_quests_db:zone(QuestID, ZoneID), + ZoneChange = if OldQuestID =:= QuestID, OldZoneID =:= ZoneID -> false; true -> true end, + AreaType = egs_quests_db:area_type(QuestID, ZoneID), + AreaShortName = "dammy", %% @todo Load the short name from egs_quests_db. + SetID = 0, %% @todo Handle multiple sets properly. {IsSeasonal, SeasonID} = egs_seasons:read(QuestID), - % broadcast spawn and unspawn to other people - {ok, UnspawnList} = egs_users:select({neighbors, OldUser}), - {ok, SpawnList} = egs_users:select({neighbors, User}), - lists:foreach(fun(Other) -> Other#users.pid ! {egs, player_unspawn, User} end, UnspawnList), - if AreaType =:= lobby -> - lists:foreach(fun(Other) -> Other#users.pid ! {egs, player_spawn, User} end, SpawnList); - true -> ignore - end, - % load area - if QuestChange =:= true -> - % load new quest + User = OldUser#users{areatype=AreaType, area={QuestID, ZoneID, MapID}, entryid=EntryID}, + egs_users:write(User), + %% @todo Handle spawn and unspawn using egs_zone:leave and egs_zone:enter. + %% Load the quest. + if QuestChange -> psu_proto:send_0c00(User, State), psu_proto:send_020e(QuestData, State); true -> ignore end, %% @todo The LID changes here. - if IsStart =:= true -> - psu_proto:send_0215(16#ffffffff, State); - true -> ignore - end, - if ZoneChange =:= true -> - % load new zone + %% Load the zone. + if ZoneChange -> psu_proto:send_0a05(State), - if AreaType =:= lobby -> - psu_proto:send_0111(User#users{lid=0}, 6, State); - true -> ignore - end, + psu_proto:send_0111(User#users{lid=0}, 6, State), psu_proto:send_010d(User#users{lid=0}, State), psu_proto:send_0200(ZoneID, AreaType, State), psu_proto:send_020f(ZoneData, SetID, SeasonID, State); true -> ignore end, + %% Load the player location. State2 = State#state{areanb=State#state.areanb + 1}, psu_proto:send_0205(User#users{lid=0}, IsSeasonal, State2), - psu_proto:send_100e(User#users.area, User#users.entryid, AreaName, State2), - if AreaType =:= mission -> - psu_proto:send_0215(0, State2), - if IsStart =:= true -> - psu_proto:send_0215(0, State2), - send_0c09(); - true -> ignore - end; - true -> - psu_proto:send_020c(State2) - end, - if ZoneChange =:= true -> - case AreaType of - myroom -> - send_1332(), - send_1202(), - psu_proto:send_1204(State2), - send_1206(); - mission -> - send_1202(), - psu_proto:send_1204(State2), - send_1206(), - send_1207(); - _ -> ignore - end; - true -> ignore - end, - if ZoneChange =:= true, AreaType =/= spaceport -> - send_1212(); - true -> ignore - end, - if AreaType =:= myroom -> - send_1309(); + psu_proto:send_100e(User#users.area, User#users.entryid, AreaShortName, State2), + %% Load the zone objects. + if ZoneChange -> + send_1212(); %% @todo Only sent if there is a set file. true -> ignore end, + %% Load the player. psu_proto:send_0201(User#users{lid=0}, State2), - if ZoneChange =:= true -> + if ZoneChange -> psu_proto:send_0a06(User, State2); true -> ignore end, - if length(SpawnList) =/= 0 -> - psu_proto:send_0233(SpawnList, State); - true -> ignore - end, - case User#users.partypid of - undefined -> ignore; - _ -> send_022c(0, 16#12) - end, + %% @todo Send the spawn list. + %% End of loading. State3 = State2#state{areanb=State2#state.areanb + 1}, psu_proto:send_0208(State3), psu_proto:send_0236(State3), - if User#users.partypid =/= undefined, AreaType =:= mission -> - {ok, NPCList} = psu_party:get_npc(User#users.partypid), - npc_load(User, NPCList, State); - true -> ok - end, + %% @todo Load APC characters. {ok, State3}. %% @todo Don't change the NPC info unless you are the leader! @@ -437,11 +339,7 @@ send_100f(NPCid, PartyPos) -> %% @doc Send the mission's quest file when starting a new mission. %% @todo Handle correctly. 0:32 is actually a missing value. Value before that is unknown too. send_1015(QuestID) -> - [{type, _}, {file, QuestFile}|_] = proplists:get_value(QuestID, ?QUESTS), - QuestData = case QuestFile of - nofile -> egs_quests_db:quest(QuestID); - Filename -> {ok, D} = file:read_file(Filename), D - end, + QuestData = egs_quests_db:quest(QuestID), Size = byte_size(QuestData), send(<< (header(16#1015))/binary, QuestID:32/little-unsigned-integer, 16#01010000:32, 0:32, Size:32/little-unsigned-integer, QuestData/binary >>). diff --git a/src/psu/psu_parser.erl b/src/psu/psu_parser.erl deleted file mode 100644 index 503f21b..0000000 --- a/src/psu/psu_parser.erl +++ /dev/null @@ -1,386 +0,0 @@ -%% @author Loïc Hoguin -%% @copyright 2010 Loïc Hoguin. -%% @doc Game data files parser. -%% -%% This file is part of EGS. -%% -%% EGS is free software: you can redistribute it and/or modify -%% it under the terms of the GNU Affero General Public License as -%% published by the Free Software Foundation, either version 3 of the -%% License, or (at your option) any later version. -%% -%% EGS is distributed in the hope that it will be useful, -%% but WITHOUT ANY WARRANTY; without even the implied warranty of -%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -%% GNU Affero General Public License for more details. -%% -%% You should have received a copy of the GNU Affero General Public License -%% along with EGS. If not, see . - --module(psu_parser). --export([run/0]). - --include("include/maps.hrl"). - -run() -> - List = [{QuestID, parse_quest(QuestID)} || {QuestID, _} <- ?QUESTS], - Begin = "%% This file is automatically generated by EGS. -%% Please do not edit it manually, as you would risk losing your changes. - --define(MISSIONS, -", - End = "). -", - Missions = io_lib:format("~s~p~s", [Begin, List, End]), - file:write_file("include/missions.hrl", Missions). - -parse_quest(QuestID) -> - [{ZoneID, parse_zone(Filename)} || {[ZoneQuestID, ZoneID], [{file, Filename}|_]} <- ?ZONES, ZoneQuestID =:= QuestID]. - -parse_zone(NblFilename) -> - Files = nbl_list_files(NblFilename), - log("~p", [Files]), - nbl_extract_files(NblFilename), - Filename = "set_r0.rel", - case filelib:is_file(io_lib:format("tmp/~s", [Filename])) of - false -> - io:format("ignoring ~s (no set file)~n", [NblFilename]), - nbl_cleanup(), - []; - true -> - io:format("parsing ~s~n", [NblFilename]), - BasePtr = calc_base_ptr(Filename, Files, 0), - {ok, << $N, $X, $R, 0, EndRelPtr:32/little-unsigned-integer, AreaIDListRelPtr:32/little-unsigned-integer, 0:32, Data/bits >>} = file:read_file(io_lib:format("tmp/~s", [Filename])), - log("header: end ptr(~b) areaid list ptr(~b)", [EndRelPtr, AreaIDListRelPtr]), - {ok, _AreaCode, NbMaps, MapsListPtr} = parse_areaid_list(Data, AreaIDListRelPtr - 16), - MapList = parse_mapnumbers_list(Data, NbMaps, MapsListPtr - BasePtr - 16), - ObjList = [{MapID, parse_object_list_headers(BasePtr, Data, NbHeaders, ObjListHeadersPtr - BasePtr - 16)} || {MapID, NbHeaders, ObjListHeadersPtr} <- MapList], - nbl_cleanup(), - ObjList - end. - -nbl_list_files(NblFilename) -> - {Cmd, NL} = case os:type() of - {win32, nt} -> {lists:flatten(io_lib:format("nbl -t ~s", [NblFilename])), "\r\n"}; - _ -> {io_lib:format("./nbl -t ~s", [NblFilename]), "\n"} - end, - StdOut = os:cmd(Cmd), - re:split(StdOut, NL, [{return, list}]). - -nbl_extract_files(NblFilename) -> - filelib:ensure_dir("tmp/"), - Cmd = case os:type() of - {win32, nt} -> lists:flatten(io_lib:format("nbl -o tmp/ ~s", [NblFilename])); - _ -> io_lib:format("./nbl -o tmp/ ~s", [NblFilename]) - end, - os:cmd(Cmd), - ok. - -nbl_cleanup() -> - {ok, Filenames} = file:list_dir("tmp/"), - [file:delete(io_lib:format("tmp/~s", [Filename])) || Filename <- Filenames], - file:del_dir("tmp/"), - ok. - -calc_base_ptr(Filename, [Current|_Tail], Ptr) when Filename =:= Current -> - Ptr; -calc_base_ptr(Filename, [Current|Tail], Ptr) -> - FileSize = filelib:file_size(io_lib:format("tmp/~s", [Current])), - RoundedSize = case FileSize rem 32 of - 0 -> FileSize; - _ -> 32 * (1 + (FileSize div 32)) - end, - calc_base_ptr(Filename, Tail, Ptr + RoundedSize). - -parse_areaid_list(Data, Ptr) -> - Bits = Ptr * 8, - << _:Bits/bits, AreaCode:16/little-unsigned-integer, NbMaps:16/little-unsigned-integer, MapsListPtr:32/little-unsigned-integer, _/bits >> = Data, - log("areaid list: area code(~b) nb maps(~b) maps list ptr(~b)", [AreaCode, NbMaps, MapsListPtr]), - {ok, AreaCode, NbMaps, MapsListPtr}. - -parse_mapnumbers_list(Data, NbMaps, Ptr) -> - IgnoredBits = Ptr * 8, - MapBits = NbMaps * 12 * 8, - << _:IgnoredBits/bits, MapList:MapBits/bits, _/bits >> = Data, - parse_mapnumbers_list_rec(MapList, NbMaps, []). - -parse_mapnumbers_list_rec(_Data, 0, Acc) -> - lists:reverse(Acc); -parse_mapnumbers_list_rec(Data, NbMaps, Acc) -> - << MapID:16/little-unsigned-integer, NbHeaders:16/little-unsigned-integer, ObjListHeadersPtr:32/little-unsigned-integer, 0:32, Rest/bits >> = Data, - log("mapnumbers list: mapid(~b) nbheaders(~b) object headers ptr(~b)", [MapID, NbHeaders, ObjListHeadersPtr]), - parse_mapnumbers_list_rec(Rest, NbMaps - 1, [{MapID, NbHeaders, ObjListHeadersPtr}|Acc]). - -parse_object_list_headers(BasePtr, Data, NbHeaders, Ptr) -> - Bits = Ptr * 8, - << _:Bits/bits, Rest/bits >> = Data, - List = parse_object_list_headers_rec(Rest, NbHeaders, []), - [parse_object_list(BasePtr, Data, NbObjects, ObjListPtr - BasePtr - 16) || {_ObjListNumber, NbObjects, ObjListPtr} <- List]. - -parse_object_list_headers_rec(_Data, 0, Acc) -> - lists:reverse(Acc); -parse_object_list_headers_rec(Data, NbHeaders, Acc) -> - %~ << Log:320/bits, _/bits >> = Data, - %~ io:format("~p~n", [Log]), - << 16#ffffffff:32, UnknownA:144/bits, UnknownB:16/little-unsigned-integer, UnknownC:32/little-unsigned-integer, - ObjListNumber:16/little-unsigned-integer, 0:32, NbObjects:16/little-unsigned-integer, ObjListPtr:32/little-unsigned-integer, Rest/bits >> = Data, - log("object list headers: a(~p) b(~p) c(~p) list nb(~b) nb obj(~b) obj list ptr(~b)", [UnknownA, UnknownB, UnknownC, ObjListNumber, NbObjects, ObjListPtr]), - parse_object_list_headers_rec(Rest, NbHeaders - 1, [{ObjListNumber, NbObjects, ObjListPtr}|Acc]). - -parse_object_list(BasePtr, Data, NbObjects, Ptr) -> - Bits = Ptr * 8, - << _:Bits/bits, Rest/bits >> = Data, - List = parse_object_list_rec(Rest, NbObjects, []), - [parse_object_args(ObjType, Params, Data, ArgSize, ArgPtr - BasePtr - 16) || {ObjType, Params, ArgSize, ArgPtr} <- List]. - -parse_object_list_rec(_Data, 0, Acc) -> - lists:reverse(Acc); -parse_object_list_rec(Data, NbObjects, Acc) -> - << 16#ffffffff:32, UnknownA:32/little-unsigned-integer, 16#ffffffff:32, 16#ffff:16, ObjType:16/little-unsigned-integer, 0:32, - PosX:32/little-float, PosY:32/little-float, PosZ:32/little-float, RotX:32/little-float, RotY:32/little-float, RotZ:32/little-float, - ArgSize:32/little-unsigned-integer, ArgPtr:32/little-unsigned-integer, Rest/bits >> = Data, - log("object entry: a(~b) nb(~b) pos[x(~p) y(~p) z(~p)] rot[x(~p) y(~p) z(~p)] argsize(~b) argptr(~b)", [UnknownA, ObjType, PosX, PosY, PosZ, RotX, RotY, RotZ, ArgSize, ArgPtr]), - parse_object_list_rec(Rest, NbObjects - 1, [{ObjType, {params, {pos, PosX, PosY, PosZ}, {rot, RotX, RotY, RotZ}}, ArgSize, ArgPtr}|Acc]). - -parse_object_args(ObjType, Params, Data, Size, Ptr) -> - BeforeBits = Ptr * 8, - SizeBits = Size * 8, - << _:BeforeBits/bits, Args:SizeBits/bits, _/bits >> = Data, - parse_object_args(ObjType, Params, Args). - -parse_object_args(4, _Params, _Data) -> - static_model; - -%% @todo Many unknowns. -parse_object_args(5, _Params, Data) -> - << _:352, TrigEvent:16/little-unsigned-integer, _Unknown:112 >> = Data, - log("floor_button: trigevent(~p)", [TrigEvent]), - {floor_button, TrigEvent}; - -parse_object_args(6, _Params, _Data) -> - fog; - -parse_object_args(9, _Params, _Data) -> - sensor; - -parse_object_args(10, _Params, _Data) -> - invisible_block; - -%% @todo UnknownG or UnknownH is probably the required event. -parse_object_args(12, _Params, Data) -> - << Model:16/little-unsigned-integer, UnknownA:16/little-unsigned-integer, UnknownB:32/little-unsigned-integer, UnknownC:16/little-unsigned-integer, Scale:16/little-unsigned-integer, - UnknownD:16/little-unsigned-integer, 16#ff00:16, UnknownE:16/little-unsigned-integer, UnknownF:16/little-unsigned-integer, UnknownG:16/little-unsigned-integer, - 16#ffff:16, 16#ffffffff:32, 16#ffffffff:32, RawTrigEvent:16/little-unsigned-integer, 16#ffffffff:32, 16#ffffffff:32, 16#ffffffff:32, - 16#ffff:16, UnknownH:16/little-unsigned-integer, 16#ffffffff:32, 16#ffffffff:32, 16#ffffffff:32, 16#ffff:16, UnknownI:16/little-unsigned-integer, 0:16 >> = Data, - Breakable = case UnknownB of - 0 -> false; - 1 -> true; - 3 -> true; %% @todo This is probably the kind of box that is only targettable (and thus breakable) after the correct event (probably UnknownG) has been sent. - _ -> true %% @todo No idea. One of them has a value of 0x300 ?? - end, - TrigEvent = convert_eventid(RawTrigEvent), - log("box: model(~b) a(~b) breakable(~p) c(~b) scale(~b) d(~b) e(~b) f(~b) g(~b) trigevent(~p) h(~b) i(~b)", [Model, UnknownA, Breakable, UnknownC, Scale, UnknownD, UnknownE, UnknownF, UnknownG, TrigEvent, UnknownH, UnknownI]), - {box, Model, Breakable, TrigEvent}; - -parse_object_args(14, {params, {pos, PosX, PosY, PosZ}, _Rot}, Data) -> - << _:96, DiffX:32/little-float, DiffY:32/little-float, DiffZ:32/little-float, DestDir:32/little-float, _Unknown:512 >> = Data, - log("warp: diffpos[x(~p) y(~p) z(~p)] destdir(~p)", [DiffX, DiffY, DiffZ, DestDir]), - {warp, PosX + DiffX, PosY + DiffY, PosZ + DiffZ, DestDir}; - -parse_object_args(17, _Params, _Data) -> - fence; - -parse_object_args(18, _Params, _Data) -> - npc; - -parse_object_args(20, _Params, _Data) -> - door; - -parse_object_args(22, _Params, Data) -> - << UnknownA:8, 0, KeySet:8, UnknownB:8, 0:16, UnknownC:8, 0, 0:16, UnknownD:16/little-unsigned-integer, RawReqKey1Event:16/little-unsigned-integer, - RawReqKey2Event:16/little-unsigned-integer, RawReqKey3Event:16/little-unsigned-integer, RawReqKey4Event:16/little-unsigned-integer, - 16#ffffffff:32, 16#ffffffff:32, RawTrigEvent:16/little-unsigned-integer, UnknownE:16/little-unsigned-integer, - 16#ffffffff:32, 16#ffffffff:32, 16#ffffffff:32 >> = Data, - ReqKeyEvents = [convert_eventid(RawReqKey1Event), convert_eventid(RawReqKey2Event), convert_eventid(RawReqKey3Event), convert_eventid(RawReqKey4Event)], - TrigEvent = convert_eventid(RawTrigEvent), - log("key_console: a(~b) keyset(~b) b(~b) c(~b) d(~b) reqkeyevents(~p) trigevent(~p) e(~b)", [UnknownA, KeySet, UnknownB, UnknownC, UnknownD, ReqKeyEvents, TrigEvent, UnknownE]), - {key_console, KeySet, TrigEvent, ReqKeyEvents}; - -%% @doc Small spawn. - -parse_object_args(23, _Params, Data) -> - %% @todo return meaningful information - << _:704, UnknownA:32/little-unsigned-integer, RawTrigEvent:16/little-unsigned-integer, RawReqEvent:16/little-unsigned-integer, UnknownB:16/little-unsigned-integer, UnknownC:8, SpawnNb:8 >> = Data, - TrigEvent = convert_eventid(RawTrigEvent), - ReqEvent = convert_eventid(RawReqEvent), - log("spawn (x10): a(~b) trigevent(~p) reqevent(~p) b(~b) c(~b) spawnnb(~b)", [UnknownA, TrigEvent, ReqEvent, UnknownB, UnknownC, SpawnNb]), - {'spawn', 10, TrigEvent, ReqEvent}; - -%% @doc Big spawn. - -parse_object_args(24, _Params, Data) -> - %% @todo return meaningful information - << _:704, UnknownA:32/little-unsigned-integer, RawTrigEvent:16/little-unsigned-integer, RawReqEvent:16/little-unsigned-integer, 16#ffff:16, UnknownB:8, SpawnNb:8 >> = Data, - TrigEvent = convert_eventid(RawTrigEvent), - ReqEvent = convert_eventid(RawReqEvent), - log("spawn (x30): a(~b) trigevent(~p) reqevent(~p) b(~b) spawnnb(~b)", [UnknownA, TrigEvent, ReqEvent, UnknownB, SpawnNb]), - {'spawn', 30, TrigEvent, ReqEvent}; - -%% @todo Find out! Big push 3rd zone file. -parse_object_args(25, _Params, _Data) -> - unknown_object_25; - -parse_object_args(26, _Params, _Data) -> - entrance; - -parse_object_args(27, _Params, _Data) -> - 'exit'; - -%% @todo Find out! Found in Gifts from Beyond+ and that other exchange mission. Also tutorial, all of it. -parse_object_args(28, _Params, _Data) -> - unknown_object_28; - -parse_object_args(31, _Params, Data) -> - << KeySet:8, UnknownA:8, UnknownB:8, UnknownC:8, 16#ffff:16, RawTrigEvent:16/little-unsigned-integer, RawReqEvent1:16/little-unsigned-integer, RawReqEvent2:16/little-unsigned-integer, - RawReqEvent3:16/little-unsigned-integer, 16#ffff:16, 16#ffffffff:32, 16#ffffffff:32 >> = Data, - TrigEvent = convert_eventid(RawTrigEvent), - ReqEvents = [convert_eventid(RawReqEvent1), convert_eventid(RawReqEvent2), convert_eventid(RawReqEvent3)], - log("key: keyset(~b) a(~b) b(~b) c(~b) trigevent(~p) reqevents(~p)", [KeySet, UnknownA, UnknownB, UnknownC, TrigEvent, ReqEvents]), - {key, KeySet, TrigEvent, ReqEvents}; - -%% @todo Find out! Found in Gifts from Beyond+ and that other exchange mission. Also tutorial. -parse_object_args(33, _Params, _Data) -> - unknown_object_33; - -parse_object_args(35, _Params, _Data) -> - boss; - -%% @todo Find out! v1 Mad Beasts zone 0. -parse_object_args(37, _Params, _Data) -> - unknown_object_37; - -%% @todo Find out! Big push 2nd zone file. -parse_object_args(39, _Params, _Data) -> - unknown_object_39; - -parse_object_args(40, _Params, _Data) -> - save_sphere; - -%% @todo Seems to be targetable elements found in your room. 3 yellow lines rotating in the otherwise normal map. -parse_object_args(42, _Params, _Data) -> - unknown_object_42; - -parse_object_args(43, _Params, _Data) -> - shoot_button; - -%% @todo Seems to be a zonde turret "trap". - -parse_object_args(44, _Params, _Data) -> - trap; - -parse_object_args(45, _Params, _Data) -> - npc_talk; - -%% @todo Might be more than just this counter. -parse_object_args(47, _Params, _Data) -> - type_counter_npc_talk; - -parse_object_args(48, _Params, _Data) -> - boss_gate; - -parse_object_args(49, _Params, _Data) -> - crystal; - -parse_object_args(50, _Params, _Data) -> - healing_pad; - -parse_object_args(51, _Params, Data) -> - << _Unknown:224, TrigEvent:16/little, _Rest/bits >> = Data, - {goggle_target, TrigEvent}; - -%% @doc Big SEED pod. -parse_object_args(52, _Params, _Data) -> - seed_blewme; - -parse_object_args(53, _Params, _Data) -> - label; - -%% @doc Photon-erasable pods. -parse_object_args(54, _Params, _Data) -> - seed_zoma; - -%% @doc For Photon Reflector on ice SEED zomas. -parse_object_args(55, _Params, _Data) -> - photon_spot; - -parse_object_args(56, _Params, _Data) -> - chair; - -%% @todo Airboard Rally, floaders. Speed boost and healing. -parse_object_args(57, _Params, _Data) -> - vehicle_boost; - -%% @todo Apparently used both for floaders and airboard. -parse_object_args(58, _Params, _Data) -> - vehicle; - -%% @todo Apparently used for the custom posters! -parse_object_args(59, _Params, _Data) -> - poster; - -parse_object_args(60, _Params, _Data) -> - uni_cube; - -parse_object_args(61, _Params, _Data) -> - ghosts_generator; - -parse_object_args(62, _Params, _Data) -> - pp_cube; - -%% @todo Used at the hot springs dressing room. -parse_object_args(63, _Params, _Data) -> - unknown_object_63; - -parse_object_args(64, _Params, _Data) -> - colored_minimap_section; - -parse_object_args(65, _Params, _Data) -> - room_decoration_slot; - -%% @todo Used for the offering box on shitenkaku. -parse_object_args(66, _Params, _Data) -> - unknown_object_66; - -%% @todo Also used for the two ladies: one that gives coins, another that exchanges coins. -parse_object_args(67, _Params, _Data) -> - casino_bets; - -parse_object_args(68, _Params, _Data) -> - casino_slots; - -%% @todo Apparently is in a version of the room that we aren't using yet. -parse_object_args(69, _Params, _Data) -> - unknown_object_69; - -%% @todo Seems to be a megid turret "trap". -parse_object_args(70, _Params, _Data) -> - trap; - -%% @todo Seems to be a ceiling fall-on-you-and-explode "trap". Possibly also poison room. Apparently also fake key. -parse_object_args(71, _Params, _Data) -> - trap. - -convert_eventid(16#ffff) -> - false; -convert_eventid(RawEventID) -> - RawEventID. - -%% @doc Log message to the console. - -log(_Message) -> - ok. - %~ io:format("~s~n", [_Message]). - -log(Message, Format) -> - FormattedMessage = io_lib:format(Message, Format), - log(FormattedMessage).