research thechnologies for existing items - PVP
research thechnologies for existing items - PVP
Appologies if this is the wrong place to post.
Hosting PVP server with a couple of friends. One destroyed their silo and saves were overwritten (default save settings).
Was able to recreate the team with the same name and was assigned same index, player joined the force and spawned on the same base with all items in there.
The only thing that got reset is the research. Wondering if there a script can be written such that:
- for all unique items / buildings in the force -> grab required research.
- set required research status to researched.
Thanks!
Hosting PVP server with a couple of friends. One destroyed their silo and saves were overwritten (default save settings).
Was able to recreate the team with the same name and was assigned same index, player joined the force and spawned on the same base with all items in there.
The only thing that got reset is the research. Wondering if there a script can be written such that:
- for all unique items / buildings in the force -> grab required research.
- set required research status to researched.
Thanks!
Re: research thechnologies for existing items - PVP
It would be possible if each item (rather: a recipe making it) was unlocked by a single research. But at least in modded games, there may be several techs that unlock the same item.mohsh86 wrote: Sat May 06, 2023 11:26 pm The only thing that got reset is the research. Wondering if there a script can be written such that:
- for all unique items / buildings in the force -> grab required research.
- set required research status to researched.
A good mod deserves a good changelog. Here's a tutorial (WIP) about Factorio's way too strict changelog syntax!
Re: research thechnologies for existing items - PVP
am playing unmodded game if that helps.
doesn't matter if there are duplicate results. the other code snippet should just set them to researched.
doesn't matter if there are duplicate results. the other code snippet should just set them to researched.
Re: research thechnologies for existing items - PVP
The following code researches technologies in tech_names
question remaining is, how do I populate tech_names with relevant technologies, based on items/buildings the force/team has
Code: Select all
local player = game.players["player_name"]
local force = player.force
local tech_names = {"automation", "logistics", "logistics-2", "logistics-3",
"electric-energy-distribution-1", "electric-energy-accumulators", "oil-processing",
"advanced-oil-processing", "sulfur-processing", "plastics", "advanced-electronics",
"modules", "nuclear-power", "rocket-silo"}
for _, tech_name in ipairs(tech_names) do
force.technologies[tech_name].researched = true
end
Re: research thechnologies for existing items - PVP
You could copy this and paste it into the chat console:mohsh86 wrote: Sun May 07, 2023 8:27 am question remaining is, how do I populate tech_names with relevant technologies, based on items/buildings the force/team has
Code: Select all
/c
forces = {}
items = {}
craft_items = {}
item_recipes = {}
prerequisites = {}
player_inventories = {
defines.inventory.character_main,
defines.inventory.character_guns,
defines.inventory.character_ammo,
defines.inventory.character_armor,
defines.inventory.character_trash
}
for f_name, force in pairs(game.forces) do
if next(force.players) then
forces[f_name] = { items = {}, recipes = {}, research_this = {} }
for p, player in pairs(force.players) do
char = player.character
for i, id in pairs(char and char.valid and player_inventories or {}) do
inv = char.get_inventory(id)
for item, i in pairs(inv and inv.valid and inv.get_contents() or {}) do
forces[f_name].items[item] = true
items[item] = true
end
end
end
end
end
for s_name, surface in pairs(game.surfaces) do
for e, entity in pairs(surface.find_entities()) do
if entity.valid and entity.last_user then
player = type(entity.last_user) == "table" and entity.last_user or
game.players[entity.last_user]
force = player.force
for i, item in pairs(entity.prototype.items_to_place_this or {}) do
forces[force.name].items[item.name] = true
items[item.name] = true
end
if entity.has_items_inside() then
for id = 1, entity.get_max_inventory_index() do
inv = entity.get_inventory(id)
for item, i in pairs(inv and inv.valid and inv.get_contents() or {}) do
forces[force.name].items[item] = true
items[item] = true
end
end
end
end
end
end
for r_name, recipe in pairs(game.recipe_prototypes) do
for p, product in pairs(recipe.products) do
if product.type == "item" then
item_recipes[r_name] = true
craft_items[product.name] = craft_items[product.name] or {}
table.insert(craft_items[product.name], r_name)
end
end
end
for i_name, i in pairs(items) do
if not craft_items[i_name] then
for f_name, f_data in pairs(forces) do
f_data.items[i_name] = nil
end
items[i_name] = nil
else
for f_name, f_data in pairs(forces) do
for r, recipe in pairs(craft_items[i_name]) do
f_data.recipes[recipe] = true
end
end
end
end
function find_prerequisites(tech_name, list)
tech = game.technology_prototypes[tech_name]
list = list or {}
for p_name, prerequisite in pairs(tech.prerequisites) do
if not list[p_name] then
list[p_name] = true
find_prerequisites(p_name, list)
end
end
return list
end
for t_name, tech in pairs(game.technology_prototypes) do
for e, effect in pairs(tech.effects) do
if effect.type == "unlock-recipe" and item_recipes[effect.recipe] then
for f_name, f_data in pairs(forces) do
if f_data.recipes[effect.recipe] then
f_data.research_this[t_name] = true
prerequisites[t_name] = prerequisites[t_name] or find_prerequisites(t_name)
end
end
end
end
end
for f_name, f_data in pairs(forces) do
research = {}
for t_name, t in pairs(f_data.research_this) do
for p_name, p in pairs(prerequisites[t_name] or {}) do
research[p_name] = true
end
research[t_name] = true
end
force = game.forces[f_name]
for t_name, t in pairs(research) do
force.technologies[t_name].researched = true
end
end
Code: Select all
local forces = {}
local items = {} -- List of all items we'll find
local craft_items = {} -- List of items that can be produced by a recipe
local item_recipes = {} -- Recipes that produce an item
local prerequisites = {} -- List of all prerequisite techs required by a tech
local player_inventories = {
defines.inventory.character_main,
defines.inventory.character_guns,
defines.inventory.character_ammo,
defines.inventory.character_armor,
defines.inventory.character_trash
}
local char, inv
-- Find all forces with at least one player
for f_name, force in pairs(game.forces) do
if next(force.players) then
forces[f_name] = { items = {}, recipes = {}, research_this = {} }
-- Store names of items found in player inventories with force
for p, player in pairs(force.players) do
char = player.character
for i, id in pairs(char and char.valid and player_inventories or {}) do
inv = char.get_inventory(id)
for item, i in pairs(inv and inv.valid and inv.get_contents() or {}) do
forces[f_name].items[item] = true
items[item] = true
end
end
end
end
end
-- Find all entities on all surfaces
local force, player, items
for s_name, surface in pairs(game.surfaces) do
for e, entity in pairs(surface.find_entities()) do
-- Get force this entity belongs to (must have been placed by a player)
if entity.valid and entity.last_user then
player = type(entity.last_user) == "table" and entity.last_user or
game.players[entity.last_user]
force = player.force
-- Add names of items used to place this entity to item list of force
for i, item in pairs(entity.prototype.items_to_place_this or {}) do
forces[force.name].items[item.name] = true
items[item.name] = true
end
-- Add names of items found inside the entity to item list of force
if entity.has_items_inside() then
for id = 1, entity.get_max_inventory_index() do
inv = entity.get_inventory(id)
for item, i in pairs(inv and inv.valid and inv.get_contents() or {}) do
forces[force.name].items[item] = true
items[item] = true
end
end
end
end
end
end
-- Find all recipes that produce items
for r_name, recipe in pairs(game.recipe_prototypes) do
for p, product in pairs(recipe.products) do
-- Ignore fluids!
if product.type == "item" then
item_recipes[r_name] = true
craft_items[product.name] = craft_items[product.name] or {}
table.insert(craft_items[product.name], r_name)
end
end
end
-- Update force data
for i_name, i in pairs(items) do
-- Remove all items that can't be crafted from force data
if not craft_items[i_name] then
for f_name, f_data in pairs(forces) do
f_data.items[i_name] = nil
end
items[i_name] = nil
-- If force has this item, store names of all recipes producing it with force data
else
for f_name, f_data in pairs(forces) do
for r, recipe in pairs(craft_items[i_name]) do
f_data.recipes[recipe] = true
end
end
end
end
function find_prerequisites(tech_name, list)
local tech = game.technology_prototypes[tech_name]
list = list or {}
for p_name, prerequisite in pairs(tech.prerequisites) do
if not list[p_name] then
list[p_name] = true
find_prerequisites(p_name, list)
end
end
return list
end
-- Find all techs that unlock any of these recipes
for t_name, tech in pairs(game.technology_prototypes) do
for e, effect in pairs(tech.effects) do
if effect.type == "unlock-recipe" and item_recipes[effect.recipe] then
-- Store this tech for all forces that have the unlock recipe in their data
for f_name, f_data in pairs(forces) do
if f_data.recipes[effect.recipe] then
f_data.research_this[t_name] = true
-- If this is the first force that needs this tech, store all technologies
-- required to unlock the tech!
prerequisites[t_name] = prerequisites[t_name] or find_prerequisites(t_name)
end
end
end
end
end
-- Research techs and their prerequisites!
for f_name, f_data in pairs(forces) do
research = {}
-- One technology may be prerequisite of several other techs. We want to research
-- as little as possible as each finished research will raise an event, so we
-- compile a list where each tech will be listed just once.
for t_name, t in pairs(f_data.research_this) do
for p_name, p in pairs(prerequisites[t_name]) do
research[p_name] = true
end
-- Add the tech that was actually needed, it may be prerequisite of another tech!
research[t_name] = true
end
force = game.forces[f_name]
for t_name, t in pairs(research) do
force.technologies[t_name].researched = true
end
end
A good mod deserves a good changelog. Here's a tutorial (WIP) about Factorio's way too strict changelog syntax!
Re: research thechnologies for existing items - PVP
Pi-C wrote: Sun May 07, 2023 2:38 pm
This is basically the same code, but commented, so it should be easier to read:Duh, how stupid! Use this instead:Code: Select all
… -- Find all entities on all surfaces local force, player, items for s_name, surface in pairs(game.surfaces) do for e, entity in pairs(surface.find_entities()) do -- Get force this entity belongs to (must have been placed by a player) if entity.valid and entity.last_user then player = type(entity.last_user) == "table" and entity.last_user or game.players[entity.last_user] force = player.force
Code: Select all
-- Find all entities on all surfaces local force, player, items for s_name, surface in pairs(game.surfaces) do for e, entity in pairs(surface.find_entities()) do -- Get force this entity belongs to (must have been placed by a player) if entity.valid then force = entity.force
A good mod deserves a good changelog. Here's a tutorial (WIP) about Factorio's way too strict changelog syntax!
Re: research thechnologies for existing items - PVP
Worked out great, Thanks!
One last thing, I've noticed that with the existing items, I won't be able to link things together (for example, extend on existing wall, etc) also, electrical grid doesn't show on map unless I build and place something new. Is it possible to reclaim entities (i.e. become the owner again for entities of force in question).
Cheers!
One last thing, I've noticed that with the existing items, I won't be able to link things together (for example, extend on existing wall, etc) also, electrical grid doesn't show on map unless I build and place something new. Is it possible to reclaim entities (i.e. become the owner again for entities of force in question).
Cheers!
Re: research thechnologies for existing items - PVP
You're welcome!
Which force do these entities belong to now? Do they have last_user? You can find out by hovering your cursor of an entity and use this on the command line:One last thing, I've noticed that with the existing items, I won't be able to link things together (for example, extend on existing wall, etc) also, electrical grid doesn't show on map unless I build and place something new. Is it possible to reclaim entities (i.e. become the owner again for entities of force in question).
Code: Select all
/c p = game.player; s = p.selected; if s then game.print(string.format("Selected entity: %s (%s)\tForce: %s\tLast user: %s", s.name, s.unit_number, s.force.name, s.last_user and s.last_user.name or "none")) end
A good mod deserves a good changelog. Here's a tutorial (WIP) about Factorio's way too strict changelog syntax!
Re: research thechnologies for existing items - PVP
I've recreated the force with the same name (got created with the same index), and I joined it with the same name. and Yes, the last user for all items was me as well.
Really Appreciated it
Edit:
I've typed the command while hovering over an item it shows:
force: neutral last user: <my user>
Really Appreciated it

Edit:
I've typed the command while hovering over an item it shows:
force: neutral last user: <my user>
Re: research thechnologies for existing items - PVP
This finally worked after lots of talks with chat GPT lol. I need to read more about lua and factorio's API
local player_name = "player_name"
local force_name = "force_name"
for _, surface in pairs(game.surfaces) do
for _, entity in pairs(surface.find_entities_filtered{last_user = player_name, force = "neutral"}) do
entity.force = game.forces[force_name]
end
end
Re: research thechnologies for existing items - PVP
Unfortunately, you can't use last_user directly as filter for find_entities_filtered. But once you've got a list of entities, you can check whether they have last_user, and whether the last_user has the same force as the entity:mohsh86 wrote: Tue May 09, 2023 12:04 pm This finally worked after lots of talks with chat GPT lol. I need to read more about lua and factorio's API
Code: Select all
local player_name = "player_name" local force_name = "force_name" for _, surface in pairs(game.surfaces) do for _, entity in pairs(surface.find_entities_filtered{last_user = player_name, force = "neutral"}) do entity.force = game.forces[force_name] end end
Code: Select all
local old, new
for s, surface in pairs(game.surfaces) do
for e, entity in pairs(surface.find_entities()) do
old = entity.force
new = entity.last_user and entity.last_user.force
if new and new ~= old then
log(string.format("Entity: %s (%s)\tOld force: %s\tNew force: %s", entity.name, entity.unit_number or "nil", old.name, new.name))
entity.force = new
end
end
end
Code: Select all
local force_name = "force_name"
…
for … do
entity.force = game.forces[force_name]
end
…
Code: Select all
local force_name = "force_name"
local force = game.forces[force_name]
…
for … do
entity.force = force
end
…
Code: Select all
local force_name = "force_name"
…
for … do
entity.force = force_name
end
…
A good mod deserves a good changelog. Here's a tutorial (WIP) about Factorio's way too strict changelog syntax!