Merge branch 'master' into playingWithTravis

This commit is contained in:
Kelenius
2016-03-23 17:12:11 +03:00
311 changed files with 5435 additions and 5458 deletions

View File

@@ -1251,7 +1251,7 @@ proc/admin_notice(var/message, var/rights)
//Returns 1 to let the dragdrop code know we are trapping this event
//Returns 0 if we don't plan to trap the event
/datum/admins/proc/cmd_ghost_drag(var/mob/dead/observer/frommob, var/mob/living/tomob)
/datum/admins/proc/cmd_ghost_drag(var/mob/observer/dead/frommob, var/mob/living/tomob)
if(!istype(frommob))
return //Extra sanity check to make sure only observers are shoved into things

View File

@@ -14,7 +14,7 @@ var/list/admin_ranks = list() //list of all ranks with associated rights
if(!length(line)) continue
if(copytext(line,1,2) == "#") continue
var/list/List = text2list(line,"+")
var/list/List = splittext(line,"+")
if(!List.len) continue
var/rank = ckeyEx(List[1])
@@ -77,7 +77,7 @@ var/list/admin_ranks = list() //list of all ranks with associated rights
if(copytext(line,1,2) == "#") continue
//Split the line at every "-"
var/list/List = text2list(line, "-")
var/list/List = splittext(line, "-")
if(!List.len) continue
//ckey is before the first "-"

View File

@@ -400,9 +400,9 @@ var/list/admin_verbs_mentor = list(
set category = "Admin"
set name = "Aghost"
if(!holder) return
if(istype(mob,/mob/dead/observer))
if(istype(mob,/mob/observer/dead))
//re-enter
var/mob/dead/observer/ghost = mob
var/mob/observer/dead/ghost = mob
if(!is_mentor(usr.client))
ghost.can_reenter_corpse = 1
if(ghost.can_reenter_corpse)
@@ -418,7 +418,7 @@ var/list/admin_verbs_mentor = list(
else
//ghostize
var/mob/body = mob
var/mob/dead/observer/ghost = body.ghostize(1)
var/mob/observer/dead/ghost = body.ghostize(1)
ghost.admin_ghosted = 1
if(body)
body.teleop = ghost

View File

@@ -2,7 +2,7 @@
/datum/admins/proc/create_mob(var/mob/user)
if (!create_mob_html)
var/mobjs = null
mobjs = list2text(typesof(/mob), ";")
mobjs = jointext(typesof(/mob), ";")
create_mob_html = file2text('html/create_object.html')
create_mob_html = replacetext(create_mob_html, "null /* object types */", "\"[mobjs]\"")

View File

@@ -3,7 +3,7 @@
/datum/admins/proc/create_object(var/mob/user)
if (!create_object_html)
var/objectjs = null
objectjs = list2text(typesof(/obj), ";")
objectjs = jointext(typesof(/obj), ";")
create_object_html = file2text('html/create_object.html')
create_object_html = replacetext(create_object_html, "null /* object types */", "\"[objectjs]\"")
@@ -22,7 +22,7 @@
if (!quick_create_object_html)
var/objectjs = null
objectjs = list2text(typesof(path), ";")
objectjs = jointext(typesof(path), ";")
quick_create_object_html = file2text('html/create_object.html')
quick_create_object_html = replacetext(quick_create_object_html, "null /* object types */", "\"[objectjs]\"")

View File

@@ -2,7 +2,7 @@
/datum/admins/proc/create_turf(var/mob/user)
if (!create_turf_html)
var/turfjs = null
turfjs = list2text(typesof(/turf), ";")
turfjs = jointext(typesof(/turf), ";")
create_turf_html = file2text('html/create_object.html')
create_turf_html = replacetext(create_turf_html, "null /* object types */", "\"[turfjs]\"")

View File

@@ -262,7 +262,7 @@
message_admins("\blue [key_name_admin(usr)] has used rudimentary transformation on [key_name_admin(M)]. Transforming to [href_list["simplemake"]]; deletemob=[delmob]", 1)
switch(href_list["simplemake"])
if("observer") M.change_mob_type( /mob/dead/observer , null, null, delmob )
if("observer") M.change_mob_type( /mob/observer/dead , null, null, delmob )
if("larva") M.change_mob_type( /mob/living/carbon/alien/larva , null, null, delmob )
if("nymph") M.change_mob_type( /mob/living/carbon/alien/diona , null, null, delmob )
if("human") M.change_mob_type( /mob/living/carbon/human , null, null, delmob, href_list["species"])
@@ -769,7 +769,7 @@
message_admins("\blue [key_name_admin(usr)] removed [t]", 1)
jobban_remove(t)
href_list["ban"] = 1 // lets it fall through and refresh
var/t_split = text2list(t, " - ")
var/t_split = splittext(t, " - ")
var/key = t_split[1]
var/job = t_split[2]
DB_ban_unban(ckey(key), BANTYPE_JOB_PERMA, job)
@@ -1574,9 +1574,9 @@
alert("Select fewer object types, (max 5)")
return
else if(length(removed_paths))
alert("Removed:\n" + list2text(removed_paths, "\n"))
alert("Removed:\n" + jointext(removed_paths, "\n"))
var/list/offset = text2list(href_list["offset"],",")
var/list/offset = splittext(href_list["offset"],",")
var/number = dd_range(1, 100, text2num(href_list["object_count"]))
var/X = offset.len > 0 ? text2num(offset[1]) : 0
var/Y = offset.len > 1 ? text2num(offset[2]) : 0
@@ -1917,7 +1917,7 @@ mob/living/silicon/ai/can_centcom_reply()
if(client && eyeobj)
return "|<A HREF='?[source];adminplayerobservejump=\ref[eyeobj]'>EYE</A>"
/mob/dead/observer/extra_admin_link(var/source)
/mob/observer/dead/extra_admin_link(var/source)
if(mind && mind.current)
return "|<A HREF='?[source];adminplayerobservejump=\ref[mind.current]'>BDY</A>"

View File

@@ -29,7 +29,7 @@ var/list/adminhelp_ignored_words = list("unknown","the","a","an","of","monkey","
var/original_msg = msg
//explode the input msg into a list
var/list/msglist = text2list(msg, " ")
var/list/msglist = splittext(msg, " ")
//generate keywords lookup
var/list/surnames = list()
@@ -40,7 +40,7 @@ var/list/adminhelp_ignored_words = list("unknown","the","a","an","of","monkey","
if(M.mind) indexing += M.mind.name
for(var/string in indexing)
var/list/L = text2list(string, " ")
var/list/L = splittext(string, " ")
var/surname_found = 0
//surnames
for(var/i=L.len, i>=1, i--)

View File

@@ -1,7 +1,7 @@
/mob/proc/on_mob_jump()
return
/mob/dead/observer/on_mob_jump()
/mob/observer/dead/on_mob_jump()
following = null
/client/proc/Jump(var/area/A in return_sorted_areas())

View File

@@ -21,7 +21,7 @@
if(T.mob)
if(istype(T.mob, /mob/new_player))
targets["(New Player) - [T]"] = T
else if(istype(T.mob, /mob/dead/observer))
else if(istype(T.mob, /mob/observer/dead))
targets["[T.mob.name](Ghost) - [T]"] = T
else
targets["[T.mob.real_name](as [T.mob.name]) - [T]"] = T

View File

@@ -37,11 +37,11 @@ var/inactive_keys = "None<br>"
var/list/ckeys_with_customitems = list()
var/file = file2text("config/custom_items.txt")
var/lines = text2list(file, "\n")
var/lines = splittext(file, "\n")
for(var/line in lines)
// split & clean up
var/list/Entry = text2list(line, ":")
var/list/Entry = splittext(line, ":")
for(var/i = 1 to Entry.len)
Entry[i] = trim(Entry[i])

View File

@@ -85,7 +85,7 @@
var/mob/choice = input("Choose a player to play the pAI", "Spawn pAI") in available
if(!choice)
return 0
if(!istype(choice, /mob/dead/observer))
if(!istype(choice, /mob/observer/dead))
var/confirm = input("[choice.key] isn't ghosting right now. Are you sure you want to yank them out of them out of their body and place them in this pAI?", "Spawn pAI Confirmation", "No") in list("Yes", "No")
if(confirm != "Yes")
return 0
@@ -214,7 +214,7 @@
set name = "Del-All"
// to prevent REALLY stupid deletions
var/blocked = list(/obj, /mob, /mob/living, /mob/living/carbon, /mob/living/carbon/human, /mob/dead, /mob/dead/observer, /mob/living/silicon, /mob/living/silicon/robot, /mob/living/silicon/ai)
var/blocked = list(/obj, /mob, /mob/living, /mob/living/carbon, /mob/living/carbon/human, /mob/observer/dead, /mob/living/silicon, /mob/living/silicon/robot, /mob/living/silicon/ai)
var/hsbitem = input(usr, "Choose an object to delete.", "Delete:") as null|anything in typesof(/obj) + typesof(/mob) - blocked
if(hsbitem)
for(var/atom/O in world)
@@ -282,7 +282,7 @@
if(alert("This mob is being controlled by [M.ckey]. Are you sure you wish to assume control of it? [M.ckey] will be made a ghost.",,"Yes","No") != "Yes")
return
else
var/mob/dead/observer/ghost = new/mob/dead/observer(M,1)
var/mob/observer/dead/ghost = new/mob/observer/dead(M,1)
ghost.ckey = M.ckey
message_admins("\blue [key_name_admin(usr)] assumed direct control of [M].", 1)
log_admin("[key_name(usr)] assumed direct control of [M].")
@@ -932,17 +932,17 @@
switch(input("Which list?") in list("Players","Admins","Mobs","Living Mobs","Dead Mobs", "Clients"))
if("Players")
usr << list2text(player_list,",")
usr << jointext(player_list,",")
if("Admins")
usr << list2text(admins,",")
usr << jointext(admins,",")
if("Mobs")
usr << list2text(mob_list,",")
usr << jointext(mob_list,",")
if("Living Mobs")
usr << list2text(living_mob_list,",")
usr << jointext(living_mob_list,",")
if("Dead Mobs")
usr << list2text(dead_mob_list,",")
usr << jointext(dead_mob_list,",")
if("Clients")
usr << list2text(clients,",")
usr << jointext(clients,",")
// DNA2 - Admin Hax
/client/proc/cmd_admin_toggle_block(var/mob/M,var/block)

View File

@@ -140,7 +140,6 @@ var/list/debug_verbs = list (
,/client/proc/ticklag
,/client/proc/cmd_admin_grantfullaccess
,/client/proc/kaboom
,/client/proc/splash
,/client/proc/cmd_admin_areatest
,/client/proc/cmd_admin_rejuvenate
,/datum/admins/proc/show_traitor_panel

View File

@@ -189,7 +189,7 @@ proc/cmd_admin_mute(mob/M as mob, mute_type, automute = 0)
M.client.prefs.muted |= mute_type
log_admin("SPAM AUTOMUTE: [muteunmute] [key_name(M)] from [mute_string]")
message_admins("SPAM AUTOMUTE: [muteunmute] [key_name_admin(M)] from [mute_string].", 1)
M << "You have been [muteunmute] from [mute_string] by the SPAM AUTOMUTE system. Contact an admin."
M << "<span class='alert'>You have been [muteunmute] from [mute_string] by the SPAM AUTOMUTE system. Contact an admin.</span>"
feedback_add_details("admin_verb","AUTOMUTE") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
return
@@ -202,7 +202,7 @@ proc/cmd_admin_mute(mob/M as mob, mute_type, automute = 0)
log_admin("[key_name(usr)] has [muteunmute] [key_name(M)] from [mute_string]")
message_admins("[key_name_admin(usr)] has [muteunmute] [key_name_admin(M)] from [mute_string].", 1)
M << "You have been [muteunmute] from [mute_string]."
M << "<span class = 'alert'>You have been [muteunmute] from [mute_string].</span>"
feedback_add_details("admin_verb","MUTE") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/cmd_admin_add_random_ai_law()
@@ -234,9 +234,9 @@ Ccomp's first proc.
var/list/mobs = list()
var/list/ghosts = list()
var/list/sortmob = sortAtom(mob_list) // get the mob list.
var/list/sortmob = sortAtom(mob_list) // get the mob list.
var/any=0
for(var/mob/dead/observer/M in sortmob)
for(var/mob/observer/dead/M in sortmob)
mobs.Add(M) //filter it where it's only ghosts
any = 1 //if no ghosts show up, any will just be 0
if(!any)
@@ -266,7 +266,7 @@ Ccomp's first proc.
src << "Hrm, appears you didn't select a ghost" // Sanity check, if no ghosts in the list we don't want to edit a null variable and cause a runtime error.
return
var/mob/dead/observer/G = ghosts[target]
var/mob/observer/dead/G = ghosts[target]
if(G.has_enabled_antagHUD && config.antag_hud_restricted)
var/response = alert(src, "Are you sure you wish to allow this individual to play?","Ghost has used AntagHUD","Yes","No")
if(response == "No") return
@@ -291,9 +291,9 @@ Ccomp's first proc.
src << "Only administrators may use this command."
var/action=""
if(config.antag_hud_allowed)
for(var/mob/dead/observer/g in get_ghosts())
for(var/mob/observer/dead/g in get_ghosts())
if(!g.client.holder) //Remove the verb from non-admin ghosts
g.verbs -= /mob/dead/observer/verb/toggle_antagHUD
g.verbs -= /mob/observer/dead/verb/toggle_antagHUD
if(g.antagHUD)
g.antagHUD = 0 // Disable it on those that have it enabled
g.has_enabled_antagHUD = 2 // We'll allow them to respawn
@@ -302,9 +302,9 @@ Ccomp's first proc.
src << "\red <B>AntagHUD usage has been disabled</B>"
action = "disabled"
else
for(var/mob/dead/observer/g in get_ghosts())
for(var/mob/observer/dead/g in get_ghosts())
if(!g.client.holder) // Add the verb back for all non-admin ghosts
g.verbs += /mob/dead/observer/verb/toggle_antagHUD
g.verbs += /mob/observer/dead/verb/toggle_antagHUD
g << "\blue <B>The Administrator has enabled AntagHUD </B>" // Notify all observers they can now use AntagHUD
config.antag_hud_allowed = 1
action = "enabled"
@@ -324,13 +324,13 @@ Ccomp's first proc.
src << "Only administrators may use this command."
var/action=""
if(config.antag_hud_restricted)
for(var/mob/dead/observer/g in get_ghosts())
for(var/mob/observer/dead/g in get_ghosts())
g << "\blue <B>The administrator has lifted restrictions on joining the round if you use AntagHUD</B>"
action = "lifted restrictions"
config.antag_hud_restricted = 0
src << "\blue <B>AntagHUD restrictions have been lifted</B>"
else
for(var/mob/dead/observer/g in get_ghosts())
for(var/mob/observer/dead/g in get_ghosts())
g << "\red <B>The administrator has placed restrictions on joining the round if you use AntagHUD</B>"
g << "\red <B>Your AntagHUD has been disabled, you may choose to re-enabled it but will be under restrictions </B>"
g.antagHUD = 0
@@ -358,8 +358,8 @@ Traitors and the like can also be revived with the previous role mostly intact.
if(!input)
return
var/mob/dead/observer/G_found
for(var/mob/dead/observer/G in player_list)
var/mob/observer/dead/G_found
for(var/mob/observer/dead/G in player_list)
if(G.ckey == input)
G_found = G
break
@@ -627,7 +627,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
log_admin("[key_name(usr)] has gibbed [key_name(M)]")
message_admins("[key_name_admin(usr)] has gibbed [key_name_admin(M)]", 1)
if(istype(M, /mob/dead/observer))
if(istype(M, /mob/observer/dead))
gibs(M.loc)
return
@@ -640,7 +640,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
var/confirm = alert(src, "You sure?", "Confirm", "Yes", "No")
if(confirm == "Yes")
if (istype(mob, /mob/dead/observer)) // so they don't spam gibs everywhere
if (istype(mob, /mob/observer/dead)) // so they don't spam gibs everywhere
return
else
mob.gib()

View File

@@ -76,9 +76,9 @@
/datum/alarm/proc/cameras()
// reset camera cache
if(camera_cache_id != cache_id)
if(camera_repository.camera_cache_id != cache_id)
cameras = null
cache_id = camera_cache_id
cache_id = camera_repository.camera_cache_id
// If the alarm origin has changed area, for example a borg containing an alarming camera, reset the list of cameras
else if(cameras && (last_camera_area != alarm_area()))
cameras = null

View File

@@ -94,7 +94,7 @@
..()
on_found(mob/finder as mob)
on_found(mob/living/finder as mob)
if(armed)
finder.visible_message("<span class='warning'>[finder] accidentally sets off [src], breaking their fingers.</span>", \
"<span class='warning'>You accidentally trigger [src]!</span>")

View File

@@ -30,7 +30,6 @@
////////////
//SECURITY//
////////////
var/next_allowed_topic_time = 10
// comment out the line below when debugging locally to enable the options & messages menu
//control_freak = 1

View File

@@ -1,7 +1,6 @@
////////////
//SECURITY//
////////////
#define TOPIC_SPAM_DELAY 2 //2 ticks is about 2/10ths of a second; it was 4 ticks, but that caused too many clicks to be lost due to lag
#define UPLOAD_LIMIT 10485760 //Restricts client uploads to the server to 10MB //Boosted this thing. What's the worst that can happen?
#define MIN_CLIENT_VERSION 0 //Just an ambiguously low version for now, I don't want to suddenly stop people playing.
//I would just like the code ready should it ever need to be used.
@@ -24,11 +23,6 @@
if(!usr || usr != mob) //stops us calling Topic for somebody else's client. Also helps prevent usr=null
return
//Reduces spamming of links by dropping calls that happen during the delay period
if(next_allowed_topic_time > world.time)
return
next_allowed_topic_time = world.time + TOPIC_SPAM_DELAY
//search the href for script injection
if( findtext(href,"<script",1,0) )
world.log << "Attempted use of scripts within a topic call, by [src]"

View File

@@ -3,14 +3,16 @@
sort_order = 4
/datum/category_item/player_setup_item/general/equipment/load_character(var/savefile/S)
S["underwear"] >> pref.underwear
S["underwear_top"] >> pref.underwear_top
S["underwear_bottom"] >> pref.underwear_bottom
S["undershirt"] >> pref.undershirt
S["socks"] >> pref.socks
S["backbag"] >> pref.backbag
S["pdachoice"] >> pref.pdachoice
/datum/category_item/player_setup_item/general/equipment/save_character(var/savefile/S)
S["underwear"] << pref.underwear
S["underwear_top"] << pref.underwear_top
S["underwear_bottom"] << pref.underwear_bottom
S["undershirt"] << pref.undershirt
S["socks"] << pref.socks
S["backbag"] << pref.backbag
@@ -22,9 +24,12 @@
if(!islist(pref.gear)) pref.gear = list()
var/undies = get_undies()
if(!get_key_by_value(undies, pref.underwear))
pref.underwear = undies[1]
var/undies_top = get_undies_top()
var/undies_bottom = get_undies_bottom()
if(!get_key_by_value(undies_top, pref.underwear_top))
pref.underwear_top = undies_top[1]
if(!get_key_by_value(undies_bottom, pref.underwear_bottom))
pref.underwear_bottom = undies_bottom[1]
if(!get_key_by_value(undershirt_t, pref.undershirt))
pref.undershirt = undershirt_t[1]
if(!get_key_by_value(socks_t, pref.socks))
@@ -32,21 +37,31 @@
/datum/category_item/player_setup_item/general/equipment/content()
. += "<b>Equipment:</b><br>"
. += "Underwear: <a href='?src=\ref[src];change_underwear=1'><b>[get_key_by_value(get_undies(),pref.underwear)]</b></a><br>"
. += "Underwear Top: <a href='?src=\ref[src];change_underwear_top=1'><b>[get_key_by_value(get_undies_top(),pref.underwear_top)]</b></a><br>"
. += "Underwear Bottom: <a href='?src=\ref[src];change_underwear_bottom=1'><b>[get_key_by_value(get_undies_bottom(),pref.underwear_bottom)]</b></a><br>"
. += "Undershirt: <a href='?src=\ref[src];change_undershirt=1'><b>[get_key_by_value(undershirt_t,pref.undershirt)]</b></a><br>"
. += "Socks: <a href='?src=\ref[src];change_socks=1'><b>[get_key_by_value(socks_t,pref.socks)]</b></a><br>"
. += "Backpack Type: <a href='?src=\ref[src];change_backpack=1'><b>[backbaglist[pref.backbag]]</b></a><br>"
. += "PDA Type: <a href='?src=\ref[src];change_pda=1'><b>[pdachoicelist[pref.pdachoice]]</b></a><br>"
/datum/category_item/player_setup_item/general/equipment/proc/get_undies()
return pref.gender == MALE ? underwear_m : underwear_f
/datum/category_item/player_setup_item/general/equipment/proc/get_undies_top()
return underwear_top_t
/datum/category_item/player_setup_item/general/equipment/proc/get_undies_bottom()
return underwear_bottom_t
/datum/category_item/player_setup_item/general/equipment/OnTopic(var/href,var/list/href_list, var/mob/user)
if(href_list["change_underwear"])
var/underwear_options = get_undies()
var/new_underwear = input(user, "Choose your character's underwear:", "Character Preference", get_key_by_value(get_undies(),pref.underwear)) as null|anything in underwear_options
if(!isnull(new_underwear) && CanUseTopic(user))
pref.underwear = underwear_options[new_underwear]
if(href_list["change_underwear_top"])
var/underwear_top_options = get_undies_top()
var/new_underwear_top = input(user, "Choose your character's top underwear:", "Character Preference", get_key_by_value(get_undies_top(),pref.underwear_top)) as null|anything in underwear_top_options
if(!isnull(new_underwear_top) && CanUseTopic(user))
pref.underwear_top = underwear_top_options[new_underwear_top]
return TOPIC_REFRESH
else if(href_list["change_underwear_bottom"])
var/underwear_bottom_options = get_undies_bottom()
var/new_underwear_bottom = input(user, "Choose your character's bottom underwear:", "Character Preference", get_key_by_value(get_undies_bottom(),pref.underwear_bottom)) as null|anything in underwear_bottom_options
if(!isnull(new_underwear_bottom) && CanUseTopic(user))
pref.underwear_bottom = underwear_bottom_options[new_underwear_bottom]
return TOPIC_REFRESH
else if(href_list["change_undershirt"])

View File

@@ -187,85 +187,253 @@
whitelisted = "Tajara"
/datum/gear/head/hijab
display_name = "Black hijab"
display_name = "hijab, black"
path = /obj/item/clothing/head/hijab
/datum/gear/head/hijab/white
display_name = "White hijab"
display_name = "hijab, white"
path = /obj/item/clothing/head/hijab/white
/datum/gear/head/hijab/aqua
display_name = "Aqua hijab"
display_name = "hijab, aqua"
path = /obj/item/clothing/head/hijab/aqua
/datum/gear/head/hijab/blue
display_name = "Blue hijab"
display_name = "hijab, blue"
path = /obj/item/clothing/head/hijab/blue
/datum/gear/head/hijab/brown
display_name = "Brown hijab"
display_name = "hijab, brown"
path = /obj/item/clothing/head/hijab/brown
/datum/gear/head/hijab/darkblue
display_name = "Dark blue hijab"
display_name = "hijab, dark blue"
path = /obj/item/clothing/head/hijab/darkblue
/datum/gear/head/hijab/darkred
display_name = "Dark red hijab"
display_name = "hijab, dark red"
path = /obj/item/clothing/head/hijab/darkred
/datum/gear/head/hijab/green
display_name = "Green hijab"
display_name = "hijab, green"
path = /obj/item/clothing/head/hijab/green
/datum/gear/head/hijab/green
display_name = "Green hijab"
/datum/gear/head/hijab/grey
display_name = "hijab, grey"
path = /obj/item/clothing/head/hijab/grey
/datum/gear/head/hijab/lightblue
display_name = "Light blue hijab"
display_name = "hijab, light blue"
path = /obj/item/clothing/head/hijab/lightblue
/datum/gear/head/hijab/lightbrown
display_name = "Light brown hijab"
display_name = "hijab, light brown"
path = /obj/item/clothing/head/hijab/lightbrown
/datum/gear/head/hijab/lightgreen
display_name = "Light green hijab"
display_name = "hijab, light green"
path = /obj/item/clothing/head/hijab/lightgreen
/datum/gear/head/hijab/lightpurple
display_name = "Light purple hijab"
display_name = "hijab, light purple"
path = /obj/item/clothing/head/hijab/lightpurple
/datum/gear/head/hijab/lightred
display_name = "Light red hijab"
display_name = "hijab, light red"
path = /obj/item/clothing/head/hijab/lightred
/datum/gear/head/hijab/maroon
display_name = "Maroon hijab"
display_name = "hijab, maroon"
path = /obj/item/clothing/head/hijab/maroon
/datum/gear/head/hijab/orange
display_name = "Orange hijab"
display_name = "hijab, orange"
path = /obj/item/clothing/head/hijab/orange
/datum/gear/head/hijab/pink
display_name = "Pink hijab"
display_name = "hijab, pink"
path = /obj/item/clothing/head/hijab/pink
/datum/gear/head/hijab/purple
display_name = "Purple hijab"
display_name = "hijab, purple"
path = /obj/item/clothing/head/hijab/purple
/datum/gear/head/hijab/red
display_name = "Red hijab"
display_name = "hijab, red"
path = /obj/item/clothing/head/hijab/red
/datum/gear/head/hijab/yellowgreen
display_name = "Yellow green hijab"
display_name = "hijab, yellow green"
path = /obj/item/clothing/head/hijab/yellowgreen
/datum/gear/head/hijab/yellow
display_name = "Yellow hijab"
display_name = "hijab, yellow"
path = /obj/item/clothing/head/hijab/yellow
/datum/gear/head/kippa
display_name = "kippa, black"
path = /obj/item/clothing/head/kippa
/datum/gear/head/kippa/white
display_name = "kippa, white"
path = /obj/item/clothing/head/kippa/white
/datum/gear/head/kippa/aqua
display_name = "kippa, aqua"
path = /obj/item/clothing/head/kippa/aqua
/datum/gear/head/kippa/blue
display_name = "kippa, blue"
path = /obj/item/clothing/head/kippa/blue
/datum/gear/head/kippa/brown
display_name = "kippa, brown"
path = /obj/item/clothing/head/kippa/brown
/datum/gear/head/kippa/darkblue
display_name = "kippa, dark blue"
path = /obj/item/clothing/head/kippa/darkblue
/datum/gear/head/kippa/darkred
display_name = "kippa, dark red"
path = /obj/item/clothing/head/kippa/darkred
/datum/gear/head/kippa/green
display_name = "kippa, green"
path = /obj/item/clothing/head/kippa/green
/datum/gear/head/kippa/grey
display_name = "kippa, grey"
path = /obj/item/clothing/head/kippa/grey
/datum/gear/head/kippa/lightblue
display_name = "kippa, light blue"
path = /obj/item/clothing/head/kippa/lightblue
/datum/gear/head/kippa/lightbrown
display_name = "kippa, light brown"
path = /obj/item/clothing/head/kippa/lightbrown
/datum/gear/head/kippa/lightgreen
display_name = "kippa, light green"
path = /obj/item/clothing/head/kippa/lightgreen
/datum/gear/head/kippa/lightpurple
display_name = "kippa, light purple"
path = /obj/item/clothing/head/kippa/lightpurple
/datum/gear/head/kippa/lightred
display_name = "kippa, light red"
path = /obj/item/clothing/head/kippa/lightred
/datum/gear/head/kippa/maroon
display_name = "kippa, maroon"
path = /obj/item/clothing/head/kippa/maroon
/datum/gear/head/kippa/orange
display_name = "kippa, orange"
path = /obj/item/clothing/head/kippa/orange
/datum/gear/head/kippa/pink
display_name = "kippa, pink"
path = /obj/item/clothing/head/kippa/pink
/datum/gear/head/kippa/purple
display_name = "kippa, purple"
path = /obj/item/clothing/head/kippa/purple
/datum/gear/head/kippa/red
display_name = "kippa, red"
path = /obj/item/clothing/head/kippa/red
/datum/gear/head/kippa/yellowgreen
display_name = "kippa, yellow green"
path = /obj/item/clothing/head/kippa/yellowgreen
/datum/gear/head/kippa/yellow
display_name = "kippa, yellow"
path = /obj/item/clothing/head/kippa/yellow
/datum/gear/head/turban
display_name = "turban, black"
path = /obj/item/clothing/head/turban
/datum/gear/head/turban/white
display_name = "turban, white"
path = /obj/item/clothing/head/turban/white
/datum/gear/head/turban/aqua
display_name = "turban, aqua"
path = /obj/item/clothing/head/turban/aqua
/datum/gear/head/turban/blue
display_name = "turban, blue"
path = /obj/item/clothing/head/turban/blue
/datum/gear/head/turban/brown
display_name = "turban, brown"
path = /obj/item/clothing/head/turban/brown
/datum/gear/head/turban/darkblue
display_name = "turban, dark blue"
path = /obj/item/clothing/head/turban/darkblue
/datum/gear/head/turban/darkred
display_name = "turban, dark red"
path = /obj/item/clothing/head/turban/darkred
/datum/gear/head/turban/green
display_name = "turban, green"
path = /obj/item/clothing/head/turban/green
/datum/gear/head/turban/grey
display_name = "turban, grey"
path = /obj/item/clothing/head/turban/grey
/datum/gear/head/turban/lightblue
display_name = "turban, light blue"
path = /obj/item/clothing/head/turban/lightblue
/datum/gear/head/turban/lightbrown
display_name = "turban, light brown"
path = /obj/item/clothing/head/turban/lightbrown
/datum/gear/head/turban/lightgreen
display_name = "turban, light green"
path = /obj/item/clothing/head/turban/lightgreen
/datum/gear/head/turban/lightpurple
display_name = "turban, light purple"
path = /obj/item/clothing/head/turban/lightpurple
/datum/gear/head/turban/lightred
display_name = "turban, light red"
path = /obj/item/clothing/head/turban/lightred
/datum/gear/head/turban/maroon
display_name = "turban, maroon"
path = /obj/item/clothing/head/turban/maroon
/datum/gear/head/turban/orange
display_name = "turban, orange"
path = /obj/item/clothing/head/turban/orange
/datum/gear/head/turban/pink
display_name = "turban, pink"
path = /obj/item/clothing/head/turban/pink
/datum/gear/head/turban/purple
display_name = "turban, purple"
path = /obj/item/clothing/head/turban/purple
/datum/gear/head/turban/red
display_name = "turban, red"
path = /obj/item/clothing/head/turban/red
/datum/gear/head/turban/yellowgreen
display_name = "turban, yellow green"
path = /obj/item/clothing/head/turban/yellowgreen
/datum/gear/head/turban/yellow
display_name = "turban, yellow"
path = /obj/item/clothing/head/turban/yellow

View File

@@ -98,6 +98,10 @@
display_name = "hoodie, NT"
path = /obj/item/clothing/suit/storage/toggle/hoodie/nt
/datum/gear/suit/hoodie/smw
display_name = "hoodie, Space Mountain Wind"
path = /obj/item/clothing/suit/storage/toggle/hoodie/smw
/datum/gear/suit/labcoat
display_name = "labcoat"
path = /obj/item/clothing/suit/storage/toggle/labcoat
@@ -161,6 +165,10 @@
display_name = "poncho, red"
path = /obj/item/clothing/suit/poncho/red
/datum/gear/suit/poncho/security
display_name = "poncho, security"
path = /obj/item/clothing/suit/poncho/security
/datum/gear/suit/unathi_robe
display_name = "roughspun robe"
path = /obj/item/clothing/suit/unathi/robe

View File

@@ -192,6 +192,21 @@
path = /obj/item/clothing/under/rank/cargo/skirt
allowed_roles = list("Quartermaster")
/datum/gear/uniform/skirt/warden
display_name = "skirt, warden"
path = /obj/item/clothing/under/rank/warden/skirt
allowed_roles = list("Head of Security", "Warden")
/datum/gear/uniform/skirt/security
display_name = "skirt, security"
path = /obj/item/clothing/under/rank/security/skirt
allowed_roles = list("Head of Security", "Warden", "Detective", "Security Officer")
/datum/gear/uniform/skirt/head_of_security
display_name = "skirt, hos"
path = /obj/item/clothing/under/rank/head_of_security/skirt
allowed_roles = list("Head of Security")
/datum/gear/uniform/jeans_qm
display_name = "jeans, QM"
path = /obj/item/clothing/under/rank/cargo/jeans
@@ -383,7 +398,7 @@
/datum/gear/uniform/scrubs
display_name = "scrubs, black"
path = /obj/item/clothing/under/rank/medical/black
allowed_roles = list("Medical Doctor","Chief Medical Officer","Chemist","Paramedic","Geneticist")
allowed_roles = list("Medical Doctor","Chief Medical Officer","Chemist","Paramedic","Geneticist", "Roboticist")
/datum/gear/uniform/scrubs/blue
display_name = "scrubs, blue"

View File

@@ -30,7 +30,8 @@ datum/preferences
var/age = 30 //age of character
var/spawnpoint = "Arrivals Shuttle" //where this character will spawn (0-2).
var/b_type = "A+" //blood type (not-chooseable)
var/underwear //underwear type
var/underwear_top
var/underwear_bottom
var/undershirt //undershirt type
var/socks //socks type
var/backbag = 2 //backpack type
@@ -333,7 +334,8 @@ datum/preferences
else if(status == "mechanical")
I.robotize()
character.underwear = underwear
character.underwear_bottom = underwear_bottom
character.underwear_top = underwear_top
character.undershirt = undershirt
character.socks = socks

View File

@@ -659,7 +659,7 @@
/obj/item/clothing/under/proc/set_sensors(mob/usr as mob)
var/mob/M = usr
if (istype(M, /mob/dead/)) return
if (istype(M, /mob/observer)) return
if (usr.stat || usr.restrained()) return
if(has_sensor >= 2)
usr << "The controls are locked."

View File

@@ -380,4 +380,222 @@
/obj/item/clothing/head/hijab/yellow
name = "yellow hijab"
desc = "A yellow veil that is wrapped to cover the head and chest"
icon_state = "hijab_yellow"
icon_state = "hijab_yellow"
//Kippot
/obj/item/clothing/head/kippa
name = "black kippa"
desc = "A small, brimless cap. It is black."
icon_state = "kippa_black"
body_parts_covered = 0
/obj/item/clothing/head/kippa/aqua
name = "aqua kippa"
desc = "A small, brimless cap. It is aqua."
icon_state = "kippa_aqua"
/obj/item/clothing/head/kippa/blue
name = "blue kippa"
desc = "A small, brimless cap. It is blue."
icon_state = "kippa_blue"
/obj/item/clothing/head/kippa/brown
name = "brown kippa"
desc = "A small, brimless cap. It is blue."
icon_state = "kippa_brown"
/obj/item/clothing/head/kippa/darkblue
name = "dark blue kippa"
desc = "A small, brimless cap. It is dark blue."
icon_state = "kippa_darkblue"
/obj/item/clothing/head/kippa/darkred
name = "dark red kippa"
desc = "A small, brimless cap. It is dark red."
icon_state = "kippa_darkred"
/obj/item/clothing/head/kippa/green
name = "green kippa"
desc = "A small, brimless cap. It is green."
icon_state = "kippa_green"
/obj/item/clothing/head/kippa/grey
name = "grey kippa"
desc = "A small, brimless cap. It is grey."
icon_state = "kippa_grey"
/obj/item/clothing/head/kippa/lightblue
name = "light blue kippa"
desc = "A small, brimless cap. It is light blue."
icon_state = "kippa_lightblue"
/obj/item/clothing/head/kippa/lightbrown
name = "light brown kippa"
desc = "A small, brimless cap. It is light brown."
icon_state = "kippa_lightbrown"
/obj/item/clothing/head/kippa/lightgreen
name = "light green kippa"
desc = "A small, brimless cap. It is light green."
icon_state = "kippa_lightgreen"
/obj/item/clothing/head/kippa/lightpurple
name = "light purple kippa"
desc = "A small, brimless cap. It is light purple."
icon_state = "kippa_lightpurple"
/obj/item/clothing/head/kippa/lightred
name = "light red kippa"
desc = "A small, brimless cap. It is light red."
icon_state = "kippa_lightred"
/obj/item/clothing/head/kippa/maroon
name = "maroon kippa"
desc = "A small, brimless cap. It is maroon."
icon_state = "kippa_maroon"
/obj/item/clothing/head/kippa/orange
name = "orange kippa"
desc = "A small, brimless cap. It is orange."
icon_state = "kippa_orange"
/obj/item/clothing/head/kippa/pink
name = "pink kippa"
desc = "A small, brimless cap. It is pink."
icon_state = "kippa_pink"
/obj/item/clothing/head/kippa/purple
name = "purple kippa"
desc = "A small, brimless cap. It is purple."
icon_state = "kippa_purple"
/obj/item/clothing/head/kippa/red
name = "red kippa"
desc = "A small, brimless cap. It is red."
icon_state = "kippa_red"
/obj/item/clothing/head/kippa/white
name = "white kippa"
desc = "A small, brimless cap. It is white."
icon_state = "kippa_white"
/obj/item/clothing/head/kippa/yellowgreen
name = "yellow green kippa"
desc = "A small, brimless cap. It is yellow green."
icon_state = "kippa_yellowgreen"
/obj/item/clothing/head/kippa/yellow
name = "yellow kippa"
desc = "A small, brimless cap. It is yellow."
icon_state = "kippa_yellow"
//Turbans
/obj/item/clothing/head/turban
name = "black turban"
desc = "A black cloth used to wind around the head"
icon_state = "turban_black"
body_parts_covered = 0
flags_inv = BLOCKHAIR
/obj/item/clothing/head/turban/aqua
name = "aqua turban"
desc = "An aqua cloth used to wind around the head."
icon_state = "turban_aqua"
/obj/item/clothing/head/turban/blue
name = "blue turban"
desc = "A blue cloth used to wind around the head."
icon_state = "turban_blue"
/obj/item/clothing/head/turban/brown
name = "brown turban"
desc = "A brown cloth used to wind around the head."
icon_state = "turban_brown"
/obj/item/clothing/head/turban/darkblue
name = "dark blue turban"
desc = "A dark blue cloth used to wind around the head."
icon_state = "turban_darkblue"
/obj/item/clothing/head/turban/darkred
name = "dark red turban"
desc = "A dark red cloth used to wind around the head."
icon_state = "turban_darkred"
/obj/item/clothing/head/turban/green
name = "green turban"
desc = "A green cloth used to wind around the head."
icon_state = "turban_green"
/obj/item/clothing/head/turban/grey
name = "grey turban"
desc = "A grey cloth used to wind around the head."
icon_state = "turban_grey"
/obj/item/clothing/head/turban/lightblue
name = "light blue turban"
desc = "A light blue cloth used to wind around the head."
icon_state = "turban_lightblue"
/obj/item/clothing/head/turban/lightbrown
name = "light brown turban"
desc = "A light brown cloth used to wind around the head."
icon_state = "turban_lightbrown"
/obj/item/clothing/head/turban/lightgreen
name = "light green turban"
desc = "A light green cloth used to wind around the head."
icon_state = "turban_lightgreen"
/obj/item/clothing/head/turban/lightpurple
name = "light purple turban"
desc = "A light purple cloth used to wind around the head."
icon_state = "turban_lightpurple"
/obj/item/clothing/head/turban/lightred
name = "light red turban"
desc = "A light red cloth used to wind around the head."
icon_state = "turban_lightred"
/obj/item/clothing/head/turban/maroon
name = "maroon turban"
desc = "A maroon cloth used to wind around the head."
icon_state = "turban_maroon"
/obj/item/clothing/head/turban/orange
name = "orange turban"
desc = "An orange cloth used to wind around the head."
icon_state = "turban_orange"
/obj/item/clothing/head/turban/pink
name = "pink turban"
desc = "A pink cloth used to wind around the head."
icon_state = "turban_pink"
/obj/item/clothing/head/turban/purple
name = "purple turban"
desc = "A purple cloth used to wind around the head."
icon_state = "turban_purple"
/obj/item/clothing/head/turban/red
name = "red turban"
desc = "A red cloth used to wind around the head."
icon_state = "turban_red"
/obj/item/clothing/head/turban/white
name = "white turban"
desc = "A white cloth used to wind around the head."
icon_state = "turban_white"
/obj/item/clothing/head/turban/yellowgreen
name = "yellow green turban"
desc = "A yellow green cloth used to wind around the head."
icon_state = "turban_yellowgreen"
/obj/item/clothing/head/turban/yellow
name = "yellow turban"
desc = "A yellow cloth used to wind around the head."
icon_state = "turban_yellow"

View File

@@ -76,7 +76,7 @@
var/turf/location = src.loc
if(istype(location, /mob/))
var/mob/living/carbon/human/M = location
if(M.l_hand == src || M.r_hand == src || M.head == src)
if(M.item_is_in_hands(src) || M.head == src)
location = M.loc
if (istype(location, /turf))

View File

@@ -22,7 +22,7 @@
say_verbs = list("mumbles", "says")
// Clumsy folks can't take the mask off themselves.
/obj/item/clothing/mask/muzzle/attack_hand(mob/user as mob)
/obj/item/clothing/mask/muzzle/attack_hand(mob/living/user as mob)
if(user.wear_mask == src && !user.IsAdvancedToolUser())
return 0
..()
@@ -129,7 +129,7 @@
item_state = "s-ninja"
flags_inv = HIDEFACE
body_parts_covered = 0
var/mob/eye/aiEye/eye
var/mob/observer/eye/aiEye/eye
/obj/item/clothing/mask/ai/New()
eye = new(src)

View File

@@ -2,7 +2,7 @@
name = "leg guards"
desc = "These will protect your legs and feet."
body_parts_covered = LEGS|FEET
slowdown = 1
slowdown = 0 //Shoes have a slowdown of -1, so this needs to be 0 in order for it to effectively be 1 slowdown.
w_class = 3
/obj/item/clothing/shoes/leg_guard/mob_can_equip(var/mob/living/carbon/human/H, slot, disable_warning = 0)
@@ -39,4 +39,4 @@
desc = "These will protect your legs and feet from a variety of weapons."
icon_state = "leg_guards_combat"
siemens_coefficient = 0.6
armor = list(melee = 50, bullet = 50, laser = 50, energy = 30, bomb = 30, bio = 0, rad = 0)
armor = list(melee = 50, bullet = 50, laser = 50, energy = 30, bomb = 30, bio = 0, rad = 0)

View File

@@ -139,7 +139,7 @@
list("dexalin plus", "dexalinp", 0, 80),
list("antibiotics", "spaceacillin", 0, 80),
list("antitoxins", "anti_toxin", 0, 80),
list("nutrients", "nutriment", 0, 80),
list("nutrients", "glucose", 0, 80),
list("hyronalin", "hyronalin", 0, 80),
list("radium", "radium", 0, 80)
)
@@ -156,7 +156,7 @@
list("dexalin plus", "dexalinp", 0, 20),
list("antibiotics", "spaceacillin", 0, 20),
list("antitoxins", "anti_toxin", 0, 20),
list("nutrients", "nutriment", 0, 80),
list("nutrients", "glucose", 0, 80),
list("hyronalin", "hyronalin", 0, 20),
list("radium", "radium", 0, 20)
)
@@ -245,7 +245,7 @@
list("synaptizine", "synaptizine", 0, 30),
list("hyperzine", "hyperzine", 0, 30),
list("oxycodone", "oxycodone", 0, 30),
list("nutrients", "nutriment", 0, 80),
list("nutrients", "glucose", 0, 80),
)
interface_name = "combat chem dispenser"

View File

@@ -1,6 +1,6 @@
/obj/item/weapon/rig/attackby(obj/item/W as obj, mob/user as mob)
/obj/item/weapon/rig/attackby(obj/item/W as obj, mob/living/user as mob)
if(!istype(user,/mob/living)) return 0
if(!istype(user)) return 0
if(electrified != 0)
if(shock(user)) //Handles removing charge from the cell, as well. No need to do that here.

View File

@@ -343,6 +343,12 @@
icon_state = "blueponcho"
item_state = "blueponcho"
/obj/item/clothing/suit/poncho/security
name = "security poncho"
desc = "A simple, comfortable cloak without sleeves. This one is black and red, standard NanoTrasen Security colors."
icon_state = "secponcho"
item_state = "secponcho"
/obj/item/clothing/suit/jacket/puffer
name = "puffer jacket"
desc = "A thick jacket with a rubbery, water-resistant shell."
@@ -502,6 +508,14 @@
icon_open = "nt_hoodie_open"
icon_closed = "nt_hoodie"
/obj/item/clothing/suit/storage/toggle/hoodie/smw
name = "Space Mountain Wind hoodie"
desc = "A warm, black sweatshirt. It has the logo for the popular softdrink Space Mountain Wind on both the front and the back."
icon_state = "smw_hoodie"
item_state = "smw_hoodie"
icon_open = "smw_hoodie_open"
icon_closed = "smw_hoodie"
// FUN!
/obj/item/clothing/suit/whitedress

View File

@@ -18,6 +18,13 @@
siemens_coefficient = 0.9
rolled_sleeves = 0
/obj/item/clothing/under/rank/warden/skirt
desc = "Standard feminine fashion for a Warden. It is made of sturdier material than standard jumpskirts. It has the word \"Warden\" written on the shoulders."
name = "warden's jumpskirt"
icon_state = "wardenf"
item_state = "r_suit"
worn_state = "wardenf"
/obj/item/clothing/head/helmet/warden
name = "warden's hat"
desc = "It's a special helmet issued to the Warden of a securiy force."
@@ -34,6 +41,13 @@
siemens_coefficient = 0.9
rolled_sleeves = 0
/obj/item/clothing/under/rank/security/skirt
name = "security officer's jumpskirt"
desc = "Standard feminine fashion for Security Officers. It's made of sturdier material than the standard jumpskirts."
icon_state = "secredf"
item_state = "r_suit"
worn_state = "secredf"
/obj/item/clothing/under/rank/dispatch
name = "dispatcher's uniform"
desc = "A dress shirt and khakis with a security patch sewn on."
@@ -127,7 +141,7 @@
icon_state = "detective2_waistcoat"
worn_state = "detective2_waistcoat"
desc = "A serious-looking tan dress shirt paired with freshly-pressed black slacks, complete with a red striped tie and waistcoat."
/obj/item/clothing/head/det
name = "fedora"
@@ -160,6 +174,13 @@
siemens_coefficient = 0.8
rolled_sleeves = 0
/obj/item/clothing/under/rank/head_of_security/skirt
desc = "It's a fashionable jumpskirt worn by those few with the dedication to achieve the position of \"Head of Security\". It has additional armor to protect the wearer."
name = "head of security's jumpskirt"
icon_state = "hosredf"
item_state = "r_suit"
worn_state = "hosredf"
/obj/item/clothing/under/rank/head_of_security/corp
icon_state = "hos_corporate"
//item_state = "hos_corporate"

View File

@@ -75,7 +75,7 @@
K.new_icon_file = CUSTOM_ITEM_OBJ
if(istype(item, /obj/item/device/kit/paint))
var/obj/item/device/kit/paint/kit = item
kit.allowed_types = text2list(additional_data, ", ")
kit.allowed_types = splittext(additional_data, ", ")
else if(istype(item, /obj/item/device/kit/suit))
var/obj/item/device/kit/suit/kit = item
kit.new_light_overlay = additional_data
@@ -130,7 +130,7 @@
/hook/startup/proc/load_custom_items()
var/datum/custom_item/current_data
for(var/line in text2list(file2text("config/custom_items.txt"), "\n"))
for(var/line in splittext(file2text("config/custom_items.txt"), "\n"))
line = trim(line)
if(line == "" || !line || findtext(line, "#", 1, 2))
@@ -173,7 +173,7 @@
if("req_access")
current_data.req_access = text2num(field_data)
if("req_titles")
current_data.req_titles = text2list(field_data,", ")
current_data.req_titles = splittext(field_data,", ")
if("kit_name")
current_data.kit_name = field_data
if("kit_desc")

View File

@@ -16,7 +16,7 @@
user << "<span class='warning'>There is already a slide in the microscope.</span>"
return
if(istype(W, /obj/item/weapon/forensics/slide) || istype(W, /obj/item/weapon/sample/print))
if(istype(W, /obj/item/weapon/forensics/swab)|| istype(W, /obj/item/weapon/sample/fibers) || istype(W, /obj/item/weapon/sample/print))
user << "<span class='notice'>You insert \the [W] into the microscope.</span>"
user.unEquip(W)
W.forceMove(src)
@@ -33,6 +33,7 @@
user << "<span class='notice'>The microscope whirrs as you examine \the [sample].</span>"
if(!do_after(user, 25) || !sample)
user << "<span class='notice'>You stop examining \the [sample].</span>"
return
user << "<span class='notice'>Printing findings now...</span>"
@@ -41,32 +42,27 @@
report.overlays = list("paper_stamped")
report_num++
if(istype(sample, /obj/item/weapon/forensics/slide))
var/obj/item/weapon/forensics/slide/slide = sample
if(slide.has_swab)
var/obj/item/weapon/forensics/swab/swab = slide.has_swab
if(istype(sample, /obj/item/weapon/forensics/swab))
var/obj/item/weapon/forensics/swab/swab = sample
report.name = "GSR report #[++report_num]: [swab.name]"
report.info = "<b>Scanned item:</b><br>[swab.name]<br><br>"
report.name = "GSR report #[++report_num]: [swab.name]"
report.info = "<b>Scanned item:</b><br>[swab.name]<br><br>"
if(swab.gsr)
report.info += "Residue from a [swab.gsr] bullet detected."
else
report.info += "No gunpowder residue found."
else if(slide.has_sample)
var/obj/item/weapon/sample/fibers/fibers = slide.has_sample
report.name = "Fiber report #[++report_num]: [fibers.name]"
report.info = "<b>Scanned item:</b><br>[fibers.name]<br><br>"
if(fibers.evidence)
report.info = "Molecular analysis on provided sample has determined the presence of unique fiber strings.<br><br>"
for(var/fiber in fibers.evidence)
report.info += "<span class='notice'>Most likely match for fibers: [fiber]</span><br><br>"
else
report.info += "No fibers found."
if(swab.gsr)
report.info += "Residue from a [swab.gsr] bullet detected."
else
report.name = "Empty slide report #[report_num]"
report.info = "Evidence suggests that there's nothing in this slide."
report.info += "No gunpowder residue found."
else if(istype(sample, /obj/item/weapon/sample/fibers))
var/obj/item/weapon/sample/fibers/fibers = sample
report.name = "Fiber report #[++report_num]: [fibers.name]"
report.info = "<b>Scanned item:</b><br>[fibers.name]<br><br>"
if(fibers.evidence)
report.info = "Molecular analysis on provided sample has determined the presence of unique fiber strings.<br><br>"
for(var/fiber in fibers.evidence)
report.info += "<span class='notice'>Most likely match for fibers: [fiber]</span><br><br>"
else
report.info += "No fibers found."
else if(istype(sample, /obj/item/weapon/sample/print))
report.name = "Fingerprint report #[report_num]: [sample.name]"
report.info = "<b>Fingerprint analysis report #[report_num]</b>: [sample.name]<br>"

View File

@@ -1,42 +0,0 @@
/obj/item/weapon/forensics/slide
name = "microscope slide"
desc = "A pair of thin glass panes used in the examination of samples beneath a microscope."
icon_state = "slide"
var/obj/item/weapon/forensics/swab/has_swab
var/obj/item/weapon/sample/fibers/has_sample
/obj/item/weapon/forensics/slide/attackby(var/obj/item/weapon/W, var/mob/user)
if(has_swab || has_sample)
user << "<span class='warning'>There is already a sample in the slide.</span>"
return
if(istype (W, /obj/item/weapon/forensics/swab))
has_swab = W
else if(istype(W, /obj/item/weapon/sample/fibers))
has_sample = W
else
user << "<span class='warning'>You don't think this will fit.</span>"
return
user << "<span class='notice'>You insert the sample into the slide.</span>"
user.unEquip(W)
W.forceMove(src)
update_icon()
/obj/item/weapon/forensics/slide/attack_self(var/mob/user)
if(has_swab || has_sample)
user << "<span class='notice'>You remove \the sample from \the [src].</span>"
if(has_swab)
has_swab.loc = get_turf(src)
has_swab = null
if(has_sample)
has_sample.forceMove(get_turf(src))
has_sample = null
update_icon()
return
/obj/item/weapon/forensics/slide/update_icon()
if(!has_swab && !has_sample)
icon_state = "slide"
else if(has_swab)
icon_state = "slideswab"
else if(has_sample)
icon_state = "slidefiber"

View File

@@ -15,7 +15,7 @@
var/mob/living/carbon/human/user = usr
if (!(user.l_hand == src || user.r_hand == src))
if(!user.item_is_in_hands(src))
return //bag must be in your hands to use
if (isturf(I.loc))
@@ -31,10 +31,8 @@
var/obj/item/weapon/storage/U = I.loc
user.client.screen -= I
U.contents.Remove(I)
else if(user.l_hand == I) //in a hand
user.drop_l_hand()
else if(user.r_hand == I) //in a hand
user.drop_r_hand()
else if(user.item_is_in_hands(I))
user.drop_from_inventory(I)
else
return

View File

@@ -11,16 +11,6 @@
for(var/i=0;i<storage_slots,i++) // Fill 'er up.
new /obj/item/weapon/forensics/swab(src)
/obj/item/weapon/storage/box/slides
name = "microscope slide box"
icon_state = "solution_trays"
storage_slots = 7
/obj/item/weapon/storage/box/slides/New()
..()
for(var/i=0;i<storage_slots,i++)
new /obj/item/weapon/forensics/slide(src)
/obj/item/weapon/storage/box/evidence
name = "evidence bag box"
desc = "A box claiming to contain evidence bags."

View File

@@ -68,7 +68,7 @@
/obj/item/weapon/forensics/swab/afterattack(var/atom/A, var/mob/user, var/proximity)
if(!proximity || istype(A, /obj/item/weapon/forensics/slide) || istype(A, /obj/machinery/dnaforensics))
if(!proximity || istype(A, /obj/machinery/dnaforensics))
return
if(is_used())

View File

@@ -51,10 +51,6 @@
overlays -= "register_cash"
else
open_cash_box()
// Reset if necessary
else if(transaction_amount)
reset_memory()
user << "<span class='notice'>You reset the machine's memory.</span>"
else
user.set_machine(src)
interact(user)
@@ -76,7 +72,12 @@
dat += "Linked account: <a href='?src=\ref[src];choice=link_account'>[linked_account ? linked_account.owner_name : "None"]</a><br>"
dat += "<a href='?src=\ref[src];choice=toggle_cash_lock'>[cash_locked? "Unlock" : "Lock"] Cash Box</a> | "
dat += "<a href='?src=\ref[src];choice=custom_order'>Custom Order</a><hr>"
for(var/i=1, i<=transaction_logs.len, i++)
if(item_list.len)
dat += get_current_transaction()
dat += "<br>"
for(var/i=transaction_logs.len, i>=1, i--)
dat += "[transaction_logs[i]]<br>"
if(transaction_logs.len)
@@ -118,12 +119,46 @@
if (!t_purpose || !Adjacent(usr)) return
transaction_purpose = t_purpose
item_list += t_purpose
var/t_amount = input("Enter price", "New price") as num
var/t_amount = round(input("Enter price", "New price") as num)
if (!t_amount || !Adjacent(usr)) return
transaction_amount += t_amount
price_list += t_amount
playsound(src, 'sound/machines/twobeep.ogg', 25)
src.visible_message("\icon[src][transaction_purpose]: [transaction_amount] Thaler\s.")
src.visible_message("\icon[src][transaction_purpose]: [t_amount] Thaler\s.")
if("set_amount")
var/item_name = locate(href_list["item"])
var/n_amount = round(input("Enter amount", "New amount") as num)
n_amount = Clamp(n_amount, 0, 20)
if (!item_list[item_name] || !Adjacent(usr)) return
transaction_amount += (n_amount - item_list[item_name]) * price_list[item_name]
if(!n_amount)
item_list -= item_name
price_list -= item_name
else
item_list[item_name] = n_amount
if("subtract")
var/item_name = locate(href_list["item"])
if(item_name)
transaction_amount -= price_list[item_name]
item_list[item_name]--
if(item_list[item_name] <= 0)
item_list -= item_name
price_list -= item_name
if("add")
var/item_name = locate(href_list["item"])
if(item_list[item_name] >= 20) return
transaction_amount += price_list[item_name]
item_list[item_name]++
if("clear")
var/item_name = locate(href_list["item"])
if(item_name)
transaction_amount -= price_list[item_name] * item_list[item_name]
item_list -= item_name
price_list -= item_name
else
transaction_amount = 0
item_list.Cut()
price_list.Cut()
if("reset_log")
transaction_logs.Cut()
usr << "\icon[src]<span class='notice'>Transaction log reset.</span>"
@@ -180,18 +215,18 @@
if (!transaction_amount)
return
if(!confirm(I))
if (cash_open)
playsound(src, 'sound/machines/buzz-sigh.ogg', 25)
usr << "\icon[src]<span class='warning'>The cash box is open.</span>"
return
if((item_list.len > 1 || item_list[item_list[1]] > 1) && !confirm(I))
return
if (!linked_account)
usr.visible_message("\icon[src]<span class='warning'>Unable to connect to linked account.</span>")
return
if (cash_open)
playsound(src, 'sound/machines/buzz-sigh.ogg', 25)
usr << "\icon[src]<span class='warning'>The cash box is open.</span>"
return
// Access account for transaction
if(check_account())
var/datum/money_account/D = get_account(I.associated_account_number)
@@ -245,14 +280,14 @@
if (!transaction_amount)
return
if(!confirm(E))
return
if (cash_open)
playsound(src, 'sound/machines/buzz-sigh.ogg', 25)
usr << "\icon[src]<span class='warning'>The cash box is open.</span>"
return
if((item_list.len > 1 || item_list[item_list[1]] > 1) && !confirm(E))
return
// Access account for transaction
if(check_account())
if(transaction_amount > E.worth)
@@ -283,14 +318,14 @@
if (!transaction_amount)
return
if(!confirm(SC))
return
if (cash_open)
playsound(src, 'sound/machines/buzz-sigh.ogg', 25)
usr << "\icon[src]<span class='warning'>The cash box is open.</span>"
return
if((item_list.len > 1 || item_list[item_list[1]] > 1) && !confirm(SC))
return
if(transaction_amount > SC.worth)
src.visible_message("\icon[src]<span class='warning'>Not enough money.</span>")
else
@@ -313,6 +348,9 @@
/obj/machinery/cash_register/proc/scan_item_price(obj/O)
if(!istype(O)) return
if(item_list.len > 10)
src.visible_message("\icon[src]<span class='warning'>Only up to ten different items allowed per purchase.</span>")
return
if (cash_open)
playsound(src, 'sound/machines/buzz-sigh.ogg', 25)
usr << "\icon[src]<span class='warning'>The cash box is open.</span>"
@@ -330,19 +368,43 @@
transaction_purpose += "<br>"
transaction_purpose += "[O]: [price] Thaler\s"
transaction_amount += price
item_list += "[O]"
price_list += price
for(var/previously_scanned in item_list)
if(price == price_list[previously_scanned] && O.name == previously_scanned)
. = item_list[previously_scanned]++
if(!.)
item_list[O.name] = 1
price_list[O.name] = price
. = 1
// Animation and sound
playsound(src, 'sound/machines/twobeep.ogg', 25)
// Reset confirmation
confirm_item = null
updateDialog()
/obj/machinery/cash_register/proc/get_current_transaction()
var/dat = {"
<head><style>
.tx-title-r {text-align: center; background-color:#ffdddd; font-weight: bold}
.tx-name-r {background-color: #eebbbb}
.tx-data-r {text-align: right; background-color: #ffcccc;}
</head></style>
<table width=300>
<tr><td colspan="2" class="tx-title-r">New Entry</td></tr>
<tr></tr>"}
var/item_name
for(var/i=1, i<=item_list.len, i++)
item_name = item_list[i]
dat += "<tr><td class=\"tx-name-r\">[item_list[item_name] ? "<a href='?src=\ref[src];choice=subtract;item=\ref[item_name]'>-</a> <a href='?src=\ref[src];choice=set_amount;item=\ref[item_name]'>Set</a> <a href='?src=\ref[src];choice=add;item=\ref[item_name]'>+</a> [item_list[item_name]] x " : ""][item_name] <a href='?src=\ref[src];choice=clear;item=\ref[item_name]'>Remove</a></td><td class=\"tx-data-r\" width=50>[price_list[item_name] * item_list[item_name]] &thorn</td></tr>"
dat += "</table><table width=300>"
dat += "<tr><td class=\"tx-name-r\"><a href='?src=\ref[src];choice=clear'>Clear Entry</a></td><td class=\"tx-name-r\" style='text-align: right'><b>Total Amount: [transaction_amount] &thorn</b></td></tr>"
dat += "</table></html>"
return dat
/obj/machinery/cash_register/proc/add_transaction_log(var/c_name, var/p_method, var/t_amount)
var/dat = {"
<!DOCTYPE html><html>
<head><style>
.tx-table {border: 1px solid black;}
.tx-title {text-align: center; background-color:#ddddff; font-weight: bold}
.tx-name {background-color: #bbbbee}
.tx-data {text-align: right; background-color: #ccccff;}
@@ -356,8 +418,10 @@
</table>
<table width=300>
"}
var/item_name
for(var/i=1, i<=item_list.len, i++)
dat += "<tr><td class=\"tx-name\">[item_list[i]]</td><td class=\"tx-data\" width=50>[price_list[i]] &thorn</td></tr>"
item_name = item_list[i]
dat += "<tr><td class=\"tx-name\">[item_list[item_name] ? "[item_list[item_name]] x " : ""][item_name]</td><td class=\"tx-data\" width=50>[price_list[item_name] * item_list[item_name]] &thorn</td></tr>"
dat += "<tr></tr><tr><td colspan=\"2\" class=\"tx-name\" style='text-align: right'><b>Total Amount: [transaction_amount] &thorn</b></td></tr>"
dat += "</table></html>"

View File

@@ -18,6 +18,9 @@
// Juices, soda and similar //
/datum/reagent/water
price_tag = 2
/datum/reagent/drink/juice
price_tag = 2
@@ -49,7 +52,6 @@
price_tag = 2
// Hot Drinks //
/datum/reagent/drink/rewriter
@@ -64,6 +66,15 @@
/datum/reagent/drink/hot_coco
price_tag = 3
/obj/item/weapon/reagent_containers/food/drinks/coffee
price_tag = 3
/obj/item/weapon/reagent_containers/food/drinks/tea
price_tag = 3
/obj/item/weapon/reagent_containers/food/drinks/h_chocolate
price_tag = 3
// Spirituous liquors //
@@ -103,6 +114,15 @@
/datum/reagent/ethanol/whiskey
price_tag = 5
/datum/reagent/ethanol/specialwhiskey
price_tag = 5
/datum/reagent/ethanol/patron
price_tag = 5
/datum/reagent/ethanol/goldschlager
price_tag = 5
/datum/reagent/ethanol/coffee/brave_bull // Not an original liquor in its own. But since it's a mix of purely Tequila
price_tag = 5 // and Kahlua, it's basically just another one and gets the same price.
@@ -202,15 +222,12 @@
/datum/reagent/ethanol/erikasurprise
price_tag = 4
/datum/reagent/ethanol/gargleblaster
/datum/reagent/ethanol/gargle_blaster
price_tag = 4
/datum/reagent/ethanol/gintonic
price_tag = 4
/datum/reagent/ethanol/goldschlager
price_tag = 4
/datum/reagent/ethanol/hippies_delight
price_tag = 4
@@ -250,9 +267,6 @@
/datum/reagent/ethanol/neurotoxin
price_tag = 4
/datum/reagent/ethanol/patron
price_tag = 4
/datum/reagent/ethanol/red_mead
price_tag = 4
@@ -301,9 +315,6 @@
/datum/reagent/ethanol/whiskeysoda
price_tag = 4
/datum/reagent/ethanol/specialwhiskey
price_tag = 4
// Cocktails without alcohol //
@@ -339,9 +350,105 @@
//***************//
//---Foodstuff---//
//----Bottles----//
//***************//
// Juices, soda and similar //
/obj/item/weapon/reagent_containers/food/drinks/bottle/cola
price_tag = 6
/obj/item/weapon/reagent_containers/food/drinks/bottle/space_up
price_tag = 6
/obj/item/weapon/reagent_containers/food/drinks/bottle/space_mountain_wind
price_tag = 6
/obj/item/weapon/reagent_containers/food/drinks/bottle/orangejuice
price_tag = 6
/obj/item/weapon/reagent_containers/food/drinks/bottle/cream
price_tag = 6
/obj/item/weapon/reagent_containers/food/drinks/bottle/tomatojuice
price_tag = 6
/obj/item/weapon/reagent_containers/food/drinks/bottle/limejuice
price_tag = 6
// Beer //
/obj/item/weapon/reagent_containers/food/drinks/bottle/small/beer
price_tag = 3
/obj/item/weapon/reagent_containers/food/drinks/bottle/small/ale
price_tag = 3
// Spirituous Liquors //
/obj/item/weapon/reagent_containers/food/drinks/bottle/absinthe
price_tag = 15
/obj/item/weapon/reagent_containers/food/drinks/bottle/bluecuracao
price_tag = 15
/obj/item/weapon/reagent_containers/food/drinks/bottle/gin
price_tag = 15
/obj/item/weapon/reagent_containers/food/drinks/bottle/kahlua
price_tag = 15
/obj/item/weapon/reagent_containers/food/drinks/bottle/melonliquor
price_tag = 15
/obj/item/weapon/reagent_containers/food/drinks/bottle/rum
price_tag = 15
/obj/item/weapon/reagent_containers/food/drinks/bottle/tequilla
price_tag = 15
/obj/item/weapon/reagent_containers/food/drinks/bottle/vodka
price_tag = 15
/obj/item/weapon/reagent_containers/food/drinks/bottle/whiskey
price_tag = 15
/obj/item/weapon/reagent_containers/food/drinks/bottle/specialwhiskey
price_tag = 15
/obj/item/weapon/reagent_containers/food/drinks/bottle/patron
price_tag = 15
/obj/item/weapon/reagent_containers/food/drinks/bottle/goldschlager
price_tag = 15
/obj/item/weapon/reagent_containers/food/drinks/bottle/bottleofnothing
price_tag = 15
/obj/item/weapon/reagent_containers/food/drinks/bottle/grenadine
price_tag = 15
// Wines //
/obj/item/weapon/reagent_containers/food/drinks/bottle/wine
price_tag = 25
/obj/item/weapon/reagent_containers/food/drinks/bottle/cognac
price_tag = 25
/obj/item/weapon/reagent_containers/food/drinks/bottle/vermouth
price_tag = 25
/obj/item/weapon/reagent_containers/food/drinks/bottle/pwine
price_tag = 25
//***************//
//---Foodstuff---//
//***************//
// Snacks //
@@ -811,4 +918,39 @@
/obj/item/pizzabox
get_item_cost()
return get_item_cost(pizza)
return get_item_cost(pizza)
//***************//
//----Smokes-----//
//***************//
/obj/item/weapon/storage/fancy/cigarettes
price_tag = 15
/obj/item/weapon/storage/fancy/cigarettes/luckystars
price_tag = 17
/obj/item/weapon/storage/fancy/cigarettes/jerichos
price_tag = 22
/obj/item/weapon/storage/fancy/cigarettes/menthols
price_tag = 18
/obj/item/weapon/storage/fancy/cigar
price_tag = 27
/obj/item/weapon/storage/fancy/cigarettes/carcinomas
price_tag = 23
/obj/item/weapon/storage/fancy/cigarettes/professionals
price_tag = 25
/obj/item/weapon/storage/box/matches
price_tag = 1
/obj/item/weapon/flame/lighter
price_tag = 2
/obj/item/weapon/flame/lighter/zippo
price_tag = 5

View File

@@ -47,13 +47,8 @@
/obj/item/device/retail_scanner/attack_self(mob/user as mob)
// Reset if necessary
if(transaction_amount)
reset_memory()
user << "<span class='notice'>You reset the device.</span>"
else
user.set_machine(src)
interact(user)
user.set_machine(src)
interact(user)
/obj/item/device/retail_scanner/AltClick(var/mob/user)
@@ -71,7 +66,12 @@
dat += "<a href='?src=\ref[src];choice=toggle_lock'>Lock</a><br>"
dat += "Linked account: <a href='?src=\ref[src];choice=link_account'>[linked_account ? linked_account.owner_name : "None"]</a><br>"
dat += "<a href='?src=\ref[src];choice=custom_order'>Custom Order</a><hr>"
for(var/i=1, i<=transaction_logs.len, i++)
if(item_list.len)
dat += get_current_transaction()
dat += "<br>"
for(var/i=transaction_logs.len, i>=1, i--)
dat += "[transaction_logs[i]]<br>"
if(transaction_logs.len)
@@ -111,12 +111,46 @@
if (!t_purpose || !Adjacent(usr)) return
transaction_purpose = t_purpose
item_list += t_purpose
var/t_amount = input("Enter price", "New price") as num
var/t_amount = round(input("Enter price", "New price") as num)
if (!t_amount || !Adjacent(usr)) return
transaction_amount += t_amount
price_list += t_amount
playsound(src, 'sound/machines/twobeep.ogg', 25)
src.visible_message("\icon[src][transaction_purpose]: [transaction_amount] Thaler\s.")
src.visible_message("\icon[src][transaction_purpose]: [t_amount] Thaler\s.")
if("set_amount")
var/item_name = locate(href_list["item"])
var/n_amount = round(input("Enter amount", "New amount") as num)
n_amount = Clamp(n_amount, 0, 20)
if (!item_list[item_name] || !Adjacent(usr)) return
transaction_amount += (n_amount - item_list[item_name]) * price_list[item_name]
if(!n_amount)
item_list -= item_name
price_list -= item_name
else
item_list[item_name] = n_amount
if("subtract")
var/item_name = locate(href_list["item"])
if(item_name)
transaction_amount -= price_list[item_name]
item_list[item_name]--
if(item_list[item_name] <= 0)
item_list -= item_name
price_list -= item_name
if("add")
var/item_name = locate(href_list["item"])
if(item_list[item_name] >= 20) return
transaction_amount += price_list[item_name]
item_list[item_name]++
if("clear")
var/item_name = locate(href_list["item"])
if(item_name)
transaction_amount -= price_list[item_name] * item_list[item_name]
item_list -= item_name
price_list -= item_name
else
transaction_amount = 0
item_list.Cut()
price_list.Cut()
if("reset_log")
transaction_logs.Cut()
usr << "\icon[src]<span class='notice'>Transaction log reset.</span>"
@@ -161,7 +195,7 @@
if (!transaction_amount)
return
if(!confirm(I))
if((item_list.len > 1 || item_list[item_list[1]] > 1) && !confirm(I))
return
if (!linked_account)
@@ -221,7 +255,7 @@
if (!transaction_amount)
return
if(!confirm(E))
if((item_list.len > 1 || item_list[item_list[1]] > 1) && !confirm(E))
return
// Access account for transaction
@@ -252,6 +286,10 @@
/obj/item/device/retail_scanner/proc/scan_item_price(var/obj/O)
if(!istype(O)) return
if(item_list.len > 10)
src.visible_message("\icon[src]<span class='warning'>Only up to ten different items allowed per purchase.</span>")
return
// First check if item has a valid price
var/price = O.get_item_cost()
if(isnull(price))
@@ -264,8 +302,13 @@
transaction_purpose += "<br>"
transaction_purpose += "[O]: [price] Thaler\s"
transaction_amount += price
item_list += "[O]"
price_list += price
for(var/previously_scanned in item_list)
if(price == price_list[previously_scanned] && O.name == previously_scanned)
. = item_list[previously_scanned]++
if(!.)
item_list[O.name] = 1
price_list[O.name] = price
. = 1
// Animation and sound
flick("retail_scan", src)
playsound(src, 'sound/machines/twobeep.ogg', 25)
@@ -273,10 +316,29 @@
confirm_item = null
/obj/item/device/retail_scanner/proc/get_current_transaction()
var/dat = {"
<head><style>
.tx-title-r {text-align: center; background-color:#ffdddd; font-weight: bold}
.tx-name-r {background-color: #eebbbb}
.tx-data-r {text-align: right; background-color: #ffcccc;}
</head></style>
<table width=300>
<tr><td colspan="2" class="tx-title-r">New Entry</td></tr>
<tr></tr>"}
var/item_name
for(var/i=1, i<=item_list.len, i++)
item_name = item_list[i]
dat += "<tr><td class=\"tx-name-r\">[item_list[item_name] ? "<a href='?src=\ref[src];choice=subtract;item=\ref[item_name]'>-</a> <a href='?src=\ref[src];choice=set_amount;item=\ref[item_name]'>Set</a> <a href='?src=\ref[src];choice=add;item=\ref[item_name]'>+</a> [item_list[item_name]] x " : ""][item_name] <a href='?src=\ref[src];choice=clear;item=\ref[item_name]'>Remove</a></td><td class=\"tx-data-r\" width=50>[price_list[item_name] * item_list[item_name]] &thorn</td></tr>"
dat += "</table><table width=300>"
dat += "<tr><td class=\"tx-name-r\"><a href='?src=\ref[src];choice=clear'>Clear Entry</a></td><td class=\"tx-name-r\" style='text-align: right'><b>Total Amount: [transaction_amount] &thorn</b></td></tr>"
dat += "</table></html>"
return dat
/obj/item/device/retail_scanner/proc/add_transaction_log(var/c_name, var/p_method, var/t_amount)
var/dat = {"
<head><style>
.tx-table {border: 1px solid black;}
.tx-title {text-align: center; background-color:#ddddff; font-weight: bold}
.tx-name {background-color: #bbbbee}
.tx-data {text-align: right; background-color: #ccccff;}
@@ -290,8 +352,10 @@
</table>
<table width=300>
"}
var/item_name
for(var/i=1, i<=item_list.len, i++)
dat += "<tr><td class=\"tx-name\">[item_list[i]]</td><td class=\"tx-data\" width=50>[price_list[i]] &thorn</td></tr>"
item_name = item_list[i]
dat += "<tr><td class=\"tx-name\">[item_list[item_name] ? "[item_list[item_name]] x " : ""][item_name]</td><td class=\"tx-data\" width=50>[price_list[item_name] * item_list[item_name]] &thorn</td></tr>"
dat += "<tr></tr><tr><td colspan=\"2\" class=\"tx-name\" style='text-align: right'><b>Total Amount: [transaction_amount] &thorn</b></td></tr>"
dat += "</table>"

View File

@@ -61,9 +61,12 @@
/datum/event/prison_break/tick()
if(activeFor == releaseWhen)
if(areas && areas.len > 0)
var/obj/machinery/power/apc/theAPC = null
for(var/area/A in areas)
for(var/obj/machinery/light/L in A)
L.flicker(10)
theAPC = A.get_apc()
if(theAPC.operating) //If the apc's off, it's a little hard to overload the lights.
for(var/obj/machinery/light/L in A)
L.flicker(10)
/datum/event/prison_break/end()

View File

@@ -26,7 +26,7 @@ proc/Intoxicated(phrase)
proc/NewStutter(phrase,stunned)
phrase = html_decode(phrase)
var/list/split_phrase = text2list(phrase," ") //Split it up into words.
var/list/split_phrase = splittext(phrase," ") //Split it up into words.
var/list/unstuttered_words = split_phrase.Copy()
var/i = rand(1,3)
@@ -57,7 +57,7 @@ proc/NewStutter(phrase,stunned)
split_phrase[index] = word
return sanitize(list2text(split_phrase," "))
return sanitize(jointext(split_phrase," "))
proc/Stagger(mob/M,d) //Technically not a filter, but it relates to drunkenness.
step(M, pick(d,turn(d,90),turn(d,-90)))
@@ -67,7 +67,7 @@ proc/Ellipsis(original_msg, chance = 50)
if(chance >= 100) return original_msg
var/list
words = text2list(original_msg," ")
words = splittext(original_msg," ")
new_words = list()
var/new_msg = ""
@@ -78,6 +78,6 @@ proc/Ellipsis(original_msg, chance = 50)
else
new_words += w
new_msg = list2text(new_words," ")
new_msg = jointext(new_words," ")
return new_msg

View File

@@ -77,12 +77,8 @@
usr << "There are no cards in the deck."
return
var/obj/item/weapon/hand/H
if(user.l_hand && istype(user.l_hand,/obj/item/weapon/hand))
H = user.l_hand
else if(user.r_hand && istype(user.r_hand,/obj/item/weapon/hand))
H = user.r_hand
else
var/obj/item/weapon/hand/H = user.get_type_in_hands(/obj/item/weapon/hand)
if(!H)
H = new(get_turf(src))
user.put_in_hands(H)

View File

@@ -22,7 +22,7 @@ proc/populate_ghost_traps()
var/ghost_trap_role = "Positronic Brain"
// Check for bans, proper atom types, etc.
/datum/ghosttrap/proc/assess_candidate(var/mob/dead/observer/candidate)
/datum/ghosttrap/proc/assess_candidate(var/mob/observer/dead/candidate)
if(!istype(candidate) || !candidate.client || !candidate.ckey)
return 0
if(!candidate.MayRespawn())
@@ -39,7 +39,7 @@ proc/populate_ghost_traps()
/datum/ghosttrap/proc/request_player(var/mob/target, var/request_string)
if(!target)
return
for(var/mob/dead/observer/O in player_list)
for(var/mob/observer/dead/O in player_list)
if(!O.MayRespawn())
continue
if(islist(ban_checks))
@@ -56,7 +56,7 @@ proc/populate_ghost_traps()
if(..())
return 1
if(href_list["candidate"] && href_list["target"])
var/mob/dead/observer/candidate = locate(href_list["candidate"]) // BYOND magic.
var/mob/observer/dead/candidate = locate(href_list["candidate"]) // BYOND magic.
var/mob/target = locate(href_list["target"]) // So much BYOND magic.
if(!target || !candidate)
return

View File

@@ -172,7 +172,7 @@
if(seed) seed.thrown_at(src,hit_atom)
..()
/obj/item/weapon/reagent_containers/food/snacks/grown/attackby(var/obj/item/weapon/W, var/mob/user)
/obj/item/weapon/reagent_containers/food/snacks/grown/attackby(var/obj/item/weapon/W, var/mob/living/user)
if(seed)
if(seed.get_trait(TRAIT_PRODUCES_POWER) && istype(W, /obj/item/stack/cable_coil))
@@ -181,7 +181,7 @@
//TODO: generalize this.
user << "<span class='notice'>You add some cable to the [src.name] and slide it inside the battery casing.</span>"
var/obj/item/weapon/cell/potato/pocell = new /obj/item/weapon/cell/potato(get_turf(user))
if(src.loc == user && !(user.l_hand && user.r_hand) && istype(user,/mob/living/carbon/human))
if(src.loc == user && istype(user,/mob/living/carbon/human))
user.put_in_hands(pocell)
pocell.maxcharge = src.potency * 10
pocell.charge = pocell.maxcharge

View File

@@ -150,7 +150,7 @@
var/body_coverage = HEAD|FACE|EYES|UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS
for(var/obj/item/clothing/clothes in target)
if(target.l_hand == clothes|| target.r_hand == clothes)
if(target.item_is_in_hands(clothes))
continue
body_coverage &= ~(clothes.body_parts_covered)
@@ -182,7 +182,7 @@
continue
var/body_coverage = HEAD|FACE|EYES|UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS
for(var/obj/item/clothing/clothes in M)
if(M.l_hand == clothes || M.r_hand == clothes)
if(M.item_is_in_hands(clothes))
continue
body_coverage &= ~(clothes.body_parts_covered)
if(!body_coverage)

View File

@@ -129,7 +129,7 @@
return 1
return ..()
/obj/machinery/portable_atmospherics/hydroponics/attack_ghost(var/mob/dead/observer/user)
/obj/machinery/portable_atmospherics/hydroponics/attack_ghost(var/mob/observer/dead/user)
if(!(harvest && seed && seed.has_mob_product))
return
@@ -152,7 +152,7 @@
return
if(weedlevel > 0)
nymph.reagents.add_reagent("nutriment", weedlevel)
nymph.reagents.add_reagent("glucose", weedlevel)
weedlevel = 0
nymph.visible_message("<font color='blue'><b>[nymph]</b> begins rooting through [src], ripping out weeds and eating them noisily.</font>","<font color='blue'>You begin rooting through [src], ripping out weeds and eating them noisily.</font>")
else if(nymph.nutrition > 100 && nutrilevel < 10)

View File

@@ -34,7 +34,7 @@
var/obj/item/weapon/paper/P = new /obj/item/weapon/paper(get_turf(src))
P.name = "paper - [form_title]"
P.info = "[last_data]"
if(istype(user,/mob/living/carbon/human) && !(user.l_hand && user.r_hand))
if(istype(user,/mob/living/carbon/human))
user.put_in_hands(P)
user.visible_message("\The [src] spits out a piece of paper.")
return

View File

@@ -1,202 +0,0 @@
#define LIQUID_TRANSFER_THRESHOLD 0.05
var/liquid_delay = 4
var/list/datum/puddle/puddles = list()
datum/puddle
var/list/obj/effect/liquid/liquid_objects = list()
datum/puddle/proc/process()
//world << "DEBUG: Puddle process!"
for(var/obj/effect/liquid/L in liquid_objects)
L.spread()
for(var/obj/effect/liquid/L in liquid_objects)
L.apply_calculated_effect()
if(liquid_objects.len == 0)
qdel(src)
datum/puddle/New()
..()
puddles += src
datum/puddle/Destroy()
puddles -= src
for(var/obj/O in liquid_objects)
qdel(O)
..()
client/proc/splash()
var/volume = input("Volume?","Volume?", 0 ) as num
if(!isnum(volume)) return
if(volume <= LIQUID_TRANSFER_THRESHOLD) return
var/turf/T = get_turf(src.mob)
if(!isturf(T)) return
trigger_splash(T, volume)
proc/trigger_splash(turf/epicenter as turf, volume as num)
if(!epicenter)
return
if(volume <= 0)
return
var/obj/effect/liquid/L = new/obj/effect/liquid(epicenter)
L.volume = volume
L.update_icon2()
var/datum/puddle/P = new/datum/puddle()
P.liquid_objects.Add(L)
L.controller = P
obj/effect/liquid
icon = 'icons/effects/liquid.dmi'
icon_state = "0"
name = "liquid"
var/volume = 0
var/new_volume = 0
var/datum/puddle/controller
obj/effect/liquid/New()
..()
if( !isturf(loc) )
qdel(src)
for( var/obj/effect/liquid/L in loc )
if(L != src)
qdel(L)
obj/effect/liquid/proc/spread()
//world << "DEBUG: liquid spread!"
var/surrounding_volume = 0
var/list/spread_directions = list(1,2,4,8)
var/turf/loc_turf = loc
for(var/direction in spread_directions)
var/turf/T = get_step(src,direction)
if(!T)
spread_directions.Remove(direction)
//world << "ERROR: Map edge!"
continue //Map edge
if(!loc_turf.can_leave_liquid(direction)) //Check if this liquid can leave the tile in the direction
spread_directions.Remove(direction)
continue
if(!T.can_accept_liquid(turn(direction,180))) //Check if this liquid can enter the tile
spread_directions.Remove(direction)
continue
var/obj/effect/liquid/L = locate(/obj/effect/liquid) in T
if(L)
if(L.volume >= src.volume)
spread_directions.Remove(direction)
continue
surrounding_volume += L.volume //If liquid already exists, add it's volume to our sum
else
var/obj/effect/liquid/NL = new(T) //Otherwise create a new object which we'll spread to.
NL.controller = src.controller
controller.liquid_objects.Add(NL)
if(!spread_directions.len)
//world << "ERROR: No candidate to spread to."
return //No suitable candidate to spread to
var/average_volume = (src.volume + surrounding_volume) / (spread_directions.len + 1) //Average amount of volume on this and the surrounding tiles.
var/volume_difference = src.volume - average_volume //How much more/less volume this tile has than the surrounding tiles.
if(volume_difference <= (spread_directions.len*LIQUID_TRANSFER_THRESHOLD)) //If we have less than the threshold excess liquid - then there is nothing to do as other tiles will be giving us volume.or the liquid is just still.
//world << "ERROR: transfer volume lower than THRESHOLD!"
return
var/volume_per_tile = volume_difference / spread_directions.len
for(var/direction in spread_directions)
var/turf/T = get_step(src,direction)
if(!T)
//world << "ERROR: Map edge 2!"
continue //Map edge
var/obj/effect/liquid/L = locate(/obj/effect/liquid) in T
if(L)
src.volume -= volume_per_tile //Remove the volume from this tile
L.new_volume = L.new_volume + volume_per_tile //Add it to the volume to the other tile
obj/effect/liquid/proc/apply_calculated_effect()
volume += new_volume
if(volume < LIQUID_TRANSFER_THRESHOLD)
qdel(src)
new_volume = 0
update_icon2()
obj/effect/liquid/Move()
return 0
obj/effect/liquid/Destroy()
src.controller.liquid_objects.Remove(src)
..()
obj/effect/liquid/proc/update_icon2()
//icon_state = num2text( max(1,min(7,(floor(volume),10)/10)) )
switch(volume)
if(0 to 0.1)
qdel(src)
if(0.1 to 5)
icon_state = "1"
if(5 to 10)
icon_state = "2"
if(10 to 20)
icon_state = "3"
if(20 to 30)
icon_state = "4"
if(30 to 40)
icon_state = "5"
if(40 to 50)
icon_state = "6"
if(50 to INFINITY)
icon_state = "7"
turf/proc/can_accept_liquid(from_direction)
return 0
turf/proc/can_leave_liquid(from_direction)
return 0
turf/space/can_accept_liquid(from_direction)
return 1
turf/space/can_leave_liquid(from_direction)
return 1
turf/simulated/floor/can_accept_liquid(from_direction)
for(var/obj/structure/window/W in src)
if(W.dir in list(5,6,9,10))
return 0
if(W.dir & from_direction)
return 0
for(var/obj/O in src)
if(!O.liquid_pass())
return 0
return 1
turf/simulated/floor/can_leave_liquid(to_direction)
for(var/obj/structure/window/W in src)
if(W.dir in list(5,6,9,10))
return 0
if(W.dir & to_direction)
return 0
for(var/obj/O in src)
if(!O.liquid_pass())
return 0
return 1
turf/simulated/wall/can_accept_liquid(from_direction)
return 0
turf/simulated/wall/can_leave_liquid(from_direction)
return 0
obj/proc/liquid_pass()
return 1
obj/machinery/door/liquid_pass()
return !density
#undef LIQUID_TRANSFER_THRESHOLD

View File

@@ -128,7 +128,7 @@ var/list/name_to_material
S.add_fingerprint(user)
S.add_to_stacks(user)
/material/proc/build_wired_product(var/mob/user, var/obj/item/stack/used_stack, var/obj/item/stack/target_stack)
/material/proc/build_wired_product(var/mob/living/user, var/obj/item/stack/used_stack, var/obj/item/stack/target_stack)
if(!wire_product)
user << "<span class='warning'>You cannot make anything out of \the [target_stack]</span>"
return
@@ -140,8 +140,7 @@ var/list/name_to_material
target_stack.use(1)
user << "<span class='notice'>You attach wire to the [name].</span>"
var/obj/item/product = new wire_product(get_turf(user))
if(!(user.l_hand && user.r_hand))
user.put_in_hands(product)
user.put_in_hands(product)
// Make sure we have a display name and shard icon even if they aren't explicitly set.
/material/New()

View File

@@ -172,10 +172,9 @@ var/list/mining_overlay_cache = list()
if(istype(AM,/mob/living/carbon/human))
var/mob/living/carbon/human/H = AM
if((istype(H.l_hand,/obj/item/weapon/pickaxe)) && (!H.hand))
attackby(H.l_hand,H)
else if((istype(H.r_hand,/obj/item/weapon/pickaxe)) && H.hand)
attackby(H.r_hand,H)
var/obj/item/weapon/pickaxe/P = H.get_inactive_hand()
if(istype(P))
src.attackby(P, H)
else if(istype(AM,/mob/living/silicon/robot))
var/mob/living/silicon/robot/R = AM

View File

@@ -1,5 +1,5 @@
/mob/dead/dust() //ghosts can't be vaporised.
/mob/observer/dust() //ghosts can't be vaporised.
return
/mob/dead/gib() //ghosts can't be gibbed.
/mob/observer/gib() //ghosts can't be gibbed.
return

View File

@@ -1,4 +1,4 @@
/mob/dead/observer/Login()
/mob/observer/dead/Login()
..()
if (ghostimage)
ghostimage.icon_state = src.icon_state

View File

@@ -1,4 +1,4 @@
/mob/dead/observer/Logout()
/mob/observer/dead/Logout()
..()
spawn(0)
if(src && !key) //we've transferred to another mob. This ghost should be deleted.

View File

@@ -1,14 +1,18 @@
var/global/list/image/ghost_darkness_images = list() //this is a list of images for things ghosts should still be able to see when they toggle darkness
var/global/list/image/ghost_sightless_images = list() //this is a list of images for things ghosts should still be able to see even without ghost sight
/mob/dead/observer
/mob/observer
name = "observer"
desc = "This shouldn't appear"
density = 0
/mob/observer/dead
name = "ghost"
desc = "It's a g-g-g-g-ghooooost!" //jinkies!
icon = 'icons/mob/mob.dmi'
icon_state = "ghost"
layer = 4
stat = DEAD
density = 0
canmove = 0
blinded = 0
anchored = 1 // don't get pushed around
@@ -31,11 +35,11 @@ var/global/list/image/ghost_sightless_images = list() //this is a list of images
var/seedarkness = 1
incorporeal_move = 1
/mob/dead/observer/New(mob/body)
/mob/observer/dead/New(mob/body)
sight |= SEE_TURFS | SEE_MOBS | SEE_OBJS | SEE_SELF
see_invisible = SEE_INVISIBLE_OBSERVER
see_in_dark = 100
verbs += /mob/dead/observer/proc/dead_tele
verbs += /mob/observer/dead/proc/dead_tele
stat = DEAD
@@ -81,7 +85,7 @@ var/global/list/image/ghost_sightless_images = list() //this is a list of images
real_name = name
..()
/mob/dead/observer/Destroy()
/mob/observer/dead/Destroy()
if (ghostimage)
ghost_darkness_images -= ghostimage
qdel(ghostimage)
@@ -89,7 +93,7 @@ var/global/list/image/ghost_sightless_images = list() //this is a list of images
updateallghostimages()
..()
/mob/dead/observer/Topic(href, href_list)
/mob/observer/dead/Topic(href, href_list)
if (href_list["track"])
var/mob/target = locate(href_list["track"]) in mob_list
if(target)
@@ -97,19 +101,19 @@ var/global/list/image/ghost_sightless_images = list() //this is a list of images
/mob/dead/attackby(obj/item/W, mob/user)
/mob/observer/dead/attackby(obj/item/W, mob/user)
if(istype(W,/obj/item/weapon/book/tome))
var/mob/dead/M = src
var/mob/observer/dead/M = src
M.manifest(user)
/mob/dead/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
/mob/observer/dead/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
return 1
/*
Transfer_mind is there to check if mob is being deleted/not going to have a body.
Works together with spawning an observer, noted above.
*/
/mob/dead/observer/Life()
/mob/observer/dead/Life()
..()
if(!loc) return
if(!client) return 0
@@ -131,13 +135,13 @@ Works together with spawning an observer, noted above.
process_medHUD(src)
/mob/dead/proc/process_medHUD(var/mob/M)
/mob/observer/dead/proc/process_medHUD(var/mob/M)
var/client/C = M.client
for(var/mob/living/carbon/human/patient in oview(M, 14))
C.images += patient.hud_list[HEALTH_HUD]
C.images += patient.hud_list[STATUS_HUD_OOC]
/mob/dead/proc/assess_targets(list/target_list, mob/dead/observer/U)
/mob/observer/dead/proc/assess_targets(list/target_list, mob/observer/dead/U)
var/client/C = U.client
for(var/mob/living/carbon/human/target in target_list)
C.images += target.hud_list[SPECIALROLE_HUD]
@@ -147,14 +151,14 @@ Works together with spawning an observer, noted above.
/mob/proc/ghostize(var/can_reenter_corpse = 1)
if(key)
var/mob/dead/observer/ghost = new(src) //Transfer safety to observer spawning proc.
var/mob/observer/dead/ghost = new(src) //Transfer safety to observer spawning proc.
ghost.can_reenter_corpse = can_reenter_corpse
ghost.timeofdeath = src.timeofdeath //BS12 EDIT
ghost.key = key
if(ghost.client)
ghost.client.time_died_as_mouse = ghost.timeofdeath
if(ghost.client && !ghost.client.holder && !config.antag_hud_allowed) // For new ghosts we remove the verb from even showing up if it's not allowed.
ghost.verbs -= /mob/dead/observer/verb/toggle_antagHUD // Poor guys, don't know what they are missing!
ghost.verbs -= /mob/observer/dead/verb/toggle_antagHUD // Poor guys, don't know what they are missing!
return ghost
/*
@@ -183,14 +187,14 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
var/turf/location = get_turf(src)
message_admins("[key_name_admin(usr)] has ghosted. (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[location.x];Y=[location.y];Z=[location.z]'>JMP</a>)")
log_game("[key_name_admin(usr)] has ghosted.")
var/mob/dead/observer/ghost = ghostize(0) //0 parameter is so we can never re-enter our body, "Charlie, you can never come baaaack~" :3
var/mob/observer/dead/ghost = ghostize(0) //0 parameter is so we can never re-enter our body, "Charlie, you can never come baaaack~" :3
ghost.timeofdeath = world.time // Because the living mob won't have a time of death and we want the respawn timer to work properly.
announce_ghost_joinleave(ghost)
/mob/dead/observer/can_use_hands() return 0
/mob/dead/observer/is_active() return 0
/mob/observer/dead/can_use_hands() return 0
/mob/observer/dead/is_active() return 0
/mob/dead/observer/Stat()
/mob/observer/dead/Stat()
..()
if(statpanel("Status"))
if(emergency_shuttle)
@@ -198,7 +202,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
if(eta_status)
stat(null, eta_status)
/mob/dead/observer/verb/reenter_corpse()
/mob/observer/dead/verb/reenter_corpse()
set category = "Ghost"
set name = "Re-enter Corpse"
if(!client) return
@@ -224,7 +228,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
announce_ghost_joinleave(mind, 0, "They now occupy their body again.")
return 1
/mob/dead/observer/verb/toggle_medHUD()
/mob/observer/dead/verb/toggle_medHUD()
set category = "Ghost"
set name = "Toggle MedicHUD"
set desc = "Toggles Medical HUD allowing you to see how everyone is doing"
@@ -237,7 +241,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
medHUD = 1
src << "\blue <B>Medical HUD Enabled</B>"
/mob/dead/observer/verb/toggle_antagHUD()
/mob/observer/dead/verb/toggle_antagHUD()
set category = "Ghost"
set name = "Toggle AntagHUD"
set desc = "Toggles AntagHUD allowing you to see who is the antagonist"
@@ -248,7 +252,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
if(!config.antag_hud_allowed && (!client.holder || mentor))
src << "\red Admins have disabled this for this round."
return
var/mob/dead/observer/M = src
var/mob/observer/dead/M = src
if(jobban_isbanned(M, "AntagHUD"))
src << "\red <B>You have been banned from using this feature</B>"
return
@@ -265,16 +269,16 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
M.antagHUD = 1
src << "\blue <B>AntagHUD Enabled</B>"
/mob/dead/observer/proc/dead_tele(A in ghostteleportlocs)
/mob/observer/dead/proc/dead_tele(A in ghostteleportlocs)
set category = "Ghost"
set name = "Teleport"
set desc= "Teleport to a location"
if(!istype(usr, /mob/dead/observer))
if(!istype(usr, /mob/observer/dead))
usr << "Not when you're not dead!"
return
usr.verbs -= /mob/dead/observer/proc/dead_tele
usr.verbs -= /mob/observer/dead/proc/dead_tele
spawn(30)
usr.verbs += /mob/dead/observer/proc/dead_tele
usr.verbs += /mob/observer/dead/proc/dead_tele
var/area/thearea = ghostteleportlocs[A]
if(!thearea) return
@@ -300,7 +304,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
usr.forceMove(pick(L))
following = null
/mob/dead/observer/verb/follow(input in getmobs())
/mob/observer/dead/verb/follow(input in getmobs())
set category = "Ghost"
set name = "Follow" // "Haunt"
set desc = "Follow and haunt a mob."
@@ -310,7 +314,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
ManualFollow(target)
// This is the ghost's follow verb with an argument
/mob/dead/observer/proc/ManualFollow(var/atom/movable/target)
/mob/observer/dead/proc/ManualFollow(var/atom/movable/target)
if(!target)
return
@@ -340,7 +344,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
/mob/proc/update_following()
. = get_turf(src)
for(var/mob/dead/observer/M in following_mobs)
for(var/mob/observer/dead/M in following_mobs)
if(M.following != src)
following_mobs -= M
else
@@ -351,12 +355,12 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
var/list/following_mobs = list()
/mob/Destroy()
for(var/mob/dead/observer/M in following_mobs)
for(var/mob/observer/dead/M in following_mobs)
M.following = null
following_mobs = null
return ..()
/mob/dead/observer/Destroy()
/mob/observer/dead/Destroy()
if(ismob(following))
var/mob/M = following
M.following_mobs -= src
@@ -376,18 +380,18 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
/mob/proc/check_holy(var/turf/T)
return 0
/mob/dead/observer/check_holy(var/turf/T)
/mob/observer/dead/check_holy(var/turf/T)
if(check_rights(R_ADMIN|R_FUN, 0, src))
return 0
return (T && T.holy) && (invisibility <= SEE_INVISIBLE_LIVING || (mind in cult.current_antagonists))
/mob/dead/observer/verb/jumptomob(target in getmobs()) //Moves the ghost instead of just changing the ghosts's eye -Nodrak
/mob/observer/dead/verb/jumptomob(target in getmobs()) //Moves the ghost instead of just changing the ghosts's eye -Nodrak
set category = "Ghost"
set name = "Jump to Mob"
set desc = "Teleport to a mob"
if(istype(usr, /mob/dead/observer)) //Make sure they're an observer!
if(istype(usr, /mob/observer/dead)) //Make sure they're an observer!
if (!target)//Make sure we actually have a target
return
@@ -401,7 +405,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
else
src << "This mob is not located in the game world."
/*
/mob/dead/observer/verb/boo()
/mob/observer/dead/verb/boo()
set category = "Ghost"
set name = "Boo!"
set desc= "Scare your crew members because of boredom!"
@@ -416,22 +420,22 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
return
*/
/mob/dead/observer/memory()
/mob/observer/dead/memory()
set hidden = 1
src << "\red You are dead! You have no mind to store memory!"
/mob/dead/observer/add_memory()
/mob/observer/dead/add_memory()
set hidden = 1
src << "\red You are dead! You have no mind to store memory!"
/mob/dead/observer/Post_Incorpmove()
/mob/observer/dead/Post_Incorpmove()
following = null
/mob/dead/observer/verb/analyze_air()
/mob/observer/dead/verb/analyze_air()
set name = "Analyze Air"
set category = "Ghost"
if(!istype(usr, /mob/dead/observer)) return
if(!istype(usr, /mob/observer/dead)) return
// Shamelessly copied from the Gas Analyzers
if (!( istype(usr.loc, /turf) ))
@@ -453,7 +457,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
src << "\blue Temperature: [round(environment.temperature-T0C,0.1)]&deg;C ([round(environment.temperature,0.1)]K)"
src << "\blue Heat Capacity: [round(environment.heat_capacity(),0.1)]"
/mob/dead/observer/verb/become_mouse()
/mob/observer/dead/verb/become_mouse()
set name = "Become mouse"
set category = "Ghost"
@@ -500,7 +504,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
host.ckey = src.ckey
host << "<span class='info'>You are now a mouse. Try to avoid interaction with players, and do not give hints away that you are more than a simple rodent.</span>"
/mob/dead/observer/verb/view_manfiest()
/mob/observer/dead/verb/view_manfiest()
set name = "Show Crew Manifest"
set category = "Ghost"
@@ -511,7 +515,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
src << browse(dat, "window=manifest;size=370x420;can_close=1")
//This is called when a ghost is drag clicked to something.
/mob/dead/observer/MouseDrop(atom/over)
/mob/observer/dead/MouseDrop(atom/over)
if(!usr || !over) return
if (isobserver(usr) && usr.client && usr.client.holder && isliving(over))
if (usr.client.holder.cmd_ghost_drag(src,over))
@@ -520,7 +524,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
return ..()
//Used for drawing on walls with blood puddles as a spooky ghost.
/mob/dead/verb/bloody_doodle()
/mob/observer/dead/verb/bloody_doodle()
set category = "Ghost"
set name = "Write in blood"
@@ -594,17 +598,17 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
W.add_hiddenprint(src)
W.visible_message("\red Invisible fingers crudely paint something in blood on [T]...")
/mob/dead/observer/pointed(atom/A as mob|obj|turf in view())
/mob/observer/dead/pointed(atom/A as mob|obj|turf in view())
if(!..())
return 0
usr.visible_message("<span class='deadsay'><b>[src]</b> points to [A]</span>")
return 1
/mob/dead/proc/manifest(mob/user)
/mob/observer/dead/proc/manifest(mob/user)
var/is_manifest = 0
if(!is_manifest)
is_manifest = 1
verbs += /mob/dead/proc/toggle_visibility
verbs += /mob/observer/dead/proc/toggle_visibility
if(src.invisibility != 0)
user.visible_message( \
@@ -618,7 +622,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
"<span class='warning'>You get the feeling that the ghost can't become any more visible.</span>" \
)
/mob/dead/proc/toggle_icon(var/icon)
/mob/observer/dead/proc/toggle_icon(var/icon)
if(!client)
return
@@ -632,7 +636,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
var/image/J = image('icons/mob/mob.dmi', loc = src, icon_state = icon)
client.images += J
/mob/dead/proc/toggle_visibility(var/forced = 0)
/mob/observer/dead/proc/toggle_visibility(var/forced = 0)
set category = "Ghost"
set name = "Toggle Visibility"
set desc = "Allows you to turn (in)visible (almost) at will."
@@ -652,7 +656,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
// Give the ghost a cult icon which should be visible only to itself
toggle_icon("cult")
/mob/dead/observer/verb/toggle_anonsay()
/mob/observer/dead/verb/toggle_anonsay()
set category = "Ghost"
set name = "Toggle Anonymous Chat"
set desc = "Toggles showing your key in dead chat."
@@ -663,13 +667,13 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
else
src << "<span class='info'>Your key will be publicly visible again.</span>"
/mob/dead/observer/canface()
/mob/observer/dead/canface()
return 1
/mob/dead/observer/proc/can_admin_interact()
/mob/observer/dead/proc/can_admin_interact()
return check_rights(R_ADMIN, 0, src)
/mob/dead/observer/verb/toggle_ghostsee()
/mob/observer/dead/verb/toggle_ghostsee()
set name = "Toggle Ghost Vision"
set desc = "Toggles your ability to see things only ghosts can see, like other ghosts"
set category = "Ghost"
@@ -677,13 +681,13 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
updateghostsight()
usr << "You [(ghostvision?"now":"no longer")] have ghost vision."
/mob/dead/observer/verb/toggle_darkness()
/mob/observer/dead/verb/toggle_darkness()
set name = "Toggle Darkness"
set category = "Ghost"
seedarkness = !(seedarkness)
updateghostsight()
/mob/dead/observer/proc/updateghostsight()
/mob/observer/dead/proc/updateghostsight()
if (!seedarkness)
see_invisible = SEE_INVISIBLE_NOLIGHTING
else
@@ -693,10 +697,10 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
updateghostimages()
/proc/updateallghostimages()
for (var/mob/dead/observer/O in player_list)
for (var/mob/observer/dead/O in player_list)
O.updateghostimages()
/mob/dead/observer/proc/updateghostimages()
/mob/observer/dead/proc/updateghostimages()
if (!client)
return
if (seedarkness || !ghostvision)
@@ -709,7 +713,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
if (ghostimage)
client.images -= ghostimage //remove ourself
mob/dead/observer/MayRespawn(var/feedback = 0)
mob/observer/dead/MayRespawn(var/feedback = 0)
if(!client)
return 0
if(mind && mind.current && mind.current.stat != DEAD && can_reenter_corpse)
@@ -729,7 +733,7 @@ mob/dead/observer/MayRespawn(var/feedback = 0)
if(client && eyeobj)
return "|<a href='byond://?src=\ref[ghost];track=\ref[eyeobj]'>eye</a>"
/mob/dead/observer/extra_ghost_link(var/atom/ghost)
/mob/observer/dead/extra_ghost_link(var/atom/ghost)
if(mind && mind.current)
return "|<a href='byond://?src=\ref[ghost];track=\ref[mind.current]'>body</a>"

View File

@@ -1,4 +1,4 @@
/mob/dead/observer/say(var/message)
/mob/observer/dead/say(var/message)
message = sanitize(message)
if (!message)
@@ -17,7 +17,7 @@
. = src.say_dead(message)
/mob/dead/observer/emote(var/act, var/type, var/message)
/mob/observer/dead/emote(var/act, var/type, var/message)
//message = sanitize(message) - already sanitized in verb/me_verb()
if(!message)

View File

@@ -3,15 +3,15 @@
// A mob that the AI controls to look around the station with.
// It streams chunks as it moves around, which will show it what the AI can and cannot see.
/mob/eye/aiEye
/mob/observer/eye/aiEye
name = "Inactive AI Eye"
icon_state = "AI-eye"
/mob/eye/aiEye/New()
/mob/observer/eye/aiEye/New()
..()
visualnet = cameranet
/mob/eye/aiEye/setLoc(var/T, var/cancel_tracking = 1)
/mob/observer/eye/aiEye/setLoc(var/T, var/cancel_tracking = 1)
if(..())
var/mob/living/silicon/ai/ai = owner
if(cancel_tracking)
@@ -43,7 +43,7 @@
/mob/living/silicon/ai/proc/create_eyeobj(var/newloc)
if(eyeobj) destroy_eyeobj()
if(!newloc) newloc = src.loc
eyeobj = PoolOrNew(/mob/eye/aiEye, newloc)
eyeobj = PoolOrNew(/mob/observer/eye/aiEye, newloc)
eyeobj.owner = src
eyeobj.name = "[src.name] (AI Eye)" // Give it a name
if(client) client.eye = eyeobj

View File

@@ -25,7 +25,7 @@
// Add an eye to the chunk, then update if changed.
/datum/chunk/proc/add(mob/eye/eye)
/datum/chunk/proc/add(mob/observer/eye/eye)
if(!eye.owner)
return
eye.visibleChunks += src
@@ -38,7 +38,7 @@
// Remove an eye from the chunk, then update if changed.
/datum/chunk/proc/remove(mob/eye/eye)
/datum/chunk/proc/remove(mob/observer/eye/eye)
if(!eye.owner)
return
eye.visibleChunks -= src
@@ -91,7 +91,7 @@
if(t.obfuscations[obfuscation.type])
obscured -= t.obfuscations[obfuscation.type]
for(var/eye in seenby)
var/mob/eye/m = eye
var/mob/observer/eye/m = eye
if(!m || !m.owner)
continue
if(m.owner.client)
@@ -105,7 +105,7 @@
obscured += t.obfuscations[obfuscation.type]
for(var/eye in seenby)
var/mob/eye/m = eye
var/mob/observer/eye/m = eye
if(!m || !m.owner)
seenby -= m
continue

View File

@@ -3,12 +3,11 @@
// A mob that another mob controls to look around the station with.
// It streams chunks as it moves around, which will show it what the controller can and cannot see.
/mob/eye
/mob/observer/eye
name = "Eye"
icon = 'icons/mob/eye.dmi'
icon_state = "default-eye"
alpha = 127
density = 0
var/sprint = 10
var/cooldown = 0
@@ -25,14 +24,14 @@
var/ghostimage = null
var/datum/visualnet/visualnet
/mob/eye/New()
/mob/observer/eye/New()
ghostimage = image(src.icon,src,src.icon_state)
ghost_darkness_images |= ghostimage //so ghosts can see the eye when they disable darkness
ghost_sightless_images |= ghostimage //so ghosts can see the eye when they disable ghost sight
updateallghostimages()
..()
mob/eye/Destroy()
mob/observer/eye/Destroy()
if (ghostimage)
ghost_darkness_images -= ghostimage
ghost_sightless_images -= ghostimage
@@ -41,30 +40,30 @@ mob/eye/Destroy()
updateallghostimages()
..()
/mob/eye/Move(n, direct)
/mob/observer/eye/Move(n, direct)
if(owner == src)
return EyeMove(n, direct)
return 0
/mob/eye/airflow_hit(atom/A)
/mob/observer/eye/airflow_hit(atom/A)
airflow_speed = 0
airflow_dest = null
/mob/eye/examinate()
/mob/observer/eye/examinate()
set popup_menu = 0
set src = usr.contents
return 0
/mob/eye/pointed()
/mob/observer/eye/pointed()
set popup_menu = 0
set src = usr.contents
return 0
/mob/eye/examine(mob/user)
/mob/observer/eye/examine(mob/user)
// Use this when setting the eye's location.
// It will also stream the chunk that the new loc is in.
/mob/eye/proc/setLoc(var/T)
/mob/observer/eye/proc/setLoc(var/T)
if(owner)
T = get_turf(T)
if(T != loc)
@@ -82,13 +81,13 @@ mob/eye/Destroy()
return 1
return 0
/mob/eye/proc/getLoc()
/mob/observer/eye/proc/getLoc()
if(owner)
if(!isturf(owner.loc) || !owner.client)
return
return loc
/mob
var/mob/eye/eyeobj
var/mob/observer/eye/eyeobj
/mob/proc/EyeMove(n, direct)
if(!eyeobj)
@@ -96,7 +95,7 @@ mob/eye/Destroy()
return eyeobj.EyeMove(n, direct)
/mob/eye/EyeMove(n, direct)
/mob/observer/eye/EyeMove(n, direct)
var/initial = initial(sprint)
var/max_sprint = 50

View File

@@ -1,4 +1,4 @@
/mob/eye/Life()
/mob/observer/eye/Life()
..()
// If we lost our client, reset the list of visible chunks so they update properly on return
if(owner == src && !client)

View File

@@ -3,11 +3,11 @@
// A mob that a cultists controls to look around the station with.
// It streams chunks as it moves around, which will show it what the cultist can and cannot see.
/mob/eye/maskEye
/mob/observer/eye/maskEye
name = "Eye of Nar-Sie"
acceleration = 0
owner_follows_eye = 1
/mob/eye/maskEye/New()
/mob/observer/eye/maskEye/New()
..()
visualnet = cultnet

View File

@@ -29,6 +29,7 @@
..()
/obj/structure/New()
..()
updateVisibility(src)
// EFFECTS

View File

@@ -36,7 +36,7 @@
// Updates what the aiEye can see. It is recommended you use this when the aiEye moves or it's location is set.
/datum/visualnet/proc/visibility(mob/eye/eye)
/datum/visualnet/proc/visibility(mob/observer/eye/eye)
// 0xf = 15
var/x1 = max(0, eye.x - 16) & ~0xf
var/y1 = max(0, eye.y - 16) & ~0xf

View File

@@ -4,14 +4,14 @@
if(!client)
return
if(speaker && !speaker.client && istype(src,/mob/dead/observer) && client.prefs.toggles & CHAT_GHOSTEARS && !speaker in view(src))
if(speaker && !speaker.client && istype(src,/mob/observer/dead) && client.prefs.toggles & CHAT_GHOSTEARS && !speaker in view(src))
//Does the speaker have a client? It's either random stuff that observers won't care about (Experiment 97B says, 'EHEHEHEHEHEHEHE')
//Or someone snoring. So we make it where they won't hear it.
return
//make sure the air can transmit speech - hearer's side
var/turf/T = get_turf(src)
if ((T) && (!(istype(src, /mob/dead/observer)))) //Ghosts can hear even in vacuum.
if ((T) && (!(istype(src, /mob/observer/dead)))) //Ghosts can hear even in vacuum.
var/datum/gas_mixture/environment = T.return_air()
var/pressure = (environment)? environment.return_pressure() : 0
if(pressure < SOUND_MINIMUM_PRESSURE && get_dist(speaker, src) > 1)
@@ -50,7 +50,7 @@
message = "<i>[message]</i>"
var/track = null
if(istype(src, /mob/dead/observer))
if(istype(src, /mob/observer/dead))
if(italics && client.prefs.toggles & CHAT_GHOSTRADIO)
return
if(speaker_name != speaker.real_name && speaker.real_name)
@@ -177,7 +177,7 @@
else
track = "<a href='byond://?src=\ref[src];trackname=[html_encode(speaker_name)];track=\ref[speaker]'>[speaker_name] ([jobname])</a>"
if(istype(src, /mob/dead/observer))
if(istype(src, /mob/observer/dead))
if(speaker_name != speaker.real_name && !isAI(speaker)) //Announce computer and various stuff that broadcasts doesn't use it's real name but AI's can't pretend to be other mobs.
speaker_name = "[speaker.real_name] ([speaker_name])"
track = "[speaker_name] ([ghost_follow_link(speaker, src)])"
@@ -199,7 +199,7 @@
/mob/proc/on_hear_radio(part_a, speaker_name, track, part_b, formatted)
src << "[part_a][speaker_name][part_b][formatted]"
/mob/dead/observer/on_hear_radio(part_a, speaker_name, track, part_b, formatted)
/mob/observer/dead/on_hear_radio(part_a, speaker_name, track, part_b, formatted)
src << "[part_a][track][part_b][formatted]"
/mob/living/silicon/on_hear_radio(part_a, speaker_name, track, part_b, formatted)
@@ -230,7 +230,7 @@
var/heard = ""
if(prob(15))
var/list/punctuation = list(",", "!", ".", ";", "?")
var/list/messages = text2list(message, " ")
var/list/messages = splittext(message, " ")
var/R = rand(1, messages.len)
var/heardword = messages[R]
if(copytext(heardword,1, 1) in punctuation)

View File

@@ -1,43 +1,3 @@
//This proc is called whenever someone clicks an inventory ui slot.
/mob/proc/attack_ui(slot)
var/obj/item/W = get_active_hand()
if(istype(W))
equip_to_slot_if_possible(W, slot)
/mob/proc/put_in_any_hand_if_possible(obj/item/W as obj, del_on_fail = 0, disable_warning = 1, redraw_mob = 1)
if(equip_to_slot_if_possible(W, slot_l_hand, del_on_fail, disable_warning, redraw_mob))
return 1
else if(equip_to_slot_if_possible(W, slot_r_hand, del_on_fail, disable_warning, redraw_mob))
return 1
return 0
//This is a SAFE proc. Use this instead of equip_to_slot()!
//set del_on_fail to have it delete W if it fails to equip
//set disable_warning to disable the 'you are unable to equip that' warning.
//unset redraw_mob to prevent the mob from being redrawn at the end.
/mob/proc/equip_to_slot_if_possible(obj/item/W as obj, slot, del_on_fail = 0, disable_warning = 0, redraw_mob = 1)
if(!istype(W)) return 0
if(!W.mob_can_equip(src, slot))
if(del_on_fail)
qdel(W)
else
if(!disable_warning)
src << "\red You are unable to equip that." //Only print if del_on_fail is false
return 0
equip_to_slot(W, slot, redraw_mob) //This proc should not ever fail.
return 1
//This is an UNSAFE proc. It merely handles the actual job of equipping. All the checks on whether you can or can't eqip need to be done before! Use mob_can_equip() for that task.
//In most cases you will want to use equip_to_slot_if_possible()
/mob/proc/equip_to_slot(obj/item/W as obj, slot)
return
//This is just a commonly used configuration for the equip_to_slot_if_possible() proc, used to equip people when the rounds tarts and when events happen and such.
/mob/proc/equip_to_slot_or_del(obj/item/W as obj, slot)
return equip_to_slot_if_possible(W, slot, 1, 1, 0)
//The list of slots by priority. equip_to_appropriate_slot() uses this list. Doesn't matter if a mob type doesn't have a slot.
var/list/slot_equipment_priority = list( \
slot_back,\
@@ -58,6 +18,49 @@ var/list/slot_equipment_priority = list( \
slot_r_store\
)
/mob
var/obj/item/weapon/storage/s_active = null // Even ghosts can/should be able to peek into boxes on the ground
//This proc is called whenever someone clicks an inventory ui slot.
/mob/proc/attack_ui(var/slot)
var/obj/item/W = get_active_hand()
if(istype(W))
equip_to_slot_if_possible(W, slot)
/* Inventory manipulation */
/mob/proc/put_in_any_hand_if_possible(obj/item/W as obj, del_on_fail = 0, disable_warning = 1, redraw_mob = 1)
if(equip_to_slot_if_possible(W, slot_l_hand, del_on_fail, disable_warning, redraw_mob))
return 1
else if(equip_to_slot_if_possible(W, slot_r_hand, del_on_fail, disable_warning, redraw_mob))
return 1
return 0
//This is a SAFE proc. Use this instead of equip_to_slot()!
//set del_on_fail to have it delete W if it fails to equip
//set disable_warning to disable the 'you are unable to equip that' warning.
//unset redraw_mob to prevent the mob from being redrawn at the end.
/mob/proc/equip_to_slot_if_possible(obj/item/W as obj, slot, del_on_fail = 0, disable_warning = 0, redraw_mob = 1)
if(!W.mob_can_equip(src, slot))
if(del_on_fail)
qdel(W)
else
if(!disable_warning)
src << "\red You are unable to equip that." //Only print if del_on_fail is false
return 0
equip_to_slot(W, slot, redraw_mob) //This proc should not ever fail.
return 1
//This is an UNSAFE proc. It merely handles the actual job of equipping. All the checks on whether you can or can't eqip need to be done before! Use mob_can_equip() for that task.
//In most cases you will want to use equip_to_slot_if_possible()
/mob/proc/equip_to_slot(obj/item/W as obj, slot)
return
//This is just a commonly used configuration for the equip_to_slot_if_possible() proc, used to equip people when the rounds tarts and when events happen and such.
/mob/proc/equip_to_slot_or_del(obj/item/W as obj, slot)
return equip_to_slot_if_possible(W, slot, 1, 1, 0)
//Checks if a given slot can be accessed at this time, either to equip or unequip I
/mob/proc/slot_is_accessible(var/slot, var/obj/item/I, mob/user=null)
return 1
@@ -65,8 +68,6 @@ var/list/slot_equipment_priority = list( \
//puts the item "W" into an appropriate slot in a human's inventory
//returns 0 if it cannot, 1 if successful
/mob/proc/equip_to_appropriate_slot(obj/item/W)
if(!istype(W)) return 0
for(var/slot in slot_equipment_priority)
if(equip_to_slot_if_possible(W, slot, del_on_fail=0, disable_warning=1, redraw_mob=1))
return 1
@@ -74,32 +75,15 @@ var/list/slot_equipment_priority = list( \
return 0
/mob/proc/equip_to_storage(obj/item/newitem)
// Try put it in their backpack
if(istype(src.back,/obj/item/weapon/storage))
var/obj/item/weapon/storage/backpack = src.back
if(backpack.contents.len < backpack.storage_slots)
newitem.forceMove(src.back)
return 1
// Try to place it in any item that can store stuff, on the mob.
for(var/obj/item/weapon/storage/S in src.contents)
if (S.contents.len < S.storage_slots)
newitem.forceMove(S)
return 1
return 0
//These procs handle putting s tuff in your hand. It's probably best to use these rather than setting l_hand = ...etc
//as they handle all relevant stuff like adding it to the player's screen and updating their overlays.
/* Hands */
//Returns the thing in our active hand
/mob/proc/get_active_hand()
if(hand) return l_hand
else return r_hand
//Returns the thing in our inactive hand
/mob/proc/get_inactive_hand()
if(hand) return r_hand
else return l_hand
//Puts the item into your l_hand if possible and calls all necessary triggers/updates. returns 1 on success.
/mob/proc/put_in_l_hand(var/obj/item/W)
@@ -150,16 +134,15 @@ var/list/slot_equipment_priority = list( \
//Drops the item in our left hand
/mob/proc/drop_l_hand(var/atom/Target)
return drop_from_inventory(l_hand, Target)
return 0
//Drops the item in our right hand
/mob/proc/drop_r_hand(var/atom/Target)
return drop_from_inventory(r_hand, Target)
return 0
//Drops the item in our active hand. TODO: rename this to drop_active_hand or something
/mob/proc/drop_item(var/atom/Target)
if(hand) return drop_l_hand(Target)
else return drop_r_hand(Target)
return
/*
Removes the object from any slots the mob might have, calling the appropriate icon update proc.
@@ -173,19 +156,6 @@ var/list/slot_equipment_priority = list( \
the search through all the slots, without having to duplicate the rest of the item dropping.
*/
/mob/proc/u_equip(obj/W as obj)
if (W == r_hand)
r_hand = null
update_inv_r_hand(0)
else if (W == l_hand)
l_hand = null
update_inv_l_hand(0)
else if (W == back)
back = null
update_inv_back(0)
else if (W == wear_mask)
wear_mask = null
update_inv_wear_mask(0)
return
/mob/proc/isEquipped(obj/item/I)
if(!I)
@@ -229,11 +199,6 @@ var/list/slot_equipment_priority = list( \
//Returns the item equipped to the specified slot, if any.
/mob/proc/get_equipped_item(var/slot)
switch(slot)
if(slot_l_hand) return l_hand
if(slot_r_hand) return r_hand
if(slot_back) return back
if(slot_wear_mask) return wear_mask
return null
//Outdated but still in use apparently. This should at least be a human proc.

View File

@@ -114,7 +114,7 @@
/mob/new_player/hear_broadcast(var/datum/language/language, var/mob/speaker, var/speaker_name, var/message)
return
/mob/dead/observer/hear_broadcast(var/datum/language/language, var/mob/speaker, var/speaker_name, var/message)
/mob/observer/dead/hear_broadcast(var/datum/language/language, var/mob/speaker, var/speaker_name, var/message)
if(speaker.name == speaker_name || antagHUD)
src << "<i><span class='game say'>[language.name], <span class='name'>[speaker_name]</span> ([ghost_follow_link(speaker, src)]) [message]</span></i>"
else

View File

@@ -92,7 +92,7 @@
. += pick(map[min_char])
message = copytext(message, min_index + 1)
return list2text(.)
return jointext(., null)
#undef AUTOHISS_OFF
#undef AUTOHISS_BASIC

View File

@@ -288,7 +288,7 @@
/* Assembly */
/obj/item/weapon/storage/toolbox/mechanical/attackby(var/obj/item/stack/tile/floor/T, mob/user as mob)
/obj/item/weapon/storage/toolbox/mechanical/attackby(var/obj/item/stack/tile/floor/T, mob/living/user as mob)
if(!istype(T, /obj/item/stack/tile/floor))
..()
return

View File

@@ -2,7 +2,7 @@
var/mob/living/carbon/human/H = over_object
if(!istype(H) || !Adjacent(H))
return ..()
if(H.a_intent == "grab" && hat && !(H.l_hand && H.r_hand))
if(H.a_intent == "grab" && hat && !H.hands_are_full())
hat.loc = get_turf(src)
H.put_in_hands(hat)
H.visible_message("<span class='danger'>\The [H] removes \the [src]'s [hat].</span>")

View File

@@ -23,7 +23,7 @@
spawn(600) reset_search()
/obj/item/device/mmi/digital/posibrain/proc/request_player()
for(var/mob/dead/observer/O in player_list)
for(var/mob/observer/dead/O in player_list)
if(!O.MayRespawn())
continue
if(jobban_isbanned(O, "AI") && jobban_isbanned(O, "Cyborg"))

View File

@@ -3,40 +3,40 @@
set name = "Give"
// TODO : Change to incapacitated() on merge.
if(usr.stat || usr.lying || usr.resting || usr.buckled)
if(src.stat || src.lying || src.resting || src.buckled)
return
if(!istype(target) || target.stat || target.lying || target.resting || target.buckled || target.client == null)
return
var/obj/item/I = usr.get_active_hand()
var/obj/item/I = src.get_active_hand()
if(!I)
I = usr.get_inactive_hand()
I = src.get_inactive_hand()
if(!I)
usr << "<span class='warning'>You don't have anything in your hands to give to \the [target].</span>"
src << "<span class='warning'>You don't have anything in your hands to give to \the [target].</span>"
return
if(alert(target,"[usr] wants to give you \a [I]. Will you accept it?",,"No","Yes") == "No")
target.visible_message("<span class='notice'>\The [usr] tried to hand \the [I] to \the [target], \
if(alert(target,"[src] wants to give you \a [I]. Will you accept it?",,"No","Yes") == "No")
target.visible_message("<span class='notice'>\The [src] tried to hand \the [I] to \the [target], \
but \the [target] didn't want it.</span>")
return
if(!I) return
if(!Adjacent(target))
usr << "<span class='warning'>You need to stay in reaching distance while giving an object.</span>"
target << "<span class='warning'>\The [usr] moved too far away.</span>"
src << "<span class='warning'>You need to stay in reaching distance while giving an object.</span>"
target << "<span class='warning'>\The [src] moved too far away.</span>"
return
if(I.loc != usr || (usr.l_hand != I && usr.r_hand != I))
usr << "<span class='warning'>You need to keep the item in your hands.</span>"
target << "<span class='warning'>\The [usr] seems to have given up on passing \the [I] to you.</span>"
if(I.loc != src || !src.item_is_in_hands(I))
src << "<span class='warning'>You need to keep the item in your hands.</span>"
target << "<span class='warning'>\The [src] seems to have given up on passing \the [I] to you.</span>"
return
if(target.r_hand != null && target.l_hand != null)
if(target.hands_are_full())
target << "<span class='warning'>Your hands are full.</span>"
usr << "<span class='warning'>Their hands are full.</span>"
src << "<span class='warning'>Their hands are full.</span>"
return
if(usr.unEquip(I))
if(src.unEquip(I))
target.put_in_hands(I) // If this fails it will just end up on the floor, but that's fitting for things like dionaea.
target.visible_message("<span class='notice'>\The [usr] handed \the [I] to \the [target].</span>")
target.visible_message("<span class='notice'>\The [src] handed \the [I] to \the [target].</span>")

View File

@@ -538,9 +538,9 @@
if ("handshake")
m_type = 1
if (!src.restrained() && !src.r_hand)
var/mob/M = null
var/mob/living/M = null
if (param)
for (var/mob/A in view(1, null))
for (var/mob/living/A in view(1, null))
if (param == A.name)
M = A
break

View File

@@ -210,7 +210,7 @@
msg += "[T.He] [T.is] small halfling!\n"
var/distance = get_dist(usr,src)
if(istype(usr, /mob/dead/observer) || usr.stat == 2) // ghosts can see anything
if(istype(usr, /mob/observer/dead) || usr.stat == 2) // ghosts can see anything
distance = 1
if (src.stat)
msg += "<span class='warning'>[T.He] [T.is]n't responding to anything around [T.him] and seems to be asleep.</span>\n"

View File

@@ -842,7 +842,7 @@
target.show_message("\blue You hear a voice that seems to echo around the room: [say]")
usr.show_message("\blue You project your mind into [target.real_name]: [say]")
log_say("[key_name(usr)] sent a telepathic message to [key_name(target)]: [say]")
for(var/mob/dead/observer/G in world)
for(var/mob/observer/dead/G in world)
G.show_message("<i>Telepathic message from <b>[src]</b> to <b>[target]</b>: [say]</i>")
/mob/living/carbon/human/proc/remoteobserve()
@@ -1115,9 +1115,11 @@
spawn(0)
regenerate_icons()
if(vessel.total_volume < species.blood_volume)
vessel.maximum_volume = species.blood_volume
vessel.add_reagent("blood", species.blood_volume - vessel.total_volume)
else if(vessel.total_volume > species.blood_volume)
vessel.remove_reagent("blood", vessel.total_volume - species.blood_volume)
vessel.maximum_volume = species.blood_volume
fixblood()
// Rebuild the HUD. If they aren't logged in then login() should reinstantiate it for them.

View File

@@ -32,7 +32,8 @@
var/age = 30 //Player's age (pure fluff)
var/b_type = "A+" //Player's bloodtype
var/underwear = 1 //Which underwear the player wants
var/underwear_top = 1 //Which underwear the player wants
var/underwear_bottom = 1
var/undershirt = 0 //Which undershirt the player wants.
var/socks = 0 //Which socks the player wants.
var/backbag = 2 //Which backpack type the player has chosen. Nothing, Satchel or Backpack.

View File

@@ -71,7 +71,7 @@
var/mob/M = targets[target]
if(istype(M, /mob/dead/observer) || M.stat == DEAD)
if(istype(M, /mob/observer/dead) || M.stat == DEAD)
src << "Not even a [src.species.name] can speak to the dead."
return

View File

@@ -207,7 +207,7 @@
var/covered = 0 // Basic coverage can help.
for(var/obj/item/clothing/clothes in H)
if(H.l_hand == clothes|| H.r_hand == clothes)
if(H.item_is_in_hands(clothes))
continue
if((clothes.body_parts_covered & UPPER_TORSO) && (clothes.body_parts_covered & LOWER_TORSO))
covered = 1

View File

@@ -320,8 +320,10 @@ var/global/list/damage_icon_parts = list()
stand_icon.Blend(base_icon,ICON_OVERLAY)
//Underwear
if(underwear && species.appearance_flags & HAS_UNDERWEAR)
stand_icon.Blend(new /icon('icons/mob/human.dmi', underwear), ICON_OVERLAY)
if(underwear_top && species.appearance_flags & HAS_UNDERWEAR)
stand_icon.Blend(new /icon('icons/mob/human.dmi', underwear_top), ICON_OVERLAY)
if(underwear_bottom && species.appearance_flags & HAS_UNDERWEAR)
stand_icon.Blend(new /icon('icons/mob/human.dmi', underwear_bottom), ICON_OVERLAY)
if(undershirt && species.appearance_flags & HAS_UNDERWEAR)
stand_icon.Blend(new /icon('icons/mob/human.dmi', undershirt), ICON_OVERLAY)

View File

@@ -92,7 +92,7 @@
if(voice_sub == "Unknown")
if(copytext(message, 1, 2) != "*")
var/list/temp_message = text2list(message, " ")
var/list/temp_message = splittext(message, " ")
var/list/pick_list = list()
for(var/i = 1, i <= temp_message.len, i++)
pick_list += i
@@ -101,7 +101,7 @@
if(findtext(temp_message[H], "*") || findtext(temp_message[H], ";") || findtext(temp_message[H], ":")) continue
temp_message[H] = ninjaspeak(temp_message[H])
pick_list -= H
message = list2text(temp_message, " ")
message = jointext(temp_message, " ")
message = replacetext(message, "o", "<22>")
message = replacetext(message, "p", "<22>")
message = replacetext(message, "l", "<22>")

View File

@@ -244,8 +244,8 @@
processing_objects.Add(src)
process()
var/mob/dead/observer/ghost
for(var/mob/dead/observer/O in src.loc)
var/mob/observer/dead/ghost
for(var/mob/observer/dead/O in src.loc)
if(!O.client) continue
if(O.mind && O.mind.current && O.mind.current.stat != DEAD) continue
ghost = O
@@ -256,8 +256,8 @@
icon_state = "golem"
attack_hand(mob/living/user as mob)
var/mob/dead/observer/ghost
for(var/mob/dead/observer/O in src.loc)
var/mob/observer/dead/ghost
for(var/mob/observer/dead/O in src.loc)
if(!O.client) continue
if(O.mind && O.mind.current && O.mind.current.stat != DEAD) continue
ghost = O
@@ -273,7 +273,7 @@
proc/announce_to_ghosts()
for(var/mob/dead/observer/G in player_list)
for(var/mob/observer/dead/G in player_list)
if(G.client)
var/area/A = get_area(src)
if(A)

View File

@@ -0,0 +1,172 @@
/mob/living
var/hand = null
var/obj/item/l_hand = null
var/obj/item/r_hand = null
var/obj/item/weapon/back = null//Human/Monkey
var/obj/item/weapon/tank/internal = null//Human/Monkey
var/obj/item/clothing/mask/wear_mask = null//Carbon
/mob/living/equip_to_storage(obj/item/newitem)
// Try put it in their backpack
if(istype(src.back,/obj/item/weapon/storage))
var/obj/item/weapon/storage/backpack = src.back
if(backpack.contents.len < backpack.storage_slots)
newitem.forceMove(src.back)
return 1
// Try to place it in any item that can store stuff, on the mob.
for(var/obj/item/weapon/storage/S in src.contents)
if (S.contents.len < S.storage_slots)
newitem.forceMove(S)
return 1
return 0
//Returns the thing in our active hand
/mob/living/get_active_hand()
if(hand) return l_hand
else return r_hand
//Returns the thing in our inactive hand
/mob/living/get_inactive_hand()
if(hand) return r_hand
else return l_hand
//Drops the item in our active hand. TODO: rename this to drop_active_hand or something
/mob/living/drop_item(var/atom/Target)
if(hand) return drop_l_hand(Target)
else return drop_r_hand(Target)
//Drops the item in our left hand
/mob/living/drop_l_hand(var/atom/Target)
return drop_from_inventory(l_hand, Target)
//Drops the item in our right hand
/mob/living/drop_r_hand(var/atom/Target)
return drop_from_inventory(r_hand, Target)
/mob/living/proc/hands_are_full()
return (r_hand && l_hand)
/mob/living/proc/item_is_in_hands(var/obj/item/I)
return (I == r_hand || I == l_hand)
/mob/living/proc/update_held_icons()
if(l_hand)
l_hand.update_held_icon()
if(r_hand)
r_hand.update_held_icon()
/mob/living/proc/get_type_in_hands(var/T)
if(istype(l_hand, T))
return l_hand
if(istype(r_hand, T))
return r_hand
return null
/mob/living/proc/get_left_hand()
return l_hand
/mob/living/proc/get_right_hand()
return r_hand
/mob/living/u_equip(obj/W as obj)
if (W == r_hand)
r_hand = null
update_inv_r_hand(0)
else if (W == l_hand)
l_hand = null
update_inv_l_hand(0)
else if (W == back)
back = null
update_inv_back(0)
else if (W == wear_mask)
wear_mask = null
update_inv_wear_mask(0)
return
/mob/living/get_equipped_item(var/slot)
switch(slot)
if(slot_l_hand) return l_hand
if(slot_r_hand) return r_hand
if(slot_back) return back
if(slot_wear_mask) return wear_mask
return null
/mob/living/show_inv(mob/user as mob)
user.set_machine(src)
var/dat = {"
<B><HR><FONT size=3>[name]</FONT></B>
<BR><HR>
<BR><B>Head(Mask):</B> <A href='?src=\ref[src];item=mask'>[(wear_mask ? wear_mask : "Nothing")]</A>
<BR><B>Left Hand:</B> <A href='?src=\ref[src];item=l_hand'>[(l_hand ? l_hand : "Nothing")]</A>
<BR><B>Right Hand:</B> <A href='?src=\ref[src];item=r_hand'>[(r_hand ? r_hand : "Nothing")]</A>
<BR><B>Back:</B> <A href='?src=\ref[src];item=back'>[(back ? back : "Nothing")]</A> [((istype(wear_mask, /obj/item/clothing/mask) && istype(back, /obj/item/weapon/tank) && !( internal )) ? text(" <A href='?src=\ref[];item=internal'>Set Internal</A>", src) : "")]
<BR>[(internal ? text("<A href='?src=\ref[src];item=internal'>Remove Internal</A>") : "")]
<BR><A href='?src=\ref[src];item=pockets'>Empty Pockets</A>
<BR><A href='?src=\ref[user];refresh=1'>Refresh</A>
<BR><A href='?src=\ref[user];mach_close=mob[name]'>Close</A>
<BR>"}
user << browse(dat, text("window=mob[];size=325x500", name))
onclose(user, "mob[name]")
return
/mob/living/ret_grab(obj/effect/list_container/mobl/L as obj, flag)
if ((!( istype(l_hand, /obj/item/weapon/grab) ) && !( istype(r_hand, /obj/item/weapon/grab) )))
if (!( L ))
return null
else
return L.container
else
if (!( L ))
L = new /obj/effect/list_container/mobl( null )
L.container += src
L.master = src
if (istype(l_hand, /obj/item/weapon/grab))
var/obj/item/weapon/grab/G = l_hand
if (!( L.container.Find(G.affecting) ))
L.container += G.affecting
if (G.affecting)
G.affecting.ret_grab(L, 1)
if (istype(r_hand, /obj/item/weapon/grab))
var/obj/item/weapon/grab/G = r_hand
if (!( L.container.Find(G.affecting) ))
L.container += G.affecting
if (G.affecting)
G.affecting.ret_grab(L, 1)
if (!( flag ))
if (L.master == src)
var/list/temp = list( )
temp += L.container
//L = null
qdel(L)
return temp
else
return L.container
return
/mob/living/mode()
set name = "Activate Held Object"
set category = "Object"
set src = usr
if(istype(loc,/obj/mecha)) return
if(hand)
var/obj/item/W = l_hand
if (W)
W.attack_self(src)
update_inv_l_hand()
else
var/obj/item/W = r_hand
if (W)
W.attack_self(src)
update_inv_r_hand()
return
/mob/living/abiotic(var/full_body = 0)
if(full_body && ((src.l_hand && !( src.l_hand.abstract )) || (src.r_hand && !( src.r_hand.abstract )) || (src.back || src.wear_mask)))
return 1
if((src.l_hand && !( src.l_hand.abstract )) || (src.r_hand && !( src.r_hand.abstract )))
return 1
return 0

View File

@@ -865,3 +865,63 @@ default behaviour is:
sleep(350)
lastpuke = 0
/mob/living/update_canmove()
if(!resting && cannot_stand() && can_stand_overridden())
lying = 0
canmove = 1
else
if(istype(buckled, /obj/vehicle))
var/obj/vehicle/V = buckled
if(cannot_stand())
lying = 0
canmove = 1
pixel_y = V.mob_offset_y - 5
else
if(buckled.buckle_lying != -1) lying = buckled.buckle_lying
canmove = 1
pixel_y = V.mob_offset_y
else if(buckled)
anchored = 1
canmove = 0
if(istype(buckled))
if(buckled.buckle_lying != -1)
lying = buckled.buckle_lying
if(buckled.buckle_movable)
anchored = 0
canmove = 1
else if(cannot_stand())
lying = 1
canmove = 0
else if(stunned)
canmove = 0
else if(captured)
anchored = 1
canmove = 0
lying = 0
else
lying = 0
canmove = 1
if(lying)
density = 0
if(l_hand) unEquip(l_hand)
if(r_hand) unEquip(r_hand)
else
density = initial(density)
for(var/obj/item/weapon/grab/G in grabbed_by)
if(G.state >= GRAB_AGGRESSIVE)
canmove = 0
break
//Temporarily moved here from the various life() procs
//I'm fixing stuff incrementally so this will likely find a better home.
//It just makes sense for now. ~Carn
if( update_icon ) //forces a full overlay update
update_icon = 0
regenerate_icons()
else if( lying != lying_prev )
update_icons()
return canmove

View File

@@ -232,11 +232,11 @@ var/list/ai_verbs_hidden = list( // For why this exists, refer to https://xkcd.c
/mob/living/silicon/ai/proc/setup_icon()
var/file = file2text("config/custom_sprites.txt")
var/lines = text2list(file, "\n")
var/lines = splittext(file, "\n")
for(var/line in lines)
// split & clean up
var/list/Entry = text2list(line, ":")
var/list/Entry = splittext(line, ":")
for(var/i = 1 to Entry.len)
Entry[i] = trim(Entry[i])

View File

@@ -39,6 +39,6 @@
/mob/proc/showLaws(var/mob/living/silicon/S)
return
/mob/dead/observer/showLaws(var/mob/living/silicon/S)
/mob/observer/dead/showLaws(var/mob/living/silicon/S)
if(antagHUD || is_admin(src))
S.laws.show_laws(src)

View File

@@ -233,7 +233,7 @@ var/datum/paiController/paiController // Global handler for pAI candidates
for(var/datum/paiCandidate/c in paiController.pai_candidates)
if(c.ready)
var/found = 0
for(var/mob/dead/observer/o in player_list)
for(var/mob/observer/dead/o in player_list)
if(o.key == c.key && o.MayRespawn())
found = 1
if(found)
@@ -346,7 +346,7 @@ var/datum/paiController/paiController // Global handler for pAI candidates
/datum/paiController/proc/requestRecruits(var/mob/user)
inquirer = user
for(var/mob/dead/observer/O in player_list)
for(var/mob/observer/dead/O in player_list)
if(!O.MayRespawn())
continue
if(jobban_isbanned(O, "pAI"))

View File

@@ -6,7 +6,7 @@ var/list/robot_custom_icons
/hook/startup/proc/load_robot_custom_sprites()
var/config_file = file2text("config/custom_sprites.txt")
var/list/lines = text2list(config_file, "\n")
var/list/lines = splittext(config_file, "\n")
robot_custom_icons = list()
for(var/line in lines)

View File

@@ -278,7 +278,7 @@ var/list/mob_hat_cache = list()
//Reboot procs.
/mob/living/silicon/robot/drone/proc/request_player()
for(var/mob/dead/observer/O in player_list)
for(var/mob/observer/dead/O in player_list)
if(jobban_isbanned(O, "Cyborg"))
continue
if(O.client)

View File

@@ -59,7 +59,7 @@
/obj/machinery/drone_fabricator/examine(mob/user)
..(user)
if(produce_drones && drone_progress >= 100 && istype(user,/mob/dead) && config.allow_drone_spawn && count_drones() < config.max_maint_drones)
if(produce_drones && drone_progress >= 100 && istype(user,/mob/observer/dead) && config.allow_drone_spawn && count_drones() < config.max_maint_drones)
user << "<BR><B>A drone is prepared. Select 'Join As Drone' from the Ghost tab to spawn as a maintenance drone.</B>"
/obj/machinery/drone_fabricator/proc/create_drone(var/client/player)
@@ -70,7 +70,7 @@
if(!produce_drones || !config.allow_drone_spawn || count_drones() >= config.max_maint_drones)
return
if(!player || !istype(player.mob,/mob/dead))
if(!player || !istype(player.mob,/mob/observer/dead))
return
announce_ghost_joinleave(player, 0, "They have taken control over a maintenance drone.")
@@ -85,7 +85,7 @@
drone_progress = 0
/mob/dead/verb/join_as_drone()
/mob/observer/dead/verb/join_as_drone()
set category = "Ghost"
set name = "Join As Drone"

View File

@@ -336,7 +336,7 @@
weaponlock_time = 120
/mob/living/silicon/robot/update_canmove()
if(paralysis || stunned || weakened || buckled || lockcharge || !is_component_functioning("actuator")) canmove = 0
if(paralysis || stunned || weakened || buckled || lockdown || !is_component_functioning("actuator")) canmove = 0
else canmove = 1
return canmove

View File

@@ -81,7 +81,8 @@
var/weapon_lock = 0
var/weaponlock_time = 120
var/lawupdate = 1 //Cyborgs will sync their laws with their AI by default
var/lockcharge //Used when locking down a borg to preserve cell charge
var/lockcharge //Used when looking to see if a borg is locked down.
var/lockdown = 0 //Controls whether or not the borg is actually locked down.
var/speed = 0 //Cause sec borgs gotta go fast //No they dont!
var/scrambledcodes = 0 // Used to determine if a borg shows up on the robotics console. Setting to one hides them.
var/tracking_entities = 0 //The number of known entities currently accessing the internal camera
@@ -864,6 +865,7 @@
disconnect_from_ai()
lawupdate = 0
lockcharge = 0
lockdown = 0
canmove = 1
scrambledcodes = 1
//Disconnect it's camera so it's not so easily tracked.
@@ -887,6 +889,7 @@
// They stay locked down if their wire is cut.
if(wires.LockedCut())
state = 1
lockdown = state
lockcharge = state
update_canmove()

View File

@@ -173,7 +173,7 @@
//Procs for grabbing players.
/mob/living/simple_animal/borer/proc/request_player()
for(var/mob/dead/observer/O in player_list)
for(var/mob/observer/dead/O in player_list)
if(jobban_isbanned(O, "Borer"))
continue
if(O.client)

View File

@@ -57,7 +57,7 @@
handle_movement_target()
if(prob(2)) //spooky
var/mob/dead/observer/spook = locate() in range(src,5)
var/mob/observer/dead/spook = locate() in range(src,5)
if(spook)
var/turf/T = spook.loc
var/list/visible = list()

View File

@@ -61,7 +61,7 @@
if(!B.brainmob.key)
var/ghost_can_reenter = 0
if(B.brainmob.mind)
for(var/mob/dead/observer/G in player_list)
for(var/mob/observer/dead/G in player_list)
if(G.can_reenter_corpse && G.mind == B.brainmob.mind)
ghost_can_reenter = 1
break

View File

@@ -195,21 +195,6 @@
/mob/proc/show_inv(mob/user as mob)
user.set_machine(src)
var/dat = {"
<B><HR><FONT size=3>[name]</FONT></B>
<BR><HR>
<BR><B>Head(Mask):</B> <A href='?src=\ref[src];item=mask'>[(wear_mask ? wear_mask : "Nothing")]</A>
<BR><B>Left Hand:</B> <A href='?src=\ref[src];item=l_hand'>[(l_hand ? l_hand : "Nothing")]</A>
<BR><B>Right Hand:</B> <A href='?src=\ref[src];item=r_hand'>[(r_hand ? r_hand : "Nothing")]</A>
<BR><B>Back:</B> <A href='?src=\ref[src];item=back'>[(back ? back : "Nothing")]</A> [((istype(wear_mask, /obj/item/clothing/mask) && istype(back, /obj/item/weapon/tank) && !( internal )) ? text(" <A href='?src=\ref[];item=internal'>Set Internal</A>", src) : "")]
<BR>[(internal ? text("<A href='?src=\ref[src];item=internal'>Remove Internal</A>") : "")]
<BR><A href='?src=\ref[src];item=pockets'>Empty Pockets</A>
<BR><A href='?src=\ref[user];refresh=1'>Refresh</A>
<BR><A href='?src=\ref[user];mach_close=mob[name]'>Close</A>
<BR>"}
user << browse(dat, text("window=mob[];size=325x500", name))
onclose(user, "mob[name]")
return
//mob verbs are faster than object verbs. See http://www.byond.com/forum/?post=1326139&page=2#comment8198716 for why this isn't atom/verb/examine()
@@ -248,37 +233,6 @@
/mob/proc/ret_grab(obj/effect/list_container/mobl/L as obj, flag)
if ((!( istype(l_hand, /obj/item/weapon/grab) ) && !( istype(r_hand, /obj/item/weapon/grab) )))
if (!( L ))
return null
else
return L.container
else
if (!( L ))
L = new /obj/effect/list_container/mobl( null )
L.container += src
L.master = src
if (istype(l_hand, /obj/item/weapon/grab))
var/obj/item/weapon/grab/G = l_hand
if (!( L.container.Find(G.affecting) ))
L.container += G.affecting
if (G.affecting)
G.affecting.ret_grab(L, 1)
if (istype(r_hand, /obj/item/weapon/grab))
var/obj/item/weapon/grab/G = r_hand
if (!( L.container.Find(G.affecting) ))
L.container += G.affecting
if (G.affecting)
G.affecting.ret_grab(L, 1)
if (!( flag ))
if (L.master == src)
var/list/temp = list( )
temp += L.container
//L = null
qdel(L)
return temp
else
return L.container
return
/mob/verb/mode()
@@ -286,18 +240,6 @@
set category = "Object"
set src = usr
if(istype(loc,/obj/mecha)) return
if(hand)
var/obj/item/W = l_hand
if (W)
W.attack_self(src)
update_inv_l_hand()
else
var/obj/item/W = r_hand
if (W)
W.attack_self(src)
update_inv_r_hand()
return
/*
@@ -388,8 +330,8 @@
return
else
var/deathtime = world.time - src.timeofdeath
if(istype(src,/mob/dead/observer))
var/mob/dead/observer/G = src
if(istype(src,/mob/observer/dead))
var/mob/observer/dead/G = src
if(G.has_enabled_antagHUD == 1 && config.antag_hud_restricted)
usr << "\blue <B>Upon using the antagHUD you forfeighted the ability to join the round.</B>"
return
@@ -735,65 +677,6 @@
//Updates canmove, lying and icons. Could perhaps do with a rename but I can't think of anything to describe it.
/mob/proc/update_canmove()
if(!resting && cannot_stand() && can_stand_overridden())
lying = 0
canmove = 1
else
if(istype(buckled, /obj/vehicle))
var/obj/vehicle/V = buckled
if(cannot_stand())
lying = 0
canmove = 1
pixel_y = V.mob_offset_y - 5
else
if(buckled.buckle_lying != -1) lying = buckled.buckle_lying
canmove = 1
pixel_y = V.mob_offset_y
else if(buckled)
anchored = 1
canmove = 0
if(istype(buckled))
if(buckled.buckle_lying != -1)
lying = buckled.buckle_lying
if(buckled.buckle_movable)
anchored = 0
canmove = 1
else if(cannot_stand())
lying = 1
canmove = 0
else if(stunned)
canmove = 0
else if(captured)
anchored = 1
canmove = 0
lying = 0
else
lying = 0
canmove = 1
if(lying)
density = 0
if(l_hand) unEquip(l_hand)
if(r_hand) unEquip(r_hand)
else
density = initial(density)
for(var/obj/item/weapon/grab/G in grabbed_by)
if(G.state >= GRAB_AGGRESSIVE)
canmove = 0
break
//Temporarily moved here from the various life() procs
//I'm fixing stuff incrementally so this will likely find a better home.
//It just makes sense for now. ~Carn
if( update_icon ) //forces a full overlay update
update_icon = 0
regenerate_icons()
else if( lying != lying_prev )
update_icons()
return canmove
@@ -1007,8 +890,7 @@ mob/proc/yank_out_object()
R.adjustFireLoss(10)
selection.forceMove(get_turf(src))
if(!(U.l_hand && U.r_hand))
U.put_in_hands(selection)
U.put_in_hands(selection)
for(var/obj/item/weapon/O in pinned)
if(O == selection)

View File

@@ -60,7 +60,6 @@
var/next_move = null
var/transforming = null //Carbon
var/other = 0.0
var/hand = null
var/eye_blind = null //Carbon
var/eye_blurry = null //Carbon
var/ear_deaf = null //Carbon
@@ -119,12 +118,6 @@
var/m_intent = "run"//Living
var/lastKnownIP = null
var/obj/buckled = null//Living
var/obj/item/l_hand = null//Living
var/obj/item/r_hand = null//Living
var/obj/item/weapon/back = null//Human/Monkey
var/obj/item/weapon/tank/internal = null//Human/Monkey
var/obj/item/weapon/storage/s_active = null//Carbon
var/obj/item/clothing/mask/wear_mask = null//Carbon
var/seer = 0 //for cult//Carbon, probably Human

View File

@@ -5,8 +5,10 @@
///Called by client/Move()
///Checks to see if you are grabbing anything and if moving will affect your grab.
/client/proc/Process_Grab()
for(var/obj/item/weapon/grab/G in list(mob.l_hand, mob.r_hand))
G.reset_kill_state() //no wandering across the station/asteroid while choking someone
if(istype(mob, /mob/living))
var/mob/living/L = mob
for(var/obj/item/weapon/grab/G in list(L.l_hand, L.r_hand))
G.reset_kill_state() //no wandering across the station/asteroid while choking someone
/obj/item/weapon/grab
name = "grab"

View File

@@ -266,7 +266,7 @@ It's fairly easy to fix if dealing with single letters but not so much with comp
var/atom/oldeye=M.client.eye
var/aiEyeFlag = 0
if(istype(oldeye, /mob/eye/aiEye))
if(istype(oldeye, /mob/observer/eye/aiEye))
aiEyeFlag = 1
var/x
@@ -288,12 +288,6 @@ It's fairly easy to fix if dealing with single letters but not so much with comp
/mob/proc/abiotic(var/full_body = 0)
if(full_body && ((src.l_hand && !( src.l_hand.abstract )) || (src.r_hand && !( src.r_hand.abstract )) || (src.back || src.wear_mask)))
return 1
if((src.l_hand && !( src.l_hand.abstract )) || (src.r_hand && !( src.r_hand.abstract )))
return 1
return 0
//converts intent-strings into numbers and back
@@ -399,8 +393,8 @@ proc/is_blind(A)
follow = "([ghost_follow_link(subject, M)]) "
if(M.stat != DEAD && M.client.holder)
follow = "([admin_jump_link(subject, M.client.holder)]) "
var/mob/dead/observer/DM
if(istype(subject, /mob/dead/observer))
var/mob/observer/dead/DM
if(istype(subject, /mob/observer/dead))
DM = subject
if(M.client.holder) // What admins see
lname = "[keyname][(DM && DM.anonsay) ? "*" : (DM ? "" : "^")] ([name])"

View File

@@ -15,468 +15,468 @@
anchored = 1 // don't get pushed around
New()
mob_list += src
/mob/new_player/New()
mob_list += src
verb/new_player_panel()
set src = usr
new_player_panel_proc()
/mob/new_player/verb/new_player_panel()
set src = usr
new_player_panel_proc()
proc/new_player_panel_proc()
var/output = "<div align='center'><B>New Player Options</B>"
output +="<hr>"
output += "<p><a href='byond://?src=\ref[src];show_preferences=1'>Setup Character</A></p>"
if(!ticker || ticker.current_state <= GAME_STATE_PREGAME)
if(ready)
output += "<p>\[ <b>Ready</b> | <a href='byond://?src=\ref[src];ready=0'>Not Ready</a> \]</p>"
else
output += "<p>\[ <a href='byond://?src=\ref[src];ready=1'>Ready</a> | <b>Not Ready</b> \]</p>"
/mob/new_player/proc/new_player_panel_proc()
var/output = "<div align='center'><B>New Player Options</B>"
output +="<hr>"
output += "<p><a href='byond://?src=\ref[src];show_preferences=1'>Setup Character</A></p>"
if(!ticker || ticker.current_state <= GAME_STATE_PREGAME)
if(ready)
output += "<p>\[ <b>Ready</b> | <a href='byond://?src=\ref[src];ready=0'>Not Ready</a> \]</p>"
else
output += "<a href='byond://?src=\ref[src];manifest=1'>View the Crew Manifest</A><br><br>"
output += "<p><a href='byond://?src=\ref[src];late_join=1'>Join Game!</A></p>"
output += "<p>\[ <a href='byond://?src=\ref[src];ready=1'>Ready</a> | <b>Not Ready</b> \]</p>"
output += "<p><a href='byond://?src=\ref[src];observe=1'>Observe</A></p>"
else
output += "<a href='byond://?src=\ref[src];manifest=1'>View the Crew Manifest</A><br><br>"
output += "<p><a href='byond://?src=\ref[src];late_join=1'>Join Game!</A></p>"
if(!IsGuestKey(src.key))
establish_db_connection()
output += "<p><a href='byond://?src=\ref[src];observe=1'>Observe</A></p>"
if(dbcon.IsConnected())
var/isadmin = 0
if(src.client && src.client.holder)
isadmin = 1
var/DBQuery/query = dbcon.NewQuery("SELECT id FROM erro_poll_question WHERE [(isadmin ? "" : "adminonly = false AND")] Now() BETWEEN starttime AND endtime AND id NOT IN (SELECT pollid FROM erro_poll_vote WHERE ckey = \"[ckey]\") AND id NOT IN (SELECT pollid FROM erro_poll_textreply WHERE ckey = \"[ckey]\")")
query.Execute()
var/newpoll = 0
while(query.NextRow())
newpoll = 1
break
if(!IsGuestKey(src.key))
establish_db_connection()
if(newpoll)
output += "<p><b><a href='byond://?src=\ref[src];showpoll=1'>Show Player Polls</A> (NEW!)</b></p>"
else
output += "<p><a href='byond://?src=\ref[src];showpoll=1'>Show Player Polls</A></p>"
output += "</div>"
src << browse(output,"window=playersetup;size=210x280;can_close=0")
return
Stat()
..()
if(statpanel("Lobby") && ticker)
if(ticker.hide_mode)
stat("Game Mode:", "Secret")
else
if(ticker.hide_mode == 0)
stat("Game Mode:", "[master_mode]") // Old setting for showing the game mode
if(ticker.current_state == GAME_STATE_PREGAME)
stat("Time To Start:", "[ticker.pregame_timeleft][round_progressing ? "" : " (DELAYED)"]")
stat("Players: [totalPlayers]", "Players Ready: [totalPlayersReady]")
totalPlayers = 0
totalPlayersReady = 0
for(var/mob/new_player/player in player_list)
stat("[player.key]", (player.ready)?("(Playing)"):(null))
totalPlayers++
if(player.ready)totalPlayersReady++
Topic(href, href_list[])
if(!client) return 0
if(href_list["show_preferences"])
client.prefs.ShowChoices(src)
return 1
if(href_list["ready"])
if(!ticker || ticker.current_state <= GAME_STATE_PREGAME) // Make sure we don't ready up after the round has started
ready = text2num(href_list["ready"])
else
ready = 0
if(href_list["refresh"])
src << browse(null, "window=playersetup") //closes the player setup window
new_player_panel_proc()
if(href_list["observe"])
if(alert(src,"Are you sure you wish to observe? You will have to wait 15 minutes before being able to respawn!","Player Setup","Yes","No") == "Yes")
if(!client) return 1
var/mob/dead/observer/observer = new()
spawning = 1
src << sound(null, repeat = 0, wait = 0, volume = 85, channel = 1) // MAD JAMS cant last forever yo
observer.started_as_observer = 1
close_spawn_windows()
var/obj/O = locate("landmark*Observer-Start")
if(istype(O))
src << "<span class='notice'>Now teleporting.</span>"
observer.loc = O.loc
else
src << "<span class='danger'>Could not locate an observer spawn point. Use the Teleport verb to jump to the station map.</span>"
observer.timeofdeath = world.time // Set the time of death so that the respawn timer works correctly.
announce_ghost_joinleave(src)
client.prefs.update_preview_icon()
observer.icon = client.prefs.preview_icon
observer.alpha = 127
if(client.prefs.be_random_name)
client.prefs.real_name = random_name(client.prefs.gender)
observer.real_name = client.prefs.real_name
observer.name = observer.real_name
if(!client.holder && !config.antag_hud_allowed) // For new ghosts we remove the verb from even showing up if it's not allowed.
observer.verbs -= /mob/dead/observer/verb/toggle_antagHUD // Poor guys, don't know what they are missing!
observer.key = key
qdel(src)
return 1
if(href_list["late_join"])
if(!ticker || ticker.current_state != GAME_STATE_PLAYING)
usr << "\red The round is either not ready, or has already finished..."
return
if(client.prefs.species != "Human" && !check_rights(R_ADMIN, 0))
if(!is_alien_whitelisted(src, client.prefs.species) && config.usealienwhitelist)
src << alert("You are currently not whitelisted to play [client.prefs.species].")
return 0
var/datum/species/S = all_species[client.prefs.species]
if(!(S.spawn_flags & IS_WHITELISTED))
src << alert("Your current species,[client.prefs.species], is not available for play on the station.")
return 0
LateChoices()
if(href_list["manifest"])
ViewManifest()
if(href_list["SelectedJob"])
if(!config.enter_allowed)
usr << "<span class='notice'>There is an administrative lock on entering the game!</span>"
return
else if(ticker && ticker.mode && ticker.mode.explosion_in_progress)
usr << "<span class='danger'>The station is currently exploding. Joining would go poorly.</span>"
return
if(client.prefs.species != "Human")
if(!is_alien_whitelisted(src, client.prefs.species) && config.usealienwhitelist)
src << alert("You are currently not whitelisted to play [client.prefs.species].")
return 0
var/datum/species/S = all_species[client.prefs.species]
if(!(S.spawn_flags & CAN_JOIN))
src << alert("Your current species, [client.prefs.species], is not available for play on the station.")
return 0
AttemptLateSpawn(href_list["SelectedJob"],client.prefs.spawnpoint)
return
if(href_list["privacy_poll"])
establish_db_connection()
if(!dbcon.IsConnected())
return
var/voted = 0
//First check if the person has not voted yet.
var/DBQuery/query = dbcon.NewQuery("SELECT * FROM erro_privacy WHERE ckey='[src.ckey]'")
if(dbcon.IsConnected())
var/isadmin = 0
if(src.client && src.client.holder)
isadmin = 1
var/DBQuery/query = dbcon.NewQuery("SELECT id FROM erro_poll_question WHERE [(isadmin ? "" : "adminonly = false AND")] Now() BETWEEN starttime AND endtime AND id NOT IN (SELECT pollid FROM erro_poll_vote WHERE ckey = \"[ckey]\") AND id NOT IN (SELECT pollid FROM erro_poll_textreply WHERE ckey = \"[ckey]\")")
query.Execute()
var/newpoll = 0
while(query.NextRow())
voted = 1
newpoll = 1
break
//This is a safety switch, so only valid options pass through
var/option = "UNKNOWN"
switch(href_list["privacy_poll"])
if("signed")
option = "SIGNED"
if("anonymous")
option = "ANONYMOUS"
if("nostats")
option = "NOSTATS"
if("later")
usr << browse(null,"window=privacypoll")
return
if("abstain")
option = "ABSTAIN"
if(newpoll)
output += "<p><b><a href='byond://?src=\ref[src];showpoll=1'>Show Player Polls</A> (NEW!)</b></p>"
else
output += "<p><a href='byond://?src=\ref[src];showpoll=1'>Show Player Polls</A></p>"
if(option == "UNKNOWN")
return
output += "</div>"
if(!voted)
var/sql = "INSERT INTO erro_privacy VALUES (null, Now(), '[src.ckey]', '[option]')"
var/DBQuery/query_insert = dbcon.NewQuery(sql)
query_insert.Execute()
usr << "<b>Thank you for your vote!</b>"
usr << browse(null,"window=privacypoll")
src << browse(output,"window=playersetup;size=210x280;can_close=0")
return
if(!ready && href_list["preference"])
if(client)
client.prefs.process_link(src, href_list)
else if(!href_list["late_join"])
new_player_panel()
/mob/new_player/Stat()
..()
if(href_list["showpoll"])
if(statpanel("Lobby") && ticker)
if(ticker.hide_mode)
stat("Game Mode:", "Secret")
else
if(ticker.hide_mode == 0)
stat("Game Mode:", "[master_mode]") // Old setting for showing the game mode
handle_player_polling()
return
if(ticker.current_state == GAME_STATE_PREGAME)
stat("Time To Start:", "[ticker.pregame_timeleft][round_progressing ? "" : " (DELAYED)"]")
stat("Players: [totalPlayers]", "Players Ready: [totalPlayersReady]")
totalPlayers = 0
totalPlayersReady = 0
for(var/mob/new_player/player in player_list)
stat("[player.key]", (player.ready)?("(Playing)"):(null))
totalPlayers++
if(player.ready)totalPlayersReady++
if(href_list["pollid"])
/mob/new_player/Topic(href, href_list[])
if(!client) return 0
var/pollid = href_list["pollid"]
if(istext(pollid))
pollid = text2num(pollid)
if(isnum(pollid))
src.poll_player(pollid)
return
if(href_list["votepollid"] && href_list["votetype"])
var/pollid = text2num(href_list["votepollid"])
var/votetype = href_list["votetype"]
switch(votetype)
if("OPTION")
var/optionid = text2num(href_list["voteoptionid"])
vote_on_poll(pollid, optionid)
if("TEXT")
var/replytext = href_list["replytext"]
log_text_poll_reply(pollid, replytext)
if("NUMVAL")
var/id_min = text2num(href_list["minid"])
var/id_max = text2num(href_list["maxid"])
if( (id_max - id_min) > 100 ) //Basic exploit prevention
usr << "The option ID difference is too big. Please contact administration or the database admin."
return
for(var/optionid = id_min; optionid <= id_max; optionid++)
if(!isnull(href_list["o[optionid]"])) //Test if this optionid was replied to
var/rating
if(href_list["o[optionid]"] == "abstain")
rating = null
else
rating = text2num(href_list["o[optionid]"])
if(!isnum(rating))
return
vote_on_numval_poll(pollid, optionid, rating)
if("MULTICHOICE")
var/id_min = text2num(href_list["minoptionid"])
var/id_max = text2num(href_list["maxoptionid"])
if( (id_max - id_min) > 100 ) //Basic exploit prevention
usr << "The option ID difference is too big. Please contact administration or the database admin."
return
for(var/optionid = id_min; optionid <= id_max; optionid++)
if(!isnull(href_list["option_[optionid]"])) //Test if this optionid was selected
vote_on_poll(pollid, optionid, 1)
proc/IsJobAvailable(rank)
var/datum/job/job = job_master.GetJob(rank)
if(!job) return 0
if(!job.is_position_available()) return 0
if(jobban_isbanned(src,rank)) return 0
if(!job.player_old_enough(src.client)) return 0
if(href_list["show_preferences"])
client.prefs.ShowChoices(src)
return 1
if(href_list["ready"])
if(!ticker || ticker.current_state <= GAME_STATE_PREGAME) // Make sure we don't ready up after the round has started
ready = text2num(href_list["ready"])
else
ready = 0
if(href_list["refresh"])
src << browse(null, "window=playersetup") //closes the player setup window
new_player_panel_proc()
if(href_list["observe"])
if(alert(src,"Are you sure you wish to observe? You will have to wait 15 minutes before being able to respawn!","Player Setup","Yes","No") == "Yes")
if(!client) return 1
var/mob/observer/dead/observer = new()
spawning = 1
src << sound(null, repeat = 0, wait = 0, volume = 85, channel = 1) // MAD JAMS cant last forever yo
observer.started_as_observer = 1
close_spawn_windows()
var/obj/O = locate("landmark*Observer-Start")
if(istype(O))
src << "<span class='notice'>Now teleporting.</span>"
observer.loc = O.loc
else
src << "<span class='danger'>Could not locate an observer spawn point. Use the Teleport verb to jump to the station map.</span>"
observer.timeofdeath = world.time // Set the time of death so that the respawn timer works correctly.
announce_ghost_joinleave(src)
client.prefs.update_preview_icon()
observer.icon = client.prefs.preview_icon
observer.alpha = 127
if(client.prefs.be_random_name)
client.prefs.real_name = random_name(client.prefs.gender)
observer.real_name = client.prefs.real_name
observer.name = observer.real_name
if(!client.holder && !config.antag_hud_allowed) // For new ghosts we remove the verb from even showing up if it's not allowed.
observer.verbs -= /mob/observer/dead/verb/toggle_antagHUD // Poor guys, don't know what they are missing!
observer.key = key
qdel(src)
return 1
if(href_list["late_join"])
proc/AttemptLateSpawn(rank,var/spawning_at)
if (src != usr)
return 0
if(!ticker || ticker.current_state != GAME_STATE_PLAYING)
usr << "\red The round is either not ready, or has already finished..."
return 0
if(!config.enter_allowed)
usr << "<span class='notice'>There is an administrative lock on entering the game!</span>"
return 0
if(!IsJobAvailable(rank))
src << alert("[rank] is not available. Please try another.")
return 0
spawning = 1
close_spawn_windows()
job_master.AssignRole(src, rank, 1)
var/mob/living/character = create_character() //creates the human and transfers vars and mind
character = job_master.EquipRank(character, rank, 1) //equips the human
UpdateFactionList(character)
equip_custom_items(character)
// AIs don't need a spawnpoint, they must spawn at an empty core
if(character.mind.assigned_role == "AI")
character = character.AIize(move=0) // AIize the character, but don't move them yet
// IsJobAvailable for AI checks that there is an empty core available in this list
var/obj/structure/AIcore/deactivated/C = empty_playable_ai_cores[1]
empty_playable_ai_cores -= C
character.loc = C.loc
AnnounceCyborg(character, rank, "has been downloaded to the empty core in \the [character.loc.loc]")
ticker.mode.latespawn(character)
qdel(C)
qdel(src)
return
//Find our spawning point.
var/join_message = job_master.LateSpawn(character, rank)
if(client.prefs.species != "Human" && !check_rights(R_ADMIN, 0))
if(!is_alien_whitelisted(src, client.prefs.species) && config.usealienwhitelist)
src << alert("You are currently not whitelisted to play [client.prefs.species].")
return 0
character.lastarea = get_area(loc)
// Moving wheelchair if they have one
if(character.buckled && istype(character.buckled, /obj/structure/bed/chair/wheelchair))
character.buckled.loc = character.loc
character.buckled.set_dir(character.dir)
var/datum/species/S = all_species[client.prefs.species]
if(!(S.spawn_flags & IS_WHITELISTED))
src << alert("Your current species,[client.prefs.species], is not available for play on the station.")
return 0
ticker.mode.latespawn(character)
LateChoices()
if(character.mind.assigned_role != "Cyborg")
data_core.manifest_inject(character)
ticker.minds += character.mind//Cyborgs and AIs handle this in the transform proc. //TODO!!!!! ~Carn
if(href_list["manifest"])
ViewManifest()
//Grab some data from the character prefs for use in random news procs.
if(href_list["SelectedJob"])
AnnounceArrival(character, rank, join_message)
else
AnnounceCyborg(character, rank, join_message)
if(!config.enter_allowed)
usr << "<span class='notice'>There is an administrative lock on entering the game!</span>"
return
else if(ticker && ticker.mode && ticker.mode.explosion_in_progress)
usr << "<span class='danger'>The station is currently exploding. Joining would go poorly.</span>"
return
qdel(src)
if(client.prefs.species != "Human")
if(!is_alien_whitelisted(src, client.prefs.species) && config.usealienwhitelist)
src << alert("You are currently not whitelisted to play [client.prefs.species].")
return 0
proc/AnnounceCyborg(var/mob/living/character, var/rank, var/join_message)
if (ticker.current_state == GAME_STATE_PLAYING)
if(character.mind.role_alt_title)
rank = character.mind.role_alt_title
// can't use their name here, since cyborg namepicking is done post-spawn, so we'll just say "A new Cyborg has arrived"/"A new Android has arrived"/etc.
global_announcer.autosay("A new[rank ? " [rank]" : " visitor" ] [join_message ? join_message : "has arrived on the station"].", "Arrivals Announcement Computer")
var/datum/species/S = all_species[client.prefs.species]
if(!(S.spawn_flags & CAN_JOIN))
src << alert("Your current species, [client.prefs.species], is not available for play on the station.")
return 0
proc/LateChoices()
var/name = client.prefs.be_random_name ? "friend" : client.prefs.real_name
AttemptLateSpawn(href_list["SelectedJob"],client.prefs.spawnpoint)
return
var/dat = "<html><body><center>"
dat += "<b>Welcome, [name].<br></b>"
dat += "Round Duration: [round_duration()]<br>"
if(href_list["privacy_poll"])
establish_db_connection()
if(!dbcon.IsConnected())
return
var/voted = 0
if(emergency_shuttle) //In case Nanotrasen decides reposess CentComm's shuttles.
if(emergency_shuttle.going_to_centcom()) //Shuttle is going to centcomm, not recalled
dat += "<font color='red'><b>The station has been evacuated.</b></font><br>"
if(emergency_shuttle.online())
if (emergency_shuttle.evac) // Emergency shuttle is past the point of no recall
dat += "<font color='red'>The station is currently undergoing evacuation procedures.</font><br>"
else // Crew transfer initiated
dat += "<font color='red'>The station is currently undergoing crew transfer procedures.</font><br>"
//First check if the person has not voted yet.
var/DBQuery/query = dbcon.NewQuery("SELECT * FROM erro_privacy WHERE ckey='[src.ckey]'")
query.Execute()
while(query.NextRow())
voted = 1
break
dat += "Choose from the following open/valid positions:<br>"
for(var/datum/job/job in job_master.occupations)
if(job && IsJobAvailable(job.title))
if(job.minimum_character_age && (client.prefs.age < job.minimum_character_age))
continue
var/active = 0
// Only players with the job assigned and AFK for less than 10 minutes count as active
for(var/mob/M in player_list) if(M.mind && M.client && M.mind.assigned_role == job.title && M.client.inactivity <= 10 * 60 * 10)
active++
dat += "<a href='byond://?src=\ref[src];SelectedJob=[job.title]'>[job.title] ([job.current_positions]) (Active: [active])</a><br>"
//This is a safety switch, so only valid options pass through
var/option = "UNKNOWN"
switch(href_list["privacy_poll"])
if("signed")
option = "SIGNED"
if("anonymous")
option = "ANONYMOUS"
if("nostats")
option = "NOSTATS"
if("later")
usr << browse(null,"window=privacypoll")
return
if("abstain")
option = "ABSTAIN"
dat += "</center>"
src << browse(dat, "window=latechoices;size=300x640;can_close=1")
if(option == "UNKNOWN")
return
if(!voted)
var/sql = "INSERT INTO erro_privacy VALUES (null, Now(), '[src.ckey]', '[option]')"
var/DBQuery/query_insert = dbcon.NewQuery(sql)
query_insert.Execute()
usr << "<b>Thank you for your vote!</b>"
usr << browse(null,"window=privacypoll")
if(!ready && href_list["preference"])
if(client)
client.prefs.process_link(src, href_list)
else if(!href_list["late_join"])
new_player_panel()
if(href_list["showpoll"])
handle_player_polling()
return
if(href_list["pollid"])
var/pollid = href_list["pollid"]
if(istext(pollid))
pollid = text2num(pollid)
if(isnum(pollid))
src.poll_player(pollid)
return
if(href_list["votepollid"] && href_list["votetype"])
var/pollid = text2num(href_list["votepollid"])
var/votetype = href_list["votetype"]
switch(votetype)
if("OPTION")
var/optionid = text2num(href_list["voteoptionid"])
vote_on_poll(pollid, optionid)
if("TEXT")
var/replytext = href_list["replytext"]
log_text_poll_reply(pollid, replytext)
if("NUMVAL")
var/id_min = text2num(href_list["minid"])
var/id_max = text2num(href_list["maxid"])
if( (id_max - id_min) > 100 ) //Basic exploit prevention
usr << "The option ID difference is too big. Please contact administration or the database admin."
return
for(var/optionid = id_min; optionid <= id_max; optionid++)
if(!isnull(href_list["o[optionid]"])) //Test if this optionid was replied to
var/rating
if(href_list["o[optionid]"] == "abstain")
rating = null
else
rating = text2num(href_list["o[optionid]"])
if(!isnum(rating))
return
vote_on_numval_poll(pollid, optionid, rating)
if("MULTICHOICE")
var/id_min = text2num(href_list["minoptionid"])
var/id_max = text2num(href_list["maxoptionid"])
if( (id_max - id_min) > 100 ) //Basic exploit prevention
usr << "The option ID difference is too big. Please contact administration or the database admin."
return
for(var/optionid = id_min; optionid <= id_max; optionid++)
if(!isnull(href_list["option_[optionid]"])) //Test if this optionid was selected
vote_on_poll(pollid, optionid, 1)
/mob/new_player/proc/IsJobAvailable(rank)
var/datum/job/job = job_master.GetJob(rank)
if(!job) return 0
if(!job.is_position_available()) return 0
if(jobban_isbanned(src,rank)) return 0
if(!job.player_old_enough(src.client)) return 0
return 1
proc/create_character()
spawning = 1
close_spawn_windows()
var/mob/living/carbon/human/new_character
var/use_species_name
var/datum/species/chosen_species
if(client.prefs.species)
chosen_species = all_species[client.prefs.species]
use_species_name = chosen_species.get_station_variant() //Only used by pariahs atm.
if(chosen_species && use_species_name)
// Have to recheck admin due to no usr at roundstart. Latejoins are fine though.
if(is_species_whitelisted(chosen_species) || has_admin_rights())
new_character = new(loc, use_species_name)
if(!new_character)
new_character = new(loc)
new_character.lastarea = get_area(loc)
for(var/lang in client.prefs.alternate_languages)
var/datum/language/chosen_language = all_languages[lang]
if(chosen_language)
if(!config.usealienwhitelist || !(chosen_language.flags & WHITELISTED) || is_alien_whitelisted(src, lang) || has_admin_rights() \
|| (new_character.species && (chosen_language.name in new_character.species.secondary_langs)))
new_character.add_language(lang)
if(ticker.random_players)
new_character.gender = pick(MALE, FEMALE)
client.prefs.real_name = random_name(new_character.gender)
client.prefs.randomize_appearance_for(new_character)
else
client.prefs.copy_to(new_character)
src << sound(null, repeat = 0, wait = 0, volume = 85, channel = 1) // MAD JAMS cant last forever yo
if(mind)
mind.active = 0 //we wish to transfer the key manually
if(mind.assigned_role == "Clown") //give them a clownname if they are a clown
new_character.real_name = pick(clown_names) //I hate this being here of all places but unfortunately dna is based on real_name!
new_character.rename_self("clown")
mind.original = new_character
mind.transfer_to(new_character) //won't transfer key since the mind is not active
new_character.name = real_name
new_character.dna.ready_dna(new_character)
new_character.dna.b_type = client.prefs.b_type
new_character.sync_organ_dna()
if(client.prefs.disabilities)
// Set defer to 1 if you add more crap here so it only recalculates struc_enzymes once. - N3X
new_character.dna.SetSEState(GLASSESBLOCK,1,0)
new_character.disabilities |= NEARSIGHTED
// And uncomment this, too.
//new_character.dna.UpdateSE()
// Do the initial caching of the player's body icons.
new_character.force_update_limbs()
new_character.update_eyes()
new_character.regenerate_icons()
new_character.key = key //Manually transfer the key to log them in
return new_character
proc/ViewManifest()
var/dat = "<html><body>"
dat += "<h4>Show Crew Manifest</h4>"
dat += data_core.get_manifest(OOC = 1)
src << browse(dat, "window=manifest;size=370x420;can_close=1")
Move()
/mob/new_player/proc/AttemptLateSpawn(rank,var/spawning_at)
if (src != usr)
return 0
if(!ticker || ticker.current_state != GAME_STATE_PLAYING)
usr << "\red The round is either not ready, or has already finished..."
return 0
if(!config.enter_allowed)
usr << "<span class='notice'>There is an administrative lock on entering the game!</span>"
return 0
if(!IsJobAvailable(rank))
src << alert("[rank] is not available. Please try another.")
return 0
proc/close_spawn_windows()
src << browse(null, "window=latechoices") //closes late choices window
src << browse(null, "window=playersetup") //closes the player setup window
spawning = 1
close_spawn_windows()
proc/has_admin_rights()
return check_rights(R_ADMIN, 0, src)
job_master.AssignRole(src, rank, 1)
proc/is_species_whitelisted(datum/species/S)
if(!S) return 1
return is_alien_whitelisted(src, S.name) || !config.usealienwhitelist || !(S.spawn_flags & IS_WHITELISTED)
var/mob/living/character = create_character() //creates the human and transfers vars and mind
character = job_master.EquipRank(character, rank, 1) //equips the human
UpdateFactionList(character)
equip_custom_items(character)
// AIs don't need a spawnpoint, they must spawn at an empty core
if(character.mind.assigned_role == "AI")
character = character.AIize(move=0) // AIize the character, but don't move them yet
// IsJobAvailable for AI checks that there is an empty core available in this list
var/obj/structure/AIcore/deactivated/C = empty_playable_ai_cores[1]
empty_playable_ai_cores -= C
character.loc = C.loc
AnnounceCyborg(character, rank, "has been downloaded to the empty core in \the [character.loc.loc]")
ticker.mode.latespawn(character)
qdel(C)
qdel(src)
return
//Find our spawning point.
var/join_message = job_master.LateSpawn(character, rank)
character.lastarea = get_area(loc)
// Moving wheelchair if they have one
if(character.buckled && istype(character.buckled, /obj/structure/bed/chair/wheelchair))
character.buckled.loc = character.loc
character.buckled.set_dir(character.dir)
ticker.mode.latespawn(character)
if(character.mind.assigned_role != "Cyborg")
data_core.manifest_inject(character)
ticker.minds += character.mind//Cyborgs and AIs handle this in the transform proc. //TODO!!!!! ~Carn
//Grab some data from the character prefs for use in random news procs.
AnnounceArrival(character, rank, join_message)
else
AnnounceCyborg(character, rank, join_message)
qdel(src)
/mob/new_player/proc/AnnounceCyborg(var/mob/living/character, var/rank, var/join_message)
if (ticker.current_state == GAME_STATE_PLAYING)
if(character.mind.role_alt_title)
rank = character.mind.role_alt_title
// can't use their name here, since cyborg namepicking is done post-spawn, so we'll just say "A new Cyborg has arrived"/"A new Android has arrived"/etc.
global_announcer.autosay("A new[rank ? " [rank]" : " visitor" ] [join_message ? join_message : "has arrived on the station"].", "Arrivals Announcement Computer")
/mob/new_player/proc/LateChoices()
var/name = client.prefs.be_random_name ? "friend" : client.prefs.real_name
var/dat = "<html><body><center>"
dat += "<b>Welcome, [name].<br></b>"
dat += "Round Duration: [round_duration()]<br>"
if(emergency_shuttle) //In case Nanotrasen decides reposess CentComm's shuttles.
if(emergency_shuttle.going_to_centcom()) //Shuttle is going to centcomm, not recalled
dat += "<font color='red'><b>The station has been evacuated.</b></font><br>"
if(emergency_shuttle.online())
if (emergency_shuttle.evac) // Emergency shuttle is past the point of no recall
dat += "<font color='red'>The station is currently undergoing evacuation procedures.</font><br>"
else // Crew transfer initiated
dat += "<font color='red'>The station is currently undergoing crew transfer procedures.</font><br>"
dat += "Choose from the following open/valid positions:<br>"
for(var/datum/job/job in job_master.occupations)
if(job && IsJobAvailable(job.title))
if(job.minimum_character_age && (client.prefs.age < job.minimum_character_age))
continue
var/active = 0
// Only players with the job assigned and AFK for less than 10 minutes count as active
for(var/mob/M in player_list) if(M.mind && M.client && M.mind.assigned_role == job.title && M.client.inactivity <= 10 * 60 * 10)
active++
dat += "<a href='byond://?src=\ref[src];SelectedJob=[job.title]'>[job.title] ([job.current_positions]) (Active: [active])</a><br>"
dat += "</center>"
src << browse(dat, "window=latechoices;size=300x640;can_close=1")
/mob/new_player/proc/create_character()
spawning = 1
close_spawn_windows()
var/mob/living/carbon/human/new_character
var/use_species_name
var/datum/species/chosen_species
if(client.prefs.species)
chosen_species = all_species[client.prefs.species]
use_species_name = chosen_species.get_station_variant() //Only used by pariahs atm.
if(chosen_species && use_species_name)
// Have to recheck admin due to no usr at roundstart. Latejoins are fine though.
if(is_species_whitelisted(chosen_species) || has_admin_rights())
new_character = new(loc, use_species_name)
if(!new_character)
new_character = new(loc)
new_character.lastarea = get_area(loc)
for(var/lang in client.prefs.alternate_languages)
var/datum/language/chosen_language = all_languages[lang]
if(chosen_language)
if(!config.usealienwhitelist || !(chosen_language.flags & WHITELISTED) || is_alien_whitelisted(src, lang) || has_admin_rights() \
|| (new_character.species && (chosen_language.name in new_character.species.secondary_langs)))
new_character.add_language(lang)
if(ticker.random_players)
new_character.gender = pick(MALE, FEMALE)
client.prefs.real_name = random_name(new_character.gender)
client.prefs.randomize_appearance_for(new_character)
else
client.prefs.copy_to(new_character)
src << sound(null, repeat = 0, wait = 0, volume = 85, channel = 1) // MAD JAMS cant last forever yo
if(mind)
mind.active = 0 //we wish to transfer the key manually
if(mind.assigned_role == "Clown") //give them a clownname if they are a clown
new_character.real_name = pick(clown_names) //I hate this being here of all places but unfortunately dna is based on real_name!
new_character.rename_self("clown")
mind.original = new_character
mind.transfer_to(new_character) //won't transfer key since the mind is not active
new_character.name = real_name
new_character.dna.ready_dna(new_character)
new_character.dna.b_type = client.prefs.b_type
new_character.sync_organ_dna()
if(client.prefs.disabilities)
// Set defer to 1 if you add more crap here so it only recalculates struc_enzymes once. - N3X
new_character.dna.SetSEState(GLASSESBLOCK,1,0)
new_character.disabilities |= NEARSIGHTED
// And uncomment this, too.
//new_character.dna.UpdateSE()
// Do the initial caching of the player's body icons.
new_character.force_update_limbs()
new_character.update_eyes()
new_character.regenerate_icons()
new_character.key = key //Manually transfer the key to log them in
return new_character
/mob/new_player/proc/ViewManifest()
var/dat = "<html><body>"
dat += "<h4>Show Crew Manifest</h4>"
dat += data_core.get_manifest(OOC = 1)
src << browse(dat, "window=manifest;size=370x420;can_close=1")
/mob/new_player/Move()
return 0
/mob/new_player/proc/close_spawn_windows()
src << browse(null, "window=latechoices") //closes late choices window
src << browse(null, "window=playersetup") //closes the player setup window
/mob/new_player/proc/has_admin_rights()
return check_rights(R_ADMIN, 0, src)
/mob/new_player/proc/is_species_whitelisted(datum/species/S)
if(!S) return 1
return is_alien_whitelisted(src, S.name) || !config.usealienwhitelist || !(S.spawn_flags & IS_WHITELISTED)
/mob/new_player/get_species()
var/datum/species/chosen_species
@@ -504,5 +504,5 @@
/mob/new_player/hear_radio(var/message, var/verb="says", var/datum/language/language=null, var/part_a, var/part_b, var/mob/speaker = null, var/hard_to_hear = 0)
return
mob/new_player/MayRespawn()
/mob/new_player/MayRespawn()
return 1

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More