View difference between Paste ID: JmdC5B8Z and UaxggfLm
SHOW: | | - or go back to the newest paste.
1
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
2
#											#
3
#			FS races v1.1 by Flovv			#
4
#											#
5
#			   Filterscript for				#
6
#				automated Races				#
7
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
8
9
#include <a_samp>
10
#include <streamer>
11
#include <sscanf2>
12
13
14
15
16
//needed plugins, Streamer Plugin by Incognito, sscanf2 by Y_Less
17
18
19
20
//********************************************************************
21
/////////////////////////////// SETTINGS /////////////////////////////
22
//********************************************************************
23
24
//use this to increase performance if your server has less than 500 slots or change it if your server has more than 500 slots
25
#undef MAX_PLAYERS
26
#define MAX_PLAYERS 500		//set to your max number of players
27
28
29
//set the maximum number of races to be loaded
30
#define MAX_RACES 50		//max number of races
31
#define MAX_CPS 201		//max number of checkpoints in a race
32
33
34
//use this function for whatever method you use to determine if a player is admin (just make sure to return true if player is admin or false if not)
35
PlayerIsAdmin(playerid)
36
{
37
	if(IsPlayerAdmin(playerid) == 1) return true;
38
	else return false;
39
}
40
41
//******************************************************************
42
////////////////////////// SETTINGS END ////////////////////////////
43
//******************************************************************
44
45
46
47
48
49
50
#define dcmd(%1,%2,%3) if (!strcmp((%3)[1], #%1, true, (%2)) && ((((%3)[(%2) + 1] == '\0') && (dcmd_%1(playerid, ""))) || (((%3)[(%2) + 1] == ' ') && (dcmd_%1(playerid, (%3)[(%2) + 2]))))) return 1
51
52
//functions that have to be forwarded for use in timers
53
forward Countdown(delay);
54
forward HideCountdown();
55
forward HideRaceStartedMsg();
56
forward HidePlayerFinishMsg(playerid);
57
forward HideWinMsg(playerid);
58
forward ShowPlayerFinishMsgDelayed(playerid);
59
forward GetBack(playerid);
60
forward AutoStart1();
61
forward AutoStart2();
62
forward AutoEnd1();
63
forward AutoEnd2();
64
forward HideTimeRemaining();
65
66
//OnPlayerExitVehicleEx vars
67
new playerveh[MAX_VEHICLES];		//save the playerid for every vehicle
68
new vehplayer[MAX_PLAYERS];			//save the vehicleid for player
69
70
//general
71
new autotimer[8];									//[0]autostart on(1) off(0), [1]timerid, [2]time(min), [3]join timerid, [4]join time(min), [5]counter, [6]autoend time, [7]autoend timerid
72
new rettime = 15;									//time to get back to vehicle
73
new exittimer[MAX_PLAYERS];							//timer id for timer that starts when player leaves vehicle
74
new exitcounter[MAX_PLAYERS] = 0;
75
new timer;											//countdown timer id
76
new count = 0;										//counter for Countdown
77
new scount = 5;										//start countdown time(sec)
78
new drace = 0;										//race to be deleted
79
new spawnarea;										//id of the race spawn area
80
new bool:freeze;									//freeze var for race start-freeze
81
new bool:sfreeze = true;							//start freeze on/off
82
new bool:winmsg;									//is the race winner msg shown atm?
83
new bool:noveh[MAX_PLAYERS];						//player is in race without vehicle
84
new bool:cprepair = true;							//repair veh every cp?
85
new Float:playerkoords[MAX_PLAYERS * 2][3];			//saving playerkoords
86
new weapons[MAX_PLAYERS][13][2];					//saving weapons
87
new Text:textdraws[MAX_PLAYERS+1][5];				//textdraws [pid][0]race position, [pid][1]race cp, [m_pl][0]raceinfo 1, [m_pl][1]raceinfo 2, [m_pl][2]race started msg line1, [m_]pl[3]line2, [m_pl][4]line3
88
89
//race vars
90
new race_editor[5];		//editor vars [0]->cp id, [1]->(0)editor free,(1) editor in use, [2]->checkpoint counter, [3]->playerid of the player using the editor, [4]->(0)cp placing disabled, (1)cp placing spawn, (2)cp placing race cps
91
new race_count = 0;		//race counter
92
new race[MAX_PLAYERS+1][3];			//race values
93
/*
94
[playerid][0] -> cp id
95
[playerid][1] -> passed cp
96
[playerid][2] -> player joined race
97
[MAX_PLAYERS][0] -> joins
98
[MAX_PLAYERS][1] -> race initialized
99
[MAX_PLAYERS][2] -> race started
100
*/
101
new rid = 0; //raceid
102
new rname[MAX_RACES + 1][64];		//race name
103
new rfilename[MAX_RACES + 1][64];	//race filename
104
new Float:rcp[MAX_RACES + 1][MAX_CPS + 1][5]; /*
105
rcp[raceID][checkpoint][vars]
106
107
[rid][checkpoint][0] -> x-koord (float)
108
[rid][checkpoint][1] -> y-koord (float)
109
[rid][checkpoint][2] -> z-koord (float)
110
[rid][checkpoint][3] -> how many players passed this cp (floatround)
111
[rid][checkpoint][4] -> parameters
112
113
[rid][0][4] -> cp diameter (float)
114
[rid][1][4] -> cp type (floatround)
115
[rid][2][4] -> number of cps (floatround)
116
[rid][3][4] -> world id (floatround)
117
[rid][4][4] -> max participants (floatround)
118
[rid][5][4] -> needed vehicle(0=no vehicle needed; 1=land vehicle; 2=car; 3=motorbike; 4=truck; 5=plane; 6=helicopter; 7=boat; 8=bike) (floatround)
119
[rid][6][4] -> future functions(unused atm)
120
[rid][7][4] -> future functions(unused atm)
121
[rid][8][4] -> future functions(unused atm)
122
[rid][9][4] -> future functions(unused atm)
123
[rid][MAX_CPS][0] -> enter spawn X (float)
124
[rid][MAX_CPS][1] -> enter spawn Y (float)
125
[rid][MAX_CPS][2] -> enter spawn Z (float)
126
[MAX_RACES][][]....-> Race Editor
127
*/
128
new rmapicons[MAX_PLAYERS];		//display mapicons for next cp, just in case the cp is to far away to be shown on minimap
129
130
public OnFilterScriptInit()
131
{
132
	printf("++++++++++++++++++++++++");
133
	printf("+       fs_race        +");
134
	printf("+   race filterscript  +");
135
	printf("+    v1.1 by Flovv     +");
136
	printf("++++++++++++++++++++++++\n");
137
	LoadRaces();
138
	InitTextdraws();
139
	race_editor[3] = -1;
140
	//initialize race autostart default values
141
	autotimer[2] = 30;
142
	autotimer[4] = 5;
143
	autotimer[6] = 15;
144
	return 1;
145
	
146
}
147
148
public OnFilterScriptExit()
149
{
150
	DestroyTextdraws();
151
	return 1;
152
}
153
154
//*************************************************************
155
//************************ commands ***************************
156
//*************************************************************
157
158
public OnPlayerCommandText(playerid, cmdtext[])
159
{
160
	if(PlayerIsAdmin(playerid))
161
	{
162
		dcmd(start, 5, cmdtext);			//start race
163
		dcmd(end, 3,  cmdtext);				//end race
164
		dcmd(reload, 6, cmdtext);			//reload races
165
	}
166
	dcmd(race, 4, cmdtext);				//enter race
167
	dcmd(exit, 4, cmdtext);					//exit race
168
	return 0;
169
}
170
171
dcmd_start(playerid, params[])		//start race
172
{
173
	new sel[32];
174
	if(sscanf(params, "s[32]", sel))		//start race
175
	{
176
		SendClientMessage(playerid, 0xFF0000FF, "SERVER: /start race		?????");
177
	}
178
	else if(!strcmp(sel, "race", true))		//initialize race
179
	{
180
		if(autotimer[0] == 1) return SendClientMessage(playerid, 0xFF0000FF, "ERROR: Not possible with autostart enabled");
181
		if(race[MAX_PLAYERS][1]==1)
182
		{
183
			race[MAX_PLAYERS][1]=0;		//set race status from "initilized"
184
			race[MAX_PLAYERS][2]=1;		//to "running"
185
			CreateFirstCP();
186
			timer = SetTimerEx("Countdown", 1000, true, "i", scount);
187
		}
188
		else if(race[MAX_PLAYERS][2]==1) SendClientMessage(playerid, 0xFF0000FF, "SERVER: Race already started.");
189
		else
190
		{
191
			if(race_count == 0) SendClientMessage(playerid, 0xFF0000FF, "SERVER: No races found! Check your race folder or create/import races.");
192
			else
193
			{
194
				new race_sel[MAX_RACES * 64];		//63 char limitation to race name
195
				new race_ins[64];
196
				for(new i = 0; i < race_count; i++)		//read race names and creat race selection dialog
197
				{
198
					format(race_ins, sizeof(race_ins), "%s\r\n",rname[i]);
199
					strins(race_sel, race_ins, strlen(race_sel));
200
				}
201
				ShowPlayerDialog(playerid,2201,DIALOG_STYLE_LIST,"Select Race",race_sel,"Start", "Cancel");
202
			}
203
		}
204
	}
205
	return 1;
206
}
207
208
dcmd_reload(playerid,params[])
209
{
210
	new sel[32];
211
	if(sscanf(params, "s[32]", sel))
212
	{
213
		SendClientMessage(playerid, 0xFF0000FF, "SERVER: /reload races		???");
214
	}
215
	else if(!strcmp(sel, "races"))
216
	{
217
		if(LoadRaces() != 1)
218
		{
219
			SendClientMessage(playerid, 0xFF0000FF, "SERVER: Error loading race files.");
220
			SendClientMessage(playerid, 0xFF0000FF, "See logfile for detailled information.");
221
		}
222
		else SendClientMessage(playerid, 0xFF0000FF, "SERVER: Racefiles reloaded.");
223
	}
224
	return 1;
225
}
226
227
dcmd_end(playerid,params[])		//cancel race
228
{
229
	new par[64];
230
	if(sscanf(params, "s[64]", par))
231
	{
232
		if(race_editor[1] == 1) SendClientMessage(playerid, 0xFF0000FF, "SERVER: Race Editor running. Type /end redit to close");
233
		if(race[MAX_PLAYERS][1] + race[MAX_PLAYERS][2] != 0) SendClientMessage(playerid, 0xFF0000FF, "SERVER: Race running. Type /end race to close");
234
	}
235
	else if(!strcmp(par, "redit"))
236
	{
237
		if(race_editor[1] == 1) 
238
		{
239
			RaceEditorClose(playerid);
240
			SendClientMessage(playerid, 0xFF0000FF, "SERVER: Race Editor closed.");
241
		}
242
		else SendClientMessage(playerid, 0xFF0000FF, "ERROR: Race Editor not running");
243
	}
244
	else if(!strcmp(par, "race"))
245
	{
246
		if(race[MAX_PLAYERS][1] + race[MAX_PLAYERS][2] != 0)
247
		{
248
			if(autotimer[0] == 1) return SendClientMessage(playerid, 0xFF0000FF, "ERROR: Not possible with autostart enabled");
249
			for (new i = 0; i < MAX_PLAYERS; i++)
250
			{
251
				if(race[i][2] == 1)		//kick players out of race
252
				{
253
					SetKoords(i);
254
					noveh[i] = false;
255
					RemovePlayerMapIcon(i, rmapicons[i]);
256
					SendClientMessage(i, 0xFF0000FF, "SERVER: This race was closed!");
257
				}
258
			}
259
			EndRace();
260
			SendClientMessage(playerid, 0xFF0000FF, "SERVER: The race was closed!");
261
		}
262
		else SendClientMessage(playerid, 0xFF0000FF, "ERROR: No race running.");
263
	}
264
	return 1;
265
}
266
267
dcmd_race(playerid, params[])		//join race
268
{
269
	new par[64];
270
	if(sscanf(params, "s[64]", par))
271
	{
272
		EnterRace(playerid);
273
	}
274
	else if(!strcmp(par, "editor"))		//start editor
275
	{
276
		if(race_editor[1] == 0)
277
		{
278
			race_editor[1] = 1;
279
			race_editor[3] = playerid;
280
			RaceEditor1(playerid);
281
		}
282
		else SendClientMessage(playerid, 0xFF0000, "SERVER: Editor allready in use.");
283
	}
284
	else if(!strcmp(par, "settings") && PlayerIsAdmin(playerid))
285
	{
286
		RaceSettings(playerid);
287
	}
288
	else if(PlayerIsAdmin(playerid)) SendClientMessage(playerid, 0xFF0000FF, "SERVER: Use /race settings to edit races");
289
	else SendClientMessage(playerid, 0xFF0000FF, "This command doesn't have parameters.");
290
	return 1;
291
}
292
293
dcmd_exit(playerid, params[])		//exit race
294
{
295
	if(!strcmp(params, ""))
296
	{
297
		if(race[playerid][2] == 1) ExitRace(playerid);
298
		else SendClientMessage(playerid, 0xFF0000FF, "SERVER: You are not in any race.");
299
	}
300
	else
301
	{
302
		SendClientMessage(playerid, 0xFF0000FF, "This command doesn't have parameters.");
303
	}
304
	return 1;
305
}
306
307
//************************************************************
308
//*********************** dialogs ****************************
309
//************************************************************
310
311
public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[])
312
{
313
	switch(dialogid) // dialogid
314
	{
315
		case 2201:		// initialize race
316
		{
317
			if(!response) return 1; // cancel
318
319
			rid = listitem;		//set race ID
320
			race[MAX_PLAYERS][1] = 1;	//race initialized
321
			ShowRaceStartedMsg(10);
322
			race[MAX_PLAYERS][0] = 0;
323
			spawnarea = CreateDynamicCircle(rcp[rid][MAX_CPS][0], rcp[rid][MAX_CPS][1], 55.0, floatround(rcp[rid][3][4]));		//create race start boundaries
324
		}
325
		//case 2241-2255 -> Race Editor
326
		case 2202:	//set vehicle
327
		{
328
			if(race_editor[1] == 0) return 1;
329
			if(!response) 
330
			{
331
				RaceEditorClose(playerid);
332
				return 1; // cancel
333
			}
334
			rcp[MAX_RACES][5][4] = listitem;
335
			if(listitem == 5 || listitem == 6 || listitem == 7) rcp[MAX_RACES][1][4] = 3.0;	//cp type air
336
			else rcp[MAX_RACES][1][4] = 0.0;		//cp type normal
337
			RaceEditor2(playerid);
338
		}
339
		case 2203:	//cp diameter
340
		{
341
			if(race_editor[1] == 0) return 1;
342
			if(!response)
343
			{
344
				//DestroyDynamicRaceCP(race_editor[0]);
345
				DisablePlayerRaceCheckpoint(playerid);
346
				RaceEditor1(playerid);
347
			}
348
			else if(listitem == 0)
349
			{
350
				rcp[MAX_RACES][0][4] += 0.5;
351
				//DestroyDynamicRaceCP(race_editor[0]);
352
				DisablePlayerRaceCheckpoint(playerid);
353
				RaceEditor2(playerid);
354
			}
355
			else if(listitem == 1)
356
			{
357
				rcp[MAX_RACES][0][4] -= 0.5;
358
				//DestroyDynamicRaceCP(race_editor[0]);
359
				DisablePlayerRaceCheckpoint(playerid);
360
				RaceEditor2(playerid);
361
			}
362
			else
363
			{
364
				//DestroyDynamicRaceCP(race_editor[0]);
365
				DisablePlayerRaceCheckpoint(playerid);
366
				RaceEditor3(playerid);
367
			}
368
		}
369
		case 2204:	//max. participants
370
		{
371
			if(race_editor[1] == 0) return 1;
372
			new part = 0;
373
			if(!response) RaceEditor2(playerid);
374
			else if(sscanf(inputtext, "d", part)) 
375
			{
376
				SendClientMessage(playerid, 0xFF0000FF, "SERVER: Please enter a valid number!");
377
				RaceEditor3(playerid);
378
			}
379
			else
380
			{
381
				rcp[MAX_RACES][4][4] = float(part);
382
				RaceEditor4(playerid);
383
			}
384
		}
385
		case 2205:	//virtual world
386
		{
387
			if(race_editor[1] == 0) return 1;
388
			new vworld = 0;
389
			if(!response) RaceEditor3(playerid);
390
			else if(sscanf(inputtext, "d", vworld)) 
391
			{
392
				SendClientMessage(playerid, 0xFF0000FF, "SERVER: Please enter a valid number!");
393
				RaceEditor4(playerid);
394
			}
395
			else
396
			{
397
				if(vworld < 0)
398
				{
399
					SendClientMessage(playerid, 0xFF0000FF, "SERVER: Please enter a valid number!");
400
					RaceEditor4(playerid);
401
				}
402
				else
403
				{
404
					rcp[MAX_RACES][3][4] = float(vworld);
405
					SetVehicleVirtualWorld(GetPlayerVehicleID(playerid),vworld);
406
					SetPlayerVirtualWorld(playerid,vworld);
407
					RaceEditor5(playerid);
408
				}
409
			}
410
		}
411
		case 2206:	//set checkpoints
412
		{
413
			if(race_editor[1] == 0) return 1;
414
			if(!response) RaceEditor4(playerid);
415
			else race_editor[4] = 1;
416
			return 1;
417
		}
418
		case 2207:	//race name
419
		{
420
			if(race_editor[1] == 0) return 1;
421
			if(!response) 
422
			{
423
				RaceEditorClose(playerid);
424
				return 1; // cancel
425
			}
426
			else
427
			{
428
				new check[64];
429
				if(sscanf(inputtext,"s[64]",check))
430
				{
431
					SendClientMessage(playerid, 0xFF0000FF, "SERVER: Please enter a valid Race name!");
432
					RaceEditor6(playerid);
433
				}
434
				else
435
				{
436
					format(rname[MAX_RACES], sizeof(rname[]), "%s", inputtext);
437
					RaceEditor7(playerid);
438
				}
439
			}
440
		}
441
		case 2208:	//save
442
		{
443
			if(race_editor[1] == 0) return 1;
444
			if(!response) RaceEditor6(playerid);
445
			else RacefileCheck(playerid);
446
		}
447
		case 2209:	//overwrite
448
		{
449
			if(race_editor[1] == 0) return 1;
450
			if(!response) RaceEditor7(playerid);
451
			else RaceToFile(playerid);
452
		}
453
		case 2210:	//race settings
454
		{
455
			if(!response) return 1;		//cancel
456
			switch(listitem)
457
			{
458
				case 0:		//delete races
459
				{
460
					if(!response) RaceSettings(playerid);
461
					else
462
					{
463
						new race_sel[MAX_RACES * 64];		//63 char limitation to race name
464
						new race_ins[64];
465
						for(new i = 0; i < race_count; i++)		//read race names and creat race selection dialog
466
						{
467
							format(race_ins, sizeof(race_ins), "%s (%s)\r\n",rname[i],rfilename[i]);
468
							strins(race_sel, race_ins, strlen(race_sel));
469
						}
470
						ShowPlayerDialog(playerid,2211,DIALOG_STYLE_LIST,"Select Race",race_sel,"Delete", "Cancel");
471
					}
472
				}
473
				case 1:		//cp autorepair
474
				{
475
					if(cprepair) cprepair = false;
476
					else cprepair = true;
477
					RaceSettings(playerid);
478
				}
479
				case 2:		//start countdown
480
				{
481
					ShowPlayerDialog(playerid, 2213, DIALOG_STYLE_INPUT, "start countdown", "Please enter a start countdown (seconds)", "Ok", "Cancel");
482
				}
483
				case 3:		//back to veh countdown
484
				{
485
					ShowPlayerDialog(playerid, 2214, DIALOG_STYLE_INPUT, "return countdown", "Please enter a \"back to vehicle\" countdown (seconds)", "Ok", "Cancel");
486
				}
487
				case 4:		//start freeze
488
				{
489
					if(sfreeze) sfreeze = false;
490
					else sfreeze = true;
491
					RaceSettings(playerid);
492
				}
493
				case 5:		//autostart
494
				{
495
					if(race[MAX_PLAYERS][1] + race[MAX_PLAYERS][2] == 0)
496
					{
497
						if(autotimer[0] == 1)
498
						{
499
							autotimer[0] = 0;
500
							KillTimer(autotimer[1]);
501
						}
502
						else 
503
						{
504
							autotimer[0] = 1;
505
							if(race_count == 0)
506
							{
507
								SendClientMessage(playerid, 0xFF0000FF, "SERVER: No races found! Check your race folder or create/import races.");
508
								autotimer[0] = 0;
509
							}
510
							else AutoStart1();
511
						}
512
					}
513
					else SendClientMessage(playerid, 0xFF0000FF, "SERVER: Please wait till the current race is over.");
514
					RaceSettings(playerid);
515
				}
516
				case 6:		//autostart time
517
				{
518
					ShowPlayerDialog(playerid, 2215, DIALOG_STYLE_INPUT, "Autostart Time", "Please enter an autostart interval (minutes)", "Ok", "Cancel");
519
				}
520
				case 7:		//join time
521
				{
522
					ShowPlayerDialog(playerid, 2216, DIALOG_STYLE_INPUT, "Join Time", "Please enter a join time (minutes)", "Ok", "Cancel");
523
				}
524
				case 8:		//autoend time
525
				{
526
					ShowPlayerDialog(playerid, 2217, DIALOG_STYLE_INPUT, "Autoend Time", "Please enter an autoend time (minutes)", "Ok", "Cancel");
527
				}
528
			}
529
		}
530
		case 2211:	//delete races confirm
531
		{
532
			if(!response) RaceSettings(playerid);
533
			else
534
			{
535
				drace = listitem;
536
				new msg[128];
537
				format(msg, sizeof(msg), "Really delete\r\n %s (%s)\r\n???", rfilename[drace], rname[drace]);
538
				ShowPlayerDialog(playerid, 2212, DIALOG_STYLE_MSGBOX, "{FF0000}DELETE", msg, "Delete", "Cancel");
539
			}
540
		}
541
		case 2212:	//delete
542
		{
543
			if(!response) RaceSettings(playerid);
544
			else if(fremove(rfilename[drace]))
545
			{
546
				new msg[128];
547
				format(msg, sizeof(msg), "SERVER: %s (%s) succesfully deleted.", rfilename[drace], rname[drace]);
548
				printf("Racefile ..%s deleted", rfilename[drace]);
549
				SendClientMessage(playerid, 0xFF0000FF, msg);
550
				LoadRaces();
551
			}
552
			else
553
			{
554
				new msg[128];
555
				format(msg, sizeof(msg), "ERROR: %s (%s) could not be deleted.", rfilename[drace], rname[drace]);
556
				SendClientMessage(playerid, 0xFF0000FF, msg);
557
			}
558
		}
559
		case 2213:	//start countdown
560
		{
561
			if(!response) RaceSettings(playerid);
562
			else
563
			{
564
				if(sscanf(inputtext, "d", scount)) SendClientMessage(playerid, 0xFF0000FF, "ERROR: Please use a valid time.");
565
			}
566
			RaceSettings(playerid);
567
		}
568
		case 2214:	//back to veh countdown
569
		{
570
			if(!response) RaceSettings(playerid);
571
			else
572
			{
573
				if(sscanf(inputtext, "d", rettime)) SendClientMessage(playerid, 0xFF0000FF, "ERROR: Please use a valid time.");
574
			}
575
			RaceSettings(playerid);
576
		}
577
		case 2215:	//autostart time
578
		{
579
			if(!response) RaceSettings(playerid);
580
			else
581
			{
582
				if(sscanf(inputtext, "d", autotimer[2])) SendClientMessage(playerid, 0xFF0000FF, "ERROR: Please use a valid time.");
583
			}
584
			RaceSettings(playerid);
585
		}
586
		case 2216:	//join time
587
		{
588
			if(!response) RaceSettings(playerid);
589
			else
590
			{
591
				if(sscanf(inputtext, "d", autotimer[4])) SendClientMessage(playerid, 0xFF0000FF, "ERROR: Please use a valid time.");
592
			}
593
			RaceSettings(playerid);
594
		}
595
		case 2217:	//autoend time
596
		{
597
			if(!response) RaceSettings(playerid);
598
			else
599
			{
600
				if(sscanf(inputtext, "d", autotimer[6])) SendClientMessage(playerid, 0xFF0000FF, "ERROR: Please use a valid time.");
601
			}
602
			RaceSettings(playerid);
603
		}
604
	}
605
	return 0;
606
}
607
608
//***************************************************************************
609
//******************** textdraw related functions ***************************
610
//***************************************************************************
611
612
InitTextdraws()		//the info and announcement textdraws
613
{
614
	textdraws[MAX_PLAYERS][0] = TextDrawCreate(320.0, 10.0, ".");
615
	ftextdraw(textdraws[MAX_PLAYERS][0], 2);
616
	textdraws[MAX_PLAYERS][1] = TextDrawCreate(320.0, 20.0, ".");
617
	ftextdraw(textdraws[MAX_PLAYERS][1], 2);
618
	textdraws[MAX_PLAYERS][2] = TextDrawCreate(320.0, 100.0, ".");
619
	ftextdraw(textdraws[MAX_PLAYERS][2], 1);
620
	textdraws[MAX_PLAYERS][3] = TextDrawCreate(320.0, 140.0, ".");
621
	ftextdraw(textdraws[MAX_PLAYERS][3], 1);
622
	textdraws[MAX_PLAYERS][4] = TextDrawCreate(320.0, 180.0, ".");
623
	ftextdraw(textdraws[MAX_PLAYERS][4], 1);
624
	return 1;
625
}
626
627
DestroyTextdraws()
628
{
629
	TextDrawHideForAll(textdraws[MAX_PLAYERS][0]);
630
	TextDrawDestroy(textdraws[MAX_PLAYERS][0]);
631
	TextDrawHideForAll(textdraws[MAX_PLAYERS][1]);
632
	TextDrawDestroy(textdraws[MAX_PLAYERS][1]);
633
	TextDrawHideForAll(textdraws[MAX_PLAYERS][2]);
634
	TextDrawDestroy(textdraws[MAX_PLAYERS][2]);
635
	TextDrawHideForAll(textdraws[MAX_PLAYERS][3]);
636
	TextDrawDestroy(textdraws[MAX_PLAYERS][3]);
637
	TextDrawHideForAll(textdraws[MAX_PLAYERS][4]);
638
	TextDrawDestroy(textdraws[MAX_PLAYERS][4]);
639
	return 1;
640
}
641
642
ShowRaceStartedMsg(time)
643
{
644
	TextDrawSetString(textdraws[MAX_PLAYERS][2], rname[rid]);
645
	TextDrawSetString(textdraws[MAX_PLAYERS][3], "started");
646
	TextDrawSetString(textdraws[MAX_PLAYERS][4], "join with /race");
647
	TextDrawShowForAll(textdraws[MAX_PLAYERS][2]);
648
	TextDrawShowForAll(textdraws[MAX_PLAYERS][3]);
649
	TextDrawShowForAll(textdraws[MAX_PLAYERS][4]);
650
	SetTimer("HideRaceStartedMsg", 1000 * time, false);
651
	return 1;
652
}
653
654
public HideRaceStartedMsg()
655
{
656
	TextDrawHideForAll(textdraws[MAX_PLAYERS][2]);
657
	TextDrawHideForAll(textdraws[MAX_PLAYERS][3]);
658
	TextDrawHideForAll(textdraws[MAX_PLAYERS][4]);
659
	ShowRaceInfo();
660
	return 1;
661
}
662
663
ShowRaceInfo()
664
{
665
	new msg[128];
666
	format(msg, sizeof(msg), "%s started", rname[rid]);
667
	TextDrawSetString(textdraws[MAX_PLAYERS][0], msg);
668
	TextDrawSetString(textdraws[MAX_PLAYERS][1], "Join with /race");
669
	TextDrawShowForAll(textdraws[MAX_PLAYERS][0]);
670
	TextDrawShowForAll(textdraws[MAX_PLAYERS][1]);
671
	return 1;
672
}
673
674
HideRaceInfo()
675
{
676
	TextDrawHideForAll(textdraws[MAX_PLAYERS][0]);
677
	TextDrawHideForAll(textdraws[MAX_PLAYERS][1]);
678
	return 1;
679
}
680
681
public Countdown(delay)  //race Countdown
682
{
683
	if(count == delay)
684
	{
685
		TextDrawSetString(textdraws[MAX_PLAYERS][3], "GO!");
686
		KillTimer(timer);
687
		count = 0;
688
		freeze = false;
689
		SetTimer("HideCountdown", 3000, false);
690
	}
691
	else
692
	{
693
		new string[4];
694
		format(string, sizeof(string), "%d", delay - count);
695
		if(count == 0)
696
		{
697
			TextDrawSetString(textdraws[MAX_PLAYERS][3], string);
698
			for (new i = 0; i < MAX_PLAYERS; i++)
699
			{
700
				if(race[i][2] == 1)
701
				{
702
					TextDrawShowForPlayer(i, textdraws[MAX_PLAYERS][3]);
703
				}
704
			}
705
		}
706
		TextDrawSetString(textdraws[MAX_PLAYERS][3], string);
707
		count++;
708
	}
709
	return 1;
710
}
711
712
public HideCountdown()
713
{
714
	TextDrawHideForAll(textdraws[MAX_PLAYERS][3]);
715
	return 1;
716
}
717
718
ShowPlayerFinishMsg(playerid)
719
{
720
	new position = floatround(rcp[rid][(race[playerid][1] - 1)][3]);
721
	switch(position)
722
	{
723
		case 1:
724
		{
725
			winmsg = true;
726
			new pName[MAX_PLAYER_NAME];
727
			GetPlayerName(playerid, pName, MAX_PLAYER_NAME);
728
			textdraws[playerid][2] = TextDrawCreate(320.0, 100.0, pName);
729
			ftextdraw(textdraws[playerid][2],1);
730
			textdraws[playerid][3] = TextDrawCreate(320.0, 140.0, "] won the race ]");
731
			ftextdraw(textdraws[playerid][3],1);
732
			textdraws[playerid][4] = TextDrawCreate(320.0, 180.0, "] You ] won ]");
733
			ftextdraw(textdraws[playerid][4],1);
734
			TextDrawShowForAll(textdraws[playerid][2]);
735
			TextDrawShowForAll(textdraws[playerid][3]);
736
			TextDrawHideForPlayer(playerid, textdraws[playerid][2]);
737
			TextDrawHideForPlayer(playerid, textdraws[playerid][3]);
738
			TextDrawShowForPlayer(playerid, textdraws[playerid][4]);
739
			SetTimerEx("HideWinMsg", 3000, false, "d", playerid);
740
		}
741
		case 2:
742
		{
743
			new pName[MAX_PLAYER_NAME];
744
			GetPlayerName(playerid, pName, MAX_PLAYER_NAME);
745
			textdraws[playerid][2] = TextDrawCreate(320.0, 100.0, pName);
746
			ftextdraw(textdraws[playerid][2],1);
747
			textdraws[playerid][3] = TextDrawCreate(320.0, 140.0, "] placed 2nd ]");
748
			ftextdraw(textdraws[playerid][3],1);
749
			textdraws[playerid][4] = TextDrawCreate(320.0, 180.0, "you placed 2nd");
750
			ftextdraw(textdraws[playerid][4],1);
751
			if(!winmsg)
752
			{
753
				winmsg = true;
754
				TextDrawShowForAll(textdraws[playerid][2]);
755
				TextDrawShowForAll(textdraws[playerid][3]);
756
				TextDrawHideForPlayer(playerid, textdraws[playerid][2]);
757
				TextDrawHideForPlayer(playerid, textdraws[playerid][3]);
758
				SetTimerEx("HideWinMsg", 3000, false, "d", playerid);
759
			}
760
			else SetTimerEx("ShowPlayerFinishMsgDelayed", 500, false, "d", playerid);
761
			TextDrawShowForPlayer(playerid, textdraws[playerid][4]);
762
		}
763
		case 3:
764
		{
765
			new pName[MAX_PLAYER_NAME];
766
			GetPlayerName(playerid, pName, MAX_PLAYER_NAME);
767
			textdraws[playerid][2] = TextDrawCreate(320.0, 100.0, pName);
768
			ftextdraw(textdraws[playerid][2],1);
769
			textdraws[playerid][3] = TextDrawCreate(320.0, 140.0, "] placed 3rd ]");
770
			ftextdraw(textdraws[playerid][3],1);
771
			textdraws[playerid][4] = TextDrawCreate(320.0, 180.0, "you placed 3rd");
772
			ftextdraw(textdraws[playerid][4],1);
773
			if(!winmsg)
774
			{
775
				winmsg = true;
776
				TextDrawShowForAll(textdraws[playerid][2]);
777
				TextDrawShowForAll(textdraws[playerid][3]);
778
				TextDrawHideForPlayer(playerid, textdraws[playerid][2]);
779
				TextDrawHideForPlayer(playerid, textdraws[playerid][3]);
780
				SetTimerEx("HideWinMsg", 3000, false, "d", playerid);
781
			}
782
			else SetTimerEx("ShowPlayerFinishMsgDelayed", 1000, false, "d", playerid);
783
			TextDrawShowForPlayer(playerid, textdraws[playerid][4]);
784
		}
785
		default :
786
		{
787
			new string[32];
788
			format(string, sizeof(string), "You placed %dth", position);
789
			textdraws[playerid][4] = TextDrawCreate(320.0, 180.0, string);
790
			ftextdraw(textdraws[playerid][4],1);
791
			TextDrawShowForPlayer(playerid, textdraws[playerid][4]);
792
		}
793
	}
794
	SetTimerEx("HidePlayerFinishMsg", 3000, false, "d", playerid);
795
	return 1;
796
}
797
798
public ShowPlayerFinishMsgDelayed(playerid)
799
{
800
	if(winmsg) SetTimerEx("ShowPlayerFinishMsgDelayed", 500, false, "d", playerid);
801
	else
802
	{
803
		winmsg = true;
804
		TextDrawShowForAll(textdraws[playerid][2]);
805
		TextDrawShowForAll(textdraws[playerid][3]);
806
		TextDrawHideForPlayer(playerid, textdraws[playerid][2]);
807
		TextDrawHideForPlayer(playerid, textdraws[playerid][3]);
808
		SetTimerEx("HideWinMsg", 3000, false, "d", playerid);
809
	}
810
	return 1;
811
}
812
813
public HideWinMsg(playerid)
814
{
815
	TextDrawHideForAll(textdraws[playerid][2]);
816
	TextDrawHideForAll(textdraws[playerid][3]);
817
	TextDrawDestroy(textdraws[playerid][2]);
818
	TextDrawDestroy(textdraws[playerid][3]);
819
	winmsg = false;
820
	return 1;
821
}
822
823
public HidePlayerFinishMsg(playerid)
824
{
825
	TextDrawHideForPlayer(playerid, textdraws[playerid][4]);
826
	TextDrawDestroy(textdraws[playerid][4]);
827
	return 1;
828
}
829
830
ftextdraw(Text:drawID, style)
831
{
832
	switch(style)
833
	{
834
		case 0:				//checkpoint & pos racing style
835
		{
836
			TextDrawFont(drawID, 1);
837
			TextDrawAlignment(drawID, 2);
838
			TextDrawColor(drawID, 0xFF0000FF);
839
			TextDrawSetOutline(drawID, 1);
840
			TextDrawSetShadow(drawID, 0);
841
			TextDrawTextSize(drawID, 60, 170);
842
			TextDrawSetProportional(drawID, 1);
843
		}
844
		case 1:			//race enter & finish style
845
		{
846
			TextDrawAlignment(drawID, 2);
847
			TextDrawColor(drawID, 0xFF0000FF);
848
			TextDrawSetOutline(drawID, 1);
849
			TextDrawSetShadow(drawID, 0);
850
			TextDrawFont(drawID, 2);
851
			TextDrawLetterSize(drawID,0.8, 2.4);
852
			TextDrawSetProportional(drawID, 1);
853
		}
854
		case 2:		//race info style
855
		{
856
			TextDrawAlignment(drawID, 2);
857
			TextDrawColor(drawID, 0xFF0000FF);
858
			TextDrawSetOutline(drawID, 1);
859
			TextDrawSetShadow(drawID, 0);
860
			TextDrawFont(drawID, 2);
861
			TextDrawLetterSize(drawID, 0.4, 1.2);
862
			TextDrawSetProportional(drawID, 1);
863
		}
864
	}
865
	return 1;
866
}
867
868
public GetBack(playerid)		//get back to your car
869
{
870
	new string[4];
871
	format(string, sizeof(string), "%d", rettime - exitcounter[playerid]);
872
	if(exitcounter[playerid] == 0)
873
	{
874
		noveh[playerid] = true;
875
		textdraws[playerid][2] = TextDrawCreate(320.0, 100.0, "Get back to");
876
		ftextdraw(textdraws[playerid][2],1);
877
		textdraws[playerid][3] = TextDrawCreate(320.0, 140.0, "your vehicle");
878
		ftextdraw(textdraws[playerid][3],1);
879
		textdraws[playerid][4] = TextDrawCreate(320.0, 180.0, string);
880
		ftextdraw(textdraws[playerid][4],1);
881
		TextDrawShowForPlayer(playerid, textdraws[playerid][2]);
882
		TextDrawShowForPlayer(playerid, textdraws[playerid][3]);
883
		TextDrawShowForPlayer(playerid, textdraws[playerid][4]);
884
	}
885
	else TextDrawSetString(textdraws[playerid][4], string);
886
	exitcounter[playerid]++;
887
	if(exitcounter[playerid] - 1 == rettime)
888
	{
889
		ExitRace(playerid);
890
	}
891
	if(!noveh[playerid])
892
	{
893
		TextDrawHideForPlayer(playerid, textdraws[playerid][2]);
894
		TextDrawHideForPlayer(playerid, textdraws[playerid][3]);
895
		TextDrawHideForPlayer(playerid, textdraws[playerid][4]);
896
		TextDrawDestroy(textdraws[playerid][2]);
897
		TextDrawDestroy(textdraws[playerid][3]);
898
		TextDrawDestroy(textdraws[playerid][4]);
899
		exitcounter[playerid] = 0;
900
		KillTimer(exittimer[playerid]);
901
	}
902
	return 1;
903
}
904
905
ShowTimeRemaining()		//displays the time left to race start
906
{
907
	new msg[32];
908
	format(msg, sizeof(msg), "race starts in %d min", autotimer[4] - autotimer[5]);
909
	TextDrawSetString(textdraws[MAX_PLAYERS][3], msg);
910
	TextDrawShowForAll(textdraws[MAX_PLAYERS][3]);
911
	SetTimer("HideTimeRemaining", 3000, false);
912
	return 1;
913
}
914
915
public HideTimeRemaining()
916
{
917
	TextDrawHideForAll(textdraws[MAX_PLAYERS][3]);
918
	return 1;
919
}
920
921
//***************************************************************************
922
//***************************** joining the race ****************************
923
//***************************************************************************
924
925
EventCheck(playerid,vehtype)  //see if the player has the right vehicle
926
{
927
	if(vehtype == 0) return 1;		//no veh needed
928
	else
929
	{
930
		switch(GetVehicleModel(GetPlayerVehicleID(playerid)))
931
		{
932
			//cars
933
			case 400, 401, 402, 404, 405, 409, 410, 411, 412, 413, 415, 416, 418, 419, 420, 421, 422, 424, 426, 429, 434, 436, 438,
934
				 439, 440, 442, 445, 451, 458, 459, 466, 467, 470, 474, 475, 477, 478, 479, 480, 482, 483, 489, 490, 491, 492, 494,
935
				 495, 496, 500, 502, 503, 504, 505, 506, 507, 516, 517, 518, 525, 526, 527, 528, 529, 531, 533, 534, 535, 536, 540,
936
				 541, 542, 543, 545, 546, 547, 549, 550, 551, 552, 554, 555, 556, 557, 558, 559, 560, 561, 562, 565, 567, 568, 571,
937
				 572, 573, 574, 575, 576, 579, 580, 582, 583, 585, 587, 589, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605 : 
938
			{
939
				if(vehtype == 1) return 1;		// motorbikes, trucks, cars
940
				else if(vehtype == 2) return 1;    //  cars
941
				else return 0;		//wrong veh
942
			}
943
			//motorbikes
944
			case 462, 448, 581, 522, 461, 521, 523, 463, 586, 468, 471 :
945
			{
946
				if(vehtype == 1) return 1;		// bikes, trucks, cars
947
				else if(vehtype == 3) return 1;		// bikes
948
				else return 0;		//wrong veh
949
			}
950
			//trucks
951
			case 403, 406, 407, 408, 414, 427, 431, 433, 437, 443, 455, 456, 498, 514, 515, 524, 544, 578, 609, 423, 428, 508, 588 :
952
			{
953
				if(vehtype == 1) return 1;		// bikes, trucks, cars
954
				else if(vehtype == 4) return 1;		// trucks
955
				else return 0;		//wrong veh
956
			}
957
			//planes
958
			case 460, 476, 511, 512, 513, 519, 553, 593 :
959
			{
960
				if(vehtype == 5) return 1;		// planes
961
				else return 0;		//wrong veh
962
			}
963
			//helis
964
			case 548, 417, 487, 488, 497, 563, 469 :
965
			{
966
				if(vehtype == 6) return 1;		// heli
967
				else return 0;		//wrong veh
968
			}
969
			//boats
970
			case 472, 473, 493, 595, 484, 430, 453, 452, 446, 454 :
971
			{
972
				if(vehtype == 7) return 1;		// boat
973
				else return 0;		//wrong veh
974
			}
975
			//bikes
976
			case 509, 481, 510 :
977
			{
978
				if(vehtype == 8) return 1;		// bikes
979
				else return 0;		//wrong veh
980
			}
981
			default : return 0;
982
		}
983
	}
984
	return 1;
985
}
986
987
WVehicleMsg(playerid,vehtype)		//errormessage for wrong veh
988
{
989
	switch(vehtype)
990
	{
991
		case 1:{SendClientMessage(playerid, 0xFF0000FF, "SERVER: You need a land vehicle to enter! (Car/Bike/Truck)");}
992
		case 2:{SendClientMessage(playerid, 0xFF0000FF, "SERVER: You need a car to enter! (better use a fast one)");}
993
		case 3:{SendClientMessage(playerid, 0xFF0000FF, "SERVER: You need a motorbike to enter! (better use a fast one)");}
994
		case 4:{SendClientMessage(playerid, 0xFF0000FF, "SERVER: You need a truck to enter!");}
995
		case 5:{SendClientMessage(playerid, 0xFF0000FF, "SERVER: You need a plane to enter! (No hydra/at400/andromeda)");}
996
		case 6:{SendClientMessage(playerid, 0xFF0000FF, "SERVER: You need a helicopter to enter! (No hunter/seasparrow)");}
997
		case 7:{SendClientMessage(playerid, 0xFF0000FF, "SERVER: You need a boat to enter!");}
998
		case 8:{SendClientMessage(playerid, 0xFF0000FF, "SERVER: You need a bike to enter!");}
999
	}
1000
	return 1;
1001
}
1002
1003
EnterRace(playerid)		//enter a race
1004
{
1005
	if(race[MAX_PLAYERS][1]==1)
1006
	{
1007
		if(race[playerid][2] == 1)
1008
		{
1009
			SendClientMessage(playerid, 0xFF0000FF, "ERROR: You already are in this race!~n~/exit to exit");
1010
		}
1011
		else if(race[MAX_PLAYERS][0] == floatround(rcp[rid][4][4]))  //race full
1012
		{
1013
			SendClientMessage(playerid, 0xFF0000FF, "SERVER: The race has reached its max players, try again next time.");
1014
			return 0;
1015
		}
1016
		else
1017
		{
1018
			if(EventCheck(playerid,floatround(rcp[rid][5][4])) == 1)
1019
			{
1020
				SaveKoords(playerid);
1021
				DisArm(playerid);
1022
				race[MAX_PLAYERS][0]++;
1023
				race[playerid][2]=1;
1024
				if(floatround(rcp[rid][5][4]) == 0)
1025
				{
1026
					SetPlayerPos(playerid,rcp[rid][MAX_CPS][0],rcp[rid][MAX_CPS][1],rcp[rid][MAX_CPS][2]);		//race spawn
1027
					SetPlayerVirtualWorld(playerid,floatround(rcp[rid][3][4]));
1028
				}
1029
				else
1030
				{
1031
					new Float:zangle;
1032
					zangle = atan2((rcp[rid][0][1] - rcp[rid][MAX_CPS][1]), (rcp[rid][0][0] - rcp[rid][MAX_CPS][0])) - 90.0;
1033
					SetVehicleZAngle(GetPlayerVehicleID(playerid), zangle);		//set vehicle direction towards first cp
1034
					SetVehiclePos(GetPlayerVehicleID(playerid),rcp[rid][MAX_CPS][0],rcp[rid][MAX_CPS][1],rcp[rid][MAX_CPS][2] + 2.0);		//race spawn
1035
					SetVehicleVirtualWorld(GetPlayerVehicleID(playerid),floatround(rcp[rid][3][4]));
1036
					SetPlayerVirtualWorld(playerid,floatround(rcp[rid][3][4]));
1037
					AddVehicleComponent(GetPlayerVehicleID(playerid),1010);		//nitro
1038
					RepairVehicle(GetPlayerVehicleID(playerid));				//repair veh
1039
					for(new i=0; i < MAX_PLAYERS; i++)
1040
					{
1041
						if(i != playerid) SetVehicleParamsForPlayer(GetPlayerVehicleID(playerid),i,0,1);
1042
					}
1043
					PlayerPlaySound(playerid,1133,0.0,0.0,0.0);
1044
				}
1045
			}
1046
			else
1047
			{
1048
				WVehicleMsg(playerid,floatround(rcp[rid][5][4]));
1049
			}
1050
		}
1051
	}
1052
	else if(race[MAX_PLAYERS][2]==1)
1053
	{
1054
		SendClientMessage(playerid, 0xFF0000FF, "SERVER: The race allready started.");
1055
	}
1056
	else
1057
	{
1058
		SendClientMessage(playerid, 0xFF0000FF, "SERVER: No race running at the moment.");
1059
	}
1060
	return 1;
1061
}
1062
1063
//*************************************************************************
1064
//**************************** race checkpoints ***************************
1065
//*************************************************************************
1066
1067
CreateFirstCP()		//creates the 1st checkpoint
1068
{
1069
	HideRaceInfo();
1070
	new playerid = 0;
1071
	for(new i = 0; i < MAX_PLAYERS; i++)
1072
	{
1073
		if(race[i][2] == 1)
1074
		{
1075
			playerid = i;
1076
			new Float:x, Float:y, Float:z;
1077
			GetVehiclePos(GetPlayerVehicleID(playerid),x,y,z);		//save in-race coordinates for start-freeze
1078
			playerkoords[playerid+MAX_PLAYERS][0] = x;
1079
			playerkoords[playerid+MAX_PLAYERS][1] = y;
1080
			playerkoords[playerid+MAX_PLAYERS][2] = z;
1081
			race[playerid][0] = CreateDynamicRaceCP(floatround(rcp[rid][1][4]),rcp[rid][race[playerid][1]][0],rcp[rid][race[playerid][1]][1],rcp[rid][(race[playerid][1])][2],rcp[rid][((race[playerid][1])+1)][0],rcp[rid][((race[playerid][1])+1)][1],rcp[rid][((race[playerid][1])+1)][2],rcp[rid][0][4],floatround(rcp[rid][3][4]),-1, playerid,300.0);
1082
			SetPlayerMapIcon(playerid, rmapicons[playerid], rcp[rid][race[playerid][1]][0],rcp[rid][race[playerid][1]][1],rcp[rid][race[playerid][1]][2], 0, 0xFF0000FF, 1);
1083
			new string[128];
1084
			//textdraw with cp & position
1085
			format(string, sizeof(string), "Position    %2d/%d",floatround(rcp[rid][race[playerid][1]][3]),race[MAX_PLAYERS][0]);
1086
			textdraws[playerid][0] = TextDrawCreate(510, 360, string); 
1087
			ftextdraw(textdraws[playerid][0],0);
1088
			format(string, sizeof(string), "Checkpoint   0/%d",floatround(rcp[rid][2][4]));
1089
			textdraws[playerid][1] = TextDrawCreate(510, 380, string); 
1090
			ftextdraw(textdraws[playerid][1],0);
1091
			TextDrawShowForPlayer(playerid, textdraws[playerid][0]);
1092
			TextDrawShowForPlayer(playerid, textdraws[playerid][1]);
1093
		}
1094
	}
1095
	freeze = true;		//activate freeze
1096
	return 1;
1097
}
1098
1099
public OnPlayerEnterDynamicRaceCP(playerid, checkpointid)
1100
{
1101
	if(race[playerid][2] == 1)
1102
	{
1103
		new string[128];
1104
		rcp[rid][(race[playerid][1])][3]++;
1105
		format(string, sizeof(string), "Position    %2d/%d",floatround(rcp[rid][race[playerid][1]][3]),race[MAX_PLAYERS][0]);
1106
		TextDrawSetString(textdraws[playerid][0], string);
1107
		format(string, sizeof(string), "Checkpoint %3d/%d",(race[playerid][1]) + 1,floatround(rcp[rid][2][4]));
1108
		TextDrawSetString(textdraws[playerid][1], string);
1109
		PlayerPlaySound(playerid,1138,0.0,0.0,0.0);
1110
		race[playerid][1]++;
1111
		RemovePlayerMapIcon(playerid, rmapicons[playerid]);
1112
		if(race[playerid][1] == floatround(rcp[rid][2][4])) ShowPlayerFinishMsg(playerid);
1113
		else SetPlayerMapIcon(playerid, rmapicons[playerid], rcp[rid][race[playerid][1]][0],rcp[rid][race[playerid][1]][1],rcp[rid][race[playerid][1]][2], 0, 0xFF0000FF, 1);
1114
	}
1115
	return 1;
1116
}
1117
1118
public OnPlayerLeaveDynamicRaceCP(playerid, checkpointid)
1119
{
1120
	if(race[playerid][2] == 1)
1121
	{
1122
		if(cprepair)
1123
		{
1124
			new Float:chealth = 0;
1125
			GetVehicleHealth(GetPlayerVehicleID(playerid),chealth);
1126
			if(chealth < 1000.0){RepairVehicle(GetPlayerVehicleID(playerid));PlayerPlaySound(playerid,1133,0.0,0.0,0.0);}		//repair vehicle at every cp
1127
		}
1128
		if(race[playerid][1] < floatround(rcp[rid][2][4]))	//not last cp
1129
		{
1130
			DestroyDynamicRaceCP(race[playerid][0]);
1131
			if((race[playerid][1] + 1) == floatround(rcp[rid][2][4])) race[playerid][0] = CreateDynamicRaceCP((floatround(rcp[rid][1][4])+1),rcp[rid][race[playerid][1]][0],rcp[rid][race[playerid][1]][1],rcp[rid][race[playerid][1]][2],rcp[rid][(race[playerid][1])+1][0],rcp[rid][(race[playerid][1])+1][1],rcp[rid][(race[playerid][1])+1][2],rcp[rid][0][4],floatround(rcp[rid][3][4]),-1, playerid,300.0);
1132
			else race[playerid][0] = CreateDynamicRaceCP(floatround(rcp[rid][1][4]),rcp[rid][race[playerid][1]][0],rcp[rid][race[playerid][1]][1],rcp[rid][race[playerid][1]][2],rcp[rid][(race[playerid][1])+1][0],rcp[rid][(race[playerid][1])+1][1],rcp[rid][(race[playerid][1])+1][2],rcp[rid][0][4],floatround(rcp[rid][3][4]),-1, playerid,300.0);
1133
		}
1134
		else	//last cp
1135
		{
1136
			rcp[rid][floatround(rcp[rid][2][4])][3]++;
1137
			DestroyDynamicRaceCP(race[playerid][0]);
1138
			SetKoords(playerid);
1139
			if(race[MAX_PLAYERS][0] == floatround(rcp[rid][floatround(rcp[rid][2][4])][3]))		//last player ends race
1140
			{
1141
				if(autotimer[0] == 1) KillTimer(autotimer[7]);
1142
				EndRace();
1143
			}
1144
		}
1145
	}
1146
	return 1;
1147
}
1148
1149
//*************************************************************************
1150
//************************ exiting / ending race **************************
1151
//*************************************************************************
1152
1153
EndRace()  //resets race variables at race end
1154
{
1155
	if(race[MAX_PLAYERS][1] == 1) HideRaceInfo();
1156
	for (new i = 0; i < (floatround(rcp[rid][2][4])+1); i++)
1157
	{
1158
		rcp[rid][i][3]=0;
1159
	}
1160
	race[MAX_PLAYERS][0]=0;
1161
	race[MAX_PLAYERS][1]=0;
1162
	race[MAX_PLAYERS][2]=0;
1163
	rid = 0;
1164
	DestroyDynamicArea(spawnarea);
1165
	if(autotimer[0] == 1) autotimer[1] = SetTimer("AutoStart1", 60000 * autotimer[2], false);
1166
	return 1;
1167
}
1168
1169
ExitRace(playerid)
1170
{
1171
	SetKoords(playerid);
1172
	if(noveh[playerid]) noveh[playerid] = false;
1173
	race[MAX_PLAYERS][0]--;
1174
	RemovePlayerMapIcon(playerid, rmapicons[playerid]);
1175
	if(race[MAX_PLAYERS][0] == 0 && race[MAX_PLAYERS][2] == 1)
1176
	{
1177
		if(autotimer[0] == 1) KillTimer(autotimer[7]);
1178
		EndRace();
1179
	}
1180
	return 1;
1181
}
1182
1183
//*********************************************************************************
1184
//********************** race file related ****************************************
1185
//*********************************************************************************
1186
1187
LoadRaces()		//load races from files
1188
{
1189
	new filename[32];		//filename
1190
	new line[64];			//stores a line read from a file
1191
	new errormsg[64];		//used for errormessages
1192
	new string[64];			//used for other messages
1193
	race_count = 0;			//reset race counter
1194
1195
	
1196
	for(new i = 0; i < MAX_RACES; i++)
1197
	{
1198
		new cp_count = 0;		//checkpoint counter
1199
		if(i < 10) 
1200
		{
1201
			format(filename, sizeof(filename), "/races/race0%d.txt", i);
1202
			format(rfilename[race_count], sizeof(rfilename[]), "/races/race0%d.txt", i);
1203
		}
1204
		else
1205
		{
1206
			format(filename, sizeof(filename), "/races/race%d.txt", i);
1207
			format(rfilename[race_count], sizeof(rfilename[]), "/races/race%d.txt", i);
1208
		}
1209
		if(fexist(filename))	//check if the racefile exists
1210
		{
1211
			new lines_read = 0;
1212
			new File:racefile = fopen(filename, io_read);		//open file
1213
			format(string, sizeof(string), "...Loading %s",filename);
1214
			print(string);
1215
			while(fread(racefile, line))		//read from file
1216
			{
1217
				switch(lines_read)
1218
				{
1219
					case 0:			//racename
1220
					{
1221
						new tempstr[64];
1222
						for(new z = 0; z < 64; z++)
1223
						{
1224
							new tempchar[2];
1225
							format(tempchar, sizeof(tempchar), "%c",line[z]);
1226
							if(!strcmp(tempchar, ";")) break;
1227
							tempstr[z] = tempchar[0];
1228
						}
1229
						format(errormsg, sizeof(errormsg), "Error reading racename in %s",filename);
1230
						if(sscanf(tempstr, "s[64]", rname[race_count])) return print(errormsg);
1231
						format(string, sizeof(string), " <%s>",rname[race_count]);
1232
						print(string);
1233
					}
1234
					case 1:			//cp diameter
1235
					{
1236
						new tempstr[32];
1237
						for(new z = 0; z < 32; z++)
1238
						{
1239
							new tempchar[2];
1240
							format(tempchar, sizeof(tempchar), "%c",line[z]);
1241
							if(!strcmp(tempchar, ";")) break;
1242
							tempstr[z] = tempchar[0];
1243
						}
1244
						format(errormsg, sizeof(errormsg), "Error reading cp diameter in %s",filename);
1245
						if(sscanf(tempstr, "f", rcp[race_count][0][4])) return print(errormsg);
1246
					}
1247
					case 2:			//cp type
1248
					{
1249
						new tempstr[32];
1250
						for(new z = 0; z < 32; z++)
1251
						{
1252
							new tempchar[2];
1253
							format(tempchar, sizeof(tempchar), "%c",line[z]);
1254
							if(!strcmp(tempchar, ";")) break;
1255
							tempstr[z] = tempchar[0];
1256
						}
1257
						format(errormsg, sizeof(errormsg), "Error reading cp type in %s",filename);
1258
						if(sscanf(tempstr, "f", rcp[race_count][1][4])) return print(errormsg);
1259
					}
1260
					case 3:			//number of cps
1261
					{
1262
						new tempstr[32];
1263
						for(new z = 0; z < 32; z++)
1264
						{
1265
							new tempchar[2];
1266
							format(tempchar, sizeof(tempchar), "%c",line[z]);
1267
							if(!strcmp(tempchar, ";")) break;
1268
							tempstr[z] = tempchar[0];
1269
						}
1270
						format(errormsg, sizeof(errormsg), "Error reading number of cps in %s",filename);
1271
						if(sscanf(tempstr, "f", rcp[race_count][2][4])) return print(errormsg);
1272
					}
1273
					case 4:			//virtual world
1274
					{
1275
						new tempstr[32];
1276
						for(new z = 0; z < 32; z++)
1277
						{
1278
							new tempchar[2];
1279
							format(tempchar, sizeof(tempchar), "%c",line[z]);
1280
							if(!strcmp(tempchar, ";")) break;
1281
							tempstr[z] = tempchar[0];
1282
						}
1283
						format(errormsg, sizeof(errormsg), "Error reading virtual world in %s",filename);
1284
						if(sscanf(tempstr, "f", rcp[race_count][3][4])) return print(errormsg);
1285
					}
1286
					case 5:			//max participants
1287
					{
1288
						new tempstr[32];
1289
						for(new z = 0; z < 32; z++)
1290
						{
1291
							new tempchar[2];
1292
							format(tempchar, sizeof(tempchar), "%c",line[z]);
1293
							if(!strcmp(tempchar, ";")) break;
1294
							tempstr[z] = tempchar[0];
1295
						}
1296
						format(errormsg, sizeof(errormsg), "Error reading max participants in %s",filename);
1297
						if(sscanf(tempstr, "f", rcp[race_count][4][4])) return print(errormsg);
1298
					}
1299
					case 6:			//vehicle requirement
1300
					{
1301
						new tempstr[32];
1302
						for(new z = 0; z < 32; z++)
1303
						{
1304
							new tempchar[2];
1305
							format(tempchar, sizeof(tempchar), "%c",line[z]);
1306
							if(!strcmp(tempchar, ";")) break;
1307
							tempstr[z] = tempchar[0];
1308
						}
1309
						format(errormsg, sizeof(errormsg), "Error reading vehicle requirements in %s",filename);
1310
						if(sscanf(tempstr, "f", rcp[race_count][5][4])) return print(errormsg);
1311
					}
1312
					case 7:			//free
1313
					{
1314
						new tempstr[32];
1315
						for(new z = 0; z < 32; z++)
1316
						{
1317
							new tempchar[2];
1318
							format(tempchar, sizeof(tempchar), "%c",line[z]);
1319
							if(!strcmp(tempchar, ";")) break;
1320
							tempstr[z] = tempchar[0];
1321
						}
1322
						format(errormsg, sizeof(errormsg), "Error reading unused var 1 in %s",filename);
1323
						if(sscanf(tempstr, "f", rcp[race_count][6][4])) return print(errormsg);
1324
					}
1325
					case 8:			//free
1326
					{
1327
						new tempstr[32];
1328
						for(new z = 0; z < 32; z++)
1329
						{
1330
							new tempchar[2];
1331
							format(tempchar, sizeof(tempchar), "%c",line[z]);
1332
							if(!strcmp(tempchar, ";")) break;
1333
							tempstr[z] = tempchar[0];
1334
						}
1335
						format(errormsg, sizeof(errormsg), "Error reading unused var 2 in %s",filename);
1336
						if(sscanf(tempstr, "f", rcp[race_count][7][4])) return print(errormsg);
1337
					}
1338
					case 9:			//free
1339
					{
1340
						new tempstr[32];
1341
						for(new z = 0; z < 32; z++)
1342
						{
1343
							new tempchar[2];
1344
							format(tempchar, sizeof(tempchar), "%c",line[z]);
1345
							if(!strcmp(tempchar, ";")) break;
1346
							tempstr[z] = tempchar[0];
1347
						}
1348
						format(errormsg, sizeof(errormsg), "Error reading unused var 3 in %s",filename);
1349
						if(sscanf(tempstr, "f", rcp[race_count][8][4])) return print(errormsg);
1350
					}
1351
					case 10:			//free
1352
					{
1353
						new tempstr[32];
1354
						for(new z = 0; z < 32; z++)
1355
						{
1356
							new tempchar[2];
1357
							format(tempchar, sizeof(tempchar), "%c",line[z]);
1358
							if(!strcmp(tempchar, ";")) break;
1359
							tempstr[z] = tempchar[0];
1360
						}
1361
						format(errormsg, sizeof(errormsg), "Error reading unused var 4 in %s",filename);
1362
						if(sscanf(tempstr, "f", rcp[race_count][9][4])) return print(errormsg);
1363
					}
1364
					case 11:			//race spawn
1365
					{
1366
						new index = 0;
1367
						new tempstrx[32];		//spawn X
1368
						for(new z = 0; z < 14; z++)
1369
						{
1370
							new tempchar[2];
1371
							format(tempchar, sizeof(tempchar), "%c",line[z]);
1372
							if(!strcmp(tempchar, ",")) break;
1373
							tempstrx[z] = tempchar[0];
1374
						}
1375
						index += (strlen(tempstrx) + 1);
1376
						format(errormsg, sizeof(errormsg), "Error reading X-spawn in %s",filename);
1377
						if(sscanf(tempstrx, "f", rcp[race_count][MAX_CPS][0])) return print(errormsg);
1378
						
1379
						new tempstry[32];		//spawn Y
1380
						for(new z = 0; z < 14; z++)
1381
						{
1382
							new tempchar[2];
1383
							format(tempchar, sizeof(tempchar), "%c",line[z + index]);
1384
							if(!strcmp(tempchar, ",")) break;
1385
							tempstry[z] = tempchar[0];
1386
						}
1387
						index += (strlen(tempstry) + 1);
1388
						format(errormsg, sizeof(errormsg), "Error reading Y-spawn in %s",filename);
1389
						if(sscanf(tempstry, "f", rcp[race_count][MAX_CPS][1])) return print(errormsg);
1390
						
1391
						new tempstrz[32];		//spawn Z
1392
						for(new z = 0; z < 14; z++)
1393
						{
1394
							new tempchar[2];
1395
							format(tempchar, sizeof(tempchar), "%c",line[z + index]);
1396
							if(!strcmp(tempchar, ";")) break;
1397
							tempstrz[z] = tempchar[0];
1398
						}
1399
						format(errormsg, sizeof(errormsg), "Error reading Z-spawn in %s",filename);
1400
						if(sscanf(tempstrz, "f", rcp[race_count][MAX_CPS][2])) return print(errormsg);
1401
					}
1402
					default :		//race checkpoints
1403
					{
1404
						new index = 0;
1405
						new tempstrx[32];		//cp X
1406
						for(new z = 0; z < 14; z++)
1407
						{
1408
							new tempchar[2];
1409
							format(tempchar, sizeof(tempchar), "%c",line[z]);
1410
							if(!strcmp(tempchar, ",")) break;
1411
							tempstrx[z] = tempchar[0];
1412
						}
1413
						index += (strlen(tempstrx) + 1);
1414
						format(errormsg, sizeof(errormsg), "Error reading X at cp %d in %s",cp_count,filename);
1415
						if(sscanf(tempstrx, "f", rcp[race_count][cp_count][0])) return print(errormsg);
1416
						
1417
						new tempstry[32];		//cp Y
1418
						for(new z = 0; z < 14; z++)
1419
						{
1420
							new tempchar[2];
1421
							format(tempchar, sizeof(tempchar), "%c",line[z + index]);
1422
							if(!strcmp(tempchar, ",")) break;
1423
							tempstry[z] = tempchar[0];
1424
						}
1425
						index += (strlen(tempstry) + 1);
1426
						format(errormsg, sizeof(errormsg), "Error reading Y at cp %d in %s",cp_count,filename);
1427
						if(sscanf(tempstry, "f", rcp[race_count][cp_count][1])) return print(errormsg);
1428
						
1429
						new tempstrz[32];		//cp Z
1430
						for(new z = 0; z < 14; z++)
1431
						{
1432
							new tempchar[2];
1433
							format(tempchar, sizeof(tempchar), "%c",line[z + index]);
1434
							if(!strcmp(tempchar, ";")) break;
1435
							tempstrz[z] = tempchar[0];
1436
						}
1437
						format(errormsg, sizeof(errormsg), "Error reading Z at cp %d in %s",cp_count,filename);
1438
						if(sscanf(tempstrz, "f", rcp[race_count][cp_count][2])) return print(errormsg);
1439
						cp_count++;
1440
					}
1441
				}
1442
				lines_read++;
1443
			}
1444
			fclose(racefile);
1445
			format(errormsg, sizeof(errormsg), "Wrong number of checkpoints in %s", filename);
1446
			if(cp_count != floatround(rcp[race_count][2][4])) return print(errormsg);
1447
			print("...Done");
1448
			race_count++;
1449
		}
1450
	}
1451
	format(string, sizeof(string), "Loaded %d Races",race_count);
1452
	print(string);
1453
	return 1;
1454
}
1455
1456
RaceToFile(playerid)
1457
{
1458
	SendClientMessage(playerid, 0x00FF00FF, "...writing racefile");
1459
	new filename[32];		//filename
1460
	new line[64];			//stores a line read from a file
1461
	//set filename
1462
	for(new i = 0; i < MAX_RACES; i++)
1463
	{
1464
		if(i < 10) format(filename, sizeof(filename), "/races/race0%d.txt", i);
1465
		else format(filename, sizeof(filename), "/races/race%d.txt", i);
1466
		if(!fexist(filename)) break;		//check if the racefile exists
1467
	}		
1468
	new File:racefile = fopen(filename, io_readwrite);		//open file
1469
	format(line,sizeof(line),"%s;	Racename\r\n", rname[MAX_RACES]);	//racename
1470
	fwrite(racefile,line);
1471
	format(line,sizeof(line),"%f;	Checkpoint size\r\n", rcp[MAX_RACES][0][4]);	//cp size
1472
	fwrite(racefile,line);
1473
	format(line,sizeof(line),"%f;	Checkpoint type\r\n", rcp[MAX_RACES][1][4]);	//cp type
1474
	fwrite(racefile,line);
1475
	format(line,sizeof(line),"%f;	number of cps\r\n", rcp[MAX_RACES][2][4]);	//cp number
1476
	fwrite(racefile,line);
1477
	format(line,sizeof(line),"%f;	worldid\r\n", rcp[MAX_RACES][3][4]);	//worldid
1478
	fwrite(racefile,line);
1479
	format(line,sizeof(line),"%f;	max players\r\n", rcp[MAX_RACES][4][4]);	//max players
1480
	fwrite(racefile,line);
1481
	format(line,sizeof(line),"%f;	needed vehicle\r\n", rcp[MAX_RACES][5][4]);	//needed veh
1482
	fwrite(racefile,line);
1483
	format(line,sizeof(line),"%f;	unused 1\r\n", rcp[MAX_RACES][6][4]);	//unused atm
1484
	fwrite(racefile,line);
1485
	format(line,sizeof(line),"%f;	unused 2\r\n", rcp[MAX_RACES][7][4]);	//unused atm
1486
	fwrite(racefile,line);
1487
	format(line,sizeof(line),"%f;	unused 3\r\n", rcp[MAX_RACES][8][4]);	//unused atm
1488
	fwrite(racefile,line);
1489
	format(line,sizeof(line),"%f;	unused 4\r\n", rcp[MAX_RACES][9][4]);	//unused atm
1490
	fwrite(racefile,line);
1491
	format(line,sizeof(line),"%f,", rcp[MAX_RACES][MAX_CPS][0]);	//spawn x
1492
	fwrite(racefile,line);
1493
	format(line,sizeof(line),"%f,", rcp[MAX_RACES][MAX_CPS][1]);	//spawn y
1494
	fwrite(racefile,line);
1495
	format(line,sizeof(line),"%f;	Race Spawn\r\n", rcp[MAX_RACES][MAX_CPS][2]);	//spawn z
1496
	fwrite(racefile,line);
1497
	for(new i = 0; i < rcp[MAX_RACES][2][4]; i++)		//write checkpoints
1498
	{
1499
		format(line,sizeof(line),"%f,", rcp[MAX_RACES][i][0]);	//cp x
1500
		fwrite(racefile,line);
1501
		format(line,sizeof(line),"%f,", rcp[MAX_RACES][i][1]);	//cp y
1502
		fwrite(racefile,line);
1503
		format(line,sizeof(line),"%f;\r\n", rcp[MAX_RACES][i][2]);	//cp z
1504
		fwrite(racefile,line);
1505
	}
1506
	fclose(racefile);
1507
	SendClientMessage(playerid, 0x00FF00FF, "...Done");
1508
	print("...Done");
1509
	if(LoadRaces() != 1)
1510
	{
1511
		SendClientMessage(playerid, 0xFF0000FF, "SERVER: Error loading race files.");
1512
		SendClientMessage(playerid, 0xFF0000FF, "See logfile for detailled information.");
1513
	}
1514
	else SendClientMessage(playerid, 0xFF0000FF, "SERVER: Racefiles reloaded.");
1515
	RaceEditorClose(playerid);
1516
	return 1;
1517
}
1518
1519
RacefileCheck(playerid)
1520
{
1521
	new filename[32];		//filename
1522
	if((race_count - 1) < 10) format(filename, sizeof(filename), "/races/race0%d.txt", race_count);
1523
	else format(filename, sizeof(filename), "/races/race%d.txt", race_count);
1524
	if(fexist(filename)) ShowPlayerDialog(playerid,2209,DIALOG_STYLE_MSGBOX,"Overwrite?","The racefile allready exists, want to overwrite?\r\nCheck your Racefile folder.","Overwrite","Back");
1525
	else RaceToFile(playerid);
1526
}
1527
1528
//*******************************************************************************
1529
//*************************** race editor related *******************************
1530
//*******************************************************************************
1531
1532
RaceEditor1(playerid)		//veh class
1533
{
1534
	if(race_count == MAX_RACES) return SendClientMessage(playerid, 0xFF0000FF, "SERVER: Too many races. Increase MAX_RACES in your filterscript or delete some races");
1535
	rcp[MAX_RACES][0][4] = 8.0;
1536
	SendClientMessage(playerid, 0xFF0000FF, "SERVER: You can leave the editor anytime with /end");
1537
	ShowPlayerDialog(playerid,2202,DIALOG_STYLE_LIST,"Select Vehicle Class","No Vehicle (e.g. Vehicle in race)\r\nLand Vehicle (Car,Motorbike,Truck)\r\nCar\r\nMotorbike\r\nTruck\r\nPlane\r\nHelicopter\r\nBoat\r\nBike","Continue","Cancel");
1538
	return 1;
1539
}
1540
1541
RaceEditor2(playerid)		//cp diameter
1542
{
1543
	new caption[32];
1544
	new Float:x, Float:y, Float:z;
1545
	if(IsPlayerInAnyVehicle(playerid) == 1)
1546
	{
1547
		new Float:ang;
1548
		GetVehiclePos(GetPlayerVehicleID(playerid),x,y,z);
1549
		GetVehicleZAngle(GetPlayerVehicleID(playerid),ang);
1550
		x += ((floatsin(ang, degrees)) * -15.0);
1551
		y += ((floatcos(ang, degrees)) * 15.0);
1552
	}
1553
	else
1554
	{
1555
		new Float:ang;
1556
		GetPlayerPos(GetPlayerVehicleID(playerid),x,y,z);
1557
		GetPlayerFacingAngle(playerid,ang);
1558
		x += ((floatsin(ang, degrees)) * -5.0);
1559
		y += ((floatcos(ang, degrees)) * 5.0);
1560
	}
1561
	SetPlayerRaceCheckpoint(playerid, floatround(rcp[MAX_RACES][1][4]) + 1, x, y, z, x+10, y+10, z, rcp[MAX_RACES][0][4]);
1562
	//CreateDynamicRaceCP(floatround(rcp[MAX_RACES][1][4]) + 1,x,y,z,x+10,y+10,z,rcp[MAX_RACES][0][4],0,-1,playerid,300.0);
1563
	format(caption, sizeof(caption), "Checkpoint Size {FF0000}%.1f",rcp[MAX_RACES][0][4]);
1564
	ShowPlayerDialog(playerid,2203,DIALOG_STYLE_LIST,caption,"Bigger <->\r\nSmaller >-<\r\nSave Size","Continue","Back");
1565
	return 1;
1566
}
1567
1568
RaceEditor3(playerid)		//max. participants
1569
{
1570
	ShowPlayerDialog(playerid,2204,DIALOG_STYLE_INPUT,"Max. Participants","Please enter the max. number of participants.","Continue","Back");
1571
	return 1;
1572
}
1573
1574
RaceEditor4(playerid)		//set virtual world
1575
{
1576
	ShowPlayerDialog(playerid,2205,DIALOG_STYLE_INPUT,"Virtual World","Please enter the Virtual World for this race. (0 is the normal VWorld)","Continue","Back");
1577
	return 1;
1578
}
1579
1580
RaceEditor5(playerid)		//place cps
1581
{
1582
	ShowPlayerDialog(playerid,2206,DIALOG_STYLE_MSGBOX,"Setting Checkpoints","Ready for Checkpoint placement.","Continue","Back");
1583
	SendClientMessage(playerid, 0x0000FFFF, "Use  ~k~~VEHICLE_FIREWEAPON~  to place a checkpoint. (First CP is Race Spawn)");
1584
	SendClientMessage(playerid, 0x0000FFFF, "Use  ~k~~VEHICLE_HORN~  to place the last checkpoint.");
1585
	return 1;
1586
}
1587
1588
public OnPlayerKeyStateChange(playerid, newkeys, oldkeys)
1589
{
1590
	if((newkeys & KEY_FIRE) && !(oldkeys & KEY_FIRE) && race_editor[3] == playerid && race_editor[4] != 0)		//place cps
1591
	{
1592
		if(race_editor[4] == 1)
1593
		{
1594
			new Float:x,Float:y,Float:z;
1595
			GetPlayerPos(playerid,x,y,z);
1596
			rcp[MAX_RACES][MAX_CPS][0] = x;
1597
			rcp[MAX_RACES][MAX_CPS][1] = y;
1598
			rcp[MAX_RACES][MAX_CPS][2] = z - 0.5;
1599
			race_editor[4]++;
1600
			SendClientMessage(playerid, 0x00FF00FF, "EDITOR: Placed race spawn.");
1601
		}
1602
		else
1603
		{
1604
			new msg[32];
1605
			new Float:x,Float:y,Float:z;
1606
			GetPlayerPos(playerid,x,y,z);
1607
			rcp[MAX_RACES][race_editor[2]][0] = x;
1608
			rcp[MAX_RACES][race_editor[2]][1] = y;
1609
			rcp[MAX_RACES][race_editor[2]][2] = z - 0.5;
1610
			race_editor[2]++;
1611
			format(msg,sizeof(msg),"EDITOR: Placed Checkpoint %d.",race_editor[2]);
1612
			SendClientMessage(playerid, 0x00FF00FF, msg);
1613
		}
1614
	}
1615
	if((newkeys & KEY_CROUCH) && !(oldkeys & KEY_CROUCH) && race_editor[3] == playerid && race_editor[4] == 2)		//place last cp
1616
	{
1617
		race_editor[4] = 0;		//disable checkpoint placing
1618
		new Float:x,Float:y,Float:z;
1619
		GetPlayerPos(playerid,x,y,z);
1620
		rcp[MAX_RACES][race_editor[2]][0] = x;
1621
		rcp[MAX_RACES][race_editor[2]][1] = y;
1622
		rcp[MAX_RACES][race_editor[2]][2] = z - 0.5;
1623
		race_editor[2]++;
1624
		rcp[MAX_RACES][2][4] = race_editor[2];		//set number of checkpoints
1625
		SendClientMessage(playerid, 0x00FF00FF, "EDITOR: Placed last Checkpoint");
1626
		RaceEditor6(playerid);
1627
	}		
1628
	return 1;
1629
}
1630
1631
RaceEditor6(playerid)		//race name
1632
{
1633
	ShowPlayerDialog(playerid,2207,DIALOG_STYLE_INPUT,"Racename","Please enter a racename. (max. 63 chars)","Continue","Cancel");
1634
	return 1;
1635
}
1636
1637
RaceEditor7(playerid)		//save race
1638
{
1639
	ShowPlayerDialog(playerid,2208,DIALOG_STYLE_MSGBOX,"Save","Save race to file now?","Continue","Back");
1640
	return 1;
1641
}
1642
1643
RaceEditorClose(playerid)
1644
{
1645
	for(new i = 0; i < race_editor[2]; i++)		//reset temp race values
1646
	{
1647
		for(new z = 0; z < 5; z++)
1648
		{
1649
			rcp[MAX_RACES][i][z] = 0.0;
1650
		}
1651
	}
1652
	
1653
	for(new i = 0; i < 3; i++)		//reset temp race spawn
1654
	{
1655
		rcp[MAX_RACES][MAX_CPS][i] = 0.0;
1656
	}
1657
1658
	for(new i = 0; i < 5; i++)		//reset race ed values
1659
	{
1660
		race_editor[i] = 0;
1661
	}
1662
	race_editor[3] = -1;
1663
	race_editor[1] = 0;
1664
	
1665
	format(rname[MAX_RACES],sizeof(rname[]),"");		//reset race name
1666
	SetVehicleVirtualWorld(GetPlayerVehicleID(playerid),0);
1667
	SetPlayerVirtualWorld(playerid,0);
1668
	SendClientMessage(playerid, 0xFF0000FF, "SERVER: Editor closed.");
1669
	return 1;
1670
}
1671
1672
//**************************************************************************************
1673
//****************************** automatic race control*********************************
1674
//**************************************************************************************
1675
1676
public AutoStart1()
1677
{
1678
	rid = random(race_count);		//set race ID
1679
	race[MAX_PLAYERS][1] = 1;	//race initialized
1680
	ShowRaceStartedMsg(10);
1681
	spawnarea = CreateDynamicCircle(rcp[rid][MAX_CPS][0], rcp[rid][MAX_CPS][1], 55.0, floatround(rcp[rid][3][4]));		//create race start boundaries
1682
	race[MAX_PLAYERS][0] = 0;
1683
	autotimer[3] = SetTimer("AutoStart2", 60000, true);
1684
	return 1;
1685
}
1686
1687
public AutoStart2()
1688
{
1689
	autotimer[5]++;
1690
	if(autotimer[5] == autotimer[4])
1691
	{
1692
		if(race[MAX_PLAYERS][0] > 1)
1693
		{
1694
			KillTimer(autotimer[3]);
1695
			autotimer[5] = 0;
1696
			race[MAX_PLAYERS][1]=0;		//set race status from "initilized"
1697
			race[MAX_PLAYERS][2]=1;		//to "running"
1698
			CreateFirstCP();
1699
			timer = SetTimerEx("Countdown", 1000, true, "i", scount);
1700
			autotimer[7] = SetTimer("AutoEnd1", (60000 * autotimer[6]) - 30000, false);
1701
		}
1702
		else
1703
		{
1704
			count = 30;
1705
			KillTimer(autotimer[3]);
1706
			autotimer[5] = 0;
1707
			AutoEnd1();
1708
		}
1709
	}
1710
	else ShowTimeRemaining();
1711
	return 1;
1712
}
1713
1714
public AutoEnd1()
1715
{
1716
	if(race[MAX_PLAYERS][2] == 1 || race[MAX_PLAYERS][1] == 1) timer = SetTimer("AutoEnd2", 1000, true);
1717
	return 1;
1718
}
1719
1720
public AutoEnd2()
1721
{
1722
	new delay = 30;
1723
	if(race[MAX_PLAYERS][2] == 1 || race[MAX_PLAYERS][1] == 1)
1724
	{
1725
		if(count == delay)
1726
		{
1727
			KillTimer(timer);
1728
			count = 0;
1729
			TextDrawHideForAll(textdraws[MAX_PLAYERS][2]);
1730
			TextDrawHideForAll(textdraws[MAX_PLAYERS][3]);
1731
			for (new i = 0; i < MAX_PLAYERS; i++)
1732
			{
1733
				if(race[i][2] == 1)		//kick players out of race
1734
				{
1735
					SetKoords(i);
1736
					noveh[i] = false;
1737
					RemovePlayerMapIcon(i, rmapicons[i]);
1738
					SendClientMessage(i, 0xFF0000FF, "SERVER: This race was closed!");
1739
				}
1740
			}
1741
			EndRace();
1742
		}
1743
		else
1744
		{
1745
			new string[32];
1746
			format(string, sizeof(string), "in %d seconds", delay - count);
1747
			if(count == 0)
1748
			{
1749
				TextDrawSetString(textdraws[MAX_PLAYERS][2], "Race will end");
1750
				TextDrawSetString(textdraws[MAX_PLAYERS][3], string);
1751
				for (new i = 0; i < MAX_PLAYERS; i++)
1752
				{
1753
					if(race[i][2] == 1)
1754
					{
1755
						TextDrawShowForPlayer(i, textdraws[MAX_PLAYERS][2]);
1756
						TextDrawShowForPlayer(i, textdraws[MAX_PLAYERS][3]);
1757
					}
1758
				}
1759
			}
1760
			TextDrawSetString(textdraws[MAX_PLAYERS][3], string);
1761
			count++;
1762
		}
1763
	}
1764
	else
1765
	{
1766
		KillTimer(timer);
1767
		TextDrawHideForAll(textdraws[MAX_PLAYERS][2]);
1768
		TextDrawHideForAll(textdraws[MAX_PLAYERS][3]);
1769
	}
1770
	return 1;
1771
}
1772
1773
//***************************************************************
1774
//****************************** misc ***************************
1775
//***************************************************************
1776
1777
RaceSettings(playerid)
1778
{
1779
	new list[256],set1[16],set2[16],set3[16];
1780
	if(cprepair) format(set1, sizeof(set1), "{00FF00}ON");		//auto repair
1781
	else format(set1, sizeof(set1), "{FF0000}OFF");
1782
	if(sfreeze) format(set2, sizeof(set2), "{00FF00}ON");		//start freeze
1783
	else format(set2, sizeof(set2), "{FF0000}OFF");
1784
	if(autotimer[0] == 1) format(set3, sizeof(set3), "{00FF00}ON");		//race autostart
1785
	else format(set3, sizeof(set3), "{FF0000}OFF");
1786
	format(list, sizeof(list), "Delete Races\r\nRepair in CP		%s\r\nStart Countdown	%d sec\r\nGet back to car		%d sec\r\nStart Freeze		%s\r\nRace Autostart		%s\r\nAutostart every		%d min\r\nAutostart Jointime	%d min\r\nAutoend after		%d min",set1,scount,rettime,set2,set3,autotimer[2],autotimer[4],autotimer[6]);
1787
	ShowPlayerDialog(playerid, 2210, DIALOG_STYLE_LIST, "Race Settings", list, "Select", "Cancel");
1788
	return 1;
1789
}
1790
1791
DisArm(playerid)		//DisArms a player before entering race
1792
{
1793
	for (new i = 0; i < 13; i++)
1794
	{
1795
		GetPlayerWeaponData(playerid, i, weapons[playerid][i][0], weapons[playerid][i][1]);
1796
	}
1797
	ResetPlayerWeapons(playerid);
1798
	return 1;
1799
}
1800
1801
ReArm(playerid)		//returns player weapons
1802
{
1803
	for (new i = 0; i < 13; i++)
1804
	{
1805
		GivePlayerWeapon(playerid, weapons[playerid][i][0], weapons[playerid][i][1]);
1806
		weapons[playerid][i][0] = 0;
1807
		weapons[playerid][i][1] = 0;
1808
	}
1809
	return 1;
1810
}
1811
1812
SaveKoords(playerid)  //save playercoordinates
1813
{
1814
	new Float:x, Float:y, Float:z;
1815
	GetPlayerPos(playerid, x, y, z);
1816
	playerkoords[playerid][0] = x;
1817
	playerkoords[playerid][1] = y;
1818
	playerkoords[playerid][2] = z;
1819
1820
	return 1;
1821
}
1822
1823
SetKoords(playerid)  //sets player back to where he was before entering the race and returns the weapons
1824
{
1825
	if(floatround(rcp[rid][5][4]) == 0 || IsPlayerInAnyVehicle(playerid) == 0)
1826
	{
1827
		SetPlayerPos(playerid, playerkoords[playerid][0], playerkoords[playerid][1], playerkoords[playerid][2]);
1828
		SetPlayerVirtualWorld(playerid,0);
1829
	}
1830
	else
1831
	{
1832
		SetVehiclePos(GetPlayerVehicleID(playerid), playerkoords[playerid][0], playerkoords[playerid][1], playerkoords[playerid][2]);
1833
		SetVehicleVirtualWorld(GetPlayerVehicleID(playerid), 0);
1834
		SetPlayerVirtualWorld(playerid, 0);
1835
		RepairVehicle(GetPlayerVehicleID(playerid));				//repair veh
1836
		for(new i=0; i < MAX_PLAYERS; i++)		//unlock
1837
		{
1838
			if(i != playerid) SetVehicleParamsForPlayer(GetPlayerVehicleID(playerid),i,0,0);
1839
		}
1840
	}
1841
	ReArm(playerid);
1842
	if(race[MAX_PLAYERS][2] == 1)
1843
	{
1844
		TextDrawHideForPlayer(playerid, textdraws[playerid][0]);
1845
		TextDrawHideForPlayer(playerid, textdraws[playerid][1]);
1846
		TextDrawDestroy(textdraws[playerid][0]);
1847
		TextDrawDestroy(textdraws[playerid][1]);
1848
	}
1849
	race[playerid][0]=0;
1850
	race[playerid][1]=0;
1851
	race[playerid][2]=0;
1852
	return 1;
1853
}
1854
1855
public OnPlayerConnect(playerid)
1856
{
1857
	if(race[MAX_PLAYERS][1] == 1)		//show race info on player connect
1858
	{
1859
		TextDrawShowForPlayer(playerid, textdraws[MAX_PLAYERS][0]);
1860
		TextDrawShowForPlayer(playerid, textdraws[MAX_PLAYERS][1]);
1861
	}
1862
	return 1;
1863
}
1864
1865
public OnPlayerDeath(playerid,killerid,reason)		//kick player out of race on death
1866
{
1867
	if(race[playerid][2] == 1)
1868
	{
1869
		ExitRace(playerid);
1870
	}
1871
	if(race_editor[3] == playerid) RaceEditorClose(playerid);
1872
	return 1;
1873
}
1874
1875
public OnPlayerDisconnect(playerid, reason)		//kick player out of race on dc
1876
{
1877
	if(race[playerid][2] == 1)
1878
	{
1879
		ExitRace(playerid);
1880
	}
1881
	if(race_editor[3] == playerid) RaceEditorClose(playerid);
1882
	return 1;
1883
}
1884
1885
public OnPlayerUpdate(playerid)
1886
{
1887
	//freeze at race start
1888
	if(race[playerid][2] == 1 && freeze && sfreeze) SetVehiclePos(GetPlayerVehicleID(playerid),playerkoords[playerid+MAX_PLAYERS][0], playerkoords[playerid+MAX_PLAYERS][1], playerkoords[playerid+MAX_PLAYERS][2]);
1889
1890
	
1891
	return 1;
1892
}
1893
1894
1895
public OnPlayerStateChange(playerid, newstate, oldstate)
1896
{
1897
	if(newstate == PLAYER_STATE_DRIVER)
1898
	{
1899
		playerveh[GetPlayerVehicleID(playerid)] = playerid;
1900
		vehplayer[playerid] = GetPlayerVehicleID(playerid);
1901
	}
1902
	if(oldstate == PLAYER_STATE_DRIVER)
1903
	{
1904
		OnPlayerExitVehicleEx(playerid,vehplayer[playerid]);
1905
		playerveh[vehplayer[playerid]] = -1;
1906
		vehplayer[playerid] = -1;
1907
	}
1908
	return 1;
1909
}
1910
1911
OnPlayerExitVehicleEx(playerid, vehicleid)		//is called when a player exits a vehicle in any way (including falling off a motorbike & dying)
1912
{
1913
	if(race[playerid][2] == 1) exittimer[playerid] = SetTimerEx("GetBack", 1000, true, "d", playerid);
1914
	if(vehicleid == vehicleid) return 1;
1915
	return 1;
1916
}
1917
		
1918
public OnPlayerEnterVehicle(playerid, vehicleid, ispassenger)
1919
{
1920
	if(noveh[playerid]) noveh[playerid] = false;
1921
	return 1;
1922
}
1923
1924
public OnPlayerLeaveDynamicArea(playerid, areaid)		//don't leave spawn area
1925
{
1926
	if(areaid == spawnarea && race[MAX_PLAYERS][1] == 1 && race[playerid][2] == 1)
1927
	{
1928
		SendClientMessage(playerid, 0xFF0000FF, "SERVER: Please don't leave the race spawn.");
1929
		if(floatround(rcp[rid][5][4]) == 0)
1930
		{
1931
			SetPlayerPos(playerid,rcp[rid][MAX_CPS][0],rcp[rid][MAX_CPS][1],rcp[rid][MAX_CPS][2]);		//race spawn
1932
		}
1933
		else
1934
		{
1935
			new Float:zangle;
1936
			zangle = atan2((rcp[rid][0][1] - rcp[rid][MAX_CPS][1]), (rcp[rid][0][0] - rcp[rid][MAX_CPS][0])) - 90.0;
1937
			SetVehicleZAngle(GetPlayerVehicleID(playerid), zangle);		//set vehicle direction towards first cp
1938
			SetVehiclePos(GetPlayerVehicleID(playerid),rcp[rid][MAX_CPS][0],rcp[rid][MAX_CPS][1],rcp[rid][MAX_CPS][2] + 2.0);		//race spawn
1939
			RepairVehicle(GetPlayerVehicleID(playerid));
1940
		}
1941
	}
1942
	return 1;
1943
}