/obj/item/reactive_armour_shell name = "reactive armour shell" desc = "An experimental suit of armour, awaiting installation of an anomaly core." icon_state = "reactiveoff" icon = 'icons/obj/clothing/suits.dmi' w_class = WEIGHT_CLASS_BULKY /obj/item/reactive_armour_shell/attackby(obj/item/I, mob/user, params) ..() var/static/list/anomaly_armour_types = list( /obj/effect/anomaly/grav = /obj/item/clothing/suit/armor/reactive/repulse, /obj/effect/anomaly/flux = /obj/item/clothing/suit/armor/reactive/tesla, /obj/effect/anomaly/bluespace = /obj/item/clothing/suit/armor/reactive/teleport ) if(istype(I, /obj/item/assembly/signaler/anomaly)) var/obj/item/assembly/signaler/anomaly/A = I var/armour_path = anomaly_armour_types[A.anomaly_type] if(!armour_path) armour_path = /obj/item/clothing/suit/armor/reactive/stealth //Lets not cheat the player if an anomaly type doesnt have its own armour coded to_chat(user, "You insert [A] into the chest plate, and the armour gently hums to life.") new armour_path(get_turf(src)) qdel(src) qdel(A) //Reactive armor /obj/item/clothing/suit/armor/reactive name = "reactive armor" desc = "Doesn't seem to do much for some reason." var/active = 0 var/reactivearmor_cooldown_duration = 0 //cooldown specific to reactive armor var/reactivearmor_cooldown = 0 icon_state = "reactiveoff" item_state = "reactiveoff" blood_overlay_type = "armor" armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 100, ACID = 100) actions_types = list(/datum/action/item_action/toggle) resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE var/hit_reaction_chance = 50 mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON /obj/item/clothing/suit/armor/reactive/attack_self(mob/user) active = !(active) if(active) to_chat(user, "[src] is now active.") icon_state = "reactive" item_state = "reactive" else to_chat(user, "[src] is now inactive.") icon_state = "reactiveoff" item_state = "reactiveoff" add_fingerprint(user) if(user.get_item_by_slot(ITEM_SLOT_OCLOTHING) == src) user.update_inv_wear_suit() /obj/item/clothing/suit/armor/reactive/emp_act(severity) . = ..() if(. & EMP_PROTECT_SELF) return active = 0 icon_state = "reactiveoff" item_state = "reactiveoff" reactivearmor_cooldown = world.time + 200 /obj/item/clothing/suit/armor/reactive/run_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return) if(!active) return BLOCK_NONE return block_action(owner, object, damage, attack_text, attack_type, armour_penetration, attacker, def_zone, final_block_chance, block_return) /obj/item/clothing/suit/armor/reactive/proc/block_action(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return) return BLOCK_NONE //When the wearer gets hit, this armor will teleport the user a short distance away (to safety or to more danger, no one knows. That's the fun of it!) /obj/item/clothing/suit/armor/reactive/teleport name = "reactive teleport armor" desc = "Someone separated our Research Director from his own head!" var/tele_range = 8 var/rad_amount = 60 var/rad_amount_before = 120 reactivearmor_cooldown_duration = 100 /obj/item/clothing/suit/armor/reactive/teleport/block_action(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return) if(prob(hit_reaction_chance)) var/mob/living/carbon/human/H = owner if(world.time < reactivearmor_cooldown) owner.visible_message("The reactive teleport system is still recharging! It fails to teleport [H]!") return owner.visible_message("The reactive teleport system flings [H] clear of [attack_text], shutting itself off in the process!") playsound(get_turf(owner), 'sound/magic/blink.ogg', 100, 1) var/list/turfs = new var/turf/old = get_turf(src) for(var/turf/T in orange(tele_range, H)) if(T.density) continue if(T.x>world.maxx-tele_range || T.xworld.maxy-tele_range || T.yThe reactive incendiary armor on [owner] activates, but fails to send out flames as it is still recharging its flame jets!") return owner.visible_message("[src] blocks [attack_text], sending out jets of flame!") playsound(get_turf(owner),'sound/magic/fireball.ogg', 100, 1) for(var/mob/living/carbon/C in range(6, owner)) if(C != owner) C.fire_stacks += 8 C.IgniteMob() owner.fire_stacks = -20 reactivearmor_cooldown = world.time + reactivearmor_cooldown_duration return BLOCK_SUCCESS | BLOCK_PHYSICAL_INTERNAL return BLOCK_NONE //Stealth /obj/item/clothing/suit/armor/reactive/stealth name = "reactive stealth armor" reactivearmor_cooldown_duration = 65 desc = "An experimental suit of armor that renders the wearer invisible on detection of imminent harm, and creates a decoy that runs away from the owner. You can't fight what you can't see." /obj/item/clothing/suit/armor/reactive/stealth/block_action(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return) if(prob(hit_reaction_chance)) if(world.time < reactivearmor_cooldown) owner.visible_message("The reactive stealth system on [owner] activates, but is still recharging its holographic emitters!") return var/mob/living/simple_animal/hostile/illusion/escape/E = new(owner.loc) E.Copy_Parent(owner, 50) E.GiveTarget(owner) //so it starts running right away E.Goto(owner, E.move_to_delay, E.minimum_distance) owner.alpha = 30 owner.visible_message("[owner] is hit by [attack_text] in the chest!") //We pretend to be hit, since blocking it would stop the message otherwise spawn(40) owner.alpha = initial(owner.alpha) reactivearmor_cooldown = world.time + reactivearmor_cooldown_duration return BLOCK_SUCCESS | BLOCK_PHYSICAL_INTERNAL return BLOCK_NONE //Tesla /obj/item/clothing/suit/armor/reactive/tesla name = "reactive tesla armor" desc = "An experimental suit of armor with sensitive detectors hooked up to a huge capacitor grid, with emitters strutting out of it. Zap." siemens_coefficient = -1 reactivearmor_cooldown_duration = 20 var/zap_power = 25000 var/zap_range = 20 var/zap_flags = ZAP_MOB_DAMAGE | ZAP_OBJ_DAMAGE var/legacy = FALSE var/legacy_dmg = 30 /obj/item/clothing/suit/armor/reactive/tesla/dropped(mob/user) ..() if(istype(user)) REMOVE_TRAIT(user, TRAIT_TESLA_SHOCKIMMUNE, "reactive_tesla_armor") /obj/item/clothing/suit/armor/reactive/tesla/equipped(mob/user, slot) ..() if(slot_flags & slot) //Was equipped to a valid slot for this item? ADD_TRAIT(user, TRAIT_TESLA_SHOCKIMMUNE, "reactive_tesla_armor") /obj/item/clothing/suit/armor/reactive/tesla/block_action(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return) if(prob(hit_reaction_chance)) if(world.time < reactivearmor_cooldown) var/datum/effect_system/spark_spread/sparks = new /datum/effect_system/spark_spread sparks.set_up(1, 1, src) sparks.start() owner.visible_message("The tesla capacitors on [owner]'s reactive tesla armor are still recharging! The armor merely emits some sparks.") return owner.visible_message("[src] blocks [attack_text], sending out arcs of lightning!") if(!legacy) tesla_zap(owner, zap_range, zap_power, zap_flags) else for(var/mob/living/M in view(7, owner)) if(M == owner) continue owner.Beam(M,icon_state="purple_lightning",icon='icons/effects/effects.dmi',time=5) M.adjustFireLoss(legacy_dmg) playsound(M, 'sound/machines/defib_zap.ogg', 50, 1, -1) reactivearmor_cooldown = world.time + reactivearmor_cooldown_duration return BLOCK_SUCCESS | BLOCK_PHYSICAL_INTERNAL return NONE //Repulse /obj/item/clothing/suit/armor/reactive/repulse name = "reactive repulse armor" reactivearmor_cooldown_duration = 20 desc = "An experimental suit of armor that violently throws back attackers." /obj/item/clothing/suit/armor/reactive/repulse/block_action(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return) if(prob(hit_reaction_chance)) if(world.time < reactivearmor_cooldown) owner.visible_message("The repulse generator is still recharging!") return FALSE playsound(get_turf(owner),'sound/magic/repulse.ogg', 100, 1) owner.visible_message("[src] blocks [attack_text], converting the attack into a wave of force!") var/turf/T = get_turf(owner) var/list/cachedrange = range(T, 7) - owner var/safety = 50 var/list/to_throw = list() for(var/mob/living/L in cachedrange) if(L.move_resist > MOVE_FORCE_EXTREMELY_STRONG) continue to_throw += L for(var/obj/O in cachedrange) if(O.anchored) continue to_throw += O for(var/i in to_throw) if(!safety) break var/atom/movable/AM = i var/throwtarget = get_edge_target_turf(T, get_dir(T, get_step_away(AM, T))) AM.throw_at(throwtarget,10,1) safety-- reactivearmor_cooldown = world.time + reactivearmor_cooldown_duration return BLOCK_SUCCESS | BLOCK_PHYSICAL_INTERNAL return BLOCK_NONE /obj/item/clothing/suit/armor/reactive/table name = "reactive table armor" reactivearmor_cooldown_duration = 0 desc = "If you can't beat the memes, embrace them." var/tele_range = 10 /obj/item/clothing/suit/armor/reactive/table/block_action(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return) if(prob(hit_reaction_chance)) var/mob/living/carbon/human/H = owner if(world.time < reactivearmor_cooldown) owner.visible_message("The reactive table armor's fabricators are still on cooldown!") return owner.visible_message("The reactive teleport system flings [H] clear of [attack_text] and slams [H.p_them()] into a fabricated table!") owner.visible_message("[H] GOES ON THE TABLE!!!") owner.DefaultCombatKnockdown(40) var/list/turfs = new/list() for(var/turf/T in orange(tele_range, H)) if(T.density) continue if(T.x>world.maxx-tele_range || T.xworld.maxy-tele_range || T.y