Merge branch 'master' into misc-recreation

This commit is contained in:
sarcoph
2022-04-25 23:06:45 -08:00
committed by GitHub
270 changed files with 4170 additions and 1411 deletions
+4 -4
View File
@@ -107,21 +107,21 @@
/datum/bounty/item/medical/advhealthscaner
name = "Advanced Health Analyzer"
description = "A ERT Medical unit needs the new 'advanced health analyzer', for a mission at a Station 4. Can you send some?."
description = "An ERT Medical unit needs the new 'advanced health analyzer' for a mission at a Station 4. Can you send some?."
reward = 3000
required_count = 5
wanted_types = list(/obj/item/healthanalyzer/advanced)
/datum/bounty/item/medical/wallmounts
name = "Defibrillator wall mounts"
description = "New Space OSHA regulation state that are new cloning medical wing needs a few 'Easy to access defibrillartors'. Can you send a few before we get a lawsuit?"
description = "New Safety Review Board regulations state that our new medical wing needs 'easy to access defibrillators'. Can you send a few before we get a lawsuit?"
reward = 2000
required_count = 3
wanted_types = list(/obj/machinery/defibrillator_mount)
/datum/bounty/item/medical/defibrillator
name = "New defibillators"
description = "After years of storage are defibrillator units have become more liabilities then we want. Please send us some new ones to replace these old ones."
name = "New defibrillators"
description = "After years of storage our defibrillator units have become more of a liability then we want. Please send us some new ones to replace them."
reward = 2250
required_count = 5
wanted_types = list(/obj/item/defibrillator)
+1 -1
View File
@@ -61,7 +61,7 @@
/datum/supply_pack/security/russianclothing
name = "Russian Surplus Clothing"
desc = "An old russian crate full of surplus armor that they used to use! Has two sets of bulletproff armor, a few union suits and some warm hats!"
desc = "An old russian crate full of surplus armor that they used to use! Has two sets of bulletproof armor, a few union suits and some warm hats!"
contraband = TRUE
cost = 5750 // Its basicly sec suits, good boots/gloves
contains = list(/obj/item/clothing/suit/security/officer/russian,
+1 -1
View File
@@ -12,7 +12,7 @@
var/removeDontImproveChance = 10 //chance the randomly created law replaces a random law instead of simply being added
var/shuffleLawsChance = 10 //chance the AI's laws are shuffled afterwards
var/botEmagChance = 10
var/announceEvent = ION_RANDOM // -1 means don't announce, 0 means have it randomly announce, 1 means it is announced
var/announceEvent = 1 // -1 means don't announce, 0 means have it randomly announce, 1 means it is announced
var/ionMessage = null
var/ionAnnounceChance = 33
announceWhen = 1
+1 -1
View File
@@ -448,7 +448,7 @@ Since Ramadan is an entire month that lasts 29.5 days on average, the start and
return FALSE
/datum/holiday/ramadan/getStationPrefix()
return pick("Harm","Halaal","Jihad","Muslim")
return pick("Fasting","Enlightenment","Prayer","Muslim")
/datum/holiday/ramadan/end
name = "End of Ramadan"
@@ -40,7 +40,6 @@
update_damage_overlays()
else
adjustStaminaLoss(damage * hit_percent)
//citadel code
if(AROUSAL)
adjustArousalLoss(damage * hit_percent)
return TRUE
@@ -62,7 +61,6 @@
amount += BP.burn_dam
return amount
/mob/living/carbon/adjustBruteLoss(amount, updating_health = TRUE, forced = FALSE)
if (!forced && amount < 0 && HAS_TRAIT(src,TRAIT_NONATURALHEAL))
return FALSE
+12 -1
View File
@@ -729,8 +729,19 @@
remove_atom_colour(TEMPORARY_COLOUR_PRIORITY, "#000000")
cut_overlay(MA)
//medical scan animation
/mob/living/carbon/human/proc/scan_animation()
var/mutable_appearance/scan_anim
scan_anim = mutable_appearance(icon, "mediscan")
add_overlay(scan_anim)
addtimer(CALLBACK(src, .proc/end_scan_animation, scan_anim), 10)
flick(icon,src)
/mob/living/carbon/human/proc/end_scan_animation(mutable_appearance/MA)
cut_overlay(MA)
/mob/living/carbon/human/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE, no_tk=FALSE)
if(incapacitated() || lying )
if(incapacitated())
to_chat(src, "<span class='warning'>You can't do that right now!</span>")
return FALSE
if(!Adjacent(M) && (M.loc != src))
+3 -1
View File
@@ -57,7 +57,6 @@
if(STAMINA)
return getStaminaLoss()
/mob/living/proc/apply_damages(brute = 0, burn = 0, tox = 0, oxy = 0, clone = 0, def_zone = null, blocked = FALSE, stamina = 0, brain = 0)
if(blocked >= 100)
return 0
@@ -230,6 +229,9 @@
/mob/living/proc/setStaminaLoss(amount, updating_stamina = TRUE, forced = FALSE)
return
/mob/living/proc/adjustPainLoss(amount, updating_health = TRUE, forced = FALSE)
return
// heal ONE external organ, organ gets randomly selected from damaged ones.
/mob/living/proc/heal_bodypart_damage(brute = 0, burn = 0, stamina = 0, updating_health = TRUE)
adjustBruteLoss(-brute, FALSE) //zero as argument for no instant health update
-45
View File
@@ -160,15 +160,6 @@
emote_type = EMOTE_AUDIBLE
stat_allowed = UNCONSCIOUS
/datum/emote/living/gasp/run_emote(mob/user, params)
. = ..()
if(. && ishuman(user))
var/mob/living/carbon/C = user
if(user.gender == FEMALE)
playsound(C, pick('hyperstation/sound/voice/emotes/gasp_female1.ogg', 'hyperstation/sound/voice/emotes/gasp_female2.ogg', 'hyperstation/sound/voice/emotes/gasp_female3.ogg', 'hyperstation/sound/voice/emotes/gasp_female4.ogg', 'hyperstation/sound/voice/emotes/gasp_female5.ogg', 'hyperstation/sound/voice/emotes/gasp_female6.ogg', 'hyperstation/sound/voice/emotes/gasp_female7.ogg'), 50, 1)
else
playsound(C, pick('hyperstation/sound/voice/emotes/gasp_male1.ogg', 'hyperstation/sound/voice/emotes/gasp_male2.ogg', 'hyperstation/sound/voice/emotes/gasp_male3.ogg', 'hyperstation/sound/voice/emotes/gasp_male4.ogg', 'hyperstation/sound/voice/emotes/gasp_male5.ogg', 'hyperstation/sound/voice/emotes/gasp_male6.ogg', 'hyperstation/sound/voice/emotes/gasp_male7.ogg'), 50, 1)
/datum/emote/living/giggle
key = "giggle"
key_third_person = "giggles"
@@ -176,17 +167,6 @@
message_mime = "giggles silently!"
emote_type = EMOTE_AUDIBLE
/datum/emote/living/giggle/run_emote(mob/user, params)
. = ..()
if(. && ishuman(user))
var/mob/living/carbon/C = user
if(!C.mind || C.mind.miming)
return
if(user.gender == FEMALE)
playsound(C, pick('hyperstation/sound/voice/emotes/female_giggle1.ogg', 'hyperstation/sound/voice/emotes/female_giggle2.ogg'), 50, 1)
else
playsound(C, pick('hyperstation/sound/voice/emotes/male_laugh3b.ogg'), 50, 1)
/datum/emote/living/glare
key = "glare"
key_third_person = "glares"
@@ -249,11 +229,6 @@
'sound/voice/catpeople/nyahehe.ogg'),
50, 1)
return
if(ishumanbasic(C))
if(user.gender == FEMALE)
playsound(C, pick('hyperstation/sound/voice/emotes/female_laugh1.ogg', 'hyperstation/sound/voice/emotes/female_laugh2.ogg', 'hyperstation/sound/voice/emotes/female_laugh3.ogg', 'hyperstation/sound/voice/emotes/female_laugh4.ogg'), 50, 1)
else
playsound(C, pick('hyperstation/sound/voice/emotes/male_laugh1.ogg', 'hyperstation/sound/voice/emotes/male_laugh1b.ogg', 'hyperstation/sound/voice/emotes/male_laugh2.ogg', 'hyperstation/sound/voice/emotes/male_laugh2b.ogg',/*'hyperstation/sound/voice/emotes/male_laugh3.ogg',*/'hyperstation/sound/voice/emotes/male_laugh3b.ogg', 'hyperstation/sound/voice/emotes/male_laugh4.ogg'), 50, 1)
/datum/emote/living/look
key = "look"
@@ -330,11 +305,6 @@
var/mob/living/carbon/C = user
if(!C.mind || C.mind.miming)
return
if(ishumanbasic(C))
if(user.gender == FEMALE)
playsound(C, pick('hyperstation/sound/voice/emotes/sigh_female.ogg'), 50, 1)
else
playsound(C, pick('hyperstation/sound/voice/emotes/sigh_male.ogg'), 50, 1)
/datum/emote/living/sit
key = "sit"
@@ -364,11 +334,6 @@
var/mob/living/carbon/C = user
if(!C.mind || C.mind.miming)//mimes can't sneeze because fuck you that's why
return
if(ishumanbasic(C))
if(user.gender == FEMALE)
playsound(C, pick('hyperstation/sound/voice/emotes/sneezef1.ogg', 'hyperstation/sound/voice/emotes/sneezef2.ogg'), 50, 1)
else
playsound(C, pick('hyperstation/sound/voice/emotes/sneezem1.ogg', 'hyperstation/sound/voice/emotes/sneezem2.ogg'), 50, 1)
/datum/emote/living/smug
key = "smug"
@@ -462,11 +427,6 @@
var/mob/living/carbon/C = user
if(!C.mind || C.mind.miming)
return
if(ishumanbasic(C))
if(user.gender == FEMALE)
playsound(C, pick('hyperstation/sound/voice/emotes/whimper_female1.ogg', 'hyperstation/sound/voice/emotes/whimper_female2.ogg', 'hyperstation/sound/voice/emotes/whimper_female3.ogg'), 50, 1)
else
playsound(C, pick('hyperstation/sound/voice/emotes/whimper_male1.ogg', 'hyperstation/sound/voice/emotes/whimper_male2.ogg', 'hyperstation/sound/voice/emotes/whimper_male3.ogg'), 50, 1)
/datum/emote/living/wsmile
key = "wsmile"
@@ -485,11 +445,6 @@
var/mob/living/carbon/C = user
if(!C.mind || C.mind.miming)
return
if(ishumanbasic(C))
if(user.gender == FEMALE)
playsound(C, pick('hyperstation/sound/voice/emotes/female_yawn1.ogg', 'hyperstation/sound/voice/emotes/female_yawn2.ogg', 'hyperstation/sound/voice/emotes/female_yawn3.ogg'), 50, 1)
else
playsound(C, pick('hyperstation/sound/voice/emotes/male_yawn1.ogg', 'hyperstation/sound/voice/emotes/male_yawn2.ogg'), 50, 1)
/datum/emote/living/custom
key = "me"
+16 -1
View File
@@ -502,6 +502,10 @@
var/obj/effect/proc_holder/spell/spell = S
spell.updateButtonIcon()
if(iscarbon(src)) //pain cooldown
var/mob/living/carbon/C = src
C.pain_cooldown = 20
//proc used to completely heal a mob.
/mob/living/proc/fully_heal(admin_revive = 0)
restore_blood()
@@ -542,6 +546,13 @@
for(var/organ in C.internal_organs)
var/obj/item/organ/O = organ
O.setOrganDamage(0)
//Heal pain
if(iscarbon(src))
var/mob/living/carbon/C = src
for(var/obj/item/bodypart/X in C.bodyparts)
X.pain_dam = 0
SEND_SIGNAL(src, COMSIG_LIVING_FULLY_HEAL, admin_revive)
//fuck shitcode I hate shitcode
@@ -1086,7 +1097,11 @@
lying = 90*buckle_lying
else if(!lying)
if(resting)
lying = pick(90, 270) // Cit change - makes resting not force you to drop your held items
if(dir == 2 || dir == 4)
lying = 90
else
lying = 270
if(has_gravity()) // Cit change - Ditto
playsound(src, "bodyfall", 50, 1) // Cit change - Ditto!
else if(ko || move_and_fall || (!has_legs && !ignore_legs) || chokehold)
@@ -25,8 +25,7 @@
disabler = FALSE
update_icons() //PUT THE GUN AWAY
else if(istype(O,/obj/item/dogborg/sleeper))
sleeper_g = FALSE
sleeper_r = FALSE
sleeper_state = BORGBELLY_NONE
update_icons()
var/obj/item/dogborg/sleeper/S = O
S.go_out() //this should stop edgecase deletions
@@ -654,10 +654,14 @@
if(disabler)
add_overlay("disabler")//ditto
if(sleeper_g && module.sleeper_overlay)
add_overlay("[module.sleeper_overlay]_g[sleeper_nv ? "_nv" : ""]")
if(sleeper_r && module.sleeper_overlay)
add_overlay("[module.sleeper_overlay]_r[sleeper_nv ? "_nv" : ""]")
if(module.sleeper_overlay)
var/sleeper_overlay_state = ""
switch(sleeper_state)
if(BORGBELLY_NONE) sleeper_overlay_state = ""
if(BORGBELLY_GREEN) sleeper_overlay_state = "_g"
if(BORGBELLY_RED) sleeper_overlay_state = "_r"
add_overlay("[module.sleeper_overlay][sleeper_overlay_state]")
if(module.dogborg == TRUE)
if(resting)
cut_overlays()
@@ -0,0 +1,263 @@
#define GREMLIN_VENT_CHANCE 1.75
//Gremlins
//Small monsters that don't attack humans or other animals. Instead they mess with electronics, computers and machinery
//List of objects that gremlins can't tamper with (because nobody coded an interaction for it)
//List starts out empty. Whenever a gremlin finds a machine that it couldn't tamper with, the machine's type is added here, and all machines of such type are ignored from then on (NOT SUBTYPES)
GLOBAL_LIST(bad_gremlin_items)
/mob/living/simple_animal/hostile/gremlin
name = "gremlin"
desc = "This tiny creature finds great joy in discovering and using technology. Nothing excites it more than pushing random buttons on a computer to see what it might do."
icon = 'icons/mob/mob.dmi'
icon_state = "gremlin"
icon_living = "gremlin"
icon_dead = "gremlin_dead"
var/body_color
var/in_vent = FALSE
health = 20
maxHealth = 20
search_objects = 3 //Completely ignore mobs
//Tampering is handled by the 'npc_tamper()' obj proc
wanted_objects = list(
/obj/machinery,
/obj/item/reagent_containers/food,
/obj/structure/sink
)
var/obj/machinery/atmospherics/components/unary/vent_pump/entry_vent
var/obj/machinery/atmospherics/components/unary/vent_pump/exit_vent
dextrous = TRUE
possible_a_intents = list(INTENT_HELP, INTENT_GRAB, INTENT_DISARM, INTENT_HARM)
faction = list("meme", "gremlin")
speed = 0.5
gold_core_spawnable = 2
unique_name = TRUE
//Ensure gremlins don't attack other mobs
melee_damage_upper = 0
melee_damage_lower = 0
attack_sound = null
obj_damage = 0
environment_smash = ENVIRONMENT_SMASH_NONE
//List of objects that we don't even want to try to tamper with
//Subtypes of these are calculated too
var/list/unwanted_objects = list(/obj/machinery/atmospherics/pipe, /turf, /obj/structure) //ensure gremlins dont try to fuck with walls / normal pipes / glass / etc
var/min_next_vent = 0
//Amount of ticks spent pathing to the target. If it gets above a certain amount, assume that the target is unreachable and stop
var/time_chasing_target = 0
//If you're going to make gremlins slower, increase this value - otherwise gremlins will abandon their targets too early
var/max_time_chasing_target = 2
var/next_eat = 0
//Last 20 heard messages are remembered by gremlins, and will be used to generate messages for comms console tampering, etc...
var/list/hear_memory = list()
var/const/max_hear_memory = 20
/mob/living/simple_animal/hostile/gremlin/Initialize()
. = ..()
AddElement(/datum/element/ventcrawling, given_tier = VENTCRAWLER_ALWAYS)
ADD_TRAIT(src, TRAIT_SHOCKIMMUNE, INNATE_TRAIT)
access_card = new /obj/item/card/id(src)
var/datum/job/captain/C = new /datum/job/captain
access_card.access = C.get_access()
if(!body_color)
body_color = pick(list("orange","blue","purple", "green", "crystal"))
AddElement(/datum/element/mob_holder, "gremlin_[body_color]")
icon_state = "gremlin_[body_color]"
icon_living = "gremlin_[body_color]"
icon_dead = "gremlin_[body_color]_dead"
/mob/living/simple_animal/hostile/gremlin/AttackingTarget()
var/is_hungry = world.time >= next_eat || prob(25)
if(istype(target, /obj/item/reagent_containers/food) && is_hungry) //eat food if we're hungry or bored
visible_message("<span class='danger'>[src] hungrily devours [target]!</span>")
playsound(src, 'sound/items/eatfood.ogg', 50, 1)
qdel(target)
LoseTarget()
next_eat = world.time + rand(700, 3000) //anywhere from 70 seconds to 5 minutes until the gremlin is hungry again
return
if(istype(target, /obj))
var/obj/M = target
tamper(M)
if(prob(50)) //50% chance to move to the next machine
LoseTarget()
/mob/living/simple_animal/hostile/gremlin/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, list/spans, message_mode)
. = ..()
if(message)
hear_memory.Insert(1, raw_message)
if(hear_memory.len > max_hear_memory)
hear_memory.Cut(hear_memory.len)
/mob/living/simple_animal/hostile/gremlin/proc/generate_markov_input()
var/result = ""
for(var/memory in hear_memory)
result += memory + " "
return result
/mob/living/simple_animal/hostile/gremlin/proc/generate_markov_chain()
return markov_chain(generate_markov_input(), rand(2,5), rand(100,700)) //The numbers are chosen arbitarily
/mob/living/simple_animal/hostile/gremlin/proc/tamper(obj/M)
switch(M.npc_tamper_act(src))
if(NPC_TAMPER_ACT_FORGET)
visible_message(pick(
"<span class='notice'>\The [src] plays around with \the [M], but finds it rather boring.</span>",
"<span class='notice'>\The [src] tries to think of some more ways to screw \the [M] up, but fails miserably.</span>",
"<span class='notice'>\The [src] decides to ignore \the [M], and starts looking for something more fun.</span>"))
LAZYADD(GLOB.bad_gremlin_items,M.type)
return FALSE
if(NPC_TAMPER_ACT_NOMSG)
//Don't create a visible message
return TRUE
else
visible_message(pick(
"<span class='danger'>\The [src]'s eyes light up as \he tampers with \the [M].</span>",
"<span class='danger'>\The [src] twists some knobs around on \the [M] and bursts into laughter!</span>",
"<span class='danger'>\The [src] presses a few buttons on \the [M] and giggles mischievously.</span>",
"<span class='danger'>\The [src] rubs its hands devilishly and starts messing with \the [M].</span>",
"<span class='danger'>\The [src] turns a small valve on \the [M].</span>"))
//Add a clue for detectives to find. The clue is only added if no such clue already existed on that machine
return TRUE
/mob/living/simple_animal/hostile/gremlin/CanAttack(atom/new_target)
if(LAZYFIND(GLOB.bad_gremlin_items,new_target.type))
return FALSE
if(is_type_in_list(new_target, unwanted_objects))
return FALSE
if(istype(new_target, /obj/machinery))
var/obj/machinery/M = new_target
if(M.stat) //Unpowered or broken
return FALSE
else if(istype(new_target, /obj/machinery/door/firedoor))
var/obj/machinery/door/firedoor/F = new_target
//Only tamper with firelocks that are closed, opening them!
if(!F.density)
return FALSE
return ..()
/mob/living/simple_animal/hostile/gremlin/death(gibbed)
walk(src,0)
QDEL_NULL(access_card)
return ..()
/mob/living/simple_animal/hostile/gremlin/Life()
. = ..()
if(!health || stat == DEAD)
return
//Don't try to path to one target for too long. If it takes longer than a certain amount of time, assume it can't be reached and find a new one
if(!client) //don't do this shit if there's a client, they're capable of ventcrawling manually
if(in_vent)
target = null
if(entry_vent && get_dist(src, entry_vent) <= 1)
var/list/vents = list()
var/datum/pipeline/entry_vent_parent = entry_vent.parents[1]
for(var/obj/machinery/atmospherics/components/unary/vent_pump/temp_vent in entry_vent_parent.other_atmosmch)
vents += temp_vent
if(!vents.len)
entry_vent = null
in_vent = FALSE
return
exit_vent = pick(vents)
visible_message("<span class='notice'>[src] crawls into the ventilation ducts!</span>")
loc = exit_vent
var/travel_time = round(get_dist(loc, exit_vent.loc) / 2)
addtimer(CALLBACK(src, .proc/exit_vents), travel_time) //come out at exit vent in 2 to 20 seconds
if(world.time > min_next_vent && !entry_vent && !in_vent && prob(GREMLIN_VENT_CHANCE)) //small chance to go into a vent
for(var/obj/machinery/atmospherics/components/unary/vent_pump/v in view(7,src))
if(!v.welded)
entry_vent = v
in_vent = TRUE
walk_to(src, entry_vent)
break
if(!target)
time_chasing_target = 0
else
if(++time_chasing_target > max_time_chasing_target)
LoseTarget()
time_chasing_target = 0
. = ..()
/mob/living/simple_animal/hostile/gremlin/EscapeConfinement()
if(istype(loc, /obj) && CanAttack(loc)) //If we're inside a machine, screw with it
var/obj/M = loc
tamper(M)
return ..()
/mob/living/simple_animal/hostile/gremlin/proc/exit_vents()
if(!exit_vent || exit_vent.welded)
loc = entry_vent
entry_vent = null
return
loc = exit_vent.loc
entry_vent = null
exit_vent = null
in_vent = FALSE
var/area/new_area = get_area(loc)
message_admins("[src] came out at [new_area][ADMIN_JMP(loc)]!")
if(new_area)
new_area.Entered(src)
visible_message("<span class='notice'>[src] climbs out of the ventilation ducts!</span>")
min_next_vent = world.time + 900 //90 seconds between ventcrawls
//This allows player-controlled gremlins to tamper with machinery
/mob/living/simple_animal/hostile/gremlin/UnarmedAttack(var/atom/A)
if(istype(A, /obj/machinery) || istype(A, /obj/structure))
tamper(A)
if(istype(target, /obj/item/reagent_containers/food)) //eat food
visible_message("<span class='danger'>[src] hungrily devours [target]!</span>", "<span class='danger'>You hungrily devour [target]!</span>")
playsound(src, 'sound/items/eatfood.ogg', 50, 1)
qdel(target)
LoseTarget()
next_eat = world.time + rand(700, 3000) //anywhere from 70 seconds to 5 minutes until the gremlin is hungry again
return ..()
/mob/living/simple_animal/hostile/gremlin/IsAdvancedToolUser()
return 1
/mob/living/simple_animal/hostile/gremlin/proc/divide()
//Health is halved and then reduced by 2. A new gremlin is spawned with the same health as the parent
//Need to have at least 6 health for this, otherwise resulting health would be less than 1
if(health < 7.5)
return
visible_message("<span class='notice'>\The [src] splits into two!</span>")
var/mob/living/simple_animal/hostile/gremlin/G = new /mob/living/simple_animal/hostile/gremlin(get_turf(src))
if(mind)
mind.transfer_to(G)
health = round(health * 0.5) - 2
maxHealth = health
resize *= 0.9
G.health = health
G.maxHealth = maxHealth
/mob/living/simple_animal/hostile/gremlin/traitor
health = 85
maxHealth = 85
gold_core_spawnable = 0
@@ -0,0 +1,214 @@
/obj/proc/npc_tamper_act(mob/living/L)
return NPC_TAMPER_ACT_FORGET
/obj/machinery/atmospherics/components/binary/passive_gate/npc_tamper_act(mob/living/L)
if(prob(50)) //Turn on/off
on = !on
investigate_log("was turned [on ? "on" : "off"] by [key_name(L)]", INVESTIGATE_ATMOS)
else //Change pressure
target_pressure = rand(0, MAX_OUTPUT_PRESSURE)
investigate_log("was set to [target_pressure] kPa by [key_name(L)]", INVESTIGATE_ATMOS)
update_icon()
/obj/machinery/atmospherics/components/binary/pump/npc_tamper_act(mob/living/L)
if(prob(50)) //Turn on/off
on = !on
investigate_log("was turned [on ? "on" : "off"] by [key_name(L)]", INVESTIGATE_ATMOS)
else //Change pressure
target_pressure = rand(0, MAX_OUTPUT_PRESSURE)
investigate_log("was set to [target_pressure] kPa by [key_name(L)]", INVESTIGATE_ATMOS)
update_icon()
/obj/machinery/atmospherics/components/binary/volume_pump/npc_tamper_act(mob/living/L)
if(prob(50)) //Turn on/off
on = !on
investigate_log("was turned [on ? "on" : "off"] by [key_name(L)]", INVESTIGATE_ATMOS)
else //Change pressure
transfer_rate = rand(0, MAX_TRANSFER_RATE)
investigate_log("was set to [transfer_rate] L/s by [key_name(L)]", INVESTIGATE_ATMOS)
update_icon()
/obj/machinery/atmospherics/components/binary/valve/npc_tamper_act(mob/living/L)
attack_hand(L)
/obj/machinery/space_heater/npc_tamper_act(mob/living/L)
var/list/choose_modes = list("standby", "heat", "cool")
if(prob(50))
choose_modes -= mode
mode = pick(choose_modes)
else
on = !on
update_icon()
/obj/machinery/shield_gen/npc_tamper_act(mob/living/L)
attack_hand(L)
/obj/machinery/firealarm/npc_tamper_act(mob/living/L)
alarm()
/obj/machinery/airalarm/npc_tamper_act(mob/living/L)
if(panel_open)
wires.npc_tamper(L)
else
panel_open = !panel_open
/obj/machinery/ignition_switch/npc_tamper_act(mob/living/L)
attack_hand(L)
/obj/machinery/flasher_button/npc_tamper_act(mob/living/L)
attack_hand(L)
/obj/machinery/crema_switch/npc_tamper_act(mob/living/L)
attack_hand(L)
/obj/machinery/camera/npc_tamper_act(mob/living/L)
if(!panel_open)
panel_open = !panel_open
if(wires)
wires.npc_tamper(L)
/obj/machinery/atmospherics/components/unary/cryo_cell/npc_tamper_act(mob/living/L)
if(prob(50))
if(beaker)
beaker.forceMove(loc)
beaker = null
else
if(occupant)
if(state_open)
if (close_machine() == usr)
on = TRUE
else
open_machine()
/obj/machinery/door_control/npc_tamper_act(mob/living/L)
attack_hand(L)
/obj/machinery/door/airlock/npc_tamper_act(mob/living/L)
//Open the firelocks as well, otherwise they block the way for our gremlin which isn't fun
for(var/obj/machinery/door/firedoor/F in get_turf(src))
if(F.density)
F.npc_tamper_act(L)
if(prob(40)) //40% - mess with wires
if(!panel_open)
panel_open = !panel_open
if(wires)
wires.npc_tamper(L)
else //60% - just open it
open()
/obj/machinery/gibber/npc_tamper_act(mob/living/L)
attack_hand(L)
/obj/machinery/light_switch/npc_tamper_act(mob/living/L)
attack_hand(L)
/obj/machinery/turretid/npc_tamper_act(mob/living/L)
enabled = rand(0, 1)
lethal = rand(0, 1)
updateTurrets()
/obj/machinery/vending/npc_tamper_act(mob/living/L)
if(!panel_open)
panel_open = !panel_open
if(wires)
wires.npc_tamper(L)
/obj/machinery/shower/npc_tamper_act(mob/living/L)
attack_hand(L)
/obj/machinery/deepfryer/npc_tamper_act(mob/living/L)
//Deepfry a random nearby item
var/list/pickable_items = list()
for(var/obj/item/I in range(1, L))
pickable_items.Add(I)
if(!pickable_items.len)
return
var/obj/item/I = pick(pickable_items)
attackby(I, L) //shove the item in, even if it can't be deepfried normally
/obj/machinery/power/apc/npc_tamper_act(mob/living/L)
if(!panel_open)
panel_open = !panel_open
if(wires)
wires.npc_tamper(L)
/obj/machinery/power/rad_collector/npc_tamper_act(mob/living/L)
attack_hand(L)
/obj/machinery/power/emitter/npc_tamper_act(mob/living/L)
attack_hand(L)
/obj/machinery/particle_accelerator/control_box/npc_tamper_act(mob/living/L)
if(!panel_open)
panel_open = !panel_open
if(wires)
wires.npc_tamper(L)
/obj/machinery/computer/communications/npc_tamper_act(mob/living/user)
if(!authenticated)
if(prob(20)) //20% chance to log in
authenticated = TRUE
else //Already logged in
if(prob(50)) //50% chance to log off
authenticated = FALSE
else if(istype(user, /mob/living/simple_animal/hostile/gremlin)) //make a hilarious public message
var/mob/living/simple_animal/hostile/gremlin/G = user
var/result = G.generate_markov_chain()
if(result)
if(prob(85))
SScommunications.make_announcement(G, FALSE, result)
var/turf/T = get_turf(G)
log_say("[key_name(usr)] ([ADMIN_JMP(T)]) has made a captain announcement: [result]")
message_admins("[key_name_admin(G)] has made a captain announcement.", 1)
else
if(SSshuttle.emergency.mode == SHUTTLE_IDLE)
SSshuttle.requestEvac(G, result)
else if(SSshuttle.emergency.mode == SHUTTLE_ESCAPE)
SSshuttle.cancelEvac(G)
/obj/machinery/button/door/npc_tamper_act(mob/living/L)
attack_hand(L)
/obj/machinery/sleeper/npc_tamper_act(mob/living/L)
if(prob(75))
inject_chem(pick(available_chems))
else
if(state_open)
close_machine()
else
open_machine()
/obj/machinery/power/smes/npc_tamper_act(mob/living/L)
if(prob(50)) //mess with input
input_level = rand(0, input_level_max)
else //mess with output
output_level = rand(0, output_level_max)
/obj/machinery/syndicatebomb/npc_tamper_act(mob/living/L) //suicide bomber gremlins
if(!open_panel)
open_panel = !open_panel
if(wires)
wires.npc_tamper(L)
/obj/machinery/computer/bank_machine/npc_tamper_act(mob/living/L)
siphoning = !siphoning
/obj/machinery/computer/slot_machine/npc_tamper_act(mob/living/L)
spin(L)
/obj/structure/sink/npc_tamper_act(mob/living/L)
if(istype(L, /mob/living/simple_animal/hostile/gremlin))
visible_message("<span class='danger'>\The [L] climbs into \the [src] and turns the faucet on!</span>")
var/mob/living/simple_animal/hostile/gremlin/G = L
G.divide()
return NPC_TAMPER_ACT_NOMSG
@@ -0,0 +1,44 @@
/datum/round_event_control/gremlin
name = "Spawn Gremlins"
typepath = /datum/round_event/gremlin
weight = 15
max_occurrences = 2
earliest_start = 20 MINUTES
min_players = 5
/datum/round_event/gremlin
var/static/list/acceptable_spawns = list("xeno_spawn", "generic event spawn", "blobstart", "Assistant")
/datum/round_event/gremlin/announce()
priority_announce("Bioscans indicate that some gremlins entered through the vents. Deal with them!", "Gremlin Alert", 'sound/ai/beep.ogg')
/datum/round_event/gremlin/start()
var/list/spawn_locs = list()
for(var/obj/effect/landmark/L in GLOB.landmarks_list)
if(isturf(L.loc) && !isspaceturf(L.loc))
if(L.name in acceptable_spawns)
spawn_locs += L.loc
if(!spawn_locs.len) //If we can't find any gremlin spawns, try the xeno spawns
for(var/obj/effect/landmark/L in GLOB.landmarks_list)
if(isturf(L.loc))
switch(L.name)
if("Assistant")
spawn_locs += L.loc
if(!spawn_locs.len) //If we can't find THAT, then just give up and cry
return MAP_ERROR
var/gremlins_to_spawn = rand(2,5)
var/list/gremlin_areas = list()
for(var/i = 0, i <= gremlins_to_spawn, i++)
var/spawnat = pick(spawn_locs)
spawn_locs -= spawnat
gremlin_areas += get_area(spawnat)
new /mob/living/simple_animal/hostile/gremlin(spawnat)
var/grems = gremlin_areas.Join(", ")
message_admins("Gremlins have been spawned at the areas: [grems]")
log_game("Gremlins have been spawned at the areas: [grems]")
return SUCCESSFUL_SPAWN
+4 -4
View File
@@ -197,7 +197,7 @@
var/static_power_used = 0
var/brightness = 8 // luminosity when on, also used in power calculation
var/bulb_power = 1 // basically the alpha of the emitted light source
var/bulb_colour = "#FFFFFF" // befault colour of the light.
var/bulb_colour = "#ffefda" // befault colour of the light.
var/status = LIGHT_OK // LIGHT_OK, _EMPTY, _BURNED or _BROKEN
var/flickering = FALSE
var/light_type = /obj/item/light/tube // the type of light item
@@ -212,13 +212,13 @@
var/nightshift_enabled = FALSE //Currently in night shift mode?
var/nightshift_allowed = TRUE //Set to FALSE to never let this light get switched to night mode.
var/nightshift_brightness = 8
var/nightshift_brightness = 7
var/nightshift_light_power = 0.45
var/nightshift_light_color = "#FFDDCC"
var/nightshift_light_color = "#dafcff"
var/emergency_mode = FALSE // if true, the light is in emergency mode
var/no_emergency = FALSE // if true, this light cannot ever have an emergency mode
var/bulb_emergency_brightness_mul = 0.25 // multiplier for this light's base brightness in emergency power mode
var/bulb_emergency_brightness_mul = 0.6 // multiplier for this light's base brightness in emergency power mode
var/bulb_emergency_colour = "#FF3232" // determines the colour of the light while it's in emergency mode
var/bulb_emergency_pow_mul = 0.75 // the multiplier for determining the light's power in emergency mode
var/bulb_emergency_pow_min = 0.5 // the minimum value for the light's power in emergency mode
@@ -36,6 +36,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
*/
/datum/reagent/consumable/ethanol/on_mob_life(mob/living/carbon/C)
C.adjustPainLoss(-0.25*REM, 0) //alchol dulls pain
if(C.drunkenness < volume * boozepwr * ALCOHOL_THRESHOLD_MODIFIER)
var/booze_power = boozepwr
if(HAS_TRAIT(C, TRAIT_ALCOHOL_TOLERANCE)) //we're an accomplished drinker
@@ -1001,3 +1001,5 @@
glass_desc = "A Summer time drink that can be frozen and eaten or Drinked from a glass!"
glass_name = "Orange Creamsicle"
hydration = 4
@@ -391,6 +391,7 @@ datum/reagent/medicine/styptic_powder/overdose_start(mob/living/M)
/datum/reagent/medicine/mine_salve/on_mob_life(mob/living/carbon/C)
C.hal_screwyhud = SCREWYHUD_HEALTHY
C.adjustBruteLoss(-0.25*REM, 0)
C.adjustPainLoss(-1*REM, 0)
C.adjustFireLoss(-0.25*REM, 0)
C.adjustStaminaLoss(-0.5*REM, 0)
..()
@@ -698,7 +699,7 @@ datum/reagent/medicine/styptic_powder/overdose_start(mob/living/M)
/datum/reagent/medicine/morphine
name = "Morphine"
description = "A painkiller that allows the patient to move at full speed even in bulky objects. Causes drowsiness and eventually unconsciousness in high doses. Overdose will cause a variety of effects, ranging from minor to lethal."
description = "A painkiller. Causes drowsiness and eventually unconsciousness in high doses. Overdose will cause a variety of effects, ranging from minor to lethal."
reagent_state = LIQUID
color = "#A9FBFB"
metabolization_rate = 0.5 * REAGENTS_METABOLISM
@@ -706,23 +707,8 @@ datum/reagent/medicine/styptic_powder/overdose_start(mob/living/M)
addiction_threshold = 25
pH = 8.96
/datum/reagent/medicine/morphine/on_mob_metabolize(mob/living/L)
..()
L.ignore_slowdown(type)
/datum/reagent/medicine/morphine/on_mob_end_metabolize(mob/living/L)
L.unignore_slowdown(type)
..()
/datum/reagent/medicine/morphine/on_mob_life(mob/living/carbon/M)
switch(current_cycle)
if(11)
to_chat(M, "<span class='warning'>You start to feel tired...</span>" )
if(12 to 24)
M.drowsyness += 1
if(24 to INFINITY)
M.Sleeping(40, 0)
. = 1
M.adjustPainLoss(-3*REM, 0)// very good pain killer.
..()
/datum/reagent/medicine/morphine/overdose_process(mob/living/M)
@@ -1022,6 +1008,7 @@ datum/reagent/medicine/styptic_powder/overdose_start(mob/living/M)
/datum/reagent/medicine/bicaridine/on_mob_life(mob/living/carbon/M)
M.adjustBruteLoss(-2*REM, 0)
M.adjustPainLoss(-1*REM, 0) //stabilize pain at threshold. and bring it down faster if above.
..()
. = 1
@@ -158,10 +158,10 @@
var/altered_height
altered_height = input(user, "Choose your desired sprite size:\n([MIN_BODYSIZE]-400%)", "Height Alteration") as num|null
if(altered_height)
H.size_multiplier = (max(min( round(text2num(altered_height)),400),MIN_BODYSIZE))/100
H.size_multiplier = (max(min( round(text2num(altered_height)),1000),MIN_BODYSIZE))/100
playsound(user.loc, pshoom_or_beepboopblorpzingshadashwoosh, 40, 1)
do_sparks(5, FALSE, user.loc)
H.visible_message("<span class='danger'>[pick("[H] shifts in size!", "[H] alters in height!", "[H] reshapes into a new stature!")]</span>")
else
return
return
@@ -31,6 +31,7 @@
var/burnstate = 0
var/brute_dam = 0
var/burn_dam = 0
var/pain_dam = 0
var/stamina_dam = 0
var/max_stamina_damage = 0
var/max_damage = 0
@@ -193,6 +194,9 @@
brute_dam += brute
burn_dam += burn
if(status == BODYPART_ORGANIC) //pain is only applied to organic organs, because nerves.
pain_dam += (brute+burn)*1.2 //add the total damage applied to the limb as pain damage, build pain quicker, because sudden pain is more.. painful.
//We've dealt the physical damages, if there's room lets apply the stamina damage.
var/current_damage = get_damage(TRUE) //This time around, count stamina loss too.
var/available_damage = max_damage - current_damage
+8 -3
View File
@@ -172,9 +172,14 @@
// lipstick
if(lip_style)
var/image/lips_overlay = image('icons/mob/human_face.dmi', "lips_[lip_style]", -BODY_LAYER, SOUTH)
lips_overlay.color = lip_color
. += lips_overlay
if (species_id == "human")
var/image/lips_overlay = image('icons/mob/human_face.dmi', "lips_[lip_style]", -BODY_LAYER, SOUTH)
lips_overlay.color = lip_color
. += lips_overlay
else //for animal species, because they have slightly bigger heads.
var/image/lips_overlay = image('icons/mob/human_face.dmi', "lips_[lip_style]_mam", -BODY_LAYER, SOUTH)
lips_overlay.color = lip_color
. += lips_overlay
// eyes
var/image/eyes_overlay = image('icons/mob/human_face.dmi', "eyes", -BODY_LAYER, SOUTH)
+2 -2
View File
@@ -1,8 +1,8 @@
//make incision
/datum/surgery_step/incise
name = "make incision"
implements = list(TOOL_SCALPEL = 100, /obj/item/melee/transforming/energy/sword = 75, /obj/item/kitchen/knife = 65,
/obj/item/shard = 45, /obj/item = 30) // 30% success with any sharp item.
implements = list(TOOL_SCALPEL = 100, /obj/item/melee/transforming/energy/sword = 85, /obj/item/kitchen/knife = 75,
/obj/item/shard = 65, /obj/item = 40) // 40% success with any sharp item. (Hyper change, raised chances with basic items, because if user is awake it has a higher chance to fail)
time = 16
/datum/surgery_step/incise/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+16 -5
View File
@@ -9,6 +9,7 @@
var/list/chems_needed = list() //list of chems needed to complete the step. Even on success, the step will have no effect if there aren't the chems required in the mob.
var/require_all_chems = TRUE //any on the list or all on the list?
var/silicons_obey_prob = FALSE
var/pain_failure = 10 //how painful it is if you fail.
/datum/surgery_step/proc/try_op(mob/user, mob/living/target, target_zone, obj/item/tool, datum/surgery/surgery, try_to_fail = FALSE)
var/success = FALSE
@@ -62,14 +63,21 @@
var/prob_chance = 100
if(implement_type) //this means it isn't a require hand or any item step.
prob_chance = implements[implement_type]
prob_chance *= surgery.get_propability_multiplier()
//if human and awake
if (ishuman(target))
var/mob/living/carbon/human/H = target
if(H.stat == 0) //victorian surgery
prob_chance = prob_chance *0.65 //deminish your chances, they are awake!
if((prob(prob_chance) || (iscyborg(user) && !silicons_obey_prob)) && chem_check(target) && !try_to_fail)
if(success(user, target, target_zone, tool, surgery))
advance = TRUE
else
if(failure(user, target, target_zone, tool, surgery))
advance = TRUE
advance = FALSE
if(advance && !repeatable)
surgery.status++
if(surgery.status > surgery.steps.len)
@@ -83,15 +91,18 @@
"[user] begins to perform surgery on [target].")
/datum/surgery_step/proc/success(mob/user, mob/living/target, target_zone, obj/item/tool, datum/surgery/surgery)
display_results(user, target, "<span class='notice'>You succeed.</span>",
"[user] succeeds!",
display_results(user, target, "<span class='notice'>You complete the procedure.</span>",
"[user] completes the procedure!",
"[user] finishes.")
return TRUE
/datum/surgery_step/proc/failure(mob/user, mob/living/target, target_zone, obj/item/tool, datum/surgery/surgery)
display_results(user, target, "<span class='warning'>You screw up!</span>",
"<span class='warning'>[user] screws up!</span>",
display_results(user, target, "<span class='warning'>You failed the procedure!</span>",
"<span class='warning'>[user] failed the procedure!</span>",
"[user] finishes.", TRUE) //By default the patient will notice if the wrong thing has been cut
if (ishuman(target)) //pain on humans for messing up.
var/obj/item/bodypart/L = target.get_bodypart(target_zone)
L.pain_dam += pain_failure
return FALSE
/datum/surgery_step/proc/tool_check(mob/user, obj/item/tool)
+2 -1
View File
@@ -46,7 +46,8 @@
/obj/item/seeds/tower = 3,
/obj/item/seeds/watermelon = 3,
/obj/item/seeds/wheat = 3,
/obj/item/seeds/whitebeet = 3)
/obj/item/seeds/whitebeet = 3,
/obj/item/seeds/kalyna = 3) //Hyperstation addition
contraband=list(/obj/item/seeds/amanita = 2,
/obj/item/seeds/glowshroom = 2,