egs_zones: Add enter and leave functions for players entering/leaving the zone.
This commit is contained in:
parent
9d10c28504
commit
326b356d02
@ -63,7 +63,8 @@
|
||||
character :: tuple(), %% @todo Details.
|
||||
%% Location/state related information.
|
||||
uni :: integer(),
|
||||
instancepid :: pid(),
|
||||
questpid :: pid(),
|
||||
zonepid :: pid(),
|
||||
partypid :: pid(),
|
||||
areatype :: counter | mission | lobby | myroom,
|
||||
area :: area(),
|
||||
@ -73,6 +74,7 @@
|
||||
prev_area = {0, 0, 0} :: area(),
|
||||
prev_entryid = 0 :: entryid(),
|
||||
%% To be moved or deleted later on.
|
||||
instancepid :: pid(),
|
||||
setid = 0 :: non_neg_integer() %% @todo Current area's set number. Move that handling to the proper zone module later.
|
||||
}).
|
||||
|
||||
|
@ -253,6 +253,7 @@ event(counter_background_locations_request, _State) ->
|
||||
|
||||
%% @todo Make sure non-mission counters follow the same loading process.
|
||||
%% @todo Probably validate the From* values, to not send the player back inside a mission.
|
||||
%% @todo Handle egs_zones entering and leaving.
|
||||
event({counter_enter, CounterID, FromZoneID, FromMapID, FromEntryID}, State=#state{gid=GID}) ->
|
||||
log("counter load ~b", [CounterID]),
|
||||
{ok, OldUser} = egs_users:read(GID),
|
||||
|
@ -20,14 +20,16 @@
|
||||
-module(egs_zones).
|
||||
-behaviour(gen_server).
|
||||
|
||||
-export([start_link/4, stop/1, setid/1]). %% API.
|
||||
-export([start_link/4, stop/1, setid/1, enter/2, leave/2]). %% API.
|
||||
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). %% gen_server.
|
||||
|
||||
-record(state, {
|
||||
setid = 0 :: integer(),
|
||||
objects = [] :: list(),
|
||||
indexes = [] :: list(),
|
||||
targets = [] :: list()
|
||||
targets = [] :: list(),
|
||||
players = [] :: list(),
|
||||
freelids = [] :: list()
|
||||
}).
|
||||
|
||||
%% API.
|
||||
@ -43,6 +45,12 @@ stop(Pid) ->
|
||||
setid(Pid) ->
|
||||
gen_server:call(Pid, setid).
|
||||
|
||||
enter(Pid, GID) ->
|
||||
gen_server:call(Pid, {enter, GID}).
|
||||
|
||||
leave(Pid, GID) ->
|
||||
gen_server:cast(Pid, {leave, GID}).
|
||||
|
||||
%% gen_server.
|
||||
|
||||
init([UniID, QuestID, ZoneID, ZoneData]) ->
|
||||
@ -50,17 +58,31 @@ init([UniID, QuestID, ZoneID, ZoneData]) ->
|
||||
Set = egs_quests_db:set(QuestID, ZoneID, SetID),
|
||||
Objects = create_units(Set),
|
||||
{Indexes, Targets} = index_objects(Objects),
|
||||
{ok, #state{setid=SetID, objects=Objects, indexes=Indexes, targets=Targets}}.
|
||||
FreeLIDs = lists:seq(0, 1023),
|
||||
{ok, #state{setid=SetID, objects=Objects, indexes=Indexes, targets=Targets, freelids=FreeLIDs}}.
|
||||
|
||||
handle_call(setid, _From, State) ->
|
||||
{reply, State#state.setid, State};
|
||||
|
||||
handle_call({enter, GID}, _From, State) ->
|
||||
Players = State#state.players,
|
||||
[LID|FreeLIDs] = State#state.freelids,
|
||||
%% @todo Broadcast spawn to other players in the zone.
|
||||
{reply, LID, State#state{players=[{GID, LID}|Players], freelids=FreeLIDs}};
|
||||
|
||||
handle_call(stop, _From, State) ->
|
||||
{stop, normal, stopped, State};
|
||||
|
||||
handle_call(_Request, _From, State) ->
|
||||
{reply, ignored, State}.
|
||||
|
||||
handle_cast({leave, GID}, State) ->
|
||||
{_, LID} = lists:keyfind(GID, 1, State#state.players),
|
||||
Players = lists:delete({GID, LID}, State#state.players),
|
||||
FreeLIDs = State#state.freelids,
|
||||
%% @todo Broadcast unspawn to other players in the zone.
|
||||
{noreply, State#state{players=Players, freelids=[LID|FreeLIDs]}};
|
||||
|
||||
handle_cast(_Msg, State) ->
|
||||
{noreply, State}.
|
||||
|
||||
|
@ -53,24 +53,29 @@ area_load(QuestID, ZoneID, MapID, EntryID, State) ->
|
||||
SetID = 0, %% @todo Handle multiple sets properly.
|
||||
{IsSeasonal, SeasonID} = egs_seasons:read(QuestID),
|
||||
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 ->
|
||||
User2 = if QuestChange ->
|
||||
psu_proto:send_0c00(User, State),
|
||||
psu_proto:send_020e(QuestData, State);
|
||||
true -> ignore
|
||||
psu_proto:send_020e(QuestData, State),
|
||||
User#users{questpid=egs_universes:lobby_pid(User#users.uni, QuestID)};
|
||||
true -> User
|
||||
end,
|
||||
%% @todo The LID changes here.
|
||||
%% Load the zone.
|
||||
if ZoneChange ->
|
||||
User3 = if ZoneChange ->
|
||||
ZonePid = egs_quests:zone_pid(User2#users.questpid, ZoneID),
|
||||
egs_zones:leave(User2#users.zonepid, User2#users.gid),
|
||||
LID = egs_zones:enter(ZonePid, User2#users.gid),
|
||||
psu_proto:send_0a05(State),
|
||||
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
|
||||
psu_proto:send_020f(ZoneData, SetID, SeasonID, State),
|
||||
User2#users{lid=LID, zonepid=ZonePid};
|
||||
true -> User2
|
||||
end,
|
||||
%% Save the user.
|
||||
egs_users:write(User3),
|
||||
%% Load the player location.
|
||||
State2 = State#state{areanb=State#state.areanb + 1},
|
||||
psu_proto:send_0205(User#users{lid=0}, IsSeasonal, State2),
|
||||
|
Loading…
Reference in New Issue
Block a user