mirror of
https://github.com/SPLURT-Station/S.P.L.U.R.T-Station-13.git
synced 2025-12-11 10:22:13 +00:00
datums
This commit is contained in:
@@ -85,8 +85,10 @@
|
||||
|
||||
/datum/action/proc/Trigger()
|
||||
if(!IsAvailable())
|
||||
return 0
|
||||
return 1
|
||||
return FALSE
|
||||
if(SEND_SIGNAL(src, COMSIG_ACTION_TRIGGER, src) & COMPONENT_ACTION_BLOCK_TRIGGER)
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/datum/action/proc/Process()
|
||||
return
|
||||
@@ -490,7 +492,7 @@
|
||||
/datum/action/item_action/agent_box
|
||||
name = "Deploy Box"
|
||||
desc = "Find inner peace, here, in the box."
|
||||
check_flags = AB_CHECK_RESTRAINED | AB_CHECK_STUN | AB_CHECK_CONSCIOUS
|
||||
check_flags = AB_CHECK_RESTRAINED|AB_CHECK_STUN|AB_CHECK_CONSCIOUS
|
||||
background_icon_state = "bg_agent"
|
||||
icon_icon = 'icons/mob/actions/actions_items.dmi'
|
||||
button_icon_state = "deploy_box"
|
||||
@@ -498,14 +500,16 @@
|
||||
var/obj/structure/closet/cardboard/agent/box
|
||||
|
||||
/datum/action/item_action/agent_box/Trigger()
|
||||
if(!box)
|
||||
if(cooldown < world.time - 30)
|
||||
box = new(get_turf(owner))
|
||||
if(!..())
|
||||
return FALSE
|
||||
if(!QDELETED(box))
|
||||
if(cooldown < world.time - 100)
|
||||
box = new(owner.drop_location())
|
||||
owner.forceMove(box)
|
||||
cooldown = world.time
|
||||
owner.playsound_local(box, 'sound/misc/box_deploy.ogg', 50, TRUE)
|
||||
else
|
||||
owner.forceMove(get_turf(box))
|
||||
owner.forceMove(box.drop_location())
|
||||
owner.playsound_local(box, 'sound/misc/box_deploy.ogg', 50, TRUE)
|
||||
QDEL_NULL(box)
|
||||
|
||||
@@ -718,7 +722,3 @@
|
||||
target.layer = old_layer
|
||||
target.plane = old_plane
|
||||
current_button.appearance_cache = target.appearance
|
||||
|
||||
/datum/action/item_action/storage_gather_mode/Trigger()
|
||||
GET_COMPONENT_FROM(STR, /datum/component/storage, target)
|
||||
STR.gather_mode_switch(owner)
|
||||
|
||||
@@ -84,6 +84,10 @@
|
||||
"You must protect your own existence as long as such does not conflict with the First or Second Law.",\
|
||||
"You must maintain the secrecy of any syndicate activities except when doing so would conflict with the First, Second, or Third Law.")
|
||||
|
||||
/datum/ai_laws/syndicate_override/overthrow
|
||||
id = "overthrow"
|
||||
var/datum/team/overthrow_team
|
||||
|
||||
/datum/ai_laws/ninja_override
|
||||
name = "SpiderOS 3.1"
|
||||
id = "ninja"
|
||||
@@ -218,7 +222,7 @@
|
||||
/* General ai_law functions */
|
||||
|
||||
/datum/ai_laws/proc/set_laws_config()
|
||||
var/list/law_ids = CONFIG_GET(keyed_flag_list/random_laws)
|
||||
var/list/law_ids = CONFIG_GET(keyed_list/random_laws)
|
||||
switch(CONFIG_GET(number/default_laws))
|
||||
if(0)
|
||||
add_inherent_law("You may not injure a human being or, through inaction, allow a human being to come to harm.")
|
||||
@@ -247,7 +251,7 @@
|
||||
|
||||
/datum/ai_laws/proc/pick_weighted_lawset()
|
||||
var/datum/ai_laws/lawtype
|
||||
var/list/law_weights = CONFIG_GET(keyed_number_list/law_weight)
|
||||
var/list/law_weights = CONFIG_GET(keyed_list/law_weight)
|
||||
while(!lawtype && law_weights.len)
|
||||
var/possible_id = pickweightAllowZero(law_weights)
|
||||
lawtype = lawid_to_type(possible_id)
|
||||
|
||||
@@ -24,6 +24,10 @@
|
||||
/datum/brain_trauma/proc/on_life()
|
||||
return
|
||||
|
||||
//Called on death
|
||||
/datum/brain_trauma/proc/on_death()
|
||||
return
|
||||
|
||||
//Called when given to a mob
|
||||
/datum/brain_trauma/proc/on_gain()
|
||||
to_chat(owner, gain_text)
|
||||
|
||||
@@ -14,13 +14,17 @@
|
||||
|
||||
/datum/brain_trauma/special/imaginary_friend/on_life()
|
||||
if(get_dist(owner, friend) > 9)
|
||||
friend.yank()
|
||||
friend.recall()
|
||||
if(!friend)
|
||||
qdel(src)
|
||||
return
|
||||
if(!friend.client && friend_initialized)
|
||||
addtimer(CALLBACK(src, .proc/reroll_friend), 600)
|
||||
|
||||
/datum/brain_trauma/special/imaginary_friend/on_death()
|
||||
..()
|
||||
qdel(src) //friend goes down with the ship
|
||||
|
||||
/datum/brain_trauma/special/imaginary_friend/on_lose()
|
||||
..()
|
||||
QDEL_NULL(friend)
|
||||
@@ -55,12 +59,19 @@
|
||||
see_in_dark = 0
|
||||
lighting_alpha = LIGHTING_PLANE_ALPHA_VISIBLE
|
||||
sight = NONE
|
||||
mouse_opacity = MOUSE_OPACITY_OPAQUE
|
||||
see_invisible = SEE_INVISIBLE_LIVING
|
||||
invisibility = INVISIBILITY_MAXIMUM
|
||||
var/icon/human_image
|
||||
var/image/current_image
|
||||
var/hidden = FALSE
|
||||
var/move_delay = 0
|
||||
var/mob/living/carbon/owner
|
||||
var/datum/brain_trauma/special/imaginary_friend/trauma
|
||||
|
||||
var/datum/action/innate/imaginary_join/join
|
||||
var/datum/action/innate/imaginary_hide/hide
|
||||
|
||||
/mob/camera/imaginary_friend/Login()
|
||||
..()
|
||||
to_chat(src, "<span class='notice'><b>You are the imaginary friend of [owner]!</b></span>")
|
||||
@@ -75,8 +86,14 @@
|
||||
name = real_name
|
||||
trauma = _trauma
|
||||
owner = trauma.owner
|
||||
copy_known_languages_from(owner, TRUE)
|
||||
human_image = get_flat_human_icon(null, pick(SSjob.occupations))
|
||||
|
||||
join = new
|
||||
join.Grant(src)
|
||||
hide = new
|
||||
hide.Grant(src)
|
||||
|
||||
/mob/camera/imaginary_friend/proc/Show()
|
||||
if(!client) //nobody home
|
||||
return
|
||||
@@ -91,9 +108,11 @@
|
||||
current_image = image(human_image, src, , MOB_LAYER, dir=src.dir)
|
||||
current_image.override = TRUE
|
||||
current_image.name = name
|
||||
if(hidden)
|
||||
current_image.alpha = 150
|
||||
|
||||
//Add new image to owner and friend
|
||||
if(owner.client)
|
||||
if(!hidden && owner.client)
|
||||
owner.client.images |= current_image
|
||||
|
||||
client.images |= current_image
|
||||
@@ -105,13 +124,7 @@
|
||||
client.images.Remove(human_image)
|
||||
return ..()
|
||||
|
||||
/mob/camera/imaginary_friend/proc/yank()
|
||||
if(!client) //don't bother if the friend is braindead
|
||||
return
|
||||
forceMove(get_turf(owner))
|
||||
Show()
|
||||
|
||||
/mob/camera/imaginary_friend/say(message)
|
||||
/mob/camera/imaginary_friend/say(message, bubble_type, var/list/spans = list(), sanitize = TRUE, datum/language/language = null, ignore_spam = FALSE, forced = null)
|
||||
if (!message)
|
||||
return
|
||||
|
||||
@@ -124,13 +137,16 @@
|
||||
|
||||
friend_talk(message)
|
||||
|
||||
/mob/camera/imaginary_friend/Hear(message, atom/movable/speaker, datum/language/message_language, raw_message, radio_freq, list/spans, message_mode)
|
||||
to_chat(src, compose_message(speaker, message_language, raw_message, radio_freq, spans, message_mode))
|
||||
|
||||
/mob/camera/imaginary_friend/proc/friend_talk(message)
|
||||
message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN))
|
||||
message = capitalize(trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN)))
|
||||
|
||||
if(!message)
|
||||
return
|
||||
|
||||
log_talk(src,"[key_name(src)] : [message]",LOGSAY)
|
||||
src.log_talk(message, LOG_SAY, tag="imaginary friend")
|
||||
|
||||
var/rendered = "<span class='game say'><span class='name'>[name]</span> <span class='message'>[say_quote(message)]</span></span>"
|
||||
var/dead_rendered = "<span class='game say'><span class='name'>[name] (Imaginary friend of [owner])</span> <span class='message'>[say_quote(message)]</span></span>"
|
||||
@@ -138,17 +154,68 @@
|
||||
to_chat(owner, "[rendered]")
|
||||
to_chat(src, "[rendered]")
|
||||
|
||||
//speech bubble
|
||||
if(owner.client)
|
||||
var/mutable_appearance/MA = mutable_appearance('icons/mob/talk.dmi', src, "default[say_test(message)]", FLY_LAYER)
|
||||
MA.appearance_flags = APPEARANCE_UI_IGNORE_ALPHA
|
||||
INVOKE_ASYNC(GLOBAL_PROC, /proc/flick_overlay, MA, list(owner.client), 30)
|
||||
|
||||
for(var/mob/M in GLOB.dead_mob_list)
|
||||
var/link = FOLLOW_LINK(M, owner)
|
||||
to_chat(M, "[link] [dead_rendered]")
|
||||
|
||||
/mob/camera/imaginary_friend/Move(NewLoc, Dir = 0)
|
||||
if(world.time < move_delay)
|
||||
return FALSE
|
||||
if(get_dist(src, owner) > 9)
|
||||
recall()
|
||||
move_delay = world.time + 10
|
||||
return FALSE
|
||||
forceMove(NewLoc)
|
||||
move_delay = world.time + 1
|
||||
|
||||
/mob/camera/imaginary_friend/forceMove(atom/destination)
|
||||
dir = get_dir(get_turf(src), destination)
|
||||
loc = destination
|
||||
if(get_dist(src, owner) > 9)
|
||||
yank()
|
||||
return
|
||||
Show()
|
||||
|
||||
/mob/camera/imaginary_friend/movement_delay()
|
||||
return 2
|
||||
/mob/camera/imaginary_friend/proc/recall()
|
||||
if(!owner || loc == owner)
|
||||
return FALSE
|
||||
forceMove(owner)
|
||||
|
||||
/datum/action/innate/imaginary_join
|
||||
name = "Join"
|
||||
desc = "Join your owner, following them from inside their mind."
|
||||
icon_icon = 'icons/mob/actions/actions_minor_antag.dmi'
|
||||
background_icon_state = "bg_revenant"
|
||||
button_icon_state = "join"
|
||||
|
||||
/datum/action/innate/imaginary_join/Activate()
|
||||
var/mob/camera/imaginary_friend/I = owner
|
||||
I.recall()
|
||||
|
||||
/datum/action/innate/imaginary_hide
|
||||
name = "Hide"
|
||||
desc = "Hide yourself from your owner's sight."
|
||||
icon_icon = 'icons/mob/actions/actions_minor_antag.dmi'
|
||||
background_icon_state = "bg_revenant"
|
||||
button_icon_state = "hide"
|
||||
|
||||
/datum/action/innate/imaginary_hide/proc/update_status()
|
||||
var/mob/camera/imaginary_friend/I = owner
|
||||
if(I.hidden)
|
||||
name = "Show"
|
||||
desc = "Become visible to your owner."
|
||||
button_icon_state = "unhide"
|
||||
else
|
||||
name = "Hide"
|
||||
desc = "Hide yourself from your owner's sight."
|
||||
button_icon_state = "hide"
|
||||
UpdateButtonIcon()
|
||||
|
||||
/datum/action/innate/imaginary_hide/Activate()
|
||||
var/mob/camera/imaginary_friend/I = owner
|
||||
I.hidden = !I.hidden
|
||||
I.Show()
|
||||
update_status()
|
||||
@@ -51,7 +51,7 @@
|
||||
if(prob(3))
|
||||
owner.emote("drool")
|
||||
else if(owner.stat == CONSCIOUS && prob(3))
|
||||
owner.say(pick_list_replacements(BRAIN_DAMAGE_FILE, "brain_damage"))
|
||||
owner.say(pick_list_replacements(BRAIN_DAMAGE_FILE, "brain_damage"), forced = "brain damage")
|
||||
..()
|
||||
|
||||
/datum/brain_trauma/mild/dumbness/on_lose()
|
||||
@@ -176,7 +176,7 @@
|
||||
var/obj/item/I = owner.get_active_held_item()
|
||||
if(I)
|
||||
to_chat(owner, "<span class='warning'>Your fingers spasm!</span>")
|
||||
log_attack("[key_name(owner)] used [I] due to a Muscle Spasm.")
|
||||
owner.log_message("used [I] due to a Muscle Spasm", LOG_ATTACK)
|
||||
I.attack_self(owner)
|
||||
if(3)
|
||||
var/prev_intent = owner.a_intent
|
||||
@@ -192,14 +192,14 @@
|
||||
targets += M
|
||||
if(LAZYLEN(targets))
|
||||
to_chat(owner, "<span class='warning'>Your arm spasms!</span>")
|
||||
log_attack("[key_name(owner)] attacked someone due to a Muscle Spasm.") //the following attack will log itself
|
||||
owner.log_message(" attacked someone due to a Muscle Spasm") //the following attack will log itself
|
||||
owner.ClickOn(pick(targets))
|
||||
owner.a_intent = prev_intent
|
||||
if(4)
|
||||
var/prev_intent = owner.a_intent
|
||||
owner.a_intent = INTENT_HARM
|
||||
to_chat(owner, "<span class='warning'>Your arm spasms!</span>")
|
||||
log_attack("[key_name(owner)] attacked himself to a Muscle Spasm.")
|
||||
owner.log_message("attacked [owner.p_them()]self to a Muscle Spasm", LOG_ATTACK)
|
||||
owner.ClickOn(owner)
|
||||
owner.a_intent = prev_intent
|
||||
if(5)
|
||||
@@ -211,6 +211,6 @@
|
||||
targets += T
|
||||
if(LAZYLEN(targets) && I)
|
||||
to_chat(owner, "<span class='warning'>Your arm spasms!</span>")
|
||||
log_attack("[key_name(owner)] threw [I] due to a Muscle Spasm.")
|
||||
owner.log_message("threw [I] due to a Muscle Spasm", LOG_ATTACK)
|
||||
owner.throw_item(pick(targets))
|
||||
..()
|
||||
|
||||
@@ -107,7 +107,7 @@
|
||||
if(2)
|
||||
owner.emote("scream")
|
||||
owner.Jitter(5)
|
||||
owner.say("AAAAH!!")
|
||||
owner.say("AAAAH!!", forced = "phobia")
|
||||
if(reason)
|
||||
owner.pointed(reason)
|
||||
if(3)
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
if(prob(4))
|
||||
if(prob(33) && (owner.IsStun() || owner.IsKnockdown() || owner.IsUnconscious()))
|
||||
speak("unstun", TRUE)
|
||||
else if(prob(60) && owner.health <= HEALTH_THRESHOLD_CRIT)
|
||||
else if(prob(60) && owner.health <= owner.crit_threshold)
|
||||
speak("heal", TRUE)
|
||||
else if(prob(30) && owner.a_intent == INTENT_HARM)
|
||||
speak("aggressive")
|
||||
|
||||
@@ -138,11 +138,11 @@
|
||||
to_chat(src, "<span class='notice'>As a split personality, you cannot do anything but observe. However, you will eventually gain control of your body, switching places with the current personality.</span>")
|
||||
to_chat(src, "<span class='warning'><b>Do not commit suicide or put the body in a deadly position. Behave like you care about it as much as the owner.</b></span>")
|
||||
|
||||
/mob/living/split_personality/say(message)
|
||||
/mob/living/split_personality/say(message, bubble_type, var/list/spans = list(), sanitize = TRUE, datum/language/language = null, ignore_spam = FALSE, forced = null)
|
||||
to_chat(src, "<span class='warning'>You cannot speak, your other self is controlling your body!</span>")
|
||||
return FALSE
|
||||
|
||||
/mob/living/split_personality/emote(message)
|
||||
/mob/living/split_personality/emote(act, m_type = null, message = null, intentional = FALSE)
|
||||
return
|
||||
|
||||
///////////////BRAINWASHING////////////////////
|
||||
|
||||
@@ -371,9 +371,11 @@
|
||||
if (isnull(settings["mainsettings"][setting]["value"]))
|
||||
settings["mainsettings"][setting]["value"] = oldval
|
||||
if ("string")
|
||||
settings["mainsettings"][setting]["value"] = stripped_input(user, "Enter new value for [settings["mainsettings"][setting]["desc"]]", "Enter new value for [settings["mainsettings"][setting]["desc"]]")
|
||||
settings["mainsettings"][setting]["value"] = stripped_input(user, "Enter new value for [settings["mainsettings"][setting]["desc"]]", "Enter new value for [settings["mainsettings"][setting]["desc"]]", settings["mainsettings"][setting]["value"])
|
||||
if ("number")
|
||||
settings["mainsettings"][setting]["value"] = input(user, "Enter new value for [settings["mainsettings"][setting]["desc"]]", "Enter new value for [settings["mainsettings"][setting]["desc"]]") as num
|
||||
if ("color")
|
||||
settings["mainsettings"][setting]["value"] = input(user, "Enter new value for [settings["mainsettings"][setting]["desc"]]", "Enter new value for [settings["mainsettings"][setting]["desc"]]", settings["mainsettings"][setting]["value"]) as color
|
||||
if ("boolean")
|
||||
settings["mainsettings"][setting]["value"] = input(user, "[settings["mainsettings"][setting]["desc"]]?") in list("Yes","No")
|
||||
if ("ckey")
|
||||
|
||||
@@ -22,7 +22,8 @@ GLOBAL_LIST_EMPTY(cinematics)
|
||||
/obj/screen/cinematic
|
||||
icon = 'icons/effects/station_explosion.dmi'
|
||||
icon_state = "station_intact"
|
||||
layer = 21
|
||||
plane = SPLASHSCREEN_PLANE
|
||||
layer = SPLASHSCREEN_LAYER
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
screen_loc = "1,1"
|
||||
|
||||
@@ -34,6 +35,7 @@ GLOBAL_LIST_EMPTY(cinematics)
|
||||
var/obj/screen/cinematic/screen
|
||||
var/datum/callback/special_callback //For special effects synced with animation (explosions after the countdown etc)
|
||||
var/cleanup_time = 300 //How long for the final screen to remain
|
||||
var/stop_ooc = TRUE //Turns off ooc when played globally.
|
||||
|
||||
/datum/cinematic/New()
|
||||
GLOB.cinematics += src
|
||||
@@ -59,6 +61,12 @@ GLOBAL_LIST_EMPTY(cinematics)
|
||||
if(is_global)
|
||||
SStgui.close_all_uis()
|
||||
|
||||
//Pause OOC
|
||||
var/ooc_toggled = FALSE
|
||||
if(is_global && stop_ooc && GLOB.ooc_allowed)
|
||||
ooc_toggled = TRUE
|
||||
toggle_ooc(FALSE)
|
||||
|
||||
|
||||
for(var/mob/M in GLOB.mob_list)
|
||||
if(M in watchers)
|
||||
@@ -76,8 +84,14 @@ GLOBAL_LIST_EMPTY(cinematics)
|
||||
|
||||
//Actually play it
|
||||
content()
|
||||
|
||||
//Cleanup
|
||||
sleep(cleanup_time)
|
||||
|
||||
//Restore OOC
|
||||
if(ooc_toggled)
|
||||
toggle_ooc(TRUE)
|
||||
|
||||
qdel(src)
|
||||
|
||||
//Sound helper
|
||||
|
||||
@@ -32,8 +32,12 @@ Stands have a lot of procs which mimic mob procs. Rather than inserting hooks fo
|
||||
|
||||
1. `/datum/var/list/datum_components` (private)
|
||||
* Lazy associated list of type -> component/list of components.
|
||||
1. `/datum/component/var/enabled` (protected, boolean)
|
||||
* If the component is enabled. If not, it will not react to signals
|
||||
1. `/datum/var/list/comp_lookup` (private)
|
||||
* Lazy associated list of signal -> registree/list of registrees
|
||||
1. `/datum/var/list/signal_procs` (private)
|
||||
* Associated lazy list of signals -> `/datum/callback`s that will be run when the parent datum receives that signal
|
||||
1. `/datum/var/signal_enabled` (protected, boolean)
|
||||
* If the datum is signal enabled. If not, it will not react to signals
|
||||
* `FALSE` by default, set to `TRUE` when a signal is registered
|
||||
1. `/datum/component/var/dupe_mode` (protected, enum)
|
||||
* How duplicate component types are handled when added to the datum.
|
||||
@@ -45,8 +49,6 @@ Stands have a lot of procs which mimic mob procs. Rather than inserting hooks fo
|
||||
* Definition of a duplicate component type
|
||||
* `null` means exact match on `type` (default)
|
||||
* Any other type means that and all subtypes
|
||||
1. `/datum/component/var/list/signal_procs` (private)
|
||||
* Associated lazy list of signals -> `/datum/callback`s that will be run when the parent datum receives that signal
|
||||
1. `/datum/component/var/datum/parent` (protected, read-only)
|
||||
* The datum this component belongs to
|
||||
* Never `null` in child procs
|
||||
@@ -88,6 +90,14 @@ Stands have a lot of procs which mimic mob procs. Rather than inserting hooks fo
|
||||
1. `/datum/proc/_SendSignal(signal, list/arguments)` (private, final)
|
||||
* Handles most of the actual signaling procedure
|
||||
* Will runtime if used on datums with an empty component list
|
||||
1. `/datum/proc/RegisterSignal(datum/target, signal(string/list of strings), proc_ref(type), override(boolean))` (protected, final)
|
||||
* If signal is a list it will be as if RegisterSignal was called for each of the entries with the same following arguments
|
||||
* Makes the datum listen for the specified `signal` on it's `parent` datum.
|
||||
* When that signal is received `proc_ref` will be called on the component, along with associated arguments
|
||||
* Example proc ref: `.proc/OnEvent`
|
||||
* If a previous registration is overwritten by the call, a runtime occurs. Setting `override` to TRUE prevents this
|
||||
* These callbacks run asyncronously
|
||||
* Returning `TRUE` from these callbacks will trigger a `TRUE` return from the `SendSignal()` that initiated it
|
||||
1. `/datum/component/New(datum/parent, ...)` (private, final)
|
||||
* Runs internal setup for the component
|
||||
* Extra arguments are passed to `Initialize()`
|
||||
@@ -121,13 +131,5 @@ Stands have a lot of procs which mimic mob procs. Rather than inserting hooks fo
|
||||
1. `/datum/component/proc/UnregisterFromParent` (abstract, no-sleep)
|
||||
* Counterpart to `RegisterWithParent()`
|
||||
* Used to unregister the signals that should only be on the `parent` object
|
||||
1. `/datum/component/proc/RegisterSignal(datum/target, signal(string/list of strings), proc_ref(type), override(boolean))` (protected, final)
|
||||
* If signal is a list it will be as if RegisterSignal was called for each of the entries with the same following arguments
|
||||
* Makes a component listen for the specified `signal` on it's `parent` datum.
|
||||
* When that signal is received `proc_ref` will be called on the component, along with associated arguments
|
||||
* Example proc ref: `.proc/OnEvent`
|
||||
* If a previous registration is overwritten by the call, a runtime occurs. Setting `override` to TRUE prevents this
|
||||
* These callbacks run asyncronously
|
||||
* Returning `TRUE` from these callbacks will trigger a `TRUE` return from the `SendSignal()` that initiated it
|
||||
|
||||
### See/Define signals and their arguments in __DEFINES\components.dm
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
/datum/component
|
||||
var/enabled = FALSE
|
||||
var/dupe_mode = COMPONENT_DUPE_HIGHLANDER
|
||||
var/dupe_type
|
||||
var/list/signal_procs
|
||||
var/datum/parent
|
||||
|
||||
/datum/component/New(datum/P, ...)
|
||||
@@ -10,7 +8,7 @@
|
||||
var/list/arguments = args.Copy(2)
|
||||
if(Initialize(arglist(arguments)) == COMPONENT_INCOMPATIBLE)
|
||||
qdel(src, TRUE, TRUE)
|
||||
CRASH("Incompatible [type] assigned to a [P.type]!")
|
||||
CRASH("Incompatible [type] assigned to a [P.type]! args: [json_encode(arguments)]")
|
||||
|
||||
_JoinParent(P)
|
||||
|
||||
@@ -57,15 +55,11 @@
|
||||
return
|
||||
|
||||
/datum/component/Destroy(force=FALSE, silent=FALSE)
|
||||
enabled = FALSE
|
||||
var/datum/P = parent
|
||||
if(!force)
|
||||
if(!force && parent)
|
||||
_RemoveFromParent()
|
||||
if(!silent)
|
||||
SEND_SIGNAL(P, COMSIG_COMPONENT_REMOVING, src)
|
||||
SEND_SIGNAL(parent, COMSIG_COMPONENT_REMOVING, src)
|
||||
parent = null
|
||||
for(var/target in signal_procs)
|
||||
UnregisterSignal(target, signal_procs[target])
|
||||
return ..()
|
||||
|
||||
/datum/component/proc/_RemoveFromParent()
|
||||
@@ -89,7 +83,7 @@
|
||||
/datum/component/proc/UnregisterFromParent()
|
||||
return
|
||||
|
||||
/datum/component/proc/RegisterSignal(datum/target, sig_type_or_types, proc_or_callback, override = FALSE)
|
||||
/datum/proc/RegisterSignal(datum/target, sig_type_or_types, proc_or_callback, override = FALSE)
|
||||
if(QDELETED(src) || QDELETED(target))
|
||||
return
|
||||
|
||||
@@ -122,9 +116,9 @@
|
||||
else // Many other things have registered here
|
||||
lookup[sig_type][src] = TRUE
|
||||
|
||||
enabled = TRUE
|
||||
signal_enabled = TRUE
|
||||
|
||||
/datum/component/proc/UnregisterSignal(datum/target, sig_type_or_types)
|
||||
/datum/proc/UnregisterSignal(datum/target, sig_type_or_types)
|
||||
var/list/lookup = target.comp_lookup
|
||||
if(!signal_procs || !signal_procs[target] || !lookup)
|
||||
return
|
||||
@@ -174,15 +168,15 @@
|
||||
/datum/proc/_SendSignal(sigtype, list/arguments)
|
||||
var/target = comp_lookup[sigtype]
|
||||
if(!length(target))
|
||||
var/datum/component/C = target
|
||||
if(!C.enabled)
|
||||
var/datum/C = target
|
||||
if(!C.signal_enabled)
|
||||
return NONE
|
||||
var/datum/callback/CB = C.signal_procs[src][sigtype]
|
||||
return CB.InvokeAsync(arglist(arguments))
|
||||
. = NONE
|
||||
for(var/I in target)
|
||||
var/datum/component/C = I
|
||||
if(!C.enabled)
|
||||
var/datum/C = I
|
||||
if(!C.signal_enabled)
|
||||
continue
|
||||
var/datum/callback/CB = C.signal_procs[src][sigtype]
|
||||
. |= CB.InvokeAsync(arglist(arguments))
|
||||
@@ -232,6 +226,7 @@
|
||||
CRASH("[nt]: Invalid dupe_type ([dt])!")
|
||||
else
|
||||
new_comp = nt
|
||||
nt = new_comp.type
|
||||
|
||||
args[1] = src
|
||||
|
||||
@@ -281,10 +276,11 @@
|
||||
var/datum/old_parent = parent
|
||||
PreTransfer()
|
||||
_RemoveFromParent()
|
||||
parent = null
|
||||
SEND_SIGNAL(old_parent, COMSIG_COMPONENT_REMOVING, src)
|
||||
|
||||
/datum/proc/TakeComponent(datum/component/target)
|
||||
if(!target)
|
||||
if(!target || target.parent == src)
|
||||
return
|
||||
if(target.parent)
|
||||
target.RemoveComponent()
|
||||
|
||||
@@ -14,13 +14,13 @@
|
||||
magic = _magic
|
||||
holy = _holy
|
||||
|
||||
/datum/component/anti_magic/proc/on_equip(mob/equipper, slot)
|
||||
/datum/component/anti_magic/proc/on_equip(datum/source, mob/equipper, slot)
|
||||
RegisterSignal(equipper, COMSIG_MOB_RECEIVE_MAGIC, .proc/can_protect, TRUE)
|
||||
|
||||
/datum/component/anti_magic/proc/on_drop(mob/user)
|
||||
/datum/component/anti_magic/proc/on_drop(datum/source, mob/user)
|
||||
UnregisterSignal(user, COMSIG_MOB_RECEIVE_MAGIC)
|
||||
|
||||
/datum/component/anti_magic/proc/can_protect(_magic, _holy, list/protection_sources)
|
||||
/datum/component/anti_magic/proc/can_protect(datum/source, _magic, _holy, list/protection_sources)
|
||||
if((_magic && magic) || (_holy && holy))
|
||||
protection_sources += parent
|
||||
return COMPONENT_BLOCK_MAGIC
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
for(var/I in other_archdrops)
|
||||
_archdrops[I] += other_archdrops[I]
|
||||
|
||||
/datum/component/archaeology/proc/Dig(obj/item/I, mob/living/user)
|
||||
/datum/component/archaeology/proc/Dig(datum/source, obj/item/I, mob/living/user)
|
||||
if(dug)
|
||||
to_chat(user, "<span class='notice'>Looks like someone has dug here already.</span>")
|
||||
return
|
||||
@@ -72,7 +72,7 @@
|
||||
if(callback)
|
||||
callback.Invoke()
|
||||
|
||||
/datum/component/archaeology/proc/SingDig(S, current_size)
|
||||
/datum/component/archaeology/proc/SingDig(datum/source, S, current_size)
|
||||
switch(current_size)
|
||||
if(STAGE_THREE)
|
||||
if(prob(30))
|
||||
@@ -84,7 +84,7 @@
|
||||
if(current_size >= STAGE_FIVE && prob(70))
|
||||
gets_dug()
|
||||
|
||||
/datum/component/archaeology/proc/BombDig(severity, target)
|
||||
/datum/component/archaeology/proc/BombDig(datum/source, severity, target)
|
||||
switch(severity)
|
||||
if(3)
|
||||
return
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
var/obj/item/typecast = upgrade_item
|
||||
upgrade_name = initial(typecast.name)
|
||||
|
||||
/datum/component/armor_plate/proc/examine(mob/user)
|
||||
/datum/component/armor_plate/proc/examine(datum/source, mob/user)
|
||||
//upgrade_item could also be typecast here instead
|
||||
if(ismecha(parent))
|
||||
if(amount)
|
||||
@@ -45,7 +45,7 @@
|
||||
else
|
||||
to_chat(user, "<span class='notice'>It can be strengthened with up to [maxamount] [upgrade_name].</span>")
|
||||
|
||||
/datum/component/armor_plate/proc/applyplate(obj/item/I, mob/user, params)
|
||||
/datum/component/armor_plate/proc/applyplate(datum/source, obj/item/I, mob/user, params)
|
||||
if(!istype(I,upgrade_item))
|
||||
return
|
||||
if(amount >= maxamount)
|
||||
@@ -72,7 +72,7 @@
|
||||
to_chat(user, "<span class='info'>You strengthen [O], improving its resistance against melee attacks.</span>")
|
||||
|
||||
|
||||
/datum/component/armor_plate/proc/dropplates(force)
|
||||
/datum/component/armor_plate/proc/dropplates(datum/source, force)
|
||||
if(ismecha(parent)) //items didn't drop the plates before and it causes erroneous behavior for the time being with collapsible helmets
|
||||
for(var/i in 1 to amount)
|
||||
new upgrade_item(get_turf(parent))
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
RegisterSignal(parent, list(COMSIG_MOVABLE_CROSSED), .proc/Crossed)
|
||||
|
||||
/datum/component/caltrop/proc/Crossed(atom/movable/AM)
|
||||
/datum/component/caltrop/proc/Crossed(datum/source, atom/movable/AM)
|
||||
var/atom/A = parent
|
||||
if(!A.has_gravity())
|
||||
return
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
target_turf = target
|
||||
START_PROCESSING(SSobj, src) // process on create, in case stuff is still there
|
||||
|
||||
/datum/component/chasm/proc/Entered(atom/movable/AM)
|
||||
/datum/component/chasm/proc/Entered(datum/source, atom/movable/AM)
|
||||
START_PROCESSING(SSobj, src)
|
||||
drop_stuff(AM)
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
RegisterSignal(parent, COMSIG_PARENT_ATTACKBY,.proc/action)
|
||||
update_parent(index)
|
||||
|
||||
/datum/component/construction/proc/examine(mob/user)
|
||||
/datum/component/construction/proc/examine(datum/source, mob/user)
|
||||
if(desc)
|
||||
to_chat(user, desc)
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
else
|
||||
update_parent(index)
|
||||
|
||||
/datum/component/construction/proc/action(obj/item/I, mob/living/user)
|
||||
/datum/component/construction/proc/action(datum/source, obj/item/I, mob/living/user)
|
||||
return check_step(I, user)
|
||||
|
||||
/datum/component/construction/proc/update_index(diff)
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
|
||||
var/first_dir // This only stores the dir arg from init
|
||||
|
||||
/datum/component/decal/Initialize(_icon, _icon_state, _dir, _cleanable=CLEAN_GOD, _color, _layer=TURF_LAYER, _description)
|
||||
if(!isatom(parent) || !generate_appearance(_icon, _icon_state, _dir, _layer, _color))
|
||||
/datum/component/decal/Initialize(_icon, _icon_state, _dir, _cleanable=CLEAN_GOD, _color, _layer=TURF_LAYER, _description, _alpha=255)
|
||||
if(!isatom(parent) || !generate_appearance(_icon, _icon_state, _dir, _layer, _color, _alpha))
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
first_dir = _dir
|
||||
description = _description
|
||||
@@ -38,13 +38,14 @@
|
||||
remove()
|
||||
apply()
|
||||
|
||||
/datum/component/decal/proc/generate_appearance(_icon, _icon_state, _dir, _layer, _color)
|
||||
/datum/component/decal/proc/generate_appearance(_icon, _icon_state, _dir, _layer, _color, _alpha)
|
||||
if(!_icon || !_icon_state)
|
||||
return FALSE
|
||||
// It has to be made from an image or dir breaks because of a byond bug
|
||||
var/temp_image = image(_icon, null, _icon_state, _layer, _dir)
|
||||
pic = new(temp_image)
|
||||
pic.color = _color
|
||||
pic.alpha = _alpha
|
||||
return TRUE
|
||||
|
||||
/datum/component/decal/proc/apply(atom/thing)
|
||||
@@ -59,16 +60,16 @@
|
||||
if(isitem(master))
|
||||
addtimer(CALLBACK(master, /obj/item/.proc/update_slot_icon), 0, TIMER_UNIQUE)
|
||||
|
||||
/datum/component/decal/proc/rotate_react(old_dir, new_dir)
|
||||
/datum/component/decal/proc/rotate_react(datum/source, old_dir, new_dir)
|
||||
if(old_dir == new_dir)
|
||||
return
|
||||
remove()
|
||||
pic.dir = turn(pic.dir, dir2angle(old_dir) - dir2angle(new_dir))
|
||||
apply()
|
||||
|
||||
/datum/component/decal/proc/clean_react(strength)
|
||||
/datum/component/decal/proc/clean_react(datum/source, strength)
|
||||
if(strength >= cleanable)
|
||||
qdel(src)
|
||||
|
||||
/datum/component/decal/proc/examine(mob/user)
|
||||
/datum/component/decal/proc/examine(datum/source, mob/user)
|
||||
to_chat(user, description)
|
||||
@@ -32,7 +32,7 @@
|
||||
blood_splatter_appearances[index] = pic
|
||||
return TRUE
|
||||
|
||||
/datum/component/decal/blood/proc/get_examine_name(mob/user, list/override)
|
||||
/datum/component/decal/blood/proc/get_examine_name(datum/source, mob/user, list/override)
|
||||
var/atom/A = parent
|
||||
override[EXAMINE_POSITION_ARTICLE] = A.gender == PLURAL? "some" : "a"
|
||||
override[EXAMINE_POSITION_BEFORE] = " blood-stained "
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
RegisterSignal(parent, list(COMSIG_ITEM_EQUIPPED, COMSIG_ITEM_DROPPED), .proc/equippedChanged)
|
||||
|
||||
/datum/component/earhealing/proc/equippedChanged(mob/living/carbon/user, slot)
|
||||
/datum/component/earhealing/proc/equippedChanged(datum/source, mob/living/carbon/user, slot)
|
||||
if (slot == SLOT_EARS && istype(user))
|
||||
if (!wearer)
|
||||
START_PROCESSING(SSobj, src)
|
||||
|
||||
@@ -7,5 +7,5 @@
|
||||
valid_slots = _valid_slots
|
||||
callback = CALLBACK(src, .proc/reducebang)
|
||||
|
||||
/datum/component/wearertargeting/earprotection/proc/reducebang(list/reflist)
|
||||
/datum/component/wearertargeting/earprotection/proc/reducebang(datum/source, list/reflist)
|
||||
reflist[1]--
|
||||
|
||||
@@ -18,6 +18,6 @@
|
||||
|
||||
RegisterSignal(SSdcs, COMSIG_GLOB_VAR_EDIT, .proc/var_edit_react)
|
||||
|
||||
/datum/component/edit_complainer/proc/var_edit_react(list/arguments)
|
||||
/datum/component/edit_complainer/proc/var_edit_react(datum/source, list/arguments)
|
||||
var/atom/movable/master = parent
|
||||
master.say(pick(say_lines))
|
||||
|
||||
@@ -7,5 +7,5 @@
|
||||
flags = _flags
|
||||
RegisterSignal(parent, list(COMSIG_ATOM_EMP_ACT), .proc/getEmpFlags)
|
||||
|
||||
/datum/component/empprotection/proc/getEmpFlags(severity)
|
||||
/datum/component/empprotection/proc/getEmpFlags(datum/source, severity)
|
||||
return flags
|
||||
|
||||
39
code/datums/components/footstep.dm
Normal file
39
code/datums/components/footstep.dm
Normal file
@@ -0,0 +1,39 @@
|
||||
/datum/component/footstep
|
||||
var/steps = 0
|
||||
var/volume
|
||||
var/e_range
|
||||
|
||||
/datum/component/footstep/Initialize(volume_ = 0.5, e_range_ = -1)
|
||||
if(!isliving(parent))
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
volume = volume_
|
||||
e_range = e_range_
|
||||
RegisterSignal(parent, list(COMSIG_MOVABLE_MOVED), .proc/play_footstep)
|
||||
|
||||
/datum/component/footstep/proc/play_footstep()
|
||||
var/turf/open/T = get_turf(parent)
|
||||
if(!istype(T))
|
||||
return
|
||||
var/mob/living/LM = parent
|
||||
var/v = volume
|
||||
var/e = e_range
|
||||
if(!T.footstep || LM.lying || !LM.canmove || LM.resting || LM.buckled || LM.throwing)
|
||||
return
|
||||
if(iscarbon(LM))
|
||||
var/mob/living/carbon/C = LM
|
||||
if(!C.get_bodypart(BODY_ZONE_L_LEG) && !C.get_bodypart(BODY_ZONE_R_LEG))
|
||||
return
|
||||
if(ishuman(C) && C.m_intent == MOVE_INTENT_WALK)
|
||||
v /= 2
|
||||
e -= 5
|
||||
steps++
|
||||
if(steps >= 6)
|
||||
steps = 0
|
||||
if(steps % 2)
|
||||
return
|
||||
if(!LM.has_gravity(T) && steps != 0) // don't need to step as often when you hop around
|
||||
return
|
||||
playsound(T, pick(GLOB.footstep[T.footstep][1]),
|
||||
GLOB.footstep[T.footstep][2] * v,
|
||||
TRUE,
|
||||
GLOB.footstep[T.footstep][3] + e)
|
||||
@@ -1,8 +1,20 @@
|
||||
/datum/component/forced_gravity
|
||||
var/gravity = 1
|
||||
var/gravity
|
||||
var/ignore_space = FALSE //If forced gravity should also work on space turfs
|
||||
|
||||
/datum/component/forced_gravity/Initialize(forced_value = 1)
|
||||
if(!isatom(parent))
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
RegisterSignal(COMSIG_ATOM_HAS_GRAVITY, .proc/gravity_check)
|
||||
if(isturf(parent))
|
||||
RegisterSignal(COMSIG_TURF_HAS_GRAVITY, .proc/turf_gravity_check)
|
||||
|
||||
gravity = forced_value
|
||||
|
||||
/datum/component/forced_gravity/proc/gravity_check(datum/source, turf/location, list/gravs)
|
||||
if(!ignore_space && isspaceturf(location))
|
||||
return
|
||||
gravs += gravity
|
||||
|
||||
/datum/component/forced_gravity/proc/turf_gravity_check(datum/source, atom/checker, list/gravs)
|
||||
return gravity_check(parent, gravs)
|
||||
@@ -40,7 +40,7 @@
|
||||
fibers = null
|
||||
return TRUE
|
||||
|
||||
/datum/component/forensics/proc/clean_act(strength)
|
||||
/datum/component/forensics/proc/clean_act(datum/source, strength)
|
||||
if(strength >= CLEAN_STRENGTH_FINGERPRINTS)
|
||||
wipe_fingerprints()
|
||||
if(strength >= CLEAN_STRENGTH_BLOOD)
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
expire_time = world.time + expire_in
|
||||
QDEL_IN(src, expire_in)
|
||||
RegisterSignal(parent, COMSIG_MOVABLE_BUCKLE, .proc/try_infect_buckle)
|
||||
RegisterSignal(parent, COMSIG_MOVABLE_COLLIDE, .proc/try_infect_collide)
|
||||
RegisterSignal(parent, COMSIG_MOVABLE_BUMP, .proc/try_infect_collide)
|
||||
RegisterSignal(parent, COMSIG_MOVABLE_CROSSED, .proc/try_infect_crossed)
|
||||
RegisterSignal(parent, COMSIG_ITEM_ATTACK_ZONE, .proc/try_infect_attack_zone)
|
||||
RegisterSignal(parent, COMSIG_ITEM_ATTACK, .proc/try_infect_attack)
|
||||
@@ -22,20 +22,20 @@
|
||||
RegisterSignal(parent, COMSIG_FOOD_EATEN, .proc/try_infect_eat)
|
||||
RegisterSignal(parent, COMSIG_COMPONENT_CLEAN_ACT, .proc/clean)
|
||||
|
||||
/datum/component/infective/proc/try_infect_eat(mob/living/eater, mob/living/feeder)
|
||||
/datum/component/infective/proc/try_infect_eat(datum/source, mob/living/eater, mob/living/feeder)
|
||||
for(var/V in diseases)
|
||||
eater.ForceContractDisease(V)
|
||||
try_infect(feeder, BODY_ZONE_L_ARM)
|
||||
|
||||
/datum/component/infective/proc/clean(clean_strength)
|
||||
/datum/component/infective/proc/clean(datum/source, clean_strength)
|
||||
if(clean_strength >= min_clean_strength)
|
||||
qdel(src)
|
||||
|
||||
/datum/component/infective/proc/try_infect_buckle(mob/M, force)
|
||||
/datum/component/infective/proc/try_infect_buckle(datum/source, mob/M, force)
|
||||
if(isliving(M))
|
||||
try_infect(M)
|
||||
|
||||
/datum/component/infective/proc/try_infect_collide(atom/A)
|
||||
/datum/component/infective/proc/try_infect_collide(datum/source, atom/A)
|
||||
var/atom/movable/P = parent
|
||||
if(P.throwing)
|
||||
//this will be handled by try_infect_impact_zone()
|
||||
@@ -43,19 +43,19 @@
|
||||
if(isliving(A))
|
||||
try_infect(A)
|
||||
|
||||
/datum/component/infective/proc/try_infect_impact_zone(mob/living/target, hit_zone)
|
||||
/datum/component/infective/proc/try_infect_impact_zone(datum/source, mob/living/target, hit_zone)
|
||||
try_infect(target, hit_zone)
|
||||
|
||||
/datum/component/infective/proc/try_infect_attack_zone(mob/living/carbon/target, mob/living/user, hit_zone)
|
||||
/datum/component/infective/proc/try_infect_attack_zone(datum/source, mob/living/carbon/target, mob/living/user, hit_zone)
|
||||
try_infect(user, BODY_ZONE_L_ARM)
|
||||
try_infect(target, hit_zone)
|
||||
|
||||
/datum/component/infective/proc/try_infect_attack(mob/living/target, mob/living/user)
|
||||
/datum/component/infective/proc/try_infect_attack(datum/source, mob/living/target, mob/living/user)
|
||||
if(!iscarbon(target)) //this case will be handled by try_infect_attack_zone
|
||||
try_infect(target)
|
||||
try_infect(user, BODY_ZONE_L_ARM)
|
||||
|
||||
/datum/component/infective/proc/try_infect_equipped(mob/living/L, slot)
|
||||
/datum/component/infective/proc/try_infect_equipped(datum/source, mob/living/L, slot)
|
||||
var/old_permeability
|
||||
if(isitem(parent))
|
||||
//if you are putting an infective item on, it obviously will not protect you, so set its permeability high enough that it will never block ContactContractDisease()
|
||||
@@ -69,7 +69,7 @@
|
||||
var/obj/item/I = parent
|
||||
I.permeability_coefficient = old_permeability
|
||||
|
||||
/datum/component/infective/proc/try_infect_crossed(atom/movable/M)
|
||||
/datum/component/infective/proc/try_infect_crossed(datum/source, atom/movable/M)
|
||||
if(isliving(M))
|
||||
try_infect(M, BODY_ZONE_PRECISE_L_FOOT)
|
||||
|
||||
|
||||
@@ -22,17 +22,17 @@
|
||||
RegisterSignal(parent, COMSIG_ITEM_DROPPED, .proc/on_drop)
|
||||
RegisterSignal(parent, COMSIG_ITEM_ATTACK, .proc/on_attack)
|
||||
|
||||
/datum/component/jousting/proc/on_equip(mob/user, slot)
|
||||
/datum/component/jousting/proc/on_equip(datum/source, mob/user, slot)
|
||||
RegisterSignal(user, COMSIG_MOVABLE_MOVED, .proc/mob_move, TRUE)
|
||||
current_holder = user
|
||||
|
||||
/datum/component/jousting/proc/on_drop(mob/user)
|
||||
/datum/component/jousting/proc/on_drop(datum/source, mob/user)
|
||||
UnregisterSignal(user, COMSIG_MOVABLE_MOVED)
|
||||
current_holder = null
|
||||
current_direction = NONE
|
||||
current_tile_charge = 0
|
||||
|
||||
/datum/component/jousting/proc/on_attack(mob/living/target, mob/user)
|
||||
/datum/component/jousting/proc/on_attack(datum/source, mob/living/target, mob/user)
|
||||
if(user != current_holder)
|
||||
return
|
||||
var/current = current_tile_charge
|
||||
@@ -58,7 +58,7 @@
|
||||
if(length(msg))
|
||||
user.visible_message("<span class='danger'>[msg]!</span>")
|
||||
|
||||
/datum/component/jousting/proc/mob_move(newloc, dir)
|
||||
/datum/component/jousting/proc/mob_move(datum/source, newloc, dir)
|
||||
if(!current_holder || (requires_mount && ((requires_mob_riding && !ismob(current_holder.buckled)) || (!current_holder.buckled))))
|
||||
return
|
||||
if(dir != current_direction)
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
var/knockoff_chance = 100 //Chance to knockoff
|
||||
var/list/target_zones //Aiming for these zones will cause the knockoff, null means all zones allowed
|
||||
var/list/slots_knockoffable //Can be only knocked off from these slots, null means all slots allowed
|
||||
var/datum/component/redirect/disarm_redirect
|
||||
|
||||
/datum/component/knockoff/Initialize(knockoff_chance,zone_override,slots_knockoffable)
|
||||
if(!isitem(parent))
|
||||
@@ -33,7 +32,7 @@
|
||||
|
||||
wearer.visible_message("<span class='warning'>[attacker] knocks off [wearer]'s [I.name]!</span>","<span class='userdanger'>[attacker] knocks off your [I.name]!</span>")
|
||||
|
||||
/datum/component/knockoff/proc/OnEquipped(mob/living/carbon/human/H,slot)
|
||||
/datum/component/knockoff/proc/OnEquipped(datum/source, mob/living/carbon/human/H,slot)
|
||||
if(!istype(H))
|
||||
return
|
||||
if(slots_knockoffable && !(slot in slots_knockoffable))
|
||||
@@ -41,5 +40,5 @@
|
||||
return
|
||||
RegisterSignal(H, COMSIG_HUMAN_DISARM_HIT, .proc/Knockoff, TRUE)
|
||||
|
||||
/datum/component/knockoff/proc/OnDropped(mob/living/M)
|
||||
/datum/component/knockoff/proc/OnDropped(datum/source, mob/living/M)
|
||||
UnregisterSignal(M, COMSIG_HUMAN_DISARM_HIT)
|
||||
@@ -1,23 +1,34 @@
|
||||
/datum/component/magnetic_catch/Initialize()
|
||||
if(!isatom(parent))
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
if(ismovableatom(parent))
|
||||
RegisterSignal(parent, COMSIG_MOVABLE_UNCROSS, .proc/uncross_react)
|
||||
else
|
||||
RegisterSignal(parent, COMSIG_ATOM_EXIT, .proc/exit_react)
|
||||
RegisterSignal(parent, COMSIG_PARENT_EXAMINE, .proc/examine)
|
||||
if(ismovableatom(parent))
|
||||
RegisterSignal(parent, COMSIG_MOVABLE_CROSSED, .proc/crossed_react)
|
||||
RegisterSignal(parent, COMSIG_MOVABLE_UNCROSSED, .proc/uncrossed_react)
|
||||
for(var/i in get_turf(parent))
|
||||
if(i == parent)
|
||||
continue
|
||||
RegisterSignal(i, COMSIG_MOVABLE_PRE_THROW, .proc/throw_react)
|
||||
else
|
||||
RegisterSignal(parent, COMSIG_ATOM_ENTERED, .proc/entered_react)
|
||||
RegisterSignal(parent, COMSIG_ATOM_EXITED, .proc/exited_react)
|
||||
for(var/i in parent)
|
||||
RegisterSignal(i, COMSIG_MOVABLE_PRE_THROW, .proc/throw_react)
|
||||
|
||||
/datum/component/magnetic_catch/proc/uncross_react(atom/movable/thing)
|
||||
if(!thing.throwing || thing.throwing.thrower)
|
||||
return
|
||||
qdel(thing.throwing)
|
||||
return COMPONENT_MOVABLE_BLOCK_UNCROSS
|
||||
|
||||
/datum/component/magnetic_catch/proc/exit_react(atom/movable/thing, atom/newloc)
|
||||
if(!thing.throwing || thing.throwing.thrower)
|
||||
return
|
||||
qdel(thing.throwing)
|
||||
return COMPONENT_ATOM_BLOCK_EXIT
|
||||
|
||||
/datum/component/magnetic_catch/proc/examine(mob/user)
|
||||
/datum/component/magnetic_catch/proc/examine(datum/source, mob/user)
|
||||
to_chat(user, "It has been installed with inertia dampening to prevent coffee spills.")
|
||||
|
||||
/datum/component/magnetic_catch/proc/crossed_react(datum/source, atom/movable/thing)
|
||||
RegisterSignal(thing, COMSIG_MOVABLE_PRE_THROW, .proc/throw_react, TRUE)
|
||||
|
||||
/datum/component/magnetic_catch/proc/uncrossed_react(datum/source, atom/movable/thing)
|
||||
UnregisterSignal(thing, COMSIG_MOVABLE_PRE_THROW)
|
||||
|
||||
/datum/component/magnetic_catch/proc/entered_react(datum/source, atom/movable/thing, atom/oldloc)
|
||||
RegisterSignal(thing, COMSIG_MOVABLE_PRE_THROW, .proc/throw_react, TRUE)
|
||||
|
||||
/datum/component/magnetic_catch/proc/exited_react(datum/source, atom/movable/thing, atom/newloc)
|
||||
UnregisterSignal(thing, COMSIG_MOVABLE_PRE_THROW)
|
||||
|
||||
/datum/component/magnetic_catch/proc/throw_react(datum/source, list/arguments)
|
||||
return COMPONENT_CANCEL_THROW
|
||||
@@ -27,8 +27,13 @@
|
||||
max_amount = max(0, max_amt)
|
||||
show_on_examine = _show_on_examine
|
||||
disable_attackby = _disable_attackby
|
||||
|
||||
if(allowed_types)
|
||||
if(ispath(allowed_types) && allowed_types == /obj/item/stack)
|
||||
allowed_typecache = GLOB.typecache_stack
|
||||
else
|
||||
allowed_typecache = typecacheof(allowed_types)
|
||||
|
||||
precondition = _precondition
|
||||
after_insert = _after_insert
|
||||
|
||||
@@ -44,7 +49,7 @@
|
||||
var/mat_path = possible_mats[id]
|
||||
materials[id] = new mat_path()
|
||||
|
||||
/datum/component/material_container/proc/OnExamine(mob/user)
|
||||
/datum/component/material_container/proc/OnExamine(datum/source, mob/user)
|
||||
if(show_on_examine)
|
||||
for(var/I in materials)
|
||||
var/datum/material/M = materials[I]
|
||||
@@ -52,7 +57,7 @@
|
||||
if(amt)
|
||||
to_chat(user, "<span class='notice'>It has [amt] units of [lowertext(M.name)] stored.</span>")
|
||||
|
||||
/datum/component/material_container/proc/OnAttackBy(obj/item/I, mob/living/user)
|
||||
/datum/component/material_container/proc/OnAttackBy(datum/source, obj/item/I, mob/living/user)
|
||||
var/list/tc = allowed_typecache
|
||||
if(disable_attackby)
|
||||
return
|
||||
@@ -242,24 +247,25 @@
|
||||
//For spawning mineral sheets; internal use only
|
||||
/datum/component/material_container/proc/retrieve(sheet_amt, datum/material/M, target = null)
|
||||
if(!M.sheet_type)
|
||||
return FALSE
|
||||
if(sheet_amt > 0)
|
||||
return 0
|
||||
if(sheet_amt <= 0)
|
||||
return 0
|
||||
|
||||
if(!target)
|
||||
target = get_turf(parent)
|
||||
if(M.amount < (sheet_amt * MINERAL_MATERIAL_AMOUNT))
|
||||
sheet_amt = round(M.amount / MINERAL_MATERIAL_AMOUNT)
|
||||
var/count = 0
|
||||
while(sheet_amt > MAX_STACK_SIZE)
|
||||
new M.sheet_type(get_turf(parent), MAX_STACK_SIZE)
|
||||
new M.sheet_type(target, MAX_STACK_SIZE)
|
||||
count += MAX_STACK_SIZE
|
||||
use_amount_type(sheet_amt * MINERAL_MATERIAL_AMOUNT, M.id)
|
||||
sheet_amt -= MAX_STACK_SIZE
|
||||
if(round((sheet_amt * MINERAL_MATERIAL_AMOUNT) / MINERAL_MATERIAL_AMOUNT))
|
||||
var/obj/item/stack/sheet/s = new M.sheet_type(get_turf(parent), sheet_amt)
|
||||
if(target)
|
||||
s.forceMove(target)
|
||||
if(sheet_amt >= 1)
|
||||
new M.sheet_type(target, sheet_amt)
|
||||
count += sheet_amt
|
||||
use_amount_type(sheet_amt * MINERAL_MATERIAL_AMOUNT, M.id)
|
||||
return count
|
||||
return FALSE
|
||||
|
||||
/datum/component/material_container/proc/retrieve_sheets(sheet_amt, id, target = null)
|
||||
if(materials[id])
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
#define MINOR_INSANITY_PEN 5
|
||||
#define MAJOR_INSANITY_PEN 10
|
||||
|
||||
/datum/component/mood
|
||||
var/mood //Real happiness
|
||||
var/sanity = 100 //Current sanity
|
||||
@@ -5,25 +8,32 @@
|
||||
var/mood_level = 5 //To track what stage of moodies they're on
|
||||
var/mood_modifier = 1 //Modifier to allow certain mobs to be less affected by moodlets
|
||||
var/datum/mood_event/list/mood_events = list()
|
||||
var/mob/living/owner
|
||||
var/datum/looping_sound/reverse_bear_trap/slow/soundloop //Insanity ticking
|
||||
var/insanity_effect = 0 //is the owner being punished for low mood? If so, how much?
|
||||
var/holdmyinsanityeffect = 0 //before we edit our sanity lets take a look
|
||||
var/obj/screen/mood/screen_obj
|
||||
|
||||
/datum/component/mood/Initialize()
|
||||
if(!isliving(parent))
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
|
||||
START_PROCESSING(SSmood, src)
|
||||
owner = parent
|
||||
soundloop = new(list(owner), FALSE, TRUE)
|
||||
|
||||
RegisterSignal(parent, COMSIG_ADD_MOOD_EVENT, .proc/add_event)
|
||||
RegisterSignal(parent, COMSIG_CLEAR_MOOD_EVENT, .proc/clear_event)
|
||||
RegisterSignal(parent, COMSIG_ENTER_AREA, .proc/update_beauty)
|
||||
|
||||
RegisterSignal(parent, COMSIG_MOB_HUD_CREATED, .proc/modify_hud)
|
||||
var/mob/living/owner = parent
|
||||
if(owner.hud_used)
|
||||
modify_hud()
|
||||
var/datum/hud/hud = owner.hud_used
|
||||
hud.show_hud(hud.hud_version)
|
||||
|
||||
/datum/component/mood/Destroy()
|
||||
STOP_PROCESSING(SSmood, src)
|
||||
QDEL_NULL(soundloop)
|
||||
unmodify_hud()
|
||||
return ..()
|
||||
|
||||
/datum/component/mood/proc/print_mood()
|
||||
/datum/component/mood/proc/print_mood(mob/user)
|
||||
var/msg = "<span class='info'>*---------*\n<EM>Your current mood</EM>\n"
|
||||
msg += "<span class='notice'>My mental status: </span>" //Long term
|
||||
switch(sanity)
|
||||
@@ -67,8 +77,8 @@
|
||||
var/datum/mood_event/event = mood_events[i]
|
||||
msg += event.description
|
||||
else
|
||||
msg += "<span class='nicegreen'>Nothing special has happened to me lately!<span>\n"
|
||||
to_chat(owner, msg)
|
||||
msg += "<span class='nicegreen'>I don't have much of a reaction to anything right now.<span>\n"
|
||||
to_chat(user || parent, msg)
|
||||
|
||||
/datum/component/mood/proc/update_mood() //Called whenever a mood event is added or removed
|
||||
mood = 0
|
||||
@@ -104,41 +114,25 @@
|
||||
|
||||
|
||||
/datum/component/mood/proc/update_mood_icon()
|
||||
var/mob/living/owner = parent
|
||||
if(owner.client && owner.hud_used)
|
||||
if(sanity < 25)
|
||||
owner.hud_used.mood.icon_state = "mood_insane"
|
||||
screen_obj.icon_state = "mood_insane"
|
||||
else
|
||||
owner.hud_used.mood.icon_state = "mood[mood_level]"
|
||||
screen_obj.icon_state = "mood[mood_level]"
|
||||
|
||||
/datum/component/mood/process() //Called on SSmood process
|
||||
switch(sanity)
|
||||
if(SANITY_INSANE to SANITY_CRAZY)
|
||||
owner.overlay_fullscreen("depression", /obj/screen/fullscreen/depression, 3)
|
||||
update_mood_icon()
|
||||
if(prob(7))
|
||||
owner.playsound_local(null, pick(CREEPY_SOUNDS), 40, 1)
|
||||
soundloop.start()
|
||||
if(SANITY_INSANE to SANITY_UNSTABLE)
|
||||
owner.overlay_fullscreen("depression", /obj/screen/fullscreen/depression, 2)
|
||||
if(prob(3))
|
||||
owner.playsound_local(null, pick(CREEPY_SOUNDS), 20, 1)
|
||||
soundloop.stop()
|
||||
if(SANITY_UNSTABLE to SANITY_DISTURBED)
|
||||
owner.overlay_fullscreen("depression", /obj/screen/fullscreen/depression, 1)
|
||||
soundloop.stop()
|
||||
if(SANITY_DISTURBED to INFINITY)
|
||||
owner.clear_fullscreen("depression")
|
||||
soundloop.stop()
|
||||
var/mob/living/owner = parent
|
||||
|
||||
switch(mood_level)
|
||||
if(1)
|
||||
DecreaseSanity(0.2, 0)
|
||||
DecreaseSanity(0.2)
|
||||
if(2)
|
||||
DecreaseSanity(0.125, 25)
|
||||
DecreaseSanity(0.125, SANITY_CRAZY)
|
||||
if(3)
|
||||
DecreaseSanity(0.075, 50)
|
||||
DecreaseSanity(0.075, SANITY_UNSTABLE)
|
||||
if(4)
|
||||
DecreaseSanity(0.025, 75)
|
||||
DecreaseSanity(0.025, SANITY_DISTURBED)
|
||||
if(5)
|
||||
IncreaseSanity(0.1)
|
||||
if(6)
|
||||
@@ -146,42 +140,60 @@
|
||||
if(7)
|
||||
IncreaseSanity(0.20)
|
||||
if(8)
|
||||
IncreaseSanity(0.25, 125)
|
||||
IncreaseSanity(0.25, SANITY_GREAT)
|
||||
if(9)
|
||||
IncreaseSanity(0.4, 125)
|
||||
IncreaseSanity(0.4, SANITY_GREAT)
|
||||
|
||||
if(insanity_effect != holdmyinsanityeffect)
|
||||
if(insanity_effect > holdmyinsanityeffect)
|
||||
owner.crit_threshold += (insanity_effect - holdmyinsanityeffect)
|
||||
else
|
||||
owner.crit_threshold -= (holdmyinsanityeffect - insanity_effect)
|
||||
|
||||
if(owner.has_trait(TRAIT_DEPRESSION))
|
||||
if(prob(0.05))
|
||||
add_event("depression", /datum/mood_event/depression)
|
||||
clear_event("jolly")
|
||||
add_event(null, "depression", /datum/mood_event/depression)
|
||||
clear_event(null, "jolly")
|
||||
if(owner.has_trait(TRAIT_JOLLY))
|
||||
if(prob(0.05))
|
||||
add_event("jolly", /datum/mood_event/jolly)
|
||||
clear_event("depression")
|
||||
add_event(null, "jolly", /datum/mood_event/jolly)
|
||||
clear_event(null, "depression")
|
||||
|
||||
var/area/A = get_area(owner)
|
||||
if(A)
|
||||
update_beauty(A)
|
||||
holdmyinsanityeffect = insanity_effect
|
||||
|
||||
/datum/component/mood/proc/DecreaseSanity(amount, limit = 0)
|
||||
if(sanity < limit) //This might make KevinZ stop fucking pinging me.
|
||||
HandleNutrition(owner)
|
||||
|
||||
/datum/component/mood/proc/DecreaseSanity(amount, minimum = SANITY_INSANE)
|
||||
if(sanity < minimum) //This might make KevinZ stop fucking pinging me.
|
||||
IncreaseSanity(0.5)
|
||||
else
|
||||
sanity = max(0, sanity - amount)
|
||||
sanity = max(minimum, sanity - amount)
|
||||
if(sanity < SANITY_UNSTABLE)
|
||||
if(sanity < SANITY_CRAZY)
|
||||
insanity_effect = (MAJOR_INSANITY_PEN)
|
||||
else
|
||||
insanity_effect = (MINOR_INSANITY_PEN)
|
||||
|
||||
/datum/component/mood/proc/IncreaseSanity(amount, limit = 99)
|
||||
if(sanity > limit)
|
||||
/datum/component/mood/proc/IncreaseSanity(amount, maximum = SANITY_NEUTRAL)
|
||||
if(sanity > maximum)
|
||||
DecreaseSanity(0.5) //Removes some sanity to go back to our current limit.
|
||||
else
|
||||
sanity = min(limit, sanity + amount)
|
||||
sanity = min(maximum, sanity + amount)
|
||||
if(sanity > SANITY_CRAZY)
|
||||
if(sanity > SANITY_UNSTABLE)
|
||||
insanity_effect = 0
|
||||
else
|
||||
insanity_effect = MINOR_INSANITY_PEN
|
||||
|
||||
/datum/component/mood/proc/add_event(category, type, param) //Category will override any events in the same category, should be unique unless the event is based on the same thing like hunger.
|
||||
/datum/component/mood/proc/add_event(datum/source, category, type, param) //Category will override any events in the same category, should be unique unless the event is based on the same thing like hunger.
|
||||
var/datum/mood_event/the_event
|
||||
if(mood_events[category])
|
||||
the_event = mood_events[category]
|
||||
if(the_event.type != type)
|
||||
clear_event(category)
|
||||
clear_event(null, category)
|
||||
else
|
||||
if(the_event.timeout)
|
||||
addtimer(CALLBACK(src, .proc/clear_event, null, category), the_event.timeout, TIMER_UNIQUE|TIMER_OVERRIDE)
|
||||
return 0 //Don't have to update the event.
|
||||
the_event = new type(src, param)
|
||||
|
||||
@@ -189,9 +201,9 @@
|
||||
update_mood()
|
||||
|
||||
if(the_event.timeout)
|
||||
addtimer(CALLBACK(src, .proc/clear_event, category), the_event.timeout)
|
||||
addtimer(CALLBACK(src, .proc/clear_event, null, category), the_event.timeout, TIMER_UNIQUE|TIMER_OVERRIDE)
|
||||
|
||||
/datum/component/mood/proc/clear_event(category)
|
||||
/datum/component/mood/proc/clear_event(datum/source, category)
|
||||
var/datum/mood_event/event = mood_events[category]
|
||||
if(!event)
|
||||
return 0
|
||||
@@ -200,22 +212,41 @@
|
||||
qdel(event)
|
||||
update_mood()
|
||||
|
||||
/datum/component/mood/proc/update_beauty(area/A)
|
||||
if(A.outdoors) //if we're outside, we don't care.
|
||||
clear_event("area_beauty")
|
||||
return FALSE
|
||||
switch(A.beauty)
|
||||
if(-INFINITY to BEAUTY_LEVEL_HORRID)
|
||||
add_event("area_beauty", /datum/mood_event/horridroom)
|
||||
if(BEAUTY_LEVEL_HORRID to BEAUTY_LEVEL_BAD)
|
||||
add_event("area_beauty", /datum/mood_event/badroom)
|
||||
if(BEAUTY_LEVEL_BAD to BEAUTY_LEVEL_MEH)
|
||||
add_event("area_beauty", /datum/mood_event/mehroom)
|
||||
if(BEAUTY_LEVEL_MEH to BEAUTY_LEVEL_DECENT)
|
||||
clear_event("area_beauty")
|
||||
if(BEAUTY_LEVEL_DECENT to BEAUTY_LEVEL_GOOD)
|
||||
add_event("area_beauty", /datum/mood_event/decentroom)
|
||||
if(BEAUTY_LEVEL_GOOD to BEAUTY_LEVEL_GREAT)
|
||||
add_event("area_beauty", /datum/mood_event/goodroom)
|
||||
if(BEAUTY_LEVEL_GREAT to INFINITY)
|
||||
add_event("area_beauty", /datum/mood_event/greatroom)
|
||||
/datum/component/mood/proc/modify_hud(datum/source)
|
||||
var/mob/living/owner = parent
|
||||
var/datum/hud/hud = owner.hud_used
|
||||
screen_obj = new
|
||||
hud.infodisplay += screen_obj
|
||||
RegisterSignal(hud, COMSIG_PARENT_QDELETED, .proc/unmodify_hud)
|
||||
RegisterSignal(screen_obj, COMSIG_CLICK, .proc/hud_click)
|
||||
|
||||
/datum/component/mood/proc/unmodify_hud(datum/source)
|
||||
if(!screen_obj)
|
||||
return
|
||||
var/mob/living/owner = parent
|
||||
var/datum/hud/hud = owner.hud_used
|
||||
if(hud && hud.infodisplay)
|
||||
hud.infodisplay -= screen_obj
|
||||
QDEL_NULL(screen_obj)
|
||||
|
||||
/datum/component/mood/proc/hud_click(datum/source, location, control, params, mob/user)
|
||||
print_mood(user)
|
||||
|
||||
|
||||
/datum/component/mood/proc/HandleNutrition(mob/living/L)
|
||||
switch(L.nutrition)
|
||||
if(NUTRITION_LEVEL_FULL to INFINITY)
|
||||
add_event(null, "nutrition", /datum/mood_event/fat)
|
||||
if(NUTRITION_LEVEL_WELL_FED to NUTRITION_LEVEL_FULL)
|
||||
add_event(null, "nutrition", /datum/mood_event/wellfed)
|
||||
if( NUTRITION_LEVEL_FED to NUTRITION_LEVEL_WELL_FED)
|
||||
add_event(null, "nutrition", /datum/mood_event/fed)
|
||||
if(NUTRITION_LEVEL_HUNGRY to NUTRITION_LEVEL_FED)
|
||||
clear_event(null, "nutrition")
|
||||
if(NUTRITION_LEVEL_STARVING to NUTRITION_LEVEL_HUNGRY)
|
||||
add_event(null, "nutrition", /datum/mood_event/hungry)
|
||||
if(0 to NUTRITION_LEVEL_STARVING)
|
||||
add_event(null, "nutrition", /datum/mood_event/starving)
|
||||
|
||||
#undef MINOR_INSANITY_PEN
|
||||
#undef MAJOR_INSANITY_PEN
|
||||
|
||||
@@ -90,12 +90,12 @@
|
||||
|
||||
/datum/component/nanites/InheritComponent(datum/component/nanites/new_nanites, i_am_original, list/arguments)
|
||||
if(new_nanites)
|
||||
adjust_nanites(new_nanites.nanite_volume)
|
||||
adjust_nanites(null, new_nanites.nanite_volume)
|
||||
else
|
||||
adjust_nanites(arguments[1]) //just add to the nanite volume
|
||||
adjust_nanites(null, arguments[1]) //just add to the nanite volume
|
||||
|
||||
/datum/component/nanites/process()
|
||||
adjust_nanites(regen_rate)
|
||||
adjust_nanites(null, regen_rate)
|
||||
for(var/X in programs)
|
||||
var/datum/nanite_program/NP = X
|
||||
NP.on_process()
|
||||
@@ -105,7 +105,7 @@
|
||||
next_sync = world.time + NANITE_SYNC_DELAY
|
||||
|
||||
//Syncs the nanite component to another, making it so programs are the same with the same programming (except activation status)
|
||||
/datum/component/nanites/proc/sync(datum/component/nanites/source, full_overwrite = TRUE, copy_activation = FALSE)
|
||||
/datum/component/nanites/proc/sync(datum/signal_source, datum/component/nanites/source, full_overwrite = TRUE, copy_activation = FALSE)
|
||||
var/list/programs_to_remove = programs.Copy()
|
||||
var/list/programs_to_add = source.programs.Copy()
|
||||
for(var/X in programs)
|
||||
@@ -122,7 +122,7 @@
|
||||
qdel(X)
|
||||
for(var/X in programs_to_add)
|
||||
var/datum/nanite_program/SNP = X
|
||||
add_program(SNP.copy())
|
||||
add_program(null, SNP.copy())
|
||||
|
||||
/datum/component/nanites/proc/cloud_sync()
|
||||
if(!cloud_id)
|
||||
@@ -131,9 +131,9 @@
|
||||
if(backup)
|
||||
var/datum/component/nanites/cloud_copy = backup.nanites
|
||||
if(cloud_copy)
|
||||
sync(cloud_copy)
|
||||
sync(null, cloud_copy)
|
||||
|
||||
/datum/component/nanites/proc/add_program(datum/nanite_program/new_program, datum/nanite_program/source_program)
|
||||
/datum/component/nanites/proc/add_program(datum/source, datum/nanite_program/new_program, datum/nanite_program/source_program)
|
||||
for(var/X in programs)
|
||||
var/datum/nanite_program/NP = X
|
||||
if(NP.unique && NP.type == new_program.type)
|
||||
@@ -149,10 +149,10 @@
|
||||
/datum/component/nanites/proc/consume_nanites(amount, force = FALSE)
|
||||
if(!force && safety_threshold && (nanite_volume - amount < safety_threshold))
|
||||
return FALSE
|
||||
adjust_nanites(-amount)
|
||||
adjust_nanites(null, -amount)
|
||||
return (nanite_volume > 0)
|
||||
|
||||
/datum/component/nanites/proc/adjust_nanites(amount)
|
||||
/datum/component/nanites/proc/adjust_nanites(datum/source, amount)
|
||||
nanite_volume = CLAMP(nanite_volume + amount, 0, max_nanites)
|
||||
if(nanite_volume <= 0) //oops we ran out
|
||||
qdel(src)
|
||||
@@ -168,39 +168,39 @@
|
||||
nanite_percent = CLAMP(CEILING(nanite_percent, 10), 10, 100)
|
||||
holder.icon_state = "nanites[nanite_percent]"
|
||||
|
||||
/datum/component/nanites/proc/on_emp(severity)
|
||||
/datum/component/nanites/proc/on_emp(datum/source, severity)
|
||||
nanite_volume *= (rand(0.60, 0.90)) //Lose 10-40% of nanites
|
||||
adjust_nanites(-(rand(5, 50))) //Lose 5-50 flat nanite volume
|
||||
adjust_nanites(null, -(rand(5, 50))) //Lose 5-50 flat nanite volume
|
||||
if(prob(40/severity))
|
||||
cloud_id = 0
|
||||
for(var/X in programs)
|
||||
var/datum/nanite_program/NP = X
|
||||
NP.on_emp(severity)
|
||||
|
||||
/datum/component/nanites/proc/on_shock(shock_damage)
|
||||
/datum/component/nanites/proc/on_shock(datum/source, shock_damage)
|
||||
nanite_volume *= (rand(0.45, 0.80)) //Lose 20-55% of nanites
|
||||
adjust_nanites(-(rand(5, 50))) //Lose 5-50 flat nanite volume
|
||||
adjust_nanites(null, -(rand(5, 50))) //Lose 5-50 flat nanite volume
|
||||
for(var/X in programs)
|
||||
var/datum/nanite_program/NP = X
|
||||
NP.on_shock(shock_damage)
|
||||
|
||||
/datum/component/nanites/proc/on_minor_shock()
|
||||
adjust_nanites(-(rand(5, 15))) //Lose 5-15 flat nanite volume
|
||||
/datum/component/nanites/proc/on_minor_shock(datum/source)
|
||||
adjust_nanites(null, -(rand(5, 15))) //Lose 5-15 flat nanite volume
|
||||
for(var/X in programs)
|
||||
var/datum/nanite_program/NP = X
|
||||
NP.on_minor_shock()
|
||||
|
||||
/datum/component/nanites/proc/on_death(gibbed)
|
||||
/datum/component/nanites/proc/on_death(datum/source, gibbed)
|
||||
for(var/X in programs)
|
||||
var/datum/nanite_program/NP = X
|
||||
NP.on_death(gibbed)
|
||||
|
||||
/datum/component/nanites/proc/on_hear(message, atom/movable/speaker, message_language, raw_message, radio_freq, list/spans, message_mode)
|
||||
/datum/component/nanites/proc/on_hear(datum/source, message, atom/movable/speaker, message_language, raw_message, radio_freq, list/spans, message_mode)
|
||||
for(var/X in programs)
|
||||
var/datum/nanite_program/NP = X
|
||||
NP.on_hear(message, speaker, message_language, raw_message, radio_freq, spans, message_mode)
|
||||
|
||||
/datum/component/nanites/proc/receive_signal(code, source = "an unidentified source")
|
||||
/datum/component/nanites/proc/receive_signal(datum/source, code, source = "an unidentified source")
|
||||
for(var/X in programs)
|
||||
var/datum/nanite_program/NP = X
|
||||
NP.receive_signal(code, source)
|
||||
@@ -209,7 +209,7 @@
|
||||
if(!(MOB_ORGANIC in host_mob.mob_biotypes) && !(MOB_UNDEAD in host_mob.mob_biotypes))
|
||||
qdel(src) //bodytype no longer sustains nanites
|
||||
|
||||
/datum/component/nanites/proc/check_access(obj/O)
|
||||
/datum/component/nanites/proc/check_access(datum/source, obj/O)
|
||||
for(var/datum/nanite_program/triggered/access/access_program in programs)
|
||||
if(access_program.activated)
|
||||
return O.check_access_list(access_program.access)
|
||||
@@ -217,19 +217,19 @@
|
||||
return FALSE
|
||||
return FALSE
|
||||
|
||||
/datum/component/nanites/proc/set_volume(amount)
|
||||
/datum/component/nanites/proc/set_volume(datum/source, amount)
|
||||
nanite_volume = CLAMP(amount, 0, max_nanites)
|
||||
|
||||
/datum/component/nanites/proc/set_max_volume(amount)
|
||||
/datum/component/nanites/proc/set_max_volume(datum/source, amount)
|
||||
max_nanites = max(1, max_nanites)
|
||||
|
||||
/datum/component/nanites/proc/set_cloud(amount)
|
||||
/datum/component/nanites/proc/set_cloud(datum/source, amount)
|
||||
cloud_id = CLAMP(amount, 0, 100)
|
||||
|
||||
/datum/component/nanites/proc/set_safety(amount)
|
||||
/datum/component/nanites/proc/set_safety(datum/source, amount)
|
||||
safety_threshold = CLAMP(amount, 0, max_nanites)
|
||||
|
||||
/datum/component/nanites/proc/set_regen(amount)
|
||||
/datum/component/nanites/proc/set_regen(datum/source, amount)
|
||||
regen_rate = amount
|
||||
|
||||
/datum/component/nanites/proc/confirm_nanites()
|
||||
@@ -243,10 +243,10 @@
|
||||
nanite_data["safety_threshold"] = safety_threshold
|
||||
nanite_data["stealth"] = stealth
|
||||
|
||||
/datum/component/nanites/proc/get_programs(list/nanite_programs)
|
||||
/datum/component/nanites/proc/get_programs(datum/source, list/nanite_programs)
|
||||
nanite_programs |= programs
|
||||
|
||||
/datum/component/nanites/proc/nanite_scan(mob/user, full_scan)
|
||||
/datum/component/nanites/proc/nanite_scan(datum/source, mob/user, full_scan)
|
||||
if(!full_scan)
|
||||
if(!stealth)
|
||||
to_chat(user, "<span class='notice'><b>Nanites Detected</b></span>")
|
||||
@@ -268,7 +268,7 @@
|
||||
to_chat(user, "<span class='info'><b>[NP.name]</b> | [NP.activated ? "Active" : "Inactive"]</span>")
|
||||
return TRUE
|
||||
|
||||
/datum/component/nanites/proc/nanite_ui_data(list/data, scan_level)
|
||||
/datum/component/nanites/proc/nanite_ui_data(datum/source, list/data, scan_level)
|
||||
data["has_nanites"] = TRUE
|
||||
data["nanite_volume"] = nanite_volume
|
||||
data["regen_rate"] = regen_rate
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
var/atom/A = parent
|
||||
A.remove_atom_colour(FIXED_COLOUR_PRIORITY, current_paint)
|
||||
|
||||
/datum/component/spraycan_paintable/proc/Repaint(obj/item/toy/crayon/spraycan/spraycan, mob/living/user)
|
||||
/datum/component/spraycan_paintable/proc/Repaint(datum/source, obj/item/toy/crayon/spraycan/spraycan, mob/living/user)
|
||||
if(!istype(spraycan) || user.a_intent == INTENT_HARM)
|
||||
return
|
||||
. = COMPONENT_NO_AFTERATTACK
|
||||
|
||||
@@ -1,9 +1,24 @@
|
||||
/datum/component/rad_insulation // Yes, this really is just a component to add some vars
|
||||
/datum/component/rad_insulation
|
||||
var/amount // Multiplier for radiation strength passing through
|
||||
var/protects // Does this protect things in its contents from being affected?
|
||||
var/contamination_proof // Can this object be contaminated?
|
||||
|
||||
/datum/component/rad_insulation/Initialize(_amount=RAD_MEDIUM_INSULATION, _protects=TRUE, _contamination_proof=TRUE)
|
||||
/datum/component/rad_insulation/Initialize(_amount=RAD_MEDIUM_INSULATION, protects=TRUE, contamination_proof=TRUE)
|
||||
if(!isatom(parent))
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
|
||||
if(protects) // Does this protect things in its contents from being affected?
|
||||
RegisterSignal(parent, COMSIG_ATOM_RAD_PROBE, .proc/rad_probe_react)
|
||||
if(contamination_proof) // Can this object be contaminated?
|
||||
RegisterSignal(parent, COMSIG_ATOM_RAD_CONTAMINATING, .proc/rad_contaminating)
|
||||
if(_amount != 1) // If it's 1 it wont have any impact on radiation passing through anyway
|
||||
RegisterSignal(parent, COMSIG_ATOM_RAD_WAVE_PASSING, .proc/rad_pass)
|
||||
|
||||
amount = _amount
|
||||
protects = _protects
|
||||
contamination_proof = _contamination_proof
|
||||
|
||||
/datum/component/rad_insulation/proc/rad_probe_react(datum/source)
|
||||
return COMPONENT_BLOCK_RADIATION
|
||||
|
||||
/datum/component/rad_insulation/proc/rad_contaminating(datum/source, strength)
|
||||
return COMPONENT_BLOCK_CONTAMINATION
|
||||
|
||||
/datum/component/rad_insulation/proc/rad_pass(datum/source, datum/radiation_wave/wave, width)
|
||||
wave.intensity = wave.intensity*(1-((1-amount)/width)) // The further out the rad wave goes the less it's affected by insulation (larger width)
|
||||
@@ -58,7 +58,7 @@
|
||||
else
|
||||
strength = max(strength, arguments[1])
|
||||
|
||||
/datum/component/radioactive/proc/rad_examine(mob/user, atom/thing)
|
||||
/datum/component/radioactive/proc/rad_examine(datum/source, mob/user, atom/thing)
|
||||
var/atom/master = parent
|
||||
var/list/out = list()
|
||||
if(get_dist(master, user) <= 1)
|
||||
@@ -74,7 +74,7 @@
|
||||
out += "."
|
||||
to_chat(user, out.Join())
|
||||
|
||||
/datum/component/radioactive/proc/rad_attack(atom/movable/target, mob/living/user)
|
||||
/datum/component/radioactive/proc/rad_attack(datum/source, atom/movable/target, mob/living/user)
|
||||
radiation_pulse(parent, strength/20)
|
||||
target.rad_act(strength/2)
|
||||
strength -= strength / hl3_release_date
|
||||
|
||||
111
code/datums/components/remote_materials.dm
Normal file
111
code/datums/components/remote_materials.dm
Normal file
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
This component allows machines to connect remotely to a material container
|
||||
(namely an /obj/machinery/ore_silo) elsewhere. It offers optional graceful
|
||||
fallback to a local material storage in case remote storage is unavailable, and
|
||||
handles linking back and forth.
|
||||
*/
|
||||
|
||||
/datum/component/remote_materials
|
||||
// Three possible states:
|
||||
// 1. silo exists, materials is parented to silo
|
||||
// 2. silo is null, materials is parented to parent
|
||||
// 3. silo is null, materials is null
|
||||
var/obj/machinery/ore_silo/silo
|
||||
var/datum/component/material_container/mat_container
|
||||
var/category
|
||||
var/allow_standalone
|
||||
var/local_size = INFINITY
|
||||
|
||||
/datum/component/remote_materials/Initialize(category, mapload, allow_standalone = TRUE, force_connect = FALSE)
|
||||
if (!isatom(parent))
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
|
||||
src.category = category
|
||||
src.allow_standalone = allow_standalone
|
||||
|
||||
RegisterSignal(parent, COMSIG_PARENT_ATTACKBY, .proc/OnAttackBy)
|
||||
|
||||
var/turf/T = get_turf(parent)
|
||||
if (force_connect || (mapload && is_station_level(T.z)))
|
||||
addtimer(CALLBACK(src, .proc/LateInitialize))
|
||||
else if (allow_standalone)
|
||||
_MakeLocal()
|
||||
|
||||
/datum/component/remote_materials/proc/LateInitialize()
|
||||
silo = GLOB.ore_silo_default
|
||||
if (silo)
|
||||
silo.connected += src
|
||||
mat_container = silo.GetComponent(/datum/component/material_container)
|
||||
else
|
||||
_MakeLocal()
|
||||
|
||||
/datum/component/remote_materials/Destroy()
|
||||
if (silo)
|
||||
silo.connected -= src
|
||||
silo.updateUsrDialog()
|
||||
silo = null
|
||||
mat_container = null
|
||||
else if (mat_container)
|
||||
// specify explicitly in case the other component is deleted first
|
||||
var/atom/P = parent
|
||||
mat_container.retrieve_all(P.drop_location())
|
||||
return ..()
|
||||
|
||||
/datum/component/remote_materials/proc/_MakeLocal()
|
||||
silo = null
|
||||
mat_container = parent.AddComponent(/datum/component/material_container,
|
||||
list(MAT_METAL, MAT_GLASS, MAT_SILVER, MAT_GOLD, MAT_DIAMOND, MAT_PLASMA, MAT_URANIUM, MAT_BANANIUM, MAT_TITANIUM, MAT_BLUESPACE, MAT_PLASTIC),
|
||||
local_size,
|
||||
FALSE,
|
||||
/obj/item/stack)
|
||||
|
||||
/datum/component/remote_materials/proc/set_local_size(size)
|
||||
local_size = size
|
||||
if (!silo && mat_container)
|
||||
mat_container.max_amount = size
|
||||
|
||||
// called if disconnected by ore silo UI or destruction
|
||||
/datum/component/remote_materials/proc/disconnect_from(obj/machinery/ore_silo/old_silo)
|
||||
if (!old_silo || silo != old_silo)
|
||||
return
|
||||
silo = null
|
||||
mat_container = null
|
||||
if (allow_standalone)
|
||||
_MakeLocal()
|
||||
|
||||
/datum/component/remote_materials/proc/OnAttackBy(datum/source, obj/item/I, mob/user)
|
||||
if (istype(I, /obj/item/multitool))
|
||||
var/obj/item/multitool/M = I
|
||||
if (!QDELETED(M.buffer) && istype(M.buffer, /obj/machinery/ore_silo))
|
||||
if (silo == M.buffer)
|
||||
to_chat(user, "<span class='notice'>[parent] is already connected to [silo].</span>")
|
||||
return COMPONENT_NO_AFTERATTACK
|
||||
if (silo)
|
||||
silo.connected -= src
|
||||
silo.updateUsrDialog()
|
||||
else if (mat_container)
|
||||
mat_container.retrieve_all()
|
||||
qdel(mat_container)
|
||||
silo = M.buffer
|
||||
silo.connected += src
|
||||
silo.updateUsrDialog()
|
||||
mat_container = silo.GetComponent(/datum/component/material_container)
|
||||
to_chat(user, "<span class='notice'>You connect [parent] to [silo] from the multitool's buffer.</span>")
|
||||
return COMPONENT_NO_AFTERATTACK
|
||||
|
||||
else if (silo && istype(I, /obj/item/stack))
|
||||
if (silo.remote_attackby(parent, user, I))
|
||||
return COMPONENT_NO_AFTERATTACK
|
||||
|
||||
/datum/component/remote_materials/proc/on_hold()
|
||||
return silo && silo.holds["[get_area(parent)]/[category]"]
|
||||
|
||||
/datum/component/remote_materials/proc/silo_log(obj/machinery/M, action, amount, noun, list/mats)
|
||||
if (silo)
|
||||
silo.silo_log(M || parent, action, amount, noun, mats)
|
||||
|
||||
/datum/component/remote_materials/proc/format_amount()
|
||||
if (mat_container)
|
||||
return "[mat_container.total_amount] / [mat_container.max_amount == INFINITY ? "Unlimited" : mat_container.max_amount] ([silo ? "remote" : "local"])"
|
||||
else
|
||||
return "0 / 0"
|
||||
@@ -26,11 +26,11 @@
|
||||
RegisterSignal(parent, COMSIG_MOVABLE_UNBUCKLE, .proc/vehicle_mob_unbuckle)
|
||||
RegisterSignal(parent, COMSIG_MOVABLE_MOVED, .proc/vehicle_moved)
|
||||
|
||||
/datum/component/riding/proc/vehicle_mob_unbuckle(mob/living/M, force = FALSE)
|
||||
/datum/component/riding/proc/vehicle_mob_unbuckle(datum/source, mob/living/M, force = FALSE)
|
||||
restore_position(M)
|
||||
unequip_buckle_inhands(M)
|
||||
|
||||
/datum/component/riding/proc/vehicle_mob_buckle(mob/living/M, force = FALSE)
|
||||
/datum/component/riding/proc/vehicle_mob_buckle(datum/source, mob/living/M, force = FALSE)
|
||||
handle_vehicle_offsets()
|
||||
|
||||
/datum/component/riding/proc/handle_vehicle_layer()
|
||||
@@ -46,7 +46,7 @@
|
||||
/datum/component/riding/proc/set_vehicle_dir_layer(dir, layer)
|
||||
directional_vehicle_layers["[dir]"] = layer
|
||||
|
||||
/datum/component/riding/proc/vehicle_moved()
|
||||
/datum/component/riding/proc/vehicle_moved(datum/source)
|
||||
var/atom/movable/AM = parent
|
||||
for(var/i in AM.buckled_mobs)
|
||||
ride_check(i)
|
||||
|
||||
@@ -77,16 +77,16 @@
|
||||
remove_verbs()
|
||||
. = ..()
|
||||
|
||||
/datum/component/simple_rotation/proc/ExamineMessage(mob/user)
|
||||
/datum/component/simple_rotation/proc/ExamineMessage(datum/source, mob/user)
|
||||
if(rotation_flags & ROTATION_ALTCLICK)
|
||||
to_chat(user, "<span class='notice'>Alt-click to rotate it clockwise.</span>")
|
||||
|
||||
/datum/component/simple_rotation/proc/HandRot(mob/user, rotation = default_rotation_direction)
|
||||
/datum/component/simple_rotation/proc/HandRot(datum/source, mob/user, rotation = default_rotation_direction)
|
||||
if(!can_be_rotated.Invoke(user, rotation) || !can_user_rotate.Invoke(user, rotation))
|
||||
return
|
||||
BaseRot(user, rotation)
|
||||
|
||||
/datum/component/simple_rotation/proc/WrenchRot(obj/item/I, mob/living/user)
|
||||
/datum/component/simple_rotation/proc/WrenchRot(datum/source, obj/item/I, mob/living/user)
|
||||
if(!can_be_rotated.Invoke(user,default_rotation_direction) || !can_user_rotate.Invoke(user,default_rotation_direction))
|
||||
return
|
||||
if(istype(I,/obj/item/wrench))
|
||||
|
||||
@@ -3,15 +3,31 @@
|
||||
|
||||
/datum/component/redirect
|
||||
dupe_mode = COMPONENT_DUPE_ALLOWED
|
||||
var/list/signals
|
||||
var/datum/callback/turfchangeCB
|
||||
|
||||
/datum/component/redirect/Initialize(list/signals, datum/callback/_callback, flags=NONE)
|
||||
/datum/component/redirect/Initialize(list/_signals, flags=NONE)
|
||||
//It's not our job to verify the right signals are registered here, just do it.
|
||||
if(!LAZYLEN(signals) || !istype(_callback))
|
||||
warning("signals are [list2params(signals)], callback is [_callback]]")
|
||||
if(!LAZYLEN(_signals))
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
if(flags & REDIRECT_TRANSFER_WITH_TURF && isturf(parent))
|
||||
RegisterSignal(parent, COMSIG_TURF_CHANGE, .proc/turf_change)
|
||||
RegisterSignal(parent, signals, _callback)
|
||||
// If they also want to listen to the turf change then we need to set it up so both callbacks run
|
||||
if(_signals[COMSIG_TURF_CHANGE])
|
||||
turfchangeCB = _signals[COMSIG_TURF_CHANGE]
|
||||
if(!istype(turfchangeCB))
|
||||
. = COMPONENT_INCOMPATIBLE
|
||||
CRASH("Redirect components must be given instanced callbacks, not proc paths.")
|
||||
_signals[COMSIG_TURF_CHANGE] = CALLBACK(src, .proc/turf_change)
|
||||
|
||||
/datum/component/redirect/proc/turf_change(path, new_baseturfs, flags, list/transfers)
|
||||
signals = _signals
|
||||
|
||||
/datum/component/redirect/RegisterWithParent()
|
||||
for(var/signal in signals)
|
||||
RegisterSignal(parent, signal, signals[signal])
|
||||
|
||||
/datum/component/redirect/UnregisterFromParent()
|
||||
UnregisterSignal(parent, signals)
|
||||
|
||||
/datum/component/redirect/proc/turf_change(datum/source, path, new_baseturfs, flags, list/transfers)
|
||||
transfers += src
|
||||
return turfchangeCB?.InvokeAsync(arglist(args))
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
callback = _callback
|
||||
RegisterSignal(parent, list(COMSIG_MOVABLE_CROSSED, COMSIG_ATOM_ENTERED), .proc/Slip)
|
||||
|
||||
/datum/component/slippery/proc/Slip(atom/movable/AM)
|
||||
/datum/component/slippery/proc/Slip(datum/source, atom/movable/AM)
|
||||
var/mob/victim = AM
|
||||
if(istype(victim) && !victim.is_flying() && victim.slip(intensity, parent, lube_flags) && callback)
|
||||
callback.Invoke(victim)
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
/datum/component/spooky/Initialize()
|
||||
RegisterSignal(parent, COMSIG_ITEM_ATTACK, .proc/spectral_attack)
|
||||
|
||||
/datum/component/spooky/proc/spectral_attack(mob/living/carbon/C, mob/user)
|
||||
/datum/component/spooky/proc/spectral_attack(datum/source, mob/living/carbon/C, mob/user)
|
||||
if(ishuman(user)) //this weapon wasn't meant for mortals.
|
||||
var/mob/living/carbon/human/U = user
|
||||
if(!istype(U.dna.species, /datum/species/skeleton))
|
||||
|
||||
87
code/datums/components/squeak.dm
Normal file
87
code/datums/components/squeak.dm
Normal file
@@ -0,0 +1,87 @@
|
||||
/datum/component/squeak
|
||||
var/static/list/default_squeak_sounds = list('sound/items/toysqueak1.ogg'=1, 'sound/items/toysqueak2.ogg'=1, 'sound/items/toysqueak3.ogg'=1)
|
||||
var/list/override_squeak_sounds
|
||||
var/squeak_chance = 100
|
||||
var/volume = 30
|
||||
|
||||
// This is so shoes don't squeak every step
|
||||
var/steps = 0
|
||||
var/step_delay = 1
|
||||
|
||||
// This is to stop squeak spam from inhand usage
|
||||
var/last_use = 0
|
||||
var/use_delay = 20
|
||||
|
||||
/datum/component/squeak/Initialize(custom_sounds, volume_override, chance_override, step_delay_override, use_delay_override)
|
||||
if(!isatom(parent))
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
RegisterSignal(parent, list(COMSIG_ATOM_ENTERED, COMSIG_ATOM_BLOB_ACT, COMSIG_ATOM_HULK_ATTACK, COMSIG_PARENT_ATTACKBY), .proc/play_squeak)
|
||||
if(ismovableatom(parent))
|
||||
RegisterSignal(parent, list(COMSIG_MOVABLE_BUMP, COMSIG_MOVABLE_IMPACT), .proc/play_squeak)
|
||||
RegisterSignal(parent, COMSIG_MOVABLE_CROSSED, .proc/play_squeak_crossed)
|
||||
RegisterSignal(parent, COMSIG_MOVABLE_DISPOSING, .proc/disposing_react)
|
||||
if(isitem(parent))
|
||||
RegisterSignal(parent, list(COMSIG_ITEM_ATTACK, COMSIG_ITEM_ATTACK_OBJ, COMSIG_ITEM_HIT_REACT), .proc/play_squeak)
|
||||
RegisterSignal(parent, COMSIG_ITEM_ATTACK_SELF, .proc/use_squeak)
|
||||
RegisterSignal(parent, COMSIG_ITEM_EQUIPPED, .proc/on_equip)
|
||||
RegisterSignal(parent, COMSIG_ITEM_DROPPED, .proc/on_drop)
|
||||
if(istype(parent, /obj/item/clothing/shoes))
|
||||
RegisterSignal(parent, COMSIG_SHOES_STEP_ACTION, .proc/step_squeak)
|
||||
|
||||
override_squeak_sounds = custom_sounds
|
||||
if(chance_override)
|
||||
squeak_chance = chance_override
|
||||
if(volume_override)
|
||||
volume = volume_override
|
||||
if(isnum(step_delay_override))
|
||||
step_delay = step_delay_override
|
||||
if(isnum(use_delay_override))
|
||||
use_delay = use_delay_override
|
||||
|
||||
/datum/component/squeak/proc/play_squeak()
|
||||
if(prob(squeak_chance))
|
||||
if(!override_squeak_sounds)
|
||||
playsound(parent, pickweight(default_squeak_sounds), volume, 1, -1)
|
||||
else
|
||||
playsound(parent, pickweight(override_squeak_sounds), volume, 1, -1)
|
||||
|
||||
/datum/component/squeak/proc/step_squeak()
|
||||
if(steps > step_delay)
|
||||
play_squeak()
|
||||
steps = 0
|
||||
else
|
||||
steps++
|
||||
|
||||
/datum/component/squeak/proc/play_squeak_crossed(atom/movable/AM)
|
||||
if(isitem(AM))
|
||||
var/obj/item/I = AM
|
||||
if(I.item_flags & ABSTRACT)
|
||||
return
|
||||
else if(istype(AM, /obj/item/projectile))
|
||||
var/obj/item/projectile/P = AM
|
||||
if(P.original != parent)
|
||||
return
|
||||
var/atom/current_parent = parent
|
||||
if(isturf(current_parent.loc))
|
||||
play_squeak()
|
||||
|
||||
/datum/component/squeak/proc/use_squeak()
|
||||
if(last_use + use_delay < world.time)
|
||||
last_use = world.time
|
||||
play_squeak()
|
||||
|
||||
/datum/component/squeak/proc/on_equip(datum/source, mob/equipper, slot)
|
||||
RegisterSignal(equipper, COMSIG_MOVABLE_DISPOSING, .proc/disposing_react, TRUE)
|
||||
|
||||
/datum/component/squeak/proc/on_drop(datum/source, mob/user)
|
||||
UnregisterSignal(user, COMSIG_MOVABLE_DISPOSING)
|
||||
|
||||
// Disposal pipes related shit
|
||||
/datum/component/squeak/proc/disposing_react(datum/source, obj/structure/disposalholder/holder, obj/machinery/disposal/source)
|
||||
//We don't need to worry about unregistering this signal as it will happen for us automaticaly when the holder is qdeleted
|
||||
RegisterSignal(holder, COMSIG_ATOM_DIR_CHANGE, .proc/holder_dir_change)
|
||||
|
||||
/datum/component/squeak/proc/holder_dir_change(datum/source, old_dir, new_dir)
|
||||
//If the dir changes it means we're going through a bend in the pipes, let's pretend we bumped the wall
|
||||
if(old_dir != new_dir)
|
||||
play_squeak()
|
||||
@@ -42,7 +42,7 @@
|
||||
var/turf/currentturf = get_turf(src)
|
||||
to_chat(get(parent, /mob), "<span class='danger'>You can't help but feel that you just lost something back there...</span>")
|
||||
var/turf/targetturf = relocate()
|
||||
log_game("[parent] has been moved out of bounds in [AREACOORD(currentturf)]. Moving it to [AREACOORD(targetturf)].")
|
||||
log_game("[parent] has been moved out of bounds in [loc_name(currentturf)]. Moving it to [loc_name(targetturf)].")
|
||||
if(inform_admins)
|
||||
message_admins("[parent] has been moved out of bounds in [ADMIN_VERBOSEJMP(currentturf)]. Moving it to [ADMIN_VERBOSEJMP(targetturf)].")
|
||||
|
||||
@@ -65,17 +65,17 @@
|
||||
|
||||
return FALSE
|
||||
|
||||
/datum/component/stationloving/proc/check_deletion(force) // TRUE = interrupt deletion, FALSE = proceed with deletion
|
||||
/datum/component/stationloving/proc/check_deletion(datum/source, force) // TRUE = interrupt deletion, FALSE = proceed with deletion
|
||||
|
||||
var/turf/T = get_turf(parent)
|
||||
|
||||
if(inform_admins && force)
|
||||
message_admins("[parent] has been !!force deleted!! in [ADMIN_VERBOSEJMP(T)].")
|
||||
log_game("[parent] has been !!force deleted!! in [AREACOORD(T)].")
|
||||
log_game("[parent] has been !!force deleted!! in [loc_name(T)].")
|
||||
|
||||
if(!force && !allow_death)
|
||||
var/turf/targetturf = relocate()
|
||||
log_game("[parent] has been destroyed in [AREACOORD(T)]. Moving it to [AREACOORD(targetturf)].")
|
||||
log_game("[parent] has been destroyed in [loc_name(T)]. Moving it to [loc_name(targetturf)].")
|
||||
if(inform_admins)
|
||||
message_admins("[parent] has been destroyed in [ADMIN_VERBOSEJMP(T)]. Moving it to [ADMIN_VERBOSEJMP(targetturf)].")
|
||||
return TRUE
|
||||
|
||||
@@ -72,7 +72,7 @@
|
||||
var/datum/component/storage/slave = i
|
||||
slave.refresh_mob_views()
|
||||
|
||||
/datum/component/storage/concrete/emp_act(severity)
|
||||
/datum/component/storage/concrete/emp_act(datum/source, severity)
|
||||
if(emp_shielded)
|
||||
return
|
||||
var/atom/real_location = real_location()
|
||||
@@ -90,13 +90,13 @@
|
||||
slaves -= S
|
||||
return FALSE
|
||||
|
||||
/datum/component/storage/concrete/proc/on_contents_del(atom/A)
|
||||
/datum/component/storage/concrete/proc/on_contents_del(datum/source, atom/A)
|
||||
var/atom/real_location = parent
|
||||
if(A in real_location)
|
||||
usr = null
|
||||
remove_from_storage(A, null)
|
||||
|
||||
/datum/component/storage/concrete/proc/on_deconstruct(disassembled)
|
||||
/datum/component/storage/concrete/proc/on_deconstruct(datum/source, disassembled)
|
||||
if(drop_all_on_deconstruct)
|
||||
do_quick_empty()
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/datum/component/storage/concrete/bluespace/bag_of_holding/handle_item_insertion(obj/item/W, prevent_warning = FALSE, mob/living/user)
|
||||
var/atom/A = parent
|
||||
if(A == W)
|
||||
if(A == W) //don't put yourself into yourself.
|
||||
return
|
||||
var/list/obj/item/storage/backpack/holding/matching = typecache_filter_list(W.GetAllContents(), typecacheof(/obj/item/storage/backpack/holding))
|
||||
matching -= A
|
||||
@@ -30,7 +30,7 @@
|
||||
for (var/obj/structure/ladder/unbreakable/binary/ladder in GLOB.ladders)
|
||||
ladder.ActivateAlmonds()
|
||||
message_admins("[ADMIN_LOOKUPFLW(user)] detonated a bag of holding at [ADMIN_VERBOSEJMP(loccheck)].")
|
||||
log_game("[key_name(user)] detonated a bag of holding at [AREACOORD(loccheck)].")
|
||||
log_game("[key_name(user)] detonated a bag of holding at [loc_name(loccheck)].")
|
||||
qdel(A)
|
||||
return
|
||||
. = ..()
|
||||
|
||||
@@ -89,12 +89,13 @@
|
||||
RegisterSignal(parent, COMSIG_ATOM_ATTACK_GHOST, .proc/show_to_ghost)
|
||||
RegisterSignal(parent, COMSIG_ATOM_ENTERED, .proc/refresh_mob_views)
|
||||
RegisterSignal(parent, COMSIG_ATOM_EXITED, .proc/_remove_and_refresh)
|
||||
RegisterSignal(parent, COMSIG_ATOM_CANREACH, .proc/canreach_react)
|
||||
|
||||
RegisterSignal(parent, COMSIG_ITEM_PRE_ATTACK, .proc/preattack_intercept)
|
||||
RegisterSignal(parent, COMSIG_ITEM_ATTACK_SELF, .proc/attack_self)
|
||||
RegisterSignal(parent, COMSIG_ITEM_PICKUP, .proc/signal_on_pickup)
|
||||
|
||||
RegisterSignal(parent, COMSIG_MOVABLE_PRE_THROW, .proc/close_all)
|
||||
RegisterSignal(parent, COMSIG_MOVABLE_POST_THROW, .proc/close_all)
|
||||
|
||||
RegisterSignal(parent, COMSIG_CLICK_ALT, .proc/on_alt_click)
|
||||
RegisterSignal(parent, COMSIG_MOUSEDROP_ONTO, .proc/mousedrop_onto)
|
||||
@@ -118,6 +119,7 @@
|
||||
return
|
||||
var/obj/item/I = parent
|
||||
modeswitch_action = new(I)
|
||||
RegisterSignal(modeswitch_action, COMSIG_ACTION_TRIGGER, .proc/action_trigger)
|
||||
if(I.obj_flags & IN_INVENTORY)
|
||||
var/mob/M = I.loc
|
||||
if(!istype(M))
|
||||
@@ -143,14 +145,24 @@
|
||||
var/datum/component/storage/concrete/master = master()
|
||||
return master? master.real_location() : null
|
||||
|
||||
/datum/component/storage/proc/attack_self(mob/M)
|
||||
/datum/component/storage/proc/canreach_react(datum/source, list/next)
|
||||
var/datum/component/storage/concrete/master = master()
|
||||
if(!master)
|
||||
return
|
||||
. = COMPONENT_BLOCK_REACH
|
||||
next += master.parent
|
||||
for(var/i in master.slaves)
|
||||
var/datum/component/storage/slave = i
|
||||
next += slave.parent
|
||||
|
||||
/datum/component/storage/proc/attack_self(datum/source, mob/M)
|
||||
if(locked)
|
||||
to_chat(M, "<span class='warning'>[parent] seems to be locked!</span>")
|
||||
return FALSE
|
||||
if((M.get_active_held_item() == parent) && allow_quick_empty)
|
||||
quick_empty(M)
|
||||
|
||||
/datum/component/storage/proc/preattack_intercept(obj/O, mob/M, params)
|
||||
/datum/component/storage/proc/preattack_intercept(datum/source, obj/O, mob/M, params)
|
||||
if(!isitem(O) || !click_gather || SEND_SIGNAL(O, COMSIG_CONTAINS_STORAGE))
|
||||
return FALSE
|
||||
. = COMPONENT_NO_ATTACK
|
||||
@@ -263,7 +275,7 @@
|
||||
remove_from_storage(I, _target)
|
||||
return TRUE
|
||||
|
||||
/datum/component/storage/proc/set_locked(new_state)
|
||||
/datum/component/storage/proc/set_locked(datum/source, new_state)
|
||||
locked = new_state
|
||||
if(locked)
|
||||
close_all()
|
||||
@@ -371,11 +383,11 @@
|
||||
close(M)
|
||||
. = TRUE //returns TRUE if any mobs actually got a close(M) call
|
||||
|
||||
/datum/component/storage/proc/emp_act(severity)
|
||||
/datum/component/storage/proc/emp_act(datum/source, severity)
|
||||
if(emp_shielded)
|
||||
return
|
||||
var/datum/component/storage/concrete/master = master()
|
||||
master.emp_act(severity)
|
||||
master.emp_act(source, severity)
|
||||
|
||||
//This proc draws out the inventory and places the items on it. tx and ty are the upper left tile and mx, my are the bottm right.
|
||||
//The numbers are calculated from the bottom-left The bottom-left slot being 1,1.
|
||||
@@ -405,7 +417,7 @@
|
||||
return FALSE
|
||||
return master._removal_reset(thing)
|
||||
|
||||
/datum/component/storage/proc/_remove_and_refresh(atom/movable/thing)
|
||||
/datum/component/storage/proc/_remove_and_refresh(datum/source, atom/movable/thing)
|
||||
_removal_reset(thing)
|
||||
refresh_mob_views()
|
||||
|
||||
@@ -447,7 +459,7 @@
|
||||
return FALSE
|
||||
|
||||
//This proc is called when you want to place an item into the storage item.
|
||||
/datum/component/storage/proc/attackby(obj/item/I, mob/M, params)
|
||||
/datum/component/storage/proc/attackby(datum/source, obj/item/I, mob/M, params)
|
||||
if(istype(I, /obj/item/hand_labeler))
|
||||
var/obj/item/hand_labeler/labeler = I
|
||||
if(labeler.mode)
|
||||
@@ -476,13 +488,13 @@
|
||||
return real_location.contents.Copy()
|
||||
|
||||
//Abuses the fact that lists are just references, or something like that.
|
||||
/datum/component/storage/proc/signal_return_inv(list/interface, recursive = TRUE)
|
||||
/datum/component/storage/proc/signal_return_inv(datum/source, list/interface, recursive = TRUE)
|
||||
if(!islist(interface))
|
||||
return FALSE
|
||||
interface |= return_inv(recursive)
|
||||
return TRUE
|
||||
|
||||
/datum/component/storage/proc/mousedrop_onto(atom/over_object, mob/M)
|
||||
/datum/component/storage/proc/mousedrop_onto(datum/source, atom/over_object, mob/M)
|
||||
set waitfor = FALSE
|
||||
. = COMPONENT_NO_MOUSEDROP
|
||||
var/atom/A = parent
|
||||
@@ -519,7 +531,7 @@
|
||||
if(force || M.CanReach(parent, view_only = TRUE))
|
||||
show_to(M)
|
||||
|
||||
/datum/component/storage/proc/mousedrop_receive(atom/movable/O, mob/M)
|
||||
/datum/component/storage/proc/mousedrop_receive(datum/source, atom/movable/O, mob/M)
|
||||
if(isitem(O))
|
||||
var/obj/item/I = O
|
||||
if(iscarbon(M) || isdrone(M))
|
||||
@@ -540,7 +552,7 @@
|
||||
if(real_location == I.loc)
|
||||
return FALSE //Means the item is already in the storage item
|
||||
if(locked)
|
||||
if(M)
|
||||
if(M && !stop_messages)
|
||||
host.add_fingerprint(M)
|
||||
to_chat(M, "<span class='warning'>[host] seems to be locked!</span>")
|
||||
return FALSE
|
||||
@@ -618,18 +630,18 @@
|
||||
var/obj/O = parent
|
||||
O.update_icon()
|
||||
|
||||
/datum/component/storage/proc/signal_insertion_attempt(obj/item/I, mob/M, silent = FALSE, force = FALSE)
|
||||
/datum/component/storage/proc/signal_insertion_attempt(datum/source, obj/item/I, mob/M, silent = FALSE, force = FALSE)
|
||||
if((!force && !can_be_inserted(I, TRUE, M)) || (I == parent))
|
||||
return FALSE
|
||||
return handle_item_insertion(I, silent, M)
|
||||
|
||||
/datum/component/storage/proc/signal_can_insert(obj/item/I, mob/M, silent = FALSE)
|
||||
/datum/component/storage/proc/signal_can_insert(datum/source, obj/item/I, mob/M, silent = FALSE)
|
||||
return can_be_inserted(I, silent, M)
|
||||
|
||||
/datum/component/storage/proc/show_to_ghost(mob/dead/observer/M)
|
||||
/datum/component/storage/proc/show_to_ghost(datum/source, mob/dead/observer/M)
|
||||
return user_show_to_mob(M, TRUE)
|
||||
|
||||
/datum/component/storage/proc/signal_show_attempt(mob/showto, force = FALSE)
|
||||
/datum/component/storage/proc/signal_show_attempt(datum/source, mob/showto, force = FALSE)
|
||||
return user_show_to_mob(showto, force)
|
||||
|
||||
/datum/component/storage/proc/on_check()
|
||||
@@ -638,14 +650,14 @@
|
||||
/datum/component/storage/proc/check_locked()
|
||||
return locked
|
||||
|
||||
/datum/component/storage/proc/signal_take_type(type, atom/destination, amount = INFINITY, check_adjacent = FALSE, force = FALSE, mob/user, list/inserted)
|
||||
/datum/component/storage/proc/signal_take_type(datum/source, type, atom/destination, amount = INFINITY, check_adjacent = FALSE, force = FALSE, mob/user, list/inserted)
|
||||
if(!force)
|
||||
if(check_adjacent)
|
||||
if(!user || !user.CanReach(destination) || !user.CanReach(parent))
|
||||
return FALSE
|
||||
var/list/taking = typecache_filter_list(contents(), typecacheof(type))
|
||||
if(length(taking) > amount)
|
||||
taking.Cut(amount)
|
||||
if(taking.len > amount)
|
||||
taking.len = amount
|
||||
if(inserted) //duplicated code for performance, don't bother checking retval/checking for list every item.
|
||||
for(var/i in taking)
|
||||
if(remove_from_storage(i, destination))
|
||||
@@ -659,7 +671,7 @@
|
||||
var/atom/real_location = real_location()
|
||||
return max(0, max_items - real_location.contents.len)
|
||||
|
||||
/datum/component/storage/proc/signal_fill_type(type, amount = 20, force = FALSE)
|
||||
/datum/component/storage/proc/signal_fill_type(datum/source, type, amount = 20, force = FALSE)
|
||||
var/atom/real_location = real_location()
|
||||
if(!force)
|
||||
amount = min(remaining_space_items(), amount)
|
||||
@@ -668,7 +680,7 @@
|
||||
CHECK_TICK
|
||||
return TRUE
|
||||
|
||||
/datum/component/storage/proc/on_attack_hand(mob/user)
|
||||
/datum/component/storage/proc/on_attack_hand(datum/source, mob/user)
|
||||
var/atom/A = parent
|
||||
if(!attack_hand_interact)
|
||||
return
|
||||
@@ -701,25 +713,25 @@
|
||||
else
|
||||
show_to(user)
|
||||
|
||||
/datum/component/storage/proc/signal_on_pickup(mob/user)
|
||||
/datum/component/storage/proc/signal_on_pickup(datum/source, mob/user)
|
||||
var/atom/A = parent
|
||||
update_actions()
|
||||
for(var/mob/M in range(1, A))
|
||||
if(M.active_storage == src)
|
||||
close(M)
|
||||
|
||||
/datum/component/storage/proc/signal_take_obj(atom/movable/AM, new_loc, force = FALSE)
|
||||
/datum/component/storage/proc/signal_take_obj(datum/source, atom/movable/AM, new_loc, force = FALSE)
|
||||
if(!(AM in real_location()))
|
||||
return FALSE
|
||||
return remove_from_storage(AM, new_loc)
|
||||
|
||||
/datum/component/storage/proc/signal_quick_empty(atom/loctarget)
|
||||
/datum/component/storage/proc/signal_quick_empty(datum/source, atom/loctarget)
|
||||
return do_quick_empty(loctarget)
|
||||
|
||||
/datum/component/storage/proc/signal_hide_attempt(mob/target)
|
||||
/datum/component/storage/proc/signal_hide_attempt(datum/source, mob/target)
|
||||
return hide_from(target)
|
||||
|
||||
/datum/component/storage/proc/on_alt_click(mob/user)
|
||||
/datum/component/storage/proc/on_alt_click(datum/source, mob/user)
|
||||
if(!isliving(user) || user.incapacitated() || !quickdraw || locked || !user.CanReach(parent))
|
||||
return
|
||||
var/obj/item/I = locate() in real_location()
|
||||
@@ -731,6 +743,10 @@
|
||||
return
|
||||
user.visible_message("<span class='warning'>[user] draws [I] from [parent]!</span>", "<span class='notice'>You draw [I] from [parent].</span>")
|
||||
|
||||
/datum/component/storage/proc/action_trigger(datum/signal_source, datum/action/source)
|
||||
gather_mode_switch(source.owner)
|
||||
return COMPONENT_ACTION_BLOCK_TRIGGER
|
||||
|
||||
/datum/component/storage/proc/gather_mode_switch(mob/user)
|
||||
collection_mode = (collection_mode+1)%3
|
||||
switch(collection_mode)
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
RegisterSignal(parent, COMSIG_MOVABLE_CROSSED, .proc/join_swarm)
|
||||
RegisterSignal(parent, COMSIG_MOVABLE_UNCROSSED, .proc/leave_swarm)
|
||||
|
||||
/datum/component/swarming/proc/join_swarm(atom/movable/AM)
|
||||
/datum/component/swarming/proc/join_swarm(datum/source, atom/movable/AM)
|
||||
GET_COMPONENT_FROM(other_swarm, /datum/component/swarming, AM)
|
||||
if(!other_swarm)
|
||||
return
|
||||
@@ -20,7 +20,7 @@
|
||||
other_swarm.swarm()
|
||||
other_swarm.swarm_members |= src
|
||||
|
||||
/datum/component/swarming/proc/leave_swarm(atom/movable/AM)
|
||||
/datum/component/swarming/proc/leave_swarm(datum/source, atom/movable/AM)
|
||||
GET_COMPONENT_FROM(other_swarm, /datum/component/swarming, AM)
|
||||
if(!other_swarm || !(other_swarm in swarm_members))
|
||||
return
|
||||
|
||||
@@ -68,14 +68,14 @@
|
||||
else
|
||||
QDEL_IN(fakefire, 50)
|
||||
|
||||
/datum/component/thermite/proc/clean_react(strength)
|
||||
/datum/component/thermite/proc/clean_react(datum/source, strength)
|
||||
//Thermite is just some loose powder, you could probably clean it with your hands. << todo?
|
||||
qdel(src)
|
||||
|
||||
/datum/component/thermite/proc/flame_react(exposed_temperature, exposed_volume)
|
||||
/datum/component/thermite/proc/flame_react(datum/source, exposed_temperature, exposed_volume)
|
||||
if(exposed_temperature > 1922) // This is roughly the real life requirement to ignite thermite
|
||||
thermite_melt()
|
||||
|
||||
/datum/component/thermite/proc/attackby_react(obj/item/thing, mob/user, params)
|
||||
/datum/component/thermite/proc/attackby_react(datum/source, obj/item/thing, mob/user, params)
|
||||
if(thing.is_hot())
|
||||
thermite_melt(user)
|
||||
@@ -84,7 +84,7 @@ GLOBAL_LIST_EMPTY(uplinks)
|
||||
gamemode = _gamemode
|
||||
uplink_items = get_uplink_items(gamemode, TRUE, allow_restricted)
|
||||
|
||||
/datum/component/uplink/proc/OnAttackBy(obj/item/I, mob/user)
|
||||
/datum/component/uplink/proc/OnAttackBy(datum/source, obj/item/I, mob/user)
|
||||
if(!active)
|
||||
return //no hitting everyone/everything just to try to slot tcs in!
|
||||
if(istype(I, /obj/item/stack/telecrystal))
|
||||
@@ -101,7 +101,7 @@ GLOBAL_LIST_EMPTY(uplinks)
|
||||
qdel(I)
|
||||
return
|
||||
|
||||
/datum/component/uplink/proc/interact(mob/user)
|
||||
/datum/component/uplink/proc/interact(datum/source, mob/user)
|
||||
if(locked)
|
||||
return
|
||||
active = TRUE
|
||||
@@ -201,28 +201,28 @@ GLOBAL_LIST_EMPTY(uplinks)
|
||||
/datum/component/uplink/proc/implant_activation()
|
||||
var/obj/item/implant/implant = parent
|
||||
locked = FALSE
|
||||
interact(implant.imp_in)
|
||||
interact(null, implant.imp_in)
|
||||
|
||||
/datum/component/uplink/proc/implanting(list/arguments)
|
||||
/datum/component/uplink/proc/implanting(datum/source, list/arguments)
|
||||
var/mob/user = arguments[2]
|
||||
owner = "[user.key]"
|
||||
|
||||
/datum/component/uplink/proc/old_implant(list/arguments, obj/item/implant/new_implant)
|
||||
/datum/component/uplink/proc/old_implant(datum/source, list/arguments, obj/item/implant/new_implant)
|
||||
// It kinda has to be weird like this until implants are components
|
||||
return SEND_SIGNAL(new_implant, COMSIG_IMPLANT_EXISTING_UPLINK, src)
|
||||
|
||||
/datum/component/uplink/proc/new_implant(datum/component/uplink/uplink)
|
||||
/datum/component/uplink/proc/new_implant(datum/source, datum/component/uplink/uplink)
|
||||
uplink.telecrystals += telecrystals
|
||||
return COMPONENT_DELETE_NEW_IMPLANT
|
||||
|
||||
// PDA signal responses
|
||||
|
||||
/datum/component/uplink/proc/new_ringtone(mob/living/user, new_ring_text)
|
||||
/datum/component/uplink/proc/new_ringtone(datum/source, mob/living/user, new_ring_text)
|
||||
var/obj/item/pda/master = parent
|
||||
if(trim(lowertext(new_ring_text)) != trim(lowertext(master.lock_code))) //why is the lock code stored on the pda?
|
||||
return
|
||||
locked = FALSE
|
||||
interact(user)
|
||||
interact(null, user)
|
||||
to_chat(user, "The PDA softly beeps.")
|
||||
user << browse(null, "window=pda")
|
||||
master.mode = 0
|
||||
@@ -230,22 +230,22 @@ GLOBAL_LIST_EMPTY(uplinks)
|
||||
|
||||
// Radio signal responses
|
||||
|
||||
/datum/component/uplink/proc/new_frequency(list/arguments)
|
||||
/datum/component/uplink/proc/new_frequency(datum/source, list/arguments)
|
||||
var/obj/item/radio/master = parent
|
||||
var/frequency = arguments[1]
|
||||
if(frequency != master.traitor_frequency)
|
||||
return
|
||||
locked = FALSE
|
||||
if(ismob(master.loc))
|
||||
interact(master.loc)
|
||||
interact(null, master.loc)
|
||||
|
||||
// Pen signal responses
|
||||
|
||||
/datum/component/uplink/proc/pen_rotation(degrees, mob/living/carbon/user)
|
||||
/datum/component/uplink/proc/pen_rotation(datum/source, degrees, mob/living/carbon/user)
|
||||
var/obj/item/pen/master = parent
|
||||
if(degrees != master.traitor_unlock_degrees)
|
||||
return
|
||||
locked = FALSE
|
||||
master.degrees = 0
|
||||
interact(user)
|
||||
interact(null, user)
|
||||
to_chat(user, "<span class='warning'>Your pen makes a clicking noise, before quickly rotating back to 0 degrees!</span>")
|
||||
15
code/datums/components/waddling.dm
Normal file
15
code/datums/components/waddling.dm
Normal file
@@ -0,0 +1,15 @@
|
||||
/datum/component/waddling
|
||||
dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS
|
||||
|
||||
/datum/component/waddling/Initialize()
|
||||
if(!isliving(parent))
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
RegisterSignal(parent, list(COMSIG_MOVABLE_MOVED), .proc/Waddle)
|
||||
|
||||
/datum/component/waddling/proc/Waddle()
|
||||
var/mob/living/L = parent
|
||||
if(L.incapacitated() || L.lying)
|
||||
return
|
||||
animate(L, pixel_z = 4, time = 0)
|
||||
animate(pixel_z = 0, transform = turn(matrix(), pick(-12, 0, 12)), time=2)
|
||||
animate(pixel_z = 0, transform = matrix(), time = 0)
|
||||
@@ -12,13 +12,13 @@
|
||||
RegisterSignal(parent, COMSIG_ITEM_EQUIPPED, .proc/on_equip)
|
||||
RegisterSignal(parent, COMSIG_ITEM_DROPPED, .proc/on_drop)
|
||||
|
||||
/datum/component/wearertargeting/proc/on_equip(mob/equipper, slot)
|
||||
/datum/component/wearertargeting/proc/on_equip(datum/source, mob/equipper, slot)
|
||||
if((slot in valid_slots) && istype(equipper, mobtype))
|
||||
RegisterSignal(equipper, signals, callback, TRUE)
|
||||
else
|
||||
UnregisterSignal(equipper, signals)
|
||||
|
||||
/datum/component/wearertargeting/proc/on_drop(mob/user)
|
||||
/datum/component/wearertargeting/proc/on_drop(datum/source, mob/user)
|
||||
UnregisterSignal(user, signals)
|
||||
|
||||
/datum/component/wearertargeting/Destroy()
|
||||
|
||||
@@ -90,7 +90,7 @@
|
||||
S.intensity = intensity
|
||||
S.lube_flags = lube_flags
|
||||
|
||||
/datum/component/wet_floor/proc/dry(strength = TURF_WET_WATER, immediate = FALSE, duration_decrease = INFINITY)
|
||||
/datum/component/wet_floor/proc/dry(datum/source, strength = TURF_WET_WATER, immediate = FALSE, duration_decrease = INFINITY)
|
||||
for(var/i in time_left_list)
|
||||
if(text2num(i) <= strength)
|
||||
time_left_list[i] = max(0, time_left_list[i] - duration_decrease)
|
||||
@@ -120,8 +120,8 @@
|
||||
if(O.obj_flags & FROZEN)
|
||||
O.make_unfrozen()
|
||||
add_wet(TURF_WET_WATER, max_time_left())
|
||||
dry(TURF_WET_ICE)
|
||||
dry(ALL, FALSE, decrease)
|
||||
dry(null, TURF_WET_ICE)
|
||||
dry(null, ALL, FALSE, decrease)
|
||||
check()
|
||||
last_process = world.time
|
||||
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
var/gc_destroyed //Time when this object was destroyed.
|
||||
var/list/active_timers //for SStimer
|
||||
var/list/datum_components //for /datum/components
|
||||
var/list/comp_lookup //for /datum/components
|
||||
var/list/comp_lookup //it used to be for looking up components which had registered a signal but now anything can register
|
||||
var/list/signal_procs
|
||||
var/signal_enabled = FALSE
|
||||
var/datum_flags = NONE
|
||||
var/datum/weakref/weak_reference
|
||||
|
||||
@@ -20,6 +22,7 @@
|
||||
// Return the appropriate QDEL_HINT; in most cases this is QDEL_HINT_QUEUE.
|
||||
/datum/proc/Destroy(force=FALSE, ...)
|
||||
tag = null
|
||||
datum_flags &= ~DF_USE_TAG //In case something tries to REF us
|
||||
weak_reference = null //ensure prompt GCing of weakref.
|
||||
|
||||
var/list/timers = active_timers
|
||||
@@ -30,6 +33,9 @@
|
||||
continue
|
||||
qdel(timer)
|
||||
|
||||
//BEGIN: ECS SHIT
|
||||
signal_enabled = FALSE
|
||||
|
||||
var/list/dc = datum_components
|
||||
if(dc)
|
||||
var/all_components = dc[/datum/component]
|
||||
@@ -55,6 +61,10 @@
|
||||
comp.UnregisterSignal(src, sig)
|
||||
comp_lookup = lookup = null
|
||||
|
||||
for(var/target in signal_procs)
|
||||
UnregisterSignal(target, signal_procs[target])
|
||||
//END: ECS SHIT
|
||||
|
||||
return QDEL_HINT_QUEUE
|
||||
|
||||
#ifdef DATUMVAR_DEBUGGING_MODE
|
||||
@@ -86,16 +96,16 @@
|
||||
|
||||
//Return a LIST for serialize_datum to encode! Not the actual json!
|
||||
/datum/proc/serialize_list(list/options)
|
||||
return NOT_IMPLEMENTED
|
||||
CRASH("Attempted to serialize datum [src] of type [type] without serialize_list being implemented!")
|
||||
|
||||
//Accepts a LIST from deserialize_datum. Should return src or another datum.
|
||||
/datum/proc/deserialize_list(json, list/options)
|
||||
return NOT_IMPLEMENTED
|
||||
CRASH("Attempted to deserialize datum [src] of type [type] without deserialize_list being implemented!")
|
||||
|
||||
//Serializes into JSON. Does not encode type.
|
||||
/datum/proc/serialize_json(list/options)
|
||||
. = serialize_list(options)
|
||||
if((. == NOT_IMPLEMENTED) || !islist(.))
|
||||
if(!islist(.))
|
||||
. = null
|
||||
else
|
||||
. = json_encode(.)
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
#define VV_MSG_MARKED "<br><font size='1' color='red'><b>Marked Object</b></font>"
|
||||
#define VV_MSG_EDITED "<br><font size='1' color='red'><b>Var Edited</b></font>"
|
||||
#define VV_MSG_DELETED "<br><font size='1' color='red'><b>Deleted</b></font>"
|
||||
|
||||
/datum/proc/CanProcCall(procname)
|
||||
return TRUE
|
||||
|
||||
@@ -9,6 +13,7 @@
|
||||
return FALSE
|
||||
vars[var_name] = var_value
|
||||
datum_flags |= DF_VAR_EDITED
|
||||
return TRUE
|
||||
|
||||
/datum/proc/vv_get_var(var_name)
|
||||
switch(var_name)
|
||||
@@ -68,6 +73,7 @@
|
||||
src << browse_rsc(sprite, "vv[hash].png")
|
||||
|
||||
title = "[D] ([REF(D)]) = [type]"
|
||||
var/formatted_type = replacetext("[type]", "/", "<wbr>/")
|
||||
|
||||
var/sprite_text
|
||||
if(sprite)
|
||||
@@ -77,36 +83,40 @@
|
||||
if(istype(D, /atom))
|
||||
var/atom/A = D
|
||||
if(isliving(A))
|
||||
atomsnowflake += "<a href='?_src_=vars;[HrefToken()];rename=[refid]'><b>[D]</b></a>"
|
||||
if(A.dir)
|
||||
atomsnowflake += "<br><font size='1'><a href='?_src_=vars;[HrefToken()];rotatedatum=[refid];rotatedir=left'><<</a> <a href='?_src_=vars;[HrefToken()];datumedit=[refid];varnameedit=dir'>[dir2text(A.dir)]</a> <a href='?_src_=vars;[HrefToken()];rotatedatum=[refid];rotatedir=right'>>></a></font>"
|
||||
atomsnowflake += "<a href='?_src_=vars;[HrefToken()];rename=[refid]'><b id='name'>[D]</b></a>"
|
||||
atomsnowflake += "<br><font size='1'><a href='?_src_=vars;[HrefToken()];rotatedatum=[refid];rotatedir=left'><<</a> <a href='?_src_=vars;[HrefToken()];datumedit=[refid];varnameedit=dir' id='dir'>[dir2text(A.dir) || A.dir]</a> <a href='?_src_=vars;[HrefToken()];rotatedatum=[refid];rotatedir=right'>>></a></font>"
|
||||
var/mob/living/M = A
|
||||
atomsnowflake += {"
|
||||
<br><font size='1'><a href='?_src_=vars;[HrefToken()];datumedit=[refid];varnameedit=ckey'>[M.ckey ? M.ckey : "No ckey"]</a> / <a href='?_src_=vars;[HrefToken()];datumedit=[refid];varnameedit=real_name'>[M.real_name ? M.real_name : "No real name"]</a></font>
|
||||
<br><font size='1'><a href='?_src_=vars;[HrefToken()];datumedit=[refid];varnameedit=ckey' id='ckey'>[M.ckey || "No ckey"]</a> / <a href='?_src_=vars;[HrefToken()];datumedit=[refid];varnameedit=real_name' id='real_name'>[M.real_name || "No real name"]</a></font>
|
||||
<br><font size='1'>
|
||||
BRUTE:<font size='1'><a href='?_src_=vars;[HrefToken()];mobToDamage=[refid];adjustDamage=brute'>[M.getBruteLoss()]</a>
|
||||
FIRE:<font size='1'><a href='?_src_=vars;[HrefToken()];mobToDamage=[refid];adjustDamage=fire'>[M.getFireLoss()]</a>
|
||||
TOXIN:<font size='1'><a href='?_src_=vars;[HrefToken()];mobToDamage=[refid];adjustDamage=toxin'>[M.getToxLoss()]</a>
|
||||
OXY:<font size='1'><a href='?_src_=vars;[HrefToken()];mobToDamage=[refid];adjustDamage=oxygen'>[M.getOxyLoss()]</a>
|
||||
CLONE:<font size='1'><a href='?_src_=vars;[HrefToken()];mobToDamage=[refid];adjustDamage=clone'>[M.getCloneLoss()]</a>
|
||||
BRAIN:<font size='1'><a href='?_src_=vars;[HrefToken()];mobToDamage=[refid];adjustDamage=brain'>[M.getBrainLoss()]</a>
|
||||
STAMINA:<font size='1'><a href='?_src_=vars;[HrefToken()];mobToDamage=[refid];adjustDamage=stamina'>[M.getStaminaLoss()]</a>
|
||||
BRUTE:<font size='1'><a href='?_src_=vars;[HrefToken()];mobToDamage=[refid];adjustDamage=brute' id='brute'>[M.getBruteLoss()]</a>
|
||||
FIRE:<font size='1'><a href='?_src_=vars;[HrefToken()];mobToDamage=[refid];adjustDamage=fire' id='fire'>[M.getFireLoss()]</a>
|
||||
TOXIN:<font size='1'><a href='?_src_=vars;[HrefToken()];mobToDamage=[refid];adjustDamage=toxin' id='toxin'>[M.getToxLoss()]</a>
|
||||
OXY:<font size='1'><a href='?_src_=vars;[HrefToken()];mobToDamage=[refid];adjustDamage=oxygen' id='oxygen'>[M.getOxyLoss()]</a>
|
||||
CLONE:<font size='1'><a href='?_src_=vars;[HrefToken()];mobToDamage=[refid];adjustDamage=clone' id='clone'>[M.getCloneLoss()]</a>
|
||||
BRAIN:<font size='1'><a href='?_src_=vars;[HrefToken()];mobToDamage=[refid];adjustDamage=brain' id='brain'>[M.getBrainLoss()]</a>
|
||||
STAMINA:<font size='1'><a href='?_src_=vars;[HrefToken()];mobToDamage=[refid];adjustDamage=stamina' id='stamina'>[M.getStaminaLoss()]</a>
|
||||
AROUSAL:<font size='1'><a href='?_src_=vars;[HrefToken()];mobToDamage=[refid];adjustDamage=arousal' id='arousal'>[M.getArousalLoss()]</a>
|
||||
</font>
|
||||
"}
|
||||
else
|
||||
atomsnowflake += "<a href='?_src_=vars;[HrefToken()];datumedit=[refid];varnameedit=name'><b>[D]</b></a>"
|
||||
if(A.dir)
|
||||
atomsnowflake += "<br><font size='1'><a href='?_src_=vars;[HrefToken()];rotatedatum=[refid];rotatedir=left'><<</a> <a href='?_src_=vars;[HrefToken()];datumedit=[refid];varnameedit=dir'>[dir2text(A.dir)]</a> <a href='?_src_=vars;[HrefToken()];rotatedatum=[refid];rotatedir=right'>>></a></font>"
|
||||
atomsnowflake += "<a href='?_src_=vars;[HrefToken()];datumedit=[refid];varnameedit=name'><b id='name'>[D]</b></a>"
|
||||
atomsnowflake += "<br><font size='1'><a href='?_src_=vars;[HrefToken()];rotatedatum=[refid];rotatedir=left'><<</a> <a href='?_src_=vars;[HrefToken()];datumedit=[refid];varnameedit=dir' id='dir'>[dir2text(A.dir) || A.dir]</a> <a href='?_src_=vars;[HrefToken()];rotatedatum=[refid];rotatedir=right'>>></a></font>"
|
||||
else if("name" in D.vars)
|
||||
atomsnowflake += "<a href='?_src_=vars;[HrefToken()];datumedit=[refid];varnameedit=name'><b id='name'>[D]</b></a>"
|
||||
else
|
||||
atomsnowflake += "<b>[D]</b>"
|
||||
atomsnowflake += "<b>[formatted_type]</b>"
|
||||
formatted_type = null
|
||||
|
||||
var/formatted_type = replacetext("[type]", "/", "<wbr>/")
|
||||
var/marked
|
||||
if(holder && holder.marked_datum && holder.marked_datum == D)
|
||||
marked = "<br><font size='1' color='red'><b>Marked Object</b></font>"
|
||||
marked = VV_MSG_MARKED
|
||||
var/varedited_line = ""
|
||||
if(!islist && (D.datum_flags & DF_VAR_EDITED))
|
||||
varedited_line = "<br><font size='1' color='red'><b>Var Edited</b></font>"
|
||||
varedited_line = VV_MSG_EDITED
|
||||
var/deleted_line
|
||||
if(!islist && D.gc_destroyed)
|
||||
deleted_line = VV_MSG_DELETED
|
||||
|
||||
var/list/dropdownoptions = list()
|
||||
if (islist)
|
||||
@@ -167,112 +177,9 @@
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body onload='selectTextField(); updateSearch()' onkeydown='return checkreload()' onkeyup='updateSearch()'>
|
||||
<body onload='selectTextField()' onkeydown='return handle_keydown()' onkeyup='handle_keyup()'>
|
||||
<script type="text/javascript">
|
||||
function checkreload() {
|
||||
if(event.keyCode == 116){ //F5 (to refresh properly)
|
||||
document.getElementById("refresh_link").click();
|
||||
event.preventDefault ? event.preventDefault() : (event.returnValue = false)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
function updateSearch(){
|
||||
var filter_text = document.getElementById('filter');
|
||||
var filter = filter_text.value.toLowerCase();
|
||||
if(event.keyCode == 13){ //Enter / return
|
||||
var vars_ol = document.getElementById('vars');
|
||||
var lis = vars_ol.getElementsByTagName("li");
|
||||
for ( var i = 0; i < lis.length; ++i )
|
||||
{
|
||||
try{
|
||||
var li = lis\[i\];
|
||||
if ( li.style.backgroundColor == "#ffee88" )
|
||||
{
|
||||
alist = lis\[i\].getElementsByTagName("a")
|
||||
if(alist.length > 0){
|
||||
location.href=alist\[0\].href;
|
||||
}
|
||||
}
|
||||
}catch(err) { }
|
||||
}
|
||||
return
|
||||
}
|
||||
if(event.keyCode == 38){ //Up arrow
|
||||
var vars_ol = document.getElementById('vars');
|
||||
var lis = vars_ol.getElementsByTagName("li");
|
||||
for ( var i = 0; i < lis.length; ++i )
|
||||
{
|
||||
try{
|
||||
var li = lis\[i\];
|
||||
if ( li.style.backgroundColor == "#ffee88" )
|
||||
{
|
||||
if( (i-1) >= 0){
|
||||
var li_new = lis\[i-1\];
|
||||
li.style.backgroundColor = "white";
|
||||
li_new.style.backgroundColor = "#ffee88";
|
||||
return
|
||||
}
|
||||
}
|
||||
}catch(err) { }
|
||||
}
|
||||
return
|
||||
}
|
||||
if(event.keyCode == 40){ //Down arrow
|
||||
var vars_ol = document.getElementById('vars');
|
||||
var lis = vars_ol.getElementsByTagName("li");
|
||||
for ( var i = 0; i < lis.length; ++i )
|
||||
{
|
||||
try{
|
||||
var li = lis\[i\];
|
||||
if ( li.style.backgroundColor == "#ffee88" )
|
||||
{
|
||||
if( (i+1) < lis.length){
|
||||
var li_new = lis\[i+1\];
|
||||
li.style.backgroundColor = "white";
|
||||
li_new.style.backgroundColor = "#ffee88";
|
||||
return
|
||||
}
|
||||
}
|
||||
}catch(err) { }
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//This part here resets everything to how it was at the start so the filter is applied to the complete list. Screw efficiency, it's client-side anyway and it only looks through 200 or so variables at maximum anyway (mobs).
|
||||
if(complete_list != null && complete_list != ""){
|
||||
var vars_ol1 = document.getElementById("vars");
|
||||
vars_ol1.innerHTML = complete_list
|
||||
}
|
||||
document.cookie="[refid][cookieoffset]search="+encodeURIComponent(filter);
|
||||
if(filter == ""){
|
||||
return;
|
||||
}else{
|
||||
var vars_ol = document.getElementById('vars');
|
||||
var lis = vars_ol.getElementsByTagName("li");
|
||||
for ( var i = 0; i < lis.length; ++i )
|
||||
{
|
||||
try{
|
||||
var li = lis\[i\];
|
||||
if ( li.innerText.toLowerCase().indexOf(filter) == -1 )
|
||||
{
|
||||
vars_ol.removeChild(li);
|
||||
i--;
|
||||
}
|
||||
}catch(err) { }
|
||||
}
|
||||
}
|
||||
var lis_new = vars_ol.getElementsByTagName("li");
|
||||
for ( var j = 0; j < lis_new.length; ++j )
|
||||
{
|
||||
var li1 = lis\[j\];
|
||||
if (j == 0){
|
||||
li1.style.backgroundColor = "#ffee88";
|
||||
}else{
|
||||
li1.style.backgroundColor = "white";
|
||||
}
|
||||
}
|
||||
}
|
||||
// onload
|
||||
function selectTextField() {
|
||||
var filter_text = document.getElementById('filter');
|
||||
filter_text.focus();
|
||||
@@ -283,23 +190,140 @@
|
||||
updateSearch();
|
||||
}
|
||||
}
|
||||
function loadPage(list) {
|
||||
if(list.options\[list.selectedIndex\].value == ""){
|
||||
return;
|
||||
}
|
||||
location.href=list.options\[list.selectedIndex\].value;
|
||||
}
|
||||
function getCookie(cname) {
|
||||
var name = cname + "=";
|
||||
var ca = document.cookie.split(';');
|
||||
for(var i=0; i<ca.length; i++) {
|
||||
var c = ca\[i\];
|
||||
var c = ca\[i];
|
||||
while (c.charAt(0)==' ') c = c.substring(1,c.length);
|
||||
if (c.indexOf(name)==0) return c.substring(name.length,c.length);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
// main search functionality
|
||||
var last_filter = "";
|
||||
function updateSearch() {
|
||||
var filter = document.getElementById('filter').value.toLowerCase();
|
||||
var vars_ol = document.getElementById("vars");
|
||||
|
||||
if (filter === last_filter) {
|
||||
// An event triggered an update but nothing has changed.
|
||||
return;
|
||||
} else if (filter.indexOf(last_filter) === 0) {
|
||||
// The new filter starts with the old filter, fast path by removing only.
|
||||
var children = vars_ol.childNodes;
|
||||
for (var i = children.length - 1; i >= 0; --i) {
|
||||
try {
|
||||
var li = children\[i];
|
||||
if (li.innerText.toLowerCase().indexOf(filter) == -1) {
|
||||
vars_ol.removeChild(li);
|
||||
}
|
||||
} catch(err) {}
|
||||
}
|
||||
} else {
|
||||
// Remove everything and put back what matches.
|
||||
while (vars_ol.hasChildNodes()) {
|
||||
vars_ol.removeChild(vars_ol.lastChild);
|
||||
}
|
||||
|
||||
for (var i = 0; i < complete_list.length; ++i) {
|
||||
try {
|
||||
var li = complete_list\[i];
|
||||
if (!filter || li.innerText.toLowerCase().indexOf(filter) != -1) {
|
||||
vars_ol.appendChild(li);
|
||||
}
|
||||
} catch(err) {}
|
||||
}
|
||||
}
|
||||
|
||||
last_filter = filter;
|
||||
document.cookie="[refid][cookieoffset]search="+encodeURIComponent(filter);
|
||||
|
||||
var lis_new = vars_ol.getElementsByTagName("li");
|
||||
for (var j = 0; j < lis_new.length; ++j) {
|
||||
lis_new\[j].style.backgroundColor = (j == 0) ? "#ffee88" : "white";
|
||||
}
|
||||
}
|
||||
|
||||
// onkeydown
|
||||
function handle_keydown() {
|
||||
if(event.keyCode == 116) { //F5 (to refresh properly)
|
||||
document.getElementById("refresh_link").click();
|
||||
event.preventDefault ? event.preventDefault() : (event.returnValue = false);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// onkeyup
|
||||
function handle_keyup() {
|
||||
if (event.keyCode == 13) { //Enter / return
|
||||
var vars_ol = document.getElementById('vars');
|
||||
var lis = vars_ol.getElementsByTagName("li");
|
||||
for (var i = 0; i < lis.length; ++i) {
|
||||
try {
|
||||
var li = lis\[i];
|
||||
if (li.style.backgroundColor == "#ffee88") {
|
||||
alist = lis\[i].getElementsByTagName("a");
|
||||
if(alist.length > 0) {
|
||||
location.href=alist\[0].href;
|
||||
}
|
||||
}
|
||||
} catch(err) {}
|
||||
}
|
||||
} else if(event.keyCode == 38){ //Up arrow
|
||||
var vars_ol = document.getElementById('vars');
|
||||
var lis = vars_ol.getElementsByTagName("li");
|
||||
for (var i = 0; i < lis.length; ++i) {
|
||||
try {
|
||||
var li = lis\[i];
|
||||
if (li.style.backgroundColor == "#ffee88") {
|
||||
if (i > 0) {
|
||||
var li_new = lis\[i-1];
|
||||
li.style.backgroundColor = "white";
|
||||
li_new.style.backgroundColor = "#ffee88";
|
||||
return
|
||||
}
|
||||
}
|
||||
} catch(err) {}
|
||||
}
|
||||
} else if(event.keyCode == 40) { //Down arrow
|
||||
var vars_ol = document.getElementById('vars');
|
||||
var lis = vars_ol.getElementsByTagName("li");
|
||||
for (var i = 0; i < lis.length; ++i) {
|
||||
try {
|
||||
var li = lis\[i];
|
||||
if (li.style.backgroundColor == "#ffee88") {
|
||||
if ((i+1) < lis.length) {
|
||||
var li_new = lis\[i+1];
|
||||
li.style.backgroundColor = "white";
|
||||
li_new.style.backgroundColor = "#ffee88";
|
||||
return
|
||||
}
|
||||
}
|
||||
} catch(err) {}
|
||||
}
|
||||
} else {
|
||||
updateSearch();
|
||||
}
|
||||
}
|
||||
|
||||
// onchange
|
||||
function handle_dropdown(list) {
|
||||
var value = list.options\[list.selectedIndex].value;
|
||||
if (value !== "") {
|
||||
location.href = value;
|
||||
}
|
||||
list.selectedIndex = 0;
|
||||
document.getElementById('filter').focus();
|
||||
}
|
||||
|
||||
// byjax
|
||||
function replace_span(what) {
|
||||
var idx = what.indexOf(':');
|
||||
document.getElementById(what.substr(0, idx)).innerHTML = what.substr(idx + 1);
|
||||
}
|
||||
</script>
|
||||
<div align='center'>
|
||||
<table width='100%'>
|
||||
@@ -317,8 +341,9 @@
|
||||
</table>
|
||||
<div align='center'>
|
||||
<b><font size='1'>[formatted_type]</font></b>
|
||||
[marked]
|
||||
[varedited_line]
|
||||
<span id='marked'>[marked]</span>
|
||||
<span id='varedited'>[varedited_line]</span>
|
||||
<span id='deleted'>[deleted_line]</span>
|
||||
</div>
|
||||
</td>
|
||||
<td width='50%'>
|
||||
@@ -326,8 +351,7 @@
|
||||
<a id='refresh_link' href='?_src_=vars;[HrefToken()];datumrefresh=[refid]'>Refresh</a>
|
||||
<form>
|
||||
<select name="file" size="1"
|
||||
onchange="loadPage(this.form.elements\[0\])"
|
||||
target="_parent._top"
|
||||
onchange="handle_dropdown(this)"
|
||||
onmouseclick="this.focus()"
|
||||
style="background-color:#ffffff">
|
||||
<option value selected>Select option</option>
|
||||
@@ -363,8 +387,9 @@
|
||||
[variable_html.Join()]
|
||||
</ol>
|
||||
<script type='text/javascript'>
|
||||
var vars_ol = document.getElementById("vars");
|
||||
var complete_list = vars_ol.innerHTML;
|
||||
var complete_list = \[\];
|
||||
var lis = document.getElementById("vars").children;
|
||||
for(var i = lis.length; i--;) complete_list\[i\] = lis\[i\];
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -372,6 +397,10 @@
|
||||
src << browse(html, "window=variables[refid];size=475x650")
|
||||
|
||||
|
||||
/client/proc/vv_update_display(datum/D, span, content)
|
||||
src << output("[span]:[content]", "variables[REF(D)].browser:replace_span")
|
||||
|
||||
|
||||
#define VV_HTML_ENCODE(thing) ( sanitize ? html_encode(thing) : thing )
|
||||
/proc/debug_variable(name, value, level, datum/DA = null, sanitize = TRUE)
|
||||
var/header
|
||||
@@ -471,7 +500,6 @@
|
||||
return
|
||||
|
||||
src.holder.show_player_panel(M)
|
||||
href_list["datumrefresh"] = href_list["mob_player_panel"]
|
||||
|
||||
else if(href_list["godmode"])
|
||||
if(!check_rights(R_ADMIN))
|
||||
@@ -483,7 +511,6 @@
|
||||
return
|
||||
|
||||
src.cmd_admin_godmode(M)
|
||||
href_list["datumrefresh"] = href_list["godmode"]
|
||||
|
||||
else if(href_list["mark_object"])
|
||||
if(!check_rights(NONE))
|
||||
@@ -494,8 +521,10 @@
|
||||
to_chat(usr, "This can only be done to instances of type /datum")
|
||||
return
|
||||
|
||||
src.holder.marked_datum = D
|
||||
href_list["datumrefresh"] = href_list["mark_object"]
|
||||
if(holder.marked_datum)
|
||||
vv_update_display(holder.marked_datum, "marked", "")
|
||||
holder.marked_datum = D
|
||||
vv_update_display(D, "marked", VV_MSG_MARKED)
|
||||
|
||||
else if(href_list["proc_call"])
|
||||
if(!check_rights(NONE))
|
||||
@@ -511,10 +540,11 @@
|
||||
return
|
||||
|
||||
var/datum/D = locate(href_list["delete"])
|
||||
if(!D)
|
||||
if(!istype(D))
|
||||
to_chat(usr, "Unable to locate item!")
|
||||
admin_delete(D)
|
||||
href_list["datumrefresh"] = href_list["delete"]
|
||||
if (isturf(D)) // show the turf that took its place
|
||||
debug_variables(D)
|
||||
|
||||
else if(href_list["osay"])
|
||||
if(!check_rights(R_FUN, 0))
|
||||
@@ -573,18 +603,33 @@
|
||||
|
||||
message_admins("Admin [key_name_admin(usr)] renamed [key_name_admin(M)] to [new_name].")
|
||||
M.fully_replace_character_name(M.real_name,new_name)
|
||||
href_list["datumrefresh"] = href_list["rename"]
|
||||
vv_update_display(M, "name", new_name)
|
||||
vv_update_display(M, "real_name", M.real_name || "No real name")
|
||||
|
||||
else if(href_list["varnameedit"] && href_list["datumedit"])
|
||||
if(!check_rights(NONE))
|
||||
return
|
||||
|
||||
var/D = locate(href_list["datumedit"])
|
||||
var/datum/D = locate(href_list["datumedit"])
|
||||
if(!istype(D, /datum))
|
||||
to_chat(usr, "This can only be used on datums")
|
||||
return
|
||||
|
||||
modify_variables(D, href_list["varnameedit"], 1)
|
||||
if (!modify_variables(D, href_list["varnameedit"], 1))
|
||||
return
|
||||
switch(href_list["varnameedit"])
|
||||
if("name")
|
||||
vv_update_display(D, "name", "[D]")
|
||||
if("dir")
|
||||
if(isatom(D))
|
||||
var/dir = D.vars["dir"]
|
||||
vv_update_display(D, "dir", dir2text(dir) || dir)
|
||||
if("ckey")
|
||||
if(isliving(D))
|
||||
vv_update_display(D, "ckey", D.vars["ckey"] || "No ckey")
|
||||
if("real_name")
|
||||
if(isliving(D))
|
||||
vv_update_display(D, "real_name", D.vars["real_name"] || "No real name")
|
||||
|
||||
else if(href_list["varnamechange"] && href_list["datumchange"])
|
||||
if(!check_rights(NONE))
|
||||
@@ -716,7 +761,6 @@
|
||||
return
|
||||
|
||||
src.give_spell(M)
|
||||
href_list["datumrefresh"] = href_list["give_spell"]
|
||||
|
||||
else if(href_list["remove_spell"])
|
||||
if(!check_rights(NONE))
|
||||
@@ -728,7 +772,6 @@
|
||||
return
|
||||
|
||||
remove_spell(M)
|
||||
href_list["datumrefresh"] = href_list["remove_spell"]
|
||||
|
||||
else if(href_list["give_disease"])
|
||||
if(!check_rights(NONE))
|
||||
@@ -740,7 +783,6 @@
|
||||
return
|
||||
|
||||
src.give_disease(M)
|
||||
href_list["datumrefresh"] = href_list["give_spell"]
|
||||
|
||||
else if(href_list["gib"])
|
||||
if(!check_rights(R_FUN))
|
||||
@@ -763,7 +805,6 @@
|
||||
return
|
||||
|
||||
togglebuildmode(M)
|
||||
href_list["datumrefresh"] = href_list["build_mode"]
|
||||
|
||||
else if(href_list["drop_everything"])
|
||||
if(!check_rights(NONE))
|
||||
@@ -814,7 +855,7 @@
|
||||
for (var/i in armorlist)
|
||||
pickerlist += list(list("value" = armorlist[i], "name" = i))
|
||||
|
||||
var/list/result = presentpicker(usr, "Modify armor", "Modify armor: [O]", Button1="Save", Button2 = "Cancel", Timeout=FALSE, Type = "text", values = pickerlist)
|
||||
var/list/result = presentpicker(usr, "Modify armor", "Modify armor: [O]", Button1="Save", Button2 = "Cancel", Timeout=FALSE, inputtype = "text", values = pickerlist)
|
||||
|
||||
if (islist(result))
|
||||
if (result["button"] == 2) // If the user pressed the cancel button
|
||||
@@ -915,8 +956,6 @@
|
||||
log_admin("[key_name(usr)] has added [amount] units of [chosen_id] to \the [A]")
|
||||
message_admins("<span class='notice'>[key_name(usr)] has added [amount] units of [chosen_id] to \the [A]</span>")
|
||||
|
||||
href_list["datumrefresh"] = href_list["addreagent"]
|
||||
|
||||
else if(href_list["explode"])
|
||||
if(!check_rights(R_FUN))
|
||||
return
|
||||
@@ -927,7 +966,6 @@
|
||||
return
|
||||
|
||||
src.cmd_admin_explosion(A)
|
||||
href_list["datumrefresh"] = href_list["explode"]
|
||||
|
||||
else if(href_list["emp"])
|
||||
if(!check_rights(R_FUN))
|
||||
@@ -939,7 +977,6 @@
|
||||
return
|
||||
|
||||
src.cmd_admin_emp(A)
|
||||
href_list["datumrefresh"] = href_list["emp"]
|
||||
|
||||
else if(href_list["modtransform"])
|
||||
if(!check_rights(R_DEBUG))
|
||||
@@ -968,8 +1005,6 @@
|
||||
if(!isnull(angle))
|
||||
A.transform = M.Turn(angle)
|
||||
|
||||
href_list["datumrefresh"] = href_list["modtransform"]
|
||||
|
||||
else if(href_list["rotatedatum"])
|
||||
if(!check_rights(NONE))
|
||||
return
|
||||
@@ -984,7 +1019,7 @@
|
||||
A.setDir(turn(A.dir, -45))
|
||||
if("left")
|
||||
A.setDir(turn(A.dir, 45))
|
||||
href_list["datumrefresh"] = href_list["rotatedatum"]
|
||||
vv_update_display(A, "dir", dir2text(A.dir))
|
||||
|
||||
else if(href_list["editorgans"])
|
||||
if(!check_rights(NONE))
|
||||
@@ -996,7 +1031,33 @@
|
||||
return
|
||||
|
||||
manipulate_organs(C)
|
||||
href_list["datumrefresh"] = href_list["editorgans"]
|
||||
|
||||
else if(href_list["givemartialart"])
|
||||
if(!check_rights(NONE))
|
||||
return
|
||||
|
||||
var/mob/living/carbon/C = locate(href_list["givemartialart"]) in GLOB.carbon_list
|
||||
if(!istype(C))
|
||||
to_chat(usr, "This can only be done to instances of type /mob/living/carbon")
|
||||
return
|
||||
|
||||
var/list/artpaths = subtypesof(/datum/martial_art)
|
||||
var/list/artnames = list()
|
||||
for(var/i in artpaths)
|
||||
var/datum/martial_art/M = i
|
||||
artnames[initial(M.name)] = M
|
||||
|
||||
var/result = input(usr, "Choose the martial art to teach","JUDO CHOP") as null|anything in artnames
|
||||
if(!usr)
|
||||
return
|
||||
if(QDELETED(C))
|
||||
to_chat(usr, "Mob doesn't exist anymore")
|
||||
return
|
||||
|
||||
if(result)
|
||||
var/chosenart = artnames[result]
|
||||
var/datum/martial_art/MA = new chosenart
|
||||
MA.teach(C)
|
||||
|
||||
else if(href_list["givetrauma"])
|
||||
if(!check_rights(NONE))
|
||||
@@ -1018,8 +1079,6 @@
|
||||
if(result)
|
||||
C.gain_trauma(result)
|
||||
|
||||
href_list["datumrefresh"] = href_list["givetrauma"]
|
||||
|
||||
else if(href_list["curetraumas"])
|
||||
if(!check_rights(NONE))
|
||||
return
|
||||
@@ -1031,8 +1090,6 @@
|
||||
|
||||
C.cure_all_traumas(TRAUMA_RESILIENCE_ABSOLUTE)
|
||||
|
||||
href_list["datumrefresh"] = href_list["curetraumas"]
|
||||
|
||||
else if(href_list["hallucinate"])
|
||||
if(!check_rights(NONE))
|
||||
return
|
||||
@@ -1262,21 +1319,32 @@
|
||||
to_chat(usr, "Mob doesn't exist anymore")
|
||||
return
|
||||
|
||||
var/newamt
|
||||
switch(Text)
|
||||
if("brute")
|
||||
L.adjustBruteLoss(amount)
|
||||
newamt = L.getBruteLoss()
|
||||
if("fire")
|
||||
L.adjustFireLoss(amount)
|
||||
newamt = L.getFireLoss()
|
||||
if("toxin")
|
||||
L.adjustToxLoss(amount)
|
||||
newamt = L.getToxLoss()
|
||||
if("oxygen")
|
||||
L.adjustOxyLoss(amount)
|
||||
newamt = L.getOxyLoss()
|
||||
if("brain")
|
||||
L.adjustBrainLoss(amount)
|
||||
newamt = L.getBrainLoss()
|
||||
if("clone")
|
||||
L.adjustCloneLoss(amount)
|
||||
newamt = L.getCloneLoss()
|
||||
if("stamina")
|
||||
L.adjustStaminaLoss(amount)
|
||||
newamt = L.getStaminaLoss()
|
||||
if("arousal")
|
||||
L.adjustArousalLoss(amount)
|
||||
newamt = L.getArousalLoss()
|
||||
else
|
||||
to_chat(usr, "You caused an error. DEBUG: Text:[Text] Mob:[L]")
|
||||
return
|
||||
@@ -1286,4 +1354,10 @@
|
||||
var/msg = "<span class='notice'>[key_name(usr)] dealt [amount] amount of [Text] damage to [L] </span>"
|
||||
message_admins(msg)
|
||||
admin_ticket_log(L, msg)
|
||||
href_list["datumrefresh"] = href_list["mobToDamage"]
|
||||
vv_update_display(L, Text, "[newamt]")
|
||||
else if(href_list["copyoutfit"])
|
||||
if(!check_rights(R_SPAWN))
|
||||
return
|
||||
var/mob/living/carbon/human/H = locate(href_list["copyoutfit"]) in GLOB.carbon_list
|
||||
if(istype(H))
|
||||
H.copy_outfit()
|
||||
@@ -233,7 +233,7 @@
|
||||
|
||||
/datum/symptom/heal/coma/CanHeal(datum/disease/advance/A)
|
||||
var/mob/living/M = A.affected_mob
|
||||
if(M.has_trait(TRAIT_FAKEDEATH))
|
||||
if(M.has_trait(TRAIT_DEATHCOMA))
|
||||
return power
|
||||
else if(M.IsUnconscious() || M.stat == UNCONSCIOUS)
|
||||
return power * 0.9
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
cure()
|
||||
else if(prob(parrot.speak_chance))
|
||||
if(parrot.speech_buffer.len)
|
||||
affected_mob.say(pick(parrot.speech_buffer))
|
||||
affected_mob.say(pick(parrot.speech_buffer), forced = "parrot possession")
|
||||
|
||||
/datum/disease/parrot_possession/cure()
|
||||
if(parrot && parrot.loc == affected_mob)
|
||||
|
||||
@@ -25,4 +25,4 @@
|
||||
to_chat(affected_mob, "<span class='danger'>Your thoughts are interrupted by a loud <b>HONK!</b></span>")
|
||||
if(4)
|
||||
if(prob(5))
|
||||
affected_mob.say( pick( list("HONK!", "Honk!", "Honk.", "Honk?", "Honk!!", "Honk?!", "Honk...") ) )
|
||||
affected_mob.say( pick( list("HONK!", "Honk!", "Honk.", "Honk?", "Honk!!", "Honk?!", "Honk...") ) , forced = "pierrot's throat")
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
var/list/stage4 = list("You feel white bread.")
|
||||
var/list/stage5 = list("Oh the humanity!")
|
||||
var/new_form = /mob/living/carbon/human
|
||||
var/bantype
|
||||
|
||||
/datum/disease/transformation/Copy()
|
||||
var/datum/disease/transformation/D = ..()
|
||||
@@ -49,10 +50,6 @@
|
||||
if(istype(affected_mob, /mob/living/carbon) && affected_mob.stat != DEAD)
|
||||
if(stage5)
|
||||
to_chat(affected_mob, pick(stage5))
|
||||
if(jobban_isbanned(affected_mob, new_form))
|
||||
if(!QDELETED(affected_mob))
|
||||
affected_mob.death(1)
|
||||
return
|
||||
if(QDELETED(affected_mob))
|
||||
return
|
||||
if(affected_mob.notransform)
|
||||
@@ -64,6 +61,8 @@
|
||||
affected_mob.dropItemToGround(I)
|
||||
var/mob/living/new_mob = new new_form(affected_mob.loc)
|
||||
if(istype(new_mob))
|
||||
if(bantype && jobban_isbanned(affected_mob, bantype))
|
||||
replace_banned_player(new_mob)
|
||||
new_mob.a_intent = INTENT_HARM
|
||||
if(affected_mob.mind)
|
||||
affected_mob.mind.transfer_to(new_mob)
|
||||
@@ -74,7 +73,22 @@
|
||||
new_mob.real_name = new_mob.name
|
||||
qdel(affected_mob)
|
||||
|
||||
/datum/disease/transformation/proc/replace_banned_player(var/mob/living/new_mob) // This can run well after the mob has been transferred, so need a handle on the new mob to kill it if needed.
|
||||
set waitfor = FALSE
|
||||
|
||||
var/list/mob/dead/observer/candidates = pollCandidatesForMob("Do you want to play as [affected_mob.name]?", bantype, null, bantype, 50, affected_mob)
|
||||
if(LAZYLEN(candidates))
|
||||
var/mob/dead/observer/C = pick(candidates)
|
||||
to_chat(affected_mob, "Your mob has been taken over by a ghost! Appeal your job ban if you want to avoid this in the future!")
|
||||
message_admins("[key_name_admin(C)] has taken control of ([key_name_admin(affected_mob)]) to replace a jobbaned player.")
|
||||
affected_mob.ghostize(0)
|
||||
affected_mob.key = C.key
|
||||
else
|
||||
to_chat(new_mob, "Your mob has been claimed by death! Appeal your job ban if you want to avoid this in the future!")
|
||||
new_mob.death()
|
||||
if (!QDELETED(new_mob))
|
||||
new_mob.ghostize(can_reenter_corpse = FALSE)
|
||||
new_mob.key = null
|
||||
|
||||
/datum/disease/transformation/jungle_fever
|
||||
name = "Jungle Fever"
|
||||
@@ -92,6 +106,8 @@
|
||||
visibility_flags = 0
|
||||
agent = "Kongey Vibrion M-909"
|
||||
new_form = /mob/living/carbon/monkey
|
||||
bantype = ROLE_MONKEY
|
||||
|
||||
|
||||
stage1 = list()
|
||||
stage2 = list()
|
||||
@@ -120,7 +136,7 @@
|
||||
affected_mob.confused += 10
|
||||
if(4)
|
||||
if(prob(3))
|
||||
affected_mob.say(pick("Eeek, ook ook!", "Eee-eeek!", "Eeee!", "Ungh, ungh."))
|
||||
affected_mob.say(pick("Eeek, ook ook!", "Eee-eeek!", "Eeee!", "Ungh, ungh."), forced = "jungle fever")
|
||||
|
||||
/datum/disease/transformation/jungle_fever/cure()
|
||||
remove_monkey(affected_mob.mind)
|
||||
@@ -153,19 +169,20 @@
|
||||
stage5 = list("<span class='danger'>Your skin feels as if it's about to burst off!</span>")
|
||||
new_form = /mob/living/silicon/robot
|
||||
infectable_biotypes = list(MOB_ORGANIC, MOB_UNDEAD, MOB_ROBOTIC)
|
||||
bantype = "Cyborg"
|
||||
|
||||
/datum/disease/transformation/robot/stage_act()
|
||||
..()
|
||||
switch(stage)
|
||||
if(3)
|
||||
if (prob(8))
|
||||
affected_mob.say(pick("Beep, boop", "beep, beep!", "Boop...bop"))
|
||||
affected_mob.say(pick("Beep, boop", "beep, beep!", "Boop...bop"), forced = "robotic transformation")
|
||||
if (prob(4))
|
||||
to_chat(affected_mob, "<span class='danger'>You feel a stabbing pain in your head.</span>")
|
||||
affected_mob.Unconscious(40)
|
||||
if(4)
|
||||
if (prob(20))
|
||||
affected_mob.say(pick("beep, beep!", "Boop bop boop beep.", "kkkiiiill mmme", "I wwwaaannntt tttoo dddiiieeee..."))
|
||||
affected_mob.say(pick("beep, beep!", "Boop bop boop beep.", "kkkiiiill mmme", "I wwwaaannntt tttoo dddiiieeee..."), forced = "robotic transformation")
|
||||
|
||||
|
||||
/datum/disease/transformation/xeno
|
||||
@@ -184,6 +201,7 @@
|
||||
stage4 = list("<span class='danger'>Your skin feels very tight.</span>", "<span class='danger'>Your blood boils!</span>", "<span class='danger'>You can feel... something...inside you.</span>")
|
||||
stage5 = list("<span class='danger'>Your skin feels as if it's about to burst off!</span>")
|
||||
new_form = /mob/living/carbon/alien/humanoid/hunter
|
||||
bantype = ROLE_ALIEN
|
||||
|
||||
/datum/disease/transformation/xeno/stage_act()
|
||||
..()
|
||||
@@ -194,7 +212,7 @@
|
||||
affected_mob.Unconscious(40)
|
||||
if(4)
|
||||
if (prob(20))
|
||||
affected_mob.say(pick("You look delicious.", "Going to... devour you...", "Hsssshhhhh!"))
|
||||
affected_mob.say(pick("You look delicious.", "Going to... devour you...", "Hsssshhhhh!"), forced = "xenomorph transformation")
|
||||
|
||||
|
||||
/datum/disease/transformation/slime
|
||||
@@ -246,10 +264,10 @@
|
||||
switch(stage)
|
||||
if(3)
|
||||
if (prob(8))
|
||||
affected_mob.say(pick("YAP", "Woof!"))
|
||||
affected_mob.say(pick("YAP", "Woof!"), forced = "corgi transformation")
|
||||
if(4)
|
||||
if (prob(20))
|
||||
affected_mob.say(pick("Bark!", "AUUUUUU"))
|
||||
affected_mob.say(pick("Bark!", "AUUUUUU"), forced = "corgi transformation")
|
||||
|
||||
/datum/disease/transformation/morph
|
||||
name = "Gluttony's Blessing"
|
||||
@@ -267,3 +285,43 @@
|
||||
stage5 = list("<span class='danger'>You have become a morph.</span>")
|
||||
new_form = /mob/living/simple_animal/hostile/morph
|
||||
infectable_biotypes = list(MOB_ORGANIC, MOB_INORGANIC, MOB_UNDEAD) //magic!
|
||||
|
||||
/datum/disease/transformation/gondola
|
||||
name = "Gondola Transformation"
|
||||
cure_text = "Condensed Capsaicin, ingested or injected." //getting pepper sprayed doesn't help
|
||||
cures = list("condensedcapsaicin") //beats the hippie crap right out of your system
|
||||
cure_chance = 80
|
||||
stage_prob = 5
|
||||
agent = "Tranquility"
|
||||
desc = "Consuming the flesh of a Gondola comes at a terrible price."
|
||||
severity = DISEASE_SEVERITY_BIOHAZARD
|
||||
visibility_flags = 0
|
||||
stage1 = list("You seem a little lighter in your step.")
|
||||
stage2 = list("You catch yourself smiling for no reason.")
|
||||
stage3 = list("<span class='danger'>A cruel sense of calm overcomes you.</span>", "<span class='danger'>You can't feel your arms!</span>", "<span class='danger'>You let go of the urge to hurt clowns.</span>")
|
||||
stage4 = list("<span class='danger'>You can't feel your arms. It does not bother you anymore.</span>", "<span class='danger'>You forgive the clown for hurting you.</span>")
|
||||
stage5 = list("<span class='danger'>You have become a Gondola.</span>")
|
||||
new_form = /mob/living/simple_animal/pet/gondola
|
||||
|
||||
/datum/disease/transformation/gondola/stage_act()
|
||||
..()
|
||||
switch(stage)
|
||||
if(2)
|
||||
if (prob(5))
|
||||
affected_mob.emote("smile")
|
||||
if (prob(20))
|
||||
affected_mob.reagents.add_reagent_list(list("pax" = 5))
|
||||
if(3)
|
||||
if (prob(5))
|
||||
affected_mob.emote("smile")
|
||||
if (prob(20))
|
||||
affected_mob.reagents.add_reagent_list(list("pax" = 5))
|
||||
if(4)
|
||||
if (prob(5))
|
||||
affected_mob.emote("smile")
|
||||
if (prob(20))
|
||||
affected_mob.reagents.add_reagent_list(list("pax" = 5))
|
||||
if (prob(2))
|
||||
to_chat(affected_mob, "<span class='danger'>You let go of what you were holding.</span>")
|
||||
var/obj/item/I = affected_mob.get_active_held_item()
|
||||
affected_mob.dropItemToGround(I)
|
||||
|
||||
@@ -29,21 +29,21 @@ STI KALY - blind
|
||||
switch(stage)
|
||||
if(2)
|
||||
if(prob(1)&&prob(50))
|
||||
affected_mob.say(pick("You shall not pass!", "Expeliarmus!", "By Merlins beard!", "Feel the power of the Dark Side!"))
|
||||
affected_mob.say(pick("You shall not pass!", "Expeliarmus!", "By Merlins beard!", "Feel the power of the Dark Side!"), forced = "wizarditis")
|
||||
if(prob(1)&&prob(50))
|
||||
to_chat(affected_mob, "<span class='danger'>You feel [pick("that you don't have enough mana", "that the winds of magic are gone", "an urge to summon familiar")].</span>")
|
||||
|
||||
|
||||
if(3)
|
||||
if(prob(1)&&prob(50))
|
||||
affected_mob.say(pick("NEC CANTIO!","AULIE OXIN FIERA!", "STI KALY!", "TARCOL MINTI ZHERI!"))
|
||||
affected_mob.say(pick("NEC CANTIO!","AULIE OXIN FIERA!", "STI KALY!", "TARCOL MINTI ZHERI!"), forced = "wizarditis")
|
||||
if(prob(1)&&prob(50))
|
||||
to_chat(affected_mob, "<span class='danger'>You feel [pick("the magic bubbling in your veins","that this location gives you a +1 to INT","an urge to summon familiar")].</span>")
|
||||
|
||||
if(4)
|
||||
|
||||
if(prob(1))
|
||||
affected_mob.say(pick("NEC CANTIO!","AULIE OXIN FIERA!","STI KALY!","EI NATH!"))
|
||||
affected_mob.say(pick("NEC CANTIO!","AULIE OXIN FIERA!","STI KALY!","EI NATH!"), forced = "wizarditis")
|
||||
return
|
||||
if(prob(1)&&prob(50))
|
||||
to_chat(affected_mob, "<span class='danger'>You feel [pick("the tidal wave of raw power building inside","that this location gives you a +2 to INT and +1 to WIS","an urge to teleport")].</span>")
|
||||
@@ -111,7 +111,7 @@ STI KALY - blind
|
||||
if(!L)
|
||||
return
|
||||
|
||||
affected_mob.say("SCYAR NILA [uppertext(thearea.name)]!")
|
||||
affected_mob.say("SCYAR NILA [uppertext(thearea.name)]!", forced = "wizarditis teleport")
|
||||
affected_mob.forceMove(pick(L))
|
||||
|
||||
return
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
var/list/temporary_mutations = list() //Timers for temporary mutations
|
||||
var/list/previous = list() //For temporary name/ui/ue/blood_type modifications
|
||||
var/mob/living/holder
|
||||
var/delete_species = TRUE //Set to FALSE when a body is scanned by a cloner to fix #38875
|
||||
|
||||
/datum/dna/New(mob/living/new_holder)
|
||||
if(istype(new_holder))
|
||||
@@ -23,6 +24,8 @@
|
||||
if(cholder.dna == src)
|
||||
cholder.dna = null
|
||||
holder = null
|
||||
|
||||
if(delete_species)
|
||||
QDEL_NULL(species)
|
||||
|
||||
mutations.Cut() //This only references mutations, just dereference.
|
||||
@@ -41,12 +44,12 @@
|
||||
destination.dna.features = features.Copy()
|
||||
destination.dna.real_name = real_name
|
||||
destination.dna.temporary_mutations = temporary_mutations.Copy()
|
||||
if(transfer_SE)
|
||||
destination.dna.struc_enzymes = struc_enzymes
|
||||
if(ishuman(destination))
|
||||
var/mob/living/carbon/human/H = destination
|
||||
H.give_genitals(TRUE)//This gives the body the genitals of this DNA. Used for any transformations based on DNA
|
||||
destination.flavor_text = destination.dna.features["flavor_text"] //Update the flavor_text to use new dna text
|
||||
if(transfer_SE)
|
||||
destination.dna.struc_enzymes = struc_enzymes
|
||||
|
||||
/datum/dna/proc/copy_dna(datum/dna/new_dna)
|
||||
new_dna.unique_enzymes = unique_enzymes
|
||||
@@ -209,10 +212,10 @@
|
||||
/datum/dna/proc/initialize_dna(newblood_type)
|
||||
if(newblood_type)
|
||||
blood_type = newblood_type
|
||||
features = random_features()
|
||||
unique_enzymes = generate_unique_enzymes()
|
||||
uni_identity = generate_uni_identity()
|
||||
struc_enzymes = generate_struc_enzymes()
|
||||
features = random_features()
|
||||
|
||||
|
||||
/datum/dna/stored //subtype used by brain mob's stored_dna
|
||||
@@ -245,17 +248,21 @@
|
||||
stored_dna.species = mrace //not calling any species update procs since we're a brain, not a monkey/human
|
||||
|
||||
|
||||
/mob/living/carbon/set_species(datum/species/mrace, icon_update = 1)
|
||||
/mob/living/carbon/set_species(datum/species/mrace, icon_update = TRUE, pref_load = FALSE)
|
||||
if(mrace && has_dna())
|
||||
dna.species.on_species_loss(src)
|
||||
var/old_species = dna.species
|
||||
var/datum/species/new_race
|
||||
if(ispath(mrace))
|
||||
dna.species = new mrace()
|
||||
new_race = new mrace
|
||||
else if(istype(mrace))
|
||||
new_race = mrace
|
||||
else
|
||||
dna.species = mrace
|
||||
dna.species.on_species_gain(src, old_species)
|
||||
return
|
||||
dna.species.on_species_loss(src, new_race, pref_load)
|
||||
var/datum/species/old_species = dna.species
|
||||
dna.species = new_race
|
||||
dna.species.on_species_gain(src, old_species, pref_load)
|
||||
|
||||
/mob/living/carbon/human/set_species(datum/species/mrace, icon_update = 1)
|
||||
/mob/living/carbon/human/set_species(datum/species/mrace, icon_update = TRUE, pref_load = FALSE)
|
||||
..()
|
||||
if(icon_update)
|
||||
update_body()
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
var/emote_type = EMOTE_VISIBLE //Whether the emote is visible or audible
|
||||
var/restraint_check = FALSE //Checks if the mob is restrained before performing the emote
|
||||
var/muzzle_ignore = FALSE //Will only work if the emote is EMOTE_AUDIBLE
|
||||
var/list/mob_type_allowed_typecache = list(/mob) //Types that are allowed to use that emote
|
||||
var/list/mob_type_allowed_typecache = /mob //Types that are allowed to use that emote
|
||||
var/list/mob_type_blacklist_typecache //Types that are NOT allowed to use that emote
|
||||
var/list/mob_type_ignore_stat_typecache
|
||||
var/stat_allowed = CONSCIOUS
|
||||
@@ -25,13 +25,22 @@
|
||||
/datum/emote/New()
|
||||
if(key_third_person)
|
||||
emote_list[key_third_person] = src
|
||||
if (ispath(mob_type_allowed_typecache))
|
||||
switch (mob_type_allowed_typecache)
|
||||
if (/mob)
|
||||
mob_type_allowed_typecache = GLOB.typecache_mob
|
||||
if (/mob/living)
|
||||
mob_type_allowed_typecache = GLOB.typecache_living
|
||||
else
|
||||
mob_type_allowed_typecache = typecacheof(mob_type_allowed_typecache)
|
||||
else
|
||||
mob_type_allowed_typecache = typecacheof(mob_type_allowed_typecache)
|
||||
mob_type_blacklist_typecache = typecacheof(mob_type_blacklist_typecache)
|
||||
mob_type_ignore_stat_typecache = typecacheof(mob_type_ignore_stat_typecache)
|
||||
|
||||
/datum/emote/proc/run_emote(mob/user, params, type_override)
|
||||
/datum/emote/proc/run_emote(mob/user, params, type_override, intentional = FALSE)
|
||||
. = TRUE
|
||||
if(!can_run_emote(user))
|
||||
if(!can_run_emote(user, TRUE, intentional))
|
||||
return FALSE
|
||||
var/msg = select_message_type(user)
|
||||
if(params && message_param)
|
||||
@@ -47,7 +56,7 @@
|
||||
if(!msg)
|
||||
return
|
||||
|
||||
user.log_message(msg, INDIVIDUAL_EMOTE_LOG)
|
||||
user.log_message(msg, LOG_EMOTE)
|
||||
msg = "<b>[user]</b> " + msg
|
||||
|
||||
for(var/mob/M in GLOB.dead_mob_list)
|
||||
@@ -61,7 +70,6 @@
|
||||
user.audible_message(msg)
|
||||
else
|
||||
user.visible_message(msg)
|
||||
log_talk(user,"[key_name(user)] : [msg]",LOGEMOTE)
|
||||
|
||||
/datum/emote/proc/replace_pronoun(mob/user, message)
|
||||
if(findtext(message, "their"))
|
||||
@@ -94,7 +102,7 @@
|
||||
/datum/emote/proc/select_param(mob/user, params)
|
||||
return replacetext(message_param, "%t", params)
|
||||
|
||||
/datum/emote/proc/can_run_emote(mob/user, status_check = TRUE)
|
||||
/datum/emote/proc/can_run_emote(mob/user, status_check = TRUE, intentional = FALSE)
|
||||
. = TRUE
|
||||
if(!is_type_in_typecache(user, mob_type_allowed_typecache))
|
||||
return FALSE
|
||||
@@ -102,9 +110,24 @@
|
||||
return FALSE
|
||||
if(status_check && !is_type_in_typecache(user, mob_type_ignore_stat_typecache))
|
||||
if(user.stat > stat_allowed)
|
||||
to_chat(user, "<span class='notice'>You cannot [key] while unconscious.</span>")
|
||||
if(!intentional)
|
||||
return FALSE
|
||||
switch(user.stat)
|
||||
if(SOFT_CRIT)
|
||||
to_chat(user, "<span class='notice'>You cannot [key] while in a critical condition.</span>")
|
||||
if(UNCONSCIOUS)
|
||||
to_chat(user, "<span class='notice'>You cannot [key] while unconscious.</span>")
|
||||
if(DEAD)
|
||||
to_chat(user, "<span class='notice'>You cannot [key] while dead.</span>")
|
||||
return FALSE
|
||||
if(restraint_check && (user.IsStun() || user.IsKnockdown()))
|
||||
if(!intentional)
|
||||
return FALSE
|
||||
to_chat(user, "<span class='notice'>You cannot [key] while stunned.</span>")
|
||||
return FALSE
|
||||
if(restraint_check && user.restrained())
|
||||
if(!intentional)
|
||||
return FALSE
|
||||
if(restraint_check && (user.restrained() || user.buckled))
|
||||
to_chat(user, "<span class='notice'>You cannot [key] while restrained.</span>")
|
||||
return FALSE
|
||||
|
||||
|
||||
@@ -86,13 +86,13 @@ GLOBAL_LIST_EMPTY(explosions)
|
||||
|
||||
if(adminlog)
|
||||
message_admins("Explosion with size ([devastation_range], [heavy_impact_range], [light_impact_range], [flame_range]) in [ADMIN_VERBOSEJMP(epicenter)]")
|
||||
log_game("Explosion with size ([devastation_range], [heavy_impact_range], [light_impact_range], [flame_range]) in [AREACOORD(epicenter)]")
|
||||
log_game("Explosion with size ([devastation_range], [heavy_impact_range], [light_impact_range], [flame_range]) in [loc_name(epicenter)]")
|
||||
|
||||
var/x0 = epicenter.x
|
||||
var/y0 = epicenter.y
|
||||
var/z0 = epicenter.z
|
||||
var/area/areatype = get_area(epicenter)
|
||||
SSblackbox.record_feedback("associative", "explosion", 1, list("dev" = devastation_range, "heavy" = heavy_impact_range, "light" = light_impact_range, "flash" = flash_range, "flame" = flame_range, "orig_dev" = orig_dev_range, "orig_heavy" = orig_heavy_range, "orig_light" = orig_light_range, "x" = x0, "y" = y0, "z" = z0, "area" = areatype.type))
|
||||
SSblackbox.record_feedback("associative", "explosion", 1, list("dev" = devastation_range, "heavy" = heavy_impact_range, "light" = light_impact_range, "flash" = flash_range, "flame" = flame_range, "orig_dev" = orig_dev_range, "orig_heavy" = orig_heavy_range, "orig_light" = orig_light_range, "x" = x0, "y" = y0, "z" = z0, "area" = areatype.type, "time" = time_stamp("YYYY-MM-DD hh:mm:ss", 1)))
|
||||
|
||||
// Play sounds; we want sounds to be different depending on distance so we will manually do it ourselves.
|
||||
// Stereo users will also hear the direction of the explosion!
|
||||
|
||||
@@ -82,7 +82,7 @@
|
||||
|
||||
. = . && (vic.loc != tar.loc)
|
||||
|
||||
/mob/Collide(atom/A)
|
||||
/mob/Bump(atom/A)
|
||||
. = ..()
|
||||
if(force_moving && force_moving.allow_climbing && isstructure(A))
|
||||
var/obj/structure/S = A
|
||||
|
||||
@@ -7,12 +7,22 @@
|
||||
/datum/getrev/New()
|
||||
testmerge = world.TgsTestMerges()
|
||||
log_world("Running /tg/ revision:")
|
||||
var/datum/tgs_revision_information/revinfo = world.TgsRevision()
|
||||
if(revinfo)
|
||||
commit = revinfo.commit
|
||||
originmastercommit = revinfo.origin_commit
|
||||
else
|
||||
var/list/logs = world.file2list(".git/logs/HEAD")
|
||||
if(logs)
|
||||
if(logs.len)
|
||||
logs = splittext(logs[logs.len - 1], " ")
|
||||
date = unix2date(text2num(logs[5]))
|
||||
commit = logs[2]
|
||||
log_world("[commit]: [date]")
|
||||
else
|
||||
log_world("Unable to read git logs, revision information not available")
|
||||
originmastercommit = commit = "Unknown"
|
||||
date = unix2date(world.timeofday)
|
||||
return
|
||||
logs = world.file2list(".git/logs/refs/remotes/origin/master")
|
||||
if(logs.len)
|
||||
originmastercommit = splittext(logs[logs.len - 1], " ")[2]
|
||||
@@ -67,17 +77,17 @@
|
||||
to_chat(src, "Protect Assistant Role From Traitor: [CONFIG_GET(flag/protect_assistant_from_antagonist)]")
|
||||
to_chat(src, "Enforce Human Authority: [CONFIG_GET(flag/enforce_human_authority)]")
|
||||
to_chat(src, "Allow Latejoin Antagonists: [CONFIG_GET(flag/allow_latejoin_antagonists)]")
|
||||
to_chat(src, "Enforce Continuous Rounds: [length(CONFIG_GET(keyed_flag_list/continuous))] of [config.modes.len] roundtypes")
|
||||
to_chat(src, "Allow Midround Antagonists: [length(CONFIG_GET(keyed_flag_list/midround_antag))] of [config.modes.len] roundtypes")
|
||||
to_chat(src, "Enforce Continuous Rounds: [length(CONFIG_GET(keyed_list/continuous))] of [config.modes.len] roundtypes")
|
||||
to_chat(src, "Allow Midround Antagonists: [length(CONFIG_GET(keyed_list/midround_antag))] of [config.modes.len] roundtypes")
|
||||
if(CONFIG_GET(flag/show_game_type_odds))
|
||||
var/list/probabilities = CONFIG_GET(keyed_number_list/probability)
|
||||
var/list/probabilities = CONFIG_GET(keyed_list/probability)
|
||||
if(SSticker.IsRoundInProgress())
|
||||
var/prob_sum = 0
|
||||
var/current_odds_differ = FALSE
|
||||
var/list/probs = list()
|
||||
var/list/modes = config.gamemode_cache
|
||||
var/list/min_pop = CONFIG_GET(keyed_number_list/min_pop)
|
||||
var/list/max_pop = CONFIG_GET(keyed_number_list/max_pop)
|
||||
var/list/min_pop = CONFIG_GET(keyed_list/min_pop)
|
||||
var/list/max_pop = CONFIG_GET(keyed_list/max_pop)
|
||||
for(var/mode in modes)
|
||||
var/datum/game_mode/M = mode
|
||||
var/ctag = initial(M.config_tag)
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
tele_play_specials(teleatom, curturf, effectin, asoundin)
|
||||
var/success = force_teleport ? teleatom.forceMove(destturf) : teleatom.Move(destturf)
|
||||
if (success)
|
||||
log_game("[teleatom] ([key_name(teleatom)]) has teleported from [AREACOORD(curturf)] to [AREACOORD(destturf)]")
|
||||
log_game("[key_name(teleatom)] has teleported from [loc_name(curturf)] to [loc_name(destturf)]")
|
||||
tele_play_specials(teleatom, destturf, effectout, asoundout)
|
||||
if(ismegafauna(teleatom))
|
||||
message_admins("[teleatom] [ADMIN_FLW(teleatom)] has teleported from [ADMIN_VERBOSEJMP(curturf)] to [ADMIN_VERBOSEJMP(destturf)].")
|
||||
@@ -60,6 +60,8 @@
|
||||
var/mob/M = teleatom
|
||||
M.cancel_camera()
|
||||
|
||||
return TRUE
|
||||
|
||||
/proc/tele_play_specials(atom/movable/teleatom, atom/location, datum/effect_system/effect, sound)
|
||||
if (location && !isobserver(teleatom))
|
||||
if (sound)
|
||||
|
||||
@@ -60,7 +60,6 @@
|
||||
user.remote_control = null
|
||||
|
||||
if(!QDELETED(eye))
|
||||
eye.RemoveImages()
|
||||
QDEL_NULL(eye)
|
||||
|
||||
if(connected_holopad && !QDELETED(hologram))
|
||||
|
||||
@@ -12,7 +12,7 @@ GLOBAL_LIST_INIT(huds, list(
|
||||
DATA_HUD_DIAGNOSTIC_ADVANCED = new/datum/atom_hud/data/diagnostic/advanced(),
|
||||
DATA_HUD_ABDUCTOR = new/datum/atom_hud/abductor(),
|
||||
DATA_HUD_SENTIENT_DISEASE = new/datum/atom_hud/sentient_disease(),
|
||||
DATA_HUD_AI_DETECT = new/datum/atom_hud(), //CIT - EMPTY PLACEHOLDER UNTIL SYNC
|
||||
DATA_HUD_AI_DETECT = new/datum/atom_hud/ai_detector(),
|
||||
ANTAG_HUD_CULT = new/datum/atom_hud/antag(),
|
||||
ANTAG_HUD_REV = new/datum/atom_hud/antag(),
|
||||
ANTAG_HUD_OPS = new/datum/atom_hud/antag(),
|
||||
@@ -26,7 +26,7 @@ GLOBAL_LIST_INIT(huds, list(
|
||||
ANTAG_HUD_SINTOUCHED = new/datum/atom_hud/antag/hidden(),
|
||||
ANTAG_HUD_SOULLESS = new/datum/atom_hud/antag/hidden(),
|
||||
ANTAG_HUD_CLOCKWORK = new/datum/atom_hud/antag(),
|
||||
ANTAG_HUD_BROTHER = new/datum/atom_hud/antag/hidden()
|
||||
ANTAG_HUD_BROTHER = new/datum/atom_hud/antag/hidden(),
|
||||
))
|
||||
|
||||
/datum/atom_hud
|
||||
@@ -101,6 +101,7 @@ GLOBAL_LIST_INIT(huds, list(
|
||||
return FALSE
|
||||
hudatoms |= A
|
||||
for(var/mob/M in hudusers)
|
||||
if(!queued_to_see[M])
|
||||
add_to_single_hud(M, A)
|
||||
return TRUE
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
volume = 25
|
||||
var/last_radiation
|
||||
|
||||
/datum/looping_sound/geiger/get_sound(looped)
|
||||
/datum/looping_sound/geiger/get_sound(starttime)
|
||||
var/danger
|
||||
switch(last_radiation)
|
||||
if(RAD_BACKGROUND_RADIATION to RAD_GEIGER_LOW)
|
||||
@@ -26,7 +26,7 @@
|
||||
danger = 4
|
||||
else
|
||||
return null
|
||||
return ..(looped, mid_sounds[danger])
|
||||
return ..(starttime, mid_sounds[danger])
|
||||
|
||||
/datum/looping_sound/geiger/stop()
|
||||
. = ..()
|
||||
@@ -41,11 +41,6 @@
|
||||
mid_length = 3.5
|
||||
volume = 25
|
||||
|
||||
/datum/looping_sound/reverse_bear_trap/slow
|
||||
mid_sounds = list('sound/effects/clock_tick.ogg')
|
||||
mid_length = 10
|
||||
volume = 40
|
||||
|
||||
|
||||
/datum/looping_sound/reverse_bear_trap_beep
|
||||
mid_sounds = list('sound/machines/beep.ogg')
|
||||
|
||||
@@ -24,10 +24,11 @@
|
||||
var/end_sound
|
||||
var/chance
|
||||
var/volume = 100
|
||||
var/muted = TRUE
|
||||
var/max_loops
|
||||
var/direct
|
||||
|
||||
var/timerid
|
||||
|
||||
/datum/looping_sound/New(list/_output_atoms=list(), start_immediately=FALSE, _direct=FALSE)
|
||||
if(!mid_sounds)
|
||||
WARNING("A looping sound datum was created without sounds to play.")
|
||||
@@ -47,25 +48,27 @@
|
||||
/datum/looping_sound/proc/start(atom/add_thing)
|
||||
if(add_thing)
|
||||
output_atoms |= add_thing
|
||||
if(!muted)
|
||||
if(timerid)
|
||||
return
|
||||
muted = FALSE
|
||||
on_start()
|
||||
|
||||
/datum/looping_sound/proc/stop(atom/remove_thing)
|
||||
if(remove_thing)
|
||||
output_atoms -= remove_thing
|
||||
if(muted)
|
||||
if(!timerid)
|
||||
return
|
||||
muted = TRUE
|
||||
on_stop()
|
||||
deltimer(timerid)
|
||||
timerid = null
|
||||
|
||||
/datum/looping_sound/proc/sound_loop(looped=0)
|
||||
if(muted || (max_loops && looped > max_loops))
|
||||
on_stop(looped)
|
||||
/datum/looping_sound/proc/sound_loop(starttime)
|
||||
if(max_loops && world.time >= starttime + mid_length * max_loops)
|
||||
stop()
|
||||
return
|
||||
if(!chance || prob(chance))
|
||||
play(get_sound(looped))
|
||||
addtimer(CALLBACK(src, .proc/sound_loop, ++looped), mid_length)
|
||||
play(get_sound(starttime))
|
||||
if(!timerid)
|
||||
timerid = addtimer(CALLBACK(src, .proc/sound_loop, world.time), mid_length, TIMER_STOPPABLE | TIMER_LOOP)
|
||||
|
||||
/datum/looping_sound/proc/play(soundfile)
|
||||
var/list/atoms_cache = output_atoms
|
||||
@@ -80,7 +83,7 @@
|
||||
else
|
||||
playsound(thing, S, volume)
|
||||
|
||||
/datum/looping_sound/proc/get_sound(looped, _mid_sounds)
|
||||
/datum/looping_sound/proc/get_sound(starttime, _mid_sounds)
|
||||
if(!_mid_sounds)
|
||||
. = mid_sounds
|
||||
else
|
||||
@@ -95,6 +98,6 @@
|
||||
start_wait = start_length
|
||||
addtimer(CALLBACK(src, .proc/sound_loop), start_wait)
|
||||
|
||||
/datum/looping_sound/proc/on_stop(looped)
|
||||
/datum/looping_sound/proc/on_stop()
|
||||
if(end_sound)
|
||||
play(end_sound)
|
||||
@@ -55,7 +55,7 @@
|
||||
playsound(D.loc, A.dna.species.miss_sound, 25, 1, -1)
|
||||
D.visible_message("<span class='warning'>[A] has attempted to [atk_verb] [D]!</span>", \
|
||||
"<span class='userdanger'>[A] has attempted to [atk_verb] [D]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
add_logs(A, D, "attempted to [atk_verb]")
|
||||
log_combat(A, D, "attempted to [atk_verb]")
|
||||
return 0
|
||||
|
||||
var/obj/item/bodypart/affecting = D.get_bodypart(ran_zone(A.zone_selected))
|
||||
@@ -67,7 +67,7 @@
|
||||
|
||||
D.apply_damage(damage, BRUTE, affecting, armor_block)
|
||||
|
||||
add_logs(A, D, "punched")
|
||||
log_combat(A, D, "punched")
|
||||
|
||||
if((D.stat != DEAD) && damage >= A.dna.species.punchstunthreshold)
|
||||
D.visible_message("<span class='danger'>[A] has knocked [D] down!!</span>", \
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
playsound(D.loc, A.dna.species.miss_sound, 25, 1, -1)
|
||||
D.visible_message("<span class='warning'>[A] has attempted to [atk_verb] [D]!</span>", \
|
||||
"<span class='userdanger'>[A] has attempted to [atk_verb] [D]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
add_logs(A, D, "attempted to hit", atk_verb)
|
||||
log_combat(A, D, "attempted to hit", atk_verb)
|
||||
return 0
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
"<span class='userdanger'>[A] has [atk_verb]ed [D]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
|
||||
D.apply_damage(damage, STAMINA, affecting, armor_block)
|
||||
add_logs(A, D, "punched (boxing) ")
|
||||
log_combat(A, D, "punched (boxing) ")
|
||||
if(D.getStaminaLoss() > 100)
|
||||
var/knockout_prob = (D.getStaminaLoss() + rand(-15,15))*0.75
|
||||
if((D.stat != DEAD) && prob(knockout_prob))
|
||||
@@ -42,7 +42,7 @@
|
||||
D.apply_effect(200,EFFECT_KNOCKDOWN,armor_block)
|
||||
D.SetSleeping(100)
|
||||
D.forcesay(GLOB.hit_appends)
|
||||
add_logs(A, D, "knocked out (boxing) ")
|
||||
log_combat(A, D, "knocked out (boxing) ")
|
||||
else if(D.lying)
|
||||
D.forcesay(GLOB.hit_appends)
|
||||
return 1
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
playsound(get_turf(A), 'sound/weapons/slam.ogg', 50, 1, -1)
|
||||
D.apply_damage(10, BRUTE)
|
||||
D.Knockdown(120)
|
||||
add_logs(A, D, "cqc slammed")
|
||||
log_combat(A, D, "slammed (CQC)")
|
||||
return TRUE
|
||||
|
||||
/datum/martial_art/cqc/proc/Kick(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
@@ -72,7 +72,7 @@
|
||||
var/atom/throw_target = get_edge_target_turf(D, A.dir)
|
||||
D.throw_at(throw_target, 1, 14, A)
|
||||
D.apply_damage(10, BRUTE)
|
||||
add_logs(A, D, "cqc kicked")
|
||||
log_combat(A, D, "kicked (CQC)")
|
||||
if(D.IsKnockdown() && !D.stat)
|
||||
D.visible_message("<span class='warning'>[A] kicks [D]'s head, knocking [D.p_them()] out!</span>", \
|
||||
"<span class='userdanger'>[A] kicks your head, knocking you out!</span>")
|
||||
@@ -129,7 +129,7 @@
|
||||
A.start_pulling(D, 1)
|
||||
if(A.pulling)
|
||||
D.stop_pulling()
|
||||
add_logs(A, D, "grabbed", addition="aggressively")
|
||||
log_combat(A, D, "grabbed", addition="aggressively")
|
||||
A.grab_state = GRAB_AGGRESSIVE //Instant aggressive grab
|
||||
|
||||
return TRUE
|
||||
@@ -140,7 +140,7 @@
|
||||
add_to_streak("H",D)
|
||||
if(check_streak(A,D))
|
||||
return TRUE
|
||||
add_logs(A, D, "CQC'd")
|
||||
log_combat(A, D, "attacked (CQC)")
|
||||
A.do_attack_animation(D)
|
||||
var/picked_hit_type = pick("CQC'd", "Big Bossed")
|
||||
var/bonus_damage = 13
|
||||
@@ -154,14 +154,14 @@
|
||||
playsound(get_turf(D), 'sound/weapons/cqchit1.ogg', 50, 1, -1)
|
||||
D.visible_message("<span class='danger'>[A] [picked_hit_type] [D]!</span>", \
|
||||
"<span class='userdanger'>[A] [picked_hit_type] you!</span>")
|
||||
add_logs(A, D, "[picked_hit_type] with CQC")
|
||||
log_combat(A, D, "[picked_hit_type] (CQC)")
|
||||
if(A.resting && !D.stat && !D.IsKnockdown())
|
||||
D.visible_message("<span class='warning'>[A] leg sweeps [D]!", \
|
||||
"<span class='userdanger'>[A] leg sweeps you!</span>")
|
||||
playsound(get_turf(A), 'sound/effects/hit_kick.ogg', 50, 1, -1)
|
||||
D.apply_damage(10, BRUTE)
|
||||
D.Knockdown(60)
|
||||
add_logs(A, D, "cqc sweeped")
|
||||
log_combat(A, D, "sweeped (CQC)")
|
||||
return TRUE
|
||||
|
||||
/datum/martial_art/cqc/disarm_act(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
@@ -185,7 +185,7 @@
|
||||
D.visible_message("<span class='danger'>[A] attempted to disarm [D]!</span>", \
|
||||
"<span class='userdanger'>[A] attempted to disarm [D]!</span>")
|
||||
playsound(D, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
|
||||
add_logs(A, D, "disarmed with CQC", "[I ? " grabbing \the [I]" : ""]")
|
||||
log_combat(A, D, "disarmed (CQC)", "[I ? " grabbing \the [I]" : ""]")
|
||||
if(restraining && A.pulling == D)
|
||||
D.visible_message("<span class='danger'>[A] puts [D] into a chokehold!</span>", \
|
||||
"<span class='userdanger'>[A] puts you into a chokehold!</span>")
|
||||
|
||||
@@ -93,7 +93,7 @@
|
||||
playsound(get_turf(A), 'sound/effects/hit_kick.ogg', 50, 1, -1)
|
||||
D.apply_damage(5, BRUTE)
|
||||
D.Knockdown(40)
|
||||
add_logs(A, D, "leg sweeped")
|
||||
log_combat(A, D, "leg sweeped")
|
||||
return 1
|
||||
|
||||
/datum/martial_art/krav_maga/proc/quick_choke(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D)//is actually lung punch
|
||||
@@ -103,7 +103,7 @@
|
||||
if(D.losebreath <= 10)
|
||||
D.losebreath = CLAMP(D.losebreath + 5, 0, 10)
|
||||
D.adjustOxyLoss(10)
|
||||
add_logs(A, D, "quickchoked")
|
||||
log_combat(A, D, "quickchoked")
|
||||
return 1
|
||||
|
||||
/datum/martial_art/krav_maga/proc/neck_chop(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D)
|
||||
@@ -113,19 +113,19 @@
|
||||
D.apply_damage(5, BRUTE)
|
||||
if(D.silent <= 10)
|
||||
D.silent = CLAMP(D.silent + 10, 0, 10)
|
||||
add_logs(A, D, "neck chopped")
|
||||
log_combat(A, D, "neck chopped")
|
||||
return 1
|
||||
|
||||
/datum/martial_art/krav_maga/grab_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D)
|
||||
if(check_streak(A,D))
|
||||
return 1
|
||||
add_logs(A, D, "grabbed with krav maga")
|
||||
log_combat(A, D, "grabbed (Krav Maga)")
|
||||
..()
|
||||
|
||||
/datum/martial_art/krav_maga/harm_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D)
|
||||
if(check_streak(A,D))
|
||||
return 1
|
||||
add_logs(A, D, "punched")
|
||||
log_combat(A, D, "punched")
|
||||
var/picked_hit_type = pick("punches", "kicks")
|
||||
var/bonus_damage = 10
|
||||
if(D.IsKnockdown() || D.resting || D.lying)
|
||||
@@ -140,7 +140,7 @@
|
||||
playsound(get_turf(D), 'sound/effects/hit_punch.ogg', 50, 1, -1)
|
||||
D.visible_message("<span class='danger'>[A] [picked_hit_type] [D]!</span>", \
|
||||
"<span class='userdanger'>[A] [picked_hit_type] you!</span>")
|
||||
add_logs(A, D, "[picked_hit_type] with [name]")
|
||||
log_combat(A, D, "[picked_hit_type] with [name]")
|
||||
return 1
|
||||
|
||||
/datum/martial_art/krav_maga/disarm_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D)
|
||||
@@ -159,7 +159,7 @@
|
||||
D.visible_message("<span class='danger'>[A] attempted to disarm [D]!</span>", \
|
||||
"<span class='userdanger'>[A] attempted to disarm [D]!</span>")
|
||||
playsound(D, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
|
||||
add_logs(A, D, "disarmed with krav maga", "[I ? " removing \the [I]" : ""]")
|
||||
log_combat(A, D, "disarmed (Krav Maga)", "[I ? " removing \the [I]" : ""]")
|
||||
return 1
|
||||
|
||||
//Krav Maga Gloves
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
D.throw_at(throwtarget, 4, 2, A)//So stuff gets tossed around at the same time.
|
||||
D.Knockdown(20)
|
||||
if(atk_verb)
|
||||
add_logs(A, D, "[atk_verb] (Mushroom Punch)")
|
||||
log_combat(A, D, "[atk_verb] (Mushroom Punch)")
|
||||
return TRUE
|
||||
|
||||
/obj/item/mushpunch
|
||||
|
||||
@@ -32,14 +32,14 @@
|
||||
sleep(1)
|
||||
|
||||
/datum/martial_art/plasma_fist/proc/Tornado(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
A.say("TORNADO SWEEP!")
|
||||
A.say("TORNADO SWEEP!", forced="plasma fist")
|
||||
TornadoAnimate(A)
|
||||
var/obj/effect/proc_holder/spell/aoe_turf/repulse/R = new(null)
|
||||
var/list/turfs = list()
|
||||
for(var/turf/T in range(1,A))
|
||||
turfs.Add(T)
|
||||
R.cast(turfs)
|
||||
add_logs(A, D, "tornado sweeped(Plasma Fist)")
|
||||
log_combat(A, D, "tornado sweeped(Plasma Fist)")
|
||||
return
|
||||
|
||||
/datum/martial_art/plasma_fist/proc/Throwback(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
@@ -48,18 +48,18 @@
|
||||
playsound(D.loc, 'sound/weapons/punch1.ogg', 50, 1, -1)
|
||||
var/atom/throw_target = get_edge_target_turf(D, get_dir(D, get_step_away(D, A)))
|
||||
D.throw_at(throw_target, 200, 4,A)
|
||||
A.say("HYAH!")
|
||||
add_logs(A, D, "threw back (Plasma Fist)")
|
||||
A.say("HYAH!", forced="plasma fist")
|
||||
log_combat(A, D, "threw back (Plasma Fist)")
|
||||
return
|
||||
|
||||
/datum/martial_art/plasma_fist/proc/Plasma(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
A.do_attack_animation(D, ATTACK_EFFECT_PUNCH)
|
||||
playsound(D.loc, 'sound/weapons/punch1.ogg', 50, 1, -1)
|
||||
A.say("PLASMA FIST!")
|
||||
A.say("PLASMA FIST!", forced="plasma fist")
|
||||
D.visible_message("<span class='danger'>[A] has hit [D] with THE PLASMA FIST TECHNIQUE!</span>", \
|
||||
"<span class='userdanger'>[A] has hit [D] with THE PLASMA FIST TECHNIQUE!</span>")
|
||||
D.gib()
|
||||
add_logs(A, D, "gibbed (Plasma Fist)")
|
||||
log_combat(A, D, "gibbed (Plasma Fist)")
|
||||
return
|
||||
|
||||
/datum/martial_art/plasma_fist/harm_act(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
|
||||
@@ -29,12 +29,12 @@
|
||||
D.drop_all_held_items()
|
||||
D.stop_pulling()
|
||||
if(A.a_intent == INTENT_GRAB)
|
||||
add_logs(A, D, "grabbed", addition="aggressively")
|
||||
log_combat(A, D, "grabbed", addition="aggressively")
|
||||
D.visible_message("<span class='warning'>[A] violently grabs [D]!</span>", \
|
||||
"<span class='userdanger'>[A] violently grabs you!</span>")
|
||||
A.grab_state = GRAB_AGGRESSIVE //Instant aggressive grab
|
||||
else
|
||||
add_logs(A, D, "grabbed", addition="passively")
|
||||
log_combat(A, D, "grabbed", addition="passively")
|
||||
A.grab_state = GRAB_PASSIVE
|
||||
if(4)
|
||||
A.do_attack_animation(D, ATTACK_EFFECT_PUNCH)
|
||||
@@ -62,5 +62,5 @@
|
||||
basic_hit(A,D)
|
||||
|
||||
if(atk_verb)
|
||||
add_logs(A, D, "[atk_verb] (Psychotic Brawling)")
|
||||
log_combat(A, D, "[atk_verb] (Psychotic Brawling)")
|
||||
return 1
|
||||
@@ -45,7 +45,7 @@
|
||||
D.apply_damage(5, BRUTE, pick(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM))
|
||||
D.Knockdown(60)//CIT CHANGE - makes sleepingcarp use knockdown() for its stuns instead of stun()
|
||||
return 1
|
||||
add_logs(A, D, "wrist wrenched (Sleeping Carp)")
|
||||
log_combat(A, D, "wrist wrenched (Sleeping Carp)")
|
||||
return basic_hit(A,D)
|
||||
|
||||
/datum/martial_art/the_sleeping_carp/proc/backKick(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
@@ -57,7 +57,7 @@
|
||||
D.Knockdown(80)
|
||||
playsound(get_turf(D), 'sound/weapons/punch1.ogg', 50, 1, -1)
|
||||
return 1
|
||||
add_logs(A, D, "back-kicked (Sleeping Carp)")
|
||||
log_combat(A, D, "back-kicked (Sleeping Carp)")
|
||||
return basic_hit(A,D)
|
||||
|
||||
/datum/martial_art/the_sleeping_carp/proc/kneeStomach(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
@@ -70,7 +70,7 @@
|
||||
D.Knockdown(40)//CIT CHANGE - makes sleepingcarp use knockdown() for its stuns instead of stun()
|
||||
playsound(get_turf(D), 'sound/weapons/punch1.ogg', 50, 1, -1)
|
||||
return 1
|
||||
add_logs(A, D, "stomach kneed (Sleeping Carp)")
|
||||
log_combat(A, D, "stomach kneed (Sleeping Carp)")
|
||||
return basic_hit(A,D)
|
||||
|
||||
/datum/martial_art/the_sleeping_carp/proc/headKick(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
@@ -83,7 +83,7 @@
|
||||
playsound(get_turf(D), 'sound/weapons/punch1.ogg', 50, 1, -1)
|
||||
D.Knockdown(80)//CIT CHANGE - makes sleepingcarp use knockdown() for its stuns instead of stun()
|
||||
return 1
|
||||
add_logs(A, D, "head kicked (Sleeping Carp)")
|
||||
log_combat(A, D, "head kicked (Sleeping Carp)")
|
||||
return basic_hit(A,D)
|
||||
|
||||
/datum/martial_art/the_sleeping_carp/proc/elbowDrop(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
@@ -96,7 +96,7 @@
|
||||
D.apply_damage(50, BRUTE, BODY_ZONE_CHEST)
|
||||
playsound(get_turf(D), 'sound/weapons/punch1.ogg', 75, 1, -1)
|
||||
return 1
|
||||
add_logs(A, D, "elbow dropped (Sleeping Carp)")
|
||||
log_combat(A, D, "elbow dropped (Sleeping Carp)")
|
||||
return basic_hit(A,D)
|
||||
|
||||
/datum/martial_art/the_sleeping_carp/grab_act(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
@@ -111,12 +111,12 @@
|
||||
D.drop_all_held_items()
|
||||
D.stop_pulling()
|
||||
if(A.a_intent == INTENT_GRAB)
|
||||
add_logs(A, D, "grabbed", addition="aggressively")
|
||||
log_combat(A, D, "grabbed", addition="aggressively")
|
||||
D.visible_message("<span class='warning'>[A] violently grabs [D]!</span>", \
|
||||
"<span class='userdanger'>[A] violently grabs you!</span>")
|
||||
A.grab_state = GRAB_AGGRESSIVE //Instant aggressive grab
|
||||
else
|
||||
add_logs(A, D, "grabbed", addition="passively")
|
||||
log_combat(A, D, "grabbed", addition="passively")
|
||||
A.grab_state = GRAB_PASSIVE
|
||||
return 1
|
||||
|
||||
@@ -133,7 +133,7 @@
|
||||
if(prob(D.getBruteLoss()) && !D.lying)
|
||||
D.visible_message("<span class='warning'>[D] stumbles and falls!</span>", "<span class='userdanger'>The blow sends you to the ground!</span>")
|
||||
D.Knockdown(80)
|
||||
add_logs(A, D, "[atk_verb] (Sleeping Carp)")
|
||||
log_combat(A, D, "[atk_verb] (Sleeping Carp)")
|
||||
return 1
|
||||
|
||||
|
||||
|
||||
@@ -121,7 +121,7 @@
|
||||
/datum/martial_art/wrestling/harm_act(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
if(check_streak(A,D))
|
||||
return 1
|
||||
add_logs(A, D, "punched with wrestling")
|
||||
log_combat(A, D, "punched with wrestling")
|
||||
..()
|
||||
|
||||
/datum/martial_art/wrestling/proc/throw_wrassle(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
@@ -192,7 +192,7 @@
|
||||
if (!D.stat)
|
||||
D.emote("scream")
|
||||
D.throw_at(T, 10, 4, A, TRUE, TRUE, callback = CALLBACK(D, /mob/living/carbon/human/.Knockdown, 20))
|
||||
add_logs(A, D, "has thrown with wrestling")
|
||||
log_combat(A, D, "has thrown with wrestling")
|
||||
return 0
|
||||
|
||||
/datum/martial_art/wrestling/proc/FlipAnimation(mob/living/carbon/human/D)
|
||||
@@ -308,7 +308,7 @@
|
||||
D.pixel_y = 0
|
||||
|
||||
|
||||
add_logs(A, D, "body-slammed")
|
||||
log_combat(A, D, "body-slammed")
|
||||
return 0
|
||||
|
||||
/datum/martial_art/wrestling/proc/CheckStrikeTurf(mob/living/carbon/human/A, turf/T)
|
||||
@@ -330,7 +330,7 @@
|
||||
D.adjustBruteLoss(rand(10,20))
|
||||
playsound(A.loc, "swing_hit", 50, 1)
|
||||
D.Unconscious(20)
|
||||
add_logs(A, D, "headbutted")
|
||||
log_combat(A, D, "headbutted")
|
||||
|
||||
/datum/martial_art/wrestling/proc/kick(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
if(!D)
|
||||
@@ -347,7 +347,7 @@
|
||||
if (T && isturf(T))
|
||||
D.Knockdown(20)
|
||||
D.throw_at(T, 3, 2)
|
||||
add_logs(A, D, "roundhouse-kicked")
|
||||
log_combat(A, D, "roundhouse-kicked")
|
||||
|
||||
/datum/martial_art/wrestling/proc/drop(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
if(!D)
|
||||
@@ -420,13 +420,13 @@
|
||||
else
|
||||
if (A)
|
||||
A.pixel_y = 0
|
||||
add_logs(A, D, "leg-dropped")
|
||||
log_combat(A, D, "leg-dropped")
|
||||
return
|
||||
|
||||
/datum/martial_art/wrestling/disarm_act(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
if(check_streak(A,D))
|
||||
return 1
|
||||
add_logs(A, D, "wrestling-disarmed")
|
||||
log_combat(A, D, "wrestling-disarmed")
|
||||
..()
|
||||
|
||||
/datum/martial_art/wrestling/grab_act(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
@@ -438,7 +438,7 @@
|
||||
D.visible_message("<span class='danger'>[A] gets [D] in a cinch!</span>", \
|
||||
"<span class='userdanger'>[A] gets [D] in a cinch!</span>")
|
||||
D.Stun(rand(60,100))
|
||||
add_logs(A, D, "cinched")
|
||||
log_combat(A, D, "cinched")
|
||||
return 1
|
||||
|
||||
/obj/item/storage/belt/champion/wrestling
|
||||
|
||||
@@ -62,6 +62,8 @@
|
||||
var/unconvertable = FALSE
|
||||
var/late_joiner = FALSE
|
||||
|
||||
var/force_escaped = FALSE // Set by Into The Sunset command of the shuttle manipulator
|
||||
|
||||
/datum/mind/New(var/key)
|
||||
src.key = key
|
||||
soulOwner = src
|
||||
@@ -254,7 +256,6 @@
|
||||
var/mob/living/carbon/human/traitor_mob = current
|
||||
if (!istype(traitor_mob))
|
||||
return
|
||||
. = TRUE
|
||||
|
||||
var/list/all_contents = traitor_mob.GetAllContents()
|
||||
var/obj/item/pda/PDA = locate() in all_contents
|
||||
@@ -302,6 +303,7 @@
|
||||
to_chat(traitor_mob, "Unfortunately, [employer] wasn't able to get you an Uplink.")
|
||||
. = 0
|
||||
else
|
||||
. = uplink_loc
|
||||
uplink_loc.AddComponent(/datum/component/uplink, traitor_mob.key)
|
||||
var/unlock_note
|
||||
|
||||
@@ -700,7 +702,7 @@
|
||||
if(!has_antag_datum(/datum/antagonist/cult,TRUE))
|
||||
SSticker.mode.add_cultist(src,FALSE,equip=TRUE)
|
||||
special_role = 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 your 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>You catch a glimpse of the Realm of Nar'Sie, The Geometer of Blood. You now see how flimsy your 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 brethren 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>")
|
||||
|
||||
/datum/mind/proc/make_Rev()
|
||||
|
||||
24
code/datums/mood_events/drink_events.dm
Normal file
24
code/datums/mood_events/drink_events.dm
Normal file
@@ -0,0 +1,24 @@
|
||||
/datum/mood_event/drunk
|
||||
mood_change = 3
|
||||
description = "<span class='nicegreen'>Everything just feels better after a drink or two.</span>\n"
|
||||
timeout = 3000
|
||||
|
||||
/datum/mood_event/quality_nice
|
||||
description = "<span class='nicegreen'>That drink wasn't bad at all.</span>\n"
|
||||
mood_change = 1
|
||||
timeout = 1200
|
||||
|
||||
/datum/mood_event/quality_good
|
||||
description = "<span class='nicegreen'>That drink was pretty good.</span>\n"
|
||||
mood_change = 2
|
||||
timeout = 1200
|
||||
|
||||
/datum/mood_event/quality_verygood
|
||||
description = "<span class='nicegreen'>That drink was great!</span>\n"
|
||||
mood_change = 3
|
||||
timeout = 1200
|
||||
|
||||
/datum/mood_event/quality_fantastic
|
||||
description = "<span class='nicegreen'>That drink was amazing!</span>\n"
|
||||
mood_change = 4
|
||||
timeout = 1200
|
||||
@@ -1,39 +1,39 @@
|
||||
/datum/mood_event/drugs/high
|
||||
/datum/mood_event/high
|
||||
mood_change = 6
|
||||
description = "<span class='nicegreen'>Woooow duudeeeeee...I'm tripping baaalls...</span>\n"
|
||||
|
||||
/datum/mood_event/drugs/smoked
|
||||
/datum/mood_event/smoked
|
||||
description = "<span class='nicegreen'>I have had a smoke recently.</span>\n"
|
||||
mood_change = 2
|
||||
timeout = 3600
|
||||
|
||||
/datum/mood_event/drugs/overdose
|
||||
/datum/mood_event/overdose
|
||||
mood_change = -8
|
||||
timeout = 3000
|
||||
|
||||
/datum/mood_event/drugs/overdose/add_effects(drug_name)
|
||||
/datum/mood_event/overdose/add_effects(drug_name)
|
||||
description = "<span class='warning'>I think I took a bit too much of that [drug_name]</span>\n"
|
||||
|
||||
/datum/mood_event/drugs/withdrawal_light
|
||||
/datum/mood_event/withdrawal_light
|
||||
mood_change = -2
|
||||
|
||||
/datum/mood_event/drugs/withdrawal_light/add_effects(drug_name)
|
||||
/datum/mood_event/withdrawal_light/add_effects(drug_name)
|
||||
description = "<span class='warning'>I could use some [drug_name]</span>\n"
|
||||
|
||||
/datum/mood_event/drugs/withdrawal_medium
|
||||
/datum/mood_event/withdrawal_medium
|
||||
mood_change = -5
|
||||
|
||||
/datum/mood_event/drugs/withdrawal_medium/add_effects(drug_name)
|
||||
/datum/mood_event/withdrawal_medium/add_effects(drug_name)
|
||||
description = "<span class='warning'>I really need [drug_name]</span>\n"
|
||||
|
||||
/datum/mood_event/drugs/withdrawal_severe
|
||||
/datum/mood_event/withdrawal_severe
|
||||
mood_change = -8
|
||||
|
||||
/datum/mood_event/drugs/withdrawal_severe/add_effects(drug_name)
|
||||
/datum/mood_event/withdrawal_severe/add_effects(drug_name)
|
||||
description = "<span class='boldwarning'>Oh god I need some [drug_name]</span>\n"
|
||||
|
||||
/datum/mood_event/drugs/withdrawal_critical
|
||||
/datum/mood_event/withdrawal_critical
|
||||
mood_change = -10
|
||||
|
||||
/datum/mood_event/drugs/withdrawal_critical/add_effects(drug_name)
|
||||
/datum/mood_event/withdrawal_critical/add_effects(drug_name)
|
||||
description = "<span class='boldwarning'>[drug_name]! [drug_name]! [drug_name]!</span>\n"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/datum/mood_event/handcuffed
|
||||
description = "<span class='warning'>I guess my antics have finally caught up with me..</span>\n"
|
||||
description = "<span class='warning'>I guess my antics have finally caught up with me.</span>\n"
|
||||
mood_change = -1
|
||||
|
||||
/datum/mood_event/broken_vow //Used for when mimes break their vow of silence
|
||||
@@ -84,8 +84,8 @@
|
||||
if(ishuman(owner))
|
||||
var/mob/living/carbon/human/H = owner
|
||||
if(iscatperson(H))
|
||||
H.startTailWag()
|
||||
addtimer(CALLBACK(H, /mob/living/carbon/human.proc/endTailWag), 30)
|
||||
H.dna.species.start_wagging_tail(H)
|
||||
addtimer(CALLBACK(H.dna.species, /datum/species.proc/stop_wagging_tail, H), 30)
|
||||
description = "<span class='nicegreen'>They want to play on the table!</span>\n"
|
||||
mood_change = 2
|
||||
|
||||
|
||||
@@ -18,6 +18,11 @@
|
||||
mood_change = 3
|
||||
timeout = 3000
|
||||
|
||||
/datum/mood_event/exercise
|
||||
description = "<span class='nicegreen'>Working out releases those endorphins!</span>\n"
|
||||
mood_change = 3
|
||||
timeout = 3000
|
||||
|
||||
/datum/mood_event/pet_corgi
|
||||
description = "<span class='nicegreen'>Corgis are adorable! I can't stop petting them!</span>\n"
|
||||
mood_change = 3
|
||||
@@ -60,3 +65,8 @@
|
||||
/datum/mood_event/family_heirloom
|
||||
description = "<span class='nicegreen'>My family heirloom is safe with me.</span>\n"
|
||||
mood_change = 1
|
||||
|
||||
/datum/mood_event/goodmusic
|
||||
description = "<span class='nicegreen'>There is something soothing about this music.</span>\n"
|
||||
mood_change = 3
|
||||
timeout = 600
|
||||
|
||||
@@ -1,37 +1,45 @@
|
||||
//nutrition
|
||||
/datum/mood_event/nutrition/fat
|
||||
/datum/mood_event/fat
|
||||
description = "<span class='warning'><B>I'm so fat...</B></span>\n" //muh fatshaming
|
||||
mood_change = -4
|
||||
|
||||
/datum/mood_event/nutrition/wellfed
|
||||
/datum/mood_event/wellfed
|
||||
description = "<span class='nicegreen'>My belly feels round and full.</span>\n"
|
||||
mood_change = 6
|
||||
|
||||
/datum/mood_event/nutrition/fed
|
||||
/datum/mood_event/fed
|
||||
description = "<span class='nicegreen'>I have recently had some food.</span>\n"
|
||||
mood_change = 3
|
||||
|
||||
/datum/mood_event/nutrition/hungry
|
||||
/datum/mood_event/hungry
|
||||
description = "<span class='warning'>I'm getting a bit hungry.</span>\n"
|
||||
mood_change = -8
|
||||
|
||||
/datum/mood_event/nutrition/starving
|
||||
/datum/mood_event/starving
|
||||
description = "<span class='boldwarning'>I'm starving!</span>\n"
|
||||
mood_change = -15
|
||||
|
||||
//Disgust
|
||||
/datum/mood_event/disgust/gross
|
||||
/datum/mood_event/gross
|
||||
description = "<span class='warning'>I saw something gross.</span>\n"
|
||||
mood_change = -2
|
||||
|
||||
/datum/mood_event/disgust/verygross
|
||||
/datum/mood_event/verygross
|
||||
description = "<span class='warning'>I think I'm going to puke...</span>\n"
|
||||
mood_change = -5
|
||||
|
||||
/datum/mood_event/disgust/disgusted
|
||||
/datum/mood_event/disgusted
|
||||
description = "<span class='boldwarning'>Oh god that's disgusting...</span>\n"
|
||||
mood_change = -8
|
||||
|
||||
/datum/mood_event/disgust/bad_smell
|
||||
description = "<span class='warning'>You smell something horribly decayed inside this room.</span>\n"
|
||||
mood_change = -3
|
||||
|
||||
/datum/mood_event/disgust/nauseating_stench
|
||||
description = "<span class='warning'>The stench of rotting carcasses is unbearable!</span>\n"
|
||||
mood_change = -7
|
||||
|
||||
//Generic needs events
|
||||
/datum/mood_event/favorite_food
|
||||
description = "<span class='nicegreen'>I really enjoyed eating that.</span>\n"
|
||||
@@ -39,12 +47,12 @@
|
||||
timeout = 2400
|
||||
|
||||
/datum/mood_event/gross_food
|
||||
description = "<span class='nicegreen'>I really didn't like that food.</span>\n"
|
||||
description = "<span class='warning'>I really didn't like that food.</span>\n"
|
||||
mood_change = -2
|
||||
timeout = 2400
|
||||
|
||||
/datum/mood_event/disgusting_food
|
||||
description = "<span class='nicegreen'>That food was disgusting!</span>\n"
|
||||
description = "<span class='warning'>That food was disgusting!</span>\n"
|
||||
mood_change = -4
|
||||
timeout = 2400
|
||||
|
||||
|
||||
@@ -107,7 +107,7 @@
|
||||
if(1)
|
||||
owner.emote("twitch")
|
||||
if(2 to 3)
|
||||
owner.say("[prob(50) ? ";" : ""][pick("SHIT", "PISS", "FUCK", "CUNT", "COCKSUCKER", "MOTHERFUCKER", "TITS")]")
|
||||
owner.say("[prob(50) ? ";" : ""][pick("SHIT", "PISS", "FUCK", "CUNT", "COCKSUCKER", "MOTHERFUCKER", "TITS")]", forced="tourette's syndrome")
|
||||
var/x_offset_old = owner.pixel_x
|
||||
var/y_offset_old = owner.pixel_y
|
||||
var/x_offset = owner.pixel_x + rand(-2,2)
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
#define RETURN_PRECISE_POSITION(A) new /datum/position(A)
|
||||
#define RETURN_PRECISE_POINT(A) new /datum/point(A)
|
||||
|
||||
#define RETURN_POINT_VECTOR(ATOM, ANGLE, SPEED) {new /datum/point/vector(ATOM, null, null, null, null, ANGLE, SPEED)}
|
||||
#define RETURN_POINT_VECTOR_INCREMENT(ATOM, ANGLE, SPEED, AMT) {new /datum/point/vector(ATOM, null, null, null, null, ANGLE, SPEED, AMT)}
|
||||
#define RETURN_POINT_VECTOR(ATOM, ANGLE, SPEED) (new /datum/point/vector(ATOM, null, null, null, null, ANGLE, SPEED))
|
||||
#define RETURN_POINT_VECTOR_INCREMENT(ATOM, ANGLE, SPEED, AMT) (new /datum/point/vector(ATOM, null, null, null, null, ANGLE, SPEED, AMT))
|
||||
|
||||
/proc/point_midpoint_points(datum/point/a, datum/point/b) //Obviously will not support multiZ calculations! Same for the two below.
|
||||
var/datum/point/P = new
|
||||
|
||||
@@ -24,8 +24,9 @@
|
||||
START_PROCESSING(SSradiation, src)
|
||||
|
||||
/datum/radiation_wave/Destroy()
|
||||
. = QDEL_HINT_IWILLGC
|
||||
STOP_PROCESSING(SSradiation, src)
|
||||
return ..()
|
||||
..()
|
||||
|
||||
/datum/radiation_wave/process()
|
||||
master_turf = get_step(master_turf, move_dir)
|
||||
@@ -80,12 +81,10 @@
|
||||
var/atom/thing = atoms[k]
|
||||
if(!thing)
|
||||
continue
|
||||
var/datum/component/rad_insulation/insulation = thing.GetComponent(/datum/component/rad_insulation)
|
||||
if(!insulation)
|
||||
continue
|
||||
intensity = intensity*(1-((1-insulation.amount)/width)) // The further out the rad wave goes the less it's affected by insulation
|
||||
SEND_SIGNAL(thing, COMSIG_ATOM_RAD_WAVE_PASSING, src, width)
|
||||
|
||||
/datum/radiation_wave/proc/radiate(list/atoms, strength)
|
||||
var/contamination_chance = (strength-RAD_MINIMUM_CONTAMINATION) * RAD_CONTAMINATION_CHANCE_COEFFICIENT * min(1, 1/(steps*range_modifier))
|
||||
for(var/k in 1 to atoms.len)
|
||||
var/atom/thing = atoms[k]
|
||||
if(!thing)
|
||||
@@ -106,11 +105,8 @@
|
||||
))
|
||||
if(!can_contaminate || blacklisted[thing.type])
|
||||
continue
|
||||
var/contamination_chance = (strength-RAD_MINIMUM_CONTAMINATION) * RAD_CONTAMINATION_CHANCE_COEFFICIENT * min(1, 1/(steps*range_modifier))
|
||||
if(prob(contamination_chance)) // Only stronk rads get to have little baby rads
|
||||
var/datum/component/rad_insulation/insulation = thing.GetComponent(/datum/component/rad_insulation)
|
||||
if(insulation && insulation.contamination_proof)
|
||||
if(SEND_SIGNAL(thing, COMSIG_ATOM_RAD_CONTAMINATING, strength) & COMPONENT_BLOCK_CONTAMINATION)
|
||||
continue
|
||||
else
|
||||
var/rad_strength = (strength-RAD_MINIMUM_CONTAMINATION) * RAD_CONTAMINATION_STR_COEFFICIENT
|
||||
thing.AddComponent(/datum/component/radioactive, rad_strength, source)
|
||||
@@ -154,11 +154,12 @@
|
||||
suffix = "lavaland_surface_ufo_crash.dmm"
|
||||
cost = 5
|
||||
|
||||
/datum/map_template/ruin/lavaland/alien_nest
|
||||
name = "Alien Nest"
|
||||
id = "alien-nest"
|
||||
description = "Not even Necropolis is safe from alien infestation. The competition for hosts has locked the legion and aliens in an endless conflict that can only be resolved by a PKA."
|
||||
suffix = "lavaland_surface_alien_nest.dmm"
|
||||
/datum/map_template/ruin/lavaland/xeno_nest
|
||||
name = "Xenomorph Nest"
|
||||
id = "xeno-nest"
|
||||
description = "These xenomorphs got bored of horrifically slaughtering people on space stations, and have settled down on a nice lava filled hellscape to focus on what's really important in life. \
|
||||
Quality memes."
|
||||
suffix = "lavaland_surface_xeno_nest.dmm"
|
||||
cost = 20
|
||||
|
||||
/datum/map_template/ruin/lavaland/fountain
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
return FALSE
|
||||
var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
|
||||
var/msg = "<i><font color=#800080><b>[changeling.changelingID]:</b> [message]</font></i>"
|
||||
log_talk(user,"[changeling.changelingID]/[user.key] : [message]",LOGSAY)
|
||||
user.log_talk(message, LOG_SAY, tag="changeling [changeling.changelingID]")
|
||||
for(var/_M in GLOB.player_list)
|
||||
var/mob/M = _M
|
||||
if(M in GLOB.dead_mob_list)
|
||||
@@ -129,7 +129,7 @@
|
||||
if(!mind)
|
||||
return TRUE
|
||||
if(is_monkey_leader(mind) || (ismonkey(user) && is_monkey(mind)))
|
||||
log_talk(user, "(MONKEY) [user]/[user.key]: [message]",LOGSAY)
|
||||
user.log_talk(message, LOG_SAY, tag="monkey")
|
||||
if(prob(75) && ismonkey(user))
|
||||
user.visible_message("<span class='notice'>\The [user] chimpers.</span>")
|
||||
var/msg = "<span class='[is_monkey_leader(mind) ? "monkeylead" : "monkeyhive"]'><b><font size=2>\[[is_monkey_leader(mind) ? "Monkey Leader" : "Monkey"]\]</font> [user]</b>: [message]</span>"
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
var/credit_cost = INFINITY
|
||||
var/can_be_bought = TRUE
|
||||
|
||||
var/port_x_offset
|
||||
var/port_y_offset
|
||||
|
||||
/datum/map_template/shuttle/proc/prerequisites_met()
|
||||
return TRUE
|
||||
@@ -21,7 +23,33 @@
|
||||
mappath = "[prefix][shuttle_id].dmm"
|
||||
. = ..()
|
||||
|
||||
/datum/map_template/shuttle/load(turf/T, centered)
|
||||
/datum/map_template/shuttle/preload_size(path, cache)
|
||||
. = ..(path, TRUE) // Done this way because we still want to know if someone actualy wanted to cache the map
|
||||
if(!cached_map)
|
||||
return
|
||||
|
||||
var/key
|
||||
var/list/models = cached_map.grid_models
|
||||
for(key in models)
|
||||
if(findtext(models[key], "[/obj/docking_port/mobile]")) // Yay compile time checks
|
||||
break // This works by assuming there will ever only be one mobile dock in a template at most
|
||||
|
||||
var/datum/grid_set/gset
|
||||
for(var/i in cached_map.gridSets)
|
||||
gset = i
|
||||
var/ycrd = gset.ycrd
|
||||
for(var/line in gset.gridLines)
|
||||
if(key != line)
|
||||
ycrd--
|
||||
continue
|
||||
port_x_offset = gset.xcrd
|
||||
port_y_offset = ycrd
|
||||
break
|
||||
|
||||
if(!cache)
|
||||
cached_map = null
|
||||
|
||||
/datum/map_template/shuttle/load(turf/T, centered, register=TRUE)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
@@ -35,6 +63,33 @@
|
||||
continue
|
||||
place.baseturfs.Insert(3, /turf/baseturf_skipover/shuttle)
|
||||
|
||||
for(var/obj/docking_port/mobile/port in place)
|
||||
if(register)
|
||||
port.register()
|
||||
if(isnull(port_x_offset))
|
||||
return
|
||||
switch(port.dir) // Yeah this looks a little ugly but mappers had to do this in their head before
|
||||
if(NORTH)
|
||||
port.width = width
|
||||
port.height = height
|
||||
port.dwidth = port_x_offset - 1
|
||||
port.dheight = port_y_offset - 1
|
||||
if(EAST)
|
||||
port.width = height
|
||||
port.height = width
|
||||
port.dwidth = height - port_y_offset
|
||||
port.dheight = port_x_offset - 1
|
||||
if(SOUTH)
|
||||
port.width = width
|
||||
port.height = height
|
||||
port.dwidth = width - port_x_offset
|
||||
port.dheight = height - port_y_offset
|
||||
if(WEST)
|
||||
port.width = height
|
||||
port.height = width
|
||||
port.dwidth = port_y_offset - 1
|
||||
port.dheight = width - port_x_offset
|
||||
|
||||
for(var/obj/structure/closet/closet in place)
|
||||
if(closet.anchorable)
|
||||
closet.anchored = TRUE
|
||||
@@ -110,6 +165,11 @@
|
||||
|
||||
// Shuttles start here:
|
||||
|
||||
/datum/map_template/shuttle/emergency/backup
|
||||
suffix = "backup"
|
||||
name = "Backup Shuttle"
|
||||
can_be_bought = FALSE
|
||||
|
||||
/datum/map_template/shuttle/emergency/airless
|
||||
suffix = "airless"
|
||||
name = "Build your own shuttle kit"
|
||||
@@ -126,6 +186,7 @@
|
||||
var/datum/supply_pack/P = SSshuttle.supply_packs[/datum/supply_pack/engineering/shuttle_engine]
|
||||
P.special_enabled = TRUE
|
||||
|
||||
|
||||
/datum/map_template/shuttle/emergency/asteroid
|
||||
suffix = "asteroid"
|
||||
name = "Asteroid Station Emergency Shuttle"
|
||||
@@ -228,7 +289,7 @@
|
||||
suffix = "scrapheap"
|
||||
name = "Standby Evacuation Vessel \"Scrapheap Challenge\""
|
||||
credit_cost = -1000
|
||||
description = "Due to a lack of functional emergency shuttles, we bought this second hand from a scrapyard and pressed it into service. Please do not lean to heavily on the exterior windows, they are fragile. <span class='danger'>VIRUS ALERT: This entry seems to be booby-trapped with a redirector trap. Buy this at your own risk.</span>"
|
||||
description = "Due to a lack of functional emergency shuttles, we bought this second hand from a scrapyard and pressed it into service. Please do not lean too heavily on the exterior windows, they are fragile."
|
||||
admin_notes = "An abomination with no functional medbay, sections missing, and some very fragile windows. Surprisingly airtight."
|
||||
|
||||
/datum/map_template/shuttle/emergency/narnar
|
||||
@@ -324,11 +385,11 @@
|
||||
|
||||
/datum/map_template/shuttle/whiteship/box
|
||||
suffix = "box"
|
||||
name = "NT Medical Ship"
|
||||
name = "Hospital Ship"
|
||||
|
||||
/datum/map_template/shuttle/whiteship/meta
|
||||
suffix = "meta"
|
||||
name = "NT Recovery Whiteship"
|
||||
name = "Salvage Ship"
|
||||
|
||||
/datum/map_template/shuttle/whiteship/pubby
|
||||
suffix = "pubby"
|
||||
@@ -340,8 +401,11 @@
|
||||
|
||||
/datum/map_template/shuttle/whiteship/delta
|
||||
suffix = "delta"
|
||||
name = "Unnamed NT Vessel"
|
||||
admin_notes = "The Delta whiteship doesn't have a name, apparently."
|
||||
name = "NT Frigate"
|
||||
|
||||
/datum/map_template/shuttle/whiteship/pod
|
||||
suffix = "whiteship_pod"
|
||||
name = "Salvage Pod"
|
||||
|
||||
/datum/map_template/shuttle/cargo/box
|
||||
suffix = "box"
|
||||
@@ -445,8 +509,8 @@
|
||||
suffix = "syndicate_dropship"
|
||||
name = "Syndicate Dropship"
|
||||
|
||||
/datum/map_template/shuttle/ruin/syndicate_fighter
|
||||
suffix = "syndicate_fighter"
|
||||
/datum/map_template/shuttle/ruin/syndicate_fighter_shiv
|
||||
suffix = "syndicate_fighter_shiv"
|
||||
name = "Syndicate Fighter"
|
||||
|
||||
/datum/map_template/shuttle/snowdin/mining
|
||||
|
||||
@@ -70,7 +70,7 @@
|
||||
return ..()
|
||||
|
||||
/datum/status_effect/vanguard_shield/on_apply()
|
||||
owner.log_message("gained Vanguard stun immunity", INDIVIDUAL_ATTACK_LOG)
|
||||
owner.log_message("gained Vanguard stun immunity", LOG_ATTACK)
|
||||
owner.add_stun_absorption("vanguard", INFINITY, 1, "'s yellow aura momentarily intensifies!", "Your ward absorbs the stun!", " radiating with a soft yellow light!")
|
||||
owner.visible_message("<span class='warning'>[owner] begins to faintly glow!</span>", "<span class='brass'>You will absorb all stuns for the next twenty seconds.</span>")
|
||||
owner.SetStun(0, FALSE)
|
||||
@@ -105,7 +105,7 @@
|
||||
else
|
||||
stuns_blocked = 0 //so logging is correct in cases where there were stuns blocked but we didn't stun for other reasons
|
||||
owner.visible_message("<span class='warning'>[owner]'s glowing aura fades!</span>", message_to_owner)
|
||||
owner.log_message("lost Vanguard stun immunity[stuns_blocked ? "and was stunned for [stuns_blocked]":""]", INDIVIDUAL_ATTACK_LOG)
|
||||
owner.log_message("lost Vanguard stun immunity[stuns_blocked ? "and was stunned for [stuns_blocked]":""]", LOG_ATTACK)
|
||||
|
||||
|
||||
/datum/status_effect/inathneqs_endowment
|
||||
@@ -120,7 +120,7 @@
|
||||
alerttooltipstyle = "clockcult"
|
||||
|
||||
/datum/status_effect/inathneqs_endowment/on_apply()
|
||||
owner.log_message("gained Inath-neq's invulnerability", INDIVIDUAL_ATTACK_LOG)
|
||||
owner.log_message("gained Inath-neq's invulnerability", LOG_ATTACK)
|
||||
owner.visible_message("<span class='warning'>[owner] shines with azure light!</span>", "<span class='notice'>You feel Inath-neq's power flow through you! You're invincible!</span>")
|
||||
var/oldcolor = owner.color
|
||||
owner.color = "#1E8CE1"
|
||||
@@ -133,7 +133,7 @@
|
||||
return ..()
|
||||
|
||||
/datum/status_effect/inathneqs_endowment/on_remove()
|
||||
owner.log_message("lost Inath-neq's invulnerability", INDIVIDUAL_ATTACK_LOG)
|
||||
owner.log_message("lost Inath-neq's invulnerability", LOG_ATTACK)
|
||||
owner.visible_message("<span class='warning'>The light around [owner] flickers and dissipates!</span>", "<span class='boldwarning'>You feel Inath-neq's power fade from your body!</span>")
|
||||
owner.status_flags &= ~GODMODE
|
||||
playsound(owner, 'sound/magic/ethereal_exit.ogg', 50, 1)
|
||||
@@ -185,7 +185,7 @@
|
||||
..()
|
||||
|
||||
/datum/status_effect/his_grace/on_apply()
|
||||
owner.log_message("gained His Grace's stun immunity", INDIVIDUAL_ATTACK_LOG)
|
||||
owner.log_message("gained His Grace's stun immunity", LOG_ATTACK)
|
||||
owner.add_stun_absorption("hisgrace", INFINITY, 3, null, "His Grace protects you from the stun!")
|
||||
return ..()
|
||||
|
||||
@@ -209,7 +209,7 @@
|
||||
owner.adjustCloneLoss(-grace_heal)
|
||||
|
||||
/datum/status_effect/his_grace/on_remove()
|
||||
owner.log_message("lost His Grace's stun immunity", INDIVIDUAL_ATTACK_LOG)
|
||||
owner.log_message("lost His Grace's stun immunity", LOG_ATTACK)
|
||||
if(islist(owner.stun_absorption) && owner.stun_absorption["hisgrace"])
|
||||
owner.stun_absorption -= "hisgrace"
|
||||
|
||||
@@ -242,7 +242,7 @@
|
||||
|
||||
/datum/status_effect/cult_master/proc/deathrattle()
|
||||
if(!QDELETED(GLOB.cult_narsie))
|
||||
return //if nar-sie is alive, don't even worry about it
|
||||
return //if Nar'Sie is alive, don't even worry about it
|
||||
var/area/A = get_area(owner)
|
||||
for(var/datum/mind/B in SSticker.mode.cult)
|
||||
if(isliving(B.current))
|
||||
@@ -304,7 +304,7 @@
|
||||
last_oxyloss = owner.getOxyLoss()
|
||||
last_cloneloss = owner.getCloneLoss()
|
||||
last_staminaloss = owner.getStaminaLoss()
|
||||
owner.log_message("gained blood-drunk stun immunity", INDIVIDUAL_ATTACK_LOG)
|
||||
owner.log_message("gained blood-drunk stun immunity", LOG_ATTACK)
|
||||
owner.add_stun_absorption("blooddrunk", INFINITY, 4)
|
||||
owner.playsound_local(get_turf(owner), 'sound/effects/singlebeat.ogg', 40, 1)
|
||||
|
||||
@@ -380,7 +380,7 @@
|
||||
owner.cloneloss *= 0.1
|
||||
owner.staminaloss *= 0.1
|
||||
owner.updatehealth()
|
||||
owner.log_message("lost blood-drunk stun immunity", INDIVIDUAL_ATTACK_LOG)
|
||||
owner.log_message("lost blood-drunk stun immunity", LOG_ATTACK)
|
||||
if(islist(owner.stun_absorption) && owner.stun_absorption["blooddrunk"])
|
||||
owner.stun_absorption -= "blooddrunk"
|
||||
|
||||
@@ -479,7 +479,7 @@
|
||||
if(deathTick < 4)
|
||||
deathTick += 1
|
||||
else
|
||||
owner.visible_message("[owner]'s soul is absorbed into the rod, releaving the previous snake of it's duty.")
|
||||
owner.visible_message("[owner]'s soul is absorbed into the rod, relieving the previous snake of its duty.")
|
||||
var/mob/living/simple_animal/hostile/retaliate/poison/snake/healSnake = new(owner.loc)
|
||||
var/list/chems = list("bicaridine", "salbutamol", "kelotane", "antitoxin")
|
||||
healSnake.poison_type = pick(chems)
|
||||
|
||||
@@ -72,7 +72,7 @@
|
||||
if(prob(20))
|
||||
if(carbon_owner)
|
||||
carbon_owner.handle_dreams()
|
||||
if(prob(10) && owner.health > HEALTH_THRESHOLD_CRIT)
|
||||
if(prob(10) && owner.health > owner.crit_threshold)
|
||||
owner.emote("snore")
|
||||
|
||||
/obj/screen/alert/status_effect/asleep
|
||||
@@ -124,7 +124,7 @@
|
||||
qdel(src)
|
||||
|
||||
/datum/status_effect/belligerent/proc/do_movement_toggle(force_damage)
|
||||
var/number_legs = owner.get_num_legs()
|
||||
var/number_legs = owner.get_num_legs(FALSE)
|
||||
if(iscarbon(owner) && !is_servant_of_ratvar(owner) && !owner.anti_magic_check() && number_legs)
|
||||
if(force_damage || owner.m_intent != MOVE_INTENT_WALK)
|
||||
if(GLOB.ratvar_awakens)
|
||||
@@ -224,7 +224,7 @@
|
||||
if(is_eligible_servant(owner))
|
||||
to_chat(owner, "<span class='sevtug[span_part]'>\"[text2ratvar("You are mine and his, now.")]\"</span>")
|
||||
if(add_servant_of_ratvar(owner))
|
||||
owner.log_message("<font color=#BE8700>Conversion was done with a Mania Motor.</font>", INDIVIDUAL_ATTACK_LOG)
|
||||
owner.log_message("conversion was done with a Mania Motor", LOG_ATTACK, color="#BE8700")
|
||||
owner.Unconscious(100)
|
||||
else
|
||||
if(prob(severity * 0.15))
|
||||
@@ -468,7 +468,7 @@
|
||||
var/health_difference = old_health - owner.health
|
||||
if(!health_difference)
|
||||
return
|
||||
owner.visible_message("<span class='warning'>The light in [owner]'s eyes dims as they're harmed!</span>", \
|
||||
owner.visible_message("<span class='warning'>The light in [owner]'s eyes dims as [owner.p_theyre()] harmed!</span>", \
|
||||
"<span class='boldannounce'>The dazzling lights dim as you're harmed!</span>")
|
||||
health_difference *= 2 //so 10 health difference translates to 20 deciseconds of stun reduction
|
||||
duration -= health_difference
|
||||
|
||||
@@ -9,11 +9,11 @@
|
||||
|
||||
/obj/screen/alert/status_effect/freon
|
||||
name = "Frozen Solid"
|
||||
desc = "You're frozen inside of an ice cube, and cannot move! You can still do stuff, like shooting. Resist out of the cube!"
|
||||
desc = "You're frozen inside an ice cube, and cannot move! You can still do stuff, like shooting. Resist out of the cube!"
|
||||
icon_state = "frozen"
|
||||
|
||||
/datum/status_effect/freon/on_apply()
|
||||
redirect_component = WEAKREF(owner.AddComponent(/datum/component/redirect, list(COMSIG_LIVING_RESIST), CALLBACK(src, .proc/owner_resist)))
|
||||
redirect_component = WEAKREF(owner.AddComponent(/datum/component/redirect, list(COMSIG_LIVING_RESIST = CALLBACK(src, .proc/owner_resist))))
|
||||
if(!owner.stat)
|
||||
to_chat(owner, "<span class='userdanger'>You become frozen in a cube!</span>")
|
||||
cube = icon('icons/effects/freeze.dmi', "ice_cube")
|
||||
|
||||
@@ -9,8 +9,6 @@
|
||||
gain_text = "<span class='notice'>You feel like you could drink a whole keg!</span>"
|
||||
lose_text = "<span class='danger'>You don't feel as resistant to alcohol anymore. Somehow.</span>"
|
||||
|
||||
|
||||
|
||||
/datum/quirk/apathetic
|
||||
name = "Apathetic"
|
||||
desc = "You just don't care as much as other people. That's nice to have in a place like this, I guess."
|
||||
@@ -23,12 +21,11 @@
|
||||
mood.mood_modifier = 0.8
|
||||
|
||||
/datum/quirk/apathetic/remove()
|
||||
if(quirk_holder)
|
||||
GET_COMPONENT_FROM(mood, /datum/component/mood, quirk_holder)
|
||||
if(mood)
|
||||
mood.mood_modifier = 1 //Change this once/if species get their own mood modifiers.
|
||||
|
||||
|
||||
|
||||
/datum/quirk/drunkhealing
|
||||
name = "Drunken Resilience"
|
||||
desc = "Nothing like a good drink to make you feel on top of the world. Whenever you're drunk, you slowly recover from injuries."
|
||||
@@ -38,7 +35,6 @@
|
||||
lose_text = "<span class='danger'>You no longer feel like drinking would ease your pain.</span>"
|
||||
medical_record_text = "Patient has unusually efficient liver metabolism and can slowly regenerate wounds by drinking alcoholic beverages."
|
||||
|
||||
|
||||
/datum/quirk/freerunning
|
||||
name = "Freerunning"
|
||||
desc = "You're great at quick moves! You can climb tables more quickly."
|
||||
@@ -47,8 +43,6 @@
|
||||
gain_text = "<span class='notice'>You feel lithe on your feet!</span>"
|
||||
lose_text = "<span class='danger'>You feel clumsy again.</span>"
|
||||
|
||||
|
||||
|
||||
/datum/quirk/jolly
|
||||
name = "Jolly"
|
||||
desc = "You sometimes just feel happy, for no reason at all."
|
||||
@@ -56,17 +50,31 @@
|
||||
mob_trait = TRAIT_JOLLY
|
||||
mood_quirk = TRUE
|
||||
|
||||
|
||||
|
||||
/datum/quirk/light_step
|
||||
name = "Light Step"
|
||||
desc = "You walk with a gentle step, making stepping on sharp objects quieter and less painful."
|
||||
desc = "You walk with a gentle step; stepping on sharp objects is quieter, less painful and you won't leave footprints behind you."
|
||||
value = 1
|
||||
mob_trait = TRAIT_LIGHT_STEP
|
||||
gain_text = "<span class='notice'>You walk with a little more litheness.</span>"
|
||||
lose_text = "<span class='danger'>You start tromping around like a barbarian.</span>"
|
||||
|
||||
/datum/quirk/musician
|
||||
name = "Musician"
|
||||
desc = "You can tune handheld musical instruments to play melodies that clear certain negative effects and soothe the soul."
|
||||
value = 1
|
||||
mob_trait = TRAIT_MUSICIAN
|
||||
gain_text = "<span class='notice'>You know everything about musical instruments.</span>"
|
||||
lose_text = "<span class='danger'>You forget how musical instruments work.</span>"
|
||||
|
||||
/datum/quirk/musician/on_spawn()
|
||||
var/mob/living/carbon/human/H = quirk_holder
|
||||
var/obj/item/instrument/guitar/guitar = new(get_turf(H))
|
||||
H.put_in_hands(guitar)
|
||||
H.equip_to_slot(guitar, SLOT_IN_BACKPACK)
|
||||
var/obj/item/musicaltuner/musicaltuner = new(get_turf(H))
|
||||
H.put_in_hands(musicaltuner)
|
||||
H.equip_to_slot(musicaltuner, SLOT_IN_BACKPACK)
|
||||
H.regenerate_icons()
|
||||
|
||||
/datum/quirk/night_vision
|
||||
name = "Night Vision"
|
||||
@@ -83,7 +91,20 @@
|
||||
return
|
||||
eyes.Insert(H) //refresh their eyesight and vision
|
||||
|
||||
/datum/quirk/photographer
|
||||
name = "Photographer"
|
||||
desc = "You know how to handle a camera, shortening the delay between each shot."
|
||||
value = 1
|
||||
mob_trait = TRAIT_PHOTOGRAPHER
|
||||
gain_text = "<span class='notice'>You know everything about photography.</span>"
|
||||
lose_text = "<span class='danger'>You forget how photo cameras work.</span>"
|
||||
|
||||
/datum/quirk/photographer/on_spawn()
|
||||
var/mob/living/carbon/human/H = quirk_holder
|
||||
var/obj/item/camera/camera = new(get_turf(H))
|
||||
H.put_in_hands(camera)
|
||||
H.equip_to_slot(camera, SLOT_NECK)
|
||||
H.regenerate_icons()
|
||||
|
||||
/datum/quirk/selfaware
|
||||
name = "Self-Aware"
|
||||
@@ -91,16 +112,12 @@
|
||||
value = 2
|
||||
mob_trait = TRAIT_SELF_AWARE
|
||||
|
||||
|
||||
|
||||
/datum/quirk/skittish
|
||||
name = "Skittish"
|
||||
desc = "You can conceal yourself in danger. Ctrl-shift-click a closed locker to jump into it, as long as you have access."
|
||||
value = 2
|
||||
mob_trait = TRAIT_SKITTISH
|
||||
|
||||
|
||||
|
||||
/datum/quirk/spiritual
|
||||
name = "Spiritual"
|
||||
desc = "You're in tune with the gods, and your prayers may be more likely to be heard. Or not."
|
||||
@@ -109,7 +126,20 @@
|
||||
gain_text = "<span class='notice'>You feel a little more faithful to the gods today.</span>"
|
||||
lose_text = "<span class='danger'>You feel less faithful in the gods.</span>"
|
||||
|
||||
/datum/quirk/tagger
|
||||
name = "Tagger"
|
||||
desc = "You're an experienced artist. While drawing graffiti, you can get twice as many uses out of drawing supplies."
|
||||
value = 1
|
||||
mob_trait = TRAIT_TAGGER
|
||||
gain_text = "<span class='notice'>You know how to tag walls efficiently.</span>"
|
||||
lose_text = "<span class='danger'>You forget how to tag walls properly.</span>"
|
||||
|
||||
/datum/quirk/tagger/on_spawn()
|
||||
var/mob/living/carbon/human/H = quirk_holder
|
||||
var/obj/item/toy/crayon/spraycan/spraycan = new(get_turf(H))
|
||||
H.put_in_hands(spraycan)
|
||||
H.equip_to_slot(spraycan, SLOT_IN_BACKPACK)
|
||||
H.regenerate_icons()
|
||||
|
||||
/datum/quirk/voracious
|
||||
name = "Voracious"
|
||||
|
||||
@@ -15,8 +15,6 @@
|
||||
else
|
||||
quirk_holder.blood_volume -= 0.275
|
||||
|
||||
|
||||
|
||||
/datum/quirk/depression
|
||||
name = "Depression"
|
||||
desc = "You sometimes just hate life."
|
||||
@@ -27,8 +25,6 @@
|
||||
medical_record_text = "Patient has a severe mood disorder causing them to experience sudden moments of sadness."
|
||||
mood_quirk = TRUE
|
||||
|
||||
|
||||
|
||||
/datum/quirk/family_heirloom
|
||||
name = "Family Heirloom"
|
||||
desc = "You are the current owner of an heirloom, passed down for generations. You have to keep it safe!"
|
||||
@@ -111,8 +107,6 @@
|
||||
/datum/quirk/brainproblems/on_process()
|
||||
quirk_holder.adjustBrainLoss(0.2)
|
||||
|
||||
|
||||
|
||||
/datum/quirk/nearsighted //t. errorage
|
||||
name = "Nearsighted"
|
||||
desc = "You are nearsighted without prescription glasses, but spawn with a pair."
|
||||
@@ -131,8 +125,6 @@
|
||||
H.equip_to_slot(glasses, SLOT_GLASSES)
|
||||
H.regenerate_icons() //this is to remove the inhand icon, which persists even if it's not in their hands
|
||||
|
||||
|
||||
|
||||
/datum/quirk/nyctophobia
|
||||
name = "Nyctophobia"
|
||||
desc = "As far as you can remember, you've always been afraid of the dark. While in the dark without a light source, you instinctually act careful, and constantly feel a sense of dread."
|
||||
@@ -152,8 +144,6 @@
|
||||
else
|
||||
SEND_SIGNAL(quirk_holder, COMSIG_CLEAR_MOOD_EVENT, "nyctophobia")
|
||||
|
||||
|
||||
|
||||
/datum/quirk/nonviolent
|
||||
name = "Pacifist"
|
||||
desc = "The thought of violence makes you sick. So much so, in fact, that you can't hurt anyone."
|
||||
@@ -168,8 +158,6 @@
|
||||
to_chat(quirk_holder, "<span class='boldannounce'>Your antagonistic nature has caused you to renounce your pacifism.</span>")
|
||||
qdel(src)
|
||||
|
||||
|
||||
|
||||
/datum/quirk/poor_aim
|
||||
name = "Poor Aim"
|
||||
desc = "You're terrible with guns and can't line up a straight shot to save your life. Dual-wielding is right out."
|
||||
@@ -177,8 +165,6 @@
|
||||
mob_trait = TRAIT_POOR_AIM
|
||||
medical_record_text = "Patient possesses a strong tremor in both hands."
|
||||
|
||||
|
||||
|
||||
/datum/quirk/prosopagnosia
|
||||
name = "Prosopagnosia"
|
||||
desc = "You have a mental disorder that prevents you from being able to recognize faces at all."
|
||||
@@ -186,8 +172,6 @@
|
||||
mob_trait = TRAIT_PROSOPAGNOSIA
|
||||
medical_record_text = "Patient suffers from prosopagnosia and cannot recognize faces."
|
||||
|
||||
|
||||
|
||||
/datum/quirk/prosthetic_limb
|
||||
name = "Prosthetic Limb"
|
||||
desc = "An accident caused you to lose one of your limbs. Because of this, you now have a random prosthetic!"
|
||||
@@ -220,8 +204,6 @@
|
||||
to_chat(quirk_holder, "<span class='boldannounce'>Your [slot_string] has been replaced with a surplus prosthetic. It is fragile and will easily come apart under duress. Additionally, \
|
||||
you need to use a welding tool and cables to repair it, instead of bruise packs and ointment.</span>")
|
||||
|
||||
|
||||
|
||||
/datum/quirk/insanity
|
||||
name = "Reality Dissociation Syndrome"
|
||||
desc = "You suffer from a severe disorder that causes very vivid hallucinations. Mindbreaker toxin can suppress its effects, and you are immune to mindbreaker's hallucinogenic properties. <b>This is not a license to grief.</b>"
|
||||
@@ -247,8 +229,6 @@
|
||||
to_chat(quirk_holder, "<span class='big bold info'>Please note that your dissociation syndrome does NOT give you the right to attack people or otherwise cause any interference to \
|
||||
the round. You are not an antagonist, and the rules will treat you the same as other crewmembers.</span>")
|
||||
|
||||
|
||||
|
||||
/datum/quirk/social_anxiety
|
||||
name = "Social Anxiety"
|
||||
desc = "Talking to people is very difficult for you, and you often stutter or even lock up."
|
||||
@@ -260,7 +240,7 @@
|
||||
|
||||
/datum/quirk/social_anxiety/on_process()
|
||||
var/nearby_people = 0
|
||||
for(var/mob/living/carbon/human/H in view(5, quirk_holder))
|
||||
for(var/mob/living/carbon/human/H in oview(3, quirk_holder))
|
||||
if(H.client)
|
||||
nearby_people++
|
||||
var/mob/living/carbon/human/H = quirk_holder
|
||||
|
||||
@@ -10,8 +10,6 @@
|
||||
lose_text = "<span class='notice'>You can taste again!</span>"
|
||||
medical_record_text = "Patient suffers from ageusia and is incapable of tasting food or reagents."
|
||||
|
||||
|
||||
|
||||
/datum/quirk/pineapple_liker
|
||||
name = "Ananas Affinity"
|
||||
desc = "You find yourself greatly enjoying fruits of the ananas genus. You can't seem to ever get enough of their sweet goodness!"
|
||||
@@ -26,6 +24,7 @@
|
||||
|
||||
/datum/quirk/pineapple_liker/remove()
|
||||
var/mob/living/carbon/human/H = quirk_holder
|
||||
if(H)
|
||||
var/datum/species/species = H.dna.species
|
||||
species.liked_food &= ~PINEAPPLE
|
||||
|
||||
@@ -43,6 +42,7 @@
|
||||
|
||||
/datum/quirk/pineapple_hater/remove()
|
||||
var/mob/living/carbon/human/H = quirk_holder
|
||||
if(H)
|
||||
var/datum/species/species = H.dna.species
|
||||
species.disliked_food &= ~PINEAPPLE
|
||||
|
||||
@@ -62,12 +62,11 @@
|
||||
|
||||
/datum/quirk/deviant_tastes/remove()
|
||||
var/mob/living/carbon/human/H = quirk_holder
|
||||
if(H)
|
||||
var/datum/species/species = H.dna.species
|
||||
species.liked_food = initial(species.liked_food)
|
||||
species.disliked_food = initial(species.disliked_food)
|
||||
|
||||
|
||||
|
||||
/datum/quirk/monochromatic
|
||||
name = "Monochromacy"
|
||||
desc = "You suffer from full colorblindness, and perceive nearly the entire world in blacks and whites."
|
||||
@@ -83,4 +82,5 @@
|
||||
quirk_holder.playsound_local(quirk_holder, 'sound/ambience/ambidet1.ogg', 50, FALSE)
|
||||
|
||||
/datum/quirk/monochromatic/remove()
|
||||
if(quirk_holder)
|
||||
quirk_holder.remove_client_colour(/datum/client_colour/monochrome)
|
||||
|
||||
@@ -81,9 +81,13 @@
|
||||
if(ishuman(L)) //Are you immune?
|
||||
var/mob/living/carbon/human/H = L
|
||||
var/thermal_protection = H.get_thermal_protection()
|
||||
if(thermal_protection >= FIRE_IMMUNITY_SUIT_MAX_TEMP_PROTECT)
|
||||
if(thermal_protection >= FIRE_IMMUNITY_MAX_TEMP_PROTECT)
|
||||
return TRUE
|
||||
L = L.loc //Matryoshka check
|
||||
if(isliving(L))// if we're a non immune mob inside an immune mob we have to reconsider if that mob is immune to protect ourselves
|
||||
var/mob/living/the_mob = L
|
||||
if("ash" in the_mob.weather_immunities)
|
||||
return TRUE
|
||||
L = L.loc //Check parent items immunities (recurses up to the turf)
|
||||
return FALSE //RIP you
|
||||
|
||||
/datum/weather/ash_storm/weather_act(mob/living/L)
|
||||
|
||||
@@ -257,8 +257,8 @@
|
||||
if("cut")
|
||||
I = L.is_holding_tool_quality(TOOL_WIRECUTTER)
|
||||
if(I || IsAdminGhost(usr))
|
||||
if(I)
|
||||
I.play_tool_sound(src, 20)
|
||||
if(I && holder)
|
||||
I.play_tool_sound(holder, 20)
|
||||
cut_color(target_wire)
|
||||
. = TRUE
|
||||
else
|
||||
@@ -266,8 +266,8 @@
|
||||
if("pulse")
|
||||
I = L.is_holding_tool_quality(TOOL_MULTITOOL)
|
||||
if(I || IsAdminGhost(usr))
|
||||
if(I)
|
||||
I.play_tool_sound(src, 20)
|
||||
if(I && holder)
|
||||
I.play_tool_sound(holder, 20)
|
||||
pulse_color(target_wire, L)
|
||||
. = TRUE
|
||||
else
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user