Factorio: implement EnergyLink
This commit is contained in:
parent
6e0165986f
commit
05fe423ef1
|
@ -441,7 +441,7 @@ async def process_server_cmd(ctx: CommonContext, args: dict):
|
|||
else:
|
||||
args['players'].sort()
|
||||
current_team = -1
|
||||
logger.info('Players:')
|
||||
logger.info('Connected Players:')
|
||||
for network_player in args['players']:
|
||||
if network_player.team != current_team:
|
||||
logger.info(f' Team #{network_player.team + 1}')
|
||||
|
|
|
@ -19,7 +19,7 @@ if __name__ == "__main__":
|
|||
Utils.init_logging("FactorioClient", exception_logger="Client")
|
||||
|
||||
from CommonClient import CommonContext, server_loop, console_loop, ClientCommandProcessor, logger, gui_enabled, \
|
||||
get_base_parser
|
||||
get_base_parser
|
||||
from MultiServer import mark_raw
|
||||
from NetUtils import NetworkItem, ClientStatus, JSONtoTextParser, JSONMessagePart
|
||||
|
||||
|
@ -62,6 +62,8 @@ class FactorioContext(CommonContext):
|
|||
self.write_data_path = None
|
||||
self.death_link_tick: int = 0 # last send death link on Factorio layer
|
||||
self.factorio_json_text_parser = FactorioJSONtoTextParser(self)
|
||||
self.energy_link_increment = 0
|
||||
self.last_deplete = 0
|
||||
|
||||
async def server_auth(self, password_requested: bool = False):
|
||||
if password_requested and not self.password:
|
||||
|
@ -105,6 +107,15 @@ class FactorioContext(CommonContext):
|
|||
if "checked_locations" in args and args["checked_locations"]:
|
||||
self.rcon_client.send_commands({item_name: f'/ap-get-technology ap-{item_name}-\t-1' for
|
||||
item_name in args["checked_locations"]})
|
||||
elif cmd == "SetReply":
|
||||
if args["key"] == "EnergyLink":
|
||||
logger.info(f"Got EnergyLink package: {args}")
|
||||
if self.energy_link_increment and args.get("last_deplete", -1) == self.last_deplete:
|
||||
# it's our deplete request
|
||||
gained = args["original_value"] - args["value"]
|
||||
if gained:
|
||||
logger.info(f"EnergyLink: Received {gained} Joules")
|
||||
self.rcon_client.send_command(f"/ap-energylink {int(gained)}")
|
||||
|
||||
|
||||
async def game_watcher(ctx: FactorioContext):
|
||||
|
@ -113,7 +124,8 @@ async def game_watcher(ctx: FactorioContext):
|
|||
next_bridge = time.perf_counter() + 1
|
||||
try:
|
||||
while not ctx.exit_event.is_set():
|
||||
if ctx.awaiting_bridge and ctx.rcon_client and time.perf_counter() > next_bridge:
|
||||
# TODO: restore on-demand refresh
|
||||
if ctx.rcon_client and time.perf_counter() > next_bridge:
|
||||
next_bridge = time.perf_counter() + 1
|
||||
ctx.awaiting_bridge = False
|
||||
data = json.loads(ctx.rcon_client.send_command("/ap-sync"))
|
||||
|
@ -127,8 +139,7 @@ async def game_watcher(ctx: FactorioContext):
|
|||
research_data = data["research_done"]
|
||||
research_data = {int(tech_name.split("-")[1]) for tech_name in research_data}
|
||||
victory = data["victory"]
|
||||
if "death_link" in data: # TODO: Remove this if statement around version 0.2.4 or so
|
||||
await ctx.update_death_link(data["death_link"])
|
||||
await ctx.update_death_link(data["death_link"])
|
||||
|
||||
if not ctx.finished_game and victory:
|
||||
await ctx.send_msgs([{"cmd": "StatusUpdate", "status": ClientStatus.CLIENT_GOAL}])
|
||||
|
@ -145,6 +156,29 @@ async def game_watcher(ctx: FactorioContext):
|
|||
ctx.death_link_tick = death_link_tick
|
||||
if "DeathLink" in ctx.tags:
|
||||
await ctx.send_death()
|
||||
if ctx.energy_link_increment:
|
||||
in_world_bridges = data["energy_bridges"]
|
||||
if in_world_bridges:
|
||||
in_world_energy = data["energy"]
|
||||
if in_world_energy < (ctx.energy_link_increment * in_world_bridges):
|
||||
# attempt to refill
|
||||
ctx.last_deplete = time.time()
|
||||
asyncio.create_task(ctx.send_msgs([{
|
||||
"cmd": "Set", "key": "EnergyLink", "operation": "deplete",
|
||||
"value": -ctx.energy_link_increment * in_world_bridges,
|
||||
"last_deplete": ctx.last_deplete
|
||||
}]))
|
||||
# Above Capacity - (len(Bridges) * ENERGY_INCREMENT)
|
||||
elif in_world_energy > (in_world_bridges * ctx.energy_link_increment * 5) - \
|
||||
ctx.energy_link_increment*in_world_bridges:
|
||||
value = ctx.energy_link_increment * in_world_bridges
|
||||
asyncio.create_task(ctx.send_msgs([{
|
||||
"cmd": "Set", "key": "EnergyLink", "operation": "add",
|
||||
"value": value
|
||||
}]))
|
||||
ctx.rcon_client.send_command(
|
||||
f"/ap-energylink -{value}")
|
||||
logger.info(f"EnergyLink: Sent {value} Joules")
|
||||
|
||||
await asyncio.sleep(0.1)
|
||||
|
||||
|
@ -239,6 +273,8 @@ async def get_info(ctx, rcon_client):
|
|||
ctx.seed_name = info["seed_name"]
|
||||
# 0.2.0 addition, not present earlier
|
||||
death_link = bool(info.get("death_link", False))
|
||||
ctx.energy_link_increment = info.get("energy_link", 0)
|
||||
logger.debug(f"Energy Link Increment: {ctx.energy_link_increment}")
|
||||
await ctx.update_death_link(death_link)
|
||||
|
||||
|
||||
|
|
2
Utils.py
2
Utils.py
|
@ -24,7 +24,7 @@ class Version(typing.NamedTuple):
|
|||
build: int
|
||||
|
||||
|
||||
__version__ = "0.2.5"
|
||||
__version__ = "0.2.6"
|
||||
version_tuple = tuplize_version(__version__)
|
||||
|
||||
from yaml import load, dump, SafeLoader
|
||||
|
|
|
@ -174,7 +174,7 @@ class Factorio(World):
|
|||
return super(Factorio, self).collect_item(state, item, remove)
|
||||
|
||||
def get_required_client_version(self) -> tuple:
|
||||
return max((0, 2, 1), super(Factorio, self).get_required_client_version())
|
||||
return max((0, 2, 6), super(Factorio, self).get_required_client_version())
|
||||
|
||||
options = factorio_options
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ TRAP_EVO_FACTOR = {{ evolution_trap_increase }} / 100
|
|||
MAX_SCIENCE_PACK = {{ max_science_pack }}
|
||||
GOAL = {{ goal }}
|
||||
ARCHIPELAGO_DEATH_LINK_SETTING = "archipelago-death-link-{{ slot_player }}-{{ seed_name }}"
|
||||
ENERGY_INCREMENT = 1000000
|
||||
|
||||
if settings.global[ARCHIPELAGO_DEATH_LINK_SETTING].value then
|
||||
DEATH_LINK = 1
|
||||
|
@ -20,6 +21,40 @@ end
|
|||
|
||||
CURRENTLY_DEATH_LOCK = 0
|
||||
|
||||
function on_check_energy_link(event)
|
||||
--- assuming 1 MJ increment and 5MJ battery:
|
||||
--- first 2 MJ request fill, last 2 MJ push energy, middle 1 MJ does nothing
|
||||
if event.tick % 60 == 30 then
|
||||
local surface = game.get_surface(1)
|
||||
local force = "player"
|
||||
local bridges = surface.find_entities_filtered({name="ap-energy-bridge", force=force})
|
||||
local bridgecount = table_size(bridges)
|
||||
global.forcedata[force].energy_bridges = bridgecount
|
||||
if global.forcedata[force].energy == nil then
|
||||
global.forcedata[force].energy = 0
|
||||
end
|
||||
if global.forcedata[force].energy < ENERGY_INCREMENT * bridgecount * 5 then
|
||||
for i, bridge in ipairs(bridges) do
|
||||
if bridge.energy > ENERGY_INCREMENT*3 then
|
||||
global.forcedata[force].energy = global.forcedata[force].energy + ENERGY_INCREMENT
|
||||
bridge.energy = bridge.energy - ENERGY_INCREMENT
|
||||
end
|
||||
end
|
||||
end
|
||||
for i, bridge in ipairs(bridges) do
|
||||
if global.forcedata[force].energy < ENERGY_INCREMENT then
|
||||
break
|
||||
end
|
||||
if bridge.energy < ENERGY_INCREMENT*2 and global.forcedata[force].energy > ENERGY_INCREMENT then
|
||||
global.forcedata[force].energy = global.forcedata[force].energy - ENERGY_INCREMENT
|
||||
bridge.energy = bridge.energy + ENERGY_INCREMENT
|
||||
end
|
||||
end
|
||||
game.print("Bridges: " .. bridgecount .. " With: " .. global.forcedata["player"].energy)
|
||||
end
|
||||
end
|
||||
script.on_event(defines.events.on_tick, on_check_energy_link)
|
||||
|
||||
{% if not imported_blueprints -%}
|
||||
function set_permissions()
|
||||
local group = game.permissions.get_group("Default")
|
||||
|
@ -69,6 +104,8 @@ function on_force_created(event)
|
|||
data['earned_samples'] = {{ dict_to_lua(starting_items) }}
|
||||
data["victory"] = 0
|
||||
data["death_link_tick"] = 0
|
||||
data["energy"] = 0
|
||||
data["energy_bridges"] = 0
|
||||
global.forcedata[event.force] = data
|
||||
{%- if silo == 2 %}
|
||||
check_spawn_silo(force)
|
||||
|
@ -434,11 +471,14 @@ commands.add_command("ap-sync", "Used by the Archipelago client to get progress
|
|||
force = game.players[call.player_index].force
|
||||
end
|
||||
local research_done = {}
|
||||
local forcedata = chain_lookup(global, "forcedata", force.name)
|
||||
local data_collection = {
|
||||
["research_done"] = research_done,
|
||||
["victory"] = chain_lookup(global, "forcedata", force.name, "victory"),
|
||||
["death_link_tick"] = chain_lookup(global, "forcedata", force.name, "death_link_tick"),
|
||||
["death_link"] = DEATH_LINK
|
||||
["victory"] = chain_lookup(forcedata, "victory"),
|
||||
["death_link_tick"] = chain_lookup(forcedata, "death_link_tick"),
|
||||
["death_link"] = DEATH_LINK,
|
||||
["energy"] = chain_lookup(forcedata, "energy"),
|
||||
["energy_bridges"] = chain_lookup(forcedata, "energy_bridges"),
|
||||
}
|
||||
|
||||
for tech_name, tech in pairs(force.technologies) do
|
||||
|
@ -515,7 +555,12 @@ end)
|
|||
|
||||
|
||||
commands.add_command("ap-rcon-info", "Used by the Archipelago client to get information", function(call)
|
||||
rcon.print(game.table_to_json({["slot_name"] = SLOT_NAME, ["seed_name"] = SEED_NAME, ["death_link"] = DEATH_LINK}))
|
||||
rcon.print(game.table_to_json({
|
||||
["slot_name"] = SLOT_NAME,
|
||||
["seed_name"] = SEED_NAME,
|
||||
["death_link"] = DEATH_LINK,
|
||||
["energy_link"] = ENERGY_INCREMENT
|
||||
}))
|
||||
end)
|
||||
|
||||
|
||||
|
@ -533,6 +578,11 @@ commands.add_command("ap-deathlink", "Kill all players", function(call)
|
|||
game.print("Death was granted by " .. source)
|
||||
end)
|
||||
|
||||
commands.add_command("ap-energylink", "Used by the Archipelago client to manage Energy Link", function(call)
|
||||
local change = tonumber(call.parameter or "0")
|
||||
local force = "player"
|
||||
global.forcedata[force].energy = global.forcedata[force].energy + change
|
||||
end)
|
||||
|
||||
-- data
|
||||
progressive_technologies = {{ dict_to_lua(progressive_technology_table) }}
|
||||
|
|
|
@ -1,4 +1,25 @@
|
|||
{% from "macros.lua" import dict_to_lua %}
|
||||
local energy_bridge = table.deepcopy(data.raw["accumulator"]["accumulator"])
|
||||
energy_bridge.name = "ap-energy-bridge"
|
||||
energy_bridge.minable.result = "ap-energy-bridge"
|
||||
energy_bridge.localised_name = "Archipelago EnergyLink Bridge"
|
||||
data.raw["accumulator"]["ap-energy-bridge"] = energy_bridge
|
||||
|
||||
local energy_bridge_item = table.deepcopy(data.raw["item"]["accumulator"])
|
||||
energy_bridge_item.name = "ap-energy-bridge"
|
||||
energy_bridge_item.localised_name = "Archipelago EnergyLink Bridge"
|
||||
energy_bridge_item.place_result = energy_bridge.name
|
||||
data.raw["item"]["ap-energy-bridge"] = energy_bridge_item
|
||||
|
||||
local energy_bridge_recipe = table.deepcopy(data.raw["recipe"]["accumulator"])
|
||||
energy_bridge_recipe.name = "ap-energy-bridge"
|
||||
energy_bridge_recipe.result = energy_bridge_item.name
|
||||
energy_bridge_recipe.energy_required = 1
|
||||
energy_bridge_recipe.ingredients = { {# {type="item", name="iron-plate", amount=1} TODO: randomized recipe #} }
|
||||
energy_bridge_recipe.enabled = true
|
||||
energy_bridge_recipe.localised_name = "Archipelago EnergyLink Bridge"
|
||||
data.raw["recipe"]["ap-energy-bridge"] = energy_bridge_recipe
|
||||
|
||||
data.raw["map-gen-presets"].default["archipelago"] = {{ dict_to_lua({"default": False, "order": "a", "basic_settings": world_gen["basic"], "advanced_settings": world_gen["advanced"]}) }}
|
||||
if mods["science-not-invited"] then
|
||||
local weights = {
|
||||
|
|
Loading…
Reference in New Issue