diff --git a/code/game/objects/contraband.dm b/code/game/objects/contraband.dm index f28b24f1cb..cdc0b1488d 100644 --- a/code/game/objects/contraband.dm +++ b/code/game/objects/contraband.dm @@ -4,14 +4,14 @@ #define NUM_OF_POSTER_DESIGNS 17 /obj/item/weapon/contraband - name = "Contraband Item" + name = "contraband item" desc = "You probably shouldn't be holding this." icon = 'contraband.dmi' - force = 5 + force = 0 /obj/item/weapon/contraband/poster - name = "Rolled poster" + name = "rolled-up poster" desc = "The poster comes with its own automatic adhesive mechanism, for easy pinning to any vertical surface. Its vulgar themes have marked it as Contraband aboard Nanotrasen© Space Facilities." icon_state = "rolled_poster" var/serial_number = 0 @@ -20,11 +20,9 @@ /obj/item/weapon/contraband/poster/New(turf/loc,var/given_serial=0) if(given_serial==0) - //world<<"HERP" serial_number = rand(1,NUM_OF_POSTER_DESIGNS) src.resulting_poster = new(serial_number) else - //world<<"DERP" serial_number = given_serial //We don't give it a resulting_poster because if we called it with a given_serial it means that we're rerolling an already used poster. src.name += " - No. [serial_number]" @@ -68,7 +66,7 @@ //############################## THE ACTUAL DECALS ########################### obj/effect/decal/poster - name = "Poster" + name = "poster" desc = "A large piece of space-resistant printed paper. It's considered contraband." icon = 'contraband.dmi' anchored = 1 @@ -128,7 +126,7 @@ obj/effect/decal/poster/New(var/serial) name += " - User of the Arcane Arts" desc += " This particular one depicts a wizard, casting a spell. You can't really make out if it's an actial photograph or a computer-generated image." if(15) - name += " - Leviating Skull" + name += " - Levitating Skull" desc += " This particular one is the portrait of a certain flying, friendly and somewhat sex-crazed enchanted skull. Its adventures along with its fabled companion are now fading through history..." if(16) name += " - Augmented Legend" @@ -173,7 +171,42 @@ obj/effect/decal/poster/attackby(obj/item/weapon/W as obj, mob/user as mob) return /obj/effect/decal/poster/proc/roll_and_drop(turf/loc) - var/obj/item/weapon/contraband/poster/P = new(src,src.serial_number) - P.resulting_poster = src - P.loc = loc - src.loc = P + var/obj/item/weapon/contraband/poster/P = new(src,src.serial_number) + P.resulting_poster = src + P.loc = loc + src.loc = P + + +//seperated to reduce code duplication. Moved here for ease of reference and to unclutter r_wall/attackby() +/turf/simulated/wall/proc/place_poster(var/obj/item/weapon/contraband/poster/P, var/mob/user) + if(!P.resulting_poster) return + + var/stuff_on_wall = 0 + for( var/obj/O in src.contents) //Let's see if it already has a poster on it or too much stuff + if(istype(O,/obj/effect/decal/poster)) + user << "The wall is far too cluttered to place a poster!" + return + stuff_on_wall++ + if(stuff_on_wall==3) + user << "The wall is far too cluttered to place a poster!" + return + + user << "You start placing the poster on the wall..." //Looks like it's uncluttered enough. Place the poster. + + //declaring D because otherwise if P gets 'deconstructed' we lose our reference to P.resulting_poster + var/obj/effect/decal/poster/D = P.resulting_poster + + var/temp_loc = user.loc + flick("poster_being_set",D) + D.loc = src + del(P) //delete it now to cut down on sanity checks afterwards. Agouri's code supports rerolling it anyway + playsound(D.loc, 'poster_being_created.ogg', 100, 1) + + sleep(17) + if(!D) return + + if(istype(src,/turf/simulated/wall) && user && user.loc == temp_loc)//Let's check if everything is still there + user << "You place the poster!" + else + D.roll_and_drop(temp_loc) + return \ No newline at end of file diff --git a/code/game/turf.dm b/code/game/turf.dm index 0259fb3733..fe3ca38d6d 100644 --- a/code/game/turf.dm +++ b/code/game/turf.dm @@ -498,47 +498,12 @@ else if(istype(W,/obj/item/apc_frame)) var/obj/item/apc_frame/AH = W AH.try_build(src) + return - else if(istype(W,/obj/item/weapon/contraband/poster)) //POSTERSSSS - var/obj/item/weapon/contraband/poster/P = W - if(P.resulting_poster) - var/check = 0 - var/stuff_on_wall = 0 - for( var/obj/O in src.contents) //Let's see if it already has a poster on it or too much stuff - if(istype(O,/obj/effect/decal/poster)) - check = 1 - break - stuff_on_wall++ - if(stuff_on_wall==3) - check = 1 - break - - if(check) - user << "The wall is far too cluttered to place a poster!" - return - - user << "You start placing the poster on the wall..." //Looks like it's uncluttered enough. Place the poster. - - P.resulting_poster.loc = src - var/temp = P.resulting_poster.icon_state - var/temp_loc = user.loc - P.resulting_poster.icon_state = "poster_being_set" - playsound(P.resulting_poster.loc, 'poster_being_created.ogg', 100, 1) - - sleep(22) - - if(!P) - return - - if(user.loc == temp_loc)//Let's check if he still is there - user << "You place the poster!" - P.resulting_poster.icon_state = temp - src.contents += P.resulting_poster - del(P) - else - user << "You stop placing the poster." - P.resulting_poster.loc = P - P.resulting_poster.icon_state = temp + //Poster stuff + else if(istype(W,/obj/item/weapon/contraband/poster)) + place_poster(W,user) + return else return attack_hand(user) @@ -619,6 +584,7 @@ O.amount-- else del(O) + return if(2) if( istype(W, /obj/item/weapon/weldingtool) ) @@ -776,45 +742,7 @@ //Poster stuff else if(istype(W,/obj/item/weapon/contraband/poster)) - var/obj/item/weapon/contraband/poster/P = W - if(P.resulting_poster) - var/check = 0 - var/stuff_on_wall = 0 - for( var/obj/O in src.contents) //Let's see if it already has a poster on it or too much stuff - if(istype(O,/obj/effect/decal/poster)) - check = 1 - break - stuff_on_wall++ - if(stuff_on_wall==3) - check = 1 - break - - if(check) - user << "The wall is far too cluttered to place a poster!" - return - - user << "You start placing the poster on the wall..." //Looks like it's uncluttered enough. Place the poster. - - P.resulting_poster.loc = src - var/temp = P.resulting_poster.icon_state - var/temp_loc = user.loc - P.resulting_poster.icon_state = "poster_being_set" - playsound(P.resulting_poster.loc, 'poster_being_created.ogg', 100, 1) - - sleep(22) - - if(!P) - return - - if(user.loc == temp_loc)//Let's check if he still is there - user << "You place the poster!" - P.resulting_poster.icon_state = temp - src.contents += P.resulting_poster - del(P) - else - user << "You stop placing the poster." - P.resulting_poster.loc = P - P.resulting_poster.icon_state = temp + place_poster(W,user) return //Finally, CHECKING FOR FALSE WALLS if it isn't damaged diff --git a/code/modules/admin/verbs/adminhelp.dm b/code/modules/admin/verbs/adminhelp.dm index 4216c68fff..a81d9e497f 100644 --- a/code/modules/admin/verbs/adminhelp.dm +++ b/code/modules/admin/verbs/adminhelp.dm @@ -1,14 +1,14 @@ -/mob/verb/adminhelp(msg as text) +/client/verb/adminhelp(msg as text) set category = "Admin" set name = "Adminhelp" - msg = copytext(sanitize(msg), 1, MAX_MESSAGE_LEN) - - if (!msg) + if (muted_complete) + src << "Error: Admin-PM: You are completely muted." return - if (usr.client && usr.client.muted_complete) - return + if(!msg) return + msg = sanitize(copytext(msg,1,MAX_MESSAGE_LEN)) + if (!msg) return for (var/client/X) if (X.holder) @@ -16,11 +16,11 @@ X << 'adminhelp.ogg' X << "\blue HELP: [key_name(src, X)] (PP) (VV) (SM) (JMP) (CA): [msg]" - usr << "Your message has been broadcast to administrators." + src << "PM to-Admins: [msg]" log_admin("HELP: [key_name(src)]: [msg]") if(tension_master) tension_master.new_adminhelp() - send2irc(usr.ckey, msg) + send2irc(ckey, msg) return proc/send2irc(msg,msg2) diff --git a/code/modules/admin/verbs/adminpm.dm b/code/modules/admin/verbs/adminpm.dm new file mode 100644 index 0000000000..50cf8cd4a8 --- /dev/null +++ b/code/modules/admin/verbs/adminpm.dm @@ -0,0 +1,105 @@ +//allows right clicking mobs to send an admin PM to their client, forwards the selected mob's client to cmd_admin_pm +/client/proc/cmd_admin_pm_context(mob/M as mob in world) + set category = null + set name = "Admin PM Mob" + if(!holder) + src << "Error: Admin-PM-Context: Only administrators may use this command." + return + if( !ismob(M) || !M.client ) return + cmd_admin_pm(M.client,null) + +//shows a list of clients we could send PMs to, then forwards our choice to cmd_admin_pm +/client/proc/cmd_admin_pm_panel() + set category = "Admin" + set name = "Admin PM" + if(!holder) + src << "Error: Admin-PM-Panel: Only administrators may use this command." + return + var/list/client/targets[0] + for(var/client/T) + if(T.mob) + if(istype(T.mob, /mob/new_player)) + targets["(New Player) - [T]"] = T + else if(istype(T.mob, /mob/dead/observer)) + targets["[T.mob.name](Ghost) - [T]"] = T + else + targets["[T.mob.real_name](as [T.mob.name]) - [T]"] = T + else + targets["(No Mob) - [T]"] = T + var/list/sorted = sortList(targets) + var/target = input(src,"To whom shall we send a message?","Admin PM",null) in sorted|null + cmd_admin_pm(targets[target],null) + + +//takes input from cmd_admin_pm_context, cmd_admin_pm_panel or /client/Topic and sends them a PM. +//Fetching a message if needed. src is the sender and C is the target client +/client/proc/cmd_admin_pm(var/client/C, var/msg) + if(src.muted_complete) + src << "Error: Admin-PM: You are completely muted." + return + + if( !C || !istype(C,/client) ) + if(holder) src << "Error: Admin-PM: Client not found." + else adminhelp(msg) //admin we are replying to left. adminhelp instead + return + + //get message text, limit it's length.and clean/escape html + if(!msg) + msg = input(src,"Message:", "Private message to [C.key]") as text|null + if(!msg) return + if(!C) + if(holder) src << "Error: Admin-PM: Client not found." + else adminhelp(msg) //admin we are replying to has vanished, adminhelp instead + return + + //clean the message if it's not sent by a GA or GM + if( !holder || !(holder.rank in list("Game Admin", "Game Master")) ) + msg = sanitize(copytext(msg,1,MAX_MESSAGE_LEN)) + if(!msg) return + + if(C.holder) + if(holder) //both are admins + C << "Admin PM from-[key_name(src, C, 1)]: [msg]" + src << "Admin PM to-[key_name(C, src, 1)]: [msg]" + + else //recipient is an admin but sender is not + C << "Reply PM from-[key_name(src, C, 1)]: [msg]" + src << "PM to-Admins: [msg]" + + //play the recieving admin the adminhelp sound (if they have them enabled) + if(C.sound_adminhelp) + C << 'adminhelp.ogg' + + else + if(holder) //sender is an admin but recipient is not. Do BIG RED TEXT + C << "-- Administrator private message --" + C << "Admin PM from-[key_name(src, C, 0)]: [msg]" + C << "Click on the administrator's name to reply." + src << "Admin PM to-[key_name(C, src, 1)]: [msg]" + + //always play non-admin recipients the adminhelp sound + C << 'adminhelp.ogg' + + //AdminPM popup for ApocStation and anybody else who wants to use it. Set it with POPUP_ADMIN_PM in config.txt ~Carn + if(config.popup_admin_pm) + spawn() //so we don't hold the caller proc up + var/sender = src + var/sendername = key + var/reply = input(C, msg,"Admin PM from-[sendername]", "") as text|null //show message and await a reply + if(C && reply) + if(sender) + C.cmd_admin_pm(sender,reply) //sender is still about, let's reply to them + else + adminhelp(reply) //sender has left, adminhelp instead + return + + else //neither are admins + src << "Error: Admin-PM: Non-admin to non-admin PM communication is forbidden." + return + + log_admin("PM: [key_name(src)]->[key_name(C)]: [msg]") + + //we don't use message_admins here because the sender/receiver might get it too + for(var/client/X) //there are fewer clients than mobs + if(X.holder && X.key!=key && X.key!=C.key) //check client/X is an admin and isn't the sender or recipient + X << "PM: [key_name(src, X, 0)]->[key_name(C, X, 0)]: \blue [msg]" //inform X diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm index 85a8055ea2..0bb4e2874b 100644 --- a/code/modules/admin/verbs/randomverbs.dm +++ b/code/modules/admin/verbs/randomverbs.dm @@ -85,111 +85,6 @@ log_admin("DirectNarrate: [key_name(usr)] to ([M.name]/[M.key]): [msg]") message_admins("\blue \bold DirectNarrate: [key_name(usr)] to ([M.name]/[M.key]): [msg]
", 1) -//allows right clicking mobs to send an admin PM to their client, forwards the selected mob's client to cmd_admin_pm -/client/proc/cmd_admin_pm_context(mob/M as mob in world) - set category = null - set name = "Admin PM Mob" - if(!holder) - src << "\red Error: Admin-PM-Context: Only administrators may use this command." - return - if( !ismob(M) || !M.client ) return - cmd_admin_pm(M.client) - -//shows a list of clients we could send PMs to, then forwards our choice to cmd_admin_pm -/client/proc/cmd_admin_pm_panel() - set category = "Admin" - set name = "Admin PM" - if(!holder) - src << "\red Error: Admin-PM-Panel: Only administrators may use this command." - return - var/list/client/targets[0] - for(var/client/T) - if(T.mob) - if(istype(T.mob, /mob/new_player)) - targets["(New Player) - [T]"] = T - else if(istype(T.mob, /mob/dead/observer)) - targets["[T.mob.name](Ghost) - [T]"] = T - else - targets["[T.mob.real_name](as [T.mob.name]) - [T]"] = T - else - targets["(No Mob) - [T]"] = T - var/list/sorted = sortList(targets) - var/target = input(usr,"To whom shall we send a message?","Admin PM",null) in sorted|null - cmd_admin_pm(targets[target]) - -//takes input from cmd_admin_pm_context, cmd_admin_pm_panel or /client/Topic and sends them a PM after fetching a message to send. -/client/proc/cmd_admin_pm(var/client/C = null, var/t = null) - if( !C || !istype(C,/client) ) - src << "\red Error: Admin-PM: Client not found." - return - if(src.muted_complete) - src << "\red Error: Admin-PM: You are muted." - return - - //get message text, limit it's length.and clean/escape html - if(!t) - t = input("Message:", "Private message to [C.key]") as text|null - if(!t) return - if(!C) - src << "\red Error: Admin PM: Client not found." - return - - //clean the message if it's not sent by a GA or GM - if( !holder || !(holder.rank in list("Game Admin", "Game Master")) ) - t = sanitize(copytext(t,1,500)) - if(!t) return - - - if(C.holder) - if(holder) //both are admins - C << "Admin PM from-[key_name(src, C, 1)]: [t]" - src << "Admin PM to-[key_name(C, src, 1)]: [t]" - - else //recipient is an admin but sender is not - C << "Reply PM from-[key_name(src, C, 1)]: [t]" - src << "Reply PM to-[key_name(C, src, 0)]: [t]" - - //play the recieving admin the adminhelp sound (if they have them enabled) - if(C.sound_adminhelp) - C << 'adminhelp.ogg' - - else - if(holder) //sender is an admin but recipient is not. Do BIG RED TEXT - C << "-- Administrator private message --" - C << "Admin PM from-[key_name(src, C, 0)]: [t]" - C << "Click on the administrator's name to reply." - src << "Admin PM to-[key_name(C, src, 1)]: [t]" - - //always play non-admin recipients the adminhelp sound - C << 'adminhelp.ogg' - - //AdminPM popup for ApocStation and anybody else who wants to use it. Set it with POPUP_ADMIN_PM in config.txt ~Carn - if(config.popup_admin_pm) - spawn() //so we don't hold the caller proc up - var/sender = src - var/sendername = key - var/reply = input(C, t,"Admin PM from-[sendername]", "") as text|null //show message and await a reply - if(C && reply) - if(sender) - C.cmd_admin_pm(sender,reply) //sender is still about, let's reply to them - else - for(var/client/X) //sender has left! find another admin to pm - if(X.holder) - return C.cmd_admin_pm(X,reply) - C << "Error: Admin PM: Client not found." //couldn't find one - return - - else //neither are admins - src << "Error: Admin PM: Non-admin to non-admin PM communication is forbidden." - return - - log_admin("PM: [key_name(src)]->[key_name(C)]: [t]") - - //we don't use message_admins here because the sender/receiver might get it too - for(var/client/X) //there are fewer clients than mobs - if(X.holder && X.key!=key && X.key!=C.key) //check client/X is an admin and isn't the sender or recipient - X << "PM: [key_name(src, X, 0)]->[key_name(C, X, 0)]: \blue [t]" //inform X - /client/proc/cmd_admin_godmode(mob/M as mob in world) set category = "Special Verbs" set name = "Godmode" diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index ff4b45ea90..ecaade290a 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -620,7 +620,7 @@ if(ismob(C)) //Old stuff can pass in mobs instead of clients var/mob/M = C C = M.client - cmd_admin_pm(C) + cmd_admin_pm(C,null) else ..() diff --git a/tgstation.dme b/tgstation.dme index 23d6704c92..a230f7860c 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -744,6 +744,7 @@ #include "code\modules\admin\player_panel.dm" #include "code\modules\admin\verbs\adminhelp.dm" #include "code\modules\admin\verbs\adminjump.dm" +#include "code\modules\admin\verbs\adminpm.dm" #include "code\modules\admin\verbs\adminsay.dm" #include "code\modules\admin\verbs\atmosdebug.dm" #include "code\modules\admin\verbs\BrokenInhands.dm"