diff --git a/aurorastation.dme b/aurorastation.dme index 5201d8961ba..b8e05b63ca0 100644 --- a/aurorastation.dme +++ b/aurorastation.dme @@ -3613,7 +3613,6 @@ #include "code\modules\research\xenoarchaeology\artifact\effects\unknown_effect_cellcharge.dm" #include "code\modules\research\xenoarchaeology\artifact\effects\unknown_effect_celldrain.dm" #include "code\modules\research\xenoarchaeology\artifact\effects\unknown_effect_emp.dm" -#include "code\modules\research\xenoarchaeology\artifact\effects\unknown_effect_forcefield.dm" #include "code\modules\research\xenoarchaeology\artifact\effects\unknown_effect_mental.dm" #include "code\modules\research\xenoarchaeology\artifact\effects\unknown_effect_physical.dm" #include "code\modules\research\xenoarchaeology\artifact\effects\unknown_effect_teleport.dm" @@ -3644,6 +3643,7 @@ #include "code\modules\shareddream\area.dm" #include "code\modules\shareddream\brainghost.dm" #include "code\modules\shareddream\dream_entry.dm" +#include "code\modules\shieldgen\_energy_field.dm" #include "code\modules\shieldgen\emergency_shield.dm" #include "code\modules\shieldgen\energy_field.dm" #include "code\modules\shieldgen\shield_capacitor.dm" diff --git a/code/__DEFINES/dcs/signals/signals_object/signals_object.dm b/code/__DEFINES/dcs/signals/signals_object/signals_object.dm index 4386c17a90a..f3ec1a99257 100644 --- a/code/__DEFINES/dcs/signals/signals_object/signals_object.dm +++ b/code/__DEFINES/dcs/signals/signals_object/signals_object.dm @@ -70,6 +70,5 @@ ///sent to the projectile when spawning the item (shrapnel) that may be embedded: (new_item) #define COMSIG_PROJECTILE_ON_SPAWN_EMBEDDED "projectile_on_spawn_embedded" -/// from /obj/projectile/energy/fisher/on_hit() or /obj/item/gun/energy/recharge/fisher when striking a target -#define COMSIG_HIT_BY_SABOTEUR "hit_by_saboteur" - #define COMSIG_SABOTEUR_SUCCESS (1<<0) +/// From code\modules\shieldgen\energy_field.dm, the energy field datum uses this to tell shields when to turn dense or not +#define COMSIG_SHIELDS_UPDATE_STRENGTH_STATUS "update_strength_status" diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index 9963299fefa..b5cc4077644 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -1978,7 +1978,7 @@ About the new airlock wires panel: healthcheck() /obj/effect/energy_field/airlock_crush(var/crush_damage) - Stress(crush_damage) + damage_field(crush_damage) /obj/structure/closet/airlock_crush(var/crush_damage) ..() diff --git a/code/modules/events/comet_expulsion.dm b/code/modules/events/comet_expulsion.dm index cdf21be0cdd..5fde976c042 100644 --- a/code/modules/events/comet_expulsion.dm +++ b/code/modules/events/comet_expulsion.dm @@ -71,7 +71,7 @@ //If there's shields and it's strong enough, the power of the explosion is reduced, but it won't stop it if(istype(A, /obj/effect/energy_field)) var/obj/effect/energy_field/impacted_energy_field = A - if(impacted_energy_field.strength > SHIELD_MINIMUM_STRENGTH_TO_REDUCE_EXPLOSION_POWER) + if(impacted_energy_field.damage < 1) hitpwr *= 0.5 qdel(impacted_energy_field) diff --git a/code/modules/mob/living/simple_animal/hostile/hostile.dm b/code/modules/mob/living/simple_animal/hostile/hostile.dm index c3ab12957eb..48dbbfbd9ad 100644 --- a/code/modules/mob/living/simple_animal/hostile/hostile.dm +++ b/code/modules/mob/living/simple_animal/hostile/hostile.dm @@ -439,7 +439,7 @@ ABSTRACT_TYPE(/mob/living/simple_animal/hostile) found_obj = locate(/obj/effect/energy_field) in target_turf if(found_obj && !found_obj.invisibility && found_obj.density) var/obj/effect/energy_field/e = found_obj - e.Stress(rand(0.5, 1.5)) + e.damage_field(rand(0.5, 1.5)) visible_message(SPAN_DANGER("[capitalize_first_letters(src.name)] [attacktext] \the [e]!")) src.do_attack_animation(e) set_last_found_target(e) diff --git a/code/modules/mob/living/simple_animal/hostile/space_fauna.dm b/code/modules/mob/living/simple_animal/hostile/space_fauna.dm index 902ab7f4150..a8438c37aee 100644 --- a/code/modules/mob/living/simple_animal/hostile/space_fauna.dm +++ b/code/modules/mob/living/simple_animal/hostile/space_fauna.dm @@ -91,7 +91,7 @@ return if(istype(last_found_target, /obj/effect/energy_field)) var/obj/effect/energy_field/e = last_found_target - e.Stress(rand(1,2)) + e.damage_field(rand(1,2)) visible_message(SPAN_DANGER("\the [src] bites \the [e]!")) src.do_attack_animation(e) return e diff --git a/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_forcefield.dm b/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_forcefield.dm deleted file mode 100644 index 12659c781ef..00000000000 --- a/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_forcefield.dm +++ /dev/null @@ -1,83 +0,0 @@ - -/datum/artifact_effect/forcefield - effecttype = "forcefield" - var/list/created_field = list() - effect_type = 4 - -/datum/artifact_effect/forcefield/New() - ..() - trigger = TRIGGER_TOUCH - -/datum/artifact_effect/forcefield/ToggleActivate() - ..() - if(created_field.len) - for(var/obj/effect/energy_field/F in created_field) - created_field.Remove(F) - qdel(F) - else if(holder) - var/turf/T = get_turf(holder) - while(created_field.len < 16) - var/obj/effect/energy_field/E = new (locate(T.x,T.y,T.z)) - created_field.Add(E) - E.strength = 1 - E.density = 1 - E.anchored = 1 - E.set_invisibility(0) - spawn(10) - UpdateMove() - return 1 - -/datum/artifact_effect/forcefield/process() - ..() - for(var/obj/effect/energy_field/E in created_field) - if(E.strength < 1) - E.Strengthen(0.15) - else if(E.strength < 5) - E.Strengthen(0.25) - -/datum/artifact_effect/forcefield/UpdateMove() - if(created_field.len && holder) - var/turf/T = get_turf(holder) - - if(!T) - return - while(created_field.len < 16) - //for now, just instantly respawn the fields when they get destroyed - var/obj/effect/energy_field/E = new (locate(T.x,T.y,T)) - created_field.Add(E) - E.anchored = 1 - E.density = 1 - E.set_invisibility(0) - - var/obj/effect/energy_field/E = created_field[1] - E.forceMove(locate(T.x + 2,T.y + 2,T.z)) - E = created_field[2] - E.forceMove(locate(T.x + 2,T.y + 1,T.z)) - E = created_field[3] - E.forceMove(locate(T.x + 2,T.y,T.z)) - E = created_field[4] - E.forceMove(locate(T.x + 2,T.y - 1,T.z)) - E = created_field[5] - E.forceMove(locate(T.x + 2,T.y - 2,T.z)) - E = created_field[6] - E.forceMove(locate(T.x + 1,T.y + 2,T.z)) - E = created_field[7] - E.forceMove(locate(T.x + 1,T.y - 2,T.z)) - E = created_field[8] - E.forceMove(locate(T.x,T.y + 2,T.z)) - E = created_field[9] - E.forceMove(locate(T.x,T.y - 2,T.z)) - E = created_field[10] - E.forceMove(locate(T.x - 1,T.y + 2,T.z)) - E = created_field[11] - E.forceMove(locate(T.x - 1,T.y - 2,T.z)) - E = created_field[12] - E.forceMove(locate(T.x - 2,T.y + 2,T.z)) - E = created_field[13] - E.forceMove(locate(T.x - 2,T.y + 1,T.z)) - E = created_field[14] - E.forceMove(locate(T.x - 2,T.y,T.z)) - E = created_field[15] - E.forceMove(locate(T.x - 2,T.y - 1,T.z)) - E = created_field[16] - E.forceMove(locate(T.x - 2,T.y - 2,T.z)) diff --git a/code/modules/shieldgen/_energy_field.dm b/code/modules/shieldgen/_energy_field.dm new file mode 100644 index 00000000000..962123c969c --- /dev/null +++ b/code/modules/shieldgen/_energy_field.dm @@ -0,0 +1,101 @@ +// This is an abstracted energy field to cut down on processing thousands of shields per process tick. +/datum/energy_field + /// A gigantic ass fucking list of energy fields. + var/list/field = list() + /// The actual strength of the field. + var/field_strength = 0 + /// Current strengthening rate of a single field. + var/strengthen_rate = 0.2 + /// Maximum rate by which an energy field can be strengthened. + var/max_strengthen_rate = 0.5 + /// The percentage of the shield strength that needs to be replaced each second + var/dissipation_rate = 0.030 + /// An energy field will dissipate by at least this rate in renwicks per field tile (otherwise field would never dissipate completely as dissipation is a percentage) + var/min_dissipation = 0.01 + /// Our target field strength. + var/target_field_strength = 10 + /// The maximum field strength we can go to. + var/max_field_strength = 10 + /// The time passed since the last "fail", AKA losing charge faster than you can replenish it. + var/time_since_fail = 100 + /// How many renwicks per watt. + var/energy_conversion_rate = 0.0002 + /// If the field is strong, then the energy field objects will turn dense. + var/strong_field = FALSE + +/datum/energy_field/Destroy(force) + clear_field() + return ..() + +/** + * This proc, called when a shield generator processes, makes the whole thing tick by updating strength and etc. + * @assumed_charge: the charge that is given to this energy field. You have to get the required energy first, if you want a balanced field. + */ +/datum/energy_field/proc/handle_strength(assumed_charge = 0) + if(length(field)) + time_since_fail++ + //the amount of renwicks that the generator can add this tick, over the entire field + var/total_renwick_increase = assumed_charge * energy_conversion_rate + + var/renwick_increase_per_field = total_renwick_increase / length(field) //per field tile + var/renwick_upkeep_per_field = max(field_strength * dissipation_rate, min_dissipation) + var/amount_to_strengthen = renwick_increase_per_field - renwick_upkeep_per_field + field_strength = min(field_strength + amount_to_strengthen, max_field_strength) + + if(field_strength < 1) + if(strong_field) + strong_field = FALSE + SEND_SIGNAL(src, COMSIG_SHIELDS_UPDATE_STRENGTH_STATUS) + time_since_fail = 0 + else + if(!strong_field) + strong_field = TRUE + SEND_SIGNAL(src, COMSIG_SHIELDS_UPDATE_STRENGTH_STATUS) + else + field_strength = 0 + +/** + * Returns the required energy upkeep for the field. + */ +/datum/energy_field/proc/get_required_energy() + var/required_energy = 0 + if(length(field)) + var/renwick_upkeep_per_field = max(field_strength * dissipation_rate, min_dissipation) + var/target_renwick_increase = min(target_field_strength - field_strength, strengthen_rate) + renwick_upkeep_per_field //per field tile + required_energy = length(field) * target_renwick_increase / energy_conversion_rate + return required_energy + +/** + * Clears the field of active field objects. + */ +/datum/energy_field/proc/clear_field() + field_strength = 0 + strong_field = FALSE + for(var/obj/effect/energy_field/D as anything in field) + field.Remove(D) + qdel(D) + +/** + * Sets the shielded turfs of the energy field. + */ +/datum/energy_field/proc/set_shielded_turfs(list/shielded_turfs) + if(length(shielded_turfs)) + for(var/turf/T in shielded_turfs) + var/obj/effect/energy_field/F = new(T, src) + field += F + +/** + * Adds a bunch of UI data for TGUIs with relevant field data. + */ +/datum/energy_field/proc/add_field_ui_data(list/data) + if(!istype(data)) + return + + data["average_field"] = round(field_strength, 0.01) + data["progress_field"] = (target_field_strength ? round(100 * field_strength / target_field_strength, 0.1) : "NA") + data["power_take"] = round(length(field) * max(field_strength * dissipation_rate, min_dissipation) / energy_conversion_rate) + data["shield_power"] = round(length(field) * min(strengthen_rate, target_field_strength - field_strength) / energy_conversion_rate) + data["strengthen_rate"] = (strengthen_rate * 10) + data["max_strengthen_rate"] = (max_strengthen_rate * 10) + data["target_field_strength"] = target_field_strength + return data diff --git a/code/modules/shieldgen/energy_field.dm b/code/modules/shieldgen/energy_field.dm index 7a2bc95baa8..8780a463905 100644 --- a/code/modules/shieldgen/energy_field.dm +++ b/code/modules/shieldgen/energy_field.dm @@ -11,20 +11,32 @@ anchored = 1 layer = ABOVE_HUMAN_LAYER density = 0 - var/strength = 0 + /// A ref holding the /datum/energy_field that this field object belongs to. + var/datum/energy_field/energy_field + /// The damage suffered by the field. + var/damage = 0 var/ticks_recovering = 10 var/diffused_for = 0 var/diffused = FALSE - - var/is_strong = FALSE // if strength goes is 1 or above, this is set to TRUE, this is to prevent flickering and animate being called constantly + /// If strength goes is 1 or above, this is set to TRUE, this is to prevent flickering and animate being called constantly + var/is_strong = FALSE atmos_canpass = CANPASS_ALWAYS -/obj/effect/energy_field/Initialize() +/obj/effect/energy_field/Initialize(mapload, datum/energy_field/mother_field) . = ..() + if(istype(mother_field)) + energy_field = mother_field + else + log_debug("Energy field generated without mother field, deleting.") + qdel_self() + RegisterSignal(mother_field, COMSIG_SHIELDS_UPDATE_STRENGTH_STATUS, PROC_REF(update_strength)) update_nearby_tiles() /obj/effect/energy_field/Destroy() + if(istype(energy_field)) + energy_field.field -= src + energy_field = null update_nearby_tiles() return ..() @@ -39,7 +51,7 @@ else user.visible_message(SPAN_WARNING("[user] attacks \the [src] with \the [attacking_item]."), SPAN_WARNING("You attack \the [src] with \the [attacking_item].")) - Stress(attacking_item.force / 10) + damage_field(attacking_item.force / 10) /obj/effect/energy_field/attack_hand(mob/living/carbon/human/H) if(istype(H)) @@ -47,35 +59,51 @@ H.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) H.do_attack_animation(src, FIST_ATTACK_ANIMATION) H.visible_message(SPAN_WARNING("[H] shreds \the [src]!"), SPAN_WARNING("You shred \the [src]!")) - Stress(1) + damage_field(1) return to_chat(H, SPAN_WARNING("You touch \the [src], and it repulses your hand.")) /obj/effect/energy_field/ex_act(var/severity) - Stress(0.5 + severity) + damage_field(0.5 + severity) /obj/effect/energy_field/bullet_act(obj/projectile/hitting_projectile, def_zone, piercing_hit) . = ..() if(. != BULLET_ACT_HIT) return . - Stress(hitting_projectile.get_structure_damage() / 10) + damage_field(hitting_projectile.get_structure_damage() / 10) -/obj/effect/energy_field/proc/Stress(var/severity) - strength -= severity +/obj/effect/energy_field/proc/damage_field(var/severity) + if(!severity) + return + damage += severity + + if(!(datum_flags & DF_ISPROCESSING)) + // Start processing ONLY when we're damaged. Through processing, we're going to slowly climb back up to field strength. + START_PROCESSING(SSprocessing, src) + + var/shield_health = get_health() //if we take too much damage, drop out - the generator will bring us back up if we have enough power ticks_recovering = min(ticks_recovering + 2, 10) - if(strength < 1 && is_strong) + if(shield_health < 1 && is_strong) density_check(FALSE) is_strong = FALSE ticks_recovering = 10 - strength = 0 - else if(strength >= 1 && !is_strong) + else if(shield_health >= 1 && !is_strong) density_check(TRUE) is_strong = TRUE -// +/obj/effect/energy_field/process(seconds_per_tick) + if(!damage) // No need to process anymore. + update_strength() + return PROCESS_KILL + + if(ticks_recovering) + ticks_recovering-- + else + damage = max(damage - energy_field.strengthen_rate, 0) + /obj/effect/energy_field/proc/density_check(var/turn_on) if(turn_on && !diffused) alpha = 0 @@ -99,17 +127,15 @@ diffused = FALSE density_check(TRUE) -/obj/effect/energy_field/proc/Strengthen(var/severity) - strength += severity - if (strength < 0) - strength = 0 - +/obj/effect/energy_field/proc/update_strength() + SIGNAL_HANDLER //if we take too much damage, drop out - the generator will bring us back up if we have enough power var/old_density = density - if(strength >= 1 && !is_strong) + var/shield_health = get_health() + if(shield_health >= 1 && !is_strong) is_strong = TRUE density_check(TRUE) - else if(strength < 1 && is_strong) + else if(shield_health < 1 && is_strong) is_strong = FALSE density_check(FALSE) @@ -118,6 +144,12 @@ diffuse_check() +/** + * Easy helper proc to return the shield's current health. + */ +/obj/effect/energy_field/proc/get_health() + return max(energy_field.field_strength - damage, 0) + /obj/effect/energy_field/CanPass(atom/movable/mover, turf/target, height=1.5, air_group = 0) if(mover?.movement_type & PHASING) return TRUE diff --git a/code/modules/shieldgen/shield_gen.dm b/code/modules/shieldgen/shield_gen.dm index d98bbb411f4..ea91cca1c2f 100644 --- a/code/modules/shieldgen/shield_gen.dm +++ b/code/modules/shieldgen/shield_gen.dm @@ -10,41 +10,36 @@ desc = "Machine that generates an impenetrable field of energy when activated." icon = 'icons/obj/machinery/shielding.dmi' icon_state = "generator0" - var/active = FALSE - var/field_radius = 3 - var/max_field_radius = 100 - var/list/field density = TRUE - var/locked = FALSE - var/average_field_strength = 0 - var/strengthen_rate = 0.2 - var/max_strengthen_rate = 0.5 //the maximum rate that the generator can increase the average field strength - var/dissipation_rate = 0.030 //the percentage of the shield strength that needs to be replaced each second - var/min_dissipation = 0.01 //will dissipate by at least this rate in renwicks per field tile (otherwise field would never dissipate completely as dissipation is a percentage) - var/powered = FALSE - var/check_powered = TRUE - var/obj/machinery/shield_capacitor/owned_capacitor - var/target_field_strength = 10 - var/max_field_strength = 10 - var/time_since_fail = 100 - var/energy_conversion_rate = 0.0002 //how many renwicks per watt? use_power = POWER_USE_OFF //doesn't use APC power - var/multiz = TRUE - var/multi_unlocked = TRUE req_one_access = list(ACCESS_CAPTAIN, ACCESS_SECURITY, ACCESS_ENGINE) + /// Our owned energy field. + var/datum/energy_field/energy_field + /// If the machine is powered or not. + var/powered = FALSE + /// Whether the shield generator is active or not. + var/active = FALSE + /// ID lock. + var/locked = FALSE + /// Radius of the field. + var/field_radius = 3 + /// Maximum field radius. + var/max_field_radius = 100 + /// The shield capacitor attached to this shield generator. + var/obj/machinery/shield_capacitor/owned_capacitor + /// If this shield generator supports multi-z. + var/multiz = TRUE /obj/machinery/shield_gen/Initialize() for(var/obj/machinery/shield_capacitor/possible_cap in range(1, src)) if(get_dir(possible_cap, src) == possible_cap.dir) owned_capacitor = possible_cap break - field = list() + energy_field = new(src, get_shielded_turfs()) . = ..() /obj/machinery/shield_gen/Destroy() - for(var/obj/effect/energy_field/D as anything in field) - field.Remove(D) - D.loc = null + owned_capacitor = null return ..() /obj/machinery/shield_gen/emag_act(var/remaining_charges, var/mob/user) @@ -77,7 +72,6 @@ if(get_dir(cap, src) == cap.dir && cap.anchored) owned_capacitor = cap owned_capacitor.owned_gen = src - updateDialog() break else if(owned_capacitor && owned_capacitor.owned_gen == src) @@ -128,46 +122,21 @@ toggle() return PROCESS_KILL - average_field_strength = max(average_field_strength, 0) + if(istype(energy_field)) + var/required_energy = energy_field.get_required_energy() + var/assumed_charge = assume_charge(required_energy) + energy_field.handle_strength(assumed_charge) - if(field.len) - time_since_fail++ - var/total_renwick_increase = 0 //the amount of renwicks that the generator can add this tick, over the entire field - var/renwick_upkeep_per_field = max(average_field_strength * dissipation_rate, min_dissipation) - - //figure out how much energy we need to draw from the capacitor - if(active && owned_capacitor?.active) - var/target_renwick_increase = min(target_field_strength - average_field_strength, strengthen_rate) + renwick_upkeep_per_field //per field tile - - var/required_energy = field.len * target_renwick_increase / energy_conversion_rate - var/assumed_charge = min(owned_capacitor.stored_charge, required_energy) - total_renwick_increase = assumed_charge * energy_conversion_rate - assumed_charge = max(assumed_charge, 0) - owned_capacitor.stored_charge -= assumed_charge - else - renwick_upkeep_per_field = max(renwick_upkeep_per_field, 0.5) - - var/renwick_increase_per_field = total_renwick_increase/field.len //per field tile - - average_field_strength = 0 //recalculate the average field strength - for(var/obj/effect/energy_field/E as anything in field) - if(!E) - field -= E - continue - var/amount_to_strengthen = renwick_increase_per_field - renwick_upkeep_per_field - if(E.ticks_recovering > 0 && amount_to_strengthen > 0) - E.Strengthen( min(amount_to_strengthen / 10, 0.1) ) - E.ticks_recovering -= 1 - else - E.Strengthen(amount_to_strengthen) - - average_field_strength += E.strength - - average_field_strength /= field.len - if(average_field_strength < 1) - time_since_fail = 0 - else - average_field_strength = 0 +/** + * Called whenever the field needs to take charge from the capacitor. + */ +/obj/machinery/shield_gen/proc/assume_charge(required_energy) + if(!owned_capacitor) + return 0 + var/assumed_charge = min(owned_capacitor.stored_charge, required_energy) + assumed_charge = max(assumed_charge, 0) + owned_capacitor.stored_charge -= assumed_charge + return assumed_charge /obj/machinery/shield_gen/ex_act(var/severity) if(active) @@ -178,22 +147,13 @@ active = !active update_icon() if(active) - var/list/covered_turfs = get_shielded_turfs() - var/turf/T = get_turf(src) - for(var/turf/O as anything in covered_turfs - T) - var/obj/effect/energy_field/E = new(O) - field.Add(E) - covered_turfs = null - for(var/mob/M as anything in hearers(5,src)) - to_chat(M, "[icon2html(src, M)] You hear heavy droning start up.") + to_chat(M, SPAN_NOTICE("[icon2html(src, M)] You hear heavy droning start up.")) + energy_field.set_shielded_turfs(get_shielded_turfs()) else - for(var/obj/effect/energy_field/D as anything in field) - field.Remove(D) - D.loc = null - for(var/mob/M as anything in hearers(5,src)) - to_chat(M, "[icon2html(src, M)] You hear heavy droning fade out.") + to_chat(M, SPAN_NOTICE("[icon2html(src, M)] You hear heavy droning fade out.")) + energy_field.clear_field() /obj/machinery/shield_gen/update_icon() if(stat & BROKEN) @@ -212,7 +172,7 @@ if(field_radius > 0 && T) var/connected_levels = list(T.z) if(multiz) - for(var/turf/connected_z_turf as anything in (getzabove(src) + getzbelow(src))) + for(var/turf/connected_z_turf as anything in (getzabove(T) + getzbelow(T))) connected_levels += connected_z_turf.z . += block(\ @@ -235,6 +195,8 @@ locate(T.x + field_radius, T.y - field_radius + 1, max(connected_levels))\ ) + return . - get_turf(src) + /obj/machinery/shield_gen/ui_interact(mob/user, var/datum/tgui/ui) ui = SStgui.try_update_ui(user, src, ui) if(!ui) @@ -246,19 +208,12 @@ data["owned_capacitor"] = !!owned_capacitor data["active"] = active - data["time_since_fail"] = time_since_fail - data["multi_unlocked"] = multi_unlocked + data["time_since_fail"] = energy_field ? energy_field.time_since_fail : 0 data["multiz"] = multiz data["field_radius"] = field_radius data["min_field_radius"] = 1 data["max_field_radius"] = max_field_radius - data["average_field"] = round(average_field_strength, 0.01) - data["progress_field"] = (target_field_strength ? round(100 * average_field_strength / target_field_strength, 0.1) : "NA") - data["power_take"] = round(field.len * max(average_field_strength * dissipation_rate, min_dissipation) / energy_conversion_rate) - data["shield_power"] = round(field.len * min(strengthen_rate, target_field_strength - average_field_strength) / energy_conversion_rate) - data["strengthen_rate"] = (strengthen_rate * 10) - data["max_strengthen_rate"] = (max_strengthen_rate * 10) - data["target_field_strength"] = target_field_strength + data = energy_field.add_field_ui_data(data) return data @@ -278,10 +233,10 @@ field_radius = between(1, text2num(params["size_set"]), max_field_radius) if ("charge_set") - strengthen_rate = (between(1, text2num(params["charge_set"]), (max_strengthen_rate * 10)) / 10) + energy_field.strengthen_rate = (between(1, text2num(params["charge_set"]), (energy_field.max_strengthen_rate * 10)) / 10) if ("field_set") - target_field_strength = between(1, text2num(params["field_set"]), 10) + energy_field.target_field_strength = between(1, text2num(params["field_set"]), 10) add_fingerprint(usr) diff --git a/code/modules/shieldgen/shield_gen_external.dm b/code/modules/shieldgen/shield_gen_external.dm index e1131da8ca4..4dd618d7ca0 100644 --- a/code/modules/shieldgen/shield_gen_external.dm +++ b/code/modules/shieldgen/shield_gen_external.dm @@ -3,7 +3,6 @@ /obj/machinery/shield_gen/external name = "hull shield generator" - multi_unlocked = TRUE //Search for space turfs within range that are adjacent to a simulated turf. /obj/machinery/shield_gen/external/get_shielded_turfs() diff --git a/html/changelogs/mattatlas-unfuckshields.yml b/html/changelogs/mattatlas-unfuckshields.yml new file mode 100644 index 00000000000..68f224935d9 --- /dev/null +++ b/html/changelogs/mattatlas-unfuckshields.yml @@ -0,0 +1,58 @@ +################################ +# Example Changelog File +# +# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb. +# +# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.) +# When it is, any changes listed below will disappear. +# +# Valid Prefixes: +# bugfix +# - (fixes bugs) +# wip +# - (work in progress) +# qol +# - (quality of life) +# soundadd +# - (adds a sound) +# sounddel +# - (removes a sound) +# rscadd +# - (adds a feature) +# rscdel +# - (removes a feature) +# imageadd +# - (adds an image or sprite) +# imagedel +# - (removes an image or sprite) +# spellcheck +# - (fixes spelling or grammar) +# experiment +# - (experimental change) +# balance +# - (balance changes) +# code_imp +# - (misc internal code change) +# refactor +# - (refactors code) +# config +# - (makes a change to the config files) +# admin +# - (makes changes to administrator tools) +# server +# - (miscellaneous changes to server) +################################# + +# Your name. +author: MattAtlas + +# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again. +delete-after: True + +# Any changes you've made. See valid prefix list above. +# INDENT WITH TWO SPACES. NOT TABS. SPACES. +# SCREW THIS UP AND IT WON'T WORK. +# Also, this gets changed to [] after reading. Just remove the brackets when you add new shit. +# Please surround your changes in double quotes ("). It works without them, but if you use certain characters it screws up compiling. The quotes will not show up in the changelog. +changes: + - experiment: "Shields have been reworked to be far more performant, and genericized to allow anything to have an energy field." diff --git a/tgui/packages/tgui/interfaces/ShieldGenerator.tsx b/tgui/packages/tgui/interfaces/ShieldGenerator.tsx index 73e2c3183b4..4461e28cb2d 100644 --- a/tgui/packages/tgui/interfaces/ShieldGenerator.tsx +++ b/tgui/packages/tgui/interfaces/ShieldGenerator.tsx @@ -7,7 +7,6 @@ export type ShieldData = { owned_capacitor: BooleanLike; active: BooleanLike; time_since_fail: number; - multi_unlocked: BooleanLike; multiz: BooleanLike; field_radius: number; min_field_radius: number;