-- this is a "cookbook" for getting turrets in the different color. -- first you run an auto-join script. -- get a zip factorio, -- change a path in the script to point to the unzipped factorio dir -- ... and try to run the autojoin script. -- works for me [tm], paste problems around should any arise! -- contributions are welcome, but this one is a humble "regression" patch. -- once all the (10 default) players have joined, scroll down -- the HUMP of code is your target, but IF YOU WAN TO, -- you can follow the idea one step at a time. Up to that hunk. -- where present, autogen code is just a js code. -- open up F12 console of your browser, -- or better yet a node engine console (I have one hotkeyed to Super(win) + v) -- paste the autogen code, get the results into lua. -- You can even change the force names "template" or numbers etc. -- help yourself :> -- well, now we begin. -- *: they are in globals cuz we want to know which belong to dummies. -- js autogen for dummy players names -- var l=10;var ul=[]; for(let i=1;i<=l;i++){ul.push(`__dummy_${i.toString().padStart(2, '0')}__`)}; console.log(ul.map(q=>(`"${q}"`)).join(',\n')) /sc global.dummy_names = { "__dummy_01__", "__dummy_02__", "__dummy_03__", "__dummy_04__", "__dummy_05__", "__dummy_06__", "__dummy_07__", "__dummy_08__", "__dummy_09__", "__dummy_10__" } -- js autogen for dummy forces names -- var l=10;var ul=[]; for(let i=1;i<=l;i++){ul.push(`__dummy_force_${i.toString().padStart(2, '0')}__`)}; console.log(ul.map(q=>(`"${q}"`)).join(',\n')) /sc global.dummy_force_names = { "__dummy_force_01__", "__dummy_force_02__", "__dummy_force_03__", "__dummy_force_04__", "__dummy_force_05__", "__dummy_force_06__", "__dummy_force_07__", "__dummy_force_08__", "__dummy_force_09__", "__dummy_force_10__" } -- helper functoins /sc function loop_full(tbl,fn) for index, value in pairs(tbl) do fn(index,value) end end /sc function loop_arr(tbl,fn) for index, value in pairs(tbl) do fn(value) end end -- remove previous iteration of these forces if necessary (should NOT be necessary) /sc loop_arr(global.dummy_force_names, function(name) local f = game.forces[name] if (f == nil) then return end game.merge_forces(f, game.forces['neutral']) end) -- create forces /sc loop_arr(global.dummy_force_names, game.create_force) -- set dummies as friends to each and every other force available :> -- also do this in reverse, we like cheese. /sc loop_arr(global.dummy_force_names, function(name) loop_arr(game.forces, function(other_force) game.forces[name].set_friend(other_force, true); other_force.set_friend(game.forces[name], true); end) end) -- "map" dummy players to join dummy forces -- autogens for the player map. -- the normal one and the "concise" one-liner one. -- var l=10;var ul=[]; for(let i=1;i<=l;i++){ul.push(`["__dummy_${i.toString().padStart(2, '0')}__"] = "__dummy_force_${i.toString().padStart(2, '0')}__"`)}; console.log(ul.join(',\n')) -- and the "packed" (lol) one: -- var l=10;var ul=[]; for(let i=1;i<=l;i++){ul.push(`["__dummy_${i.toString().padStart(2, '0')}__"] = "__dummy_force_${i.toString().padStart(2, '0')}__"`)}; console.log(`local map_players = {${ul.join(',')}}`) -- i.e: /sc local map_players = { ["__dummy_01__"] = "__dummy_force_01__", ["__dummy_02__"] = "__dummy_force_02__", ["__dummy_03__"] = "__dummy_force_03__", ["__dummy_04__"] = "__dummy_force_04__", ["__dummy_05__"] = "__dummy_force_05__", ["__dummy_06__"] = "__dummy_force_06__", ["__dummy_07__"] = "__dummy_force_07__", ["__dummy_08__"] = "__dummy_force_08__", ["__dummy_09__"] = "__dummy_force_09__", ["__dummy_10__"] = "__dummy_force_10__" }; loop_full(map_players, function(ply, frc) game.get_player(ply).force = frc; end) -- or /sc local map_players = {["__dummy_01__"] = "__dummy_force_01__",["__dummy_02__"] = "__dummy_force_02__",["__dummy_03__"] = "__dummy_force_03__",["__dummy_04__"] = "__dummy_force_04__",["__dummy_05__"] = "__dummy_force_05__",["__dummy_06__"] = "__dummy_force_06__",["__dummy_07__"] = "__dummy_force_07__",["__dummy_08__"] = "__dummy_force_08__",["__dummy_09__"] = "__dummy_force_09__",["__dummy_10__"] = "__dummy_force_10__"}; loop_full(map_players, function(ply, frc) game.get_player(ply).force = frc; end) /sc function crazy_color() return {math.random(),math.random(),math.random(),1} end /sc function crazy_ppl() loop_arr(global.dummy_names, function(name) game.get_player(name).color = crazy_color() end) end /sc global.wait_ticks = 120 /sc script.on_event(defines.events.on_tick, function(e) if (e.tick % global.wait_ticks ~= 0) then return end crazy_ppl() end) -- now set up turrets! -- make up a postion map! -- autogen it lol -- the anchor and step size is purely cosmetic -- (map is entity -> column (x cord) ) -- var by=-10;var sty=2; var number = 11; var mp={'gun-turret':-10,'laser-turret':-5,'car':1.5,'tank':6};var tbl = [];for(let i=0; i< 11;i++){for(n in mp){tbl.push(`{"${n}",{${mp[n]},${by + (i * sty)}},${i+1}}`)}}; console.log(tbl.join(',')) /sc local spawn_map = {{"gun-turret",{-10,-10},1},{"laser-turret",{-5,-10},1},{"car",{1.5,-10},1},{"tank",{6,-10},1},{"gun-turret",{-10,-8},2},{"laser-turret",{-5,-8},2},{"car",{1.5,-8},2},{"tank",{6,-8},2},{"gun-turret",{-10,-6},3},{"laser-turret",{-5,-6},3},{"car",{1.5,-6},3},{"tank",{6,-6},3},{"gun-turret",{-10,-4},4},{"laser-turret",{-5,-4},4},{"car",{1.5,-4},4},{"tank",{6,-4},4},{"gun-turret",{-10,-2},5},{"laser-turret",{-5,-2},5},{"car",{1.5,-2},5},{"tank",{6,-2},5},{"gun-turret",{-10,0},6},{"laser-turret",{-5,0},6},{"car",{1.5,0},6},{"tank",{6,0},6},{"gun-turret",{-10,2},7},{"laser-turret",{-5,2},7},{"car",{1.5,2},7},{"tank",{6,2},7},{"gun-turret",{-10,4},8},{"laser-turret",{-5,4},8},{"car",{1.5,4},8},{"tank",{6,4},8},{"gun-turret",{-10,6},9},{"laser-turret",{-5,6},9},{"car",{1.5,6},9},{"tank",{6,6},9},{"gun-turret",{-10,8},10},{"laser-turret",{-5,8},10},{"car",{1.5,8},10},{"tank",{6,8},10},{"gun-turret",{-10,10},11},{"laser-turret",{-5,10},11},{"car",{1.5,10},11},{"tank",{6,10},11}} -- spawn entities: add to the previous one: local surf = game.player.surface; loop_arr(spawn_map, function(data) surf.create_entity({name=data[1], position=data[2], direction=defines.direction.west, force=game.forces[global.dummy_force_names[data[3]] or "player"]}) end) -- add some cosmetic stuff /sc game.player.insert({name="electric-energy-interface"}) game.player.insert({name="substation", count = 2}) game.player.insert({name="uranium-rounds-magazine", count = 400}) game.player.insert({name="coal", count = 200}) -- all of it to the huge fucking clonk -- JUST -- select from here /sc global.dummy_names = { "__dummy_01__", "__dummy_02__", "__dummy_03__", "__dummy_04__", "__dummy_05__", "__dummy_06__", "__dummy_07__", "__dummy_08__", "__dummy_09__", "__dummy_10__" }; global.dummy_force_names = { "__dummy_force_01__", "__dummy_force_02__", "__dummy_force_03__", "__dummy_force_04__", "__dummy_force_05__", "__dummy_force_06__", "__dummy_force_07__", "__dummy_force_08__", "__dummy_force_09__", "__dummy_force_10__" }; function loop_full(tbl,fn) for index, value in pairs(tbl) do fn(index,value) end end function loop_arr(tbl,fn) for index, value in pairs(tbl) do fn(value) end end loop_arr(global.dummy_force_names, function(name) local f = game.forces[name] if (f == nil) then return end game.merge_forces(f, game.forces['neutral']) end) loop_arr(global.dummy_force_names, game.create_force) loop_arr(global.dummy_force_names, function(name) loop_arr(game.forces, function(other_force) game.forces[name].set_friend(other_force, true); other_force.set_friend(game.forces[name], true); end) end) local map_players = { ["__dummy_01__"] = "__dummy_force_01__", ["__dummy_02__"] = "__dummy_force_02__", ["__dummy_03__"] = "__dummy_force_03__", ["__dummy_04__"] = "__dummy_force_04__", ["__dummy_05__"] = "__dummy_force_05__", ["__dummy_06__"] = "__dummy_force_06__", ["__dummy_07__"] = "__dummy_force_07__", ["__dummy_08__"] = "__dummy_force_08__", ["__dummy_09__"] = "__dummy_force_09__", ["__dummy_10__"] = "__dummy_force_10__" }; loop_full(map_players, function(ply, frc) game.get_player(ply).force = frc; end) function crazy_color() return {math.random(),math.random(),math.random(),1} end function crazy_ppl() loop_arr(global.dummy_names, function(name) game.get_player(name).color = crazy_color() end) end global.wait_ticks = 30 local spawn_map = {{"gun-turret",{-10,-10},1},{"laser-turret",{-5,-10},1},{"car",{1.5,-10},1},{"tank",{6,-10},1},{"gun-turret",{-10,-8},2},{"laser-turret",{-5,-8},2},{"car",{1.5,-8},2},{"tank",{6,-8},2},{"gun-turret",{-10,-6},3},{"laser-turret",{-5,-6},3},{"car",{1.5,-6},3},{"tank",{6,-6},3},{"gun-turret",{-10,-4},4},{"laser-turret",{-5,-4},4},{"car",{1.5,-4},4},{"tank",{6,-4},4},{"gun-turret",{-10,-2},5},{"laser-turret",{-5,-2},5},{"car",{1.5,-2},5},{"tank",{6,-2},5},{"gun-turret",{-10,0},6},{"laser-turret",{-5,0},6},{"car",{1.5,0},6},{"tank",{6,0},6},{"gun-turret",{-10,2},7},{"laser-turret",{-5,2},7},{"car",{1.5,2},7},{"tank",{6,2},7},{"gun-turret",{-10,4},8},{"laser-turret",{-5,4},8},{"car",{1.5,4},8},{"tank",{6,4},8},{"gun-turret",{-10,6},9},{"laser-turret",{-5,6},9},{"car",{1.5,6},9},{"tank",{6,6},9},{"gun-turret",{-10,8},10},{"laser-turret",{-5,8},10},{"car",{1.5,8},10},{"tank",{6,8},10},{"gun-turret",{-10,10},11},{"laser-turret",{-5,10},11},{"car",{1.5,10},11},{"tank",{6,10},11}} local surf = game.player.surface; loop_arr(spawn_map, function(data) surf.create_entity({name=data[1], position=data[2], direction=defines.direction.west, force=game.forces[global.dummy_force_names[data[3]] or "player"]}) end) game.player.insert({name="electric-energy-interface"}) game.player.insert({name="substation", count = 2}) game.player.insert({name="uranium-rounds-magazine", count = 400}) game.player.insert({name="coal", count = 200}) -- ... aaaaand up to here. -- and the run line. Just start flipping colors, if you need it. -- be advised! It does not ADD handler (as your usual Event.lua from just any scenario) it OVERWRITES the handler /sc script.on_event(defines.events.on_tick, function(e) if (e.tick % global.wait_ticks ~= 0) then return end crazy_ppl() end) -- shoudl be fine though? -- debug -- use those if you want to play around more, but have no tools handy on the shelf at the moment. -- position of the entity you are hoovering over /sc game.print(game.player.selected.position) -- show current forces list. Yup name > name, ikr. You can add more tho. /sc for i, f in pairs(game.forces) do game.print(i..'>'..f.name) end -- delete all the dummy forces (... why though? well maybe you've got a migration script or something) loop_arr(global.dummy_force_names, function(name) local f = game.forces[name] if (f == nil) then return end game.merge_forces(f, game.forces['neutral']) end) -- AND REMEMBER! -- THIS IS A GOOD PLAYBOOK! -- BUT! -- FACTORIO DOES NOT "SAVE" FUNCTIONS YOU'VE JUST COPYPASTED OVER! -- IF ANYONE JOINS AFTER YOU'VE COPYPASTED THOSE U GET A DESYNC! -- (if they do so before, you are fine) -- if you delete the on_tick you would also be somewhat fine -- untill you run anything that is, lol. -- if you load such a game you "loose" all the scriptery you've "commited". -- well, good luck with your scripting adventure :> -- To keep it "persistent" you add the code to scenarios .lua files, -- or, should you also need just about ANY assets as well... -- welcome to the dark side of the mods creation! -- versions, mod portal, mods-lua-sandbox, yeeehaw! Dependencies order! Yay! -- (alas "only assets" are fine for a dedicated scenario if you want those)