Advertisement
LordNoobIV

finite_fuel_client.lua

Jun 1st, 2014
168
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 12.96 KB | None | 0 0
  1. -- math.round function
  2. function math.round(number, decimals)
  3.     local multiply = 10 ^ (decimals or 0)
  4.     return math.floor(number * multiply + 0.5) / multiply
  5. end
  6.  
  7. fill = Image.Create(AssetLocation.Game, "hud_heat_meter_dif.dds")
  8. background = Image.Create(AssetLocation.Game, "hud_health_max_dif.dds")
  9. fill:SetSize(Vector2(16, 512))
  10.  
  11.  
  12.  
  13. transform = Transform2()
  14.  
  15. class "FiniteFuel"
  16.  
  17. function FiniteFuel:__init()
  18.     -- Configurable
  19.     self.gasStationMinimapIcon = true -- Square on the minimap showing closest fuel station
  20.     self.gasStationMinimapColor = Color(0, 255, 0) -- The color of the minimap square
  21.  
  22.     self.gasStationMarker = true -- 3D markers that show up at the gas station itself
  23.     self.gasStationMarkerVisibleRadius = 100 -- The radius in which the 3D marker will be visible
  24.     self.gasStationMarkerColor = Color(0, 255, 0, 100) -- The color of the 3D marker
  25.  
  26.     self.gasStationRefuelRadius = 10 -- The radius from the center of the gas station that you can refuel within
  27.     self.gasStationRefuelMaxVelocity = 0.4 -- The maximum velocity you can have while refueling
  28.  
  29.     self.externalRefuel = false -- Set this to true if you want to control refuel with an external script
  30.     self.refuelRate = 35 -- The amount of fuel to refuel every 500 milliseconds, if at a gas station, and externalRefuel = false
  31.  
  32.     self.enterVehicleFuelMessage = true -- Show message with current vehicle's fuel when entering one
  33.     self.enterVehicleMessageColor = Color(255, 0, 0)
  34.  
  35.     -- Variables
  36.     self.currentVehicle = nil
  37.  
  38.     self.tickTimer = Timer()
  39.     self.tickTimeout = 500
  40.  
  41.     -- Fuel meter
  42.     self.fuelMeterPosition = "BottomCenter" -- Options: BottomLeft, BottomRight, BottomCenter, TopRight, TopCenter
  43.     self.fuelMeterRelativeWidth = 0.2 -- value * screen width
  44.     self.fuelMeterRelativeHeight = 0.03 -- value * screen height
  45.     self.fuelMeterBackground = Color(0, 0, 0, 100)
  46.     self.fuelMeterForeground = Color(0, 255, 0)
  47.     self.fuelMeterRelativeTextSize = 0.02 -- value * screen height
  48.     self.fuelMeterTextColor = Color(255, 255, 255)
  49.  
  50.     self.fuelMeterWidth = 0
  51.     self.fuelMeterHeight = 0
  52.     self.fuelMeterLeft = 0
  53.     self.fuelMeterTop = 0
  54.     self.fuelMeterTextLeft = 0
  55.     self.fuelMeterTextTop = 0
  56.     self.fuelMeterIndicatorWidth = 0
  57.     self.fuelMeterTextSize = 0
  58.     self.fuelMeterText = "Fuel"
  59.  
  60.     self.gasStationClosest = {gasStation = nil, distance = nil}
  61.     self.sentAtGasStation = nil
  62.  
  63.     self:CalculateMeterPosition({size = Vector2(Render.Width, Render.Height)})
  64.  
  65.     -- Events
  66.     Events:Subscribe("LocalPlayerEnterVehicle", self, self.LocalPlayerEnterVehicle)
  67.     Events:Subscribe("LocalPlayerExitVehicle", self, self.LocalPlayerExitVehicle)
  68.     Events:Subscribe("LocalPlayerInput", self, self.LocalPlayerInput)
  69.     Events:Subscribe("InputPoll", self, self.InputPoll)
  70.     Events:Subscribe("PostTick", self, self.PostTick)
  71.     Events:Subscribe("ResolutionChange", self, self.CalculateMeterPosition)
  72.     Events:Subscribe("Render", self, self.Render)
  73.  
  74.     -- Custom events
  75.     Events:Subscribe("FiniteFuelGetFuel", self, self.LocalGetFuel)
  76.     Events:Subscribe("FiniteFuelSetFuel", self, self.LocalSetFuel)
  77.  
  78.     -- Networked events
  79.     Network:Subscribe("FiniteFuelGetFuel", self, self.GetFuel)
  80.  
  81.     -- Get current vehicle's fuel if player in one
  82.     if LocalPlayer:InVehicle() and IsValid(LocalPlayer:GetVehicle()) then
  83.         Network:Send("FiniteFuelGetFuel", LocalPlayer:GetVehicle())
  84.     end
  85. end
  86.  
  87. -- ======================== Position calculations ========================
  88. function FiniteFuel:CalculateMeterPosition(args)
  89.     local size = args.size
  90.  
  91.  
  92.  
  93.     -- Calculate width and height
  94.     self.fuelMeterWidth = size.x * self.fuelMeterRelativeWidth
  95.     self.fuelMeterHeight = size.y * self.fuelMeterRelativeHeight
  96.  
  97.     -- Calculate left and top positions
  98.     self.fuelMeterLeft = 0
  99.     self.fuelMeterTop = 0
  100.  
  101.     if self.fuelMeterPosition == "BottomLeft" then
  102.         self.fuelMeterLeft = 0
  103.         self.fuelMeterTop = size.y - self.fuelMeterHeight
  104.     elseif self.fuelMeterPosition == "BottomRight" then
  105.         self.fuelMeterLeft = size.x - self.fuelMeterWidth
  106.         self.fuelMeterTop = size.y - self.fuelMeterHeight
  107.     elseif self.fuelMeterPosition == "BottomCenter" then
  108.         self.fuelMeterLeft = (size.x / 2) - (self.fuelMeterWidth / 2)
  109.         self.fuelMeterTop = size.y - self.fuelMeterHeight
  110.     elseif self.fuelMeterPosition == "TopRight" then
  111.         self.fuelMeterLeft = size.x - self.fuelMeterWidth
  112.         self.fuelMeterTop = 0
  113.     elseif self.fuelMeterPosition == "TopCenter" then
  114.         self.fuelMeterLeft = (size.x / 2) - (self.fuelMeterWidth / 2)
  115.         self.fuelMeterTop = 0
  116.     end
  117.  
  118.     self.fuelMeterTextSize = size.y * self.fuelMeterRelativeTextSize
  119.  
  120.     self:CalculateTextPosition()
  121. end
  122.  
  123. function FiniteFuel:CalculateTextPosition()
  124.     local textSize = Render:GetTextSize(self.fuelMeterText, self.fuelMeterTextSize)
  125.  
  126.     self.fuelMeterTextLeft = self.fuelMeterLeft + (self.fuelMeterWidth / 2) - (textSize.x / 2)
  127.     self.fuelMeterTextTop = self.fuelMeterTop + (self.fuelMeterHeight / 2) - (textSize.y / 2)
  128. end
  129.  
  130. -- ======================== Rendering ========================
  131. function FiniteFuel:Render(args)
  132.     fill:SetPosition(Vector2(0, 120))
  133.     background:SetPosition(Vector2(0, 120))
  134.     if self.currentVehicle == nil or not IsValid(self.currentVehicle.vehicle) or not LocalPlayer:InVehicle() or Game:GetState() ~= GUIState.Game then return end
  135.     v = LocalPlayer:GetVehicle()
  136.     background:SetSize(Vector2(16, 512))
  137.     fill:SetSize(Vector2(16, math.floor(self.currentVehicle.fuel / (v:GetMass() / 1024))))
  138.     print(self.currentVehicle.fuel)
  139.     transform = Transform2()
  140.     transform:Translate(Vector2(Render.Size.x + 120, Render.Size.y - 128))
  141.     transform:Rotate(math.rad(90))
  142.     Render:SetTransform(transform)
  143.     -- Draw background
  144.     background:Draw()
  145.     -- Draw indicator
  146.     fill:Draw()
  147.  
  148.     Render:ResetTransform()
  149.  
  150.  
  151.     -- Draw closest gas station on minimap
  152.     if self.gasStationMinimapIcon and self.gasStationClosest.gasStation ~= nil then Render:FillArea(Render:WorldToMinimap(self.gasStationClosest.gasStation.position), Vector2(10, 10), self.gasStationMinimapColor) end
  153.  
  154.     -- Draw gas station marker
  155.     if self.gasStationMarker and self.gasStationClosest.gasStation ~= nil and self.gasStationClosest.distance <= self.gasStationMarkerVisibleRadius then
  156.         local position = self.gasStationClosest.gasStation.position
  157.         local distance = self.gasStationClosest.distance
  158.         local pos1 = position
  159.         local pos2 = position + (Vector3(-1, 2, 0) * (distance / 20))
  160.         local pos3 = position + (Vector3(1, 2, 0) * (distance / 20))
  161.         Render:FillTriangle(pos1, pos2, pos3, self.gasStationMarkerColor)
  162.         pos1 = position
  163.         pos2 = position + (Vector3(0, 2, -1) * (distance / 20))
  164.         pos3 = position + (Vector3(0, 2, 1) * (distance / 20))
  165.         Render:FillTriangle(pos1, pos2, pos3, self.gasStationMarkerColor)
  166.     end
  167. end
  168.  
  169. -- ======================== Enter/exit vehicle ========================
  170. function FiniteFuel:LocalPlayerEnterVehicle(args)
  171.     if not IsValid(args.vehicle) then return end
  172.  
  173.     self.gasStationClosest = {gasStation = nil, distance = nil}
  174.  
  175.     Network:Send("FiniteFuelGetFuel", args.vehicle)
  176. end
  177.  
  178. function FiniteFuel:LocalPlayerExitVehicle(args)
  179.     if self.currentVehicle == nil or self.currentVehicle.vehicle ~= args.vehicle then return end
  180.  
  181.     Network:Send("FiniteFuelSetFuel", {vehicle = args.vehicle, fuel = self.currentVehicle.fuel})
  182.  
  183.     -- Notify external scripts of fuel station exit
  184.     if self.externalRefuel and self.sentAtGasStation ~= nil then
  185.         Events:Fire("FiniteFuelExitedGasStation", {vehicle = self.currentVehicle.vehicle, gasStation = self.sentAtGasStation})
  186.         self.sentAtGasStation = nil
  187.     end
  188.  
  189.     self.currentVehicle = nil
  190. end
  191.  
  192. -- ======================== Tick update events ========================
  193. function FiniteFuel:InputPoll()
  194.     if self.currentVehicle == nil or
  195.     not IsValid(self.currentVehicle.vehicle) or
  196.     self.currentVehicle.fuel > 0 or
  197.     (self.currentVehicle.vehicleGasType ~= FiniteFuelGasTypes.Aircraft and self.currentVehicle.vehicleGasType ~= FiniteFuelGasTypes.Aircraft) then return end
  198.  
  199.     Input:SetValue(Action.HeliDecAltitude, 1)
  200.     Input:SetValue(Action.PlaneDecTrust, 1)
  201. end
  202.  
  203. function FiniteFuel:PostTick()
  204.     if self.tickTimer:GetMilliseconds() < self.tickTimeout or self.currentVehicle == nil or not IsValid(self.currentVehicle.vehicle) then return end
  205.     self.tickTimer:Restart()
  206.  
  207.     local playerPosition = LocalPlayer:GetPosition()
  208.     if self.gasStationClosest.gasStation ~= nil then self.gasStationClosest.distance = Vector3.Distance(self.gasStationClosest.gasStation.position, playerPosition) end
  209.     for index, gasStation in ipairs(FiniteFuelGasStations) do
  210.         -- Only evaluate if of same gas type
  211.         if gasStation.gasType == self.currentVehicle.vehicleGasType then
  212.             local gasStationPosition = gasStation.position
  213.             local distance = Vector3.Distance(gasStationPosition, playerPosition)
  214.  
  215.             -- Closer than last gas station checked
  216.             if self.gasStationClosest.distance == nil or distance < self.gasStationClosest.distance then
  217.                 self.gasStationClosest = {gasStation = gasStation, distance = distance}
  218.             end
  219.         end
  220.     end
  221.  
  222.     -- Close and moving slow enough to refuel, and tank is not full
  223.     local velocity = self.currentVehicle.vehicle:GetLinearVelocity():Length()
  224.     local idling = velocity <= self.gasStationRefuelMaxVelocity
  225.  
  226.     if self.gasStationClosest.distance ~= nil and self.gasStationClosest.distance <= self.gasStationRefuelRadius and idling and self.currentVehicle.fuel < self.currentVehicle.tankSize then
  227.         if not self.externalRefuel then
  228.             -- Fuel up. Set to tank size if full
  229.             self.currentVehicle.fuel = self.currentVehicle.fuel + self.refuelRate
  230.             if self.currentVehicle.fuel > self.currentVehicle.tankSize then self.currentVehicle.fuel = self.currentVehicle.tankSize end
  231.  
  232.             -- Change text
  233.             if self.fuelMeterText ~= "Refuelling..." then
  234.                 self.fuelMeterText = "Refuelling..."
  235.                 self:CalculateTextPosition()
  236.             end
  237.         else
  238.             -- Send network event for external refuelling scripts
  239.             if self.sentAtGasStation ~= self.gasStationClosest.gasStation then
  240.                 self.sentAtGasStation = self.gasStationClosest.gasStation
  241.                 Events:Fire("FiniteFuelEnteredGasStation", {vehicle = self.currentVehicle.vehicle, vehicleGasType = self.currentVehicle.vehicleGasType, gasStation = self.gasStationClosest.gasStation})
  242.             end
  243.         end
  244.     elseif idling and self.currentVehicle.fuel > 0 then -- Idling
  245.         -- Drain idle. Set tank to 0 if less than empty
  246.         self.currentVehicle.fuel = self.currentVehicle.fuel - self.currentVehicle.idleDrainRate
  247.  
  248.         -- Change text
  249.         if self.fuelMeterText ~= "Idle" then
  250.             self.fuelMeterText = "Idle"
  251.             self:CalculateTextPosition()
  252.         end
  253.         if self.currentVehicle.fuel < 0 then self.currentVehicle.fuel = 0 end
  254.     elseif not idling and self.currentVehicle.fuel > 0 then -- Moving
  255.         -- Drain moving. Set tank to 0 if less than empty
  256.         local drain = (velocity * self.currentVehicle.drainRate)-- * 100 -- DEBUGGING
  257.         self.currentVehicle.fuel = self.currentVehicle.fuel - drain
  258.         if self.currentVehicle.fuel < 0 then self.currentVehicle.fuel = 0 end
  259.  
  260.         -- Change text
  261.         if self.fuelMeterText ~= "Fuel" then
  262.             self.fuelMeterText = "Fuel"
  263.             self:CalculateTextPosition()
  264.         end
  265.     end
  266.  
  267.     -- Send left gas station to external scripts
  268.     if self.externalRefuel and self.sentAtGasStation ~= nil and self.gasStationClosest.distance > self.gasStationRefuelRadius then
  269.         Events:Fire("FiniteFuelExitedGasStation", {vehicle = self.currentVehicle.vehicle, gasStation = self.sentAtGasStation})
  270.         self.sentAtGasStation = nil
  271.     end
  272.  
  273.     -- Calculate indicator width
  274.     self.fuelMeterIndicatorWidth = self.fuelMeterWidth / self.currentVehicle.tankSize * self.currentVehicle.fuel
  275.     fill:SetSize(Vector2(16, self.fuelMeterWidth))
  276. end
  277.  
  278. -- ======================== Movement blocker ========================
  279. function FiniteFuel:LocalPlayerInput(args)
  280.     if self.currentVehicle == nil or not IsValid(self.currentVehicle.vehicle) or self.currentVehicle.fuel > 0 then return end
  281.  
  282.     -- Fuel empty, block movement keys
  283.     return not FiniteFuelVehicleKeys[args.input]
  284. end
  285.  
  286. -- ======================== Vehicle info ========================
  287. function FiniteFuel:GetFuel(args)
  288.     local vehicle = args.vehicle
  289.     local fuel = args.fuel
  290.  
  291.     self.currentVehicle = FiniteFuelVehicle(vehicle, fuel)
  292.     if self.enterVehicleFuelMessage then
  293.         Chat:Print("Vehicle currently has " .. math.round(self.currentVehicle.fuel) .. "/" .. math.round(self.currentVehicle.tankSize) .. " fuel.", self.enterVehicleMessageColor)
  294.     end
  295. end
  296.  
  297. -- ======================== Local events ========================
  298. function FiniteFuel:LocalGetFuel()
  299.     if self.currentVehicle == nil or not IsValid(self.currentVehicle.vehicle) then return end
  300.  
  301.     Events:Fire("FiniteFuelReturnGetFuel", {vehicle = self.currentVehicle.vehicle, vehicleGasType = self.currentVehicle.vehicleGasType, fuel = self.currentVehicle.fuel, tankSize = self.currentVehicle.tankSize})
  302. end
  303.  
  304. function FiniteFuel:LocalSetFuel(fuel)
  305.     if fuel < 0 or self.currentVehicle == nil or not IsValid(self.currentVehicle.vehicle) then return end
  306.  
  307.     if fuel > self.currentVehicle.tankSize then fuel = self.currentVehicle.tankSize end
  308.  
  309.     self.currentVehicle.fuel = fuel
  310. end
  311.  
  312. -- ======================== Initialize ========================
  313. Events:Subscribe("ModuleLoad", function()
  314.     FiniteFuel()
  315. end)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement