From 006fcea22f0b40d67623861f7bed6d6644571c5b Mon Sep 17 00:00:00 2001
From: schwiti6190 <58079399+schwiti6190@users.noreply.github.com>
Date: Fri, 25 Jun 2021 12:56:51 +0200
Subject: [PATCH] Small fixes and improved global info texts
- fixes #7312
- created CourseDrawModeSetting
- global info texts improvements
---
AIDriver.lua | 15 +-
BalerAIDriver.lua | 2 +-
CpManager.lua | 353 +-------------------------------
Events/InfoTextEvent.lua | 7 +-
FieldworkAIDriver.lua | 6 +
GlobalInfoTextHandler.lua | 410 ++++++++++++++++++++++++++++++++++++++
TriggerHandler.lua | 10 +-
base.lua | 54 ++---
button.lua | 7 +-
config/InfoTexts.xml | 64 ++++++
courseplay.lua | 40 ++--
hud.lua | 16 +-
input.lua | 8 +-
settings.lua | 48 ++++-
start_stop.lua | 5 +-
15 files changed, 590 insertions(+), 455 deletions(-)
create mode 100644 GlobalInfoTextHandler.lua
create mode 100644 config/InfoTexts.xml
diff --git a/AIDriver.lua b/AIDriver.lua
index ee86c00f3..9db3784f0 100644
--- a/AIDriver.lua
+++ b/AIDriver.lua
@@ -416,14 +416,15 @@ end
-- This has to be called in each update cycle to show messages
function AIDriver:updateInfoText()
for msg, _ in pairs(self.activeMsgReferences) do
- CpManager:setGlobalInfoText(self.vehicle, msg)
+ g_globalInfoTextHandler:setInfoText(self.vehicle, msg)
end
end
--- Displays an one time ingame warning.
---@param msgReference string this can be a global info text or just a translation text.
function AIDriver:displayWarning(msgReference)
- local msg = CpManager.globalInfoText.msgReference[msgReference] or msgReference
+ local infoTexts = g_globalInfoTextHandler:getInfoTexts()
+ local msg = infoTexts[msgReference] and infoTexts[msgReference].text or msgReference
local text = string.format("%s: %s",nameNum(self.vehicle),courseplay:loc(msg))
g_currentMission:addIngameNotification(FSBaseMission.INGAME_NOTIFICATION_CRITICAL, text)
end
@@ -1725,7 +1726,7 @@ end
--- without restarting the game.
function AIDriver:onDraw()
if CpManager.isDeveloper and self.course and
- (self.vehicle.cp.drawCourseMode == courseplay.COURSE_2D_DISPLAY_DBGONLY or self.vehicle.cp.drawCourseMode == courseplay.COURSE_2D_DISPLAY_BOTH) then
+ self.settings.courseDrawMode:isCourseVisible() then
self.course:draw()
end
if CpManager.isDeveloper and self.pathfinder then
@@ -2189,13 +2190,13 @@ end
function AIDriver:isFuelLevelOk()
local currentFuelPercentage = self:getFuelLevelPercentage()
if currentFuelPercentage < 5 then
- CpManager:setGlobalInfoText(self.vehicle, 'FUEL_MUST');
+ self:setInfoText('FUEL_MUST')
return false
elseif currentFuelPercentage < 20 then
- CpManager:setGlobalInfoText(self.vehicle, 'FUEL_SHOULD');
+ self:setInfoText('FUEL_SHOULD')
elseif currentFuelPercentage < 99.99 then
- -- CpManager:setGlobalInfoText(vehicle, 'FUEL_IS');
- end;
+ -- self:setInfoText('FUEL_IS')
+ end
return true
end
diff --git a/BalerAIDriver.lua b/BalerAIDriver.lua
index e97dbd51d..9e41423ab 100644
--- a/BalerAIDriver.lua
+++ b/BalerAIDriver.lua
@@ -120,7 +120,7 @@ function BalerAIDriver:handleBaler()
self:setSpeed(0)
--baler needs refilling of some sort (net,...)
if self.balerSpec.unloadingState == Baler.UNLOADING_CLOSED then
- CpManager:setGlobalInfoText(self.vehicle, 'NEEDS_REFILLING');
+ self:setInfoText('NEEDS_REFILLING')
end
end
end
diff --git a/CpManager.lua b/CpManager.lua
index bce4cbb3a..358eed1b9 100644
--- a/CpManager.lua
+++ b/CpManager.lua
@@ -55,7 +55,7 @@ function CpManager:loadMap(name)
-- SETUP (continued)
courseplay.hud:setup(); -- NOTE: hud has to be set up after the xml settings have been loaded, as almost all its values are based on basePosX/Y
self:setUpDebugChannels(); -- NOTE: debugChannels have to be set up after the hud, as they rely on some hud values [positioning]
- self:setupGlobalInfoText(); -- NOTE: globalInfoText has to be set up after the hud, as they rely on some hud values [colors, function]
+ g_globalInfoTextHandler:setup() -- NOTE: globalInfoText has to be set up after the hud, as they rely on some hud values [colors, function]
courseplay.courses:setup(); -- NOTE: load the courses and folders from the XML
self:setup2dCourseData(true); -- NOTE: setup2dCourseData is called a second time, now we actually create the data and overlays
courseplay:register(true)-- NOTE: running here again to check whether there were mods loaded after courseplay
@@ -72,8 +72,6 @@ function CpManager:loadMap(name)
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- INPUT
- self.playerOnFootMouseEnabled = false;
- self.wasPlayerFrozen = false;
local ovl = courseplay.inputBindings.mouse.overlaySecondary;
if ovl then
local h = (2.5 * g_currentMission.helpBoxTextSize);
@@ -173,19 +171,7 @@ function CpManager:deleteMap()
end;
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- if self.globalInfoText and self.globalInfoText.buttons then
- --delete globalInfoText overlays
- for i,button in pairs(self.globalInfoText.buttons) do
- button:deleteOverlay();
-
- if self.globalInfoText.overlays[i] then
- local ovl = self.globalInfoText.overlays[i];
- if ovl.overlayId ~= nil and ovl.delete ~= nil then
- ovl:delete();
- end;
- end;
- end;
- end
+ g_globalInfoTextHandler:delete()
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- delete waypoint signs and protoTypes
for section,signDatas in pairs(courseplay.signs.buffer) do
@@ -315,20 +301,8 @@ function CpManager:draw()
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- DISPLAY GLOBALINFOTEXTS
- local git = self.globalInfoText;
- git.hasContent = false;
- local numLinesRendered = 0;
- local basePosY = git.posY;
- if not (g_currentMission.hud.ingameMap.isVisible and g_currentMission.hud.ingameMap:getIsFullSize()) and next(git.content) ~= nil then
- git.hasContent = true;
- if g_currentMission.hud.ingameMap.isVisible then
- basePosY = git.posYAboveMap;
- end;
- numLinesRendered = self:renderGlobalInfoTexts(basePosY);
- end;
- git.buttonsClickArea.y1 = basePosY;
- git.buttonsClickArea.y2 = basePosY + (numLinesRendered * (git.lineHeight + git.lineMargin));
-
+ g_globalInfoTextHandler:render()
+
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- DISPLAY FIELD SCAN MSG
if courseplay.fields.fieldDefinitionBase and courseplay.globalSettings.autoFieldScan:is(true) and not courseplay.fields.allFieldsScanned and self.startFieldScanAfter <= 0 then
@@ -347,110 +321,11 @@ function CpManager:mouseEvent(posX, posY, isDown, isUp, mouseKey)
courseplay:onMouseEvent(posX, posY, isDown, isUp, mouseKey)
-
- local area = self.globalInfoText.buttonsClickArea;
- if area == nil then
- return;
- end;
+ g_globalInfoTextHandler:mouseEvent(posX, posY, isDown, isUp, mouseKey)
- -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- -- LEFT CLICK to click the button shown in globalInfoText
- if (isDown or isUp) and mouseKey == courseplay.inputBindings.mouse.primaryButtonId and courseplay:mouseIsInArea(posX, posY, area.x1, area.x2, area.y1, area.y2) then
- self:onPrimaryMouseClick(posX, posY, isDown, isUp, mouseKey)
- -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- -- RIGHT CLICK to activate the mouse cursor when I'm not in a vehicle and a globalInfoText is shown
- elseif isUp and mouseKey == courseplay.inputBindings.mouse.secondaryButtonId and g_currentMission.controlledVehicle == nil then
- self:onSecondaryMouseClick(posX, posY, isDown, isUp, mouseKey)
- -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- -- HOVER
- elseif not isDown and not isUp and self:getHasGlobalInfoText() then
- for _,button in pairs(self.globalInfoText.buttons) do
- button:setClicked(false);
- if button.show and not button.isHidden then
- button:setHovered(button:getHasMouse(posX, posY));
- end;
- end;
- end;
g_devHelper:mouseEvent(posX, posY, isDown, isUp, mouseKey)
end;
----Secondary mouse button pressed
----@param float posX, mouse x position
----@param float posY, mouse y position
----@param boolean isDown, is the mouse button down ?
----@param boolean isUp, is the mouse button up ?
----@param int mouseKey, which mouse button was pressed ?
-function CpManager:onSecondaryMouseClick(posX, posY, isDown, isUp, mouseKey)
- if self:getHasGlobalInfoText() and not self.playerOnFootMouseEnabled and not g_currentMission.player.currentTool then
- self.playerOnFootMouseEnabled = true
- self.wasPlayerFrozen = g_currentMission.isPlayerFrozen
- g_currentMission.isPlayerFrozen = true
- elseif self.playerOnFootMouseEnabled then
- self.playerOnFootMouseEnabled = false
- if self:getHasGlobalInfoText() then --if a button was hovered when deactivating the cursor, deactivate hover state
- self:resetGlobalInfoTextButtons()
- end;
- if not self.wasPlayerFrozen then
- g_currentMission.isPlayerFrozen = false
- end;
- end;
- g_inputBinding:setShowMouseCursor(self.playerOnFootMouseEnabled)
- CpManager:updateMouseInputText()
-end
-
----Primary mouse button pressed
----@param float posX, mouse x position
----@param float posY, mouse y position
----@param boolean isDown, is the mouse button down ?
----@param boolean isUp, is the mouse button up ?
----@param int mouseKey, which mouse button was pressed ?
-function CpManager:onPrimaryMouseClick(posX, posY, isDown, isUp, mouseKey)
- if self:getHasGlobalInfoText() then
- for i,button in pairs(self.globalInfoText.buttons) do
- if button.show and button:getHasMouse(posX, posY) then
- button:setClicked(isDown)
- if isUp then
- local sourceVehicle = g_currentMission.controlledVehicle or button.parameter
- button:handleMouseClick(sourceVehicle)
- end
- break
- end
- end
- CpManager:updateMouseInputText()
- end
-end
-
----Is the second mouse button allowed, when the player isn't in a vehicle ?
----@return boolean allowed?
-function CpManager:isSecondaryMouseClickAllowed()
- return self.playerOnFootMouseEnabled or self:getHasGlobalInfoText() and not self.playerOnFootMouseEnabled and not g_currentMission.player.currentTool
-end
-
----Is the first mouse button allowed, when the player isn't in a vehicle ?
----@return boolean allowed?
-function CpManager:isPrimaryMouseClickAllowed()
- return self:getHasGlobalInfoText() and self.playerOnFootMouseEnabled
-end
-
----Updates mouse input texts
----@param boolean forceText should the texts forced to display?
-function CpManager:updateMouseInputText()
- -- HELP MENU
- ---TODO: For now always display the mouse action text,
- --- as this one would probably be broken in MP,
- --- should probably rework global info texts.
-
--- if g_gui.currentGui == nil and not g_currentMission.player.currentTool then
--- g_currentMission.hud.inputHelp:clearCustomEntries()
--- if self:isPrimaryMouseClickAllowed() or g_currentMission.controlledVehicle ~= nil then
--- g_currentMission.hud.inputHelp:addCustomEntry('COURSEPLAY_MOUSEACTION_PRIMARY', '', courseplay:loc("input_COURSEPLAY_MOUSEACTION_PRIMARY"), false)
--- end
--- if self:isSecondaryMouseClickAllowed() or g_currentMission.controlledVehicle ~= nil then
--- g_currentMission.hud.inputHelp:addCustomEntry('COURSEPLAY_MOUSEACTION_SECONDARY', '', courseplay:loc("input_COURSEPLAY_MOUSEACTION_SECONDARY"), false)
--- end
--- end
-end
-
function CpManager:keyEvent(unicode, sym, modifier, isDown)
courseplay:onKeyEvent(unicode, sym, modifier, isDown)
g_devHelper:keyEvent(unicode, sym, modifier, isDown)
@@ -945,224 +820,6 @@ function CpManager:fieldScanDialogueCallback(setActive)
self.showFieldScanYesNoDialogue = false
end;
--- ####################################################################################################
--- GLOBALINFOTEXT
-function CpManager:setupGlobalInfoText()
- print('## Courseplay: setting up globalInfoText');
-
- self.globalInfoText = {};
-
- self.globalInfoText.posY = 0.01238; -- = ingameMap posY
- self.globalInfoText.posYAboveMap = self.globalInfoText.posY + 0.027777777777778 + 0.20833333333333;
- self.globalInfoText.fontSize = courseplay.hud:pxToNormal(18, 'y');
- self.globalInfoText.lineHeight = self.globalInfoText.fontSize * 1.2;
- self.globalInfoText.lineMargin = self.globalInfoText.lineHeight * 0.2;
- self.globalInfoText.buttonHeight = self.globalInfoText.lineHeight;
- self.globalInfoText.buttonWidth = self.globalInfoText.buttonHeight / g_screenAspectRatio;
- self.globalInfoText.buttonPosX = 0.015625; -- = ingameMap posX
- self.globalInfoText.buttonMargin = self.globalInfoText.buttonWidth * 0.4;
- self.globalInfoText.backgroundPadding = self.globalInfoText.buttonWidth * 0.2;
- self.globalInfoText.backgroundImg = 'dataS2/menu/white.png';
- self.globalInfoText.backgroundPosX = self.globalInfoText.buttonPosX + self.globalInfoText.buttonWidth + self.globalInfoText.buttonMargin;
- self.globalInfoText.backgroundPosY = self.globalInfoText.posY;
- self.globalInfoText.textPosX = self.globalInfoText.backgroundPosX + self.globalInfoText.backgroundPadding;
- self.globalInfoText.content = {};
- self.globalInfoText.vehicleHasText = {};
- self.globalInfoText.levelColors = {
- [-2] = courseplay.hud.colors.closeRed;
- [-1] = courseplay.hud.colors.activeRed;
- [0] = courseplay.hud.colors.hover;
- [1] = courseplay.hud.colors.activeGreen;
- };
-
- self.globalInfoText.maxNum = 20;
- self.globalInfoText.overlays = {};
- self.globalInfoText.buttons = {};
- for i=1, self.globalInfoText.maxNum do
- local posY = self.globalInfoText.backgroundPosY + (i - 1) * self.globalInfoText.lineHeight;
- self.globalInfoText.overlays[i] = Overlay:new(self.globalInfoText.backgroundImg, self.globalInfoText.backgroundPosX, posY, 0.1, self.globalInfoText.buttonHeight);
- courseplay.button:new(self, 'globalInfoText', 'iconSprite.png', 'goToVehicle', i, self.globalInfoText.buttonPosX, posY, self.globalInfoText.buttonWidth, self.globalInfoText.buttonHeight);
- end;
- self.globalInfoText.buttonsClickArea = {
- x1 = self.globalInfoText.buttonPosX;
- x2 = self.globalInfoText.buttonPosX + self.globalInfoText.buttonWidth;
- y1 = self.globalInfoText.backgroundPosY,
- y2 = self.globalInfoText.backgroundPosY + (self.globalInfoText.maxNum * (self.globalInfoText.lineHeight + self.globalInfoText.lineMargin));
- };
- self.globalInfoText.hasContent = false;
-
-
- self.globalInfoText.msgReference = {
- BGA_IS_FULL = { level = -1, text = 'COURSEPLAY_BGA_IS_FULL'};
- DAMAGE_IS = { level = 0, text = 'COURSEPLAY_DAMAGE_IS_BEING_REPAIRED' };
- DAMAGE_MUST = { level = -2, text = 'COURSEPLAY_DAMAGE_MUST_BE_REPAIRED' };
- DAMAGE_SHOULD = { level = -1, text = 'COURSEPLAY_DAMAGE_SHOULD_BE_REPAIRED' };
- END_POINT = { level = 0, text = 'COURSEPLAY_REACHED_END_POINT' };
- END_POINT_MODE_1 = { level = 0, text = 'COURSEPLAY_REACHED_END_POINT_MODE_1' };
- END_POINT_MODE_8 = { level = 0, text = 'COURSEPLAY_REACHED_END_POINT_MODE_8' };
- FARM_SILO_NO_FILLTYPE = { level = -2, text = 'COURSEPLAY_FARM_SILO_NO_FILLTYPE'};
- FARM_SILO_IS_EMPTY = { level = 0, text = 'COURSEPLAY_FARM_SILO_IS_EMPTY'};
- FARM_SILO_IS_FULL = { level = 0, text = 'COURSEPLAY_FARM_SILO_IS_FULL'};
- FUEL_IS = { level = 0, text = 'COURSEPLAY_IS_BEING_REFUELED' };
- FUEL_MUST = { level = -2, text = 'COURSEPLAY_MUST_BE_REFUELED' };
- FUEL_SHOULD = { level = -1, text = 'COURSEPLAY_SHOULD_BE_REFUELED' };
- HOSE_MISSING = { level = -2, text = 'COURSEPLAY_HOSEMISSING' };
- NEEDS_REFILLING = { level = -1, text = 'COURSEPLAY_NEEDS_REFILLING' };
- NEEDS_UNLOADING = { level = -1, text = 'COURSEPLAY_NEEDS_UNLOADING' };
- OVERLOADING_POINT = { level = 0, text = 'COURSEPLAY_REACHED_OVERLOADING_POINT' };
- PICKUP_JAMMED = { level = -2, text = 'COURSEPLAY_PICKUP_JAMMED' };
- SLIPPING_1 = { level = -1, text = 'COURSEPLAY_SLIPPING_WARNING' };
- SLIPPING_2 = { level = -2, text = 'COURSEPLAY_SLIPPING_WARNING' };
- TRAFFIC = { level = -1, text = 'COURSEPLAY_IS_IN_TRAFFIC' };
- SLOWING_DOWN_FOR_TRAFFIC = { level = 0, text = 'COURSEPLAY_SLOWING_DOWN_FOR_TRAFFIC' };
- UNLOADING_BALE = { level = 0, text = 'COURSEPLAY_UNLOADING_BALES' };
- WAIT_POINT = { level = 0, text = 'COURSEPLAY_REACHED_WAITING_POINT' };
- WATER = { level = -2, text = 'COURSEPLAY_WATER_WARNING' };
- WEATHER = { level = 0, text = 'COURSEPLAY_WEATHER_WARNING' };
- WEIGHING_VEHICLE = { level = 0, text = 'COURSEPLAY_IS_BEING_WEIGHED' };
- WORK_END = { level = 1, text = 'COURSEPLAY_WORK_END' };
- REACHED_OVERLOADING_POINT = { level = 0, text = 'COURSEPLAY_REACHED_OVERLOADING_POINT' };
- NO_SELECTED_FILLTYPE = { level = 0, text = 'COURSEPLAY_NO_SELECTED_FILLTYPE' };
- REACHED_REFILLING_POINT = { level = 0, text = 'COURSEPLAY_REACHED_REFILL_POINT' };
- WRONG_FILLTYPE_FOR_TRIGGER = { level = 0, text = 'COURSEPLAY_WRONG_FILLTYPE_FOR_TRIGGER' };
- RUNCOUNTER_ERROR_FOR_TRIGGER = { level = 0, text = 'COURSEPLAY_RUNCOUNTER_ERROR_FOR_TRIGGER' };
- WAITING_FOR_UNLOADERS = { level = 0, text = 'COURSEPLAY_WAITING_FOR_UNLOADERS' };
- WAITING_FOR_LEVELCOMPACTAIDRIVER = { level = 0, text = 'COURSEPLAY_WAITING_FOR_LEVELCOMPACTAIDRIVER' };
- NO_FIELD_SELECTED = { level = -1, text = 'COURSEPLAY_NO_FIELD_SELECTED' };
- };
-end;
-
-function CpManager:setGlobalInfoText(vehicle, refIdx, forceRemove,additionalString)
- local git = self.globalInfoText;
-
- --TODO: test in Multiplayer if it works fine
- if vehicle.cp.activeGlobalInfoTexts[refIdx] ~= nil and (additionalString ~= vehicle.cp.gitAdditionalText and g_server~= nil) then
- vehicle:setCpVar('gitAdditionalText',additionalString,courseplay.isClient)
- forceRemove = true
- end
-
-
- --print(string.format('setGlobalInfoText(vehicle, %s, %s)', tostring(refIdx), tostring(forceRemove)));
- if forceRemove then
- if g_server ~= nil then
- -- CourseplayEvent.sendEvent(vehicle, "setMPGlobalInfoText", refIdx, false, forceRemove)
- InfoTextEvent.sendEvent(vehicle,refIdx,forceRemove)
- end
- if git.content[vehicle.rootNode][refIdx] then
- git.content[vehicle.rootNode][refIdx] = nil;
- end;
- vehicle.cp.activeGlobalInfoTexts[refIdx] = nil;
- vehicle.cp.numActiveGlobalInfoTexts = vehicle.cp.numActiveGlobalInfoTexts - 1;
- --print(string.format('\t%s: remove globalInfoText[%s] from global table, numActiveGlobalInfoTexts=%d', nameNum(vehicle), refIdx, vehicle.cp.numActiveGlobalInfoTexts));
- if vehicle.cp.numActiveGlobalInfoTexts == 0 then
- git.content[vehicle.rootNode] = nil;
- --print(string.format('\t\tset globalInfoText.content[rootNode] to nil'));
- end;
- return;
- end;
-
- vehicle.cp.hasSetGlobalInfoTextThisLoop[refIdx] = true;
- local data = git.msgReference[refIdx];
- --print(string.format('refIdx=%q, level=%s, text=%q, textLoc=%q', tostring(refIdx), tostring(data.level), tostring(data.text), tostring(courseplay:loc(data.text))));
- if vehicle.cp.activeGlobalInfoTexts[refIdx] == nil or vehicle.cp.activeGlobalInfoTexts[refIdx] ~= data.level then
- if g_server ~= nil then
- -- CourseplayEvent.sendEvent(vehicle, "setMPGlobalInfoText", refIdx, false, forceRemove)
- InfoTextEvent.sendEvent(vehicle,refIdx,forceRemove)
- end
- if vehicle.cp.activeGlobalInfoTexts[refIdx] == nil then
- vehicle.cp.numActiveGlobalInfoTexts = vehicle.cp.numActiveGlobalInfoTexts + 1;
- end;
- local text = nameNum(vehicle) .. " " .. courseplay:loc(data.text);
- if vehicle.cp.gitAdditionalText ~= nil then
- text = text..": "..vehicle.cp.gitAdditionalText
- end
- --print(string.format('\t%s: setGlobalInfoText [%q] numActiveGlobalInfoTexts=%d, lvl %d, text=%q', nameNum(vehicle), refIdx, vehicle.cp.numActiveGlobalInfoTexts, data.level, tostring(text)));
- vehicle.cp.activeGlobalInfoTexts[refIdx] = data.level;
-
- if git.content[vehicle.rootNode] == nil then
- git.content[vehicle.rootNode] = {};
- end;
- git.content[vehicle.rootNode][refIdx] = {
- level = data.level,
- text = text,
- backgroundWidth = getTextWidth(git.fontSize, text) + git.backgroundPadding * 2.5,
- vehicle = vehicle
- };
- end;
-end;
-
-function CpManager:renderGlobalInfoTexts(basePosY)
- local git = self.globalInfoText;
- local line = 0;
- courseplay:setFontSettings('white', false, 'left');
- for _,refIndexes in pairs(git.content) do
- if line >= self.globalInfoText.maxNum then
- break;
- end;
-
- for refIdx,data in pairs(refIndexes) do
- line = line + 1;
-
- -- background
- local bg = git.overlays[line];
- bg:setColor(unpack(git.levelColors[data.level]));
- local gfxPosY = basePosY + (line - 1) * (git.lineHeight + git.lineMargin);
- bg:setPosition(bg.x, gfxPosY);
- bg:setDimension(data.backgroundWidth, bg.height);
- bg:render();
-
- -- text
- local textPosY = gfxPosY + (git.lineHeight - git.fontSize) * 1.2; -- should be (lineHeight-fontSize)*0.5, but there seems to be some pixel/sub-pixel rendering error
- renderText(git.textPosX, textPosY, git.fontSize, data.text);
- -- button
- local button = self.globalInfoText.buttons[line];
- if button ~= nil then
- button:setPosition(button.overlay.x, gfxPosY)
-
- local currentColor = button.curColor;
- local targetColor = currentColor;
-
- button:setCanBeClicked(true);
- button:setDisabled(data.vehicle.isBroken or data.vehicle.isControlled);
- button:setParameter(data.vehicle);
- if g_currentMission.controlledVehicle and g_currentMission.controlledVehicle == data.vehicle then
- targetColor = 'activeGreen';
- button:setCanBeClicked(false);
- elseif button.isDisabled then
- targetColor = 'whiteDisabled';
- elseif button.isClicked then
- targetColor = 'activeRed';
- elseif button.isHovered then
- targetColor = 'hover';
- else
- targetColor = 'white';
- end;
-
- -- set color
- if currentColor ~= targetColor then
- button:setColor(targetColor);
- end;
-
- -- NOTE: do not use button:render() here, as we neither need the button.show check, nor the hoveredButton var, nor the color setting. Simply rendering the overlay suffices
- button.overlay:render();
- end;
- end;
- end;
-
- return line;
-end;
-
-function CpManager:resetGlobalInfoTextButtons()
- for _,button in pairs(self.globalInfoText.buttons) do
- button:setClicked(false);
- button:setHovered(false);
- end;
-end
-
-function CpManager:getHasGlobalInfoText()
- return self.globalInfoText.hasContent
-end
-
-- ####################################################################################################
-- 2D COURSE DRAW SETUP
function CpManager:setup2dCourseData(createOverlays)
diff --git a/Events/InfoTextEvent.lua b/Events/InfoTextEvent.lua
index 3c7df036c..3e18da41e 100644
--- a/Events/InfoTextEvent.lua
+++ b/Events/InfoTextEvent.lua
@@ -44,9 +44,12 @@ end
function InfoTextEvent:run(connection) -- wir fuehren das empfangene event aus
courseplay.debugVehicle(courseplay.DBG_MULTIPLAYER,vehicle,"run infoText event")
if self.vehicle then
- CpManager:setGlobalInfoText(self.vehicle, self.refIdx, self.forceRemove)
+ if self.forceRemove then
+ g_globalInfoTextHandler:resetInfoText(self.vehicle,self.refIdx)
+ else
+ g_globalInfoTextHandler:setInfoText(self.vehicle,self.refIdx)
+ end
end
-
end
function InfoTextEvent.sendEvent(vehicle,refIdx,forceRemove)
diff --git a/FieldworkAIDriver.lua b/FieldworkAIDriver.lua
index bed4f39d9..dbe3cc0ee 100644
--- a/FieldworkAIDriver.lua
+++ b/FieldworkAIDriver.lua
@@ -304,6 +304,12 @@ function FieldworkAIDriver:stop(msgReference)
AIDriver.stop(self, msgReference)
end
+
+function FieldworkAIDriver:setWorkFinished(msgReference)
+ self:stopWork()
+ AIDriver.setWorkFinished(self, msgReference)
+end
+
function FieldworkAIDriver:writeUpdateStream(streamId, connection, dirtyMask)
if self.vehicle.cp.settings.convoyActive:is(true) then
streamWriteInt32(streamId,self.convoyCurrentDistance)
diff --git a/GlobalInfoTextHandler.lua b/GlobalInfoTextHandler.lua
new file mode 100644
index 000000000..879da56e6
--- /dev/null
+++ b/GlobalInfoTextHandler.lua
@@ -0,0 +1,410 @@
+--[[
+This file is part of Courseplay (https://github.com/Courseplay/courseplay)
+Copyright (C) 2021 courseplay dev team
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+]]
+
+--[[
+ The global info texts handler controls all info texts at the left side of the screen relative to the vehicles.
+ It enables quick vehicle swapping by pressing the button which has an info texts by the vehicle.
+]]--
+
+
+---@class GlobalInfoTextHandler
+GlobalInfoTextHandler = CpObject()
+
+GlobalInfoTextHandler.attributes = {
+ {name = 'level', getXmlFunction = getXMLInt},
+ {name = 'text', getXmlFunction = getXMLString},
+}
+
+function GlobalInfoTextHandler:init()
+ self.playerOnFootMouseEnabled = false;
+ self.wasPlayerFrozen = false;
+ self.infoTexts = {}
+ self.vehicles = {}
+end
+
+--- Load the info text xml File.
+function GlobalInfoTextHandler:loadFromXml()
+ self.xmlFileName = Utils.getFilename('config/InfoTexts.xml', courseplay.path)
+ self.xmlFile = self:loadXmlFile(self.xmlFileName)
+end
+
+--- Loads the info texts.
+---@param fileName string
+function GlobalInfoTextHandler:loadXmlFile(fileName)
+ courseplay.info('Loading Info texts from %s ...', fileName)
+ if fileExists(fileName) then
+ local xmlFile = loadXMLFile('infoTexts', fileName);
+ local rootElement = 'InfoTexts'
+ if xmlFile and hasXMLProperty(xmlFile, rootElement) then
+ local i = 0
+ while true do
+ local infoTextElement = string.format('%s.InfoText(%d)', rootElement, i)
+ if hasXMLProperty(xmlFile, infoTextElement) then
+ self:loadInfoText(xmlFile, infoTextElement)
+ else
+ break
+ end
+ i = i + 1
+ end
+ return xmlFile
+ end
+ else
+ courseplay.info('Info text file %s does not exist.', fileName)
+ end
+end
+
+--- Load a single info text.
+---@param xmlFile number id of the loaded xml file.
+---@param infoTextElement string xml key to the info text element.
+function GlobalInfoTextHandler:loadInfoText(xmlFile, infoTextElement)
+ local infoText = {}
+ local name = getXMLString(xmlFile,string.format("%s#name",infoTextElement))
+ for _,attribute in pairs(self.attributes) do
+ infoText[attribute.name] = attribute.getXmlFunction(xmlFile,string.format("%s#%s",infoTextElement,attribute.name))
+ end
+ self.infoTexts[name] = infoText
+end
+
+--- Setup all the basic global info text information.
+--- Needs to be done after the hud is initialized.
+function GlobalInfoTextHandler:setup()
+ --- Load info texts
+ self:loadFromXml()
+
+ --- All visual/button variables
+ self.posY = 0.01238; -- = ingameMap posY
+ self.posYAboveMap = self.posY + 0.027777777777778 + 0.20833333333333;
+ self.fontSize = courseplay.hud:pxToNormal(18, 'y');
+ self.lineHeight = self.fontSize * 1.2;
+ self.lineMargin = self.lineHeight * 0.2;
+ self.buttonHeight = self.lineHeight;
+ self.buttonWidth = self.buttonHeight / g_screenAspectRatio;
+ self.buttonPosX = 0.015625; -- = ingameMap posX
+ self.buttonMargin = self.buttonWidth * 0.4;
+ self.backgroundPadding = self.buttonWidth * 0.2;
+ self.backgroundImg = 'dataS2/menu/white.png';
+ self.backgroundPosX = self.buttonPosX + self.buttonWidth + self.buttonMargin;
+ self.backgroundPosY = self.posY;
+ self.textPosX = self.backgroundPosX + self.backgroundPadding;
+ self.content = {};
+ self.vehicleHasText = {};
+ self.levelColors = {
+ [-2] = courseplay.hud.colors.closeRed;
+ [-1] = courseplay.hud.colors.activeRed;
+ [0] = courseplay.hud.colors.hover;
+ [1] = courseplay.hud.colors.activeGreen;
+ };
+
+ self.maxNum = 20;
+ self.overlays = {};
+ self.buttons = {};
+ for i=1, self.maxNum do
+ local posY = self.backgroundPosY + (i - 1) * self.lineHeight;
+ self.overlays[i] = Overlay:new(self.backgroundImg, self.backgroundPosX, posY, 0.1, self.buttonHeight);
+ courseplay.button:new(self, 'globalInfoText', 'iconSprite.png', 'goToVehicle', i, self.buttonPosX, posY, self.buttonWidth, self.buttonHeight);
+ end;
+ self.buttonsClickArea = {
+ x1 = self.buttonPosX;
+ x2 = self.buttonPosX + self.buttonWidth;
+ y1 = self.backgroundPosY,
+ y2 = self.backgroundPosY + (self.maxNum * (self.lineHeight + self.lineMargin));
+ };
+ self.hasContent = false;
+end
+
+--- TODO: Find a better solution then to saves these in the vehicle.
+--- Adds a new vehicle.
+---@param vehicle table
+function GlobalInfoTextHandler:addVehicle(vehicle)
+ self.vehicles[vehicle] = {
+ currentInfoTexts = {},
+ lastInfoTexts = {}
+ }
+end
+
+--- Removes a vehicle.
+---@param vehicle table
+function GlobalInfoTextHandler:removeVehicle(vehicle)
+ self:resetAllInfoTextsForVehicle(vehicle)
+ self.vehicles[vehicle] = nil
+end
+
+
+--- Reset all not used info texts at the end of the vehicle update loop.
+---@param vehicle table
+function GlobalInfoTextHandler:resetInactiveInfoTextsForVehicle(vehicle)
+ for refIdx,_ in pairs(self.infoTexts) do
+ if not self.vehicles[vehicle].currentInfoTexts[refIdx] then
+ if self.vehicles[vehicle].lastInfoTexts[refIdx] then
+ self:resetInfoText(vehicle,refIdx)
+ end
+ end
+ end
+ self.vehicles[vehicle].lastInfoTexts = self.vehicles[vehicle].currentInfoTexts
+ self.vehicles[vehicle].currentInfoTexts = {}
+end
+
+--- Completely resets all info texts related to the vehicle.
+---@param vehicle table
+function GlobalInfoTextHandler:resetAllInfoTextsForVehicle(vehicle)
+ for refIdx,_ in pairs(self.infoTexts) do
+ if self.vehicles[vehicle].currentInfoTexts[refIdx]
+ or self.vehicles[vehicle].lastInfoTexts[refIdx] then
+ self:resetInfoText(vehicle,refIdx)
+ end
+ end
+end
+
+--- Sets a global info text for the given vehicle.
+---@param vehicle table
+---@param refIdx string index for the info text.
+function GlobalInfoTextHandler:setInfoText(vehicle, refIdx)
+
+ local data = self.infoTexts[refIdx]
+ if self.vehicles[vehicle].currentInfoTexts[refIdx] == nil or self.vehicles[vehicle].currentInfoTexts[refIdx] ~= data.level then
+ if g_server ~= nil then
+ InfoTextEvent.sendEvent(vehicle,refIdx,false)
+ end
+
+ local text = nameNum(vehicle) .. " " .. courseplay:loc(data.text);
+
+ self.vehicles[vehicle].currentInfoTexts[refIdx] = data.level;
+
+ if self.content[vehicle.rootNode] == nil then
+ self.content[vehicle.rootNode] = {};
+ end;
+ self.content[vehicle.rootNode][refIdx] = {
+ level = data.level,
+ text = text,
+ backgroundWidth = getTextWidth(self.fontSize, text) + self.backgroundPadding * 2.5,
+ vehicle = vehicle
+ };
+ end;
+end
+
+--- Resets a global info text for the given vehicle.
+---@param vehicle table
+---@param refIdx string index for the info text.
+function GlobalInfoTextHandler:resetInfoText(vehicle, refIdx)
+
+ if g_server ~= nil then
+ InfoTextEvent.sendEvent(vehicle,refIdx,true)
+ end
+ if self.content[vehicle.rootNode] and self.content[vehicle.rootNode][refIdx] then
+ self.content[vehicle.rootNode][refIdx] = nil;
+ end;
+ self.vehicles[vehicle][refIdx] = nil
+ if #self.vehicles[vehicle].currentInfoTexts == 0 then
+ self.content[vehicle.rootNode] = nil;
+ end;
+end
+
+
+--- Renders the info texts buttons.
+function GlobalInfoTextHandler:render()
+ self.hasContent = false;
+ local numLinesRendered = 0;
+ local basePosY = self.posY;
+ if not (g_currentMission.hud.ingameMap.isVisible and g_currentMission.hud.ingameMap:getIsFullSize()) and next(self.content) ~= nil then
+ self.hasContent = true;
+ if g_currentMission.hud.ingameMap.isVisible then
+ basePosY = self.posYAboveMap;
+ end;
+ end;
+ local line = 0;
+ courseplay:setFontSettings('white', false, 'left');
+ for _,refIndexes in pairs(self.content) do
+ if line >= self.maxNum then
+ break;
+ end;
+
+ for refIdx,data in pairs(refIndexes) do
+ line = line + 1;
+
+ -- background
+ local bg = self.overlays[line];
+ bg:setColor(unpack(self.levelColors[data.level]));
+ local gfxPosY = basePosY + (line - 1) * (self.lineHeight + self.lineMargin);
+ bg:setPosition(bg.x, gfxPosY);
+ bg:setDimension(data.backgroundWidth, bg.height);
+ bg:render();
+
+ -- text
+ local textPosY = gfxPosY + (self.lineHeight - self.fontSize) * 1.2; -- should be (lineHeight-fontSize)*0.5, but there seems to be some pixel/sub-pixel rendering error
+ renderText(self.textPosX, textPosY, self.fontSize, data.text);
+ -- button
+ local button = self.buttons[line];
+ if button ~= nil then
+ button:setPosition(button.overlay.x, gfxPosY)
+
+ local currentColor = button.curColor;
+ local targetColor = currentColor;
+
+ button:setCanBeClicked(true);
+ button:setDisabled(data.vehicle.isBroken or data.vehicle.isControlled);
+ button:setParameter(data.vehicle);
+ if g_currentMission.controlledVehicle and g_currentMission.controlledVehicle == data.vehicle then
+ targetColor = 'activeGreen';
+ button:setCanBeClicked(false);
+ elseif button.isDisabled then
+ targetColor = 'whiteDisabled';
+ elseif button.isClicked then
+ targetColor = 'activeRed';
+ elseif button.isHovered then
+ targetColor = 'hover';
+ else
+ targetColor = 'white';
+ end;
+
+ -- set color
+ if currentColor ~= targetColor then
+ button:setColor(targetColor);
+ end;
+
+ -- NOTE: do not use button:render() here, as we neither need the button.show check, nor the hoveredButton var, nor the color setting. Simply rendering the overlay suffices
+ button.overlay:render();
+ end;
+ end;
+ end;
+ self.buttonsClickArea.y1 = basePosY;
+ self.buttonsClickArea.y2 = basePosY + (line * (self.lineHeight + self.lineMargin));
+end;
+
+--- Resets all buttons.
+function GlobalInfoTextHandler:resetButtons()
+ for _,button in pairs(self.buttons) do
+ button:setClicked(false);
+ button:setHovered(false);
+ end;
+end
+
+--- Delete all button overlays.
+function GlobalInfoTextHandler:delete()
+ --delete globalInfoText overlays
+ for i,button in pairs(self.buttons) do
+ button:deleteOverlay();
+
+ if self.overlays[i] then
+ local ovl = self.overlays[i];
+ if ovl.overlayId ~= nil and ovl.delete ~= nil then
+ ovl:delete();
+ end;
+ end;
+ end;
+end
+
+--- Mouse event to interact with the info text buttons.
+---@param posX number mouse x position
+---@param posY number mouse y position
+---@param isDown boolean the mouse button down ?
+---@param isUp boolean the mouse button up ?
+---@param mouseKey number mouse button was pressed ?
+function GlobalInfoTextHandler:mouseEvent(posX, posY, isDown, isUp, mouseKey)
+ local area = self.buttonsClickArea;
+
+ -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ -- LEFT CLICK to click the button shown in globalInfoText
+ if (isDown or isUp) and mouseKey == courseplay.inputBindings.mouse.primaryButtonId and courseplay:mouseIsInArea(posX, posY, area.x1, area.x2, area.y1, area.y2) then
+ self:onPrimaryMouseClick(posX, posY, isDown, isUp, mouseKey)
+ -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ -- RIGHT CLICK to activate the mouse cursor when I'm not in a vehicle and a globalInfoText is shown
+ elseif isUp and mouseKey == courseplay.inputBindings.mouse.secondaryButtonId and g_currentMission.controlledVehicle == nil then
+ self:onSecondaryMouseClick(posX, posY, isDown, isUp, mouseKey)
+ -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ -- HOVER
+ elseif not isDown and not isUp and self.hasContent then
+ for _,button in pairs(self.buttons) do
+ button:setClicked(false)
+ if button.show and not button.isHidden then
+ button:setHovered(button:getHasMouse(posX, posY))
+ end
+ end
+ end
+end
+
+---Secondary mouse button pressed
+---@param posX number mouse x position
+---@param posY number mouse y position
+---@param isDown boolean the mouse button down ?
+---@param isUp boolean the mouse button up ?
+---@param mouseKey number mouse button was pressed ?
+function GlobalInfoTextHandler:onSecondaryMouseClick(posX, posY, isDown, isUp, mouseKey)
+ if self.hasContent and not self.playerOnFootMouseEnabled and not g_currentMission.player.currentTool then
+ self.playerOnFootMouseEnabled = true
+ self.wasPlayerFrozen = g_currentMission.isPlayerFrozen
+ g_currentMission.isPlayerFrozen = true
+ elseif self.playerOnFootMouseEnabled then
+ self.playerOnFootMouseEnabled = false
+ if self.hasContent then --if a button was hovered when deactivating the cursor, deactivate hover state
+ self:resetButtons()
+ end;
+ if not self.wasPlayerFrozen then
+ g_currentMission.isPlayerFrozen = false
+ end;
+ end;
+ g_inputBinding:setShowMouseCursor(self.playerOnFootMouseEnabled)
+end
+
+---Primary mouse button pressed
+---@param posX number mouse x position
+---@param posY number mouse y position
+---@param isDown boolean the mouse button down ?
+---@param isUp boolean the mouse button up ?
+---@param mouseKey number mouse button was pressed ?
+function GlobalInfoTextHandler:onPrimaryMouseClick(posX, posY, isDown, isUp, mouseKey)
+ if self.hasContent then
+ for i,button in pairs(self.buttons) do
+ if button.show and button:getHasMouse(posX, posY) then
+ button:setClicked(isDown)
+ if isUp then
+ local sourceVehicle = g_currentMission.controlledVehicle or button.parameter
+ button:handleMouseClick(sourceVehicle)
+ end
+ break
+ end
+ end
+ end
+end
+
+---Is the second mouse button allowed, when the player isn't in a vehicle ?
+---@return boolean allowed?
+function GlobalInfoTextHandler:isSecondaryMouseClickAllowed()
+ return self.playerOnFootMouseEnabled or self.hasContent and not self.playerOnFootMouseEnabled and not g_currentMission.player.currentTool
+end
+
+---Is the first mouse button allowed, when the player isn't in a vehicle ?
+---@return boolean allowed?
+function GlobalInfoTextHandler:isPrimaryMouseClickAllowed()
+ return self.hasContent and self.playerOnFootMouseEnabled
+end
+
+--- Gets all info texts
+function GlobalInfoTextHandler:getInfoTexts()
+ return self.infoTexts
+end
+
+--- Switch to a vehicle, which info text button was pressed.
+function GlobalInfoTextHandler:goToVehicle(vehicle)
+ g_client:getServerConnection():sendEvent(VehicleEnterRequestEvent:new(vehicle, g_currentMission.missionInfo.playerStyle, g_currentMission.player.farmId));
+ g_currentMission.isPlayerFrozen = false;
+ self.playerOnFootMouseEnabled = false;
+ g_inputBinding:setShowMouseCursor(vehicle.cp.mouseCursorActive);
+end
+
+
+g_globalInfoTextHandler = GlobalInfoTextHandler()
\ No newline at end of file
diff --git a/TriggerHandler.lua b/TriggerHandler.lua
index 6a25f331e..377055fb6 100644
--- a/TriggerHandler.lua
+++ b/TriggerHandler.lua
@@ -738,7 +738,7 @@ function TriggerHandler:onActivateObject(superFunc,vehicle)
return
else
triggerHandler:setFuelLoadingState()
- CpManager:setGlobalInfoText(vehicle, 'FARM_SILO_IS_EMPTY')
+ g_globalInfoTextHandler:setInfoText(vehicle, 'FARM_SILO_IS_EMPTY')
courseplay.debugFormat(courseplay.DBG_LOAD_UNLOAD, 'No Diesel at this trigger.')
end
else
@@ -791,7 +791,7 @@ function TriggerHandler:handleLoadingCallback(trigger,object,fillUnitIndex,loadi
-- min FillLevel not reached to start filling
elseif callbackData.callback == TriggerHandler.CALLBACK.MIN_NOT_REACHED then
self:setLoadingState()
- CpManager:setGlobalInfoText(self.vehicle, 'FARM_SILO_IS_EMPTY');
+ g_globalInfoTextHandler:setInfoText(self.vehicle, 'FARM_SILO_IS_EMPTY');
self:debugSparse(object, 'LoadingTrigger: minLevel not reached, fillType: '..g_fillTypeManager:getFillTypeByIndex(fillType).title)
return
--min is reached so continue..
@@ -805,14 +805,14 @@ function TriggerHandler:handleLoadingCallback(trigger,object,fillUnitIndex,loadi
--runCounter = 0
if lastCallbackData and lastCallbackData.callback == TriggerHandler.CALLBACK.RUN_COUNTER_NOT_REACHED then
self:setLoadingState()
- CpManager:setGlobalInfoText(self.vehicle, 'RUNCOUNTER_ERROR_FOR_TRIGGER');
+ g_globalInfoTextHandler:setInfoText(self.vehicle, 'RUNCOUNTER_ERROR_FOR_TRIGGER');
self:debugSparse(object, 'last runCounter=0, fillType: '..g_fillTypeManager:getFillTypeByIndex(lastCallbackData.data.fillType).title)
return
end
if lastCallbackData and (lastCallbackData.callback == TriggerHandler.CALLBACK.SKIP_LOADING or lastCallbackData.callback == TriggerHandler.CALLBACK.SEPARATE_FILLTYPE_NOT_ALLOWED) then
--not enough fillTypes loaded!!
self:setLoadingState()
- CpManager:setGlobalInfoText(self.vehicle, 'FARM_SILO_IS_EMPTY');
+ g_globalInfoTextHandler:setInfoText(self.vehicle, 'FARM_SILO_IS_EMPTY');
self:debugSparse(object, 'last FillType minLevel not reached, fillType: '..g_fillTypeManager:getFillTypeByIndex(lastCallbackData.data.fillType).title)
return
end
@@ -1179,7 +1179,7 @@ function TriggerHandler:onUpdateDischargeable(dt, isActiveForInput, isActiveForI
spec:setDischargeState(Dischargeable.DISCHARGE_STATE_OBJECT)
end
if currentDischargeNode.dischargeFailedReason and currentDischargeNode.dischargeFailedReason == Dischargeable.DISCHARGE_REASON_NO_FREE_CAPACITY then
- CpManager:setGlobalInfoText(rootVehicle, 'FARM_SILO_IS_FULL') -- not working for now, might have to double check
+ g_globalInfoTextHandler:setInfoText(rootVehicle, 'FARM_SILO_IS_FULL') -- not working for now, might have to double check
end
if currentDischargeNode.dischargeObject then
if triggerHandler.objectsInTrigger[self] == nil then
diff --git a/base.lua b/base.lua
index b405973fc..bc60245ed 100644
--- a/base.lua
+++ b/base.lua
@@ -69,11 +69,8 @@ function courseplay:onLoad(savegame)
self.cp.infoText = nil; -- info text in tractor
self.cp.toolTip = nil;
- -- global info text - also displayed when not in vehicle
- self.cp.hasSetGlobalInfoTextThisLoop = {};
- self.cp.activeGlobalInfoTexts = {};
- self.cp.numActiveGlobalInfoTexts = 0;
-
+ --- Adds the vehicle to the global info texts handler
+ g_globalInfoTextHandler:addVehicle(self)
-- CP mode
@@ -268,18 +265,12 @@ function courseplay:onLoad(savegame)
self.cp.mouseCursorActive = false;
- -- 2D course
- self.cp.drawCourseMode = courseplay.COURSE_2D_DISPLAY_OFF;
-- 2D pda map background -- TODO: MP?
if g_currentMission.hud.ingameMap and g_currentMission.hud.ingameMap.mapOverlay and g_currentMission.hud.ingameMap.mapOverlay.filename then
self.cp.course2dPdaMapOverlay = Overlay:new(g_currentMission.hud.ingameMap.mapOverlay.filename, 0, 0, 1, 1);
self.cp.course2dPdaMapOverlay:setColor(1, 1, 1, CpManager.course2dPdaMapOpacity);
end;
- -- HUD
- courseplay.hud:setupVehicleHud(self);
-
- courseplay:validateCanSwitchMode(self);
---@type SettingsContainer
self.cp.settings = SettingsContainer.createVehicleSpecificSettings(self)
@@ -287,6 +278,12 @@ function courseplay:onLoad(savegame)
---@type SettingsContainer
self.cp.courseGeneratorSettings = SettingsContainer.createCourseGeneratorSettings(self)
+ -- HUD
+ courseplay.hud:setupVehicleHud(self);
+
+ courseplay:validateCanSwitchMode(self);
+
+
courseplay.signs:updateWaypointSigns(self);
courseplay:setAIDriver(self, self.cp.mode)
@@ -303,8 +300,6 @@ function courseplay:onLeaveVehicle()
courseplay:setMouseCursor(self, false);
courseEditor:reset()
end
- ---Update mouse action event texts
- CpManager:updateMouseInputText()
--hide visual i3D waypoint signs when not in vehicle
courseplay.signs:setSignsVisibility(self, true);
end
@@ -319,8 +314,6 @@ function courseplay:onEnterVehicle()
if self.cp.mouseCursorActive then
courseplay:setMouseCursor(self, true);
end;
- ---Update mouse action event texts
- CpManager:updateMouseInputText()
--show visual i3D waypoint signs only when in vehicle
courseplay.signs:setSignsVisibility(self);
end
@@ -372,7 +365,7 @@ function courseplay:onDraw()
self.cp.hudBroken = true
end
- if self.cp.drawCourseMode == courseplay.COURSE_2D_DISPLAY_2DONLY or self.cp.drawCourseMode == courseplay.COURSE_2D_DISPLAY_BOTH then
+ if self.cp.settings.courseDrawMode:isCourseMapVisible() then
courseplay:drawCourse2D(self, false);
end;
end; --END draw()
@@ -507,7 +500,7 @@ function courseplay:onUpdate(dt)
end
- if self.cp.drawCourseMode == courseplay.COURSE_2D_DISPLAY_DBGONLY or self.cp.drawCourseMode == courseplay.COURSE_2D_DISPLAY_BOTH then
+ if self.cp.settings.courseDrawMode:isCourseVisible() then
courseplay:drawWaypointsLines(self);
end;
@@ -518,17 +511,11 @@ function courseplay:onUpdate(dt)
-- we are in drive mode and single player /MP server
if self.cp.isDriving and g_server ~= nil then
- for refIdx,_ in pairs(CpManager.globalInfoText.msgReference) do
- self.cp.hasSetGlobalInfoTextThisLoop[refIdx] = false;
- end;
-
+
local status, err = xpcall(self.cp.driver.update, function(err) printCallstack(); return err end, self.cp.driver, dt)
- for refIdx,_ in pairs(self.cp.activeGlobalInfoTexts) do
- if not self.cp.hasSetGlobalInfoTextThisLoop[refIdx] then
- CpManager:setGlobalInfoText(self, refIdx, true); --force remove
- end;
- end;
+ --- Resets all global info texts that were not called in this update loop.
+ g_globalInfoTextHandler:resetInactiveInfoTextsForVehicle(self)
if not status then
courseplay.infoVehicle(self, 'Exception, stopping Courseplay driver, %s', tostring(err))
@@ -605,13 +592,10 @@ end;
function courseplay:onPreDelete()
---Delete map hotspot and all global info texts leftovers.
- CpMapHotSpot.deleteMapHotSpot(self)
+ CpMapHotSpot.deleteMapHotSpot(self)
if g_server ~= nil then
- for refIdx,_ in pairs(CpManager.globalInfoText.msgReference) do
- if self.cp.activeGlobalInfoTexts[refIdx] ~= nil then
- CpManager:setGlobalInfoText(self, refIdx, true)
- end
- end
+ --- Removes this vehicle form the global info texts handler.
+ g_globalInfoTextHandler:removeVehicle(self)
end
end
@@ -1318,11 +1302,7 @@ function courseplay.onStopCpAIDriver(vehicle, reason, noEventSend)
--remove any global info texts
if g_server ~= nil then
- for refIdx,_ in pairs(CpManager.globalInfoText.msgReference) do
- if vehicle.cp.activeGlobalInfoTexts[refIdx] ~= nil then
- CpManager:setGlobalInfoText(vehicle, refIdx, true);
- end;
- end;
+ g_globalInfoTextHandler:resetAllInfoTextsForVehicle(vehicle)
end
--remove from activeCoursePlayers
diff --git a/button.lua b/button.lua
index d03cfa4aa..499c57080 100644
--- a/button.lua
+++ b/button.lua
@@ -75,8 +75,8 @@ function courseplay.button:new(vehicle, hudPage, img, functionToCall, parameter,
self:setSpecialButtonUVs();
end;
- if vehicle.isCourseplayManager then
- table.insert(vehicle[hudPage].buttons, self);
+ if not vehicle.cp then
+ table.insert(vehicle.buttons, self);
else
table.insert(vehicle.cp.buttons[hudPage], self);
end;
@@ -238,8 +238,9 @@ function courseplay.button:handleMouseClick(vehicle)
if self.functionToCall == "showSaveCourseForm" then
vehicle.cp.imWriting = true
end
+ --- Global info text button was pressed, switch to vehicle.
if self.functionToCall == "goToVehicle" then
- courseplay:executeFunction(vehicle, "goToVehicle", parameter)
+ g_globalInfoTextHandler:goToVehicle(parameter)
else
courseplay:debug(string.format("%s: MOUSE_BUTTON_ClICKED: %s(%s)", nameNum(vehicle), tostring(self.functionToCall), tostring(parameter)), courseplay.DBG_HUD);
self:handleInput(vehicle,parameter)
diff --git a/config/InfoTexts.xml b/config/InfoTexts.xml
new file mode 100644
index 000000000..746d79346
--- /dev/null
+++ b/config/InfoTexts.xml
@@ -0,0 +1,64 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/courseplay.lua b/courseplay.lua
index 3d2a75b83..72390fe3b 100644
--- a/courseplay.lua
+++ b/courseplay.lua
@@ -112,6 +112,7 @@ local function initialize()
'AITurn',
'VehicleConfigurations',
'ActionEventsLoader',
+ 'GlobalInfoTextHandler',
'course-generator/geo',
'course-generator/Island',
'course-generator/courseGenerator',
@@ -222,12 +223,6 @@ local function setGlobalData()
courseplay.lights.HEADLIGHT_STREET = 1;
courseplay.lights.HEADLIGHT_FULL = 7;
- -- 2D/debug lines display options
- courseplay.COURSE_2D_DISPLAY_OFF = 0;
- courseplay.COURSE_2D_DISPLAY_2DONLY = 1;
- courseplay.COURSE_2D_DISPLAY_DBGONLY = 2;
- courseplay.COURSE_2D_DISPLAY_BOTH = 3;
-
-- number separators
local langNumData = {
br = { '.', ',' },
@@ -259,23 +254,22 @@ local function setGlobalData()
[1]={name='self.cp.mode',dataFormat='Int'},
[2]={name='self.cp.turnDiameterAuto',dataFormat='Float'},
[3]={name='self.cp.canDrive',dataFormat='Bool'},
- [6]={name='self.cp.drivingDirReverse',dataFormat='Bool'},
- [7]={name='self.cp.fieldEdge.customField.isCreated',dataFormat='Bool'},
- [8]={name='self.cp.fieldEdge.customField.fieldNum',dataFormat='Int'},
- [9]={name='self.cp.fieldEdge.customField.selectedFieldNumExists',dataFormat='Bool'},
- [10]={name='self.cp.fieldEdge.selectedField.fieldNum',dataFormat='Int'},
- [11]={name='self.cp.globalInfoTextLevel',dataFormat='Int'},
- [15]={name='self.cp.isDriving',dataFormat='Bool'},
- [26]={name='self.cp.hud.openWithMouse',dataFormat='Bool'},
- [29]={name='self.cp.workWidth',dataFormat='Float'},
- [20]={name='self.cp.turnDiameterAutoMode',dataFormat='Bool'},
- [21]={name='self.cp.turnDiameter',dataFormat='Float'},
- [22]={name='self.cp.coursePlayerNum',dataFormat='Int'}, --??
- [23]={name='self.cp.laneOffset',dataFormat='Float'},
- [36]={name='self.cp.hud.currentPage',dataFormat='Int'},
- [37]={name='self.cp.waypointIndex',dataFormat='Int'},
- [38]={name='self.cp.isRecording',dataFormat='Bool'},
- [39]={name='self.cp.recordingIsPaused',dataFormat='Bool'},
+ [4]={name='self.cp.drivingDirReverse',dataFormat='Bool'},
+ [5]={name='self.cp.fieldEdge.customField.isCreated',dataFormat='Bool'},
+ [6]={name='self.cp.fieldEdge.customField.fieldNum',dataFormat='Int'},
+ [7]={name='self.cp.fieldEdge.customField.selectedFieldNumExists',dataFormat='Bool'},
+ [8]={name='self.cp.fieldEdge.selectedField.fieldNum',dataFormat='Int'},
+ [9]={name='self.cp.isDriving',dataFormat='Bool'},
+ [10]={name='self.cp.hud.openWithMouse',dataFormat='Bool'},
+ [11]={name='self.cp.workWidth',dataFormat='Float'},
+ [12]={name='self.cp.turnDiameterAutoMode',dataFormat='Bool'},
+ [13]={name='self.cp.turnDiameter',dataFormat='Float'},
+ [14]={name='self.cp.coursePlayerNum',dataFormat='Int'}, --??
+ [15]={name='self.cp.laneOffset',dataFormat='Float'},
+ [16]={name='self.cp.hud.currentPage',dataFormat='Int'},
+ [17]={name='self.cp.waypointIndex',dataFormat='Int'},
+ [18]={name='self.cp.isRecording',dataFormat='Bool'},
+ [19]={name='self.cp.recordingIsPaused',dataFormat='Bool'},
}
courseplay.globalSettings = SettingsContainer.createGlobalSettings()
diff --git a/hud.lua b/hud.lua
index 785f64ee0..efef6b83d 100644
--- a/hud.lua
+++ b/hud.lua
@@ -563,15 +563,9 @@ function courseplay.hud:renderHud(vehicle)
-- 2D/DEBUG LINE BUTTON MODE
- if vehicle.cp.drawCourseMode ~= courseplay.COURSE_2D_DISPLAY_OFF then
- local txt;
- if vehicle.cp.drawCourseMode == courseplay.COURSE_2D_DISPLAY_2DONLY then
- txt = '2D';
- elseif vehicle.cp.drawCourseMode == courseplay.COURSE_2D_DISPLAY_DBGONLY then
- txt = '\nDBG';
- else
- txt = '2D\nDBG';
- end;
+ local courseDrawModeSetting = vehicle.cp.settings.courseDrawMode
+ if not courseDrawModeSetting:isDeactivated() then
+ local txt = courseDrawModeSetting:getText()
courseplay:setFontSettings('white', true);
renderText(vehicle.cp.hud.changeDrawCourseModeButton.x + vehicle.cp.hud.changeDrawCourseModeButton.width * 0.5, self.topIconsY + self.fontSizes.version * 1.25, self.fontSizes.version, txt);
courseplay:setFontSettings('white', false);
@@ -1215,7 +1209,7 @@ function courseplay.hud:updatePageContent(vehicle, page)
else
self:showShowWaypointsButtons(vehicle, false)
end
-
+ vehicle.cp.hud.changeDrawCourseModeButton:setActive(not vehicle.cp.settings.courseDrawMode:isDeactivated())
-- make sure AutoDrive mode has all options currently available for the vehicle
vehicle.cp.settings.autoDriveMode:update()
self:setReloadPageOrder(vehicle, page, forceUpdate);
@@ -1376,7 +1370,7 @@ function courseplay.hud:setupVehicleHud(vehicle)
vehicle.cp.hud.saveCourseButton = courseplay.button:new(vehicle, 'global', { 'iconSprite.png', 'save' }, 'showSaveCourseForm', 'course', topIconsX[3], self.topIconsY, wMiddle, hMiddle, nil, nil, false, false, false, courseplay:loc('COURSEPLAY_SAVE_CURRENT_COURSE'));
vehicle.cp.hud.clearCurrentCourseButton = courseplay.button:new(vehicle, 'global', { 'iconSprite.png', 'courseClear' }, 'clearCurrentLoadedCourse', nil, topIconsX[0], self.topIconsY, wMiddle, hMiddle, nil, nil, false, false, false, courseplay:loc('COURSEPLAY_CLEAR_COURSE'));
- vehicle.cp.hud.changeDrawCourseModeButton = courseplay.button:new(vehicle, 'global', { 'iconSprite.png', 'eye' }, 'changeDrawCourseMode', 1, self.col1posX, self.topIconsY, wMiddle, hMiddle, nil, -1, false, false, true);
+ vehicle.cp.hud.changeDrawCourseModeButton = courseplay.button:new(vehicle, 'global', { 'iconSprite.png', 'eye' }, 'changeByX', 1, self.col1posX, self.topIconsY, wMiddle, hMiddle, nil, -1, false, false, true):setSetting(vehicle.cp.settings.courseDrawMode)
self:setupCpModeButtons(vehicle)
self:setupRecordingButtons(vehicle)
self:setupCoursePageButtons(vehicle,2)
diff --git a/input.lua b/input.lua
index 5d19e2a80..a673dc0ac 100644
--- a/input.lua
+++ b/input.lua
@@ -124,7 +124,7 @@ function courseplay:onMouseEvent(posX, posY, isDown, isUp, mouseButton)
-- ##################################################
-- 2D COURSE WINDOW: DRAG + DROP MOVE
- if vehicle.cp.course2dDrawData and (vehicle.cp.drawCourseMode == courseplay.COURSE_2D_DISPLAY_2DONLY or vehicle.cp.drawCourseMode == courseplay.COURSE_2D_DISPLAY_BOTH) then
+ if vehicle.cp.course2dDrawData and vehicle.cp.settings.courseDrawMode:isCourseVisible() then
local plot = CpManager.course2dPlotField;
if isDown and mouseButton == courseplay.inputBindings.mouse.primaryButtonId and vehicle.cp.mouseCursorActive and vehicle:getIsEntered() and courseplay:mouseIsInArea(posX, posY, plot.x, plot.x + plot.width, plot.y, plot.y + plot.height) then
CpManager.course2dDragDropMouseDown = { posX, posY };
@@ -162,11 +162,7 @@ end
function courseplay:executeFunction(self, func, value, page)
courseplay:debug("executeFunction: function: " .. func .. " value: " .. tostring(value) .. " page: " .. tostring(page), courseplay.DBG_MULTIPLAYER)
--legancy code
- if func == "setMPGlobalInfoText" then
- CpManager:setGlobalInfoText(self, value, page)
- courseplay:debug(" setting infoText: "..value..", force remove: "..tostring(page),courseplay.DBG_MULTIPLAYER)
- return
- elseif StringUtil.startsWith(func,"self") or StringUtil.startsWith(func,"courseplay") then
+ if StringUtil.startsWith(func,"self") or StringUtil.startsWith(func,"courseplay") then
courseplay:debug(" setting value",courseplay.DBG_MULTIPLAYER)
courseplay:setVarValueFromString(self, func, value)
--courseplay:debug(" "..tostring(func)..": "..tostring(value),courseplay.DBG_MULTIPLAYER)
diff --git a/settings.lua b/settings.lua
index f63449090..05d961d63 100644
--- a/settings.lua
+++ b/settings.lua
@@ -722,13 +722,7 @@ function courseplay:changeDebugChannelSection(vehicle, changeBy)
--courseplay.buttons:setActiveEnabled(vehicle, 'debug');
end;
-function courseplay:goToVehicle(curVehicle, targetVehicle)
- -- print(string.format("%s: goToVehicle(): targetVehicle=%q", nameNum(curVehicle), nameNum(targetVehicle)));
- g_client:getServerConnection():sendEvent(VehicleEnterRequestEvent:new(targetVehicle, g_currentMission.missionInfo.playerStyle, g_currentMission.player.farmId));
- g_currentMission.isPlayerFrozen = false;
- CpManager.playerOnFootMouseEnabled = false;
- g_inputBinding:setShowMouseCursor(targetVehicle.cp.mouseCursorActive);
-end;
+
--FIELD EDGE PATHS
function courseplay:createFieldEdgeButtons(vehicle)
@@ -3806,7 +3800,7 @@ end
--- The wait time setting can be incremented by 15 seconds up to max: 60min.
---
----@class WaitTimeSetting
+---@class WaitTimeSetting : IntSetting
WaitTimeSetting = CpObject(IntSetting)
function WaitTimeSetting:init(vehicle)
local max = 3600 --- 60 min
@@ -3840,6 +3834,43 @@ function WaitTimeSetting:changeByX(x)
IntSetting.changeByX(self,x)
end
+--- @class CourseDrawModeSetting : SettingList
+CourseDrawModeSetting = CpObject(SettingList)
+-- 2D/debug lines display options
+CourseDrawModeSetting.COURSE_2D_DISPLAY_OFF = 0;
+CourseDrawModeSetting.COURSE_2D_DISPLAY_2DONLY = 1;
+CourseDrawModeSetting.COURSE_2D_DISPLAY_DBGONLY = 2;
+CourseDrawModeSetting.COURSE_2D_DISPLAY_BOTH = 3;
+function CourseDrawModeSetting:init(vehicle)
+ local values = {
+ self.COURSE_2D_DISPLAY_OFF,
+ self.COURSE_2D_DISPLAY_2DONLY,
+ self.COURSE_2D_DISPLAY_DBGONLY,
+ self.COURSE_2D_DISPLAY_BOTH
+ }
+ local texts = {
+ "",
+ "2D",
+ "\nDBG",
+ "2D\nDBG"
+ }
+ SettingList.init(self,"courseDrawMode","","",vehicle,values,texts)
+ self:set(self.COURSE_2D_DISPLAY_OFF)
+ self.syncValue = false
+end
+
+function CourseDrawModeSetting:isDeactivated()
+ return self:get() == self.COURSE_2D_DISPLAY_OFF
+end
+
+function CourseDrawModeSetting:isCourseMapVisible()
+ return self:get() == self.COURSE_2D_DISPLAY_2DONLY or self:get() == self.COURSE_2D_DISPLAY_BOTH
+end
+
+function CourseDrawModeSetting:isCourseVisible()
+ return self:get() == self.COURSE_2D_DISPLAY_DBGONLY or self:get() == self.COURSE_2D_DISPLAY_BOTH
+end
+
--[[
---@class SearchCombineAutomaticallySetting : BooleanSetting
SearchCombineAutomaticallySetting = CpObject(BooleanSetting)
@@ -4035,6 +4066,7 @@ function SettingsContainer.createVehicleSpecificSettings(vehicle)
container:addSetting(WaitTimeSetting, vehicle)
container:addSetting(MixerWagonAIDriver_SiloSelectedFillTypeSetting, vehicle)
container:addSetting(MixerWagonToolPositionsSetting, vehicle)
+ container:addSetting(CourseDrawModeSetting,vehicle)
return container
end
diff --git a/start_stop.lua b/start_stop.lua
index 405c837f3..9af570967 100644
--- a/start_stop.lua
+++ b/start_stop.lua
@@ -120,10 +120,7 @@ function courseplay:stop(self)
courseplay:setEngineState(self, true);
self.cp.saveFuel = false;
end
- if courseplay:getCustomTimerExists(self,'fuelSaveTimer') then
- --print("reset existing timer")
- courseplay:resetCustomTimer(self,'fuelSaveTimer',true)
- end
+
if self.cp.directionNodeToTurnNodeLength ~= nil then
self.cp.directionNodeToTurnNodeLength = nil