/*
/////////////////////////////////////////////////////////////////////
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
/////////////////////////////////////////////////////////////////////
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
/////////////////////////////////////////////////////////////////////
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
/////////////////////////////////////////////////////////////////////
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
*****************************************************
*****************************************************
AJX's Modification of Spuzzum's Administrative Library
Modified Version - v3.0
by AJ "AJX"
*****************************************************
*****************************************************
******************************************************
This is my modification of the great Spuzzum's Admin code...
IMPORTANT NOTE: This was made by Spuzzum, NOT AJX!
All I did was change some stuff around, and add some more stuff!
I TAKE NO CREDIT FOR MOST OF THIS LIBRARY!!!
Although,
Copyright ©2002-2003 AJ "AJX" Huntington. Refer to
A_Admin.html for more copyright information.
/*********************************************/
Spuzzum's Administrative Library v2.2
by Jeremy "Spuzzum" Gibson
/**********************************************/
Refer to the included A_Admin.html for more information
on how to get this library up and running for your world.
Copyright ©2000-2001 Jeremy "Spuzzum" Gibson. Refer to
A_Admin.html for more copyright information.
*********************************************/
//GM PREFIXES AND SUFFIXES
// This is added to the beginning of a GM's name.
// For your convenience, you can set a different
// prefix for the Master GM rather than Admin or
// regular GMs.
//
// If you dislike having the prefix, it can be
// disabled by setting it to 'null'
// Eg. var/const/MASTER_GM_PREFIX = null
var/const/MASTER_GM_PREFIX = "\[M-GM] "
var/const/ADMIN_GM_PREFIX = "\[A-GM] "
var/const/GM_PREFIX = "\[GM] "
// The suffix works like the prefix, but it is
// added to the end of the name rather than the
// beginning.
// For your convenience, you can set a different
// suffix for the Master GM rather than Admin or
// regular GMs.
// By default, these are disabled (see above).
var/const/MASTER_GM_SUFFIX = null
var/const/ADMIN_GM_SUFFIX = null
var/const/GM_SUFFIX = null
/********************************************/
//!!! [MASTER KEY((S))] !!!
// The master key determines who the master GM is.
// The person with the master GM key gains verbs
// that allow him or her to add, remove, and modify
// GMs in addition to the standard functions.
//
// The master GM should usually be the person who
// made the world itself, though it doesn't have to
// be.
//AJ EDITITATION!(If thats a word) I switched some stuff around so
//there could be 5 Masta GMs! Although, u could just make all your
//keys be them... }-p
var/const/MASTER_KEY = "Hell Ramen" //(change my key to yours!)
var/const/MASTER_KEY2 = "Hell Ramen"
var/const/MASTER_KEY3 = "Hell Ramen"
var/const/MASTER_KEY4 = "Hell Ramen"
var/const/MASTER_KEY5 = "Hell Ramen"
//This change is only made in this version for my RPG demo, not any
//others. 5 MORE Master keys, this is for server hosters.
var/const/MASTER_KEY6 = "Hell Ramen"
var/const/MASTER_KEY7 = "Hell Ramen"
var/const/MASTER_KEY8 = "Hell Ramen"
var/const/MASTER_KEY9 = "Hell Ramen "
var/const/MASTER_KEY10 = "Hell Ramen"
/********************************************/
//INACTIVITY BOOTER
// The inactivity setting will occasionally check a player's
// client to see how long it has been inactive. If so, it
// will Logout() the player.
// Times are in seconds. If you don't want this to happen,
// set this equal to zero.
var/const/MAX_INACTIVITY_TIME = 1800//allow 30 mins. (1800 seconds) of AFK
// Note that this is not an exacting figure; the proc that checks clients
// loops itself very, very slowly to prevent lag. They are guaranteed at LEAST
// that amount of time.
/********************************************/
//Hide Report Bad GM Command
//Removed this for this particular game
/********************************************/
/********************************************/
//GM_EDIT SETTINGS
// Though it is a perceivable security risk, if you wish you can allow
// non-master GM types to edit themselves. This feature was partially
// disabled due to both foresight and an error in the code.
// If you wish to allow them to edit themselves, set this to 1.
var/const/ALLOW_GM_SELF_EDIT = 1
/********************************************/
// These are initialised later, so no need to initialize yet.
var/list/GMs
var/list/Admins
//var/list/Bad_GM <--- bye bye
// This is initialised later too. It contains a list of all keys that aren't allowed.
var/list/banned
world
New()
..() //do any other user-provided things first
world.log << "Instance opened at approx. [ReportDate(world.realtime)]."
var/savefile/F = new ("s_admin.sav")
F["banned"] >> banned //load banned list
if(isnull(banned)) //if first time starting
banned = new /list //initialise the list
F["GMs"] >> GMs //load the GM list
if(isnull(GMs)) //if this is the first time starting up
GMs = new /list //initialise.
F["Admins"] >> Admins //load the Admin list
if(isnull(Admins)) //if this is the first time starting up
Admins = new /list //initialise.
F["completelist"] >> completelist //load the player history list
if(isnull(completelist)) //if this is the first time starting up
completelist = new /list //initialise.
Del()
var/savefile/F = new ("s_admin.sav")
F["GMs"] << GMs //save the GM list
F["completelist"] << completelist //save the player history list
F["banned"] << banned //save the banned list
// F["Bad GM"] << Bad_GM <--- bye
world.log << "Instance closed at approx. [ReportDate(world.realtime)]."
..() //and finish closing with other user-provided procs
mob/GM_verbs
// The GM verbs mob contains all of the verbs. Players should
// NOT be able to be this type of mob.
verb
GM_Announce(message as message)
set desc = "() Announce something globally"
set category = "GM"
world << "<font color=red><center>________________________________<br>\..."
world << "<b>Announcement:</b><br>[message]<br>\..."
world << "________________________________</center></font>"
world.log << "[src.name] announced, \"[message]\""
GM_Assimilate(mob/M in world)
set desc = "(NPC) Take over the body of an NPC (Caution!)"
set category = "GM"
if(M.key)
usr << "You can't take over PCs' mobs."
return
//Prevents a possible security breach.
if(istype(M,/mob/admin_GM_verbs) || istype(M,/mob/GM_verbs) \
|| istype(M,/mob/master_GM_verbs))
del(M) //delete the mob. There should never be a mob of those types, ever.
world.log << "[src.name] assimilated [M]."
M.key = src.key
GM_Ban(mob/M in world)
set desc = "(person) Remove a player from your world and don't let them return"
set category = "GM"
if(M == src) return
if(!M.key)
usr << "That is not a player."
return
var/hash = 0
if(GMCheck() && (M.GMCheck() || M.AdminGMCheck() || M.MasterGMCheck())) hash = 1
else if(AdminGMCheck() && (M.AdminGMCheck() || M.MasterGMCheck())) hash = 1
else if(MasterGMCheck() && M.MasterGMCheck()) hash = 1
if(hash)
usr << "You can't ban GMs equal to or higher than you in rank!"
M<<alert("[src] tried to ban you.")
return
if(alert("Are you sure?","Ban [M]:","Yes","No") == "Yes")
banned += M.key
if(M.client)
banned += M.client.address
del(M.client)
for(var/mob/O)
if(O.GMCheck() || O.AdminGMCheck() || O.MasterGMCheck())
O << "[src] banned [M]."
world.log << "[src.name] banned [M] ([M.key]) from the world."
del(M)
GM_Unban()
set desc = "() Remove banned keys and IPs from the banned list"
set category = "GM"
var/removal = input("Remove which IP/key from the ban list?","Unban:") as null|anything \
in banned
if(!removal) return
banned -= removal
for(var/mob/M)
if(M.GMCheck() || M.AdminGMCheck() || M.MasterGMCheck())
M << "[src] removed [removal] from the banned list."
GM_Carboncopy(atom/movable/O in world)
set desc = "() Create an exact duplicate of a given object"
set category = "GM"
var/mob/M = O
if(istype(M) && M:key)
usr << "You can't duplicate PCs' mobs."
return
//Prevents possible security breach.
if(istype(O,/mob/GM_verbs) || istype(O,/mob/admin_GM_verbs) \
|| istype(O,/mob/master_GM_verbs))
del(O)
var/atom/new_O = new O.type(O.loc)
for(var/V in O.vars)
if(issaved(O.vars[V])) new_O.vars[V] = O.vars[V]
usr << "[O] was duplicated."
world.log << "[src.name] duplicated \an [O]."
GM_Lock_All_Movement()
set category = "GM"
for(var/mob/M in world)
M._GM_lockmove = 1
M<<"Your Movement Has Been Locked By [usr]."
if((!M.GMCheck() || !M.AdminGMCheck() || !M.MasterGMCheck()))
M._GM_lockmove = 0
M<<"Your Movement Is Restored Because You Are A GM"
GM_UnLock_All_Movement()
set category = "GM"
for(var/mob/M in world)
M._GM_lockmove = 0
M<<"Your Movement Has Been UnLocked By [usr]."
GM_Create()
set desc = "() Create an object of any type"
set category = "GM"
var/html = "<html><body bgcolor=gray text=#CCCCCC link=white vlink=white alink=white>"
var/L[] = typesof(/atom)
//BYOND BUG
/*
//strip out illegal options
if(L.Find(/atom)) L -= /atom
if(L.Find(/atom/movable)) L -= /atom/movable
//don't allow these three types, either
if(L.Find(/mob/GM_verbs)) L -= /mob/GM_verbs
if(L.Find(/mob/master_GM_verbs)) L -= /mob/master_GM_verbs
if(L.Find(/mob/admin_GM_verbs)) L -= /mob/admin_GM_verbs*/
for(var/X in L)
//WORKAROUND FOR ABOVE BUG
switch("[X]")
if("/atom", "/atom/movable", "/mob/GM_verbs", "/mob/master_GM_verbs",
"/mob/admin_GM_verbs") continue //ignore options of these types
//END OF WORKAROUND
html += "<a href=byond://?src=\ref[src];action=create;type=[X]>[X]</a><br>"
usr << browse(html)
GM_Dissappear()
set desc = "() Toggle invisibility and lack of density"
set category = "GM"
src.density = !density
src.invisibility = !invisibility
if(!density)
oview() << "[src] dematerializes and vanishes!"
src << "You dematerialize and vanish."
src.overlays += 'Invis.dmi'
world.log << "[src.name] becomes invisible."
else
oview() << "[src] suddenly rematerializes and appears!"
src << "You materialize and appear."
src.overlays -= 'Invis.dmi'
world.log << "[src.name] becomes visible."
GM_Eradicate(atom/M as mob|obj|turf|area in world)
set desc = "(target) Destroy an mob, obj, or turf"
set category = "GM"
//If they're a player, we should take special consideration and make
//sure that we really do want to boot this person.
var/mob/mob = M
if(istype(mob) && mob.key)
if(mob == src) //don't let people delete themselves!
return
//If the target is a GM that is equal or higher in rank, it sets hash. When hash is
//checked, it'll stop if the GM can't do that.
var/hash = 0
if(GMCheck() && (mob.GMCheck() || mob.AdminGMCheck() || mob.MasterGMCheck())) hash = 1
else if(AdminGMCheck() && (mob.AdminGMCheck() || mob.MasterGMCheck())) hash = 1
else if(MasterGMCheck() && !mob.MasterGMCheck()) hash = 1
if(hash)
usr << "You can't eradicate GMs equal to or higher than you in rank!"
M << "[src] tried to boot you." //tell them there's dissention among the ranks!
return
//If they input yes,
if((input("Are you sure?") in list("Yes","No")) == "Yes")
var/reason = input("Enter a reason if desired.","Reason?") as \
null|text
if(reason)
//This just randomly chooses some "flavour" text. Your reason should generally
//be generic, not suited to any of these, because otherwise it won't make any
//sense.
//An alternate implementation is beneath these.
///*
world << pick(
"A giant hand swoops down to the ground, plucks [mob] into the sky, and \
promptly tosses \him away, whilst shouting <b>\"[reason]\"</b>",
"A vat of liquid nitrogen materialises from nowhere and dumps itself on [mob]. \
The label reads, <b>\"[reason]\"</b>",
"[mob] looks up to see a giant hand. It grabs \him between its fingers and \
smushes him like an ant, booming <b>\"[reason]\"</b>",
"[mob] turns around to see a sniper in the bushes, who promptly puts a hole \
through \his head and says, <b>\"[reason]\"</b>",
"An arrow suddenly flies straight through [mob]'s heart. A note attached to \
the arrow says, <b>\"[reason]\"</b>",
"[mob]'s eyes glaze over as a scroll appears in front of \him that reads \
<b>\"[reason]\"</b> [mob] promptly screams and then vanishes.",
"[mob], suddenly compelled by supernatural forces, writes <b>\"[reason]\"</b> \
in the dirt before committing suicide.",
"A giant sneaker, probably Nike or Reebok, suddenly lands square on top of \
[mob]. A Post-it Note attached to the side reads <b>\"[reason]\"</b>")
//*/
//If you want, remove two slashes before the /* and */ above, and then remove
//the // on the following line, to have a generic bland boot message.
//world << "[src] boots [M] from the world: <b>[reason]</b>"
else
///*
world << pick(
"[mob] suddenly suffers multiple simultaneous heart attacks and collapses \
into a writhing mass of gurgling goo, which drains away into the ground.",
"A giant pit opens in the ground, swallowing [mob] in eternal hellfire, before \
it slams shut once again.",
"An AH-64 Apache Longbow swoops over the horizon and guns down [mob] with \
its chaingun.",
"A glittering golden dragon appears from nowhere, screaming like a banshee, \
eats [mob] in an instant, and vanishes before anyone is any the wiser.",
"[mob] screams as a chestburster erupts from \his internal organs. The alien \
hisses slowly before both [mob] and the creature suddenly vanish.",
"[mob] involuntarily puts \his fingers in \his ears, shouts \"Armageddon!\", \
and explodes, Lemmings-style.",
"[mob] glances up to see a meteor come crashing down on \him, splattering \him \
to pieces.",
"An Klingon D7 Cruiser launches a photon torpedo at [mob] before recloaking and \
warping away.")
//*/
//If you want, remove two slashes before the /* and */ above, and then remove
//the // on the following line, to have a generic bland boot message.
//world << "[src] boots [M] from the world.</b>"
world.log << "[src] boots [M] from the world."
if(mob.client) del(mob.client)
if(mob) del(mob)
else
del(M)
GM_Edit(atom/O in world)
set desc = "(object) Modify/examine the variables of any object"
set category = "GM"
var/html = "<html><body bgcolor=gray text=#CCCCCC link=white vlink=white alink=white>"
var/variables[0]
html += "<h3 align=center>[O.name] ([O.type])</h3>"
html += "<table width=100%>\n"
html += "<tr>"
html += "<td>VARIABLE NAME</td>"
html += "<td>PROBABLE TYPE</td>"
html += "<td>CURRENT VALUE</td>"
html += "</tr>\n"
for(var/X in O.vars) variables += X
//Protect the key var for mobs, since that's a pretty important var! We don't
//want GMs editing players' keys and disconnecting them from their character,
//after all.
variables -= "key"
//Protect the top-secret _temp_gm var! This is used internally only.
variables -= "_temp_gm"
//Prevent this one, too. GMs should use the GM_movement verb so they are aware.
variables -= "_GM_lockmove"
//Also protect these lists because you should never edit lists directly.
//(And, because s_admin isn't capable of editing lists, and never will be.)
variables -= "contents"
variables -= "overlays"
variables -= "underlays"
variables -= "verbs"
variables -= "vars"
variables -= "group"
for(var/X in variables)
html += "<tr>"
html += "<td><a href=byond://?src=\ref[O];action=edit;var=[X]>"
html += X
html += "</a>"
if(!issaved(O.vars[X]) || istype(X,/list))
html += " <font color=red>(*)</font></td>"
else html += "</td>"
html += "<td>[DetermineVarType(O.vars[X])]</td>"
html += "<td>[DetermineVarValue(O.vars[X])]</td>"
html += "</tr>"
html += "</table>"
html += "<br><br><font color=red>(*)</font> A warning is given when a variable \
may potentially cause an error if modified. If you ignore that warning and \
continue to modify the variable, you alone are responsible for whatever \
mayhem results!</body></html>"
usr << browse(html)
GM_Find(O in (typesof(/atom) - /atom) - /atom/movable)
set desc = "() Report coordinates of a desired object"
set category = "GM"
var/L[0]
for(var/atom/A in world)
if(L.len > 20) break
if(istype(A.type,O))
L += A
if(!L.len)
usr << "No objects of type [O] found."
for(var/atom/A in L)
usr << "[A] ([A.type]) [A.x] [A.y] [A.z] -- \..."
usr << null
GM_GMs_list()
set desc = "() Read the list of all GMs' keys"
set category = "GM"
if(GMs.len)
usr << "<b>GMs:</b>"
for(var/X in GMs)
usr << "--> [X]"
if(Admins.len)
usr << "<b>Admins:</b>"
for(var/X in Admins)
usr << "--> [X]"
if(!GMs.len && !Admins.len)
usr << "There are no recorded GMs or Admins."
GM_Locale()
set desc = "() Give your X,Y,Z coordinates, or other location"
set category = "GM"
if(isloc(src.loc)) //if I'm actually in a region
if(istype(src.loc,/atom/movable)) //if I'm in a mob or an obj
var/atom/movable/O = src.loc
usr << "Location: inside [O] at [O.x],[O.y],[O.z]."
else if(isturf(src.loc)) //if I'm on a turf
usr << "Location: on [src.loc] at [x],[y],[z]."
else //if I'm in an area off the map
usr << "Location: in [src.loc]."
else //I'm sitting in nilspace
usr << "Location: nowhere."
GM_Mindwhisper(mob/M as mob in world, T as text)
set desc = "() Silently report a message to someone"
set category = "GM"
M << "Message from <a href=?src=\ref[src];action=mindwhisper>[src]</a>: [T]"
src << "Message to <a href=?src=\ref[M];action=mindwhisper>[M]</a>: [T]"
GM_Movement(mob/M in world)
set desc = "(victim) Remove movement abilities from a player's mob"
set category = "GM"
if((!M.GMCheck() || !M.AdminGMCheck() || !M.MasterGMCheck()))
alert("YOU CANT LOCK DOWN GMS!")
M<<alert("[src] tried to lock you down!")
return
M._GM_lockmove = !M._GM_lockmove
if(M._GM_lockmove)
M << "[src] locks you in place!"
world.log << "[src.name] prevents [M] from moving."
else
M << "[src] releases you."
world.log << "[src.name] allows [M] to move."
GM_Who()
set desc = "() Advanced WHO command - reports all people connected"
set category = "GM"
var/connected[0]
var/linkdead[0]
var/disconnected[] = sessionlist
for(var/mob/M)
if(M.key && M.client)
connected += M
disconnected -= M.key
else if(M.key)
linkdead += M
disconnected -= M.key
if(connected.len)
usr << "<b>Connected:</b>"
for(var/mob/M in connected)
usr << "[M.name] \..."
if(M.key != M.name) usr << "(Key: [M.key]) \..."
usr << "- Inactive for [M.client.inactivity/10] seconds"
if(linkdead.len)
usr << "<b>Linkdead:</b>"
for(var/mob/M in linkdead)
var/key = "(Key: [M.key])"
usr << "[M.name] [M.key != M.name ? key : ""]"
if(disconnected.len)
usr << "<b>No longer connected:</b>"
for(var/keys in disconnected)
usr << "Key: [keys]"
GM_Rename(atom/O in world, new_name as text)
set desc = "(object, new name) Rename any item in the world"
set category = "GM"
if(ismob(O))
var/mob/M = O
var/hash = 0
if(GMCheck() && (M.GMCheck() || M.AdminGMCheck() || M.MasterGMCheck())) hash = 1
else if(AdminGMCheck() && (M.AdminGMCheck() || M.MasterGMCheck())) hash = 1
if(hash)
usr << "You can't rename GMs equal to or higher than you in rank."
M << "[src] tried to rename you to [new_name]."
return
world.log << "[src] renamed [O.name] to \"[new_name]\"."
src.name = new_name
GM_Recorded_people()
set desc = "() Read the recorded history of all players"
set category = "GM"
var/connected[0]
var/linkdead[0]
var/disconnected[] = completelist
for(var/mob/M)
if(M.key && M.client)
connected += M
disconnected -= M.key
else if(M.key)
linkdead += M
disconnected -= M.key
if(connected.len)
usr << "<b>Connected:</b>"
for(var/mob/M in connected)
usr << "[M.name] \..."
if(M.key != M.name) usr << "(Key: [M.key]) \..."
usr << "- Inactive for [M.client.inactivity/10] seconds"
if(linkdead.len)
usr << "<b>Linkdead:</b>"
for(var/mob/M in linkdead)
var/key = "(Key: [M.key])"
usr << "[M.name] [M.key != M.name ? key : ""]"
if(disconnected.len)
usr << "<b>No longer connected:</b>"
for(var/keys in disconnected)
usr << "Key: [keys]"
/*******************************************************************/
//AJ Verb...
// GM_Read_Bad_GM_List()
//This went poofa too
GM_Summon(mob/M in world)
set category = "GM"
if(usr == M)
return
else
M.Move(locate(usr.x,usr.y - 1, usr.z))
M<<"[usr] summoned you!"
usr<<"You summoned [M]!"
GM_Summon_All()
set category = "GM"
for(var/mob/M in world)
if(usr == M)
return
else
M.Move(locate(usr.x,usr.y - 1, usr.z))
M<<"[usr] summoned you!"
/*******************************************************************/
GM_Time()
set desc = "() Get the approx. time the world has been running"
set category = "GM"
usr << "[ReportTime(world.time)] ([ReportDate(world.realtime)])"
GM_Teleport()
set desc = "() Teleport to coordinates, or to a given object"
set category = "GM"
if(!world.maxx)
var/area/area = input("Teleport to which area?","Teleport:") as null|area in world
if(area) src.Move(area)
return
switch(input("Teleport to what?","Teleport:") as null|anything in \
list("coordinates","object"))
if(null) return
if("coordinates")
var/_x = input("(Range: 1 - [world.maxx])","X Coordinate:",src.x) as null|num
var/_y = input("(Range: 1 - [world.maxy])","Y Coordinate:",src.y) as null|num
var/_z = input("(Range: 1 - [world.maxz])","Z Coordinate:",src.z) as null|num
if(_x > world.maxx || _x < 1) return
if(_y > world.maxy || _y < 1) return
if(_z > world.maxz || _z < 1) return
src.loc = locate(_x,_y,_z)
world.log << "[src.name] teleports to [_x],[_y],[_z]."
if("object")
var/atom/movable/O = input("Choose an object:","Object:") as null|mob|obj in world
src.loc = O.loc
world.log << "[src.name] teleports to [O]'s location."
GM_Warp(atom/movable/O in world)
set desc = "() Teleport an object to coordinates, or to another object"
set category = "GM"
if(!world.maxx)
var/area/area = input("Teleport [O] to which area?","Teleport:") as null|area in world
if(area) O.Move(area)
return
switch(input("Teleport [O] to what?","Teleport:") as null|anything in \
list("coordinates","object"))
if(null) return
if("coordinates")
var/_x = input("(Range: 1 - [world.maxx])","X Coordinate:",O.x) as null|num
var/_y = input("(Range: 1 - [world.maxy])","Y Coordinate:",O.y) as null|num
var/_z = input("(Range: 1 - [world.maxz])","Z Coordinate:",O.z) as null|num
if(_x > world.maxx || _x < 1) return
if(_y > world.maxy || _y < 1) return
if(_z > world.maxz || _z < 1) return
O.loc = locate(_x,_y,_z)
world.log << "[src.name] teleports [O] to [_x],[_y],[_z]."
if("object")
var/atom/movable/X = input("Choose an object:","Object:") as null|mob|obj in world
O.loc = X.loc
world.log << "[src.name] teleports [O] to [X]'s location."
mob/admin_GM_verbs
verb
GM_Add_GM(mob/M in world)
set desc = "() Grant GM powers to someone permanently"
set category = "GM"
if(!M.key)
usr << "You can't make NPCs into GMs! Isn't that obvious?"
return
if(M.GMCheck() || M.AdminGMCheck() || M.MasterGMCheck())
usr << "[M] is already a GM or above."
return
else
world << "[M] is granted GM status by [src]."
world.log << "GM [src] (Key: [src.key]) granted GM status to [M] (Key: [M.key])."
GMs += M.key
M.AddGMVerbs()
GM_Remove_GM(mob/M in world)
set desc = "() Strip GM powers from someone permanently"
set category = "GM"
if(M == src)
usr << "You can't remove yourself!"
return
if(!M.GMCheck() && !M.AdminGMCheck() && !M.MasterGMCheck())
usr << "[M] has no GM powers."
return
if(GMCheck() || (AdminGMCheck() && !M.GMCheck()))
usr << "You can't strip GM powers from anyone equal to or higher in rank."
//AJ CHANGE!!! I made it so M got alerted instead of just told. :-p
M << alert("[src] tried to strip your GM powers.")
return
GMs -= M
Admins -= M
world << "[M]'s GM status was stripped by [src]."
world.log << "GM [src] (Key: \"[src.key]\") removed all GM status from [M] \
(Key: \"[M.key]\")."
M.RemoveGMVerbs()
GM_Add_temp_GM(mob/M in world)
set desc = "() Grant temporary GM powers to someone"
set category = "GM"
if(M == src)
usr << "There's no point in explaining what's wrong with using a GM verb to make \
yourself temporarily a GM."
return
if(M.GMCheck() || M.AdminGMCheck() || M.MasterGMCheck())
usr << "[M] is already a GM or above."
return
else
M._temp_gm = 1
world.log << "GM [src] (Key: \"[src.key]\") granted temporary GM status to [M] \
(Key: \"[M.key]\")."
world << "[M] is granted temporary GM powers by [src]."
M.AddGMVerbs()
M << "You now have GM powers until you disconnect from the world."
//AJ THING ADDED!!! I added a repop verb, :-D
GM_Repop()
set category = "GM"
world.Repop()
world<<"[usr] has repop-ed the world!"
mob/master_GM_verbs
verb
//Now THIS is funnnnnnnnnnny! *snicker* *snicker*
//I like this one... anyone wanna help me improve it?
//AAAAAACK! For some reason unknown to me, THE VERB STOPPED WORKIN!
//theres an error of some sort, if you can figure it out please
//lemme know
/* GM_Hack(mob/M in oview())
set category = "GM"
set desc = "Really Freak Somone Out By Making Them Thing They Are Gettin Hacked"
view()<<"<font color = red>Accessing, File 1: Part File 2: Part"
sleep(20)
view()<<"<font color = red>M data accessed... sorting files..."
sleep(20)
view()<<"<font color = red>Accessing Game Data..."
sleep(20)
view()<<"<font color = red>Classify Target as M"
sleep(20)
view()<<"<font color = red>M = Character '[M]'"
sleep(5)
view()<<"<font color = red>Accesing Byond Data..."
sleep(10)
view()<<"<font color = red>M Key = [M.key]"
sleep(5)
view()<<"<font color = red>M Supossed Gender = [M.gender]"
sleep(10)
view()<<"<font color = red>Downloading: C:/Program Files"
sleep(10)
view()<<"<font color = red>Searching For Byond... Checked File [1--]."
sleep(10)
view()<<"<font color = red>Error checking file 4 and 5. Begining Re-check."
sleep(10)
view()<<"<font color = red>Warning! Warning! Virus Located In M Computer"
sleep(10)
view()<<"<font color = red>Tracking..."
sleep(10)
view()<<"<font color = red>Locate unsucsessful, retryng..."
sleep(10)
view()<<"<font color = red>Unable To Locate, searching for encyrpted files."
sleep(10)
view()<<"<font color = red>Located 3 non system files that are encrypted, decypting..."
sleep(10)
view()<<"<font color = red>Part 1 of File 1 is decyrpted. Starting next... finished[2+.]"
sleep(10)
view()<<"<font color = red>File decyrpted, scanning..."
sleep(10)
view()<<"<font color = red>File is clean... decyrpting next..."
sleep(10)
view()<<"<font color = red>Part 1 done... [2+..."
sleep(10)
view()<<"<font color = red>File is double encyrpted... finishing decyrpting..."
sleep(10)
view()<<"<font color = red>Finished... Scanning..."
sleep(7)
view()<<"<font color = red><font size = 3> WARNING! </font> "
sleep(8)
view()<<"<font color = red>Virus tracked scan, Virus protocals have been engauged!"
sleep(7)
view()<<"<font color = red>Begining Anti-Transfer protocals..."
sleep(6)
view()<<"<font color = red>Complete."
sleep(7)
view()<<"Accessing virus data..."
sleep(10)
view()<<"Accessed... Overriding..."
sleep(10)
view()<<"WARNING! Virus override failed, virus compensated for Anti-Transfer protocals!"
sleep(8)
view()<<"Cancled Anti-Transfer... Attemting to override virus before transfer."
sleep(7)
view()<<"Succsess, virus overridden, reversing data..."
sleep(7)
view()<<"Located source! Accessing files..."
sleep(8)
view()<<"Source has been shut down, canceling hacking procedures."
*/
GM_Add_Admin(mob/M in world)
set desc = "() Grant administrative GM powers to someone permanently"
set category = "GM"
if(!M.key)
usr << "You can't make NPCs into GMs! Isn't that obvious?"
return
if(M.AdminGMCheck() || M.MasterGMCheck())
usr << "[M] is already an administrative GM or above."
return
else
if(M.GMCheck())
world << "[M] is upgraded from GM status to Administrative GM status by [src]."
GMs -= M.key
else
world << "[M] is granted Administrative GM status by [src]."
world.log << "GM [src] (Key: \"[src.key]\") granted Admin GM status to [M] \
(Key: \"[M.key]\")."
Admins += M.key
M.AddGMVerbs()
GM_Remove_Admin(mob/M in world)
set desc = "() Strip administrative GM powers from someone permanently"
set category = "GM"
if(!M.AdminGMCheck())
usr << "[M] isn't an admin!"
return
else
world.log << "GM [src] (Key: \"[src.key]\") removed Admin GM status from [M] \
(Key: \"[M.key]\")."
Admins -= M.key
M.RemoveGMVerbs()
M.AddGMVerbs()
// GM_Delete_Bad_GM_List()
//GONE!
//AJ Modification: Reboot
GM_Reboot()
set desc = "() Restart the world"
set category = "GM"
if(alert("Are you sure?","Reboot","Yes","No") == "Yes")
var/mob/M = src
M:GM_Announce("World is rebooting in 10 seconds!")
sleep(10)
M:GM_Announce("World is rebooting in 9 seconds!")
sleep(10)
M:GM_Announce("World is rebooting in 8 seconds!")
sleep(10)
M:GM_Announce("World is rebooting in 7 seconds!")
sleep(10)
M:GM_Announce("World is rebooting in 6 seconds!")
sleep(10)
M:GM_Announce("World is rebooting in 5 seconds!")
sleep(10)
M:GM_Announce("World is rebooting in 4 seconds!")
sleep(10)
M:GM_Announce("World is rebooting in 3 seconds!")
sleep(10)
M:GM_Announce("World is rebooting in 2 seconds!")
sleep(10)
M:GM_Announce("World is rebooting in 1 second!")
sleep(10)
M:GM_Announce("World is rebooting!")
world.Reboot()
//EDITING, CREATING, AND MINDWHISPER HTML INTERACTION
atom/Topic(href,href_list[])
switch(href_list["action"])
if("edit")
if(!usr.GMCheck() && !usr.AdminGMCheck() && !usr.MasterGMCheck())
usr << "You aren't a GM!"
return
var/variable = href_list["var"]
if(ismob(src))
var/mob/M = src
if(!ALLOW_GM_SELF_EDIT)
if(M == usr && (M.GMCheck() || M.AdminGMCheck()))
usr << "You can't edit your own variables or variables of GMs of equal or \
greater rank."
return
if(M != usr)
if(usr.GMCheck() && (M.GMCheck() || M.AdminGMCheck() || M.MasterGMCheck()))
usr << "You can't edit the variables of GMs of equal or greater rank."
return
else if(usr.AdminGMCheck() && (M.AdminGMCheck() || M.MasterGMCheck()))
usr << "You can't edit the variables of GMs of equal or greater rank."
return
var/class = input(usr,"Change [variable] to what?","Variable Type") as null|anything \
in list("text","num","type","reference","icon","file","restore to default")
if(!class) return
var/initial_value = src.vars[variable]
switch(class)
if("restore to default")
src.vars[variable] = initial(src.vars[variable])
if("text")
src.vars[variable] = input("Enter new text:","Text",src.vars[variable]) as text
if("num")
src.vars[variable] = input("Enter new number:","Num",src.vars[variable]) as num
if("type")
src.vars[variable] = input("Enter type:","Type",src.vars[variable]) \
in typesof(/atom)
if("reference")
src.vars[variable] = input("Select reference:","Reference", \
src.vars[variable]) as mob|obj|turf|area in world
if("file")
src.vars[variable] = input("Pick file:","File",src.vars[variable]) \
as file
if("icon")
src.vars[variable] = input("Pick icon:","Icon",src.vars[variable]) \
as icon
world.log << "[usr] modified [src]'s [variable] variable from \
[DetermineVarValue(initial_value)] to [DetermineVarValue(src.vars[variable])]."
usr:GM_Edit(src)
. = ..()
//mobs have different procs.
mob/Topic(href,href_list[])
switch(href_list["action"])
if("create")
if(!usr.GMCheck() && !usr.AdminGMCheck() && !usr.MasterGMCheck())
usr << "You aren't a GM!"
return
var/new_type = href_list["type"]
var/atom/O = new new_type(src.loc)
usr << "Created a new [O.name]."
world.log << "[usr] created a new [O.name]."
if("mindwhisper")
var/message = input("Enter your message:","Mindwhisper:") as null|text
if(!message) return
src << "Message from [usr]: [message]"
usr << "Message to [src]: [message]"
. = ..()
//This is the proc where all the intuitiveness and ease of the code stems from.
mob/proc/AddGMVerbs()
//everyone gets the basic package
if(GMCheck() || AdminGMCheck() || MasterGMCheck())
for(var/X in typesof(/mob/GM_verbs/verb)) //add every verb
src.verbs += X
//the master GM and the admins get a few extras!
if(AdminGMCheck() || MasterGMCheck())
for(var/X in typesof(/mob/admin_GM_verbs/verb)) //add every verb
src.verbs += X
//finally, the master GM gets two more for keeping Admins in line
if(MasterGMCheck())
for(var/X in typesof(/mob/master_GM_verbs/verb))
src.verbs += X
//Set their names to include the prefixes and suffixes.
//Be sure not to allow duplication.
if(MasterGMCheck())
if(MASTER_GM_PREFIX && !findtext(name, MASTER_GM_PREFIX))
src.name = "[MASTER_GM_PREFIX][name]"
if(MASTER_GM_SUFFIX && !findtext(name, MASTER_GM_SUFFIX))
src.name = "[name][MASTER_GM_SUFFIX]"
if(AdminGMCheck())
if(ADMIN_GM_PREFIX && !findtext(name, ADMIN_GM_PREFIX))
src.name = "[ADMIN_GM_PREFIX][name]"
if(ADMIN_GM_SUFFIX && !findtext(name, ADMIN_GM_SUFFIX))
src.name = "[name][ADMIN_GM_SUFFIX]"
if(GMCheck())
if(GM_PREFIX && !findtext(name, GM_PREFIX))
src.name = "[GM_PREFIX][name]"
if(GM_SUFFIX && !findtext(name, GM_SUFFIX))
src.name = "[name][GM_SUFFIX]"
mob/proc/RemoveGMVerbs()
//If you're removing verbs from someone, then you're turning them completely normal.
//Since BYOND ignores list subtractions if the list doesn't contain them, we can
//simply loop through all of the GM verbs and remove each one. Since removal doesn't
//occur too often, this shouldn't be a problem.
for(var/X in typesof(/mob/GM_verbs/verb) + typesof(/mob/admin_GM_verbs/verb) + \
typesof(/mob/master_GM_verbs/verb))
src.verbs -= X
mob/var/tmp/_temp_gm = 0
mob/var/_GM_lockmove = 0
//GM_LOCKMOVE CHECK
// This is an additional check added to mob/Move() to account for the _GM_lockmove
// variable which locks down mobs.
mob/Move()
if(_GM_lockmove) return 0
. = ..()
//GM STATUS PROCS
// These are used to valididate whether a mob is a GM or not. I found myself
// typing these same lines over and over again, so I converted them to procs.
mob/proc/GMCheck()
if(GMs.Find(key) || _temp_gm) return 1
return 0
mob/proc/AdminGMCheck()
if(Admins.Find(key)) return 1
return 0
mob/proc/MasterGMCheck()
if(key == MASTER_KEY) return 1
if(key == MASTER_KEY2) return 1
if(key == MASTER_KEY3) return 1
if(key == MASTER_KEY4) return 1
if(key == MASTER_KEY5) return 1
if(key == MASTER_KEY6) return 1
if(key == MASTER_KEY7) return 1
if(key == MASTER_KEY8) return 1
if(key == MASTER_KEY9) return 1
if(key == MASTER_KEY10) return 1
return 0
//DATE AND TIME PROCS
// These are used to simplify things. The first proc, ReportDate(), will
// convert a time in ticks (after January 1, 2000) to a date in laymans' terms.
// The second (ReportTime()) will convert a time in ticks to a readable number
// in hours, minutes, and seconds.
proc/ReportDate(time)
var/format = "hh:mm:ss MM/DD/YYYY"
return time2text(time, format)
proc/ReportTime(time)
time = round(world.time/10, 1) //round to the nearest second
var/hours = round(time / 3600)
time %= 3600
var/minutes = round(time / 60)
time %= 60
if(minutes < 10) minutes = "0[minutes]"
if(time < 10) time = "0[time]"
return "[hours]:[minutes]:[time]"
//REPLACE_TEXT PROC
// This is a function that does the exact function that dd_replace_text() performs,
// but it avoids using lists, which most likely saves time in transition.
proc/replace_text(string,search,replace)
if(search)
while(findtext(string, search))
var/position = findtext(string, search)
var/first_portion = copytext(string,1,position)
var/last_portion = copytext(string,position+lentext(search))
string = "[first_portion][replace][last_portion]"
return string
//GM_EDIT PROCS
// These are used to format the output of the GM_edit command. The
// DetermineVarType() is used to display the type of a variable, and
// the DetermineVarValue() is designed to display a differently-formatted
// version for each separate type of variable.
proc/DetermineVarType(variable)
if(istext(variable)) return "Text"
if(isloc(variable)) return "Atom"
if(isnum(variable)) return "Num"
if(isicon(variable)) return "Icon"
if(istype(variable,/datum)) return "Type (or datum)"
if(isnull(variable)) return "(Null)"
return "(Unknown)"
proc/DetermineVarValue(variable)
if(istext(variable)) return "\"[variable]\""
if(isloc(variable)) return "<i>[variable:name]</i> ([variable:type])"
if(isnum(variable))
var/return_val = num2text(variable,13)
switch(variable)
if(0) return_val += "<font size=1> (FALSE)</font>"
if(1) return_val += "<font size=1> (TRUE, NORTH, or AREA_LAYER)</font>"
if(2) return_val += "<font size=1> (SOUTH or TURF_LAYER)</font>"
if(3) return_val += "<font size=1> (OBJ_LAYER)</font>"
if(4) return_val += "<font size=1> (EAST or MOB_LAYER)</font>"
if(5) return_val += "<font size=1> (NORTHEAST or FLOAT_LAYER)</font>"
if(6) return_val += "<font size=1> (SOUTHEAST)</font>"
if(8) return_val += "<font size=1> (WEST)</font>"
if(9) return_val += "<font size=1> (NORTHWEST)</font>"
if(10) return_val += "<font size=1> (SOUTHWEST)</font>"
return return_val
if(isnull(variable)) return "null"
return "- [variable] -"
//VERB ADDITION/REMOVAL
// These procs control the default addition and removal of the GM verbs.
// Every time a GM connects to a mob, their former self, if any, will lose all
// of its GM verbs and their current self will gain them. This is yet another
// level of security.
mob/Login()
..()
. = ..()
AddGMVerbs()
mob/Logout()
..()
RemoveGMVerbs()
. = ..()
//SECURITY BREACH COUNTERMEASURES
// These procs are an extra level of security to prevent a person from drawing
// these mob types on the map. You're not allowed!
mob/GM_verbs/New() del(src)
mob/admin_GM_verbs/New() del(src)
mob/master_GM_verbs/New() del(src)
//LOGGING FUNCTIONS
// These add additional logging support for ease in tracking down users.
//Logging lists. The first is initialised earlier, the second is not.
var/list/completelist
var/tmp/list/sessionlist = list() //list of all people recorded this session
client/var/tmp/login_time
client/New()
if(banned.Find(src.key) || banned.Find(src.address))
world.log << "(Key \"[src.key]\" tried to connect, but was banned.)"
del(src)
return
if(MAX_INACTIVITY_TIME > 0) InactivityCheck()
if(!completelist.Find(src.key))
completelist["[src.key]"] = 1
else
completelist["[src.key]"] += 1
world.log << "Key \"[src.key]\" connected for the [completelist[src.key]]\th time \
at approx. [ReportDate(world.realtime)]."
login_time = world.time
if(!sessionlist.Find(key)) sessionlist += key
. = ..()
client/Del()
world.log << "Key \"[src.key]\" disconnected at approx. [ReportDate(world.realtime)] after \
playing for about [ReportTime(world.time - login_time)]."
. = ..()
//INACTIVITY BOOTER
// This will disconnect someone from the world if they have been idle for too long.
client/proc/InactivityCheck()
if(MAX_INACTIVITY_TIME > 0)
//WORKAROUND FOR BUG
if(src.mob)
//END WORKAROUND
//NORMAL PROCEDURE CONTINUES (INDENTED TO TAKE ADVANTAGE OF WORKAROUND)
if(src.inactivity/10 > MAX_INACTIVITY_TIME)
world << "[src.mob] was inactive and was removed from the game."
world.log << "(Key \"[src.key]\" was disconnected due to being inactive.)"
src.mob.Logout()
spawn(rand(100,600)) InactivityCheck()
:O
mob
var
Slimer
Slimeb
Slimeg
Slime = 'Slime.dmi'
Login()
usr.name = copytext(name,1,15)
usr.name = input("What is your name, though Slime Warrior?","Thine's Name")
usr.icon = 'Slime.dmi'
var/cred = input("How much red do you want in your slime? (0,0,0 = Black Slime, 200,200,200 = White Slime)") as num
var/cgreen = input("How much green do you want in your slime? (0,0,0 = Black Slime, 200,200,200 = White Slime)") as num
var/cblue = input("How much blue do you want in your slime? (0,0,0 = Black Slime, 200,200,200 = White Slime)") as num
src.Slimer = cred
src.Slimeg = cgreen
src.Slimeb = cblue
Slime += rgb(src.Slimer,src.Slimeg,src.Slimeb)
src.overlays += src.Slime
loc = locate(88,98,1)
world << "</font><font color = red><B>[usr]</font>, the <B>level (insert level here)</B> has joined the world!"
client
script = "<STYLE>BODY {background: #000077; color: blue}</STYLE>"
world
view = 6
mob/var
speeding = 0
rundelay = 2
client/Move()
if(mob.speeding <= 0)
mob.speeding = 1
..()
sleep(mob.rundelay)
mob.speeding = 0
else
return
My Admin Data, and my Login Data. :O Yeah, I decided to make a slime game with custom colors... so, meh.
Help will be more then greatly appreciated...
NOTE:
I am not in ANYWAY copying Metroid with his series of Slime games, this game will be totally original(Except tiles and icons :P)