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/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/mining/drilling/deep_drill.dm b/code/modules/mining/drilling/deep_drill.dm index a9abec4e932..8730e69ef3d 100644 --- a/code/modules/mining/drilling/deep_drill.dm +++ b/code/modules/mining/drilling/deep_drill.dm @@ -1,10 +1,17 @@ -#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' 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 +26,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, @@ -42,52 +42,29 @@ MATERIAL_PLASTIC = /obj/item/ore/coal ) - //Upgrades - var/harvest_speed - 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() 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 . = ..() /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") + shutdown_drill(DRILL_SHUTDOWN_TEXT_OBSTACLE,DRILL_SHUTDOWN_LOG_OBSTACLE) return if(health == 0) - system_error("critical damage") - - if(need_update_field) - get_resource_field() + shutdown_drill(DRILL_SHUTDOWN_TEXT_BROKEN,DRILL_SHUTDOWN_LOG_OBSTACLE) //Drill through the flooring, if any. if(istype(get_turf(src), /turf/floor/asteroid)) @@ -96,70 +73,13 @@ T.gets_dug() else if(istype(get_turf(src), /turf/floor)) 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) + 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 - //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' @@ -193,10 +113,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 @@ -206,176 +126,79 @@ return // Repair the drill if it is damaged - var/damage = maxHealth - health - if(damage && (QUALITY_WELDING in I.tool_qualities)) - if(active) + if((health < maxHealth) && (QUALITY_WELDING in I.tool_qualities)) + 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].") - 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 + 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 || 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(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()) - 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 - else - GC.stop() - GC = null - visible_message(SPAN_NOTICE("\The [src] shudders to a grinding halt.")) - */ + if(!panel_open) + 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 - to_chat(user, SPAN_NOTICE("The drill is unpowered.")) + 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.")) + 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 //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) 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("Operating a piece of industrial machinery with wires exposed seems like a bad idea.")) update_icon() /obj/machinery/mining/deep_drill/update_icon() - if(need_player_check) + if(anchored && (check_surroundings() || !istype(get_turf(src), /turf/floor/asteroid))) icon_state = "mining_drill_error" - else if(active || cave_connected) + else if(cave_connected) icon_state = "mining_drill_active" else 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 - 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 - 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)) + if(cave_gen.is_closed()) //easy sanity check 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 + 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() /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) && !istype(F,/turf/space)) //if it's not a floor and not space it's probably an obstacle. + return TRUE return FALSE /obj/machinery/mining/deep_drill/attack_generic(mob/user, damage) @@ -392,21 +215,13 @@ /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 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 +234,14 @@ 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) +#undef DRILL_REPAIR_AMOUNT - var/mob/M = usr - if(ismob(M) && M.incapacitated()) - return +#undef DRILL_SHUTDOWN_TEXT_BROKEN +#undef DRILL_SHUTDOWN_TEXT_OBSTACLE - 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 DRILL_SHUTDOWN_LOG_BROKEN +#undef DRILL_SHUTDOWN_LOG_OBSTACLE +#undef DRILL_SHUTDOWN_LOG_MANUAL -#undef RADIUS -#undef DRILL_COOLDOWN 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..6be50feb177 100644 --- a/code/modules/mob/living/carbon/superior_animal/golem/golem.dm +++ b/code/modules/mob/living/carbon/superior_animal/golem/golem.dm @@ -77,32 +77,7 @@ 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 - controller = null - . = ..() // Spawn ores @@ -129,15 +104,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..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 @@ -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." @@ -41,9 +43,9 @@ 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(loc, obj/machinery/mining/deep_drill/drill, datum/golem_controller/parent) +/mob/living/carbon/superior_animal/golem/ansible/New() ..() set_light(3, 3, "#82C2D8") @@ -54,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 - if(target_mob && controller) - go_to_bluespace(target_mob.loc, 1, TRUE, target_mob, get_step(pick(controller.golems), pick(cardinal)), \ - 0, TRUE, null, null, 'sound/effects/teleport.ogg', 'sound/effects/teleport.ogg') + // 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)) /mob/living/carbon/superior_animal/golem/ansible/proc/focus_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 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/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..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 @@ -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." @@ -32,7 +34,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") @@ -42,8 +44,8 @@ // 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/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 . = ..()