From fb4dba0462597554bf79349e5a4407df0b631b46 Mon Sep 17 00:00:00 2001 From: Wrill <86113712+WrillWasTaken@users.noreply.github.com> Date: Tue, 21 Jan 2025 17:37:22 +0000 Subject: [PATCH 01/52] Update deep_drill.dm --- code/modules/mining/drilling/deep_drill.dm | 269 ++++----------------- 1 file changed, 49 insertions(+), 220 deletions(-) diff --git a/code/modules/mining/drilling/deep_drill.dm b/code/modules/mining/drilling/deep_drill.dm index a9abec4e932..9a3b97aebd4 100644 --- a/code/modules/mining/drilling/deep_drill.dm +++ b/code/modules/mining/drilling/deep_drill.dm @@ -4,7 +4,7 @@ /obj/machinery/mining icon = 'icons/obj/mining_drill.dmi' anchored = FALSE - use_power = NO_POWER_USE //The drill takes power directly from a cell. + use_power = NO_POWER_USE //The drill doesn't need power density = TRUE layer = MOB_LAYER+0.1 //So it draws over mobs in the tile north of it. @@ -19,15 +19,8 @@ maxHealth = 2000 health = 2000 - var/last_update = 0 - var/list/stored_ore = list() - - var/active = FALSE - var/list/resource_field = list() - var/datum/golem_controller/GC var/obj/cave_generator/cave_gen var/cave_connected = FALSE - var/last_use = 0.0 var/ore_types = list( MATERIAL_IRON = /obj/item/ore/iron, @@ -47,18 +40,10 @@ var/capacity var/charge_use var/radius - var/obj/item/cell/large/cell - - //Flags - var/need_update_field = FALSE - var/need_player_check = FALSE /obj/machinery/mining/deep_drill/Initialize() . = ..() cave_gen = locate(/obj/cave_generator) - var/obj/item/cell/large/high/C = new(src) - component_parts += C - cell = C update_icon() /obj/machinery/mining/deep_drill/Destroy() @@ -72,22 +57,15 @@ . = ..() /obj/machinery/mining/deep_drill/Process() - if(!active) - return - - if(!anchored || !use_cell_power()) - system_error("system configuration or charge error") + if(!cave_connected) return if(check_surroundings()) - system_error("obstacle detected near the drill") + system_error("ERROR W411: OBSTACLE DETECTED") return if(health == 0) - system_error("critical damage") - - if(need_update_field) - get_resource_field() + system_error("ERROR HP00: CRITICAL DAMAGE") //Drill through the flooring, if any. if(istype(get_turf(src), /turf/floor/asteroid)) @@ -98,68 +76,9 @@ var/turf/floor/T = get_turf(src) T.explosion_act(200, null) - dig_ore() - -/obj/machinery/mining/deep_drill/proc/dig_ore() - //Dig out the tasty ores. - if(!resource_field.len) - system_error("resources depleted") - return - - var/turf/harvesting = pick(resource_field) - - //remove emty trufs - while(resource_field.len && !harvesting.resources) - harvesting.has_resources = FALSE - harvesting.resources = null - resource_field -= harvesting - if(resource_field.len) - harvesting = pick(resource_field) - - if(!harvesting) - system_error("resources depleted") - return - - var/total_harvest = harvest_speed //Ore harvest-per-tick. - var/found_resource = FALSE - - for(var/metal in shuffle(ore_types)) - - if(contents.len >= capacity) - system_error("insufficient storage space") - - if(contents.len + total_harvest >= capacity) - total_harvest = capacity - contents.len - - if(total_harvest <= 0) - break - - if(harvesting.resources[metal]) - - found_resource = TRUE - - var/create_ore = 0 - if(harvesting.resources[metal] >= total_harvest) - harvesting.resources[metal] -= total_harvest - create_ore = total_harvest * GC.GW.mineral_multiplier - total_harvest = 0 - else - total_harvest -= harvesting.resources[metal] - create_ore = harvesting.resources[metal] * GC.GW.mineral_multiplier - harvesting.resources[metal] = 0 - - for(var/i = 1, i <= create_ore, i++) - var/oretype = ore_types[metal] - new oretype(src) - - if(!found_resource) - harvesting.has_resources = FALSE - harvesting.resources = null - resource_field -= harvesting - /obj/machinery/mining/deep_drill/attackby(obj/item/I, mob/user as mob) - if(!active) + if(!cave_connected) var/tool_type = I.get_tool_type(user, list(QUALITY_SCREW_DRIVING), src) if(tool_type == QUALITY_SCREW_DRIVING) var/used_sound = panel_open ? 'sound/machines/Custom_screwdriveropen.ogg' : 'sound/machines/Custom_screwdriverclose.ogg' @@ -208,7 +127,7 @@ // Repair the drill if it is damaged var/damage = maxHealth - health if(damage && (QUALITY_WELDING in I.tool_qualities)) - if(active) + if(cave_connected) to_chat(user, SPAN_WARNING("Turn \the [src] off first!")) return to_chat(user, "You start repairing the damage to [src].") @@ -223,92 +142,63 @@ take_damage(-(0.33 * maxHealth - health)) // Repair the drill to 33 percents return - if(!panel_open || active) + if(!panel_open || cave_connected) return ..() - if(istype(I, /obj/item/cell/large)) - if(cell) - to_chat(user, "The drill already has a cell installed.") - else - user.drop_item() - I.loc = src - cell = I - component_parts += I - to_chat(user, "You install \the [I].") - return - ..() /obj/machinery/mining/deep_drill/attack_hand(mob/user as mob) - if (panel_open && cell) - to_chat(user, "You take out \the [cell].") - cell.loc = get_turf(user) - component_parts -= cell - cell = null - return - else if(need_player_check) - to_chat(user, "You hit the manual override and reset the drill's error checking.") - need_player_check = FALSE - if(anchored) - get_resource_field() - update_icon() - return - else if(!panel_open) + if(!panel_open) if(health == 0) to_chat(user, SPAN_NOTICE("The drill is too damaged to be turned on.")) else if(!anchored) to_chat(user, SPAN_NOTICE("The drill needs to be anchored to be turned on.")) - else if(!active && check_surroundings()) + else if(!cave_connected && check_surroundings()) to_chat(user, SPAN_WARNING("The space around \the [src] has to be clear of obstacles!")) - else if(world.time - last_use < DRILL_COOLDOWN) - to_chat(user, SPAN_WARNING("\The [src] needs some time to cool down! [round((last_use + DRILL_COOLDOWN - world.time) / 10)] seconds remaining.")) - else if(use_cell_power()) - - if(!cave_connected) - if(cave_gen.is_generating()) - to_chat(user, SPAN_WARNING("A cave system is already being dug.")) - else if(cave_gen.is_opened()) - to_chat(user, SPAN_WARNING("A cave system is already being explored.")) - else if(cave_gen.is_collapsing() || cave_gen.is_cleaning()) - to_chat(user, SPAN_WARNING("The cave system is being collapsed!")) - else if(!cave_gen.check_cooldown()) - to_chat(user, SPAN_WARNING("The asteroid structure is too unstable for now to open a new cave system. Best to take your current haul to the ship, miner!\nYou have to wait [cave_gen.remaining_cooldown()] minutes.")) - else - var/turf/T = get_turf(loc) - cave_connected = cave_gen.place_ladders(loc.x, loc.y, loc.z, T.seismic_activity) - update_icon() - else - if(!cave_gen.is_closed()) // If cave is already closed, something went wrong - log_and_message_admins("[key_name(user)] has collapsed an active cave system.") - cave_gen.initiate_collapse() - cave_connected = FALSE - update_icon() - /* // Only if on mother load - active = !active - if(active) - var/turf/T = get_turf(loc) - GC = new /datum/golem_controller(location=T, seismic=T.seismic_activity, drill=src) - visible_message(SPAN_NOTICE("\The [src] lurches downwards, grinding noisily.")) - last_use = world.time - need_update_field = TRUE + if(!cave_connected) + if(cave_gen.is_generating()) + to_chat(user, SPAN_WARNING("A cave system is already being dug.")) + else if(cave_gen.is_opened()) + to_chat(user, SPAN_WARNING("A cave system is already being explored.")) + else if(cave_gen.is_collapsing() || cave_gen.is_cleaning()) + to_chat(user, SPAN_WARNING("The cave system is being collapsed!")) + else if(!cave_gen.check_cooldown()) + to_chat(user, SPAN_WARNING("The asteroid structure is too unstable for now to open a new cave system. Best to take your current haul to the ship, miner!\nYou have to wait [cave_gen.remaining_cooldown()] minutes.")) else - GC.stop() - GC = null - visible_message(SPAN_NOTICE("\The [src] shudders to a grinding halt.")) - */ + var/turf/T = get_turf(loc) + cave_connected = cave_gen.place_ladders(loc.x, loc.y, loc.z, T.seismic_activity) + update_icon() + else + if(!cave_gen.is_closed()) // If cave is already closed, something went wrong + log_and_message_admins("[key_name(user)] has collapsed an active cave system.") + cave_gen.initiate_collapse() + cave_connected = FALSE + update_icon() + + /* // Only if on mother load + active = !active + if(active) + var/turf/T = get_turf(loc) + GC = new /datum/golem_controller(location=T, seismic=T.seismic_activity, drill=src) + visible_message(SPAN_NOTICE("\The [src] lurches downwards, grinding noisily.")) + last_use = world.time + need_update_field = TRUE else - to_chat(user, SPAN_NOTICE("The drill is unpowered.")) + GC.stop() + GC = null + visible_message(SPAN_NOTICE("\The [src] shudders to a grinding halt.")) + */ else to_chat(user, SPAN_NOTICE("Turning on a piece of industrial machinery with wires exposed is a bad idea.")) update_icon() /obj/machinery/mining/deep_drill/update_icon() - if(need_player_check) + if(anchored && check_surroundings()) icon_state = "mining_drill_error" - else if(active || cave_connected) + else if(cave_connected) icon_state = "mining_drill_active" else icon_state = "mining_drill" @@ -332,50 +222,21 @@ charge_use = max(charge_use, 0) if(istype(P, /obj/item/stock_parts/scanning_module)) radius = RADIUS + P.rating - cell = locate(/obj/item/cell/large) in component_parts /obj/machinery/mining/deep_drill/proc/system_error(error) if(error) - visible_message(SPAN_NOTICE("\The [src] flashes a '[error]' warning.")) - need_player_check = TRUE - active = FALSE - if(GC) - GC.stop() - GC = null + visible_message(SPAN_NOTICE("\The [src] flashes with '[error]' and shuts down!")) + log_and_message_admins("An active cave system was collapsed.") + cave_gen.initiate_collapse() + cave_connected = FALSE update_icon() -/obj/machinery/mining/deep_drill/proc/get_resource_field() - resource_field = list() - need_update_field = FALSE - - var/turf/T = get_turf(src) - if(!istype(T)) - return - - for(var/turf/mine_trufs in range(T, radius)) - if(mine_trufs.has_resources) - resource_field += mine_trufs - - if(!resource_field.len) - system_error("resources depleted") - -/obj/machinery/mining/deep_drill/proc/use_cell_power() - if(!cell) - return FALSE - if(cell.checked_use(charge_use)) - return TRUE - return FALSE - /obj/machinery/mining/deep_drill/proc/check_surroundings() - // Check if there is no dense obstacles around the drill to avoid blocking access to it + // Check if there are no walls around the drill for(var/turf/F in block(locate(x - 1, y - 1, z), locate(x + 1, y + 1, z))) - if(F != loc) - if(F.density) - return TRUE - for(var/atom/A in F) - if(A.density && !(A.flags & ON_BORDER) && !ismob(A)) - return TRUE + if(!istype(F,/turf/floor)) + return TRUE return FALSE /obj/machinery/mining/deep_drill/attack_generic(mob/user, damage) @@ -399,14 +260,6 @@ explosion(get_turf(src), 800, 50) qdel(src) -/obj/machinery/mining/deep_drill/proc/update_ore_count() - stored_ore = list() - for(var/obj/item/ore/O in contents) - if(stored_ore[O.name]) - stored_ore[O.name]++ - else - stored_ore[O.name] = 1 - /obj/machinery/mining/deep_drill/examine(mob/user, extra_description = "") if(health <= 0) extra_description += "\n\The [src] is wrecked." @@ -419,31 +272,7 @@ else extra_description += "\n\The [src] is in pristine condition." - if(world.time > last_update + 1 SECONDS) - update_ore_count() - last_update = world.time - - extra_description += "\nIt holds:" - for(var/obj/item/ore/O in contents) - extra_description += "\n- [stored_ore[O]] [O]" ..(user, extra_description) -/obj/machinery/mining/deep_drill/verb/unload() - set name = "Unload Drill" - set category = "Object" - set src in oview(1) - - var/mob/M = usr - if(ismob(M) && M.incapacitated()) - return - - var/obj/structure/ore_box/B = locate() in orange(1) - if(B) - for(var/obj/item/ore/O in contents) - O.loc = B - to_chat(usr, SPAN_NOTICE("You unload the drill's storage cache into the ore box.")) - else - to_chat(usr, SPAN_NOTICE("You must move an ore box up to the drill before you can unload it.")) - #undef RADIUS #undef DRILL_COOLDOWN From 138275205af544cdae6893448cf5a8e59d4d48fa Mon Sep 17 00:00:00 2001 From: Wrill <86113712+WrillWasTaken@users.noreply.github.com> Date: Tue, 21 Jan 2025 18:50:16 +0000 Subject: [PATCH 02/52] Update deep_drill.dm --- code/modules/mining/drilling/deep_drill.dm | 100 ++++++++------------- 1 file changed, 37 insertions(+), 63 deletions(-) diff --git a/code/modules/mining/drilling/deep_drill.dm b/code/modules/mining/drilling/deep_drill.dm index 9a3b97aebd4..e829461b72f 100644 --- a/code/modules/mining/drilling/deep_drill.dm +++ b/code/modules/mining/drilling/deep_drill.dm @@ -1,5 +1,12 @@ -#define RADIUS 4 -#define DRILL_COOLDOWN 1 MINUTE +#define DRILL_REPAIR_AMOUNT 500 + +//these are defined because a few of them are used in multiple places and this makes it easier to work with them all at once +#define DRILL_SHUTDOWN_TEXT_BROKEN "ERROR HP00: CRITICAL DAMAGE" +#define DRILL_SHUTDOWN_TEXT_OBSTACLE "ERROR W411: OBSTACLE DETECTED" + +#define DRILL_SHUTDOWN_LOG_BROKEN "A cave system was collapsed because its associated drill was destroyed." +#define DRILL_SHUTDOWN_LOG_OBSTACLE "A cave system was collapsed because its associated drill was too close to an obstacle." +#define DRILL_SHUTDOWN_LOG_MANUAL "[key_name(user)] has collapsed an active cave system." /obj/machinery/mining icon = 'icons/obj/mining_drill.dmi' @@ -49,9 +56,7 @@ /obj/machinery/mining/deep_drill/Destroy() if(cave_connected) // In case the drill gets destroyed with an active cave system - log_and_message_admins("Collapsing active cave system as its associated drill got destroyed.") - cave_gen.initiate_collapse() - cave_connected = FALSE + shutdown_drill(DRILL_SHUTDOWN_TEXT_BROKEN,DRILL_SHUTDOWN_LOG_OBSTACLE) if(cave_gen) cave_gen = null . = ..() @@ -61,11 +66,11 @@ return if(check_surroundings()) - system_error("ERROR W411: OBSTACLE DETECTED") + shutdown_drill(DRILL_SHUTDOWN_TEXT_OBSTACLE,DRILL_SHUTDOWN_LOG_OBSTACLE) return if(health == 0) - system_error("ERROR HP00: CRITICAL DAMAGE") + shutdown_drill(DRILL_SHUTDOWN_TEXT_BROKEN,DRILL_SHUTDOWN_LOG_OBSTACLE) //Drill through the flooring, if any. if(istype(get_turf(src), /turf/floor/asteroid)) @@ -112,10 +117,10 @@ else if(cave_gen.is_collapsing() || cave_gen.is_cleaning()) to_chat(user, SPAN_WARNING("The cave system is being collapsed!")) return - else if (check_surroundings()) + else if (!anchored && check_surroundings()) // we only care about the terrain when anchoring, not the other way around, otherwise the drill gets stuck if the terrain under it changes (like if someone RCDs the asteroid tile under it) to_chat(user, SPAN_WARNING("The space around \the [src] has to be clear of obstacles!")) return - else if(!(istype(loc, /turf/floor/asteroid) || istype(loc, /turf/floor/exoplanet))) + else if(!anchored && !(istype(loc, /turf/floor/asteroid) || istype(loc, /turf/floor/exoplanet))) to_chat(user, SPAN_WARNING("\The [src] cannot dig that kind of ground!")) return @@ -125,8 +130,7 @@ return // Repair the drill if it is damaged - var/damage = maxHealth - health - if(damage && (QUALITY_WELDING in I.tool_qualities)) + if((health < maxHealth) && (QUALITY_WELDING in I.tool_qualities)) if(cave_connected) to_chat(user, SPAN_WARNING("Turn \the [src] off first!")) return @@ -134,12 +138,8 @@ if(I.use_tool(user, src, WORKTIME_LONG, QUALITY_WELDING, FAILCHANCE_EASY, required_stat = STAT_ROB)) playsound(src, 'sound/items/Welder.ogg', 100, 1) to_chat(user, "You finish repairing the damage to [src].") - if(damage < 0.33 * maxHealth) - take_damage(-damage) // Completely repair the drill - else if(damage < 0.66 * maxHealth) - take_damage(-(0.66 * maxHealth - health)) // Repair the drill to 66 percents - else - take_damage(-(0.33 * maxHealth - health)) // Repair the drill to 33 percents + var/repair_amount = ((health + DRILL_REPAIR_AMOUNT) < maxHealth) ? DRILL_REPAIR_AMOUNT : ((health + DRILL_REPAIR_AMOUNT) - maxHealth) //heal by the drill repair amount defined, unless that would go over max health, in which case do some math to avoid going over maxhealth + take_damage(-(repair_amount)) // Repair the drill to 33 percents return if(!panel_open || cave_connected) @@ -171,32 +171,15 @@ cave_connected = cave_gen.place_ladders(loc.x, loc.y, loc.z, T.seismic_activity) update_icon() else - if(!cave_gen.is_closed()) // If cave is already closed, something went wrong - log_and_message_admins("[key_name(user)] has collapsed an active cave system.") - cave_gen.initiate_collapse() - cave_connected = FALSE - update_icon() - - /* // Only if on mother load - active = !active - if(active) - var/turf/T = get_turf(loc) - GC = new /datum/golem_controller(location=T, seismic=T.seismic_activity, drill=src) - visible_message(SPAN_NOTICE("\The [src] lurches downwards, grinding noisily.")) - last_use = world.time - need_update_field = TRUE - else - GC.stop() - GC = null - visible_message(SPAN_NOTICE("\The [src] shudders to a grinding halt.")) - */ + shutdown_drill(null,DRILL_SHUTDOWN_LOG_MANUAL) + else to_chat(user, SPAN_NOTICE("Turning on a piece of industrial machinery with wires exposed is a bad idea.")) update_icon() /obj/machinery/mining/deep_drill/update_icon() - if(anchored && check_surroundings()) + if(anchored && (check_surroundings() || !istype(get_turf(src), /turf/floor/asteroid)) icon_state = "mining_drill_error" else if(cave_connected) icon_state = "mining_drill_active" @@ -204,30 +187,14 @@ icon_state = "mining_drill" return +/obj/machinery/mining/deep_drill/proc/shutdown_drill(displaytext,log) -/obj/machinery/mining/deep_drill/RefreshParts() - ..() - harvest_speed = 0 - capacity = 0 - charge_use = 37 - radius = RADIUS - - for(var/obj/item/stock_parts/P in component_parts) - if(istype(P, /obj/item/stock_parts/micro_laser)) - harvest_speed = P.rating - if(istype(P, /obj/item/stock_parts/matter_bin)) - capacity = 200 * P.rating - if(istype(P, /obj/item/stock_parts/capacitor)) - charge_use -= 8 * (P.rating - harvest_speed) - charge_use = max(charge_use, 0) - if(istype(P, /obj/item/stock_parts/scanning_module)) - radius = RADIUS + P.rating - -/obj/machinery/mining/deep_drill/proc/system_error(error) - - if(error) - visible_message(SPAN_NOTICE("\The [src] flashes with '[error]' and shuts down!")) - log_and_message_admins("An active cave system was collapsed.") + if(cave_gen.is_closed()) //easy sanity check + return + + if(displaytext) + visible_message(SPAN_NOTICE("\The [src] flashes with '[displaytext]' and shuts down!")) + log_and_message_admins(log) cave_gen.initiate_collapse() cave_connected = FALSE update_icon() @@ -253,7 +220,7 @@ /obj/machinery/mining/deep_drill/take_damage(value) health = min(max(health - value, 0), maxHealth) if(health == 0) - system_error("critical damage") + shutdown_drill("critical damage") if(prob(10)) // Some chance that the drill completely blows up var/turf/O = get_turf(src) if(!O) return @@ -274,5 +241,12 @@ ..(user, extra_description) -#undef RADIUS -#undef DRILL_COOLDOWN +#undef DRILL_REPAIR_AMOUNT + +#undef DRILL_SHUTDOWN_TEXT_BROKEN +#undef DRILL_SHUTDOWN_TEXT_OBSTACLE + +#undef DRILL_SHUTDOWN_LOG_BROKEN +#undef DRILL_SHUTDOWN_LOG_OBSTACLE +#undef DRILL_SHUTDOWN_LOG_MANUAL + From a30e47dc289b7863778c7065d3ede776bdfbe3f7 Mon Sep 17 00:00:00 2001 From: Wrill <86113712+WrillWasTaken@users.noreply.github.com> Date: Tue, 21 Jan 2025 19:54:05 +0000 Subject: [PATCH 03/52] kill waves now that the drill is debloated --- cev_eris.dme | 3 - code/modules/mining/drilling/deep_drill.dm | 13 +- code/modules/mining/drilling/golem_burrow.dm | 58 --------- .../mining/drilling/golem_controller.dm | 123 ------------------ code/modules/mining/drilling/golem_wave.dm | 62 --------- .../carbon/superior_animal/golem/golem.dm | 33 +---- .../superior_animal/golem/types/ansible.dm | 2 +- .../superior_animal/golem/types/diamond.dm | 35 ----- .../superior_animal/golem/types/uranium.dm | 2 +- 9 files changed, 7 insertions(+), 324 deletions(-) delete mode 100644 code/modules/mining/drilling/golem_burrow.dm delete mode 100644 code/modules/mining/drilling/golem_controller.dm delete mode 100644 code/modules/mining/drilling/golem_wave.dm diff --git a/cev_eris.dme b/cev_eris.dme index 2de7485a2b4..6cbeb81d22f 100644 --- a/cev_eris.dme +++ b/cev_eris.dme @@ -1848,9 +1848,6 @@ #include "code\modules\mining\drilling\cave_generator.dm" #include "code\modules\mining\drilling\cave_mineral.dm" #include "code\modules\mining\drilling\deep_drill.dm" -#include "code\modules\mining\drilling\golem_burrow.dm" -#include "code\modules\mining\drilling\golem_controller.dm" -#include "code\modules\mining\drilling\golem_wave.dm" #include "code\modules\mining\drilling\scanner.dm" #include "code\modules\mob\animations.dm" #include "code\modules\mob\death.dm" diff --git a/code/modules/mining/drilling/deep_drill.dm b/code/modules/mining/drilling/deep_drill.dm index e829461b72f..22d0dc76367 100644 --- a/code/modules/mining/drilling/deep_drill.dm +++ b/code/modules/mining/drilling/deep_drill.dm @@ -42,12 +42,6 @@ MATERIAL_PLASTIC = /obj/item/ore/coal ) - //Upgrades - var/harvest_speed - var/capacity - var/charge_use - var/radius - /obj/machinery/mining/deep_drill/Initialize() . = ..() cave_gen = locate(/obj/cave_generator) @@ -134,12 +128,13 @@ if(cave_connected) to_chat(user, SPAN_WARNING("Turn \the [src] off first!")) return + to_chat(user, "You start repairing the damage to [src].") if(I.use_tool(user, src, WORKTIME_LONG, QUALITY_WELDING, FAILCHANCE_EASY, required_stat = STAT_ROB)) playsound(src, 'sound/items/Welder.ogg', 100, 1) to_chat(user, "You finish repairing the damage to [src].") - var/repair_amount = ((health + DRILL_REPAIR_AMOUNT) < maxHealth) ? DRILL_REPAIR_AMOUNT : ((health + DRILL_REPAIR_AMOUNT) - maxHealth) //heal by the drill repair amount defined, unless that would go over max health, in which case do some math to avoid going over maxhealth - take_damage(-(repair_amount)) // Repair the drill to 33 percents + health = ((health + DRILL_REPAIR_AMOUNT) < maxHealth ? health + DRILL_REPAIR_AMOUNT : maxHealth) // increase health by the defined repair amount unless it would go over maxHealth, in which case just set heal to maxHealth instead. + return if(!panel_open || cave_connected) @@ -179,7 +174,7 @@ update_icon() /obj/machinery/mining/deep_drill/update_icon() - if(anchored && (check_surroundings() || !istype(get_turf(src), /turf/floor/asteroid)) + if(anchored && (check_surroundings() || !istype(get_turf(src), /turf/floor/asteroid))) icon_state = "mining_drill_error" else if(cave_connected) icon_state = "mining_drill_active" diff --git a/code/modules/mining/drilling/golem_burrow.dm b/code/modules/mining/drilling/golem_burrow.dm deleted file mode 100644 index 2554c7e71c5..00000000000 --- a/code/modules/mining/drilling/golem_burrow.dm +++ /dev/null @@ -1,58 +0,0 @@ -/obj/structure/golem_burrow - name = "golem burrow" - icon = 'icons/obj/burrows.dmi' - icon_state = "maint_hole" - desc = "A pile of rocks that regularly pulses as if it was alive." - density = TRUE - anchored = TRUE - - maxHealth = 50 - health = 50 - explosion_coverage = 0.3 - var/datum/golem_controller/controller - -/obj/structure/golem_burrow/New(loc, parent) - ..() - controller = parent // Link burrow with golem controller - -/obj/structure/golem_burrow/Destroy() - visible_message(SPAN_DANGER("\The [src] crumbles!")) - if(controller) - controller.burrows -= src - controller = null - ..() - -/obj/structure/golem_burrow/attack_generic(mob/user, damage) - user.do_attack_animation(src) - visible_message(SPAN_DANGER("\The [user] smashes \the [src]!")) - take_damage(damage) - user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN * 1.5) - -/obj/structure/golem_burrow/attackby(obj/item/I, mob/user) - if (user.a_intent == I_HURT && user.Adjacent(src)) - if(!(I.flags & NOBLUDGEON)) - user.do_attack_animation(src) - var/damage = I.force * I.structure_damage_factor - var/volume = min(damage * 3.5, 15) - if (I.hitsound) - playsound(src, I.hitsound, volume, 1, -1) - visible_message(SPAN_DANGER("[src] has been hit by [user] with [I].")) - take_damage(damage) - user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN * 1.5) - return TRUE - -/obj/structure/golem_burrow/bullet_act(obj/item/projectile/Proj) - ..() - // Bullet not really efficient against a pile of rock - take_damage(Proj.get_structure_damage() * 0.25) - -/obj/structure/golem_burrow/take_damage(damage) - . = health - damage < 0 ? damage - (damage - health) : damage - . *= explosion_coverage - health = min(max(health - damage, 0), maxHealth) - if(health == 0) - qdel(src) - return - -/obj/structure/golem_burrow/proc/stop() - qdel(src) // Delete burrow diff --git a/code/modules/mining/drilling/golem_controller.dm b/code/modules/mining/drilling/golem_controller.dm deleted file mode 100644 index 4ac0c07e569..00000000000 --- a/code/modules/mining/drilling/golem_controller.dm +++ /dev/null @@ -1,123 +0,0 @@ -/datum/golem_controller - - var/turf/loc // Location of the golem_controller - var/list/obj/structure/golem_burrow/burrows = list() // List of golem burrows tied to the controller - var/list/mob/living/carbon/superior_animal/golems = list() // List of golems tied to the controller - var/processing = TRUE - var/obj/machinery/mining/deep_drill/DD - - // Wave related variables - var/datum/golem_wave/GW // Golem wave datum - var/count = 0 // Number of burrows created since the start - var/time_burrow = 0 // Timestamp of last created burrow - var/time_spawn = 0 // Timestamp of last spawn wave - -/datum/golem_controller/New(turf/location, seismic, drill) - loc = location - var/path = GLOB.golem_waves[seismic] // Retrieve which kind of wave it is depending on seismic activity - GW = new path() - if(drill) - DD = drill - - START_PROCESSING(SSobj, src) - -/datum/golem_controller/Destroy() - processing = FALSE // Stop processing - qdel(GW) // Destroy wave object - GW = null - DD = null - for(var/obj/structure/golem_burrow/GB in burrows) // Unlink burrows and controller - GB.stop() - ..() - -/datum/golem_controller/Process() - // Currently, STOP_PROCESSING does NOT instantly remove the object from processing queue - // This is a quick and dirty fix for runtime error spam caused by this - if(!processing) - return - - // Check if a new burrow should be created - if(count < GW.burrow_count && (world.time - time_burrow) > GW.burrow_interval) - time_burrow = world.time - count++ - spawn_golem_burrow() - - // Check if a new spawn wave should occur - if((world.time - time_spawn) > GW.spawn_interval) - time_spawn = world.time - spawn_golems() - -/datum/golem_controller/proc/spawn_golem_burrow() - // Spawn burrow randomly in a donut around the drill - var/turf/T = pick(getcircle(loc, 7)) - if(!istype(T)) // Try again with a smaller circle - T = pick(getcircle(loc, 6)) - if(!istype(T)) // Something wrong is happening - log_and_message_admins("Golem controller failed to create a new burrow around ([loc.x], [loc.y], [loc.z]).") - return - - while(loc && check_density_no_mobs(T) && T != loc) - T = get_step(T, get_dir(T, loc)) - // If we end up on top of the drill, just spawn next to it - if(T == loc) - T = get_step(loc, pick(cardinal)) - - burrows += new /obj/structure/golem_burrow(T, src) // Spawn burrow at final location - -/datum/golem_controller/proc/spawn_golems() - // Spawn golems at all burrows - for(var/obj/structure/golem_burrow/GB in burrows) - if(!GB.loc) // If the burrow is in nullspace for some reason - burrows -= GB // Remove it from the pool of burrows - continue - var/list/possible_directions = cardinal.Copy() - var/i = 0 - var/proba = GW.special_probability - // Spawn golems around the burrow on free turfs - while(i < GW.golem_spawn && possible_directions.len) - var/turf/possible_T = get_step(GB.loc, pick_n_take(possible_directions)) - if(!check_density_no_mobs(possible_T)) - var/golemtype - if(prob(proba)) - golemtype = pick(GLOB.golems_special) // Pick a special golem - proba = max(0, proba - 10) // Decreasing probability to avoid mass spawn of special - else - golemtype = pick(GLOB.golems_normal) // Pick a normal golem - i++ - new golemtype(possible_T, drill=DD, parent=src) // Spawn golem at free location - // Spawn remaining golems on top of burrow - if(i < GW.golem_spawn) - for(var/j in i to (GW.golem_spawn-1)) - var/golemtype - if(prob(proba)) - golemtype = pick(GLOB.golems_special) // Pick a special golem - proba = max(0, proba - 10) // Decreasing probability to avoid mass spawn of special - else - golemtype = pick(GLOB.golems_normal) // Pick a normal golem - new golemtype(GB.loc, drill=DD, parent=src) // Spawn golem at that burrow - -/datum/golem_controller/proc/stop() - // Disable wave - processing = FALSE - - // Delete controller and all golems after given delay - spawn(3 MINUTES) - // Delete burrows - for(var/obj/structure/golem_burrow/BU in burrows) - qdel(BU) - - // Delete golems - for(var/mob/living/carbon/superior_animal/golem/GO in golems) - GO.ore = null // Do not spawn ores - GO.death(FALSE, "burrows into the ground.") - - // Delete controller - qdel(src) - -/datum/golem_controller/proc/check_density_no_mobs(turf/F) - if(F.density) - return TRUE - for(var/atom/A in F) - if(A.density && !(A.flags & ON_BORDER) && !ismob(A)) - return TRUE - return FALSE diff --git a/code/modules/mining/drilling/golem_wave.dm b/code/modules/mining/drilling/golem_wave.dm deleted file mode 100644 index a87dd39f873..00000000000 --- a/code/modules/mining/drilling/golem_wave.dm +++ /dev/null @@ -1,62 +0,0 @@ -GLOBAL_LIST_INIT(golem_waves, list(/datum/golem_wave/dormant, - /datum/golem_wave/negligible, - /datum/golem_wave/typical, - /datum/golem_wave/substantial, - /datum/golem_wave/major, - /datum/golem_wave/abnormal)) - -/datum/golem_wave - var/burrow_count // Total number of burrows spawned over the course of drilling - var/burrow_interval // Number of seconds that pass between each new burrow spawns - var/golem_spawn // Number of golems spawned by each burrow on spawn event - var/spawn_interval // Number of seconds that pass between spawn events of burrows - var/special_probability // Probability of a golem being a special one instead of a normal one - var/mineral_multiplier // A multiplier of materials excavated by the drill - -/datum/golem_wave/dormant - burrow_count = 2 - burrow_interval = 30 SECONDS - golem_spawn = 2 - spawn_interval = 24 SECONDS - special_probability = 0 - mineral_multiplier = 1.0 - -/datum/golem_wave/negligible - burrow_count = 2 - burrow_interval = 24 SECONDS - golem_spawn = 2 - spawn_interval = 20 SECONDS - special_probability = 0 - mineral_multiplier = 1.4 - -/datum/golem_wave/typical - burrow_count = 3 - burrow_interval = 24 SECONDS - golem_spawn = 3 - spawn_interval = 18 SECONDS - special_probability = 10 - mineral_multiplier = 1.7 - -/datum/golem_wave/substantial - burrow_count = 3 - burrow_interval = 24 SECONDS - golem_spawn = 3 - spawn_interval = 18 SECONDS - special_probability = 20 - mineral_multiplier = 2 - -/datum/golem_wave/major - burrow_count = 4 - burrow_interval = 20 SECONDS - golem_spawn = 4 - spawn_interval = 14 SECONDS - special_probability = 30 - mineral_multiplier = 2.3 - -/datum/golem_wave/abnormal - burrow_count = 5 - burrow_interval = 18 SECONDS - golem_spawn = 4 - spawn_interval = 12 SECONDS - special_probability = 30 - mineral_multiplier = 3.0 diff --git a/code/modules/mob/living/carbon/superior_animal/golem/golem.dm b/code/modules/mob/living/carbon/superior_animal/golem/golem.dm index e3274aef98a..ecd6abc7bf2 100644 --- a/code/modules/mob/living/carbon/superior_animal/golem/golem.dm +++ b/code/modules/mob/living/carbon/superior_animal/golem/golem.dm @@ -77,27 +77,6 @@ GLOBAL_LIST_INIT(golems_special, list(/mob/living/carbon/superior_animal/golem/s // Type of ore to spawn when the golem dies var/ore - // The ennemy of all golemkind - var/obj/machinery/mining/deep_drill/DD - - // Controller that spawned the golem - var/datum/golem_controller/controller - -/mob/living/carbon/superior_animal/golem/New(loc, obj/machinery/mining/deep_drill/drill, datum/golem_controller/parent) - ..() - if(parent) - controller = parent // Link golem with golem controller - controller.golems += src - if(drill) - DD = drill - if(prob(50)) - target_mob = drill - stance = HOSTILE_STANCE_ATTACK - -/mob/living/carbon/superior_animal/golem/Destroy() - DD = null - ..() - /mob/living/carbon/superior_animal/golem/death(gibbed, message = deathmessage) if(controller) // Unlink from controller controller.golems -= src @@ -129,15 +108,5 @@ GLOBAL_LIST_INIT(golems_special, list(/mob/living/carbon/superior_animal/golem/s T.attack_generic(src, rand(surrounds_mult * melee_damage_lower, surrounds_mult * melee_damage_upper), pick(attacktext), TRUE) else var/obj/structure/obstacle = locate(/obj/structure) in T - if(obstacle && !istype(obstacle, /obj/structure/golem_burrow)) + if(obstacle) obstacle.attack_generic(src, rand(surrounds_mult * melee_damage_lower, surrounds_mult * melee_damage_upper), pick(attacktext), TRUE) - -/mob/living/carbon/superior_animal/golem/handle_ai() - // Chance to re-aggro the drill if doing nothing - if((stance == HOSTILE_STANCE_IDLE) && prob(10)) - if(!busy) // if not busy with a special task - stop_automated_movement = FALSE - target_mob = DD - if(target_mob) - stance = HOSTILE_STANCE_ATTACK - . = ..() diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/ansible.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/ansible.dm index 07bfa2aa8f5..0147132337d 100644 --- a/code/modules/mob/living/carbon/superior_animal/golem/types/ansible.dm +++ b/code/modules/mob/living/carbon/superior_animal/golem/types/ansible.dm @@ -43,7 +43,7 @@ // Cooldown of special ability var/teleport_cooldown = 0 -/mob/living/carbon/superior_animal/golem/ansible/New(loc, obj/machinery/mining/deep_drill/drill, datum/golem_controller/parent) +/mob/living/carbon/superior_animal/golem/ansible/New() ..() set_light(3, 3, "#82C2D8") diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/diamond.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/diamond.dm index 5dadf5458db..e4406d9c739 100644 --- a/code/modules/mob/living/carbon/superior_animal/golem/types/diamond.dm +++ b/code/modules/mob/living/carbon/superior_animal/golem/types/diamond.dm @@ -31,38 +31,3 @@ // Loot related variables ore = /obj/item/ore/diamond - -// Special capacity of diamond golem: rush towards the drill without caring about pathplanning -/mob/living/carbon/superior_animal/golem/diamond/handle_ai() - - objectsInView = null - - //CONSCIOUS UNCONSCIOUS DEAD - - if(!check_AI_act()) - return FALSE - - switch(stance) - if(HOSTILE_STANCE_IDLE) - if(!busy) // if not busy with a special task - stop_automated_movement = FALSE - target_mob = DD - if(target_mob) - stance = HOSTILE_STANCE_ATTACK - - if(HOSTILE_STANCE_ATTACK) - destroySurroundings() - stop_automated_movement = TRUE - stance = HOSTILE_STANCE_ATTACKING - set_glide_size(DELAY2GLIDESIZE(move_to_delay)) - walk_towards(src, target_mob, 1, move_to_delay) - - if(HOSTILE_STANCE_ATTACKING) - destroySurroundings() - prepareAttackOnTarget() - - //Speaking - if(speak_chance && prob(speak_chance)) - visible_emote(emote_see) - - return TRUE diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/uranium.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/uranium.dm index a580da58f34..d8365c589c1 100644 --- a/code/modules/mob/living/carbon/superior_animal/golem/types/uranium.dm +++ b/code/modules/mob/living/carbon/superior_animal/golem/types/uranium.dm @@ -32,7 +32,7 @@ // Uranium golem does not attack viewRange = 0 // Cannot attack if it cannot see -/mob/living/carbon/superior_animal/golem/uranium/New(loc, obj/machinery/mining/deep_drill/drill, datum/golem_controller/parent) +/mob/living/carbon/superior_animal/golem/uranium/New() ..() set_light(3, 3, "#8AD55D") From ee39afb42ce3ee27307cff4d0bb81405555b22b5 Mon Sep 17 00:00:00 2001 From: Wrill <86113712+WrillWasTaken@users.noreply.github.com> Date: Tue, 21 Jan 2025 20:40:14 +0000 Subject: [PATCH 04/52] purge more references to the drill and controller --- .../mob/living/carbon/superior_animal/golem/golem.dm | 4 ---- .../living/carbon/superior_animal/golem/types/ansible.dm | 8 ++++++-- .../living/carbon/superior_animal/golem/types/coal.dm | 2 +- .../living/carbon/superior_animal/golem/types/uranium.dm | 9 +++++---- 4 files changed, 12 insertions(+), 11 deletions(-) diff --git a/code/modules/mob/living/carbon/superior_animal/golem/golem.dm b/code/modules/mob/living/carbon/superior_animal/golem/golem.dm index ecd6abc7bf2..6be50feb177 100644 --- a/code/modules/mob/living/carbon/superior_animal/golem/golem.dm +++ b/code/modules/mob/living/carbon/superior_animal/golem/golem.dm @@ -78,10 +78,6 @@ GLOBAL_LIST_INIT(golems_special, list(/mob/living/carbon/superior_animal/golem/s var/ore /mob/living/carbon/superior_animal/golem/death(gibbed, message = deathmessage) - if(controller) // Unlink from controller - controller.golems -= src - controller = null - . = ..() // Spawn ores diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/ansible.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/ansible.dm index 0147132337d..84b04a0c341 100644 --- a/code/modules/mob/living/carbon/superior_animal/golem/types/ansible.dm +++ b/code/modules/mob/living/carbon/superior_animal/golem/types/ansible.dm @@ -1,3 +1,5 @@ +#define ANSIBLE_TELEPORT_RANGE 7 //range from the ansible golem that the target can be teleported to, not the total distance the target can teleport + /mob/living/carbon/superior_animal/golem/ansible name = "ansible golem" desc = "A moving pile of rocks with ansible crystals in it." @@ -55,8 +57,8 @@ /mob/living/carbon/superior_animal/golem/ansible/proc/teleport_target() // Teleport target near random golem - if(target_mob && controller) - go_to_bluespace(target_mob.loc, 1, TRUE, target_mob, get_step(pick(controller.golems), pick(cardinal)), \ + if(target_mob) + go_to_bluespace(target_mob.loc, 1, TRUE, target_mob, get_step(pick(/mob/living/carbon/superior_animal/golem in range(ANSIBLE_TELEPORT_RANGE)), pick(cardinal)), \ 0, TRUE, null, null, 'sound/effects/teleport.ogg', 'sound/effects/teleport.ogg') /mob/living/carbon/superior_animal/golem/ansible/proc/focus_target() @@ -75,3 +77,5 @@ teleport_cooldown = world.time focus_target() . = ..() + +#undef ANSIBLE_TELEPORT_RANGE diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/coal.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/coal.dm index 7b4e3f791ae..63594ef19f8 100644 --- a/code/modules/mob/living/carbon/superior_animal/golem/types/coal.dm +++ b/code/modules/mob/living/carbon/superior_animal/golem/types/coal.dm @@ -34,7 +34,7 @@ /mob/living/carbon/superior_animal/golem/coal/handle_ai() if(on_fire) visible_message(SPAN_DANGER("\The [src] is engulfed by fire and turns into diamond!")) - new /mob/living/carbon/superior_animal/golem/diamond(loc, drill=DD, parent=controller) // Spawn diamond golem at location + new /mob/living/carbon/superior_animal/golem/diamond(loc) // Spawn diamond golem at location ore = null // So that the golem does not drop coal ores death(FALSE, "no message") . = ..() diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/uranium.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/uranium.dm index d8365c589c1..b91d8bcee58 100644 --- a/code/modules/mob/living/carbon/superior_animal/golem/types/uranium.dm +++ b/code/modules/mob/living/carbon/superior_animal/golem/types/uranium.dm @@ -1,3 +1,5 @@ +#define GOLEM_URANIUM_HEAL_RANGE 7 + /mob/living/carbon/superior_animal/golem/uranium name = "uranium golem" desc = "A moving pile of rocks with uranium specks in it." @@ -42,8 +44,7 @@ // Special capacity of uranium golem: quickly repair all nearby golems. /mob/living/carbon/superior_animal/golem/uranium/handle_ai() - if(controller) - for(var/mob/living/carbon/superior_animal/golem/GO in controller.golems) - if(!istype(GO, /mob/living/carbon/superior_animal/golem/uranium)) // Uraniums do not regen - GO.adjustBruteLoss(-GOLEM_REGENERATION) // Regeneration + for(var/mob/living/carbon/superior_animal/golem/GO in range(GOLEM_URANIUM_HEAL_RANGE)) + if(!istype(GO, /mob/living/carbon/superior_animal/golem/uranium)) // Uraniums do not regen + GO.adjustBruteLoss(-GOLEM_REGENERATION) // Regeneration . = ..() From 4375936a373ba177e8dc651978ad7df4bf6cf4cc Mon Sep 17 00:00:00 2001 From: Wrill <86113712+WrillWasTaken@users.noreply.github.com> Date: Wed, 22 Jan 2025 00:29:28 +0000 Subject: [PATCH 05/52] FIX ANSIBLE GOLEMS this should not have taken me 4 hours but it did so here we are. --- .../modules/mining/drilling/cave_generator.dm | 32 +++++++++---------- .../superior_animal/golem/types/ansible.dm | 14 ++++---- 2 files changed, 24 insertions(+), 22 deletions(-) diff --git a/code/modules/mining/drilling/cave_generator.dm b/code/modules/mining/drilling/cave_generator.dm index 9113c4ce6cf..04531383699 100644 --- a/code/modules/mining/drilling/cave_generator.dm +++ b/code/modules/mining/drilling/cave_generator.dm @@ -139,7 +139,7 @@ x1_new = x0_new y0_new = rand(CAVE_MARGIN, y0) y1_new = rand(y0, CAVE_SIZE - CAVE_MARGIN) - draw_recursive_corridor(x0_new, x1_new, y0_new, y1_new, N - 1) + draw_recursive_corridor(x0_new, x1_new, y0_new, y1_new, N - 1) // Run one iteration of the cellular automata that processes the initial random noise /obj/cave_generator/proc/run_cellular_automata() @@ -159,7 +159,7 @@ return CAVE_FREE else if(num_walls >= 5) return CAVE_WALL - + return CAVE_FREE // Get number of walls in a given range around the target tile @@ -172,7 +172,7 @@ return num_walls // Place points of interest on the map -/obj/cave_generator/proc/generate_pois(seismic_lvl) +/obj/cave_generator/proc/generate_pois(seismic_lvl) // Reset pois lists pois_placed = list() @@ -217,11 +217,11 @@ pois_placed_pos += list(list(x_corner_bl, y_corner_bl, x_corner_tr, y_corner_tr)) // Check if a potential poi does not overlap with already placed pois -/obj/cave_generator/proc/check_poi_overlap(x_bl, y_bl, size_x, size_y) +/obj/cave_generator/proc/check_poi_overlap(x_bl, y_bl, size_x, size_y) if(!pois_placed.len) // No overlap since no poi has been placed yet return TRUE - + var/x_tr = x_bl + size_x var/y_tr = y_bl + size_y for(var/k = 1 to pois_placed.len) @@ -229,14 +229,14 @@ // If top right corner is on the left or under the bottom left corner of already placed poi, then it's clear // Otherwise it means they overlap var/list/placed_pos = pois_placed_pos[k] - + if(!(x_bl > placed_pos[3] || y_bl > placed_pos[4] || x_tr < placed_pos[1] || y_tr < placed_pos[2])) return FALSE // No overlap return TRUE // Generate mineral veins once cave layout has been decided -/obj/cave_generator/proc/generate_mineral_veins(seismic_lvl) +/obj/cave_generator/proc/generate_mineral_veins(seismic_lvl) var/x_vein = 0 var/y_vein = 0 var/N_veins = rand(15, 20 * (1 + 0.5 * (seismic_lvl - SEISMIC_MIN) / (SEISMIC_MAX - SEISMIC_MIN))) @@ -250,7 +250,7 @@ // Find a free spot in the cave /obj/cave_generator/proc/find_free_spot(x_start, y_start, x_margin = 0, y_margin = 0) - var/x0 = x_start - 1 + var/x0 = x_start - 1 var/x1 = x_start + 1 var/y0 = y_start - 1 var/y1 = y_start + 1 @@ -270,14 +270,14 @@ y_start = y1 else found = FALSE - + if(!found) x0-- x1++ y0-- y1++ edge = (x0 <= 1 + x_margin) || (x1 >= CAVE_SIZE - x_margin) || (y0 <= 1 + y_margin) || (y1 >= CAVE_SIZE - y_margin) - + // Hit an edge before finding an available spot if(!found) return list(FALSE, 0, 0) @@ -421,7 +421,7 @@ // Find closest available spot (wall tile near a free tile) var/search_for = map[x_start][y_start] == CAVE_FREE ? CAVE_WALL : CAVE_FREE - var/x0 = x_start - 1 + var/x0 = x_start - 1 var/x1 = x_start + 1 var/y0 = y_start - 1 var/y1 = y_start + 1 @@ -447,14 +447,14 @@ y_start = y1 else found = FALSE - + if(!found) x0-- x1++ y0-- y1++ edge = (x0 == 1) || (x1 == CAVE_SIZE) || (y0 == 1) || (y1 == CAVE_SIZE) - + // Hit an edge before finding an available spot if(!found) return 0 @@ -477,7 +477,7 @@ var/datum/cave_vein/CV = new vein_path() // Place mineral vein at the available spot in a recursive manner - place_recursive_mineral(x_start, y_start, CV.p_spread, CV.size_max, CV.size_min, CV.mineral) + place_recursive_mineral(x_start, y_start, CV.p_spread, CV.size_max, CV.size_min, CV.mineral) return 1 // Place a mineral vein in a recursive manner @@ -580,7 +580,7 @@ /obj/cave_generator/proc/place_pois() if(!LAZYLEN(pois_placed)) return - + for(var/k = 1 to LAZYLEN(pois_placed)) var/turf/corner_turf = get_turf(locate(x + pois_placed_pos[k][1], y + pois_placed_pos[k][2], z)) pois_placed[k].load(corner_turf) @@ -597,7 +597,7 @@ else golem_type = pick(GLOB.golems_normal) // Spawn golem at free location - new golem_type(get_turf(locate(x + i, y + j, z)), drill=null, parent=null) + new golem_type(get_turf(locate(x + i, y + j, z))) ////////////////////////////// // Mineral veins for the cave generator diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/ansible.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/ansible.dm index 84b04a0c341..5d7c94fd75b 100644 --- a/code/modules/mob/living/carbon/superior_animal/golem/types/ansible.dm +++ b/code/modules/mob/living/carbon/superior_animal/golem/types/ansible.dm @@ -43,7 +43,7 @@ kept_distance = 3 // Cooldown of special ability - var/teleport_cooldown = 0 + var/teleport_cooldown = -90 SECONDS // negative so that it isn't on cooldown at round start /mob/living/carbon/superior_animal/golem/ansible/New() ..() @@ -56,10 +56,14 @@ // Special capacity of ansible golem: it will focus and teleport a miner near other golems /mob/living/carbon/superior_animal/golem/ansible/proc/teleport_target() - // Teleport target near random golem + // Teleport target to a random golem near the ansible golem if(target_mob) - go_to_bluespace(target_mob.loc, 1, TRUE, target_mob, get_step(pick(/mob/living/carbon/superior_animal/golem in range(ANSIBLE_TELEPORT_RANGE)), pick(cardinal)), \ - 0, TRUE, null, null, 'sound/effects/teleport.ogg', 'sound/effects/teleport.ogg') + var/list/teleport_destinations = list() + + for(var/mob/living/carbon/superior_animal/golem/td in range(ANSIBLE_TELEPORT_RANGE, get_turf(src))) + teleport_destinations += td + + go_to_bluespace(get_turf(src), 1, TRUE, target_mob,pick(teleport_destinations)) /mob/living/carbon/superior_animal/golem/ansible/proc/focus_target() @@ -77,5 +81,3 @@ teleport_cooldown = world.time focus_target() . = ..() - -#undef ANSIBLE_TELEPORT_RANGE From 47c9f9126097bedfa27dc43a344fb80302e321da Mon Sep 17 00:00:00 2001 From: Wrill <86113712+WrillWasTaken@users.noreply.github.com> Date: Wed, 22 Jan 2025 14:03:28 +0000 Subject: [PATCH 06/52] uranium golems also heal burn damage --- .../mob/living/carbon/superior_animal/golem/types/uranium.dm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/uranium.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/uranium.dm index b91d8bcee58..5526cf5a758 100644 --- a/code/modules/mob/living/carbon/superior_animal/golem/types/uranium.dm +++ b/code/modules/mob/living/carbon/superior_animal/golem/types/uranium.dm @@ -46,5 +46,6 @@ /mob/living/carbon/superior_animal/golem/uranium/handle_ai() for(var/mob/living/carbon/superior_animal/golem/GO in range(GOLEM_URANIUM_HEAL_RANGE)) if(!istype(GO, /mob/living/carbon/superior_animal/golem/uranium)) // Uraniums do not regen - GO.adjustBruteLoss(-GOLEM_REGENERATION) // Regeneration + GO.adjustBruteLoss(-GOLEM_REGENERATION) // Brute Regeneration + GO.adjustFireLoss(-GOLEM_REGENERATION) // Burn Regeneration . = ..() From a3c1b0cb4257ad68cb90e2ee606deca8b9c416c5 Mon Sep 17 00:00:00 2001 From: Wrill <86113712+WrillWasTaken@users.noreply.github.com> Date: Wed, 22 Jan 2025 14:45:32 +0000 Subject: [PATCH 07/52] adjust drill turf checks --- code/modules/mining/drilling/deep_drill.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mining/drilling/deep_drill.dm b/code/modules/mining/drilling/deep_drill.dm index 22d0dc76367..cdb16bea01c 100644 --- a/code/modules/mining/drilling/deep_drill.dm +++ b/code/modules/mining/drilling/deep_drill.dm @@ -197,7 +197,7 @@ /obj/machinery/mining/deep_drill/proc/check_surroundings() // Check if there are no walls around the drill for(var/turf/F in block(locate(x - 1, y - 1, z), locate(x + 1, y + 1, z))) - if(!istype(F,/turf/floor)) + if(!istype(F,/turf/floor) && !istype(F,/turf/space)) //if it's not a floor and not space it's probably an obstacle. return TRUE return FALSE From f22cf4073c5f85334846afe15618d1327fa88310 Mon Sep 17 00:00:00 2001 From: Wrill <86113712+WrillWasTaken@users.noreply.github.com> Date: Wed, 22 Jan 2025 14:57:47 +0000 Subject: [PATCH 08/52] replace floor turfs under the drill with asteroid, instead of just damaging them --- code/modules/mining/drilling/deep_drill.dm | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/code/modules/mining/drilling/deep_drill.dm b/code/modules/mining/drilling/deep_drill.dm index cdb16bea01c..52e201374c6 100644 --- a/code/modules/mining/drilling/deep_drill.dm +++ b/code/modules/mining/drilling/deep_drill.dm @@ -73,7 +73,9 @@ T.gets_dug() else if(istype(get_turf(src), /turf/floor)) var/turf/floor/T = get_turf(src) - T.explosion_act(200, null) + visible_message(SPAN_NOTICE("\The [src] drills straight through the [T]!")) + T.ChangeTurf(/turf/floor/asteroid) //turn it back into an asteroid, otherwise things like platings become underplatings which makes no sense + /obj/machinery/mining/deep_drill/attackby(obj/item/I, mob/user as mob) From 189a4146597ff7f8231903df6a4d669e51f298d7 Mon Sep 17 00:00:00 2001 From: Wrill <86113712+WrillWasTaken@users.noreply.github.com> Date: Wed, 22 Jan 2025 15:56:28 +0000 Subject: [PATCH 09/52] adjust the drill's checks --- code/modules/mining/drilling/deep_drill.dm | 30 ++++++++++------------ 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/code/modules/mining/drilling/deep_drill.dm b/code/modules/mining/drilling/deep_drill.dm index 52e201374c6..616ce5ffaad 100644 --- a/code/modules/mining/drilling/deep_drill.dm +++ b/code/modules/mining/drilling/deep_drill.dm @@ -73,7 +73,7 @@ T.gets_dug() else if(istype(get_turf(src), /turf/floor)) var/turf/floor/T = get_turf(src) - visible_message(SPAN_NOTICE("\The [src] drills straight through the [T]!")) + visible_message(SPAN_NOTICE("\The [src] drills straight through the [T], exposing the asteroid underneath!")) T.ChangeTurf(/turf/floor/asteroid) //turn it back into an asteroid, otherwise things like platings become underplatings which makes no sense @@ -147,15 +147,17 @@ /obj/machinery/mining/deep_drill/attack_hand(mob/user as mob) if(!panel_open) - if(health == 0) - to_chat(user, SPAN_NOTICE("The drill is too damaged to be turned on.")) - else if(!anchored) - to_chat(user, SPAN_NOTICE("The drill needs to be anchored to be turned on.")) - else if(!cave_connected && check_surroundings()) - to_chat(user, SPAN_WARNING("The space around \the [src] has to be clear of obstacles!")) - - if(!cave_connected) - if(cave_gen.is_generating()) + if(cave_connected) //there are no restrictions on turning off the drill besides the panel being shut. + shutdown_drill(null,DRILL_SHUTDOWN_LOG_MANUAL) + to_chat(user, SPAN_NOTICE("You turn off \the [src], collapsing the attached cave system.")) + else + if(health == 0) + to_chat(user, SPAN_NOTICE("\The [src] is too damaged to turn on!")) + else if(!anchored) + to_chat(user, SPAN_NOTICE("\The [src] needs to be anchored to be turned on.")) + else if(check_surroundings()) + to_chat(user, SPAN_WARNING("The space around \the [src] has to be clear of obstacles!")) + else if(cave_gen.is_generating()) to_chat(user, SPAN_WARNING("A cave system is already being dug.")) else if(cave_gen.is_opened()) to_chat(user, SPAN_WARNING("A cave system is already being explored.")) @@ -163,15 +165,11 @@ to_chat(user, SPAN_WARNING("The cave system is being collapsed!")) else if(!cave_gen.check_cooldown()) to_chat(user, SPAN_WARNING("The asteroid structure is too unstable for now to open a new cave system. Best to take your current haul to the ship, miner!\nYou have to wait [cave_gen.remaining_cooldown()] minutes.")) - else + else //if we've gotten this far all the checks have succeeded so we can turn it on and gen a cave var/turf/T = get_turf(loc) cave_connected = cave_gen.place_ladders(loc.x, loc.y, loc.z, T.seismic_activity) - update_icon() - else - shutdown_drill(null,DRILL_SHUTDOWN_LOG_MANUAL) - else - to_chat(user, SPAN_NOTICE("Turning on a piece of industrial machinery with wires exposed is a bad idea.")) + to_chat(user, SPAN_NOTICE("Turning on a piece of industrial machinery with wires exposed seems like a bad idea.")) update_icon() From cf3f6ad37eb557fe83e29cc7d9e493dad098bd41 Mon Sep 17 00:00:00 2001 From: Wrill <86113712+WrillWasTaken@users.noreply.github.com> Date: Wed, 22 Jan 2025 16:29:42 +0000 Subject: [PATCH 10/52] fix uranium regen --- code/modules/mining/drilling/deep_drill.dm | 2 +- .../living/carbon/superior_animal/golem/types/uranium.dm | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/code/modules/mining/drilling/deep_drill.dm b/code/modules/mining/drilling/deep_drill.dm index 616ce5ffaad..8730e69ef3d 100644 --- a/code/modules/mining/drilling/deep_drill.dm +++ b/code/modules/mining/drilling/deep_drill.dm @@ -169,7 +169,7 @@ var/turf/T = get_turf(loc) cave_connected = cave_gen.place_ladders(loc.x, loc.y, loc.z, T.seismic_activity) else - to_chat(user, SPAN_NOTICE("Turning on a piece of industrial machinery with wires exposed seems like a bad idea.")) + to_chat(user, SPAN_NOTICE("Operating a piece of industrial machinery with wires exposed seems like a bad idea.")) update_icon() diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/uranium.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/uranium.dm index 5526cf5a758..fc782c0116d 100644 --- a/code/modules/mob/living/carbon/superior_animal/golem/types/uranium.dm +++ b/code/modules/mob/living/carbon/superior_animal/golem/types/uranium.dm @@ -44,8 +44,8 @@ // Special capacity of uranium golem: quickly repair all nearby golems. /mob/living/carbon/superior_animal/golem/uranium/handle_ai() - for(var/mob/living/carbon/superior_animal/golem/GO in range(GOLEM_URANIUM_HEAL_RANGE)) - if(!istype(GO, /mob/living/carbon/superior_animal/golem/uranium)) // Uraniums do not regen - GO.adjustBruteLoss(-GOLEM_REGENERATION) // Brute Regeneration - GO.adjustFireLoss(-GOLEM_REGENERATION) // Burn Regeneration + for(var/mob/living/carbon/superior_animal/golem/G in range(GOLEM_URANIUM_HEAL_RANGE,get_turf(src))) + if(!istype(G, /mob/living/carbon/superior_animal/golem/uranium)) // Uraniums do not regen + G.adjustBruteLoss(-GOLEM_REGENERATION) // Brute Regeneration + G.adjustFireLoss(-GOLEM_REGENERATION) // Burn Regeneration . = ..() From baa5bf4bdb99bab32f546cc25764738029247be1 Mon Sep 17 00:00:00 2001 From: Wrill <86113712+WrillWasTaken@users.noreply.github.com> Date: Wed, 5 Feb 2025 22:06:33 +0000 Subject: [PATCH 11/52] weighted golem spawning --- cev_eris.dme | 1 + .../modules/mining/drilling/cave_generator.dm | 57 ++++++++++++++++--- .../superior_animal/golem/types/gold.dm | 30 ++++++++++ 3 files changed, 81 insertions(+), 7 deletions(-) create mode 100644 code/modules/mob/living/carbon/superior_animal/golem/types/gold.dm diff --git a/cev_eris.dme b/cev_eris.dme index 6cbeb81d22f..71e0832d7a5 100644 --- a/cev_eris.dme +++ b/cev_eris.dme @@ -1994,6 +1994,7 @@ #include "code\modules\mob\living\carbon\superior_animal\golem\types\ansible.dm" #include "code\modules\mob\living\carbon\superior_animal\golem\types\coal.dm" #include "code\modules\mob\living\carbon\superior_animal\golem\types\diamond.dm" +#include "code\modules\mob\living\carbon\superior_animal\golem\types\gold.dm" #include "code\modules\mob\living\carbon\superior_animal\golem\types\iron.dm" #include "code\modules\mob\living\carbon\superior_animal\golem\types\plasma.dm" #include "code\modules\mob\living\carbon\superior_animal\golem\types\platinum.dm" diff --git a/code/modules/mining/drilling/cave_generator.dm b/code/modules/mining/drilling/cave_generator.dm index 04531383699..f3382719645 100644 --- a/code/modules/mining/drilling/cave_generator.dm +++ b/code/modules/mining/drilling/cave_generator.dm @@ -28,6 +28,8 @@ #define CAVE_GOLD 9 #define CAVE_PLATINUM 10 +#define GOLEM_SPAWN_FACTOR 0.1 // multiplier for the chance for a golem cluster to spawn on each tile + ////////////////////////////// // Generator used to handle underground caves ////////////////////////////// @@ -588,16 +590,55 @@ // Spawn golems on free turfs depending on seismic level /obj/cave_generator/proc/place_golems(seismic_lvl) - var/golem_type + var/list/mob/living/carbon/superior_animal/golem/golems_to_spawn = list() for(var/i = 1 to CAVE_SIZE) for(var/j = 1 to CAVE_SIZE) - if(map[i][j] == CAVE_FREE && prob(2 + seismic_lvl)) - if(prob(4 * seismic_lvl)) // Probability of special golem - golem_type = pick(GLOB.golems_special) - else - golem_type = pick(GLOB.golems_normal) + if(map[i][j] == CAVE_FREE && prob((2 + seismic_lvl) * GOLEM_SPAWN_FACTOR)) + switch(seismic_lvl) + if(1,2) //easy: pick 5 random golems + var/weights = list( + /mob/living/carbon/superior_animal/golem/iron = 3, + /mob/living/carbon/superior_animal/golem/coal = 2, + /mob/living/carbon/superior_animal/golem/silver = (seismic_lvl == 2) ? 2 : 0) //0 weight on seismic 1, 2 weight on seismic 2. + + golems_to_spawn += pickweight_mult(weights, 5) + + if(3,4) //medium: guarantee 1 melee, 1 ranged/special and then pick 3 random + var/melee_weights = list( + /mob/living/carbon/superior_animal/golem/iron = 4, + /mob/living/carbon/superior_animal/golem/coal = 2, + /mob/living/carbon/superior_animal/golem/platinum = 3, + /mob/living/carbon/superior_animal/golem/plasma = (seismic_lvl == 4) ? 2 : 0) + + var/ranged_weights = list( + /mob/living/carbon/superior_animal/golem/silver = 3, + /mob/living/carbon/superior_animal/golem/uranium = 1) + + golems_to_spawn += pickweight(melee_weights) + golems_to_spawn += pickweight(ranged_weights) + golems_to_spawn += pickweight_mult(melee_weights + ranged_weights, 3) + + if(5,6) // HELL: guarantee 2 melee, 2 ranged/special and then pick 1 random golem + var/melee_weights = list( + /mob/living/carbon/superior_animal/golem/iron = 3, + /mob/living/carbon/superior_animal/golem/coal = 2, + /mob/living/carbon/superior_animal/golem/platinum = 3, + /mob/living/carbon/superior_animal/golem/plasma = 2, + /mob/living/carbon/superior_animal/golem/diamond = (seismic_lvl == 6) ? 2 : 0) + + var/ranged_weights = list( + /mob/living/carbon/superior_animal/golem/silver = 3, + /mob/living/carbon/superior_animal/golem/gold = 3, + /mob/living/carbon/superior_animal/golem/uranium = 2, + /mob/living/carbon/superior_animal/golem/ansible = (seismic_lvl == 6) ? 2 : 0) + + golems_to_spawn += pickweight_mult(melee_weights, 2) + golems_to_spawn += pickweight_mult(ranged_weights, 2) + golems_to_spawn += pickweight(ranged_weights + melee_weights) + // Spawn golem at free location - new golem_type(get_turf(locate(x + i, y + j, z))) + for(var/mob/living/carbon/superior_animal/golem/g in golems_to_spawn) + new g(get_turf(locate(x + i, y + j, z))) ////////////////////////////// // Mineral veins for the cave generator @@ -715,3 +756,5 @@ #undef CAVE_SILVER #undef CAVE_GOLD #undef CAVE_PLATINUM + +#undef GOLEM_SPAWN_FACTOR diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/gold.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/gold.dm new file mode 100644 index 00000000000..1cc78f11a92 --- /dev/null +++ b/code/modules/mob/living/carbon/superior_animal/golem/types/gold.dm @@ -0,0 +1,30 @@ +/mob/living/carbon/superior_animal/golem/gold + name = "gold golem" + desc = "A moving pile of rocks with hyper-malleable gold flowing through its cracks." + icon_state = "golem_gold" + icon_living = "golem_gold" + + // Health related variables + maxHealth = GOLEM_HEALTH_HIGH + health = GOLEM_HEALTH_HIGH + + // Movement related variables + move_to_delay = GOLEM_SPEED_SLUG + turns_per_move = 5 + + // Damage related variables + melee_damage_lower = GOLEM_DMG_FEEBLE + melee_damage_upper = GOLEM_DMG_LOW + + // Armor related variables + armor = list( + melee = 0, + bullet = GOLEM_ARMOR_HIGH, + energy = GOLEM_ARMOR_LOW, + bomb = 0, + bio = 0, + rad = 0 + ) + + // Loot related variables + ore = /obj/item/ore/gold From 5c0adf2fc017af45f23c31b763466fe0093618cb Mon Sep 17 00:00:00 2001 From: Wrill <86113712+WrillWasTaken@users.noreply.github.com> Date: Thu, 6 Feb 2025 23:01:15 +0000 Subject: [PATCH 12/52] finish reworking spawns --- .../modules/mining/drilling/cave_generator.dm | 59 +++++++++++++++---- .../carbon/superior_animal/golem/golem.dm | 1 + 2 files changed, 50 insertions(+), 10 deletions(-) diff --git a/code/modules/mining/drilling/cave_generator.dm b/code/modules/mining/drilling/cave_generator.dm index f3382719645..b5d0f912832 100644 --- a/code/modules/mining/drilling/cave_generator.dm +++ b/code/modules/mining/drilling/cave_generator.dm @@ -28,7 +28,11 @@ #define CAVE_GOLD 9 #define CAVE_PLATINUM 10 -#define GOLEM_SPAWN_FACTOR 0.1 // multiplier for the chance for a golem cluster to spawn on each tile +//minimum distance between spawned clusters. the spawn is canceled if it's lower than this. +#define GOLEM_SPAWN_SPACING 7.5 // +//chance for a cluster of 5 golems to spawn per tile, calculated as "GOLEM_SPAWN_CHANCE_BASE + (GOLEM_SPAWN_CHANCE_SCALING * seismic level)" +#define GOLEM_SPAWN_CHANCE_BASE 1.6 +#define GOLEM_SPAWN_CHANCE_SCALING 0.4 // 2% on level 1, 4% on level 6. ////////////////////////////// // Generator used to handle underground caves @@ -590,10 +594,20 @@ // Spawn golems on free turfs depending on seismic level /obj/cave_generator/proc/place_golems(seismic_lvl) - var/list/mob/living/carbon/superior_animal/golem/golems_to_spawn = list() + var/list/turf/golem_spawn_points = list() + for(var/i = 1 to CAVE_SIZE) for(var/j = 1 to CAVE_SIZE) - if(map[i][j] == CAVE_FREE && prob((2 + seismic_lvl) * GOLEM_SPAWN_FACTOR)) + if(map[i][j] == CAVE_FREE && prob(GOLEM_SPAWN_CHANCE_BASE + seismic_lvl * GOLEM_SPAWN_CHANCE_SCALING) && check_spawn_overlap(get_turf(locate(x + i, y + j, z)), golem_spawn_points)) + + var/turf/turf = get_turf(locate(x + i, y + j, z)) + + golem_spawn_points += turf + + //var/list/mob/golems_to_spawn = list() + + var/list/mob/living/carbon/superior_animal/golem/golems_to_spawn = list() + switch(seismic_lvl) if(1,2) //easy: pick 5 random golems var/weights = list( @@ -601,7 +615,8 @@ /mob/living/carbon/superior_animal/golem/coal = 2, /mob/living/carbon/superior_animal/golem/silver = (seismic_lvl == 2) ? 2 : 0) //0 weight on seismic 1, 2 weight on seismic 2. - golems_to_spawn += pickweight_mult(weights, 5) + for(var/c = 0, c < 5, c++) // I couldn't get pickweight_mult to work, so running pickweight 5 times is a more reliable solution + golems_to_spawn += pickweight(weights) if(3,4) //medium: guarantee 1 melee, 1 ranged/special and then pick 3 random var/melee_weights = list( @@ -616,7 +631,9 @@ golems_to_spawn += pickweight(melee_weights) golems_to_spawn += pickweight(ranged_weights) - golems_to_spawn += pickweight_mult(melee_weights + ranged_weights, 3) + + for(var/c = 0, c < 3, c++) + golems_to_spawn += pickweight(melee_weights + ranged_weights) if(5,6) // HELL: guarantee 2 melee, 2 ranged/special and then pick 1 random golem var/melee_weights = list( @@ -632,13 +649,33 @@ /mob/living/carbon/superior_animal/golem/uranium = 2, /mob/living/carbon/superior_animal/golem/ansible = (seismic_lvl == 6) ? 2 : 0) - golems_to_spawn += pickweight_mult(melee_weights, 2) - golems_to_spawn += pickweight_mult(ranged_weights, 2) + for(var/c = 0, c < 2, c++) + golems_to_spawn += pickweight(melee_weights) + golems_to_spawn += pickweight(ranged_weights) golems_to_spawn += pickweight(ranged_weights + melee_weights) // Spawn golem at free location - for(var/mob/living/carbon/superior_animal/golem/g in golems_to_spawn) - new g(get_turf(locate(x + i, y + j, z))) + for(var/golem in golems_to_spawn) + var/spawnturf = get_turf(locate(turf.x + rand(-1,1), turf.y + rand(-1,1), turf.z)) // slightly randomize the spawn turfs so golems don't spawn in a doomstack + new golem(spawnturf) + + for(var/c = 1 to golem_spawn_points.len) + log_world(golem_spawn_points[c]) + +/obj/cave_generator/proc/check_spawn_overlap(target_turf,list/pointlist) + if(!(target_turf && pointlist)) + return FALSE + + var/lowest_distance = 500 + + for(var/turf/t in pointlist) + if(get_dist_euclidian(target_turf, t) < GOLEM_SPAWN_SPACING) + log_world("skipping a coordinate with distance [get_dist_euclidian(target_turf, t)]") + lowest_distance = get_dist_euclidian(target_turf, t) < lowest_distance ? get_dist_euclidian(target_turf, t) : lowest_distance + return FALSE + + log_world("spawning on a coordinate with lowest distance [lowest_distance]") + return TRUE ////////////////////////////// // Mineral veins for the cave generator @@ -757,4 +794,6 @@ #undef CAVE_GOLD #undef CAVE_PLATINUM -#undef GOLEM_SPAWN_FACTOR +#undef GOLEM_SPAWN_CHANCE_BASE +#undef GOLEM_SPAWN_CHANCE_SCALING +#undef GOLEM_SPAWN_SPACING diff --git a/code/modules/mob/living/carbon/superior_animal/golem/golem.dm b/code/modules/mob/living/carbon/superior_animal/golem/golem.dm index 6be50feb177..14493dce957 100644 --- a/code/modules/mob/living/carbon/superior_animal/golem/golem.dm +++ b/code/modules/mob/living/carbon/superior_animal/golem/golem.dm @@ -56,6 +56,7 @@ GLOBAL_LIST_INIT(golems_special, list(/mob/living/carbon/superior_animal/golem/s meat_type = null meat_amount = 0 stop_automated_movement_when_pulled = 0 + wander = FALSE destroy_surroundings = TRUE From 92ab120d2d19eee34af0d6437c39916775880576 Mon Sep 17 00:00:00 2001 From: Wrill <86113712+WrillWasTaken@users.noreply.github.com> Date: Fri, 7 Feb 2025 12:33:27 +0000 Subject: [PATCH 13/52] golem adjustments + remove debug prints --- .../modules/mining/drilling/cave_generator.dm | 6 +-- .../carbon/superior_animal/golem/golem.dm | 20 ++++---- .../superior_animal/golem/types/ansible.dm | 2 +- .../superior_animal/golem/types/diamond.dm | 2 +- .../superior_animal/golem/types/plasma.dm | 50 ++++++------------- .../superior_animal/golem/types/platinum.dm | 13 +---- .../superior_animal/golem/types/silver.dm | 28 ++++++++--- .../superior_animal/golem/types/uranium.dm | 2 +- 8 files changed, 51 insertions(+), 72 deletions(-) diff --git a/code/modules/mining/drilling/cave_generator.dm b/code/modules/mining/drilling/cave_generator.dm index b5d0f912832..83561a2142a 100644 --- a/code/modules/mining/drilling/cave_generator.dm +++ b/code/modules/mining/drilling/cave_generator.dm @@ -59,6 +59,7 @@ var/list/blacklist = list(/mob/observer, /obj/machinery/nuclearbomb, /obj/item/disk/nuclear) + var/list/generated_golems = list() //golems use this for targeting allies /obj/cave_generator/Initialize() // Initialize and not New to ensure SSmapping.maploader has been created @@ -666,15 +667,10 @@ if(!(target_turf && pointlist)) return FALSE - var/lowest_distance = 500 - for(var/turf/t in pointlist) if(get_dist_euclidian(target_turf, t) < GOLEM_SPAWN_SPACING) - log_world("skipping a coordinate with distance [get_dist_euclidian(target_turf, t)]") - lowest_distance = get_dist_euclidian(target_turf, t) < lowest_distance ? get_dist_euclidian(target_turf, t) : lowest_distance return FALSE - log_world("spawning on a coordinate with lowest distance [lowest_distance]") return TRUE ////////////////////////////// diff --git a/code/modules/mob/living/carbon/superior_animal/golem/golem.dm b/code/modules/mob/living/carbon/superior_animal/golem/golem.dm index 14493dce957..9370381dfe0 100644 --- a/code/modules/mob/living/carbon/superior_animal/golem/golem.dm +++ b/code/modules/mob/living/carbon/superior_animal/golem/golem.dm @@ -21,17 +21,7 @@ #define GOLEM_REGENERATION 10 // Healing by special ability of uranium golems -// Normal types of golems -GLOBAL_LIST_INIT(golems_normal, list(/mob/living/carbon/superior_animal/golem/coal, - /mob/living/carbon/superior_animal/golem/iron)) - -// Special types of golems -GLOBAL_LIST_INIT(golems_special, list(/mob/living/carbon/superior_animal/golem/silver, - /mob/living/carbon/superior_animal/golem/plasma, - /mob/living/carbon/superior_animal/golem/platinum, - /mob/living/carbon/superior_animal/golem/diamond, - /mob/living/carbon/superior_animal/golem/ansible, - /mob/living/carbon/superior_animal/golem/uranium)) +GLOBAL_LIST_EMPTY(all_golems) // golems check this list to target allies // OneStar patrol borg that defends OneStar facilities /mob/living/carbon/superior_animal/golem @@ -78,6 +68,14 @@ GLOBAL_LIST_INIT(golems_special, list(/mob/living/carbon/superior_animal/golem/s // Type of ore to spawn when the golem dies var/ore +/mob/living/carbon/superior_animal/golem/Initialize(var/mapload) + GLOB.all_golems += src + .=..() + +/mob/living/carbon/superior_animal/golem/Destroy() + GLOB.all_golems -= src + ..() + /mob/living/carbon/superior_animal/golem/death(gibbed, message = deathmessage) . = ..() diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/ansible.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/ansible.dm index 5d7c94fd75b..3a6368e0605 100644 --- a/code/modules/mob/living/carbon/superior_animal/golem/types/ansible.dm +++ b/code/modules/mob/living/carbon/superior_animal/golem/types/ansible.dm @@ -2,7 +2,7 @@ /mob/living/carbon/superior_animal/golem/ansible name = "ansible golem" - desc = "A moving pile of rocks with ansible crystals in it." + desc = "A moving pile of rocks dotted with ansible crystals, each bursting with energy." icon_state = "golem_ansible_idle" icon_living = "golem_ansible_idle" diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/diamond.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/diamond.dm index e4406d9c739..c00d5e5f411 100644 --- a/code/modules/mob/living/carbon/superior_animal/golem/types/diamond.dm +++ b/code/modules/mob/living/carbon/superior_animal/golem/types/diamond.dm @@ -1,6 +1,6 @@ /mob/living/carbon/superior_animal/golem/diamond name = "diamond golem" - desc = "A moving pile of rocks with diamond specks in it." + desc = "A moving pile of rocks covered in glistening diamonds." icon_state = "golem_diamond" icon_living = "golem_diamond" diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/plasma.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/plasma.dm index e4b84d0fe2c..a9d4fc7449b 100644 --- a/code/modules/mob/living/carbon/superior_animal/golem/types/plasma.dm +++ b/code/modules/mob/living/carbon/superior_animal/golem/types/plasma.dm @@ -1,10 +1,9 @@ #define DET_STABLE 0 #define DET_BLOWING 1 -#define DET_DEFUSED 2 -/mob/living/carbon/superior_animal/golem/plasma +/mob/living/carbon/superior_animal/golem/plasma // plasma golems detonate instead of hitting targets, or prematurely when they're killed. name = "plasma golem" - desc = "A moving pile of rocks with plasma specks in it." + desc = "A moving pile of rocks with spikes of highly volatile plasma jutting out." icon_state = "golem_plasma" icon_living = "golem_plasma" @@ -33,47 +32,28 @@ // Loot related variables ore = /obj/item/ore/plasma - // Ranged attack related variables - ranged = TRUE // Will it shoot? - rapid = FALSE // Will it shoot fast? - projectiletype = /obj/item/projectile/plasma - projectilesound = 'sound/weapons/energy/burn.ogg' - casingtype = null - ranged_cooldown = 1 SECOND - fire_verb = "fires" - acceptableTargetDistance = 6 - kept_distance = 3 - // How much time before detonation - var/det_time = 5 SECONDS + var/det_time = 2.5 SECONDS var/det_status = DET_STABLE -// Special capacity of plasma golem: blow up upon death except if hit with melee weapon /mob/living/carbon/superior_animal/golem/plasma/death(gibbed, message = deathmessage) if(det_status == DET_STABLE) + src.Stun(10) //prevent any movement. not actually sure if this is necessary for a dead mob. det_status = DET_BLOWING - icon_state = "golem_plasma_idle" visible_message(SPAN_DANGER("\The [src] starts glowing!")) + icon_state = "golem_plasma_explosion" spawn(det_time) - if(det_status == DET_BLOWING) // Blowing up since no one defused it - icon_state = "golem_plasma_explosion" - spawn(1.5 SECONDS) - // Plasma ball on location - visible_message(SPAN_DANGER("\The [src] explodes into a ball of burning palsma!")) - for(var/turf/floor/target_tile in range(2, loc)) - new /obj/effect/decal/cleanable/liquid_fuel(target_tile, 2, 1) - spawn (0) target_tile.hotspot_expose((T20C * 2) + 380, 500) // From flamethrower code - . = ..() - else if(det_status == DET_DEFUSED) // Will triger when hit by melee while blowing - . = ..() + // Plasma ball on location + visible_message(SPAN_DANGER("\The [src] explodes into a ball of burning palsma!")) + for(var/turf/floor/target_tile in range(2, loc)) + new /obj/effect/decal/cleanable/liquid_fuel(target_tile, 2, 1) + spawn (0) target_tile.hotspot_expose((T20C * 2) + 380, 500) // From flamethrower code + . = ..() + +/mob/living/carbon/superior_animal/giant_spider/UnarmedAttack(atom/A, proximity) + if(det_status == DET_STABLE) + src.death(false, false) -// Called when the mob is hit with an item in combat. -/mob/living/carbon/superior_animal/golem/plasma/hit_with_weapon(obj/item/I, mob/living/user, var/effective_force, var/hit_zone) - if(det_status == DET_BLOWING) - det_status = DET_DEFUSED - icon_state = "golem_plasma" - . = ..() #undef DET_STABLE #undef DET_BLOWING -#undef DET_DEFUSED diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/platinum.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/platinum.dm index 10e9b7cfe7c..6c7043e107c 100644 --- a/code/modules/mob/living/carbon/superior_animal/golem/types/platinum.dm +++ b/code/modules/mob/living/carbon/superior_animal/golem/types/platinum.dm @@ -1,6 +1,6 @@ /mob/living/carbon/superior_animal/golem/platinum name = "platinum golem" - desc = "A moving pile of rocks with platinum specks in it." + desc = "A hulking pile of rocks with platinum rings running through it." icon_state = "golem_platinum" icon_living = "golem_platinum" @@ -28,14 +28,3 @@ // Loot related variables ore = /obj/item/ore/osmium - - // Ranged attack related variables - ranged = TRUE // Will it shoot? - rapid = FALSE // Will it shoot fast? - projectiletype = /obj/item/projectile/plasma/stun/heavy - projectilesound = 'sound/weapons/energy/burn.ogg' - casingtype = null - ranged_cooldown = 3 SECOND - fire_verb = "fires" - acceptableTargetDistance = 6 - kept_distance = 3 diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/silver.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/silver.dm index 46f21333520..68abcaee4a9 100644 --- a/code/modules/mob/living/carbon/superior_animal/golem/types/silver.dm +++ b/code/modules/mob/living/carbon/superior_animal/golem/types/silver.dm @@ -1,6 +1,6 @@ /mob/living/carbon/superior_animal/golem/silver name = "silver golem" - desc = "A moving pile of rocks with silver specks in it." + desc = "A moving pile of rocks lined with menacing silver spikes." icon_state = "golem_silver" icon_living = "golem_silver" @@ -30,9 +30,25 @@ // Loot related variables ore = /obj/item/ore/silver -// Special capacity of silver golem: when attacked in melee, it reflects part of the damage to the attacker. -// Called when the mob is hit with an item in combat. -/mob/living/carbon/superior_animal/golem/silver/hit_with_weapon(obj/item/I, mob/living/user, var/effective_force, var/hit_zone) + // Ranged attack related variables + ranged = TRUE // Will it shoot? + rapid = FALSE // Will it shoot fast? + projectiletype = /obj/item/projectile/plasma/stun/golem + projectilesound = 'sound/weapons/energy/burn.ogg' + casingtype = null + ranged_cooldown = 3 SECOND + fire_verb = "fires" + acceptableTargetDistance = 6 + kept_distance = 5 + +/obj/item/projectile/plasma/stun/golem //special projectile that passes straight through golems + name = "stun plasma bolt" + taser_effect = 1 + damage_types = list(HALLOSS = 30, BURN = 5) + impact_type = /obj/effect/projectile/stun/golem + +/obj/item/projectile/plasma/stun/golem/bump(atom/A as mob|obj|turf|area, forced = FALSE) + if(istype(A, /mob/living/carbon/superior_animal/golem)) + return FALSE . = ..() - visible_message(SPAN_DANGER("\The [src] reflects \the [I.name]!")) - user.hit_with_weapon(I, user, effective_force * 0.2, pick(BP_ALL_LIMBS)) + diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/uranium.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/uranium.dm index fc782c0116d..4a61e963243 100644 --- a/code/modules/mob/living/carbon/superior_animal/golem/types/uranium.dm +++ b/code/modules/mob/living/carbon/superior_animal/golem/types/uranium.dm @@ -2,7 +2,7 @@ /mob/living/carbon/superior_animal/golem/uranium name = "uranium golem" - desc = "A moving pile of rocks with uranium specks in it." + desc = "A moving pile of rocks with uranium branches growing of it." icon_state = "golem_uranium_idle" icon_living = "golem_uranium_idle" From ccb72bc927478ddfcd3e38b4f2bed7fba990e881 Mon Sep 17 00:00:00 2001 From: Wrill <86113712+WrillWasTaken@users.noreply.github.com> Date: Sat, 8 Feb 2025 22:58:07 +0000 Subject: [PATCH 14/52] finally get platinum charges working. mostly. there's still an issue where they'll stay locked onto their target permanently once they charge. --- code/__HELPERS/turfs.dm | 9 +++ code/game/objects/effects/temporary_visual.dm | 4 ++ .../living/carbon/superior_animal/attack.dm | 9 ++- .../superior_animal/golem/types/plasma.dm | 4 +- .../superior_animal/golem/types/platinum.dm | 65 ++++++++++++++++++- .../superior_animal/golem/types/silver.dm | 4 +- 6 files changed, 87 insertions(+), 8 deletions(-) diff --git a/code/__HELPERS/turfs.dm b/code/__HELPERS/turfs.dm index cc62a2c4cdb..b90299fdfff 100644 --- a/code/__HELPERS/turfs.dm +++ b/code/__HELPERS/turfs.dm @@ -37,6 +37,15 @@ return FALSE return TRUE +//A copy of a proc above because sometimes you actually need to check if turf is clear no matter if it has wires or pipes or mobs +/proc/turf_clear_ignore_cables_and_mobs(turf/T) + if (T.density) + return FALSE + for(var/atom/A in T) + if(A.density && !istype(A, /mob/living)) + return FALSE + return TRUE + /proc/clear_interior(var/turf/T) if (turf_clear(T)) if (!turf_is_external(T)) diff --git a/code/game/objects/effects/temporary_visual.dm b/code/game/objects/effects/temporary_visual.dm index affd8d52dd8..9d102b2b624 100644 --- a/code/game/objects/effects/temporary_visual.dm +++ b/code/game/objects/effects/temporary_visual.dm @@ -34,3 +34,7 @@ if(set_dir) dir = set_dir . = ..() + +/obj/effect/temp_visual/long //temp visual with longer duration + randomdir = FALSE + duration = 25 diff --git a/code/modules/mob/living/carbon/superior_animal/attack.dm b/code/modules/mob/living/carbon/superior_animal/attack.dm index a421505a764..807ed220a73 100644 --- a/code/modules/mob/living/carbon/superior_animal/attack.dm +++ b/code/modules/mob/living/carbon/superior_animal/attack.dm @@ -1,11 +1,16 @@ /mob/living/carbon/superior_animal/attack_ui(slot_id) return -/mob/living/carbon/superior_animal/UnarmedAttack(atom/A, var/proximity) +/mob/living/carbon/superior_animal/UnarmedAttack(atom/A, var/proximity, var/attackdamage) if(!..()) return - var/damage = rand(melee_damage_lower, melee_damage_upper) + var/damage + + if(attackdamage) // this allows damage to be overridden, for special cases like the platinum golem's charge + damage = attackdamage + else + damage = rand(melee_damage_lower, melee_damage_upper) . = A.attack_generic(src, damage, pick(attacktext), environment_smash, melee_sharp, melee_edge, wound_mult) if(.) diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/plasma.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/plasma.dm index a9d4fc7449b..2b16f665968 100644 --- a/code/modules/mob/living/carbon/superior_animal/golem/types/plasma.dm +++ b/code/modules/mob/living/carbon/superior_animal/golem/types/plasma.dm @@ -50,9 +50,9 @@ spawn (0) target_tile.hotspot_expose((T20C * 2) + 380, 500) // From flamethrower code . = ..() -/mob/living/carbon/superior_animal/giant_spider/UnarmedAttack(atom/A, proximity) +/mob/living/carbon/superior_animal/golem/plasma/UnarmedAttack(atom/A, proximity) if(det_status == DET_STABLE) - src.death(false, false) + src.death(FALSE, FALSE) #undef DET_STABLE diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/platinum.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/platinum.dm index 6c7043e107c..82fbe1b71ef 100644 --- a/code/modules/mob/living/carbon/superior_animal/golem/types/platinum.dm +++ b/code/modules/mob/living/carbon/superior_animal/golem/types/platinum.dm @@ -1,6 +1,12 @@ -/mob/living/carbon/superior_animal/golem/platinum +#define PLATINUM_CHARGE_DAMAGE_OBSTACLES 50 +#define PLATINUM_CHARGE_DAMAGE_TARGET 50 +#define PLATINUM_CHARGE_CD 30 SECONDS +#define PLATINUM_CHARGE_WINDUP 1.5 SECONDS +#define PLATINUM_CHARGE_RANGE 5 + +/mob/living/carbon/superior_animal/golem/platinum // platinum golems charge at the player for heavy damage. the charge can be dodged. name = "platinum golem" - desc = "A hulking pile of rocks with platinum rings running through it." + desc = "A sleek-looking pile of rocks with platinum rings running through it." icon_state = "golem_platinum" icon_living = "golem_platinum" @@ -28,3 +34,58 @@ // Loot related variables ore = /obj/item/ore/osmium + + var/charge_verbs = list("launches itself", "charges", "rams") + var/charge_cooldown = 0 + +/mob/living/carbon/superior_animal/golem/platinum/handle_ai() // half of this proc is just the visuals. the visuals are irritatingly difficult with this method of actually charging + . = ..() + + if(target_mob && (world.time > charge_cooldown) && (get_dist_euclidian(src, target_mob) < PLATINUM_CHARGE_RANGE)) + charge_cooldown = world.time + PLATINUM_CHARGE_CD + + walk(src,0) // halt movement + visible_message(SPAN_DANGER("[src] stops and prepares to charge at [target_mob]!"), 1) + var/list/passedturfs = getline(src, target_mob) // do this at the start of the windup, so that the golem's charge doesn't track the target (and it can be dodged) + + spawn(PLATINUM_CHARGE_WINDUP) + var/turf/lastvalidturf // I am not even going to pretend I understand how this proc works + passedturfs -= passedturfs[(passedturfs.len)] // cut off the end of the line so we stop right before the target + var/vfxindex = passedturfs.len - 1 + var/vfxfalloff = 250 / (passedturfs.len - 1) + + + for(var/turf/targetturf in passedturfs) + if(turf_clear_ignore_cables_and_mobs(targetturf)) + lastvalidturf = targetturf + vfxindex-- + + new /obj/effect/decal/cleanable/rubble(targetturf) + + if(vfxindex >= 0) //every turf except the one we end on. + var/obj/effect/temp_visual/long/charge_effect = new /obj/effect/temp_visual/long(targetturf) + charge_effect.icon = icon + charge_effect.icon_state = icon_state // copy over the icon and direction + charge_effect.dir = dir + charge_effect.alpha = 250 - (vfxfalloff * vfxindex) // todo: linear interpolation math so that this looks consistent at all distances + animate(charge_effect, time = 25 - ((vfxfalloff * vfxindex) / 10), alpha = 0) + + for(var/mob/living/victim in targetturf.contents) + if(victim != src) + victim.adjustBruteLoss(PLATINUM_CHARGE_DAMAGE_OBSTACLES) + else + for(var/atom/victim in targetturf.contents) + victim.explosion_act(PLATINUM_CHARGE_DAMAGE_OBSTACLES * 4) //TEAR THROUGH ALL THAT IMPEDES YOU + break // if the turf is blocked (ie a wall/door/window), stop charging here + + visible_message(SPAN_DANGER("[src] [pick(charge_verbs)] at [target_mob]!"), 1) + forceMove(lastvalidturf) + + if(Adjacent(target_mob)) + UnarmedAttack(target_mob, 1, PLATINUM_CHARGE_DAMAGE_TARGET) + + playsound(loc, 'sound/weapons/melee/blunthit.ogg', attack_sound_volume, 1) + walk_to(src, target_mob, 1, move_to_delay) // continue moving towards the target once the charge is finished + +#undef PLATINUM_CHARGE_DAMAGE_OBSTACLES +#undef PLATINUM_CHARGE_DAMAGE_TARGET diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/silver.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/silver.dm index 68abcaee4a9..697662a7d3e 100644 --- a/code/modules/mob/living/carbon/superior_animal/golem/types/silver.dm +++ b/code/modules/mob/living/carbon/superior_animal/golem/types/silver.dm @@ -45,9 +45,9 @@ name = "stun plasma bolt" taser_effect = 1 damage_types = list(HALLOSS = 30, BURN = 5) - impact_type = /obj/effect/projectile/stun/golem + impact_type = /obj/effect/projectile/stun/impact -/obj/item/projectile/plasma/stun/golem/bump(atom/A as mob|obj|turf|area, forced = FALSE) +/obj/item/projectile/plasma/stun/golem/Bump(atom/A as mob|obj|turf|area, forced = FALSE) if(istype(A, /mob/living/carbon/superior_animal/golem)) return FALSE . = ..() From 8e31aa27bb6e846bba244d26f48848a175653499 Mon Sep 17 00:00:00 2001 From: Wrill <86113712+WrillWasTaken@users.noreply.github.com> Date: Mon, 10 Feb 2025 00:15:46 +0000 Subject: [PATCH 15/52] get gold working still need to test coal!!! --- .../modules/mining/drilling/cave_generator.dm | 2 +- .../living/carbon/superior_animal/attack.dm | 2 +- .../superior_animal/golem/types/coal.dm | 24 +++++--- .../superior_animal/golem/types/gold.dm | 52 +++++++++++++++++- .../superior_animal/golem/types/silver.dm | 9 ++- .../superior_animal/golem/types/uranium.dm | 11 +--- .../carbon/superior_animal/superior_animal.dm | 5 +- icons/mob/golems.dmi | Bin 202114 -> 202467 bytes 8 files changed, 81 insertions(+), 24 deletions(-) diff --git a/code/modules/mining/drilling/cave_generator.dm b/code/modules/mining/drilling/cave_generator.dm index 83561a2142a..0db1c7b4473 100644 --- a/code/modules/mining/drilling/cave_generator.dm +++ b/code/modules/mining/drilling/cave_generator.dm @@ -645,7 +645,7 @@ /mob/living/carbon/superior_animal/golem/diamond = (seismic_lvl == 6) ? 2 : 0) var/ranged_weights = list( - /mob/living/carbon/superior_animal/golem/silver = 3, + /mob/living/carbon/superior_animal/golem/silver/enhanced = 3, /mob/living/carbon/superior_animal/golem/gold = 3, /mob/living/carbon/superior_animal/golem/uranium = 2, /mob/living/carbon/superior_animal/golem/ansible = (seismic_lvl == 6) ? 2 : 0) diff --git a/code/modules/mob/living/carbon/superior_animal/attack.dm b/code/modules/mob/living/carbon/superior_animal/attack.dm index 807ed220a73..59b1feff047 100644 --- a/code/modules/mob/living/carbon/superior_animal/attack.dm +++ b/code/modules/mob/living/carbon/superior_animal/attack.dm @@ -7,7 +7,7 @@ var/damage - if(attackdamage) // this allows damage to be overridden, for special cases like the platinum golem's charge + if(attackdamage) // this allows damage to be overridden, for special cases like the end of the platinum golem's charge damage = attackdamage else damage = rand(melee_damage_lower, melee_damage_upper) diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/coal.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/coal.dm index 63594ef19f8..5a17a7d7c42 100644 --- a/code/modules/mob/living/carbon/superior_animal/golem/types/coal.dm +++ b/code/modules/mob/living/carbon/superior_animal/golem/types/coal.dm @@ -1,3 +1,5 @@ +#define COAL_STUN_DURATION 10 + /mob/living/carbon/superior_animal/golem/coal name = "coal golem" desc = "A moving pile of rocks with coal clumps in it." @@ -29,12 +31,16 @@ // Loot related variables ore = /obj/item/ore/coal -// Special capacity of coal golem: when set on fire, it turns into a diamond golem -// Especially dangerous since uranium golem can explode into a fireball -/mob/living/carbon/superior_animal/golem/coal/handle_ai() - if(on_fire) - visible_message(SPAN_DANGER("\The [src] is engulfed by fire and turns into diamond!")) - new /mob/living/carbon/superior_animal/golem/diamond(loc) // Spawn diamond golem at location - ore = null // So that the golem does not drop coal ores - death(FALSE, "no message") - . = ..() +// enhanced coal golems will "grab" (stun) players, leaving them vulnerable to very high damage golems like gold and platinum +/mob/living/carbon/superior_animal/golem/coal/enhanced + name = "graphite golem" + desc = "A moving pile of rocks with unusually large hands and graphite chunks in it." + +/mob/living/carbon/superior_animal/golem/coal/enhanced/UnarmedAttack(atom/A, proximity) + if(istype(A, /mob/living/carbon)) + visible_message(SPAN_DANGER("[src] grabs at [target_mob]!"), 1) + playsound(src, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) + A.Stun(COAL_STUN_DURATION) + else // if they're not a carbon just attack them normally. this includes things like simple animals + . = ..() + diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/gold.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/gold.dm index 1cc78f11a92..527a9e841ff 100644 --- a/code/modules/mob/living/carbon/superior_animal/golem/types/gold.dm +++ b/code/modules/mob/living/carbon/superior_animal/golem/types/gold.dm @@ -1,3 +1,7 @@ +#define GOLD_SPIKE_COOLDOWN 50 // 5 seconds +#define GOLD_SPIKE_WINDUP 20 +#define GOLD_SPIKE_DAMAGE 40 //equivalent to GOLEM_DMG_HIGH + /mob/living/carbon/superior_animal/golem/gold name = "gold golem" desc = "A moving pile of rocks with hyper-malleable gold flowing through its cracks." @@ -26,5 +30,51 @@ rad = 0 ) + kept_distance = 4 + retreat_on_too_close = TRUE + // Loot related variables - ore = /obj/item/ore/gold + ore = /obj/item/ore/ + + var/spike_cooldown = 0 + +/mob/living/carbon/superior_animal/golem/gold/handle_ai() + if(isliving(target_mob) && ((spike_cooldown + GOLD_SPIKE_COOLDOWN) < world.time)) + spike_cooldown = world.time + spike_attack() + . = ..() + +/mob/living/carbon/superior_animal/golem/gold/proc/spike_attack() + var/list/turfstoattack = list() + turfstoattack += get_turf(target_mob) // always attack the turf with the target + for(var/turf/potentialturf in range(1,target_mob)) + if(prob(50) && !(/obj/golem_spike in potentialturf.contents)) // don't stack golem spikes + turfstoattack += potentialturf + + for(var/turf/targetturf in turfstoattack) + new /obj/golem_spike(targetturf) + +/obj/golem_spike + icon = 'icons/mob/golems.dmi' + icon_state = "goldspike_tip" + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + +/obj/golem_spike/Initialize() + . = ..() + playsound(src, pick(crumble_sound), 20) + spawn(GOLD_SPIKE_WINDUP) + icon_state = "goldspike_full" + var/turf/turf = get_turf(src) + for(var/mob/living/victim in turf.contents) + if(!istype(victim, /mob/living/carbon/superior_animal/golem)) + victim.adjustBruteLoss(GOLD_SPIKE_DAMAGE) + playsound(src, 'sound/weapons/slice.ogg', 30) + victim.shake_animation(4) + animate(src, alpha = 0, time = 20, easing = BACK_EASING|EASE_IN) + QDEL_IN(src, 20) + + + + + + diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/silver.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/silver.dm index 697662a7d3e..f5aef3c8497 100644 --- a/code/modules/mob/living/carbon/superior_animal/golem/types/silver.dm +++ b/code/modules/mob/living/carbon/superior_animal/golem/types/silver.dm @@ -37,9 +37,9 @@ projectilesound = 'sound/weapons/energy/burn.ogg' casingtype = null ranged_cooldown = 3 SECOND - fire_verb = "fires" + fire_verb = "hurls a spike" acceptableTargetDistance = 6 - kept_distance = 5 + kept_distance = 4 /obj/item/projectile/plasma/stun/golem //special projectile that passes straight through golems name = "stun plasma bolt" @@ -52,3 +52,8 @@ return FALSE . = ..() +/mob/living/carbon/superior_animal/golem/silver/enhanced + name = "ancient silver golem" + desc = "A moving pile of rocks lined with menacing silver spikes and keen self preservation instincts." + retreat_on_too_close = TRUE //originally I also intended to increase their kept_distance, but walk_away acts really strangely when it's too high + diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/uranium.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/uranium.dm index 4a61e963243..63ae5de579c 100644 --- a/code/modules/mob/living/carbon/superior_animal/golem/types/uranium.dm +++ b/code/modules/mob/living/carbon/superior_animal/golem/types/uranium.dm @@ -31,8 +31,8 @@ // Loot related variables ore = /obj/item/ore/uranium - // Uranium golem does not attack - viewRange = 0 // Cannot attack if it cannot see + kept_distance = 3 + retreat_on_too_close = TRUE /mob/living/carbon/superior_animal/golem/uranium/New() ..() @@ -42,10 +42,3 @@ set_light(0) . = ..() -// Special capacity of uranium golem: quickly repair all nearby golems. -/mob/living/carbon/superior_animal/golem/uranium/handle_ai() - for(var/mob/living/carbon/superior_animal/golem/G in range(GOLEM_URANIUM_HEAL_RANGE,get_turf(src))) - if(!istype(G, /mob/living/carbon/superior_animal/golem/uranium)) // Uraniums do not regen - G.adjustBruteLoss(-GOLEM_REGENERATION) // Brute Regeneration - G.adjustFireLoss(-GOLEM_REGENERATION) // Burn Regeneration - . = ..() diff --git a/code/modules/mob/living/carbon/superior_animal/superior_animal.dm b/code/modules/mob/living/carbon/superior_animal/superior_animal.dm index 662bc285bd2..5af2d4fdaf7 100644 --- a/code/modules/mob/living/carbon/superior_animal/superior_animal.dm +++ b/code/modules/mob/living/carbon/superior_animal/superior_animal.dm @@ -96,6 +96,7 @@ var/ranged_cooldown var/fire_verb //what does it do when it shoots? var/kept_distance //how far away will it be before it stops moving closer + var/retreat_on_too_close = FALSE // if this is enabled avoid using very high kept_distance values, byond's pathfinding can get very upset if it can't get far enough away var/grabbed_by_friend = FALSE //is this superior_animal being wrangled? var/ticks_processed = 0 @@ -255,7 +256,9 @@ set_glide_size(DELAY2GLIDESIZE(move_to_delay)) if(!kept_distance) walk_to(src, target_mob, 1, move_to_delay) - else + else if (kept_distance && retreat_on_too_close && (get_dist(loc, target_mob.loc) < kept_distance)) + walk_away(src,target_mob,kept_distance,move_to_delay) // warning: mobs will strafe nonstop if they can't get far enough away + else if(kept_distance) step_to(src, target_mob, kept_distance) if(HOSTILE_STANCE_ATTACKING) diff --git a/icons/mob/golems.dmi b/icons/mob/golems.dmi index 43e3b8d5650ec8c451eb26c1e179886851dcaf79..6bb9e0cca456cc55196dbd526da9192267fcf919 100644 GIT binary patch delta 12362 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 delta 12007 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 H{N?`u;8u{q From d7d9536056596b75e16eb07e7130280a5d732a77 Mon Sep 17 00:00:00 2001 From: Wrill <86113712+WrillWasTaken@users.noreply.github.com> Date: Mon, 10 Feb 2025 18:09:48 +0000 Subject: [PATCH 16/52] grab functionality --- code/datums/movement/mob.dm | 2 +- .../modules/mining/drilling/cave_generator.dm | 5 ++-- code/modules/mob/living/carbon/resist.dm | 6 ++++ .../superior_animal/golem/types/coal.dm | 2 +- .../superior_animal/golem/types/platinum.dm | 3 ++ .../carbon/superior_animal/superior_animal.dm | 30 +++++++++++++++++++ 6 files changed, 44 insertions(+), 4 deletions(-) diff --git a/code/datums/movement/mob.dm b/code/datums/movement/mob.dm index 4d348bbd4f2..243ebfe35ad 100755 --- a/code/datums/movement/mob.dm +++ b/code/datums/movement/mob.dm @@ -249,7 +249,7 @@ to_chat(mob, "You're pinned down by \a [mob.pinned[1]]!") return MOVEMENT_STOP - for(var/obj/item/grab/G in mob.grabbed_by) + for(var/G in mob.grabbed_by) return MOVEMENT_STOP /* TODO: Bay grab system if(G.stop_move()) diff --git a/code/modules/mining/drilling/cave_generator.dm b/code/modules/mining/drilling/cave_generator.dm index 0db1c7b4473..91e85caea4b 100644 --- a/code/modules/mining/drilling/cave_generator.dm +++ b/code/modules/mining/drilling/cave_generator.dm @@ -622,7 +622,8 @@ if(3,4) //medium: guarantee 1 melee, 1 ranged/special and then pick 3 random var/melee_weights = list( /mob/living/carbon/superior_animal/golem/iron = 4, - /mob/living/carbon/superior_animal/golem/coal = 2, + /mob/living/carbon/superior_animal/golem/coal = (seismic_lvl == 3) ? 2 : 0, + /mob/living/carbon/superior_animal/golem/coal/enhanced = (seismic_lvl == 4) ? 2 : 0, /mob/living/carbon/superior_animal/golem/platinum = 3, /mob/living/carbon/superior_animal/golem/plasma = (seismic_lvl == 4) ? 2 : 0) @@ -639,7 +640,7 @@ if(5,6) // HELL: guarantee 2 melee, 2 ranged/special and then pick 1 random golem var/melee_weights = list( /mob/living/carbon/superior_animal/golem/iron = 3, - /mob/living/carbon/superior_animal/golem/coal = 2, + /mob/living/carbon/superior_animal/golem/coal/enhanced = 2, /mob/living/carbon/superior_animal/golem/platinum = 3, /mob/living/carbon/superior_animal/golem/plasma = 2, /mob/living/carbon/superior_animal/golem/diamond = (seismic_lvl == 6) ? 2 : 0) diff --git a/code/modules/mob/living/carbon/resist.dm b/code/modules/mob/living/carbon/resist.dm index 6c9ec381e04..fa782466457 100644 --- a/code/modules/mob/living/carbon/resist.dm +++ b/code/modules/mob/living/carbon/resist.dm @@ -76,6 +76,12 @@ if(prob(conditionsapply * (5 + max((stats?.getStat(STAT_ROB)) - G.assailant.stats?.getStat(STAT_ROB), 1) ** 0.8))) // 4% minimal chance visible_message("[src] has broken free of [G.assailant]'s headlock!") qdel(G) + for(var/mob/living/carbon/superior_animal/G_mob in grabbed_by) //grabs by non-humans work differently, as they do not have stats nor hands + resisting++ + if(prob(((5 * stats?.getStat(STAT_ROB)) ** 0.75) / max(grabbed_by.len / 1.5, 1))) + G_mob.breakgrab() + visible_message("[src] has broken free of [G_mob]'s grip!") + if(resisting) setClickCooldown(20) visible_message("[src] resists!") diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/coal.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/coal.dm index 5a17a7d7c42..8baa84514c5 100644 --- a/code/modules/mob/living/carbon/superior_animal/golem/types/coal.dm +++ b/code/modules/mob/living/carbon/superior_animal/golem/types/coal.dm @@ -40,7 +40,7 @@ if(istype(A, /mob/living/carbon)) visible_message(SPAN_DANGER("[src] grabs at [target_mob]!"), 1) playsound(src, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) - A.Stun(COAL_STUN_DURATION) + simplegrab(target_mob) else // if they're not a carbon just attack them normally. this includes things like simple animals . = ..() diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/platinum.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/platinum.dm index 82fbe1b71ef..58b5603108c 100644 --- a/code/modules/mob/living/carbon/superior_animal/golem/types/platinum.dm +++ b/code/modules/mob/living/carbon/superior_animal/golem/types/platinum.dm @@ -89,3 +89,6 @@ #undef PLATINUM_CHARGE_DAMAGE_OBSTACLES #undef PLATINUM_CHARGE_DAMAGE_TARGET +#undef PLATINUM_CHARGE_CD +#undef PLATINUM_CHARGE_WINDUP +#undef PLATINUM_CHARGE_RANGE diff --git a/code/modules/mob/living/carbon/superior_animal/superior_animal.dm b/code/modules/mob/living/carbon/superior_animal/superior_animal.dm index 5af2d4fdaf7..d50b69a9f9d 100644 --- a/code/modules/mob/living/carbon/superior_animal/superior_animal.dm +++ b/code/modules/mob/living/carbon/superior_animal/superior_animal.dm @@ -101,6 +101,8 @@ var/grabbed_by_friend = FALSE //is this superior_animal being wrangled? var/ticks_processed = 0 + var/mob/living/grabbing // the currently grabbed mob + // Armor related datum var/datum/armor/armor @@ -229,6 +231,8 @@ else canmove = TRUE set_density(initial(density)) + if(!lying && grabbing) + canmove = FALSE // don't move if we're grabbing someone /mob/living/carbon/superior_animal/proc/handle_ai() @@ -346,6 +350,8 @@ handle_cheap_environment(environment) updateicon() ticks_processed = 0 + if(grabbing && !Adjacent(grabbing)) + breakgrab() if(handle_cheap_regular_status_updates()) // They have died after all of this, do not scan or do not handle AI anymore. return PROCESS_KILL @@ -377,3 +383,27 @@ if(istype(mover, /obj/item/projectile)) return stat ? TRUE : FALSE . = ..() + +/mob/living/carbon/superior_animal/death() + breakgrab() + . = ..() + +/mob/living/carbon/superior_animal/proc/simplegrab(var/mob/living/target) // superior animals won't do this naturally, but this proc makes it easy to implement such behaviour in specific mobs + if(!target && target_mob) + target = target_mob // if no target was specified, but we have a target, default to them + else if(!target || !Adjacent(target)) + return + + visible_message("[src] has grabs [target]!") + target.grabbed_by += src + grabbing = target + cheap_update_lying_buckled_and_verb_status_() + + +/mob/living/carbon/superior_animal/proc/breakgrab() + if(grabbing) + grabbing.grabbed_by -= src + grabbing = null + cheap_update_lying_buckled_and_verb_status_() + + From 45d0ecb45c9c8a2e735fdeef313fd8eb7ef6067e Mon Sep 17 00:00:00 2001 From: Wrill <86113712+WrillWasTaken@users.noreply.github.com> Date: Mon, 10 Feb 2025 19:32:29 +0000 Subject: [PATCH 17/52] slight adjustments --- code/modules/mob/living/carbon/resist.dm | 4 ++-- .../mob/living/carbon/superior_animal/golem/types/coal.dm | 4 +--- .../mob/living/carbon/superior_animal/superior_animal.dm | 2 +- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/code/modules/mob/living/carbon/resist.dm b/code/modules/mob/living/carbon/resist.dm index fa782466457..bb44b31aaac 100644 --- a/code/modules/mob/living/carbon/resist.dm +++ b/code/modules/mob/living/carbon/resist.dm @@ -76,9 +76,9 @@ if(prob(conditionsapply * (5 + max((stats?.getStat(STAT_ROB)) - G.assailant.stats?.getStat(STAT_ROB), 1) ** 0.8))) // 4% minimal chance visible_message("[src] has broken free of [G.assailant]'s headlock!") qdel(G) - for(var/mob/living/carbon/superior_animal/G_mob in grabbed_by) //grabs by non-humans work differently, as they do not have stats nor hands + for(var/mob/living/carbon/superior_animal/G_mob in grabbed_by) //grabs by non-humans work differently, as they have neither stats nor hands resisting++ - if(prob(((5 * stats?.getStat(STAT_ROB)) ** 0.75) / max(grabbed_by.len / 1.5, 1))) + if(prob(max(((stats?.getStat(STAT_ROB) ** 0.9) / grabbed_by.len),20))) G_mob.breakgrab() visible_message("[src] has broken free of [G_mob]'s grip!") diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/coal.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/coal.dm index 8baa84514c5..cc2b49dfc19 100644 --- a/code/modules/mob/living/carbon/superior_animal/golem/types/coal.dm +++ b/code/modules/mob/living/carbon/superior_animal/golem/types/coal.dm @@ -1,5 +1,3 @@ -#define COAL_STUN_DURATION 10 - /mob/living/carbon/superior_animal/golem/coal name = "coal golem" desc = "A moving pile of rocks with coal clumps in it." @@ -31,7 +29,7 @@ // Loot related variables ore = /obj/item/ore/coal -// enhanced coal golems will "grab" (stun) players, leaving them vulnerable to very high damage golems like gold and platinum +// enhanced coal golems will grab players, leaving them vulnerable to very high damage golems like gold and platinum /mob/living/carbon/superior_animal/golem/coal/enhanced name = "graphite golem" desc = "A moving pile of rocks with unusually large hands and graphite chunks in it." diff --git a/code/modules/mob/living/carbon/superior_animal/superior_animal.dm b/code/modules/mob/living/carbon/superior_animal/superior_animal.dm index d50b69a9f9d..9f09eb232c0 100644 --- a/code/modules/mob/living/carbon/superior_animal/superior_animal.dm +++ b/code/modules/mob/living/carbon/superior_animal/superior_animal.dm @@ -394,7 +394,7 @@ else if(!target || !Adjacent(target)) return - visible_message("[src] has grabs [target]!") + visible_message("[src] grabs [target]!") target.grabbed_by += src grabbing = target cheap_update_lying_buckled_and_verb_status_() From 49406ba906fe43a144ed2c7eff866b9ce5195c67 Mon Sep 17 00:00:00 2001 From: Wrill <86113712+WrillWasTaken@users.noreply.github.com> Date: Tue, 11 Feb 2025 00:00:54 +0000 Subject: [PATCH 18/52] adjust golem AI --- .../modules/mining/drilling/cave_generator.dm | 12 +-- .../carbon/superior_animal/golem/golem.dm | 78 ++++++++++++++++++- .../superior_animal/golem/types/gold.dm | 10 ++- .../superior_animal/golem/types/platinum.dm | 8 +- 4 files changed, 94 insertions(+), 14 deletions(-) diff --git a/code/modules/mining/drilling/cave_generator.dm b/code/modules/mining/drilling/cave_generator.dm index 91e85caea4b..1cff4423c69 100644 --- a/code/modules/mining/drilling/cave_generator.dm +++ b/code/modules/mining/drilling/cave_generator.dm @@ -31,8 +31,8 @@ //minimum distance between spawned clusters. the spawn is canceled if it's lower than this. #define GOLEM_SPAWN_SPACING 7.5 // //chance for a cluster of 5 golems to spawn per tile, calculated as "GOLEM_SPAWN_CHANCE_BASE + (GOLEM_SPAWN_CHANCE_SCALING * seismic level)" -#define GOLEM_SPAWN_CHANCE_BASE 1.6 -#define GOLEM_SPAWN_CHANCE_SCALING 0.4 // 2% on level 1, 4% on level 6. +#define GOLEM_SPAWN_CHANCE_BASE 2.8 +#define GOLEM_SPAWN_CHANCE_SCALING 0.2 // 3% on level 1, 4% on level 6. ////////////////////////////// // Generator used to handle underground caves @@ -610,16 +610,16 @@ var/list/mob/living/carbon/superior_animal/golem/golems_to_spawn = list() switch(seismic_lvl) - if(1,2) //easy: pick 5 random golems + if(1,2) //easy: pick 3 random golems var/weights = list( /mob/living/carbon/superior_animal/golem/iron = 3, /mob/living/carbon/superior_animal/golem/coal = 2, /mob/living/carbon/superior_animal/golem/silver = (seismic_lvl == 2) ? 2 : 0) //0 weight on seismic 1, 2 weight on seismic 2. - for(var/c = 0, c < 5, c++) // I couldn't get pickweight_mult to work, so running pickweight 5 times is a more reliable solution + for(var/c = 0, c < 3, c++) // I couldn't get pickweight_mult to work, so running pickweight 5 times is a more reliable solution golems_to_spawn += pickweight(weights) - if(3,4) //medium: guarantee 1 melee, 1 ranged/special and then pick 3 random + if(3,4) //medium: guarantee 1 melee, 1 ranged/special and then pick 2 random var/melee_weights = list( /mob/living/carbon/superior_animal/golem/iron = 4, /mob/living/carbon/superior_animal/golem/coal = (seismic_lvl == 3) ? 2 : 0, @@ -634,7 +634,7 @@ golems_to_spawn += pickweight(melee_weights) golems_to_spawn += pickweight(ranged_weights) - for(var/c = 0, c < 3, c++) + for(var/c = 0, c < 2, c++) golems_to_spawn += pickweight(melee_weights + ranged_weights) if(5,6) // HELL: guarantee 2 melee, 2 ranged/special and then pick 1 random golem diff --git a/code/modules/mob/living/carbon/superior_animal/golem/golem.dm b/code/modules/mob/living/carbon/superior_animal/golem/golem.dm index 9370381dfe0..dfe2ca12bfc 100644 --- a/code/modules/mob/living/carbon/superior_animal/golem/golem.dm +++ b/code/modules/mob/living/carbon/superior_animal/golem/golem.dm @@ -21,9 +21,9 @@ #define GOLEM_REGENERATION 10 // Healing by special ability of uranium golems -GLOBAL_LIST_EMPTY(all_golems) // golems check this list to target allies +GLOBAL_LIST_EMPTY(all_golems) // golems check this list to loop over allies +GLOBAL_LIST_EMPTY(active_golems) // smaller list that only contains golems with a current target mob -// OneStar patrol borg that defends OneStar facilities /mob/living/carbon/superior_animal/golem icon = 'icons/mob/golems.dmi' @@ -47,6 +47,8 @@ GLOBAL_LIST_EMPTY(all_golems) // golems check this list to target allies meat_amount = 0 stop_automated_movement_when_pulled = 0 wander = FALSE + viewRange = 8 + kept_distance destroy_surroundings = TRUE @@ -68,12 +70,16 @@ GLOBAL_LIST_EMPTY(all_golems) // golems check this list to target allies // Type of ore to spawn when the golem dies var/ore + var/aiticks = 0 + var/targetrecievedtime = -250 + /mob/living/carbon/superior_animal/golem/Initialize(var/mapload) GLOB.all_golems += src .=..() /mob/living/carbon/superior_animal/golem/Destroy() GLOB.all_golems -= src + GLOB.active_golems -= src ..() /mob/living/carbon/superior_animal/golem/death(gibbed, message = deathmessage) @@ -105,3 +111,71 @@ GLOBAL_LIST_EMPTY(all_golems) // golems check this list to target allies var/obj/structure/obstacle = locate(/obj/structure) in T if(obstacle) obstacle.attack_generic(src, rand(surrounds_mult * melee_damage_lower, surrounds_mult * melee_damage_upper), pick(attacktext), TRUE) + +/mob/living/carbon/superior_animal/golem/loseTarget() + GLOB.active_golems -= src + . = ..() + +/mob/living/carbon/superior_animal/golem/handle_ai() + + objectsInView = null + + //CONSCIOUS UNCONSCIOUS DEAD + + if (!check_AI_act()) + return FALSE + + switch(stance) + if(HOSTILE_STANCE_IDLE) + if (!busy) // if not busy with a special task + stop_automated_movement = FALSE + target_mob = findTarget() + if (target_mob) + stance = HOSTILE_STANCE_ATTACK + for(var/mob/living/carbon/superior_animal/golem/ally in GLOB.all_golems) + if(!ally.target_mob && (get_dist(ally, src) < 5)) + ally.stance = HOSTILE_STANCE_ATTACK + ally.target_mob = target_mob + ally.targetrecievedtime = world.time + + if(HOSTILE_STANCE_ATTACK) + if(destroy_surroundings) + destroySurroundings() + + stop_automated_movement = TRUE + stance = HOSTILE_STANCE_ATTACKING + set_glide_size(DELAY2GLIDESIZE(move_to_delay)) + if(!kept_distance) + walk_to(src, target_mob, 1, move_to_delay) + else if (kept_distance && retreat_on_too_close && (get_dist(loc, target_mob.loc) < kept_distance)) + walk_away(src,target_mob,kept_distance,move_to_delay) // warning: mobs will strafe nonstop if they can't get far enough away + else if(kept_distance) + step_to(src, target_mob, kept_distance) + + if(HOSTILE_STANCE_ATTACKING) + if(destroy_surroundings) + destroySurroundings() + + if((targetrecievedtime - world.time) < 50) // golems will disregard target validity temporarily after another golem gives them a target, so that they don't immediately lose their target + attemptAttackOnTarget() + else + prepareAttackOnTarget() + + //random movement + if(wander && !stop_automated_movement && !anchored) + if(isturf(loc) && !resting && !buckled && canmove) + turns_since_move++ + if(turns_since_move >= turns_per_move) + if(!(stop_automated_movement_when_pulled && pulledby)) + var/moving_to = pick(cardinal) + set_dir(moving_to) + step_glide(src, moving_to, DELAY2GLIDESIZE(0.5 SECONDS)) + turns_since_move = 0 + + //Speaking + if(speak_chance && prob(speak_chance)) + visible_emote(emote_see) + + return TRUE + + diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/gold.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/gold.dm index 527a9e841ff..e9ab44018b4 100644 --- a/code/modules/mob/living/carbon/superior_animal/golem/types/gold.dm +++ b/code/modules/mob/living/carbon/superior_animal/golem/types/gold.dm @@ -52,12 +52,18 @@ turfstoattack += potentialturf for(var/turf/targetturf in turfstoattack) - new /obj/golem_spike(targetturf) + var/obj/golem_spike/spike = new /obj/golem_spike(targetturf) + spike.parent = src /obj/golem_spike icon = 'icons/mob/golems.dmi' icon_state = "goldspike_tip" mouse_opacity = MOUSE_OPACITY_TRANSPARENT + var/parent + var/attacktext = list( + "skewered", + "impaled,", + "punctured") /obj/golem_spike/Initialize() . = ..() @@ -67,7 +73,7 @@ var/turf/turf = get_turf(src) for(var/mob/living/victim in turf.contents) if(!istype(victim, /mob/living/carbon/superior_animal/golem)) - victim.adjustBruteLoss(GOLD_SPIKE_DAMAGE) + victim.attack_generic(parent, GOLD_SPIKE_DAMAGE, pick(attacktext), FALSE, TRUE, FALSE, 1) playsound(src, 'sound/weapons/slice.ogg', 30) victim.shake_animation(4) animate(src, alpha = 0, time = 20, easing = BACK_EASING|EASE_IN) diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/platinum.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/platinum.dm index 58b5603108c..d240ac75e0c 100644 --- a/code/modules/mob/living/carbon/superior_animal/golem/types/platinum.dm +++ b/code/modules/mob/living/carbon/superior_animal/golem/types/platinum.dm @@ -36,6 +36,7 @@ ore = /obj/item/ore/osmium var/charge_verbs = list("launches itself", "charges", "rams") + var/charge_hit_verbs = list("crashes into", "smashes", "slams into") var/charge_cooldown = 0 /mob/living/carbon/superior_animal/golem/platinum/handle_ai() // half of this proc is just the visuals. the visuals are irritatingly difficult with this method of actually charging @@ -52,8 +53,7 @@ var/turf/lastvalidturf // I am not even going to pretend I understand how this proc works passedturfs -= passedturfs[(passedturfs.len)] // cut off the end of the line so we stop right before the target var/vfxindex = passedturfs.len - 1 - var/vfxfalloff = 250 / (passedturfs.len - 1) - + var/vfxfalloff = 250 / max((passedturfs.len - 1),1) for(var/turf/targetturf in passedturfs) if(turf_clear_ignore_cables_and_mobs(targetturf)) @@ -62,7 +62,7 @@ new /obj/effect/decal/cleanable/rubble(targetturf) - if(vfxindex >= 0) //every turf except the one we end on. + if((vfxindex >= 0) && (passedturfs.len >= 1)) //every turf except the one we end on. var/obj/effect/temp_visual/long/charge_effect = new /obj/effect/temp_visual/long(targetturf) charge_effect.icon = icon charge_effect.icon_state = icon_state // copy over the icon and direction @@ -82,7 +82,7 @@ forceMove(lastvalidturf) if(Adjacent(target_mob)) - UnarmedAttack(target_mob, 1, PLATINUM_CHARGE_DAMAGE_TARGET) + target_mob.attack_generic(src, PLATINUM_CHARGE_DAMAGE_TARGET, pick(charge_hit_verbs), FALSE, FALSE, FALSE, 1) playsound(loc, 'sound/weapons/melee/blunthit.ogg', attack_sound_volume, 1) walk_to(src, target_mob, 1, move_to_delay) // continue moving towards the target once the charge is finished From 5b8447d1b46e7a3bb92e81201a0dd5fdfebb0770 Mon Sep 17 00:00:00 2001 From: Wrill <86113712+WrillWasTaken@users.noreply.github.com> Date: Tue, 11 Feb 2025 00:32:50 +0000 Subject: [PATCH 19/52] Update golem.dm --- code/modules/mob/living/carbon/superior_animal/golem/golem.dm | 1 - 1 file changed, 1 deletion(-) diff --git a/code/modules/mob/living/carbon/superior_animal/golem/golem.dm b/code/modules/mob/living/carbon/superior_animal/golem/golem.dm index dfe2ca12bfc..e07e2d9250c 100644 --- a/code/modules/mob/living/carbon/superior_animal/golem/golem.dm +++ b/code/modules/mob/living/carbon/superior_animal/golem/golem.dm @@ -48,7 +48,6 @@ GLOBAL_LIST_EMPTY(active_golems) // smaller list that only contains golems with stop_automated_movement_when_pulled = 0 wander = FALSE viewRange = 8 - kept_distance destroy_surroundings = TRUE From d35467c78377204c0784dc3b07b7d11cbff75d44 Mon Sep 17 00:00:00 2001 From: Wrill <86113712+WrillWasTaken@users.noreply.github.com> Date: Tue, 11 Feb 2025 14:55:40 +0000 Subject: [PATCH 20/52] tweaks + re-add uranium healing --- .../carbon/superior_animal/golem/golem.dm | 21 +++++++++++++++---- .../superior_animal/golem/types/ansible.dm | 2 +- .../superior_animal/golem/types/gold.dm | 2 +- .../superior_animal/golem/types/silver.dm | 2 +- .../superior_animal/golem/types/uranium.dm | 9 ++++++++ 5 files changed, 29 insertions(+), 7 deletions(-) diff --git a/code/modules/mob/living/carbon/superior_animal/golem/golem.dm b/code/modules/mob/living/carbon/superior_animal/golem/golem.dm index e07e2d9250c..6a3fa1375e1 100644 --- a/code/modules/mob/living/carbon/superior_animal/golem/golem.dm +++ b/code/modules/mob/living/carbon/superior_animal/golem/golem.dm @@ -48,6 +48,7 @@ GLOBAL_LIST_EMPTY(active_golems) // smaller list that only contains golems with stop_automated_movement_when_pulled = 0 wander = FALSE viewRange = 8 + kept_Distance = 0 destroy_surroundings = TRUE @@ -69,7 +70,6 @@ GLOBAL_LIST_EMPTY(active_golems) // smaller list that only contains golems with // Type of ore to spawn when the golem dies var/ore - var/aiticks = 0 var/targetrecievedtime = -250 /mob/living/carbon/superior_animal/golem/Initialize(var/mapload) @@ -126,10 +126,10 @@ GLOBAL_LIST_EMPTY(active_golems) // smaller list that only contains golems with switch(stance) if(HOSTILE_STANCE_IDLE) - if (!busy) // if not busy with a special task + if(!busy) // if not busy with a special task stop_automated_movement = FALSE target_mob = findTarget() - if (target_mob) + if(target_mob) stance = HOSTILE_STANCE_ATTACK for(var/mob/living/carbon/superior_animal/golem/ally in GLOB.all_golems) if(!ally.target_mob && (get_dist(ally, src) < 5)) @@ -148,7 +148,7 @@ GLOBAL_LIST_EMPTY(active_golems) // smaller list that only contains golems with walk_to(src, target_mob, 1, move_to_delay) else if (kept_distance && retreat_on_too_close && (get_dist(loc, target_mob.loc) < kept_distance)) walk_away(src,target_mob,kept_distance,move_to_delay) // warning: mobs will strafe nonstop if they can't get far enough away - else if(kept_distance) + else step_to(src, target_mob, kept_distance) if(HOSTILE_STANCE_ATTACKING) @@ -177,4 +177,17 @@ GLOBAL_LIST_EMPTY(active_golems) // smaller list that only contains golems with return TRUE +/mob/living/carbon/superior_animal/golem/prepareAttackOnTarget() + stop_automated_movement = 1 + + if (!target_mob || !isValidAttackTarget(target_mob)) + loseTarget() + return + + if ((get_dist(src, target_mob) >= (viewRange + kept_distance)) || src.z != target_mob.z) //golems with a kept distance need to be further away to lose their gargets, to avoid losing targets by trying to keep distance + loseTarget() + return + + attemptAttackOnTarget() + diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/ansible.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/ansible.dm index 3a6368e0605..01b73dca5e3 100644 --- a/code/modules/mob/living/carbon/superior_animal/golem/types/ansible.dm +++ b/code/modules/mob/living/carbon/superior_animal/golem/types/ansible.dm @@ -40,7 +40,7 @@ ranged_cooldown = 3 SECOND fire_verb = "fires" acceptableTargetDistance = 6 - kept_distance = 3 + kept_distance = 5 // Cooldown of special ability var/teleport_cooldown = -90 SECONDS // negative so that it isn't on cooldown at round start diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/gold.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/gold.dm index e9ab44018b4..b22945c8663 100644 --- a/code/modules/mob/living/carbon/superior_animal/golem/types/gold.dm +++ b/code/modules/mob/living/carbon/superior_animal/golem/types/gold.dm @@ -30,7 +30,7 @@ rad = 0 ) - kept_distance = 4 + kept_distance = 3 retreat_on_too_close = TRUE // Loot related variables diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/silver.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/silver.dm index f5aef3c8497..d3b205d1351 100644 --- a/code/modules/mob/living/carbon/superior_animal/golem/types/silver.dm +++ b/code/modules/mob/living/carbon/superior_animal/golem/types/silver.dm @@ -39,7 +39,7 @@ ranged_cooldown = 3 SECOND fire_verb = "hurls a spike" acceptableTargetDistance = 6 - kept_distance = 4 + kept_distance = 3 /obj/item/projectile/plasma/stun/golem //special projectile that passes straight through golems name = "stun plasma bolt" diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/uranium.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/uranium.dm index 63ae5de579c..da9e21eaebc 100644 --- a/code/modules/mob/living/carbon/superior_animal/golem/types/uranium.dm +++ b/code/modules/mob/living/carbon/superior_animal/golem/types/uranium.dm @@ -42,3 +42,12 @@ set_light(0) . = ..() +/mob/living/carbon/superior_animal/golem/uranium/handle_ai() + . = ..() + if(target_mob) + for(var/mob/living/carbon/superior_animal/golem/ally in GLOB.active_golems) + if((ally != src) && (get_dist(src, ally) < GOLEM_URANIUM_HEAL_RANGE)) + log_world("[src] trying to heal [ally]") + ally.adjustBruteLoss(-GOLEM_REGENERATION) + ally.adjustFireLoss(-GOLEM_REGENERATION) + From 7f86edd3983144b8a185941574bee35568c586b8 Mon Sep 17 00:00:00 2001 From: Wrill <86113712+WrillWasTaken@users.noreply.github.com> Date: Tue, 11 Feb 2025 14:56:25 +0000 Subject: [PATCH 21/52] typo --- code/modules/mob/living/carbon/superior_animal/golem/golem.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mob/living/carbon/superior_animal/golem/golem.dm b/code/modules/mob/living/carbon/superior_animal/golem/golem.dm index 6a3fa1375e1..eec5497a0e7 100644 --- a/code/modules/mob/living/carbon/superior_animal/golem/golem.dm +++ b/code/modules/mob/living/carbon/superior_animal/golem/golem.dm @@ -48,7 +48,7 @@ GLOBAL_LIST_EMPTY(active_golems) // smaller list that only contains golems with stop_automated_movement_when_pulled = 0 wander = FALSE viewRange = 8 - kept_Distance = 0 + kept_distance = 0 destroy_surroundings = TRUE From f4e3b2f1a71f183435b8e240b531fb4a3875f104 Mon Sep 17 00:00:00 2001 From: Wrill <86113712+WrillWasTaken@users.noreply.github.com> Date: Tue, 11 Feb 2025 16:30:03 +0000 Subject: [PATCH 22/52] adjust how retreating golems update pathfinding --- .../carbon/superior_animal/golem/golem.dm | 18 +++++++++++------- .../superior_animal/golem/types/ansible.dm | 1 + .../carbon/superior_animal/golem/types/gold.dm | 2 +- .../superior_animal/golem/types/silver.dm | 2 +- .../carbon/superior_animal/superior_animal.dm | 5 +++++ 5 files changed, 19 insertions(+), 9 deletions(-) diff --git a/code/modules/mob/living/carbon/superior_animal/golem/golem.dm b/code/modules/mob/living/carbon/superior_animal/golem/golem.dm index eec5497a0e7..44e9b183a5c 100644 --- a/code/modules/mob/living/carbon/superior_animal/golem/golem.dm +++ b/code/modules/mob/living/carbon/superior_animal/golem/golem.dm @@ -143,18 +143,16 @@ GLOBAL_LIST_EMPTY(active_golems) // smaller list that only contains golems with stop_automated_movement = TRUE stance = HOSTILE_STANCE_ATTACKING - set_glide_size(DELAY2GLIDESIZE(move_to_delay)) - if(!kept_distance) - walk_to(src, target_mob, 1, move_to_delay) - else if (kept_distance && retreat_on_too_close && (get_dist(loc, target_mob.loc) < kept_distance)) - walk_away(src,target_mob,kept_distance,move_to_delay) // warning: mobs will strafe nonstop if they can't get far enough away - else - step_to(src, target_mob, kept_distance) + + updatePathFinding() if(HOSTILE_STANCE_ATTACKING) if(destroy_surroundings) destroySurroundings() + if(retreat_on_too_close) + updatePathFinding() //retreating enemies need to update their pathfinding way more often + if((targetrecievedtime - world.time) < 50) // golems will disregard target validity temporarily after another golem gives them a target, so that they don't immediately lose their target attemptAttackOnTarget() else @@ -190,4 +188,10 @@ GLOBAL_LIST_EMPTY(active_golems) // smaller list that only contains golems with attemptAttackOnTarget() +/mob/living/carbon/superior_animal/golem/proc/updatePathFinding() // moved to a separate proc to avoid code repeats + set_glide_size(DELAY2GLIDESIZE(move_to_delay)) + if(!retreat_on_too_close || (get_dist(loc, target_mob.loc) > kept_distance)) // if this AI doesn't retreat or the target is further than our retreat distance, walk to them. + walk_to(src, target_mob, kept_distance + 1, move_to_delay) + else + walk_away(src,target_mob,kept_distance,move_to_delay) // warning: mobs will strafe nonstop if they can't get far enough awaye) diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/ansible.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/ansible.dm index 01b73dca5e3..54bf7b2cbd4 100644 --- a/code/modules/mob/living/carbon/superior_animal/golem/types/ansible.dm +++ b/code/modules/mob/living/carbon/superior_animal/golem/types/ansible.dm @@ -41,6 +41,7 @@ fire_verb = "fires" acceptableTargetDistance = 6 kept_distance = 5 + retreat_on_too_close = TRUE // Cooldown of special ability var/teleport_cooldown = -90 SECONDS // negative so that it isn't on cooldown at round start diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/gold.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/gold.dm index b22945c8663..74e806d67c0 100644 --- a/code/modules/mob/living/carbon/superior_animal/golem/types/gold.dm +++ b/code/modules/mob/living/carbon/superior_animal/golem/types/gold.dm @@ -30,7 +30,7 @@ rad = 0 ) - kept_distance = 3 + kept_distance = 5 retreat_on_too_close = TRUE // Loot related variables diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/silver.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/silver.dm index d3b205d1351..f5aef3c8497 100644 --- a/code/modules/mob/living/carbon/superior_animal/golem/types/silver.dm +++ b/code/modules/mob/living/carbon/superior_animal/golem/types/silver.dm @@ -39,7 +39,7 @@ ranged_cooldown = 3 SECOND fire_verb = "hurls a spike" acceptableTargetDistance = 6 - kept_distance = 3 + kept_distance = 4 /obj/item/projectile/plasma/stun/golem //special projectile that passes straight through golems name = "stun plasma bolt" diff --git a/code/modules/mob/living/carbon/superior_animal/superior_animal.dm b/code/modules/mob/living/carbon/superior_animal/superior_animal.dm index 9f09eb232c0..2a307e3fa9f 100644 --- a/code/modules/mob/living/carbon/superior_animal/superior_animal.dm +++ b/code/modules/mob/living/carbon/superior_animal/superior_animal.dm @@ -269,6 +269,11 @@ if(destroy_surroundings) destroySurroundings() + if(kept_distance && retreat_on_too_close && (get_dist(loc, target_mob.loc) < kept_distance)) + walk_away(src,target_mob,kept_distance,move_to_delay) // warning: mobs will strafe nonstop if they can't get far enough away + else if(kept_distance) + step_to(src, target_mob, kept_distance) + prepareAttackOnTarget() //random movement From 7c0e07664a661518badab2cf057e646aa9fdee3c Mon Sep 17 00:00:00 2001 From: Wrill <86113712+WrillWasTaken@users.noreply.github.com> Date: Tue, 11 Feb 2025 16:53:31 +0000 Subject: [PATCH 23/52] activate allies' AI when sharing targets limited CPU and its consequences on the human race --- code/modules/mob/living/carbon/superior_animal/golem/golem.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/code/modules/mob/living/carbon/superior_animal/golem/golem.dm b/code/modules/mob/living/carbon/superior_animal/golem/golem.dm index 44e9b183a5c..4e937a1a7eb 100644 --- a/code/modules/mob/living/carbon/superior_animal/golem/golem.dm +++ b/code/modules/mob/living/carbon/superior_animal/golem/golem.dm @@ -136,6 +136,7 @@ GLOBAL_LIST_EMPTY(active_golems) // smaller list that only contains golems with ally.stance = HOSTILE_STANCE_ATTACK ally.target_mob = target_mob ally.targetrecievedtime = world.time + try_activate_ai() // otherwise we attack alone even if a target is set if(HOSTILE_STANCE_ATTACK) if(destroy_surroundings) From d4ba6047190c522162330cd7ff83818276cc715a Mon Sep 17 00:00:00 2001 From: Wrill <86113712+WrillWasTaken@users.noreply.github.com> Date: Tue, 11 Feb 2025 16:53:50 +0000 Subject: [PATCH 24/52] Update golem.dm --- code/modules/mob/living/carbon/superior_animal/golem/golem.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mob/living/carbon/superior_animal/golem/golem.dm b/code/modules/mob/living/carbon/superior_animal/golem/golem.dm index 4e937a1a7eb..7fd03381980 100644 --- a/code/modules/mob/living/carbon/superior_animal/golem/golem.dm +++ b/code/modules/mob/living/carbon/superior_animal/golem/golem.dm @@ -136,7 +136,7 @@ GLOBAL_LIST_EMPTY(active_golems) // smaller list that only contains golems with ally.stance = HOSTILE_STANCE_ATTACK ally.target_mob = target_mob ally.targetrecievedtime = world.time - try_activate_ai() // otherwise we attack alone even if a target is set + ally.try_activate_ai() // otherwise we attack alone even if a target is set if(HOSTILE_STANCE_ATTACK) if(destroy_surroundings) From a5f74983f97a11aaae7514e48c93cea63dbb6eff Mon Sep 17 00:00:00 2001 From: Wrill <86113712+WrillWasTaken@users.noreply.github.com> Date: Tue, 11 Feb 2025 23:20:20 +0000 Subject: [PATCH 25/52] remove a debug print --- .../mob/living/carbon/superior_animal/golem/types/uranium.dm | 1 - 1 file changed, 1 deletion(-) diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/uranium.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/uranium.dm index da9e21eaebc..3ad57179a46 100644 --- a/code/modules/mob/living/carbon/superior_animal/golem/types/uranium.dm +++ b/code/modules/mob/living/carbon/superior_animal/golem/types/uranium.dm @@ -47,7 +47,6 @@ if(target_mob) for(var/mob/living/carbon/superior_animal/golem/ally in GLOB.active_golems) if((ally != src) && (get_dist(src, ally) < GOLEM_URANIUM_HEAL_RANGE)) - log_world("[src] trying to heal [ally]") ally.adjustBruteLoss(-GOLEM_REGENERATION) ally.adjustFireLoss(-GOLEM_REGENERATION) From 8249ed9c946bc34a688b2d20533a0dc78d75f3ba Mon Sep 17 00:00:00 2001 From: Wrill <86113712+WrillWasTaken@users.noreply.github.com> Date: Wed, 12 Feb 2025 00:19:59 +0000 Subject: [PATCH 26/52] reduce silver bolt pain, increase burn it knocks players out in only a few shots- it's disproportionately strong for the level it's introduced at. --- .../mob/living/carbon/superior_animal/golem/types/silver.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/silver.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/silver.dm index f5aef3c8497..dba5225872e 100644 --- a/code/modules/mob/living/carbon/superior_animal/golem/types/silver.dm +++ b/code/modules/mob/living/carbon/superior_animal/golem/types/silver.dm @@ -44,7 +44,7 @@ /obj/item/projectile/plasma/stun/golem //special projectile that passes straight through golems name = "stun plasma bolt" taser_effect = 1 - damage_types = list(HALLOSS = 30, BURN = 5) + damage_types = list(HALLOSS = 20, BURN = 10) impact_type = /obj/effect/projectile/stun/impact /obj/item/projectile/plasma/stun/golem/Bump(atom/A as mob|obj|turf|area, forced = FALSE) From 545f64546fd9bfd6196da4a0b3ead7c613611c1d Mon Sep 17 00:00:00 2001 From: Wrill <86113712+WrillWasTaken@users.noreply.github.com> Date: Wed, 12 Feb 2025 14:08:52 +0000 Subject: [PATCH 27/52] tweak some stuff --- code/modules/mining/drilling/cave_generator.dm | 8 +++++--- .../mob/living/carbon/superior_animal/golem/attack.dm | 6 +----- .../living/carbon/superior_animal/golem/types/platinum.dm | 7 +++++-- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/code/modules/mining/drilling/cave_generator.dm b/code/modules/mining/drilling/cave_generator.dm index 1cff4423c69..283ed76b500 100644 --- a/code/modules/mining/drilling/cave_generator.dm +++ b/code/modules/mining/drilling/cave_generator.dm @@ -656,10 +656,12 @@ golems_to_spawn += pickweight(ranged_weights) golems_to_spawn += pickweight(ranged_weights + melee_weights) - // Spawn golem at free location + var/potentialturfs = list() + for(var/turf/floor/asteroid/cave/potential_turf in range(1, turf)) + potentialturfs += potential_turf + for(var/golem in golems_to_spawn) - var/spawnturf = get_turf(locate(turf.x + rand(-1,1), turf.y + rand(-1,1), turf.z)) // slightly randomize the spawn turfs so golems don't spawn in a doomstack - new golem(spawnturf) + new golem(pick_mobless_turf_if_exists(potentialturfs)) for(var/c = 1 to golem_spawn_points.len) log_world(golem_spawn_points[c]) diff --git a/code/modules/mob/living/carbon/superior_animal/golem/attack.dm b/code/modules/mob/living/carbon/superior_animal/golem/attack.dm index 3db71afe240..8b137891791 100644 --- a/code/modules/mob/living/carbon/superior_animal/golem/attack.dm +++ b/code/modules/mob/living/carbon/superior_animal/golem/attack.dm @@ -1,5 +1 @@ -/mob/living/carbon/superior_animal/golem/isValidAttackTarget(atom/O) - // Golems can actively try to attack the drill - if(istype(O, /obj/machinery/mining/deep_drill)) - return TRUE - return ..() + diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/platinum.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/platinum.dm index d240ac75e0c..66b18887898 100644 --- a/code/modules/mob/living/carbon/superior_animal/golem/types/platinum.dm +++ b/code/modules/mob/living/carbon/superior_animal/golem/types/platinum.dm @@ -50,8 +50,11 @@ var/list/passedturfs = getline(src, target_mob) // do this at the start of the windup, so that the golem's charge doesn't track the target (and it can be dodged) spawn(PLATINUM_CHARGE_WINDUP) - var/turf/lastvalidturf // I am not even going to pretend I understand how this proc works - passedturfs -= passedturfs[(passedturfs.len)] // cut off the end of the line so we stop right before the target + var/turf/lastvalidturf + var/turf/lineend = passedturfs[(passedturfs.len)] + if(target_mob in lineend.contents) //if the target hasn't moved, cut off the end of the line so we don't end up on top of them + passedturfs -= lineend + var/vfxindex = passedturfs.len - 1 var/vfxfalloff = 250 / max((passedturfs.len - 1),1) From bb817c83f27e2fcefe44f06522131940d578a602 Mon Sep 17 00:00:00 2001 From: Wrill <86113712+WrillWasTaken@users.noreply.github.com> Date: Wed, 12 Feb 2025 14:15:52 +0000 Subject: [PATCH 28/52] slightly increase platinum's stats --- .../living/carbon/superior_animal/golem/types/platinum.dm | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/platinum.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/platinum.dm index 66b18887898..11aa81e0bd0 100644 --- a/code/modules/mob/living/carbon/superior_animal/golem/types/platinum.dm +++ b/code/modules/mob/living/carbon/superior_animal/golem/types/platinum.dm @@ -11,16 +11,16 @@ icon_living = "golem_platinum" // Health related variables - maxHealth = GOLEM_HEALTH_MED - health = GOLEM_HEALTH_MED + maxHealth = GOLEM_HEALTH_HIGH + health = GOLEM_HEALTH_HIGH // Movement related variables move_to_delay = GOLEM_SPEED_SLUG turns_per_move = 5 // Damage related variables - melee_damage_lower = GOLEM_DMG_FEEBLE - melee_damage_upper = GOLEM_DMG_LOW + melee_damage_lower = GOLEM_DMG_LOW + melee_damage_upper = GOLEM_DMG_MED // Armor related variables armor = list( From b00e9bc640ec015cd66fbaebe9361299d4025820 Mon Sep 17 00:00:00 2001 From: Wrill <86113712+WrillWasTaken@users.noreply.github.com> Date: Fri, 14 Feb 2025 18:46:57 +0000 Subject: [PATCH 29/52] suggested change --- code/datums/movement/mob.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/datums/movement/mob.dm b/code/datums/movement/mob.dm index 243ebfe35ad..d141d374249 100755 --- a/code/datums/movement/mob.dm +++ b/code/datums/movement/mob.dm @@ -249,7 +249,7 @@ to_chat(mob, "You're pinned down by \a [mob.pinned[1]]!") return MOVEMENT_STOP - for(var/G in mob.grabbed_by) + if(mob.grabbed_by.len) return MOVEMENT_STOP /* TODO: Bay grab system if(G.stop_move()) From cc5445ecc326b1884b76e5e53beff268d7f55e2f Mon Sep 17 00:00:00 2001 From: Wrill <86113712+WrillWasTaken@users.noreply.github.com> Date: Sun, 9 Mar 2025 22:25:08 +0000 Subject: [PATCH 30/52] completely rewrite golem spawns --- cev_eris.dme | 1 + .../modules/mining/drilling/cave_generator.dm | 95 ++++--------- code/modules/mining/drilling/difficulties.dm | 128 ++++++++++++++++++ 3 files changed, 155 insertions(+), 69 deletions(-) create mode 100644 code/modules/mining/drilling/difficulties.dm diff --git a/cev_eris.dme b/cev_eris.dme index 71e0832d7a5..da9ed277ae5 100644 --- a/cev_eris.dme +++ b/cev_eris.dme @@ -1848,6 +1848,7 @@ #include "code\modules\mining\drilling\cave_generator.dm" #include "code\modules\mining\drilling\cave_mineral.dm" #include "code\modules\mining\drilling\deep_drill.dm" +#include "code\modules\mining\drilling\difficulties.dm" #include "code\modules\mining\drilling\scanner.dm" #include "code\modules\mob\animations.dm" #include "code\modules\mob\death.dm" diff --git a/code/modules/mining/drilling/cave_generator.dm b/code/modules/mining/drilling/cave_generator.dm index 283ed76b500..719096242e4 100644 --- a/code/modules/mining/drilling/cave_generator.dm +++ b/code/modules/mining/drilling/cave_generator.dm @@ -28,8 +28,9 @@ #define CAVE_GOLD 9 #define CAVE_PLATINUM 10 -//minimum distance between spawned clusters. the spawn is canceled if it's lower than this. -#define GOLEM_SPAWN_SPACING 7.5 // +#define GOLEM_SPAWN_INTERVAL 15 // the spacing along each corridor that each golem squad will spawn +#define GOLEM_SPAWN_SPACING 10 //squads WILL NOT spawn closer than this no matter what, even if corridors intersect or run too close.area + //chance for a cluster of 5 golems to spawn per tile, calculated as "GOLEM_SPAWN_CHANCE_BASE + (GOLEM_SPAWN_CHANCE_SCALING * seismic level)" #define GOLEM_SPAWN_CHANCE_BASE 2.8 #define GOLEM_SPAWN_CHANCE_SCALING 0.2 // 3% on level 1, 4% on level 6. @@ -59,7 +60,15 @@ var/list/blacklist = list(/mob/observer, /obj/machinery/nuclearbomb, /obj/item/disk/nuclear) - var/list/generated_golems = list() //golems use this for targeting allies + var/list/golem_spawn_nodes = list() + var/list/datum/cave_difficulty_level/difficulties = list( + new /datum/cave_difficulty_level/beginner, + new /datum/cave_difficulty_level/novice, + new /datum/cave_difficulty_level/adept, + new /datum/cave_difficulty_level/experienced, + new /datum/cave_difficulty_level/expert, + new /datum/cave_difficulty_level/nightmare + ) /obj/cave_generator/Initialize() // Initialize and not New to ensure SSmapping.maploader has been created @@ -124,8 +133,12 @@ // Draw a 2-wide corridor for(var/i = x0 to x1 + 1) + if((y0 == y1) && ((i % GOLEM_SPAWN_SPACING) == 0) && check_spawn_overlap(locate(x + i,y + y0,z), golem_spawn_nodes)) + golem_spawn_nodes |= locate(x + i,y + y0,z) //i would use lists of x,y (like the rest of the generation code) but neither the | or the in operators work with nested lists so turfs it is for(var/j = y0 to y1 + 1) map[i][j] = CAVE_FREE + if((x0 == x1) && ((j % GOLEM_SPAWN_SPACING) == 0) && check_spawn_overlap(locate(x + x0,y + j,z), golem_spawn_nodes)) + golem_spawn_nodes |= locate(x + x0,y + j,z) // If this is the last corridor if(N == 0) @@ -595,77 +608,22 @@ // Spawn golems on free turfs depending on seismic level /obj/cave_generator/proc/place_golems(seismic_lvl) - var/list/turf/golem_spawn_points = list() - - for(var/i = 1 to CAVE_SIZE) - for(var/j = 1 to CAVE_SIZE) - if(map[i][j] == CAVE_FREE && prob(GOLEM_SPAWN_CHANCE_BASE + seismic_lvl * GOLEM_SPAWN_CHANCE_SCALING) && check_spawn_overlap(get_turf(locate(x + i, y + j, z)), golem_spawn_points)) - - var/turf/turf = get_turf(locate(x + i, y + j, z)) - - golem_spawn_points += turf - - //var/list/mob/golems_to_spawn = list() - - var/list/mob/living/carbon/superior_animal/golem/golems_to_spawn = list() + var/list/datum/cave_difficulty_level/current_difficulty = difficulties[seismic_lvl] - switch(seismic_lvl) - if(1,2) //easy: pick 3 random golems - var/weights = list( - /mob/living/carbon/superior_animal/golem/iron = 3, - /mob/living/carbon/superior_animal/golem/coal = 2, - /mob/living/carbon/superior_animal/golem/silver = (seismic_lvl == 2) ? 2 : 0) //0 weight on seismic 1, 2 weight on seismic 2. + for(var/turf/floor/asteroid/cave/spawnloc in golem_spawn_nodes) //filtering to only asteroid turfs avoids headaches with POIs and null locs that come from god knows where - for(var/c = 0, c < 3, c++) // I couldn't get pickweight_mult to work, so running pickweight 5 times is a more reliable solution - golems_to_spawn += pickweight(weights) + var/list/mob/living/carbon/superior_animal/golem/golems_to_spawn = current_difficulty.get_golem_spawns() - if(3,4) //medium: guarantee 1 melee, 1 ranged/special and then pick 2 random - var/melee_weights = list( - /mob/living/carbon/superior_animal/golem/iron = 4, - /mob/living/carbon/superior_animal/golem/coal = (seismic_lvl == 3) ? 2 : 0, - /mob/living/carbon/superior_animal/golem/coal/enhanced = (seismic_lvl == 4) ? 2 : 0, - /mob/living/carbon/superior_animal/golem/platinum = 3, - /mob/living/carbon/superior_animal/golem/plasma = (seismic_lvl == 4) ? 2 : 0) + var/potentialturfs = list() - var/ranged_weights = list( - /mob/living/carbon/superior_animal/golem/silver = 3, - /mob/living/carbon/superior_animal/golem/uranium = 1) + for(var/turf/floor/asteroid/cave/potential_turf in range(1, spawnloc)) + potentialturfs += potential_turf - golems_to_spawn += pickweight(melee_weights) - golems_to_spawn += pickweight(ranged_weights) - - for(var/c = 0, c < 2, c++) - golems_to_spawn += pickweight(melee_weights + ranged_weights) - - if(5,6) // HELL: guarantee 2 melee, 2 ranged/special and then pick 1 random golem - var/melee_weights = list( - /mob/living/carbon/superior_animal/golem/iron = 3, - /mob/living/carbon/superior_animal/golem/coal/enhanced = 2, - /mob/living/carbon/superior_animal/golem/platinum = 3, - /mob/living/carbon/superior_animal/golem/plasma = 2, - /mob/living/carbon/superior_animal/golem/diamond = (seismic_lvl == 6) ? 2 : 0) - - var/ranged_weights = list( - /mob/living/carbon/superior_animal/golem/silver/enhanced = 3, - /mob/living/carbon/superior_animal/golem/gold = 3, - /mob/living/carbon/superior_animal/golem/uranium = 2, - /mob/living/carbon/superior_animal/golem/ansible = (seismic_lvl == 6) ? 2 : 0) - - for(var/c = 0, c < 2, c++) - golems_to_spawn += pickweight(melee_weights) - golems_to_spawn += pickweight(ranged_weights) - golems_to_spawn += pickweight(ranged_weights + melee_weights) - - var/potentialturfs = list() - for(var/turf/floor/asteroid/cave/potential_turf in range(1, turf)) - potentialturfs += potential_turf - - for(var/golem in golems_to_spawn) - new golem(pick_mobless_turf_if_exists(potentialturfs)) - - for(var/c = 1 to golem_spawn_points.len) - log_world(golem_spawn_points[c]) + if(potentialturfs) + for(var/golem in golems_to_spawn) + new golem(pick_mobless_turf_if_exists(potentialturfs)) +//crude check if a point is within a given distance of any point in the given list /obj/cave_generator/proc/check_spawn_overlap(target_turf,list/pointlist) if(!(target_turf && pointlist)) return FALSE @@ -673,7 +631,6 @@ for(var/turf/t in pointlist) if(get_dist_euclidian(target_turf, t) < GOLEM_SPAWN_SPACING) return FALSE - return TRUE ////////////////////////////// diff --git a/code/modules/mining/drilling/difficulties.dm b/code/modules/mining/drilling/difficulties.dm new file mode 100644 index 00000000000..bcace7fb46d --- /dev/null +++ b/code/modules/mining/drilling/difficulties.dm @@ -0,0 +1,128 @@ +/datum/cave_difficulty_level //using a datum here lets me simplify the spawn pool logic and declutter cave_generator.dm in the process + var/golem_ore_mult = 1 + + //number of golems to spawn *per squad* + var/golem_count_melee = 0 + var/golem_count_ranged = 0 + var/golem_count_mixed = 0 // the "mixed" pool is the concatenation of the melee and ranged pools + + //lists of types and weights + var/list/golem_weights_melee = list() + var/list/golem_weights_ranged = list() + +/datum/cave_difficulty_level/proc/get_golem_spawns() + var/list/golems_to_spawn = list() //list of golem types to spawn + if(golem_count_melee) + for(var/c = 0, c < golem_count_melee, c++) + golems_to_spawn += pickweight(golem_weights_melee) + + if(golem_count_ranged) + for(var/c = 0, c < golem_count_ranged, c++) + golems_to_spawn += pickweight(golem_weights_ranged) + + if(golem_count_mixed) + var/list/golem_weights_mixed = golem_weights_melee + golem_weights_ranged + for(var/c = 0, c < golem_count_mixed, c++) + golems_to_spawn += pickweight(golem_weights_mixed) + + return golems_to_spawn + +//Seismic Level 1 +//Easy enough to figure out the basics, but not very rewarding. +/datum/cave_difficulty_level/beginner + golem_count_mixed = 3 + + golem_weights_melee = list( + /mob/living/carbon/superior_animal/golem/iron = 3, + /mob/living/carbon/superior_animal/golem/coal = 2) + +//Seismic Level 2 +//Tougher, more rewarding. +/datum/cave_difficulty_level/novice + golem_ore_mult = 1.75 + + golem_count_mixed = 3 + + golem_weights_melee = list( + /mob/living/carbon/superior_animal/golem/iron = 3, + /mob/living/carbon/superior_animal/golem/coal = 2) + + golem_weights_ranged = list( + /mob/living/carbon/superior_animal/golem/silver = 2) + +//Seismic Level 3 +//Ever harder. The golems introduced here are hard to fight alone. This is the limit for a solo miner on their roundstart gear. +/datum/cave_difficulty_level/adept + golem_ore_mult = 2.5 + + golem_count_melee = 1 + golem_count_ranged = 1 + golem_count_mixed = 3 + + golem_weights_melee = list( + /mob/living/carbon/superior_animal/golem/iron = 4, + /mob/living/carbon/superior_animal/golem/coal = 2, + /mob/living/carbon/superior_animal/golem/platinum = 3) + + golem_weights_ranged = list( + /mob/living/carbon/superior_animal/golem/silver = 3, + /mob/living/carbon/superior_animal/golem/uranium = 1) + +//Seismic Level 4 +//Teams should start to have trouble here; graphite golems make plasma and platinum golems very dangerous. +/datum/cave_difficulty_level/experienced + golem_ore_mult = 3.25 + + golem_count_melee = 1 + golem_count_ranged = 1 + golem_count_mixed = 3 + + golem_weights_melee = list( + /mob/living/carbon/superior_animal/golem/iron = 4, + /mob/living/carbon/superior_animal/golem/coal/enhanced = 2, + /mob/living/carbon/superior_animal/golem/platinum = 3, + /mob/living/carbon/superior_animal/golem/plasma = 2) + + golem_weights_ranged = list( + /mob/living/carbon/superior_animal/golem/silver = 3, + /mob/living/carbon/superior_animal/golem/uranium = 1) + +//Seismic Level 5 +//All the lethal golems are out now. A lot of prep or a lot of manpower is necessary to survive this. +/datum/cave_difficulty_level/expert + golem_ore_mult = 4 + + golem_count_melee = 2 + golem_count_ranged = 2 + golem_count_mixed = 1 + + golem_weights_melee = list( + /mob/living/carbon/superior_animal/golem/iron = 3, + /mob/living/carbon/superior_animal/golem/coal/enhanced = 2, + /mob/living/carbon/superior_animal/golem/platinum = 3, + /mob/living/carbon/superior_animal/golem/plasma = 2) + golem_weights_ranged = list( + /mob/living/carbon/superior_animal/golem/silver/enhanced = 3, + /mob/living/carbon/superior_animal/golem/gold = 3, + /mob/living/carbon/superior_animal/golem/uranium = 2) + +//Seismic Level 6 +//Hell. Ansibles will rip teams apart and diamonds are walking tanks unless you've invested in ballistics. +/datum/cave_difficulty_level/nightmare + golem_ore_mult = 4 + + golem_count_melee = 2 + golem_count_ranged = 2 + golem_count_mixed = 1 + + golem_weights_melee = list( + /mob/living/carbon/superior_animal/golem/iron = 3, + /mob/living/carbon/superior_animal/golem/coal/enhanced = 2, + /mob/living/carbon/superior_animal/golem/platinum = 3, + /mob/living/carbon/superior_animal/golem/plasma = 2, + /mob/living/carbon/superior_animal/golem/diamond = 2) + golem_weights_ranged = list( + /mob/living/carbon/superior_animal/golem/silver/enhanced = 3, + /mob/living/carbon/superior_animal/golem/gold = 3, + /mob/living/carbon/superior_animal/golem/uranium = 2, + /mob/living/carbon/superior_animal/golem/ansible = 2) From a24a7d877379af1d3c20717920c325931f52ed65 Mon Sep 17 00:00:00 2001 From: Wrill <86113712+WrillWasTaken@users.noreply.github.com> Date: Mon, 10 Mar 2025 00:53:48 +0000 Subject: [PATCH 31/52] rewrite ore drops + add difficulty scaling --- .../modules/mining/drilling/cave_generator.dm | 2 +- code/modules/mining/drilling/difficulties.dm | 14 +++++++++++ .../carbon/superior_animal/golem/golem.dm | 23 +++++++++++-------- .../superior_animal/golem/types/ansible.dm | 9 +++++--- .../superior_animal/golem/types/coal.dm | 2 +- .../superior_animal/golem/types/diamond.dm | 2 +- .../superior_animal/golem/types/gold.dm | 2 +- .../superior_animal/golem/types/iron.dm | 2 +- .../superior_animal/golem/types/plasma.dm | 2 +- .../superior_animal/golem/types/platinum.dm | 2 +- .../superior_animal/golem/types/silver.dm | 2 +- .../superior_animal/golem/types/uranium.dm | 2 +- 12 files changed, 43 insertions(+), 21 deletions(-) diff --git a/code/modules/mining/drilling/cave_generator.dm b/code/modules/mining/drilling/cave_generator.dm index 719096242e4..5fa0ef8277d 100644 --- a/code/modules/mining/drilling/cave_generator.dm +++ b/code/modules/mining/drilling/cave_generator.dm @@ -621,7 +621,7 @@ if(potentialturfs) for(var/golem in golems_to_spawn) - new golem(pick_mobless_turf_if_exists(potentialturfs)) + new golem(pick_mobless_turf_if_exists(potentialturfs), current_difficulty) //crude check if a point is within a given distance of any point in the given list /obj/cave_generator/proc/check_spawn_overlap(target_turf,list/pointlist) diff --git a/code/modules/mining/drilling/difficulties.dm b/code/modules/mining/drilling/difficulties.dm index bcace7fb46d..16f590cf619 100644 --- a/code/modules/mining/drilling/difficulties.dm +++ b/code/modules/mining/drilling/difficulties.dm @@ -1,4 +1,6 @@ /datum/cave_difficulty_level //using a datum here lets me simplify the spawn pool logic and declutter cave_generator.dm in the process + var/level //number value is easier to work with in some situations + var/golem_ore_mult = 1 //number of golems to spawn *per squad* @@ -30,6 +32,8 @@ //Seismic Level 1 //Easy enough to figure out the basics, but not very rewarding. /datum/cave_difficulty_level/beginner + level = 1 + golem_count_mixed = 3 golem_weights_melee = list( @@ -39,6 +43,8 @@ //Seismic Level 2 //Tougher, more rewarding. /datum/cave_difficulty_level/novice + level = 2 + golem_ore_mult = 1.75 golem_count_mixed = 3 @@ -53,6 +59,8 @@ //Seismic Level 3 //Ever harder. The golems introduced here are hard to fight alone. This is the limit for a solo miner on their roundstart gear. /datum/cave_difficulty_level/adept + level = 3 + golem_ore_mult = 2.5 golem_count_melee = 1 @@ -71,6 +79,8 @@ //Seismic Level 4 //Teams should start to have trouble here; graphite golems make plasma and platinum golems very dangerous. /datum/cave_difficulty_level/experienced + level = 4 + golem_ore_mult = 3.25 golem_count_melee = 1 @@ -90,6 +100,8 @@ //Seismic Level 5 //All the lethal golems are out now. A lot of prep or a lot of manpower is necessary to survive this. /datum/cave_difficulty_level/expert + level = 5 + golem_ore_mult = 4 golem_count_melee = 2 @@ -109,6 +121,8 @@ //Seismic Level 6 //Hell. Ansibles will rip teams apart and diamonds are walking tanks unless you've invested in ballistics. /datum/cave_difficulty_level/nightmare + level = 6 + golem_ore_mult = 4 golem_count_melee = 2 diff --git a/code/modules/mob/living/carbon/superior_animal/golem/golem.dm b/code/modules/mob/living/carbon/superior_animal/golem/golem.dm index 7fd03381980..d24bdc63df3 100644 --- a/code/modules/mob/living/carbon/superior_animal/golem/golem.dm +++ b/code/modules/mob/living/carbon/superior_animal/golem/golem.dm @@ -67,14 +67,20 @@ GLOBAL_LIST_EMPTY(active_golems) // smaller list that only contains golems with // Damage multiplier when destroying surroundings var/surrounds_mult = 0.5 - // Type of ore to spawn when the golem dies - var/ore + // Ore datum the golem holds. + var/ore/mineral + var/mineral_name var/targetrecievedtime = -250 -/mob/living/carbon/superior_animal/golem/Initialize(var/mapload) + var/datum/cave_difficulty_level/difficultylevel //currently this is only used for multiplying ore drops + +/mob/living/carbon/superior_animal/golem/Initialize(var/mapload, difficulty) GLOB.all_golems += src - .=..() + if(mineral_name && (mineral_name in ore_data)) + mineral = ore_data[mineral_name] + difficultylevel = difficulty + . = ..() /mob/living/carbon/superior_animal/golem/Destroy() GLOB.all_golems -= src @@ -85,13 +91,12 @@ GLOBAL_LIST_EMPTY(active_golems) // smaller list that only contains golems with . = ..() // Spawn ores - if(ore) - var/nb_ores = rand(8, 13) + if(mineral) + var/nb_ores = ceil((mineral.result_amount + rand(-3, 3)) * (difficultylevel ? difficultylevel.golem_ore_mult : 1)) for(var/i in 1 to nb_ores) - new ore(loc) + new mineral.ore(loc) - // Specials have a small chance to also drop a golem core - if(prob(30) && !istype(src, /mob/living/carbon/superior_animal/golem/coal) && !istype(src, /mob/living/carbon/superior_animal/golem/iron)) + if(prob(20)) new /obj/item/golem_core(loc) // Poof diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/ansible.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/ansible.dm index 54bf7b2cbd4..363d8634192 100644 --- a/code/modules/mob/living/carbon/superior_animal/golem/types/ansible.dm +++ b/code/modules/mob/living/carbon/superior_animal/golem/types/ansible.dm @@ -28,9 +28,6 @@ rad = 0 ) - // Loot related variables - ore = /obj/item/stock_parts/subspace/crystal - // Ranged attack related variables ranged = TRUE // Will it shoot? rapid = FALSE // Will it shoot fast? @@ -54,6 +51,12 @@ set_light(0) . = ..() +/mob/living/carbon/superior_animal/golem/ansible/death() + if(prob(10)) //10% chance to drop a bs crystal. since ansible golems are only present on max difficulty this seems like a fair reward. + var/crystal = new /obj/item/bluespace_crystal(loc) + visible_message(SPAN_NOTICE("A [crystal] falls out of [src] as it disintegrates."), 1) + ..() + // Special capacity of ansible golem: it will focus and teleport a miner near other golems /mob/living/carbon/superior_animal/golem/ansible/proc/teleport_target() diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/coal.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/coal.dm index cc2b49dfc19..bceed7f70ac 100644 --- a/code/modules/mob/living/carbon/superior_animal/golem/types/coal.dm +++ b/code/modules/mob/living/carbon/superior_animal/golem/types/coal.dm @@ -27,7 +27,7 @@ ) // Loot related variables - ore = /obj/item/ore/coal + mineral_name = ORE_CARBON // enhanced coal golems will grab players, leaving them vulnerable to very high damage golems like gold and platinum /mob/living/carbon/superior_animal/golem/coal/enhanced diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/diamond.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/diamond.dm index c00d5e5f411..d1e03788207 100644 --- a/code/modules/mob/living/carbon/superior_animal/golem/types/diamond.dm +++ b/code/modules/mob/living/carbon/superior_animal/golem/types/diamond.dm @@ -30,4 +30,4 @@ ) // Loot related variables - ore = /obj/item/ore/diamond + mineral_name = ORE_DIAMOND diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/gold.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/gold.dm index 74e806d67c0..ebf3ffc7f5f 100644 --- a/code/modules/mob/living/carbon/superior_animal/golem/types/gold.dm +++ b/code/modules/mob/living/carbon/superior_animal/golem/types/gold.dm @@ -34,7 +34,7 @@ retreat_on_too_close = TRUE // Loot related variables - ore = /obj/item/ore/ + mineral_name = ORE_GOLD var/spike_cooldown = 0 diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/iron.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/iron.dm index a7230a974ab..e9adeb47e2d 100644 --- a/code/modules/mob/living/carbon/superior_animal/golem/types/iron.dm +++ b/code/modules/mob/living/carbon/superior_animal/golem/types/iron.dm @@ -27,4 +27,4 @@ ) // Loot related variables - ore = /obj/item/ore/iron + mineral_name = ORE_IRON diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/plasma.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/plasma.dm index 2b16f665968..5f8c7ca0ec8 100644 --- a/code/modules/mob/living/carbon/superior_animal/golem/types/plasma.dm +++ b/code/modules/mob/living/carbon/superior_animal/golem/types/plasma.dm @@ -30,7 +30,7 @@ ) // Loot related variables - ore = /obj/item/ore/plasma + mineral_name = ORE_PLASMA // How much time before detonation var/det_time = 2.5 SECONDS diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/platinum.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/platinum.dm index 11aa81e0bd0..4da16bf7e57 100644 --- a/code/modules/mob/living/carbon/superior_animal/golem/types/platinum.dm +++ b/code/modules/mob/living/carbon/superior_animal/golem/types/platinum.dm @@ -33,7 +33,7 @@ ) // Loot related variables - ore = /obj/item/ore/osmium + mineral_name = ORE_PLATINUM var/charge_verbs = list("launches itself", "charges", "rams") var/charge_hit_verbs = list("crashes into", "smashes", "slams into") diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/silver.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/silver.dm index dba5225872e..173f20b5a6f 100644 --- a/code/modules/mob/living/carbon/superior_animal/golem/types/silver.dm +++ b/code/modules/mob/living/carbon/superior_animal/golem/types/silver.dm @@ -28,7 +28,7 @@ ) // Loot related variables - ore = /obj/item/ore/silver + mineral_name = ORE_SILVER // Ranged attack related variables ranged = TRUE // Will it shoot? diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/uranium.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/uranium.dm index 3ad57179a46..c5b0c53d367 100644 --- a/code/modules/mob/living/carbon/superior_animal/golem/types/uranium.dm +++ b/code/modules/mob/living/carbon/superior_animal/golem/types/uranium.dm @@ -29,7 +29,7 @@ ) // Loot related variables - ore = /obj/item/ore/uranium + mineral_name = ORE_URANIUM kept_distance = 3 retreat_on_too_close = TRUE From ef0910669be99013a67807fc33e61826347c49a9 Mon Sep 17 00:00:00 2001 From: Wrill <86113712+WrillWasTaken@users.noreply.github.com> Date: Mon, 10 Mar 2025 01:16:35 +0000 Subject: [PATCH 32/52] qol changes --- code/game/objects/items/weapons/storage/bags.dm | 2 +- code/modules/mining/ore.dm | 1 + .../mob/living/carbon/superior_animal/golem/golem_core.dm | 3 ++- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/code/game/objects/items/weapons/storage/bags.dm b/code/game/objects/items/weapons/storage/bags.dm index ecd2746cc11..af66b10b29d 100644 --- a/code/game/objects/items/weapons/storage/bags.dm +++ b/code/game/objects/items/weapons/storage/bags.dm @@ -109,7 +109,7 @@ icon_state = "satchel" slot_flags = SLOT_BELT | SLOT_POCKET w_class = ITEM_SIZE_NORMAL - max_storage_space = 200 + max_storage_space = 400 //stores 200 ore, not 400. max_w_class = ITEM_SIZE_NORMAL can_hold = list(/obj/item/ore) diff --git a/code/modules/mining/ore.dm b/code/modules/mining/ore.dm index 4db44988dfa..68e96a7c177 100644 --- a/code/modules/mining/ore.dm +++ b/code/modules/mining/ore.dm @@ -2,6 +2,7 @@ name = "rock" icon = 'icons/obj/mining.dmi' icon_state = "ore2" + layer = OBJ_LAYER - 0.05 //slightly below other items so that ore piles don't bury anything on the same tile w_class = ITEM_SIZE_SMALL rarity_value = 25 bad_type = /obj/item/ore diff --git a/code/modules/mob/living/carbon/superior_animal/golem/golem_core.dm b/code/modules/mob/living/carbon/superior_animal/golem/golem_core.dm index 38ec962c72e..c72c15cddf4 100644 --- a/code/modules/mob/living/carbon/superior_animal/golem/golem_core.dm +++ b/code/modules/mob/living/carbon/superior_animal/golem/golem_core.dm @@ -7,6 +7,7 @@ gender = PLURAL icon = 'icons/mob/golems.dmi' icon_state = "golem_core" + layer = OBJ_LAYER w_class = ITEM_SIZE_SMALL throwforce = 0 throw_speed = 4 @@ -34,7 +35,7 @@ if(!do_mob(user, M, 2 SECOND)) to_chat(user, SPAN_NOTICE("You must stand still to apply \the [src].")) return TRUE - + // Heal the target M.adjustBruteLoss(-GOLEM_CORE_HEAL) M.adjustFireLoss(-GOLEM_CORE_HEAL) From 678b6586cb2930f65f3ed8ad7fe06b4cce9eb6ca Mon Sep 17 00:00:00 2001 From: Wrill <86113712+WrillWasTaken@users.noreply.github.com> Date: Mon, 10 Mar 2025 21:32:02 +0000 Subject: [PATCH 33/52] commit spaghetti i forgot to commit and then i made another change and then i was like "oh one more change" and i still didn't commit and now here we are --- code/game/objects/items/weapons/tools/karl.dm | 22 ++++- .../modules/mining/drilling/cave_generator.dm | 85 +++++++++++++------ code/modules/mining/drilling/cave_mineral.dm | 9 ++ code/modules/mining/drilling/deep_drill.dm | 32 +++++-- code/modules/mining/drilling/difficulties.dm | 9 ++ code/modules/mining/mine_items.dm | 7 -- code/modules/mining/mine_turfs.dm | 8 +- .../carbon/superior_animal/golem/golem.dm | 2 +- .../superior_animal/golem/types/ansible.dm | 4 +- 9 files changed, 124 insertions(+), 54 deletions(-) diff --git a/code/game/objects/items/weapons/tools/karl.dm b/code/game/objects/items/weapons/tools/karl.dm index 43bb4d1de73..c148613a247 100644 --- a/code/game/objects/items/weapons/tools/karl.dm +++ b/code/game/objects/items/weapons/tools/karl.dm @@ -43,6 +43,7 @@ var/shot_sound // What sound should play when the gun fires var/reqpower = 10 // Power needed to shoot var/isPumping = FALSE // Whether someone is currently pumping the KARL to recharge it + var/pumping_time = 5 SECONDS /obj/item/tool/karl/New() . = ..() @@ -97,18 +98,17 @@ if(isPumping) to_chat(user, SPAN_NOTICE("You are already pumping \the [src] to recharge it.")) return - var/pumping_time = wielded ? 1 SECOND : 2 SECONDS isPumping = TRUE if(do_after(user, pumping_time)) if(cell) // Check the cell is still there in case big brain player chose to remove it during pumping - cell.give(use_power_cost * 1 SECOND) // Enough to use the tool during 1 second + cell.give(use_power_cost * pumping_time) to_chat(user, SPAN_NOTICE("You recharge \the [src] by pumping it, cell charge at [round(cell.percent())]%.")) // Continue pumping till user cancels the pumping isPumping = FALSE attack_self(user) isPumping = FALSE else - to_chat(user, SPAN_NOTICE("\The [src]\'cell is fully charged'.")) + to_chat(user, SPAN_NOTICE("\The [src]'s cell is fully charged'.")) else to_chat(user, SPAN_NOTICE("\The [src] is missing a cell to recharge.")) return @@ -140,7 +140,7 @@ // Recharge upon successfull use when switched off if(. && !switched_on && cell) - cell.give(use_power_cost * 1 SECOND) // Enough to use the tool during 1 second + cell.give(use_power_cost * 25) /obj/item/tool/karl/proc/toggle_mode_verb() set name = "Unique Action" @@ -206,3 +206,17 @@ nano_ui_interact(user) else toggle_karl_mode(user) + +/obj/item/tool/karl/attackby(var/obj/item/I, var/mob/user) + if(istype(I, /obj/item/golem_core)) + if(cell) + if(!cell.fully_charged()) + cell.give(200) + to_chat(user, SPAN_NOTICE("You use the [I] to charge the [src] to [round(cell.percent())]%, destroying it in the process.")) //this makes no sense realistically, but ye olde gameplay over realism + qdel(I) + else + to_chat(user, SPAN_NOTICE("The [src] is already fully charged.")) + else + to_chat(user, SPAN_NOTICE("Trying to recharge the [src] without a cell installed would be pointless.")) + else + . = ..() diff --git a/code/modules/mining/drilling/cave_generator.dm b/code/modules/mining/drilling/cave_generator.dm index 5fa0ef8277d..ca572521dd2 100644 --- a/code/modules/mining/drilling/cave_generator.dm +++ b/code/modules/mining/drilling/cave_generator.dm @@ -5,6 +5,10 @@ #define CAVE_CORRIDORS 10 // Number of corridors to guide cave generation #define CAVE_WALL_PROPORTION 70 // Proportion of wall in random noise generation #define CAVE_VWEIGHT 10 // Base mineral weight for choice of mineral vein +#define CAVE_VEINS_MINIMUM 8 +#define CAVE_VEINS_MAXIMUM 20 +#define CAVE_VEINS_SIZE 2 //size factor for veins generated with RNG +#define CAVE_VEINS_SIZE_FORCED 2 //size factor for veins forced to generate because RNG didn't generate any of that mineral type #define CAVE_COOLDOWN 5 MINUTES #define CAVE_COLLAPSE 3 MINUTES @@ -27,14 +31,11 @@ #define CAVE_SILVER 8 #define CAVE_GOLD 9 #define CAVE_PLATINUM 10 +#define CAVE_HYDROGEN 11 #define GOLEM_SPAWN_INTERVAL 15 // the spacing along each corridor that each golem squad will spawn #define GOLEM_SPAWN_SPACING 10 //squads WILL NOT spawn closer than this no matter what, even if corridors intersect or run too close.area -//chance for a cluster of 5 golems to spawn per tile, calculated as "GOLEM_SPAWN_CHANCE_BASE + (GOLEM_SPAWN_CHANCE_SCALING * seismic level)" -#define GOLEM_SPAWN_CHANCE_BASE 2.8 -#define GOLEM_SPAWN_CHANCE_SCALING 0.2 // 3% on level 1, 4% on level 6. - ////////////////////////////// // Generator used to handle underground caves ////////////////////////////// @@ -69,6 +70,9 @@ new /datum/cave_difficulty_level/expert, new /datum/cave_difficulty_level/nightmare ) + var/datum/cave_difficulty_level/current_difficulty + var/list/veins_to_guarantee = list() + var/orecount = 0 /obj/cave_generator/Initialize() // Initialize and not New to ensure SSmapping.maploader has been created @@ -80,6 +84,11 @@ pool_pois += new cave_poi_tmpl /obj/cave_generator/proc/generate_map(seismic_lvl = 1) + + current_difficulty = difficulties[seismic_lvl] + golem_spawn_nodes = list() + orecount = 0 + // Fill the map with random noise random_fill_map() @@ -121,7 +130,6 @@ // Draw a few straight lines in the initial random noise to guide the generation /obj/cave_generator/proc/generate_corridors() - // Draw a vertical corridor from (CAVE_MARGIN, CAVE_SIZE/2) to (CAVE_SIZE/2, CAVE_SIZE/2) // then recursively draw corridors that branches out from it draw_recursive_corridor(CAVE_MARGIN, CAVE_SIZE/2, CAVE_SIZE/2, CAVE_SIZE/2, CAVE_CORRIDORS/2) @@ -257,15 +265,29 @@ // Generate mineral veins once cave layout has been decided /obj/cave_generator/proc/generate_mineral_veins(seismic_lvl) + + veins_to_guarantee = list(/datum/cave_vein/carbon, //if these veins don't get spawned by RNG, force mini-veins to spawn + /datum/cave_vein/iron, + /datum/cave_vein/plasma, + /datum/cave_vein/silver, + /datum/cave_vein/gold, + /datum/cave_vein/uranium, + /datum/cave_vein/diamond, + /datum/cave_vein/platinum) var/x_vein = 0 var/y_vein = 0 - var/N_veins = rand(15, 20 * (1 + 0.5 * (seismic_lvl - SEISMIC_MIN) / (SEISMIC_MAX - SEISMIC_MIN))) + var/N_veins = rand(20, 35) var/N_trials = 50 while(N_veins > 0 && N_trials > 0) N_trials-- x_vein = rand(CAVE_MARGIN, CAVE_SIZE - CAVE_MARGIN) y_vein = rand(CAVE_MARGIN, CAVE_SIZE - CAVE_MARGIN) - N_veins -= place_mineral_vein(x_vein, y_vein, seismic_lvl) + N_veins -= place_mineral_vein(x_vein, y_vein, seismic_lvl, CAVE_VEINS_SIZE) + + for(var/datum/cave_vein/forcedvein in veins_to_guarantee) + x_vein = rand(CAVE_MARGIN, CAVE_SIZE - CAVE_MARGIN) + y_vein = rand(CAVE_MARGIN, CAVE_SIZE - CAVE_MARGIN) + N_veins -= place_mineral_vein(x_vein, y_vein, seismic_lvl, CAVE_VEINS_SIZE_FORCED, forcedvein) // Find a free spot in the cave /obj/cave_generator/proc/find_free_spot(x_start, y_start, x_margin = 0, y_margin = 0) @@ -437,7 +459,7 @@ QDEL_NULL(ladder_up) // Place a mineral vein starting at the designated spot -/obj/cave_generator/proc/place_mineral_vein(x_start, y_start, seismic_lvl) +/obj/cave_generator/proc/place_mineral_vein(x_start, y_start, seismic_lvl, sizemult = 1, vein_path) // Find closest available spot (wall tile near a free tile) var/search_for = map[x_start][y_start] == CAVE_FREE ? CAVE_WALL : CAVE_FREE @@ -481,23 +503,21 @@ // Choose which kind of mineral should the vein be made of // Multiplier scale from 0 to 1 - // Carbon and iron always have same probability - // Plasma, silver, gold scale up until medium seismic level - // Uranium, diamond and platinum scale up until max seismic level - var/seismic_mult = (seismic_lvl - SEISMIC_MIN) / (SEISMIC_MAX - SEISMIC_MIN) - var/list/datum/cave_vein/cave_veins = list(/datum/cave_vein/carbon = CAVE_VWEIGHT, - /datum/cave_vein/iron = CAVE_VWEIGHT, - /datum/cave_vein/plasma = CAVE_VWEIGHT * min(1, 2 * seismic_mult), - /datum/cave_vein/silver = CAVE_VWEIGHT * min(1, 2 * seismic_mult), - /datum/cave_vein/gold = CAVE_VWEIGHT * min(1, 2 * seismic_mult), - /datum/cave_vein/uranium = CAVE_VWEIGHT * seismic_mult, - /datum/cave_vein/diamond = CAVE_VWEIGHT * seismic_mult, - /datum/cave_vein/platinum = CAVE_VWEIGHT * seismic_mult) - var/vein_path = pickweight(cave_veins) + var/list/datum/cave_vein/cave_veins = list(/datum/cave_vein/carbon = CAVE_VWEIGHT * 2, + /datum/cave_vein/iron = CAVE_VWEIGHT * 2, + /datum/cave_vein/plasma = CAVE_VWEIGHT, + /datum/cave_vein/silver = CAVE_VWEIGHT, + /datum/cave_vein/gold = CAVE_VWEIGHT, + /datum/cave_vein/uranium = CAVE_VWEIGHT, + /datum/cave_vein/diamond = CAVE_VWEIGHT * 0.75, + /datum/cave_vein/platinum = CAVE_VWEIGHT * 0.75, + /datum/cave_vein/hydrogen = CAVE_VWEIGHT * ((seismic_lvl == 6) ? (CAVE_VWEIGHT * 0.5) : 0))//only generate on max difficulty. super duper valuable. + vein_path ||= pickweight(cave_veins) var/datum/cave_vein/CV = new vein_path() + veins_to_guarantee -= vein_path // Place mineral vein at the available spot in a recursive manner - place_recursive_mineral(x_start, y_start, CV.p_spread, CV.size_max, CV.size_min, CV.mineral) + place_recursive_mineral(x_start, y_start, CV.p_spread, ceil(CV.size_max * sizemult), floor(CV.size_min * sizemult), CV.mineral) return 1 // Place a mineral vein in a recursive manner @@ -586,6 +606,8 @@ turf_type = /turf/cave_mineral/gold if(CAVE_PLATINUM) turf_type = /turf/cave_mineral/platinum + if(CAVE_HYDROGEN) + turf_type = /turf/cave_mineral/hydrogen else turf_type = /turf/floor/asteroid/cave @@ -594,7 +616,9 @@ T.ChangeTurf(turf_type) if(istype(T, /turf/cave_mineral)) var/turf/cave_mineral/CM = T - CM.seismic_multiplier = seismic_lvl + CM.seismic_multiplier = current_difficulty.vein_ore_mult + CM.cave_gen = src + orecount++ // Spawn points of interest at their respective position /obj/cave_generator/proc/place_pois() @@ -608,8 +632,6 @@ // Spawn golems on free turfs depending on seismic level /obj/cave_generator/proc/place_golems(seismic_lvl) - var/list/datum/cave_difficulty_level/current_difficulty = difficulties[seismic_lvl] - for(var/turf/floor/asteroid/cave/spawnloc in golem_spawn_nodes) //filtering to only asteroid turfs avoids headaches with POIs and null locs that come from god knows where var/list/mob/living/carbon/superior_animal/golem/golems_to_spawn = current_difficulty.get_golem_spawns() @@ -691,6 +713,12 @@ size_min = 4 size_max = 8 +/datum/cave_vein/hydrogen //valuable and scarce + name = "hydrogen vein" + mineral = CAVE_HYDROGEN + size_min = 3 + size_max = 6 + ////////////////////////////// // Ladders to enter and exit the cave ////////////////////////////// @@ -727,6 +755,10 @@ #undef CAVE_CORRIDORS #undef CAVE_WALL_PROPORTION #undef CAVE_VWEIGHT +#undef CAVE_VEINS_MINIMUM +#undef CAVE_VEINS_MAXIMUM +#undef CAVE_VEINS_SIZE +#undef CAVE_VEINS_SIZE_FORCED #undef CAVE_COOLDOWN #undef CAVE_COLLAPSE @@ -749,7 +781,6 @@ #undef CAVE_SILVER #undef CAVE_GOLD #undef CAVE_PLATINUM +#undef CAVE_HYDROGEN -#undef GOLEM_SPAWN_CHANCE_BASE -#undef GOLEM_SPAWN_CHANCE_SCALING #undef GOLEM_SPAWN_SPACING diff --git a/code/modules/mining/drilling/cave_mineral.dm b/code/modules/mining/drilling/cave_mineral.dm index 8d012fa54fb..ce8e6a926c4 100644 --- a/code/modules/mining/drilling/cave_mineral.dm +++ b/code/modules/mining/drilling/cave_mineral.dm @@ -35,6 +35,7 @@ var/mineral_name var/mined_ore = 0 var/seismic_multiplier = 1 + var/obj/cave_generator/cave_gen has_resources = 1 @@ -97,6 +98,9 @@ //Not even going to touch this pile of spaghetti /turf/cave_mineral/attackby(obj/item/I, mob/living/user) + if(cave_gen) + cave_gen.orecount-- + var/tool_type = I.get_tool_type(user, list(QUALITY_DIGGING), src, CB = CALLBACK(src, PROC_REF(check_radial_dig))) switch(tool_type) if(QUALITY_DIGGING) @@ -122,6 +126,8 @@ /turf/cave_mineral/proc/GetDrilled() + + if (mineral && mineral.result_amount) // If the turf has already been excavated, some of it's ore has been removed clear_ore_effects() @@ -162,3 +168,6 @@ /turf/cave_mineral/platinum mineral_name = ORE_PLATINUM + +/turf/cave_mineral/hydrogen + mineral_name = ORE_HYDROGEN diff --git a/code/modules/mining/drilling/deep_drill.dm b/code/modules/mining/drilling/deep_drill.dm index 8730e69ef3d..e6046acb288 100644 --- a/code/modules/mining/drilling/deep_drill.dm +++ b/code/modules/mining/drilling/deep_drill.dm @@ -135,7 +135,7 @@ if(I.use_tool(user, src, WORKTIME_LONG, QUALITY_WELDING, FAILCHANCE_EASY, required_stat = STAT_ROB)) playsound(src, 'sound/items/Welder.ogg', 100, 1) to_chat(user, "You finish repairing the damage to [src].") - health = ((health + DRILL_REPAIR_AMOUNT) < maxHealth ? health + DRILL_REPAIR_AMOUNT : maxHealth) // increase health by the defined repair amount unless it would go over maxHealth, in which case just set heal to maxHealth instead. + health = min(maxHealth, health + DRILL_REPAIR_AMOUNT) return @@ -223,14 +223,28 @@ qdel(src) /obj/machinery/mining/deep_drill/examine(mob/user, extra_description = "") - if(health <= 0) - extra_description += "\n\The [src] is wrecked." - else if(health < maxHealth * 0.33) - extra_description += SPAN_DANGER("\n\The [src] looks like it's about to break!") - else if(health < maxHealth * 0.66) - extra_description += SPAN_DANGER("\n\The [src] looks seriously damaged!") - else if(health < maxHealth) - extra_description += "\n\The [src] shows signs of damage!" + if(cave_connected) + switch(cave_gen.orecount) + if(-INFINITY to 3) + extra_description += SPAN_NOTICE("\nThe integrated ore scanner can't detect any ore in the attached cave.") + if(3 to 10) + extra_description += SPAN_NOTICE("\nThe integrated ore scanner barely detects any ore in the attached cave.") + if(10 to 50) + extra_description += SPAN_NOTICE("\nThe integrated ore scanner still detects plenty of ore in the attached cave.") + if(50 to INFINITY) + extra_description += SPAN_NOTICE("\nThe integrated ore scanner detects an abundance of ore in the attached cave.") + else //something has gone wrong + extra_description += SPAN_WARNING("\nThe integrated ore scanner seems to be malfunctioning.") + if(health < maxHealth) + switch(health) + if(-INFINITY to 0) + extra_description += "\n\The [src] is wrecked." + if(0 to 600) + extra_description += SPAN_DANGER("\n\The [src] looks like it's about to break!") + if(600 to 1200) + extra_description += SPAN_DANGER("\n\The [src] looks seriously damaged!") + else + extra_description += "\n\The [src] shows signs of damage!" else extra_description += "\n\The [src] is in pristine condition." diff --git a/code/modules/mining/drilling/difficulties.dm b/code/modules/mining/drilling/difficulties.dm index 16f590cf619..bc91101cc50 100644 --- a/code/modules/mining/drilling/difficulties.dm +++ b/code/modules/mining/drilling/difficulties.dm @@ -1,7 +1,11 @@ +//Cave difficulty levels store most stats that affect cavegen based on seismic level.area +//Golems also store a reference to the current difficulty, currently used only for golem_ore_mult + /datum/cave_difficulty_level //using a datum here lets me simplify the spawn pool logic and declutter cave_generator.dm in the process var/level //number value is easier to work with in some situations var/golem_ore_mult = 1 + var/vein_ore_mult = 1 //number of golems to spawn *per squad* var/golem_count_melee = 0 @@ -45,6 +49,7 @@ /datum/cave_difficulty_level/novice level = 2 + vein_ore_mult = 1.5 golem_ore_mult = 1.75 golem_count_mixed = 3 @@ -61,6 +66,7 @@ /datum/cave_difficulty_level/adept level = 3 + vein_ore_mult = 2 golem_ore_mult = 2.5 golem_count_melee = 1 @@ -81,6 +87,7 @@ /datum/cave_difficulty_level/experienced level = 4 + vein_ore_mult = 2.5 golem_ore_mult = 3.25 golem_count_melee = 1 @@ -102,6 +109,7 @@ /datum/cave_difficulty_level/expert level = 5 + vein_ore_mult = 3 golem_ore_mult = 4 golem_count_melee = 2 @@ -123,6 +131,7 @@ /datum/cave_difficulty_level/nightmare level = 6 + vein_ore_mult = 4 golem_ore_mult = 4 golem_count_melee = 2 diff --git a/code/modules/mining/mine_items.dm b/code/modules/mining/mine_items.dm index 896f5ac06b5..bf020639bfa 100644 --- a/code/modules/mining/mine_items.dm +++ b/code/modules/mining/mine_items.dm @@ -16,22 +16,15 @@ new /obj/item/clothing/glasses/powered/meson(src) new /obj/item/clothing/shoes/color/black(src) new /obj/item/storage/belt/utility(src) - new /obj/item/cell/large/high(src) - new /obj/item/cell/large/high(src) new /obj/item/cell/medium/high(src) new /obj/item/cell/medium/high(src) new /obj/item/cell/small/high(src) new /obj/item/cell/small/high(src) - new /obj/item/tool_upgrade/augment/cell_mount(src) - new /obj/item/tool_upgrade/productivity/motor(src) new /obj/item/device/scanner/gas(src) new /obj/item/storage/bag/ore(src) new /obj/item/device/lighting/toggleable/flashlight/heavy(src) new /obj/item/tool/shovel(src) new /obj/item/tool/pickaxe(src) - new /obj/item/tool/pickaxe/jackhammer(src) - new /obj/item/gun/projectile/shotgun/doublebarrel(src) - new /obj/item/ammo_magazine/ammobox/shotgun(src) new /obj/item/device/t_scanner(src) new /obj/item/gun/projectile/flare_gun(src) new /obj/item/ammo_casing/flare(src) diff --git a/code/modules/mining/mine_turfs.dm b/code/modules/mining/mine_turfs.dm index b5bcb52d662..7b8b8859696 100644 --- a/code/modules/mining/mine_turfs.dm +++ b/code/modules/mining/mine_turfs.dm @@ -171,8 +171,8 @@ /turf/mineral/random name = "Mineral deposit" - var/mineralSpawnChanceList = list(ORE_URANIUM = 5, ORE_PLATINUM = 5, ORE_IRON = 35, ORE_CARBON = 35, ORE_DIAMOND = 1, ORE_GOLD = 5, ORE_SILVER = 5, ORE_PLASMA = 10, ORE_HYDROGEN = 1) - var/mineralChance = 100 //10 //means 10% chance of this plot changing to a mineral deposit + var/mineralSpawnChanceList = list(ORE_URANIUM = 5, ORE_PLATINUM = 5, ORE_IRON = 35, ORE_CARBON = 35, ORE_DIAMOND = 1, ORE_GOLD = 5, ORE_SILVER = 5, ORE_PLASMA = 10) + var/mineralChance = 50 //% /turf/mineral/random/New() if (prob(mineralChance) && !mineral) @@ -188,8 +188,8 @@ return TRUE /turf/mineral/random/high_chance - mineralChance = 100 //25 - mineralSpawnChanceList = list(ORE_URANIUM = 10, ORE_PLATINUM = 10, ORE_IRON = 20, ORE_CARBON = 20, ORE_DIAMOND = 2, ORE_GOLD = 10, ORE_SILVER = 10, ORE_PLASMA = 20, ORE_HYDROGEN = 1) + mineralChance = 75 //% + mineralSpawnChanceList = list(ORE_URANIUM = 10, ORE_PLATINUM = 10, ORE_IRON = 20, ORE_CARBON = 20, ORE_DIAMOND = 2, ORE_GOLD = 10, ORE_SILVER = 10, ORE_PLASMA = 20) /**********************Asteroid**************************/ diff --git a/code/modules/mob/living/carbon/superior_animal/golem/golem.dm b/code/modules/mob/living/carbon/superior_animal/golem/golem.dm index d24bdc63df3..9b54367514a 100644 --- a/code/modules/mob/living/carbon/superior_animal/golem/golem.dm +++ b/code/modules/mob/living/carbon/superior_animal/golem/golem.dm @@ -159,7 +159,7 @@ GLOBAL_LIST_EMPTY(active_golems) // smaller list that only contains golems with if(retreat_on_too_close) updatePathFinding() //retreating enemies need to update their pathfinding way more often - if((targetrecievedtime - world.time) < 50) // golems will disregard target validity temporarily after another golem gives them a target, so that they don't immediately lose their target + if(((targetrecievedtime + 5 SECONDS) > world.time) && (target_mob.z == z)) // golems will disregard target validity temporarily after another golem gives them a target, so that they don't immediately lose their target attemptAttackOnTarget() else prepareAttackOnTarget() diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/ansible.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/ansible.dm index 363d8634192..8a89e1e7d58 100644 --- a/code/modules/mob/living/carbon/superior_animal/golem/types/ansible.dm +++ b/code/modules/mob/living/carbon/superior_animal/golem/types/ansible.dm @@ -53,8 +53,8 @@ /mob/living/carbon/superior_animal/golem/ansible/death() if(prob(10)) //10% chance to drop a bs crystal. since ansible golems are only present on max difficulty this seems like a fair reward. - var/crystal = new /obj/item/bluespace_crystal(loc) - visible_message(SPAN_NOTICE("A [crystal] falls out of [src] as it disintegrates."), 1) + var/obj/item/bluespace_crystal/crystal = new /obj/item/bluespace_crystal(loc) + visible_message(SPAN_NOTICE("A [crystal.name] falls out of [src] as it disintegrates."), 1) ..() // Special capacity of ansible golem: it will focus and teleport a miner near other golems From b4b4ac9476eceb79df1cdac353db50e103c81feb Mon Sep 17 00:00:00 2001 From: Wrill <86113712+WrillWasTaken@users.noreply.github.com> Date: Thu, 13 Mar 2025 13:28:20 +0000 Subject: [PATCH 34/52] karl can no longer be toggled by ghosts, and fixes for charge from using it to mine --- code/game/objects/items/weapons/tools/karl.dm | 23 +++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/code/game/objects/items/weapons/tools/karl.dm b/code/game/objects/items/weapons/tools/karl.dm index c148613a247..e8e10e2bdba 100644 --- a/code/game/objects/items/weapons/tools/karl.dm +++ b/code/game/objects/items/weapons/tools/karl.dm @@ -28,8 +28,8 @@ // Turn on-off related toggleable = TRUE tool_qualities = list(QUALITY_DIGGING = 10, QUALITY_PRYING = 10, QUALITY_CUTTING = 5) // So it still shares its switch off quality despite not yet being used. - switched_off_qualities = list(QUALITY_DIGGING = 10, QUALITY_PRYING = 10, QUALITY_CUTTING = 5) - switched_on_qualities = list(QUALITY_DIGGING = 30, QUALITY_WELDING = 10) + switched_off_qualities = list(QUALITY_DIGGING = 30, QUALITY_PRYING = 10, QUALITY_CUTTING = 5) + switched_on_qualities = list(QUALITY_DIGGING = 45, QUALITY_WELDING = 10) suitable_cell = /obj/item/cell/medium/high use_power_cost = 1.5 passive_power_cost = 0.01 @@ -120,11 +120,13 @@ if(.) to_chat(user, SPAN_NOTICE("A dangerous energy blade now covers the edges of the tool.")) update_force() + update_use_cost() /obj/item/tool/karl/turn_off(mob/user) ..() to_chat(user, SPAN_NOTICE("The energy blade swiftly retracts.")) update_force() + update_use_cost() /obj/item/tool/karl/proc/update_force() if(gunmode) @@ -134,27 +136,40 @@ else force = initial(force) // Back to standard damage when KARL is turned off +/obj/item/tool/karl/proc/update_use_cost() + if(gunmode || !switched_on) + use_power_cost = 0 + else + use_power_cost = initial(use_power_cost) + + // Same values than /obj/item/proc/use_tool /obj/item/tool/karl/use_tool(mob/living/user, atom/target, base_time, required_quality, fail_chance, required_stat, instant_finish_tier = 110, forced_sound = null, sound_repeat = 2.5 SECONDS) . = ..() // That proc will return TRUE only when everything was done right, and FALSE if something went wrong, ot user was unlucky. // Recharge upon successfull use when switched off - if(. && !switched_on && cell) - cell.give(use_power_cost * 25) + if(. && !switched_on && cell && (istype(target, /turf/cave_mineral) || istype(target, /turf/mineral))) + cell.give(initial(use_power_cost) * 25) /obj/item/tool/karl/proc/toggle_mode_verb() set name = "Unique Action" set category = "Object" set src in view(1) + if(usr.incapacitated() || !Adjacent(usr)) + to_chat(usr, "You can't do that.") + return FALSE + toggle_karl_mode(usr) /obj/item/tool/karl/proc/toggle_karl_mode(mob/user) + gunmode = !gunmode to_chat(user, SPAN_NOTICE("\The [src] switches to [gunmode ? "gun" : "tool"] mode.")) no_double_tact = gunmode ? TRUE : FALSE // No double tact in gunmode no_swing = gunmode ? TRUE : FALSE // No swinging in gunmode update_force() + update_use_cost() update_icon() update_wear_icon() From 5c3c827f2d14944712acbbb064568eba0c181807 Mon Sep 17 00:00:00 2001 From: Wrill <86113712+WrillWasTaken@users.noreply.github.com> Date: Thu, 13 Mar 2025 13:38:56 +0000 Subject: [PATCH 35/52] move miner spawns to the mining dock map changes jumpscare --- maps/CEVEris/_CEV_Eris.dmm | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/maps/CEVEris/_CEV_Eris.dmm b/maps/CEVEris/_CEV_Eris.dmm index 2680ffb8233..a50fed8b336 100644 --- a/maps/CEVEris/_CEV_Eris.dmm +++ b/maps/CEVEris/_CEV_Eris.dmm @@ -91436,6 +91436,7 @@ /obj/machinery/light{ dir = 8 }, +/obj/landmark/join/start/mining, /turf/floor/tiled/steel/panels, /area/eris/quartermaster/miningdock) "etI" = ( @@ -91443,6 +91444,7 @@ dir = 4 }, /obj/machinery/light, +/obj/landmark/join/start/mining, /turf/floor/tiled/steel/gray_platform, /area/eris/quartermaster/miningdock) "etJ" = ( @@ -95057,8 +95059,8 @@ /area/eris/medical/medeva) "eCg" = ( /obj/landmark/join/start/mining, -/turf/floor/carpet, -/area/eris/quartermaster/misc) +/turf/floor/tiled/steel/panels, +/area/eris/quartermaster/miningdock) "eCh" = ( /obj/machinery/door/firedoor, /obj/machinery/door/airlock/engineering{ @@ -212127,8 +212129,8 @@ ewW cHz ewZ dII -euJ -euJ +eCg +eCg etH cHz cHz @@ -255136,10 +255138,10 @@ edM eou enR ehh -eCg +eCl edL egq -eCg +eCl ehh enR efW @@ -255338,10 +255340,10 @@ eFf ebN ebN eys -eCg +eCl edL egq -eCg +eCl ehh enR exT From 179c631df6d9114c65b929923d90479a3c064cf1 Mon Sep 17 00:00:00 2001 From: Wrill <86113712+WrillWasTaken@users.noreply.github.com> Date: Thu, 13 Mar 2025 14:53:30 +0000 Subject: [PATCH 36/52] a bundle of changes - Remove tile-based resources and the noise datum that generates them. Nothing used them anyway. - Remove advanced ore detector, it only existed to detect the now-removed tile resources. - More KARL fixes - Add some description_info text to mining equipment to make it more clear what to do. --- cev_eris.dme | 1 - code/controllers/subsystems/mapping.dm | 2 - code/game/objects/items/weapons/tools/karl.dm | 5 +- code/game/turfs/turf.dm | 2 - code/modules/mining/drilling/cave_mineral.dm | 2 - code/modules/mining/drilling/deep_drill.dm | 1 + code/modules/mining/drilling/scanner.dm | 78 +------------ code/modules/mining/mine_turfs.dm | 4 +- .../overmap/exoplanets/planet_types/barren.dm | 2 +- .../exoplanets/planet_types/chlorine.dm | 2 +- .../overmap/exoplanets/planet_types/desert.dm | 2 +- .../exoplanets/planet_types/garbage.dm | 2 +- .../exoplanets/planet_types/shrouded.dm | 2 +- .../overmap/exoplanets/planet_types/snow.dm | 2 +- .../exoplanets/planet_types/volcanic.dm | 2 +- code/modules/overmap/exoplanets/turfs.dm | 3 +- code/modules/random_map/noise/ore.dm | 106 ------------------ code/modules/research/designs/mining.dm | 4 +- 18 files changed, 21 insertions(+), 201 deletions(-) delete mode 100644 code/modules/random_map/noise/ore.dm diff --git a/cev_eris.dme b/cev_eris.dme index da9ed277ae5..235cbac9c91 100644 --- a/cev_eris.dme +++ b/cev_eris.dme @@ -2545,7 +2545,6 @@ #include "code\modules\random_map\noise\desert.dm" #include "code\modules\random_map\noise\magma.dm" #include "code\modules\random_map\noise\noise.dm" -#include "code\modules\random_map\noise\ore.dm" #include "code\modules\random_map\noise\tundra.dm" #include "code\modules\reagents\atomic_distillery.dm" #include "code\modules\reagents\bonsai.dm" diff --git a/code/controllers/subsystems/mapping.dm b/code/controllers/subsystems/mapping.dm index 76d34a05559..ef113db5dd2 100644 --- a/code/controllers/subsystems/mapping.dm +++ b/code/controllers/subsystems/mapping.dm @@ -19,8 +19,6 @@ SUBSYSTEM_DEF(mapping) admin_notice("Error: ASTEROID_Z_LEVELS config wasn't given a number.") // Now for the actual map generating. This occurs for every z-level defined in the config. new /datum/random_map/automata/cave_system(null, 1, 1, z_level, 300, 300) - // Let's add ore too. - new /datum/random_map/noise/ore(null, 1, 1, z_level, 64, 64) else admin_notice("Error: No asteroid z-levels defined in config!") diff --git a/code/game/objects/items/weapons/tools/karl.dm b/code/game/objects/items/weapons/tools/karl.dm index e8e10e2bdba..8b5417478c5 100644 --- a/code/game/objects/items/weapons/tools/karl.dm +++ b/code/game/objects/items/weapons/tools/karl.dm @@ -1,6 +1,7 @@ /obj/item/tool/karl name = "K.A.R.L" desc = "Kinetic Acceleration Reconfigurable Lodebreaker. Rock and stone to the bone, miner!" + description_info = "It can be recharged by applying a golem core to it, mining with the energy blade powered off, or by using it in-hand in gun mode." flags = CONDUCT slot_flags = SLOT_BELT icon = 'icons/obj/karl_mining.dmi' @@ -27,7 +28,7 @@ // Turn on-off related toggleable = TRUE - tool_qualities = list(QUALITY_DIGGING = 10, QUALITY_PRYING = 10, QUALITY_CUTTING = 5) // So it still shares its switch off quality despite not yet being used. + tool_qualities = list(QUALITY_DIGGING = 30, QUALITY_PRYING = 10, QUALITY_CUTTING = 5) // So it still shares its switch off quality despite not yet being used. switched_off_qualities = list(QUALITY_DIGGING = 30, QUALITY_PRYING = 10, QUALITY_CUTTING = 5) switched_on_qualities = list(QUALITY_DIGGING = 45, QUALITY_WELDING = 10) suitable_cell = /obj/item/cell/medium/high @@ -101,7 +102,7 @@ isPumping = TRUE if(do_after(user, pumping_time)) if(cell) // Check the cell is still there in case big brain player chose to remove it during pumping - cell.give(use_power_cost * pumping_time) + cell.give(initial(use_power_cost) * pumping_time) to_chat(user, SPAN_NOTICE("You recharge \the [src] by pumping it, cell charge at [round(cell.percent())]%.")) // Continue pumping till user cancels the pumping isPumping = FALSE diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index 28bec280614..d0b836a77ca 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -28,8 +28,6 @@ var/needs_air_update = FALSE var/datum/gas_mixture/air - var/has_resources - var/list/resources // Mining resources (for the large drills) var/list/initial_gas var/list/decals var/list/affecting_lights // List of light sources affecting this turf diff --git a/code/modules/mining/drilling/cave_mineral.dm b/code/modules/mining/drilling/cave_mineral.dm index ce8e6a926c4..76b6fe3296e 100644 --- a/code/modules/mining/drilling/cave_mineral.dm +++ b/code/modules/mining/drilling/cave_mineral.dm @@ -37,8 +37,6 @@ var/seismic_multiplier = 1 var/obj/cave_generator/cave_gen - has_resources = 1 - /turf/cave_mineral/Initialize() .=..() if (mineral_name && (mineral_name in ore_data)) diff --git a/code/modules/mining/drilling/deep_drill.dm b/code/modules/mining/drilling/deep_drill.dm index e6046acb288..0a41309c521 100644 --- a/code/modules/mining/drilling/deep_drill.dm +++ b/code/modules/mining/drilling/deep_drill.dm @@ -18,6 +18,7 @@ /obj/machinery/mining/deep_drill name = "deep mining drill head" desc = "An enormous drill to dig out deep ores." + description_info = "Can be used to open caves on asteroid surfaces, with difficulty and ore level depending on the seismic level of the tile it's activated on.\nThe seismic level of a tile can be found with a subsurface ore detector." icon_state = "mining_drill" pixel_x = -16 diff --git a/code/modules/mining/drilling/scanner.dm b/code/modules/mining/drilling/scanner.dm index f73f2b52579..4222ad54900 100644 --- a/code/modules/mining/drilling/scanner.dm +++ b/code/modules/mining/drilling/scanner.dm @@ -7,87 +7,19 @@ matter = list(MATERIAL_PLASTIC = 2, MATERIAL_STEEL = 1, MATERIAL_GLASS = 1) charge_per_use = 0.5 - var/precision = FALSE /obj/item/device/scanner/mining/is_valid_scan_target(atom/O) return istype(O, /turf) - /obj/item/device/scanner/mining/scan(turf/T, mob/user) - scan_data = mining_scan_action(T, user, precision) + scan_data = mining_scan_action(T, user) scan_title = "Subsurface ore scan - ([T.x], [T.y])" show_results(user) -/obj/item/device/scanner/mining/advanced - name = "advanced subsurface ore detector" - precision = TRUE - -/proc/mining_scan_action(turf/source, mob/user, precision) - if(precision) - return mining_scan_action_precise(source, user) - var/list/metals = list("surface minerals" = 0, - "precious metals" = 0, - "nuclear fuel" = 0, - "exotic matter" = 0 - ) - var/list/lines = list("Ore deposits found at [source.x], [source.y]:") - - for(var/turf/T in RANGE_TURFS(2, source)) - if(!T.has_resources) - continue - - for(var/metal in T.resources) - var/ore_type - - switch(metal) - if(MATERIAL_GLASS, MATERIAL_PLASTIC, MATERIAL_IRON) - ore_type = "surface minerals" - if(MATERIAL_GOLD, MATERIAL_SILVER, MATERIAL_DIAMOND) - ore_type = "precious metals" - if(MATERIAL_URANIUM) - ore_type = "nuclear fuel" - if(MATERIAL_PLASMA, MATERIAL_OSMIUM, MATERIAL_TRITIUM) - ore_type = "exotic matter" - - if(ore_type) - metals[ore_type] += T.resources[metal] - - for(var/ore_type in metals) - var/result = "no sign" - - switch(metals[ore_type]) - if(1 to 25) result = "trace amounts" - if(26 to 75) result = "significant amounts" - if(76 to INFINITY) result = "huge quantities" +/proc/mining_scan_action(turf/source, mob/user) - lines += "- [result] of [ore_type]." - - if(istype(source, /turf)) + if(istype(source, /turf/floor/asteroid) || istype(source, /turf/floor/exoplanet)) var/turf/source_simulated = source - lines += "Seismic activity (from 1 up to 6): [source_simulated.seismic_activity]" - else - lines += "Seismic activity: 1" - - return jointext(lines, "
") - -/proc/mining_scan_action_precise(turf/source, mob/user) - var/list/lines = list("Ore deposits found at [source.x], [source.y]:") - var/list/metals = list() - for(var/turf/T in RANGE_TURFS(2, source)) - if(!T.has_resources) - continue - - for(var/metal in T.resources) - metals[metal] += T.resources[metal] - - for(var/ore_type in metals) - var/result = "no sign" - - switch(metals[ore_type]) - if(1 to 25) result = "trace amounts" - if(26 to 75) result = "significant amounts" - if(76 to INFINITY) result = "huge quantities" - - lines += "- [result] of [ore_type]." + return "Seismic activity (from 1 up to 6): [source_simulated.seismic_activity]" - return jointext(lines, "
") + return "Seismic activity: N/A - The deep drill cannot mine this ground." diff --git a/code/modules/mining/mine_turfs.dm b/code/modules/mining/mine_turfs.dm index 7b8b8859696..f78a59b123f 100644 --- a/code/modules/mining/mine_turfs.dm +++ b/code/modules/mining/mine_turfs.dm @@ -35,8 +35,6 @@ var/obj/item/last_find var/datum/artifact_find/artifact_find - has_resources = 1 - /turf/mineral/Initialize() .=..() icon_state = "rock[rand(0,4)]" @@ -207,7 +205,6 @@ temperature = TCMB var/dug = 0 //0 = has not yet been dug, 1 = has already been dug var/overlay_detail - has_resources = 1 /turf/floor/asteroid/New() ..() @@ -215,6 +212,7 @@ if(prob(20)) overlay_detail = "asteroid[rand(0,8)]" updateMineralOverlays(1) + seismic_activity = rand(1,6) /turf/floor/asteroid/explosion_act(target_power, explosion_handler/handler) . = ..() diff --git a/code/modules/overmap/exoplanets/planet_types/barren.dm b/code/modules/overmap/exoplanets/planet_types/barren.dm index 34a7edbc1b6..3132cc60165 100644 --- a/code/modules/overmap/exoplanets/planet_types/barren.dm +++ b/code/modules/overmap/exoplanets/planet_types/barren.dm @@ -5,7 +5,7 @@ planetary_area = /area/exoplanet/barren rock_colors = list(COLOR_BEIGE, COLOR_GRAY80, COLOR_BROWN) possible_themes = list(/datum/exoplanet_theme/mountains) - map_generators = list(/datum/random_map/noise/exoplanet/barren, /datum/random_map/noise/ore/rich) + map_generators = list(/datum/random_map/noise/exoplanet/barren) ruin_tags_blacklist = RUIN_HABITAT|RUIN_WATER features_budget = 6 surface_color = "#847c6f" diff --git a/code/modules/overmap/exoplanets/planet_types/chlorine.dm b/code/modules/overmap/exoplanets/planet_types/chlorine.dm index 91ed9e9f57b..bc4d50dad02 100644 --- a/code/modules/overmap/exoplanets/planet_types/chlorine.dm +++ b/code/modules/overmap/exoplanets/planet_types/chlorine.dm @@ -5,7 +5,7 @@ planetary_area = /area/exoplanet/chlorine rock_colors = list(COLOR_GRAY80, COLOR_PALE_GREEN_GRAY, COLOR_PALE_BTL_GREEN) plant_colors = list("#eba487", "#ceeb87", "#eb879c", "#ebd687", "#f6d6c9", "#f2b3e0") - map_generators = list(/datum/random_map/noise/exoplanet/chlorine, /datum/random_map/noise/ore/poor) + map_generators = list(/datum/random_map/noise/exoplanet/chlorine) ruin_tags_blacklist = RUIN_HABITAT|RUIN_WATER surface_color = "#a3b879" water_color = COLOR_BOTTLE_GREEN diff --git a/code/modules/overmap/exoplanets/planet_types/desert.dm b/code/modules/overmap/exoplanets/planet_types/desert.dm index 93560d3ad6e..06348a422ea 100644 --- a/code/modules/overmap/exoplanets/planet_types/desert.dm +++ b/code/modules/overmap/exoplanets/planet_types/desert.dm @@ -6,7 +6,7 @@ rock_colors = list(COLOR_BEIGE, COLOR_PALE_YELLOW, COLOR_GRAY80, COLOR_BROWN) plant_colors = list("#efdd6f","#7b4a12","#e49135","#ba6222","#5c755e","#420d22") planet_colors = list(PIPE_COLOR_YELLOW, COLOR_AMBER) - map_generators = list(/datum/random_map/noise/exoplanet/desert, /datum/random_map/noise/ore/rich) + map_generators = list(/datum/random_map/noise/exoplanet/desert) surface_color = "#d6cca4" water_color = null diff --git a/code/modules/overmap/exoplanets/planet_types/garbage.dm b/code/modules/overmap/exoplanets/planet_types/garbage.dm index a7c1ce64e94..77ab31e86b5 100644 --- a/code/modules/overmap/exoplanets/planet_types/garbage.dm +++ b/code/modules/overmap/exoplanets/planet_types/garbage.dm @@ -3,7 +3,7 @@ desc = "An arid exoplanet with unnatural formations covering the surface. Hotspots of radiation detected." //color = "#a5a18b" planetary_area = /area/exoplanet/garbage - map_generators = list(/datum/random_map/noise/exoplanet/garbage, /datum/random_map/noise/ore/poor) + map_generators = list(/datum/random_map/noise/exoplanet/garbage) ruin_tags_whitelist = RUIN_ALIEN|RUIN_NATURAL|RUIN_WRECK plant_colors = list("#efdd6f","#7b4a12","#e49135","#ba6222","#5c755e","#120309") surface_color = "#a5a18b" diff --git a/code/modules/overmap/exoplanets/planet_types/shrouded.dm b/code/modules/overmap/exoplanets/planet_types/shrouded.dm index c1664703ce3..5d2600fd027 100644 --- a/code/modules/overmap/exoplanets/planet_types/shrouded.dm +++ b/code/modules/overmap/exoplanets/planet_types/shrouded.dm @@ -5,7 +5,7 @@ planetary_area = /area/exoplanet/shrouded rock_colors = list(COLOR_INDIGO, COLOR_DARK_BLUE_GRAY, COLOR_NAVY_BLUE) plant_colors = list("#3c5434", "#2f6655", "#0e703f", "#495139", "#394c66", "#1a3b77", "#3e3166", "#52457c", "#402d56", "#580d6d") - map_generators = list(/datum/random_map/noise/exoplanet/shrouded, /datum/random_map/noise/ore/poor) + map_generators = list(/datum/random_map/noise/exoplanet/shrouded) ruin_tags_blacklist = RUIN_HABITAT planet_colors = list(COLOR_DEEP_SKY_BLUE, COLOR_PURPLE) surface_color = "#3e3960" diff --git a/code/modules/overmap/exoplanets/planet_types/snow.dm b/code/modules/overmap/exoplanets/planet_types/snow.dm index 1674c78782c..7e7672fd3dc 100644 --- a/code/modules/overmap/exoplanets/planet_types/snow.dm +++ b/code/modules/overmap/exoplanets/planet_types/snow.dm @@ -5,7 +5,7 @@ planetary_area = /area/exoplanet/snow rock_colors = list(COLOR_DARK_BLUE_GRAY, COLOR_GUNMETAL, COLOR_GRAY80, COLOR_DARK_GRAY) plant_colors = list("#d0fef5","#93e1d8","#93e1d8", "#b2abbf", "#3590f3", "#4b4e6d") - map_generators = list(/datum/random_map/noise/exoplanet/snow, /datum/random_map/noise/ore/poor) + map_generators = list(/datum/random_map/noise/exoplanet/snow) planet_colors = list("#e8faff") surface_color = "#e8faff" water_color = "#b5dfeb" diff --git a/code/modules/overmap/exoplanets/planet_types/volcanic.dm b/code/modules/overmap/exoplanets/planet_types/volcanic.dm index a445ae0da94..550d402f344 100644 --- a/code/modules/overmap/exoplanets/planet_types/volcanic.dm +++ b/code/modules/overmap/exoplanets/planet_types/volcanic.dm @@ -6,7 +6,7 @@ rock_colors = list(COLOR_DARK_GRAY) plant_colors = list("#a23c05","#3f1f0d","#662929","#ba6222","#7a5b3a","#120309") possible_themes = list() - map_generators = list(/datum/random_map/automata/cave_system/mountains/volcanic, /datum/random_map/noise/exoplanet/volcanic, /datum/random_map/noise/ore/filthy_rich) + map_generators = list(/datum/random_map/automata/cave_system/mountains/volcanic, /datum/random_map/noise/exoplanet/volcanic) ruin_tags_blacklist = RUIN_HABITAT|RUIN_WATER planet_colors = list("#8e3900", COLOR_RED) surface_color = "#261e19" diff --git a/code/modules/overmap/exoplanets/turfs.dm b/code/modules/overmap/exoplanets/turfs.dm index 50e7937985f..41efe78190a 100644 --- a/code/modules/overmap/exoplanets/turfs.dm +++ b/code/modules/overmap/exoplanets/turfs.dm @@ -3,7 +3,6 @@ name = "space land" icon = 'icons/turf/desert.dmi' icon_state = "desert" - has_resources = 1 var/diggable = 1 var/dirt_color = "#7c5e42" initial_flooring = null @@ -24,6 +23,8 @@ //Must be done here, as light data is not fully carried over by ChangeTurf (but overlays are). if(E.planetary_area && istype(loc, world.area)) ChangeArea(src, E.planetary_area) + + seismic_activity = rand(1,6) ..() /turf/floor/exoplanet/attackby(obj/item/C, mob/user) diff --git a/code/modules/random_map/noise/ore.dm b/code/modules/random_map/noise/ore.dm deleted file mode 100644 index 69e11690cc9..00000000000 --- a/code/modules/random_map/noise/ore.dm +++ /dev/null @@ -1,106 +0,0 @@ -/datum/random_map/noise/ore - descriptor = "ore distribution map" - var/deep_val = 0.8 // Threshold for deep metals, set in new as percentage of cell_range. - var/rare_val = 0.7 // Threshold for rare metal, set in new as percentage of cell_range. - var/chunk_size = 4 // Size each cell represents on map - -/datum/random_map/noise/ore/New() - rare_val = cell_range * rare_val - deep_val = cell_range * deep_val - ..() - -/datum/random_map/noise/ore/check_map_sanity() - - var/rare_count = 0 - var/surface_count = 0 - var/deep_count = 0 - - // Increment map sanity counters. - for(var/value in map) - if(value < rare_val) - surface_count++ - else if(value < deep_val) - rare_count++ - else - deep_count++ - // Sanity check. - if(surface_count < MIN_SURFACE_COUNT) - admin_notice(SPAN_DANGER("Insufficient surface minerals. Rerolling..."), R_DEBUG) - return 0 - else if(rare_count < MIN_RARE_COUNT) - admin_notice(SPAN_DANGER("Insufficient rare minerals. Rerolling..."), R_DEBUG) - return 0 - else if(deep_count < MIN_DEEP_COUNT) - admin_notice(SPAN_DANGER("Insufficient deep minerals. Rerolling..."), R_DEBUG) - return 0 - else - return 1 - -/datum/random_map/noise/ore/apply_to_turf(var/x,var/y) - - var/tx = ((origin_x-1)+x)*chunk_size - var/ty = ((origin_y-1)+y)*chunk_size - - for(var/i=0,i Date: Thu, 13 Mar 2025 15:08:37 +0000 Subject: [PATCH 37/52] kill a stray apostrophe --- code/game/objects/items/weapons/tools/karl.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/objects/items/weapons/tools/karl.dm b/code/game/objects/items/weapons/tools/karl.dm index 8b5417478c5..92de3796cb2 100644 --- a/code/game/objects/items/weapons/tools/karl.dm +++ b/code/game/objects/items/weapons/tools/karl.dm @@ -109,7 +109,7 @@ attack_self(user) isPumping = FALSE else - to_chat(user, SPAN_NOTICE("\The [src]'s cell is fully charged'.")) + to_chat(user, SPAN_NOTICE("\The [src]'s cell is fully charged.")) else to_chat(user, SPAN_NOTICE("\The [src] is missing a cell to recharge.")) return From 59ed865a40847f6dbc7630643fedf628c4f3199d Mon Sep 17 00:00:00 2001 From: VmpOS2NHSkhkejA9 Date: Fri, 14 Mar 2025 14:53:49 +0000 Subject: [PATCH 38/52] Apply suggestions from code review Co-authored-by: SirRichardFrancis <65828539+SirRichardFrancis@users.noreply.github.com> --- code/datums/movement/mob.dm | 2 +- code/game/objects/items/weapons/tools/karl.dm | 4 ++-- code/modules/mob/living/carbon/superior_animal/attack.dm | 2 +- .../mob/living/carbon/superior_animal/golem/types/gold.dm | 6 +++--- .../mob/living/carbon/superior_animal/superior_animal.dm | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/code/datums/movement/mob.dm b/code/datums/movement/mob.dm index d141d374249..76ad9ea7fe1 100755 --- a/code/datums/movement/mob.dm +++ b/code/datums/movement/mob.dm @@ -249,7 +249,7 @@ to_chat(mob, "You're pinned down by \a [mob.pinned[1]]!") return MOVEMENT_STOP - if(mob.grabbed_by.len) + if(length(mob.grabbed_by)) return MOVEMENT_STOP /* TODO: Bay grab system if(G.stop_move()) diff --git a/code/game/objects/items/weapons/tools/karl.dm b/code/game/objects/items/weapons/tools/karl.dm index 92de3796cb2..7c8319013a6 100644 --- a/code/game/objects/items/weapons/tools/karl.dm +++ b/code/game/objects/items/weapons/tools/karl.dm @@ -158,7 +158,7 @@ set src in view(1) if(usr.incapacitated() || !Adjacent(usr)) - to_chat(usr, "You can't do that.") + to_chat(usr, SPAN_WARNING("You can't do that.")) return FALSE toggle_karl_mode(usr) @@ -223,7 +223,7 @@ else toggle_karl_mode(user) -/obj/item/tool/karl/attackby(var/obj/item/I, var/mob/user) +/obj/item/tool/karl/attackby(obj/item/I, mob/user) if(istype(I, /obj/item/golem_core)) if(cell) if(!cell.fully_charged()) diff --git a/code/modules/mob/living/carbon/superior_animal/attack.dm b/code/modules/mob/living/carbon/superior_animal/attack.dm index 59b1feff047..1c35dcd5eb7 100644 --- a/code/modules/mob/living/carbon/superior_animal/attack.dm +++ b/code/modules/mob/living/carbon/superior_animal/attack.dm @@ -1,7 +1,7 @@ /mob/living/carbon/superior_animal/attack_ui(slot_id) return -/mob/living/carbon/superior_animal/UnarmedAttack(atom/A, var/proximity, var/attackdamage) +/mob/living/carbon/superior_animal/UnarmedAttack(atom/A, proximity, attackdamage) if(!..()) return diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/gold.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/gold.dm index ebf3ffc7f5f..8358082536f 100644 --- a/code/modules/mob/living/carbon/superior_animal/golem/types/gold.dm +++ b/code/modules/mob/living/carbon/superior_animal/golem/types/gold.dm @@ -80,7 +80,7 @@ QDEL_IN(src, 20) - - - +#undef GOLD_SPIKE_COOLDOWN +#undef GOLD_SPIKE_WINDUP +#undef GOLD_SPIKE_DAMAGE diff --git a/code/modules/mob/living/carbon/superior_animal/superior_animal.dm b/code/modules/mob/living/carbon/superior_animal/superior_animal.dm index 2a307e3fa9f..94334d7ea0f 100644 --- a/code/modules/mob/living/carbon/superior_animal/superior_animal.dm +++ b/code/modules/mob/living/carbon/superior_animal/superior_animal.dm @@ -393,7 +393,7 @@ breakgrab() . = ..() -/mob/living/carbon/superior_animal/proc/simplegrab(var/mob/living/target) // superior animals won't do this naturally, but this proc makes it easy to implement such behaviour in specific mobs +/mob/living/carbon/superior_animal/proc/simplegrab(mob/living/target) // superior animals won't do this naturally, but this proc makes it easy to implement such behaviour in specific mobs if(!target && target_mob) target = target_mob // if no target was specified, but we have a target, default to them else if(!target || !Adjacent(target)) From 90a22ff8fc26ba75f999efc2d516a2bda6f81d84 Mon Sep 17 00:00:00 2001 From: VmpOS2NHSkhkejA9 Date: Fri, 14 Mar 2025 14:54:41 +0000 Subject: [PATCH 39/52] Update code/modules/mob/living/carbon/superior_animal/golem/types/plasma.dm Co-authored-by: SirRichardFrancis <65828539+SirRichardFrancis@users.noreply.github.com> --- .../mob/living/carbon/superior_animal/golem/types/plasma.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/plasma.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/plasma.dm index 5f8c7ca0ec8..0ac46186a83 100644 --- a/code/modules/mob/living/carbon/superior_animal/golem/types/plasma.dm +++ b/code/modules/mob/living/carbon/superior_animal/golem/types/plasma.dm @@ -52,7 +52,7 @@ /mob/living/carbon/superior_animal/golem/plasma/UnarmedAttack(atom/A, proximity) if(det_status == DET_STABLE) - src.death(FALSE, FALSE) + death(FALSE, FALSE) #undef DET_STABLE From b7f2b523bfc348b22198b9a16b9114e68aa14038 Mon Sep 17 00:00:00 2001 From: Wrill <86113712+WrillWasTaken@users.noreply.github.com> Date: Fri, 14 Mar 2025 15:00:36 +0000 Subject: [PATCH 40/52] swap ceil() and floor() for CEIL() and FLOOR() --- code/modules/mining/drilling/cave_generator.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mining/drilling/cave_generator.dm b/code/modules/mining/drilling/cave_generator.dm index ca572521dd2..3e597ab1dc4 100644 --- a/code/modules/mining/drilling/cave_generator.dm +++ b/code/modules/mining/drilling/cave_generator.dm @@ -517,7 +517,7 @@ veins_to_guarantee -= vein_path // Place mineral vein at the available spot in a recursive manner - place_recursive_mineral(x_start, y_start, CV.p_spread, ceil(CV.size_max * sizemult), floor(CV.size_min * sizemult), CV.mineral) + place_recursive_mineral(x_start, y_start, CV.p_spread, CEILING(CV.size_max * sizemult), FLOOR(CV.size_min * sizemult), CV.mineral) return 1 // Place a mineral vein in a recursive manner From 7cf82e38bc553b8082cbe1dac780342e0943781a Mon Sep 17 00:00:00 2001 From: Wrill <86113712+WrillWasTaken@users.noreply.github.com> Date: Fri, 14 Mar 2025 18:00:27 +0000 Subject: [PATCH 41/52] requested changes --- code/controllers/subsystems/mapping.dm | 1 + .../controllers/subsystems/processing/mobs.dm | 3 +++ .../modules/mining/drilling/cave_generator.dm | 7 +++---- code/modules/mining/drilling/cave_mineral.dm | 4 +--- code/modules/mining/drilling/difficulties.dm | 6 +++--- .../carbon/superior_animal/golem/golem.dm | 19 ++++++++++--------- .../superior_animal/golem/types/uranium.dm | 2 +- 7 files changed, 22 insertions(+), 20 deletions(-) diff --git a/code/controllers/subsystems/mapping.dm b/code/controllers/subsystems/mapping.dm index ef113db5dd2..34fabcf497e 100644 --- a/code/controllers/subsystems/mapping.dm +++ b/code/controllers/subsystems/mapping.dm @@ -7,6 +7,7 @@ SUBSYSTEM_DEF(mapping) var/dmm_suite/maploader = null var/list/teleportlocs = list() var/list/ghostteleportlocs = list() + var/list/cave_ore_count /datum/controller/subsystem/mapping/Initialize(start_timeofday) if(config.generate_asteroid) diff --git a/code/controllers/subsystems/processing/mobs.dm b/code/controllers/subsystems/processing/mobs.dm index 3dc36ade93e..cf6d5baff4d 100644 --- a/code/controllers/subsystems/processing/mobs.dm +++ b/code/controllers/subsystems/processing/mobs.dm @@ -10,6 +10,9 @@ PROCESSING_SUBSYSTEM_DEF(mobs) var/list/mob_list var/list/mob_living_by_zlevel[][] + var/list/golem_list = list() + var/list/golem_active_list = list() + /datum/controller/subsystem/processing/mobs/PreInit() mob_list = processing // Simply setups a more recognizable var name than "processing" MaxZChanged() diff --git a/code/modules/mining/drilling/cave_generator.dm b/code/modules/mining/drilling/cave_generator.dm index 3e597ab1dc4..a5bfbc67f0b 100644 --- a/code/modules/mining/drilling/cave_generator.dm +++ b/code/modules/mining/drilling/cave_generator.dm @@ -87,7 +87,7 @@ current_difficulty = difficulties[seismic_lvl] golem_spawn_nodes = list() - orecount = 0 + SSmapping.cave_ore_count = 0 // Fill the map with random noise random_fill_map() @@ -517,7 +517,7 @@ veins_to_guarantee -= vein_path // Place mineral vein at the available spot in a recursive manner - place_recursive_mineral(x_start, y_start, CV.p_spread, CEILING(CV.size_max * sizemult), FLOOR(CV.size_min * sizemult), CV.mineral) + place_recursive_mineral(x_start, y_start, CV.p_spread, CEILING(CV.size_max * sizemult, 1), FLOOR(CV.size_min * sizemult, 1), CV.mineral) return 1 // Place a mineral vein in a recursive manner @@ -617,8 +617,7 @@ if(istype(T, /turf/cave_mineral)) var/turf/cave_mineral/CM = T CM.seismic_multiplier = current_difficulty.vein_ore_mult - CM.cave_gen = src - orecount++ + SSmapping.cave_ore_count++ // Spawn points of interest at their respective position /obj/cave_generator/proc/place_pois() diff --git a/code/modules/mining/drilling/cave_mineral.dm b/code/modules/mining/drilling/cave_mineral.dm index 76b6fe3296e..572b4d45bf5 100644 --- a/code/modules/mining/drilling/cave_mineral.dm +++ b/code/modules/mining/drilling/cave_mineral.dm @@ -35,7 +35,6 @@ var/mineral_name var/mined_ore = 0 var/seismic_multiplier = 1 - var/obj/cave_generator/cave_gen /turf/cave_mineral/Initialize() .=..() @@ -96,8 +95,7 @@ //Not even going to touch this pile of spaghetti /turf/cave_mineral/attackby(obj/item/I, mob/living/user) - if(cave_gen) - cave_gen.orecount-- + SSmapping.cave_ore_count-- var/tool_type = I.get_tool_type(user, list(QUALITY_DIGGING), src, CB = CALLBACK(src, PROC_REF(check_radial_dig))) switch(tool_type) diff --git a/code/modules/mining/drilling/difficulties.dm b/code/modules/mining/drilling/difficulties.dm index bc91101cc50..656cac60a21 100644 --- a/code/modules/mining/drilling/difficulties.dm +++ b/code/modules/mining/drilling/difficulties.dm @@ -19,16 +19,16 @@ /datum/cave_difficulty_level/proc/get_golem_spawns() var/list/golems_to_spawn = list() //list of golem types to spawn if(golem_count_melee) - for(var/c = 0, c < golem_count_melee, c++) + for(var/c in 0 to golem_count_melee) golems_to_spawn += pickweight(golem_weights_melee) if(golem_count_ranged) - for(var/c = 0, c < golem_count_ranged, c++) + for(var/c in 0 to golem_count_ranged) golems_to_spawn += pickweight(golem_weights_ranged) if(golem_count_mixed) var/list/golem_weights_mixed = golem_weights_melee + golem_weights_ranged - for(var/c = 0, c < golem_count_mixed, c++) + for(var/c in 0 to golem_count_mixed) golems_to_spawn += pickweight(golem_weights_mixed) return golems_to_spawn diff --git a/code/modules/mob/living/carbon/superior_animal/golem/golem.dm b/code/modules/mob/living/carbon/superior_animal/golem/golem.dm index 9b54367514a..fb7b26f8515 100644 --- a/code/modules/mob/living/carbon/superior_animal/golem/golem.dm +++ b/code/modules/mob/living/carbon/superior_animal/golem/golem.dm @@ -21,9 +21,6 @@ #define GOLEM_REGENERATION 10 // Healing by special ability of uranium golems -GLOBAL_LIST_EMPTY(all_golems) // golems check this list to loop over allies -GLOBAL_LIST_EMPTY(active_golems) // smaller list that only contains golems with a current target mob - /mob/living/carbon/superior_animal/golem icon = 'icons/mob/golems.dmi' @@ -76,15 +73,17 @@ GLOBAL_LIST_EMPTY(active_golems) // smaller list that only contains golems with var/datum/cave_difficulty_level/difficultylevel //currently this is only used for multiplying ore drops /mob/living/carbon/superior_animal/golem/Initialize(var/mapload, difficulty) - GLOB.all_golems += src + SSmobs.golem_list += src if(mineral_name && (mineral_name in ore_data)) mineral = ore_data[mineral_name] difficultylevel = difficulty . = ..() /mob/living/carbon/superior_animal/golem/Destroy() - GLOB.all_golems -= src - GLOB.active_golems -= src + SSmobs.golem_list -= src + SSmobs.golem_active_list -= src + difficultylevel = null + mineral = null ..() /mob/living/carbon/superior_animal/golem/death(gibbed, message = deathmessage) @@ -92,7 +91,7 @@ GLOBAL_LIST_EMPTY(active_golems) // smaller list that only contains golems with // Spawn ores if(mineral) - var/nb_ores = ceil((mineral.result_amount + rand(-3, 3)) * (difficultylevel ? difficultylevel.golem_ore_mult : 1)) + var/nb_ores = CEILING((mineral.result_amount + rand(-3, 3)) * (difficultylevel ? difficultylevel.golem_ore_mult : 1), 1) for(var/i in 1 to nb_ores) new mineral.ore(loc) @@ -117,7 +116,7 @@ GLOBAL_LIST_EMPTY(active_golems) // smaller list that only contains golems with obstacle.attack_generic(src, rand(surrounds_mult * melee_damage_lower, surrounds_mult * melee_damage_upper), pick(attacktext), TRUE) /mob/living/carbon/superior_animal/golem/loseTarget() - GLOB.active_golems -= src + SSmobs.golem_active_list -= src . = ..() /mob/living/carbon/superior_animal/golem/handle_ai() @@ -136,8 +135,10 @@ GLOBAL_LIST_EMPTY(active_golems) // smaller list that only contains golems with target_mob = findTarget() if(target_mob) stance = HOSTILE_STANCE_ATTACK - for(var/mob/living/carbon/superior_animal/golem/ally in GLOB.all_golems) + SSmobs.golem_active_list += src + for(var/mob/living/carbon/superior_animal/golem/ally in SSmobs.golem_list) if(!ally.target_mob && (get_dist(ally, src) < 5)) + SSmobs.golem_active_list += ally ally.stance = HOSTILE_STANCE_ATTACK ally.target_mob = target_mob ally.targetrecievedtime = world.time diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/uranium.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/uranium.dm index c5b0c53d367..28c90d22dd0 100644 --- a/code/modules/mob/living/carbon/superior_animal/golem/types/uranium.dm +++ b/code/modules/mob/living/carbon/superior_animal/golem/types/uranium.dm @@ -45,7 +45,7 @@ /mob/living/carbon/superior_animal/golem/uranium/handle_ai() . = ..() if(target_mob) - for(var/mob/living/carbon/superior_animal/golem/ally in GLOB.active_golems) + for(var/mob/living/carbon/superior_animal/golem/ally in SSmobs.golem_active_list) if((ally != src) && (get_dist(src, ally) < GOLEM_URANIUM_HEAL_RANGE)) ally.adjustBruteLoss(-GOLEM_REGENERATION) ally.adjustFireLoss(-GOLEM_REGENERATION) From 46524408de90e493c3a9786d0a2d53b47a09ac31 Mon Sep 17 00:00:00 2001 From: Wrill <86113712+WrillWasTaken@users.noreply.github.com> Date: Fri, 14 Mar 2025 18:10:17 +0000 Subject: [PATCH 42/52] oh so THAT'S why they're failing --- code/controllers/subsystems/mapping.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/controllers/subsystems/mapping.dm b/code/controllers/subsystems/mapping.dm index 34fabcf497e..f43c6885061 100644 --- a/code/controllers/subsystems/mapping.dm +++ b/code/controllers/subsystems/mapping.dm @@ -7,7 +7,7 @@ SUBSYSTEM_DEF(mapping) var/dmm_suite/maploader = null var/list/teleportlocs = list() var/list/ghostteleportlocs = list() - var/list/cave_ore_count + var/cave_ore_count = 0 /datum/controller/subsystem/mapping/Initialize(start_timeofday) if(config.generate_asteroid) From 33ccdf79490e22d4fe2c5484574f434908e90ae5 Mon Sep 17 00:00:00 2001 From: VmpOS2NHSkhkejA9 Date: Fri, 14 Mar 2025 18:42:47 +0000 Subject: [PATCH 43/52] Update code/modules/mob/living/carbon/superior_animal/golem/types/plasma.dm Co-authored-by: SirRichardFrancis <65828539+SirRichardFrancis@users.noreply.github.com> --- .../mob/living/carbon/superior_animal/golem/types/plasma.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/plasma.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/plasma.dm index 0ac46186a83..bf3ad65f27c 100644 --- a/code/modules/mob/living/carbon/superior_animal/golem/types/plasma.dm +++ b/code/modules/mob/living/carbon/superior_animal/golem/types/plasma.dm @@ -38,7 +38,7 @@ /mob/living/carbon/superior_animal/golem/plasma/death(gibbed, message = deathmessage) if(det_status == DET_STABLE) - src.Stun(10) //prevent any movement. not actually sure if this is necessary for a dead mob. + Stun(10) // Prevents movement. Not actually sure if this is necessary for a dead mob. det_status = DET_BLOWING visible_message(SPAN_DANGER("\The [src] starts glowing!")) icon_state = "golem_plasma_explosion" From 8a38ef2b0bdbe2cb6b864962b9e2bd0b46ab1a6a Mon Sep 17 00:00:00 2001 From: VmpOS2NHSkhkejA9 Date: Fri, 14 Mar 2025 18:44:32 +0000 Subject: [PATCH 44/52] Update code/modules/mob/living/carbon/superior_animal/golem/types/plasma.dm Co-authored-by: SirRichardFrancis <65828539+SirRichardFrancis@users.noreply.github.com> --- .../mob/living/carbon/superior_animal/golem/types/plasma.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/plasma.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/plasma.dm index bf3ad65f27c..51cb24afb98 100644 --- a/code/modules/mob/living/carbon/superior_animal/golem/types/plasma.dm +++ b/code/modules/mob/living/carbon/superior_animal/golem/types/plasma.dm @@ -45,7 +45,7 @@ spawn(det_time) // Plasma ball on location visible_message(SPAN_DANGER("\The [src] explodes into a ball of burning palsma!")) - for(var/turf/floor/target_tile in range(2, loc)) + for(var/turf/floor/target_tile as anything in RANGE_TURFS(2, loc)) new /obj/effect/decal/cleanable/liquid_fuel(target_tile, 2, 1) spawn (0) target_tile.hotspot_expose((T20C * 2) + 380, 500) // From flamethrower code . = ..() From e16d00ed5d99fa2cb8f9f68fe7fe8c5b3b14b937 Mon Sep 17 00:00:00 2001 From: Wrill <86113712+WrillWasTaken@users.noreply.github.com> Date: Fri, 14 Mar 2025 19:18:21 +0000 Subject: [PATCH 45/52] optimizations + fixes for plasma golems --- .../living/carbon/superior_animal/golem/types/plasma.dm | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/plasma.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/plasma.dm index 51cb24afb98..cc2abe3c8fd 100644 --- a/code/modules/mob/living/carbon/superior_animal/golem/types/plasma.dm +++ b/code/modules/mob/living/carbon/superior_animal/golem/types/plasma.dm @@ -38,21 +38,22 @@ /mob/living/carbon/superior_animal/golem/plasma/death(gibbed, message = deathmessage) if(det_status == DET_STABLE) - Stun(10) // Prevents movement. Not actually sure if this is necessary for a dead mob. + walk(src,0) + anchored = TRUE // Prevents movement. det_status = DET_BLOWING visible_message(SPAN_DANGER("\The [src] starts glowing!")) icon_state = "golem_plasma_explosion" spawn(det_time) // Plasma ball on location - visible_message(SPAN_DANGER("\The [src] explodes into a ball of burning palsma!")) + visible_message(SPAN_DANGER("\The [src] explodes into a ball of burning plasma!")) for(var/turf/floor/target_tile as anything in RANGE_TURFS(2, loc)) new /obj/effect/decal/cleanable/liquid_fuel(target_tile, 2, 1) - spawn (0) target_tile.hotspot_expose((T20C * 2) + 380, 500) // From flamethrower code + target_tile.hotspot_expose((T20C * 2) + 380, 500) // From flamethrower code . = ..() /mob/living/carbon/superior_animal/golem/plasma/UnarmedAttack(atom/A, proximity) if(det_status == DET_STABLE) - death(FALSE, FALSE) + death(FALSE) #undef DET_STABLE From 76e7dd487256301a54e58397b8ee5a9b3b2fc975 Mon Sep 17 00:00:00 2001 From: Wrill <86113712+WrillWasTaken@users.noreply.github.com> Date: Sat, 15 Mar 2025 15:01:42 +0000 Subject: [PATCH 46/52] swap over to `getMobsInRangeChunked()` --- code/controllers/subsystems/processing/mobs.dm | 3 --- .../living/carbon/superior_animal/golem/golem.dm | 13 ++----------- .../carbon/superior_animal/golem/types/ansible.dm | 7 +------ .../carbon/superior_animal/golem/types/uranium.dm | 5 ++--- 4 files changed, 5 insertions(+), 23 deletions(-) diff --git a/code/controllers/subsystems/processing/mobs.dm b/code/controllers/subsystems/processing/mobs.dm index cf6d5baff4d..3dc36ade93e 100644 --- a/code/controllers/subsystems/processing/mobs.dm +++ b/code/controllers/subsystems/processing/mobs.dm @@ -10,9 +10,6 @@ PROCESSING_SUBSYSTEM_DEF(mobs) var/list/mob_list var/list/mob_living_by_zlevel[][] - var/list/golem_list = list() - var/list/golem_active_list = list() - /datum/controller/subsystem/processing/mobs/PreInit() mob_list = processing // Simply setups a more recognizable var name than "processing" MaxZChanged() diff --git a/code/modules/mob/living/carbon/superior_animal/golem/golem.dm b/code/modules/mob/living/carbon/superior_animal/golem/golem.dm index fb7b26f8515..2763fae1393 100644 --- a/code/modules/mob/living/carbon/superior_animal/golem/golem.dm +++ b/code/modules/mob/living/carbon/superior_animal/golem/golem.dm @@ -73,15 +73,12 @@ var/datum/cave_difficulty_level/difficultylevel //currently this is only used for multiplying ore drops /mob/living/carbon/superior_animal/golem/Initialize(var/mapload, difficulty) - SSmobs.golem_list += src if(mineral_name && (mineral_name in ore_data)) mineral = ore_data[mineral_name] difficultylevel = difficulty . = ..() /mob/living/carbon/superior_animal/golem/Destroy() - SSmobs.golem_list -= src - SSmobs.golem_active_list -= src difficultylevel = null mineral = null ..() @@ -115,10 +112,6 @@ if(obstacle) obstacle.attack_generic(src, rand(surrounds_mult * melee_damage_lower, surrounds_mult * melee_damage_upper), pick(attacktext), TRUE) -/mob/living/carbon/superior_animal/golem/loseTarget() - SSmobs.golem_active_list -= src - . = ..() - /mob/living/carbon/superior_animal/golem/handle_ai() objectsInView = null @@ -135,10 +128,8 @@ target_mob = findTarget() if(target_mob) stance = HOSTILE_STANCE_ATTACK - SSmobs.golem_active_list += src - for(var/mob/living/carbon/superior_animal/golem/ally in SSmobs.golem_list) - if(!ally.target_mob && (get_dist(ally, src) < 5)) - SSmobs.golem_active_list += ally + for(var/mob/living/carbon/superior_animal/golem/ally in getMobsInRangeChunked(src, 5, TRUE)) + if(!ally.target_mob) ally.stance = HOSTILE_STANCE_ATTACK ally.target_mob = target_mob ally.targetrecievedtime = world.time diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/ansible.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/ansible.dm index 8a89e1e7d58..2ec9f5fae0e 100644 --- a/code/modules/mob/living/carbon/superior_animal/golem/types/ansible.dm +++ b/code/modules/mob/living/carbon/superior_animal/golem/types/ansible.dm @@ -62,12 +62,7 @@ // Teleport target to a random golem near the ansible golem if(target_mob) - var/list/teleport_destinations = list() - - for(var/mob/living/carbon/superior_animal/golem/td in range(ANSIBLE_TELEPORT_RANGE, get_turf(src))) - teleport_destinations += td - - go_to_bluespace(get_turf(src), 1, TRUE, target_mob,pick(teleport_destinations)) + go_to_bluespace(get_turf(src), 1, TRUE, target_mob, pick(getMobsInRangeChunked(src, ANSIBLE_TELEPORT_RANGE, TRUE))) /mob/living/carbon/superior_animal/golem/ansible/proc/focus_target() diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/uranium.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/uranium.dm index 28c90d22dd0..3fbcff002ad 100644 --- a/code/modules/mob/living/carbon/superior_animal/golem/types/uranium.dm +++ b/code/modules/mob/living/carbon/superior_animal/golem/types/uranium.dm @@ -45,8 +45,7 @@ /mob/living/carbon/superior_animal/golem/uranium/handle_ai() . = ..() if(target_mob) - for(var/mob/living/carbon/superior_animal/golem/ally in SSmobs.golem_active_list) - if((ally != src) && (get_dist(src, ally) < GOLEM_URANIUM_HEAL_RANGE)) + for(var/mob/living/carbon/superior_animal/golem/ally in getMobsInRangeChunked(src, GOLEM_URANIUM_HEAL_RANGE, TRUE)) + if((ally != src)) ally.adjustBruteLoss(-GOLEM_REGENERATION) ally.adjustFireLoss(-GOLEM_REGENERATION) - From bfb2c21f6d5f58cd287c39decc377d9c20881522 Mon Sep 17 00:00:00 2001 From: Wrill <86113712+WrillWasTaken@users.noreply.github.com> Date: Sun, 16 Mar 2025 12:47:31 +0000 Subject: [PATCH 47/52] Update cave_generator.dm --- code/modules/mining/drilling/cave_generator.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mining/drilling/cave_generator.dm b/code/modules/mining/drilling/cave_generator.dm index a5bfbc67f0b..067bc848041 100644 --- a/code/modules/mining/drilling/cave_generator.dm +++ b/code/modules/mining/drilling/cave_generator.dm @@ -511,7 +511,7 @@ /datum/cave_vein/uranium = CAVE_VWEIGHT, /datum/cave_vein/diamond = CAVE_VWEIGHT * 0.75, /datum/cave_vein/platinum = CAVE_VWEIGHT * 0.75, - /datum/cave_vein/hydrogen = CAVE_VWEIGHT * ((seismic_lvl == 6) ? (CAVE_VWEIGHT * 0.5) : 0))//only generate on max difficulty. super duper valuable. + /datum/cave_vein/hydrogen = (seismic_lvl == 6) ? (CAVE_VWEIGHT * 0.5) : 0)//only generate on max difficulty. super duper valuable. vein_path ||= pickweight(cave_veins) var/datum/cave_vein/CV = new vein_path() veins_to_guarantee -= vein_path From 4b6f9bd48fefa59cc29afa159cdec56d73f7da52 Mon Sep 17 00:00:00 2001 From: VmpOS2NHSkhkejA9 Date: Sun, 16 Mar 2025 14:05:26 +0000 Subject: [PATCH 48/52] Update code/modules/mob/living/carbon/superior_animal/superior_animal.dm Co-authored-by: hyperioo <64754494+hyperioo@users.noreply.github.com> --- .../mob/living/carbon/superior_animal/superior_animal.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mob/living/carbon/superior_animal/superior_animal.dm b/code/modules/mob/living/carbon/superior_animal/superior_animal.dm index 94334d7ea0f..36bcddefb79 100644 --- a/code/modules/mob/living/carbon/superior_animal/superior_animal.dm +++ b/code/modules/mob/living/carbon/superior_animal/superior_animal.dm @@ -399,7 +399,7 @@ else if(!target || !Adjacent(target)) return - visible_message("[src] grabs [target]!") + visible_message(SPAN_WARNING("[src] grabs [target]!")) target.grabbed_by += src grabbing = target cheap_update_lying_buckled_and_verb_status_() From d1a6a8d17d124477d7a78981262cc92de3735c82 Mon Sep 17 00:00:00 2001 From: VmpOS2NHSkhkejA9 Date: Sun, 16 Mar 2025 14:05:37 +0000 Subject: [PATCH 49/52] Update code/modules/mob/living/carbon/resist.dm Co-authored-by: hyperioo <64754494+hyperioo@users.noreply.github.com> --- code/modules/mob/living/carbon/resist.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mob/living/carbon/resist.dm b/code/modules/mob/living/carbon/resist.dm index bb44b31aaac..1c7e94c6007 100644 --- a/code/modules/mob/living/carbon/resist.dm +++ b/code/modules/mob/living/carbon/resist.dm @@ -80,7 +80,7 @@ resisting++ if(prob(max(((stats?.getStat(STAT_ROB) ** 0.9) / grabbed_by.len),20))) G_mob.breakgrab() - visible_message("[src] has broken free of [G_mob]'s grip!") + visible_message(SPAN_WARNING("[src] has broken free of [G_mob]'s grip!")) if(resisting) setClickCooldown(20) From 356ea7723cb9f597ae469eb1c701ded579794761 Mon Sep 17 00:00:00 2001 From: Wrill <86113712+WrillWasTaken@users.noreply.github.com> Date: Sun, 16 Mar 2025 14:08:08 +0000 Subject: [PATCH 50/52] remove the 1s --- .../mob/living/carbon/superior_animal/golem/types/ansible.dm | 2 +- .../mob/living/carbon/superior_animal/golem/types/coal.dm | 2 +- .../mob/living/carbon/superior_animal/golem/types/platinum.dm | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/ansible.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/ansible.dm index 2ec9f5fae0e..42ca9ed3183 100644 --- a/code/modules/mob/living/carbon/superior_animal/golem/types/ansible.dm +++ b/code/modules/mob/living/carbon/superior_animal/golem/types/ansible.dm @@ -54,7 +54,7 @@ /mob/living/carbon/superior_animal/golem/ansible/death() if(prob(10)) //10% chance to drop a bs crystal. since ansible golems are only present on max difficulty this seems like a fair reward. var/obj/item/bluespace_crystal/crystal = new /obj/item/bluespace_crystal(loc) - visible_message(SPAN_NOTICE("A [crystal.name] falls out of [src] as it disintegrates."), 1) + visible_message(SPAN_NOTICE("A [crystal.name] falls out of [src] as it disintegrates.")) ..() // Special capacity of ansible golem: it will focus and teleport a miner near other golems diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/coal.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/coal.dm index bceed7f70ac..51fde12f328 100644 --- a/code/modules/mob/living/carbon/superior_animal/golem/types/coal.dm +++ b/code/modules/mob/living/carbon/superior_animal/golem/types/coal.dm @@ -36,7 +36,7 @@ /mob/living/carbon/superior_animal/golem/coal/enhanced/UnarmedAttack(atom/A, proximity) if(istype(A, /mob/living/carbon)) - visible_message(SPAN_DANGER("[src] grabs at [target_mob]!"), 1) + visible_message(SPAN_DANGER("[src] grabs at [target_mob]!")) playsound(src, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) simplegrab(target_mob) else // if they're not a carbon just attack them normally. this includes things like simple animals diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/platinum.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/platinum.dm index 4da16bf7e57..c5a0b751fa4 100644 --- a/code/modules/mob/living/carbon/superior_animal/golem/types/platinum.dm +++ b/code/modules/mob/living/carbon/superior_animal/golem/types/platinum.dm @@ -46,7 +46,7 @@ charge_cooldown = world.time + PLATINUM_CHARGE_CD walk(src,0) // halt movement - visible_message(SPAN_DANGER("[src] stops and prepares to charge at [target_mob]!"), 1) + visible_message(SPAN_DANGER("[src] stops and prepares to charge at [target_mob]!")) var/list/passedturfs = getline(src, target_mob) // do this at the start of the windup, so that the golem's charge doesn't track the target (and it can be dodged) spawn(PLATINUM_CHARGE_WINDUP) @@ -81,7 +81,7 @@ victim.explosion_act(PLATINUM_CHARGE_DAMAGE_OBSTACLES * 4) //TEAR THROUGH ALL THAT IMPEDES YOU break // if the turf is blocked (ie a wall/door/window), stop charging here - visible_message(SPAN_DANGER("[src] [pick(charge_verbs)] at [target_mob]!"), 1) + visible_message(SPAN_DANGER("[src] [pick(charge_verbs)] at [target_mob]!")) forceMove(lastvalidturf) if(Adjacent(target_mob)) From a8f517f8040044b30278276ec820d786fcea6801 Mon Sep 17 00:00:00 2001 From: Wrill <86113712+WrillWasTaken@users.noreply.github.com> Date: Sun, 16 Mar 2025 18:08:30 +0000 Subject: [PATCH 51/52] Update golem.dm --- .../mob/living/carbon/superior_animal/golem/golem.dm | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/code/modules/mob/living/carbon/superior_animal/golem/golem.dm b/code/modules/mob/living/carbon/superior_animal/golem/golem.dm index 2763fae1393..833b9b81429 100644 --- a/code/modules/mob/living/carbon/superior_animal/golem/golem.dm +++ b/code/modules/mob/living/carbon/superior_animal/golem/golem.dm @@ -67,19 +67,19 @@ // Ore datum the golem holds. var/ore/mineral var/mineral_name + var/oremult = 1 var/targetrecievedtime = -250 - var/datum/cave_difficulty_level/difficultylevel //currently this is only used for multiplying ore drops - -/mob/living/carbon/superior_animal/golem/Initialize(var/mapload, difficulty) +/mob/living/carbon/superior_animal/golem/Initialize(mapload, var/datum/cave_difficulty_level/difficulty) if(mineral_name && (mineral_name in ore_data)) mineral = ore_data[mineral_name] - difficultylevel = difficulty + + if(difficulty) + oremult = difficulty.golem_ore_mult . = ..() /mob/living/carbon/superior_animal/golem/Destroy() - difficultylevel = null mineral = null ..() @@ -88,7 +88,7 @@ // Spawn ores if(mineral) - var/nb_ores = CEILING((mineral.result_amount + rand(-3, 3)) * (difficultylevel ? difficultylevel.golem_ore_mult : 1), 1) + var/nb_ores = CEILING((mineral.result_amount + rand(-3, 3)) * oremult, 1) for(var/i in 1 to nb_ores) new mineral.ore(loc) From cb46bbe2cfa36c6302895ca32b50a424fe7d7cc5 Mon Sep 17 00:00:00 2001 From: Wrill <86113712+WrillWasTaken@users.noreply.github.com> Date: Fri, 21 Mar 2025 23:48:23 +0000 Subject: [PATCH 52/52] balance pass --- code/modules/mining/drilling/difficulties.dm | 26 +++++++++---------- code/modules/mining/satchel_ore_boxdm.dm | 1 + .../superior_animal/golem/types/gold.dm | 6 ++--- .../superior_animal/golem/types/platinum.dm | 11 ++++---- .../superior_animal/golem/types/silver.dm | 4 +-- .../superior_animal/golem/types/uranium.dm | 2 +- 6 files changed, 26 insertions(+), 24 deletions(-) diff --git a/code/modules/mining/drilling/difficulties.dm b/code/modules/mining/drilling/difficulties.dm index 656cac60a21..2bdd282ada5 100644 --- a/code/modules/mining/drilling/difficulties.dm +++ b/code/modules/mining/drilling/difficulties.dm @@ -19,16 +19,16 @@ /datum/cave_difficulty_level/proc/get_golem_spawns() var/list/golems_to_spawn = list() //list of golem types to spawn if(golem_count_melee) - for(var/c in 0 to golem_count_melee) + for(var/c = 1 to golem_count_melee) golems_to_spawn += pickweight(golem_weights_melee) if(golem_count_ranged) - for(var/c in 0 to golem_count_ranged) + for(var/c = 1 to golem_count_ranged) golems_to_spawn += pickweight(golem_weights_ranged) if(golem_count_mixed) var/list/golem_weights_mixed = golem_weights_melee + golem_weights_ranged - for(var/c in 0 to golem_count_mixed) + for(var/c = 1 to golem_count_mixed) golems_to_spawn += pickweight(golem_weights_mixed) return golems_to_spawn @@ -71,12 +71,12 @@ golem_count_melee = 1 golem_count_ranged = 1 - golem_count_mixed = 3 + golem_count_mixed = 2 golem_weights_melee = list( - /mob/living/carbon/superior_animal/golem/iron = 4, + /mob/living/carbon/superior_animal/golem/iron = 5, /mob/living/carbon/superior_animal/golem/coal = 2, - /mob/living/carbon/superior_animal/golem/platinum = 3) + /mob/living/carbon/superior_animal/golem/platinum = 2) golem_weights_ranged = list( /mob/living/carbon/superior_animal/golem/silver = 3, @@ -92,11 +92,11 @@ golem_count_melee = 1 golem_count_ranged = 1 - golem_count_mixed = 3 + golem_count_mixed = 2 golem_weights_melee = list( - /mob/living/carbon/superior_animal/golem/iron = 4, - /mob/living/carbon/superior_animal/golem/coal/enhanced = 2, + /mob/living/carbon/superior_animal/golem/iron = 8, + /mob/living/carbon/superior_animal/golem/coal/enhanced = 4, /mob/living/carbon/superior_animal/golem/platinum = 3, /mob/living/carbon/superior_animal/golem/plasma = 2) @@ -117,8 +117,8 @@ golem_count_mixed = 1 golem_weights_melee = list( - /mob/living/carbon/superior_animal/golem/iron = 3, - /mob/living/carbon/superior_animal/golem/coal/enhanced = 2, + /mob/living/carbon/superior_animal/golem/iron = 6, + /mob/living/carbon/superior_animal/golem/coal/enhanced = 4, /mob/living/carbon/superior_animal/golem/platinum = 3, /mob/living/carbon/superior_animal/golem/plasma = 2) golem_weights_ranged = list( @@ -139,8 +139,8 @@ golem_count_mixed = 1 golem_weights_melee = list( - /mob/living/carbon/superior_animal/golem/iron = 3, - /mob/living/carbon/superior_animal/golem/coal/enhanced = 2, + /mob/living/carbon/superior_animal/golem/iron = 8, + /mob/living/carbon/superior_animal/golem/coal/enhanced = 6, /mob/living/carbon/superior_animal/golem/platinum = 3, /mob/living/carbon/superior_animal/golem/plasma = 2, /mob/living/carbon/superior_animal/golem/diamond = 2) diff --git a/code/modules/mining/satchel_ore_boxdm.dm b/code/modules/mining/satchel_ore_boxdm.dm index aca6c84753e..b8e6833b97b 100644 --- a/code/modules/mining/satchel_ore_boxdm.dm +++ b/code/modules/mining/satchel_ore_boxdm.dm @@ -9,6 +9,7 @@ density = TRUE rarity_value = 10 spawn_tags = SPAWN_TAG_STRUCTURE_COMMON + climbable = TRUE var/last_update = 0 var/list/stored_ore = list() diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/gold.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/gold.dm index 8358082536f..d85b8d45fdc 100644 --- a/code/modules/mob/living/carbon/superior_animal/golem/types/gold.dm +++ b/code/modules/mob/living/carbon/superior_animal/golem/types/gold.dm @@ -1,6 +1,6 @@ -#define GOLD_SPIKE_COOLDOWN 50 // 5 seconds -#define GOLD_SPIKE_WINDUP 20 -#define GOLD_SPIKE_DAMAGE 40 //equivalent to GOLEM_DMG_HIGH +#define GOLD_SPIKE_COOLDOWN 5 SECONDS +#define GOLD_SPIKE_WINDUP 2 SECONDS +#define GOLD_SPIKE_DAMAGE 25 /mob/living/carbon/superior_animal/golem/gold name = "gold golem" diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/platinum.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/platinum.dm index c5a0b751fa4..8f40f65eec9 100644 --- a/code/modules/mob/living/carbon/superior_animal/golem/types/platinum.dm +++ b/code/modules/mob/living/carbon/superior_animal/golem/types/platinum.dm @@ -1,5 +1,5 @@ -#define PLATINUM_CHARGE_DAMAGE_OBSTACLES 50 -#define PLATINUM_CHARGE_DAMAGE_TARGET 50 +#define PLATINUM_CHARGE_DAMAGE_OBSTACLES 25 +#define PLATINUM_CHARGE_DAMAGE_TARGET 35 #define PLATINUM_CHARGE_CD 30 SECONDS #define PLATINUM_CHARGE_WINDUP 1.5 SECONDS #define PLATINUM_CHARGE_RANGE 5 @@ -70,15 +70,16 @@ charge_effect.icon = icon charge_effect.icon_state = icon_state // copy over the icon and direction charge_effect.dir = dir - charge_effect.alpha = 250 - (vfxfalloff * vfxindex) // todo: linear interpolation math so that this looks consistent at all distances + charge_effect.alpha = 250 - (vfxfalloff * vfxindex) animate(charge_effect, time = 25 - ((vfxfalloff * vfxindex) / 10), alpha = 0) for(var/mob/living/victim in targetturf.contents) if(victim != src) - victim.adjustBruteLoss(PLATINUM_CHARGE_DAMAGE_OBSTACLES) + victim.attack_generic(src, PLATINUM_CHARGE_DAMAGE_OBSTACLES, pick(charge_hit_verbs), FALSE, FALSE, FALSE, 1) else for(var/atom/victim in targetturf.contents) - victim.explosion_act(PLATINUM_CHARGE_DAMAGE_OBSTACLES * 4) //TEAR THROUGH ALL THAT IMPEDES YOU + if(victim.density) + victim.attack_generic(src, PLATINUM_CHARGE_DAMAGE_OBSTACLES, pick(charge_hit_verbs), FALSE, FALSE, FALSE, 1) break // if the turf is blocked (ie a wall/door/window), stop charging here visible_message(SPAN_DANGER("[src] [pick(charge_verbs)] at [target_mob]!")) diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/silver.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/silver.dm index 173f20b5a6f..83ee78da849 100644 --- a/code/modules/mob/living/carbon/superior_animal/golem/types/silver.dm +++ b/code/modules/mob/living/carbon/superior_animal/golem/types/silver.dm @@ -9,7 +9,7 @@ health = GOLEM_HEALTH_LOW // Movement related variables - move_to_delay = GOLEM_SPEED_HIGH + move_to_delay = GOLEM_SPEED_MED turns_per_move = 5 // Damage related variables @@ -44,7 +44,7 @@ /obj/item/projectile/plasma/stun/golem //special projectile that passes straight through golems name = "stun plasma bolt" taser_effect = 1 - damage_types = list(HALLOSS = 20, BURN = 10) + damage_types = list(HALLOSS = 15, BURN = 5) impact_type = /obj/effect/projectile/stun/impact /obj/item/projectile/plasma/stun/golem/Bump(atom/A as mob|obj|turf|area, forced = FALSE) diff --git a/code/modules/mob/living/carbon/superior_animal/golem/types/uranium.dm b/code/modules/mob/living/carbon/superior_animal/golem/types/uranium.dm index 3fbcff002ad..683f00ccea9 100644 --- a/code/modules/mob/living/carbon/superior_animal/golem/types/uranium.dm +++ b/code/modules/mob/living/carbon/superior_animal/golem/types/uranium.dm @@ -22,7 +22,7 @@ armor = list( melee = 0, bullet = GOLEM_ARMOR_MED, - energy = GOLEM_ARMOR_ULTRA, + energy = GOLEM_ARMOR_HIGH, bomb = 0, bio = 0, rad = 0