diff --git a/betterContracts.lua b/betterContracts.lua index cca1750..1e4e320 100644 --- a/betterContracts.lua +++ b/betterContracts.lua @@ -5,455 +5,468 @@ -- Author: Royal-Modding / Mmtrx -- Changelog: -- v1.0.0.0 19.10.2020 initial by Royal-Modding --- v1.1.0.0 12.04.2021 release candidate RC-2 --- v1.1.0.3 24.04.2021 (Mmtrx) gui enhancements: addtl details, sort buttons --- v1.1.0.4 07.07.2021 (Mmtrx) add user-defined missionVehicles.xml, allow missions with no vehicles --- v1.2.0.0 18.01.2022 (Mmtrx) adapt for FS22 --- v1.2.0.0.rc 22.01.2022 (Mmtrx) release candidate. Gui optics in blue --- v1.2.0.1.rc 30.01.2022 (Mmtrx) enabled MP --- v1.2.1.0 09.02.2022 (Mmtrx) support for FS22_SuppyTransportontracts by GtX +-- v1.1.0.0 12.04.2021 (Mmtrx) release candidate RC-2 +-- v1.1.0.3 24.04.2021 gui enhancements: addtl details, sort buttons +-- v1.1.0.4 07.07.2021 add user-defined missionVehicles.xml, allow missions with no vehicles +-- v1.2.0.0 18.01.2022 adapt for FS22 +-- v1.2.0.0.rc 22.01.2022 release candidate. Gui optics in blue +-- v1.2.0.1.rc 30.01.2022 enabled MP +-- v1.2.1.0 09.02.2022 support for FS22_SupplyTransportContracts by GtX +-- v1.2.2.0 30.03.2022 recognize conflict FS22_Contracts_Plus, adjust harvest keep formulas to FS22 1.3.1 +-- details for transport missions --======================================================================================================= InitRoyalUtility(Utils.getFilename("lib/utility/", g_currentModDirectory)) InitRoyalMod(Utils.getFilename("lib/rmod/", g_currentModDirectory)) SC = { - FERTILIZER = 1, -- prices index - LIQUIDFERT = 2, - HERBICIDE = 3, - SEEDS = 4, - -- my mission cats: - HARVEST = 1, - SPREAD = 2, - SIMPLE = 3, - BALING = 4, - TRANSP = 5, - SUPPLY = 6, - -- Gui controls: - CONTROLS = { - npcbox = "npcbox", - sortbox = "sortbox", - layout = "layout", - filltype = "filltype", - widhei = "widhei", - ppmin = "ppmin", - line3 = "line3", - line4a = "line4a", - line4b = "line4b", - line5 = "line5", - line6 = "line6", - field = "field", - dimen = "dimen", - etime = "etime", - valu4a = "valu4a", - valu4b = "valu4b", - price = "price", - valu6 = "valu6", - valu7 = "valu7", - sortcat = "sortcat", - sortprof = "sortprof", - sortpmin = "sortpmin", - helpsort = "helpsort" - } + FERTILIZER = 1, -- prices index + LIQUIDFERT = 2, + HERBICIDE = 3, + SEEDS = 4, + -- my mission cats: + HARVEST = 1, + SPREAD = 2, + SIMPLE = 3, + BALING = 4, + TRANSP = 5, + SUPPLY = 6, + -- Gui controls: + CONTROLS = { + npcbox = "npcbox", + sortbox = "sortbox", + layout = "layout", + filltype = "filltype", + widhei = "widhei", + ppmin = "ppmin", + line3 = "line3", + line4a = "line4a", + line4b = "line4b", + line5 = "line5", + line6 = "line6", + field = "field", + dimen = "dimen", + etime = "etime", + valu4a = "valu4a", + valu4b = "valu4b", + price = "price", + valu6 = "valu6", + valu7 = "valu7", + sort = "sort", + sortcat = "sortcat", + sortprof = "sortprof", + sortpmin = "sortpmin", + helpsort = "helpsort" + } } ---@class BetterContracts : RoyalMod BetterContracts = RoyalMod.new(false, false) --params bool debug, bool sync function debugPrint(text, ...) - if BetterContracts.debug then - Logging.info(text,...) - end + if BetterContracts.debug then + Logging.info(text,...) + end end function BetterContracts:initialize() - self.modSettings= string.sub(g_modsDirectory,1,-3) .. "Settings/" - -- check for debug switch in modSettings/ - if not self.debug and - fileExists(self.modSettings.."BetterContracts.debug") then - self.debug = true - end - debugPrint("[%s] initialize(): %s", self.name,self.initialized) - if self.initialized ~= nil then return end -- run only once - g_missionManager.missionMapNumChannels = 6 - self.missionUpdTimeout = 15000 - self.missionUpdTimer = 0 -- will also update on frame open of contracts page - self.turnTime = 5.0 -- estimated seconds per turn at end of each lane - self.events = {} - self.initialized = false - -- Amazon ZA-TS3200, Hardi Mega, Pöttr TerraC6F, Lemken Azur 9, mission, Lemken Titan18 - -- default:spreader, sprayer, sower, planter, empty, harvest, plow, mow - self.SPEEDLIMS = {15, 12, 15, 15, 0, 10, 12, 20} - self.WORKWIDTH = {42, 24, 6, 6, 0, 9, 4.9, 9} - --[[ contract types: - 1 mow/ bale - 2 plow - 3 cultivate - 4 sow - 5 harvest - 6 weed - 7 spray - 8 fertilize - 9 transport - 10 supplyTransport (Mod) - ]] - self.typeToCat = {4, 3, 3, 2, 1, 3, 2, 2, 5, 6} -- mission.type to self category: harvest, spread, simple, mow, transport - self.harvest = {} -- harvest missions 1 - self.spread = {} -- sow, spray, fertilize 2 - self.simple = {} -- plow, cultivate, weed 3 - self.baling = {} -- mow/ bale 4 - self.transp = {} -- transport 5 - self.supply = {} -- supplyTransport mod 6 - self.IdToCont = {} -- to find a contract from its mission id - self.fieldToMission = {} -- to find a contract from its field number - self.catHarvest = "BEETHARVESTING BEETVEHICLES CORNHEADERS COTTONVEHICLES CUTTERS POTATOHARVESTING POTATOVEHICLES SUGARCANEHARVESTING SUGARCANEVEHICLES" - self.catSpread = "fertilizerspreaders seeders planters sprayers sprayervehicles slurrytanks manurespreaders" - self.catSimple = "CULTIVATORS DISCHARROWS PLOWS POWERHARROWS SUBSOILERS WEEDERS" - self.isOn = false - self.numCont = 0 -- # of contracts in our tables - self.my = {} -- will hold my gui element adresses - self.sort = 0 -- sorted status: 1 cat, 2 prof, 3 permin - self.lastSort = 0 -- last sorted status - self.buttons = { - {"sortcat", g_i18n:getText("SC_sortCat")}, -- {button id, help text} - {"sortprof", g_i18n:getText("SC_sortProf")}, - {"sortpmin", g_i18n:getText("SC_sortpMin")} - } - if g_modIsLoaded["FS22_RefreshContracts"] then - self.needsRefreshContractsConflictsPrevention = true - end - if g_modIsLoaded["FS22_SupplyTransportContracts"] then - self.supplyTransport = true - end - -- to load own mission vehicles: - Utility.overwrittenFunction(MissionManager, "loadMissionVehicles", BetterContracts.loadMissionVehicles) - -- fix AbstractMission: - Utility.overwrittenFunction(AbstractMission, "new", abstractMissionNew) + self.modSettings= string.sub(g_modsDirectory,1,-3) .. "Settings/" + -- check for debug switch in modSettings/ + if not self.debug and + fileExists(self.modSettings.."BetterContracts.debug") then + self.debug = true + end + debugPrint("[%s] initialize(): %s", self.name,self.initialized) + if self.initialized ~= nil then return end -- run only once + g_missionManager.missionMapNumChannels = 6 + self.missionUpdTimeout = 15000 + self.missionUpdTimer = 0 -- will also update on frame open of contracts page + self.turnTime = 5.0 -- estimated seconds per turn at end of each lane + self.events = {} + self.initialized = false + -- Amazon ZA-TS3200, Hardi Mega, Pöttr TerraC6F, Lemken Azur 9, mission, Lemken Titan18 + -- default:spreader, sprayer, sower, planter, empty, harvest, plow, mow + self.SPEEDLIMS = {15, 12, 15, 15, 0, 10, 12, 20} + self.WORKWIDTH = {42, 24, 6, 6, 0, 9, 4.9, 9} + --[[ contract types: + 1 mow/ bale + 2 plow + 3 cultivate + 4 sow + 5 harvest + 6 weed + 7 spray + 8 fertilize + 9 transport + 10 supplyTransport (Mod) + ]] + self.typeToCat = {4, 3, 3, 2, 1, 3, 2, 2, 5, 6} -- mission.type to self category: harvest, spread, simple, mow, transport + self.harvest = {} -- harvest missions 1 + self.spread = {} -- sow, spray, fertilize 2 + self.simple = {} -- plow, cultivate, weed 3 + self.baling = {} -- mow/ bale 4 + self.transp = {} -- transport 5 + self.supply = {} -- supplyTransport mod 6 + self.IdToCont = {} -- to find a contract from its mission id + self.fieldToMission = {} -- to find a contract from its field number + self.catHarvest = "BEETHARVESTING BEETVEHICLES CORNHEADERS COTTONVEHICLES CUTTERS POTATOHARVESTING POTATOVEHICLES SUGARCANEHARVESTING SUGARCANEVEHICLES" + self.catSpread = "fertilizerspreaders seeders planters sprayers sprayervehicles slurrytanks manurespreaders" + self.catSimple = "CULTIVATORS DISCHARROWS PLOWS POWERHARROWS SUBSOILERS WEEDERS" + self.isOn = false + self.numCont = 0 -- # of contracts in our tables + self.my = {} -- will hold my gui element adresses + self.sort = 0 -- sorted status: 1 cat, 2 prof, 3 permin + self.lastSort = 0 -- last sorted status + self.buttons = { + {"sortcat", g_i18n:getText("SC_sortCat")}, -- {button id, help text} + {"sortprof", g_i18n:getText("SC_sortProf")}, + {"sortpmin", g_i18n:getText("SC_sortpMin")} + } + local mods = {"FS22_RefreshContracts","FS22_Contracts_Plus"} + if g_modIsLoaded["FS22_RefreshContracts"] then + self.needsRefreshContractsConflictsPrevention = true + end + if g_modIsLoaded["FS22_Contracts_Plus"] then + self.preventContractsPlus = true + end + if g_modIsLoaded["FS22_SupplyTransportContracts"] then + self.supplyTransport = true + end + -- to load own mission vehicles: + Utility.overwrittenFunction(MissionManager, "loadMissionVehicles", BetterContracts.loadMissionVehicles) + -- fix AbstractMission: + Utility.overwrittenFunction(AbstractMission, "new", abstractMissionNew) - -- get addtnl mission vales from server: - Utility.appendedFunction(HarvestMission, "writeStream", BetterContracts.writeStream) - Utility.appendedFunction(HarvestMission, "readStream", BetterContracts.readStream) - Utility.appendedFunction(BaleMission, "writeStream", BetterContracts.writeStream) - Utility.appendedFunction(BaleMission, "readStream", BetterContracts.readStream) - Utility.appendedFunction(AbstractMission, "writeUpdateStream", BetterContracts.writeUpdateStream) - Utility.appendedFunction(AbstractMission, "readUpdateStream", BetterContracts.readUpdateStream) - -- functions for ingame menu contracts frame: - InGameMenuContractsFrame.onFrameOpen = Utils.overwrittenFunction(InGameMenuContractsFrame.onFrameOpen, onFrameOpen) - InGameMenuContractsFrame.onFrameClose = Utils.appendedFunction(InGameMenuContractsFrame.onFrameClose, onFrameClose) - InGameMenuContractsFrame.updateFarmersBox = Utils.appendedFunction(InGameMenuContractsFrame.updateFarmersBox, updateFarmersBox) - InGameMenuContractsFrame.populateCellForItemInSection = Utils.appendedFunction(InGameMenuContractsFrame.populateCellForItemInSection, populateCell) - InGameMenuContractsFrame.updateList = Utils.prependedFunction(InGameMenuContractsFrame.updateList, updateList) - InGameMenuContractsFrame.sortList = Utils.overwrittenFunction(InGameMenuContractsFrame.sortList, sortList) - -- to allow multiple missions: - MissionManager.hasFarmReachedMissionLimit = - Utils.overwrittenFunction(nil, - function() return false end - ) - if self.debug then - g_showDevelopmentWarnings = true - addConsoleCommand("printBetterContracts", "Print detail stats for all available missions.", "consoleCommandPrint", self) - addConsoleCommand("restartGame", 'Restart my savegame [savegameId]', 'restartGame', self) - addConsoleCommand("gsFieldGenerateMission", "Force generating a new mission for given field", "consoleGenerateFieldMission", g_missionManager) - addConsoleCommand("gsMissionLoadAllVehicles", "Loading and unloading all field mission vehicles", "consoleLoadAllFieldMissionVehicles", g_missionManager) - addConsoleCommand("gsMissionHarvestField", "Harvest a field and print the liters", "consoleHarvestField", g_missionManager) - addConsoleCommand("gsMissionTestHarvests", "Run an expansive tests for harvest missions", "consoleHarvestTests", g_missionManager) - addConsoleCommand("gsFieldSetFruit", "Sets a given fruit to field", "consoleCommandSetFieldFruit", g_fieldManager) - addConsoleCommand("gsFieldSetFruitAll", "Sets a given fruit to all fields", "consoleCommandSetFieldFruitAll", g_fieldManager) - addConsoleCommand("gsFieldSetGround", "Sets a given fruit to field", "consoleCommandSetFieldGround", g_fieldManager) - addConsoleCommand("gsFieldSetGroundAll", "Sets a given fruit to allfield", "consoleCommandSetFieldGroundAll", g_fieldManager) - end + -- get addtnl mission values from server: + Utility.appendedFunction(HarvestMission, "writeStream", BetterContracts.writeStream) + Utility.appendedFunction(HarvestMission, "readStream", BetterContracts.readStream) + Utility.appendedFunction(BaleMission, "writeStream", BetterContracts.writeStream) + Utility.appendedFunction(BaleMission, "readStream", BetterContracts.readStream) + Utility.appendedFunction(AbstractMission, "writeUpdateStream", BetterContracts.writeUpdateStream) + Utility.appendedFunction(AbstractMission, "readUpdateStream", BetterContracts.readUpdateStream) + -- functions for ingame menu contracts frame: + InGameMenuContractsFrame.onFrameOpen = Utils.overwrittenFunction(InGameMenuContractsFrame.onFrameOpen, onFrameOpen) + InGameMenuContractsFrame.onFrameClose = Utils.appendedFunction(InGameMenuContractsFrame.onFrameClose, onFrameClose) + InGameMenuContractsFrame.updateFarmersBox = Utils.appendedFunction(InGameMenuContractsFrame.updateFarmersBox, updateFarmersBox) + InGameMenuContractsFrame.populateCellForItemInSection = Utils.appendedFunction(InGameMenuContractsFrame.populateCellForItemInSection, populateCell) + InGameMenuContractsFrame.updateList = Utils.prependedFunction(InGameMenuContractsFrame.updateList, updateList) + InGameMenuContractsFrame.sortList = Utils.overwrittenFunction(InGameMenuContractsFrame.sortList, sortList) + -- to allow multiple missions: + MissionManager.hasFarmReachedMissionLimit = + Utils.overwrittenFunction(nil, + function() return false end + ) + if self.debug then + addConsoleCommand("printBetterContracts", "Print detail stats for all available missions.", "consoleCommandPrint", self) + addConsoleCommand("restartGame", 'Restart my savegame [savegameId]', 'restartGame', self) + addConsoleCommand("gsFieldGenerateMission", "Force generating a new mission for given field", "consoleGenerateFieldMission", g_missionManager) + addConsoleCommand("gsMissionLoadAllVehicles", "Loading and unloading all field mission vehicles", "consoleLoadAllFieldMissionVehicles", g_missionManager) + addConsoleCommand("gsMissionHarvestField", "Harvest a field and print the liters", "consoleHarvestField", g_missionManager) + addConsoleCommand("gsMissionTestHarvests", "Run an expansive tests for harvest missions", "consoleHarvestTests", g_missionManager) + end end function BetterContracts:onMissionInitialize(baseDirectory, missionCollaborators) - MissionManager.AI_PRICE_MULTIPLIER = 1.5 - MissionManager.MISSION_GENERATION_INTERVAL = 3600000 -- every 1 game hour + MissionManager.AI_PRICE_MULTIPLIER = 1.5 + MissionManager.MISSION_GENERATION_INTERVAL = 3600000 -- every 1 game hour end function BetterContracts:onSetMissionInfo(missionInfo, missionDynamicInfo) - Utility.overwrittenFunction(g_currentMission.inGameMenu, "onClickMenuExtra1", onClickMenuExtra1) - Utility.overwrittenFunction(g_currentMission.inGameMenu, "onClickMenuExtra2", onClickMenuExtra2) + Utility.overwrittenFunction(g_currentMission.inGameMenu, "onClickMenuExtra1", onClickMenuExtra1) + Utility.overwrittenFunction(g_currentMission.inGameMenu, "onClickMenuExtra2", onClickMenuExtra2) end function BetterContracts:onPostLoadMap(mapNode, mapFile) - -- adjust max missions - local fieldsAmount = TableUtility.count(g_fieldManager.fields) - local adjustedFieldsAmount = math.max(fieldsAmount, 45) - MissionManager.MAX_MISSIONS = math.min(120, math.ceil(adjustedFieldsAmount * 0.60)) -- max missions = 60% of fields amount (minimum 45 fields) max 120 - MissionManager.MAX_TRANSPORT_MISSIONS = math.max(math.ceil(MissionManager.MAX_MISSIONS / 15), 2) -- max transport missions is 1/15 of maximum missions but not less then 2 - MissionManager.MAX_MISSIONS = MissionManager.MAX_MISSIONS + MissionManager.MAX_TRANSPORT_MISSIONS -- add max transport missions to max missions - MissionManager.MAX_MISSIONS_PER_GENERATION = math.min(MissionManager.MAX_MISSIONS / 5, 30) -- max missions per generation = max mission / 5 but not more then 30 - MissionManager.MAX_TRIES_PER_GENERATION = math.ceil(MissionManager.MAX_MISSIONS_PER_GENERATION * 1.5) -- max tries per generation 50% more then max missions per generation - debugPrint("[%s] Fields amount %s (%s)", self.name, fieldsAmount, adjustedFieldsAmount) - debugPrint("[%s] MAX_MISSIONS set to %s", self.name, MissionManager.MAX_MISSIONS) - debugPrint("[%s] MAX_TRANSPORT_MISSIONS set to %s", self.name, MissionManager.MAX_TRANSPORT_MISSIONS) - debugPrint("[%s] MAX_MISSIONS_PER_GENERATION set to %s", self.name, MissionManager.MAX_MISSIONS_PER_GENERATION) - debugPrint("[%s] MAX_TRIES_PER_GENERATION set to %s", self.name, MissionManager.MAX_TRIES_PER_GENERATION) + -- adjust max missions + local fieldsAmount = TableUtility.count(g_fieldManager.fields) + local adjustedFieldsAmount = math.max(fieldsAmount, 45) + MissionManager.MAX_MISSIONS = math.min(120, math.ceil(adjustedFieldsAmount * 0.60)) -- max missions = 60% of fields amount (minimum 45 fields) max 120 + MissionManager.MAX_TRANSPORT_MISSIONS = math.max(math.ceil(MissionManager.MAX_MISSIONS / 15), 2) -- max transport missions is 1/15 of maximum missions but not less then 2 + MissionManager.MAX_MISSIONS = MissionManager.MAX_MISSIONS + MissionManager.MAX_TRANSPORT_MISSIONS -- add max transport missions to max missions + MissionManager.MAX_MISSIONS_PER_GENERATION = math.min(MissionManager.MAX_MISSIONS / 5, 30) -- max missions per generation = max mission / 5 but not more then 30 + MissionManager.MAX_TRIES_PER_GENERATION = math.ceil(MissionManager.MAX_MISSIONS_PER_GENERATION * 1.5) -- max tries per generation 50% more then max missions per generation + debugPrint("[%s] Fields amount %s (%s)", self.name, fieldsAmount, adjustedFieldsAmount) + debugPrint("[%s] MAX_MISSIONS set to %s", self.name, MissionManager.MAX_MISSIONS) + debugPrint("[%s] MAX_TRANSPORT_MISSIONS set to %s", self.name, MissionManager.MAX_TRANSPORT_MISSIONS) + debugPrint("[%s] MAX_MISSIONS_PER_GENERATION set to %s", self.name, MissionManager.MAX_MISSIONS_PER_GENERATION) + debugPrint("[%s] MAX_TRIES_PER_GENERATION set to %s", self.name, MissionManager.MAX_TRIES_PER_GENERATION) - -- initialize constants depending on game manager instances - self.ft = g_fillTypeManager.fillTypes - self.prices = { - -- storeprices per 1000 l - g_storeManager.xmlFilenameToItem["data/objects/bigbagpallet/fertilizer/bigbagpallet_fertilizer.xml"].price, - g_storeManager.xmlFilenameToItem["data/objects/pallets/liquidtank/fertilizertank.xml"].price / 2, - g_storeManager.xmlFilenameToItem["data/objects/pallets/liquidtank/herbicidetank.xml"].price / 2, - g_storeManager.xmlFilenameToItem["data/objects/bigbagpallet/seeds/bigbagpallet_seeds.xml"].price - } - self.sprUse = { - g_sprayTypeManager.sprayTypes[SprayType.FERTILIZER].litersPerSecond, - g_sprayTypeManager.sprayTypes[SprayType.LIQUIDFERTILIZER].litersPerSecond, - g_sprayTypeManager.sprayTypes[SprayType.HERBICIDE].litersPerSecond - } - self.mtype = { - FERTILIZE = g_missionManager:getMissionType("fertilize").typeId, - SOW = g_missionManager:getMissionType("sow").typeId, - SPRAY = g_missionManager:getMissionType("spray").typeId - } - self.gameMenu = g_currentMission.inGameMenu - self.frCon = self.gameMenu.pageContracts + -- initialize constants depending on game manager instances + self.ft = g_fillTypeManager.fillTypes + self.prices = { + -- storeprices per 1000 l + g_storeManager.xmlFilenameToItem["data/objects/bigbagpallet/fertilizer/bigbagpallet_fertilizer.xml"].price, + g_storeManager.xmlFilenameToItem["data/objects/pallets/liquidtank/fertilizertank.xml"].price / 2, + g_storeManager.xmlFilenameToItem["data/objects/pallets/liquidtank/herbicidetank.xml"].price / 2, + g_storeManager.xmlFilenameToItem["data/objects/bigbagpallet/seeds/bigbagpallet_seeds.xml"].price + } + self.sprUse = { + g_sprayTypeManager.sprayTypes[SprayType.FERTILIZER].litersPerSecond, + g_sprayTypeManager.sprayTypes[SprayType.LIQUIDFERTILIZER].litersPerSecond, + g_sprayTypeManager.sprayTypes[SprayType.HERBICIDE].litersPerSecond + } + self.mtype = { + FERTILIZE = g_missionManager:getMissionType("fertilize").typeId, + SOW = g_missionManager:getMissionType("sow").typeId, + SPRAY = g_missionManager:getMissionType("spray").typeId + } + self.gameMenu = g_currentMission.inGameMenu + self.frCon = self.gameMenu.pageContracts - -- check mission types - for i = #self.typeToCat+1, g_missionManager.nextMissionTypeId -1 do - Logging.warning("[%s] ignoring new mission type %s (id %s)", self.name, - g_missionManager.missionTypes[i].name, i) - end - -- load my gui xmls - if not self:loadGUI(true, self.directory .. "gui/") then - Logging.warning("'%s.Gui' failed to load! Supporting files are missing.", self.name) - else - debugPrint("-------- gui loaded -----------") - end + -- check mission types + for i = #self.typeToCat+1, g_missionManager.nextMissionTypeId -1 do + Logging.warning("[%s] ignoring new mission type %s (id %s)", self.name, + g_missionManager.missionTypes[i].name, i) + end + -- load my gui xmls + if not self:loadGUI(true, self.directory .. "gui/") then + Logging.warning("'%s.Gui' failed to load! Supporting files are missing.", self.name) + else + debugPrint("-------- gui loaded -----------") + end - ------------------- setup my display elements ------------------------------------- - -- move farmer picture to right - local fbox = self.frCon.farmerBox - for _,v in ipairs(fbox:getDescendants()) do - if v.id ~= nil and - v.id:sub(1,6) == "farmer" then - v:move(115/1920, 0) - end - end - -- add field "profit" to all listItems - local rewd = self.frCon.contractsList.cellDatabase.autoCell1:getDescendantByName("reward") - local profit = rewd:clone(self.frCon.contractsList.cellDatabase.autoCell1) - profit.name = "profit" - profit:setPosition(-110 / 1920, -12/1080) - --profit:setTextColor(1, 1, 1, 1) - profit.textBold = false - profit:setVisible(false) - -- set controls for npcbox, sortbox and their elements: - for _, name in pairs(SC.CONTROLS) do - self.my[name] = self.frCon.farmerBox:getDescendantById(name) - end - -- set callbacks for our 3 sort buttons - for _, name in ipairs({"sortcat", "sortprof", "sortpmin"}) do - self.my[name].onClickCallback = onClickSortButton - self.my[name].onHighlightCallback = onHighSortButton - self.my[name].onHighlightRemoveCallback = onRemoveSortButton - self.my[name].onFocusCallback = onHighSortButton - self.my[name].onLeaveCallback = onRemoveSortButton - end - -- set static texts - self.my.widhei:setText(g_i18n:getText("SC_widhei")) - self.my.ppmin:setText(g_i18n:getText("SC_profpmin")) + ------------------- setup my display elements ------------------------------------- + -- move farmer picture to right + local fbox = self.frCon.farmerBox + for _,v in ipairs(fbox:getDescendants()) do + if v.id ~= nil and + v.id:sub(1,6) == "farmer" then + v:move(115/1920, 0) + end + end + -- add field "profit" to all listItems + local rewd = self.frCon.contractsList.cellDatabase.autoCell1:getDescendantByName("reward") + local profit = rewd:clone(self.frCon.contractsList.cellDatabase.autoCell1) + profit.name = "profit" + profit:setPosition(-110 / 1920, -12/1080) + --profit:setTextColor(1, 1, 1, 1) + profit.textBold = false + profit:setVisible(false) + -- set controls for npcbox, sortbox and their elements: + for _, name in pairs(SC.CONTROLS) do + self.my[name] = self.frCon.farmerBox:getDescendantById(name) + end + -- set callbacks for our 3 sort buttons + for _, name in ipairs({"sortcat", "sortprof", "sortpmin"}) do + self.my[name].onClickCallback = onClickSortButton + self.my[name].onHighlightCallback = onHighSortButton + self.my[name].onHighlightRemoveCallback = onRemoveSortButton + self.my[name].onFocusCallback = onHighSortButton + self.my[name].onLeaveCallback = onRemoveSortButton + end + -- set static texts: "SORT" + self.my.sort:setText(g_i18n:getText("SC_sort")) - self.my.npcbox:setVisible(false) - self.my.sortbox:setVisible(false) - self.initialized = true + self.my.npcbox:setVisible(false) + self.my.sortbox:setVisible(false) + self.initialized = true end function BetterContracts:onUpdate(dt) - local self = BetterContracts - self.missionUpdTimer = self.missionUpdTimer + dt - if self.missionUpdTimer >= self.missionUpdTimeout then - if self.isOn then self:refresh() end -- only needed when GUI shown - self.missionUpdTimer = 0 - end + local self = BetterContracts + self.missionUpdTimer = self.missionUpdTimer + dt + if self.missionUpdTimer >= self.missionUpdTimeout then + if self.isOn then self:refresh() end -- only needed when GUI shown + self.missionUpdTimer = 0 + end end function BetterContracts:loadGUI(canLoad, guiPath) - if canLoad then - local fname - -- load my gui profiles - fname = guiPath .. "guiProfiles.xml" - if fileExists(fname) then - g_gui:loadProfiles(fname) - else - canLoad = false - end - -- load "SCGui.xml" - fname = guiPath .. "SCGui.xml" - if canLoad and fileExists(fname) then - local xmlFile = loadXMLFile("Temp", fname) - local fbox = self.frCon.farmerBox - g_gui:loadGuiRec(xmlFile, "GUI", fbox, self.frCon) - local layout = fbox:getDescendantById("layout") - layout:invalidateLayout(true) -- adjust sort buttons - fbox:applyScreenAlignment() - fbox:updateAbsolutePosition() - fbox:onGuiSetupFinished() -- connect the tooltip elements - delete(xmlFile) - else - canLoad = false - Logging.error("[GuiLoader %s] Required file '%s' could not be found!", self.name, fname) - end - end - return canLoad + if canLoad then + local fname + -- load my gui profiles + fname = guiPath .. "guiProfiles.xml" + if fileExists(fname) then + g_gui:loadProfiles(fname) + else + canLoad = false + end + -- load "SCGui.xml" + fname = guiPath .. "SCGui.xml" + if canLoad and fileExists(fname) then + local xmlFile = loadXMLFile("Temp", fname) + local fbox = self.frCon.farmerBox + g_gui:loadGuiRec(xmlFile, "GUI", fbox, self.frCon) + local layout = fbox:getDescendantById("layout") + layout:invalidateLayout(true) -- adjust sort buttons + fbox:applyScreenAlignment() + fbox:updateAbsolutePosition() + fbox:onGuiSetupFinished() -- connect the tooltip elements + delete(xmlFile) + else + canLoad = false + Logging.error("[GuiLoader %s] Required file '%s' could not be found!", self.name, fname) + end + end + return canLoad end function BetterContracts:refresh() - -- refresh our contract tables. Called by onFrameOpen/updateList, and every 15 sec by self:onUpdate - self.harvest, self.spread, self.simple, self.baling, self.transp = {}, {}, {}, {}, {} - self.IdToCont, self.fieldToMission = {}, {} - local list = g_missionManager:getMissionsList(g_currentMission:getFarmId()) - local res = {} - debugPrint("[%s] refresh() at %s sec, found %d contracts", self.name, - g_i18n:formatNumber(g_currentMission.time/1000) ,#list) - self.numCont = 0 - for _, m in ipairs(list) do - res = self:addMission(m) - if res[1] and res[1] > 0 then - self.IdToCont[m.id] = res - self.numCont = self.numCont +1 - end - end - self.missionUpdTimer = 0 -- don't call us again too soon + -- refresh our contract tables. Called by onFrameOpen/updateList, and every 15 sec by self:onUpdate + self.harvest, self.spread, self.simple, self.baling, self.transp = {}, {}, {}, {}, {} + self.IdToCont, self.fieldToMission = {}, {} + local list = g_missionManager:getMissionsList(g_currentMission:getFarmId()) + local res = {} + debugPrint("[%s] refresh() at %s sec, found %d contracts", self.name, + g_i18n:formatNumber(g_currentMission.time/1000) ,#list) + self.numCont = 0 + for _, m in ipairs(list) do + res = self:addMission(m) + if res[1] and res[1] > 0 then + self.IdToCont[m.id] = res + self.numCont = self.numCont +1 + end + end + self.missionUpdTimer = 0 -- don't call us again too soon end function BetterContracts:getFilltypePrice(m) - -- get price for harvest/ mow-bale missions - if m.sellPointId then - m:tryToResolveSellPoint() - end - if not m.sellPoint then - Logging.warning("[%s]:addMission(): contract '%s %s on field %s' has no sellPoint.", - self.name, m.type.name, self.ft[m.fillType].title, m.field.fieldId) - return 0 - end - return m.sellPoint:getEffectiveFillTypePrice(m.fillType) + -- get price for harvest/ mow-bale missions + if m.sellPointId then + m:tryToResolveSellPoint() + end + if not m.sellPoint then + Logging.warning("[%s]:addMission(): contract '%s %s on field %s' has no sellPoint.", + self.name, m.type.name, self.ft[m.fillType].title, m.field.fieldId) + return 0 + end + return m.sellPoint:getEffectiveFillTypePrice(m.fillType) end function BetterContracts:addMission(m) - -- add mission m to the corresponding BetterContracts list - local cont = {} - local dim, wid, hei, dura, wwidth, speed, vtype, vname, vfound - local cat = self.typeToCat[m.type.typeId] - local rew = m:getReward() - if cat < SC.TRANSP then - dim = self:getDimensions(m.field, false) - wid, hei = dim.width, dim.height - if wid > hei then - wid, hei = hei, wid - end - self.fieldToMission[m.field.fieldId] = m - vfound, wwidth, speed, vtype, vname = self:getFromVehicle(cat, m) + -- add mission m to the corresponding BetterContracts list + local cont = {} + local dim, wid, hei, dura, wwidth, speed, vtype, vname, vfound + local cat = self.typeToCat[m.type.typeId] + local rew = m:getReward() + if cat < SC.TRANSP then + dim = self:getDimensions(m.field, false) + wid, hei = dim.width, dim.height + if wid > hei then + wid, hei = hei, wid + end + self.fieldToMission[m.field.fieldId] = m + vfound, wwidth, speed, vtype, vname = self:getFromVehicle(cat, m) - -- estimate mission duration: - if vfound and wwidth > 0 then - _, dura = self:estWorktime(wid, hei, wwidth, speed) - elseif not vfound or cat~=SC.SPREAD then - Logging.warning("[%s]:addMission(): problem with vehicles for contract '%s field %s'.", - self.name, m.type.name, m.field.fieldId) - local cat1 = cat == 1 and 1 or 0 - -- use default width and speed values : - -- cat/index: 1/6, 3/7, 4/8 = harvest, plow, mow - _,dura = self:estWorktime(wid, hei, self.WORKWIDTH[4+cat+cat1], self.SPEEDLIMS[4+cat+cat1]) - end - if (cat==SC.HARVEST or cat==SC.BALING) and m.expectedLiters == nil then - Logging.warning("[%s]:addMission(): contract '%s %s on field %s' has no expectedLiters.", - self.name, m.type.name, self.ft[m.fillType].title, m.field.fieldId) - m.expectedLiters = 0 - return {0, cont} - end - end - if cat == SC.HARVEST then - local keep = math.floor(m.expectedLiters * 0.265) - local price = self:getFilltypePrice(m) - local profit = rew + keep * price - cont = { - miss = m, - width = wid, - height = hei, - worktime = dura, - ftype = self.ft[m.fillType].title, - deliver = math.floor(m.expectedLiters * 0.735), --must be delivered - keep = keep, --can be sold on your own - price = price * 1000, - profit = profit, - permin = profit / dura * 60, - reward = rew - } - table.insert(self.harvest, cont) - elseif cat == SC.SPREAD then - cont = self:spreadMission(m, wid, hei, wwidth, speed) - table.insert(self.spread, cont) - elseif cat == SC.SIMPLE then - cont = { - miss = m, - width = wid, - height = hei, - worktime = dura, - profit = rew, - permin = rew / dura * 60, - reward = rew - } - table.insert(self.simple, cont) - elseif cat == SC.BALING then - local deliver = math.ceil(m.expectedLiters * 0.7895/(0.8/BaleMission.FILL_SUCCESS_FACTOR)) - local keep = math.floor(m.expectedLiters - deliver) --can be sold on your own - local price = self:getFilltypePrice(m) - local profit = rew + keep * price - cont = { - miss = m, - width = wid, - height = hei, - worktime = dura * 3, -- dura is just the mow time, adjust for windrowing/ baling - ftype = self.ft[m.fillType].title, - deliver = deliver, - keep = keep, --can be sold on your own - price = price * 1000, - profit = profit, - permin = profit / dura / 3 * 60, - reward = rew - } - table.insert(self.baling, cont) - elseif cat == SC.SUPPLY then - cont = { - miss = m, - worktime = 0, - ftype = self.ft[m.fillType].title, - deliver = m.contractLiters, - price = m.pricePerLitre * 1000, - profit = rew - m.contractLiters * m.pricePerLitre, - permin = 0, - reward = rew - } - table.insert(self.transp, cont) - else -- cat == SC.TRANSP - cont = { - miss = m, - profit = rew, - permin = 0, - reward = rew - } - table.insert(self.transp, cont) - end - return {cat, cont} + -- estimate mission duration: + if vfound and wwidth > 0 then + _, dura = self:estWorktime(wid, hei, wwidth, speed) + elseif not vfound or cat~=SC.SPREAD then + Logging.warning("[%s]:addMission(): problem with vehicles for contract '%s field %s'.", + self.name, m.type.name, m.field.fieldId) + local cat1 = cat == 1 and 1 or 0 + -- use default width and speed values : + -- cat/index: 1/6, 3/7, 4/8 = harvest, plow, mow + _,dura = self:estWorktime(wid, hei, self.WORKWIDTH[4+cat+cat1], self.SPEEDLIMS[4+cat+cat1]) + end + if (cat==SC.HARVEST or cat==SC.BALING) and m.expectedLiters == nil then + Logging.warning("[%s]:addMission(): contract '%s %s on field %s' has no expectedLiters.", + self.name, m.type.name, self.ft[m.fillType].title, m.field.fieldId) + m.expectedLiters = 0 + return {0, cont} + end + end + if cat == SC.HARVEST then + local keep = math.floor(m.expectedLiters *(1 - HarvestMission.SUCCESS_FACTOR)) + local price = self:getFilltypePrice(m) + local profit = rew + keep * price + cont = { + miss = m, + width = wid, + height = hei, + worktime = dura, + ftype = self.ft[m.fillType].title, + deliver = math.ceil(m.expectedLiters - keep), --must be delivered + keep = keep, --can be sold on your own + price = price * 1000, + profit = profit, + permin = profit / dura * 60, + reward = rew + } + table.insert(self.harvest, cont) + elseif cat == SC.SPREAD then + cont = self:spreadMission(m, wid, hei, wwidth, speed) + table.insert(self.spread, cont) + elseif cat == SC.SIMPLE then + cont = { + miss = m, + width = wid, + height = hei, + worktime = dura, + profit = rew, + permin = rew / dura * 60, + reward = rew + } + table.insert(self.simple, cont) + elseif cat == SC.BALING then + local deliver = math.ceil(m.expectedLiters * BaleMission.FILL_SUCCESS_FACTOR) + local keep = math.floor(m.expectedLiters - deliver) --can be sold on your own + local price = self:getFilltypePrice(m) + local profit = rew + keep * price + cont = { + miss = m, + width = wid, + height = hei, + worktime = dura * 3, -- dura is just the mow time, adjust for windrowing/ baling + ftype = self.ft[m.fillType].title, + deliver = deliver, + keep = keep, --can be sold on your own + price = price * 1000, + profit = profit, + permin = profit / dura / 3 * 60, + reward = rew + } + table.insert(self.baling, cont) + elseif cat == SC.SUPPLY then + cont = { + miss = m, + worktime = 0, + ftype = self.ft[m.fillType].title, + deliver = m.contractLiters, + price = m.pricePerLitre * 1000, + profit = rew - m.contractLiters * m.pricePerLitre, + permin = 0, + reward = rew + } + table.insert(self.supply, cont) + else -- cat == SC.TRANSP + cont = { + miss = m, + worktime = 0, + ftype = getPalletType(m), + deliver = m.numObjects, + profit = rew, + permin = 0, + reward = rew + } + table.insert(self.transp, cont) + end + return {cat, cont} +end +function getPalletType(m) + -- return type of pallet contents, from mission object + for _, o in ipairs(m.missionConfig.objects) do + if m.objectFilename == o.filename then + return o.title + end + end + return "" end function BetterContracts.writeStream(self, streamId, connection) - streamWriteFloat32(streamId, self.expectedLiters) - streamWriteFloat32(streamId, self.depositedLiters) + streamWriteFloat32(streamId, self.expectedLiters) + streamWriteFloat32(streamId, self.depositedLiters) end function BetterContracts.readStream(self, streamId, connection) - self.expectedLiters = streamReadFloat32(streamId) - self.depositedLiters = streamReadFloat32(streamId) + self.expectedLiters = streamReadFloat32(streamId) + self.depositedLiters = streamReadFloat32(streamId) end function BetterContracts.writeUpdateStream(self, streamId, connection, dirtyMask) - local fieldPercent, depo = 0., 0. - if self.fieldPercentageDone then fieldPercent = self.fieldPercentageDone end - if self.depositedLiters then depo = self.depositedLiters end - streamWriteFloat32(streamId, fieldPercent) - streamWriteFloat32(streamId, depo) + local fieldPercent, depo = 0., 0. + if self.fieldPercentageDone then fieldPercent = self.fieldPercentageDone end + if self.depositedLiters then depo = self.depositedLiters end + streamWriteFloat32(streamId, fieldPercent) + streamWriteFloat32(streamId, depo) end function BetterContracts.readUpdateStream(self, streamId, timestamp, connection) - self.fieldPercentageDone = streamReadFloat32(streamId) - self.depositedLiters = streamReadFloat32(streamId) + self.fieldPercentageDone = streamReadFloat32(streamId) + self.depositedLiters = streamReadFloat32(streamId) end function abstractMissionNew(isServer, superf, isClient, customMt ) - local self = superf(isServer, isClient, customMt) - self.mission = g_currentMission - -- Fix for error in AbstractMission 'self.mission' still missing in Version 1.2.0.2 - return self + local self = superf(isServer, isClient, customMt) + self.mission = g_currentMission + -- Fix for error in AbstractMission 'self.mission' still missing in Version 1.2.0.2 + return self end \ No newline at end of file diff --git a/gui/SCGui.xml b/gui/SCGui.xml index 5297fd8..454ed81 100644 --- a/gui/SCGui.xml +++ b/gui/SCGui.xml @@ -38,7 +38,7 @@ - + diff --git a/l10n/l10n_de.xml b/l10n/l10n_de.xml index 757dcb6..31cae8f 100644 --- a/l10n/l10n_de.xml +++ b/l10n/l10n_de.xml @@ -27,6 +27,7 @@ + diff --git a/l10n/l10n_en.xml b/l10n/l10n_en.xml index 7b0d9bb..56ed526 100644 --- a/l10n/l10n_en.xml +++ b/l10n/l10n_en.xml @@ -27,8 +27,10 @@ + + diff --git a/l10n/l10n_fr.xml b/l10n/l10n_fr.xml index 64b67cf..1dd5282 100644 --- a/l10n/l10n_fr.xml +++ b/l10n/l10n_fr.xml @@ -25,10 +25,13 @@ + + + - + diff --git a/l10n/l10n_it.xml b/l10n/l10n_it.xml index 46645a7..760d3de 100644 --- a/l10n/l10n_it.xml +++ b/l10n/l10n_it.xml @@ -25,6 +25,9 @@ + + + diff --git a/l10n/l10n_jp.xml b/l10n/l10n_jp.xml index a2773e7..48b36d9 100644 --- a/l10n/l10n_jp.xml +++ b/l10n/l10n_jp.xml @@ -25,6 +25,9 @@ + + + diff --git a/l10n/l10n_pl.xml b/l10n/l10n_pl.xml index 733c9ab..44fc9fd 100644 --- a/l10n/l10n_pl.xml +++ b/l10n/l10n_pl.xml @@ -25,6 +25,9 @@ + + + diff --git a/l10n/l10n_ru.xml b/l10n/l10n_ru.xml index 618a4a6..31faf5c 100644 --- a/l10n/l10n_ru.xml +++ b/l10n/l10n_ru.xml @@ -25,6 +25,9 @@ + + + diff --git a/modDesc.xml b/modDesc.xml index 68aa803..b167668 100644 --- a/modDesc.xml +++ b/modDesc.xml @@ -1,7 +1,7 @@  - + Mmtrx - 1.2.0.2 + 1.2.2.0 <en>Better Contracts</en> @@ -23,6 +23,11 @@ - With the "Details" button you can toggle on/ off the display of additional contract information. Like cost estimates for usage material as fertilizer, herbicide, or seeds. For harvest and baling contracts, it shows the minimum amount to be delivered, and the amount that you can keep (and sell). From this it calculates the total profit value for a contract, i.e. reward minus cost for fertilize/ spray/ sow contracts, and reward plus value of kept harvest for harvest/ baling contracts. It even estimates the time you will probably need for total completion of the job, by taking into account the work speed and work width of the appropriate leasing vehicles/ tools that are offered with the contract. Disclaimer: All values shown in details display are ESTIMATES. You should not take them absolutely, but rather as an indication of what contracts to prefer among others. + +Changelog v1.2.2.0: +- Adjusted calculation of keep / deliver values for harvest / baling contracts +- Added conflicts prevention with other mods +- Added support for FS22_SupplyTransportContracts, FS22_TransportMissions ]]> @@ -42,6 +47,11 @@ Disclaimer: All values shown in details display are ESTIMATES. You should not ta - Mit dem "Details" Button kann die Anzeige der zusätzlichen Vertragsdetails ein- und ausgeschaltet werden. Z.B. die geschätzten Kosten des Verbrauchsmaterials (Dünger, Pflanzenschutzmittel, Saatgut). Bei Ernte- und Gras-Missionen wird die abzuliefernde Mindestmenge angezeigt, sowie die Erntemenge, die Sie behalten (und verkaufen) können. Daraus ermittelt der Mod den Gesamtertrag der Mission, also Belohnung minus Kosten für Dünge-, Spritz-, und Sähen-Verträge; und Belohnung plus Wert der behaltenen Erntemenge bei den Ernte- und Gras-Verträgen. Er schätzt sogar die Gesamtzeit, die Sie für die Erledigung des Auftrags benötigen werden, und berücksichtigt dafür Arbeitsgeschwindigkeit und Arbeitsbreite der entsprechenden Leasing-Geräte, die für den Vertrag angeboten werden. Warnung: Alle in der Detailanzeige angegebenen Werte sind GESCHÄTZT. Sie sollten sie also nicht als absolute Zahlen verstehen, sondern als Hinweis, welche Verträge vielleicht anderen vorzuziehen sind. + +Changelog v1.2.2.0: +- Berechnung der Mindestliefer- und Eigenmengen angepasst bei Ernte- und Gras-Verträgen +- Konfliktvermeidung mit anderen Mods +- Unterstützung für FS22_SupplyTransportContracts, FS22_TransportMissions ]]> @@ -62,6 +72,11 @@ Ce mod permet d'améliorer le système de contrat, à la fois en solo et multijo - Affichage des détails supplémentaires des contrats directement à l'aide d'un raccourci clavier depuis le menu des contrats. En plus du type de contrat et du numéro+taille du champ, vous trouverez maintenant les coûts estimés du contrat (engrais, herbicide, semence), le surplus de récolte ou de pressage, le calcul automatique du profit net généré. Il y a même l'affichage du temps que vous passerez à réaliser le contrat avec le matériel proposé en location avec celui-ci. Avertissement: toutes les valeurs indiquées dans l'affichage détaillé sont des ESTIMATIONS. Il ne faut donc pas les considérer comme des chiffres absolus, mais plutôt comme une indication des contrats qui pourraient être préférés à d'autres. + +Changelog v1.2.2.0: +- Calcul ajusté des valeurs de conservation et de livraison pour les contrats de récolte et de mise en balles +- Ajout de la prévention des conflits avec d'autres mods +- Ajout de support pour FS22_SupplyTransportContracts, FS22_TransportMissions ]]> @@ -81,6 +96,11 @@ Avertissement: toutes les valeurs indiquées dans l'affichage détaillé sont de - Добавлено много новых комбинаций техники для контрактов Внимание: Все значения, указанные на подробном дисплее, являются ИСКЛЮЧИТЕЛЬНЫМИ. Поэтому не следует воспринимать их как абсолютные цифры, а как указание на то, какие контракты могут быть предпочтительнее других. + +Changelog v1.2.2.0: +- Adjusted calculation of keep / deliver values for harvest / baling contracts +- Added conflicts prevention with other mods +- Added support for FS22_SupplyTransportContracts, FS22_TransportMissions ]]> diff --git a/scripts/gui.lua b/scripts/gui.lua index af0285a..f50c0d1 100644 --- a/scripts/gui.lua +++ b/scripts/gui.lua @@ -10,32 +10,41 @@ -- v1.1.1.0 24.04.2021 (Mmtrx) gui enhancements: addtl details, sort buttons -- v1.1.1.4 07.07.2021 (Mmtrx) add user-defined missionVehicles.xml, allow missions with no vehicles -- v1.2.0.0 18.01.2022 (Mmtrx) adapt for FS22 +-- v1.2.2.0 30.03.2022 recognize conflict FS22_Contracts_Plus, +-- details for transport missions --======================================================================================================= -------------------- Gui enhance functions --------------------------------------------------- -function onFrameOpen(self, superFunc, ...) - if BetterContracts.needsRefreshContractsConflictsPrevention then +function onFrameOpen(superself, superFunc, ...) + local self = BetterContracts + local inGameMenu = self.gameMenu + if self.needsRefreshContractsConflictsPrevention then -- this will prevent execution of FS22_RefreshContracts code (because they check for that field to be nil) - BetterContracts.gameMenu.refreshContractsElement_Button = 1 + inGameMenu.refreshContractsElement_Button = 1 + end + if self.preventContractsPlus then + -- this will prevent execution of FS22_Contracts_Plus code (because they check for those fields to be nil) + inGameMenu.newContractsButton = 1 + inGameMenu.clearContractsButton = 1 end - superFunc(self, ...) - BetterContracts.gameMenu.refreshContractsElement_Button = nil + superFunc(superself, ...) + inGameMenu.refreshContractsElement_Button = nil + inGameMenu.newContractsButton = nil + inGameMenu.clearContractsButton = nil - local self = BetterContracts - local inGameMenu = self.gameMenu local parent = inGameMenu.menuButton[1].parent -- add new buttons - if inGameMenu.newContractsButton == nil then - inGameMenu.newContractsButton = inGameMenu.menuButton[1]:clone(parent) - inGameMenu.newContractsButton.onClickCallback = onClickNewContractsCallback - inGameMenu.newContractsButton:setText(g_i18n:getText("bc_new_contracts")) - inGameMenu.newContractsButton:setInputAction("MENU_EXTRA_1") - end - if inGameMenu.clearContractsButton == nil then - inGameMenu.clearContractsButton = inGameMenu.menuButton[1]:clone(parent) - inGameMenu.clearContractsButton.onClickCallback = onClickClearContractsCallback - inGameMenu.clearContractsButton:setText(g_i18n:getText("bc_clear_contracts")) - inGameMenu.clearContractsButton:setInputAction("MENU_EXTRA_2") + if inGameMenu.newButton == nil then + inGameMenu.newButton = inGameMenu.menuButton[1]:clone(parent) + inGameMenu.newButton.onClickCallback = onClickNewContractsCallback + inGameMenu.newButton:setText(g_i18n:getText("bc_new_contracts")) + inGameMenu.newButton:setInputAction("MENU_EXTRA_1") + end + if inGameMenu.clearButton == nil then + inGameMenu.clearButton = inGameMenu.menuButton[1]:clone(parent) + inGameMenu.clearButton.onClickCallback = onClickClearContractsCallback + inGameMenu.clearButton:setText(g_i18n:getText("bc_clear_contracts")) + inGameMenu.clearButton:setInputAction("MENU_EXTRA_2") end if inGameMenu.detailsButton == nil then local button = inGameMenu.menuButton[1]:clone(parent) @@ -61,8 +70,8 @@ function onFrameClose() local inGameMenu = g_currentMission.inGameMenu for _, button in ipairs( { - inGameMenu.newContractsButton, - inGameMenu.clearContractsButton, + inGameMenu.newButton, + inGameMenu.clearButton, inGameMenu.detailsButton } ) do @@ -74,8 +83,8 @@ function onFrameClose() if BetterContracts.eventExtra3 ~= nil then g_inputBinding:removeActionEvent(BetterContracts.eventExtra3) end - inGameMenu.newContractsButton = nil - inGameMenu.clearContractsButton = nil + inGameMenu.newButton = nil + inGameMenu.clearButton = nil inGameMenu.detailsButton = nil end @@ -83,16 +92,16 @@ function onClickMenuExtra1(inGameMenu, superFunc, ...) if superFunc ~= nil then superFunc(inGameMenu, ...) end - if inGameMenu.newContractsButton ~= nil then - inGameMenu.newContractsButton.onClickCallback(inGameMenu) + if inGameMenu.newButton ~= nil then + inGameMenu.newButton.onClickCallback(inGameMenu) end end function onClickMenuExtra2(inGameMenu, superFunc, ...) if superFunc ~= nil then superFunc(inGameMenu, ...) end - if inGameMenu.clearContractsButton ~= nil then - inGameMenu.clearContractsButton.onClickCallback(inGameMenu) + if inGameMenu.clearButton ~= nil then + inGameMenu.clearButton.onClickCallback(inGameMenu) end end function onClickMenuExtra3(inGameMenu) @@ -268,34 +277,50 @@ function updateFarmersBox(frCon, field, npc) self.my.npcbox:setVisible(true) -- handle non-field missions - if cat == SC.TRANSP then -- it's a transport/snow mission - self.my.npcbox:setVisible(false) + self.my.field:setText(g_i18n:getText("SC_fillType")) -- line 1 + self.my.filltype:setText(c.ftype) + self.my.widhei:setText("") -- line 2 + self.my.dimen:setText("") + self.my.line3:setText("") -- line 3 + self.my.etime:setText("") + if cont.active then + self.my.line4a:setText(g_i18n:getText("SC_delivered")) + self.my.line4b:setText(g_i18n:getText("SC_togo")) + else + self.my.line4a:setText(g_i18n:getText("SC_deliver")) + self.my.line4b:setText("") + self.my.valu4b:setText("") + end + self.my.line6:setText(g_i18n:getText("SC_profitSupply")) + self.my.valu6:setText(g_i18n:formatMoney(c.profit)) + self.my.ppmin:setText("") + self.my.valu7:setText("") + + if cat == SC.TRANSP then -- it's a transport mission (maybe mod) + if cont.active then + self.my.valu4a:setText(string.format("%d Pal.", m.numFinished)) + self.my.valu4b:setText(string.format("%d Pal.",m.numObjects - m.numFinished)) + else + self.my.valu4a:setText(string.format("%d Pal.",m.numObjects)) + self.my.ppmin:setText(g_i18n:getText("SC_timeleft")) + local secLeft = m.timeLeft / 1000 + local hh = math.floor(secLeft / 3600) + local mm = (secLeft - 3600*hh) / 60 + local ss = (mm - math.floor(mm)) *60 + self.my.valu7:setText(string.format("%02d:%02d:%02d",hh,mm,ss)) + end + self.my.line5:setText("") + self.my.price:setText("") return elseif cat == SC.SUPPLY then -- a supplyTransp mission (mod) - self.my.field:setText(g_i18n:getText("SC_fillType")) -- line 1 - self.my.filltype:setText(c.ftype) - self.my.widhei:setText("") -- line 2 - self.my.dimen:setText("") - self.my.line3:setText("") -- line 3 - self.my.etime:setText("") if cont.active then - self.my.line4a:setText(g_i18n:getText("SC_delivered")) - self.my.line4b:setText(g_i18n:getText("SC_togo")) self.my.valu4a:setText(g_i18n:formatVolume(MathUtil.round(m.deliveredLiters,-2))) self.my.valu4b:setText(g_i18n:formatVolume(MathUtil.round(m.contractLiters-m.deliveredLiters,-2))) else - self.my.line4a:setText(g_i18n:getText("SC_deliver")) - self.my.line4b:setText("") self.my.valu4a:setText(g_i18n:formatVolume(MathUtil.round(m.contractLiters,-2))) - self.my.valu4b:setText("") end - self.my.line5:setText(g_i18n:getText("SC_price")) self.my.price:setText(g_i18n:formatMoney(c.price)) - self.my.line6:setText(g_i18n:getText("SC_profitSupply")) - self.my.valu6:setText(g_i18n:formatMoney(c.profit)) - self.my.ppmin:setText("") - self.my.valu7:setText("") return end @@ -303,8 +328,8 @@ function updateFarmersBox(frCon, field, npc) if field ~= nil then local text = string.format(g_i18n:getText("SC_field"), field.fieldId, g_i18n:formatArea(field.fieldArea, 2)) self.my.field:setText(text) - self.my.widhei:setText(g_i18n:getText("SC_widhei")) - self.my.ppmin:setText(g_i18n:getText("SC_profpmin")) + self.my.widhei:setText(g_i18n:getText("SC_widhei")) + self.my.ppmin:setText(g_i18n:getText("SC_profpmin")) end local etime = c.worktime if cat == SC.SPREAD then