View difference between Paste ID: MawafQsm and c8JJQR6y
SHOW: | | - or go back to the newest paste.
1
--Creator: Bolodefchoco
2
--Made in: 06/02/2017
3
--Last update: 14/07/2017
4
5
--[[ Module ]]--
6
local module = {
7
	_VERSION = "3.6",
8
	_NAME = "grounds",
9
	_STATUS = "semi-official",
10
	_AUTHOR = "Bolodefchoco",
11
	_LICENSE = [[
12
		MIT LICENSE
13
		
14
		Copyright (c) 2017 @Transformice + @Bolodefchoco
15
		
16
		Permission is hereby granted, free of charge, to any person obtaining
17
		a copy of this software and associated documentation files (the
18
		"Software"), to deal in the Software without restriction, including
19
		without limitation the rights to use, copy, modify, merge, and to
20
		permit persons to whom the Software is furnished to do so, subject to
21
		the following conditions:
22
23
		The above copyright notice and this permission notice shall be included
24
		in all copies or substantial portions of the Software.
25
26
		THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
27
		OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF FITNESS FOR
28
		A PARTICULAR PURPOSE AND NONINFRINGEMENT.
29
		IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
30
		CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
31
		TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
32
		SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33
	]],
34
	_FREEACCESS = { -- Verified players
35
		-- 3 : Commands + Room admin + Debug
36
		Bolodefchoco = 3,
37
		-- 2 : Commands
38
		Bodykudo = 2,
39
		Error_404 = 2,
40
		Jordynl = 2,
41
		Laagaadoo = 2,
42
		Sebafrancuz = 2,
43
		Tocutoeltuco = 2,
44
		-- 1 : Some commands
45
		Artinoe = 1,
46
		Bapereira = 1,
47
		Barberserk = 1,
48
		Byontr = 1,
49
		Claumiau = 1,
50
		Drescen = 1,
51
		Ekull = 1,
52
		Elvismouse = 1,
53
		Grastfetry = 1,
54
		Mcqv = 1,
55
		Mescouleur = 1,
56
		Mquk = 1,
57
		Reshman = 1,
58
		Rikkeshang = 1,
59
		Ruamorangos = 1,
60
		Sammynya = 1,
61
	},
62
}
63
64
--[[ Optimization ]]--
65
  --[[ String ]]--
66
local stringlen,stringfind,stringgmatch,stringbyte,stringdump,stringreverse,stringupper,stringformat,stringrep,stringlower,stringsub,stringgsub,stringmatch,stringchar = string.len,string.find,string.gmatch,string.byte,string.dump,string.reverse,string.upper,string.format,string.rep,string.lower,string.sub,string.gsub,string.match,string.char
67
  --[[ Math ]]--
68
local mathdeg,mathfmod,mathrandom,mathasin,mathmax,mathmodf,mathfloor,mathcosh,mathldexp,mathatan2,mathpow,mathrandomseed,mathfrexp,mathabs,mathtanh,mathacos,mathlog,mathtan,mathmin,mathceil,mathsinh,mathsqrt,mathhuge,mathrad,mathsin,mathexp,mathcos,mathatan,mathpi = math.deg,math.fmod,math.random,math.asin,math.max,math.modf,math.floor,math.cosh,math.ldexp,math.atan2,math.pow,math.randomseed,math.frexp,math.abs,math.tanh,math.acos,math.log,math.tan,math.min,math.ceil,math.sinh,math.sqrt,math.huge,math.rad,math.sin,math.exp,math.cos,math.atan,math.pi
69
  --[[ Table ]]--
70
local tablepack,tableforeachi,tableforeach,tableremove,tableinsert,tableunpack,tableconcat,tablesort = table.pack,table.foreachi,table.foreach,table.remove,table.insert,table.unpack,table.concat,table.sort
71
72
--[[ API ]]--
73
	-- Timers
74
system.newGameTimer = 0
75
76
	-- Control
77
system.officialMode = {"",""}
78
system.setAdmins = function()
79
	local out = {}
80
	for k,v in next,module._FREEACCESS do
81
		if v > 2 then
82
			out[k] = true
83
		end
84
	end
85
	return out
86
end
87
88
	-- Improvements
89
tableconcat = function(list,sep,f,i,j)
90
	local txt = ""
91
	sep = sep or ""
92
	i,j = i or 1,j or #list
93
	for k,v in next,list do
94
		if type(k) ~= "number" and true or (k >= i and k <= j) then
95
			txt = txt .. (f and f(k,v) or v) .. sep
96
		end
97
	end
98
	return stringsub(txt,1,-1-#sep)
99
end
100
do
101
	local newGame = tfm.exec.newGame
102
	tfm.exec.newGame = function(code)
103
		if os.time() > system.newGameTimer then
104
			system.newGameTimer = os.time() + 6000
105
			newGame(code)
106
			return true
107
		end
108
		return false
109
	end
110
	
111
	local addImage = tfm.exec.addImage
112
	local removeImage = tfm.exec.removeImage
113
	tfm.exec.addImage = function(...)
114
		local id = addImage(...)
115
		if id then
116
			system.objects.image[id] = true
117
		end
118
		return id
119
	end
120
	tfm.exec.removeImage = function(id)
121
		removeImage(id)
122
		if system.objects.image[id] then
123
			system.objects.image[id] = nil
124
		end
125
	end
126
	
127
	local addTextArea = ui.addTextArea
128
	ui.addTextArea = function(id,...)
129
		addTextArea(id,...)
130
		if not system.objects.textarea[id] then
131
			system.objects.textarea[id] = true
132
		end
133
	end
134
	
135
	local chatMessage = tfm.exec.chatMessage
136
	tfm.exec.chatMessage = function(txt,n)
137
		if #txt > 1000 then
138
			local total = 0
139
			while #txt > total do
140
				chatMessage(stringsub(txt,total,total + 1000),n)
141
				total = total + 1001
142
			end
143
		else
144
			chatMessage(txt,n)
145
		end
146
	end
147
	
148
	local loadPlayerData = system.loadPlayerData
149
	system.loadPlayerData = function(n)
150
		if module._STATUS == "official" then
151
			return loadPlayerData(n)
152
		else
153
			if _G["eventPlayerDataLoaded"] then
154
				eventPlayerDataLoaded(n,"")
155
			end
156
			return true
157
		end
158
	end
159
	
160
	local savePlayerData = system.savePlayerData
161
	system.savePlayerData = function(n,data)
162
		if module._STATUS == "official" then
163
			savePlayerData(n,data)
164
			return true
165
		else
166
			return false
167
		end
168
	end
169
end
170
171
	-- Room
172
system.isRoom = stringbyte(tfm.get.room.name,2) ~= 3
173
system.roomAdmins = system.setAdmins()
174
system.miscAttrib = 0
175
system.roomNumber,system.roomAttributes = (function()
176
	if system.isRoom then
177
		local number,attribute = stringmatch(tfm.get.room.name,"%*?#"..module._NAME.."(%d+)(.*)")
178
		return tonumber(number) or "",attribute or ""
179
	else
180
		return "",""
181
	end
182
end)()
183
184
	-- Player
185
system.isPlayer = function(n)
186
	--[[
187
		The player must not be a souris;
188
		The player must have played Transformice for at least 5 days
189
	]]
190
	return tfm.get.room.playerList[n] and stringsub(n,1,1) ~= "*" and tfm.get.room.playerList[n].registrationDate and (os.time() - (tfm.get.room.playerList[n].registrationDate or 0) >= 432e6) or false
191
end
192
system.players = function(alivePlayers)
193
	local alive,total = 0,0
194
	if alivePlayers then
195
		alive = {}
196
	end
197
	for k,v in next,tfm.get.room.playerList do
198
		if system.isPlayer(k) then
199
			if not v.isDead and not v.isVampire then
200
				if alivePlayers then
201
					alive[#alive + 1] = k
202
				else
203
					alive = alive + 1
204
				end
205
			end
206
			total = total + 1
207
		end
208
	end
209
	if alivePlayers then
210
		return alive
211
	else
212
		return alive,total
213
	end
214
end
215
216
	-- System
217
currentTime,leftTime = 0,0
218
system.loadTable = function(s)
219
	-- "a.b.c.1" returns a[b][c][1]
220
	local list
221
	for tbl in stringgmatch(s,"[^%.]+") do
222
		tbl = tonumber(tbl) and tonumber(tbl) or tbl
223
		list = (list and list[tbl] or _G[tbl])
224
	end
225
	return list
226
end
227
system.getTranslation = function(index,n)
228
	local t = stringformat("mode.%s.translations.%s.%s",system.gameMode,(n and mode[system.gameMode].info[n].langue or mode[system.gameMode].langue),index)
229
	return system.loadTable(t) or system.loadTable(stringgsub(t,"translations%..-%.",function() return "translations.en." end))
230
end
231
system.looping = function(f,tick)
232
	local s = 1000 / tick
233
	local t = {}
234
	for timer = 0,1000 - s,s do
235
		system.newTimer(function()
236
			t[#t+1] = system.newTimer(f,1000,true)
237
		end,1000 + timer,false)
238
	end
239
	return t
240
end
241
242
	-- Math
243
mathisNegative = function(x,iN,iP)
244
	return (x<0 and (iN or x) or (iP or x))
245
end
246
mathpercent = function(x,y,v)
247
	v = (v or 100)
248
	local m = x/y * v
249
	return mathmin(m,v)
250
end
251
mathpythag = function(x1,y1,x2,y2,range)
252
	return (x1-x2)^2 + (y1-y2)^2 <= (range^2)
253
end
254
mathsetLim = function(value,min,max)
255
	return mathmax(min,mathmin(max,value))
256
end
257
258
	-- String
259
stringsplit = function(value,pattern,f)
260
	local out = {}
261
	for v in stringgmatch(value,pattern) do
262
		out[#out + 1] = (f and f(v) or v)
263
	end
264
	return out
265
end
266
stringnick = function(player)
267
	return stringgsub(stringlower(player),"%a",stringupper,1)
268
end
269
270
	-- Table
271
tablefind = function(list,value,index,f)
272
	for k,v in next,list do
273
		local i = (type(v) == "table" and index and v[index] or v)
274
		if (f and f(i) or i) == value then
275
			return true,k
276
		end
277
	end
278
	return false,0
279
end
280
tableturnTable = function(x)
281
	return (type(x)=="table" and x or {x})
282
end
283
tablerandom = function(t)
284
	return (type(t) == "table" and t[mathrandom(#t)] or mathrandom())
285
end
286
tableshuffle = function(t)
287
	local randomized = {}
288
	for v = 1,#t do
289-
		tableinsert(randomized,mathrandom(#randomized),t[v])
289+
290
	return randomized
291
end
292
293
	-- Others
294
deactivateAccents=function(str)
295
	local letters = {a = {"á","â","à","å","ã","ä"},e = {"é","ê","è","ë"},i = {"í","î","ì","ï"},o = {"ó","ô","ò","õ","ö"},u = {"ú","û","ù","ü"}}
296
	for k,v in next,letters do
297
		for i = 1,#v do
298
			str = stringgsub(str,v[i],tostring(k))
299
		end
300
	end
301
	return str
302
end
303
normalizeTime = function(time)
304
	return mathfloor(time) + ((time - mathfloor(time)) >= .5 and .5 or 0)
305
end
306
disableChatCommand = function(command)
307
	system.disableChatCommandDisplay(command,true)
308
	system.disableChatCommandDisplay(stringlower(command),true)
309
	system.disableChatCommandDisplay(stringupper(command),true)
310
end	
311
normalizeTranslation = function()
312
	local t = mode[system.gameMode].translations
313
314
	for k,v in next,t.en do
315
		for i,j in next,t do
316
			if i ~= "en" then
317
				if not j[k] then
318
					j[k] = v
319
				end
320
			end
321
		end
322
	end
323
end
324
325
	-- XML Dealer
326
xml = {}
327
xml.parse = function(currentXml)
328
	currentXml = stringmatch(currentXml,"<P (.-)/>") or ""
329
	local out = {}
330
	for tag,_,value in stringgmatch(currentXml,"([%-%w]+)=([\"'])(.-)%2") do
331
		out[tag] = value
332
	end
333
	return out
334
end
335
xml.attribFunc = function(currentXml,funcs)
336
	local attributes = xml.parse(currentXml)
337
	for k,v in next,funcs do
338
		if attributes[v.attribute] then
339
			v.func(attributes[v.attribute])
340
		end
341
	end
342
end
343
xml.addAttrib = function(currentXml,out,launch)
344
	local parameters = stringmatch(currentXml,"<P (.-)/>") or ""
345
	for k,v in next,out do
346
		if not stringfind(parameters,v.tag) then
347
			currentXml = stringgsub(currentXml,"<P (.-)/>",function(attribs)
348
				return stringformat("<P %s=\"%s\" %s/>",v.tag,v.value,attribs)
349
			end)
350
		end
351
	end
352
	if launch then
353
		tfm.exec.newGame(currentXml)
354
	else
355
		return currentXml
356
	end
357
end
358
xml.getCoordinates = function(s)
359
	if stringfind(s,";") then
360
		local x,y
361
		local axis,value = stringmatch(s,"(%a);(%d+)")
362
		value = tonumber(value)
363
		if value then
364
			if axis == "x" then x = value else y = value end
365
		end
366
		return x or 0,y or 0
367
	else
368
		local pos = {}
369
		for x,y in stringgmatch(s,"(%d+) ?, ?(%d+)") do
370
			pos[#pos+1] = {x = x,y = y}
371
		end
372
		return pos
373
	end
374
end
375
376
--[[ Game Mode System ]]--
377
system.normalizedModeName = function(name,back)
378
	if back then
379
		name = stringgsub(name,"%+","P") -- Test+ = TestP
380
	else
381
		name = stringgsub(name,"P$","+") -- TestP = Test+
382
	end
383
	return name
384
end
385
386
system.submodes = {}
387
388
system.gameMode = module._NAME
389
system.modeChanged = os.time() + 10e3
390
391
system.getGameMode = function(value,notFirst)
392
	local found,submode = tablefind(system.submodes,stringlower(value),nil,stringlower)
393
	if found then
394
		system.gameMode = system.normalizedModeName(system.submodes[submode],true)
395
		
396
		if notFirst then
397
			eventModeChanged()
398
		end
399
		
400
		system.modeChanged = os.time() + 10e3
401
	end
402
	return found
403
end
404
405
--[[ Modes ]]--
406
mode = setmetatable({},{
407
	__newindex = function(list,key,value)
408
		rawset(list,key,value)
409
		system.submodes[#system.submodes+1] = system.normalizedModeName(key,false)
410
	end
411
})
412
413
--[[ Grounds ]]--
414
mode.grounds = {
415
	-- Translations
416
	translations = {
417
		en = {
418
			-- Data
419
			grounds = {
420
				-- Ground, Description
421
				[0] = {"Wood","?","?"},
422
				[1] = {"Ice","Increases your speed by pressing spacebar","Increases the speed in <BL>%s%%</BL>"},
423
				[2] = {"Trampoline","?","?"},
424
				[3] = {"Lava","Teleports you to the last Z indexed ground","?"},
425
				[4] = {"Chocolate","?","?"},
426
				[5] = {"Earth","?","?"},
427
				[6] = {"Grass","?","?"},
428
				[7] = {"Sand","Creates a sand storm","Decreases the storm in <BL>%s%%</BL>"},
429
				[8] = {"Cloud","Enables you to fly by pressing spacebar","Increases the fly in <BL>%s%%</BL>"},
430
				[9] = {"Water","Drowns you","Drowns you <BL>%s%%</BL> slower"},
431
				[10] = {"Stone","Creates a block of stone by pressing spacebar","Increases the block size in <BL>%s%%</BL>"},
432
				[11] = {"Snow","Shoots snowballs by pressing spacebar","Increases the snowball speed in <BL>%s%%</BL>"},
433
				[12] = {"Rectangle","Each color has its own function","?",{
434
					["C90909"] = "Kills you",
435
					["18C92B"] = "Revives all the enemies",
436
					["555D77"] = "Respawning Checkpoint",
437
				}},
438
				[13] = {"Circle","Each color has its own function","?"},
439
				[14] = {"Invisible","?","?"},
440
				[15] = {"Spiderweb","Teleports you to the spawn point","?"},
441
			},
442
			categories = {
443
				[1] = "Often long maps that, in most of the cases, the players must pass the same obstacles more than once.",
444
				[2] = "Usually long maps with dodgeable spiderwebs or lavas, sometimes using invisible waters to simule a fly.",
445
				[3] = "Harder maps that requires multiple skills to be completed.",
446
				[4] = "Maps that has as main obstacle the water drowning.",
447
				[5] = "Maps based mainly on lava teleports.",
448
				[6] = "Maps that requires a new skill, with mechanisms or something that makes you think before act.",
449
				[7] = "Maps based on speed and agility, built mostly with ice grounds.",
450
				[8] = "Maps based on snowball mechanisms/technics.",
451
				[9] = "Maps with different gameplays that doesn't fit any other category, also locates the <i>vanilla maps</i>.",
452
				[10] = "Soloable (mostly) maps, but with faster paths when the players work together.",
453
				[11] = "Maps with vampires.",
454
				[12] = "Houses without gameplay, only a place for noobs.",
455
			},
456
457
			-- Init
458
			welcome = "Welcome to #%s! Can you be the fastest mouse using the ground effects? Try it!\n<PS>Press H for more info!",
459
			developer = "Developed by %s",
460
			
461
			-- Shop
462
			shop = {
463
				coin = "Coins",
464
				power = "Ground power",
465
				upgrade = "Upgrade",
466
				price = "Upgrade price",
467
				close = "Close",
468
			},
469
			bought = "You just spent %s coins for the ground %s!",
470
			cantbuy = "You haven't coins enough in order to buy this upgrade! :(",
471
			
472
			-- Profile
473
			profile = "Leaderboard : %s\n\n<N>Rounds : %s\n<N>Podiums : %s\n\n<N>Deaths : %s\n\n<N>Shop Coins : %s",
474
			
475
			-- Gameplay
476
			gotcoin = "You just got %s coins! :D",
477
			zombie = "Now you are a zombie!",
478
			countstats = {
479
				mice = "At least 5 mice are needed to stats count",
480
				tribe = "Stats do not count in tribe houses"
481
			},
482
			
483
			-- New map
484
			powersenabled = "The ground powers were enabled! Good luck!",
485
			tribehouse = "This is a House place. No stats, no gameplay. Enjoy with your friends",
486
			
487
			-- Language
488
			language = "Current language : <J>%s",
489
			
490
			-- Settings
491
			password = {
492
				on = "New password : %s",
493
				off = "Password disabled!"
494
			},
495
			
496
			-- Commands
497
			commands = {
498
				shop = "shop",
499
				profile = "profile",
500
				help = "help",
501
				langue = "langue",
502
				leaderboard = "leaderboard",
503
				info = "info",
504
				pw = "password",
505
				mapinfo = "mapinfo",
506
			},
507
			
508
			-- Menu
509
			menu = {
510
				[1] = {"%s","\tYour aim in this minigame is to collect the cheese the faster you can, using the effects each ground offers."},
511
				[2] = {"Ground effects","Click in the ground's name to read more.\n\n%s"},
512
				[3] = {"Commands",{
513
					[1] = {"\t<J>» User</J>\n",{
514
						[1] = "<VP>!%s</VP> <PS>playerName</PS> <R>or</R> <VP>Key P</VP> - Opens the profile!",
515
						[2] = "<VP>!%s</VP> <R>or</R> <VP>Key O</VP> - Opens the shop!",
516
						[3] = "<VP>!%s</VP> - Changes the language!",
517
					}},
518
					[2] = {"\n\t<J>» Others</J>\n",{
519
						[1] = "<VP>!%s</VP> <R>or</R> <VP>Key H</VP> - Opens the help menu!",
520
						[2] = "<VP>!%s</VP> - Opens the leaderboard!",
521
						[3] = "<VP>!%s</VP> - Opens the help according to the ground you are on!",
522
						[4] = "<VP>!%s</VP> - Displays the map info if it is in the rotation!",
523
					}},
524
					[3] = {"\n\t<J>» Room admin</J>\n",{
525
						[1] = "<VP>!%s</VP> <PS>password</PS> - Adds or removes a password in the room!",
526
					}},
527
				}},
528
				[4] = {"Maps","<J>Maps : %s\n\n\tAccess %s and send your map. Do not forget to read all the rules before!"},
529
				[5] = {"Thanks for","<R>%s <G>- <N>Developer\n%s <G>- <N>Translators\n%s <G>- <N>Map evaluators"},
530
			},
531
			max = "15a2df47d2e",
532
		},
533
		br = {
534
			grounds = {
535
				[0] = {"Madeira","?","?"},
536
				[1] = {"Gelo","Aumenta sua velocidade ao pressionar a barra de espaço","Aumenta a velocidade em <BL>%s%%</BL>"},
537
				[2] = {"Trampolim","?","?"},
538
				[3] = {"Lava","Teletransporta-o para o piso de Z anterior","?"},
539
				[4] = {"Chocolate","?","?"},
540
				[5] = {"Terra","?","?"},
541
				[6] = {"Grama","?","?"},
542
				[7] = {"Areia","Cria uma tempestade de areia","Diminui a tempestade em <BL>%s%%</BL>"},
543
				[8] = {"Nuvem","Permite o voo ao pressionar a barra de espaço","Aumenta o voo em <BL>%s%%</BL>"},
544
				[9] = {"Água","Afoga-o","Afoga-o <BL>%s%%</BL> mais devagar"},
545
				[10] = {"Pedra","Cria um bloco de pedra ao pressionar a barra de espaço","Aumenta o tamanho do bloco em <BL>%s%%</BL>"},
546
				[11] = {"Neve","Atira bolas de neve ao pressionar a barra de espaço","Aumenta a velocidade da bola de neve em <BL>%s%%</BL>"},
547
				[12] = {"Retângulo","Cada cor tem sua própria função","?",{
548
					["C90909"] = "Mata-o",
549
					["18C92B"] = "Revive todos os inimigos",
550
					["555D77"] = "Checkpoint para reviver",
551
				}},
552
				[13] = {"Círculo","Cada cor tem sua própria função","?","?"},
553
				[14] = {"Invisível","?","?"},
554
				[15] = {"Teia de aranha","Teletransporta-o para o ponto de spawn","?"},
555
			},
556
			categories = {
557
				[1] = "Geralmente mapas longos que, na maioria dos casos, os jogadores devem passar pelo mesmo obstáculo mais de uma vez.",
558
				[2] = "Geralmente mapas grandes com teias de aranha ou lavas desviáveis, às vezes usando águas invisíveis para simular voo.",
559
				[3] = "Mapas mais difíceis que requem múltiplas habilidades para serem completados.",
560
				[4] = "Mapas que tem como obstáculo principal o afogamento na água.",
561
				[5] = "Mapas baseados principalmente em teleportes de lava.",
562
				[6] = "Mapas que requerem novas habilidades, com mecanismos ou algo que o faça pensar antes de agir.",
563
				[7] = "Mapas baseados em velocidade e agilidade, construídos em sua maioria por pisos de gelo.",
564
				[8] = "Mapas baseados em mecanismos/técnicas com bolas de neve.",
565
				[9] = "Mapas com gameplays diferentes que não se encaixam em nenhuma outra categoria, também dá espaço aos <i>mapas vanilla</i>.",
566
				[10] = "Mapas em que você pode completar sozinho (em maioria), mas com caminhos mais rápidos quando há trabalho em equipe entre os jogadores.",
567
				[11] = "Mapas com vampiros.",
568
				[12] = "Casas sem jogabilidade, apenas um lugar para noobs.",
569
			},
570
			
571
			welcome = "Bem-vindo ao #%s! Você pode ser o rato mais rápido usando os efeitos dos pisos? Prove!\n<PS>Pressione H para mais informações!",
572
			developer = "Desenvolvido por %s",
573
			
574
			shop = {
575
				coin = "Moedas",
576
				power = "Poder do piso",
577
				upgrade = "Melhorar",
578
				price = "Preço de aprimoramento",
579
				close = "Fechar",
580
			},
581
			bought = "Você acaba de gastar %s moedas pelo piso %s!",
582
			cantbuy = "Você não tem moedas suficientes para comprar esta atualização! :(",
583
			
584
			profile = "Rank : %s\n\n<N>Partidas : %s\n<N>Pódios : %s\n\n<N>Mortes : %s\n\n<N>Moedas na loja : %s",
585
			
586
			gotcoin = "Você acaba de conseguir %s moedas! :D",
587
			zombie = "Agora você é um zumbi!",
588
			countstats = {
589
				mice = "Ao menos 5 ratos são necessários para as estatísticas serem contabilizadas",
590
				tribe = "Estatísticas não são contabilizadas em cafofos de tribo"
591
			},
592
			
593
			powersenabled = "Os poderes dos pisos foram ativados! Boa sorte!",
594
			tribehouse = "Este lugar é uma casa. Sem estatísticas, sem gameplay. Divirta-se com seus amigos",
595
			
596
			language = "Idioma atual : <J>%s",
597
			
598
			password = {
599
				on = "Nova senha : %s",
600
				off = "Senha desativada!"
601
			},
602
603
			commands = {
604
				shop = "loja",
605
				profile = "perfil",
606
				help = "ajuda",
607
				langue = "idioma",
608
				leaderboard = "rank",
609
				info = "info",
610
				pw = "senha",
611
			},
612
			
613
			menu = {
614
				[1] = {"%s","\tSeu objetivo neste mini-game é coletar o queijo o mais rápido possível, utilizando os efeitos que cada piso oferecer."},
615
				[2] = {"Efeitos dos pisos","Clique no nome do piso para ler mais.\n\n%s"},
616
				[3] = {"Comandos",{
617
					[1] = {"\t<J>» Usuário</J>\n",{
618
						[1] = "<VP>!%s</VP> <PS>nomeDoJogador</PS> <R>ou</R> <VP>Tecla P</VP> - Abre o perfil!",
619
						[2] = "<VP>!%s</VP> <R>ou</R> <VP>Tecla O</VP> - Abre a loja!",
620
						[3] = "<VP>!%s</VP> - Altera o idioma!",
621
					}},
622
					[2] = {"\n\t<J>» Outros</J>\n",{
623
						[1] = "<VP>!%s</VP> <R>ou</R> <VP>Tecla H</VP> - Abre o menu de ajuda!",
624
						[2] = "<VP>!%s</VP> - Abre o ranking!",
625
						[3] = "<VP>!%s</VP> - Abre a ajuda de acordo com o piso que você está pisando!",
626
						[4] = "<VP>!%s</VP> - Mostra as informações do mapa se estiver na rotação!",
627
					}},
628
					[3] = {"\n\t<J>» Administrador da sala</J>\n",{
629
						[1] = "<VP>!%s</VP> <PS>senha</PS> - Adiciona ou remove uma senha na sala!",
630
					}},
631
				}},
632
				[4] = {"Mapas","<J>Mapas : %s\n\n\tAcesse %s e envie seu mapa. Não se esqueça de ler todas as regras antes!"},
633
				[5] = {"Agradecimentos","<R>%s <G>- <N>Desenvolvedor\n%s <G>- <N>Tradutores\n%s <G>- <N>Avaliadores de mapa"},
634
			},
635
			max = "15a2df3e699",
636
		},
637
		es = {
638
			grounds = {
639
				[0] = {"Madera","?","?"},
640
				[1] = {"Hielo","Incrementa tu velocidad apretando espacio","Aumenta la velocidad en <BL>%s%%</BL>"},
641
				[2] = {"Trampolín","?","?"},
642
				[3] = {"Lava","Te teletransporta al suelo que tenga el último Z index","?"},
643
				[4] = {"Chocolate","?","?"},
644
				[5] = {"Tierra","?","?"},
645
				[6] = {"Hierba","?","?"},
646
				[7] = {"Arena","Crea una tormenta de arena","Disminuye la tormenta en <BL>%s%%</BL>"},
647
				[8] = {"Nube","Te permite volar presionando espacio","Aumenta el vuelo en <BL>%s%%</BL>"},
648
				[9] = {"Agua","Te ahogas","Te ahogas <BL>%s%%</BL> más lento"},
649
				[10] = {"Piedra","Crea un bloque de piedra presionando espacio","Aumenta el tamaño del bloque en <BL>%s%%</BL>"},
650
				[11] = {"Nieve","Dispara bolas de nieve presionando espacio","Aumenta la velocidad de la bola de nieve en <BL>%s%%</BL>"},
651
				[12] = {"Rectángulo","Cada color tiene su propia función","?",{
652
					["C90909"] = "Te mata",
653
					["18C92B"] = "Revive todos los enemigos",
654
					["555D77"] = "Respawning Checkpoint", -- *
655
				}},
656
				[13] = {"Círculo","Cada color tiene su propia función","?"},
657
				[14] = {"Invisible","?","?"},
658
				[15] = {"Tela de araña","Te teletransporta al punto de aparición","?"},
659
			},
660
			categories = {
661
				[1] = "Mapas que, en la mayoría de los casos, los jugadores deben pasar obstaculos más de una vez.",
662
				[2] = "Usualmente mapas largos con telas de araña y lavas esquivables, algunas veces usando agua invisible para simular un vuelo.",
663
				[3] = "Mapas difíciles que necesitan una gran habilidad para completarlos.",
664
				[4] = "Mapas que tienen un obstáculo principal: el agua. ¡Te puedes ahogar!.",
665
				[5] = "Mapas basados principalmente en teletransportes de lava.",
666
				[6] = "Mapas que necesitan una nueva habilidad, con mecanismos o algo que te haga pensar antes de actuar.",
667
				[7] = "Mapas basados en la velocidad del jugador, construidos mayoritariamente con suelos de hielo.",
668
				[8] = "Mapas basados en mecanismos/técnicas con nieve.",
669
				[9] = "Mapas con un gameplay diferente que no entran en otra categoría, también localizados en los <i>mapas vanilla</i>.",
670
				[10] = "Mapas que (mayoritariamente) pueden ser completados solo, pero con patrones rápidos donde los jugadores necesitan trabajar juntos.",
671
				[11] = "Mapas con vampiros.",
672
				[12] = "Houses without gameplay, only a place for noobs",
673
			},
674
			
675
			welcome = "Bienvenido a #%s! Podrás ser el más rápido usando los efectos de los suelos? Inténtalo!\n<PS>Presiona H para más información!",
676
			developer = "Programado por %s",
677
			
678
			shop = {
679
				coin = "Monedas",
680
				power = "Potencia del suelo",
681
				upgrade = "Mejorar",
682
				price = "Precio de la mejora",
683
				close = "Cerrar",
684
			},
685
			bought = "Has gastado %s monedas para el suelo %s!",
686
			cantbuy = "No tienes las suficientes monedas para comprar esta mejora! :(",
687
688
			profile = "Tabla de líderes : %s\n\n<N>Rondas : %s\n<N>Podios : %s\n\n<N>Muertes : %s\n\n<N>Monedas : %s",
689
690
			gotcoin = "Has obtenido %s monedas! :D",
691
			zombie = "Ahora eres un Zombi!",
692
			countstats = {
693
				mice = "Por lo menos 5 ratones son necesarios para contar estadísticas",
694
				tribe = "Las estadísticas no cuentan en casas de tribu"
695
			},
696
			
697
			powersenabled = "Los poderes de los suelos han sido activados! Buena suerte!",
698
			-- *
699
			
700
			language = "Idioma actual : <J>%s",
701
			
702
			password = {
703
				on = "Nueva contraseña : %s",
704
				off = "Contraseña desactivada!"
705
			},
706
			
707
			commands = {
708
				shop = "tienda",
709
				profile = "perfil",
710
				help = "ayuda",
711
				langue = "idioma",
712
				leaderboard = "ranking",
713
				info = "info",
714
				pw = "contraseña",
715
			},
716
			
717
			menu = {
718
				[1] = {"%s","\tTu objetivo en este juego es agarrar el queso lo más rápido que puedas, usando los efectos que cada suelo ofrece."},
719
				[2] = {"Efectos de suelo","Clickea en el nombre del suelo para leer más.\n\n%s"},
720
				[3] = {"Comandos",{
721
					[1] = {"\t<J>» Usuario</J>\n",{
722
						[1] = "<VP>!%s</VP> <PS>nombreDeUsuario</PS> <R>o</R> <VP>Tecla P</VP> - Abre el perfil!",
723
						[2] = "<VP>!%s</VP> <R>o</R> <VP>Tecla O</VP> - Abre la tienda!",
724
						[3] = "<VP>!%s</VP> - Cambia el idioma!\n",
725
					}},
726
					[2] = {"\t<J>» Otros</J>\n",{
727
						[1] = "<VP>!%s</VP> <R>o</R> <VP>Tecla H</VP> - Abre el menu de ayuda!",
728
						[2] = "<VP>!%s</VP> - Abre el ranking!",
729
						[3] = "<VP>!%s</VP> - Abre la guía del suelo en el que estás!",
730
						[4] = "<VP>!%s</VP> - Muestra la información del mapa si está en la rotación!",
731
					}},
732
					[3] = {"\n\t<J>» Admin de la sala</J>\n",{
733
						[1] = "<VP>!%s</VP> <PS>contraseña</PS> - Activa o desactiva la contraseña en la sala.",
734
					}},
735
				}},
736
				[4] = {"Mapas","<J>Mapas : %s\n\n\tEntra a %s y envía tu mapa. No olvides leer las reglas antes!"},
737
				[5] = {"Agradecimientos","<R>%s <G>- <N>Programador\n%s <G>- <N>Traductores\n%s <G>- <N>Evaluadores de mapas"},
738
			},
739
			max = "15a2df3e699",
740
		},
741
		fr = {
742
			grounds = {
743
				[0] = {"Bois","?","?"},
744
				[1] = {"Glace","Augmente votre vitesse en appuyant sur Espace","Augmente la vitesse de <BL>%s%%</BL>"},
745
				[2] = {"Trampoline","?","?"},
746
				[3] = {"Lave","Vous téléporte au sol avec le dernier indice Z","?"},
747
				[4] = {"Chocolat","?","?"},
748
				[5] = {"Terre","?","?"},
749
				[6] = {"Herbe","?","?"},
750
				[7] = {"Sable","Crée une tempête de sable","Diminue la tempête de <BL>%s%%</BL>"},
751
				[8] = {"Nuage","Vous donne la possibilité de voler en appuyant sur Espace","Augmente le vol de <BL>%s%%</BL>"},
752
				[9] = {"Eau","Vous noie","Vous noie <BL>%s%%</BL> plus lentement"},
753
				[10] = {"Pierre","Crée un bloc de pierre en appuyant sur Espace","Augmente la taille du bloc de <BL>%s%%</BL>"},
754
				[11] = {"Neige","Tire des boules de neige en appuyant sur Espace","Augmente la vitesse de la boule de neige de <BL>%s%%</BL>"},
755
				[12] = {"Rectangle","Chaque couleur a sa propre fonction","?",{
756
					["C90909"] = "Te tue",
757
					["18C92B"] = "Ressuscite tous les ennemis",
758
					["555D77"] = "Respawning Checkpoint", -- *
759
				}},
760
				[13] = {"Cercle","Chaque couleur a sa propre fonction","?"},
761
				[14] = {"Invisible","?","?"},
762
				[15] = {"Toile d'araignée","Vous téléporte au point de spawn","?"},
763
			},
764
			-- *
765
			
766
			welcome = "Bienvenue à #%s! Pouvez vous être la souris la plus rapide grâce aux effets des sols? Essayez!\n<PS>Appuyez sur H pour plus d'informations!",
767
			developer = "Développé par %s",
768
769
			shop = {
770
				coin = "Pièces",
771
				power = "Force du sol",
772
				upgrade = "Améliorer",
773
				price = "Coût d'amélioration",
774
				close = "Fermer",
775
			},
776
			bought = "Vous venez de dépenser %s pièces pour le sol %s!",
777
			cantbuy = "Vous n'avez pas assez de pièces pour acheter cette amélioration! :(",
778
			
779
			profile = "Leaderboard : %s\n\n<N>Parties : %s\n<N>Podiums : %s\n\n<N>Morts : %s\n\n<N>Shop Pièces : %s",
780
			
781
			gotcoin = "Vous venez de recevoir %s pièces! :D",
782
			countstats = {
783
				mice = "Au moins 5 souris sont nécessaires pour que les statistiques comptent",
784
				tribe = "Les statistiques ne comptent pas en maison de tribu"
785
			},
786
			zombie = "Vous êtes maintenant un zombie!",
787
			
788
			powersenabled = "Les pouvoirs des sols ont été activés! Bonne chance!",
789
			-- *
790
	
791
			language = "Langage actuel : <J>%s",
792
			
793
			password = {
794
				on = "Nouveau mot de passe : %s",
795
				off = "Mot de passe désactivé!"
796
			},
797
			
798
			commands = {
799
				shop = "magasin",
800
				profile = "profil",
801
				help = "aide",
802
				langue = "langue",
803
				leaderboard = "leaderboard",
804
				info = "info",
805
				pw = "password",
806
			},
807
			
808
			menu = {
809
				[1] = {"%s","\tVotre but dans ce minijeu est de collecter le fromage aussi vite que possible, en utilisant les effets des différents sols."},
810
				[2] = {"Effets du sol","Clique sur le nom du salon pour en lire plus.\n\n%s"},
811
				[3] = {"Commandes",{
812
					[1] = {"\t<J>» Joueur</J>\n",{
813
						[1] = "<VP>!%s</VP> <PS>playerName</PS> <R>ou</R> <VP>Touche P</VP> - Ouvre le profil !",
814
						[2] = "<VP>!%s</VP> <R>ou</R> <VP>Touche O</VP> - Ouvre le magasin !",
815
						[3] = "<VP>!%s</VP> - Change la langue !\n",
816
					}},
817
					[2] = {"\t<J>» Autres</J>\n",{
818
						[1] = "<VP>!%s</VP> <R>ou</R> <VP>Touche H</VP> - Ouvre le menu d'aide !",
819
						[2] = "<VP>!%s</VP> - Ouvre le leaderboard!",
820
						[3] = "<VP>!%s</VP> - Ouvre l'aide en fonction du sol sur lequel vous vous trouvez!",
821
						[4] = "<VP>!%s</VP> - Affiche les informations de la carte si elle est dans la rotation!"
822
					}},
823
					[3] = {"\n\t<J>» Place admin</J>\n",{
824
						[1] = "<VP>!%s</VP> <PS>mot de passe</PS> - Ajoute ou supprime un mot de passe dans la chambre.",
825
					}},
826
				}},
827
				[4] = {"Cartes","<J>Cartes : %s\n\n\tAccédez à %s et envoyez votre carte. N'oubliez pas de lire toutes les règles avant!"},
828
				[5] = {"Merci à","<R>%s <G>- <N>Développeur\n%s <G>- <N>Traducteurs\n%s <G>- <N>Evaluateurs de maps"},
829
			},
830
			-- *
831
		},
832
		pl = {
833
			grounds = {
834
				[0] = {"Drewno","?","?"},
835
				[1] = {"Lód","Zwiększa twoją szybkość, gdy klikasz spację","Zwiększa prędkość w <BL>%s%%</BL>"},
836
				[2] = {"Trampolina","?","?"},
837
				[3] = {"Lawa","Przenosi ciebie do ostatniego indexu Z","?"},
838
				[4] = {"Czekolada","?","?"},
839
				[5] = {"Ziemia","?","?"},
840
				[6] = {"Trawa","?","?"},
841
				[7] = {"Piasek","Tworzy burzę piaskową","Zmniejsza storm w <BL>%s%%</BL>"},
842
				[8] = {"Chmura","Pozwala tobie latać, gdy klikasz spację","Zwiększa latanie w <BL>%s%%</BL>"},
843
				[9] = {"Woda","Topi ciebie","Topi <BL>%s%%</BL> wolniej"},
844
				[10] = {"Kamień","Powoduje, że możesz stworzyć blok kamienia, wciskając spację","Zwiększa wielkość bloku w <BL>%s%%</BL>"},
845
				[11] = {"Śnieg","Powoduje, że możesz strzelić śnieżką, wciskając spację","Zwiększa prędkość śnieżki w <BL>%s%%</BL>"},
846
				[12] = {"Trójkąt","Każdy kolor ma swoją funkcję","?",{
847
					["C90909"] = "Zabija ciebie",
848
					["18C92B"] = "Ożywia wszystkich przeciwników",
849
					["555D77"] = "Ponowne spawnowanie Checkpointów",
850
				}},
851
				[13] = {"Koło","Każdy kolor ma swoją funkcję","?"},
852
				[14] = {"Niewidzialność","?","?"},
853
				[15] = {"Pajęcza sieć","Przenosi ciebie do miejsca spawnu","?"},
854
			},
855
			categories = {
856
				[1] = "Często długie mapy, w większości przypadków, gracze muszą przejść takie same przeszkody.",
857
				[2] = "Zwyczajnie długie mapy z lawami i pajęczynami, czasami używana woda aby zasymulować latanie.",
858
				[3] = "Trudniejsze mapy, które wymagają większej ilości zdolności, aby zostały ukończone.",
859
				[4] = "Mapy, które jako główną mapę mają wodę, w której myszki się topią.",
860
				[5] = "Mapy bazowane głównie na teleportacji z lawy.",
861
				[6] = "Mapy, które wymagają nowej zdolności, z mechanizmem albo czymś co powoduje, że musisz myśleć zanim coś zrobisz.",
862
				[7] = "Mapy bazowane na szybkości i zwinności, budowane najczęsciej z gruntów lodu.",
863
				[8] = "Mapy bazowane na technikach/mechanikach śnieżnych kulek.",
864
				[9] = "Mapy z zupełnie inną rozgrywką niż inne kategorie, również znaduje się w <I>mapach vanilliowych</I>.",
865
				[10] = "Mapy (w większości) zdolne do przejścia samemu, ale szybciej się ją przechodzi gdy gracze pracują wspólnie.",
866
				[11] = "Mapy z wampirami.",
867
				[12] = "Chatki plemienne bez rozgrywki, są miejscem tylko dla noobków.",
868
			},
869
			
870
			welcome = "Witaj w #%s! Możesz zostać najszybszą myszką, używając moce gruntów? Spróbuj!\n<PS>Wciśnij H, aby otrzymać więcej informacji!",
871
			developer = "Stworzone przez %s",
872
			
873
			shop = {
874
				coin = "Kredyty",
875
				power = "Moc gruntu",
876
				upgrade = "Ulepsz",
877
				price = "Cena ulepszenia",
878
				close = "Zamknij",
879
			},
880
			bought = "Wydałeś %s monet na %s!",
881
			cantbuy = "Nie masz wystarczającej ilości monet, żeby zakupić to ulepszenie! :(",
882
			
883
			profile = "Ranking : %s\n\n<N>Rund : %s\n<N>Podia : %s\n\n<N>Zgony : %s\n\n<N>Monety : %s",
884
885
			gotcoin = "Masz %s monet! :D",
886
			zombie = "Zostałeś/-aś zombie!",
887
			countstats = {
888
				mice = "Przynajmniej 5 myszek jest potrzebnych aby statystyki były naliczane",
889
				tribe = "Statystyki nie są naliczane w chatkach plemiennych"
890
			},
891
892
			powersenabled = "Moce gruntów są włączone! Powodzenia!",
893
			tribehouse = "To jest miejsce chatki plemiennej. Bez statystyk, bez rozgrywki. Ciesz się ze swoimi znajomymi.",
894
895
			language = "Bieżący język : <J>%s",
896
			
897
			password = {
898
				on = "Nowe hasło : %s",
899
				off = "Hasło wyłączone!"
900
			},
901
			
902
			commands = {
903
				shop = "sklep",
904
				profile = "profil",
905
				help = "pomoc",
906
				langue = "język",
907
				leaderboard = "ranking",
908
				info = "informacje",
909
				pw = "hasło",
910
			},
911
			
912
			menu = {
913
				[1] = {"%s","\tTwoim zadaniem w tej minigrze jest zbieranie serka najszybciej jak potrafisz, wykorzystując moce gruntów."},
914
				[2] = {"Moce gruntu","Kliknij w nazwę gruntu, żeby uzyskać więcej informacji.\n\n%s"},
915
				[3] = {"Komendy",{
916
					[1] = {"\t<J>» Użytkowe</J>\n",{
917
						[1] = "<VP>!%s</VP> <PS>nazwaGracza</PS> <R>albo</R> <VP>Klawisz P</VP> - Otwiera profil!",
918
						[2] = "<VP>!%s</VP> <R>albo</R> <VP>Klawisz O</VP> - Otwiera Sklep!",
919
						[3] = "<VP>!%s</VP> - Zmienia język!",
920
					}},
921
					[2] = {"\t<J>» Inne</J>\n",{
922
						[1] = "<VP>!%s</VP> <R>albo</R> <VP>Klawisz H</VP> - Otwiera pomoc!",
923
						[2] = "<VP>!%s</VP> - Otwiera ranking!",
924
						[3] = "<VP>!%s</VP> - Otwiera pomoc zależnie, na którym gruncie jesteś!",
925
						[4] = "<VP>!%s</VP> - Pokazuje informacje o mapie jeżeli jest w rotacji!",
926
					}},
927
					[3] = {"\n\t<J>» Pokój z adminem</J>\n",{
928
						[1] = "<VP>!%s</VP> <PS>hasło</PS> - Dodaje lub usuwa hasło w pokoju.",
929
					}},
930
				}},
931
				[4] = {"Mapy","<J>Mapy : %s\n\n\tStwórz %s i prześlij swoją mapę. Nie zapomnij, aby najpierw przeczytać zasady!"},
932
				[5] = {"Podziękowania","<R>%s <G>- <N>Twórca\n%s <G>- <N>Tłumacze\n%s <G>- <N>Testerzy map"},
933
			},
934
			max = "15a2df4de75",
935
		},
936
		hu = {
937
			grounds = {
938
				[0] = {"Fa","?","?"},
939
				[1] = {"Jég","Növeli a sebességedet, ha megnyomod a Szóközt","Növeli a sebességet <BL>%s%%</BL>-kal"},
940
				[2] = {"Trambulin","?","?"},
941
				[3] = {"Láva","Elteleportál téged a legutóbbi Z index talajhoz","?"},
942
				[4] = {"Csoki","?","?"},
943
				[5] = {"Föld","?","?"},
944
				[6] = {"Füves talaj","?","?"},
945
				[7] = {"Homok","Homokvihart hoz létre","Csökkenti a sebességet <BL>%s%%</BL>-kal"},
946
				[8] = {"Felhő","Lehetővé teszi számodra a repülést, ha megnyomod a Szóközt","Növeli a repülést <BL>%s%%</BL>-kal"},
947
				[9] = {"Víz","Megfullaszt téged","Megfullaszt <BL>%s%%</BL>-kal lassabban"},
948
				[10] = {"Kő","Egy kőtömböt hoz létre, ha megnyomod a Szóközt","Növeli a blokk méretét <BL>%s%%</BL>-kal"},
949
				[11] = {"Hó","Hógolyót lő, ha megnyomod a Szóközt","Növeli a hógolyó sebességét <BL>%s%%</BL>-kal"},
950
				[12] = {"Téglalap","Mindegyik színnek megvan a saját szerepe","?",{
951
					["C90909"] = "Megöl téged",
952
					["18C92B"] = "Újraéleszti az összes ellenséget",
953
					["555D77"] = "Újraéledő Ellenőrzőpont",
954
				}},
955
				[13] = {"Kör","Mindegyik színnek megvan a saját szerepe","?"},
956
				[14] = {"Láthatatlan","?","?"},
957
				[15] = {"Pókháló","Elteleportál téged a kezdőpontra","?"},
958
			},
959
			-- *
960
			
961
			welcome = "Üdvözöllek a #%s! Sikerül neked a leggyorsabb egérré válni a talajhatások használatával? Próbáld ki!\n<PS>Nyomd meg a H betűt több információért!",
962
			developer = "Fejlesztve %s által",
963
			
964
			shop = {
965
				coin = "Pénzérmék",
966
				power = "Talaj ereje",
967
				upgrade = "Frissítés",
968
				price = "Ár frissítése",
969
				close = "Bezárás",
970
			},
971
			bought = "Te most költöttél el %s pénzt a talajra %s!",
972
			cantbuy = "Nincs elég pénzed ahhoz, hogy megvedd ezt a frissítést! :(",
973
			
974
			profile = "Ranglista : %s\n\n<N>Körök : %s\n<N>Dobogók : %s\n\n<N>Halálozások : %s\n\n<N>Bolti pénz : %s",
975
			
976
			gotcoin = "Te most szereztél %s pénzt! :D",
977
			zombie = "Most egy zombi vagy!",
978
			countstats = {
979
				mice = "Legalább 5 egérnek kell lennie, hogy statisztikát lehessen számolni",
980
				tribe = "A statisztika nem számít a törzsházakban"
981
			},
982
			
983
			powersenabled = "A talajhatások engedélyezve lettek! Sok szerencsét!",
984
			-- *
985
			
986
			language = "Jelenlegi nyelv : <J>%s",
987
			
988
			password = {
989
				on = "Új jelszó : %s",
990
				off = "Jelszó letiltva!"
991
			},
992
			
993
			commands = {
994
				shop = "bolt",
995
				profile = "profil",
996
				help = "súgó",
997
				langue = "nyelv",
998
				leaderboard = "ranglistát",
999
				info = "infó",
1000
				pw = "jelszó",
1001
			},
1002
			
1003
			menu = {
1004
				[1] = {"%s","\tA te feladatod ebben a minijátékban az, hogy a lehető leggyorsabban összegyűjtsd a sajtot a talajhatások használatával."},
1005
				[2] = {"Talajhatások","Kattints a talaj nevére, hogy több mindent megtudhass.\n\n%s"},
1006
				[3] = {"Parancsok",{
1007
					[1] = {"\t<J>» Felhasználó</J>\n",{
1008
						[1] = "<VP>!%s</VP> <PS>játékosNeve</PS> <R>vagy</R> <VP>P billenytű</VP> - Megnyitja a profilt!",
1009
						[2] = "<VP>!%s</VP> <R>vagy</R> <VP>O billentyű</VP> - Megnyitja a boltot!",
1010
						[3] = "<VP>!%s</VP> - Megváltoztatja a nyelvet!\n",
1011
					}},
1012
					[2] = {"\t<J>» Egyebek</J>\n",{
1013
						[1] = "<VP>!%s</VP> <R>vagy</R> <VP>H billentyű</VP> - Megnyitja a Súgó menüpontot!",
1014
						[2] = "<VP>!%s</VP> - Megnyitja a ranglistát!",
1015
						[3] = "<VP>!%s</VP> - Megnyitja a Súgót aszerint, amelyik talajon állsz!",
1016
						[4] = "<VP>!%s</VP> - Displays the map info if it is in the rotation!",
1017
					}},
1018
					[3] = {"\n\t<J>» Szoba admin</J>\n",{
1019
						[1] = "<VP>!%s</VP> <PS>jelszó</PS> - Bekapcsolja vagy kikapcsolja a jelszót a szobában!",
1020
					}},
1021
				}},
1022
				[4] = {"Pályák","<J>Pályák : %s\n\n\tEngedélyezd a %s és küldd be a pályádat. Előtte ne felejtsd el elolvasni az összes szabály!"},
1023
				[5] = {"Köszönet","<R>%s - Nak <G>- <N>Fejlesztő\n%s <G>- <N>Fordítók\n%s <G>- <N>Pálya értékelők"},
1024
			},
1025
			-- *
1026
		},
1027
		ar = {
1028
			grounds = {
1029
				[0] = {"خشب","?","?"},
1030
				[1] = {"جليد","تزيد من سرعتك عند الضغط على زر المسطرة","يزيد من السرعة ب <BL>%s%%</BL>"},
1031
				[2] = {"الترامبولين","?","?"},
1032
				[3] = {"الحمم","تنقلك إلى الأرضية التي لديها اَخر رقم في الـ Z","?"},
1033
				[4] = {"الشوكولاته","?","?"},
1034
				[5] = {"الأرض","?","?"},
1035
				[6] = {"العشب","?","?"},
1036
				[7] = {"الرمل","تصنع عاصفة رملية","يقلل من العاصفة ب <BL>%s%%</BL>"},
1037
				[8] = {"غيمة","تجعلك تطير عن طريق الضغط على زر المسطرة","يزيد من الطيران ب <BL>%s%%</BL>"},
1038
				[9] = {"المياه","تغرقك","يغرقك <BL>%s%%</BL> ببطئ"},
1039
				[10] = {"الحجارة","تصنع حاجو من الحجارة عن طريق الضغط على زر المسطرة","يزيد من حجم الارضية ب <BL>%s%%</BL>"},
1040
				[11] = {"الثلج","تطلق كرات ثلجية عن طريق الضغط على زر المسطرة","يزيد من سرعة كرة الثلج ب <BL>%s%%</BL>"},
1041
				[12] = {"مستطيل","كل لون له قوته الخاصة","?",{
1042
					["C90909"] = "يقتلك",
1043
					["18C92B"] = "إعادة الحياة إلى جميع أعدائك",
1044
					["555D77"] = "نقطة العودة للحياة",
1045
				}},
1046
				[13] = {"الدائرة","كل لون له قوته الخاصة","?"},
1047
				[14] = {"الإختفاء","?","?"},
1048
				[15] = {"شبكة العنكبوت","تنقلك إلى نقطة البداية","?"},
1049
			},
1050
			-- *
1051
			
1052
			welcome = "مرحبا إلى #%s! هل يمكنك أن تكون أسرع فأر يستعمل قوى الأرض؟ قم بتجربتها!\n<PS>اضغط على الزر H لمعرفة المزيد!",
1053
			developer = "مبرمجة من قبل %s",
1054
			
1055
			shop = {
1056
				coin = "النقود",
1057
				power = "طاقة الارضية",
1058
				upgrade = "ترقية",
1059
				price = "ترقبة السعر",
1060
				close = "اغلاق",
1061
			},
1062
			bought = "لقد قمت بإستعمال %s من النقود من أجل الأرضية %s!",
1063
			cantbuy = "لا تملك النقود الكافية لشراء هذا! :(",
1064
			
1065
			profile = "لائحة المتقدمين : %s\n\n<N>الجولات : %s\n<N>المناصب : %s\n\n<N>الموت : %s\n\n<N>نقود المتجر : %s",
1066
			
1067
			gotcoin = "لقد حصلت على %s نقود! :D",
1068
			zombie = "أصبحت الأن ميت حي!",
1069
			countstats = {
1070
				mice = "تحتاج الاقل ل 5 فئران لاحصائيات الاعتماد",
1071
				tribe = "الاحصائيات لا تحسب بمنزل القبيلة"
1072
			},
1073
			
1074
			powersenabled = "تم تفعيل قوى الأرض! حظا موفقا!",
1075
			-- *
1076
			
1077
			language = "اللغة الحالية : <J>%s",
1078
			
1079
			password = {
1080
				on = "جديدة سر كلمة : %s",
1081
				off = "السر كلمة تعطيل!"
1082
			},
1083
			
1084
			commands = {
1085
				shop = "المتجر",
1086
				profile = "لاعب",
1087
				help = "المساعدة",
1088
				langue = "اللغة",
1089
				leaderboard = "مراكز",
1090
				info = "معلومة",
1091
				pw = "password",
1092
			},
1093
			
1094
			menu = {
1095
				[1] = {"%s","\tما عليك فعله في هذه اللعبة هو جمع الجبن بأسرع ما يمكن يمكنك إستخدام القوى التي  توفرها لك الأرضيات."},
1096
				[2] = {"تأثيرات الأراضي","أنقر على إسم الأرضية لمعرفة المزيد عنها\n\n%s"},
1097
				[3] = {"الأوامر",{
1098
					[1] = {"\t<J>» اللاعب</J>\n",{
1099
						[1] = "<VP>!%s</VP> <PS>إسم اللاعب</PS> <R>أو</R> <VP>زر P</VP> - لفتح الملف الشخصي!",
1100
						[2] = "<VP>!%s</VP> <R>أو</R> <VP>الزر O</VP> - لفتح المتجر!",
1101
						[3] = "<VP>!%s</VP> - لتغيير اللغة!\n",
1102
					}},
1103
					[2] = {"\t<J>» البقية</J>\n",{
1104
						[1] = "<VP>!%s</VP> <R>أو</R> <VP>الزر H</VP> - لقتح لائحة المساعدة!",
1105
						[2] = "<VP>!%s</VP> - فتح قائمة المراكز!",
1106
						[3] = "<VP>!%s</VP> - فتح المساعدة وفقا للمكان الذي انت عليه!",
1107
						[4] = "<VP>!%s</VP> - يعرض معلومات الخريطة إذا كانت في دوران",
1108
					}},
1109
					[3] = {"\n\t<J>» مشرف غرفة</J>\n",{
1110
						[1] = "<VP>!%s</VP> <PS>سر كلمة</PS> - إضافة أو إزالة كلمة مرور في الغرفة!",
1111
					}},
1112
				}},
1113
				[4] = {"الخرائط","<J>الخرائط : %s\n\n\tتفعيل %s وأرسل الخارطة. لا تنسى قراءة القوانين!"},
1114
				[5] = {"شكرا لـ","<R>%s <G>- <N>المبرمج\n%s <G>- <N>مترجمون\n%s <G>- <N>مقيموا الخرائط"},
1115
			},
1116
			-- *
1117
		},
1118
		nl = {
1119
			grounds = {
1120
				[0] = {"Hout","?","?"},
1121
				[1] = {"Ijs","Verhoogt je snelheid door op de spatiebalk te drukken","Verhoogd de snelheid met <BL>%s%%</BL>"},
1122
				[2] = {"Trampoline","?","?"},
1123
				[3] = {"Lava","Teleport jou naar de laatst Z index grond","?"},
1124
				[4] = {"Chocolade","?","?"},
1125
				[5] = {"Aarde","?","?"},
1126
				[6] = {"Gras","?","?"},
1127
				[7] = {"Zand","Maakt een zandstorm","Vemindert de storm met <BL>%s%%</BL>"},
1128
				[8] = {"Wolk","Hiermee kun je vliegen door op de spatiebalk te drukken","Verhoogd de vlucht met <BL>%s%%</BL>"},
1129
				[9] = {"Water","Laat je verdrinken","Maakt je <BL>%s%%</BL> langzamer"},
1130
				[10] = {"Steen","Hiermee maak je een blok steen door op de spatiebalk te drukken","Vergroot de grootte van het blok met <BL>%s%%</BL>"},
1131
				[11] = {"Sneeuw","Schiet sneeuwballen door op de spatiebalk te drukken","Verhoogd de snelheid van de sneeuwbal met <BL>%s%%</BL>"},
1132
				[12] = {"Rechthoek","Elke kleur heeft zijn eigen functie","?",{
1133
					["C90909"] = "Vermoordt jou",
1134
					["18C92B"] = "Brengt alle tegenstanders weer tot leven",
1135
					["555D77"] = "Respawning Checkpoint", -- *
1136
				}},
1137
				[13] = {"Cirkel","Elke kleur heeft zijn eigen functie","?"},
1138
				[14] = {"Onzichtbaar","?","?"},
1139
				[15] = {"Spinnenweb","Teleport je naar het beginpunt","?"},
1140
			},
1141
			-- *
1142
			
1143
			
1144
			welcome = "Welkom bij #%s! Ben jij de snelste muis door grond effecten te gebruiken? Probeer het!",
1145
			developer = "Gemaakt door %s",
1146
			
1147
			shop = {
1148
				coin = "Munten",
1149
				power = "Grondkracht",
1150
				upgrade = "Upgraden",
1151
				price = "Upgrade kosten",
1152
				close = "Sluit",
1153
			},
1154
			bought = "Je gaf net %s munten uit voor de grond %s!",
1155
			cantbuy = "Je hebt niet genoeg munten om deze upgrade uit te voeren! :(",
1156
1157
			profile = "Ranglijst : %s\n\n<N>Rondes : %s\n<N>Podiums : %s\n\n<N>Sterfgevallen : %s\n\n<N>Winkel Munten : %s",
1158
1159
			gotcoin = "Je kreeg zojuist %s munten! :D",
1160
			zombie = "Nu ben je een zombie!",
1161
			countstats = {
1162
				mice = "Er zijn minstens 5 muizen nodig voordat de stats tellen",
1163
				tribe = "Stats tellen niet in stamhuizen"
1164
			},
1165
1166
			powersenabled = "De grondkrachten zijn ingeschakeld! Succes!",
1167
			-- *
1168
1169
			language = "Huidige taal : <J>%s",
1170
1171
			password = {
1172
				on = "Nieuwe wachtwoord : %s",
1173
				off = "Wachtwoord uitgezet!"
1174
			},
1175
1176
			commands = {
1177
				shop = "winkel",
1178
				profile = "profiel",
1179
				help = "help",
1180
				langue = "taal",
1181
				leaderboard = "leaderboard",
1182
				info = "info",
1183
				pw = "wachtwoord",
1184
			},
1185
			
1186
			menu = {
1187
				[1] = {"%s","\tJouw doel is om zoveel mogelijk kaas te verzamelen, met gebruik van verschillende grond-effecten."},
1188
				[2] = {"Grond effecten","Klik op de grond om meer info te lezen.\n\n%s"},
1189
				[3] = {"Commands",{
1190
					[1] = {"\t<J>» User</J>\n",{
1191
						[1] = "<VP>!%s</VP> <PS>playerName</PS> <R>or</R> <VP>Key P</VP> - Opent het profiel!",
1192
						[2] = "<VP>!%s</VP> <R>or</R> <VP>Key O</VP> - Opent de winkel!",
1193
						[3] = "<VP>!%s</VP> - Wijzigt de taal!\n",
1194
					}},
1195
					[2] = {"\t<J>» Others</J>\n",{
1196
						[1] = "<VP>!%s</VP> <R>or</R> <VP>Key H</VP> - Opent de Help menu!",
1197
						[2] = "<VP>!%s</VP> - Opent de leaderboard!",
1198
						[3] = "<VP>!%s</VP> - Opent help op basis van de grond waarop je staat!",
1199
						[4] = "<VP>!%s</VP> - Displays the map info if it is in the rotation!", -- *
1200
					}},
1201
					[3] = {"\n\t<J>» Kamer admin</J>\n",{
1202
						[1] = "<VP>!%s</VP> <PS>wachtwoord</PS> - Voegt of haalt een wachtwoord weg van een kamer!",
1203
					}},
1204
				}},
1205
				[4] = {"Maps","<J>Maps : %s\n\n\tBereik %s en verzend jouw map. Vergeet niet om alle regels te lezen voordat je begint!"},
1206
				[5] = {"Dank aan","<R>%s <G>- <N>Developer\n%s <G>- <N>Translators\n%s <G>- <N>Mapbeoordelaars"},
1207
			},
1208
			-- *
1209
		},
1210
		de = {
1211
			grounds = {
1212
				[0] = {"Holz","?","?"},
1213
				[1] = {"Eis","Beschleunigt dich indem du die Leertaste drückst","Erhoht die geschwindigkeit in <BL>%s%%</BL>"},
1214
				[2] = {"Trampoline","?","?"},
1215
				[3] = {"Lava","Teleportiert dich zum letzen Z Index Boden","?"},
1216
				[4] = {"Schokolade","?","?"},
1217
				[5] = {"Erde","?","?"},
1218
				[6] = {"Gras","?","?"},
1219
				[7] = {"Sand","Kreiert einen Sandsturm","Verringert die sturm in <BL>%s%%</BL>"},
1220
				[8] = {"Wolke","Du kannst fliegen indem du die Leertaste drückst","Erhoht die fliege in <BL>%s%%</BL>"},
1221
				[9] = {"Wasser","Ertränkt dich","Ertrinkt dich <BL>%s%%</BL> langsamer"},
1222
				[10] = {"Stein","Erschaffe einen Stein indem du die Leertaste drückst","Erhoht die blockgrosse in <BL>%s%%</BL>"},
1223
				[11] = {"Schnee","Wirf Schneebälle indem du die Leertaste drückst","Erhoht die schneeball geschwindigkeit in <BL>%s%%</BL>"},
1224
				[12] = {"Rechteck","Jede Farbe hat seine eigene Funktion","?",{
1225
					["C90909"] = "Tötet du",
1226
					["18C92B"] = "Aufleben alle Feinde",
1227
					["555D77"] = "Respawning Checkpoint", -- *
1228
				}},
1229
				[13] = {"Kreis","Jede Farbe hat seine eigene Funktion","?"},
1230
				[14] = {"Unsichtbar","?","?"},
1231
				[15] = {"Spinnweben","Teleportiert dich zum Startpunkt","?"},
1232
			},
1233
			-- *
1234
			
1235
			welcome = "Willkommen zu #%s! Kannst du die schnellste Maus mit den Bodeneffekten sein? Versuch es!\n<PS>Drück H für mehr informationen!",
1236
			developer = "Entwickelt von %s",
1237
			
1238
			shop = {
1239
				coin = "Munzen",
1240
				power = "Bodenleistung",
1241
				upgrade = "Aktualisierung",
1242
				price = "Upgrade Preis",
1243
				close = "Schliessen",
1244
			},
1245
			bought = "Du hast %s Münzen für den Boden %s ausgegeben!",
1246
			cantbuy = "Du hast nicht genügend Münzen um dieses Upgrade zu kaufen! :(",
1247
			
1248
			profile = "Bestenliste : %s\n\n<N>Runden: %s\n<N>Podiums: %s\n\n<N>Tode : %s\n\n<N>Shop Münzen: %s",
1249
			
1250
			gotcoin = "Du hast soeben %s Münzen erhalten! :D",
1251
			zombie = "Du bist nun ein Zombie!",
1252
			countstats = {
1253
				mice = "Es müssen mindestens 5 Mäuse im Raum sein damit die Stats zählen",
1254
				tribe = "Stats zählen in Stammeshäusern nicht"
1255
			},
1256
			
1257
			powersenabled = "Der Effekt des Bodens wurde aktiviert! Viel Glück!",
1258
			-- *
1259
			
1260
			language = "Aktuelle Sprache : <J>%s",
1261
			
1262
			password = {
1263
				on = "Neu passwort: : %s",
1264
				off = "Passwort deaktiviert!"
1265
			},
1266
			
1267
			commands = {
1268
				shop = "shop",
1269
				profile = "profil",
1270
				help = "hilfe",
1271
				langue = "sprache",
1272
				leaderboard = "bestenliste",
1273
				info = "info",
1274
				pw = "passwort",
1275
			},
1276
			
1277
			menu = {
1278
				[1] = {"%s","\tDein Ziel in diesem Minigame ist es den Käse so schnell wie möglich zu sammeln, indem du die verschiedenen Effekte der Böden ausnutzt."},
1279
				[2] = {"Bodeneffekte","Klicken in den bodens namen um mehr zu lesen.\n\n%s"},
1280
				[3] = {"Kommandos",{
1281
					[1] = {"\t<J>» Benutzer</J>\n",{
1282
						[1] = "<VP>!%s</VP> <PS>Spielername</PS> <R>oder</R> <VP>Taste P</VP> - Öffnet das Profil!",
1283
						[2] = "<VP>!%s</VP> <R>oder</R> <VP>Taste O</VP> - Öffnet den Shop!",
1284
						[3] = "<VP>!%s</VP> - Ändert die Sprache!\n",
1285
					}},
1286
					[2] = {"\t<J>» Anderes</J>\n",{
1287
						[1] = "<VP>!%s</VP> <R>oder</R> <VP>Taste H</VP> - Öffnet das Hilfsmenu!",
1288
						[2] = "<VP>!%s</VP> - Öffnet die Bestenliste!",
1289
						[3] = "<VP>!%s</VP> - Öffnet die hilfe nach dem boden auf dem du bist auf!",
1290
						[4] = "<VP>!%s</VP> - Displays the map info if it is in the rotation!", -- *
1291
					}},
1292
					[3] = {"\n\t<J>» Zimmer admin</J>\n",{
1293
						[1] = "<VP>!%s</VP> <PS>passwort</PS> - Hinzufugen oder entfernen eines passwortes im raum!",
1294
					}},
1295
				}},
1296
				[4] = {"Maps","<J>Maps : %s\n\n\tBesuche das Thema %s und reiche deine Map ein. Vergiss nicht zuvor alle Regeln zu lesen!"},
1297
				[5] = {"Danke an ","<R>%s <G>- <N>Entwickler\n%s <G>- <N>Übersetzer\n%s <G>- <N>Landkarte bewerter"},
1298
			},
1299
			-- *
1300
		},
1301
	},
1302
	langue = "en",
1303
	-- Info
1304
	staff = {
1305
		translators = {
1306
			-- Name, Languages
1307
			{"Bolodefchoco",{"EN","BR"}},
1308
			{"Distances","NL"},
1309
			{"Tocutoeltuco","ES"},
1310
			{"Sebafrancuz","PL"},
1311
			{"Doriiarvai","HU"},
1312
			{"Error_404","AR"},
1313
			{"Cheeselicious","NL"},
1314
			{"Archaeron","DE"},
1315
			{"Aewing","FR"},
1316
			{"Fashionkid","DE"},
1317
			{"Yuir","ES"},
1318
			{"Mquk","FR"}
1319
		},
1320
		mapEvaluators = {
1321
			-- Name, Joined
1322
			{"Bolodefchoco","14/02/2017"},
1323
			{"Error_404","11/03/2017"}
1324
		},
1325
	},
1326
	-- Data
1327
	bindKeys = {0,1,2,3,stringbyte("OPHK",1,4)},
1328
	info = {},
1329
	stormIntensities = {
1330
		--[[ Opaque images
1331
			[1] = "15a6d6fcd18",
1332
			[2] = "15a6d6ff82f",
1333
			[4] = "15a6d7015bc",
1334
			[8] = "15a6d703149"
1335
		]]
1336
		[1] = .75,
1337
		[2] = .65,
1338
		[4] = .5,
1339
		[8] = .25
1340
	},
1341
	-- Maps (G Categories)
1342
	maps = {},
1343
	G = {
1344
		--[[
1345
			name = catName,
1346
			queue{maps},
1347
			id = 1,
1348
			icon = {iconImage,x axis (from 360),y axis (from 123)}
1349
			color = catColor,
1350
			before = function executed before the map,
1351
			after = function executed after the map
1352
		]]--
1353
		[1] = {
1354
			name = "Circuit",
1355
			queue = {3099763,4612510,7078090,4493715,7102175,5921816,7127261,7102187},
1356
			id = 1,
1357
			icon = {"15c60371706",0,-1},
1358
			color = "9A9ACE",
1359
		},
1360
		[2] = {
1361
			name = "Flap Bird",
1362
			queue = {7069835,2265250,6300148,5921754,2874090,2310427},
1363
			id = 1,
1364
			icon = {"15c603730a6",0,0},
1365
			color = "E084D4",
1366
		},
1367
		[3] = {
1368
			name = "Bootcamp",
1369
			queue = {4592612,7079708,5921867,7087840,6391815,7090909,7011800,7069314,6333026,6000012,6990787,7100040},
1370
			id = 1,
1371
			icon = {"15c60382627",-5,-5},
1372
			color = "A4CF9E",
1373
		},
1374
		[4] = {
1375
			name = "Aquatic",
1376
			queue = {6133469,3324284,6578479,7095393,5772226,2310447},
1377
			id = 1,
1378
			icon = {"15c603788c1",0,0},
1379
			color = "2194D9",
1380
		},
1381
		[5] = {
1382
			name = "Teleport",
1383
			queue = {5168440,6987992,7069343,6945850,7090907,3326655,7069816,5921744,7071075,7071400,4509060,7118888},
1384
			id = 1,
1385
			icon = {"15c60376d57",2,-1},
1386
			color = "E29E71",
1387
		},
1388
		[6] = {
1389
			name = "Puzzle",
1390
			queue = {5993927,7057010,5507021,6994066,6332986,7074686,3448597,2887357,6576282,4514386,7079827,7079880},
1391
			id = 1,
1392
			icon = {"15c6037edb7",0,-1},
1393
			color = "CB56D8",
1394
		},
1395
		[7] = {
1396
			name = "Racing",
1397
			queue = {4140491,3324180,6564380,6600268,6987993,6726599,2283901,6568120,4055924,4361785,3851416,7079644,6347093,6620004,7086768,6797243,2030030,5198518,6230212,6340023,7069304,4362362,5981054,4364504,7086737,6623930},
1398
			id = 1,
1399
			icon = {"15c6037ccd7",-5,-5},
1400
			color = "9DBCF2",
1401
		},
1402
		[8] = {
1403
			name = "Snow",
1404
			queue = {4396371,5632126,7079092,4531989,4509584},
1405
			id = 1,
1406
			icon = {"15c6037b089",5,1},
1407
			color = "C4F4F6",
1408
			after = function()
1409
				if os.date("%m") == "12" then
1410
					tfm.exec.chatMessage("<PS>Merry christmas :)")
1411
					tfm.exec.snow(60)
1412
				end
1413
			end,
1414
		},
1415
		[9] = {
1416
			name = "Miscellaneous",
1417
			queue = {6226386,5425815,7047955,6558179,6961916,6968299,6935117,4802574,7087798,6335452,7093647,7145064},
1418
			id = 1,
1419
			icon = {"15c6036fb66",-10,-2},
1420
			color = "DED963",
1421
		},
1422
		[10] = {
1423
			name = "Cooperation",
1424
			queue = {3326675,4184558,5198607,6988672},
1425
			id = 1,
1426
			icon = {"15c60374f1f",-3,-1},
1427
			color = "2EBA7E",
1428
		},
1429
		[11] = {
1430
			name = "Vampire",
1431
			queue = {5043429,4361619,4633670},
1432
			id = 1,
1433
			icon = {"15c60380b12",-10,-5},
1434
			color = "CB546B",
1435
			after = function()
1436
				if os.date("%m") == "10" then
1437
					tfm.exec.chatMessage("<R>Happy Halloween :>")
1438
				end
1439
			end,
1440
		},
1441
		[12] = {
1442
			name = "House",
1443
			queue = {510966},
1444
			id = 1,
1445
			icon = {"15cb6dbea83",-8,-4},
1446
			color = "D1AB83",
1447
			after = function()
1448
				tfm.exec.setGameTime(1800) -- 30 minutes
1449
				tfm.exec.chatMessage("<ROSE>" .. system.getTranslation("tribehouse"))
1450
			end,
1451
		},
1452
	},
1453
	rotation = {1,{9,7,4,1,5,7,10,8,6,11,2,1,3,5}},
1454
	newMap = coroutine.wrap(function()
1455
		while true do
1456
			local map
1457
			if os.time() > system.newGameTimer then
1458
				if mode.grounds.rotation[1] > #mode.grounds.rotation[2] then
1459
					mode.grounds.rotation[1] = 1
1460
				end
1461
				
1462
				local category = mode.grounds.rotation[2][mode.grounds.rotation[1]]
1463
				mode.grounds.mapInfo[2] = category
1464
				category = mode.grounds.G[category]
1465
				mode.grounds.mapInfo[5] = category.color
1466
				map = category.queue[category.id]
1467
				mode.grounds.mapInfo[1] = map
1468
				
1469
				category.id = category.id + 1
1470
				
1471
				mode.grounds.afterFunction = category.after or (function() end)
1472
				if category.before then
1473
					category.before()
1474
				end
1475
				
1476
				if category.id > #category.queue then
1477
					category.queue = tableshuffle(category.queue)
1478
					category.id = 1
1479
				end
1480
				
1481
				mode.grounds.rotation[1] = mode.grounds.rotation[1] + 1
1482
			end
1483
			coroutine.yield(map)
1484
		end
1485
	end),
1486
	-- New Map Settings
1487
	review = false,
1488
	afterFunction = (function() end),
1489
	mapInfo = {0,0,0,0,"CAA4CF"}, -- Code, Category, Width, Height, Color
1490
	respawn = 0,
1491
	hasWater = false,
1492
	podium = 0,
1493
	availableRoom = false,
1494
	alivePlayers = 0,
1495
	totalPlayers = 0,
1496
	spawnPoint = {0,0},
1497
	-- Loop Settings
1498
	despawnGrounds = {},
1499
	announceTimer = 0,
1500
	-- Misc Settings
1501
	welcomeMessage = (function()
1502
		if system.roomNumber == 666 then
1503
			return {"<R>","<R>","<R>","<R>"}
1504
		else
1505
			return {"<BV>","<PT>","<BV>","<VP>"}	
1506
		end
1507
	end)(),
1508
	isHouse = system.roomNumber == 801 or system.officialMode[1] == "village",
1509
	-- Leaderboard Settings
1510
	leaderboard = {update = 0,data = {}},
1511
	-- Shop
1512
	shop = {
1513
		images = {
1514
			[1] = {'15a2a340dd5','15a2a342b88','15a2a3449a9','15a2a3459e1','15a2a346953','15a2a3479a3','15a2a348ad3','15a2a349a89','15a2a34aa0d'},
1515
			[3] = {'15a2a35fef7','15a2a36114b','15a2a36240d','15a2a36332f','15a2a3645f3'},
1516
			[7] = {'15a2a3721bc','15a2a3731bb','15a2a3742b6','15a2a375439','15a2a376339'},
1517
			[8] = {'15a2a31b8dc','15a2a31d292','15a2a323150','15a2a32815c','15a2a32af10','15a2a32ce03','15a2a32dc09','15a2a32ecde','15a2a32fc20'},
1518
			[9] = {'15a2a3b475f','15a2a3b5996','15a2a3b6ab9','15a2a3b8250','15a2a3b924f'},
1519
			[10] = {'15a2a3a0156','15a2a3a1229','15a2a3a2460','15a2a3a3702','15a2a3a4c70'},
1520
			[11] = {'15a2a381307','15a2a3824c8','15a2a383682','15a2a384dc1','15a2a3865c5','15a2a38820d','15a2a38a3a8','15a2a38bbd6','15a2a38d0ec'},
1521
			[15] = {'15a2a3c4442','15a2a3c54f3','15a2a3c69b7','15a2a3c78e7','15a2a3c873b'},	
1522
		},
1523
		unpackImages = function(id,e)
1524
			local t = {}
1525
			for k,v in next,mode.grounds.shop.images[id] do
1526
				if #t < e then
1527
					t[#t+1] = v
1528
				end
1529
			end
1530
			return t
1531
		end,
1532
	},
1533
	-- System functions
1534
	concat = function(k,v)
1535
		if type(v) == "table" then
1536
			return tableconcat(v,"\n",function(i,j) return mode.grounds.concat(i,j) end)
1537
		else
1538
			return v
1539
		end
1540
	end,
1541
	listener = function(t,st,from)
1542
		from = (from and from.."." or "")
1543
		for k,v in next,t do
1544
			if type(v) == "table" then
1545
				mode.grounds.listener(v,st,from .. tostring(k))
1546
			else
1547
				st[#st + 1] = from .. k
1548
			end
1549
		end
1550
		return st
1551
	end,
1552
	-- Bar
1553
	uibar = function(id,player,value,color,size,height)
1554
		size = size or 100
1555
		height = height or 20
1556
1557
		if value > size then
1558
			value = size
1559
		elseif value < 0 then
1560
			value = 0
1561
		end
1562
1563
		ui.addTextArea(id,"",player,5,(height+8) * id,size + 4,height,0xC7CED2,1,1,true)
1564
		if value ~= 0 then
1565
			ui.addTextArea(id+1,"",player,6,(height+8) * id + 2,value + 2,height - 4,color,color,1,true)
1566
		end
1567
		ui.addTextArea(id+2,"<p align='center'><B><font color='#0'>"..value.."%",player,5,(height+8) * id,size + 4,height,1,1,0,true)
1568
	end,
1569
	-- Shop
1570
	uishop = function(n)
1571
		if mode.grounds.info[n].groundsDataLoaded then
1572
			for k,v in next,mode.grounds.info[n].shop.image do
1573
				tfm.exec.removeImage(v)
1574
			end
1575
			if not mode.grounds.info[n].shop.accessing then
1576
				local get,index = tablefind(mode.grounds.shop.grounds,mode.grounds.info[n].powersOP.GTYPE,1)
1577
				if get then
1578
					mode.grounds.info[n].shop.page = index
1579
				else
1580
					mode.grounds.info[n].shop.page = 1
1581
				end
1582
				mode.grounds.info[n].shop.accessing = true
1583
			end
1584
			if mode.grounds.info[n].shop.page < 1 then
1585
				mode.grounds.info[n].shop.page = #mode.grounds.shop.grounds
1586
			elseif mode.grounds.info[n].shop.page > #mode.grounds.shop.grounds then
1587
				mode.grounds.info[n].shop.page = 1
1588
			end
1589
			
1590
			local shopTxt = system.getTranslation("shop",n)
1591
			local debuggedGround = mode.grounds.shop.grounds[mode.grounds.info[n].shop.page]
1592
			local ground = system.getTranslation("grounds."..debuggedGround[1],n)
1593
			local G = stringlower(mode.grounds.translations.en.grounds[debuggedGround[1]][1])
1594
			local groundLevel = mode.grounds.info[n].stats.powers[G]
1595
			groundLevel = groundLevel[#groundLevel]
1596
			
1597
			ui.addTextArea(4,"",n,160,50,480,320,0x1a2433,1,1,true)
1598
1599
			ui.addTextArea(5,"",n,171,56,240,15,0x1d5a78,0x1d5a78,1,true)
1600
			ui.addTextArea(6,"<p align='center'><font size='13'>"..stringnick(mode.grounds.cmds.shop),n,170,53,240,25,1,1,0,true)
1601
1602
			ui.addTextArea(7,"<p align='center'><font size='12'><B><a href='event:shop.left'><BV>«</BV></a>  <font size='14'><a href='event:info.grounds."..stringgsub(ground[1],"'","#").."."..ground[2].."'>"..ground[1].."</a></font>  <a href='event:shop.right'><BV>»</BV></a>",n,170,87,240,25,0x073247,0x073247,1,true)
1603
			
1604
			mode.grounds.info[n].shop.image[1] = tfm.exec.addImage(debuggedGround[2][1]..".png","&0",435,70,n)
1605
1606
			local playerData = stringformat("<font size='12'><N>%s <G>: <J>$%s\n<N>%s\n<N>%s <G>: <BL>%s",shopTxt.coin,mode.grounds.info[n].stats.groundsCoins,"%s",shopTxt.power,mathfloor(mathpercent(groundLevel,#debuggedGround[2])).."%%")
1607
			local groundData = ""
1608
			local upgradeData = "<p align='center'><font size='15'><B>%s" .. shopTxt.upgrade
1609
1610
			if (groundLevel + 1) <= #debuggedGround[2] then
1611
				local price = (groundLevel + 1) * (120 * debuggedGround[3])
1612
				playerData = stringformat(playerData,shopTxt.price .. " <G>: <R>$" .. price)
1613
				local iniPerc = mathfloor(mathpercent(1,#mode.grounds.shop.grounds[mode.grounds.info[n].shop.page][2]))
1614
				groundData = stringformat(ground[3],iniPerc)
1615
				upgradeData = stringformat(upgradeData,"<a href='event:shop.buy."..price.."."..G.."'><PT>")
1616
				
1617
				local gId = mode.grounds.info[n].stats.powers[G][#mode.grounds.info[n].stats.powers[G]]
1618
				mode.grounds.info[n].shop.image[2] = tfm.exec.addImage(debuggedGround[2][gId]..".png","&1",540,70,n)
1619
				mode.grounds.info[n].shop.image[3] = tfm.exec.addImage("15a2df6ab69.png","&2",440,205,n)
1620
				mode.grounds.info[n].shop.image[4] = tfm.exec.addImage(debuggedGround[2][gId+1]..".png","&3",540,210,n)
1621
			else
1622
				playerData = stringformat(playerData,"<R>-")
1623
				upgradeData = stringformat(upgradeData,"<V>")
1624
				
1625
				mode.grounds.info[n].shop.image[2] = tfm.exec.addImage(system.getTranslation("max",n)..".png","&2",175,215,n)
1626
			end
1627
			
1628
			ui.addTextArea(8,playerData,n,170,130,240,52,0x073247,0x073247,1,true)
1629
			ui.addTextArea(9,groundData,n,170,200,240,80,0x073247,0x073247,1,true)
1630
1631
			ui.addTextArea(10,upgradeData,n,170,298,240,24,0x073247,0x073247,1,true)
1632
			ui.addTextArea(11,"<p align='center'><font size='15'><R><B><a href='event:shop.close'>"..shopTxt.close.."</a></B>",n,170,339,240,24,0x073247,0x073247,1,true)
1633
1634
			ui.addTextArea(12,"",n,430,62,200,300,0x073247,0x073247,1,true)
1635
			ui.addTextArea(13,"",n,426,58,90,90,0x1a2433,0x1a2433,1,true)
1636
		end
1637
	end,
1638
	-- Profile
1639
	uiprofile = function(n,p)
1640
		if mode.grounds.info[p].groundsDataLoaded then
1641
			local nickSize = #p > 12 and 10 or 15
1642
			ui.addTextArea(14,"<p align='center'><B><R><a href='event:profile.close'>X",n,513,115,20,20,1,1,1,true)
1643
			ui.addTextArea(15,"<p align='center'><B><PS><a href='event:profile.open'>•",n,513,145,20,20,1,1,1,true)
1644
			ui.addTextArea(16,"<p align='center'><font size='16'><B><V>"..p.."</V></B> "..(mode.grounds.info[p].isOnline and "<VP>" or "<R>").."•</font></p><p align='left'><font size='12'>\n<N>" .. stringformat(system.getTranslation("profile",n),"<V>#"..mode.grounds.info[p].ranking,"<V>"..mode.grounds.info[p].stats.rounds,"<V>"..mode.grounds.info[p].stats.podiums,"<V>"..mode.grounds.info[p].stats.deaths,"<J>$"..mode.grounds.info[p].stats.groundsCoins),n,290,115,220,160,0x073247,1,1,true)
1645
		end
1646
	end,
1647
	-- Menu
1648
	uimenu = function(n)
1649
		if not mode.grounds.info[n].menu.accessing then
1650
			mode.grounds.info[n].menu.page = 1
1651
			mode.grounds.info[n].menu.accessing = true
1652
		end
1653
1654
		local langue = system.getTranslation("menu",n)
1655
1656
		if mode.grounds.info[n].menu.page < 1 then
1657
			mode.grounds.info[n].menu.page = #langue
1658
		elseif mode.grounds.info[n].menu.page > #langue then
1659
			mode.grounds.info[n].menu.page = 1
1660
		end
1661
1662
		local popupFormat = "<%s><a href='event:menu.page.%d'>#%s</a>"
1663
		local popups = {}
1664
		for k,v in next,langue do
1665
			popups[#popups+1] = stringformat(popupFormat,(k == mode.grounds.info[n].menu.page and "VP" or "J"),k,stringformat(v[1],stringnick(module._NAME)))
1666
		end
1667
1668
		local popup = {
1669
			x = {663,546},
1670
			d = "«",
1671
			txt = "<font size='11'><J>"..tableconcat(popups,"\n\n")
1672
		}
1673
		if not mode.grounds.info[n].menu.showPopup then
1674
			popup = {
1675
				x = {552,435},
1676
				d = "»",
1677
				txt = "",
1678
			}
1679
		end
1680
		
1681
		local displayText = {tableunpack(langue[mode.grounds.info[n].menu.page])}
1682
1683
		if mode.grounds.info[n].menu.page == 1 then
1684
			displayText[1] = stringformat(displayText[1],stringnick(module._NAME))
1685
			
1686
			local gameModes = "<PT>"
1687
			for k,v in next,{"powers",tableunpack(system.submodes,2)} do
1688
				local room
1689
				if k > 1 then
1690
					room = stringformat("/room #%s%s@%s*%s",module._NAME,mathrandom(0,999),n,system.normalizedModeName(v,false))
1691
				else
1692
					room = stringformat("/room #%s%s%s",v,mathrandom(0,999),n)
1693
				end
1694
				gameModes = gameModes .. stringformat("<a href='event:print.&lt;ROSE>%s'>%s</a>\n",room,room)
1695
			end
1696
			
1697
			displayText[2] = displayText[2] .. "\n\n" .. gameModes
1698
		else
1699
			local textFormat = nil
1700
			if mode.grounds.info[n].menu.page == 2 then
1701
				textFormat = {{},system.getTranslation("grounds",n)}
1702
				for k,v in next,textFormat[2] do
1703
					if v[2] ~= "?" then
1704
						tableinsert(textFormat[1],stringformat("<a href='event:info.grounds.%s.%s'><B>%s</B></a>",stringgsub(v[1],"'","#"),stringgsub(v[2],"%.","@"),stringupper(v[1])))
1705
					end
1706
				end
1707
				displayText[2] = stringformat(displayText[2],"• "..tableconcat(textFormat[1],"\n• "))
1708
			elseif mode.grounds.info[n].menu.page == 3 then
1709
				displayText[2] = tableconcat(displayText[2],"\n",function(k,v)
1710
					return mode.grounds.concat(k,v)
1711
				end)
1712
				displayText[2] = "<font size='10'>" .. stringformat(displayText[2],mode.grounds.cmds.profile,mode.grounds.cmds.shop,mode.grounds.cmds.langue,mode.grounds.cmds.help,mode.grounds.cmds.leaderboard,mode.grounds.cmds.info,mode.grounds.cmds.mapinfo,mode.grounds.cmds.pw)
1713
			elseif mode.grounds.info[n].menu.page == 4 then
1714
				displayText[2] = stringformat(displayText[2] .. "\n\n%s",#mode.grounds.maps.."<N>","<BV><a href='event:print.atelier801¬com/topic?f=6&t=845005'>#"..stringupper(module._NAME).." MAP SUBMISSIONS</a></BV>",tableconcat(mode.grounds.G,"\n",function(k,v)
1715
					return stringformat("<font color='#%s'><a href='event:info.mapCategory.%s'>G%2d</a> : %3d</font>",v.color,k,k,#v.queue)
1716
				end))
1717
			elseif mode.grounds.info[n].menu.page == 5 then
1718
				local concat = {}
1719
				for i,j in next,{{"translators","<CEP>"},{"mapEvaluators","<BV>"}} do
1720
					concat[#concat+1] = j[2] .. tableconcat(mode.grounds.staff[j[1]],"<G>, " .. j[2],function(k,v)
1721
						return stringformat("<a href='event:info.%s.%s'>%s</a>",j[1],k,v[1])
1722
					end)
1723
				end
1724
				displayText[2] = stringformat(displayText[2],"Bolodefchoco",concat[1],concat[2])
1725
			end
1726
		end
1727
1728
		ui.addTextArea(17,"<font size='1'>\n</font><p align='center'><J><B><a href='event:menu.right'>»</a>",n,543,352,40,20,1,1,1,true)
1729
		ui.addTextArea(18,"<font size='1'>\n</font><p align='center'><J><B><a href='event:menu.left'>«</a>",n,217,352,40,20,1,1,1,true)
1730
1731
		ui.addTextArea(19,"<font size='1'>\n</font><p align='center'><PT><B><a href='event:menu.popup'>"..popup.d.."</a>",n,popup.x[1],137,20,20,1,1,1,true)
1732
		ui.addTextArea(20,popup.txt,n,popup.x[2],137,115,125,0x123e54,1,1,true)
1733
1734
		ui.addTextArea(21,"<p align='center'><B><R><a href='event:menu.close'>X",n,543,42,20,20,1,1,1,true)
1735
		ui.addTextArea(22,"<p align='center'><font size='20'><V><B>"..stringupper(displayText[1]).."</B></V><font size='15'>\n<R>_____________\n\n<font size='11'><N><p align='left'>"..displayText[2],n,260,42,280,330,0x073247,1,1,true)
1736
	end,
1737
	-- Info
1738
	uidisplayInfo = function(n,data)
1739
		local what = data[2]
1740
		local title,text,color = "","",""
1741
		if what == "grounds" then
1742
			color = "<N>"
1743
			title = stringgsub(data[3],"#","'")
1744
			local info = stringgsub(data[4],"@",".")
1745
			local groundTxt = system.getTranslation("grounds.12",n)
1746
			if info == groundTxt[2] then
1747
				local colors = {}
1748
				for k,v in next,groundTxt[4] do
1749
					colors[#colors+1] = stringformat("<PT>[•] <N2><font color='#%s'>(#%s)</a> <BL>- <PS>%s",k,k,v)
1750
				end
1751
				text = tableconcat(colors,"\n")
1752
			else
1753
				text = stringformat("<PT>[•] <PS>%s",info)
1754
			end
1755
		elseif what == "mapCategory" then
1756
			data[3] = tonumber(data[3])
1757
			color = "<S>"
1758
			title = "G"..data[3]
1759
			text = stringformat("%s\n# %s\n@ %s",mode.grounds.G[data[3]].name,#mode.grounds.G[data[3]].queue,system.getTranslation("categories." .. data[3],n))
1760
			if mode.grounds.info[n].infoImage[#mode.grounds.info[n].infoImage] then
1761
				tfm.exec.removeImage(mode.grounds.info[n].infoImage[#mode.grounds.info[n].infoImage])
1762
			end
1763
			mode.grounds.info[n].infoImage[#mode.grounds.info[n].infoImage + 1] = tfm.exec.addImage(mode.grounds.G[data[3]].icon[1] .. ".png","&4",360 + mode.grounds.G[data[3]].icon[2],125 + mode.grounds.G[data[3]].icon[3],n)
1764
		elseif mode.grounds.staff[what] then
1765
			local comp = data[3]
1766
			local info = mode.grounds.staff[what][tonumber(comp)]
1767
			title = info[1]
1768
			if what == "translators" then
1769
				color = "<CEP>"
1770
				text = stringformat("[•] !%s %s",mode.grounds.cmds.langue,tableconcat(tableturnTable(info[2]),", "))
1771
			elseif what == "mapEvaluators" then
1772
				color = "<BV>"
1773
				text = stringformat("[•] %s",info[2])
1774
			end
1775
		end
1776
		ui.addTextArea(37,"<p align='center'><B><R><a href='event:info.close'>X",n,528,115,20,20,1,1,1,true)
1777
		ui.addTextArea(38,"<p align='center'><font size='20'><V><B>" .. title .. "</B>" .. color .. (mode.grounds.staff[what] and " •" or "") .. "\n\n<p align='left'><font size='13'>" .. text,n,275,115,250,160,0x073247,1,1,true)
1778
	end,
1779
	-- Leaderboard
1780
	uileaderboard = function(n)
1781
		if os.time() > mode.grounds.leaderboard.update or not n then
1782
			mode.grounds.leaderboard = {update = os.time() + 180e3,data = {}}
1783
			
1784
			local players = {}
1785
			for k,v in next,mode.grounds.info do
1786
				if stringsub(k,1,1) ~= "*" then
1787
					players[#players + 1] = {k,mathfloor((v.stats.rounds - v.stats.deaths)/10) * (v.stats.podiums + 1)}
1788
				end
1789
			end
1790
			tablesort(players,function(p1,p2) return p1[2] > p2[2] end)
1791
1792
			for k,v in next,players do
1793
				mode.grounds.info[v[1]].ranking = k
1794
				if k < 11 then
1795
					tableinsert(mode.grounds.leaderboard.data,"<J>"..k..". " .. (({"<BV>","<PS>","<CE>"})[k] or "<V>") .. "<a href='event:profile.open."..v[1].."'>".. v[1] .. "</a> <BL>- <VP>" .. v[2] .. "G")
1796
				end
1797
			end
1798
			if #mode.grounds.leaderboard.data == 0 then
1799
				mode.grounds.leaderboard.update = 0
1800
			end
1801
		end
1802
1803
		if n then
1804
			mode.grounds.info[n].leaderboardAccessing = true
1805
			local id,y = 25,100
1806
			ui.addTextArea(23,"<p align='center'><B><R><a href='event:ranking.close'>X",n,603,35,20,20,1,1,1,true)
1807
			ui.addTextArea(24,"<p align='center'><font size='45'>" .. stringnick(mode.grounds.cmds.leaderboard),n,200,35,400,350,0x073247,1,1,true)
1808
1809
			for i = 1,10 do
1810
				local v = mode.grounds.leaderboard.data[i] or ""
1811
				local color = id % 2 == 0 and 0x123e54 or 0x042636
1812
				if stringfind(v,n) then
1813
					v = stringgsub(v,"'>(.-)</a>",function(name)
1814
						return "'><a:active>"..name.."</a:active></a>"
1815
					end)
1816
				end
1817
				ui.addTextArea(id,v,n,245,y,315,20,color,color,1,true)
1818
				id = id + 1
1819
				y = y + 28
1820
			end
1821
1822
			ui.addTextArea(id,"",n,230,90,10,285,0x073247,0x073247,1,true)
1823
			ui.addTextArea(id + 1,"",n,565,90,10,285,0x073247,0x073247,1,true)
1824
		end
1825
	end,
1826
	-- Grounds system
1827
	gsys = {
1828
		-- Ground system
1829
		grounds = {},
1830
		disabledGrounds = {},
1831
		collisionArea = {34,40,50,50,40,34,34,35,0,0,40,35,35,23,0,0},
1832
		getTpPos = function(g,center)
1833
			if center then
1834
				return {g.X,g.Y}
1835
			else
1836
				local ang = stringsplit(g.P,"[^,]+",tonumber)
1837
				ang = ang[5]
1838
				local hTP = {g.X,g.Y}
1839
				if ang == 90 or ang == -270 then
1840
					hTP[1] = hTP[1] + g.L/2
1841
				elseif ang == -90 or ang == 270 then
1842
					hTP[1] = hTP[1] - g.L/2
1843
				elseif mathabs(ang) == 180 then
1844
					hTP[2] = hTP[2] + g.H/2
1845
				else
1846
					hTP[2] = hTP[2] - g.H/2
1847
				end
1848
				
1849
				return hTP
1850
			end
1851
		end,
1852
		onGround = function(t,px,py)
1853
			local prop = stringsplit(t.P,"[^,]+",tonumber)
1854
1855
			px,py = px or 0,py or 0
1856
			local offset = {}
1857
			local isOn = false
1858
1859
			local w = tonumber(t.L)
1860
			local h = tonumber(t.H)
1861
			local x = tonumber(t.X)
1862
			local y = tonumber(t.Y)
1863
			local gtype = tonumber(t.T)
1864
			gtype = mathsetLim(gtype,0,15) -- mathmin(15,mathmax(0,gtype))
1865
1866
			if not tablefind({8,9,15},gtype) then
1867
				local area = mode.grounds.gsys.collisionArea[gtype + 1]
1868
				w = w + area
1869
				h = h + area
1870
			end
1871
1872
			if gtype == 13 then
1873
				isOn = mathpythag(x,y,px,py,w)
1874
			else
1875
				local ang = mathrad(prop[5])
1876
1877
				local range = {w = w/2,h = h/2}
1878
1879
				local cosA = mathcos(ang)
1880
				local sinA = mathsin(ang)
1881
				
1882
				local vxA = {x = ((-range.w * cosA - (-range.h) * sinA) + x),y = ((-range.w * sinA + (-range.h) * cosA) + y)}
1883
				local vxB = {x = ((range.w * cosA - (-range.h) * sinA) + x),y = ((range.w * sinA + (-range.h) * cosA) + y)}
1884
				local vxC = {x = ((range.w * cosA - range.h * sinA) + x),y = ((range.w * sinA + range.h * cosA) + y)}
1885
				local vxD = {x = ((-range.w * cosA - range.h * sinA) + x),y = ((-range.w * sinA + range.h * cosA) + y)}
1886
				offset = {vxA,vxB,vxC,vxD}
1887
1888
				local p = 4
1889
				for i = 1,4 do
1890
					if (offset[i].y < py and offset[p].y >= py) or (offset[p].y < py and offset[i].y >= py) then
1891
						if offset[i].x + (py - offset[i].y) / (offset[p].y - offset[i].y) * (offset[p].x - offset[i].x) < px then
1892
							isOn = not isOn
1893
						end
1894
					end
1895
					p = i
1896
				end
1897
			end
1898
1899
			return isOn
1900
		end,
1901
		getGroundProperties = function(xml)
1902
			mode.grounds.gsys.grounds = {}
1903
			stringgsub(xml,"<S (.-)/>", function(parameters)
1904
				local attributes = {}
1905
				stringgsub(parameters,"([%-%w]+)=([\"'])(.-)%2",function(tag,_,value)
1906
					attributes[tag] = tonumber(value) or value
1907
				end)
1908
				mode.grounds.gsys.grounds[#mode.grounds.gsys.grounds + 1] = attributes
1909
			end)
1910
		end,
1911
		groundEffects = function()
1912
			for n,p in next,tfm.get.room.playerList do
1913
				if not p.isDead then
1914
					local affected = false
1915
					for id = 1,#mode.grounds.gsys.grounds do
1916
						local ground = mode.grounds.gsys.grounds[id]
1917
						local newId = id - 1
1918
						if (ground.disablepower or stringsub(ground.P,1,1) == "1" or (ground.v and (_G.currentTime - 3) == (tonumber(ground.v)/1000))) and not mode.grounds.gsys.disabledGrounds[newId] then
1919
							-- If the ground has the disablepower attribute, or is dynamic, or the v despawner attribute exists (after it disappear)
1920
							mode.grounds.gsys.disabledGrounds[newId] = true
1921
						end
1922
						if not mode.grounds.gsys.disabledGrounds[newId] and _G.currentTime >= 3 then
1923
							if mode.grounds.gsys.onGround(ground,p.x,p.y) then
1924
								affected = true
1925
								local gtype = ground.T
1926
								local color = stringupper(tostring(ground.o or ""))
1927
								mode.grounds.info[n].powersOP.GTYPE = gtype
1928
								if gtype == 1 or color == "89A7F5" then -- ice
1929
									system.bindKeyboard(n,32,true,true)
1930
									if color ~= "" then
1931
										mode.grounds.info[n].powersOP.GTYPE = 1
1932
									end
1933
								elseif gtype == 2 or color == "6D4E94" then -- trampoline
1934
									if color ~= "" then
1935
										mode.grounds.info[n].powersOP.GTYPE = 2
1936
									end
1937
								elseif gtype == 3 or color == "D84801" then -- lava
1938
									if color ~= "" then
1939
										mode.grounds.info[n].powersOP.GTYPE = 3
1940
									end
1941
									id = (id > 1 and id - 1 or #mode.grounds.gsys.grounds)
1942
									local g = mode.grounds.gsys.grounds[id]
1943
									local hTP = mode.grounds.gsys.getTpPos(g)
1944
									tfm.exec.displayParticle(36,p.x,p.y,0,0,0,0,n)
1945
									tfm.get.room.playerList[n].x = 0
1946
									tfm.get.room.playerList[n].y = 0
1947
									tfm.exec.movePlayer(n,hTP[1],hTP[2])
1948
									tfm.exec.displayParticle(36,hTP[1],hTP[2],0,0,0,0,n)
1949
								elseif gtype == 8 or color == "9BAABC" then -- cloud
1950
									system.bindKeyboard(n,32,true,true)
1951
								elseif gtype == 7 then -- sand
1952
									ui.addTextArea(-1,"",n,-1500,-1500,3e3,3e3,0xE5CC5D,0xE5CC5D,mode.grounds.stormIntensities[mode.grounds.info[n].stats.powers.sand[1]],false)
1953
									for i = 1,2 do
1954
										tfm.exec.displayParticle(26,mathrandom(800),mathrandom(350),0,0,0,0,n)
1955
										tfm.exec.displayParticle(27,mathrandom(800),mathrandom(350),0,0,0,0,n)
1956
									end
1957
								elseif gtype == 9 then -- water
1958
									if mode.grounds.hasWater then
1959
										mode.grounds.info[n].drown = mode.grounds.info[n].drown + mathrandom(1,mathfloor(mode.grounds.info[n].stats.powers.water[1]))
1960
										mode.grounds.uibar(1,n,mode.grounds.info[n].drown,0x519DDA,100,20)
1961
										if mode.grounds.info[n].drown > 99 then
1962
											tfm.exec.killPlayer(n)
1963
											mode.grounds.uibar(1,n,mode.grounds.info[n].drown,0xDA516D,100,20)
1964
											mode.grounds.info[n].drown = 0
1965
											for i = 1,8 do
1966
												tfm.exec.displayParticle(14,p.x+mathrandom(-50,50),p.y+mathrandom(-20,20),0,-1,0,0,n)
1967
											end
1968
										end
1969
										for i = 1,mathrandom(2,4) do
1970
											tfm.exec.displayParticle(14,p.x+mathrandom(-50,50),p.y+mathrandom(-20,20),0,-1,0,0,n)
1971
										end
1972
									end
1973
								elseif gtype == 10 then -- stone
1974
									system.bindKeyboard(n,32,true,true)
1975
								elseif gtype == 11 or color == "E7F0F2" then -- snow
1976
									system.bindKeyboard(n,32,true,true)
1977
								elseif gtype == 12 or gtype == 13 then -- retangle or circle
1978
									if color == "C90909" then
1979
										tfm.exec.killPlayer(n)
1980
									elseif color == "18C92B" then
1981
										if os.time() > mode.grounds.respawn then
1982
											mode.grounds.respawn = os.time() + 7e3
1983
											for k,v in next,tfm.get.room.playerList do
1984
												if v.isVampire then
1985
													tfm.exec.killPlayer(k)
1986
												elseif v.isDead and mode.grounds.info[k].canRev then
1987
													tfm.exec.respawnPlayer(k)
1988
												end
1989
											end
1990
										end
1991
									elseif color == "555D77" then
1992
										mode.grounds.info[n].checkpoint = id
1993
									end
1994
								elseif gtype == 15 then -- web
1995
									tfm.exec.movePlayer(n,mode.grounds.spawnPoint[1],mode.grounds.spawnPoint[2])
1996
									tfm.get.room.playerList[n].x = 0
1997
									tfm.get.room.playerList[n].y = 0
1998
								end
1999
							end
2000
						end
2001
					end
2002
					if not affected then
2003
						mode.grounds.info[n].powersOP.GTYPE = -1
2004
					end
2005
				end
2006
			end
2007
		end,
2008
	},
2009
	-- Init
2010
	reset = function()
2011
		-- Settings and modes
2012
		mode.grounds.welcomeMessage = (function()
2013
			if system.roomNumber == 666 then
2014
				return {"<R>","<R>","<R>","<R>"}
2015
			else
2016
				return {"<BV>","<PT>","<BV>","<VP>"}	
2017
			end
2018
		end)()
2019
		
2020
		mode.grounds.isHouse = system.roomNumber == 801 or system.officialMode[1] == "village"
2021
		
2022
		-- Data
2023
		mode.grounds.info = {}
2024
		
2025
		-- Maps
2026
		mode.grounds.rotation = {1,{9,7,4,1,5,7,10,8,6,11,2,1,3,5}}
2027
	end,
2028
	init = function()
2029
		mode.grounds.translations.pt = mode.grounds.translations.br
2030
	
2031
		-- Sets the main language according to the community
2032
		if mode.grounds.translations[tfm.get.room.community] then
2033
			mode.grounds.langue = tfm.get.room.community
2034
		end
2035
2036
		-- Shuffle the map rotation
2037
		for k,v in next,mode.grounds.G do
2038
			v.queue = tableshuffle(v.queue)
2039
		end
2040
		
2041
		-- Map list
2042
		for k,v in next,mode.grounds.G do
2043
			for i,j in next,v.queue do
2044
				mode.grounds.maps[#mode.grounds.maps + 1] = {j,k}
2045
			end
2046
		end
2047
	
2048
		-- Organizates the staff table
2049
		for k,v in next,mode.grounds.staff do
2050
			tablesort(v,function(t1,t2) return t2[1] > t1[1] end)
2051
		end
2052
		
2053
		-- Organizes the languages
2054
		mode.grounds.langues = (function()
2055
			local l = {}
2056
			for id in next,mode.grounds.translations do
2057
				l[#l + 1] = stringupper(id)
2058
			end
2059
			tablesort(l)
2060
			return l
2061
		end)()
2062
		
2063
		-- Translation indexes
2064
		mode.grounds.translationIndexes = mode.grounds.listener(mode.grounds.translations.en,{})
2065
		
2066
		-- Sets the shop prices, upgrades, etc
2067
		mode.grounds.shop.grounds = {
2068
			-- Ground ID, #Possible upgrades (Imgs), Price average, Upgrade average
2069
			[1] = {1,mode.grounds.shop.unpackImages(1,3),1.05,1.5},
2070
			[2] = {7,mode.grounds.shop.unpackImages(7,4),.4,2},
2071
			[3] = {8,mode.grounds.shop.unpackImages(8,3),1.15,1.47},
2072
			[4] = {9,mode.grounds.shop.unpackImages(9,3),1.6,.6},
2073
			[5] = {10,mode.grounds.shop.unpackImages(10,3),1.1,1.65},
2074
			[6] = {11,mode.grounds.shop.unpackImages(11,5),.5,1.42},
2075
		}
2076
		
2077
		-- Sets the commands
2078
		mode.grounds.cmds = system.getTranslation("commands")
2079
		
2080
		-- Disable commands
2081
		for k,v in next,mode.grounds.cmds do
2082
			disableChatCommand(v)
2083
		end
2084
		for k,v in next,{"o","p","h","k","?","pw","time","np","is","check","review","next","again"} do
2085
			disableChatCommand(v)
2086
		end
2087
		
2088
		-- Official modes running together
2089
		if system.officialMode[1] == "racing" then
2090
			mode.grounds.rotation = {1,{7}}
2091
		elseif system.officialMode[1] == "bootcamp" then
2092
			mode.grounds.rotation = {1,{3}}
2093
		end
2094
		
2095
		-- House system
2096
		if mode.grounds.isHouse then
2097
			system.isRoom = false
2098
			mode.grounds.rotation = {1,{12}}
2099
			tfm.exec.disableAfkDeath()
2100
		end
2101
		
2102
		-- Init
2103
		for _,f in next,{"AutoShaman","AutoScore","AutoNewGame","AutoTimeLeft","MinimalistMode","PhysicalConsumables"} do
2104
			tfm.exec["disable"..f]()
2105
		end
2106
		tfm.exec.setAutoMapFlipMode(false)
2107
		tfm.exec.setRoomMaxPlayers(16)
2108
		
2109
		mode.grounds.alivePlayers,mode.grounds.totalPlayers = system.players()
2110
		
2111
		mode.grounds.uileaderboard()
2112
		system.newTimer(function()
2113
			tfm.exec.newGame(mode.grounds.newMap())
2114
		end,1000,false)
2115
	end,
2116
	-- Callbacks
2117
	eventTextAreaCallback = function(i,n,c)
2118
		local p = stringsplit(c,"[^%.]+")
2119
		if p[1] == "shop" and os.time() > mode.grounds.info[n].shop.timer then
2120
			mode.grounds.info[n].shop.timer = os.time() + 900
2121
			if p[2] == "left" then
2122
				mode.grounds.info[n].shop.page = mode.grounds.info[n].shop.page - 1
2123
				mode.grounds.uishop(n)
2124
			elseif p[2] == "right" then
2125
				mode.grounds.info[n].shop.page = mode.grounds.info[n].shop.page + 1
2126
				mode.grounds.uishop(n)
2127
			elseif p[2] == "buy" and mode.grounds.info[n].groundsDataLoaded then
2128
				p[3] = tonumber(p[3]) or 0
2129
				if mode.grounds.info[n].stats.groundsCoins >= p[3] then
2130
					mode.grounds.info[n].stats.groundsCoins = mode.grounds.info[n].stats.groundsCoins - p[3]
2131
					local loc = mode.grounds.info[n].stats.powers[p[4]]
2132
					mode.grounds.info[n].stats.powers[p[4]][#loc] = mode.grounds.info[n].stats.powers[p[4]][#loc] + 1
2133
					mode.grounds.info[n].stats.powers[p[4]][1] = mode.grounds.info[n].stats.powers[p[4]][1] * mode.grounds.shop.grounds[mode.grounds.info[n].shop.page][4]
2134
					tfm.exec.chatMessage(stringformat("<PT>[•] <BV>%s",stringformat(system.getTranslation("bought",n),"<J>$"..p[3].."</J>","<ROSE>"..system.getTranslation("grounds."..mode.grounds.shop.grounds[mode.grounds.info[n].shop.page][1],n)[1].."</ROSE>",n)),n)
2135
					mode.grounds.uishop(n)
2136
				else
2137
					tfm.exec.chatMessage(stringformat("<PT>[•] <R>%s",system.getTranslation("cantbuy",n)),n)
2138
				end
2139
			elseif p[2] == "close" then
2140
				for i = 4,13 do
2141
					ui.removeTextArea(i,n)
2142
				end
2143
				mode.grounds.info[n].shop.accessing = false
2144
				for k,v in next,mode.grounds.info[n].shop.image do
2145
					tfm.exec.removeImage(v)
2146
				end
2147
			end
2148
		elseif p[1] == "profile" then
2149
			if p[2] == "close" then
2150
				for i = 14,16 do
2151
					ui.removeTextArea(i,n)
2152
				end
2153
				mode.grounds.info[n].profileAccessing = false
2154
			elseif p[2] == "open" then
2155
				if p[3] then
2156
					mode.grounds.uiprofile(n,p[3])
2157
				else
2158
					mode.grounds.uiprofile(n,n)
2159
				end
2160
			end
2161
		elseif p[1] == "menu" and os.time() > mode.grounds.info[n].menu.timer then
2162
			mode.grounds.info[n].menu.timer = os.time() + 750
2163
			if p[2] == "page" and p[3] then
2164
				mode.grounds.info[n].menu.page = tonumber(p[3])
2165
				mode.grounds.uimenu(n)
2166
			elseif p[2] == "right" then
2167
				mode.grounds.info[n].menu.page = mode.grounds.info[n].menu.page + 1
2168
				mode.grounds.uimenu(n)
2169
			elseif p[2] == "left" then
2170
				mode.grounds.info[n].menu.page = mode.grounds.info[n].menu.page - 1
2171
				mode.grounds.uimenu(n)
2172
			elseif p[2] == "popup" then
2173
				mode.grounds.info[n].menu.showPopup = not mode.grounds.info[n].menu.showPopup
2174
				mode.grounds.uimenu(n)
2175
			elseif p[2] == "close" then
2176
				for i = 22,17,-1 do
2177
					ui.removeTextArea(i,n)
2178
				end
2179
				mode.grounds.info[n].menu.accessing = false
2180
				if mode.grounds.info[n].showHelp then
2181
					mode.grounds.info[n].showHelp = false
2182
					ui.removeTextArea(0,n)
2183
				end
2184
			end
2185
		elseif p[1] == "print" then
2186
			p[2] = stringgsub(p[2],"¬",".")
2187
			tfm.exec.chatMessage(stringformat("<PT>[•] <BV>%s",p[2]),n)
2188
		elseif p[1] == "ranking" then
2189
			if p[2] == "close" then
2190
				mode.grounds.info[n].leaderboardAccessing = false
2191
				for i = 23,36 do
2192
					ui.removeTextArea(i,n)
2193
				end
2194
			end
2195
		elseif p[1] == "info" then
2196
			if p[2] == "close" then
2197
				for i = 37,38 do
2198
					ui.removeTextArea(i,n)
2199
				end
2200
				for k,v in next,mode.grounds.info[n].infoImage do
2201
					tfm.exec.removeImage(v)
2202
				end
2203
				mode.grounds.info[n].infoImage = {}
2204
			else
2205
				mode.grounds.uidisplayInfo(n,p)
2206
			end
2207
		end
2208
	end,
2209
	-- New Player
2210
	eventNewPlayer = function(n)
2211
		tfm.exec.chatMessage(stringformat("%s[•] %s%s\n\n<G>[^_^] %s%s",mode.grounds.welcomeMessage[2],mode.grounds.welcomeMessage[3],stringformat(system.getTranslation("welcome"),"<ROSE>" .. module._NAME .. mode.grounds.welcomeMessage[1]),mode.grounds.welcomeMessage[4],stringformat(system.getTranslation("developer"),"Bolodefchoco")),n)
2212
		if mathrandom(10) < 3 then
2213
			tfm.exec.chatMessage("<ROSE>[•] Play #powers at /room #powers",n)
2214
		end
2215
		
2216
		if system.isPlayer(n) then
2217
			for _,key in next,mode.grounds.bindKeys do
2218
				if key < 4 then
2219
					system.bindKeyboard(n,key,false,true)
2220
				end
2221
				system.bindKeyboard(n,key,true,true)
2222
			end
2223
		else
2224
			tfm.exec.chatMessage("<R>Souris! :(",n)
2225
		end
2226
		if not mode.grounds.info[n] then
2227
			mode.grounds.info[n] = {
2228
				groundsDataLoaded = true,
2229
				showHelp = true,
2230
				right = true,
2231
				langue = mode.grounds.langue,
2232
				isWalking = false,
2233
				drown = 0,
2234
				ranking = -1,
2235
				canRev = false,
2236
				checkpoint = -1,
2237
				shop = {
2238
					accessing = false,
2239
					page = 0,
2240
					timer = 0,
2241
					image = {},
2242
				},
2243
				menu = {
2244
					accessing = false,
2245
					page = 0,
2246
					timer = 0,
2247
					showPopup = true,
2248
				},
2249
				profileAccessing = false,
2250
				leaderboardAccessing = false,
2251
				profileTimer = 0,
2252
				leaderboardTimer = 0,
2253
				isOnline = true,
2254
				stats = {
2255
					groundsCoins = 1000,
2256
					rounds = 0,
2257
					podiums = 0,
2258
					deaths = 0,
2259
					powers = {
2260
						ice = {25,100,1}, -- power, timer, level
2261
						lava = {0,1}, -- power, level
2262
						sand = {1,1}, -- Txtarea opacity, level
2263
						cloud = {35,100,1}, -- power, timer, level
2264
						water = {5,1}, -- power, level
2265
						stone = {15,2500,700,1}, -- size, despawn timer, timer, level
2266
						snow = {5,100,1}, -- power, timer, level
2267
						spiderweb = {0,1}, -- power, level
2268
					},
2269
				},
2270
				powersOP = {
2271
					TIMER = 0,
2272
					GTYPE = -1,
2273
				},
2274
				infoImage = {},
2275
			}
2276
			if not mode.grounds.isHouse then
2277
				ui.addTextArea(0,"",n,-1500,-1500,3e3,3e3,1,1,.8,true)
2278
				mode.grounds.uimenu(n)
2279
			end
2280
		end
2281
	
2282
		mode.grounds.info[n].isOnline = true
2283
		mode.grounds.info[n].canRev = false
2284
	end,
2285
	-- New Game
2286
	eventNewGame = function()
2287
		local mapName = {}
2288
		if tablefind(mode.grounds.maps,tfm.get.room.xmlMapInfo.mapCode,1) then
2289
			mapName[#mapName + 1] = "<font color='#".. mode.grounds.mapInfo[5] .."'>G" .. mode.grounds.mapInfo[2] .. "</font>"
2290
		else
2291
			mode.grounds.mapInfo = {0,0,0,0,"CAA4CF"}
2292
			mode.grounds.afterFunction = (function() end)
2293
		end
2294
2295
		tfm.exec.setGameTime(3 * 60)
2296
2297
		mode.grounds.podium = 0
2298
		mode.grounds.availableRoom = system.isRoom and mode.grounds.totalPlayers > 2
2299
		if not mode.grounds.availableRoom then
2300
			if mathrandom(30) < 16 then
2301
				if not system.isRoom then
2302
					tfm.exec.chatMessage(stringformat("<PT>[•] <BV>%s",system.getTranslation("countstats.tribe")))
2303
				else
2304
					tfm.exec.chatMessage(stringformat("<PT>[•] <BV>%s",system.getTranslation("countstats.mice")))
2305
				end
2306
			end
2307
		end
2308
2309
		for k,v in next,mode.grounds.info do
2310
			if not system.isPlayer(k) then
2311
				tfm.exec.killPlayer(k)
2312
			end
2313
			if v.groundsDataLoaded and mode.grounds.availableRoom then
2314
				v.stats.rounds = v.stats.rounds + 1
2315
			end
2316
			v.canRev = true
2317
			v.right = true
2318
			v.checkpoint = -1
2319
		end
2320
2321
		mode.grounds.afterFunction()
2322
		
2323
		mode.grounds.hasWater = false
2324
		local deactivateWater = mode.grounds.isHouse
2325
2326
		mode.grounds.despawnGrounds = {}
2327
		mode.grounds.gsys.disabledGrounds = {}
2328
		local currentXml = tfm.get.room.xmlMapInfo
2329
2330
		local xmlPowers = {}
2331
			-- Info
2332
		xmlPowers[1] = { -- Soulmate system
2333
			attribute = "A", -- Soulmate not allowed for rooms with odd amount of players
2334
			func = function()
2335
				if mode.grounds.totalPlayers % 2 ~= 0 then
2336
					tableforeach(mode.grounds.info,tfm.exec.killPlayer)
2337
				end
2338
			end
2339
		}
2340
		xmlPowers[2] = { -- Map Width
2341
			attribute = "L",
2342
			func = function(size)
2343
				if size then
2344
					mode.grounds.mapInfo[3] = tonumber(size)
2345
				end
2346
			end
2347
		}
2348
		xmlPowers[3] = { -- Map Height
2349
			attribute = "H",
2350
			func = function(size)
2351
				if size then
2352
					mode.grounds.mapInfo[4] = tonumber(size)
2353
				end
2354
			end
2355
		}
2356
		
2357
		mode.grounds.mapInfo[3] = mathmax(800,mode.grounds.mapInfo[3])
2358
		mode.grounds.mapInfo[4] = mathmax(400,mode.grounds.mapInfo[4])
2359
			-- Powers
2360
		xmlPowers[4] = { -- mapname
2361
			attribute = "mapname",
2362
			func = function(t)
2363
				if t ~= "" then
2364
					mapName[#mapName + 1] = t
2365
				end
2366
			end
2367
		}
2368
		xmlPowers[5] = { -- disablepower
2369
			attribute = "disablepower",
2370
			func = function(g)
2371
				for ground in stringgmatch(g,"[^,]+") do
2372
					ground = tonumber(ground)
2373
					if ground and not mode.grounds.gsys.disabledGrounds[ground] then
2374
						mode.grounds.gsys.disabledGrounds[ground] = true
2375
					end
2376
				end
2377
			end
2378
		}
2379
		xmlPowers[6] = { -- cheese
2380
			attribute = "cheese",
2381
			func = function()
2382
				tableforeach(mode.grounds.info,tfm.exec.giveCheese)
2383
			end
2384
		}
2385
		xmlPowers[7] = { -- meep
2386
			attribute = "meep",
2387
			func = function()
2388
				tableforeach(mode.grounds.info,tfm.exec.giveMeep)
2389
			end
2390
		}
2391
		xmlPowers[8] = { -- addtime
2392
			attribute = "addtime",
2393
			func = function(minutes)
2394
				tfm.exec.setGameTime((3 + (tonumber(minutes) or 0)) * 60)
2395
			end
2396
		}
2397
		xmlPowers[9] = { -- notwater
2398
			attribute = "notwater",
2399
			func = function()
2400
				deactivateWater = true
2401
			end
2402
		}
2403
		xmlPowers[10] = { -- setvampire
2404
			attribute = "setvampire",
2405
			func = function(coordinates)
2406
				if mode.grounds.totalPlayers > 2 then
2407
					local coord,axY = xml.getCoordinates(coordinates)
2408
2409
					local vampires,p = {},{}
2410
					for k,v in next,mode.grounds.info do
2411
						if v.isOnline then
2412
							p[#p + 1] = k
2413
						end
2414
					end
2415
					local randomVamp = ""
2416
					for i = 1,mathfloor(mode.grounds.totalPlayers/3) do
2417
						repeat
2418
							randomVamp = tablerandom(p)
2419
						until not tablefind(vampires,randomVamp)
2420
						vampires[#vampires + 1] = randomVamp
2421
					end
2422
					for k,v in next,vampires do
2423
						if type(coord) == "table" then
2424
							local c = tablerandom(coord)
2425
							tfm.exec.movePlayer(v,c.x,c.y)
2426
						else
2427
							if axY == 0 then
2428
								tfm.exec.movePlayer(v,coord,mathrandom(10,mode.grounds.mapInfo[4] - 10))
2429
							else
2430
								tfm.exec.movePlayer(v,mathrandom(10,mode.grounds.mapInfo[4] - 10),axY)
2431
							end
2432
						end
2433
						tfm.exec.setVampirePlayer(v)
2434
					end
2435
				else
2436
					tableforeach(mode.grounds.info,tfm.exec.setVampirePlayer)
2437
				end
2438
			end
2439
		}
2440
		xmlPowers[11] = { -- shaman
2441
			attribute = "shaman",
2442
			func = function(t)
2443
				if t ~= "" then
2444
					ui.setShamanName(t)
2445
				end
2446
			end
2447
		}	
2448
2449
		xml.attribFunc(currentXml.xml or "",xmlPowers)
2450
2451
		mode.grounds.gsys.getGroundProperties(currentXml.xml)
2452
2453
		if not deactivateWater then
2454
			for k,v in next,mode.grounds.gsys.grounds do
2455
				if v.T == 9 then
2456
					mode.grounds.hasWater = true
2457
					for k,v in next,mode.grounds.info do
2458
						v.drown = 0
2459
						mode.grounds.uibar(1,k,v.drown,0x519DDA,100,20)
2460
					end
2461
					break
2462
				end
2463
			end
2464
		end
2465
		if not mode.grounds.hasWater then
2466
			for i = 1,3 do
2467
				ui.removeTextArea(i)
2468
			end
2469
		end
2470
		
2471
		local ini = ""
2472
		local D = stringmatch(tfm.get.room.xmlMapInfo.xml,"<D>(.-)</D>") or ""
2473
		for k,v in next,{"DS","T"} do
2474
			ini = stringmatch(D,"<"..v.." (.-)/>")
2475
			if ini then
2476
				break
2477
			end
2478
		end
2479
		ini = ini or ""
2480
		local sX = stringmatch(ini,"X=\"(.-)\"")
2481
		local sY = stringmatch(ini,"Y=\"(.-)\"")
2482
		mode.grounds.spawnPoint = {tonumber(sX) or 0,tonumber(sY) or 0}
2483
		
2484
		ui.setMapName(tableconcat(mapName,"   <G>|<J>   ") .. (#mapName > 0 and "   <G>|<J>   " or "") .. currentXml.author .. " <BL>- " .. tfm.get.room.currentMap)
2485
	end,
2486
	-- Loop
2487
	eventLoop = function()
2488
		mode.grounds.gsys.groundEffects()
2489
		
2490
		if _G.currentTime % 5 == 0 then
2491
			mode.grounds.alivePlayers,mode.grounds.totalPlayers = system.players()
2492
		end
2493
		
2494
		if not mode.grounds.isHouse and _G.currentTime == 3 and mathrandom(50) < 16 and os.time() > mode.grounds.announceTimer then
2495
			mode.grounds.announceTimer = os.time() + 5000
2496
			tfm.exec.chatMessage(stringformat("<PT>[•] <BV>%s",system.getTranslation("powersenabled")))
2497
		end
2498
2499
		if mode.grounds.isHouse then
2500
			if _G.currentTime%5 == 0 then
2501
				if _G.leftTime <= 2 then
2502
					tfm.exec.newGame(mode.grounds.newMap())
2503
				end
2504
			end
2505
		else
2506
			if _G.currentTime%2 == 0 and not mode.grounds.review then
2507
				if mode.grounds.alivePlayers < 1 or _G.leftTime <= 2 then
2508
					tfm.exec.newGame(mode.grounds.newMap())
2509
				elseif mode.grounds.alivePlayers == 1 and _G.leftTime > 50 and mode.grounds.totalPlayers > 1 then
2510
					tfm.exec.setGameTime(30)
2511
				elseif mode.grounds.podium > 5 and mode.grounds.alivePlayers > 3 then
2512
					tfm.exec.setGameTime(20,false)
2513
				end
2514
			end
2515
		end
2516
2517
		--[[
2518
		local grounds = {}
2519
		for k,v in next,mode.grounds.despawnGrounds do
2520
			grounds[k] = v
2521
		end
2522
		for k,v in next,grounds do
2523
			if os.time() > v[2] then
2524
				tfm.exec.removePhysicObject(v[1])
2525
				tableremove(mode.grounds.despawnGrounds,k)
2526
			end
2527
		end
2528
		]]
2529
		
2530
		for n,v in next,mode.grounds.info do
2531
			v.isWalking = (tfm.get.room.playerList[n] and (tfm.get.room.playerList[n].movingRight or tfm.get.room.playerList[n].movingLeft) or false)
2532
			v.right = (tfm.get.room.playerList[n] and (tfm.get.room.playerList[n].isFacingRight) or false)
2533
			if v.powersOP.GTYPE ~= 7 then -- Sand
2534
				ui.removeTextArea(-1,n)
2535
			end
2536
			if mode.grounds.hasWater then
2537
				if _G.currentTime%2 == 0 then
2538
					if tfm.get.room.playerList[n] then
2539
						if not tfm.get.room.playerList[n].isDead and v.powersOP.GTYPE ~= 9 then -- Water
2540
							if v.drown > 0 then
2541
								v.drown = v.drown - mathrandom(1,mathfloor(v.stats.powers.water[1]))
2542
								mode.grounds.uibar(1,n,v.drown,0x519DDA,100,20)
2543
							end
2544
						end
2545
					end
2546
				end
2547
			end
2548
		end
2549
	end,
2550
	-- Keyboard
2551
	eventKeyboard = function(n,k,d,x,y)
2552
		tfm.get.room.playerList[n].x = x
2553
		tfm.get.room.playerList[n].x = y
2554
		if tablefind(mode.grounds.bindKeys,k) then
2555
			if k < 4 then
2556
				if k == 0 then
2557
					mode.grounds.info[n].right = false
2558
				elseif k == 2 then
2559
					mode.grounds.info[n].right = true
2560
				end
2561
			elseif k == stringbyte("O") then
2562
				mode.grounds.eventChatCommand(n,"o")
2563
			elseif k == stringbyte("P") then
2564
				if mode.grounds.info[n].profileAccessing then
2565
					mode.grounds.eventTextAreaCallback(nil,n,"profile.close")
2566
				else
2567
					if os.time() > mode.grounds.info[n].profileTimer then
2568
						mode.grounds.info[n].profileTimer = os.time() + 1e3
2569
						mode.grounds.eventChatCommand(n,"p")
2570
					end
2571
				end
2572
			elseif k == stringbyte("H") then
2573
				mode.grounds.eventChatCommand(n,"h")
2574
			elseif k == stringbyte("K") then
2575
				mode.grounds.eventChatCommand(n,"k")
2576
			end
2577
		else
2578
			if k == 32 and os.time() > mode.grounds.info[n].powersOP.TIMER then
2579
				local ms = 0
2580
				local power = {0,0}
2581
				if mode.grounds.info[n].powersOP.GTYPE == 8 then -- Cloud
2582
					power = mode.grounds.info[n].stats.powers.cloud
2583
					ms = power[2]
2584
					tfm.exec.movePlayer(n,0,0,true,0,-power[1],true)
2585
				elseif mode.grounds.info[n].powersOP.GTYPE == 1 and mode.grounds.info[n].isWalking then -- Ice
2586
					power = mode.grounds.info[n].stats.powers.ice
2587
					ms = power[2]
2588
					tfm.exec.movePlayer(n,0,0,false,(mode.grounds.info[n].right and power[1] or -power[1]),0,true)
2589
				elseif mode.grounds.info[n].powersOP.GTYPE == 11 and not mode.grounds.info[n].isWalking then -- Snow
2590
					power = mode.grounds.info[n].stats.powers.snow
2591
					ms = power[2]
2592
					tfm.exec.addShamanObject(34,x + (mode.grounds.info[n].right and 20 or -20),y - 5,0,(mode.grounds.info[n].right and power[1] or -power[1]))
2593
					tfm.exec.playEmote(n,26)
2594
				elseif mode.grounds.info[n].powersOP.GTYPE == 10 and not mode.grounds.info[n].isWalking then -- Stone
2595
					power = mode.grounds.info[n].stats.powers.stone
2596
					local id = tfm.get.room.playerList[n].id
2597
					if not mode.grounds.despawnGrounds[id] then--if not tablefind(mode.grounds.despawnGrounds,id,1) then
2598
						ms = power[3]
2599
						local halfSize = (power[1]/2) + 15
2600
						tfm.exec.addPhysicObject(id,x + (mode.grounds.info[n].right and halfSize or -halfSize),y + 32 - halfSize,{
2601
							type = 10,
2602
							miceCollision = true,
2603
							groundCollision = false,
2604
							width = power[1],
2605
							height = power[1],
2606
							friction = .3,
2607
							restitution = 0
2608
						})
2609
						mode.grounds.despawnGrounds[id] = true
2610
2611
						system.newTimer(function()
2612
							tfm.exec.removePhysicObject(id)
2613
							mode.grounds.despawnGrounds[id] = nil
2614
						end,power[2],false)
2615
						--tableinsert(mode.grounds.despawnGrounds,{id,os.time() + power[2]})
2616
					end
2617
				end
2618
				mode.grounds.info[n].powersOP.TIMER = os.time() + ms
2619
				system.bindKeyboard(n,32,true,false)
2620
			end
2621
			mode.grounds.info[n].powersOP.GTYPE = -1
2622
		end
2623
	end,
2624
	-- Commands
2625
	eventChatCommand = function(n,c)
2626
		if system.isPlayer(n) then
2627
			c = deactivateAccents(c)
2628
			system.disableChatCommandDisplay(c,true)
2629
			local p = stringsplit(c,"[^%s]+",stringlower)
2630
			disableChatCommand(p[1])
2631
			if (p[1] == mode.grounds.cmds.shop or p[1] == "o") and not mode.grounds.isHouse then
2632
				if mode.grounds.info[n].shop.accessing then
2633
					mode.grounds.eventTextAreaCallback(nil,n,"shop.close")
2634
				else
2635
					if os.time() > mode.grounds.info[n].shop.timer then
2636
						mode.grounds.info[n].shop.timer = os.time() + 1200
2637
						mode.grounds.uishop(n)
2638
					end
2639
				end
2640
			elseif (p[1] == mode.grounds.cmds.profile or p[1] == "p") and not mode.grounds.isHouse then
2641
				if p[2] then
2642
					p[2] = stringnick(p[2])
2643
					if mode.grounds.info[p[2]] then
2644
						mode.grounds.uiprofile(n,p[2])
2645
					end
2646
				else
2647
					mode.grounds.uiprofile(n,n)
2648
				end
2649
				mode.grounds.info[n].profileAccessing = true
2650
			elseif p[1] == mode.grounds.cmds.help or p[1] == "h" then
2651
				if mode.grounds.info[n].menu.accessing then
2652
					mode.grounds.eventTextAreaCallback(nil,n,"menu.close")
2653
				else
2654
					if os.time() > mode.grounds.info[n].menu.timer then
2655
						mode.grounds.info[n].menu.timer = os.time() + 1e3
2656
						mode.grounds.uimenu(n)
2657
					end
2658
				end
2659
			elseif p[1] == mode.grounds.cmds.langue then
2660
				p[2] = p[2] and stringlower(p[2]) or nil
2661
				if p[2] and (p[2] == "default" or mode.grounds.translations[p[2]]) then
2662
					if p[2] == "default" then
2663
						mode.grounds.info[n].langue = (mode.grounds.translations[tfm.get.room.playerList[n].community] and tfm.get.room.playerList[n].community or mode.grounds.langue)
2664
					else
2665
						mode.grounds.info[n].langue = stringlower(p[2])
2666
					end
2667
					tfm.exec.chatMessage(stringformat("<PT>[•] <BV>%s",stringformat(system.getTranslation("language",n),stringupper(mode.grounds.info[n].langue))),n)
2668
				else
2669
					tfm.exec.chatMessage(stringformat("<PT>[•] <J>!%s <PS>%s",p[1],tableconcat(mode.grounds.langues," <G>-</G> ")),n)
2670
				end
2671
			elseif (p[1] == mode.grounds.cmds.leaderboard or p[1] == "k") and not mode.grounds.isHouse then
2672
				if mode.grounds.info[n].leaderboardAccessing then
2673
					mode.grounds.eventTextAreaCallback(nil,n,"ranking.close")
2674
				else
2675
					if os.time() > mode.grounds.info[n].leaderboardTimer then
2676
						mode.grounds.info[n].leaderboardTimer = os.time() + 1e3
2677
						mode.grounds.uileaderboard(n)
2678
					end
2679
				end
2680
			elseif p[1] == mode.grounds.cmds.info or p[1] == "?" then
2681
				local grounds = system.getTranslation("grounds",n)
2682
				local ground = grounds[mode.grounds.info[n].powersOP.GTYPE]
2683
				if ground then
2684
					mode.grounds.uidisplayInfo(n,{"info","grounds",stringgsub(ground[1],"'","#"),ground[2]})
2685
				end
2686
			elseif p[1] == "mapinfo" and mode.grounds.mapInfo[2] > 0 then
2687
				tfm.exec.chatMessage(stringformat("<PT>[•] <BV>G%s (%s) - %s - @%s",mode.grounds.mapInfo[2],mode.grounds.G[mode.grounds.mapInfo[2]].name,tfm.get.room.xmlMapInfo.author,mode.grounds.mapInfo[1]),n)
2688
			else
2689
				local isAdmin,isMapEv,isTranslator = system.roomAdmins[n],tablefind(mode.grounds.staff.mapEvaluators,n,1),tablefind(mode.grounds.staff.translators,n,1)
2690
				if p[1] == mode.grounds.cmds.pw or p[1] == "pw" then
2691
					if isAdmin then
2692
						local newPassword = p[2] and tableconcat(p," ",nil,2) or ""
2693
						local pwMsg = system.getTranslation("password")
2694
						if newPassword == "" then
2695
							tfm.exec.chatMessage(stringformat("<R>[•] %s",pwMsg.off))
2696
						else
2697
							local xxx = stringrep("*",#newPassword)
2698
							for k in next,mode.grounds.info do
2699
								if system.roomAdmins[k] and system.isPlayer(k) then
2700
									tfm.exec.chatMessage(stringformat("<R>[•] %s",stringformat(pwMsg.on,newPassword)),k)
2701
								else
2702
									tfm.exec.chatMessage(stringformat("<R>[•] %s",stringformat(pwMsg.on,xxx)),k)
2703
								end
2704
							end
2705
						end
2706
						tfm.exec.setRoomPassword(newPassword)
2707
					else
2708
						tfm.exec.chatMessage("<ROSE>[•] /room #" .. module._NAME .. mathrandom(0,999) .. "@" .. n,n)
2709
					end
2710
				end
2711
				if not system.isRoom then
2712
					local permission = (mode.grounds.isHouse and system.roomAdmins[n] or isMapEv)
2713
					if p[1] == "time" and permission then
2714
						tfm.exec.setGameTime(p[2] or 1e7)
2715
					elseif p[1] == "np" and p[2] and permission then
2716
						mode.grounds.mapInfo = {0,0,0,0,"CAA4CF"}
2717
						tfm.exec.newGame(p[2])
2718
					elseif p[1] == "review" and isMapEv then
2719
						mode.grounds.review = not mode.grounds.review
2720
						tfm.exec.chatMessage("<BV>[•] REVIEW MODE : " .. stringupper(tostring(mode.grounds.review)),n)
2721
						tfm.exec.disableAfkDeath(mode.grounds.review)
2722
						if mode.grounds.review then
2723
							tableforeach(mode.grounds.info,tfm.exec.respawnPlayer)
2724
						end
2725
					elseif p[1] == "next" and _G.currentTime > 10 and permission then
2726
						tfm.exec.newGame(mode.grounds.newMap())
2727
					elseif p[1] == "again" and _G.currentTime > 10 and permission then
2728
						if tfm.get.room.currentMap then
2729
							tfm.exec.newGame(tfm.get.room.currentMap)
2730
						end
2731
					end
2732
				end
2733
				if p[1] == "is" and (mode.grounds.isHouse or isMapEv) then
2734
					p[2] = p[2] or tfm.get.room.currentMap
2735
					p[2] = tonumber(stringmatch(p[2],"@?(%d+)")) or 0
2736
					
2737
					local exist,index = tablefind(mode.grounds.maps,p[2],1)
2738
					local cat = exist and mode.grounds.maps[index][2] or 0
2739
					tfm.exec.chatMessage(stringformat("<BV>[•] @%s : %s",p[2],stringupper(tostring(exist)) .. (exist and " (G"..cat..")" or "")),n)
2740
				end	
2741
				if p[1] == "check" and isTranslator then
2742
					p[2] = p[2] and stringlower(p[2]) or nil
2743
					if p[2] and mode.grounds.translations[p[2]] then
2744
						local newP3 = p[3] and system.loadTable("mode.grounds.translations."..p[2].."."..p[3]) or {}
2745
						if newP3 and type(newP3) == "string" then
2746
							tfm.exec.chatMessage("<CEP>[•] [" .. p[3] .. "] : <N><VI>\"</VI>" .. newP3 .. "<VI>\"</VI>",n)
2747
						else
2748
							tfm.exec.chatMessage("<CEP>[•] " .. (p[3] and "Invalid! Try one of these indexes:" or "!" .. p[1] .. " " .. p[2] .. " <VI>id"),n)
2749
							for k,v in next,mode.grounds.translationIndexes do
2750
								tfm.exec.chatMessage("<N>\t\t" .. v,n)
2751
							end
2752
						end
2753
					else
2754
						tfm.exec.chatMessage("<CEP>[•] !" .. p[1] .. " " .. tableconcat(mode.grounds.langues," <G>-</G> "),n)
2755
					end
2756
				end
2757
			end
2758
		end
2759
	end,
2760
	-- Victory
2761
	eventPlayerWon = function(n)
2762
		if mode.grounds.availableRoom and mode.grounds.info[n].groundsDataLoaded and system.isPlayer(n) then
2763
			mode.grounds.podium = mode.grounds.podium + 1
2764
			
2765
			if mode.grounds.podium < 4 then
2766
				mode.grounds.info[n].stats.podiums = mode.grounds.info[n].stats.podiums + 1
2767
				
2768
				local addedCoins = 20 - mode.grounds.podium * 5
2769
				mode.grounds.info[n].stats.groundsCoins = mode.grounds.info[n].stats.groundsCoins + addedCoins
2770
				tfm.exec.setPlayerScore(n,4-podium,true)
2771
				tfm.exec.chatMessage(stringformat("<PT>[•] <BV>%s",stringformat(system.getTranslation("gotcoin",n),"<J>+$"..addedCoins.."</J>")),n)
2772
				
2773
				if mode.grounds.podium == 1 then
2774
					tfm.exec.setGameTime(60,false)
2775
				end
2776
			else
2777
				if mode.grounds.podium == 4 then
2778
					tfm.exec.setGameTime(30,false)
2779
				end
2780
				
2781
				mode.grounds.info[n].stats.groundsCoins = mode.grounds.info[n].stats.groundsCoins + 1
2782
				tfm.exec.setPlayerScore(n,1,true)
2783
			end
2784
			
2785
			if mode.grounds.hasWater then
2786
				mode.grounds.uibar(1,n,mode.grounds.info[n].drown,0x6FDA51,100,20)
2787
			end
2788
			
2789
			if system.miscAttrib ~= 0 then
2790
				if mode.grounds.podium == system.miscAttrib then
2791
					tfm.exec.setGameTime(0)
2792
				end
2793
			end
2794
		end
2795
		
2796
		if mode.grounds.review or mode.grounds.isHouse then
2797
			tfm.exec.respawnPlayer(n)
2798
		else
2799
			mode.grounds.info[n].canRev = false
2800
		end
2801
	end,
2802
	-- Died
2803
	eventPlayerDied = function(n)
2804
		if mode.grounds.info[n].groundsDataLoaded and mode.grounds.availableRoom then
2805
			mode.grounds.info[n].stats.deaths = mode.grounds.info[n].stats.deaths + 1
2806
		end
2807
		if mode.grounds.hasWater then
2808
			if mode.grounds.info[n].drown > 0 then
2809
				mode.grounds.uibar(1,n,mode.grounds.info[n].drown,0xDA516D,100,20)
2810
			end
2811
		end
2812
		
2813
		system.bindKeyboard(n,32,true,false)
2814
		ui.removeTextArea(-1,n)
2815
		
2816
		if mode.grounds.review or mode.grounds.isHouse then
2817
			tfm.exec.respawnPlayer(n)
2818
		end
2819
	end,
2820
	-- Left
2821
	eventPlayerLeft = function(n)
2822
		if mode.grounds.info[n] then
2823
			mode.grounds.info[n].isOnline = false
2824
		end
2825
	end,
2826
	-- Respawn
2827
	eventPlayerRespawn = function(n)
2828
		if mode.grounds.info[n].checkpoint ~= -1 then
2829
			local g = mode.grounds.gsys.grounds[mode.grounds.info[n].checkpoint]
2830
			local hTP = mode.grounds.gsys.getTpPos(g,true)
2831
			tfm.exec.movePlayer(n,hTP[1],hTP[2])
2832
		end
2833
		if mode.grounds.info[n].groundsDataLoaded and mode.grounds.availableRoom then
2834
			mode.grounds.info[n].stats.rounds = mode.grounds.info[n].stats.rounds + 1
2835
		end
2836
		if mode.grounds.hasWater then
2837
			mode.grounds.uibar(1,n,mode.grounds.info[n].drown,0x519DDA,100,20)
2838
		end
2839
		
2840
		if not mode.grounds.isHouse then
2841
			tfm.exec.chatMessage(stringformat("<R>[•] %s",system.getTranslation("zombie",n)),n)
2842
		end
2843
	end,
2844
}
2845
2846
--[[ Jokenpo ]]--
2847
mode.jokenpo = {
2848
	-- Translations
2849
	translations = {
2850
		en = {
2851
			-- Init
2852
			welcome = "Welcome to <ROSE>#Jokenpo<CE>! Choose a chair, press space and start playing!\n\tReport any issue to Bolodefchoco",
2853
			
2854
			-- Simple words
2855
			round = "Round",
2856
			players = "Players",
2857
			won = "won the round!",
2858
			tie = "Tie!",
2859
			victory = "won the game!",
2860
			
2861
			-- Info
2862
			guide = "Press\n\t<PS>»</PS> %s<PT> - Rock</PT>\n\t<PS>»</PS> %s<PT> - Paper</PT>\n\t<PS>»</PS> %s<PT> - Scissor (Pufferfish)</PT>",
2863
			
2864
			-- Game
2865
			items = {"Rock","Paper","Scissor"},
2866
			selected = "You've selected the item %s!",
2867
		},
2868
		br = {
2869
			welcome = "Bem-vindo ao <ROSE>#Jokenpo<CE>! Escolha uma cadeira, aperte espaço e comece a jogar!\n\tReporte qualquer problema para Bolodefchoco",
2870
		
2871
			round = "Partida",
2872
			players = "Jogadores",
2873
			won = "venceu a partida!",
2874
			tie = "Empate!",
2875
			victory = "ganhou!",
2876
			
2877
			guide = "Pressione\n\t<PS>»</PS> %s<PT> - Pedra</PT>\n\t<PS>»</PS> %s<PT> - Papel</PT>\n\t<PS>»</PS> %s<PT> - Tesoura (Baiacu)</PT>",
2878
			
2879
			items = {"Pedra","Papel","Tesoura"},
2880
			selected = "Você selecionou o item %s!",
2881
		},
2882
	},
2883
	langue = "en",
2884
	-- Maps
2885
	maps = {5198315,4093087},
2886
	buildSquares = function(c)
2887
		tfm.exec.removePhysicObject(1)
2888
		for k,v in next,{{346,224},{454,224},{400,105}} do
2889
			for i = 1,4 do
2890
				local x = i == 1 and v[1] + 28 or i == 2 and v[1] - 28 or v[1]
2891
				local y = i == 3 and v[2] + 28 or i == 4 and v[2] - 28 or v[2]
2892
				
2893
				local w = x == v[1] and 46 or 10
2894
				local h = w == 10 and 66 or 10
2895
				
2896
				tfm.exec.addPhysicObject(i..k,x,y,{
2897
					type = 12,
2898
					color = c[k],
2899
					width = w,
2900
					height = h,
2901
				})
2902
			end
2903
		end
2904
	end,
2905
	-- New Round Settings
2906
	playing = false,
2907
	players = {},
2908
	colors = {0xE3454D,0x4577E3,0x45E374},
2909
	timer = 9.5,
2910
	partialTimer = 0,
2911
	tie = 0,
2912
	round = 0,
2913
	roundsPerGame = 5,
2914
	-- Game settings
2915
	objects = {
2916
		85,
2917
		95,
2918
		65,
2919
	},
2920
	-- Emotes
2921
	emote = {
2922
		sit = 8,
2923
		victory = 24,
2924
		fail = 5,
2925
		tie = 4,
2926
		no = 2
2927
	},
2928
	-- Battle
2929
	decision = function()
2930
		for i = 1,2 do
2931
			mode.jokenpo.players[i].obj = mode.jokenpo.players[i].obj ~= 0 and mode.jokenpo.players[i].obj or false
2932
			if mode.jokenpo.players[i].obj then
2933
				mode.jokenpo.players[i].remId = tfm.exec.addShamanObject(mode.jokenpo.objects[mode.jokenpo.players[i].obj],({350,455})[i],200)
2934
			end
2935
		end
2936
2937
		local winner = ((mode.jokenpo.players[1].obj and mode.jokenpo.players[2].obj) and ((3 + mode.jokenpo.players[1].obj - mode.jokenpo.players[2].obj) % 3) or mode.jokenpo.players[1].obj and 1 or mode.jokenpo.players[2].obj and 2 or 0)
2938
		
2939
		if winner == 0 then
2940
			mode.jokenpo.tie = mode.jokenpo.tie + 1
2941
			tfm.exec.chatMessage("<CE>[•] <J>" .. system.getTranslation("tie"))
2942
			
2943
			for k,v in next,mode.jokenpo.players do
2944
				tfm.exec.playEmote(v.name,mode.jokenpo.emote.tie)
2945
			end
2946
		else
2947
			mode.jokenpo.players[winner].score = mode.jokenpo.players[winner].score + 1
2948
			tfm.exec.playEmote(mode.jokenpo.players[winner].name,mode.jokenpo.emote.victory)
2949
			
2950
			local looser = (winner == 1 and 2 or 1)
2951
			local looserEmote = mode.jokenpo.emote.fail
2952
			if not mode.jokenpo.players[looser].obj then
2953
				looserEmote = mode.jokenpo.emote.no
2954
			end
2955
			tfm.exec.playEmote(mode.jokenpo.players[looser].name,looserEmote)
2956
2957
			tfm.exec.chatMessage("<CE>[•] " .. mode.jokenpo.players[winner].color .. mode.jokenpo.players[winner].name .. " " .. system.getTranslation("won"))
2958
		end
2959
		
2960
		ui.addTextArea(5,stringformat("<font size='50'><p align='center'>%s%d <PT>| <J>%d <PT>| %s%s",mode.jokenpo.players[1].color,mode.jokenpo.players[1].score,mode.jokenpo.tie,mode.jokenpo.players[2].color,mode.jokenpo.players[2].score),nil,5,270,795,nil,1,1,0,true)
2961
	end,
2962
	-- Partial Next Round
2963
	pNextRound = function()
2964
		mode.jokenpo.playing = false
2965
		mode.jokenpo.timer = 9.5
2966
		mode.jokenpo.partialTimer = 3.5
2967
		mode.jokenpo.decision()
2968
		if mode.jokenpo.round == mode.jokenpo.roundsPerGame then
2969
			tablesort(mode.jokenpo.players,function(p1,p2) return p1.score > p2.score end)
2970
			if (mode.jokenpo.players[1].score == mode.jokenpo.players[2].score) or (mode.jokenpo.tie > mode.jokenpo.players[1].score) then
2971
				tfm.exec.chatMessage("<CE>[•] " .. system.getTranslation("tie"))
2972
			else
2973
				tfm.exec.chatMessage("<CE>[•] " .. mode.jokenpo.players[1].color .. mode.jokenpo.players[1].name .. " " .. system.getTranslation("victory"))
2974
			end
2975
		end
2976
	end,
2977
	-- Next Round
2978
	nextRound = function()
2979
		for i = 1,2 do
2980
			if mode.jokenpo.players[i].remId then
2981
				tfm.exec.removeObject(mode.jokenpo.players[i].remId)
2982
			end
2983
			mode.jokenpo.players[i].remId = nil
2984
			mode.jokenpo.players[i].obj = 0
2985
		end
2986
		ui.removeTextArea(5,nil)
2987
		mode.jokenpo.partialTimer = 0
2988
		if mode.jokenpo.roundsPerGame > mode.jokenpo.round then
2989
			mode.jokenpo.playing = true
2990
			mode.jokenpo.round = mode.jokenpo.round + 1
2991
		else
2992
			mode.jokenpo.playing = false
2993
			mode.jokenpo.round = 0
2994
			mode.jokenpo.tie = 0
2995
			mode.jokenpo.timer = 9.5
2996
			mode.jokenpo.partialTimer = 0
2997
			mode.jokenpo.players = {}
2998
			tfm.exec.newGame(tablerandom(mode.jokenpo.maps))
2999
			for i = 2,3 do
3000
				ui.removeTextArea(i,nil)
3001
			end
3002
		end
3003
		mode.jokenpo.uiinfo()
3004
	end,
3005
	-- Display names
3006
	displayNames = function()
3007
		if #mode.jokenpo.players == 0 then
3008
			return ""
3009
		else
3010
			return "   <G>|   <N>" .. system.getTranslation("players") .. " : " .. tableconcat(mode.jokenpo.players," <V>- ",function(k,v)
3011
				tfm.exec.setNameColor(v.name,mode.jokenpo.colors[v.id])
3012
				return v.color .. v.name
3013
			end)
3014
		end
3015
	end,
3016
	-- Info textareas
3017
	uiinfo = function()
3018
		ui.addTextArea(0,"<p align='center'><font size='35'><J>"..mathfloor(mode.jokenpo.timer),nil,380,85,40,40,1,1,0,true)
3019
		ui.addTextArea(1,"<p align='center'><font size='25'><J><B>X</B><font size='13'>\n"..stringformat("%02d",mode.jokenpo.tie),nil,380,207,40,nil,1,1,0,true)
3020
		
3021
		for k,v in next,mode.jokenpo.players do
3022
			ui.addTextArea(v.id + 1,"<p align='center'>"..v.name.."\n"..stringformat("%02d",v.score),nil,v.x,165,105,nil,1,1,0,true)
3023
		end
3024
		
3025
		ui.setMapName("<PT>#Jokenpo   <G>|   <N>" .. system.getTranslation("round") .. " : <V>" .. mode.jokenpo.round .. mode.jokenpo.displayNames() .. "<")
3026
	end,
3027
	-- Init
3028
	reset = function()
3029
		-- Scores
3030
		mode.jokenpo.tie = 0
3031
		mode.jokenpo.round = 0
3032
		mode.jokenpo.roundsPerGame = 5
3033
		
3034
		-- Data
3035
		mode.jokenpo.players = {}
3036
		mode.jokenpo.playing = false
3037
		
3038
		-- Timers
3039
		mode.jokenpo.timer = 9.5
3040
		mode.jokenpo.partialTimer = 0
3041
	end,
3042
	init = function()
3043
		mode.jokenpo.translations.pt = mode.jokenpo.translations.br
3044
	
3045
		-- Sets the main language according to the community
3046
		if mode.jokenpo.translations[tfm.get.room.community] then
3047
			mode.jokenpo.langue = tfm.get.room.community
3048
		end
3049
		
3050
		-- Sets the rounds per game
3051
		mode.jokenpo.roundsPerGame = mathmax(5,system.miscAttrib)
3052
		
3053
		-- Init
3054
		for _,f in next,{"AutoShaman","AutoNewGame","PhysicalConsumables","AfkDeath"} do
3055
			tfm.exec["disable"..f]()
3056
		end
3057
		tfm.exec.setAutoMapFlipMode(false)
3058
		tfm.exec.setRoomMaxPlayers(20)
3059
3060
		tfm.exec.newGame(tablerandom(mode.jokenpo.maps))
3061
	end,
3062
	-- New Player
3063
	eventNewPlayer = function(n)
3064
		tfm.exec.chatMessage("<CE>[•] " .. system.getTranslation("welcome"),n)
3065
	
3066
		for k,v in next,{32,stringbyte("BNM",1,3)} do
3067
			system.bindKeyboard(n,v,true,true)
3068
		end
3069
		
3070
		if mode.jokenpo.playing then
3071
			mode.jokenpo.round = mode.jokenpo.round + 1
3072
		else
3073
			tfm.exec.respawnPlayer(n)
3074
		end
3075
		
3076
		mode.jokenpo.buildSquares(mode.jokenpo.colors)
3077
		mode.jokenpo.uiinfo()
3078
	end,
3079
	-- New Game
3080
	eventNewGame = function()
3081
		if mode.jokenpo.playing then
3082
			for k,v in next,tfm.get.room.playerList do
3083
				if not tablefind(mode.jokenpo.players,k,"name") then
3084
					tfm.exec.killPlayer(k)
3085
				end
3086
			end
3087
		end
3088
	
3089
		mode.jokenpo.colors = {0xE3454D,0x4577E3,0x45E374}	
3090
		xml.attribFunc(tfm.get.room.xmlMapInfo.xml or "",{
3091
			[1] = {
3092
				attribute = "o",
3093
				func = function(color)
3094
					local c = stringsplit(color,"[^,]+",function(o)
3095
						return stringmatch(o,"#?(.+)")
3096
					end)
3097
					
3098
					for i = 1,#c do
3099
						mode.jokenpo.colors[i] = tonumber(c[i],16)
3100
					end
3101
				end
3102
			}
3103
		})
3104
		
3105
		mode.jokenpo.buildSquares(mode.jokenpo.colors)
3106
		mode.jokenpo.uiinfo()
3107
	end,
3108
	-- Keyboard
3109
	eventKeyboard = function(n,k,d,x,y)
3110
		if k == 32 and #mode.jokenpo.players < 2 then
3111
			for k,v in next,{{285,330,270},{515,330,425}} do
3112
				if mathpythag(v[1],v[2],x,y,30) then
3113
					if not tablefind(mode.jokenpo.players,n,"name") then
3114
						if not tablefind(mode.jokenpo.players,k,"id") then
3115
							mode.jokenpo.players[#mode.jokenpo.players + 1] = {
3116
								name = n,
3117
								x = v[3],
3118
								score = 0,
3119
								color = stringformat("<font color='#%s'>",stringformat("%x",mode.jokenpo.colors[k])),
3120
								id = k,
3121
								obj = 0,
3122
								remId = nil,
3123
							}
3124
							
3125
							tfm.exec.chatMessage("<CE>[•] " .. mode.jokenpo.players[#mode.jokenpo.players].color .. stringformat(system.getTranslation("guide"),"B","N","M"),n)
3126
							
3127
							mode.jokenpo.uiinfo()
3128
							tfm.exec.playEmote(n,mode.jokenpo.emote.sit)
3129
						end
3130
					end
3131
				end
3132
			end
3133
			
3134
			if #mode.jokenpo.players == 2 then
3135
				tablesort(mode.jokenpo.players,function(p1,p2) return p1.id < p2.id end)
3136
				mode.jokenpo.playing = true
3137
3138
				mode.jokenpo.round = mode.jokenpo.round + 1
3139
				mode.jokenpo.uiinfo()
3140
			end
3141
		else
3142
			if mode.jokenpo.playing then
3143
				local foundObject,objectIndex = tablefind({stringbyte("BNM",1,3)},k)
3144
				if foundObject then	
3145
					local found,i = tablefind(mode.jokenpo.players,n,"name")
3146
					if found then
3147
						i = mode.jokenpo.players[i]
3148
						if i.obj == 0 then
3149
							i.obj = objectIndex
3150
3151
							tfm.exec.chatMessage("<CE>[•] " .. i.color .. stringformat(system.getTranslation("selected"),system.getTranslation("items")[objectIndex]),n)
3152
						end
3153
					end
3154
				end
3155
			end
3156
		end
3157
	end,
3158
	-- Loop
3159
	eventLoop = function()
3160
		if mode.jokenpo.playing then
3161
			if mode.jokenpo.timer > 0 then
3162
				mode.jokenpo.timer = mode.jokenpo.timer - .5
3163
				ui.addTextArea(0,"<p align='center'><font size='35'><J>"..mathfloor(mode.jokenpo.timer),nil,380,85,40,40,1,1,0,true)
3164
				for i = 1,2 do
3165
					tfm.exec.movePlayer(mode.jokenpo.players[i].name,({285,515})[i],330)
3166
					tfm.exec.playEmote(mode.jokenpo.players[i].name,26)
3167
				end
3168
			else
3169
				mode.jokenpo.pNextRound()
3170
			end
3171
		else
3172
			if mode.jokenpo.partialTimer > 0 then
3173
				mode.jokenpo.partialTimer = mode.jokenpo.partialTimer - .5
3174
				ui.addTextArea(0,"<p align='center'><font size='35'><PT>"..mathfloor(mode.jokenpo.partialTimer),nil,380,85,40,40,1,1,0,true)
3175
				
3176
				if mode.jokenpo.partialTimer <= 0 then
3177
					mode.jokenpo.nextRound()
3178
				end
3179
			end
3180
		end
3181
	end,
3182
	-- Player Left
3183
	eventPlayerLeft = function(n)
3184
		if tablefind(mode.jokenpo.players,n,"name") then
3185
			mode.jokenpo.round = mode.jokenpo.roundsPerGame
3186
			mode.jokenpo.nextRound()
3187
		end
3188
	end,
3189
}
3190
3191
--[[ Click ]]--
3192
mode.click = {
3193
	-- Translations
3194
	translations = {
3195
		en = {
3196
			-- Init
3197
			welcome = "<BV>Welcome to <CH><B>#click</B><BV>!\n\t» Type <B>!p Playername</B> to open the profile of the player\n\t» Report any issue to <B>Bolodefchoco</B>",
3198
		
3199
			-- Info
3200
			newGame = "New game in %s seconds!",
3201
			clickfast = "Click several times in the circle before %s seconds!",
3202
			
3203
			-- Simple words
3204
			click = "CLICK!",
3205
			won = "won!",
3206
			
3207
			-- Profile
3208
			profile = "Total clicks <BL>: <V>%s\n<J>High Score <BL>: <V>%s\n\n<J>Victories <BL>: <V>%s",
3209
		},
3210
		br = {
3211
			welcome = "<BV>Bem-vindo ao <CH><B>#click</B><BV>!\n\t\n\t» Digite <B>!p Jogador</B> para abrir o perfil do jogador\n\t» Reporte qualquer problema para <B>Bolodefchoco</B>",
3212
			
3213
			newGame = "Novo jogo em %s segundos!",
3214
			clickfast = "Clique várias vezes no círculo antes de %s segundos!",
3215
			
3216
			click = "CLIQUE!",
3217
			won = "venceu!",
3218
			
3219
			profile = "Cliques totais <BL>: <V>%s\n<J>Maior pontuação <BL>: <V>%s\n\n<J>Vitórias <BL>: <V>%s",
3220
		},
3221
	},
3222
	langue = "en",
3223
	-- Data
3224
	info = {},
3225
	-- System
3226
	circle = {
3227
		id = 0,
3228
		status = false
3229
	},
3230
	spawnCircle = function(on)
3231
		if mode.click.circle.id > 0 then
3232
			tfm.exec.removeJoint(mode.click.circle)
3233
		end
3234
		
3235
		mode.click.circle = {id = 1,status = on}
3236
		
3237
		local color = on and 0x53D08B or 0x555D77
3238
		
3239
		tfm.exec.addJoint(1,0,0,{
3240
			type = 0,
3241
			alpha = .9,
3242
			color = color,
3243
			foreground = false,
3244
			line = 300,
3245
			point1 = "400,200",
3246
			point2 = "400,201"
3247
		})
3248
	end,
3249
	-- Timers
3250
	partialTimer = 1,
3251
	counter = 0,
3252
	-- Ranking
3253
	uileaderboard = function()
3254
		local data = {}
3255
		for k,v in next,mode.click.info do
3256
			if v.canPlay and v.roundClick > 0 then
3257
				data[#data + 1] = {k,v.roundClick}
3258
			end
3259
			
3260
			if v.highScore < v.roundClick then
3261
				v.highScore = v.roundClick
3262
			end
3263
			v.totalClick = v.totalClick + v.roundClick
3264
			v.roundClick = 0
3265
		end
3266
		
3267
		tablesort(data,function(p1,p2) return p1[2] > p2[2] end)
3268
		
3269
		local str = ""
3270
		for k,v in next,data do
3271
			if k < 51 then
3272
				if k == 1 then
3273
					mode.click.info[v[1]].victories = mode.click.info[v[1]].victories + 1
3274
					tfm.exec.chatMessage("<J>" .. v[1] .. " <G>" .. system.getTranslation("won"))
3275
					tfm.exec.setPlayerScore(v[1],1,true)
3276
				end
3277
				
3278
				str = str .. stringformat("<J>%s. <V>%s <BL>- <PT>%sP\n",k,v[1],v[2])
3279
			end
3280
		end
3281
		
3282
		ui.addTextArea(1,str,nil,5,30,250,330,1,1,.9,true)
3283
	end,
3284
	-- Init
3285
	reset = function()
3286
		-- Data
3287
		mode.click.info = {}
3288
	end,
3289
	init = function()
3290
		mode.click.translations.pt = mode.click.translations.br
3291
3292
		-- Sets the main language according to the community
3293
		if mode.click.translations[tfm.get.room.community] then
3294
			mode.click.langue = tfm.get.room.community
3295
		end
3296
		
3297
		-- Init
3298
		for _,f in next,{"AutoShaman","AutoScore","AutoNewGame","AfkDeath"} do
3299
			tfm.exec["disable"..f]()
3300
		end
3301
3302
		tfm.exec.newGame(5993911)
3303
	end,
3304
	-- New Player
3305
	eventNewPlayer = function(n)
3306
		system.bindMouse(n,true)
3307
		if not mode.click.info[n] then
3308
			mode.click.info[n] = {
3309
				canPlay = false,
3310
				totalClick = 0,
3311
				roundClick = 0,
3312
				highScore = 0,
3313
				victories = 0,
3314
			}
3315
		end
3316
		if not mode.click.circle.status then
3317
			tfm.exec.respawnPlayer(n)
3318
			mode.click.info[n].canPlay = true
3319
		end
3320
		tfm.exec.chatMessage(system.getTranslation("welcome"),n)
3321
	end,
3322
	-- New Game
3323
	eventNewGame = function()
3324
		mode.click.spawnCircle(false)
3325
		mode.click.partialTimer = 10.5
3326
	end,
3327
	-- Loop
3328
	eventLoop = function()
3329
		if mode.click.partialTimer > 0 then
3330
			mode.click.partialTimer = mode.click.partialTimer - .5
3331
			ui.setMapName(stringformat(system.getTranslation("newGame"),"<ROSE>"..mathfloor(mode.click.partialTimer).."<J>") .. "<")
3332
			if mode.click.partialTimer <= 0 then
3333
				mode.click.spawnCircle(true)
3334
				
3335
				mode.click.counter = mathmax(20,system.miscAttrib)
3336
				
3337
				for k,v in next,mode.click.info do
3338
					v.canPlay = true
3339
					tfm.exec.respawnPlayer(k)
3340
				end
3341
				
3342
				ui.removeTextArea(1,nil)
3343
				ui.setMapName(system.getTranslation("click") .. "<")
3344
			end
3345
		else
3346
			if mode.click.counter > 0 then
3347
				mode.click.counter = mode.click.counter - .5
3348
				ui.addTextArea(0,"<p align='center'><font size='28'>" .. stringformat(system.getTranslation("clickfast"),mathfloor(mode.click.counter)),nil,0,30,800,50,1,1,0,true)
3349
				if mode.click.counter <= 0 then
3350
					mode.click.spawnCircle(false)
3351
3352
					mode.click.partialTimer = 10.5
3353
3354
					ui.removeTextArea(0,nil)
3355
					mode.click.uileaderboard()
3356
				end
3357
			end
3358
		end
3359
	end,
3360
	-- Mouse
3361
	eventMouse = function(n,x,y)
3362
		if mode.click.circle.status then
3363
			if mode.click.info[n].canPlay then
3364
				if mathpythag(400,200,x,y,150) then
3365
					mode.click.info[n].roundClick = mode.click.info[n].roundClick + 1
3366
					tfm.exec.displayParticle(15,mathrandom(150,650),mathrandom(100,300),0,0,0,0,n)
3367
				end
3368
			end
3369
		end
3370
	end,
3371
	-- Commands
3372
	eventChatCommand = function(n,c)
3373
		local p = stringsplit(c,"[^%s]+",stringlower)
3374
		if p[1] == "p" then
3375
			p[2] = p[2] and stringnick(p[2]) or n
3376
			if mode.click.info[p[2]] then
3377
				ui.addTextArea(2,"<p align='center'><font size='18'><a:active><a href='event:close'>"..p[2].."</a><p align='left'><font size='13'>\n<J>" .. stringformat(system.getTranslation("profile"),mode.click.info[p[2]].totalClick,mode.click.info[p[2]].highScore,mode.click.info[p[2]].victories),n,620,295,175,100,1,1,1,true)
3378
			end
3379
		end
3380
	end,
3381
	-- Callbacks
3382
	eventTextAreaCallback = function(i,n,c)
3383
		if c == "close" then
3384
			ui.removeTextArea(2,n)
3385
		end
3386
	end,
3387
	-- Respawn
3388
	eventPlayerDied = function(n)
3389
		tfm.exec.respawnPlayer(n)
3390
	end,
3391
	-- Player Left
3392
	eventPlayerLeft = function(n)
3393
		mode.click.info[n].canPlay = false
3394
	end,
3395
}
3396
3397
--[[ Presents ]]--
3398
mode.presents = {
3399
	-- Translations
3400
	translations = {
3401
		en = {
3402
			-- Init
3403
			welcome = "<J>Welcome to <VP><B>#presents</B><J>! Choose a gap according to the gift represented and good luck! You will win if your three-gifts-sequence is correct!\nType !p PlayerName to open the profile of the specified player\n\n<CE>Developed by Bolodefchoco and projected by Ruamorangos",
3404
		
3405
			-- Info
3406
			choose = "Choose a gift before <PT>%s seconds!",
3407
			kill = "Those who are out of the correct gift will be dead!",
3408
			newGame = "New game in <PT>%s seconds!",
3409
			nowinner = "No one won!",
3410
			appear = "You will appear in the next game!",
3411
			
3412
			-- Simple words
3413
			rival = "Rivals",
3414
			won = "won!",
3415
			
3416
			-- Profile
3417
			profile = "Rounds <BL>: <V>%s\n<J>Gifts <BL>: <V>%s\n\n<J>Victories <BL>: <V>%s",
3418
		},
3419
		br = {
3420
			welcome = "<J>Bem-vindo ao <VP><B>#presents</B><J>! Escolha um buraco de acordo com o presente representado e boa sorte! Você ganhará se sua sequência nos três presentes estiver correta!\nDigite !p Jogador para abrir o perfil o jogador especificado\n\n<CE>Desenvolvido por Bolodefchoco, pedido por Ruamorangos",
3421
		
3422
			choose = "Escolha um presente antes de <PT>%s segundos!",
3423
			kill = "Aqueles que estão fora do presente correto serão mortos!",
3424
			newGame = "Novo jogo em <PT>%s segundos!",
3425
			nowinner = "Ninguém ganhou!",
3426
			appear = "Você irá aparecer no próximo jogo!",
3427
			
3428
			rival = "Rivais",
3429
			won = "venceu!",
3430
3431
			profile = "Partidas <BL>: <V>%s\n<J>Presents <BL>: <V>%s\n\n<J>Vitórias <BL>: <V>%s",
3432
		},
3433
	},
3434
	langue = "en",
3435
	-- Data
3436
	info = {},
3437
	-- System
3438
	isRunning = false,
3439
	gifts = {},
3440
	-- Timers
3441
	chooseTimer = 15,
3442
	blockTimer = 0,
3443
	newMapTimer = 0,
3444
	currentGift = 1,
3445
	-- Map
3446
	generateMap = function()
3447
		mode.presents.isRunning = true
3448
		mode.presents.gifts = {
3449
			[1] = tablerandom({2104,2102,2100,2101,2103,2100,2104,2102,2103,2101,2104,2102,2100,2101,2103,2100,2104,2102,2103,2101,2104,2102,2100,2101,2103,2100,2104,2102,2103,2101}),
3450
			[2] = tablerandom({2102,2100,2101,2103,2100,2104,2102,2103,2101,2104,2102,2100,2101,2103,2100,2104,2102,2103,2101,2104,2102,2100,2101,2103,2100,2104,2102,2103,2101,2104}),
3451
			[3] = tablerandom({2100,2101,2103,2100,2104,2102,2103,2101,2104,2102,2100,2101,2103,2100,2104,2102,2103,2101,2104,2102,2100,2101,2103,2100,2104,2102,2103,2101,2104,2102})
3452
		}
3453
		
3454
		tfm.exec.newGame('<C><P DS="m;250,120,400,120,550,120" D="x_transformice/x_inventaire/'..mode.presents.gifts[1]..'.jpg,230,60;x_transformice/x_inventaire/'..mode.presents.gifts[2]..'.jpg,380,60;x_transformice/x_inventaire/'..mode.presents.gifts[3]..'.jpg,530,60;x_transformice/x_inventaire/2100.jpg,140,320;x_transformice/x_inventaire/2101.jpg,260,320;x_transformice/x_inventaire/2102.jpg,380,320;x_transformice/x_inventaire/2103.jpg,500,320;x_transformice/x_inventaire/2104.jpg,620,320" /><Z><S><S P="1,0.0001,20,0.2,90,1,0,0" H="700" L="15" X="400" c="3" Y="161" T="4" /><S X="100" P="0,0,20,0.2,0,0,0,0" L="40" H="135" c="3" Y="335" T="4" /><S H="135" P="0,0,20,0.2,0,0,0,0" L="40" X="220" c="3" Y="335" T="4" /><S X="340" P="0,0,20,0.2,0,0,0,0" L="40" H="135" c="3" Y="335" T="4" /><S H="135" P="0,0,20,0.2,0,0,0,0" L="40" X="460" c="3" Y="335" T="4" /><S X="580" P="0,0,20,0.2,0,0,0,0" L="40" H="135" c="3" Y="335" T="4" /><S H="40" P="0,0,0.3,0.2,0,0,0,0" L="40" X="100" c="3" Y="160" T="0" /><S X="700" P="0,0,0.3,0.2,0,0,0,0" L="40" H="40" c="3" Y="160" T="0" /><S X="550" P="0,0,0.3,0.2,0,0,0,0" L="40" H="40" c="3" Y="160" T="0" /><S X="400" P="0,0,0.3,0.2,0,0,0,0" L="40" H="40" c="3" Y="160" T="0" /><S X="250" P="0,0,0.3,0.2,0,0,0,0" L="40" H="40" c="3" Y="160" T="0" /><S H="20" P="0,0,0.3,0.2,0,0,0,0" L="800" X="400" Y="10" T="0" /><S H="135" P="0,0,20,0.2,0,0,0,0" L="40" X="700" c="3" Y="335" T="4" /><S X="400" P="0,0,0.3,0.2,0,0,0,0" L="800" H="100" c="3" Y="415" T="0" /><S P="0,0,0.3,0.2,0,0,0,0" H="10" L="50" o="324650" X="745" c="3" Y="138" T="13" /><S X="55" P="0,0,0.3,0.2,0,0,0,0" L="50" o="324650" H="10" c="3" Y="138" T="13" /><S P="0,0,0.3,0.2,0,0,0,0" H="140" L="100" o="324650" X="55" c="3" Y="72" T="12" /><S X="745" P="0,0,0.3,0.2,0,0,0,0" L="100" o="324650" H="140" c="3" Y="72" T="12" /><S P="0,0,0,0,0,0,0,0" H="102" L="581" o="6a7495" X="401" c="4" v="3001" Y="78" T="12" /></S><D /><O /><L><JR M2="10" M1="0" /></L></Z></C>')
3455
	end,
3456
	-- Kill wrong gaps
3457
	killOutOfRange = function()
3458
		local gift = mode.presents.gifts[mode.presents.currentGift] - 2099
3459
		for k,v in next,tfm.get.room.playerList do
3460
			if not v.isDead then
3461
				if v.x >= (gift * 120) and v.x <= (gift * 120 + 80) and v.y > 267 then
3462
					mode.presents.info[k].gifts = mode.presents.info[k].gifts + 1
3463
					tfm.exec.setPlayerScore(k,1,true)
3464
				else
3465
					tfm.exec.killPlayer(k)
3466
				end
3467
			end
3468
		end
3469
	end,
3470
	-- Victory
3471
	victory = function(noone)
3472
		if noone then
3473
			tfm.exec.chatMessage("<J>" .. system.getTranslation("nowinner"))
3474
			mode.presents.chooseTimer = 0
3475
			mode.presents.blockTimer = 0
3476
		else
3477
			tfm.exec.chatMessage("<S>" .. tableconcat(system.players(true),"<J>, <S>",function(k,v)
3478
				mode.presents.info[v].victories = mode.presents.info[v].victories + 1
3479
				return v
3480
			end) .. " <J>" .. system.getTranslation("won"))
3481
		end
3482
		mode.presents.newMapTimer = 10.5
3483
	end,
3484
	-- Init
3485
	reset = function()
3486
		-- Data
3487
		mode.presents.info = {}
3488
	end,
3489
	init = function()
3490
		mode.presents.translations.pt = mode.presents.translations.br
3491
3492
		-- Sets the main language according to the community
3493
		if mode.presents.translations[tfm.get.room.community] then
3494
			mode.presents.langue = tfm.get.room.community
3495
		end
3496
		
3497
		-- Init
3498
		for _,f in next,{"AutoShaman","AutoNewGame","AutoScore","AfkDeath","MortCommand","DebugCommand","PhysicalConsumables"} do
3499
			tfm.exec["disable"..f]()
3500
		end	
3501
		tfm.exec.setRoomMaxPlayers(30)
3502
3503
		mode.presents.generateMap()
3504
		
3505
		-- Auto Admin
3506
		system.roomAdmins.Ruamorangos = true
3507
	end,
3508
	-- New Player
3509
	eventNewPlayer = function(n)
3510
		if not mode.presents.info[n] then
3511
			mode.presents.info[n] = {
3512
				rounds = 0,
3513
				gifts = 0,
3514
				victories = 0,
3515
			}
3516
		end
3517
		
3518
		tfm.exec.chatMessage(system.getTranslation("welcome"),n)
3519
		
3520
		if mode.presents.isRunning then
3521
			local m = "<PT>" .. system.getTranslation("appear")
3522
			ui.addTextArea(0,"<p align='center'><font size='20'><VP>" .. m,n,216,65,365,35,1,1,1,true)
3523
			tfm.exec.chatMessage(m,n)
3524
		else
3525
			tfm.exec.respawnPlayer(n)
3526
		end
3527
	end,
3528
	-- New Game
3529
	eventNewGame = function()
3530
		if mode.presents.isRunning then
3531
			for i,x in next,{250,400,550} do
3532
				tfm.exec.addPhysicObject(i,x,75,{
3533
					type = 12,
3534
					height = 90,
3535
					width = 90,
3536
					miceCollision = false,
3537
					groundCollision = false,
3538
					color = 0x6A7495
3539
				})
3540
			end
3541
			for i = 0,1 do
3542
				ui.removeTextArea(i)
3543
			end
3544
			mode.presents.chooseTimer = 15
3545
			mode.presents.blockTimer = 0
3546
			mode.presents.newMapTimer = 0
3547
			mode.presents.currentGift = 1
3548
			for k,v in next,mode.presents.info do
3549
				v.rounds = v.rounds + 1
3550
			end
3551
		end
3552
	end,
3553
	-- Loop
3554
	eventLoop = function()
3555
		local mapName = "<N>" .. system.getTranslation("rival") .." : <V>" .. mathisNegative(system.players()-1,0)
3556
		if _G.currentTime > 4 and mode.presents.isRunning then
3557
			if mode.presents.chooseTimer > 0 then
3558
				mode.presents.chooseTimer = mode.presents.chooseTimer - .5
3559
				
3560
				if mode.presents.chooseTimer <= 0 then
3561
					mode.presents.blockTimer = 5
3562
					tfm.exec.addPhysicObject(4,400,270,{
3563
						type = 4,
3564
						height = 10,
3565
						width = 640,
3566
						miceCollision = true,
3567
						groundCollision = false
3568
					})
3569
					tfm.exec.removePhysicObject(mode.presents.currentGift)
3570
				else
3571
					mapName = mapName .. "   <G>|   <J>" .. stringformat(system.getTranslation("choose"),mathfloor(mode.presents.chooseTimer).."<J>")
3572
				end
3573
				
3574
				if system.players() == 0 then
3575
					mode.presents.victory(true)
3576
				end
3577
			end
3578
			
3579
			if mode.presents.blockTimer > 0 then
3580
				mode.presents.blockTimer = mode.presents.blockTimer - .5
3581
				
3582
				if mode.presents.blockTimer == 2 then
3583
					mode.presents.killOutOfRange()
3584
				end
3585
				
3586
				if mode.presents.blockTimer <= 0 then
3587
					mode.presents.currentGift = mode.presents.currentGift + 1
3588
					if mode.presents.currentGift > 3 then
3589
						mode.presents.victory()
3590
					else
3591
						tfm.exec.removePhysicObject(4)
3592
						mode.presents.chooseTimer = 15
3593
					end
3594
				else
3595
					mapName = mapName .. "   <G>|   <R>" .. system.getTranslation("kill")
3596
				end
3597
			end
3598
			
3599
			if mode.presents.newMapTimer > 0 then
3600
				mode.presents.newMapTimer = mode.presents.newMapTimer - .5
3601
				
3602
				mapName = "<PS>" .. stringformat(system.getTranslation("newGame"),mathfloor(mode.presents.newMapTimer) .. "<PS>")
3603
				if mode.presents.newMapTimer <= 0 then
3604
					mode.presents.generateMap()
3605
				end
3606
			end
3607
		end
3608
		ui.setMapName(mapName .. "<")
3609
	end,
3610
	-- Commands
3611
	eventChatCommand = function(n,c)
3612
		local p = stringsplit(c,"[^%s]+",stringlower)
3613
		if p[1] == "p" then
3614
			p[2] = p[2] and stringnick(p[2]) or n
3615
			if mode.presents.info[p[2]] then
3616
				ui.addTextArea(1,"<p align='center'><font size='18'><a:active><a href='event:close'>"..p[2].."</a><p align='left'><font size='13'>\n<J>" .. stringformat(system.getTranslation("profile"),mode.presents.info[p[2]].rounds,mode.presents.info[p[2]].gifts,mode.presents.info[p[2]].victories),n,5,30,790,100,1,1,.8,true)
3617
			end
3618
		end
3619
	end,
3620
	-- Callbacks
3621
	eventTextAreaCallback = function(i,n,c)
3622
		if c == "close" then
3623
			ui.removeTextArea(1,n)
3624
		end
3625
	end,
3626
}
3627
3628
--[[ Chat ]]--
3629
mode.chat = {
3630
	-- Translations
3631
	translations = {
3632
		en = {
3633
			-- Init
3634
			welcome = "<J>Welcome to #chat. Enjoy while you are muted ?! Report any issue to Bolodefchoco.",
3635
		
3636
			-- Info
3637
			loadmap = "loaded by",
3638
			enabled = "enabled",
3639
			disabled = "disabled",
3640
			
3641
			-- Cats
3642
			shaman = "shaman",
3643
			newGame = "Auto New Game",
3644
			
3645
			-- Misc
3646
			title = "%s has just unlocked the «%s» title.\n<ROSE>Type /title to choose a title",
3647
		},
3648
		br = {
3649
			welcome = "<J>Bem-vindo ao #chat. Aproveite enquanto você está mutado ?! Reporte qualquer problema para Bolodefchoco.",
3650
		
3651
			loadmap = "carregado por",
3652
			enabled = "ativado",
3653
			disabled = "desativado",
3654
			
3655
			shaman = "shaman",
3656
			newGame = "Novo Jogo Automático",
3657
			
3658
			title = "%s Desbloqueou o título «%s»\n<ROSE>Digite /title para escolher um título.",
3659
		},
3660
		ar = {
3661
			welcome = "<J>مرحبًا بك في #chat. استمتع بينما أنت مكتوم ?! بلغ عن أي مشكلة إلى Bolodefchoco.",
3662
		
3663
			loadmap = "شُغل بواسطة",
3664
			enabled = "فُعل",
3665
			disabled = "أُلغي",
3666
			
3667
			shaman = "الشامان",
3668
			newGame = "جولة جديدة تلقائية",
3669
			
3670
			title = "%s has just unlocked the «%s» title.\n<ROSE>Type /title to choose a title",
3671
		},
3672
	},
3673
	langue = "en",
3674
	-- Data
3675
	info = {},
3676
	data = {},
3677
	displayData = {},
3678
	messageId = 0,
3679
	-- New Game Settings
3680
	hasShaman = false,
3681
	autoNeWGame = false,
3682
	-- Chat settings
3683
	chatTitle = "Chat",
3684
	-- Chat
3685
	chat = function(n,message,update)
3686
		if not update then
3687
			ui.addPopup(0,2,"",n,107,325,565,true)
3688
		end
3689
		ui.addTextArea(0,"",n,108,73,564,253,0x212E35,0x212E35,1,true)
3690
		ui.addTextArea(1,message,n,110,75,560,250,0x324650,0x324650,1,true)
3691
		ui.addTextArea(2,"<p align='center'><B><V>" .. mode.chat.chatTitle,n,108,53,564,20,0x212E35,0x212E35,1,true)
3692
		ui.addTextArea(3,"<p align='right'><B><R><a href='event:close'>X",n,110,54,560,20,1,1,0,true)
3693
	end,
3694
	getTextLength = function(line)
3695
		return stringlen(stringgsub(line,"<.*>",""))
3696
	end,
3697
	loadData = function()
3698
		local message = "<font size='7'>\n</font>"
3699
		for i = 18,1,-1 do
3700
			if #message < 1900 then
3701
				local line = mode.chat.displayData[i] or ""
3702
				message = message .. line
3703
			end
3704
		end
3705
		return message
3706
	end,
3707
	updateToRead = function(n)
3708
		ui.addTextArea(4,"<p align='center'><V><a href='event:open'><B>" .. stringsub(stringlower(mode.chat.chatTitle),1,8) .. "</B> <J>" .. mode.chat.info[n].toRead,n,712,378,80,nil,0x324650,0x212E35,1,true)
3709
	end,
3710
	displayChat = function(n,update)
3711
		local loadedM = mode.chat.loadData()
3712
		if not update then
3713
			mode.chat.chat(n,loadedM)
3714
		else
3715
			for k,v in next,mode.chat.info do
3716
				if v.open then
3717
					mode.chat.chat(k,loadedM,k ~= n)
3718
				else
3719
					v.toRead = v.toRead + 1
3720
					mode.chat.updateToRead(k)
3721
				end
3722
			end
3723
		end
3724
	end,
3725
	newMessage = function(message,n)
3726
		mode.chat.messageId = mode.chat.messageId + 1
3727
		tableinsert(mode.chat.data,{mode.chat.messageId,n,stringgsub(stringgsub(message,"@%((.*)%)",function(text) return text end),"{.-:(.-)}",function(text) return text end)})
3728
	
3729
		if mode.chat.getTextLength(message) > 50 then
3730
			message = stringsub(message,1,47) .. "..."
3731
		end
3732
		message = stringgsub(message,"<","&lt;") -- < to <
3733
		message = stringgsub(message,"https?","") -- https to ""
3734
		message = stringgsub(message,"://","") -- :// to ""
3735
		message = stringgsub(message,"@%((.*)%)",function(text) -- @(link:text)
3736
			return stringformat("<a href='event:display.%s'>%s</a>",mode.chat.messageId,text)
3737
		end)
3738
		
3739
		if #message > 0 then
3740
			if stringsub(message,1,1) == "/" then
3741
				mode.chat.eventChatCommand(n,stringsub(message,2))
3742
			else
3743
				message = stringgsub(message,"{(.-):(.-)}",function(color,text) -- {colorTag:Text}
3744
					color = stringupper(color)
3745
					if tablefind({"BV","R","BL","J","N","N2","PT","CE","CEP","CS","S","PS","G","V","VP","VI","ROSE","CH","T"},color) then
3746
						return stringformat("<%s>%s</%s>",color,text,color)
3747
					else
3748
						return text
3749
					end
3750
				end)
3751
				tableinsert(mode.chat.displayData,1,stringformat("<V>[%s] <N>%s\n",n,message))
3752
			end
3753
		end
3754
	end,
3755
	-- Init
3756
	init = function()
3757
		mode.chat.translations.pt = mode.chat.translations.br
3758
		mode.chat.langue = mode.chat.translations[tfm.get.room.community] and tfm.get.room.community or "en"
3759
		tfm.exec.setRoomMaxPlayers(30)
3760
		system.disableChatCommandDisplay("title",true)
3761
		mode.chat.displayChat()
3762
	end,
3763
	-- New Player
3764
	eventNewPlayer = function(n)
3765
		mode.chat.info[n] = {
3766
			open = true,
3767
			toRead = 0,
3768
		}
3769
		mode.chat.displayChat(n)
3770
		tfm.exec.chatMessage(system.getTranslation("welcome"),n)
3771
	end,
3772
	-- Answer bar
3773
	eventPopupAnswer = function(i,n,a)
3774
		if #stringgsub(a," ","") > 0 then
3775
			mode.chat.newMessage(a,n)
3776
			mode.chat.displayChat(n,true)
3777
		else
3778
			mode.chat.displayChat(n)
3779
		end
3780
	end,
3781
	-- Callbacks
3782
	eventTextAreaCallback = function(i,n,c)
3783
		local p = stringsplit(c,"[^%.]+")
3784
		if p[1] == "close" then
3785
			ui.addPopup(0,2,"",n,1e7,1e7)
3786
			for i = 0,3 do
3787
				ui.removeTextArea(i,n)
3788
			end
3789
			mode.chat.info[n].open = false
3790
			mode.chat.updateToRead(n)
3791
		elseif p[1] == "open" then
3792
			mode.chat.info[n].open = true
3793
			mode.chat.info[n].toRead = 0
3794
			mode.chat.displayChat(n)
3795
			ui.removeTextArea(4,n)
3796
		elseif p[1] == "display" then
3797
			local msg = mode.chat.data[tonumber(p[2])]		
3798
			tfm.exec.chatMessage(stringformat("<N>> <V>[%s] <N>%s",msg[2],msg[3]),n)
3799
		end
3800
	end,
3801
	-- Commands
3802
	eventChatCommand = function(n,c)
3803
		local p = stringsplit(c,"[^%s]+",stringlower)
3804
		if p[1] == "title" and p[2] and system.roomAdmins[n] then
3805
			mode.chat.chatTitle = stringsub(tableconcat(p," ",nil,2),1,40)
3806
			mode.chat.displayChat()
3807
		elseif p[1] == "np" and p[2] then
3808
			tfm.exec.chatMessage(stringformat("<S>%s %s %s",stringsub(p[2],1,1) == "@" and p[2] or "@" .. p[2],system.getTranslation("loadmap"),n))
3809
			tfm.exec.newGame(p[2])
3810
		elseif p[1] == "sha" then
3811
			mode.chat.hasShaman = not mode.chat.hasShaman
3812
			
3813
			tfm.exec.chatMessage("<S>• " .. system.getTranslation("shaman") .. " " .. system.getTranslation((mode.chat.hasShaman and "disabled" or "enabled")),n)
3814
			tfm.exec.disableAutoShaman(mode.chat.hasShaman)
3815
		elseif p[1] == "new" then
3816
			mode.chat.autoNeWGame = not mode.chat.autoNeWGame
3817
		
3818
			tfm.exec.chatMessage("<S>• " .. system.getTranslation("newGame") .. " " .. system.getTranslation((mode.chat.autoNeWGame and "disabled" or "enabled")),n)
3819
			tfm.exec.disableAutoNewGame(mode.chat.autoNeWGame)
3820
			tfm.exec.disableAutoTimeLeft(mode.chat.autoNeWGame)
3821
		elseif stringsub(c,1,6) == "unlock" then
3822
			tfm.exec.chatMessage("<J>" .. stringformat(system.getTranslation("title"),n,stringsub(c,8)),n)
3823
		end
3824
	end,	
3825
}
3826
3827
--[[ Cannonup ]]--
3828
mode.cannonup = {
3829
	-- Translations
3830
	translations = {
3831
		en = {
3832
			-- Init
3833
			welcome = "Welcome to #cannonup. Your aim is to be the survivor! <VP>Take care, watermelons are dangerous!\n\t<J>Report any issue to Bolodefchoco.",
3834
3835
			-- Info
3836
			nowinner = "No one won!",
3837
			
3838
			-- Simple words
3839
			won = "won!",
3840
			
3841
			-- Profile
3842
			profile = "Rounds : <V>%d</V>\nCheeses : <V>%d</V>\n\nDeaths : <V>%d</V>",
3843
		},
3844
		br = {
3845
			welcome = "Bem-vindo ao #cannonup. Seu objetivo é ser o sobrevivente! <VP>Tome cuidado, melancias são perigosas!\n\t<J>Reporte qualquer problema para Bolodefchoco.",
3846
		
3847
			nowinner = "Ninguém ganhou!",
3848
		
3849
			won = "venceu!",
3850
			
3851
			profile = "Rodadas : <V>%d</V>\nQueijos : <V>%d</V>\n\nMortes : <V>%d</V>",
3852
		},
3853
	},
3854
	langue = "en",
3855
	-- Data
3856
	info = {},
3857
	-- Maps
3858
	maps = {3746497,6001536,3666224,4591929,"#10","#10","#10","#10","#10","#10","#10","#10","#10"},
3859
	-- Settings
3860
	isRunning = false,
3861
	totalPlayers = 0,
3862
	-- New Map Settings
3863
	cannon = {
3864
		x = 0,
3865
		y = 0,
3866
		time = 3,
3867
		amount = 1,
3868
		speed = 20,
3869
	},
3870
	canMessage = false,
3871
	currentXml = -1,
3872
	toDespawn = {},
3873
	alivePlayers = {},
3874
	-- Cannon ID
3875
	getCannon = function()
3876
		local currentMonth = tonumber(os.date("%m"))
3877
		
3878
		if currentMonth == 12 then
3879
			return 1703 -- Christmas [Ornament]
3880
		elseif currentMonth == 10 then
3881
			return tablerandom({17,1701,1702}) -- Halloween [Normal, Glass, Lollipop]
3882
		elseif currentMonth == 5 and tonumber(os.date("%d")) < 11 then
3883
			return 1704 -- Transformice's Birthday [Shaman]
3884
		elseif currentMonth == 7 then
3885
			return tablerandom({17,1705,1706}) -- Vacations [Normal, Apple, Watermellon]
3886
		else
3887
			return tablerandom({17,17,17,1706}) -- Standard
3888
		end
3889
	end,
3890
	-- Spawn Cannon
3891
	newCannon = function()
3892
		local alive = system.players(true)
3893
		if #alive > 0 then
3894
			local player
3895
			repeat
3896
				player = tfm.get.room.playerList[tablerandom(alive)]
3897
			until not player.isDead
3898
			
3899
			local coordinates = {
3900
				{player.x,mathrandom() * 700},
3901
				{player.y,mathrandom() * 300},
3902
				{false,false}
3903
			}
3904
			
3905
			if mode.cannonup.cannon.x ~= 0 then
3906
				coordinates[1][2] = mode.cannonup.cannon.x
3907
				coordinates[3][1] = true
3908
			end
3909
			if mode.cannonup.cannon.y ~= 0 then
3910
				coordinates[2][2] = mode.cannonup.cannon.y
3911
				coordinates[3][2] = true
3912
			end
3913
			
3914
			if not coordinates[3][2] and coordinates[2][2] > coordinates[2][1] then
3915
				coordinates[2][2] = coordinates[2][1] - mathrandom(100) - 35
3916
			end
3917
			if not coordinates[3][1] and mathabs(coordinates[1][2] - coordinates[1][1]) > 350 then
3918
				coordinates[1][2] = coordinates[1][1] + mathrandom(-100,100)
3919
			end
3920
			
3921
			local ang = mathdeg(mathatan2(coordinates[2][2] - coordinates[2][1],coordinates[1][2] - coordinates[1][1]))
3922
			tfm.exec.addShamanObject(0,coordinates[1][2] - (coordinates[3][1] and 0 or 10),coordinates[2][2] - (coordinates[3][2] and 0 or 10),ang + 90)
3923
			
3924
			--system.newTimer(function()
3925
				mode.cannonup.toDespawn[#mode.cannonup.toDespawn + 1] = {tfm.exec.addShamanObject(mode.cannonup.getCannon(),coordinates[1][2],coordinates[2][2],ang - 90,mode.cannonup.cannon.speed),os.time() + 5000}
3926
			--end,mathisNegative((mode.cannonup.cannon.speed - 1) * 500,0),false)
3927
		end
3928
	end,
3929
	-- Profile
3930
	uiprofile = function(p,n)
3931
		ui.addTextArea(1,"\n\n<font size='13'>\n" .. stringformat(system.getTranslation("profile"),mode.cannonup.info[p].round,mode.cannonup.info[p].victory,mode.cannonup.info[p].death),n,300,100,200,150,0x0B282E,0x1B282E,1,true)
3932
		ui.addTextArea(2,"<p align='center'><font size='20'><VP><B><a href='event:close'>"..p.."</a>",n,305,105,190,30,0x244452,0x1B282E,.4,true)
3933
	end,
3934
	-- Update data
3935
	updatePlayers = function()
3936
		local alive,total = system.players()
3937
		mode.cannonup.alivePlayers = system.players(true)
3938
		mode.cannonup.totalPlayers = total
3939
	end,
3940
	-- Init
3941
	reset = function()
3942
		-- Data
3943
		mode.cannonup.info = {}
3944
	end,
3945
	init = function()
3946
		mode.cannonup.translations.pt = mode.cannonup.translations.br
3947
		
3948
		-- Sets the main language according to the community
3949
		if mode.cannonup.translations[tfm.get.room.community] then
3950
			mode.cannonup.langue = tfm.get.room.community
3951
		end
3952
		
3953
		-- Init
3954
		for _,f in next,{"AutoShaman","AutoScore","AutoNewGame","AutoTimeLeft","PhysicalConsumables"} do
3955
			tfm.exec["disable"..f]()
3956
		end
3957
		tfm.exec.setRoomMaxPlayers(25)
3958
		tfm.exec.newGame('<C><P /><Z><S><S L="800" o="324650" H="100" X="400" Y="400" T="12" P="0,0,0.3,0.2,0,0,0,0" /></S><D /><O /></Z></C>')
3959
	
3960
		-- Auto Admin
3961
		system.roomAdmins.Byontr = true
3962
	end,
3963
	-- New Player
3964
	eventNewPlayer = function(n)
3965
		if not mode.cannonup.info[n] then
3966
			mode.cannonup.info[n] = {
3967
				round = 0,
3968
				victory = 0,
3969
				death = 0
3970
			}
3971
		end
3972
		
3973
		tfm.exec.chatMessage("<J>" .. system.getTranslation("welcome"),n)
3974
	end,
3975
	-- New Game
3976
	eventNewGame = function()
3977
		ui.setMapName("#CannonUp")
3978
		
3979
		mode.cannonup.cannon = {
3980
			x = 0,
3981
			y = 0,
3982
			time = 3,
3983
			amount = ((mode.cannonup.totalPlayers - (mode.cannonup.totalPlayers % 10)) / 10) + mathsetLim(system.miscAttrib+1,1,5), -- mathmin(5,mathmax(1,system.miscAttrib+1))
3984
			speed = 20,
3985
		}
3986
3987
		mode.cannonup.toDespawn = {}
3988
		
3989
		if mode.cannonup.currentXml == -1 then
3990
			mode.cannonup.currentXml = 0
3991
		elseif mode.cannonup.currentXml == -2 then
3992
			mode.cannonup.currentXml = -1
3993
		end
3994
		
3995
		ui.removeTextArea(0,nil)
3996
		if mode.cannonup.isRunning then
3997
			if mode.cannonup.currentXml == 0 then
3998
				tfm.exec.setGameTime(5)
3999
				
4000
				mode.cannonup.currentXml = xml.addAttrib(tfm.get.room.xmlMapInfo.xml or "",{
4001
					[1] = {
4002
						tag = "BH",
4003
						value = "",
4004
					}
4005
				},false)
4006
				ui.addTextArea(0,"",nil,-1500,-1500,3e3,3e3,0x6A7495,0x6A7495,1,true)
4007
				
4008
				mode.cannonup.canMessage = false
4009
			else
4010
				tfm.exec.setGameTime(125)
4011
				mode.cannonup.canMessage = true
4012
				
4013
				if mode.cannonup.totalPlayers > 3 then
4014
					for k,v in next,mode.cannonup.info do
4015
						v.round = v.round + 1
4016
					end
4017
				end
4018
				
4019
				xml.attribFunc(mode.cannonup.currentXml or "",{
4020
					[1] = {
4021
						attribute = "cn",
4022
						func = function(value)
4023
							local coord,axY = xml.getCoordinates(value)
4024
							if type(coord) == "table" then
4025
								mode.cannonup.cannon.x = coord[1].x
4026
								mode.cannonup.cannon.y = coord[1].y
4027
							else
4028
								if axY == 0 then
4029
									mode.cannonup.cannon.x = coord
4030
								else
4031
									mode.cannonup.cannon.y = coord
4032
								end
4033
							end
4034
						end
4035
					},
4036
					[2] = {
4037
						attribute = "cheese",
4038
						func = function()
4039
							tableforeach(tfm.get.room.playerList,tfm.exec.giveCheese)
4040
						end,
4041
					},
4042
					[3] = {
4043
						attribute = "meep",
4044
						func = function()
4045
							tableforeach(tfm.get.room.playerList,tfm.exec.giveMeep)
4046
						end,
4047
					},
4048
				})
4049
			
4050
				mode.cannonup.currentXml = 0
4051
				mode.cannonup.canMessage = true
4052
			end
4053
		else
4054
			tfm.exec.setGameTime(1e7)
4055
			mode.cannonup.currentXml = -1
4056
			mode.cannonup.canMessage = false
4057
		end
4058
	end,
4059
	-- Loop
4060
	eventLoop = function()
4061
		mode.cannonup.updatePlayers()
4062
4063
		if mode.cannonup.isRunning then
4064
			if mode.cannonup.totalPlayers < 2 then
4065
				mode.cannonup.isRunning = false
4066
				mode.cannonup.canMessage = false
4067
				mode.cannonup.currentXml = -2
4068
			else
4069
				if mode.cannonup.currentXml == -1 then
4070
					tfm.exec.newGame(tablerandom(mode.cannonup.maps))
4071
				elseif mode.cannonup.currentXml ~= 0 then
4072
					tfm.exec.newGame(mode.cannonup.currentXml)
4073
				else		
4074
					if _G.leftTime < 4 or #mode.cannonup.alivePlayers < 2 then
4075
						if mode.cannonup.canMessage and mode.cannonup.totalPlayers > 1  then
4076
							mode.cannonup.canMessage = false
4077
							if #mode.cannonup.alivePlayers > 0 then
4078
								for k,v in next,mode.cannonup.alivePlayers do
4079
									tfm.exec.giveCheese(v)
4080
									tfm.exec.playerVictory(v)
4081
									if mode.cannonup.totalPlayers > 3 then
4082
										mode.cannonup.info[v].victory = mode.cannonup.info[v].victory + 1
4083
									end
4084
									tfm.exec.setPlayerScore(v,5,true)
4085
								end
4086
								
4087
								tfm.exec.chatMessage("<J>" .. tableconcat(mode.cannonup.alivePlayers,"<G>, <J>") .. " <J>" .. system.getTranslation("won"))
4088
							else
4089
								tfm.exec.chatMessage("<J>" .. system.getTranslation("nowinner"))
4090
							end
4091
						end
4092
						tfm.exec.newGame(tablerandom(mode.cannonup.maps))
4093
					else
4094
						if _G.currentTime > 5 and mode.cannonup.currentXml == 0 then
4095
							if _G.currentTime % mode.cannonup.cannon.time == 0 then
4096
								for i = 1,mode.cannonup.cannon.amount do
4097
									mode.cannonup.newCannon()
4098
								end
4099
							end
4100
							
4101
							if #mode.cannonup.toDespawn > 0 then
4102
								for i = 1,#mode.cannonup.toDespawn do
4103
									if os.time() > mode.cannonup.toDespawn[i][2] then
4104
										tfm.exec.removeObject(mode.cannonup.toDespawn[i][1])
4105
									end
4106
								end
4107
							end
4108
							
4109
							if _G.currentTime % 20 == 0 then
4110
								mode.cannonup.cannon.amount = ((mode.cannonup.totalPlayers - (mode.cannonup.totalPlayers % 10)) / 10) + mathsetLim(system.miscAttrib+1,1,5) --mathmin(5,mathmax(1,system.miscAttrib+1))
4111
								mode.cannonup.cannon.speed = mode.cannonup.cannon.speed + 20
4112
								mode.cannonup.cannon.time = mathmax(.5,mode.cannonup.cannon.time-.5)
4113
							end
4114
						end
4115
					end
4116
				end
4117
			end
4118
		else
4119
			if mode.cannonup.currentXml == -2 then
4120
				tfm.exec.newGame('<C><P /><Z><S><S L="800" o="324650" H="100" X="400" Y="400" T="12" P="0,0,0.3,0.2,0,0,0,0" /></S><D /><O /></Z></C>')
4121
			end
4122
		
4123
			if mode.cannonup.totalPlayers > 1 then
4124
				mode.cannonup.isRunning = true
4125
			end
4126
		end
4127
	end,
4128
	-- Commands
4129
	eventChatCommand = function(n,c)
4130
		local p = stringsplit(c,"[^%s]+",stringlower)
4131
		if p[1] == "p" or p[1] == "profile" then
4132
			if p[2] then
4133
				p[2] = stringnick(p[2])
4134
				if tfm.get.room.playerList[p[2]] then
4135
					mode.cannonup.uiprofile(p[2],n)
4136
				end
4137
			else
4138
				mode.cannonup.uiprofile(n,n)
4139
			end
4140
		end
4141
	end,
4142
	-- Callbacks
4143
	eventTextAreaCallback = function(i,n,c)
4144
		if c == "close" then
4145
			for i = 1,2 do
4146
				ui.removeTextArea(i,n)
4147
			end
4148
		end
4149
	end,
4150
	-- Player Left
4151
	eventPlayerLeft = function()
4152
		mode.cannonup.updatePlayers()
4153
	end,
4154
	-- Player Died
4155
	eventPlayerDied = function(n)
4156
		mode.cannonup.info[n].death = mode.cannonup.info[n].death + 1
4157
	end,
4158
}
4159
4160
--[[ Xmas ]]--
4161
mode.xmas = {
4162
	-- Translations
4163
	translations = {
4164
		en = {"Merry Christmas & Happy New Year!","Christmas is approaching and S4nt4 has a lot to do on his <I>paws</I>. He wants to give all the gifts on time, but he must be fast! Since our dear S4nt4 is clumsy, some gifts will fall and you will have to <CE>collect</CE> them by pressing the <I>space bar</I>! Give the gifts back to S4nt4 when he feels <CE>dizzy</CE> by pressing the <I>space bar</I>!"},
4165
		fr = {"Joyeux Noël et Bonne Année!","Noël approche et S4nt4 en a plein les <I>pattes</I>. Il veut donner tous les cadeaux à temps, mais il doit être rapide ! Puisque notre cher S4nt4 est maladroix, certains cadeaux tombent et vous devrez les, <CE>collecter</CE> en appuyant sur la <I>barre d'espace</I>! Donnez les cadeaux à S4nt4 quand il se sent <CE>étourdi</CE> en appuyant sur la <I>barre d'espace</I>!"},
4166
		br = {"Feliz Natal & Feliz Ano Novo!","O Natal está chegando e S4nt4 tem em suas <I>patas</I> muito o que fazer. Ele quer entregar todos os presentes a tempo, mas ele deve ser rápido! Uma vez que nosso querido S4NT4 é desajeitado, alguns presentes cairão e você terá que <CE>coletá-los</CE> pressionando a <I>barra de espaço</I>! Devolva os presentes ao S4nt4, pressionando a <I>barra de espaço</I>, quando ele se sentir <CE>tonto</CE>!"},
4167
		es = {"¡Feliz Navidad y Próspero Año Nuevo!","La Navidad se está acercando y S4nt4 tiene muchas cosas que hacer con sus <I>patas</I>. Él quiere dar todos los regalos a tiempo, pero debe ser rápido! Puesto que nuestro querido S4nt4 es torpe, algunos regalos caerán y tendrás que <CE>recogerlos</CE> pulsando la <I>barra espaciadora</I>! Regrese los regalos a S4nt4 cuando se sienta <CE>mareado</CE> presionando la <I>barra de espacio</I>!"},
4168
		tr = {"Mutlu Noeller & Mutlu Yıllar!","Noel geliyor ve S4nt4'nın <I>patilerinde</I> yapacağı çok işi var. Bütün hediyeleri zamanında vermek istiyor ama hızlı olması gerek! Sevgili S4nt4'mız sakar olduğu için, bazı hediyeler düşecek ve <I>boşluk tuşuna</I> basarak onları <CE>toplamanız</CE> gerekecek! S4nt4'nın <CE>başı döndüğünde</CE> <I>boşluk tuşuna</I> basarak hediyeleri ona geri verin!"},
4169
		pl = {"Wesołych Świąt i Wesołego Nowego Roku!","Święta nadchodzą, a S4nt4 ma <I>łapki</I> pełne roboty. On chce dać wszystkim prezenty na czas, ale musi się pośpieszyć! Od kiedy nasz S4nt4 jest niezdarny, gubi prezenty, które musicie <CE>pozbierać</CE> wciskając <I>spację</I>! Oddajcie prezenty S4nt4 kiedy jest <CE>oszołomiony</CE> wciskając <I>spację</I>!"},
4170
		ar = {"عيد ميلاد مجيدا و كل عام و أنتم بخير","عيد الميلاد اقترب و<I> يدى </I> سانتا مليئة. يريد سانتا تسليم جميع الهدايا على الوقت, ولكن يجب ان يكون سريعا! ولكن صديقنا العزيز سانتا غير بارع في تسليم الهدايا, بعض الهدايا ستسقط وعليك ان تقوم <CE> بجمع</CE>  الهدايا التي سقطت عن طريق الضغط على المسطرة ! وارجاع الهدايا الى صديقنا العزيز سانتا عندما يشعر <CE> بالدوار</CE> عن طريق الضغط على زر المسطرة!"},
4171
		hu = {"Boldog Karácsonyt & Boldog Új Évet!","A Karácsony közeleg, és a Mikulásra pedig <I>rengeteg munka vár<I>. Oda akarja adni az összes ajándékot időben, de muszáj gyorsnak lennie! Mivel a mi Mikulásunk kétbalkezes, néhány ajándék lepottyan és Neked kell <CE>összegyűjteni</CE> azokat, a <I>Szóköz</I> megnyomásával! Vidd vissza a Mikulásnak az ajándékot a <I>Szóköz</I> megnyomásával, amikor Mikulás <CE>megszédül</CE>!"},
4172
		ru = {"С новым годом и Рождеством!","Рождество приближается и S4nt4 направляется к вам! Он очень спешит, чтобы раздать все подарки вовремя! Но так как наш дорогой S4nt4 неуклюж, то некоторые подарки будут падать. Вы должны <CE>собрать</CE> их, нажимая клавишу <I>пробел</I>! Помогите S4nta. <CE>Верните</CE> ему подарки обратно с помощью <I>пробела</I>!"},
4173
	},
4174
	langue = "en",
4175
	-- Data
4176
	info = {},
4177
	gifts = {
4178
		[1] = {
4179
			[1] = "158bb1db61b",
4180
			[2] = 20000,
4181
		};
4182
		[2] = {
4183
			[1] = "158bb1c95e0",
4184
			[2] = 15000,
4185
		};
4186
		[3] = {
4187
			[1] = "158bb1cc6ec",
4188
			[2] = 10000,
4189
		};
4190
		[4] = {
4191
			[1] = "158bb1ce1aa",
4192
			[2] = 8000,
4193
		};
4194
		[5] = {
4195
			[1] = "1591c9b3123",
4196
			[2] = 6000,
4197
		};
4198
	},
4199
	-- Maps
4200
	xml = '<C><P DS="y;310" /><Z><S><S H="10" L="50" X="275" c="2" Y="165" T="12" P="0,0,0.3,0.2,0,0,0,0" /><S L="200" X="100" H="80" Y="360" T="12" P="0,0,0.3,0.2,0,0,0,0" /><S L="200" X="109" H="80" Y="379" T="12" P="0,0,0.3,0.2,-10,0,0,0" /><S X="391" L="230" H="80" c="3" Y="354" T="12" P="0,0,0.3,0.2,-2,0,0,0" /><S H="100" L="230" X="430" c="3" Y="411" T="12" P="0,0,0.3,0.2,-30,0,0,0" /><S H="80" L="180" X="705" c="3" Y="397" T="12" P="0,0,0.3,0.2,-2,0,0,0" /><S P="0,0,0.3,0.2,0,0,0,0" L="44" H="10" c="3" Y="361" T="13" X="237" /><S X="-5" L="10" H="3000" c="3" Y="100" T="12" P="0,0,0,0,0,0,0,0" /><S H="3000" L="10" X="805" c="3" Y="101" T="12" P="0,0,0,0,0,0,0,0" /><S L="10" X="400" H="3000" Y="-5" T="12" P="0,0,0,0,90,0,0,0" /><S L="80" H="10" X="96" Y="158" T="12" P="0,0,0.3,0.2,0,0,0,0" /><S P="0,0,0.3,.9,0,0,0,0" L="50" X="275" c="3" Y="165" T="12" H="10" /><S L="130" X="527" H="10" Y="128" T="12" P="0,0,0.3,0.2,10,0,0,0" /><S L="90" H="10" X="632" Y="131" T="12" P="0,0,0.3,0.2,-10,0,0,0" /><S H="3000" L="10" o="23E9E9" X="805" c="2" Y="100" T="12" m="" P="0,0,0,2,0,0,0,0" /><S X="-5" L="10" o="23E9E9" H="3000" c="2" Y="100" T="12" m="" P="0,0,0,2,0,0,0,0" /><S P="0,0,0.3,0.2,-35,0,0,0" L="230" X="549" c="3" Y="467" T="12" H="100" /><S P="0,0,0.3,0.2,-55,0,0,0" L="230" H="100" c="3" Y="441" T="12" X="250" /><S L="230" X="125" H="100" Y="422" T="12" P="0,0,0.3,0.2,-30,0,0,0" /><S X="510" L="230" H="100" c="3" Y="477" T="12" P="0,0,0.3,0.2,-65,0,0,0" /><S L="50" X="91" H="50" Y="339" T="12" P="0,0,0.3,0.2,-45,0,0,0" /><S P="0,0,0.3,0.2,0,0,0,0" L="30" X="164" c="2" Y="325" T="12" H="50" /><S P="0,0,0.3,1.1,0,0,0,0" L="30" H="50" c="3" Y="325" T="12" X="164" /><S L="50" X="240" H="10" Y="158" T="12" P="0,0,0.3,0.2,0,0,0,0" /><S L="50" H="10" X="443" Y="125" T="12" P="0,0,0.3,0.2,-20,0,0,0" /><S H="80" L="220" o="23E9E9" X="393" c="1" Y="359" T="12" m="" P="0,0,0.3,0.2,-2,0,0,0" /><S L="230" o="23E9E9" X="427" H="100" Y="416" T="12" m="" P="0,0,0.3,0.2,-30,0,0,0" /><S P="0,0,0.3,0.2,-65,0,0,0" L="230" o="23E9E9" H="100" Y="481" T="12" m="" X="501" /><S P="0,0,0.3,0.2,-35,0,0,0" L="230" o="23E9E9" H="100" Y="474" T="12" m="" X="550" /><S P="0,0,0.3,0.2,-2,0,0,0" L="180" o="23E9E9" X="706" Y="404" T="12" m="" H="80" /><S P="0,0,0.3,0.2,1,0,0,0" L="230" o="23E9E9" X="314" c="2" Y="373" T="12" m="" H="100" /></S><D><P X="241" Y="507" T="51" P="0,1" /><P X="566" Y="449" T="46" P="0,0" /></D><O /></Z></C>',
4201
	initx = 240,
4202
	inity = 140,
4203
	-- New Game Settings
4204
	aim = 8,
4205
	start = true,
4206
	amountPlayers = 20,
4207
	despawnObjects = {},
4208
	currentGifts = {},
4209
	currentTime = 0,
4210
	leftTime = 150,
4211
	-- Player Settings
4212
	setPlayerTools = function(k)
4213
		mode.xmas.info[k] = {
4214
			db = {
4215
				eventNoelGifts = {0,0},
4216
			},
4217
			catch = 0,
4218
			lastColor = 0xB73535,
4219
		}
4220
		if not tfm.get.room.playerList[k].isDead then
4221
			system.bindKeyboard(k,32,true,true)
4222
		end
4223
		mode.xmas.updateBar(k)
4224
	end,
4225
	-- Noel's AI
4226
	noel = {
4227
		x = 240,
4228
		y = 140,
4229
		id = -1,
4230
		isEscaping = false,
4231
		isDizzy = {0,false},
4232
		timers = {
4233
			teleport = 0,
4234
			prize = 0
4235
		},
4236
		img = {
4237
			dizzy = {"158bb1dccb6","158bb1cf9a8","158bb1d6489","158bb1e2518"},
4238
			right = "158bb1d8069",
4239
			left = "158bb1e0daf",
4240
			jumping = "158bb1d470a",
4241
			stop = "158bb1d9b67",
4242
		},
4243
		updateImage = function(img)
4244
			tfm.exec.removeImage(mode.xmas.noel.imgId)
4245
			mode.xmas.noel.imgId = tfm.exec.addImage(img..".png","#"..mode.xmas.noel.id,-23,-32)
4246
		end,
4247
		particles = function(id)
4248
			for i = 1,5 do
4249
				tfm.exec.displayParticle(id,mode.xmas.noel.x + mathrandom(-50,50),mode.xmas.noel.y + mathrandom(-50,50),tablerandom({-.2,.2}),tablerandom({-.2,.2}))
4250
			end
4251
		end,
4252
		move = function(x,y)
4253
			tfm.exec.moveObject(mode.xmas.noel.id,0,0,false,x,y,false)
4254
		end,
4255
		nearMouse = function(range)
4256
			local player = {"",{dist=mathrandom(800),x=0,y=0}}
4257
			for k,v in next,tfm.get.room.playerList do
4258
				if not v.isDead then
4259
					if mathpythag(v.x,v.y,mode.xmas.noel.x,mode.xmas.noel.y,range) then
4260
						local m = v.x-mode.xmas.noel.x
4261
						if mathabs(m) < player[2].dist then
4262
							player = {k,{dist=m,x=v.x,y=v.y}}
4263
						end
4264
					end
4265
				end
4266
			end
4267
			mode.xmas.noel.isEscaping = player[1] ~= ""
4268
			return player
4269
		end,
4270
		escape = function(id)
4271
			local player = mode.xmas.noel.nearMouse(mathrandom(80,100))
4272
			local mul = (player[1] ~= "" and mathisNegative(player[2].dist,1,-1) or tablerandom({-1,1}))
4273
			local img = mathisNegative(mul,"left","right")
4274
			local rand = 9 - mathrandom(0,9)
4275
			if id == 0 or (rand < 6) then
4276
				mode.xmas.noel.move(mul * mathrandom(50,80),-mathrandom(1,10))
4277
				mode.xmas.noel.updateImage(mode.xmas.noel.img[img])
4278
			elseif id == 1 or (rand < 9) then
4279
				mode.xmas.noel.move(mul * mathrandom(60,70),-80)
4280
				mode.xmas.noel.updateImage(tablerandom({mode.xmas.noel.img[img],mode.xmas.noel.img.jumping}))
4281
			elseif id == 2 or rand == 9 then
4282
				mode.xmas.noel.move(mul * mathrandom(10,20),-mathrandom(70,100))
4283
				mode.xmas.noel.updateImage(mode.xmas.noel.img.jumping)
4284
			end
4285
		end,
4286
		meep = function()
4287
			tfm.exec.displayParticle(20,mode.xmas.noel.x,mode.xmas.noel.y)
4288
			tfm.exec.explosion(mode.xmas.noel.x,mode.xmas.noel.y,20,50)
4289
		end,
4290
		cannon = function()
4291
			local player = mode.xmas.noel.nearMouse(100)
4292
			if player[1] ~= "" then
4293
				local x = mode.xmas.noel.x + (mode.xmas.noel.x > player[2].x and -40 or 40)
4294
				local y = mode.xmas.noel.y + (mode.xmas.noel.y > player[2].y and -40 or 40)
4295
				local angle = mathdeg(mathatan2(player[2].y-mode.xmas.noel.y,player[2].x-mode.xmas.noel.x)) + 90
4296
				tableinsert(mode.xmas.despawnObjects,{
4297
					[1] = tfm.exec.addShamanObject(1703,x,y,angle),
4298
					[2] = os.time() + 2500
4299
				})
4300
				local effect = function(id,sx,sy,xs,ys,e)
4301
					for i = 1,2 do
4302
						tfm.exec.displayParticle(id[i] and id[i] or id[1],x + sx * e,y - sy * e,xs/1.5,ys/1.5)
4303
					end
4304
				end
4305
				for i = 1,20 do
4306
					effect({9,11},mathcos(i),mathsin(i),mathcos(i),-mathsin(i),22)
4307
					effect({13},mathcos(i),mathsin(i),mathsin(i),mathcos(i),19)
4308
				end
4309
			end
4310
		end,
4311
		teleport = function()
4312
			if os.time() > mode.xmas.noel.timers.teleport then
4313
				mode.xmas.noel.timers.teleport = os.time() + 8000
4314
				tfm.exec.displayParticle(37,mode.xmas.noel.x,mode.xmas.noel.y)
4315
				local x,y = mathrandom(20,780),mathrandom(50,300)
4316
				tfm.exec.moveObject(mode.xmas.noel.id,x,y)
4317
				tfm.exec.displayParticle(37,x,y)
4318
			else
4319
				mode.xmas.noel.escape(2)
4320
			end
4321
		end,
4322
		gift = function()
4323
			if os.time() > mode.xmas.noel.timers.prize then
4324
				mode.xmas.noel.timers.prize = os.time() + 5000
4325
				mode.xmas.noel.updateImage(mode.xmas.noel.img.stop)
4326
				local giftsAmount = mode.xmas.amountPlayers < 10 and 1 or mathfloor(mode.xmas.amountPlayers/10)
4327
				for i = 1,giftsAmount do
4328
					local gift = tablerandom({2,4,3,1,1,2,3,5,2,4})
4329
					for k,v in next,mode.xmas.gifts do
4330
						if gift == k then
4331
							gift = k
4332
							break
4333
						end
4334
					end
4335
					local gen = {}
4336
					gen[1] = tfm.exec.addShamanObject(6300,mode.xmas.noel.x,mode.xmas.noel.y,0,tablerandom({-13,-10,-5,5,10,13}))
4337
					gen[2] = os.time() + mode.xmas.gifts[gift][2]
4338
					gen[3] = tfm.exec.addImage(mode.xmas.gifts[gift][1]..".png","#"..gen[1],-15,-15)
4339
					gen[4] = gift
4340
					tableinsert(mode.xmas.currentGifts,gen)
4341
				end
4342
			else
4343
				mode.xmas.noel.escape(0)
4344
			end
4345
		end,
4346
		dizzy = function(timer)
4347
			if os.time() > mode.xmas.noel.timers.prize then
4348
				mode.xmas.noel.isDizzy[1] = os.time() + 9500
4349
			else
4350
				mode.xmas.noel.escape(2)
4351
			end
4352
		end,
4353
	},
4354
	resetNoel = function()
4355
		mode.xmas.initx = 240
4356
		mode.xmas.inity = 140
4357
		mode.xmas.noel.x = mode.xmas.initx
4358
		mode.xmas.noel.y = mode.xmas.inity
4359
		mode.xmas.noel.id = -1
4360
		mode.xmas.noel.isEscaping = false
4361
		mode.xmas.noel.isDizzy = {0,false}
4362
		mode.xmas.noel.timers = {
4363
			teleport = 0,
4364
			prize = 0
4365
		}
4366
	end,
4367
	-- Bar
4368
	displayBar = function(id,player,value,nvalue,color,sig,size,height)
4369
		sig = sig or ""
4370
		size = size or 100
4371
		height = height or 20
4372
4373
		ui.addTextArea(id,"",player,5,(height+8) * id,size + 4,height,0xC7CED2,1,1,true)
4374
		if value ~= 0 then
4375
			ui.addTextArea(id.."0","",player,6,(height+8) * id + 2,nvalue + 2,height - 4,color,color,1,true)
4376
		end
4377
		ui.addTextArea(id + 2,"<B><font color='#0'>"..value..sig,player,(size-30)/2,(height+8) * id + 1,50,height,1,1,0,true)
4378
	end,
4379
	updateBar = function(n,giftColor)
4380
		giftColor = giftColor or mode.xmas.info[n].lastColor
4381
		mode.xmas.displayBar(1,n,mathfloor(mode.xmas.info[n].db.eventNoelGifts[2]) .. " / "..mode.xmas.aim,(mode.xmas.info[n].db.eventNoelGifts[2] > mode.xmas.aim and 100 or mathpercent(mode.xmas.info[n].db.eventNoelGifts[2],mode.xmas.aim,100)),0xFF0000)
4382
		mode.xmas.displayBar(2,n,mode.xmas.info[n].db.eventNoelGifts[1],(mode.xmas.info[n].db.eventNoelGifts[1] > 50 and 50 or mathpercent(mode.xmas.info[n].db.eventNoelGifts[1],50,50)),giftColor,"G",50,20)
4383
	end,
4384
	-- Init
4385
	init = function()
4386
		mode.xmas.translations.pt = mode.xmas.translations.br
4387
		mode.xmas.langue = mode.xmas.translations[tfm.get.room.community] and tfm.get.room.community or "en"
4388
		for i,f in next,{"AutoShaman","AfkDeath","MortCommand","AutoTimeLeft","PhysicalConsumables","AutoNewGame","DebugCommand"} do
4389
			tfm.exec["disable"..f]()
4390
		end
4391
		tfm.exec.setRoomMaxPlayers(25)
4392
		tfm.exec.newGame(mode.xmas.xml)
4393
		mode.xmas.aim = system.miscAttrib > 0 and system.miscAttrib or 8
4394
	end,
4395
	-- New Game
4396
	eventNewGame = function()
4397
		mode.xmas.resetNoel()
4398
4399
		mode.xmas.start = true
4400
		
4401
		local _,aP = system.players()
4402
		mode.xmas.amountPlayers = aP
4403
		
4404
		tfm.exec.setGameTime(150)
4405
		tfm.exec.snow(150)
4406
		mode.xmas.currentTime = 0
4407
		mode.xmas.leftTime = 150
4408
		
4409
		tfm.exec.addImage("158c1feaf90.png","?0",0,0)
4410
		
4411
		ui.setMapName("<J>"..tablerandom({"Nöel","Christmas","Bolodefchoco","Lua event","#xmas","Bogkitty"}).." <G>- @"..tablerandom({666,404,801,os.date("%Y"),0,1}))
4412
		ui.setShamanName("<R>S4NT4 M4U5")
4413
		
4414
		for k,v in next,tfm.get.room.playerList do
4415
			mode.xmas.setPlayerTools(k)
4416
		end
4417
		tfm.exec.chatMessage(stringformat("<V><B>[^_^]</B></V> <BV>%s</BV>\n<V><B>[S4NT4 M4U5]</B></V> <R>%s</R>",mode.xmas.translations[mode.xmas.langue][2],stringupper(mode.xmas.translations[mode.xmas.langue][1])))
4418
	end,
4419
	-- New Player
4420
	eventNewPlayer = function(n)
4421
		tfm.exec.addImage("158c1feaf90.png","?0",0,0,n)
4422
		mode.xmas.setPlayerTools(n)
4423
		tfm.exec.respawnPlayer(n)
4424
	end,
4425
	-- Loop
4426
	eventLoop = function()
4427
		mode.xmas.currentTime = mode.xmas.currentTime + .5
4428
		mode.xmas.leftTime = mode.xmas.leftTime - .5
4429
		if mode.xmas.start then
4430
			if mode.xmas.currentTime > 4 then
4431
				if mode.xmas.noel.id == -1 then
4432
					mode.xmas.noel.id = tfm.exec.addShamanObject(6300,mode.xmas.noel.x,mode.xmas.noel.y)
4433
					mode.xmas.noel.updateImage(mode.xmas.noel.img.stop)
4434
				end
4435
4436
				local ox,oy
4437
				if tfm.get.room.objectList[mode.xmas.noel.id] then
4438
					ox,oy = tfm.get.room.objectList[mode.xmas.noel.id].x,tfm.get.room.objectList[mode.xmas.noel.id].y
4439
				else
4440
					ox,oy = mode.xmas.noel.x,mode.xmas.noel.y
4441
				end
4442
4443
				if (ox < -10 or ox > 810) or (oy > 400 or oy < -50) then
4444
					tfm.exec.removeObject(mode.xmas.noel.id)
4445
					mode.xmas.noel.x,mode.xmas.noel.y = mode.xmas.initx,mode.xmas.inity
4446
					mode.xmas.noel.id = nil
4447
				end
4448
4449
				if mode.xmas.noel.id then
4450
					mode.xmas.noel.x = ox
4451
					mode.xmas.noel.y = oy
4452
				end
4453
4454
				for k,v in ipairs(mode.xmas.despawnObjects) do
4455
					if os.time() > v[2] then
4456
						tfm.exec.removeObject(v[1])
4457
					end
4458
				end
4459
				for k,v in ipairs(mode.xmas.currentGifts) do
4460
					if os.time() > v[2] then
4461
						tfm.exec.removeObject(v[1])
4462
						tfm.exec.removeImage(v[3])
4463
					end
4464
				end
4465
4466
				if os.time() > mode.xmas.noel.isDizzy[1] and mode.xmas.currentTime > 5 then
4467
					mode.xmas.noel.particles(13)
4468
					if mode.xmas.currentTime % 60 == 0 then
4469
						mode.xmas.noel.dizzy()
4470
					elseif mode.xmas.currentTime % 5 == 0 then
4471
						mode.xmas.noel.gift()
4472
						mode.xmas.noel.escape(1)
4473
					elseif mathfloor(mode.xmas.currentTime) % 2 == 0 then
4474
						local option = mathrandom((mode.xmas.noel.isEscaping and 15 or 12))
4475
						if option > 3 then
4476
							mode.xmas.noel.escape()
4477
						else
4478
							mode.xmas.noel.updateImage(mode.xmas.noel.img.stop)
4479
							if mode.xmas.currentTime > 7 and mathrandom(1,2) == 1 then
4480
								if option == 3 then
4481
									mode.xmas.noel.cannon()
4482
								elseif option == 2 then
4483
									mode.xmas.noel.teleport()
4484
								elseif option == 1 then
4485
									mode.xmas.noel.meep()
4486
								end
4487
							end
4488
						end
4489
					else
4490
						mode.xmas.noel.updateImage(mode.xmas.noel.img.stop)
4491
					end
4492
				else
4493
					mode.xmas.noel.particles(1)
4494
					if not mode.xmas.noel.isDizzy[2] then
4495
						mode.xmas.noel.isDizzy[2] = true
4496
						mode.xmas.noel.timers.prize = os.time() + 5000
4497
						local imgId = #mode.xmas.noel.img.dizzy
4498
						local animation = {}
4499
						local numb = 1
4500
						animation = system.looping(function()
4501
							mode.xmas.noel.updateImage(mode.xmas.noel.img.dizzy[imgId])
4502
4503
							if imgId == #mode.xmas.noel.img.dizzy or imgId == 1 then
4504
								numb = -numb
4505
							end
4506
4507
							imgId = imgId + numb
4508
4509
							if (os.time()+250) > mode.xmas.noel.isDizzy[1] then
4510
								for k,v in next,animation do
4511
									system.removeTimer(v)
4512
								end
4513
								mode.xmas.noel.isDizzy = {0,false}
4514
							end
4515
						end,10)
4516
					end
4517
				end
4518
			end
4519
			if mode.xmas.leftTime < 2 then
4520
				mode.xmas.start = false
4521
				tfm.exec.newGame(mode.xmas.xml)
4522
			end
4523
		end
4524
	end,
4525
	-- Keyboard
4526
	eventKeyboard = function(n,k,d,x,y)
4527
		if mode.xmas.start then
4528
			if os.time() > mode.xmas.info[n].catch and k == 32 then
4529
				if os.time() < mode.xmas.noel.isDizzy[1] then
4530
					if mathpythag(x,y,mode.xmas.noel.x,mode.xmas.noel.y,32) then
4531
						mode.xmas.info[n].db.eventNoelGifts[2] = (mode.xmas.info[n].db.eventNoelGifts[1]/10) + mode.xmas.info[n].db.eventNoelGifts[2]
4532
						mode.xmas.info[n].db.eventNoelGifts[1] = 0
4533
4534
						mode.xmas.updateBar(n)
4535
					end
4536
				else
4537
					for k,v in next,mode.xmas.currentGifts do
4538
						local o = tfm.get.room.objectList[v[1]]
4539
						if o and mathpythag(x,y,o.x,o.y,25) then
4540
							if (mode.xmas.info[n].db.eventNoelGifts[1]+v[4]) <= 50 then
4541
								tfm.exec.removeObject(v[1])
4542
								tfm.exec.removeImage(v[3])
4543
4544
								mode.xmas.currentGifts[k][2] = 0
4545
								mode.xmas.info[n].db.eventNoelGifts[1] = mode.xmas.info[n].db.eventNoelGifts[1] + v[4]
4546
4547
								mode.xmas.updateBar(n,({0xB73535,0x358CB7,0x35B765,0xB7B735,0xB73487})[v[4]])
4548
								break
4549
							end
4550
						end
4551
					end
4552
				end
4553
				mode.xmas.info[n].catch = os.time() + 1000
4554
			end
4555
		end
4556
	end,
4557
	-- Player Died
4558
	eventPlayerDied = function(n)
4559
		if mode.xmas.start then
4560
			system.bindKeyboard(n,32,true,false)
4561
		end
4562
	end,
4563
}
4564
4565
--[[ Signal ]]--
4566
mode.signal = {
4567
	-- Translations
4568
	translations = {
4569
		en = {
4570
			-- Init
4571
			welcome = "<S>Welcome to <PS>#Signal<S>! Follow the signs and join the hole! Use !help to read more informations.\n\tReport any issue to Bolodefchoco",
4572
			
4573
			-- Info
4574
			info = {
4575
				[1] = {"Run","Run the faster you can. Do not stop!"},
4576
				[2] = {"Attention","Pay attention! You can die in a few seconds!"},
4577
				[3] = {"Stop","Stop or die!"},
4578
			},
4579
			skip = "<PS>[•] <S>Impossible map? Type !skip",
4580
			skipped = "Your vote to skip the map has been recorded.",
4581
			
4582
			-- Simple words
4583
			close = "Close",
4584
		},
4585
		br = {
4586
			welcome = "<S>Bem-vindo ao <PS>#Signal<S>! Siga os sinais e entre na toca!  Use !help para ler mais informações.\n\tReporte qualquer problema para Bolodefchoco",
4587
4588
			info = {
4589
				[1] = {"Corra","Corra o mais rápido que puder. Não pare!"},
4590
				[2] = {"Atenção","Preste atenção! Você poderá morrer a qualquer momento!"},
4591
				[3] = {"Pare","Pare ou morra!"},
4592
			},
4593
			skip = "<PS>[•] <S>Mapa impossível? Digite !skip",
4594
			skipped = "Seu voto para passar o mapa foi registrado.",
4595
4596
			close = "Fechar",
4597
		},
4598
		pl = {
4599
			welcome = "<S>Witaj w <PS>#Signal<S>! Patrz na tabliczke i wejdź do norki! Użyj komendy !help, aby przeczytać więcej informacji.\n\tZgłoś wszystkie błędy jakie znajdziesz do Bolodefchoco",
4600
			
4601
			info = {
4602
				[1] = {"Biegnij","Biegnij jak najszybciej do norki. Nie zatrzymuj się!"},
4603
				[2] = {"Uważaj","Uważaj! Możesz zginąć za kilka sekund!"},
4604
				[3] = {"Stój","Stój albo zgiń!"},
4605
			},
4606
			skip = "<PS>[•] <S>Niemożliwa mapa? Wpisz komendę !skip",
4607
			skipped = "Twój głos na ominięcie mapy został policzony.",
4608
			
4609
			close = "Zamknij",
4610
		},
4611
	},
4612
	langue = "en",
4613
	-- Data
4614
	info = {},
4615
	-- Maps
4616
	generateMap = function()
4617
		local groundProperties = {[0] = {.3,.2},[4] = {20,.2},[5] = {.3,.2},[6] = {.3,.2},[7] = {.1,.2},[10] = {.3,0},[11] = {.05,.1},[3] = {5,20}}
4618
		local groundDecorations = {[0] = {0,4,5},[4] = {1,42,51},[5] = {1,2,4,12,18,20,32,42,46},[6] = {0,1,2,3,4,5,11,42},[7] = {7,8,9,10},[10] = {42,103,118},[11] = {51,106},[3] = {}}
4619
		local newGround = "<S L=\"%s\" H=\"%s\" X=\"%s\" Y=\"%s\" T=\"%s\" P=\"0,0,%s,%s,0,0,0,0\" />"
4620
		local newDecoration = "<P P=\"%s,0\" X=\"%d\" Y=\"%d\" T=\"%d\" />"
4621
		local object = "<%s X=\"%s\" Y=\"%s\"/>"
4622
		local objects = {hole="T",mice="DS",cheese="F"}
4623
4624
		local mapHeight = mathrandom(1500,3000)
4625
4626
		local grounds = {}
4627
		local decorations = {}
4628
		for i = 1,mathceil(mapHeight/180) do
4629
			local T = tablerandom({0,4,5,6,7,10,11,tablerandom({4,5,6,10,3})})
4630
4631
			local H = T==3 and mathrandom(10,20) or mathrandom(40,100)
4632
4633
			local Y = (#grounds > 1 and grounds[#grounds].Y < 320 and mathrandom(230,310) or mathrandom(300,350)) or mathrandom(290,350)
4634
4635
			local X,L
4636
			repeat
4637
				X = (#grounds > 1 and (grounds[#grounds].X + ((mathrandom(-1,1) * 30) + 200)) or mathrandom(50,300))
4638
				X = X < 60 and 100 or X > mapHeight - 100 and mapHeight - 300 or X
4639
				L = T==3 and H or mathrandom(40,mathceil(mapHeight/18))
4640
			until (X - (L/2)) > 50 and (X + (L/2)) < mapHeight - 50
4641
4642
			local properties = groundProperties[T]
4643
			grounds[#grounds + 1] = {X=X,Y=Y,L=L,H=H,stringformat(newGround,L,H,X,Y,T,properties[1],properties[2])}
4644
4645
			if T ~= 3 and mathrandom(20) < 10 then
4646
				local decoList = groundDecorations[T]
4647
				decorations[#decorations + 1] = stringformat(newDecoration,tablerandom({0,0,0,mathrandom(0,1),1}),X - mathrandom(-((L/4)+1),((L/4)+1)),Y - (H/2),tablerandom(decoList))
4648
			end
4649
		end
4650
		
4651
		local cheeseX
4652
		repeat
4653
			cheeseX = mathrandom(200,mapHeight - 500)
4654
		until (function()
4655
			for k,v in next,grounds do
4656
				if (cheeseX + 10) > (v.X - v.L/2) and (cheeseX - 10) < (v.X + v.L/2) then
4657
					return false
4658
				end
4659
			end
4660
			return true
4661
		end)()
4662
4663
		grounds[#grounds + 1] = {X=0,Y=0,L=0,H=0,stringformat(newGround,200,40,100,380,2,.3,.9)}
4664
		grounds[#grounds + 1] = {X=0,Y=0,L=0,H=0,stringformat(newGround,300,40,mapHeight - 150,380,6,.3,.2)}
4665
4666
		tfm.exec.newGame(stringformat("<C><P G=\"0,%s\" F=\"%s\" L=\"%s\" /><Z><S>%s</S><D>%s%s%s%s</D><O /></Z></C>",tablerandom({mathrandom(7,12),10,11,9}),tablerandom({0,1,2,3,4,5,7,8}),mapHeight,tableconcat(grounds,"",function(k,v) return v[1] end),stringformat(object,objects.hole,mapHeight - 30,360),stringformat(object,objects.mice,10,365),stringformat(object,objects.cheese,cheeseX,mathrandom(280,340)),tableconcat(decorations)))
4667
	end,
4668
	-- Settings
4669
	sys = {0,1},
4670
	discrepancy = 0,
4671
	lights = {"15b52f8717d","15b52f8583a","15b52f88765"},
4672
	lightId = -1,
4673
	skip = 0,
4674
	rounds = 0,
4675
	possible = false,
4676
	-- Settings
4677
	update = function(id)
4678
		tfm.exec.removeImage(mode.signal.lightId)
4679
		mode.signal.lightId = tfm.exec.addImage(mode.signal.lights[mode.signal.sys[2]] .. ".png","&0",375,30)
4680
		local color = ({0x1CB70C,0xF4D400,0xEC0000})[mode.signal.sys[2]]
4681
		for k,v in next,mode.signal.info do
4682
			if id == 1 then
4683
				if not v.afk and v.canRev then
4684
					tfm.exec.respawnPlayer(k)
4685
				end
4686
			end
4687
			tfm.exec.setNameColor(k,color)
4688
		end
4689
	end,
4690
	-- Help
4691
	displayInfo = function(n,id)
4692
		local color = ({"<VP>","<J>","<R>"})[id]
4693
		ui.addTextArea(1,"<p align='center'><font size='25'>" .. color .. mode.signal.translations[mode.signal.langue].info[id][1] .. "\n</font></p><p align='left'><font size='14'>" .. mode.signal.translations[mode.signal.langue].info[id][2],n,250,110,300,181,0x324650,0x27343A,1,true)
4694
		ui.addTextArea(2,"<font size='2'>\n</font><p align='center'><font size='16'><a href='event:close'>" .. mode.signal.translations[mode.signal.langue].close,n,250,300,300,30,0x27343A,0x27343A,1,true)
4695
		ui.addTextArea(3,"<p align='center'><font size='20'><a href='event:info.1'><VP>•</a> <a href='event:info.2'><J>•</a> <a href='event:info.3'><R>•</a>",n,250,145,300,30,1,1,0,true)
4696
		tfm.exec.removeImage(mode.signal.info[n].imageId)
4697
		mode.signal.info[n].imageId = tfm.exec.addImage(mode.signal.lights[id] .. ".png","&1",375,200,n)
4698
	end,
4699
	-- Init
4700
	reset = function()
4701
		-- Data
4702
		mode.signal.info = {}
4703
	end,
4704
	init = function()
4705
		mode.signal.translations.pt = mode.signal.translations.br
4706
		mode.signal.langue = mode.signal.translations[tfm.get.room.community] and tfm.get.room.community or "en"
4707
4708
		for _,f in next,{"AutoShaman","AutoNewGame","AutoTimeLeft","PhysicalConsumables"} do
4709
			tfm.exec["disable"..f]()
4710
		end
4711
4712
		mode.signal.generateMap()
4713
	end,
4714
	-- New Player
4715
	eventNewPlayer = function(n)
4716
		if not mode.signal.info[n] then
4717
			mode.signal.info[n] = {
4718
				isMoving = {false,false,false,false},
4719
				imageId = -1,
4720
				afk = true,
4721
				skipped = false,
4722
				canRev = true,
4723
			}
4724
		end
4725
		for i = 0,3 do
4726
			system.bindKeyboard(n,i,true,true)
4727
			system.bindKeyboard(n,i,false,true)
4728
		end
4729
		tfm.exec.chatMessage(mode.signal.translations[mode.signal.langue].welcome,n)
4730
	end,
4731
	-- New Game
4732
	eventNewGame = function()
4733
		mode.signal.skip = 0
4734
		mode.signal.possible = false
4735
		mode.signal.rounds = mode.signal.rounds + 1
4736
		
4737
		if mode.signal.rounds % 3 == 0 then
4738
			tfm.exec.chatMessage(mode.signal.translations[mode.signal.langue].skip)
4739
		end
4740
		
4741
		ui.setMapName("<BL>@" .. mathrandom(999) .. "   <G>|   <N>Round : <V>" .. mode.signal.rounds)
4742
		
4743
		for k,v in next,mode.signal.info do
4744
			v.isMoving = {false,false,false,false}
4745
			v.afk = true
4746
			v.skipped = false
4747
			v.canRev = true
4748
		end
4749
		
4750
		mode.signal.sys = {0,1}
4751
		mode.signal.update(mode.signal.sys[2])
4752
	end,
4753
	-- Keyboard
4754
	eventKeyboard = function(n,k,d)
4755
		if mode.signal.sys[2] == 3 and d and os.time() > mode.signal.discrepancy then
4756
			tfm.exec.killPlayer(n)
4757
		else
4758
			mode.signal.info[n].isMoving[k + 1] = d
4759
		end
4760
		mode.signal.info[n].afk = false
4761
	end,
4762
	-- Loop
4763
	eventLoop = function(currentTime,leftTime)
4764
		if _G.currentTime > 8 then
4765
			if os.time() > mode.signal.sys[1] then
4766
				mode.signal.sys[2] = (mode.signal.sys[2] % 3) + 1
4767
				mode.signal.sys[1] = os.time() + ({mathrandom(7,13),mathrandom(2,3),mathrandom(3,5)})[mode.signal.sys[2]] * 1000
4768
				mode.signal.update(mode.signal.sys[2])
4769
				mode.signal.discrepancy = os.time() + 520
4770
			end
4771
		end
4772
4773
		if _G.leftTime > 2 and system.players() > 0 then
4774
			if mode.signal.sys[2] == 3 and os.time() > mode.signal.discrepancy then
4775
				for k,v in next,mode.signal.info do
4776
					for i,j in next,v.isMoving do
4777
						if j then
4778
							tfm.exec.killPlayer(k)
4779
							break
4780
						end
4781
					end
4782
				end
4783
			end
4784
		else
4785
			mode.signal.generateMap()
4786
		end
4787
	end,
4788
	-- Callbacks
4789
	eventTextAreaCallback = function(i,n,c)
4790
		local p = stringsplit(c,"[^%.]+")
4791
		if p[1] == "info" then
4792
			mode.signal.displayInfo(n,tonumber(p[2]))
4793
		elseif p[1] == "close" then
4794
			tfm.exec.removeImage(mode.signal.info[n].imageId)
4795
			for i = 1,3 do
4796
				ui.removeTextArea(i,n)
4797
			end
4798
		end
4799
	end,
4800
	-- Commands
4801
	eventChatCommand = function(n,c)
4802
		if c == "info" or c == "help" or c == "?" then
4803
			eventTextAreaCallback(nil,n,"info." .. mode.signal.sys[2])
4804
		elseif c == "skip" and _G.currentTime > 8 and not mode.signal.possible and not mode.signal.info[n].skipped then
4805
			mode.signal.skip = mode.signal.skip + 1
4806
			tfm.exec.chatMessage(mode.signal.translations[mode.signal.langue].skipped,n)
4807
			
4808
			local alive,total = system.players()
4809
			if mode.signal.skip == mathceil(.5 * total) then
4810
				tfm.exec.chatMessage("o/")
4811
				mode.signal.generateMap()
4812
			end
4813
		end
4814
	end,
4815
	-- Victory
4816
	eventPlayerWon = function(n)
4817
		mode.signal.possible = true
4818
		mode.signal.info[n].canRev = false
4819
		tfm.exec.setGameTime(40,false)
4820
	end,
4821
}
4822
4823
--[[ Bootcamp+ ]]--
4824
mode.bootcampP = {
4825
	-- Translations
4826
	translations = {
4827
		en = {
4828
			-- Init
4829
			welcome = "Welcome to <B>#Bootcamp+</B>! Type !info to check the commands\n\tReport any issue to Bolodefchoco!",
4830
			
4831
			-- Info
4832
			info = "Checkpoint:\n\tIf the checkpoint system is enabled, press <B>E</B> to put a checkpoint and <B>Shift+E</B> to remove it.\nAdmin\n\tIf you are a room admin, there are some commands that you can execute:\n\tMaps\n\t\t!next <V>--> Pass the map</V>\n\t\t!again <V>--> Resets the current map</V>\n\t\t!np @Code <VP>or</VP> !map @Code <V>--> Loads a map</V>\n\t\t!queue clear <V>--> Clear the map queue</V>\n\t\t!queue add @Code <V>--> Adds a map in the map queue</V>\n\t\t!queue P3 <VP>or</VP> P13 <VP>or</VP> P23 <V>--> Adds the whole official rotation of P3 or P13 or P23 in the map queue</V>\n\tTime\n\t\t!time TimeInMinutes <V>--> Set the time of the current round in TimeInMinutes</V>\n\t\t!standtime TimeInMinutes <V>--> Set the time of all the rounds in TimeInMinutes</V>\n\tOthers\n\t\t<B>Shift+Click</B> in a ground to read its properties\n\t\t!checkpoint [[not] cheese] <V>--> Enables/Disables the checkpoint system</V>\n\t\tKey Delete <V>--> Kills you</V>",
4833
			skip = "<VP>%s</VP> just skipped the map!",
4834
			restart = "<VP>%s</VP> just restarted the current map!",
4835
			loadmap = "<VP>%s</VP> just loaded the map %s!",
4836
			settime = "The time has been set to %s minutes!",
4837
			setstandtime = "The standard time of all the rounds has been set to %s minutes!",
4838
			enabled = "enabled! Press <B>E</B> to put a checkpoint and <B>Shift+E</B> to remove it.",
4839
			queuecleared = "%s just cleared the map queue",
4840
			queuemapadded = "%s just added the map %s to the map queue",
4841
			queueperm = "%s just added the category %s to the map queue",
4842
			queuereset = "%s just reseted the queue to the main maps",
4843
			
4844
			-- Simple words
4845
			disabled = "disabled!",
4846
		},
4847
		br = {
4848
			welcome = "Bem-vindo ao <B>#Bootcamp+</B>! Digite !info para checar os comandos\n\tReporte quaisquer problemas para Bolodefchoco!",
4849
			
4850
			info = "Checkpoint:\n\tSe o sistema de checkpoint está ativado, pressione <B>E</B> para marcar um checkpoint e <B>Shift+E</B> para remove-lo.\nAdmin\n\tSe você é um administrador da sala, há alguns comandos que você pode executar:\n\tMapas\n\t\t!next <V>--> Passa o mapa</V>\n\t\t!again <V>--> Reinicia o mapa atual</V>\n\t\t!np @Código <VP>ou</VP> !map @Código <V>--> Carrega um mapa</V>\n\t\t!queue clear <V>--> Limpa a lista de mapas</V>\n\t\t!queue add @Código <V>--> Adiciona um mapa na lista de mapas</V>\n\t\t!queue P3 <VP>ou</VP> P13 <VP>ou</VP> P23 <V>--> Adiciona a rotação inteira de P3 ou P13 ou P23 na lista de mapas</V>\n\tTempo\n\t\t!time TempoEmMinutos <V>--> Define o tempo do mapa atual em TempoEmMinutos</V>\n\t\t!standtime TempoEmMinutos <V>--> Define o tempo de todas as partidas em TempoEmMinutos</V>\n\tOutros\n\t\t<B>Shift+Click</B> sobre um piso para ler suas propriedades\n\t\t!checkpoint [[not] cheese] <V>--> Ativa/Desativa o sistema de checkpoint</V>\n\t\tTecla Delete <V>--> Mata-o</V>",
4851
			skip = "<VP>%s</VP> acabou de passar o mapa!",
4852
			restart = "<VP>%s</VP> acabou de reiniciar o mapa atual!",
4853
			loadmap = "<VP>%s</VP> acabou de carregar o mapa %s!",
4854
			settime = "O tempo foi definido para %s minutos!",
4855
			setstandtime = "O tempo padrão para todas as partidas foram definidas para %s minutos!",
4856
			enabled = "ativado! Pressione <B>E</B> para marcar um checkpoint e <B>Shift+E</B> para remove-lo.",
4857
			queuecleared = "%s acabou de limpar a rotação de mapas",
4858
			queuemapadded = "%s acabou de adicionar o mapa %s na rotação de mapas",
4859
			queueperm = "%s acabou de adicionar a categoria %s na rotação de mapas",
4860
			queuereset = "%s acabou de resetar a rotação de mapas para os mapas principais",
4861
			
4862
			disabled = "desativado!",
4863
		},
4864
		pl = {
4865
			welcome = "Witaj w <B>#Bootcamp+</B>! Wpisz !info na czacie aby sprawdzić jakie są komendy\n\tZgłaszaj wszelkie błędy do Bolodefchoco!",
4866
	
4867
			info = "Checkpoint:\n\tJeżeli system checkpointów jest włączony, kliknij <B>E</B>, aby ustawić checkpoint i <B>Shift+E</B>, aby go usunąć.\nAdmin\n\tJeżeli jesteś administratorem pokoju, jest kilka komend, które możesz użyć:\n\tMapy\n\t\t!next <V>--> Przełącza mapę</V>\n\t\t!again <V>--> Restartuje mapę</V>\n\t\t!np @Code <VP>albo</VP> !map @Code <V>--> Ładuje mapę</V>\n\t\t!queue clear <V>--> Czyści kolejkę map</V>\n\t\t!queue add @Code <V>--> Dodaję mapę do kolejki</V>\n\t\t!queue P3 <VP>albo</VP> P13 <VP>albo</VP> P23 <V>--> Dodaje wszystkie oficjalne rotacje z permów P3 albo P13 albo P23 do kolejki map</V>\n\tCzas\n\t\t!time CzasWMinutach <V>--> Ustawia czas obecnej mapy na CzasWMinutach</V>\n\t\t!standtime CzasWMinutach <V>--> Ustawia czas dla wszystkich rund na CzasWMinutach</V>\n\tInne\n\t\t<B>Shift+Click</B> na gruncie aby przeczytać jego właściwości\n\t\t!checkpoint [[not] cheese] <V>--> Włącza/Wyłącza system checkpointów</V>\n\t\tKey Delete <V>--> Kills you</V>",
4868
			skip = "<VP>%s</VP> pominął/-ęła mapę!",
4869
			restart = "<VP>%s</VP> zrestartował/-a mapę!",
4870
			loadmap = "<VP>%s</VP> załadował/-a mapę %s!",
4871
			settime = "Czas został ustawiony na %s minut!",
4872
			setstandtime = "Standardowy czas dla wszystkich map został ustawiony na %s minut!",
4873
			enabled = "włączony! Kliknij <B>E</B>, aby ustawić checkpoint i <B>Shift+E</B>, aby go usunąć.",
4874
			queuecleared = "%s just cleared the map queue",
4875
			queuemapadded = "%s just added the map %s to the map queue",
4876
			queueperm = "%s just added the category %s to the map queue",
4877
			queuereset = "%s just reseted the queue to the main maps",
4878
			
4879
			disabled = "wyłączony!",
4880
		},
4881
	},
4882
	langue = "en",
4883
	-- Data
4884
	info = {},
4885
	-- Maps
4886
	maps = {},
4887
	map = function()
4888
		mode.bootcampP.maps = {6501305,6118143,2604997,2836937,6921682,3339586,5776126,5678468,6531399,5847160,5745650,7091808,7000003,6999993,4559999,4784241,3883780,4976520,4854044,6374076,3636206,6793803,4499335,4694197,5485847,6258690,3938895,1719709,4209243,6550335,5994088,3866650,3999455,4095418,4523127,1964971,1554670,4423047,764650,5562230,4883346,2978216,1947288,7025830,7108857,4766627,5888889,6782978,5699275,6422459,2634659,4808290,3620953,2973289,2604643,6591698,7134487,7054821,6900009,7159725,3737744,6933187,6864581,4701337,6631702,6761156,4212122,4160675,4623227,5191670,6377984,1132272,2781845,3460976,7167027,4834444,3734991,7138019,7037760,6521356,6502657,6469688,6092666,2749928,7175796,7142063,7167539,7173296,6995540,7151000,3931358,3374686,6324891,3704015,3937060,2429057,7192029,7192034,7192689}
4889
	end,
4890
	-- New Game Settings
4891
	groundsData = {},
4892
	mapData = {},
4893
	standardTime = 6,
4894
	checkpoint = false,
4895
	-- Settings
4896
	respawnCheese = false,
4897
	-- Leaderboard
4898
	rank = function(players,fromValue,showPos,showPoints,pointsName,lim)
4899
		local p,rank = {},""
4900
		fromValue,lim = fromValue or {tfm.get.room.playerList,"score"},tonumber(lim) or 100
4901
		for n in next,players do
4902
			p[#p+1] = {name=n,v=fromValue[1][n][fromValue[2]]}
4903
		end
4904
		tablesort(p,function(f,s) return f.v>s.v end)
4905
		for o,n in next,p do
4906
			if o <= lim then
4907
				rank = rank .. (showPos and "<J>"..o..". " or "") .. "<V>" .. n.name .. (showPoints and " <BL>- <VP>" .. n.v .. " "..(pointsName or "points") .."\n" or "\n")
4908
			end
4909
		end
4910
		return rank
4911
	end,
4912
	-- Init
4913
	reset = function()
4914
		-- Data
4915
		mode.bootcampP.info = {}
4916
	end,
4917
	init = function()
4918
		-- Translations
4919
		mode.bootcampP.translations.pt = mode.bootcampP.translations.br
4920
		mode.bootcampP.langue = mode.bootcampP.translations[tfm.get.room.community] and tfm.get.room.community or "en"
4921
		
4922
		-- Settings
4923
		mode.bootcampP.respawnCheese = system.miscAttrib == 1
4924
		
4925
		-- Init
4926
		for _,f in next,{"AutoShaman","AutoScore","AutoTimeLeft","AutoNewGame","PhysicalConsumables","AfkDeath"} do
4927
			tfm.exec["disable"..f]()
4928
		end
4929
		tfm.exec.setAutoMapFlipMode(false)
4930
4931
		mode.bootcampP.map()
4932
		tfm.exec.newGame(tablerandom(mode.bootcampP.maps))
4933
		
4934
		-- Auto Admin
4935
		system.roomAdmins.Mquk = true
4936
	end,
4937
	-- New Game
4938
	eventNewGame = function()
4939
		tfm.exec.setGameTime(mode.bootcampP.standardTime * 60)
4940
		mode.bootcampP.groundsData = {}
4941
		mode.bootcampP.mapData = {}
4942
		for k,v in next,mode.bootcampP.info do
4943
			v.cheese = false
4944
			v.checkpoint = {false,0,0,false}
4945
			ui.removeTextArea(1,n)
4946
		end
4947
		
4948
		local xml = tfm.get.room.xmlMapInfo.xml
4949
		if xml then
4950
			local grounds = stringmatch(xml,"<S>(.-)</S>")
4951
			local properties = stringmatch(xml,"<C><P (.-)/>.*<Z>")
4952
			if properties then
4953
				mode.bootcampP.mapData = {
4954
					width = stringmatch(properties,'L="(%d+)"') or 800,
4955
					heigth = stringmatch(properties,'H="(%d+)"') or 400,
4956
				}
4957
			else
4958
				mode.bootcampP.mapData = {
4959
					width = 800,
4960
					heigth = 400,
4961
				}
4962
			end
4963
4964
			local data = {}
4965
			stringgsub(grounds,"<S (.-)/>",function(attributes)
4966
				data[#data + 1] = attributes
4967
			end)
4968
			for i = 1,#data do
4969
				mode.bootcampP.groundsData[i] = {}
4970
				
4971
				local type = stringmatch(data[i],'T="(%d+)"')
4972
				mode.bootcampP.groundsData[i].type = type and tonumber(type) or -1
4973
4974
				local x = stringmatch(data[i],'X="(%d+)"')
4975
				mode.bootcampP.groundsData[i].x = x and tonumber(x) or 0
4976
4977
				local y = stringmatch(data[i],'Y="(%d+)"')
4978
				mode.bootcampP.groundsData[i].y = y and tonumber(y) or 0
4979
4980
				local width = stringmatch(data[i],'L="(%d+)"')
4981
				mode.bootcampP.groundsData[i].width = width and tonumber(width) or 0
4982
4983
				local heigth = stringmatch(data[i],'H="(%d+)"')
4984
				mode.bootcampP.groundsData[i].heigth = heigth and tonumber(heigth) or 0
4985
4986
				local info = stringmatch(data[i],'P="(.*)"')
4987
				info = stringsplit(info,"[^,]+")
4988
4989
				mode.bootcampP.groundsData[i].friction = info[3] and tonumber(info[3]) or .3
4990
				mode.bootcampP.groundsData[i].restitution = info[3] and tonumber(info[4]) or .2
4991
				mode.bootcampP.groundsData[i].angle = info[3] and tonumber(info[5]) or 0
4992
			end
4993
		end
4994
	end,
4995
	-- New Player
4996
	eventNewPlayer = function(n)
4997
		if not mode.bootcampP.info[n] then
4998
			mode.bootcampP.info[n] = {
4999
				shift = false,
5000
				checkpoint = {false,0,0,false},
5001
				cheese = false,
5002
			}
5003
		end
5004
		
5005
		system.bindMouse(n,true)
5006
		for i = 1,2 do
5007
			system.bindKeyboard(n,16,i==1,true)
5008
			system.bindKeyboard(n,stringbyte("K"),i==1,true)
5009
		end
5010
		
5011
		system.bindKeyboard(n,stringbyte("E"),true,true)
5012
		system.bindKeyboard(n,46,true,true) -- Delete key
5013
		tfm.exec.chatMessage("<T>" .. system.getTranslation("welcome") .. "\n\t<CEP>/w Mquk #bootcamp+ @mapCode",n)
5014
		
5015
		local id = tfm.exec.addImage("15c6ee6324d.png","&0",120,100,n)
5016
		system.newTimer(function()
5017
			tfm.exec.removeImage(id)
5018
		end,5000,false)
5019
	end,
5020
	-- Mouse
5021
	eventMouse = function(n,x,y)
5022
		if mode.bootcampP.info[n].shift then
5023
			for i = #mode.bootcampP.groundsData,1,-1 do
5024
				local g = mode.bootcampP.groundsData[i]
5025
				local rad = mathrad(g.angle)
5026
				local ax = {mathcos(rad),mathsin(rad)}
5027
5028
				local gX = g.x + ax[1] * (x - g.x) - ax[2] * (y - g.y)
5029
				local gY = g.y + ax[2] * (x - g.x) + ax[1] * (y - g.y)
5030
5031
				if (g.type == 13 and mathpythag(x,y,g.x,g.y,g.width/2) or (mathabs(gX - g.x) < g.width/2 and mathabs(gY - g.y) < g.heigth/2)) then
5032
					local properties = {"Type","ID","X","Y","Heigth","Width","Friction","Restitution","Angle"}
5033
					local info = ""
5034
5035
					for k,v in next,properties do
5036
						info = info .. stringformat("<N>%s : <V>%s\n",v,(v == "ID" and i or v == "Type" and (({[0] = "Unknown","Wood","Ice","Trampoline","Lava","Chocolate","Earth","Grass","Sand","Cloud","Water","Stone","Snow","Rectangle","Circle","Spiderweb"})[g.type + 1]) or tostring(g[stringlower(v)])))
5037
					end
5038
5039
					local mapW = tonumber(mode.bootcampP.mapData.width)
5040
					local mapH = tonumber(mode.bootcampP.mapData.heigth)
5041
					ui.addTextArea(0,info,n,(x + 150 <= mapW and x) or (x < 0 and 0) or (mapW - 150),(y + 180 <= mapH and y > 20 and y) or (y < 20 and 25) or (mapH - 180),nil,nil,nil,nil,.8,false)
5042
				end
5043
			end
5044
		else
5045
			ui.removeTextArea(0,n)
5046
		end
5047
	end,
5048
	-- Keyboard
5049
	eventKeyboard = function(n,k,d,x,y)
5050
		if k == 16 then
5051
			mode.bootcampP.info[n].shift = d
5052
		elseif k == stringbyte("E") and mode.bootcampP.checkpoint then
5053
			if mode.bootcampP.info[n].shift then
5054
				mode.bootcampP.info[n].checkpoint = {false,0,0,mode.bootcampP.info[n].checkpoint[4]}
5055
				ui.removeTextArea(1,n)
5056
			else
5057
				mode.bootcampP.info[n].checkpoint = {true,x,y,true}
5058
				ui.addTextArea(1,"",n,x-5,y-5,10,10,0x56A75A,0x56A75A,.5,true)
5059
			end
5060
		elseif k == stringbyte("K") then
5061
			if d then
5062
				ui.addTextArea(2,mode.bootcampP.rank(tfm.get.room.playerList,{tfm.get.room.playerList,"score"},true,true,"points",20),n,5,30,nil,200,nil,nil,.8,true)
5063
			else
5064
				ui.removeTextArea(2,n)
5065
			end
5066
		elseif k == 46 then
5067
			tfm.exec.killPlayer(n)
5068
		end
5069
	end,
5070
	-- Commands
5071
	eventChatCommand = function(n,c)
5072
		local p = stringsplit(c,"[^%s]+",stringlower)
5073
		if p[1] == "info" then
5074
			tfm.exec.chatMessage("<T>" .. system.getTranslation("info"),n)
5075
		else
5076
			if system.roomAdmins[n] then
5077
				if p[1] == "next" and os.time() > system.newGameTimer then
5078
					tfm.exec.newGame(tablerandom(mode.bootcampP.maps))
5079
					tfm.exec.chatMessage("<T>• " .. stringformat(system.getTranslation("skip"),n))
5080
				elseif p[1] == "again" and os.time() > system.newGameTimer then
5081
					tfm.exec.newGame(tfm.get.room.currentMap)
5082
					tfm.exec.chatMessage("<T>• " .. stringformat(system.getTranslation("restart"),n))
5083
				elseif (p[1] == "np" or p[1] == "map") and os.time() > system.newGameTimer then
5084
					tfm.exec.newGame(p[2])
5085
					tfm.exec.chatMessage("<T>• " .. stringformat(system.getTranslation("loadmap"),n,stringfind(p[2],"@") and p[2] or "@"..p[2]))
5086
				elseif p[1] == "time" then
5087
					tfm.exec.setGameTime(p[2] * 60)
5088
					tfm.exec.chatMessage(stringformat(system.getTranslation("settime"),p[2]))
5089
				elseif p[1] == "standtime" then
5090
					p[2] = p[2] and tonumber(p[2]) or 6
5091
					if p[2] > 0 and p[2] < 10 then
5092
						mode.bootcampP.standardTime = p[2]
5093
						tfm.exec.chatMessage(stringformat(system.getTranslation("setstandtime",p[2])))
5094
					end
5095
				elseif p[1] == "checkpoint" then
5096
					local attribute = false
5097
					if p[2] then
5098
						attribute = true
5099
						if p[2] == "not" and p[3] and p[3] == "cheese" then
5100
							mode.bootcampP.respawnCheese = false
5101
						elseif p[2] == "cheese" then
5102
							mode.bootcampP.respawnCheese = true
5103
						else
5104
							attribute = false
5105
						end
5106
					end
5107
					
5108
					if not (mode.bootcampP.checkpoint and attribute) then
5109
						mode.bootcampP.checkpoint = not mode.bootcampP.checkpoint
5110
						tfm.exec.chatMessage("<T>Checkpoint " .. system.getTranslation(mode.bootcampP.checkpoint and "enabled" or "disabled"))
5111
					
5112
						if not mode.bootcampP.checkpoint then
5113
							ui.removeTextArea(1,nil)
5114
							for k,v in next,mode.bootcampP.info do
5115
								v.checkpoint = {false,0,0,v.checkpoint[4]}
5116
							end
5117
							if system.miscAttrib ~= 1 then
5118
								mode.bootcampP.respawnCheese = false
5119
							end
5120
							for k,v in next,mode.bootcampP.info do
5121
								v.cheese = false
5122
							end
5123
						end
5124
					end
5125
				elseif p[1] == "queue" then
5126
					if p[2] == "clear" then
5127
						mode.bootcampP.maps = {}
5128
						tfm.exec.chatMessage("• " .. stringformat(system.getTranslation("queuecleared"),n))
5129
					elseif p[2] == "add" then
5130
						mode.bootcampP.maps[#mode.bootcampP.maps + 1] = p[3]
5131
						tfm.exec.chatMessage("• " .. stringformat(system.getTranslation("queuemapadded"),n,stringfind(p[3],"@") and p[3] or "@"..p[3]))
5132
					elseif p[2] and stringsub(p[2],1,1) == "p" then
5133
						if p[2] == "p3" or p[2] == "p13" or p[2] == "p23" then
5134
							mode.bootcampP.maps[#mode.bootcampP.maps + 1] = "#" .. stringsub(p[2],2)
5135
							tfm.exec.chatMessage("• " .. stringformat(system.getTranslation("queueperm"),n,stringupper(p[2])))
5136
						end
5137
					else
5138
						mode.bootcampP.map()
5139
						tfm.exec.chatMessage("• " .. stringformat(system.getTranslation("queuereset"),n))
5140
					end
5141
				end
5142
			end
5143
		end
5144
	end,
5145
	-- Loop
5146
	eventLoop = function()
5147
		if _G.leftTime < 1 then
5148
			tfm.exec.newGame(tablerandom(mode.bootcampP.maps))
5149
		end
5150
	end,
5151
	-- Player Died
5152
	eventPlayerDied = function(n)
5153
		system.newTimer(function()
5154
			tfm.exec.respawnPlayer(n)
5155
			
5156
			if mode.bootcampP.checkpoint and mode.bootcampP.info[n].checkpoint[1] then
5157
				tfm.exec.movePlayer(n,mode.bootcampP.info[n].checkpoint[2],mode.bootcampP.info[n].checkpoint[3])
5158
			end
5159
			if mode.bootcampP.checkpoint and mode.bootcampP.info[n].cheese and mode.bootcampP.respawnCheese then
5160
				tfm.exec.giveCheese(n)
5161
			end
5162
		end,1500,false)
5163
	end,
5164
	-- Victory
5165
	eventPlayerWon = function(n,t,time)
5166
		mode.bootcampP.info[n].cheese = false
5167
		mode.bootcampP.info[n].checkpoint = {false,0,0,mode.bootcampP.info[n].checkpoint[4]}
5168
		ui.removeTextArea(1,n)
5169
5170
		mode.bootcampP.eventPlayerDied(n)
5171
		tfm.exec.setPlayerScore(n,1,true)
5172
		tfm.exec.chatMessage(stringformat("<ROSE>%s (%ss <PT>(%scheckpoint)</PT>)",n,time/100,mode.bootcampP.info[n].checkpoint[4] and "" or "no "),n)
5173
	end,
5174
	-- Got Cheese
5175
	eventPlayerGetCheese = function(n)
5176
		if mode.bootcampP.checkpoint and mode.bootcampP.respawnCheese then
5177
			mode.bootcampP.info[n].cheese = true
5178
		end
5179
	end,
5180
}
5181
5182
--[[ Map ]]--
5183
mode.map = {
5184
	-- Translations
5185
	translations = {
5186
		en = {
5187
			-- Init
5188
			welcome = "Welcome to #map! Here you can test your maps in different categories and check its approvation in the community!\n\tAdd a map to the queue with the command <B>!maptest @Code PCategory</B> and check the map info using the command <B>!mapinfo</B>.\n\n\tReport any problem to Bolodefchoco.",
5189
5190
			-- Info
5191
			savenewmap = "Your map %s is in the position %s",
5192
			newmaptime = "Less than %s minutes",
5193
			vote = "Your vote has been recorded.",
5194
			dovote = "Hold P and vote according to your opinion about this map!",
5195
5196
			-- Map Info
5197
			mapby = "Map %s loaded by %s as %s.",
5198
5199
			-- Security
5200
			cantvote = "You cannot vote.",
5201
			
5202
			-- Simple words
5203
			grounds = "Grounds",
5204
			status = "Status",
5205
			author = "Author",
5206
		},
5207
		br = {
5208
			welcome = "Bem-vindo ao #map! Aqui você pode testar seus mapas em diferentes categorias e checar sua aprovação na comunidade!\n\tAdicione um mapa na lista de espera com o comando <B>!maptest @Código PCategoria</B> e cheque as informações do mapa usando o comando <B>!mapinfo</B>.\n\n\tReporte qualquer problema para Bolodefchoco.",
5209
5210
			savenewmap = "Seu mapa %s está na posição %s",
5211
			newmaptime = "Menos de %s minutos",
5212
			vote = "Seu voto foi registrado.",
5213
			dovote = "Segure P e vote de acordo com sua opinião sobre este mapa!",
5214
5215
			mapby = "Mapa %s carregado por %s como %s.",
5216
5217
			cantvote = "Vote não pode votar.",
5218
			
5219
			grounds = "Pisos",
5220
			status = "Estado",
5221
			author = "Autor",
5222
		}
5223
	},
5224
	langue = "en",
5225
	-- Data
5226
	info = {},
5227
	-- Maps
5228
	queue = {},
5229
	-- Map Settings
5230
	autoRespawn = false,
5231
	category = -1,
5232
	mapInfo = {},
5233
	canInfo = false,
5234
	totalPlayers = 0,
5235
	skip = false,
5236
	images = {},
5237
	-- Next Map
5238
	nextMap = function()
5239
		if os.time() > system.newGameTimer and #mode.map.queue > 0 then
5240
			local mapData = mode.map.queue[1]
5241
5242
			mode.map.mapInfo = {mapData[1],mapData[2],0,0}
5243
			mode.map.category = mapData[3]
5244
5245
			mode.map.before()		
5246
			tfm.exec.newGame(mapData[1])
5247
		end
5248
	end,
5249
	-- Category rules
5250
	before = function()
5251
		if mode.map.category >= 0 then
5252
			if tablefind({0,1,4,5,6,8,9},mode.map.category) then
5253
				tfm.exec.disableAutoShaman(false)
5254
				tfm.exec.disableAfkDeath(false)
5255
				mode.map.autoRespawn = false
5256
			elseif tablefind({3,7,17},mode.map.category) then
5257
				tfm.exec.disableAutoShaman()
5258
				if mode.map.category == 3 then
5259
					mode.map.autoRespawn = true
5260
					tfm.exec.disableAfkDeath()
5261
				end
5262
			end
5263
		end
5264
	end,
5265
	after = function()
5266
		if mode.map.category >= 0 then
5267
			if tablefind({0,1,4,5,6,8,9},mode.map.category) then
5268
				tfm.exec.setGameTime(135)
5269
				if mode.map.category == 8 and mode.map.totalPlayers > 1 then
5270
					local newShaman
5271
					repeat
5272
						newShaman = tablerandom(system.players(true))
5273
					until not tfm.get.room.playerList[newShaman].isShaman
5274
5275
					ui.setShamanName((function()
5276
						for k,v in next,tfm.get.room.playerList do
5277
							if v.isShaman then
5278
								return k
5279
							end
5280
						end
5281
						return "?"
5282
					end)() .. " - <PS>" .. newShaman)
5283
					tfm.exec.setShaman(newShaman)
5284
5285
					local xml = tfm.get.room.xmlMapInfo.xml
5286
					local attribute = stringmatch(xml,"<DC2 (.-)/>")
5287
					if attribute then
5288
						local x = stringmatch(attribute,"X=\"(%d+)\"")
5289
						local y = stringmatch(attribute,"Y=\"(%d+)\"")
5290
						if x and y then
5291
							tfm.exec.movePlayer(newShaman,x,y)
5292
						end
5293
					end
5294
5295
					tfm.exec.setNameColor(newShaman,0xF1C4F6)
5296
				end
5297
			elseif mode.map.category == 3 then
5298
				tfm.exec.setGameTime(360)
5299
			elseif mode.map.category == 7 then
5300
				tfm.exec.setGameTime(120)
5301
			elseif mode.map.category == 17 then
5302
				tfm.exec.setGameTime(63)
5303
			end
5304
		end
5305
	end,
5306
	-- Init
5307
	init = function()
5308
		mode.map.translations.pt = mode.map.translations.br
5309
		mode.map.langue = mode.map.translations[tfm.get.room.community] and tfm.get.room.community or "en"
5310
5311
		tfm.exec.disableAutoNewGame()
5312
		tfm.exec.setGameTime(10,false)
5313
		
5314
		local alive
5315
		alive,mode.map.totalPlayers = system.players()
5316
	end,
5317
	-- New Player
5318
	eventNewPlayer = function(n)
5319
		if not mode.map.info[n] then
5320
			mode.map.info[n] = {
5321
				hasVoted = false
5322
			}
5323
		end
5324
5325
		for i = 1,2 do
5326
			system.bindKeyboard(n,stringbyte("P"),i == 1,true)
5327
		end
5328
5329
		tfm.exec.chatMessage("<J>" .. system.getTranslation("welcome"),n)
5330
	end,
5331
	-- New Game
5332
	eventNewGame = function()
5333
		ui.removeTextArea(2,nil)
5334
		mode.map.skip = false
5335
		if mode.map.mapInfo[1] then
5336
			mode.map.canInfo = true
5337
			
5338
			mode.map.after()
5339
			mode.map.after = function() end
5340
			tableremove(mode.map.queue,1)
5341
5342
			for k,v in next,mode.map.info do
5343
				v.hasVoted = false
5344
			end
5345
			
5346
			for k,v in next,mode.map.images do
5347
				tfm.exec.removeImage(v)
5348
			end
5349
			
5350
			xml.attribFunc(tfm.get.room.xmlMapInfo.xml,{
5351
				[1] = {
5352
					attribute = "img",
5353
					func = function(value)
5354
						local images = stringsplit(value,"[^;]+")
5355
						for k,v in next,images do
5356
							local info = stringsplit(v,"[^,]+")
5357
							
5358
							-- "img.png,x or 0,y or 0,0/1 (foreground)"
5359
							info[4] = tonumber(info[4]) or 0
5360
							if tablefind({0,1},info[4]) then
5361
								mode.map.images[#mode.map.images + 1] = tfm.exec.addImage(info[1],(info[4] == 0 and "?" or info[4] == 1 and "&") .. k,tonumber(info[2]) or 5,tonumber(info[3]) or 30)
5362
							end
5363
						end
5364
					end
5365
				}
5366
			})
5367
5368
			tfm.exec.chatMessage("<J>" .. stringformat(system.getTranslation("mapby"),"@" .. mode.map.mapInfo[1],mode.map.mapInfo[2],"P" .. mode.map.category))
5369
			tfm.exec.chatMessage("<J>" .. system.getTranslation("dovote"))
5370
		end
5371
	end,
5372
	-- Commands
5373
	eventChatCommand = function(n,c)
5374
		local p = stringsplit(c,"[^%s]+",stringlower)
5375
		if system.isPlayer(n) and p[1] == "maptest" and p[2] then
5376
			p[2] = tonumber(stringsub(p[2],(stringfind(p[2],"@") and 2 or 1),8))
5377
			if p[2] and #tostring(p[2]) > 3 then
5378
				if #mode.map.mapInfo == 0 then
5379
					tfm.exec.setGameTime(10,false)
5380
				end
5381
5382
				local pos = #mode.map.queue + 1
5383
				local category = (p[3] and tonumber(stringsub(p[3],(stringfind(p[3],"p") and 2 or 1))) or 0)
5384
				if tablefind({0,1,3,4,5,6,7,8,9,17,18},category) then
5385
					if category == 18 then
5386
						category = 1
5387
					end
5388
				else
5389
					category = 0
5390
				end
5391
5392
				mode.map.queue[pos] = {p[2],n,category}
5393
				tfm.exec.chatMessage("<J><B>" .. stringformat(system.getTranslation("savenewmap"),stringformat("@%s (P%s)",p[2],category),"#" .. pos) .. "</B>. <ROSE>" .. stringformat("(%s)",stringformat(system.getTranslation("newmaptime"),pos * 2.5)),n)
5394
			end
5395
		elseif mode.map.mapInfo[1] and p[1] == "mapinfo" then
5396
			local xml = tfm.get.room.xmlMapInfo
5397
			xml = xml and xml.xml or "?"
5398
			
5399
			local attributes = stringmatch(xml,"<P (.-)/>") or "?"
5400
			
5401
			local totalGrounds = (function()
5402
				local g = stringmatch(xml,"<S>(.-)</S>") or "?"
5403
5404
				local total = 0
5405
				stringgsub(g,"<S ",function()
5406
					total = total + 1		
5407
				end)
5408
5409
				return total
5410
			end)()
5411
			
5412
			local info = {attributes,system.getTranslation("grounds") .. ": " .. totalGrounds,system.getTranslation("author") .. ": " .. (tfm.get.room.xmlMapInfo.author or "?"),system.getTranslation("status") .. ": " .. ("P" .. tfm.get.room.xmlMapInfo.permCode or "?")}
5413
			ui.addTextArea(2,"\t<J>" .. tableconcat(info,"   <G>|<J>   "),n,5,380,790,20,1,1,.7,true)
5414
		elseif n == mode.map.mapInfo[2] and p[1] == "time" then
5415
			tfm.exec.setGameTime(tonumber(stringsub(p[2],1,3)) or 60,false)
5416
		elseif n == mode.map.mapInfo[2] and p[1] == "skip" then
5417
			if os.time() > system.newGameTimer then
5418
				mode.map.skip = true
5419
				mode.map.mapInfo = {}
5420
			end
5421
		end
5422
	end,
5423
	eventKeyboard = function(n,k,d)
5424
		if k == stringbyte("P") and _G.currentTime > 5 and #mode.map.mapInfo > 0 then
5425
			if d and not mode.map.info[n].hasVoted then
5426
				if n == mode.map.mapInfo[2] or not system.isPlayer(n) then
5427
					tfm.exec.chatMessage("<R>" .. system.getTranslation("cantvote"),n)
5428
				else
5429
					local ic = {{"+","VP"},{"-","R"}}
5430
					for i = 0,1 do
5431
						ui.addTextArea(i,"<p align='center'><font size='6'>\n<font size='17'><" .. ic[i+1][2] .. "><a href='event:" .. ic[i+1][1] .. "'><B>" .. ic[i+1][1] .. "1",n,5 + i * 50,30,40,40,1,1,.7,true)
5432
					end
5433
				end
5434
			else
5435
				for i = 0,1 do
5436
					ui.removeTextArea(i,n)
5437
				end
5438
			end
5439
		end
5440
	end,
5441
	-- Callbacks
5442
	eventTextAreaCallback = function(i,n,c)
5443
		mode.map.info[n].hasVoted = true
5444
		if c == "+" then
5445
			mode.map.mapInfo[3] = mode.map.mapInfo[3] + 1
5446
		elseif c == "-" then
5447
			mode.map.mapInfo[4] = mode.map.mapInfo[4] + 1
5448
		end
5449
		mode.map.eventKeyboard(n,stringbyte("P"),false)
5450
5451
		tfm.exec.chatMessage("• " .. system.getTranslation("vote"),n)
5452
	end,
5453
	-- Loop
5454
	eventLoop = function()
5455
		local alive = 100
5456
		if _G.currentTime % 5 == 0 then
5457
			alive,mode.map.totalPlayers = system.players()
5458
		end
5459
		if _G.leftTime < 1 or alive < 1 or mode.map.skip then
5460
			if mode.map.mapInfo[1] and mode.map.canInfo then
5461
				mode.map.canInfo = false
5462
				
5463
				local totalVotes = mode.map.mapInfo[3] + mode.map.mapInfo[4]
5464
				if totalVotes > 0 then
5465
					tfm.exec.chatMessage(stringformat("• [@%s] %s%% (%s)",mode.map.mapInfo[1],mathpercent(mode.map.mapInfo[3],totalVotes),totalVotes),mode.map.mapInfo[2])
5466
				end
5467
			end
5468
5469
			if #mode.map.queue > 0 then
5470
				mode.map.nextMap()
5471
			else
5472
				tfm.exec.newGame()
5473
			end
5474
		end
5475
	end,
5476
	-- Player Died
5477
	eventPlayerDied = function(n)
5478
		if mode.map.autoRespawn then
5479
			tfm.exec.respawnPlayer(n)
5480
		end
5481
	end,
5482
	-- Player Won
5483
	eventPlayerWon = function(n)
5484
		mode.map.eventPlayerDied(n)
5485
	end,
5486
}
5487
5488
--[[ Godmode ]]--
5489
mode.godmode = {
5490
	-- Translations
5491
	translations = {
5492
		en = {
5493
			-- Init
5494
			welcome = "Welcome to <B>#godmode</B>. Type !info to read the help message.\n\tReport any issue to Bolodefchoco.",
5495
5496
			-- Guide
5497
			shaman = "Hello shaman! Try to build without nails! Good luck.",
5498
5499
			-- Info
5500
			info = "Use your creativity and build WITHOUT nails in shaman maps! The more mice you save, the higher your score will be. Do not let the mice die.\nPress P or type !p [playername] to open a profile.",
5501
			xp = "You've saved %s mice and %s died.",
5502
5503
			-- Warning
5504
			nail = "You can use %s more nails. After that, you will die.",
5505
			kill = "Try not to use nails in your buildings.",
5506
			fail = "You failed!",
5507
			
5508
			-- Profile
5509
			profile = "Title : <V>«%s»<N>\n\nRounds : %s\n<N>Shaman : %s <G>/ %s\n\n<N>Deaths : %s",
5510
			
5511
			-- Titles
5512
			titles = {
5513
				"Shammy",
5514
				"Experienced Shaman",
5515
				"Evil Shaman",
5516
				"Angry Shaman",
5517
				"Spirit",
5518
				"Haunted Shaman",
5519
				"Troll Shaman",
5520
				"Scientist",
5521
				"Physics Master",
5522
				"Black Magic",
5523
			},
5524
			unlock = "%s just unlocked «%s»",
5525
		},
5526
		br = {
5527
			welcome = "Bem-vindo ao <B>#godmode</B>. Digite !info para ler a mensagem de ajuda.\n\tReporte qualquer problema para Bolodefchoco.",
5528
5529
			shaman = "Olá shaman! Tente construir sem pregos! Boa sorte.",
5530
5531
			info = "Utilize sua criatividade e construa em mapas shaman SEM pregos! Quanto mais ratos você salvar, maior será sua pontuação. Não deixe nenhum rato morrer.\nPressione P ou digite !p [nome] para abrir um perfil.",
5532
			xp = "Você salvou %s ratos e %s morreram.",
5533
5534
			nail = "Você pode usar mais %s pregos. Depois disso, você morrerá.",
5535
			kill = "Tente não usar pregos em suas construções.",
5536
			fail = "Você falhou!",
5537
5538
			profile = "Título : <V>«%s»<N>\n\nPartidas : %s\n<N>Shaman : %s <G>/ %s\n\n<N>Mortes : %s",
5539
			
5540
			titles = {
5541
				"Pequeno Shaman",
5542
				"Shaman Profissional",
5543
				"Shaman Mau",
5544
				"Shaman Bravo",
5545
				"Espírito",
5546
				"Shaman Assombado",
5547
				"Shaman Troll",
5548
				"Cientista",
5549
				"Mestre da Física",
5550
				"Magia Negra",
5551
			},
5552
			unlock = "%s acabou de desbloquear «%s»",
5553
		},
5554
	},
5555
	langue = "en",
5556
	-- Data
5557
	info = {},
5558
	-- Shaman
5559
	getShaman = function()
5560
		local s = {}
5561
		for k,v in next,tfm.get.room.playerList do
5562
			if v.isShaman then
5563
				s[#s + 1] = k
5564
			end
5565
		end
5566
5567
		return s
5568
	end,
5569
	-- New Game Settings
5570
	savedMice = 0,
5571
	deadMice = 0,
5572
	lastShaman = {},
5573
	-- Other Settings
5574
	title = nil,
5575
	titles = {0,10,20,30,40,50,60,70,80,90},
5576
	-- Profile
5577
	profile = function(n,p)
5578
		ui.addTextArea(0,"<p align='center'><B><R><a href='event:profile.close'>X",n,513,115,20,20,1,1,1,true)
5579
		ui.addTextArea(1,"<p align='center'><font size='16'><B><V>"..p.."</V></B></font></p><p align='left'><font size='12'>\n<N>" .. stringformat(system.getTranslation("profile"),mode.godmode.info[p].title,"<V>"..mode.godmode.info[p].roundSha,"<J>"..mode.godmode.info[p].cheeseMice,"<R>"..mode.godmode.info[p].deathMice,"<V>"..mode.godmode.info[p].deathSha),n,290,115,220,160,1,1,1,true)
5580
	end,
5581
	-- Update Menu Bar
5582
	updateMenu = function()
5583
		ui.setShamanName(tableconcat(mode.godmode.getShaman()," - <PS>") .. "   <G>|   <N>Status : <J>" .. mode.godmode.savedMice .. " <BL>/ <R>" ..  mode.godmode.deadMice)
5584
	end,
5585
	-- Init
5586
	reset = function()
5587
		-- Data
5588
		mode.godmode.info = {}
5589
	end,
5590
	init = function()
5591
		-- Translations
5592
		mode.godmode.translations.pt = mode.godmode.translations.br
5593
		mode.godmode.langue = mode.godmode.translations[tfm.get.room.community] and tfm.get.room.community or "en"
5594
5595
		-- Titles
5596
		mode.godmode.title = system.getTranslation("titles")
5597
		
5598
		-- Init
5599
		tfm.exec.disableAutoNewGame()
5600
		tfm.exec.disableAllShamanSkills()
5601
		tfm.exec.newGame("#4")
5602
		
5603
		-- Auto Admin
5604
		system.roomAdmins.Mcqv = true
5605
	end,
5606
	-- New Player
5607
	eventNewPlayer = function(n)
5608
		if not mode.godmode.info[n] then
5609
			mode.godmode.info[n] = {
5610
				usedNails = 0,
5611
				roundSha = 0,
5612
				deathSha = 0,
5613
				deathMice = 0,
5614
				cheeseMice = 0,
5615
				title = "Shammy",
5616
			}
5617
		end
5618
5619
		for k,v in next,{66,67,74,78,80,86} do
5620
			system.bindKeyboard(n,v,true,true)
5621
		end
5622
5623
		tfm.exec.chatMessage("<ROSE>" .. system.getTranslation("welcome"),n)
5624
		
5625
		local id = tfm.exec.addImage("15ca3f4a200.png","&0",5,150,n)
5626
		system.newTimer(function()
5627
			tfm.exec.removeImage(id)
5628
		end,10000,false)
5629
	end,
5630
	-- New Game
5631
	eventNewGame = function()
5632
		if #mode.godmode.lastShaman > 0 then
5633
			for k,v in next,mode.godmode.lastShaman do
5634
				mode.godmode.info[v].cheeseMice = mode.godmode.info[v].cheeseMice + mode.godmode.savedMice
5635
				mode.godmode.info[v].deathMice = mode.godmode.info[v].deathMice + mode.godmode.deadMice
5636
				tfm.exec.chatMessage("<CH>" .. stringformat(system.getTranslation("xp"),mode.godmode.savedMice,mode.godmode.deadMice),v)
5637
				
5638
				
5639
				for i = #mode.godmode.titles,1,-1 do
5640
					if mode.godmode.info[v].cheeseMice >= mode.godmode.titles[i] then
5641
						if mode.godmode.info[v].title ~= mode.godmode.title[i] then
5642
							mode.godmode.info[v].title = mode.godmode.title[i]
5643
							tfm.exec.chatMessage("<J>" .. stringformat(system.getTranslation("unlock"),v,mode.godmode.title[i]))
5644
						end
5645
						break	
5646
					end
5647
				end
5648
			end
5649
		end
5650
		
5651
		mode.godmode.savedMice = 0
5652
		mode.godmode.deadMice = 0
5653
		
5654
		mode.godmode.updateMenu()
5655
5656
		for k,v in next,mode.godmode.info do
5657
			v.usedNails = 0
5658
		end
5659
		for k,v in next,mode.godmode.getShaman() do
5660
			mode.godmode.info[v].roundSha = mode.godmode.info[v].roundSha + 1
5661
			tfm.exec.chatMessage("<CH>" .. system.getTranslation("shaman"),v)
5662
		end
5663
		
5664
		tfm.exec.setGameTime(183)
5665
	end,
5666
	-- Keyboard
5667
	eventKeyboard = function(n,k)
5668
		if k == 80 then
5669
			mode.godmode.profile(n,n)
5670
		elseif not tfm.get.room.playerList[n].isDead and tfm.get.room.playerList[n].isShaman then
5671
			if tablefind({66,67,74,78,86},k) then -- B;C;V;N;J
5672
				mode.godmode.info[n].usedNails = mode.godmode.info[n].usedNails + 1
5673
				if mode.godmode.info[n].usedNails > 4 then
5674
					tfm.exec.killPlayer(n)
5675
					tfm.exec.chatMessage("<R>" .. system.getTranslation("fail") .. " " .. system.getTranslation("kill"),n)
5676
				else
5677
					tfm.exec.chatMessage("<R>" .. stringformat(system.getTranslation("nail"),5 - mode.godmode.info[n].usedNails),n)
5678
				end
5679
			end
5680
		end
5681
	end,
5682
	-- Summoned
5683
	eventSummoningEnd = function(n,o,x,y,a,i)
5684
		tfm.exec.removeObject(i.id)
5685
		
5686
		tfm.exec.addShamanObject(o,x,y,a,i.vx,i.vy,i.ghost)
5687
	end,
5688
	-- Loop
5689
	eventLoop = function()
5690
		local alive,total = system.players()
5691
		if _G.leftTime < 2 or (total > 1 and alive < 2) or alive == 0 then
5692
			mode.godmode.lastShaman = mode.godmode.getShaman()
5693
			tfm.exec.newGame("#4")
5694
		end
5695
	end,
5696
	-- Player Died
5697
	eventPlayerDied = function(n)
5698
		if tfm.get.room.playerList[n].isShaman then
5699
			tfm.exec.setGameTime(10,false)
5700
			mode.godmode.info[n].deathSha = mode.godmode.info[n].deathSha + 1
5701
			tfm.exec.chatMessage("<R>" .. system.getTranslation("fail"),n)
5702
		else
5703
			mode.godmode.deadMice = mode.godmode.deadMice + 1
5704
			mode.godmode.updateMenu()
5705
		end
5706
	end,
5707
	-- Player Won
5708
	eventPlayerWon = function(n)
5709
		if not tfm.get.room.playerList[n].isShaman then
5710
			mode.godmode.savedMice = mode.godmode.savedMice + 1
5711
			mode.godmode.updateMenu()
5712
		end
5713
	end,
5714
	-- Commands
5715
	eventChatCommand = function(n,c)
5716
		local p = stringsplit(c,"[^%s]+",stringlower)
5717
		if p[1] == "info" then
5718
			tfm.exec.chatMessage("<J>" .. system.getTranslation("info"),n)
5719
		elseif p[1] == "p" then
5720
			if p[2] then
5721
				p[2] = stringnick(p[2])
5722
				if mode.godmode.info[p[2]] then
5723
					mode.godmode.profile(n,p[2])
5724
				end
5725
			else
5726
				mode.godmode.profile(n,n)
5727
			end
5728
		end
5729
	end,
5730
	-- Callback
5731
	eventTextAreaCallback = function(i,n,c)
5732
		local p = stringsplit(c,"[^%.]+")
5733
		if p[1] == "profile" then
5734
			if p[2] == "close" then
5735
				for i = 0,1 do
5736
					ui.removeTextArea(i,n)
5737
				end
5738
			end
5739
		end
5740
	end,
5741
}
5742
5743
--[[ Sharpie ]]--
5744
mode.sharpie = {
5745
	-- Translations
5746
	translations = {
5747
		en = {
5748
			-- Init
5749
			welcome = "Welcome to #sharpie! Fly pressing space.",
5750
5751
			-- Warning
5752
			nothacker = "The mice flying are NOT hackers!",
5753
5754
			-- Sample words
5755
			won = "won",
5756
			
5757
			-- Messages
5758
			first = {
5759
				"yay 2 in a row",
5760
				"super pro",
5761
				"oml are you playing alone or what",
5762
				"wooow 4 in a row!",
5763
				"getting hard? good luck pro!",
5764
				"you noob just unlocked the title lightning",
5765
				"woah speedmaster",
5766
				"formula 1",
5767
				"time traveler you sir",
5768
				"queen of the win",
5769
				"as pro as the developer",
5770
				"ILLUMINATI!",
5771
				"are you a real hacker?",
5772
				"I hope you dont loose the chance of seeing the last message",
5773
				"THIS IS A SHIT MESSAGE BECAUSE YOU DIDNT DESERVE IT",
5774
			},
5775
			hardMode = "The hard mode is activated this round!",
5776
		},
5777
		br = {
5778
			welcome = "Bem-vindo ao #sharpie! Voe apertando espaço.",
5779
5780
			nothacker = "Os ratos voando NÃO são hackers!",
5781
5782
			won = "venceu",
5783
5784
			first = {
5785
				"yay 2 seguidas",
5786
				"super pro",
5787
				"omg você tá jogando sozinho ou o que",
5788
				"etaaa 4 seguidas!",
5789
				"ficando difícil? boa sorte mito!",
5790
				"vc noob acaba de desbloquear o título relâmpago",
5791
				"vuash mestre da corrida",
5792
				"relâmpago marquinhos",
5793
				"viajante do tempo vc senhor",
5794
				"rainha da vitória",
5795
				"tão pro quanto o criador do jogo",
5796
				"ILLUMINATI!",
5797
				"éres um hacker de verdade?",
5798
				"Espero que você não perca a chance de ler a última mensagem",
5799
				"ESSA É UMA MENSAGEM DE MERDA PQ VC N MERECEU ISSO",
5800
			},
5801
			hardMode = "O modo difícil está ativado nessa partida!",
5802
		},
5803
	},
5804
	langue = "en",
5805
	-- New Game Settings
5806
	flyPower = -50,
5807
	firstRow = {"",0}, -- Player, amount
5808
	podium = 0,
5809
	totalPlayers = 0,
5810
	hardmode = false,
5811
	modeImages = {"15cbdb3c427","15cbdb479ca","15cbdb4a1ca","15cbdb4cae5"},
5812
	mapInfo = {800,400},
5813
	-- Not Hacker Message
5814
	uiborder = function(t,x,y)
5815
		local colors = {
5816
			{"#F7F918","#EC4848"},
5817
			{"#4CE7F7","#2C9F5B"},
5818
			{"#4BD9CD","#2A64E9"},
5819
			{"#D4F31A","#8C8fA4"},
5820
		}
5821
		local color = tablerandom(colors)
5822
5823
		ui.addTextArea(0,"<font color='" .. color[2] .. "'><B>"..t,nil,x,y-1,900,25,1,1,0,true)
5824
		ui.addTextArea(1,"<font color='" .. color[2] .. "'><B>"..t,nil,x,y+1,900,25,1,1,0,true)
5825
		ui.addTextArea(2,"<font color='" .. color[2] .. "'><B>"..t,nil,x+1,y,900,25,1,1,0,true)
5826
		ui.addTextArea(3,"<font color='" .. color[2] .. "'><B>"..t,nil,x-1,y,900,25,1,1,0,true)
5827
		ui.addTextArea(4,"<font color='" .. color[1] .. "'><B>"..t,nil,x,y,900,25,1,1,0,true)
5828
	end,
5829
	-- Init
5830
	init = function()
5831
		-- Init
5832
		tfm.exec.disableAutoShaman()
5833
		tfm.exec.disableAutoScore()
5834
		
5835
		tfm.exec.newGame()
5836
	end,
5837
	-- New Game
5838
	eventNewGame = function()
5839
		mode.sharpie.podium = 0
5840
		
5841
		local currentXml = tfm.get.room.xmlMapInfo
5842
		currentXml = currentXml and currentXml.xml or ""
5843
		
5844
		mode.sharpie.mapInfo = {800,400}
5845
		mode.sharpie.flyPower = -50
5846
		
5847
		xml.attribFunc(currentXml or "",{
5848
			[1] = {
5849
				attribute = "G",
5850
				func = function(value)
5851
					value = stringsplit(value,"[^,]+")
5852
					value = tonumber(value[2]) or value
5853
					mode.sharpie.flyPower = value < 0 and 50 or -50
5854
				end
5855
			},
5856
			[2] = {
5857
				attribute = "L",
5858
				func = function(value)
5859
					value = tonumber(value)
5860
					if value then
5861
						mode.sharpie.mapInfo[1] = value
5862
					end
5863
				end
5864
			},
5865
			[3] = {
5866
				attribute = "H",
5867
				func = function(value)
5868
					value = tonumber(value)
5869
					if value then
5870
						mode.sharpie.mapInfo[2] = value
5871
					end
5872
				end
5873
			},
5874
			
5875
		})
5876
		
5877
		mode.sharpie.hardmode = mathrandom(10) == 6
5878
		if mode.sharpie.hardmode then
5879
			tfm.exec.chatMessage("<CH>" .. system.getTranslation("hardMode"))
5880
		end
5881
	end,
5882
	-- New Player
5883
	eventNewPlayer = function(n)
5884
		tfm.exec.chatMessage("<CE>" .. system.getTranslation("welcome"),n)
5885
5886
		system.bindKeyboard(n,32,true,true)
5887
	end,
5888
	-- Keyboard
5889
	eventKeyboard = function(n,k,d,x,y)
5890
		if k == 32 then
5891
			
5892
			tfm.exec.movePlayer(n,0,0,true,0,mode.sharpie.flyPower,true)
5893
		end
5894
	end,
5895
	-- Victory
5896
	eventPlayerWon = function(n)
5897
		mode.sharpie.podium = mode.sharpie.podium + 1
5898
		if mode.sharpie.podium == 1 then
5899
			if mode.sharpie.firstRow[1] == n then
5900
				mode.sharpie.firstRow[2] = mode.sharpie.firstRow[2] + 1
5901
				
5902
				if mode.sharpie.totalPlayers > 3 then
5903
					local msg = system.getTranslation("first")
5904
					tfm.exec.chatMessage("<G># <ROSE>" .. (msg[mode.sharpie.firstRow[2] - 1] or tablerandom({msg[2],msg[3],msg[6],msg[13],msg[15]})),n)
5905
				end
5906
			else
5907
				mode.sharpie.firstRow = {n,1}
5908
			end
5909
5910
			tfm.exec.setPlayerScore(n,(mode.sharpie.firstRow[2]+1) * 5,true)
5911
5912
			tfm.exec.chatMessage(stringformat("<J>%s %s! %s",n,system.getTranslation("won"),mode.sharpie.firstRow[2] > 1 and "("..mode.sharpie.firstRow[2]..")" or ""))
5913
		else
5914
			tfm.exec.setPlayerScore(n,5,true)
5915
		end
5916
	end,
5917
	-- Loop
5918
	eventLoop = function()
5919
		if _G.currentTime % 5 == 0 then
5920
			local alive,total = system.players()
5921
			mode.sharpie.totalPlayers = total
5922
			
5923
			-- Warning
5924
			mode.sharpie.uiborder(system.getTranslation("nothacker"),10,382)
5925
		end
5926
5927
		if mode.sharpie.hardmode and _G.currentTime % 14 == 0 then
5928
			system.newTimer(function()
5929
				local x,y = mathrandom(0,mode.sharpie.mapInfo[1]),mathrandom(0,mode.sharpie.mapInfo[2])
5930
				local id = tfm.exec.addImage(tablerandom(mode.sharpie.modeImages) .. ".png","&0",x - 56,y - 51) -- 112x103 img
5931
				system.newTimer(function()
5932
					tfm.exec.removeImage(id)
5933
5934
					tfm.exec.displayParticle(24,x,y)
5935
					tfm.exec.explosion(x,y,50,100)
5936
				end,1250,false)
5937
			end,1000,false)
5938
		end
5939
	end,
5940
}
5941
5942
--[[ Non-official Events ]]--
5943
system.objects = {
5944
	image = {},
5945
	textarea = {}
5946
}
5947
eventModeChanged = function()
5948
	-- Remove content
5949
	for k in next,system.objects.image do
5950
		tfm.exec.removeImage(k)
5951
	end
5952
	
5953
	for k in next,system.objects.textarea do
5954
		ui.removeTextArea(k,nil)
5955
	end
5956
	
5957
	system.objects = {
5958
		image = {},
5959
		textarea = {}
5960
	}
5961
	
5962
	ui.addPopup(0,0,"",nil,-1500,-1500)
5963
	
5964
	-- Unbind keyboard and mouse, also normalize color name and scores
5965
	for k in next,tfm.get.room.playerList do
5966
		for i = 0,255 do
5967
			for v = 0,1 do
5968
				system.bindKeyboard(k,i,v == 0,false)
5969
			end
5970
		end
5971
		
5972
		system.bindMouse(k,false)
5973
		
5974
		tfm.exec.setNameColor(k,-1)
5975
		tfm.exec.setPlayerScore(k,0)
5976
	end
5977
	
5978
	-- Set admin back
5979
	system.roomAdmins = system.setAdmins()
5980
	
5981
	-- Reset settings
5982
	for k,v in next,{"AutoScore","WatchCommand","AutoNewGame","AutoShaman","AllShamanSkills","MortCommand","DebugCommand","MinimalistMode","AfkDeath","PhysicalConsumables","AutoTimeLeft"} do
5983
		tfm.exec["disable" .. v](false)
5984
	end
5985
	tfm.exec.setAutoMapFlipMode()
5986
	
5987
	tfm.exec.setRoomMaxPlayers(25)
5988
	tfm.exec.setRoomPassword("")	
5989
end
5990
5991
--[[ Event Functions ]]--
5992
events = {}
5993
5994
events.eventLoop = function(currentTime,leftTime)
5995
	_G.currentTime = normalizeTime(currentTime / 1e3)
5996
	_G.leftTime = normalizeTime(leftTime / 1e3)
5997
end
5998
5999
events.eventChatCommand = function(n,c)
6000
	disableChatCommand(c)
6001
	if module._FREEACCESS[n] then
6002
		if c == "refresh" and (not system.isRoom or module._FREEACCESS[n] > 1) then
6003
			eventModeChanged()
6004
			system.init(true)
6005
		elseif stringsub(c,1,4) == "room" and (not system.isRoom or module._FREEACCESS[n] > 1) then
6006
			system.roomNumber = tonumber(stringsub(c,6)) or 0
6007
			if _G["eventChatCommand"] then
6008
				eventChatCommand(n,"refresh")
6009
			end
6010
		elseif stringsub(c,1,4) == "load" and (not system.isRoom or module._FREEACCESS[n] > 2) then
6011
			if os.time() > system.modeChanged and os.time() > system.newGameTimer then
6012
				local newMode = system.getGameMode(stringsub(c,6),true)
6013
				if newMode then
6014
					system.init(system.isRoom)
6015
				end
6016
			end
6017
		end
6018
	end
6019
	if stringsub(c,1,6) == "module" then
6020
		c = stringupper(stringsub(c,8))
6021
		if module["_" .. c] then
6022
			tfm.exec.chatMessage(c .. " : " .. tableconcat(tableturnTable(module["_" .. c]),"\n",function(k,v)
6023
				return (c == "FREEACCESS" and stringformat("%s(%s)",k,v) or v)
6024
			end),n)
6025
		else
6026
			tfm.exec.chatMessage(stringformat("VERSION : %s\nNAME : %s\nSTATUS : %s\nAUTHOR : %s\n\nMODE : %s",module._VERSION,module._NAME,module._STATUS,module._AUTHOR,system.gameMode),n)
6027
		end
6028
	elseif c == "modes" then
6029
		tfm.exec.chatMessage(tableconcat(system.submodes,"\n",function(k,v)
6030
			return "#" .. system.normalizedModeName(v)
6031
		end),n)
6032
	elseif c == "admin" then
6033
		tfm.exec.chatMessage(tableconcat(system.roomAdmins,", ",tostring),n)
6034
	elseif c == "stop" and system.roomAdmins[n] then
6035
		system.exit()
6036
	elseif stringsub(c,1,3) == "adm" and (system.roomAdmins[n] or module._FREEACCESS[n] > 2) then
6037
		system.roomAdmins[stringnick(stringsub(c,5))] = true
6038
	end
6039
end
6040
6041
events.eventNewPlayer = function(n)
6042
	
6043
	if system.officialMode[2] ~= "" then
6044
		tfm.exec.chatMessage(system.officialMode[2],n)
6045
	end
6046
end
6047
6048
--[[ Room Settings ]]--
6049
system.roomSettings = {
6050
	["@"] = function(n)
6051
		system.roomAdmins[stringnick(n)] = true
6052
	end,
6053
	["#"] = function(id)
6054
		system.miscAttrib = tonumber(id) or 1
6055
		system.miscAttrib = mathsetLim(system.miscAttrib,1,99) -- mathmax(1,mathmin(system.miscAttrib,99))
6056
	end,
6057
	["*"] = function(name)
6058
		local game = system.getGameMode(name)
6059
		if not game then
6060
			system.gameMode = "grounds"
6061
		end
6062
	end
6063
}
6064
system.setRoom = function()
6065
	if system.isRoom and system.roomAttributes then
6066
		local chars = ""
6067
		for k in next,system.roomSettings do
6068
			chars = chars .. k
6069
		end
6070
6071
		for char,value in stringgmatch(system.roomAttributes,"(["..chars.."])([^"..chars.."]+)") do
6072
			value = stringmatch(value,"[^%s]+")
6073
			for k,v in next,system.roomSettings do
6074
				if k == char then
6075
					v(value)
6076
					break
6077
				end
6078
			end
6079
		end
6080
		
6081
		local officialModes = {
6082
			{"vanilla","<VP>Enjoy your vanilla (: .. okno"},
6083
			{"survivor","<R>Aw, you cannot play survivor on #grounds"},
6084
			{"racing","<CH>Uh, racing? Good luck!"},
6085
			{"music","<BV>Music? Nice choice! Why don't you try a rock'n'roll?"},
6086
			{"bootcamp","<PT>Bootcamp? Ok. This is unfair and your data won't be saved out of the room."},
6087
			{"defilante","<R>Aw, you cannot play defilante on #grounds"},
6088
			{"village","<R>You cannot play village on #grounds. Please, change your room."},
6089
		}
6090
		for k,v in next,officialModes do
6091
			if stringfind(system.roomAttributes,v[1] .. "$") then
6092
				system.officialMode = {v[1],v[2]}
6093
				break
6094
			end
6095
		end
6096
	end
6097
end
6098
6099
--[[ Initialize ]]--
6100
execute = {}
6101
system.setRoom()
6102
6103
system.init = function(refresh)
6104
	for i,event in next,{"Loop","NewGame","PlayerDied","PlayerGetCheese","PlayerVampire","PlayerWon","PlayerLeft","EmotePlayed","Keyboard","Mouse","PopupAnswer","TextAreaCallback","ChatCommand","ChatMessage","SummoningStart","SummoningEnd","SummoningCancel","NewPlayer","PlayerRespawn","ColorPicked"} do
6105
		local e = "event" .. event
6106
		
6107
		local found = false
6108
		for k,v in next,mode[system.gameMode] do
6109
			if k == e then
6110
				execute[e] = v
6111
				found = true
6112
				break
6113
			end
6114
		end
6115
		if not found then
6116
			execute[e] = function() end
6117
		end
6118
6119
		_G[e] = function(...)
6120
			if events[e] then
6121
				events[e](...)
6122
			end
6123
			execute[e](...)
6124
		end
6125
	end
6126
6127
	if refresh then
6128
		if mode[system.gameMode].reset then
6129
			mode[system.gameMode].reset()
6130
		end
6131
	end
6132
	
6133
	if _G["eventNewPlayer"] then
6134
		tableforeach(tfm.get.room.playerList,eventNewPlayer)
6135
	end
6136
	
6137
	normalizeTranslation()
6138
	mode[system.gameMode].init()
6139
end
6140
system.init()