rendered paste body#include <a_samp>#include <foreach>#include <sscanf>#include <conf> //http://zeex.pastebin.ca/1641138#define MAX_RACE_RACE_CHECKPOINTS 100#define MAX_RACE_PICKUPS 50#define MAX_RACE_NAME 32#define RACE_UPDATE_INTERVAL 1000#define RACE_BOOST_EFFECT 1.5#define RACE_BOOM_RADIUS 5.0#define RACE_REPAIR_DAMAGE 0.8#define RACE_DRUNK_TIME 15000#define RACE_PICKUP_TYPE_NITRO 0#define RACE_PICKUP_TYPE_REPAIR 3096#define RACE_PICKUP_TYPE_BOOST 1237//#define RACE_PICKUP_TYPE_BOOM 1254#define RACE_PICKUP_TYPE_BEER 1484#define cpdata(%1,%2) \ gRaceCheckpoints[%1][E_RACE_CHECKPOINT_%2] #define sqdist(%1,%2,%3,%4,%5,%6) \ ((%1 - %4)*(%1 - %4) + (%2 - %5)*(%2 - %5) + (%3 - %6)*(%3 - %6)) #define near(%1,%2) \ (%1 + (%2)*floatsin(random(cellmax))) enum E_RACE_PICKUP{ E_RACE_PICKUP_ID, E_RACE_PICKUP_TYPE, Float:E_RACE_PICKUP_XPOS, Float:E_RACE_PICKUP_YPOS, Float:E_RACE_PICKUP_ZPOS,}enum E_RACE_RACE_CHECKPOINT{ E_RACE_CHECKPOINT_TYPE, Float:E_RACE_CHECKPOINT_XPOS, Float:E_RACE_CHECKPOINT_YPOS, Float:E_RACE_CHECKPOINT_ZPOS, Float:E_RACE_CHECKPOINT_SIZE,}enum e_RACE_STATE{ e_RACE_STATE_NONE, e_RACE_STATE_ACTIVE, e_RACE_STATE_STARTED,}enum E_RACE{ E_RACE_NAME[MAX_RACE_NAME], e_RACE_STATE:E_RACE_STATE, E_RACE_CHECKPOINTS, E_RACE_PICKUPS, E_RACE_LAPS, E_RACE_PLAYERS, E_RACE_WORLD, E_RACE_UPD_TIMER, E_RACE_PSDELAY,}enum E_RACE_PLAYER{ E_PLAYER_RACER, E_PLAYER_CUR_CP, E_PLAYER_CUR_LAP, E_PLAYER_CUR_POS, E_PLAYER_WORLD, Float:E_PLAYER_POS[3], Text:E_PLAYER_TEXT,}new gRaceData[E_RACE], gPlayerData[MAX_PLAYERS][E_RACE_PLAYER], gRacePickups[MAX_RACE_PICKUPS][E_RACE_PICKUP], gRaceCheckpoints[MAX_RACE_RACE_CHECKPOINTS][E_RACE_RACE_CHECKPOINT];Itter_Create(Racer, MAX_PLAYERS);forward TogglePlayerShooting(playerid, bool:toggle);forward RaceCountdown(value);forward OnRaceMapEntryRead(block[], name[], value[]);forward UpdatePlayers();forward RecreateRacePickup(pickup);forward ResetDrunkLevel(playerid);public OnFilterScriptInit(){ for (new i; i < MAX_PLAYERS; i++) { if (IsPlayerConnected(i)) { Itter_Add(Player, i); } } return 1;}public OnFilterScriptExit(){ StopRace(); return 1;}public OnPlayerEnterRaceCheckpoint(playerid){ if (gRaceData[E_RACE_STATE] == e_RACE_STATE_STARTED) { new cp = gPlayerData[playerid][E_PLAYER_CUR_CP], lap = gPlayerData[playerid][E_PLAYER_CUR_LAP], cpcount = gRaceData[E_RACE_CHECKPOINTS], lapcount = gRaceData[E_RACE_LAPS]; if (++cp >= cpcount) { if (++lap >= lapcount) { if (gPlayerData[playerid][E_PLAYER_CUR_POS] == 1) { GameTextForPlayer(playerid, "~h~~y~YOU WON!", 5000, 6); } else { GameTextForPlayer(playerid, "~h~~b~FINISH!", 3000, 6); } RemovePlayerFromRace(playerid); if (!gRaceData[E_RACE_PLAYERS]) { return StopRace(); } } cp = 0; } gPlayerData[playerid][E_PLAYER_CUR_CP] = cp; gPlayerData[playerid][E_PLAYER_CUR_LAP] = lap; SetRaceCheckpoint(playerid); } return 1; }public OnPlayerPickUpPickup(playerid, pickupid){ SendClientMessage(playerid, 0x00FFFFFF, "pickup!"); if (!gPlayerData[playerid][E_PLAYER_RACER] || gRaceData[E_RACE_STATE] != e_RACE_STATE_STARTED) return 0; for (new pickup; pickup < MAX_RACE_PICKUPS; pickup++) { if (gRacePickups[pickup][E_RACE_PICKUP_ID] == pickupid) { switch (gRacePickups[pickup][E_RACE_PICKUP_TYPE]) { case RACE_PICKUP_TYPE_BEER: { SetPlayerDrunkLevel(playerid, 10000); SetTimerEx("ResetDrunkLevel", RACE_DRUNK_TIME, false, "i", playerid); } case RACE_PICKUP_TYPE_NITRO: { AddVehicleComponent(GetPlayerVehicleID(playerid), 1009); PlayerPlaySound(playerid, 1133, 0.0, 0.0, 0.0); } case RACE_PICKUP_TYPE_REPAIR: { new Float:vhealth; GetVehicleHealth(GetPlayerVehicleID(playerid), vhealth); if (vhealth <= RACE_REPAIR_DAMAGE*1000.0) { RepairVehicle(GetPlayerVehicleID(playerid)); PlayerPlaySound(playerid, 1134, 0.0, 0.0, 0.0); } else { return RecreateRacePickup(pickup); } } case RACE_PICKUP_TYPE_BOOST: { new Float:vX, Float:vY, Float:vZ; GetVehicleVelocity(GetPlayerVehicleID(playerid), vX, vY, vZ); SetVehicleVelocity(GetPlayerVehicleID(playerid), vX*RACE_BOOST_EFFECT, vY*RACE_BOOST_EFFECT, vZ*RACE_BOOST_EFFECT); PlayerPlaySound(playerid, 1190 , 0.0, 0.0, 0.0); } /*case RACE_PICKUP_TYPE_BOOM: { new Float:x, Float:y, Float:z; GetPlayerPos(playerid, x, y, z); CreateExplosion(near(x, RACE_BOOM_RADIUS*2), near(y, RACE_BOOM_RADIUS*2), z, 5, RACE_BOOM_RADIUS); PlayerPlaySound(playerid, 1159 , 0.0, 0.0, 0.0); } */ } SetTimerEx("RecreateRacePickup", gRaceData[E_RACE_PSDELAY]*1000, false, "i", pickup); break; } } return 1;}public OnPlayerConnect(playerid){ if (gRaceData[E_RACE_STATE] == e_RACE_STATE_ACTIVE) { SetRaceCheckpoint(playerid); } return 1;}public OnPlayerDeath(playerid, killerid, reason){ RemovePlayerFromRace(playerid); return 1; }public OnPlayerDisconnect(playerid, reason){ RemovePlayerFromRace(playerid); return 1;}public OnRaceMapEntryRead(block[], name[], value[]){ //printf("block=\"%s\" | name=\"%s\" | value=\"%s\"", block, name, value); if (!strcmp(block, "GENERAL", true)) { if (!strcmp(name, "name", true)) { format(gRaceData[E_RACE_NAME], MAX_RACE_NAME, "%s", value); printf("name = %s", gRaceData[E_RACE_NAME]); } else if (!strcmp(name, "laps", true)) { gRaceData[E_RACE_LAPS] = strval(value); printf("laps = %d", gRaceData[E_RACE_LAPS]); } else if (!strcmp(name, "world", true)) { gRaceData[E_RACE_WORLD] = strval(value); printf("world = %d", gRaceData[E_RACE_WORLD]); } else if (!strcmp(name, "psdelay", true)) { gRaceData[E_RACE_PSDELAY] = strval(value); printf("psdelay = %d", gRaceData[E_RACE_PSDELAY]); } } else if (!strcmp(block, "CHECKPOINTS", true)) { new type; if (!strcmp(name, "NORMAL", true)) { type = 0; } else if (!strcmp(name, "FINISH", true)) { type = 1; } else if (!strcmp(name, "START", true)) { type = 2; } else if (!strcmp(name, "AIRNORMAL", true)) { type = 3; } else if (!strcmp(name, "AIRFINISH", true)) { type = 4; } else { return 1; } new Float:x, Float:y, Float:z, Float:size; if (!sscanf(value, "ffff", x, y, z, size)) { new count = gRaceData[E_RACE_CHECKPOINTS]; if (count >= MAX_RACE_RACE_CHECKPOINTS) return 1; gRaceCheckpoints[count][E_RACE_CHECKPOINT_TYPE] = type; gRaceCheckpoints[count][E_RACE_CHECKPOINT_XPOS] = x; gRaceCheckpoints[count][E_RACE_CHECKPOINT_YPOS] = y; gRaceCheckpoints[count][E_RACE_CHECKPOINT_ZPOS] = z; gRaceCheckpoints[count][E_RACE_CHECKPOINT_SIZE] = size; printf("checkpoint: %d %f %f %f %f", type, x, y, z, size); gRaceData[E_RACE_CHECKPOINTS]++; } } else if (!strcmp(block, "PICKUPS", true)) { new type; if (!strcmp(name, "NITRO", true)) { type = RACE_PICKUP_TYPE_NITRO; } else if (!strcmp(name, "REPAIR", true)) { type = RACE_PICKUP_TYPE_REPAIR; } /*else if (!strcmp(name, "BOOM", true)) { type = RACE_PICKUP_TYPE_BOOM; }*/ else if (!strcmp(name, "BEER", true)) { type = RACE_PICKUP_TYPE_BEER; } else if (!strcmp(name, "BOOST", true)) { type = RACE_PICKUP_TYPE_BOOST; } else { return 1; } new Float:x, Float:y, Float:z; if (!sscanf(value, "fff", x, y, z)) { new count = gRaceData[E_RACE_PICKUPS]; if (count >= MAX_RACE_PICKUPS) return 1; gRacePickups[count][E_RACE_PICKUP_ID] = CreatePickup(type, 14, x, y, z, gRaceData[E_RACE_WORLD]); gRacePickups[count][E_RACE_PICKUP_TYPE] = type; gRacePickups[count][E_RACE_PICKUP_XPOS] = x; gRacePickups[count][E_RACE_PICKUP_YPOS] = y; gRacePickups[count][E_RACE_PICKUP_ZPOS] = z; printf("pickup: %d %f %f %f ||| %d", type, x, y, z, gRacePickups[count][E_RACE_PICKUP_ID]); gRaceData[E_RACE_PICKUPS]++; } } return 1;}public RaceCountdown(value){ if (value > 0) { new text[3]; valstr(text, value); foreach (Racer, i) { SetCameraBehindPlayer(i); TogglePlayerControllable(i, false); PlayerPlaySound(i, 1056 , 0.0, 0.0, 0.0); GameTextForPlayer(i, text, 1500, 6); } SetTimerEx("RaceCountdown", 1000, false, "i", --value); } else { foreach (Racer, i) { TogglePlayerControllable(i, true); PlayerPlaySound(i, 1057 , 0.0, 0.0, 0.0); GameTextForPlayer(i, "~h~~h~~w~GO!", 3000, 6); gPlayerData[i][E_PLAYER_CUR_CP] = 1; SetRaceCheckpoint(i); } gRaceData[E_RACE_UPD_TIMER] = SetTimer("UpdatePlayers", RACE_UPDATE_INTERVAL, true); } return 1;}public UpdatePlayers(){ new bool:first = true, playerLap, playerCP, otherLap, otherCP, Float:playerX, Float:playerY, Float:playerZ, Float:otherX, Float:otherY, Float:otherZ, Float:cpX, Float:cpY, Float:cpZ; foreach (Racer, i) { gPlayerData[i][E_PLAYER_CUR_POS] = 1; playerCP = gPlayerData[i][E_PLAYER_CUR_CP]; playerLap = gPlayerData[i][E_PLAYER_CUR_LAP]; cpX = gRaceCheckpoints[playerCP][E_RACE_CHECKPOINT_XPOS]; cpY = gRaceCheckpoints[playerCP][E_RACE_CHECKPOINT_YPOS]; cpZ = gRaceCheckpoints[playerCP][E_RACE_CHECKPOINT_ZPOS]; if (first) { GetPlayerPos(i, playerX, playerY, playerZ); gPlayerData[i][E_PLAYER_POS][0] = playerX; gPlayerData[i][E_PLAYER_POS][1] = playerY; gPlayerData[i][E_PLAYER_POS][2] = playerZ; } else { playerX = gPlayerData[i][E_PLAYER_POS][0]; playerY = gPlayerData[i][E_PLAYER_POS][1]; playerZ = gPlayerData[i][E_PLAYER_POS][2]; } foreach (Racer, j) { if (i == j) continue; otherCP = gPlayerData[j][E_PLAYER_CUR_CP]; otherLap = gPlayerData[j][E_PLAYER_CUR_LAP]; if (playerLap == otherLap || playerCP == otherCP) { if (first) { GetPlayerPos(j, otherX, otherY, otherZ); gPlayerData[j][E_PLAYER_POS][0] = otherX; gPlayerData[j][E_PLAYER_POS][1] = otherY; gPlayerData[j][E_PLAYER_POS][2] = otherZ; } else { otherX = gPlayerData[j][E_PLAYER_POS][0]; otherY = gPlayerData[j][E_PLAYER_POS][1]; otherZ = gPlayerData[j][E_PLAYER_POS][2]; } if (sqdist(playerX, playerY, playerZ, cpX, cpY, cpZ) < sqdist(otherX, otherY, otherZ, cpX, cpY, cpZ)) { gPlayerData[i][E_PLAYER_CUR_POS]++; } } } UpdatePlayerRaceHUD(i); } return 1;}public RecreateRacePickup(pickup){ DestroyPickup(gRacePickups[pickup][E_RACE_PICKUP_ID]); gRacePickups[pickup][E_RACE_PICKUP_ID] = CreatePickup(gRacePickups[pickup][E_RACE_PICKUP_TYPE], 14, gRacePickups[pickup][E_RACE_PICKUP_XPOS], gRacePickups[pickup][E_RACE_PICKUP_YPOS], gRacePickups[pickup][E_RACE_PICKUP_ZPOS], gRaceData[E_RACE_WORLD]); return 1;}public ResetDrunkLevel(playerid){ return SetPlayerDrunkLevel(playerid, 0);}StartRace(){ if (gRaceData[E_RACE_STATE] != e_RACE_STATE_ACTIVE) return 0; new racers; foreach (Player, i) { if (IsPlayerInRaceCheckpoint(i) && GetPlayerState(i) == PLAYER_STATE_DRIVER) { AddPlayerToRace(i); racers++; } else { DisablePlayerRaceCheckpoint(i); } } if (!racers) { StopRace(); } gRaceData[E_RACE_STATE] = e_RACE_STATE_STARTED; RaceCountdown(3); return 1;}StopRace(){ if (gRaceData[E_RACE_STATE] != e_RACE_STATE_STARTED) return 0; foreach (Racer, i) { RemovePlayerFromRace(i); } for (new i; i < MAX_RACE_PICKUPS; i++) { if (gRacePickups[i][E_RACE_PICKUP_TYPE]) { DestroyPickup(gRacePickups[i][E_RACE_PICKUP_ID]); gRacePickups[i][E_RACE_PICKUP_TYPE] = 0; } } gRaceData[E_RACE_STATE] = e_RACE_STATE_NONE; KillTimer(gRaceData[E_RACE_UPD_TIMER]); return 1;}LoadRace(const filename[]){ gRaceData[E_RACE_LAPS] = 1; gRaceData[E_RACE_WORLD] = 0; gRaceData[E_RACE_PICKUPS] = 0; gRaceData[E_RACE_CHECKPOINTS] = 0; format(gRaceData[E_RACE_NAME], MAX_RACE_NAME, "~UNKNOWN~"); if (Conf_ParseFile(filename, "OnRaceMapEntryRead")) { gRaceData[E_RACE_STATE] = e_RACE_STATE_ACTIVE; foreach (Player, i) { SetRaceCheckpoint(i); } return 1; } return 0;}AddPlayerToRace(playerid){ if (Itter_Add(Racer, playerid)) { gRaceData[E_RACE_PLAYERS]++; gPlayerData[playerid][E_PLAYER_CUR_CP] = 0; gPlayerData[playerid][E_PLAYER_CUR_LAP] = 0; gPlayerData[playerid][E_PLAYER_CUR_POS] = 0; gPlayerData[playerid][E_PLAYER_RACER] = true; gPlayerData[playerid][E_PLAYER_WORLD] = GetPlayerVirtualWorld(playerid); SetPlayerVirtualWorld(playerid, gRaceData[E_RACE_WORLD]); SetVehicleVirtualWorld(GetPlayerVehicleID(playerid), gRaceData[E_RACE_WORLD]); CreatePlayerRaceHUD(playerid); return 1; } return 0;}RemovePlayerFromRace(playerid){ if (Itter_Remove(Racer, playerid)) { gRaceData[E_RACE_PLAYERS]--; gPlayerData[playerid][E_PLAYER_CUR_CP] = 0; gPlayerData[playerid][E_PLAYER_CUR_LAP] = 0; gPlayerData[playerid][E_PLAYER_CUR_POS] = 0; gPlayerData[playerid][E_PLAYER_RACER] = false; SetPlayerVirtualWorld(playerid, gPlayerData[playerid][E_PLAYER_WORLD]); SetVehicleVirtualWorld(GetPlayerVehicleID(playerid), gPlayerData[playerid][E_PLAYER_WORLD]); DisablePlayerRaceCheckpoint(playerid); DestroyPlayerRaceHUD(playerid); return 1; } return 0;} CreatePlayerRaceHUD(playerid){ gPlayerData[playerid][E_PLAYER_TEXT] = TextDrawCreate(320.0, 240.0, " "); return TextDrawShowForPlayer(playerid, gPlayerData[playerid][E_PLAYER_TEXT]);}DestroyPlayerRaceHUD(playerid){ TextDrawHideForAll(gPlayerData[playerid][E_PLAYER_TEXT]); return TextDrawDestroy(gPlayerData[playerid][E_PLAYER_TEXT]);}UpdatePlayerRaceHUD(playerid){ new HUDText[50]; format(HUDText, sizeof(HUDText), "POS:%d/%d~n~LAP:%d/%d", gPlayerData[playerid][E_PLAYER_CUR_POS], gRaceData[E_RACE_PLAYERS], gPlayerData[playerid][E_PLAYER_CUR_LAP]+1, gRaceData[E_RACE_LAPS]); TextDrawSetString(gPlayerData[playerid][E_PLAYER_TEXT], HUDText); return 1;}SetRaceCheckpoint(playerid){ new cur = gPlayerData[playerid][E_PLAYER_CUR_CP]; return SetPlayerRaceCheckpoint(playerid, cpdata(cur,TYPE), cpdata(cur,XPOS), cpdata(cur,YPOS), cpdata(cur,ZPOS), cpdata(cur+1,XPOS), cpdata(cur+1,YPOS), cpdata(cur+1,ZPOS), cpdata(cur,SIZE)); }public OnPlayerCommandText(playerid, cmdtext[]){ if (!strcmp("/load", cmdtext, true)) { LoadRace("testrace.race"); SendClientMessage(playerid, 0xFFFFFFFF, "Loaded!"); return 1; } if (!strcmp("/start", cmdtext, true)) { StartRace(); SendClientMessage(playerid, 0xFFFFFFFF, "Started!"); return 1; } return 0;}