Advertisement
HR_Shaft

Taxi v3 for SAPP

Jan 1st, 2017
594
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 12.27 KB | None | 0 0
  1. -- Taxi v3 for SAPP by H® Shaft 1/1/2017
  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. -- Flag and Oddball holders cannot hail a taxi
  6. -- After a player dies, they may not hail a taxi until the hail_delay (below) expires
  7.  
  8. -- Changelog:
  9. -- Works with all Halo PC/CE maps
  10. -- taxi enabled by default for all maps (no longer need to enable per-map)
  11. -- added feature: Flag and Oddball holders cannot hail a taxi
  12. -- When a player dies, a player must wait until hail_delay (below) is expired
  13. -- may not perform well in non-standard custom vehicles with odd seating
  14.  
  15. -- what message will be shown to players on joining
  16. reminder_message = "Taxi is ENABLED: Press your crouch key, or type TAXI to hail a taxi and ride with a teammate."
  17.  
  18. -- Taxi Hailing Delay: amount of time, in seconds a player must wait after dying before they can hail a taxi
  19. -- This addresses the complaint that in race, a driver/gunner team is sometimes hard to eliminate, if only one is killed
  20. hail_delay = 10
  21.  
  22. -- do not touch --
  23. api_version = "1.9.0.0"
  24. taxi, hails = {}, {}
  25. taxi_delay = 2 -- do not edit this
  26. game_started = false
  27.  
  28. function OnScriptLoad()
  29.     register_callback(cb['EVENT_TICK'], "OnTaxiCall")
  30.     register_callback(cb['EVENT_DIE'], "OnPlayerDeath")
  31.     register_callback(cb['EVENT_JOIN'], "OnPlayerJoin")
  32.     register_callback(cb['EVENT_LEAVE'], "OnPlayerLeave")  
  33.     register_callback(cb['EVENT_GAME_START'], "OnNewGame")
  34.     register_callback(cb['EVENT_GAME_END'], "OnGameEnd")
  35.     register_callback(cb['EVENT_CHAT'], "OnPlayerChat")
  36.     if get_var(0, "$gt") ~= "n/a" then 
  37.         game_started = true
  38.         for i=1,16 do
  39.             if player_present(i) then
  40.                 hails[i] = 0   
  41.             end
  42.         end        
  43.     end
  44. end
  45.  
  46. function OnScriptUnload()
  47.     taxi, hails = {}, {}
  48. end
  49.  
  50. -- on new game, set values
  51. function OnNewGame()
  52.     game_started = true
  53.     for i=1,16 do
  54.         if player_present(i) then
  55.             hails[i] = 0   
  56.         end
  57.     end    
  58. end
  59.  
  60. -- on game end, set values
  61. function OnGameEnd()
  62.     game_started = false
  63. end
  64.  
  65.  
  66. -- when player joins, set their values, set timer to notify if taxi is enabled, after welcome messages scroll
  67. function OnPlayerJoin(PlayerIndex)
  68.     if player_present(PlayerIndex) then
  69.         hails[PlayerIndex] = 0
  70.         notice = timer(12000, "TimedJoinNotice", PlayerIndex)      
  71.     end
  72. end
  73.  
  74. -- when player joins, notify if taxi is enabled, after welcome messages scroll
  75. function TimedJoinNotice(PlayerIndex)
  76.     if game_started and player_present(PlayerIndex) then
  77.         say(PlayerIndex, reminder_message)         
  78.     end
  79.     return false   
  80. end
  81.  
  82. -- when player leaves, nil their values
  83. function OnPlayerLeave(PlayerIndex)
  84.     if player_present(PlayerIndex) then
  85.         hails[PlayerIndex] = nil
  86.     end
  87. end
  88.  
  89. -- when player dies, set hail delay, set flag status
  90. function OnPlayerDeath(PlayerIndex, KillerIndex)
  91.     if player_present(PlayerIndex) then
  92.         if game_started then
  93.             hails[PlayerIndex] = (taxi_delay + hail_delay *30)
  94.         end
  95.     end
  96. end
  97.  
  98. -- monitor player crouch key press
  99. function OnTaxiCall()
  100.     for i=1,16 do
  101.         if player_present(i) then
  102.             local player_object = get_dynamic_player(i)
  103.             if (player_object ~= 0) then
  104.                 if hails[i] > 0 then hails[i] = hails[i] - 1 end
  105.                 if not isinvehicle(i) then
  106.                     local player_crouch = bit.band(read_dword(player_object + 0x208),7)
  107.                     local id = i
  108.                     if (player_crouch == 1) and (taxi[id] == nil) then
  109.                         taxi[id] = OnPlayerCrouch(id)
  110.                     elseif player_crouch ~= 1 and taxi[id] ~= nil then
  111.                         taxi[id] = nil
  112.                     end
  113.                 end
  114.             end
  115.         end    
  116.     end
  117. end
  118.  
  119. -- called from OnTaxiCall, sets a delay between crouch activations of taxi
  120. function OnPlayerCrouch(PlayerIndex)
  121.     if game_started then
  122.         if hails[PlayerIndex] == 0 then
  123.             getTaxi(PlayerIndex)
  124.             hails[PlayerIndex] = (taxi_delay*30)
  125.         end
  126.     end
  127.     return false
  128. end
  129.  
  130. -- players can hail a taxi by typing "taxI" and - includes common typo's
  131. function OnPlayerChat(PlayerIndex, Message)
  132.     local response = nil
  133.     local name = get_var(PlayerIndex,"$name")
  134.     local Message = string.lower(Message)
  135.     if (Message == "taxi") or (Message == "/taxi") or (Message == "taxo") or (Message == "taxci") or (Message == "taci") then
  136.         response = false
  137.         if player_present(PlayerIndex) then
  138.             if game_started then
  139.                 if player_alive(PlayerIndex) then
  140.                     if not Has_Objective(PlayerIndex) then
  141.                         if isinvehicle(PlayerIndex) then
  142.                             say(PlayerIndex, "**Taxi**  You are already in a vehicle.")
  143.                         else
  144.                             getTaxi(PlayerIndex)
  145.                         end
  146.                     else
  147.                         say(PlayerIndex, "**Taxi**  You cannot hail a taxi while you have the flag or oddball.")
  148.                     end
  149.                 else
  150.                     say(PlayerIndex, "**Taxi**  You are dead. Try again after you respawn.")
  151.                 end
  152.             else
  153.                 say(PlayerIndex, "**Taxi**  Game has ended. Please wait until a new game begins.")
  154.             end
  155.         end
  156.     end
  157.     return response
  158. end
  159.  
  160. -- seek for an available taxi
  161. function getTaxi(PlayerIndex)
  162.     if not Has_Objective(PlayerIndex) then
  163.         local player2
  164.         local team = get_var(PlayerIndex,"$team")
  165.         for i = 1,16 do
  166.             if PlayerIndex ~= i and get_var(i,"$team") == team and isinvehicle(i) and CheckSeats(i, GetplayerVehicleId(i)) > 0 then
  167.                 player2 = i
  168.                 break
  169.             end
  170.         end
  171.         if player2 then
  172.             if CheckSeats(player2, GetplayerVehicleId(player2)) > 0 then
  173.                 InjectPlayer(PlayerIndex, GetplayerVehicleId(player2), true)
  174.             end
  175.         elseif not player2 then
  176.             say(PlayerIndex, "**Taxi**  Sorry no taxi available. Please try again later.") 
  177.         end
  178.     else
  179.         say(PlayerIndex, "**Taxi**  You cannot hail a taxi while you have the flag or oddball.")
  180.     end
  181. end
  182.  
  183. -- inserts selected player into selected vehicle, first to driver, then to gunner, then to passenger seats
  184. function InjectPlayer(PlayerIndex, vehicleId, count)
  185.     if (player_alive(PlayerIndex) ~= true) then return false end
  186.     local bool = false
  187.     if player_alive(PlayerIndex) then
  188.         local name = get_var(PlayerIndex,"$name")
  189.         if vehicleId ~= false then
  190.             local veh_obj = get_object_memory(vehicleId)
  191.             local driver = read_dword(veh_obj + 0x324)
  192.             local gunner = read_dword(veh_obj + 0x328)
  193.             local passenger = read_dword(veh_obj + 0x32C)  
  194.             if driver == 0xFFFFFFFF then
  195.                 enter_vehicle(vehicleId, PlayerIndex, 0)
  196.                 bool = true
  197.             elseif gunner == 0xFFFFFFFF then
  198.                 enter_vehicle(vehicleId, PlayerIndex, 2)
  199.                 bool = true
  200.             elseif (passenger == 0xFFFFFFFF or passenger  == 0) then
  201.                 enter_vehicle(vehicleId, PlayerIndex, 1)
  202.                 bool = true
  203.             end
  204.             if bool and count then
  205.                 say(PlayerIndex, "**Taxi**  You called a taxi, welcome aboard!")
  206.             end
  207.         end
  208.     end
  209. end
  210.  
  211. -- returns the number of available seats in players vehicle, requires GetVehicleSeats function
  212. function CheckSeats(PlayerIndex, vehicleId)
  213.     if player_alive(PlayerIndex) then
  214.         local seats = GetVehicleSeats(PlayerIndex, vehicleId)
  215.         local team = get_var(PlayerIndex,"$team")
  216.         if (vehicleId ~= nil) then
  217.             if seats > 0  then
  218.                 for i = 1,16 do
  219.                     if PlayerIndex ~= i and player_alive(i) and get_var(i,"$team") == team and isinvehicle(i) then
  220.                         if GetplayerVehicleId(i) == vehicleId then
  221.                             seats = seats - 1
  222.                         end
  223.                     end
  224.                 end
  225.             end
  226.             return seats
  227.         end
  228.     end    
  229. end
  230.  
  231. -- returns number of seats in selected vehicle, sets the number of seats (some vehicles have seats not correctly setup)
  232. -- return the number of vehicle seats not including the driver
  233. function GetVehicleSeats(PlayerIndex, m_vehicleId)
  234.     if (player_alive(PlayerIndex) == false) then return false end
  235.     if m_vehicleId ~= false then
  236.         local avail_seats = 0
  237.         local veh_name = string.lower(GetPlayerVehicleTagName(PlayerIndex))
  238.         if veh_name ~= nil then
  239.             if string.find(veh_name, "ghost") or string.find(veh_name, "banshee") or string.find(veh_name, "turret") or string.find(veh_name, "snowhog") or string.find(veh_name, "hogfoot") or string.find(veh_name, "civi") then
  240.                 avail_seats = 0    
  241.             elseif string.find(veh_name, "hog") or string.find(veh_name, "hawg") or string.find(veh_name, "puma") then
  242.                 avail_seats = 2
  243.             elseif string.find(veh_name, "scorpion") or string.find(veh_name, "falcon") or string.find(veh_name, "car") then
  244.                 avail_seats = 1
  245.             else
  246.                 avail_seats = 0
  247.             end
  248.             local seats = avail_seats
  249.             return tonumber(seats)
  250.         end
  251.     else
  252.         return false
  253.     end
  254. end
  255.  
  256. -- returns vehicle tag name of players vehicle for function GetVehicleSeats, which sets number of available seats in the vehicle
  257. function GetPlayerVehicleTagName(PlayerIndex)
  258.     if isinvehicle(PlayerIndex) and game_started then
  259.         local player_object = get_dynamic_player(PlayerIndex)
  260.         local vehicleId = read_dword(player_object + 0x11C)
  261.         local vehicle_obj = get_object_memory(vehicleId)
  262.         if (vehicle_obj ~= 0) then
  263.             local vehicle_metaid = read_dword(vehicle_obj)     
  264.             local veh_name = get_vehicle_name(vehicle_metaid)
  265.             if veh_name ~= nil and veh_name ~= "NULL METAID" then
  266.                 return veh_name
  267.             else
  268.                 return nil
  269.             end
  270.         end
  271.     end
  272. end
  273.  
  274. -- returns vehicle object id player is in, or false
  275. function GetplayerVehicleId(PlayerIndex)
  276.     if (player_alive(PlayerIndex) == false) then return false end
  277.     local player_object = get_dynamic_player(PlayerIndex)
  278.     local vehicleId = read_dword(player_object + 0x11C)
  279.     if (vehicleId ~= 0xFFFFFFFF) then return vehicleId else return false end
  280. end
  281.  
  282. function get_vehicle_name(MetaID) -- Thanks to Giraffe!
  283.     if (MetaID == 0xFFFFFFFF) then
  284.         return "NULL METAID"
  285.     else
  286.         local globals_tag = lookup_tag("matg", "globals\\globals")
  287.         local globals_data = read_dword(globals_tag + 0x14)
  288.         local interface_bitmaps_data = read_dword(globals_data + 0x144)
  289.         local hud_globals_metaid = read_dword(interface_bitmaps_data + 0x6C)
  290.         local hud_globals_tag = lookup_tag(hud_globals_metaid)
  291.         local hud_globals_data = read_dword(hud_globals_tag + 0x14)
  292.         local hud_icon_messages_metaid = read_dword(hud_globals_data + 0xC0)
  293.         local hud_icon_messages_tag = lookup_tag(hud_icon_messages_metaid)
  294.         local hud_icon_messages_data = read_dword(hud_icon_messages_tag + 0x14)
  295.         local string_references_count = read_dword(hud_icon_messages_data)
  296.         local string_references_data = read_dword(hud_icon_messages_data + 0x4)
  297.         local strings = {}
  298.         for i=0,string_references_count-1 do
  299.             local bytes = read_dword(string_references_data + i*20)
  300.             local string_data = read_dword(string_references_data + i*20 + 0xC)
  301.             local string = ''
  302.             for j=0,bytes-3,2 do
  303.                 string = string .. string.char(read_char(string_data +j))
  304.             end
  305.             strings[i] = string
  306.         end
  307.         local vehicle_tag = lookup_tag(MetaID)
  308.         local vehicle_data = read_dword(vehicle_tag + 0x14)
  309.         local hud_text_message_index = read_short(vehicle_data + 0x13C)
  310.         if(strings[hud_text_message_index] ~= nil) then
  311.             return strings[hud_text_message_index]
  312.         else
  313.             return strings[0]
  314.         end
  315.     end
  316. end
  317.  
  318. function isinvehicle(PlayerIndex)
  319.     local player_object = get_dynamic_player(PlayerIndex)
  320.     if player_object ~= 0 then
  321.         local vehicleId = read_dword(player_object + 0x11C)
  322.         if vehicleId == 0xFFFFFFFF then
  323.             return false
  324.         else
  325.             return true
  326.         end
  327.     else
  328.         return false
  329.     end
  330. end
  331.  
  332. -- iterates thru all players weapons, returns true if they have flag or oddball, if not, returns false
  333. -- this is specifically checking the 'must be readied' flag of each of their weapons
  334. function Has_Objective(PlayerIndex)
  335.     local response = false
  336.     if get_var(0, "$gt") ~= "n/a" then
  337.         if (get_var(0, "$gt") == "ctf") or (get_var(0, "$gt") == "oddball") then
  338.             local player_object = get_dynamic_player(PlayerIndex)
  339.             for w=0,3 do
  340.                 local weap_id = read_dword(player_object + 0x2F8 + 0x4 * w)
  341.                 if (weap_id ~= 0xFFFFFFFF) then
  342.                     local weap_obj = get_object_memory(weap_id)
  343.                     if (weap_obj ~= 0) then
  344.                         local obj_type = read_byte(weap_obj + 0xB4)
  345.                         local tag_address = read_word(weap_obj)
  346.                         local tagdata = read_dword(read_dword(0x40440000) + tag_address * 0x20 + 0x14)
  347.                         if (read_bit(tagdata + 0x308,3) == 1) then
  348.                             response = true
  349.                         end
  350.                     end    
  351.                 end
  352.             end    
  353.         end
  354.     end
  355.     return response
  356. end
  357.  
  358. function OnError(Message)
  359.     print(debug.traceback())
  360. end
  361.  
  362. -- Created by H® Shaft
  363. -- Visit http://halorace.org/forum/index.php
  364.  
  365. -- The player -db-GoNe/Juhleek - a well spoken liar, cheat.
  366. -- -db- is: "diverging from the believable" - How ironic. A race clan where admins use rcon to favor themselves to win.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement