diff --git a/changelog.txt b/changelog.txt index 8e3810a..06433a3 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,3 +1,15 @@ +--------------------------------------------------------------------------------------------------- +Version: 2.0.0 +Date: 09.05.2025 + Major changes: + - Updated to Factorio 2.0 (thanks to Shadow_Man) + - Space Age is not supported. Elevated Rails and Quality is supported. + - New game recommended. No migration support for previous savegames. + Changes: + - Added custom Warptorio2 intro text and victory screen. + - Changed some technologies research cost to better match similar vanilla techs. + - Changed some recipes with non-stacking ingredients to have only 1 of these ingredients. + --------------------------------------------------------------------------------------------------- Version: 1.3.11 Date: 18.2.2024 @@ -8,7 +20,6 @@ Date: 18.2.2024 - Changed warp reactor specific heat from 10MJ to 1MJ to address heat distribution issues - Updated heat related code to better respect specific heats (Thanks chingis_khagan!) - --------------------------------------------------------------------------------------------------- Version: 1.3.10 Date: 8.5.2023 @@ -36,14 +47,12 @@ Date: 8.4.2022 Changes: - Typo - --------------------------------------------------------------------------------------------------- Version: 1.3.7 Date: 7.4.2022 Changes: - Lib bugfix related to cloning spider legs - --------------------------------------------------------------------------------------------------- Version: 1.3.6 Date: 7.3.2022 @@ -59,7 +68,6 @@ Date: 13.3.2021 Changes: - Fixed multiplayer crash, missing nil check on updating ownership and connection of cloned spidertrons to the remotes in players inventories between warps. - --------------------------------------------------------------------------------------------------- Version: 1.3.4 Date: 30.12.2020 diff --git a/control.lua b/control.lua index 54d8b9c..155639a 100644 --- a/control.lua +++ b/control.lua @@ -19,13 +19,11 @@ Status bar wastes screen space, don't use it. Use https://tools.stefankueng.com/grepWin.html to mass search, find and replace many files in bulk. -]]--------------------------------------- +]] --------------------------------------- ---[[ Environment ]]-- -lib={PLANETORIO=true,REMOTES=true} +--[[ Environment ]] -- +lib = { PLANETORIO = true, REMOTES = true } require("lib/lib") require("control_main") lib.lua() - - diff --git a/control_class_harvester.lua b/control_class_harvester.lua index c453875..c2020a6 100644 --- a/control_class_harvester.lua +++ b/control_class_harvester.lua @@ -1,428 +1,607 @@ - - ---[[ -harvestpad item on upgrade - - local lv=research.level("warptorio-harvester-"..self.name) - local cls="warptorio-harvestpad-"..lv - for k,v in pairs(game.players)do if(v and v.valid)then local iv=v.get_main_inventory() if(iv)then for i,x in pairs(iv.get_contents())do - if(i:sub(1,20)=="warptorio-harvestpad" and i:sub(22,22+self.name:len())==self.name)then local lvx=tonumber(i:sub(-1,-1)) - if(lvx1)then iv.remove{name=i,count=(x-1)} end - end - end end end end - -]] - - ---[[ Harvesters ]]-- - -warptorio.HarvesterSizes={12,20,26,32,38,46} -function warptorio.GetHarvesterLevelSize(lv) local z=warptorio.HarvesterSizes[lv] return vector(z,z) end -function warptorio.GetHarvesterLevelSizeNum(lv) local z=warptorio.HarvesterSizes[lv] return z end - -local HARV={} HARV.__index=HARV warptorio.HarvesterMeta=HARV setmetatable(HARV,warptorio.TeleporterMeta) -function HARV.__init(self,tbl) - self.key=tbl.key - self.rank=1 - local t={} - table.merge(t,table.deepcopy(warptorio.platform.harvesters[self.key])) - table.merge(t,table.deepcopy(warptorio.platform.HarvesterPointData)) - self.gdata=t - warptorio.TeleporterMeta.__init(self,self) - self.position=tbl.position - - self.pipes=self.pipes or {{},{}} - self.loaders=self.loaders or {{},{}} - self.loaderFilter=self.loaderFilter or {{},{}} - self.combos=self.combos or {nil,nil} - if(not self.dir)then self.dir={{},{}} for i=1,6,1 do self.dir[1][i]="input" self.dir[2][i]="output" end end - - self.deployed=self.deployed or false - self.deploy_position=self.deploy_position or nil - self.gdata.pair[2].position=self.gdata.pair[2].position or self.deploy_position or self.position - self.gdata.pair[1].position=self.gdata.pair[1].position or self.position - self.chests=nil - - global.Harvesters[tbl.key]=self -end -function HARV:Data() return self.gdata end - -function HARV:GetSize(brank) - local tps=self:Data() - if(tps.fixed_level)then return warptorio.GetHarvesterLevelSizeNum(tps.fixed_level) end - local tcn=tps.tech - local lv=(brank and self.rank or warptorio.GetPlatformTechLevel(tcn)) - return warptorio.GetHarvesterLevelSize(lv) -end -function HARV:GetBaseArea(z,rank) z=z or self:GetSize(rank)-1 return vector.square(self.position,vector(z,z)) end -function HARV:GetDeployArea(z,rank) z=z or self:GetSize(rank)-2 return vector.square(vector.pos(self.deploy_position),vector(z,z)) end - - -function HARV:CheckTeleporterPairs(bSound) -- Call updates and stuff. Automatically deals with logistics, upgrades and cleaning as-needed with good accuracy - local tps=self:Data() - local wps=warptorio.platform.HarvesterPointData - self:MakePointTeleporter(wps,1,wps.pair[1],self.position) - if(self.deployed)then - self:MakePointTeleporter(wps,2,wps.pair[2],self.deploy_position) - end - self:CheckPointLogistics(1) - self:CheckPointLogistics(2) -end - -function HARV:UpgradePlayerInventories() - for k,v in pairs(game.players)do if(v and v.valid)then local iv=v.get_main_inventory() if(iv)then for i,x in pairs(iv.get_contents())do - if(i:sub(1,20)=="warptorio-harvestpad" and i:sub(22,22+self.key:len())==self.key)then local lvx=tonumber(i:sub(-1,-1)) - if(lvx1)then iv.remove{name=i,count=(x-1)} end - end - end end end end -end - - -function HARV:MakePointTeleporter(tps,i,t,pos) - local p=self.points[i] - local f=global.floor[t.floor].host - - local epos - if(t.prototype)then - local vproto=t.prototype - if(tps.energy)then vproto=vproto.."-"..(warptorio.GetPlatformTechLevel(tps.energy)) end - local e=p.ent - if(isvalid(e))then - if(e.surface~=f)then self:DestroyPointTeleporter(i) self:DestroyPointLogistics(i) - elseif(e.name~=vproto)then epos=e.position self:DestroyPointTeleporter(i) - end - end - if(not isvalid(e))then - local vepos=epos or (pos or t.position) - if(not vepos)then return end - local vpos=((t.gate and not epos) and f.find_non_colliding_position(vproto,vepos,0,1,1) or vepos) - local varea - if(not t.gate)then varea=vector.square(vpos,vector(2,2)) vector.clean(f,varea) end - e=entity.protect(entity.create(f,vproto,vpos),t.minable~=nil and t.minable or false,t.destructible~=nil and t.destructible or false) - if(not t.gate)then vector.cleanplayers(f,varea) end - p.ent=e - end - if(p.energy)then e.energy=e.energy+p.energy p.energy=nil end - if(t.sprites)then self:MakePointSprites(tps,i,t.sprites) end - if(t.sprite_arrow)then self:MakePointArrow(tps,i,t.sprite_arrow) end - end - if(epos or not t.gate)then self:CheckPointLogistics(i) end - - cache.force_entity(p.ent,"Harvesters",self.key,"points",i) - -end - -function HARV:RunUpgrade() - local tps=self:Data() - local vz=self:GetSize() - local lv=warptorio.GetPlatformTechLevel(tps.tech) - - local f=global.floor[tps.pair[1].floor].host - - local pos=tps.position - if(not self.deployed)then - local bh=warptorio.platform.floors.harvester.BuildHarvester -- bridges first - if(bh[self.key])then bh[self.key](f) end - - local lvm=math.max(lv*2,2) -- Makes buffer area around the harvesters - vector.LayTiles("warp-tile-concrete",f,vector.square(tps.position,vector(vz+lvm,vz+lvm))) - vector.LayTiles("warptorio-red-concrete",f,vector.square(tps.position,vector(vz-2,vz-2))) - - self:CheckTeleporterPairs(true) - end - if(research.has("warptorio-logistics-1"))then - self:DestroyPointLogistics(1) - self:CheckPointLogistics(1) - if(not self.deployed)then self:DestroyPointLogistics(2) self:CheckPointLogistics(2) end - end - self:DestroyCombos() - self:CheckCombo() - - self:UpgradePlayerInventories() -- upgrade their harvestpads for this harvester (if needed) - - self.rank=lv -end - - -function HARV:Upgrade() self.ReadyUpgrade=true if(not self.deployed)then self:DoUpgrade() end end -function HARV:DoUpgrade() if(self.ReadyUpgrade)then self.ReadyUpgrade=false self:RunUpgrade() end end - - ---[[ Harvester Combinator ]]-- - - -function HARV:ConnectCombo() if(not self.deployed and self:ValidCombos())then - self.combos[1].connect_neighbour({target_entity=self.combos[2],wire=defines.wire_type.red}) self.combos[1].connect_neighbour({target_entity=self.combos[2],wire=defines.wire_type.green}) -end end -function HARV:ValidCombos() return isvalid(self.combos[1]) and isvalid(self.combos[2]) end -function HARV:CheckCombo() if(research.has("warptorio-alt-combinator"))then self:MakeComboA() self:MakeComboB() self:ConnectCombo() end end -function HARV:DestroyComboA() if(isvalid(self.combos[1]))then entity.destroy(self.combos[1]) end self.combos[1]=nil end -function HARV:DestroyComboB() if(isvalid(self.combos[2]))then entity.destroy(self.combos[2]) end self.combos[2]=nil end -function HARV:DestroyCombos() self:DestroyComboA() self:DestroyComboB() end - -function HARV:MakeComboA() local vx=self.points[1].ent - local cfg=settings.global.warptorio_combinator_offset.value local ofv if(cfg)then ofv=(self.key=="east" and 1 or 1.5) else ofv=0 end - local vpos=vector.pos(vx.position)+vector(self:GetSize().x/2*(self.key=="east" and 1 or -1)+ofv,0) - vector.clean(vx.surface,vector.square(vpos,vector(0.5,0.5))) - local e=entity.protect(entity.create(vx.surface,"warptorio-alt-combinator",vpos),false,false) - self.combos[1]=e - - cache.force_entity(e,"Harvesters",self.key,"combos",1) -end -function HARV:MakeComboB() local vx=(isvalid(self.points[2].ent) and self.points[2].ent or self.points[1].ent) - local cfg=settings.global.warptorio_combinator_offset.value local ofv if(cfg)then ofv=(self.key=="east" and -2 or -1) else ofv=(self.key=="east" and -1 or 1) end - local vpos=vector.pos(vx.position)+vector(self:GetSize().x/2*(self.key=="east" and 1 or -1)+ofv,0) - vector.clean(vx.surface,vector.square(vpos,vector(0.5,0.5))) - local e=entity.protect(entity.create(vx.surface,"warptorio-alt-combinator",vpos),false,false) - self.combos[2]=e - - cache.force_entity(e,"Harvesters",self.key,"combos",2) -end - ---[[ Harvester Logistics ]]-- - -function HARV:MakePointPipes(tps,i,id,pos,f,lddir,belty,vexdir) - local pipe="warptorio-logistics-pipe" - local v=self.pipes[i][id] - local vpos=vector(pos)+vector(vexdir)+vector(belty) - if(isvalid(v) and (v.surface~=f or v.position.x~=vpos.x or v.position.y~=vpos.y))then entity.destroy(v) end - if(not isvalid(v))then - local varea=vector.square(vpos,vector(0.5,0.5)) - vector.clean(f,varea) - v=entity.protect(entity.create(f,pipe,vpos,lddir),false,false) - self.pipes[i][id]=v - end - - cache.force_entity(v,"Harvesters",self.key,"pipes",i,id) -end - -function HARV:MakePointLoader(tps,i,id,pos,f,belt,lddir,belty,beltsquare,vexdir) - local v=self.loaders[i][id] - if(isvalid(v) and v.name~=belt)then v.destroy{raise_destroy=true} end - if(not isvalid(v))then - local vpos=vector(pos)+vector(vexdir)+vector(belty) - local varea=vector.square(vpos,beltsquare) - vector.clean(f,varea) - v=entity.protect(entity.create(f,belt,vpos,lddir),false,false) - v.loader_type=self.dir[i][id] - self.loaders[i][id]=v - local inv=self.loaderFilter[i][id] if(inv)then for invx,invy in pairs(inv)do v.set_filter(invx,invy) end end - end - cache.force_entity(v,"Harvesters",self.key,"loaders",i,id) - -end - -function HARV:CheckPointLogistics(i) - local tps=self:Data() - local t=tps.pair[i] - if(self.maxloader==0 or not tps.logs_pattern)then return end - local belt=warptorio.GetBelt() - local pos=tps.position - local f=global.floor.harvester.host - if(i==2 and self.deployed)then f=global.floor.main.host pos=self.deploy_position end - - local ldl=0 - local lvLogs=research.level("warptorio-logistics") - if(tps.logs and lvLogs>0)then ldl=ldl+1 end - if(tps.dualloader and research.has("warptorio-dualloader-1"))then ldl=ldl+1 end - if(tps.triloader and research.has("warptorio-triloader"))then ldl=ldl+1 end - if(ldl<=0)then return end - - local lddir=(i==2 and string.compassdef[tps.logs_pattern] or string.compassdef[string.compassopp[tps.logs_pattern]]) - local ldodir=(i==1 and string.compassdef[tps.logs_pattern] or string.compassdef[string.compassopp[tps.logs_pattern]]) - local vcomp=vector.compass[tps.logs_pattern] - --game.print(tps.logs_pattern .. " , lddir: " .. lddir) - local vdir=vcomp*(self:GetSize()/2) + vcomp*(i==2 and -1 or 1) - - local beltsquare=vector(1,0.5) - local pipe=vector(0,(id==1 and 2 or -2) ) - if(tps.logs_pattern=="north" or tps.logs_pattern=="south")then beltsquare=vector(0.5,1) end - for id=1,ldl do - local belty=vector( 0,(id%2==0 and 1 or 0)+(id%3==0 and -1 or 0) ) - self:MakePointLoader(tps,i,id,pos,f,belt,lddir,belty,beltsquare,vdir-vcomp*0.5) - end - - if(tps.dopipes and lvLogs>0)then - for id=1,math.min(lvLogs,2),1 do - local belty=vector( 0,(id==1 and 2 or -2) ) + (i==1 and vcomp*-1 or 0) - self:MakePointPipes(tps,i,id,pos,f,ldodir,belty,vdir) - end - end -end - - - ---[[ DEPLOY/RECALL ]]-- ---cleanlanding() - - -function HARV:Recall(bply) -- recall after portal is mined - if(self.recalling)then return end self.recalling=true - local tps=self:Data() - if(not self.deployed)then self:DestroyPointTeleporter(1,false) self:CheckTeleporterPairs() - self:DoUpgrade() - self:CheckCombo() - self:ConnectCombo() - self.recalling=false - return true - end - local t=tps.pair[i] - --self:CleanLanding() -- clean for loaders and combinators -- done automatically now - --if(isvalid(self.points[2].ent))then self.points[2].ent.destroy() end - --self.points[2].ent=nil - - - - local f=global.floor.main.host - local ebs={} - for k,v in pairs(f.find_entities_filtered{type="character",invert=true,area=self:GetDeployArea(nil,true)})do - if(v.type~="resource" and v~=self.points[1].ent)then table.insert(ebs,v) end - --v~=self.b and v~=self.a and (v.name=="warptorio-combinator" or v.name:sub(1,9)~="warptorio") )then table.insert(ebs,v) end - end - - local hf=global.floor.harvester.host - local harvArea=self:GetBaseArea(nil,true) - - - local tbs={} - local tcs={} for k,v in pairs(hf.find_tiles_filtered{area=harvArea})do - local vpos=vector.add(vector.sub(v.position,self.position),self.deploy_position) - table.insert(tcs,{name=v.name,position=vpos}) - table.insert(tbs,{name="warptorio-red-concrete",position=v.position}) - end - local dcs={} for k,v in pairs(hf.find_decoratives_filtered{area=self:GetBaseArea(nil,true)})do - local vpos=vector.add(vector.sub(v.position,self.position),self.deploy_position) - table.insert(dcs,{name=v.decorative.name,position=vpos,amount=v.amount}) - end - - - local ecs={} for k,v in pairs(hf.find_entities_filtered{area=harvArea,type="character",invert=true})do - if(v and v.valid and v~=self.points[1].ent and v~=self.points[2].ent and not entity.shouldClean(v) and not cache.get_entity(v) and v.type~="resource")then table.insert(ecs,v) end - end - - - - local blacktbl={} - for k,v in pairs(ebs)do if(table.HasValue(warptorio.GetWarpBlacklist(),v.name))then table.insert(blacktbl,v) ebs[k]=nil end end - for k,v in pairs(ebs)do if(table.HasValue(warptorio.GetModTable("harvester_blacklist"),v.name))then table.insert(blacktbl,v) ebs[k]=nil end end - - for k,v in pairs(ecs)do if(table.HasValue(warptorio.GetWarpBlacklist(),v.name))then table.insert(blacktbl,v) ecs[k]=nil end end - for k,v in pairs(ecs)do if(table.HasValue(warptorio.GetModTable("harvester_blacklist"),v.name))then table.insert(blacktbl,v) ecs[k]=nil end end - - - warptorio.Cloned_Entities={} warptorio.IsCloning=true - hf.clone_entities{entities=ecs,destination_surface=f,destination_offset=vector.add(vector.mul(self.position,-1),self.deploy_position),snap_to_grid=false} - local hfe=warptorio.Cloned_Entities warptorio.IsCloning=false warptorio.Cloned_Entities=nil - - - if(#ebs>0)then for i=#ebs,1,-1 do if(not ebs[i] or not ebs[i].valid)then table.remove(ebs,i) end end end -- bad ents in table ? - - warptorio.Cloned_Entities={} warptorio.IsCloning=true - f.clone_entities{entities=ebs,destination_surface=hf,destination_offset=vector.add(vector.mul(self.deploy_position,-1),self.position),snap_to_grid=false} - local fe=warptorio.Cloned_Entities warptorio.IsCloning=false warptorio.Cloned_Entities=nil - - local hfm={} for k,v in pairs(hfe)do if(isvalid(v.source) and isvalid(v.destination) and table.HasValue(ecs,v.source))then table.insert(hfm,v.source) end end - local fm={} for k,v in pairs(fe)do if(isvalid(v.source) and isvalid(v.destination) and table.HasValue(ebs,v.source))then table.insert(fm,v.source) end end - - for k,v in pairs(fm)do entity.destroy(v) end - for k,v in pairs(hfm)do entity.destroy(v) end - - f.set_tiles(tcs,true) - f.create_decoratives{decoratives=dcs} - - hf.destroy_decoratives{area=harvArea} - - if(bply)then -- players now - local tpply={} - for k,v in pairs(game.players)do if(v.character==nil or (v.surface==f and vector.inarea(v.position,self:GetDeployArea(nil,true))) )then - table.insert(tpply,{v,vector.add(vector.add(vector.mul(self.deploy_position,-1),vector.pos(v.position)),self.position)}) - end end - for k,v in pairs(tpply)do v[1].teleport(f.find_non_colliding_position("character",{v[2][1],v[2][2]},0,1),hf) end - end - - --vector.LayTiles("warp-tile-concrete",hf,self:GetBaseArea(self:GetSize()+2)) - --vector.LayTiles("warptorio-red-concrete",hf,self:GetBaseArea()) - hf.set_tiles(tbs,true) - self.deployed=false - self:DestroyComboB() - self:DestroyPointTeleporter(1,false) self:DestroyPointTeleporter(2,false) - self:CheckTeleporterPairs() - - self:DoUpgrade() - self:CheckCombo() - self:ConnectCombo() - self.recalling=false - -end - - - -function HARV:Deploy(surf,pos) -- deploy over a harvester platform - if(self.deployed)then return false end - local f=surf if(f~=warptorio.GetMainSurface())then game.print("Harvesters can only be placed on the planet") return false end - --game.print("deployed at: " .. serpent.line(pos)) - self.deploy_position=vector.pos(pos) - local hf=global.floor.harvester.host - - local ebs=hf.find_entities_filtered{type="character",invert=true,area=self:GetBaseArea()} - - local planetArea=self:GetDeployArea() - - local tcs={} for x=planetArea[1][1],planetArea[2][1] do for y=planetArea[1][2],planetArea[2][2]do local v=f.get_tile(x,y) - local vpos=vector.add(vector.sub(vector(x,y),self.deploy_position),self.position) - table.insert(tcs,{name=v.name,position=vpos}) - end end - local dcs={} for k,v in pairs(f.find_decoratives_filtered{area=self:GetDeployArea(self:GetSize()-3)})do - local vpos=vector.add(vector.sub(v.position,self.deploy_position),self.position) - table.insert(dcs,{name=v.decorative.name,position=vpos,amount=v.amount}) - end - local ecs={} for k,v in pairs(f.find_entities_filtered{area=planetArea,type={"construction-robot","logistic-robot","character"},invert=true})do if(v.type~="resource" and v.name:sub(1,9)~=("warptorio"))then table.insert(ecs,v) end end - - hf.set_tiles(tcs,true) - hf.create_decoratives{decoratives=dcs} - - local ebsc=#ebs - local ecsc=#ecs - - - local blacktbl={} - --for k,v in pairs(ebs)do if(isvalid(v))then if(table.HasValue(warptorio.GetWarpBlacklist(),v.name))then table.insert(blacktbl,v) ebs[k]=nil end end end - --for k,v in pairs(ebs)do if(isvalid(v))then if(table.HasValue(warptorio.GetModTable("harvester_blacklist"),v.name))then table.insert(blacktbl,v) ebs[k]=nil end end end - - --for k,v in pairs(ecs)do if(isvalid(v))then if(table.HasValue(warptorio.GetWarpBlacklist(),v.name))then table.insert(blacktbl,v) ecs[k]=nil end end end - --for k,v in pairs(ecs)do if(isvalid(v))then if(table.HasValue(warptorio.GetModTable("harvester_blacklist"),v.name))then table.insert(blacktbl,v) ecs[k]=nil end end end - - - if(ecsc>0)then for i=ecsc,1,-1 do if(not ecs[i] or not ecs[i].valid)then table.remove(ecs,i) end end end -- bad ents in table ? - - warptorio.Cloned_Entities={} warptorio.IsCloning=true - f.clone_entities{entities=ecs,destination_surface=hf,destination_offset=vector.mul(vector.sub(self.deploy_position,self.position),-1),snap_to_grid=false} - local fe=warptorio.Cloned_Entities warptorio.IsCloning=false warptorio.Cloned_Entities=nil - - - if(ebsc>0)then for i=ebsc,1,-1 do if(not ebs[i] or not ebs[i].valid)then table.remove(ebs,i) end end end -- bad ents in table ? - - vector.LayTiles("warptorio-red-concrete",f,self:GetDeployArea()) - - -- this doesnt really work - - warptorio.Cloned_Entities={} warptorio.IsCloning=true - hf.clone_entities{entities=ebs,destination_surface=f,destination_offset=vector.mul(vector.sub(self.position,self.deploy_position),-1),snap_to_grid=false} - local hfe=warptorio.Cloned_Entities warptorio.IsCloning=false warptorio.Cloned_Entities=nil - - local hfm={} for k,v in pairs(hfe)do if(isvalid(v.source) and isvalid(v.destination) and table.HasValue(ebs,v.source))then table.insert(hfm,v.source) end end - local fm={} for k,v in pairs(fe)do if(isvalid(v.source) and isvalid(v.destination) and table.HasValue(ecs,v.source))then table.insert(fm,v.source) end end - - for k,v in pairs(fm)do if(isvalid(v) and v~=self.points[1].ent and v~=self.points[2].ent)then entity.destroy(v) end end - for k,v in pairs(hfm)do if(isvalid(v) and v~=self.points[1].ent and v~=self.points[2].ent)then entity.destroy(v) end end - - for k,v in pairs(blacktbl)do if(v and v.valid)then v.destroy{raise_destroy=true} end end -- cleanup past entities - - vector.clearplayers(f,planetArea) - - self.deployed=true - -- game.print("deployed") - self:CheckTeleporterPairs() -end - - +--[[ +harvestpad item on upgrade + + local lv=research.level("warptorio-harvester-"..self.name) + local cls="warptorio-harvestpad-"..lv + for k,v in pairs(game.players)do if(v and v.valid)then local iv=v.get_main_inventory() if(iv)then for i,x in pairs(iv.get_contents())do + if(i:sub(1,20)=="warptorio-harvestpad" and i:sub(22,22+self.name:len())==self.name)then local lvx=tonumber(i:sub(-1,-1)) + if(lvx1)then iv.remove{name=i,count=(x-1)} end + end + end end end end + +]] + + +--[[ Harvesters ]] -- + +warptorio.HarvesterSizes = { 12, 20, 26, 32, 38, 46 } +function warptorio.GetHarvesterLevelSize(lv) + local z = warptorio.HarvesterSizes[lv] + return vector(z, z) +end + +function warptorio.GetHarvesterLevelSizeNum(lv) + local z = warptorio.HarvesterSizes[lv] + return z +end + +local HARV = {} +HARV.__index = HARV +warptorio.HarvesterMeta = HARV +setmetatable(HARV, warptorio.TeleporterMeta) +function HARV.__init(self, tbl) + self.key = tbl.key + self.rank = 1 + local t = {} + table.merge(t, table.deepcopy(warptorio.platform.harvesters[self.key])) + table.merge(t, table.deepcopy(warptorio.platform.HarvesterPointData)) + self.gdata = t + warptorio.TeleporterMeta.__init(self, self) + self.position = tbl.position + + self.pipes = self.pipes or { {}, {} } + self.loaders = self.loaders or { {}, {} } + self.loaderFilter = self.loaderFilter or { {}, {} } + self.combos = self.combos or { nil, nil } + if (not self.dir) then + self.dir = { {}, {} } + for i = 1, 6, 1 do + self.dir[1][i] = "input" + self.dir[2][i] = "output" + end + end + + self.deployed = self.deployed or false + self.deploy_position = self.deploy_position or nil + self.gdata.pair[2].position = self.gdata.pair[2].position or self.deploy_position or self.position + self.gdata.pair[1].position = self.gdata.pair[1].position or self.position + self.chests = nil + + storage.Harvesters[tbl.key] = self +end + +function HARV:Data() return self.gdata end + +function HARV:GetSize(brank) + local tps = self:Data() + if (tps.fixed_level) then return warptorio.GetHarvesterLevelSizeNum(tps.fixed_level) end + local tcn = tps.tech + local lv = (brank and self.rank or warptorio.GetPlatformTechLevel(tcn)) + return warptorio.GetHarvesterLevelSize(lv) +end + +function HARV:GetBaseArea(z, rank) + z = z or self:GetSize(rank) - 1 + return vector.square(self.position, vector(z, z)) +end + +function HARV:GetDeployArea(z, rank) + z = z or self:GetSize(rank) - 2 + return vector.square(vector.pos(self.deploy_position), vector(z, z)) +end + +function HARV:CheckTeleporterPairs(bSound) -- Call updates and stuff. Automatically deals with logistics, upgrades and cleaning as-needed with good accuracy + local tps = self:Data() + local wps = warptorio.platform.HarvesterPointData + self:MakePointTeleporter(wps, 1, wps.pair[1], self.position) + if (self.deployed) then + self:MakePointTeleporter(wps, 2, wps.pair[2], self.deploy_position) + end + self:CheckPointLogistics(1) + self:CheckPointLogistics(2) +end + +function HARV:UpgradePlayerInventories() + for k, v in pairs(game.players) do + if (v and v.valid) then + local iv = v.get_main_inventory() + if (iv) then + for i, x in pairs(iv.get_contents()) do + if (x.name:sub(1, 20) == "warptorio-harvestpad" and x.name:sub(22, 22 + self.key:len()) == self.key) then + local lvx = tonumber(x.name:sub(-1, -1)) + if (lvx < lv) then + iv.remove { name = x.name, count = x.count } + iv.insert { name = cls, count = 1 } + elseif (x > 1) then + iv.remove { name = x.name, count = (x.count - 1) } + end + end + end + end + end + end +end + +function HARV:MakePointTeleporter(tps, i, t, pos) + local p = self.points[i] + local f = storage.floor[t.floor].host + + local epos + if (t.prototype) then + local vproto = t.prototype + if (tps.energy) then vproto = vproto .. "-" .. (warptorio.GetPlatformTechLevel(tps.energy)) end + local e = p.ent + if (isvalid(e)) then + if (e.surface ~= f) then + self:DestroyPointTeleporter(i) + self:DestroyPointLogistics(i) + elseif (e.name ~= vproto) then + epos = e.position + self:DestroyPointTeleporter(i) + end + end + if (not isvalid(e)) then + local vepos = epos or (pos or t.position) + if (not vepos) then return end + local vpos = ((t.gate and not epos) and f.find_non_colliding_position(vproto, vepos, 0, 1, 1) or vepos) + local varea + if (not t.gate) then + varea = vector.square(vpos, vector(2, 2)) + vector.clean(f, varea) + end + e = entity.protect(entity.create(f, vproto, vpos), t.minable ~= nil and t.minable or false, + t.destructible ~= nil and t.destructible or false) + if (not t.gate) then vector.cleanplayers(f, varea) end + p.ent = e + end + if (p.energy) then + e.energy = e.energy + p.energy + p.energy = nil + end + if (t.sprites) then self:MakePointSprites(tps, i, t.sprites) end + if (t.sprite_arrow) then self:MakePointArrow(tps, i, t.sprite_arrow) end + end + if (epos or not t.gate) then self:CheckPointLogistics(i) end + + cache.force_entity(p.ent, "Harvesters", self.key, "points", i) +end + +function HARV:RunUpgrade() + local tps = self:Data() + local vz = self:GetSize() + local lv = warptorio.GetPlatformTechLevel(tps.tech) + + local f = storage.floor[tps.pair[1].floor].host + + local pos = tps.position + if (not self.deployed) then + local bh = warptorio.platform.floors.harvester.BuildHarvester -- bridges first + if (bh[self.key]) then bh[self.key](f) end + + local lvm = math.max(lv * 2, 2) -- Makes buffer area around the harvesters + vector.LayTiles("warp-tile-concrete", f, vector.square(tps.position, vector(vz + lvm, vz + lvm))) + vector.LayTiles("warptorio-red-concrete", f, vector.square(tps.position, vector(vz - 2, vz - 2))) + + self:CheckTeleporterPairs(true) + end + if (research.has("warptorio-logistics-1")) then + self:DestroyPointLogistics(1) + self:CheckPointLogistics(1) + if (not self.deployed) then + self:DestroyPointLogistics(2) + self:CheckPointLogistics(2) + end + end + self:DestroyCombos() + self:CheckCombo() + + self:UpgradePlayerInventories() -- upgrade their harvestpads for this harvester (if needed) + + self.rank = lv +end + +function HARV:Upgrade() + self.ReadyUpgrade = true + if (not self.deployed) then self:DoUpgrade() end +end + +function HARV:DoUpgrade() + if (self.ReadyUpgrade) then + self.ReadyUpgrade = false + self:RunUpgrade() + end +end + +--[[ Harvester Combinator ]] -- + +function HARV:ConnectCombo() + if (not self.deployed and self:ValidCombos()) then + local red1 = self.combos[1].get_wire_connector(defines.wire_connector_id.circuit_red, true) + local red2 = self.combos[2].get_wire_connector(defines.wire_connector_id.circuit_red, true) + red1.connect_to(red2) + local green1 = self.combos[1].get_wire_connector(defines.wire_connector_id.circuit_green, true) + local green2 = self.combos[2].get_wire_connector(defines.wire_connector_id.circuit_green, true) + green1.connect_to(green2) + -- self.combos[1].connect_neighbour({target_entity=self.combos[2],wire=defines.wire_type.red}) + -- self.combos[1].connect_neighbour({target_entity=self.combos[2],wire=defines.wire_type.green}) + end +end + +function HARV:ValidCombos() return isvalid(self.combos[1]) and isvalid(self.combos[2]) end + +function HARV:CheckCombo() + if (research.has("warptorio-alt-combinator")) then + self:MakeComboA() + self:MakeComboB() + self:ConnectCombo() + end +end + +function HARV:DestroyComboA() + if (isvalid(self.combos[1])) then entity.destroy(self.combos[1]) end + self.combos[1] = nil +end + +function HARV:DestroyComboB() + if (isvalid(self.combos[2])) then entity.destroy(self.combos[2]) end + self.combos[2] = nil +end + +function HARV:DestroyCombos() + self:DestroyComboA() + self:DestroyComboB() +end + +function HARV:MakeComboA() + local vx = self.points[1].ent + local cfg = settings.global.warptorio_combinator_offset.value + local ofv + if (cfg) then ofv = (self.key == "east" and 1 or 1.5) else ofv = 0 end + local vpos = vector.pos(vx.position) + vector(self:GetSize().x / 2 * (self.key == "east" and 1 or -1) + ofv, 0) + vector.clean(vx.surface, vector.square(vpos, vector(0.5, 0.5))) + local e = entity.protect(entity.create(vx.surface, "warptorio-alt-combinator", vpos), false, false) + self.combos[1] = e + + cache.force_entity(e, "Harvesters", self.key, "combos", 1) +end + +function HARV:MakeComboB() + local vx = (isvalid(self.points[2].ent) and self.points[2].ent or self.points[1].ent) + local cfg = settings.global.warptorio_combinator_offset.value + local ofv + if (cfg) then ofv = (self.key == "east" and -2 or -1) else ofv = (self.key == "east" and -1 or 1) end + local vpos = vector.pos(vx.position) + vector(self:GetSize().x / 2 * (self.key == "east" and 1 or -1) + ofv, 0) + vector.clean(vx.surface, vector.square(vpos, vector(0.5, 0.5))) + local e = entity.protect(entity.create(vx.surface, "warptorio-alt-combinator", vpos), false, false) + self.combos[2] = e + + cache.force_entity(e, "Harvesters", self.key, "combos", 2) +end + +--[[ Harvester Logistics ]] -- + +function HARV:MakePointPipes(tps, i, id, pos, f, lddir, belty, vexdir) + local pipe = "warptorio-logistics-pipe" + local v = self.pipes[i][id] + local vpos = vector(pos) + vector(vexdir) + vector(belty) + if (isvalid(v) and (v.surface ~= f or v.position.x ~= vpos.x or v.position.y ~= vpos.y)) then entity.destroy(v) end + if (not isvalid(v)) then + local varea = vector.square(vpos, vector(0.5, 0.5)) + vector.clean(f, varea) + v = entity.protect(entity.create(f, pipe, vpos, lddir), false, false) + self.pipes[i][id] = v + end + + cache.force_entity(v, "Harvesters", self.key, "pipes", i, id) +end + +function HARV:MakePointLoader(tps, i, id, pos, f, belt, lddir, belty, beltsquare, vexdir) + local v = self.loaders[i][id] + if (isvalid(v) and v.name ~= belt) then v.destroy { raise_destroy = true } end + if (not isvalid(v)) then + local vpos = vector(pos) + vector(vexdir) + vector(belty) + local varea = vector.square(vpos, beltsquare) + vector.clean(f, varea) + v = entity.protect(entity.create(f, belt, vpos, lddir), false, false) + v.loader_type = self.dir[i][id] + if v.loader_type == "output" then + v.loader_type = "input" + elseif v.loader_type == "input" then + v.loader_type = "output" + end + self.loaders[i][id] = v + local inv = self.loaderFilter[i][id] + if (inv) then for invx, invy in pairs(inv) do v.set_filter(invx, invy) end end + end + cache.force_entity(v, "Harvesters", self.key, "loaders", i, id) +end + +function HARV:CheckPointLogistics(i) + local tps = self:Data() + local t = tps.pair[i] + if (self.maxloader == 0 or not tps.logs_pattern) then return end + local belt = warptorio.GetBelt() + local pos = tps.position + local f = storage.floor.harvester.host + if (i == 2 and self.deployed) then + f = storage.floor.main.host + pos = self.deploy_position + end + + local ldl = 0 + local lvLogs = research.level("warptorio-logistics") + if (tps.logs and lvLogs > 0) then ldl = ldl + 1 end + if (tps.dualloader and research.has("warptorio-dualloader-1")) then ldl = ldl + 1 end + if (tps.triloader and research.has("warptorio-triloader")) then ldl = ldl + 1 end + if (ldl <= 0) then return end + + local ldodir = (i == 2 and string.compassdef[tps.logs_pattern] or string.compassdef[string.compassopp[tps.logs_pattern]]) + local lddir = (i == 1 and string.compassdef[tps.logs_pattern] or string.compassdef[string.compassopp[tps.logs_pattern]]) + local vcomp = vector.compass[tps.logs_pattern] + --game.print(tps.logs_pattern .. " , lddir: " .. lddir) + local vdir = vcomp * (self:GetSize() / 2) + vcomp * (i == 2 and -1 or 1) + + local beltsquare = vector(1, 0.5) + local pipe = vector(0, (id == 1 and 2 or -2)) + if (tps.logs_pattern == "north" or tps.logs_pattern == "south") then beltsquare = vector(0.5, 1) end + for id = 1, ldl do + local belty = vector(0, (id % 2 == 0 and 1 or 0) + (id % 3 == 0 and -1 or 0)) + self:MakePointLoader(tps, i, id, pos, f, belt, lddir, belty, beltsquare, vdir - vcomp * 0.5) + end + + if (tps.dopipes and lvLogs > 0) then + for id = 1, math.min(lvLogs, 2), 1 do + local belty = vector(0, (id == 1 and 2 or -2)) + (i == 1 and vcomp * -1 or 0) + self:MakePointPipes(tps, i, id, pos, f, lddir, belty, vdir) + end + end +end + +--[[ DEPLOY/RECALL ]] -- +--cleanlanding() + + +function HARV:Recall(bply) -- recall after portal is mined + if (self.recalling) then return end + self.recalling = true + local tps = self:Data() + if (not self.deployed) then + self:DestroyPointTeleporter(1, false) + self:CheckTeleporterPairs() + self:DoUpgrade() + self:CheckCombo() + self:ConnectCombo() + self.recalling = false + return true + end + local t = tps.pair[i] + --self:CleanLanding() -- clean for loaders and combinators -- done automatically now + --if(isvalid(self.points[2].ent))then self.points[2].ent.destroy() end + --self.points[2].ent=nil + + + + local f = storage.floor.main.host + local ebs = {} + for k, v in pairs(f.find_entities_filtered { type = "character", invert = true, area = self:GetDeployArea(nil, true) }) do + if (v.type ~= "resource" and v ~= self.points[1].ent) then table.insert(ebs, v) end + --v~=self.b and v~=self.a and (v.name=="warptorio-combinator" or v.name:sub(1,9)~="warptorio") )then table.insert(ebs,v) end + end + + local hf = storage.floor.harvester.host + local harvArea = self:GetBaseArea(nil, true) + + + local tbs = {} + local tcs = {} + for k, v in pairs(hf.find_tiles_filtered { area = harvArea }) do + local vpos = vector.add(vector.sub(v.position, self.position), self.deploy_position) + table.insert(tcs, { name = v.name, position = vpos }) + table.insert(tbs, { name = "warptorio-red-concrete", position = v.position }) + end + local dcs = {} + for k, v in pairs(hf.find_decoratives_filtered { area = self:GetBaseArea(nil, true) }) do + local vpos = vector.add(vector.sub(v.position, self.position), self.deploy_position) + table.insert(dcs, { name = v.decorative.name, position = vpos, amount = v.amount }) + end + + + local ecs = {} + for k, v in pairs(hf.find_entities_filtered { area = harvArea, type = "character", invert = true }) do + if (v and v.valid and v ~= self.points[1].ent and v ~= self.points[2].ent and not entity.shouldClean(v) and not cache.get_entity(v) and v.type ~= "resource") then + table.insert(ecs, v) + end + end + + + + local blacktbl = {} + for k, v in pairs(ebs) do + if (table.HasValue(warptorio.GetWarpBlacklist(), v.name)) then + table.insert(blacktbl, v) + ebs[k] = nil + end + end + for k, v in pairs(ebs) do + if (table.HasValue(warptorio.GetModTable("harvester_blacklist"), v.name)) then + table.insert(blacktbl, v) + ebs[k] = nil + end + end + + for k, v in pairs(ecs) do + if (table.HasValue(warptorio.GetWarpBlacklist(), v.name)) then + table.insert(blacktbl, v) + ecs[k] = nil + end + end + for k, v in pairs(ecs) do + if (table.HasValue(warptorio.GetModTable("harvester_blacklist"), v.name)) then + table.insert(blacktbl, v) + ecs[k] = nil + end + end + + + warptorio.Cloned_Entities = {} + warptorio.IsCloning = true + hf.clone_entities { entities = ecs, destination_surface = f, destination_offset = { self.deploy_position.x - self.position.x, self.deploy_position.y - self.position.y }, snap_to_grid = false } + local hfe = warptorio.Cloned_Entities + warptorio.IsCloning = false + warptorio.Cloned_Entities = nil + + + if (#ebs > 0) then for i = #ebs, 1, -1 do if (not ebs[i] or not ebs[i].valid) then table.remove(ebs, i) end end end -- bad ents in table ? + + warptorio.Cloned_Entities = {} + warptorio.IsCloning = true + f.clone_entities { entities = ebs, destination_surface = hf, destination_offset = { self.position.x - self.deploy_position.x, self.position.y - self.deploy_position.y }, snap_to_grid = false } + local fe = warptorio.Cloned_Entities + warptorio.IsCloning = false + warptorio.Cloned_Entities = nil + + local hfm = {} + for k, v in pairs(hfe) do + if (isvalid(v.source) and isvalid(v.destination) and table.HasValue(ecs, v.source)) then + table.insert(hfm, v.source) + end + end + local fm = {} + for k, v in pairs(fe) do + if (isvalid(v.source) and isvalid(v.destination) and table.HasValue(ebs, v.source)) then + table.insert(fm, v.source) + end + end + + for k, v in pairs(fm) do entity.destroy(v) end + for k, v in pairs(hfm) do entity.destroy(v) end + + f.set_tiles(tcs, true) + f.create_decoratives { decoratives = dcs } + + hf.destroy_decoratives { area = harvArea } + + if (bply) then -- players now + local tpply = {} + for k, v in pairs(game.players) do + if (v.character == nil or (v.surface == f and vector.inarea(v.position, self:GetDeployArea(nil, true)))) then + table.insert(tpply, + { v, vector.add(vector.add(vector.mul(self.deploy_position, -1), vector.pos(v.position)), + self.position) }) + end + end + for k, v in pairs(tpply) do + v[1].teleport(f.find_non_colliding_position("character", { v[2][1], v[2][2] }, 0, 1), + hf) + end + end + + --vector.LayTiles("warp-tile-concrete",hf,self:GetBaseArea(self:GetSize()+2)) + --vector.LayTiles("warptorio-red-concrete",hf,self:GetBaseArea()) + hf.set_tiles(tbs, true) + self.deployed = false + self:DestroyComboB() + self:DestroyPointTeleporter(1, false) + self:DestroyPointTeleporter(2, false) + self:CheckTeleporterPairs() + + self:DoUpgrade() + self:CheckCombo() + self:ConnectCombo() + self.recalling = false +end + +function HARV:Deploy(surf, pos) -- deploy over a harvester platform + if (self.deployed) then return false end + local f = surf + if (f ~= warptorio.GetMainSurface()) then + game.print({ "warptorio.harvester-placement-error" }) + return false + end + --game.print("deployed at: " .. serpent.line(pos)) + self.deploy_position = vector.pos(pos) + local hf = storage.floor.harvester.host + + local ebs = hf.find_entities_filtered { type = "character", invert = true, area = self:GetBaseArea() } + + local planetArea = self:GetDeployArea() + + local tcs = {} + for x = planetArea[1][1], planetArea[2][1] do + for y = planetArea[1][2], planetArea[2][2] do + local v = f.get_tile(x, y) + local vpos = vector.add(vector.sub(vector(x, y), self.deploy_position), self.position) + table.insert(tcs, { name = v.name, position = vpos }) + end + end + local dcs = {} + for k, v in pairs(f.find_decoratives_filtered { area = self:GetDeployArea(self:GetSize() - 3) }) do + local vpos = vector.add(vector.sub(v.position, self.deploy_position), self.position) + table.insert(dcs, { name = v.decorative.name, position = vpos, amount = v.amount }) + end + local ecs = {} + for k, v in pairs(f.find_entities_filtered { area = planetArea, type = { "construction-robot", "logistic-robot", "character" }, invert = true }) do + if (v.type ~= "resource" and v.name:sub(1, 9) ~= ("warptorio")) then + table.insert(ecs, v) + end + end + + hf.set_tiles(tcs, true) + hf.create_decoratives { decoratives = dcs } + + local ebsc = #ebs + local ecsc = #ecs + + local blacktbl = {} + --for k,v in pairs(ebs)do if(isvalid(v))then if(table.HasValue(warptorio.GetWarpBlacklist(),v.name))then table.insert(blacktbl,v) ebs[k]=nil end end end + --for k,v in pairs(ebs)do if(isvalid(v))then if(table.HasValue(warptorio.GetModTable("harvester_blacklist"),v.name))then table.insert(blacktbl,v) ebs[k]=nil end end end + + --for k,v in pairs(ecs)do if(isvalid(v))then if(table.HasValue(warptorio.GetWarpBlacklist(),v.name))then table.insert(blacktbl,v) ecs[k]=nil end end end + --for k,v in pairs(ecs)do if(isvalid(v))then if(table.HasValue(warptorio.GetModTable("harvester_blacklist"),v.name))then table.insert(blacktbl,v) ecs[k]=nil end end end + + if (ecsc > 0) then for i = ecsc, 1, -1 do if (not ecs[i] or not ecs[i].valid) then table.remove(ecs, i) end end end -- bad ents in table ? + + warptorio.Cloned_Entities = {} + warptorio.IsCloning = true + -- f.clone_entities { entities = ecs, destination_surface = hf, destination_offset = vector.mul(vector.sub(self.position, self.deploy_position), -1), snap_to_grid = false } + f.clone_entities { entities = ecs, destination_surface = hf, destination_offset = { self.deploy_position.x - self.position.x, self.deploy_position.y - self.position.y }, snap_to_grid = false } + local fe = warptorio.Cloned_Entities + warptorio.IsCloning = false + warptorio.Cloned_Entities = nil + + if (ebsc > 0) then for i = ebsc, 1, -1 do if (not ebs[i] or not ebs[i].valid) then table.remove(ebs, i) end end end -- bad ents in table ? + + vector.LayTiles("warptorio-red-concrete", f, self:GetDeployArea()) + + -- this doesnt really work + + warptorio.Cloned_Entities = {} + warptorio.IsCloning = true + -- hf.clone_entities { entities = ebs, destination_surface = f, destination_offset = vector.mul(vector.sub(self.position, self.deploy_position), -1), snap_to_grid = false } + hf.clone_entities { entities = ebs, destination_surface = f, destination_offset = { self.deploy_position.x - self.position.x, self.deploy_position.y - self.position.y }, snap_to_grid = false } + local hfe = warptorio.Cloned_Entities + warptorio.IsCloning = false + warptorio.Cloned_Entities = nil + + local hfm = {} + for k, v in pairs(hfe) do + if (isvalid(v.source) and isvalid(v.destination) and table.HasValue(ebs, v.source)) then + table.insert(hfm, v.source) + end + end + local fm = {} + for k, v in pairs(fe) do + if (isvalid(v.source) and isvalid(v.destination) and table.HasValue(ecs, v.source)) then + table.insert(fm, v.source) + end + end + + for k, v in pairs(fm) do + if (isvalid(v) and v ~= self.points[1].ent and v ~= self.points[2].ent) then + entity.destroy(v) + end + end + for k, v in pairs(hfm) do + if (isvalid(v) and v ~= self.points[1].ent and v ~= self.points[2].ent) then + entity.destroy(v) + end + end + + for k, v in pairs(blacktbl) do if (v and v.valid) then v.destroy { raise_destroy = true } end end -- cleanup past entities + + vector.clearplayers(f, planetArea) + + self.deployed = true + -- game.print("deployed") + self:CheckTeleporterPairs() +end diff --git a/control_class_rails.lua b/control_class_rails.lua index 5690098..bcae97c 100644 --- a/control_class_rails.lua +++ b/control_class_rails.lua @@ -1,129 +1,232 @@ - -local TRAIL={} TRAIL.__index=TRAIL warptorio.RailMeta=TRAIL -function TRAIL.__init(self,tbl) - self.key=self.key or tbl.key - self.chests={{}} - self.rails={} - self.loaders={{},{},{},{}} - self.chestcontents={} - self.dir="output" - global.Rails[self.key]=self -end - -function TRAIL:Data() return warptorio.platform.rails[self.key] end - -function TRAIL:MakeRails() - local f=warptorio.GetMainSurface() - local tps=self:Data() - if(not isvalid(self.rails[1]) or not isvalid(self.rails[2]))then vector.clean(f,vector.square(tps.railpos,vector(1,1))) end - if(not isvalid(self.rails[1]))then self.rails[1]=entity.protect(entity.spawn(f,"straight-rail",tps.railpos,defines.direction.south),false,false) end - if(not isvalid(self.rails[2]))then self.rails[2]=entity.protect(entity.spawn(f,"straight-rail",tps.railpos,defines.direction.east),false,false) end -end - -function TRAIL:MakeChests() - local ccls=warptorio.GetChest(self.dir) - local tps=self:Data() - local f=global.floor[tps.floor].host - for i,px in pairs(vector.compasscorn)do - local v=self.chests[1][i] - if(isvalid(v) and v.name~=ccls)then self.chestcontents[i]=v.get_inventory(defines.inventory.chest).get_contents() v.destroy{raise_destroy=true} end - if(not isvalid(v))then - local vpos=tps.chestpos+px*0.5 - local varea=vector.square(vpos,vector(0.5,0.5)) - vector.clean(f,varea) - v=entity.protect(entity.create(f,ccls,vpos),false,false) - self.chests[1][i]=v - local inv=self.chestcontents[i] - if(inv)then local cv=v.get_inventory(defines.inventory.chest) for x,y in pairs(inv)do cv.insert{name=x,count=y} end self.chestcontents[i]=nil end - end - cache.get_raise_type("types",v.type,v,"Rails",self.key,"chests",1,i) - end -end - -function TRAIL:Rotate() self:MakeChests() for i,tbl in pairs(self.loaders)do for k,v in pairs(tbl)do v.loader_type=self.dir end end end - - -function TRAIL:MakeLoaders() - local tps=self:Data() - local f=global.floor[tps.floor].host - local bcls=warptorio.GetBelt(self.dir) - for i,b in pairs(tps.logs)do if(b)then - local cd=vector.compass[string.compass[i]]*2 - - for x=1,2,1 do - local v=self.loaders[i][x] - if(isvalid(v) and v.name~=bcls)then entity.destroy(v) end - if(not isvalid(v))then - local vang=(((i-1)*2)+4)%8 - local vpos=tps.chestpos+cd+vector.compassall[string.compassall[((vang+2)%8)+1]]*(x==1 and 0.5 or -0.5) - local varea=vector.square(vpos,vector((i==1 or i==3) and 0.5 or 1,(i==1 or i==3) and 1 or 0.5)) - vector.clean(f,varea) - v=entity.protect(entity.create(f,bcls,vpos,vang),false,false) - v.loader_type=self.dir - self.loaders[i][x]=v - end - cache.force_entity(v,"Rails",self.key,"loaders",i,x) - end - end end -end - - -function TRAIL:DoMakes() self:MakeRails() self:MakeChests() self:MakeLoaders() end - --- Warp Rail Logistics - - -function TRAIL:SplitItem(u,n) local c=n local cx=0 local cinv={} local ui={name=k,count=n} - for k,v in pairs(self.chests[1])do local iv=v.get_inventory(defines.inventory.chest) if(iv.can_insert(u))then cinv[k]=iv end end local tcn=table_size(cinv) - for k,v in pairs(cinv)do if(c>0)then local w=v.insert{name=u,count=math.ceil(c/tcn)} cx=cx+w c=c-w tcn=tcn-1 end end - return cx -end - -function TRAIL:UnloadLogistics(e) for _,r in pairs(e)do - local inv=r.get_inventory(defines.inventory.cargo_wagon) for k,v in pairs(inv.get_contents())do local ct=self:SplitItem(k,v) if(ct>0)then inv.remove({name=k,count=ct}) end end -end end - -function TRAIL:LoadLogistics(e) - local inv={} for k,v in pairs(self.chests[1])do inv[k]=v.get_inventory(defines.inventory.chest) end - local ct={} for k,v in pairs(inv)do for a,b in pairs(v.get_contents())do ct[a]=(ct[a] or 0)+b end v.clear() end - for _,r in pairs(e)do local tr=r.get_inventory(defines.inventory.cargo_wagon) for k,v in pairs(ct)do ct[k]=v-(tr.insert{name=k,count=v}) end end - local ci for a,b in pairs(ct)do local g=b ci=#inv - for k,v in pairs(inv)do if(ci>0)then local gci=math.ceil(g/ci) if(gci>0)then local w=v.insert{name=a,count=math.ceil(g/ci)} ci=ci-1 g=g-w end end end - end -end -function TRAIL:BalanceChests() local inv={} for k,v in pairs(self.chests[1])do if(isvalid(v))then inv[k]=v.get_inventory(defines.inventory.chest) end end if(table_size(inv)>0)then - local ct={} for k,v in pairs(inv)do for a,b in pairs(v.get_contents())do ct[a]=(ct[a] or 0)+b end v.clear() end - local ci for a,b in pairs(ct)do local g=b ci=table_size(inv) for k,v in pairs(inv)do - local gci=math.ceil(g/ci) if(gci>0)then local w=v.insert{name=a,count=math.ceil(g/ci)} ci=ci-1 g=g-w end - end end -end end - -function TRAIL:TickLogistics() local f=global.floor.main.host if(not f.valid)then return end local c=self:Data().railpos - local e=f.find_entities_filtered{name="cargo-wagon",area={{c.x-1,c.y-1},{c.x+1,c.y+1}} } - if(table_size(e)>0)then if(self.dir=="output")then self:UnloadLogistics(e) self:BalanceChests() else self:LoadLogistics(e) end else self:BalanceChests() end -end - - -events.on_tick(3,0,"TickRails",function(ev) for k,v in pairs(global.Rails)do v:TickLogistics() end end) ---[[ old stuff - - --- Warp Rail Constructor - -function warptorio.BuildRailCorner(cn) local r=gwarptorio.Rails[cn] --if(true) then return end - if(not r)then r=trail(cn) - local f,fp=warptorio.GetFactorySurface(),warptorio.GetMainSurface() local c,co,cl=platform.railCorner[cn],platform.railOffset[cn],platform.railLoader[cn] - local vec,cx=vector(2,2),c+co - local sq=vector.square(cx,vec) - vector.clear(fp,sq) vector.clear(f,sq) cx=c+vector(-1,-1) vector.clear(f,vector.square(cx,vec)) vector.clear(f,vector.square(cx+cl[1],vec)) vector.clear(f,vector.square(cx+cl[2],vec)) - end - r:DoMakes() -end - -function warptorio.BuildRails() warptorio.BuildRailCorner("nw") warptorio.BuildRailCorner("sw") warptorio.BuildRailCorner("ne") warptorio.BuildRailCorner("se") end --for k,v in pairs(warptorio.railCorn)do warptorio.BuildRailCorner(k) end end - - - -]] - - +local TRAIL = {} +TRAIL.__index = TRAIL +warptorio.RailMeta = TRAIL +function TRAIL.__init(self, tbl) + self.key = self.key or tbl.key + self.chests = { {} } + self.rails = {} + self.loaders = { {}, {}, {}, {} } + self.chestcontents = {} + self.dir = "output" + storage.Rails[self.key] = self +end + +function TRAIL:Data() + return warptorio.platform.rails[self.key] +end + +function TRAIL:MakeRails() + local f = warptorio.GetMainSurface() + local tps = self:Data() + if (not isvalid(self.rails[1]) or not isvalid(self.rails[2])) then + vector.clean(f, + vector.square(tps.railpos, vector(1, 1))) + end + if (not isvalid(self.rails[1])) then + self.rails[1] = entity.protect( + entity.spawn(f, "straight-rail", tps.railpos, defines.direction.south), false, false) + end + if (not isvalid(self.rails[2])) then + self.rails[2] = entity.protect( + entity.spawn(f, "straight-rail", tps.railpos, defines.direction.east), false, false) + end +end + +function TRAIL:MakeChests() + local ccls = warptorio.GetChest(self.dir) + local tps = self:Data() + local f = storage.floor[tps.floor].host + for i, px in pairs(vector.compasscorn) do + local v = self.chests[1][i] + if (isvalid(v) and v.name ~= ccls) then + self.chestcontents[i] = v.get_inventory(defines.inventory.chest).get_contents() + v.destroy { raise_destroy = true } + end + if (not isvalid(v)) then + local vpos = tps.chestpos + px * 0.5 + local varea = vector.square(vpos, vector(0.5, 0.5)) + vector.clean(f, varea) + v = entity.protect(entity.create(f, ccls, vpos), false, false) + self.chests[1][i] = v + local inv = self.chestcontents[i] + if (inv) then + local cv = v.get_inventory(defines.inventory.chest) + for x, y in pairs(inv) do cv.insert { name = x, count = y } end + self.chestcontents[i] = nil + end + end + cache.get_raise_type("types", v.type, v, "Rails", self.key, "chests", 1, i) + end +end + +function TRAIL:Rotate() + self:MakeChests() + for i, tbl in pairs(self.loaders) do + for k, v in pairs(tbl) do + v.loader_type = self.dir + end + end +end + +function TRAIL:MakeLoaders() + local tps = self:Data() + local f = storage.floor[tps.floor].host + local bcls = warptorio.GetBelt(self.dir) + for i, b in pairs(tps.logs) do + if (b) then + local cd = vector.compass[string.compass[i]] * 2 + for x = 1, 2, 1 do + local v = self.loaders[i][x] + if (isvalid(v) and v.name ~= bcls) then + entity.destroy(v) + end + if (not isvalid(v)) then + local vang = (((i - 1) * 2) + 4) % 8 + local vpos = tps.chestpos + cd + + vector.compassall[string.compassall[((vang + 2) % 8) + 1]] * (x == 1 and 0.5 or -0.5) + local varea = vector.square(vpos, vector((i == 1 or i == 3) and 0.5 or 1, (i == 1 or i == 3) and 1 or + 0.5)) + vector.clean(f, varea) + v = entity.protect(entity.create(f, bcls, vpos, (vang * 2 + 8) % 16), false, false) + v.loader_type = self.dir + self.loaders[i][x] = v + end + cache.force_entity(v, "Rails", self.key, "loaders", i, x) + end + end + end +end + +function TRAIL:DoMakes() + self:MakeRails() + self:MakeChests() + self:MakeLoaders() +end + +-- Warp Rail Logistics + +function TRAIL:SplitItem(u, n) + local c = n + local cx = 0 + local cinv = {} + local ui = { name = k, count = n } + for k, v in pairs(self.chests[1]) do + local iv = v.get_inventory(defines.inventory.chest) + if (iv.can_insert(u)) then + cinv[k] = iv + end + end + local tcn = table_size(cinv) + for k, v in pairs(cinv) do + if (c > 0) then + local w = v.insert { name = u, count = math.ceil(c / tcn) } + cx = cx + w + c = c - w + tcn = tcn - 1 + end + end + return cx +end + +function TRAIL:UnloadLogistics(e) + for _, r in pairs(e) do + local inv = r.get_inventory(defines.inventory.cargo_wagon) + for k, v in pairs(inv.get_contents()) do + local ct = self:SplitItem(v.name, v.count) + if (ct > 0) then inv.remove({ name = v.name, count = ct }) end + end + end +end + +function TRAIL:LoadLogistics(e) + local inv = {} + for k, v in pairs(self.chests[1]) do inv[k] = v.get_inventory(defines.inventory.chest) end + local ct = {} + for k, v in pairs(inv) do + for a, b in pairs(v.get_contents()) do ct[a] = (ct[a] or 0) + b end + v.clear() + end + for _, r in pairs(e) do + local tr = r.get_inventory(defines.inventory.cargo_wagon) + for k, v in pairs(ct) do ct[k] = v - (tr.insert { name = k, count = v }) end + end + local ci + for a, b in pairs(ct) do + local g = b + ci = #inv + for k, v in pairs(inv) do + if (ci > 0) then + local gci = math.ceil(g / ci) + if (gci > 0) then + local w = v.insert { name = a, count = math.ceil(g / ci) } + ci = ci - 1 + g = g - w + end + end + end + end +end + +function TRAIL:BalanceChests() + local inv = {} + for k, v in pairs(self.chests[1]) do if (isvalid(v)) then inv[k] = v.get_inventory(defines.inventory.chest) end end + if (table_size(inv) > 0) then + local ct = {} + for k, v in pairs(inv) do + for a, b in pairs(v.get_contents()) do ct[b] = (ct[b] or 0) + b.count end + v.clear() + end + local ci + for a, b in pairs(ct) do + local g = b + ci = table_size(inv) + for k, v in pairs(inv) do + local gci = math.ceil(g / ci) + if (gci > 0) then + local w = v.insert { name = a.name, count = math.ceil(g / ci) } + ci = ci - 1 + g = g - w + end + end + end + end +end + +function TRAIL:TickLogistics() + local f = storage.floor.main.host + if (not f.valid) then return end + local c = self:Data().railpos + local e = f.find_entities_filtered { name = "cargo-wagon", area = { { c.x - 1, c.y - 1 }, { c.x + 1, c.y + 1 } } } + if (table_size(e) > 0) then + if (self.dir == "output") then + self:UnloadLogistics(e) + self:BalanceChests() + else + self:LoadLogistics(e) + end + else + self:BalanceChests() + end +end + +events.on_tick(3, 0, "TickRails", function(ev) for k, v in pairs(storage.Rails) do v:TickLogistics() end end) +--[[ old stuff + + +-- Warp Rail Constructor + +function warptorio.BuildRailCorner(cn) local r=gwarptorio.Rails[cn] --if(true) then return end + if(not r)then r=trail(cn) + local f,fp=warptorio.GetFactorySurface(),warptorio.GetMainSurface() local c,co,cl=platform.railCorner[cn],platform.railOffset[cn],platform.railLoader[cn] + local vec,cx=vector(2,2),c+co + local sq=vector.square(cx,vec) + vector.clear(fp,sq) vector.clear(f,sq) cx=c+vector(-1,-1) vector.clear(f,vector.square(cx,vec)) vector.clear(f,vector.square(cx+cl[1],vec)) vector.clear(f,vector.square(cx+cl[2],vec)) + end + r:DoMakes() +end + +function warptorio.BuildRails() warptorio.BuildRailCorner("nw") warptorio.BuildRailCorner("sw") warptorio.BuildRailCorner("ne") warptorio.BuildRailCorner("se") end --for k,v in pairs(warptorio.railCorn)do warptorio.BuildRailCorner(k) end end + + + +]] diff --git a/control_class_teleporter.lua b/control_class_teleporter.lua index 9bf5d13..66d04c0 100644 --- a/control_class_teleporter.lua +++ b/control_class_teleporter.lua @@ -1,404 +1,547 @@ - - -function warptorio.GetPlatformTechLevel(nm) local tc=warptorio.platform.techs[nm] if(not tc)then return false end - if(tc.level_range or tc.levels)then return research.level(tc.tech) else return research.has(tc.tech) end -end -function warptorio.GetPlatformTechAmount(nm) local tc=warptorio.platform.techs[nm] if(not tc)then return false end - local lv=warptorio.GetPlatformTechLevel(nm) or 0 - if(tc.levels)then return tc.levels[lv] end -end - -function warptorio.GetPlatformResearches() -- cache stuff - if(warptorio.PlatformResearches)then return warptorio.PlatformResearches end - warptorio.PlatformResearches={} - for vi,v in pairs(warptorio.platform.techs)do - v.key=v.key or vi - if(v.levels)then for k in pairs(v.levels)do warptorio.PlatformResearches[v.tech.."-"..k]=v end - elseif(v.level_range)then for i=v.level_range[1],v.level_range[2] do warptorio.PlatformResearches[v.tech.."-"..i]=v end - else warptorio.PlatformResearches[v.tech]=v - end - end - return warptorio.PlatformResearches -end - -function warptorio.GetPlatformResearch(nm) return warptorio.GetPlatformResearches()[nm] end - -warptorio.ResearchEffects={} - - -function warptorio.ResearchEffects.retile(floors) - for k,v in pairs(floors)do warptorio.ConstructFloor(v,true) end -end -function warptorio.ResearchEffects.rehazard(floors) - for k,v in pairs(floors)do warptorio.ConstructFloorHazard(v) end -end -function warptorio.ResearchEffects.unlock_teleporters(tpt) if(not istable(tpt))then tpt={tpt} end - for i,nm in pairs(tpt)do - local tpx=warptorio.platform.teleporters[nm] - local gps=global.Teleporters[nm] - if(not gps)then - --game.print("New teleporter: " .. tostring(nm)) - gps=new(warptorio.TeleporterMeta,tpx) - end - gps:CheckTeleporterPairs(true) - end -end -function warptorio.ResearchEffects.unlock_rails(tpt) if(not istable(tpt))then tpt={tpt} end - for i,nm in pairs(tpt)do - local tpx=warptorio.platform.rails[nm] - local gps=global.Rails[nm] - if(not gps)then - --game.print("New Rails: " .. tostring(nm)) - gps=new(warptorio.RailMeta,tpx) - end - gps:DoMakes() - end -end - -function warptorio.ResearchEffects.harvesters(hvt) - for i,nm in pairs(hvt)do - local tpx=warptorio.platform.harvesters[nm] - local gps=global.Harvesters[nm] - if(not gps)then - gps=new(warptorio.HarvesterMeta,tpx) - end - gps:Upgrade() - end -end -function warptorio.ResearchEffects.upgrade_energy(tgt) - if(tgt==true)then - for k,v in pairs(global.Teleporters)do v:CheckTeleporterPairs(true) end - for k,v in pairs(global.Harvesters)do v:CheckTeleporterPairs(true) end - else - for k,v in pairs(tgt)do if(global.Teleporters[v])then global.Teleporters[v]:CheckTeleporterPairs(true) end end - end -end -function warptorio.ResearchEffects.upgrade_logistics(tgt) - if(tgt==true)then - for k,v in pairs(global.Teleporters)do v:CheckTeleporterPairs(true) end - for k,v in pairs(global.Harvesters)do v:CheckTeleporterPairs(true) end - for k,v in pairs(global.Rails)do v:DoMakes() end - else - for k,v in pairs(tgt)do if(global.Teleporters[v])then global.Teleporters[v]:CheckTeleporterPairs(true) end end - end -end -function warptorio.ResearchEffects.do_combinators() - for k,v in pairs(global.Harvesters)do v:CheckCombo(true) end -end -function warptorio.ResearchEffects.special(spt) - for k,v in pairs(spt)do warptorio.CheckPlatformSpecials(global.floor[v]) end -end -function warptorio.ResearchEffects.reactor(b,lv) - local m=global.floor.main players.playsound("warp_in",m.host) - for i=1,3,1 do for x,ply in pairs(game.players)do ply.print{"warptorio_lore."..lv .."_"..i} end end - - if(lv<6)then global.warp_auto_time=global.warp_auto_time+60*10 end - - if(lv>=8)then warptorio.ResetHUD() end - - --warptorio.CheckPlatformSpecials(global.floor.main) -end -function warptorio.ResearchEffects.ability(tgt) - warptorio.ResetHUD() -end -function warptorio.ResearchEffects.unlock_homeworld() - warptorio.ResetHUD() -end -function warptorio.ResearchEffects.unlock_toolbar() - warptorio.ResetHUD() -end - - -function warptorio.DoResearchEffects(fx,lv) - for k,v in pairs(fx)do - if(warptorio.ResearchEffects[k])then warptorio.ResearchEffects[k](v,lv) end - end -end -function warptorio.ResearchFinished(ev) - local rs=ev.research - --game.print("researched_finished: " .. rs.name) - local u=warptorio.GetPlatformResearch(rs.name) - if(u)then - local lv=warptorio.GetPlatformTechLevel(u.key) or 0 - --if(u.first_effect)then game.print("testing: " .. tostring(lv) .. " , " .. serpent.line(u)) end - - if(u.first_effect and (u.levels and (u.levels[0] and lv==0 or lv==1) or (u.level_range and lv==u.level_range[1])) )then - warptorio.DoResearchEffects(u.first_effect,lv) - --game.print("first effect") - end - if(u.effect)then warptorio.DoResearchEffects(u.effect,lv) end - if(u.lv_effect)then local lvt=u.lv_effect[lv] if(lvt)then warptorio.DoResearchEffects(lvt,lv) end end - - end - - warptorio.ConstructHazards() -end - - -events.on_event(defines.events.on_research_finished,warptorio.ResearchFinished) - - -local platform=warptorio.platform - ---[[ Warp Teleporters ]]-- - -local TELL={} TELL.__index=TELL warptorio.TeleporterMeta=TELL -function TELL.__init(self,tbl,bHarvester) - self.key=self.key or tbl.key - --self.maxloader=(tbl.logs and 1 or 0)+(tbl.dualloader and 1 or 0)+(tbl.triloader and 1 or 0) - --if(not tbl.prototype)then error(serpent.block(self)) end - self.offloader=(tbl.prototype and 1 or 0) - - self.points=self.points or {{},{}} - self.chestcontents=self.chestcontents or {{},{}} - self.loaders=self.loaders or {{},{}} - self.pipes=self.pipes or {{},{}} - self.chests=self.chests or {{},{}} - if(not self.dir)then self.dir={{},{}} for i=1,6,1 do self.dir[1][i]="input" self.dir[2][i]="output" end end - self.loaderFilter=self.loaderFilter or {{},{}} - self.sprites=self.sprites or {{},{}} - self.sprite_arrows=self.sprite_arrows or {nil,nil} - if(not bHarvester)then global.Teleporters[self.key]=self end -end -function TELL:Data() return warptorio.platform.teleporters[self.key] end - -function TELL:ValidA() return isvalid(self.points[1].ent) end -function TELL:ValidB() return isvalid(self.points[2].ent) end - -function TELL:ConnectCircuit() local p=self.points - if(self:ValidA() and self:ValidB())then - p[1].ent.connect_neighbour({target_entity=p[2].ent,wire=defines.wire_type.red}) - p[1].ent.connect_neighbour({target_entity=p[2].ent,wire=defines.wire_type.green}) - end -end - -function TELL:CheckTeleporterPairs(bSound) -- Call updates and stuff. Automatically deals with logistics, upgrades and cleaning as-needed with good accuracy - local tps=self:Data() - if(tps.pair)then for i,t in pairs(tps.pair)do local pi=self.points[i] self:MakePointTeleporter(tps,i,t,(t.gate and isvalid(pi.ent)) and pi.ent.position or nil) end end - local ca=cache.get_entity(self.points[1].ent) - local cb=cache.get_entity(self.points[2].ent) - if(ca and cb)then ca.teleport_dest=cb.host cb.teleport_dest=ca.host else if(ca)then ca.teleport_dest=nil end if(cb)then cb.teleport_dest=nil end end - if(tps.circuit)then self:ConnectCircuit() end -end - - - ---[[ Teleporter Logistics & Spawning Stuff ]]-- - - -function TELL:DestroyPointTeleporter(i,rd) - local e=self.points[i].ent if(isvalid(e))then self.points[i].energy=e.energy entity.destroy(e,rd) end - self:DestroyPointSprites(i) -end -function TELL:DestroyPointSprites(i) - if(self.sprites and self.sprites[i])then for k,v in pairs(self.sprites[i])do if(rendering.is_valid(v))then rendering.destroy(v) self.sprites[i][k]=nil end end end - if(self.sprite_arrows and self.sprite_arrows[i])then if(rendering.is_valid(self.sprite_arrows[i]))then rendering.destroy(self.sprite_arrows[i]) self.sprite_arrows[i]=nil end end -end -function TELL:CheckPointSprites(i) - local tps=self:Data() local t=tps.pair[i] - if(warptorio.setting("hide_sprites"))then self:DestroyPointSprites(i) else - if(t.sprites)then self:MakePointSprites(tps,i,t.sprites) end - if(t.sprite_arrow)then self:MakePointArrow(tps,i,t.sprite_arrow) end - end -end - -function TELL:MakePointTeleporter(tps,i,t,pos) - local p=self.points[i] - local f=global.floor[t.floor].host - - local epos - if(t.prototype)then - local vproto=t.prototype - if(tps.energy)then vproto=vproto.."-"..warptorio.GetPlatformTechLevel(tps.energy) end - local e=p.ent - if(isvalid(e))then - if(e.surface~=f)then self:DestroyPointTeleporter(i) self:DestroyPointLogistics(i) - elseif(e.name~=vproto)then epos=e.position self:DestroyPointTeleporter(i) - end - end - if(not isvalid(e))then - local vepos=epos or (pos or t.position) - if(not vepos)then return end - local vpos=((t.gate and not epos) and f.find_non_colliding_position(vproto,vepos,0,1,1) or vepos) - --error(serpent.line(vpos)) - local varea - if(not t.gate)then varea=vector.square(vpos+vector(0.5,0.5),vector(2,2)) vector.clean(f,varea) end - e=entity.protect(entity.create(f,vproto,vpos),t.minable~=nil and t.minable or false,t.destructible~=nil and t.destructible or false) - if(not t.gate)then vector.cleanplayers(f,varea) end - p.ent=e - end - if(p.energy)then e.energy=e.energy+p.energy p.energy=nil end - if(t.sprites)then self:MakePointSprites(tps,i,t.sprites) end - if(t.sprite_arrow)then self:MakePointArrow(tps,i,t.sprite_arrow) end - end - if(epos or not t.gate)then self:CheckPointLogistics(i) end - - local ce=cache.force_entity(p.ent,"Teleporters",self.key,"points",i) -end - - -warptorio.arrowSprite={sprite="utility/medium_gui_arrow",target_offset={0.75,-0.75},x_scale=0.4,y_scale=0.4} - -function TELL:MakePointArrow(tps,i,arrow) - local spid=self.sprite_arrows[i] - if(spid and rendering.is_valid(spid))then return end - local tp=self.points[i].ent - local t=table.deepcopy(warptorio.arrowSprite) - t.surface=tp.surface - t.target=tp - t.only_in_alt_mode=true - t.render_layer="higher-object-above" - t.orientation=(arrow=="down" and 0.5 or 0) - self.sprite_arrows[i]=rendering.draw_sprite(t) -end - -function TELL:MakePointSprites(tps,i,sprites) - for k,v in pairs(sprites)do - local spid=self.sprites[i][k] - if(not (spid and rendering.is_valid(spid)))then - local tp=self.points[i].ent - local t=table.deepcopy(v) - t.surface=tp.surface t.target=tp t.only_in_alt_mode=true t.render_layer="higher-object-under" - self.sprites[i][k]=rendering.draw_sprite(t) - end - end -end - - -function TELL:GetLoaderDirection() local tps=self:Data() - if(tps.dirsetting)then return warptorio.setting(tps.dirsetting) end - return (tps.staticdir and tps.staticdir or (tps.top and warptorio.setting("loader_top") or warptorio.setting("loader_bottom"))) or "up" -end - -function TELL:DestroyPointLogistics(o) - if(self.chests)then for k,v in pairs(self.chests[o])do self.chestcontents[o][k]=v.get_inventory(defines.inventory.chest).get_contents() entity.destroy(v) self.chests[o][k]=nil end end - for k,v in pairs(self.loaders[o])do if(v and isvalid(v))then - self.loaderFilter[o][k]={} for i=1,v.filter_slot_count,1 do self.loaderFilter[o][k][i]=v.get_filter(i) end entity.destroy(v) - end self.loaders[o][k]=nil end - for k,v in pairs(self.pipes[o])do entity.destroy(v) self.pipes[o][k]=nil end -end - -function TELL:RemakeChestPair(o,k) local e=self.chests[o][k] local ex=warptorio.GetChest(self.dir[o][k]) - if(e and e.name~=ex)then - local v=entity.protect(entity.create(e.surface,ex,e.position),false,false) entity.copy.chest(e,v) - entity.destroy(e) self.chests[o][k]=v if(self.dir[o][k]=="input")then entity.ChestRequestMode(v) end - cache.get_raise_type("types",v.type,v,"Teleporters",self.key,"chests",o,k) - end -end -function TELL:SwapLoaderChests(id) self:RemakeChestPair(1,id) self:RemakeChestPair(2,id) end -function TELL:UpgradeChests() for i=1,6,1 do self:SwapLoaderChests(i) end end - -function TELL:GetTeleporterSize() local d=self:Data() return warptorio.GetTeleporterSize(d.logs,d.dualloader,d.triloader) end -function TELL:GetLogisticsArea(o) return vector.square(o or self:Data().position,self:GetTeleporterSize()) end - - - - -function TELL:MakePointLoader(tps,i,id,ido,pos,f,belt,lddir,chesty,belty,vexdir) - local offld=tps.pair[i].prototype and 1 or 0 - - local v=self.loaders[i][id] - if(isvalid(v) and v.name~=belt)then v.destroy{raise_destroy=true} end - if(not isvalid(v))then - local vpos=vector(pos)+vector((offld+ido)*vexdir,belty) - local varea=vector.square(vpos+vector(0,0.5),vector(1,1)) - vector.clean(f,varea) - v=entity.protect(entity.create(f,belt,vpos,lddir),false,false) - vector.cleanplayers(f,varea) - v.loader_type=self.dir[i][id] - self.loaders[i][id]=v - local inv=self.loaderFilter[i][id] if(inv)then for invx,invy in pairs(inv)do v.set_filter(invx,invy) end end - end - cache.force_entity(v,"Teleporters",self.key,"loaders",i,id) - - local v=self.chests[i][id] - local chest=warptorio.GetChest(self.dir[i][id]) - if(isvalid(v) and v.name~=chest)then self.chestcontents[i][id]=v.get_inventory(defines.inventory.chest).get_contents() v.destroy{raise_destroy=true} end - if(not isvalid(v))then - local vpos=vector(pos)+vector((offld+ido)*vexdir,chesty) - local varea=vector.square(vpos,vector(0.5,0.5)) - vector.clean(f,varea) - v=entity.protect(entity.create(f,chest,vpos),false,false) - vector.cleanplayers(f,varea) - self.chests[i][id]=v - local inv=self.chestcontents[i][id] - if(inv)then local cv=v.get_inventory(defines.inventory.chest) for x,y in pairs(inv)do cv.insert{name=x,count=y} end self.chestcontents[i][id]=nil end - --if(v.type=="logistic-container")then entity.ChestRequestMode(r) end - end - cache.get_raise_type("types",v.type,v,"Teleporters",self.key,"chests",i,id) - - -end -function TELL:MakePointLoaders(tps,i,id,pos,f,belt,lddir,chesty,belty) - if(not tps.oneside or tps.oneside=="right")then self:MakePointLoader(tps,i,id,id,pos,f,belt,lddir,chesty,belty,1) end - if(not tps.oneside or tps.oneside=="left")then self:MakePointLoader(tps,i,id+3,id,pos,f,belt,lddir,chesty,belty,-1) end -end -function TELL:MakePointPipes(tps,i,id,pos,f,dist,vexdir,ido) -- TODO: Initial pipe dir & remember direction - local pipe="warptorio-logistics-pipe" - local v=self.pipes[i][id] - local vpos=vector(pos)+vector(dist*vexdir,2-ido) - local pipedir=(vexdir==1 and 2 or 6) - if(isvalid(v) and (v.surface~=f or v.position.x~=vpos.x or v.position.y~=vpos.y))then pipedir=v.direction entity.destroy(v) end - if(not isvalid(v))then - local varea=vector.square(vpos,vector(0.5,0.5)) - vector.clean(f,varea) - v=entity.protect(entity.create(f,pipe,vpos,pipedir),false,false) - vector.cleanplayers(f,varea) - self.pipes[i][id]=v - end - - cache.force_entity(v,"Teleporters",self.key,"pipes",i,id) -end -function TELL:CheckEmptyPipes() - local ppr={} for a,b in pairs(self.pipes)do for k,v in pairs(b)do if(isvalid(v) and table_size(v.neighbours[1])>=1)then ppr[k]=true end end end - for a,b in pairs(self.pipes)do for k,v in pairs(b)do if(isvalid(v) and not ppr[k])then v.clear_fluid_inside() end end end -end - -function TELL:CheckPointLogistics(i,vxpos) - local tps=self:Data() - local t=tps.pair[i] - if(not tps.logs and not tps.dualloader and not tps.triloader)then return end - local belt=warptorio.GetBelt() - local pos=vxpos or t.position+vector(0.5,0.5) - if(t.gate and not vxpos)then if(not isvalid(self.points[i].ent))then return end pos=vector(self.points[i].ent.position) end - local f=global.floor[t.floor].host - local offld=tps.pair[i].prototype and 1 or 0 - local lddir,chesty,belty - if(self:GetLoaderDirection()=="up")then lddir=defines.direction.north chesty=-1 belty=0 else lddir=defines.direction.south chesty=1 belty=-1 end - local ldl=0 - local lvLogs=research.level("warptorio-logistics") - if(tps.logs and lvLogs>0)then ldl=ldl+1 end - if(tps.dualloader and research.has("warptorio-dualloader-1"))then ldl=ldl+1 end - if(tps.triloader and research.has("warptorio-triloader"))then ldl=ldl+1 end - local can=true - if(t.gate)then -- check if placement area is clear - local vsize=offld+ldl+(tps.dopipes and 1 or 0) - local varea=vector.square(pos,vector(vsize*2,3)) - if(f.count_entities_filtered{area=varea,collision_mask={"object-layer"}} >1)then - f.create_entity{name="flying-text", position=pos, text="Logistics blocked - Needs more space", color={r=1,g=0.5,b=0.5}} - f.play_sound{path="utility/cannot_build",position=pos} - --game.print("Planet Teleporter Gate Logistics were blocked by nearby obstructions") - can=false - end - end - if(can and ldl>0)then for id=1,ldl,1 do - self:MakePointLoaders(tps,i,id,pos,f,belt,lddir,chesty,belty) - end end - if(can and tps.dopipes and lvLogs>0)then for id=1,math.min(lvLogs,3),1 do -- pipes first, it removes the old ones - if(not tps.oneside or tps.oneside=="right")then self:MakePointPipes(tps,i,id,pos,f,ldl+offld+1,1,id) end - if(not tps.oneside or tps.oneside=="left")then self:MakePointPipes(tps,i,id+3,pos,f,ldl+offld+1,-1,id) end - end end -end - ---[[ -function events.on_tick("logistics_teleporters",function(ev) for k,v in pairs(global.Teleporters)do v:TickLogistics() end end end) - -function TELL:TickLogistics() - for k,v in pairs(self.chests[1])do if(isvalid(self.chests[2][k]))then - if(self.dir[1][k]=="input")then warptorio.BalanceLogistics(v,self.chests[2][k]) else warptorio.BalanceLogistics(self.chests[2][k],v) end - end end - for k,v in pairs(self.pipes[1])do if(isvalid(self.pipes[2][k]))then - warptorio.BalanceLogistics(v,self.pipes[2][k]) - end end -end]] - +function warptorio.GetPlatformTechLevel(nm) + local tc = warptorio.platform.techs[nm] + if (not tc) then return false end + if (tc.level_range or tc.levels) then return research.level(tc.tech) else return research.has(tc.tech) end +end + +function warptorio.GetPlatformTechAmount(nm) + local tc = warptorio.platform.techs[nm] + if (not tc) then return false end + local lv = warptorio.GetPlatformTechLevel(nm) or 0 + if (tc.levels) then return tc.levels[lv] end +end + +function warptorio.GetPlatformResearches() -- cache stuff + if (warptorio.PlatformResearches) then return warptorio.PlatformResearches end + warptorio.PlatformResearches = {} + for vi, v in pairs(warptorio.platform.techs) do + v.key = v.key or vi + if (v.levels) then + for k in pairs(v.levels) do warptorio.PlatformResearches[v.tech .. "-" .. k] = v end + elseif (v.level_range) then + for i = v.level_range[1], v.level_range[2] do warptorio.PlatformResearches[v.tech .. "-" .. i] = v end + else + warptorio.PlatformResearches[v.tech] = v + end + end + return warptorio.PlatformResearches +end + +function warptorio.GetPlatformResearch(nm) return warptorio.GetPlatformResearches()[nm] end + +warptorio.ResearchEffects = {} + + +function warptorio.ResearchEffects.retile(floors) + for k, v in pairs(floors) do warptorio.ConstructFloor(v, true) end +end + +function warptorio.ResearchEffects.rehazard(floors) + for k, v in pairs(floors) do warptorio.ConstructFloorHazard(v) end +end + +function warptorio.ResearchEffects.unlock_teleporters(tpt) + if (not istable(tpt)) then tpt = { tpt } end + for i, nm in pairs(tpt) do + local tpx = warptorio.platform.teleporters[nm] + local gps = storage.Teleporters[nm] + if (not gps) then + --game.print("New teleporter: " .. tostring(nm)) + gps = new(warptorio.TeleporterMeta, tpx) + end + gps:CheckTeleporterPairs(true) + end +end + +function warptorio.ResearchEffects.unlock_rails(tpt) + if (not istable(tpt)) then tpt = { tpt } end + for i, nm in pairs(tpt) do + local tpx = warptorio.platform.rails[nm] + local gps = storage.Rails[nm] + if (not gps) then + --game.print("New Rails: " .. tostring(nm)) + gps = new(warptorio.RailMeta, tpx) + end + gps:DoMakes() + end +end + +function warptorio.ResearchEffects.harvesters(hvt) + for i, nm in pairs(hvt) do + local tpx = warptorio.platform.harvesters[nm] + local gps = storage.Harvesters[nm] + if (not gps) then + gps = new(warptorio.HarvesterMeta, tpx) + end + gps:Upgrade() + end +end + +function warptorio.ResearchEffects.upgrade_energy(tgt) + if (tgt == true) then + for k, v in pairs(storage.Teleporters) do v:CheckTeleporterPairs(true) end + for k, v in pairs(storage.Harvesters) do v:CheckTeleporterPairs(true) end + else + for k, v in pairs(tgt) do if (storage.Teleporters[v]) then storage.Teleporters[v]:CheckTeleporterPairs(true) end end + end +end + +function warptorio.ResearchEffects.upgrade_logistics(tgt) + if (tgt == true) then + for k, v in pairs(storage.Teleporters) do v:CheckTeleporterPairs(true) end + for k, v in pairs(storage.Harvesters) do v:CheckTeleporterPairs(true) end + for k, v in pairs(storage.Rails) do v:DoMakes() end + else + for k, v in pairs(tgt) do if (storage.Teleporters[v]) then storage.Teleporters[v]:CheckTeleporterPairs(true) end end + end +end + +function warptorio.ResearchEffects.do_combinators() + for k, v in pairs(storage.Harvesters) do v:CheckCombo(true) end +end + +function warptorio.ResearchEffects.special(spt) + for k, v in pairs(spt) do warptorio.CheckPlatformSpecials(storage.floor[v]) end +end + +function warptorio.ResearchEffects.reactor(b, lv) + local m = storage.floor.main + players.playsound("warp_in", m.host) + for i = 1, 3, 1 do for x, ply in pairs(game.players) do ply.print { "warptorio_lore." .. lv .. "_" .. i } end end + + if (lv < 6) then storage.warp_auto_time = storage.warp_auto_time + 60 * 10 end + + if (lv >= 8) then warptorio.ResetHUD() end + + --warptorio.CheckPlatformSpecials(storage.floor.main) +end + +function warptorio.ResearchEffects.ability(tgt) + warptorio.ResetHUD() +end + +function warptorio.ResearchEffects.unlock_homeworld() + warptorio.ResetHUD() +end + +function warptorio.ResearchEffects.unlock_toolbar() + warptorio.ResetHUD() +end + +function warptorio.DoResearchEffects(fx, lv) + for k, v in pairs(fx) do + if (warptorio.ResearchEffects[k]) then warptorio.ResearchEffects[k](v, lv) end + end +end + +function warptorio.ResearchFinished(ev) + local rs = ev.research + --game.print("researched_finished: " .. rs.name) + local u = warptorio.GetPlatformResearch(rs.name) + if (u) then + local lv = warptorio.GetPlatformTechLevel(u.key) or 0 + --if(u.first_effect)then game.print("testing: " .. tostring(lv) .. " , " .. serpent.line(u)) end + + if (u.first_effect and (u.levels and (u.levels[0] and lv == 0 or lv == 1) or (u.level_range and lv == u.level_range[1]))) then + warptorio.DoResearchEffects(u.first_effect, lv) + --game.print("first effect") + end + if (u.effect) then warptorio.DoResearchEffects(u.effect, lv) end + if (u.lv_effect) then + local lvt = u.lv_effect[lv] + if (lvt) then warptorio.DoResearchEffects(lvt, lv) end + end + end + + warptorio.ConstructHazards() +end + +events.on_event(defines.events.on_research_finished, warptorio.ResearchFinished) + + +local platform = warptorio.platform + +--[[ Warp Teleporters ]] -- + +local TELL = {} +TELL.__index = TELL +warptorio.TeleporterMeta = TELL +function TELL.__init(self, tbl, bHarvester) + self.key = self.key or tbl.key + --self.maxloader=(tbl.logs and 1 or 0)+(tbl.dualloader and 1 or 0)+(tbl.triloader and 1 or 0) + --if(not tbl.prototype)then error(serpent.block(self)) end + self.offloader = (tbl.prototype and 1 or 0) + + self.points = self.points or { {}, {} } + self.chestcontents = self.chestcontents or { {}, {} } + self.loaders = self.loaders or { {}, {} } + self.pipes = self.pipes or { {}, {} } + self.chests = self.chests or { {}, {} } + if (not self.dir) then + self.dir = { {}, {} } + for i = 1, 6, 1 do + self.dir[1][i] = "input" + self.dir[2][i] = "output" + end + end + self.loaderFilter = self.loaderFilter or { {}, {} } + self.sprites = self.sprites or { {}, {} } + self.sprite_arrows = self.sprite_arrows or { nil, nil } + if (not bHarvester) then storage.Teleporters[self.key] = self end +end + +function TELL:Data() return warptorio.platform.teleporters[self.key] end + +function TELL:ValidA() return isvalid(self.points[1].ent) end + +function TELL:ValidB() return isvalid(self.points[2].ent) end + +function TELL:ConnectCircuit() + local p = self.points + if (self:ValidA() and self:ValidB()) then + local red1 = p[1].ent.get_wire_connector(defines.wire_connector_id.circuit_red, true) + local red2 = p[2].ent.get_wire_connector(defines.wire_connector_id.circuit_red, true) + red1.connect_to(red2) + local green1 = p[1].ent.get_wire_connector(defines.wire_connector_id.circuit_green, true) + local green2 = p[2].ent.get_wire_connector(defines.wire_connector_id.circuit_green, true) + green1.connect_to(green2) + end +end + +function TELL:CheckTeleporterPairs(bSound) -- Call updates and stuff. Automatically deals with logistics, upgrades and cleaning as-needed with good accuracy + local tps = self:Data() + if (tps.pair) then + for i, t in pairs(tps.pair) do + local pi = self.points[i] + self:MakePointTeleporter(tps, i, t, (t.gate and isvalid(pi.ent)) and pi.ent.position or nil) + end + end + local ca = cache.get_entity(self.points[1].ent) + local cb = cache.get_entity(self.points[2].ent) + if (ca and cb) then + ca.teleport_dest = cb.host + cb.teleport_dest = ca.host + else + if (ca) then ca.teleport_dest = nil end + if (cb) then cb.teleport_dest = nil end + end + if (tps.circuit) then self:ConnectCircuit() end +end + +--[[ Teleporter Logistics & Spawning Stuff ]] -- + +function TELL:DestroyPointTeleporter(i, rd) + local e = self.points[i].ent + if (isvalid(e)) then + self.points[i].energy = e.energy + entity.destroy(e, rd) + end + self:DestroyPointSprites(i) +end + +function TELL:DestroyPointSprites(i) + if (self.sprites and self.sprites[i]) then + for k, v in pairs(self.sprites[i]) do + if (v.valid) then + v.destroy() + self.sprites[i][k] = nil + end + end + end + if (self.sprite_arrows and self.sprite_arrows[i]) then + if (self.sprite_arrows[i] ~= nil) then + self.sprite_arrows[i].destroy() + self.sprite_arrows[i] = nil + end + end +end + +function TELL:CheckPointSprites(i) + local tps = self:Data() + local t = tps.pair[i] + if (warptorio.setting("hide_sprites")) then + self:DestroyPointSprites(i) + else + if (t.sprites) then self:MakePointSprites(tps, i, t.sprites) end + if (t.sprite_arrow) then self:MakePointArrow(tps, i, t.sprite_arrow) end + end +end + +function TELL:MakePointTeleporter(tps, i, t, pos) + local p = self.points[i] + local f = storage.floor[t.floor].host + local epos + if (t.prototype) then + local vproto = t.prototype + if (tps.energy) then vproto = vproto .. "-" .. warptorio.GetPlatformTechLevel(tps.energy) end + local e = p.ent + if (isvalid(e)) then + if (e.surface ~= f) then + self:DestroyPointTeleporter(i) + self:DestroyPointLogistics(i) + elseif (e.name ~= vproto) then + epos = e.position + self:DestroyPointTeleporter(i) + end + end + if (not isvalid(e)) then + local vepos = epos or (pos or t.position) + if (not vepos) then return end + local vpos = ((t.gate and not epos) and f.find_non_colliding_position(vproto, vepos, 0, 1, true) or vepos) + --error(serpent.line(vpos)) + local varea + if (not t.gate) then + varea = vector.square(vpos + vector(0.5, 0.5), vector(2, 2)) + vector.clean(f, varea) + end + e = entity.protect(entity.create(f, vproto, vpos), t.minable ~= nil and t.minable or false, + t.destructible ~= nil and t.destructible or false) + if (not t.gate) then vector.cleanplayers(f, varea) end + p.ent = e + end + if (p.energy) then + e.energy = e.energy + p.energy + p.energy = nil + end + if (t.sprites) then self:MakePointSprites(tps, i, t.sprites) end + if (t.sprite_arrow) then self:MakePointArrow(tps, i, t.sprite_arrow) end + end + if (epos or not t.gate) then self:CheckPointLogistics(i) end + + local ce = cache.force_entity(p.ent, "Teleporters", self.key, "points", i) +end + +warptorio.arrowSprite = { sprite = "utility/medium_gui_arrow", target_offset = { 0.75, -0.75 }, x_scale = 0.5, y_scale = 0.5 } + +function TELL:MakePointArrow(tps, i, arrow) + local spid = self.sprite_arrows[i] + if (spid and spid.valid) then return end + local tp = self.points[i].ent + local t = table.deepcopy(warptorio.arrowSprite) + t.surface = tp.surface + t.target = tp + t.only_in_alt_mode = true + t.render_layer = "higher-object-above" + t.orientation = (arrow == "down" and 0.5 or 0) + self.sprite_arrows[i] = rendering.draw_sprite(t) +end + +function TELL:MakePointSprites(tps, i, sprites) + for k, v in pairs(sprites) do + local spid = self.sprites[i][k] + if (not (spid and spid.valid)) then + local tp = self.points[i].ent + local t = table.deepcopy(v) + t.surface = tp.surface + t.target = tp + t.only_in_alt_mode = true + t.render_layer = "higher-object-under" + self.sprites[i][k] = rendering.draw_sprite(t) + end + end +end + +function TELL:GetLoaderDirection() + local tps = self:Data() + if (tps.dirsetting) then return warptorio.setting(tps.dirsetting) end + return (tps.staticdir and tps.staticdir or (tps.top and warptorio.setting("loader_top") or warptorio.setting("loader_bottom"))) or + "up" +end + +function TELL:DestroyPointLogistics(o) + if (self.chests) then + for k, v in pairs(self.chests[o]) do + self.chestcontents[o][k] = v.get_inventory(defines.inventory.chest).get_contents() + entity.destroy(v) + self.chests[o][k] = nil + end + end + for k, v in pairs(self.loaders[o]) do + if (v and isvalid(v)) then + self.loaderFilter[o][k] = {} + for i = 1, v.filter_slot_count, 1 do self.loaderFilter[o][k][i] = v.get_filter(i) end + entity.destroy(v) + end + self.loaders[o][k] = nil + end + for k, v in pairs(self.pipes[o]) do + entity.destroy(v) + self.pipes[o][k] = nil + end +end + +function TELL:RemakeChestPair(o, k) + local e = self.chests[o][k] + local ex = warptorio.GetChest(self.dir[o][k]) + if (e and e.name ~= ex) then + local v = entity.protect(entity.create(e.surface, ex, e.position), false, false) + entity.copy.chest(e, v) + entity.destroy(e) + self.chests[o][k] = v + if (self.dir[o][k] == "input") then entity.ChestRequestMode(v) end + cache.get_raise_type("types", v.type, v, "Teleporters", self.key, "chests", o, k) + end +end + +function TELL:SwapLoaderChests(id) + self:RemakeChestPair(1, id) + self:RemakeChestPair(2, id) +end + +function TELL:UpgradeChests() for i = 1, 6, 1 do self:SwapLoaderChests(i) end end + +function TELL:GetTeleporterSize() + local d = self:Data() + return warptorio.GetTeleporterSize(d.logs, d.dualloader, d.triloader) +end + +function TELL:GetLogisticsArea(o) return vector.square(o or self:Data().position, self:GetTeleporterSize()) end + +function TELL:MakePointLoader(tps, i, id, ido, pos, f, belt, lddir, chesty, belty, vexdir) + local offld = tps.pair[i].prototype and 1 or 0 + + local v = self.loaders[i][id] + if (isvalid(v) and v.name ~= belt) then v.destroy { raise_destroy = true } end + if (not isvalid(v)) then + local vpos = vector(pos) + vector((offld + ido) * vexdir, belty) + local varea = vector.square(vpos + vector(0, 0.5), vector(1, 1)) + vector.clean(f, varea) + v = entity.protect(entity.create(f, belt, vpos, lddir), false, false) + vector.cleanplayers(f, varea) + v.loader_type = self.dir[i][id] + self.loaders[i][id] = v + local inv = self.loaderFilter[i][id] + if (inv) then for invx, invy in pairs(inv) do v.set_filter(invx, invy) end end + end + cache.force_entity(v, "Teleporters", self.key, "loaders", i, id) + + local v = self.chests[i][id] + local chest = warptorio.GetChest(self.dir[i][id]) + if (isvalid(v) and v.name ~= chest) then + self.chestcontents[i][id] = v.get_inventory(defines.inventory.chest).get_contents() + v.destroy { raise_destroy = true } + end + if (not isvalid(v)) then + local vpos = vector(pos) + vector((offld + ido) * vexdir, chesty) + local varea = vector.square(vpos, vector(0.5, 0.5)) + vector.clean(f, varea) + v = entity.protect(entity.create(f, chest, vpos), false, false) + vector.cleanplayers(f, varea) + self.chests[i][id] = v + local inv = self.chestcontents[i][id] + if (inv) then + local cv = v.get_inventory(defines.inventory.chest) + for x, y in pairs(inv) do cv.insert { name = y.name, count = y.count } end + self.chestcontents[i][id] = nil + end + --if(v.type=="logistic-container")then entity.ChestRequestMode(r) end + end + cache.get_raise_type("types", v.type, v, "Teleporters", self.key, "chests", i, id) +end + +function TELL:MakePointLoaders(tps, i, id, pos, f, belt, lddir, chesty, belty) + if (not tps.oneside or tps.oneside == "right") then + self:MakePointLoader(tps, i, id, id, pos, f, belt, lddir, chesty, + belty, 1) + end + if (not tps.oneside or tps.oneside == "left") then + self:MakePointLoader(tps, i, id + 3, id, pos, f, belt, lddir, + chesty, belty, -1) + end +end + +function TELL:MakePointPipes(tps, i, id, pos, f, dist, vexdir, ido) -- TODO: Initial pipe dir & remember direction + local pipe = "warptorio-logistics-pipe" + local v = self.pipes[i][id] + local vpos = vector(pos) + vector(dist * vexdir, 2 - ido) + local pipedir = (vexdir == 1 and 3 or 6) + if (isvalid(v) and (v.surface ~= f or v.position.x ~= vpos.x or v.position.y ~= vpos.y)) then + pipedir = v.direction + entity.destroy(v) + end + if (not isvalid(v)) then + local varea = vector.square(vpos, vector(0.5, 0.5)) + vector.clean(f, varea) + v = entity.protect(entity.create(f, pipe, vpos, pipedir * 2), false, false) + vector.cleanplayers(f, varea) + self.pipes[i][id] = v + end + + cache.force_entity(v, "Teleporters", self.key, "pipes", i, id) +end + +function TELL:CheckEmptyPipes() + local ppr = {} + for a, b in pairs(self.pipes) do for k, v in pairs(b) do if (isvalid(v) and table_size(v.neighbours[1]) >= 1) then ppr[k] = true end end end + for a, b in pairs(self.pipes) do for k, v in pairs(b) do if (isvalid(v) and not ppr[k]) then v.clear_fluid_inside() end end end +end + +function TELL:CheckPointLogistics(i, vxpos) + local tps = self:Data() + local t = tps.pair[i] + if (not tps.logs and not tps.dualloader and not tps.triloader) then return end + local belt = warptorio.GetBelt() + local pos = vxpos or t.position + vector(0.5, 0.5) + if (t.gate and not vxpos) then + if (not isvalid(self.points[i].ent)) then return end + pos = vector(self.points[i].ent.position) + end + local f = storage.floor[t.floor].host + local offld = tps.pair[i].prototype and 1 or 0 + local lddir, chesty, belty + if (self:GetLoaderDirection() == "up") then + lddir = defines.direction.south + chesty = -1 + belty = 0 + else + lddir = defines.direction.north + chesty = 1 + belty = -1 + end + local ldl = 0 + local lvLogs = research.level("warptorio-logistics") + if (tps.logs and lvLogs > 0) then ldl = ldl + 1 end + if (tps.dualloader and research.has("warptorio-dualloader-1")) then ldl = ldl + 1 end + if (tps.triloader and research.has("warptorio-triloader")) then ldl = ldl + 1 end + local can = true + if (t.gate) then -- check if placement area is clear + local vsize = offld + ldl + (tps.dopipes and 1 or 0) + local varea = vector.square(pos, vector(vsize * 2, 3)) + -- if(f.count_entities_filtered{area=varea,collision_mask={"object-layer"}} >1)then + if (f.count_entities_filtered { area = varea, collision_mask = "object" } > 1) then + --f.create_entity { name = "flying-text", position = pos, text = "Logistics blocked - Needs more space", color = { r = 1, g = 0.5, b = 0.5 } } + game.print({ "warptorio.teleporter-blocked-error" }) + f.play_sound { path = "utility/cannot_build", position = pos } + can = false + end + end + if (can and ldl > 0) then + for id = 1, ldl, 1 do + self:MakePointLoaders(tps, i, id, pos, f, belt, lddir, chesty, belty) + end + end + if (can and tps.dopipes and lvLogs > 0) then + for id = 1, math.min(lvLogs, 3), 1 do -- pipes first, it removes the old ones + if (not tps.oneside or tps.oneside == "right") then + self:MakePointPipes(tps, i, id, pos, f, ldl + offld + 1, + 1, id) + end + if (not tps.oneside or tps.oneside == "left") then + self:MakePointPipes(tps, i, id + 3, pos, f, ldl + offld + + 1, -1, id) + end + end + end +end + +--[[ +function events.on_tick("logistics_teleporters",function(ev) for k,v in pairs(storage.Teleporters)do v:TickLogistics() end end end) + +function TELL:TickLogistics() + for k,v in pairs(self.chests[1])do if(isvalid(self.chests[2][k]))then + if(self.dir[1][k]=="input")then warptorio.BalanceLogistics(v,self.chests[2][k]) else warptorio.BalanceLogistics(self.chests[2][k],v) end + end end + for k,v in pairs(self.pipes[1])do if(isvalid(self.pipes[2][k]))then + warptorio.BalanceLogistics(v,self.pipes[2][k]) + end end +end]] diff --git a/control_main.lua b/control_main.lua index c6f1d41..0d361bd 100644 --- a/control_main.lua +++ b/control_main.lua @@ -1,1068 +1,1415 @@ ---[[------------------------------------- - -Author: Pyro-Fire -https://mods.factorio.com/mod/warptorio2 - -Script: control.lua -Purpose: control stuff - - -Written using Microsoft Notepad. -IDE's are for children. - -How to notepad like a pro: -ctrl+f = find -ctrl+h = find & replace -ctrl+g = show/jump to line (turn off wordwrap n00b) - -Status bar wastes screen space, don't use it. - -Use https://tools.stefankueng.com/grepWin.html to mass search, find and replace many files in bulk. - - -]]--------------------------------------- - -local planets=lib.planets - ---[[ Warptorio Environment ]]-- - -warptorio=warptorio or {} -warptorio.Loaded=false - -require("control_main_helpers") - -warptorio.platform=require("control_platform_classic") -local platform=warptorio.platform - - -require("control_class_teleporter") -require("control_class_harvester") -require("control_class_rails") - -warptorio.chatcmd={} -function warptorio.chatcmd.kill(ev) - local ply=game.players[ev.player_index] local c=ply.character - if(c and c.valid)then c.die(c.force,c) end -end -commands.add_command("kill","Suicides the player",warptorio.chatcmd.kill) - - ---[[ Warptorio custom events ]]-- --- Hook in on_load with --- local eventdefs=remote.call("warptorio","get_events") --- script.on_event(eventdefs["on_warp"],func() end) - -events.register("on_warp") -- during Warpout() -events.register("on_post_warp") -- during Warpout() -events.register("warp_started") -- StartWarp() -events.register("warp_stopped") -- StopWarp() - -events.register("harvester_deploy") -- ? -events.register("harvester_recall") -- ? - -events.register("ability_used") -- ? - - - - ---[[ Warptorio Libraries ]]-- - - -warptorio.ChestBeltPairs={{"loader","wooden-chest"},{"fast-loader","iron-chest"},{"express-loader","steel-chest"}, - {"express-loader",function(dir) return (dir=="output" and warptorio.setting("loaderchest_provider") or warptorio.setting("loaderchest_requester")) end}, -} -warptorio.ChestBeltPairs[0]={"loader","wooden-chest"} -function warptorio.GetChest(dir) local lv=research.level("warptorio-logistics") local lvb=warptorio.ChestBeltPairs[lv] return (isstring(lvb[2]) and lvb[2] or lvb[2](dir)) end -function warptorio.GetBelt(dir) local lv=research.level("warptorio-logistics") local lvb=warptorio.ChestBeltPairs[lv] return (isstring(lvb[1]) and lvb[1] or lvb[1](dir)) end ---remotes.register("GetChest",warptorio.GetChest) ---remotes.register("GetBelt",warptorio.GetBelt) - - - ---[[ Warptorio Platform ]]-- - -function warptorio.GetPlatform() return warptorio.platform end -function warptorio.GetCurrentSurface() return global.floor.main.host end -function warptorio.GetMainSurface() return global.floor.main.host end -function warptorio.GetHomeSurface() return global.floor.home and global.floor.home.host or nil end -function warptorio.GetMainPlanet() return planets.GetBySurface(warptorio.GetMainSurface()) end -- planetorio -function warptorio.GetHomePlanet() return planets.GetBySurface(warptorio.GetHomeSurface()) end -- planetorio - -function warptorio.GetNamedSurfaces(tbl) local t={} for k,nm in pairs(tbl)do t[nm]=global.floor[nm].host end return t end -function warptorio.GetAllSurfaces() local t={} for nm,v in pairs(global.floor)do t[v.hostindex]=v.host end return t end -function warptorio.GetPlatformSurfaces() local t={} for nm,v in pairs(global.floor)do if(platform.floors[nm].empty==true)then t[v.hostindex]=v.host end end return t end - - -function warptorio.GetTeleporterSize(a,b,c,noproto) -- for clearing - local x=1 - if(a and research.has("warptorio-logistics-1"))then x=x+2 end - if(b and research.has("warptorio-dualloader-1"))then x=x+1 end - if(c and research.has("warptorio-triloader"))then x=x+1 end - return vector((x*2)+2,2) -end -function warptorio.GetTeleporterHazard(bMain,bFull) -- for hazard tiles - local x=0 - bFull=(bFull==nil and true or bFull) -- has the tech, or -1 - local lgHas=research.has("warptorio-logistics-1") - local dlHas=research.has("warptorio-dualloader-1") - local tlHas=research.has("warptorio-triloader") - local lgCan=research.can("warptorio-logistics-1") - local dlCan=research.can("warptorio-dualloader-1") - local tlCan=research.can("warptorio-triloader") - - if(lgCan or lgHas)then x=x+2 end - - if(bMain)then - if(tlHas and dlHas)then x=x+2 - elseif(tlHas or dlHas)then x=x+1 if(bFull and ( (not tlHas and tlCan) or (not dlHas and dlCan) ) )then x=x+1 end - elseif(bFull and (tlCan or dlCan))then x=x+1 - end - else - if(tlCan)then x=x+1 end - end - - - return vector((x*2)+2,2) -end - -warptorio.EmptyGenSettings={default_enable_all_autoplace_controls=false,width=32*12,height=32*12, - autoplace_settings={entity={treat_missing_as_default=false},tile={treat_missing_as_default=false},decorative={treat_missing_as_default=false}, }, starting_area="none",} - -function warptorio.MakePlatformFloor(vt) - local f=game.create_surface(vt.name,(vt.empty and warptorio.EmptyGenSettings or nil)) - if(vt.empty)then - f.solar_power_multiplier=settings.global.warptorio_solar_multiplier.value - f.daytime=0 - f.always_day=true - f.request_to_generate_chunks({0,0},16) - f.force_generate_chunk_requests() - f.destroy_decoratives({}) - for k,v in pairs(f.find_entities())do entity.destroy(v) end - local area=vector.area(vector(-32*8,-32*8),vector(32*8*2,32*8*2)) - vector.LayTiles("out-of-map",f,area) - end - local floor=cache.raise_surface(f) - if(vt.init)then lib.call(vt.init,floor) end - global.floor[vt.key]=floor - return floor -end - -function warptorio.GetPlatformFloor(vt) if(isstring(vt))then vt=warptorio.platform.floors[vt] end - local floor - if(vt.key=="main")then -- Special; nauvis / primary planet - floor=global.floor.main if(not floor)then floor={key=vt.key,host=game.surfaces.nauvis,hostindex=1} global.floor.main=floor if(vt.init)then lib.call(vt.init,floor) end end - elseif(vt.key=="home")then -- Special; homeworld - floor=global.floor.home if(not floor)then floor={key=vt.key,host=game.surfaces.nauvis,hostindex=1} global.floor.home=floor end - else - floor=global.floor[vt.key] if(not floor)then floor=warptorio.MakePlatformFloor(vt) end - floor.key=vt.key - end - return floor -end - -function warptorio.ConstructFloor(fn,bhzd) warptorio.ConstructPlatform(platform.floors[fn],bhzd) end -function warptorio.ConstructFloorHazard(fn) warptorio.ConstructHazard(platform.floors[fn]) end - -function warptorio.ConstructPlatformVoid(surf) - local vt=warptorio.platform.floors["main"] if(vt.tile)then lib.call(vt.tile,surf,true) end -end -function warptorio.ConstructPlatform(vt,bhzd) - if(isstring(vt))then vt=warptorio.platform.floors[vt] end - local floor=warptorio.GetPlatformFloor(vt) if(floor)then - if(vt.tile)then lib.call(vt.tile,floor.host) end - if(bhzd and vt.hazard)then lib.call(vt.hazard,floor.host) end -end end - -function warptorio.ConstructPlatforms(bhzd) - local platform=warptorio.GetPlatform() - for nm,vt in pairs(platform.floors)do warptorio.ConstructPlatform(vt,bhzd) end -end - -function warptorio.ConstructHazard(vt) - if(isstring(vt))then vt=warptorio.platform.floors[vt] end - local floor=warptorio.GetPlatformFloor(vt) - if(floor and vt.hazard)then lib.call(vt.hazard,floor.host) end -end - -function warptorio.ConstructHazards() - local platform=warptorio.GetPlatform() - for nm,vt in pairs(platform.floors)do warptorio.ConstructHazard(vt) end -end - -function warptorio.CheckFloorRadar(floor) if(research.has("warptorio-charting") and not isvalid(floor.radar))then - floor.radar=entity.protect(entity.create(floor.host,"warptorio-invisradar",vector(-1,-1)),false,false) -end end - - -function warptorio.CheckPlatformSpecials(self) - local platform=warptorio.platform - local vfloor=platform.floors[self.key] - if(not vfloor)then - game.print("no vfloor error: " .. serpent.line(self)) - end - local sp=vfloor.special if(not sp)then return end - if(not sp.upgrade)then if(not research.has(sp.tech) or isvalid(self.SpecialEnt))then return end elseif(research.level(sp.tech)<1)then return end - local protoname=sp.prototype - local inv={} - if(sp.upgrade)then protoname=protoname.."-"..research.level(sp.tech) - if(isvalid(self.SpecialEnt) and self.SpecialEnt.name==protoname)then return elseif(isvalid(self.SpecialEnt))then inv=warptorio.DestroyPlatformSpecial(self) end - end - - local f=self.host - local efply={} - local area=vector.square(vector(-0.5,-0.5),sp.size) - local eft=f.find_entities_filtered{area=area} - local rdr=false if(isvalid(self.radar))then rdr=true entity.destroy(self.radar) end - for k,v in pairs(eft)do if(isvalid(v))then if(v.type=="character")then table.insert(efply,v) elseif(v~=self.radar)then entity.destroy(v) end end end - - local e=entity.protect(entity.create(f,protoname,vector(-0.5,-0.5)),false,false) - self.SpecialEnt=e - if(inv)then for k,v in pairs(inv)do e.get_module_inventory().insert{name=k,count=v} end end -- beacon modules. Close enough. - warptorio.CheckFloorRadar(self) - vector.cleanplayers(f,area) - players.playsound("warp_in",f) -end - -function warptorio.DestroyPlatformSpecial(self) local inv - if(isvalid(self.SpecialEnt))then local x=self.SpecialEnt.get_module_inventory() if(x)then inv=x.get_contents() end entity.destroy(self.SpecialEnt) end - self.SpecialEnt=nil return inv - -end - -function warptorio.InitPlatform() - global.floor={} - - for nm,vt in pairs(warptorio.platform.floors)do - local floor=warptorio.GetPlatformFloor(vt) - if(floor)then - warptorio.ConstructPlatform(vt,true) - end - end -end - - - - - ---[[ Bootstrap Initialization and Migrations ]]-- - -events.on_init(function() - events.raise_migrate() - lib.planets.lua() - warptorio.ValidateWarpBlacklist() - --warptorio.HookNewGamePlus() -end) - - - - -function warptorio.ApplyMapSettings() - local gmp=game.map_settings - gmp.pollution.diffusion_ratio = 0.105 - gmp.pollution.pollution_factor = 0.0000001 - - gmp.pollution.min_to_diffuse=15 -- default 15 - gmp.pollution.ageing=1.0 -- 1.0 - gmp.pollution.expected_max_per_chunk=250 - gmp.pollution.min_to_show_per_chunk=50 - gmp.pollution.pollution_restored_per_tree_damage=9 - gmp.pollution.enemy_attack_pollution_consumption_modifier=1.0 - - gmp.enemy_evolution.destroy_factor=0.0002 -- default 0.002 - - gmp.unit_group.min_group_gathering_time = 600 - gmp.unit_group.max_group_gathering_time = 2 * 600 - gmp.unit_group.max_unit_group_size = 200 - gmp.unit_group.max_wait_time_for_late_members = 2 * 360 - gmp.unit_group.settler_group_min_size = 1 - gmp.unit_group.settler_group_max_size = 1 - - --gmp.enemy_expansion.max_expansion_cooldown = (gmp.enemy_expansion.min_expansion_cooldown*1.25) - - -end - -events.on_config(function(ev) if(warptorio.Loaded)then return end - lib.planets.lua() - cache.validate("combinators") - cache.validate("heat") - cache.validate("power") - cache.validate("loaderinput") - cache.validate("loaderoutput") - cache.validate("ldinputf") - cache.validate("ldoutputf") - - global.warpzone=global.warpzone or 0 - global.time_spent_start_tick=global.time_spent_start_tick or game.tick - global.time_passed=global.time_passed or 0 - - global.warp_charge_time=global.warp_charge_time or 10 - global.warp_charge_start_tick=global.warp_charge_start_tick or 0 - global.warp_charging=global.warp_charging or 0 - global.warp_timeleft=global.warp_timeleft or 60*10 - global.warp_auto_time = global.warp_auto_time or 60*settings.global["warptorio_autowarp_time"].value - global.warp_auto_end = global.warp_auto_end or 60*60*settings.global["warptorio_autowarp_time"].value - global.warp_last=global.warp_last or game.tick - global.abilities=global.abilities or {} - global.ability_drain=global.ability_drain or settings.global["warptorio_ability_drain"].value - - global.pollution_amount = global.pollution_amount or 1.1 - global.pollution_expansion = global.pollution_expansion or 1.1 - global.ability_uses=global.ability_uses or 0 - global.ability_next=global.ability_next or 0 - global.radar_uses=global.radar_uses or 0 - - warptorio.ApplyMapSettings() - - global.votewarp=global.votewarp or {} if(type(global.votewarp)~="table")then global.votewarp={} end - warptorio.CheckVotewarps() - - -- todo: global.warp_blacklist={} - warptorio.ValidateWarpBlacklist() - - --[[ more todo: - for k,v in pairs(gwarptorio.Harvesters)do v.position=warptorio.platform.harvester[k] end - for k,v in pairs(gwarptorio.Teleporters)do v.position=warptorio.Teleporters[k].position end - ]] - - global.Teleporters=global.Teleporters or {} - global.Research=global.Research or {} -- todo remove this - global.Turrets=global.Turrets or {} - global.Rails=global.Rails or {} - global.Harvesters=global.Harvesters or {} - - - if(not global.floor)then warptorio.InitPlatform() end - - - for k,v in pairs(global.Rails)do - v:MakeRails() - end - for k,v in pairs(global.Teleporters)do - v:CheckTeleporterPairs(true) - end - for k,v in pairs(global.Harvesters)do - local gdata=warptorio.platform.harvesters[v.key] - v.rank=warptorio.GetPlatformTechLevel(gdata.tech) - v:CheckTeleporterPairs(true) - v:Upgrade() - end - - for k,v in pairs(warptorio.settings)do v() end - - -- todo: warptorio.ApplyMapSettings() - for k,t in pairs(global.Harvesters)do - table.merge(t,table.deepcopy(warptorio.platform.harvesters[t.key])) - table.merge(t,table.deepcopy(warptorio.platform.HarvesterPointData)) - end - - warptorio.Loaded=true -end) - -events.on_load(function() - warptorio.HookNewGamePlus() - if(global.Teleporters)then for k,v in pairs(global.Teleporters)do setmetatable(v,warptorio.TeleporterMeta) end end - if(global.Harvesters)then for k,v in pairs(global.Harvesters)do setmetatable(v,warptorio.HarvesterMeta) end end - if(global.Rails)then for k,v in pairs(global.Rails)do setmetatable(v,warptorio.RailMeta) end end - --lib.planets.lua() -end) - - ---[[ Players Manager ]]-- - -function warptorio.CheckVotewarps() for k,v in pairs(global.votewarp)do if(isvalid(v) or not v.connected)then global.votewarp[k]=nil end end cache.updatemenu("hud","warpbtn") end - - -warptorio.teleDir={[0]={0,-1},[1]={1,-1},[2]={1,0},[3]={1,1},[4]={0,1},[5]={-1,1},[6]={-1,0},[7]={-1,-1}} -function warptorio.TeleportLogic(ply,e,tent) - local w=ply.walking_state - local ox=tent.position - local x=e.position - local mp=2 if(not ply.character)then mp=3 end - --game.print(serpent.line(ply.vehicle.name)) - if(ply.driving)then - local veh=ply.vehicle - if(veh.type=="spider-vehicle")then - local cp=ply.position local xd,yd=(x.x-cp.x),(x.y-cp.y) - local vpos=vector(ox.x+xd*3,ox.y+yd*3) - entity.safeteleport(ply,tent.surface,vpos) - local cn=veh.clone{position=ply.position,surface=ply.surface,force=ply.force} - veh.destroy() - ply.driving=cn - else - local cp=ply.position local xd,yd=(x.x-cp.x),(x.y-cp.y) entity.safeteleport(veh,tent.surface,vector(ox.x+xd*3,ox.y+yd*3)) - end - elseif(not w.walking)then - local cp=ply.position local xd,yd=(x.x-cp.x),(x.y-cp.y) entity.safeteleport(ply,tent.surface,vector(ox.x+xd*mp,ox.y+yd*mp)) - else - local td=warptorio.teleDir[w.direction] local tpe=ply entity.safeteleport(tpe,tent.surface,vector(ox.x+td[1]*mp,ox.y+td[2]*mp)) - end - players.playsound("teleport",e.surface,e.position) players.playsound("teleport",tent.surface,tent.position) -end - - -cache.player({ - raise=function(cp) local ply=cp.host - entity.safeteleport(ply,warptorio.GetMainSurface(),vector(0,-5)) - local hud=cache.force_menu("hud",ply) - end, - on_position=function(ply) - local cp=cache.force_player(ply) - if((cp.tprecent or 0)>game.tick)then return end - local f=ply.surface - local z=vector.square(ply.position,vector(0.8,0.8)) - if(ply.driving)then - local bbox=ply.vehicle.bounding_box - --game.print(serpent.line(bbox)) - bbox.left_top.x=bbox.left_top.x-0.8 - bbox.left_top.y=bbox.left_top.y-0.8 - bbox.right_bottom.x=bbox.right_bottom.x+0.8 - bbox.right_bottom.y=bbox.right_bottom.y+0.8 - z=bbox - end - - local ents=f.find_entities_filtered{area=z,type="accumulator"} --todo - for k,v in pairs(ents)do - local tpg=cache.get_entity(v) - if(tpg and isvalid(tpg.teleport_dest))then - cp.tprecent=game.tick+10 - local tgate=tpg.teleport_dest - warptorio.TeleportLogic(ply,v,tgate) - end - end - end, - on_create=function(ply) - local cp=cache.raise_player(ply) - end, - on_join=function(ply) - local menu=cache.force_menu("hud",ply) - entity.safeteleport(ply,warptorio.GetMainSurface(),{0,-5}) - end, - on_respawn=function(ply) - local cf=warptorio.GetMainSurface() local gp=ply - if(gp.surface~=cf)then local pos=cf.find_non_colliding_position("character",{0,-5},0,1,1) gp.teleport(pos,cf) end - end, - on_left=function(ply) - if(global.votewarp[ply.index])then - global.votewarp[ply.index]=nil - cache.updatemenu("hud","warpbtn") - end - end, - on_pre_removed=function(ply) - local cp=cache.get_player(ply) if(cp)then - cache.destroy_player(ply) - end - end, - on_capsule=function(ply,ev) - if(ev.item.name=="warptorio-townportal")then - local p=game.players[ev.player_index] - if(p and p.valid)then - players.playsound("teleport",p.surface,p.position) - entity.safeteleport(p,warptorio.GetMainSurface(),vector(0,-5)) - players.playsound("teleport",p.surface,p.position) - end - elseif(ev.item.name=="warptorio-homeportal" and warptorio.GetHomeSurface())then - local p=game.players[ev.player_index] - if(p and p.valid)then - players.playsound("teleport",p.surface,p.position) - entity.safeteleport(p,warptorio.GetHomeSurface(),vector(0,-5)) - players.playsound("teleport",p.surface,p.position) - end - end - - end, -}) - - - - - ---[[ Warptorio Cache Manager ]]-- - - - -- Pumps and resources cannot be cloned in warptorio -cache.type("offshore-pump",{ clone=function(e) e.destroy{raise_destroy=true} end, }) -cache.type("resource",{ clone=function(e) e.destroy{raise_destroy=true} end, }) - --- Simple globally balanced entities -cache.ent("warptorio-heatpipe",{ create=function(e) cache.insert("heat",e) end, destroy=function(e) cache.remove("heat",e) end }) -cache.ent("warptorio-reactor",{ create=function(e) cache.insert("heat",e) end, destroy=function(e) cache.remove("heat",e) end }) -cache.ent("warptorio-accumulator",{ create=function(e) cache.insert("power",e) end, destroy=function(e) cache.remove("power",e) end }) - -events.on_tick(1,0,"heattick",function(tick) entity.AutoBalanceHeat(cache.get("heat")) end) -events.on_tick(1,0,"powertick",function(tick) local t=cache.get("power") - local g,c=0,0 - for k,v in pairs(t)do if(isvalid(v))then g=g+v.energy c=c+v.electric_buffer_size end end - - local egdrain=global.ability_drain - local abc=0 - if(global.abilities.stabilizing)then - abc=abc+1 - end - if(global.abilities.accelerating)then - abc=abc+1 - end - if(global.abilities.scanning)then - abc=abc+1 - end - - if(abc>0)then - local gcost=c*egdrain*abc - if(g>=gcost)then - g=math.max(g-gcost,0) - global.ability_drain=math.min(egdrain+(0.00000002*abc),0.25) - else - global.abilities.stabilizing=false global.abilities.scanning=false global.abilities.accelerating=false - end - end - global.energycount=g global.energymax=c - for k,v in pairs(t)do if(v.valid)then v.energy=g*(v.electric_buffer_size/c) end end -end) - --- Warptorio Combinators -cache.ent("warptorio-combinator",{ - create=function(e,ev) cache.insert("combinators",e) end, - destroy=function(e,ev) cache.remove("combinators",e) end, - update=function(e,ev) local cbh=e.get_or_create_control_behavior() for k,v in pairs(ev.signals)do cbh.set_signal(k,v) end end, -}) -function warptorio.RefreshWarpCombinators() local sigs=warptorio.GetCombinatorSignals() cache.entcall("combinators","update",{signals=sigs}) end -function warptorio.GetCombinatorSignals() local tbl={} for k,v in pairs(warptorio.Signals)do tbl[k]={signal=v.signal,count=v.get()} end return tbl end -warptorio.Signals={} -- 18 max default -warptorio.Signals[1]={ signal={type="virtual",name="signal-W"},get=function() return (global.warp_charging>=1 and (global.warp_time_left or 10)/60 or (global.warp_charge_time or 10)) end} -warptorio.Signals[2]={ signal={type="virtual",name="signal-X"},get=function() return global.warp_charging or 0 end} -warptorio.Signals[3]={ signal={type="virtual",name="signal-A"},get=function() return global.warp_auto_end/60 end} -warptorio.Signals[4]={ signal={type="virtual",name="signal-L"},get=function() local hv=global.Harvesters.west return ((hv and hv.deployed) and 1 or 0) end} -warptorio.Signals[5]={ signal={type="virtual",name="signal-R"},get=function() local hv=global.Harvesters.east return ((hv and hv.deployed) and 1 or 0) end} -warptorio.Signals[6]={ signal={type="virtual",name="signal-P"},get=function() return global.time_passed end} - ---[[ Warptorio Gui ]]-- - - ---cache.updatemenu("hud","raise") -- to recreate the menu - -function warptorio.RaiseHUD(v) local m=cache.get_menu("hud",v) if(not m)then cache.raise_menu("hud",v) else cache.call_menu("raise",m) end end -function warptorio.ResetHUD(p) if(not p)then for k,v in pairs(game.players)do warptorio.RaiseHUD(v) end else warptorio.RaiseHUD(p) end end -function warptorio.PlayerCanStartWarp(ply) return true end - -function warptorio.ToolRecallHarvester(k,ply) if(not research.has("warptorio-harvester-"..k.."-1"))then return end - local cn=("warptorio-harvestpad-"..k.."-"..research.level("warptorio-harvester-"..k)) - if(not ply or (ply and not ply.get_main_inventory().get_contents()[cn]))then ply.get_main_inventory().insert{name=cn,count=1} players.playsound("warp_in",ply.surface,ply.position) end - local hv=global.Harvesters[k] if(hv and hv.deployed and isvalid(hv.b))then players.playsound("warp_in",hv.b.surface,hv.b.position) hv:Recall() hv:DestroyB() end -end -function warptorio.ToolRecallGate(ply) if(not research.has("warptorio-teleporter-portal"))then return end - local t=global.Teleporters.offworld if(t)then - if(t.b and t.b.valid)then players.playsound("warp_in",t.b.surface,t.b.position) t:DestroyLogsB() t:DestroyB() end - local inv=ply.get_main_inventory() - if(not inv.get_contents()["warptorio-teleporter-gate-0"])then inv.insert{name="warptorio-teleporter-gate-0",count=1} players.playsound("warp_in",ply.surface,ply.position) end - end -end - -cache.vgui("warptorio_toolbutton",{click=function(elm,ev) local menu=cache.get_menu("hud",elm.player_index) local b=menu.toolbar b.visible=not b.visible end}) -cache.vgui("warptorio_tool_hv_west",{click=function(elm,ev) warptorio.ToolRecallHarvester("west",game.players[elm.player_index]) end}) -cache.vgui("warptorio_tool_hv_east",{click=function(elm,ev) warptorio.ToolRecallHarvester("east",game.players[elm.player_index]) end}) -cache.vgui("warptorio_tool_planet_gate",{click=function(elm,ev) warptorio.ToolRecallGate(game.players[elm.player_index]) end}) - - -cache.vgui("warptorio_homeworld",{ - click=function(elm,ev) local menu=cache.get_menu("hud",elm.player_index) - if(menu.hometmr=1)then menu.charge_time.caption={"warptorio.warp-in",util.formattime(val or (global.warp_time_left or 0))} - elseif(menu.charge_time)then menu.charge_time.caption={"warptorio.charge_time",util.formattime((global.warp_charge_time or 0)*60)} - end - - menu.time_passed.caption={"warptorio.time_passed",util.formattime(global.time_passed or 0)} - if(warptorio.IsAutowarpEnabled())then menu.autowarp.caption={"warptorio.autowarp-in",util.formattime(global.warp_auto_end)} else menu.autowarp.caption="" end - - menu.hometmr=menu.hometmr or 0 - if(menu.homeworld)then - if(menu.hometmr>game.tick)then menu.homeworld.caption={"warptorio.confirm_homeworld",util.formattime(menu.hometmr-game.tick)} - else menu.homeworld.caption={"warptorio.button_homeworld"} - end - end - - if(menu.energybar)then - local cureng=global.energycount or 0 - local maxeng=math.max(global.energymax or 1,1) - local energydif=cureng-(menu.last_energy or 0) - menu.last_energy=cureng - - local egdrain=global.ability_drain*100*60 - local abc=0 - local r=menu.stabilizer - if(r)then if(global.abilities.stabilizing)then abc=abc+1 r.caption={"warptorio-stabilize-on","-"..math.roundx(egdrain,2).."%/sec"} else r.caption={"warptorio-stabilize"} end end - local r=menu.accelerator - if(r)then if(global.abilities.accelerating)then abc=abc+1 r.caption={"warptorio-accel-on","-"..math.roundx(egdrain,2).."%/sec"} else r.caption={"warptorio-accel"} end end - local r=menu.radar - if(r)then if(global.abilities.scanning)then abc=abc+1 r.caption={"warptorio-radar-on","-"..math.roundx(egdrain,2).."%/sec"} else r.caption={"warptorio-radar"} end end - - - menu.energybar_energy.caption=" "..string.energy_to_string(cureng) .. " " - menu.energybar_energymax.caption=" "..string.energy_to_string(maxeng) .. " " - - menu.energybar_energybal.caption=" ("..(energydif>=1 and "+" or (energydif>0 and "+-" or ""))..string.energy_to_string(energydif) .. "/sec) " - menu.energybar_energybal.style.font_color=(energydif>0 and {r=0,g=1,b=0} or (energydif<0 and {r=1,g=0,b=0} or {r=0.75,g=0.75,b=0.75})) - - menu.energybar.value=cureng/maxeng - - menu.energybar_energypct.caption=" "..math.roundx((cureng/maxeng)*100,2) .. "% " - - if(abc>0)then menu.energybar_energypctx.caption="-"..math.roundx(egdrain*abc,2).."%/sec" else menu.energybar_energypctx.caption="" end - - end - -end - - -function HUD.raise(menu,ev) local ply=menu.host - menu.frame=vgui.create(ply.gui.left,{name="warptorio_frame",type="flow",direction="vertical"}) - menu.frame.style.left_padding=4 - menu.row1=vgui.create(menu.frame,{name="warptorio_row1",type="flow",direction="horizontal"}) - menu.row2=vgui.create(menu.frame,{name="warptorio_row2",type="flow",direction="horizontal"}) - menu.row4=vgui.create(menu.frame,{name="warptorio_row4",type="flow",direction="horizontal"}) - menu.row3=vgui.create(menu.frame,{name="warptorio_row3",type="flow",direction="horizontal"}) - menu.row1.clear() - menu.row2.clear() - menu.row3.clear() - menu.row4.clear() - - menu.warpbtn=vgui.create(menu.row1,{name="warptorio_warpbutton",type="button",caption={"warptorio.button-warp","-"}}) - if(research.has("warptorio-toolbar"))then menu.toolbtn=vgui.create(menu.row1,{name="warptorio_toolbutton",type="button",caption={"warptorio.toolbutton","-"}}) end - if(research.level("warptorio-reactor")>=8)then - menu.warptgt=vgui.create(menu.row1,{name="warptorio_warptarget",type="drop-down"}) - HUD.rebuild_warptargets(menu) - HUD.warptarget(menu,{tgt=(sx==nil and "(Random)" or (sx=="home" and "(Homeworld)" or (sx=="(nauvis)" and "nauvis" or sx)))}) - end - - menu.time_passed=vgui.create(menu.row1,{name="warptorio_time_passed",type="label"}) - menu.charge_time=vgui.create(menu.row1,{name="warptorio_charge_time",type="label"}) - menu.warpzone=vgui.create(menu.row1,{name="warptorio_warpzone",type="label",caption="Warpzone: " .. global.warpzone or 0}) - menu.autowarp=vgui.create(menu.row1,{name="warptorio_autowarp",type="label"}) - - if(research.has("warptorio-homeworld"))then menu.homeworld=vgui.create(menu.row1,{name="warptorio_homeworld",type="button",caption={"warptorio.button_homeworld"}}) end - - - local hasabil=false - if(research.has("warptorio-stabilizer"))then hasabil=true menu.stabilizer=vgui.create(menu.row2,{name="warptorio_stabilizer",type="button",caption={"warptorio-stabilize","-"}}) end - if(research.has("warptorio-accelerator"))then hasabil=true menu.accelerator=vgui.create(menu.row2,{name="warptorio_accelerator",type="button",caption={"warptorio-accel","-"}}) end - if(research.has("warptorio-charting"))then hasabil=true menu.radar=vgui.create(menu.row2,{name="warptorio_radar",type="button",caption={"warptorio-radar","-"}}) end - if(hasabil)then - menu.last_energy=menu.last_energy or 100 - local energydif=1000-menu.last_energy - menu.energybar_label=vgui.create(menu.row4,{name="warptorio_energybar_label",type="label",caption={"warptorio.energybar","-"}}) - menu.energybar_energy=vgui.create(menu.row4,{name="warptorio_energybar_energy",type="label",caption=" 100kw "}) - menu.energybar_energy.style.font_color={r=0,g=1,b=0} - - menu.energybar_energydiv=vgui.create(menu.row4,{name="warptorio_energybar_energydiv",type="label",caption=" / "}) - - menu.energybar_energymax=vgui.create(menu.row4,{name="warptorio_energybar_energymax",type="label",caption=" 0kw "}) - menu.energybar_energymax.style.font_color={r=0.25,g=1,b=1} - - - menu.energybar_energybal=vgui.create(menu.row4,{name="warptorio_energybar_energybal",type="label",caption=" (+100.32MW/sec) "}) - menu.energybar_energybal.style.font_color=(energydif>0 and {r=0,g=1,b=0} or (energydif==0 and {r=1,g=1,b=0} or {r=1,g=0,b=0})) - - - menu.energybar_energydivb=vgui.create(menu.row4,{name="warptorio_energybar_energydivb",type="label",caption=" | "}) - - - menu.energybar=vgui.create(menu.row4,{name="warptorio_time_passed",type="progressbar",value=0.3}) - menu.energybar.style.natural_width=250 - menu.energybar.style.top_padding=7 - menu.energybar.style.bottom_padding=7 - - menu.energybar_energypcta=vgui.create(menu.row4,{name="warptorio_energybar_energypcta",type="label",caption=" | "}) - menu.energybar_energypct=vgui.create(menu.row4,{name="warptorio_energybar_energypct",type="label",caption="25%"}) - menu.energybar_energypct.style.font_color={r=1,g=1,b=1} - menu.energybar_energypctx=vgui.create(menu.row4,{name="warptorio_energybar_energypctx",type="label",caption="-3%/sec"}) - menu.energybar_energypctx.style.font_color={r=1,g=0,b=0} - - - - end - - if(research.has("warptorio-toolbar"))then - menu.toolbar=vgui.create(menu.row3,{name="warptorio_toolframe",type="flow",direction="horizontal",visible=false}) - menu.toolbar.clear() - menu.tool_harvester_west=vgui.create(menu.toolbar,{name="warptorio_tool_hv_west",type="sprite-button",sprite="entity/warptorio-harvestportal-1",tooltip={"warptorio.tool_hv_west","-"}}) - menu.tool_planet_gate=vgui.create(menu.toolbar,{name="warptorio_tool_planet_gate",type="sprite-button",sprite="item/warptorio-teleporter-gate-0",tooltip={"warptorio.tool_planet_gate","-"}}) - menu.tool_harvester_east=vgui.create(menu.toolbar,{name="warptorio_tool_hv_east",type="sprite-button",sprite="entity/warptorio-harvestportal-1",tooltip={"warptorio.tool_hv_east","-"}}) - end - - - HUD.clocktick(menu) - HUD.rebuild_warptargets(menu) - local sx=global.planet_target - -end - -function HUD.rebuild_warptargets(menu,ev) - if(menu.warptgt)then - local tgl={"(Random)"} - if(research.has("warptorio-homeworld"))then table.insert(tgl,"(Homeworld)") table.insert(tgl,"(Nauvis)") end - if(research.has("warptorio-charting"))then for k,v in pairs(lib.planets.GetTemplates())do table.insert(tgl,v.key) end end - menu.warptgt.items=tgl - HUD.warptarget(menu,{tgt=global.planet_target}) - end -end -function HUD.warptarget(menu,ev) local ply=menu.host if(not menu.warptgt or ply.index==ev.ply)then return end - local elm,items=menu.warptgt if(elm)then items=elm.items end if(not items)then return end - for idx,kv in pairs(items)do if(type(kv)=="string" and kv:lower()==ev.tgt)then elm.selected_index=idx end end -end - -function HUD.warpbtn(menu) - local r=menu.warpbtn - local ply=menu.host - if(global.warp_charging>=1)then r.caption={"warptorio.warping","-"} r.enabled=false - else local cx=table.Count(global.votewarp) local c=table.Count(game.connected_players) -- table.Count(game.non_afk_players) - if(c>1)then - local vcn=math.ceil(c*warptorio.setting("votewarp_multi")) - if(global.votewarp[ply.index] and cx0)then r.caption={"warptorio.button-votewarp-count",cx,vcn} - else r.caption={"warptorio.button-votewarp","-"} - end - else r.enabled=true r.caption={"warptorio.button-warp","-"} menu.warpzone.caption={"warptorio.warpzone_label",global.warpzone or 0} - end - end -end - -cache.menu("hud",HUD) - - - -cache.vgui("warptorio_warptarget",{ -selection_changed=function(elm,ev) local ply=game.players[elm.player_index] - local s=elm.items[elm.selected_index] if(not s)then return end local sx=s:lower() - local vt=(sx=="(random)" and nil or (sx=="(homeworld)" and "home" or (sx=="(nauvis)" and "nauvis" or sx))) - if(vt~=global.planet_target)then global.planet_target=vt game.print({"warptorio.player_set_warp_target",ply.name,s}) cache.updatemenu("hud","warptarget",{ply=elm.player_index,tgt=sx}) end -end, -}) - -function warptorio.StartWarp() - if(global.warp_charging<1)then - events.vraise("warp_started") - global.warp_charge_start_tick=game.tick - global.warp_charging=1 - players.playsound("reactor-stabilized") - cache.updatemenu("hud","warpbtn") - end -end -function warptorio.StopWarp() - if(global.warp_charging>0)then - events.vraise("warp_stopped") - global.warp_charging=0 - global.warp_charge_time=global.warp_time_left/60 - global.warp_charge_start_tick=0 - end -end -function warptorio.IsWarping() return global.warp_charging>0 end -cache.vgui("warptorio_warpbutton",{ -click=function(elm,ev) local ply=game.players[elm.player_index] local menu=cache.get_menu("hud",elm.player_index) - if(global.warp_charging<1)then local c=table.Count(game.connected_players) -- table.Count(game.non_afk_players) - if(c>1 and warptorio.setting("votewarp_multi")>0)then --votewarp - local vcn=math.ceil(c*warptorio.setting("votewarp_multi")) - global.votewarp[ply.index]=ply - local cx=table.Count(global.votewarp) - if(vcn<=1 or cx>=vcn)then - warptorio.StartWarp() - game.print(ply.name .. " started the warpout procedure.") - else - players.playsound("teleport") - game.print({"warptorio.player_want_vote_warp",ply.name,cx,vcn}) - cache.updatemenu("hud","warpbtn") - end - elseif(warptorio.PlayerCanStartWarp(ply))then - global.warp_charge_start_tick = game.tick - global.warp_charging = 1 - players.playsound("reactor-stabilized") - cache.updatemenu("hud","warpbtn") - else - ply.print("You must be on the same planet as the platform to warp") - end - end -end, -}) - -cache.vgui("warptorio_stabilizer",{ -click=function(elm,ev) local ply=game.players[elm.player_index] local menu=cache.get_menu("hud",elm.player_index) - global.abilities.stabilizing= not global.abilities.stabilizing -end, -}) -cache.vgui("warptorio_accelerator",{ -click=function(elm,ev) local ply=game.players[elm.player_index] local menu=cache.get_menu("hud",elm.player_index) - global.abilities.accelerating= not global.abilities.accelerating -end, -}) -cache.vgui("warptorio_radar",{ -click=function(elm,ev) local ply=game.players[elm.player_index] local menu=cache.get_menu("hud",elm.player_index) - global.abilities.scanning= not global.abilities.scanning -end, -}) - - - - ---[[ Warping stuff ]]-- - -function warptorio.ValidateWarpBlacklist() -end - -local staticBlacklist={"highlight-box","big_brother-blueprint-radar","osp_repair_radius"} -function warptorio.GetWarpBlacklist() - return staticBlacklist -end - --- OnEntCloned -events.on_event(defines.events.on_entity_cloned,function(ev) - if(warptorio.IsCloning)then table.insert(warptorio.Cloned_Entities,{source=ev.source,destination=ev.destination}) end - if(ev.source.type=="spider-vehicle")then - for k,v in pairs(game.players)do local inv=v.get_main_inventory() if(inv)then - for i=1,#inv,1 do local e=inv[i] if(e and e.valid_for_read and e.connected_entity==ev.source)then e.connected_entity=ev.destination end end - local e=v.cursor_stack if(e and e.valid_for_read and e.connected_entity==ev.source)then e.connected_entity=ev.destination end - if(v.driving and v.vehicle==ev.source)then - entity.safeteleport(v,ev.destination.surface,ev.destination.position) - v.driving=ev.destination - end - end end - end -end) - -function warptorio.CountPlatformEntities() return 5 end -- todo - -function warptorio.Warpout(key) - warptorio.IsWarping=true - for k,v in pairs(global.Harvesters)do if(v.deployed)then v:Recall(true) end end - - local cp=warptorio.GetMainPlanet() - local cf=warptorio.GetMainSurface() - warptorio.WarpPreBuildPlanet(key) - local f,w,frc=warptorio.WarpBuildPlanet(key) - warptorio.WarpPostBuildPlanet(w) - - global.floor.main.host=f - global.floor.main.hostindex=f.index - - warptorio.ConstructPlatform("main",true) - - events.vraise("on_warp",{newsurface=f,newplanet=w,oldsurface=cf,oldplanet=cp}) - if(cp and cp.on_warp)then lib.call(cp.on_warp,f,w,cf,cp) end - - warptorio.Warp(cf,f) - warptorio.WarpPost(cf,f) - - -- reset pollution & biters - game.forces["enemy"].evolution_factor=0 - global.pollution_amount=1.1 - global.pollution_expansion=1.1 - - -- warp sound - players.playsound("warp_in") - - - warptorio.WarpFinished() - events.vraise("on_post_warp",{newsurface=f,newplanet=w}) - if(w.postwarpout)then lib.call(w.postwarpout,{newsurface=f,newplanet=w}) end - warptorio.IsWarping=false -end - - -function warptorio.WarpPreBuildPlanet(key) - global.warp_charge=0 - global.warp_charging=0 - global.votewarp={} - global.warp_last=game.tick - - global.warpzone=global.warpzone+1 - - -- Warp chargetime cooldown math - local cot=warptorio.CountPlatformEntities() - - local sgZone=warptorio.setting("warpcharge_zone") - local sgZoneGain=warptorio.setting("warpcharge_zonegain") - local sgMax=warptorio.setting("warpcharge_max") - local sgFactor=warptorio.setting("warp_charge_factor") - local sgMul=warptorio.setting("warpcharge_multi") - - global.warp_charge_time=math.min(10+ (cot/sgFactor) + (global.warpzone*sgMul) + (sgZoneGain*(math.min(global.warpzone,sgZone)/sgZone)*60), 60*sgMax) - global.warp_time_left=60*global.warp_charge_time - - -- Autowarp timer math - local rta=research.level("warptorio-reactor") - global.warp_auto_time=60*warptorio.setting("autowarp_time")+60*10*rta - global.warp_auto_end=game.tick+ global.warp_auto_time*60 - - -- Abilities - --global.ability_uses=0 - --global.radar_uses=0 - --global.ability_next=game.tick+60*60*warptorio.setting("ability_warp") - - global.ability_drain=warptorio.setting("ability_drain") or 0.00001 - global.abilities={} - - -- Update guis - --if(research.has("warptorio-accelerator") or research.has("warptorio-charting") or research.has("warptorio-stabilizer"))then end --gui.uses() gui.cooldown() - --if(warptorio.IsAutowarpEnabled())then gui.autowarp() end - --gui.warpzone() - cache.updatemenu("hud","warpbtn") - - - -- packup old teleporter gate - --local tp=global.Teleporters.offworld if(tp and tp:ValidB())then tp:DestroyB() tp:DestroyLogsB() end - -- Recall harvester plates and players on them. - --for k,v in pairs(global.Harvesters)do v:Recall(true) end - -end - - -function warptorio.WarpBuildPlanet(key) - local nplanet - if(key)then - nplanet=remote.call("planetorio","FromTemplate","warpzone_"..global.warpzone,key) - else - local vplanet=warptorio.GetMainPlanet() - local lvl=research.level("warptorio-reactor") - if(lvl>=8)then local wx=global.planet_target - if(wx=="home" or wx=="nauvis")then if(research.has("warptorio-homeworld"))then local hf=(wx=="nauvis" and game.surfaces.nauvis or global.floor.home.host) - if(warptorio.GetMainSurface()~=hf and math.random(1,100)<=warptorio.setting("warpchance"))then local hp=remote.call("planetorio","GetBySurface",hf) or {name="Nauvis"} - game.print({"warptorio.successful_warp"}) game.print({"warptorio.home_sweet_home",hp.name}) - return hf,hp - end - end elseif(wx and math.random(1,100)<=warptorio.setting("warpchance"))then - nplanet=remote.call("planetorio","FromTemplate","warpzone_"..global.warpzone,wx) - if(nplanet)then game.print({"warptorio.successful_warp"}) end - end - end - if(not nplanet)then nplanet=remote.call("planetorio","SimplePlanetRoll","warpzone_"..global.warpzone,{zone=global.warpzone,prevplanet=vplanet}) end -- planetorio, modifiers={{"",stuff}}) - end - if(research.has("warptorio-charting") or not nplanet.planet.desc)then game.print(nplanet.planet.name) end - if(nplanet.planet.desc)then game.print(nplanet.planet.desc) end - return nplanet.surface,nplanet.planet,nplanet.force -end - - -function warptorio.WarpPostBuildPlanet(planet) - if(planet.warp_multiply)then - global.warp_charge_time=global.warp_charge_time*planet.warp_multiply - global.warp_time_left=global.warp_time_left*planet.warp_multiply - end - --gui.charge_time() -end - -function warptorio.Warp(cf,f) -- Find and clone entities to new surface - --cf.find_entities() - --cf.clone_entities{surface=f,entities=tbl} - - -- call to platform() - - - if(global.Teleporters.offworld)then global.Teleporters.offworld:DestroyPointTeleporter(2) end - - local etbl,tpply=warptorio.platform.GetWarpables(cf,f) --{},{} - for k,v in pairs(etbl)do if(not isvalid(v))then etbl[k]=nil end end - - local blacktbl={} - for k,v in pairs(etbl)do if(table.HasValue(warptorio.GetWarpBlacklist(),v.name))then table.insert(blacktbl,v) etbl[k]=nil end end - for k,v in pairs(etbl)do if(not v or not v.valid)then etbl[k]=nil end end - - -- find logistics networks and robots among entities to catch robots outside the platform - if(settings.global["warptorio_robot_warping"].value==true)then - local lgn={} for k,v in pairs(etbl)do if(v.type=="roboport")then local g=v.logistic_network if(g and g.valid)then table.insertExclusive(lgn,g) end end end - for k,v in pairs(lgn)do for i,e in pairs(v.robots)do table.insertExclusive(etbl,e) end end - end - - - -- do the cloning - warptorio.Cloned_Entities={} - warptorio.IsCloning=true - cf.clone_entities{entities=etbl,destination_offset={0,0},destination_surface=f} --,destination_force=game.forces.player} - warptorio.IsCloning=false - local new_ents=warptorio.Cloned_Entities - warptorio.Cloned_Entities=nil - - -- AAI Vehicles - if(remote.interfaces["aai-programmable-vehicles"])then local rmt="aai-programmable-vehicles" - for k,v in pairs(new_ents)do if(isvalid(v.source) and isvalid(v.destination))then - local sig=remote.call(rmt,"get_unit_by_entity",v.source) if(sig)then remote.call(rmt,"on_entity_deployed",{entity=v.destination,signals=sig.data}) end - end end - end - - --local clones={} for k,v in pairs(etbl)do if(v.valid)then table.insert(clones,v.clone{position=v.position,surface=f,force=v.force}) end end - - -- Recreate teleporter gate - --if(global.Teleporters.offworld)then global.Teleporters.offworld:CheckTeleporterPairs() end - - -- Clean inventories - for k,v in pairs(game.players)do if(v and v.valid)then local iv=v.get_main_inventory() if(iv)then for i,x in pairs(iv.get_contents())do - if(i:sub(1,25)=="warptorio-teleporter-gate")then iv.remove{name=i,count=x} end - if(i:sub(1,20)=="warptorio-harvestpad")then if(x>1)then iv.remove{name=i,count=(x-1)} end end - end end end end - - -- do the player teleport - for k,v in pairs(tpply)do v[1].teleport(f.find_non_colliding_position("character",{v[2][1],v[2][2]},0,1),f) end - - --// cleanup past entities - - for k,v in pairs(etbl)do if(v and v.valid)then v.destroy{raise_destroy=true} end end - for k,v in pairs(blacktbl)do if(v and v.valid)then v.destroy{raise_destroy=true} end end -end - -function warptorio.SurfaceIsWarpzone(f) local n=f.name - local hw=warptorio.GetHomeSurface() - local sf=(n:sub(1,9)=="warpsurf_") -- backwards compatability - local zf=(n:sub(1,9)=="warpzone_") - return (n~="nauvis" and (sf or zf) and f~=hw) -end - -function warptorio.WarpFinished() - local f=warptorio.GetMainSurface() - - --// delete abandoned surfaces - for k,v in pairs(game.surfaces)do - if( table_size(v.find_entities_filtered{type="character"})<1 and v~=f)then - --if(n=="nauvis" and not global.nauvis_is_clear)then global.nauvis_is_clear=true v.clear(true) else - if(warptorio.SurfaceIsWarpzone(v))then game.delete_surface(v) end - end - end - - --warptorio.CheckReactor() - -end - -function warptorio.WarpPost(cf,f) - -- Recreate teleporter gate - if(global.Teleporters.offworld)then global.Teleporters.offworld:CheckTeleporterPairs() end - - --// radar -- game.forces.player.chart(f,{lefttop={x=-256,y=-256},rightbottom={x=256,y=256}}) - - --// build void - --for k,v in pairs({"nw","ne","sw","se"})do local ug=research.level("turret-"..v) or -1 if(ug>=0)then vector.LayCircle("out-of-map",c,vector.circleEx(vector(cx[v].x+0.5,cx[v].y+0.5),math.floor(10+(ug*6)) )) end end - --vector.LayTiles("out-of-map",c,marea) - - if(cf and cf.valid)then warptorio.ConstructPlatformVoid(cf) end - - -end - - - - ---[[ Remotes ]]-- - -warptorio.remote={} - -require("control_main_remotes") - -remote.add_interface("warptorio",warptorio.remote) -remote.add_interface("warptorio2",warptorio.remote) - +--[[------------------------------------- + +Author: Pyro-Fire +https://mods.factorio.com/mod/warptorio2 + +Script: control.lua +Purpose: control stuff + + +Written using Microsoft Notepad. +IDE's are for children. + +How to notepad like a pro: +ctrl+f = find +ctrl+h = find & replace +ctrl+g = show/jump to line (turn off wordwrap n00b) + +Status bar wastes screen space, don't use it. + +Use https://tools.stefankueng.com/grepWin.html to mass search, find and replace many files in bulk. + + +]] --------------------------------------- + +local planets = lib.planets + +--[[ Warptorio Environment ]] -- + +warptorio = warptorio or {} +warptorio.Loaded = false + +require("control_main_helpers") + +warptorio.platform = require("control_platform_classic") +local platform = warptorio.platform + + +require("control_class_teleporter") +require("control_class_harvester") +require("control_class_rails") + + +warptorio.chatcmd = {} +function warptorio.chatcmd.kill(ev) + local ply = game.players[ev.player_index] + local c = ply.character + if (c and c.valid) then c.die(c.force, c) end +end + +commands.add_command("kill", "Suicides the player", warptorio.chatcmd.kill) + + +--[[ Warptorio custom events ]] -- +-- Hook in on_load with +-- local eventdefs=remote.call("warptorio","get_events") +-- script.on_event(eventdefs["on_warp"],func() end) + +events.register("on_warp") -- during Warpout() +events.register("on_post_warp") -- during Warpout() +events.register("warp_started") -- StartWarp() +events.register("warp_stopped") -- StopWarp() + +events.register("harvester_deploy") -- ? +events.register("harvester_recall") -- ? + +events.register("ability_used") -- ? + + +--[[ Warptorio Libraries ]] -- + +warptorio.ChestBeltPairs = { { "loader", "wooden-chest" }, { "fast-loader", "iron-chest" }, { "express-loader", "steel-chest" }, + { "express-loader", function(dir) return (dir == "output" and warptorio.setting("loaderchest_provider") or warptorio.setting("loaderchest_requester")) end }, +} +warptorio.ChestBeltPairs[0] = { "loader", "wooden-chest" } +function warptorio.GetChest(dir) + local lv = research.level("warptorio-logistics") + local lvb = warptorio.ChestBeltPairs[lv] + return (isstring(lvb[2]) and lvb[2] or lvb[2](dir)) +end + +function warptorio.GetBelt(dir) + local lv = research.level("warptorio-logistics") + local lvb = warptorio.ChestBeltPairs[lv] + return (isstring(lvb[1]) and lvb[1] or lvb[1](dir)) +end + +--remotes.register("GetChest",warptorio.GetChest) +--remotes.register("GetBelt",warptorio.GetBelt) + + + +--[[ Warptorio Platform ]] -- + +function warptorio.GetPlatform() return warptorio.platform end + +function warptorio.GetCurrentSurface() return storage.floor.main.host end + +function warptorio.GetMainSurface() return storage.floor.main.host end + +function warptorio.GetHomeSurface() return storage.floor.home and storage.floor.home.host or nil end + +function warptorio.GetMainPlanet() return planets.GetBySurface(warptorio.GetMainSurface()) end -- planetorio + +function warptorio.GetHomePlanet() return planets.GetBySurface(warptorio.GetHomeSurface()) end -- planetorio + +function warptorio.GetNamedSurfaces(tbl) + local t = {} + for k, nm in pairs(tbl) do t[nm] = storage.floor[nm].host end + return t +end + +function warptorio.GetAllSurfaces() + local t = {} + for nm, v in pairs(storage.floor) do t[v.hostindex] = v.host end + return t +end + +function warptorio.GetPlatformSurfaces() + local t = {} + for nm, v in pairs(storage.floor) do if (platform.floors[nm].empty == true) then t[v.hostindex] = v.host end end + return t +end + +function warptorio.GetTeleporterSize(a, b, c, noproto) -- for clearing + local x = 1 + if (a and research.has("warptorio-logistics-1")) then x = x + 2 end + if (b and research.has("warptorio-dualloader-1")) then x = x + 1 end + if (c and research.has("warptorio-triloader")) then x = x + 1 end + return vector((x * 2) + 2, 2) +end + +function warptorio.GetTeleporterHazard(bMain, bFull) -- for hazard tiles + local x = 0 + bFull = (bFull == nil and true or bFull) -- has the tech, or -1 + local lgHas = research.has("warptorio-logistics-1") + local dlHas = research.has("warptorio-dualloader-1") + local tlHas = research.has("warptorio-triloader") + local lgCan = research.can("warptorio-logistics-1") + local dlCan = research.can("warptorio-dualloader-1") + local tlCan = research.can("warptorio-triloader") + + if (lgCan or lgHas) then x = x + 2 end + + if (bMain) then + if (tlHas and dlHas) then + x = x + 2 + elseif (tlHas or dlHas) then + x = x + 1 + if (bFull and ((not tlHas and tlCan) or (not dlHas and dlCan))) then x = x + 1 end + elseif (bFull and (tlCan or dlCan)) then + x = x + 1 + end + else + if (tlCan) then x = x + 1 end + end + + + return vector((x * 2) + 2, 2) +end + +warptorio.EmptyGenSettings = { + default_enable_all_autoplace_controls = false, + width = 32 * 12, + height = 32 * 12, + autoplace_settings = { entity = { treat_missing_as_default = false }, tile = { treat_missing_as_default = false }, decorative = { treat_missing_as_default = false }, }, + starting_area = "none", +} + +function warptorio.MakePlatformFloor(vt) + local f = game.create_surface(vt.name, (vt.empty and warptorio.EmptyGenSettings or nil)) + if (vt.empty) then + f.solar_power_multiplier = settings.global.warptorio_solar_multiplier.value + f.daytime = 0 + f.always_day = true + f.request_to_generate_chunks({ 0, 0 }, 16) + f.force_generate_chunk_requests() + f.destroy_decoratives({}) + for k, v in pairs(f.find_entities()) do entity.destroy(v) end + local area = vector.area(vector(-32 * 8, -32 * 8), vector(32 * 8 * 2, 32 * 8 * 2)) + vector.LayTiles("out-of-map", f, area) + end + local floor = cache.raise_surface(f) + if (vt.init) then lib.call(vt.init, floor) end + storage.floor[vt.key] = floor + return floor +end + +function warptorio.GetPlatformFloor(vt) + if (isstring(vt)) then vt = warptorio.platform.floors[vt] end + local floor + if (vt.key == "main") then -- Special; nauvis / primary planet + floor = storage.floor.main + if (not floor) then + floor = { key = vt.key, host = game.surfaces.nauvis, hostindex = 1 } + storage.floor.main = floor + if (vt.init) then lib.call(vt.init, floor) end + end + elseif (vt.key == "home") then -- Special; homeworld + floor = storage.floor.home + if (not floor) then + floor = { key = vt.key, host = game.surfaces.nauvis, hostindex = 1 } + storage.floor.home = floor + end + else + floor = storage.floor[vt.key] + if (not floor) then floor = warptorio.MakePlatformFloor(vt) end + floor.key = vt.key + end + return floor +end + +function warptorio.ConstructFloor(fn, bhzd) warptorio.ConstructPlatform(platform.floors[fn], bhzd) end + +function warptorio.ConstructFloorHazard(fn) warptorio.ConstructHazard(platform.floors[fn]) end + +function warptorio.ConstructPlatformVoid(surf) + local vt = warptorio.platform.floors["main"] + if (vt.tile) then lib.call(vt.tile, surf, true) end +end + +function warptorio.ConstructPlatform(vt, bhzd) + if (isstring(vt)) then vt = warptorio.platform.floors[vt] end + local floor = warptorio.GetPlatformFloor(vt) + if (floor) then + if (vt.tile) then lib.call(vt.tile, floor.host) end + if (bhzd and vt.hazard) then lib.call(vt.hazard, floor.host) end + end +end + +function warptorio.ConstructPlatforms(bhzd) + local platform = warptorio.GetPlatform() + for nm, vt in pairs(platform.floors) do warptorio.ConstructPlatform(vt, bhzd) end +end + +function warptorio.ConstructHazard(vt) + if (isstring(vt)) then vt = warptorio.platform.floors[vt] end + local floor = warptorio.GetPlatformFloor(vt) + if (floor and vt.hazard) then lib.call(vt.hazard, floor.host) end +end + +function warptorio.ConstructHazards() + local platform = warptorio.GetPlatform() + for nm, vt in pairs(platform.floors) do warptorio.ConstructHazard(vt) end +end + +function warptorio.CheckFloorRadar(floor) + if (research.has("warptorio-charting") and not isvalid(floor.radar)) then + floor.radar = entity.protect(entity.create(floor.host, "warptorio-invisradar", vector(-1, -1)), false, false) + end +end + +function warptorio.CheckPlatformSpecials(self) + local platform = warptorio.platform + local vfloor = platform.floors[self.key] + if (not vfloor) then + game.print("no vfloor error: " .. serpent.line(self)) + end + local sp = vfloor.special + if (not sp) then return end + if (not sp.upgrade) then if (not research.has(sp.tech) or isvalid(self.SpecialEnt)) then return end elseif (research.level(sp.tech) < 1) then return end + local protoname = sp.prototype + local inv = {} + if (sp.upgrade) then + protoname = protoname .. "-" .. research.level(sp.tech) + if (isvalid(self.SpecialEnt) and self.SpecialEnt.name == protoname) then + return + elseif (isvalid(self.SpecialEnt)) then + inv = + warptorio.DestroyPlatformSpecial(self) + end + end + + local f = self.host + local efply = {} + local area = vector.square(vector(-0.5, -0.5), sp.size) + local eft = f.find_entities_filtered { area = area } + local rdr = false + if (isvalid(self.radar)) then + rdr = true + entity.destroy(self.radar) + end + for k, v in pairs(eft) do + if (isvalid(v)) then + if (v.type == "character") then + table.insert(efply, v) + elseif (v ~= self.radar) then + entity.destroy(v) + end + end + end + + local e = entity.protect(entity.create(f, protoname, vector(-0.5, -0.5)), false, false) + self.SpecialEnt = e + if (inv) then for k, v in pairs(inv) do e.get_module_inventory().insert { name = v.name, count = v.count } end end -- beacon modules. Close enough. + warptorio.CheckFloorRadar(self) + vector.cleanplayers(f, area) + players.playsound("warp_in", f) +end + +function warptorio.DestroyPlatformSpecial(self) + local inv + if (isvalid(self.SpecialEnt)) then + local x = self.SpecialEnt.get_module_inventory() + if (x) then inv = x.get_contents() end + entity.destroy(self.SpecialEnt) + end + self.SpecialEnt = nil + return inv +end + +function warptorio.InitPlatform() + storage.floor = {} + + for nm, vt in pairs(warptorio.platform.floors) do + local floor = warptorio.GetPlatformFloor(vt) + if (floor) then + warptorio.ConstructPlatform(vt, true) + end + end +end + +--[[ Bootstrap Initialization and Migrations ]] -- + +events.on_init(function() + events.raise_migrate() + lib.planets.lua() + warptorio.ValidateWarpBlacklist() + --warptorio.HookNewGamePlus() + + -- Custom Intro Message + remote.call("freeplay", "set_custom_intro_message", { "warptorio.intro" }) + -- Disable Rocket Victory + if remote.interfaces.silo_script then + remote.call("silo_script", "set_no_victory", true) + end +end) + + +function warptorio.ApplyMapSettings() + local gmp = game.map_settings + gmp.pollution.diffusion_ratio = 0.105 + + gmp.pollution.min_to_diffuse = 15 -- default 15 + gmp.pollution.ageing = 1.0 -- 1.0 + gmp.pollution.expected_max_per_chunk = 250 + gmp.pollution.min_to_show_per_chunk = 50 + gmp.pollution.pollution_restored_per_tree_damage = 9 + gmp.pollution.enemy_attack_pollution_consumption_modifier = 1.0 + + gmp.enemy_evolution.pollution_factor = 0.0000001 + gmp.enemy_evolution.destroy_factor = 0.0002 -- default 0.002 + + gmp.unit_group.min_group_gathering_time = 600 + gmp.unit_group.max_group_gathering_time = 2 * 600 + gmp.unit_group.max_unit_group_size = 200 + gmp.unit_group.max_wait_time_for_late_members = 2 * 360 + gmp.enemy_expansion.settler_group_min_size = 1 + gmp.enemy_expansion.settler_group_max_size = 1 + + --gmp.enemy_expansion.max_expansion_cooldown = (gmp.enemy_expansion.min_expansion_cooldown*1.25) +end + +events.on_config(function(ev) + if (warptorio.Loaded) then return end + lib.planets.lua() + cache.validate("combinators") + cache.validate("heat") + cache.validate("power") + cache.validate("loaderinput") + cache.validate("loaderoutput") + cache.validate("ldinputf") + cache.validate("ldoutputf") + + storage.warpzone = storage.warpzone or 0 + storage.time_spent_start_tick = storage.time_spent_start_tick or game.tick + storage.time_passed = storage.time_passed or 0 + + storage.warp_charge_time = storage.warp_charge_time or 10 + storage.warp_charge_start_tick = storage.warp_charge_start_tick or 0 + storage.warp_charging = storage.warp_charging or 0 + storage.warp_timeleft = storage.warp_timeleft or 60 * 10 + storage.warp_auto_time = storage.warp_auto_time or 60 * settings.global["warptorio_autowarp_time"].value + storage.warp_auto_end = storage.warp_auto_end or 60 * 60 * settings.global["warptorio_autowarp_time"].value + storage.warp_last = storage.warp_last or game.tick + storage.abilities = storage.abilities or {} + storage.ability_drain = storage.ability_drain or settings.global["warptorio_ability_drain"].value + + storage.pollution_amount = storage.pollution_amount or 1.1 + storage.pollution_expansion = storage.pollution_expansion or 1.1 + storage.ability_uses = storage.ability_uses or 0 + storage.ability_next = storage.ability_next or 0 + storage.radar_uses = storage.radar_uses or 0 + + warptorio.ApplyMapSettings() + + storage.votewarp = storage.votewarp or {} + if (type(storage.votewarp) ~= "table") then storage.votewarp = {} end + warptorio.CheckVotewarps() + + -- todo: storage.warp_blacklist={} + warptorio.ValidateWarpBlacklist() + + --[[ more todo: + for k,v in pairs(gwarptorio.Harvesters)do v.position=warptorio.platform.harvester[k] end + for k,v in pairs(gwarptorio.Teleporters)do v.position=warptorio.Teleporters[k].position end + ]] + + storage.Teleporters = storage.Teleporters or {} + storage.Research = storage.Research or {} -- todo remove this + storage.Turrets = storage.Turrets or {} + storage.Rails = storage.Rails or {} + storage.Harvesters = storage.Harvesters or {} + + + if (not storage.floor) then warptorio.InitPlatform() end + + + for k, v in pairs(storage.Rails) do + v:MakeRails() + end + for k, v in pairs(storage.Teleporters) do + v:CheckTeleporterPairs(true) + end + for k, v in pairs(storage.Harvesters) do + local gdata = warptorio.platform.harvesters[v.key] + v.rank = warptorio.GetPlatformTechLevel(gdata.tech) + v:CheckTeleporterPairs(true) + v:Upgrade() + end + + for k, v in pairs(warptorio.settings) do v() end + + -- todo: warptorio.ApplyMapSettings() + for k, t in pairs(storage.Harvesters) do + table.merge(t, table.deepcopy(warptorio.platform.harvesters[t.key])) + table.merge(t, table.deepcopy(warptorio.platform.HarvesterPointData)) + end + + warptorio.Loaded = true +end) + +events.on_load(function() + warptorio.HookNewGamePlus() + if (storage.Teleporters) then for k, v in pairs(storage.Teleporters) do setmetatable(v, warptorio.TeleporterMeta) end end + if (storage.Harvesters) then for k, v in pairs(storage.Harvesters) do setmetatable(v, warptorio.HarvesterMeta) end end + if (storage.Rails) then for k, v in pairs(storage.Rails) do setmetatable(v, warptorio.RailMeta) end end + --lib.planets.lua() +end) + + +--[[ Players Manager ]] -- + +function warptorio.CheckVotewarps() + for k, v in pairs(storage.votewarp) do if (isvalid(v) or not v.connected) then storage.votewarp[k] = nil end end + cache.updatemenu("hud", "warpbtn") +end + +warptorio.teleDir = { + [0] = { 0, -1 }, + [1] = { 1, -1 }, + [2] = { 1, 0 }, + [3] = { 1, 1 }, + [4] = { 0, 1 }, + [5] = { -1, 1 }, + [6] = { -1, 0 }, + [7] = { -1, -1 } +} +function warptorio.TeleportLogic(ply, e, tent) + if ply.controller_type == defines.controllers.remote then return end + local w = ply.walking_state + local ox = tent.position + local x = e.position + local mp = 2 + if (not ply.character) then mp = 3 end + --game.print(serpent.line(ply.vehicle.name)) + if (ply.driving) then + local veh = ply.vehicle + if (veh.type == "spider-vehicle") then + --[[ local cp = ply.position + local xd, yd = (x.x - cp.x), (x.y - cp.y) + local vpos = vector(ox.x + xd * 3, ox.y + yd * 3) + entity.safeteleport(ply, tent.surface, vpos) + local cn = veh.clone { position = ply.position, surface = ply.surface, force = ply.force } + veh.destroy() + cn.set_driver(ply) + else]] -- + local cp = ply.position + local xd, yd = (x.x - cp.x), (x.y - cp.y) + entity.safeteleport(veh, tent.surface, vector(ox.x + xd, ox.y + yd)) + end + elseif (not w.walking) then + local cp = ply.position + local xd, yd = (x.x - cp.x), (x.y - cp.y) + entity.safeteleport(ply, tent.surface, vector(ox.x + xd * mp, ox.y + yd * mp)) + else + local cp = ply.position + local xd, yd = (x.x - cp.x), (x.y - cp.y) + entity.safeteleport(ply, tent.surface, vector(ox.x + xd * mp, ox.y + yd * mp)) + -- local td=warptorio.teleDir[w.direction] local tpe=ply entity.safeteleport(tpe,tent.surface,vector(ox.x+td[1]*mp,ox.y+td[2]*mp)) + end + players.playsound("teleport", e.surface, e.position) + players.playsound("teleport", tent.surface, tent.position) +end + +cache.player({ + raise = function(cp) + local ply = cp.host + entity.safeteleport(ply, warptorio.GetMainSurface(), vector(0, -5)) + local hud = cache.force_menu("hud", ply) + end, + on_position = function(ply) + local cp = cache.force_player(ply) + if ((cp.tprecent or 0) > game.tick) then return end + local f = ply.surface + local z = vector.square(ply.position, vector(0.8, 0.8)) + if (ply.driving) then + local bbox = ply.vehicle.bounding_box + --game.print(serpent.line(bbox)) + bbox.left_top.x = bbox.left_top.x - 0.8 + bbox.left_top.y = bbox.left_top.y - 0.8 + bbox.right_bottom.x = bbox.right_bottom.x + 0.8 + bbox.right_bottom.y = bbox.right_bottom.y + 0.8 + z = bbox + end + + local ents = f.find_entities_filtered { area = z, type = "accumulator" } --todo + for k, v in pairs(ents) do + local tpg = cache.get_entity(v) + if (tpg and isvalid(tpg.teleport_dest)) then + cp.tprecent = game.tick + 10 + local tgate = tpg.teleport_dest + warptorio.TeleportLogic(ply, v, tgate) + end + end + end, + on_create = function(ply) + local cp = cache.raise_player(ply) + end, + on_join = function(ply) + local menu = cache.force_menu("hud", ply) + entity.safeteleport(ply, warptorio.GetMainSurface(), { 0, -5 }) + end, + on_respawn = function(ply) + local cf = warptorio.GetMainSurface() + local gp = ply + if (gp.surface ~= cf) then + local pos = cf.find_non_colliding_position("character", { 0, -5 }, 0, 1, 1) + gp.teleport(pos, cf) + end + end, + on_left = function(ply) + if (storage.votewarp[ply.index]) then + storage.votewarp[ply.index] = nil + cache.updatemenu("hud", "warpbtn") + end + end, + on_pre_removed = function(ply) + local cp = cache.get_player(ply) + if (cp) then + cache.destroy_player(ply) + end + end, + on_capsule = function(ply, ev) + if (ev.item.name == "warptorio-townportal") then + local p = game.players[ev.player_index] + if (p and p.valid) then + players.playsound("teleport", p.surface, p.position) + entity.safeteleport(p, warptorio.GetMainSurface(), vector(0, -5)) + players.playsound("teleport", p.surface, p.position) + end + elseif (ev.item.name == "warptorio-homeportal" and warptorio.GetHomeSurface()) then + local p = game.players[ev.player_index] + if (p and p.valid) then + players.playsound("teleport", p.surface, p.position) + entity.safeteleport(p, warptorio.GetHomeSurface(), vector(0, -5)) + players.playsound("teleport", p.surface, p.position) + end + end + end, +}) + + + + + +--[[ Warptorio Cache Manager ]] -- + + +-- Pumps and resources cannot be cloned in warptorio +cache.type("offshore-pump", { clone = function(e) e.destroy { raise_destroy = true } end, }) +cache.type("resource", { clone = function(e) e.destroy { raise_destroy = true } end, }) + +-- Simple globally balanced entities +cache.ent("warptorio-heatpipe", + { create = function(e) cache.insert("heat", e) end, destroy = function(e) cache.remove("heat", e) end }) +cache.ent("warptorio-reactor", + { create = function(e) cache.insert("heat", e) end, destroy = function(e) cache.remove("heat", e) end }) +cache.ent("warptorio-accumulator", + { create = function(e) cache.insert("power", e) end, destroy = function(e) cache.remove("power", e) end }) + +events.on_tick(1, 0, "heattick", function(tick) entity.AutoBalanceHeat(cache.get("heat")) end) +events.on_tick(1, 0, "powertick", function(tick) + local t = cache.get("power") + local g, c = 0, 0 + for k, v in pairs(t) do + if (isvalid(v)) then + g = g + v.energy + c = c + v.electric_buffer_size + end + end + + local egdrain = storage.ability_drain + local abc = 0 + if (storage.abilities.stabilizing) then + abc = abc + 1 + end + if (storage.abilities.accelerating) then + abc = abc + 1 + end + if (storage.abilities.scanning) then + abc = abc + 1 + end + + if (abc > 0) then + local gcost = c * egdrain * abc + if (g >= gcost) then + g = math.max(g - gcost, 0) + storage.ability_drain = math.min(egdrain + (0.00000002 * abc), 0.25) + else + storage.abilities.stabilizing = false + storage.abilities.scanning = false + storage.abilities.accelerating = false + end + end + storage.energycount = g + storage.energymax = c + for k, v in pairs(t) do if (v.valid) then v.energy = g * (v.electric_buffer_size / c) end end +end) + +-- Warptorio Combinators +cache.ent("warptorio-combinator", { + create = function(e, ev) cache.insert("combinators", e) end, + destroy = function(e, ev) cache.remove("combinators", e) end, + update = function(e, ev) + local cbh = e.get_or_create_control_behavior() + for k, v in pairs(ev.signals) do cbh.set_signal(k, v) end + end, +}) +function warptorio.RefreshWarpCombinators() + local sigs = warptorio.GetCombinatorSignals() + cache.entcall("combinators", "update", { signals = sigs }) +end + +function warptorio.GetCombinatorSignals() + local tbl = {} + for k, v in pairs(warptorio.Signals) do tbl[k] = { signal = v.signal, count = v.get() } end + return tbl +end + +warptorio.Signals = {} -- 18 max default +warptorio.Signals[1] = { signal = { type = "virtual", name = "signal-W" }, get = function() return (storage.warp_charging >= 1 and (storage.warp_time_left or 10) / 60 or (storage.warp_charge_time or 10)) end } +warptorio.Signals[2] = { + signal = { type = "virtual", name = "signal-X" }, + get = function() + return storage.warp_charging or + 0 + end +} +warptorio.Signals[3] = { + signal = { type = "virtual", name = "signal-A" }, + get = function() + return storage.warp_auto_end / + 60 + end +} +warptorio.Signals[4] = { + signal = { type = "virtual", name = "signal-L" }, + get = function() + local hv = storage.Harvesters.west + return ((hv and hv.deployed) and 1 or 0) + end +} +warptorio.Signals[5] = { + signal = { type = "virtual", name = "signal-R" }, + get = function() + local hv = storage.Harvesters.east + return ((hv and hv.deployed) and 1 or 0) + end +} +warptorio.Signals[6] = { signal = { type = "virtual", name = "signal-P" }, get = function() return storage.time_passed end } + +--[[ Warptorio Gui ]] -- + + +--cache.updatemenu("hud","raise") -- to recreate the menu + +function warptorio.RaiseHUD(v) + local m = cache.get_menu("hud", v) + if (not m) then cache.raise_menu("hud", v) else cache.call_menu("raise", m) end +end + +function warptorio.ResetHUD(p) + if (not p) then + for k, v in pairs(game.players) do warptorio.RaiseHUD(v) end + else + warptorio.RaiseHUD(p) + end +end + +function warptorio.PlayerCanStartWarp(ply) return true end + +function warptorio.ToolRecallHarvester(k, ply) + if (not research.has("warptorio-harvester-" .. k .. "-1")) then return end + local cn = ("warptorio-harvestpad-" .. k .. "-" .. research.level("warptorio-harvester-" .. k)) + if (not ply or (ply and not ply.get_main_inventory().get_contents()[cn])) then + ply.get_main_inventory().insert { name = cn, count = 1 } + players.playsound("warp_in", ply.surface, ply.position) + end + local hv = storage.Harvesters[k] + if (hv and hv.deployed and isvalid(hv.b)) then + players.playsound("warp_in", hv.b.surface, hv.b.position) + hv:Recall() + hv:DestroyB() + end +end + +function warptorio.ToolRecallGate(ply) + if (not research.has("warptorio-teleporter-portal")) then return end + local t = storage.Teleporters.offworld + if (t) then + if (t.b and t.b.valid) then + players.playsound("warp_in", t.b.surface, t.b.position) + t:DestroyLogsB() + t:DestroyB() + end + local inv = ply.get_main_inventory() + if (not inv.get_contents()["warptorio-teleporter-gate-0"]) then + inv.insert { name = "warptorio-teleporter-gate-0", count = 1 } + players.playsound("warp_in", ply.surface, ply.position) + end + end +end + +function HomeSweetHome() + --Warptorio Victory Screen + game.set_win_ending_info({ + title = { "warptorio.victory-title" }, + message = { "warptorio.victory-text" }, + final_message = { "warptorio.victoty-text2" }, + image_path = "__warptorio2__/graphics/victory.png" + }) + game.set_game_state({ + can_continue = true, + game_finished = true, + player_won = true, + }) +end + +cache.vgui("warptorio_toolbutton", + { + click = function(elm, ev) + local menu = cache.get_menu("hud", elm.player_index) + local b = menu.toolbar + b.visible = not b.visible + end + }) +cache.vgui("warptorio_tool_hv_west", + { click = function(elm, ev) warptorio.ToolRecallHarvester("west", game.players[elm.player_index]) end }) +cache.vgui("warptorio_tool_hv_east", + { click = function(elm, ev) warptorio.ToolRecallHarvester("east", game.players[elm.player_index]) end }) +cache.vgui("warptorio_tool_planet_gate", + { click = function(elm, ev) warptorio.ToolRecallGate(game.players[elm.player_index]) end }) + + +cache.vgui("warptorio_homeworld", { + click = function(elm, ev) + local menu = cache.get_menu("hud", elm.player_index) + if (menu.hometmr < game.tick) then + menu.hometmr = game.tick + (60 * 5) + cache.call_menu("clocktick", menu) + else + storage.homeworld = storage.warpzone + local f = storage.floor.main.host + storage.floor.home.host = f + storage.floor.home.hostindex = f.index + players.playsound("warp_in", storage.floor.home.host) + game.print({ "warptorio.homeworld-set" }) + menu.hometmr = 0 + cache.call_menu("clocktick", menu) + HomeSweetHome() --victory screen + end + end, +}) + +local HUD = {} +warptorio.HUD = HUD +function HUD.clocktick(menu) + local ply = menu.host + if (storage.warp_charging >= 1) then + menu.charge_time.caption = { "warptorio.warp-in", util.formattime(val or (storage.warp_time_left or 0)) } + elseif (menu.charge_time) then + menu.charge_time.caption = { "warptorio.charge_time", util.formattime((storage.warp_charge_time or 0) * 60) } + end + + menu.time_passed.caption = { "warptorio.time_passed", util.formattime(storage.time_passed or 0) } + if (warptorio.IsAutowarpEnabled()) then + menu.autowarp.caption = { "warptorio.autowarp-in", util.formattime(storage.warp_auto_end) } + else + menu.autowarp.caption = "" + end + + menu.hometmr = menu.hometmr or 0 + if (menu.homeworld) then + if (menu.hometmr > game.tick) then + menu.homeworld.caption = { "warptorio.confirm_homeworld", util.formattime(menu.hometmr - game.tick) } + else + menu.homeworld.caption = { "warptorio.button-homeworld" } + end + end + + if (menu.energybar) then + local cureng = storage.energycount or 0 + local maxeng = math.max(storage.energymax or 1, 1) + local energydif = cureng - (menu.last_energy or 0) + menu.last_energy = cureng + + local egdrain = storage.ability_drain * 100 * 60 + local abc = 0 + local r = menu.stabilizer + if (r) then + if (storage.abilities.stabilizing) then + abc = abc + 1 + r.caption = { "warptorio.stabilize-on", "-" .. math.roundx(egdrain, 2) .. "%/sec" } + else + r.caption = { "warptorio.stabilize" } + end + end + local r = menu.accelerator + if (r) then + if (storage.abilities.accelerating) then + abc = abc + 1 + r.caption = { "warptorio.accel-on", "-" .. math.roundx(egdrain, 2) .. "%/sec" } + else + r.caption = { "warptorio.accel" } + end + end + local r = menu.radar + if (r) then + if (storage.abilities.scanning) then + abc = abc + 1 + r.caption = { "warptorio.radar-on", "-" .. math.roundx(egdrain, 2) .. "%/sec" } + else + r.caption = { "warptorio.radar" } + end + end + menu.energybar_energy.caption = " " .. string.energy_to_string(cureng) .. " " + menu.energybar_energymax.caption = " " .. string.energy_to_string(maxeng) .. " " + menu.energybar_energybal.caption = " (" .. + (energydif >= 1 and "+" or (energydif > 0 and "+-" or "")) .. string.energy_to_string(energydif) .. "/sec) " + menu.energybar_energybal.style.font_color = (energydif > 0 and { r = 0, g = 1, b = 0 } or (energydif < 0 and { r = 1, g = 0, b = 0 } or { r = 0.75, g = 0.75, b = 0.75 })) + menu.energybar.value = cureng / maxeng + menu.energybar_energypct.caption = " " .. math.roundx((cureng / maxeng) * 100, 2) .. "% " + if (abc > 0) then + menu.energybar_energypctx.caption = "-" .. math.roundx(egdrain * abc, 2) .. "%/sec" + else + menu.energybar_energypctx.caption = "" + end + end +end + +function HUD.raise(menu, ev) + local ply = menu.host + menu.frame = vgui.create(ply.gui.left, { name = "warptorio_frame", type = "flow", direction = "vertical" }) + menu.frame.style.left_padding = 4 + menu.row1 = vgui.create(menu.frame, { name = "warptorio_row1", type = "flow", direction = "horizontal" }) + menu.row2 = vgui.create(menu.frame, { name = "warptorio_row2", type = "flow", direction = "horizontal" }) + menu.row4 = vgui.create(menu.frame, { name = "warptorio_row4", type = "flow", direction = "horizontal" }) + menu.row3 = vgui.create(menu.frame, { name = "warptorio_row3", type = "flow", direction = "horizontal" }) + menu.row1.clear() + menu.row2.clear() + menu.row3.clear() + menu.row4.clear() + + menu.warpbtn = vgui.create(menu.row1, + { name = "warptorio_warpbutton", type = "button", caption = { "warptorio.button-warp", "-" } }) + if (research.has("warptorio-toolbar")) then + menu.toolbtn = vgui.create(menu.row1, + { name = "warptorio_toolbutton", type = "button", caption = { "warptorio.toolbutton", "-" } }) + end + if (research.level("warptorio-reactor") >= 8) then + menu.warptgt = vgui.create(menu.row1, { name = "warptorio_warptarget", type = "drop-down" }) + HUD.rebuild_warptargets(menu) + HUD.warptarget(menu, + { tgt = (sx == nil and "(Random)" or (sx == "home" and "(Homeworld)" or (sx == "(nauvis)" and "nauvis" or sx))) }) + end + + menu.time_passed = vgui.create(menu.row1, { name = "warptorio_time_passed", type = "label" }) + menu.charge_time = vgui.create(menu.row1, { name = "warptorio_charge_time", type = "label" }) + menu.warpzone = vgui.create(menu.row1, + { name = "warptorio_warpzone", type = "label", caption = { "warptorio.warpzone", storage.warpzone or 0 } }) + menu.autowarp = vgui.create(menu.row1, { name = "warptorio_autowarp", type = "label" }) + + if (research.has("warptorio-homeworld")) then + menu.homeworld = vgui.create(menu.row1, + { name = "warptorio_homeworld", type = "button", caption = { "warptorio.button-homeworld" } }) + end + + + local hasabil = false + if (research.has("warptorio-stabilizer")) then + hasabil = true + menu.stabilizer = vgui.create(menu.row2, + { name = "warptorio_stabilizer", type = "button", caption = { "warptorio.stabilize", "-" } }) + end + if (research.has("warptorio-accelerator")) then + hasabil = true + menu.accelerator = vgui.create(menu.row2, + { name = "warptorio_accelerator", type = "button", caption = { "warptorio.accel", "-" } }) + end + if (research.has("warptorio-charting")) then + hasabil = true + menu.radar = vgui.create(menu.row2, + { name = "warptorio_radar", type = "button", caption = { "warptorio.radar", "-" } }) + end + if (hasabil) then + menu.last_energy = menu.last_energy or 100 + local energydif = 1000 - menu.last_energy + menu.energybar_label = vgui.create(menu.row4, + { name = "warptorio_energybar_label", type = "label", caption = { "warptorio.energybar", "-" } }) + menu.energybar_energy = vgui.create(menu.row4, { + name = "warptorio_energybar_energy", + type = "label", + caption = + " 100kw " + }) + menu.energybar_energy.style.font_color = { r = 0, g = 1, b = 0 } + + menu.energybar_energydiv = vgui.create(menu.row4, + { name = "warptorio_energybar_energydiv", type = "label", caption = " / " }) + + menu.energybar_energymax = vgui.create(menu.row4, + { name = "warptorio_energybar_energymax", type = "label", caption = " 0kw " }) + menu.energybar_energymax.style.font_color = { r = 0.25, g = 1, b = 1 } + + + menu.energybar_energybal = vgui.create(menu.row4, + { name = "warptorio_energybar_energybal", type = "label", caption = " (+100.32MW/sec) " }) + menu.energybar_energybal.style.font_color = (energydif > 0 and { r = 0, g = 1, b = 0 } or (energydif == 0 and { r = 1, g = 1, b = 0 } or { r = 1, g = 0, b = 0 })) + + + menu.energybar_energydivb = vgui.create(menu.row4, + { name = "warptorio_energybar_energydivb", type = "label", caption = " | " }) + + + menu.energybar = vgui.create(menu.row4, { name = "warptorio_time_passed", type = "progressbar", value = 0.3 }) + menu.energybar.style.natural_width = 250 + menu.energybar.style.top_padding = 7 + menu.energybar.style.bottom_padding = 7 + + menu.energybar_energypcta = vgui.create(menu.row4, + { name = "warptorio_energybar_energypcta", type = "label", caption = " | " }) + menu.energybar_energypct = vgui.create(menu.row4, + { name = "warptorio_energybar_energypct", type = "label", caption = "25%" }) + menu.energybar_energypct.style.font_color = { r = 1, g = 1, b = 1 } + menu.energybar_energypctx = vgui.create(menu.row4, + { name = "warptorio_energybar_energypctx", type = "label", caption = "-3%/sec" }) + menu.energybar_energypctx.style.font_color = { r = 1, g = 0, b = 0 } + end + + if (research.has("warptorio-toolbar")) then + menu.toolbar = vgui.create(menu.row3, + { name = "warptorio_toolframe", type = "flow", direction = "horizontal", visible = false }) + menu.toolbar.clear() + menu.tool_harvester_west = vgui.create(menu.toolbar, + { name = "warptorio_tool_hv_west", type = "sprite-button", sprite = "entity/warptorio-harvestportal-1", tooltip = { "warptorio.tool_hv_west", "-" } }) + menu.tool_planet_gate = vgui.create(menu.toolbar, + { name = "warptorio_tool_planet_gate", type = "sprite-button", sprite = "item/warptorio-teleporter-gate-0", tooltip = { "warptorio.tool_planet_gate", "-" } }) + menu.tool_harvester_east = vgui.create(menu.toolbar, + { name = "warptorio_tool_hv_east", type = "sprite-button", sprite = "entity/warptorio-harvestportal-1", tooltip = { "warptorio.tool_hv_east", "-" } }) + end + + HUD.clocktick(menu) + HUD.rebuild_warptargets(menu) + local sx = storage.planet_target +end + +function HUD.rebuild_warptargets(menu, ev) + if (menu.warptgt) then + local tgl = { "(Random)" } + if (research.has("warptorio-homeworld")) then + table.insert(tgl, "(Homeworld)") + table.insert(tgl, "(Nauvis)") + end + if (research.has("warptorio-charting")) then + for k, v in pairs(lib.planets.GetTemplates()) do + table.insert(tgl, v.key) + end + end + menu.warptgt.items = tgl + HUD.warptarget(menu, { tgt = storage.planet_target }) + end +end + +function HUD.warptarget(menu, ev) + local ply = menu.host + if (not menu.warptgt or ply.index == ev.ply) then return end + local elm, items = menu.warptgt + if (elm) then items = elm.items end + if (not items) then return end + for idx, kv in pairs(items) do if (type(kv) == "string" and kv:lower() == ev.tgt) then elm.selected_index = idx end end +end + +function HUD.warpbtn(menu) + local r = menu.warpbtn + local ply = menu.host + if (storage.warp_charging >= 1) then + r.caption = { "warptorio.warping", "-" } + r.enabled = false + else + local cx = table.Count(storage.votewarp) + local c = table.Count(game.connected_players) -- table.Count(game.non_afk_players) + if (c > 1) then + local vcn = math.ceil(c * warptorio.setting("votewarp_multi")) + if (storage.votewarp[ply.index] and cx < vcn) then r.enabled = false else r.enabled = true end + if (cx > 0) then + r.caption = { "warptorio.button-votewarp-count", cx, vcn } + else + r.caption = { "warptorio.button-votewarp", "-" } + end + else + r.enabled = true + r.caption = { "warptorio.button-warp", "-" } + menu.warpzone.caption = { "warptorio.warpzone_label", storage.warpzone or 0 } + end + end +end + +cache.menu("hud", HUD) + +cache.vgui("warptorio_warptarget", { + selection_changed = function(elm, ev) + local ply = game.players[elm.player_index] + local s = elm.items[elm.selected_index] + if (not s) then return end + local sx = s:lower() + local vt = (sx == "(random)" and nil or (sx == "(homeworld)" and "home" or (sx == "(nauvis)" and "nauvis" or sx))) + if (vt ~= storage.planet_target) then + storage.planet_target = vt + game.print({ "warptorio.player_set_warp_target", ply.name, s }) + cache.updatemenu("hud", "warptarget", { ply = elm.player_index, tgt = sx }) + end + end, +}) + +function warptorio.StartWarp() + if (storage.warp_charging < 1) then + events.vraise("warp_started") + storage.warp_charge_start_tick = game.tick + storage.warp_charging = 1 + players.playsound("reactor-stabilized") + cache.updatemenu("hud", "warpbtn") + end +end + +function warptorio.StopWarp() + if (storage.warp_charging > 0) then + events.vraise("warp_stopped") + storage.warp_charging = 0 + storage.warp_charge_time = storage.warp_time_left / 60 + storage.warp_charge_start_tick = 0 + end +end + +function warptorio.IsWarping() return storage.warp_charging > 0 end + +cache.vgui("warptorio_warpbutton", { + click = function(elm, ev) + local ply = game.players[elm.player_index] + local menu = cache.get_menu("hud", elm.player_index) + if (storage.warp_charging < 1) then + local c = table.Count(game.connected_players) -- table.Count(game.non_afk_players) + if (c > 1 and warptorio.setting("votewarp_multi") > 0) then --votewarp + local vcn = math.ceil(c * warptorio.setting("votewarp_multi")) + storage.votewarp[ply.index] = ply + local cx = table.Count(storage.votewarp) + if (vcn <= 1 or cx >= vcn) then + warptorio.StartWarp() + game.print({ "warptorio.player_started_warpout", ply.name }) + else + players.playsound("teleport") + game.print({ "warptorio.player_want_vote_warp", ply.name, cx, vcn }) + cache.updatemenu("hud", "warpbtn") + end + elseif (warptorio.PlayerCanStartWarp(ply)) then + storage.warp_charge_start_tick = game.tick + storage.warp_charging = 1 + players.playsound("reactor-stabilized") + cache.updatemenu("hud", "warpbtn") + else + ply.print({ "warptorio.same-planet-error" }) + end + end + end, +}) + +cache.vgui("warptorio_stabilizer", { + click = function(elm, ev) + local ply = game.players[elm.player_index] + local menu = cache.get_menu("hud", elm.player_index) + storage.abilities.stabilizing = not storage.abilities.stabilizing + end, +}) +cache.vgui("warptorio_accelerator", { + click = function(elm, ev) + local ply = game.players[elm.player_index] + local menu = cache.get_menu("hud", elm.player_index) + storage.abilities.accelerating = not storage.abilities.accelerating + end, +}) +cache.vgui("warptorio_radar", { + click = function(elm, ev) + local ply = game.players[elm.player_index] + local menu = cache.get_menu("hud", elm.player_index) + storage.abilities.scanning = not storage.abilities.scanning + end, +}) + +--[[ Warping stuff ]] -- + +function warptorio.ValidateWarpBlacklist() +end + +local staticBlacklist = { "highlight-box", "big_brother-blueprint-radar", "osp_repair_radius" } +function warptorio.GetWarpBlacklist() + return staticBlacklist +end + +-- OnEntCloned +events.on_event(defines.events.on_entity_cloned, function(ev) + if (warptorio.IsCloning) then + table.insert(warptorio.Cloned_Entities, { + source = ev.source, + destination = ev.destination + }) + end + if (ev.source.type == "spider-vehicle") then + for k, v in pairs(game.players) do + if (v.driving and v.vehicle == ev.source) then + entity.safeteleport(v, ev.destination.surface, ev.destination.position) + ev.destination.set_driver(v) + end + --[[ + local inv = v.get_main_inventory() + if (inv) then + for i = 1, #inv, 1 do + local e = inv[i] + if (e and e.valid_for_read and e.connected_entity == ev.source) then + e.connected_entity = ev.destination + end + end + local e = v.cursor_stack + if (e and e.valid_for_read and e.connected_entity == ev.source) then e.connected_entity = ev.destination end + end]] + end + end +end) + +function warptorio.CountPlatformEntities() return 5 end -- todo + +function warptorio.Warpout(key) + warptorio.IsWarping = true + for k, v in pairs(storage.Harvesters) do if (v.deployed) then v:Recall(true) end end + + local cp = warptorio.GetMainPlanet() + local cf = warptorio.GetMainSurface() + warptorio.WarpPreBuildPlanet(key) + local f, w, frc = warptorio.WarpBuildPlanet(key) + warptorio.WarpPostBuildPlanet(w) + + storage.floor.main.host = f + storage.floor.main.hostindex = f.index + + warptorio.ConstructPlatform("main", true) + + events.vraise("on_warp", { newsurface = f, newplanet = w, oldsurface = cf, oldplanet = cp }) + if (cp and cp.on_warp) then lib.call(cp.on_warp, f, w, cf, cp) end + + warptorio.Warp(cf, f) + warptorio.WarpPost(cf, f) + + -- reset pollution & biters + game.forces["enemy"].set_evolution_factor(0) + storage.pollution_amount = 1.1 + storage.pollution_expansion = 1.1 + + -- warp sound + players.playsound("warp_in") + + warptorio.WarpFinished() + events.vraise("on_post_warp", { newsurface = f, newplanet = w }) + if (w.postwarpout) then lib.call(w.postwarpout, { newsurface = f, newplanet = w }) end + warptorio.IsWarping = false +end + +function warptorio.WarpPreBuildPlanet(key) + storage.warp_charge = 0 + storage.warp_charging = 0 + storage.votewarp = {} + storage.warp_last = game.tick + + storage.warpzone = storage.warpzone + 1 + + -- Warp chargetime cooldown math + local cot = warptorio.CountPlatformEntities() + + local sgZone = warptorio.setting("warpcharge_zone") + local sgZoneGain = warptorio.setting("warpcharge_zonegain") + local sgMax = warptorio.setting("warpcharge_max") + local sgFactor = warptorio.setting("warp_charge_factor") + local sgMul = warptorio.setting("warpcharge_multi") + + storage.warp_charge_time = math.min( + 10 + (cot / sgFactor) + (storage.warpzone * sgMul) + + (sgZoneGain * (math.min(storage.warpzone, sgZone) / sgZone) * 60), + 60 * sgMax) + storage.warp_time_left = 60 * storage.warp_charge_time + + -- Autowarp timer math + local rta = research.level("warptorio-reactor") + storage.warp_auto_time = 60 * warptorio.setting("autowarp_time") + 60 * 10 * rta + storage.warp_auto_end = game.tick + storage.warp_auto_time * 60 + + -- Abilities + --storage.ability_uses=0 + --storage.radar_uses=0 + --storage.ability_next=game.tick+60*60*warptorio.setting("ability_warp") + + storage.ability_drain = warptorio.setting("ability_drain") or 0.00001 + storage.abilities = {} + + -- Update guis + --if(research.has("warptorio-accelerator") or research.has("warptorio-charting") or research.has("warptorio-stabilizer"))then end --gui.uses() gui.cooldown() + --if(warptorio.IsAutowarpEnabled())then gui.autowarp() end + --gui.warpzone() + cache.updatemenu("hud", "warpbtn") + + -- packup old teleporter gate + --local tp=storage.Teleporters.offworld if(tp and tp:ValidB())then tp:DestroyB() tp:DestroyLogsB() end + -- Recall harvester plates and players on them. + --for k,v in pairs(storage.Harvesters)do v:Recall(true) end +end + +function warptorio.WarpBuildPlanet(key) + local nplanet + if (key) then + nplanet = remote.call("planetorio", "FromTemplate", "warpzone_" .. storage.warpzone, key) + else + local vplanet = warptorio.GetMainPlanet() + local lvl = research.level("warptorio-reactor") + if (lvl >= 8) then + local wx = storage.planet_target + if (wx == "home" or wx == "nauvis") then + if (research.has("warptorio-homeworld")) then + local hf = (wx == "nauvis" and game.surfaces.nauvis or storage.floor.home.host) + if (warptorio.GetMainSurface() ~= hf and math.random(1, 100) <= warptorio.setting("warpchance")) then + local hp = remote.call("planetorio", "GetBySurface", hf) or { name = "Nauvis" } + game.print({ "warptorio.successful_warp" }) + game.print({ "warptorio.home_sweet_home", hp.name }) + return hf, hp + end + end + elseif (wx and math.random(1, 100) <= warptorio.setting("warpchance")) then + nplanet = remote.call("planetorio", "FromTemplate", "warpzone_" .. storage.warpzone, wx) + if (nplanet) then game.print({ "warptorio.successful_warp" }) end + end + end + if (not nplanet) then + nplanet = remote.call("planetorio", "SimplePlanetRoll", "warpzone_" .. storage.warpzone, + { zone = storage.warpzone, prevplanet = vplanet }) + end -- planetorio, modifiers={{"",stuff}}) + end + if (research.has("warptorio-charting") or not nplanet.planet.desc) then game.print(nplanet.planet.name) end + if (nplanet.planet.desc) then game.print(nplanet.planet.desc) end + return nplanet.surface, nplanet.planet, nplanet.force +end + +function warptorio.WarpPostBuildPlanet(planet) + if (planet.warp_multiply) then + storage.warp_charge_time = storage.warp_charge_time * planet.warp_multiply + storage.warp_time_left = storage.warp_time_left * planet.warp_multiply + end + --gui.charge_time() +end + +function warptorio.Warp(cf, f) -- Find and clone entities to new surface + --cf.find_entities() + --cf.clone_entities{surface=f,entities=tbl} + + -- call to platform() + + if (storage.Teleporters.offworld) then storage.Teleporters.offworld:DestroyPointTeleporter(2) end + + local etbl, tpply = warptorio.platform.GetWarpables(cf, f) --{},{} + for k, v in pairs(etbl) do if (not isvalid(v)) then etbl[k] = nil end end + + local blacktbl = {} + for k, v in pairs(etbl) do + if (table.HasValue(warptorio.GetWarpBlacklist(), v.name)) then + table.insert(blacktbl, v) + etbl[k] = nil + end + end + for k, v in pairs(etbl) do if (not v or not v.valid) then etbl[k] = nil end end + + -- find logistics networks and robots among entities to catch robots outside the platform + if (settings.global["warptorio_robot_warping"].value == true) then + local lgn = {} + for k, v in pairs(etbl) do + if (v.type == "roboport") then + local g = v.logistic_network + if (g and g.valid) then table.insertExclusive(lgn, g) end + end + end + for k, v in pairs(lgn) do for i, e in pairs(v.robots) do table.insertExclusive(etbl, e) end end + end + + -- do the cloning + warptorio.Cloned_Entities = {} + warptorio.IsCloning = true + cf.clone_entities { entities = etbl, destination_offset = { 0, 0 }, destination_surface = f } --,destination_force=game.forces.player} + warptorio.IsCloning = false + local new_ents = warptorio.Cloned_Entities + warptorio.Cloned_Entities = nil + + -- AAI Vehicles + if (remote.interfaces["aai-programmable-vehicles"]) then + local rmt = "aai-programmable-vehicles" + for k, v in pairs(new_ents) do + if (isvalid(v.source) and isvalid(v.destination)) then + local sig = remote.call(rmt, "get_unit_by_entity", v.source) + if (sig) then remote.call(rmt, "on_entity_deployed", { entity = v.destination, signals = sig.data }) end + end + end + end + + --local clones={} for k,v in pairs(etbl)do if(v.valid)then table.insert(clones,v.clone{position=v.position,surface=f,force=v.force}) end end + + -- Recreate teleporter gate + --if(storage.Teleporters.offworld)then storage.Teleporters.offworld:CheckTeleporterPairs() end + + -- Clean inventories + for k, v in pairs(game.players) do + if (v and v.valid) then + local iv = v.get_main_inventory() + if (iv) then + for i, x in pairs(iv.get_contents()) do + if (x.name:sub(1, 25) == "warptorio-teleporter-gate") then iv.remove { name = x.name, count = x.count } end + if (x.name:sub(1, 20) == "warptorio-harvestpad") then if (x.count > 1) then iv.remove { name = x.name, count = (x.count - 1) } end end + end + end + end + end + + -- do the player teleport + for k, v in pairs(tpply) do v[1].teleport(f.find_non_colliding_position("character", { v[2][1], v[2][2] }, 0, 1), f) end + + --// cleanup past entities + + for k, v in pairs(etbl) do if (v and v.valid) then v.destroy { raise_destroy = true } end end + for k, v in pairs(blacktbl) do if (v and v.valid) then v.destroy { raise_destroy = true } end end +end + +function warptorio.SurfaceIsWarpzone(f) + local n = f.name + local hw = warptorio.GetHomeSurface() + local sf = (n:sub(1, 9) == "warpsurf_") -- backwards compatability + local zf = (n:sub(1, 9) == "warpzone_") + return (n ~= "nauvis" and (sf or zf) and f ~= hw) +end + +function warptorio.WarpFinished() + local f = warptorio.GetMainSurface() + + --// delete abandoned surfaces + for k, v in pairs(game.surfaces) do + if (table_size(v.find_entities_filtered { type = "character" }) < 1 and v ~= f) then + --if(n=="nauvis" and not storage.nauvis_is_clear)then storage.nauvis_is_clear=true v.clear(true) else + if (warptorio.SurfaceIsWarpzone(v)) then game.delete_surface(v) end + end + end + + --warptorio.CheckReactor() +end + +function warptorio.WarpPost(cf, f) + -- Recreate teleporter gate + if (storage.Teleporters.offworld) then storage.Teleporters.offworld:CheckTeleporterPairs() end + + --// radar -- game.forces.player.chart(f,{lefttop={x=-256,y=-256},rightbottom={x=256,y=256}}) + + --// build void + --for k,v in pairs({"nw","ne","sw","se"})do local ug=research.level("turret-"..v) or -1 if(ug>=0)then vector.LayCircle("out-of-map",c,vector.circleEx(vector(cx[v].x+0.5,cx[v].y+0.5),math.floor(10+(ug*6)) )) end end + --vector.LayTiles("out-of-map",c,marea) + + if (cf and cf.valid) then warptorio.ConstructPlatformVoid(cf) end +end + +--[[ Remotes ]] -- + +warptorio.remote = {} + +require("control_main_remotes") + +remote.add_interface("warptorio", warptorio.remote) +remote.add_interface("warptorio2", warptorio.remote) diff --git a/control_main_helpers.lua b/control_main_helpers.lua index b6e634b..ee62cd8 100644 --- a/control_main_helpers.lua +++ b/control_main_helpers.lua @@ -1,826 +1,1075 @@ - ---[[ Todo list ]]-- - ---[[ -function warptorio.CountEntities() local c=0 for k,v in pairs(gwarptorio.floor)do if(v.surface and v.surface.valid and k~="main" and k~="home")then - c=c+table_size(v.surface.find_entities()) -end end return c end -- used in warpout - -function warptorio.BlueprintEntityIsBlacklisted(e) if(warptorio.EntityIsPlatform(e))then return true end return false end -function warptorio.on_player_setup_blueprint.generic(ev) - if(settings.global.warptorio_no_blueprint.value)then return end - local mp=ev.mapping if(not mp)then return end local bpe=mp.get() local ply=game.players[ev.player_index] - local cst=ply.blueprint_to_setup if(not cst or not cst.valid_for_read)then cst=ply.cursor_stack end if(not cst or not cst.valid_for_read)then return end - local ents=cst.get_blueprint_entities() - if(ents)then for k,v in pairs(ents)do if(warptorio.BlueprintEntityIsBlacklisted(bpe[v.entity_number]))then ents[k]=nil end end cst.set_blueprint_entities(ents) end -end - - -function warptorio.PlanetEntityIsPlatform(e) local r --=(e.name:sub(1,9)=="warptorio") if(r)then return true end - for k,v in pairs(gwarptorio.Rails)do if(table.HasValue(v.rails,e))then return true end end - for k,v in pairs{gwarptorio.Teleporters.offworld,gwarptorio.Teleporters.b1}do if(v:ManagesEntity(e))then return true end end -end -function warptorio.EntityIsPlatform(e) local r --=(e.name:sub(1,9)=="warptorio") if(r)then return true end - for k,v in pairs(gwarptorio.Rails)do if(v:ManagesEntity(e))then return true end end - for k,v in pairs(gwarptorio.Teleporters)do if(v:ManagesEntity(e))then return true end end - for k,v in pairs(gwarptorio.Harvesters)do if(v:ManagesEntity(e))then return true end end - for k,v in pairs(gwarptorio.floor)do if(v:ManagesEntity(e))then return true end end - return false -end -]] - ---[[ TODO - -function warptorio.MigrateTileFloor(floor,buildfunc) local f=floor.surface - vector.LayTiles("grass-1",f,vector.square(vector(-1,-1),vector(512,512))) - buildfunc() - local tcs={} - for k,v in pairs(f.find_tiles_filtered{name="grass-1"})do table.insert(tcs,{name="out-of-map",position=v.position}) end - f.set_tiles(tcs,true) -end -function warptorio.MigrateHarvesterFloor() - warptorio.BuildB3() - local rLogs=game.forces.player.technologies["warptorio-logistics-1"].researched - for k,v in pairs(global.warptorio.Harvesters)do local f,pos v:DestroyLogs() - if(v.deployed)then f,pos=v.b.surface,v.deploy_position v:Recall() end - v:DestroyA() v:DestroyB() v:Warpin() if(rLogs)then v:SpawnLogs() end v:Upgrade() - end -end -function warptorio.MigrateTiles() if(warptorio.tilesAreMigrated)then return end warptorio.tilesAreMigrated = true - local flv=gwarptorio.floor.b1 if(flv)then warptorio.MigrateTileFloor(flv,warptorio.BuildB1) end - local flv=gwarptorio.floor.b2 if(flv)then warptorio.MigrateTileFloor(flv,warptorio.BuildB2) end - local flv=gwarptorio.floor.b3 if(flv)then warptorio.MigrateTileFloor(flv,warptorio.MigrateHarvesterFloor) end - warptorio.ValidateCache() - warptorio.BuildPlatform() -end - - - -function warptorio.init.floors(bhzd) - if(not gwarptorio.floor)then gwarptorio.floor={} end - local m=gwarptorio.floor.main if(not m)then m=new(FLOOR,"main",8) m.surface=game.surfaces["nauvis"] end - local m=gwarptorio.floor.b1 if(not m)then m=new(FLOOR,"b1",16) m:MakeEmptySurface() end - local m=gwarptorio.floor.b2 if(not m)then m=new(FLOOR,"b2",17) m:MakeEmptySurface() end - local m=gwarptorio.floor.b3 if(not m)then m=new(FLOOR,"b3",17) m.ovalsize={x=19,y=17} m:MakeEmptySurface() end - warptorio.BuildPlatform(bhzd) - warptorio.BuildB1(bhzd) - warptorio.BuildB2(bhzd) - warptorio.BuildB3(bhzd) -end -function warptorio.RebuildFloors(bhzd) warptorio.init.floors(bhzd) end - - -function warptorio.BuildHazards() warptorio.BuildPlatformHazard() warptorio.BuildB1Hazard() warptorio.BuildB2Hazard() warptorio.BuildB3Hazard() end - - - -function warptorio.BuildPlatformHazard() - -end - -function warptorio.BuildPlatform(bhzd) - - if(bhzd~=true)then warptorio.BuildPlatformHazard() end - - players.playsound("warp_in",f) -end - - -function warptorio.CheckReactor() - local m=gwarptorio.floor.main - local rlv=research.level("warptorio-reactor") -- gwarptorio.Research["reactor"] or 0 - if(rlv>=6 and (not gwarptorio.warp_reactor or not gwarptorio.warp_reactor.valid))then - local f=m.surface - vector.clean(f,vector.square(vector(-0.5,-0.5),vector(5,5))) - local e=f.create_entity{name="warptorio-reactor",position={-1,-1},force=game.forces.player,player=game.players[1]} - vector.cleanplayers(f,vector.square(vector(-0.5,-0.5),vector(5,5))) - gwarptorio.warp_reactor=e - e.minable=false - end -end - - - - -]]-- - - - - ---[[ Settings ]]-- -function warptorio.setting(n) return settings.global["warptorio_"..n].value end - -warptorio.settings={} local setter=warptorio.settings - -function setter.warptorio_autowarp_disable() warptorio.ResetHUD() end -function setter.warptorio_autowarp_always() warptorio.ResetHUD() end -function setter.warptorio_water() warptorio.EarlyWater(settings.global["warptorio_water"].value) end -function setter.warptorio_carebear() warptorio.Carebear(settings.global["warptorio_carebear"].value) end -function setter.warptorio_solar_multiplier() warptorio.SolarMultiplier(settings.global["warptorio_solar_multiplier"].value) end -function setter.warptorio_loaderchest_provider() warptorio.LoaderChestChanged(true) end -function setter.warptorio_loaderchest_requester() warptorio.LoaderChestChanged(false) end -function setter.warptorio_loader_top() warptorio.LoaderSideChanged(true) end -function setter.warptorio_loader_bottom() warptorio.LoaderSideChanged(false) end -function setter.warptorio_combinator_offset() warptorio.CombinatorOffsetChanged() end -function setter.warptorio_hide_sprites() for k,v in pairs(global.Teleporters)do v:CheckPointSprites(1) v:CheckPointSprites(2) end end - - -function warptorio.CombinatorOffsetChanged() - for k,v in pairs(global.Harvesters)do v:DestroyCombos() v:CheckCombo() end -end -function warptorio.LoaderChestChanged(bprovider) -end -function warptorio.LoaderSideChanged(btop) - for k,v in pairs(global.Teleporters)do local g=v:Data().top if((btop and g) or (not btop and not g))then - v:DestroyPointLogistics(1) - v:DestroyPointLogistics(2) - v:CheckTeleporterPairs(true) - end end -end - -function warptorio.SolarMultiplier(x) - for k,v in pairs(warptorio.GetPlatformSurfaces())do v.solar_power_multiplier=x end -end - -warptorio.carebearItems={ -["stone"]=20,["coal"]=20,["iron-plate"]=20,["copper-plate"]=20,["electronic-circuit"]=10,["iron-gear-wheel"]=10, -["wooden-chest"]=4,["transport-belt"]=10,["underground-belt"]=2,["splitter"]=1, -["burner-mining-drill"]=2,["assembling-machine-1"]=2,["small-electric-pole"]=5,["steam-engine"]=1,["boiler"]=1, -["gun-turret"]=4,["uranium-rounds-magazine"]=50,["piercing-rounds-magazine"]=200,["firearm-magazine"]=400, -} -function warptorio.Carebear(b) if(b and not global.carebear)then global.carebear=true - local e=global.floor.main.host.create_entity{name="warptorio-carebear-chest",position={-1,-1},force=game.forces.player} - local inv=e.get_inventory(defines.inventory.chest) for k,v in pairs(warptorio.carebearItems)do inv.insert{name=k,count=v} end -end end - - -function warptorio.EarlyWater(b) if(b and not global.earlywater)then global.earlywater=true - game.forces.player.technologies["warptorio-boiler-water-1"].researched=true -end end - -function warptorio.OnModSettingChanged(ev) local p=ev.player_index local s=ev.setting local st=ev.setting_type - if(warptorio.settings[s])then warptorio.settings[s](ev) end -end script.on_event(defines.events.on_runtime_mod_setting_changed,warptorio.OnModSettingChanged) - - -function warptorio.IsAutowarpEnabled() return warptorio.setting("autowarp_disable")~=true and (not research.has("warptorio-reactor-6") or warptorio.setting("autowarp_always")) end - - -function warptorio.HookNewGamePlus() - if(remote.interfaces["newgameplus"])then if(not warptorio.newgameplus)then warptorio.newgameplus=true - local ngp=remote.call("newgameplus","get_on_technology_reset_event") if(ngp)then script.on_event(ngp,warptorio.OnPreNewGame) end - local ngp=remote.call("newgameplus","get_on_post_new_game_plus_event") if(ngp)then script.on_event(ngp,warptorio.OnPostNewGame) end - end end -end - - - ---[[ Loot Chest ]]-- - - -warptorio.LootItems={ -["roboport"]=4,["construction-robot"]=10,["logistic-robot"]=20, -["logistic-chest-passive-provider"]=10,["logistic-chest-requester"]=10,["logistic-chest-buffer"]=10, -["wooden-chest"]=20,["iron-chest"]=20,["steel-chest"]=20,["storage-tank"]=10, -["wood"]=100,["stone"]=100,["iron-plate"]=400,["iron-gear-wheel"]=300,["steel-plate"]=200,["copper-plate"]=300,["copper-cable"]=400, -["red-wire"]=100,["green-wire"]=100,["electronic-circuit"]=200,["advanced-circuit"]=100,["processing-unit"]=50, -["big-electric-pole"]=25,["medium-electric-pole"]=25,["small-electric-pole"]=25,["substation"]=15, -["landfill"]=100, -["pipe"]=200,["pipe-to-ground"]=50, -["express-transport-belt"]=100,["fast-transport-belt"]=200,["transport-belt"]=300, -["express-underground-belt"]=15,["fast-underground-belt"]=20,["underground-belt"]=25, -["accumulator"]=10,["steam-engine"]=10, -["nuclear-reactor"]=2,["heat-exchanger"]=10,["heat-pipe"]=25,["steam-turbine"]=10, -["chemical-plant"]=10,["assembling-machine-1"]=15,["assembling-machine-2"]=15,["assembling-machine-3"]=15, -["inserter"]=30,["fast-inserter"]=20,["stack-inserter"]=15, -["warptorio-atomic-bomb"]=1,["warptorio-warponium-fuel-cell"]=2,["warptorio-warponium-fuel"]=1, -["gun-turret"]=10,["uranium-rounds-magazine"]=100,["firearm-magazine"]=400,["piercing-rounds-magazine"]=200, -["atomic-bomb"]=2, -} - -function warptorio.GetPossibleLoot() local lt={} for k,v in pairs(warptorio.LootItems)do local r=game.forces.player.recipes[k] if(not r or (r and r.enabled==true))then lt[k]=v end end return lt end -function warptorio.LootTable(mn,mx,cDist,cStack) local lt=warptorio.GetPossibleLoot() local t,u,k,vDist,vStack={} for i=1,math.random(mn or 1,mx or 5),1 do - u,k=table.Random(lt) vDist,vStack=math.min((cDist or 850)/1700,1),math.random((cStack or 20),100)/100 t[k]=math.max(math.ceil(u*vDist*vStack),1) -end return t end -function warptorio.SpawnLootChest(f,pos,varg) pos=vector(pos) varg=varg or {} - local e=f.create_entity{name="warptorio-lootchest",position=pos,force=game.forces.player,raise_built=true} if(not isvalid(e))then return false end - local lt=warptorio.LootTable(varg.min or 1, varg.max or 5,varg.dist or vector.length(pos), varg.stack or 20) - local inv=e.get_inventory(defines.inventory.chest) for k,v in pairs(lt)do inv.insert{name=k,count=v} end - return e -end - -function warptorio.ChunkLootChest(ev) if(settings.global["warptorio_no_lootchest"].value==true or math.random(1,settings.global["warptorio_lootchest_chance"].value)>1)then return end - local f=ev.surface if(not (f.name=="nauvis" or f==warptorio.GetMainSurface()))then return end local a=ev.area - local x,y=math.random(a.left_top.x,a.right_bottom.x),math.random(a.left_top.y,a.right_bottom.y) - local dist=math.sqrt(math.abs(x^2)+math.abs(y^2)) - if(dist>=settings.global["warptorio_lootchest_distance"].value)then warptorio.SpawnLootChest(f,{x,y}) end -end events.on_event(defines.events.on_chunk_generated,warptorio.ChunkLootChest) - - - ---[[ Tick Functions ]]-- - - -function warptorio.ClockTick(tick) - local donewarp=false - if(global.warp_charging==1)then - global.warp_time_left=(60*global.warp_charge_time)-(tick-global.warp_charge_start_tick) - if(global.warp_time_left<=0)then warptorio.Warpout() donewarp=true end - end - global.time_passed=tick-global.warp_last - --gui.time_passed() - --gui.charge_time() - - if(not donewarp and warptorio.IsAutowarpEnabled())then - global.warp_auto_end=(60*global.warp_auto_time)-(tick-global.warp_last) - if(global.warp_auto_end<=0)then warptorio.Warpout() donewarp=true end - end - - cache.updatemenu("hud","clocktick") - --gui.autowarp() - --gui if(research.has("warptorio-charting") or research.has("warptorio-accelerator") or research.has("warptorio-stabilizer"))then warptorio.derma.cooldown() end - --gui if(global.homeworld)then warptorio.derma.homeworld() end - - warptorio.RefreshWarpCombinators() - - - --events.vraise("ticktime",{warp_left=global.warp_time_left,auto_left=warptorio.IsAutowarpEnabled() and global.warp_auto_end or false, donewarp=donewarp}) -end -events.on_tick(60,0,"clock",warptorio.ClockTick) - - -function warptorio.ChargeCountdownTick(tick) - if(global.warp_charging<1 and global.warp_charge_time>30)then - local r=(780)-(research.level("warptorio-reactor")*60) if(tick%r==0)then global.warp_charge_time=math.max(global.warp_charge_time-1,30) end -- 60t*13s=780t - end -end -events.on_tick(60,0,"charge_countdown",warptorio.ChargeCountdownTick) - -function warptorio.WarpAlarmTick(tick) - if((global.warp_charging==1 and global.warp_time_left<=3600) or (warptorio.IsAutowarpEnabled() and global.warp_auto_end<=3600))then players.playsound("warp_alarm") end -end -events.on_tick(120,1,"warpalarm",warptorio.WarpAlarmTick) - -function warptorio.PollutionTick(tick) if(tick%(warptorio.setting("pollution_tickrate")*60)~=0)then return end - local f=warptorio.GetMainSurface() if(not isvalid(f))then return end - local stb=global.abilities.stabilizing - local vpol=0 - if(warptorio.setting("pollution_disable")~=true)then - vpol=global.pollution_amount - global.pollution_amount=math.min( vpol+ (vpol^warptorio.setting("pollution_exponent"))*(stb and 0.05 or warptorio.setting("pollution_multiplier")), 1000000) - end - - for k,v in pairs(warptorio.GetPlatformSurfaces())do - vpol=vpol+v.get_total_pollution() - v.clear_pollution() - end - if(vpol>0)then - f.pollute({-1,-1},vpol*(stb and 0.05 or 1)) -- todo; pollute to teleporters and harvesters *0.125 - end - -end -events.on_tick(60,0,"pollution",warptorio.PollutionTick) - -events.on_tick(60,0,"radar_ability",function(tick) - local rdr=global.abilities.scanning if(not rdr)then return end - local rdrt=global.abilities.scantick or 0 - local rdrg=global.abilities.scanzone or 0 - rdrt=rdrt+1 global.abilities.scantick=rdrt if(rdrt<3+rdrg)then return end rdrt=0 global.abilities.scantick=0 - - - global.abilities.scanzone=rdrg+1 - local f=warptorio.GetMainSurface() - game.forces.player.chart(f,{lefttop={x=-64-32*rdrg,y=-64-32*rdrg},rightbottom={x=64+32*rdrg,y=64+32*rdrg}}) - players.playsound("reactor-stabilized", f) - -end) - - -function warptorio.BiterTick(tick) if(warptorio.setting("biter_wave_disable")==true or tick%(warptorio.setting("pollution_tickrate")*60)~=0)then return end - global.pollution_expansion = math.min( global.pollution_expansion * settings.global["warptorio_biter_expansion"].value, 60*60*settings.global["warptorio_biter_redux"].value ) - game.map_settings.enemy_expansion.min_expansion_cooldown = math.max((60*60*settings.global["warptorio_biter_min"].value)-global.pollution_expansion,60*60*1) - game.map_settings.enemy_expansion.max_expansion_cooldown = math.max( ((60*60*settings.global["warptorio_biter_max"].value)-global.pollution_expansion)+1,60*60*1) - --game.print("pol: " .. game.map_settings.enemy_expansion.min_expansion_cooldown) - local pt=(global.time_passed/60)/60 - if(pt>settings.global["warptorio_biter_wavestart"].value)then pt=pt-settings.global["warptorio_biter_wavestart"].value - local el=math.ceil(pt*settings.global["warptorio_biter_wavesize"].value) - local erng=math.ceil(pt*settings.global["warptorio_biter_waverng"].value) - local bmax=settings.global["warptorio_biter_wavesizemax"].value if(bmax>0)then el=math.min(el,bmax) end - if(math.random(1,math.max(math.min(settings.global["warptorio_biter_wavemax"].value-erng,settings.global["warptorio_biter_wavemin"].value),1))<=1)then - local f=global.floor.main.host - f.set_multi_command{command={type=defines.command.attack_area, destination={0,0},radius=128}, unit_count=el} - end - end -end -events.on_tick(60,0,"biters",warptorio.BiterTick) - - ---[[ --- Old ability buttons -wderma.stabilizer=derma.GuiControl("warptorio_stabilizer","button") -function wderma.stabilizer:get(p) return derma.control(derma.getrow(p,2),self.name,self.type) end -function wderma.stabilizer:update(p) local r=self:get(p) r.caption={"warptorio.button_stabilizer"} end -function wderma.stabilizer:click(p) - if(game.tick<(global.ability_next or 0) or not research.has("warptorio-stabilizer"))then return end - warptorio.IncrementAbility(settings.global["warptorio_ability_timegain"].value,settings.global["warptorio_ability_cooldown"].value) - warptorio.raise_event("ability_used",{player=p,ability="stabilizer",use_num=global.ability_uses}) - game.forces["enemy"].evolution_factor=0 - global.pollution_amount = 1.25 - global.pollution_expansion = 1.5 - local f=warptorio.GetMainSurface() - f.clear_pollution() - if(global.warp_reactor and isvalid(global.warp_reactor))then f.set_multi_command{command={type=defines.command.flee, from=global.warp_reactor}, unit_count=1000, unit_search_distance=500} end - players.playsound("reactor-stabilized", f) - game.print("Warp Reactor Stabilized") -end - -wderma.accelerator=derma.GuiControl("warptorio_accelerator","button") -function wderma.accelerator:get(p) return derma.control(derma.getrow(p,2),self.name,self.type) end -function wderma.accelerator:update(p) local r=self:get(p) r.caption={"warptorio.button_accelerator"} end -function wderma.accelerator:click(p) - if(game.tick<(gwarptorio.ability_next or 0) or gwarptorio.warp_charge_time<=10)then return end - warptorio.IncrementAbility(settings.global["warptorio_ability_timegain"].value,settings.global["warptorio_ability_cooldown"].value) - warptorio.raise_event("ability_used",{player=p,ability="accelerator",use_num=gwarptorio.ability_uses}) - - gwarptorio.warp_charge_time=math.max(math.ceil(gwarptorio.warp_charge_time^0.75),10) - if(gwarptorio.warp_charging~=1)then warptorio.derma.charge_time() end --,gwarptorio.warp_charge_time*60) end - - local f=warptorio.GetMainSurface() - players.playsound("reactor-stabilized", f) - game.print("Warp Reactor Accelerated") -end - -wderma.radar=derma.GuiControl("warptorio_radar","button") -function wderma.radar:get(p) return derma.control(derma.getrow(p,2),self.name,self.type) end -function wderma.radar:update(p) local r=self:get(p) r.caption={"warptorio.button_radar"} end -function wderma.radar:click(p) - if(game.tick<(gwarptorio.ability_next or 0))then return end - warptorio.IncrementAbility(settings.global["warptorio_ability_timegain"].value/1.25,settings.global["warptorio_ability_cooldown"].value*0.6) - --warptorio.derma.radar() - local n=gwarptorio.radar_uses+1 gwarptorio.radar_uses=n - warptorio.raise_event("ability_used",{player=p,ability="radar",use_num=gwarptorio.ability_uses,radar_num=n}) - - local f=warptorio.GetMainSurface() - game.forces.player.chart(f,{lefttop={x=-64-128*n,y=-64-128*n},rightbottom={x=64+128*n,y=64+128*n}}) - players.playsound("reactor-stabilized", f) - game.print("Warp Reactor Scanner Sweep") -end -]] - - ---[[ Class Cache ]]-- - - - - - - -local tpCache={} -function tpCache.raise(obj,cls,entkey,pth,vi) - obj.cls=cls - obj.entkey=entkey - obj.pth=pth - obj.vi=vi -end -function tpCache.unraise(obj,b_noraise) - local gv=global[obj.cls][obj.entkey] - --gv:DestroyPointTeleporter(obj.vi) -end -function tpCache.create(e,ev) - cache.insert("power",e) -end -function tpCache.clone(e,ev) - local obj=cache.get_entity(ev.source) - if(obj)then - local gv=global[obj.cls][obj.entkey] - gv:DestroyPointSprites(obj.vi) - local nv=cache.force_entity(e,obj.cls,obj.entkey,obj.pth,obj.vi) - cache.destroy_entity(obj,true) - gv[nv.pth][nv.vi].ent=e - gv:CheckPointSprites(nv.vi) - - local gvoe=gv[nv.pth][nv.vi==1 and 2 or 1].ent - local gvoc=cache.get_entity(gvoe) - if(gvoc)then gvoc.teleport_dest=e nv.teleport_dest=gvoe end - if(gv:Data().circuit)then gv:ConnectCircuit() end - end -end -function tpCache.destroy(e,ev) - cache.remove("power",e) - local obj=cache.get_entity(e) - if(obj)then - local gv=global[obj.cls][obj.entkey] - --gv:DestroyPointTeleporter(obj.vi) - --gv:DestroyPointLogistics(obj.vi) - cache.destroy(obj) - end -end - -local tpgateCache=table.deepcopy(tpCache) -function tpgateCache.built(e,ev) - local obj=cache.force_entity(e,"Teleporters","offworld","points",2) - - if(obj)then - local ef=e.surface - local t=global.Teleporters["offworld"] - local gv=global[obj.cls][obj.entkey] - if(gv:ValidB())then entity.destroy(gv.points[2].ent) game.print("Max 1 Planet Teleporter Gate allowed at a time - built") end - - --if(ef~=warptorio.GetMainSurface())then game.print("Teleporter Logistics only functions on the Planet") return end - --[[if(ef.count_entities_filtered{area=t:GetLogisticsArea(e.position),collision_mask={"object-layer"}} >1)then - game.print("Unable to place teleporter logistics, something is in the way!") - - gv[obj.pth][obj.vi].ent=e - gv:CheckTeleporterPairs() - return - end]] - local gve=gv[obj.pth][obj.vi] - gve.ent=e - gv:CheckPointLogistics(2,e.position) - if(gve.energy)then e.energy=gve.energy gve.energy=nil end - gv:CheckTeleporterPairs() - end -end -function tpgateCache.destroy(e,ev) - cache.remove("power",e) - local obj=cache.get_entity(e) - if(obj)then - local gv=global[obj.cls][obj.entkey] - --gv:DestroyPointTeleporter(obj.vi) - gv:DestroyPointLogistics(obj.vi) - cache.destroy(obj) - end -end - - - -local tpharvCache=table.deepcopy(tpCache) - -function tpharvCache.destroy(e,ev) - cache.remove("power",e) - local obj=cache.get_entity(e) - if(obj and not obj.dead)then obj.dead=true - local gv=global[obj.cls][obj.entkey] - cache.destroy(obj) - gv:Recall() - end -end -tpharvCache.died=tpharvCache.destroy - -function tpharvCache.mined(e,ev) - local obj=cache.get_entity(e) - if(obj)then - local gv=global[obj.cls][obj.entkey] - for x,y in pairs(ev.buffer.get_contents())do ev.buffer.remove({name=x,count=y}) end - local cn=(gv:Data().pad_prototype .."-"..research.level("warptorio-harvester-"..obj.entkey)) - if(not ply or (ply and not ply.get_main_inventory().get_contents()[cn]))then ev.buffer.insert{name=cn,count=1} end - local hv=global.Harvesters[obj.entkey] - if(not hv.deployed)then hv:Recall() else hv:CheckTeleporterPairs() end - end -end - ---[[ -function tpharvCache.clone(e,ev) - local obj=cache.get_entity(ev.source) - if(obj)then - local gv=global[obj.cls][obj.entkey] - gv:DestroyPointSprites(obj.vi) - local nv=cache.force_entity(e,obj.cls,obj.entkey,obj.pth,obj.vi) - cache.destroy_entity(obj,true) - gv[nv.pth][nv.vi].ent=e - gv:CheckPointSprites(nv.vi) - - local gvoe=gv[nv.pth][nv.vi==1 and 2 or 1].ent - local gvoc=cache.get_entity(gvoe) - if(gvoc)then gvoc.teleport_dest=e nv.teleport_dest=gvoe end - if(gv:Data().circuit)then gv:ConnectCircuit() end - end -end -]] - -function tpharvCache.clone(e,ev) - local obj=cache.get_entity(ev.source) - if(obj)then - local gv=global[obj.cls][obj.entkey] - gv:DestroyPointSprites(obj.vi) - local ovi=(obj.vi==1 and 2 or 1) - - local nv=cache.force_entity(e,obj.cls,obj.entkey,obj.pth,ovi) - --cache.destroy_entity(obj,true) - --gv:DestroyPointTeleporter(obj.vi) - gv[nv.pth][ovi].ent=e - e.energy=0 - - local gvoe=gv[nv.pth][obj.vi].ent - local gvoc=cache.get_entity(gvoe) - if(gvoc)then gvoc.teleport_dest=e nv.teleport_dest=gvoe end - --gv:CheckTeleporterPairs() - end -end - - -local tppadWestCache={} -function tppadWestCache.built(e,ev) - local f=e.surface if(f~=warptorio.GetMainSurface())then return end - local pos=e.position - entity.destroy(e) - local hv=global.Harvesters["west"] if(hv)then hv:Deploy(f,pos) end -end -local tppadEastCache={} -function tppadEastCache.built(e,ev) - local f=e.surface if(f~=warptorio.GetMainSurface())then return end - local pos=e.position - entity.destroy(e) - local hv=global.Harvesters["east"] if(hv)then hv:Deploy(f,pos) end -end - - -for k,v in pairs{"warptorio-harvestportal","warptorio-harvestpad-west","warptorio-harvestpad-east"}do - for i=0,8,1 do cache.ent(v.."-"..i,tpharvCache) end -end -for i=0,8,1 do cache.ent("warptorio-harvestpad-west-"..i,tppadWestCache) end -for i=0,8,1 do cache.ent("warptorio-harvestpad-east-"..i,tppadEastCache) end - - - -cache.ent("warptorio-teleporter",tpCache) -cache.ent("warptorio-teleporter-gate",tpgateCache) -cache.ent("warptorio-underground",tpCache) -for i=0,8,1 do - cache.ent("warptorio-teleporter-gate-"..i,tpgateCache) - cache.ent("warptorio-teleporter-"..i,tpCache) - cache.ent("warptorio-underground-"..i,tpCache) -end - - -local loaderCache={} -function loaderCache.raise(obj,cls,entkey,pth,vi,vid) - obj.cls=cls - obj.entkey=entkey - obj.pth=pth - obj.vi=vi - obj.vid=vid -end -function loaderCache.unraise(obj) - local gv=global[obj.cls][obj.entkey] - --gv[obj.pth][obj.vi][obj.vid]=nil -end -function loaderCache.clone(e,ev) - local obj=cache.get_entity(ev.source) - if(obj)then - local gv=global[obj.cls][obj.entkey] - local nv=cache.force_entity(e,obj.cls,obj.entkey,obj.pth,obj.vi,obj.vid) - cache.destroy_entity(obj,true) - gv[nv.pth][nv.vi][nv.vid]=e - end -end -function loaderCache.destroy(e,ev) - local obj=cache.get_entity(e) - if(obj)then cache.destroy(obj) end -end -function loaderCache.rotate(e,ev) - local obj=cache.get_entity(e) - if(obj)then - local gv=global[obj.cls][obj.entkey] - if(obj.cls=="Rails")then - gv.dir=e.loader_type - gv:Rotate() - else - gv.dir[obj.vi][obj.vid]=e.loader_type - gv.dir[(obj.vi==1 and 2 or 1)][obj.vid]=string.opposite_loader[e.loader_type] - local de=gv.loaders[(obj.vi==1 and 2 or 1)][obj.vid] - if(isvalid(de))then de.loader_type=string.opposite_loader[e.loader_type] end - if(gv.chests)then gv:SwapLoaderChests(obj.vid) end - end - end -end -cache.ent("loader",loaderCache) -cache.ent("fast-loader",loaderCache) -cache.ent("express-loader",loaderCache) - - -local pipeCache={} -function pipeCache.raise(obj,cls,key,pth,vi,vid) - obj.cls=cls - obj.entkey=key - obj.pth=pth - obj.vi=vi - obj.vid=vid -end -function pipeCache.unraise(obj) - local gv=global[obj.cls][obj.entkey] - --gv[obj.pth][vi][vid]=nil -end -function pipeCache.clone(e,ev) - local obj=cache.get_entity(ev.source) - if(obj)then - local gv=global[obj.cls][obj.entkey] - local nv=cache.force_entity(e,obj.cls,obj.entkey,obj.pth,obj.vi,obj.vid) - cache.destroy_entity(obj,true) - gv[nv.pth][nv.vi][nv.vid]=e - end -end -function pipeCache.destroy(e,ev) - local obj=cache.get_entity(e) - if(obj)then cache.destroy(obj) end -end - -cache.ent("warptorio-logistics-pipe",pipeCache) - - -local gpipeCache={} -- Global pipe cache to clean warppipes - -function gpipeCache.destroy(e,ev) - for k,v in pairs(global.Teleporters)do v:CheckEmptyPipes() end -end -cache.type("pipe",gpipeCache) -cache.type("pipe-to-ground",gpipeCache) - - -local chestCache={} -function chestCache.raise(obj,cls,key,pth,vi,vid) - obj.cls=cls - obj.entkey=key - obj.pth=pth - obj.vi=vi - obj.vid=vid -end -function chestCache.unraise(obj) - --local gv=global[obj.cls][obj.entkey] - --gv[obj.pth][vi][vid]=nil -end -function chestCache.clone(e,ev) - local obj=cache.get_type("types",ev.source.type,ev.source) - if(obj)then - local gv=global[obj.cls][obj.entkey] - local nv=cache.get_raise_type("types",e.type,e,obj.cls,obj.entkey,obj.pth,obj.vi,obj.vid) - gv[nv.pth][nv.vi][nv.vid]=e - --cache.destroy(obj,true) - end -end - -function chestCache.destroy(e,ev) - local obj=cache.get_entity(e) - if(obj)then cache.destroy(obj) end -end - -cache.type("container",chestCache) -cache.type("logistic-container",chestCache) - - -local comboCache={} -function comboCache.raise(obj,cls,key,pth,vi) - obj.cls=cls - obj.entkey=key - obj.pth=pth - obj.vi=vi -end -function comboCache.unraise(obj) - local gv=global[obj.cls][obj.entkey] - --gv[obj.pth][vi][vid]=nil -end -function comboCache.clone(e,ev) - local obj=cache.get_entity(ev.source) - if(obj)then - local gv=global[obj.cls][obj.entkey] - local nv=cache.force_entity(e,obj.cls,obj.entkey,obj.pth,obj.vi) - cache.destroy_entity(obj,true) - gv[nv.pth][nv.vi]=e - end -end -function comboCache.destroy(e,ev) - local obj=cache.get_entity(e) - if(obj)then - local gv=global[obj.cls][obj.entkey] - --gv[obj.vi][obj.vid]=nil - cache.destroy_entity(obj) - end -end - -cache.ent("warptorio-alt-combinator",comboCache) - - --- string.opposite_loader[e.loader_type] -local warploader={} - -function warploader.dofilters(e) - local tp=e.loader_type - local lanes={e.get_transport_line(1),e.get_transport_line(2)} - for k,v in pairs(global.warploaders.outputf)do for i=1,2,1 do table.RemoveByValue(v,lanes[i]) end end - if(tp~="output")then --if(tp=="input")then - for i=1,2,1 do table.RemoveByValue(global.warploaders.output,lanes[i]) end - for i=1,2,1 do table.insertExclusive(global.warploaders.input,lanes[i]) end - else --if(tp=="output")then - local ct=global.warploaders.outputf - local hf=false - for i=1,5,1 do local f=e.get_filter(i) if(f)then hf=true - ct[f]=ct[f] or {} for a=1,2,1 do table.insertExclusive(ct[f],lanes[a]) end - end end - if(hf)then - for i=1,2,1 do table.RemoveByValue(global.warploaders.output,lanes[i]) end - else - for a=1,2,1 do table.insertExclusive(global.warploaders.output,lanes[a]) end - end - for a=1,2,1 do table.RemoveByValue(global.warploaders.input,lanes[a]) end - end -end -function warploader.built(e,ev) - global.warploaders=global.warploaders or {} - global.warploaders.input=global.warploaders.input or {} - global.warploaders.output=global.warploaders.output or {} - global.warploaders.outputf=global.warploaders.outputf or {} - global.warploaders.outputf_next=global.warploaders.outputf_next or {} - - warploader.dofilters(e) -end -function warploader.rotate(e,ev) - warploader.dofilters(e) -end - -function warploader.destroy(e,ev) - local obj=cache.get_entity(e) if(obj)then cache.destroy(obj) end - local un=e.unit_number - local tp=e.loader_type - local wpg=global.warploaders - local lanes={e.get_transport_line(1),e.get_transport_line(2)} - if(tp=="output")then - local hf=false for i=1,5,1 do if(e.get_filter(i))then hf=true break end end - if(hf)then for k,v in pairs(wpg.outputf)do for i=1,2,1 do table.RemoveByValue(v,lanes[i]) end end else - for i=1,2,1 do table.RemoveByValue(wpg.output,lanes[i]) end - end - else - for i=1,2,1 do table.RemoveByValue(wpg.input,lanes[i]) end - end -end -function warploader.settings_pasted(e) warploader.dofilters(e) end -function warploader.gui_closed(e) warploader.dofilters(e) end - -cache.ent("warptorio-warploader",warploader) - - -function warptorio.InsertWarpLane(cv,item_name) if(cv.can_insert_at_back())then cv.insert_at_back({name=item_name,count=1}) return true end return false end -function warptorio.NextWarploader(tbl,key) local k,v=next(tbl,key) if(not k and not v)then return next(tbl,nil) end return k,v end - -function warptorio.DistributeLoaderLine(line) local inv=line.get_contents() - for item_name,item_count in pairs(inv)do if(warptorio.OutputWarpLoader(item_name,item_count))then line.remove_item{name=item_name,count=1} return true end end -end -function warptorio.OutputWarpLoader(cv,c) - local wpg=global.warploaders - - local ins=false - if(wpg.outputf[cv])then - local wpfnext=wpg.outputf_next[cv] - local coutf=wpg.outputf[cv] - for k,v in pairs(coutf)do local rk,rv=warptorio.NextWarploader(coutf,wpfnext) wpfnext=rk if(rv and warptorio.InsertWarpLane(rv,cv))then ins=true break end end - wpg.outputf_next[cv]=wpfnext - if(ins)then return true end - end - local wpnext=wpg.output_next - local cout=wpg.output - for k,v in pairs(cout)do local rk,rv=warptorio.NextWarploader(cout,wpnext) wpnext=rk if(rv and warptorio.InsertWarpLane(rv,cv))then ins=true break end end - wpg.output_next=wpnext - if(ins)then return true end - return false -end - -function warptorio.TickWarploaders() - local wpg=global.warploaders if(not wpg)then return end - local k,line=warptorio.NextWarploader(wpg.input,wpg.input_next) - wpg.input_next=k - if(not isvalid(line))then return end - warptorio.DistributeLoaderLine(line) -end - -function warptorio.TickLogistics() - for nm,tpt in pairs(global.Teleporters)do - if(tpt.pipes)then if(type(tpt.pipes)=="boolean")then error(serpent.block(tpt)) end for vi,ve in pairs(tpt.pipes[1])do if(isvalid(ve))then - local vo=tpt.pipes[2][vi] - if(isvalid(vo))then entity.BalanceFluidPair(ve,vo) end - end end end - if(tpt.chests)then for vi,ve in pairs(tpt.chests[1])do if(isvalid(ve))then - local vo=tpt.chests[2][vi] - if(isvalid(vo))then - local vdir=tpt.dir[1][vi] - if(vdir=="input")then entity.ShiftContainer(ve,vo) else entity.ShiftContainer(vo,ve) end - end - end end end - end - for nm,tpt in pairs(global.Harvesters)do - for vi,ve in pairs(tpt.pipes[1])do if(isvalid(ve))then - local vo=tpt.pipes[2][vi] - if(isvalid(vo))then entity.BalanceFluidPair(ve,vo) end - end end - for vi,ve in pairs(tpt.loaders[1])do if(isvalid(ve))then - local vo=tpt.loaders[2][vi] - if(isvalid(vo))then - local vdir=tpt.dir[1][vi] - if(vdir=="input")then entity.ShiftBelt(ve,vo) else entity.ShiftBelt(vo,ve) end - end - end end - end - entity.AutoBalancePower(cache.get("power")) - entity.AutoBalanceHeat(cache.get("heat")) - if(global.warploaders)then for i=1,math.min(table_size(global.warploaders.input),10),1 do warptorio.TickWarploaders() end end -end -events.on_tick(1,0,"TickLogs",warptorio.TickLogistics) - +--[[ Todo list ]] -- + +--[[ +function warptorio.CountEntities() local c=0 for k,v in pairs(gwarptorio.floor)do if(v.surface and v.surface.valid and k~="main" and k~="home")then + c=c+table_size(v.surface.find_entities()) +end end return c end -- used in warpout + +function warptorio.BlueprintEntityIsBlacklisted(e) if(warptorio.EntityIsPlatform(e))then return true end return false end +function warptorio.on_player_setup_blueprint.generic(ev) + if(settings.global.warptorio_no_blueprint.value)then return end + local mp=ev.mapping if(not mp)then return end local bpe=mp.get() local ply=game.players[ev.player_index] + local cst=ply.blueprint_to_setup if(not cst or not cst.valid_for_read)then cst=ply.cursor_stack end if(not cst or not cst.valid_for_read)then return end + local ents=cst.get_blueprint_entities() + if(ents)then for k,v in pairs(ents)do if(warptorio.BlueprintEntityIsBlacklisted(bpe[v.entity_number]))then ents[k]=nil end end cst.set_blueprint_entities(ents) end +end + + +function warptorio.PlanetEntityIsPlatform(e) local r --=(e.name:sub(1,9)=="warptorio") if(r)then return true end + for k,v in pairs(gwarptorio.Rails)do if(table.HasValue(v.rails,e))then return true end end + for k,v in pairs{gwarptorio.Teleporters.offworld,gwarptorio.Teleporters.b1}do if(v:ManagesEntity(e))then return true end end +end +function warptorio.EntityIsPlatform(e) local r --=(e.name:sub(1,9)=="warptorio") if(r)then return true end + for k,v in pairs(gwarptorio.Rails)do if(v:ManagesEntity(e))then return true end end + for k,v in pairs(gwarptorio.Teleporters)do if(v:ManagesEntity(e))then return true end end + for k,v in pairs(gwarptorio.Harvesters)do if(v:ManagesEntity(e))then return true end end + for k,v in pairs(gwarptorio.floor)do if(v:ManagesEntity(e))then return true end end + return false +end +]] + +--[[ TODO + +function warptorio.MigrateTileFloor(floor,buildfunc) local f=floor.surface + vector.LayTiles("grass-1",f,vector.square(vector(-1,-1),vector(512,512))) + buildfunc() + local tcs={} + for k,v in pairs(f.find_tiles_filtered{name="grass-1"})do table.insert(tcs,{name="out-of-map",position=v.position}) end + f.set_tiles(tcs,true) +end +function warptorio.MigrateHarvesterFloor() + warptorio.BuildB3() + local rLogs=game.forces.player.technologies["warptorio-logistics-1"].researched + for k,v in pairs(storage.warptorio.Harvesters)do local f,pos v:DestroyLogs() + if(v.deployed)then f,pos=v.b.surface,v.deploy_position v:Recall() end + v:DestroyA() v:DestroyB() v:Warpin() if(rLogs)then v:SpawnLogs() end v:Upgrade() + end +end +function warptorio.MigrateTiles() if(warptorio.tilesAreMigrated)then return end warptorio.tilesAreMigrated = true + local flv=gwarptorio.floor.b1 if(flv)then warptorio.MigrateTileFloor(flv,warptorio.BuildB1) end + local flv=gwarptorio.floor.b2 if(flv)then warptorio.MigrateTileFloor(flv,warptorio.BuildB2) end + local flv=gwarptorio.floor.b3 if(flv)then warptorio.MigrateTileFloor(flv,warptorio.MigrateHarvesterFloor) end + warptorio.ValidateCache() + warptorio.BuildPlatform() +end + + + +function warptorio.init.floors(bhzd) + if(not gwarptorio.floor)then gwarptorio.floor={} end + local m=gwarptorio.floor.main if(not m)then m=new(FLOOR,"main",8) m.surface=game.surfaces["nauvis"] end + local m=gwarptorio.floor.b1 if(not m)then m=new(FLOOR,"b1",16) m:MakeEmptySurface() end + local m=gwarptorio.floor.b2 if(not m)then m=new(FLOOR,"b2",17) m:MakeEmptySurface() end + local m=gwarptorio.floor.b3 if(not m)then m=new(FLOOR,"b3",17) m.ovalsize={x=19,y=17} m:MakeEmptySurface() end + warptorio.BuildPlatform(bhzd) + warptorio.BuildB1(bhzd) + warptorio.BuildB2(bhzd) + warptorio.BuildB3(bhzd) +end +function warptorio.RebuildFloors(bhzd) warptorio.init.floors(bhzd) end + + +function warptorio.BuildHazards() warptorio.BuildPlatformHazard() warptorio.BuildB1Hazard() warptorio.BuildB2Hazard() warptorio.BuildB3Hazard() end + + + +function warptorio.BuildPlatformHazard() + +end + +function warptorio.BuildPlatform(bhzd) + + if(bhzd~=true)then warptorio.BuildPlatformHazard() end + + players.playsound("warp_in",f) +end + + +function warptorio.CheckReactor() + local m=gwarptorio.floor.main + local rlv=research.level("warptorio-reactor") -- gwarptorio.Research["reactor"] or 0 + if(rlv>=6 and (not gwarptorio.warp_reactor or not gwarptorio.warp_reactor.valid))then + local f=m.surface + vector.clean(f,vector.square(vector(-0.5,-0.5),vector(5,5))) + local e=f.create_entity{name="warptorio-reactor",position={-1,-1},force=game.forces.player,player=game.players[1]} + vector.cleanplayers(f,vector.square(vector(-0.5,-0.5),vector(5,5))) + gwarptorio.warp_reactor=e + e.minable=false + end +end + + + + +]] -- + + + + +--[[ Settings ]] -- +function warptorio.setting(n) return settings.global["warptorio_" .. n].value end + +warptorio.settings = {} +local setter = warptorio.settings + +function setter.warptorio_autowarp_disable() warptorio.ResetHUD() end + +function setter.warptorio_autowarp_always() warptorio.ResetHUD() end + +function setter.warptorio_water() warptorio.EarlyWater(settings.global["warptorio_water"].value) end + +function setter.warptorio_carebear() warptorio.Carebear(settings.global["warptorio_carebear"].value) end + +function setter.warptorio_solar_multiplier() + warptorio.SolarMultiplier(settings.global["warptorio_solar_multiplier"] + .value) +end + +function setter.warptorio_loaderchest_provider() warptorio.LoaderChestChanged(true) end + +function setter.warptorio_loaderchest_requester() warptorio.LoaderChestChanged(false) end + +function setter.warptorio_loader_top() warptorio.LoaderSideChanged(true) end + +function setter.warptorio_loader_bottom() warptorio.LoaderSideChanged(false) end + +function setter.warptorio_combinator_offset() warptorio.CombinatorOffsetChanged() end + +function setter.warptorio_hide_sprites() + for k, v in pairs(storage.Teleporters) do + v:CheckPointSprites(1) + v:CheckPointSprites(2) + end +end + +function warptorio.CombinatorOffsetChanged() + for k, v in pairs(storage.Harvesters) do + v:DestroyCombos() + v:CheckCombo() + end +end + +function warptorio.LoaderChestChanged(bprovider) +end + +function warptorio.LoaderSideChanged(btop) + for k, v in pairs(storage.Teleporters) do + local g = v:Data().top + if ((btop and g) or (not btop and not g)) then + v:DestroyPointLogistics(1) + v:DestroyPointLogistics(2) + v:CheckTeleporterPairs(true) + end + end +end + +function warptorio.SolarMultiplier(x) + for k, v in pairs(warptorio.GetPlatformSurfaces()) do v.solar_power_multiplier = x end +end + +warptorio.carebearItems = { + ["stone"] = 20, + ["coal"] = 20, + ["iron-plate"] = 20, + ["copper-plate"] = 20, + ["electronic-circuit"] = 10, + ["iron-gear-wheel"] = 10, + ["wooden-chest"] = 4, + ["transport-belt"] = 10, + ["underground-belt"] = 2, + ["splitter"] = 1, + ["burner-mining-drill"] = 2, + ["assembling-machine-1"] = 2, + ["small-electric-pole"] = 5, + ["steam-engine"] = 1, + ["boiler"] = 1, + ["gun-turret"] = 4, + ["uranium-rounds-magazine"] = 50, + ["piercing-rounds-magazine"] = 200, + ["firearm-magazine"] = 400, +} +function warptorio.Carebear(b) + if (b and not storage.carebear) then + storage.carebear = true + local e = storage.floor.main.host.create_entity { name = "warptorio-carebear-chest", position = { -1, -1 }, force = game.forces.player } + local inv = e.get_inventory(defines.inventory.chest) + for k, v in pairs(warptorio.carebearItems) do inv.insert { name = k, count = v } end + end +end + +function warptorio.EarlyWater(b) + if (b and not storage.earlywater) then + storage.earlywater = true + game.forces.player.technologies["warptorio-boiler-water-1"].researched = true + end +end + +function warptorio.OnModSettingChanged(ev) + local p = ev.player_index + local s = ev.setting + local st = ev.setting_type + if (warptorio.settings[s]) then warptorio.settings[s](ev) end +end + +script.on_event(defines.events.on_runtime_mod_setting_changed, warptorio.OnModSettingChanged) + + +function warptorio.IsAutowarpEnabled() + return warptorio.setting("autowarp_disable") ~= true and + (not research.has("warptorio-reactor-6") or warptorio.setting("autowarp_always")) +end + +function warptorio.HookNewGamePlus() + if (remote.interfaces["newgameplus"]) then + if (not warptorio.newgameplus) then + warptorio.newgameplus = true + local ngp = remote.call("newgameplus", "get_on_technology_reset_event") + if (ngp) then script.on_event(ngp, warptorio.OnPreNewGame) end + local ngp = remote.call("newgameplus", "get_on_post_new_game_plus_event") + if (ngp) then script.on_event(ngp, warptorio.OnPostNewGame) end + end + end +end + +--[[ Loot Chest ]] -- + + +warptorio.LootItems = { + ["roboport"] = 4, + ["construction-robot"] = 10, + ["logistic-robot"] = 20, + ["passive-provider-chest"] = 10, + ["requester-chest"] = 10, + ["buffer-chest"] = 10, + ["wooden-chest"] = 20, + ["iron-chest"] = 20, + ["steel-chest"] = 20, + ["storage-tank"] = 10, + ["wood"] = 100, + ["stone"] = 100, + ["iron-plate"] = 400, + ["iron-gear-wheel"] = 300, + ["steel-plate"] = 200, + ["copper-plate"] = 300, + ["copper-cable"] = 400, + ["electronic-circuit"] = 200, + ["advanced-circuit"] = 100, + ["processing-unit"] = 50, + ["big-electric-pole"] = 25, + ["medium-electric-pole"] = 25, + ["small-electric-pole"] = 25, + ["substation"] = 15, + ["landfill"] = 100, + ["pipe"] = 200, + ["pipe-to-ground"] = 50, + ["express-transport-belt"] = 100, + ["fast-transport-belt"] = 200, + ["transport-belt"] = 300, + ["express-underground-belt"] = 15, + ["fast-underground-belt"] = 20, + ["underground-belt"] = 25, + ["accumulator"] = 10, + ["steam-engine"] = 10, + ["nuclear-reactor"] = 2, + ["heat-exchanger"] = 10, + ["heat-pipe"] = 25, + ["steam-turbine"] = 10, + ["chemical-plant"] = 10, + ["assembling-machine-1"] = 15, + ["assembling-machine-2"] = 15, + ["assembling-machine-3"] = 15, + ["inserter"] = 30, + ["fast-inserter"] = 20, + ["bulk-inserter"] = 15, + ["warptorio-atomic-bomb"] = 1, + ["warptorio-warponium-fuel-cell"] = 2, + ["warptorio-warponium-fuel"] = 1, + ["gun-turret"] = 10, + ["uranium-rounds-magazine"] = 100, + ["firearm-magazine"] = 400, + ["piercing-rounds-magazine"] = 200, + ["atomic-bomb"] = 2, +} + +function warptorio.GetPossibleLoot() + local lt = {} + for k, v in pairs(warptorio.LootItems) do + local r = game.forces.player.recipes[k] + if (not r or (r and r.enabled == true)) then lt[k] = v end + end + return lt +end + +function warptorio.LootTable(mn, mx, cDist, cStack) + local lt = warptorio.GetPossibleLoot() + local t, u, k, vDist, vStack = {} + for i = 1, math.random(mn or 1, mx or 5), 1 do + u, k = table.Random(lt) + vDist, vStack = math.min((cDist or 850) / 1700, 1), math.random((cStack or 20), 100) / 100 + t[k] = math.max(math.ceil(u * vDist * vStack), 1) + end + return t +end + +function warptorio.SpawnLootChest(f, pos, varg) + pos = vector(pos) + varg = varg or {} + local e = f.create_entity { name = "warptorio-lootchest", position = pos, force = game.forces.player, raise_built = true } + if (not isvalid(e)) then return false end + local lt = warptorio.LootTable(varg.min or 1, varg.max or 5, varg.dist or vector.length(pos), varg.stack or 20) + local inv = e.get_inventory(defines.inventory.chest) + for k, v in pairs(lt) do inv.insert { name = k, count = v } end + return e +end + +function warptorio.ChunkLootChest(ev) + if (settings.global["warptorio_no_lootchest"].value == true or math.random(1, settings.global["warptorio_lootchest_chance"].value) > 1) then return end + local f = ev.surface + if (not (f.name == "nauvis" or f == warptorio.GetMainSurface())) then return end + local a = ev.area + local x, y = math.random(a.left_top.x, a.right_bottom.x), math.random(a.left_top.y, a.right_bottom.y) + local dist = math.sqrt(math.abs(x ^ 2) + math.abs(y ^ 2)) + if (dist >= settings.global["warptorio_lootchest_distance"].value) then + warptorio.SpawnLootChest(f, { x, y }) + end +end + +events.on_event(defines.events.on_chunk_generated, warptorio.ChunkLootChest) + + + +--[[ Tick Functions ]] -- + + +function warptorio.ClockTick(tick) + local donewarp = false + if (storage.warp_charging == 1) then + storage.warp_time_left = (60 * storage.warp_charge_time) - (tick - storage.warp_charge_start_tick) + if (storage.warp_time_left <= 0) then + warptorio.Warpout() + donewarp = true + end + end + storage.time_passed = tick - storage.warp_last + --gui.time_passed() + --gui.charge_time() + + if (not donewarp and warptorio.IsAutowarpEnabled()) then + storage.warp_auto_end = (60 * storage.warp_auto_time) - (tick - storage.warp_last) + if (storage.warp_auto_end <= 0) then + warptorio.Warpout() + donewarp = true + end + end + + cache.updatemenu("hud", "clocktick") + --gui.autowarp() + --gui if(research.has("warptorio-charting") or research.has("warptorio-accelerator") or research.has("warptorio-stabilizer"))then warptorio.derma.cooldown() end + --gui if(storage.homeworld)then warptorio.derma.homeworld() end + + warptorio.RefreshWarpCombinators() + + + --events.vraise("ticktime",{warp_left=storage.warp_time_left,auto_left=warptorio.IsAutowarpEnabled() and storage.warp_auto_end or false, donewarp=donewarp}) +end + +events.on_tick(60, 0, "clock", warptorio.ClockTick) + + +function warptorio.ChargeCountdownTick(tick) + if (storage.warp_charging < 1 and storage.warp_charge_time > 30) then + local r = (780) - (research.level("warptorio-reactor") * 60) + if (tick % r == 0) then storage.warp_charge_time = math.max(storage.warp_charge_time - 1, 30) end -- 60t*13s=780t + end +end + +events.on_tick(60, 0, "charge_countdown", warptorio.ChargeCountdownTick) + +function warptorio.WarpAlarmTick(tick) + if ((storage.warp_charging == 1 and storage.warp_time_left <= 3600) or (warptorio.IsAutowarpEnabled() and storage.warp_auto_end <= 3600)) then + players.playsound("warp_alarm") + end +end + +events.on_tick(120, 1, "warpalarm", warptorio.WarpAlarmTick) + +function warptorio.PollutionTick(tick) + if (tick % (warptorio.setting("pollution_tickrate") * 60) ~= 0) then return end + local f = warptorio.GetMainSurface() + if (not isvalid(f)) then return end + local stb = storage.abilities.stabilizing + local vpol = 0 + if (warptorio.setting("pollution_disable") ~= true) then + vpol = storage.pollution_amount + storage.pollution_amount = math.min( + vpol + (vpol ^ warptorio.setting("pollution_exponent")) * + (stb and 0.05 or warptorio.setting("pollution_multiplier")), 1000000) + end + + for k, v in pairs(warptorio.GetPlatformSurfaces()) do + vpol = vpol + v.get_total_pollution() + v.clear_pollution() + end + if (vpol > 0) then + f.pollute({ -1, -1 }, vpol * (stb and 0.05 or 1)) -- todo; pollute to teleporters and harvesters *0.125 + end +end + +events.on_tick(60, 0, "pollution", warptorio.PollutionTick) + +events.on_tick(60, 0, "radar_ability", function(tick) + local rdr = storage.abilities.scanning + if (not rdr) then return end + local rdrt = storage.abilities.scantick or 0 + local rdrg = storage.abilities.scanzone or 0 + rdrt = rdrt + 1 + storage.abilities.scantick = rdrt + if (rdrt < 3 + rdrg) then return end + rdrt = 0 + storage.abilities.scantick = 0 + + + storage.abilities.scanzone = rdrg + 1 + local f = warptorio.GetMainSurface() + game.forces.player.chart(f, + { lefttop = { x = -64 - 32 * rdrg, y = -64 - 32 * rdrg }, rightbottom = { x = 64 + 32 * rdrg, y = 64 + 32 * rdrg } }) + players.playsound("reactor-stabilized", f) +end) + + +function warptorio.BiterTick(tick) + if (warptorio.setting("biter_wave_disable") == true or tick % (warptorio.setting("pollution_tickrate") * 60) ~= 0) then return end + storage.pollution_expansion = math.min( + storage.pollution_expansion * settings.global["warptorio_biter_expansion"].value, + 60 * 60 * settings.global["warptorio_biter_redux"].value) + game.map_settings.enemy_expansion.min_expansion_cooldown = math.max( + (60 * 60 * settings.global["warptorio_biter_min"].value) - storage.pollution_expansion, 60 * 60 * 1) + game.map_settings.enemy_expansion.max_expansion_cooldown = math.max( + ((60 * 60 * settings.global["warptorio_biter_max"].value) - storage.pollution_expansion) + 1, 60 * 60 * 1) + --game.print("pol: " .. game.map_settings.enemy_expansion.min_expansion_cooldown) + local pt = (storage.time_passed / 60) / 60 + if (pt > settings.global["warptorio_biter_wavestart"].value) then + pt = pt - settings.global["warptorio_biter_wavestart"].value + local el = math.ceil(pt * settings.global["warptorio_biter_wavesize"].value) + local erng = math.ceil(pt * settings.global["warptorio_biter_waverng"].value) + local bmax = settings.global["warptorio_biter_wavesizemax"].value + if (bmax > 0) then el = math.min(el, bmax) end + if (math.random(1, math.max(math.min(settings.global["warptorio_biter_wavemax"].value - erng, settings.global["warptorio_biter_wavemin"].value), 1)) <= 1) then + local f = storage.floor.main.host + f.set_multi_command { command = { type = defines.command.attack_area, destination = { 0, 0 }, radius = 128 }, unit_count = el } + end + end +end + +events.on_tick(60, 0, "biters", warptorio.BiterTick) + + +--[[ +-- Old ability buttons +wderma.stabilizer=derma.GuiControl("warptorio_stabilizer","button") +function wderma.stabilizer:get(p) return derma.control(derma.getrow(p,2),self.name,self.type) end +function wderma.stabilizer:update(p) local r=self:get(p) r.caption={"warptorio.button_stabilizer"} end +function wderma.stabilizer:click(p) + if(game.tick<(storage.ability_next or 0) or not research.has("warptorio-stabilizer"))then return end + warptorio.IncrementAbility(settings.global["warptorio_ability_timegain"].value,settings.global["warptorio_ability_cooldown"].value) + warptorio.raise_event("ability_used",{player=p,ability="stabilizer",use_num=storage.ability_uses}) + game.forces["enemy"].evolution_factor=0 + storage.pollution_amount = 1.25 + storage.pollution_expansion = 1.5 + local f=warptorio.GetMainSurface() + f.clear_pollution() + if(storage.warp_reactor and isvalid(storage.warp_reactor))then f.set_multi_command{command={type=defines.command.flee, from=storage.warp_reactor}, unit_count=1000, unit_search_distance=500} end + players.playsound("reactor-stabilized", f) + game.print("Warp Reactor Stabilized") +end + +wderma.accelerator=derma.GuiControl("warptorio_accelerator","button") +function wderma.accelerator:get(p) return derma.control(derma.getrow(p,2),self.name,self.type) end +function wderma.accelerator:update(p) local r=self:get(p) r.caption={"warptorio.button_accelerator"} end +function wderma.accelerator:click(p) + if(game.tick<(gwarptorio.ability_next or 0) or gwarptorio.warp_charge_time<=10)then return end + warptorio.IncrementAbility(settings.global["warptorio_ability_timegain"].value,settings.global["warptorio_ability_cooldown"].value) + warptorio.raise_event("ability_used",{player=p,ability="accelerator",use_num=gwarptorio.ability_uses}) + + gwarptorio.warp_charge_time=math.max(math.ceil(gwarptorio.warp_charge_time^0.75),10) + if(gwarptorio.warp_charging~=1)then warptorio.derma.charge_time() end --,gwarptorio.warp_charge_time*60) end + + local f=warptorio.GetMainSurface() + players.playsound("reactor-stabilized", f) + game.print("Warp Reactor Accelerated") +end + +wderma.radar=derma.GuiControl("warptorio_radar","button") +function wderma.radar:get(p) return derma.control(derma.getrow(p,2),self.name,self.type) end +function wderma.radar:update(p) local r=self:get(p) r.caption={"warptorio.button_radar"} end +function wderma.radar:click(p) + if(game.tick<(gwarptorio.ability_next or 0))then return end + warptorio.IncrementAbility(settings.global["warptorio_ability_timegain"].value/1.25,settings.global["warptorio_ability_cooldown"].value*0.6) + --warptorio.derma.radar() + local n=gwarptorio.radar_uses+1 gwarptorio.radar_uses=n + warptorio.raise_event("ability_used",{player=p,ability="radar",use_num=gwarptorio.ability_uses,radar_num=n}) + + local f=warptorio.GetMainSurface() + game.forces.player.chart(f,{lefttop={x=-64-128*n,y=-64-128*n},rightbottom={x=64+128*n,y=64+128*n}}) + players.playsound("reactor-stabilized", f) + game.print("Warp Reactor Scanner Sweep") +end +]] + + +--[[ Class Cache ]] -- + + +local tpCache = {} +function tpCache.raise(obj, cls, entkey, pth, vi) + obj.cls = cls + obj.entkey = entkey + obj.pth = pth + obj.vi = vi +end + +function tpCache.unraise(obj, b_noraise) + local gv = storage[obj.cls][obj.entkey] + --gv:DestroyPointTeleporter(obj.vi) +end + +function tpCache.create(e, ev) + cache.insert("power", e) +end + +function tpCache.clone(e, ev) + local obj = cache.get_entity(ev.source) + if (obj) then + local gv = storage[obj.cls][obj.entkey] + gv:DestroyPointSprites(obj.vi) + local nv = cache.force_entity(e, obj.cls, obj.entkey, obj.pth, obj.vi) + cache.destroy_entity(obj, true) + gv[nv.pth][nv.vi].ent = e + gv:CheckPointSprites(nv.vi) + + local gvoe = gv[nv.pth][nv.vi == 1 and 2 or 1].ent + local gvoc = cache.get_entity(gvoe) + if (gvoc) then + gvoc.teleport_dest = e + nv.teleport_dest = gvoe + end + if (gv:Data().circuit) then gv:ConnectCircuit() end + end +end + +function tpCache.destroy(e, ev) + cache.remove("power", e) + local obj = cache.get_entity(e) + if (obj) then + local gv = storage[obj.cls][obj.entkey] + --gv:DestroyPointTeleporter(obj.vi) + --gv:DestroyPointLogistics(obj.vi) + cache.destroy(obj) + end +end + +local tpgateCache = table.deepcopy(tpCache) +function tpgateCache.built(e, ev) + local obj = cache.force_entity(e, "Teleporters", "offworld", "points", 2) + + if (obj) then + local ef = e.surface + local t = storage.Teleporters["offworld"] + local gv = storage[obj.cls][obj.entkey] + if (gv:ValidB()) then + entity.destroy(gv.points[2].ent) + game.print({ "warptorio.max-one-teleporter-error" }) + end + + --if(ef~=warptorio.GetMainSurface())then game.print("Teleporter Logistics only functions on the Planet") return end + --[[if(ef.count_entities_filtered{area=t:GetLogisticsArea(e.position),collision_mask={"object-layer"}} >1)then + game.print("Unable to place teleporter logistics, something is in the way!") + + gv[obj.pth][obj.vi].ent=e + gv:CheckTeleporterPairs() + return + end]] + local gve = gv[obj.pth][obj.vi] + gve.ent = e + gv:CheckPointLogistics(2, e.position) + if (gve.energy) then + e.energy = gve.energy + gve.energy = nil + end + gv:CheckTeleporterPairs() + end +end + +function tpgateCache.destroy(e, ev) + cache.remove("power", e) + local obj = cache.get_entity(e) + if (obj) then + local gv = storage[obj.cls][obj.entkey] + --gv:DestroyPointTeleporter(obj.vi) + gv:DestroyPointLogistics(obj.vi) + cache.destroy(obj) + end +end + +local tpharvCache = table.deepcopy(tpCache) + +function tpharvCache.destroy(e, ev) + cache.remove("power", e) + local obj = cache.get_entity(e) + if (obj and not obj.dead) then + obj.dead = true + local gv = storage[obj.cls][obj.entkey] + cache.destroy(obj) + gv:Recall() + end +end + +tpharvCache.died = tpharvCache.destroy + +function tpharvCache.mined(e, ev) + local obj = cache.get_entity(e) + if (obj) then + local gv = storage[obj.cls][obj.entkey] + for x, y in pairs(ev.buffer.get_contents()) do ev.buffer.remove({ name = y.name, count = y.count }) end + local cn = (gv:Data().pad_prototype .. "-" .. research.level("warptorio-harvester-" .. obj.entkey)) + if (not ply or (ply and not ply.get_main_inventory().get_contents()[cn])) then ev.buffer.insert { name = cn, count = 1 } end + local hv = storage.Harvesters[obj.entkey] + if (not hv.deployed) then hv:Recall() else hv:CheckTeleporterPairs() end + end +end + +--[[ +function tpharvCache.clone(e,ev) + local obj=cache.get_entity(ev.source) + if(obj)then + local gv=storage[obj.cls][obj.entkey] + gv:DestroyPointSprites(obj.vi) + local nv=cache.force_entity(e,obj.cls,obj.entkey,obj.pth,obj.vi) + cache.destroy_entity(obj,true) + gv[nv.pth][nv.vi].ent=e + gv:CheckPointSprites(nv.vi) + + local gvoe=gv[nv.pth][nv.vi==1 and 2 or 1].ent + local gvoc=cache.get_entity(gvoe) + if(gvoc)then gvoc.teleport_dest=e nv.teleport_dest=gvoe end + if(gv:Data().circuit)then gv:ConnectCircuit() end + end +end +]] + +function tpharvCache.clone(e, ev) + local obj = cache.get_entity(ev.source) + if (obj) then + local gv = storage[obj.cls][obj.entkey] + gv:DestroyPointSprites(obj.vi) + local ovi = (obj.vi == 1 and 2 or 1) + + local nv = cache.force_entity(e, obj.cls, obj.entkey, obj.pth, ovi) + --cache.destroy_entity(obj,true) + --gv:DestroyPointTeleporter(obj.vi) + gv[nv.pth][ovi].ent = e + e.energy = 0 + + local gvoe = gv[nv.pth][obj.vi].ent + local gvoc = cache.get_entity(gvoe) + if (gvoc) then + gvoc.teleport_dest = e + nv.teleport_dest = gvoe + end + --gv:CheckTeleporterPairs() + end +end + +local tppadWestCache = {} +function tppadWestCache.built(e, ev) + local f = e.surface + if (f ~= warptorio.GetMainSurface()) then return end + local pos = e.position + entity.destroy(e) + local hv = storage.Harvesters["west"] + if (hv) then hv:Deploy(f, pos) end +end + +local tppadEastCache = {} +function tppadEastCache.built(e, ev) + local f = e.surface + if (f ~= warptorio.GetMainSurface()) then return end + local pos = e.position + entity.destroy(e) + local hv = storage.Harvesters["east"] + if (hv) then hv:Deploy(f, pos) end +end + +for k, v in pairs { "warptorio-harvestportal", "warptorio-harvestpad-west", "warptorio-harvestpad-east" } do + for i = 0, 8, 1 do cache.ent(v .. "-" .. i, tpharvCache) end +end +for i = 0, 8, 1 do cache.ent("warptorio-harvestpad-west-" .. i, tppadWestCache) end +for i = 0, 8, 1 do cache.ent("warptorio-harvestpad-east-" .. i, tppadEastCache) end + + + +cache.ent("warptorio-teleporter", tpCache) +cache.ent("warptorio-teleporter-gate", tpgateCache) +cache.ent("warptorio-underground", tpCache) +for i = 0, 8, 1 do + cache.ent("warptorio-teleporter-gate-" .. i, tpgateCache) + cache.ent("warptorio-teleporter-" .. i, tpCache) + cache.ent("warptorio-underground-" .. i, tpCache) +end + + +local loaderCache = {} +function loaderCache.raise(obj, cls, entkey, pth, vi, vid) + obj.cls = cls + obj.entkey = entkey + obj.pth = pth + obj.vi = vi + obj.vid = vid +end + +function loaderCache.unraise(obj) + local gv = storage[obj.cls][obj.entkey] + --gv[obj.pth][obj.vi][obj.vid]=nil +end + +function loaderCache.clone(e, ev) + local obj = cache.get_entity(ev.source) + if (obj) then + local gv = storage[obj.cls][obj.entkey] + local nv = cache.force_entity(e, obj.cls, obj.entkey, obj.pth, obj.vi, obj.vid) + cache.destroy_entity(obj, true) + gv[nv.pth][nv.vi][nv.vid] = e + end +end + +function loaderCache.destroy(e, ev) + local obj = cache.get_entity(e) + if (obj) then cache.destroy(obj) end +end + +function loaderCache.rotate(e, ev) + local obj = cache.get_entity(e) + if (obj) then + local gv = storage[obj.cls][obj.entkey] + if (obj.cls == "Rails") then + gv.dir = e.loader_type + gv:Rotate() + else + gv.dir[obj.vi][obj.vid] = e.loader_type + gv.dir[(obj.vi == 1 and 2 or 1)][obj.vid] = string.opposite_loader[e.loader_type] + local de = gv.loaders[(obj.vi == 1 and 2 or 1)][obj.vid] + if (isvalid(de)) then de.loader_type = string.opposite_loader[e.loader_type] end + if (gv.chests) then gv:SwapLoaderChests(obj.vid) end + end + end +end + +cache.ent("loader", loaderCache) +cache.ent("fast-loader", loaderCache) +cache.ent("express-loader", loaderCache) + + +local pipeCache = {} +function pipeCache.raise(obj, cls, key, pth, vi, vid) + obj.cls = cls + obj.entkey = key + obj.pth = pth + obj.vi = vi + obj.vid = vid +end + +function pipeCache.unraise(obj) + local gv = storage[obj.cls][obj.entkey] + --gv[obj.pth][vi][vid]=nil +end + +function pipeCache.clone(e, ev) + local obj = cache.get_entity(ev.source) + if (obj) then + local gv = storage[obj.cls][obj.entkey] + local nv = cache.force_entity(e, obj.cls, obj.entkey, obj.pth, obj.vi, obj.vid) + cache.destroy_entity(obj, true) + gv[nv.pth][nv.vi][nv.vid] = e + end +end + +function pipeCache.destroy(e, ev) + local obj = cache.get_entity(e) + if (obj) then cache.destroy(obj) end +end + +cache.ent("warptorio-logistics-pipe", pipeCache) + + +local gpipeCache = {} -- Global pipe cache to clean warppipes + +function gpipeCache.destroy(e, ev) + for k, v in pairs(storage.Teleporters) do v:CheckEmptyPipes() end +end + +cache.type("pipe", gpipeCache) +cache.type("pipe-to-ground", gpipeCache) + + +local chestCache = {} +function chestCache.raise(obj, cls, key, pth, vi, vid) + obj.cls = cls + obj.entkey = key + obj.pth = pth + obj.vi = vi + obj.vid = vid +end + +function chestCache.unraise(obj) + --local gv=storage[obj.cls][obj.entkey] + --gv[obj.pth][vi][vid]=nil +end + +function chestCache.clone(e, ev) + local obj = cache.get_type("types", ev.source.type, ev.source) + if (obj) then + local gv = storage[obj.cls][obj.entkey] + local nv = cache.get_raise_type("types", e.type, e, obj.cls, obj.entkey, obj.pth, obj.vi, obj.vid) + gv[nv.pth][nv.vi][nv.vid] = e + --cache.destroy(obj,true) + end +end + +function chestCache.destroy(e, ev) + local obj = cache.get_entity(e) + if (obj) then cache.destroy(obj) end +end + +cache.type("container", chestCache) +cache.type("logistic-container", chestCache) + + +local comboCache = {} +function comboCache.raise(obj, cls, key, pth, vi) + obj.cls = cls + obj.entkey = key + obj.pth = pth + obj.vi = vi +end + +function comboCache.unraise(obj) + local gv = storage[obj.cls][obj.entkey] + --gv[obj.pth][vi][vid]=nil +end + +function comboCache.clone(e, ev) + local obj = cache.get_entity(ev.source) + if (obj) then + local gv = storage[obj.cls][obj.entkey] + local nv = cache.force_entity(e, obj.cls, obj.entkey, obj.pth, obj.vi) + cache.destroy_entity(obj, true) + gv[nv.pth][nv.vi] = e + end +end + +function comboCache.destroy(e, ev) + local obj = cache.get_entity(e) + if (obj) then + local gv = storage[obj.cls][obj.entkey] + --gv[obj.vi][obj.vid]=nil + cache.destroy_entity(obj) + end +end + +cache.ent("warptorio-alt-combinator", comboCache) + + +-- string.opposite_loader[e.loader_type] +local warploader = {} + +function warploader.dofilters(e) + local tp = e.loader_type + local lanes = { e.get_transport_line(1), e.get_transport_line(2) } + for k, v in pairs(storage.warploaders.outputf) do for i = 1, 2, 1 do table.RemoveByValue(v, lanes[i]) end end + if (tp ~= "output") then --if(tp=="input")then + for i = 1, 2, 1 do table.RemoveByValue(storage.warploaders.output, lanes[i]) end + for i = 1, 2, 1 do table.insertExclusive(storage.warploaders.input, lanes[i]) end + else --if(tp=="output")then + local ct = storage.warploaders.outputf + local hf = false + for i = 1, 5, 1 do + local f = e.get_filter(i) + if (f) then + hf = true + ct[f] = ct[f] or {} + for a = 1, 2, 1 do table.insertExclusive(ct[f], lanes[a]) end + end + end + if (hf) then + for i = 1, 2, 1 do table.RemoveByValue(storage.warploaders.output, lanes[i]) end + else + for a = 1, 2, 1 do table.insertExclusive(storage.warploaders.output, lanes[a]) end + end + for a = 1, 2, 1 do table.RemoveByValue(storage.warploaders.input, lanes[a]) end + end +end + +function warploader.built(e, ev) + storage.warploaders = storage.warploaders or {} + storage.warploaders.input = storage.warploaders.input or {} + storage.warploaders.output = storage.warploaders.output or {} + storage.warploaders.outputf = storage.warploaders.outputf or {} + storage.warploaders.outputf_next = storage.warploaders.outputf_next or {} + + warploader.dofilters(e) +end + +function warploader.rotate(e, ev) + warploader.dofilters(e) +end + +function warploader.destroy(e, ev) + local obj = cache.get_entity(e) + if (obj) then cache.destroy(obj) end + local un = e.unit_number + local tp = e.loader_type + local wpg = storage.warploaders + local lanes = { e.get_transport_line(1), e.get_transport_line(2) } + if (tp == "output") then + local hf = false + for i = 1, 5, 1 do + if (e.get_filter(i)) then + hf = true + break + end + end + if (hf) then + for k, v in pairs(wpg.outputf) do for i = 1, 2, 1 do table.RemoveByValue(v, lanes[i]) end end + else + for i = 1, 2, 1 do table.RemoveByValue(wpg.output, lanes[i]) end + end + else + for i = 1, 2, 1 do table.RemoveByValue(wpg.input, lanes[i]) end + end +end + +function warploader.settings_pasted(e) warploader.dofilters(e) end + +function warploader.gui_closed(e) warploader.dofilters(e) end + +cache.ent("warptorio-warploader", warploader) + +function warptorio.InsertWarpLane(cv, item_name) + if (cv.can_insert_at_back()) then + cv.insert_at_back({ name = item_name, count = 1 }) + return true + end + return false +end + +function warptorio.NextWarploader(tbl, key) + local k, v = next(tbl, key) + if (not k and not v) then + return next(tbl, nil) + end + return k, v +end + +function warptorio.DistributeLoaderLine(line) + local inv = line.get_contents() + for item_name, item_count in pairs(inv) do + if (warptorio.OutputWarpLoader(item_count.name, item_count.count)) then + line.remove_item { name = item_count.name, count = 1 } + return true + end + end +end + +function warptorio.OutputWarpLoader(cv, c) + local wpg = storage.warploaders + + local ins = false + if (wpg.outputf[cv]) then + local wpfnext = wpg.outputf_next[cv] + local coutf = wpg.outputf[cv] + for k, v in pairs(coutf) do + local rk, rv = warptorio.NextWarploader(coutf, wpfnext) + wpfnext = rk + if (rv and warptorio.InsertWarpLane(rv, cv)) then + ins = true + break + end + end + wpg.outputf_next[cv] = wpfnext + if (ins) then return true end + end + local wpnext = wpg.output_next + local cout = wpg.output + for k, v in pairs(cout) do + local rk, rv = warptorio.NextWarploader(cout, wpnext) + wpnext = rk + if (rv and warptorio.InsertWarpLane(rv, cv)) then + ins = true + break + end + end + wpg.output_next = wpnext + if (ins) then return true end + return false +end + +function warptorio.TickWarploaders() + local wpg = storage.warploaders + if (not wpg) then return end + local k, line = warptorio.NextWarploader(wpg.input, wpg.input_next) + wpg.input_next = k + if (not isvalid(line)) then return end + warptorio.DistributeLoaderLine(line) +end + +function warptorio.TickLogistics() + for nm, tpt in pairs(storage.Teleporters) do + if (tpt.pipes) then + if (type(tpt.pipes) == "boolean") then error(serpent.block(tpt)) end + for vi, ve in pairs(tpt.pipes[1]) do + if (isvalid(ve)) then + local vo = tpt.pipes[2][vi] + if (isvalid(vo)) then entity.BalanceFluidPair(ve, vo) end + end + end + end + if (tpt.chests) then + for vi, ve in pairs(tpt.chests[1]) do + if (isvalid(ve)) then + local vo = tpt.chests[2][vi] + if (isvalid(vo)) then + local vdir = tpt.dir[1][vi] + if (vdir == "input") then entity.ShiftContainer(ve, vo) else entity.ShiftContainer(vo, ve) end + end + end + end + end + end + for nm, tpt in pairs(storage.Harvesters) do + for vi, ve in pairs(tpt.pipes[1]) do + if (isvalid(ve)) then + local vo = tpt.pipes[2][vi] + if (isvalid(vo)) then entity.BalanceFluidPair(ve, vo) end + end + end + for vi, ve in pairs(tpt.loaders[1]) do + if (isvalid(ve)) then + local vo = tpt.loaders[2][vi] + if (isvalid(vo)) then + local vdir = tpt.dir[1][vi] + if (vdir == "input") then entity.ShiftBelt(ve, vo) else entity.ShiftBelt(vo, ve) end + end + end + end + end + entity.AutoBalancePower(cache.get("power")) + entity.AutoBalanceHeat(cache.get("heat")) + if (storage.warploaders) then + for i = 1, math.min(table_size(storage.warploaders.input), 10), 1 do + warptorio + .TickWarploaders() + end + end +end + +events.on_tick(1, 0, "TickLogs", warptorio.TickLogistics) diff --git a/control_main_remotes.lua b/control_main_remotes.lua index 6475e8f..088b587 100644 --- a/control_main_remotes.lua +++ b/control_main_remotes.lua @@ -1,144 +1,144 @@ - ---[[ Custom Events ]]-- - -function warptorio.remote.get_events() return events.vdefs end -- call (), returns {event_name=script_generated_event_name_int}. Used to get a copy of the entire table. -function warptorio.remote.get_event(n) return events.vdefs[n] end -- call (warptorio_event_name_string), returns a specific event. - - - ---------------------------------------------------------------------- ---[[ New Surfaces/Platform Interface ]]-- -warptorio.remote.GetMainSurface=warptorio.GetMainSurface -- call (), returns LuaSurface, -warptorio.remote.GetMainPlanet=warptorio.GetMainPlanet -- call (), returns planet_table. Same as doing remote.call("planetorio","GetPlanetBySurface",remote.call("warptorio","GetMainSurface")) -warptorio.remote.GetHomeSurface=warptorio.GetHomeSurface -- call (), returns LuaSurface, -warptorio.remote.GetHomePlanet=warptorio.GetHomePlanet -- call (), returns planet_table. Same as doing remote.call("planetorio","GetPlanetBySurface",remote.call("warptorio","GetHomeSurface")) -warptorio.remote.GetSurfaces=warptorio.GetAllSurfaces -- call (), returns {table_of_warptorio_surfaces}. This does not include surfaces that are marked for destroy, such as player being left behind on warp. -warptorio.remote.GetSurface=function(key) return (global.floor[key] and global.floor[key].host or nil) end -warptorio.remote.GetFloor=function(key) return global.floor[key] end -warptorio.remote.GetFloors=function() return global.floor end -warptorio.remote.GetNamedSurfaces=warptorio.GetNamedSurfaces -- call ({table_of_floor_names, e.g. "home","main","factory"}), returns {[name]=surface,...}. Used to get surfaces in bulk. - -warptorio.remote.RecallTeleporterGate=function() local t=global.Teleporters.offworld if(t and isvalid(t.b))then t:DestroyLogsB() t:DestroyB() end end -- call(). Used to destroy the teleporter gate. -warptorio.remote.RecallHarvester=function(side,bply) if(global.Harvesters[side])then global.Harvesters[side]:Recall(bply) end end -- call(string_side,bool_recallplayers). side must be "east" or "west". future values may include "nw","ne","sw","se" if i ever add those. - ---------------------------------------------------------------------- - ---[[ Warptorio Remote Interface - Mod Managed Tables ]]-- ---[[ -For dealing with blacklists and stuff, so if your mod is uninstalled i can remove it from the global table. - -old stuff first: -warptorio.remote.insert_warp_blacklist=warptorio.cmdinsertcloneblacklist -- call (mod_name,prototype_name), returns nil. Stops warptorio from cloning a specific prototype name when warping. -warptorio.remote.remove_warp_blacklist=warptorio.cmdremovecloneblacklist -- call (mod_name,prototype_name), returns nil. Stops warptorio from cloning a specific prototype name when warping. -warptorio.remote.is_warp_blacklisted=warptorio.cmdiscloneblacklisted -- call (mod_name,prototype_name), returns nil. Stops warptorio from cloning a specific prototype name when warping. -warptorio.remote.GetWarpBlacklist=warptorio.GetWarpBlacklist -- call (), returns: {warptorio_warp_blacklist}. Returns the full table of all blacklisted entities. - - -function warptorio.cmdinsertcloneblacklist(mn,e) if(not global.warp_blacklist[mn])then global.warp_blacklist[mn]={} end table.insertExclusive(global.warp_blacklist[mn],e) end -function warptorio.cmdremovecloneblacklist(mn,e) if(not global.warp_blacklist[mn])then global.warp_blacklist[mn]={} end table.RemoveByValue(global.warp_blacklist[mn],e) end -function warptorio.cmdiscloneblacklisted(mn,e) if(not global.warp_blacklist[mn])then return false end return table.HasValue(global.warp_blacklist[mn],e) end -]] - - -function warptorio.ValidateRemoteTable(x) local mt=global.modtbl if(not mt[x])then mt[x]={} end - for k,v in pairs(mt[x])do if(not game.active_mods[k])then mt[x][k]=nil end end -end -function warptorio.InsertModTable(x,y,z) if(y=="warptorio2")then return end local mt=global.modtbl if(not mt[x])then return false end mt[x][y]=mt[x][y] or {} - return table.insertExclusive(mt[x][y],z) -end -function warptorio.RemoveModTable(x,y,z) if(y=="warptorio2")then return end local mt=global.modtbl if(not mt[x])then return false end mt[x][y]=mt[x][y] or {} - return table.RemoveByValue(mt[x][y],z) -end - -warptorio.ModTables={} -function warptorio.GetModTable(x) - if(warptorio.ModTables[x])then return warptorio.ModTables[x] end - local mt=global.modtbl if(not mt[x])then return true end - local t={} for k,v in pairs(mt[x])do for y,z in pairs(v)do table.insertExclusive(t,z) end end - warptorio.ModTables[x]=t - return t -end - -events.on_config(function() - global.modtbl=global.modtbl or {} - warptorio.ValidateRemoteTable("harvester_blacklist") -- prevents certain entities from being affected by harvester deploy/recall cloning. - warptorio.ValidateRemoteTable("warp_blacklist") -- prevents certain entities from being affected by the big Warpout function / cloning. -end) - - -warptorio.remote.InsertModTable=warptorio.InsertModTable -- call ("table_name", "mod_name", (ANY) Value). Used to interface with numerous mod related tables. Returns false if bad table, true if the value already exists, and int on success -warptorio.remote.RemoveModTable=warptorio.RemoveModTable -- call ("table_name", "mod_name", (ANY) Value). Returns false/int depending on success - ---------------------------------------------------------------------- ---[[ Cheats ]]-- - -warptorio.remote.ResearchNauvis=function() for k,v in pairs(game.forces.player.technologies)do if(not v.name:match("warptorio"))then v.researched=true end end end -warptorio.remote.ResearchCheat=function() for k,v in pairs(game.forces.player.research_queue)do v.researched=true end end -warptorio.remote.cheat=function() for i,p in pairs(game.players)do for k,v in pairs(lootItems)do p.get_main_inventory().insert{name=k,count=v} end end end -- call (), returns: Nil. Gives all players all the items in the lootchest table. Useful for testing. -warptorio.remote.reveal=function(n) n=n or 10 local f=global.floor.main.host game.forces.player.chart(f,{lefttop={x=-64-128*n,y=-64-128*n},rightbottom={x=64+128*n,y=64+128*n}}) end -- call (reveal_scale), returns: nil. Cheat command to reveal the map - - ---------------------------------------------------------------------- ---[[ Warptorio Loot Chest stuff ]]-- -warptorio.remote.SpawnLootChest=warptorio.SpawnLootChest -- call (surface,position_table,varg_table={min=1,max=5,dist=dist_from_0_0,stack=stack_size_min_fraction}). returns entity. Creates and fills a loot chest on given surface at given position. varg is used to tweak potential stack sizes and number of items. -warptorio.remote.GetPossibleLoot=warptorio.GetPossibleLoot -- returns a table of potential items from the loot table, filtered by is-craftable. -warptorio.remote.LootTable=warptorio.LootTable -- call (min,max,dist,stack), returns {[item_name]=#count}. Used to get a rolled table of loot items. See varg_table on SpawnLootChest. - ---------------------------------------------------------------------- ---[[ Needs review, CallDerma is deprecated ]]-- -warptorio.remote.ResetGui=warptorio.ResetGui -- call (*optional LuaPlayer), returns nil, used to re-construct a player's, or all player's gui HUD. Used when unlocking research and fixing gui issues. -warptorio.remote.CallDerma=warptorio.CallDerma -- call (derma_name, *event_table), returns nil, specifically added for remotes. Used to refresh a specific internal gui control. - ---------------------------------------------------------------------- ---[[ Generic/backend stuff exposed for no good reason, if you actually need these let me know ]]-- -warptorio.remote.GetChest=warptorio.GetChest -- call ("input" or "output"), returns "chest-prototype-name" depending on level and settings value: loaderchest_provider / loaderchest_requester based on variable. -warptorio.remote.GetBelt=warptorio.GetBelt -- call (), returns loader type based on current logistics level - -warptorio.remote.PlanetEntityIsPlatform=warptorio.PlanetEntityIsPlatform -- call (entity), returns true if the entity is a warptorio entity (aka special chest or loader used by stairs or the rails). Used specifically to check for ents on the planet -warptorio.remote.EntityIsPlatform=warptorio.EntityIsPlatform -- call (entity), returns true. Same as PlanetEntityIsPlatform, except checks all teleporters on all surfaces and stuff. -warptorio.remote.BlueprintEntityIsBlacklisted=warptorio.BlueprintEntityIsBlacklisted -- call (entity), returns true/false whether the entity should not be added to blueprints. Currently identical to remote.call("warptorio","EntityIsPlatform",entity), but is not an alias. - -warptorio.remote.ResetPlatform=function() warptorio.BuildB1() warptorio.BuildB2() for k,v in pairs(global.Teleporters)do v:Warpin() end end -- Rebuild the platform?? - - ---------------------------------------------------------------------- ---[[ Warping related stuff ]]-- - -warptorio.remote.GetWarpzone=function() return global.warpzone end -- Returns the current warpzone -warptorio.remote.IsAutowarpEnabled=warptorio.IsAutowarpEnabled -- call (), returns: boolean_IsAutowarpEnabled. Does exactly what it says on the tin. If true, the autowarp timer is running. -warptorio.remote.Warpout=warptorio.Warpout -- call (*optional planet_name), returns: nil. The big warp function. Increments the warpzone and other stuff. -warptorio.remote.warp=warptorio.Warpout -- alias - -warptorio.remote.StartWarp=warptorio.StartWarp -- call() Forcibly start the warping countdown -warptorio.remote.StopWarp=warptorio.StopWarp -- call() Forcibly stop the warping countdown -warptorio.remote.IsWarping=warptorio.IsWarping -- call(), returns bool_IsWarping. - -function warptorio.remote.GetWarpTime() return (global.warp_charging>0 and global.warp_time_left/60 or global.warp_charge_time) end -function warptorio.remote.SetWarpTime(n) global.warp_charge_time=n end - ---[[ todo? -function warptorio.remote.GetAutowarpTimeLeft() end -function warptorio.remote.SetAutowarpTimeLeft(n) end -]] - ---------------------------------------------------------------------- ---[[ Backwards Compatability - DEPRECATED -function warptorio.cmdgetwarpevent() if(not warptorio.warpevent_name)then warptorio.warpevent_name = script.generate_event_name() end return warptorio.warpevent_name end -function warptorio.cmdgetpostwarpevent() if(not warptorio.warpevent_post_name)then warptorio.warpevent_post_name = script.generate_event_name() end return warptorio.warpevent_post_name end -function warptorio.cmdgettickevent() return warptorio.custom_events.ticktime end -function warptorio.cmdevent_harvester_deploy() return warptorio.custom_events.harvester_deploy end -function warptorio.cmdevent_harvester_recall() return warptorio.custom_events.harvester_recall end -function warptorio.cmdevent_warp_started() return warptorio.custom_events.warp_started end -function warptorio.cmdevent_warp_countdown() return warptorio.custom_events.warp_countdown end -function warptorio.cmdevent_autowarp_countdown() return warptorio.custom_events.autowarp_countdown end -function warptorio.cmdevent_ability_used() return warptorio.custom_events.ability_used end -function warptorio.cmdevent_autowarp_countdown() return warptorio.custom_events.autowarp_countdown end -warptorio.remote.event_ticktime=warptorio.cmdgettickevent -warptorio.remote.event_harvester_deploy=warptorio.cmdevent_harvester_deploy -warptorio.remote.event_harvester_recall=warptorio.cmdevent_harvester_recall -warptorio.remote.event_warp=warptorio.cmdgetwarpevent -warptorio.remote.event_post_warp=warptorio.cmdgetpostwarpevent -warptorio.remote.event_warp_started=warptorio.cmdevent_warp_started -warptorio.remote.warpevent=warptorio.cmdgetwarpevent -warptorio.remote.postwarpevent=warptorio.cmdgetpostwarpevent --_- ]]-- + +--[[ Custom Events ]]-- + +function warptorio.remote.get_events() return events.vdefs end -- call (), returns {event_name=script_generated_event_name_int}. Used to get a copy of the entire table. +function warptorio.remote.get_event(n) return events.vdefs[n] end -- call (warptorio_event_name_string), returns a specific event. + + + +--------------------------------------------------------------------- +--[[ New Surfaces/Platform Interface ]]-- +warptorio.remote.GetMainSurface=warptorio.GetMainSurface -- call (), returns LuaSurface, +warptorio.remote.GetMainPlanet=warptorio.GetMainPlanet -- call (), returns planet_table. Same as doing remote.call("planetorio","GetPlanetBySurface",remote.call("warptorio","GetMainSurface")) +warptorio.remote.GetHomeSurface=warptorio.GetHomeSurface -- call (), returns LuaSurface, +warptorio.remote.GetHomePlanet=warptorio.GetHomePlanet -- call (), returns planet_table. Same as doing remote.call("planetorio","GetPlanetBySurface",remote.call("warptorio","GetHomeSurface")) +warptorio.remote.GetSurfaces=warptorio.GetAllSurfaces -- call (), returns {table_of_warptorio_surfaces}. This does not include surfaces that are marked for destroy, such as player being left behind on warp. +warptorio.remote.GetSurface=function(key) return (storage.floor[key] and storage.floor[key].host or nil) end +warptorio.remote.GetFloor=function(key) return storage.floor[key] end +warptorio.remote.GetFloors=function() return storage.floor end +warptorio.remote.GetNamedSurfaces=warptorio.GetNamedSurfaces -- call ({table_of_floor_names, e.g. "home","main","factory"}), returns {[name]=surface,...}. Used to get surfaces in bulk. + +warptorio.remote.RecallTeleporterGate=function() local t=storage.Teleporters.offworld if(t and isvalid(t.b))then t:DestroyLogsB() t:DestroyB() end end -- call(). Used to destroy the teleporter gate. +warptorio.remote.RecallHarvester=function(side,bply) if(storage.Harvesters[side])then storage.Harvesters[side]:Recall(bply) end end -- call(string_side,bool_recallplayers). side must be "east" or "west". future values may include "nw","ne","sw","se" if i ever add those. + +--------------------------------------------------------------------- + +--[[ Warptorio Remote Interface - Mod Managed Tables ]]-- +--[[ +For dealing with blacklists and stuff, so if your mod is uninstalled i can remove it from the global table. + +old stuff first: +warptorio.remote.insert_warp_blacklist=warptorio.cmdinsertcloneblacklist -- call (mod_name,prototype_name), returns nil. Stops warptorio from cloning a specific prototype name when warping. +warptorio.remote.remove_warp_blacklist=warptorio.cmdremovecloneblacklist -- call (mod_name,prototype_name), returns nil. Stops warptorio from cloning a specific prototype name when warping. +warptorio.remote.is_warp_blacklisted=warptorio.cmdiscloneblacklisted -- call (mod_name,prototype_name), returns nil. Stops warptorio from cloning a specific prototype name when warping. +warptorio.remote.GetWarpBlacklist=warptorio.GetWarpBlacklist -- call (), returns: {warptorio_warp_blacklist}. Returns the full table of all blacklisted entities. + + +function warptorio.cmdinsertcloneblacklist(mn,e) if(not storage.warp_blacklist[mn])then storage.warp_blacklist[mn]={} end table.insertExclusive(storage.warp_blacklist[mn],e) end +function warptorio.cmdremovecloneblacklist(mn,e) if(not storage.warp_blacklist[mn])then storage.warp_blacklist[mn]={} end table.RemoveByValue(storage.warp_blacklist[mn],e) end +function warptorio.cmdiscloneblacklisted(mn,e) if(not storage.warp_blacklist[mn])then return false end return table.HasValue(storage.warp_blacklist[mn],e) end +]] + + +function warptorio.ValidateRemoteTable(x) local mt=storage.modtbl if(not mt[x])then mt[x]={} end + for k,v in pairs(mt[x])do if(not script.active_mods[k])then mt[x][k]=nil end end +end +function warptorio.InsertModTable(x,y,z) if(y=="warptorio2")then return end local mt=storage.modtbl if(not mt[x])then return false end mt[x][y]=mt[x][y] or {} + return table.insertExclusive(mt[x][y],z) +end +function warptorio.RemoveModTable(x,y,z) if(y=="warptorio2")then return end local mt=storage.modtbl if(not mt[x])then return false end mt[x][y]=mt[x][y] or {} + return table.RemoveByValue(mt[x][y],z) +end + +warptorio.ModTables={} +function warptorio.GetModTable(x) + if(warptorio.ModTables[x])then return warptorio.ModTables[x] end + local mt=storage.modtbl if(not mt[x])then return true end + local t={} for k,v in pairs(mt[x])do for y,z in pairs(v)do table.insertExclusive(t,z) end end + warptorio.ModTables[x]=t + return t +end + +events.on_config(function() + storage.modtbl=storage.modtbl or {} + warptorio.ValidateRemoteTable("harvester_blacklist") -- prevents certain entities from being affected by harvester deploy/recall cloning. + warptorio.ValidateRemoteTable("warp_blacklist") -- prevents certain entities from being affected by the big Warpout function / cloning. +end) + + +warptorio.remote.InsertModTable=warptorio.InsertModTable -- call ("table_name", "mod_name", (ANY) Value). Used to interface with numerous mod related tables. Returns false if bad table, true if the value already exists, and int on success +warptorio.remote.RemoveModTable=warptorio.RemoveModTable -- call ("table_name", "mod_name", (ANY) Value). Returns false/int depending on success + +--------------------------------------------------------------------- +--[[ Cheats ]]-- + +warptorio.remote.ResearchNauvis=function() for k,v in pairs(game.forces.player.technologies)do if(not v.name:match("warptorio"))then v.researched=true end end end +warptorio.remote.ResearchCheat=function() for k,v in pairs(game.forces.player.research_queue)do v.researched=true end end +warptorio.remote.cheat=function() for i,p in pairs(game.players)do for k,v in pairs(lootItems)do p.get_main_inventory().insert{name=k,count=v} end end end -- call (), returns: Nil. Gives all players all the items in the lootchest table. Useful for testing. +warptorio.remote.reveal=function(n) n=n or 10 local f=storage.floor.main.host game.forces.player.chart(f,{lefttop={x=-64-128*n,y=-64-128*n},rightbottom={x=64+128*n,y=64+128*n}}) end -- call (reveal_scale), returns: nil. Cheat command to reveal the map + + +--------------------------------------------------------------------- +--[[ Warptorio Loot Chest stuff ]]-- +warptorio.remote.SpawnLootChest=warptorio.SpawnLootChest -- call (surface,position_table,varg_table={min=1,max=5,dist=dist_from_0_0,stack=stack_size_min_fraction}). returns entity. Creates and fills a loot chest on given surface at given position. varg is used to tweak potential stack sizes and number of items. +warptorio.remote.GetPossibleLoot=warptorio.GetPossibleLoot -- returns a table of potential items from the loot table, filtered by is-craftable. +warptorio.remote.LootTable=warptorio.LootTable -- call (min,max,dist,stack), returns {[item_name]=#count}. Used to get a rolled table of loot items. See varg_table on SpawnLootChest. + +--------------------------------------------------------------------- +--[[ Needs review, CallDerma is deprecated ]]-- +warptorio.remote.ResetGui=warptorio.ResetGui -- call (*optional LuaPlayer), returns nil, used to re-construct a player's, or all player's gui HUD. Used when unlocking research and fixing gui issues. +warptorio.remote.CallDerma=warptorio.CallDerma -- call (derma_name, *event_table), returns nil, specifically added for remotes. Used to refresh a specific internal gui control. + +--------------------------------------------------------------------- +--[[ Generic/backend stuff exposed for no good reason, if you actually need these let me know ]]-- +warptorio.remote.GetChest=warptorio.GetChest -- call ("input" or "output"), returns "chest-prototype-name" depending on level and settings value: loaderchest_provider / loaderchest_requester based on variable. +warptorio.remote.GetBelt=warptorio.GetBelt -- call (), returns loader type based on current logistics level + +warptorio.remote.PlanetEntityIsPlatform=warptorio.PlanetEntityIsPlatform -- call (entity), returns true if the entity is a warptorio entity (aka special chest or loader used by stairs or the rails). Used specifically to check for ents on the planet +warptorio.remote.EntityIsPlatform=warptorio.EntityIsPlatform -- call (entity), returns true. Same as PlanetEntityIsPlatform, except checks all teleporters on all surfaces and stuff. +warptorio.remote.BlueprintEntityIsBlacklisted=warptorio.BlueprintEntityIsBlacklisted -- call (entity), returns true/false whether the entity should not be added to blueprints. Currently identical to remote.call("warptorio","EntityIsPlatform",entity), but is not an alias. + +warptorio.remote.ResetPlatform=function() warptorio.BuildB1() warptorio.BuildB2() for k,v in pairs(storage.Teleporters)do v:Warpin() end end -- Rebuild the platform?? + + +--------------------------------------------------------------------- +--[[ Warping related stuff ]]-- + +warptorio.remote.GetWarpzone=function() return storage.warpzone end -- Returns the current warpzone +warptorio.remote.IsAutowarpEnabled=warptorio.IsAutowarpEnabled -- call (), returns: boolean_IsAutowarpEnabled. Does exactly what it says on the tin. If true, the autowarp timer is running. +warptorio.remote.Warpout=warptorio.Warpout -- call (*optional planet_name), returns: nil. The big warp function. Increments the warpzone and other stuff. +warptorio.remote.warp=warptorio.Warpout -- alias + +warptorio.remote.StartWarp=warptorio.StartWarp -- call() Forcibly start the warping countdown +warptorio.remote.StopWarp=warptorio.StopWarp -- call() Forcibly stop the warping countdown +warptorio.remote.IsWarping=warptorio.IsWarping -- call(), returns bool_IsWarping. + +function warptorio.remote.GetWarpTime() return (storage.warp_charging>0 and storage.warp_time_left/60 or storage.warp_charge_time) end +function warptorio.remote.SetWarpTime(n) storage.warp_charge_time=n end + +--[[ todo? +function warptorio.remote.GetAutowarpTimeLeft() end +function warptorio.remote.SetAutowarpTimeLeft(n) end +]] + +--------------------------------------------------------------------- +--[[ Backwards Compatability - DEPRECATED +function warptorio.cmdgetwarpevent() if(not warptorio.warpevent_name)then warptorio.warpevent_name = script.generate_event_name() end return warptorio.warpevent_name end +function warptorio.cmdgetpostwarpevent() if(not warptorio.warpevent_post_name)then warptorio.warpevent_post_name = script.generate_event_name() end return warptorio.warpevent_post_name end +function warptorio.cmdgettickevent() return warptorio.custom_events.ticktime end +function warptorio.cmdevent_harvester_deploy() return warptorio.custom_events.harvester_deploy end +function warptorio.cmdevent_harvester_recall() return warptorio.custom_events.harvester_recall end +function warptorio.cmdevent_warp_started() return warptorio.custom_events.warp_started end +function warptorio.cmdevent_warp_countdown() return warptorio.custom_events.warp_countdown end +function warptorio.cmdevent_autowarp_countdown() return warptorio.custom_events.autowarp_countdown end +function warptorio.cmdevent_ability_used() return warptorio.custom_events.ability_used end +function warptorio.cmdevent_autowarp_countdown() return warptorio.custom_events.autowarp_countdown end +warptorio.remote.event_ticktime=warptorio.cmdgettickevent +warptorio.remote.event_harvester_deploy=warptorio.cmdevent_harvester_deploy +warptorio.remote.event_harvester_recall=warptorio.cmdevent_harvester_recall +warptorio.remote.event_warp=warptorio.cmdgetwarpevent +warptorio.remote.event_post_warp=warptorio.cmdgetpostwarpevent +warptorio.remote.event_warp_started=warptorio.cmdevent_warp_started +warptorio.remote.warpevent=warptorio.cmdgetwarpevent +warptorio.remote.postwarpevent=warptorio.cmdgetpostwarpevent +-_- ]]-- diff --git a/control_platform_classic.lua b/control_platform_classic.lua index f158395..4a20a8f 100644 --- a/control_platform_classic.lua +++ b/control_platform_classic.lua @@ -1,954 +1,954 @@ -local platform={} -platform.name="classic" - ---[[ Offsets and stuff ]]-- - -platform.railCorner={nw=vector(-35,-35),ne=vector(34,-35),sw=vector(-35,34),se=vector(34,34)} -platform.railOffset={nw=vector(0,0),ne=vector(-1,0),sw=vector(0,-1),se=vector(-1,-1)} --{nw=vector(-1,-1),ne=vector(0,-1),sw=vector(-1,0),se=vector(0,0)} -platform.railLoader={nw=vector.area(vector(2,0),vector(0,2)),sw=vector.area(vector(2,0),vector(0,-2)),ne=vector.area(vector(-2,0),vector(0,2)),se=vector.area(vector(-2,0),vector(0,-2))} - -platform.letterOpposite={n=defines.direction.south,s=defines.direction.north,e=defines.direction.west,w=defines.direction.east} -platform.railLoaderPos={ - nw={vector(2,0),vector(2,-1),vector(0,2),vector(-1,2)}, - sw={vector(2,0),vector(2,-1),vector(0,-2),vector(-1,-2)}, - ne={vector(-2,0),vector(-2,-1),vector(0,2),vector(-1,2)}, - se={vector(-2,0),vector(-2,-1),vector(0,-2),vector(-1,-2)}, -} - ---platform.corner={nw=vector(-52,-52),ne=vector(50,-52),sw=vector(-52,50),se=vector(50,50)} -- old -platform.corner={nw=vector(-51.5,-51.5),ne=vector(50.5,-51.5),sw=vector(-51.5,50.5),se=vector(50.5,50.5)} - -platform.side={north=vector(0,-52),south=vector(0,51),east=vector(51,0),west=vector(-52,0)} ---[[ -local cirMaxWidth=128+8 -local cirHeight=17 --64+4 --17 -- -local vz=cirMaxWidth ---local ez=m.harvestSize or 10 -- harvester size max 47 -local hvMax=47 -local vzx=vz/2 local hvx=hvMax/2 local hvy=hvMax/8 - -local westPos=warptorio.platform.harvester.west --vector(-(vzx+(hvx-hvy))+0.5,-0.5) -local eastPos=warptorio.platform.harvester.east --vector(vzx+(hvx-hvy),-0.5) -]] -local hvSize=(128+8)/2 -local hvMax=47 -platform.harvester={} -platform.harvester.east=vector(85.5,-0.5) --hvSize+((hvMax/2)-(hvMax/8)),-0.5) -- 85.625 -platform.harvester.west=vector(-86.5,-0.5) -- -(hvSize+((hvMax/2)-(hvMax/8)))+0.5,-0.5) -- -85.125 -- was -86 - - -platform.corn={} -platform.corn.nw={x=-52,y=-52} -platform.corn.ne={x=50,y=-52} -platform.corn.sw={x=-52,y=50} -platform.corn.se={x=50,y=50} -platform.corn.north=-52 -platform.corn.south=50 -platform.corn.east=50 -platform.corn.west=-51.5 - - - ---[[ Floors ]]-- - -platform.floors={} - - --- Todo: Make teleporters and specials automatically do hazard tiles - ---[[ Platform Technology Effects ]]-- - -platform.techs={} - --- General technologies - -platform.techs.boiler_station={tech="warptorio-boiler-station",effect={special={"boiler"}},} -platform.techs.reactor={tech="warptorio-reactor",level_range={1,8},effect={reactor=true,special={"main"}}, } - -platform.techs.tele_portal={tech="warptorio-teleporter-portal",effect={unlock_teleporters={"offworld"},},} -platform.techs.tele_energy={tech="warptorio-teleporter",level_range={1,5},effect={upgrade_energy={"offworld"},},} -platform.techs.energy={tech="warptorio-energy",level_range={1,5},effect={upgrade_energy=true},} -platform.techs.logistics={tech="warptorio-logistics",level_range={1,4},effect={upgrade_logistics=true},} -platform.techs.warp_beacon={tech="warptorio-beacon",level_range={1,10},effect={special={"factory"},},} - -platform.techs.dualloader={tech="warptorio-dualloader-1",effect={upgrade_logistics=true},} -platform.techs.triloader={tech="warptorio-triloader",effect={upgrade_logistics=true},} - -platform.techs.accelerator={tech="warptorio-accelerator",effect={ability="accelerator"},} -platform.techs.stabilizer={tech="warptorio-stabilizer",effect={ability="stabilizer"},} -platform.techs.charting={tech="warptorio-charting",effect={ability="charting",special={"factory","boiler"}},} - - -platform.techs.alt_combinator={tech="warptorio-alt-combinator",effect={do_combinators=true},} - -platform.techs.homeworld={tech="warptorio-homeworld",effect={unlock_homeworld=true},} - -platform.techs.toolbar={tech="warptorio-toolbar",effect={unlock_toolbar=true}} - - - - --- Platform Surface Techs -platform.techs.size={tech="warptorio-platform-size",effect={retile={"main"}}, -levels={ - [0]=8, - [1]=10+7-1, - [2]=18+7-1, - [3]=26+7-1, - [4]=40+7-1, - [5]=56+7-1+2, - [6]=74+7-1+2, - [7]=92+7-1+4, -}} - -platform.techs.railnw={tech="warptorio-rail-nw",effect={unlock_rails="nw"},} -platform.techs.railne={tech="warptorio-rail-ne",effect={unlock_rails="ne"},} -platform.techs.railsw={tech="warptorio-rail-sw",effect={unlock_rails="sw"},} -platform.techs.railse={tech="warptorio-rail-se",effect={unlock_rails="se"},} - -platform.techs.turret_nw={tech="warptorio-turret-nw",first_effect={unlock_teleporters={"main_tur_factory_nw"}},effect={retile={"main","factory"}},level_range={0,3},} -platform.techs.turret_ne={tech="warptorio-turret-ne",first_effect={unlock_teleporters={"main_tur_factory_ne"}},effect={retile={"main","factory"}},level_range={0,3},} -platform.techs.turret_sw={tech="warptorio-turret-sw",first_effect={unlock_teleporters={"main_tur_factory_sw"}},effect={retile={"main","factory"}},level_range={0,3},} -platform.techs.turret_se={tech="warptorio-turret-se",first_effect={unlock_teleporters={"main_tur_factory_se"}},effect={retile={"main","factory"}},level_range={0,3},} - - --- Factory Techs - -platform.techs.factory_n={tech="warptorio-factory-n",effect={retile={"factory"}},} -platform.techs.factory_s={tech="warptorio-factory-s",effect={retile={"factory"}},} -platform.techs.factory_e={tech="warptorio-factory-e",effect={retile={"factory"}},} -platform.techs.factory_w={tech="warptorio-factory-w",effect={retile={"factory"}},} -platform.techs.bridgesize={tech="warptorio-bridgesize",level_range={1,2},effect={retile={"factory"}},} - - -platform.techs.factorysize={tech="warptorio-factory",effect={retile={"factory"}}, -first_effect={rehazard={"main"},unlock_teleporters={"main_to_factory"},}, -levels={ - [0]=19-1, - [1]=23-1, - [2]=31-1, - [3]=39-1, - [4]=47-1, - [5]=55-1, - [6]=63-1, - [7]=71+2-1, -}, -} - - --- Boiler Techs - -platform.techs.boiler_water={tech="warptorio-boiler-water",level_range={1,3},effect={retile={"boiler"},},} - -platform.techs.boiler_n={tech="warptorio-boiler-n",effect={retile={"boiler"}},} -platform.techs.boiler_s={tech="warptorio-boiler-s",effect={retile={"boiler"}},} -platform.techs.boiler_e={tech="warptorio-boiler-e",effect={retile={"boiler"}},} -platform.techs.boiler_w={tech="warptorio-boiler-w",effect={retile={"boiler"}},} - - -platform.techs.boilersize={tech="warptorio-boiler", -first_effect={rehazard={"harvester"},unlock_teleporters={"harvester_to_boiler"}}, -effect={retile={"boiler"}}, -levels={ - [0]=18, - [1]=24, - [2]=32, - [3]=40, - [4]=48, - [5]=56, - [6]=64, - [7]=72, -}, -} - - -platform.techs.harvesterfloor={tech="warptorio-harvester-floor",effect={retile={"harvester"},unlock_teleporters={"factory_to_harvester"}}, -} -platform.techs.harvestersize={tech="warptorio-harvester-size",effect={retile={"harvester"},}, -- oval sizes -levels={ - [0]=vector(19,17), - [1]=vector(28,22), - [2]=vector(36,26), - [3]=vector(48,32), - [4]=vector(74,40), - [5]=vector(92,48), - [6]=vector(112,56), - [7]=vector(128+8,64), -}, -} -platform.techs.harvester_west={tech="warptorio-harvester-west",effect={harvesters={"west"}}, -levels={ - [1]=12, - [2]=20, - [3]=26, - [4]=32, - [5]=38, -}, -} -platform.techs.harvester_east={tech="warptorio-harvester-east",effect={harvesters={"east"}}, -levels={ - [1]=12, - [2]=20, - [3]=26, - [4]=32, - [5]=38, -}, -} - ---unused platform.techs.harvester_west_loader={tech="warptorio-harvester-west-loader",effect={harvesters={"west"}},} ---unused platform.techs.harvester_east_loader={tech="warptorio-harvester-east-loader",effect={harvesters={"east"}},} - - ---[[ Rails registers ]]-- - -platform.rails={} -local tpr={key="nw"} platform.rails[tpr.key]=tpr -tpr.railpos=platform.railCorner[tpr.key]+platform.railOffset[tpr.key] -tpr.chestpos=platform.railCorner[tpr.key] --+platform.railOffset[tpr.key] -tpr.floor="factory" -tpr.logs={false,true,true,false} - -local tpr={key="ne"} platform.rails[tpr.key]=tpr -tpr.railpos=platform.railCorner[tpr.key]+platform.railOffset[tpr.key] -tpr.chestpos=platform.railCorner[tpr.key] --+platform.railOffset[tpr.key] -tpr.floor="factory" -tpr.logs={false,false,true,true} - -local tpr={key="sw"} platform.rails[tpr.key]=tpr -tpr.railpos=platform.railCorner[tpr.key]+platform.railOffset[tpr.key] -tpr.chestpos=platform.railCorner[tpr.key] --+platform.railOffset[tpr.key] -tpr.floor="factory" -tpr.logs={true,true,false,false} - -local tpr={key="se"} platform.rails[tpr.key]=tpr -tpr.railpos=platform.railCorner[tpr.key]+platform.railOffset[tpr.key] -tpr.chestpos=platform.railCorner[tpr.key] --+platform.railOffset[tpr.key] -tpr.floor="factory" -tpr.logs={true,false,false,true} - - - - ---[[ Teleporter registers ]]-- - -platform.teleporters={} - ---[[ Offworld Teleporter ]]-- - --- Offworld is special and has some special handling on its pair, e.g. the second pair doesn't get hazards and can be spawned freely because you can pick it up. -local tps={key="offworld"} platform.teleporters[tps.key]=tps -tps.logs=true -- this teleporter gains loaders on the first logistics upgrade -tps.dopipes=true -- this teleporter should be given pipes -tps.dualloader=false -- this teleporter gets an extra loader on the dualloader upgrade -tps.triloader=true -- this teleporter gets an extra loader on the triloader upgrade -tps.top=false -- this teleporter is a "top loader" used to determine loader direction via settings. -tps.circuit=false -- Should be false if the teleporter pair isn't in the same position. -tps.staticdir=false -- "up" or "down" if the logistics cannot have their direction changed with setting -tps.oneside=false -- If this teleporter is onesided, "left" or "right" -tps.rotated=false -- If true, this has logistics on top and bottom instead of left and right -tps.logiport=false -- Set to true if this is logistics only. -tps.energy="tele_energy" -- platform tech name - -tps.pair={ - {floor="main",position=vector(-1,5), - prototype="warptorio-teleporter", - }, - {floor="main",position=vector(-1,8), - prototype="warptorio-teleporter-gate", - gate=true, -- Logistics spawning behaviour flag - minable=true, -- Flag to pickup - destructible=true, -- Can be destroyed - } -} - - ---[[ Main Factory Teleporter ]]-- - -local tps={key="main_to_factory"} platform.teleporters[tps.key]=tps -tps.logs=true -tps.dopipes=true -tps.dualloader=true -tps.triloader=true -tps.top=true -tps.circuit=true -tps.staticdir=false -tps.oneside=false -tps.rotated=false -tps.logiport=false -tps.energy="energy" - -tps.pair={ - {floor="main",position=vector(-1,-7), - prototype="warptorio-underground", - sprite_arrow="down", - sprites={ - {sprite="technology/automation",target_offset={0,-0.25},x_scale=0.5,y_scale=0.5,tint={r=1,g=0.7,b=0.4,a=1}}, - }, - }, - {floor="factory",position=vector(-1,-7), - prototype="warptorio-underground", - sprite_arrow="up", - sprites={ - {sprite="technology/concrete",target_offset={0,-0.25},x_scale=0.5,y_scale=0.5,tint={r=1,g=0.7,b=0.4,a=1}}, - }, - } -} - --- Main Turrets copy from Main Factory - -local kdir="nw" -local key="main_tur_factory_"..kdir -local tpv=table.deepcopy(tps) -tpv.dualloader=false -tpv.top=true -tpv.triloader=true -tpv.circuit=true -tpv.key=key platform.teleporters[key]=tpv -tpv.pair[1].position=platform.corner[kdir]-vector(0.5,0.5) -tpv.pair[2].position=platform.corner[kdir]-vector(0.5,0.5) -tpv.pair[1].sprites=nil -tpv.pair[2].sprites=nil - -local kdir="ne" -local key="main_tur_factory_"..kdir -local tpv=table.deepcopy(tps) -tpv.dualloader=false -tpv.top=true -tpv.triloader=true -tpv.circuit=true -tpv.key=key platform.teleporters[key]=tpv -tpv.pair[1].position=platform.corner[kdir]-vector(0.5,0.5) -tpv.pair[2].position=platform.corner[kdir]-vector(0.5,0.5) -tpv.pair[1].sprites=nil -tpv.pair[2].sprites=nil - -local kdir="sw" -local key="main_tur_factory_"..kdir -local tpv=table.deepcopy(tps) -tpv.dualloader=false -tpv.triloader=true -tpv.circuit=true -tpv.top=false -tpv.key=key platform.teleporters[key]=tpv -tpv.pair[1].position=platform.corner[kdir]-vector(0.5,0.5) -tpv.pair[2].position=platform.corner[kdir]-vector(0.5,0.5) -tpv.pair[1].sprites=nil -tpv.pair[2].sprites=nil - -local kdir="se" -local key="main_tur_factory_"..kdir -local tpv=table.deepcopy(tps) -tpv.dualloader=false -tpv.triloader=true -tpv.circuit=true -tpv.top=false -tpv.key=key platform.teleporters[key]=tpv -tpv.pair[1].position=platform.corner[kdir]-vector(0.5,0.5) -tpv.pair[2].position=platform.corner[kdir]-vector(0.5,0.5) -tpv.pair[1].sprites=nil -tpv.pair[2].sprites=nil - - ---[[ Factory to Harvester Teleporter ]]-- - -local tps={key="factory_to_harvester"} platform.teleporters[tps.key]=tps -tps.logs=true -tps.dopipes=true -tps.dualloader=true -tps.triloader=true -tps.top=false -tps.circuit=true -tps.staticdir=false -tps.oneside=false -tps.rotated=false -tps.logiport=false -tps.energy="energy" -tps.pair={ - {floor="factory",position=vector(-1,5), - prototype="warptorio-underground", - sprite_arrow="down", - sprites={ - {sprite="technology/tank",target_offset={0,-0.25},x_scale=0.5,y_scale=0.5,tint={r=1,g=0.7,b=0.4,a=1}}, - }, - }, - {floor="harvester",position=vector(-1,5), - prototype="warptorio-underground", - sprite_arrow="up", - sprites={ - {sprite="technology/automation",target_offset={0,-0.25},x_scale=0.5,y_scale=0.5,tint={r=1,g=0.7,b=0.4,a=1}}, - }, - } -} - - - ---[[ Harvester to Boiler Teleporter ]]-- - -local tps={key="harvester_to_boiler"} platform.teleporters[tps.key]=tps -tps.logs=true -tps.dopipes=true -tps.dualloader=true -tps.triloader=true -tps.top=true -tps.circuit=true -tps.staticdir=false -tps.oneside=false -tps.rotated=false -tps.logiport=false -tps.energy="energy" -tps.pair={ - {floor="harvester",position=vector(-1,-7), - prototype="warptorio-underground", - sprite_arrow="down", - sprites={ - {sprite="technology/fluid-handling",target_offset={0,-0.25},x_scale=0.5,y_scale=0.5,tint={r=1,g=0.7,b=0.4,a=1}} - }, - }, - {floor="boiler",position=vector(-1,-7), - prototype="warptorio-underground", - sprite_arrow="up", - sprites={ - - {sprite="technology/tank",target_offset={0,-0.25},x_scale=0.5,y_scale=0.5,tint={r=1,g=0.7,b=0.4,a=1}} - }, - } -} - - - - ---[[ Harvester registers ]]-- - -platform.HarvesterPointData={ - energy="energy", - pair={ - {floor="harvester",prototype="warptorio-harvestportal",minable=true,destructible=false}, - {floor="main",prototype="warptorio-harvestportal",minable=true,destructible=true,gate=true}, - }, -} - -platform.harvesters={} - -local hvs={key="west",position=platform.harvester.west} -hvs.energy="energy" -hvs.pad_prototype="warptorio-harvestpad-west" -hvs.prototype="warptorio-harvestportal" -hvs.tech="harvester_west" -- harvester size tech name, or.. -hvs.fixed_level=nil -- If this harvester is a fixed level -hvs.logs=true -hvs.dualloader=true -hvs.triloader=true -hvs.dopipes=true -hvs.pipes_pattern="east" --{east={{2},{2,-2},{2,-2}},} -hvs.logs_pattern="east" --{east={{0},{0,-1},{0,-1,1}},} -- Which side the logistics are on. Yes you can have on all 4 sides. -hvs.combinator_pattern="west" -- Which side the combinator is on. - -platform.harvesters.west=hvs - -local hvs={key="east",position=platform.harvester.east} -hvs.energy="energy" -hvs.pad_prototype="warptorio-harvestpad-east" -hvs.prototype="warptorio-harvestportal" -hvs.tech="harvester_east" -hvs.fixed_level=nil -hvs.logs=true -hvs.dualloader=true -hvs.triloader=true -hvs.dopipes=true -hvs.pipes_pattern="west" --{west={{2},{2,-2},{2,-2}},} -hvs.logs_pattern="west" --{west={{0},{0,-1},{0,-1,1}},} -- Which side the logistics are on. -hvs.combinator_pattern="east" -- Which side the combinator is on. No patterns, dont put logistics over it. - - -platform.harvesters.east=hvs - --- No gigas yet - - ---[[ Homeworld ]]-- - -local floor={key="home"} -- Special key doesnt need a name -floor.empty=false -floor.radar=false -floor.special=nil -floor.migrate_tile=nil -platform.floors.home=floor - - - ---[[ Main Floor (Planet Surface) ]]-- - -local floor={key="main"} -- Special key doesnt need a name -floor.empty=false -floor.radar=false -floor.special={tech="warptorio-reactor-6",prototype="warptorio-reactor",size=vector(4,4),destructible=true} --vector.clean(f,vector.square(vector(-0.5,-0.5),vector(5,5))) -floor.migrate_tile=nil -- A tile that will never appear during default tile & hazard placement, excluding harvesters (special handling on them). nil=no migration - - -function floor.get_sizes() local t={} - t.size=warptorio.GetPlatformTechAmount("size") -- research.level etc -return t end - - -function floor.tile(f,b_void) - local zt=floor.get_sizes() - local z=zt.size or 8 - - local tiler="warp-tile-concrete" if(b_void)then tiler="out-of-map" end - - local area=vector.square(vector(-0.5,-0.5),vector(z,z)) - vector.clearFiltered(f,area) - vector.LayTiles(tiler,f,area) - - local rSize=research.level("warptorio-platform-size") - local rLogs=research.level("warptorio-logistics") - local rFacSize=research.level("warptorio-factory") - local rTpGate=research.has("warptorio-teleporter-portal") - - for u,c in pairs(platform.corner)do - local lvc=research.level("warptorio-turret-"..u.."") - if(research.has("warptorio-turret-"..u.."-0"))then local rad=math.floor((10+lvc*6)) - for k,v in pairs(f.find_entities_filtered{type="character",force={game.forces.player,game.forces.enemy},invert=true,position=c,radius=rad/2})do entity.tryclean(v) end - vector.LayCircle(tiler,f,vector.circleEx(c,rad)) - end - end -end -function floor.hazard(f) - local zt=floor.get_sizes() - local z=zt.size or 8 - - local area=vector.square(vector(-0.5,-0.5),vector(z,z)) - vector.LayTiles("hazard-concrete-left",f,vector.square(vector(-1,-1),vector(4,4))) - - local rSize=research.level("warptorio-platform-size") - --local rLogs=research.level("warptorio-logistics") - local rFacSize=research.level("warptorio-factory") - local rFac=research.has("warptorio-factory-0") - local rTpGate=research.has("warptorio-teleporter-portal") - - if(rSize>0)then local ltm,ltp - ltm=warptorio.GetTeleporterHazard(true,rFac) - ltp=warptorio.GetTeleporterHazard(false,rTpGate) - vector.LayTiles("hazard-concrete-left",f,vector.square(platform.teleporters["main_to_factory"].pair[1].position,ltm)) - vector.LayTiles("hazard-concrete-left",f,vector.square(platform.teleporters["offworld"].pair[1].position,ltp)) - end - if(rSize>=6)then for k,v in pairs(platform.railCorner)do local o=platform.railOffset[k] vector.LayTiles("hazard-concrete-left",f,vector.square(v+o,vector(1,1))) end end -- trains - - for u,c in pairs(platform.corner)do - local lvc=research.level("warptorio-turret-"..u.."") - if(research.has("warptorio-turret-"..u.."-0"))then local rad=math.floor((10+lvc*6)) - vector.LayTiles("hazard-concrete-left",f,vector.square(c,warptorio.GetTeleporterHazard(false))) - end - end -end - -function floor.technology(f) -- Check/re-apply technology-effects - -end -platform.floors.main=floor - - ---[[ Factory Floor ]]-- - -local floor={key="factory",name="warptorio_factory"} -floor.empty=true -floor.radar=true -floor.special={tech="warptorio-beacon",upgrade=true,prototype="warptorio-beacon",size=vector(2,2)} -floor.migrate_tile="grass-1" -- A tile that will never appear during default tile & hazard placement, excluding harvesters (special handling on them). nil=no migration - -function floor.get_sizes() local t={} - t.size=warptorio.GetPlatformTechAmount("factorysize") -- research.level etc -return t end - -function floor.tile(f) - local zt=floor.get_sizes() - local z=zt.size - - local area=vector.square(vector(-0.5,-0.5),vector(z,z)) - local rFacSize=research.level("warptorio-factory") - local rBoiler=research.has("warptorio-boiler-1") - local rLogs=research.level("warptorio-logistics") - local rBridge=research.level("warptorio-bridgesize") - vector.LayTiles("warp-tile-concrete",f,area) - - local rc={} for k in pairs(platform.corner)do local rclv=research.level("warptorio-turret-"..k) if(rclv>0 or research.has("warptorio-turret-"..k.."-0"))then rc[k]=rclv end end - local zMainWidth=10+rBridge*2 - local zMainHeight=59+rBridge*2-2 - local zLeg=6+rBridge*4 - local whas=(rc.nw or rc.sw) local nhas=(rc.nw or rc.ne) local ehas=(rc.ne or rc.se) local shas=(rc.sw or rc.se) - if(nhas)then vector.LayTiles("warp-tile-concrete",f,vector.square(vector(-0.5,platform.side.north.y/2),vector(zMainWidth,zMainHeight))) end - if(shas)then vector.LayTiles("warp-tile-concrete",f,vector.square(vector(-0.5,platform.side.south.y/2-0.5),vector(zMainWidth,zMainHeight))) end - if(ehas)then vector.LayTiles("warp-tile-concrete",f,vector.square(vector(platform.side.east.x/2-0.5,-0.5),vector(zMainHeight,zMainWidth))) end - if(whas)then vector.LayTiles("warp-tile-concrete",f,vector.square(vector(platform.side.west.x/2,-0.5),vector(zMainHeight,zMainWidth))) end - if(nhas and rc.nw)then vector.LayTiles("warp-tile-concrete",f,vector.square(vector(platform.side.west.x/2,platform.side.north.y),vector(zMainHeight,zLeg))) end - if(nhas and rc.ne)then vector.LayTiles("warp-tile-concrete",f,vector.square(vector(platform.side.east.x/2,platform.side.north.y),vector(zMainHeight,zLeg))) end - if(shas and rc.sw)then vector.LayTiles("warp-tile-concrete",f,vector.square(vector(platform.side.west.x/2,platform.side.south.y-0.5),vector(zMainHeight,zLeg))) end - if(shas and rc.se)then vector.LayTiles("warp-tile-concrete",f,vector.square(vector(platform.side.east.x/2,platform.side.south.y-0.5),vector(zMainHeight,zLeg))) end - if(ehas and rc.ne)then vector.LayTiles("warp-tile-concrete",f,vector.square(vector(platform.side.east.x-0.5,platform.side.north.y/2),vector(zLeg,zMainHeight))) end - if(ehas and rc.se)then vector.LayTiles("warp-tile-concrete",f,vector.square(vector(platform.side.east.x-0.5,platform.side.south.y/2),vector(zLeg,zMainHeight))) end - if(whas and rc.nw)then vector.LayTiles("warp-tile-concrete",f,vector.square(vector(platform.side.west.x,platform.side.north.y/2),vector(zLeg,zMainHeight))) end - if(whas and rc.sw)then vector.LayTiles("warp-tile-concrete",f,vector.square(vector(platform.side.west.x,platform.side.south.y/2),vector(zLeg,zMainHeight))) end - - for k,c in pairs(platform.corner)do if(rc[k])then local zx=(10+rc[k]*6) - vector.LayTiles("warp-tile-concrete",f,vector.square(c,vector(zx,zx))) vector.LayTiles("hazard-concrete-left",f,vector.square(c,warptorio.GetTeleporterHazard(false))) - end end - - local zgWidth=128-16 - local zgHeight=96-12 - local zgLegHeight=17 - local zgLegWidth=10 - - if(research.has("warptorio-factory-n"))then - vector.LayTiles("warp-tile-concrete",f,vector.square(platform.side.north+vector(-1,-zgLegHeight-zgHeight/2-1),vector(zgWidth,zgHeight))) - vector.LayTiles("warp-tile-concrete",f,vector.square(platform.side.north+vector(9-1,-zgLegHeight/2-1),vector(zgLegWidth,zgLegHeight))) - vector.LayTiles("warp-tile-concrete",f,vector.square(platform.side.north+vector(-9-1,-zgLegHeight/2-1),vector(zgLegWidth,zgLegHeight))) - end if(research.has("warptorio-factory-s"))then - vector.LayTiles("warp-tile-concrete",f,vector.square(platform.side.south+vector(-1,zgLegHeight+zgHeight/2),vector(zgWidth,zgHeight))) - vector.LayTiles("warp-tile-concrete",f,vector.square(platform.side.south+vector(9-1,zgLegHeight/2-1),vector(zgLegWidth,zgLegHeight))) - vector.LayTiles("warp-tile-concrete",f,vector.square(platform.side.south+vector(-9-1,zgLegHeight/2-1),vector(zgLegWidth,zgLegHeight))) - end if(research.has("warptorio-factory-w"))then - vector.LayTiles("warp-tile-concrete",f,vector.square(platform.side.west+vector(-zgLegHeight-zgHeight/2-1,-1),vector(zgHeight,zgWidth))) - vector.LayTiles("warp-tile-concrete",f,vector.square(platform.side.west+vector(-zgLegHeight/2-1,9-1),vector(zgLegHeight,zgLegWidth))) - vector.LayTiles("warp-tile-concrete",f,vector.square(platform.side.west+vector(-zgLegHeight/2-1,-9-1),vector(zgLegHeight,zgLegWidth))) - end if(research.has("warptorio-factory-e"))then - vector.LayTiles("warp-tile-concrete",f,vector.square(platform.side.east+vector(zgLegHeight+zgHeight/2,-1),vector(zgHeight,zgWidth))) - vector.LayTiles("warp-tile-concrete",f,vector.square(platform.side.east+vector(zgLegHeight/2-1,9-1),vector(zgLegHeight,zgLegWidth))) - vector.LayTiles("warp-tile-concrete",f,vector.square(platform.side.east+vector(zgLegHeight/2-1,-9-1),vector(zgLegHeight,zgLegWidth))) - end - -end - -function floor.hazard(f) - local zt=floor.get_sizes() - local z=zt.size - local area=vector.square(vector(-0.5,-0.5),vector(z,z)) - local rFac=research.has("warptorio-factory-0") - local rFacSize=research.level("warptorio-factory") - local rBoiler=research.has("warptorio-boiler-1") - local rHarv=research.has("warptorio-harvester-floor") - local rLogs=research.level("warptorio-logistics") - local rBridge=research.level("warptorio-bridgesize") - - if(rFacSize>=7)then for k,rv in pairs(platform.railOffset)do local rc=platform.railCorner[k] -- trains - local rvx=platform.railLoader[k] - vector.LayTiles("hazard-concrete-left",f,vector.square(vector(rc.x,rc.y),vector(1,1))) - vector.LayTiles("hazard-concrete-left",f,vector.square(vector(rc.x+rvx[1][1],rc.y+rvx[1][2]),vector(1,1))) - vector.LayTiles("hazard-concrete-left",f,vector.square(vector(rc.x+rvx[2][1],rc.y+rvx[2][2]),vector(1,1))) - end end - - vector.LayTiles("hazard-concrete-left",f,vector.square(platform.teleporters["factory_to_harvester"].pair[1].position, -- factory to harvester - (warptorio.GetTeleporterHazard(true,rHarv)) - )) - - vector.LayTiles("hazard-concrete-left",f,vector.square(platform.teleporters["main_to_factory"].pair[1].position, -- planet to factory - (warptorio.GetTeleporterHazard(true,rFac) ) - )) - vector.LayTiles("hazard-concrete-left",f,vector.square(vector(-0.5,-0.5),vector(2,2))) -end - -function floor.technology(f) - -end -platform.floors.factory=floor - - - ---[[ Harvester Floor ]]-- - -local floor={key="harvester",name="warptorio_harvester"} -floor.empty=true -floor.radar=false -floor.special=nil -- no special for harvester -floor.migrate_tile="grass-1" -- A tile that will never appear during default tile & hazard placement, excluding harvesters (special handling on them). nil=no migration - - -function floor.BuildHarvestCorner(f,cz,k,v) -- for giga harvesters unused - if(research.has("warptorio-harvester-"..k.."-gate"))then - vector.LayTiles("warp-tile-concrete",f,vector.square(v/3*2,vector(cz*1.25,cz*1.25))) - vector.LayTiles("warptorio-red-concrete",f,vector.square(v/3*2,vector(cz,cz))) - vector.LayTiles("hazard-concrete-left",f,vector.square((v/3*2),vector(2,2))) - end -end - - -function floor.get_sizes() local t={} - t.size=16 -- research.level etc - t.ovalsize=warptorio.GetPlatformTechAmount("harvestersize") or vector(22,17) -return t end - -function floor.hazard(f) - local zt=floor.get_sizes() - local z=zt.size - - --local rLogs=research.level("warptorio-logistics") - local rBoiler=research.has("warptorio-boiler-0") - - local bpair=platform.teleporters["factory_to_harvester"].pair - local apair=platform.teleporters["harvester_to_boiler"].pair - vector.LayTiles("hazard-concrete-left",f,vector.square(apair[1].position,(warptorio.GetTeleporterHazard(true,rBoiler)) )) -- harvester to boiler - vector.LayTiles("hazard-concrete-left",f,vector.square(bpair[1].position,warptorio.GetTeleporterHazard(true))) -- factory to harvester - --vector.LayTiles("hazard-concrete-left",f,vector.square(vector(-1,-1),vector(2,2))) -- beacon -end - -function floor.tile(f) - local zt=floor.get_sizes() - local z=zt.size - - - local cirMaxWidth=128+8 - local cirHeight=17 --64+4 --17 -- - - local minCir=vector(22,17) - local maxCir=vector(128+8,64+4) - local ovSize=vector(vector.getx(zt.ovalsize),vector.gety(zt.ovalsize)) -- vector(cirWidth,cirHeight) - - vector.LayCircle("warp-tile-concrete",f,vector.oval(vector(-1,-1),ovSize)) - - ---[[ for 4 corners -- unfinished - - --local zx=(platform.side.east.x+platform.side.west.x)/3*2 - --vector.LayTiles("warp-tile-concrete",f,vector.square(vector(platform.side.east.x/3*2,-1),vector(6,platform.side.south.y+3))) - --vector.LayTiles("warp-tile-concrete",f,vector.square(vector(platform.side.west.x/3*2,-1),vector(6,platform.side.south.y+3))) - local cz=16 - for k,v in pairs(platform.corner)do warptorio.BuildHarvestCorner(cz,k,v) end -]] - - -end - -function floor.technology(f) - -end - -floor.BuildHarvester={} -floor.BuildHarvester.west=function(f) - local zt=floor.get_sizes() - local z=zt.size - - local lvWest=research.level("warptorio-harvester-west") - if(lvWest>0)then - local ez=warptorio.GetHarvesterLevelSizeNum(lvWest) - local vz=128+8 local hvMax=47 local vzx=vz/2 local hvx=hvMax/2 local hvy=hvMax/8 - vector.LayTiles("warp-tile-concrete",f,vector.square(vector(-1-vz/3,-1),vector(vz/2+(hvMax/2.5)-ez/2,4+((lvWest-1)*2 ))) ) -- west bridge - end -end -floor.BuildHarvester.east=function(f) - local zt=floor.get_sizes() - local z=zt.size - - - - local lvEast=research.level("warptorio-harvester-east") - if(lvEast>0)then - local ez=warptorio.GetHarvesterLevelSizeNum(lvEast) - local vz=128+8 local hvMax=47 local vzx=vz/2 local hvx=hvMax/2 local hvy=hvMax/8 - local vecSize=vector( (vz/2+(hvMax/2.5)-ez/2),4+((lvEast-1)*2)) - vector.LayTiles("warp-tile-concrete",f,vector.square(vector(-1+vz/3,-1), vecSize)) -- east bridge - end -end - -platform.floors.harvester=floor - - - - - - ---[[ Boiler Floor ]]-- - -local floor={key="boiler",name="warptorio_boiler"} -floor.empty=true -floor.radar=true -floor.special={tech="warptorio-boiler-station",prototype="warptorio-warpstation",size=vector(2,2)} -floor.migrate_tile="grass-1" -- A tile that will never appear during default tile & hazard placement, excluding harvesters (special handling on them). nil=no migration - -function floor.get_sizes() local t={} - t.size=warptorio.GetPlatformTechAmount("boilersize") or 17 -- research.level etc - --error(serpent.block(warptorio.platform.techs.boilersize)) -return t end - -function floor.hazard(f) - local zt=floor.get_sizes() - local z=zt.size - - local rBoiler=research.level("warptorio-boiler") - local rLogs=research.level("warptorio-logistics") - local rWater=research.level("warptorio-boiler-water") - - vector.LayTiles("hazard-concrete-left",f,vector.square(platform.teleporters["harvester_to_boiler"].pair[1].position,warptorio.GetTeleporterHazard(true) )) -- Boiler entry - --vector.LayTiles("hazard-concrete-left",f,vector.square(warptorio.Teleporters.b2.position,warptorio.GetTeleporterHazard(true))) -- next level - vector.LayTiles("hazard-concrete-left",f,vector.square(vector(-1,-1),vector(2,2))) -- beacon -end -function floor.tile(f) - local zt=floor.get_sizes() - local z=zt.size - - local rBoiler=research.level("warptorio-boiler") - local rLogs=research.level("warptorio-logistics") - local rWater=research.level("warptorio-boiler-water") - - local zf=z/3 - local zfx=math.floor(zf) + (zf%2==0 and 0 or 1) - vector.LayTiles("warp-tile-concrete",f,vector.square(vector(-0.5,-0.5),vector(zfx*2,(z*2)))) - vector.LayTiles("warp-tile-concrete",f,vector.square(vector(-0.5,-0.5),vector((z*2),zfx*2))) - - if(rWater>0)then - local zx=(rWater*2) - local vx=zfx+zx/2+1 - vector.LayTiles("deepwater",f,vector.square(vector(-0.5,-0.5)+vector(vx,vx),vector(zx,zx))) -- se - vector.LayTiles("deepwater",f,vector.square(vector(-0.5,-0.5)+vector(-vx,vx),vector(zx,zx))) -- sw - vector.LayTiles("deepwater",f,vector.square(vector(-0.5,-0.5)+vector(-vx,-vx),vector(zx,zx))) -- nw - vector.LayTiles("deepwater",f,vector.square(vector(-0.5,-0.5)+vector(vx,-vx),vector(zx,zx))) -- ne - end - local rgNorth=research.has("warptorio-boiler-n") - local rgSouth=research.has("warptorio-boiler-s") - local rgEast=research.has("warptorio-boiler-e") - local rgWest=research.has("warptorio-boiler-w") - - local zgWidth=96 - local zgHeight=64 - local zgLegHeight=12 - local zgLegWidth=10 - - if(rgNorth)then - vector.LayTiles("warp-tile-concrete",f,vector.square(vector(-1,-z-zgLegHeight-(zgHeight/2)-1),vector(zgWidth,zgHeight))) - vector.LayTiles("warp-tile-concrete",f,vector.square(vector(9-1,-z-zgLegHeight/2-1),vector(zgLegWidth,zgLegHeight))) - vector.LayTiles("warp-tile-concrete",f,vector.square(vector(-9-1,-z-zgLegHeight/2-1),vector(zgLegWidth,zgLegHeight))) - end if(rgSouth)then - vector.LayTiles("warp-tile-concrete",f,vector.square(vector(-1,z+zgLegHeight+(zgHeight/2)-1),vector(zgWidth,zgHeight))) - vector.LayTiles("warp-tile-concrete",f,vector.square(vector(9-1,z+zgLegHeight/2-1),vector(zgLegWidth,zgLegHeight))) - vector.LayTiles("warp-tile-concrete",f,vector.square(vector(-9-1,z+zgLegHeight/2-1),vector(zgLegWidth,zgLegHeight))) - end if(rgEast)then - vector.LayTiles("warp-tile-concrete",f,vector.square(vector(z+zgLegHeight+(zgHeight/2)-1,-1),vector(zgHeight,zgWidth))) - vector.LayTiles("warp-tile-concrete",f,vector.square(vector(z+zgLegHeight/2-1,9-1),vector(zgLegHeight,zgLegWidth))) - vector.LayTiles("warp-tile-concrete",f,vector.square(vector(z+zgLegHeight/2-1,-9-1),vector(zgLegHeight,zgLegWidth))) - end if(rgWest)then - vector.LayTiles("warp-tile-concrete",f,vector.square(vector(-z-zgLegHeight-(zgHeight/2)-1,-1),vector(zgHeight,zgWidth))) - vector.LayTiles("warp-tile-concrete",f,vector.square(vector(-z-zgLegHeight/2-1,9-1),vector(zgLegHeight,zgLegWidth))) - vector.LayTiles("warp-tile-concrete",f,vector.square(vector(-z-zgLegHeight/2-1,-9-1),vector(zgLegHeight,zgLegWidth))) - end - -end - - -function floor.technology(f) - -end -platform.floors.boiler=floor - - - - - ---[[ Empty surface cache ]]-- - -cache.surface("platform_factory",{ - raise=function(self) local f=self.host - - -- size=16 - end, -}) - -cache.surface("platform_harvester",{ - raise=function(self) local f=self.host - f.solar_power_multiplier=settings.global.warptorio_solar_multiplier.value - f.daytime=0 - f.always_day=true - f.request_to_generate_chunks({0,0},16) - f.force_generate_chunk_requests() - f.destroy_decoratives({}) - for k,v in pairs(f.find_entities())do entity.destroy(v) end - local area=vector.area(vector(-32*8,-32*8),vector(32*8*2,32*8*2)) - vector.LayTiles("out-of-map",f,area) - -- size=16 - end, -}) - -cache.surface("platform_boiler",{ - raise=function(self) local f=self.host - f.solar_power_multiplier=settings.global.warptorio_solar_multiplier.value - f.daytime=0 - f.always_day=true - f.request_to_generate_chunks({0,0},16) - f.force_generate_chunk_requests() - f.destroy_decoratives({}) - for k,v in pairs(f.find_entities())do entity.destroy(v) end - local area=vector.area(vector(-32*8,-32*8),vector(32*8*2,32*8*2)) - vector.LayTiles("out-of-map",f,area) - -- size=16 - end, -}) - - - ---[[ General Platform Stuff ]]-- - -function platform.PositionInPlatform(f,pos) local gf=global.floor - if(f==gf.factory.surface)then return true - elseif(f==gf.boiler.surface)then return true - elseif(f==gf.harvester.surface)then return true - end - -- Do overworld checks here - -end - -function platform.GetWarpables(c,cf) - -- warptorio.IsWarping=true - --local m=global.floor.main - --local c=m.host - local mt=platform.floors.main.get_sizes() - - local marea=vector.square(vector.pos({-0.5,-0.5}),vector(mt.size,mt.size)) - - -- find entities and players to copy/transfer to new surface - local tpply={} local cx=platform.corn - local etbl={} - for k,v in pairs(c.find_entities_filtered{type={"car","character","player"},invert=true,area=marea})do - local biterwarp=(warptorio.setting("biter_warping")==false) - if(v.type=="spider-vehicle")then - --local drv=v.get_driver() if(isvalid(drv))then drv.driving=nil v.set_driver(nil) end - table.insert(etbl,v) - elseif(v.type=="item-entity" or v.type=="character-corpse" or v.last_user or v.force.name=="player" or (biterwarp and v.force.name=="enemy"))then - table.insert(etbl,v) - end - end - - -- find players to teleport to new platform - for k,v in pairs(game.players)do if(not v.driving)then if(v.character==nil or (v.surface==c and vector.inarea(v.position,marea)))then - table.insert(tpply,{v,vector.pos(v.position)}) - end end end - - -- find cars to teleport to new platform - for k,v in pairs(c.find_entities_filtered{type={"car","tank"},area=marea})do if((v.surface==c and vector.inarea(v.position,marea)))then - table.insert(tpply,{v,vector.pos(v.position)}) - end end - - -- find entities/players on the corners - for k,v in pairs({"nw","ne","sw","se"})do local ugName="turret-"..v local rHas=research.has("warptorio-"..ugName.."-0") if(rHas)then local ug=research.level("warptorio-"..ugName) - local etc=cf.find_entities_filtered{position={cx[v].x+0.5,cx[v].y+0.5},radius=math.floor(10+ug*6)/2} for a,e in pairs(etc)do e.destroy() end -- clean new platform corner - - local etp=c.find_entities_filtered{type="character",position={cx[v].x+0.5,cx[v].y+0.5},radius=(10+(ug*6))/2} -- find corner players - for a,e in pairs(etp)do if(e.player and e.player.character~=nil and not e.driving)then table.insert(tpply,{e.player,{e.position.x,e.position.y}}) end end - - local etp=c.find_entities_filtered{type={"car","tank"},position={cx[v].x+0.5,cx[v].y+0.5},radius=(10+(ug*6))/2} -- find corner cars - for a,e in pairs(etp)do table.insert(tpply,{e,{e.position.x,e.position.y}}) end - - local et=c.find_entities_filtered{type={"car","character","tank"},invert=true,position={cx[v].x+0.5,cx[v].y+0.5},radius=math.floor((10+ug*6)/2)-(1e-6)} -- find corner ents - for k,v in pairs(et)do if(v.last_user or v.force.name=="player" or (biterwarp and v.force.name=="enemy"))then - table.insertExclusive(etbl,v) - end end - - end end - - return etbl,tpply -end - - - - - - -return platform - - +local platform={} +platform.name="classic" + +--[[ Offsets and stuff ]]-- + +platform.railCorner={nw=vector(-35,-35),ne=vector(34,-35),sw=vector(-35,34),se=vector(34,34)} +platform.railOffset={nw=vector(0,0),ne=vector(-1,0),sw=vector(0,-1),se=vector(-1,-1)} --{nw=vector(-1,-1),ne=vector(0,-1),sw=vector(-1,0),se=vector(0,0)} +platform.railLoader={nw=vector.area(vector(2,0),vector(0,2)),sw=vector.area(vector(2,0),vector(0,-2)),ne=vector.area(vector(-2,0),vector(0,2)),se=vector.area(vector(-2,0),vector(0,-2))} + +platform.letterOpposite={n=defines.direction.south,s=defines.direction.north,e=defines.direction.west,w=defines.direction.east} +platform.railLoaderPos={ + nw={vector(2,0),vector(2,-1),vector(0,2),vector(-1,2)}, + sw={vector(2,0),vector(2,-1),vector(0,-2),vector(-1,-2)}, + ne={vector(-2,0),vector(-2,-1),vector(0,2),vector(-1,2)}, + se={vector(-2,0),vector(-2,-1),vector(0,-2),vector(-1,-2)}, +} + +--platform.corner={nw=vector(-52,-52),ne=vector(50,-52),sw=vector(-52,50),se=vector(50,50)} -- old +platform.corner={nw=vector(-51.5,-51.5),ne=vector(50.5,-51.5),sw=vector(-51.5,50.5),se=vector(50.5,50.5)} + +platform.side={north=vector(0,-52),south=vector(0,51),east=vector(51,0),west=vector(-52,0)} +--[[ +local cirMaxWidth=128+8 +local cirHeight=17 --64+4 --17 -- +local vz=cirMaxWidth +--local ez=m.harvestSize or 10 -- harvester size max 47 +local hvMax=47 +local vzx=vz/2 local hvx=hvMax/2 local hvy=hvMax/8 + +local westPos=warptorio.platform.harvester.west --vector(-(vzx+(hvx-hvy))+0.5,-0.5) +local eastPos=warptorio.platform.harvester.east --vector(vzx+(hvx-hvy),-0.5) +]] +local hvSize=(128+8)/2 +local hvMax=47 +platform.harvester={} +platform.harvester.east=vector(85.5,-0.5) --hvSize+((hvMax/2)-(hvMax/8)),-0.5) -- 85.625 +platform.harvester.west=vector(-86.5,-0.5) -- -(hvSize+((hvMax/2)-(hvMax/8)))+0.5,-0.5) -- -85.125 -- was -86 + + +platform.corn={} +platform.corn.nw={x=-52,y=-52} +platform.corn.ne={x=50,y=-52} +platform.corn.sw={x=-52,y=50} +platform.corn.se={x=50,y=50} +platform.corn.north=-52 +platform.corn.south=50 +platform.corn.east=50 +platform.corn.west=-51.5 + + + +--[[ Floors ]]-- + +platform.floors={} + + +-- Todo: Make teleporters and specials automatically do hazard tiles + +--[[ Platform Technology Effects ]]-- + +platform.techs={} + +-- General technologies + +platform.techs.boiler_station={tech="warptorio-boiler-station",effect={special={"boiler"}},} +platform.techs.reactor={tech="warptorio-reactor",level_range={1,8},effect={reactor=true,special={"main"}}, } + +platform.techs.tele_portal={tech="warptorio-teleporter-portal",effect={unlock_teleporters={"offworld"},},} +platform.techs.tele_energy={tech="warptorio-teleporter",level_range={1,5},effect={upgrade_energy={"offworld"},},} +platform.techs.energy={tech="warptorio-energy",level_range={1,5},effect={upgrade_energy=true},} +platform.techs.logistics={tech="warptorio-logistics",level_range={1,4},effect={upgrade_logistics=true},} +platform.techs.warp_beacon={tech="warptorio-beacon",level_range={1,10},effect={special={"factory"},},} + +platform.techs.dualloader={tech="warptorio-dualloader-1",effect={upgrade_logistics=true},} +platform.techs.triloader={tech="warptorio-triloader",effect={upgrade_logistics=true},} + +platform.techs.accelerator={tech="warptorio-accelerator",effect={ability="accelerator"},} +platform.techs.stabilizer={tech="warptorio-stabilizer",effect={ability="stabilizer"},} +platform.techs.charting={tech="warptorio-charting",effect={ability="charting",special={"factory","boiler"}},} + + +platform.techs.alt_combinator={tech="warptorio-alt-combinator",effect={do_combinators=true},} + +platform.techs.homeworld={tech="warptorio-homeworld",effect={unlock_homeworld=true},} + +platform.techs.toolbar={tech="warptorio-toolbar",effect={unlock_toolbar=true}} + + + + +-- Platform Surface Techs +platform.techs.size={tech="warptorio-platform-size",effect={retile={"main"}}, +levels={ + [0]=8, + [1]=10+7-1, + [2]=18+7-1, + [3]=26+7-1, + [4]=40+7-1, + [5]=56+7-1+2, + [6]=74+7-1+2, + [7]=92+7-1+4, +}} + +platform.techs.railnw={tech="warptorio-rail-nw",effect={unlock_rails="nw"},} +platform.techs.railne={tech="warptorio-rail-ne",effect={unlock_rails="ne"},} +platform.techs.railsw={tech="warptorio-rail-sw",effect={unlock_rails="sw"},} +platform.techs.railse={tech="warptorio-rail-se",effect={unlock_rails="se"},} + +platform.techs.turret_nw={tech="warptorio-turret-nw",first_effect={unlock_teleporters={"main_tur_factory_nw"}},effect={retile={"main","factory"}},level_range={0,3},} +platform.techs.turret_ne={tech="warptorio-turret-ne",first_effect={unlock_teleporters={"main_tur_factory_ne"}},effect={retile={"main","factory"}},level_range={0,3},} +platform.techs.turret_sw={tech="warptorio-turret-sw",first_effect={unlock_teleporters={"main_tur_factory_sw"}},effect={retile={"main","factory"}},level_range={0,3},} +platform.techs.turret_se={tech="warptorio-turret-se",first_effect={unlock_teleporters={"main_tur_factory_se"}},effect={retile={"main","factory"}},level_range={0,3},} + + +-- Factory Techs + +platform.techs.factory_n={tech="warptorio-factory-n",effect={retile={"factory"}},} +platform.techs.factory_s={tech="warptorio-factory-s",effect={retile={"factory"}},} +platform.techs.factory_e={tech="warptorio-factory-e",effect={retile={"factory"}},} +platform.techs.factory_w={tech="warptorio-factory-w",effect={retile={"factory"}},} +platform.techs.bridgesize={tech="warptorio-bridgesize",level_range={1,2},effect={retile={"factory"}},} + + +platform.techs.factorysize={tech="warptorio-factory",effect={retile={"factory"}}, +first_effect={rehazard={"main"},unlock_teleporters={"main_to_factory"},}, +levels={ + [0]=19-1, + [1]=23-1, + [2]=31-1, + [3]=39-1, + [4]=47-1, + [5]=55-1, + [6]=63-1, + [7]=71+2-1, +}, +} + + +-- Boiler Techs + +platform.techs.boiler_water={tech="warptorio-boiler-water",level_range={1,3},effect={retile={"boiler"},},} + +platform.techs.boiler_n={tech="warptorio-boiler-n",effect={retile={"boiler"}},} +platform.techs.boiler_s={tech="warptorio-boiler-s",effect={retile={"boiler"}},} +platform.techs.boiler_e={tech="warptorio-boiler-e",effect={retile={"boiler"}},} +platform.techs.boiler_w={tech="warptorio-boiler-w",effect={retile={"boiler"}},} + + +platform.techs.boilersize={tech="warptorio-boiler", +first_effect={rehazard={"harvester"},unlock_teleporters={"harvester_to_boiler"}}, +effect={retile={"boiler"}}, +levels={ + [0]=18, + [1]=24, + [2]=32, + [3]=40, + [4]=48, + [5]=56, + [6]=64, + [7]=72, +}, +} + + +platform.techs.harvesterfloor={tech="warptorio-harvester-floor",effect={retile={"harvester"},unlock_teleporters={"factory_to_harvester"}}, +} +platform.techs.harvestersize={tech="warptorio-harvester-size",effect={retile={"harvester"},}, -- oval sizes +levels={ + [0]=vector(19,17), + [1]=vector(28,22), + [2]=vector(36,26), + [3]=vector(48,32), + [4]=vector(74,40), + [5]=vector(92,48), + [6]=vector(112,56), + [7]=vector(128+8,64), +}, +} +platform.techs.harvester_west={tech="warptorio-harvester-west",effect={harvesters={"west"}}, +levels={ + [1]=12, + [2]=20, + [3]=26, + [4]=32, + [5]=38, +}, +} +platform.techs.harvester_east={tech="warptorio-harvester-east",effect={harvesters={"east"}}, +levels={ + [1]=12, + [2]=20, + [3]=26, + [4]=32, + [5]=38, +}, +} + +--unused platform.techs.harvester_west_loader={tech="warptorio-harvester-west-loader",effect={harvesters={"west"}},} +--unused platform.techs.harvester_east_loader={tech="warptorio-harvester-east-loader",effect={harvesters={"east"}},} + + +--[[ Rails registers ]]-- + +platform.rails={} +local tpr={key="nw"} platform.rails[tpr.key]=tpr +tpr.railpos=platform.railCorner[tpr.key]+platform.railOffset[tpr.key] +tpr.chestpos=platform.railCorner[tpr.key] --+platform.railOffset[tpr.key] +tpr.floor="factory" +tpr.logs={false,true,true,false} + +local tpr={key="ne"} platform.rails[tpr.key]=tpr +tpr.railpos=platform.railCorner[tpr.key]+platform.railOffset[tpr.key] +tpr.chestpos=platform.railCorner[tpr.key] --+platform.railOffset[tpr.key] +tpr.floor="factory" +tpr.logs={false,false,true,true} + +local tpr={key="sw"} platform.rails[tpr.key]=tpr +tpr.railpos=platform.railCorner[tpr.key]+platform.railOffset[tpr.key] +tpr.chestpos=platform.railCorner[tpr.key] --+platform.railOffset[tpr.key] +tpr.floor="factory" +tpr.logs={true,true,false,false} + +local tpr={key="se"} platform.rails[tpr.key]=tpr +tpr.railpos=platform.railCorner[tpr.key]+platform.railOffset[tpr.key] +tpr.chestpos=platform.railCorner[tpr.key] --+platform.railOffset[tpr.key] +tpr.floor="factory" +tpr.logs={true,false,false,true} + + + + +--[[ Teleporter registers ]]-- + +platform.teleporters={} + +--[[ Offworld Teleporter ]]-- + +-- Offworld is special and has some special handling on its pair, e.g. the second pair doesn't get hazards and can be spawned freely because you can pick it up. +local tps={key="offworld"} platform.teleporters[tps.key]=tps +tps.logs=true -- this teleporter gains loaders on the first logistics upgrade +tps.dopipes=true -- this teleporter should be given pipes +tps.dualloader=false -- this teleporter gets an extra loader on the dualloader upgrade +tps.triloader=true -- this teleporter gets an extra loader on the triloader upgrade +tps.top=false -- this teleporter is a "top loader" used to determine loader direction via settings. +tps.circuit=false -- Should be false if the teleporter pair isn't in the same position. +tps.staticdir=false -- "up" or "down" if the logistics cannot have their direction changed with setting +tps.oneside=false -- If this teleporter is onesided, "left" or "right" +tps.rotated=false -- If true, this has logistics on top and bottom instead of left and right +tps.logiport=false -- Set to true if this is logistics only. +tps.energy="tele_energy" -- platform tech name + +tps.pair={ + {floor="main",position=vector(-1,5), + prototype="warptorio-teleporter", + }, + {floor="main",position=vector(-1,8), + prototype="warptorio-teleporter-gate", + gate=true, -- Logistics spawning behaviour flag + minable=true, -- Flag to pickup + destructible=true, -- Can be destroyed + } +} + + +--[[ Main Factory Teleporter ]]-- + +local tps={key="main_to_factory"} platform.teleporters[tps.key]=tps +tps.logs=true +tps.dopipes=true +tps.dualloader=true +tps.triloader=true +tps.top=true +tps.circuit=true +tps.staticdir=false +tps.oneside=false +tps.rotated=false +tps.logiport=false +tps.energy="energy" + +tps.pair={ + {floor="main",position=vector(-1,-7), + prototype="warptorio-underground", + sprite_arrow="down", + sprites={ + {sprite="technology/automation",target_offset={0,-0.25},x_scale=0.5,y_scale=0.5,tint={r=1,g=0.7,b=0.4,a=1}}, + }, + }, + {floor="factory",position=vector(-1,-7), + prototype="warptorio-underground", + sprite_arrow="up", + sprites={ + {sprite="technology/concrete",target_offset={0,-0.25},x_scale=0.5,y_scale=0.5,tint={r=1,g=0.7,b=0.4,a=1}}, + }, + } +} + +-- Main Turrets copy from Main Factory + +local kdir="nw" +local key="main_tur_factory_"..kdir +local tpv=table.deepcopy(tps) +tpv.dualloader=false +tpv.top=true +tpv.triloader=true +tpv.circuit=true +tpv.key=key platform.teleporters[key]=tpv +tpv.pair[1].position=platform.corner[kdir]-vector(0.5,0.5) +tpv.pair[2].position=platform.corner[kdir]-vector(0.5,0.5) +tpv.pair[1].sprites=nil +tpv.pair[2].sprites=nil + +local kdir="ne" +local key="main_tur_factory_"..kdir +local tpv=table.deepcopy(tps) +tpv.dualloader=false +tpv.top=true +tpv.triloader=true +tpv.circuit=true +tpv.key=key platform.teleporters[key]=tpv +tpv.pair[1].position=platform.corner[kdir]-vector(0.5,0.5) +tpv.pair[2].position=platform.corner[kdir]-vector(0.5,0.5) +tpv.pair[1].sprites=nil +tpv.pair[2].sprites=nil + +local kdir="sw" +local key="main_tur_factory_"..kdir +local tpv=table.deepcopy(tps) +tpv.dualloader=false +tpv.triloader=true +tpv.circuit=true +tpv.top=false +tpv.key=key platform.teleporters[key]=tpv +tpv.pair[1].position=platform.corner[kdir]-vector(0.5,0.5) +tpv.pair[2].position=platform.corner[kdir]-vector(0.5,0.5) +tpv.pair[1].sprites=nil +tpv.pair[2].sprites=nil + +local kdir="se" +local key="main_tur_factory_"..kdir +local tpv=table.deepcopy(tps) +tpv.dualloader=false +tpv.triloader=true +tpv.circuit=true +tpv.top=false +tpv.key=key platform.teleporters[key]=tpv +tpv.pair[1].position=platform.corner[kdir]-vector(0.5,0.5) +tpv.pair[2].position=platform.corner[kdir]-vector(0.5,0.5) +tpv.pair[1].sprites=nil +tpv.pair[2].sprites=nil + + +--[[ Factory to Harvester Teleporter ]]-- + +local tps={key="factory_to_harvester"} platform.teleporters[tps.key]=tps +tps.logs=true +tps.dopipes=true +tps.dualloader=true +tps.triloader=true +tps.top=false +tps.circuit=true +tps.staticdir=false +tps.oneside=false +tps.rotated=false +tps.logiport=false +tps.energy="energy" +tps.pair={ + {floor="factory",position=vector(-1,5), + prototype="warptorio-underground", + sprite_arrow="down", + sprites={ + {sprite="technology/tank",target_offset={0,-0.25},x_scale=0.5,y_scale=0.5,tint={r=1,g=0.7,b=0.4,a=1}}, + }, + }, + {floor="harvester",position=vector(-1,5), + prototype="warptorio-underground", + sprite_arrow="up", + sprites={ + {sprite="technology/automation",target_offset={0,-0.25},x_scale=0.5,y_scale=0.5,tint={r=1,g=0.7,b=0.4,a=1}}, + }, + } +} + + + +--[[ Harvester to Boiler Teleporter ]]-- + +local tps={key="harvester_to_boiler"} platform.teleporters[tps.key]=tps +tps.logs=true +tps.dopipes=true +tps.dualloader=true +tps.triloader=true +tps.top=true +tps.circuit=true +tps.staticdir=false +tps.oneside=false +tps.rotated=false +tps.logiport=false +tps.energy="energy" +tps.pair={ + {floor="harvester",position=vector(-1,-7), + prototype="warptorio-underground", + sprite_arrow="down", + sprites={ + {sprite="technology/fluid-handling",target_offset={0,-0.25},x_scale=0.5,y_scale=0.5,tint={r=1,g=0.7,b=0.4,a=1}} + }, + }, + {floor="boiler",position=vector(-1,-7), + prototype="warptorio-underground", + sprite_arrow="up", + sprites={ + + {sprite="technology/tank",target_offset={0,-0.25},x_scale=0.5,y_scale=0.5,tint={r=1,g=0.7,b=0.4,a=1}} + }, + } +} + + + + +--[[ Harvester registers ]]-- + +platform.HarvesterPointData={ + energy="energy", + pair={ + {floor="harvester",prototype="warptorio-harvestportal",minable=true,destructible=false}, + {floor="main",prototype="warptorio-harvestportal",minable=true,destructible=true,gate=true}, + }, +} + +platform.harvesters={} + +local hvs={key="west",position=platform.harvester.west} +hvs.energy="energy" +hvs.pad_prototype="warptorio-harvestpad-west" +hvs.prototype="warptorio-harvestportal" +hvs.tech="harvester_west" -- harvester size tech name, or.. +hvs.fixed_level=nil -- If this harvester is a fixed level +hvs.logs=true +hvs.dualloader=true +hvs.triloader=true +hvs.dopipes=true +hvs.pipes_pattern="east" --{east={{2},{2,-2},{2,-2}},} +hvs.logs_pattern="east" --{east={{0},{0,-1},{0,-1,1}},} -- Which side the logistics are on. Yes you can have on all 4 sides. +hvs.combinator_pattern="west" -- Which side the combinator is on. + +platform.harvesters.west=hvs + +local hvs={key="east",position=platform.harvester.east} +hvs.energy="energy" +hvs.pad_prototype="warptorio-harvestpad-east" +hvs.prototype="warptorio-harvestportal" +hvs.tech="harvester_east" +hvs.fixed_level=nil +hvs.logs=true +hvs.dualloader=true +hvs.triloader=true +hvs.dopipes=true +hvs.pipes_pattern="west" --{west={{2},{2,-2},{2,-2}},} +hvs.logs_pattern="west" --{west={{0},{0,-1},{0,-1,1}},} -- Which side the logistics are on. +hvs.combinator_pattern="east" -- Which side the combinator is on. No patterns, dont put logistics over it. + + +platform.harvesters.east=hvs + +-- No gigas yet + + +--[[ Homeworld ]]-- + +local floor={key="home"} -- Special key doesnt need a name +floor.empty=false +floor.radar=false +floor.special=nil +floor.migrate_tile=nil +platform.floors.home=floor + + + +--[[ Main Floor (Planet Surface) ]]-- + +local floor={key="main"} -- Special key doesnt need a name +floor.empty=false +floor.radar=false +floor.special={tech="warptorio-reactor-6",prototype="warptorio-reactor",size=vector(4,4),destructible=true} --vector.clean(f,vector.square(vector(-0.5,-0.5),vector(5,5))) +floor.migrate_tile=nil -- A tile that will never appear during default tile & hazard placement, excluding harvesters (special handling on them). nil=no migration + + +function floor.get_sizes() local t={} + t.size=warptorio.GetPlatformTechAmount("size") -- research.level etc +return t end + + +function floor.tile(f,b_void) + local zt=floor.get_sizes() + local z=zt.size or 8 + + local tiler="warp-tile-concrete" if(b_void)then tiler="out-of-map" end + + local area=vector.square(vector(-0.5,-0.5),vector(z,z)) + vector.clearFiltered(f,area) + vector.LayTiles(tiler,f,area) + + local rSize=research.level("warptorio-platform-size") + local rLogs=research.level("warptorio-logistics") + local rFacSize=research.level("warptorio-factory") + local rTpGate=research.has("warptorio-teleporter-portal") + + for u,c in pairs(platform.corner)do + local lvc=research.level("warptorio-turret-"..u.."") + if(research.has("warptorio-turret-"..u.."-0"))then local rad=math.floor((10+lvc*6)) + for k,v in pairs(f.find_entities_filtered{type="character",force={game.forces.player,game.forces.enemy},invert=true,position=c,radius=rad/2})do entity.tryclean(v) end + vector.LayCircle(tiler,f,vector.circleEx(c,rad)) + end + end +end +function floor.hazard(f) + local zt=floor.get_sizes() + local z=zt.size or 8 + + local area=vector.square(vector(-0.5,-0.5),vector(z,z)) + vector.LayTiles("hazard-concrete-left",f,vector.square(vector(-1,-1),vector(4,4))) + + local rSize=research.level("warptorio-platform-size") + --local rLogs=research.level("warptorio-logistics") + local rFacSize=research.level("warptorio-factory") + local rFac=research.has("warptorio-factory-0") + local rTpGate=research.has("warptorio-teleporter-portal") + + if(rSize>0)then local ltm,ltp + ltm=warptorio.GetTeleporterHazard(true,rFac) + ltp=warptorio.GetTeleporterHazard(false,rTpGate) + vector.LayTiles("hazard-concrete-left",f,vector.square(platform.teleporters["main_to_factory"].pair[1].position,ltm)) + vector.LayTiles("hazard-concrete-left",f,vector.square(platform.teleporters["offworld"].pair[1].position,ltp)) + end + if(rSize>=6)then for k,v in pairs(platform.railCorner)do local o=platform.railOffset[k] vector.LayTiles("hazard-concrete-left",f,vector.square(v+o,vector(1,1))) end end -- trains + + for u,c in pairs(platform.corner)do + local lvc=research.level("warptorio-turret-"..u.."") + if(research.has("warptorio-turret-"..u.."-0"))then local rad=math.floor((10+lvc*6)) + vector.LayTiles("hazard-concrete-left",f,vector.square(c,warptorio.GetTeleporterHazard(false))) + end + end +end + +function floor.technology(f) -- Check/re-apply technology-effects + +end +platform.floors.main=floor + + +--[[ Factory Floor ]]-- + +local floor={key="factory",name="warptorio_factory"} +floor.empty=true +floor.radar=true +floor.special={tech="warptorio-beacon",upgrade=true,prototype="warptorio-beacon",size=vector(2,2)} +floor.migrate_tile="grass-1" -- A tile that will never appear during default tile & hazard placement, excluding harvesters (special handling on them). nil=no migration + +function floor.get_sizes() local t={} + t.size=warptorio.GetPlatformTechAmount("factorysize") -- research.level etc +return t end + +function floor.tile(f) + local zt=floor.get_sizes() + local z=zt.size + + local area=vector.square(vector(-0.5,-0.5),vector(z,z)) + local rFacSize=research.level("warptorio-factory") + local rBoiler=research.has("warptorio-boiler-1") + local rLogs=research.level("warptorio-logistics") + local rBridge=research.level("warptorio-bridgesize") + vector.LayTiles("warp-tile-concrete",f,area) + + local rc={} for k in pairs(platform.corner)do local rclv=research.level("warptorio-turret-"..k) if(rclv>0 or research.has("warptorio-turret-"..k.."-0"))then rc[k]=rclv end end + local zMainWidth=10+rBridge*2 + local zMainHeight=59+rBridge*2-2 + local zLeg=6+rBridge*4 + local whas=(rc.nw or rc.sw) local nhas=(rc.nw or rc.ne) local ehas=(rc.ne or rc.se) local shas=(rc.sw or rc.se) + if(nhas)then vector.LayTiles("warp-tile-concrete",f,vector.square(vector(-0.5,platform.side.north.y/2),vector(zMainWidth,zMainHeight))) end + if(shas)then vector.LayTiles("warp-tile-concrete",f,vector.square(vector(-0.5,platform.side.south.y/2-0.5),vector(zMainWidth,zMainHeight))) end + if(ehas)then vector.LayTiles("warp-tile-concrete",f,vector.square(vector(platform.side.east.x/2-0.5,-0.5),vector(zMainHeight,zMainWidth))) end + if(whas)then vector.LayTiles("warp-tile-concrete",f,vector.square(vector(platform.side.west.x/2,-0.5),vector(zMainHeight,zMainWidth))) end + if(nhas and rc.nw)then vector.LayTiles("warp-tile-concrete",f,vector.square(vector(platform.side.west.x/2,platform.side.north.y),vector(zMainHeight,zLeg))) end + if(nhas and rc.ne)then vector.LayTiles("warp-tile-concrete",f,vector.square(vector(platform.side.east.x/2,platform.side.north.y),vector(zMainHeight,zLeg))) end + if(shas and rc.sw)then vector.LayTiles("warp-tile-concrete",f,vector.square(vector(platform.side.west.x/2,platform.side.south.y-0.5),vector(zMainHeight,zLeg))) end + if(shas and rc.se)then vector.LayTiles("warp-tile-concrete",f,vector.square(vector(platform.side.east.x/2,platform.side.south.y-0.5),vector(zMainHeight,zLeg))) end + if(ehas and rc.ne)then vector.LayTiles("warp-tile-concrete",f,vector.square(vector(platform.side.east.x-0.5,platform.side.north.y/2),vector(zLeg,zMainHeight))) end + if(ehas and rc.se)then vector.LayTiles("warp-tile-concrete",f,vector.square(vector(platform.side.east.x-0.5,platform.side.south.y/2),vector(zLeg,zMainHeight))) end + if(whas and rc.nw)then vector.LayTiles("warp-tile-concrete",f,vector.square(vector(platform.side.west.x,platform.side.north.y/2),vector(zLeg,zMainHeight))) end + if(whas and rc.sw)then vector.LayTiles("warp-tile-concrete",f,vector.square(vector(platform.side.west.x,platform.side.south.y/2),vector(zLeg,zMainHeight))) end + + for k,c in pairs(platform.corner)do if(rc[k])then local zx=(10+rc[k]*6) + vector.LayTiles("warp-tile-concrete",f,vector.square(c,vector(zx,zx))) vector.LayTiles("hazard-concrete-left",f,vector.square(c,warptorio.GetTeleporterHazard(false))) + end end + + local zgWidth=128-16 + local zgHeight=96-12 + local zgLegHeight=17 + local zgLegWidth=10 + + if(research.has("warptorio-factory-n"))then + vector.LayTiles("warp-tile-concrete",f,vector.square(platform.side.north+vector(-1,-zgLegHeight-zgHeight/2-1),vector(zgWidth,zgHeight))) + vector.LayTiles("warp-tile-concrete",f,vector.square(platform.side.north+vector(9-1,-zgLegHeight/2-1),vector(zgLegWidth,zgLegHeight))) + vector.LayTiles("warp-tile-concrete",f,vector.square(platform.side.north+vector(-9-1,-zgLegHeight/2-1),vector(zgLegWidth,zgLegHeight))) + end if(research.has("warptorio-factory-s"))then + vector.LayTiles("warp-tile-concrete",f,vector.square(platform.side.south+vector(-1,zgLegHeight+zgHeight/2),vector(zgWidth,zgHeight))) + vector.LayTiles("warp-tile-concrete",f,vector.square(platform.side.south+vector(9-1,zgLegHeight/2-1),vector(zgLegWidth,zgLegHeight))) + vector.LayTiles("warp-tile-concrete",f,vector.square(platform.side.south+vector(-9-1,zgLegHeight/2-1),vector(zgLegWidth,zgLegHeight))) + end if(research.has("warptorio-factory-w"))then + vector.LayTiles("warp-tile-concrete",f,vector.square(platform.side.west+vector(-zgLegHeight-zgHeight/2-1,-1),vector(zgHeight,zgWidth))) + vector.LayTiles("warp-tile-concrete",f,vector.square(platform.side.west+vector(-zgLegHeight/2-1,9-1),vector(zgLegHeight,zgLegWidth))) + vector.LayTiles("warp-tile-concrete",f,vector.square(platform.side.west+vector(-zgLegHeight/2-1,-9-1),vector(zgLegHeight,zgLegWidth))) + end if(research.has("warptorio-factory-e"))then + vector.LayTiles("warp-tile-concrete",f,vector.square(platform.side.east+vector(zgLegHeight+zgHeight/2,-1),vector(zgHeight,zgWidth))) + vector.LayTiles("warp-tile-concrete",f,vector.square(platform.side.east+vector(zgLegHeight/2-1,9-1),vector(zgLegHeight,zgLegWidth))) + vector.LayTiles("warp-tile-concrete",f,vector.square(platform.side.east+vector(zgLegHeight/2-1,-9-1),vector(zgLegHeight,zgLegWidth))) + end + +end + +function floor.hazard(f) + local zt=floor.get_sizes() + local z=zt.size + local area=vector.square(vector(-0.5,-0.5),vector(z,z)) + local rFac=research.has("warptorio-factory-0") + local rFacSize=research.level("warptorio-factory") + local rBoiler=research.has("warptorio-boiler-1") + local rHarv=research.has("warptorio-harvester-floor") + local rLogs=research.level("warptorio-logistics") + local rBridge=research.level("warptorio-bridgesize") + + if(rFacSize>=7)then for k,rv in pairs(platform.railOffset)do local rc=platform.railCorner[k] -- trains + local rvx=platform.railLoader[k] + vector.LayTiles("hazard-concrete-left",f,vector.square(vector(rc.x,rc.y),vector(1,1))) + vector.LayTiles("hazard-concrete-left",f,vector.square(vector(rc.x+rvx[1][1],rc.y+rvx[1][2]),vector(1,1))) + vector.LayTiles("hazard-concrete-left",f,vector.square(vector(rc.x+rvx[2][1],rc.y+rvx[2][2]),vector(1,1))) + end end + + vector.LayTiles("hazard-concrete-left",f,vector.square(platform.teleporters["factory_to_harvester"].pair[1].position, -- factory to harvester + (warptorio.GetTeleporterHazard(true,rHarv)) + )) + + vector.LayTiles("hazard-concrete-left",f,vector.square(platform.teleporters["main_to_factory"].pair[1].position, -- planet to factory + (warptorio.GetTeleporterHazard(true,rFac) ) + )) + vector.LayTiles("hazard-concrete-left",f,vector.square(vector(-0.5,-0.5),vector(2,2))) +end + +function floor.technology(f) + +end +platform.floors.factory=floor + + + +--[[ Harvester Floor ]]-- + +local floor={key="harvester",name="warptorio_harvester"} +floor.empty=true +floor.radar=false +floor.special=nil -- no special for harvester +floor.migrate_tile="grass-1" -- A tile that will never appear during default tile & hazard placement, excluding harvesters (special handling on them). nil=no migration + + +function floor.BuildHarvestCorner(f,cz,k,v) -- for giga harvesters unused + if(research.has("warptorio-harvester-"..k.."-gate"))then + vector.LayTiles("warp-tile-concrete",f,vector.square(v/3*2,vector(cz*1.25,cz*1.25))) + vector.LayTiles("warptorio-red-concrete",f,vector.square(v/3*2,vector(cz,cz))) + vector.LayTiles("hazard-concrete-left",f,vector.square((v/3*2),vector(2,2))) + end +end + + +function floor.get_sizes() local t={} + t.size=16 -- research.level etc + t.ovalsize=warptorio.GetPlatformTechAmount("harvestersize") or vector(22,17) +return t end + +function floor.hazard(f) + local zt=floor.get_sizes() + local z=zt.size + + --local rLogs=research.level("warptorio-logistics") + local rBoiler=research.has("warptorio-boiler-0") + + local bpair=platform.teleporters["factory_to_harvester"].pair + local apair=platform.teleporters["harvester_to_boiler"].pair + vector.LayTiles("hazard-concrete-left",f,vector.square(apair[1].position,(warptorio.GetTeleporterHazard(true,rBoiler)) )) -- harvester to boiler + vector.LayTiles("hazard-concrete-left",f,vector.square(bpair[1].position,warptorio.GetTeleporterHazard(true))) -- factory to harvester + --vector.LayTiles("hazard-concrete-left",f,vector.square(vector(-1,-1),vector(2,2))) -- beacon +end + +function floor.tile(f) + local zt=floor.get_sizes() + local z=zt.size + + + local cirMaxWidth=128+8 + local cirHeight=17 --64+4 --17 -- + + local minCir=vector(22,17) + local maxCir=vector(128+8,64+4) + local ovSize=vector(vector.getx(zt.ovalsize),vector.gety(zt.ovalsize)) -- vector(cirWidth,cirHeight) + + vector.LayCircle("warp-tile-concrete",f,vector.oval(vector(-1,-1),ovSize)) + + +--[[ for 4 corners -- unfinished + + --local zx=(platform.side.east.x+platform.side.west.x)/3*2 + --vector.LayTiles("warp-tile-concrete",f,vector.square(vector(platform.side.east.x/3*2,-1),vector(6,platform.side.south.y+3))) + --vector.LayTiles("warp-tile-concrete",f,vector.square(vector(platform.side.west.x/3*2,-1),vector(6,platform.side.south.y+3))) + local cz=16 + for k,v in pairs(platform.corner)do warptorio.BuildHarvestCorner(cz,k,v) end +]] + + +end + +function floor.technology(f) + +end + +floor.BuildHarvester={} +floor.BuildHarvester.west=function(f) + local zt=floor.get_sizes() + local z=zt.size + + local lvWest=research.level("warptorio-harvester-west") + if(lvWest>0)then + local ez=warptorio.GetHarvesterLevelSizeNum(lvWest) + local vz=128+8 local hvMax=47 local vzx=vz/2 local hvx=hvMax/2 local hvy=hvMax/8 + vector.LayTiles("warp-tile-concrete",f,vector.square(vector(-1-vz/3,-1),vector(vz/2+(hvMax/2.5)-ez/2,4+((lvWest-1)*2 ))) ) -- west bridge + end +end +floor.BuildHarvester.east=function(f) + local zt=floor.get_sizes() + local z=zt.size + + + + local lvEast=research.level("warptorio-harvester-east") + if(lvEast>0)then + local ez=warptorio.GetHarvesterLevelSizeNum(lvEast) + local vz=128+8 local hvMax=47 local vzx=vz/2 local hvx=hvMax/2 local hvy=hvMax/8 + local vecSize=vector( (vz/2+(hvMax/2.5)-ez/2),4+((lvEast-1)*2)) + vector.LayTiles("warp-tile-concrete",f,vector.square(vector(-1+vz/3,-1), vecSize)) -- east bridge + end +end + +platform.floors.harvester=floor + + + + + + +--[[ Boiler Floor ]]-- + +local floor={key="boiler",name="warptorio_boiler"} +floor.empty=true +floor.radar=true +floor.special={tech="warptorio-boiler-station",prototype="warptorio-warpstation",size=vector(2,2)} +floor.migrate_tile="grass-1" -- A tile that will never appear during default tile & hazard placement, excluding harvesters (special handling on them). nil=no migration + +function floor.get_sizes() local t={} + t.size=warptorio.GetPlatformTechAmount("boilersize") or 17 -- research.level etc + --error(serpent.block(warptorio.platform.techs.boilersize)) +return t end + +function floor.hazard(f) + local zt=floor.get_sizes() + local z=zt.size + + local rBoiler=research.level("warptorio-boiler") + local rLogs=research.level("warptorio-logistics") + local rWater=research.level("warptorio-boiler-water") + + vector.LayTiles("hazard-concrete-left",f,vector.square(platform.teleporters["harvester_to_boiler"].pair[1].position,warptorio.GetTeleporterHazard(true) )) -- Boiler entry + --vector.LayTiles("hazard-concrete-left",f,vector.square(warptorio.Teleporters.b2.position,warptorio.GetTeleporterHazard(true))) -- next level + vector.LayTiles("hazard-concrete-left",f,vector.square(vector(-1,-1),vector(2,2))) -- beacon +end +function floor.tile(f) + local zt=floor.get_sizes() + local z=zt.size + + local rBoiler=research.level("warptorio-boiler") + local rLogs=research.level("warptorio-logistics") + local rWater=research.level("warptorio-boiler-water") + + local zf=z/3 + local zfx=math.floor(zf) + (zf%2==0 and 0 or 1) + vector.LayTiles("warp-tile-concrete",f,vector.square(vector(-0.5,-0.5),vector(zfx*2,(z*2)))) + vector.LayTiles("warp-tile-concrete",f,vector.square(vector(-0.5,-0.5),vector((z*2),zfx*2))) + + if(rWater>0)then + local zx=(rWater*2) + local vx=zfx+zx/2+1 + vector.LayTiles("deepwater",f,vector.square(vector(-0.5,-0.5)+vector(vx,vx),vector(zx,zx))) -- se + vector.LayTiles("deepwater",f,vector.square(vector(-0.5,-0.5)+vector(-vx,vx),vector(zx,zx))) -- sw + vector.LayTiles("deepwater",f,vector.square(vector(-0.5,-0.5)+vector(-vx,-vx),vector(zx,zx))) -- nw + vector.LayTiles("deepwater",f,vector.square(vector(-0.5,-0.5)+vector(vx,-vx),vector(zx,zx))) -- ne + end + local rgNorth=research.has("warptorio-boiler-n") + local rgSouth=research.has("warptorio-boiler-s") + local rgEast=research.has("warptorio-boiler-e") + local rgWest=research.has("warptorio-boiler-w") + + local zgWidth=96 + local zgHeight=64 + local zgLegHeight=12 + local zgLegWidth=10 + + if(rgNorth)then + vector.LayTiles("warp-tile-concrete",f,vector.square(vector(-1,-z-zgLegHeight-(zgHeight/2)-1),vector(zgWidth,zgHeight))) + vector.LayTiles("warp-tile-concrete",f,vector.square(vector(9-1,-z-zgLegHeight/2-1),vector(zgLegWidth,zgLegHeight))) + vector.LayTiles("warp-tile-concrete",f,vector.square(vector(-9-1,-z-zgLegHeight/2-1),vector(zgLegWidth,zgLegHeight))) + end if(rgSouth)then + vector.LayTiles("warp-tile-concrete",f,vector.square(vector(-1,z+zgLegHeight+(zgHeight/2)-1),vector(zgWidth,zgHeight))) + vector.LayTiles("warp-tile-concrete",f,vector.square(vector(9-1,z+zgLegHeight/2-1),vector(zgLegWidth,zgLegHeight))) + vector.LayTiles("warp-tile-concrete",f,vector.square(vector(-9-1,z+zgLegHeight/2-1),vector(zgLegWidth,zgLegHeight))) + end if(rgEast)then + vector.LayTiles("warp-tile-concrete",f,vector.square(vector(z+zgLegHeight+(zgHeight/2)-1,-1),vector(zgHeight,zgWidth))) + vector.LayTiles("warp-tile-concrete",f,vector.square(vector(z+zgLegHeight/2-1,9-1),vector(zgLegHeight,zgLegWidth))) + vector.LayTiles("warp-tile-concrete",f,vector.square(vector(z+zgLegHeight/2-1,-9-1),vector(zgLegHeight,zgLegWidth))) + end if(rgWest)then + vector.LayTiles("warp-tile-concrete",f,vector.square(vector(-z-zgLegHeight-(zgHeight/2)-1,-1),vector(zgHeight,zgWidth))) + vector.LayTiles("warp-tile-concrete",f,vector.square(vector(-z-zgLegHeight/2-1,9-1),vector(zgLegHeight,zgLegWidth))) + vector.LayTiles("warp-tile-concrete",f,vector.square(vector(-z-zgLegHeight/2-1,-9-1),vector(zgLegHeight,zgLegWidth))) + end + +end + + +function floor.technology(f) + +end +platform.floors.boiler=floor + + + + + +--[[ Empty surface cache ]]-- + +cache.surface("platform_factory",{ + raise=function(self) local f=self.host + + -- size=16 + end, +}) + +cache.surface("platform_harvester",{ + raise=function(self) local f=self.host + f.solar_power_multiplier=settings.global.warptorio_solar_multiplier.value + f.daytime=0 + f.always_day=true + f.request_to_generate_chunks({0,0},16) + f.force_generate_chunk_requests() + f.destroy_decoratives({}) + for k,v in pairs(f.find_entities())do entity.destroy(v) end + local area=vector.area(vector(-32*8,-32*8),vector(32*8*2,32*8*2)) + vector.LayTiles("out-of-map",f,area) + -- size=16 + end, +}) + +cache.surface("platform_boiler",{ + raise=function(self) local f=self.host + f.solar_power_multiplier=settings.global.warptorio_solar_multiplier.value + f.daytime=0 + f.always_day=true + f.request_to_generate_chunks({0,0},16) + f.force_generate_chunk_requests() + f.destroy_decoratives({}) + for k,v in pairs(f.find_entities())do entity.destroy(v) end + local area=vector.area(vector(-32*8,-32*8),vector(32*8*2,32*8*2)) + vector.LayTiles("out-of-map",f,area) + -- size=16 + end, +}) + + + +--[[ General Platform Stuff ]]-- + +function platform.PositionInPlatform(f,pos) local gf=storage.floor + if(f==gf.factory.surface)then return true + elseif(f==gf.boiler.surface)then return true + elseif(f==gf.harvester.surface)then return true + end + -- Do overworld checks here + +end + +function platform.GetWarpables(c,cf) + -- warptorio.IsWarping=true + --local m=storage.floor.main + --local c=m.host + local mt=platform.floors.main.get_sizes() + + local marea=vector.square(vector.pos({-0.5,-0.5}),vector(mt.size,mt.size)) + + -- find entities and players to copy/transfer to new surface + local tpply={} local cx=platform.corn + local etbl={} + for k,v in pairs(c.find_entities_filtered{type={"car","character","player"},invert=true,area=marea})do + local biterwarp=(warptorio.setting("biter_warping")==false) + if(v.type=="spider-vehicle")then + --local drv=v.get_driver() if(isvalid(drv))then drv.driving=nil v.set_driver(nil) end + table.insert(etbl,v) + elseif(v.type=="item-entity" or v.type=="character-corpse" or v.last_user or v.force.name=="player" or (biterwarp and v.force.name=="enemy"))then + table.insert(etbl,v) + end + end + + -- find players to teleport to new platform + for k,v in pairs(game.players)do if(not v.driving)then if(v.character==nil or (v.surface==c and vector.inarea(v.position,marea)))then + table.insert(tpply,{v,vector.pos(v.position)}) + end end end + + -- find cars to teleport to new platform + for k,v in pairs(c.find_entities_filtered{type={"car","tank"},area=marea})do if((v.surface==c and vector.inarea(v.position,marea)))then + table.insert(tpply,{v,vector.pos(v.position)}) + end end + + -- find entities/players on the corners + for k,v in pairs({"nw","ne","sw","se"})do local ugName="turret-"..v local rHas=research.has("warptorio-"..ugName.."-0") if(rHas)then local ug=research.level("warptorio-"..ugName) + local etc=cf.find_entities_filtered{position={cx[v].x+0.5,cx[v].y+0.5},radius=math.floor(10+ug*6)/2} for a,e in pairs(etc)do e.destroy() end -- clean new platform corner + + local etp=c.find_entities_filtered{type="character",position={cx[v].x+0.5,cx[v].y+0.5},radius=(10+(ug*6))/2} -- find corner players + for a,e in pairs(etp)do if(e.player and e.player.character~=nil and not e.driving)then table.insert(tpply,{e.player,{e.position.x,e.position.y}}) end end + + local etp=c.find_entities_filtered{type={"car","tank"},position={cx[v].x+0.5,cx[v].y+0.5},radius=(10+(ug*6))/2} -- find corner cars + for a,e in pairs(etp)do table.insert(tpply,{e,{e.position.x,e.position.y}}) end + + local et=c.find_entities_filtered{type={"car","character","tank"},invert=true,position={cx[v].x+0.5,cx[v].y+0.5},radius=math.floor((10+ug*6)/2)-(1e-6)} -- find corner ents + for k,v in pairs(et)do if(v.last_user or v.force.name=="player" or (biterwarp and v.force.name=="enemy"))then + table.insertExclusive(etbl,v) + end end + + end end + + return etbl,tpply +end + + + + + + +return platform + + diff --git a/data-updates.lua b/data-updates.lua index db12ae3..83d3891 100644 --- a/data-updates.lua +++ b/data-updates.lua @@ -73,7 +73,7 @@ local entIgnore={ "big-electric-pole", } - +--[[ local s="" for u,n in pairs(entTbl)do for k,v in pairs(data.raw[n])do @@ -90,4 +90,4 @@ for u,n in pairs(entTbl)do end end --error(s) - +]]-- diff --git a/data.lua b/data.lua index e94781d..e3d20ce 100644 --- a/data.lua +++ b/data.lua @@ -1,21 +1,21 @@ require("lib/lib") -local reqpth="prototypes/" +local reqpth = "prototypes/" --require("technology/warp-technology") require("sound/sound") -require(reqpth.."data_warptorio-heatpipe") -require(reqpth.."data_warptorio-warpport") -require(reqpth.."data_warptorio-logistics-pipe") -require(reqpth.."data_warptorio-warpstation") -require(reqpth.."data_warpnuke") -require(reqpth.."data_warptorio-warploader") -require(reqpth.."data_warptorio-townportal") -require(reqpth.."data_warptorio-combinator") -require(reqpth.."data_warptorio-warpspider") +require(reqpth .. "data_warptorio-heatpipe") +require(reqpth .. "data_warptorio-warpport") +require(reqpth .. "data_warptorio-logistics-pipe") +require(reqpth .. "data_warptorio-warpstation") +require(reqpth .. "data_warpnuke") +require(reqpth .. "data_warptorio-warploader") +require(reqpth .. "data_warptorio-townportal") +require(reqpth .. "data_warptorio-combinator") +require(reqpth .. "data_warptorio-warpspider") --require("data_nauvis_preset") --require("data_accumulators") -- This would be included here if it weren't for factorioextended ruining the accumulator tables >:| require("data_warptorio") -lib.lua() \ No newline at end of file +lib.lua() diff --git a/data_warptorio.lua b/data_warptorio.lua index 0f531c1..c79e0c0 100644 --- a/data_warptorio.lua +++ b/data_warptorio.lua @@ -1,769 +1,1452 @@ - -local function istable(t) return type(t)=="table" end -local function rgb(r,g,b,a) a=a or 255 return {r=r/255,g=g/255,b=b/255,a=a/255} end - -function table.deepmerge(s,t) for k,v in pairs(t)do if(istable(v) and s[k] and istable(s[k]))then table.deepmerge(s[k],v) else s[k]=v end end end -function table.merge(s,t) local x={} for k,v in pairs(s)do x[k]=v end for k,v in pairs(t)do x[k]=v end return x end -local function MakeDataCopy(a,b,x) local t=table.deepcopy(data.raw[a][b]) if(x)then table.deepmerge(t,x) end return t end -local function ExtendRecipeItem(t) - local r=table.deepcopy(data.raw.recipe["nuclear-reactor"]) - r.enabled=false r.name=t.name r.ingredients={{"steel-plate",1}} r.result=t.name - local i=table.deepcopy(data.raw.item["nuclear-reactor"]) - i.name=t.name i.place_result=t.name - data:extend{i,r} -end -local function ExtendRecipeItemFix(t) t.order=t.order or "warptorio" end -local function ExtendDataCopy(a,b,x,ri,tx) local t=MakeDataCopy(a,b,x) if(tx)then for k,v in pairs(tx)do if(v==false)then t[k]=nil else t[k]=v end end end if(ri)then ExtendRecipeItemFix(t) end data:extend{t} return t end - -local function ExtendCopyRecipe(src,name) - local r=table.deepcopy( data.raw.recipe[src] ) - r.enabled=false r.name=name r.ingredients={{"steel-plate",1}} r.result=name - local i=table.deepcopy( data.raw.recipe[src] ) - i.name=name i.place_result=name - data:extend{i,r} -end - -local techPacks={red="automation-science-pack",green="logistic-science-pack",blue="chemical-science-pack",black="military-science-pack", - purple="production-science-pack",yellow="utility-science-pack",white="space-science-pack"} - -local function SciencePacks(x) local t={} for k,v in pairs(x)do table.insert(t,{techPacks[k],v}) end return t end -local function ExtendTech(t,d,s) local x=table.merge(t,d) if(s)then x.unit.ingredients=SciencePacks(s) end data:extend{x} return x end - ---[[ -local t=ExtendDataCopy("electric-pole","small-electric-pole",{name="warptorio-electric-pole", - pictures={layers={[1]={tint={r=0.6,g=0.6,b=1,a=1},hr_version={tint={r=0.6,g=0.6,b=1,a=1}} }, }}, -},true) -]] - - --- -------- --- vonNeumann compatability. It's base game stuff anyway. Perhaps expand on this later - --- data.raw.lab["crash-site-lab-repaired"].minable={mining_time=3,result="crash-site-lab-repaired"} --- data.raw.container["crash-site-chest-1"].minable={mining_time=3,result="crash-site-chest-1"} --- data.raw.container["crash-site-chest-2"].minable={mining_time=3,result="crash-site-chest-2"} --- data.raw["assembling-machine"]["crash-site-assembling-machine-1-repaired"].minable={mining_time=3,result="crash-site-assembling-machine-1-repaired"} --- data.raw["assembling-machine"]["crash-site-assembling-machine-2-repaired"].minable={mining_time=3,result="crash-site-assembling-machine-2-repaired"} - - - - - - --- -------- --- Warp Tiles - --- purple tiles -local t=ExtendDataCopy("tile","tutorial-grid",{name="warp-tile-concrete",tint={r=0.6,g=0.6,b=0.7,a=1},layer=99,decorative_removal_probability=1,walking_speed_modifier=1.6,map_color={r=0.2,g=0.1,b=0.25,a=1}}) - --- orange tiles -local t=ExtendDataCopy("tile","tutorial-grid",{name="warptorio-red-concrete",tint={r=1,g=0.5,b=0,a=0.25},layer=67,decorative_removal_probability=1,walking_speed_modifier=1.5,map_color={r=0.2,g=0.1,b=0,a=1}}) - --- -------- --- Invisiradar -local rtint={r=0.4,g=0.4,b=1,a=1} -local rvtint={scale=1/3,shift={0.03125/3,-0.5/3},tint={r=1,g=1,b=1,a=0},hr_version={scale=0.5/3,tint={r=1,g=1,b=1,a=0},shift={0.03125/3,-0.5/3}}} -local r=ExtendDataCopy("radar","radar",{name="warptorio-invisradar", - icons={{icon="__base__/graphics/icons/radar.png",tint=rtint}},integration_patch=rvtint,pictures={layers={rvtint,rvtint}}, -},true,{energy_per_nearby_scan="10kJ",energy_per_sector="200kJ",energy_usage="1kW", icon=false, - max_distance_of_nearby_sector_revealed=5,max_distance_of_sector_revealed=18, - collision_box={{-1.2/3,-1.2/3},{1.2/3,1.2/3}},selection_box={{-1.5/3,-1.5/3},{1.5/3,1.5/3}}, -}) - - --- -------- --- Loot Chest - -local rtint={r=0.4,g=0.4,b=1,a=1} -local t=ExtendDataCopy("container","wooden-chest",{name="warptorio-lootchest",inventory_size=8, - icons={{icon="__base__/graphics/icons/wooden-chest.png",tint=rtint}}, - picture={layers={ [1]={tint=rtint,hr_version={tint=rtint}}, }}, -},true,{icon=false,minable={mining_time=0.1}}) - - --- -------- --- Carebear Chest - -local rtint=rgb(255,20,147) -local t=ExtendDataCopy("container","wooden-chest",{name="warptorio-carebear-chest",inventory_size=99, - icons={{icon="__base__/graphics/icons/wooden-chest.png",tint=rtint}}, - picture={layers={ [1]={tint=rtint,hr_version={tint=rtint}}, }}, -},true,{icon=false,minable={mining_time=10}}) - - - --- ---- --- Logistics - ---[[ -local rtint={r=0.5,g=0.5,b=1,a=1} -local rtintpic={tint=rtint,hr_version={tint=rtint}} -local rctint={r=0.39,g=0,b=0,a=1} -local rtintcov={layers={ [1]={tint=rctint,hr_version={tint=rctint}} }} -local t=ExtendDataCopy("pipe-to-ground","pipe-to-ground",{name="warptorio-logistics-pipe",fluid_box={base_area=5,pipe_connections={[2]={max_underground_distance=-1}}}, - pictures={ left=rtintpic, right=rtintpic,up=rtintpic,down=rtintpic }, - pipe_covers={ east={layers={ [1]={tint=rctint,hr_version={tint=rctint}} }}, north=rtintcov, south=rtintcov, west=rtintcov,} -},true) -]] - --- -------- --- Warp Reactor - --- Fuel -data:extend{{type="fuel-category", name="warp"}} - -ExtendDataCopy("item","uranium-fuel-cell",{name="warptorio-warponium-fuel-cell",fuel_category="warp",burnt_result="uranium-fuel-cell",fuel_value="32GJ",stack_size=50, - icon_size=64,icons={ {icon="__base__/graphics/icons/uranium-fuel-cell.png",tint={r=1,g=0.2,b=1,a=0.8}}, }, },false,{icon=false}) - -ExtendDataCopy("recipe","uranium-fuel-cell",{name="warptorio-warponium-fuel-cell",enabled=false,result="warptorio-warponium-fuel-cell",result_count=1},false, - {ingredients={{"uranium-fuel-cell",5}}, - icon_size=64,icons={ {icon="__base__/graphics/icons/uranium-fuel-cell.png",tint={r=1,g=0.2,b=1,a=0.8}}, }, -},false,{icon=false}) - -ExtendDataCopy("item","nuclear-fuel",{name="warptorio-warponium-fuel",fuel_category="chemical", - fuel_acceleration_multiplier=5,fuel_value="7GJ",stack_size=1,fuel_top_speed_multiplier=1.25, - icon_size=64,icons={ {icon="__base__/graphics/icons/nuclear-fuel.png",tint={r=1,g=0.2,b=1,a=0.8}}, }, -},false,{icon=false}) - -ExtendDataCopy("recipe","nuclear-fuel",{name="warptorio-warponium-fuel",enabled=false,result="warptorio-warponium-fuel",result_count=1},false, - {ingredients={{"warptorio-warponium-fuel-cell",1},{"nuclear-fuel",1}}, - icon=false,icon_size=64,icons={ {icon="__base__/graphics/icons/nuclear-fuel.png",tint={r=1,g=0.2,b=1,a=0.8}}, }, -}) - - --- The Reactor Itself -local t=ExtendDataCopy("reactor","nuclear-reactor",{name="warptorio-reactor",max_health=5000,neighbour_bonus=12,consumption="160MW", - energy_source={fuel_category="warp"},heat_buffer={specific_heat="1MJ",max_temperature=1000}, light={ intensity=10, size=9.9, shift={0.0,0.0}, color={r=1.0,g=0.0,b=0.0} }, - working_light_picture={ filename="__base__/graphics/entity/nuclear-reactor/reactor-lights-color.png", tint={r=1,g=0.4,b=0.4,a=1}, - hr_version={ filename="__base__/graphics/entity/nuclear-reactor/hr-reactor-lights-color.png", tint={r=1,g=0.4,b=0.4,a=1}, }, - }, - picture={layers={ - [1]={ tint={r=0.8,g=0.8,b=1,a=1}, hr_version={ tint={r=0.8,g=0.8,b=1,a=1}, }, }, - }}, -},true) - - - - --- ------------------------------------------------------------------------- --- Technologies - - --- ---- --- Warp Roboport - -local t={type="technology",upgrade=true,icon_size=128,effects={{recipe="warptorio-warpport",type="unlock-recipe"}},icons={ - {icon="__base__/graphics/entity/roboport/roboport-base.png",tint={r=0.3,g=0.3,b=1,a=1},scale=0.75,priority="low",}, -}, } -ExtendTech(t,{name="warptorio-warpport",unit={count=1000,time=5}, prerequisites={"warptorio-logistics-4","warptorio-reactor-8","space-science-pack"}}, {red=1,green=1,black=1,blue=1,purple=1,yellow=1,white=1}) - - --- ---- --- Warp Nuke - -local t={type="technology",upgrade=true,icon_size=128,icons={ - {icon="__base__/graphics/technology/atomic-bomb.png",tint={r=0.3,g=0.3,b=1,a=1},priority="low",icon_mipmaps=4,icon_size=256,}, -}, } -ExtendTech(t,{name="warptorio-warpnuke",unit={count=1000,time=5},effects={{recipe="warptorio-atomic-bomb",type="unlock-recipe"}}, - prerequisites={"atomic-bomb","warptorio-reactor-8","space-science-pack"}}, {red=1,green=1,black=1,blue=1,purple=1,yellow=1,white=1}) - - --- ---- --- Warp Module - -local t={type="technology",upgrade=true,icon_size=128,icons={ - {icon="__base__/graphics/technology/module.png",tint={r=0.3,g=0.3,b=1,a=1},priority="low",icon_mipmaps=4,icon_size=256,}, -}, } -ExtendTech(t,{name="warptorio-warpmodule",unit={count=3000,time=5}, prerequisites={"warptorio-reactor-8","space-science-pack","effectivity-module-3"}, - effects={{recipe="warptorio-warpmodule",type="unlock-recipe"}},}, {red=1,green=1,black=1,blue=1,purple=1,yellow=1,white=1}) - -data:extend{{type="module-category",name="warpivity"}} -local t={type="module",category="warpivity",name="warptorio-warpmodule",stack_size=50,subgroup="module",tier=4,localised_description={"item-description.warptorio-warpmodule"}, - limitation_message_key = "production-module-usable-only-on-intermediates", - effect={ consumption={bonus=0.6},pollution={bonus=0.05},productivity={bonus=0.1},speed={bonus=0.35} }, - icon_size=64,icons={ {icon="__base__/graphics/icons/speed-module-3.png",tint={r=0.2,g=0.2,b=1,a=1}} }, -} -data:extend{t} - -data:extend{{type="recipe",result="warptorio-warpmodule",name="warptorio-warpmodule",enabled=false,energy_required=60, - ingredients={{"speed-module-3",50},{"productivity-module-3",50},{"effectivity-module-3",50},{"advanced-circuit",200},{"processing-unit",200},{"low-density-structure",10}}, -}} - - --- ---- --- Warp Reactor - -local t={type="technology",upgrade=true,icon_size=128,icons={ - {icon="__base__/graphics/technology/nuclear-power.png",tint={r=0.3,g=0.3,b=1,a=1},priority="low",icon_mipmaps=4,icon_size=256,}, - {icon="__base__/graphics/technology/engine.png",tint={r=0.7,g=0.7,b=1,a=1},scale=0.5,shift={32,32},priority="high",icon_mipmaps=4,icon_size=256,}, -}, } -ExtendTech(t,{name="warptorio-reactor-1",unit={count=50,time=5}, prerequisites={}}, {red=1}) - -local t={type="technology",upgrade=true,icon_size=128,icons={ - {icon="__base__/graphics/technology/nuclear-power.png",tint={r=0.3,g=0.3,b=1,a=1},priority="low",icon_mipmaps=4,icon_size=256,}, - {icon="__base__/graphics/technology/electronics.png",tint={r=0.7,g=0.7,b=1,a=1},scale=0.5,shift={32,32},priority="high",icon_mipmaps=4,icon_size=256,} -}, } -ExtendTech(t,{name="warptorio-reactor-2",unit={count=50,time=5}, prerequisites={"warptorio-reactor-1","logistic-science-pack"}}, {red=1,green=1}) - -local t={type="technology",upgrade=true,icon_size=128,icons={ - {icon="__base__/graphics/technology/nuclear-power.png",tint={r=0.3,g=0.3,b=1,a=1},priority="low",icon_mipmaps=4,icon_size=256,}, - {icon="__base__/graphics/technology/advanced-electronics.png",tint={r=0.7,g=0.7,b=1,a=1},scale=0.5,shift={32,32},priority="high",icon_mipmaps=4,icon_size=256,} -}, } -ExtendTech(t,{name="warptorio-reactor-3",unit={count=50,time=5}, prerequisites={"warptorio-reactor-2","military-science-pack"}}, {red=1,green=2,black=1}) - -local t={type="technology",upgrade=true,icon_size=128,icons={ - {icon="__base__/graphics/technology/nuclear-power.png",tint={r=0.3,g=0.3,b=1,a=1},priority="low",icon_mipmaps=4,icon_size=256,}, - {icon="__base__/graphics/technology/advanced-electronics-2.png",tint={r=0.7,g=0.7,b=1,a=1},scale=0.5,shift={32,32},priority="high",icon_mipmaps=4,icon_size=256,} -}, } -ExtendTech(t,{name="warptorio-reactor-4",unit={count=50,time=5}, prerequisites={"warptorio-reactor-3","rocketry"}}, {red=2,green=2,black=1,}) - -local t={type="technology",upgrade=true,icon_size=128,icons={ - {icon="__base__/graphics/technology/nuclear-power.png",tint={r=0.3,g=0.3,b=1,a=1},priority="low",icon_mipmaps=4,icon_size=256,}, - {icon="__base__/graphics/technology/explosives.png",tint={r=0.7,g=0.7,b=1,a=1},scale=0.5,shift={32,32},priority="high",icon_mipmaps=4,icon_size=256,} -}, } -ExtendTech(t,{name="warptorio-reactor-5",unit={count=50,time=5}, prerequisites={"warptorio-reactor-4","chemical-science-pack"}}, {red=1,green=3,black=1,blue=1}) - -local t={type="technology",upgrade=true,icon_size=128,icons={ - {icon="__base__/graphics/technology/nuclear-power.png",tint={r=0.3,g=0.3,b=1,a=1},priority="low",icon_mipmaps=4,icon_size=256,}, - {icon="__base__/graphics/technology/atomic-bomb.png",tint={r=0.7,g=0.7,b=1,a=1},scale=0.5,shift={32,32},priority="high",icon_mipmaps=4,icon_size=256,} -}, localised_description={"technology-description.warptorio-reactor-6"} } -ExtendTech(t,{name="warptorio-reactor-6",unit={count=100,time=90}, effects={{recipe="warptorio-townportal",type="unlock-recipe"}},prerequisites={"warptorio-reactor-5","uranium-processing","robotics"}}, {red=5,black=5}) -- reactor module - -local t={type="technology",upgrade=true,icon_size=128,icons={ - {icon="__base__/graphics/technology/nuclear-power.png",tint={r=0.3,g=0.3,b=1,a=1},priority="low",icon_mipmaps=4,icon_size=256,}, - {icon="__base__/graphics/technology/kovarex-enrichment-process.png",tint={r=0.7,g=0.7,b=1,a=1},scale=0.5,shift={32,32},priority="high",icon_mipmaps=4,icon_size=256,} -}, } -ExtendTech(t,{name="warptorio-reactor-7",unit={count=1000,time=30}, effects={{recipe="warptorio-heatpipe",type="unlock-recipe"},{recipe="warptorio-warponium-fuel-cell",type="unlock-recipe"}}, prerequisites={"nuclear-power","warptorio-reactor-6"}}, {red=1,green=1,black=1,blue=1}) - -local t={type="technology",upgrade=true,icon_size=128,icons={ - {icon="__base__/graphics/technology/nuclear-power.png",tint={r=0.3,g=0.3,b=1,a=1},priority="low",icon_mipmaps=4,icon_size=256,}, - {icon="__warptorio2__/graphics/technology/earth.png",tint={r=0.8,g=0.8,b=1,a=1},scale=0.5,shift={32,32},priority="high"} -}, localised_description={"technology-description.warptorio-reactor-8"} } -ExtendTech(t,{name="warptorio-reactor-8",unit={count=1000,time=30}, prerequisites={"warptorio-reactor-7","warptorio-charting","warptorio-accelerator","warptorio-stabilizer","warptorio-kovarex","rocket-control-unit"}}, {red=1,green=1,black=1,blue=1,purple=1,yellow=1}) -- steering - - - --- ---- --- Reactor Abilities - -local t={type="technology",upgrade=false,icon_size=128,icons={ - {icon="__base__/graphics/technology/battery.png",tint={r=0.3,g=0.3,b=1,a=1},priority="low",icon_mipmaps=4,icon_size=256,}, -}, } -ExtendTech(t,{name="warptorio-stabilizer",unit={count=400,time=30}, prerequisites={"warptorio-reactor-6","military-3","circuit-network"}}, {red=1,green=1,black=1,blue=1}) -- stabilizer - -local t={type="technology",upgrade=false,icon_size=128,icons={ {icon="__base__/graphics/technology/nuclear-power.png",tint={r=0.3,g=0.3,b=1,a=1},priority="low",icon_mipmaps=4,icon_size=256,} }, } -t.icons={ {icon="__base__/graphics/technology/engine.png",tint={r=0.3,g=0.3,b=1,a=1},icon_mipmaps=4,icon_size=256,} } -ExtendTech(t,{name="warptorio-accelerator",unit={count=400,time=30}, prerequisites={"warptorio-reactor-6","military-3","circuit-network"}}, {red=1,green=1,black=1,blue=1}) -- accelerator - -local t={type="technology",upgrade=false,icon_size=128,icons={ {icon="__base__/graphics/technology/nuclear-power.png",tint={r=0.3,g=0.3,b=1,a=1},priority="low",icon_mipmaps=4,icon_size=256,} }, } -t.icons={ {icon="__base__/graphics/technology/radar.png",tint={r=0.3,g=0.3,b=1,a=1},icon_mipmaps=4,icon_size=256,} } -ExtendTech(t,{name="warptorio-charting",unit={count=400,time=30}, prerequisites={"warptorio-reactor-6","military-3","circuit-network"}}, {red=1,green=1,black=1,blue=1}) -- charting - - -local t={type="technology",upgrade=true,icon_size=128,icons={ - {icon="__warptorio2__/graphics/technology/earth.png",tint={r=0.8,g=0.8,b=1,a=1},priority="low"} -}, } -ExtendTech(t,{name="warptorio-homeworld",unit={count=5000,time=30}, effects={{recipe="warptorio-homeportal",type="unlock-recipe"}}, prerequisites={"warptorio-reactor-8","space-science-pack"}}, {red=1,green=1,black=1,blue=1,purple=1,yellow=1,white=1}) - - --- ---- --- Warponium Fuel - -local t={type="technology",upgrade=true,icon_size=128,icons={ - {icon="__base__/graphics/technology/nuclear-power.png",tint={r=0.3,g=0.3,b=1,a=1},priority="low",icon_mipmaps=4,icon_size=256,}, - {icon="__base__/graphics/technology/rocket-fuel.png",tint={r=0.7,g=0.7,b=1,a=1},scale=0.5,shift={32,32},priority="high",icon_mipmaps=4,icon_size=256,}, - }, - effects={{recipe="warptorio-warponium-fuel",type="unlock-recipe"}}, -} -ExtendTech(t,{name="warptorio-kovarex",unit={count=1000,time=15}, prerequisites={"warptorio-reactor-7","kovarex-enrichment-process"}}, {red=1,green=1,black=1,blue=1,purple=1}) -- Kovarex - - --- ---- --- Boiler Warp Substation - -local t={type="technology",upgrade=false,icon_size=128,icons={ - {icon="__base__/graphics/technology/electric-energy-distribution-1.png",tint={r=0.3,g=0.3,b=1,a=1},priority="low",icon_mipmaps=4,icon_size=256,}, - {icon="__base__/graphics/technology/fluid-handling.png",tint={r=0.7,g=0.7,b=1,a=1},scale=0.5,shift={32,32},priority="high",icon_mipmaps=4,icon_size=256,}, -}, } -ExtendTech(t,{name="warptorio-boiler-station",unit={count=500,time=10}, prerequisites={"electric-energy-distribution-2","warptorio-boiler-0","production-science-pack"}}, {red=1,blue=1,green=1,purple=1}) - - --- ---- --- Warp Energy Pipe - -local rtint={tint={r=0.3,g=0.3,b=1,a=1},hr_version={tint={r=0.3,g=0.3,b=1,a=1}}} - ---[[ -local pipe_sprites={corner_left_down={{rtint},{rtint},{rtint},{rtint},{rtint}},corner_left_up={{rtint},{rtint},{rtint},{rtint},{rtint},{rtint}}, - corner_right_down={{rtint},{rtint},{rtint},{rtint},{rtint},{rtint}},corner_right_up={{rtint},{rtint},{rtint},{rtint},{rtint},{rtint}}, - cross={{rtint}},ending_down={{rtint}},ending_left={{rtint}},ending_right={{rtint}},ending_up={{rtint}},single={{rtint}}, - straight_horizontal={{rtint},{rtint},{rtint},{rtint},{rtint},{rtint}},straight_vertical={{rtint},{rtint},{rtint},{rtint},{rtint},{rtint}}, - t_down={{rtint}},t_left={{rtint}},t_right={{rtint}},t_up={{rtint}},} - -local t=ExtendDataCopy("heat-pipe","heat-pipe",{name="warptorio-heatpipe",connection_sprites=pipe_sprites,heat_glow_sprites=pipe_sprites, - max_temperature=5000, - max_transfer="5GW", - specific_heat="1MJ", - icon_size=64,icons={ {icon="__base__/graphics/icons/heat-pipe.png",tint={r=0.3,g=0.3,b=1,a=1},hr_version={tint={r=0.3,g=0.3,b=1,a=1}} } } -})]] - -local pipe_icon={ {icon="__base__/graphics/icons/heat-pipe.png",tint={r=0.3,g=0.3,b=1,a=1},hr_version={tint={r=0.3,g=0.3,b=1,a=1},icon_mipmaps=4,icon_size=256,} } } -local t=ExtendDataCopy("recipe","heat-pipe",{name="warptorio-heatpipe",result="warptorio-heatpipe",ingredients={{"processing-unit",200},{"heat-pipe",50}}, enabled=false,energy_required=30, }) -local t=ExtendDataCopy("item","heat-pipe",{name="warptorio-heatpipe",place_result="warptorio-heatpipe", - icon_size=64,icons=pipe_icon, -}) - --- ---- --- Sandbox Boosts - -local t={type="technology",upgrade=true,icon_size=128,icons={ {icon="__base__/graphics/technology/mining-productivity.png",tint={r=0.3,g=0.3,b=1,a=1},icon_mipmaps=4,icon_size=256,} }, - effects={ {type="mining-drill-productivity-bonus",modifier=0.1}}, } -ExtendTech(t,{name="warptorio-mining-prod-1",unit={count_formula="20*L",time=30},max_level=5}, {red=1}) -ExtendTech(t,{name="warptorio-mining-prod-6",unit={count_formula="(20*L)-50",time=30},max_level=10,prerequisites={"warptorio-mining-prod-1","logistic-science-pack"}}, {red=2,green=1}) -ExtendTech(t,{name="warptorio-mining-prod-11",unit={count_formula="(20*L)-100",time=30},max_level=15,prerequisites={"warptorio-mining-prod-6","chemical-science-pack"}}, {red=2,green=2,blue=1} ) -ExtendTech(t,{name="warptorio-mining-prod-16",unit={count_formula="(20*L)-150",time=30},max_level=20,prerequisites={"warptorio-mining-prod-11","production-science-pack"}}, {red=3,green=3,blue=1,purple=1} ) -ExtendTech(t,{name="warptorio-mining-prod-21",unit={count_formula="(20*L)-200",time=30},max_level=25,prerequisites={"warptorio-mining-prod-16","utility-science-pack"}}, {red=3,green=3,blue=2,purple=1,yellow=1} ) - -local t={type="technology",upgrade=true,icon_size=64,icons={ {icon="__base__/graphics/icons/steel-axe.png",tint={r=0.3,g=0.3,b=1,a=1},} }, - effects={ {type="character-mining-speed",modifier=0.5}}, } -ExtendTech(t,{name="warptorio-axe-speed-1",unit={count_formula="50*L",time=30},prerequisites={"steel-axe","warptorio-reactor-1"},max_level=2}, {red=1}) -ExtendTech(t,{name="warptorio-axe-speed-3",unit={count_formula="(50*L)",time=30},max_level=4,prerequisites={"warptorio-axe-speed-1","logistic-science-pack"}}, {red=1,green=1}) -ExtendTech(t,{name="warptorio-axe-speed-5",unit={count_formula="(50*L)",time=30},max_level=6,prerequisites={"warptorio-axe-speed-3","chemical-science-pack"}}, {red=1,green=1,blue=1} ) -ExtendTech(t,{name="warptorio-axe-speed-7",unit={count_formula="(50*L)",time=30},max_level=8,prerequisites={"warptorio-axe-speed-5","production-science-pack"}}, {red=1,green=1,blue=1,purple=1} ) -ExtendTech(t,{name="warptorio-axe-speed-9",unit={count_formula="(50*L)",time=30},max_level=10,prerequisites={"warptorio-axe-speed-7","utility-science-pack"}}, {red=1,green=1,blue=1,purple=1,yellow=1} ) - -local t={type="technology",upgrade=true,icon_size=128,icons={ {icon="__base__/graphics/technology/inserter-capacity.png",tint={r=0.3,g=0.3,b=1,a=1},icon_mipmaps=4,icon_size=256,} }, - effects={ {type="stack-inserter-capacity-bonus",modifier=1}, {type="inserter-stack-size-bonus",modifier=1},} } -ExtendTech(t,{name="warptorio-inserter-cap-1",unit={count=150,time=30},prerequisites={"warptorio-reactor-1","fast-inserter"},}, {red=1}) -ExtendTech(t,{name="warptorio-inserter-cap-2",unit={count=200,time=30},prerequisites={"warptorio-inserter-cap-1","logistic-science-pack"}}, {red=2,green=1}) -ExtendTech(t,{name="warptorio-inserter-cap-3",unit={count=250,time=30},prerequisites={"warptorio-inserter-cap-2","chemical-science-pack"}}, {red=3,green=2,blue=1} ) -ExtendTech(t,{name="warptorio-inserter-cap-4",unit={count=300,time=30},prerequisites={"warptorio-inserter-cap-3","production-science-pack"}}, {red=4,green=3,blue=2,purple=1} ) -ExtendTech(t,{name="warptorio-inserter-cap-5",unit={count=350,time=30},prerequisites={"warptorio-inserter-cap-4","utility-science-pack"}}, {red=5,green=4,blue=3,purple=2,yellow=1} ) - - -local t={type="technology",upgrade=true,icon_size=128,icons={ {icon="__base__/graphics/technology/worker-robots-speed.png",tint={r=0.3,g=0.3,b=1,a=1},icon_mipmaps=4,icon_size=256,} }, - effects={ {type="worker-robot-speed",modifier=0.35},} } -ExtendTech(t,{name="warptorio-bot-speed-1",unit={count=120,time=30},prerequisites={"robotics","warptorio-reactor-2"}}, {red=1,green=1}) -ExtendTech(t,{name="warptorio-bot-speed-2",unit={count=180,time=30},prerequisites={"warptorio-bot-speed-1","logistic-robotics"}}, {red=2,green=1}) -ExtendTech(t,{name="warptorio-bot-speed-3",unit={count=250,time=30},prerequisites={"warptorio-bot-speed-2","chemical-science-pack"}}, {red=3,green=2,blue=1} ) -ExtendTech(t,{name="warptorio-bot-speed-4",unit={count=300,time=30},prerequisites={"warptorio-bot-speed-3","production-science-pack"}}, {red=4,green=3,blue=2,purple=1} ) -ExtendTech(t,{name="warptorio-bot-speed-5",unit={count=350,time=30},prerequisites={"warptorio-bot-speed-4","utility-science-pack"}}, {red=5,green=4,blue=3,purple=2,yellow=1} ) - -local t={type="technology",upgrade=true,icon_size=128,icons={ {icon="__base__/graphics/technology/worker-robots-storage.png",tint={r=0.3,g=0.3,b=1,a=1},icon_mipmaps=4,icon_size=256,} }, - effects={ {type="worker-robot-storage",modifier=1}, } } -ExtendTech(t,{name="warptorio-bot-cap-1",unit={count=120,time=30},prerequisites={"robotics","warptorio-reactor-2"}}, {red=1,green=1}) -ExtendTech(t,{name="warptorio-bot-cap-2",unit={count=180,time=30},prerequisites={"warptorio-bot-cap-1","construction-robotics"}}, {red=2,green=1}) -ExtendTech(t,{name="warptorio-bot-cap-3",unit={count=250,time=30},prerequisites={"warptorio-bot-cap-2","chemical-science-pack"}}, {red=2,green=2,blue=1} ) -ExtendTech(t,{name="warptorio-bot-cap-4",unit={count=300,time=30},prerequisites={"warptorio-bot-cap-3","production-science-pack"}}, {red=3,green=3,blue=1,purple=1} ) -ExtendTech(t,{name="warptorio-bot-cap-5",unit={count=350,time=30},prerequisites={"warptorio-bot-cap-4","utility-science-pack"}}, {red=3,green=3,blue=2,purple=1,yellow=1} ) - - -local t={type="technology",upgrade=true,icon_size=128,icons={ {icon="__base__/graphics/technology/physical-projectile-damage-1.png",tint={r=0.3,g=0.3,b=1,a=1},icon_mipmaps=4,icon_size=256,} }, - effects={ {type="turret-attack",modifier=0.15,turret_id="gun-turret"},{ammo_category="bullet",modifier=0.15,type="ammo-damage"},{ammo_category="shotgun-shell",modifier=0.2,type="ammo-damage"} } } -ExtendTech(t,{name="warptorio-physdmg-1",unit={count=250,time=30},prerequisites={"warptorio-reactor-1","physical-projectile-damage-1"}}, {red=1}) -ExtendTech(t,{name="warptorio-physdmg-2",unit={count=250,time=30},prerequisites={"warptorio-reactor-2","warptorio-physdmg-1","physical-projectile-damage-2"}}, {red=2,green=1} ) -ExtendTech(t,{name="warptorio-physdmg-3",unit={count=350,time=30},prerequisites={"warptorio-reactor-3","warptorio-physdmg-2","physical-projectile-damage-3"}}, {red=3,green=2,black=1} ) - -local t={type="technology",upgrade=true,icon_size=128,icons={ {icon="__base__/graphics/technology/toolbelt.png",tint={r=0.3,g=0.3,b=1,a=1},icon_mipmaps=4,icon_size=256,} }, - effects={ {type="character-inventory-slots-bonus",modifier=10} }, } -ExtendTech(t,{name="warptorio-toolbelt-1",unit={count=70,time=30},prerequisites={"warptorio-reactor-1"}}, {red=1}) -ExtendTech(t,{name="warptorio-toolbelt-2",unit={count=120,time=30},prerequisites={"warptorio-toolbelt-1","toolbelt","logistic-science-pack"}}, {red=2,green=1}) -ExtendTech(t,{name="warptorio-toolbelt-3",unit={count=150,time=30},prerequisites={"warptorio-toolbelt-2","chemical-science-pack"}}, {red=2,green=2,blue=1} ) -ExtendTech(t,{name="warptorio-toolbelt-4",unit={count=180,time=30},prerequisites={"warptorio-toolbelt-3","production-science-pack"}}, {red=3,green=2,blue=2,purple=1} ) -ExtendTech(t,{name="warptorio-toolbelt-5",unit={count=200,time=30},prerequisites={"warptorio-toolbelt-4","utility-science-pack"}}, {red=4,green=3,blue=2,purple=2,yellow=1} ) - -local t={type="technology",upgrade=true,icons={ - {icon="__warptorio2__/graphics/technology/earth.png",tint={r=0.7,g=0.7,b=1,a=1},shift={0,0},scale=0.375,priority="medium",icon_size=128}, - {icon="__base__/graphics/icons/steel-axe.png",tint={r=0.3,g=0.3,b=1,a=1},priority="low",icon_size=64,scale=0.5}, - }, - effects={ - {type="character-reach-distance",modifier=1}, - {type="character-build-distance",modifier=1}, - {type="character-item-drop-distance",modifier=1}, - {type="character-resource-reach-distance",modifier=1}, - }, -} -ExtendTech(t,{name="warptorio-reach-1",unit={count=50,time=30},prerequisites={"warptorio-reactor-1"}}, {red=1}) -ExtendTech(t,{name="warptorio-reach-2",unit={count=100,time=30},prerequisites={"warptorio-reach-1","logistic-science-pack"}}, {red=2,green=1}) -ExtendTech(t,{name="warptorio-reach-3",unit={count=150,time=30},prerequisites={"warptorio-reach-2","chemical-science-pack"}}, {red=2,green=2,blue=1} ) -ExtendTech(t,{name="warptorio-reach-4",unit={count=180,time=30},prerequisites={"warptorio-reach-3","production-science-pack"}}, {red=3,green=2,blue=2,purple=1} ) -ExtendTech(t,{name="warptorio-reach-5",unit={count=200,time=30},prerequisites={"warptorio-reach-4","utility-science-pack"}}, {red=4,green=3,blue=2,purple=2,yellow=1} ) - - -local t={type="technology",upgrade=true,icon_size=128,icons={ - {icon="__base__/graphics/technology/exoskeleton-equipment.png",tint={r=0.3,g=0.3,b=1,a=1},icon_mipmaps=4,icon_size=256,}, -}, effects={ - {type="character-running-speed",modifier=0.1}, -}, } -ExtendTech(t,{name="warptorio-striders-1",unit={count=150,time=20}, prerequisites={"warptorio-reactor-1"},upgrade=false}, {red=1}) -ExtendTech(t,{name="warptorio-striders-2",unit={count=300,time=20}, prerequisites={"warptorio-reactor-2","modular-armor","warptorio-striders-1"},upgrade=false}, {red=1,green=1}) - - - --- ---- --- Platform Size - -local t={type="technology",upgrade=true,icon_size=128,icons={ {icon="__base__/graphics/technology/concrete.png",tint={r=0.3,g=0.3,b=1,a=1},icon_mipmaps=4,icon_size=256,} }, } -ExtendTech(t,{name="warptorio-platform-size-1", unit={count=70,time=20}, prerequisites={}}, {red=1} ) -ExtendTech(t,{name="warptorio-platform-size-2", unit={count=120,time=20}, prerequisites={"warptorio-platform-size-1","warptorio-reactor-1"}}, {red=1} ) -ExtendTech(t,{name="warptorio-platform-size-3", unit={count=150,time=40}, prerequisites={"warptorio-platform-size-2","logistic-science-pack"}}, {red=1,green=1} ) -ExtendTech(t,{name="warptorio-platform-size-4", unit={count=250,time=30}, prerequisites={"concrete","warptorio-platform-size-3"}}, {red=1,green=1} ) -ExtendTech(t,{name="warptorio-platform-size-5", unit={count=120,time=30}, prerequisites={"chemical-science-pack","warptorio-platform-size-4"}}, {red=2,green=2,blue=1} ) -ExtendTech(t,{name="warptorio-platform-size-6", unit={count=150,time=30}, prerequisites={"warptorio-platform-size-5","solar-energy","production-science-pack"}}, {red=2,green=2,blue=1,purple=1} ) -ExtendTech(t,{name="warptorio-platform-size-7", unit={count=150,time=30}, prerequisites={"warptorio-platform-size-6","utility-science-pack"}}, {red=2,green=2,blue=1,purple=1,yellow=1} ) - - --- ---- --- Train Stops - - -for v,w in pairs({nw={-38,-38},ne={38,-38},se={38,38},sw={-38,38}})do -local t={type="technology",upgrade=false,icon_size=128,icons={ - {icon="__base__/graphics/technology/railway.png",tint={r=0.3,g=0.3,b=1,a=1},priority="low",icon_mipmaps=4,icon_size=256,}, - {icon="__base__/graphics/technology/railway.png",tint={r=0.7,g=0.7,b=1,a=0.9},shift={w[1],w[2]},scale=0.45,priority="high",icon_mipmaps=4,icon_size=256,}, -}, } - -ExtendTech(t,{name="warptorio-rail-"..v, unit={count=500,time=40}, prerequisites={"railway","warptorio-platform-size-6","warptorio-factory-7"}}, {red=1,green=1,black=1,blue=1,purple=1,yellow=1} ) -end - - --- ---- --- Castle Ramps - - -for v,w in pairs({nw={-38,-38},ne={38,-38},se={38,38},sw={-38,38}})do -local t={type="technology",upgrade=true,icon_size=128,icons={ - {icon="__base__/graphics/technology/stone-wall.png",tint={r=0.3,g=0.3,b=1,a=1},priority="low",icon_mipmaps=4,icon_size=256,}, - {icon="__base__/graphics/technology/stone-wall.png",tint={r=0.7,g=0.7,b=1,a=0.9},shift={w[1],w[2]},scale=0.45,priority="high",icon_mipmaps=4,icon_size=256,}, -}, } -ExtendTech(t,{name="warptorio-turret-"..v.."-0",upgrade=false, unit={count=100,time=40}, prerequisites={"gate","warptorio-factory-0"}}, {red=1,green=1} ) -ExtendTech(t,{name="warptorio-turret-"..v.."-1", unit={count=150,time=40}, prerequisites={"warptorio-turret-"..v.."-0","military-science-pack",}}, {red=2,green=1,black=1,} ) -ExtendTech(t,{name="warptorio-turret-"..v.."-2", unit={count=200,time=30}, prerequisites={"warptorio-turret-"..v.."-1","chemical-science-pack"}}, {red=2,green=1,black=1,blue=1} ) -ExtendTech(t,{name="warptorio-turret-"..v.."-3", unit={count=300,time=40}, prerequisites={"warptorio-turret-"..v.."-2","production-science-pack"}}, {red=2,green=2,black=1,blue=1,purple=1} ) -end - -local t={type="technology",upgrade=true,icon_size=128,icons={ - {icon="__base__/graphics/technology/stone-wall.png",tint={r=0.3,g=0.3,b=1,a=1},priority="low",icon_mipmaps=4,icon_size=256,}, - {icon="__base__/graphics/technology/stone-wall.png",tint={r=0.7,g=0.7,b=1,a=0.9},shift={38,38},scale=0.45,priority="high",icon_mipmaps=4,icon_size=256,}, - {icon="__base__/graphics/technology/stone-wall.png",tint={r=0.7,g=0.7,b=1,a=0.9},shift={-38,-38},scale=0.45,priority="high",icon_mipmaps=4,icon_size=256,}, - {icon="__base__/graphics/technology/stone-wall.png",tint={r=0.7,g=0.7,b=1,a=0.9},shift={-38,38},scale=0.45,priority="high",icon_mipmaps=4,icon_size=256,}, - {icon="__base__/graphics/technology/stone-wall.png",tint={r=0.7,g=0.7,b=1,a=0.9},shift={38,-38},scale=0.45,priority="high",icon_mipmaps=4,icon_size=256,}, -}, } -ExtendTech(t,{name="warptorio-bridgesize-1",unit={count=500,time=40},prerequisites={"warptorio-turret-nw-0","warptorio-turret-ne-0","warptorio-turret-se-0","warptorio-turret-sw-0"}, - unit={count=200,time=40}},{red=1,green=1,black=1}) -ExtendTech(t,{name="warptorio-bridgesize-2",unit={count=500,time=40},prerequisites={"warptorio-bridgesize-1","warptorio-turret-nw-1","warptorio-turret-ne-1","warptorio-turret-se-1","warptorio-turret-sw-1","low-density-structure"}, - unit={count=400,time=40}},{red=1,green=1,black=1,blue=1}) - --- ---- --- Factory Floor Upgrades - -local t={type="technology",upgrade=true,icon_size=128,icons={ - {icon="__base__/graphics/technology/automation-1.png",tint={r=0.3,g=0.3,b=1,a=1},icon_mipmaps=4,icon_size=256,} -}, } -ExtendTech(t,{name="warptorio-factory-0",unit={count=80,time=20}, prerequisites={"automation","warptorio-platform-size-1"}, upgrade=false, - localised_name={"technology-name.warptorio-factory"}, - localised_description={"technology-description.warptorio-factory-floor"}, -},{red=1}) - -local t={type="technology",upgrade=true,icon_size=128,icons={ - {icon="__base__/graphics/technology/automation-1.png",tint={r=0.3,g=0.3,b=1,a=1},icon_mipmaps=4,icon_size=256,}, - {icon="__base__/graphics/technology/concrete.png",tint={r=0.7,g=0.7,b=1,a=0.9},priority="medium",shift={32,32},scale=0.5,icon_mipmaps=4,icon_size=256,}, -}, } -ExtendTech(t,{name="warptorio-factory-1",unit={count=120,time=20}, prerequisites={"warptorio-factory-0","steel-processing"}}, {red=1}) -ExtendTech(t,{name="warptorio-factory-2",unit={count=150,time=15}, prerequisites={"electric-energy-distribution-1","advanced-material-processing","automation-2","warptorio-factory-1"}}, {red=1,green=1}) -ExtendTech(t,{name="warptorio-factory-3",unit={count=180,time=20}, prerequisites={"warptorio-factory-2","sulfur-processing"}}, {red=2,green=2}) -ExtendTech(t,{name="warptorio-factory-4",unit={count=220,time=25}, prerequisites={"warptorio-factory-3","chemical-science-pack","modules"}}, {red=2,green=2,blue=1}) -ExtendTech(t,{name="warptorio-factory-5",unit={count=250,time=20}, prerequisites={"warptorio-factory-4","advanced-material-processing-2"}}, {red=2,green=2,blue=1}) -ExtendTech(t,{name="warptorio-factory-6",unit={count=300,time=20}, prerequisites={"warptorio-factory-5","automation-3"}}, {red=2,green=2,blue=1,purple=1}) -ExtendTech(t,{name="warptorio-factory-7",unit={count=350,time=20}, prerequisites={"warptorio-factory-6","utility-science-pack","effect-transmission"}}, {red=2,green=3,blue=1,purple=1,yellow=1}) - -local t={type="technology",upgrade=false,icon_size=128,icons={ - {icon="__base__/graphics/technology/automation-1.png",tint={r=0.3,g=0.3,b=1,a=1},icon_mipmaps=4,icon_size=256,}, - {icon="__base__/graphics/technology/concrete.png",tint={r=0.7,g=0.7,b=1,a=0.9},priority="medium",shift={0,-32},scale=0.5,icon_mipmaps=4,icon_size=256,}, -}, } -ExtendTech(t,{name="warptorio-factory-n",unit={count=1000,time=30}, prerequisites={"warptorio-factory-7","space-science-pack","warptorio-bridgesize-2"}}, {red=3,green=2,blue=3,purple=2,yellow=1,white=1}) -local t={type="technology",upgrade=false,icon_size=128,icons={ - {icon="__base__/graphics/technology/automation-1.png",tint={r=0.3,g=0.3,b=1,a=1},icon_mipmaps=4,icon_size=256,}, - {icon="__base__/graphics/technology/concrete.png",tint={r=0.7,g=0.7,b=1,a=0.9},priority="medium",shift={0,32},scale=0.5,icon_mipmaps=4,icon_size=256,}, -}, } -ExtendTech(t,{name="warptorio-factory-s",unit={count=1000,time=30}, prerequisites={"warptorio-factory-7","space-science-pack","warptorio-bridgesize-2"}}, {red=3,green=2,blue=3,purple=2,yellow=1,white=1}) -local t={type="technology",upgrade=false,icon_size=128,icons={ - {icon="__base__/graphics/technology/automation-1.png",tint={r=0.3,g=0.3,b=1,a=1},icon_mipmaps=4,icon_size=256,}, - {icon="__base__/graphics/technology/concrete.png",tint={r=0.7,g=0.7,b=1,a=0.9},priority="medium",shift={32,0},scale=0.5,icon_mipmaps=4,icon_size=256,}, -}, } -ExtendTech(t,{name="warptorio-factory-e",unit={count=1000,time=30}, prerequisites={"warptorio-factory-7","space-science-pack","warptorio-bridgesize-2"}}, {red=3,green=2,blue=3,purple=2,yellow=1,white=1}) -local t={type="technology",upgrade=false,icon_size=128,icons={ - {icon="__base__/graphics/technology/automation-1.png",tint={r=0.3,g=0.3,b=1,a=1},icon_mipmaps=4,icon_size=256,}, - {icon="__base__/graphics/technology/concrete.png",tint={r=0.7,g=0.7,b=1,a=0.9},priority="medium",shift={-32,0},scale=0.5,icon_mipmaps=4,icon_size=256,}, -}, } -ExtendTech(t,{name="warptorio-factory-w",unit={count=1000,time=30}, prerequisites={"warptorio-factory-7","space-science-pack","warptorio-bridgesize-2"}}, {red=3,green=2,blue=3,purple=2,yellow=1,white=1}) - --- ---- --- Boiler Room Upgrades - -local t={type="technology",upgrade=true,icon_size=128,icons={ - {icon="__base__/graphics/technology/fluid-handling.png",tint={r=0.3,g=0.3,b=1,a=1},icon_mipmaps=4,icon_size=256,} -}, } -ExtendTech(t,{name="warptorio-boiler-0",unit={count=100,time=30}, prerequisites={"steel-processing","warptorio-harvester-floor"},upgrade=false, - localised_name={"technology-name.warptorio-boiler"}, - localised_description={"technology-description.warptorio-boiler-floor"}, -}, {red=1}) - -local t={type="technology",upgrade=true,icon_size=128,icons={ - {icon="__base__/graphics/technology/fluid-handling.png",tint={r=0.3,g=0.3,b=1,a=1},icon_mipmaps=4,icon_size=256,}, - {icon="__base__/graphics/technology/concrete.png",tint={r=0.7,g=0.7,b=1,a=0.9},priority="medium",shift={32,32},scale=0.5,icon_mipmaps=4,icon_size=256,}, -}, } -ExtendTech(t,{name="warptorio-boiler-1",unit={count=100,time=30}, prerequisites={"warptorio-boiler-0","fluid-handling"}}, {red=1,green=1}) -ExtendTech(t,{name="warptorio-boiler-2",unit={count=200,time=30}, prerequisites={"warptorio-boiler-1","flammables"}}, {red=1,green=1}) -ExtendTech(t,{name="warptorio-boiler-3",unit={count=300,time=30}, prerequisites={"warptorio-boiler-2","battery"}}, {red=1,green=1}) -ExtendTech(t,{name="warptorio-boiler-4",unit={count=150,time=30}, prerequisites={"warptorio-boiler-3","chemical-science-pack"}}, {red=2,green=2,blue=1}) -ExtendTech(t,{name="warptorio-boiler-5",unit={count=200,time=30}, prerequisites={"warptorio-boiler-4","production-science-pack"}}, {red=2,green=2,blue=1,purple=1}) -ExtendTech(t,{name="warptorio-boiler-6",unit={count=300,time=30}, prerequisites={"warptorio-boiler-5","nuclear-fuel-reprocessing"}}, {red=2,green=2,blue=1,purple=1,}) -ExtendTech(t,{name="warptorio-boiler-7",unit={count=300,time=30}, prerequisites={"warptorio-boiler-6","utility-science-pack"}}, {red=2,green=2,blue=1,purple=1,yellow=1}) - - -local t={type="technology",upgrade=true,icon_size=128,icons={ - {icon="__base__/graphics/technology/fluid-handling.png",tint={r=0.3,g=0.3,b=1,a=1},priority="low",icon_mipmaps=4,icon_size=256,}, - {icon="__base__/graphics/technology/oil-gathering.png",tint={r=0.7,g=0.7,b=1,a=0.9},priority="medium",shift={32,32},scale=0.5,icon_mipmaps=4,icon_size=256,}, -}, } -ExtendTech(t,{name="warptorio-boiler-water-1",upgrade=true,unit={count=500,time=30}, prerequisites={"warptorio-boiler-3","landfill"}}, {red=2,green=2,blue=1}) -ExtendTech(t,{name="warptorio-boiler-water-2",upgrade=true,unit={count=500,time=30}, prerequisites={"warptorio-boiler-5","warptorio-boiler-water-1"}}, {red=2,green=2,blue=1,purple=1}) - -ExtendTech(t,{name="warptorio-boiler-water-3",upgrade=true,unit={count=2000,time=30}, prerequisites={"warptorio-boiler-water-2","space-science-pack"}}, {red=1,green=1,blue=1,purple=1,yellow=1,white=1}) - -local t={type="technology",upgrade=false,icon_size=128,icons={ - {icon="__base__/graphics/technology/fluid-handling.png",tint={r=0.3,g=0.3,b=1,a=1},icon_mipmaps=4,icon_size=256,}, - {icon="__base__/graphics/technology/concrete.png",tint={r=0.7,g=0.7,b=1,a=0.9},priority="medium",shift={0,-32},scale=0.5,icon_mipmaps=4,icon_size=256,}, -}, } -ExtendTech(t,{name="warptorio-boiler-n",unit={count=1000,time=30}, prerequisites={"warptorio-boiler-7","space-science-pack"}}, {red=3,green=2,blue=2,purple=2,yellow=1,white=1}) - -local t={type="technology",upgrade=false,icon_size=128,icons={ - {icon="__base__/graphics/technology/fluid-handling.png",tint={r=0.3,g=0.3,b=1,a=1},icon_mipmaps=4,icon_size=256,}, - {icon="__base__/graphics/technology/concrete.png",tint={r=0.7,g=0.7,b=1,a=0.9},priority="medium",shift={0,32},scale=0.5,icon_mipmaps=4,icon_size=256,}, -}, } -ExtendTech(t,{name="warptorio-boiler-s",unit={count=1000,time=30}, prerequisites={"warptorio-boiler-7","space-science-pack"}}, {red=3,green=2,blue=2,purple=2,yellow=1,white=1}) -local t={type="technology",upgrade=false,icon_size=128,icons={ - {icon="__base__/graphics/technology/fluid-handling.png",tint={r=0.3,g=0.3,b=1,a=1},icon_mipmaps=4,icon_size=256,}, - {icon="__base__/graphics/technology/concrete.png",tint={r=0.7,g=0.7,b=1,a=0.9},priority="medium",shift={32,0},scale=0.5,icon_mipmaps=4,icon_size=256,}, -}, } -ExtendTech(t,{name="warptorio-boiler-e",unit={count=1000,time=30}, prerequisites={"warptorio-boiler-7","space-science-pack"}}, {red=3,green=2,blue=2,purple=2,yellow=1,white=1}) -local t={type="technology",upgrade=false,icon_size=128,icons={ - {icon="__base__/graphics/technology/fluid-handling.png",tint={r=0.3,g=0.3,b=1,a=1},icon_mipmaps=4,icon_size=256,}, - {icon="__base__/graphics/technology/concrete.png",tint={r=0.7,g=0.7,b=1,a=0.9},priority="medium",shift={-32,0},scale=0.5,icon_mipmaps=4,icon_size=256,}, -}, } -ExtendTech(t,{name="warptorio-boiler-w",unit={count=1000,time=30}, prerequisites={"warptorio-boiler-7","space-science-pack"}}, {red=3,green=2,blue=2,purple=2,yellow=1,white=1}) - - - - --- ---- --- Harvester Size - -local t={type="technology",upgrade=true,icon_size=128,icons={ - {icon="__base__/graphics/technology/tank.png",tint={r=0.3,g=0.3,b=1,a=1},icon_mipmaps=4,icon_size=256,} -}, } -ExtendTech(t,{name="warptorio-harvester-floor",unit={count=100,time=30}, prerequisites={"fast-inserter","warptorio-factory-0"},upgrade=false}, {red=1}) - -local t={type="technology",upgrade=true,icon_size=128,icons={ - {icon="__base__/graphics/technology/tank.png",tint={r=0.3,g=0.3,b=1,a=1},icon_mipmaps=4,icon_size=256,}, - {icon="__base__/graphics/technology/concrete.png",tint={r=0.7,g=0.7,b=1,a=0.9},priority="medium",shift={32,32},scale=0.5,icon_mipmaps=4,icon_size=256,}, -}, } -ExtendTech(t,{name="warptorio-harvester-size-1",unit={count=100,time=30}, prerequisites={"warptorio-harvester-floor","oil-processing"}}, {red=1,green=1}) -ExtendTech(t,{name="warptorio-harvester-size-2",unit={count=150,time=30}, prerequisites={"warptorio-harvester-size-1","stack-inserter"}}, {red=1,green=1}) -ExtendTech(t,{name="warptorio-harvester-size-3",unit={count=200,time=30}, prerequisites={"warptorio-harvester-size-2","mining-productivity-1"}}, {red=1,green=1}) -ExtendTech(t,{name="warptorio-harvester-size-4",unit={count=250,time=30}, prerequisites={"warptorio-harvester-size-3","chemical-science-pack"}}, {red=2,green=2,blue=1}) -ExtendTech(t,{name="warptorio-harvester-size-5",unit={count=300,time=30}, prerequisites={"warptorio-harvester-size-4","production-science-pack","mining-productivity-2"}}, {red=2,green=2,blue=1,purple=1}) -ExtendTech(t,{name="warptorio-harvester-size-6",unit={count=350,time=30}, prerequisites={"warptorio-harvester-size-5","nuclear-fuel-reprocessing"}}, {red=2,green=2,blue=1,purple=1,}) -ExtendTech(t,{name="warptorio-harvester-size-7",unit={count=400,time=30}, prerequisites={"warptorio-harvester-size-6","utility-science-pack","mining-productivity-3"}}, {red=2,green=2,blue=1,purple=1,yellow=1}) - - -for v,w in pairs({east={32,0},west={-32,0}})do local odr=(v=="east" and "a-b" or "a-a") -local t={type="technology",upgrade=true,icon_size=128,icons={ - {icon="__base__/graphics/technology/tank.png",tint={r=0.3,g=0.3,b=1,a=1},priority="low",icon_mipmaps=4,icon_size=256,}, - {icon="__base__/graphics/technology/concrete.png",tint={r=1,g=0.7,b=0.4,a=0.9},shift={w[1],w[2]},scale=0.45,priority="high",icon_mipmaps=4,icon_size=256,}, -}, } ---ExtendTech(t,{name="warptorio-harvester-"..v.."-gate",upgrade=false, unit={count=150,time=25}, prerequisites={"warptorio-harvester-floor"}}, {red=1,green=1} ) - -ExtendTech(t,{name="warptorio-harvester-"..v.."-1", order=odr, unit={count=150,time=25}, prerequisites={"warptorio-harvester-floor"},localised_description={"technology-description.warptorio-harvester-"..v.."-gate"}}, {red=1,green=1,} ) -ExtendTech(t,{name="warptorio-harvester-"..v.."-2", order=odr, unit={count=200,time=25}, prerequisites={"warptorio-harvester-"..v.."-1","mining-productivity-1","military-science-pack"}}, {red=2,green=1,black=1} ) -ExtendTech(t,{name="warptorio-harvester-"..v.."-3", order=odr, unit={count=300,time=25}, prerequisites={"warptorio-harvester-"..v.."-2","mining-productivity-2"}}, {red=2,green=2,black=1,blue=1} ) -ExtendTech(t,{name="warptorio-harvester-"..v.."-4", order=odr, unit={count=400,time=25}, prerequisites={"warptorio-harvester-"..v.."-3","nuclear-fuel-reprocessing"}}, {red=2,green=2,black=1,blue=1,purple=1} ) -ExtendTech(t,{name="warptorio-harvester-"..v.."-5", order=odr, unit={count=500,time=25}, prerequisites={"warptorio-harvester-"..v.."-4","mining-productivity-3"}}, {red=2,green=2,black=1,blue=1,purple=1,yellow=1} ) -end - ---[[ todo -for v,w in pairs({nw={-38,-38},ne={38,-38},se={38,38},sw={-38,38}})do -local t={type="technology",upgrade=true,icon_size=128,icons={ - {icon="__base__/graphics/technology/tank.png",tint={r=0.3,g=0.3,b=1,a=1},priority="low",icon_mipmaps=4,icon_size=256,}, - {icon="__base__/graphics/technology/concrete.png",tint={r=1,g=0.7,b=0.4,a=0.9},shift={w[1],w[2]},scale=0.45,priority="high",icon_mipmaps=4,icon_size=256,}, -}, } -ExtendTech(t,{name="warptorio-harvester-"..v.."",upgrade=false, unit={count=1000,time=40}, prerequisites={"warptorio-harvester-size-7","warptorio-reactor-8","space-science-pack"}}, {red=1,green=1,black=1,blue=1,purple=1,yellow=1,white=1} ) -end -]] - --- ---- --- Logistics - -local t={type="technology",upgrade=true,icon_size=128,icons={ - {icon="__base__/graphics/technology/logistics-1.png",tint={r=0.3,g=0.3,b=1,a=1},icon_mipmaps=4,icon_size=256,}, - }, -} -ExtendTech(t,{name="warptorio-logistics-1", unit={count=100,time=20}, prerequisites={"logistics","warptorio-factory-0"},upgrade=false}, {red=1} ) -ExtendTech(t,{name="warptorio-logistics-2", unit={count=200,time=20}, prerequisites={"logistics-2","warptorio-logistics-1"}}, {red=2,green=1} ) -ExtendTech(t,{name="warptorio-logistics-3", unit={count=300,time=20}, prerequisites={"logistics-3","warptorio-logistics-2"}}, {red=2,green=2,blue=1,purple=1} ) -ExtendTech(t,{name="warptorio-logistics-4", unit={count=400,time=20}, prerequisites={"logistic-system","warptorio-logistics-3"}}, {red=2,green=2,blue=1,purple=1,yellow=1} ) - -local t={type="technology",upgrade=true,icon_size=128,icons={ - {icon="__base__/graphics/technology/logistics-1.png",tint={r=0.3,g=0.3,b=1,a=1},priority="low",icon_mipmaps=4,icon_size=256,}, - {icon="__base__/graphics/technology/logistics-2.png",tint={r=1,g=1,b=0.7,a=0.9},shift={24,24},scale=0.4,priority="medium",icon_mipmaps=4,icon_size=256,}, - {icon="__base__/graphics/technology/logistics-3.png",tint={r=1,g=1,b=0.7,a=0.9},shift={-24,24},scale=0.4,priority="medium",icon_mipmaps=4,icon_size=256,}, - }, -} -ExtendTech(t,{name="warptorio-dualloader-1", unit={count=1000,time=10}, prerequisites={"logistics-2","warptorio-logistics-1"}}, {red=1,green=1} ) ---ExtendTech(t,{name="warptorio-dualloader-2", unit={count=1000,time=15}, prerequisites={"logistics-2","warptorio-dualloader-1"}}, {red=2,green=1} ) ---ExtendTech(t,{name="warptorio-dualloader-3", unit={count=1000,time=20}, prerequisites={"logistics-3","warptorio-dualloader-2","production-science-pack"}}, {red=3,green=2,blue=1,purple=1} ) -t.upgrade=false - -local t={type="technology",upgrade=false,icon_size=128,icons={ - {icon="__base__/graphics/technology/logistics-1.png",tint={r=0.3,g=0.3,b=1,a=1},priority="low",icon_mipmaps=4,icon_size=256,}, - {icon="__base__/graphics/technology/logistics-1.png",tint={r=1,g=1,b=0.7,a=0.9},shift={-28,-12},scale=0.4,priority="medium",icon_mipmaps=4,icon_size=256,}, - {icon="__base__/graphics/technology/logistics-1.png",tint={r=1,g=1,b=0.7,a=0.9},shift={28,-12},scale=0.4,priority="medium",icon_mipmaps=4,icon_size=256,}, - {icon="__base__/graphics/technology/logistics-1.png",tint={r=1,g=1,b=0.7,a=0.9},shift={0,32},scale=0.4,priority="high",icon_mipmaps=4,icon_size=256,}, - }, -} -ExtendTech(t,{name="warptorio-triloader", unit={count=10000,time=10}, prerequisites={"warptorio-logistics-1"}}, {red=1} ) - - - --- ---- --- Warp Loader - -local t={type="technology",upgrade=false,icon_size=128,icons={ - {icon="__base__/graphics/technology/logistics-1.png",tint={r=0.3,g=0.3,b=1,a=1},priority="low",icon_mipmaps=4,icon_size=256,}, - {icon="__warptorio2__/graphics/technology/earth.png",tint={r=0.8,g=0.8,b=1,a=1},scale=1,shift={32,32},priority="high",} - }, effects={ {recipe="warptorio-warploader",type="unlock-recipe"} }, -} -ExtendTech(t,{name="warptorio-warploader", unit={count=10000,time=10}, prerequisites={"warptorio-armor","warptorio-warpmodule","warptorio-warpnuke","warptorio-warpport"}}, {red=1,green=1,blue=1,purple=1,yellow=1,white=1} ) - - - --- ---- --- Energy Upgrades - -local t={type="technology",upgrade=true,icon_size=128,icons={ {icon="__base__/graphics/technology/electric-energy-acumulators.png",tint={r=0.3,g=0.3,b=1,a=1},icon_mipmaps=4,icon_size=256,} }, } -ExtendTech(t,{name="warptorio-energy-1",unit={count=30,time=20}, prerequisites={"warptorio-factory-0"},upgrade=false}, {red=1}) -ExtendTech(t,{name="warptorio-energy-2",unit={count=100,time=25}, prerequisites={"warptorio-energy-1","electric-energy-distribution-1"}}, {red=1,green=1}) -ExtendTech(t,{name="warptorio-energy-3",unit={count=150,time=30}, prerequisites={"warptorio-energy-2","advanced-electronics"}}, {red=1,green=1}) -ExtendTech(t,{name="warptorio-energy-4",unit={count=200,time=35}, prerequisites={"warptorio-energy-3","electric-energy-distribution-2","advanced-electronics-2"}}, {red=1,green=1,blue=1}) -ExtendTech(t,{name="warptorio-energy-5",unit={count=250,time=40}, prerequisites={"warptorio-energy-4","utility-science-pack","production-science-pack"}}, {red=1,green=1,blue=1,purple=1,yellow=1}) - --- ---- --- Teleporter - -local t={type="technology",upgrade=true,icon_size=128,icons={ {icon="__base__/graphics/technology/research-speed.png",tint={r=0.3,g=0.3,b=1,a=1},icon_mipmaps=4,icon_size=256,} }, } -ExtendTech(t,{name="warptorio-teleporter-portal",unit={count=30,time=20}, prerequisites={"warptorio-factory-0","electronics",},upgrade=false}, {red=1}) -ExtendTech(t,{name="warptorio-teleporter-1",unit={count=30,time=20}, prerequisites={"warptorio-teleporter-portal","electric-energy-distribution-1"}}, {red=1,green=1}) -ExtendTech(t,{name="warptorio-teleporter-2",unit={count=30,time=20}, prerequisites={"warptorio-teleporter-1","advanced-electronics"}}, {red=2,green=2,}) -ExtendTech(t,{name="warptorio-teleporter-3",unit={count=30,time=20}, prerequisites={"warptorio-teleporter-2","electric-energy-distribution-2","advanced-electronics-2"}}, {red=2,green=2,blue=1}) -ExtendTech(t,{name="warptorio-teleporter-4",unit={count=30,time=20}, prerequisites={"warptorio-teleporter-3","nuclear-power"}}, {red=2,green=2,blue=2,}) -ExtendTech(t,{name="warptorio-teleporter-5",unit={count=30,time=20}, prerequisites={"warptorio-teleporter-4","utility-science-pack","production-science-pack"}}, {red=2,green=3,blue=2,purple=1,yellow=1}) - - --- ---- --- Beacon - - -local t={type="technology",upgrade=true,icon_size=64,icons={ {icon="__base__/graphics/icons/beacon.png",tint={r=0.3,g=0.3,b=1,a=1}} }, } -ExtendTech(t,{name="warptorio-beacon-1",unit={count=300,time=20}, prerequisites={"modules","warptorio-factory-0"},upgrade=false}, {red=1,green=1}) -ExtendTech(t,{name="warptorio-beacon-2",unit={count=500,time=20}, prerequisites={"warptorio-beacon-1","speed-module","productivity-module","effectivity-module"}}, {red=1,green=1}) -ExtendTech(t,{name="warptorio-beacon-3",unit={count=300,time=20}, prerequisites={"warptorio-beacon-2","speed-module-2","productivity-module-2","effectivity-module-2"}}, {red=2,green=2,blue=1}) -ExtendTech(t,{name="warptorio-beacon-4",unit={count=500,time=20}, prerequisites={"warptorio-beacon-3","speed-module-3","productivity-module-3","effectivity-module-3"}}, {red=2,green=2,blue=1,purple=1}) -ExtendTech(t,{name="warptorio-beacon-5",unit={count="700",time=20}, prerequisites={"warptorio-beacon-4","utility-science-pack"}}, {red=2,green=2,blue=1,purple=1,yellow=1}) -ExtendTech(t,{name="warptorio-beacon-6",unit={count="900",time=20}, prerequisites={"warptorio-beacon-5"}}, {red=2,green=2,blue=1,purple=1,yellow=1}) -ExtendTech(t,{name="warptorio-beacon-7",unit={count="1200",time=20}, prerequisites={"warptorio-beacon-6"}}, {red=2,green=2,blue=1,purple=1,yellow=1}) -ExtendTech(t,{name="warptorio-beacon-8",unit={count="1500",time=20}, prerequisites={"warptorio-beacon-7"}}, {red=2,green=2,blue=1,purple=1,yellow=1}) -ExtendTech(t,{name="warptorio-beacon-9",unit={count="1000",time=20}, prerequisites={"warptorio-beacon-8","space-science-pack"}}, {red=3,green=3,blue=2,purple=1,yellow=1,white=1}) -ExtendTech(t,{name="warptorio-beacon-10",unit={count="2000",time=20}, prerequisites={"warptorio-beacon-9"}}, {red=3,green=3,blue=2,purple=2,yellow=2,white=1}) - ---[[ unused -local t={type="technology",upgrade=true,icon_size=64,icons={ {icon="__base__/graphics/icons/beacon.png",tint={r=0.3,g=0.3,b=1,a=1}} }, } -ExtendTech(t,{name="warptorio-beacon-1",unit={count=300,time=20}, prerequisites={"modules","warptorio-factory-0"},upgrade=false}, {red=1,green=1}) -ExtendTech(t,{name="warptorio-beacon-2",unit={count=500,time=20}, prerequisites={"warptorio-beacon-1","speed-module","productivity-module","effectivity-module"}}, {red=1,green=1}) -ExtendTech(t,{name="warptorio-beacon-3",unit={count=300,time=20}, prerequisites={"warptorio-beacon-2","speed-module-2","productivity-module-2","effectivity-module-2"}}, {red=2,green=2,blue=1}) -ExtendTech(t,{name="warptorio-beacon-4",unit={count=500,time=20}, prerequisites={"warptorio-beacon-3","speed-module-3","productivity-module-3","effectivity-module-3"}}, {red=2,green=2,blue=1,purple=1}) -ExtendTech(t,{name="warptorio-beacon-5",unit={count_formula="250+50*L",time=20},max_level=10, prerequisites={"warptorio-beacon-4","utility-science-pack"}}, {red=2,green=2,blue=1,purple=1,yellow=1}) -ExtendTech(t,{name="warptorio-beacon-11",unit={count=5,time=1}, prerequisites={"warptorio-beacon-5"}}, {red=5,green=5,blue=5,purple=5,white=5}) -ExtendTech(t,{name="warptorio-beacon-12",unit={count=5,time=1}, prerequisites={"warptorio-beacon-11"}}, {red=2,green=5,blue=5,purple=5,white=5}) -]] - - --- ---- --- Warp Beacon - -local t=ExtendDataCopy("beacon","beacon",{name="warptorio-beacon-1",supply_area_distance=16,module_specification={module_slots=1}, - base_picture={ tint={r=0.5,g=0.7,b=1,a=1}, }, animation={ tint={r=1,g=0.2,b=0.2,a=1}, }, - allowed_effects={"consumption","speed","pollution","productivity"}, - distribution_effectivity=1, -},true) -for i=2,10,1 do local xt=table.deepcopy(t) xt.name="warptorio-beacon-"..i xt.supply_area_distance=math.min(16+8*i,64) xt.module_specification.module_slots=i data:extend{xt} end - - - --- ---- --- Radar - ---[[ -local t={type="technology",icon_size=128,icons={ {icon="__base__/graphics/technology/radar.png",tint={r=0.3,g=0.3,b=1,a=1},icon_mipmaps=4,icon_size=256,} }, } -ExtendTech(t,{name="warptorio-radar-1",unit={count=300,time=15},prerequisites={"radar","chemical-science-pack","optics"}}, {red=1,green=1}) -]] - - --- ---- --- Warp Armor -local t={type="technology",icon_size=128,icons={ {icon="__base__/graphics/technology/power-armor-mk2.png",tint={r=0.3,g=0.3,b=1,a=1},icon_size=256},},prerequisites={"power-armor-mk2","warptorio-reactor-8","space-science-pack",} } -ExtendTech(t,{name="warptorio-armor",unit={count=1000,time=60},effects={{recipe="warptorio-armor",type="unlock-recipe"}}},{red=4,green=4,blue=4,black=5,yellow=2,white=1}) - - -data:extend{{type="equipment-grid",name="warptorio-warparmor-grid",equipment_categories={"armor"},height=16,width=16}} -local t=ExtendDataCopy("armor","power-armor-mk2",{name="warptorio-armor",equipment_grid="warptorio-warparmor-grid", - icon_size=64,icons={{icon="__base__/graphics/icons/power-armor-mk2.png",tint={r=0.3,g=0.3,b=1,a=1},}},inventory_size_bonus=100},false) - -local t=ExtendDataCopy("recipe","power-armor-mk2",{name="warptorio-armor",enabled=false,ingredients={{"power-armor-mk2",5},{"power-armor",5},{"modular-armor",5},{"heavy-armor",5},{"light-armor",5}},result="warptorio-armor"}) - - - --- ---- --- Warp Combinators - -local t={type="technology",upgrade=true,icon_size=128,icons={ - {icon="__base__/graphics/technology/circuit-network.png",tint={r=0.3,g=0.3,b=1,a=1},icon_mipmaps=4,icon_size=256,}, - --{icon="__base__/graphics/technology/concrete.png",tint={r=0.7,g=0.7,b=1,a=0.9},priority="medium",shift={32,32},scale=0.5,icon_mipmaps=4,icon_size=256,}, -}, effects={ - {recipe="warptorio-combinator",type="unlock-recipe"}, -}, } -ExtendTech(t,{name="warptorio-combinator",unit={count=50,time=20}, prerequisites={"circuit-network","chemical-science-pack"}}, {red=1,green=1,blue=1}) - -local t={type="technology",upgrade=true,icon_size=128,icons={ - {icon="__base__/graphics/technology/circuit-network.png",tint={r=0.3,g=0.3,b=1,a=1},icon_mipmaps=4,icon_size=256,}, - {icon="__base__/graphics/technology/tank.png",tint={r=0.7,g=0.7,b=1,a=0.9},priority="medium",shift={32,32},scale=0.5,icon_mipmaps=4,icon_size=256,}, -}, } -ExtendTech(t,{name="warptorio-alt-combinator",unit={count=50,time=20}, prerequisites={"circuit-network","production-science-pack","warptorio-harvester-east-1","warptorio-harvester-west-1"}}, {red=1,green=1,blue=1,purple=1}) - - - --- ---- --- Warp Toolbar - - -local t={type="technology",upgrade=true,icon_size=128,icons={ - {icon="__base__/graphics/technology/toolbelt.png",tint={r=0.4,g=0.4,b=1,a=1},icon_mipmaps=4,icon_size=256,}, - {icon="__warptorio2__/graphics/technology/earth.png",tint={r=0.8,g=0.8,b=1,a=0.9},priority="medium",shift={32,32},scale=1}, -},} -ExtendTech(t,{name="warptorio-toolbar",unit={count=2000,time=20}, - prerequisites={"space-science-pack","warptorio-toolbelt-5","warptorio-reach-5","warptorio-harvester-east-5","warptorio-harvester-west-5","warptorio-teleporter-5","warptorio-striders-2"}, -}, - {red=1,green=1,blue=1,purple=1,black=1,yellow=1,white=1} -) - - - +local function istable(t) return type(t) == "table" end +local function rgb(r, g, b, a) + a = a or 255 + return { r = r / 255, g = g / 255, b = b / 255, a = a / 255 } +end + +function table.deepmerge(s, t) + for k, v in pairs(t) do + if (istable(v) and s[k] and istable(s[k])) then + table.deepmerge( + s[k], v) + else + s[k] = v + end + end +end + +function table.merge(s, t) + local x = {} + for k, v in pairs(s) do x[k] = v end + for k, v in pairs(t) do x[k] = v end + return x +end + +local function MakeDataCopy(a, b, x) + local t = table.deepcopy(data.raw[a][b]) + if (x) then table.deepmerge(t, x) end + return t +end +local function ExtendRecipeItem(t) + local r = table.deepcopy(data.raw.recipe["nuclear-reactor"]) + r.enabled = false + r.name = t.name + r.ingredients = { { type = "item", name = "steel-plate", amount = 1 } } + r.results = { { type = "item", name = t.name, amount = 1 } } + local i = table.deepcopy(data.raw.item["nuclear-reactor"]) + i.name = t.name + i.place_result = t.name + data:extend { i, r } +end +local function ExtendRecipeItemFix(t) t.order = t.order or "warptorio" end +local function ExtendDataCopy(a, b, x, ri, tx) + local t = MakeDataCopy(a, b, x) + if (tx) then for k, v in pairs(tx) do if (v == false) then t[k] = nil else t[k] = v end end end + if (ri) then ExtendRecipeItemFix(t) end + data:extend { t } + return t +end + +local function ExtendCopyRecipe(src, name) + local r = table.deepcopy(data.raw.recipe[src]) + r.enabled = false + r.name = name + r.ingredients = { { type = "item", name = "steel-plate", amount = 1 } } + r.results = { { type = "item", name = name, amount = 1 } } + local i = table.deepcopy(data.raw.recipe[src]) + i.name = name + i.place_result = name + data:extend { i, r } +end + +local techPacks = { + red = "automation-science-pack", + green = "logistic-science-pack", + blue = "chemical-science-pack", + black = "military-science-pack", + purple = "production-science-pack", + yellow = "utility-science-pack", + white = "space-science-pack" +} + +local function SciencePacks(x) + local t = {} + for k, v in pairs(x) do table.insert(t, { techPacks[k], v }) end + return t +end +local function ExtendTech(t, d, s) + local x = table.merge(t, d) + if (s) then x.unit.ingredients = SciencePacks(s) end + data:extend { x } + return x +end + +--[[ +local t=ExtendDataCopy("electric-pole","small-electric-pole",{name="warptorio-electric-pole", + pictures={layers={[1]={tint={r=0.6,g=0.6,b=1,a=1},hr_version={tint={r=0.6,g=0.6,b=1,a=1}} }, }}, +},true) +]] + + +-- -------- +-- vonNeumann compatability. It's base game stuff anyway. Perhaps expand on this later + +-- data.raw.lab["crash-site-lab-repaired"].minable={mining_time=3,result="crash-site-lab-repaired"} +-- data.raw.container["crash-site-chest-1"].minable={mining_time=3,result="crash-site-chest-1"} +-- data.raw.container["crash-site-chest-2"].minable={mining_time=3,result="crash-site-chest-2"} +-- data.raw["assembling-machine"]["crash-site-assembling-machine-1-repaired"].minable={mining_time=3,result="crash-site-assembling-machine-1-repaired"} +-- data.raw["assembling-machine"]["crash-site-assembling-machine-2-repaired"].minable={mining_time=3,result="crash-site-assembling-machine-2-repaired"} + + +-- -------- +-- Warp Tiles + +-- purple tiles +local t = ExtendDataCopy("tile", "tutorial-grid", + { name = "warp-tile-concrete", tint = { r = 0.6, g = 0.6, b = 0.7, a = 1 }, layer = 99, decorative_removal_probability = 1, walking_speed_modifier = 1.6, map_color = { r = 0.2, g = 0.1, b = 0.25, a = 1 } }) + +-- orange tiles +local t = ExtendDataCopy("tile", "tutorial-grid", + { name = "warptorio-red-concrete", tint = { r = 1, g = 0.5, b = 0, a = 0.25 }, layer = 67, decorative_removal_probability = 1, walking_speed_modifier = 1.5, map_color = { r = 0.2, g = 0.1, b = 0, a = 1 } }) + +-- -------- +-- Invisiradar +local rtint = { r = 0.4, g = 0.4, b = 1, a = 1 } +local rvtint = { scale = 0.5 / 3, tint = { r = 1, g = 1, b = 1, a = 0 }, shift = { 0.03125 / 3, -0.5 / 3 } } +local r = ExtendDataCopy("radar", "radar", { + name = "warptorio-invisradar", + icons = { { icon = "__base__/graphics/icons/radar.png", tint = rtint } }, + integration_patch = rvtint, + pictures = { layers = { rvtint, rvtint } }, +}, true, { + energy_source = { type = "void" }, + energy_per_nearby_scan = "10kJ", + energy_per_sector = "200kJ", + energy_usage = "1kW", + icon = false, + max_distance_of_nearby_sector_revealed = 5, + max_distance_of_sector_revealed = 18, + collision_box = { { -1.2 / 3, -1.2 / 3 }, { 1.2 / 3, 1.2 / 3 } }, + selection_box = { { -1.5 / 3, -1.5 / 3 }, { 1.5 / 3, 1.5 / 3 } }, +}) + + +-- -------- +-- Loot Chest + +local rtint = { r = 0.4, g = 0.4, b = 1, a = 1 } +local t = ExtendDataCopy("container", "wooden-chest", { + name = "warptorio-lootchest", + inventory_size = 8, + icons = { { icon = "__base__/graphics/icons/wooden-chest.png", tint = rtint } }, + picture = { layers = { [1] = { tint = rtint }, } }, +}, true, { icon = false, minable = { mining_time = 0.1 } }) + + +-- -------- +-- Carebear Chest + +local rtint = rgb(255, 20, 147) +local t = ExtendDataCopy("container", "wooden-chest", { + name = "warptorio-carebear-chest", + inventory_size = 99, + icons = { { icon = "__base__/graphics/icons/wooden-chest.png", tint = rtint } }, + picture = { layers = { [1] = { tint = rtint }, } }, +}, true, { icon = false, minable = { mining_time = 10 } }) + + +-- ---- +-- Logistics + +--[[ +local rtint={r=0.5,g=0.5,b=1,a=1} +local rtintpic={tint=rtint,hr_version={tint=rtint}} +local rctint={r=0.39,g=0,b=0,a=1} +local rtintcov={layers={ [1]={tint=rctint,hr_version={tint=rctint}} }} +local t=ExtendDataCopy("pipe-to-ground","pipe-to-ground",{name="warptorio-logistics-pipe",fluid_box={base_area=5,pipe_connections={[2]={max_underground_distance=-1}}}, + pictures={ left=rtintpic, right=rtintpic,up=rtintpic,down=rtintpic }, + pipe_covers={ east={layers={ [1]={tint=rctint,hr_version={tint=rctint}} }}, north=rtintcov, south=rtintcov, west=rtintcov,} +},true) +]] + +-- -------- +-- Warp Reactor + +-- Fuel +data:extend { { type = "fuel-category", name = "warp" } } + +ExtendDataCopy("item", "uranium-fuel-cell", + { + name = "warptorio-warponium-fuel-cell", + fuel_category = "warp", + burnt_result = "uranium-fuel-cell", + fuel_value = "32GJ", + stack_size = 50, + icon_size = 64, + icons = { { icon = "__base__/graphics/icons/uranium-fuel-cell.png", tint = { r = 1, g = 0.2, b = 1, a = 0.8 } }, }, + }, false, { icon = false }) + +ExtendDataCopy("recipe", "uranium-fuel-cell", + { name = "warptorio-warponium-fuel-cell", enabled = false, results = { { type = "item", name = "warptorio-warponium-fuel-cell", amount = 1 } } }, + false, + { + ingredients = { { type = "item", name = "uranium-fuel-cell", amount = 5 } }, + icon_size = 64, + icons = { { icon = "__base__/graphics/icons/uranium-fuel-cell.png", tint = { r = 1, g = 0.2, b = 1, a = 0.8 } }, }, + }, false, { icon = false }) + +ExtendDataCopy("item", "nuclear-fuel", { + name = "warptorio-warponium-fuel", + fuel_category = "chemical", + fuel_acceleration_multiplier = 5, + fuel_value = "7GJ", + stack_size = 1, + fuel_top_speed_multiplier = 1.25, + icon_size = 64, + icons = { { icon = "__base__/graphics/icons/nuclear-fuel.png", tint = { r = 1, g = 0.2, b = 1, a = 0.8 } }, }, +}, false, { icon = false }) + +ExtendDataCopy("recipe", "nuclear-fuel", + { name = "warptorio-warponium-fuel", enabled = false, results = { { type = "item", name = "warptorio-warponium-fuel", amount = 1 } } }, + false, + { + ingredients = { { type = "item", name = "warptorio-warponium-fuel-cell", amount = 1 }, { type = "item", name = "nuclear-fuel", amount = 1 } }, + icon = false, + icon_size = 64, + icons = { { icon = "__base__/graphics/icons/nuclear-fuel.png", tint = { r = 1, g = 0.2, b = 1, a = 0.8 } }, }, + }) + + +-- The Reactor Itself +local t = ExtendDataCopy("reactor", "nuclear-reactor", + { + name = "warptorio-reactor", + max_health = 5000, + neighbour_bonus = 12, + consumption = "160MW", + energy_source = { fuel_categories = { "warp" } }, + heat_buffer = { specific_heat = "1MJ", max_temperature = 1000 }, + light = { intensity = 10, size = 9.9, shift = { 0.0, 0.0 }, color = { r = 1.0, g = 0.0, b = 0.0 } }, + working_light_picture = { filename = "__base__/graphics/entity/nuclear-reactor/reactor-lights-color.png", tint = { r = 1, g = 0.4, b = 0.4, a = 1 }, + }, + picture = { + layers = { + [1] = { tint = { r = 0.8, g = 0.8, b = 1, a = 1 } }, + } + }, + }, true) + + +-- ------------------------------------------------------------------------- +-- Technologies + + +-- ---- +-- Warp Roboport + +local t = { + type = "technology", + upgrade = true, + icon_size = 128, + effects = { { recipe = "warptorio-warpport", type = "unlock-recipe" } }, + icons = { + { icon = "__base__/graphics/entity/roboport/roboport-base.png", tint = { r = 0.3, g = 0.3, b = 1, a = 1 }, priority = "low", icon_size = 220, scale = 0.25 }, + }, +} +ExtendTech(t, + { name = "warptorio-warpport", unit = { count = 1000, time = 30 }, prerequisites = { "warptorio-logistics-4", "warptorio-reactor-8", "space-science-pack" } }, + { red = 1, green = 1, black = 1, blue = 1, purple = 1, yellow = 1, white = 1 }) + + +-- ---- +-- Warp Nuke + +local t = { + type = "technology", + upgrade = true, + icon_size = 128, + icons = { + { icon = "__base__/graphics/technology/atomic-bomb.png", tint = { r = 0.3, g = 0.3, b = 1, a = 1 }, priority = "low", icon_mipmaps = 4, icon_size = 256, }, + }, +} +ExtendTech(t, + { + name = "warptorio-warpnuke", + unit = { count = 1000, time = 5 }, + effects = { { recipe = "warptorio-atomic-bomb", type = "unlock-recipe" } }, + prerequisites = { "atomic-bomb", "warptorio-reactor-8", "space-science-pack" } + }, { red = 1, green = 1, black = 1, blue = 1, purple = 1, yellow = 1, white = 1 }) + + +-- ---- +-- Warp Module + +local t = { + type = "technology", + upgrade = true, + icon_size = 128, + icons = { + { icon = "__base__/graphics/technology/module.png", tint = { r = 0.3, g = 0.3, b = 1, a = 1 }, priority = "low", icon_mipmaps = 4, icon_size = 256, }, + }, +} +ExtendTech(t, + { + name = "warptorio-warpmodule", + unit = { count = 3000, time = 60 }, + prerequisites = { "warptorio-reactor-8", "space-science-pack", "efficiency-module-3" }, + effects = { { recipe = "warptorio-warpmodule", type = "unlock-recipe" } }, + }, { red = 1, green = 1, black = 1, blue = 1, purple = 1, yellow = 1, white = 1 }) + +data:extend { { type = "module-category", name = "warpivity" } } +local t = { + type = "module", + category = "warpivity", + name = "warptorio-warpmodule", + stack_size = 50, + subgroup = "module", + tier = 4, + localised_description = { "item-description.warptorio-warpmodule" }, + limitation_message_key = "production-module-usable-only-on-intermediates", + effect = { consumption = 0.6, pollution = 0.05, productivity = 0.1, speed = 0.35 }, + icon_size = 64, + icons = { { icon = "__base__/graphics/icons/speed-module-3.png", tint = { r = 0.2, g = 0.2, b = 1, a = 1 } } }, +} +data:extend { t } + +data:extend { { type = "recipe", results = { { type = "item", name = "warptorio-warpmodule", amount = 1 } }, name = "warptorio-warpmodule", enabled = false, energy_required = 60, + ingredients = { + { type = "item", name = "speed-module-3", amount = 50 }, + { type = "item", name = "productivity-module-3", amount = 50 }, + { type = "item", name = "efficiency-module-3", amount = 50 }, + { type = "item", name = "advanced-circuit", amount = 200 }, + { type = "item", name = "processing-unit", amount = 200 }, + { type = "item", name = "low-density-structure", amount = 10 } + }, +} } + + +-- ---- +-- Warp Reactor + +local t = { + type = "technology", + upgrade = true, + icon_size = 128, + icons = { + { icon = "__base__/graphics/technology/nuclear-power.png", tint = { r = 0.3, g = 0.3, b = 1, a = 1 }, priority = "low", icon_mipmaps = 4, icon_size = 256, }, + { icon = "__base__/graphics/technology/engine.png", tint = { r = 0.7, g = 0.7, b = 1, a = 1 }, scale = 0.25, shift = { 16, 16 }, priority = "high", icon_mipmaps = 4, icon_size = 256, }, + }, +} +ExtendTech(t, { name = "warptorio-reactor-1", unit = { count = 50, time = 5 }, prerequisites = {} }, { red = 1 }) + +local t = { + type = "technology", + upgrade = true, + icon_size = 128, + icons = { + { icon = "__base__/graphics/technology/nuclear-power.png", tint = { r = 0.3, g = 0.3, b = 1, a = 1 }, priority = "low", icon_mipmaps = 4, icon_size = 256, }, + { icon = "__base__/graphics/technology/electronics.png", tint = { r = 0.7, g = 0.7, b = 1, a = 1 }, scale = 0.25, shift = { 16, 16 }, priority = "high", icon_mipmaps = 4, icon_size = 256, } + }, +} +ExtendTech(t, + { name = "warptorio-reactor-2", unit = { count = 75, time = 10 }, prerequisites = { "warptorio-reactor-1", "logistic-science-pack" } }, + { red = 1, green = 1 }) + +local t = { + type = "technology", + upgrade = true, + icon_size = 128, + icons = { + { icon = "__base__/graphics/technology/nuclear-power.png", tint = { r = 0.3, g = 0.3, b = 1, a = 1 }, priority = "low", icon_mipmaps = 4, icon_size = 256, }, + { icon = "__base__/graphics/technology/advanced-circuit.png", tint = { r = 0.7, g = 0.7, b = 1, a = 1 }, scale = 0.25, shift = { 16, 16 }, priority = "high", icon_mipmaps = 4, icon_size = 256, } + }, +} +ExtendTech(t, + { name = "warptorio-reactor-3", unit = { count = 100, time = 15 }, prerequisites = { "warptorio-reactor-2", "military-science-pack" } }, + { red = 1, green = 2, black = 1 }) + +local t = { + type = "technology", + upgrade = true, + icon_size = 128, + icons = { + { icon = "__base__/graphics/technology/nuclear-power.png", tint = { r = 0.3, g = 0.3, b = 1, a = 1 }, priority = "low", icon_mipmaps = 4, icon_size = 256, }, + { icon = "__base__/graphics/technology/processing-unit.png", tint = { r = 0.7, g = 0.7, b = 1, a = 1 }, scale = 0.25, shift = { 16, 16 }, priority = "high", icon_mipmaps = 4, icon_size = 256, } + }, +} +ExtendTech(t, + { name = "warptorio-reactor-4", unit = { count = 200, time = 20 }, prerequisites = { "warptorio-reactor-3", "rocketry" } }, + { red = 2, green = 2, black = 1, }) + +local t = { + type = "technology", + upgrade = true, + icon_size = 128, + icons = { + { icon = "__base__/graphics/technology/nuclear-power.png", tint = { r = 0.3, g = 0.3, b = 1, a = 1 }, priority = "low", icon_mipmaps = 4, icon_size = 256, }, + { icon = "__base__/graphics/technology/explosives.png", tint = { r = 0.7, g = 0.7, b = 1, a = 1 }, scale = 0.25, shift = { 16, 16 }, priority = "high", icon_mipmaps = 4, icon_size = 256, } + }, +} +ExtendTech(t, + { name = "warptorio-reactor-5", unit = { count = 250, time = 25 }, prerequisites = { "warptorio-reactor-4", "chemical-science-pack" } }, + { red = 1, green = 3, black = 1, blue = 1 }) + +local t = { + type = "technology", + upgrade = true, + icon_size = 128, + icons = { + { icon = "__base__/graphics/technology/nuclear-power.png", tint = { r = 0.3, g = 0.3, b = 1, a = 1 }, priority = "low", icon_mipmaps = 4, icon_size = 256, }, + { icon = "__base__/graphics/technology/atomic-bomb.png", tint = { r = 0.7, g = 0.7, b = 1, a = 1 }, scale = 0.25, shift = { 16, 16 }, priority = "high", icon_mipmaps = 4, icon_size = 256, } + }, + localised_description = { "technology-description.warptorio-reactor-6" } +} +ExtendTech(t, + { name = "warptorio-reactor-6", unit = { count = 300, time = 30 }, effects = { { recipe = "warptorio-townportal", type = "unlock-recipe" } }, prerequisites = { "warptorio-reactor-5", "uranium-processing", "robotics" } }, + { red = 5, black = 5 }) -- reactor module + +local t = { + type = "technology", + upgrade = true, + icon_size = 128, + icons = { + { icon = "__base__/graphics/technology/nuclear-power.png", tint = { r = 0.3, g = 0.3, b = 1, a = 1 }, priority = "low", icon_mipmaps = 4, icon_size = 256, }, + { icon = "__base__/graphics/technology/kovarex-enrichment-process.png", tint = { r = 0.7, g = 0.7, b = 1, a = 1 }, scale = 0.25, shift = { 16, 16 }, priority = "high", icon_mipmaps = 4, icon_size = 256, } + }, +} +ExtendTech(t, + { name = "warptorio-reactor-7", unit = { count = 500, time = 40 }, effects = { { recipe = "warptorio-heatpipe", type = "unlock-recipe" }, { recipe = "warptorio-warponium-fuel-cell", type = "unlock-recipe" } }, prerequisites = { "nuclear-power", "warptorio-reactor-6" } }, + { red = 1, green = 1, black = 1, blue = 1 }) + +local t = { + type = "technology", + upgrade = true, + icon_size = 128, + icons = { + { icon = "__base__/graphics/technology/nuclear-power.png", tint = { r = 0.3, g = 0.3, b = 1, a = 1 }, priority = "low", icon_mipmaps = 4, icon_size = 256, }, + { icon = "__warptorio2__/graphics/technology/earth.png", tint = { r = 0.8, g = 0.8, b = 1, a = 1 }, scale = 0.25, shift = { 16, 16 }, priority = "high" } + }, + localised_description = { "technology-description.warptorio-reactor-8" } +} +ExtendTech(t, + { name = "warptorio-reactor-8", unit = { count = 1000, time = 60 }, prerequisites = { "warptorio-reactor-7", "warptorio-charting", "warptorio-accelerator", "warptorio-stabilizer", "warptorio-kovarex" } }, + { red = 1, green = 1, black = 1, blue = 1, purple = 1, yellow = 1 }) -- steering + + + +-- ---- +-- Reactor Abilities + +local t = { + type = "technology", + upgrade = false, + icon_size = 128, + icons = { + { icon = "__base__/graphics/technology/battery.png", tint = { r = 0.3, g = 0.3, b = 1, a = 1 }, priority = "low", icon_mipmaps = 4, icon_size = 256, }, + }, +} +ExtendTech(t, + { name = "warptorio-stabilizer", unit = { count = 400, time = 30 }, prerequisites = { "warptorio-reactor-6", "military-3", "circuit-network" } }, + { red = 1, green = 1, black = 1, blue = 1 }) -- stabilizer + +local t = { type = "technology", upgrade = false, icon_size = 128, icons = { { icon = "__base__/graphics/technology/nuclear-power.png", tint = { r = 0.3, g = 0.3, b = 1, a = 1 }, priority = "low", icon_mipmaps = 4, icon_size = 256, } }, } +t.icons = { { icon = "__base__/graphics/technology/engine.png", tint = { r = 0.3, g = 0.3, b = 1, a = 1 }, icon_mipmaps = 4, icon_size = 256, } } +ExtendTech(t, + { name = "warptorio-accelerator", unit = { count = 400, time = 30 }, prerequisites = { "warptorio-reactor-6", "military-3", "circuit-network" } }, + { red = 1, green = 1, black = 1, blue = 1 }) -- accelerator + +local t = { type = "technology", upgrade = false, icon_size = 128, icons = { { icon = "__base__/graphics/technology/nuclear-power.png", tint = { r = 0.3, g = 0.3, b = 1, a = 1 }, priority = "low", icon_mipmaps = 4, icon_size = 256, } }, } +t.icons = { { icon = "__base__/graphics/technology/radar.png", tint = { r = 0.3, g = 0.3, b = 1, a = 1 }, icon_mipmaps = 4, icon_size = 256, } } +ExtendTech(t, + { name = "warptorio-charting", unit = { count = 400, time = 30 }, prerequisites = { "warptorio-reactor-6", "military-3", "circuit-network" } }, + { red = 1, green = 1, black = 1, blue = 1 }) -- charting + + +local t = { + type = "technology", + upgrade = true, + icons = { + { icon = "__warptorio2__/graphics/technology/earth.png", tint = { r = 0.8, g = 0.8, b = 1, a = 1 }, scale = 0.375, priority = "low", icon_size = 128 } + }, +} +ExtendTech(t, + { name = "warptorio-homeworld", unit = { count = 5000, time = 30 }, effects = { { recipe = "warptorio-homeportal", type = "unlock-recipe" } }, prerequisites = { "warptorio-reactor-8", "space-science-pack" } }, + { red = 1, green = 1, black = 1, blue = 1, purple = 1, yellow = 1, white = 1 }) + + +-- ---- +-- Warponium Fuel + +local t = { + type = "technology", + upgrade = true, + icon_size = 128, + icons = { + { icon = "__base__/graphics/technology/nuclear-power.png", tint = { r = 0.3, g = 0.3, b = 1, a = 1 }, priority = "low", icon_mipmaps = 4, icon_size = 256, }, + { icon = "__base__/graphics/technology/rocket-fuel.png", tint = { r = 0.7, g = 0.7, b = 1, a = 1 }, scale = 0.25, shift = { 16, 16 }, priority = "high", icon_mipmaps = 4, icon_size = 256, }, + }, + effects = { { recipe = "warptorio-warponium-fuel", type = "unlock-recipe" } }, +} +ExtendTech(t, + { name = "warptorio-kovarex", unit = { count = 1000, time = 15 }, prerequisites = { "warptorio-reactor-7", "kovarex-enrichment-process" } }, + { red = 1, green = 1, black = 1, blue = 1, purple = 1 }) -- Kovarex + + +-- ---- +-- Boiler Warp Substation + +local t = { + type = "technology", + upgrade = false, + icon_size = 128, + icons = { + { icon = "__base__/graphics/technology/electric-energy-distribution-1.png", tint = { r = 0.3, g = 0.3, b = 1, a = 1 }, priority = "low", icon_mipmaps = 4, icon_size = 256, }, + { icon = "__base__/graphics/technology/fluid-handling.png", tint = { r = 0.7, g = 0.7, b = 1, a = 1 }, scale = 0.25, shift = { 16, 16 }, priority = "high", icon_mipmaps = 4, icon_size = 256, }, + }, +} +ExtendTech(t, + { name = "warptorio-boiler-station", unit = { count = 500, time = 10 }, prerequisites = { "electric-energy-distribution-2", "warptorio-boiler-0", "production-science-pack" } }, + { red = 1, blue = 1, green = 1, purple = 1 }) + + +-- ---- +-- Warp Energy Pipe + +local rtint = { tint = { r = 0.3, g = 0.3, b = 1, a = 1 } } + +--[[ +local pipe_sprites={corner_left_down={{rtint},{rtint},{rtint},{rtint},{rtint}},corner_left_up={{rtint},{rtint},{rtint},{rtint},{rtint},{rtint}}, + corner_right_down={{rtint},{rtint},{rtint},{rtint},{rtint},{rtint}},corner_right_up={{rtint},{rtint},{rtint},{rtint},{rtint},{rtint}}, + cross={{rtint}},ending_down={{rtint}},ending_left={{rtint}},ending_right={{rtint}},ending_up={{rtint}},single={{rtint}}, + straight_horizontal={{rtint},{rtint},{rtint},{rtint},{rtint},{rtint}},straight_vertical={{rtint},{rtint},{rtint},{rtint},{rtint},{rtint}}, + t_down={{rtint}},t_left={{rtint}},t_right={{rtint}},t_up={{rtint}},} + +local t=ExtendDataCopy("heat-pipe","heat-pipe",{name="warptorio-heatpipe",connection_sprites=pipe_sprites,heat_glow_sprites=pipe_sprites, + max_temperature=5000, + max_transfer="5GW", + specific_heat="1MJ", + icon_size=64,icons={ {icon="__base__/graphics/icons/heat-pipe.png",tint={r=0.3,g=0.3,b=1,a=1},hr_version={tint={r=0.3,g=0.3,b=1,a=1}} } } +})]] + +local pipe_icon = { { icon = "__base__/graphics/icons/heat-pipe.png", tint = { r = 0.3, g = 0.3, b = 1, a = 1 }, icon_mipmaps = 4, icon_size = 64 } } +local t = ExtendDataCopy("recipe", "heat-pipe", + { name = "warptorio-heatpipe", results = { { type = "item", name = "warptorio-heatpipe", amount = 1 } }, ingredients = { { type = "item", name = "processing-unit", amount = 200 }, { type = "item", name = "heat-pipe", amount = 50 } }, enabled = false, energy_required = 30, }) +local t = ExtendDataCopy("item", "heat-pipe", { + name = "warptorio-heatpipe", + place_result = "warptorio-heatpipe", + icon_size = 64, + icons = pipe_icon, +}) + +-- ---- +-- Sandbox Boosts + +local t = { + type = "technology", + upgrade = true, + icon_size = 128, + icons = { { icon = "__base__/graphics/technology/mining-productivity.png", tint = { r = 0.3, g = 0.3, b = 1, a = 1 }, icon_mipmaps = 4, icon_size = 256, } }, + effects = { { type = "mining-drill-productivity-bonus", modifier = 0.1 } }, +} +ExtendTech(t, { name = "warptorio-mining-prod-1", unit = { count_formula = "20*L", time = 30 }, max_level = 5 }, + { red = 1 }) +ExtendTech(t, + { name = "warptorio-mining-prod-6", unit = { count_formula = "(20*L)+50", time = 40 }, max_level = 10, prerequisites = { "warptorio-mining-prod-1", "logistic-science-pack" } }, + { red = 2, green = 1 }) +ExtendTech(t, + { name = "warptorio-mining-prod-11", unit = { count_formula = "(20*L)+100", time = 50 }, max_level = 15, prerequisites = { "warptorio-mining-prod-6", "chemical-science-pack" } }, + { red = 2, green = 2, blue = 1 }) +ExtendTech(t, + { name = "warptorio-mining-prod-16", unit = { count_formula = "(20*L)+150", time = 60 }, max_level = 20, prerequisites = { "warptorio-mining-prod-11", "production-science-pack" } }, + { red = 3, green = 3, blue = 1, purple = 1 }) +ExtendTech(t, + { name = "warptorio-mining-prod-21", unit = { count_formula = "(20*L)+200", time = 60 }, max_level = 25, prerequisites = { "warptorio-mining-prod-16", "utility-science-pack" } }, + { red = 3, green = 3, blue = 2, purple = 1, yellow = 1 }) + +local t = { + type = "technology", + upgrade = true, + icon_size = 64, + icons = { { icon = "__base__/graphics/technology/steel-axe.png", tint = { r = 0.3, g = 0.3, b = 1, a = 1 }, icon_mipmaps = 4, icon_size = 256, } }, + effects = { { type = "character-mining-speed", modifier = 0.5 } }, +} +ExtendTech(t, + { name = "warptorio-axe-speed-1", unit = { count_formula = "50*L", time = 30 }, prerequisites = { "steel-axe", "warptorio-reactor-1" }, max_level = 2 }, + { red = 1 }) +ExtendTech(t, + { name = "warptorio-axe-speed-3", unit = { count_formula = "(50*L)+50", time = 30 }, max_level = 4, prerequisites = { "warptorio-axe-speed-1", "logistic-science-pack" } }, + { red = 1, green = 1 }) +ExtendTech(t, + { name = "warptorio-axe-speed-5", unit = { count_formula = "(50*L)+100", time = 30 }, max_level = 6, prerequisites = { "warptorio-axe-speed-3", "chemical-science-pack" } }, + { red = 1, green = 1, blue = 1 }) +ExtendTech(t, + { name = "warptorio-axe-speed-7", unit = { count_formula = "(50*L)+150", time = 30 }, max_level = 8, prerequisites = { "warptorio-axe-speed-5", "production-science-pack" } }, + { red = 1, green = 1, blue = 1, purple = 1 }) +ExtendTech(t, + { name = "warptorio-axe-speed-9", unit = { count_formula = "(50*L)+200", time = 30 }, max_level = 10, prerequisites = { "warptorio-axe-speed-7", "utility-science-pack" } }, + { red = 1, green = 1, blue = 1, purple = 1, yellow = 1 }) + +local t = { + type = "technology", + upgrade = true, + icon_size = 128, + icons = { { icon = "__base__/graphics/technology/inserter-capacity.png", tint = { r = 0.3, g = 0.3, b = 1, a = 1 }, icon_mipmaps = 4, icon_size = 256, } }, + effects = { { type = "bulk-inserter-capacity-bonus", modifier = 1 }, { type = "inserter-stack-size-bonus", modifier = 1 }, } +} +ExtendTech(t, + { name = "warptorio-inserter-cap-1", unit = { count = 150, time = 30 }, prerequisites = { "warptorio-reactor-1", "fast-inserter" }, }, + { red = 1 }) +ExtendTech(t, + { name = "warptorio-inserter-cap-2", unit = { count = 200, time = 30 }, prerequisites = { "warptorio-inserter-cap-1", "logistic-science-pack" } }, + { red = 2, green = 1 }) +ExtendTech(t, + { name = "warptorio-inserter-cap-3", unit = { count = 250, time = 30 }, prerequisites = { "warptorio-inserter-cap-2", "chemical-science-pack" } }, + { red = 3, green = 2, blue = 1 }) +ExtendTech(t, + { name = "warptorio-inserter-cap-4", unit = { count = 300, time = 30 }, prerequisites = { "warptorio-inserter-cap-3", "production-science-pack" } }, + { red = 4, green = 3, blue = 2, purple = 1 }) +ExtendTech(t, + { name = "warptorio-inserter-cap-5", unit = { count = 350, time = 30 }, prerequisites = { "warptorio-inserter-cap-4", "utility-science-pack" } }, + { red = 5, green = 4, blue = 3, purple = 2, yellow = 1 }) + + +local t = { + type = "technology", + upgrade = true, + icon_size = 128, + icons = { { icon = "__base__/graphics/technology/worker-robots-speed.png", tint = { r = 0.3, g = 0.3, b = 1, a = 1 }, icon_mipmaps = 4, icon_size = 256, } }, + effects = { { type = "worker-robot-speed", modifier = 0.35 }, } +} +ExtendTech(t, + { name = "warptorio-bot-speed-1", unit = { count = 120, time = 30 }, prerequisites = { "robotics", "warptorio-reactor-2" } }, + { red = 1, green = 1 }) +ExtendTech(t, + { name = "warptorio-bot-speed-2", unit = { count = 180, time = 30 }, prerequisites = { "warptorio-bot-speed-1", "logistic-robotics" } }, + { red = 2, green = 1 }) +ExtendTech(t, + { name = "warptorio-bot-speed-3", unit = { count = 250, time = 30 }, prerequisites = { "warptorio-bot-speed-2", "chemical-science-pack" } }, + { red = 3, green = 2, blue = 1 }) +ExtendTech(t, + { name = "warptorio-bot-speed-4", unit = { count = 300, time = 30 }, prerequisites = { "warptorio-bot-speed-3", "production-science-pack" } }, + { red = 4, green = 3, blue = 2, purple = 1 }) +ExtendTech(t, + { name = "warptorio-bot-speed-5", unit = { count = 350, time = 30 }, prerequisites = { "warptorio-bot-speed-4", "utility-science-pack" } }, + { red = 5, green = 4, blue = 3, purple = 2, yellow = 1 }) + +local t = { + type = "technology", + upgrade = true, + icon_size = 128, + icons = { { icon = "__base__/graphics/technology/worker-robots-storage.png", tint = { r = 0.3, g = 0.3, b = 1, a = 1 }, icon_mipmaps = 4, icon_size = 256, } }, + effects = { { type = "worker-robot-storage", modifier = 1 }, } +} +ExtendTech(t, + { name = "warptorio-bot-cap-1", unit = { count = 120, time = 30 }, prerequisites = { "robotics", "warptorio-reactor-2" } }, + { red = 1, green = 1 }) +ExtendTech(t, + { name = "warptorio-bot-cap-2", unit = { count = 180, time = 30 }, prerequisites = { "warptorio-bot-cap-1", "construction-robotics" } }, + { red = 2, green = 1 }) +ExtendTech(t, + { name = "warptorio-bot-cap-3", unit = { count = 250, time = 30 }, prerequisites = { "warptorio-bot-cap-2", "chemical-science-pack" } }, + { red = 2, green = 2, blue = 1 }) +ExtendTech(t, + { name = "warptorio-bot-cap-4", unit = { count = 300, time = 30 }, prerequisites = { "warptorio-bot-cap-3", "production-science-pack" } }, + { red = 3, green = 3, blue = 1, purple = 1 }) +ExtendTech(t, + { name = "warptorio-bot-cap-5", unit = { count = 350, time = 30 }, prerequisites = { "warptorio-bot-cap-4", "utility-science-pack" } }, + { red = 3, green = 3, blue = 2, purple = 1, yellow = 1 }) + + +local t = { + type = "technology", + upgrade = true, + icon_size = 128, + icons = { { icon = "__base__/graphics/technology/physical-projectile-damage-1.png", tint = { r = 0.3, g = 0.3, b = 1, a = 1 }, icon_mipmaps = 4, icon_size = 256, } }, + effects = { { type = "turret-attack", modifier = 0.15, turret_id = "gun-turret" }, { ammo_category = "bullet", modifier = 0.15, type = "ammo-damage" }, { ammo_category = "shotgun-shell", modifier = 0.2, type = "ammo-damage" } } +} +ExtendTech(t, + { name = "warptorio-physdmg-1", unit = { count = 250, time = 30 }, prerequisites = { "warptorio-reactor-1", "physical-projectile-damage-1" } }, + { red = 1 }) +ExtendTech(t, + { name = "warptorio-physdmg-2", unit = { count = 250, time = 30 }, prerequisites = { "warptorio-reactor-2", "warptorio-physdmg-1", "physical-projectile-damage-2" } }, + { red = 2, green = 1 }) +ExtendTech(t, + { name = "warptorio-physdmg-3", unit = { count = 350, time = 30 }, prerequisites = { "warptorio-reactor-3", "warptorio-physdmg-2", "physical-projectile-damage-3" } }, + { red = 3, green = 2, black = 1 }) + +local t = { + type = "technology", + upgrade = true, + icon_size = 128, + icons = { { icon = "__base__/graphics/technology/toolbelt.png", tint = { r = 0.3, g = 0.3, b = 1, a = 1 }, icon_mipmaps = 4, icon_size = 256, } }, + effects = { { type = "character-inventory-slots-bonus", modifier = 10 } }, +} +ExtendTech(t, + { name = "warptorio-toolbelt-1", unit = { count = 70, time = 30 }, prerequisites = { "warptorio-reactor-1" } }, + { red = 1 }) +ExtendTech(t, + { name = "warptorio-toolbelt-2", unit = { count = 120, time = 30 }, prerequisites = { "warptorio-toolbelt-1", "toolbelt", "logistic-science-pack" } }, + { red = 2, green = 1 }) +ExtendTech(t, + { name = "warptorio-toolbelt-3", unit = { count = 150, time = 30 }, prerequisites = { "warptorio-toolbelt-2", "chemical-science-pack" } }, + { red = 2, green = 2, blue = 1 }) +ExtendTech(t, + { name = "warptorio-toolbelt-4", unit = { count = 180, time = 30 }, prerequisites = { "warptorio-toolbelt-3", "production-science-pack" } }, + { red = 3, green = 2, blue = 2, purple = 1 }) +ExtendTech(t, + { name = "warptorio-toolbelt-5", unit = { count = 200, time = 30 }, prerequisites = { "warptorio-toolbelt-4", "utility-science-pack" } }, + { red = 4, green = 3, blue = 2, purple = 2, yellow = 1 }) + +local t = { + type = "technology", + upgrade = true, + icons = { + { icon = "__warptorio2__/graphics/technology/earth.png", tint = { r = 0.7, g = 0.7, b = 1, a = 1 }, shift = { 0, 0 }, scale = 0.375, priority = "medium", icon_size = 128 }, + { icon = "__base__/graphics/technology/steel-axe.png", tint = { r = 0.3, g = 0.3, b = 1, a = 1 }, priority = "low", icon_size = 256, scale = 0.125 }, + }, + effects = { + { type = "character-reach-distance", modifier = 1 }, + { type = "character-build-distance", modifier = 1 }, + { type = "character-item-drop-distance", modifier = 1 }, + { type = "character-resource-reach-distance", modifier = 1 }, + }, +} +ExtendTech(t, { name = "warptorio-reach-1", unit = { count = 50, time = 30 }, prerequisites = { "warptorio-reactor-1" } }, + { red = 1 }) +ExtendTech(t, + { name = "warptorio-reach-2", unit = { count = 100, time = 30 }, prerequisites = { "warptorio-reach-1", "logistic-science-pack" } }, + { red = 2, green = 1 }) +ExtendTech(t, + { name = "warptorio-reach-3", unit = { count = 150, time = 30 }, prerequisites = { "warptorio-reach-2", "chemical-science-pack" } }, + { red = 2, green = 2, blue = 1 }) +ExtendTech(t, + { name = "warptorio-reach-4", unit = { count = 180, time = 30 }, prerequisites = { "warptorio-reach-3", "production-science-pack" } }, + { red = 3, green = 2, blue = 2, purple = 1 }) +ExtendTech(t, + { name = "warptorio-reach-5", unit = { count = 200, time = 30 }, prerequisites = { "warptorio-reach-4", "utility-science-pack" } }, + { red = 4, green = 3, blue = 2, purple = 2, yellow = 1 }) + + +local t = { + type = "technology", + upgrade = true, + icon_size = 128, + icons = { + { icon = "__base__/graphics/technology/exoskeleton-equipment.png", tint = { r = 0.3, g = 0.3, b = 1, a = 1 }, icon_mipmaps = 4, icon_size = 256, }, + }, + effects = { + { type = "character-running-speed", modifier = 0.1 }, + }, +} +ExtendTech(t, + { name = "warptorio-striders-1", unit = { count = 150, time = 20 }, prerequisites = { "warptorio-reactor-1" }, upgrade = false }, + { red = 1 }) +ExtendTech(t, + { name = "warptorio-striders-2", unit = { count = 300, time = 20 }, prerequisites = { "warptorio-reactor-2", "modular-armor", "warptorio-striders-1" }, upgrade = false }, + { red = 1, green = 1 }) + + + +-- ---- +-- Platform Size + +local t = { type = "technology", upgrade = true, icon_size = 128, icons = { { icon = "__base__/graphics/technology/concrete.png", tint = { r = 0.3, g = 0.3, b = 1, a = 1 }, icon_mipmaps = 4, icon_size = 256, } }, } +ExtendTech(t, { name = "warptorio-platform-size-1", unit = { count = 70, time = 20 }, prerequisites = {} }, { red = 1 }) +ExtendTech(t, + { name = "warptorio-platform-size-2", unit = { count = 120, time = 20 }, prerequisites = { "warptorio-platform-size-1", "warptorio-reactor-1" } }, + { red = 1 }) +ExtendTech(t, + { name = "warptorio-platform-size-3", unit = { count = 150, time = 30 }, prerequisites = { "warptorio-platform-size-2", "logistic-science-pack" } }, + { red = 1, green = 1 }) +ExtendTech(t, + { name = "warptorio-platform-size-4", unit = { count = 200, time = 30 }, prerequisites = { "concrete", "warptorio-platform-size-3" } }, + { red = 1, green = 1 }) +ExtendTech(t, + { name = "warptorio-platform-size-5", unit = { count = 120, time = 30 }, prerequisites = { "chemical-science-pack", "warptorio-platform-size-4" } }, + { red = 2, green = 2, blue = 1 }) +ExtendTech(t, + { name = "warptorio-platform-size-6", unit = { count = 150, time = 30 }, prerequisites = { "warptorio-platform-size-5", "solar-energy", "production-science-pack" } }, + { red = 2, green = 2, blue = 1, purple = 1 }) +ExtendTech(t, + { name = "warptorio-platform-size-7", unit = { count = 150, time = 30 }, prerequisites = { "warptorio-platform-size-6", "utility-science-pack" } }, + { red = 2, green = 2, blue = 1, purple = 1, yellow = 1 }) + + +-- ---- +-- Train Stops + + +for v, w in pairs({ nw = { -38, -38 }, ne = { 38, -38 }, se = { 38, 38 }, sw = { -38, 38 } }) do + local t = { + type = "technology", + upgrade = false, + icon_size = 128, + icons = { + { icon = "__base__/graphics/technology/railway.png", tint = { r = 0.7, g = 0.7, b = 1, a = 0.9 }, priority = "low", icon_mipmaps = 4, icon_size = 256, scale = 0.375 }, + { icon = "__base__/graphics/technology/railway.png", tint = { r = 0.3, g = 0.3, b = 1, a = 1 }, shift = { w[1], w[2] }, scale = 0.25, priority = "high", icon_mipmaps = 4, icon_size = 256, }, + }, + } + + ExtendTech(t, + { name = "warptorio-rail-" .. v, unit = { count = 500, time = 30 }, prerequisites = { "railway", "warptorio-platform-size-6", "warptorio-factory-7" } }, + { red = 1, green = 1, black = 1, blue = 1, purple = 1, yellow = 1 }) +end + + +-- ---- +-- Castle Ramps + + +for v, w in pairs({ nw = { -38, -38 }, ne = { 38, -38 }, se = { 38, 38 }, sw = { -38, 38 } }) do + local t = { + type = "technology", + upgrade = true, + icon_size = 128, + icons = { + { icon = "__base__/graphics/technology/stone-wall.png", tint = { r = 0.3, g = 0.3, b = 1, a = 1 }, priority = "low", icon_mipmaps = 4, icon_size = 256, scale = 0.4 }, + { icon = "__base__/graphics/technology/stone-wall.png", tint = { r = 0.7, g = 0.7, b = 1, a = 0.9 }, shift = { w[1], w[2] }, scale = 0.25, priority = "high", icon_mipmaps = 4, icon_size = 256, }, + }, + } + ExtendTech(t, + { name = "warptorio-turret-" .. v .. "-0", upgrade = false, unit = { count = 100, time = 30 }, prerequisites = { "gate", "warptorio-factory-0" } }, + { red = 1, green = 1 }) + ExtendTech(t, + { name = "warptorio-turret-" .. v .. "-1", unit = { count = 150, time = 30 }, prerequisites = { "warptorio-turret-" .. v .. "-0", "military-science-pack", } }, + { red = 2, green = 1, black = 1, }) + ExtendTech(t, + { name = "warptorio-turret-" .. v .. "-2", unit = { count = 200, time = 30 }, prerequisites = { "warptorio-turret-" .. v .. "-1", "chemical-science-pack" } }, + { red = 2, green = 1, black = 1, blue = 1 }) + ExtendTech(t, + { name = "warptorio-turret-" .. v .. "-3", unit = { count = 300, time = 40 }, prerequisites = { "warptorio-turret-" .. v .. "-2", "production-science-pack" } }, + { red = 2, green = 2, black = 1, blue = 1, purple = 1 }) +end + +local t = { + type = "technology", + upgrade = true, + icon_size = 128, + icons = { + { icon = "__base__/graphics/technology/stone-wall.png", tint = { r = 0.3, g = 0.3, b = 1, a = 1 }, priority = "low", icon_mipmaps = 4, icon_size = 256, }, + { icon = "__base__/graphics/technology/stone-wall.png", tint = { r = 0.7, g = 0.7, b = 1, a = 0.9 }, shift = { 32, 32 }, scale = 0.25, priority = "high", icon_mipmaps = 4, icon_size = 256, }, + { icon = "__base__/graphics/technology/stone-wall.png", tint = { r = 0.7, g = 0.7, b = 1, a = 0.9 }, shift = { -32, -32 }, scale = 0.25, priority = "high", icon_mipmaps = 4, icon_size = 256, }, + { icon = "__base__/graphics/technology/stone-wall.png", tint = { r = 0.7, g = 0.7, b = 1, a = 0.9 }, shift = { -32, 32 }, scale = 0.25, priority = "high", icon_mipmaps = 4, icon_size = 256, }, + { icon = "__base__/graphics/technology/stone-wall.png", tint = { r = 0.7, g = 0.7, b = 1, a = 0.9 }, shift = { 32, -32 }, scale = 0.25, priority = "high", icon_mipmaps = 4, icon_size = 256, }, + }, +} +ExtendTech(t, + { + name = "warptorio-bridgesize-1", + unit = { count = 500, time = 40 }, + prerequisites = { "warptorio-turret-nw-0", "warptorio-turret-ne-0", "warptorio-turret-se-0", "warptorio-turret-sw-0" }, + unit = { count = 200, time = 40 } + }, { red = 1, green = 1, black = 1 }) +ExtendTech(t, + { + name = "warptorio-bridgesize-2", + unit = { count = 500, time = 40 }, + prerequisites = { "warptorio-bridgesize-1", "warptorio-turret-nw-1", "warptorio-turret-ne-1", "warptorio-turret-se-1", "warptorio-turret-sw-1", "low-density-structure" }, + unit = { count = 400, time = 40 } + }, { red = 1, green = 1, black = 1, blue = 1 }) + +-- ---- +-- Factory Floor Upgrades + +local t = { + type = "technology", + upgrade = true, + icon_size = 128, + icons = { + { icon = "__base__/graphics/technology/automation-1.png", tint = { r = 0.3, g = 0.3, b = 1, a = 1 }, icon_mipmaps = 4, icon_size = 256, } + }, +} +ExtendTech(t, + { + name = "warptorio-factory-0", + unit = { count = 80, time = 20 }, + prerequisites = { "automation", "warptorio-platform-size-1" }, + upgrade = false, + localised_name = { "technology-name.warptorio-factory" }, + localised_description = { "technology-description.warptorio-factory-floor" }, + }, { red = 1 }) + +local t = { + type = "technology", + upgrade = true, + icon_size = 128, + icons = { + { icon = "__base__/graphics/technology/automation-1.png", tint = { r = 0.3, g = 0.3, b = 1, a = 1 }, icon_mipmaps = 4, icon_size = 256, }, + { icon = "__base__/graphics/technology/concrete.png", tint = { r = 0.7, g = 0.7, b = 1, a = 0.9 }, priority = "medium", shift = { 16, 16 }, scale = 0.25, icon_mipmaps = 4, icon_size = 256, }, + }, +} +ExtendTech(t, + { name = "warptorio-factory-1", unit = { count = 120, time = 20 }, prerequisites = { "warptorio-factory-0", "steel-processing" } }, + { red = 1 }) +ExtendTech(t, + { name = "warptorio-factory-2", unit = { count = 150, time = 20 }, prerequisites = { "electric-energy-distribution-1", "advanced-material-processing", "automation-2", "warptorio-factory-1" } }, + { red = 1, green = 1 }) +ExtendTech(t, + { name = "warptorio-factory-3", unit = { count = 180, time = 20 }, prerequisites = { "warptorio-factory-2", "sulfur-processing" } }, + { red = 2, green = 2 }) +ExtendTech(t, + { name = "warptorio-factory-4", unit = { count = 220, time = 20 }, prerequisites = { "warptorio-factory-3", "chemical-science-pack", "modules" } }, + { red = 2, green = 2, blue = 1 }) +ExtendTech(t, + { name = "warptorio-factory-5", unit = { count = 250, time = 20 }, prerequisites = { "warptorio-factory-4", "advanced-material-processing-2" } }, + { red = 2, green = 2, blue = 1 }) +ExtendTech(t, + { name = "warptorio-factory-6", unit = { count = 300, time = 20 }, prerequisites = { "warptorio-factory-5", "automation-3" } }, + { red = 2, green = 2, blue = 1, purple = 1 }) +ExtendTech(t, + { name = "warptorio-factory-7", unit = { count = 350, time = 20 }, prerequisites = { "warptorio-factory-6", "utility-science-pack", "effect-transmission" } }, + { red = 2, green = 3, blue = 1, purple = 1, yellow = 1 }) + +local t = { + type = "technology", + upgrade = false, + icon_size = 128, + icons = { + { icon = "__base__/graphics/technology/automation-1.png", tint = { r = 0.3, g = 0.3, b = 1, a = 1 }, icon_mipmaps = 4, icon_size = 256, }, + { icon = "__base__/graphics/technology/concrete.png", tint = { r = 0.7, g = 0.7, b = 1, a = 0.9 }, priority = "medium", shift = { 0, -24 }, scale = 0.25, icon_mipmaps = 4, icon_size = 256, }, + }, +} +ExtendTech(t, + { name = "warptorio-factory-n", unit = { count = 1000, time = 30 }, prerequisites = { "warptorio-factory-7", "space-science-pack", "warptorio-bridgesize-2" } }, + { red = 3, green = 2, blue = 3, purple = 2, yellow = 1, white = 1 }) +local t = { + type = "technology", + upgrade = false, + icon_size = 128, + icons = { + { icon = "__base__/graphics/technology/automation-1.png", tint = { r = 0.3, g = 0.3, b = 1, a = 1 }, icon_mipmaps = 4, icon_size = 256, }, + { icon = "__base__/graphics/technology/concrete.png", tint = { r = 0.7, g = 0.7, b = 1, a = 0.9 }, priority = "medium", shift = { 0, 24 }, scale = 0.25, icon_mipmaps = 4, icon_size = 256, }, + }, +} +ExtendTech(t, + { name = "warptorio-factory-s", unit = { count = 1000, time = 30 }, prerequisites = { "warptorio-factory-7", "space-science-pack", "warptorio-bridgesize-2" } }, + { red = 3, green = 2, blue = 3, purple = 2, yellow = 1, white = 1 }) +local t = { + type = "technology", + upgrade = false, + icon_size = 128, + icons = { + { icon = "__base__/graphics/technology/automation-1.png", tint = { r = 0.3, g = 0.3, b = 1, a = 1 }, icon_mipmaps = 4, icon_size = 256, }, + { icon = "__base__/graphics/technology/concrete.png", tint = { r = 0.7, g = 0.7, b = 1, a = 0.9 }, priority = "medium", shift = { 24, 0 }, scale = 0.25, icon_mipmaps = 4, icon_size = 256, }, + }, +} +ExtendTech(t, + { name = "warptorio-factory-e", unit = { count = 1000, time = 30 }, prerequisites = { "warptorio-factory-7", "space-science-pack", "warptorio-bridgesize-2" } }, + { red = 3, green = 2, blue = 3, purple = 2, yellow = 1, white = 1 }) +local t = { + type = "technology", + upgrade = false, + icon_size = 128, + icons = { + { icon = "__base__/graphics/technology/automation-1.png", tint = { r = 0.3, g = 0.3, b = 1, a = 1 }, icon_mipmaps = 4, icon_size = 256, }, + { icon = "__base__/graphics/technology/concrete.png", tint = { r = 0.7, g = 0.7, b = 1, a = 0.9 }, priority = "medium", shift = { -24, 0 }, scale = 0.25, icon_mipmaps = 4, icon_size = 256, }, + }, +} +ExtendTech(t, + { name = "warptorio-factory-w", unit = { count = 1000, time = 30 }, prerequisites = { "warptorio-factory-7", "space-science-pack", "warptorio-bridgesize-2" } }, + { red = 3, green = 2, blue = 3, purple = 2, yellow = 1, white = 1 }) + +-- ---- +-- Boiler Room Upgrades + +local t = { + type = "technology", + upgrade = true, + icon_size = 128, + icons = { + { icon = "__base__/graphics/technology/fluid-handling.png", tint = { r = 0.3, g = 0.3, b = 1, a = 1 }, icon_mipmaps = 4, icon_size = 256, } + }, +} +ExtendTech(t, + { + name = "warptorio-boiler-0", + unit = { count = 100, time = 30 }, + prerequisites = { "steel-processing", "warptorio-harvester-floor" }, + upgrade = false, + localised_name = { "technology-name.warptorio-boiler" }, + localised_description = { "technology-description.warptorio-boiler-floor" }, + }, { red = 1 }) + +local t = { + type = "technology", + upgrade = true, + icon_size = 128, + icons = { + { icon = "__base__/graphics/technology/fluid-handling.png", tint = { r = 0.3, g = 0.3, b = 1, a = 1 }, icon_mipmaps = 4, icon_size = 256, }, + { icon = "__base__/graphics/technology/concrete.png", tint = { r = 0.7, g = 0.7, b = 1, a = 0.9 }, priority = "medium", shift = { 16, 16 }, scale = 0.25, icon_mipmaps = 4, icon_size = 256, }, + }, +} +ExtendTech(t, + { name = "warptorio-boiler-1", unit = { count = 100, time = 30 }, prerequisites = { "warptorio-boiler-0", "fluid-handling" } }, + { red = 1, green = 1 }) +ExtendTech(t, + { name = "warptorio-boiler-2", unit = { count = 200, time = 30 }, prerequisites = { "warptorio-boiler-1", "flammables" } }, + { red = 1, green = 1 }) +ExtendTech(t, + { name = "warptorio-boiler-3", unit = { count = 300, time = 30 }, prerequisites = { "warptorio-boiler-2", "battery" } }, + { red = 1, green = 1 }) +ExtendTech(t, + { name = "warptorio-boiler-4", unit = { count = 200, time = 30 }, prerequisites = { "warptorio-boiler-3", "chemical-science-pack" } }, + { red = 2, green = 2, blue = 1 }) +ExtendTech(t, + { name = "warptorio-boiler-5", unit = { count = 200, time = 30 }, prerequisites = { "warptorio-boiler-4", "production-science-pack" } }, + { red = 2, green = 2, blue = 1, purple = 1 }) +ExtendTech(t, + { name = "warptorio-boiler-6", unit = { count = 300, time = 30 }, prerequisites = { "warptorio-boiler-5", "nuclear-fuel-reprocessing" } }, + { red = 2, green = 2, blue = 1, purple = 1, }) +ExtendTech(t, + { name = "warptorio-boiler-7", unit = { count = 300, time = 30 }, prerequisites = { "warptorio-boiler-6", "utility-science-pack" } }, + { red = 2, green = 2, blue = 1, purple = 1, yellow = 1 }) + + +local t = { + type = "technology", + upgrade = true, + icon_size = 128, + icons = { + { icon = "__base__/graphics/technology/fluid-handling.png", tint = { r = 0.3, g = 0.3, b = 1, a = 1 }, priority = "low", icon_mipmaps = 4, icon_size = 256, }, + { icon = "__base__/graphics/technology/oil-gathering.png", tint = { r = 0.7, g = 0.7, b = 1, a = 0.9 }, priority = "medium", shift = { 16, 16 }, scale = 0.25, icon_mipmaps = 4, icon_size = 256, }, + }, +} +ExtendTech(t, + { name = "warptorio-boiler-water-1", upgrade = true, unit = { count = 500, time = 30 }, prerequisites = { "warptorio-boiler-3", "landfill" } }, + { red = 2, green = 2, blue = 1 }) +ExtendTech(t, + { name = "warptorio-boiler-water-2", upgrade = true, unit = { count = 1000, time = 40 }, prerequisites = { "warptorio-boiler-5", "warptorio-boiler-water-1" } }, + { red = 2, green = 2, blue = 1, purple = 1 }) + +ExtendTech(t, + { name = "warptorio-boiler-water-3", upgrade = true, unit = { count = 2000, time = 50 }, prerequisites = { "warptorio-boiler-water-2", "space-science-pack" } }, + { red = 1, green = 1, blue = 1, purple = 1, yellow = 1, white = 1 }) + +local t = { + type = "technology", + upgrade = false, + icon_size = 128, + icons = { + { icon = "__base__/graphics/technology/fluid-handling.png", tint = { r = 0.3, g = 0.3, b = 1, a = 1 }, icon_mipmaps = 4, icon_size = 256, }, + { icon = "__base__/graphics/technology/concrete.png", tint = { r = 0.7, g = 0.7, b = 1, a = 0.9 }, priority = "medium", shift = { 0, -24 }, scale = 0.25, icon_mipmaps = 4, icon_size = 256, }, + }, +} +ExtendTech(t, + { name = "warptorio-boiler-n", unit = { count = 1000, time = 30 }, prerequisites = { "warptorio-boiler-7", "space-science-pack" } }, + { red = 3, green = 2, blue = 2, purple = 2, yellow = 1, white = 1 }) + +local t = { + type = "technology", + upgrade = false, + icon_size = 128, + icons = { + { icon = "__base__/graphics/technology/fluid-handling.png", tint = { r = 0.3, g = 0.3, b = 1, a = 1 }, icon_mipmaps = 4, icon_size = 256, }, + { icon = "__base__/graphics/technology/concrete.png", tint = { r = 0.7, g = 0.7, b = 1, a = 0.9 }, priority = "medium", shift = { 0, 24 }, scale = 0.25, icon_mipmaps = 4, icon_size = 256, }, + }, +} +ExtendTech(t, + { name = "warptorio-boiler-s", unit = { count = 1000, time = 30 }, prerequisites = { "warptorio-boiler-7", "space-science-pack" } }, + { red = 3, green = 2, blue = 2, purple = 2, yellow = 1, white = 1 }) +local t = { + type = "technology", + upgrade = false, + icon_size = 128, + icons = { + { icon = "__base__/graphics/technology/fluid-handling.png", tint = { r = 0.3, g = 0.3, b = 1, a = 1 }, icon_mipmaps = 4, icon_size = 256, }, + { icon = "__base__/graphics/technology/concrete.png", tint = { r = 0.7, g = 0.7, b = 1, a = 0.9 }, priority = "medium", shift = { 24, 0 }, scale = 0.25, icon_mipmaps = 4, icon_size = 256, }, + }, +} +ExtendTech(t, + { name = "warptorio-boiler-e", unit = { count = 1000, time = 30 }, prerequisites = { "warptorio-boiler-7", "space-science-pack" } }, + { red = 3, green = 2, blue = 2, purple = 2, yellow = 1, white = 1 }) +local t = { + type = "technology", + upgrade = false, + icon_size = 128, + icons = { + { icon = "__base__/graphics/technology/fluid-handling.png", tint = { r = 0.3, g = 0.3, b = 1, a = 1 }, icon_mipmaps = 4, icon_size = 256, }, + { icon = "__base__/graphics/technology/concrete.png", tint = { r = 0.7, g = 0.7, b = 1, a = 0.9 }, priority = "medium", shift = { -24, 0 }, scale = 0.25, icon_mipmaps = 4, icon_size = 256, }, + }, +} +ExtendTech(t, + { name = "warptorio-boiler-w", unit = { count = 1000, time = 30 }, prerequisites = { "warptorio-boiler-7", "space-science-pack" } }, + { red = 3, green = 2, blue = 2, purple = 2, yellow = 1, white = 1 }) + + + + +-- ---- +-- Harvester Size + +local t = { + type = "technology", + upgrade = true, + icon_size = 128, + icons = { + { icon = "__base__/graphics/technology/tank.png", tint = { r = 0.3, g = 0.3, b = 1, a = 1 }, icon_mipmaps = 4, icon_size = 256, } + }, +} +ExtendTech(t, + { name = "warptorio-harvester-floor", unit = { count = 100, time = 30 }, prerequisites = { "fast-inserter", "warptorio-factory-0" }, upgrade = false }, + { red = 1 }) + +local t = { + type = "technology", + upgrade = true, + icon_size = 256, + icons = { + { icon = "__base__/graphics/technology/tank.png", tint = { r = 0.3, g = 0.3, b = 1, a = 1 }, icon_mipmaps = 4, icon_size = 256, }, + { icon = "__base__/graphics/technology/concrete.png", tint = { r = 0.7, g = 0.7, b = 1, a = 0.9 }, shift = { 16, 16 }, scale = 0.25, icon_mipmaps = 4, icon_size = 256, }, + }, +} +ExtendTech(t, + { name = "warptorio-harvester-size-1", unit = { count = 100, time = 30 }, prerequisites = { "warptorio-harvester-floor", "oil-processing" } }, + { red = 1, green = 1 }) +ExtendTech(t, + { name = "warptorio-harvester-size-2", unit = { count = 150, time = 30 }, prerequisites = { "warptorio-harvester-size-1", "bulk-inserter" } }, + { red = 1, green = 1 }) +ExtendTech(t, + { name = "warptorio-harvester-size-3", unit = { count = 200, time = 30 }, prerequisites = { "warptorio-harvester-size-2", "mining-productivity-1" } }, + { red = 1, green = 1 }) +ExtendTech(t, + { name = "warptorio-harvester-size-4", unit = { count = 250, time = 30 }, prerequisites = { "warptorio-harvester-size-3", "chemical-science-pack" } }, + { red = 2, green = 2, blue = 1 }) +ExtendTech(t, + { name = "warptorio-harvester-size-5", unit = { count = 300, time = 30 }, prerequisites = { "warptorio-harvester-size-4", "production-science-pack", "mining-productivity-2" } }, + { red = 2, green = 2, blue = 1, purple = 1 }) +ExtendTech(t, + { name = "warptorio-harvester-size-6", unit = { count = 350, time = 30 }, prerequisites = { "warptorio-harvester-size-5", "nuclear-fuel-reprocessing" } }, + { red = 2, green = 2, blue = 1, purple = 1, }) +ExtendTech(t, + { name = "warptorio-harvester-size-7", unit = { count = 400, time = 30 }, prerequisites = { "warptorio-harvester-size-6", "utility-science-pack", "mining-productivity-3" } }, + { red = 2, green = 2, blue = 1, purple = 1, yellow = 1 }) + + +for v, w in pairs({ east = { 24, 0 }, west = { -24, 0 } }) do + local odr = (v == "east" and "a-b" or "a-a") + local t = { + type = "technology", + upgrade = true, + icon_size = 256, + icons = { + { icon = "__base__/graphics/technology/tank.png", tint = { r = 0.3, g = 0.3, b = 1, a = 1 }, priority = "low", icon_mipmaps = 4, icon_size = 256, }, + { icon = "__base__/graphics/technology/concrete.png", tint = { r = 1, g = 0.7, b = 0.4, a = 0.9 }, shift = { w[1], w[2] }, scale = 0.25, priority = "high", icon_mipmaps = 4, icon_size = 256, }, + }, + } + --ExtendTech(t,{name="warptorio-harvester-"..v.."-gate",upgrade=false, unit={count=150,time=25}, prerequisites={"warptorio-harvester-floor"}}, {red=1,green=1} ) + + ExtendTech(t, + { name = "warptorio-harvester-" .. v .. "-1", order = odr, unit = { count = 150, time = 25 }, prerequisites = { "warptorio-harvester-floor" }, localised_description = { "technology-description.warptorio-harvester-" .. v .. "-gate" } }, + { red = 1, green = 1, }) + ExtendTech(t, + { name = "warptorio-harvester-" .. v .. "-2", order = odr, unit = { count = 200, time = 25 }, prerequisites = { "warptorio-harvester-" .. v .. "-1", "mining-productivity-1", "military-science-pack" } }, + { red = 2, green = 1, black = 1 }) + ExtendTech(t, + { name = "warptorio-harvester-" .. v .. "-3", order = odr, unit = { count = 300, time = 25 }, prerequisites = { "warptorio-harvester-" .. v .. "-2", "mining-productivity-2" } }, + { red = 2, green = 2, black = 1, blue = 1 }) + ExtendTech(t, + { name = "warptorio-harvester-" .. v .. "-4", order = odr, unit = { count = 400, time = 25 }, prerequisites = { "warptorio-harvester-" .. v .. "-3", "nuclear-fuel-reprocessing" } }, + { red = 2, green = 2, black = 1, blue = 1, purple = 1 }) + ExtendTech(t, + { name = "warptorio-harvester-" .. v .. "-5", order = odr, unit = { count = 500, time = 25 }, prerequisites = { "warptorio-harvester-" .. v .. "-4", "mining-productivity-3" } }, + { red = 2, green = 2, black = 1, blue = 1, purple = 1, yellow = 1 }) +end + +--[[ todo +for v,w in pairs({nw={-38,-38},ne={38,-38},se={38,38},sw={-38,38}})do +local t={type="technology",upgrade=true,icon_size=128,icons={ + {icon="__base__/graphics/technology/tank.png",tint={r=0.3,g=0.3,b=1,a=1},priority="low",icon_mipmaps=4,icon_size=256,}, + {icon="__base__/graphics/technology/concrete.png",tint={r=1,g=0.7,b=0.4,a=0.9},shift={w[1],w[2]},scale=0.45,priority="high",icon_mipmaps=4,icon_size=256,}, +}, } +ExtendTech(t,{name="warptorio-harvester-"..v.."",upgrade=false, unit={count=1000,time=40}, prerequisites={"warptorio-harvester-size-7","warptorio-reactor-8","space-science-pack"}}, {red=1,green=1,black=1,blue=1,purple=1,yellow=1,white=1} ) +end +]] + +-- ---- +-- Logistics + +local t = { + type = "technology", + upgrade = true, + icon_size = 128, + icons = { + { icon = "__base__/graphics/technology/logistics-1.png", tint = { r = 0.3, g = 0.3, b = 1, a = 1 }, icon_mipmaps = 4, icon_size = 256, }, + }, +} +ExtendTech(t, + { name = "warptorio-logistics-1", unit = { count = 100, time = 20 }, prerequisites = { "logistics", "warptorio-factory-0" }, upgrade = false }, + { red = 1 }) +ExtendTech(t, + { name = "warptorio-logistics-2", unit = { count = 200, time = 20 }, prerequisites = { "logistics-2", "warptorio-logistics-1" } }, + { red = 2, green = 1 }) +ExtendTech(t, + { name = "warptorio-logistics-3", unit = { count = 300, time = 20 }, prerequisites = { "logistics-3", "warptorio-logistics-2" } }, + { red = 2, green = 2, blue = 1, purple = 1 }) +ExtendTech(t, + { name = "warptorio-logistics-4", unit = { count = 400, time = 20 }, prerequisites = { "logistic-system", "warptorio-logistics-3" } }, + { red = 2, green = 2, blue = 1, purple = 1, yellow = 1 }) + +local t = { + type = "technology", + upgrade = true, + icon_size = 128, + icons = { + { icon = "__base__/graphics/technology/logistics-1.png", tint = { r = 0.3, g = 0.3, b = 1, a = 1 }, priority = "low", icon_mipmaps = 4, icon_size = 256, }, + { icon = "__base__/graphics/technology/logistics-2.png", tint = { r = 1, g = 1, b = 0.7, a = 0.9 }, shift = { -14, 12 }, scale = 0.2, priority = "medium", icon_mipmaps = 4, icon_size = 256, }, + { icon = "__base__/graphics/technology/logistics-3.png", tint = { r = 1, g = 1, b = 0.7, a = 0.9 }, shift = { 14, 12 }, scale = 0.2, priority = "medium", icon_mipmaps = 4, icon_size = 256, }, + }, +} +ExtendTech(t, + { name = "warptorio-dualloader-1", unit = { count = 500, time = 20 }, prerequisites = { "logistics-2", "warptorio-logistics-1" } }, + { red = 1, green = 1 }) +--ExtendTech(t,{name="warptorio-dualloader-2", unit={count=1000,time=15}, prerequisites={"logistics-2","warptorio-dualloader-1"}}, {red=2,green=1} ) +--ExtendTech(t,{name="warptorio-dualloader-3", unit={count=1000,time=20}, prerequisites={"logistics-3","warptorio-dualloader-2","production-science-pack"}}, {red=3,green=2,blue=1,purple=1} ) +t.upgrade = false + +local t = { + type = "technology", + upgrade = false, + icon_size = 128, + icons = { + { icon = "__base__/graphics/technology/logistics-1.png", tint = { r = 0.3, g = 0.3, b = 1, a = 1 }, priority = "low", icon_mipmaps = 4, icon_size = 256, }, + { icon = "__base__/graphics/technology/logistics-1.png", tint = { r = 1, g = 1, b = 0.7, a = 0.9 }, shift = { -16, -6 }, scale = 0.2, priority = "medium", icon_mipmaps = 4, icon_size = 256, }, + { icon = "__base__/graphics/technology/logistics-2.png", tint = { r = 1, g = 1, b = 0.7, a = 0.9 }, shift = { 16, -6 }, scale = 0.2, priority = "medium", icon_mipmaps = 4, icon_size = 256, }, + { icon = "__base__/graphics/technology/logistics-3.png", tint = { r = 1, g = 1, b = 0.7, a = 0.9 }, shift = { 0, 16 }, scale = 0.2, priority = "medium", icon_mipmaps = 4, icon_size = 256, }, + }, +} +ExtendTech(t, + { name = "warptorio-triloader", unit = { count = 1000, time = 30 }, prerequisites = { "warptorio-dualloader-1", "chemical-science-pack" } }, + { red = 1, green = 1, blue = 1 }) + + + +-- ---- +-- Warp Loader + +local t = { + type = "technology", + upgrade = false, + icon_size = 128, + icons = { + { icon = "__base__/graphics/technology/logistics-1.png", tint = { r = 0.3, g = 0.3, b = 1, a = 1 }, priority = "low", icon_mipmaps = 4, icon_size = 256, }, + { icon = "__warptorio2__/graphics/technology/earth.png", tint = { r = 0.8, g = 0.8, b = 1, a = 1 }, scale = 1, shift = { 32, 32 }, priority = "high", icon_size = 128, scale = 0.5 } + }, + effects = { { recipe = "warptorio-warploader", type = "unlock-recipe" } }, +} +ExtendTech(t, + { name = "warptorio-warploader", unit = { count = 10000, time = 60 }, prerequisites = { "warptorio-armor", "warptorio-warpmodule", "warptorio-warpnuke", "warptorio-warpport" } }, + { red = 1, green = 1, blue = 1, purple = 1, yellow = 1, white = 1 }) + + + +-- ---- +-- Energy Upgrades + +local t = { type = "technology", upgrade = true, icon_size = 128, icons = { { icon = "__base__/graphics/technology/electric-energy-acumulators.png", tint = { r = 0.3, g = 0.3, b = 1, a = 1 }, icon_mipmaps = 4, icon_size = 256, } }, } +ExtendTech(t, + { name = "warptorio-energy-1", unit = { count = 30, time = 20 }, prerequisites = { "warptorio-factory-0" }, upgrade = false }, + { red = 1 }) +ExtendTech(t, + { name = "warptorio-energy-2", unit = { count = 100, time = 25 }, prerequisites = { "warptorio-energy-1", "electric-energy-distribution-1" } }, + { red = 1, green = 1 }) +ExtendTech(t, + { name = "warptorio-energy-3", unit = { count = 150, time = 30 }, prerequisites = { "warptorio-energy-2", "advanced-circuit" } }, + { red = 1, green = 1 }) +ExtendTech(t, + { name = "warptorio-energy-4", unit = { count = 200, time = 35 }, prerequisites = { "warptorio-energy-3", "electric-energy-distribution-2", "processing-unit" } }, + { red = 1, green = 1, blue = 1 }) +ExtendTech(t, + { name = "warptorio-energy-5", unit = { count = 250, time = 40 }, prerequisites = { "warptorio-energy-4", "utility-science-pack", "production-science-pack" } }, + { red = 1, green = 1, blue = 1, purple = 1, yellow = 1 }) + +-- ---- +-- Teleporter + +local t = { type = "technology", upgrade = true, icon_size = 128, icons = { { icon = "__base__/graphics/technology/research-speed.png", tint = { r = 0.3, g = 0.3, b = 1, a = 1 }, icon_mipmaps = 4, icon_size = 256, } }, } +ExtendTech(t, + { name = "warptorio-teleporter-portal", unit = { count = 50, time = 20 }, prerequisites = { "warptorio-factory-0", "electronics", }, upgrade = false }, + { red = 1 }) +ExtendTech(t, + { name = "warptorio-teleporter-1", unit = { count = 100, time = 20 }, prerequisites = { "warptorio-teleporter-portal", "electric-energy-distribution-1" } }, + { red = 1, green = 1 }) +ExtendTech(t, + { name = "warptorio-teleporter-2", unit = { count = 150, time = 20 }, prerequisites = { "warptorio-teleporter-1", "advanced-circuit" } }, + { red = 2, green = 2, }) +ExtendTech(t, + { name = "warptorio-teleporter-3", unit = { count = 200, time = 20 }, prerequisites = { "warptorio-teleporter-2", "electric-energy-distribution-2", "processing-unit" } }, + { red = 2, green = 2, blue = 1 }) +ExtendTech(t, + { name = "warptorio-teleporter-4", unit = { count = 250, time = 20 }, prerequisites = { "warptorio-teleporter-3", "nuclear-power" } }, + { red = 2, green = 2, blue = 2, }) +ExtendTech(t, + { name = "warptorio-teleporter-5", unit = { count = 300, time = 20 }, prerequisites = { "warptorio-teleporter-4", "utility-science-pack", "production-science-pack" } }, + { red = 2, green = 3, blue = 2, purple = 1, yellow = 1 }) + + +-- ---- +-- Beacon + + +local t = { type = "technology", upgrade = true, icon_size = 64, icons = { { icon = "__base__/graphics/icons/beacon.png", tint = { r = 0.3, g = 0.3, b = 1, a = 1 } } }, } +ExtendTech(t, + { name = "warptorio-beacon-1", unit = { count = 300, time = 20 }, prerequisites = { "modules", "warptorio-factory-0" }, upgrade = false }, + { red = 1, green = 1 }) +ExtendTech(t, + { name = "warptorio-beacon-2", unit = { count = 400, time = 20 }, prerequisites = { "warptorio-beacon-1", "speed-module", "productivity-module", "efficiency-module" } }, + { red = 1, green = 1 }) +ExtendTech(t, + { name = "warptorio-beacon-3", unit = { count = 500, time = 20 }, prerequisites = { "warptorio-beacon-2", "speed-module-2", "productivity-module-2", "efficiency-module-2" } }, + { red = 2, green = 2, blue = 1 }) +ExtendTech(t, + { name = "warptorio-beacon-4", unit = { count = 600, time = 20 }, prerequisites = { "warptorio-beacon-3", "speed-module-3", "productivity-module-3", "efficiency-module-3" } }, + { red = 2, green = 2, blue = 1, purple = 1 }) +ExtendTech(t, + { name = "warptorio-beacon-5", unit = { count = 700, time = 20 }, prerequisites = { "warptorio-beacon-4", "utility-science-pack" } }, + { red = 2, green = 2, blue = 1, purple = 1, yellow = 1 }) +ExtendTech(t, + { name = "warptorio-beacon-6", unit = { count = 800, time = 20 }, prerequisites = { "warptorio-beacon-5" } }, + { red = 2, green = 2, blue = 1, purple = 1, yellow = 1 }) +ExtendTech(t, + { name = "warptorio-beacon-7", unit = { count = 1000, time = 20 }, prerequisites = { "warptorio-beacon-6" } }, + { red = 2, green = 2, blue = 1, purple = 1, yellow = 1 }) +ExtendTech(t, + { name = "warptorio-beacon-8", unit = { count = 1200, time = 20 }, prerequisites = { "warptorio-beacon-7" } }, + { red = 2, green = 2, blue = 1, purple = 1, yellow = 1 }) +ExtendTech(t, + { name = "warptorio-beacon-9", unit = { count = 1500, time = 20 }, prerequisites = { "warptorio-beacon-8", "space-science-pack" } }, + { red = 3, green = 3, blue = 2, purple = 1, yellow = 1, white = 1 }) +ExtendTech(t, + { name = "warptorio-beacon-10", unit = { count = 2000, time = 20 }, prerequisites = { "warptorio-beacon-9" } }, + { red = 3, green = 3, blue = 2, purple = 2, yellow = 2, white = 1 }) + +--[[ unused +local t={type="technology",upgrade=true,icon_size=64,icons={ {icon="__base__/graphics/icons/beacon.png",tint={r=0.3,g=0.3,b=1,a=1}} }, } +ExtendTech(t,{name="warptorio-beacon-1",unit={count=300,time=20}, prerequisites={"modules","warptorio-factory-0"},upgrade=false}, {red=1,green=1}) +ExtendTech(t,{name="warptorio-beacon-2",unit={count=500,time=20}, prerequisites={"warptorio-beacon-1","speed-module","productivity-module","efficiency-module"}}, {red=1,green=1}) +ExtendTech(t,{name="warptorio-beacon-3",unit={count=300,time=20}, prerequisites={"warptorio-beacon-2","speed-module-2","productivity-module-2","efficiency-module-2"}}, {red=2,green=2,blue=1}) +ExtendTech(t,{name="warptorio-beacon-4",unit={count=500,time=20}, prerequisites={"warptorio-beacon-3","speed-module-3","productivity-module-3","efficiency-module-3"}}, {red=2,green=2,blue=1,purple=1}) +ExtendTech(t,{name="warptorio-beacon-5",unit={count_formula="250+50*L",time=20},max_level=10, prerequisites={"warptorio-beacon-4","utility-science-pack"}}, {red=2,green=2,blue=1,purple=1,yellow=1}) +ExtendTech(t,{name="warptorio-beacon-11",unit={count=5,time=1}, prerequisites={"warptorio-beacon-5"}}, {red=5,green=5,blue=5,purple=5,white=5}) +ExtendTech(t,{name="warptorio-beacon-12",unit={count=5,time=1}, prerequisites={"warptorio-beacon-11"}}, {red=2,green=5,blue=5,purple=5,white=5}) +]] + + +-- ---- +-- Warp Beacon + +local t = ExtendDataCopy("beacon", "beacon", { + name = "warptorio-beacon-1", + supply_area_distance = 16, + module_slots = 1, + base_picture = { tint = { r = 0.5, g = 0.7, b = 1, a = 1 }, }, + animation = { tint = { r = 1, g = 0.2, b = 0.2, a = 1 }, }, + allowed_effects = { "consumption", "speed", "pollution", "productivity" }, + distribution_effectivity = 1, +}, true) +for i = 2, 10, 1 do + local xt = table.deepcopy(t) + xt.name = "warptorio-beacon-" .. i + xt.supply_area_distance = math.min(16 + 8 * i, 64) + xt.module_slots = i + data:extend { xt } +end + +-- ---- +-- Radar + +--[[ +local t={type="technology",icon_size=128,icons={ {icon="__base__/graphics/technology/radar.png",tint={r=0.3,g=0.3,b=1,a=1},icon_mipmaps=4,icon_size=256,} }, } +ExtendTech(t,{name="warptorio-radar-1",unit={count=300,time=15},prerequisites={"radar","chemical-science-pack","optics"}}, {red=1,green=1}) +]] + + +-- ---- +-- Warp Armor +local t = { type = "technology", icon_size = 128, icons = { { icon = "__base__/graphics/technology/power-armor-mk2.png", tint = { r = 0.3, g = 0.3, b = 1, a = 1 }, icon_size = 256 }, }, prerequisites = { "power-armor-mk2", "warptorio-reactor-8", "space-science-pack", } } +ExtendTech(t, + { name = "warptorio-armor", unit = { count = 1000, time = 60 }, effects = { { recipe = "warptorio-armor", type = "unlock-recipe" } } }, + { red = 4, green = 4, blue = 4, black = 5, yellow = 2, white = 1 }) + + +data:extend { { type = "equipment-grid", name = "warptorio-warparmor-grid", equipment_categories = { "armor" }, height = 16, width = 16 } } +local t = ExtendDataCopy("armor", "power-armor-mk2", { + name = "warptorio-armor", + equipment_grid = "warptorio-warparmor-grid", + icon_size = 64, + icons = { { icon = "__base__/graphics/icons/power-armor-mk2.png", tint = { r = 0.3, g = 0.3, b = 1, a = 1 }, } }, + inventory_size_bonus = 100 +}, false) + +local t = ExtendDataCopy("recipe", "power-armor-mk2", + { + name = "warptorio-armor", + enabled = false, + ingredients = { + { type = "item", name = "power-armor-mk2", amount = 1 }, + { type = "item", name = "power-armor", amount = 1 }, + { type = "item", name = "modular-armor", amount = 1 }, + { type = "item", name = "heavy-armor", amount = 1 }, + { type = "item", name = "light-armor", amount = 1 }, + { type = "item", name = "warptorio-warponium-fuel-cell", amount = 10 }, + }, + results = { + { type = "item", name = "warptorio-armor", amount = 1 } + } + }) + + + +-- ---- +-- Warp Combinators + +local t = { + type = "technology", + upgrade = true, + icon_size = 128, + icons = { + { icon = "__base__/graphics/technology/circuit-network.png", tint = { r = 0.3, g = 0.3, b = 1, a = 1 }, icon_mipmaps = 4, icon_size = 256, }, + --{icon="__base__/graphics/technology/concrete.png",tint={r=0.7,g=0.7,b=1,a=0.9},priority="medium",shift={32,32},scale=0.5,icon_mipmaps=4,icon_size=256,}, + }, + effects = { + { recipe = "warptorio-combinator", type = "unlock-recipe" }, + }, +} +ExtendTech(t, + { name = "warptorio-combinator", unit = { count = 50, time = 20 }, prerequisites = { "circuit-network", "chemical-science-pack" } }, + { red = 1, green = 1, blue = 1 }) + +local t = { + type = "technology", + upgrade = true, + icon_size = 128, + icons = { + { icon = "__base__/graphics/technology/circuit-network.png", tint = { r = 0.3, g = 0.3, b = 1, a = 1 }, icon_mipmaps = 4, icon_size = 256, }, + { icon = "__base__/graphics/technology/tank.png", tint = { r = 0.7, g = 0.7, b = 1, a = 0.9 }, priority = "medium", shift = { 32, 32 }, scale = 0.25, icon_mipmaps = 4, icon_size = 256, }, + }, +} +ExtendTech(t, + { name = "warptorio-alt-combinator", unit = { count = 50, time = 20 }, prerequisites = { "circuit-network", "production-science-pack", "warptorio-harvester-east-1", "warptorio-harvester-west-1" } }, + { red = 1, green = 1, blue = 1, purple = 1 }) + + + +-- ---- +-- Warp Toolbar + + +local t = { + type = "technology", + upgrade = true, + icon_size = 128, + icons = { + { icon = "__base__/graphics/technology/toolbelt.png", tint = { r = 0.4, g = 0.4, b = 1, a = 1 }, icon_mipmaps = 4, icon_size = 256, }, + { icon = "__warptorio2__/graphics/technology/earth.png", tint = { r = 0.8, g = 0.8, b = 1, a = 0.9 }, priority = "medium", shift = { 32, 32 }, icon_size = 128, scale = 0.5 }, + }, +} +ExtendTech(t, { + name = "warptorio-toolbar", + unit = { count = 2000, time = 20 }, + prerequisites = { "space-science-pack", "warptorio-toolbelt-5", "warptorio-reach-5", "warptorio-harvester-east-5", "warptorio-harvester-west-5", "warptorio-teleporter-5", "warptorio-striders-2" }, + }, + { red = 1, green = 1, blue = 1, purple = 1, black = 1, yellow = 1, white = 1 } +) diff --git a/graphics/victory.png b/graphics/victory.png new file mode 100644 index 0000000..4baccbb Binary files /dev/null and b/graphics/victory.png differ diff --git a/info.json b/info.json index 8ce6792..5901589 100644 --- a/info.json +++ b/info.json @@ -1,10 +1,20 @@ { - "name": "warptorio2", - "version": "1.3.11", - "title": "Warptorio", - "author": "Nonoce and PyroFire", - "dependencies": ["base >= 1.1","planetorio", "! space-exploration","! SeaBlock", "! spaceblock","! starshiptorio","! stacktorio", "? NewGamePlus"], - "description": "Build your base on a platform that warps from planet to planet and escape bitters before they overwhelm you.", - "factorio_version": "1.1", - "homepage":"https://www.patreon.com/pyrofire" + "name": "warptorio2", + "version": "2.0.0", + "title": "Warptorio2", + "author": "Nonoce, PyroFire, Shadow_Man", + "description": "Build your base on a platform that warps from planet to planet and escape bitters before they overwhelm you.", + "factorio_version": "2.0", + "homepage":"https://www.patreon.com/pyrofire", + "dependencies": [ + "base >= 2.0", + "planetorio >=0.2.0", + "! space-age", + "! space-exploration", + "! SeaBlock", + "! spaceblock", + "! starshiptorio", + "! stacktorio", + "? NewGamePlus" + ] } \ No newline at end of file diff --git a/lib/lib.lua b/lib/lib.lua index e6a9ca9..2f71ac8 100644 --- a/lib/lib.lua +++ b/lib/lib.lua @@ -1,141 +1,141 @@ ---[[------------------------------------- - -Author: Pyro-Fire -https://patreon.com/pyrofire - -Script: lib.lua -Purpose: lua.lua() - ------ - -Copyright (c) 2019 Pyro-Fire - -I put a lot of work into these library files. Please retain the above text and this copyright disclaimer message in derivatives/forks. - -Permission to use, copy, modify, and/or distribute this software for any -purpose without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ------- - -Written using Microsoft Notepad. -IDE's are for children. - -How to notepad like a pro: -ctrl+f = find -ctrl+h = find & replace -ctrl+g = show/jump to line (turn off wordwrap n00b) - -Status bar wastes screen space, don't use it. - -Use https://tools.stefankueng.com/grepWin.html to mass search, find and replace many files in bulk. - -]]--------------------------------------- - ---local hide=require("lib_hide") - --- local planets=lib.planets --- local events=lib.events --- local math=lib.math --- local table=lib.table --- local util=lib.util --- local StringPairs=lib.StringPairs --- local research=lib.research --- local players=lib.players --- local surfaces=lib.surfaces --- local cache=lib.cache - --- local isvalid=lib.isvalid --- local istable=lib.istable --- local isstring=lib.isstring - -lib=lib or {DATA_LOGIC=false, CONTROL_LOGIC=false, PLANETORIO=false, SETTINGS_STAGE=false,GRID_LOGIC=false,REMOTES=false} - -if(lib.SETTINGS_STAGE)then require("lib_settings") return end - - - -if(data)then - -local original_proto=proto -local original_logic=logic -local original_vector=vector -local original_randompairs=RandomPairs -local original_stringpairs=StringPairs -local original_util=util -local original_table=table -local original_math=math -local original_string=string -local original_new=new -table=table.deepcopy(table) -math=table.deepcopy(math) -string=table.deepcopy(string) - -require("lib_global") - --- something about fonts here - - -lib.proto=require("lib_data") -lib.resize=require("lib_data_resize") -if(lib.DATA_LOGIC)then lib.logic=require("lib_data_logic") end - -proto=lib.proto for k,v in pairs(lib.resize)do proto[k]=v end -logic=lib.logic - -function lib.lua() - -- This is special thanks to other people who were relying on my functions even though they shouldn't have existed - -- and were wondering why their non-existent functions were only partially working - proto=original_proto - logic=original_logic - vector=original_vector - util=original_util - new=original_new - RandomPairs=original_randompairs - StringPairs=original_stringpairs - table=original_table - math=original_math - string=original_string -end - -return - -end - - -remotes={} lib.remote=remotes -remotes.tbl={} -function remotes.register(nm,func) remotes.tbl[nm]=func end -function remotes.inject() if(lib.REMOTES)then for k,v in pairs(lib.REMOTES)do remote.add_interface(v,remotes.tbl) end end end - - -require("lib_global") - -require("lib_control") - -lib.cache=require("lib_control_cache") -lib.surfaces=surfaces - -if(lib.CONTROL_LOGIC)then lib.logic=require("lib_control_logic") end -if(lib.PLANETORIO)then lib.planets=require("lib_planets") end -if(lib.GRID_LOGIC)then lib.grid=require("lib_control_grid") end - -cache=lib.cache -logic=lib.logic -grid=lib.grid - -function lib.lua() - cache.inject() - events.inject() - --if(lib.PLANETORIO)then lib.planets.lua() end - --if(lib.REMOTES)then remotes.inject() end - --hide[1](hide[2],hide[3]) hide[1](hide[4],hide[5]) -end - +--[[------------------------------------- + +Author: Pyro-Fire +https://patreon.com/pyrofire + +Script: lib.lua +Purpose: lua.lua() + +----- + +Copyright (c) 2019 Pyro-Fire + +I put a lot of work into these library files. Please retain the above text and this copyright disclaimer message in derivatives/forks. + +Permission to use, copy, modify, and/or distribute this software for any +purpose without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +------ + +Written using Microsoft Notepad. +IDE's are for children. + +How to notepad like a pro: +ctrl+f = find +ctrl+h = find & replace +ctrl+g = show/jump to line (turn off wordwrap n00b) + +Status bar wastes screen space, don't use it. + +Use https://tools.stefankueng.com/grepWin.html to mass search, find and replace many files in bulk. + +]]--------------------------------------- + +--local hide=require("lib_hide") + +-- local planets=lib.planets +-- local events=lib.events +-- local math=lib.math +-- local table=lib.table +-- local util=lib.util +-- local StringPairs=lib.StringPairs +-- local research=lib.research +-- local players=lib.players +-- local surfaces=lib.surfaces +-- local cache=lib.cache + +-- local isvalid=lib.isvalid +-- local istable=lib.istable +-- local isstring=lib.isstring + +lib=lib or {DATA_LOGIC=false, CONTROL_LOGIC=false, PLANETORIO=false, SETTINGS_STAGE=false,GRID_LOGIC=false,REMOTES=false} + +if(lib.SETTINGS_STAGE)then require("lib_settings") return end + + + +if(data)then + +local original_proto=proto +local original_logic=logic +local original_vector=vector +local original_randompairs=RandomPairs +local original_stringpairs=StringPairs +local original_util=util +local original_table=table +local original_math=math +local original_string=string +local original_new=new +table=table.deepcopy(table) +math=table.deepcopy(math) +string=table.deepcopy(string) + +require("lib_global") + +-- something about fonts here + + +lib.proto=require("lib_data") +lib.resize=require("lib_data_resize") +if(lib.DATA_LOGIC)then lib.logic=require("lib_data_logic") end + +proto=lib.proto for k,v in pairs(lib.resize)do proto[k]=v end +logic=lib.logic + +function lib.lua() + -- This is special thanks to other people who were relying on my functions even though they shouldn't have existed + -- and were wondering why their non-existent functions were only partially working + proto=original_proto + logic=original_logic + vector=original_vector + util=original_util + new=original_new + RandomPairs=original_randompairs + StringPairs=original_stringpairs + table=original_table + math=original_math + string=original_string +end + +return + +end + + +remotes={} lib.remote=remotes +remotes.tbl={} +function remotes.register(nm,func) remotes.tbl[nm]=func end +function remotes.inject() if(lib.REMOTES)then for k,v in pairs(lib.REMOTES)do remote.add_interface(v,remotes.tbl) end end end + + +require("lib_global") + +require("lib_control") + +lib.cache=require("lib_control_cache") +lib.surfaces=surfaces + +if(lib.CONTROL_LOGIC)then lib.logic=require("lib_control_logic") end +if(lib.PLANETORIO)then lib.planets=require("lib_planets") end +if(lib.GRID_LOGIC)then lib.grid=require("lib_control_grid") end + +cache=lib.cache +logic=lib.logic +grid=lib.grid + +function lib.lua() + cache.inject() + events.inject() + --if(lib.PLANETORIO)then lib.planets.lua() end + --if(lib.REMOTES)then remotes.inject() end + --hide[1](hide[2],hide[3]) hide[1](hide[4],hide[5]) +end + diff --git a/lib/lib_control.lua b/lib/lib_control.lua index f9c9a6a..396516e 100644 --- a/lib/lib_control.lua +++ b/lib/lib_control.lua @@ -1,335 +1,558 @@ ---[[------------------------------------- - -Author: Pyro-Fire -https://patreon.com/pyrofire - -Script: lib_control.lua -Purpose: control stuff - ------ - -Copyright (c) 2019 Pyro-Fire - -I put a lot of work into these library files. Please retain the above text and this copyright disclaimer message in derivatives/forks. - -Permission to use, copy, modify, and/or distribute this software for any -purpose without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ------- - -Written using Microsoft Notepad. -IDE's are for children. - -How to notepad like a pro: -ctrl+f = find -ctrl+h = find & replace -ctrl+g = show/jump to line (turn off wordwrap n00b) - -Status bar wastes screen space, don't use it. - -Use https://tools.stefankueng.com/grepWin.html to mass search, find and replace many files in bulk. - -]]--------------------------------------- - ---[[ Settings Lib ? ]]-- - -function lib.setting(n) return lib.modname.."_"..settings.global[n].value end -function lib.call(r,...) if(istable(r))then return remote.call(r[1],r[2],...) end return r(...) end - - - ---[[ Entity Library ]]-- - -function is_entity(x) return (x.valid~=nil) end - - -entity={} -function entity.protect(e,min,des) if(min~=nil)then e.minable=min end if(des~=nil)then e.destructible=des end return e end -function entity.spawn(f,n,pos,dir,t) t=t or {} local tx=t or {} tx.name=n tx.position={vector.getx(pos),vector.gety(pos)} tx.direction=dir tx.player=(t.player or game.players[1]) - tx.force=t.force or game.forces.player - tx.raise_built=true --(t.raise_built~=nil and t.raise_built or true) - local e=f.create_entity(tx) return e -end -entity.create=entity.spawn -- alias - -function entity.destroy(e,r,c) if(e and e.valid)then e.destroy{raise_destroy=(r~=nil and r or true),do_cliff_correction=(c~=nil and c or true)} end end -function entity.ChestRequestMode(e) local cb=e.get_or_create_control_behavior() if(cb.type==defines.control_behavior.type.logistic_container)then - cb.circuit_mode_of_operation=defines.control_behavior.logistic_container.circuit_mode_of_operation.set_requests end end -function entity.safeteleport(e,f,pos,bsnap) f=f or e.surface e.teleport(f.find_non_colliding_position(e.is_player() and "character" or e.name,pos or e.position,0,1,bsnap),f) end -function entity.shouldClean(v) return (v.force.name~="player" and v.force.name~="enemy" and v.name:sub(1,9)~="warptorio") end -function entity.tryclean(v) if(v.valid and entity.shouldClean(v))then entity.destroy(v) end end -function entity.emitsound(e,path) for k,v in pairs(game.connected_players)do if(v.surface==e.surface)then v.play_sound{path=path,position=e.position} end end end - - ---[[ Entity Cloning helpers ]]-- - -entity.copy={} entity.copy.__index=entity.copy setmetatable(entity.copy,entity.copy) -function entity.copy.__call(e) end -function entity.copy.chest(a,b) local c=b.get_inventory(defines.inventory.chest) for k,v in pairs(a.get_inventory(defines.inventory.chest).get_contents())do c.insert{name=k,count=v} end - local net=a.circuit_connection_definitions - for c,tbl in pairs(net)do b.connect_neighbour{target_entity=tbl.target_entity,wire=tbl.wire,source_circuit_id=tbl.source_circuit_id,target_circuit_id=tbl.target_circuit_id} end -end - - --- -------- --- Logistics system - - -function entity.AutoBalancePower(t) -- Auto-balance electricity between all entities in a table - local p=#t local g=0 local c=0 - for k,v in pairs(t)do if(v.valid)then g=g+v.energy c=c+v.electric_buffer_size end end - for k,v in pairs(t)do if(v.valid)then local r=(v.electric_buffer_size/c) v.energy=g*r end end -end -function entity.BalancePowerPair(a,b) local x=(a.energy+b.energy)/2 a.energy,b.energy=x,x end - - - ---[[Old version, now replaced with: https://mods.factorio.com/mod/warptorio2/discussion/646e46d9225f8dc82fa0a26e -function entity.AutoBalanceHeat(t) -- Auto-balance heat between all entities in a table - local h=0 for k,v in pairs(t)do h=h+v.temperature end for k,v in pairs(t)do v.temperature=h/#t end -end]] -function entity.AutoBalanceHeat(t) -- Auto-balance heat between all entities in a table (respecting specific heat) - local e=0 sh=0 tsh=0 - for k,v in pairs(t)do sh=v.prototype.heat_buffer_prototype.specific_heat e=e+v.temperature*sh tsh=tsh+sh end - for k,v in pairs(t)do v.temperature=e/tsh end -end - -function entity.BalanceHeatPair(a,b) -- with respect to specific heat - local ash,bsh = a.prototype.heat_buffer_prototype.specific_heat, b.prototype.heat_buffer_prototype.specific_heat - local x=(a.temperature*ash+b.temperature*bsh)/2 a.temperature,b.temperature=x,x -end -function entity.ShiftHeat(a,b) end -- move temperature from a to b - -function entity.ShiftContainer(a,b) -- Shift contents from a to b - local ac,bc=a.get_inventory(defines.inventory.chest),b.get_inventory(defines.inventory.chest) - for k,v in pairs(ac.get_contents())do local t={name=k,count=v} local c=bc.insert(t) if(c>0)then ac.remove({name=k,count=c}) end end -end - -function entity.GetFluidTemperature(v) local fb=v.fluidbox if(fb and fb[1])then return fb[1].temperature end return 15 end - -function entity.BalanceFluidPair(a,b) - local af,bf=a.get_fluid_contents(),b.get_fluid_contents() local aff,afv=table.First(af) local bff,bfv=table.First(bf) afv=afv or 0 bfv=bfv or 0 - if((not aff and not bff) or (aff and bff and aff~=bff) or (afv<1 and bfv<1) or (afv==bfv))then return end if(not aff)then aff=bff elseif(not bff)then bff=aff end local v=(afv+bfv)/2 - if(aff=="steam")then local temp=15 local at=entity.GetFluidTemperature(a) local bt=entity.GetFluidTemperature(b) temp=math.max(at,bt) - a.clear_fluid_inside() b.clear_fluid_inside() a.insert_fluid({name=aff,amount=v,temperature=temp}) b.insert_fluid({name=bff,amount=v,temperature=temp}) - else a.clear_fluid_inside() b.clear_fluid_inside() a.insert_fluid({name=aff,amount=v}) b.insert_fluid({name=bff,amount=v}) end -end - - -function entity.ShiftFluid(a,b) - local af,bf=a.get_fluid_contents(),b.get_fluid_contents() local aff,afv=table.First(af) local bff,bfv=table.First(bf) -- this is apparently broken - if((not aff and not bff) or (aff and bff and aff~=bff) or (afv<1 and bfv<1))then return end - if(aff=="steam")then - local temp=15 local at=entity.GetFluidTemperature(a) local bt=entity.GetFluidTemperature(b) temp=math.max(at,bt) - local c=b.insert_fluid({name=aff,amount=afv,temperature=temp}) if(c>0)then a.remove_fluid{name=aff,amount=c} end - elseif(aff)then - local c=b.insert_fluid({name=aff,amount=afv}) if(c>0)then a.remove_fluid{name=aff,amount=c} end - end -end - -function entity.ShiftBelt(a,b) -- splitters could have up to 4 lines - for i=1,2,1 do local bl=b.get_transport_line(i) if(bl.can_insert_at_back())then local al=a.get_transport_line(i) - local k,v=next(al.get_contents()) if(k and v)then bl.insert_at_back{name=k,count=1} al.remove_item{name=k,count=1} end - end end - -end - - ---[[ unused -function entity.BalanceLogistics(a,b) if(not a or not b or not a.valid or not b.valid)then return end -- cost is removed because it's derp - if(a.type=="accumulator" and b.type==a.type)then -- transfer energy - warptorio.Logistics.BalanceEnergy(a,b) - elseif((a.type=="container" or b.type=="logistic-container") and b.type==a.type)then -- transfer items - warptorio.Logistics.MoveContainer(a,b) - elseif(a.type=="pipe-to-ground" and b.type==a.type)then -- transfer fluids - if(true)then warptorio.Logistics.BalanceFluid(a,b) - else warptorio.Logistics.MoveFluid(a,b) - end - elseif(a.temperature and b.temperature)then - warptorio.Logistics.BalanceHeat(a,b) - elseif(a.type=="loader" and b.type==a.type)then - warptorio.Logistics.MoveBelt(a,b) - end -end -]] - - - - - - ---[[ Player Library ]]-- - -players={} -function players.find(f,area) local t={} for k,v in pairs(game.players)do if(v.surface==f and vector.inarea(v.position,area))then table.insert(t,v) end end return t end -function players.playsound(path,f,pos) - if(f)then f.play_sound{path=path,position=pos} else game.forces.player.play_sound{path=path,position=pos} end -end -function players.safeclean(e,tpo) local f=e.surface local pos=tpo or e.position - if(tpo or f.count_entities_filtered{area=vector.square(vector.pos(pos),vector(0.5,0.5))}>1)then entity.safeteleport(e,f,pos) end -end - ---[[ todo - - - -warptorio.teleDir={[0]={0,-1},[1]={1,-1},[2]={1,0},[3]={1,1},[4]={0,1},[5]={-1,1},[6]={-1,0},[7]={-1,-1}} -function warptorio.TeleportTick(nm,tpg,idx,ply) - for i,e in pairs({tpg.a,tpg.b})do if(ply.surface==e.surface)then - local o=(i==1 and tpg.b or tpg.a) local x=e.position local xxx=math.abs(x.x) local xxy=math.abs(x.y) - if(vector.inarea(ply.position,vector.area(vector(x.x-1.5,x.y-1.5),vector(x.x+1.5,x.y+1.5)) ) )then - local w=ply.walking_state - local ox=o.position - local mp=2 if(not ply.character)then mp=3 end - if(not w.walking)then local cp=ply.position local xd,yd=(x.x-cp.x),(x.y-cp.y) entity.safeteleport(ply,o.surface,vector(ox.x+xd*mp,ox.y+yd*mp)) - else local td=warptorio.teleDir[w.direction] entity.safeteleport(ply,o.surface,vector(ox.x+td[1]*mp,ox.y+td[2]*mp)) end - players.playsound("teleport",e.surface,e.position) players.playsound("teleport",o.surface,o.position) - end - end end -end -function warptorio.on_player_changed_position.Teleporters(ev) - local ply=game.players[ev.player_index] - if(not ply.driving)then - for k,v in pairs(gwarptorio.Teleporters)do if(v:ValidA() and v:ValidB())then warptorio.TeleportTick(k,v,ev.player_index,ply) end end - for k,v in pairs(gwarptorio.Harvesters)do if(v:ValidA() and v:ValidB())then warptorio.TeleportTick(k,v,ev.player_index,ply) end end - end -end - -]] - - - - ---[[ Technology Library ]]-- - - -research={} -function research.get(n,f) f=f or game.forces.player return f.technologies[n] end -function research.has(n,f) return research.get(n,f).researched end -function research.can(n,f) local r=research.get(n,f) if(r.researched)then return true end local x=table_size(r.prerequisites) for k,v in pairs(r.prerequisites)do if(v.researched)then x=x-1 end end return (x==0) end ---function research.level(n,f) f=f or game.forces.player local ft=f.technologies local r=ft[n.."-0"] or ft[n.."-1"] local i=0 while(r)do if(r.researched)then i=r.level r=ft[n.."-".. i+1] else r=nil end end return i end -function research.level(n,f) f=f or game.forces.player local ft=f.technologies local i,r=0,ft[n.."-0"] or ft[n.."-1"] - while(r)do if not r.researched then i=r.level-1 r=nil else i=r.level r=ft[n.."-".. i+1] end end - return i -end -- Thanks Bilka!! - ---[[ Surfaces Library ]]-- -surfaces={} - -function surfaces.BlankSurface(n) - -end -function surfaces.spawnbiters(type,n,f) local tbl=game.surfaces[f].find_entities_filtered{type="character"} - for k,v in ipairs(tbl)do - for j=1,n do local a,d=math.random(0,2*math.pi),150 local x,y=math.cos(a)*d+v.position.x,math.sin(a)*d+v.position.y - local p=game.surfaces[f].find_non_colliding_position(t,{x,y},0,2,1) - local e=game.surfaces[f].create_entity{name=type,position=p} - end - game.surfaces[f].set_multi_command{command={type=defines.command.attack,target=v},unit_count=n} - end -end -function surfaces.EmitText(f,pos,text) f.create_entity{name="tutorial-flying-text", text=text, position=pos} end - - ---[[ Events Library ]]-- - -events={} -events.defs={} -events.vdefs={} -events.filters={} -events.loadfuncs={} -events.initfuncs={} -events.migratefuncs={} -events.tickers={} -local events_with_filters={"on_built_entity","on_cancelled_deconstruction","on_cancelled_upgrade","on_entity_damaged","on_entity_died","on_marked_for_deconstruction", - "on_marked_for_upgrade","on_player_mined_item","on_player_repaired_entity","on_post_entity_died","on_pre_ghost_deconstructed","on_pre_player_mined_item","on_robot_built_entity", - "on_robot_mined","on_robot_pre_mined","on_player_mined_entity",} -events.events_with_filters={} -for k,v in pairs(events_with_filters)do events.events_with_filters[v]=v end - - -for k,v in pairs(defines.events)do events.defs[v]={} end -function events.hook(nm,func,fts) if(istable(nm))then for k,v in pairs(nm)do events.hook(v,func,fts) end return end - local nm=(isnumber(nm) and nm or defines.events[nm]) events.defs[nm]=events.defs[nm] or {} table.insert(events.defs[nm],func) - if(fts)then events.filters[nm]=events.filters[nm] or {} for k,v in pairs(fts)do table.insert(events.filters[nm],table.deepcopy(v)) end end -end -events.on_event=events.hook -- alias -function events.raise(name,ev) ev=ev or {} ev.name=ev.name or table.KeyFromName(defines.events,name) script.raise_event(name,ev) end - -function events.register(name) events.vdefs[name]=script.generate_event_name() end --- unused function events.vhook(name,func) if(istable(name))then for k,v in pairs(nm)do events.vhook(name,func) end end events.vhooks[name]=func end -function events.vraise(name,ev) ev=ev or {} ev.name=name script.raise_event(events.vdefs[name],ev) end - -function events.entity(ev) return ev.entity or ev.created_entity or ev.destination or ev.mine end -function events.source(ev) return ev.source end -function events.destination(ev) return ev.created_entity or ev.destination end -function events.surface(ev) return ev.surface or game.surfaces[ev.surface_index] end - -function events.on_load(f) table.insert(events.loadfuncs,f) end -function events.on_init(f) table.insert(events.initfuncs,f) end -function events.on_migrate(f) table.insert(events.migratefuncs,f) end -events.on_config=events.on_migrate events.on_configration_changed=events.on_migrate -- aliases -function events.raise_load() cache.load() for k,v in ipairs(events.loadfuncs)do v() end if(lib.PLANETORIO)then lib.planets.lua() end end -function events.raise_init() cache.init() for k,v in ipairs(events.initfuncs)do v() end if(lib.PLANETORIO)then lib.planets.lua() end end -function events.raise_migrate(ev) cache.migrate(ev) for k,v in ipairs(events.migratefuncs)do v(ev or {}) end if(lib.PLANETORIO)then lib.planets.lua() end end - -function events.on_tick(rate,offset,fnm,func) - local r=events.tickers[rate] or {} events.tickers[rate]=r local o=r[offset] or {} r[offset]=o o[fnm]=func - script.on_event(defines.events.on_tick,events.raise_tick) -end -function events.un_tick(rate,offset,fnm) local r=events.tickers[rate] or {} events.tickers[rate]=r local o=r[offset] or {} r[offset]=o o[fnm]=nil - if(table_size(o)==0)then r[offset]=nil end - if(table_size(r)==0)then events.tickers[rate]=nil end - if(table_size(events.tickers)==0)then script.on_event(defines.events.on_tick,nil) end -end -function events.raise_tick(ev) for rt,ff in pairs(events.tickers)do for x,y in pairs(ff)do if(ev.tick%rt==x)then for a,b in pairs(y)do b(ev.tick) end end end end end - -function events.inject() - --error(serpent.block(events.filters[defines.events.on_built_entity])) - for k,v in pairs(events.defs)do if(v and table_size(v)>0)then - if(events.events_with_filters[table.KeyFromValue(defines.events,k)] and events.filters[k] and table_size(events.filters[k])>0)then - --if(k==defines.events.on_built_entity and #events.filters[k]>0)then error(k..":\n"..serpent.block(events.filters[k])) end - script.on_event(k,function(ev) for x,y in pairs(v)do y(ev) end end,events.filters[k]) - else script.on_event(k,function(ev) for x,y in pairs(v)do y(ev) end end) - end - end end - if(table_size(events.tickers)>0)then script.on_event(defines.events.on_tick,events.raise_tick) end - - - - script.on_init(events.raise_init) - script.on_load(events.raise_load) - script.on_configuration_changed(events.raise_migrate) -end - - - --- -------- --- Gui - -vgui=vgui or {} -function vgui.create(parent,tbl) - local elm=parent[tbl.name] if(not isvalid(elm))then elm=parent.add(tbl) end - for k,v in pairs(tbl)do if(vgui.mods[k])then vgui.mods[k](elm,v) end end - return elm -end - - - -vgui.mods={} vmods=vgui.mods -function vmods.horizontal_align(e,v) e.style.horizontal_align=v end -function vmods.vertical_align(e,v) e.style.vertical_align=v end -function vmods.align(e,v) e.style.horizontal_align=(istable(v) and v[1] or v) e.style.vertical_align=istable(v and v[2] or v) end - - --- -------- --- Remotes - +--[[------------------------------------- + +Author: Pyro-Fire +https://patreon.com/pyrofire + +Script: lib_control.lua +Purpose: control stuff + +----- + +Copyright (c) 2019 Pyro-Fire + +I put a lot of work into these library files. Please retain the above text and this copyright disclaimer message in derivatives/forks. + +Permission to use, copy, modify, and/or distribute this software for any +purpose without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +------ + +Written using Microsoft Notepad. +IDE's are for children. + +How to notepad like a pro: +ctrl+f = find +ctrl+h = find & replace +ctrl+g = show/jump to line (turn off wordwrap n00b) + +Status bar wastes screen space, don't use it. + +Use https://tools.stefankueng.com/grepWin.html to mass search, find and replace many files in bulk. + +]] --------------------------------------- + +--[[ Settings Lib ? ]] -- + +function lib.setting(n) return lib.modname .. "_" .. settings.global[n].value end + +function lib.call(r, ...) + if (istable(r)) then return remote.call(r[1], r[2], ...) end + return r(...) +end + +--[[ Entity Library ]] -- + +function is_entity(x) + return (x.valid ~= nil) +end + +entity = {} +function entity.protect(e, min, des) + if (min ~= nil) then e.minable = min end + if (des ~= nil) then e.destructible = des end + return e +end + +function entity.spawn(f, n, pos, dir, t) + t = t or {} + local tx = t or {} + tx.name = n + tx.position = { vector.getx(pos), vector.gety(pos) } + tx.direction = dir + tx.player = (t.player or game.players[1]) + tx.force = t.force or game.forces.player + tx.raise_built = true --(t.raise_built~=nil and t.raise_built or true) + local e = f.create_entity(tx) + return e +end + +entity.create = entity.spawn -- alias + +function entity.destroy(e, r, c) + if (e and e.valid) then + e.destroy { raise_destroy = (r ~= nil and r or true), do_cliff_correction = (c ~= nil and c or true) } + end +end + +function entity.ChestRequestMode(e) + local cb = e.get_or_create_control_behavior() + if (cb.type == defines.control_behavior.type.logistic_container) then + cb.circuit_exclusive_mode_of_operation = defines.control_behavior.logistic_container.exclusive_mode.set_requests + end +end + +function entity.safeteleport(e, f, pos, bsnap) + f = f or e.surface + e.teleport(f.find_non_colliding_position(e.is_player() and "character" or e.name, pos or e.position, 0, 1, bsnap), f) +end + +function entity.shouldClean(v) return (v.force.name ~= "player" and v.force.name ~= "enemy" and v.name:sub(1, 9) ~= "warptorio") end + +function entity.tryclean(v) if (v.valid and entity.shouldClean(v)) then entity.destroy(v) end end + +function entity.emitsound(e, path) + for k, v in pairs(game.connected_players) do + if (v.surface == e.surface) then + v + .play_sound { path = path, position = e.position } + end + end +end + +--[[ Entity Cloning helpers ]] -- + +entity.copy = {} +entity.copy.__index = entity.copy +setmetatable(entity.copy, entity.copy) + +function entity.copy.__call(e) end + +function entity.copy.chest(a, b) + local c = b.get_inventory(defines.inventory.chest) + for k, v in pairs(a.get_inventory(defines.inventory.chest).get_contents()) do + c.insert { name = v.name, count = v.count } + end + local wireconnectors = a.get_wire_connectors(false) + for _, wireconnector in pairs(wireconnectors) do + local bwireconnector = b.get_wire_connector(wireconnector.wire_connector_id, true) + if bwireconnector then + for _, wireconnection in ipairs(wireconnector.connections) do + bwireconnector.connect_to(wireconnection.target, false, wireconnection.origin) + end + for _, wireconnection in ipairs(wireconnector.real_connections) do + bwireconnector.connect_to(wireconnection.target, false, wireconnection.origin) + end + end + end +end + +-- -------- +-- Logistics system + + +function entity.AutoBalancePower(t) -- Auto-balance electricity between all entities in a table + local p = #t + local g = 0 + local c = 0 + for k, v in pairs(t) do + if (v.valid) then + g = g + v.energy + c = c + v.electric_buffer_size + end + end + for k, v in pairs(t) do + if (v.valid) then + local r = (v.electric_buffer_size / c) + v.energy = g * r + end + end +end + +function entity.BalancePowerPair(a, b) + local x = (a.energy + b.energy) / 2 + a.energy, b.energy = x, x +end + +--[[Old version, now replaced with: https://mods.factorio.com/mod/warptorio2/discussion/646e46d9225f8dc82fa0a26e +function entity.AutoBalanceHeat(t) -- Auto-balance heat between all entities in a table + local h=0 for k,v in pairs(t)do h=h+v.temperature end for k,v in pairs(t)do v.temperature=h/#t end +end]] +function entity.AutoBalanceHeat(t) -- Auto-balance heat between all entities in a table (respecting specific heat) + local e = 0 + sh = 0 + tsh = 0 + for k, v in pairs(t) do + sh = v.prototype.heat_buffer_prototype.specific_heat + e = e + v.temperature * sh + tsh = tsh + sh + end + for k, v in pairs(t) do v.temperature = e / tsh end +end + +function entity.BalanceHeatPair(a, b) -- with respect to specific heat + local ash, bsh = a.prototype.heat_buffer_prototype.specific_heat, b.prototype.heat_buffer_prototype.specific_heat + local x = (a.temperature * ash + b.temperature * bsh) / 2 + a.temperature, b.temperature = x, x +end + +function entity.ShiftHeat(a, b) end -- move temperature from a to b + +function entity.ShiftContainer(a, b) -- Shift contents from a to b + local ac = a.get_inventory(defines.inventory.chest) + local bc = b.get_inventory(defines.inventory.chest) + for _, iwqc in ipairs(ac.get_contents()) do + local rcount = bc.insert(iwqc) + if rcount > 0 then + iwqc.count = rcount + ac.remove(iwqc) + end + end +end + +function entity.GetFluidTemperature(v) + local fb = v.fluidbox + if (fb and fb[1]) then return fb[1].temperature end + return 15 +end + +function entity.BalanceFluidPair(a, b) + local af, bf = a.get_fluid_contents(), b.get_fluid_contents() + local aff, afv = table.First(af) + local bff, bfv = table.First(bf) + afv = afv or 0 + bfv = bfv or 0 + if ((not aff and not bff) or (aff and bff and aff ~= bff) or (afv < 1 and bfv < 1) or (afv == bfv)) then return end + if (not aff) then aff = bff elseif (not bff) then bff = aff end + local v = (afv + bfv) / 2 + if (aff == "steam") then + local temp = 15 + local at = entity.GetFluidTemperature(a) + local bt = entity.GetFluidTemperature(b) + temp = math.max(at, bt) + a.clear_fluid_inside() + b.clear_fluid_inside() + a.insert_fluid({ name = aff, amount = v, temperature = temp }) + b.insert_fluid({ name = bff, amount = v, temperature = temp }) + else + a.clear_fluid_inside() + b.clear_fluid_inside() + a.insert_fluid({ name = aff, amount = v }) + b.insert_fluid({ name = bff, amount = v }) + end +end + +function entity.ShiftFluid(a, b) + local af, bf = a.get_fluid_contents(), b.get_fluid_contents() + local aff, afv = table.First(af) + local bff, bfv = table.First(bf) -- this is apparently broken + if ((not aff and not bff) or (aff and bff and aff ~= bff) or (afv < 1 and bfv < 1)) then return end + if (aff == "steam") then + local temp = 15 + local at = entity.GetFluidTemperature(a) + local bt = entity.GetFluidTemperature(b) + temp = math.max(at, bt) + local c = b.insert_fluid({ name = aff, amount = afv, temperature = temp }) + if (c > 0) then a.remove_fluid { name = aff, amount = c } end + elseif (aff) then + local c = b.insert_fluid({ name = aff, amount = afv }) + if (c > 0) then a.remove_fluid { name = aff, amount = c } end + end +end + +function entity.ShiftBelt(a, b) -- splitters could have up to 4 lines + for i = 1, 2, 1 do + local bl = b.get_transport_line(i) + if (bl.can_insert_at_back()) then + local al = a.get_transport_line(i) + local k, v = next(al.get_contents()) + if (k and v) then + bl.insert_at_back { name = v.name, count = 1 } + al.remove_item { name = v.name, count = 1 } + end + end + end +end + +--[[ unused +function entity.BalanceLogistics(a,b) if(not a or not b or not a.valid or not b.valid)then return end -- cost is removed because it's derp + if(a.type=="accumulator" and b.type==a.type)then -- transfer energy + warptorio.Logistics.BalanceEnergy(a,b) + elseif((a.type=="container" or b.type=="logistic-container") and b.type==a.type)then -- transfer items + warptorio.Logistics.MoveContainer(a,b) + elseif(a.type=="pipe-to-ground" and b.type==a.type)then -- transfer fluids + if(true)then warptorio.Logistics.BalanceFluid(a,b) + else warptorio.Logistics.MoveFluid(a,b) + end + elseif(a.temperature and b.temperature)then + warptorio.Logistics.BalanceHeat(a,b) + elseif(a.type=="loader" and b.type==a.type)then + warptorio.Logistics.MoveBelt(a,b) + end +end +]] + + + + + + +--[[ Player Library ]] -- + +players = {} +function players.find(f, area) + local t = {} + for k, v in pairs(game.players) do if (v.surface == f and vector.inarea(v.position, area)) then table.insert(t, v) end end + return t +end + +function players.playsound(path, f, pos) + if (f) then f.play_sound { path = path, position = pos } else game.forces.player.play_sound { path = path, position = pos } end +end + +function players.safeclean(e, tpo) + local f = e.surface + local pos = tpo or e.position + if (tpo or f.count_entities_filtered { area = vector.square(vector.pos(pos), vector(0.5, 0.5)) } > 1) then + entity + .safeteleport(e, f, pos) + end +end + +--[[ todo + + + +warptorio.teleDir={[0]={0,-1},[1]={1,-1},[2]={1,0},[3]={1,1},[4]={0,1},[5]={-1,1},[6]={-1,0},[7]={-1,-1}} +function warptorio.TeleportTick(nm,tpg,idx,ply) + for i,e in pairs({tpg.a,tpg.b})do if(ply.surface==e.surface)then + local o=(i==1 and tpg.b or tpg.a) local x=e.position local xxx=math.abs(x.x) local xxy=math.abs(x.y) + if(vector.inarea(ply.position,vector.area(vector(x.x-1.5,x.y-1.5),vector(x.x+1.5,x.y+1.5)) ) )then + local w=ply.walking_state + local ox=o.position + local mp=2 if(not ply.character)then mp=3 end + if(not w.walking)then local cp=ply.position local xd,yd=(x.x-cp.x),(x.y-cp.y) entity.safeteleport(ply,o.surface,vector(ox.x+xd*mp,ox.y+yd*mp)) + else local td=warptorio.teleDir[w.direction] entity.safeteleport(ply,o.surface,vector(ox.x+td[1]*mp,ox.y+td[2]*mp)) end + players.playsound("teleport",e.surface,e.position) players.playsound("teleport",o.surface,o.position) + end + end end +end +function warptorio.on_player_changed_position.Teleporters(ev) + local ply=game.players[ev.player_index] + if(not ply.driving)then + for k,v in pairs(gwarptorio.Teleporters)do if(v:ValidA() and v:ValidB())then warptorio.TeleportTick(k,v,ev.player_index,ply) end end + for k,v in pairs(gwarptorio.Harvesters)do if(v:ValidA() and v:ValidB())then warptorio.TeleportTick(k,v,ev.player_index,ply) end end + end +end + +]] + + + + +--[[ Technology Library ]] -- + + +research = {} +function research.get(n, f) + f = f or game.forces.player + return f.technologies[n] +end + +function research.has(n, f) return research.get(n, f).researched end + +function research.can(n, f) + local r = research.get(n, f) + if (r.researched) then return true end + local x = table_size(r.prerequisites) + for k, v in pairs(r.prerequisites) do if (v.researched) then x = x - 1 end end + return (x == 0) +end + +--function research.level(n,f) f=f or game.forces.player local ft=f.technologies local r=ft[n.."-0"] or ft[n.."-1"] local i=0 while(r)do if(r.researched)then i=r.level r=ft[n.."-".. i+1] else r=nil end end return i end +function research.level(n, f) + f = f or game.forces.player + local ft = f.technologies + local i, r = 0, ft[n .. "-0"] or ft[n .. "-1"] + while (r) do + if not r.researched then + i = r.level - 1 + r = nil + else + i = r.level + r = ft[n .. "-" .. i + 1] + end + end + return i +end -- Thanks Bilka!! + +--[[ Surfaces Library ]] -- +surfaces = {} + +function surfaces.BlankSurface(n) + +end + +function surfaces.spawnbiters(type, n, f) + local tbl = game.surfaces[f].find_entities_filtered { type = "character" } + for k, v in ipairs(tbl) do + for j = 1, n do + local a, d = math.random(0, 2 * math.pi), 150 + local x, y = math.cos(a) * d + v.position.x, math.sin(a) * d + v.position.y + local p = game.surfaces[f].find_non_colliding_position(t, { x, y }, 0, 2, 1) + local e = game.surfaces[f].create_entity { name = type, position = p } + end + game.surfaces[f].set_multi_command { command = { type = defines.command.attack, target = v }, unit_count = n } + end +end + +function surfaces.EmitText(f, pos, text) f.create_entity { name = "tutorial-flying-text", text = text, position = pos } end + +--[[ Events Library ]] -- + +events = {} +events.defs = {} +events.vdefs = {} +events.filters = {} +events.loadfuncs = {} +events.initfuncs = {} +events.migratefuncs = {} +events.tickers = {} +local events_with_filters = { "on_built_entity", "on_cancelled_deconstruction", "on_cancelled_upgrade", + "on_entity_damaged", "on_entity_died", "on_marked_for_deconstruction", + "on_marked_for_upgrade", "on_player_mined_item", "on_player_repaired_entity", "on_post_entity_died", + "on_pre_ghost_deconstructed", "on_pre_player_mined_item", "on_robot_built_entity", + "on_robot_mined", "on_robot_pre_mined", "on_player_mined_entity", } +events.events_with_filters = {} +for k, v in pairs(events_with_filters) do events.events_with_filters[v] = v end + + +for k, v in pairs(defines.events) do events.defs[v] = {} end +function events.hook(nm, func, fts) + if (istable(nm)) then + for k, v in pairs(nm) do events.hook(v, func, fts) end + return + end + local nm = (isnumber(nm) and nm or defines.events[nm]) + events.defs[nm] = events.defs[nm] or {} + table.insert(events.defs[nm], func) + if (fts) then + events.filters[nm] = events.filters[nm] or {} + for k, v in pairs(fts) do table.insert(events.filters[nm], table.deepcopy(v)) end + end +end + +events.on_event = events.hook -- alias +function events.raise(name, ev) + ev = ev or {} + ev.name = ev.name or table.KeyFromName(defines.events, name) + script.raise_event(name, ev) +end + +function events.register(name) events.vdefs[name] = script.generate_event_name() end + +-- unused function events.vhook(name,func) if(istable(name))then for k,v in pairs(nm)do events.vhook(name,func) end end events.vhooks[name]=func end +function events.vraise(name, ev) + ev = ev or {} + ev.name = name + script.raise_event(events.vdefs[name], ev) +end + +function events.entity(ev) return ev.entity or ev.created_entity or ev.destination or ev.mine end + +function events.source(ev) return ev.source end + +function events.destination(ev) return ev.created_entity or ev.destination end + +function events.surface(ev) return ev.surface or game.surfaces[ev.surface_index] end + +function events.on_load(f) table.insert(events.loadfuncs, f) end + +function events.on_init(f) table.insert(events.initfuncs, f) end + +function events.on_migrate(f) table.insert(events.migratefuncs, f) end + +events.on_config = events.on_migrate +events.on_configration_changed = events.on_migrate -- aliases +function events.raise_load() + cache.load() + for k, v in ipairs(events.loadfuncs) do v() end + if (lib.PLANETORIO) then lib.planets.lua() end +end + +function events.raise_init() + cache.init() + for k, v in ipairs(events.initfuncs) do v() end + if (lib.PLANETORIO) then lib.planets.lua() end +end + +function events.raise_migrate(ev) + cache.migrate(ev) + for k, v in ipairs(events.migratefuncs) do v(ev or {}) end + if (lib.PLANETORIO) then lib.planets.lua() end +end + +function events.on_tick(rate, offset, fnm, func) + local r = events.tickers[rate] or {} + events.tickers[rate] = r + local o = r[offset] or {} + r[offset] = o + o[fnm] = func + script.on_event(defines.events.on_tick, events.raise_tick) +end + +function events.un_tick(rate, offset, fnm) + local r = events.tickers[rate] or {} + events.tickers[rate] = r + local o = r[offset] or {} + r[offset] = o + o[fnm] = nil + if (table_size(o) == 0) then r[offset] = nil end + if (table_size(r) == 0) then events.tickers[rate] = nil end + if (table_size(events.tickers) == 0) then script.on_event(defines.events.on_tick, nil) end +end + +function events.raise_tick(ev) + for rt, ff in pairs(events.tickers) do + for x, y in pairs(ff) do + if (ev.tick % rt == x) then + for a, b in pairs(y) do + b(ev.tick) + end + end + end + end +end + +function events.inject() + --error(serpent.block(events.filters[defines.events.on_built_entity])) + for k, v in pairs(events.defs) do + if (v and table_size(v) > 0) then + if (events.events_with_filters[table.KeyFromValue(defines.events, k)] and events.filters[k] and table_size(events.filters[k]) > 0) then + --if(k==defines.events.on_built_entity and #events.filters[k]>0)then error(k..":\n"..serpent.block(events.filters[k])) end + script.on_event(k, function(ev) for x, y in pairs(v) do y(ev) end end, events.filters[k]) + else + script.on_event(k, function(ev) for x, y in pairs(v) do y(ev) end end) + end + end + end + if (table_size(events.tickers) > 0) then script.on_event(defines.events.on_tick, events.raise_tick) end + + + + script.on_init(events.raise_init) + script.on_load(events.raise_load) + script.on_configuration_changed(events.raise_migrate) +end + +-- -------- +-- Gui + +vgui = vgui or {} +function vgui.create(parent, tbl) + local elm = parent[tbl.name] + if (not isvalid(elm)) then elm = parent.add(tbl) end + for k, v in pairs(tbl) do if (vgui.mods[k]) then vgui.mods[k](elm, v) end end + return elm +end + +vgui.mods = {} +vmods = vgui.mods +function vmods.horizontal_align(e, v) e.style.horizontal_align = v end + +function vmods.vertical_align(e, v) e.style.vertical_align = v end + +function vmods.align(e, v) + e.style.horizontal_align = (istable(v) and v[1] or v) + e.style.vertical_align = istable(v and v[2] or v) +end + +-- -------- +-- Remotes diff --git a/lib/lib_control_cache.lua b/lib/lib_control_cache.lua index d6b6a31..a29574e 100644 --- a/lib/lib_control_cache.lua +++ b/lib/lib_control_cache.lua @@ -1,663 +1,663 @@ ---[[------------------------------------- - -Author: Pyro-Fire -https://patreon.com/pyrofire - -Script: lib_control_cache.lua -Purpose: cache stuff with events - ------ - -Copyright (c) 2019 Pyro-Fire - -I put a lot of work into these library files. Please retain the above text and this copyright disclaimer message in derivatives/forks. - -Permission to use, copy, modify, and/or distribute this software for any -purpose without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ------- - -Written using Microsoft Notepad. -IDE's are for children. - -How to notepad like a pro: -ctrl+f = find -ctrl+h = find & replace -ctrl+g = show/jump to line (turn off wordwrap n00b) - -Status bar wastes screen space, don't use it. - -Use https://tools.stefankueng.com/grepWin.html to mass search, find and replace many files in bulk. - -]]--------------------------------------- - - ---[[ Simple Cache & Events Manager ]]-- ---[[ Usage -cache.ent("assembling-machine-1",{built=function(ent) dostuff() end}) -cache.type("assembling-machine",{built=function(ent_with_type) dostuff() end}) - -Also has global table manager for arbitrary data on stuff. -Create/destroy manually though, still easier than writing a new handler every time. - -cache.vgui("hud_frame",{ click=function(elm,ev) - local menu=cache.get_menu("hud",ev.player_index) - cache.call_menu("clickyframe",menu,ev,...) - ..etc -end }) - -cache.menu("menu_name",{ create=function(menu,...) menu.frame=etc() end, destroy=function(menu,ev,...) forceclose() end, closed=function(menu,ev,...) onclosed() end }) -local menu=cache.raise_menu("hud",ply) -menu.frame=ply.gui.add("hud_frame",...) -... -local menu=cache.get_menu("menu_name",ply) -cache.call_menu("func_name",menu,data,...) -... -... -cache.destroy_menu(menu) -- force close menu - - -local vtbl=cache.raise_entity(entity) -... -cache.destroy_entity(vtbl) --- etc etc - - -]]-- - -local cache={} - - --- cache classes -cache.surfaces={} -cache.spatterns={} -cache.ents={} -cache.types={} -cache.patterns={} -cache.vguis={} -cache.gtypes={} -cache.gpatterns={} -cache.players={} -cache.forces={} -cache.fpatterns={} -cache.units={} -cache.utypes={} -cache.menus={} - --- translate named function tables -cache.primaries={ - ent="ents",type="types",pattern="patterns", - vgui="vguis",gpattern="gpatterns",gtype="gtype", - menu="menus", - player="players",force="forces", - surface="surfaces",spattern="spatterns", - unit="units",utype="utypes", -} --- grouped class types for event filters -cache.classes={ - ents={name="ents",type="types",ptrn="patterns"}, - vgui={name="vguis",type="gtypes",ptrn="gpatterns"}, - menus={name="menus"}, - players={single="players"}, - forces={name="forces",ptrn="fpatterns"}, - surfaces={name="surfaces",spattern="spatterns"}, -} - -for k,v in pairs(cache.primaries)do if(k~="player")then cache[k]=function(name,tbl) cache[v][name]=tbl end end end -function cache.player(tbl) cache.players=tbl end - - -cache.events={} -- Functions to distribute individual events among the caches in correct orders - -function cache.init() - global._lib=global._lib or {} - cache.migrate() -end - -function cache.migrate(ev) - if(global._libcache)then global._lib={cache=global._libcache} global._libcache=nil else global._lib=global._lib or {cache={}} end -- global._lib.cache - global._lib.cache=global._lib.cache or {} - for key,category in pairs(cache.primaries)do -- global._lib[raised_type] - global._lib[category]=global._lib[category] or {} - global._lib[category.."_idx"]=global._lib[category.."_idx"] or {} - end -end - - -function cache.load() -end - - -- helper functions for simple caching -function cache.insert(n,ent) global._lib.cache[n]=global._lib.cache[n] or {} table.insertExclusive(global._lib.cache[n],ent) end -function cache.validate(n) global._lib.cache[n]=global._lib.cache[n] or {} for k,v in pairs(global._lib.cache[n])do if(not isvalid(v))then global._lib.cache[n][k]=nil end end end -function cache.remove(n,ent) global._lib.cache[n]=global._lib.cache[n] or {} table.RemoveByValue(global._lib.cache[n],ent) end -function cache.get(n) if(isstring(n))then return global._lib.cache[n] or {} end end ---function cache.call(n,evn,ev,...) for k,v in pairs(cache.get(n))do ev.entity=v cache.call_ents(evn,ev,...) end end -- Call a simple event on all entities in a cache table. -function cache.entcall(n,evn,ev,...) for k,v in pairs(cache.get(n))do ev.entity=v cache.call_ents(evn,ev,...) end end -- Call a simple event on all entities in a cache table. -function cache.surfacecall(n,evn,ev,...) for k,v in pairs(cache.get(n))do ev.entity=v cache.call_surfaces(evn,ev,...) end end -- Call a simple event on all entities in a cache table. - - - - -function cache.call_ents(vn,ev,...) local ent=events.entity(ev) if(not isvalid(ent))then return end - local tx=cache.types[ent.type=="ghost" and ent.ghost_type or ent.type] if(tx and tx[vn])then tx[vn](ent,ev,...) end if(not isvalid(ent))then return end - local tx=cache.ents[ent.type=="ghost" and ent.ghost_name or ent.name] if(tx and tx[vn])then tx[vn](ent,ev,...) end if(not isvalid(ent))then return end - local tx for k,v in pairs(cache.patterns)do if((ent.type=="ghost" and ent.ghost_name or ent.name):find(k,1,true))then tx=v break end end if(tx and tx[vn])then tx[vn](ent,ev,...) end -end -function cache.call_vgui(vn,ev,...) local elm=ev.element if(not isvalid(elm))then return end - local tx=cache.vguis[elm.name] if(tx and tx[vn])then tx[vn](ev.element,ev,...) end - local tx=cache.gtypes[elm.type] if(tx and tx[vn])then tx[vn](ev.element,ev,...) end - local tx for k,v in pairs(cache.gpatterns)do if(elm.name:find(k,1,true))then tx=v break end end if(tx and tx[vn])then tx[vn](ev.element,ev,...) end -end -function cache.call_player(vn,ev,...) local tx=cache.players[vn] if(not tx)then return end - if(tx)then tx(game.players[ev.player_index],ev,...) end -end -function cache.call_force(vn,ev,...) local f=ev.force if(not f)then f=game.forces[ev.force_index] end if(not f)then f=game.forces[ev.force_name] end if(not isvalid(f))then return end - local tx=cache.forces[f.name] if(tx and tx[vn])then tx[vn](f,ev,...) end - local tx for k,v in pairs(cache.fpatterns)do if(f.name:find(k,1,true))then tx=v break end end if(tx and tx[vn])then tx[vn](f,ev,...) end -end - -function cache.call_surface(vn,ev,...) local f=ev.surface if(not f)then f=game.surfaces[ev.surface_index] end if(not isvalid(f))then return end - local tx=cache.surfaces[f.name] if(tx and tx[vn])then tx[vn](f,ev,...) end - local tx for k,v in pairs(cache.spatterns)do if(f.name:find(k,1,true))then tx=v break end end if(tx and tx[vn])then tx[vn](f,ev,...) end -end -function cache.call_menu(vn,menu,ev,...) - local tx=cache.menus[menu.name] if(tx and tx[vn])then tx[vn](menu,ev,...) end -end - -function cache.get_index(host,key) return host[key] end - --- Raise/destroy stuff to cache into global table. It gives us an internally managed cache table to shove data into e.g. creation/destruction of the base object. -function cache.raise_type(vtype,name,host,...) - local uid if(isnumber(host))then uid=host else local cx cx,uid=pcall(cache.get_index,host,"index") if(not cx)then cx,uid=pcall(cache.get_index,host,"unit_number") if(not cx)then uid=nil end end end - local hdx=uid - if(hdx)then local gc=global._lib[vtype.."_idx"][hdx] if(gc and name)then gc=gc[name] end if(gc)then return gc end end -- get existing hosted/index vtype - local c=cache[vtype] -- cache["ents"][name]. You can call these manually if you need to for ptrn, surfaces etc. - if(not c)then return end if(name)then c=c[name] if(not c)then return end end -- only menus and vguis typically use names. - local idx=#global._lib[vtype]+1 - local t={index=idx,name=name,type=vtype,host=host,hostindex=hdx} global._lib[vtype][idx]=t - if(hdx)then - if(name)then local gc=global._lib[vtype.."_idx"][hdx] or {} global._lib[vtype.."_idx"][hdx]=gc gc[t.name]=t - else global._lib[vtype.."_idx"][hdx]=t - end - end - if(c.raise)then c.raise(t,...) end - if(vtype=="ents")then if(c[host.name] and c[host.name].raise)then c[host.name].raise(t,...) end end - if(vtype=="types")then local htype=(host.is_player() and "player" or host.type) if(c[htype] and c[htype].raise)then c[htype].raise(t,...) end end - - return t -end -function cache.destroy_type(obj,...) local vtype=obj.type - local c=cache[vtype] if(not c)then return end if(obj.name)then c=c[obj.name] if(not c)then return end end - if(c.unraise)then c.unraise(obj,...) end - global._lib[vtype][obj.index]=nil - if(obj.hostindex)then global._lib[vtype.."_idx"][obj.hostindex]=nil end -end -function cache.get_type(vtype,name,host) local t=global._lib[vtype.."_idx"] - if(t)then - local uid if(isnumber(host))then uid=host else local cx cx,uid=pcall(cache.get_index,host,"index") if(not cx)then cx,uid=pcall(cache.get_index,host,"unit_number") if(not cx)then uid=nil end end end - if(uid)then t=t[uid] else t=nil end - end - if(t and name)then t=t[name] end - return t -end -function cache.get_raise_type(vtype,name,host,...) return cache.get_type(vtype,name,host) or cache.raise_type(vtype,name,host,...) end -function cache.get_types(vtype) local t=global._lib[vtype] return t end - -function cache.destroy(obj,...) return cache.destroy_type(obj,...) end -- This just destroys the cache object, not the actual in-game object. - - -function cache.raise_menu(name,ply,...) return cache.raise_type("menus",name,ply,...) end -function cache.force_menu(name,ply,...) return cache.get_raise_type("menus",name,ply,...) end -function cache.get_menu(name,ply) return cache.get_type("menus",name,ply) end -cache.destroy_menu=cache.destroy - -function cache.raise_vgui(name,menu,...) return cache.raise_type("vguis",name,menu,...) end -function cache.force_vgui(name,menu,...) return cache.get_raise_type("vguis",name,menu,...) end -function cache.get_vgui(name,menu) return cache.get_type("vguis",name,menu) end -cache.destroy_vgui=cache.destroy - -function cache.raise_player(ply,...) return cache.raise_type("players",nil,ply,...) end -function cache.force_player(ply,...) return cache.get_raise_type("players",nil,ply,...) end -function cache.get_player(ply) return cache.get_type("players",nil,ply) end -cache.destroy_player=cache.destroy - -function cache.raise_force(force,...) return cache.raise_type("forces",nil,force,...) end -function cache.force_force(force,...) return cache.get_raise_type("forces",nil,force,...) end -function cache.get_force(force) return cache.get_type("forces",nil,force) end -cache.destroy_force=cache.destroy - -function cache.raise_surface(surface,...) return cache.raise_type("surfaces",nil,surface,...) end -function cache.force_surface(surface,...) return cache.get_raise_type("surfaces",nil,surface,...) end -function cache.get_surface(surface) return cache.get_type("surfaces",nil,surface) end -cache.destroy_surface=cache.destroy - -function cache.raise_unit(unit,...) return cache.raise_type("units",nil,unit,...) end -function cache.force_unit(unit,...) return cache.get_raise_type("units",nil,unit,...) end -function cache.get_unit(unit) return cache.get_type("units",nil,unit) end -cache.destroy_unit=cache.destroy - -function cache.raise_entity(ent,...) return cache.raise_type("ents",nil,ent,...) end -function cache.force_entity(ent,...) return cache.get_raise_type("ents",nil,ent,...) end -function cache.get_entity(ent) return cache.get_type("ents",nil,ent) end -cache.destroy_entity=cache.destroy - - - -function cache.update(ent,vn,...) vn=vn or "update" - local tx=cache.types[ent.type] if(tx and tx[vn])then tx[vn](ent,...) end - local tx=cache.ents[ent.name] if(tx and tx[vn])then tx[vn](ent,...) end - local tx for k,v in pairs(cache.patterns)do if(ent.name:find(k,1,true))then tx=v break end end if(tx and tx[vn])then tx[vn](ent,...) end -end -function cache.updategui(elm,...) local vn="update" if(not isstring(elm))then elm=elm.name end - local tx=cache.vguis[elm.name] if(tx and tx[vn])then tx[vn](elm,...) end - local tx=cache.gtypes[elm.name] if(tx and tx[vn])then tx[vn](elm,...) end - local tx for k,v in pairs(cache.gpatterns)do if(elm.name:find(k,1,true))then tx=v break end end if(tx and tx[vn])then tx[vn](elm,...) end -end -function cache.updatemenu(mn,vn,ev,...) for i,ply in pairs(game.players)do - local menu=cache.get_menu(mn,ply) if(menu)then - cache.call_menu(vn,menu,ev,...) - end -end end - - - -function cache.inject_type(nm,evdata) - local funcs=cache.events[nm] - local defs=cache.events[nm.."_defs"] - local ccls=cache.classes[nm] - - - local ptrn=false - for evtype,vdefs in pairs(defs)do - if(ccls.name)then for tpnm,cls in pairs(cache[ccls.name])do if(cls[evtype])then - for _,def in pairs(vdefs)do evdata[def]=evdata[def] or {} table.insert(evdata[def],{nm=nm,tpnm=tpnm,evtype=evtype,ghost=cls.ghost,clsname=ccls.name,func=funcs[def]}) end - end end end - if(ccls.type)then for tpnm,cls in pairs(cache[ccls.type])do if(cls[evtype])then - for _,def in pairs(vdefs)do evdata[def]=evdata[def] or {} table.insert(evdata[def],{nm=nm,tpnm=tpnm,evtype=evtype,ghost=cls.ghost,clstype=ccls.type,func=funcs[def]}) end - end end end - if(ccls.ptrn)then for tpnm,cls in pairs(cache[ccls.ptrn])do if(cls[evtype])then ptrn=true - for _,def in pairs(vdefs)do evdata[def]=evdata[def] or {} table.insert(evdata[def],{nm=nm,tpnm=tpnm,evtype=evtype,ghost=cls.ghost,clsptrn=ccls.ptrn,func=funcs[def]}) end - end end end - if(ccls.single)then local cls=cache[ccls.single] if(cls[evtype])then - for _,def in pairs(vdefs)do evdata[def]=evdata[def] or {} table.insert(evdata[def],{nm=nm,tpnm=tpnm,evtype=evtype,ghost=cls.ghost,clssingle=ccls.single,func=funcs[def]}) end - end end - end - --if(nm=="players")then error(serpent.block(evdata)) end -end - - -function cache.inject() -- interface with events - local evdata={} for nm in pairs(cache.classes)do cache.inject_type(nm,evdata) end - --error(serpent.block(evdata)) - for def,tbl in pairs(evdata)do - local filters={} - local nmf,tpf,ptf,sgf - --if(events.events_with_filters[def])then - for i,vtbl in pairs(tbl)do - if(vtbl.clsptrn)then ptf=vtbl.func filters=nil - elseif(vtbl.clstype)then tpf=vtbl.func - if(filters)then table.insert(filters,{filter="type",type=vtbl.tpnm}) - if(vtbl.ghost)then table.insert(filters,{filter="ghost_type",type=vtbl.tpnm}) end - end - elseif(vtbl.clsname)then nmf=vtbl.func - if(filters)then table.insert(filters,{filter="name",name=vtbl.tpnm}) - if(vtbl.ghost)then table.insert(filters,{filter="ghost_name",name=vtbl.tpnm}) end - end - elseif(vtbl.clssingle)then sgf=vtbl.func filters=nil - end - end - --end - if(not events.events_with_filters[def])then filters=nil end - - if(nmf)then events.hook(defines.events[def],nmf,filters) end - if(tpf)then events.hook(defines.events[def],tpf,filters) end - if(ptf)then events.hook(defines.events[def],ptf,filters) end - if(sgf)then events.hook(defines.events[def],sgf,filters) end - end -end - ---[[ Unknowns -on_put_item -on_ai_command_completed - -on_difficulty_settings_changed -on_cutscene_waypout_reached - -on_console_command -on_console_chat - -on_chart_tag_added -on_chart_tag_modified -on_chart_tag_removed -- force events - -on_game_created_from_scenario - -on_robot_built_entity -on_robot_built_tile -on_robot_exploded_cliff -on_robot_mined -on_robot_mined_entity -on_robot_mined_tile -on_robot_pre_mined -on_rocket_launch_ordered -on_rocket_launched -on_runtime_mod_setting_changed -on_script_path_request_finished -- pathfinding -on_sector_scanned -- radar -on_string_translated - -on_train_changed_state -on_train_created -on_train_schedule_changed - -on_trigger_fired_artillery - -on_unit_added_to_group -on_unit_group_created -on_unit_removed_from_group -on_biter_base_built - - -on_market_item_purchased - - -]] - - -cache.events.forces={} -function cache.events.forces.on_research_finished(ev) cache.call_force("research_finished",ev) end -function cache.events.forces.on_research_started(ev) cache.call_force("research_started",ev) end -function cache.events.forces.on_technology_effects_reset(ev) cache.call_force("research_reset",ev) end -function cache.events.forces.on_chart_tag_added(ev) cache.call_force("tag_added",ev) end -function cache.events.forces.on_chart_tag_modified(ev) cache.call_force("tag_modified",ev) end -function cache.events.forces.on_chart_tag_removed(ev) cache.call_force("tag_removed",ev) end - -cache.events.forces_defs={ -- Things that specifically are called with a force. Player stuff can be hooked from players. - research_finished={"on_research_finished"}, - research_started={"on_research_started"}, - research_reset={"on_technology_effects_reset"}, -} - -cache.events.ents={} -function cache.events.ents.on_built_entity(ev) cache.call_ents("built",ev) cache.call_ents("create",ev) end -function cache.events.ents.script_raised_built(ev) cache.call_ents("create",ev) end -function cache.events.ents.on_entity_cloned(ev) cache.call_ents("clone",ev) cache.call_ents("create",ev) end -function cache.events.ents.on_robot_built_entity(ev) cache.call_ents("built",ev) cache.call_ents("create",ev) end -function cache.events.ents.script_raised_destroy(ev) cache.call_ents("destroy",ev) end -function cache.events.ents.on_entity_died(ev) cache.call_ents("died",ev) cache.call_ents("destroy",ev) end -function cache.events.ents.on_post_entity_died(ev) cache.call_ents("post_died",ev) end -function cache.events.ents.on_player_mined_entity(ev) cache.call_ents("mined",ev) cache.call_ents("destroy",ev) end -function cache.events.ents.on_robot_mined_entity(ev) cache.call_ents("mined",ev) cache.call_ents("destroy",ev) end -function cache.events.ents.on_player_rotated_entity(ev) cache.call_ents("rotate",ev) end -function cache.events.ents.on_entity_settings_pasted(ev) cache.call_ents("settings_pasted",ev) end -function cache.events.ents.on_pre_entity_settings_pasted(ev) cache.call_ents("pre_settings_pasted",ev) end -function cache.events.ents.on_cancelled_deconstruction(ev) cache.call_ents("cancel_deconstruct",ev) end -function cache.events.ents.on_cancelled_upgrade(ev) cache.call_ents("cancel_upgrade",ev) end -function cache.events.ents.on_marked_for_deconstruction(ev) cache.call_ents("deconstruct",ev) end -function cache.events.ents.on_marked_for_upgrade(ev) cache.call_ents("upgrade",ev) end -function cache.events.ents.on_pre_ghost_deconstructed(ev) cache.call_ents("deconstruct_ghost",ev) end -function cache.events.ents.on_post_entity_died(ev) cache.call_ents("post_died",ev) end -function cache.events.ents.on_mod_item_opened(ev) cache.call_ents("item_menu",ev) end -function cache.events.ents.on_entity_damaged(ev) cache.call_ents("damage",ev) end -function cache.events.ents.on_trigger_created_entity(ev) cache.call_ents("trigger",ev) end -function cache.events.ents.on_entity_spawned(ev) cache.call_ents("spawned",ev) end -function cache.events.ents.on_land_mine_armed(ev) cache.call_ents("mine_armed",ev) end -function cache.events.ents.on_gui_opened(ev) cache.call_ents("gui_opened",ev) end -function cache.events.ents.on_gui_closed(ev) cache.call_ents("gui_closed",ev) end -function cache.events.ents.on_pre_robot_exploded_cliff(ev) cache.call_ents("pre_robot_exploded_cliff",ev) end -function cache.events.ents.on_post_entity_died(ev) cache.call_ents("post_died",ev) end -function cache.events.ents.on_combat_robot_expired(ev) cache.call_ents("robot_expired",ev) end -function cache.events.ents.script_raised_revive(ev) cache.call_ents("create",ev) end -function cache.events.ents.on_entity_renamed(ev) cache.call_ents("rename",ev) end - -cache.events.ents_defs={ - built={"on_built_entity","on_robot_built_entity"}, - create={"on_built_entity","script_raised_built","on_entity_cloned","on_robot_built_entity","script_raised_revive"}, - mined={"on_player_mined_entity","on_robot_mined_entity"}, - rotate={"on_player_rotated_entity"}, - rename={"on_entity_renamed"}, - destroy={"on_player_mined_entity","on_robot_mined_entity","script_raised_destroy","on_entity_died"}, - - died={"on_entity_died"}, - post_died={"on_post_entity_died"}, - - settings_pasted={"on_entity_settings_pasted"}, - pre_settings_pasted={"on_pre_entity_settings_pasted"}, - cancel_deconstruct={"on_cancelled_deconstruction"}, - cancel_upgrade={"on_cancelled_upgrade"}, - deconstruct={"on_marked_for_deconstruction"}, - deconstruct_ghost={"on_pre_ghost_deconstructed"}, - - upgrade={"on_marked_for_upgrade"}, - - gui_opened={"on_gui_opened"}, - gui_closed={"on_gui_closed"}, - - item_menu={"on_mod_item_opened"}, --Called when the player uses the 'Open item GUI' control on an item defined with 'can_be_mod_opened' as true - damage={"on_entity_damaged"}, - trigger={"on_trigger_created_entity"}, - robot_expired={"on_combat_robot_expired"}, - - spawned={"on_entity_spawned"}, - mine_armed={"on_land_mine_armed"}, - - pre_robot_exploded_cliff={"on_pre_robot_exploded_cliff"}, - post_died={"on_post_entity_died"}, -} - - -cache.events.vgui={} -function cache.events.vgui.on_gui_opened(ev) cache.call_vgui("open_menu",ev) end -function cache.events.vgui.on_gui_closed(ev) cache.call_vgui("gui_closed",ev) cache.call_vgui("gui_closed",ev) end -function cache.events.vgui.on_gui_click(ev) cache.call_vgui("click",ev) end -function cache.events.vgui.on_gui_confirmed(ev) cache.call_vgui("confirm",ev) end -function cache.events.vgui.on_gui_text_changed(ev) cache.call_vgui("text_changed",ev) end -function cache.events.vgui.on_gui_selection_state_changed(ev) cache.call_vgui("selection_changed",ev) end -function cache.events.vgui.on_player_display_resolution_changed(ev) cache.call_vgui("on_resolution",ev) end -function cache.events.vgui.on_player_display_scale_changed(ev) cache.call_vgui("on_scale",ev) end -function cache.events.vgui.on_gui_checked_state_changed(ev) cache.call_vgui("on_checked",ev) end -function cache.events.vgui.on_gui_elem_changed(ev) cache.call_vgui("elem_changed",ev) end -function cache.events.vgui.on_gui_location_changed(ev) cache.call_vgui("location_changed",ev) end -function cache.events.vgui.on_gui_selected_tab_changed(ev) cache.call_vgui("tab_changed",ev) end -function cache.events.vgui.on_gui_switch_state_changed(ev) cache.call_vgui("on_switched",ev) end -function cache.events.vgui.on_gui_value_changed(ev) cache.call_vgui("value_changed",ev) end - -cache.events.vgui_defs={ - click={"on_gui_click"}, - open_menu={"on_gui_opened"}, - gui_closed={"on_gui_closed"}, - confirm={"on_gui_confirmed"}, - text_changed={"on_gui_text_changed"}, - selection_changed={"on_gui_selection_state_changed"}, - on_resolution={"on_player_display_resolution_changed"}, - on_scale={"on_player_display_scale_changed"}, - on_checked={"on_gui_checked_state_changed"}, - elem_changed={"on_gui_elem_changed"}, - location_changed={"on_gui_location_changed"}, - tab_changed={"on_gui_selected_tab_changed"}, - on_switched={"on_gui_switch_state_changed"}, - value_changed={"on_gui_value_changed"}, -} - - - -cache.events.surfaces={} -function cache.events.surfaces.on_surface_created(ev) cache.call_surface("create",ev) end -function cache.events.surfaces.on_pre_surface_deleted(ev) cache.call_surface("pre_deleted",ev) end -function cache.events.surfaces.on_pre_surface_cleared(ev) cache.call_surface("pre_cleared",ev) end -function cache.events.surfaces.on_surface_deleted(ev) cache.call_surface("on_deleted",ev) end -function cache.events.surfaces.on_surface_imported(ev) cache.call_surface("import",ev) end -function cache.events.surfaces.on_surface_renamed(ev) cache.call_surface("rename",ev) end -function cache.events.surfaces.on_chunk_generated(ev) cache.call_surface("chunk",ev) end -function cache.events.surfaces.on_chunk_deleted(ev) cache.call_surface("chunk_deleted",ev) end -function cache.events.surfaces.on_pre_chunk_deleted(ev) cache.call_surface("pre_chunk_deleted",ev) end -function cache.events.surfaces.on_chunk_charted(ev) cache.call_surface("chart",ev) end - -cache.events.surfaces_defs={ - create={"on_surface_created"}, - pre_deleted={"on_pre_surface_deleted"}, - pre_cleared={"on_pre_surface_cleared"}, - on_cleared={"on_surface_cleared"}, - on_deleted={"on_surface_deleted"}, - - import={"on_surface_imported"}, - rename={"on_surface_renamed"}, - chunk={"on_chunk_generated"}, - chunk_deleted={"on_chunk_deleted"}, - pre_chunk_deleted={"on_pre_chunk_deleted"}, - - chart={"on_chunk_charted"}, -} - -cache.events.players={} -function cache.events.players.on_player_toggled_alt_mode(ev) cache.call_player("on_alt",ev) end -function cache.events.players.on_player_toggled_map_editor(ev) cache.call_player("on_editor",ev) end -function cache.events.players.on_player_cheat_mode_enabled(ev) cache.call_player("on_cheat",ev) end -function cache.events.players.on_player_cheat_mode_disabled(ev) cache.call_player("on_uncheat",ev) end -function cache.events.players.on_player_driving_changed_state(ev) cache.call_player("on_driving",ev) end -function cache.events.players.on_pickup_item(ev) cache.call_player("on_pickup_item",ev) end -function cache.events.players.on_player_dropped_item(ev) cache.call_player("on_drop_item",ev) end -function cache.events.players.on_player_fast_transferred(ev) cache.call_player("on_fast_transfer",ev) end -function cache.events.players.on_player_gun_inventory_changed(ev) cache.call_player("on_gun_inv",ev) end -function cache.events.players.on_player_ammo_inventory_changed(ev) cache.call_player("on_ammo_changed",ev) end -function cache.events.players.on_player_armor_inventory_changed(ev) cache.call_player("on_armor_changed",ev) end -function cache.events.players.on_player_placed_equipment(ev) cache.call_player("on_equip",ev) end -function cache.events.players.on_player_removed_equipment(ev) cache.call_player("on_dequip",ev) end - -function cache.events.players.on_built_tile(ev) cache.call_player("on_built_tile",ev) end -function cache.events.players.on_built_entity(ev) cache.call_player("on_built",ev) end -function cache.events.players.on_player_changed_position(ev) cache.call_player("on_position",ev) end -function cache.events.players.on_player_changed_surface(ev) cache.call_player("on_surface",ev) end -function cache.events.players.on_character_corpse_expired(ev) cache.call_player("on_corpse_expired",ev) end -function cache.events.players.on_lua_shortcut(ev) cache.call_player("on_shortcut",ev) end -function cache.events.players.on_player_alt_selected_area(ev) cache.call_player("on_alt_select_area",ev) end -function cache.events.players.on_player_deconstructed_area(ev) cache.call_player("on_deconstruct_area",ev) end -function cache.events.players.on_player_selected_area(ev) cache.call_player("on_select_area",ev) end -function cache.events.players.on_player_configured_blueprint(ev) cache.call_player("on_blueprint",ev) end -function cache.events.players.on_player_setup_blueprint(ev) cache.call_player("on_setup_blueprint",ev) end -function cache.events.players.on_selected_entity_changed(ev) cache.call_player("on_selected_entity_changed",ev) end -function cache.events.players.on_player_respawned(ev) cache.call_player("on_respawn",ev) end -function cache.events.players.on_player_created(ev) cache.call_player("on_create",ev) end -function cache.events.players.on_player_joined_game(ev) cache.call_player("on_join",ev) end -function cache.events.players.on_player_banned(ev) cache.call_player("on_banned",ev) end -function cache.events.players.on_player_left_game(ev) cache.call_player("on_left",ev) end -function cache.events.players.on_player_removed(ev) cache.call_player("on_removed",ev) end -function cache.events.players.on_pre_player_left_game(ev) cache.call_player("on_pre_left",ev) end -function cache.events.players.on_pre_player_removed(ev) cache.call_player("on_pre_removed",ev) end -function cache.events.players.on_player_unbanned(ev) cache.call_player("on_unban",ev) end -function cache.events.players.on_player_unmuted(ev) cache.call_player("on_unmute",ev) end -function cache.events.players.on_player_demoted(ev) cache.call_player("on_demoted",ev) end -function cache.events.players.on_player_died(ev) cache.call_player("on_died",ev) end -function cache.events.players.on_pre_player_died(ev) cache.call_player("on_pre_died",ev) end -function cache.events.players.on_player_muted(ev) cache.call_player("on_muted",ev) end -function cache.events.players.on_player_promoted(ev) cache.call_player("on_promoted",ev) end -function cache.events.players.on_player_main_inventory_changed(ev) cache.call_player("on_inventory",ev) end -function cache.events.players.on_player_mined_entity(ev) cache.call_player("on_mined",ev) end -function cache.events.players.on_pre_player_mined_item(ev) cache.call_player("on_pre_mined_item",ev) end -function cache.events.players.on_player_mined_item(ev) cache.call_player("on_mined_item",ev) end -function cache.events.players.on_player_mined_tile(ev) cache.call_player("on_mined_tile",ev) end -function cache.events.players.on_player_cursor_stack_changed(ev) cache.call_player("on_cursor",ev) end -function cache.events.players.on_player_pipette(ev) cache.call_player("on_pipette",ev) end -function cache.events.players.on_player_cancelled_crafting(ev) cache.call_player("on_cancel_craft",ev) end -function cache.events.players.on_pre_player_crafted_item(ev) cache.call_player("on_pre_craft",ev) end -function cache.events.players.on_player_crafted_item(ev) cache.call_player("on_craft",ev) end -function cache.events.players.on_player_repaired_entity(ev) cache.call_player("on_repair",ev) end -function cache.events.players.on_player_rotated_entity(ev) cache.call_player("on_rotate",ev) end -function cache.events.players.on_player_trash_inventory_changed(ev) cache.call_player("on_trash_changed",ev) end -function cache.events.players.on_player_used_capsule(ev) cache.call_player("on_capsule",ev) end - - -cache.events.players_defs={ - - on_alt={"on_player_toggled_alt_mode"}, - on_editor={"on_player_toggled_map_editor"}, - - on_cheat={"on_player_cheat_mode_enabled"}, - on_uncheat={"on_player_cheat_mode_disabled"}, - - on_driving={"on_player_driving_changed_state"}, - - on_pickup_item={"on_picked_up_item"}, - on_drop_item={"on_player_dropped_item"}, - - on_fast_transfer={"on_player_fast_transferred"}, - on_gun_inv={"on_player_gun_inventory_changed"}, - on_ammo_changed={"on_player_ammo_inventory_changed"}, - on_armor_changed={"on_player_armor_inventory_changed"}, - on_equip={"on_player_placed_equipment"}, - on_dequip={"on_player_removed_equipment"}, - - on_built_tile={"on_player_built_tile"}, - on_built={"on_entity_built"}, - - on_position={"on_player_changed_position"}, - on_surface={"on_player_changed_surface"}, - - on_corpse_expired={"on_character_corpse_expired"}, - - on_shortcut={"on_lua_shortcut"}, - on_alt_select_area={"on_player_alt_selected_area"}, - on_deconstruct_area={"on_player_deconstructed_area"}, - on_select_area={"on_player_selected_area"}, - - - on_blueprint={"on_player_configured_blueprint"}, - on_setup_blueprint={"on_player_setup_blueprint"}, - - on_select={"on_selected_entity_changed"}, - - on_respawn={"on_player_respawned"}, - on_create={"on_player_created"}, - on_join={"on_player_joined_game"}, - - on_banned={"on_player_banned"}, - on_left={"on_player_left_game"}, - on_removed={"on_player_removed"}, - on_pre_left={"on_pre_player_left_game"}, - on_pre_removed={"on_pre_player_removed"}, - - on_unban={"on_player_unbanned"}, - on_unmute={"on_player_unmuted"}, - on_demote={"on_player_demoted"}, - - on_died={"on_player_died"}, - on_pre_died={"on_pre_player_died"}, - - on_muted={"on_player_muted"}, - on_promoted={"on_player_promoted"}, - - on_inventory={"on_player_main_inventory_changed"}, - on_mined={"on_player_mined_entity"}, - on_pre_mined_item={"on_pre_player_mined_item"}, - on_mined_item={"on_player_mined_item"}, - on_mined_tile={"on_player_mined_tile"}, - - on_cursor={"on_player_cursor_stack_changed"}, - on_pipette={"on_player_pipette"}, - - on_cancel_craft={"on_player_cancelled_crafting"}, - on_pre_craft={"on_pre_player_crafted_item"}, - on_craft={"on_player_crafted_item"}, - - on_repair={"on_player_repaired_entity"}, - on_rotate={"on_player_rotated_entity"}, - - on_trash_changed={"on_player_trash_inventory_changed"}, - - on_capsule={"on_player_used_capsule"}, - -} -cache.events.menus={} -cache.events.menus_defs={ -} - +--[[------------------------------------- + +Author: Pyro-Fire +https://patreon.com/pyrofire + +Script: lib_control_cache.lua +Purpose: cache stuff with events + +----- + +Copyright (c) 2019 Pyro-Fire + +I put a lot of work into these library files. Please retain the above text and this copyright disclaimer message in derivatives/forks. + +Permission to use, copy, modify, and/or distribute this software for any +purpose without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +------ + +Written using Microsoft Notepad. +IDE's are for children. + +How to notepad like a pro: +ctrl+f = find +ctrl+h = find & replace +ctrl+g = show/jump to line (turn off wordwrap n00b) + +Status bar wastes screen space, don't use it. + +Use https://tools.stefankueng.com/grepWin.html to mass search, find and replace many files in bulk. + +]]--------------------------------------- + + +--[[ Simple Cache & Events Manager ]]-- +--[[ Usage +cache.ent("assembling-machine-1",{built=function(ent) dostuff() end}) +cache.type("assembling-machine",{built=function(ent_with_type) dostuff() end}) + +Also has global table manager for arbitrary data on stuff. +Create/destroy manually though, still easier than writing a new handler every time. + +cache.vgui("hud_frame",{ click=function(elm,ev) + local menu=cache.get_menu("hud",ev.player_index) + cache.call_menu("clickyframe",menu,ev,...) + ..etc +end }) + +cache.menu("menu_name",{ create=function(menu,...) menu.frame=etc() end, destroy=function(menu,ev,...) forceclose() end, closed=function(menu,ev,...) onclosed() end }) +local menu=cache.raise_menu("hud",ply) +menu.frame=ply.gui.add("hud_frame",...) +... +local menu=cache.get_menu("menu_name",ply) +cache.call_menu("func_name",menu,data,...) +... +... +cache.destroy_menu(menu) -- force close menu + + +local vtbl=cache.raise_entity(entity) +... +cache.destroy_entity(vtbl) +-- etc etc + + +]]-- + +local cache={} + + +-- cache classes +cache.surfaces={} +cache.spatterns={} +cache.ents={} +cache.types={} +cache.patterns={} +cache.vguis={} +cache.gtypes={} +cache.gpatterns={} +cache.players={} +cache.forces={} +cache.fpatterns={} +cache.units={} +cache.utypes={} +cache.menus={} + +-- translate named function tables +cache.primaries={ + ent="ents",type="types",pattern="patterns", + vgui="vguis",gpattern="gpatterns",gtype="gtype", + menu="menus", + player="players",force="forces", + surface="surfaces",spattern="spatterns", + unit="units",utype="utypes", +} +-- grouped class types for event filters +cache.classes={ + ents={name="ents",type="types",ptrn="patterns"}, + vgui={name="vguis",type="gtypes",ptrn="gpatterns"}, + menus={name="menus"}, + players={single="players"}, + forces={name="forces",ptrn="fpatterns"}, + surfaces={name="surfaces",spattern="spatterns"}, +} + +for k,v in pairs(cache.primaries)do if(k~="player")then cache[k]=function(name,tbl) cache[v][name]=tbl end end end +function cache.player(tbl) cache.players=tbl end + + +cache.events={} -- Functions to distribute individual events among the caches in correct orders + +function cache.init() + storage._lib=storage._lib or {} + cache.migrate() +end + +function cache.migrate(ev) + if(storage._libcache)then storage._lib={cache=storage._libcache} storage._libcache=nil else storage._lib=storage._lib or {cache={}} end -- storage._lib.cache + storage._lib.cache=storage._lib.cache or {} + for key,category in pairs(cache.primaries)do -- storage._lib[raised_type] + storage._lib[category]=storage._lib[category] or {} + storage._lib[category.."_idx"]=storage._lib[category.."_idx"] or {} + end +end + + +function cache.load() +end + + -- helper functions for simple caching +function cache.insert(n,ent) storage._lib.cache[n]=storage._lib.cache[n] or {} table.insertExclusive(storage._lib.cache[n],ent) end +function cache.validate(n) storage._lib.cache[n]=storage._lib.cache[n] or {} for k,v in pairs(storage._lib.cache[n])do if(not isvalid(v))then storage._lib.cache[n][k]=nil end end end +function cache.remove(n,ent) storage._lib.cache[n]=storage._lib.cache[n] or {} table.RemoveByValue(storage._lib.cache[n],ent) end +function cache.get(n) if(isstring(n))then return storage._lib.cache[n] or {} end end +--function cache.call(n,evn,ev,...) for k,v in pairs(cache.get(n))do ev.entity=v cache.call_ents(evn,ev,...) end end -- Call a simple event on all entities in a cache table. +function cache.entcall(n,evn,ev,...) for k,v in pairs(cache.get(n))do ev.entity=v cache.call_ents(evn,ev,...) end end -- Call a simple event on all entities in a cache table. +function cache.surfacecall(n,evn,ev,...) for k,v in pairs(cache.get(n))do ev.entity=v cache.call_surfaces(evn,ev,...) end end -- Call a simple event on all entities in a cache table. + + + + +function cache.call_ents(vn,ev,...) local ent=events.entity(ev) if(not isvalid(ent))then return end + local tx=cache.types[ent.type=="ghost" and ent.ghost_type or ent.type] if(tx and tx[vn])then tx[vn](ent,ev,...) end if(not isvalid(ent))then return end + local tx=cache.ents[ent.type=="ghost" and ent.ghost_name or ent.name] if(tx and tx[vn])then tx[vn](ent,ev,...) end if(not isvalid(ent))then return end + local tx for k,v in pairs(cache.patterns)do if((ent.type=="ghost" and ent.ghost_name or ent.name):find(k,1,true))then tx=v break end end if(tx and tx[vn])then tx[vn](ent,ev,...) end +end +function cache.call_vgui(vn,ev,...) local elm=ev.element if(not isvalid(elm))then return end + local tx=cache.vguis[elm.name] if(tx and tx[vn])then tx[vn](ev.element,ev,...) end + local tx=cache.gtypes[elm.type] if(tx and tx[vn])then tx[vn](ev.element,ev,...) end + local tx for k,v in pairs(cache.gpatterns)do if(elm.name:find(k,1,true))then tx=v break end end if(tx and tx[vn])then tx[vn](ev.element,ev,...) end +end +function cache.call_player(vn,ev,...) local tx=cache.players[vn] if(not tx)then return end + if(tx)then tx(game.players[ev.player_index],ev,...) end +end +function cache.call_force(vn,ev,...) local f=ev.force if(not f)then f=game.forces[ev.force_index] end if(not f)then f=game.forces[ev.force_name] end if(not isvalid(f))then return end + local tx=cache.forces[f.name] if(tx and tx[vn])then tx[vn](f,ev,...) end + local tx for k,v in pairs(cache.fpatterns)do if(f.name:find(k,1,true))then tx=v break end end if(tx and tx[vn])then tx[vn](f,ev,...) end +end + +function cache.call_surface(vn,ev,...) local f=ev.surface if(not f)then f=game.surfaces[ev.surface_index] end if(not isvalid(f))then return end + local tx=cache.surfaces[f.name] if(tx and tx[vn])then tx[vn](f,ev,...) end + local tx for k,v in pairs(cache.spatterns)do if(f.name:find(k,1,true))then tx=v break end end if(tx and tx[vn])then tx[vn](f,ev,...) end +end +function cache.call_menu(vn,menu,ev,...) + local tx=cache.menus[menu.name] if(tx and tx[vn])then tx[vn](menu,ev,...) end +end + +function cache.get_index(host,key) return host[key] end + +-- Raise/destroy stuff to cache into global table. It gives us an internally managed cache table to shove data into e.g. creation/destruction of the base object. +function cache.raise_type(vtype,name,host,...) + local uid if(isnumber(host))then uid=host else local cx cx,uid=pcall(cache.get_index,host,"index") if(not cx)then cx,uid=pcall(cache.get_index,host,"unit_number") if(not cx)then uid=nil end end end + local hdx=uid + if(hdx)then local gc=storage._lib[vtype.."_idx"][hdx] if(gc and name)then gc=gc[name] end if(gc)then return gc end end -- get existing hosted/index vtype + local c=cache[vtype] -- cache["ents"][name]. You can call these manually if you need to for ptrn, surfaces etc. + if(not c)then return end if(name)then c=c[name] if(not c)then return end end -- only menus and vguis typically use names. + local idx=#storage._lib[vtype]+1 + local t={index=idx,name=name,type=vtype,host=host,hostindex=hdx} storage._lib[vtype][idx]=t + if(hdx)then + if(name)then local gc=storage._lib[vtype.."_idx"][hdx] or {} storage._lib[vtype.."_idx"][hdx]=gc gc[t.name]=t + else storage._lib[vtype.."_idx"][hdx]=t + end + end + if(c.raise)then c.raise(t,...) end + if(vtype=="ents")then if(c[host.name] and c[host.name].raise)then c[host.name].raise(t,...) end end + if(vtype=="types")then local htype=(host.is_player() and "player" or host.type) if(c[htype] and c[htype].raise)then c[htype].raise(t,...) end end + + return t +end +function cache.destroy_type(obj,...) local vtype=obj.type + local c=cache[vtype] if(not c)then return end if(obj.name)then c=c[obj.name] if(not c)then return end end + if(c.unraise)then c.unraise(obj,...) end + storage._lib[vtype][obj.index]=nil + if(obj.hostindex)then storage._lib[vtype.."_idx"][obj.hostindex]=nil end +end +function cache.get_type(vtype,name,host) local t=storage._lib[vtype.."_idx"] + if(t)then + local uid if(isnumber(host))then uid=host else local cx cx,uid=pcall(cache.get_index,host,"index") if(not cx)then cx,uid=pcall(cache.get_index,host,"unit_number") if(not cx)then uid=nil end end end + if(uid)then t=t[uid] else t=nil end + end + if(t and name)then t=t[name] end + return t +end +function cache.get_raise_type(vtype,name,host,...) return cache.get_type(vtype,name,host) or cache.raise_type(vtype,name,host,...) end +function cache.get_types(vtype) local t=storage._lib[vtype] return t end + +function cache.destroy(obj,...) return cache.destroy_type(obj,...) end -- This just destroys the cache object, not the actual in-game object. + + +function cache.raise_menu(name,ply,...) return cache.raise_type("menus",name,ply,...) end +function cache.force_menu(name,ply,...) return cache.get_raise_type("menus",name,ply,...) end +function cache.get_menu(name,ply) return cache.get_type("menus",name,ply) end +cache.destroy_menu=cache.destroy + +function cache.raise_vgui(name,menu,...) return cache.raise_type("vguis",name,menu,...) end +function cache.force_vgui(name,menu,...) return cache.get_raise_type("vguis",name,menu,...) end +function cache.get_vgui(name,menu) return cache.get_type("vguis",name,menu) end +cache.destroy_vgui=cache.destroy + +function cache.raise_player(ply,...) return cache.raise_type("players",nil,ply,...) end +function cache.force_player(ply,...) return cache.get_raise_type("players",nil,ply,...) end +function cache.get_player(ply) return cache.get_type("players",nil,ply) end +cache.destroy_player=cache.destroy + +function cache.raise_force(force,...) return cache.raise_type("forces",nil,force,...) end +function cache.force_force(force,...) return cache.get_raise_type("forces",nil,force,...) end +function cache.get_force(force) return cache.get_type("forces",nil,force) end +cache.destroy_force=cache.destroy + +function cache.raise_surface(surface,...) return cache.raise_type("surfaces",nil,surface,...) end +function cache.force_surface(surface,...) return cache.get_raise_type("surfaces",nil,surface,...) end +function cache.get_surface(surface) return cache.get_type("surfaces",nil,surface) end +cache.destroy_surface=cache.destroy + +function cache.raise_unit(unit,...) return cache.raise_type("units",nil,unit,...) end +function cache.force_unit(unit,...) return cache.get_raise_type("units",nil,unit,...) end +function cache.get_unit(unit) return cache.get_type("units",nil,unit) end +cache.destroy_unit=cache.destroy + +function cache.raise_entity(ent,...) return cache.raise_type("ents",nil,ent,...) end +function cache.force_entity(ent,...) return cache.get_raise_type("ents",nil,ent,...) end +function cache.get_entity(ent) return cache.get_type("ents",nil,ent) end +cache.destroy_entity=cache.destroy + + + +function cache.update(ent,vn,...) vn=vn or "update" + local tx=cache.types[ent.type] if(tx and tx[vn])then tx[vn](ent,...) end + local tx=cache.ents[ent.name] if(tx and tx[vn])then tx[vn](ent,...) end + local tx for k,v in pairs(cache.patterns)do if(ent.name:find(k,1,true))then tx=v break end end if(tx and tx[vn])then tx[vn](ent,...) end +end +function cache.updategui(elm,...) local vn="update" if(not isstring(elm))then elm=elm.name end + local tx=cache.vguis[elm.name] if(tx and tx[vn])then tx[vn](elm,...) end + local tx=cache.gtypes[elm.name] if(tx and tx[vn])then tx[vn](elm,...) end + local tx for k,v in pairs(cache.gpatterns)do if(elm.name:find(k,1,true))then tx=v break end end if(tx and tx[vn])then tx[vn](elm,...) end +end +function cache.updatemenu(mn,vn,ev,...) for i,ply in pairs(game.players)do + local menu=cache.get_menu(mn,ply) if(menu)then + cache.call_menu(vn,menu,ev,...) + end +end end + + + +function cache.inject_type(nm,evdata) + local funcs=cache.events[nm] + local defs=cache.events[nm.."_defs"] + local ccls=cache.classes[nm] + + + local ptrn=false + for evtype,vdefs in pairs(defs)do + if(ccls.name)then for tpnm,cls in pairs(cache[ccls.name])do if(cls[evtype])then + for _,def in pairs(vdefs)do evdata[def]=evdata[def] or {} table.insert(evdata[def],{nm=nm,tpnm=tpnm,evtype=evtype,ghost=cls.ghost,clsname=ccls.name,func=funcs[def]}) end + end end end + if(ccls.type)then for tpnm,cls in pairs(cache[ccls.type])do if(cls[evtype])then + for _,def in pairs(vdefs)do evdata[def]=evdata[def] or {} table.insert(evdata[def],{nm=nm,tpnm=tpnm,evtype=evtype,ghost=cls.ghost,clstype=ccls.type,func=funcs[def]}) end + end end end + if(ccls.ptrn)then for tpnm,cls in pairs(cache[ccls.ptrn])do if(cls[evtype])then ptrn=true + for _,def in pairs(vdefs)do evdata[def]=evdata[def] or {} table.insert(evdata[def],{nm=nm,tpnm=tpnm,evtype=evtype,ghost=cls.ghost,clsptrn=ccls.ptrn,func=funcs[def]}) end + end end end + if(ccls.single)then local cls=cache[ccls.single] if(cls[evtype])then + for _,def in pairs(vdefs)do evdata[def]=evdata[def] or {} table.insert(evdata[def],{nm=nm,tpnm=tpnm,evtype=evtype,ghost=cls.ghost,clssingle=ccls.single,func=funcs[def]}) end + end end + end + --if(nm=="players")then error(serpent.block(evdata)) end +end + + +function cache.inject() -- interface with events + local evdata={} for nm in pairs(cache.classes)do cache.inject_type(nm,evdata) end + --error(serpent.block(evdata)) + for def,tbl in pairs(evdata)do + local filters={} + local nmf,tpf,ptf,sgf + --if(events.events_with_filters[def])then + for i,vtbl in pairs(tbl)do + if(vtbl.clsptrn)then ptf=vtbl.func filters=nil + elseif(vtbl.clstype)then tpf=vtbl.func + if(filters)then table.insert(filters,{filter="type",type=vtbl.tpnm}) + if(vtbl.ghost)then table.insert(filters,{filter="ghost_type",type=vtbl.tpnm}) end + end + elseif(vtbl.clsname)then nmf=vtbl.func + if(filters)then table.insert(filters,{filter="name",name=vtbl.tpnm}) + if(vtbl.ghost)then table.insert(filters,{filter="ghost_name",name=vtbl.tpnm}) end + end + elseif(vtbl.clssingle)then sgf=vtbl.func filters=nil + end + end + --end + if(not events.events_with_filters[def])then filters=nil end + + if(nmf)then events.hook(defines.events[def],nmf,filters) end + if(tpf)then events.hook(defines.events[def],tpf,filters) end + if(ptf)then events.hook(defines.events[def],ptf,filters) end + if(sgf)then events.hook(defines.events[def],sgf,filters) end + end +end + +--[[ Unknowns +on_put_item +on_ai_command_completed + +on_difficulty_settings_changed +on_cutscene_waypout_reached + +on_console_command +on_console_chat + +on_chart_tag_added +on_chart_tag_modified +on_chart_tag_removed -- force events + +on_game_created_from_scenario + +on_robot_built_entity +on_robot_built_tile +on_robot_exploded_cliff +on_robot_mined +on_robot_mined_entity +on_robot_mined_tile +on_robot_pre_mined +on_rocket_launch_ordered +on_rocket_launched +on_runtime_mod_setting_changed +on_script_path_request_finished -- pathfinding +on_sector_scanned -- radar +on_string_translated + +on_train_changed_state +on_train_created +on_train_schedule_changed + +on_trigger_fired_artillery + +on_unit_added_to_group +on_unit_group_created +on_unit_removed_from_group +on_biter_base_built + + +on_market_item_purchased + + +]] + + +cache.events.forces={} +function cache.events.forces.on_research_finished(ev) cache.call_force("research_finished",ev) end +function cache.events.forces.on_research_started(ev) cache.call_force("research_started",ev) end +function cache.events.forces.on_technology_effects_reset(ev) cache.call_force("research_reset",ev) end +function cache.events.forces.on_chart_tag_added(ev) cache.call_force("tag_added",ev) end +function cache.events.forces.on_chart_tag_modified(ev) cache.call_force("tag_modified",ev) end +function cache.events.forces.on_chart_tag_removed(ev) cache.call_force("tag_removed",ev) end + +cache.events.forces_defs={ -- Things that specifically are called with a force. Player stuff can be hooked from players. + research_finished={"on_research_finished"}, + research_started={"on_research_started"}, + research_reset={"on_technology_effects_reset"}, +} + +cache.events.ents={} +function cache.events.ents.on_built_entity(ev) cache.call_ents("built",ev) cache.call_ents("create",ev) end +function cache.events.ents.script_raised_built(ev) cache.call_ents("create",ev) end +function cache.events.ents.on_entity_cloned(ev) cache.call_ents("clone",ev) cache.call_ents("create",ev) end +function cache.events.ents.on_robot_built_entity(ev) cache.call_ents("built",ev) cache.call_ents("create",ev) end +function cache.events.ents.script_raised_destroy(ev) cache.call_ents("destroy",ev) end +function cache.events.ents.on_entity_died(ev) cache.call_ents("died",ev) cache.call_ents("destroy",ev) end +function cache.events.ents.on_post_entity_died(ev) cache.call_ents("post_died",ev) end +function cache.events.ents.on_player_mined_entity(ev) cache.call_ents("mined",ev) cache.call_ents("destroy",ev) end +function cache.events.ents.on_robot_mined_entity(ev) cache.call_ents("mined",ev) cache.call_ents("destroy",ev) end +function cache.events.ents.on_player_rotated_entity(ev) cache.call_ents("rotate",ev) end +function cache.events.ents.on_entity_settings_pasted(ev) cache.call_ents("settings_pasted",ev) end +function cache.events.ents.on_pre_entity_settings_pasted(ev) cache.call_ents("pre_settings_pasted",ev) end +function cache.events.ents.on_cancelled_deconstruction(ev) cache.call_ents("cancel_deconstruct",ev) end +function cache.events.ents.on_cancelled_upgrade(ev) cache.call_ents("cancel_upgrade",ev) end +function cache.events.ents.on_marked_for_deconstruction(ev) cache.call_ents("deconstruct",ev) end +function cache.events.ents.on_marked_for_upgrade(ev) cache.call_ents("upgrade",ev) end +function cache.events.ents.on_pre_ghost_deconstructed(ev) cache.call_ents("deconstruct_ghost",ev) end +function cache.events.ents.on_post_entity_died(ev) cache.call_ents("post_died",ev) end +function cache.events.ents.on_mod_item_opened(ev) cache.call_ents("item_menu",ev) end +function cache.events.ents.on_entity_damaged(ev) cache.call_ents("damage",ev) end +function cache.events.ents.on_trigger_created_entity(ev) cache.call_ents("trigger",ev) end +function cache.events.ents.on_entity_spawned(ev) cache.call_ents("spawned",ev) end +function cache.events.ents.on_land_mine_armed(ev) cache.call_ents("mine_armed",ev) end +function cache.events.ents.on_gui_opened(ev) cache.call_ents("gui_opened",ev) end +function cache.events.ents.on_gui_closed(ev) cache.call_ents("gui_closed",ev) end +function cache.events.ents.on_pre_robot_exploded_cliff(ev) cache.call_ents("pre_robot_exploded_cliff",ev) end +function cache.events.ents.on_post_entity_died(ev) cache.call_ents("post_died",ev) end +function cache.events.ents.on_combat_robot_expired(ev) cache.call_ents("robot_expired",ev) end +function cache.events.ents.script_raised_revive(ev) cache.call_ents("create",ev) end +function cache.events.ents.on_entity_renamed(ev) cache.call_ents("rename",ev) end + +cache.events.ents_defs={ + built={"on_built_entity","on_robot_built_entity"}, + create={"on_built_entity","script_raised_built","on_entity_cloned","on_robot_built_entity","script_raised_revive"}, + mined={"on_player_mined_entity","on_robot_mined_entity"}, + rotate={"on_player_rotated_entity"}, + rename={"on_entity_renamed"}, + destroy={"on_player_mined_entity","on_robot_mined_entity","script_raised_destroy","on_entity_died"}, + + died={"on_entity_died"}, + post_died={"on_post_entity_died"}, + + settings_pasted={"on_entity_settings_pasted"}, + pre_settings_pasted={"on_pre_entity_settings_pasted"}, + cancel_deconstruct={"on_cancelled_deconstruction"}, + cancel_upgrade={"on_cancelled_upgrade"}, + deconstruct={"on_marked_for_deconstruction"}, + deconstruct_ghost={"on_pre_ghost_deconstructed"}, + + upgrade={"on_marked_for_upgrade"}, + + gui_opened={"on_gui_opened"}, + gui_closed={"on_gui_closed"}, + + item_menu={"on_mod_item_opened"}, --Called when the player uses the 'Open item GUI' control on an item defined with 'can_be_mod_opened' as true + damage={"on_entity_damaged"}, + trigger={"on_trigger_created_entity"}, + robot_expired={"on_combat_robot_expired"}, + + spawned={"on_entity_spawned"}, + mine_armed={"on_land_mine_armed"}, + + pre_robot_exploded_cliff={"on_pre_robot_exploded_cliff"}, + post_died={"on_post_entity_died"}, +} + + +cache.events.vgui={} +function cache.events.vgui.on_gui_opened(ev) cache.call_vgui("open_menu",ev) end +function cache.events.vgui.on_gui_closed(ev) cache.call_vgui("gui_closed",ev) cache.call_vgui("gui_closed",ev) end +function cache.events.vgui.on_gui_click(ev) cache.call_vgui("click",ev) end +function cache.events.vgui.on_gui_confirmed(ev) cache.call_vgui("confirm",ev) end +function cache.events.vgui.on_gui_text_changed(ev) cache.call_vgui("text_changed",ev) end +function cache.events.vgui.on_gui_selection_state_changed(ev) cache.call_vgui("selection_changed",ev) end +function cache.events.vgui.on_player_display_resolution_changed(ev) cache.call_vgui("on_resolution",ev) end +function cache.events.vgui.on_player_display_scale_changed(ev) cache.call_vgui("on_scale",ev) end +function cache.events.vgui.on_gui_checked_state_changed(ev) cache.call_vgui("on_checked",ev) end +function cache.events.vgui.on_gui_elem_changed(ev) cache.call_vgui("elem_changed",ev) end +function cache.events.vgui.on_gui_location_changed(ev) cache.call_vgui("location_changed",ev) end +function cache.events.vgui.on_gui_selected_tab_changed(ev) cache.call_vgui("tab_changed",ev) end +function cache.events.vgui.on_gui_switch_state_changed(ev) cache.call_vgui("on_switched",ev) end +function cache.events.vgui.on_gui_value_changed(ev) cache.call_vgui("value_changed",ev) end + +cache.events.vgui_defs={ + click={"on_gui_click"}, + open_menu={"on_gui_opened"}, + gui_closed={"on_gui_closed"}, + confirm={"on_gui_confirmed"}, + text_changed={"on_gui_text_changed"}, + selection_changed={"on_gui_selection_state_changed"}, + on_resolution={"on_player_display_resolution_changed"}, + on_scale={"on_player_display_scale_changed"}, + on_checked={"on_gui_checked_state_changed"}, + elem_changed={"on_gui_elem_changed"}, + location_changed={"on_gui_location_changed"}, + tab_changed={"on_gui_selected_tab_changed"}, + on_switched={"on_gui_switch_state_changed"}, + value_changed={"on_gui_value_changed"}, +} + + + +cache.events.surfaces={} +function cache.events.surfaces.on_surface_created(ev) cache.call_surface("create",ev) end +function cache.events.surfaces.on_pre_surface_deleted(ev) cache.call_surface("pre_deleted",ev) end +function cache.events.surfaces.on_pre_surface_cleared(ev) cache.call_surface("pre_cleared",ev) end +function cache.events.surfaces.on_surface_deleted(ev) cache.call_surface("on_deleted",ev) end +function cache.events.surfaces.on_surface_imported(ev) cache.call_surface("import",ev) end +function cache.events.surfaces.on_surface_renamed(ev) cache.call_surface("rename",ev) end +function cache.events.surfaces.on_chunk_generated(ev) cache.call_surface("chunk",ev) end +function cache.events.surfaces.on_chunk_deleted(ev) cache.call_surface("chunk_deleted",ev) end +function cache.events.surfaces.on_pre_chunk_deleted(ev) cache.call_surface("pre_chunk_deleted",ev) end +function cache.events.surfaces.on_chunk_charted(ev) cache.call_surface("chart",ev) end + +cache.events.surfaces_defs={ + create={"on_surface_created"}, + pre_deleted={"on_pre_surface_deleted"}, + pre_cleared={"on_pre_surface_cleared"}, + on_cleared={"on_surface_cleared"}, + on_deleted={"on_surface_deleted"}, + + import={"on_surface_imported"}, + rename={"on_surface_renamed"}, + chunk={"on_chunk_generated"}, + chunk_deleted={"on_chunk_deleted"}, + pre_chunk_deleted={"on_pre_chunk_deleted"}, + + chart={"on_chunk_charted"}, +} + +cache.events.players={} +function cache.events.players.on_player_toggled_alt_mode(ev) cache.call_player("on_alt",ev) end +function cache.events.players.on_player_toggled_map_editor(ev) cache.call_player("on_editor",ev) end +function cache.events.players.on_player_cheat_mode_enabled(ev) cache.call_player("on_cheat",ev) end +function cache.events.players.on_player_cheat_mode_disabled(ev) cache.call_player("on_uncheat",ev) end +function cache.events.players.on_player_driving_changed_state(ev) cache.call_player("on_driving",ev) end +function cache.events.players.on_pickup_item(ev) cache.call_player("on_pickup_item",ev) end +function cache.events.players.on_player_dropped_item(ev) cache.call_player("on_drop_item",ev) end +function cache.events.players.on_player_fast_transferred(ev) cache.call_player("on_fast_transfer",ev) end +function cache.events.players.on_player_gun_inventory_changed(ev) cache.call_player("on_gun_inv",ev) end +function cache.events.players.on_player_ammo_inventory_changed(ev) cache.call_player("on_ammo_changed",ev) end +function cache.events.players.on_player_armor_inventory_changed(ev) cache.call_player("on_armor_changed",ev) end +function cache.events.players.on_player_placed_equipment(ev) cache.call_player("on_equip",ev) end +function cache.events.players.on_player_removed_equipment(ev) cache.call_player("on_dequip",ev) end + +function cache.events.players.on_built_tile(ev) cache.call_player("on_built_tile",ev) end +function cache.events.players.on_built_entity(ev) cache.call_player("on_built",ev) end +function cache.events.players.on_player_changed_position(ev) cache.call_player("on_position",ev) end +function cache.events.players.on_player_changed_surface(ev) cache.call_player("on_surface",ev) end +function cache.events.players.on_character_corpse_expired(ev) cache.call_player("on_corpse_expired",ev) end +function cache.events.players.on_lua_shortcut(ev) cache.call_player("on_shortcut",ev) end +function cache.events.players.on_player_alt_selected_area(ev) cache.call_player("on_alt_select_area",ev) end +function cache.events.players.on_player_deconstructed_area(ev) cache.call_player("on_deconstruct_area",ev) end +function cache.events.players.on_player_selected_area(ev) cache.call_player("on_select_area",ev) end +function cache.events.players.on_player_configured_blueprint(ev) cache.call_player("on_blueprint",ev) end +function cache.events.players.on_player_setup_blueprint(ev) cache.call_player("on_setup_blueprint",ev) end +function cache.events.players.on_selected_entity_changed(ev) cache.call_player("on_selected_entity_changed",ev) end +function cache.events.players.on_player_respawned(ev) cache.call_player("on_respawn",ev) end +function cache.events.players.on_player_created(ev) cache.call_player("on_create",ev) end +function cache.events.players.on_player_joined_game(ev) cache.call_player("on_join",ev) end +function cache.events.players.on_player_banned(ev) cache.call_player("on_banned",ev) end +function cache.events.players.on_player_left_game(ev) cache.call_player("on_left",ev) end +function cache.events.players.on_player_removed(ev) cache.call_player("on_removed",ev) end +function cache.events.players.on_pre_player_left_game(ev) cache.call_player("on_pre_left",ev) end +function cache.events.players.on_pre_player_removed(ev) cache.call_player("on_pre_removed",ev) end +function cache.events.players.on_player_unbanned(ev) cache.call_player("on_unban",ev) end +function cache.events.players.on_player_unmuted(ev) cache.call_player("on_unmute",ev) end +function cache.events.players.on_player_demoted(ev) cache.call_player("on_demoted",ev) end +function cache.events.players.on_player_died(ev) cache.call_player("on_died",ev) end +function cache.events.players.on_pre_player_died(ev) cache.call_player("on_pre_died",ev) end +function cache.events.players.on_player_muted(ev) cache.call_player("on_muted",ev) end +function cache.events.players.on_player_promoted(ev) cache.call_player("on_promoted",ev) end +function cache.events.players.on_player_main_inventory_changed(ev) cache.call_player("on_inventory",ev) end +function cache.events.players.on_player_mined_entity(ev) cache.call_player("on_mined",ev) end +function cache.events.players.on_pre_player_mined_item(ev) cache.call_player("on_pre_mined_item",ev) end +function cache.events.players.on_player_mined_item(ev) cache.call_player("on_mined_item",ev) end +function cache.events.players.on_player_mined_tile(ev) cache.call_player("on_mined_tile",ev) end +function cache.events.players.on_player_cursor_stack_changed(ev) cache.call_player("on_cursor",ev) end +function cache.events.players.on_player_pipette(ev) cache.call_player("on_pipette",ev) end +function cache.events.players.on_player_cancelled_crafting(ev) cache.call_player("on_cancel_craft",ev) end +function cache.events.players.on_pre_player_crafted_item(ev) cache.call_player("on_pre_craft",ev) end +function cache.events.players.on_player_crafted_item(ev) cache.call_player("on_craft",ev) end +function cache.events.players.on_player_repaired_entity(ev) cache.call_player("on_repair",ev) end +function cache.events.players.on_player_rotated_entity(ev) cache.call_player("on_rotate",ev) end +function cache.events.players.on_player_trash_inventory_changed(ev) cache.call_player("on_trash_changed",ev) end +function cache.events.players.on_player_used_capsule(ev) cache.call_player("on_capsule",ev) end + + +cache.events.players_defs={ + + on_alt={"on_player_toggled_alt_mode"}, + on_editor={"on_player_toggled_map_editor"}, + + on_cheat={"on_player_cheat_mode_enabled"}, + on_uncheat={"on_player_cheat_mode_disabled"}, + + on_driving={"on_player_driving_changed_state"}, + + on_pickup_item={"on_picked_up_item"}, + on_drop_item={"on_player_dropped_item"}, + + on_fast_transfer={"on_player_fast_transferred"}, + on_gun_inv={"on_player_gun_inventory_changed"}, + on_ammo_changed={"on_player_ammo_inventory_changed"}, + on_armor_changed={"on_player_armor_inventory_changed"}, + on_equip={"on_player_placed_equipment"}, + on_dequip={"on_player_removed_equipment"}, + + on_built_tile={"on_player_built_tile"}, + on_built={"on_entity_built"}, + + on_position={"on_player_changed_position"}, + on_surface={"on_player_changed_surface"}, + + on_corpse_expired={"on_character_corpse_expired"}, + + on_shortcut={"on_lua_shortcut"}, + on_alt_select_area={"on_player_alt_selected_area"}, + on_deconstruct_area={"on_player_deconstructed_area"}, + on_select_area={"on_player_selected_area"}, + + + on_blueprint={"on_player_configured_blueprint"}, + on_setup_blueprint={"on_player_setup_blueprint"}, + + on_select={"on_selected_entity_changed"}, + + on_respawn={"on_player_respawned"}, + on_create={"on_player_created"}, + on_join={"on_player_joined_game"}, + + on_banned={"on_player_banned"}, + on_left={"on_player_left_game"}, + on_removed={"on_player_removed"}, + on_pre_left={"on_pre_player_left_game"}, + on_pre_removed={"on_pre_player_removed"}, + + on_unban={"on_player_unbanned"}, + on_unmute={"on_player_unmuted"}, + on_demote={"on_player_demoted"}, + + on_died={"on_player_died"}, + on_pre_died={"on_pre_player_died"}, + + on_muted={"on_player_muted"}, + on_promoted={"on_player_promoted"}, + + on_inventory={"on_player_main_inventory_changed"}, + on_mined={"on_player_mined_entity"}, + on_pre_mined_item={"on_pre_player_mined_item"}, + on_mined_item={"on_player_mined_item"}, + on_mined_tile={"on_player_mined_tile"}, + + on_cursor={"on_player_cursor_stack_changed"}, + on_pipette={"on_player_pipette"}, + + on_cancel_craft={"on_player_cancelled_crafting"}, + on_pre_craft={"on_pre_player_crafted_item"}, + on_craft={"on_player_crafted_item"}, + + on_repair={"on_player_repaired_entity"}, + on_rotate={"on_player_rotated_entity"}, + + on_trash_changed={"on_player_trash_inventory_changed"}, + + on_capsule={"on_player_used_capsule"}, + +} +cache.events.menus={} +cache.events.menus_defs={ +} + return cache \ No newline at end of file diff --git a/lib/lib_control_grid.lua b/lib/lib_control_grid.lua index 3753d20..0c42c01 100644 --- a/lib/lib_control_grid.lua +++ b/lib/lib_control_grid.lua @@ -1,40 +1,40 @@ ---[[------------------------------------- - -Author: Pyro-Fire -https://patreon.com/pyrofire - -Script: lib_grid.lua -Purpose: grid manager stuff - ------ - -Copyright (c) 2019 Pyro-Fire - -I put a lot of work into these library files. Please retain the above text and this copyright disclaimer message in derivatives/forks. - -Permission to use, copy, modify, and/or distribute this software for any -purpose without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ------- - -Written using Microsoft Notepad. -IDE's are for children. - -How to notepad like a pro: -ctrl+f = find -ctrl+h = find & replace -ctrl+g = show/jump to line (turn off wordwrap n00b) - -Status bar wastes screen space, don't use it. - -Use https://tools.stefankueng.com/grepWin.html to mass search, find and replace many files in bulk. - -]]--------------------------------------- +--[[------------------------------------- + +Author: Pyro-Fire +https://patreon.com/pyrofire + +Script: lib_grid.lua +Purpose: grid manager stuff + +----- + +Copyright (c) 2019 Pyro-Fire + +I put a lot of work into these library files. Please retain the above text and this copyright disclaimer message in derivatives/forks. + +Permission to use, copy, modify, and/or distribute this software for any +purpose without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +------ + +Written using Microsoft Notepad. +IDE's are for children. + +How to notepad like a pro: +ctrl+f = find +ctrl+h = find & replace +ctrl+g = show/jump to line (turn off wordwrap n00b) + +Status bar wastes screen space, don't use it. + +Use https://tools.stefankueng.com/grepWin.html to mass search, find and replace many files in bulk. + +]]--------------------------------------- diff --git a/lib/lib_control_logic.lua b/lib/lib_control_logic.lua index 57f5c22..5219e20 100644 --- a/lib/lib_control_logic.lua +++ b/lib/lib_control_logic.lua @@ -1,55 +1,55 @@ ---[[------------------------------------- - -Author: Pyro-Fire -https://patreon.com/pyrofire - -Script: lib_control_logic.lua -Purpose: control stage logic - ------ - -Copyright (c) 2019 Pyro-Fire - -I put a lot of work into these library files. Please retain the above text and this copyright disclaimer message in derivatives/forks. - -Permission to use, copy, modify, and/or distribute this software for any -purpose without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ------- - -Written using Microsoft Notepad. -IDE's are for children. - -How to notepad like a pro: -ctrl+f = find -ctrl+h = find & replace -ctrl+g = show/jump to line (turn off wordwrap n00b) - -Status bar wastes screen space, don't use it. - -Use https://tools.stefankueng.com/grepWin.html to mass search, find and replace many files in bulk. - -]]--------------------------------------- - - - ---[[ Unused - - -function warptorio.GetFastestLoader() -- currently unused - if(warptorio.FastestLoader)then return warptorio.FastestLoader end if(true)then return "express-loader" end - local ld={} local topspeed=game.entity_prototypes["express-loader"].belt_speed local top="express-loader" - for k,v in pairs(game.entity_prototypes)do if(v.type=="loader")then table.insert(ld,v) end end - for k,v in pairs(ld)do if(not v.name:match("warptorio") and not v.name:match("mini") and v.belt_speed>=topspeed)then topspeed=v.belt_speed top=v.name end end - warptorio.FastestLoader=top return top -end - +--[[------------------------------------- + +Author: Pyro-Fire +https://patreon.com/pyrofire + +Script: lib_control_logic.lua +Purpose: control stage logic + +----- + +Copyright (c) 2019 Pyro-Fire + +I put a lot of work into these library files. Please retain the above text and this copyright disclaimer message in derivatives/forks. + +Permission to use, copy, modify, and/or distribute this software for any +purpose without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +------ + +Written using Microsoft Notepad. +IDE's are for children. + +How to notepad like a pro: +ctrl+f = find +ctrl+h = find & replace +ctrl+g = show/jump to line (turn off wordwrap n00b) + +Status bar wastes screen space, don't use it. + +Use https://tools.stefankueng.com/grepWin.html to mass search, find and replace many files in bulk. + +]]--------------------------------------- + + + +--[[ Unused + + +function warptorio.GetFastestLoader() -- currently unused + if(warptorio.FastestLoader)then return warptorio.FastestLoader end if(true)then return "express-loader" end + local ld={} local topspeed=game.entity_prototypes["express-loader"].belt_speed local top="express-loader" + for k,v in pairs(game.entity_prototypes)do if(v.type=="loader")then table.insert(ld,v) end end + for k,v in pairs(ld)do if(not v.name:match("warptorio") and not v.name:match("mini") and v.belt_speed>=topspeed)then topspeed=v.belt_speed top=v.name end end + warptorio.FastestLoader=top return top +end + ]] \ No newline at end of file diff --git a/lib/lib_data.lua b/lib/lib_data.lua index b2bce1b..a6a7fb3 100644 --- a/lib/lib_data.lua +++ b/lib/lib_data.lua @@ -1,219 +1,219 @@ ---[[------------------------------------- - -Author: Pyro-Fire -https://patreon.com/pyrofire - -Script: lib_data.lua -Purpose: data library - ------ - -Copyright (c) 2019 Pyro-Fire - -I put a lot of work into these library files. Please retain the above text and this copyright disclaimer message in derivatives/forks. - -Permission to use, copy, modify, and/or distribute this software for any -purpose without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ------- - -Written using Microsoft Notepad. -IDE's are for children. - -How to notepad like a pro: -ctrl+f = find -ctrl+h = find & replace -ctrl+g = show/jump to line (turn off wordwrap n00b) - -Status bar wastes screen space, don't use it. - -Use https://tools.stefankueng.com/grepWin.html to mass search, find and replace many files in bulk. - -]]--------------------------------------- - ---[[ Prototype/data stage libraries ]]-- - -local proto={} - - - - ---[[ Prototyping Data Stuff ]]-- - - - --- All the different things an item can be --- See also data.raw["item-subgroup"][k].name - -proto.ItemGroups={"item","tool","gun","ammo","capsule","armor","repair-tool","car","module","locomotive","cargo-wagon","artillery-wagon","fluid-wagon","rail-planner","item-with-entity-data"} - --- All the different things an item can be place_result'd as -proto.PlacementGroups={ -"accumulator","ammo-turret","arithmetic-combinator","artillery-turret","artillery-wagon","assembling-machine", -"beacon","boiler", -"car","cargo-wagon","character","constant-combinator","container", -"decider-combinator", -"electric-energy-interface","electric-turret","electric-pole", -"fluid-turret","fluid-wagon","furnace", -"gate","generator", -"heat-pipe", -"inserter", -"lab","loader","logistic-container","logistic-robot", -"mining-drill", -"offshore-pump", -"pipe","pipe-to-ground","power-switch","programmable-speaker","pump", -"radar","reactor","roboport","rocket-silo", -"simple-entity","simple-entity-with-force","simple-entity-with-owner","solar-panel","splitter","storage-tank", -"train-stop","transport-belt", -"underground-belt", -"wall", -} - -function proto.Recache() proto._items=nil proto._placeables=nil proto._labpacks=nil proto._used=nil proto._furnacecat=nil end - -function proto.CacheItems() local t={} for k,v in pairs(proto.ItemGroups)do for x,y in pairs(data.raw[v])do t[y.name]=y end end proto._items=t return t end -function proto.Items(b) return (proto._items and (not b and proto._items or proto.CacheItems()) or proto.CacheItems()) end -function proto.RawItem(n,b) return proto.Items(b)[n] end - -function proto.CacheLabPacks() local tx={} for k,v in pairs(data.raw.lab)do local vin=v.inputs for i,e in pairs(vin)do tx[e]=e end end proto._labpacks=tx return tx end -function proto.GetLabPacks(b) return (proto._labpacks and (not b and proto._labpacks or proto.CacheLabPacks()) or proto.CacheLabPacks()) end -function proto.LabPack(n,b) return proto.GetLabPacks(b)[n] end - -function proto.CachePlaceables() local t={} for k,v in pairs(proto.PlacementGroups)do for x,y in pairs(data.raw[v])do t[y.name]=y end end proto._placeables=t return t end -function proto.Placeables(b) return (proto._placeables and (not b and proto._placeables or proto.CachePlaceables()) or proto.CachePlaceables()) end -function proto.RawPlaceable(n,b) return proto.Placeables(b)[n] end -- place_result_entity -proto.PlaceResultEntity=proto.RawPlaceable --alias - -function proto.CacheUsedRecipes() local t={} - for k,v in pairs(data.raw.technology)do local fx=proto.TechEffects(v) for i,rcp in pairs(fx.recipes)do t[rcp]=true end end - for k,v in pairs(data.raw.recipe)do if(proto.IsEnabled(v))then t[v.name]=true end end -proto._used=t return t end -function proto.UsedRecipes() return (proto._used and (not b and proto._used or proto.CacheUsedRecipes()) or proto.CacheUsedRecipes()) end -function proto.UsedRecipe(n,b) return proto.UsedRecipes(b)[n] end -function proto.CountUsedRecipes() return table_size(proto.UsedRecipes()) end -function proto.CountUnsedRecipes() return table_size(data.raw.recipe)-proto.CountUsedRecipes() end - -function proto.IsAutoplaceControl(t) local dra=data.raw["autoplace-control"] if(dra[t.name] or dra[t.type] or (t.autoplace and t.autoplace.control))then return true end return false end - -function proto.HasFluidbox(t) return t.fluid_box or t.fluid_boxes or t.input_fluid_box or t.output_fluid_box end - -function proto.CacheFurnaceCats() local t={} for k,v in pairs(data.raw.furnace)do for cc in pairs(proto.CraftingCategories(v))do t[cc]=cc end end proto._furnacecat=t return t end -function proto.FurnaceCats(b) return (proto._furnacecat and (not b and proto._furnacecat or proto.CacheFurnaceCats()) or proto.CacheFurnaceCats()) end -function proto.FurnaceCat(n,b) return proto.FurnaceCats(b)[n] end - -function proto.Name(t) return (isstring(t) and t or (t.name and t.name or (isstring(t[1]) and t[1] or false))) end - -function proto.Fluids() return data.raw.fluid end -function proto.Recipes() return data.raw.recipe end -function proto.Techs() return data.raw.technology end - -function proto.IsEnabled(v) local c=false - if(tostring(v.enabled)=="true")then c=true end - if(v.normal and tostring(v.normal.enabled)=="true")then c=true end - if(v.expensive and tostring(v.expensive.enabled)=="true")then c=true end - --if(v.enabled==nil and (not v.normal or v.normal and v.normal.enabled==nil) and (not v.expensive or v.expensive and v.expensive.enabled==nil))then return true end - return c -end -function proto.IsDisabled(v) local c=false - if(tostring(v.enabled)=="false")then c=true end - if(v.normal and tostring(v.normal.enabled)=="false")then c=true end - if(v.expensive and tostring(v.expensive.enabled)=="false")then c=true end - --if(v.enabled==nil and (not v.normal or v.normal and v.normal.enabled==nil) and (not v.expensive or v.expensive and v.expensive.enabled==nil))then return true end - return c -end - -proto.IsTechnologyEnabled=proto.IsEnabled -- alias - -function proto.IsHidden(v) - if(tostring(v.hidden)=="true")then return true end - if(v.normal and tostring(v.normal.hidden)=="true")then return true end - if(v.expensive and tostring(v.expensive.hidden)=="true")then return true end - return false -end - - - -proto.Difficulties={[0]="standard",[1]="normal",[2]="expensive"} -function proto.Normal(t) local v=t if(t.normal)then v=t.normal elseif(t.expensive)then v=t.expensive end return v end -function proto.FetchDifficultyLayer(tx,seek) - local t=tx if(t)then for k,v in pairs(seek)do if(t[v])then return t,0 end end end - local t=tx.normal if(t)then for k,v in pairs(seek)do if(t[v])then return t,1 end end end - local t=tx.expensive if(t)then for k,v in pairs(seek)do if(t[v])then return t,2 end end end -end - -function proto.Result(t) if(t[1] and t[2])then return {type="item",name=t[1],amount=t[2]} else return t end end -function proto.Results(tx) local t,dfc=proto.FetchDifficultyLayer(tx,{"result","results"}) if(t)then if(t.results)then rs=t.results else rs={{t.result,t.result_count or 1}} end end return rs,dfc end -function proto.Ingredient(t) return proto.Result(t) end -function proto.Ingredients(tx) local t,dfc=proto.FetchDifficultyLayer(tx,{"ingredients"}) return (t and t.ingredients),dfc end - --- Fetch the raw item/object/etc -function proto.CraftingObject(rs) local raw=proto.RawItem(rs.name) return raw or data.raw.fluid[rs.name] end -function proto.ResultObject(t) local rs=proto.Result(t) return proto.CraftingObject(rs) end -function proto.IngredientObject(t) local rs=proto.Ingredient(t) return proto.CraftingObject(rs) end - -function proto.TechBottles(tz) local t,dfc=proto.FetchDifficultyLayer(tz,{"unit"}) if(not t or not t.unit or not t.unit.ingredients)then return end - local tx={} for k,v in pairs(t.unit.ingredients)do local rs=proto.Ingredient(v) tx[rs.name]=rs.name end return tx -end -function proto.LoopTech(n,p) p=p or {} p[n]=true local r=data.raw.technology[n] for k,v in pairs(r.prerequisites or {})do if(not p[v])then proto.LoopTech(v,p) end end return p end -function proto.RecursiveTechBottles(g) local t={} for n in pairs(proto.LoopTech(g.name))do local c,u=data.raw.technology[n] u=proto.TechBottles(c) for k,v in pairs(u)do t[v]=true end end return t end - -function proto.TechEffects(g) local t={recipes={},items={},c=0} if(not g.effects)then return t end - for k,v in pairs(g.effects)do local x=v.type if(x=="unlock-recipe")then table.insert(t.recipes,v.recipe) t.c=t.c+1 elseif(x=="give-item")then table.insert(x.items,v.item) t.c=t.c+1 end end - return t -end - -function proto.CraftingCategories(t) if(isstring(t))then return {t} end return t end -function proto.FuelCategories(t) local x - if(t.fuel_category)then x={} table.insert(x,t.fuel_category) end - if(t.fuel_categories)then x=x or {} for k,v in pairs(t.fuel_categories)do table.insertExclusive(x,v) end end - return x -end - -function proto.MinableResults(tx) - return {} -end - -function proto.GetRawAutoplacers(raw,vfunc) local t={} -- data.raw.resource,data.raw.tree vfunc(v) return true_is_valid end - for n,rsc in pairs(raw)do if(rsc.minable and proto.IsAutoplaceControl(rsc) and (not vfunc or (vfunc and vfunc(rsc))) )then - local rs=proto.Results(rsc.minable) - if(rs)then for k,v in pairs(rs)do local rso=proto.ResultObject(v) - if(not t[rso.name])then t[rso.name]={type=(rso.type~="fluid" and "item" or "fluid"),name=rso.name,proto=rsc} end - end end - end end - return t -end -function proto.GetRawResources() return proto.GetRawAutoplacers(data.raw.resource) end -function proto.GetRawTrees() return proto.GetRawAutoplacers(data.raw.tree) end -function proto.GetRawRocks() return proto.GetRawAutoplacers(data.raw["simple-entity"],function(v) return v.count_as_rock_for_filtered_deconstruction end) end -function proto.GetRaw() local t={} for k,v in pairs({proto.GetRawResources(),proto.GetRawTrees(),proto.GetRawRocks()})do for i,e in pairs(v)do table.insertExclusive(t,e) end end return t end - - -function proto.Copy(a,b,x) local t=table.deepcopy(data.raw[a][b]) if(x)then table.deepmerge(t,x) end return t end - -function proto.ExtendBlankEntityItems(ent) - local rcp=proto.Copy("recipe","nuclear-reactor") - rcp.enabled=false rcp.name=ent.name rcp.ingredients={{"steel-plate",1}} rcp.result=ent.name - - local item=proto.Copy("item","nuclear-reactor") - item.name=ent.name item.place_result=ent.name - data:extend{rcp,item} -end - - -proto.VanillaPacks={red="automation-science-pack",green="logistic-science-pack",blue="chemical-science-pack",black="military-science-pack", - purple="production-science-pack",yellow="utility-science-pack",white="space-science-pack"} - -function proto.SciencePacks(x) local t={} for k,v in pairs(x)do table.insert(t,{proto.VanillaPacks[k],v}) end return t end -function proto.ExtendTech(t,d,s) local x=table.merge(t,d) if(s)then x.unit.ingredients=proto.SciencePacks(s) end data:extend{x} return x end - -function proto.Icons(p) if(p.icons)then return p.icons end if(p.icon)then return {{icon=p.icon,icon_size=p.icon_size}} end end - +--[[------------------------------------- + +Author: Pyro-Fire +https://patreon.com/pyrofire + +Script: lib_data.lua +Purpose: data library + +----- + +Copyright (c) 2019 Pyro-Fire + +I put a lot of work into these library files. Please retain the above text and this copyright disclaimer message in derivatives/forks. + +Permission to use, copy, modify, and/or distribute this software for any +purpose without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +------ + +Written using Microsoft Notepad. +IDE's are for children. + +How to notepad like a pro: +ctrl+f = find +ctrl+h = find & replace +ctrl+g = show/jump to line (turn off wordwrap n00b) + +Status bar wastes screen space, don't use it. + +Use https://tools.stefankueng.com/grepWin.html to mass search, find and replace many files in bulk. + +]]--------------------------------------- + +--[[ Prototype/data stage libraries ]]-- + +local proto={} + + + + +--[[ Prototyping Data Stuff ]]-- + + + +-- All the different things an item can be +-- See also data.raw["item-subgroup"][k].name + +proto.ItemGroups={"item","tool","gun","ammo","capsule","armor","repair-tool","car","module","locomotive","cargo-wagon","artillery-wagon","fluid-wagon","rail-planner","item-with-entity-data"} + +-- All the different things an item can be place_result'd as +proto.PlacementGroups={ +"accumulator","ammo-turret","arithmetic-combinator","artillery-turret","artillery-wagon","assembling-machine", +"beacon","boiler", +"car","cargo-wagon","character","constant-combinator","container", +"decider-combinator", +"electric-energy-interface","electric-turret","electric-pole", +"fluid-turret","fluid-wagon","furnace", +"gate","generator", +"heat-pipe", +"inserter", +"lab","loader","logistic-container","logistic-robot", +"mining-drill", +"offshore-pump", +"pipe","pipe-to-ground","power-switch","programmable-speaker","pump", +"radar","reactor","roboport","rocket-silo", +"simple-entity","simple-entity-with-force","simple-entity-with-owner","solar-panel","splitter","storage-tank", +"train-stop","transport-belt", +"underground-belt", +"wall", +} + +function proto.Recache() proto._items=nil proto._placeables=nil proto._labpacks=nil proto._used=nil proto._furnacecat=nil end + +function proto.CacheItems() local t={} for k,v in pairs(proto.ItemGroups)do for x,y in pairs(data.raw[v])do t[y.name]=y end end proto._items=t return t end +function proto.Items(b) return (proto._items and (not b and proto._items or proto.CacheItems()) or proto.CacheItems()) end +function proto.RawItem(n,b) return proto.Items(b)[n] end + +function proto.CacheLabPacks() local tx={} for k,v in pairs(data.raw.lab)do local vin=v.inputs for i,e in pairs(vin)do tx[e]=e end end proto._labpacks=tx return tx end +function proto.GetLabPacks(b) return (proto._labpacks and (not b and proto._labpacks or proto.CacheLabPacks()) or proto.CacheLabPacks()) end +function proto.LabPack(n,b) return proto.GetLabPacks(b)[n] end + +function proto.CachePlaceables() local t={} for k,v in pairs(proto.PlacementGroups)do for x,y in pairs(data.raw[v])do t[y.name]=y end end proto._placeables=t return t end +function proto.Placeables(b) return (proto._placeables and (not b and proto._placeables or proto.CachePlaceables()) or proto.CachePlaceables()) end +function proto.RawPlaceable(n,b) return proto.Placeables(b)[n] end -- place_result_entity +proto.PlaceResultEntity=proto.RawPlaceable --alias + +function proto.CacheUsedRecipes() local t={} + for k,v in pairs(data.raw.technology)do local fx=proto.TechEffects(v) for i,rcp in pairs(fx.recipes)do t[rcp]=true end end + for k,v in pairs(data.raw.recipe)do if(proto.IsEnabled(v))then t[v.name]=true end end +proto._used=t return t end +function proto.UsedRecipes() return (proto._used and (not b and proto._used or proto.CacheUsedRecipes()) or proto.CacheUsedRecipes()) end +function proto.UsedRecipe(n,b) return proto.UsedRecipes(b)[n] end +function proto.CountUsedRecipes() return table_size(proto.UsedRecipes()) end +function proto.CountUnsedRecipes() return table_size(data.raw.recipe)-proto.CountUsedRecipes() end + +function proto.IsAutoplaceControl(t) local dra=data.raw["autoplace-control"] if(dra[t.name] or dra[t.type] or (t.autoplace and t.autoplace.control))then return true end return false end + +function proto.HasFluidbox(t) return t.fluid_box or t.fluid_boxes or t.input_fluid_box or t.output_fluid_box end + +function proto.CacheFurnaceCats() local t={} for k,v in pairs(data.raw.furnace)do for cc in pairs(proto.CraftingCategories(v))do t[cc]=cc end end proto._furnacecat=t return t end +function proto.FurnaceCats(b) return (proto._furnacecat and (not b and proto._furnacecat or proto.CacheFurnaceCats()) or proto.CacheFurnaceCats()) end +function proto.FurnaceCat(n,b) return proto.FurnaceCats(b)[n] end + +function proto.Name(t) return (isstring(t) and t or (t.name and t.name or (isstring(t[1]) and t[1] or false))) end + +function proto.Fluids() return data.raw.fluid end +function proto.Recipes() return data.raw.recipe end +function proto.Techs() return data.raw.technology end + +function proto.IsEnabled(v) local c=false + if(tostring(v.enabled)=="true")then c=true end + if(v.normal and tostring(v.normal.enabled)=="true")then c=true end + if(v.expensive and tostring(v.expensive.enabled)=="true")then c=true end + --if(v.enabled==nil and (not v.normal or v.normal and v.normal.enabled==nil) and (not v.expensive or v.expensive and v.expensive.enabled==nil))then return true end + return c +end +function proto.IsDisabled(v) local c=false + if(tostring(v.enabled)=="false")then c=true end + if(v.normal and tostring(v.normal.enabled)=="false")then c=true end + if(v.expensive and tostring(v.expensive.enabled)=="false")then c=true end + --if(v.enabled==nil and (not v.normal or v.normal and v.normal.enabled==nil) and (not v.expensive or v.expensive and v.expensive.enabled==nil))then return true end + return c +end + +proto.IsTechnologyEnabled=proto.IsEnabled -- alias + +function proto.IsHidden(v) + if(tostring(v.hidden)=="true")then return true end + if(v.normal and tostring(v.normal.hidden)=="true")then return true end + if(v.expensive and tostring(v.expensive.hidden)=="true")then return true end + return false +end + + + +proto.Difficulties={[0]="standard",[1]="normal",[2]="expensive"} +function proto.Normal(t) local v=t if(t.normal)then v=t.normal elseif(t.expensive)then v=t.expensive end return v end +function proto.FetchDifficultyLayer(tx,seek) + local t=tx if(t)then for k,v in pairs(seek)do if(t[v])then return t,0 end end end + local t=tx.normal if(t)then for k,v in pairs(seek)do if(t[v])then return t,1 end end end + local t=tx.expensive if(t)then for k,v in pairs(seek)do if(t[v])then return t,2 end end end +end + +function proto.Result(t) if(t[1] and t[2])then return {type="item",name=t[1],amount=t[2]} else return t end end +function proto.Results(tx) local t,dfc=proto.FetchDifficultyLayer(tx,{"result","results"}) if(t)then if(t.results)then rs=t.results else rs={{t.result,t.result_count or 1}} end end return rs,dfc end +function proto.Ingredient(t) return proto.Result(t) end +function proto.Ingredients(tx) local t,dfc=proto.FetchDifficultyLayer(tx,{"ingredients"}) return (t and t.ingredients),dfc end + +-- Fetch the raw item/object/etc +function proto.CraftingObject(rs) local raw=proto.RawItem(rs.name) return raw or data.raw.fluid[rs.name] end +function proto.ResultObject(t) local rs=proto.Result(t) return proto.CraftingObject(rs) end +function proto.IngredientObject(t) local rs=proto.Ingredient(t) return proto.CraftingObject(rs) end + +function proto.TechBottles(tz) local t,dfc=proto.FetchDifficultyLayer(tz,{"unit"}) if(not t or not t.unit or not t.unit.ingredients)then return end + local tx={} for k,v in pairs(t.unit.ingredients)do local rs=proto.Ingredient(v) tx[rs.name]=rs.name end return tx +end +function proto.LoopTech(n,p) p=p or {} p[n]=true local r=data.raw.technology[n] for k,v in pairs(r.prerequisites or {})do if(not p[v])then proto.LoopTech(v,p) end end return p end +function proto.RecursiveTechBottles(g) local t={} for n in pairs(proto.LoopTech(g.name))do local c,u=data.raw.technology[n] u=proto.TechBottles(c) for k,v in pairs(u)do t[v]=true end end return t end + +function proto.TechEffects(g) local t={recipes={},items={},c=0} if(not g.effects)then return t end + for k,v in pairs(g.effects)do local x=v.type if(x=="unlock-recipe")then table.insert(t.recipes,v.recipe) t.c=t.c+1 elseif(x=="give-item")then table.insert(x.items,v.item) t.c=t.c+1 end end + return t +end + +function proto.CraftingCategories(t) if(isstring(t))then return {t} end return t end +function proto.FuelCategories(t) local x + if(t.fuel_category)then x={} table.insert(x,t.fuel_category) end + if(t.fuel_categories)then x=x or {} for k,v in pairs(t.fuel_categories)do table.insertExclusive(x,v) end end + return x +end + +function proto.MinableResults(tx) + return {} +end + +function proto.GetRawAutoplacers(raw,vfunc) local t={} -- data.raw.resource,data.raw.tree vfunc(v) return true_is_valid end + for n,rsc in pairs(raw)do if(rsc.minable and proto.IsAutoplaceControl(rsc) and (not vfunc or (vfunc and vfunc(rsc))) )then + local rs=proto.Results(rsc.minable) + if(rs)then for k,v in pairs(rs)do local rso=proto.ResultObject(v) + if(not t[rso.name])then t[rso.name]={type=(rso.type~="fluid" and "item" or "fluid"),name=rso.name,proto=rsc} end + end end + end end + return t +end +function proto.GetRawResources() return proto.GetRawAutoplacers(data.raw.resource) end +function proto.GetRawTrees() return proto.GetRawAutoplacers(data.raw.tree) end +function proto.GetRawRocks() return proto.GetRawAutoplacers(data.raw["simple-entity"],function(v) return v.count_as_rock_for_filtered_deconstruction end) end +function proto.GetRaw() local t={} for k,v in pairs({proto.GetRawResources(),proto.GetRawTrees(),proto.GetRawRocks()})do for i,e in pairs(v)do table.insertExclusive(t,e) end end return t end + + +function proto.Copy(a,b,x) local t=table.deepcopy(data.raw[a][b]) if(x)then table.deepmerge(t,x) end return t end + +function proto.ExtendBlankEntityItems(ent) + local rcp=proto.Copy("recipe","nuclear-reactor") + rcp.enabled=false rcp.name=ent.name rcp.ingredients={{"steel-plate",1}} rcp.result=ent.name + + local item=proto.Copy("item","nuclear-reactor") + item.name=ent.name item.place_result=ent.name + data:extend{rcp,item} +end + + +proto.VanillaPacks={red="automation-science-pack",green="logistic-science-pack",blue="chemical-science-pack",black="military-science-pack", + purple="production-science-pack",yellow="utility-science-pack",white="space-science-pack"} + +function proto.SciencePacks(x) local t={} for k,v in pairs(x)do table.insert(t,{proto.VanillaPacks[k],v}) end return t end +function proto.ExtendTech(t,d,s) local x=table.merge(t,d) if(s)then x.unit.ingredients=proto.SciencePacks(s) end data:extend{x} return x end + +function proto.Icons(p) if(p.icons)then return p.icons end if(p.icon)then return {{icon=p.icon,icon_size=p.icon_size}} end end + return proto \ No newline at end of file diff --git a/lib/lib_data_logic.lua b/lib/lib_data_logic.lua index 90543ab..b3fb802 100644 --- a/lib/lib_data_logic.lua +++ b/lib/lib_data_logic.lua @@ -1,517 +1,517 @@ ---[[------------------------------------- - -Author: Pyro-Fire -https://patreon.com/pyrofire - -Script: lib_data_logic.lua -Purpose: data stage logic - ------ - -Copyright (c) 2019 Pyro-Fire - -I put a lot of work into these library files. Please retain the above text and this copyright disclaimer message in derivatives/forks. - -Permission to use, copy, modify, and/or distribute this software for any -purpose without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ------- - -Written using Microsoft Notepad. -IDE's are for children. - -How to notepad like a pro: -ctrl+f = find -ctrl+h = find & replace -ctrl+g = show/jump to line (turn off wordwrap n00b) - -Status bar wastes screen space, don't use it. - -Use https://tools.stefankueng.com/grepWin.html to mass search, find and replace many files in bulk. - -]]--------------------------------------- - - - -local logic={} -logic.loading=true - -function logic.seed(s) - local n=tonumber(s) if(tostring(n)==s)then math.randomseed(n) return n end -- its just a number - n=0 for i=1,string.len(s),1 do n=n+string.byte(s:sub(i,i)) end - math.randomseed(n*24) for i=1,n,1 do local x=math.random() end - return n -end - --- The original hand & starting conditions of the logic system -logic.origin={} local origin=logic.origin - --- Prototype types with their logic functions -logic.ent={} - --- The items, fluids, recipes, ents and everything and stuff currently in our hand & their logical status -logic.hand={} local hand=logic.hand -hand.recipes={} -- recipes in crafting menu -hand.recipescan={} -- recipes that have their item and entity results pushed to hand -hand.reciperead={} -- recipes that have had ingredients read -hand.techs={} -- technologies that we are able to finish thanks to labs, bottles etc -hand.techscan={} -- technologies that have been scanned and effects pushed to hand (recipes etc) aka we have "researched" this technology. -hand.ents={} -- Entities that we can place in the world -hand.entscan={} -- "usable" entities - we can fuel/operate them because we have neccessary items e.g. pipes needed for machines with fluidboxes -hand.items={} -- accessible and craftable items -hand.itemscan={} -- Items that have already been scanned and have fully pushed all potential uses -hand.fluids={} - -hand.labpacks={} -- Science pack items (that are in hand) that we can put into a lab (if we have a labbable slot for it). -hand.labslots={} -- Labbable science packs. - --- Flags, e.g. has a power source, has power pole, has belts etc -hand.void=true -- void power -hand.power=false -hand.pole=false -hand.pipes=false -hand.pipe_to_ground=false -hand.belts=false -hand.underground_belts=false -hand.splitters=false -hand.inserters=false -hand.drill=false -hand.fluid_drill=false -- can be true for a drill accepting all fluids, or a table of drills with filtered fluidboxes -hand.rocket_silo=false -- Has a thing capable of launching items for rocket_launch_product - -hand.heat=0 -- max heat capacity - -hand.craft_cats={} -hand.burner_cats={} -- [cat]=n with n=burnt_inventory_size. Burnable Categories that we can burn, and their burnt inventory size. -hand.burnables={} -- Items that can be put in a burner -hand.resource_cats={} -hand.resource_scan={} -- Resources that have been scanned & added to our hand, e.g. iron-ore, but not uranium ore because it waits for sulfuric acid. [name]=0/1 automation -hand.fuel_types={} - -logic.ignored={} -logic.is_bobs=false -logic.spaceblock=false -function logic.bobs(b) if(b)then logic.is_bobs=b end return logic.is_bobs end -function logic.Ignore(rcpname) logic.ignored[rcpname]=true end -function logic.ShouldIgnore(rcpname,rcp) - if(rcp and rcp.subgroup)then - if(logic.spaceblock and rcp.subgroup:find("spaceblock"))then return true end - end - return rcpname:find("void") or rcpname:find("converter") or logic.ignored[rcpname] - --or (logic.bobs() and rcpname:find("alien")) -end -function logic.Ignoring(rcp) return logic.ShouldIgnore(rcp.name,rcp) end - -logic.seablock=false -logic.SeablockScience={ - ["angels-ore3"]="sb-angelsore3-tool", - ["basic-circuit-board"]="sb-basic-circuit-board-tool", - ["algae-green"]="sb-algae-green-tool", - ["sulfur"]="sb-sulfur-tool", - ["lab"]="sb-lab-tool", -} - --- Other initial conditions -function logic.Seablock() hand.pole=true hand.power=true hand.pipes=true hand.belts=true hand.inserters=true - -- And push some entities too? - logic.seablock=true - logic.bobs(true) - logic.PushItem(data.raw.item["stone-furnace"],0,true) -- inv furnace - logic.PushItem(data.raw.item["burner-ore-crusher"],0,true) - logic.PushItem(data.raw.item["iron-plate"],0,true) - logic.PushItem(data.raw.item["stone-brick"],0,true) - logic.PushItem(data.raw.item["landfill-sand-3"],0,true) - logic.PushItem(data.raw.item["small-electric-pole"],0,true) - logic.PushItem(data.raw.item["copper-pipe"],0,true) - logic.PushItem(data.raw.item["stone-pipe"],0,true) - logic.PushItem(data.raw.item["stone-pipe-to-ground"],0,true) - logic.PushItem(data.raw.item["wind-turbine-2"],0,true) - logic.PushItem(data.raw.item["iron-stick"],0,true) - logic.PushItem(data.raw.item["pipe"],0,true) - logic.PushItem(data.raw.item["basic-circuit-board"],0,true) - logic.PushItem(data.raw.item["electronic-circuit"],0,true) - logic.PushItem(data.raw.item["iron-gear-wheel"],0,true) - logic.PushItem(data.raw.item["small-lamp"],0,true) - logic.PushItem(data.raw.item["stone"],0,true) - logic.PushItem(data.raw.item["pipe-to-ground"],0,true) - --logic.PushItem(data.raw.tool["sb-angelsore3-tool"],0,true) -- because apparently this is a special item you can't actually obtain. why. - --logic.PushItem(data.raw.tool["sb-basic-circuit-board-tool"],0,true) -- because apparently this is a special item you can't actually obtain. why. - --logic.PushItem(data.raw.tool["sb-algae-green-tool"],0,true) -- because apparently this is a special item you can't actually obtain. why. - --logic.PushItem(data.raw.tool["sb-lab-tool"],0,true) -- because apparently this is a special item you can't actually obtain. why. - - - --logic.Ignore("offshore-pump") - --logic.Ignore("crystallizer") - --logic.Ignore("electrolyzer") -end - -function logic.HasMoreRecipes() for k,v in pairs(data.raw.recipe)do if(not hand.recipescan[k] and proto.UsedRecipe(k) and not logic.ShouldIgnore(k))then return true end end return false end - - - --- Easy check if Fluid (with temperatures) or Item is in our hand (by name) --- fluids may need a min/max... --- Todo push a temperature without a fluid --- It is possible fluid temperature may be removed in future https://forums.factorio.com/viewtopic.php?f=34&t=64499 ---function logic.CanFluid(fld,tmp) tmp=tmp or 15 local ft=hand.fluids[fld] if(ft)then for m in pairs(ft)do if(m>=tmp)then return true end end end return false end -function logic.CanFluid(d,n,x) n=n or 15 local ft=hand.fluids[d] if(ft)then if(not x)then for m in pairs(ft)do if(m>=n)then return true end end else - for m in pairs(ft)do - if(m==x or m==n or (m>n and mx)then a=true elseif(m=(fuel.default_temperature or fuel.min_working_temperature or 1) end -function logic.CanFuel.electric(fuel) return hand.power and hand.pole end -function logic.CanFuel.burner(fuel) - local fcats=proto.FuelCategories(fuel) if(not fcats)then return table_size(hand.burner_cats)>0 end - local c=false for k,v in pairs(fcats)do if(hand.burner_cats[v])then c=true break end end if(c)then logic.PushBurner(fuel) return true end -end - --- Fluidbox fueling - note of future temperature changes --- logic.CanFuelFluidbox(entity.input_fluid_box) -function logic.CanFuelFluidbox(fbox,min,max) - if(not hand.pipes)then return false end - local ft=fbox.filter min=(fbox.minimum_temperature or min) max=(fbox.maximum_temperature or max) - --if(not ft)then return logic.CanFluidTemperature(min) end - return logic.CanFluid(ft,min,max) -end -function logic.CanFuel.fluid(fuel) if(fuel.pipe_connections)then return logic.CanFuelFluidbox(fuel) else return logic.CanFuelFluidbox(fuel.fluid_box,nil,fuel.maximum_temperature) end end - - - -function logic.CanMineResource(c) - local cat=c.category or "basic-solid" - if(not hand.resource_cats[cat])then return false end -- can we mine it by hand or auto? - local min=c.minable if(not min)then error(cat .. " type resource without a .minable?\n" .. serpent.block(c)) end - if(min.required_fluid and ((not logic.Fluid(min.required_fluid)) or (istable(hand.fluid_drill) and not hand.fluid_drill[min.required_fluid])))then return false end -- do we have the fluids needed for the resource? - return hand.resource_cats[cat] -- return automation level -end - -function logic.ScanResource(c) -- Scans a resource and pushes results if we can mine it. Odds are this will be called without need for further handling. - local lvl=logic.CanMineResource(c) if(not lvl)then return false end - if((hand.resource_scan[proto.Name(c)] or -1)0)then for k,v in pairs(fx.recipes)do logic.PushRecipe(data.raw.recipe[v]) end end - hand.techscan[t.name]=true - return true -end -function logic.ScanTechnologies() for k in pairs(hand.techs)do local r=data.raw.technology[k] if(logic.CanResearchTechnology(r) and logic.CanRecursiveAffordTechnology(r))then logic.PushTechnology(r) logic.ScanTechnology(r) end end end - -function logic.CanAffordRecipe(c) local ing=proto.Ingredients(c) if(not ing)then return true end - local can=true for k,ig in pairs(ing)do local v=proto.Ingredient(ig) - if(v.type~="fluid")then if(not hand.items[v.name])then can=false break end elseif(not logic.CanFluid(v.name,v.temperature))then can=false break end - end return can -end - -function logic.CanCraftRecipe(c) return hand.craft_cats[c.category or "crafting"] end -- Return automation level. 0=handcraft. 1=automated. -function logic.ScanRecipe(c,bscan) if(hand.recipescan[c.name])then return true end - if(logic.ShouldIgnore(c.name))then hand.recipescan[c.name]=true return true end - for k,v in pairs(proto.Results(c))do local x=proto.Result(v) logic.PushResult(x,hand.craft_cats[v.category or "crafting"] or 0,bscan) end - hand.recipescan[c.name]=true - return true -end -function logic.ScanRecipes(bscan) for k,v in pairs(hand.recipes)do logic.ScanRecipe(v,bscan) end end - ---[[ Push Functions ]]-- --- Push stuff into the hand - -function logic.PushRecipe(c) local n=proto.Name(c) if(not hand.recipes[n])then hand.recipes[n]=c logic.HandChanged("recipe",c) end end -function logic.PushTechnology(c) local n=proto.Name(c) if(not hand.techs[n])then hand.techs[n]=c logic.HandChanged("technology",c) end end -function logic.PushEntity(c,s) local n=proto.Name(c) if(not hand.ents[n])then hand.ents[n]=c if(s)then logic.ScanEntity(c) end logic.HandChanged("entity",c) end end -function logic.PushFluid(c,m) m=m or 15 local n=proto.Name(c) hand.fluids[n]=hand.fluids[n] or {} hand.fluids[n][m]=c logic.HandChanged("fluid",c,m) end - - -function logic.PushCraftCat(v,n) if(not hand.craft_cats[v] or (n and hand.craft_cats[v]=tmp)then return true end end end return false end +function logic.CanFluid(d,n,x) n=n or 15 local ft=hand.fluids[d] if(ft)then if(not x)then for m in pairs(ft)do if(m>=n)then return true end end else + for m in pairs(ft)do + if(m==x or m==n or (m>n and mx)then a=true elseif(m=(fuel.default_temperature or fuel.min_working_temperature or 1) end +function logic.CanFuel.electric(fuel) return hand.power and hand.pole end +function logic.CanFuel.burner(fuel) + local fcats=proto.FuelCategories(fuel) if(not fcats)then return table_size(hand.burner_cats)>0 end + local c=false for k,v in pairs(fcats)do if(hand.burner_cats[v])then c=true break end end if(c)then logic.PushBurner(fuel) return true end +end + +-- Fluidbox fueling - note of future temperature changes +-- logic.CanFuelFluidbox(entity.input_fluid_box) +function logic.CanFuelFluidbox(fbox,min,max) + if(not hand.pipes)then return false end + local ft=fbox.filter min=(fbox.minimum_temperature or min) max=(fbox.maximum_temperature or max) + --if(not ft)then return logic.CanFluidTemperature(min) end + return logic.CanFluid(ft,min,max) +end +function logic.CanFuel.fluid(fuel) if(fuel.pipe_connections)then return logic.CanFuelFluidbox(fuel) else return logic.CanFuelFluidbox(fuel.fluid_box,nil,fuel.maximum_temperature) end end + + + +function logic.CanMineResource(c) + local cat=c.category or "basic-solid" + if(not hand.resource_cats[cat])then return false end -- can we mine it by hand or auto? + local min=c.minable if(not min)then error(cat .. " type resource without a .minable?\n" .. serpent.block(c)) end + if(min.required_fluid and ((not logic.Fluid(min.required_fluid)) or (istable(hand.fluid_drill) and not hand.fluid_drill[min.required_fluid])))then return false end -- do we have the fluids needed for the resource? + return hand.resource_cats[cat] -- return automation level +end + +function logic.ScanResource(c) -- Scans a resource and pushes results if we can mine it. Odds are this will be called without need for further handling. + local lvl=logic.CanMineResource(c) if(not lvl)then return false end + if((hand.resource_scan[proto.Name(c)] or -1)0)then for k,v in pairs(fx.recipes)do logic.PushRecipe(data.raw.recipe[v]) end end + hand.techscan[t.name]=true + return true +end +function logic.ScanTechnologies() for k in pairs(hand.techs)do local r=data.raw.technology[k] if(logic.CanResearchTechnology(r) and logic.CanRecursiveAffordTechnology(r))then logic.PushTechnology(r) logic.ScanTechnology(r) end end end + +function logic.CanAffordRecipe(c) local ing=proto.Ingredients(c) if(not ing)then return true end + local can=true for k,ig in pairs(ing)do local v=proto.Ingredient(ig) + if(v.type~="fluid")then if(not hand.items[v.name])then can=false break end elseif(not logic.CanFluid(v.name,v.temperature))then can=false break end + end return can +end + +function logic.CanCraftRecipe(c) return hand.craft_cats[c.category or "crafting"] end -- Return automation level. 0=handcraft. 1=automated. +function logic.ScanRecipe(c,bscan) if(hand.recipescan[c.name])then return true end + if(logic.ShouldIgnore(c.name))then hand.recipescan[c.name]=true return true end + for k,v in pairs(proto.Results(c))do local x=proto.Result(v) logic.PushResult(x,hand.craft_cats[v.category or "crafting"] or 0,bscan) end + hand.recipescan[c.name]=true + return true +end +function logic.ScanRecipes(bscan) for k,v in pairs(hand.recipes)do logic.ScanRecipe(v,bscan) end end + +--[[ Push Functions ]]-- +-- Push stuff into the hand + +function logic.PushRecipe(c) local n=proto.Name(c) if(not hand.recipes[n])then hand.recipes[n]=c logic.HandChanged("recipe",c) end end +function logic.PushTechnology(c) local n=proto.Name(c) if(not hand.techs[n])then hand.techs[n]=c logic.HandChanged("technology",c) end end +function logic.PushEntity(c,s) local n=proto.Name(c) if(not hand.ents[n])then hand.ents[n]=c if(s)then logic.ScanEntity(c) end logic.HandChanged("entity",c) end end +function logic.PushFluid(c,m) m=m or 15 local n=proto.Name(c) hand.fluids[n]=hand.fluids[n] or {} hand.fluids[n][m]=c logic.HandChanged("fluid",c,m) end + + +function logic.PushCraftCat(v,n) if(not hand.craft_cats[v] or (n and hand.craft_cats[v]0)then -- Do the fluidbox thing - local pipesizemin=math.max(goalsize,fbc.northern,fbc.southern,fbc.eastern,fbc.western) -- The minimum tile-size we can be due to fluidboxes - goalsize=pipesizemin - local pipesize=goalsize+1 -- the goal tile-size which we would use if we were resizing to the size of the bbox if it were 1 tile bigger in all directions - local pipescale=vector(pipesize,pipesize)/pipemax - local bbnewpipe=bbpipe*pipescale - local bbnew=bbsize*(goalsize/bbmax) - - proto.ShiftFluidboxCenters(pr,bbsize,fbc) -- Shift fluidboxes to center of new bbox - proto.SizeFluidboxesTo(pr,pipescale,fbc) -- Shift positions of fluidboxes - - --if(proto.dbg)then error("DEBUG: Size " .. goalsize .. ", bbmax: " .. pipemax .. ", scale: " .. goalsize/bbmax .. ", Pipescale: " .. serpent.block(pipescale) .. "\nData:\n"..serpent.block(pr).."\n---------------FB----------------\n"..serpent.block(fbc).."\n".."") end - - - - - - end - - proto.SizeTo(pr,goalsize/bbmax) - -end - - - +--[[------------------------------------- + +Author: Pyro-Fire +https://patreon.com/pyrofire + +Script: lib_data_resize.lua +Purpose: proto code for resizing stuff + +----- + +Copyright (c) 2019 Pyro-Fire + +I put a lot of work into these library files. Please retain the above text and this copyright disclaimer message in derivatives/forks. + +Permission to use, copy, modify, and/or distribute this software for any +purpose without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +------ + +Written using Microsoft Notepad. +IDE's are for children. + +How to notepad like a pro: +ctrl+f = find +ctrl+h = find & replace +ctrl+g = show/jump to line (turn off wordwrap n00b) + +Status bar wastes screen space, don't use it. + +Use https://tools.stefankueng.com/grepWin.html to mass search, find and replace many files in bulk. + +]]--------------------------------------- + +-- Todo: resize equipments to 1x1 https://mods.factorio.com/mod/Super_Pinky_Man_SmallPortableEquipment + +local proto={} + + + + +proto.no_resize_types={"item","item-on-ground","item-entity","item-request-proxy","tile","resource","recipe", +"rail","locomotive","cargo-wagon","fluid-wagon","artillery-wagon","rail-chain-signal","rail-signal", +--"pipe","pipe-to-ground","infinity-pipe", +"underground-belt","transport-belt","splitter", +--"construction-robot","logistic-robot","combat-robot","electric-pole","rocket-silo","rocket-silo-rocket", +--"offshore-pump", +} + +function proto.ShouldResize(pr) if(table.HasValue(proto.no_resize_types,pr.type))then return false end return true end + + +--[[ Basic pictures and layers and offsets resizing and rescaling ]]-- + +proto.scale_keys={"alert_icon_scale"} -- Stuff that is a single number. todo. + + +proto.offset_keys={ + -- Table keys that are offsets +"north_position","south_position","east_position","west_position","red","green","alert_icon_shift", +-- Spider keys +--[[ +"light_positions", +]] +"ground_position", +"offset_deviation", +"mount_position", + +} +function proto.IsImageLayer(k,v) if(v.filenames)then for i,e in pairs(v.filenames)do if(e:find(".png"))then return true end end end return v.layers or (v.filename and v.filename:find(".png")) or k=="animation" end +function proto.IsOffsetLayer(k,v) return (istable(v) and isstring(k) and (k:find("offset") or table.HasValue(proto.offset_keys,k))) end +function proto.IsRailLayer(k,v) return istable(v) and (v.metals or v.backplates) end +function proto.LoopFindImageLayers(prototype,lz) if(not prototype)then return end for key,val in pairs(prototype)do if(istable(val) and key~="sound")then + if(proto.IsImageLayer(key,val))then if(val.layers)then for i,e in pairs(val.layers)do table.insert(lz.images,e) end else table.insert(lz.images,val) end + elseif(proto.IsOffsetLayer(key,val))then table.insert(lz.offsets,val) elseif(proto.IsRailLayer(key,val))then table.insert(lz.rails,val) else proto.LoopFindImageLayers(val,lz) + end +end end end +function proto.FindImageLayers(prototype) local imgz={images={},offsets={},rails={}} proto.LoopFindImageLayers(prototype,imgz) return imgz end +function proto.MergeImageTable(img,tbl) if(img.hr_version)then proto.MergeImageTable(img.hr_version,table.deepcopy(tbl)) end table.merge(img,table.deepcopy(tbl)) end +function proto.MultiplyOffsets(v,z) --if(v[1] and istable(v[1]) and not vector.is_zero(v[1]) and not vector.is_zero(v[2]))then + for a,b in pairs(v)do if(istable(b))then for c,d in pairs(b)do if(type(d)=="table")then error(serpent.block(v)) end v[a][c]=d*z end else v[a]=b*z end end --else vector.set(v,vector(v)*z) --v[1]=v[1]*z v[2]=v[2]*z +end --end +function proto.MultiplyImageSize(img,z) if(img.hr_version)then proto.MultiplyImageSize(img.hr_version,z) end + if(img.shift and istable(img.shift))then for i,e in pairs(img.shift)do if(istable(e))then for a,b in pairs(e)do e[a]=b*z end else img.shift[i]=e*z end end end + img.scale=(img.scale or 1)*z img.y_scale=(img.y_scale or 1)*z img.x_scale=(img.x_scale or 1)*z +end + +function proto.TintImages(pr,tint) local imgz=proto.FindImageLayers(pr) for k,v in pairs(imgz.images)do proto.MergeImageTable(v,{tint=table.deepcopy(tint)}) end end +function proto.MultiplyImages(pr,z) local imgz=proto.FindImageLayers(pr) + for k,v in pairs(imgz.images)do proto.MultiplyImageSize(v,z) end + for k,v in pairs(imgz.offsets)do proto.MultiplyOffsets(v,z) end +end + + + + +proto.bbox_keys={"collision_box","selection_box", -- Table keys that are bounding boxes + "drawing_box","window_bounding_box","horizontal_window_bounding_box","sticker_box","map_generator_bounding_box", +} +proto.ScalableBBoxes={"collision_box","selection_box"} -- Ordered pairs of bounding boxes we can make sized based calculations from +function proto.BBoxIsZero(bbox) if(bbox and bbox[1][1]==0 and bbox[1][2]==0 and bbox[2][1]==0 and bbox[2][2]==0)then return true end return false end +function proto.GetSizableBBox(pr) local b=pr[proto.ScalableBBoxes[1]] for i=2,#proto.ScalableBBoxes,1 do if(not b or proto.BBoxIsZero(b))then b=pr[proto.ScalableBBoxes[i]] else return b end end return b end +function proto.MultiplyBBox(b,z) if(not proto.BBoxIsZero(b))then b[1]=vector.raw(vector(b[1])*z) b[2]=vector.raw(vector(b[2])*z) end end +function proto.MultiplyBBoxes(t,z) for _,nm in pairs(proto.bbox_keys)do if(t[nm] and not proto.BBoxIsZero(t[nm]))then proto.MultiplyBBox(t[nm],z) end end end +function proto.AddBBox(b,f) b[1]=vector.raw(vector(b[1])-vector(f)) b[2]=vector.raw(vector(b[2])+vector(f)) end +function proto.AddBBoxes(t,f) for _,nm in pairs(proto.bbox_keys)do if(t[nm] and not proto.BBoxIsZero(t[nm]))then proto.AddBBox(t[nm],f) end end end +function proto.BBoxSize(b) return vector(b[2])-vector(b[1]) end +function proto.RecenterBBox(b) local len=proto.BBoxSize(b) b[2]=len/2 b[1]=-len/2 end + + +function proto.GetBBoxOrigin(bbox) -- This is to give us +0.5 origin if the bbox needs it, but i dont think this is needed idfk + local bbx=proto.BBoxSize(bbox) + local bv=vector(math.round(bbx.x),math.round(bbx.y)) + local forigin=vector(bv.x%2==0 and 0.5 or 0,bv.y%2==0 and 0.5 or 0) + return forigin +end + +function proto.SizeTo(pr,scale) -- Resizes something purely off a simple scale, this function simply does *scale + proto.MultiplyBBoxes(pr,scale) + proto.MultiplyImages(pr,scale) +end +function proto.SizeToTile(pr,tilesize) -- Resizes something to a tile size based off its scaleable bbox. This is a simple call function to do simple image/bbox/offset resizing. + local bbox=proto.GetSizableBBox(pr) if(not bbox or proto.BBoxIsZero(bbox))then return end + local bbx=proto.BBoxSize(bbox) + proto.SizeTo(pr,tilesize/math.max(bbx.x,bbx.y)) +end + + +--[[ Fluidbox Counter/Scanner ]]-- + + +proto.fluidbox_keys={"fluid_boxes","fluid_box","input_fluid_box","output_fluid_box"} + +function proto.ScanReadFluidbox(fbox,fb) + if(not fbox.pipe_connections)then for k,v in pairs(fbox)do if(istable(v) and v.pipe_connections)then proto.ScanReadFluidbox(v,fb) end end return end + for pipeid,pipe in pairs(fbox.pipe_connections)do + if(pipe.position or pipe.positions)then fb.c=fb.c+1 end + if(pipe.position)then + local maxdir,maxkey=vector.MaxDir(vector(pipe.position)) + fb[maxdir.."ern"]=fb[maxdir.."ern"]+1 + fb[maxdir.."single"]=fb[maxdir.."single"]+1 + local id=#fb[maxdir]+1 fb[maxdir][id]=pipe.position + elseif(pipe.positions)then + fb["north".."single"]=fb["north".."single"]+1 + for i=1,4,1 do local dir=string.compassnum[i] fb[dir.."ern"]=fb[dir.."ern"]+1 local id=#fb[dir]+1 fb[dir][id]=pipe.positions[i] end + end + end +end +function proto.ScanFluidboxCounts(pr) + local fbc={c=0, + north={},east={},south={},west={}, -- Table of fluidbox datas based on direction. Fluidboxes always default to north (y=-5) + northern=0,eastern=0,southern=0,western=0, -- Number of fluidboxes for each given direction total, for all pipe connections. + northsingle=0,eastsingle=0,southsingle=0,westsingle=0, -- Number of fluidboxes for each given direction counting by only a single orientation (north) + } + for _,fbn in pairs(proto.fluidbox_keys)do if(pr[fbn] and istable(pr[fbn]))then proto.ScanReadFluidbox(pr[fbn],fbc) end end + return fbc +end + +function proto.SizeFluidboxesTo(pr,vecscale,fbc) + fbc=fbc or proto.ScanFluidboxCounts(pr) + for dir in pairs(string.strcompass)do + for vi,fbox in pairs(fbc[dir])do + local vfb=vector.raw(vector.floorEx(vector(fbox)*vecscale,2,true)) + +--if(proto.dbg)then error("FBOX:"..serpent.block(fbox) .. " \n NEW FBOX: " .. serpent.block(vfb) .. " \n ORIGIN: " .. serpent.block(origin) .. " \n BBOX: " .. serpent.block(bbround) .. " \n VECSCALE: " .. serpent.block(vecscale)) end + + vector.set(fbox,vfb) + + end + end +end + +function proto.ShiftFluidboxCenters(pr,bbox,fbc) -- Shift fluidboxes more towards the center if they're off-center as a sum. + fbc=fbc or proto.ScanFluidboxCounts(pr) + local shifts={north=vector(),east=vector(),south=vector(),west=vector()} + for dir,vec in pairs(shifts)do + for ktd,pos in pairs(fbc[dir])do --if(proto.dbg and dir=="north")then error("northtest" .. serpent.block(pos)) end + shifts[dir]=shifts[dir]+vector(((dir=="north" or dir=="south") and vector.getx(pos) or 0),((dir=="east" or dir=="west") and vector.gety(pos) or 0)) + end + if(not vector.is_zero(shifts[dir]))then shifts[dir]=shifts[dir]/fbc[dir.."ern"] end + end +--if(proto.dbg)then error(serpent.block(shifts) .. ", " .. serpent.block(fbc)) end + + for dir,vec in pairs(shifts)do + for vi,fbox in pairs(fbc[dir])do local vfb=vector(fbox)-vec vector.set(fbox,vfb) end + end + +end + +function proto.AutoResize(pr,tilesize) + --if(table.HasValue(proto.no_resize_types,pr.type))then return end + local goalsize=tilesize + local bbox=proto.GetSizableBBox(pr) if(not bbox or proto.BBoxIsZero(bbox))then return end + local bbsize=vector.roundEx(proto.BBoxSize(bbox),2,true) + local bbpipe=bbsize+vector(1,1) -- The size the bbox would be if it were 1 tile bigger (fluidbox size = {-0.5,-0.5},{0.5,0.5} bigger than regular bbox.) + local bbmax=math.ceil(math.max(bbsize.x,bbsize.y)) + local pipemax=math.ceil(math.max(bbpipe.x,bbpipe.y)) + if(pr.type=="character" or pr.type=="character-corpse")then goalsize=0.75 end + local fbc=proto.ScanFluidboxCounts(pr) + + --if(pr.name=="furnace")then proto.dbg=true end + --if(pr.name=="boiler")then proto.dbg=true end + --if(pr.name=="pumpjack")then proto.dbg=true end + --if(pr.name=="offshore-pump")then proto.dbg=true end + --if(pr.name=="oil-refinery")then proto.dbg=true end + --if(pr.name=="chemical-plant")then proto.dbg=true end + --if(pr.name=="pump")then proto.dbg=true end + + + + if(fbc.c>0)then -- Do the fluidbox thing + local pipesizemin=math.max(goalsize,fbc.northern,fbc.southern,fbc.eastern,fbc.western) -- The minimum tile-size we can be due to fluidboxes + goalsize=pipesizemin + local pipesize=goalsize+1 -- the goal tile-size which we would use if we were resizing to the size of the bbox if it were 1 tile bigger in all directions + local pipescale=vector(pipesize,pipesize)/pipemax + local bbnewpipe=bbpipe*pipescale + local bbnew=bbsize*(goalsize/bbmax) + + proto.ShiftFluidboxCenters(pr,bbsize,fbc) -- Shift fluidboxes to center of new bbox + proto.SizeFluidboxesTo(pr,pipescale,fbc) -- Shift positions of fluidboxes + + --if(proto.dbg)then error("DEBUG: Size " .. goalsize .. ", bbmax: " .. pipemax .. ", scale: " .. goalsize/bbmax .. ", Pipescale: " .. serpent.block(pipescale) .. "\nData:\n"..serpent.block(pr).."\n---------------FB----------------\n"..serpent.block(fbc).."\n".."") end + + + + + + end + + proto.SizeTo(pr,goalsize/bbmax) + +end + + + return proto \ No newline at end of file diff --git a/lib/lib_global.lua b/lib/lib_global.lua index cb4f496..cded851 100644 --- a/lib/lib_global.lua +++ b/lib/lib_global.lua @@ -1,254 +1,254 @@ ---[[------------------------------------- - -Author: Pyro-Fire -https://patreon.com/pyrofire - -Script: lib_global.lua -Purpose: lib.lua() - ------ - -Copyright (c) 2019 Pyro-Fire - -I put a lot of work into these library files. Please retain the above text and this copyright disclaimer message in derivatives/forks. - -Permission to use, copy, modify, and/or distribute this software for any -purpose without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ------- - -Written using Microsoft Notepad. -IDE's are for children. - -How to notepad like a pro: -ctrl+f = find -ctrl+h = find & replace -ctrl+g = show/jump to line (turn off wordwrap n00b) - -Status bar wastes screen space, don't use it. - -Use https://tools.stefankueng.com/grepWin.html to mass search, find and replace many files in bulk. - -]]--------------------------------------- - -util=require("util") - -function istable(v) return type(v)=="table" end -function isstring(v) return type(v)=="string" end -function isnumber(v) return type(v)=="number" end - -function isvalid(v) return v and v.valid end - - -function new(x,a,b,c,d,e,f,g) local t,v=setmetatable({},x),rawget(x,"__init") if(v)then v(t,a,b,c,d,e,f,g) end return t end - -local function toKeyValues(t) local r={} for k,v in pairs(t)do table.insert(r,{k=k,v=v}) end return r end -local function keyValuePairs(x) x.i=x.i+1 local kv=x.kv[x.i] if(not kv)then return end return kv.k,kv.v end -function RandomPairs(t,d) local rt=toKeyValues(t) for k,v in pairs(rt)do v.rand=math.random(1,1000000) end - if(d)then table.sort(rt,function(a,b) return a.rand>b.rand end) else table.sort(rt,function(a,b) return a.rand>b.rand end) end - return keyValuePairs, {i=0,kv=rt} -end -function StringPairs(t,d) local tbl=toKeyValues(t) if(d)then table.sort(tbl,function(a,b) return a.v>b.v end) else table.sort(tbl,function(a,b) return a.vb.k end) else table.sort(tbl,function(a,b) return a.k=0 and math.ceil(x*k)/k or math.floor(x*k)/k) end return math.round(x*k)/k end -- round to nearest fraction e.g. *2 = nearest 0.5. -function math.floorEx(x,k,b) if(b)then return (x>=0 and math.floor(x*k)/k or math.ceil(x*k)/k) end return math.floor(x*k)/k end -- round to nearest fraction e.g. *2 = nearest 0.5. -function math.radtodeg(x) return x*(180/math.pi) end -function math.nroot(r,n) return n^(1/r) end -function math.sign(v) return v>0 and 1 or (v<0 and -1 or 0) end -function math.signx(v) return v>=0 and 1 or (v<0 and -1 or 0) end -function math.wrap(a,b) local lg=1 local dif=a-b if(math.abs(dif)>lg/2)then return (lg-math.abs(dif))*(dif>0 and 1 or -1) else return dif end end -math.uint32=4294967295 - - - -string.energy_chars={{10^3,"k"},{10^6,"M"},{10^9,"G"},{10^12,"T"},{10^15,"P"},{10^18,"E"},{10^21,"Z"},{10^24,"Y"}} -function string.energy_to_string(e,f) - local exp,str=10^3,"k" - local ev=math.abs(e) - for k,v in ipairs(string.energy_chars)do if(ev>v[1])then exp=v[1] str=v[2] else break end end - return math.roundx(e/exp,f or 2) .. str .. "W" -end - ---[[ Vector Meta ]]-- - -vector={} local vectorMeta={__index=vector} setmetatable(vector,vectorMeta) -setmetatable(vectorMeta,{__index=function(t,k) if(k=="x")then return rawget(t,"k") or t[1] elseif(k=="y")then return rawget(t,"y") or t[2] end end}) -function vectorMeta:__call(x,y) if(type(x)=="table")then return vector(vector.getx(x),vector.gety(x)) else return setmetatable({[1]=x or 0,[2]=y or 0,x=x or 0,y=y or 0},vector) end end -function vectorMeta.__tostring(v) return "{"..vector.getx(v) .. ", " .. vector.gety(v) .."}" end -function vector.__add(x,y) return vector.add(x,y) end -function vector.__sub(x,y) return vector.sub(x,y) end -function vector.__mul(x,y) return vector.mul(x,y) end -function vector.__div(x,y) return vector.div(x,y) end -function vector.__pow(x,y) return vector.pow(x,y) end -function vector.__mod(x,y) return vector.mod(x,y) end -function vector.__eq(x,y) return vector.equal(x,y) end -function vector.__lt(x,y) return vector.getx(x)math.abs(vec.y))then - maxkey="x" - if(vec.x<0)then maxdir="west" else maxdir="east" end - else - maxkey="y" - if(vec.y<0)then maxdir="north" else maxdir="south" end - end - return maxdir,maxkey -end - -function vector.isinbbox(p,a,b) local x,y=(p.x or p[1]),(p.y or p[2]) return not ( (x<(a.x or a[1]) or y<(a.y or a[2])) or (x>(b.x or b[1]) or y>(b.y or b[2]) ) ) end - -function vector.inarea(v,a) local x,y=(v.x or v[1]),(v.y or v[2]) return not ( (x<(a[1].x or a[1][1]) or y<(a[1].y or a[1][2])) or (x>(a[2].x or a[2][1]) or y>(a[2].y or a[2][2]))) end -function vector.table(area) local t={} for x=area[1].x,area[2].x,1 do for y=area[1].y,area[2].y,1 do table.insert(t,vector(x,y)) end end return t end -function vector.circle(p,z) local t,c,d={},math.round(z/2) for x=p.x-c,p.x+c,1 do for y=p.y-c,p.y+c,1 do d=math.sqrt(((x-p.x)^2)+((y-p.y)^2)) if(d<=c)then table.insert(t,vector(x,y)) end end end return t end -function vector.circleEx(p,z) local t,c,d={},z/2 for x=p.x-c,p.x+c,1 do for y=p.y-c,p.y+c,1 do d=math.sqrt(((x-p.x)^2)+((y-p.y)^2)) if(db.rand end) else table.sort(rt,function(a,b) return a.rand>b.rand end) end + return keyValuePairs, {i=0,kv=rt} +end +function StringPairs(t,d) local tbl=toKeyValues(t) if(d)then table.sort(tbl,function(a,b) return a.v>b.v end) else table.sort(tbl,function(a,b) return a.vb.k end) else table.sort(tbl,function(a,b) return a.k=0 and math.ceil(x*k)/k or math.floor(x*k)/k) end return math.round(x*k)/k end -- round to nearest fraction e.g. *2 = nearest 0.5. +function math.floorEx(x,k,b) if(b)then return (x>=0 and math.floor(x*k)/k or math.ceil(x*k)/k) end return math.floor(x*k)/k end -- round to nearest fraction e.g. *2 = nearest 0.5. +function math.radtodeg(x) return x*(180/math.pi) end +function math.nroot(r,n) return n^(1/r) end +function math.sign(v) return v>0 and 1 or (v<0 and -1 or 0) end +function math.signx(v) return v>=0 and 1 or (v<0 and -1 or 0) end +function math.wrap(a,b) local lg=1 local dif=a-b if(math.abs(dif)>lg/2)then return (lg-math.abs(dif))*(dif>0 and 1 or -1) else return dif end end +math.uint32=4294967295 + + + +string.energy_chars={{10^3,"k"},{10^6,"M"},{10^9,"G"},{10^12,"T"},{10^15,"P"},{10^18,"E"},{10^21,"Z"},{10^24,"Y"}} +function string.energy_to_string(e,f) + local exp,str=10^3,"k" + local ev=math.abs(e) + for k,v in ipairs(string.energy_chars)do if(ev>v[1])then exp=v[1] str=v[2] else break end end + return math.roundx(e/exp,f or 2) .. str .. "W" +end + +--[[ Vector Meta ]]-- + +vector={} local vectorMeta={__index=vector} setmetatable(vector,vectorMeta) +setmetatable(vectorMeta,{__index=function(t,k) if(k=="x")then return rawget(t,"k") or t[1] elseif(k=="y")then return rawget(t,"y") or t[2] end end}) +function vectorMeta:__call(x,y) if(type(x)=="table")then return vector(vector.getx(x),vector.gety(x)) else return setmetatable({[1]=x or 0,[2]=y or 0,x=x or 0,y=y or 0},vector) end end +function vectorMeta.__tostring(v) return "{"..vector.getx(v) .. ", " .. vector.gety(v) .."}" end +function vector.__add(x,y) return vector.add(x,y) end +function vector.__sub(x,y) return vector.sub(x,y) end +function vector.__mul(x,y) return vector.mul(x,y) end +function vector.__div(x,y) return vector.div(x,y) end +function vector.__pow(x,y) return vector.pow(x,y) end +function vector.__mod(x,y) return vector.mod(x,y) end +function vector.__eq(x,y) return vector.equal(x,y) end +function vector.__lt(x,y) return vector.getx(x)math.abs(vec.y))then + maxkey="x" + if(vec.x<0)then maxdir="west" else maxdir="east" end + else + maxkey="y" + if(vec.y<0)then maxdir="north" else maxdir="south" end + end + return maxdir,maxkey +end + +function vector.isinbbox(p,a,b) local x,y=(p.x or p[1]),(p.y or p[2]) return not ( (x<(a.x or a[1]) or y<(a.y or a[2])) or (x>(b.x or b[1]) or y>(b.y or b[2]) ) ) end + +function vector.inarea(v,a) local x,y=(v.x or v[1]),(v.y or v[2]) return not ( (x<(a[1].x or a[1][1]) or y<(a[1].y or a[1][2])) or (x>(a[2].x or a[2][1]) or y>(a[2].y or a[2][2]))) end +function vector.table(area) local t={} for x=area[1].x,area[2].x,1 do for y=area[1].y,area[2].y,1 do table.insert(t,vector(x,y)) end end return t end +function vector.circle(p,z) local t,c,d={},math.round(z/2) for x=p.x-c,p.x+c,1 do for y=p.y-c,p.y+c,1 do d=math.sqrt(((x-p.x)^2)+((y-p.y)^2)) if(d<=c)then table.insert(t,vector(x,y)) end end end return t end +function vector.circleEx(p,z) local t,c,d={},z/2 for x=p.x-c,p.x+c,1 do for y=p.y-c,p.y+c,1 do d=math.sqrt(((x-p.x)^2)+((y-p.y)^2)) if(d