I don't suppose there are any plans to expand this with mods for the Drone? I would love a system for adding on things like reduced battery cost for covert quickhacks, the ability to explode (possibly increasing damage equal to remaining battery power), Interacting with things like radios and computers. Perhaps to balance it, You could only have one or two mods at a time on it and they massively reduce battery capacity or range, or it takes much longer to recharge.
What lua file to change for infinite battery? EDIT 1: nevermind, I figured it out. It's the .json file that needs changing. In your Cyberpunk 2077\bin\x64\plugins\cyber_engine_tweaks\mods\nanoDrone\config\config.json. Look for "batteryMult": some number}. Change that number to whatever you want. Changed it to 50 for example and works. It's not infinite but lasts a very long time.
i dont know about this r6/inut/NanoDrone.xml <action name="Jump" map="Jump_Button" /> <!-- Added for NanoDrone mod --> <action name="Down" map="Crouch_Button" /> but this working (just copy all) bin\x64\plugins\cyber_engine_tweaks\mods\nanoDrone\modules\input.lua local utils = require("modules/utils") local Cron = require("modules/Cron") local data = require("modules/data") local collision = require("modules/collision") local target = require("modules/TargetingHelper") local lang = require("modules/lang") drone = {} function drone:new(nd) local o = {} o.nd = nd o.spawned = false o.entID = nil o.forceTakeOver = false o.fullySpawned = false o.path = "base\\nano_drone\\drone.ent" o.handle = nil o.tier = nil o.pos = nil o.vel = nil o.accel = 0 o.topSpeed = 0 o.range = 0 o.batteryPercent = nil o.rechargeID = nil o.rthID = nil o.pinID = nil o.ui = require("modules/ui") o.playerPos = nil o.playerRot = nil self.__index = self return setmetatable(o, self) end function drone:init() self.batteryPercent = data.getBatteryPercent() self.pos = Vector4.new(0, 0, 0, 0) self.vel = Vector4.new(0, 0, 0, 0) end function drone:spawn() if data.getTier() == 0 or Game.GetWorkspotSystem():IsActorInWorkspot(GetPlayer()) then return end if not self.spawned then if self.batteryPercent > 20 then self.spawned = true self.playerPos = GetPlayer():GetWorldPosition() self.playerRot = GetPlayer():GetWorldOrientation():ToEulerAngles() self.nd.input.noSave = true self:startDecharge() self.accel = data.getAccel() self.topSpeed = data.getTopSpeed() self.range = data.getRange() self.tier = data.getTier() local pos = collision.getSpawnPos() pos.z = pos.z + 1.5 self.pos = pos self.entID = utils.spawnObject(self.path, pos, GetPlayer():GetWorldForward():ToRotation():ToQuat()) self.forceTakeOver = true self.pinID = utils.placePin(utils.addVector(GetPlayer():GetWorldPosition(), Vector4.new(0, 0, 1.5, 0)), gamedataMappinVariant.ApartmentVariant) self.spawnCron = Cron.After(1, function () self.fullySpawned = true -- Need this to filter out this cameras OnTakeControllOverDevice call end) else GetPlayer():SetWarningMessage(tostring(lang.getText(lang.battery_too_low) .. "(" .. self.batteryPercent .. "%/" .. "100%)")) end end end function drone:startDecharge() Cron.Every(data.getBatteryDrain(), function(timer) self.batteryPercent = self.batteryPercent - 1 -- * speed maybe? if self.batteryPercent <= 0 then self:despawn() self.batteryPercent = 0 Cron.After(0.1, function () GetPlayer():SetWarningMessage(lang.getText(lang.battery_empty)) end) timer:Halt() end if not self.spawned then timer:Halt() end data.setBatteryPercent(self.batteryPercent) end) end function drone:startRecharge() self.rechargeID = Cron.Every(data.getBatterySpeed(), function(timer) if self.spawned then timer:Halt() self.rechargeID = nil end self.batteryPercent = self.batteryPercent + 1 if self.batteryPercent >= 100 then timer:Halt() self.rechargeID = nil self.batteryPercent = 100 GetPlayer():SetWarningMessage(lang.getText(lang.battery_full)) end data.setBatteryPercent(self.batteryPercent) end) end function drone:despawn(release) StatusEffectHelper.RemoveStatusEffect(GetPlayer(), "GameplayRestriction.NoJump") if not self.spawned then return end local ctrl = true if release ~= nil then ctrl = release end if ctrl then TakeOverControlSystem.ReleaseControl() end self.spawned = false self.fullySpawned = false self.ui.ramCostTooHigh = false self.nd.input.noSave = false utils.removePin(self.pinID) if self.spawnCron then Cron.Halt(self.spawnCron) self.spawnCron = nil end if self.rthID then Cron.Halt(self.rthID) self.rthID = nil end Cron.NextTick(function () self.handle:GetEntity():Destroy() end) Cron.After(1.5, function () utils.showInputHint("QuickMelee", lang.getText(lang.input_hint), 1, true) end) end function drone:handleInput(deltaTime) local acc = deltaTime * self.accel local f = 1.8 -- Deaccaleration factor if self.nd.input.forward then self.vel.y = math.min(self.vel.y + acc * self.nd.input.analogForward, math.max(self.vel.y, self.topSpeed * self.nd.input.analogForward)) elseif self.vel.y > 0 then self.vel.y = self.vel.y - acc * f self.vel.y = math.max(0, self.vel.y) end if self.nd.input.backwards then self.vel.y = math.max(self.vel.y - acc * self.nd.input.analogBackwards, math.min(self.vel.y, -self.topSpeed * self.nd.input.analogBackwards)) elseif self.vel.y < 0 then self.vel.y = self.vel.y + acc * f self.vel.y = math.min(0, self.vel.y) end if self.nd.input.right then self.vel.x = math.min(self.vel.x + acc * self.nd.input.analogRight, math.max(self.vel.x, self.topSpeed * self.nd.input.analogRight)) elseif self.vel.x > 0 then self.vel.x = self.vel.x - acc * f self.vel.x = math.max(0, self.vel.x) end if self.nd.input.left then self.vel.x = math.max(self.vel.x - acc * self.nd.input.analogLeft, math.min(self.vel.x, -self.topSpeed * self.nd.input.analogLeft)) elseif self.vel.x < 0 then self.vel.x = self.vel.x + acc * f self.vel.x = math.min(0, self.vel.x) end if self.nd.input.up then self.vel.z = math.min(self.vel.z + acc * self.nd.input.analogUp, self.topSpeed) elseif self.vel.z > 0 then self.vel.z = self.vel.z - acc * f self.vel.z = math.max(0, self.vel.z) end if self.nd.input.down then self.vel.z = math.max(self.vel.z - acc * self.nd.input.analogDown, -self.topSpeed) elseif self.vel.z < 0 then self.vel.z = self.vel.z + acc * f self.vel.z = math.min(0, self.vel.z) end end function drone:move(deltaTime) local dir = Game.GetCameraSystem():GetActiveCameraForward() local dist = 100 local globalVel = Vector4.new(0, 0, 0, 0) globalVel.x = globalVel.x + (dir.x * self.vel.y) * (deltaTime * 25) globalVel.y = globalVel.y + (dir.y * self.vel.y) * (deltaTime * 25) local dir = Game.GetCameraSystem():GetActiveCameraRight() globalVel.x = globalVel.x + (dir.x * self.vel.x) * (deltaTime * 25) globalVel.y = globalVel.y + (dir.y * self.vel.x) * (deltaTime * 25) globalVel.z = self.vel.z * 0.3 local globalVelN = globalVel:Normalize() local hit, normal = target.GetLookAtPosition(utils.addVector(self.pos, utils.multVector(globalVelN, 0.7)), utils.addVector(self.pos, utils.multVector(globalVelN, 10))) if hit then dist = Vector4.Distance(hit, self.pos) end if (dist < 0.8) then globalVel = utils.multVector(globalVel, 0.9) normal = utils.multVector(Vector4.Vector3To4(normal), globalVel:Length()) self.pos.x = self.pos.x + math.min((globalVel.x + normal.x), normal.y) self.pos.y = self.pos.y + math.max((globalVel.y + normal.y), normal.x) self.pos.z = self.pos.z + (globalVel.z + normal.z) else self.pos.x = self.pos.x + globalVel.x self.pos.y = self.pos.y + globalVel.y self.pos.z = self.pos.z + globalVel.z end Game.GetTeleportationFacility():Teleport(self.handle, self.pos, self.handle:GetWorldOrientation():ToEulerAngles()) end function drone:handleHUD() if self.ui.hud then local dist = math.floor(Vector4.Distance(GetPlayer():GetWorldPosition(), self.pos)) local rangeStr = lang.getText(lang.range) .. ": " .. dist .. "/" .. math.floor(self.range) local batteryStr = lang.getText(lang.drone_status) .. ": \n " .. lang.getText(lang.battery) .. ": " .. math.floor(self.batteryPercent) .. "%" if self.ui.quickhacking then local qhBattery = ui.qhCost * data.getQuickhackMult() * 10 if self.batteryPercent - qhBattery <= 0 then self.ui.ram_conflictText:SetVisible(true) self.ui.ramCostTooHigh = true else self.ui.ram_conflictText:SetVisible(false) self.ui.ramCostTooHigh = false end batteryStr = batteryStr .. " - " .. math.floor(qhBattery) .. "%" else self.ui.ram_conflictText:SetVisible(false) self.ui.ramCostTooHigh = false end inkTextRef.SetText(self.ui.hud.Date, tostring(batteryStr .. " \n " .. rangeStr)) end end function drone:handleRange() local time = 5 if math.floor(Vector4.Distance(GetPlayer():GetWorldPosition(), self.pos)) > data.getRange() and not self.rthID then self.ui.max_range_text:SetVisible(true) self.ui.max_range_text:SetText(tostring(lang.getText(lang.range_warning) .. time .. "s")) self.rthID = Cron.Every(1.0, {tick = time}, function(timer) if timer.tick > 0 then timer.tick = timer.tick - 1 self.ui.max_range_text:SetText(tostring(lang.getText(lang.range_warning) .. timer.tick .. "s")) else timer:Halt() self.ui.max_range_text:SetVisible(false) self:despawn() self.rthID = nil end end) elseif math.floor(Vector4.Distance(GetPlayer():GetWorldPosition(), self.pos)) < data.getRange() and self.rthID then self.ui.max_range_text:SetVisible(false) Cron.Halt(self.rthID) self.rthID = nil end end function drone:handleDoors() local target = Game.GetTargetingSystem():GetLookAtObject(GetPlayer(), false, true) if not (self.tier >= 3) then return end utils.createInteractionHub(lang.getText(lang.open_door), "Choice1", false) if not target then return end if Vector4.Distance(target:GetWorldPosition(), self.pos) > 2.9 then return end if target:GetClassName().value == "Door" then -- Handle UI if target:HasAnySkillCheckActive() then utils.createInteractionHub(lang.getText(lang.door_requires_skillcheck), "Choice1", true) else local ps = target:GetDevicePS() local state = ps:IsOpen() local costText = "" local cost = 0 if ps:IsLocked() or ps:IsSealed() then cost = data.getQuickhackMult() * 10 * 3 else cost = data.getQuickhackMult() * 8 end cost = math.floor(cost) costText = string.format(" (%i%% " .. lang.getText(lang.battery_cost) .. ")", cost) if self.batteryPercent - cost <= 0 and costText ~= "" then self.ui.ram_conflictText:SetVisible(true) else self.ui.ram_conflictText:SetVisible(false) end if not state then utils.createInteractionHub(tostring(lang.getText(lang.open_door)) .. costText, "Choice1", true) else utils.createInteractionHub(tostring(lang.getText(lang.close_door)) .. costText, "Choice1", true) end -- Handle input if self.nd.input.interact and (self.batteryPercent - cost > 0) then self.nd.input.interact = false if ps:IsLocked() then ps:ToggleLockOnDoor() end if ps:IsSealed() then ps:ToggleSealOnDoor() end self.batteryPercent = self.batteryPercent - cost if not state then target:OpenDoor() else target:CloseDoor() end end end else -- Remove input UI utils.createInteractionHub(lang.getText(lang.open_door), "Choice1", false) utils.createInteractionHub(lang.getText(lang.close_door), "Choice1", false) utils.createInteractionHub(lang.getText(lang.door_requires_skillcheck), "Choice1", false) end end function drone:update(deltaTime) if self.spawned then if self.forceTakeOver then if Game.FindEntityByID(self.entID) then self.forceTakeOver = false self.handle = Game.FindEntityByID(self.entID) self.handle:OnToggleTakeOverControl(ToggleTakeOverControl.new()) self.handle.maxPitch = 3 Game.GetStatusEffectSystem():ApplyStatusEffect(GetPlayer():GetEntityID(), "GameplayRestriction.NoJump", GetPlayer():GetRecordID(), GetPlayer():GetEntityID()) end end if self.fullySpawned then self:handleInput(deltaTime) self:move(deltaTime) self:handleRange() self:handleHUD() self:handleDoors() Game.GetTimeSystem():UnsetTimeDilation("focusMode") if not Game.FindEntityByID(self.entID) then self:despawn(true) end end Game.GetTeleportationFacility():Teleport(GetPlayer(), self.playerPos, self.playerRot) elseif not self.rechargeID and self.batteryPercent ~= 100 then self:startRecharge() end end return drone
It crashes when I open the game, I play with other mods, could you tell me which mods it is not compatible with or is it the version of this mod that is not currently updated to that of cyberpunk 2077?
Does nano droid can't move down Z axis? It seems there is even no key map for this in config. I mean, drone can move in all directions except going down. I mean, like dive in water by crouch key. Wtf?
Upd. For some reason "ToggleSprint" is just not working for me to move drone down. I made some changes to bind it to "Crouch_Button". And it works.
r6/inut/NanoDrone.xml <action name="Jump" map="Jump_Button" /> <!-- Added for NanoDrone mod --> <action name="Down" map="Crouch_Button" /> bin\x64\plugins\cyber_engine_tweaks\mods\nanoDrone\modules\input.lua elseif actionName == 'ToggleSprint' then if actionType == 'BUTTON_PRESSED' then input.down = true input.analogDown = 1 elseif actionType == 'BUTTON_RELEASED' then input.down = false input.analogDown = 0 end elseif actionName == 'Down' then if actionType == 'BUTTON_PRESSED' then input.down = true input.analogDown = 1 elseif actionType == 'BUTTON_RELEASED' then input.down = false input.analogDown = 0 end
And another annoying thing... A drone can look In all directions but can't look upper the "horizon". How can I fix it?
You're the goat lol, I decided to check here before messing around in the lua so that's for a quick fix. Also noticed the lack of up on the y-axis camera, if I get something working I'll respond here but just being able to go down may be enough of a fix.
323 comments
EDIT 1: nevermind, I figured it out. It's the .json file that needs changing.
In your Cyberpunk 2077\bin\x64\plugins\cyber_engine_tweaks\mods\nanoDrone\config\config.json. Look for "batteryMult": some number}.
Change that number to whatever you want. Changed it to 50 for example and works. It's not infinite but lasts a very long time.
r6/inut/NanoDrone.xml
<action name="Jump" map="Jump_Button" /> <!-- Added for NanoDrone mod -->
<action name="Down" map="Crouch_Button" />
but this working (just copy all)
bin\x64\plugins\cyber_engine_tweaks\mods\nanoDrone\modules\input.lua
local utils = require("modules/utils")
local Cron = require("modules/Cron")
local data = require("modules/data")
local collision = require("modules/collision")
local target = require("modules/TargetingHelper")
local lang = require("modules/lang")
drone = {}
function drone:new(nd)
local o = {}
o.nd = nd
o.spawned = false
o.entID = nil
o.forceTakeOver = false
o.fullySpawned = false
o.path = "base\\nano_drone\\drone.ent"
o.handle = nil
o.tier = nil
o.pos = nil
o.vel = nil
o.accel = 0
o.topSpeed = 0
o.range = 0
o.batteryPercent = nil
o.rechargeID = nil
o.rthID = nil
o.pinID = nil
o.ui = require("modules/ui")
o.playerPos = nil
o.playerRot = nil
self.__index = self
return setmetatable(o, self)
end
function drone:init()
self.batteryPercent = data.getBatteryPercent()
self.pos = Vector4.new(0, 0, 0, 0)
self.vel = Vector4.new(0, 0, 0, 0)
end
function drone:spawn()
if data.getTier() == 0 or Game.GetWorkspotSystem():IsActorInWorkspot(GetPlayer()) then
return
end
if not self.spawned then
if self.batteryPercent > 20 then
self.spawned = true
self.playerPos = GetPlayer():GetWorldPosition()
self.playerRot = GetPlayer():GetWorldOrientation():ToEulerAngles()
self.nd.input.noSave = true
self:startDecharge()
self.accel = data.getAccel()
self.topSpeed = data.getTopSpeed()
self.range = data.getRange()
self.tier = data.getTier()
local pos = collision.getSpawnPos()
pos.z = pos.z + 1.5
self.pos = pos
self.entID = utils.spawnObject(self.path, pos, GetPlayer():GetWorldForward():ToRotation():ToQuat())
self.forceTakeOver = true
self.pinID = utils.placePin(utils.addVector(GetPlayer():GetWorldPosition(), Vector4.new(0, 0, 1.5, 0)), gamedataMappinVariant.ApartmentVariant)
self.spawnCron = Cron.After(1, function ()
self.fullySpawned = true -- Need this to filter out this cameras OnTakeControllOverDevice call
end)
else
GetPlayer():SetWarningMessage(tostring(lang.getText(lang.battery_too_low) .. "(" .. self.batteryPercent .. "%/" .. "100%)"))
end
end
end
function drone:startDecharge()
Cron.Every(data.getBatteryDrain(), function(timer)
self.batteryPercent = self.batteryPercent - 1 -- * speed maybe?
if self.batteryPercent <= 0 then
self:despawn()
self.batteryPercent = 0
Cron.After(0.1, function ()
GetPlayer():SetWarningMessage(lang.getText(lang.battery_empty))
end)
timer:Halt()
end
if not self.spawned then timer:Halt() end
data.setBatteryPercent(self.batteryPercent)
end)
end
function drone:startRecharge()
self.rechargeID = Cron.Every(data.getBatterySpeed(), function(timer)
if self.spawned then
timer:Halt()
self.rechargeID = nil
end
self.batteryPercent = self.batteryPercent + 1
if self.batteryPercent >= 100 then
timer:Halt()
self.rechargeID = nil
self.batteryPercent = 100
GetPlayer():SetWarningMessage(lang.getText(lang.battery_full))
end
data.setBatteryPercent(self.batteryPercent)
end)
end
function drone:despawn(release)
StatusEffectHelper.RemoveStatusEffect(GetPlayer(), "GameplayRestriction.NoJump")
if not self.spawned then return end
local ctrl = true
if release ~= nil then
ctrl = release
end
if ctrl then TakeOverControlSystem.ReleaseControl() end
self.spawned = false
self.fullySpawned = false
self.ui.ramCostTooHigh = false
self.nd.input.noSave = false
utils.removePin(self.pinID)
if self.spawnCron then
Cron.Halt(self.spawnCron)
self.spawnCron = nil
end
if self.rthID then
Cron.Halt(self.rthID)
self.rthID = nil
end
Cron.NextTick(function ()
self.handle:GetEntity():Destroy()
end)
Cron.After(1.5, function ()
utils.showInputHint("QuickMelee", lang.getText(lang.input_hint), 1, true)
end)
end
function drone:handleInput(deltaTime)
local acc = deltaTime * self.accel
local f = 1.8 -- Deaccaleration factor
if self.nd.input.forward then
self.vel.y = math.min(self.vel.y + acc * self.nd.input.analogForward, math.max(self.vel.y, self.topSpeed * self.nd.input.analogForward))
elseif self.vel.y > 0 then
self.vel.y = self.vel.y - acc * f
self.vel.y = math.max(0, self.vel.y)
end
if self.nd.input.backwards then
self.vel.y = math.max(self.vel.y - acc * self.nd.input.analogBackwards, math.min(self.vel.y, -self.topSpeed * self.nd.input.analogBackwards))
elseif self.vel.y < 0 then
self.vel.y = self.vel.y + acc * f
self.vel.y = math.min(0, self.vel.y)
end
if self.nd.input.right then
self.vel.x = math.min(self.vel.x + acc * self.nd.input.analogRight, math.max(self.vel.x, self.topSpeed * self.nd.input.analogRight))
elseif self.vel.x > 0 then
self.vel.x = self.vel.x - acc * f
self.vel.x = math.max(0, self.vel.x)
end
if self.nd.input.left then
self.vel.x = math.max(self.vel.x - acc * self.nd.input.analogLeft, math.min(self.vel.x, -self.topSpeed * self.nd.input.analogLeft))
elseif self.vel.x < 0 then
self.vel.x = self.vel.x + acc * f
self.vel.x = math.min(0, self.vel.x)
end
if self.nd.input.up then
self.vel.z = math.min(self.vel.z + acc * self.nd.input.analogUp, self.topSpeed)
elseif self.vel.z > 0 then
self.vel.z = self.vel.z - acc * f
self.vel.z = math.max(0, self.vel.z)
end
if self.nd.input.down then
self.vel.z = math.max(self.vel.z - acc * self.nd.input.analogDown, -self.topSpeed)
elseif self.vel.z < 0 then
self.vel.z = self.vel.z + acc * f
self.vel.z = math.min(0, self.vel.z)
end
end
function drone:move(deltaTime)
local dir = Game.GetCameraSystem():GetActiveCameraForward()
local dist = 100
local globalVel = Vector4.new(0, 0, 0, 0)
globalVel.x = globalVel.x + (dir.x * self.vel.y) * (deltaTime * 25)
globalVel.y = globalVel.y + (dir.y * self.vel.y) * (deltaTime * 25)
local dir = Game.GetCameraSystem():GetActiveCameraRight()
globalVel.x = globalVel.x + (dir.x * self.vel.x) * (deltaTime * 25)
globalVel.y = globalVel.y + (dir.y * self.vel.x) * (deltaTime * 25)
globalVel.z = self.vel.z * 0.3
local globalVelN = globalVel:Normalize()
local hit, normal = target.GetLookAtPosition(utils.addVector(self.pos, utils.multVector(globalVelN, 0.7)), utils.addVector(self.pos, utils.multVector(globalVelN, 10)))
if hit then
dist = Vector4.Distance(hit, self.pos)
end
if (dist < 0.8) then
globalVel = utils.multVector(globalVel, 0.9)
normal = utils.multVector(Vector4.Vector3To4(normal), globalVel:Length())
self.pos.x = self.pos.x + math.min((globalVel.x + normal.x), normal.y)
self.pos.y = self.pos.y + math.max((globalVel.y + normal.y), normal.x)
self.pos.z = self.pos.z + (globalVel.z + normal.z)
else
self.pos.x = self.pos.x + globalVel.x
self.pos.y = self.pos.y + globalVel.y
self.pos.z = self.pos.z + globalVel.z
end
Game.GetTeleportationFacility():Teleport(self.handle, self.pos, self.handle:GetWorldOrientation():ToEulerAngles())
end
function drone:handleHUD()
if self.ui.hud then
local dist = math.floor(Vector4.Distance(GetPlayer():GetWorldPosition(), self.pos))
local rangeStr = lang.getText(lang.range) .. ": " .. dist .. "/" .. math.floor(self.range)
local batteryStr = lang.getText(lang.drone_status) .. ": \n " .. lang.getText(lang.battery) .. ": " .. math.floor(self.batteryPercent) .. "%"
if self.ui.quickhacking then
local qhBattery = ui.qhCost * data.getQuickhackMult() * 10
if self.batteryPercent - qhBattery <= 0 then
self.ui.ram_conflictText:SetVisible(true)
self.ui.ramCostTooHigh = true
else
self.ui.ram_conflictText:SetVisible(false)
self.ui.ramCostTooHigh = false
end
batteryStr = batteryStr .. " - " .. math.floor(qhBattery) .. "%"
else
self.ui.ram_conflictText:SetVisible(false)
self.ui.ramCostTooHigh = false
end
inkTextRef.SetText(self.ui.hud.Date, tostring(batteryStr .. " \n " .. rangeStr))
end
end
function drone:handleRange()
local time = 5
if math.floor(Vector4.Distance(GetPlayer():GetWorldPosition(), self.pos)) > data.getRange() and not self.rthID then
self.ui.max_range_text:SetVisible(true)
self.ui.max_range_text:SetText(tostring(lang.getText(lang.range_warning) .. time .. "s"))
self.rthID = Cron.Every(1.0, {tick = time}, function(timer)
if timer.tick > 0 then
timer.tick = timer.tick - 1
self.ui.max_range_text:SetText(tostring(lang.getText(lang.range_warning) .. timer.tick .. "s"))
else
timer:Halt()
self.ui.max_range_text:SetVisible(false)
self:despawn()
self.rthID = nil
end
end)
elseif math.floor(Vector4.Distance(GetPlayer():GetWorldPosition(), self.pos)) < data.getRange() and self.rthID then
self.ui.max_range_text:SetVisible(false)
Cron.Halt(self.rthID)
self.rthID = nil
end
end
function drone:handleDoors()
local target = Game.GetTargetingSystem():GetLookAtObject(GetPlayer(), false, true)
if not (self.tier >= 3) then return end
utils.createInteractionHub(lang.getText(lang.open_door), "Choice1", false)
if not target then return end
if Vector4.Distance(target:GetWorldPosition(), self.pos) > 2.9 then return end
if target:GetClassName().value == "Door" then
-- Handle UI
if target:HasAnySkillCheckActive() then
utils.createInteractionHub(lang.getText(lang.door_requires_skillcheck), "Choice1", true)
else
local ps = target:GetDevicePS()
local state = ps:IsOpen()
local costText = ""
local cost = 0
if ps:IsLocked() or ps:IsSealed() then
cost = data.getQuickhackMult() * 10 * 3
else
cost = data.getQuickhackMult() * 8
end
cost = math.floor(cost)
costText = string.format(" (%i%% " .. lang.getText(lang.battery_cost) .. ")", cost)
if self.batteryPercent - cost <= 0 and costText ~= "" then
self.ui.ram_conflictText:SetVisible(true)
else
self.ui.ram_conflictText:SetVisible(false)
end
if not state then
utils.createInteractionHub(tostring(lang.getText(lang.open_door)) .. costText, "Choice1", true)
else
utils.createInteractionHub(tostring(lang.getText(lang.close_door)) .. costText, "Choice1", true)
end
-- Handle input
if self.nd.input.interact and (self.batteryPercent - cost > 0) then
self.nd.input.interact = false
if ps:IsLocked() then
ps:ToggleLockOnDoor()
end
if ps:IsSealed() then
ps:ToggleSealOnDoor()
end
self.batteryPercent = self.batteryPercent - cost
if not state then
target:OpenDoor()
else
target:CloseDoor()
end
end
end
else
-- Remove input UI
utils.createInteractionHub(lang.getText(lang.open_door), "Choice1", false)
utils.createInteractionHub(lang.getText(lang.close_door), "Choice1", false)
utils.createInteractionHub(lang.getText(lang.door_requires_skillcheck), "Choice1", false)
end
end
function drone:update(deltaTime)
if self.spawned then
if self.forceTakeOver then
if Game.FindEntityByID(self.entID) then
self.forceTakeOver = false
self.handle = Game.FindEntityByID(self.entID)
self.handle:OnToggleTakeOverControl(ToggleTakeOverControl.new())
self.handle.maxPitch = 3
Game.GetStatusEffectSystem():ApplyStatusEffect(GetPlayer():GetEntityID(), "GameplayRestriction.NoJump", GetPlayer():GetRecordID(), GetPlayer():GetEntityID())
end
end
if self.fullySpawned then
self:handleInput(deltaTime)
self:move(deltaTime)
self:handleRange()
self:handleHUD()
self:handleDoors()
Game.GetTimeSystem():UnsetTimeDilation("focusMode")
if not Game.FindEntityByID(self.entID) then
self:despawn(true)
end
end
Game.GetTeleportationFacility():Teleport(GetPlayer(), self.playerPos, self.playerRot)
elseif not self.rechargeID and self.batteryPercent ~= 100 then
self:startRecharge()
end
end
return drone
Upd. For some reason "ToggleSprint" is just not working for me to move drone down. I made some changes to bind it to "Crouch_Button". And it works.
r6/inut/NanoDrone.xml
<action name="Jump" map="Jump_Button" /> <!-- Added for NanoDrone mod -->
<action name="Down" map="Crouch_Button" />
bin\x64\plugins\cyber_engine_tweaks\mods\nanoDrone\modules\input.lua
elseif actionName == 'ToggleSprint' then
if actionType == 'BUTTON_PRESSED' then
input.down = true
input.analogDown = 1
elseif actionType == 'BUTTON_RELEASED' then
input.down = false
input.analogDown = 0
end
elseif actionName == 'Down' then
if actionType == 'BUTTON_PRESSED' then
input.down = true
input.analogDown = 1
elseif actionType == 'BUTTON_RELEASED' then
input.down = false
input.analogDown = 0
end
And another annoying thing... A drone can look In all directions but can't look upper the "horizon". How can I fix it?