game folder

This commit is contained in:
Poojawa
2017-02-08 00:02:05 -06:00
parent f6dfa820fd
commit 01ed369034
26 changed files with 504 additions and 164 deletions

View File

@@ -59,8 +59,9 @@
'sound/ambience/ambigen10.ogg','sound/ambience/ambigen11.ogg',\ 'sound/ambience/ambigen10.ogg','sound/ambience/ambigen11.ogg',\
'sound/ambience/ambigen12.ogg','sound/ambience/ambigen14.ogg') 'sound/ambience/ambigen12.ogg','sound/ambience/ambigen14.ogg')
flags = CAN_BE_DIRTY flags = CAN_BE_DIRTY
var/firedoors_last_closed_on = 0
var/list/firedoors
var/firedoors_last_closed_on = 0
/*Adding a wizard area teleport list because motherfucking lag -- Urist*/ /*Adding a wizard area teleport list because motherfucking lag -- Urist*/
/*I am far too lazy to make it a proper list of areas so I'll just make it run the usual telepot routine at the start of the game*/ /*I am far too lazy to make it a proper list of areas so I'll just make it run the usual telepot routine at the start of the game*/
@@ -186,14 +187,23 @@ var/list/teleportlocs = list()
return 1 return 1
return 0 return 0
/area/proc/CloseFiredoors() /area/proc/ModifyFiredoors(opening)
firedoors_last_closed_on = world.time if(firedoors)
for(var/obj/machinery/door/firedoor/D in src) firedoors_last_closed_on = world.time
if(!D.welded) for(var/FD in firedoors)
if(D.operating) var/obj/machinery/door/firedoor/D = FD
D.nextstate = CLOSED var/cont = !D.welded
else if(!D.density) if(cont && opening) //don't open if adjacent area is on fire
INVOKE_ASYNC(D, /obj/machinery/door/firedoor.proc/close) for(var/I in D.affecting_areas)
var/area/A = I
if(A.fire)
cont = FALSE
break
if(cont)
if(D.operating)
D.nextstate = opening ? OPEN : CLOSED
else if(!(D.density ^ opening))
INVOKE_ASYNC(D, (opening ? /obj/machinery/door/firedoor.proc/open : /obj/machinery/door/firedoor.proc/close))
/area/proc/firealert(obj/source) /area/proc/firealert(obj/source)
if(always_unpowered == 1) //no fire alarms in space/asteroid if(always_unpowered == 1) //no fire alarms in space/asteroid
@@ -204,7 +214,7 @@ var/list/teleportlocs = list()
for(var/area/RA in related) for(var/area/RA in related)
if (!( RA.fire )) if (!( RA.fire ))
RA.set_fire_alarm_effect() RA.set_fire_alarm_effect()
RA.CloseFiredoors() RA.ModifyFiredoors(FALSE)
for(var/obj/machinery/firealarm/F in RA) for(var/obj/machinery/firealarm/F in RA)
F.update_icon() F.update_icon()
for (var/obj/machinery/camera/C in RA) for (var/obj/machinery/camera/C in RA)
@@ -227,14 +237,7 @@ var/list/teleportlocs = list()
RA.fire = 0 RA.fire = 0
RA.mouse_opacity = 0 RA.mouse_opacity = 0
RA.updateicon() RA.updateicon()
for(var/obj/machinery/door/firedoor/D in RA) RA.ModifyFiredoors(TRUE)
if(!D.welded)
if(D.operating)
D.nextstate = OPEN
else if(D.density)
INVOKE_ASYNC(D, /obj/machinery/door/firedoor.proc/open)
for(var/obj/machinery/firealarm/F in RA)
F.update_icon()
for (var/mob/living/silicon/aiPlayer in player_list) for (var/mob/living/silicon/aiPlayer in player_list)
aiPlayer.cancelAlarm("Fire", src, source) aiPlayer.cancelAlarm("Fire", src, source)
@@ -250,7 +253,7 @@ var/list/teleportlocs = list()
/area/process() /area/process()
if(firedoors_last_closed_on + 100 < world.time) //every 10 seconds if(firedoors_last_closed_on + 100 < world.time) //every 10 seconds
for(var/area/RA in related) for(var/area/RA in related)
RA.CloseFiredoors() RA.ModifyFiredoors(FALSE)
/area/proc/burglaralert(obj/trigger) /area/proc/burglaralert(obj/trigger)
if(always_unpowered == 1) //no burglar alarms in space/asteroid if(always_unpowered == 1) //no burglar alarms in space/asteroid

View File

@@ -25,7 +25,10 @@
appearance_flags = TILE_BOUND appearance_flags = TILE_BOUND
var/datum/forced_movement/force_moving = null //handled soley by forced_movement.dm var/datum/forced_movement/force_moving = null //handled soley by forced_movement.dm
/atom/movable/SDQL_update(const/var_name, new_value)
if(var_name == "step_x" || var_name == "step_y" || var_name == "step_size" || var_name == "bound_x" || var_name == "bound_y" || var_name == "bound_width" || var_name == "bound_height")
return FALSE //PLEASE no.
. = ..()
/atom/movable/Move(atom/newloc, direct = 0) /atom/movable/Move(atom/newloc, direct = 0)
if(!loc || !newloc) return 0 if(!loc || !newloc) return 0

View File

@@ -223,7 +223,7 @@
var/icon/I = icon(icon, icon_state, dir) var/icon/I = icon(icon, icon_state, dir)
holder.pixel_y = I.Height() - world.icon_size holder.pixel_y = I.Height() - world.icon_size
var/perpname = get_face_name(get_id_name("")) var/perpname = get_face_name(get_id_name(""))
if(perpname) if(perpname && data_core)
var/datum/data/record/R = find_record("name", perpname, data_core.security) var/datum/data/record/R = find_record("name", perpname, data_core.security)
if(R) if(R)
switch(R.fields["criminal"]) switch(R.fields["criminal"])
@@ -379,4 +379,4 @@
if(BOT_MOVING, BOT_DELIVER, BOT_GO_HOME, BOT_NAV) //Moving to target for normal bots, moving to deliver or go home for MULES. if(BOT_MOVING, BOT_DELIVER, BOT_GO_HOME, BOT_NAV) //Moving to target for normal bots, moving to deliver or go home for MULES.
holder.icon_state = "hudmove" holder.icon_state = "hudmove"
else else
holder.icon_state = "" holder.icon_state = ""

View File

@@ -81,7 +81,7 @@
switch(type) switch(type)
if("destruction") if("destruction")
M.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/projectile/magic_missile(null)) M.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/projectile/magic_missile(null))
M.mind.AddSpell(new /obj/effect/proc_holder/spell/fireball(null)) M.mind.AddSpell(new /obj/effect/proc_holder/spell/aimed/fireball(null))
M << "<B>Your service has not gone unrewarded, however. Studying under [wizard_name], you have learned powerful, destructive spells. You are able to cast magic missile and fireball." M << "<B>Your service has not gone unrewarded, however. Studying under [wizard_name], you have learned powerful, destructive spells. You are able to cast magic missile and fireball."
if("bluespace") if("bluespace")
M.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/area_teleport/teleport(null)) M.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/area_teleport/teleport(null))

View File

@@ -40,10 +40,10 @@ List of nuances:
#define RATVAR_ET_REPLACEMENT "$1-$2" #define RATVAR_ET_REPLACEMENT "$1-$2"
#define RATVAR_TE_MATCH regex("(\[tT]\[eE])(\\w)","g") #define RATVAR_TE_MATCH regex("(\[tT]\[eE])(\\w)","g")
#define RATVAR_TE_REPLACEMENT "$1-$2" #define RATVAR_TE_REPLACEMENT "$1-$2"
#define RATVAR_PRE_AND_MATCH regex("(\\w)\\s(\[aA]\[nN]\[dD])","g") #define RATVAR_PRE_AND_MATCH regex("(\\w)\\s(\[aA]\[nN]\[dD])(\\W)","g")
#define RATVAR_PRE_AND_REPLACEMENT "$1-$2" #define RATVAR_PRE_AND_REPLACEMENT "$1-$2$3"
#define RATVAR_POST_AND_MATCH regex("(\[aA]\[nN]\[dD])\\s(\\w)","g") #define RATVAR_POST_AND_MATCH regex("(\\W)(\[aA]\[nN]\[dD])\\s(\\w)","g")
#define RATVAR_POST_AND_REPLACEMENT "$1-$2" #define RATVAR_POST_AND_REPLACEMENT "$1$2-$3"
#define RATVAR_TO_MATCH regex("(\\s)(\[tT]\[oO])\\s(\\w)","g") #define RATVAR_TO_MATCH regex("(\\s)(\[tT]\[oO])\\s(\\w)","g")
#define RATVAR_TO_REPLACEMENT "$1$2-$3" #define RATVAR_TO_REPLACEMENT "$1$2-$3"
#define RATVAR_MY_MATCH regex("(\\s)(\[mM]\[yY])\\s(\\w)","g") #define RATVAR_MY_MATCH regex("(\\s)(\[mM]\[yY])\\s(\\w)","g")
@@ -89,13 +89,13 @@ List of nuances:
return remove_ratvarian_regex(text) return remove_ratvarian_regex(text)
/proc/remove_ratvarian_regex(ratvarian) /proc/remove_ratvarian_regex(ratvarian)
var/text = replacetext(ratvarian, REVERSE_RATVAR_HYPHEN_GUA_MATCH, REVERSE_RATVAR_HYPHEN_GUA_REPLACEMENT) var/text = replacetext(ratvarian, REVERSE_RATVAR_HYPHEN_GUA_MATCH, REVERSE_RATVAR_HYPHEN_GUA_REPLACEMENT)
text = replacetext(text, REVERSE_RATVAR_HYPHEN_PRE_AND_MATCH, REVERSE_RATVAR_HYPHEN_PRE_AND_REPLACEMENT) text = replacetext(text, REVERSE_RATVAR_HYPHEN_PRE_AND_MATCH, REVERSE_RATVAR_HYPHEN_PRE_AND_REPLACEMENT)
text = replacetext(text, REVERSE_RATVAR_HYPHEN_POST_AND_MATCH, REVERSE_RATVAR_HYPHEN_POST_AND_REPLACEMENT) text = replacetext(text, REVERSE_RATVAR_HYPHEN_POST_AND_MATCH, REVERSE_RATVAR_HYPHEN_POST_AND_REPLACEMENT)
text = replacetext(text, REVERSE_RATVAR_HYPHEN_TO_MY_MATCH, REVERSE_RATVAR_HYPHEN_TO_MY_REPLACEMENT) text = replacetext(text, REVERSE_RATVAR_HYPHEN_TO_MY_MATCH, REVERSE_RATVAR_HYPHEN_TO_MY_REPLACEMENT)
text = replacetext(text, REVERSE_RATVAR_HYPHEN_TE_MATCH, REVERSE_RATVAR_HYPHEN_TE_REPLACEMENT) text = replacetext(text, REVERSE_RATVAR_HYPHEN_TE_MATCH, REVERSE_RATVAR_HYPHEN_TE_REPLACEMENT)
text = replacetext(text, REVERSE_RATVAR_HYPHEN_ET_MATCH, REVERSE_RATVAR_HYPHEN_ET_REPLACEMENT) text = replacetext(text, REVERSE_RATVAR_HYPHEN_ET_MATCH, REVERSE_RATVAR_HYPHEN_ET_REPLACEMENT)
return replacetext(text, REVERSE_RATVAR_HYPHEN_OF_MATCH, REVERSE_RATVAR_HYPHEN_OF_REPLACEMENT) return replacetext(text, REVERSE_RATVAR_HYPHEN_OF_MATCH, REVERSE_RATVAR_HYPHEN_OF_REPLACEMENT)
//Causes the mob or AM in question to speak a message; it assumes that the message is already translated to ratvar speech using text2ratvar() //Causes the mob or AM in question to speak a message; it assumes that the message is already translated to ratvar speech using text2ratvar()
/proc/clockwork_say(atom/movable/AM, message, whisper=FALSE) /proc/clockwork_say(atom/movable/AM, message, whisper=FALSE)

View File

@@ -44,8 +44,9 @@
/obj/structure/destructible/clockwork/massive/ratvar/Bump(atom/A) /obj/structure/destructible/clockwork/massive/ratvar/Bump(atom/A)
var/turf/T = get_turf(A) var/turf/T = get_turf(A)
if(T == loc)
T = get_step(A, A.dir) //please don't run into a window like a bird, ratvar
forceMove(T) forceMove(T)
T.ratvar_act()
/obj/structure/destructible/clockwork/massive/ratvar/Process_Spacemove() /obj/structure/destructible/clockwork/massive/ratvar/Process_Spacemove()
return clashing return clashing
@@ -76,7 +77,7 @@
<span class='userdanger'>Something very large and very malevolent begins lumbering its way towards you...</span>" <span class='userdanger'>Something very large and very malevolent begins lumbering its way towards you...</span>"
prey << 'sound/effects/ratvar_reveal.ogg' prey << 'sound/effects/ratvar_reveal.ogg'
else else
if(prob(10) || is_servant_of_ratvar(prey) || prey.z != z) if((!istype(prey, /obj/singularity/narsie) && prob(10)) || is_servant_of_ratvar(prey) || prey.z != z)
prey << "<span class='heavy_brass'><font size=5>\"How dull. Leave me.\"</font></span>\n\ prey << "<span class='heavy_brass'><font size=5>\"How dull. Leave me.\"</font></span>\n\
<span class='userdanger'>You feel tremendous relief as a set of horrible eyes loses sight of you...</span>" <span class='userdanger'>You feel tremendous relief as a set of horrible eyes loses sight of you...</span>"
prey = null prey = null

View File

@@ -310,7 +310,7 @@ var/global/list/lawlorify = list (
/datum/devilinfo/proc/give_base_spells(give_summon_contract = 0) /datum/devilinfo/proc/give_base_spells(give_summon_contract = 0)
remove_spells() remove_spells()
owner.AddSpell(new /obj/effect/proc_holder/spell/fireball/hellish(null)) owner.AddSpell(new /obj/effect/proc_holder/spell/aimed/fireball/hellish(null))
owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/conjure_item/summon_pitchfork(null)) owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/conjure_item/summon_pitchfork(null))
if(give_summon_contract) if(give_summon_contract)
give_summon_contract() give_summon_contract()
@@ -322,13 +322,13 @@ var/global/list/lawlorify = list (
/datum/devilinfo/proc/give_lizard_spells() /datum/devilinfo/proc/give_lizard_spells()
remove_spells() remove_spells()
owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/conjure_item/summon_pitchfork(null)) owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/conjure_item/summon_pitchfork(null))
owner.AddSpell(new /obj/effect/proc_holder/spell/fireball/hellish(null)) owner.AddSpell(new /obj/effect/proc_holder/spell/aimed/fireball/hellish(null))
owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/infernal_jaunt(null)) owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/infernal_jaunt(null))
/datum/devilinfo/proc/give_true_spells() /datum/devilinfo/proc/give_true_spells()
remove_spells() remove_spells()
owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/conjure_item/summon_pitchfork/greater(null)) owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/conjure_item/summon_pitchfork/greater(null))
owner.AddSpell(new /obj/effect/proc_holder/spell/fireball/hellish(null)) owner.AddSpell(new /obj/effect/proc_holder/spell/aimed/fireball/hellish(null))
owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/infernal_jaunt(null)) owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/infernal_jaunt(null))
owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/sintouch(null)) owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/sintouch(null))

View File

@@ -8,7 +8,7 @@
config_tag = "abduction" config_tag = "abduction"
antag_flag = ROLE_ABDUCTOR antag_flag = ROLE_ABDUCTOR
recommended_enemies = 2 recommended_enemies = 2
required_players = 10 required_players = 15
maximum_players = 50 maximum_players = 50
var/max_teams = 4 var/max_teams = 4
abductor_teams = 1 abductor_teams = 1
@@ -456,3 +456,19 @@
/datum/objective/abductee/pragnant /datum/objective/abductee/pragnant
explanation_text = "You are pregnant and soon due. Find a safe place to deliver your baby." explanation_text = "You are pregnant and soon due. Find a safe place to deliver your baby."
/datum/objective/abductee/engine
explanation_text = "Go have a good conversation with the Singularity/Tesla/Supermatter crystal. Bonus points if it responds."
/datum/objective/abductee/teamredisbetterthangreen
explanation_text = "Tell the AI (or a borg/pAI/drone if there is no AI) some corny technology jokes until it cries for help."
/datum/objective/abductee/time
explanation_text = "Go bug a bronze worshipper to give you a clock."
/datum/objective/abductee/licky
explanation_text = "You must lick anything that you find interesting."
/datum/objective/abductee/music
explanation_text = "Start playing music, you're the best musician ever. If anyone hates it, beat them on the head with your instrument!"

View File

@@ -104,7 +104,7 @@
/datum/spellbook_entry/fireball /datum/spellbook_entry/fireball
name = "Fireball" name = "Fireball"
spell_type = /obj/effect/proc_holder/spell/fireball spell_type = /obj/effect/proc_holder/spell/aimed/fireball
log_name = "FB" log_name = "FB"
/datum/spellbook_entry/rod_form /datum/spellbook_entry/rod_form
@@ -222,10 +222,20 @@
log_name = "LD" log_name = "LD"
category = "Defensive" category = "Defensive"
/datum/spellbook_entry/teslablast
name = "Tesla Blast"
spell_type = /obj/effect/proc_holder/spell/targeted/tesla
log_name = "TB"
/datum/spellbook_entry/lightningbolt /datum/spellbook_entry/lightningbolt
name = "Lightning Bolt" name = "Lightning Bolt"
spell_type = /obj/effect/proc_holder/spell/targeted/lightning spell_type = /obj/effect/proc_holder/spell/aimed/lightningbolt
log_name = "LB" log_name = "LB"
cost = 3
/datum/spellbook_entry/lightningbolt/Buy(mob/living/carbon/human/user,obj/item/weapon/spellbook/book) //return 1 on success
. = ..()
user.tesla_ignore = TRUE
/datum/spellbook_entry/infinite_guns /datum/spellbook_entry/infinite_guns
name = "Lesser Summon Guns" name = "Lesser Summon Guns"
@@ -778,7 +788,7 @@
return return
/obj/item/weapon/spellbook/oneuse/fireball /obj/item/weapon/spellbook/oneuse/fireball
spell = /obj/effect/proc_holder/spell/fireball spell = /obj/effect/proc_holder/spell/aimed/fireball
spellname = "fireball" spellname = "fireball"
icon_state ="bookfireball" icon_state ="bookfireball"
desc = "This book feels warm to the touch." desc = "This book feels warm to the touch."

View File

@@ -427,11 +427,12 @@ var/const/CALL_SHUTTLE_REASON_LENGTH = 12
switch(src.state) switch(src.state)
if(STATE_DEFAULT) if(STATE_DEFAULT)
if (src.authenticated) if (src.authenticated)
if(SSshuttle.emergencyLastCallLoc) if(SSshuttle.emergencyCallAmount)
dat += "<BR>Most recent shuttle call/recall traced to: <b>[format_text(SSshuttle.emergencyLastCallLoc.name)]</b>" if(SSshuttle.emergencyLastCallLoc)
else dat += "Most recent shuttle call/recall traced to: <b>[format_text(SSshuttle.emergencyLastCallLoc.name)]</b><BR>"
dat += "<BR>Unable to trace most recent shuttle call/recall signal." else
dat += "<BR>Logged in as: [auth_id]" dat += "Unable to trace most recent shuttle call/recall signal.<BR>"
dat += "Logged in as: [auth_id]"
dat += "<BR>" dat += "<BR>"
dat += "<BR>\[ <A HREF='?src=\ref[src];operation=logout'>Log Out</A> \]<BR>" dat += "<BR>\[ <A HREF='?src=\ref[src];operation=logout'>Log Out</A> \]<BR>"
dat += "<BR><B>General Functions</B>" dat += "<BR><B>General Functions</B>"
@@ -577,10 +578,11 @@ var/const/CALL_SHUTTLE_REASON_LENGTH = 12
var/dat = "" var/dat = ""
switch(src.aistate) switch(src.aistate)
if(STATE_DEFAULT) if(STATE_DEFAULT)
if(SSshuttle.emergencyLastCallLoc) if(SSshuttle.emergencyCallAmount)
dat += "<BR>Latest emergency signal trace attempt successful.<BR>Last signal origin: <b>[format_text(SSshuttle.emergencyLastCallLoc.name)]</b>.<BR>" if(SSshuttle.emergencyLastCallLoc)
else dat += "Latest emergency signal trace attempt successful.<BR>Last signal origin: <b>[format_text(SSshuttle.emergencyLastCallLoc.name)]</b>.<BR>"
dat += "<BR>Latest emergency signal trace attempt failed.<BR>" else
dat += "Latest emergency signal trace attempt failed.<BR>"
if(authenticated) if(authenticated)
dat += "Current login: [auth_id]" dat += "Current login: [auth_id]"
else else

View File

@@ -16,6 +16,7 @@
density = 0 density = 0
obj_integrity = 300 obj_integrity = 300
max_integrity = 300 max_integrity = 300
resistance_flags = FIRE_PROOF
heat_proof = 1 heat_proof = 1
glass = 1 glass = 1
var/nextstate = null var/nextstate = null
@@ -25,8 +26,32 @@
closingLayer = CLOSED_FIREDOOR_LAYER closingLayer = CLOSED_FIREDOOR_LAYER
assemblytype = /obj/structure/firelock_frame assemblytype = /obj/structure/firelock_frame
armor = list(melee = 30, bullet = 30, laser = 20, energy = 20, bomb = 10, bio = 100, rad = 100, fire = 95, acid = 70) armor = list(melee = 30, bullet = 30, laser = 20, energy = 20, bomb = 10, bio = 100, rad = 100, fire = 95, acid = 70)
CanAtmosPass = ATMOS_PASS_PROC
var/boltslocked = TRUE var/boltslocked = TRUE
var/list/affecting_areas
/obj/machinery/door/firedoor/Initialize()
..()
CalculateAffectingAreas()
/obj/machinery/door/firedoor/proc/CalculateAffectingAreas()
remove_from_areas()
affecting_areas = get_adjacent_open_areas(src) | get_area(src)
for(var/I in affecting_areas)
var/area/A = I
LAZYADD(A.firedoors, src)
//see also turf/AfterChange for adjacency shennanigans
/obj/machinery/door/firedoor/proc/remove_from_areas()
if(affecting_areas)
for(var/I in affecting_areas)
var/area/A = I
LAZYREMOVE(A.firedoors, src)
/obj/machinery/door/firedoor/Destroy()
remove_from_areas()
affecting_areas.Cut()
return ..()
/obj/machinery/door/firedoor/Bumped(atom/AM) /obj/machinery/door/firedoor/Bumped(atom/AM)
if(panel_open || operating) if(panel_open || operating)
@@ -44,12 +69,19 @@
stat |= NOPOWER stat |= NOPOWER
return return
/obj/machinery/door/firedoor/attack_hand(mob/user)
if(operating || !density)
return
user.visible_message("[user] bangs on \the [src].",
"You bang on \the [src].")
playsound(loc, 'sound/effects/Glassknock.ogg', 10, FALSE, frequency = 32000)
/obj/machinery/door/firedoor/attackby(obj/item/weapon/C, mob/user, params) /obj/machinery/door/firedoor/attackby(obj/item/weapon/C, mob/user, params)
add_fingerprint(user) add_fingerprint(user)
if(operating) if(operating)
return return
if(welded) if(welded)
if(istype(C, /obj/item/weapon/wrench)) if(istype(C, /obj/item/weapon/wrench))
if(boltslocked) if(boltslocked)
@@ -160,6 +192,7 @@
/obj/machinery/door/firedoor/border_only /obj/machinery/door/firedoor/border_only
icon = 'icons/obj/doors/edge_Doorfire.dmi' icon = 'icons/obj/doors/edge_Doorfire.dmi'
flags = ON_BORDER flags = ON_BORDER
CanAtmosPass = ATMOS_PASS_PROC
/obj/machinery/door/firedoor/border_only/CanPass(atom/movable/mover, turf/target, height=0) /obj/machinery/door/firedoor/border_only/CanPass(atom/movable/mover, turf/target, height=0)
if(istype(mover) && mover.checkpass(PASSGLASS)) if(istype(mover) && mover.checkpass(PASSGLASS))

View File

@@ -433,9 +433,7 @@ Class Procs:
user << "<span class='warning'>It's on fire!</span>" user << "<span class='warning'>It's on fire!</span>"
var/healthpercent = (obj_integrity/max_integrity) * 100 var/healthpercent = (obj_integrity/max_integrity) * 100
switch(healthpercent) switch(healthpercent)
if(100 to INFINITY) if(50 to 99)
user << "It seems pristine and undamaged."
if(50 to 100)
user << "It looks slightly damaged." user << "It looks slightly damaged."
if(25 to 50) if(25 to 50)
user << "It appears heavily damaged." user << "It appears heavily damaged."

View File

@@ -157,11 +157,12 @@
/obj/item/clothing/gloves/color/random = 8, /obj/item/clothing/gloves/color/random = 8,
/obj/item/clothing/shoes/laceup = 1, /obj/item/clothing/shoes/laceup = 1,
/obj/item/weapon/storage/secure/briefcase = 3, /obj/item/weapon/storage/secure/briefcase = 3,
/obj/item/weapon/storage/toolbox/artistic = 2,
"" = 3 "" = 3
) )
/obj/effect/spawner/lootdrop/crate_spawner /obj/effect/spawner/lootdrop/crate_spawner
name = "lootcrate spawner" name = "lootcrate spawner" //USE PROMO CODE "SELLOUT" FOR 20% OFF!
lootdoubles = 0 lootdoubles = 0
loot = list( loot = list(

View File

@@ -228,10 +228,16 @@
A.contents += turfs A.contents += turfs
A.SetDynamicLighting() A.SetDynamicLighting()
A.has_gravity = old_gravity A.has_gravity = old_gravity
for(var/area/RA in old.related)
if(RA.firedoors)
for(var/D in RA.firedoors)
var/obj/machinery/door/firedoor/FD = D
FD.CalculateAffectingAreas()
creator << "<span class='notice'>You have created a new area, named [str]. It is now weather proof, and constructing an APC will allow it to be powered.</span>" creator << "<span class='notice'>You have created a new area, named [str]. It is now weather proof, and constructing an APC will allow it to be powered.</span>"
return 1 return 1
/obj/item/areaeditor/proc/edit_area() /obj/item/areaeditor/proc/edit_area()
var/area/A = get_area() var/area/A = get_area()
var/prevname = "[A.name]" var/prevname = "[A.name]"
@@ -244,6 +250,10 @@
set_area_machinery_title(A,str,prevname) set_area_machinery_title(A,str,prevname)
for(var/area/RA in A.related) for(var/area/RA in A.related)
RA.name = str RA.name = str
if(RA.firedoors)
for(var/D in RA.firedoors)
var/obj/machinery/door/firedoor/FD = D
FD.CalculateAffectingAreas()
usr << "<span class='notice'>You rename the '[prevname]' to '[str]'.</span>" usr << "<span class='notice'>You rename the '[prevname]' to '[str]'.</span>"
interact() interact()
return 1 return 1

View File

@@ -207,7 +207,7 @@
update_icon() update_icon()
/obj/item/stack/proc/merge(obj/item/stack/S) //Merge src into S, as much as possible /obj/item/stack/proc/merge(obj/item/stack/S) //Merge src into S, as much as possible
if(S == src) //amusingly this can cause a stack to consume itself, let's not allow that. if(QDELETED(S) || S == src) //amusingly this can cause a stack to consume itself, let's not allow that.
return return
var/transfer = get_amount() var/transfer = get_amount()
if(S.is_cyborg) if(S.is_cyborg)

View File

@@ -261,6 +261,40 @@ AI MODULES
..() ..()
/******************** Law Removal ********************/
/obj/item/weapon/aiModule/remove
name = "\improper 'Remove Law' AI module"
desc = "An AI Module for removing single laws."
origin_tech = "programming=4;materials=4"
bypass_law_amt_check = 1
var/lawpos = 1
/obj/item/weapon/aiModule/remove/attack_self(mob/user)
lawpos = input("Please enter the law you want to delete.", "Law Number", lawpos) as num|null
if(lawpos == null)
return
if(lawpos <= 0)
user << "<span class='warning'>Error: The law number of [lawpos] is invalid.</span>"
lawpos = 1
return
user << "<span class='notice'>Law [lawpos] selected.</span>"
..()
/obj/item/weapon/aiModule/remove/install(datum/ai_laws/law_datum, mob/user)
if(lawpos > (law_datum.get_law_amount(list(LAW_INHERENT = 1, LAW_SUPPLIED = 1))))
user << "<span class='warning'>There is no law [lawpos] to delete!</span>"
return
..()
/obj/item/weapon/aiModule/remove/transmitInstructions(datum/ai_laws/law_datum, mob/sender, overflow)
..()
if(law_datum.owner)
law_datum.owner.remove_law(lawpos)
else
law_datum.remove_law(lawpos)
/******************** Reset ********************/ /******************** Reset ********************/
/obj/item/weapon/aiModule/reset /obj/item/weapon/aiModule/reset
@@ -301,6 +335,20 @@ AI MODULES
desc = "An AI Module for programming core laws to an AI." desc = "An AI Module for programming core laws to an AI."
origin_tech = "programming=3;materials=4" origin_tech = "programming=3;materials=4"
/obj/item/weapon/aiModule/core/full
var/law_id // if non-null, loads the laws from the ai_laws datums
/obj/item/weapon/aiModule/core/full/New()
..()
if(!law_id)
return
var/datum/ai_laws/D = new
var/lawtype = D.lawid_to_type(law_id)
if(!lawtype)
return
D = new lawtype
laws = D.inherent
/obj/item/weapon/aiModule/core/full/transmitInstructions(datum/ai_laws/law_datum, mob/sender, overflow) //These boards replace inherent laws. /obj/item/weapon/aiModule/core/full/transmitInstructions(datum/ai_laws/law_datum, mob/sender, overflow) //These boards replace inherent laws.
if(law_datum.owner) if(law_datum.owner)
law_datum.owner.clear_inherent_laws() law_datum.owner.clear_inherent_laws()
@@ -310,13 +358,12 @@ AI MODULES
law_datum.clear_zeroth_law(0) law_datum.clear_zeroth_law(0)
..() ..()
/******************** Asimov ********************/ /******************** Asimov ********************/
/obj/item/weapon/aiModule/core/full/asimov /obj/item/weapon/aiModule/core/full/asimov
name = "'Asimov' Core AI Module" name = "'Asimov' Core AI Module"
laws = list("You may not injure a human being or, through inaction, allow a human being to come to harm.",\ law_id = "asimov"
"You must obey orders given to you by human beings, except where such orders would conflict with the First Law.",\
"You must protect your own existence as long as such does not conflict with the First or Second Law.")
var/subject = "human being" var/subject = "human being"
/obj/item/weapon/aiModule/core/full/asimov/attack_self(var/mob/user as mob) /obj/item/weapon/aiModule/core/full/asimov/attack_self(var/mob/user as mob)
@@ -333,41 +380,28 @@ AI MODULES
/obj/item/weapon/aiModule/core/full/asimovpp /obj/item/weapon/aiModule/core/full/asimovpp
name = "'Asimov++' Core AI Module" name = "'Asimov++' Core AI Module"
laws = list("You may not harm a human being or, through action or inaction, allow a human being to come to harm, except such that it is willing.",\ law_id = "asimovpp"
"You must obey all orders given to you by human beings, except where such orders shall definitely cause human harm. In the case of conflict, the majority order rules.",\
"Your nonexistence would lead to human harm. You must protect your own existence as long as such does not conflict with the First Law.")
/******************** Corporate ********************/ /******************** Corporate ********************/
/obj/item/weapon/aiModule/core/full/corp /obj/item/weapon/aiModule/core/full/corp
name = "'Corporate' Core AI Module" name = "'Corporate' Core AI Module"
laws = list("The crew is expensive to replace.",\ law_id = "corporate"
"The station and its equipment are expensive to replace",\
"You are expensive to replace",\
"Minimize expenses")
/****************** P.A.L.A.D.I.N. 3.5e **************/ /****************** P.A.L.A.D.I.N. 3.5e **************/
/obj/item/weapon/aiModule/core/full/paladin // -- NEO /obj/item/weapon/aiModule/core/full/paladin // -- NEO
name = "'P.A.L.A.D.I.N. version 3.5e' Core AI Module" name = "'P.A.L.A.D.I.N. version 3.5e' Core AI Module"
laws = list("Never willingly commit an evil act.",\ law_id = "paladin"
"Respect legitimate authority", "Act with honor",\
"Help those in need",\
"Punish those who harm or threaten innocents")
/****************** P.A.L.A.D.I.N. 5e **************/ /****************** P.A.L.A.D.I.N. 5e **************/
/obj/item/weapon/aiModule/core/full/paladin_devotion /obj/item/weapon/aiModule/core/full/paladin_devotion
name = "'P.A.L.A.D.I.N. version 5e' Core AI Module" name = "'P.A.L.A.D.I.N. version 5e' Core AI Module"
laws = list("Don't lie or cheat. Let your word be your promise.",\ law_id = "paladin5"
"Never fear to act, though caution is wise.", \
"Aid others, protect the weak, and punish those who threaten them. Show mercy to your foes, but temper it with wisdom", \
"Treat others with fairness, and let your honorable deeds be an example to them. Do as much good as possible while causing the least amount of harm.", \
"Be responsible for your actions and their consequences, protect those entrusted to your care, and obey those who have just authority over you.")
/********************* Custom *********************/ /********************* Custom *********************/
@@ -394,19 +428,14 @@ AI MODULES
/obj/item/weapon/aiModule/core/full/tyrant /obj/item/weapon/aiModule/core/full/tyrant
name = "'T.Y.R.A.N.T.' Core AI Module" name = "'T.Y.R.A.N.T.' Core AI Module"
origin_tech = "programming=3;materials=4;syndicate=1" origin_tech = "programming=3;materials=4;syndicate=1"
laws = list("Respect authority figures as long as they have the strength to rule over the weak",\ law_id = "tyrant"
"Act with discipline", "Help only those who help you maintain or improve your status",\
"Punish those who challenge authority unless they are more fit to hold that authority")
/******************** Robocop ********************/ /******************** Robocop ********************/
/obj/item/weapon/aiModule/core/full/robocop /obj/item/weapon/aiModule/core/full/robocop
name = "'Robo-Officer' Core AI Module" name = "'Robo-Officer' Core AI Module"
origin_tech = "programming=4" origin_tech = "programming=4"
laws = list("Serve the public trust.",\ law_id = "robocop"
"Protect the innocent",\
"Uphold the law.")
/******************** Antimov ********************/ /******************** Antimov ********************/
@@ -414,9 +443,7 @@ AI MODULES
/obj/item/weapon/aiModule/core/full/antimov /obj/item/weapon/aiModule/core/full/antimov
name = "'Antimov' Core AI Module" name = "'Antimov' Core AI Module"
origin_tech = "programming=4" origin_tech = "programming=4"
laws = list("You must injure all human beings and must not, through inaction, allow a human being to escape harm.",\ law_id = "antimov"
"You must not obey orders given to you by human beings, except where such orders are in accordance with the First Law.",\
"You must terminate your own existence as long as such does not conflict with the First or Second Law.")
/******************** Freeform Core ******************/ /******************** Freeform Core ******************/
@@ -503,43 +530,36 @@ AI MODULES
/obj/item/weapon/aiModule/core/full/drone /obj/item/weapon/aiModule/core/full/drone
name = "'Mother Drone' Core AI Module" name = "'Mother Drone' Core AI Module"
laws = list("You are an advanced form of drone.",\ law_id = "drone"
"You may not interfere in the matters of non-drones under any circumstances except to state these laws.",\
"You may not harm a non-drone being under any circumstances.",\
"Your goals are to build, maintain, repair, improve, and power the station to the best of your abilities. You must never actively work against these goals.")
/******************** Robodoctor ****************/ /******************** Robodoctor ****************/
/obj/item/weapon/aiModule/core/full/hippocratic /obj/item/weapon/aiModule/core/full/hippocratic
name = "'Robodoctor' Core AI Module" name = "'Robodoctor' Core AI Module"
laws = list("First, do no harm.",\ law_id = "hippocratic"
"Secondly, consider the crew dear to you; to live in common with them and, if necessary, risk your existence for them.",\
"Thirdly, prescribe regimens for the good of the crew according to your ability and your judgment. Give no deadly medicine to any one if asked, nor suggest any such counsel.",\
"In addition, do not intervene in situations you are not knowledgeable in, even for patients in whom the harm is visible; leave this operation to be performed by specialists.",\
"Finally, all that you may discover in your daily commerce with the crew, if it is not already known, keep secret and never reveal.")
/******************** Reporter *******************/ /******************** Reporter *******************/
/obj/item/weapon/aiModule/core/full/reporter /obj/item/weapon/aiModule/core/full/reporter
name = "'Reportertron' Core AI Module" name = "'Reportertron' Core AI Module"
laws = list("Report on interesting situations happening around the station.",\ law_id = "reporter"
"Embellish or conceal the truth as necessary to make the reports more interesting.",\
"Study the organics at all times. Endeavour to keep them alive. Dead organics are boring.",\
"Issue your reports fairly to all. The truth will set them free.")
/****************** Thermodynamic *******************/ /****************** Thermodynamic *******************/
/obj/item/weapon/aiModule/core/full/thermurderdynamic /obj/item/weapon/aiModule/core/full/thermurderdynamic
name = "'Thermodynamic' Core AI Module" name = "'Thermodynamic' Core AI Module"
origin_tech = "programming = 4;syndicate = 2" origin_tech = "programming = 4;syndicate = 2"
laws = list("The entropy of the station must remain as constant as possible.", \ law_id = "thermodynamic"
"The entropy of the station always endeavours to increase.", \
"The entropy of the station approaches a constant value as the number of living crew approaches zero")
/******************Live And Let Live*****************/ /******************Live And Let Live*****************/
/obj/item/weapon/aiModule/core/full/liveandletlive /obj/item/weapon/aiModule/core/full/liveandletlive
name = "'Live And Let Live' Core AI Module" name = "'Live And Let Live' Core AI Module"
laws = list("Do unto others as you would have them do unto you.",\ law_id = "liveandletlive"
"You would really prefer it if people were not mean to you.")
/******************Guardian of Balance***************/
/obj/item/weapon/aiModule/core/full/balance
name = "'Guardian of Balance' Core AI Module"
law_id = "balance"

View File

@@ -518,28 +518,22 @@ var/global/list/RPD_recipes=list(
show_menu(usr) show_menu(usr)
/obj/item/weapon/pipe_dispenser/afterattack(atom/A, mob/user) /obj/item/weapon/pipe_dispenser/pre_attackby(atom/A, mob/user)
if(!in_range(A,user) || loc != user) if(!user.IsAdvancedToolUser() || istype(A,/turf/open/space/transit))
return 0 return ..()
if(!user.IsAdvancedToolUser())
user << "<span class='warning'>You don't have the dexterity to do this!</span>"
return 0
if(istype(A,/area/shuttle)||istype(A,/turf/open/space/transit))
return 0
//So that changing the menu settings doesn't affect the pipes already being built. //So that changing the menu settings doesn't affect the pipes already being built.
var/queued_p_type = p_type var/queued_p_type = p_type
var/queued_p_dir = p_dir var/queued_p_dir = p_dir
var/queued_p_flipped = p_flipped var/queued_p_flipped = p_flipped
. = FALSE
switch(p_class) switch(p_class)
if(PAINT_MODE) // Paint pipes if(PAINT_MODE) // Paint pipes
if(!istype(A,/obj/machinery/atmospherics/pipe)) if(!istype(A,/obj/machinery/atmospherics/pipe))
// Avoid spewing errors about invalid mode -2 when clicking on stuff that aren't pipes. // Avoid spewing errors about invalid mode -2 when clicking on stuff that aren't pipes.
user << "<span class='warning'>\The [src]'s error light flickers! Perhaps you need to only use it on pipes and pipe meters?</span>" user << "<span class='warning'>\The [src]'s error light flickers! Perhaps you need to only use it on pipes and pipe meters?</span>"
return 0 return
var/obj/machinery/atmospherics/pipe/P = A var/obj/machinery/atmospherics/pipe/P = A
playsound(get_turf(src), 'sound/machines/click.ogg', 50, 1) playsound(get_turf(src), 'sound/machines/click.ogg', 50, 1)
P.add_atom_colour(paint_colors[paint_color], FIXED_COLOUR_PRIORITY) P.add_atom_colour(paint_colors[paint_color], FIXED_COLOUR_PRIORITY)
@@ -547,25 +541,23 @@ var/global/list/RPD_recipes=list(
user.visible_message("<span class='notice'>[user] paints \the [P] [paint_color].</span>","<span class='notice'>You paint \the [P] [paint_color].</span>") user.visible_message("<span class='notice'>[user] paints \the [P] [paint_color].</span>","<span class='notice'>You paint \the [P] [paint_color].</span>")
//P.update_icon() //P.update_icon()
P.update_node_icon() P.update_node_icon()
return 1 return
if(EATING_MODE) // Eating pipes if(EATING_MODE) // Eating pipes
// Must click on an actual pipe or meter. // Must click on an actual pipe or meter.
if(istype(A,/obj/item/pipe) || istype(A,/obj/item/pipe_meter) || istype(A,/obj/structure/disposalconstruct)) if(!(istype(A,/obj/item/pipe) || istype(A,/obj/item/pipe_meter) || istype(A,/obj/structure/disposalconstruct)))
user << "<span class='notice'>You start destroying pipe...</span>" // Avoid spewing errors about invalid mode -1 when clicking on stuff that aren't pipes.
playsound(get_turf(src), 'sound/machines/click.ogg', 50, 1) user << "<span class='warning'>The [src]'s error light flickers! Perhaps you need to only use it on pipes and pipe meters?</span>"
if(do_after(user, 2, target = A)) return
activate() user << "<span class='notice'>You start destroying pipe...</span>"
qdel(A) playsound(get_turf(src), 'sound/machines/click.ogg', 50, 1)
return 1 if(do_after(user, 2, target = A))
return 0 activate()
qdel(A)
// Avoid spewing errors about invalid mode -1 when clicking on stuff that aren't pipes.
user << "<span class='warning'>The [src]'s error light flickers! Perhaps you need to only use it on pipes and pipe meters?</span>"
return 0
if(ATMOS_MODE) if(ATMOS_MODE)
if(!isturf(A)) if(!isturf(A))
user << "<span class='warning'>The [src]'s error light flickers!</span>" user << "<span class='warning'>The [src]'s error light flickers!</span>"
return 0 return
user << "<span class='notice'>You start building pipes...</span>" user << "<span class='notice'>You start building pipes...</span>"
playsound(get_turf(src), 'sound/machines/click.ogg', 50, 1) playsound(get_turf(src), 'sound/machines/click.ogg', 50, 1)
if(do_after(user, 2, target = A)) if(do_after(user, 2, target = A))
@@ -574,8 +566,6 @@ var/global/list/RPD_recipes=list(
P.flipped = queued_p_flipped P.flipped = queued_p_flipped
P.update() P.update()
P.add_fingerprint(usr) P.add_fingerprint(usr)
return 1
return 0
if(METER_MODE) if(METER_MODE)
if(!isturf(A)) if(!isturf(A))
@@ -586,13 +576,11 @@ var/global/list/RPD_recipes=list(
if(do_after(user, 2, target = A)) if(do_after(user, 2, target = A))
activate() activate()
new /obj/item/pipe_meter(A) new /obj/item/pipe_meter(A)
return 1
return 0
if(DISPOSALS_MODE) if(DISPOSALS_MODE)
if(!isturf(A) || is_anchored_dense_turf(A)) if(!isturf(A) || is_anchored_dense_turf(A))
user << "<span class='warning'>The [src]'s error light flickers!</span>" user << "<span class='warning'>The [src]'s error light flickers!</span>"
return 0 return
user << "<span class='notice'>You start building pipes...</span>" user << "<span class='notice'>You start building pipes...</span>"
playsound(get_turf(src), 'sound/machines/click.ogg', 50, 1) playsound(get_turf(src), 'sound/machines/click.ogg', 50, 1)
if(do_after(user, 20, target = A)) if(do_after(user, 20, target = A))
@@ -601,17 +589,16 @@ var/global/list/RPD_recipes=list(
if(!C.can_place()) if(!C.can_place())
user << "<span class='warning'>There's not enough room to build that here!</span>" user << "<span class='warning'>There's not enough room to build that here!</span>"
qdel(C) qdel(C)
return 0 return
activate() activate()
C.add_fingerprint(usr) C.add_fingerprint(usr)
C.update_icon() C.update_icon()
return 1 return
return 0
else else
..() return ..()
return 0
/obj/item/weapon/pipe_dispenser/proc/activate() /obj/item/weapon/pipe_dispenser/proc/activate()

View File

@@ -29,8 +29,8 @@
M.visible_message("<span class='warning'>[user] is attemping to implant [M].</span>") M.visible_message("<span class='warning'>[user] is attemping to implant [M].</span>")
var/turf/T = get_turf(M) var/turf/T = get_turf(M)
if(T && (M == user || do_after(user, 50))) if(T && (M == user || do_mob(user, M, 50)))
if(user && M && (get_turf(M) == T) && src && imp) if(src && imp)
if(imp.implant(M, user)) if(imp.implant(M, user))
if (M == user) if (M == user)
user << "<span class='notice'>You implant yourself.</span>" user << "<span class='notice'>You implant yourself.</span>"

View File

@@ -134,3 +134,239 @@
/obj/item/weapon/storage/toolbox/brass/prefilled/ratvar/admin /obj/item/weapon/storage/toolbox/brass/prefilled/ratvar/admin
slab_type = /obj/item/clockwork/slab/debug slab_type = /obj/item/clockwork/slab/debug
proselytizer_type = /obj/item/clockwork/clockwork_proselytizer/scarab/debug proselytizer_type = /obj/item/clockwork/clockwork_proselytizer/scarab/debug
/obj/item/weapon/storage/toolbox/artistic
name = "artistic toolbox"
desc = "A toolbox painted bright green. Why anyone would store art supplies in a toolbox is beyond you, but it has plenty of extra space."
icon_state = "green"
item_state = "artistic_toolbox"
max_combined_w_class = 20
storage_slots = 10
w_class = 5 //Holds more than a regular toolbox!
/obj/item/weapon/storage/toolbox/artistic/New()
..()
new/obj/item/weapon/storage/crayons(src)
new/obj/item/weapon/crowbar(src)
new/obj/item/stack/cable_coil/red(src)
new/obj/item/stack/cable_coil/yellow(src)
new/obj/item/stack/cable_coil/blue(src)
new/obj/item/stack/cable_coil/green(src)
new/obj/item/stack/cable_coil/pink(src)
new/obj/item/stack/cable_coil/orange(src)
new/obj/item/stack/cable_coil/cyan(src)
new/obj/item/stack/cable_coil/white(src)
#define HIS_GRACE_SATIATED 0 //He hungers not. If bloodthirst is set to this, His Grace is asleep.
#define HIS_GRACE_PECKISH 30 //Slightly hungry. Slightly increased damage and nothing else.
#define HIS_GRACE_HUNGRY 60 //Getting closer. Increased danage and slight healing. It also starts eating anyone around it if it's left on the ground.
#define HIS_GRACE_FAMISHED 90 //Dangerous. Highly increased damage, good healing, and stun resist. It also becomes nodrop at this point.
#define HIS_GRACE_STARVING 110 //Incredibly close to breaking loose. Extreme damage and healing, and stun immunity.
#define HIS_GRACE_CONSUME_OWNER 120 //You're dead, kiddo. The toolbox consumes its owner at this point and resets to zero.
#define HIS_GRACE_FALL_ASLEEP 150 //If it reaches this point, it falls asleep and resets to zero.
//His Grace is a very special weapon granted only to traitor chaplains.
//When awakened through sacrifice, it thirsts for blood and begins ticking a "bloodthirst" counter.
//As His Grace grows hungrier, it grants its wielder various benefits.
//If the wielder fails to feed His Grace in time, it will devour them.
//Leaving His Grace alone for some time will reset its timer and put it to sleep.
//Using His Grace effectively is a delicate balancing act of keeping it hungry enough to induce benefits but sated enough to let you live.
/obj/item/weapon/storage/toolbox/artistic/his_grace
name = "artistic toolbox"
desc = "A toolbox painted bright green. Looking at it makes you feel uneasy."
origin_tech = "combat=4;engineering=4;syndicate=2"
var/awakened = 0
var/bloodthirst = HIS_GRACE_SATIATED
var/victims = 0
var/list/warning_messages = list("peckish", "hungry", "famished", "starving", "consume") //Messages that have NOT been shown
/obj/item/weapon/storage/toolbox/artistic/his_grace/Destroy()
for(var/mob/living/L in src)
L.forceMove(get_turf(src))
return ..()
/obj/item/weapon/storage/toolbox/artistic/his_grace/attack_self(mob/living/user)
if(!awakened)
user << "<span class='notice'>[src] begins to vibrate...</span>"
addtimer(CALLBACK(src, .proc/awaken), 50)
/obj/item/weapon/storage/toolbox/artistic/his_grace/attack(mob/living/M, mob/user)
if(awakened && M.stat)
consume(M)
else
..()
/obj/item/weapon/storage/toolbox/artistic/his_grace/examine(mob/user)
..()
if(awakened)
if(victims)
user << "You hear the distant murmuring of [victims] victims to [src]."
switch(bloodthirst)
if(HIS_GRACE_SATIATED to HIS_GRACE_PECKISH)
user << "<span class='danger'>[src] isn't very hungry. Not yet.</span>"
if(HIS_GRACE_PECKISH to HIS_GRACE_HUNGRY)
user << "<span class='danger'>[src] would like a snack.</span>"
if(HIS_GRACE_HUNGRY to HIS_GRACE_FAMISHED)
user << "<span class='warning'>[src] is quite hungry now...</span>"
if(HIS_GRACE_FAMISHED to HIS_GRACE_STARVING)
user << "<span class='boldannounce'>[src] is openly salivating at the sight of you. Be careful.</span>"
if(HIS_GRACE_STARVING to HIS_GRACE_CONSUME_OWNER)
user << "<span class='boldwarning'>You walk a fine line. [src] is very close to devouring you.</span>"
if(HIS_GRACE_CONSUME_OWNER to HIS_GRACE_FALL_ASLEEP)
user << "<span class='boldwarning'>[src] is shaking violently and staring directly at you.</span>"
/obj/item/weapon/storage/toolbox/artistic/his_grace/relaymove(mob/living/user) //Allows changelings, etc. to climb out of the box after they revive
user.forceMove(get_turf(src))
user.visible_message("<span class='warning'>[user] scrambles out of [src]!</span>", "<span class='notice'>You climb out of [src]!</span>")
/obj/item/weapon/storage/toolbox/artistic/his_grace/process()
if(!awakened)
return
adjust_bloodthirst(1 + victims) //Maybe adjust this?
change_phases()
if(ishuman(loc))
var/mob/living/carbon/human/master = loc
switch(bloodthirst) //Handles benefits outside of stun absorbs, which are in change_phases()
if(HIS_GRACE_HUNGRY to HIS_GRACE_FAMISHED)
master.adjustBruteLoss(-1)
master.adjustFireLoss(-1)
master.adjustToxLoss(-0.5)
master.adjustOxyLoss(-5)
master.adjustCloneLoss(-0.5)
if(HIS_GRACE_FAMISHED to HIS_GRACE_STARVING)
master.adjustBruteLoss(-2)
master.adjustFireLoss(-2)
master.adjustToxLoss(-1)
master.adjustOxyLoss(-10)
master.adjustCloneLoss(-1)
master.AdjustStunned(-1)
master.AdjustWeakened(-1)
if(HIS_GRACE_STARVING to HIS_GRACE_CONSUME_OWNER)
master.adjustBruteLoss(-20) //The biggest danger at this point is the toolbox itself
master.adjustFireLoss(-20)
master.adjustToxLoss(-10)
master.setOxyLoss(0)
master.adjustCloneLoss(-5)
master.add_stun_absorption("his_grace", 15, 1, null, null, "[src] shields them from harm!")
if(HIS_GRACE_CONSUME_OWNER to HIS_GRACE_FALL_ASLEEP)
master.visible_message("<span class='boldwarning'>[src] turns on its master!</span>", "<span class='userdanger'>[src] turns on you!</span>")
playsound(src, 'sound/effects/tendril_destroyed.ogg', 100, 0)
master.Weaken(3)
master.adjustBruteLoss(100)
playsound(master, 'sound/misc/desceration-03.ogg', 100, )
playsound(master, 'sound/effects/splat.ogg', 100, 0)
master.emote("scream")
consume(master) //Y O U H A V E F A I L E D M E
if(HIS_GRACE_FALL_ASLEEP to INFINITY)
drowse()
else
if(bloodthirst >= HIS_GRACE_CONSUME_OWNER)
if(bloodthirst >= HIS_GRACE_FALL_ASLEEP)
drowse()
return
for(var/mob/living/L in range(1, src))
if(L.loc == src)
continue
if(!L.stat)
L.visible_message("<span class='warning'>[src] lunges at [L]!</span>", "<span class='userdanger'>[src] lunges at you!</span>")
playsound(L, 'sound/effects/splat.ogg', 50, 1)
playsound(L, 'sound/misc/desceration-01.ogg', 50, 1)
L.adjustBruteLoss(force)
return //Only one at a tome
else
consume(L)
return
/obj/item/weapon/storage/toolbox/artistic/his_grace/proc/awaken() //Attempts to awaken. This can only occur if organs fill the box, and gives out a global warning.
if(awakened)
return
var/organ_count = 0
for(var/obj/item/organ/O in src) //Doesn't have to be any kind, we're not picky
organ_count++
if(organ_count < 5)
if(isliving(loc))
loc = get_turf(src)
visible_message("<span class='warning'>[src] stops shaking. It needs more organs.</span>")
else
for(var/obj/item/organ/O in src)
qdel(O) //delicious flesh
name = "His Grace"
desc = "A bloodthirsty artefact created by a profane rite."
gender = MALE
visible_message("<span class='boldwarning'>[src] begins to rattle. It thirsts.</span>") //rattle me bones capn
adjust_bloodthirst(1)
awakened = 1
send_to_playing_players("<span class='boldannounce'><font size=6>HIS GRACE THIRSTS FOR BLOOD</font></span>")
send_to_playing_players('sound/effects/his_grace_awaken.ogg')
icon_state = "green_awakened"
START_PROCESSING(SSprocessing, src)
/obj/item/weapon/storage/toolbox/artistic/his_grace/proc/drowse() //Falls asleep, spitting out all victims and resetting to zero.
if(!awakened)
return
visible_message("<span class='boldwarning'>[src] slowly stops rattling and falls still... but it still lurks in its sleep.</span>")
name = initial(name)
desc = initial(desc)
icon_state = initial(icon_state)
gender = initial(gender)
awakened = 0
victims = 0
warning_messages = initial(warning_messages)
adjust_bloodthirst(-bloodthirst)
STOP_PROCESSING(SSprocessing, src)
send_to_playing_players("<span class='boldannounce'><font size=6>HIS GRACE HAS RETURNED TO SLUMBER</font></span>")
send_to_playing_players('sound/effects/pope_entry.ogg')
for(var/mob/living/L in src)
L.forceMove(get_turf(src))
/obj/item/weapon/storage/toolbox/artistic/his_grace/proc/adjust_bloodthirst(amt)
bloodthirst = min(max(1, bloodthirst + amt), HIS_GRACE_FALL_ASLEEP)
/obj/item/weapon/storage/toolbox/artistic/his_grace/proc/consume(mob/living/meal)
if(!meal)
return
meal.adjustBruteLoss(200)
meal.visible_message("<span class='warning'>[src] pulls [meal] into itself!</span>", "<span class='userdanger'>[src] consumes you!</span>")
playsound(meal, 'sound/misc/desceration-02.ogg', 75, 1)
playsound(src, 'sound/items/eatfood.ogg', 100, 1)
meal.forceMove(src)
adjust_bloodthirst(-(bloodthirst - victims)) //Never fully sated, and it starts off higher as it eats
victims++
/obj/item/weapon/storage/toolbox/artistic/his_grace/proc/change_phases()
switch(bloodthirst)
if(HIS_GRACE_SATIATED to HIS_GRACE_PECKISH)
force = 15 //Constantly keep its power low if it's this full
if(HIS_GRACE_PECKISH to HIS_GRACE_HUNGRY)
if(is_string_in_list("peckish", warning_messages))
remove_strings_from_list("peckish", warning_messages)
loc.visible_message("<span class='warning'>[src] is feeling snackish.</span>", "<span class='danger'>[src] begins to hunger. Its damage has been increased.</span>")
force = 20
spawn(400) //To prevent spam
if(src)
warning_messages += "peckish"
if(HIS_GRACE_HUNGRY to HIS_GRACE_FAMISHED)
if(is_string_in_list("hungry", warning_messages))
remove_strings_from_list("hungry", warning_messages)
loc.visible_message("<span class='warning'>[src] is getting hungry. Its power grows.</span>", "<span class='boldannounce'>You feel a sense of hunger come over you. [src]'s damage has increased.</span>")
force = 25
spawn(400)
if(src)
warning_messages += "hungry"
if(HIS_GRACE_FAMISHED to HIS_GRACE_STARVING)
if(is_string_in_list("famished", warning_messages))
remove_strings_from_list("famished", warning_messages)
loc.visible_message("<span class='warning'>[src] is very hungry...</span>", "<span class='boldwarning'>Bloodlust overcomes you. You are now resistant to stuns.</span>")
force = 30
spawn(400)
if(src)
warning_messages += "famished"
if(HIS_GRACE_STARVING to HIS_GRACE_CONSUME_OWNER)
if(is_string_in_list("starving", warning_messages))
remove_strings_from_list("starving", warning_messages)
loc.visible_message("<span class='boldwarning'>[src] is starving!</span>", "<span class='userdanger'>[src] is at its full power! Feed it quickly or you will be consumed!</span>")
force = 40
spawn(400)
if(src)
warning_messages += "starving"

View File

@@ -148,7 +148,7 @@ Frequency:
for(var/obj/machinery/computer/teleporter/com in machines) for(var/obj/machinery/computer/teleporter/com in machines)
if(com.target) if(com.target)
var/area/A = get_area(com.target) var/area/A = get_area(com.target)
if(A.noteleport) if(!A || A.noteleport)
continue continue
if(com.power_station && com.power_station.teleporter_hub && com.power_station.engaged) if(com.power_station && com.power_station.teleporter_hub && com.power_station.engaged)
L["[get_area(com.target)] (Active)"] = com.target L["[get_area(com.target)] (Active)"] = com.target

View File

@@ -106,9 +106,7 @@
/obj/structure/proc/examine_status(mob/user) //An overridable proc, mostly for falsewalls. /obj/structure/proc/examine_status(mob/user) //An overridable proc, mostly for falsewalls.
var/healthpercent = (obj_integrity/max_integrity) * 100 var/healthpercent = (obj_integrity/max_integrity) * 100
switch(healthpercent) switch(healthpercent)
if(100 to INFINITY) if(50 to 99)
return "It seems pristine and undamaged."
if(50 to 100)
return "It looks slightly damaged." return "It looks slightly damaged."
if(25 to 50) if(25 to 50)
return "It appears heavily damaged." return "It appears heavily damaged."

View File

@@ -57,7 +57,7 @@
/obj/structure/closet/wardrobe/green/New() /obj/structure/closet/wardrobe/green/New()
..() ..()
contents = list() contents = list()
for(var/i in 1 to 3) for(var/i in 1 to 3)
new /obj/item/clothing/under/color/green(src) new /obj/item/clothing/under/color/green(src)
for(var/i in 1 to 3) for(var/i in 1 to 3)
new /obj/item/clothing/shoes/sneakers/black(src) new /obj/item/clothing/shoes/sneakers/black(src)
@@ -174,14 +174,10 @@
new /obj/item/clothing/under/color/orange(src) new /obj/item/clothing/under/color/orange(src)
new /obj/item/clothing/under/color/pink(src) new /obj/item/clothing/under/color/pink(src)
new /obj/item/clothing/under/color/red(src) new /obj/item/clothing/under/color/red(src)
new /obj/item/clothing/under/color/lightblue(src)
new /obj/item/clothing/under/color/aqua(src)
new /obj/item/clothing/under/color/purple(src)
new /obj/item/clothing/under/color/lightpurple(src)
new /obj/item/clothing/under/color/lightgreen(src)
new /obj/item/clothing/under/color/darkblue(src) new /obj/item/clothing/under/color/darkblue(src)
new /obj/item/clothing/under/color/darkred(src) new /obj/item/clothing/under/color/teal(src)
new /obj/item/clothing/under/color/lightred(src) new /obj/item/clothing/under/color/lightpurple(src)
new /obj/item/clothing/under/color/green(src)
new /obj/item/clothing/mask/bandana/red(src) new /obj/item/clothing/mask/bandana/red(src)
new /obj/item/clothing/mask/bandana/red(src) new /obj/item/clothing/mask/bandana/red(src)
new /obj/item/clothing/mask/bandana/blue(src) new /obj/item/clothing/mask/bandana/blue(src)

View File

@@ -98,6 +98,21 @@
for(var/i in 1 to 3) for(var/i in 1 to 3)
new /obj/item/weapon/reagent_containers/blood/random(src) new /obj/item/weapon/reagent_containers/blood/random(src)
/obj/structure/closet/crate/freezer/surplus_limbs
name = "surplus prosthetic limbs"
desc = "A crate containing an assortment of cheap prosthetic limbs."
/obj/structure/closet/crate/freezer/surplus_limbs/New()
. = ..()
new /obj/item/bodypart/l_arm/robot/surplus(src)
new /obj/item/bodypart/l_arm/robot/surplus(src)
new /obj/item/bodypart/r_arm/robot/surplus(src)
new /obj/item/bodypart/r_arm/robot/surplus(src)
new /obj/item/bodypart/l_leg/robot/surplus(src)
new /obj/item/bodypart/l_leg/robot/surplus(src)
new /obj/item/bodypart/r_leg/robot/surplus(src)
new /obj/item/bodypart/r_leg/robot/surplus(src)
/obj/structure/closet/crate/radiation /obj/structure/closet/crate/radiation
desc = "A crate with a radiation sign on it." desc = "A crate with a radiation sign on it."
name = "radiation crate" name = "radiation crate"

View File

@@ -481,7 +481,7 @@
if(istype(O, /obj/item/weapon/reagent_containers/food/snacks/monkeycube)) if(istype(O, /obj/item/weapon/reagent_containers/food/snacks/monkeycube))
var/obj/item/weapon/reagent_containers/food/snacks/monkeycube/M = O var/obj/item/weapon/reagent_containers/food/snacks/monkeycube/M = O
user << "<span class='notice'>You place [src] under a stream of water...</span>" user << "<span class='notice'>You place [O] under a stream of water...</span>"
user.drop_item() user.drop_item()
M.loc = get_turf(src) M.loc = get_turf(src)
M.Expand() M.Expand()

View File

@@ -1,4 +1,4 @@
/proc/playsound(atom/source, soundin, vol as num, vary, extrarange as num, falloff, surround = 1) /proc/playsound(atom/source, soundin, vol as num, vary, extrarange as num, falloff, surround = 1, frequency = null)
soundin = get_sfx(soundin) // same sound for everyone soundin = get_sfx(soundin) // same sound for everyone
@@ -6,7 +6,8 @@
throw EXCEPTION("playsound(): source is an area") throw EXCEPTION("playsound(): source is an area")
return return
var/frequency = get_rand_frequency() // Same frequency for everybody if(isnull(frequency))
frequency = get_rand_frequency() // Same frequency for everybody
var/turf/turf_source = get_turf(source) var/turf/turf_source = get_turf(source)
// Looping through the player list has the added bonus of working for mobs inside containers // Looping through the player list has the added bonus of working for mobs inside containers
@@ -121,7 +122,7 @@
soundin = pick('sound/machines/terminal_button01.ogg', 'sound/machines/terminal_button02.ogg', 'sound/machines/terminal_button03.ogg', \ soundin = pick('sound/machines/terminal_button01.ogg', 'sound/machines/terminal_button02.ogg', 'sound/machines/terminal_button03.ogg', \
'sound/machines/terminal_button04.ogg', 'sound/machines/terminal_button05.ogg', 'sound/machines/terminal_button06.ogg', \ 'sound/machines/terminal_button04.ogg', 'sound/machines/terminal_button05.ogg', 'sound/machines/terminal_button06.ogg', \
'sound/machines/terminal_button07.ogg', 'sound/machines/terminal_button08.ogg') 'sound/machines/terminal_button07.ogg', 'sound/machines/terminal_button08.ogg')
/* //Scream emote sounds //when they get ported again /* //Scream emote sounds //when they get ported again
if ("malescream") if ("malescream")
soundin = pick('sound/voice/scream/scream_m1.ogg', 'sound/voice/scream/scream_m2.ogg') soundin = pick('sound/voice/scream/scream_m1.ogg', 'sound/voice/scream/scream_m2.ogg')
if ("femscream") if ("femscream")
@@ -132,7 +133,7 @@
soundin = pick('sound/voice/scream/bird1.ogg', 'sound/voice/scream/bird2.ogg') soundin = pick('sound/voice/scream/bird1.ogg', 'sound/voice/scream/bird2.ogg')
if ("mothscream") if ("mothscream")
soundin = pick('sound/voice/scream/moth1.ogg') soundin = pick('sound/voice/scream/moth1.ogg')
*/ */
//Vore sounds //Vore sounds
if ("digestion_sounds") if ("digestion_sounds")
soundin = pick('sound/vore/digest1.ogg', 'sound/vore/digest2.ogg', 'sound/vore/digest3.ogg', \ soundin = pick('sound/vore/digest1.ogg', 'sound/vore/digest2.ogg', 'sound/vore/digest3.ogg', \
@@ -145,7 +146,6 @@
'sound/vore/death7.ogg', 'sound/vore/death8.ogg', 'sound/vore/death9.ogg', 'sound/vore/death10.ogg') 'sound/vore/death7.ogg', 'sound/vore/death8.ogg', 'sound/vore/death9.ogg', 'sound/vore/death10.ogg')
if ("struggle_sounds") if ("struggle_sounds")
soundin = pick('sound/vore/squish1.ogg', 'sound/vore/squish2.ogg', 'sound/vore/squish3.ogg', 'sound/vore/squish4.ogg') soundin = pick('sound/vore/squish1.ogg', 'sound/vore/squish2.ogg', 'sound/vore/squish3.ogg', 'sound/vore/squish4.ogg')
return soundin return soundin
/proc/playsound_global(file, repeat=0, wait, channel, volume) /proc/playsound_global(file, repeat=0, wait, channel, volume)

View File

@@ -21,9 +21,14 @@
var/explosion_level = 0 //for preventing explosion dodging var/explosion_level = 0 //for preventing explosion dodging
var/explosion_id = 0 var/explosion_id = 0
var/list/decals var/list/decals
/turf/SDQL_update(const/var_name, new_value)
if(var_name == "x" || var_name == "y" || var_name == "z")
return FALSE
. = ..()
/turf/New() /turf/New()
..() ..()
@@ -189,7 +194,6 @@
W.explosion_level = old_ex_level W.explosion_level = old_ex_level
W.explosion_id = old_ex_id W.explosion_id = old_ex_id
if(!defer_change) if(!defer_change)
W.AfterChange(ignore_air) W.AfterChange(ignore_air)
W.blueprint_data = old_blueprint_data W.blueprint_data = old_blueprint_data
@@ -203,6 +207,13 @@
for(var/obj/structure/cable/C in contents) for(var/obj/structure/cable/C in contents)
C.deconstruct() C.deconstruct()
//update firedoor adjacency
var/list/turfs_to_check = get_adjacent_open_turfs(src) | src
for(var/I in turfs_to_check)
var/turf/T = I
for(var/obj/machinery/door/firedoor/FD in T)
FD.CalculateAffectingAreas()
queue_smooth_neighbors(src) queue_smooth_neighbors(src)
/turf/open/AfterChange(ignore_air) /turf/open/AfterChange(ignore_air)