diff --git a/src/psu/psu_game.erl b/src/psu/psu_game.erl index 144b43f..8d01b70 100644 --- a/src/psu/psu_game.erl +++ b/src/psu/psu_game.erl @@ -608,7 +608,41 @@ event({item_unequip, ItemID, TargetGID, TargetLID, A, B}) -> _ -> 1 % weapons end, send(<< 16#01050300:32, 0:64, GID:32/little-unsigned-integer, 0:64, 16#00011300:32, GID:32/little-unsigned-integer, - 0:64, TargetGID:32/little-unsigned-integer, TargetLID:32/little-unsigned-integer, ItemID, 2, Category, A, B:32/little-unsigned-integer >>). + 0:64, TargetGID:32/little-unsigned-integer, TargetLID:32/little-unsigned-integer, ItemID, 2, Category, A, B:32/little-unsigned-integer >>); + +%% @doc Uni cube handler. +event(unicube_request) -> + send_021e(); + +%% @doc Uni selection handler. +%% @todo When selecting 'Your room', load a default room. +%% @todo When selecting 'Reload', reload the character in the current lobby. +event({unicube_select, Selection, EntryID}) -> + case Selection of + cancel -> ignore; + 16#ffffffff -> + log("uni selection (my room)"), + send_0230(), + % 0220 + area_load(1120000, 0, 100, 0); + _UniID -> + log("uni selection (reload)"), + send_0230(), + % 0220 + %% force reloading the character and data files (@todo hack, uses myroom questid to do it) + {ok, User} = egs_user_model:read(get(gid)), + if User#egs_user_model.partypid =:= undefined -> + ignore; + true -> + %% @todo Replace stop by leave when leaving stops the party correctly when nobody's there anymore. + %~ psu_party:leave(User#egs_user_model.partypid, User#egs_user_model.id) + psu_party:stop(User#egs_user_model.partypid) + end, + Area = User#egs_user_model.area, + NewRow = User#egs_user_model{partypid=undefined, area=Area#psu_area{questid=1120000, zoneid=undefined}, entryid=EntryID}, + egs_user_model:write(NewRow), + area_load(Area#psu_area.questid, Area#psu_area.zoneid, Area#psu_area.mapid, EntryID) + end. %% @doc Movement (non-broadcast) handler. Do nothing. handle(16#0102, _) -> @@ -653,42 +687,6 @@ handle(16#0110, Data) -> log("unknown 0110 (~b, ~b, ~b)", [A, B, C]) end; -%% @doc Uni cube handler. -handle(16#021d, _) -> - send_021e(); - -%% @doc Uni selection handler. -%% When selecting 'Your room', load a default room. -%% When selecting 'Reload', reload the character in the current lobby. -%% @todo There's probably an entryid given in the uni selection packet. -handle(16#021f, << Uni:32/little-unsigned-integer, _/bits >>) -> - case Uni of - 0 -> % cancelled uni selection - ignore; - 16#ffffffff -> - log("uni selection (my room)"), - send_0230(), - % 0220 - area_load(1120000, 0, 100, 0); - _ -> - log("uni selection (reload)"), - send_0230(), - % 0220 - % force reloading the character and data files (hack) - {ok, User} = egs_user_model:read(get(gid)), - if User#egs_user_model.partypid =:= undefined -> - ignore; - true -> - %% @todo Replace stop by leave when leaving stops the party correctly when nobody's there anymore. - %~ psu_party:leave(User#egs_user_model.partypid, User#egs_user_model.id) - psu_party:stop(User#egs_user_model.partypid) - end, - Area = User#egs_user_model.area, - NewRow = User#egs_user_model{partypid=undefined, area=Area#psu_area{questid=1120000, zoneid=undefined}}, - egs_user_model:write(NewRow), - area_load(Area#psu_area.questid, Area#psu_area.zoneid, Area#psu_area.mapid, User#egs_user_model.entryid) - end; - %% @doc Shortcut changes handler. Do nothing. %% @todo Save it. handle(16#0302, _) -> diff --git a/src/psu/psu_proto.erl b/src/psu/psu_proto.erl index c8b83b0..89c0453 100644 --- a/src/psu/psu_proto.erl +++ b/src/psu/psu_proto.erl @@ -53,7 +53,7 @@ parse(<< Size:32/little, Command:16, Channel:8, _Unknown:8, Data/bits >>) -> %% @todo One of the missing events is probably learning a new PA. parse(Size, 16#0105, Channel, Data) -> - << _VarA:16/little, _VarB:16/little, VarC:32/little, _FromGID:32/little, VarD:32/little, VarE:32/little, TypeID:32/little, GID:32/little, + << _LID:16/little, _VarB:16/little, VarC:32/little, _FromGID:32/little, VarD:32/little, VarE:32/little, TypeID:32/little, GID:32/little, VarF:32/little, VarG:32/little, TargetGID:32/little, TargetLID:32/little, ItemID:8, EventID:8, _PAID:8, VarH:8, VarI:32/little, Rest/bits >> = Data, ?ASSERT_EQ(Channel, 2), ?ASSERT_EQ(VarC, 0), @@ -89,6 +89,42 @@ parse(Size, 16#0105, Channel, Data) -> {Event, ItemID, TargetGID, TargetLID, VarH, VarI} end; +parse(Size, 16#021d, Channel, Data) -> + << _LID:16/little, VarB:16/little, VarC:32/little, VarD:32/little, VarE:32/little, VarF:32/little, + VarG:32/little, VarH:32/little, VarI:32/little, VarJ:32/little, _EntryID:32/little >> = Data, + ?ASSERT_EQ(Size, 48), + ?ASSERT_EQ(Channel, 2), + ?ASSERT_EQ(VarB, 0), + ?ASSERT_EQ(VarC, 0), + ?ASSERT_EQ(VarD, 0), + ?ASSERT_EQ(VarE, 0), + ?ASSERT_EQ(VarF, 0), + ?ASSERT_EQ(VarG, 0), + ?ASSERT_EQ(VarH, 0), + ?ASSERT_EQ(VarI, 0), + ?ASSERT_EQ(VarJ, 0), + unicube_request; + +parse(Size, 16#021f, Channel, Data) -> + << _LID:16/little, VarB:16/little, VarC:32/little, VarD:32/little, VarE:32/little, VarF:32/little, + VarG:32/little, VarH:32/little, VarI:32/little, VarJ:32/little, UniID:32/little, EntryID:32/little >> = Data, + ?ASSERT_EQ(Size, 52), + ?ASSERT_EQ(Channel, 2), + ?ASSERT_EQ(VarB, 0), + ?ASSERT_EQ(VarC, 0), + ?ASSERT_EQ(VarD, 0), + ?ASSERT_EQ(VarE, 0), + ?ASSERT_EQ(VarF, 0), + ?ASSERT_EQ(VarG, 0), + ?ASSERT_EQ(VarH, 0), + ?ASSERT_EQ(VarI, 0), + ?ASSERT_EQ(VarJ, 0), + Selection = case UniID of + 0 -> cancel; + _ -> UniID + end, + {unicube_select, Selection, EntryID}; + parse(Size, 16#0b05, _Channel, _Data) -> ?ASSERT_EQ(Size, 8), ignore;