diff --git a/src/egs_game.erl b/src/egs_game.erl index b2e72e4..f65a7d8 100644 --- a/src/egs_game.erl +++ b/src/egs_game.erl @@ -838,14 +838,13 @@ handle(16#0e00, Data) -> %% @todo B should be the ObjType. handle(16#0f0a, Data) -> - << BlockID:16/little-unsigned-integer, _:16, ObjectNb:16/little-unsigned-integer, _MapID:16/little-unsigned-integer, ObjectID:16/little-unsigned-integer, + << BlockID:16/little-unsigned-integer, ListNb:16/little-unsigned-integer, ObjectNb:16/little-unsigned-integer, _MapID:16/little-unsigned-integer, ObjectID:16/little-unsigned-integer, _:16, A:32/little-unsigned-integer, B:32/little-unsigned-integer, _:32, C:32/little-unsigned-integer, _:272, Action:8, _/bits >> = Data, - log("~p", [Data]), log("object event handler: action ~b object ~b a ~b b ~b c ~b", [Action, ObjectID, A, B, C]), case Action of 0 -> % warp User = egs_db:users_select(get(gid)), - {X, Y, Z, Dir} = psu_missions:warp_event(User#users.instanceid, BlockID, ObjectNb), + {X, Y, Z, Dir} = psu_missions:warp_event(User#users.instanceid, BlockID, ListNb, ObjectNb), NewUser = User#users{pos=#pos{x=X, y=Y, z=Z, dir=Dir}}, egs_db:users_insert(NewUser), send_0503(User#users.pos), diff --git a/src/psu_missions.erl b/src/psu_missions.erl index 2824d48..29302cb 100644 --- a/src/psu_missions.erl +++ b/src/psu_missions.erl @@ -18,7 +18,7 @@ -module(psu_missions). -export([ - start/3, stop/1, key_event/2, warp_event/3, object_hit/3, spawn_cleared/2 + start/3, stop/1, key_event/2, warp_event/4, object_hit/3, spawn_cleared/2 ]). -include("include/missions.hrl"). @@ -32,54 +32,60 @@ map_init(_InstanceID, [], _BlockID, _ObjectID, _TargetID) -> ok; map_init(InstanceID, [Map|Tail], BlockID, ObjectID, TargetID) -> {_MapID, Objects} = Map, - {ok, NewObjectID, NewTargetID} = object_init(InstanceID, BlockID, Objects, 0, ObjectID, TargetID), + {ok, NewObjectID, NewTargetID} = list_init(InstanceID, BlockID, Objects, 0, ObjectID, TargetID), map_init(InstanceID, Tail, BlockID + 1, NewObjectID, NewTargetID). -object_init(_InstanceID, _BlockID, [], _ObjectNb, ObjectID, TargetID) -> +list_init(_InstanceID, _BlockID, [], _ListNb, ObjectID, TargetID) -> {ok, ObjectID, TargetID}; -object_init(InstanceID, BlockID, [{box, _Model, Breakable, TrigEventID}|Tail], ObjectNb, ObjectID, TargetID) -> +list_init(InstanceID, BlockID, [Objects|Tail], ListNb, ObjectID, TargetID) -> + {ok, NewObjectID, NewTargetID} = object_init(InstanceID, BlockID, Objects, ListNb, 0, ObjectID, TargetID), + list_init(InstanceID, BlockID, Tail, ListNb + 1, NewObjectID, NewTargetID). + +object_init(_InstanceID, _BlockID, [], _ListNb, _ObjectNb, ObjectID, TargetID) -> + {ok, ObjectID, TargetID}; +object_init(InstanceID, BlockID, [{box, _Model, Breakable, TrigEventID}|Tail], ListNb, ObjectNb, ObjectID, TargetID) -> case Breakable of false -> ignore; true -> egs_db:objects_insert(#objects{id=[InstanceID, ObjectID], instanceid=InstanceID, objectid=ObjectID, type=box, targetid=TargetID, blockid=BlockID, triggereventid=TrigEventID}) end, - object_init(InstanceID, BlockID, Tail, ObjectNb + 1, ObjectID + 1, TargetID + 1); + object_init(InstanceID, BlockID, Tail, ListNb, ObjectNb + 1, ObjectID + 1, TargetID + 1); %% @todo key and key_console event handling will have to be fixed. -object_init(InstanceID, BlockID, [{key, _KeySet, TrigEventID, _ReqEventID}|Tail], ObjectNb, ObjectID, TargetID) -> +object_init(InstanceID, BlockID, [{key, _KeySet, TrigEventID, _ReqEventID}|Tail], ListNb, ObjectNb, ObjectID, TargetID) -> egs_db:objects_insert(#objects{id=[InstanceID, {key, ObjectID}], instanceid=InstanceID, objectid=ObjectID, type=key, blockid=BlockID, triggereventid=[TrigEventID]}), - object_init(InstanceID, BlockID, Tail, ObjectNb + 1, ObjectID + 1, TargetID); + object_init(InstanceID, BlockID, Tail, ListNb, ObjectNb + 1, ObjectID + 1, TargetID); %% @todo Maybe separate key from key_console in its handling? -object_init(InstanceID, BlockID, [{key_console, KeySet, _ReqKeyEventsID, TrigEventID}|Tail], ObjectNb, ObjectID, TargetID) -> +object_init(InstanceID, BlockID, [{key_console, KeySet, _ReqKeyEventsID, TrigEventID}|Tail], ListNb, ObjectNb, ObjectID, TargetID) -> egs_db:objects_insert(#objects{id=[InstanceID, {key, ObjectID}], instanceid=InstanceID, objectid=ObjectID, type=key, blockid=BlockID, triggereventid=[243 + KeySet, 201 + KeySet, TrigEventID]}), - object_init(InstanceID, BlockID, Tail, ObjectNb + 1, ObjectID + 1, TargetID); + object_init(InstanceID, BlockID, Tail, ListNb, ObjectNb + 1, ObjectID + 1, TargetID); %% @todo save enemies individually, do something, etc. %% @todo temporarily save the spawn to handle events properly -object_init(InstanceID, BlockID, [{'spawn', TrigEventID, _ReqEventID}|Tail], ObjectNb, ObjectID, TargetID) -> +object_init(InstanceID, BlockID, [{'spawn', TrigEventID, _ReqEventID}|Tail], ListNb, ObjectNb, ObjectID, TargetID) -> egs_db:objects_insert(#objects{id=[InstanceID, {'spawn', TargetID - 1024}], instanceid=InstanceID, type='spawn', blockid=BlockID, triggereventid=TrigEventID}), - object_init(InstanceID, BlockID, Tail, ObjectNb + 1, ObjectID + 1, TargetID + 30); -object_init(InstanceID, BlockID, [{warp, DestX, DestY, DestZ, DestDir}|Tail], ObjectNb, ObjectID, TargetID) -> - egs_db:objects_insert(#objects{id=[InstanceID, {warp, BlockID, ObjectNb}], instanceid=InstanceID, type=warp, blockid=BlockID, args={DestX, DestY, DestZ, DestDir}}), - object_init(InstanceID, BlockID, Tail, ObjectNb + 1, ObjectID, TargetID); + object_init(InstanceID, BlockID, Tail, ListNb, ObjectNb + 1, ObjectID + 1, TargetID + 30); +object_init(InstanceID, BlockID, [{warp, DestX, DestY, DestZ, DestDir}|Tail], ListNb, ObjectNb, ObjectID, TargetID) -> + egs_db:objects_insert(#objects{id=[InstanceID, {warp, BlockID, ListNb, ObjectNb}], instanceid=InstanceID, type=warp, blockid=BlockID, args={DestX, DestY, DestZ, DestDir}}), + object_init(InstanceID, BlockID, Tail, ListNb, ObjectNb + 1, ObjectID, TargetID); %% @todo Not sure where these 2 come from yet, assuming crystal but might not be that. -object_init(InstanceID, BlockID, [crystal|Tail], ObjectNb, ObjectID, TargetID) -> - object_init(InstanceID, BlockID, Tail, ObjectNb + 1, ObjectID + 1, TargetID + 2); +object_init(InstanceID, BlockID, [crystal|Tail], ListNb, ObjectNb, ObjectID, TargetID) -> + object_init(InstanceID, BlockID, Tail, ListNb, ObjectNb + 1, ObjectID + 1, TargetID + 2); %~ %% @todo Not sure where these 9 come from yet, assuming healing pad + pp cube but might not be that. %~ object_init(InstanceID, BlockID, [healing_pad|Tail], ObjectID, TargetID) -> %~ object_init(InstanceID, BlockID, Tail, ObjectID + 1, TargetID + 9); %~ object_init(InstanceID, BlockID, [pp_cube|Tail], ObjectID, TargetID) -> %~ object_init(InstanceID, BlockID, Tail, ObjectID + 1, TargetID + 1); %% A few object types don't have an ObjectID nor a TargetID. Disregard them completely. -object_init(InstanceID, BlockID, [ObjType|Tail], ObjectNb, ObjectID, TargetID) +object_init(InstanceID, BlockID, [ObjType|Tail], ListNb, ObjectNb, ObjectID, TargetID) when ObjType =:= static_model; ObjType =:= invisible_block; ObjType =:= entrance; ObjType =:= 'exit'; ObjType =:= label; ObjType =:= hidden_minimap_section -> - object_init(InstanceID, BlockID, Tail, ObjectNb + 1, ObjectID, TargetID); + object_init(InstanceID, BlockID, Tail, ListNb, ObjectNb + 1, ObjectID, TargetID); %% Others are normal objects, we don't handle them but they have an ObjectID. -object_init(InstanceID, BlockID, [_|Tail], ObjectNb, ObjectID, TargetID) -> - object_init(InstanceID, BlockID, Tail, ObjectNb + 1, ObjectID + 1, TargetID). +object_init(InstanceID, BlockID, [_|Tail], ListNb, ObjectNb, ObjectID, TargetID) -> + object_init(InstanceID, BlockID, Tail, ListNb, ObjectNb + 1, ObjectID + 1, TargetID). stop(InstanceID) -> egs_db:objects_delete(InstanceID). @@ -88,8 +94,8 @@ key_event(InstanceID, ObjectID) -> #objects{triggereventid=EventID, blockid=BlockID} = egs_db:objects_select([InstanceID, {key, ObjectID}]), [EventID, BlockID]. -warp_event(InstanceID, BlockID, ObjectNb) -> - #objects{args=Args} = egs_db:objects_select([InstanceID, {warp, BlockID, ObjectNb}]), +warp_event(InstanceID, BlockID, ListNb, ObjectNb) -> + #objects{args=Args} = egs_db:objects_select([InstanceID, {warp, BlockID, ListNb, ObjectNb}]), Args. object_hit(User, _SourceID, TargetID) -> diff --git a/src/psu_parser.erl b/src/psu_parser.erl index 18d5f8b..0e635d2 100644 --- a/src/psu_parser.erl +++ b/src/psu_parser.erl @@ -45,7 +45,7 @@ parse_zone(QuestID, NblFilename) -> 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 = {QuestID, [{MapID, lists:flatten(parse_object_list_headers(BasePtr, Data, NbHeaders, ObjListHeadersPtr - BasePtr - 16))} || {MapID, NbHeaders, ObjListHeadersPtr} <- MapList]}, + ObjList = {QuestID, [{MapID, parse_object_list_headers(BasePtr, Data, NbHeaders, ObjListHeadersPtr - BasePtr - 16)} || {MapID, NbHeaders, ObjListHeadersPtr} <- MapList]}, nbl_cleanup(), ObjList.