Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package.path = package.path .. ";data/scripts/lib/?.lua"
- package.path = package.path .. ";data/scripts/?.lua"
- require ("oosproductionLib")
- require ("utility")
- require ("asteroidSpawningLib")
- require ("goodsindex")
- --data\scripts\player\oosproduction.lua
- "[0.9_6b]" -- do not change
- SectorGenerator = require("SectorGenerator")--remove
- PlanGenerator = require ("plangenerator")--remove
- Placer = require("placer")
- local spawnAstroInThisSector = 0
- local usesRightversion = false
- function initialize()
- if onServer() then
- print(OOSPVERSION.."[OOSP] ".."======oos initialising for Player "..Player().name.."======")
- --unregister events to clear things up.
- local unregisterOnSectorLeftValue = Player():unregisterCallback("onSectorLeft", "onSectorLeft")
- local unregisterOnSectorEnteredValue = Player():unregisterCallback("onSectorEntered", "onSectorEntered")
- local unregisterOnPlayerLogOffValue = Server():unregisterCallback("onPlayerLogOff", "onPlayerLogOff")
- print(OOSPVERSION.."[OOSP] ".."Event unregisteration: "..tostring(unregisterOnSectorLeftValue).." | "..tostring(unregisterOnSectorEnteredValue).." | "..tostring(unregisterOnPlayerLogOffValue))
- --begin registering events for a fresh start
- Player():registerCallback("onSectorLeft", "onSectorLeft")
- Player():registerCallback("onSectorEntered", "onSectorEntered")
- Server():registerCallback("onPlayerLogOff", "onPlayerLogOff")
- else
- local isallowed = invokeServerFunction("processVersion", Player().index, OOSPVERSION)
- if isallowed then
- else
- end
- invokeServerFunction("onPlayerLogIn",Player().index)
- end
- end
- function processVersion(playerIndex, version)
- if onServer() then
- if version ~= OOSPVERSION then
- print(OOSPVERSION.."[OOSP] ".."Player "..Player(playerIndex).name.."uses a different version of OOSP: "..version)
- Player(playerIndex):sendChatMessage("Server", 2, "Update your Version ("..version..") to "..OOSPVERSION..". OOSP is deactivated for you! ")
- return false
- else
- print(OOSPVERSION.."[OOSP][T] ".."Player "..Player(playerIndex).name.."Logged in with the correct version of OOSP: "..version)
- usesRightversion = true
- return true
- end
- end
- end
- --When a Player logs in, the onSectorEntered-Event is not fired. This would cause the Sector to be ignored by the oosproduction-Script.
- function onPlayerLogIn(playerIndex)
- if Player(playerIndex).name ~= Player().name then --wrong player called
- return
- end
- if usesRightversion == false then
- Player(playerIndex):sendChatMessage("Server", 2, "Update your Version to "..OOSPVERSION..". OOSP is deactivated for you! ")
- print(OOSPVERSION.."[OOSP] ".."Player "..Player(playerIndex).name.."uses a different version of OOSP")
- local unregisterOnSectorLeftValue = Player():unregisterCallback("onSectorLeft", "onSectorLeft")
- local unregisterOnSectorEnteredValue = Player():unregisterCallback("onSectorEntered", "onSectorEntered")
- local unregisterOnPlayerLogOffValue = Server():unregisterCallback("onPlayerLogOff", "onPlayerLogOff")
- print(OOSPVERSION.."[OOSP] ".."Event unregisteration: "..tostring(unregisterOnSectorLeftValue).." | "..tostring(unregisterOnSectorEnteredValue).." | "..tostring(unregisterOnPlayerLogOffValue))
- sendMoreMessages()
- onPlayerLogOff(playerIndex)
- return
- end
- --print(OOSPVERSION.."[OOSP] ".."onPlayerLogIn executed from Client")
- local x,y = Sector():getCoordinates()
- onSectorEntered(playerIndex, x, y)
- end
- function sendMoreMessages(playerIndex)
- Player(playerIndex):sendChatMessage("Server", 2, "Update your Version to "..OOSPVERSION..". OOSP is deactivated for you! ")
- print(OOSPVERSION.."[OOSP] ".."Remembered "..Player(playerIndex).name.." that he is using the wrong version")
- deferredCallback(10,"sendMoreMessages",playerIndex)
- end
- function onPlayerLogOff(playerIndex)--Initialize gets called on PlayerLogIn
- if Player(playerIndex).name ~= Player().name then --wrong player called
- print(OOSPVERSION.."[OOSP] ".."Wrong Player Logoff")
- return
- end
- --unregister twice: better safe than sorry
- local unregisterOnSectorLeftValue = Player():unregisterCallback("onSectorLeft", "onSectorLeft")
- local unregisterOnSectorEnteredValue = Player():unregisterCallback("onSectorEntered", "onSectorEntered")
- local unregisterOnPlayerLogOffValue = Server():unregisterCallback("onPlayerLogOff", "onPlayerLogOff")
- print(OOSPVERSION.."[OOSP] ".."Event unregisteration: "..tostring(unregisterOnSectorLeftValue).." | "..tostring(unregisterOnSectorEnteredValue).." | "..tostring(unregisterOnPlayerLogOffValue))
- print(OOSPVERSION.."[OOSP] ".."======oos unloading Player "..Player(playerIndex).name.."======")
- local x,y = Sector():getCoordinates()
- print(OOSPVERSION.."[OOSP] "..Player(playerIndex).name .. " " .. x .. ":" .. y)
- onSectorLeft(playerIndex, x, y)
- end
- --sets a Timestamp when the last player leaves the Sector
- function onSectorLeft(playerIndex, x, y)
- if Player(playerIndex).name ~= Player().name then --wrong player called
- return
- end
- local numplayer = Sector().numPlayers
- local galaxyTickName = ("galaxyticks"..tostring(Server().seed))
- --local mutexstr = ("MA"..Player(playerIndex).name) --TODO
- if(numplayer <=1) then -- we only need a new timestamp when an sector gets unloaded. The player is still in sector when the Hook calls, thus we check for 1 remaining player
- local timestamp = Sector():getValue("oosTimestamp")
- if timestamp ~= nil then --update Timestamp
- timestamp = Server():getValue(galaxyTickName)
- Sector():setValue("oosTimestamp", timestamp)
- print(OOSPVERSION.."[OOSP] ".."timestamp: ".. timestamp .. " for Sector ".. x .. ":" .. y.." updated")
- else --sector was never timestamped
- timestamp = Server():getValue(galaxyTickName)
- Sector():setValue("oosTimestamp", timestamp)
- print(OOSPVERSION.."[OOSP] ".."Sector get first timestamp: ".. timestamp .. " | ".. x .. ":" .. y)
- end
- end
- end
- --Is there a timestamp on which we can work?-Then do so.
- function onSectorEntered(playerIndex, x, y)
- if Player(playerIndex).name ~= Player().name then --wrong player called
- return
- end
- local sec = systemTimeMs()
- local totaltime = 0
- local timestamp = Sector():getValue("oosTimestamp")
- print(OOSPVERSION.."[OOSP] ".."Player: "..Player().name.." entered sector with: "..(Sector().numPlayers-1).." more player(s)")
- if timestamp ~= nil then
- if Sector().numPlayers <= 1 then
- print(OOSPVERSION.."[OOSP] ".."timestamp aquired: " .. timestamp)
- calculateOOSProductionForStations(Sector(),timestamp)
- else
- print(OOSPVERSION.."[OOSP] ".."Sector has been loaded already: "..Sector().numPlayers)
- end
- else
- print(OOSPVERSION.."[OOSP] ".."no timestamp - no production!")
- end
- print(OOSPVERSION.."[OOSP] ".."Sector: "..x..":"..y.. " needed " .. (systemTimeMs()- sec).."ms for Production catch-up")
- totaltime = totaltime + (systemTimeMs()- sec)
- sec = systemTimeMs()
- --spawn Asteroids int the sector we just enetered
- asteroidSpawning(playerIndex,x,y)
- print(OOSPVERSION.."[OOSP][mOS] ".."Asteroid Construction/Spawning/resolving needed "..(systemTimeMs()- sec).."ms")
- totaltime = totaltime + (systemTimeMs()- sec)
- sec = systemTimeMs()
- --especially needed after Serverrestarts and players relogging
- activateAsteroidScripts(playerIndex)
- totaltime = totaltime + (systemTimeMs()- sec)
- print(OOSPVERSION.."[OOSP][mOS] ".."Asteroid activation needed "..(systemTimeMs()- sec).."ms of the total "..totaltime.."ms")
- end
- function asteroidSpawning(playerIndex, x, y)
- local desc
- local player = Player(playerIndex)
- local hasToSpawn = (spawnAstroInThisSector > 0 )
- if hasToSpawn then
- player:sendChatMessage("Asteroid", 3, "Interact with Asteroid(s) to jump again.")
- desc = createAsteroidPlan(x,y)
- print(OOSPVERSION.."[OOSP][mOS] ".. "will spawn "..spawnAstroInThisSector.." Asteroids in Sector")
- end
- while spawnAstroInThisSector > 0 do
- spawnAstroInThisSector = spawnAstroInThisSector -1
- spawnClaimedAsteroid(playerIndex,x,y,desc)
- end
- if hasToSpawn then
- local sec = systemTimeMs()
- Placer.resolveIntersections()
- print(OOSPVERSION.."[OOSP][mOS] ".."Asteroid resolving needed "..(systemTimeMs()- sec).."ms")
- end
- end
- function activateAsteroidScripts(playerIndex)
- local MSSN = "isMarkedToMove"
- local MAEI = "MAEI%s:%s|%s"
- local x,y = Sector():getCoordinates()
- local asteroidIndex = Server():getValue(string.format(MAEI, x, y, playerIndex))
- --activateAllAstros(playerIndex) --testfunction
- if asteroidIndex ~= nil then --most likely a player relogin or server restart
- print(OOSPVERSION.."[OOSP][mOS] ".."activating Asteroid: "..asteroidIndex)
- Entity(asteroidIndex):invokeFunction("data/scripts/entity/moveAsteroid.lua","initCallback",playerIndex)
- end
- end
- function activateAllAstros(playerIndex) --just testing
- local MSSN = "isMarkedToMove"
- local MAEI = "MAEI%s:%s|%s"
- local astroList = {Sector():getEntitiesByScript("data/scripts/entity/moveAsteroid.lua")}
- print(OOSPVERSION.."[OOSP][mOS] "..#astroList)
- for i,astro in pairs(astroList) do
- if astro.factionIndex == playerIndex then
- if astro:getValue(MSSN) == nil or astro:getValue(MSSN) == false then
- astro:setValue(MSSN, true)
- --print(OOSPVERSION.."[OOSP][mOS] ".."Register Entity to extrajump: "..tostring(astro.index))
- end
- local x,y = Sector():getCoordinates()
- if Server():getValue(string.format(MAEI, x, y, playerIndex)) == nil then
- print(OOSPVERSION.."[OOSP][mOS] ".."Callbackholder: "..tostring(astro.index))
- Server():setValue(string.format(MAEI, x, y, playerIndex),astro.index)
- end
- end
- end
- end
- function increaseSpawnAstroInNextSector(val)
- if val then
- print("+val")
- spawnAstroInThisSector = spawnAstroInThisSector + val
- else
- print("val++")
- spawnAstroInThisSector = spawnAstroInThisSector + 1
- end
- end
- --apply retro-production to factories and shipyards.
- function calculateOOSProductionForStations(sector,timestamp)
- local stations = {sector:getEntitiesByType(EntityType.Station)}
- for _, station in pairs(stations) do
- if (station:hasScript("factory.lua")) then --normal factory
- if (station:hasScript("turretfactory.lua")) then --factory is a substring of turretfactory, but a turretfactory doesn't produce anything
- return
- end
- calculateOOSProductionForFactory(station, timestamp)
- end
- if (station:hasScript("shipyard.lua")) then --shipyard
- print(OOSPVERSION.."[OOSP] ".."update shipyard: "..station.name)
- calculateOOSProductionForShipyard(station,timestamp)
- end
- end
- end
- function calculateOOSProductionForShipyard(shipyard,timestamp)
- local galaxyTickName = ("galaxyticks"..tostring(Server().seed))
- local currentTime = Server():getValue(galaxyTickName)
- local timeDelta = currentTime - timestamp
- timeDelta = timeDelta/20
- if timeDelta <= 0 then
- return
- end
- local dat = shipyard:invokeFunction("data/scripts/entity/merchants/shipyard.lua","update",timeDelta)
- if(tostring(dat) == "0") then
- print(OOSPVERSION.."[OOSP] ".."update shipyard +: "..timeDelta)
- else
- print(OOSPVERSION.."[OOSP] ".."Error updating shipyard: "..tostring(dat))
- end
- end
- --calculate the production in absence
- function calculateOOSProductionForFactory(factory,timestamp)
- local galaxyTickName = ("galaxyticks"..tostring(Server().seed))
- local currentTime = Server():getValue(galaxyTickName)
- if type(currentTime) ~= "number" then
- print(OOSPVERSION.."[OOSP] ".."galaxyticks not found!")
- return
- end
- local timeDelta = currentTime - timestamp
- if timeDelta < 1 then
- print(OOSPVERSION.."[OOSP] ".."There was a Jump back in time! Did the server crash previously?") --more likely : the Tickhandler restarted or could not load the Ticksfile
- return
- end
- print(OOSPVERSION.."[OOSP] "..factory.title.. " "..factory.name)
- local status , factoryData = factory:invokeFunction("factory", "secure", nil)
- print(OOSPVERSION.."[OOSP] ".."Status: " .. status)
- local maxDuration = 0
- local maxNumProductions = 0
- local factorySize = 0
- local production = {}
- local currentProductions = {}
- local tradingdata = {}
- if status == 0 then
- maxDuration = factoryData.maxDuration --Factory total cycle time
- maxNumProductions = factoryData.maxNumProductions --max. number simultainious Productions
- factorySize = factoryData.maxNumProductions - 1 --self explained
- production = factoryData.production -- *.ingredients, *.results, *.garbage
- currentProductions = factoryData.currentProductions --Table with the passed cycletime per running Production
- tradingdata = factoryData.tradingData --All Information about stored Goods in a Station
- else
- print(OOSPVERSION.."[OOSP] "..factory.name..": konnte keine Daten erhalten")
- return
- end
- if(maxDuration == 0) then
- print(OOSPVERSION.."[OOSP] "..factory.name.."has a cycletime of 0. This is odd!")
- end
- local maximumProcesses = (timeDelta / (maxDuration * 20)) * maxNumProductions -- theoretical maximum we can produce ine the Timeframe. Might be corrected down later on.
- local minimumProcess = maximumProcesses / 4 -- minimum guaranteed production, to takes into account traders moving goods as the player is away
- print(OOSPVERSION.."[OOSP] ".."timeDelta: "..timeDelta)
- print(OOSPVERSION.."[OOSP] ".."Starting with: "..maximumProcesses)
- local spaceForExtraProcessesNeeded = 0 --since the currently running processes will be ended within the factory script, we need to make sure that they will still fit in.
- for i,timepassed in pairs(currentProductions) do
- if(maxDuration - timepassed) * 20 <= timeDelta then --20 ticks / Sec. ; timeDelta is in Ticks
- print(OOSPVERSION.."[OOSP] ".."Current Process at: "..timepassed)
- maximumProcesses = maximumProcesses - 1
- spaceForExtraProcessesNeeded = spaceForExtraProcessesNeeded + 1
- currentProductions[i] = maxDuration
- else
- -- we don't bother about this special case
- end
- end
- print(OOSPVERSION.."[OOSP] ".."Current production reduces to: "..maximumProcesses)
- if(maximumProcesses <= 0 )then
- print(OOSPVERSION.."[OOSP] ".."no Production catch-up needed.")
- end
- --get max. amount of Processcycles we can have with our ressources
- for _, ingredient in pairs(production.ingredients) do
- if(ingredient.amount == 0) then
- print(OOSPVERSION.."[OOSP] "..factory.name.." doesn't need "..ingredient.name.."for production.")
- else
- if ingredient.optional == 0 and math.floor(getNumGoods(factory, ingredient.name) / ingredient.amount) > 0 then
- print(OOSPVERSION.."[OOSP] "..ingredient.name..": "..getNumGoods(factory, ingredient.name).." | required: " .. ingredient.amount)
- maximumProcesses = math.min(math.floor(getNumGoods(factory, ingredient.name) / ingredient.amount), maximumProcesses)
- end
- if(ingredient.optional == 0 and getNumGoods(factory, ingredient.name) < ingredient.amount) then
- print(OOSPVERSION.."[OOSP] ".."can't do single process: "..ingredient.name)
- end
- end
- end
- print(OOSPVERSION.."[OOSP] ".."Ressources reduce to: "..maximumProcesses)
- -- only halve production if factory was stocked
- minimumProcess = math.max(maximumProcesses/2, minimumProcess)
- --get max. amount of Processcycles we can have with our garbage capacity
- for _, garbage in pairs(production.garbages) do
- print(OOSPVERSION.."[OOSP] ".."Free space for "..garbage.name..": "..(getMaxGoods(factory, tradingdata, garbage.name) - getNumGoods(factory, garbage.name)).." | required: " .. garbage.amount)
- maximumProcesses = math.min((getMaxGoods(factory, tradingdata, garbage.name) - getNumGoods(factory, garbage.name)), maximumProcesses)
- if maximumProcesses == 0 then
- print(OOSPVERSION.."[OOSP] ".."can't do single process: "..garbage.name)
- end
- end
- print(OOSPVERSION.."[OOSP] ".."Garbage Storage Space reduces to: "..maximumProcesses)
- --get max. amount of Processcycles we can have with our result capacity
- for _, result in pairs(production.results) do
- print(OOSPVERSION.."[OOSP] ".."Free space for "..result.name..": "..(getMaxGoods(factory, tradingdata, result.name) - getNumGoods(factory, result.name)).. " minus: "..spaceForExtraProcessesNeeded.. " | required: " .. result.amount)
- maximumProcesses = math.min((getMaxGoods(factory, tradingdata, result.name) - getNumGoods(factory, result.name) - spaceForExtraProcessesNeeded), maximumProcesses)
- if maximumProcesses == 0 then
- print(OOSPVERSION.."[OOSP] ".."can't do single process: "..result.name)
- end
- end
- maximumProcesses = math.floor(math.max(maximumProcesses, minimumProcess))
- if(maximumProcesses <= 0) then -- just in case. We wouldn't want negative Production right?
- print(OOSPVERSION.."[OOSP] "..factory.name.." needs no Production catch-up.")
- return
- end
- print(OOSPVERSION.."[OOSP] ".."The Factory is "..maximumProcesses.." processes behind.")
- for _, ingredient in pairs(production.ingredients) do
- print(OOSPVERSION.."[OOSP] ".."remove "..ingredient.amount * maximumProcesses.." of " .. ingredient.name)
- decreaseGoods(factory, tradingdata, ingredient.name, math.max(ingredient.amount * maximumProcesses, getNumGoods(factory, ingredient.name)))
- end
- for i, result in pairs(production.results) do
- print(OOSPVERSION.."[OOSP] ".."add "..result.amount * maximumProcesses.." of " .. result.name)
- local excessProduction = result.amount * maximumProcesses - (getMaxGoods(factory, tradingdata, result.name) - getNumGoods(factory, result.name))
- if excessProduction > 0 then
- local f = Faction(factory.factionIndex)
- if (f.isPlayer) then
- local p = Player(factory.factionIndex)
- local price = goods[result.name].price
- print(OOSPVERSION.."[OOSP] ".."sending earnings "..(excessProduction * price / 5).." from " .. result.name)
- p:receiveMoney( math.ceil((price * excessProduction)/5) )
- p:sendChatMessage(factory.name, 0, "Sending Production Earnings...")
- end
- end
- increaseGoods(factory, tradingdata, result.name, math.min(result.amount * maximumProcesses, getMaxGoods(factory, tradingdata, result.name) - getNumGoods(factory, result.name)))
- end
- for i, garbage in pairs(production.garbages) do
- print(OOSPVERSION.."[OOSP] ".."remove "..garbage.amount * maximumProcesses.." of " .. garbage.name)
- increaseGoods(factory, tradingdata, garbage.name, math.min(garbage.amount * maximumProcesses, getMaxGoods(factory, tradingdata, garbage.name) - getNumGoods(factory, garbage.name)))
- end
- --factory:invokeFunction("factory", "sync", nil)
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement