forked from RogueClaris/Nebulous-Liberations-Scripts
-
Notifications
You must be signed in to change notification settings - Fork 1
/
player.lua
225 lines (195 loc) · 6.42 KB
/
player.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
local ezmemory = require("scripts/ezlibs-scripts/ezmemory")
local helpers = require('scripts/ezlibs-scripts/helpers')
local ezencounters = require('scripts/ezlibs-scripts/ezencounters/main')
-- private functions
local function create_textbox_promise(self)
if self.disconnected then
return Async.create_promise(function(resolve)
resolve()
end)
end
return Async.create_promise(function(resolve)
table.insert(self.textbox_promise_resolvers, resolve)
end)
end
-- public
local Player = {}
function Player:new(player_id)
local position = Net.get_player_position(player_id)
local player = {
id = player_id,
activity = nil,
mug = Net.get_player_mugshot(player_id),
textbox_promise_resolvers = {},
resolve_battle = nil,
avatar_details = nil,
moved = false,
x = position.x,
y = position.y,
z = position.z,
disconnected = false
}
setmetatable(player, self)
self.__index = self
return player
end
-- all messages to this player should be made through the session while the session is alive
function Player:message(message, texture_path, animation_path)
Net.message_player(self.id, message, texture_path, animation_path)
return create_textbox_promise(self)
end
-- all messages to this player should be made through the session while the session is alive
function Player:message_with_mug(message)
return self:message(message, self.mug.texture_path, self.mug.animation_path)
end
-- all questions to this player should be made through the session while the session is alive
function Player:question(question, texture_path, animation_path)
Net.question_player(self.id, question, texture_path, animation_path)
return create_textbox_promise(self)
end
-- all questions to this player should be made through the session while the session is alive
function Player:question_with_mug(question)
return self:question(question, self.mug.texture_path, self.mug.animation_path)
end
-- all quizzes to this player should be made through the session while the session is alive
function Player:quiz(a, b, c, texture_path, animation_path)
Net.quiz_player(self.id, a, b, c, texture_path, animation_path)
return create_textbox_promise(self)
end
function Player:is_battling()
return self.resolve_battle ~= nil
end
local function create_default_results()
-- { health: number, score: number, time: number, ran: bool, emotion: number }
return {
health = 1,
score = 0,
time = 0,
ran = true,
emotion = 0
}
end
-- all encounters to this player should be made through the session while the session is alive
function Player:initiate_encounter(asset_path, data, is_specific)
if self.disconnected then
return Async.create_promise(function(resolve)
resolve(create_default_results())
end)
end
if self:is_battling() then
error("This player is already in a battle")
end
if not is_specific then
local encounter_info = ezencounters.pick_encounter_from_table(asset_path, data.terrain)
encounter_info.freedom_mission = {
turns = 3,
can_flip = data.terrain == "surrounded"
}
if data.terrain == "advantage" then
encounter_info.teams = {
{ 2, 2, 2, 2, 1, 1 },
{ 2, 2, 2, 2, 1, 1 },
{ 2, 2, 2, 2, 1, 1 }
}
elseif data.terrain == "disadvantage" then
encounter_info.player_positions = {
{ 0, 0, 0, 0, 0, 0 },
{ 0, 1, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0 }
}
encounter_info.teams = {
{ 2, 2, 1, 1, 1, 1 },
{ 2, 2, 1, 1, 1, 1 },
{ 2, 2, 1, 1, 1, 1 }
}
elseif data.terrain == "surrounded" then
encounter_info.player_positions = {
{ 0, 0, 0, 0, 0, 0 },
{ 0, 0, 1, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0 }
}
encounter_info.teams = {
{ 1, 1, 2, 2, 1, 1 },
{ 1, 1, 2, 2, 1, 1 },
{ 1, 1, 2, 2, 1, 1 }
}
else
encounter_info.teams = {
{ 2, 2, 2, 1, 1, 1 },
{ 2, 2, 2, 1, 1, 1 },
{ 2, 2, 2, 1, 1, 1 }
}
end
ezencounters.begin_encounter(self.id, encounter_info)
else
Net.initiate_encounter(self.id, asset_path, data)
end
return Async.create_promise(function(resolve)
self.resolve_battle = resolve
end)
end
-- will throw if a textbox is sent to the player using Net directly
function Player:handle_textbox_response(response)
local resolve = table.remove(self.textbox_promise_resolvers, 1)
--may cause silent errors in liberation stuff.
--maybe undo this change (if resolve ~= nil) when debugging.
if resolve ~= nil then
resolve(response)
else
print('resolve was nil')
end
end
function Player:handle_battle_results(stats)
if not self.resolve_battle then
return
end
local resolve = self.resolve_battle
self.resolve_battle = nil
resolve(stats)
end
function Player:handle_disconnect()
self.disconnected = true
for _, resolve in ipairs(self.textbox_promise_resolvers) do
resolve()
end
if self.resolve_battle then
self:handle_battle_results(create_default_results())
end
self.textbox_promise_resolvers = nil
if self.activity then
self.activity:handle_player_disconnect(self.id)
end
end
function Player:boot_to_lobby(isVictory, mapName)
self.activity:handle_player_disconnect(self.id)
self.activity = nil
local area_id = Net.get_player_area(self.id)
local respawn_area = Net.get_area_custom_property(area_id, "Respawn Area")
local spawn = nil
if respawn_area ~= nil then
spawn = Net.get_object_by_name(respawn_area, "Liberation Respawn")
else
respawn_area = "default"
spawn = Net.get_spawn_position("default")
end
Net.transfer_player(self.id, respawn_area, true, spawn.x, spawn.y, spawn.z)
if isVictory then
local gate_to_remove = nil
for index, value in ipairs(Net.list_objects(respawn_area)) do
local prospective_gate = Net.get_object_by_id(respawn_area, value)
if prospective_gate.custom_properties["Liberation Map Name"] == mapName then
gate_to_remove = prospective_gate
break
end
end
if gate_to_remove ~= nil then
local safe_secret = helpers.get_safe_player_secret(self.id)
local player_area_memory = ezmemory.get_player_area_memory(safe_secret, respawn_area)
player_area_memory.hidden_objects[tostring(gate_to_remove.id)] = true
ezmemory.save_player_memory(safe_secret)
end
end
ezmemory.set_player_max_health(self.id, ezmemory.get_player_max_health(self.id), true)
ezmemory.set_player_health(self.id, 9999)
end
return Player