1#include "explanations.h"
2
3#include <base/system.h>
4
5#include <game/mapitems.h>
6
7// DDNet entity explanations by Lady Saavik
8// TODO: Add other entities' tiles' explanations and improve new ones
9
10// Tile Numbers For Explanations - TODO: Add/Improve tiles and explanations
11enum
12{
13 TILE_PUB_AIR = 0,
14 TILE_PUB_HOOKABLE = 1,
15 TILE_PUB_DEATH = 2,
16 TILE_PUB_UNHOOKABLE = 3,
17
18 TILE_PUB_CREDITS1 = 140,
19 TILE_PUB_CREDITS2 = 141,
20 TILE_PUB_CREDITS3 = 142,
21 TILE_PUB_CREDITS4 = 143,
22 TILE_PUB_CREDITS5 = 156,
23 TILE_PUB_CREDITS6 = 157,
24 TILE_PUB_CREDITS7 = 158,
25 TILE_PUB_CREDITS8 = 159,
26
27 TILE_PUB_ENTITIES_OFF1 = 190,
28 TILE_PUB_ENTITIES_OFF2 = 191,
29};
30
31enum
32{
33 TILE_FNG_SPIKE_GOLD = 7,
34 TILE_FNG_SPIKE_NORMAL = 8,
35 TILE_FNG_SPIKE_RED = 9,
36 TILE_FNG_SPIKE_BLUE = 10,
37 TILE_FNG_SCORE_RED = 11,
38 TILE_FNG_SCORE_BLUE = 12,
39
40 TILE_FNG_SPIKE_GREEN = 14,
41 TILE_FNG_SPIKE_PURPLE = 15,
42
43 TILE_FNG_SPAWN = 192,
44 TILE_FNG_SPAWN_RED = 193,
45 TILE_FNG_SPAWN_BLUE = 194,
46 TILE_FNG_FLAG_RED = 195,
47 TILE_FNG_FLAG_BLUE = 196,
48 TILE_FNG_SHIELD = 197,
49 TILE_FNG_HEART = 198,
50 TILE_FNG_SHOTGUN = 199,
51 TILE_FNG_GRENADE = 200,
52 TILE_FNG_NINJA = 201,
53 TILE_FNG_LASER = 202,
54
55 TILE_FNG_SPIKE_OLD1 = 208,
56 TILE_FNG_SPIKE_OLD2 = 209,
57 TILE_FNG_SPIKE_OLD3 = 210,
58};
59
60enum
61{
62 TILE_VANILLA_SPAWN = 192,
63 TILE_VANILLA_SPAWN_RED = 193,
64 TILE_VANILLA_SPAWN_BLUE = 194,
65 TILE_VANILLA_FLAG_RED = 195,
66 TILE_VANILLA_FLAG_BLUE = 196,
67 TILE_VANILLA_SHIELD = 197,
68 TILE_VANILLA_HEART = 198,
69 TILE_VANILLA_SHOTGUN = 199,
70 TILE_VANILLA_GRENADE = 200,
71 TILE_VANILLA_NINJA = 201,
72 TILE_VANILLA_LASER = 202,
73};
74
75const char *CExplanations::ExplainDDNet(int Tile, int Layer)
76{
77 switch(Tile)
78 {
79 case TILE_AIR:
80 return "EMPTY: Can be used as an eraser.";
81 case TILE_SOLID:
82 if(Layer == LAYER_GAME)
83 return "HOOKABLE: It's possible to hook and collide with it.";
84 break;
85 case TILE_DEATH:
86 if(Layer == LAYER_GAME || Layer == LAYER_FRONT)
87 return "KILL: Kills the tee.";
88 break;
89 case TILE_NOHOOK:
90 if(Layer == LAYER_GAME)
91 return "UNHOOKABLE: It's not possible to hook it, but can collide with it.";
92 break;
93 case TILE_NOLASER:
94 if(Layer == LAYER_GAME || Layer == LAYER_FRONT)
95 return "LASER BLOCKER: Doesn't let DRAGGING & SPINNING LASER and PLASMA TURRET reach tees through it.";
96 break;
97 case TILE_THROUGH_CUT:
98 if(Layer == LAYER_GAME || Layer == LAYER_FRONT)
99 return "HOOKTHROUGH: Shortcut for new hookthrough.";
100 break;
101 case TILE_THROUGH_ALL:
102 if(Layer == LAYER_GAME || Layer == LAYER_FRONT)
103 return "HOOKTHROUGH: Combined with a collision tile is new hookthrough, otherwise stops hooks, from all directions.";
104 break;
105 case TILE_THROUGH_DIR:
106 if(Layer == LAYER_GAME || Layer == LAYER_FRONT)
107 return "HOOKTHROUGH: Combined with a collision tile is new hookthrough, otherwise stops hook, from one direction.";
108 break;
109 case TILE_THROUGH:
110 if(Layer == LAYER_GAME || Layer == LAYER_FRONT)
111 return "HOOKTHROUGH: Combined with (UN)HOOKABLE tiles, allows to hook through the walls.";
112 break;
113 case TILE_JUMP:
114 if(Layer == LAYER_SWITCH)
115 return "JUMP: Sets defined amount of jumps (default is 2).";
116 break;
117 case TILE_FREEZE:
118 if(Layer == LAYER_GAME || Layer == LAYER_FRONT)
119 return "FREEZE: Freezes tees for 3 seconds.";
120 if(Layer == LAYER_SWITCH)
121 return "FREEZE: Freezes tees for defined amount of seconds.";
122 break;
123 case TILE_UNFREEZE:
124 if(Layer == LAYER_GAME || Layer == LAYER_FRONT)
125 return "UNFREEZE: Unfreezes tees immediately.";
126 break;
127 case TILE_TELEINEVIL:
128 if(Layer == LAYER_TELE)
129 return "RED TELEPORT: After falling into this tile, tees appear on TO with the same number. Speed and hooks are reset.";
130 break;
131 case TILE_DFREEZE:
132 if(Layer == LAYER_GAME || Layer == LAYER_FRONT || Layer == LAYER_SWITCH)
133 return "DEEP FREEZE: Permanent freeze. Only UNDEEP tile can cancel this effect.";
134 break;
135 case TILE_DUNFREEZE:
136 if(Layer == LAYER_GAME || Layer == LAYER_FRONT || Layer == LAYER_SWITCH)
137 return "UNDEEP: Removes DEEP FREEZE effect.";
138 break;
139 case TILE_LFREEZE:
140 if(Layer == LAYER_GAME || Layer == LAYER_FRONT || Layer == LAYER_SWITCH)
141 return "LIVE FREEZE: Live frozen tees cannot move or jump, while hook and weapons can still be used.";
142 break;
143 case TILE_LUNFREEZE:
144 if(Layer == LAYER_GAME || Layer == LAYER_FRONT || Layer == LAYER_SWITCH)
145 return "LIVE UNFREEZE: Removes LIVE FREEZE effect.";
146 break;
147 case TILE_TELEINWEAPON:
148 if(Layer == LAYER_TELE)
149 return "WEAPON TELEPORT: Teleports bullets shot into it to TELEPORT TO, where it comes out. Direction, angle and length are kept.";
150 break;
151 case TILE_TELEINHOOK:
152 if(Layer == LAYER_TELE)
153 return "HOOK TELEPORT: Teleports hooks entering into it to TELEPORT TO, where it comes out. Direction, angle and length are kept.";
154 break;
155 case TILE_WALLJUMP:
156 if(Layer == LAYER_GAME || Layer == LAYER_FRONT)
157 return "WALLJUMP: Placed next to a wall. Enables climbing up the wall.";
158 break;
159 case TILE_EHOOK_ENABLE:
160 if(Layer == LAYER_GAME || Layer == LAYER_FRONT)
161 return "ENDLESS HOOK: Activates endless hook.";
162 break;
163 case TILE_EHOOK_DISABLE:
164 if(Layer == LAYER_GAME || Layer == LAYER_FRONT)
165 return "ENDLESS HOOK OFF: Deactivates endless hook.";
166 break;
167 case TILE_HIT_ENABLE:
168 if(Layer == LAYER_GAME || Layer == LAYER_FRONT)
169 return "HIT OTHERS: You can hit others.";
170 if(Layer == LAYER_SWITCH)
171 return "HIT OTHERS: You can activate hitting others for single weapons, using delay number to select which.";
172 break;
173 case TILE_HIT_DISABLE:
174 if(Layer == LAYER_GAME || Layer == LAYER_FRONT)
175 return "HIT OTHERS: You can't hit others.";
176 if(Layer == LAYER_SWITCH)
177 return "HIT OTHERS: You can deactivate hitting others for single weapons, using delay number to select which.";
178 break;
179 case TILE_SOLO_ENABLE:
180 if(Layer == LAYER_GAME || Layer == LAYER_FRONT)
181 return "SOLO: You are now in a solo part.";
182 break;
183 case TILE_SOLO_DISABLE: // also TILE_SWITCHTIMEDOPEN
184 if(Layer == LAYER_GAME || Layer == LAYER_FRONT)
185 return "SOLO: You are now out of the solo part.";
186 if(Layer == LAYER_SWITCH)
187 return "TIME SWITCH: Activates switch (e.g. closes door) with the same number for a set amount of seconds.";
188 break;
189 case TILE_SWITCHTIMEDCLOSE:
190 if(Layer == LAYER_SWITCH)
191 return "TIME SWITCH: Deactivates switch (e.g. opens door) with the same number for a set amount of seconds.";
192 break;
193 case TILE_SWITCHOPEN:
194 if(Layer == LAYER_SWITCH)
195 return "SWITCH: Activates switch (e.g. closes door) with the same number.";
196 break;
197 case TILE_SWITCHCLOSE:
198 if(Layer == LAYER_SWITCH)
199 return "SWITCH: Deactivates switch (e.g. opens door) with the same number.";
200 break;
201 case TILE_TELEIN:
202 if(Layer == LAYER_TELE)
203 return "BLUE TELEPORT: After falling into this tile, tees appear on TO with the same number. Speed and hook are kept.";
204 break;
205 case TILE_TELEOUT:
206 if(Layer == LAYER_TELE)
207 return "TELEPORT TO: Destination tile for FROMs, WEAPON & HOOK TELEPORTs with the same numbers.";
208 break;
209 case TILE_SPEED_BOOST_OLD:
210 if(Layer == LAYER_SPEEDUP)
211 return "OLD SPEEDUP: Gives tee defined speed. Arrow shows direction and angle. Deprecated.";
212 break;
213 case TILE_TELECHECK: // also TILE_SPEED_BOOST
214 if(Layer == LAYER_TELE)
215 return "CHECKPOINT TELEPORT: After having touched this tile, any CFRM will teleport you to CTO with the same number.";
216 if(Layer == LAYER_SPEEDUP)
217 return "SPEEDUP: Gives tee defined speed. Arrow shows direction and angle.";
218 break;
219 case TILE_TELECHECKOUT:
220 if(Layer == LAYER_TELE)
221 return "CHECKPOINT TELEPORT TO: Tees will appear here after touching TELEPORT CHECKPOINT with the same number and falling into CFROM TELEPORT.";
222 break;
223 case TILE_TELECHECKIN:
224 if(Layer == LAYER_TELE)
225 return "BLUE CHECKPOINT TELEPORT: Sends tees to CTO with the same number as the last touched TELEPORT CHECKPOINT. Speed and hook are kept.";
226 break;
227 case TILE_REFILL_JUMPS:
228 if(Layer == LAYER_GAME || Layer == LAYER_FRONT)
229 return "REFILL JUMPS: Restores all jumps.";
230 break;
231 case TILE_START:
232 if(Layer == LAYER_GAME || Layer == LAYER_FRONT)
233 return "START: Starts counting your race time.";
234 break;
235 case TILE_FINISH:
236 if(Layer == LAYER_GAME || Layer == LAYER_FRONT)
237 return "FINISH: End of race.";
238 break;
239 case TILE_STOP:
240 if(Layer == LAYER_GAME || Layer == LAYER_FRONT)
241 return "STOPPER: You can hook and shoot through it. You can't go through it against the arrow.";
242 break;
243 case TILE_STOPS:
244 if(Layer == LAYER_GAME || Layer == LAYER_FRONT)
245 return "STOPPER: You can hook and shoot through it. You can't go through it against the arrows.";
246 break;
247 case TILE_STOPA:
248 if(Layer == LAYER_GAME || Layer == LAYER_FRONT)
249 return "STOPPER: You can hook and shoot through it. You can't go through it.";
250 break;
251 case TILE_TELECHECKINEVIL:
252 if(Layer == LAYER_TELE)
253 return "RED CHECKPOINT TELEPORT: Send tees to CTO with the same number as the last touched TELEPORT CHECKPOINT. Speed and hook are reset.";
254 break;
255 case TILE_CP:
256 if(Layer == LAYER_GAME || Layer == LAYER_FRONT)
257 return "SPEEDER: Causes weapons, SHIELD, HEART and SPINNING LASER to move slowly.";
258 break;
259 case TILE_CP_F:
260 if(Layer == LAYER_GAME || Layer == LAYER_FRONT)
261 return "SPEEDER: Causes weapons, SHIELD, HEART and SPINNING LASER to move quickly.";
262 break;
263 case TILE_TUNE:
264 if(Layer == LAYER_TUNE)
265 return "TUNE ZONE: Area where defined tunes work.";
266 break;
267 case TILE_OLDLASER:
268 if(Layer == LAYER_GAME || Layer == LAYER_FRONT)
269 return "GLOBAL OLD SHOTGUN: Shotgun drags others always towards the shooter, even after having bounced. Shooter can't hit themselves. Place only one tile somewhere on the map.";
270 break;
271 case TILE_NPC:
272 if(Layer == LAYER_GAME || Layer == LAYER_FRONT)
273 return "GLOBAL COLLISION OFF: Nobody can collide with others. Place only one tile somewhere on the map.";
274 break;
275 case TILE_EHOOK:
276 if(Layer == LAYER_GAME || Layer == LAYER_FRONT)
277 return "GLOBAL ENDLESS HOOK ON: Everyone has endless hook. Place only one tile somewhere on the map.";
278 break;
279 case TILE_NOHIT:
280 if(Layer == LAYER_GAME || Layer == LAYER_FRONT)
281 return "GLOBAL HIT OTHERS OFF: Nobody can hit others. Place only one tile somewhere on the map.";
282 break;
283 case TILE_NPH:
284 if(Layer == LAYER_GAME || Layer == LAYER_FRONT)
285 return "GLOBAL HOOK OTHERS OFF: Nobody can hook others. Place only one tile somewhere on the map.";
286 break;
287 case TILE_UNLOCK_TEAM:
288 if(Layer == LAYER_GAME || Layer == LAYER_FRONT)
289 return "UNLOCK TEAM: Forces team to be unlocked so that team doesn't get killed when one dies.";
290 break;
291 case TILE_ADD_TIME:
292 if(Layer == LAYER_SWITCH)
293 return "PENALTY: Adds time to your current race time. Opposite of BONUS.";
294 break;
295 case TILE_NPC_DISABLE:
296 if(Layer == LAYER_GAME || Layer == LAYER_FRONT)
297 return "COLLISION OFF: You can't collide with others.";
298 break;
299 case TILE_UNLIMITED_JUMPS_DISABLE:
300 if(Layer == LAYER_GAME || Layer == LAYER_FRONT)
301 return "SUPER JUMP OFF: You don't have unlimited air jumps.";
302 break;
303 case TILE_JETPACK_DISABLE:
304 if(Layer == LAYER_GAME || Layer == LAYER_FRONT)
305 return "JETPACK OFF: You lose your jetpack gun.";
306 break;
307 case TILE_NPH_DISABLE:
308 if(Layer == LAYER_GAME || Layer == LAYER_FRONT)
309 return "HOOK OTHERS OFF: You can't hook others.";
310 break;
311 case TILE_SUBTRACT_TIME:
312 if(Layer == LAYER_SWITCH)
313 return "BONUS: Subtracts time from your current race time. Opposite of PENALTY.";
314 break;
315 case TILE_NPC_ENABLE:
316 if(Layer == LAYER_GAME || Layer == LAYER_FRONT)
317 return "COLLISION: You can collide with others.";
318 break;
319 case TILE_UNLIMITED_JUMPS_ENABLE:
320 if(Layer == LAYER_GAME || Layer == LAYER_FRONT)
321 return "SUPER JUMP: You have unlimited air jumps.";
322 break;
323 case TILE_JETPACK_ENABLE:
324 if(Layer == LAYER_GAME || Layer == LAYER_FRONT)
325 return "JETPACK: You have a jetpack gun.";
326 break;
327 case TILE_NPH_ENABLE:
328 if(Layer == LAYER_GAME || Layer == LAYER_FRONT)
329 return "HOOK OTHERS: You can hook others.";
330 break;
331 case TILE_CREDITS_1:
332 case TILE_CREDITS_2:
333 case TILE_CREDITS_3:
334 case TILE_CREDITS_4:
335 case TILE_CREDITS_5:
336 case TILE_CREDITS_6:
337 case TILE_CREDITS_7:
338 case TILE_CREDITS_8:
339 return "CREDITS: Who designed the entities.";
340 case TILE_ENTITIES_OFF_1:
341 case TILE_ENTITIES_OFF_2:
342 return "ENTITIES OFF SIGN: Informs people playing with entities about important marks, tips, information or text on the map.";
343 // Entities
344 case ENTITY_OFFSET + ENTITY_SPAWN:
345 if(Layer == LAYER_GAME || Layer == LAYER_FRONT)
346 return "SPAWN: Here tees will appear after joining the game or dying somewhere on the map.";
347 break;
348 case ENTITY_OFFSET + ENTITY_SPAWN_RED:
349 if(Layer == LAYER_GAME || Layer == LAYER_FRONT)
350 return "SPAWN: Red team members spawn here, same as normal spawn in DDRace.";
351 break;
352 case ENTITY_OFFSET + ENTITY_SPAWN_BLUE:
353 if(Layer == LAYER_GAME || Layer == LAYER_FRONT)
354 return "SPAWN: Blue team members spawn here, same as normal spawn in DDRace.";
355 break;
356 case ENTITY_OFFSET + ENTITY_FLAGSTAND_RED:
357 if(Layer == LAYER_GAME || Layer == LAYER_FRONT)
358 return "FLAG: Not used in DDRace. Place where red team flag is.";
359 break;
360 case ENTITY_OFFSET + ENTITY_FLAGSTAND_BLUE:
361 if(Layer == LAYER_GAME || Layer == LAYER_FRONT)
362 return "FLAG: Not used in DDRace. Place where blue team flag is.";
363 break;
364 case ENTITY_OFFSET + ENTITY_ARMOR_1:
365 if(Layer == LAYER_GAME || Layer == LAYER_FRONT || Layer == LAYER_SWITCH)
366 return "SHIELD: Takes all weapons (except hammer and pistol) away.";
367 break;
368 case ENTITY_OFFSET + ENTITY_HEALTH_1:
369 if(Layer == LAYER_GAME || Layer == LAYER_FRONT || Layer == LAYER_SWITCH)
370 return "HEART: Works like a FREEZE tile. Freezes tees for 3 seconds by default.";
371 break;
372 case ENTITY_OFFSET + ENTITY_WEAPON_SHOTGUN:
373 if(Layer == LAYER_GAME || Layer == LAYER_FRONT || Layer == LAYER_SWITCH)
374 return "SHOTGUN: Drags the tees towards it. Bounces off the walls.";
375 break;
376 case ENTITY_OFFSET + ENTITY_WEAPON_GRENADE:
377 if(Layer == LAYER_GAME || Layer == LAYER_FRONT || Layer == LAYER_SWITCH)
378 return "GRENADE LAUNCHER: Throws exploding bullets. Also known as rocket.";
379 break;
380 case ENTITY_OFFSET + ENTITY_POWERUP_NINJA:
381 if(Layer == LAYER_GAME || Layer == LAYER_FRONT || Layer == LAYER_SWITCH)
382 return "NINJA: Makes you invisible in the darkest nights.";
383 break;
384 case ENTITY_OFFSET + ENTITY_WEAPON_LASER:
385 if(Layer == LAYER_GAME || Layer == LAYER_FRONT || Layer == LAYER_SWITCH)
386 return "LASER: Unfreezes hit tee. Bounces off the walls. Also known as laser.";
387 break;
388 case ENTITY_OFFSET + ENTITY_LASER_FAST_CCW:
389 if(Layer == LAYER_GAME || Layer == LAYER_FRONT || Layer == LAYER_SWITCH)
390 return "SPINNING LASER: Tile where freezing laser (made with LASER LENGTH) begins. Counter-Clockwise, fast.";
391 break;
392 case ENTITY_OFFSET + ENTITY_LASER_NORMAL_CCW:
393 if(Layer == LAYER_GAME || Layer == LAYER_FRONT || Layer == LAYER_SWITCH)
394 return "SPINNING LASER: Tile where freezing laser (made with LASER LENGTH) begins. Counter-Clockwise, medium speed.";
395 break;
396 case ENTITY_OFFSET + ENTITY_LASER_SLOW_CCW:
397 if(Layer == LAYER_GAME || Layer == LAYER_FRONT || Layer == LAYER_SWITCH)
398 return "SPINNING LASER: Tile where freezing laser (made with LASER LENGTH) begins. Counter-Clockwise, slow.";
399 break;
400 case ENTITY_OFFSET + ENTITY_LASER_STOP:
401 if(Layer == LAYER_GAME || Layer == LAYER_FRONT || Layer == LAYER_SWITCH)
402 return "NON-SPINNING LASER: Tile where freezing laser (made with LASER LENGTH) begins.";
403 break;
404 case ENTITY_OFFSET + ENTITY_LASER_SLOW_CW:
405 if(Layer == LAYER_GAME || Layer == LAYER_FRONT || Layer == LAYER_SWITCH)
406 return "SPINNING LASER: Tile where freezing laser (made with LASER LENGTH) begins. Clockwise, slow.";
407 break;
408 case ENTITY_OFFSET + ENTITY_LASER_NORMAL_CW:
409 if(Layer == LAYER_GAME || Layer == LAYER_FRONT || Layer == LAYER_SWITCH)
410 return "SPINNING LASER: Tile where freezing laser (made with LASER LENGTH) begins. Clockwise, medium speed.";
411 break;
412 case ENTITY_OFFSET + ENTITY_LASER_FAST_CW:
413 if(Layer == LAYER_GAME || Layer == LAYER_FRONT || Layer == LAYER_SWITCH)
414 return "SPINNING LASER: Tile where freezing laser (made with LASER LENGTH) begins. Clockwise, fast.";
415 break;
416 case ENTITY_OFFSET + ENTITY_LASER_SHORT:
417 if(Layer == LAYER_GAME || Layer == LAYER_FRONT || Layer == LAYER_SWITCH)
418 return "LASER LENGTH: Put next to DOOR or SPINNING LASER, makes it 3 tiles long.";
419 break;
420 case ENTITY_OFFSET + ENTITY_LASER_MEDIUM:
421 if(Layer == LAYER_GAME || Layer == LAYER_FRONT || Layer == LAYER_SWITCH)
422 return "LASER LENGTH: Put next to DOOR or SPINNING LASER, makes it 6 tiles long.";
423 break;
424 case ENTITY_OFFSET + ENTITY_LASER_LONG:
425 if(Layer == LAYER_GAME || Layer == LAYER_FRONT || Layer == LAYER_SWITCH)
426 return "LASER LENGTH: Put next to DOOR or SPINNING LASER, makes it 9 tiles long.";
427 break;
428 case ENTITY_OFFSET + ENTITY_LASER_C_SLOW:
429 if(Layer == LAYER_GAME || Layer == LAYER_FRONT || Layer == LAYER_SWITCH)
430 return "LASER LENGTH CHANGE: Put next to LASER LENGTH, causes it to length and shorten constantly. Works only on (NON-)SPINNING LASER, not on DOOR. Lengthen, slow.";
431 break;
432 case ENTITY_OFFSET + ENTITY_LASER_C_NORMAL:
433 if(Layer == LAYER_GAME || Layer == LAYER_FRONT || Layer == LAYER_SWITCH)
434 return "LASER LENGTH CHANGE: Put next to LASER LENGTH, causes it to length and shorten constantly. Works only on (NON-)SPINNING LASER, not on DOOR. Lengthen, medium speed.";
435 break;
436 case ENTITY_OFFSET + ENTITY_LASER_C_FAST:
437 if(Layer == LAYER_GAME || Layer == LAYER_FRONT || Layer == LAYER_SWITCH)
438 return "LASER LENGTH CHANGE: Put next to LASER LENGTH, causes it to length and shorten constantly. Works only on (NON-)SPINNING LASER, not on DOOR. Lengthen, fast.";
439 break;
440 case ENTITY_OFFSET + ENTITY_LASER_O_SLOW:
441 if(Layer == LAYER_GAME || Layer == LAYER_FRONT || Layer == LAYER_SWITCH)
442 return "LASER LENGTH CHANGE: Put next to LASER LENGTH, causes it to length and shorten constantly. Works only on (NON-)SPINNING LASER, not on DOOR. Shorten, slow.";
443 break;
444 case ENTITY_OFFSET + ENTITY_LASER_O_NORMAL:
445 if(Layer == LAYER_GAME || Layer == LAYER_FRONT || Layer == LAYER_SWITCH)
446 return "LASER LENGTH CHANGE: Put next to LASER LENGTH, causes it to length and shorten constantly. Works only on (NON-)SPINNING LASER, not on DOOR. Shorten, medium speed.";
447 break;
448 case ENTITY_OFFSET + ENTITY_LASER_O_FAST:
449 if(Layer == LAYER_GAME || Layer == LAYER_FRONT || Layer == LAYER_SWITCH)
450 return "LASER LENGTH CHANGE: Put next to LASER LENGTH, causes it to length and shorten constantly. Works only on (NON-)SPINNING LASER, not on DOOR. Shorten, fast.";
451 break;
452 case ENTITY_OFFSET + ENTITY_PLASMAE:
453 if(Layer == LAYER_GAME || Layer == LAYER_FRONT || Layer == LAYER_SWITCH)
454 return "PLASMA TURRET: Shoots plasma bullets at the closest tee. They explode on an obstactle they hit (wall or tee).";
455 break;
456 case ENTITY_OFFSET + ENTITY_PLASMAF:
457 if(Layer == LAYER_GAME || Layer == LAYER_FRONT || Layer == LAYER_SWITCH)
458 return "PLASMA TURRET: Shoots plasma bullets that work like FREEZE at the closest tee.";
459 break;
460 case ENTITY_OFFSET + ENTITY_PLASMA:
461 if(Layer == LAYER_GAME || Layer == LAYER_FRONT || Layer == LAYER_SWITCH)
462 return "PLASMA TURRET: Shoots plasma bullets that work like FREEZE at the closest tee. They also explode on an obstactly they hit (wall or tee).";
463 break;
464 case ENTITY_OFFSET + ENTITY_PLASMAU:
465 if(Layer == LAYER_GAME || Layer == LAYER_FRONT || Layer == LAYER_SWITCH)
466 return "PLASMA TURRET: Shoots plasma bullets that work like UNFREEZE at the closest tee.";
467 break;
468 case ENTITY_OFFSET + ENTITY_CRAZY_SHOTGUN_EX:
469 if(Layer == LAYER_GAME || Layer == LAYER_FRONT || Layer == LAYER_SWITCH)
470 return "EXPLODING BULLET: Bounces off the walls with explosion. Touching the bullet works like FREEZE tile (freezes for 3 seconds by default).";
471 break;
472 case ENTITY_OFFSET + ENTITY_CRAZY_SHOTGUN:
473 if(Layer == LAYER_GAME || Layer == LAYER_FRONT || Layer == LAYER_SWITCH)
474 return "BULLET: Bounces off the walls without explosion. Touching the bullet works like FREEZE tile (freezes for 3 seconds by default).";
475 break;
476 case ENTITY_OFFSET + ENTITY_ARMOR_SHOTGUN:
477 if(Layer == LAYER_GAME || Layer == LAYER_FRONT || Layer == LAYER_SWITCH)
478 return "SHOTGUN SHIELD: Takes shotgun away.";
479 break;
480 case ENTITY_OFFSET + ENTITY_ARMOR_GRENADE:
481 if(Layer == LAYER_GAME || Layer == LAYER_FRONT || Layer == LAYER_SWITCH)
482 return "GRENADE SHIELD: Takes grenade away.";
483 break;
484 case ENTITY_OFFSET + ENTITY_ARMOR_NINJA:
485 if(Layer == LAYER_GAME || Layer == LAYER_FRONT || Layer == LAYER_SWITCH)
486 return "NINJA SHIELD: Takes ninja away.";
487 break;
488 case ENTITY_OFFSET + ENTITY_ARMOR_LASER:
489 if(Layer == LAYER_GAME || Layer == LAYER_FRONT || Layer == LAYER_SWITCH)
490 return "LASER SHIELD: Takes laser away.";
491 break;
492 case ENTITY_OFFSET + ENTITY_DRAGGER_WEAK:
493 if(Layer == LAYER_GAME || Layer == LAYER_FRONT || Layer == LAYER_SWITCH)
494 return "DRAGGING LASER: Grabs and attracts the closest tee to it. Can't reach tees through walls and LASER BLOCKER. Weak.";
495 break;
496 case ENTITY_OFFSET + ENTITY_DRAGGER_NORMAL:
497 if(Layer == LAYER_GAME || Layer == LAYER_FRONT || Layer == LAYER_SWITCH)
498 return "DRAGGING LASER: Grabs and attracts the closest tee to it. Can't reach tees through walls and LASER BLOCKER. Medium strength.";
499 break;
500 case ENTITY_OFFSET + ENTITY_DRAGGER_STRONG:
501 if(Layer == LAYER_GAME || Layer == LAYER_FRONT || Layer == LAYER_SWITCH)
502 return "DRAGGING LASER: Grabs and attracts the closest tee to it. Can't reach tees through walls and LASER BLOCKER. Strong.";
503 break;
504 case ENTITY_OFFSET + ENTITY_DRAGGER_WEAK_NW:
505 if(Layer == LAYER_GAME || Layer == LAYER_FRONT || Layer == LAYER_SWITCH)
506 return "DRAGGING LASER: Grabs and attracts the closest tee to it. Can reach tees through walls but not through LASER BLOCKER. Weak.";
507 break;
508 case ENTITY_OFFSET + ENTITY_DRAGGER_NORMAL_NW:
509 if(Layer == LAYER_GAME || Layer == LAYER_FRONT || Layer == LAYER_SWITCH)
510 return "DRAGGING LASER: Grabs and attracts the closest tee to it. Can reach tees through walls but not through LASER BLOCKER. Medium strength.";
511 break;
512 case ENTITY_OFFSET + ENTITY_DRAGGER_STRONG_NW:
513 if(Layer == LAYER_GAME || Layer == LAYER_FRONT || Layer == LAYER_SWITCH)
514 return "DRAGGING LASER: Grabs and attracts the closest tee to it. Can reach tees through walls but not through LASER BLOCKER. Strong.";
515 break;
516 case ENTITY_OFFSET + ENTITY_DOOR:
517 if(Layer == LAYER_GAME || Layer == LAYER_FRONT || Layer == LAYER_SWITCH)
518 return "DOOR: Combined with LASER LENGTH creates doors. Doesn't allow to go through it (only with NINJA).";
519 break;
520 case TILE_TELE_GUN_ENABLE:
521 if(Layer == LAYER_GAME || Layer == LAYER_FRONT)
522 return "TELEGUN: Turn gun on as telegun weapon.";
523 break;
524 case TILE_TELE_GUN_DISABLE:
525 if(Layer == LAYER_GAME || Layer == LAYER_FRONT)
526 return "TELEGUN OFF: Turn gun off as telegun weapon.";
527 break;
528 case TILE_ALLOW_TELE_GUN:
529 if(Layer == LAYER_FRONT)
530 return "TELEGUN: Place on top of a collision tile, activates a spot to teleport to, cancels movement.";
531 if(Layer == LAYER_SWITCH)
532 return "TELEGUN: Place on top of a collision tile, activates a spot to teleport to, cancels movement, for single weapons, using delay number to select which.";
533 break;
534 case TILE_ALLOW_BLUE_TELE_GUN:
535 if(Layer == LAYER_FRONT)
536 return "TELEGUN: Place on top of a collision tile, activates a spot to teleport to, preserves movement.";
537 if(Layer == LAYER_SWITCH)
538 return "TELEGUN: Place on top of a collision tile, activates a spot to teleport to, preserves movement, for single weapons, using delay number to select which.";
539 break;
540 case TILE_TELE_GRENADE_ENABLE:
541 if(Layer == LAYER_GAME || Layer == LAYER_FRONT)
542 return "TELEGRENADE: Turn grenade on as telegun weapon.";
543 break;
544 case TILE_TELE_GRENADE_DISABLE:
545 if(Layer == LAYER_GAME || Layer == LAYER_FRONT)
546 return "TELEGRENADE OFF: Turn grenade off as telegun weapon.";
547 break;
548 case TILE_TELE_LASER_ENABLE:
549 if(Layer == LAYER_GAME || Layer == LAYER_FRONT)
550 return "TELELASER: Turn laser on as telegun weapon.";
551 break;
552 case TILE_TELE_LASER_DISABLE:
553 if(Layer == LAYER_GAME || Layer == LAYER_FRONT)
554 return "TELELASER OFF: Turn laser off as telegun weapon.";
555 break;
556 }
557 if(Tile >= TILE_TIME_CHECKPOINT_FIRST && Tile <= TILE_TIME_CHECKPOINT_LAST && (Layer == LAYER_GAME || Layer == LAYER_FRONT))
558 return "TIME CHECKPOINT: Compares your current race time with your record to show you whether you are running faster or slower.";
559 return nullptr;
560}
561
562const char *CExplanations::ExplainFNG(int Tile, int Layer)
563{
564 switch(Tile)
565 {
566 case TILE_PUB_AIR:
567 return "EMPTY: Can be used as an eraser.";
568 case TILE_PUB_HOOKABLE:
569 if(Layer == LAYER_GAME)
570 return "HOOKABLE: It's possible to hook and collide with it.";
571 break;
572 case TILE_PUB_DEATH:
573 if(Layer == LAYER_GAME)
574 return "DEATH: Kills the tee.";
575 break;
576 case TILE_PUB_UNHOOKABLE:
577 if(Layer == LAYER_GAME)
578 return "UNHOOKABLE: It's not possible to hook it, but can collide with it.";
579 break;
580 case TILE_FNG_SPIKE_GOLD:
581 if(Layer == LAYER_GAME)
582 return "GOLDEN SPIKE: Kills the tee and gives points to the killer. Amount of points given is set inside the server.";
583 break;
584 case TILE_FNG_SPIKE_NORMAL:
585 if(Layer == LAYER_GAME)
586 return "NORMAL SPIKE: Kills the tee and gives points to the killer. Amount of points given is set inside the server.";
587 break;
588 case TILE_FNG_SPIKE_RED:
589 if(Layer == LAYER_GAME)
590 return "RED SPIKE: Red team spikes. Gives negative points when killer is in blue team. Amount of points given is set inside the server.";
591 break;
592 case TILE_FNG_SPIKE_BLUE:
593 if(Layer == LAYER_GAME)
594 return "BLUE SPIKE: Blue team spikes. Gives negative points when killer is in red team. Amount of points given is set inside the server.";
595 break;
596 case TILE_FNG_SCORE_RED:
597 if(Layer == LAYER_GAME)
598 return "SCORE: Old tile used for showing red team score using laser text. No longer usable in FNG2.";
599 break;
600 case TILE_FNG_SCORE_BLUE:
601 if(Layer == LAYER_GAME)
602 return "SCORE: Old tile used for showing blue team score using laser text. No longer usable in FNG2.";
603 break;
604 case TILE_FNG_SPIKE_GREEN:
605 if(Layer == LAYER_GAME)
606 return "GREEN SPIKE: Kills the tee and gives points to the killer. Amount of points given is set inside the server.";
607 break;
608 case TILE_FNG_SPIKE_PURPLE:
609 if(Layer == LAYER_GAME)
610 return "PURPLE SPIKE: Kills the tee and gives points to the killer. Amount of points given is set inside the server.";
611 break;
612 case TILE_FNG_SPAWN:
613 if(Layer == LAYER_GAME)
614 return "SPAWN: Here tees will appear after joining the game or dying.";
615 break;
616 case TILE_FNG_SPAWN_RED:
617 if(Layer == LAYER_GAME)
618 return "SPAWN: Red team members spawn here.";
619 break;
620 case TILE_FNG_SPAWN_BLUE:
621 if(Layer == LAYER_GAME)
622 return "SPAWN: Blue team members spawn here.";
623 break;
624 case TILE_FNG_FLAG_RED:
625 if(Layer == LAYER_GAME)
626 return "FLAG: Not used in FNG. Place where red team flag is.";
627 break;
628 case TILE_FNG_FLAG_BLUE:
629 if(Layer == LAYER_GAME)
630 return "FLAG: Not used in FNG. Place where blue team flag is.";
631 break;
632 case TILE_FNG_SHIELD:
633 if(Layer == LAYER_GAME)
634 return "SHIELD: Does nothing in FNG.";
635 break;
636 case TILE_FNG_HEART:
637 if(Layer == LAYER_GAME)
638 return "HEART: Does nothing in FNG.";
639 break;
640 case TILE_FNG_SHOTGUN:
641 if(Layer == LAYER_GAME)
642 return "SHOTGUN: Not used in FNG. Gives you shotgun with 10 charges.";
643 break;
644 case TILE_FNG_GRENADE:
645 if(Layer == LAYER_GAME)
646 return "GRENADE: Gives you grenade weapon with 10 charges. Not really useful in FNG.";
647 break;
648 case TILE_FNG_NINJA:
649 if(Layer == LAYER_GAME)
650 return "NINJA: Does nothing in FNG.";
651 break;
652 case TILE_FNG_LASER:
653 if(Layer == LAYER_GAME)
654 return "LASER: Gives you laser weapon with 10 charges. Not really useful in FNG.";
655 break;
656 case TILE_FNG_SPIKE_OLD1:
657 case TILE_FNG_SPIKE_OLD2:
658 case TILE_FNG_SPIKE_OLD3:
659 if(Layer == LAYER_GAME)
660 return "SPIKE: Old FNG spikes. Deprecated.";
661 break;
662 }
663 if((Tile >= TILE_PUB_CREDITS1 && Tile <= TILE_PUB_CREDITS8) && Layer == LAYER_GAME)
664 return "CREDITS: Who designed the entities.";
665 else if((Tile == TILE_PUB_ENTITIES_OFF1 || Tile == TILE_PUB_ENTITIES_OFF2) && Layer == LAYER_GAME)
666 return "ENTITIES OFF SIGN: Informs people playing with entities about important marks, tips, information or text on the map.";
667 return nullptr;
668}
669
670const char *CExplanations::ExplainVanilla(int Tile, int Layer)
671{
672 switch(Tile)
673 {
674 case TILE_PUB_AIR:
675 return "EMPTY: Can be used as an eraser.";
676 case TILE_PUB_HOOKABLE:
677 if(Layer == LAYER_GAME)
678 return "HOOKABLE: It's possible to hook and collide with it.";
679 break;
680 case TILE_PUB_DEATH:
681 if(Layer == LAYER_GAME)
682 return "DEATH: Kills the tee.";
683 break;
684 case TILE_PUB_UNHOOKABLE:
685 if(Layer == LAYER_GAME)
686 return "UNHOOKABLE: It's not possible to hook it, but can collide with it.";
687 break;
688 case TILE_VANILLA_SPAWN:
689 if(Layer == LAYER_GAME)
690 return "SPAWN: Here tees will appear after joining the game or dying.";
691 break;
692 case TILE_VANILLA_SPAWN_RED:
693 if(Layer == LAYER_GAME)
694 return "SPAWN: Red team members spawn here.";
695 break;
696 case TILE_VANILLA_SPAWN_BLUE:
697 if(Layer == LAYER_GAME)
698 return "SPAWN: Blue team members spawn here.";
699 break;
700 case TILE_VANILLA_FLAG_RED:
701 if(Layer == LAYER_GAME)
702 return "FLAG: Place where red team flag is.";
703 break;
704 case TILE_VANILLA_FLAG_BLUE:
705 if(Layer == LAYER_GAME)
706 return "FLAG: Place where blue team flag is.";
707 break;
708 case TILE_VANILLA_SHIELD:
709 if(Layer == LAYER_GAME)
710 return "SHIELD: Gives player +1 shield.";
711 break;
712 case TILE_VANILLA_HEART:
713 if(Layer == LAYER_GAME)
714 return "HEART: Gives player +1 health";
715 break;
716 case TILE_VANILLA_SHOTGUN:
717 if(Layer == LAYER_GAME)
718 return "SHOTGUN: Gives you shotgun weapon with 10 charges.";
719 break;
720 case TILE_VANILLA_GRENADE:
721 if(Layer == LAYER_GAME)
722 return "GRENADE: Gives you grenade weapon with 10 charges.";
723 break;
724 case TILE_VANILLA_NINJA:
725 if(Layer == LAYER_GAME)
726 return "NINJA: Gives you ninja for a period of time.";
727 break;
728 case TILE_VANILLA_LASER:
729 if(Layer == LAYER_GAME)
730 return "LASER: Gives you laser weapon with 10 charges.";
731 break;
732 }
733 if((Tile >= TILE_PUB_CREDITS1 && Tile <= TILE_PUB_CREDITS8) && Layer == LAYER_GAME)
734 return "CREDITS: Who designed the entities.";
735 else if((Tile == TILE_PUB_ENTITIES_OFF1 || Tile == TILE_PUB_ENTITIES_OFF2) && Layer == LAYER_GAME)
736 return "ENTITIES OFF SIGN: Informs people playing with entities about important marks, tips, information or text on the map.";
737 return nullptr;
738}
739
740const char *CExplanations::Explain(EGametype Gametype, int Tile, int Layer)
741{
742 switch(Gametype)
743 {
744 case EGametype::NONE:
745 return nullptr;
746 case EGametype::DDNET:
747 return ExplainDDNet(Tile, Layer);
748 case EGametype::FNG:
749 return ExplainFNG(Tile, Layer);
750 case EGametype::RACE:
751 return nullptr; // TODO: Explanations for Race
752 case EGametype::VANILLA:
753 return ExplainVanilla(Tile, Layer);
754 case EGametype::BLOCKWORLDS:
755 return nullptr; // TODO: Explanations for Blockworlds
756 }
757 dbg_assert_failed("Gametype invalid: %d", (int)Gametype);
758}
759