diff --git a/code/__DEFINES/resonator_defines.dm b/code/__DEFINES/resonator_defines.dm new file mode 100644 index 00000000000..b6a4b897d26 --- /dev/null +++ b/code/__DEFINES/resonator_defines.dm @@ -0,0 +1,3 @@ +#define RESONATOR_MODE_AUTO 1 +#define RESONATOR_MODE_MANUAL 2 +#define RESONATOR_MODE_MATRIX 3 diff --git a/code/modules/mining/equipment/resonator.dm b/code/modules/mining/equipment/resonator.dm index 6c94015d9a5..ba80370b261 100644 --- a/code/modules/mining/equipment/resonator.dm +++ b/code/modules/mining/equipment/resonator.dm @@ -9,42 +9,60 @@ w_class = WEIGHT_CLASS_NORMAL force = 15 throwforce = 10 - var/burst_time = 30 - var/fieldlimit = 4 - var/list/fields = list() + + /// the mode of the resonator; has three modes: auto (1), manual (2), and matrix (3) + var/mode = RESONATOR_MODE_AUTO + /// How efficient it is in manual mode. Yes, we lower the damage cuz it's gonna be used for mobhunt var/quick_burst_mod = 0.8 + /// the number of fields the resonator is allowed to have at once + var/fieldlimit = 4 + /// the list of currently active fields from this resonator + var/list/fields = list() + /// the number that is added to the failure_prob, which is the probability of whether it will spread or not + var/adding_failure = 50 + +/obj/item/resonator/attack_self(mob/user) + if(mode == RESONATOR_MODE_AUTO) + to_chat(user, "You set the [name]'s fields to detonate only after you hit it with [src].") + mode = RESONATOR_MODE_MANUAL + else + to_chat(user, "You set [src]'s fields to detonate after 2 seconds.") + mode = RESONATOR_MODE_AUTO /obj/item/resonator/upgraded name = "upgraded resonator" - desc = "An upgraded version of the resonator that can produce more fields at once." + desc = "An upgraded version of the resonator that can produce more fields at once, as well as having no damage penalty for bursting a resonance field early. It also allows you to set 'Resonance matrixes', that detonate after someone (or something) walks over it." icon_state = "resonator_u" origin_tech = "materials=4;powerstorage=3;engineering=3;magnets=3" fieldlimit = 6 quick_burst_mod = 1 -/obj/item/resonator/attack_self(mob/user) - if(burst_time == 50) - burst_time = 30 - to_chat(user, "You set the resonator's fields to detonate after 3 seconds.") +/obj/item/resonator/upgraded/attack_self(mob/user) + if(mode == RESONATOR_MODE_AUTO) + to_chat(user, "You set [src]'s fields to detonate only after being attacked by [src].") + mode = RESONATOR_MODE_MANUAL + else if(mode == RESONATOR_MODE_MANUAL) + to_chat(user, "You set [src]'s fields to work as matrix traps.") + mode = RESONATOR_MODE_MATRIX else - burst_time = 50 - to_chat(user, "You set the resonator's fields to detonate after 5 seconds.") + to_chat(user, "You set [src]'s fields to detonate automatically after 2 seconds.") + mode = RESONATOR_MODE_AUTO -/obj/item/resonator/proc/CreateResonance(target, mob/user) - var/turf/T = get_turf(target) - var/obj/effect/temp_visual/resonance/R = locate(/obj/effect/temp_visual/resonance) in T - if(R) - R.damage_multiplier = quick_burst_mod - R.burst() +/obj/item/resonator/proc/create_resonance(target, mob/user) + var/turf/target_turf = get_turf(target) + var/obj/effect/temp_visual/resonance/resonance_field = locate(/obj/effect/temp_visual/resonance) in target_turf + if(resonance_field) + resonance_field.damage_multiplier = quick_burst_mod + resonance_field.burst() return if(LAZYLEN(fields) < fieldlimit) - new /obj/effect/temp_visual/resonance(T, user, src, burst_time) + new /obj/effect/temp_visual/resonance(target_turf, user, src, mode, adding_failure) user.changeNext_move(CLICK_CD_MELEE) /obj/item/resonator/pre_attack(atom/target, mob/user, params) - if(check_allowed_items(target, 1)) - CreateResonance(target, user) - return TRUE + if(check_allowed_items(target, not_inside = TRUE)) + create_resonance(target, user) + return ..() //resonance field, crushes rock, damages mobs /obj/effect/temp_visual/resonance @@ -53,31 +71,48 @@ icon = 'icons/effects/effects.dmi' icon_state = "shield1" layer = ABOVE_ALL_MOB_LAYER - duration = 50 + duration = 60 SECONDS + /// the amount of damage living beings will take whilst inside the field during its burst var/resonance_damage = 20 + /// the modifier to resonance_damage; affected by the quick_burst_mod from the resonator var/damage_multiplier = 1 - var/creator - var/obj/item/resonator/res + /// the parent creator (user) of this field + var/mob/creator + /// the parent resonator of this field + var/obj/item/resonator/parent_resonator + /// whether the field is rupturing currently or not (to prevent recursion) + var/rupturing = FALSE + /// the probability that the field will not be able to spread + var/failure_prob = 0 + /// the number that is added to the failure_prob. Will default to 50 + var/adding_failure -/obj/effect/temp_visual/resonance/New(loc, set_creator, set_resonator, set_duration) - duration = set_duration +/obj/effect/temp_visual/resonance/Initialize(mapload, set_creator, set_resonator, mode, set_failure = 50) + if(mode == RESONATOR_MODE_AUTO) + duration = 2 SECONDS + if(mode == RESONATOR_MODE_MATRIX) + icon_state = "shield2" + name = "resonance matrix" + RegisterSignal(src, COMSIG_MOVABLE_CROSSED, PROC_REF(burst)) . = ..() creator = set_creator - res = set_resonator - if(res) - res.fields += src - playsound(src,'sound/weapons/resonator_fire.ogg',50,1) - transform = matrix() * 0.75 - animate(src, transform = matrix() * 1.5, time = duration) + parent_resonator = set_resonator + if(parent_resonator) + parent_resonator.fields += src + adding_failure = set_failure + playsound(src, 'sound/weapons/resonator_blast.ogg', 50, TRUE) + if(mode == RESONATOR_MODE_AUTO) + transform = matrix() * 0.75 + animate(src, transform = matrix() * 1.5, time = duration) deltimer(timerid) timerid = addtimer(CALLBACK(src, PROC_REF(burst)), duration, TIMER_STOPPABLE) /obj/effect/temp_visual/resonance/Destroy() - if(res) - res.fields -= src - res = null + if(parent_resonator) + parent_resonator.fields -= src + parent_resonator = null creator = null - return ..() + . = ..() /obj/effect/temp_visual/resonance/proc/check_pressure(turf/proj_turf) if(!proj_turf) @@ -91,21 +126,33 @@ resonance_damage *= damage_multiplier /obj/effect/temp_visual/resonance/proc/burst() - var/turf/T = get_turf(src) - new /obj/effect/temp_visual/resonance_crush(T) - if(ismineralturf(T)) - if(is_ancient_rock(T)) - visible_message("This rock appears to be resistant to all mining tools except pickaxes!") - else - var/turf/simulated/mineral/M = T - M.gets_drilled(creator) - check_pressure(T) - playsound(T,'sound/weapons/resonator_blast.ogg',50,1) - for(var/mob/living/L in T) + SIGNAL_HANDLER // COMSIG_MOVABLE_CROSSED + if(rupturing) + return + rupturing = TRUE + var/turf/src_turf = get_turf(src) + new /obj/effect/temp_visual/resonance_crush(src_turf) + if(ismineralturf(src_turf)) + var/turf/simulated/mineral/mineral_turf = src_turf + mineral_turf.gets_drilled(creator) + check_pressure(src_turf) + playsound(src_turf, 'sound/weapons/resonator_blast.ogg', 50, TRUE) + for(var/mob/living/attacked_living in src_turf) if(creator) - add_attack_logs(creator, L, "Resonance field'ed") - to_chat(L, "[src] ruptured with you in it!") - L.apply_damage(resonance_damage, BRUTE) + log_attack(creator, attacked_living, "used a resonator field on", "resonator") + to_chat(attacked_living, "[src] ruptured with you in it!") + attacked_living.apply_damage(resonance_damage, BRUTE) + for(var/obj/effect/temp_visual/resonance/field in orange(1, src)) + if(field.rupturing) + continue + if(parent_resonator.mode == RESONATOR_MODE_AUTO || parent_resonator.mode == RESONATOR_MODE_MANUAL) + field.burst() + if(!prob(failure_prob) && parent_resonator) + for(var/turf/simulated/mineral/mineral_spread in orange(1, src)) + if(locate(/obj/effect/temp_visual/resonance) in mineral_spread) + continue + var/obj/effect/temp_visual/resonance/new_field = new(mineral_spread, creator, parent_resonator, parent_resonator.mode) + new_field.failure_prob = failure_prob + adding_failure qdel(src) /obj/effect/temp_visual/resonance_crush @@ -113,7 +160,7 @@ layer = ABOVE_ALL_MOB_LAYER duration = 4 -/obj/effect/temp_visual/resonance_crush/New() - ..() - transform = matrix()*1.5 +/obj/effect/temp_visual/resonance_crush/Initialize(mapload) + . = ..() + transform = matrix() * 1.5 animate(src, transform = matrix() * 0.1, alpha = 50, time = 4) diff --git a/code/modules/projectiles/guns/energy/kinetic_accelerator.dm b/code/modules/projectiles/guns/energy/kinetic_accelerator.dm index 5b22c551ca5..a5a8f66f953 100644 --- a/code/modules/projectiles/guns/energy/kinetic_accelerator.dm +++ b/code/modules/projectiles/guns/energy/kinetic_accelerator.dm @@ -538,7 +538,7 @@ R.damage_multiplier = modifier R.burst() return - new /obj/effect/temp_visual/resonance(target_turf, K.firer, null, 30) + new /obj/effect/temp_visual/resonance(target_turf, K.firer, null, RESONATOR_MODE_MANUAL, 100) //manual detonate mode and will NOT spread /obj/item/borg/upgrade/modkit/bounty name = "death syphon" diff --git a/paradise.dme b/paradise.dme index a20ea022411..ddaee141df4 100644 --- a/paradise.dme +++ b/paradise.dme @@ -109,6 +109,7 @@ #include "code\__DEFINES\reagents_defines.dm" #include "code\__DEFINES\regex.dm" #include "code\__DEFINES\revolution_defines.dm" +#include "code\__DEFINES\resonator_defines.dm" #include "code\__DEFINES\role_preferences.dm" #include "code\__DEFINES\rolebans.dm" #include "code\__DEFINES\rust.dm"