diff --git a/include/maps.hrl b/include/maps.hrl index 2047e0f..7c7531f 100644 --- a/include/maps.hrl +++ b/include/maps.hrl @@ -145,6 +145,26 @@ {1003023, [{type, mission}, {file, "data/missions/black-nest.3.s.quest.nbl"}, {start, [0, 6803, 0]}]}, %~ {1003024, [{type, mission}, {file, "data/missions/black-nest.3.s2.quest.nbl"}, {start, [0, 6803, 0]}]}, + % The Dark God + + {1003100, [{type, mission}, {file, "data/missions/dark-god.1.c.quest.nbl"}, {start, [0, 6302, 0]}]}, + %~ {1003101, [{type, mission}, {file, "data/missions/dark-god.1.b.quest.nbl"}, {start, [0, 6302, 0]}]}, + {1003102, [{type, mission}, {file, "data/missions/dark-god.1.a.quest.nbl"}, {start, [0, 6302, 0]}]}, + {1003103, [{type, mission}, {file, "data/missions/dark-god.1.s.quest.nbl"}, {start, [0, 6302, 0]}]}, + {1003104, [{type, mission}, {file, "data/missions/dark-god.1.s2.quest.nbl"}, {start, [0, 6302, 0]}]}, + + {1003110, [{type, mission}, {file, "data/missions/dark-god.2.c.quest.nbl"}, {start, [0, 6304, 0]}]}, + {1003111, [{type, mission}, {file, "data/missions/dark-god.2.b.quest.nbl"}, {start, [0, 6304, 0]}]}, + {1003112, [{type, mission}, {file, "data/missions/dark-god.2.a.quest.nbl"}, {start, [0, 6304, 0]}]}, + {1003113, [{type, mission}, {file, "data/missions/dark-god.2.s.quest.nbl"}, {start, [0, 6304, 0]}]}, + {1003114, [{type, mission}, {file, "data/missions/dark-god.2.s2.quest.nbl"}, {start, [0, 6304, 0]}]}, + + {1003120, [{type, mission}, {file, "data/missions/dark-god.3.c.quest.nbl"}, {start, [0, 6302, 0]}]}, + {1003121, [{type, mission}, {file, "data/missions/dark-god.3.b.quest.nbl"}, {start, [0, 6302, 0]}]}, + {1003122, [{type, mission}, {file, "data/missions/dark-god.3.a.quest.nbl"}, {start, [0, 6302, 0]}]}, + {1003123, [{type, mission}, {file, "data/missions/dark-god.3.s.quest.nbl"}, {start, [0, 6302, 0]}]}, + {1003124, [{type, mission}, {file, "data/missions/dark-god.3.s2.quest.nbl"}, {start, [0, 6302, 0]}]}, + % Phantom Ruins (Linear Line counter) %~ {1060300, [{type, mission}, {file, "data/missions/phantom-ruins.c.quest.nbl"}, {start, [0, 8002, 0]}]}, @@ -346,6 +366,44 @@ {[1003023, 0], [{file, "data/missions/black-nest.3.s.zone.nbl"}]}, %~ {[1003024, 0], [{file, "data/missions/black-nest.3.s2.zone.nbl"}]}, + % The Dark God + + {[1003100, 0], [{file, "data/missions/dark-god.1.c.zone-0.nbl"}]}, + {[1003100, 1], [{file, "data/missions/dark-god.1.c.zone-1.nbl"}]}, + %~ {[1003101, 0], [{file, "data/missions/dark-god.1.b.zone-0.nbl"}]}, + %~ {[1003101, 1], [{file, "data/missions/dark-god.1.b.zone-1.nbl"}]}, + {[1003102, 0], [{file, "data/missions/dark-god.1.a.zone-0.nbl"}]}, + %~ {[1003102, 1], [{file, "data/missions/dark-god.1.a.zone-1.nbl"}]}, + {[1003103, 0], [{file, "data/missions/dark-god.1.s.zone-0.nbl"}]}, + {[1003103, 1], [{file, "data/missions/dark-god.1.s.zone-1.nbl"}]}, + {[1003104, 0], [{file, "data/missions/dark-god.1.s2.zone-0.nbl"}]}, + {[1003104, 1], [{file, "data/missions/dark-god.1.s2.zone-1.nbl"}]}, + {[1003104, 2], [{file, "data/missions/dark-god.1.s2.zone-2.nbl"}]}, + + {[1003110, 0], [{file, "data/missions/dark-god.2.c.zone-0.nbl"}]}, + {[1003110, 1], [{file, "data/missions/dark-god.2.c.zone-1.nbl"}]}, + {[1003111, 0], [{file, "data/missions/dark-god.2.b.zone-0.nbl"}]}, + {[1003111, 1], [{file, "data/missions/dark-god.2.b.zone-1.nbl"}]}, + {[1003112, 0], [{file, "data/missions/dark-god.2.a.zone-0.nbl"}]}, + {[1003112, 1], [{file, "data/missions/dark-god.2.a.zone-1.nbl"}]}, + {[1003113, 0], [{file, "data/missions/dark-god.2.s.zone-0.nbl"}]}, + %~ {[1003113, 1], [{file, "data/missions/dark-god.2.s.zone-1.nbl"}]}, + {[1003114, 0], [{file, "data/missions/dark-god.2.s2.zone-0.nbl"}]}, + {[1003114, 1], [{file, "data/missions/dark-god.2.s2.zone-1.nbl"}]}, + {[1003114, 2], [{file, "data/missions/dark-god.2.s2.zone-2.nbl"}]}, + + {[1003120, 0], [{file, "data/missions/dark-god.3.c.zone-0.nbl"}]}, + {[1003120, 1], [{file, "data/missions/dark-god.3.c.zone-1.nbl"}]}, + {[1003121, 0], [{file, "data/missions/dark-god.3.b.zone-0.nbl"}]}, + {[1003121, 1], [{file, "data/missions/dark-god.3.b.zone-1.nbl"}]}, + {[1003122, 0], [{file, "data/missions/dark-god.3.a.zone-0.nbl"}]}, + {[1003122, 1], [{file, "data/missions/dark-god.3.a.zone-1.nbl"}]}, + {[1003123, 0], [{file, "data/missions/dark-god.3.s.zone-0.nbl"}]}, + {[1003123, 1], [{file, "data/missions/dark-god.3.s.zone-1.nbl"}]}, + {[1003124, 0], [{file, "data/missions/dark-god.3.s2.zone-0.nbl"}]}, + {[1003124, 1], [{file, "data/missions/dark-god.3.s2.zone-1.nbl"}]}, + {[1003124, 2], [{file, "data/missions/dark-god.3.s2.zone-2.nbl"}]}, + % Phantom Ruins (Linear Line counter) %~ {[1060300, 0], [{file, "data/missions/phantom-ruins.c-0.zone.nbl"}]}, @@ -1064,13 +1122,20 @@ % Rykros (entry 1): Phantom Ruins, The Dark God - {201, [{quests, "data/counters/colony.rykros-1.pack"}, {bg, 255}, {options, << 16#01d11c00:32, 3, 3, - 3, 3, 3, 3, 0, % Phantom Ruins C-S - 3, 3, 3, 3, 3, 0, % The Dark God C-S2 variant 1 + {201, [{quests, "data/counters/colony.rykros-1.pack"}, {bg, 255}, {options, << 16#01d11c00:32, 0, 3, + 0, 0, 0, 0, 0, % Phantom Ruins C-S + 3, 0, 3, 3, 3, 0, % The Dark God C-S2 variant 1 3, 3, 3, 3, 3, 0, % The Dark God C-S2 variant 2 3, 3, 3, 3, 3, 0, % The Dark God C-S2 variant 3 0:24 >>}]}, + %~ {201, [{quests, "data/counters/colony.rykros-1.pack"}, {bg, 255}, {options, << 16#01d11c00:32, 3, 3, + %~ 3, 3, 3, 3, 0, % Phantom Ruins C-S + %~ 3, 3, 3, 3, 3, 0, % The Dark God C-S2 variant 1 + %~ 3, 3, 3, 3, 3, 0, % The Dark God C-S2 variant 2 + %~ 3, 3, 3, 3, 3, 0, % The Dark God C-S2 variant 3 + %~ 0:24 >>}]}, + % Falz Memoria {203, [{quests, "data/counters/colony.memoria.pack"}, {bg, 255}, {options, << 16#01013800:32, 0:448 >>}]}, diff --git a/src/psu_missions.erl b/src/psu_missions.erl index cc09c22..cf642e2 100644 --- a/src/psu_missions.erl +++ b/src/psu_missions.erl @@ -56,6 +56,9 @@ object_init(InstanceID, BlockID, [floor_button|Tail], ListNb, ObjectNb, ObjectID %% @todo Apparently shoot_button has a TargetID. I'm sure why though. object_init(InstanceID, BlockID, [shoot_button|Tail], ListNb, ObjectNb, ObjectID, TargetID) -> object_init(InstanceID, BlockID, Tail, ListNb, ObjectNb + 1, ObjectID + 1, TargetID + 1); +%% @todo Goggle targets have a targetid. +object_init(InstanceID, BlockID, [goggle_target|Tail], ListNb, ObjectNb, ObjectID, TargetID) -> + object_init(InstanceID, BlockID, Tail, ListNb, ObjectNb + 1, ObjectID + 1, TargetID + 1); %% @todo All kinds of traps have a TargetID, even if they're not targettable. object_init(InstanceID, BlockID, [trap|Tail], ListNb, ObjectNb, ObjectID, TargetID) -> object_init(InstanceID, BlockID, Tail, ListNb, ObjectNb + 1, ObjectID + 1, TargetID + 1); diff --git a/src/psu_parser.erl b/src/psu_parser.erl index 3796db4..2c04353 100644 --- a/src/psu_parser.erl +++ b/src/psu_parser.erl @@ -114,7 +114,6 @@ parse_object_list(BasePtr, Data, NbObjects, Ptr) -> parse_object_list_rec(_Data, 0, Acc) -> lists:reverse(Acc); parse_object_list_rec(Data, NbObjects, Acc) -> - % todo x z y ?? << 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, @@ -138,17 +137,20 @@ parse_object_args(6, _Params, _Data) -> 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, - 16#ffffffff:32, 16#ffffffff:32, 16#ffffffff:32, RawTrigEvent:16/little-unsigned-integer, - 16#ffffffff:32, 16#ffffffff:32, 16#ffffffff:32, 16#ffffffff:32, 16#ffffffff:32, 16#ffffffff:32, 16#ffffffff:32, 16#ffffffff:32, 0:16, _/bits >> = Data, + 16#ffffffff:32, 16#ffffffff:32, 16#ffffffff:32, RawTrigEvent:16/little-unsigned-integer, 16#ffffffff:32, 16#ffffffff:32, 16#ffffffff:32, + 16#ffff:16, UnknownG:16/little-unsigned-integer, 16#ffffffff:32, 16#ffffffff:32, 16#ffffffff:32, 16#ffff:16, UnknownH:16/little-unsigned-integer, 0:16, _/bits >> = Data, Breakable = case UnknownB of 0 -> false; - 1 -> true + 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) trigevent(~p)", [Model, UnknownA, Breakable, UnknownC, Scale, UnknownD, UnknownE, UnknownF, TrigEvent]), + log("box: model(~b) a(~b) breakable(~p) c(~b) scale(~b) d(~b) e(~b) f(~b) trigevent(~p) g(~b) h(~b)", [Model, UnknownA, Breakable, UnknownC, Scale, UnknownD, UnknownE, UnknownF, TrigEvent, UnknownG, UnknownH]), {box, Model, Breakable, TrigEvent}; parse_object_args(14, {params, {pos, PosX, PosY, PosZ}, _Rot}, Data) -> @@ -199,12 +201,12 @@ parse_object_args(27, _Params, _Data) -> 'exit'; parse_object_args(31, _Params, Data) -> - << KeySet:8, UnknownB:8, 16#0001:16, 16#ffff:16, RawTrigEvent:16/little-unsigned-integer, RawReqEvent:16/little-unsigned-integer, 16#ffff:16, - 16#ffffffff:32, 16#ffffffff:32, 16#ffffffff:32, _/bits >> = Data, + << KeySet:8, UnknownA:8, UnknownB:8, 1: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, _/bits >> = Data, TrigEvent = convert_eventid(RawTrigEvent), - ReqEvent = convert_eventid(RawReqEvent), - log("key: keyset(~b) b(~b) trigevent(~p) reqevent(~p)", [KeySet, UnknownB, TrigEvent, ReqEvent]), - {key, KeySet, TrigEvent, ReqEvent}; + ReqEvents = [convert_eventid(RawReqEvent1), convert_eventid(RawReqEvent2), convert_eventid(RawReqEvent3)], + log("key: keyset(~b) a(~b) b(~b) trigevent(~p) reqevents(~p)", [KeySet, UnknownA, UnknownB, TrigEvent, ReqEvents]), + {key, KeySet, TrigEvent, ReqEvents}; parse_object_args(35, _Params, _Data) -> boss; @@ -226,6 +228,9 @@ parse_object_args(49, _Params, _Data) -> parse_object_args(50, _Params, _Data) -> healing_pad; +parse_object_args(51, _Params, _Data) -> + goggle_target; + parse_object_args(53, _Params, _Data) -> label;