--[[ ### Taxi v5 for Phasor v2 ###]]-- --[[ ### by H® Shaft, AElitePrime & H® BugZ ###]]-- -- Intended to be used as a Persistent Script -- What does it do? If your team are in warthogs/tanks, taxi will insert you a seat into one of their vehicles by crouching or typing "taxi" -- type 'gun me' and pickup a gunner, type 'eject' to kick em out! -- Version 4: Anti Hog Camping, Hog Spawn, Passenger Weapon, Show Players in Vehicle (type 'whois'), Per-Map Toggle Don't like this version? Use version 4: http://pastebin.com/EYqiMWU4 -- Version 5 Changelog: -- Added crouch detection that is does not accidentally activate on impact/falling crouch if crouch-to-taxi is enabled. -- Fine tuned some of the code to improve performance. -- Added CTF/Oddball compatibility so I removed automatic assignment of passenger heavy weapons that was in version 4 -- Added driver activated passenger ejection seat: When driver types 'eject' passenger and/or gunner are both ejected from the hog. -- Added Aelite's 'Taxi-Teams' * - players in same hog are temporarily treated as a team, when one dies, they can call taxi and be put back into same hog - IF - there is still a teammate in it. -- Note: Taxi-Team assumes this is your preference rather than to be inserted into 'any' teammates hog - this is NOT editable, and comes after a year of testing player preferences in CTF/Race/Team King -- Added logging of taxi commands usage to Gamelog -- Commands: -- Crouch key or type 'Taxi' -- | Inserts you into a teammates hog or tank, if available. (if crouch-to-taxi/text-to-taxi is enabled) -- type 'Gun me' while in hog -- | Inserts a walking teammate into your driver, gunner or passenger seat (if gunme is enabled) -- type 'who is' while in hog -- | Shows you the driver/passenger/gunner names -- type 'hog' while walking -- | spawns a hog and puts you into the drivers seat (if hog_spawn is enabled for the map) -- type 'eject' while driving -- | Ejects any passenger or gunner from your vehicle -- type /taxi or @taxi -- | See the above list -- edit defaults-- taxi_limit = 20 -- | Number of times a player can call taxi during one game. You can go as high as you want, it won't affect gameplay or lag. hog_limit = 10 -- | Number of times a player can spawn a hog during one game. Should not be higher than 15 - ever! Spawning too many can cause lag and/or crash. crouch_to_taxi = true -- | Toggle on/off the crouching taxi call. On = true, Off = false. text_to_taxi = true -- | Toggle on/off the typed taxi call. On = true, Off = false. passenger_taxi = true -- | Toggle on/off the passenger seat. If off, the Taxi/Gun Me calls will not use passenger seats. On = true, Off = false. gunme_active = true -- | Toggle on/off the typed 'gun me' call which when typed by a player in a vehicle, inserts gunners/passengers. On = true, Off = false. gunner_damage = true -- | Toggle on/off damage from a vehicle gunner which has no driver (a.k.a. Hog Camper) If false, they cannot kill without a driver. This value should be opposite of rider_ejection value rider_ejection = false -- | Toggle on/off anti-camping which ejects a player from a driverless vehicle. On = true, Off = false. This value should be opposite of gunner_damage value max_time = 5 -- | amount of time in seconds before a hog turret camper or passenger is ejected (only valid if rider_ejection is true) -- don't edit -- taxi, calls, crouch, hails, hogs, map_ids, vehicles, taxi_teams = {}, {}, {}, {}, {}, {}, {}, {} crouch_time = 2 call_time = 0.1 -- | minimum of time in seconds before timer to rider ejection is initiated - value should be 0.1 -- | Toggle on/off script spawn hog on server chat - edit: -- | Small indoor maps should not use hog spawn, false to disable (spawning hogs in walls/below ground can cause crashes) hog_spawn = {} -- Map: Boolean: hog_spawn. beavercreek = false -- battle creek hog_spawn. bloodgulch = true hog_spawn. boardingaction = true hog_spawn. carousel = false -- derelict hog_spawn. chillout = false hog_spawn. damnation = false hog_spawn. dangercanyon = true hog_spawn. deathisland = true hog_spawn. gephyrophobia = true hog_spawn. hangemhigh = false hog_spawn. icefields = true hog_spawn. infinity = true hog_spawn. longest = false hog_spawn. prisoner = false hog_spawn. putput = false -- chiron tl34 hog_spawn. ratrace = false hog_spawn. sidewinder = true hog_spawn. timberland = true hog_spawn. wizard = false function GetRequiredVersion() return 200 end function OnScriptLoad(process, game, persistent) if game == true or game == "PC" then GAME = "PC" map_name = readstring(0x698F21) else GAME = "CE" map_name = readstring(0x61D151) end LoadTags() for i=0,15 do calls[i], hails[i], taxi[i], hogs[i] = 0, 0, {}, 0 if getplayer(i) then local player_obj_id = getplayerobjectid(i) if player_obj_id then local m_object = getobject(player_obj_id) if readbyte(m_object + 0x2A0) == 2 then taxi[i].seat = 1 taxi[i].vehicle = getobject(readdword(m_object + 0x11C)) end end end end Ejection = registertimer(call_time*1000, "ejection") end function OnNewGame(map) if GAME == "PC" then map_name = readstring(0x698F21) elseif GAME == "CE" then map_name = readstring(0x61D151) end LoadTags() end function ejection(id, c) if rider_ejection then for k, v in pairs(vehicles) do if vehicles[k] ~= {} then for key, value in pairs(vehicles[k]) do if vehicles[k].players and vehicles[k].players ~= {} then vehicles[k].count = (vehicles[k].count or 0) + call_time if vehicles[k].count >= max_time then for i=1, #vehicles[k].players do local player = vehicles[k].players[i] if player and getplayer(player) and isinvehicle(player) then sendconsoletext(player, "**Taxi** Ejected! Please don't camp.") log_msg(1, getname(player) .. " was force ejected from vehicle.") exitvehicle(player) if taxi[player].seat == 1 then resetpassenger(player, getobject(getplayerobjectid(player))) end end end vehicles[k] = {} end else vehicles[k] = {} end end end end return true else return false end end function OnServerChat(player, type, message) local response = nil if player then if string.lower(message) == "taxi" then if text_to_taxi then if not isinvehicle(player) then if taxi_limit == false or calls[player] < taxi_limit then if getplayerobjectid(player) then getTaxi(player) log_msg(1, getname(player) .. " used the taxi command.") else sendconsoletext(player, "**Taxi** You are dead. Try again after you respawn.") end else sendconsoletext(player, "**Taxi** You have reached the max amount of taxi calls for this game.") end else sendconsoletext(player, "**Taxi** You are already in a vehicle.") end else sendconsoletext(player, "**Taxi** This feature is currently disabled.") end response = false elseif string.lower(message) == "gunme" or string.lower(message) == "gun me" then if gunme_active then if isinvehicle(player) then getWalker(player) log_msg(1, getname(player) .. " used the gun me command.") else sendconsoletext(player, "**Gun Me** You must be in a vehicle to use this feature.") end else sendconsoletext(player, "**Gun Me** This feature is currently disabled.") end response = false elseif string.lower(message) == "hog" then local m_player = getplayer(player) if m_player then if hog_spawn[map_name] then if not isinvehicle(player) then local m_player = getplayerobjectid(player) if m_player ~= nil then local x,y,z = getobjectcoords(m_player) if not hog_limit or hogs[player] < hog_limit then local m_vehicleId = createobject(map_ids[map_name], 0, 15, false, x,y,z+0.4) entervehicle(player, m_vehicleId, 0) hogs[player] = hogs[player] + 1 sendconsoletext(player, "**Hogs** You have " .. hog_limit - hogs[player] .. " hog calls remaining.") log_msg(1, getname(player) .. " spawned a hog.") else sendconsoletext(player, "**Hogs** You have reached the max amount of hog calls for this game.") end else sendconsoletext(player, "**Hogs** Derp, you cannot spawn a hog while dead. ") end else sendconsoletext(player, "**Hogs** You already have a vehicle.") end else sendconsoletext(player, "**Hogs** That feature has been disabled for this map.") end end response = false elseif string.lower(message) == "whois" or string.lower(message) == "who is" then local m_vehicleId = getplayervehicleid(player) if isinvehicle(player) and m_vehicleId then local m_vehicle = getobject(m_vehicleId) local driver = getdriverplayer(m_vehicle) local gunner = getgunnerplayer(m_vehicle) local passenger = getpassengerplayer(m_vehicle) local driver = getdriverplayer(m_vehicle) local gunner = getgunnerplayer(m_vehicle) local passenger = getpassengerplayer(m_vehicle) message_players(driver, gunner, passenger) log_msg(1, getname(player) .. " used the whois command.") else sendconsoletext(player, "**WhoIs** You must be in a vehicle to use this feature.") end response = false elseif string.lower(message) == "reject" or string.lower(message) == "eject" then if isinvehicle(player) then local m_objectId = getplayervehicleid(player) local m_vehicle = getobject(m_objectId) if getdriverplayer(m_vehicle) == player then local drivername = getname(getdriverplayer(m_vehicle)) local driver_veh = getplayervehicleid(player) local gunner = getgunnerplayer(m_vehicle) local passenger = getpassengerplayer(m_vehicle) if gunner and isinvehicle(gunner) and driver_veh == getplayervehicleid(gunner) then exitvehicle(gunner) sendconsoletext(gunner, "**Ejected!** " .. drivername .. " activated the ejection seat!") taxi[gunner].seat = nil end if passenger and isinvehicle(passenger) and driver_veh == getplayervehicleid(passenger) then exitvehicle(passenger) sendconsoletext(passenger, "**Ejected!** " .. drivername .. " activated the ejection seat!") taxi[passenger].seat = nil end log_msg(1, getname(player) .. " activated ejection seat.") end end response = true elseif string.lower(message) == "/taxi" or string.lower(message) == "@taxi" then privatesay(player, "Crouch key or type 'Taxi' = Inserts you into a teammates hog or tank." ) privatesay(player, "type 'Gun me' while in hog = Inserts teammate into your driver, gunner or passenger seat." ) privatesay(player, "type 'who is' while in hog = Shows you the driver/passenger/gunner names." ) privatesay(player, "type 'hog' while walking = spawns a hog and puts you into the drivers seat." ) privatesay(player, "type 'eject' while driving = Ejects any passenger or gunner from your vehicle." ) log_msg(1, getname(player) .. " is reading taxi commands.") response = false end return response end return response end function OnPlayerJoin(player) calls[player], hails[player], taxi[player], hogs[player] = 0, 0, {}, 0 announce = registertimer(4000, "timedannounce", player) end function timedannounce(id, count, player) if count == 1 then if getplayer(player) then if text_to_taxi then sendconsoletext(player, "Taxi is Enabled. Type @taxi to learn more.") end if crouch_to_taxi and not text_to_taxi then sendconsoletext(player, "Crouch-to-Taxi is Enabled. Type @taxi to learn more.") end if gunme_active and not text_to_taxi then sendconsoletext(player, "Gun Me is Enabled. Type @taxi to learn more.") end end end return true end function OnGameEnd(stage) if stage == 1 then if Ejection then removetimer(Ejection) Ejection = nil end if announce then removetimer(announce) announce = nil end if passenger then removetimer(passenger) passenger = nil end if settonil then removetimer(settonil) settonil = nil end if setupseat then removetimer(setupseat) setupseat = nil end if showplayers then removetimer(showplayers) showplayers = nil end end end function OnPlayerLeave(player) if taxi[player].vehicle then if taxi[player].seat == 1 then writedword(taxi[player].vehicle + 0x32C, 0xFFFFFFFF) end end taxi[player] = nil end function OnPlayerKill(killer, victim, mode) local m_vehicleId = getplayervehicleid(victim) if taxi[victim].seat == 1 then resetpassenger(victim, getobject(getplayerobjectid(victim))) end if victim and isinvehicle(victim) then checkplayer(victim) end taxi[victim] = {} end function OnVehicleEntry(player, m_vehicleId, seat, mapId, relevant) taxi[player].seat = seat if seat == 1 then local player_obj_id = getplayerobjectid(player) local m_object = getobject(player_obj_id) taxi[player].vehicle = getobject(readdword(m_object + 0x11C)) passenger = registertimer(0, "assignpassenger", {player_obj_id, getobject(m_vehicleId)}) end if seat == 0 then vehicles[m_vehicleId] = {} settonil = registertimer(20, "setnil", m_vehicleId) elseif not getdriverplayer(getobject(m_vehicleId)) then setupseat = registertimer(0, "setupseattable", {m_vehicleId, player}) end local player_obj_id = getplayerobjectid(player) if player_obj_id then local m_object = getobject(player_obj_id) taxi[player].vehicle = getobject(readdword(m_object + 0x11C)) end showplayers = registertimer(0, "showPlayers", getobject(m_vehicleId)) return nil end function OnVehicleEject(player, relevant) local m_vehicleId = getplayervehicleid(player) if taxi[player].seat == 1 then resetpassenger(player, getobject(getplayerobjectid(player))) end checkplayer(player) taxi[player] = {} return nil end function showPlayers(id, count, m_vehicle) message_players(getdriverplayer(m_vehicle), getgunnerplayer(m_vehicle), getpassengerplayer(m_vehicle)) return false end function checkplayer(player) if taxi_teams[player] then return player end for k,v in pairs(taxi_teams) do if taxi_teams[k] ~= {} then for key,value in pairs(taxi_teams[k]) do if value == player then return k end end end end return false end function setupdrivertable(m_vehicleId, driver) vehicles[m_vehicleId] = {} vehicles[m_vehicleId].players = {} vehicles[m_vehicleId].count = 0 local team = getteam(driver) for player=0,15 do if getplayer(player) and getteam(player) == team and isinvehicle(player) and getplayervehicleid(player) == m_vehicleId and driver ~= player then table.insert(vehicles[m_vehicleId].players, player) end end end function setupseattable(id, count, arg) local m_vehicleId = arg[1] vehicles[m_vehicleId] = {} vehicles[m_vehicleId].players = {} vehicles[m_vehicleId].count = 0 local driver = getdriverplayer(getobject(m_vehicleId)) local team = getteam(arg[2]) for player=0,15 do if getplayer(player) and getteam(player) == team and isinvehicle(player) and getplayervehicleid(player) == m_vehicleId and driver ~= player then table.insert(vehicles[m_vehicleId].players, player) end end return false end function setnil(id, count, m_vehicleId) if count >= 20 then return false end if vehicles[m_vehicleId] ~= {} then vehicles[m_vehicleId] = {} end return true end function getplayervehicleid(player) local m_objectId = getplayerobjectid(player) if m_objectId then return readdword(getobject(m_objectId) + 0x11C) end end function getdriverobjid(m_vehicle) return readdword(m_vehicle + 0x324) end function getgunnerobjid(m_vehicle) return readdword(m_vehicle + 0x328) end function getpassengerobjid(m_vehicle) return readdword(m_vehicle + 0x32C) end function getdriverplayer(m_vehicle) local obj_id = readdword(m_vehicle + 0x324) if obj_id and obj_id ~= 0xFFFFFFFF then return objectidtoplayer(obj_id) end end function getgunnerplayer(m_vehicle) local obj_id = readdword(m_vehicle + 0x328) if obj_id ~= 0xFFFFFFFF then return objectidtoplayer(obj_id) end end function getpassengerplayer(m_vehicle) local obj_id = getpassengerobjid(m_vehicle) if obj_id ~= 0xFFFFFFFF then return objectidtoplayer(obj_id) end end function message_players(driver, gunner, passenger) local t,n = {}, {} if driver then table.insert(t, driver) table.insert(n, "Driver") end if gunner then table.insert(t, gunner) table.insert(n, "Gunner") end if passenger then table.insert(t, passenger) table.insert(n, "Passenger") end for k, v in pairs(t) do for key, value in pairs(t) do if v ~= value then sendconsoletext(v, n[key] .. " : " .. getname(value)) end end end end function OnClientUpdate(player) if hails[player] > 0 then hails[player] = hails[player] - 1 end if crouch_to_taxi then if not isinvehicle(player) then local m_objectId = getplayerobjectid(player) if m_objectId then local id = resolveplayer(player) if readbit(getobject(m_objectId) + 0x208, 0) and crouch[id] == nil then crouch[id] = OnPlayerCrouch(player) elseif readbyte(getobject(m_objectId) + 0x2A0) == 4 and crouch[id] ~= nil then crouch[id] = nil end end end end end function OnPlayerCrouch(player) if hails[player] == 0 then if taxi_limit == false or calls[player] < taxi_limit then getTaxi(player) hails[player] = (crouch_time*30) else sendconsoletext(player, "**Taxi** You have reached the max amount of taxi calls for this game.") end end return true end function assignpassenger(id, count, arg) taxi[objectidtoplayer(arg[1])].vehicle = arg[2] writedword(arg[2] + 0x32C, arg[1]) return false end function checkSpaces(player, team, m_vehicleId) local seats = getseats(m_vehicleId) if seats > 0 and m_vehicleId then for i=0,15 do if player ~= i and getplayer(i) and getteam(i) == team and isinvehicle(i) then if getplayervehicleid(i) == m_vehicleId then seats = seats - 1 end end end end return seats end function getseats(m_vehicleId) local name = gettaginfo(readdword(getobject(m_vehicleId))) local seats = 0 if string.find(name, "ghost") or string.find(name, "banshee") or string.find(name, "turret") then seats = 0 elseif string.find(name, "hog") then seats = 2 elseif string.find(name, "scorpion") then seats = 1 end return seats end function getTaxi(player) local check = checkplayer(player) local player2 if check then for k,v in pairs(taxi_teams[check]) do if isinvehicle(v) and checkSpaces(v, getteam(v), getplayervehicleid(v)) > 0 then player2 = v break end end else for i=0,15 do if player ~= i and getplayer(i) and getteam(i) == getteam(player) and isinvehicle(i) and not checkplayer(i) and checkSpaces(i, getteam(i), getplayervehicleid(i)) > 0 then player2 = i break end end end if player2 then InjectPlayer(player, getplayervehicleid(player2), true) else sendconsoletext(player, "**Taxi** Sorry no taxi is available at the moment. Please try again later.") end end function getWalker(player) local m_vehicleId = getplayervehicleid(player) if m_vehicleId then if checkSpaces(player, getteam(player), m_vehicleId) > 0 then local check = checkplayer(player) local player2 if check then for k,v in pairs(taxi_teams[check]) do if not isinvehicle(v) then player2 = v break end end else for i=0,15 do if player ~= i and getplayer(i) and getteam(i) == getteam(player) and not isinvehicle(i) and not checkplayer(i) and getplayerobjectid(i) then player2 = i break end end end if player2 then InjectPlayer(player2, m_vehicleId, false) else sendconsoletext(player, "**Gun Me** No teammates, or no available teammates.") end else sendconsoletext(player, "**Gun Me** No available seats in your vehicle.") end end end function InjectPlayer(player, m_vehicleId, count) local bool = false if m_vehicleId then local m_vehicle = getobject(m_vehicleId) local driver = readdword(m_vehicle + 0x324) local gunner = readdword(m_vehicle + 0x328) local passenger = readdword(m_vehicle + 0x32C) if driver == 0xFFFFFFFF then entervehicle(player, m_vehicleId, 0) bool = true elseif gunner == 0xFFFFFFFF then entervehicle(player, m_vehicleId, 2) bool = true elseif passenger_taxi and (passenger == 0xFFFFFFFF or passenger == 0) then entervehicle(player, m_vehicleId, 1) bool = true end if bool and taxi_limit and count then calls[player] = calls[player] + 1 sendconsoletext(player, "**Taxi** You have " .. taxi_limit - calls[player] .. " taxi calls left.") elseif not count then sendconsoletext(player, "**Gun Me** You have been put into the vehicle by a teammate.") end end end function resetpassenger(player, m_object) if player then if taxi[player].vehicle then writedword(taxi[player].vehicle + 0x32C, 0xFFFFFFFF) end end end function OnDamageLookup(receiving, causing, tagid) if causing then local c_player = objectidtoplayer(causing) if c_player and isinvehicle(c_player) then local m_vehicleId = getplayervehicleid(c_player) if m_vehicleId then local m_vehicle = getobject(m_vehicleId) local driver = readdword(m_vehicle + 0x324) local gunner = readdword(m_vehicle + 0x328) if not gunner_damage and (driver == 0xFFFFFFFF) and (gunner == causing) then return false end end end end end function LoadTags() map_ids["beavercreek"] = gettagid("vehi", "vehicles\\rwarthog\\rwarthog") map_ids["bloodgulch"] = gettagid("vehi", "vehicles\\rwarthog\\rwarthog") map_ids["boardingaction"] = gettagid("vehi", "vehicles\\rwarthog\\rwarthog") map_ids["carousel"] = gettagid("vehi", "vehicles\\rwarthog\\rwarthog") map_ids["chillout"] = gettagid("vehi", "vehicles\\rwarthog\\rwarthog") map_ids["damnation"] = gettagid("vehi", "vehicles\\rwarthog\\rwarthog") map_ids["dangercanyon"] = gettagid("vehi", "vehicles\\rwarthog\\rwarthog") map_ids["deathisland"] = gettagid("vehi", "vehicles\\rwarthog\\rwarthog") map_ids["gephyrophobia"] = gettagid("vehi", "vehicles\\rwarthog\\rwarthog") map_ids["hangemhigh"] = gettagid("vehi", "vehicles\\rwarthog\\rwarthog") map_ids["icefields"] = gettagid("vehi", "vehicles\\rwarthog\\rwarthog") map_ids["infinity"] = gettagid("vehi", "vehicles\\rwarthog\\rwarthog") map_ids["longest"] = gettagid("vehi", "vehicles\\rwarthog\\rwarthog") map_ids["prisoner"] = gettagid("vehi", "vehicles\\rwarthog\\rwarthog") map_ids["putput"] = gettagid("vehi", "vehicles\\rwarthog\\rwarthog") map_ids["ratrace"] = gettagid("vehi", "vehicles\\rwarthog\\rwarthog") map_ids["sidewinder"] = gettagid("vehi", "vehicles\\rwarthog\\rwarthog") map_ids["timberland"] = gettagid("vehi", "vehicles\\rwarthog\\rwarthog") map_ids["wizard"] = gettagid("vehi", "vehicles\\rwarthog\\rwarthog") -- if you prefer a chain hog for a specific map, replace above "vehicles\\rwarthog\\rwarthog" with "vehicles\\warthog\\mp_warthog" for that map. end -- Created by H® Shaft thank you to Oxide, AelitePrime, Nugget & Wizard. -- Visit http://halorace.org/forum/index.php?topic=514.0 or -- Visit http://pastebin.com/u/HR_Shaft for more phasor scripts