money = money or 10 --how random the racers stats should be --set to % to +/- original stats by --i.e. a randomness of 25 will make a racer with 100 speed have a range of 75 ~ 125 --set to 0 to keep stats as set in the racer's individual scripts --(0 ~ 99) stat_randomness = 25 --location of the racer stats text on screen (when choosing a racer) local racer_stats_pos_x = 50 local racer_stats_pos_y = 15 local got_racers = false racer = {} local state = "" local tspeed = {} local racer_odds = {} local last_choice = 0 local direction = {} local destx,destz = {},{} local startx,starty,startz,startax,startay,startaz = {},{},{},{},{},{} local distance_travelled = {} local position = {} local total_racers = 0 local stamina = {} local bet = 0 local betting_on_racer = 0 local race_timer = 0 pressed = 0 --**** --[[ to do add money and betting amounts add stamina --]] --use waypoints to define the race tracks function racing_init(e) got_racers = false state = "randomise racers" end function racing_main(e) Panel(80,1,99,6) TextCenterOnX(90,3,3,"You have $"..money) if got_racers == false then local temps = 0 for a,b in pairs (racer_speed) do temps = temps + 1 racer_speed[a] = racer_speed[a] * 100 stamina[a] = math.random(150,150)/100 startx[a],starty[a],startz[a],startax[a],startay[a],startaz[a] = GetEntityPosAng(a) end if temps == 0 then return else got_racers = true state = "reset racers" end else --PromptLocal(e,state) if state == "reset racers" then for a,b in pairs (isRacer) do CharacterControlManual(b) GetPath(b) betting_on_racer = 0 state = "randomise racers" end elseif state == "randomise racers" then total_racers = 0 for a,b in pairs (racer_speed) do local tspd = b*stat_randomness tspeed[b] = b + (math.random(-tspd,tspd)) total_racers = total_racers + 1 distance_travelled[a] = 0 end for a,b in pairs (racer_speed) do racer_odds[a] = total_racers for c,d in pairs (racer_speed) do if a ~= c then if b > d then racer_odds[a] = racer_odds[a] - 1 end end end end last_choice = 0 state = "choose racer" elseif state == "choose racer" then local tempy = 0 local tx = 0 local ty = 0 local tempn = 0 tx = racer_stats_pos_x ty = racer_stats_pos_y+tempy-10 Panel(tx-20,ty-3,tx+20,ty+3) TextCenterOnX(tx,ty,3,"Upcoming race") for a,b in pairs (isRacer) do tempn = tempn + 1 tx = racer_stats_pos_x ty = racer_stats_pos_y+tempy Panel(tx-20,ty-3,tx+20,ty+3) if betting_on_racer == b then TextCenterOnXColor(tx,ty,3,"["..tempn.."]".." "..racer_name[b],0,255,0) else TextCenterOnX(tx,ty,3,"["..tempn.."]".." "..racer_name[b]) end tempy = tempy + 6 tx = racer_stats_pos_x ty = racer_stats_pos_y+tempy Panel(tx-20,ty-3,tx+20,ty+3) TextCenterOnX(tx,ty,3,"win bet multiplier = x "..racer_odds[b]) tempy = tempy + 8 end local scode = GetScancode() if scode > 1 and scode <= tempn+1 then if pressed == 0 then pressed = 1 if last_choice == scode then bet = 1 state = "place bet" end last_choice = scode local tempn = 0 for a,b in pairs (isRacer) do tempn = tempn + 1 if tempn == last_choice-1 then betting_on_racer = b break end end end else pressed = 0 end if last_choice > 0 then if money >= racer_odds[betting_on_racer] then Prompt("Press ["..(last_choice-1).."] again to confirm racer selection") else Prompt("Sorry you don't have the funds to bet on that racer") end else Prompt("Press the number shown in [ ] to pick your racer") end elseif state == "place bet" then FreezePlayer() TextCenterOnX(50,70,3,"Press [Up] or [Down] keys to raise or lower the bet by 1") TextCenterOnX(50,75,3,"Press [Left] or [Right] keys to raise or lower the bet by 10") TextCenterOnX(50,80,3,"Press [Enter] to confirm and place bet") local tempn = 0 local tempy = 0 tx = racer_stats_pos_x ty = racer_stats_pos_y+tempy-8 Panel(tx-20,ty-3,tx+20,ty+3) TextCenterOnX(tx,ty,3,"Place your bets...") ty = ty + 7 Panel(tx-10,ty-3,tx+10,ty+3) TextCenterOnX(tx,ty,3,bet) ty = ty + 7 Panel(tx-10,ty-3,tx+10,ty+3) TextCenterOnX(tx,ty,3,"Win multiplier = x "..racer_odds[betting_on_racer]) local scode = GetScancode() --Prompt(scode) if scode == 200 then if pressed == 0 or GetTimer(e) > 150 then StartTimer(e) pressed = 1 bet = bet + 1 end elseif scode == 205 then if pressed == 0 or GetTimer(e) > 150 then StartTimer(e) pressed = 1 bet = bet + 10 end elseif scode == 208 then if pressed == 0 or GetTimer(e) > 150 then StartTimer(e) pressed = 1 bet = bet - 1 if bet < 1 then bet = 1 end end elseif scode == 203 then if pressed == 0 or GetTimer(e) > 150 then StartTimer(e) pressed = 1 bet = bet - 10 if bet < 1 then bet = 1 end end elseif scode == 28 then if money >= bet then money = money - bet StartTimer(e) state = "racing" UnFreezePlayer() for a,b in pairs (isRacer) do SetAnimation(race_animation[b]) LoopAnimation(b) end else PromptDuration("Not enough money to place that bet!",2000) end else StartTimer(e) pressed = 0 end elseif state == "racing" then local ftime = GetElapsedTime() local tspd = 0 local obj = 0 for a,b in pairs (isRacer) do tspd = (racer_speed[b]*stamina[b])*ftime ModulateSpeed(b,1) obj = g_Entity[b]['obj'] AIEntityGoToPosition(obj,destx[b],destz[b]) MoveForward(b,tspd) SetRotation(b,0,AIGetEntityAngleY(obj),0) AISetEntityPosition(obj,GetEntityPositionX(b),GetEntityPositionY(b),GetEntityPositionZ(b)) distance_travelled[b] = distance_travelled[b] + tspd stamina[b] = stamina[b] - (tspd/20000) if stamina[b] < 0.5 then stamina[b] = 0.5 end --PromptLocal(b,stamina[b]) position[b] = total_racers for c,d in pairs (isRacer) do if distance_travelled[b] > distance_travelled[d] then position[b] = position[b] - 1 end end end local tempn = 0 local tempy = 0 tx = racer_stats_pos_x ty = racer_stats_pos_y+tempy-8 Panel(tx-20,ty-3,tx+20,ty+3) TextCenterOnX(tx,ty,3,"The race is on...") ty = ty + 7 race_timer = GetTimer(e) / 1000 Panel(tx-10,ty-3,tx+10,ty+3) TextCenterOnX(tx,ty,3,"Race time : "..round(race_timer,1).."s") ty = ty + 7 for a = 1, total_racers do for b,c in pairs (isRacer) do if position[c] == a then tx = racer_stats_pos_x Panel(tx-20,ty-3,tx+20,ty+3) if betting_on_racer == c then TextCenterOnXColor(tx,ty,3,"["..a.."]".." "..racer_name[c],0,255,0) else TextCenterOnX(tx,ty,3,"["..a.."]".." "..racer_name[c]) end ty = ty + 6 break end end end for a,b in pairs (isRacer) do local tdestx,tdesty,tdestz = 0,0,0 tdestx = AIPathGetPointX(ai_bot_pathindex[a],ai_bot_pointindex[a]) tdesty = AIPathGetPointY(ai_bot_pathindex[a],ai_bot_pointindex[a]) tdestz = AIPathGetPointZ(ai_bot_pathindex[a],ai_bot_pointindex[a]) if GetDistanceToPoint(a,tdestx,tdesty,tdestz) < 2000 then stamina[b] = ((150/total_racers)*position[b])/100 local temp = math.random(75,125)/100 stamina[b] = stamina[b]*temp if direction[a] == 1 then ai_bot_pointindex[a] = ai_bot_pointindex[a] + 1 if ai_bot_pointindex[a] > ai_bot_pointmax[a] then for c,d in pairs (isRacer) do StopAnimation(c) end winner = b if winner == betting_on_racer then money = money + ((racer_odds[winner]+1)*bet) end state = "show results" StartTimer(e) return end else ai_bot_pointindex[a] = ai_bot_pointindex[a] - 1 if ai_bot_pointindex[a] < 1 then for c,d in pairs (isRacer) do StopAnimation(c) AIEntityStop(g_Entity[d]['obj']) end winner = b if winner == betting_on_racer then money = money + ((racer_odds[winner]+1)*bet) end state = "show results" StartTimer(e) return end end destx[a] = AIPathGetPointX(ai_bot_pathindex[a],ai_bot_pointindex[a]) destz[a] = AIPathGetPointZ(ai_bot_pathindex[a],ai_bot_pointindex[a]) end end elseif state == "show results" then if GetTimer(e) > 2000 then state = "reset race" return end local tempn = 0 local tempy = 0 tx = racer_stats_pos_x ty = racer_stats_pos_y+tempy-8 Panel(tx-20,ty-3,tx+20,ty+3) TextCenterOnX(tx,ty,3,"And the winner is...") tempn = tempn + 1 tx = racer_stats_pos_x ty = racer_stats_pos_y+tempy Panel(tx-20,ty-3,tx+20,ty+3) if betting_on_racer == winner then TextCenterOnXColor(tx,ty,3,racer_name[winner].."!",0,255,0) else TextCenterOnX(tx,ty,3,racer_name[winner].."!") end ty = ty + 7 Panel(tx-10,ty-3,tx+10,ty+3) TextCenterOnX(tx,ty,3,"Winning time : "..round(race_timer,1).."s") if winner == betting_on_racer then Prompt("Congratulations you won $"..((racer_odds[winner]+1)*bet)) else Prompt("Better luck next time!") end elseif state == "reset race" then for a,b in pairs (isRacer) do destx[b] = startx[b] destz[b] = startz[b] local obj = g_Entity[b]['obj'] SetPosition(b,startx[b],starty[b],startz[b]) ResetPosition(b,startx[b],starty[b],startz[b]) SetRotation(b,startax[b],startay[b],startaz[b]) ResetRotation(b,startax[b],startay[b],startaz[b]) SetRotation(b,0,AIGetEntityAngleY(obj),0) AIEntityGoToPosition(obj,startx[b],starty[b],startz[b]) AISetEntityPosition(obj,startx[b],starty[b],startz[b]) AIEntityStop(obj) end StartTimer(e) state = "reset race2" elseif state == "reset race2" then if GetTimer(e) > 250 then state = "reset racers" end end end end function racing_exit(e) end function GetPath(a) PathIndex = -1 PointIndex = 2 pClosest = 99999 for pa = 1, AIGetTotalPaths(), 1 do for po = 1 , AIGetPathCountPoints(pa), 1 do pDX = g_Entity[a]['x'] - AIPathGetPointX(pa,po) pDY = g_Entity[a]['y'] - AIPathGetPointY(pa,po) pDZ = g_Entity[a]['z'] - AIPathGetPointZ(pa,po) pDist = math.sqrt(math.abs(pDX*pDX)+math.abs(pDY*pDY)+math.abs(pDZ*pDZ)); if pDist < pClosest and pDist < 120 then pClosest = pDist PathIndex = pa PointIndex = po end end -- po end -- pa ai_bot_pathindex[a] = PathIndex if PathIndex > -1 then direction[a] = 1 ai_bot_pointmax[a] = AIGetPathCountPoints(PathIndex) if PointIndex+1 > ai_bot_pointmax[a] then direction[a] = -1 end ai_bot_pointindex[a] = PointIndex destx[a] = AIPathGetPointX(ai_bot_pathindex[a],ai_bot_pointindex[a]) destz[a] = AIPathGetPointZ(ai_bot_pathindex[a],ai_bot_pointindex[a]) end end function GetDistanceToPoint(e,x,y,z) local dx, dy, dz = g_Entity[e]['x'] - x, g_Entity[e]['y'] - y, g_Entity[e]['z'] - z return dx*dx+dy*dy+dz*dz end function round(num, numDecimalPlaces) local mult = 10^(numDecimalPlaces or 0) return math.floor(num * mult + 0.5) / mult end