Merge branch 'master' of https://github.com/Citadel-Station-13/Citadel-Station-13 into ninjasarecum
# Conflicts: # code/modules/ninja/suit/suit.dm
This commit is contained in:
@@ -96,6 +96,7 @@ GLOBAL_LIST_EMPTY(antagonists)
|
||||
|
||||
//Proc called when the datum is given to a mind.
|
||||
/datum/antagonist/proc/on_gain()
|
||||
set waitfor = FALSE
|
||||
if(!(owner?.current))
|
||||
return
|
||||
if(!silent)
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
active_mind_control = TRUE
|
||||
message_admins("[key_name(user)] sent an abductor mind control message to [key_name(owner)]: [command]")
|
||||
update_gland_hud()
|
||||
var/obj/screen/alert/mind_control/mind_alert = owner.throw_alert("mind_control", /obj/screen/alert/mind_control)
|
||||
var/atom/movable/screen/alert/mind_control/mind_alert = owner.throw_alert("mind_control", /atom/movable/screen/alert/mind_control)
|
||||
mind_alert.command = command
|
||||
addtimer(CALLBACK(src, .proc/clear_mind_control), mind_control_duration)
|
||||
return TRUE
|
||||
|
||||
@@ -144,7 +144,7 @@
|
||||
owner.Stun(15)
|
||||
owner.adjustToxLoss(-15, TRUE, TRUE)
|
||||
|
||||
owner.blood_volume = min(BLOOD_VOLUME_NORMAL, owner.blood_volume + 20)
|
||||
owner.adjust_integration_blood(20)
|
||||
if(owner.blood_volume < BLOOD_VOLUME_NORMAL)
|
||||
keep_going = TRUE
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
|
||||
message_admins("[key_name(user)] broadcasted an abductor mind control message from [key_name(owner)] to [key_name(H)]: [command]")
|
||||
|
||||
var/obj/screen/alert/mind_control/mind_alert = H.throw_alert("mind_control", /obj/screen/alert/mind_control)
|
||||
var/atom/movable/screen/alert/mind_control/mind_alert = H.throw_alert("mind_control", /atom/movable/screen/alert/mind_control)
|
||||
mind_alert.command = command
|
||||
|
||||
if(LAZYLEN(broadcasted_mobs))
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
if(entangled_mob && ishuman(entangled_mob) && (entangled_mob.stat < DEAD))
|
||||
to_chat(entangled_mob, "<span class='userdanger'>You suddenly feel an irresistible compulsion to follow an order...</span>")
|
||||
to_chat(entangled_mob, "<span class='mind_control'>[command]</span>")
|
||||
var/obj/screen/alert/mind_control/mind_alert = entangled_mob.throw_alert("mind_control", /obj/screen/alert/mind_control)
|
||||
var/atom/movable/screen/alert/mind_control/mind_alert = entangled_mob.throw_alert("mind_control", /atom/movable/screen/alert/mind_control)
|
||||
mind_alert.command = command
|
||||
message_admins("[key_name(owner)] mirrored an abductor mind control message to [key_name(entangled_mob)]: [command]")
|
||||
update_gland_hud()
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
if(naut)
|
||||
naut.factory = null
|
||||
to_chat(naut, "<span class='userdanger'>Your factory was destroyed! You feel yourself dying!</span>")
|
||||
naut.throw_alert("nofactory", /obj/screen/alert/nofactory)
|
||||
naut.throw_alert("nofactory", /atom/movable/screen/alert/nofactory)
|
||||
spores = null
|
||||
return ..()
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
result++
|
||||
. -= result - 1
|
||||
|
||||
/obj/structure/blob/BlockSuperconductivity()
|
||||
/obj/structure/blob/BlockThermalConductivity()
|
||||
return atmosblock
|
||||
|
||||
/obj/structure/blob/CanPass(atom/movable/mover, turf/target)
|
||||
|
||||
@@ -89,6 +89,7 @@
|
||||
owner.current.adjustStaminaLoss(-1.5 + (actual_regen * -7) * mult, 0) // Humans lose stamina damage really quickly. Vamps should heal more.
|
||||
owner.current.adjustCloneLoss(-0.1 * (actual_regen * 2) * mult, 0)
|
||||
owner.current.adjustOrganLoss(ORGAN_SLOT_BRAIN, -1 * (actual_regen * 4) * mult)
|
||||
owner.current.integrating_blood = 0
|
||||
// No Bleeding
|
||||
/*if(ishuman(owner.current)) //NOTE Current bleeding is horrible, not to count the amount of blood ballistics delete.
|
||||
var/mob/living/carbon/human/H = owner.current
|
||||
|
||||
@@ -670,9 +670,9 @@
|
||||
#define ui_vamprank_display "WEST:6,CENTER-2:-5" // 2 tiles down
|
||||
|
||||
/datum/hud
|
||||
var/obj/screen/bloodsucker/blood_counter/blood_display
|
||||
var/obj/screen/bloodsucker/rank_counter/vamprank_display
|
||||
var/obj/screen/bloodsucker/sunlight_counter/sunlight_display
|
||||
var/atom/movable/screen/bloodsucker/blood_counter/blood_display
|
||||
var/atom/movable/screen/bloodsucker/rank_counter/vamprank_display
|
||||
var/atom/movable/screen/bloodsucker/sunlight_counter/sunlight_display
|
||||
|
||||
/datum/antagonist/bloodsucker/proc/add_hud()
|
||||
return
|
||||
@@ -708,36 +708,36 @@
|
||||
owner.current.hud_used.vamprank_display.icon_state = (bloodsucker_level_unspent > 0) ? "rank_up" : "rank"
|
||||
|
||||
|
||||
/obj/screen/bloodsucker
|
||||
/atom/movable/screen/bloodsucker
|
||||
invisibility = INVISIBILITY_ABSTRACT
|
||||
|
||||
/obj/screen/bloodsucker/proc/clear()
|
||||
/atom/movable/screen/bloodsucker/proc/clear()
|
||||
invisibility = INVISIBILITY_ABSTRACT
|
||||
|
||||
/obj/screen/bloodsucker/proc/update_counter(value, valuecolor)
|
||||
/atom/movable/screen/bloodsucker/proc/update_counter(value, valuecolor)
|
||||
invisibility = 0
|
||||
|
||||
/obj/screen/bloodsucker/blood_counter
|
||||
/atom/movable/screen/bloodsucker/blood_counter
|
||||
icon = 'icons/mob/actions/bloodsucker.dmi'
|
||||
name = "Blood Consumed"
|
||||
icon_state = "blood_display"
|
||||
screen_loc = ui_blood_display
|
||||
|
||||
/obj/screen/bloodsucker/blood_counter/update_counter(value, valuecolor)
|
||||
/atom/movable/screen/bloodsucker/blood_counter/update_counter(value, valuecolor)
|
||||
..()
|
||||
maptext = "<div align='center' valign='middle' style='position:relative; top:0px; left:6px'><font color='[valuecolor]'>[round(value,1)]</font></div>"
|
||||
|
||||
/obj/screen/bloodsucker/rank_counter
|
||||
/atom/movable/screen/bloodsucker/rank_counter
|
||||
name = "Bloodsucker Rank"
|
||||
icon = 'icons/mob/actions/bloodsucker.dmi'
|
||||
icon_state = "rank"
|
||||
screen_loc = ui_vamprank_display
|
||||
|
||||
/obj/screen/bloodsucker/rank_counter/update_counter(value, valuecolor)
|
||||
/atom/movable/screen/bloodsucker/rank_counter/update_counter(value, valuecolor)
|
||||
..()
|
||||
maptext = "<div align='center' valign='middle' style='position:relative; top:0px; left:6px'><font color='[valuecolor]'>[round(value,1)]</font></div>"
|
||||
|
||||
/obj/screen/bloodsucker/sunlight_counter
|
||||
/atom/movable/screen/bloodsucker/sunlight_counter
|
||||
icon = 'icons/mob/actions/bloodsucker.dmi'
|
||||
name = "Solar Flare Timer"
|
||||
icon_state = "sunlight_night"
|
||||
@@ -761,7 +761,7 @@
|
||||
owner.current.hud_used.sunlight_display.icon_state = "sunlight_" + (amDay ? "day":"night")
|
||||
|
||||
|
||||
/obj/screen/bloodsucker/sunlight_counter/update_counter(value, valuecolor)
|
||||
/atom/movable/screen/bloodsucker/sunlight_counter/update_counter(value, valuecolor)
|
||||
..()
|
||||
maptext = "<div align='center' valign='bottom' style='position:relative; top:0px; left:6px'><font color='[valuecolor]'>[value]</font></div>"
|
||||
|
||||
|
||||
@@ -109,13 +109,13 @@
|
||||
|
||||
|
||||
/datum/status_effect/agent_pinpointer/hunter_edition
|
||||
alert_type = /obj/screen/alert/status_effect/agent_pinpointer/hunter_edition
|
||||
alert_type = /atom/movable/screen/alert/status_effect/agent_pinpointer/hunter_edition
|
||||
minimum_range = HUNTER_SCAN_MIN_DISTANCE
|
||||
tick_interval = HUNTER_SCAN_PING_TIME
|
||||
duration = 160 // Lasts 10s
|
||||
range_fuzz_factor = 5//PINPOINTER_EXTRA_RANDOM_RANGE
|
||||
|
||||
/obj/screen/alert/status_effect/agent_pinpointer/hunter_edition
|
||||
/atom/movable/screen/alert/status_effect/agent_pinpointer/hunter_edition
|
||||
name = "Monster Tracking"
|
||||
desc = "You always know where the hellspawn are."
|
||||
|
||||
|
||||
@@ -110,13 +110,13 @@
|
||||
|
||||
/datum/status_effect/agent_pinpointer/vassal_edition
|
||||
id = "agent_pinpointer"
|
||||
alert_type = /obj/screen/alert/status_effect/agent_pinpointer/vassal_edition
|
||||
alert_type = /atom/movable/screen/alert/status_effect/agent_pinpointer/vassal_edition
|
||||
minimum_range = VASSAL_SCAN_MIN_DISTANCE
|
||||
tick_interval = VASSAL_SCAN_PING_TIME
|
||||
duration = -1 // runs out fast
|
||||
range_fuzz_factor = 0
|
||||
|
||||
/obj/screen/alert/status_effect/agent_pinpointer/vassal_edition
|
||||
/atom/movable/screen/alert/status_effect/agent_pinpointer/vassal_edition
|
||||
name = "Blood Bond"
|
||||
desc = "You always know where your master is."
|
||||
//icon = 'icons/obj/device.dmi'
|
||||
|
||||
@@ -297,8 +297,14 @@
|
||||
prof.socks = H.socks
|
||||
prof.socks_color = H.socks_color
|
||||
|
||||
var/list/slots = list("head", "wear_mask", "back", "wear_suit", "w_uniform", "shoes", "belt", "gloves", "glasses", "ears", "wear_id", "s_store")
|
||||
for(var/slot in slots)
|
||||
var/datum/icon_snapshot/entry = new
|
||||
entry.name = H.name
|
||||
entry.icon = H.icon
|
||||
entry.icon_state = H.icon_state
|
||||
entry.overlays = H.get_overlays_copy(list(HANDS_LAYER, HANDCUFF_LAYER, LEGCUFF_LAYER))
|
||||
prof.profile_snapshot = entry
|
||||
|
||||
for(var/slot in GLOB.slots)
|
||||
if(slot in H.vars)
|
||||
var/obj/item/I = H.vars[slot]
|
||||
if(!I)
|
||||
@@ -518,6 +524,9 @@
|
||||
var/socks
|
||||
var/socks_color
|
||||
|
||||
/// Icon snapshot of the profile
|
||||
var/datum/icon_snapshot/profile_snapshot
|
||||
|
||||
/datum/changelingprofile/Destroy()
|
||||
qdel(dna)
|
||||
. = ..()
|
||||
@@ -535,13 +544,14 @@
|
||||
newprofile.underwear = underwear
|
||||
newprofile.undershirt = undershirt
|
||||
newprofile.socks = socks
|
||||
|
||||
newprofile.profile_snapshot = profile_snapshot
|
||||
|
||||
/datum/antagonist/changeling/xenobio
|
||||
name = "Xenobio Changeling"
|
||||
give_objectives = FALSE
|
||||
show_in_roundend = FALSE //These are here for admin tracking purposes only
|
||||
you_are_greet = FALSE
|
||||
antag_moodlet = FALSE
|
||||
|
||||
/datum/antagonist/changeling/roundend_report()
|
||||
var/list/parts = list()
|
||||
|
||||
@@ -13,5 +13,5 @@
|
||||
|
||||
//Recover from stuns.
|
||||
/obj/effect/proc_holder/changeling/adrenaline/sting_action(mob/living/user)
|
||||
user.do_adrenaline(0, FALSE, 70, 0, TRUE, list(/datum/reagent/medicine/epinephrine = 3, /datum/reagent/drug/methamphetamine/changeling = 10, /datum/reagent/medicine/changelingadrenaline = 5), "<span class='notice'>Energy rushes through us.</span>", 0, 0.75, 0)
|
||||
user.do_adrenaline(0, FALSE, 70, 0, TRUE, list(/datum/reagent/medicine/epinephrine = 3, /datum/reagent/medicine/changelinghaste = 10, /datum/reagent/medicine/changelingadrenaline = 5), "<span class='notice'>Energy rushes through us.</span>", 0, 0.75, 0)
|
||||
return TRUE
|
||||
|
||||
@@ -10,15 +10,8 @@
|
||||
//Transform into a human.
|
||||
/obj/effect/proc_holder/changeling/humanform/sting_action(mob/living/carbon/user)
|
||||
var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
|
||||
var/list/names = list()
|
||||
for(var/datum/changelingprofile/prof in changeling.stored_profiles)
|
||||
names += "[prof.name]"
|
||||
|
||||
var/chosen_name = input("Select the target DNA: ", "Target DNA", null) as null|anything in names
|
||||
if(!chosen_name)
|
||||
return
|
||||
|
||||
var/datum/changelingprofile/chosen_prof = changeling.get_dna(chosen_name)
|
||||
var/datum/changelingprofile/chosen_prof = changeling.select_dna()
|
||||
if(!chosen_prof)
|
||||
return
|
||||
if(!user || user.mob_transforming)
|
||||
|
||||
@@ -466,7 +466,7 @@
|
||||
block_return[BLOCK_RETURN_BLOCK_CAPACITY] = (block_return[BLOCK_RETURN_BLOCK_CAPACITY] || 0) + remaining_uses
|
||||
return ..()
|
||||
|
||||
/obj/item/shield/changeling/active_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
|
||||
/obj/item/shield/changeling/directional_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
|
||||
. = ..()
|
||||
if(--remaining_uses < 1)
|
||||
if(ishuman(loc))
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
//Modified IA pinpointer - Points to the NEAREST changeling, but will only get you within a few tiles of the target.
|
||||
//You'll still have to rely on intuition and observation to make the identification. Lings can 'hide' in public places.
|
||||
/datum/status_effect/agent_pinpointer/changeling
|
||||
alert_type = /obj/screen/alert/status_effect/agent_pinpointer/changeling
|
||||
alert_type = /atom/movable/screen/alert/status_effect/agent_pinpointer/changeling
|
||||
minimum_range = CHANGELING_PHEROMONE_MIN_DISTANCE
|
||||
tick_interval = CHANGELING_PHEROMONE_PING_TIME
|
||||
range_fuzz_factor = 0
|
||||
@@ -55,6 +55,6 @@
|
||||
scan_target = null
|
||||
|
||||
|
||||
/obj/screen/alert/status_effect/agent_pinpointer/changeling
|
||||
/atom/movable/screen/alert/status_effect/agent_pinpointer/changeling
|
||||
name = "Pheromone Scent"
|
||||
desc = "The nose always knows."
|
||||
|
||||
@@ -78,7 +78,7 @@
|
||||
if(changeling.chosen_sting)
|
||||
unset_sting(user)
|
||||
return
|
||||
selected_dna = changeling.select_dna("Select the target DNA: ", "Target DNA")
|
||||
selected_dna = changeling.select_dna()
|
||||
if(!selected_dna)
|
||||
return
|
||||
if(NOTRANSSTING in selected_dna.dna.species.species_traits)
|
||||
|
||||
@@ -134,7 +134,7 @@
|
||||
//Change our DNA to that of somebody we've absorbed.
|
||||
/obj/effect/proc_holder/changeling/transform/sting_action(mob/living/carbon/human/user)
|
||||
var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
|
||||
var/datum/changelingprofile/chosen_prof = changeling.select_dna("Select the target DNA: ", "Target DNA")
|
||||
var/datum/changelingprofile/chosen_prof = changeling.select_dna()
|
||||
|
||||
if(!chosen_prof)
|
||||
return
|
||||
@@ -142,15 +142,21 @@
|
||||
changeling_transform(user, chosen_prof)
|
||||
return TRUE
|
||||
|
||||
/datum/antagonist/changeling/proc/select_dna(var/prompt, var/title)
|
||||
/**
|
||||
* Gives a changeling a list of all possible dnas in their profiles to choose from and returns profile containing their chosen dna
|
||||
*/
|
||||
/datum/antagonist/changeling/proc/select_dna()
|
||||
var/mob/living/carbon/user = owner.current
|
||||
if(!istype(user))
|
||||
return
|
||||
var/list/names = list("Drop Flesh Disguise")
|
||||
for(var/datum/changelingprofile/prof in stored_profiles)
|
||||
names += "[prof.name]"
|
||||
var/list/disguises = list("Drop Flesh Disguise" = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_drop"))
|
||||
for(var/datum/changelingprofile/current_profile in stored_profiles)
|
||||
var/datum/icon_snapshot/snap = current_profile.profile_snapshot
|
||||
var/image/disguise_image = image(icon = snap.icon, icon_state = snap.icon_state)
|
||||
disguise_image.overlays = snap.overlays
|
||||
disguises[current_profile.name] = disguise_image
|
||||
|
||||
var/chosen_name = input(prompt, title, null) as null|anything in names
|
||||
var/chosen_name = show_radial_menu(user, user, disguises, custom_check = CALLBACK(src, .proc/check_menu, user), radius = 40, require_near = TRUE, tooltips = TRUE)
|
||||
if(!chosen_name)
|
||||
return
|
||||
|
||||
@@ -158,6 +164,21 @@
|
||||
for(var/slot in GLOB.slots)
|
||||
if(istype(user.vars[slot], GLOB.slot2type[slot]))
|
||||
qdel(user.vars[slot])
|
||||
return
|
||||
|
||||
var/datum/changelingprofile/prof = get_dna(chosen_name)
|
||||
return prof
|
||||
|
||||
/**
|
||||
* Checks if we are allowed to interact with a radial menu
|
||||
*
|
||||
* Arguments:
|
||||
* * user The carbon mob interacting with the menu
|
||||
*/
|
||||
/datum/antagonist/changeling/proc/check_menu(mob/living/carbon/user)
|
||||
if(!istype(user))
|
||||
return FALSE
|
||||
var/datum/antagonist/changeling/changeling_datum = user.mind.has_antag_datum(/datum/antagonist/changeling)
|
||||
if(!changeling_datum)
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
@@ -69,7 +69,7 @@
|
||||
do_sparks(5, TRUE, AM)
|
||||
if(isliving(AM))
|
||||
var/mob/living/L = AM
|
||||
L.overlay_fullscreen("flash", /obj/screen/fullscreen/flash/static)
|
||||
L.overlay_fullscreen("flash", /atom/movable/screen/fullscreen/flash/static)
|
||||
L.clear_fullscreen("flash", 5)
|
||||
var/obj/item/transfer_valve/TTV = locate() in L.GetAllContents()
|
||||
if(TTV)
|
||||
|
||||
@@ -225,18 +225,22 @@
|
||||
return ..()
|
||||
|
||||
/obj/effect/clockwork/sigil/transmission/process()
|
||||
var/power_drained = 0
|
||||
var/power_mod = 0.005
|
||||
for(var/t in spiral_range_turfs(SIGIL_ACCESS_RANGE, src))
|
||||
var/turf/T = t
|
||||
for(var/M in T)
|
||||
var/atom/movable/A = M
|
||||
power_drained += A.power_drain(TRUE)
|
||||
do_process()
|
||||
|
||||
CHECK_TICK
|
||||
/obj/effect/clockwork/sigil/transmission/proc/do_process()
|
||||
set waitfor = FALSE
|
||||
var/power_drained = 0
|
||||
var/power_mod = 0.005
|
||||
for(var/t in spiral_range_turfs(SIGIL_ACCESS_RANGE, src))
|
||||
var/turf/T = t
|
||||
for(var/M in T)
|
||||
var/atom/movable/A = M
|
||||
power_drained += A.power_drain(TRUE)
|
||||
|
||||
adjust_clockwork_power(power_drained * power_mod * 15)
|
||||
new /obj/effect/temp_visual/ratvar/sigil/transmission(loc, 1 + (power_drained * 0.0035))
|
||||
CHECK_TICK
|
||||
|
||||
adjust_clockwork_power(power_drained * power_mod * 15)
|
||||
new /obj/effect/temp_visual/ratvar/sigil/transmission(loc, 1 + (power_drained * 0.0035))
|
||||
|
||||
/obj/effect/clockwork/sigil/transmission/proc/charge_cyborg(mob/living/silicon/robot/cyborg)
|
||||
if(!cyborg_checks(cyborg))
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
return
|
||||
return TRUE
|
||||
|
||||
/obj/effect/clockwork/servant_blocker/BlockSuperconductivity()
|
||||
/obj/effect/clockwork/servant_blocker/BlockThermalConductivity()
|
||||
return TRUE
|
||||
|
||||
/obj/effect/clockwork/servant_blocker/singularity_act()
|
||||
|
||||
@@ -90,7 +90,6 @@
|
||||
parry_time_perfect = 2
|
||||
parry_efficiency_perfect = 110 //Very low leeway for counterattacks...
|
||||
parry_efficiency_considered_successful = 0.8
|
||||
parry_efficiency_to_counterattack = 1
|
||||
parry_efficiency_to_counterattack = 110
|
||||
parry_cooldown = 15 //But also very low cooldown..
|
||||
parry_failed_stagger_duration = 2 SECONDS //And relatively small penalties for failing.
|
||||
parry_failed_clickcd_duration = 1 SECONDS
|
||||
|
||||
@@ -97,18 +97,18 @@
|
||||
id = "wraith_spectacles"
|
||||
duration = -1 //remains until eye damage done reaches 0 while the glasses are not worn
|
||||
tick_interval = 20
|
||||
alert_type = /obj/screen/alert/status_effect/wraith_spectacles
|
||||
alert_type = /atom/movable/screen/alert/status_effect/wraith_spectacles
|
||||
var/eye_damage_done = 0
|
||||
var/nearsight_breakpoint = 30
|
||||
var/blind_breakpoint = 45
|
||||
|
||||
/obj/screen/alert/status_effect/wraith_spectacles
|
||||
/atom/movable/screen/alert/status_effect/wraith_spectacles
|
||||
name = "Wraith Spectacles"
|
||||
desc = "You shouldn't actually see this, as it should be procedurally generated."
|
||||
icon_state = "wraithspecs"
|
||||
alerttooltipstyle = "clockcult"
|
||||
|
||||
/obj/screen/alert/status_effect/wraith_spectacles/MouseEntered(location,control,params)
|
||||
/atom/movable/screen/alert/status_effect/wraith_spectacles/MouseEntered(location,control,params)
|
||||
var/mob/living/carbon/human/L = usr
|
||||
if(istype(L)) //this is probably more safety than actually needed
|
||||
var/datum/status_effect/wraith_spectacles/W = attached_effect
|
||||
|
||||
+42
-32
@@ -141,7 +141,7 @@
|
||||
if(isliving(M.current) && M.current.stat != DEAD)
|
||||
var/turf/t_turf = isAI(M.current) ? get_step(get_step(src, NORTH),NORTH) : get_turf(src) // AI too fat, must make sure it always ends up a 2 tiles north instead of on the ark.
|
||||
do_teleport(M.current, t_turf, channel = TELEPORT_CHANNEL_CULT, forced = TRUE)
|
||||
M.current.overlay_fullscreen("flash", /obj/screen/fullscreen/flash)
|
||||
M.current.overlay_fullscreen("flash", /atom/movable/screen/fullscreen/flash)
|
||||
M.current.clear_fullscreen("flash", 5)
|
||||
playsound(src, 'sound/magic/clockwork/invoke_general.ogg', 50, FALSE)
|
||||
recalls_remaining--
|
||||
@@ -181,9 +181,15 @@
|
||||
make_glow()
|
||||
glow.icon_state = "clockwork_gateway_disrupted"
|
||||
resistance_flags |= INDESTRUCTIBLE
|
||||
sleep(27)
|
||||
explosion(src, 1, 3, 8, 8)
|
||||
sound_to_playing_players('sound/effects/explosion_distant.ogg', volume = 50)
|
||||
addtimer(CALLBACK(src, .proc/go_boom), 2.7 SECONDS)
|
||||
return
|
||||
qdel(src)
|
||||
|
||||
/obj/structure/destructible/clockwork/massive/celestial_gateway/proc/go_boom()
|
||||
if(QDELETED(src))
|
||||
return
|
||||
explosion(src, 1, 3, 8, 8)
|
||||
sound_to_playing_players('sound/effects/explosion_distant.ogg', volume = 50)
|
||||
qdel(src)
|
||||
|
||||
/obj/structure/destructible/clockwork/massive/celestial_gateway/proc/make_glow()
|
||||
@@ -240,6 +246,36 @@
|
||||
if(GATEWAY_RATVAR_COMING to INFINITY)
|
||||
. += "<span class='boldwarning'>The anomaly is stable! Something is coming through!</span>"
|
||||
|
||||
/obj/structure/destructible/clockwork/massive/celestial_gateway/proc/fulfill_purpose()
|
||||
set waitfor = FALSE
|
||||
countdown.stop()
|
||||
resistance_flags |= INDESTRUCTIBLE
|
||||
purpose_fulfilled = TRUE
|
||||
make_glow()
|
||||
animate(glow, transform = matrix() * 1.5, alpha = 255, time = 125)
|
||||
sound_to_playing_players(volume = 100, channel = CHANNEL_JUSTICAR_ARK, S = sound('sound/effects/ratvar_rises.ogg')) //End the sounds
|
||||
sleep(125)
|
||||
make_glow()
|
||||
animate(glow, transform = matrix() * 3, alpha = 0, time = 5)
|
||||
QDEL_IN(src, 3)
|
||||
sleep(3)
|
||||
GLOB.clockwork_gateway_activated = TRUE
|
||||
var/turf/T = SSmapping.get_station_center()
|
||||
new /obj/structure/destructible/clockwork/massive/ratvar(T)
|
||||
var/x0 = T.x
|
||||
var/y0 = T.y
|
||||
for(var/I in spiral_range_turfs(255, T, tick_checked = TRUE))
|
||||
var/turf/T2 = I
|
||||
if(!T2)
|
||||
continue
|
||||
var/dist = cheap_hypotenuse(T2.x, T2.y, x0, y0)
|
||||
if(dist < 100)
|
||||
dist = TRUE
|
||||
else
|
||||
dist = FALSE
|
||||
T.ratvar_act(dist)
|
||||
CHECK_TICK
|
||||
|
||||
/obj/structure/destructible/clockwork/massive/celestial_gateway/process()
|
||||
adjust_clockwork_power(2.5) //Provides weak power generation on its own
|
||||
if(seconds_until_activation)
|
||||
@@ -275,7 +311,7 @@
|
||||
var/turf/T = get_turf(M)
|
||||
if(is_servant_of_ratvar(M) && (!T || T.z != z))
|
||||
M.forceMove(get_step(src, SOUTH))
|
||||
M.overlay_fullscreen("flash", /obj/screen/fullscreen/flash)
|
||||
M.overlay_fullscreen("flash", /atom/movable/screen/fullscreen/flash)
|
||||
M.clear_fullscreen("flash", 5)
|
||||
progress_in_seconds += GATEWAY_SUMMON_RATE
|
||||
switch(progress_in_seconds)
|
||||
@@ -300,33 +336,7 @@
|
||||
glow.icon_state = "clockwork_gateway_closing"
|
||||
if(GATEWAY_RATVAR_ARRIVAL to INFINITY)
|
||||
if(!purpose_fulfilled)
|
||||
countdown.stop()
|
||||
resistance_flags |= INDESTRUCTIBLE
|
||||
purpose_fulfilled = TRUE
|
||||
make_glow()
|
||||
animate(glow, transform = matrix() * 1.5, alpha = 255, time = 125)
|
||||
sound_to_playing_players(volume = 100, channel = CHANNEL_JUSTICAR_ARK, S = sound('sound/effects/ratvar_rises.ogg')) //End the sounds
|
||||
sleep(125)
|
||||
make_glow()
|
||||
animate(glow, transform = matrix() * 3, alpha = 0, time = 5)
|
||||
QDEL_IN(src, 3)
|
||||
sleep(3)
|
||||
GLOB.clockwork_gateway_activated = TRUE
|
||||
var/turf/T = SSmapping.get_station_center()
|
||||
new /obj/structure/destructible/clockwork/massive/ratvar(T)
|
||||
var/x0 = T.x
|
||||
var/y0 = T.y
|
||||
for(var/I in spiral_range_turfs(255, T, tick_checked = TRUE))
|
||||
var/turf/T2 = I
|
||||
if(!T2)
|
||||
continue
|
||||
var/dist = cheap_hypotenuse(T2.x, T2.y, x0, y0)
|
||||
if(dist < 100)
|
||||
dist = TRUE
|
||||
else
|
||||
dist = FALSE
|
||||
T.ratvar_act(dist)
|
||||
CHECK_TICK
|
||||
fulfill_purpose()
|
||||
|
||||
//Converts nearby turfs into their clockwork equivalent, with ever-increasing range the closer the ark is to summoning Ratvar
|
||||
/obj/structure/destructible/clockwork/massive/celestial_gateway/proc/conversion_pulse()
|
||||
|
||||
@@ -60,12 +60,8 @@
|
||||
delay_remaining += PRISM_DELAY_DURATION
|
||||
toggle(0, user)
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/prolonging_prism/process()
|
||||
var/turf/own_turf = get_turf(src)
|
||||
if(SSshuttle.emergency.mode != SHUTTLE_CALL || delay_remaining <= 0 || !own_turf || !is_station_level(own_turf.z))
|
||||
forced_disable(FALSE)
|
||||
return
|
||||
. = ..()
|
||||
/obj/structure/destructible/clockwork/powered/prolonging_prism/proc/do_process()
|
||||
set waitfor = FALSE
|
||||
var/delay_amount = 40
|
||||
delay_remaining -= delay_amount
|
||||
var/efficiency = get_efficiency_mod()
|
||||
@@ -114,6 +110,14 @@
|
||||
new /obj/effect/temp_visual/ratvar/prolonging_prism(T)
|
||||
CHECK_TICK //we may be going over a hell of a lot of turfs
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/prolonging_prism/process()
|
||||
var/turf/own_turf = get_turf(src)
|
||||
if(SSshuttle.emergency.mode != SHUTTLE_CALL || delay_remaining <= 0 || !own_turf || !is_station_level(own_turf.z))
|
||||
forced_disable(FALSE)
|
||||
return
|
||||
. = ..()
|
||||
do_process()
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/prolonging_prism/proc/get_delay_cost()
|
||||
return FLOOR(delay_cost, MIN_CLOCKCULT_POWER)
|
||||
|
||||
|
||||
@@ -110,6 +110,7 @@
|
||||
|
||||
//Put me in Reebe, will you? Ratvar has found and is going to do a hecking murder on Nar'Sie
|
||||
/obj/structure/destructible/clockwork/massive/ratvar/proc/clash_of_the_titans(obj/singularity/narsie/narsie)
|
||||
set waitfor = FALSE
|
||||
var/winner = "Undeclared"
|
||||
var/base_victory_chance = 1
|
||||
while(src && narsie)
|
||||
|
||||
@@ -136,7 +136,7 @@
|
||||
hierophant_network.span_for_name = "nezbere"
|
||||
hierophant_network.span_for_message = "brass"
|
||||
hierophant_network.Grant(current)
|
||||
current.throw_alert("clockinfo", /obj/screen/alert/clockwork/infodump)
|
||||
current.throw_alert("clockinfo", /atom/movable/screen/alert/clockwork/infodump)
|
||||
var/obj/structure/destructible/clockwork/massive/celestial_gateway/G = GLOB.ark_of_the_clockwork_justiciar
|
||||
if(G && G.active && ishuman(current))
|
||||
current.add_overlay(mutable_appearance('icons/effects/genetics.dmi', "servitude", -ANTAG_LAYER))
|
||||
|
||||
@@ -687,10 +687,10 @@
|
||||
if(H.stat == DEAD)
|
||||
to_chat(user,"<span class='warning'>Only a revive rune can bring back the dead!</span>")
|
||||
return
|
||||
if(H.blood_volume < (BLOOD_VOLUME_SAFE*H.blood_ratio))
|
||||
if(H.functional_blood() < (BLOOD_VOLUME_SAFE*H.blood_ratio))
|
||||
var/restore_blood = (BLOOD_VOLUME_SAFE*H.blood_ratio) - H.blood_volume
|
||||
if(uses*2 < restore_blood)
|
||||
H.blood_volume += uses*2
|
||||
if(uses * 2 < restore_blood)
|
||||
H.adjust_integration_blood(uses * 2)
|
||||
to_chat(user,"<span class='danger'>You use the last of your blood rites to restore what blood you could!</span>")
|
||||
uses = 0
|
||||
return ..()
|
||||
|
||||
@@ -124,7 +124,7 @@
|
||||
communion.Grant(current)
|
||||
if(ishuman(current))
|
||||
magic.Grant(current)
|
||||
current.throw_alert("bloodsense", /obj/screen/alert/bloodsense)
|
||||
current.throw_alert("bloodsense", /atom/movable/screen/alert/bloodsense)
|
||||
if(cult_team?.cult_risen)
|
||||
cult_team.rise(current)
|
||||
if(cult_team.cult_ascendent)
|
||||
|
||||
@@ -204,26 +204,31 @@
|
||||
STOP_PROCESSING(SSfastprocess, src)
|
||||
return ..()
|
||||
|
||||
/obj/structure/destructible/cult/pylon/proc/heal_friends()
|
||||
set waitfor = FALSE
|
||||
for(var/mob/living/L in range(5, src))
|
||||
if(iscultist(L) || isshade(L) || isconstruct(L))
|
||||
if(L.health != L.maxHealth)
|
||||
new /obj/effect/temp_visual/heal(get_turf(src), "#960000")
|
||||
if(ishuman(L))
|
||||
L.adjustBruteLoss(-1, 0, only_organic = FALSE)
|
||||
L.adjustFireLoss(-1, 0, only_organic = FALSE)
|
||||
L.updatehealth()
|
||||
if(isshade(L) || isconstruct(L))
|
||||
var/mob/living/simple_animal/M = L
|
||||
if(M.health < M.maxHealth)
|
||||
M.adjustHealth(-3)
|
||||
if(ishuman(L) && L.blood_volume < (BLOOD_VOLUME_NORMAL * L.blood_ratio))
|
||||
L.adjust_integration_blood(1.0)
|
||||
CHECK_TICK
|
||||
|
||||
|
||||
/obj/structure/destructible/cult/pylon/process()
|
||||
if(!anchored)
|
||||
return
|
||||
if(last_heal <= world.time)
|
||||
last_heal = world.time + heal_delay
|
||||
for(var/mob/living/L in range(5, src))
|
||||
if(iscultist(L) || isshade(L) || isconstruct(L))
|
||||
if(L.health != L.maxHealth)
|
||||
new /obj/effect/temp_visual/heal(get_turf(src), "#960000")
|
||||
if(ishuman(L))
|
||||
L.adjustBruteLoss(-1, 0, only_organic = FALSE)
|
||||
L.adjustFireLoss(-1, 0, only_organic = FALSE)
|
||||
L.updatehealth()
|
||||
if(isshade(L) || isconstruct(L))
|
||||
var/mob/living/simple_animal/M = L
|
||||
if(M.health < M.maxHealth)
|
||||
M.adjustHealth(-3)
|
||||
if(ishuman(L) && L.blood_volume < (BLOOD_VOLUME_NORMAL * L.blood_ratio))
|
||||
L.blood_volume += 1.0
|
||||
CHECK_TICK
|
||||
heal_friends()
|
||||
if(last_corrupt <= world.time)
|
||||
var/list/validturfs = list()
|
||||
var/list/cultturfs = list()
|
||||
|
||||
@@ -647,7 +647,7 @@ structure_check() searches for nearby cultist structures required for the invoca
|
||||
GLOB.wall_runes -= src
|
||||
return ..()
|
||||
|
||||
/obj/effect/rune/wall/BlockSuperconductivity()
|
||||
/obj/effect/rune/wall/BlockThermalConductivity()
|
||||
return density
|
||||
|
||||
/obj/effect/rune/wall/invoke(var/list/invokers)
|
||||
|
||||
@@ -515,7 +515,6 @@ GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master",
|
||||
var/mob/living/silicon/robot_devil = owner.current
|
||||
var/laws = list("You may not use violence to coerce someone into selling their soul.", "You may not directly and knowingly physically harm a devil, other than yourself.", GLOB.lawlorify[LAW][ban], GLOB.lawlorify[LAW][obligation], "Accomplish your objectives at all costs.")
|
||||
robot_devil.set_law_sixsixsix(laws)
|
||||
sleep(10)
|
||||
if(owner.assigned_role == "Clown" && ishuman(owner.current))
|
||||
var/mob/living/carbon/human/S = owner.current
|
||||
to_chat(S, "<span class='notice'>Your infernal nature has allowed you to overcome your clownishness.</span>")
|
||||
|
||||
@@ -104,7 +104,7 @@
|
||||
/mob/living/carbon/true_devil/assess_threat(judgement_criteria, lasercolor = "", datum/callback/weaponcheck=null)
|
||||
return 666
|
||||
|
||||
/mob/living/carbon/true_devil/flash_act(intensity = 1, override_blindness_check = 0, affect_silicon = 0, visual = 0, type = /obj/screen/fullscreen/flash, override_protection = 0)
|
||||
/mob/living/carbon/true_devil/flash_act(intensity = 1, override_blindness_check = 0, affect_silicon = 0, visual = 0, type = /atom/movable/screen/fullscreen/flash, override_protection = 0)
|
||||
if(mind && has_bane(BANE_LIGHT))
|
||||
mind.disrupt_spells(-500)
|
||||
return ..() //flashes don't stop devils UNLESS it's their bane.
|
||||
|
||||
@@ -147,7 +147,7 @@
|
||||
|
||||
carbon_target.blood_volume -= 20
|
||||
if(carbon_user.blood_volume < BLOOD_VOLUME_MAXIMUM) //we dont want to explode after all
|
||||
carbon_user.blood_volume += 20
|
||||
carbon_user.adjust_integration_blood(20)
|
||||
return
|
||||
|
||||
/obj/effect/proc_holder/spell/pointed/blood_siphon/can_target(atom/target, mob/user, silent)
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
var/atom/movable/form = null
|
||||
var/morph_time = 0
|
||||
var/static/list/blacklist_typecache = typecacheof(list(
|
||||
/obj/screen,
|
||||
/atom/movable/screen,
|
||||
/obj/singularity,
|
||||
/mob/living/simple_animal/hostile/morph,
|
||||
/obj/effect,
|
||||
|
||||
@@ -42,12 +42,12 @@
|
||||
id = "agent_pinpointer"
|
||||
duration = -1
|
||||
tick_interval = PINPOINTER_PING_TIME
|
||||
alert_type = /obj/screen/alert/status_effect/agent_pinpointer
|
||||
alert_type = /atom/movable/screen/alert/status_effect/agent_pinpointer
|
||||
var/minimum_range = PINPOINTER_MINIMUM_RANGE
|
||||
var/range_fuzz_factor = PINPOINTER_EXTRA_RANDOM_RANGE
|
||||
var/mob/scan_target = null
|
||||
|
||||
/obj/screen/alert/status_effect/agent_pinpointer
|
||||
/atom/movable/screen/alert/status_effect/agent_pinpointer
|
||||
name = "Internal Affairs Integrated Pinpointer"
|
||||
desc = "Even stealthier than a normal implant."
|
||||
icon = 'icons/obj/device.dmi'
|
||||
|
||||
@@ -401,6 +401,7 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list(
|
||||
next_announce += DOOMSDAY_ANNOUNCE_INTERVAL
|
||||
|
||||
/obj/machinery/doomsday_device/proc/detonate()
|
||||
set waitfor = FALSE
|
||||
sound_to_playing_players('sound/machines/alarm.ogg')
|
||||
sleep(100)
|
||||
for(var/i in GLOB.mob_living_list)
|
||||
|
||||
@@ -224,7 +224,7 @@
|
||||
if(target.type == /mob/living/simple_animal/hostile/construct/shade) //Make sure we remember which body belonged to the shade
|
||||
var/mob/living/simple_animal/hostile/construct/shade/shade = target
|
||||
newstruct.original_mind = shade.original_mind
|
||||
var/obj/screen/alert/bloodsense/BS
|
||||
var/atom/movable/screen/alert/bloodsense/BS
|
||||
if(newstruct.mind && ((stoner && iscultist(stoner)) || cultoverride) && SSticker?.mode)
|
||||
SSticker.mode.add_cultist(newstruct.mind, 0)
|
||||
if(iscultist(stoner) || cultoverride)
|
||||
@@ -232,7 +232,7 @@
|
||||
else if(stoner)
|
||||
to_chat(newstruct, "<b>You are still bound to serve your creator, [stoner], follow [stoner.p_their()] orders and help [stoner.p_them()] complete [stoner.p_their()] goals at all costs.</b>")
|
||||
newstruct.clear_alert("bloodsense")
|
||||
BS = newstruct.throw_alert("bloodsense", /obj/screen/alert/bloodsense)
|
||||
BS = newstruct.throw_alert("bloodsense", /atom/movable/screen/alert/bloodsense)
|
||||
if(BS)
|
||||
BS.Cviewer = newstruct
|
||||
newstruct.cancel_camera()
|
||||
|
||||
Reference in New Issue
Block a user