psu_proto: Add a new event: party_remove_member. NPCs can now be removed from the party.
This commit is contained in:
parent
bab8913645
commit
f785b290bb
@ -220,9 +220,9 @@ char_load(User) ->
|
||||
send_0d01(User),
|
||||
% 0246
|
||||
send_0a0a(),
|
||||
send_1006(5),
|
||||
send_1006(5, 0),
|
||||
send_1005((User#egs_user_model.character)#characters.name),
|
||||
send_1006(12),
|
||||
send_1006(12, 0),
|
||||
send_0210(),
|
||||
send_0222(),
|
||||
send_1500(User),
|
||||
@ -450,7 +450,8 @@ loop(SoFar) ->
|
||||
send_0233(SpawnList),
|
||||
?MODULE:loop(SoFar);
|
||||
{psu_player_unspawn, Spawn} ->
|
||||
send_0204(Spawn#egs_user_model.id, Spawn#egs_user_model.lid, 5),
|
||||
{ok, User} = egs_user_model:read(get(gid)),
|
||||
send_0204(User, Spawn, 5),
|
||||
?MODULE:loop(SoFar);
|
||||
{psu_warp, QuestID, ZoneID, MapID, EntryID} ->
|
||||
event({area_change, QuestID, ZoneID, MapID, EntryID}),
|
||||
@ -754,7 +755,7 @@ event(lumilass_options_request) ->
|
||||
|
||||
%% @todo Probably replenish the player HP when entering a non-mission area rather than when aborting the mission?
|
||||
event(mission_abort) ->
|
||||
send_1006(11),
|
||||
send_1006(11, 0),
|
||||
{ok, User} = egs_user_model:read(get(gid)),
|
||||
%% delete the mission
|
||||
if User#egs_user_model.instancepid =:= undefined -> ignore;
|
||||
@ -956,6 +957,20 @@ event({object_warp_take, BlockID, ListNb, ObjectNb}) ->
|
||||
send_0503(User#egs_user_model.pos),
|
||||
send_1211(16#ffffffff, 0, 14, 0);
|
||||
|
||||
event({party_remove_member, PartyPos}) ->
|
||||
log("party remove member ~b", [PartyPos]),
|
||||
{ok, DestUser} = egs_user_model:read(get(gid)),
|
||||
{ok, RemovedGID} = psu_party:get_member(DestUser#egs_user_model.partypid, PartyPos),
|
||||
psu_party:remove_member(DestUser#egs_user_model.partypid, PartyPos),
|
||||
{ok, RemovedUser} = egs_user_model:read(RemovedGID),
|
||||
case (RemovedUser#egs_user_model.character)#characters.type of
|
||||
npc -> egs_user_model:delete(RemovedGID);
|
||||
_ -> ignore
|
||||
end,
|
||||
send_1006(8, PartyPos),
|
||||
send_0204(DestUser, RemovedUser, 1),
|
||||
psu_proto:send_0215(DestUser, 0);
|
||||
|
||||
event({player_options_change, Options}) ->
|
||||
{ok, User} = egs_user_model:read(get(gid)),
|
||||
file:write_file(io_lib:format("save/~s/~b-character.options", [User#egs_user_model.folder, (User#egs_user_model.character)#characters.slot]), Options);
|
||||
@ -1174,11 +1189,16 @@ send_0202() ->
|
||||
send(<< 16#02020300:32, 0:352 >>).
|
||||
|
||||
%% @todo Not sure. Used for unspawning, and more.
|
||||
send_0204(PlayerGID, PlayerLID, Action) ->
|
||||
GID = get(gid),
|
||||
send(<< 16#02040300:32, 0:32, 16#00001200:32, PlayerGID:32/little-unsigned-integer, 0:64,
|
||||
16#00011300:32, GID:32/little-unsigned-integer, 0:64, PlayerGID:32/little-unsigned-integer,
|
||||
PlayerLID:32/little-unsigned-integer, Action:32/little-unsigned-integer >>).
|
||||
send_0204(DestUser, TargetUser, Action) ->
|
||||
DestGID = DestUser#egs_user_model.id,
|
||||
TargetTypeID = case (TargetUser#egs_user_model.character)#characters.type of
|
||||
npc -> 16#00001d00;
|
||||
_ -> 16#00001200
|
||||
end,
|
||||
#egs_user_model{id=TargetGID, lid=TargetLID} = TargetUser,
|
||||
send(<< 16#02040300:32, 0:32, TargetTypeID:32, TargetGID:32/little-unsigned-integer, 0:64,
|
||||
16#00011300:32, DestGID:32/little-unsigned-integer, 0:64, TargetGID:32/little-unsigned-integer,
|
||||
TargetLID:32/little-unsigned-integer, Action:32/little-unsigned-integer >>).
|
||||
|
||||
%% @doc Indicate to the client that loading should finish.
|
||||
%% @todo Last value seems to be 2 most of the time. Never 0 though. Apparently counters have it at 4.
|
||||
@ -1414,10 +1434,9 @@ send_1005(Name) ->
|
||||
send(<< (header(16#1005))/binary, Before/binary, GID:32/little-unsigned-integer, 0:64, Name/binary, After/binary >>).
|
||||
|
||||
%% @doc Party-related command probably controlling the party state.
|
||||
%% Value 11 aborts the mission.
|
||||
%% @todo Figure out what the packet is.
|
||||
send_1006(N) ->
|
||||
send(<< (header(16#1006))/binary, N:32/little-unsigned-integer >>).
|
||||
%% EventID 11 aborts the mission.
|
||||
send_1006(EventID, PartyPos) ->
|
||||
send(<< (header(16#1006))/binary, EventID:8, PartyPos:8, 0:16 >>).
|
||||
|
||||
%% @doc Send the player's current location.
|
||||
send_100e(QuestID, ZoneID, MapID, Location, CounterID) ->
|
||||
|
@ -19,7 +19,7 @@
|
||||
|
||||
-module(psu_party).
|
||||
-behavior(gen_server).
|
||||
-export([start_link/1, stop/1, join/3, leave/2, get_instance/1, set_instance/2, remove_instance/1, get_npc/1]). %% API.
|
||||
-export([start_link/1, stop/1, join/3, leave/2, get_instance/1, set_instance/2, remove_instance/1, get_member/2, remove_member/2, get_npc/1]). %% API.
|
||||
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). %% gen_server.
|
||||
|
||||
-record(state, {free_spots, users, instancepid}).
|
||||
@ -50,6 +50,14 @@ set_instance(PartyPid, InstancePid) ->
|
||||
remove_instance(PartyPid) ->
|
||||
gen_server:cast(PartyPid, remove_instance).
|
||||
|
||||
%% @doc Return the user at the given position.
|
||||
get_member(PartyPid, Spot) ->
|
||||
gen_server:call(PartyPid, {get_member, Spot}).
|
||||
|
||||
%% @doc Remove a member from the party.
|
||||
remove_member(PartyPid, Spot) ->
|
||||
gen_server:cast(PartyPid, {remove_member, Spot}).
|
||||
|
||||
%% @doc Returns a list of NPC UserID.
|
||||
get_npc(PartyPid) ->
|
||||
gen_server:call(PartyPid, get_npc).
|
||||
@ -82,6 +90,10 @@ handle_call({join, PlayerType, UserID}, _From, State) ->
|
||||
handle_call(get_instance, _From, State) ->
|
||||
{reply, {ok, State#state.instancepid}, State};
|
||||
|
||||
handle_call({get_member, Spot}, _From, State) ->
|
||||
[UserID] = [FoundUserID || {PlayerSpot, _PlayerType, FoundUserID} <- State#state.users, PlayerSpot =:= Spot],
|
||||
{reply, {ok, UserID}, State};
|
||||
|
||||
handle_call(get_npc, _From, State) ->
|
||||
List = [{Spot, UserID} || {Spot, PlayerType, UserID} <- State#state.users, PlayerType =:= npc],
|
||||
{reply, {ok, List}, State};
|
||||
@ -109,6 +121,11 @@ handle_cast({set_instance, InstancePid}, State) ->
|
||||
handle_cast(remove_instance, State) ->
|
||||
{noreply, State#state{instancepid=undefined}};
|
||||
|
||||
handle_cast({remove_member, Spot}, State) ->
|
||||
Users = [{PlayerSpot, PlayerType, UserID} || {PlayerSpot, PlayerType, UserID} <- State#state.users, PlayerSpot =/= Spot],
|
||||
FreeSpots = State#state.free_spots,
|
||||
{noreply, State#state{free_spots=[Spot|FreeSpots], users=Users}};
|
||||
|
||||
handle_cast(_Msg, State) ->
|
||||
{noreply, State}.
|
||||
|
||||
|
@ -366,6 +366,23 @@ parse(Size, 16#080d, Channel, Data) ->
|
||||
?ASSERT_EQ(VarI, 0),
|
||||
ignore;
|
||||
|
||||
%% @todo Find out what it's really doing!
|
||||
parse(Size, 16#080f, Channel, Data) ->
|
||||
<< _LID:16/little, VarA:16/little, VarB:32/little, VarC:32/little, VarD:32/little, VarE:32/little,
|
||||
VarF:32/little, VarG:32/little, VarH:32/little, VarI:32/little, _PartyPos:32/little >> = Data,
|
||||
?ASSERT_EQ(Size, 48),
|
||||
?ASSERT_EQ(Channel, 2),
|
||||
?ASSERT_EQ(VarA, 0),
|
||||
?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),
|
||||
ignore;
|
||||
|
||||
parse(Size, 16#0811, Channel, Data) ->
|
||||
<< _LID:16/little, VarA:16/little, VarB:32/little, VarC:32/little, VarD:32/little, VarE:32/little, VarF:32/little, VarG:32/little, VarH:32/little, VarI:32/little,
|
||||
_CounterType:8, VarJ:8, FromZoneID:16/little, FromMapID:16/little, FromEntryID:16/little, CounterID:32/little, VarK:32/little >> = Data,
|
||||
@ -798,6 +815,22 @@ parse(Size, 16#0f0a, Channel, Data) ->
|
||||
ignore
|
||||
end;
|
||||
|
||||
parse(Size, 16#1007, Channel, Data) ->
|
||||
<< VarA:32/little, VarB:32/little, VarC:32/little, VarD:32/little, VarE:32/little, VarF:32/little,
|
||||
VarG:32/little, VarH:32/little, VarI:32/little, PartyPos:32/little, _Name:512/bits >> = Data,
|
||||
?ASSERT_EQ(Size, 112),
|
||||
?ASSERT_EQ(Channel, 2),
|
||||
?ASSERT_EQ(VarA, 0),
|
||||
?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),
|
||||
{party_remove_member, PartyPos};
|
||||
|
||||
parse(Size, 16#1705, Channel, Data) ->
|
||||
<< _LID:16/little, VarA:16/little, VarB:32/little, VarC:32/little, VarD:32/little, VarE:32/little, VarF:32/little, VarG:32/little, VarH:32/little, VarI:32/little >> = Data,
|
||||
?ASSERT_EQ(Size, 44),
|
||||
|
Loading…
Reference in New Issue
Block a user