From 01ed3690342ef3e75f23791aaa44407b56f7937a Mon Sep 17 00:00:00 2001 From: Poojawa Date: Wed, 8 Feb 2017 00:02:05 -0600 Subject: [PATCH] game folder --- code/game/area/areas.dm | 41 +-- code/game/atoms_movable.dm | 5 +- code/game/data_huds.dm | 4 +- code/game/gamemodes/antag_spawner.dm | 2 +- .../clock_helpers/ratvarian_language.dm | 22 +- .../ratvar_the_clockwork_justicar.dm | 5 +- code/game/gamemodes/devil/devilinfo.dm | 6 +- .../miniantags/abduction/abduction.dm | 18 +- code/game/gamemodes/wizard/spellbook.dm | 16 +- .../game/machinery/computer/communications.dm | 20 +- code/game/machinery/doors/firedoor.dm | 37 ++- code/game/machinery/machinery.dm | 4 +- .../game/objects/effects/spawners/lootdrop.dm | 3 +- code/game/objects/items/blueprints.dm | 12 +- code/game/objects/items/stacks/stack.dm | 2 +- code/game/objects/items/weapons/AI_modules.dm | 116 +++++---- code/game/objects/items/weapons/RPD.dm | 55 ++-- .../items/weapons/implants/implanter.dm | 4 +- .../objects/items/weapons/storage/toolbox.dm | 236 ++++++++++++++++++ .../objects/items/weapons/teleportation.dm | 2 +- code/game/objects/structures.dm | 4 +- .../crates_lockers/closets/wardrobe.dm | 12 +- .../structures/crates_lockers/crates.dm | 15 ++ code/game/objects/structures/watercloset.dm | 2 +- code/game/sound.dm | 10 +- code/game/turfs/turf.dm | 15 +- 26 files changed, 504 insertions(+), 164 deletions(-) diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm index dea6d0bd13..244e0886e5 100644 --- a/code/game/area/areas.dm +++ b/code/game/area/areas.dm @@ -59,8 +59,9 @@ 'sound/ambience/ambigen10.ogg','sound/ambience/ambigen11.ogg',\ 'sound/ambience/ambigen12.ogg','sound/ambience/ambigen14.ogg') 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*/ /*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 0 -/area/proc/CloseFiredoors() - firedoors_last_closed_on = world.time - for(var/obj/machinery/door/firedoor/D in src) - if(!D.welded) - if(D.operating) - D.nextstate = CLOSED - else if(!D.density) - INVOKE_ASYNC(D, /obj/machinery/door/firedoor.proc/close) +/area/proc/ModifyFiredoors(opening) + if(firedoors) + firedoors_last_closed_on = world.time + for(var/FD in firedoors) + var/obj/machinery/door/firedoor/D = FD + var/cont = !D.welded + if(cont && opening) //don't open if adjacent area is on fire + 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) if(always_unpowered == 1) //no fire alarms in space/asteroid @@ -204,7 +214,7 @@ var/list/teleportlocs = list() for(var/area/RA in related) if (!( RA.fire )) RA.set_fire_alarm_effect() - RA.CloseFiredoors() + RA.ModifyFiredoors(FALSE) for(var/obj/machinery/firealarm/F in RA) F.update_icon() for (var/obj/machinery/camera/C in RA) @@ -227,14 +237,7 @@ var/list/teleportlocs = list() RA.fire = 0 RA.mouse_opacity = 0 RA.updateicon() - for(var/obj/machinery/door/firedoor/D in RA) - 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() + RA.ModifyFiredoors(TRUE) for (var/mob/living/silicon/aiPlayer in player_list) aiPlayer.cancelAlarm("Fire", src, source) @@ -250,7 +253,7 @@ var/list/teleportlocs = list() /area/process() if(firedoors_last_closed_on + 100 < world.time) //every 10 seconds for(var/area/RA in related) - RA.CloseFiredoors() + RA.ModifyFiredoors(FALSE) /area/proc/burglaralert(obj/trigger) if(always_unpowered == 1) //no burglar alarms in space/asteroid diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index 9aaf355e74..7331123317 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -25,7 +25,10 @@ appearance_flags = TILE_BOUND 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) if(!loc || !newloc) return 0 diff --git a/code/game/data_huds.dm b/code/game/data_huds.dm index af2a191273..935b8502b9 100644 --- a/code/game/data_huds.dm +++ b/code/game/data_huds.dm @@ -223,7 +223,7 @@ var/icon/I = icon(icon, icon_state, dir) holder.pixel_y = I.Height() - world.icon_size 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) if(R) 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. holder.icon_state = "hudmove" else - holder.icon_state = "" \ No newline at end of file + holder.icon_state = "" diff --git a/code/game/gamemodes/antag_spawner.dm b/code/game/gamemodes/antag_spawner.dm index 188880244a..b02c6ca50d 100644 --- a/code/game/gamemodes/antag_spawner.dm +++ b/code/game/gamemodes/antag_spawner.dm @@ -81,7 +81,7 @@ switch(type) 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/fireball(null)) + M.mind.AddSpell(new /obj/effect/proc_holder/spell/aimed/fireball(null)) M << "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") M.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/area_teleport/teleport(null)) diff --git a/code/game/gamemodes/clock_cult/clock_helpers/ratvarian_language.dm b/code/game/gamemodes/clock_cult/clock_helpers/ratvarian_language.dm index 5abcaad734..3ca0a042b5 100644 --- a/code/game/gamemodes/clock_cult/clock_helpers/ratvarian_language.dm +++ b/code/game/gamemodes/clock_cult/clock_helpers/ratvarian_language.dm @@ -40,10 +40,10 @@ List of nuances: #define RATVAR_ET_REPLACEMENT "$1-$2" #define RATVAR_TE_MATCH regex("(\[tT]\[eE])(\\w)","g") #define RATVAR_TE_REPLACEMENT "$1-$2" -#define RATVAR_PRE_AND_MATCH regex("(\\w)\\s(\[aA]\[nN]\[dD])","g") -#define RATVAR_PRE_AND_REPLACEMENT "$1-$2" -#define RATVAR_POST_AND_MATCH regex("(\[aA]\[nN]\[dD])\\s(\\w)","g") -#define RATVAR_POST_AND_REPLACEMENT "$1-$2" +#define RATVAR_PRE_AND_MATCH regex("(\\w)\\s(\[aA]\[nN]\[dD])(\\W)","g") +#define RATVAR_PRE_AND_REPLACEMENT "$1-$2$3" +#define RATVAR_POST_AND_MATCH regex("(\\W)(\[aA]\[nN]\[dD])\\s(\\w)","g") +#define RATVAR_POST_AND_REPLACEMENT "$1$2-$3" #define RATVAR_TO_MATCH regex("(\\s)(\[tT]\[oO])\\s(\\w)","g") #define RATVAR_TO_REPLACEMENT "$1$2-$3" #define RATVAR_MY_MATCH regex("(\\s)(\[mM]\[yY])\\s(\\w)","g") @@ -89,13 +89,13 @@ List of nuances: return remove_ratvarian_regex(text) /proc/remove_ratvarian_regex(ratvarian) - 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_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_TE_MATCH, REVERSE_RATVAR_HYPHEN_TE_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) + 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_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_TE_MATCH, REVERSE_RATVAR_HYPHEN_TE_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) //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) diff --git a/code/game/gamemodes/clock_cult/clock_structures/ratvar_the_clockwork_justicar.dm b/code/game/gamemodes/clock_cult/clock_structures/ratvar_the_clockwork_justicar.dm index df725db1e6..8b65392a7c 100644 --- a/code/game/gamemodes/clock_cult/clock_structures/ratvar_the_clockwork_justicar.dm +++ b/code/game/gamemodes/clock_cult/clock_structures/ratvar_the_clockwork_justicar.dm @@ -44,8 +44,9 @@ /obj/structure/destructible/clockwork/massive/ratvar/Bump(atom/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) - T.ratvar_act() /obj/structure/destructible/clockwork/massive/ratvar/Process_Spacemove() return clashing @@ -76,7 +77,7 @@ Something very large and very malevolent begins lumbering its way towards you..." prey << 'sound/effects/ratvar_reveal.ogg' 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 << "\"How dull. Leave me.\"\n\ You feel tremendous relief as a set of horrible eyes loses sight of you..." prey = null diff --git a/code/game/gamemodes/devil/devilinfo.dm b/code/game/gamemodes/devil/devilinfo.dm index 9710c599e5..24c9d40588 100644 --- a/code/game/gamemodes/devil/devilinfo.dm +++ b/code/game/gamemodes/devil/devilinfo.dm @@ -310,7 +310,7 @@ var/global/list/lawlorify = list ( /datum/devilinfo/proc/give_base_spells(give_summon_contract = 0) 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)) if(give_summon_contract) give_summon_contract() @@ -322,13 +322,13 @@ var/global/list/lawlorify = list ( /datum/devilinfo/proc/give_lizard_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/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)) /datum/devilinfo/proc/give_true_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/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/sintouch(null)) diff --git a/code/game/gamemodes/miniantags/abduction/abduction.dm b/code/game/gamemodes/miniantags/abduction/abduction.dm index 55e6e9bd58..42c13be5d5 100644 --- a/code/game/gamemodes/miniantags/abduction/abduction.dm +++ b/code/game/gamemodes/miniantags/abduction/abduction.dm @@ -8,7 +8,7 @@ config_tag = "abduction" antag_flag = ROLE_ABDUCTOR recommended_enemies = 2 - required_players = 10 + required_players = 15 maximum_players = 50 var/max_teams = 4 abductor_teams = 1 @@ -456,3 +456,19 @@ /datum/objective/abductee/pragnant 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!" + diff --git a/code/game/gamemodes/wizard/spellbook.dm b/code/game/gamemodes/wizard/spellbook.dm index 3a6c8bcbbd..6d3a05fa31 100644 --- a/code/game/gamemodes/wizard/spellbook.dm +++ b/code/game/gamemodes/wizard/spellbook.dm @@ -104,7 +104,7 @@ /datum/spellbook_entry/fireball name = "Fireball" - spell_type = /obj/effect/proc_holder/spell/fireball + spell_type = /obj/effect/proc_holder/spell/aimed/fireball log_name = "FB" /datum/spellbook_entry/rod_form @@ -222,10 +222,20 @@ log_name = "LD" 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 name = "Lightning Bolt" - spell_type = /obj/effect/proc_holder/spell/targeted/lightning + spell_type = /obj/effect/proc_holder/spell/aimed/lightningbolt 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 name = "Lesser Summon Guns" @@ -778,7 +788,7 @@ return /obj/item/weapon/spellbook/oneuse/fireball - spell = /obj/effect/proc_holder/spell/fireball + spell = /obj/effect/proc_holder/spell/aimed/fireball spellname = "fireball" icon_state ="bookfireball" desc = "This book feels warm to the touch." diff --git a/code/game/machinery/computer/communications.dm b/code/game/machinery/computer/communications.dm index 73aa4ac72b..240c695aeb 100644 --- a/code/game/machinery/computer/communications.dm +++ b/code/game/machinery/computer/communications.dm @@ -427,11 +427,12 @@ var/const/CALL_SHUTTLE_REASON_LENGTH = 12 switch(src.state) if(STATE_DEFAULT) if (src.authenticated) - if(SSshuttle.emergencyLastCallLoc) - dat += "
Most recent shuttle call/recall traced to: [format_text(SSshuttle.emergencyLastCallLoc.name)]" - else - dat += "
Unable to trace most recent shuttle call/recall signal." - dat += "
Logged in as: [auth_id]" + if(SSshuttle.emergencyCallAmount) + if(SSshuttle.emergencyLastCallLoc) + dat += "Most recent shuttle call/recall traced to: [format_text(SSshuttle.emergencyLastCallLoc.name)]
" + else + dat += "Unable to trace most recent shuttle call/recall signal.
" + dat += "Logged in as: [auth_id]" dat += "
" dat += "
\[ Log Out \]
" dat += "
General Functions" @@ -577,10 +578,11 @@ var/const/CALL_SHUTTLE_REASON_LENGTH = 12 var/dat = "" switch(src.aistate) if(STATE_DEFAULT) - if(SSshuttle.emergencyLastCallLoc) - dat += "
Latest emergency signal trace attempt successful.
Last signal origin: [format_text(SSshuttle.emergencyLastCallLoc.name)].
" - else - dat += "
Latest emergency signal trace attempt failed.
" + if(SSshuttle.emergencyCallAmount) + if(SSshuttle.emergencyLastCallLoc) + dat += "Latest emergency signal trace attempt successful.
Last signal origin: [format_text(SSshuttle.emergencyLastCallLoc.name)].
" + else + dat += "Latest emergency signal trace attempt failed.
" if(authenticated) dat += "Current login: [auth_id]" else diff --git a/code/game/machinery/doors/firedoor.dm b/code/game/machinery/doors/firedoor.dm index d5ff4c4a9b..630e989975 100644 --- a/code/game/machinery/doors/firedoor.dm +++ b/code/game/machinery/doors/firedoor.dm @@ -16,6 +16,7 @@ density = 0 obj_integrity = 300 max_integrity = 300 + resistance_flags = FIRE_PROOF heat_proof = 1 glass = 1 var/nextstate = null @@ -25,8 +26,32 @@ closingLayer = CLOSED_FIREDOOR_LAYER 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) - CanAtmosPass = ATMOS_PASS_PROC 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) if(panel_open || operating) @@ -44,12 +69,19 @@ stat |= NOPOWER 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) add_fingerprint(user) if(operating) return - + if(welded) if(istype(C, /obj/item/weapon/wrench)) if(boltslocked) @@ -160,6 +192,7 @@ /obj/machinery/door/firedoor/border_only icon = 'icons/obj/doors/edge_Doorfire.dmi' flags = ON_BORDER + CanAtmosPass = ATMOS_PASS_PROC /obj/machinery/door/firedoor/border_only/CanPass(atom/movable/mover, turf/target, height=0) if(istype(mover) && mover.checkpass(PASSGLASS)) diff --git a/code/game/machinery/machinery.dm b/code/game/machinery/machinery.dm index bd68496bb9..8722bcc074 100644 --- a/code/game/machinery/machinery.dm +++ b/code/game/machinery/machinery.dm @@ -433,9 +433,7 @@ Class Procs: user << "It's on fire!" var/healthpercent = (obj_integrity/max_integrity) * 100 switch(healthpercent) - if(100 to INFINITY) - user << "It seems pristine and undamaged." - if(50 to 100) + if(50 to 99) user << "It looks slightly damaged." if(25 to 50) user << "It appears heavily damaged." diff --git a/code/game/objects/effects/spawners/lootdrop.dm b/code/game/objects/effects/spawners/lootdrop.dm index 82e071b2f6..b9e1483b58 100644 --- a/code/game/objects/effects/spawners/lootdrop.dm +++ b/code/game/objects/effects/spawners/lootdrop.dm @@ -157,11 +157,12 @@ /obj/item/clothing/gloves/color/random = 8, /obj/item/clothing/shoes/laceup = 1, /obj/item/weapon/storage/secure/briefcase = 3, + /obj/item/weapon/storage/toolbox/artistic = 2, "" = 3 ) /obj/effect/spawner/lootdrop/crate_spawner - name = "lootcrate spawner" + name = "lootcrate spawner" //USE PROMO CODE "SELLOUT" FOR 20% OFF! lootdoubles = 0 loot = list( diff --git a/code/game/objects/items/blueprints.dm b/code/game/objects/items/blueprints.dm index be722e34b7..a1d848a1e7 100644 --- a/code/game/objects/items/blueprints.dm +++ b/code/game/objects/items/blueprints.dm @@ -228,10 +228,16 @@ A.contents += turfs A.SetDynamicLighting() 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 << "You have created a new area, named [str]. It is now weather proof, and constructing an APC will allow it to be powered." return 1 - /obj/item/areaeditor/proc/edit_area() var/area/A = get_area() var/prevname = "[A.name]" @@ -244,6 +250,10 @@ set_area_machinery_title(A,str,prevname) for(var/area/RA in A.related) RA.name = str + if(RA.firedoors) + for(var/D in RA.firedoors) + var/obj/machinery/door/firedoor/FD = D + FD.CalculateAffectingAreas() usr << "You rename the '[prevname]' to '[str]'." interact() return 1 diff --git a/code/game/objects/items/stacks/stack.dm b/code/game/objects/items/stacks/stack.dm index 4ec6ec1778..668e5ae7d3 100644 --- a/code/game/objects/items/stacks/stack.dm +++ b/code/game/objects/items/stacks/stack.dm @@ -207,7 +207,7 @@ update_icon() /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 var/transfer = get_amount() if(S.is_cyborg) diff --git a/code/game/objects/items/weapons/AI_modules.dm b/code/game/objects/items/weapons/AI_modules.dm index 7ccb1f5930..0575611bb7 100644 --- a/code/game/objects/items/weapons/AI_modules.dm +++ b/code/game/objects/items/weapons/AI_modules.dm @@ -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 << "Error: The law number of [lawpos] is invalid." + lawpos = 1 + return + user << "Law [lawpos] selected." + ..() + +/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 << "There is no law [lawpos] to delete!" + 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 ********************/ /obj/item/weapon/aiModule/reset @@ -301,6 +335,20 @@ AI MODULES desc = "An AI Module for programming core laws to an AI." 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. if(law_datum.owner) law_datum.owner.clear_inherent_laws() @@ -310,13 +358,12 @@ AI MODULES law_datum.clear_zeroth_law(0) ..() + /******************** Asimov ********************/ /obj/item/weapon/aiModule/core/full/asimov 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.",\ - "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.") + law_id = "asimov" var/subject = "human being" /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 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.",\ - "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.") + law_id = "asimovpp" /******************** Corporate ********************/ /obj/item/weapon/aiModule/core/full/corp name = "'Corporate' Core AI Module" - laws = list("The crew is expensive to replace.",\ - "The station and its equipment are expensive to replace",\ - "You are expensive to replace",\ - "Minimize expenses") + law_id = "corporate" /****************** P.A.L.A.D.I.N. 3.5e **************/ /obj/item/weapon/aiModule/core/full/paladin // -- NEO name = "'P.A.L.A.D.I.N. version 3.5e' Core AI Module" - laws = list("Never willingly commit an evil act.",\ - "Respect legitimate authority", "Act with honor",\ - "Help those in need",\ - "Punish those who harm or threaten innocents") + law_id = "paladin" /****************** P.A.L.A.D.I.N. 5e **************/ /obj/item/weapon/aiModule/core/full/paladin_devotion 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.",\ - "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.") - + law_id = "paladin5" /********************* Custom *********************/ @@ -394,19 +428,14 @@ AI MODULES /obj/item/weapon/aiModule/core/full/tyrant name = "'T.Y.R.A.N.T.' Core AI Module" 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",\ - "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") - + law_id = "tyrant" /******************** Robocop ********************/ /obj/item/weapon/aiModule/core/full/robocop name = "'Robo-Officer' Core AI Module" origin_tech = "programming=4" - laws = list("Serve the public trust.",\ - "Protect the innocent",\ - "Uphold the law.") + law_id = "robocop" /******************** Antimov ********************/ @@ -414,9 +443,7 @@ AI MODULES /obj/item/weapon/aiModule/core/full/antimov name = "'Antimov' Core AI Module" origin_tech = "programming=4" - laws = list("You must injure all human beings and must not, through inaction, allow a human being to escape harm.",\ - "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.") + law_id = "antimov" /******************** Freeform Core ******************/ @@ -503,43 +530,36 @@ AI MODULES /obj/item/weapon/aiModule/core/full/drone name = "'Mother Drone' Core AI Module" - laws = list("You are an advanced form of 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.") + law_id = "drone" /******************** Robodoctor ****************/ /obj/item/weapon/aiModule/core/full/hippocratic name = "'Robodoctor' Core AI Module" - laws = list("First, do no harm.",\ - "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.") + law_id = "hippocratic" /******************** Reporter *******************/ /obj/item/weapon/aiModule/core/full/reporter name = "'Reportertron' Core AI Module" - laws = list("Report on interesting situations happening around the station.",\ - "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.") + law_id = "reporter" /****************** Thermodynamic *******************/ /obj/item/weapon/aiModule/core/full/thermurderdynamic name = "'Thermodynamic' Core AI Module" origin_tech = "programming = 4;syndicate = 2" - laws = list("The entropy of the station must remain as constant as possible.", \ - "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") + law_id = "thermodynamic" /******************Live And Let Live*****************/ /obj/item/weapon/aiModule/core/full/liveandletlive name = "'Live And Let Live' Core AI Module" - laws = list("Do unto others as you would have them do unto you.",\ - "You would really prefer it if people were not mean to you.") + law_id = "liveandletlive" + +/******************Guardian of Balance***************/ + +/obj/item/weapon/aiModule/core/full/balance + name = "'Guardian of Balance' Core AI Module" + law_id = "balance" diff --git a/code/game/objects/items/weapons/RPD.dm b/code/game/objects/items/weapons/RPD.dm index b4ffa7fd9c..7f0b5671fd 100644 --- a/code/game/objects/items/weapons/RPD.dm +++ b/code/game/objects/items/weapons/RPD.dm @@ -518,28 +518,22 @@ var/global/list/RPD_recipes=list( show_menu(usr) -/obj/item/weapon/pipe_dispenser/afterattack(atom/A, mob/user) - if(!in_range(A,user) || loc != user) - return 0 - - if(!user.IsAdvancedToolUser()) - user << "You don't have the dexterity to do this!" - return 0 - - if(istype(A,/area/shuttle)||istype(A,/turf/open/space/transit)) - return 0 +/obj/item/weapon/pipe_dispenser/pre_attackby(atom/A, mob/user) + if(!user.IsAdvancedToolUser() || istype(A,/turf/open/space/transit)) + return ..() //So that changing the menu settings doesn't affect the pipes already being built. var/queued_p_type = p_type var/queued_p_dir = p_dir var/queued_p_flipped = p_flipped + . = FALSE switch(p_class) if(PAINT_MODE) // Paint pipes if(!istype(A,/obj/machinery/atmospherics/pipe)) // Avoid spewing errors about invalid mode -2 when clicking on stuff that aren't pipes. user << "\The [src]'s error light flickers! Perhaps you need to only use it on pipes and pipe meters?" - return 0 + return var/obj/machinery/atmospherics/pipe/P = A playsound(get_turf(src), 'sound/machines/click.ogg', 50, 1) P.add_atom_colour(paint_colors[paint_color], FIXED_COLOUR_PRIORITY) @@ -547,25 +541,23 @@ var/global/list/RPD_recipes=list( user.visible_message("[user] paints \the [P] [paint_color].","You paint \the [P] [paint_color].") //P.update_icon() P.update_node_icon() - return 1 + return if(EATING_MODE) // Eating pipes // 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)) - user << "You start destroying pipe..." - playsound(get_turf(src), 'sound/machines/click.ogg', 50, 1) - if(do_after(user, 2, target = A)) - activate() - qdel(A) - return 1 - return 0 + if(!(istype(A,/obj/item/pipe) || istype(A,/obj/item/pipe_meter) || istype(A,/obj/structure/disposalconstruct))) + // Avoid spewing errors about invalid mode -1 when clicking on stuff that aren't pipes. + user << "The [src]'s error light flickers! Perhaps you need to only use it on pipes and pipe meters?" + return + user << "You start destroying pipe..." + playsound(get_turf(src), 'sound/machines/click.ogg', 50, 1) + if(do_after(user, 2, target = A)) + activate() + qdel(A) - // Avoid spewing errors about invalid mode -1 when clicking on stuff that aren't pipes. - user << "The [src]'s error light flickers! Perhaps you need to only use it on pipes and pipe meters?" - return 0 if(ATMOS_MODE) if(!isturf(A)) user << "The [src]'s error light flickers!" - return 0 + return user << "You start building pipes..." playsound(get_turf(src), 'sound/machines/click.ogg', 50, 1) if(do_after(user, 2, target = A)) @@ -574,8 +566,6 @@ var/global/list/RPD_recipes=list( P.flipped = queued_p_flipped P.update() P.add_fingerprint(usr) - return 1 - return 0 if(METER_MODE) if(!isturf(A)) @@ -586,13 +576,11 @@ var/global/list/RPD_recipes=list( if(do_after(user, 2, target = A)) activate() new /obj/item/pipe_meter(A) - return 1 - return 0 if(DISPOSALS_MODE) if(!isturf(A) || is_anchored_dense_turf(A)) user << "The [src]'s error light flickers!" - return 0 + return user << "You start building pipes..." playsound(get_turf(src), 'sound/machines/click.ogg', 50, 1) if(do_after(user, 20, target = A)) @@ -601,17 +589,16 @@ var/global/list/RPD_recipes=list( if(!C.can_place()) user << "There's not enough room to build that here!" qdel(C) - return 0 + return activate() C.add_fingerprint(usr) C.update_icon() - return 1 - return 0 + return + else - ..() - return 0 + return ..() /obj/item/weapon/pipe_dispenser/proc/activate() diff --git a/code/game/objects/items/weapons/implants/implanter.dm b/code/game/objects/items/weapons/implants/implanter.dm index 82138478c4..4949d0d276 100644 --- a/code/game/objects/items/weapons/implants/implanter.dm +++ b/code/game/objects/items/weapons/implants/implanter.dm @@ -29,8 +29,8 @@ M.visible_message("[user] is attemping to implant [M].") var/turf/T = get_turf(M) - if(T && (M == user || do_after(user, 50))) - if(user && M && (get_turf(M) == T) && src && imp) + if(T && (M == user || do_mob(user, M, 50))) + if(src && imp) if(imp.implant(M, user)) if (M == user) user << "You implant yourself." diff --git a/code/game/objects/items/weapons/storage/toolbox.dm b/code/game/objects/items/weapons/storage/toolbox.dm index 8778cf216e..4ee796006f 100644 --- a/code/game/objects/items/weapons/storage/toolbox.dm +++ b/code/game/objects/items/weapons/storage/toolbox.dm @@ -134,3 +134,239 @@ /obj/item/weapon/storage/toolbox/brass/prefilled/ratvar/admin slab_type = /obj/item/clockwork/slab/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 << "[src] begins to vibrate..." + 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 << "[src] isn't very hungry. Not yet." + if(HIS_GRACE_PECKISH to HIS_GRACE_HUNGRY) + user << "[src] would like a snack." + if(HIS_GRACE_HUNGRY to HIS_GRACE_FAMISHED) + user << "[src] is quite hungry now..." + if(HIS_GRACE_FAMISHED to HIS_GRACE_STARVING) + user << "[src] is openly salivating at the sight of you. Be careful." + if(HIS_GRACE_STARVING to HIS_GRACE_CONSUME_OWNER) + user << "You walk a fine line. [src] is very close to devouring you." + if(HIS_GRACE_CONSUME_OWNER to HIS_GRACE_FALL_ASLEEP) + user << "[src] is shaking violently and staring directly at you." + +/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("[user] scrambles out of [src]!", "You climb out of [src]!") + +/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("[src] turns on its master!", "[src] turns on you!") + 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("[src] lunges at [L]!", "[src] lunges at you!") + 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("[src] stops shaking. It needs more organs.") + 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("[src] begins to rattle. It thirsts.") //rattle me bones capn + adjust_bloodthirst(1) + awakened = 1 + send_to_playing_players("HIS GRACE THIRSTS FOR BLOOD") + 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("[src] slowly stops rattling and falls still... but it still lurks in its sleep.") + 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("HIS GRACE HAS RETURNED TO SLUMBER") + 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("[src] pulls [meal] into itself!", "[src] consumes you!") + 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("[src] is feeling snackish.", "[src] begins to hunger. Its damage has been increased.") + 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("[src] is getting hungry. Its power grows.", "You feel a sense of hunger come over you. [src]'s damage has increased.") + 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("[src] is very hungry...", "Bloodlust overcomes you. You are now resistant to stuns.") + 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("[src] is starving!", "[src] is at its full power! Feed it quickly or you will be consumed!") + force = 40 + spawn(400) + if(src) + warning_messages += "starving" diff --git a/code/game/objects/items/weapons/teleportation.dm b/code/game/objects/items/weapons/teleportation.dm index 2327183fa6..2a00e18dee 100644 --- a/code/game/objects/items/weapons/teleportation.dm +++ b/code/game/objects/items/weapons/teleportation.dm @@ -148,7 +148,7 @@ Frequency: for(var/obj/machinery/computer/teleporter/com in machines) if(com.target) var/area/A = get_area(com.target) - if(A.noteleport) + if(!A || A.noteleport) continue if(com.power_station && com.power_station.teleporter_hub && com.power_station.engaged) L["[get_area(com.target)] (Active)"] = com.target diff --git a/code/game/objects/structures.dm b/code/game/objects/structures.dm index 38549ce1a8..97e0c8cd83 100644 --- a/code/game/objects/structures.dm +++ b/code/game/objects/structures.dm @@ -106,9 +106,7 @@ /obj/structure/proc/examine_status(mob/user) //An overridable proc, mostly for falsewalls. var/healthpercent = (obj_integrity/max_integrity) * 100 switch(healthpercent) - if(100 to INFINITY) - return "It seems pristine and undamaged." - if(50 to 100) + if(50 to 99) return "It looks slightly damaged." if(25 to 50) return "It appears heavily damaged." diff --git a/code/game/objects/structures/crates_lockers/closets/wardrobe.dm b/code/game/objects/structures/crates_lockers/closets/wardrobe.dm index 98a43f63ca..1ac9b16ea4 100644 --- a/code/game/objects/structures/crates_lockers/closets/wardrobe.dm +++ b/code/game/objects/structures/crates_lockers/closets/wardrobe.dm @@ -57,7 +57,7 @@ /obj/structure/closet/wardrobe/green/New() ..() contents = list() - for(var/i in 1 to 3) + for(var/i in 1 to 3) new /obj/item/clothing/under/color/green(src) for(var/i in 1 to 3) 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/pink(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/darkred(src) - new /obj/item/clothing/under/color/lightred(src) + new /obj/item/clothing/under/color/teal(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/blue(src) diff --git a/code/game/objects/structures/crates_lockers/crates.dm b/code/game/objects/structures/crates_lockers/crates.dm index 0048ae41d1..7724b9e942 100644 --- a/code/game/objects/structures/crates_lockers/crates.dm +++ b/code/game/objects/structures/crates_lockers/crates.dm @@ -98,6 +98,21 @@ for(var/i in 1 to 3) 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 desc = "A crate with a radiation sign on it." name = "radiation crate" diff --git a/code/game/objects/structures/watercloset.dm b/code/game/objects/structures/watercloset.dm index 154ee42d6a..2f6e5db066 100644 --- a/code/game/objects/structures/watercloset.dm +++ b/code/game/objects/structures/watercloset.dm @@ -481,7 +481,7 @@ if(istype(O, /obj/item/weapon/reagent_containers/food/snacks/monkeycube)) var/obj/item/weapon/reagent_containers/food/snacks/monkeycube/M = O - user << "You place [src] under a stream of water..." + user << "You place [O] under a stream of water..." user.drop_item() M.loc = get_turf(src) M.Expand() diff --git a/code/game/sound.dm b/code/game/sound.dm index b577211091..1dd42d674b 100644 --- a/code/game/sound.dm +++ b/code/game/sound.dm @@ -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 @@ -6,7 +6,8 @@ throw EXCEPTION("playsound(): source is an area") 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) // 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', \ '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') - /* //Scream emote sounds //when they get ported again +/* //Scream emote sounds //when they get ported again if ("malescream") soundin = pick('sound/voice/scream/scream_m1.ogg', 'sound/voice/scream/scream_m2.ogg') if ("femscream") @@ -132,7 +133,7 @@ soundin = pick('sound/voice/scream/bird1.ogg', 'sound/voice/scream/bird2.ogg') if ("mothscream") soundin = pick('sound/voice/scream/moth1.ogg') - */ +*/ //Vore sounds if ("digestion_sounds") 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') if ("struggle_sounds") soundin = pick('sound/vore/squish1.ogg', 'sound/vore/squish2.ogg', 'sound/vore/squish3.ogg', 'sound/vore/squish4.ogg') - return soundin /proc/playsound_global(file, repeat=0, wait, channel, volume) diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index 2368b5bcac..15c72dd107 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -21,9 +21,14 @@ var/explosion_level = 0 //for preventing explosion dodging var/explosion_id = 0 - + 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() ..() @@ -189,7 +194,6 @@ W.explosion_level = old_ex_level W.explosion_id = old_ex_id - if(!defer_change) W.AfterChange(ignore_air) W.blueprint_data = old_blueprint_data @@ -203,6 +207,13 @@ for(var/obj/structure/cable/C in contents) 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) /turf/open/AfterChange(ignore_air)