Merge branch 'master' of https://github.com/Citadel-Station-13/Citadel-Station-13 into upstream-merge-26974

This commit is contained in:
LetterJay
2017-05-17 05:06:23 -05:00
504 changed files with 16497 additions and 8255 deletions
+4 -3
View File
@@ -482,6 +482,7 @@
/datum/action/language_menu/Trigger()
if(!..())
return FALSE
if(isliving(owner))
var/mob/living/L = owner
L.open_language_menu(usr)
if(ismob(owner))
var/mob/M = owner
var/datum/language_holder/H = M.get_language_holder()
H.open_language_menu(usr)
+109 -11
View File
@@ -2,9 +2,55 @@
var/datum/action/innate/cultcomm/communion = new
/datum/antagonist/cult/Destroy()
qdel(communion)
QDEL_NULL(communion)
return ..()
/datum/antagonist/cult/proc/add_objectives()
var/list/target_candidates = list()
for(var/mob/living/carbon/human/player in GLOB.player_list)
if(player.mind && !player.mind.has_antag_datum(ANTAG_DATUM_CULT) && !is_convertable_to_cult(player) && (player != owner) && player.stat != DEAD)
target_candidates += player.mind
if(target_candidates.len == 0)
message_admins("Cult Sacrifice: Could not find unconvertable target, checking for convertable target.")
for(var/mob/living/carbon/human/player in GLOB.player_list)
if(player.mind && !player.mind.has_antag_datum(ANTAG_DATUM_CULT) && (player != owner) && player.stat != DEAD)
target_candidates += player.mind
listclearnulls(target_candidates)
if(LAZYLEN(target_candidates))
GLOB.sac_mind = pick(target_candidates)
if(!GLOB.sac_mind)
message_admins("Cult Sacrifice: ERROR - Null target chosen!")
else
var/datum/job/sacjob = SSjob.GetJob(GLOB.sac_mind.assigned_role)
var/datum/preferences/sacface = GLOB.sac_mind.current.client.prefs
var/icon/reshape = get_flat_human_icon(null, sacjob, sacface)
reshape.Shift(SOUTH, 4)
reshape.Shift(EAST, 1)
reshape.Crop(7,4,26,31)
reshape.Crop(-5,-3,26,30)
GLOB.sac_image = reshape
else
message_admins("Cult Sacrifice: Could not find unconvertable or convertable target. WELP!")
GLOB.sac_complete = TRUE
SSticker.mode.cult_objectives += "sacrifice"
SSticker.mode.cult_objectives += "eldergod"
/datum/antagonist/cult/proc/cult_memorization(datum/mind/cult_mind)
var/mob/living/current = cult_mind.current
for(var/obj_count = 1,obj_count <= SSticker.mode.cult_objectives.len,obj_count++)
var/explanation
switch(SSticker.mode.cult_objectives[obj_count])
if("sacrifice")
if(GLOB.sac_mind)
explanation = "Sacrifice [GLOB.sac_mind], the [GLOB.sac_mind.assigned_role] via invoking a Sacrifice rune with them on it and three acolytes around it."
else
explanation = "The veil has already been weakened here, proceed to the final objective."
if("eldergod")
explanation = "Summon Nar-Sie by invoking the rune 'Summon Nar-Sie' with nine acolytes on it. You must do this after sacrificing your target."
if(!silent)
to_chat(current, "<B>Objective #[obj_count]</B>: [explanation]")
cult_mind.memory += "<B>Objective #[obj_count]</B>: [explanation]<BR>"
/datum/antagonist/cult/can_be_owned(datum/mind/new_owner)
. = ..()
if(.)
@@ -12,14 +58,17 @@
/datum/antagonist/cult/on_gain()
. = ..()
SSticker.mode.cult += owner
var/mob/living/current = owner.current
if(!LAZYLEN(SSticker.mode.cult_objectives))
add_objectives()
SSticker.mode.cult += owner // Only add after they've been given objectives
cult_memorization(owner)
if(jobban_isbanned(current, ROLE_CULTIST))
addtimer(CALLBACK(SSticker.mode, /datum/game_mode.proc/replace_jobbaned_player, current, ROLE_CULTIST, ROLE_CULTIST), 0)
SSticker.mode.update_cult_icons_added(owner)
if(istype(SSticker.mode, /datum/game_mode/cult))
var/datum/game_mode/cult/C = SSticker.mode
C.memorize_cult_objectives(owner)
if(jobban_isbanned(owner.current, ROLE_CULTIST))
addtimer(CALLBACK(SSticker.mode, /datum/game_mode.proc/replace_jobbaned_player, owner.current, ROLE_CULTIST, ROLE_CULTIST), 0)
owner.current.log_message("<font color=#960000>Has been converted to the cult of Nar'Sie!</font>", INDIVIDUAL_ATTACK_LOG)
current.log_message("<font color=#960000>Has been converted to the cult of Nar'Sie!</font>", INDIVIDUAL_ATTACK_LOG)
if(GLOB.blood_target && GLOB.blood_target_image && current.client)
current.client.images += GLOB.blood_target_image
/datum/antagonist/cult/apply_innate_effects(mob/living/mob_override)
. = ..()
@@ -28,7 +77,10 @@
current = mob_override
current.faction |= "cult"
current.verbs += /mob/living/proc/cult_help
if(!GLOB.cult_mastered)
current.verbs += /mob/living/proc/cult_master
communion.Grant(current)
current.throw_alert("bloodsense", /obj/screen/alert/bloodsense)
/datum/antagonist/cult/remove_innate_effects(mob/living/mob_override)
. = ..()
@@ -38,13 +90,59 @@
current.faction -= "cult"
current.verbs -= /mob/living/proc/cult_help
communion.Remove(current)
owner.current.verbs -= /mob/living/proc/cult_master
for(var/datum/action/innate/cultmast/H in owner.current.actions)
qdel(H)
current.clear_alert("bloodsense")
/datum/antagonist/cult/on_removal()
owner.wipe_memory()
SSticker.mode.cult -= owner
SSticker.mode.update_cult_icons_removed(owner)
to_chat(owner, "<span class='userdanger'>An unfamiliar white light flashes through your mind, cleansing the taint of the Dark One and all your memories as its servant.</span>")
owner.current.log_message("<font color=#960000>Has renounced the cult of Nar'Sie!</font>", INDIVIDUAL_ATTACK_LOG)
if(!silent)
owner.current.visible_message("<span class='big'>[owner] looks like [owner.current.p_they()] just reverted to their old faith!</span>")
to_chat(owner.current, "<span class='userdanger'>An unfamiliar white light flashes through your mind, cleansing the taint of the Geometer and all your memories as her servant.</span>")
owner.current.log_message("<font color=#960000>Has renounced the cult of Nar'Sie!</font>", INDIVIDUAL_ATTACK_LOG)
owner.current.visible_message("<span class='big'>[owner.current] looks like [owner.current.p_they()] just reverted to their old faith!</span>")
if(GLOB.blood_target && GLOB.blood_target_image && owner.current.client)
owner.current.client.images -= GLOB.blood_target_image
. = ..()
/datum/antagonist/cult/master
var/datum/action/innate/cultmast/finalreck/reckoning = new
var/datum/action/innate/cultmast/cultmark/bloodmark = new
/datum/antagonist/cult/master/Destroy()
QDEL_NULL(reckoning)
QDEL_NULL(bloodmark)
return ..()
/datum/antagonist/cult/master/on_gain()
. = ..()
var/mob/living/current = owner.current
SSticker.mode.set_antag_hud(current, "cultmaster")
/datum/antagonist/cult/master/greet()
to_chat(owner.current, "<span class='cultlarge'>You are the cult's Master</span>. As the cult's Master, you have a unique title and loud voice when communicating, are capable of marking \
targets, such as a location or a noncultist, to direct the cult to them, and, finally, you are capable of summoning the entire living cult to your location <b><i>once</i></b>.")
to_chat(owner.current, "Use these abilities to direct the cult to victory at any cost.")
/datum/antagonist/cult/master/apply_innate_effects(mob/living/mob_override)
. = ..()
var/mob/living/current = owner.current
if(mob_override)
current = mob_override
if(!GLOB.reckoning_complete)
reckoning.Grant(current)
bloodmark.Grant(current)
current.update_action_buttons_icon()
current.apply_status_effect(/datum/status_effect/cult_master)
/datum/antagonist/cult/master/remove_innate_effects(mob/living/mob_override)
. = ..()
var/mob/living/current = owner.current
if(mob_override)
current = mob_override
reckoning.Remove(current)
bloodmark.Remove(current)
current.update_action_buttons_icon()
current.remove_status_effect(/datum/status_effect/cult_master)
+4 -2
View File
@@ -75,10 +75,12 @@
if(GLOB.revdata.parentcommit)
to_chat(src, "<b>Server revision compiled on:</b> [GLOB.revdata.date]")
var/prefix = ""
if(GLOB.revdata.testmerge.len)
to_chat(src, GLOB.revdata.GetTestMergeInfo())
to_chat(src, "Based off master commit:")
to_chat(src, "<a href='[config.githuburl]/commit/[GLOB.revdata.parentcommit]'>[GLOB.revdata.parentcommit]</a>")
prefix = "Based off master commit: "
var/pc = GLOB.revdata.parentcommit
to_chat(src, "[prefix]<a href='[config.githuburl]/commit/[pc]'>[copytext(pc, 1, min(length(pc), 7))]</a>")
else
to_chat(src, "Revision unknown")
to_chat(src, "<b>Current Infomational Settings:</b>")
+160 -154
View File
@@ -1,154 +1,160 @@
#define HOLOPAD_MAX_DIAL_TIME 200
/mob/camera/aiEye/remote/holo/setLoc()
. = ..()
var/obj/machinery/holopad/H = origin
H.move_hologram(eye_user, loc)
//this datum manages it's own references
/datum/holocall
var/mob/living/user //the one that called
var/obj/machinery/holopad/calling_holopad //the one that sent the call
var/obj/machinery/holopad/connected_holopad //the one that answered the call (may be null)
var/list/dialed_holopads //all things called, will be cleared out to just connected_holopad once answered
var/mob/camera/aiEye/remote/holo/eye //user's eye, once connected
var/obj/effect/overlay/holo_pad_hologram/hologram //user's hologram, once connected
var/call_start_time
//creates a holocall made by `caller` from `calling_pad` to `callees`
/datum/holocall/New(mob/living/caller, obj/machinery/holopad/calling_pad, list/callees)
call_start_time = world.time
user = caller
calling_pad.outgoing_call = src
calling_holopad = calling_pad
dialed_holopads = list()
for(var/I in callees)
var/obj/machinery/holopad/H = I
if(!QDELETED(H) && H.is_operational())
dialed_holopads += H
LAZYADD(H.holo_calls, src)
if(!dialed_holopads.len)
calling_pad.say("Connection failure.")
qdel(src)
testing("Holocall started")
//cleans up ALL references :)
/datum/holocall/Destroy()
QDEL_NULL(eye)
user.reset_perspective()
user = null
hologram.HC = null
hologram = null
calling_holopad.outgoing_call = null
for(var/I in dialed_holopads)
var/obj/machinery/holopad/H = I
LAZYREMOVE(H.holo_calls, src)
dialed_holopads.Cut()
if(calling_holopad)
calling_holopad.SetLightsAndPower()
calling_holopad = null
if(connected_holopad)
connected_holopad.SetLightsAndPower()
connected_holopad = null
testing("Holocall destroyed")
return ..()
//Gracefully disconnects a holopad `H` from a call. Pads not in the call are ignored. Notifies participants of the disconnection
/datum/holocall/proc/Disconnect(obj/machinery/holopad/H)
testing("Holocall disconnect")
if(H == connected_holopad)
calling_holopad.say("[usr] disconnected.")
else if(H == calling_holopad && connected_holopad)
connected_holopad.say("[usr] disconnected.")
ConnectionFailure(H, TRUE)
//Forcefully disconnects a holopad `H` from a call. Pads not in the call are ignored.
/datum/holocall/proc/ConnectionFailure(obj/machinery/holopad/H, graceful = FALSE)
testing("Holocall connection failure: graceful [graceful]")
if(H == connected_holopad || H == calling_holopad)
if(!graceful)
calling_holopad.say("Connection failure.")
qdel(src)
return
LAZYREMOVE(H.holo_calls, src)
dialed_holopads -= H
if(!dialed_holopads.len)
if(graceful)
calling_holopad.say("Call rejected.")
testing("No recipients, terminating")
qdel(src)
//Answers a call made to a holopad `H` which cannot be the calling holopad. Pads not in the call are ignored
/datum/holocall/proc/Answer(obj/machinery/holopad/H)
testing("Holocall answer")
if(H == calling_holopad)
CRASH("How cute, a holopad tried to answer itself.")
if(!(H in dialed_holopads))
return
if(connected_holopad)
CRASH("Multi-connection holocall")
connected_holopad = H
for(var/I in dialed_holopads)
if(I == H)
continue
var/obj/machinery/holopad/Holo = I
LAZYREMOVE(Holo.holo_calls, src)
dialed_holopads -= Holo
if(!Check())
return
hologram = H.activate_holo(user)
hologram.HC = src
//eyeobj code is horrid, this is the best copypasta I could make
eye = new
eye.origin = H
eye.eye_initialized = TRUE
eye.eye_user = user
eye.name = "Camera Eye ([user.name])"
user.remote_control = eye
user.reset_perspective(eye)
eye.setLoc(H.loc)
//Checks the validity of a holocall and qdels itself if it's not. Returns TRUE if valid, FALSE otherwise
/datum/holocall/proc/Check()
for(var/I in dialed_holopads)
var/obj/machinery/holopad/H = I
if(!H.is_operational())
ConnectionFailure(H)
if(QDELETED(src))
return FALSE
. = !QDELETED(user) && !user.incapacitated() && !QDELETED(calling_holopad) && calling_holopad.is_operational() && user.loc == calling_holopad.loc
if(.)
if(connected_holopad)
. = !QDELETED(connected_holopad) && connected_holopad.is_operational()
else
. = world.time < (call_start_time + HOLOPAD_MAX_DIAL_TIME)
if(!.)
calling_holopad.say("No answer recieved.")
calling_holopad.temp = ""
if(!.)
testing("Holocall Check fail")
qdel(src)
#define HOLOPAD_MAX_DIAL_TIME 200
/mob/camera/aiEye/remote/holo/setLoc()
. = ..()
var/obj/machinery/holopad/H = origin
H.move_hologram(eye_user, loc)
//this datum manages it's own references
/datum/holocall
var/mob/living/user //the one that called
var/obj/machinery/holopad/calling_holopad //the one that sent the call
var/obj/machinery/holopad/connected_holopad //the one that answered the call (may be null)
var/list/dialed_holopads //all things called, will be cleared out to just connected_holopad once answered
var/mob/camera/aiEye/remote/holo/eye //user's eye, once connected
var/obj/effect/overlay/holo_pad_hologram/hologram //user's hologram, once connected
var/call_start_time
//creates a holocall made by `caller` from `calling_pad` to `callees`
/datum/holocall/New(mob/living/caller, obj/machinery/holopad/calling_pad, list/callees)
call_start_time = world.time
user = caller
calling_pad.outgoing_call = src
calling_holopad = calling_pad
dialed_holopads = list()
for(var/I in callees)
var/obj/machinery/holopad/H = I
if(!QDELETED(H) && H.is_operational())
dialed_holopads += H
LAZYADD(H.holo_calls, src)
if(!dialed_holopads.len)
calling_pad.say("Connection failure.")
qdel(src)
return
testing("Holocall started")
//cleans up ALL references :)
/datum/holocall/Destroy()
QDEL_NULL(eye)
user.reset_perspective()
user = null
hologram.HC = null
hologram = null
calling_holopad.outgoing_call = null
for(var/I in dialed_holopads)
var/obj/machinery/holopad/H = I
LAZYREMOVE(H.holo_calls, src)
dialed_holopads.Cut()
if(calling_holopad)
calling_holopad.SetLightsAndPower()
calling_holopad = null
if(connected_holopad)
connected_holopad.SetLightsAndPower()
connected_holopad = null
testing("Holocall destroyed")
return ..()
//Gracefully disconnects a holopad `H` from a call. Pads not in the call are ignored. Notifies participants of the disconnection
/datum/holocall/proc/Disconnect(obj/machinery/holopad/H)
testing("Holocall disconnect")
if(H == connected_holopad)
calling_holopad.say("[usr] disconnected.")
else if(H == calling_holopad && connected_holopad)
connected_holopad.say("[usr] disconnected.")
ConnectionFailure(H, TRUE)
//Forcefully disconnects a holopad `H` from a call. Pads not in the call are ignored.
/datum/holocall/proc/ConnectionFailure(obj/machinery/holopad/H, graceful = FALSE)
testing("Holocall connection failure: graceful [graceful]")
if(H == connected_holopad || H == calling_holopad)
if(!graceful)
calling_holopad.say("Connection failure.")
qdel(src)
return
LAZYREMOVE(H.holo_calls, src)
dialed_holopads -= H
if(!dialed_holopads.len)
if(graceful)
calling_holopad.say("Call rejected.")
testing("No recipients, terminating")
qdel(src)
//Answers a call made to a holopad `H` which cannot be the calling holopad. Pads not in the call are ignored
/datum/holocall/proc/Answer(obj/machinery/holopad/H)
testing("Holocall answer")
if(H == calling_holopad)
CRASH("How cute, a holopad tried to answer itself.")
if(!(H in dialed_holopads))
return
if(connected_holopad)
CRASH("Multi-connection holocall")
for(var/I in dialed_holopads)
if(I == H)
continue
Disconnect(I)
for(var/I in H.holo_calls)
var/datum/holocall/HC = I
if(HC != src)
HC.Disconnect(H)
connected_holopad = H
if(!Check())
return
hologram = H.activate_holo(user)
hologram.HC = src
//eyeobj code is horrid, this is the best copypasta I could make
eye = new
eye.origin = H
eye.eye_initialized = TRUE
eye.eye_user = user
eye.name = "Camera Eye ([user.name])"
user.remote_control = eye
user.reset_perspective(eye)
eye.setLoc(H.loc)
//Checks the validity of a holocall and qdels itself if it's not. Returns TRUE if valid, FALSE otherwise
/datum/holocall/proc/Check()
for(var/I in dialed_holopads)
var/obj/machinery/holopad/H = I
if(!H.is_operational())
ConnectionFailure(H)
if(QDELETED(src))
return FALSE
. = !QDELETED(user) && !user.incapacitated() && !QDELETED(calling_holopad) && calling_holopad.is_operational() && user.loc == calling_holopad.loc
if(.)
if(connected_holopad)
. = !QDELETED(connected_holopad) && connected_holopad.is_operational()
else
. = world.time < (call_start_time + HOLOPAD_MAX_DIAL_TIME)
if(!.)
calling_holopad.say("No answer recieved.")
calling_holopad.temp = ""
if(!.)
testing("Holocall Check fail")
qdel(src)
+73 -68
View File
@@ -52,7 +52,7 @@
var/linglink
var/miming = 0 // Mime's vow of silence
var/list/antag_datums
var/list/antag_datums
var/antag_hud_icon_state = null //this mind's ANTAG_HUD should have this icon_state
var/datum/atom_hud/antag/antag_hud = null //this mind's antag HUD
var/datum/gang/gang_datum //Which gang this mind belongs to, if any
@@ -63,23 +63,35 @@
var/mob/living/enslaved_to //If this mind's master is another mob (i.e. adamantine golems)
var/datum/language_holder
/datum/mind/New(var/key)
src.key = key
soulOwner = src
/datum/mind/Destroy()
SSticker.minds -= src
if(islist(antag_datums))
for(var/i in antag_datums)
qdel(i)
antag_datums = null
if(islist(antag_datums))
for(var/i in antag_datums)
qdel(i)
antag_datums = null
return ..()
/datum/mind/proc/get_language_holder()
if(!language_holder)
var/datum/language_holder/L = current.get_language_holder(shadow=FALSE)
language_holder = L.copy(src)
return language_holder
/datum/mind/proc/transfer_to(mob/new_character, var/force_key_move = 0)
if(current) // remove ourself from our old body's mind variable
current.mind = null
SStgui.on_transfer(current, new_character)
if(!language_holder)
language_holder = new_character.language_holder.copy(src)
if(key)
if(new_character.key != key) //if we're transfering into a body with a key associated which is not ours
new_character.ghostize(1) //we'll need to ghostize so that key isn't mobless.
@@ -90,12 +102,12 @@
new_character.mind.current = null
var/datum/atom_hud/antag/hud_to_transfer = antag_hud//we need this because leave_hud() will clear this list
var/mob/living/old_current = current
var/mob/living/old_current = current
current = new_character //associate ourself with our new body
new_character.mind = src //and associate our new body with ourself
for(var/a in antag_datums) //Makes sure all antag datums effects are applied in the new body
var/datum/antagonist/A = a
A.on_body_transfer(old_current, current)
for(var/a in antag_datums) //Makes sure all antag datums effects are applied in the new body
var/datum/antagonist/A = a
A.on_body_transfer(old_current, current)
if(iscarbon(new_character))
var/mob/living/carbon/C = new_character
C.last_mind = src
@@ -111,42 +123,42 @@
/datum/mind/proc/wipe_memory()
memory = null
// Datum antag mind procs
/datum/mind/proc/add_antag_datum(datum_type)
if(!datum_type)
return
var/datum/antagonist/A = new datum_type(src)
if(!A.can_be_owned(src))
qdel(A)
return
LAZYADD(antag_datums, A)
A.on_gain()
return A
/datum/mind/proc/remove_antag_datum(datum_type)
if(!datum_type)
return
var/datum/antagonist/A = has_antag_datum(datum_type)
if(A)
A.on_removal()
return TRUE
/datum/mind/proc/remove_all_antag_datums() //For the Lazy amongst us.
for(var/a in antag_datums)
var/datum/antagonist/A = a
A.on_removal()
/datum/mind/proc/has_antag_datum(datum_type, check_subtypes = TRUE)
if(!datum_type)
return
. = FALSE
for(var/a in antag_datums)
var/datum/antagonist/A = a
if(check_subtypes && istype(A, datum_type))
return A
else if(A.type == datum_type)
return A
// Datum antag mind procs
/datum/mind/proc/add_antag_datum(datum_type)
if(!datum_type)
return
var/datum/antagonist/A = new datum_type(src)
if(!A.can_be_owned(src))
qdel(A)
return
LAZYADD(antag_datums, A)
A.on_gain()
return A
/datum/mind/proc/remove_antag_datum(datum_type)
if(!datum_type)
return
var/datum/antagonist/A = has_antag_datum(datum_type)
if(A)
A.on_removal()
return TRUE
/datum/mind/proc/remove_all_antag_datums() //For the Lazy amongst us.
for(var/a in antag_datums)
var/datum/antagonist/A = a
A.on_removal()
/datum/mind/proc/has_antag_datum(datum_type, check_subtypes = TRUE)
if(!datum_type)
return
. = FALSE
for(var/a in antag_datums)
var/datum/antagonist/A = a
if(check_subtypes && istype(A, datum_type))
return A
else if(A.type == datum_type)
return A
/*
Removes antag type's references from a mind.
objectives, uplinks, powers etc are all handled.
@@ -272,7 +284,7 @@
creator.faction |= current.faction
if(creator.mind.special_role)
message_admins("[key_name_admin(current)](<A HREF='?_src_=holder;adminmoreinfo=\ref[current]'>?</A>) has been created by [key_name_admin(creator)](<A HREF='?_src_=holder;adminmoreinfo=\ref[creator]'>?</A>), an antagonist.")
message_admins("[ADMIN_LOOKUPFLW(current)] has been created by [ADMIN_LOOKUPFLW(creator)], an antagonist.")
to_chat(current, "<span class='userdanger'>Despite your creators current allegiances, your true master remains [creator.real_name]. If their loyalities change, so do yours. This will never change unless your creator's body is destroyed.</span>")
/datum/mind/proc/show_memory(mob/recipient, window=1)
@@ -293,7 +305,7 @@
to_chat(recipient, "<i>[output]</i>")
/datum/mind/proc/edit_memory()
if(!SSticker.HasRoundStarted())
if(!SSticker.HasRoundStarted())
alert("Not before round-start!", "Alert")
return
@@ -1181,7 +1193,7 @@
log_admin("[key_name_admin(usr)] has made [current] unable to ascend as a devil.")
return
if(!ishuman(current) && !iscyborg(current))
to_chat(usr, "<span class='warning'>This only works on humans and cyborgs!</span>")
to_chat(usr, "<span class='warning'>This only works on humans and cyborgs!</span>")
return
SSticker.mode.devils += src
special_role = "devil"
@@ -1230,17 +1242,17 @@
log_admin("[key_name(usr)] turned [current] into abductor.")
SSticker.mode.update_abductor_icons_added(src)
if("equip")
if(!ishuman(current))
to_chat(usr, "<span class='warning'>This only works on humans!</span>")
return
var/mob/living/carbon/human/H = current
if(!ishuman(current))
to_chat(usr, "<span class='warning'>This only works on humans!</span>")
return
var/mob/living/carbon/human/H = current
var/gear = alert("Agent or Scientist Gear","Gear","Agent","Scientist")
if(gear)
if(gear=="Agent")
H.equipOutfit(/datum/outfit/abductor/agent)
H.equipOutfit(/datum/outfit/abductor/agent)
else
H.equipOutfit(/datum/outfit/abductor/scientist)
H.equipOutfit(/datum/outfit/abductor/scientist)
else if (href_list["monkey"])
var/mob/living/L = current
@@ -1437,15 +1449,8 @@
special_role = "Cultist"
to_chat(current, "<font color=\"purple\"><b><i>You catch a glimpse of the Realm of Nar-Sie, The Geometer of Blood. You now see how flimsy the world is, you see that it should be open to the knowledge of Nar-Sie.</b></i></font>")
to_chat(current, "<font color=\"purple\"><b><i>Assist your new compatriots in their dark dealings. Their goal is yours, and yours is theirs. You serve the Dark One above all else. Bring It back.</b></i></font>")
var/datum/game_mode/cult/cult = SSticker.mode
if (istype(cult))
cult.memorize_cult_objectives(src)
else
var/explanation = "Summon Nar-Sie via the use of the appropriate rune (Hell join self). It will only work if nine cultists stand on and around it."
to_chat(current, "<B>Objective #1</B>: [explanation]")
memory += "<B>Objective #1</B>: [explanation]<BR>"
var/datum/antagonist/cult/C
C.cult_memorization(src)
var/mob/living/carbon/human/H = current
if (!SSticker.mode.equip_cultist(current))
to_chat(H, "Spawning an amulet from your Master failed.")
@@ -1509,8 +1514,8 @@
H.set_species(/datum/species/abductor)
var/datum/species/abductor/S = H.dna.species
if(role == "Scientist")
S.scientist = TRUE
if(role == "Scientist")
S.scientist = TRUE
S.team = team
var/list/obj/effect/landmark/abductor/agent_landmarks = new
@@ -1529,8 +1534,8 @@
if("Agent")
L = agent_landmarks[team]
if("Scientist")
L = scientist_landmarks[team]
H.forceMove(L.loc)
L = scientist_landmarks[team]
H.forceMove(L.loc)
/datum/mind/proc/AddSpell(obj/effect/proc_holder/spell/S)
spell_list += S
+1
View File
@@ -42,6 +42,7 @@
However, all the inhabitants seem to do is grow drugs and guns."
suffix = "lavaland_surface_seed_vault.dmm"
cost = 10
allow_duplicates = FALSE
/datum/map_template/ruin/lavaland/ash_walker
name = "Ash Walker Nest"
+1 -1
View File
@@ -72,7 +72,7 @@
/datum/map_template/shuttle/emergency/meteor
suffix = "meteor"
name = "An Asteroid With Engines Strapped To It"
name = "Asteroid With Engines Strapped To It"
description = "A hollowed out asteroid with engines strapped to it. Due to its size and difficulty in steering it, this shuttle may damage the docking area."
admin_notes = "This shuttle will likely crush escape, killing anyone there."
credit_cost = -5000
+34
View File
@@ -13,6 +13,7 @@
/datum/status_effect/shadow_mend/on_apply()
owner.visible_message("<span class='notice'>Violet light wraps around [owner]'s body!</span>", "<span class='notice'>Violet light wraps around your body!</span>")
playsound(owner, 'sound/magic/Teleport_app.ogg', 50, 1)
return ..()
/datum/status_effect/shadow_mend/tick()
owner.adjustBruteLoss(-15)
@@ -77,6 +78,7 @@
progbar = new(owner, duration, owner)
progbar.bar.color = list("#FAE48C", "#FAE48C", "#FAE48C", rgb(0,0,0))
progbar.update(duration - world.time)
return ..()
/datum/status_effect/vanguard_shield/tick()
progbar.update(duration - world.time)
@@ -129,6 +131,7 @@
animate(owner, color = oldcolor, time = 150, easing = EASE_IN)
addtimer(CALLBACK(owner, /atom/proc/update_atom_colour), 150)
playsound(owner, 'sound/magic/Ethereal_Enter.ogg', 50, 1)
return ..()
/datum/status_effect/inathneqs_endowment/on_remove()
add_logs(owner, null, "lost Inath-neq's invulnerability")
@@ -180,6 +183,7 @@
/datum/status_effect/his_grace/on_apply()
add_logs(owner, null, "gained His Grace's stun immunity")
owner.add_stun_absorption("hisgrace", INFINITY, 3, null, "His Grace protects you from the stun!")
return ..()
/datum/status_effect/his_grace/tick()
bloodlust = 0
@@ -213,6 +217,7 @@
/datum/status_effect/wish_granters_gift/on_apply()
to_chat(owner, "<span class='notice'>Death is not your end! The Wish Granter's energy suffuses you, and you begin to rise...</span>")
return ..()
/datum/status_effect/wish_granters_gift/on_remove()
owner.revive(full_heal = 1, admin_revive = 1)
@@ -223,3 +228,32 @@
name = "Wish Granter's Immortality"
desc = "You are being resurrected!"
icon_state = "wish_granter"
/datum/status_effect/cult_master
id = "The Cult Master"
duration = -1
tick_interval = 100
alert_type = null
var/alive = TRUE
/datum/status_effect/cult_master/proc/deathrattle()
var/area/A = get_area(owner)
for(var/datum/mind/B in SSticker.mode.cult)
if(isliving(B.current))
var/mob/living/M = B.current
M << 'sound/hallucinations/veryfar_noise.ogg'
to_chat(M, "<span class='cultlarge'>The Cult's Master, [owner], has fallen in the [A]!")
/datum/status_effect/cult_master/tick()
if(owner.stat != DEAD && !alive)
alive = TRUE
return
if(owner.stat == DEAD && alive)
alive = FALSE
deathrattle()
/datum/status_effect/cult_master/on_remove()
deathrattle()
. = ..()
+133
View File
@@ -29,3 +29,136 @@
owner.adjustBruteLoss(0.1)
owner.adjustFireLoss(0.1)
owner.adjustToxLoss(0.2, TRUE, TRUE)
/datum/status_effect/belligerent
id = "belligerent"
duration = 70
tick_interval = 0 //tick as fast as possible
status_type = STATUS_EFFECT_REPLACE
alert_type = /obj/screen/alert/status_effect/belligerent
var/leg_damage_on_toggle = 2 //damage on initial application and when the owner tries to toggle to run
var/cultist_damage_on_toggle = 10 //damage on initial application and when the owner tries to toggle to run, but to cultists
/obj/screen/alert/status_effect/belligerent
name = "Belligerent"
desc = "<b><font color=#880020>Kneel, her-eti'c.</font></b>"
icon_state = "belligerent"
alerttooltipstyle = "clockcult"
/datum/status_effect/belligerent/on_apply()
return do_movement_toggle(TRUE)
/datum/status_effect/belligerent/tick()
if(!do_movement_toggle())
qdel(src)
/datum/status_effect/belligerent/proc/do_movement_toggle(force_damage)
var/number_legs = owner.get_num_legs()
if(iscarbon(owner) && !is_servant_of_ratvar(owner) && !owner.null_rod_check() && number_legs)
if(force_damage || owner.m_intent != MOVE_INTENT_WALK)
if(GLOB.ratvar_awakens)
owner.Weaken(1)
if(iscultist(owner))
owner.apply_damage(cultist_damage_on_toggle * 0.5, BURN, "l_leg")
owner.apply_damage(cultist_damage_on_toggle * 0.5, BURN, "r_leg")
else
owner.apply_damage(leg_damage_on_toggle * 0.5, BURN, "l_leg")
owner.apply_damage(leg_damage_on_toggle * 0.5, BURN, "r_leg")
if(owner.m_intent != MOVE_INTENT_WALK)
if(!iscultist(owner))
to_chat(owner, "<span class='warning'>Your leg[number_legs > 1 ? "s shiver":" shivers"] with pain!</span>")
else //Cultists take extra burn damage
to_chat(owner, "<span class='warning'>Your leg[number_legs > 1 ? "s burn":" burns"] with pain!</span>")
owner.toggle_move_intent()
return TRUE
return FALSE
/datum/status_effect/belligerent/on_remove()
if(owner.m_intent == MOVE_INTENT_WALK)
owner.toggle_move_intent()
/datum/status_effect/maniamotor
id = "maniamotor"
duration = -1
tick_interval = 10
status_type = STATUS_EFFECT_MULTIPLE
alert_type = null
var/obj/structure/destructible/clockwork/powered/mania_motor/motor
var/severity = 0 //goes up to a maximum of MAX_MANIA_SEVERITY
var/warned_turnoff = FALSE //if we've warned that the motor is off
var/warned_outofsight = FALSE //if we've warned that the target is out of sight of the motor
var/static/list/mania_messages = list("Go nuts.", "Take a crack at crazy.", "Make a bid for insanity.", "Get kooky.", "Move towards mania.", "Become bewildered.", "Wax wild.", \
"Go round the bend.", "Land in lunacy.", "Try dementia.", "Strive to get a screw loose.", "Advance forward.", "Approach the transmitter.", "Touch the antennae.", \
"Move towards the mania motor.", "Come closer.", "Get over here already!", "Keep your eyes on the motor.")
var/static/list/flee_messages = list("Oh, NOW you flee.", "Get back here!", "If you were smarter, you'd come back.", "Only fools run.", "You'll be back.")
var/static/list/turnoff_messages = list("Why would they turn it-", "What are these idi-", "Fools, fools, all of-", "Are they trying to c-", "All this effort just f-")
var/static/list/powerloss_messages = list("\"Oh, the id**ts di***t s***e en**** pow**...\"", "\"D*dn't **ey mak* an **te***c*i*n le**?\"", "\"The** f**ls for**t t* make a ***** *f-\"", \
"\"No, *O, you **re so cl***-\"", "You hear a yell of frustration, cut off by static.")
/datum/status_effect/maniamotor/Destroy()
motor = null
return ..()
/datum/status_effect/maniamotor/tick()
var/is_servant = is_servant_of_ratvar(owner)
var/span_part = severity > 50 ? "" : "_small" //let's save like one check
if(QDELETED(motor))
if(!is_servant)
to_chat(owner, "<span class='sevtug[span_part]'>You feel a frustrated voice quietly fade from your mind...</span>")
qdel(src)
return
if(!motor.active) //it being off makes it fall off much faster
if(!is_servant && !warned_turnoff)
if(motor.total_accessable_power() > motor.mania_cost)
to_chat(owner, "<span class='sevtug[span_part]'>\"[text2ratvar(pick(turnoff_messages))]\"</span>")
else
to_chat(owner, "<span class='sevtug[span_part]'>[text2ratvar(pick(powerloss_messages))]</span>")
warned_turnoff = TRUE
severity = max(severity - 2, 0)
if(!severity)
qdel(src)
return
else
if(prob(severity * 2))
warned_turnoff = FALSE
if(!(owner in viewers(7, motor))) //not being in range makes it fall off slightly faster
if(!is_servant && !warned_outofsight)
to_chat(owner, "<span class='sevtug[span_part]'>\"[text2ratvar(pick(flee_messages))]\"</span>")
warned_outofsight = TRUE
severity = max(severity - 1, 0)
if(!severity)
qdel(src)
return
else if(prob(severity * 2))
warned_outofsight = FALSE
if(is_servant) //heals servants of braindamage, hallucination, druggy, dizziness, and confusion
if(owner.hallucination)
owner.hallucination = 0
if(owner.druggy)
owner.adjust_drugginess(-owner.druggy)
if(owner.dizziness)
owner.dizziness = 0
if(owner.confused)
owner.confused = 0
severity = 0
else if(!owner.null_rod_check() && owner.stat != DEAD && severity)
var/static/hum = get_sfx('sound/effects/screech.ogg') //same sound for every proc call
if(owner.getToxLoss() > MANIA_DAMAGE_TO_CONVERT)
if(is_eligible_servant(owner))
to_chat(owner, "<span class='sevtug[span_part]'>\"[text2ratvar("You are mine and his, now.")]\"</span>")
add_servant_of_ratvar(owner)
owner.Paralyse(5)
else
if(prob(severity * 0.15))
to_chat(owner, "<span class='sevtug[span_part]'>\"[text2ratvar(pick(mania_messages))]\"</span>")
owner.playsound_local(get_turf(motor), hum, severity, 1)
owner.adjust_drugginess(Clamp(max(severity * 0.075, 1), 0, max(0, 50 - owner.druggy))) //7.5% of severity per second, minimum 1
if(owner.hallucination < 50)
owner.hallucination = min(owner.hallucination + max(severity * 0.075, 1), 50) //7.5% of severity per second, minimum 1
if(owner.dizziness < 50)
owner.dizziness = min(owner.dizziness + round(severity * 0.05, 1), 50) //5% of severity per second above 10 severity
if(owner.confused < 25)
owner.confused = min(owner.confused + round(severity * 0.025, 1), 25) //2.5% of severity per second above 20 severity
owner.adjustToxLoss(severity * 0.02, TRUE, TRUE) //2% of severity per second
severity--
+1
View File
@@ -16,6 +16,7 @@
cube = icon('icons/effects/freeze.dmi', "ice_cube")
owner.add_overlay(cube)
owner.update_canmove()
return ..()
/datum/status_effect/freon/tick()
owner.update_canmove()
+13 -2
View File
@@ -10,6 +10,7 @@
var/status_type = STATUS_EFFECT_UNIQUE //How many of the effect can be on one mob, and what happens when you try to add another
var/on_remove_on_mob_delete = FALSE //if we call on_remove() when the mob is deleted
var/alert_type = /obj/screen/alert/status_effect //the alert thrown by the status effect, contains name and description
var/obj/screen/alert/status_effect/linked_alert = null //the alert itself, if it exists
/datum/status_effect/New(mob/living/new_owner)
if(new_owner)
@@ -30,16 +31,16 @@
/datum/status_effect/proc/start_ticking()
if(!src)
return
if(!owner)
if(!owner || !on_apply())
qdel(src)
return
on_apply()
if(duration != -1)
duration = world.time + initial(duration)
tick_interval = world.time + initial(tick_interval)
if(alert_type)
var/obj/screen/alert/status_effect/A = owner.throw_alert(id, alert_type)
A.attached_effect = src //so the alert can reference us, if it needs to
linked_alert = A //so we can reference the alert, if we need to
START_PROCESSING(SSfastprocess, src)
/datum/status_effect/process()
@@ -53,6 +54,8 @@
qdel(src)
/datum/status_effect/proc/on_apply() //Called whenever the buff is applied.
return TRUE
/datum/status_effect/proc/tick() //Called every tick.
/datum/status_effect/proc/on_remove() //Called whenever the buff expires or is removed; do note that at the point this is called, it is out of the owner's status_effects but owner is not yet null
/datum/status_effect/proc/be_replaced() //Called instead of on_remove when a status effect is replaced by itself or when a status effect with on_remove_on_mob_delete = FALSE has its mob deleted
@@ -103,3 +106,11 @@
for(var/datum/status_effect/S in status_effects)
if(initial(S1.id) == S.id)
return S
/mob/living/proc/has_status_effect_list(effect) //returns a list of effects with matching IDs that the mod owns; use for effects there can be multiple of
. = list()
if(status_effects)
var/datum/status_effect/S1 = effect
for(var/datum/status_effect/S in status_effects)
if(initial(S1.id) == S.id)
. += S