SHARE
TWEET

Taxi v2 for SAPP

HR_Shaft Aug 7th, 2016 123 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. -- Taxi v2 for SAPP by H® Shaft 8/7/2016
  2.  
  3. -- Allows walking players to hitch a ride/teleported into a teammates vehicle.
  4. -- To hail a taxi, just press crouch key - Or, type "Taxi" in the chat.
  5. -- Can be used with all gametypes. Best used with "team" gametypes in Stock PC/CE maps and unprotected CE maps, which use stock vehicles/flags
  6. -- Flag holders in CTF cannot hail a taxi
  7. -- When a player dies, a player must wait until hail_delay (below) is expired
  8. -- Enable or disable taxi, and passenger seat on a per-map basis, see line 374, function LoadDefaults
  9.  
  10. -- How often (in seconds) to remind walking players if taxi is enabled, default 120 seconds = 2 min (too often will be annoying)
  11. taxi_reminder = 120
  12.  
  13. -- what message will be shown to players on joining (only shown if taxi is enabled for the map, see line 374, function LoadDefaults)
  14. reminder_message = "Taxi is ENABLED: Press your crouch key, or type TAXI to hail a taxi (be put into a teammates vehicle)."
  15.  
  16. -- Taxi Hailing Delay: amount of time, in seconds a player must wait after dying before they can hail a taxi
  17. -- This addresses the complaint that in race, a driver/gunner team is sometimes hard to eliminate, if only one is killed
  18. hail_delay = 10
  19.  
  20. -- do not touch --
  21. api_version = "1.9.0.0"
  22. taxi, hails, enable_taxi, enable_passenger, has_flag = {}, {}, {}, {}, {}
  23. taxi_delay = 2 -- do not edit this
  24. game_started = false
  25.  
  26. function OnScriptLoad()
  27.     register_callback(cb['EVENT_TICK'], "OnTaxiCall")
  28.     register_callback(cb['EVENT_DIE'], "OnPlayerDeath")
  29.     register_callback(cb['EVENT_JOIN'], "OnPlayerJoin")
  30.     register_callback(cb['EVENT_LEAVE'], "OnPlayerLeave")  
  31.     register_callback(cb['EVENT_GAME_START'], "OnNewGame")
  32.     register_callback(cb['EVENT_GAME_END'], "OnGameEnd")
  33.     register_callback(cb['EVENT_CHAT'], "OnPlayerChat")
  34.     -- retrieve meta-ids if game is running
  35.     if get_var(0, "$gt") ~= "n/a" then 
  36.         game_started = true
  37.         game_type = get_var(0, "$gt")
  38.         if game_type == "ctf" then
  39.             GetMetaID()
  40.         end
  41.     end
  42.     -- set default values on load, or if script is reloaded
  43.     if game_started then
  44.         game_started = true
  45.         map_name = get_var(0,"$map")
  46.         game_type = get_var(0, "$gt")      
  47.         LoadDefaults()
  48.         for i=1,16 do
  49.             if player_present(i) then
  50.                 hails[i] = 0
  51.                 if game_type == "ctf" then
  52.                     local player_object = get_dynamic_player(i)
  53.                     if (player_object ~= 0) then
  54.                         if PlayerHasFlag(i) then has_flag[i] = true else has_flag[i] = false end   
  55.                     end
  56.                 end    
  57.             end
  58.         end        
  59.     end
  60. end
  61.  
  62. function OnScriptUnload()
  63.     taxi, hails, enable_taxi, enable_passenger, has_flag = {}, {}, {}, {}, {}
  64. end
  65.  
  66. -- on new game, set values
  67. function OnNewGame()
  68.     game_started = true
  69.     map_name = get_var(0,"$map")
  70.     game_type = get_var(0, "$gt")
  71.     if game_type == "ctf" then
  72.         GetMetaID()
  73.     end
  74.     LoadDefaults()
  75.     reminder = timer(taxi_reminder * 1000, "TimedReminder")
  76.     for i=1,16 do
  77.         if player_present(i) then
  78.             hails[i] = 0
  79.             has_flag[i] = false    
  80.         end
  81.     end    
  82. end
  83.  
  84. -- on game end, set values
  85. function OnGameEnd()
  86.     game_started = false
  87. end
  88.  
  89. -- on new game, set recurring reminder if taxi is enabled, show to all players
  90. function TimedReminder()
  91.     if game_started then
  92.         for i=1,16 do
  93.             if player_present(i) then
  94.                 if (enable_taxi[map_name] == true) then
  95.                     say(i, reminder_message)
  96.                 end
  97.             end
  98.         end    
  99.         return true
  100.     else   
  101.         return false   
  102.     end
  103. end
  104.  
  105. -- when player joins, set their values, set timer to notify if taxi is enabled, after welcome messages scroll
  106. function OnPlayerJoin(PlayerIndex)
  107.     if player_present(PlayerIndex) then
  108.         hails[PlayerIndex] = 0
  109.         has_flag[PlayerIndex] = false
  110.         notice = timer(12000, "TimedJoinNotice", PlayerIndex)      
  111.     end
  112. end
  113.  
  114. -- when player joins, notify if taxi is enabled, after welcome messages scroll
  115. function TimedJoinNotice(PlayerIndex)
  116.     if game_started and player_present(PlayerIndex) then
  117.         if (enable_taxi[map_name] == true) then
  118.             say(PlayerIndex, reminder_message)         
  119.         end
  120.     end
  121.     return false   
  122. end
  123.  
  124. -- when player leaves, nil their values
  125. function OnPlayerLeave(PlayerIndex)
  126.     if player_present(PlayerIndex) then
  127.         hails[PlayerIndex] = nil
  128.         has_flag[PlayerIndex] = nil
  129.     end
  130. end
  131.  
  132. -- when player dies, set hail delay, set flag status
  133. function OnPlayerDeath(PlayerIndex, KillerIndex)
  134.     if player_present(PlayerIndex) then
  135.         if game_started then
  136.             has_flag[PlayerIndex] = false
  137.             hails[PlayerIndex] = (taxi_delay + hail_delay *30)
  138.         end
  139.     end
  140. end
  141.  
  142. -- monitor player crouch key press, and flag possession
  143. function OnTaxiCall()
  144.     for i=1,16 do
  145.         if player_present(i) then
  146.             local player_object = get_dynamic_player(i)
  147.             if (player_object ~= 0) then
  148.                 if hails[i] > 0 then hails[i] = hails[i] - 1 end
  149.                 if game_type == "ctf" then
  150.                     if PlayerHasFlag(i) then has_flag[i] = true else has_flag[i] = false end
  151.                 end
  152.                 if not isinvehicle(i) then
  153.                     local player_crouch = bit.band(read_dword(player_object + 0x208),7)
  154.                     local id = i
  155.                     if (player_crouch == 1) and (taxi[id] == nil) then
  156.                         taxi[id] = OnPlayerCrouch(id)
  157.                     elseif player_crouch ~= 1 and taxi[id] ~= nil then
  158.                         taxi[id] = nil
  159.                     end
  160.                 end
  161.             end
  162.         end    
  163.     end
  164. end
  165.  
  166. -- called from OnTaxiCall, sets a delay between crouch activations of taxi
  167. function OnPlayerCrouch(PlayerIndex)
  168.     if game_started then
  169.         if hails[PlayerIndex] == 0 then
  170.             getTaxi(PlayerIndex)
  171.             hails[PlayerIndex] = (taxi_delay*30)
  172.         end
  173.     end
  174.     return false
  175. end
  176.  
  177. -- players can hail a taxi by typing "taxI" and - includes common typo's
  178. function OnPlayerChat(PlayerIndex, Message)
  179.     local response = nil
  180.     local name = get_var(PlayerIndex,"$name")
  181.     local Message = string.lower(Message)
  182.     if (Message == "taxi") or (Message == "/taxi") or (Message == "taxo") or (Message == "taxci") or (Message == "taci") then
  183.         response = false
  184.         if player_present(PlayerIndex) then
  185.             if game_started then
  186.                 if player_alive(PlayerIndex) then
  187.                     if isinvehicle(PlayerIndex) then
  188.                         say(PlayerIndex, "**Taxi**  You are already in a vehicle.")
  189.                     else
  190.                         getTaxi(PlayerIndex)
  191.                     end
  192.                 else
  193.                     say(PlayerIndex, "**Taxi**  You are dead. Try again after you respawn.")
  194.                 end
  195.             else
  196.                 say(PlayerIndex, "**Taxi**  Game has ended. Please wait until a new game begins.")
  197.             end
  198.         end
  199.     end
  200.     return response
  201. end
  202.  
  203. -- seek for an available taxi
  204. function getTaxi(PlayerIndex)
  205.     if (enable_taxi[map_name] == true) then
  206.         if (has_flag[PlayerIndex] == false) then
  207.             local player2
  208.             local team = get_var(PlayerIndex,"$team")
  209.             for i = 1,16 do
  210.                 if PlayerIndex ~= i and get_var(i,"$team") == team and isinvehicle(i) and CheckSeats(i, GetplayerVehicleId(i)) > 0 then
  211.                     player2 = i
  212.                     break
  213.                 end
  214.             end
  215.             if player2 then
  216.                 if CheckSeats(player2, GetplayerVehicleId(player2)) > 0 then
  217.                     InjectPlayer(PlayerIndex, GetplayerVehicleId(player2), true)
  218.                 end
  219.             elseif not player2 then
  220.                 say(PlayerIndex, "**Taxi**  Sorry no taxi available. Please try again later.") 
  221.             end
  222.         else
  223.             say(PlayerIndex, "**Taxi**  You cannot hail a taxi while you have the flag.")
  224.         end
  225.     else
  226.         say(PlayerIndex, "**Taxi**  Is not enabled for this map.")
  227.     end
  228. end
  229.  
  230. -- inserts selected player into selected vehicle, first to driver, then to gunner, then to passenger seats
  231. function InjectPlayer(PlayerIndex, vehicleId, count)
  232.     if (player_alive(PlayerIndex) ~= true) then return false end
  233.     local bool = false
  234.     if player_alive(PlayerIndex) then
  235.         local name = get_var(PlayerIndex,"$name")
  236.         if vehicleId ~= false then
  237.             local veh_obj = get_object_memory(vehicleId)
  238.             local driver = read_dword(veh_obj + 0x324)
  239.             local gunner = read_dword(veh_obj + 0x328)
  240.             local passenger = read_dword(veh_obj + 0x32C)  
  241.             if driver == 0xFFFFFFFF then
  242.                 enter_vehicle(vehicleId, PlayerIndex, 0)
  243.                 bool = true
  244.             elseif gunner == 0xFFFFFFFF then
  245.                 enter_vehicle(vehicleId, PlayerIndex, 2)
  246.                 bool = true
  247.             elseif enable_passenger and (passenger == 0xFFFFFFFF or passenger  == 0) then
  248.                 enter_vehicle(vehicleId, PlayerIndex, 1)
  249.                 bool = true
  250.             end
  251.             if bool and count then
  252.                 say(PlayerIndex, "**Taxi**  You called a taxi, welcome aboard!")
  253.             end
  254.         end
  255.     end
  256. end
  257.  
  258. -- returns the number of available seats in players vehicle, requires GetVehicleSeats function
  259. function CheckSeats(PlayerIndex, vehicleId)
  260.     if player_alive(PlayerIndex) then
  261.         local seats = GetVehicleSeats(PlayerIndex, vehicleId)
  262.         local team = get_var(PlayerIndex,"$team")
  263.         if (vehicleId ~= nil) then
  264.             if seats > 0  then
  265.                 for i = 1,16 do
  266.                     if PlayerIndex ~= i and player_alive(i) and get_var(i,"$team") == team and isinvehicle(i) then
  267.                         if GetplayerVehicleId(i) == vehicleId then
  268.                             seats = seats - 1
  269.                         end
  270.                     end
  271.                 end
  272.             end
  273.             return seats
  274.         end
  275.     end    
  276. end
  277.  
  278. -- returns number of seats in selected vehicle, sets the number of seats (some vehicles have seats not correctly setup)
  279. -- return the number of vehicle seats not including the driver
  280. function GetVehicleSeats(PlayerIndex, m_vehicleId)
  281.     if (player_alive(PlayerIndex) == false) then return false end
  282.     if m_vehicleId ~= false then
  283.         local avail_seats = 0
  284.         local veh_name = GetPlayerVehicleTagName(PlayerIndex)
  285.         if veh_name ~= nil then
  286.             if string.find(veh_name, "ghost") or string.find(veh_name, "banshee") or string.find(veh_name, "turret") then
  287.                 avail_seats = 0    
  288.             elseif string.find(veh_name, "hog") then
  289.                 avail_seats = 2
  290.             elseif string.find(veh_name, "scorpion") then
  291.                 avail_seats = 1
  292.             else
  293.                 avail_seats = 0
  294.             end
  295.             local seats = avail_seats
  296.             return tonumber(seats)
  297.         end
  298.     else
  299.         return 0
  300.     end
  301. end
  302.  
  303. -- returns vehicle tag name of players vehicle for function GetVehicleSeats, which sets number of available seats in the vehicle
  304. function GetPlayerVehicleTagName(PlayerIndex)
  305.     if isinvehicle(PlayerIndex) then
  306.         local player_object = get_dynamic_player(PlayerIndex)
  307.         local vehicleId = read_dword(player_object + 0x11C)
  308.         local vehicle_obj = get_object_memory(vehicleId)
  309.         local veh_name = read_string(read_dword(read_word(vehicle_obj) * 32 + 0x40440038))
  310.         if veh_name ~= nil then
  311.             return veh_name
  312.         else
  313.             return nil
  314.         end
  315.     end
  316. end
  317.  
  318. -- returns vehicle object id player is in, or false
  319. function GetplayerVehicleId(PlayerIndex)
  320.     if (player_alive(PlayerIndex) == false) then return false end
  321.     local player_object = get_dynamic_player(PlayerIndex)
  322.     local vehicleId = read_dword(player_object + 0x11C)
  323.     if (vehicleId ~= 0xFFFFFFFF) then return vehicleId else return false end
  324. end
  325.  
  326. -- returns true if player is in a vehicle, or false if not -- edited 7/20/2016
  327. function isinvehicle(PlayerIndex)  
  328.     local player_object = get_dynamic_player(PlayerIndex)
  329.     if player_object ~= 0 then
  330.         local vehicleId = read_dword(player_object + 0x11C)
  331.         if vehicleId == 0xFFFFFFFF then
  332.             return false
  333.         else
  334.             return true
  335.         end
  336.     else
  337.         return false
  338.     end
  339. end
  340.  
  341. -- returns true if player has the flag during ctf games, false if not, requires function GetMetaID()
  342. function PlayerHasFlag(PlayerIndex)
  343.     if game_started then
  344.         local player_object = get_dynamic_player(PlayerIndex)
  345.         if player_object ~= 0 then
  346.             local weaponId = read_dword(player_object + 0x118)
  347.             local weap_obj = get_object_memory(weaponId)
  348.             if weap_obj ~= 0 then
  349.                 local weapon_metaid = read_dword(weap_obj)
  350.                 if (weapon_metaid == flag_metaid) then
  351.                     return true
  352.                 else
  353.                     return false
  354.                 end
  355.             end
  356.         else
  357.             return false
  358.         end
  359.     else
  360.         return false
  361.     end
  362. end
  363.  
  364. -- retrieves flag metaid, sets players flag value to false
  365. function GetMetaID()
  366.     flag_metaid = read_dword(lookup_tag("weap", "weapons\\flag\\flag") + 12)
  367.     for i = 1, 16 do
  368.         has_flag[i] = false
  369.     end
  370. end
  371.  
  372. -- set defaults on a per map basis, entire map name should be within quotes, even when map name has
  373. -- square brackets, parenthesis, periods; example: ["[h3] core"]
  374. function LoadDefaults()
  375.     -- default enable/disable TAXI for the specified map: true = enable, false = disable
  376.     enable_taxi = {
  377.         ["beavercreek"] = false,
  378.         ["bloodgulch"] = true,
  379.         ["boardingaction"] = true,
  380.         ["carousel"] = false,
  381.         ["chillout"] = false,
  382.         ["damnation"] = false,
  383.         ["dangercanyon"] = true,
  384.         ["deathisland"] = true,
  385.         ["gephyrophobia"] = true,
  386.         ["hangemhigh"] = false,
  387.         ["icefields"] = true,
  388.         ["infinity"] = true,
  389.         ["longest"] = false,
  390.         ["prisoner"] = false,
  391.         ["putput"] = false,
  392.         ["ratrace"] = false,
  393.         ["sidewinder"] = true,
  394.         ["timberland"] = true,
  395.         ["wizard"] = false
  396.     }
  397.     -- default enable/disable taxi to PASSENGER seat for the specified map: true = enable, false = disable
  398.     -- ignored if taxi is disabled for the map
  399.     enable_passenger = {
  400.         ["beavercreek"] = false,
  401.         ["bloodgulch"] = true,
  402.         ["boardingaction"] = false,
  403.         ["carousel"] = false,
  404.         ["chillout"] = false,
  405.         ["damnation"] = false,
  406.         ["dangercanyon"] = true,
  407.         ["deathisland"] = true,
  408.         ["gephyrophobia"] = true,
  409.         ["hangemhigh"] = false,
  410.         ["icefields"] = true,
  411.         ["infinity"] = true,
  412.         ["longest"] = false,
  413.         ["prisoner"] = false,
  414.         ["putput"] = false,
  415.         ["ratrace"] = false,
  416.         ["sidewinder"] = true,
  417.         ["timberland"] = true,
  418.         ["wizard"] = false
  419.     }  
  420. end
  421.  
  422. function OnError(Message)
  423.     print(debug.traceback())
  424. end
  425.  
  426. -- Created by H® Shaft
  427. -- Visit http://halorace.org/forum/index.php
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top