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"