From 8a25e656b4fdf16877d633e987266ce74f4ff8bb Mon Sep 17 00:00:00 2001 From: ZephyrTFA Date: Wed, 8 Nov 2023 03:48:27 -0500 Subject: [PATCH] workage --- .../shuttle/shield/ship_shield_generator.dm | 57 ++++++- code/modules/overmap/objects/event_datum.dm | 150 +++++++++++------- .../overmap/ships/controlled_ship_datum.dm | 9 ++ 3 files changed, 151 insertions(+), 65 deletions(-) diff --git a/code/game/machinery/shuttle/shield/ship_shield_generator.dm b/code/game/machinery/shuttle/shield/ship_shield_generator.dm index 46d65d1522cf..fe151827ffc5 100644 --- a/code/game/machinery/shuttle/shield/ship_shield_generator.dm +++ b/code/game/machinery/shuttle/shield/ship_shield_generator.dm @@ -16,12 +16,11 @@ max_integrity = 1000 integrity_failure = 250 - var/repair_integrity = 125 + /// Amount we repair per weld cycle. + var/repair_integrity = 50 /// The ship we are linked to. var/datum/overmap/ship/controlled/linked_ship - /// The apc we are drawing power from. - var/obj/machinery/power/apc/linked_apc /// The rate of charge per tick. var/charge_rate @@ -31,6 +30,8 @@ var/charge /// The ratio of power to charge var/charge_ratio = 2 + /// The ratio of damage to charge + var/damage_ratio = 4 /// The rate of spooling per tick. var/spool_rate @@ -38,7 +39,7 @@ var/spool_percent /// The penalty for spooling while inoperable. var/spool_inoperable_penalty = 0.8 - + /// Have we announced that we are inoperable? var/inoperable_announced = FALSE /obj/machinery/power/ship_shield_generator/update_icon_state() @@ -83,6 +84,7 @@ port_ship.shield_generator = src linked_ship = port_ship linked_ship.broadcast("Link established to ship magnetosphere array.") + START_PROCESSING(SSmachines, src) /obj/machinery/power/ship_shield_generator/process() if(isnull(linked_ship)) @@ -130,11 +132,29 @@ /obj/machinery/power/ship_shield_generator/proc/charge_depleted() set_machine_stat(machine_stat|BROKEN) linked_ship.broadcast("Critical failure in magnetocore, unable to error correct.") + charge = 0 spool_percent = 0 playsound(src, 'sound/mecha/mech_shield_drop.ogg', 50) +/obj/machinery/power/ship_shield_generator/multitool_act(mob/living/user, obj/item/I) + if(obj_integrity < max_integrity) + balloon_alert(user, "damaged!") + return TRUE + + if(!(machine_stat & BROKEN)) + balloon_alert(user, "not broken!") + return TRUE + + balloon_alert(user, "resetting...") + if(!do_after(user, 1 SECONDS, target = src)) + balloon_alert(user, "interrupted!") + return TRUE + + set_machine_stat(machine_stat & ~BROKEN) + balloon_alert(user, "reset.") + /obj/machinery/power/ship_shield_generator/welder_act(mob/living/user, obj/item/weldingtool/welder) - if(obj_integrity >= max_integrity) + if(obj_integrity >= max_integrity && !(machine_stat & BROKEN)) return if(!welder.isOn()) @@ -155,11 +175,34 @@ obj_integrity = min(obj_integrity + repair_integrity, max_integrity) if(obj_integrity >= max_integrity) balloon_alert(user, "repaired.") - set_machine_stat(machine_stat & ~BROKEN) return TRUE if(repair_time > 0.5 SECONDS) - repair_time -= 0.5 SECONDS + repair_time = max(repair_time - 0.2 SECONDS, 0.5 SECONDS) balloon_alert(user, "stopped!") return TRUE + +/// Handle blocking damage +/obj/machinery/power/ship_shield_generator/proc/on_shield_block_damage(damage) + set waitfor = FALSE + return + +/// Handle taking enough damage to break the shield +/obj/machinery/power/ship_shield_generator/proc/on_shield_break() + set waitfor = FALSE + return + +/// Handles blocking damage and draining charge. +/// An attack which is not blocked will strike at full power. +/obj/machinery/power/ship_shield_generator/proc/block_damage(damage) + if(!charge) + return FALSE + + var/needed_charge = damage * damage_ratio + if(needed_charge < charge) + charge -= needed_charge + on_shield_block_damage(damage) + return TRUE + charge_depleted() + on_shield_break() diff --git a/code/modules/overmap/objects/event_datum.dm b/code/modules/overmap/objects/event_datum.dm index bfed840a1acd..489f544a1a09 100644 --- a/code/modules/overmap/objects/event_datum.dm +++ b/code/modules/overmap/objects/event_datum.dm @@ -5,8 +5,14 @@ */ /datum/overmap/event name = "generic overmap event" - ///If prob(this), call affect_ship when processed - var/chance_to_affect = 0 + + /// The probability that this event will affect a ship + var/effect_chance = 100 + /// If this event ignores shields on a ship + var/ignore_shield = FALSE + /// The amount of damage the event does to the shield of the ship, if present + var/shield_damage = 0 + ///Chance to spread to nearby tiles if spawned var/spread_chance = 0 ///How many additional tiles to spawn at once in the selected orbit. Used with OVERMAP_GENERATOR_SOLAR. @@ -22,35 +28,52 @@ . = ..() SSovermap.events -= src +/// Determines if this event can affect the given ship. +/datum/overmap/event/proc/can_affect(datum/overmap/ship/controlled/ship) + if(!prob(effect_chance)) + return FALSE + return default_can_affect_shield(ship) + +/// Default proc to check shield effects. Done here so it can be used in overriden can_affect procs. +/datum/overmap/event/proc/default_can_affect_shield(datum/overmap/ship/controlled/ship) + if(ignore_shield || !ship.shield_active()) + return TRUE + if(!shield_damage) + return FALSE + return !ship.shield_block(shield_damage) + /** * The main proc for calling other procs. Called by SSovermap. */ /datum/overmap/event/proc/apply_effect() - for(var/datum/overmap/ship/controlled/Ship in get_nearby_overmap_objects()) - if(prob(chance_to_affect)) - affect_ship(Ship) + for(var/datum/overmap/ship/controlled/ship in get_nearby_overmap_objects()) + if(!can_affect(ship)) + continue + do_effect(ship) /** * The proc called on all ships that are currently being affected. */ -/datum/overmap/event/proc/affect_ship(datum/overmap/ship/controlled/Ship) +/datum/overmap/event/proc/do_effect(datum/overmap/ship/controlled/ship) return - ///METEOR STORMS - explodes your ship if you go too fast /datum/overmap/event/meteor name = "asteroid field (moderate)" desc = "An area of space rich with asteroids, going fast through here could prove dangerous" token_icon_state = "meteor1" - chance_to_affect = 15 + effect_chance = 15 + shield_damage = 20 spread_chance = 50 chain_rate = 4 + /// The speed at which a ship can travel through the asteroid field without being affected var/safe_speed = 3 + /// The types of meteors that can be spawned, and their relative probabilities var/list/meteor_types = list( - /obj/effect/meteor/dust=3, - /obj/effect/meteor/medium=8, - /obj/effect/meteor/big=1, - /obj/effect/meteor/irradiated=3 + /obj/effect/meteor/big = 1, + /obj/effect/meteor/dust = 3, + /obj/effect/meteor/irradiated = 3, + /obj/effect/meteor/medium = 8, ) /datum/overmap/event/meteor/Initialize(position, ...) @@ -60,37 +83,45 @@ token.light_color = "#a08444" token.update_appearance() -/datum/overmap/event/meteor/apply_effect() - for(var/datum/overmap/ship/controlled/Ship in get_nearby_overmap_objects()) - if(Ship.get_speed() > safe_speed) - var/how_fast = (Ship.get_speed() - safe_speed) - if(prob(chance_to_affect + how_fast)) - affect_ship(Ship) +/datum/overmap/event/meteor/proc/meteor_types() + return + +/datum/overmap/event/meteor/can_affect(datum/overmap/ship/controlled/ship) + var/ship_speed = ship.get_speed() + if(ship_speed < safe_speed) + return FALSE + + var/affect_prob = effect_chance + (ship_speed - safe_speed) + if(!prob(affect_prob)) + return FALSE + return default_can_affect_shield(ship) -/datum/overmap/event/meteor/affect_ship(datum/overmap/ship/controlled/Ship) - spawn_meteor(meteor_types, Ship.shuttle_port.get_virtual_level(), 0) +/datum/overmap/event/meteor/do_effect(datum/overmap/ship/controlled/ship) + spawn_meteor(meteor_types, ship.shuttle_port.get_virtual_level(), 0) /datum/overmap/event/meteor/minor name = "asteroid field (minor)" chain_rate = 3 + shield_damage = 10 meteor_types = list( - /obj/effect/meteor/dust=12, - /obj/effect/meteor/medium=4, - /obj/effect/meteor/irradiated=2 + /obj/effect/meteor/dust = 12, + /obj/effect/meteor/medium = 4, + /obj/effect/meteor/irradiated = 2 ) /datum/overmap/event/meteor/major name = "asteroid field (major)" spread_chance = 25 chain_rate = 6 + shield_damage = 30 meteor_types = list( - /obj/effect/meteor/medium=50, - /obj/effect/meteor/big=25, - /obj/effect/meteor/flaming=10, - /obj/effect/meteor/irradiated=10, + /obj/effect/meteor/medium = 50, + /obj/effect/meteor/big = 25, + /obj/effect/meteor/flaming = 10, + /obj/effect/meteor/irradiated = 10, /obj/effect/meteor/tunguska = 1 ) -/* commented out until ion storms aren't literal torture + ///ION STORM - explodes your IPCs /datum/overmap/event/emp name = "ion storm (moderate)" @@ -98,7 +129,7 @@ token_icon_state = "ion1" spread_chance = 20 chain_rate = 2 - chance_to_affect = 20 + shield_damage = 2 var/strength = 4 /datum/overmap/event/emp/Initialize(position, ...) @@ -108,7 +139,7 @@ token.light_color = "#7cb4d4" token.update_appearance() -/datum/overmap/event/emp/affect_ship(datum/overmap/ship/controlled/S) +/datum/overmap/event/emp/do_effect(datum/overmap/ship/controlled/S) var/area/source_area = pick(S.shuttle_port.shuttle_areas) source_area.set_fire_alarm_effect() var/source_object = pick(source_area.contents) @@ -121,20 +152,22 @@ name = "ion storm (minor)" chain_rate = 1 strength = 1 - chance_to_affect = 15 + shield_damage = 0 + effect_chance = 15 /datum/overmap/event/emp/major name = "ion storm (major)" - chance_to_affect = 25 + effect_chance = 25 chain_rate = 4 + shield_damage = 5 strength = 6 -*/ -///ELECTRICAL STORM - explodes your computer and IPCs + /datum/overmap/event/electric name = "electrical storm (moderate)" desc = "A spatial anomaly, an unfortunately common sight on the frontier. Disturbing it tends to lead to intense electrical discharges" token_icon_state = "electrical1" - chance_to_affect = 15 + effect_chance = 15 + shield_damage = 10 spread_chance = 30 chain_rate = 3 var/zap_flag = ZAP_STORM_FLAGS @@ -148,7 +181,7 @@ token.light_color = "#e8e85c" token.update_appearance() -/datum/overmap/event/electric/affect_ship(datum/overmap/ship/controlled/S) +/datum/overmap/event/electric/do_effect(datum/overmap/ship/controlled/S) var/datum/virtual_level/ship_vlevel = S.shuttle_port.get_virtual_level() var/turf/source = ship_vlevel.get_side_turf(pick(GLOB.cardinals)) tesla_zap(source, 10, TESLA_DEFAULT_POWER, zap_flag) @@ -160,6 +193,7 @@ name = "electrical storm (minor)" spread_chance = 40 chain_rate = 2 + shield_damage = 5 max_damage = 10 min_damage = 3 @@ -167,6 +201,7 @@ name = "electrical storm (major)" spread_chance = 15 chain_rate = 6 + shield_damage = 15 max_damage = 20 min_damage = 10 zap_flag = ZAP_TESLA_FLAGS @@ -174,6 +209,7 @@ /datum/overmap/event/nebula name = "nebula" desc = "There's coffee in here" + ignore_shield = TRUE token_icon_state = "nebula" chain_rate = 8 spread_chance = 75 @@ -188,10 +224,11 @@ /datum/overmap/event/wormhole name = "wormhole" desc = "A hole through space. If you go through here, you might end up anywhere." + ignore_shield = TRUE token_icon_state = "wormhole" spread_chance = 0 chain_rate = 0 - chance_to_affect = 100 + effect_chance = 100 ///The currently linked wormhole var/datum/overmap/event/wormhole/other_wormhole ///Amount of times a ship can pass through before it collapses @@ -208,7 +245,7 @@ token.light_color = adjust_colors() token.update_appearance() -/datum/overmap/event/wormhole/affect_ship(datum/overmap/ship/controlled/S) +/datum/overmap/event/wormhole/do_effect(datum/overmap/ship/controlled/S) if(!other_wormhole) qdel(src) if(--stability <= 0) @@ -249,7 +286,8 @@ name = "carp migration (moderate)" desc = "A migratory school of space carp. They travel at high speeds, and flying through them may cause them to impact your ship" token_icon_state = "carp1" - chance_to_affect = 15 + ignore_shield = TRUE + effect_chance = 15 spread_chance = 50 chain_rate = 4 safe_speed = 2 @@ -269,37 +307,35 @@ /datum/overmap/event/meteor/carp/minor name = "carp migration (minor)" token_icon_state = "carp1" - chance_to_affect = 5 + effect_chance = 5 spread_chance = 25 chain_rate = 4 meteor_types = list( - /obj/effect/meteor/carp=8 + /obj/effect/meteor/carp = 8 ) - /datum/overmap/event/meteor/carp/major name = "carp migration (major)" token_icon_state = "carp1" - chance_to_affect = 25 + effect_chance = 25 spread_chance = 25 chain_rate = 4 - meteor_types = list( - /obj/effect/meteor/carp=7, - /obj/effect/meteor/carp/big=1, + meteor_types = list( // lol why are these meteors + /obj/effect/meteor/carp = 7, + /obj/effect/meteor/carp/big = 1, ) -// dust clouds throw dust if you go Way Fast - /datum/overmap/event/meteor/dust name = "dust cloud" desc = "A cloud of spaceborne dust. Relatively harmless, unless you're travelling at relative speeds" token_icon_state = "carp1" - chance_to_affect = 30 + effect_chance = 30 spread_chance = 50 + shield_damage = 2 chain_rate = 4 safe_speed = 7 meteor_types = list( - /obj/effect/meteor/dust=3, + /obj/effect/meteor/dust = 3, ) /datum/overmap/event/meteor/dust/Initialize(position, ...) @@ -313,7 +349,7 @@ name = "anomaly field" desc = "A highly anomalous area of space, disturbing it leads to the manifestation of odd spatial phenomena" token_icon_state = "anomaly1" - chance_to_affect = 10 + effect_chance = 10 spread_chance = 35 chain_rate = 6 @@ -324,13 +360,13 @@ token.light_color = "#c46a24" token.update_icon() -/datum/overmap/event/anomaly/affect_ship(datum/overmap/ship/controlled/S) - var/area/source_area = pick(S.shuttle_port.shuttle_areas) +/datum/overmap/event/anomaly/do_effect(datum/overmap/ship/controlled/ship) + var/area/source_area = pick(ship.shuttle_port.shuttle_areas) var/source_object = pick(source_area.contents) new /obj/effect/spawner/lootdrop/anomaly/storm(get_turf(source_object)) - for(var/mob/M as anything in GLOB.player_list) - if(S.shuttle_port.is_in_shuttle_bounds(M)) - M.playsound_local(S.shuttle_port, 'sound/effects/bamf.ogg', 100) + for(var/mob/crewmate as anything in GLOB.player_list) + if(ship.shuttle_port.is_in_shuttle_bounds(crewmate)) + crewmate.playsound_local(ship.shuttle_port, 'sound/effects/bamf.ogg', 100) GLOBAL_LIST_INIT(overmap_event_pick_list, list( /datum/overmap/event/wormhole = 10, @@ -338,11 +374,9 @@ GLOBAL_LIST_INIT(overmap_event_pick_list, list( /datum/overmap/event/electric/minor = 45, /datum/overmap/event/electric = 40, /datum/overmap/event/electric/major = 35, - /* commented out until ion storms aren't literal torture /datum/overmap/event/emp/minor = 45, /datum/overmap/event/emp = 40, /datum/overmap/event/emp/major = 45, - */ /datum/overmap/event/meteor/minor = 45, /datum/overmap/event/meteor = 40, /datum/overmap/event/meteor/major = 35, diff --git a/code/modules/overmap/ships/controlled_ship_datum.dm b/code/modules/overmap/ships/controlled_ship_datum.dm index add7da6a78ca..dbfa44291292 100644 --- a/code/modules/overmap/ships/controlled_ship_datum.dm +++ b/code/modules/overmap/ships/controlled_ship_datum.dm @@ -248,6 +248,15 @@ return ..() +/// Checks if this ship has an active shield that is both enabled and charged. +/datum/overmap/ship/controlled/proc/shield_active() + return !!shield_generator?.charge + +/// Attempts to deal damage to the shield of this ship. +/// Returns TRUE if the attack was blocked by the shield, FALSE otherwise. +/datum/overmap/ship/controlled/proc/shield_block(damage) + return shield_generator?.block_damage(damage) + /** * Connects a new shuttle port to the ship datum. Should be used very shortly after the ship is created, if at all. * Used to connect the shuttle port to a ship datum that was created without a template.