diff --git a/baystation12.dme b/baystation12.dme index b39db33700..880ba77035 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -677,6 +677,7 @@ #include "code\game\objects\items\weapons\stungloves.dm" #include "code\game\objects\items\weapons\surgery_tools.dm" #include "code\game\objects\items\weapons\swords_axes_etc.dm" +#include "code\game\objects\items\weapons\syndie.dm" #include "code\game\objects\items\weapons\table_rack_parts.dm" #include "code\game\objects\items\weapons\teleportation.dm" #include "code\game\objects\items\weapons\tiles_wires.dm" @@ -830,6 +831,7 @@ #include "code\modules\mob\living\say.dm" #include "code\modules\mob\living\blob\blob.dm" #include "code\modules\mob\living\carbon\carbon.dm" +#include "code\modules\mob\living\carbon\give.dm" #include "code\modules\mob\living\carbon\shock.dm" #include "code\modules\mob\living\carbon\alien\alien.dm" #include "code\modules\mob\living\carbon\alien\say.dm" diff --git a/code/WorkInProgress/SkyMarshal/evidence.dm b/code/WorkInProgress/SkyMarshal/evidence.dm index ad3454db7b..c349adf332 100644 --- a/code/WorkInProgress/SkyMarshal/evidence.dm +++ b/code/WorkInProgress/SkyMarshal/evidence.dm @@ -16,8 +16,6 @@ */ /obj/item/weapon/evidencebag/afterattack(obj/item/O, mob/user as mob) - -//Now you can put it into a briefcase, if it is in your hand. Otherwise, if it is evidence on the ground, it picks it up. if(istype(O, /obj/item/weapon/storage) && O in user) user << "You put the evidence bag into the [O]." return ..() @@ -30,10 +28,13 @@ if(src.contents.len > 0) user << "The [src] already has something inside it." return ..() - if(istype(O.loc, /obj/item/weapon/storage)) - user << "This is broke as hell." - return + if(istype(O.loc,/obj/item/weapon/storage)) var/obj/item/weapon/storage/U = O.loc + user.client.screen -= O + U.contents.Remove(O) + if(istype(O.loc,/obj/item/clothing/suit/storage/)) + var/obj/item/clothing/suit/storage/U = O.loc + user.client.screen -= O U.contents.Remove(O) user << "You put the [O] inside the [src]." icon_state = "evidence" @@ -67,7 +68,7 @@ new /obj/item/weapon/evidencebag(src) new /obj/item/weapon/evidencebag(src) new /obj/item/weapon/evidencebag(src) - new /obj/item/weapon/f_card(src) + new /obj/item/weapon/evidencebag(src) new /obj/item/weapon/f_card(src) ..() return \ No newline at end of file diff --git a/code/defines/atom.dm b/code/defines/atom.dm index 151b81198a..bd86699be5 100644 --- a/code/defines/atom.dm +++ b/code/defines/atom.dm @@ -2,7 +2,7 @@ layer = 2 var/level = 2 var/flags = FPRINT - var/fingerprints = null + var/list/fingerprints var/list/fingerprintshidden = new/list() var/fingerprintslast = null var/blood_DNA = null diff --git a/code/defines/global.dm b/code/defines/global.dm index d4e5dd29bc..170b887a2b 100644 --- a/code/defines/global.dm +++ b/code/defines/global.dm @@ -169,6 +169,7 @@ var //Don't set this very much higher then 1024 unless you like inviting people in to dos your server with message spam const/MAX_MESSAGE_LEN = 1024 const/MAX_PAPER_MESSAGE_LEN = 3072 + const/MAX_BOOK_MESSAGE_LEN = 9216 list/paper_blacklist = list("script","frame","iframe","input","button","a","embed","object") diff --git a/code/defines/procs/gamehelpers.dm b/code/defines/procs/gamehelpers.dm index 587d98969f..e9b2c0207f 100644 --- a/code/defines/procs/gamehelpers.dm +++ b/code/defines/procs/gamehelpers.dm @@ -187,4 +187,107 @@ var/dy = T.y - centerturf.y if(dx*dx + dy*dy <= rsq) turfs += T - return turfs \ No newline at end of file + return turfs + +proc/check_can_reach(atom/user, atom/target) + var/direct = get_dir(user, target) + var/obj/item/weapon/dummy/D = new /obj/item/weapon/dummy( user.loc ) + var/ok = 0 + if ( (direct - 1) & direct) + + // ------- CLICKED OBJECT IS LOCATED IN A DIAGONAL POSITION FROM THE PERSON ------- + + var/turf/Step_1 + var/turf/Step_2 + switch(direct) + if(5.0) + Step_1 = get_step(user, NORTH) + Step_2 = get_step(user, EAST) + + if(6.0) + Step_1 = get_step(user, SOUTH) + Step_2 = get_step(user, EAST) + + if(9.0) + Step_1 = get_step(user, NORTH) + Step_2 = get_step(user, WEST) + + if(10.0) + Step_1 = get_step(user, SOUTH) + Step_2 = get_step(user, WEST) + + else + if(Step_1 && Step_2) + + // ------- BOTH CARDINAL DIRECTIONS OF THE DIAGONAL EXIST IN THE GAME WORLD ------- + + var/check_1 = 0 + var/check_2 = 0 + if(step_to(D, Step_1)) + check_1 = 1 + for(var/obj/border_obstacle in Step_1) + if(border_obstacle.flags & ON_BORDER) + if(!border_obstacle.CheckExit(D, target)) + check_1 = 0 + // ------- YOU TRIED TO CLICK ON AN ITEM THROUGH A WINDOW (OR SIMILAR THING THAT LIMITS ON BORDERS) ON ONE OF THE DIRECITON TILES ------- + for(var/obj/border_obstacle in get_turf(target)) + if((border_obstacle.flags & ON_BORDER) && (target != border_obstacle)) + if(!border_obstacle.CanPass(D, D.loc, 1, 0)) + // ------- YOU TRIED TO CLICK ON AN ITEM THROUGH A WINDOW (OR SIMILAR THING THAT LIMITS ON BORDERS) ON THE TILE YOU'RE ON ------- + check_1 = 0 + + D.loc = user.loc + if(step_to(D, Step_2)) + check_2 = 1 + + for(var/obj/border_obstacle in Step_2) + if(border_obstacle.flags & ON_BORDER) + if(!border_obstacle.CheckExit(D, target)) + check_2 = 0 + for(var/obj/border_obstacle in get_turf(target)) + if((border_obstacle.flags & ON_BORDER) && (target != border_obstacle)) + if(!border_obstacle.CanPass(D, D.loc, 1, 0)) + check_2 = 0 + + + if(check_1 || check_2) + ok = 1 + // ------- YOU CAN REACH THE ITEM THROUGH AT LEAST ONE OF THE TWO DIRECTIONS. GOOD. ------- + + /* + More info: + If you're trying to click an item in the north-east of your mob, the above section of code will first check if tehre's a tile to the north or you and to the east of you + These two tiles are Step_1 and Step_2. After this, a new dummy object is created on your location. It then tries to move to Step_1, If it succeeds, objects on the turf you're on and + the turf that Step_1 is are checked for items which have the ON_BORDER flag set. These are itmes which limit you on only one tile border. Windows, for the most part. + CheckExit() and CanPass() are use to determine this. The dummy object is then moved back to your location and it tries to move to Step_2. Same checks are performed here. + If at least one of the two checks succeeds, it means you can reach the item and ok is set to 1. + */ + else + // ------- OBJECT IS ON A CARDINAL TILE (NORTH, SOUTH, EAST OR WEST OR THE TILE YOU'RE ON) ------- + if(target.loc == user.loc) + ok = 1 + // ------- OBJECT IS ON THE SAME TILE AS YOU ------- + else + ok = 1 + + //Now, check objects to block exit that are on the border + for(var/obj/border_obstacle in user.loc) + if(border_obstacle.flags & ON_BORDER) + if(!border_obstacle.CheckExit(D, target)) + ok = 0 + + //Next, check objects to block entry that are on the border + for(var/obj/border_obstacle in get_turf(target)) + if((border_obstacle.flags & ON_BORDER) && (target != border_obstacle)) + if(!border_obstacle.CanPass(D, D.loc, 1, 0)) + ok = 0 + /* + See the previous More info, for... more info... + */ + + if(get_dist(user, target) > 1) + return 0 + + del(D) + // ------- DUMMY OBJECT'S SERVED IT'S PURPOSE, IT'S REWARDED WITH A SWIFT DELETE ------- + return ok \ No newline at end of file diff --git a/code/defines/procs/helpers.dm b/code/defines/procs/helpers.dm index a30f6fa172..0bfdb8d640 100644 --- a/code/defines/procs/helpers.dm +++ b/code/defines/procs/helpers.dm @@ -1490,4 +1490,25 @@ proc/get_opposite(var/checkdir) list += found_string found_char = findtext(cur_text,character,last_found) list += copytext(cur_text,last_found,length(cur_text)+1) - return list \ No newline at end of file + return list + +/proc/stringmerge(var/text,var/compare,replace = "*") +//This proc fills in all spaces with the "replace" var (* by default) with whatever +//is in the other string at the same spot (assuming it is not a replace char). +//This is used for fingerprints + var/newtext = text + if(lentext(text) != lentext(compare)) + return 0 + for(var/i = 1, i < lentext(text), i++) + var/a = copytext(text,i,i+1) + var/b = copytext(compare,i,i+1) +//if it isn't both the same letter, or if they are both the replacement character +//(no way to know what it was supposed to be) + if(a != b) + if(a == replace) //if A is the replacement char + newtext = copytext(newtext,1,i) + b + copytext(newtext, i+1) + else if(b == replace) //if B is the replacement char + newtext = copytext(newtext,1,i) + a + copytext(newtext, i+1) + else //The lists disagree, Uh-oh! + return 0 + return newtext \ No newline at end of file diff --git a/code/game/atom_procs.dm b/code/game/atom_procs.dm index f94a756c30..a0a32c5367 100644 --- a/code/game/atom_procs.dm +++ b/code/game/atom_procs.dm @@ -88,27 +88,36 @@ var/mob/living/carbon/human/H = M if (!istype(H.dna, /datum/dna)) return 0 + world << md5(H.dna.uni_identity) if (H.gloves) if(src.fingerprintslast != H.key) src.fingerprintshidden += text("(Wearing gloves). Real name: [], Key: []",H.real_name, H.key) src.fingerprintslast = H.key return 0 if (!( src.fingerprints )) - src.fingerprints = text("[]", md5(H.dna.uni_identity)) + src.fingerprints = list(text("[]&[]", md5(H.dna.uni_identity), stars(md5(H.dna.uni_identity), rand(40,60)))) if(src.fingerprintslast != H.key) src.fingerprintshidden += text("Real name: [], Key: []",H.real_name, H.key) src.fingerprintslast = H.key return 1 else - var/list/L = params2list(src.fingerprints) - L -= md5(H.dna.uni_identity) - while(L.len >= 3) - L -= L[1] - L += md5(H.dna.uni_identity) - src.fingerprints = list2params(L) if(src.fingerprintslast != H.key) src.fingerprintshidden += text("Real name: [], Key: []",H.real_name, H.key) src.fingerprintslast = H.key + var/new_prints = 0 + var/prints + for(var/i = 1, i < src.fingerprints.len, i++) + var/list/L = params2list(src.fingerprints[i]) + if(L[1] == md5(H.dna.uni_identity)) + new_prints = i + prints = L[2] + break + if(new_prints) + src.fingerprints[new_prints] = list(text("[]&[]", md5(H.dna.uni_identity), stringmerge(prints,stars(md5(H.dna.uni_identity), rand(40,60))))) + return 1 + else + src.fingerprints += text("[]&[]", md5(H.dna.uni_identity), stars(md5(H.dna.uni_identity), rand(40,60))) + return 1 else if(src.fingerprintslast != M.key) src.fingerprintshidden += text("Real name: [], Key: []",M.real_name, M.key) diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm index 0b7c655230..f1198e1cd1 100644 --- a/code/game/gamemodes/game_mode.dm +++ b/code/game/gamemodes/game_mode.dm @@ -64,7 +64,8 @@ Implants; /obj/item/weapon/storage/syndie_kit/imp_uplink:10:Uplink Implant (Contains 5 Telecrystals); Whitespace:Seperator; Badassery; -/obj/item/toy/syndicateballoon:10:For showing that You Are The BOSS (Useless Balloon);"} +/obj/item/toy/syndicateballoon:10:For showing that You Are The BOSS (Useless Balloon); +Whitespace:Seperator;"} /datum/game_mode/proc/announce() //to be calles when round starts world << "Notice: [src] did not define announce()" diff --git a/code/game/machinery/alarm.dm b/code/game/machinery/alarm.dm index 89e37c8331..33d47cd9a4 100644 --- a/code/game/machinery/alarm.dm +++ b/code/game/machinery/alarm.dm @@ -90,7 +90,7 @@ "plasma" = new/datum/tlv(-1.0, -1.0, 0.2, 0.5), // Partial pressure, kpa "other" = new/datum/tlv(-1.0, -1.0, 0.5, 1.0), // Partial pressure, kpa "pressure" = new/datum/tlv(ONE_ATMOSPHERE*0.20,ONE_ATMOSPHERE*0.35,ONE_ATMOSPHERE*0.8,ONE_ATMOSPHERE*0.9), /* kpa */ - "temperature" = new/datum/tlv(40, 60, 140, 160), // K + "temperature" = new/datum/tlv(40, 60, 150, 160), // K ) //all air alarms in area are connected via magic diff --git a/code/game/magic/library.dm b/code/game/magic/library.dm index 82378071c9..aced80ed11 100644 --- a/code/game/magic/library.dm +++ b/code/game/magic/library.dm @@ -232,11 +232,11 @@ if ((!in_range(src, usr) && src.loc != user && src.loc.loc != user && user.equipped() != W)) return - if(lentext(t) >= MAX_PAPER_MESSAGE_LEN) + if(lentext(t) >= MAX_BOOK_MESSAGE_LEN) var/cont = input(user, "Your message is too long! Would you like to continue editing it?", "", "yes") in list("yes", "no") if(cont == "no") break - while(lentext(t) > MAX_PAPER_MESSAGE_LEN) + while(lentext(t) > MAX_BOOK_MESSAGE_LEN) if ((!in_range(src, usr) && src.loc != user && src.loc.loc != user && user.equipped() != W)) return diff --git a/code/game/objects/blood.dm b/code/game/objects/blood.dm index da37b28f3d..e8185cbe20 100644 --- a/code/game/objects/blood.dm +++ b/code/game/objects/blood.dm @@ -20,6 +20,9 @@ sleep(3) if (i > 0) var/obj/effect/decal/cleanable/blood/b = new /obj/effect/decal/cleanable/blood/splatter(src.loc) + b.blood_DNA = blood_DNA + b.blood_type = blood_type + b.OriginalMob = OriginalMob for(var/datum/disease/D in src.viruses) b.viruses += D if (step_to(src, get_step(src, direction), 0)) diff --git a/code/game/objects/devices/scanners.dm b/code/game/objects/devices/scanners.dm index 70991042c1..4166d44e12 100644 --- a/code/game/objects/devices/scanners.dm +++ b/code/game/objects/devices/scanners.dm @@ -66,11 +66,11 @@ MASS SPECTROMETER var/amount = 20.0 var/printing = 0.0 var/fibers_index = 0 - var/list/stored_fibers = null - var/list/stored_name = null + var/list/stored_fibers = list() + var/list/stored_name = list() var/prints_index = 0 - var/list/stored_prints = null - var/list/prints_name = null + var/list/stored_prints = list() + var/list/prints_name = list() w_class = 3.0 item_state = "electronic" flags = FPRINT | TABLEPASS | ONBELT | CONDUCT | USEDELAY @@ -138,20 +138,22 @@ MASS SPECTROMETER return /obj/item/device/detective_scanner/afterattack(atom/A as mob|obj|turf|area, mob/user as mob) - + if(src.loc != user) + return 0 src.add_fingerprint(user) if (istype(A, /obj/effect/decal/cleanable/blood) || istype(A, /obj/effect/rune)) if(A.blood_DNA) user << "\blue Blood type: [A.blood_type]\nDNA: [A.blood_DNA]" + return + if (!( A.fingerprints ) && !(A.suit_fibers) && !(A.blood_DNA)) + user << "\blue Unable to locate any fingerprints, materials, fibers, or fingerprints on [A]!" + return 0 else if (A.blood_DNA) user << "\blue Blood found on [A]. Analysing..." sleep(15) user << "\blue Blood type: [A.blood_type]\nDNA: [A.blood_DNA]" else user << "\blue No blood found on [A]." - if (!( A.fingerprints ) && !(A.suit_fibers)) - user << "\blue Unable to locate any fingerprints or fibers on [A]!" - return 0 if(!( A.fingerprints )) user << "\blue Unable to locate any fingerprints on [A]!" else diff --git a/code/game/objects/items/item.dm b/code/game/objects/items/item.dm index 7805cc1ac9..351dd922f5 100644 --- a/code/game/objects/items/item.dm +++ b/code/game/objects/items/item.dm @@ -162,7 +162,7 @@ if(isalien(user)) // -- TLE var/mob/living/carbon/alien/A = user - if(!A.has_fine_manipulation || w_class >= 4) + if(!A.has_fine_manipulation || w_class <= 4) user << "Your claws aren't capable of such fine manipulation." return @@ -196,20 +196,23 @@ /obj/item/attackby(obj/item/W as obj, mob/user as mob) if (istype(W, /obj/item/weapon/packageWrap)) + var/location = get_turf(src.loc) if(istype(src,/obj/item/weapon/storage) && istype(src.loc, /mob)) //Put it into the bag return - if(istype(src.loc,/obj/item/weapon/storage) || istype(src.loc,/obj/item/clothing/suit/storage/)) //Taking stuff out of storage duplicates it. - user << "\blue Do not do this, it is broken as all hell. Take it out of the container first." - return - for(var/obj/item/T in user) //Lets remove it from their inventory - if(T == src) - user.remove_from_mob(T) - break + if(istype(src.loc,/obj/item/weapon/storage)) //Taking stuff out of storage duplicates it. + var/obj/item/weapon/storage/U = src.loc + user.client.screen -= src + U.contents.Remove(src) + if(istype(src.loc,/obj/item/clothing/suit/storage/)) + var/obj/item/clothing/suit/storage/X = src.loc + user.client.screen -= src + X.contents.Remove(src) + if(src in user) + user.remove_from_mob(src) var/obj/item/weapon/packageWrap/O = W if (O.amount > 1) - var/obj/item/smallDelivery/P = new /obj/item/smallDelivery(get_turf(src.loc)) + var/obj/item/smallDelivery/P = new /obj/item/smallDelivery(location) P.wrapped = src - src.loc = P O.amount -= 1 else if(istype(W,/obj/item/wardrobe)) @@ -225,6 +228,7 @@ user << "\blue The wardrobe is full." return user << "\blue You pick up all the items." + user.visible_message("\blue [user] gathers up the pile of stuff, and puts it into \the [src]") I.update_icon() /obj/item/attack_self(mob/user as mob) diff --git a/code/game/objects/items/weapons/syndie.dm b/code/game/objects/items/weapons/syndie.dm new file mode 100644 index 0000000000..6055252d56 --- /dev/null +++ b/code/game/objects/items/weapons/syndie.dm @@ -0,0 +1,84 @@ +/obj/item/weapon/syndie + icon = 'syndieweapons.dmi' + +/*C-4 explosive charge and etc, replaces the old syndie transfer valve bomb.*/ + + +/*The explosive charge itself. Flashes for five seconds before exploding.*/ + +/obj/item/weapon/syndie/c4explosive + icon_state = "c-4small_0" + item_state = "c-4small" + name = "mysterious package" + desc = "A mysterious package." + w_class = 3 + + var/power = 1 /*Size of the explosion.*/ + var/size = "small" /*Used for the icon, this one will make c-4small_0 for the off state.*/ + +/obj/item/weapon/syndie/c4explosive/heavy + icon_state = "c-4large_0" + item_state = "c-4large" + desc = "A mysterious package, it's quite heavy." + power = 2 + size = "large" + +/obj/item/weapon/syndie/c4explosive/New() + var/K = rand(1,2000) + K = md5(num2text(K)+name) + K = copytext(K,1,7) + src.desc += "\n You see [K] engraved on \the [src]" + var/obj/item/weapon/syndie/c4detonator/detonator = new(src.loc) + detonator.desc += "\n You see [K] engraved on \the [src]" + detonator.bomb = src + +/obj/item/weapon/syndie/c4explosive/proc/detonate() + icon_state = "c-4[size]_1" + spawn(50) + explosion(get_turf(src), power, power*2, power*3, power*4, power*4) + for(var/dirn in cardinal) //This is to guarantee that C4 at least breaks down all immediately adjacent walls and doors. + var/turf/simulated/wall/T = get_step(src,dirn) + if(locate(/obj/machinery/door/airlock) in T) + var/obj/machinery/door/airlock/D = locate() in T + if(D.density) + D.open() + if(istype(T,/turf/simulated/wall)) + T.dismantle_wall(1) + del(src) + + +/*Detonator, disguised as a lighter*/ +/*Click it when closed to open, when open to bring up a prompt asking you if you want to close it or press the button.*/ + +/obj/item/weapon/syndie/c4detonator + icon_state = "c-4detonator_0" + item_state = "c-4detonator" + name = "lighter" /*Sneaky, thanks Dreyfus.*/ + desc = "A disposable lighter, it's quite heavy." + w_class = 1 + + var/obj/item/weapon/syndie/c4explosive/bomb + var/pr_open = 0 /*Is the "What do you want to do?" prompt open?*/ + +/obj/item/weapon/syndie/c4detonator/attack_self(mob/user as mob) + switch(src.icon_state) + if("c-4detonator_0") + src.icon_state = "c-4detonator_1" + user << "You flick open the lighter." + + if("c-4detonator_1") + if(!pr_open) + pr_open = 1 + switch(alert(user, "What would you like to do?", "Lighter", "Press the button.", "Close the lighter.")) + if("Press the button.") + user << "\red You press the button." + flick("c-4detonator_click", src) + if(src.bomb) + src.bomb.detonate() + log_admin("[user.real_name]([user.ckey]) has triggered [src.bomb] with [src].") + message_admins("\red [user.real_name]([user.ckey]) has triggered [src.bomb] with [src].") + + if("Close the lighter.") + src.icon_state = "c-4detonator_0" + user << "You close the lighter." + pr_open = 0 \ No newline at end of file diff --git a/code/game/verbs/suicide.dm b/code/game/verbs/suicide.dm index 475202d2ed..495bd5e935 100644 --- a/code/game/verbs/suicide.dm +++ b/code/game/verbs/suicide.dm @@ -11,8 +11,14 @@ src << "You can't commit suicide before the game starts!" return + var/permitted = 0 var/list/allowed = list("Syndicate","traitor","Wizard","Head Revolutionary","Cultist","Changeling") - if (mind.special_role in allowed) + for(var/T in allowed) + if(mind.special_role == T) + permitted = 1 + break + + if(!permitted) message_admins("[ckey] has tried to suicide, but they were not permitted due to not being antagonist as human.", 1) src << "No. Adminhelp if there is a legitimate reason." return diff --git a/code/modules/admin/verbs/adminhelp.dm b/code/modules/admin/verbs/adminhelp.dm index 9b8a3a76d8..7333030377 100644 --- a/code/modules/admin/verbs/adminhelp.dm +++ b/code/modules/admin/verbs/adminhelp.dm @@ -22,6 +22,7 @@ var/list/replacechars = list("'","\"",">","<","(",")") for(var/rep in replacechars) msg = dd_list2text((dd_text2list(msg, rep))) + world << msg send2adminirc("#bs12admin","HELP: [src.key]: [msg]") if(tension_master) tension_master.new_adminhelp() diff --git a/code/modules/mob/living/carbon/give.dm b/code/modules/mob/living/carbon/give.dm new file mode 100644 index 0000000000..b551bfb86e --- /dev/null +++ b/code/modules/mob/living/carbon/give.dm @@ -0,0 +1,101 @@ +mob/living/carbon/verb/give() + set name = "Give" + set src in view(1) + if(src.stat == 2 || usr.stat == 2|| src.client == null) + return + if(src == usr) + usr << "I feel stupider, suddenly." + return + var/obj/item/I + if(!usr.hand && usr.r_hand == null) + usr << "You don't have anything in your right hand to give to [src.name]" + return + if(usr.hand && usr.l_hand == null) + usr << "You don't have anything in your left hand to give to [src.name]" + return + if(usr.hand) + I = usr.l_hand + else if(!usr.hand) + I = usr.r_hand + if(!I) + return + var/obj/item/weapon/T = new(usr.loc) + if(!src.loc.Enter(T)) + usr << "Can't reach him" + del(T) + return + del(T) + if(src.r_hand == null) + switch(alert(src,"[usr.name] wants to give you \a [I.name]?",,"Yes","No")) + if("Yes") + if(!check_can_reach(usr,src)) + usr << "You need to keep in reaching distance." + src << "[usr.name] moved too far away." + return + if((usr.hand && usr.l_hand != I) || (!usr.hand && usr.r_hand != I)) + usr << "You need to keep the item in your active hand." + src << "[usr.name] seem to have given up on giving \the [I.name] to you." + return + if(src.r_hand != null) + if(src.l_hand == null) + usr.drop_item(I) + src.l_hand = I + else + usr << "Their hands are full." + else + usr.drop_item(I) + src.r_hand = I + I.loc = src + I.layer = 20 + I.add_fingerprint(src) + src.update_clothing() + usr.update_clothing() + action_message(src,"[usr.name] handed \the [I.name] to [src.name].") + if("No") + action_message(src,"[usr.name] tried to hand [I.name] to [src.name] but [src.name] didn't want it.") + else if(src.l_hand == null) + switch(alert(src,"[src.name] wants to give you \a [I.name]?",,"Yes","No")) + if("Yes") + if(!check_can_reach(usr,src)) + usr << "You need to keep in reaching distance." + src << "[usr.name] moved too far away." + return + if((usr.hand && usr.l_hand != I) || (!usr.hand && usr.r_hand != I)) + usr << "You need to keep the item in your active hand." + src << "[usr.name] seem to have given up on giving \the [I.name] to you." + return + if(src.l_hand != null) + if(src.r_hand == null) + usr.drop_item(I) + src.r_hand = I + else + usr << "Their hands are full." + else + usr.drop_item(I) + src.l_hand = I + I.loc = src + I.layer = 20 + I.add_fingerprint(src) + src.update_clothing() + usr.update_clothing() + action_message(src,"[usr.name] handed \the [I.name] to [src.name].") + if("No") + action_message(src,"[usr.name] tried to hand [I.name] to [src.name] but [src.name] didn't want it.") + else + usr << "[src.name]\s hands are full." + +proc/action_message(var/mob/living/carbon/A,var/message) + if (message != "") + if (1 & 1) + for (var/mob/O in viewers(A.loc, null)) + O.show_message(message, 1) + else if (1 & 2) + for (var/mob/O in hearers(A.loc, null)) + O.show_message(message, 1) + else if (message != "") + if (1 & 1) + for (var/mob/O in viewers(A, null)) + O.show_message(message, 1) + else if (1 & 2) + for (var/mob/O in hearers(A, null)) + O.show_message(message, 1) \ No newline at end of file diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 7783552690..83bf307127 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -793,19 +793,19 @@ spawn() if(key) if(istype(src, /mob/living/silicon)) - robogibs(loc, viruses, name) + robogibs(loc, viruses) else if (istype(src, /mob/living/carbon/alien)) - xgibs(loc, viruses, name) + xgibs(loc, viruses) else - gibs(loc, viruses, name, dna) + gibs(loc, viruses, dna) else if(istype(src, /mob/living/silicon)) robogibs(loc, viruses) else if(istype(src, /mob/living/carbon/alien)) - xgibs(loc, viruses, name) + xgibs(loc, viruses) else - gibs(loc, viruses, name, dna) + gibs(loc, viruses, dna) sleep(15) for(var/obj/item/I in src.contents) I.loc = get_turf(src) diff --git a/code/modules/mob/screen.dm b/code/modules/mob/screen.dm index 666245a89c..59c871e55b 100644 --- a/code/modules/mob/screen.dm +++ b/code/modules/mob/screen.dm @@ -429,6 +429,11 @@ O.show_message(text("\red [] resists!", usr), 1) if(usr:handcuffed && usr:canmove && (usr.last_special <= world.time)) + var/breakouttime = 1200 + var/displaytime = 2 + if(!usr:canmove) + breakouttime = 2400 + displaytime = 4 usr.next_move = world.time + 100 usr.last_special = world.time + 100 if(isalienadult(usr) || usr.mutations & HULK)//Don't want to do a lot of logic gating here. @@ -444,17 +449,31 @@ del(usr:handcuffed) usr:handcuffed = null else - usr << "\red You attempt to remove your handcuffs. (This will take around 2 minutes and you need to stand still)" + usr << "\red You attempt to remove your handcuffs. (This will take around [displaytime] minutes and you need to stand still)" for(var/mob/O in viewers(usr)) O.show_message(text("\red [] attempts to remove the handcuffs!", usr), 1) spawn(0) - if(do_after(usr, 1200)) - if(!usr:handcuffed) return - for(var/mob/O in viewers(usr)) - O.show_message(text("\red [] manages to remove the handcuffs!", usr), 1) - usr << "\blue You successfully remove your handcuffs." - usr:handcuffed:loc = usr:loc - usr:handcuffed = null + var/increment = 150 + for(var/i = 0, i < breakouttime, i += increment) + if(!do_after(usr, increment)) + return + + else + usr << pick("You hear something click, but it doesn't open yet.", // - Uristqwerty + "The latch resists!", // - IRC: BowlSoldier + "The chain is starting to give!", // - IRC: BowlSoldier + "The chain bends a little.", // - IRC: STALKER + "Your wrist hurts.", // - IRC: STALKER + "Unnng", // - IRC: Doug_H_Nuts + "The chain jangles a bit.", // - SkyMarshal + "\red Hurry up, dammit!", // - SkyMarshal + "This is exhausting!") // - SkyMarshal + if(!usr:handcuffed) return + for(var/mob/O in viewers(usr)) + O.show_message(text("\red [] manages to remove the handcuffs!", usr), 1) + usr << "\blue You successfully remove your handcuffs." + usr:handcuffed:loc = usr:loc + usr:handcuffed = null if(istype(usr, /mob/living/carbon/human) && istype(usr:wear_suit, /obj/item/clothing/suit/straight_jacket) && usr:canmove && (usr.last_special <= world.time)) usr.next_move = world.time + 200 diff --git a/maps/tgstation.2.0.8.dmm b/maps/tgstation.2.0.8.dmm index 6849c8a79e..ab54e19e0c 100644 --- a/maps/tgstation.2.0.8.dmm +++ b/maps/tgstation.2.0.8.dmm @@ -2642,7 +2642,7 @@ "aYP" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 8; on = 1; scrub_Toxins = 1},/obj/machinery/light{icon_state = "tube1"; dir = 8},/turf/simulated/floor{icon_state = "arrival"; dir = 8},/area/quartermaster/sorting) "aYQ" = (/obj/structure/table/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/turf/simulated/floor,/area/quartermaster/sorting) "aYR" = (/obj/machinery/door_control{id = "aicore"; name = "AI Core Access"; pixel_x = -22; pixel_y = 2; req_access_txt = ""},/turf/simulated/floor{icon_state = "wood"},/area/crew_quarters/captain) -"aYS" = (/obj/structure/stool/chair{dir = 1},/obj/effect/landmark/start{name = "Captain"},/obj/machinery/door_control{id = "aicore"; name = "AI Core Access"; pixel_x = 21; pixel_y = 20; req_access_txt = ""},/turf/simulated/floor{icon_state = "wood"},/area/crew_quarters/captain) +"aYS" = (/obj/structure/stool/chair{dir = 1},/obj/effect/landmark/start{name = "Captain"},/turf/simulated/floor{icon_state = "wood"},/area/crew_quarters/captain) "aYT" = (/obj/item/weapon/paper{info = "Our scientists stole your suit and shoved it in their destructive analyzer. We replaced it with one that isn't space capable.

--Central Command"; name = "Important Memo"},/obj/item/weapon/book/manual/security_space_law,/obj/structure/table/woodentable,/obj/structure/disposalpipe/segment{dir = 1},/turf/simulated/floor{icon_state = "wood"},/area/crew_quarters/captain) "aYU" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = "Streight"},/obj/machinery/keycard_auth{pixel_x = 25},/turf/simulated/floor{icon_state = "wood"},/area/crew_quarters/captain) "aYV" = (/obj/machinery/telecomms/allinone{frequency = 144.7},/turf/simulated/floor/grid,/area/turret_protected/ai)