1
0
mirror of https://github.com/ComfyFactory/ComfyFactorio.git synced 2025-01-28 03:57:22 +02:00

Bug fixes and tweaks

Changes:
- It's darker in the cabin and holds now.
- Slightly decreased amount of time you can stay in Maze island.
- Slightly decreased Nightmare difficulty index.
- Slightly increased amount of biters that spawn in Red Desert.
- Biters in Red Desert island now spawn every 5 mins instead of every 6 mins.
- Fixed an issue where some classes like Scout or Samurai would heal themselves when getting splashed by grenades instead of getting damaged.
- Fixed an issue where obstacle boxes in hold could spawn on top of substations.
- Fixed an issue where players could get teleported around for no reason when boat was undocking.
This commit is contained in:
Piratux 2023-02-03 23:24:11 +02:00
parent 087ed90bb2
commit 7e32ea3a77
15 changed files with 279 additions and 225 deletions

View File

@ -237,7 +237,7 @@ class_definition_for=Class definition for
class_deckhand=Deckhand
# class_deckhand_explanation=They move faster and generate ore for the cabin whilst onboard above deck.
class_deckhand_explanation_advanced=They move __1__% times faster and generate ore (+__2__ every __3__ seconds) for the cabin whilst onboard above deck. No ore is generated while at sea.
class_deckhand_explanation_advanced=They move __1__% times faster and generate ore (+__2__ every __3__ seconds) for the cabin whilst onboard above deck.\nNo ore is generated while at sea.
class_fisherman=Fisherman
# class_fisherman_explanation=They fish at greater distance.
class_fisherman_explanation_advanced=They fish at greater distance (__1__ extra tile range), and catch more (+__2__ fish).
@ -255,7 +255,7 @@ class_shoresman=Shoresman
class_shoresman_explanation_advanced=They move __1__% times faster and generate ore (+__2__ every __3__ seconds) for the cabin whilst offboard.
class_boatswain=Boatswain
# class_boatswain_explanation=They move faster and generate ore for the cabin whilst below deck.
class_boatswain_explanation_advanced=They move __1__% times faster and generate ore (+__2__ every __3__ seconds) for the cabin whilst below deck. No ore is generated while at sea.
class_boatswain_explanation_advanced=They move __1__% times faster and generate ore (+__2__ every __3__ seconds) for the cabin whilst below deck.\nNo ore is generated while at sea.
class_prospector=Prospector
# class_prospector_explanation=They find more resources when handmining.
class_prospector_explanation_advanced=They find more resources when handmining.
@ -279,7 +279,7 @@ class_iron_leg=Iron Leg
class_iron_leg_explanation_advanced=They receive __1__% less damage when carrying at least __2__ iron ore.
class_quartermaster=Quartermaster
# class_quartermaster_explanation=Nearby crewmates get +10% physical attack and generate ore for the cabin.
class_quartermaster_explanation_advanced=Nearby crewmates (at __1__ tile radius) get +__2__% physical attack bonus and generate ore for the cabin (ore amount depends on nearby crewmate count). No ore is generated while at sea.
class_quartermaster_explanation_advanced=Nearby crewmates (at __1__ tile radius) get +__2__% physical attack bonus and generate ore for the cabin (ore amount depends on nearby crewmate count).\nNo ore is generated while at sea.
class_dredger=Dredger
# class_dredger_explanation=They find surprising items when they fish.
class_dredger_explanation_advanced=They can grab fish from an insane distance (__1__ extra tile range), and catch more (+__2__ fish). In addition, they find surprising items when fishing.

View File

@ -449,6 +449,7 @@ local function damage_dealt_by_players_changes(event)
if not event.cause.valid then return end
if not event.entity.valid then return end
if event.cause.name ~= 'character' then return end
if event.entity.name == 'character' then return end
local character = event.cause
local player = character.player
@ -459,78 +460,78 @@ local function damage_dealt_by_players_changes(event)
local player_index = player.index
local class = Classes.get_class(player_index)
if class and class == Classes.enum.SCOUT and event.final_health > 0 then --lethal damage must be unaffected
event.entity.health = event.entity.health + (1 - Balance.scout_damage_dealt_multiplier) * event.final_damage_amount
elseif class and (class == Classes.enum.SAMURAI or class == Classes.enum.HATAMOTO) then
local samurai = class == Classes.enum.SAMURAI
local hatamoto = class == Classes.enum.HATAMOTO
-- Lethal damage must be unaffected, otherwise enemy will never die.
-- @Future reference: when implementing damage changes for mobs with healthbar, make this check with healthbar health too
if event.final_health > 0 then
if class and class == Classes.enum.SCOUT then
event.entity.health = event.entity.health + (1 - Balance.scout_damage_dealt_multiplier) * event.final_damage_amount
elseif class and (class == Classes.enum.SAMURAI or class == Classes.enum.HATAMOTO) then
local samurai = class == Classes.enum.SAMURAI
local hatamoto = class == Classes.enum.HATAMOTO
--==Note this! (what the hell is this)
if not (samurai or hatamoto) then return end
local no_weapon = (not (character.get_inventory(defines.inventory.character_guns) and character.get_inventory(defines.inventory.character_guns)[character.selected_gun_index] and character.get_inventory(defines.inventory.character_guns)[character.selected_gun_index].valid_for_read))
local no_weapon = (not (character.get_inventory(defines.inventory.character_guns) and character.get_inventory(defines.inventory.character_guns)[character.selected_gun_index] and character.get_inventory(defines.inventory.character_guns)[character.selected_gun_index].valid_for_read))
local melee = (physical or acid) and no_weapon
local melee = (physical or acid) and no_weapon
local extra_damage_to_deal = 0
local extra_damage_to_deal = 0
local big_number = 1000
local big_number = 1000
local extra_physical_damage_from_research_multiplier = 1 + memory.force.get_ammo_damage_modifier('bullet')
local extra_physical_damage_from_research_multiplier = 1 + memory.force.get_ammo_damage_modifier('bullet')
if melee and event.final_health > 0 then
if physical then
if samurai then
extra_damage_to_deal = Balance.samurai_damage_dealt_with_melee * extra_physical_damage_from_research_multiplier
elseif hatamoto then
extra_damage_to_deal = Balance.hatamoto_damage_dealt_with_melee * extra_physical_damage_from_research_multiplier
if melee then
if physical then
if samurai then
extra_damage_to_deal = Balance.samurai_damage_dealt_with_melee * extra_physical_damage_from_research_multiplier
elseif hatamoto then
extra_damage_to_deal = Balance.hatamoto_damage_dealt_with_melee * extra_physical_damage_from_research_multiplier
end
elseif acid then --this hacky stuff is to implement repeated spillover splash damage, whilst getting around the fact that if ovekill damage takes something to zero health, we can't tell in that event how much double-overkill damage should be dealt by reading off its HP. This code assumes that characters only deal acid damage via this function.
extra_damage_to_deal = event.original_damage_amount * big_number
end
elseif acid then --this hacky stuff is to implement repeated spillover splash damage, whilst getting around the fact that if ovekill damage takes something to zero health, we can't tell in that event how much double-overkill damage should be dealt by reading off its HP. This code assumes that characters only deal acid damage via this function.
extra_damage_to_deal = event.original_damage_amount * big_number
end
elseif (not melee) and event.final_health > 0 then
if samurai then
event.entity.health = event.entity.health + (1 - Balance.samurai_damage_dealt_when_not_melee_multiplier) * event.final_damage_amount
elseif hatamoto then
event.entity.health = event.entity.health + (1 - Balance.hatamoto_damage_dealt_when_not_melee_multiplier) * event.final_damage_amount
end
end
if extra_damage_to_deal > 0 then
if event.entity.health >= extra_damage_to_deal then
event.entity.damage(extra_damage_to_deal, character.force, 'impact', character) --using .damage rather than subtracting from health directly plays better with entities which use healthbars
else
local surplus = (extra_damage_to_deal - event.entity.health)*0.8
event.entity.die(character.force, character)
local nearest = player.surface.find_nearest_enemy{position = player.position, max_distance = 2, force = player.force}
if nearest and nearest.valid then
nearest.damage(surplus/big_number, character.force, 'acid', character)
if samurai then
event.entity.health = event.entity.health + (1 - Balance.samurai_damage_dealt_when_not_melee_multiplier) * event.final_damage_amount
elseif hatamoto then
event.entity.health = event.entity.health + (1 - Balance.hatamoto_damage_dealt_when_not_melee_multiplier) * event.final_damage_amount
end
end
end
end
if physical then
-- QUARTERMASTER BUFFS
local nearby_players = player.surface.find_entities_filtered{position = player.position, radius = Balance.quartermaster_range, type = {'character'}}
for _, p2 in pairs(nearby_players) do
if p2.player and p2.player.valid then
local p2_index = p2.player.index
if event.entity.valid and player_index ~= p2_index and Classes.get_class(p2_index) == Classes.enum.QUARTERMASTER then
event.entity.damage((Balance.quartermaster_bonus_physical_damage - 1) * event.final_damage_amount, character.force, 'impact', character) --triggers this function again, but not physical this time
if extra_damage_to_deal > 0 then
if event.entity.health >= extra_damage_to_deal then
event.entity.damage(extra_damage_to_deal, character.force, 'impact', character) --using .damage rather than subtracting from health directly plays better with entities which use healthbars
else
local surplus = (extra_damage_to_deal - event.entity.health)*0.8
event.entity.die(character.force, character)
local nearest = player.surface.find_nearest_enemy{position = player.position, max_distance = 2, force = player.force}
if nearest and nearest.valid then
nearest.damage(surplus/big_number, character.force, 'acid', character)
end
end
end
end
if physical then
-- PISTOL BUFFS
if character.shooting_state.state ~= defines.shooting.not_shooting then
local weapon = character.get_inventory(defines.inventory.character_guns)[character.selected_gun_index]
local ammo = character.get_inventory(defines.inventory.character_ammo)[character.selected_gun_index]
if event.entity.valid and weapon.valid_for_read and ammo.valid_for_read and weapon.name == 'pistol' and (ammo.name == 'firearm-magazine' or ammo.name == 'piercing-rounds-magazine' or ammo.name == 'uranium-rounds-magazine') then
event.entity.damage(event.final_damage_amount * (Balance.pistol_damage_multiplier() - 1), character.force, 'impact', character) --triggers this function again, but not physical this time
-- QUARTERMASTER BUFFS
local nearby_players = player.surface.find_entities_filtered{position = player.position, radius = Balance.quartermaster_range, type = {'character'}}
for _, p2 in pairs(nearby_players) do
if p2.player and p2.player.valid then
local p2_index = p2.player.index
if event.entity.valid and player_index ~= p2_index and Classes.get_class(p2_index) == Classes.enum.QUARTERMASTER then
event.entity.damage((Balance.quartermaster_bonus_physical_damage - 1) * event.final_damage_amount, character.force, 'impact', character) --triggers this function again, but not physical this time
end
end
end
-- PISTOL BUFFS
if character.shooting_state.state ~= defines.shooting.not_shooting then
local weapon = character.get_inventory(defines.inventory.character_guns)[character.selected_gun_index]
local ammo = character.get_inventory(defines.inventory.character_ammo)[character.selected_gun_index]
if event.entity.valid and weapon.valid_for_read and ammo.valid_for_read and weapon.name == 'pistol' and (ammo.name == 'firearm-magazine' or ammo.name == 'piercing-rounds-magazine' or ammo.name == 'uranium-rounds-magazine') then
event.entity.damage(event.final_damage_amount * (Balance.pistol_damage_multiplier() - 1), character.force, 'impact', character) --triggers this function again, but not physical this time
end
end
end
end

View File

@ -81,6 +81,7 @@ Public.doctor_heal_radius = 20
Public.doctor_heal_percentage_amount = 0.15
Public.shaman_energy_required_per_summon = 1000000
Public.shaman_max_charge = 30000000
Public.shaman_summoned_biter_time_to_live = 60 * 5 -- in seconds
Public.class_cycle_count = 5 -- How many classes should be purchased to have a chance to buy the same class again
@ -206,8 +207,8 @@ function Public.max_time_on_island(island_subtype)
if x == 40 then -- it's important for this island to be somewhat chill, so that it's not such a shock to go here from the first lobby chill island
time = time * 1.2
elseif island_subtype == IslandEnum.enum.MAZE then --more time
time = time * 1.05
-- elseif island_subtype == IslandEnum.enum.MAZE then --more time
-- time = time * 1.05
elseif island_subtype == IslandEnum.enum.CAVE then -- supposed to be chill island
time = time * 0.9
elseif island_subtype == IslandEnum.enum.RED_DESERT then --this island has big amount of resources so rather high risk (need time to mine resources) and high reward (lots of iron/copper/stone)

View File

@ -1215,6 +1215,7 @@ if _DEBUG then
player.insert{name='steel-chest', count = 50}
player.insert{name='express-loader', count = 50}
player.insert{name='burner-inserter', count = 50}
player.insert{name='accumulator', count = 50}
end
end)

View File

@ -123,11 +123,11 @@ Public.difficulty_options = {
--For the value of Easy difficulty, we are pulled in two directions: We wish to make the game comfy to play for those who haven't played it, but we also wish to represent the game mechanics faithfully so that Normal is not a crazy distance away.
{value = 0.5, icon = 'item/firearm-magazine', text = {'pirates.difficulty_easy'}, associated_color = {r = 50, g = 255, b = 50}},
{value = 0.95, icon = 'item/piercing-rounds-magazine', text = {'pirates.difficulty_normal'}, associated_color = {r = 255, g = 255, b = 50}},
{value = 1.0, icon = 'item/piercing-rounds-magazine', text = {'pirates.difficulty_normal'}, associated_color = {r = 255, g = 255, b = 50}},
{value = 1.5, icon = 'item/uranium-rounds-magazine', text = {'pirates.difficutly_hard'}, associated_color = {r = 255, g = 50, b = 50}},
{value = 2.2, icon = 'item/atomic-bomb', text = {'pirates.difficulty_nightmare'}, associated_color = {r = 170, g = 60, b = 60}},
{value = 2.0, icon = 'item/atomic-bomb', text = {'pirates.difficulty_nightmare'}, associated_color = {r = 170, g = 60, b = 60}},
}
function Public.get_difficulty_option_from_value(difficulty_value)
-- given a difficulty value, key in to the closesy entry in the above table. (organising things this way allows us to make changes to the 'value' keys in the above table without disrupting e.g. past highscores data)

View File

@ -718,6 +718,8 @@ function Public.initialise_crew(accepted_proposal)
memory.class_renderings = {}
memory.class_auxiliary_data = {}
memory.pet_biters = {}
memory.hold_surface_count = 1
memory.speed_boost_characters = {}

View File

@ -234,9 +234,9 @@ function Public.generate_destination_base_cost_to_undock(p, subtype)
['uranium-235'] = Math.ceil(Math.ceil(80 + (macro_p.x - 1))),
-- ['uranium-235'] = Math.ceil(Math.ceil(80 + (macro_p.x)/2)), --tried adding beacons instead of this
}
elseif subtype == IslandEnum.enum.RED_DESERT then
elseif subtype == IslandEnum.enum.RED_DESERT or subtype == IslandEnum.enum.CAVE then
if base_cost_to_undock and base_cost_to_undock['launch_rocket'] == true then
base_cost_to_undock['launch_rocket'] = false -- some extra variety
base_cost_to_undock['launch_rocket'] = false
end
end

View File

@ -469,29 +469,37 @@ local function class_on_player_used_capsule(event)
end
end
elseif class == Public.enum.SHAMAN then
local data = memory.class_auxiliary_data[player.index]
if data and data.shaman_charge then
for _ = 1, 3 do
if data.shaman_charge < Balance.shaman_energy_required_per_summon then break end
local player_surface_type = SurfacesCommon.decode_surface_name(player.surface.name).type
local pos = Math.vector_sum(player.position, Math.random_vec(2))
local name = Common.get_random_unit_type(Math.clamp(0, 1, memory.evolution_factor))
if player_surface_type == SurfacesCommon.enum.ISLAND or player_surface_type == SurfacesCommon.enum.SEA then
local data = memory.class_auxiliary_data[player.index]
if data and data.shaman_charge then
for _ = 1, 2 do
if data.shaman_charge < Balance.shaman_energy_required_per_summon then break end
if player.surface.can_place_entity{name = name, position = pos, force = memory.force} then
local e = player.surface.create_entity{name = name, position = pos, force = memory.force}
if e and e.valid then
data.shaman_charge = data.shaman_charge - Balance.shaman_energy_required_per_summon
rendering.draw_text {
text = '~' .. player.name .. "'s minion~",
surface = player.surface,
target = e,
target_offset = {0, -2.6},
color = player.force.color,
scale = 1.05,
font = 'default-large-semibold',
alignment = 'center',
scale_with_zoom = false
}
local spawn_range = 2
local pos = Math.vector_sum(player.position, Math.random_vec(spawn_range))
local name = Common.get_random_unit_type(Math.clamp(0, 1, memory.evolution_factor))
local spawn_pos = player.surface.find_non_colliding_position(name, pos, spawn_range + 1, 0.5)
if spawn_pos then
local e = player.surface.create_entity{name = name, position = spawn_pos, force = memory.force}
if e and e.valid then
data.shaman_charge = data.shaman_charge - Balance.shaman_energy_required_per_summon
rendering.draw_text {
text = '~' .. player.name .. "'s minion~",
surface = player.surface,
target = e,
target_offset = {0, -2.6},
color = player.force.color,
scale = 1.05,
font = 'default-large-semibold',
alignment = 'center',
scale_with_zoom = false
}
memory.pet_biters[e.unit_number] = {pet_owner = player, pet = e, time_to_live = Balance.shaman_summoned_biter_time_to_live}
end
end
end
end

View File

@ -337,11 +337,11 @@ function Public.afk_player_tick(player)
-- local global_memory = Memory.get_global_memory()
local memory = Memory.get_crew_memory()
if Common.is_captain(player) and (not memory.run_is_protected) then
-- in this case, lose captainhood
local non_afk_members = Common.crew_get_nonafk_crew_members()
if #Common.crew_get_nonafk_crew_members() == 1 then --don't need to bounce it around
Public.make_captain(Common.crew_get_nonafk_crew_members()[1])
if Common.is_captain(player) and (not memory.run_is_protected) and #non_afk_members >= 1 then
if #non_afk_members == 1 then --don't need to bounce it around
Public.make_captain(non_afk_members[1])
else
local force = memory.force
if force and force.valid then

View File

@ -849,118 +849,162 @@ local function process_entity_on_boat_unteleportable(memory, boat, newsurface, v
end
end
-- @TODO: Rocket silo that is prepared to launch the rocket needs to be cloned with clone_entities instead. See: https://forums.factorio.com/viewtopic.php?f=23&t=105073&p=580968
local function process_entity_on_boat_teleportable(memory, boat, newsurface, newposition, vector, oldsurface_name, newsurface_name, electric_pole_neighbours_matrix, circuit_neighbours_matrix, e)
if oldsurface_name == newsurface_name then
e.teleport(vector.x, vector.y)
e.update_connections()
else
local p = Utils.deepcopy(e.position)
local p2 = {x = p.x + vector.x, y = p.y + vector.y}
return
end
if e.type == 'electric-pole' then
for k, v in pairs(e.neighbours or {}) do
if k == 'copper' then --red and green cases handled by circuit_neighbours_matrix
if not electric_pole_neighbours_matrix[k] then electric_pole_neighbours_matrix[k] = {} end
for _, v2 in pairs(v) do
if v2 and v2.valid and v2.position then
local v2p = v2.position
if not electric_pole_neighbours_matrix[k][v2p.x] then
electric_pole_neighbours_matrix[k][v2p.x] = {}
end
if not electric_pole_neighbours_matrix[k][v2p.x][v2p.y] then
electric_pole_neighbours_matrix[k][v2p.x][v2p.y] = {}
end
electric_pole_neighbours_matrix[k][v2p.x][v2p.y][#electric_pole_neighbours_matrix[k][v2p.x][v2p.y] + 1] = {name = e.name, pos = p}
local p = Utils.deepcopy(e.position)
local p2 = {x = p.x + vector.x, y = p.y + vector.y}
if e.type == 'electric-pole' then
for k, v in pairs(e.neighbours or {}) do
if k == 'copper' then --red and green cases handled by circuit_neighbours_matrix
if not electric_pole_neighbours_matrix[k] then electric_pole_neighbours_matrix[k] = {} end
for _, v2 in pairs(v) do
if v2 and v2.valid and v2.position then
local v2p = v2.position
if not electric_pole_neighbours_matrix[k][v2p.x] then
electric_pole_neighbours_matrix[k][v2p.x] = {}
end
if not electric_pole_neighbours_matrix[k][v2p.x][v2p.y] then
electric_pole_neighbours_matrix[k][v2p.x][v2p.y] = {}
end
electric_pole_neighbours_matrix[k][v2p.x][v2p.y][#electric_pole_neighbours_matrix[k][v2p.x][v2p.y] + 1] = {name = e.name, pos = p}
end
end
end
end
end
for _, v in pairs(e.circuit_connection_definitions or {}) do
local e2 = v.target_entity
local wire = v.wire
local source_circuit_id = v.source_circuit_id
local target_circuit_id = v.target_circuit_id
if e2 and e2.valid and e2.position and (wire == defines.wire_type.red or wire == defines.wire_type.green) then --observed an error "Expected source_wire_id for entities with more than one wire connection" in the .connect_neighbour() function called later, so putting the red/green wire check in to try and catch it
local e2p = e2.position
if not circuit_neighbours_matrix[e2p.x] then
circuit_neighbours_matrix[e2p.x] = {}
end
if not circuit_neighbours_matrix[e2p.x][e2p.y] then
circuit_neighbours_matrix[e2p.x][e2p.y] = {}
end
circuit_neighbours_matrix[e2p.x][e2p.y][#circuit_neighbours_matrix[e2p.x][e2p.y] + 1] = {name = e.name, pos = p, wire = wire, source_circuit_id = target_circuit_id, target_circuit_id = source_circuit_id} --flip since we will read these backwards
for _, v in pairs(e.circuit_connection_definitions or {}) do
local e2 = v.target_entity
local wire = v.wire
local source_circuit_id = v.source_circuit_id
local target_circuit_id = v.target_circuit_id
if e2 and e2.valid and e2.position and (wire == defines.wire_type.red or wire == defines.wire_type.green) then --observed an error "Expected source_wire_id for entities with more than one wire connection" in the .connect_neighbour() function called later, so putting the red/green wire check in to try and catch it
local e2p = e2.position
if not circuit_neighbours_matrix[e2p.x] then
circuit_neighbours_matrix[e2p.x] = {}
end
end
-- Special case for vehicles, because currently they can be exclusively teleported between surfaces
local ee
if e.name == 'car' or e.name == 'tank' or e.name == 'spidertron' then
e.teleport(p2, newsurface)
else
if string.sub(e.name, 1, 14) ~= 'spidertron-leg' then
ee = e.clone{position = p2, surface = newsurface, create_build_effect_smoke = false}
if not circuit_neighbours_matrix[e2p.x][e2p.y] then
circuit_neighbours_matrix[e2p.x][e2p.y] = {}
end
circuit_neighbours_matrix[e2p.x][e2p.y][#circuit_neighbours_matrix[e2p.x][e2p.y] + 1] = {name = e.name, pos = p, wire = wire, source_circuit_id = target_circuit_id, target_circuit_id = source_circuit_id} --flip since we will read these backwards
end
end
if e == boat.upstairs_pole then
boat.upstairs_pole = ee
if boat.downstairs_poles and boat.downstairs_poles[1] then
-- Remove previous connection, before connecting it with the new clone to avoid sometimes having to remove wire connection because of limit
e.disconnect_neighbour(boat.downstairs_poles[1][1])
Common.force_connect_poles(boat.upstairs_pole, boat.downstairs_poles[1][1])
end
-- Special case for vehicles, because currently they can be exclusively teleported between surfaces
local ee
if e.name == 'car' or e.name == 'tank' or e.name == 'spidertron' then
e.teleport(p2, newsurface)
else
if string.sub(e.name, 1, 14) ~= 'spidertron-leg' then
ee = e.clone{position = p2, surface = newsurface, create_build_effect_smoke = false}
end
end
-- We don't want to destroy spidertron leg, because otherwise it will destroy whole spidertron. Funny huh?
if not (e.name == 'car' or e.name == 'tank' or e.name == 'spidertron' or string.sub(e.name, 1, 14) == 'spidertron-leg') then
e.destroy()
if e == boat.upstairs_pole then
boat.upstairs_pole = ee
if boat.downstairs_poles and boat.downstairs_poles[1] then
-- Remove previous connection, before connecting it with the new clone to avoid sometimes having to remove wire connection because of limit
e.disconnect_neighbour(boat.downstairs_poles[1][1])
Common.force_connect_poles(boat.upstairs_pole, boat.downstairs_poles[1][1])
end
end
-- Right now in the game we don't expect any non-player characters, so let's kill them to make a point:
if ee and ee.valid and ee.name == 'character' and (not ee.player) then
ee.die()
local pet_biter_data = memory.pet_biters[e.unit_number]
if pet_biter_data then
local owner = pet_biter_data.pet_owner
rendering.draw_text {
text = '~' .. owner.name .. "'s minion~",
surface = newsurface,
target = ee,
target_offset = {0, -2.6},
color = owner.force.color,
scale = 1.05,
font = 'default-large-semibold',
alignment = 'center',
scale_with_zoom = false
}
memory.pet_biters[ee.unit_number] = {pet_owner = owner, pet = ee, time_to_live = pet_biter_data.time_to_live}
memory.pet_biters[e.unit_number] = nil
end
-- We don't want to destroy spidertron leg, because otherwise it will destroy whole spidertron. Funny huh?
if not (e.name == 'car' or e.name == 'tank' or e.name == 'spidertron' or string.sub(e.name, 1, 14) == 'spidertron-leg') then
e.destroy()
end
-- Right now in the game we don't expect any non-player characters, so let's kill them to make a point:
if ee and ee.valid and ee.name == 'character' and (not ee.player) then
ee.die()
end
if not (ee and ee.valid and ee.name) then
return
end
if ee.name == 'blue-chest' then
if p2.y < newposition.y then
memory.boat.decksteeringchests.left = ee
-- --attach parrot to this:
-- if boat.parrot then
-- local r = rendering.draw_sprite{
-- sprite = "file/parrot/parrot_idle_fly_1.png",
-- surface = newsurface,
-- target = ee,
-- target_offset = Utils.psum{boat.parrot.position_relative_to_boat, boat.parrot.sprite_extra_offset},
-- x_scale = 2.8,
-- y_scale = 2.8,
-- }
-- local r2 = rendering.draw_text{
-- text = 'Parrot',
-- color = CoreData.colors.parrot,
-- surface = newsurface,
-- target = ee,
-- target_offset = Utils.psum{boat.parrot.position_relative_to_boat, boat.parrot.text_extra_offset},
-- alignment = 'center',
-- }
-- rendering.destroy(boat.parrot.render)
-- rendering.destroy(boat.parrot.render_name)
-- boat.parrot.frame = 1
-- boat.parrot.state = Parrot.enum.FLY
-- boat.parrot.render = r
-- boat.parrot.render_name = r2
-- end
elseif p2.y > newposition.y then
memory.boat.decksteeringchests.right = ee
end
end
if ee and ee.valid and ee.name then
if ee.name == 'blue-chest' then
if p2.y < newposition.y then
memory.boat.decksteeringchests.left = ee
-- --attach parrot to this:
-- if boat.parrot then
-- local r = rendering.draw_sprite{
-- sprite = "file/parrot/parrot_idle_fly_1.png",
-- surface = newsurface,
-- target = ee,
-- target_offset = Utils.psum{boat.parrot.position_relative_to_boat, boat.parrot.sprite_extra_offset},
-- x_scale = 2.8,
-- y_scale = 2.8,
-- }
-- local r2 = rendering.draw_text{
-- text = 'Parrot',
-- color = CoreData.colors.parrot,
-- surface = newsurface,
-- target = ee,
-- target_offset = Utils.psum{boat.parrot.position_relative_to_boat, boat.parrot.text_extra_offset},
-- alignment = 'center',
-- }
-- rendering.destroy(boat.parrot.render)
-- rendering.destroy(boat.parrot.render_name)
-- boat.parrot.frame = 1
-- boat.parrot.state = Parrot.enum.FLY
-- boat.parrot.render = r
-- boat.parrot.render_name = r2
-- end
elseif p2.y > newposition.y then
memory.boat.decksteeringchests.right = ee
if circuit_neighbours_matrix[p.x] and circuit_neighbours_matrix[p.x][p.y] then
for _, v2 in pairs(circuit_neighbours_matrix[p.x][p.y]) do
local p3 = {x = v2.pos.x + vector.x, y = v2.pos.y + vector.y}
local e3s = newsurface.find_entities_filtered{
name = v2.name,
position = p3,
radius = 0.01,
}
if e3s and #e3s>0 then
local e3 = e3s[1]
if e3 and e3.valid then
ee.connect_neighbour{wire = v2.wire, target_entity = e3, source_circuit_id = v2.source_circuit_id, target_circuit_id = v2.target_circuit_id}
end
end
end
end
if circuit_neighbours_matrix[p.x] and circuit_neighbours_matrix[p.x][p.y] then
for _, v2 in pairs(circuit_neighbours_matrix[p.x][p.y]) do
if ee.type == 'electric-pole' then
for k, v in pairs(electric_pole_neighbours_matrix or {}) do
if v[p.x] and v[p.x][p.y] then
for _, v2 in pairs(v[p.x][p.y]) do
local p3 = {x = v2.pos.x + vector.x, y = v2.pos.y + vector.y}
local e3s = newsurface.find_entities_filtered{
name = v2.name,
@ -970,33 +1014,12 @@ local function process_entity_on_boat_teleportable(memory, boat, newsurface, new
if e3s and #e3s>0 then
local e3 = e3s[1]
if e3 and e3.valid then
ee.connect_neighbour{wire = v2.wire, target_entity = e3, source_circuit_id = v2.source_circuit_id, target_circuit_id = v2.target_circuit_id}
end
end
end
end
if ee.type and ee.type == 'electric-pole' then
for k, v in pairs(electric_pole_neighbours_matrix or {}) do
if v[p.x] and v[p.x][p.y] then
for _, v2 in pairs(v[p.x][p.y]) do
local p3 = {x = v2.pos.x + vector.x, y = v2.pos.y + vector.y}
local e3s = newsurface.find_entities_filtered{
name = v2.name,
position = p3,
radius = 0.01,
}
if e3s and #e3s>0 then
local e3 = e3s[1]
if e3 and e3.valid then
if k == 'copper' then
ee.connect_neighbour(e3)
-- elseif k == 'red' then
-- ee.connect_neighbour{wire = defines.wire_type.red, target_entity = e3}
-- elseif k == 'green' then
-- ee.connect_neighbour{wire = defines.wire_type.green, target_entity = e3}
end
end
if k == 'copper' then
ee.connect_neighbour(e3)
-- elseif k == 'red' then
-- ee.connect_neighbour{wire = defines.wire_type.red, target_entity = e3}
-- elseif k == 'green' then
-- ee.connect_neighbour{wire = defines.wire_type.green, target_entity = e3}
end
end
end
@ -1088,7 +1111,7 @@ local function teleport_handle_wake_tiles(boat, dummyboat, newsurface_name, olds
-- NOTE: this will need to be changed, when ship doesn't necessarily arrive from the left
if vector.x < 0 then
for _, player in pairs(Common.crew_get_crew_members()) do
if player.character and player.character.valid then
if player.character and player.character.valid and player.surface.name == oldsurface_name then
local tile = oldsurface.get_tile(player.character.position.x, player.character.position.y)
if tile.valid then
if Utils.contains(CoreData.water_tile_names, tile.name) then
@ -1101,7 +1124,6 @@ local function teleport_handle_wake_tiles(boat, dummyboat, newsurface_name, olds
end
end
end
else
local p = dummyboat.position

View File

@ -168,7 +168,7 @@ function Public.create_cabin_surface()
local surface = game.create_surface(cabinname, map_gen_settings)
surface.freeze_daytime = true
surface.daytime = 0
surface.daytime = 0.3
surface.show_clouds = false
-- more here

View File

@ -127,7 +127,7 @@ function Public.create_hold_surface(nth)
local surface = game.create_surface(holdname, map_gen_settings)
surface.freeze_daytime = true
surface.daytime = 0
surface.daytime = 0.3
surface.show_clouds = false
surface.solar_power_multiplier = 0
@ -184,20 +184,6 @@ function Public.create_hold_surface(nth)
Common.build_small_loco(surface, Public.Data.loco_offset, memory.force, {255, 106, 52})
-- We place obstacle boxes before the other static boxes, so that they are potentially one tile closer to the edge than they would be otherwise:
local items = subtype == enum.INITIAL and Balance.starting_items_crew_downstairs() or {}
Common.surface_place_random_obstacle_boxes(Public.get_hold_surface(nth), {x=0,y=0}, Public.Data.width, Public.Data.height, 'rocket-silo', {[1] = 0, [2] = 6, [3] = 5, [4] = 2}, items)
-- Public.hold_place_random_obstacle_boxes(nth, {[1] = 0, [2] = 9, [3] = 3, [4] = 1}, items)
local boxes = Common.build_from_blueprint(Public.Data.boxes_bp, surface, Public.Data.boxes_bp_offset, boat.force_name)
for _, e in pairs(boxes) do
if e and e.valid then
e.destructible = false
e.minable = false
e.rotatable = false
end
end
if not boat.downstairs_poles then boat.downstairs_poles = {} end
boat.downstairs_poles[nth] = {}
for i = 1, #Public.Data.downstairs_pole_positions do
@ -225,6 +211,20 @@ function Public.create_hold_surface(nth)
end
end
-- We place obstacle boxes before the other static boxes, so that they are potentially one tile closer to the edge than they would be otherwise:
local items = subtype == enum.INITIAL and Balance.starting_items_crew_downstairs() or {}
Common.surface_place_random_obstacle_boxes(Public.get_hold_surface(nth), {x=0,y=0}, Public.Data.width, Public.Data.height, 'rocket-silo', {[1] = 0, [2] = 6, [3] = 5, [4] = 2}, items)
-- Public.hold_place_random_obstacle_boxes(nth, {[1] = 0, [2] = 9, [3] = 3, [4] = 1}, items)
local boxes = Common.build_from_blueprint(Public.Data.boxes_bp, surface, Public.Data.boxes_bp_offset, boat.force_name)
for _, e in pairs(boxes) do
if e and e.valid then
e.destructible = false
e.minable = false
e.rotatable = false
end
end
if subtype == enum.SECONDARY then
local difficulty_name = CoreData.get_difficulty_option_informal_name_from_value(memory.difficulty)
if difficulty_name == 'nightmare' then

View File

@ -10,6 +10,7 @@ local BoatData = require 'maps.pirates.structures.boats.sloop.data'
local Event = require 'utils.event'
local IslandEnum = require 'maps.pirates.surfaces.islands.island_enum'
local Balance = require 'maps.pirates.balance'
local CoreData = require 'maps.pirates.coredata'
local Public = {}
Public.Data = require 'maps.pirates.surfaces.islands.cave.data'
@ -100,6 +101,8 @@ function Public.reveal(cave_miner, surface, source_surface, position, brushsize)
destination.dynamic_data.disabled_wave_timer = Balance.prevent_waves_from_spawning_in_cave_timer_length
end
Public.try_make_spawner_elite(e, destination)
Public.reveal(cave_miner, surface, source_surface, entity_position, 15)
end
end
@ -111,6 +114,22 @@ function Public.reveal(cave_miner, surface, source_surface, position, brushsize)
source_surface.request_to_generate_chunks(position, 3)
end
function Public.try_make_spawner_elite(spawner, destination)
local memory = Memory.get_crew_memory()
if spawner and CoreData.get_difficulty_option_from_value(memory.difficulty) >= 3 then
if Math.random(20) == 1 then
local max_health = Balance.elite_spawner_health()
Common.new_healthbar(true, spawner, max_health, nil, max_health, 0.8, nil, destination.dynamic_data)
local elite_spawners = destination.dynamic_data.elite_spawners
if elite_spawners then
elite_spawners[#elite_spawners + 1] = spawner
end
end
end
end
function Public.roll_source_surface(destination_data)
local map_gen_settings = {

View File

@ -233,7 +233,7 @@ local function red_desert_tick()
Public.underground_worms_ai()
if game.tick % 360 == 0 and destination.dynamic_data.timer and destination.dynamic_data.timer > 60 then
if game.tick % 300 == 0 and destination.dynamic_data.timer and destination.dynamic_data.timer > 60 then
Public.custom_biter_ai()
end
end
@ -387,7 +387,7 @@ function Public.custom_biter_ai()
local units_created = {}
local name = Common.get_random_unit_type(evolution)
local unittype_pollutioncost = CoreData.biterPollutionValues[name] * 1.1 * Balance.scripted_biters_pollution_cost_multiplier()
local unittype_pollutioncost = CoreData.biterPollutionValues[name] * Balance.scripted_biters_pollution_cost_multiplier()
local function spawn(name2)
units_created_count = units_created_count + 1

View File

@ -83,7 +83,7 @@ function Public.terrain(args)
else
args.tiles[#args.tiles + 1] = {name = 'water-shallow', position = p}
if math.random(1, 1024) == 1 then
if math.random(1, 512) == 1 then
local name = Common.get_random_worm_type(memory.evolution_factor)
local force = memory.enemy_force_name
args.entities[#args.entities + 1] = {name = name, position = p, force = force}