Repository navigation
Expand file tree
/
Copy pathcontrol.lua
More file actions
324 lines (282 loc) · 11.7 KB
/
Copy pathcontrol.lua
File metadata and controls
324 lines (282 loc) · 11.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
local island_link_pole = require("scripts.island-link-pole")
-- ============================================
-- XP SYSTEM CONFIGURATION
-- ============================================
-- XP rates for different items (how much XP per craft)
local XP_RATES = {
-- Basic materials
["iron-plate"] = 1,
["copper-plate"] = 1,
["stone-brick"] = 2,
["steel-plate"] = 5,
-- Components
["iron-gear-wheel"] = 2,
["copper-cable"] = 1,
["iron-stick"] = 1,
["electronic-circuit"] = 5,
["advanced-circuit"] = 15,
["processing-unit"] = 50,
-- Intermediates
["engine-unit"] = 10,
["electric-engine-unit"] = 20,
["flying-robot-frame"] = 30,
-- LavaBlock specific
["lava-science-pack"] = 20,
["foundation-platform-nauvis"] = 10,
["foundation-catalyst"] = 5,
}
-- How much XP needed for 1 XP Science Pack
local XP_PER_PACK = 100
-- ============================================
-- XP SYSTEM FUNCTIONS
-- ============================================
-- Add XP to a force and distribute XP packs if threshold reached
local function add_xp_to_force(force, xp_amount, triggering_player)
if not force or xp_amount <= 0 then return end
local force_name = force.name
storage.force_xp[force_name] = (storage.force_xp[force_name] or 0) + xp_amount
local total_xp = storage.force_xp[force_name]
local packs_earned = math.floor(total_xp / XP_PER_PACK)
if packs_earned > 0 then
storage.force_xp[force_name] = total_xp % XP_PER_PACK
-- Give packs to the triggering player (or first player in force)
local recipient = triggering_player
if not recipient or not recipient.valid then
for _, player in pairs(force.players) do
if player.valid then
recipient = player
break
end
end
end
if recipient and recipient.valid then
recipient.insert({ name = "xp-science-pack", count = packs_earned })
recipient.create_local_flying_text({
text = { "", "+", packs_earned, " [img=item/xp-science-pack]" },
position = recipient.position,
color = { r = 0.7, g = 0.3, b = 1.0 }
})
end
end
end
-- ============================================
-- HELPER FUNCTIONS
-- ============================================
-- Check if player is wearing lava-mech-armor
local function is_wearing_lava_mech_armor(player)
if not player.character then return false end
local armor_inventory = player.get_inventory(defines.inventory.character_armor)
if not armor_inventory or armor_inventory.is_empty() then return false end
local armor = armor_inventory[1]
return armor and armor.valid and armor.name == "lava-mech-armor"
end
-- Update player speed based on armor
local function update_player_speed(player)
if not player or not player.character then return end
if is_wearing_lava_mech_armor(player) then
-- 80% slower, a fifth of walking speed. 0.2.1 announced 80% but this
-- line stayed at 90% until 0.3.2.
player.character_running_speed_modifier = -0.8
else
player.character_running_speed_modifier = 0
end
end
-- Helper function to disable freeplay crashsite and intro
local function disable_freeplay()
if remote.interfaces["freeplay"] then
remote.call("freeplay", "set_disable_crashsite", true)
remote.call("freeplay", "set_skip_intro", true)
remote.call("freeplay", "set_created_items", {})
remote.call("freeplay", "set_respawn_items", {})
end
end
-- Helper function to give starting items to a player
local function give_starting_items(player)
-- The 2 gears + 3 pipes are exactly one offshore pump (vanilla 2.0 recipe:
-- 2 iron-gear-wheel + 3 pipe). on_init researches steam-power, which unlocks
-- the offshore-pump recipe at tick 0, so the opening move is:
-- craft pump -> place on lava -> feed the chemical plant.
--
-- Two chemical plants, because lava extraction takes eight seconds a run:
-- one plant alone has to take turns at ore, coal and steam at 0.63 a
-- second until Steel processing unlocks the chemical plant.
--
-- Power budget for that first setup:
-- 2 chemical-plant 420 kW + offshore-pump 60 kW = 480 kW
-- solar-panel 60 kW each (Nauvis solar-power = 100)
-- Without a buffer the whole factory stops every night. 10 panels cover
-- the 480 kW draw in daylight; 5 accumulators (5 MJ each) carry it
-- through dusk and dawn, as 3 did for a single plant.
player.insert({ name = "chemical-plant", count = 2 })
player.insert({ name = "solar-panel", count = 10 })
player.insert({ name = "accumulator", count = 5 })
player.insert({ name = "small-electric-pole", count = 4 })
player.insert({ name = "iron-gear-wheel", count = 2 })
player.insert({ name = "pipe", count = 3 })
-- Equip lava-mech-armor if setting is enabled and item exists
if settings.global["lava-block-mech-armor-start"].value and prototypes.item["lava-mech-armor"] then
player.insert({ name = "lava-mech-armor", count = 1 })
end
-- Display helpful hints
player.print({ "lava-block.on-start-mechanics-explanation-1" })
player.print({ "lava-block.on-start-mechanics-explanation-2" })
player.print({ "lava-block.on-start-mechanics-explanation-3" })
end
-- Disable a recipe for a specific force
local function disable_recipe_for_force(force, recipe_name)
local recipes = force.recipes
if recipes[recipe_name] then
recipes[recipe_name].enabled = false
game.print({ "lava-block.recipe-disabled", {"recipe-name." .. recipe_name} })
end
end
-- Mark a technology researched for every force that has it
local function research_for_all_forces(tech_name)
for _, force in pairs(game.forces) do
local tech = force.technologies[tech_name]
if tech then
tech.researched = true
end
end
end
-- Get technology effects (handles both LuaTechnology and LuaTechnologyPrototype)
local function get_tech_effects(technology)
if technology.object_name == "LuaTechnology" then
return technology.prototype.effects
end
return technology.effects
end
-- Initialize game on first load
script.on_init(function()
storage.players_needing_items = {}
storage.force_xp = {}
-- Disable crashsite and intro FIRST
disable_freeplay()
-- Research steam power for all forces
research_for_all_forces("steam-power")
-- Create 25x25 landfill area at spawn
local surface = game.get_surface("nauvis")
if surface then
local tiles = {}
for x = -12, 12 do
for y = -12, 12 do
table.insert(tiles, { name = "landfill", position = { x, y } })
end
end
surface.set_tiles(tiles)
end
island_link_pole.rescan()
end)
-- Handle mod updates on existing saves
script.on_configuration_changed(function(data)
storage.players_needing_items = storage.players_needing_items or {}
storage.force_xp = storage.force_xp or {}
disable_freeplay()
island_link_pole.rescan()
-- The armor's slowdown is set on the player when the armor goes on, so a
-- save made while wearing it would keep an old figure until it came off.
-- Only wearers: everyone else's modifier may belong to another mod.
for _, player in pairs(game.players) do
if is_wearing_lava_mech_armor(player) then
update_player_speed(player)
end
end
-- A technology that gained an unlock in an update (Railway now unlocks
-- the condenser coil, Electric energy distribution 1 the island link
-- pole) does not hand it to a force that researched it before. Resetting
-- the effects re-applies every researched technology; the disable pass
-- below then switches off again whatever a "disable-recipe" effect
-- turned off, which the reset would otherwise have turned back on.
for _, force in pairs(game.forces) do
force.reset_technology_effects()
end
-- Re-apply recipe disable for all researched technologies with disable-recipe effects
for _, force in pairs(game.forces) do
for _, tech in pairs(force.technologies) do
local effects = get_tech_effects(tech)
if tech.researched and effects then
for _, effect in pairs(effects) do
if effect.type == "nothing" and effect.effect_description then
local desc = effect.effect_description
if desc[1] == "technology-effect.disable-recipe" then
local recipe_name = desc[2]
-- Silently disable without printing message
if force.recipes[recipe_name] then
force.recipes[recipe_name].enabled = false
end
end
end
end
end
end
end
end)
-- Give starting items when player is created
script.on_event(defines.events.on_player_created, function(event)
storage.players_needing_items[event.player_index] = true
end)
-- Give items when cutscene is cancelled (skip intro)
script.on_event(defines.events.on_cutscene_cancelled, function(event)
if not storage.players_needing_items[event.player_index] then
return
end
local player = game.get_player(event.player_index)
if player then
give_starting_items(player)
end
storage.players_needing_items[event.player_index] = nil
end)
-- Fallback: give items on tick if cutscene was skipped entirely
script.on_event(defines.events.on_tick, function(event)
if not storage.players_needing_items or not next(storage.players_needing_items) then return end
-- Wait for freeplay to finish its setup
if event.tick < 30 then return end
for player_index, _ in pairs(storage.players_needing_items) do
local player = game.get_player(player_index)
if player then
give_starting_items(player)
end
storage.players_needing_items[player_index] = nil
end
end)
-- Handle technology effects (disable-recipe via "nothing" effect type)
script.on_event(defines.events.on_research_finished, function(event)
local force = event.research.force
local effects = get_tech_effects(event.research)
if not effects then return end
for _, effect in pairs(effects) do
if effect.type == "nothing" and effect.effect_description then
local desc = effect.effect_description
if desc[1] == "technology-effect.disable-recipe" then
local recipe_name = desc[2]
disable_recipe_for_force(force, recipe_name)
end
end
end
end)
-- Update speed when armor changes
script.on_event(defines.events.on_player_armor_inventory_changed, function(event)
local player = game.get_player(event.player_index)
update_player_speed(player)
end)
-- Update speed when player respawns
script.on_event(defines.events.on_player_respawned, function(event)
local player = game.get_player(event.player_index)
update_player_speed(player)
end)
-- ============================================
-- XP SYSTEM EVENT HANDLERS
-- ============================================
-- Award XP when player crafts items
script.on_event(defines.events.on_player_crafted_item, function(event)
local player = game.get_player(event.player_index)
if not player or not player.valid then return end
local item = event.item_stack
if not item or not item.valid then return end
local xp_rate = XP_RATES[item.name]
if xp_rate and xp_rate > 0 then
local xp_gained = xp_rate * item.count
add_xp_to_force(player.force, xp_gained, player)
end
end)
island_link_pole.register()