· 10 years ago · Aug 31, 2016, 04:02 AM
1--[[
2CREATE TABLE IF NOT EXISTS `castle_info` (
3 `id` int(11) NOT NULL AUTO_INCREMENT,
4 `guild_id` int(11) NOT NULL,
5 `timestamp` bigint(20) NOT NULL,
6 `active` BOOLEAN NOT NULL DEFAULT FALSE,
7 PRIMARY KEY (`id`),
8 FOREIGN KEY (`guild_id`) REFERENCES `guilds` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
9) ENGINE=InnoDB;]]
10
11local config = {
12 minPlayers = 1, -- Players online para poder invadir.
13 minLevel = 250, -- Level minimo dos players online.
14 warningDelay = 5, -- Delay entre mensgens de invasao (só sera mandada se nao houver nenhum player da guild dentro do castelo ao entrar)
15 NW = Position(5475, 4918, 7), -- Posiçao NW do quadrado minimo envolvente do castelo.
16 SE = Position(5511, 4956, 7), -- Posiçao SE do quadrado minimo envolvente do castelo.
17 castleEntrance = Position(5493, 4936, 7),
18 timeToKill = 60, -- Tempo em segundos para matar todos os geradores. (A diferença entre o tempo da morte de todos deve ser no maximo 60 segundos)
19 generators = {
20 [1] = {pos = Position(294, 298, 7), name = "Rat", spawn = 120},
21 [2] = {pos = Position(294, 302, 7), name = "Cave Rat", spawn = 120},
22 [3] = {pos = Position(306, 300, 7), name = "Troll", main = true},
23 },
24 teleport = {pos = Position(5493, 4920, 6), topos = Position(5493, 4935, 5), duration = 60}, -- Teleporte gerado apos morte dos geradores para terceira sala.
25}
26
27if not CASTLE then
28 CASTLE = {}
29 CASTLE.warnings = {}
30end
31
32function checkPlayers(guild)
33 local players = Game.getPlayers()
34 local total = 0
35 for i = 1, #players do
36 local pguild = players[i]:getGuild()
37 if pguild and pguild == guild then
38 if players[i]:getLevel() >= config.minLevel then
39 total = total + 1
40 end
41 end
42
43 if total >= config.minPlayers then
44 return true
45 end
46 end
47
48 return false
49end
50
51function CASTLE:getPlayersInside()
52 local players = Game.getPlayers()
53 local ret = {}
54
55 for i = 1, #players do
56 local pos = players[i]:getPosition()
57 if pos.x >= config.NW.x and pos.y >= config.NW.y and pos.x <= config.SE.x and pos.y <= config.SE.y then
58 table.insert(ret, players[i])
59 end
60 end
61
62 return ret
63end
64
65function CASTLE:isGuildInside(guild)
66 local players = self:getPlayersInside()
67
68 for i = 1, #players do
69 local pguild = players[i]:getGuild()
70 if pguild and pguild == guild then
71 return true
72 end
73 end
74
75 return false
76end
77
78function CASTLE:load()
79 if not self.loaded then
80 self.loaded = true
81 local resultId = db.storeQuery("SELECT * FROM `castle_info` WHERE `active` = 1;")
82 if resultId then
83 local res = result.getDataInt(resultId, "guild_id")
84 if not tonumber(res) then
85 self.dominant = false
86 else
87 self.dominant = res
88 end
89 else
90 self.dominant = false
91 end
92
93 self:spawnGenerator()
94 end
95end
96
97function CASTLE:findGenerator(cid)
98 for i = 1, #self.generators do
99 if self.generators[i].cid == cid then
100 return self.generators[i]
101 end
102 end
103
104 return false
105end
106
107function CASTLE:spawnGenerator(id)
108 if not self.generators then
109 self.generators = {}
110 end
111 if not id then
112 for id, generator in ipairs(config.generators) do
113 if not self.generators[id] or self.generators[id].dead then
114 local creature = Game.createMonster(generator.name, generator.pos)
115 if creature then
116 self.generators[id] = {id = id, cid = creature:getId(), spawntime = os.time()}
117 creature:registerEvent("Generator_Health")
118 if generator.main then
119 creature:registerEvent("MainGenerator_Death")
120 self.generators[id].main = true
121 else
122 creature:registerEvent("Generator_Death")
123 end
124 else
125 print("[Critical Error :: Castle 24HRS] Failed to create generator " .. id .. ".")
126 end
127 end
128 end
129 else
130 if config.generators[id] and (not self.generators[id] or self.generators[id].dead) then
131 local generator = config.generators[id]
132
133 local creature = Game.createMonster(generator.name, generator.pos)
134 if creature then
135 self.generators[id] = {id = id, cid = creature:getId(), spawntime = os.time()}
136 creature:registerEvent("Generator_Health")
137 if generator.main then
138 creature:registerEvent("MainGenerator_Death")
139 else
140 creature:registerEvent("Generator_Death")
141 end
142 else
143 print("[Critical Error :: Castle 24HRS] Failed to create generator " .. id .. ".")
144 end
145
146 end
147 end
148end
149
150function CASTLE:getDominantGuild()
151 if not self.dominant or not Guild(self.dominant) then
152 return false
153 end
154
155 return Guild(self.dominant)
156end
157
158function CASTLE:dominate(guild)
159 local guild = Guild(guild)
160 if guild then
161 self.dominant = guild:getId()
162 db.query("UPDATE `castle_info` SET `active` = 0 WHERE 1;")
163 db.query(("INSERT INTO `castle_info` (`guild_id`, `timestamp`, `active`) VALUES (%d, %d, %d)"):format(guild:getId(), os.time(), 1))
164 end
165end
166
167function CASTLE:teleportPlayer(player)
168 local ret = "Boa sorte!"
169 local guild = player:getGuild()
170 local dominant = self:getDominantGuild()
171 if not guild then
172 return "Voce não possui uma guild no momento."
173 elseif guild:getId() ~= self.dominant and not checkPlayers(guild) then
174 return "Sua guild nao possui " .. config.minPlayers .. " players level " .. config.minLevel .. " ou maior online no momento."
175 end
176
177 if (not dominant or dominant ~= guild) and not self:isGuildInside(guild) and (not self.warnings[guild:getId()] or self.warnings[guild:getId()] + config.warningDelay * 60 <= os.time()) then
178 local dominant = self:getDominantGuild()
179 Game.broadcastMessage(("[Castle 24HRS] A guild %s esta invadindo o castelo%s"):format(guild:getName(), dominant and (" da guild dominante " .. dominant:getName() .. ".") or "."), MESSAGE_STATUS_WARNING)
180 self.warnings[guild:getId()] = os.time()
181 end
182
183 player:teleportTo(config.castleEntrance)
184 config.castleEntrance:sendMagicEffect(CONST_ME_TELEPORT)
185 return ret
186end
187
188function CASTLE:removeTeleport()
189 self:spawnGenerator()
190 local teleport = Tile(config.teleport.pos):getItemById(1387)
191 if teleport then
192 teleport:remove()
193 end
194
195 Game.broadcastMessage("[Castle 24HRS] O teleport desapareceu e os geradores foram restaurados.", MESSAGE_STATUS_WARNING)
196end
197
198function CASTLE:createTeleport()
199 local teleport = Game.createItem(1387, 1, config.teleport.pos)
200 if teleport then
201 teleport:setDestination(config.teleport.topos)
202 end
203 self.teleportevent = addEvent(CASTLE.removeTeleport, config.teleport.duration * 1000, self)
204end
205
206function CASTLE:checkGenerators()
207 local maxtime = -math.huge
208 local mintime = math.huge
209 for _, generator in pairs(self.generators) do
210 if not generator.main then
211 if generator.dead then
212 if generator.deathtime > maxtime then
213 maxtime = generator.deathtime
214 end
215 if generator.deathtime < mintime then
216 mintime = generator.deathtime
217 end
218 else
219 return false
220 end
221 end
222 end
223
224 if math.abs(maxtime - mintime) < config.timeToKill then
225 print(math.abs(maxtime - mintime))
226 for _, generator in pairs(self.generators) do
227 stopEvent(generator.spawnevent)
228 generator.spawnevent = nil
229 end
230 Game.broadcastMessage("[Castle 24HRS] Todos os geradores foram mortos o teleport para o gerador principal foi criado e sumira em " .. config.teleport.duration .. " segundos.", MESSAGE_STATUS_WARNING)
231 self:createTeleport()
232 else
233 Game.broadcastMessage("[Castle 24HRS] Todos os geradores foram mortos mas o teleport nao foi criado.", MESSAGE_STATUS_WARNING)
234 end
235end
236
237function CASTLE:onGeneratorDeath(creature, killer)
238 local generator = self:findGenerator(creature:getId())
239 if generator and config.generators[generator.id] then
240 generator.dead = true
241 generator.deathtime = os.time()
242 generator.spawnevent = addEvent(CASTLE.spawnGenerator, config.generators[generator.id].spawn * 1000, self, generator.id)
243 Game.broadcastMessage("[Castle 24HRS] Um gerador foi morto.", MESSAGE_STATUS_WARNING)
244 end
245
246 self:checkGenerators()
247end
248
249function CASTLE:finish()
250 if self.teleportevent then
251 stopEvent(self.teleportevent)
252 self.teleportevent = nil
253
254 local teleport = Tile(config.teleport.pos):getItemById(1387)
255 if teleport then
256 teleport:remove()
257 end
258 end
259
260 local players = self:getPlayersInside()
261 for i = 1, #players do
262 local temple = players[i]:getTown():getTemplePosition()
263 players[i]:teleportTo(temple)
264 temple:sendMagicEffect(CONST_ME_TELEPORT)
265 end
266
267 self:spawnGenerator()
268end
269
270function CASTLE:onMainGeneratorDeath(creature, killer)
271 local generator = self:findGenerator(creature:getId())
272 generator.dead = true
273 if killer:getMaster() then
274 killer = killer:getMaster()
275 end
276
277 local guild = killer:getGuild()
278
279 self:finish()
280 if not guild then
281 print("[Critical Error :: Castle 24HRS] Player that last hited the main generator didn't have guild something really wrong happened, exiting gracefully.")
282 return false
283 end
284 self:dominate(guild:getId())
285 Game.broadcastMessage(("[Castle 24HRS] O gerador principal foi morto por %s da guild %s que agora e a guild dominante do castelo."):format(killer:getName(), guild:getName()), MESSAGE_STATUS_WARNING)
286end
287
288function CASTLE:onGeneratorChangeHealth(creature, attacker, primaryDamage, primaryType, secondaryDamage, secondaryType)
289 if attacker:getMaster() then
290 attacker = attacker:getMaster()
291 end
292
293 if attacker and attacker:isPlayer() then
294 local dominant = self:getDominantGuild()
295 local guild = attacker:getGuild()
296 if dominant and guild and dominant == guild then
297 return 0, primaryType, 0, secondaryType
298 end
299 end
300
301 if primaryType == COMBAT_HEALING then
302 primaryDamage = 0
303 end
304 if secondaryType == COMBAT_HEALING then
305 secondaryDamage = 0
306 end
307
308 return primaryDamage, primaryType, secondaryDamage, secondaryType
309end