mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-08-29 15:08:02 +01:00
Adds the bluespace anchor cybernetic implant (#26978)
* Anchor? I hardly know her! * biochip code my hated * yeah that's fair * Apply suggestions from code review Co-authored-by: Luc <89928798+lewcc@users.noreply.github.com> Signed-off-by: Qwertytoforty <52090703+Qwertytoforty@users.noreply.github.com> --------- Signed-off-by: Qwertytoforty <52090703+Qwertytoforty@users.noreply.github.com> Co-authored-by: Luc <89928798+lewcc@users.noreply.github.com>
This commit is contained in:
@@ -206,3 +206,7 @@
|
||||
|
||||
/// called when a living mob's stun status is cleared: ()
|
||||
#define COMSIG_LIVING_CLEAR_STUNS "living_clear_stuns"
|
||||
|
||||
/// Sent from datum/spell/ethereal_jaunt/cast, before the mob enters jaunting as a pre-check: (mob/jaunter)
|
||||
#define COMSIG_MOB_PRE_JAUNT "spell_mob_pre_jaunt"
|
||||
#define COMPONENT_BLOCK_JAUNT (1<<0)
|
||||
|
||||
@@ -63,3 +63,9 @@
|
||||
// Note that this is only defined for actions because this could be a good bit expensive otherwise
|
||||
/// From base of /atom/movable/screen/movable/action_button/MouseWheel(src, delta_x, delta_y, location, control, params)
|
||||
#define COMSIG_ACTION_SCROLLED "action_scrolled"
|
||||
|
||||
/// Called before a movable is being teleported from multiple sources: (destination)
|
||||
#define COMSIG_MOVABLE_TELEPORTING "movable_teleporting"
|
||||
/// Called when blocking a teleport
|
||||
#define COMSIG_ATOM_INTERCEPT_TELEPORTED "intercept_teleported"
|
||||
#define COMPONENT_BLOCK_TELEPORT (1<<0)
|
||||
|
||||
@@ -90,6 +90,8 @@
|
||||
/datum/disease/wizarditis/proc/teleport()
|
||||
if(!is_teleport_allowed(affected_mob.z))
|
||||
return
|
||||
if(SEND_SIGNAL(affected_mob, COMSIG_MOVABLE_TELEPORTING, get_turf(affected_mob)) & COMPONENT_BLOCK_TELEPORT)
|
||||
return FALSE
|
||||
|
||||
var/list/possible_areas = get_areas_in_range(80, affected_mob)
|
||||
for(var/area/space/S in possible_areas)
|
||||
|
||||
@@ -149,6 +149,10 @@
|
||||
|
||||
if(!is_teleport_allowed(destturf.z) && !ignore_area_flag)
|
||||
return FALSE
|
||||
if(!ignore_area_flag) // Admin or contractor portal, let em through without running signals
|
||||
if(SEND_SIGNAL(teleatom, COMSIG_MOVABLE_TELEPORTING, destination) & COMPONENT_BLOCK_TELEPORT)
|
||||
return FALSE
|
||||
|
||||
// Only check the destination zlevel for is_teleport_allowed. Checking origin as well breaks ERT teleporters.
|
||||
|
||||
var/area/destarea = get_area(destturf)
|
||||
|
||||
@@ -29,6 +29,8 @@
|
||||
return
|
||||
if(!isliving(user))
|
||||
return FALSE
|
||||
if(SEND_SIGNAL(user, COMSIG_MOB_PRE_JAUNT, get_turf(user)) & COMPONENT_BLOCK_JAUNT)
|
||||
return FALSE
|
||||
|
||||
/datum/spell/bloodcrawl/cast(list/targets, mob/living/user)
|
||||
var/atom/target = targets[1]
|
||||
|
||||
@@ -26,6 +26,8 @@
|
||||
/datum/spell/ethereal_jaunt/cast(list/targets, mob/user = usr) //magnets, so mostly hardcoded
|
||||
playsound(get_turf(user), sound1, 50, TRUE, -1)
|
||||
for(var/mob/living/target in targets)
|
||||
if(SEND_SIGNAL(target, COMSIG_MOB_PRE_JAUNT, target) & COMPONENT_BLOCK_JAUNT)
|
||||
continue
|
||||
if(!target.can_safely_leave_loc()) // No more brainmobs hopping out of their brains
|
||||
to_chat(target, "<span class='warning'>You are somehow too bound to your current location to abandon it.</span>")
|
||||
continue
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
playsound(get_turf(user), sound1, 50, TRUE)
|
||||
|
||||
for(var/mob/living/target in targets)
|
||||
if(SEND_SIGNAL(target, COMSIG_MOVABLE_TELEPORTING, get_turf(target)) & COMPONENT_BLOCK_TELEPORT)
|
||||
continue
|
||||
var/list/turfs = list()
|
||||
for(var/turf/T in range(target,outer_tele_radius))
|
||||
if(T in range(target,inner_tele_radius)) continue
|
||||
|
||||
@@ -537,6 +537,8 @@
|
||||
|
||||
var/turf/origin = get_turf(teleportee)
|
||||
var/turf/destination = get_turf(actual_selected_rune)
|
||||
if(SEND_SIGNAL(target, COMSIG_MOVABLE_TELEPORTING, destination) & COMPONENT_BLOCK_TELEPORT)
|
||||
return
|
||||
INVOKE_ASYNC(actual_selected_rune, TYPE_PROC_REF(/obj/effect/rune, teleport_effect), teleportee, origin, destination)
|
||||
|
||||
if(is_mining_level(user.z) && !is_mining_level(destination.z)) //No effect if you stay on lavaland
|
||||
|
||||
@@ -324,6 +324,8 @@
|
||||
if(C.pulling)
|
||||
var/atom/movable/pulled = C.pulling
|
||||
var/turf/turf_behind = get_turf(get_step(T, turn(C.dir, 180)))
|
||||
if(SEND_SIGNAL(pulled, COMSIG_MOVABLE_TELEPORTING, turf_behind) & COMPONENT_BLOCK_TELEPORT)
|
||||
return FALSE
|
||||
if(!pulled.anchored) //Item may have been anchored while pulling, and pulling state isn't updated until you move away, so we double check.
|
||||
pulled.forceMove(turf_behind)
|
||||
. = pulled
|
||||
@@ -338,6 +340,8 @@
|
||||
step(src, pick(GLOB.alldirs))
|
||||
to_chat(user, "<span class='warning'>[src] flickers out of your hands, too eager to move!</span>")
|
||||
return
|
||||
if(SEND_SIGNAL(user, COMSIG_MOVABLE_TELEPORTING, get_turf(user)) & COMPONENT_BLOCK_TELEPORT)
|
||||
return FALSE
|
||||
if(user.holy_check())
|
||||
return
|
||||
var/outer_tele_radius = 9
|
||||
|
||||
@@ -494,6 +494,8 @@ structure_check() searches for nearby cultist structures required for the invoca
|
||||
var/movedsomething = FALSE
|
||||
var/moveuser = FALSE
|
||||
for(var/atom/movable/A in T)
|
||||
if(SEND_SIGNAL(A, COMSIG_MOVABLE_TELEPORTING, target) & COMPONENT_BLOCK_TELEPORT)
|
||||
continue
|
||||
if(ishuman(A))
|
||||
if(A != user) // Teleporting someone else
|
||||
INVOKE_ASYNC(src, PROC_REF(teleport_effect), A, T, target)
|
||||
@@ -775,6 +777,11 @@ structure_check() searches for nearby cultist structures required for the invoca
|
||||
fail_invoke()
|
||||
log_game("Summon Cultist rune failed - target in away mission")
|
||||
return
|
||||
if(SEND_SIGNAL(cultist_to_summon, COMSIG_MOVABLE_TELEPORTING, get_turf(src)) & COMPONENT_BLOCK_TELEPORT)
|
||||
to_chat(user, "<span class='cultitalic'>[cultist_to_summon] is anchored in bluespace!</span>")
|
||||
fail_invoke()
|
||||
log_game("Summon Cultist rune failed - anchored in bluespace")
|
||||
return
|
||||
|
||||
cultist_to_summon.visible_message("<span class='warning'>[cultist_to_summon] suddenly disappears in a flash of red light!</span>", \
|
||||
"<span class='cultitalic'><b>Overwhelming vertigo consumes you as you are hurled through the air!</b></span>")
|
||||
|
||||
@@ -287,6 +287,8 @@
|
||||
card_icon = "the_fool"
|
||||
|
||||
/datum/tarot/the_fool/activate(mob/living/target)
|
||||
if(SEND_SIGNAL(target, COMSIG_MOVABLE_TELEPORTING, get_turf(target)) & COMPONENT_BLOCK_TELEPORT)
|
||||
return FALSE
|
||||
target.forceMove(pick(GLOB.latejoin))
|
||||
to_chat(target, "<span class='userdanger'>You are abruptly pulled through space!</span>")
|
||||
|
||||
@@ -364,7 +366,8 @@
|
||||
if(!length(L))
|
||||
to_chat(target, "<span class='warning'>Huh. No bridge? Well, that sucks.</span>")
|
||||
return
|
||||
|
||||
if(SEND_SIGNAL(target, COMSIG_MOVABLE_TELEPORTING, get_turf(target)) & COMPONENT_BLOCK_TELEPORT)
|
||||
return FALSE
|
||||
target.forceMove(pick(L))
|
||||
to_chat(target, "<span class='userdanger'>You are abruptly pulled through space!</span>")
|
||||
|
||||
@@ -440,7 +443,8 @@
|
||||
if(!length(viable_vendors))
|
||||
to_chat(target, "<span class='warning'>No vending machines? Well, with luck cargo will have something to offer. If you go there yourself.</span>")
|
||||
return
|
||||
|
||||
if(SEND_SIGNAL(target, COMSIG_MOVABLE_TELEPORTING, get_turf(target)) & COMPONENT_BLOCK_TELEPORT)
|
||||
return FALSE
|
||||
target.forceMove(get_turf(pick(viable_vendors)))
|
||||
to_chat(target, "<span class='userdanger'>You are abruptly pulled through space!</span>")
|
||||
|
||||
@@ -554,7 +558,8 @@
|
||||
if(!length(L))
|
||||
to_chat(target, "<span class='warning'>Huh. No evidence? Well, that means they can't charge you with a crime, right?</span>")
|
||||
return
|
||||
|
||||
if(SEND_SIGNAL(target, COMSIG_MOVABLE_TELEPORTING, get_turf(target)) & COMPONENT_BLOCK_TELEPORT)
|
||||
return FALSE
|
||||
target.forceMove(pick(L))
|
||||
to_chat(target, "<span class='userdanger'>You are abruptly pulled through space!</span>")
|
||||
for(var/obj/structure/closet/C in shuffle(view(9, target)))
|
||||
@@ -573,6 +578,8 @@
|
||||
/datum/tarot/the_moon/activate(mob/living/target)
|
||||
var/list/funny_ruin_list = list()
|
||||
var/turf/target_turf = get_turf(target)
|
||||
if(SEND_SIGNAL(target, COMSIG_MOVABLE_TELEPORTING, get_turf(target)) & COMPONENT_BLOCK_TELEPORT)
|
||||
return FALSE
|
||||
for(var/I in GLOB.ruin_landmarks)
|
||||
var/obj/effect/landmark/ruin/ruin_landmark = I
|
||||
if(ruin_landmark.z == target_turf.z)
|
||||
@@ -722,7 +729,8 @@
|
||||
if(!length(L))
|
||||
to_chat(target, "<span class='warning'>Huh. No command members? I hope you didn't kill them all already...</span>")
|
||||
return
|
||||
|
||||
if(SEND_SIGNAL(target, COMSIG_MOVABLE_TELEPORTING, get_turf(target)) & COMPONENT_BLOCK_TELEPORT)
|
||||
return FALSE
|
||||
target.forceMove(get_turf(pick(L)))
|
||||
to_chat(target, "<span class='userdanger'>You are abruptly pulled through space!</span>")
|
||||
|
||||
@@ -975,6 +983,7 @@
|
||||
if(!length(L))
|
||||
to_chat(target, "<span class='warning'>Hmm. No base? A miner issue.</span>")
|
||||
return
|
||||
|
||||
if(SEND_SIGNAL(target, COMSIG_MOVABLE_TELEPORTING, get_turf(target)) & COMPONENT_BLOCK_TELEPORT)
|
||||
return FALSE
|
||||
target.forceMove(pick(L))
|
||||
to_chat(target, "<span class='userdanger'>You are abruptly pulled through space!</span>")
|
||||
|
||||
@@ -113,6 +113,8 @@
|
||||
if(!is_teleport_allowed(starting.z) || starting_area.tele_proof)
|
||||
to_chat(user, "<span class='danger'>[src] will not work here!</span>")
|
||||
return
|
||||
if(SEND_SIGNAL(user, COMSIG_MOVABLE_TELEPORTING, starting) & COMPONENT_BLOCK_TELEPORT)
|
||||
return FALSE
|
||||
var/mob/living/M = user
|
||||
var/turf/mobloc = get_turf(M)
|
||||
var/list/turfs = list()
|
||||
|
||||
@@ -20,6 +20,13 @@
|
||||
return ..()
|
||||
|
||||
/obj/item/bio_chip/tracking/implant(mob/target)
|
||||
if(ishuman(target))
|
||||
var/mob/living/carbon/human/H = target
|
||||
var/obj/item/organ/internal/cyberimp/chest/bluespace_anchor/anchor = H.get_int_organ(/obj/item/organ/internal/cyberimp/chest/bluespace_anchor)
|
||||
if(anchor)
|
||||
target.visible_message("<span class='danger'>[src] sparks out, disrupted by [anchor] inside [H]!</span>")
|
||||
qdel(src)
|
||||
return FALSE
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
|
||||
@@ -164,8 +164,10 @@
|
||||
var/mob/living/target = targets[1]
|
||||
var/turf/user_turf = get_turf(user)
|
||||
var/turf/target_turf = get_turf(target)
|
||||
target.forceMove(user_turf)
|
||||
user.forceMove(target_turf)
|
||||
if(!(SEND_SIGNAL(target, COMSIG_MOVABLE_TELEPORTING, user_turf) & COMPONENT_BLOCK_TELEPORT))
|
||||
target.forceMove(user_turf)
|
||||
if(!(SEND_SIGNAL(user, COMSIG_MOVABLE_TELEPORTING, target_turf) & COMPONENT_BLOCK_TELEPORT))
|
||||
user.forceMove(target_turf)
|
||||
|
||||
/datum/spell/vampire/self/decoy
|
||||
name = "Deploy Decoy (30)"
|
||||
|
||||
@@ -173,6 +173,8 @@
|
||||
user.make_invisible()
|
||||
addtimer(CALLBACK(user, TYPE_PROC_REF(/mob/living, reset_visibility)), 4 SECONDS)
|
||||
else
|
||||
if(SEND_SIGNAL(user, COMSIG_MOVABLE_TELEPORTING, end_turf) & COMPONENT_BLOCK_TELEPORT) //You can fake it out, but no teleporting
|
||||
return FALSE
|
||||
user.forceMove(end_turf)
|
||||
|
||||
if(end_turf.z == start_turf.z)
|
||||
@@ -226,6 +228,8 @@
|
||||
|
||||
/datum/spell/vampire/dark_passage/cast(list/targets, mob/user)
|
||||
var/turf/target = get_turf(targets[1])
|
||||
if(SEND_SIGNAL(user, COMSIG_MOVABLE_TELEPORTING, target) & COMPONENT_BLOCK_TELEPORT)
|
||||
return FALSE
|
||||
|
||||
new /obj/effect/temp_visual/vamp_mist_out(get_turf(user))
|
||||
|
||||
|
||||
@@ -242,6 +242,8 @@
|
||||
var/turf/turf_to_teleport_to = get_step(target, get_dir(source, M)) //get position relative to caster
|
||||
if(!turf_to_teleport_to || is_blocked_turf(turf_to_teleport_to, TRUE))
|
||||
return
|
||||
if(SEND_SIGNAL(M, COMSIG_MOVABLE_TELEPORTING, turf_to_teleport_to) & COMPONENT_BLOCK_TELEPORT)
|
||||
return FALSE
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
H.set_alpha_tracking(0, src, update_alpha = FALSE)
|
||||
|
||||
@@ -293,6 +293,8 @@
|
||||
if(cooldown)
|
||||
to_chat(user, "<span class='warning'>[src] sparks and fizzles.</span>")
|
||||
return
|
||||
if(SEND_SIGNAL(user, COMSIG_MOVABLE_TELEPORTING, get_turf(linked)) & COMPONENT_BLOCK_TELEPORT)
|
||||
return FALSE
|
||||
|
||||
var/datum/effect_system/smoke_spread/smoke = new
|
||||
smoke.set_up(1, FALSE, user)
|
||||
|
||||
@@ -634,6 +634,17 @@
|
||||
build_path = /obj/item/organ/internal/cyberimp/brain/wire_interface
|
||||
category = list("Medical")
|
||||
|
||||
/datum/design/bluespace_anchor
|
||||
name = "Bluespace Anchor Implant"
|
||||
desc = "This large cybernetic implant anchors you in bluespace, preventing almost any teleportation effects from working. It disrupts GPS systems however."
|
||||
id = "bluespace_anchor_implant"
|
||||
req_tech = list("bluespace" = 7, "biotech" = 5)
|
||||
build_type = PROTOLATHE | MECHFAB
|
||||
construction_time = 6 SECONDS
|
||||
materials = list(MAT_METAL = 10000, MAT_BLUESPACE = 2000)
|
||||
build_path = /obj/item/organ/internal/cyberimp/chest/bluespace_anchor
|
||||
category = list("Medical")
|
||||
|
||||
/datum/design/raiden_implant
|
||||
name = "Reactive Repair Implant"
|
||||
desc = "This implant reworks the IPC frame, in order to incorporate materials that return to their original shape after being damaged. Requires power to function."
|
||||
|
||||
@@ -318,6 +318,12 @@
|
||||
cost = 500
|
||||
containername = "chemical bio-chip crate"
|
||||
|
||||
/datum/supply_packs/security/armory/bluespace_anchor
|
||||
name = "Bluespace Anchor Crate"
|
||||
contains = list(/obj/item/organ/internal/cyberimp/chest/bluespace_anchor)
|
||||
cost = 250
|
||||
containername = "bluespace anchor crate"
|
||||
|
||||
/datum/supply_packs/security/securitybarriers
|
||||
name = "Security Barriers Crate"
|
||||
contains = list(/obj/item/grenade/barrier,
|
||||
|
||||
@@ -734,6 +734,51 @@
|
||||
if(H.stat == CONSCIOUS)
|
||||
to_chat(H, "<span class='notice'>You feel your heart beating again!</span>")
|
||||
|
||||
/obj/item/organ/internal/cyberimp/chest/bluespace_anchor
|
||||
name = "bluespace anchor implant"
|
||||
desc = "This large cybernetic implant anchors you in bluespace, preventing almost any teleportation effects from working. It disrupts GPS systems however."
|
||||
icon_state = "bluespace_anchor"
|
||||
implant_overlay = null
|
||||
slot = "bluespace_anchor"
|
||||
origin_tech = "bluespace=6;biotech=4"
|
||||
|
||||
/obj/item/organ/internal/cyberimp/chest/bluespace_anchor/insert(mob/living/carbon/M, special = FALSE)
|
||||
..()
|
||||
RegisterSignal(M, COMSIG_MOVABLE_TELEPORTING, PROC_REF(on_teleport))
|
||||
RegisterSignal(M, COMSIG_MOB_PRE_JAUNT, PROC_REF(on_jaunt))
|
||||
for(var/obj/item/bio_chip/tracking/T in M)
|
||||
if(T && T.implanted)
|
||||
qdel(T)
|
||||
|
||||
/obj/item/organ/internal/cyberimp/chest/bluespace_anchor/remove(mob/living/carbon/M, special = FALSE)
|
||||
UnregisterSignal(M, COMSIG_MOVABLE_TELEPORTING)
|
||||
UnregisterSignal(M, COMSIG_MOB_PRE_JAUNT)
|
||||
return ..()
|
||||
|
||||
/// Blocks teleports and stuns the would-be-teleportee.
|
||||
/obj/item/organ/internal/cyberimp/chest/bluespace_anchor/proc/on_teleport(mob/living/teleportee, atom/destination, channel)
|
||||
SIGNAL_HANDLER // COMSIG_MOVABLE_TELEPORTED
|
||||
|
||||
to_chat(teleportee, "<span class='userdanger'>You feel yourself teleporting, but are suddenly flung back to where you just were!</span>")
|
||||
|
||||
teleportee.Weaken(5 SECONDS)
|
||||
var/datum/effect_system/spark_spread/spark_system = new()
|
||||
spark_system.set_up(5, TRUE, teleportee)
|
||||
spark_system.start()
|
||||
return COMPONENT_BLOCK_TELEPORT
|
||||
|
||||
/// Prevents a user from entering a jaunt.
|
||||
/obj/item/organ/internal/cyberimp/chest/bluespace_anchor/proc/on_jaunt(mob/living/jaunter)
|
||||
SIGNAL_HANDLER // COMSIG_MOB_PRE_JAUNT
|
||||
|
||||
to_chat(jaunter, "<span class='userdanger'>As you attempt to jaunt, you slam directly into the barrier between realities and are sent crashing back into corporeality!</span>")
|
||||
|
||||
jaunter.Weaken(5 SECONDS)
|
||||
var/datum/effect_system/spark_spread/spark_system = new()
|
||||
spark_system.set_up(5, TRUE, jaunter)
|
||||
spark_system.start()
|
||||
return COMPONENT_BLOCK_JAUNT
|
||||
|
||||
/obj/item/organ/internal/cyberimp/chest/ipc_repair
|
||||
name = "Reactive Repair Implant"
|
||||
desc = "This implant reworks the IPC frame, in order to incorporate materials that return to their original shape after being damaged. Requires power to function."
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 42 KiB |
Reference in New Issue
Block a user