Merge branch 'master' into upstream-merge-26386

This commit is contained in:
LetterJay
2017-05-01 15:27:25 -05:00
committed by GitHub
267 changed files with 15247 additions and 8768 deletions
+1
View File
@@ -42,6 +42,7 @@
var/has_gravity = 0
var/noteleport = 0 //Are you forbidden from teleporting to the area? (centcomm, mobs, wizard, hand teleporter)
var/hidden = FALSE //Hides area from player Teleport function.
var/safe = 0 //Is the area teleport-safe: no space / radiation / aggresive mobs / other dangers
var/no_air = null
+4 -4
View File
@@ -3,6 +3,7 @@
icon_state = "Holodeck"
dynamic_lighting = DYNAMIC_LIGHTING_DISABLED
flags = 0
hidden = TRUE
var/obj/machinery/computer/holodeck/linked
var/restricted = 0 // if true, program goes on emag list
@@ -95,16 +96,15 @@
/area/holodeck/rec_center/kobayashi
name = "Holodeck - Kobayashi Maru"
/area/holodeck/rec_center/winterwonderland
name = "Holodeck - Winter Wonderland"
// Bad programs
/area/holodeck/rec_center/burn
name = "Holodeck - Atmospheric Burn Test"
restricted = 1
/area/holodeck/rec_center/winterwonderland
name = "Holodeck - Winter Wonderland"
restricted = 1
/area/holodeck/rec_center/wildlife
name = "Holodeck - Wildlife Simulation"
restricted = 1
+1
View File
@@ -4,6 +4,7 @@
name = "\improper Unexplored Location"
icon_state = "away"
has_gravity = 1
hidden = TRUE
/area/ruin/unpowered
+20 -10
View File
@@ -39,20 +39,21 @@
var/do_initialize = SSatoms.initialized
if(do_initialize > INITIALIZATION_INSSATOMS)
if(QDELETED(src))
CRASH("Found new qdeletion in type [type]!")
var/mapload = do_initialize == INITIALIZATION_INNEW_MAPLOAD
args[1] = mapload
if(Initialize(arglist(args)) && mapload)
LAZYADD(SSatoms.late_loaders, src)
args[1] = do_initialize == INITIALIZATION_INNEW_MAPLOAD
if(SSatoms.InitAtom(src, args))
//we were deleted
return
var/list/created = SSatoms.created_atoms
if(created)
created += src
//Called after New if the map is being loaded. mapload = TRUE
//Called from base of New if the map is being loaded. mapload = FALSE
//This base must be called or derivatives must set initialized to TRUE to prevent repeat calls
//Derivatives must not sleep
//Returning TRUE while mapload is TRUE will cause the object to be initialized again with mapload = FALSE when everything else is done
//(Useful for things that requires turfs to have air). This base may only be called once, however
//This base must be called or derivatives must set initialized to TRUE
//must not sleep
//Other parameters are passed from New (excluding loc), this does not happen if mapload is TRUE
//Must return an Initialize hint. Defined in __DEFINES/subsystems.dm
//Note: the following functions don't call the base for optimization and must copypasta:
// /turf/Initialize
@@ -75,7 +76,16 @@
if (opacity && isturf(loc))
var/turf/T = loc
T.has_opaque_atom = TRUE // No need to recalculate it in this case, it's guaranteed to be on afterwards anyways.
return INITIALIZE_HINT_NORMAL
//called if Initialize returns INITIALIZE_HINT_LATELOAD
//This version shouldn't be called
/atom/proc/LateInitialize()
var/static/list/warned_types = list()
if(!warned_types[type])
WARNING("Old style LateInitialize behaviour detected in [type]!")
warned_types[type] = TRUE
Initialize(FALSE)
/atom/Destroy()
if(alternate_appearances)
+4 -4
View File
@@ -45,7 +45,7 @@
return ..()
/atom/movable/Initialize(mapload)
..()
. = ..()
for(var/L in initial_languages)
grant_language(L)
@@ -120,7 +120,7 @@
if(flags & CLEAN_ON_MOVE)
clean_on_move()
var/datum/proximity_monitor/proximity_monitor = src.proximity_monitor
if(proximity_monitor)
proximity_monitor.HandleMove()
@@ -562,7 +562,7 @@
return
else
var/turf/currentturf = get_turf(src)
get(src, /mob) << "<span class='danger'>You can't help but feel that you just lost something back there...</span>"
to_chat(get(src, /mob), "<span class='danger'>You can't help but feel that you just lost something back there...</span>")
var/turf/targetturf = relocate()
log_game("[src] has been moved out of bounds in [COORD(currentturf)]. Moving it to [COORD(targetturf)].")
if(HAS_SECONDARY_FLAG(src, INFORM_ADMINS_ON_RELOCATE))
@@ -627,4 +627,4 @@
/atom/movable/proc/ConveyorMove(movedir)
set waitfor = FALSE
if(!anchored && has_gravity())
step(src, movedir)
step(src, movedir)
+11 -7
View File
@@ -46,7 +46,7 @@ Credit where due:
///////////
/proc/is_servant_of_ratvar(mob/living/M)
return istype(M) && M.has_antag_datum(/datum/antagonist/clockcultist, TRUE)
return istype(M) && M.mind && M.mind.has_antag_datum(ANTAG_DATUM_CLOCKCULT)
/proc/is_eligible_servant(mob/living/M)
if(!istype(M))
@@ -65,17 +65,21 @@ Credit where due:
return FALSE
/proc/add_servant_of_ratvar(mob/living/L, silent = FALSE)
var/update_type = /datum/antagonist/clockcultist
if(!L || !L.mind)
return
var/update_type = ANTAG_DATUM_CLOCKCULT
if(silent)
update_type = /datum/antagonist/clockcultist/silent
. = L.gain_antag_datum(update_type)
update_type = ANTAG_DATUM_CLOCKCULT_SILENT
. = L.mind.add_antag_datum(update_type)
/proc/remove_servant_of_ratvar(mob/living/L, silent = FALSE)
var/datum/antagonist/clockcultist/clock_datum = L.has_antag_datum(/datum/antagonist/clockcultist, TRUE)
if(!L || !L.mind)
return
var/datum/antagonist/clockcult/clock_datum = L.mind.has_antag_datum(/datum/antagonist/clockcult)
if(!clock_datum)
return FALSE
clock_datum.silent_update = silent
clock_datum.on_remove()
clock_datum.silent = silent
clock_datum.on_removal()
return TRUE
///////////////
@@ -106,6 +106,6 @@ List of nuances:
if(!whisper)
L.say(message, "clock", spans, language=/datum/language/common)
else
L.whisper(message)
L.whisper(message, "clock", spans, language=/datum/language/common)
else
AM.say(message, language=/datum/language/common)
@@ -61,7 +61,7 @@
/obj/item/clockwork/slab/cyborg/medical //five scriptures, plus a spear
quickbound = list(/datum/clockwork_scripture/ranged_ability/linked_vanguard, /datum/clockwork_scripture/ranged_ability/sentinels_compromise, \
/datum/clockwork_scripture/create_object/vitality_matrix, /datum/clockwork_scripture/fellowship_armory, /datum/clockwork_scripture/create_object/mending_motor)
/datum/clockwork_scripture/create_object/vitality_matrix, /datum/clockwork_scripture/channeled/mending_mantra, /datum/clockwork_scripture/fellowship_armory)
/obj/item/clockwork/slab/cyborg/security //four scriptures, plus a spear
quickbound = list(/datum/clockwork_scripture/channeled/belligerent, /datum/clockwork_scripture/ranged_ability/judicial_marker, /datum/clockwork_scripture/channeled/taunting_tirade, \
@@ -214,28 +214,6 @@
quickbind_desc = "Creates an Interdiction Lens, which drains power into nearby Sigils of Transmission."
//Mending Motor: Creates a prism that will quickly heal mechanical servants/clockwork structures at a power cost
/datum/clockwork_scripture/create_object/mending_motor
descname = "Powered Structure, Repairs Other Structures"
name = "Mending Motor"
desc = "Creates a mechanized prism that will rapidly repair damaged clockwork constructs, converted cyborgs, and clockwork structures."
invocations = list("May this prism...", "...mend our dents and scratches!")
channel_time = 80
consumed_components = list(VANGUARD_COGWHEEL = 3, GEIS_CAPACITOR = 1, REPLICANT_ALLOY = 1)
object_path = /obj/structure/destructible/clockwork/powered/mending_motor
creator_message = "<span class='brass'>You form a mending motor, which will rapidly repair damaged clockwork constructs, converted cyborgs, and clockwork structures.</span>"
observer_message = "<span class='warning'>An onyx prism forms in midair and sprouts tendrils to support itself!</span>"
invokers_required = 2
multiple_invokers_used = TRUE
usage_tip = "Powerful healing but power use is somewhat inefficient, though much better than a proselytizer."
tier = SCRIPTURE_APPLICATION
one_per_tile = TRUE
primary_component = VANGUARD_COGWHEEL
sort_priority = 7
quickbind = TRUE
quickbind_desc = "Creates a Mending Motor, which rapidly repairs constructs and structures at a power cost."
//Mania Motor: Creates a malevolent transmitter that will broadcast the whispers of Sevtug into the minds of nearby nonservants, causing a variety of mental effects at a power cost.
/datum/clockwork_scripture/create_object/mania_motor
descname = "Powered Structure, Area Denial"
@@ -110,7 +110,7 @@
channel_time = 150
consumed_components = list(BELLIGERENT_EYE = 3, VANGUARD_COGWHEEL = 3, GEIS_CAPACITOR = 3, REPLICANT_ALLOY = 6)
usage_tip = "Ocular wardens will become empowered, clockwork proselytizers will require no alloy, tinkerer's daemons will produce twice as quickly, \
and interdiction lenses, mending motors, mania motors, tinkerer's daemons, and clockwork obelisks will all require no power."
and interdiction lenses, mania motors, tinkerer's daemons, and clockwork obelisks will all require no power."
tier = SCRIPTURE_REVENANT
primary_component = REPLICANT_ALLOY
sort_priority = 4
@@ -69,6 +69,117 @@
quickbind_desc = "Creates a Vitality Matrix, which drains non-Servants on it to heal Servants that cross it."
//Mending Mantra: Channeled for up to ten times over twenty seconds to repair structures and heal allies
/datum/clockwork_scripture/channeled/mending_mantra
descname = "Channeled, Area Healing and Repair"
name = "Mending Mantra"
desc = "Repairs nearby structures and constructs. Servants wearing clockwork armor will also be healed. Channeled every two seconds for a maximum of twenty seconds."
chant_invocations = list("Mend our dents!", "Heal our scratches!", "Repair our gears!")
chant_amount = 10
chant_interval = 20
consumed_components = list(VANGUARD_COGWHEEL = 1, REPLICANT_ALLOY = 1)
usage_tip = "This is a very effective way to rapidly reinforce a base after an attack."
tier = SCRIPTURE_SCRIPT
primary_component = VANGUARD_COGWHEEL
sort_priority = 4
quickbind = TRUE
quickbind_desc = "Repairs nearby structures and constructs. Servants wearing clockwork armor will also be healed.<br><b>Maximum 10 chants.</b>"
var/heal_attempts = 4
var/heal_amount = 2.5
var/static/list/damage_heal_order = list(BRUTE, BURN, OXY)
var/static/list/heal_finish_messages = list("There, all mended!", "Try not to get too damaged.", "No more dents and scratches for you!", "Champions never die.", "All patched up.", \
"Ah, child, it's okay now.", "Pain is temporary.", "What you do for the Justiciar is eternal.", "Bear this for me.", "Be strong, child.", "Please, be careful!", \
"If you die, you will be remembered.")
var/static/list/heal_target_typecache = typecacheof(list(
/obj/structure/destructible/clockwork,
/obj/machinery/door/airlock/clockwork,
/obj/machinery/door/window/clockwork,
/obj/structure/window/reinforced/clockwork,
/obj/structure/table/reinforced/brass))
var/static/list/ratvarian_armor_typecache = typecacheof(list(
/obj/item/clothing/suit/armor/clockwork,
/obj/item/clothing/head/helmet/clockwork,
/obj/item/clothing/gloves/clockwork,
/obj/item/clothing/shoes/clockwork))
/datum/clockwork_scripture/channeled/mending_mantra/chant_effects(chant_number)
var/turf/T
for(var/atom/movable/M in range(7, invoker))
if(isliving(M))
if(isclockmob(M) || istype(M, /mob/living/simple_animal/drone/cogscarab))
var/mob/living/simple_animal/S = M
if(S.health == S.maxHealth || S.stat == DEAD)
continue
T = get_turf(M)
for(var/i in 1 to heal_attempts)
if(S.health < S.maxHealth)
S.adjustHealth(-heal_amount)
new /obj/effect/overlay/temp/heal(T, "#1E8CE1")
if(i == heal_attempts && S.health >= S.maxHealth) //we finished healing on the last tick, give them the message
to_chat(S, "<span class='inathneq'>\"[text2ratvar(pick(heal_finish_messages))]\"</span>")
break
else
to_chat(S, "<span class='inathneq'>\"[text2ratvar(pick(heal_finish_messages))]\"</span>")
break
else if(issilicon(M))
var/mob/living/silicon/S = M
if(S.health == S.maxHealth || S.stat == DEAD || !is_servant_of_ratvar(S))
continue
T = get_turf(M)
for(var/i in 1 to heal_attempts)
if(S.health < S.maxHealth)
S.heal_ordered_damage(heal_amount, damage_heal_order)
new /obj/effect/overlay/temp/heal(T, "#1E8CE1")
if(i == heal_attempts && S.health >= S.maxHealth)
to_chat(S, "<span class='inathneq'>\"[text2ratvar(pick(heal_finish_messages))]\"</span>")
break
else
to_chat(S, "<span class='inathneq'>\"[text2ratvar(pick(heal_finish_messages))]\"</span>")
break
else if(ishuman(M))
var/mob/living/carbon/human/H = M
if(H.health == H.maxHealth || H.stat == DEAD || !is_servant_of_ratvar(H))
continue
T = get_turf(M)
var/heal_ticks = 0 //one heal tick for each piece of ratvarian armor worn
var/obj/item/I = H.get_item_by_slot(slot_wear_suit)
if(is_type_in_typecache(I, ratvarian_armor_typecache))
heal_ticks++
I = H.get_item_by_slot(slot_head)
if(is_type_in_typecache(I, ratvarian_armor_typecache))
heal_ticks++
I = H.get_item_by_slot(slot_gloves)
if(is_type_in_typecache(I, ratvarian_armor_typecache))
heal_ticks++
I = H.get_item_by_slot(slot_shoes)
if(is_type_in_typecache(I, ratvarian_armor_typecache))
heal_ticks++
if(heal_ticks)
for(var/i in 1 to heal_ticks)
if(H.health < H.maxHealth)
H.heal_ordered_damage(heal_amount, damage_heal_order)
new /obj/effect/overlay/temp/heal(T, "#1E8CE1")
if(i == heal_ticks && H.health >= H.maxHealth)
to_chat(H, "<span class='inathneq'>\"[text2ratvar(pick(heal_finish_messages))]\"</span>")
break
else
to_chat(H, "<span class='inathneq'>\"[text2ratvar(pick(heal_finish_messages))]\"</span>")
break
else if(is_type_in_typecache(M, heal_target_typecache))
var/obj/structure/destructible/clockwork/C = M
if(C.obj_integrity == C.max_integrity || (istype(C) && !C.can_be_repaired))
continue
T = get_turf(M)
for(var/i in 1 to heal_attempts)
if(C.obj_integrity < C.max_integrity)
C.obj_integrity = min(C.obj_integrity + 5, C.max_integrity)
C.update_icon()
new /obj/effect/overlay/temp/heal(T, "#1E8CE1")
else
break
return TRUE
//Sigil of Submission: Creates a sigil of submission, which converts one heretic above it after a delay.
/datum/clockwork_scripture/create_object/sigil_of_submission
descname = "Trap, Conversion"
@@ -1,107 +0,0 @@
//Mending Motor: A prism that consumes replicant alloy or power to repair nearby mechanical servants at a quick rate.
/obj/structure/destructible/clockwork/powered/mending_motor
name = "mending motor"
desc = "A dark onyx prism, held in midair by spiraling tendrils of stone."
clockwork_desc = "A powerful prism that rapidly repairs nearby mechanical servants and clockwork structures."
icon_state = "mending_motor_inactive"
active_icon = "mending_motor"
inactive_icon = "mending_motor_inactive"
unanchored_icon = "mending_motor_unwrenched"
construction_value = 20
max_integrity = 125
obj_integrity = 125
break_message = "<span class='warning'>The prism falls to the ground with a heavy thud!</span>"
debris = list(/obj/item/clockwork/alloy_shards/small = 3, \
/obj/item/clockwork/alloy_shards/medium = 1, \
/obj/item/clockwork/alloy_shards/large = 1, \
/obj/item/clockwork/component/vanguard_cogwheel/onyx_prism = 1)
var/heal_attempts = 4
var/heal_cost = MIN_CLOCKCULT_POWER*2
var/static/list/damage_heal_order = list(BRUTE, BURN, OXY)
var/static/list/heal_finish_messages = list("There, all mended!", "Try not to get too damaged.", "No more dents and scratches for you!", "Champions never die.", "All patched up.", \
"Ah, child, it's okay now.")
var/static/list/heal_failure_messages = list("Pain is temporary.", "What you do for the Justiciar is eternal.", "Bear this for me.", "Be strong, child.", "Please, be careful!", \
"If you die, you will be remembered.")
var/static/list/mending_motor_typecache = typecacheof(list(
/obj/structure/destructible/clockwork,
/obj/machinery/door/airlock/clockwork,
/obj/machinery/door/window/clockwork,
/obj/structure/window/reinforced/clockwork,
/obj/structure/table/reinforced/brass))
/obj/structure/destructible/clockwork/powered/mending_motor/examine(mob/user)
..()
if(is_servant_of_ratvar(user) || isobserver(user))
to_chat(user, "<span class='inathneq_small'>It requires at least <b>[heal_cost]W</b> to attempt to repair clockwork mobs, structures, or converted silicons.</span>")
/obj/structure/destructible/clockwork/powered/mending_motor/forced_disable(bad_effects)
if(active)
if(bad_effects)
try_use_power(heal_cost)
visible_message("<span class='warning'>[src] emits an airy chuckling sound and falls dark!</span>")
toggle()
return TRUE
/obj/structure/destructible/clockwork/powered/mending_motor/attack_hand(mob/living/user)
if(user.canUseTopic(src, !issilicon(user), NO_DEXTERY) && is_servant_of_ratvar(user))
if(total_accessable_power() < MIN_CLOCKCULT_POWER)
to_chat(user, "<span class='warning'>[src] needs more power to function!</span>")
return 0
toggle(0, user)
/obj/structure/destructible/clockwork/powered/mending_motor/process()
var/efficiency = get_efficiency_mod()
for(var/atom/movable/M in range(7, src))
var/turf/T
if(isclockmob(M) || istype(M, /mob/living/simple_animal/drone/cogscarab))
T = get_turf(M)
var/mob/living/simple_animal/S = M
if(S.health == S.maxHealth || S.stat == DEAD)
continue
for(var/i in 1 to heal_attempts)
if(S.health < S.maxHealth)
if(try_use_power(heal_cost))
S.adjustHealth(-(8 * efficiency))
new /obj/effect/overlay/temp/heal(T, "#1E8CE1")
else
to_chat(S, "<span class='inathneq'>\"[text2ratvar(pick(heal_failure_messages))]\"</span>")
break
else
to_chat(S, "<span class='inathneq'>\"[text2ratvar(pick(heal_finish_messages))]\"</span>")
break
else if(is_type_in_typecache(M, mending_motor_typecache))
T = get_turf(M)
var/obj/structure/destructible/clockwork/C = M
if(C.obj_integrity == C.max_integrity || (istype(C) && !C.can_be_repaired))
continue
for(var/i in 1 to heal_attempts)
if(C.obj_integrity < C.max_integrity)
if(try_use_power(heal_cost))
C.obj_integrity = min(C.obj_integrity + (8 * efficiency), C.max_integrity)
if(C == src)
efficiency = get_efficiency_mod()
C.update_icon()
new /obj/effect/overlay/temp/heal(T, "#1E8CE1")
else
break
else
break
else if(issilicon(M))
T = get_turf(M)
var/mob/living/silicon/S = M
if(S.health == S.maxHealth || S.stat == DEAD || !is_servant_of_ratvar(S))
continue
for(var/i in 1 to heal_attempts)
if(S.health < S.maxHealth)
if(try_use_power(heal_cost))
S.heal_ordered_damage(8 * efficiency, damage_heal_order)
new /obj/effect/overlay/temp/heal(T, "#1E8CE1")
else
to_chat(S, "<span class='inathneq'>\"[text2ratvar(pick(heal_failure_messages))]\"</span>")
break
else
to_chat(S, "<span class='inathneq'>\"[text2ratvar(pick(heal_finish_messages))]\"</span>")
break
. = ..()
if(. < heal_cost)
forced_disable(FALSE)
@@ -40,8 +40,8 @@
/obj/structure/destructible/clockwork/massive/ratvar/attack_ghost(mob/dead/observer/O)
var/alertresult = alert(O, "Embrace the Justiciar's light? You can no longer be cloned!",,"Yes", "No")
if(alertresult == "No" || !O)
return 0
if(alertresult == "No" || QDELETED(O) || !istype(O) || !O.key)
return FALSE
var/mob/living/simple_animal/drone/cogscarab/ratvar/R = new/mob/living/simple_animal/drone/cogscarab/ratvar(get_turf(src))
R.visible_message("<span class='heavy_brass'>[R] forms, and its eyes blink open, glowing bright red!</span>")
R.key = O.key
+5 -5
View File
@@ -5,7 +5,7 @@
var/list/cult_objectives = list()
/proc/iscultist(mob/living/M)
return istype(M) && M.has_antag_datum(/datum/antagonist/cultist, TRUE)
return istype(M) && M.mind && M.mind.has_antag_datum(ANTAG_DATUM_CULT)
/proc/is_sacrifice_target(datum/mind/mind)
if(SSticker.mode.name == "cult")
@@ -158,18 +158,18 @@
/datum/game_mode/proc/add_cultist(datum/mind/cult_mind, stun) //BASE
if (!istype(cult_mind))
return 0
if(cult_mind.current.gain_antag_datum(/datum/antagonist/cultist))
if(cult_mind.add_antag_datum(ANTAG_DATUM_CULT))
if(stun)
cult_mind.current.Paralyse(5)
return 1
/datum/game_mode/proc/remove_cultist(datum/mind/cult_mind, show_message = 1, stun)
if(cult_mind.current)
var/datum/antagonist/cultist/cult_datum = cult_mind.current.has_antag_datum(/datum/antagonist/cultist, TRUE)
var/datum/antagonist/cult/cult_datum = cult_mind.has_antag_datum(ANTAG_DATUM_CULT)
if(!cult_datum)
return FALSE
cult_datum.silent_update = show_message
cult_datum.on_remove()
cult_datum.silent = show_message
cult_datum.on_removal()
if(stun)
cult_mind.current.Paralyse(5)
return TRUE
+2 -2
View File
@@ -287,7 +287,7 @@ GLOBAL_LIST_INIT(lawlorify, list (
notify_ghosts("An arch devil has ascended in \the [A.name]. Reach out to the devil to be given a new shell for your soul.", source = owner.current, action=NOTIFY_ATTACK)
sleep(50)
if(!SSticker.mode.devil_ascended)
SSshuttle.emergency.request(null, 0.3)
SSshuttle.emergency.request(null, set_coefficient = 0.3)
SSticker.mode.devil_ascended++
form = ARCH_DEVIL
@@ -449,7 +449,7 @@ GLOBAL_LIST_INIT(lawlorify, list (
A.convert_to_archdevil()
else
throw EXCEPTION("Unable to find a blobstart landmark for hellish resurrection")
/datum/devilinfo/proc/update_hud()
if(istype(owner.current, /mob/living/carbon))
@@ -556,7 +556,7 @@
var/mob/living/silicon/ai/A = usr
if(A.stat == DEAD)
A <<"You are already dead!" //Omae Wa Mou Shindeiru
to_chat(A, "You are already dead!") //Omae Wa Mou Shindeiru
return
for(var/datum/AI_Module/AM in possible_modules)
@@ -166,7 +166,7 @@
var/obj/machinery/abductor/console/con = get_team_console(team_number)
var/datum/objective/objective = team_objectives[team_number]
if (con.experiment.points >= objective.target_amount)
SSshuttle.emergency.request(null, 0.5)
SSshuttle.emergency.request(null, set_coefficient = 0.5)
finished = 1
return ..()
return ..()
@@ -14,6 +14,13 @@
origin_tech = "magnets=7;biotech=4;powerstorage=4;abductor=4"
armor = list(melee = 15, bullet = 15, laser = 15, energy = 15, bomb = 15, bio = 15, rad = 15, fire = 70, acid = 70)
actions_types = list(/datum/action/item_action/hands_free/activate)
allowed = list(
/obj/item/device/abductor,
/obj/item/weapon/abductor_baton,
/obj/item/weapon/melee/baton,
/obj/item/weapon/gun/energy,
/obj/item/weapon/restraints/handcuffs
)
var/mode = VEST_STEALTH
var/stealth_active = 0
var/combat_cooldown = 10
@@ -21,6 +28,11 @@
var/stealth_armor = list(melee = 15, bullet = 15, laser = 15, energy = 15, bomb = 15, bio = 15, rad = 15, fire = 70, acid = 70)
var/combat_armor = list(melee = 50, bullet = 50, laser = 50, energy = 50, bomb = 50, bio = 50, rad = 50, fire = 90, acid = 90)
/obj/item/clothing/suit/armor/abductor/vest/proc/toggle_nodrop()
flags ^= NODROP
if(ismob(loc))
to_chat(loc, "<span class='notice'>Your vest is now [flags & NODROP ? "locked" : "unlocked"].</span>")
/obj/item/clothing/suit/armor/abductor/vest/proc/flip_mode()
switch(mode)
if(VEST_STEALTH)
@@ -107,6 +119,18 @@
if(combat_cooldown==initial(combat_cooldown))
STOP_PROCESSING(SSobj, src)
/obj/item/clothing/suit/armor/abductor/Destroy()
STOP_PROCESSING(SSobj, src)
for(var/obj/machinery/abductor/console/C in GLOB.machines)
if(C.vest == src)
C.vest = null
break
. = ..()
/obj/item/device/abductor
icon = 'icons/obj/abductor.dmi'
/obj/item/device/abductor/proc/AbductorCheck(user)
if(isabductor(user))
return TRUE
@@ -114,14 +138,19 @@
return FALSE
/obj/item/device/abductor/proc/ScientistCheck(user)
if(!AbductorCheck(user))
return FALSE
var/mob/living/carbon/human/H = user
var/datum/species/abductor/S = H.dna.species
return S.scientist
if(S.scientist)
return TRUE
to_chat(user, "<span class='warning'>You're not trained to use this!</span>")
return FALSE
/obj/item/device/abductor/gizmo
name = "science tool"
desc = "A dual-mode tool for retrieving specimens and scanning appearances. Scanning can be done through cameras."
icon = 'icons/obj/abductor.dmi'
icon_state = "gizmo_scan"
item_state = "silencer"
origin_tech = "engineering=7;magnets=4;bluespace=4;abductor=3"
@@ -130,11 +159,12 @@
var/obj/machinery/abductor/console/console
/obj/item/device/abductor/gizmo/attack_self(mob/user)
if(!AbductorCheck(user))
return
if(!ScientistCheck(user))
to_chat(user, "<span class='warning'>You're not trained to use this!</span>")
return
if(!console)
to_chat(user, "<span class='warning'>The device is not linked to console!</span>")
return
if(mode == GIZMO_SCAN)
mode = GIZMO_MARK
icon_state = "gizmo_mark"
@@ -144,11 +174,12 @@
to_chat(user, "<span class='notice'>You switch the device to [mode==GIZMO_SCAN? "SCAN": "MARK"] MODE</span>")
/obj/item/device/abductor/gizmo/attack(mob/living/M, mob/user)
if(!AbductorCheck(user))
return
if(!ScientistCheck(user))
to_chat(user, "<span class='notice'>You're not trained to use this</span>")
return
if(!console)
to_chat(user, "<span class='warning'>The device is not linked to console!</span>")
return
switch(mode)
if(GIZMO_SCAN)
scan(M, user)
@@ -159,11 +190,12 @@
/obj/item/device/abductor/gizmo/afterattack(atom/target, mob/living/user, flag, params)
if(flag)
return
if(!AbductorCheck(user))
return
if(!ScientistCheck(user))
to_chat(user, "<span class='notice'>You're not trained to use this</span>")
return
if(!console)
to_chat(user, "<span class='warning'>The device is not linked to console!</span>")
return
switch(mode)
if(GIZMO_SCAN)
scan(target, user)
@@ -172,9 +204,8 @@
/obj/item/device/abductor/gizmo/proc/scan(atom/target, mob/living/user)
if(ishuman(target))
if(console!=null)
console.AddSnapshot(target)
to_chat(user, "<span class='notice'>You scan [target] and add them to the database.</span>")
console.AddSnapshot(target)
to_chat(user, "<span class='notice'>You scan [target] and add them to the database.</span>")
/obj/item/device/abductor/gizmo/proc/mark(atom/target, mob/living/user)
if(marked == target)
@@ -198,11 +229,15 @@
marked = target
to_chat(user, "<span class='notice'>You finish preparing [target] for transport.</span>")
/obj/item/device/abductor/gizmo/Destroy()
if(console)
console.gizmo = null
. = ..()
/obj/item/device/abductor/silencer
name = "abductor silencer"
desc = "A compact device used to shut down communications equipment."
icon = 'icons/obj/abductor.dmi'
icon_state = "silencer"
item_state = "gizmo"
origin_tech = "materials=4;programming=7;abductor=3"
@@ -419,10 +454,10 @@ Congratulations! You are now trained for invasive xenobiology research!"}
if(!C.handcuffed)
C.handcuffed = new /obj/item/weapon/restraints/handcuffs/energy/used(C)
C.update_handcuffed()
to_chat(user, "<span class='notice'>You handcuff [C].</span>")
to_chat(user, "<span class='notice'>You restrain [C].</span>")
add_logs(user, C, "handcuffed")
else
to_chat(user, "<span class='warning'>You fail to handcuff [C].</span>")
to_chat(user, "<span class='warning'>You fail to restrain [C].</span>")
else
to_chat(user, "<span class='warning'>[C] doesn't have two hands...</span>")
@@ -471,11 +506,11 @@ Congratulations! You are now trained for invasive xenobiology research!"}
..()
switch(mode)
if(BATON_STUN)
user <<"<span class='warning'>The baton is in stun mode.</span>"
to_chat(user, "<span class='warning'>The baton is in stun mode.</span>")
if(BATON_SLEEP)
user <<"<span class='warning'>The baton is in sleep inducement mode.</span>"
to_chat(user, "<span class='warning'>The baton is in sleep inducement mode.</span>")
if(BATON_CUFF)
user <<"<span class='warning'>The baton is in restraining mode.</span>"
to_chat(user, "<span class='warning'>The baton is in restraining mode.</span>")
if(BATON_PROBE)
to_chat(user, "<span class='warning'>The baton is in probing mode.</span>")
@@ -22,13 +22,13 @@
if(console)
var/obj/item/clothing/suit/armor/abductor/vest/V = locate() in H
if(V)
console.vest = V
console.AddVest(V)
V.flags |= NODROP
var/obj/item/device/abductor/gizmo/G = locate() in H.getBackSlot()
if(G)
console.gizmo = G
G.console = console
var/obj/item/weapon/storage/backpack/B = locate() in H
if(B)
for(var/obj/item/device/abductor/gizmo/G in B.contents)
console.AddGizmo(G)
/datum/outfit/abductor/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
..()
@@ -40,10 +40,10 @@
name = "Abductor Agent"
head = /obj/item/clothing/head/helmet/abductor
suit = /obj/item/clothing/suit/armor/abductor/vest
suit_store = /obj/item/weapon/abductor_baton
belt = /obj/item/weapon/storage/belt/military/abductor/full
backpack_contents = list(
/obj/item/weapon/abductor_baton = 1,
/obj/item/weapon/gun/energy/alien = 1,
/obj/item/device/abductor/silencer = 1
)
@@ -7,7 +7,7 @@
//Console
/obj/machinery/abductor/console
name = "Abductor console"
name = "abductor console"
desc = "Ship command center."
icon = 'icons/obj/abductor.dmi'
icon_state = "console"
@@ -32,7 +32,7 @@
var/dat = ""
dat += "<H3> Abductsoft 3000 </H3>"
if(experiment != null)
if(experiment)
var/points = experiment.points
var/credits = experiment.credits
dat += "Collected Samples : [points] <br>"
@@ -46,18 +46,18 @@
else
dat += "<span class='bad'>NO EXPERIMENT MACHINE DETECTED</span> <br>"
if(pad!=null)
if(pad)
dat += "<span class='bad'>Emergency Teleporter System.</span>"
dat += "<span class='bad'>Consider using primary observation console first.</span>"
dat += "<a href='?src=\ref[src];teleporter_send=1'>Activate Teleporter</A><br>"
if(gizmo!=null && gizmo.marked!=null)
if(gizmo && gizmo.marked)
dat += "<a href='?src=\ref[src];teleporter_retrieve=1'>Retrieve Mark</A><br>"
else
dat += "<span class='linkOff'>Retrieve Mark</span><br>"
else
dat += "<span class='bad'>NO TELEPAD DETECTED</span></br>"
if(vest!=null)
if(vest)
dat += "<h4> Agent Vest Mode </h4><br>"
var/mode = vest.mode
if(mode == VEST_STEALTH)
@@ -88,7 +88,8 @@
else if(href_list["flip_vest"])
FlipVest()
else if(href_list["toggle_vest"])
toggle_vest()
if(vest)
vest.toggle_nodrop()
else if(href_list["select_disguise"])
SelectDisguise()
else if(href_list["dispense"])
@@ -105,23 +106,22 @@
Dispense(/obj/item/clothing/suit/armor/abductor/vest)
updateUsrDialog()
/obj/machinery/abductor/console/proc/TeleporterRetrieve()
if(gizmo!=null && pad!=null && gizmo.marked)
if(pad && gizmo && gizmo.marked)
pad.Retrieve(gizmo.marked)
/obj/machinery/abductor/console/proc/TeleporterSend()
if(pad!=null)
if(pad)
pad.Send()
/obj/machinery/abductor/console/proc/FlipVest()
if(vest!=null)
if(vest)
vest.flip_mode()
/obj/machinery/abductor/console/proc/SelectDisguise(remote = 0)
var/entry_name = input( "Choose Disguise", "Disguise") as null|anything in disguises
var/datum/icon_snapshot/chosen = disguises[entry_name]
if(chosen && (remote || in_range(usr,src)))
if(chosen && vest && (remote || in_range(usr,src)))
vest.SetDisguise(chosen)
/obj/machinery/abductor/console/proc/SetDroppoint(turf/open/location,user)
@@ -135,10 +135,10 @@
/obj/machinery/abductor/console/Initialize(mapload)
if(mapload)
return TRUE //wait for machines list
..()
return INITIALIZE_HINT_LATELOAD
/obj/machinery/abductor/console/LateInitialize()
if(!team)
return
@@ -169,36 +169,48 @@
return
disguises[entry.name] = entry
/obj/machinery/abductor/console/proc/AddGizmo(obj/item/device/abductor/gizmo/G)
if(G == gizmo && G.console == src)
return FALSE
if(G.console)
G.console.gizmo = null
gizmo = G
G.console = src
return TRUE
/obj/machinery/abductor/console/proc/AddVest(obj/item/clothing/suit/armor/abductor/vest/V)
if(vest == V)
return FALSE
for(var/obj/machinery/abductor/console/C in GLOB.machines)
if(C.vest == V)
C.vest = null
break
vest = V
return TRUE
/obj/machinery/abductor/console/attackby(obj/O, mob/user, params)
if(istype(O, /obj/item/device/abductor/gizmo))
var/obj/item/device/abductor/gizmo/G = O
if(istype(O, /obj/item/device/abductor/gizmo) && AddGizmo(O))
to_chat(user, "<span class='notice'>You link the tool to the console.</span>")
gizmo = G
G.console = src
else if(istype(O, /obj/item/clothing/suit/armor/abductor/vest))
var/obj/item/clothing/suit/armor/abductor/vest/V = O
else if(istype(O, /obj/item/clothing/suit/armor/abductor/vest) && AddVest(O))
to_chat(user, "<span class='notice'>You link the vest to the console.</span>")
if(istype(vest))
if(vest.flags & NODROP)
toggle_vest()
vest = V
else
return ..()
/obj/machinery/abductor/console/proc/Dispense(item,cost=1)
if(experiment && experiment.credits >= cost)
experiment.credits -=cost
say("Incoming supply!")
var/drop_location = loc
if(pad)
flick("alien-pad", pad)
new item(pad.loc)
else
new item(loc)
drop_location = pad.loc
new item(drop_location)
else
say("Insufficent data!")
/obj/machinery/abductor/console/proc/toggle_vest()
vest.flags ^= NODROP
var/mob/M = vest.loc
if(istype(M))
to_chat(M, "<span class='notice'>[src] is now [vest.flags & NODROP ? "locked" : "unlocked"].</span>")
@@ -1,5 +1,5 @@
/obj/machinery/abductor/gland_dispenser
name = "Replacement Organ Storage"
name = "replacement organ storage"
desc = "A tank filled with replacement organs."
icon = 'icons/obj/abductor.dmi'
icon_state = "dispenser"
@@ -49,7 +49,7 @@
var/g_color = gland_colors[i]
var/amount = amounts[i]
dat += "<a class='box gland' style='background-color:[g_color]' href='?src=\ref[src];dispense=[i]'>[amount]</a>"
if(item_count == 3) // Three boxes per line
if(item_count == 4) // Four boxes per line
dat +="</br></br>"
item_count = 0
var/datum/browser/popup = new(user, "glands", "Gland Dispenser", 200, 200)
@@ -628,7 +628,7 @@ GLOBAL_VAR_INIT(total_borer_hosts_needed, 10)
chemicals -= 250
to_chat(src, "<span class='notice'>You send a jolt of energy to your host, reviving them!</span>")
victim.grab_ghost(force = TRUE) //brings the host back, no eggscape
victim <<"<span class='notice'>You bolt upright, gasping for breath!</span>"
to_chat(victim, "<span class='notice'>You bolt upright, gasping for breath!</span>")
/mob/living/simple_animal/borer/verb/bond_brain()
set category = "Borer"
@@ -672,7 +672,7 @@ GLOBAL_VAR_INIT(total_borer_hosts_needed, 10)
if(!bonding)
return
if(docile)
src <<"<span class='warning'>You are feeling far too docile to do that.</span>"
to_chat(src, "<span class='warning'>You are feeling far too docile to do that.</span>")
return
if(is_servant_of_ratvar(victim) || iscultist(victim) || victim.isloyal())
to_chat(src, "<span class='warning'>[victim]'s mind seems to be blocked by some unknown force!</span>")
@@ -92,7 +92,7 @@
playsound(user, 'sound/magic/Demon_consume.ogg', 50, 1)
for(var/obj/effect/proc_holder/spell/knownspell in user.mind.spell_list)
if(knownspell.type == /obj/effect/proc_holder/spell/bloodcrawl)
user <<"<span class='warning'>...and you don't feel any different.</span>"
to_chat(user, "<span class='warning'>...and you don't feel any different.</span>")
qdel(src)
return
user.visible_message("<span class='warning'>[user]'s eyes flare a deep crimson!</span>", \
+27 -10
View File
@@ -1,22 +1,24 @@
/datum/game_mode/traitor/double_agents
name = "double agents"
config_tag = "double_agents"
/datum/game_mode/traitor/internal_affairs
name = "Internal Affairs"
config_tag = "internal_affairs"
employer = "Internal Affairs"
required_players = 25
required_enemies = 5
recommended_enemies = 8
reroll_friendly = 0
traitor_name = "Nanotrasen Internal Affairs Agent"
traitors_possible = 10 //hard limit on traitors if scaling is turned off
num_modifier = 4 // Four additional traitors
announce_text = "There are double agents trying to kill each other!\n\
<span class='danger'>Traitors</span>: Eliminate your targets and protect yourself!\n\
<span class='notice'>Crew</span>: Stop the double agents before they can cause too much mayhem."
announce_text = "There are Nanotrasen Internal Affairs Agents trying to kill each other!\n\
<span class='danger'>IAA</span>: Eliminate your targets and protect yourself!\n\
<span class='notice'>Crew</span>: Stop the IAA agents before they can cause too much mayhem."
var/list/target_list = list()
var/list/late_joining_list = list()
/datum/game_mode/traitor/double_agents/post_setup()
/datum/game_mode/traitor/internal_affairs/post_setup()
var/i = 0
for(var/datum/mind/traitor in traitors)
i++
@@ -25,7 +27,7 @@
target_list[traitor] = traitors[i + 1]
..()
/datum/game_mode/traitor/double_agents/forge_traitor_objectives(datum/mind/traitor)
/datum/game_mode/traitor/internal_affairs/forge_traitor_objectives(datum/mind/traitor)
if(target_list.len && target_list[traitor]) // Is a double agent
@@ -58,7 +60,7 @@
..() // Give them standard objectives.
return
/datum/game_mode/traitor/double_agents/add_latejoin_traitor(datum/mind/character)
/datum/game_mode/traitor/internal_affairs/add_latejoin_traitor(datum/mind/character)
check_potential_agents()
@@ -87,7 +89,7 @@
late_joining_list += character
return
/datum/game_mode/traitor/double_agents/proc/check_potential_agents()
/datum/game_mode/traitor/internal_affairs/proc/check_potential_agents()
for(var/M in late_joining_list)
if(istype(M, /datum/mind))
@@ -100,3 +102,18 @@
// If any check fails, remove them from our list
late_joining_list -= M
/datum/game_mode/traitor/internal_affairs/greet_traitor(datum/mind/traitor)
var/crime = pick("distribution of contraband" , "unauthorized erotic action on duty", "embezzlement", "piloting under the influence", "dereliction of duty", "syndicate collaboration", "mutiny", "multiple homicides", "corporate espionage", "recieving bribes", "malpractice", "worship of prohbited life forms", "possession of profane texts", "murder", "arson", "insulting their manager", "grand theft", "conspiracy", "attempting to unionize", "vandalism", "gross incompetence")
to_chat(traitor.current, "<B><font size=3 color=red>You are the [traitor_name].</font></B>")
to_chat(traitor.current, "<B><font size=3 color=red>Your target is suspected of [crime], and you have been tasked with eliminating them by any means necessary to avoid a costly and embarrassing public trial.</font></B>")
to_chat(traitor.current, "<B><font size=5 color=red>While you have a license to kill, unneeded property damage or loss of employee life will lead to your contract being terminated.</font></B>")
to_chat(traitor.current, "<B><font size=3 color=red>For the sake of plausible deniability, you have been equipped with an array of captured Syndicate weaponry available via uplink.</font></B>")
to_chat(traitor.current, "<B><font size=3 color=red>Finally, watch your back. Your target has friends in high places, and intel suggests someone may have taken out a contract of their own to protect them.</font></B>")
traitor.announce_objectives()
/datum/game_mode/traitor/internal_affairs/give_codewords(mob/living/traitor_mob)
return
+6 -5
View File
@@ -1,5 +1,6 @@
/datum/game_mode
var/traitor_name = "traitor"
var/employer = "The Syndicate"
var/list/datum/mind/traitors = list()
var/datum/mind/exchange_red
@@ -213,7 +214,7 @@
..()
return//Traitors will be checked as part of check_extra_completion. Leaving this here as a reminder.
/proc/give_codewords(mob/living/traitor_mob)
/datum/game_mode/proc/give_codewords(mob/living/traitor_mob)
to_chat(traitor_mob, "<U><B>The Syndicate provided you with the following information on how to identify their agents:</B></U>")
to_chat(traitor_mob, "<B>Code Phrase</B>: <span class='danger'>[GLOB.syndicate_code_phrase]</span>")
to_chat(traitor_mob, "<B>Code Response</B>: <span class='danger'>[GLOB.syndicate_code_response]</span>")
@@ -335,7 +336,7 @@
uplink_loc = R
if (!uplink_loc)
to_chat(traitor_mob, "Unfortunately, the Syndicate wasn't able to get you an Uplink.")
to_chat(traitor_mob, "Unfortunately, [employer] wasn't able to get you an Uplink.")
. = 0
else
var/obj/item/device/uplink/U = new(uplink_loc)
@@ -345,19 +346,19 @@
if(uplink_loc == R)
R.traitor_frequency = sanitize_frequency(rand(MIN_FREQ, MAX_FREQ))
to_chat(traitor_mob, "The Syndicate have cunningly disguised a Syndicate Uplink as your [R.name]. Simply dial the frequency [format_frequency(R.traitor_frequency)] to unlock its hidden features.")
to_chat(traitor_mob, "[employer] has cunningly disguised a Syndicate Uplink as your [R.name]. Simply dial the frequency [format_frequency(R.traitor_frequency)] to unlock its hidden features.")
traitor_mob.mind.store_memory("<B>Radio Frequency:</B> [format_frequency(R.traitor_frequency)] ([R.name]).")
else if(uplink_loc == PDA)
PDA.lock_code = "[rand(100,999)] [pick("Alpha","Bravo","Charlie","Delta","Echo","Foxtrot","Golf","Hotel","India","Juliet","Kilo","Lima","Mike","November","Oscar","Papa","Quebec","Romeo","Sierra","Tango","Uniform","Victor","Whiskey","X-ray","Yankee","Zulu")]"
to_chat(traitor_mob, "The Syndicate have cunningly disguised a Syndicate Uplink as your [PDA.name]. Simply enter the code \"[PDA.lock_code]\" into the ringtone select to unlock its hidden features.")
to_chat(traitor_mob, "[employer] has cunningly disguised a Syndicate Uplink as your [PDA.name]. Simply enter the code \"[PDA.lock_code]\" into the ringtone select to unlock its hidden features.")
traitor_mob.mind.store_memory("<B>Uplink Passcode:</B> [PDA.lock_code] ([PDA.name]).")
else if(uplink_loc == P)
P.traitor_unlock_degrees = rand(1, 360)
to_chat(traitor_mob, "The Syndicate have cunningly disguised a Syndicate Uplink as your [P.name]. Simply twist the top of the pen [P.traitor_unlock_degrees] from its starting position to unlock its hidden features.")
to_chat(traitor_mob, "[employer] has cunningly disguised a Syndicate Uplink as your [P.name]. Simply twist the top of the pen [P.traitor_unlock_degrees] from its starting position to unlock its hidden features.")
traitor_mob.mind.store_memory("<B>Uplink Degrees:</B> [P.traitor_unlock_degrees] ([P.name]).")
if(!safety) // If they are not a rev. Can be added on to.
+644 -1
View File
@@ -1,4 +1,3 @@
//Apprenticeship contract - moved to antag_spawner.dm
///////////////////////////Veil Render//////////////////////
@@ -633,3 +632,647 @@
/obj/effect/overlay/temp/tornado/Initialize()
. = ..()
animate(src, pixel_x = -500, time = 40)
=======
//Apprenticeship contract - moved to antag_spawner.dm
///////////////////////////Veil Render//////////////////////
/obj/item/weapon/veilrender
name = "veil render"
desc = "A wicked curved blade of alien origin, recovered from the ruins of a vast city."
icon = 'icons/obj/wizard.dmi'
icon_state = "render"
item_state = "render"
force = 15
throwforce = 10
w_class = WEIGHT_CLASS_NORMAL
hitsound = 'sound/weapons/bladeslice.ogg'
var/charges = 1
var/spawn_type = /obj/singularity/wizard
var/spawn_amt = 1
var/activate_descriptor = "reality"
var/rend_desc = "You should run now."
var/spawn_fast = 0 //if 1, ignores checking for mobs on loc before spawning
/obj/item/weapon/veilrender/attack_self(mob/user)
if(charges > 0)
new /obj/effect/rend(get_turf(user), spawn_type, spawn_amt, rend_desc, spawn_fast)
charges--
user.visible_message("<span class='boldannounce'>[src] hums with power as [user] deals a blow to [activate_descriptor] itself!</span>")
else
to_chat(user, "<span class='danger'>The unearthly energies that powered the blade are now dormant.</span>")
/obj/effect/rend
name = "tear in the fabric of reality"
desc = "You should run now."
icon = 'icons/obj/biomass.dmi'
icon_state = "rift"
density = 1
anchored = 1
var/spawn_path = /mob/living/simple_animal/cow //defaulty cows to prevent unintentional narsies
var/spawn_amt_left = 20
var/spawn_fast = 0
/obj/effect/rend/New(loc, var/spawn_type, var/spawn_amt, var/desc, var/spawn_fast)
src.spawn_path = spawn_type
src.spawn_amt_left = spawn_amt
src.desc = desc
src.spawn_fast = spawn_fast
START_PROCESSING(SSobj, src)
return
/obj/effect/rend/process()
if(!spawn_fast)
if(locate(/mob) in loc)
return
new spawn_path(loc)
spawn_amt_left--
if(spawn_amt_left <= 0)
qdel(src)
/obj/effect/rend/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/weapon/nullrod))
user.visible_message("<span class='danger'>[user] seals \the [src] with \the [I].</span>")
qdel(src)
return
else
return ..()
/obj/item/weapon/veilrender/vealrender
name = "veal render"
desc = "A wicked curved blade of alien origin, recovered from the ruins of a vast farm."
spawn_type = /mob/living/simple_animal/cow
spawn_amt = 20
activate_descriptor = "hunger"
rend_desc = "Reverberates with the sound of ten thousand moos."
/obj/item/weapon/veilrender/honkrender
name = "honk render"
desc = "A wicked curved blade of alien origin, recovered from the ruins of a vast circus."
spawn_type = /mob/living/simple_animal/hostile/retaliate/clown
spawn_amt = 10
activate_descriptor = "depression"
rend_desc = "Gently wafting with the sounds of endless laughter."
icon_state = "clownrender"
////TEAR IN REALITY
/obj/singularity/wizard
name = "tear in the fabric of reality"
desc = "This isn't right."
icon = 'icons/effects/224x224.dmi'
icon_state = "reality"
pixel_x = -96
pixel_y = -96
grav_pull = 6
consume_range = 3
current_size = STAGE_FOUR
allowed_size = STAGE_FOUR
/obj/singularity/wizard/process()
move()
eat()
return
/////////////////////////////////////////Scrying///////////////////
/obj/item/weapon/scrying
name = "scrying orb"
desc = "An incandescent orb of otherworldly energy, staring into it gives you vision beyond mortal means."
icon = 'icons/obj/projectiles.dmi'
icon_state ="bluespace"
throw_speed = 3
throw_range = 7
throwforce = 15
damtype = BURN
force = 15
hitsound = 'sound/items/welder2.ogg'
/obj/item/weapon/scrying/attack_self(mob/user)
to_chat(user, "<span class='notice'>You can see...everything!</span>")
visible_message("<span class='danger'>[user] stares into [src], their eyes glazing over.</span>")
user.ghostize(1)
return
/////////////////////////////////////////Necromantic Stone///////////////////
/obj/item/device/necromantic_stone
name = "necromantic stone"
desc = "A shard capable of resurrecting humans as skeleton thralls."
icon = 'icons/obj/wizard.dmi'
icon_state = "necrostone"
item_state = "electronic"
origin_tech = "bluespace=4;materials=4"
w_class = WEIGHT_CLASS_TINY
var/list/spooky_scaries = list()
var/unlimited = 0
/obj/item/device/necromantic_stone/unlimited
unlimited = 1
/obj/item/device/necromantic_stone/attack(mob/living/carbon/human/M, mob/living/carbon/human/user)
if(!istype(M))
return ..()
if(!istype(user) || !user.canUseTopic(M,1))
return
if(M.stat != DEAD)
to_chat(user, "<span class='warning'>This artifact can only affect the dead!</span>")
return
if(!M.mind || !M.client)
to_chat(user, "<span class='warning'>There is no soul connected to this body...</span>")
return
check_spooky()//clean out/refresh the list
if(spooky_scaries.len >= 3 && !unlimited)
to_chat(user, "<span class='warning'>This artifact can only affect three undead at a time!</span>")
return
M.set_species(/datum/species/skeleton, icon_update=0)
M.revive(full_heal = 1, admin_revive = 1)
spooky_scaries |= M
to_chat(M, "<span class='userdanger'>You have been revived by </span><B>[user.real_name]!</B>")
to_chat(M, "<span class='userdanger'>[user.p_they(TRUE)] [user.p_are()] your master now, assist them even if it costs you your new life!</span>")
equip_roman_skeleton(M)
desc = "A shard capable of resurrecting humans as skeleton thralls[unlimited ? "." : ", [spooky_scaries.len]/3 active thralls."]"
/obj/item/device/necromantic_stone/proc/check_spooky()
if(unlimited) //no point, the list isn't used.
return
for(var/X in spooky_scaries)
if(!ishuman(X))
spooky_scaries.Remove(X)
continue
var/mob/living/carbon/human/H = X
if(H.stat == DEAD)
spooky_scaries.Remove(X)
continue
listclearnulls(spooky_scaries)
//Funny gimmick, skeletons always seem to wear roman/ancient armour
/obj/item/device/necromantic_stone/proc/equip_roman_skeleton(mob/living/carbon/human/H)
for(var/obj/item/I in H)
H.dropItemToGround(I)
var/hat = pick(/obj/item/clothing/head/helmet/roman, /obj/item/clothing/head/helmet/roman/legionaire)
H.equip_to_slot_or_del(new hat(H), slot_head)
H.equip_to_slot_or_del(new /obj/item/clothing/under/roman(H), slot_w_uniform)
H.equip_to_slot_or_del(new /obj/item/clothing/shoes/roman(H), slot_shoes)
H.put_in_hands_or_del(new /obj/item/weapon/shield/riot/roman(H))
H.put_in_hands_or_del(new /obj/item/weapon/claymore(H))
H.equip_to_slot_or_del(new /obj/item/weapon/twohanded/spear(H), slot_back)
/////////////////////Multiverse Blade////////////////////
/obj/item/weapon/multisword
name = "multiverse sword"
desc = "A weapon capable of conquering the universe and beyond. Activate it to summon copies of yourself from others dimensions to fight by your side."
icon = 'icons/obj/weapons.dmi'
icon_state = "multiverse"
item_state = "multiverse"
hitsound = 'sound/weapons/bladeslice.ogg'
flags = CONDUCT
slot_flags = SLOT_BELT
sharpness = IS_SHARP
force = 20
throwforce = 10
w_class = WEIGHT_CLASS_NORMAL
attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
var/faction = list("unassigned")
var/cooldown = 0
var/assigned = "unassigned"
var/static/list/multiverse = list()
/obj/item/weapon/multisword/New()
..()
multiverse += src
/obj/item/weapon/multisword/Destroy()
multiverse.Remove(src)
return ..()
/obj/item/weapon/multisword/attack_self(mob/user)
if(user.mind.special_role == "apprentice")
to_chat(user, "<span class='warning'>You know better than to touch your teacher's stuff.</span>")
return
if(cooldown < world.time)
var/faction_check = 0
for(var/F in faction)
if(F in user.faction)
faction_check = 1
break
if(faction_check == 0)
faction = list("[user.real_name]")
assigned = "[user.real_name]"
user.faction = list("[user.real_name]")
to_chat(user, "You bind the sword to yourself. You can now use it to summon help.")
if(!is_gangster(user))
var/datum/gang/multiverse/G = new(src, "[user.real_name]")
SSticker.mode.gangs += G
G.bosses += user.mind
G.add_gang_hud(user.mind)
user.mind.gang_datum = G
to_chat(user, "<span class='warning'><B>With your new found power you could easily conquer the station!</B></span>")
var/datum/objective/hijackclone/hijack_objective = new /datum/objective/hijackclone
hijack_objective.owner = user.mind
user.mind.objectives += hijack_objective
hijack_objective.explanation_text = "Ensure only [user.real_name] and their copies are on the shuttle!"
to_chat(user, "<B>Objective #[1]</B>: [hijack_objective.explanation_text]")
SSticker.mode.traitors += user.mind
user.mind.special_role = "[user.real_name] Prime"
else
var/list/candidates = get_candidates(ROLE_WIZARD)
if(candidates.len)
var/client/C = pick(candidates)
spawn_copy(C, get_turf(user.loc), user)
to_chat(user, "<span class='warning'><B>The sword flashes, and you find yourself face to face with...you!</B></span>")
cooldown = world.time + 400
for(var/obj/item/weapon/multisword/M in multiverse)
if(M.assigned == assigned)
M.cooldown = cooldown
else
to_chat(user, "You fail to summon any copies of yourself. Perhaps you should try again in a bit.")
else
to_chat(user, "<span class='warning'><B>[src] is recharging! Keep in mind it shares a cooldown with the swords wielded by your copies.</span>")
/obj/item/weapon/multisword/proc/spawn_copy(var/client/C, var/turf/T, mob/user)
var/mob/living/carbon/human/M = new/mob/living/carbon/human(T)
C.prefs.copy_to(M, icon_updates=0)
M.key = C.key
M.mind.name = user.real_name
to_chat(M, "<B>You are an alternate version of [user.real_name] from another universe! Help them accomplish their goals at all costs.</B>")
SSticker.mode.add_gangster(M.mind, user.mind.gang_datum, FALSE)
M.real_name = user.real_name
M.name = user.real_name
M.faction = list("[user.real_name]")
if(prob(50))
var/list/all_species = list()
for(var/speciestype in subtypesof(/datum/species))
var/datum/species/S = speciestype
if(!initial(S.dangerous_existence))
all_species += speciestype
M.set_species(pick(all_species), icon_update=0)
M.update_body()
M.update_hair()
M.update_body_parts()
M.dna.update_dna_identity()
equip_copy(M)
/obj/item/weapon/multisword/proc/equip_copy(var/mob/living/carbon/human/M)
var/obj/item/weapon/multisword/sword = new /obj/item/weapon/multisword
sword.assigned = assigned
sword.faction = list("[assigned]")
var/randomize = pick("mobster","roman","wizard","cyborg","syndicate","assistant", "animu", "cultist", "highlander", "clown", "killer", "pirate", "soviet", "officer", "gladiator")
switch(randomize)
if("mobster")
M.equip_to_slot_or_del(new /obj/item/clothing/head/fedora(M), slot_head)
M.equip_to_slot_or_del(new /obj/item/clothing/shoes/laceup(M), slot_shoes)
M.equip_to_slot_or_del(new /obj/item/clothing/gloves/color/black(M), slot_gloves)
M.equip_to_slot_or_del(new /obj/item/device/radio/headset(M), slot_ears)
M.equip_to_slot_or_del(new /obj/item/clothing/glasses/sunglasses(M), slot_glasses)
M.equip_to_slot_or_del(new /obj/item/clothing/under/suit_jacket/really_black(M), slot_w_uniform)
M.put_in_hands_or_del(sword)
if("roman")
var/hat = pick(/obj/item/clothing/head/helmet/roman, /obj/item/clothing/head/helmet/roman/legionaire)
M.equip_to_slot_or_del(new hat(M), slot_head)
M.equip_to_slot_or_del(new /obj/item/clothing/under/roman(M), slot_w_uniform)
M.equip_to_slot_or_del(new /obj/item/clothing/shoes/roman(M), slot_shoes)
M.put_in_hands_or_del(new /obj/item/weapon/shield/riot/roman(M))
M.put_in_hands_or_del(sword)
if("wizard")
M.equip_to_slot_or_del(new /obj/item/clothing/under/color/lightpurple(M), slot_w_uniform)
M.equip_to_slot_or_del(new /obj/item/clothing/suit/wizrobe/red(M), slot_wear_suit)
M.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal/magic(M), slot_shoes)
M.equip_to_slot_or_del(new /obj/item/device/radio/headset(M), slot_ears)
M.equip_to_slot_or_del(new /obj/item/clothing/head/wizard/red(M), slot_head)
M.put_in_hands_or_del(sword)
if("cyborg")
for(var/X in M.bodyparts)
var/obj/item/bodypart/affecting = X
affecting.change_bodypart_status(BODYPART_ROBOTIC, FALSE, TRUE)
M.equip_to_slot_or_del(new /obj/item/clothing/glasses/thermal/eyepatch(M), slot_glasses)
M.put_in_hands_or_del(sword)
if("syndicate")
M.equip_to_slot_or_del(new /obj/item/clothing/under/syndicate(M), slot_w_uniform)
M.equip_to_slot_or_del(new /obj/item/clothing/shoes/combat(M), slot_shoes)
M.equip_to_slot_or_del(new /obj/item/clothing/gloves/combat(M), slot_gloves)
M.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/swat(M), slot_head)
M.equip_to_slot_or_del(new /obj/item/device/radio/headset(M), slot_ears)
M.equip_to_slot_or_del(new /obj/item/clothing/suit/armor/vest(M), slot_wear_suit)
M.equip_to_slot_or_del(new /obj/item/clothing/mask/gas(M),slot_wear_mask)
M.put_in_hands_or_del(sword)
if("assistant")
M.equip_to_slot_or_del(new /obj/item/clothing/under/color/grey(M), slot_w_uniform)
M.equip_to_slot_or_del(new /obj/item/device/radio/headset(M), slot_ears)
M.equip_to_slot_or_del(new /obj/item/clothing/shoes/sneakers/black(M), slot_shoes)
M.put_in_hands_or_del(sword)
if("animu")
M.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal(M), slot_shoes)
M.equip_to_slot_or_del(new /obj/item/device/radio/headset(M), slot_ears)
M.equip_to_slot_or_del(new /obj/item/clothing/head/kitty(M), slot_head)
M.equip_to_slot_or_del(new /obj/item/clothing/under/schoolgirl/red(M), slot_w_uniform)
M.put_in_hands_or_del(sword)
if("cultist")
M.equip_to_slot_or_del(new /obj/item/clothing/head/culthood/alt(M), slot_head)
M.equip_to_slot_or_del(new /obj/item/clothing/suit/cultrobes/alt(M), slot_wear_suit)
M.equip_to_slot_or_del(new /obj/item/clothing/shoes/cult(M), slot_shoes)
M.equip_to_slot_or_del(new /obj/item/device/radio/headset(M), slot_ears)
M.put_in_hands_or_del(sword)
if("highlander")
M.equip_to_slot_or_del(new /obj/item/clothing/under/kilt(M), slot_w_uniform)
M.equip_to_slot_or_del(new /obj/item/device/radio/headset(M), slot_ears)
M.equip_to_slot_or_del(new /obj/item/clothing/head/beret(M), slot_head)
M.equip_to_slot_or_del(new /obj/item/clothing/shoes/combat(M), slot_shoes)
M.put_in_hands_or_del(sword)
if("clown")
M.equip_to_slot_or_del(new /obj/item/clothing/under/rank/clown(M), slot_w_uniform)
M.equip_to_slot_or_del(new /obj/item/device/radio/headset(M), slot_ears)
M.equip_to_slot_or_del(new /obj/item/clothing/shoes/clown_shoes(M), slot_shoes)
M.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/clown_hat(M), slot_wear_mask)
M.equip_to_slot_or_del(new /obj/item/weapon/bikehorn(M), slot_l_store)
M.put_in_hands_or_del(sword)
if("killer")
M.equip_to_slot_or_del(new /obj/item/clothing/under/overalls(M), slot_w_uniform)
M.equip_to_slot_or_del(new /obj/item/clothing/shoes/sneakers/white(M), slot_shoes)
M.equip_to_slot_or_del(new /obj/item/clothing/gloves/color/latex(M), slot_gloves)
M.equip_to_slot_or_del(new /obj/item/clothing/mask/surgical(M), slot_wear_mask)
M.equip_to_slot_or_del(new /obj/item/clothing/head/welding(M), slot_head)
M.equip_to_slot_or_del(new /obj/item/device/radio/headset(M), slot_ears)
M.equip_to_slot_or_del(new /obj/item/clothing/suit/apron(M), slot_wear_suit)
M.equip_to_slot_or_del(new /obj/item/weapon/kitchen/knife(M), slot_l_store)
M.equip_to_slot_or_del(new /obj/item/weapon/scalpel(M), slot_r_store)
M.put_in_hands_or_del(sword)
for(var/obj/item/carried_item in M.get_equipped_items())
carried_item.add_mob_blood(M)
for(var/obj/item/I in M.held_items)
I.add_mob_blood(M)
if("pirate")
M.equip_to_slot_or_del(new /obj/item/clothing/under/pirate(M), slot_w_uniform)
M.equip_to_slot_or_del(new /obj/item/clothing/shoes/sneakers/brown(M), slot_shoes)
M.equip_to_slot_or_del(new /obj/item/clothing/head/bandana(M), slot_head)
M.equip_to_slot_or_del(new /obj/item/clothing/glasses/eyepatch(M), slot_glasses)
M.equip_to_slot_or_del(new /obj/item/device/radio/headset(M), slot_ears)
M.put_in_hands_or_del(sword)
if("soviet")
M.equip_to_slot_or_del(new /obj/item/clothing/head/pirate/captain(M), slot_head)
M.equip_to_slot_or_del(new /obj/item/clothing/shoes/combat(M), slot_shoes)
M.equip_to_slot_or_del(new /obj/item/clothing/gloves/combat(M), slot_gloves)
M.equip_to_slot_or_del(new /obj/item/device/radio/headset(M), slot_ears)
M.equip_to_slot_or_del(new /obj/item/clothing/suit/pirate/captain(M), slot_wear_suit)
M.equip_to_slot_or_del(new /obj/item/clothing/under/soviet(M), slot_w_uniform)
M.put_in_hands_or_del(sword)
if("officer")
M.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/beret(M), slot_head)
M.equip_to_slot_or_del(new /obj/item/clothing/shoes/combat(M), slot_shoes)
M.equip_to_slot_or_del(new /obj/item/clothing/gloves/combat(M), slot_gloves)
M.equip_to_slot_or_del(new /obj/item/clothing/mask/cigarette/cigar/havana(M), slot_wear_mask)
M.equip_to_slot_or_del(new /obj/item/device/radio/headset(M), slot_ears)
M.equip_to_slot_or_del(new /obj/item/clothing/suit/jacket/miljacket(M), slot_wear_suit)
M.equip_to_slot_or_del(new /obj/item/clothing/under/syndicate(M), slot_w_uniform)
M.equip_to_slot_or_del(new /obj/item/clothing/glasses/eyepatch(M), slot_glasses)
M.put_in_hands_or_del(sword)
if("gladiator")
M.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/gladiator(M), slot_head)
M.equip_to_slot_or_del(new /obj/item/clothing/under/gladiator(M), slot_w_uniform)
M.equip_to_slot_or_del(new /obj/item/device/radio/headset(M), slot_ears)
M.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal(M), slot_shoes)
M.put_in_hands_or_del(sword)
else
return
M.update_body_parts()
var/obj/item/weapon/card/id/W = new /obj/item/weapon/card/id
W.icon_state = "centcom"
W.access += GLOB.access_maint_tunnels
W.assignment = "Multiverse Traveller"
W.registered_name = M.real_name
W.update_label(M.real_name)
M.equip_to_slot_or_del(W, slot_wear_id)
/obj/item/voodoo
name = "wicker doll"
desc = "Something creepy about it."
icon = 'icons/obj/wizard.dmi'
icon_state = "voodoo"
item_state = "electronic"
var/mob/living/carbon/human/target = null
var/list/mob/living/carbon/human/possible = list()
var/obj/item/link = null
var/cooldown_time = 30 //3s
var/cooldown = 0
obj_integrity = 10
max_integrity = 10
resistance_flags = FLAMMABLE
/obj/item/voodoo/attackby(obj/item/I, mob/user, params)
if(target && cooldown < world.time)
if(I.is_hot())
to_chat(target, "<span class='userdanger'>You suddenly feel very hot</span>")
target.bodytemperature += 50
GiveHint(target)
else if(is_pointed(I))
to_chat(target, "<span class='userdanger'>You feel a stabbing pain in [parse_zone(user.zone_selected)]!</span>")
target.Weaken(2)
GiveHint(target)
else if(istype(I,/obj/item/weapon/bikehorn))
to_chat(target, "<span class='userdanger'>HONK</span>")
target << 'sound/items/AirHorn.ogg'
target.adjustEarDamage(0,3)
GiveHint(target)
cooldown = world.time +cooldown_time
return
if(!link)
if(I.loc == user && istype(I) && I.w_class <= WEIGHT_CLASS_SMALL)
user.drop_item()
I.loc = src
link = I
to_chat(user, "You attach [I] to the doll.")
update_targets()
/obj/item/voodoo/check_eye(mob/user)
if(loc != user)
user.reset_perspective(null)
user.unset_machine()
/obj/item/voodoo/attack_self(mob/user)
if(!target && possible.len)
target = input(user, "Select your victim!", "Voodoo") as null|anything in possible
return
if(user.zone_selected == "chest")
if(link)
target = null
link.loc = get_turf(src)
to_chat(user, "<span class='notice'>You remove the [link] from the doll.</span>")
link = null
update_targets()
return
if(target && cooldown < world.time)
switch(user.zone_selected)
if("mouth")
var/wgw = sanitize(input(user, "What would you like the victim to say", "Voodoo", null) as text)
target.say(wgw)
log_game("[user][user.key] made [target][target.key] say [wgw] with a voodoo doll.")
if("eyes")
user.set_machine(src)
user.reset_perspective(target)
spawn(100)
user.reset_perspective(null)
user.unset_machine()
if("r_leg","l_leg")
to_chat(user, "<span class='notice'>You move the doll's legs around.</span>")
var/turf/T = get_step(target,pick(GLOB.cardinal))
target.Move(T)
if("r_arm","l_arm")
target.click_random_mob()
GiveHint(target)
if("head")
to_chat(user, "<span class='notice'>You smack the doll's head with your hand.</span>")
target.Dizzy(10)
to_chat(target, "<span class='warning'>You suddenly feel as if your head was hit with a hammer!</span>")
GiveHint(target,user)
if("groin")
if(target.canbearoused)
to_chat(user, "<span class='notice'>You rub the groin on [src]. You're weird.</span>")
target.adjustArousalLoss(5)
to_chat(target, "<span class='warning'>You suddenly feel hot... and quite </span><span class='notice'><i>good</i></span>")
if(prob(33))
target.emote(pick("moan","blush"))
GiveHint(target, user)
cooldown = world.time + cooldown_time
/obj/item/voodoo/proc/update_targets()
possible = list()
if(!link)
return
for(var/mob/living/carbon/human/H in GLOB.living_mob_list)
if(md5(H.dna.uni_identity) in link.fingerprints)
possible |= H
/obj/item/voodoo/proc/GiveHint(mob/victim,force=0)
if(prob(50) || force)
var/way = dir2text(get_dir(victim,get_turf(src)))
to_chat(victim, "<span class='notice'>You feel a dark presence from [way]</span>")
if(prob(20) || force)
var/area/A = get_area(src)
to_chat(victim, "<span class='notice'>You feel a dark presence from [A.name]</span>")
/obj/item/voodoo/fire_act(exposed_temperature, exposed_volume)
if(target)
target.adjust_fire_stacks(20)
target.IgniteMob()
GiveHint(target,1)
return ..()
//Provides a decent heal, need to pump every 6 seconds
/obj/item/organ/heart/cursed/wizard
pump_delay = 60
heal_brute = 25
heal_burn = 25
heal_oxy = 25
//Warp Whistle: Provides uncontrolled long distance teleportation.
/obj/item/warpwhistle
name = "warp whistle"
desc = "One toot on this whistle will send you to a far away land!"
icon = 'icons/obj/wizard.dmi'
icon_state = "whistle"
var/on_cooldown = 0 //0: usable, 1: in use, 2: on cooldown
var/mob/living/carbon/last_user
/obj/item/warpwhistle/proc/interrupted(mob/living/carbon/user)
if(!user || QDELETED(src))
on_cooldown = FALSE
return TRUE
return FALSE
/obj/item/warpwhistle/attack_self(mob/living/carbon/user)
if(!istype(user) || on_cooldown)
return
on_cooldown = TRUE
last_user = user
var/turf/T = get_turf(user)
playsound(T,'sound/magic/WarpWhistle.ogg', 200, 1)
user.canmove = 0
new /obj/effect/overlay/temp/tornado(T)
sleep(20)
if(interrupted(user))
return
user.invisibility = INVISIBILITY_MAXIMUM
user.status_flags |= GODMODE
sleep(20)
if(interrupted(user))
return
var/breakout = 0
while(breakout < 50)
var/turf/potential_T = find_safe_turf()
if(T.z != potential_T.z || abs(get_dist_euclidian(potential_T,T)) > 50 - breakout)
user.forceMove(potential_T)
user.canmove = 0
T = potential_T
break
breakout += 1
new /obj/effect/overlay/temp/tornado(T)
sleep(20)
if(interrupted(user))
return
user.invisibility = initial(user.invisibility)
user.status_flags &= ~GODMODE
user.canmove = 1
on_cooldown = 2
sleep(40)
on_cooldown = 0
/obj/item/warpwhistle/Destroy()
if(on_cooldown == 1 && last_user) //Flute got dunked somewhere in the teleport
last_user.invisibility = initial(last_user.invisibility)
last_user.status_flags &= ~GODMODE
last_user.canmove = 1
return ..()
/obj/effect/overlay/temp/tornado
icon = 'icons/obj/wizard.dmi'
icon_state = "tornado"
name = "tornado"
desc = "This thing sucks!"
layer = FLY_LAYER
randomdir = 0
duration = 40
pixel_x = 500
/obj/effect/overlay/temp/tornado/New(loc)
..()
animate(src, pixel_x = -500, time = 40)
+1 -1
View File
@@ -253,7 +253,7 @@
/datum/spellbook_entry/the_traps
name = "The Traps!"
spell_type = /obj/effect/proc_holder/spell/aoe_turf/conjure/the_traps
category = "Offensive"
category = "Defensive"
cost = 1
+25 -12
View File
@@ -4,7 +4,21 @@
icon = 'goon/icons/obj/goon_terminals.dmi'
idle_power_usage = 100
var/siphoning = FALSE
var/last_warning = 0
var/next_warning = 0
var/obj/item/device/radio/radio
var/radio_channel = "Common"
var/minimum_time_between_warnings = 400
/obj/machinery/computer/bank_machine/Initialize(mapload)
..()
radio = new(src)
radio.subspace_transmission = TRUE
radio.canhear_range = 0
radio.recalculateChannels()
/obj/machinery/computer/bank_machine/Destroy()
QDEL_NULL(radio)
. = ..()
/obj/machinery/computer/bank_machine/attackby(obj/item/I, mob/user)
var/value = 0
@@ -32,18 +46,17 @@
say("Station funds depleted. Halting siphon.")
siphoning = FALSE
else
var/obj/item/stack/spacecash/c200/on_turf = locate() in src.loc
if(on_turf && on_turf.amount < on_turf.max_amount)
on_turf.amount++
else
new /obj/item/stack/spacecash/c200(get_turf(src))
new /obj/item/stack/spacecash/c200(get_turf(src)) // will autostack
playsound(src.loc, 'sound/items/poster_being_created.ogg', 100, 1)
SSshuttle.points -= 200
if(last_warning < world.time && prob(15))
if(next_warning < world.time && prob(15))
var/area/A = get_area(loc)
minor_announce("Unauthorized credit withdrawal underway in [A.map_name]." , "Network Breach", TRUE)
last_warning = world.time + 400
var/message = "Unauthorized credit withdrawal underway in [A.map_name]!!"
radio.talk_into(src, message, radio_channel, get_spans())
next_warning = world.time + minimum_time_between_warnings
/obj/machinery/computer/bank_machine/get_spans()
. = ..() | SPAN_ROBOT
/obj/machinery/computer/bank_machine/attack_hand(mob/user)
if(..())
@@ -67,8 +80,8 @@
if(..())
return
if(href_list["siphon"])
say("<span class='warning'>Siphon of station credits has begun!</span>")
say("Siphon of station credits has begun!")
siphoning = TRUE
if(href_list["halt"])
say("<span class='warning'>Station credit withdrawal halted.</span>")
siphoning = FALSE
say("Station credit withdrawal halted.")
siphoning = FALSE
+5 -8
View File
@@ -204,11 +204,13 @@
clonemind.transfer_to(H)
H.grab_ghost()
to_chat(H, "<span class='notice'><b>Consciousness slowly creeps over you as your body regenerates.</b><br><i>So this is what cloning feels like?</i></span>")
if(grab_ghost_when == CLONER_FRESH_CLONE)
H.grab_ghost()
to_chat(H, "<span class='notice'><b>Consciousness slowly creeps over you as your body regenerates.</b><br><i>So this is what cloning feels like?</i></span>")
if(grab_ghost_when == CLONER_MATURE_CLONE)
addtimer(CALLBACK(src, .proc/occupant_dreams), 100)
H.ghostize(TRUE) //Only does anything if they were still in their old body and not already a ghost
to_chat(H.get_ghost(TRUE), "<span class='notice'>Your body is beginning to regenerate in a cloning pod. You will become conscious when it is complete.</span>")
if(H)
H.faction |= factions
@@ -219,11 +221,6 @@
attempting = FALSE
return TRUE
/obj/machinery/clonepod/proc/occupant_dreams()
if(occupant)
to_chat(occupant, "<span class='revennotice'>While your body grows, you have the strangest dream, like you can see yourself from the outside.</span>")
occupant.ghostize(TRUE)
//Grow clones to maturity then kick them out. FREELOADERS
/obj/machinery/clonepod/process()
+1 -1
View File
@@ -108,7 +108,7 @@
if(!authenticated) //Check for emags
var/obj/item/weapon/card/emag/E = usr.get_active_held_item()
if(E && istype(E) && usr.Adjacent(src))
usr << "<span class='warning'>You bypass [src]'s access requirements using your emag.</span>"
to_chat(usr, "<span class='warning'>You bypass [src]'s access requirements using your emag.</span>")
authenticated = TRUE
log_activity("logged in") //Auth ID doesn't change, hinting that it was illicit
if(href_list["log_out"])
@@ -304,17 +304,17 @@
build_path = /obj/machinery/computer/gulag_teleporter_computer
/obj/item/weapon/circuitboard/computer/rdconsole
name = "RD Console (Computer Board)"
name = "R&D Console (Computer Board)"
build_path = /obj/machinery/computer/rdconsole/core
/obj/item/weapon/circuitboard/computer/rdconsole/attackby(obj/item/I, mob/user, params)
if(istype(I,/obj/item/weapon/screwdriver))
if(build_path == /obj/machinery/computer/rdconsole/core)
name = "RD Console - Robotics (Computer Board)"
name = "R&D Console - Robotics (Computer Board)"
build_path = /obj/machinery/computer/rdconsole/robotics
to_chat(user, "<span class='notice'>Access protocols successfully updated.</span>")
else
name = "RD Console (Computer Board)"
name = "R&D Console (Computer Board)"
build_path = /obj/machinery/computer/rdconsole/core
to_chat(user, "<span class='notice'>Defaulting access protocols.</span>")
else
+1 -1
View File
@@ -532,7 +532,7 @@ GLOBAL_VAR_INIT(time_last_changed_position, 0)
else
SSjob.prioritized_jobs += j
prioritycount++
usr << "<span class='notice'>[j.title] has been successfully [priority ? "prioritized" : "unprioritized"]. Potential employees will notice your request.</span>"
to_chat(usr, "<span class='notice'>[j.title] has been successfully [priority ? "prioritized" : "unprioritized"]. Potential employees will notice your request.</span>")
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
if ("print")
+12 -10
View File
@@ -455,14 +455,16 @@
name = "monitor decryption key"
var/obj/machinery/message_server/server = null
/obj/item/weapon/paper/monitorkey/New()
/obj/item/weapon/paper/monitorkey/Initialize()
..()
spawn(10)
if(GLOB.message_servers)
for(var/obj/machinery/message_server/server in GLOB.message_servers)
if(!isnull(server))
if(!isnull(server.decryptkey))
info = "<center><h2>Daily Key Reset</h2></center><br>The new message monitor key is '[server.decryptkey]'.<br>Please keep this a secret and away from the clown.<br>If necessary, change the password to a more secure one."
info_links = info
add_overlay("paper_words")
break
return INITIALIZE_HINT_LATELOAD
/obj/item/weapon/paper/monitorkey/LateInitialize()
if(GLOB.message_servers)
for(var/obj/machinery/message_server/server in GLOB.message_servers)
if(!isnull(server))
if(!isnull(server.decryptkey))
info = "<center><h2>Daily Key Reset</h2></center><br>The new message monitor key is '[server.decryptkey]'.<br>Please keep this a secret and away from the clown.<br>If necessary, change the password to a more secure one."
info_links = info
add_overlay("paper_words")
break
+21 -16
View File
@@ -13,8 +13,6 @@
var/list/rangers = list()
var/charge = 35
var/stop = 0
var/list/available = list()
var/list/select_name = list()
var/list/spotlights = list()
var/list/sparkles = list()
var/static/list/songs = list(
@@ -30,6 +28,7 @@
var/song_path = null
var/song_length = 0
var/song_beat = 0
var/GBP_required = 0
/datum/track/New(name, path, length, beat)
song_name = name
@@ -37,6 +36,19 @@
song_length = length
song_beat = beat
/obj/machinery/disco/proc/add_track(file, name, length, beat)
var/sound/S = file
if(!istype(S))
return
if(!name)
name = "[file]"
if(!beat)
beat = 5
if(!length)
length = 2400 //Unless there's a way to discern via BYOND.
var/datum/track/T = new /datum/track(name, file, length, beat)
songs += T
/obj/machinery/disco/Initialize()
..()
selection = songs[1]
@@ -126,14 +138,14 @@
if(active)
to_chat(usr, "<span class='warning'>Error: You cannot change the song until the current one is over.</span>")
return
check_GBP()
select_name = input(usr, "Choose your song", "Track:") as null|anything in available
if (QDELETED(src))
return
var/list/available = list()
for(var/datum/track/S in songs)
if(select_name == S.song_name)
selection = S
break
available[S.song_name] = S
var/selected = input(usr, "Choose your song", "Track:") as null|anything in available
if(QDELETED(src) || !selected || !istype(available[selected], /datum/track))
return
selection = available[selected]
updateUsrDialog()
if("horn")
deejay('sound/items/AirHorn2.ogg')
@@ -159,13 +171,6 @@
charge -= 5
playsound(src, S,300,1)
/obj/machinery/disco/proc/check_GBP()
available |= "Engineering's Basic Beat"
available |= "Engineering's Domination Dance"
available |= "Engineering's Superiority Shimmy"
available |= "Engineering's Ultimate High-Energy Hustle"
/obj/machinery/disco/proc/dance_setup()
stop = world.time + selection.song_length
var/turf/cen = get_turf(src)
@@ -19,12 +19,12 @@
/obj/machinery/doorButtons/proc/findObjsByTag()
return
/obj/machinery/doorButtons/Initialize(mapload)
if(mapload)
..()
return TRUE
else
findObjsByTag()
/obj/machinery/doorButtons/Initialize()
..()
return INITIALIZE_HINT_LATELOAD
/obj/machinery/doorButtons/LateInitialize()
findObjsByTag()
/obj/machinery/doorButtons/emag_act(mob/user)
if(!emagged)
+1 -1
View File
@@ -200,7 +200,7 @@
if(beaker.reagents && beaker.reagents.reagent_list.len)
to_chat(usr, "<span class='notice'>Attached is \a [beaker] with [beaker.reagents.total_volume] units of liquid.</span>")
else
to_chat(usr, "<span class='notice'>Attached is an empty [beaker].</span>")
to_chat(usr, "<span class='notice'>Attached is an empty [beaker.name].</span>")
else
to_chat(usr, "<span class='notice'>No chemicals are attached.</span>")
Regular → Executable
+5 -2
View File
@@ -61,7 +61,7 @@
G.loc = src
charging = G
use_power = 2
update_icon()
update_icon(scan = TRUE)
else
to_chat(user, "<span class='notice'>[src] isn't connected to anything!</span>")
return 1
@@ -162,10 +162,13 @@
..()
/obj/machinery/recharger/update_icon(using_power = 0) //we have an update_icon() in addition to the stuff in process to make it feel a tiny bit snappier.
/obj/machinery/recharger/update_icon(using_power = 0, scan) //we have an update_icon() in addition to the stuff in process to make it feel a tiny bit snappier.
if(stat & (NOPOWER|BROKEN) || !anchored)
icon_state = "rechargeroff"
return
if(scan)
icon_state = "rechargeroff"
return
if(panel_open)
icon_state = "rechargeropen"
return
+4 -4
View File
@@ -439,12 +439,12 @@ GLOBAL_LIST_EMPTY(allConsoles)
updateUsrDialog()
return
/obj/machinery/requests_console/say_quote(input, list/spans, message_mode)
/obj/machinery/requests_console/say_mod(input, message_mode)
var/ending = copytext(input, length(input) - 2)
if (ending == "!!!")
return "blares, \"[attach_spans(input, spans)]\""
return ..()
. = "blares"
else
. = ..()
/obj/machinery/requests_console/proc/clear_emergency()
emergency = null
+3 -2
View File
@@ -732,7 +732,8 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C
icon_state = "sustenance"
products = list(/obj/item/weapon/reagent_containers/food/snacks/tofu = 24,
/obj/item/weapon/reagent_containers/food/drinks/ice = 12,
/obj/item/weapon/reagent_containers/food/snacks/candy_corn = 6)
/obj/item/weapon/reagent_containers/food/snacks/candy_corn = 6,
/obj/item/weapon/reagent_containers/glass/beaker/waterbottle = 10)
contraband = list(/obj/item/weapon/kitchen/knife = 6,
/obj/item/weapon/reagent_containers/food/drinks/coffee = 12,
/obj/item/weapon/tank/internals/emergency_oxygen = 6,
@@ -749,7 +750,7 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C
products = list(/obj/item/weapon/reagent_containers/food/drinks/soda_cans/cola = 10,/obj/item/weapon/reagent_containers/food/drinks/soda_cans/space_mountain_wind = 10,
/obj/item/weapon/reagent_containers/food/drinks/soda_cans/dr_gibb = 10,/obj/item/weapon/reagent_containers/food/drinks/soda_cans/starkist = 10,
/obj/item/weapon/reagent_containers/food/drinks/soda_cans/space_up = 10,/obj/item/weapon/reagent_containers/food/drinks/soda_cans/pwr_game = 10,
/obj/item/weapon/reagent_containers/food/drinks/soda_cans/lemon_lime = 10)
/obj/item/weapon/reagent_containers/food/drinks/soda_cans/lemon_lime = 10,/obj/item/weapon/reagent_containers/glass/beaker/waterbottle = 10)
contraband = list(/obj/item/weapon/reagent_containers/food/drinks/soda_cans/thirteenloko = 6,/obj/item/weapon/reagent_containers/food/drinks/soda_cans/shamblers = 6)
premium = list(/obj/item/weapon/reagent_containers/food/drinks/drinkingglass/filled/nuka_cola = 1,/obj/item/weapon/reagent_containers/food/drinks/soda_cans/air = 1)
refill_canister = /obj/item/weapon/vending_refill/cola
+10
View File
@@ -0,0 +1,10 @@
diff a/code/game/objects/items.dm b/code/game/objects/items.dm (rejected hunks)
@@ -102,7 +102,7 @@ var/global/image/fire_overlay = image("icon" = 'icons/effects/fire.dmi', "icon_s
/obj/item/Initialize()
if (!materials)
materials = list()
- ..()
+ . = ..()
for(var/path in actions_types)
new path(src)
actions_types = null
+2
View File
@@ -465,11 +465,13 @@
icon_state = "crayonblack"
paint_color = "#1C1C1C" //Not completely black because total black looks bad. So Mostly Black.
item_color = "black"
reagent_contents = list("nutriment" = 1, "blackcrayonpowder" = 1)
/obj/item/toy/crayon/white
icon_state = "crayonwhite"
paint_color = "#FFFFFF"
item_color = "white"
reagent_contents = list("nutriment" = 1, "whitecrayonpowder" = 1)
/obj/item/toy/crayon/mime
icon_state = "crayonmime"
@@ -19,10 +19,10 @@
var/threatscale = 1 // Used by advanced grenades to make them slightly more worthy.
var/no_splash = FALSE //If the grenade deletes even if it has no reagents to splash with. Used for slime core reactions.
/obj/item/weapon/grenade/chem_grenade/New()
/obj/item/weapon/grenade/chem_grenade/Initialize()
. = ..()
create_reagents(1000)
stage_change() // If no argument is set, it will change the stage to the current stage, useful for stock grenades that start READY.
..()
/obj/item/weapon/grenade/chem_grenade/examine(mob/user)
display_timer = (stage == READY && !nadeassembly) //show/hide the timer based on assembly state
@@ -313,8 +313,8 @@
desc = "Used for emergency sealing of air breaches."
stage = READY
/obj/item/weapon/grenade/chem_grenade/metalfoam/New()
..()
/obj/item/weapon/grenade/chem_grenade/metalfoam/Initialize()
. = ..()
var/obj/item/weapon/reagent_containers/glass/beaker/B1 = new(src)
var/obj/item/weapon/reagent_containers/glass/beaker/B2 = new(src)
@@ -331,8 +331,8 @@
desc = "Used for clearing rooms of living things."
stage = READY
/obj/item/weapon/grenade/chem_grenade/incendiary/New()
..()
/obj/item/weapon/grenade/chem_grenade/incendiary/Initialize()
. = ..()
var/obj/item/weapon/reagent_containers/glass/beaker/B1 = new(src)
var/obj/item/weapon/reagent_containers/glass/beaker/B2 = new(src)
@@ -349,8 +349,8 @@
desc = "Used for purging large areas of invasive plant species. Contents under pressure. Do not directly inhale contents."
stage = READY
/obj/item/weapon/grenade/chem_grenade/antiweed/New()
..()
/obj/item/weapon/grenade/chem_grenade/antiweed/Initialize()
. = ..()
var/obj/item/weapon/reagent_containers/glass/beaker/B1 = new(src)
var/obj/item/weapon/reagent_containers/glass/beaker/B2 = new(src)
@@ -368,8 +368,8 @@
desc = "BLAM!-brand foaming space cleaner. In a special applicator for rapid cleaning of wide areas."
stage = READY
/obj/item/weapon/grenade/chem_grenade/cleaner/New()
..()
/obj/item/weapon/grenade/chem_grenade/cleaner/Initialize()
. = ..()
var/obj/item/weapon/reagent_containers/glass/beaker/B1 = new(src)
var/obj/item/weapon/reagent_containers/glass/beaker/B2 = new(src)
@@ -386,8 +386,8 @@
desc = "Waffle Co.-brand foaming space cleaner. In a special applicator for rapid cleaning of wide areas."
stage = READY
/obj/item/weapon/grenade/chem_grenade/ez_clean/New()
..()
/obj/item/weapon/grenade/chem_grenade/ez_clean/Initialize()
. = ..()
var/obj/item/weapon/reagent_containers/glass/beaker/large/B1 = new(src)
var/obj/item/weapon/reagent_containers/glass/beaker/large/B2 = new(src)
@@ -405,8 +405,8 @@
desc = "Used for nonlethal riot control. Contents under pressure. Do not directly inhale contents."
stage = READY
/obj/item/weapon/grenade/chem_grenade/teargas/New()
..()
/obj/item/weapon/grenade/chem_grenade/teargas/Initialize()
. = ..()
var/obj/item/weapon/reagent_containers/glass/beaker/large/B1 = new(src)
var/obj/item/weapon/reagent_containers/glass/beaker/large/B2 = new(src)
@@ -424,8 +424,8 @@
desc = "Used for melting armoured opponents."
stage = READY
/obj/item/weapon/grenade/chem_grenade/facid/New()
..()
/obj/item/weapon/grenade/chem_grenade/facid/Initialize()
. = ..()
var/obj/item/weapon/reagent_containers/glass/beaker/bluespace/B1 = new(src)
var/obj/item/weapon/reagent_containers/glass/beaker/bluespace/B2 = new(src)
@@ -444,8 +444,8 @@
desc = "Used for wide scale painting projects."
stage = READY
/obj/item/weapon/grenade/chem_grenade/colorful/New()
..()
/obj/item/weapon/grenade/chem_grenade/colorful/Initialize()
. = ..()
var/obj/item/weapon/reagent_containers/glass/beaker/B1 = new(src)
var/obj/item/weapon/reagent_containers/glass/beaker/B2 = new(src)
@@ -463,8 +463,8 @@
stage = READY
var/glitter_type = "glitter"
/obj/item/weapon/grenade/chem_grenade/glitter/New()
..()
/obj/item/weapon/grenade/chem_grenade/glitter/Initialize()
. = ..()
var/obj/item/weapon/reagent_containers/glass/beaker/B1 = new(src)
var/obj/item/weapon/reagent_containers/glass/beaker/B2 = new(src)
@@ -496,8 +496,8 @@
desc = "BURN!-brand foaming clf3. In a special applicator for rapid purging of wide areas."
stage = READY
/obj/item/weapon/grenade/chem_grenade/clf3/New()
..()
/obj/item/weapon/grenade/chem_grenade/clf3/Initialize()
. = ..()
var/obj/item/weapon/reagent_containers/glass/beaker/bluespace/B1 = new(src)
var/obj/item/weapon/reagent_containers/glass/beaker/bluespace/B2 = new(src)
@@ -514,8 +514,8 @@
desc = "Tiger Cooperative chemical foam grenade. Causes temporary irration, blindness, confusion, mutism, and mutations to carbon based life forms. Contains additional spore toxin"
stage = READY
/obj/item/weapon/grenade/chem_grenade/bioterrorfoam/New()
..()
/obj/item/weapon/grenade/chem_grenade/bioterrorfoam/Initialize()
. = ..()
var/obj/item/weapon/reagent_containers/glass/beaker/bluespace/B1 = new(src)
var/obj/item/weapon/reagent_containers/glass/beaker/bluespace/B2 = new(src)
@@ -534,8 +534,8 @@
desc = "WARNING: GRENADE WILL RELEASE DEADLY SPORES CONTAINING ACTIVE AGENTS. SEAL SUIT AND AIRFLOW BEFORE USE."
stage = READY
/obj/item/weapon/grenade/chem_grenade/tuberculosis/New()
..()
/obj/item/weapon/grenade/chem_grenade/tuberculosis/Initialize()
. = ..()
var/obj/item/weapon/reagent_containers/glass/beaker/bluespace/B1 = new(src)
var/obj/item/weapon/reagent_containers/glass/beaker/bluespace/B2 = new(src)
@@ -87,7 +87,7 @@
var/mob/living/silicon/robot/R = user
if(shock)
user <<"<span class='notice'>You clear all active holograms, and reset your projector to normal.</span>"
to_chat(user, "<span class='notice'>You clear all active holograms, and reset your projector to normal.</span>")
holosign_type = /obj/structure/holosign/barrier/cyborg
creation_time = 5
if(signs.len)
@@ -96,7 +96,7 @@
shock = 0
return
else if(R.emagged&&!shock)
user <<"<span class='warning'>You clear all active holograms, and overload your energy projector!</span>"
to_chat(user, "<span class='warning'>You clear all active holograms, and overload your energy projector!</span>")
holosign_type = /obj/structure/holosign/barrier/cyborg/hacked
creation_time = 30
if(signs.len)
+2 -2
View File
@@ -60,9 +60,9 @@
/obj/item/weapon/melee/baton/examine(mob/user)
..()
if(bcell)
user <<"<span class='notice'>The baton is [round(bcell.percent())]% charged.</span>"
to_chat(user, "<span class='notice'>The baton is [round(bcell.percent())]% charged.</span>")
else
user <<"<span class='warning'>The baton does not have a power source installed.</span>"
to_chat(user, "<span class='warning'>The baton does not have a power source installed.</span>")
/obj/item/weapon/melee/baton/attackby(obj/item/weapon/W, mob/user, params)
if(istype(W, /obj/item/weapon/stock_parts/cell))
@@ -116,7 +116,7 @@
var/mob/living/carbon/human/H = user
user.visible_message("<span class='suicide'>[user] is putting [src]'s valve to [user.p_their()] lips! It looks like [user.p_theyre()] trying to commit suicide!</span>")
playsound(loc, 'sound/effects/spray.ogg', 10, 1, -3)
if (H && !QDELETED(H))
if (!QDELETED(H) && air_contents && air_contents.return_pressure() >= 1000)
for(var/obj/item/W in H)
H.dropItemToGround(W)
if(prob(50))
+1 -1
View File
@@ -37,7 +37,7 @@
..()
/obj/Initialize()
..()
. = ..()
if (!armor)
armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 0, acid = 0)
if(on_blueprints && isturf(loc))
+3 -3
View File
@@ -115,7 +115,7 @@
update_icon()
return
if(locked)
user <<"<span class='warning'> The [name] won't budge!</span>"
to_chat(user, "<span class='warning'>The [name] won't budge!</span>")
return
else
open = !open
@@ -131,7 +131,7 @@
/obj/structure/fireaxecabinet/attack_tk(mob/user)
if(locked)
user <<"<span class='warning'> The [name] won't budge!</span>"
to_chat(user, "<span class='warning'>The [name] won't budge!</span>")
return
else
open = !open
@@ -177,7 +177,7 @@
set src in oview(1)
if(locked)
usr <<"<span class='warning'> The [name] won't budge!</span>"
to_chat(usr, "<span class='warning'>The [name] won't budge!</span>")
return
else
open = !open
+4 -7
View File
@@ -14,18 +14,15 @@
/obj/structure/ladder/Initialize(mapload)
if(!initialized)
GLOB.ladders += src
..()
if(mapload)
return TRUE
update_link()
GLOB.ladders += src
..()
return INITIALIZE_HINT_LATELOAD
/obj/structure/ladder/Destroy()
GLOB.ladders -= src
. = ..()
/obj/structure/ladder/proc/update_link()
/obj/structure/ladder/LateInitialize()
for(var/obj/structure/ladder/L in GLOB.ladders)
if(L.id == id)
if(L.height == (height - 1))
+19 -4
View File
@@ -8,8 +8,10 @@
alpha = 30 //initially quite hidden when not "recharging"
var/last_trigger = 0
var/time_between_triggers = 600 //takes a minute to recharge
var/charges = INFINITY
var/list/static/ignore_typecache
var/list/mob/immune_minds = list()
var/datum/effect_system/spark_spread/spark_system
@@ -30,9 +32,11 @@
. = ..()
/obj/structure/trap/examine(mob/user)
..()
. = ..()
if(!isliving(user))
return
if(user.mind && user.mind in immune_minds)
return
if(get_dist(user, src) <= 1)
to_chat(user, "<span class='notice'>You reveal [src]!</span>")
flare()
@@ -41,10 +45,15 @@
// Makes the trap visible, and starts the cooldown until it's
// able to be triggered again.
visible_message("<span class='warning'>[src] flares brightly!</span>")
alpha = 200
animate(src, alpha = initial(alpha), time = time_between_triggers)
last_trigger = world.time
spark_system.start()
alpha = 200
last_trigger = world.time
charges--
if(charges <= 0)
animate(src, alpha = 0, time = 10)
QDEL_IN(src, 10)
else
animate(src, alpha = initial(alpha), time = time_between_triggers)
/obj/structure/trap/Crossed(atom/movable/AM)
if(last_trigger + time_between_triggers > world.time)
@@ -52,6 +61,12 @@
// Don't want the traps triggered by sparks, ghosts or projectiles.
if(is_type_in_typecache(AM, ignore_typecache))
return
if(ismob(AM))
var/mob/M = AM
if(M.mind in immune_minds)
return
if(charges <= 0)
return
flare()
if(isliving(AM))
trap_effect(AM)
+27 -17
View File
@@ -56,10 +56,16 @@ GLOBAL_LIST_INIT(freqtospan, list(
var/namepart = "[speaker.GetVoice()][speaker.get_alt_name()]"
//End name span.
var/endspanpart = "</span>"
//Message
var/messagepart = " <span class='message'>[lang_treat(speaker, message_language, raw_message, spans, message_mode)]</span></span>"
return "[spanpart1][spanpart2][freqpart][compose_track_href(speaker, namepart)][namepart][compose_job(speaker, message_language, raw_message, radio_freq)][endspanpart][messagepart]"
//Message
var/messagepart = " <span class='message'>[lang_treat(speaker, message_language, raw_message, spans)]</span></span>"
var/languageicon = ""
var/datum/language/D = get_language_instance(message_language)
if(D.display_icon(src))
languageicon = "[D.get_icon()] "
return "[spanpart1][spanpart2][freqpart][languageicon][compose_track_href(speaker, namepart)][namepart][compose_job(speaker, message_language, raw_message, radio_freq)][endspanpart][messagepart]"
/atom/movable/proc/compose_track_href(atom/movable/speaker, message_langs, raw_message, radio_freq)
return ""
@@ -67,33 +73,37 @@ GLOBAL_LIST_INIT(freqtospan, list(
/atom/movable/proc/compose_job(atom/movable/speaker, message_langs, raw_message, radio_freq)
return ""
/atom/movable/proc/say_quote(input, list/spans=list(), message_mode)
if(!input)
return "says, \"...\"" //not the best solution, but it will stop a large number of runtimes. The cause is somewhere in the Tcomms code
/atom/movable/proc/say_mod(input, message_mode)
var/ending = copytext(input, length(input))
if(copytext(input, length(input) - 1) == "!!")
spans |= SPAN_YELL
return "[verb_yell], \"[attach_spans(input, spans)]\""
input = attach_spans(input, spans)
if(ending == "?")
return "[verb_ask], \"[input]\""
if(ending == "!")
return "[verb_exclaim], \"[input]\""
return verb_yell
else if(ending == "?")
return verb_ask
else if(ending == "!")
return verb_exclaim
else
return verb_say
return "[verb_say], \"[input]\""
/atom/movable/proc/say_quote(input, list/spans=list(), message_mode)
if(!input)
input = "..."
if(copytext(input, length(input) - 1) == "!!")
spans |= SPAN_YELL
var/spanned = attach_spans(input, spans)
return "[say_mod(input, message_mode)], \"[spanned]\""
/atom/movable/proc/lang_treat(atom/movable/speaker, datum/language/language, raw_message, list/spans, message_mode)
if(has_language(language))
var/atom/movable/AM = speaker.GetSource()
if(AM) //Basically means "if the speaker is virtual"
if(AM.verb_say != speaker.verb_say || AM.verb_ask != speaker.verb_ask || AM.verb_exclaim != speaker.verb_exclaim || AM.verb_yell != speaker.verb_yell) //If the saymod was changed
return speaker.say_quote(raw_message, spans, message_mode)
return AM.say_quote(raw_message, spans, message_mode)
else
return speaker.say_quote(raw_message, spans, message_mode)
else if(language)
var/atom/movable/AM = speaker.GetSource()
var/datum/language/D = new language
var/datum/language/D = get_language_instance(language)
raw_message = D.scramble(raw_message)
if(AM)
return AM.say_quote(raw_message, spans, message_mode)
+2
View File
@@ -42,6 +42,8 @@
if (opacity)
has_opaque_atom = TRUE
return INITIALIZE_HINT_NORMAL
/turf/open/space/attack_ghost(mob/dead/observer/user)
if(destination_z)
+1
View File
@@ -56,6 +56,7 @@
if (opacity)
has_opaque_atom = TRUE
return INITIALIZE_HINT_NORMAL
/turf/proc/Initalize_Atmos(times_fired)
CalculateAdjacentTurfs()