From 8b7d8a9560760bfaff2676cb46e6cad444f065bb Mon Sep 17 00:00:00 2001 From: Monica Moniot Date: Mon, 24 Oct 2022 22:20:05 -0400 Subject: [PATCH 1/5] added cybernetic combinators --- LICENSE | 2 +- cybersyn/control.lua | 2 +- cybersyn/data.lua | 22 +- .../icons/{depot.png => combinator.png} | Bin ...{p_threshold.png => provide-threshold.png} | Bin ...{r_threshold.png => request-threshold.png} | Bin cybersyn/graphics/icons/station.png | Bin 2532 -> 0 bytes cybersyn/graphics/invisible.png | Bin 0 -> 505 bytes cybersyn/locale/en/base.cfg | 30 +- cybersyn/prototypes/entity.lua | 80 +-- cybersyn/prototypes/item.lua | 16 +- cybersyn/prototypes/signal.lua | 14 +- cybersyn/prototypes/tech.lua | 23 +- cybersyn/scripts/constants.lua | 15 +- cybersyn/scripts/controller.lua | 76 ++- cybersyn/scripts/global.lua | 19 +- cybersyn/scripts/main.lua | 454 +++++++++++------- cybersyn/settings.lua | 6 +- 18 files changed, 456 insertions(+), 303 deletions(-) rename cybersyn/graphics/icons/{depot.png => combinator.png} (100%) rename cybersyn/graphics/icons/{p_threshold.png => provide-threshold.png} (100%) rename cybersyn/graphics/icons/{r_threshold.png => request-threshold.png} (100%) delete mode 100644 cybersyn/graphics/icons/station.png create mode 100644 cybersyn/graphics/invisible.png diff --git a/LICENSE b/LICENSE index aeb0e16..0c08310 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2022 Monica Moniot +Copyright (c) 2022 Mami Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/cybersyn/control.lua b/cybersyn/control.lua index 9ef9749..6b7facc 100644 --- a/cybersyn/control.lua +++ b/cybersyn/control.lua @@ -1,4 +1,4 @@ - +--By Mami require("scripts.constants") require("scripts.global") diff --git a/cybersyn/data.lua b/cybersyn/data.lua index 78fc92c..3cc2b38 100644 --- a/cybersyn/data.lua +++ b/cybersyn/data.lua @@ -8,18 +8,14 @@ require('prototypes.entity') require('prototypes.signal') data:extend({ - cybersyn_depot_item, - cybersyn_station_item, - cybersyn_depot_recipe, - cybersyn_station_recipe, + combinator_entity, + combinator_out_entity, + combinator_item, + combinator_recipe, cybersyn_tech, - cybersyn_depot_entity, - cybersyn_station_entity, - cybersyn_station_in, - cybersyn_station_out, - cybersyn_subgroup, - cybersyn_priority, - cybersyn_p_threshold, - cybersyn_r_threshold, - cybersyn_locked_slots, + subgroup_signal, + priority_signal, + p_threshold_signal, + r_threshold_signal, + locked_slots_signal, }) diff --git a/cybersyn/graphics/icons/depot.png b/cybersyn/graphics/icons/combinator.png similarity index 100% rename from cybersyn/graphics/icons/depot.png rename to cybersyn/graphics/icons/combinator.png diff --git a/cybersyn/graphics/icons/p_threshold.png b/cybersyn/graphics/icons/provide-threshold.png similarity index 100% rename from cybersyn/graphics/icons/p_threshold.png rename to cybersyn/graphics/icons/provide-threshold.png diff --git a/cybersyn/graphics/icons/r_threshold.png b/cybersyn/graphics/icons/request-threshold.png similarity index 100% rename from cybersyn/graphics/icons/r_threshold.png rename to cybersyn/graphics/icons/request-threshold.png diff --git a/cybersyn/graphics/icons/station.png b/cybersyn/graphics/icons/station.png deleted file mode 100644 index 3f4233236012a0c3d07b99909145f407a013676f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2532 zcmVEX>4Tx04R}tkv&MmKpe$iQ>9ue3U&}t$WUFhAS&W0RV;#q(pG5I!Q|2}Xws0R zxHt-~1qVMCs}3&Cx;nTDg5U>;qmz@OinMK^}g2S3InX6muzVhU}?*F8LZy$kcK_UHZ_JxbPOfJY>rW4d7xZxGLH zS~}-_;vg$X3h_DdxIq^re&o9B@*C&8!vfC?8mYuQagbQdx3Jv8tYE0b)5IY~)hJ&` zyR2~D;;fb`tZ`5N!a!DANphX$5TaN@3~`8%Q9%(USP0Xqkzyi2`;j*OLB}5_mrSlA z7&#VDh6>5?ga5(rZq3}(q?;6o0G%(k{V@Xgc7b};w!e>UyM6+ApMfi_=`YuS*-z4| zO)Yc;^lk$e*G)~{11@)ffhS!uBuDbn6mmJ>{fxdT1N7el{x!F^#y(CTfE0DLd;=UD z0;74#UT^d6uGZfEJ=5s#2b#xnxA)#C(f|Me24YJ`L;(K){{a7>y{D4^000SaNLh0L z01ejw01ejxLMWSf00007bV*G`2j&SK5DP4Bps7><00-bnL_t(|+U;9=Y*W`6|DEG| zedA{yB*ZZx51K-Gc54S?-4hzBDA^{Vc4`@$CecCFYGcyYMtgLTwIVi}YD_|tx`4C| zM(NabUB@F53k5XPg{a!bibz62L*m4C$iqqezSq9r{s<&-Y!W+QLvX%7zw7Uw@Ao_B zdz^ER8E%Tx={i8bP5=^8C|;i*$KG$mnAZnU6hW$rr>iSbTvUiONr(XrMMaj~0Kfsj z;cz@c!1q!O9sn*~xr#p54S2jh47*3*9v#DnA6-HkMIzw)eSLi^CJ0azr60gp%Bc^@ z=)B$&qj&V*z_5EHog|FPvc4Yx*ey+OfB&PL=ov;#OvQ-T?T);6PMzNB_4)JTJr@Ka zwE1)EPkw&=r#n)KoERw)#@<<4Sopsv0#YeEYi(a=L`MLaC$%gBkS|&X6<|MasJHzR z0HwpXR1?5nsI99dVta3e+fDTlW9qgr=Utizy$4{;G_&L2fp0hL+c!FI3D{9vYZ6KS zM*?k~wgxY$2yZ>~#-1(!c*$lnDqi|MV|ZqoYwaovZ$0$-p4NFsz>Zp*RUkS8;E^co zV8@sN-)*qj{L}r|^@{B$0KFEyQZNF}zSgkMb|F;+@Kn51ApA5MJc|(6D+lXs-;4tu z0H~qfwwF};D!|-R^f^#ze=1i1Ptm#>oTiaEQ)eyqg2>we@=Q|?&OZY5c%6WAQzlqP z#NU6RwreCHx{Nm&-@ER_j1*kk4e0Wns z{hn*{y$_g?ga}10-%IdwBH+xK^G^|@?c-UVX%cEbiMYq_uLy@Drip#u4wnoyDrZUjIZ7#*qHw5cg&1T=kcZa0A6q^pIVORGm7uhCl!39##80%0U0YX4$Y9~faLITAgvKYgPqINO3I_YIrnMPbMSieqo+#n+ z%FkjTe+g7JIq&Qne;JO+0r|sDJpZRX$Q>DYAixjjEXJX4y^7&HOJbX$!Mq~8SG^NE z-r5`UEG&pPRkPjR*_zzrM}Yo|B5Dy;o7) zbQD5ZiLv`z&Ca;sZ%Y6GbS_(iupq{~@Z#fJ@ZpB)+p^ugbOp+K+EDC>KG3mSD{$he z@60+|bG5fyE090jk0)9hVhjLkOCeA9Cie09D+fTAc;nBQt_pKok+;} zA+K-3k-3V7a}-PCXSVCEG-KVB=2>k#fgpUL@$akT@j?oC5z-lxOM)}H?>Se(_!{=DH?nhHK=pcjH18#e|?LcZCU z)WE$%?zD zyQ^ai(262NQ4E;PW@kDb9~&DhQWQleD+=OmSr`DVRs`o<$<58RCv$c&AU0wD+_vqF0IFI$u0d8}KZkM7ux7<_Fvc#weeCGk zxrV?+05BU(aUW)zZt7LKnD*=qv;aVkIlgaZlM#$DfY`-3=K#*=004D~WibpoUGxA( zBZ?O11Aq@u52ihNaU2AL-?BI#W}_i`M(_t3J6|I9+bo3oa|;h|x4_jJMUo4jgkGMQ0UUIw!{`<`a;(XmlEX>4Tx04R}tkv&MmKpe$iQ>7{uhjtKg2w0sg_=PxX6^c-y)C#RSm|Xe=O&XFE z7e~Rh;NZt%)xpJCR|i)?5c~jfa&%I3krMxx6k5c1aNLh~_a1le0HI!Hs@X9HsG4P@ z;xRFkT@?eb=!PF53}IYiraqTUCg3@~?&0I>U6f~epZjz4Dmjw@K9P8q>4rtTK|H-_ z>74h8!>lMN#OK7L23?T&k?XR{Z=4Gb3p_Jyq*L?6VPdh+#&R38qM;H`5l0kNqkJLb zvch?bvs$jQ<~{ifgE?(wnd>wM5yv8ykc0>sRg_SMg($5WDJD|1AM@}JIQ}HLWO9|j z$gzM5R7j2={11M2Yvv~>+@xR(=zOv5k6|FN3p8rB{e5iPjT6BC3|wg~f29u0e3D*k zX^|tKZyUI{ZfWu!aJd8YKk1SoIg+2Ikk13}XY@^3Aao1#thv24_i_3Fq^YaK4RCM> zj1(w)-Q(R|?Y;ebrrF;Qi86Aqr#a3j0000PbVXQnLvL+uWo~o;Lvm$dbY)~9cWHEJ vAV*0}P*;Ht7XSbN3rR#lR0!8&U;qLD00jU6;wA-~00000NkvXXu0mjfKZ4Te literal 0 HcmV?d00001 diff --git a/cybersyn/locale/en/base.cfg b/cybersyn/locale/en/base.cfg index 9c42495..27d1aff 100644 --- a/cybersyn/locale/en/base.cfg +++ b/cybersyn/locale/en/base.cfg @@ -1,32 +1,26 @@ [mod-setting-name] cybersyn-ticks-per-second=Dispatcher ticks per second -cybersyn-requester-threshold=Default requester threshold -cybersyn-provider-threshold=Default provider threshold +cybersyn-request-threshold=Default requester threshold +cybersyn-provide-threshold=Default provider threshold [mod-setting-description] cybersyn-ticks-per-second=How many times per second to check all stations for possible deliveries. This value will be rounded up to a divisor of 60. -cybersyn-requester-threshold=When a requester threshold signal is not recieved by a station it will default to this value. -cybersyn-provider-threshold=When a provider threshold signal is not recieved by a station it will default to this value. +cybersyn-request-threshold=When a requester threshold signal is not recieved by a station it will default to this value. +cybersyn-provide-threshold=When a provider threshold signal is not recieved by a station it will default to this value. [item-name] -cybersyn-depot=Cybersyn depot -cybersyn-station=Cybersyn station +cybersyn-combinator=Cybernetic combinator [item-description] -cybersyn-depot=Cybersyn depot -cybersyn-station=Cybersyn station +cybersyn-combinator=Cybernetic combinator [entity-name] -cybersyn-depot=Cybersyn depot -cybersyn-station=Cybersyn station -cybersyn-station-out=Cybersyn station output -cybersyn-station-in=Cybersyn station input +cybersyn-combinator=Cybernetic combinator +cybersyn-combinator-output=NA [entity-description] -cybersyn-depot=Cybersyn depot -cybersyn-station=Cybersyn station -cybersyn-station-out=Cybersyn station output -cybersyn-station-in=Cybersyn station input +cybersyn-combinator=Cybersyn depot +cybersyn-combinator-output=NA [technology-name] cybersyn-train-network=Cybernetic train network @@ -36,6 +30,6 @@ cybersyn-train-network=Cybernetic train network [virtual-signal-name] cybersyn-priority=Station priority -cybersyn-p_threshold=Provide threshold -cybersyn-r_threshold=Request threshold +cybersyn-provide-threshold=Provide threshold +cybersyn-request-threshold=Request threshold cybersyn-locked-slots=Locked slots per cargo wagon diff --git a/cybersyn/prototypes/entity.lua b/cybersyn/prototypes/entity.lua index fc9fb6a..e9d08e4 100644 --- a/cybersyn/prototypes/entity.lua +++ b/cybersyn/prototypes/entity.lua @@ -1,39 +1,47 @@ --By Mami -cybersyn_station_entity = flib.copy_prototype(data.raw["train-stop"]["train-stop"], BUFFER_STATION_NAME) -cybersyn_station_entity.icon = "__cybersyn__/graphics/icons/station.png" -cybersyn_station_entity.icon_size = 64 -cybersyn_station_entity.icon_mipmaps = 4 -cybersyn_station_entity.next_upgrade = nil -cybersyn_station_entity.color = {.5, .1, .9} +combinator_entity = flib.copy_prototype(data.raw["arithmetic-combinator"]["arithmetic-combinator"], COMBINATOR_NAME) +combinator_entity.icon = "__cybersyn__/graphics/icons/combinator.png" +combinator_entity.radius_visualisation_specification = { + sprite = { + filename = "__cybersyn__/graphics/icons/combinator.png", + tint = {r = 1, g = 1, b = .25, a = 1}, + height = 64, + width = 64, + }, + distance = 1, +} -cybersyn_depot_entity = flib.copy_prototype(data.raw["train-stop"]["train-stop"], DEPOT_STATION_NAME) -cybersyn_depot_entity.icon = "__cybersyn__/graphics/icons/depot.png" -cybersyn_depot_entity.icon_size = 64 -cybersyn_depot_entity.icon_mipmaps = 4 -cybersyn_depot_entity.next_upgrade = nil -cybersyn_depot_entity.color = {1, .9, .9} +combinator_out_entity = flib.copy_prototype(data.raw["constant-combinator"]["constant-combinator"], COMBINATOR_OUT_NAME) +combinator_out_entity.icon = nil +combinator_out_entity.icon_size = nil +combinator_out_entity.icon_mipmaps = nil +combinator_out_entity.next_upgrade = nil +combinator_out_entity.minable = nil +combinator_out_entity.selection_box = nil +combinator_out_entity.collision_box = nil +combinator_out_entity.collision_mask = {} +combinator_out_entity.item_slot_count = 500 +combinator_out_entity.circuit_wire_max_distance = 3 +combinator_out_entity.flags = {"not-blueprintable", "not-deconstructable", "placeable-off-grid"} -cybersyn_station_in = flib.copy_prototype(data.raw["lamp"]["small-lamp"], STATION_IN_NAME) -cybersyn_station_in.icon = "__cybersyn__/graphics/icons/station.png" -cybersyn_station_in.icon_size = 64 -cybersyn_station_in.icon_mipmaps = 4 -cybersyn_station_in.next_upgrade = nil -cybersyn_station_in.minable = nil -cybersyn_station_in.selection_box = {{-0.5, -0.5}, {0.5, 0.5}} -cybersyn_station_in.selection_priority = 60 -cybersyn_station_in.collision_box = {{-0.15, -0.15}, {0.15, 0.15}} -cybersyn_station_in.collision_mask = {"rail-layer"} -cybersyn_station_in.energy_usage_per_tick = "10W" -cybersyn_station_in.light = {intensity = 1, size = 6} -cybersyn_station_in.energy_source = {type="void"} - -cybersyn_station_out = flib.copy_prototype(data.raw["constant-combinator"]["constant-combinator"],STATION_OUT_NAME) -cybersyn_station_out.icon = "__cybersyn__/graphics/icons/station.png" -cybersyn_station_out.icon_size = 64 -cybersyn_station_out.icon_mipmaps = 4 -cybersyn_station_out.next_upgrade = nil -cybersyn_station_out.minable = nil -cybersyn_station_out.selection_box = {{-0.5, -0.5}, {0.5, 0.5}} -cybersyn_station_out.selection_priority = 60 -cybersyn_station_out.collision_box = {{-0.15, -0.15}, {0.15, 0.15}} -cybersyn_station_out.collision_mask = {"rail-layer"} +local origin = {0.0, 0.0} +local invisible_sprite = {filename = "__cybersyn__/graphics/invisible.png", width = 1, height = 1} +local wire_con1 = { + red = origin, + green = origin +} +local wire_con0 = {wire = wire_con1, shadow = wire_con1} +combinator_out_entity.sprites = invisible_sprite +combinator_out_entity.activity_led_sprites = invisible_sprite +combinator_out_entity.activity_led_light = { + intensity = 0, + size = 0, +} +combinator_out_entity.activity_led_light_offsets = {origin, origin, origin, origin} +combinator_out_entity.draw_circuit_wires = false +combinator_out_entity.circuit_wire_connection_points = { + wire_con0, + wire_con0, + wire_con0, + wire_con0 +} diff --git a/cybersyn/prototypes/item.lua b/cybersyn/prototypes/item.lua index cbe919e..428db83 100644 --- a/cybersyn/prototypes/item.lua +++ b/cybersyn/prototypes/item.lua @@ -1,12 +1,6 @@ --By Mami -cybersyn_station_item = flib.copy_prototype(data.raw["item"]["train-stop"], BUFFER_STATION_NAME) -cybersyn_station_item.icon = "__cybersyn__/graphics/icons/station.png" -cybersyn_station_item.icon_size = 64 -cybersyn_station_item.icon_mipmaps = 4 -cybersyn_station_item.order = cybersyn_station_item.order.."-c" - -cybersyn_depot_item = flib.copy_prototype(data.raw["item"]["train-stop"], DEPOT_STATION_NAME) -cybersyn_depot_item.icon = "__cybersyn__/graphics/icons/depot.png" -cybersyn_depot_item.icon_size = 64 -cybersyn_depot_item.icon_mipmaps = 4 -cybersyn_depot_item.order = cybersyn_depot_item.order.."-d" +combinator_item = flib.copy_prototype(data.raw["item"]["arithmetic-combinator"], COMBINATOR_NAME) +combinator_item.icon = "__cybersyn__/graphics/icons/combinator.png" +combinator_item.icon_size = 64 +combinator_item.icon_mipmaps = 4 +combinator_item.order = combinator_item.order.."-c" diff --git a/cybersyn/prototypes/signal.lua b/cybersyn/prototypes/signal.lua index cc5a5e8..cbc8fff 100644 --- a/cybersyn/prototypes/signal.lua +++ b/cybersyn/prototypes/signal.lua @@ -1,11 +1,11 @@ --By Mami -cybersyn_subgroup = { +subgroup_signal = { type = "item-subgroup", name = "cybersyn-signal", group = "signals", order = "cybersyn0[cybersyn-signal]" } -cybersyn_priority = { +priority_signal = { type = "virtual-signal", name = SIGNAL_PRIORITY, icon = "__cybersyn__/graphics/icons/priority.png", @@ -13,23 +13,23 @@ cybersyn_priority = { subgroup = "cybersyn-signal", order = "a-a" } -cybersyn_p_threshold = { +p_threshold_signal = { type = "virtual-signal", name = PROVIDE_THRESHOLD, - icon = "__cybersyn__/graphics/icons/p_threshold.png", + icon = "__cybersyn__/graphics/icons/provide-threshold.png", icon_size = 64, subgroup = "cybersyn-signal", order = "a-b" } -cybersyn_r_threshold = { +r_threshold_signal = { type = "virtual-signal", name = REQUEST_THRESHOLD, - icon = "__cybersyn__/graphics/icons/r_threshold.png", + icon = "__cybersyn__/graphics/icons/request-threshold.png", icon_size = 64, subgroup = "cybersyn-signal", order = "a-c" } -cybersyn_locked_slots = { +locked_slots_signal = { type = "virtual-signal", name = LOCKED_SLOTS, icon = "__cybersyn__/graphics/icons/locked_slots.png", diff --git a/cybersyn/prototypes/tech.lua b/cybersyn/prototypes/tech.lua index fa7c661..e787109 100644 --- a/cybersyn/prototypes/tech.lua +++ b/cybersyn/prototypes/tech.lua @@ -1,17 +1,10 @@ --By Mami -cybersyn_station_recipe = flib.copy_prototype(data.raw["recipe"]["train-stop"], BUFFER_STATION_NAME) -cybersyn_station_recipe.ingredients = { - {"train-stop", 1}, +combinator_recipe = flib.copy_prototype(data.raw["recipe"]["train-stop"], COMBINATOR_NAME) +combinator_recipe.ingredients = { + {"copper-cable", 5}, {"advanced-circuit", 5}, } -cybersyn_station_recipe.enabled = false - -cybersyn_depot_recipe = flib.copy_prototype(data.raw["recipe"]["train-stop"], DEPOT_STATION_NAME) -cybersyn_depot_recipe.ingredients = { - {"train-stop", 1}, - {"electronic-circuit", 5}, -} -cybersyn_depot_recipe.enabled = false +combinator_recipe.enabled = false cybersyn_tech = { type = "technology", @@ -27,11 +20,7 @@ cybersyn_tech = { effects = { { type = "unlock-recipe", - recipe = BUFFER_STATION_NAME - }, - { - type = "unlock-recipe", - recipe = DEPOT_STATION_NAME + recipe = COMBINATOR_NAME }, }, unit = { @@ -39,7 +28,7 @@ cybersyn_tech = { {"automation-science-pack", 1}, {"logistic-science-pack", 1} }, - count = 300, + count = 400, time = 30 }, order = "c-g-c" diff --git a/cybersyn/scripts/constants.lua b/cybersyn/scripts/constants.lua index ca80e9e..86cd4e2 100644 --- a/cybersyn/scripts/constants.lua +++ b/cybersyn/scripts/constants.lua @@ -1,14 +1,17 @@ --By Mami SIGNAL_PRIORITY = "cybersyn-priority" -REQUEST_THRESHOLD = "cybersyn-r_threshold" -PROVIDE_THRESHOLD = "cybersyn-p_threshold" +REQUEST_THRESHOLD = "cybersyn-request-threshold" +PROVIDE_THRESHOLD = "cybersyn-provide-threshold" LOCKED_SLOTS = "cybersyn-locked-slots" -STATION_IN_NAME = "cybersyn-station-in" -STATION_OUT_NAME = "cybersyn-station-out" -BUFFER_STATION_NAME = "cybersyn-station" -DEPOT_STATION_NAME = "cybersyn-depot" +COMBINATOR_NAME = "cybersyn-combinator" +COMBINATOR_OUT_NAME = "cybersyn-combinator-output" + +OPERATION_PRIMARY_IO = "*" +OPERATION_SECONDARY_IO = "/" +OPERATION_DEPOT = "+" +OPERATION_WAGON_MANIFEST = "-" DELTA = 1/2048 diff --git a/cybersyn/scripts/controller.lua b/cybersyn/scripts/controller.lua index 045f40f..cc8fbe9 100644 --- a/cybersyn/scripts/controller.lua +++ b/cybersyn/scripts/controller.lua @@ -54,20 +54,76 @@ function create_manifest_schedule(depot_name, p_stop, r_stop, manifest) end - local function get_signals(station) - local signals = station.entity_in.get_merged_signals() - return signals + if station.comb1.valid then + local signals = station.comb1.get_merged_signals(defines.circuit_connector_id.combinator_input) + return signals + else + return nil + end +end + +function set_combinator_output(map_data, comb, signals) + if comb.valid then + local out = map_data.to_output[comb.unit_number] + if out.valid then + out.get_or_create_control_behavior().parameters = signals + else + --TODO: error logging? + end + else + --TODO: error logging? + end +end + +local function set_comb2(map_data, station) + if station.comb2 then + local deliveries = station.deliveries + local signals = {} + for item_name, count in pairs(deliveries) do + local i = #signals + 1 + local item_type = game.item_prototypes[item_name].type + signals[i] = {index = i, signal = {type = item_type, name = item_name}, count = count} + end + set_combinator_output(map_data, station.comb2, signals) + end +end + +function remove_manifest(map_data, station, manifest, sign) + local deliveries = station.deliveries + for i, item in ipairs(manifest) do + deliveries[item.name] = deliveries[item.name] + sign*item.count + if deliveries[item.name] == 0 then + deliveries[item.name] = nil + end + end + set_comb2(map_data, station) + station.deliveries_total = station.deliveries_total - 1 +end + +local function get_thresholds(map_data, station, signal) + local comb2 = station.comb2 + if comb2 and comb2.valid then + local count = comb2.get_merged_signal(signal, defines.circuit_connector_id.combinator_input) + if count > 0 then + return station.r_threshold, count + elseif count < 0 then + return -count, station.p_threshold + end + end + return station.r_threshold, station.p_threshold end local function get_stop_dist(stop0, stop1) return get_distance(stop0.position, stop1.position) end + local function station_accepts_layout(station, layout_id) return true end + local function get_valid_train(map_data, r_station_id, p_station_id, item_type) --NOTE: this code is the critical section for run-time optimization local r_station = map_data.stations[r_station_id] @@ -113,6 +169,7 @@ local function get_valid_train(map_data, r_station_id, p_station_id, item_type) end end + local function send_train_between(map_data, r_station_id, p_station_id, train, primary_item_name, economy) local r_station = map_data.stations[r_station_id] local p_station = map_data.stations[p_station_id] @@ -128,7 +185,8 @@ local function send_train_between(map_data, r_station_id, p_station_id, train, p local item_type = v.signal.type if item_name and item_type and item_type ~= "virtual" then local effective_item_count = item_count + (r_station.deliveries[item_name] or 0) - if -effective_item_count >= r_station.r_threshold then + local r_threshold, p_threshold = get_thresholds(map_data, r_station, v) + if -effective_item_count >= r_threshold then requests[item_name] = -effective_item_count end end @@ -143,7 +201,8 @@ local function send_train_between(map_data, r_station_id, p_station_id, train, p local item_type = v.signal.type if item_name and item_type and item_type ~= "virtual" then local effective_item_count = item_count + (p_station.deliveries[item_name] or 0) - if effective_item_count >= p_station.p_threshold then + local r_threshold, p_threshold = get_thresholds(map_data, r_station, v) + if effective_item_count >= p_threshold then local r = requests[item_name] if r then local item = {name = item_name, count = math.min(r, effective_item_count), type = item_type} @@ -230,6 +289,8 @@ local function send_train_between(map_data, r_station_id, p_station_id, train, p train.manifest = manifest train.entity.schedule = create_manifest_schedule(train.depot_name, p_station.entity, r_station.entity, manifest) + set_comb2(map_data, p_station) + set_comb2(map_data, r_station) end @@ -279,8 +340,9 @@ function tick(map_data, mod_settings) local item_name = v.signal.name local item_count = v.count local effective_item_count = item_count + (station.deliveries[item_name] or 0) + local r_threshold, p_threshold = get_thresholds(map_data, station, v) - if -effective_item_count >= station.r_threshold then + if -effective_item_count >= r_threshold then if r_stations_all[item_name] == nil then r_stations_all[item_name] = {} p_stations_all[item_name] = {} @@ -288,7 +350,7 @@ function tick(map_data, mod_settings) all_items[#all_items + 1] = v.signal.type end table.insert(r_stations_all[item_name], station_id) - elseif effective_item_count >= station.p_threshold then + elseif effective_item_count >= p_threshold then if r_stations_all[item_name] == nil then r_stations_all[item_name] = {} p_stations_all[item_name] = {} diff --git a/cybersyn/scripts/global.lua b/cybersyn/scripts/global.lua index d5d8dae..5404611 100644 --- a/cybersyn/scripts/global.lua +++ b/cybersyn/scripts/global.lua @@ -4,7 +4,10 @@ global: { total_ticks: int layout_top_id: int + to_output: {[comb_unit_number]: LuaEntity} + to_stop: {[comb_unit_number]: LuaEntity} stations: {[stop_id]: Station} + depots: {[stop_id]: LuaEntity} trains: {[train_id]: Train} trains_available: {[train_id]: bool} layouts: {[layout_id]: Layout} @@ -18,12 +21,16 @@ Station: { r_threshold: int >= 0 p_threshold: int >= 0 locked_slots: int >= 0 - entity: LuaEntity - entity_in: LuaEntity - entity_out: LuaEntity + entity_stop: LuaEntity + entity_comb1: LuaEntity + entity_comb2: LuaEntity? + wagon_combs: {[int]: LuaEntity}--allowed to be invalid entities deliveries: { [item_name]: int } + deliveries: { + [item_name]: item-type + } train_class: string accepted_layouts: TrainClass layout_pattern: string|nil @@ -51,11 +58,13 @@ Layout: string --TODO: only init once mod_settings = {} mod_settings.tps = settings.global["cybersyn-ticks-per-second"].value -mod_settings.r_threshold = settings.global["cybersyn-requester-threshold"].value -mod_settings.p_threshold = settings.global["cybersyn-provider-threshold"].value +mod_settings.r_threshold = settings.global["cybersyn-request-threshold"].value +mod_settings.p_threshold = settings.global["cybersyn-provide-threshold"].value global.total_ticks = 0 +global.to_output = {} global.stations = {} +global.depots = {} global.trains = {} global.trains_available = {} global.layouts = {} diff --git a/cybersyn/scripts/main.lua b/cybersyn/scripts/main.lua index e428922..a1b1315 100644 --- a/cybersyn/scripts/main.lua +++ b/cybersyn/scripts/main.lua @@ -1,38 +1,21 @@ --By Mami -local function set_station_output_empty(station) - --change circuit outputs - station.entity_out.get_control_behavior().parameters = nil -end - local function on_failed_delivery(map_data, train) --NOTE: must change train status to STATUS_D or remove it from tracked trains after this call local is_p_delivery_made = train.status ~= STATUS_D_TO_P and train.status ~= STATUS_P if not is_p_delivery_made then local station = map_data.stations[train.p_station_id] - for i, item in ipairs(train.manifest) do - station.deliveries[item.name] = station.deliveries[item.name] + item.count - if station.deliveries[item.name] == 0 then - station.deliveries[item.name] = nil - end - end - station.deliveries_total = station.deliveries_total - 1 + remove_manifest(map_data, station, train.manifest, 1) if train.status == STATUS_P then - set_station_output_empty(station) + set_combinator_output(map_data, station.comb1, nil) end end local is_r_delivery_made = train.status == STATUS_R_TO_D if not is_r_delivery_made then local station = map_data.stations[train.r_station_id] - for i, item in ipairs(train.manifest) do - station.deliveries[item.name] = station.deliveries[item.name] - item.count - if station.deliveries[item.name] == 0 then - station.deliveries[item.name] = nil - end - end - station.deliveries_total = station.deliveries_total - 1 + remove_manifest(map_data, station, train.manifest, -1) if train.status == STATUS_R then - set_station_output_empty(station) + set_combinator_output(map_data, station.comb1, nil) end end train.r_station_id = 0 @@ -40,91 +23,12 @@ local function on_failed_delivery(map_data, train) train.manifest = nil end -local function on_station_built(map_data, stop) - local pos_x = stop.position.x - local pos_y = stop.position.y - - local in_pos - local out_pos - local search_area - if stop.direction == 0 then - in_pos = {pos_x, pos_y - 1} - out_pos = {pos_x - 1, pos_y - 1} - search_area = { - {pos_x + DELTA - 1, pos_y + DELTA - 1}, - {pos_x - DELTA + 1, pos_y - DELTA} - } - elseif stop.direction == 2 then - in_pos = {pos_x, pos_y} - out_pos = {pos_x, pos_y - 1} - search_area = { - {pos_x + DELTA, pos_y + DELTA - 1}, - {pos_x - DELTA + 1, pos_y - DELTA + 1} - } - elseif stop.direction == 4 then - in_pos = {pos_x - 1, pos_y} - out_pos = {pos_x, pos_y} - search_area = { - {pos_x + DELTA - 1, pos_y + DELTA}, - {pos_x - DELTA + 1, pos_y - DELTA + 1} - } - elseif stop.direction == 6 then - in_pos = {pos_x - 1, pos_y - 1} - out_pos = {pos_x - 1, pos_y} - search_area = { - {pos_x + DELTA - 1, pos_y + DELTA - 1}, - {pos_x - DELTA, pos_y - DELTA + 1} - } - else - assert(false, "cybersyn: invalid direction of train stop") - end - - local entity_in = nil - local entity_out = nil - local entities = stop.surface.find_entities(search_area) - for _, cur_entity in pairs(entities) do - if cur_entity.valid then - if cur_entity.name == "entity-ghost" then - if cur_entity.ghost_name == STATION_IN_NAME then - _, entity_in = cur_entity.silent_revive() - elseif cur_entity.ghost_name == STATION_OUT_NAME then - _, entity_out = cur_entity.silent_revive() - end - elseif cur_entity.name == STATION_IN_NAME then - entity_in = cur_entity - elseif cur_entity.name == STATION_OUT_NAME then - entity_out = cur_entity - end - end - end - - if entity_in == nil then - entity_in = stop.surface.create_entity({ - name = STATION_IN_NAME, - position = in_pos, - force = stop.force - }) - end - entity_in.operable = false - entity_in.minable = false - entity_in.destructible = false - - if entity_out == nil then - entity_out = stop.surface.create_entity({ - name = STATION_OUT_NAME, - position = out_pos, - direction = stop.direction, - force = stop.force - }) - end - entity_out.operable = false - entity_out.minable = false - entity_out.destructible = false - +local function on_station_built(map_data, stop, comb1, comb2) local station = { - entity = stop, - entity_in = entity_in, - entity_out = entity_out, + entity_stop = stop, + entity_comb1 = comb1, + entity_comb2 = comb2, + wagon_combs = nil, deliveries_total = 0, last_delivery_tick = 0, priority = 0, @@ -140,11 +44,9 @@ local function on_station_built(map_data, stop) update_station_if_auto(map_data, station) end -local function on_station_broken(map_data, stop) - --search for trains coming to the destroyed station - local station_id = stop.unit_number - local station = map_data.stations[station_id] +local function on_station_broken(map_data, station_id, station) if station.deliveries_total > 0 then + --search for trains coming to the destroyed station for train_id, train in pairs(map_data.trains) do local is_r = train.r_station_id == station_id local is_p = train.p_station_id == station_id @@ -161,13 +63,226 @@ local function on_station_broken(map_data, stop) end end end - - if station.entity_in.valid then station.entity_in.destroy() end - if station.entity_out.valid then station.entity_out.destroy() end - map_data.stations[station_id] = nil end +local function search_for_station_combinator(map_data, stop, comb_operation, comb_forbidden) + local pos_x = stop.position.x + local pos_y = stop.position.y + --TODO: fix search area + local search_area = { + {pos_x + DELTA - 1, pos_y + DELTA - 1}, + {pos_x - DELTA + 1, pos_y - DELTA + 1} + } + local entities = stop.surface.find_entities(search_area) + for _, entity in pairs(entities) do + if + entity.valid and entity.name == COMBINATOR_NAME and + entity ~= comb_forbidden and map_data.to_stop[entity.unit_number] == stop + then + local control = entity.get_or_create_control_behavior().parameters + if control.operation == comb_operation then + return entity + end + end + end +end + +local function on_combinator_built(map_data, comb) + local pos_x = comb.position.x + local pos_y = comb.position.y + + --TODO: fix search area + local search_area = { + {pos_x + DELTA - 1, pos_y + DELTA - 1}, + {pos_x - DELTA + 1, pos_y - DELTA + 1} + } + local stop = nil + local rail = nil + local entities = stop.surface.find_entities(search_area) + for _, cur_entity in pairs(entities) do + if cur_entity.valid then + if cur_entity.name == "train-stop" then + --NOTE: if there are multiple stops we take the later one + stop = cur_entity + elseif cur_entity.name == "rail-straight" then + rail = cur_entity + end + end + end + + local out = comb.surface.create_entity({ + name = COMBINATOR_OUT_NAME, + position = comb.position, + force = comb.force + }) + comb.connect_neighbour({ + target_entity = out, + source_wire_id = defines.circuit_connector_id.combinator_output, + wire = defines.wire_type.green, + }) + comb.connect_neighbour({ + target_entity = out, + source_wire_id = defines.circuit_connector_id.combinator_output, + wire = defines.wire_type.red, + }) + + map_data.to_output[comb.unit_number] = out + map_data.to_stop[comb.unit_number] = stop + + local control = comb.get_or_create_control_behavior().parameters + if control.operation == OPERATION_WAGON_MANIFEST then + if rail then + update_station_from_rail(map_data, rail) + end + elseif control.operation == OPERATION_DEPOT then + if stop then + local station = map_data.stations[stop.unit_number] + local depot_comb = map_data.depots[stop.unit_number] + if depot_comb or station then + --NOTE: repeated combinators are ignored + else + map_data.depots[stop.unit_number] = comb + end + end + elseif control.operation == OPERATION_SECONDARY_IO then + if stop then + local station = map_data.stations[stop.unit_number] + if station and not station.entity_comb2 then + station.entity_comb2 = comb + end + end + elseif stop then + control.operation = OPERATION_PRIMARY_IO + local station = map_data.stations[stop.unit_number] + local depot_comb = map_data.depots[stop.unit_number] + if station then + --NOTE: repeated combinators are ignored + else + if depot_comb then + --NOTE: this will disrupt deliveries in progress that where dispatched from this station in a minor way + map_data.depots[stop.unit_number] = nil + end + --no station or depot + --add station + + local comb2 = search_for_station_combinator(map_data, stop, OPERATION_SECONDARY_IO, nil) + + station = { + entity_stop = stop, + entity_comb1 = comb, + entity_comb2 = comb2, + wagon_combs = nil, + deliveries_total = 0, + last_delivery_tick = 0, + priority = 0, + r_threshold = 0, + p_threshold = 0, + locked_slots = 0, + deliveries = {}, + train_class = TRAIN_CLASS_AUTO, + accepted_layouts = {}, + layout_pattern = nil, + } + map_data.stations[stop.unit_number] = station + + update_station_if_auto(map_data, station) + end + end +end +local function on_combinator_broken(map_data, comb) + local out = map_data.to_output[comb.unit_number] + local stop = map_data.to_stop[comb.unit_number] + + if stop and stop.valid then + local station = map_data.stations[stop.unit_number] + if station then + if station.comb1 == comb then + local comb1 = search_for_station_combinator(map_data, stop, OPERATION_PRIMARY_IO, comb) + if comb1 then + station.comb1 = comb1 + else + on_station_broken(map_data, stop.unit_number, station) + map_data.depots[stop.unit_number] = search_for_station_combinator(map_data, stop, OPERATION_DEPOT, nil) + end + elseif station.comb2 == comb then + station.comb2 = search_for_station_combinator(map_data, stop, OPERATION_SECONDARY_IO, comb) + end + else + local depot_comb = map_data.depots[stop.unit_number] + if depot_comb == comb then + --NOTE: this will disrupt deliveries in progress that where dispatched from this station in a minor way + map_data.depots[stop.unit_number] = search_for_station_combinator(map_data, stop, OPERATION_DEPOT, comb) + end + end + end + + if out and out.valid then + out.destroy() + end + map_data.to_output[comb.unit_number] = nil + map_data.to_stop[comb.unit_number] = nil +end +local function on_combinator_updated(map_data, comb) + --NOTE: this is the lazy way to implement updates and is not robust + on_combinator_broken(map_data, comb) + on_combinator_built(map_data, comb) +end + +local function on_stop_built(map_data, stop) + local pos_x = stop.position.x + local pos_y = stop.position.y + + --TODO: fix search area + local search_area = { + {pos_x + DELTA - 1, pos_y + DELTA - 1}, + {pos_x - DELTA + 1, pos_y - DELTA + 1} + } + local comb2 = nil + local comb1 = nil + local depot_comb = nil + local entities = stop.surface.find_entities(search_area) + for _, entity in pairs(entities) do + if entity.valid and entity.name == COMBINATOR_NAME and map_data.to_stop[entity.unit_number] == nil then + map_data.to_stop[entity.unit_number] = stop + local control = entity.get_or_create_control_behavior().parameters + if control.operation == OPERATION_PRIMARY_IO then + comb1 = entity + elseif control.operation == OPERATION_SECONDARY_IO then + comb2 = entity + elseif control.operation == OPERATION_DEPOT then + depot_comb = entity + end + end + end + if comb1 then + on_station_built(map_data, stop, comb1, comb2) + elseif depot_comb then + map_data.depots[stop.unit_number] = depot_comb + end +end +local function on_stop_broken(map_data, stop) + local pos_x = stop.position.x + local pos_y = stop.position.y + + --TODO: fix search area + local search_area = { + {pos_x + DELTA - 1, pos_y + DELTA - 1}, + {pos_x - DELTA + 1, pos_y - DELTA + 1} + } + local entities = stop.surface.find_entities(search_area) + for _, entity in pairs(entities) do + if map_data.to_stop[entity.unit_number] == stop then + map_data.to_stop[entity.unit_number] = nil + end + end + + local station = map_data.stations[stop.unit_number] + if station then + on_station_broken(map_data, stop.unit_number, station) + end + map_data.depots[stop.unit_number] = nil +end local function on_station_rename(map_data, stop) --search for trains coming to the renamed station local station_id = stop.unit_number @@ -193,24 +308,18 @@ local function on_station_rename(map_data, stop) end -local function find_and_add_all_stations(map_data) +local function find_and_add_all_stations_from_nothing(map_data) for _, surface in pairs(game.surfaces) do - local stops = surface.find_entities_filtered({type="train-stop"}) - if stops then - for k, stop in pairs(stops) do - if stop.name == BUFFER_STATION_NAME then - local station = map_data.stations[stop.unit_number] - if not station then - on_station_built(map_data, stop) - end - end + local entities = surface.find_entities_filtered({name = COMBINATOR_NAME}) + for k, comb in pairs(entities) do + if comb.valid then + on_combinator_built(map_data, comb) end end end end - local function on_train_arrives_depot(map_data, train_entity) local train = map_data.trains[train_entity.id] if train then @@ -251,15 +360,15 @@ local function on_train_arrives_depot(map_data, train_entity) r_station_id = 0, manifest = nil, } - update_train_layout(global, train) + update_train_layout(map_data, train) map_data.trains[train_entity.id] = train map_data.trains_available[train_entity.id] = true local schedule = create_depot_schedule(train.depot_name) train_entity.schedule = schedule end end - -local function on_train_arrives_buffer(map_data, station_id, train) +local function on_train_arrives_buffer(map_data, stop, train) + local station_id = stop.unit_number if train.manifest then if train.status == STATUS_D_TO_P then if train.p_station_id == station_id then @@ -270,7 +379,7 @@ local function on_train_arrives_buffer(map_data, station_id, train) for i, item in ipairs(train.manifest) do signals[i] = {index = i, signal = {type = item.type, name = item.name}, count = item.count} end - station.entity_out.get_control_behavior().parameters = signals + set_combinator_output(map_data, station.comb1, signals) end elseif train.status == STATUS_P_TO_R then if train.r_station_id == station_id then @@ -281,7 +390,7 @@ local function on_train_arrives_buffer(map_data, station_id, train) for i, item in ipairs(train.manifest) do signals[i] = {index = i, signal = {type = item.type, name = item.name}, count = -1} end - station.entity_out.get_control_behavior().parameters = signals + set_combinator_output(map_data, station.comb1, signals) end else on_failed_delivery(map_data, train) @@ -293,31 +402,18 @@ local function on_train_arrives_buffer(map_data, station_id, train) remove_train(map_data, train, train.entity.id) end end - local function on_train_leaves_station(map_data, train) if train.manifest then if train.status == STATUS_P then train.status = STATUS_P_TO_R local station = map_data.stations[train.p_station_id] - for i, item in ipairs(train.manifest) do - station.deliveries[item.name] = station.deliveries[item.name] + item.count - if station.deliveries[item.name] == 0 then - station.deliveries[item.name] = nil - end - end - station.deliveries_total = station.deliveries_total - 1 - set_station_output_empty(station) + remove_manifest(map_data, station, train.manifest, 1) + set_combinator_output(map_data, station.comb1, nil) elseif train.status == STATUS_R then train.status = STATUS_R_TO_D local station = map_data.stations[train.r_station_id] - for i, item in ipairs(train.manifest) do - station.deliveries[item.name] = station.deliveries[item.name] - item.count - if station.deliveries[item.name] == 0 then - station.deliveries[item.name] = nil - end - end - station.deliveries_total = station.deliveries_total - 1 - set_station_output_empty(station) + remove_manifest(map_data, station, train.manifest, -1) + set_combinator_output(map_data, station.comb1, nil) end end end @@ -331,7 +427,6 @@ local function on_train_broken(map_data, train) end end end - local function on_train_modified(map_data, pre_train_id, train_entity) local train = map_data.trains[pre_train_id] if train then @@ -347,8 +442,6 @@ local function on_train_modified(map_data, pre_train_id, train_entity) end - - local function on_tick(event) tick(global, mod_settings) global.total_ticks = global.total_ticks + 1 @@ -358,8 +451,10 @@ local function on_built(event) local entity = event.entity or event.created_entity or event.destination if not entity or not entity.valid then return end - if entity.name == BUFFER_STATION_NAME then - on_station_built(global, entity) + if entity.name == "train-stop" then + on_stop_built(global, entity) + elseif entity.name == COMBINATOR_NAME then + on_combinator_built(global, entity) elseif entity.type == "inserter" then update_station_from_inserter(global, entity) elseif entity.type == "pump" then @@ -377,10 +472,11 @@ local function on_broken(event) if train then on_train_broken(global, train) end - elseif entity.name == BUFFER_STATION_NAME then - on_station_broken(global, entity) + elseif entity.name == "train-stop" then + on_stop_broken(global, entity) + elseif entity.name == COMBINATOR_NAME then + on_combinator_broken(global, entity) elseif entity.type == "inserter" then - --NOTE: check if this works or if it needs to be delayed update_station_from_inserter(global, entity) elseif entity.type == "pump" then update_station_from_pump(global, entity) @@ -388,22 +484,9 @@ local function on_broken(event) update_station_from_rail(global, entity) end end - -local function on_train_changed(event) - local train_e = event.train - local train = global.trains[train_e.id] - if train_e.state == defines.train_state.wait_station and train_e.station ~= nil then - if train_e.station.name == DEPOT_STATION_NAME then - on_train_arrives_depot(global, train_e) - elseif train_e.station.name == BUFFER_STATION_NAME then - if train then - on_train_arrives_buffer(global, train_e.station.unit_number, train) - end - end - elseif event.old_state == defines.train_state.wait_station then - if train then - on_train_leaves_station(global, train) - end +local function on_rename(event) + if event.entity.name == "train-stop" then + on_station_rename(global, event.entity) end end @@ -416,33 +499,48 @@ local function on_train_built(event) on_train_modified(global, event.old_train_id_2, train_e) end end +local function on_train_changed(event) + local train_e = event.train + local train = global.trains[train_e.id] + if train_e.state == defines.train_state.wait_station then + local stop = train_e.station + if stop and stop.name == "train-stop" then + if global.stations[stop.unit_number] then + on_train_arrives_buffer(global, stop, train) + elseif global.depots[stop.unit_number] then + on_train_arrives_depot(global, train_e) + end + end + elseif event.old_state == defines.train_state.wait_station then + if train then + on_train_leaves_station(global, train) + end + end +end local function on_surface_removed(event) local surface = game.surfaces[event.surface_index] if surface then local train_stops = surface.find_entities_filtered({type = "train-stop"}) for _, entity in pairs(train_stops) do - if entity.name == BUFFER_STATION_NAME then + if entity.name == "train-stop" then on_station_broken(global, entity) end end end end -local function on_rename(event) - if event.entity.name == BUFFER_STATION_NAME then - on_station_rename(global, event.entity) - end -end local filter_built = { {filter = "type", type = "train-stop"}, + {filter = "type", type = "arithmetic-combinator"}, {filter = "type", type = "inserter"}, {filter = "type", type = "pump"}, {filter = "type", type = "straight-rail"}, } local filter_broken = { {filter = "type", type = "train-stop"}, + {filter = "type", type = "arithmetic-combinator"}, {filter = "type", type = "inserter"}, {filter = "type", type = "pump"}, {filter = "type", type = "straight-rail"}, @@ -477,12 +575,12 @@ end) script.on_init(function() --TODO: we are not checking changed cargo capacities - find_and_add_all_stations(global) + --find_and_add_all_stations(global) register_events() end) script.on_configuration_changed(function(data) --TODO: we are not checking changed cargo capacities - find_and_add_all_stations(global) + --find_and_add_all_stations(global) register_events() end) diff --git a/cybersyn/settings.lua b/cybersyn/settings.lua index 8de42a3..be2a1c9 100644 --- a/cybersyn/settings.lua +++ b/cybersyn/settings.lua @@ -1,4 +1,4 @@ ---By cybersyn +--By Mami data:extend({ { type = "int-setting", @@ -11,7 +11,7 @@ data:extend({ }, { type = "int-setting", - name = "cybersyn-requester-threshold", + name = "cybersyn-request-threshold", order = "ab", setting_type = "runtime-global", default_value = 1000000000, @@ -20,7 +20,7 @@ data:extend({ }, { type = "int-setting", - name = "cybersyn-provider-threshold", + name = "cybersyn-provide-threshold", order = "ac", setting_type = "runtime-global", default_value = 1000000000, From b29efea3ea11303b21fa8e42b1ebc99ca06c5823 Mon Sep 17 00:00:00 2001 From: Monica Moniot Date: Tue, 25 Oct 2022 12:10:01 -0400 Subject: [PATCH 2/5] added alerts --- cybersyn/data.lua | 4 +++ cybersyn/locale/en/base.cfg | 5 +++ cybersyn/prototypes/misc.lua | 24 +++++++++++++++ cybersyn/scripts/alerts.lua | 38 +++++++++++++++++++++++ cybersyn/scripts/constants.lua | 4 +++ cybersyn/scripts/controller.lua | 23 +++++++------- cybersyn/scripts/main.lua | 54 ++++++++++++++++++--------------- 7 files changed, 116 insertions(+), 36 deletions(-) create mode 100644 cybersyn/prototypes/misc.lua create mode 100644 cybersyn/scripts/alerts.lua diff --git a/cybersyn/data.lua b/cybersyn/data.lua index 3cc2b38..7b95676 100644 --- a/cybersyn/data.lua +++ b/cybersyn/data.lua @@ -6,6 +6,7 @@ require('prototypes.item') require('prototypes.tech') require('prototypes.entity') require('prototypes.signal') +require('prototypes.misc') data:extend({ combinator_entity, @@ -18,4 +19,7 @@ data:extend({ p_threshold_signal, r_threshold_signal, locked_slots_signal, + missing_train_icon, + lost_train_icon, + nonempty_train_icon, }) diff --git a/cybersyn/locale/en/base.cfg b/cybersyn/locale/en/base.cfg index 27d1aff..503d985 100644 --- a/cybersyn/locale/en/base.cfg +++ b/cybersyn/locale/en/base.cfg @@ -33,3 +33,8 @@ cybersyn-priority=Station priority cybersyn-provide-threshold=Provide threshold cybersyn-request-threshold=Request threshold cybersyn-locked-slots=Locked slots per cargo wagon + +[cybersyn-messages] +missing-trains=No trains available to make a delivery from station __2__ to station __1__ +lost-train=A train has become lost +nonempty-train=A train has parked in a depot while still containing items; it cannot be dispatched until it is empty diff --git a/cybersyn/prototypes/misc.lua b/cybersyn/prototypes/misc.lua new file mode 100644 index 0000000..65309b9 --- /dev/null +++ b/cybersyn/prototypes/misc.lua @@ -0,0 +1,24 @@ + +missing_train_icon = flib.copy_prototype(data.raw["fluid"]["water"], MISSING_TRAIN_NAME) +missing_train_icon.icon = "__cybersyn__/graphics/icons/missing-train.png" +missing_train_icon.icon_size = 64 +missing_train_icon.icon_mipmaps = 0 +missing_train_icon.hidden = true +missing_train_icon.auto_barrel = false +missing_train_icon.subgroup = "cybersyn-signal" + +lost_train_icon = flib.copy_prototype(data.raw["fluid"]["water"], LOST_TRAIN_NAME) +lost_train_icon.icon = "__cybersyn__/graphics/icons/lost-train.png" +lost_train_icon.icon_size = 64 +lost_train_icon.icon_mipmaps = 0 +lost_train_icon.hidden = true +lost_train_icon.auto_barrel = false +lost_train_icon.subgroup = "cybersyn-signal" + +nonempty_train_icon = flib.copy_prototype(data.raw["fluid"]["water"], NONEMPTY_TRAIN_NAME) +nonempty_train_icon.icon = "__cybersyn__/graphics/icons/nonempty-train.png" +nonempty_train_icon.icon_size = 64 +nonempty_train_icon.icon_mipmaps = 0 +nonempty_train_icon.hidden = true +nonempty_train_icon.auto_barrel = false +nonempty_train_icon.subgroup = "cybersyn-signal" diff --git a/cybersyn/scripts/alerts.lua b/cybersyn/scripts/alerts.lua new file mode 100644 index 0000000..2f90450 --- /dev/null +++ b/cybersyn/scripts/alerts.lua @@ -0,0 +1,38 @@ +--By Mami + +local send_missing_train_alert_for_stop_icon = {name = MISSING_TRAIN_NAME, type = "fluid"} +function send_missing_train_alert_for_stops(r_stop, p_stop) + for _, player in pairs(r_stop.force.players) do + player.add_custom_alert( + r_stop, + send_missing_train_alert_for_stop_icon, + {"cybersyn-messages.missing-trains", r_stop.backer_name, p_stop.backer_name}, + true + ) + end +end + +local send_lost_train_alert_icon = {name = LOST_TRAIN_NAME, type = "fluid"} +function send_lost_train_alert(train) + for _, player in pairs(train.force.players) do + player.add_custom_alert( + train, + send_lost_train_alert_icon, + {"cybersyn-messages.lost-train"}, + true + ) + end +end + + +local send_nonempty_train_in_depot_alert_icon = {name = NONEMPTY_TRAIN_NAME, type = "fluid"} +function send_nonempty_train_in_depot_alert(train) + for _, player in pairs(train.force.players) do + player.add_custom_alert( + train, + send_nonempty_train_in_depot_alert_icon, + {"cybersyn-messages.nonempty-train"}, + true + ) + end +end diff --git a/cybersyn/scripts/constants.lua b/cybersyn/scripts/constants.lua index 86cd4e2..df8b31b 100644 --- a/cybersyn/scripts/constants.lua +++ b/cybersyn/scripts/constants.lua @@ -1,5 +1,9 @@ --By Mami +MISSING_TRAIN_NAME = "cybersyn-missing-train" +LOST_TRAIN_NAME = "cybersyn-lost-train" +NONEMPTY_TRAIN_NAME = "cybersyn-nonempty-train" + SIGNAL_PRIORITY = "cybersyn-priority" REQUEST_THRESHOLD = "cybersyn-request-threshold" PROVIDE_THRESHOLD = "cybersyn-provide-threshold" diff --git a/cybersyn/scripts/controller.lua b/cybersyn/scripts/controller.lua index cc8fbe9..acf4dc3 100644 --- a/cybersyn/scripts/controller.lua +++ b/cybersyn/scripts/controller.lua @@ -129,7 +129,7 @@ local function get_valid_train(map_data, r_station_id, p_station_id, item_type) local r_station = map_data.stations[r_station_id] local p_station = map_data.stations[p_station_id] - local p_to_r_dist = get_stop_dist(p_station.entity, r_station.entity) + local p_to_r_dist = get_stop_dist(p_station.entity_stop, r_station.entity_stop) if p_to_r_dist == INF then return nil, INF end @@ -147,12 +147,12 @@ local function get_valid_train(map_data, r_station_id, p_station_id, item_type) ((is_fluid and train.fluid_capacity > 0) or (not is_fluid and train.item_slot_capacity > 0)) and station_accepts_layout(r_station, train.layout_id) and station_accepts_layout(p_station, train.layout_id) - and train.entity.station + and train.entity_stop.station then valid_train_exists = true --check if exists valid path --check if path is shortest so we prioritize locality - local d_to_p_dist = get_stop_dist(train.entity.station, p_station.entity) + local d_to_p_dist = get_stop_dist(train.entity.station, p_station.entity_stop) local dist = d_to_p_dist if dist < best_dist then @@ -288,7 +288,7 @@ local function send_train_between(map_data, r_station_id, p_station_id, train, p train.r_station_id = r_station_id train.manifest = manifest - train.entity.schedule = create_manifest_schedule(train.depot_name, p_station.entity, r_station.entity, manifest) + train.entity.schedule = create_manifest_schedule(train.depot_name, p_station.entity_stop, r_station.entity_stop, manifest) set_comb2(map_data, p_station) set_comb2(map_data, r_station) end @@ -308,7 +308,7 @@ function tick(map_data, mod_settings) local all_items = economy.all_items for station_id, station in pairs(stations) do - if station.deliveries_total < station.entity.trains_limit then + if station.deliveries_total < station.entity_stop.trains_limit then station.r_threshold = mod_settings.r_threshold station.p_threshold = mod_settings.p_threshold station.priority = 0 @@ -364,7 +364,7 @@ function tick(map_data, mod_settings) end end - local failed_because_missing_trains_total = 0 + local failed_because_missing_trains = {} --we do not dispatch more than one train per station per tick --psuedo-randomize what item (and what station) to check first so if trains available is low they choose orders psuedo-randomly local start_i = 2*(total_ticks%(#all_items/2)) + 1 @@ -398,13 +398,14 @@ function tick(map_data, mod_settings) highest_prior = prior elseif d < INF then could_have_been_serviced = true + best = j end end end - if best > 0 then + if best_train then send_train_between(map_data, r_station_id, p_stations[best], best_train, item_name, economy) elseif could_have_been_serviced then - failed_because_missing_trains_total = failed_because_missing_trains_total + 1 + send_missing_train_alert_for_stops(stations[r_station_id].entity_stop, p_stations[best].entity_stop) end until #r_stations == 0 else @@ -430,17 +431,17 @@ function tick(map_data, mod_settings) highest_prior = prior elseif d < INF then could_have_been_serviced = true + best = i end end end - if best > 0 then + if best_train then send_train_between(map_data, r_stations[best], p_station_id, best_train, item_name, economy) elseif could_have_been_serviced then - failed_because_missing_trains_total = failed_because_missing_trains_total + 1 + send_missing_train_alert_for_stops(stations[best].entity_stop, p_stations[p_station_id].entity_stop) end until #p_stations == 0 end end end - --TODO: add alert for missing trains end diff --git a/cybersyn/scripts/main.lua b/cybersyn/scripts/main.lua index a1b1315..5dbc2c8 100644 --- a/cybersyn/scripts/main.lua +++ b/cybersyn/scripts/main.lua @@ -58,7 +58,7 @@ local function on_station_broken(map_data, station_id, station) on_failed_delivery(map_data, train) train.entity.schedule = nil remove_train(map_data, train, train_id) - --TODO: mark train as lost in the alerts system + send_lost_train_alert(train.entity) end end end @@ -298,7 +298,7 @@ local function on_station_rename(map_data, stop) --train is attempting delivery to a stop that was renamed local p_station = map_data.stations[train.p_station_id] local r_station = map_data.stations[train.r_station_id] - local schedule = create_manifest_schedule(train.depot_name, p_station.entity, r_station.entity, train.manifest) + local schedule = create_manifest_schedule(train.depot_name, p_station.entity_stop, r_station.entity_stop, train.manifest) schedule.current = train.entity.schedule.current train.entity.schedule = schedule end @@ -321,34 +321,35 @@ end local function on_train_arrives_depot(map_data, train_entity) + local contents = train_entity.get_contents() local train = map_data.trains[train_entity.id] if train then - if train.manifest then - if train.status == STATUS_R_TO_D then - --succeeded delivery - train.p_station_id = 0 - train.r_station_id = 0 - train.manifest = nil - train.depot_name = train_entity.station.backer_name - train.status = STATUS_D - train.entity.schedule = create_depot_schedule(train.depot_name) - map_data.trains_available[train_entity.id] = true - else + if train.manifest and train.status == STATUS_R_TO_D then + --succeeded delivery + train.p_station_id = 0 + train.r_station_id = 0 + train.manifest = nil + train.depot_name = train_entity.station.backer_name + train.status = STATUS_D + map_data.trains_available[train_entity.id] = true + else + if train.manifest then on_failed_delivery(map_data, train) - local contents = train.entity.get_contents() - if next(contents) == nil then - train.depot_name = train_entity.station.backer_name - train.status = STATUS_D - train.entity.schedule = create_depot_schedule(train.depot_name) - map_data.trains_available[train_entity.id] = true - else--train still has cargo - train.entity.schedule = nil - remove_train(map_data, train, train_entity.id) - --TODO: mark train as lost in the alerts system - end + send_lost_train_alert(train.entity) end + train.depot_name = train_entity.station.backer_name + train.status = STATUS_D + map_data.trains_available[train_entity.id] = true end - else + if next(contents) ~= nil then + --train still has cargo + train_entity.schedule = nil + remove_train(map_data, train, train_entity.id) + send_nonempty_train_in_depot_alert(train_entity) + else + train_entity.schedule = create_depot_schedule(train.depot_name) + end + elseif next(contents) == nil then train = { depot_name = train_entity.station.backer_name, status = STATUS_D, @@ -365,6 +366,8 @@ local function on_train_arrives_depot(map_data, train_entity) map_data.trains_available[train_entity.id] = true local schedule = create_depot_schedule(train.depot_name) train_entity.schedule = schedule + else + send_nonempty_train_in_depot_alert(train_entity) end end local function on_train_arrives_buffer(map_data, stop, train) @@ -396,6 +399,7 @@ local function on_train_arrives_buffer(map_data, stop, train) on_failed_delivery(map_data, train) remove_train(map_data, train, train.entity.id) train.entity.schedule = nil + send_lost_train_alert(train.entity) end else --train is lost somehow, probably from player intervention From dd06652c74ddb0c1718fe1cd1c41523b8213b8e5 Mon Sep 17 00:00:00 2001 From: Monica Moniot Date: Tue, 25 Oct 2022 13:20:17 -0400 Subject: [PATCH 3/5] added type annotations --- cybersyn/scripts/alerts.lua | 38 +++++++----- cybersyn/scripts/controller.lua | 92 +++++++++++++++++++--------- cybersyn/scripts/global.lua | 104 +++++++++++++++----------------- cybersyn/scripts/layout.lua | 27 +++++++-- cybersyn/scripts/main.lua | 55 +++++++++++++++-- 5 files changed, 210 insertions(+), 106 deletions(-) diff --git a/cybersyn/scripts/alerts.lua b/cybersyn/scripts/alerts.lua index 2f90450..81cca79 100644 --- a/cybersyn/scripts/alerts.lua +++ b/cybersyn/scripts/alerts.lua @@ -1,6 +1,8 @@ --By Mami local send_missing_train_alert_for_stop_icon = {name = MISSING_TRAIN_NAME, type = "fluid"} +---@param r_stop LuaEntity +---@param p_stop LuaEntity function send_missing_train_alert_for_stops(r_stop, p_stop) for _, player in pairs(r_stop.force.players) do player.add_custom_alert( @@ -13,26 +15,34 @@ function send_missing_train_alert_for_stops(r_stop, p_stop) end local send_lost_train_alert_icon = {name = LOST_TRAIN_NAME, type = "fluid"} +---@param train LuaTrain function send_lost_train_alert(train) - for _, player in pairs(train.force.players) do - player.add_custom_alert( - train, - send_lost_train_alert_icon, - {"cybersyn-messages.lost-train"}, - true - ) + local loco = train.front_stock or train.back_stock + if loco then + for _, player in pairs(loco.force.players) do + player.add_custom_alert( + loco, + send_lost_train_alert_icon, + {"cybersyn-messages.lost-train"}, + true + ) + end end end local send_nonempty_train_in_depot_alert_icon = {name = NONEMPTY_TRAIN_NAME, type = "fluid"} +---@param train LuaTrain function send_nonempty_train_in_depot_alert(train) - for _, player in pairs(train.force.players) do - player.add_custom_alert( - train, - send_nonempty_train_in_depot_alert_icon, - {"cybersyn-messages.nonempty-train"}, - true - ) + local loco = train.front_stock or train.back_stock + if loco then + for _, player in pairs(loco.force.players) do + player.add_custom_alert( + loco, + send_nonempty_train_in_depot_alert_icon, + {"cybersyn-messages.nonempty-train"}, + true + ) + end end end diff --git a/cybersyn/scripts/controller.lua b/cybersyn/scripts/controller.lua index acf4dc3..20c6303 100644 --- a/cybersyn/scripts/controller.lua +++ b/cybersyn/scripts/controller.lua @@ -4,6 +4,8 @@ local math = math local INF = math.huge local create_loading_order_condition = {type = "inactivity", compare_type = "and", ticks = 120} +---@param stop LuaEntity +---@param manifest Manifest function create_loading_order(stop, manifest) local condition = {} for _, item in ipairs(manifest) do @@ -25,24 +27,32 @@ function create_loading_order(stop, manifest) end local create_unloading_order_condition = {{type = "empty", compare_type = "and"}} +---@param stop LuaEntity function create_unloading_order(stop) return {station = stop.backer_name, wait_conditions = create_unloading_order_condition} end local create_inactivity_order_condition = {{type = "inactivity", compare_type = "and", ticks = 120}} +---@param depot_name string function create_inactivity_order(depot_name) return {station = depot_name, wait_conditions = create_inactivity_order_condition} end local create_direct_to_station_order_condition = {{type = "time", compare_type = "and", ticks = 0}} +---@param stop LuaEntity local function create_direct_to_station_order(stop) return {rail = stop.connected_rail, rail_direction = stop.connected_rail_direction} end +---@param depot_name string function create_depot_schedule(depot_name) return {current = 1, records = {create_inactivity_order(depot_name)}} end +---@param depot_name string +---@param p_stop LuaEntity +---@param r_stop LuaEntity +---@param manifest Manifest function create_manifest_schedule(depot_name, p_stop, r_stop, manifest) return {current = 1, records = { create_inactivity_order(depot_name), @@ -53,16 +63,19 @@ function create_manifest_schedule(depot_name, p_stop, r_stop, manifest) }} end - +---@param station Station local function get_signals(station) - if station.comb1.valid then - local signals = station.comb1.get_merged_signals(defines.circuit_connector_id.combinator_input) + if station.entity_comb1.valid then + local signals = station.entity_comb1.get_merged_signals(defines.circuit_connector_id.combinator_input) return signals else return nil end end +---@param map_data MapData +---@param comb LuaEntity +---@param signals ConstantCombinatorParameters[]? function set_combinator_output(map_data, comb, signals) if comb.valid then local out = map_data.to_output[comb.unit_number] @@ -76,8 +89,10 @@ function set_combinator_output(map_data, comb, signals) end end +---@param map_data MapData +---@param station Station local function set_comb2(map_data, station) - if station.comb2 then + if station.entity_comb2 then local deliveries = station.deliveries local signals = {} for item_name, count in pairs(deliveries) do @@ -85,10 +100,13 @@ local function set_comb2(map_data, station) local item_type = game.item_prototypes[item_name].type signals[i] = {index = i, signal = {type = item_type, name = item_name}, count = count} end - set_combinator_output(map_data, station.comb2, signals) + set_combinator_output(map_data, station.entity_comb2, signals) end end +---@param map_data MapData +---@param station Station +---@param manifest Manifest function remove_manifest(map_data, station, manifest, sign) local deliveries = station.deliveries for i, item in ipairs(manifest) do @@ -101,8 +119,11 @@ function remove_manifest(map_data, station, manifest, sign) station.deliveries_total = station.deliveries_total - 1 end +---@param map_data MapData +---@param station Station +---@param signal SignalID local function get_thresholds(map_data, station, signal) - local comb2 = station.comb2 + local comb2 = station.entity_comb2 if comb2 and comb2.valid then local count = comb2.get_merged_signal(signal, defines.circuit_connector_id.combinator_input) if count > 0 then @@ -114,16 +135,25 @@ local function get_thresholds(map_data, station, signal) return station.r_threshold, station.p_threshold end +---@param stop0 LuaEntity +---@param stop1 LuaEntity local function get_stop_dist(stop0, stop1) return get_distance(stop0.position, stop1.position) end +---@param station Station +---@param layout_id uint local function station_accepts_layout(station, layout_id) return true end + +---@param map_data MapData +---@param r_station_id uint +---@param p_station_id uint +---@param item_type string local function get_valid_train(map_data, r_station_id, p_station_id, item_type) --NOTE: this code is the critical section for run-time optimization local r_station = map_data.stations[r_station_id] @@ -147,7 +177,7 @@ local function get_valid_train(map_data, r_station_id, p_station_id, item_type) ((is_fluid and train.fluid_capacity > 0) or (not is_fluid and train.item_slot_capacity > 0)) and station_accepts_layout(r_station, train.layout_id) and station_accepts_layout(p_station, train.layout_id) - and train.entity_stop.station + and train.entity.station then valid_train_exists = true --check if exists valid path @@ -170,6 +200,12 @@ local function get_valid_train(map_data, r_station_id, p_station_id, item_type) end +---@param map_data MapData +---@param r_station_id uint +---@param p_station_id uint +---@param train Train +---@param primary_item_name string +---@param economy Economy local function send_train_between(map_data, r_station_id, p_station_id, train, primary_item_name, economy) local r_station = map_data.stations[r_station_id] local p_station = map_data.stations[p_station_id] @@ -185,7 +221,7 @@ local function send_train_between(map_data, r_station_id, p_station_id, train, p local item_type = v.signal.type if item_name and item_type and item_type ~= "virtual" then local effective_item_count = item_count + (r_station.deliveries[item_name] or 0) - local r_threshold, p_threshold = get_thresholds(map_data, r_station, v) + local r_threshold, p_threshold = get_thresholds(map_data, r_station, v.signal) if -effective_item_count >= r_threshold then requests[item_name] = -effective_item_count end @@ -201,7 +237,7 @@ local function send_train_between(map_data, r_station_id, p_station_id, train, p local item_type = v.signal.type if item_name and item_type and item_type ~= "virtual" then local effective_item_count = item_count + (p_station.deliveries[item_name] or 0) - local r_threshold, p_threshold = get_thresholds(map_data, r_station, v) + local r_threshold, p_threshold = get_thresholds(map_data, r_station, v.signal) if effective_item_count >= p_threshold then local r = requests[item_name] if r then @@ -293,7 +329,7 @@ local function send_train_between(map_data, r_station_id, p_station_id, train, p set_comb2(map_data, r_station) end - +---@param map_data MapData function tick(map_data, mod_settings) local total_ticks = map_data.total_ticks local stations = map_data.stations @@ -340,24 +376,26 @@ function tick(map_data, mod_settings) local item_name = v.signal.name local item_count = v.count local effective_item_count = item_count + (station.deliveries[item_name] or 0) - local r_threshold, p_threshold = get_thresholds(map_data, station, v) - - if -effective_item_count >= r_threshold then - if r_stations_all[item_name] == nil then - r_stations_all[item_name] = {} - p_stations_all[item_name] = {} - all_items[#all_items + 1] = item_name - all_items[#all_items + 1] = v.signal.type + local r_threshold, p_threshold = get_thresholds(map_data, station, v.signal) + + if item_name then + if -effective_item_count >= r_threshold then + if r_stations_all[item_name] == nil then + r_stations_all[item_name] = {} + p_stations_all[item_name] = {} + all_items[#all_items + 1] = item_name + all_items[#all_items + 1] = v.signal.type + end + table.insert(r_stations_all[item_name], station_id) + elseif effective_item_count >= p_threshold then + if r_stations_all[item_name] == nil then + r_stations_all[item_name] = {} + p_stations_all[item_name] = {} + all_items[#all_items + 1] = item_name + all_items[#all_items + 1] = v.signal.type + end + table.insert(p_stations_all[item_name], station_id) end - table.insert(r_stations_all[item_name], station_id) - elseif effective_item_count >= p_threshold then - if r_stations_all[item_name] == nil then - r_stations_all[item_name] = {} - p_stations_all[item_name] = {} - all_items[#all_items + 1] = item_name - all_items[#all_items + 1] = v.signal.type - end - table.insert(p_stations_all[item_name], station_id) end end end diff --git a/cybersyn/scripts/global.lua b/cybersyn/scripts/global.lua index 5404611..d7429e2 100644 --- a/cybersyn/scripts/global.lua +++ b/cybersyn/scripts/global.lua @@ -1,60 +1,54 @@ --By Mami +---@class MapData +---@field public total_ticks uint +---@field public layout_top_id uint +---@field public to_output {[uint]: LuaEntity} +---@field public to_stop {[uint]: LuaEntity} +---@field public stations {[uint]: Station} +---@field public depots {[uint]: LuaEntity} +---@field public trains {[uint]: Train} +---@field public trains_available {[uint]: boolean} +---@field public layouts {[uint]: string} +---@field public layout_train_count {[uint]: int} +---@field public train_classes {[string]: TrainClass} + +---@class Station +---@field public deliveries_total int +---@field public priority int +---@field public last_delivery_tick int +---@field public r_threshold int >= 0 +---@field public p_threshold int >= 0 +---@field public locked_slots int >= 0 +---@field public entity_stop LuaEntity +---@field public entity_comb1 LuaEntity +---@field public entity_comb2 LuaEntity? +---@field public wagon_combs {[int]: LuaEntity}?--allowed to be invalid entities +---@field public deliveries {[string]: int} +---@field public train_class string +---@field public accepted_layouts TrainClass +---@field public layout_pattern string? + +---@class Train +---@field public entity LuaTrain +---@field public layout_id uint +---@field public item_slot_capacity int +---@field public fluid_capacity int +---@field public depot_name string +---@field public status int +---@field public p_station_id uint +---@field public r_station_id uint +---@field public manifest Manifest + +---@alias Manifest {}[] +---@alias TrainClass {[uint]: boolean} +---@alias cybersyn.global MapData + +---@class Economy +---@field public r_stations_all {[string]: uint[]} +---@field public p_stations_all {[string]: uint[]} +---@field public all_items string[] +---@field public total_ticks uint ---[[ -global: { - total_ticks: int - layout_top_id: int - to_output: {[comb_unit_number]: LuaEntity} - to_stop: {[comb_unit_number]: LuaEntity} - stations: {[stop_id]: Station} - depots: {[stop_id]: LuaEntity} - trains: {[train_id]: Train} - trains_available: {[train_id]: bool} - layouts: {[layout_id]: Layout} - layout_train_count: {[layout_id]: int} - train_classes: {[string]: TrainClass} -} -Station: { - deliveries_total: int - priority: int - last_delivery_tick: int - r_threshold: int >= 0 - p_threshold: int >= 0 - locked_slots: int >= 0 - entity_stop: LuaEntity - entity_comb1: LuaEntity - entity_comb2: LuaEntity? - wagon_combs: {[int]: LuaEntity}--allowed to be invalid entities - deliveries: { - [item_name]: int - } - deliveries: { - [item_name]: item-type - } - train_class: string - accepted_layouts: TrainClass - layout_pattern: string|nil -} -Train: { - entity: LuaEntity - layout_id: int - item_slot_capacity: int - fluid_capacity: int - depot_name: string - status: int - p_station_id: stop_id - r_station_id: stop_id - manifest: [{ - name: string - type: string - count: int - }] -} -TrainClass: { - [layout_id]: bool -} -Layout: string -]] --TODO: only init once mod_settings = {} mod_settings.tps = settings.global["cybersyn-ticks-per-second"].value diff --git a/cybersyn/scripts/layout.lua b/cybersyn/scripts/layout.lua index 30403d7..b3d7a2a 100644 --- a/cybersyn/scripts/layout.lua +++ b/cybersyn/scripts/layout.lua @@ -1,6 +1,9 @@ --By Mami local area = require("__flib__.area") +---@param map_data MapData +---@param train Train +---@param train_id uint function remove_train(map_data, train, train_id) map_data.trains[train_id] = nil map_data.trains_available[train_id] = nil @@ -18,6 +21,8 @@ function remove_train(map_data, train, train_id) end end +---@param map_data MapData +---@param train Train function update_train_layout(map_data, train) local carriages = train.entity.carriages local layout = "" @@ -68,17 +73,18 @@ function update_train_layout(map_data, train) train.fluid_capacity = fluid_capacity end +---@param map_data MapData +---@param station Station local function reset_station_layout(map_data, station) - --station.entity - local station_rail = station.entity.connected_rail + local station_rail = station.entity_stop.connected_rail local rail_direction_from_station - if station.entity.connected_rail_direction == defines.rail_direction.front then + if station.entity_stop.connected_rail_direction == defines.rail_direction.front then rail_direction_from_station = defines.rail_direction.back else rail_direction_from_station = defines.rail_direction.front end - local station_direction = station.entity.direction - local surface = station.entity.surface + local station_direction = station.entity_stop.direction + local surface = station.entity_stop.surface local middle_x = station_rail.position.x local middle_y = station_rail.position.y local reach = LONGEST_INSERTER_REACH + 1 - DELTA @@ -167,6 +173,9 @@ local function reset_station_layout(map_data, station) end end +---@param map_data MapData +---@param station Station +---@param train_class_name string function set_station_train_class(map_data, station, train_class_name) if train_class_name == TRAIN_CLASS_AUTO then if station.train_class ~= TRAIN_CLASS_AUTO then @@ -182,12 +191,16 @@ function set_station_train_class(map_data, station, train_class_name) end end +---@param map_data MapData +---@param station Station function update_station_if_auto(map_data, station) if station.train_class == TRAIN_CLASS_AUTO then reset_station_layout(map_data, station) end end +---@param map_data MapData +---@param rail LuaEntity function update_station_from_rail(map_data, rail) --TODO: search further? local entity = rail.get_rail_segment_entity(nil, false) @@ -195,11 +208,15 @@ function update_station_from_rail(map_data, rail) update_station_if_auto(map_data, map_data.stations[entity.unit_number]) end end +---@param map_data MapData +---@param pump LuaEntity function update_station_from_pump(map_data, pump) if pump.pump_rail_target then update_station_from_rail(map_data, pump.pump_rail_target) end end +---@param map_data MapData +---@param inserter LuaEntity function update_station_from_inserter(map_data, inserter) --TODO: check if correct local surface = inserter.surface diff --git a/cybersyn/scripts/main.lua b/cybersyn/scripts/main.lua index 5dbc2c8..7e717be 100644 --- a/cybersyn/scripts/main.lua +++ b/cybersyn/scripts/main.lua @@ -1,5 +1,7 @@ --By Mami +---@param map_data MapData +---@param train Train local function on_failed_delivery(map_data, train) --NOTE: must change train status to STATUS_D or remove it from tracked trains after this call local is_p_delivery_made = train.status ~= STATUS_D_TO_P and train.status ~= STATUS_P @@ -7,7 +9,7 @@ local function on_failed_delivery(map_data, train) local station = map_data.stations[train.p_station_id] remove_manifest(map_data, station, train.manifest, 1) if train.status == STATUS_P then - set_combinator_output(map_data, station.comb1, nil) + set_combinator_output(map_data, station.entity_comb1, nil) end end local is_r_delivery_made = train.status == STATUS_R_TO_D @@ -15,7 +17,7 @@ local function on_failed_delivery(map_data, train) local station = map_data.stations[train.r_station_id] remove_manifest(map_data, station, train.manifest, -1) if train.status == STATUS_R then - set_combinator_output(map_data, station.comb1, nil) + set_combinator_output(map_data, station.entity_comb1, nil) end end train.r_station_id = 0 @@ -23,6 +25,10 @@ local function on_failed_delivery(map_data, train) train.manifest = nil end +---@param map_data MapData +---@param stop LuaEntity +---@param comb1 LuaEntity +---@param comb2 LuaEntity local function on_station_built(map_data, stop, comb1, comb2) local station = { entity_stop = stop, @@ -44,6 +50,9 @@ local function on_station_built(map_data, stop, comb1, comb2) update_station_if_auto(map_data, station) end +---@param map_data MapData +---@param station_id uint +---@param station Station local function on_station_broken(map_data, station_id, station) if station.deliveries_total > 0 then --search for trains coming to the destroyed station @@ -66,6 +75,10 @@ local function on_station_broken(map_data, station_id, station) map_data.stations[station_id] = nil end +---@param map_data MapData +---@param stop LuaEntity +---@param comb_operation string +---@param comb_forbidden LuaEntity? local function search_for_station_combinator(map_data, stop, comb_operation, comb_forbidden) local pos_x = stop.position.x local pos_y = stop.position.y @@ -88,6 +101,8 @@ local function search_for_station_combinator(map_data, stop, comb_operation, com end end +---@param map_data MapData +---@param comb LuaEntity local function on_combinator_built(map_data, comb) local pos_x = comb.position.x local pos_y = comb.position.y @@ -116,6 +131,7 @@ local function on_combinator_built(map_data, comb) position = comb.position, force = comb.force }) + assert(out) comb.connect_neighbour({ target_entity = out, source_wire_id = defines.circuit_connector_id.combinator_output, @@ -190,6 +206,8 @@ local function on_combinator_built(map_data, comb) end end end +---@param map_data MapData +---@param comb LuaEntity local function on_combinator_broken(map_data, comb) local out = map_data.to_output[comb.unit_number] local stop = map_data.to_stop[comb.unit_number] @@ -223,12 +241,16 @@ local function on_combinator_broken(map_data, comb) map_data.to_output[comb.unit_number] = nil map_data.to_stop[comb.unit_number] = nil end +---@param map_data MapData +---@param comb LuaEntity local function on_combinator_updated(map_data, comb) --NOTE: this is the lazy way to implement updates and is not robust on_combinator_broken(map_data, comb) on_combinator_built(map_data, comb) end +---@param map_data MapData +---@param stop LuaEntity local function on_stop_built(map_data, stop) local pos_x = stop.position.x local pos_y = stop.position.y @@ -261,6 +283,8 @@ local function on_stop_built(map_data, stop) map_data.depots[stop.unit_number] = depot_comb end end +---@param map_data MapData +---@param stop LuaEntity local function on_stop_broken(map_data, stop) local pos_x = stop.position.x local pos_y = stop.position.y @@ -283,6 +307,8 @@ local function on_stop_broken(map_data, stop) end map_data.depots[stop.unit_number] = nil end +---@param map_data MapData +---@param stop LuaEntity local function on_station_rename(map_data, stop) --search for trains coming to the renamed station local station_id = stop.unit_number @@ -308,6 +334,7 @@ local function on_station_rename(map_data, stop) end +---@param map_data MapData local function find_and_add_all_stations_from_nothing(map_data) for _, surface in pairs(game.surfaces) do local entities = surface.find_entities_filtered({name = COMBINATOR_NAME}) @@ -320,6 +347,8 @@ local function find_and_add_all_stations_from_nothing(map_data) end +---@param map_data MapData +---@param train_entity LuaTrain local function on_train_arrives_depot(map_data, train_entity) local contents = train_entity.get_contents() local train = map_data.trains[train_entity.id] @@ -370,6 +399,9 @@ local function on_train_arrives_depot(map_data, train_entity) send_nonempty_train_in_depot_alert(train_entity) end end +---@param map_data MapData +---@param stop LuaEntity +---@param train Train local function on_train_arrives_buffer(map_data, stop, train) local station_id = stop.unit_number if train.manifest then @@ -383,6 +415,11 @@ local function on_train_arrives_buffer(map_data, stop, train) signals[i] = {index = i, signal = {type = item.type, name = item.name}, count = item.count} end set_combinator_output(map_data, station.comb1, signals) + if station.wagon_combs then + for i, entity in ipairs(station.wagon_combs) do + + end + end end elseif train.status == STATUS_P_TO_R then if train.r_station_id == station_id then @@ -406,22 +443,27 @@ local function on_train_arrives_buffer(map_data, stop, train) remove_train(map_data, train, train.entity.id) end end +---@param map_data MapData +---@param train Train local function on_train_leaves_station(map_data, train) if train.manifest then if train.status == STATUS_P then train.status = STATUS_P_TO_R local station = map_data.stations[train.p_station_id] remove_manifest(map_data, station, train.manifest, 1) - set_combinator_output(map_data, station.comb1, nil) + set_combinator_output(map_data, station.entity_comb1, nil) elseif train.status == STATUS_R then train.status = STATUS_R_TO_D local station = map_data.stations[train.r_station_id] remove_manifest(map_data, station, train.manifest, -1) - set_combinator_output(map_data, station.comb1, nil) + set_combinator_output(map_data, station.entity_comb1, nil) end end end + +---@param map_data MapData +---@param train Train local function on_train_broken(map_data, train) if train.manifest then on_failed_delivery(map_data, train) @@ -431,6 +473,9 @@ local function on_train_broken(map_data, train) end end end +---@param map_data MapData +---@param pre_train_id uint +---@param train_entity LuaEntity local function on_train_modified(map_data, pre_train_id, train_entity) local train = map_data.trains[pre_train_id] if train then @@ -528,7 +573,7 @@ local function on_surface_removed(event) local train_stops = surface.find_entities_filtered({type = "train-stop"}) for _, entity in pairs(train_stops) do if entity.name == "train-stop" then - on_station_broken(global, entity) + on_stop_broken(global, entity) end end end From 7e502cf4f77b340683535e7283f46b602c269b41 Mon Sep 17 00:00:00 2001 From: Monica Moniot Date: Wed, 26 Oct 2022 15:53:33 -0400 Subject: [PATCH 4/5] fixed automatic train layout detection --- .../{locked_slots.png => locked-slots.png} | Bin cybersyn/graphics/icons/lost-train.png | Bin 0 -> 2532 bytes cybersyn/graphics/icons/missing-train.png | Bin 0 -> 2532 bytes cybersyn/graphics/icons/nonempty-train.png | Bin 0 -> 2532 bytes cybersyn/prototypes/signal.lua | 2 +- cybersyn/scripts/constants.lua | 11 +- cybersyn/scripts/controller.lua | 3 +- cybersyn/scripts/global.lua | 5 +- cybersyn/scripts/layout.lua | 161 ++++++++++++------ cybersyn/scripts/main.lua | 77 ++++----- 10 files changed, 157 insertions(+), 102 deletions(-) rename cybersyn/graphics/icons/{locked_slots.png => locked-slots.png} (100%) create mode 100644 cybersyn/graphics/icons/lost-train.png create mode 100644 cybersyn/graphics/icons/missing-train.png create mode 100644 cybersyn/graphics/icons/nonempty-train.png diff --git a/cybersyn/graphics/icons/locked_slots.png b/cybersyn/graphics/icons/locked-slots.png similarity index 100% rename from cybersyn/graphics/icons/locked_slots.png rename to cybersyn/graphics/icons/locked-slots.png diff --git a/cybersyn/graphics/icons/lost-train.png b/cybersyn/graphics/icons/lost-train.png new file mode 100644 index 0000000000000000000000000000000000000000..3f4233236012a0c3d07b99909145f407a013676f GIT binary patch literal 2532 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 r_threshold then if r_stations_all[item_name] == nil then diff --git a/cybersyn/scripts/global.lua b/cybersyn/scripts/global.lua index d7429e2..449030a 100644 --- a/cybersyn/scripts/global.lua +++ b/cybersyn/scripts/global.lua @@ -22,9 +22,9 @@ ---@field public entity_stop LuaEntity ---@field public entity_comb1 LuaEntity ---@field public entity_comb2 LuaEntity? ----@field public wagon_combs {[int]: LuaEntity}?--allowed to be invalid entities +---@field public wagon_combs {[int]: LuaEntity}?--NOTE: allowed to be invalid entities or combinators with the wrong operation, these must be checked and lazy deleted when found ---@field public deliveries {[string]: int} ----@field public train_class string +---@field public train_class SignalID? ---@field public accepted_layouts TrainClass ---@field public layout_pattern string? @@ -57,6 +57,7 @@ mod_settings.p_threshold = settings.global["cybersyn-provide-threshold"].value global.total_ticks = 0 global.to_output = {} +global.to_stop = {} global.stations = {} global.depots = {} global.trains = {} diff --git a/cybersyn/scripts/layout.lua b/cybersyn/scripts/layout.lua index b3d7a2a..ecc5cc5 100644 --- a/cybersyn/scripts/layout.lua +++ b/cybersyn/scripts/layout.lua @@ -75,8 +75,16 @@ end ---@param map_data MapData ---@param station Station -local function reset_station_layout(map_data, station) +---@param forbidden_entity LuaEntity? +local function reset_station_layout(map_data, station, forbidden_entity) + --NOTE: station must be in auto mode local station_rail = station.entity_stop.connected_rail + if station_rail == nil then + --cannot accept deliveries + station.layout_pattern = "X" + station.accepted_layouts = {} + return + end local rail_direction_from_station if station.entity_stop.connected_rail_direction == defines.rail_direction.front then rail_direction_from_station = defines.rail_direction.back @@ -87,26 +95,32 @@ local function reset_station_layout(map_data, station) local surface = station.entity_stop.surface local middle_x = station_rail.position.x local middle_y = station_rail.position.y - local reach = LONGEST_INSERTER_REACH + 1 - DELTA + local reach = LONGEST_INSERTER_REACH + 1 local search_area local area_delta local direction_filter + local is_ver + --local center_line if station_direction == defines.direction.north then - search_area = {left_top = {x = middle_x - reach, y = middle_y}, right_bottom = {x = middle_x + reach, y = middle_y - 6}} - area_delta = {x = 0, y = -7} - direction_filter = {defines.direction.east, defines.direction.west} - elseif station_direction == defines.direction.east then - search_area = {left_top = {y = middle_y - reach, x = middle_x}, right_bottom = {y = middle_y + reach, x = middle_x - 6}} - area_delta = {y = 0, x = -7} - direction_filter = {defines.direction.north, defines.direction.south} - elseif station_direction == defines.direction.south then - search_area = {left_top = {x = middle_x - reach, y = middle_y + 6}, right_bottom = {x = middle_x + reach, y = middle_y}} + search_area = {left_top = {x = middle_x - reach, y = middle_y}, right_bottom = {x = middle_x + reach, y = middle_y + 6}} area_delta = {x = 0, y = 7} direction_filter = {defines.direction.east, defines.direction.west} + is_ver = true + elseif station_direction == defines.direction.east then + search_area = {left_top = {y = middle_y - reach, x = middle_x}, right_bottom = {y = middle_y + reach, x = middle_x - 6}} + area_delta = {x = -7, y = 0} + direction_filter = {defines.direction.north, defines.direction.south} + is_ver = false + elseif station_direction == defines.direction.south then + search_area = {left_top = {x = middle_x - reach, y = middle_y - 6}, right_bottom = {x = middle_x + reach, y = middle_y}} + area_delta = {x = 0, y = -7} + direction_filter = {defines.direction.east, defines.direction.west} + is_ver = true elseif station_direction == defines.direction.west then search_area = {left_top = {y = middle_y - reach, x = middle_x + 6}, right_bottom = {y = middle_y + reach, x = middle_x}} - area_delta = {y = 0, x = 7} + area_delta = {x = 7, y = 0} direction_filter = {defines.direction.north, defines.direction.south} + is_ver = false else assert(false, "cybersyn: invalid station direction") end @@ -114,14 +128,17 @@ local function reset_station_layout(map_data, station) local pre_rail = station_rail local layout_pattern = "^" local layout_min_size = 10000 - local type_filter = {"inserter", "pump"} + local type_filter = {"inserter", "pump", "arithmetic-combinator"} + local wagon_number = 0 for i = 1, 100 do local rail, rail_direction, rail_connection_direction = pre_rail.get_connected_rail({rail_direction = rail_direction_from_station, rail_connection_direction = defines.rail_connection_direction.straight}) - if rail_connection_direction ~= defines.rail_connection_direction.straight or not rail.valid then + if not rail or rail_connection_direction ~= defines.rail_connection_direction.straight or not rail.valid then break end + pre_rail = rail length = length + 2 if length%7 <= 1 then + wagon_number = wagon_number + 1 local supports_cargo = false local supports_fluid = false local entities = surface.find_entities_filtered({ @@ -130,26 +147,64 @@ local function reset_station_layout(map_data, station) direction = direction_filter, }) for _, entity in pairs(entities) do - if entity.type == "inserter" then - --local pickup_pos = entity.prototype.inserter_pickup_position + entity.position - --local drop_pos = entity.prototype.inserter_drop_position + entity.position - --TODO: add further checks - supports_cargo = true - elseif entity.type == "pump" then - if entity.pump_rail_target then - supports_fluid = true + if entity.valid and entity ~= forbidden_entity then + if entity.type == "inserter" then + if not supports_cargo then + local pos = entity.pickup_position + local is_there + if is_ver then + is_there = middle_x - 1 <= pos.x and pos.x <= middle_x + 1 + else + is_there = middle_y - 1 <= pos.y and pos.y <= middle_y + 1 + end + if is_there then + supports_cargo = true + else + pos = entity.drop_position + if is_ver then + is_there = middle_x - 1 <= pos.x and pos.x <= middle_x + 1 + else + is_there = middle_y - 1 <= pos.y and pos.y <= middle_y + 1 + end + if is_there then + supports_cargo = true + end + end + end + elseif entity.type == "pump" then + if not supports_fluid and entity.pump_rail_target then + supports_fluid = true + end + elseif entity.name == COMBINATOR_NAME then + local control = entity.get_or_create_control_behavior().parameters + if control.operation == OPERATION_WAGON_MANIFEST then + local pos = entity.position + local is_there + if is_ver then + is_there = middle_x - 2.1 <= pos.x and pos.x <= middle_x + 2.1 + else + is_there = middle_y - 2.1 <= pos.y and pos.y <= middle_y + 2.1 + end + if is_there then + if not station.wagon_combs then + station.wagon_combs = {} + end + station.wagon_combs[wagon_number] = entity + end + end end end end if supports_cargo then if supports_fluid then - layout_pattern = layout_pattern..STATION_LAYOUT_BOTH + layout_pattern = layout_pattern..STATION_LAYOUT_ALL else - layout_pattern = layout_pattern..STATION_LAYOUT_CARGO + --TODO: needs to allow misc wagons as well + layout_pattern = layout_pattern..STATION_LAYOUT_NOT_FLUID end elseif supports_fluid then - layout_pattern = layout_pattern..STATION_LAYOUT_FLUID + layout_pattern = layout_pattern..STATION_LAYOUT_NOT_CARGO else layout_pattern = layout_pattern..STATION_LAYOUT_NA end @@ -175,17 +230,17 @@ end ---@param map_data MapData ---@param station Station ----@param train_class_name string -function set_station_train_class(map_data, station, train_class_name) - if train_class_name == TRAIN_CLASS_AUTO then - if station.train_class ~= TRAIN_CLASS_AUTO then +---@param train_class SignalID +function set_station_train_class(map_data, station, train_class) + if train_class.name == TRAIN_CLASS_AUTO.name then + if station.train_class.name ~= TRAIN_CLASS_AUTO.name then station.train_class = TRAIN_CLASS_AUTO station.accepted_layouts = {} end - reset_station_layout(map_data, station) + reset_station_layout(map_data, station, nil) else - station.train_class = train_class_name - station.accepted_layouts = map_data.train_classes[train_class_name] + station.train_class = train_class + station.accepted_layouts = map_data.train_classes[train_class.name] assert(station.accepted_layouts ~= nil) station.layout_pattern = nil end @@ -193,26 +248,39 @@ end ---@param map_data MapData ---@param station Station -function update_station_if_auto(map_data, station) - if station.train_class == TRAIN_CLASS_AUTO then - reset_station_layout(map_data, station) +---@param forbidden_entity LuaEntity? +function update_station_if_auto(map_data, station, forbidden_entity) + if station.train_class.name == TRAIN_CLASS_AUTO.name then + reset_station_layout(map_data, station, forbidden_entity) end end ---@param map_data MapData ---@param rail LuaEntity -function update_station_from_rail(map_data, rail) - --TODO: search further? - local entity = rail.get_rail_segment_entity(nil, false) - if entity.name == BUFFER_STATION_NAME then - update_station_if_auto(map_data, map_data.stations[entity.unit_number]) +---@param forbidden_entity LuaEntity +function update_station_from_rail(map_data, rail, forbidden_entity) + --TODO: search further or better? + local entity = rail.get_rail_segment_entity(defines.rail_direction.back, false) + if entity and entity.valid and entity.name == "train-stop" then + local station = map_data.stations[entity.unit_number] + if station then + update_station_if_auto(map_data, station, forbidden_entity) + end + else + entity = rail.get_rail_segment_entity(defines.rail_direction.front, false) + if entity and entity.valid and entity.name == "train-stop" then + local station = map_data.stations[entity.unit_number] + if station then + update_station_if_auto(map_data, station, forbidden_entity) + end + end end end ---@param map_data MapData ---@param pump LuaEntity function update_station_from_pump(map_data, pump) if pump.pump_rail_target then - update_station_from_rail(map_data, pump.pump_rail_target) + update_station_from_rail(map_data, pump.pump_rail_target, pump) end end ---@param map_data MapData @@ -220,16 +288,13 @@ end function update_station_from_inserter(map_data, inserter) --TODO: check if correct local surface = inserter.surface - local pos = inserter.position - local pickup_pos = inserter.prototype.inserter_pickup_position - local drop_pos = inserter.prototype.inserter_drop_position - local rail = surface.find_entity("straight-rail", {pos.x + pickup_pos.x, pos.y + pickup_pos.y}) + local rail = surface.find_entity("straight-rail", inserter.pickup_position) if rail then - update_station_from_rail(map_data, rail) + update_station_from_rail(map_data, rail, inserter) end - rail = surface.find_entity("straight-rail", {pos.x + drop_pos.x, pos.y + drop_pos.y}) + rail = surface.find_entity("straight-rail", inserter.drop_position) if rail then - update_station_from_rail(map_data, rail) + update_station_from_rail(map_data, rail, inserter) end end diff --git a/cybersyn/scripts/main.lua b/cybersyn/scripts/main.lua index 7e717be..e311246 100644 --- a/cybersyn/scripts/main.lua +++ b/cybersyn/scripts/main.lua @@ -48,7 +48,7 @@ local function on_station_built(map_data, stop, comb1, comb2) } map_data.stations[stop.unit_number] = station - update_station_if_auto(map_data, station) + update_station_if_auto(map_data, station, nil) end ---@param map_data MapData ---@param station_id uint @@ -84,8 +84,8 @@ local function search_for_station_combinator(map_data, stop, comb_operation, com local pos_y = stop.position.y --TODO: fix search area local search_area = { - {pos_x + DELTA - 1, pos_y + DELTA - 1}, - {pos_x - DELTA + 1, pos_y - DELTA + 1} + {pos_x - 2, pos_y - 2}, + {pos_x + 2, pos_y + 2} } local entities = stop.surface.find_entities(search_area) for _, entity in pairs(entities) do @@ -108,13 +108,21 @@ local function on_combinator_built(map_data, comb) local pos_y = comb.position.y --TODO: fix search area - local search_area = { - {pos_x + DELTA - 1, pos_y + DELTA - 1}, - {pos_x - DELTA + 1, pos_y - DELTA + 1} - } + local search_area + if comb.direction == defines.direction.north or comb.direction == defines.direction.south then + search_area = { + {pos_x - 1.5, pos_y - 2}, + {pos_x + 1.5, pos_y + 2} + } + else + search_area = { + {pos_x - 2, pos_y - 1.5}, + {pos_x + 2, pos_y + 1.5} + } + end local stop = nil local rail = nil - local entities = stop.surface.find_entities(search_area) + local entities = comb.surface.find_entities(search_area) for _, cur_entity in pairs(entities) do if cur_entity.valid then if cur_entity.name == "train-stop" then @@ -131,15 +139,15 @@ local function on_combinator_built(map_data, comb) position = comb.position, force = comb.force }) - assert(out) + assert(out, "cybersyn: could not spawn combinator controller") comb.connect_neighbour({ target_entity = out, - source_wire_id = defines.circuit_connector_id.combinator_output, + source_circuit_id = defines.circuit_connector_id.combinator_output, wire = defines.wire_type.green, }) comb.connect_neighbour({ target_entity = out, - source_wire_id = defines.circuit_connector_id.combinator_output, + source_circuit_id = defines.circuit_connector_id.combinator_output, wire = defines.wire_type.red, }) @@ -149,7 +157,7 @@ local function on_combinator_built(map_data, comb) local control = comb.get_or_create_control_behavior().parameters if control.operation == OPERATION_WAGON_MANIFEST then if rail then - update_station_from_rail(map_data, rail) + update_station_from_rail(map_data, rail, nil) end elseif control.operation == OPERATION_DEPOT then if stop then @@ -182,49 +190,32 @@ local function on_combinator_built(map_data, comb) --no station or depot --add station - local comb2 = search_for_station_combinator(map_data, stop, OPERATION_SECONDARY_IO, nil) + local comb2 = search_for_station_combinator(map_data, stop, OPERATION_SECONDARY_IO, comb) - station = { - entity_stop = stop, - entity_comb1 = comb, - entity_comb2 = comb2, - wagon_combs = nil, - deliveries_total = 0, - last_delivery_tick = 0, - priority = 0, - r_threshold = 0, - p_threshold = 0, - locked_slots = 0, - deliveries = {}, - train_class = TRAIN_CLASS_AUTO, - accepted_layouts = {}, - layout_pattern = nil, - } - map_data.stations[stop.unit_number] = station - - update_station_if_auto(map_data, station) + on_station_built(map_data, stop, comb, comb2) end end end ---@param map_data MapData ---@param comb LuaEntity local function on_combinator_broken(map_data, comb) + --NOTE: we do not check for wagon manifest combinators and update their stations, it is assumed they will be lazy deleted later local out = map_data.to_output[comb.unit_number] local stop = map_data.to_stop[comb.unit_number] if stop and stop.valid then local station = map_data.stations[stop.unit_number] if station then - if station.comb1 == comb then + if station.entity_comb1 == comb then local comb1 = search_for_station_combinator(map_data, stop, OPERATION_PRIMARY_IO, comb) if comb1 then - station.comb1 = comb1 + station.entity_comb1 = comb1 else on_station_broken(map_data, stop.unit_number, station) map_data.depots[stop.unit_number] = search_for_station_combinator(map_data, stop, OPERATION_DEPOT, nil) end - elseif station.comb2 == comb then - station.comb2 = search_for_station_combinator(map_data, stop, OPERATION_SECONDARY_IO, comb) + elseif station.entity_comb2 == comb then + station.entity_comb2 = search_for_station_combinator(map_data, stop, OPERATION_SECONDARY_IO, comb) end else local depot_comb = map_data.depots[stop.unit_number] @@ -244,7 +235,7 @@ end ---@param map_data MapData ---@param comb LuaEntity local function on_combinator_updated(map_data, comb) - --NOTE: this is the lazy way to implement updates and is not robust + --NOTE: this is the lazy way to implement updates and puts strong restrictions on data validity on on_combinator_broken on_combinator_broken(map_data, comb) on_combinator_built(map_data, comb) end @@ -257,8 +248,8 @@ local function on_stop_built(map_data, stop) --TODO: fix search area local search_area = { - {pos_x + DELTA - 1, pos_y + DELTA - 1}, - {pos_x - DELTA + 1, pos_y - DELTA + 1} + {pos_x - 2, pos_y - 2}, + {pos_x + 2, pos_y + 2} } local comb2 = nil local comb1 = nil @@ -291,8 +282,8 @@ local function on_stop_broken(map_data, stop) --TODO: fix search area local search_area = { - {pos_x + DELTA - 1, pos_y + DELTA - 1}, - {pos_x - DELTA + 1, pos_y - DELTA + 1} + {pos_x - 2, pos_y - 2}, + {pos_x + 2, pos_y + 2} } local entities = stop.surface.find_entities(search_area) for _, entity in pairs(entities) do @@ -509,7 +500,7 @@ local function on_built(event) elseif entity.type == "pump" then update_station_from_pump(global, entity) elseif entity.type == "straight-rail" then - update_station_from_rail(global, entity) + update_station_from_rail(global, entity, nil) end end local function on_broken(event) @@ -530,7 +521,7 @@ local function on_broken(event) elseif entity.type == "pump" then update_station_from_pump(global, entity) elseif entity.type == "straight-rail" then - update_station_from_rail(global, entity) + update_station_from_rail(global, entity, nil) end end local function on_rename(event) From b80e85eb41b98c602e08f110f750ed2596151825 Mon Sep 17 00:00:00 2001 From: Monica Moniot Date: Wed, 26 Oct 2022 20:51:23 -0400 Subject: [PATCH 5/5] got gui to work --- cybersyn/control.lua | 1 + cybersyn/locale/en/base.cfg | 8 +++ cybersyn/scripts/gui.lua | 98 +++++++++++++++++++++++++++++++++++++ cybersyn/scripts/layout.lua | 25 +++++----- cybersyn/scripts/main.lua | 10 ++-- 5 files changed, 125 insertions(+), 17 deletions(-) create mode 100644 cybersyn/scripts/gui.lua diff --git a/cybersyn/control.lua b/cybersyn/control.lua index 6b7facc..ed1cfee 100644 --- a/cybersyn/control.lua +++ b/cybersyn/control.lua @@ -4,4 +4,5 @@ require("scripts.constants") require("scripts.global") require("scripts.controller") require("scripts.layout") +require("scripts.gui") require("scripts.main") diff --git a/cybersyn/locale/en/base.cfg b/cybersyn/locale/en/base.cfg index 503d985..e432a4d 100644 --- a/cybersyn/locale/en/base.cfg +++ b/cybersyn/locale/en/base.cfg @@ -38,3 +38,11 @@ cybersyn-locked-slots=Locked slots per cargo wagon missing-trains=No trains available to make a delivery from station __2__ to station __1__ lost-train=A train has become lost nonempty-train=A train has parked in a depot while still containing items; it cannot be dispatched until it is empty + +[cybersyn-gui] +operation=Choose combinator type +comb1=Primary controller +comb2=Secondary station control +depot=Depot +wagon-manifest=Wagon +combinator-title=Cybernetic combinator diff --git a/cybersyn/scripts/gui.lua b/cybersyn/scripts/gui.lua new file mode 100644 index 0000000..9c3c493 --- /dev/null +++ b/cybersyn/scripts/gui.lua @@ -0,0 +1,98 @@ +--By Mami +local gui = require("__flib__.gui") + +local RED = "utility/status_not_working" +local GREEN = "utility/status_working" +local YELLOW = "utility/status_yellow" + +local STATUS_SPRITES = {} +STATUS_SPRITES[defines.entity_status.working] = GREEN +STATUS_SPRITES[defines.entity_status.normal] = GREEN +STATUS_SPRITES[defines.entity_status.no_power] = RED +STATUS_SPRITES[defines.entity_status.low_power] = YELLOW +STATUS_SPRITES[defines.entity_status.disabled_by_control_behavior] = RED +STATUS_SPRITES[defines.entity_status.disabled_by_script] = RED +STATUS_SPRITES[defines.entity_status.marked_for_deconstruction] = RED +local STATUS_SPRITES_DEFAULT = RED + +local STATUS_NAMES = {} +STATUS_NAMES[defines.entity_status.working] = "entity-status.working" +STATUS_NAMES[defines.entity_status.normal] = "entity-status.normal" +STATUS_NAMES[defines.entity_status.no_power] = "entity-status.no-power" +STATUS_NAMES[defines.entity_status.low_power] = "entity-status.low-power" +STATUS_NAMES[defines.entity_status.disabled_by_control_behavior] = "entity-status.disabled" +STATUS_NAMES[defines.entity_status.disabled_by_script] = "entity-status.disabled-by-script" +STATUS_NAMES[defines.entity_status.marked_for_deconstruction] = "entity-status.marked-for-deconstruction" +STATUS_NAMES_DEFAULT = "entity-status.disabled" + +---@param entity LuaEntity +function gui_opened(entity, player) + local rootgui = player.gui.screen + local window = gui.build(rootgui, { + {type="frame", direction="vertical", ref={"main_window"}, name=COMBINATOR_NAME, tags={unit_number=entity.unit_number}, actions={ + on_close = {"test"} + }, children={ + --title bar + {type="flow", ref={"titlebar"}, children={ + {type="label", style="frame_title", caption={"cybersyn-gui.combinator-title"}, elem_mods={ignored_by_interaction=true}}, + {type="empty-widget", style="flib_titlebar_drag_handle", elem_mods={ignored_by_interaction=true}}, + {type="sprite-button", style="frame_action_button", mouse_button_filter={"left"}, sprite="utility/close_white", hovered_sprite="utility/close_black", name=COMBINATOR_NAME, actions={ + on_click = {"test"} + }} + }}, + {type="frame", style="inside_shallow_frame_with_padding", style_mods={padding=8}, children={ + {type="flow", direction="vertical", style_mods={horizontal_align="left"}, children={ + --status + {type="flow", style = "status_flow", direction = "horizontal", style_mods={vertical_align="center", horizontally_stretchable=true}, children={ + {type="sprite", sprite=STATUS_SPRITES[entity.status] or STATUS_SPRITES_DEFAULT, style="status_image", ref={"status_icon"}, style_mods={stretch_image_to_widget_size=true}}, + {type="label", caption={STATUS_NAMES[entity.status] or STATUS_NAMES_DEFAULT}, ref={"status_label"}} + }}, + --preview + {type="frame", style="deep_frame_in_shallow_frame", style_mods={minimal_width=0, horizontally_stretchable=true, padding=0}, children={ + {type="entity-preview", style="wide_entity_button", ref={"preview"}}, + }}, + {type="label", caption={"cybersyn-gui.operation"}, style_mods={top_padding=8}}, + {type="drop-down", ref={"operation"}, actions={ + on_selection_state_changed = {"test"} + }, items={ + {"cybersyn-gui.comb1"}, + {"cybersyn-gui.comb2"}, + {"cybersyn-gui.depot"}, + {"cybersyn-gui.wagon-manifest"}, + }}, + }} + }} + }} + }) + + window.preview.entity = entity + window.titlebar.drag_target = window.main_window + window.main_window.force_auto_center() + + player.opened = window.main_window +end + +local function o(event) + local entity = event.entity + if not entity or not entity.valid then return end + local player = game.get_player(event.player_index) + if not player then return end + local rootgui = player.gui.screen + + if rootgui[COMBINATOR_NAME] then + --rootgui[COMBINATOR_NAME].destroy() + else + gui_opened(entity, player) + end +end + +function register_gui_actions() + gui.hook_events(function(event) + local msg = gui.read_action(event) + if msg then + -- read the action to determine what to do + local hi = 2 + end + end) + script.on_event(defines.events.on_gui_opened, o) +end diff --git a/cybersyn/scripts/layout.lua b/cybersyn/scripts/layout.lua index ecc5cc5..5dafdfa 100644 --- a/cybersyn/scripts/layout.lua +++ b/cybersyn/scripts/layout.lua @@ -127,9 +127,9 @@ local function reset_station_layout(map_data, station, forbidden_entity) local length = 2 local pre_rail = station_rail local layout_pattern = "^" - local layout_min_size = 10000 local type_filter = {"inserter", "pump", "arithmetic-combinator"} local wagon_number = 0 + local pattern_length = 1 for i = 1, 100 do local rail, rail_direction, rail_connection_direction = pre_rail.get_connected_rail({rail_direction = rail_direction_from_station, rail_connection_direction = defines.rail_connection_direction.straight}) if not rail or rail_connection_direction ~= defines.rail_connection_direction.straight or not rail.valid then @@ -203,20 +203,17 @@ local function reset_station_layout(map_data, station, forbidden_entity) --TODO: needs to allow misc wagons as well layout_pattern = layout_pattern..STATION_LAYOUT_NOT_FLUID end + pattern_length = #layout_pattern elseif supports_fluid then layout_pattern = layout_pattern..STATION_LAYOUT_NOT_CARGO + pattern_length = #layout_pattern else layout_pattern = layout_pattern..STATION_LAYOUT_NA end - if layout_min_size <= 0 then - layout_pattern = layout_pattern.."?" - else - layout_min_size = layout_min_size - 1 - end search_area = area.move(search_area, area_delta) end end - layout_pattern = layout_pattern..STATION_LAYOUT_NA.."*$" + layout_pattern = string.sub(layout_pattern, 1, pattern_length)..STATION_LAYOUT_NA.."*$" station.layout_pattern = layout_pattern local accepted_layouts = station.accepted_layouts for id, layout in pairs(map_data.layouts) do @@ -257,7 +254,7 @@ end ---@param map_data MapData ---@param rail LuaEntity ----@param forbidden_entity LuaEntity +---@param forbidden_entity LuaEntity? function update_station_from_rail(map_data, rail, forbidden_entity) --TODO: search further or better? local entity = rail.get_rail_segment_entity(defines.rail_direction.back, false) @@ -278,23 +275,25 @@ function update_station_from_rail(map_data, rail, forbidden_entity) end ---@param map_data MapData ---@param pump LuaEntity -function update_station_from_pump(map_data, pump) +---@param forbidden_entity LuaEntity? +function update_station_from_pump(map_data, pump, forbidden_entity) if pump.pump_rail_target then - update_station_from_rail(map_data, pump.pump_rail_target, pump) + update_station_from_rail(map_data, pump.pump_rail_target, forbidden_entity) end end ---@param map_data MapData ---@param inserter LuaEntity -function update_station_from_inserter(map_data, inserter) +---@param forbidden_entity LuaEntity? +function update_station_from_inserter(map_data, inserter, forbidden_entity) --TODO: check if correct local surface = inserter.surface local rail = surface.find_entity("straight-rail", inserter.pickup_position) if rail then - update_station_from_rail(map_data, rail, inserter) + update_station_from_rail(map_data, rail, forbidden_entity) end rail = surface.find_entity("straight-rail", inserter.drop_position) if rail then - update_station_from_rail(map_data, rail, inserter) + update_station_from_rail(map_data, rail, forbidden_entity) end end diff --git a/cybersyn/scripts/main.lua b/cybersyn/scripts/main.lua index e311246..2d69b9b 100644 --- a/cybersyn/scripts/main.lua +++ b/cybersyn/scripts/main.lua @@ -128,7 +128,7 @@ local function on_combinator_built(map_data, comb) if cur_entity.name == "train-stop" then --NOTE: if there are multiple stops we take the later one stop = cur_entity - elseif cur_entity.name == "rail-straight" then + elseif cur_entity.name == "straight-rail" then rail = cur_entity end end @@ -500,7 +500,7 @@ local function on_built(event) elseif entity.type == "pump" then update_station_from_pump(global, entity) elseif entity.type == "straight-rail" then - update_station_from_rail(global, entity, nil) + update_station_from_rail(global, entity) end end local function on_broken(event) @@ -517,9 +517,9 @@ local function on_broken(event) elseif entity.name == COMBINATOR_NAME then on_combinator_broken(global, entity) elseif entity.type == "inserter" then - update_station_from_inserter(global, entity) + update_station_from_inserter(global, entity, entity) elseif entity.type == "pump" then - update_station_from_pump(global, entity) + update_station_from_pump(global, entity, entity) elseif entity.type == "straight-rail" then update_station_from_rail(global, entity, nil) end @@ -607,6 +607,8 @@ local function register_events() script.on_event(defines.events.on_train_changed_state, on_train_changed) script.on_event(defines.events.on_entity_renamed, on_rename) + + register_gui_actions() end script.on_load(function()