--[[ THE SOFTMOD MOD Author: PyroFire https://mods.factorio.com/mod/warptorio2 https://github.com/PyroFire232 Credit also to Kizrak, Kovus, Thuro, & Diablo-D3 for helping make this happen ]] local config={} config.mods={ "vonNeumann", "long-reach", } ----- code below no touchy ----- local trueScript=script local trueSettings=settings local softmod={} softmod.config=config softmod.environment="global" softmod.inscript=false function softmod.Call(f,...) local wasScript=softmod.inscript softmod.inscript=true local r=softmod.environment for k,v in ipairs(softmod.config.mods)do softmod.environment=v f(...) end softmod.environment=r softmod.inscript=wasScript end -- Script overrides softmod.events={} softmod.on_init={} softmod.on_load={} softmod.on_config={} local scriptMeta={} scriptMeta.__index=scriptMeta scriptMeta.__newindex=function() end scriptMeta.on_event=function(u,f) local t=softmod.events[softmod.environment] if(not t)then t={} softmod.events[softmod.environment]=t end if(type(u)=="table")then for k,v in pairs(u)do t[v]=f end else t[u]=f end end scriptMeta.on_init=function(f) softmod.on_init[softmod.environment]=f end scriptMeta.on_load=function(f) softmod.on_load[softmod.environment]=f end scriptMeta.on_configuration_changed=function(f) softmod.on_config[softmod.environment]=f end scriptMeta.raise_event=function(n,...) trueScript.raise_event(n,...) end function softmod.LoadControls() pcall(softmod.Call,function() require(softmod.environment .. "/control.lua") end) end function softmod.DoCallInit(...) local t=softmod.on_init[softmod.environment] if(t)then t(...) end end function softmod.CallInit(...) softmod.Call(softmod.DoCallInit,...) end function softmod.DoCallLoad(...) local t=softmod.on_load[softmod.environment] if(t)then t(...) end end function softmod.CallLoad(...) softmod.Call(softmod.DoCallLoad,...) end function softmod.DoCallConfig(...) local t=softmod.on_config[softmod.environment] if(t)then t(...) end end function softmod.CallConfig(...) softmod.Call(softmod.DoCallConfig,...) end function softmod.DoEvent(ev,...) local t=softmod.events[softmod.environment] if(t and t[ev])then t[ev](...) end end function softmod.Event(ev,...) softmod.Call(softmod.DoEvent,...) end -- Settings Data Overrides softmod.settings={} function softmod.SettingsType(v) if(v=="runtime-global")then return "global" elseif(v=="startup")then return "startup" elseif(v=="player")then return "player" end end local dataSettingsMeta={} dataSettingsMeta.__index=dataSettingsMeta -- todo for later; function dataSettingsMeta.__index(t,k) local x=softmod.settings[softmod.environment] if(x and x[k])then return x[k] end return settings[k] end -- todo for later; function dataSettingsMeta.__newindex(t,k,v) local x=softmod.settings[softmod.environment] if(not x)then x={} softmod.settings[softmod.environment]=x end x[k]=v end function dataSettingsMeta:extend(t) local s=softmod.settings[softmod.environment] if(not s)then s={} softmod.settings[softmod.environment]=s end for k,v in pairs(t)do local tx=softmod.SettingsType(v["setting_type"]) if(not s[tx])then s[tx]={} end s[tx][v.name]={type=v.type,name=v.name,value=v.default_value,setting_type=v.setting_type,default_value=v.default_value,minimum_value=v.minimum_value,maximum_value=v.maximum_value} end end function softmod.LoadSetting() softmod.settings[softmod.environment]=softmod.settings[softmod.environment] or {} pcall(require,softmod.environment .."/settings") end function softmod.LoadSettingUpdate() softmod.settings[softmod.environment]=softmod.settings[softmod.environment] or {} pcall(require,softmod.environment .."/settings-updates") end function softmod.LoadSettingFinal() softmod.settings[softmod.environment]=softmod.settings[softmod.environment] or {} pcall(require,softmod.environment .."/settings-final-fixes") end function softmod.LoadSettings() softmod.Call(softmod.LoadSetting) pcall(softmod.Call,softmod.LoadSettingUpdate) pcall(softmod.Call,LoadSettingFinal) end -- Settings Lookup Overrides local settingsLookupMeta={} function settingsLookupMeta.__index(t,k) local x=softmod.settings[softmod.environment] local n=rawget(t,"_name") if(x and x[n] and x[n][k])then return x[n][k] else return trueSettings[n][k] end end --local settingsMeta={} --function settingsMeta.__index(t,u) local x=softmod.settings[softmod.environment] if(x and x[u])then return x[u] else return trueSettings[u] end end -- Global Table Handler softmod.GlobalMeta={} function softmod.GlobalMeta.__index(t,k) if(softmod.inscript)then if(not rawget(t,softmod.environment))then rawset(t,softmod.environment,{}) return rawget(t,softmod.environment)[k] end else return rawget(global,k) end end function softmod.GlobalMeta.__newindex(t,k,v) if(softmod.inscript)then if(not rawget(rawget(global,"softmod_data"),softmod.environment))then rawset(rawget(global,"softmod_data"),softmod.environment,{}) end rawget(rawget(global,"softmod_data"),softmod.environment)[k]=v else rawset(global,k,v) end end function softmod.Global() if(not softmod.Loaded)then softmod.Hijack() end if(not softmod.global)then setmetatable(rawget(global,"softmod_data"),softmod.GlobalMeta) softmod.global=rawget(global,"softmod_data") end if(not softmod.inscript)then return global end return softmod.global end local globalMeta={} function globalMeta.__index(t,k) return softmod.Global()[k] end function globalMeta.__newindex(t,k,v) softmod.Global()[k]=v end function softmod.OverrideGlobal() if(global)then global.softmod_mods=global.softmod_mods or {} global.softmod_data=global.softmod_data or {} setmetatable(global,globalMeta) end end -- Hijack everything function softmod.CheckMods(bForce) local v=global.softmod_mods if(not v)then v={} global.softmod_mods=v end local r=softmod.environment local wasScript=softmod.inscript softmod.inscript=true for k,mod in pairs(softmod.config.mods)do if(bForce or not v[mod])then softmod.environment=mod v[mod]=0 if(softmod.on_init[mod])then softmod.on_init[mod]() end end end softmod.inscript=wasScript softmod.environment=r end function softmod.Hijack(bForce) if(bForce or not softmod.Loaded)then softmod.OverrideGlobal(bForce) softmod.CheckMods(bForce) softmod.Loaded=true end end function softmod.Initialize(...) softmod.Hijack(true) softmod.CallInit(...) end function softmod.Load(...) softmod.CallLoad(...) end function softmod.ChangeConfig(...) softmod.Hijack(true) softmod.CallConfig(...) end script.on_init(softmod.Initialize) script.on_load(softmod.Load) script.on_configuration_changed(softmod.ChangeConfig) for k,v in pairs(defines.events)do script.on_event(v,function(...) softmod.Hijack() softmod.Event(v,...) end) end script=setmetatable({},scriptMeta) data=setmetatable({},dataSettingsMeta) settings={} --setmetatable({},settingsMeta) for k,v in pairs{"global","startup","player"}do settings[v]=setmetatable({_name=v},settingsLookupMeta) end -- "Install" ALL the mods!! softmod.LoadSettings() softmod.LoadControls() ------------------------------------------------------------------------------------- ------------------------------------------------------------------------------------- ------------------------------------------------------------------------------------- ------------------------------------------------------------------------------------- ------------------------------------------------------------------------------------- ------------------------------------------------------------------------------------- --[[ -- old hijack.lua local old_script_on_event = script.on_event local table_event = {} local on_event_history = {} local function doAllEvents(event) name = event.name for index,value in ipairs(table_event[name]) do value(event) end end script.on_event = function(event_ids, _function) event_ids = (type(event_ids) == "table" and event_ids) or {event_ids} for _, event_id in pairs(event_ids) do if not table_event[event_id] then table_event[event_id] = {} end table.insert(on_event_history,event_id) table.insert(table_event[event_id],_function) old_script_on_event(event_id,doAllEvents); end end local old_script_on_init = script.on_init local table_init = {} local function doAllInits(event) for index,value in ipairs(table_init) do value(event) end end script.on_init(doAllInits) script.on_init = function(_function) table.insert(table_init,_function) end local function print_on_event_history(event) local player = game.players[event.player_index] player.print("on_event_history #"..#on_event_history) player.print(serpent.block(on_event_history)) local printHelper = {} local count = 0 for key,value in pairs(table_event) do printHelper[key] = #value count = #value + count end player.print("table_event #"..#table_event..' '..count) player.print(serpent.block(table_event)) player.print(serpent.block(printHelper)) log(serpent.block(printHelper)) log(serpent.block(table_event)) player.print("table_init #"..#table_init) end commands.add_command("history", "history", print_on_event_history) ]]