mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-07-20 20:45:28 +01:00
Merge conflic fix
This commit is contained in:
@@ -145,8 +145,8 @@ var/global/BSACooldown = 0
|
||||
body += "<A href='?_src_=holder;simplemake=coffee;mob=\ref[M]'>Coffee</A> | "
|
||||
//body += "<A href='?_src_=holder;simplemake=parrot;mob=\ref[M]'>Parrot</A> | "
|
||||
//body += "<A href='?_src_=holder;simplemake=polyparrot;mob=\ref[M]'>Poly</A> | "
|
||||
body += "\[ Construct: <A href='?_src_=holder;simplemake=constructarmored;mob=\ref[M]'>Armored</A> , "
|
||||
body += "<A href='?_src_=holder;simplemake=constructbuilder;mob=\ref[M]'>Builder</A> , "
|
||||
body += "\[ Construct: <A href='?_src_=holder;simplemake=constructarmored;mob=\ref[M]'>Juggernaut</A> , "
|
||||
body += "<A href='?_src_=holder;simplemake=constructbuilder;mob=\ref[M]'>Artificer</A> , "
|
||||
body += "<A href='?_src_=holder;simplemake=constructwraith;mob=\ref[M]'>Wraith</A> \] "
|
||||
body += "<A href='?_src_=holder;simplemake=shade;mob=\ref[M]'>Shade</A>"
|
||||
body += "<br>"
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
message_admins("[key_name_admin(usr)] tried to create changelings. Unfortunately, there were no candidates available.")
|
||||
log_admin("[key_name(usr)] failed to create changelings.")
|
||||
if("3")
|
||||
if(!src.makeRevs())
|
||||
if(src.makeRevs())
|
||||
message_admins("[key_name(usr)] started a revolution.")
|
||||
log_admin("[key_name(usr)] started a revolution.")
|
||||
else
|
||||
|
||||
@@ -71,6 +71,11 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
|
||||
if(targetselected && !hascall(target,procname))
|
||||
usr << "<font color='red'>Error: callproc(): target has no such call [procname].</font>"
|
||||
return
|
||||
else
|
||||
var/procpath = text2path(procname)
|
||||
if (!procpath)
|
||||
usr << "<font color='red'>Error: callproc(): proc [procname] does not exist. (Did you forget the /proc/ part?)</font>"
|
||||
return
|
||||
var/list/lst = get_callproc_args()
|
||||
if(!lst)
|
||||
return
|
||||
|
||||
@@ -114,12 +114,14 @@
|
||||
for(var/mob/living/carbon/human/applicant in player_list)
|
||||
if(ROLE_REV in applicant.client.prefs.be_special)
|
||||
if(applicant.stat == CONSCIOUS)
|
||||
if(applicant.mind)
|
||||
if(!applicant.mind.special_role)
|
||||
if(!jobban_isbanned(applicant, ROLE_REV) && !jobban_isbanned(applicant, "Syndicate"))
|
||||
if(temp.age_check(applicant.client))
|
||||
if(!(applicant.job in temp.restricted_jobs))
|
||||
candidates += applicant
|
||||
var/turf/T = get_turf(applicant)
|
||||
if(T.z == ZLEVEL_STATION)
|
||||
if(applicant.mind)
|
||||
if(!applicant.mind.special_role)
|
||||
if(!jobban_isbanned(applicant, ROLE_REV) && !jobban_isbanned(applicant, "Syndicate"))
|
||||
if(temp.age_check(applicant.client))
|
||||
if(!(applicant.job in temp.restricted_jobs))
|
||||
candidates += applicant
|
||||
|
||||
if(candidates.len)
|
||||
var/numRevs = min(candidates.len, 3)
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
var/death = TRUE
|
||||
var/flavour_text = "The mapper forgot to set this!"
|
||||
var/faction = null
|
||||
var/list/implants = list()
|
||||
density = 1
|
||||
|
||||
/obj/effect/landmark/corpse/initialize()
|
||||
@@ -105,6 +106,11 @@
|
||||
W.registered_name = M.real_name
|
||||
W.update_label()
|
||||
M.equip_to_slot_or_del(W, slot_wear_id)
|
||||
|
||||
for(var/I in implants)
|
||||
var/obj/item/weapon/implant/X = new I
|
||||
X.implant(M)
|
||||
|
||||
if(ckey)
|
||||
M.ckey = ckey
|
||||
M << "[flavour_text]"
|
||||
@@ -270,7 +276,7 @@
|
||||
|
||||
|
||||
|
||||
/////////////////Officers//////////////////////
|
||||
/////////////////Officers+Nanotrasen Security//////////////////////
|
||||
|
||||
/obj/effect/landmark/corpse/bridgeofficer
|
||||
name = "Bridge Officer"
|
||||
@@ -298,6 +304,21 @@
|
||||
corpseidjob = "Commander"
|
||||
corpseidaccess = "Captain"
|
||||
|
||||
/obj/effect/landmark/corpse/nanotrasensoldier
|
||||
name = "Nanotrasen Private Security Officer"
|
||||
corpseuniform = /obj/item/clothing/under/rank/security
|
||||
corpsesuit = /obj/item/clothing/suit/armor/vest
|
||||
corpseshoes = /obj/item/clothing/shoes/combat
|
||||
corpsegloves = /obj/item/clothing/gloves/combat
|
||||
corpseradio = /obj/item/device/radio/headset
|
||||
corpsemask = /obj/item/clothing/mask/gas/sechailer/swat
|
||||
corpsehelmet = /obj/item/clothing/head/helmet/swat/nanotrasen
|
||||
corpseback = /obj/item/weapon/storage/backpack/security
|
||||
corpseid = 1
|
||||
corpseidjob = "Private Security Force"
|
||||
corpseidaccess = "Security Officer"
|
||||
|
||||
|
||||
/obj/effect/landmark/corpse/commander/alive
|
||||
death = FALSE
|
||||
roundstart = FALSE
|
||||
@@ -350,4 +371,4 @@
|
||||
mobname = "???"
|
||||
mob_species = /datum/species/abductor
|
||||
corpseuniform = /obj/item/clothing/under/color/grey
|
||||
corpseshoes = /obj/item/clothing/shoes/combat
|
||||
corpseshoes = /obj/item/clothing/shoes/combat
|
||||
|
||||
@@ -1,31 +1,31 @@
|
||||
//Academy Areas
|
||||
|
||||
/area/awaymission/academy
|
||||
name = "\improper Academy Asteroids"
|
||||
name = "Academy Asteroids"
|
||||
icon_state = "away"
|
||||
|
||||
/area/awaymission/academy/headmaster
|
||||
name = "\improper Academy Fore Block"
|
||||
name = "Academy Fore Block"
|
||||
icon_state = "away1"
|
||||
|
||||
/area/awaymission/academy/classrooms
|
||||
name = "\improper Academy Classroom Block"
|
||||
name = "Academy Classroom Block"
|
||||
icon_state = "away2"
|
||||
|
||||
/area/awaymission/academy/academyaft
|
||||
name = "\improper Academy Ship Aft Block"
|
||||
name = "Academy Ship Aft Block"
|
||||
icon_state = "away3"
|
||||
|
||||
/area/awaymission/academy/academygate
|
||||
name = "\improper Academy Gateway"
|
||||
name = "Academy Gateway"
|
||||
icon_state = "away4"
|
||||
|
||||
/area/awaymission/academy/academycellar
|
||||
name = "\improper Academy Cellar"
|
||||
name = "Academy Cellar"
|
||||
icon_state = "away4"
|
||||
|
||||
/area/awaymission/academy/academyengine
|
||||
name = "\improper Academy Engine"
|
||||
name = "Academy Engine"
|
||||
icon_state = "away4"
|
||||
|
||||
//Academy Items
|
||||
@@ -102,7 +102,7 @@
|
||||
|
||||
/obj/structure/academy_wizard_spawner/proc/summon_wizard()
|
||||
var/turf/T = src.loc
|
||||
|
||||
|
||||
var/mob/living/carbon/human/wizbody = new(T)
|
||||
wizbody.equipOutfit(/datum/outfit/wizard/academy)
|
||||
var/obj/item/weapon/implant/exile/Implant = new/obj/item/weapon/implant/exile(wizbody)
|
||||
@@ -110,7 +110,7 @@
|
||||
wizbody.faction |= "wizard"
|
||||
wizbody.real_name = "Academy Teacher"
|
||||
wizbody.name = "Academy Teacher"
|
||||
|
||||
|
||||
var/datum/mind/wizmind = new /datum/mind()
|
||||
wizmind.name = "Wizard Defender"
|
||||
wizmind.special_role = "Academy Defender"
|
||||
@@ -118,13 +118,13 @@
|
||||
wizmind.objectives += O
|
||||
wizmind.transfer_to(wizbody)
|
||||
ticker.mode.wizards |= wizmind
|
||||
|
||||
|
||||
wizmind.AddSpell(new /obj/effect/proc_holder/spell/targeted/ethereal_jaunt)
|
||||
wizmind.AddSpell(new /obj/effect/proc_holder/spell/targeted/projectile/magic_missile)
|
||||
wizmind.AddSpell(new /obj/effect/proc_holder/spell/dumbfire/fireball)
|
||||
|
||||
current_wizard = wizbody
|
||||
|
||||
|
||||
give_control()
|
||||
|
||||
/obj/structure/academy_wizard_spawner/proc/update_status()
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
//Packer Ship Areas
|
||||
|
||||
/area/awaymission/BMPship
|
||||
name = "\improper BMP Asteroids"
|
||||
name = "BMP Asteroids"
|
||||
icon_state = "away"
|
||||
luminosity = 0
|
||||
|
||||
|
||||
/area/awaymission/BMPship/Aft
|
||||
name = "\improper Aft Block"
|
||||
name = "Aft Block"
|
||||
icon_state = "away1"
|
||||
requires_power = 1
|
||||
|
||||
/area/awaymission/BMPship/Midship
|
||||
name = "\improper Midship Block"
|
||||
name = "Midship Block"
|
||||
icon_state = "away2"
|
||||
requires_power = 1
|
||||
|
||||
/area/awaymission/BMPship/Fore
|
||||
name = "\improper Fore Block"
|
||||
name = "Fore Block"
|
||||
icon_state = "away3"
|
||||
requires_power = 1
|
||||
@@ -5,7 +5,7 @@
|
||||
icon_state = "away"
|
||||
|
||||
/area/awaymission/challenge/main
|
||||
name = "\improper Danger Room"
|
||||
name = "Danger Room"
|
||||
icon_state = "away1"
|
||||
requires_power = 0
|
||||
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
//Research Base Areas//--
|
||||
|
||||
/area/awaymission/research
|
||||
name = "Research Outpost"
|
||||
icon_state = "away"
|
||||
luminosity = 0
|
||||
lighting_use_dynamic = DYNAMIC_LIGHTING_ENABLED
|
||||
|
||||
/area/awaymission/research/interior
|
||||
name = "Research Inside"
|
||||
requires_power = 1
|
||||
icon_state = "away2"
|
||||
|
||||
/area/awaymission/research/interior/cryo
|
||||
name = "Research Cryostasis Room"
|
||||
icon_state = "medbay"
|
||||
|
||||
/area/awaymission/research/interior/clonestorage
|
||||
name = "Research Clone Storage"
|
||||
icon_state = "cloning"
|
||||
|
||||
/area/awaymission/research/interior/genetics
|
||||
name = "Research Genetics Research"
|
||||
icon_state = "genetics"
|
||||
|
||||
/area/awaymission/research/interior/engineering
|
||||
name = "Research Engineering"
|
||||
icon_state = "engine"
|
||||
|
||||
/area/awaymission/research/interior/security
|
||||
name = "Research Security"
|
||||
icon_state = "security"
|
||||
|
||||
/area/awaymission/research/interior/secure
|
||||
name = "Research Secure Vault"
|
||||
|
||||
/area/awaymission/research/interior/maint
|
||||
name = "Research Maintenance"
|
||||
icon_state = "maintcentral"
|
||||
|
||||
/area/awaymission/research/interior/dorm
|
||||
name = "Research Dorms"
|
||||
icon_state = "Sleep"
|
||||
|
||||
/area/awaymission/research/interior/escapepods
|
||||
name = "Research Escape Wing"
|
||||
icon_state = "exit"
|
||||
|
||||
/area/awaymission/research/interior/gateway
|
||||
name = "Research Gateway"
|
||||
icon_state = "start"
|
||||
|
||||
/area/awaymission/research/interior/bathroom
|
||||
name = "Research Bathrooms"
|
||||
icon_state = "restrooms"
|
||||
|
||||
/area/awaymission/research/interior/medbay
|
||||
name = "Research Medbay"
|
||||
icon_state = "medbay"
|
||||
|
||||
/area/awaymission/research/exterior
|
||||
name = "Research Exterior"
|
||||
icon_state = "unknown"
|
||||
|
||||
@@ -1,37 +1,37 @@
|
||||
//Snow Valley Areas//--
|
||||
|
||||
/area/awaymission/snowdin
|
||||
name = "\improper Snowdin Tundra Plains"
|
||||
name = "Snowdin Tundra Plains"
|
||||
icon_state = "away"
|
||||
requires_power = 0
|
||||
luminosity = 1
|
||||
lighting_use_dynamic = DYNAMIC_LIGHTING_ENABLED
|
||||
|
||||
/area/awaymission/snowdin/post
|
||||
name = "\improper Snowdin Outpost"
|
||||
name = "Snowdin Outpost"
|
||||
requires_power = 1
|
||||
|
||||
/area/awaymission/snowdin/igloo
|
||||
name = "\improper Snowdin Igloos"
|
||||
name = "Snowdin Igloos"
|
||||
icon_state = "away2"
|
||||
|
||||
/area/awaymission/snowdin/cave
|
||||
name = "\improper Snowdin Caves"
|
||||
name = "Snowdin Caves"
|
||||
icon_state = "away2"
|
||||
luminosity = 0
|
||||
|
||||
/area/awaymission/snowdin/base
|
||||
name = "\improper Snowdin Main Base"
|
||||
name = "Snowdin Main Base"
|
||||
icon_state = "away3"
|
||||
requires_power = 1
|
||||
|
||||
/area/awaymission/snowdin/dungeon1
|
||||
name = "\improper Snowdin Depths"
|
||||
name = "Snowdin Depths"
|
||||
icon_state = "away2"
|
||||
luminosity = 0
|
||||
|
||||
/area/awaymission/snowdin/sekret
|
||||
name = "\improper Snowdin Operations"
|
||||
name = "Snowdin Operations"
|
||||
icon_state = "away3"
|
||||
requires_power = 1
|
||||
|
||||
@@ -237,6 +237,7 @@ obj/item/weapon/paper/crumpled/snowdin/shovel
|
||||
icon_state = "sleeper"
|
||||
roundstart = FALSE
|
||||
death = FALSE
|
||||
implants = list(/obj/item/weapon/implant/exile)
|
||||
faction = "syndicate"
|
||||
flavour_text = {"You are a syndicate operative recently awoken from cyrostatis in an underground outpost. Monitor Nanotrasen communications and record infomation. All intruders should be
|
||||
disposed of swirfly to assure no gathered infomation is stolen or lost. Try not to wander too far from the outpost as the caves can be a deadly place even for a trained operative such as yourself."}
|
||||
|
||||
@@ -1,33 +1,33 @@
|
||||
//Spacebattle Areas
|
||||
|
||||
/area/awaymission/spacebattle
|
||||
name = "\improper Space Battle"
|
||||
name = "Space Battle"
|
||||
icon_state = "away"
|
||||
requires_power = 0
|
||||
|
||||
/area/awaymission/spacebattle/cruiser
|
||||
name = "\improper Nanotrasen Cruiser"
|
||||
name = "Nanotrasen Cruiser"
|
||||
|
||||
/area/awaymission/spacebattle/syndicate1
|
||||
name = "\improper Syndicate Assault Ship 1"
|
||||
name = "Syndicate Assault Ship 1"
|
||||
|
||||
/area/awaymission/spacebattle/syndicate2
|
||||
name = "\improper Syndicate Assault Ship 2"
|
||||
name = "Syndicate Assault Ship 2"
|
||||
|
||||
/area/awaymission/spacebattle/syndicate3
|
||||
name = "\improper Syndicate Assault Ship 3"
|
||||
name = "Syndicate Assault Ship 3"
|
||||
|
||||
/area/awaymission/spacebattle/syndicate4
|
||||
name = "\improper Syndicate War Sphere 1"
|
||||
name = "Syndicate War Sphere 1"
|
||||
|
||||
/area/awaymission/spacebattle/syndicate5
|
||||
name = "\improper Syndicate War Sphere 2"
|
||||
name = "Syndicate War Sphere 2"
|
||||
|
||||
/area/awaymission/spacebattle/syndicate6
|
||||
name = "\improper Syndicate War Sphere 3"
|
||||
name = "Syndicate War Sphere 3"
|
||||
|
||||
/area/awaymission/spacebattle/syndicate7
|
||||
name = "\improper Syndicate Fighter"
|
||||
name = "Syndicate Fighter"
|
||||
|
||||
/area/awaymission/spacebattle/secret
|
||||
name = "\improper Hidden Chamber"
|
||||
name = "Hidden Chamber"
|
||||
@@ -7,30 +7,30 @@
|
||||
//Wild West Areas
|
||||
|
||||
/area/awaymission/wwmines
|
||||
name = "\improper Wild West Mines"
|
||||
name = "Wild West Mines"
|
||||
icon_state = "away1"
|
||||
luminosity = 1
|
||||
requires_power = 0
|
||||
|
||||
/area/awaymission/wwgov
|
||||
name = "\improper Wild West Mansion"
|
||||
name = "Wild West Mansion"
|
||||
icon_state = "away2"
|
||||
luminosity = 1
|
||||
requires_power = 0
|
||||
|
||||
/area/awaymission/wwrefine
|
||||
name = "\improper Wild West Refinery"
|
||||
name = "Wild West Refinery"
|
||||
icon_state = "away3"
|
||||
luminosity = 1
|
||||
requires_power = 0
|
||||
|
||||
/area/awaymission/wwvault
|
||||
name = "\improper Wild West Vault"
|
||||
name = "Wild West Vault"
|
||||
icon_state = "away3"
|
||||
luminosity = 0
|
||||
|
||||
/area/awaymission/wwvaultdoors
|
||||
name = "\improper Wild West Vault Doors" // this is to keep the vault area being entirely lit because of requires_power
|
||||
name = "Wild West Vault Doors" // this is to keep the vault area being entirely lit because of requires_power
|
||||
icon_state = "away2"
|
||||
requires_power = 0
|
||||
luminosity = 0
|
||||
|
||||
@@ -22,6 +22,7 @@ var/global/list/potentialSpaceRuins = generateMapList(filename = "config/spaceRu
|
||||
var/file = file(map)
|
||||
if(isfile(file))
|
||||
maploader.load_map(file)
|
||||
smooth_zlevel(world.maxz)
|
||||
world.log << "away mission loaded: [map]"
|
||||
|
||||
map_transition_config.Add(AWAY_MISSION_LIST)
|
||||
@@ -66,7 +67,7 @@ var/global/list/potentialSpaceRuins = generateMapList(filename = "config/spaceRu
|
||||
|
||||
potentialMaps.Add(t)
|
||||
|
||||
return potentialMaps
|
||||
return potentialMaps
|
||||
|
||||
|
||||
/proc/seedRuins(z_level = 1, ruin_number = 0, whitelist = /area/space, list/potentialRuins = potentialSpaceRuins)
|
||||
|
||||
@@ -173,10 +173,10 @@ You can set verify to TRUE if you want send() to sleep until the client has the
|
||||
//DEFINITIONS FOR ASSET DATUMS START HERE.
|
||||
|
||||
|
||||
/datum/asset/simple/nanoui
|
||||
/datum/asset/simple/tgui
|
||||
assets = list(
|
||||
"nanoui.css" = 'nano/assets/nanoui.css',
|
||||
"nanoui.js" = 'nano/assets/nanoui.js'
|
||||
"tgui.css" = 'tgui/assets/tgui.css',
|
||||
"tgui.js" = 'tgui/assets/tgui.js'
|
||||
)
|
||||
|
||||
/datum/asset/simple/pda
|
||||
|
||||
@@ -27,7 +27,8 @@ var/list/preferences_datums = list()
|
||||
|
||||
|
||||
var/UI_style = "Midnight"
|
||||
var/nanoui_fancy = TRUE
|
||||
var/tgui_fancy = TRUE
|
||||
var/tgui_lock = TRUE
|
||||
var/toggles = TOGGLES_DEFAULT
|
||||
var/chat_toggles = TOGGLES_DEFAULT_CHAT
|
||||
var/ghost_form = "ghost"
|
||||
@@ -325,7 +326,8 @@ var/list/preferences_datums = list()
|
||||
dat += "<table><tr><td width='340px' height='300px' valign='top'>"
|
||||
dat += "<h2>General Settings</h2>"
|
||||
dat += "<b>UI Style:</b> <a href='?_src_=prefs;preference=ui'>[UI_style]</a><br>"
|
||||
dat += "<b>Fancy NanoUI:</b> <a href='?_src_=prefs;preference=nanoui'>[(nanoui_fancy) ? "Yes" : "No"]</a><br>"
|
||||
dat += "<b>tgui Style:</b> <a href='?_src_=prefs;preference=tgui_fancy'>[(tgui_fancy) ? "Fancy" : "No Frills"]</a><br>"
|
||||
dat += "<b>tgui Monitors:</b> <a href='?_src_=prefs;preference=tgui_lock'>[(tgui_lock) ? "Primary" : "All"]</a><br>"
|
||||
dat += "<b>Play admin midis:</b> <a href='?_src_=prefs;preference=hear_midis'>[(toggles & SOUND_MIDI) ? "Yes" : "No"]</a><br>"
|
||||
dat += "<b>Play lobby music:</b> <a href='?_src_=prefs;preference=lobby_music'>[(toggles & SOUND_LOBBY) ? "Yes" : "No"]</a><br>"
|
||||
dat += "<b>Ghost ears:</b> <a href='?_src_=prefs;preference=ghost_ears'>[(chat_toggles & CHAT_GHOSTEARS) ? "All Speech" : "Nearest Creatures"]</a><br>"
|
||||
@@ -1011,8 +1013,10 @@ var/list/preferences_datums = list()
|
||||
else
|
||||
UI_style = "Midnight"
|
||||
|
||||
if("nanoui")
|
||||
nanoui_fancy = !nanoui_fancy
|
||||
if("tgui_fancy")
|
||||
tgui_fancy = !tgui_fancy
|
||||
if("tgui_lock")
|
||||
tgui_lock = !tgui_lock
|
||||
|
||||
if("hear_adminhelps")
|
||||
toggles ^= SOUND_ADMINHELP
|
||||
|
||||
@@ -102,7 +102,6 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
if(current_version < 12)
|
||||
ignoring = list()
|
||||
|
||||
|
||||
//should this proc get fairly long (say 3 versions long),
|
||||
//just increase SAVEFILE_VERSION_MIN so it's not as far behind
|
||||
//SAVEFILE_VERSION_MAX and then delete any obsolete if clauses
|
||||
@@ -165,14 +164,14 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
S["ooccolor"] >> ooccolor
|
||||
S["lastchangelog"] >> lastchangelog
|
||||
S["UI_style"] >> UI_style
|
||||
S["nanoui_fancy"] >> nanoui_fancy
|
||||
S["be_special"] >> be_special
|
||||
S["tgui_fancy"] >> tgui_fancy
|
||||
S["tgui_lock"] >> tgui_lock
|
||||
|
||||
if(islist(S["be_special"]))
|
||||
S["be_special"] >> be_special
|
||||
S["be_special"] >> be_special
|
||||
else //force update and store the old bitflag version of be_special
|
||||
needs_update = 11
|
||||
S["be_special"] >> old_be_special
|
||||
S["be_special"] >> old_be_special
|
||||
|
||||
S["default_slot"] >> default_slot
|
||||
S["chat_toggles"] >> chat_toggles
|
||||
@@ -193,7 +192,8 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
ooccolor = sanitize_ooccolor(sanitize_hexcolor(ooccolor, 6, 1, initial(ooccolor)))
|
||||
lastchangelog = sanitize_text(lastchangelog, initial(lastchangelog))
|
||||
UI_style = sanitize_inlist(UI_style, list("Midnight", "Plasmafire", "Retro"), initial(UI_style))
|
||||
nanoui_fancy = sanitize_integer(nanoui_fancy, 0, 1, initial(nanoui_fancy))
|
||||
tgui_fancy = sanitize_integer(tgui_fancy, 0, 1, initial(tgui_fancy))
|
||||
tgui_lock = sanitize_integer(tgui_lock, 0, 1, initial(tgui_lock))
|
||||
default_slot = sanitize_integer(default_slot, 1, max_save_slots, initial(default_slot))
|
||||
toggles = sanitize_integer(toggles, 0, 65535, initial(toggles))
|
||||
ghost_form = sanitize_inlist(ghost_form, ghost_forms, initial(ghost_form))
|
||||
@@ -213,7 +213,8 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
S["ooccolor"] << ooccolor
|
||||
S["lastchangelog"] << lastchangelog
|
||||
S["UI_style"] << UI_style
|
||||
S["nanoui_fancy"] << nanoui_fancy
|
||||
S["tgui_fancy"] << tgui_fancy
|
||||
S["tgui_lock"] << tgui_lock
|
||||
S["be_special"] << be_special
|
||||
S["default_slot"] << default_slot
|
||||
S["toggles"] << toggles
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
icon_state = null
|
||||
flags = OPENCONTAINER
|
||||
var/gulp_size = 5 //This is now officially broken ... need to think of a nice way to fix it.
|
||||
possible_transfer_amounts = list(5,10,25)
|
||||
possible_transfer_amounts = list(5,10,15,20,25,30,50)
|
||||
volume = 50
|
||||
burn_state = FIRE_PROOF
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
/obj/item/weapon/reagent_containers/food/drinks/bottle
|
||||
amount_per_transfer_from_this = 10
|
||||
volume = 100
|
||||
throwforce = 15
|
||||
item_state = "broken_beer" //Generic held-item sprite until unique ones are made.
|
||||
var/const/duration = 13 //Directly relates to the 'weaken' duration. Lowered by armor (i.e. helmets)
|
||||
var/isGlass = 1 //Whether the 'bottle' is made of glass or not so that milk cartons dont shatter when someone gets hit by it
|
||||
|
||||
@@ -36,9 +36,9 @@
|
||||
if(M.z == target_z)
|
||||
M << start_up_message
|
||||
|
||||
sleep(start_up_time)
|
||||
stage = MAIN_STAGE
|
||||
weather_main()
|
||||
spawn(start_up_time)
|
||||
stage = MAIN_STAGE
|
||||
weather_main()
|
||||
|
||||
|
||||
/datum/weather/proc/weather_main()
|
||||
|
||||
@@ -47,12 +47,13 @@
|
||||
duration_overlay = ""
|
||||
overlay_layer = 10
|
||||
|
||||
/datum/weather/advanced_darkness/advanced_darkness/update_areas()
|
||||
..()
|
||||
/datum/weather/advanced_darkness/update_areas()
|
||||
for(var/area/A in impacted_areas)
|
||||
if(stage == MAIN_STAGE)
|
||||
A.invisibility = 0
|
||||
A.opacity = 1
|
||||
else
|
||||
A.invisibility = 100
|
||||
A.opacity = 0
|
||||
//Ash storms
|
||||
|
||||
|
||||
@@ -86,7 +86,7 @@ Works together with spawning an observer, noted above.
|
||||
if(key)
|
||||
if(!cmptext(copytext(key,1,2),"@")) // Skip aghosts.
|
||||
var/mob/dead/observer/ghost = new(src) // Transfer safety to observer spawning proc.
|
||||
SSnano.on_transfer(src, ghost) // Transfer NanoUIs.
|
||||
SStgui.on_transfer(src, ghost) // Transfer NanoUIs.
|
||||
ghost.can_reenter_corpse = can_reenter_corpse
|
||||
ghost.key = key
|
||||
return ghost
|
||||
@@ -156,7 +156,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
if(mind.current.key && copytext(mind.current.key,1,2)!="@") //makes sure we don't accidentally kick any clients
|
||||
usr << "<span class='warning'>Another consciousness is in your body...It is resisting you.</span>"
|
||||
return
|
||||
SSnano.on_transfer(src, mind.current) // Transfer NanoUIs.
|
||||
SStgui.on_transfer(src, mind.current) // Transfer NanoUIs.
|
||||
mind.current.key = key
|
||||
return 1
|
||||
|
||||
|
||||
@@ -11,8 +11,10 @@
|
||||
var/message_a = say_quote(message, get_spans())
|
||||
var/rendered = "<i><span class='alien'>Hivemind, <span class='name'>[shown_name]</span> <span class='message'>[message_a]</span></span></i>"
|
||||
for(var/mob/S in player_list)
|
||||
if((!S.stat && S.hivecheck()) || (S in dead_mob_list))
|
||||
if(!S.stat && S.hivecheck())
|
||||
S << rendered
|
||||
if(S in dead_mob_list)
|
||||
S << "<a href='?src=\ref[S];follow=\ref[src]'>(F)</a>[rendered]"
|
||||
|
||||
/mob/living/carbon/alien/humanoid/royal/queen/alien_talk(message, shown_name = name)
|
||||
shown_name = "<FONT size = 3>[shown_name]</FONT>"
|
||||
|
||||
@@ -39,7 +39,10 @@ var/global/posibrain_notif_cooldown = 0
|
||||
spawn(askDelay) //Seperate from the global cooldown.
|
||||
notified = 0
|
||||
update_icon()
|
||||
visible_message("<span class='notice'>The positronic brain buzzes quietly, and the golden lights fade away. Perhaps you could try again?</span>")
|
||||
if(brainmob.stat == CONSCIOUS && brainmob.client)
|
||||
visible_message("<span class='notice'>The positronic brain pings, and its lights start flashing. Success!</span>")
|
||||
else
|
||||
visible_message("<span class='notice'>The positronic brain buzzes quietly, and the golden lights fade away. Perhaps you could try again?</span>")
|
||||
|
||||
return //Code for deleting personalities recommended here.
|
||||
|
||||
@@ -127,7 +130,6 @@ var/global/posibrain_notif_cooldown = 0
|
||||
return
|
||||
|
||||
/obj/item/device/mmi/posibrain/New()
|
||||
|
||||
brainmob = new(src)
|
||||
brainmob.name = "[pick(list("PBU","HIU","SINA","ARMA","OSI","HBL","MSO","RR","CHRI","CDB","HG","XSI","ORNG","GUN","KOR","MET","FRE","XIS","SLI","PKP","HOG","RZH","GOOF","MRPR","JJR","FIRC","INC","PHL","BGB","ANTR","MIW","WJ","JRD","CHOC","ANCL","JLLO","ANNS","KOS","TKRG","XAL","STLP","CBOS","DNCN","FXMC","DRSD"))]-[rand(100, 999)]"
|
||||
brainmob.real_name = brainmob.name
|
||||
@@ -137,7 +139,6 @@ var/global/posibrain_notif_cooldown = 0
|
||||
brainmob.silent = 0
|
||||
dead_mob_list -= brainmob
|
||||
ping_ghosts("created")
|
||||
|
||||
..()
|
||||
|
||||
|
||||
|
||||
@@ -21,8 +21,6 @@
|
||||
t_has = "have"
|
||||
t_is = "are"
|
||||
else
|
||||
if(icon)
|
||||
msg += "\icon[src] " //note, should we ever go back to runtime-generated icons (please don't), you will need to change this to \icon[icon] to prevent crashes.
|
||||
switch(gender)
|
||||
if(MALE)
|
||||
t_He = "He"
|
||||
|
||||
@@ -306,6 +306,8 @@
|
||||
if(head)
|
||||
if(head.flags & BLOCK_GAS_SMOKE_EFFECT)
|
||||
. = 1
|
||||
if(NOBREATH in dna.species.specflags)
|
||||
. = 1
|
||||
return .
|
||||
/mob/living/carbon/human/proc/handle_embedded_objects()
|
||||
for(var/obj/item/organ/limb/L in organs)
|
||||
|
||||
@@ -208,7 +208,7 @@ var/list/crit_allowed_modes = list(MODE_WHISPER,MODE_CHANGELING,MODE_ALIEN)
|
||||
log_say("[mind.changeling.changelingID]/[src.key] : [message]")
|
||||
for(var/mob/M in mob_list)
|
||||
if(M in dead_mob_list)
|
||||
M << msg
|
||||
M << "<a href='?src=\ref[M];follow=\ref[src]'>(F)</a>[msg]"
|
||||
else
|
||||
switch(M.lingcheck())
|
||||
if(2)
|
||||
|
||||
@@ -842,4 +842,10 @@ var/list/ai_list = list()
|
||||
//get_turf_pixel() is because APCs in maint aren't actually in view of the inner camera
|
||||
if(M && cameranet && !cameranet.checkTurfVis(get_turf_pixel(M)) && !apc_override)
|
||||
return
|
||||
return 1
|
||||
return 1
|
||||
|
||||
/mob/living/silicon/ai/proc/relay_speech(message, atom/movable/speaker, message_langs, raw_message, radio_freq, list/spans)
|
||||
raw_message = lang_treat(speaker, message_langs, raw_message, spans)
|
||||
var/name_used = speaker.GetVoice()
|
||||
var/rendered = "<i><span class='game say'>Relayed Speech: <span class='name'>[name_used]</span> <span class='message'>[raw_message]</span></span></i>"
|
||||
show_message(rendered, 2)
|
||||
@@ -6,9 +6,10 @@
|
||||
/mob/camera/aiEye
|
||||
name = "Inactive AI Eye"
|
||||
|
||||
invisibility = 100
|
||||
var/list/visibleCameraChunks = list()
|
||||
var/mob/living/silicon/ai/ai = null
|
||||
|
||||
var/relay_speech = FALSE
|
||||
|
||||
// Use this when setting the aiEye's location.
|
||||
// It will also stream the chunk that the new loc is in.
|
||||
@@ -78,7 +79,6 @@
|
||||
if (user.camera_light_on)
|
||||
user.light_cameras()
|
||||
|
||||
|
||||
// Return to the Core.
|
||||
/mob/living/silicon/ai/proc/view_core()
|
||||
|
||||
@@ -104,3 +104,7 @@
|
||||
return //won't work if dead
|
||||
acceleration = !acceleration
|
||||
usr << "Camera acceleration has been toggled [acceleration ? "on" : "off"]."
|
||||
|
||||
/mob/camera/aiEye/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, list/spans)
|
||||
if(relay_speech && speaker && ai && !radio_freq && speaker != ai && near_camera(speaker))
|
||||
ai.relay_speech(message, speaker, message_langs, raw_message, radio_freq, spans)
|
||||
@@ -17,3 +17,10 @@
|
||||
|
||||
src.laws_sanity_check()
|
||||
src.laws.show_laws(who)
|
||||
if(!everyone)
|
||||
for(var/mob/living/silicon/robot/R in connected_robots)
|
||||
if(R.lawupdate)
|
||||
R.lawsync()
|
||||
R.show_laws()
|
||||
R.law_change_counter++
|
||||
|
||||
|
||||
@@ -13,12 +13,14 @@
|
||||
var/message_a = say_quote(message, get_spans())
|
||||
var/rendered = "<i><span class='game say'>Robotic Talk, <span class='name'>[name]</span> <span class='message'>[message_a]</span></span></i>"
|
||||
for(var/mob/M in player_list)
|
||||
if(M.binarycheck() || (M in dead_mob_list))
|
||||
if(M.binarycheck())
|
||||
if(istype(M, /mob/living/silicon/ai))
|
||||
var/renderedAI = "<i><span class='game say'>Robotic Talk, <a href='?src=\ref[M];track=[html_encode(name)]'><span class='name'>[name] ([desig])</span></a> <span class='message'>[message_a]</span></span></i>"
|
||||
M << renderedAI
|
||||
else
|
||||
M << rendered
|
||||
if(M in dead_mob_list)
|
||||
M << "<a href='?src=\ref[M];follow=\ref[src]'>(F)</a>[rendered]"
|
||||
|
||||
/mob/living/silicon/binarycheck()
|
||||
return 1
|
||||
|
||||
@@ -161,4 +161,19 @@
|
||||
corpseuniform = /obj/item/clothing/under/color/lightpurple
|
||||
corpsesuit = /obj/item/clothing/suit/wizrobe
|
||||
corpseshoes = /obj/item/clothing/shoes/sandal
|
||||
corpsehelmet = /obj/item/clothing/head/wizard
|
||||
corpsehelmet = /obj/item/clothing/head/wizard
|
||||
|
||||
|
||||
/obj/effect/landmark/mobcorpse/nanotrasensoldier
|
||||
name = "Nanotrasen Private Security Officer"
|
||||
corpseuniform = /obj/item/clothing/under/rank/security
|
||||
corpsesuit = /obj/item/clothing/suit/armor/vest
|
||||
corpseshoes = /obj/item/clothing/shoes/combat
|
||||
corpsegloves = /obj/item/clothing/gloves/combat
|
||||
corpseradio = /obj/item/device/radio/headset
|
||||
corpsemask = /obj/item/clothing/mask/gas/sechailer/swat
|
||||
corpsehelmet = /obj/item/clothing/head/helmet/swat/nanotrasen
|
||||
corpseback = /obj/item/weapon/storage/backpack/security
|
||||
corpseid = 1
|
||||
corpseidjob = "Private Security Force"
|
||||
corpseidaccess = "Security Officer"
|
||||
@@ -2,13 +2,13 @@
|
||||
name = "Guardian Spirit"
|
||||
real_name = "Guardian Spirit"
|
||||
desc = "A mysterious being that stands by it's charge, ever vigilant."
|
||||
speak_emote = list("intones")
|
||||
speak_emote = list("hisses")
|
||||
response_help = "passes through"
|
||||
response_disarm = "flails at"
|
||||
response_harm = "punches"
|
||||
icon = 'icons/mob/mob.dmi'
|
||||
icon_state = "stand"
|
||||
icon_living = "stand"
|
||||
icon = 'icons/mob/guardian.dmi'
|
||||
icon_state = "guardianorange"
|
||||
icon_living = "guardianorange"
|
||||
icon_dead = "stand"
|
||||
speed = 0
|
||||
a_intent = "harm"
|
||||
@@ -26,7 +26,6 @@
|
||||
melee_damage_upper = 15
|
||||
butcher_results = list(/obj/item/weapon/ectoplasm = 1)
|
||||
AIStatus = AI_OFF
|
||||
var/animated_manifest = FALSE
|
||||
var/cooldown = 0
|
||||
var/damage_transfer = 1 //how much damage from each attack we transfer to the owner
|
||||
var/mob/living/summoner
|
||||
@@ -34,7 +33,6 @@
|
||||
var/playstyle_string = "You are a standard Guardian. You shouldn't exist!"
|
||||
var/magic_fluff_string = " You draw the Coder, symbolizing bugs and errors. This shouldn't happen! Submit a bug report!"
|
||||
var/tech_fluff_string = "BOOT SEQUENCE COMPLETE. ERROR MODULE LOADED. THIS SHOULDN'T HAPPEN. Submit a bug report!"
|
||||
var/bio_fluff_string = "Your scarabs fail to mutate. This shouldn't happen! Submit a bug report!"
|
||||
|
||||
/mob/living/simple_animal/hostile/guardian/Life() //Dies if the summoner dies
|
||||
..()
|
||||
@@ -119,11 +117,6 @@
|
||||
if(loc == summoner)
|
||||
loc = get_turf(summoner)
|
||||
cooldown = world.time + 30
|
||||
if(animated_manifest)
|
||||
var/end_icon = icon_state
|
||||
icon_state = "parasite_forming"
|
||||
spawn(6)
|
||||
icon_state = end_icon
|
||||
|
||||
/mob/living/simple_animal/hostile/guardian/proc/Recall()
|
||||
if(cooldown > world.time)
|
||||
@@ -136,10 +129,13 @@
|
||||
var/input = stripped_input(src, "Please enter a message to tell your summoner.", "Guardian", "")
|
||||
if(!input) return
|
||||
|
||||
var/my_message = "<span class='boldannounce'><i>[src]:</i> [input]</span>"
|
||||
for(var/mob/M in mob_list)
|
||||
if(M == summoner || (M in dead_mob_list))
|
||||
M << "<span class='boldannounce'><i>[src]:</i> [input]</span>"
|
||||
src << "<span class='boldannounce'><i>[src]:</i> [input]</span>"
|
||||
if(M == summoner)
|
||||
M << my_message
|
||||
if(M in dead_mob_list)
|
||||
M << "<a href='?src=\ref[M];follow=\ref[src]'>(F)</a>[my_message]"
|
||||
src << "[my_message]"
|
||||
log_say("[src.real_name]/[src.key] : [input]")
|
||||
|
||||
/mob/living/simple_animal/hostile/guardian/proc/ToggleMode()
|
||||
@@ -153,13 +149,14 @@
|
||||
var/input = stripped_input(src, "Please enter a message to tell your guardian.", "Message", "")
|
||||
if(!input) return
|
||||
|
||||
var/my_message = "<span class='boldannounce'><i>[src]:</i> [input]</span>"
|
||||
for(var/mob/M in mob_list)
|
||||
if(istype (M, /mob/living/simple_animal/hostile/guardian))
|
||||
var/mob/living/simple_animal/hostile/guardian/G = M
|
||||
if(G.summoner == src)
|
||||
G << "<span class='boldannounce'><i>[src]:</i> [input]</span>"
|
||||
G << "[my_message]"
|
||||
else if (M in dead_mob_list)
|
||||
M << "<span class='boldannounce'><i>[src]:</i> [input]</span>"
|
||||
M << "<a href='?src=\ref[M];follow=\ref[src]'>(F)</a>[my_message]"
|
||||
src << "<span class='boldannounce'><i>[src]:</i> [input]</span>"
|
||||
log_say("[src.real_name]/[src.key] : [text]")
|
||||
|
||||
@@ -217,7 +214,6 @@
|
||||
environment_smash = 1
|
||||
magic_fluff_string = "..And draw the Wizard, bringer of endless chaos!"
|
||||
tech_fluff_string = "Boot sequence complete. Crowd control modules activated. Holoparasite swarm online."
|
||||
bio_fluff_string = "Your scarab swarm finishes mutating and stirs to life, ready to sow havoc at random."
|
||||
|
||||
/mob/living/simple_animal/hostile/guardian/fire/Life() //Dies if the summoner dies
|
||||
..()
|
||||
@@ -265,7 +261,6 @@
|
||||
environment_smash = 2
|
||||
magic_fluff_string = "..And draw the Assistant, faceless and generic, but never to be underestimated."
|
||||
tech_fluff_string = "Boot sequence complete. Standard combat modules loaded. Holoparasite swarm online."
|
||||
bio_fluff_string = "Your scarab swarm stirs to life, ready to tear apart your enemies."
|
||||
var/battlecry = "AT"
|
||||
|
||||
/mob/living/simple_animal/hostile/guardian/punch/verb/Battlecry()
|
||||
@@ -299,7 +294,6 @@
|
||||
playstyle_string = "As a Support type, you may toggle your basic attacks to a healing mode. In addition, Alt-Clicking on an adjacent mob will warp them to your bluespace beacon after a short delay."
|
||||
magic_fluff_string = "..And draw the CMO, a potent force of life...and death."
|
||||
tech_fluff_string = "Boot sequence complete. Medical modules active. Bluespace modules activated. Holoparasite swarm online."
|
||||
bio_fluff_string = "Your scarab swarm finishes mutating and stirs to life, capable of mending wounds and travelling via bluespace."
|
||||
var/turf/simulated/floor/beacon
|
||||
var/beacon_cooldown = 0
|
||||
var/toggle = FALSE
|
||||
@@ -424,7 +418,6 @@
|
||||
playstyle_string = "As a ranged type, you have only light damage resistance, but are capable of spraying shards of crystal at incredibly high speed. You can also deploy surveillance snares to monitor enemy movement. Finally, you can switch to scout mode, in which you can't attack, but can move without limit."
|
||||
magic_fluff_string = "..And draw the Sentinel, an alien master of ranged combat."
|
||||
tech_fluff_string = "Boot sequence complete. Ranged combat modules active. Holoparasite swarm online."
|
||||
bio_fluff_string = "Your scarab swarm finishes mutating and stirs to life, capable of spraying shards of crystal."
|
||||
var/list/snares = list()
|
||||
var/toggle = FALSE
|
||||
|
||||
@@ -502,7 +495,6 @@
|
||||
playstyle_string = "As an explosive type, you have only moderate close combat abilities, but are capable of converting any adjacent item into a disguised bomb via alt click."
|
||||
magic_fluff_string = "..And draw the Scientist, master of explosive death."
|
||||
tech_fluff_string = "Boot sequence complete. Explosive modules active. Holoparasite swarm online."
|
||||
bio_fluff_string = "Your scarab swarm finishes mutating and stirs to life, capable of stealthily booby trapping items."
|
||||
var/bomb_cooldown = 0
|
||||
|
||||
/mob/living/simple_animal/hostile/guardian/bomb/AltClickOn(atom/movable/A)
|
||||
@@ -609,7 +601,6 @@
|
||||
else
|
||||
gaurdiantype = input(user, "Pick the type of [mob_name]", "[mob_name] Creation") as null|anything in possible_guardians
|
||||
var/pickedtype = /mob/living/simple_animal/hostile/guardian/punch
|
||||
var/picked_color = randomColor(0)
|
||||
switch(gaurdiantype)
|
||||
|
||||
if("Chaos")
|
||||
@@ -638,26 +629,20 @@
|
||||
user.verbs += /mob/living/proc/guardian_comm
|
||||
user.verbs += /mob/living/proc/guardian_recall
|
||||
user.verbs += /mob/living/proc/guardian_reset
|
||||
|
||||
var/picked_name = pick("Aries", "Leo", "Sagittarius", "Taurus", "Virgo", "Capricorn", "Gemini", "Libra", "Aquarius", "Cancer", "Scorpio", "Pisces")
|
||||
var/colour = pick("orange", "pink", "red", "blue", "green")
|
||||
G.name = "[picked_name] [capitalize(colour)]"
|
||||
G.real_name = "[picked_name] [capitalize(colour)]"
|
||||
G.icon_living = "guardian[colour]"
|
||||
G.icon_state = "guardian[colour]"
|
||||
G.icon_dead = "guardian[colour]"
|
||||
|
||||
switch (theme)
|
||||
if("magic")
|
||||
G.name = "[mob_name] [capitalize(picked_color)]"
|
||||
G.color = color2hex(picked_color)
|
||||
G.real_name = "[mob_name] [capitalize(picked_color)]"
|
||||
user << "[G.magic_fluff_string]."
|
||||
if("tech")
|
||||
var/colour = pick("orange", "neon", "pink", "red", "blue", "green")
|
||||
G.name = "[mob_name] [capitalize(colour)]"
|
||||
G.real_name = "[mob_name] [capitalize(colour)]"
|
||||
G.icon_living = "parasite[colour]"
|
||||
G.icon_state = "parasite[colour]"
|
||||
G.icon_dead = "parasite[colour]"
|
||||
G.animated_manifest = TRUE
|
||||
user << "[G.tech_fluff_string]."
|
||||
G.speak_emote = list("states")
|
||||
if("bio")
|
||||
user << "[G.bio_fluff_string]."
|
||||
G.attacktext = "swarms"
|
||||
G.speak_emote = list("chitters")
|
||||
G.mind.name = "[G.real_name]"
|
||||
|
||||
/obj/item/weapon/guardiancreator/choose
|
||||
@@ -678,21 +663,6 @@
|
||||
/obj/item/weapon/guardiancreator/tech/choose
|
||||
random = FALSE
|
||||
|
||||
/obj/item/weapon/guardiancreator/biological
|
||||
name = "scarab egg cluster"
|
||||
desc = "A parasitic species that will nest in the closest living creature upon birth. While not great for your health, they'll defend their new 'hive' to the death."
|
||||
icon = 'icons/obj/syringe.dmi'
|
||||
icon_state = "combat_hypo"
|
||||
theme = "bio"
|
||||
mob_name = "Scarab Swarm"
|
||||
use_message = "The eggs begin to twitch..."
|
||||
used_message = "The cluster already hatched."
|
||||
failure_message = "<B>...but soon settles again. Guess they weren't ready to hatch after all.</B>"
|
||||
|
||||
/obj/item/weapon/guardiancreator/biological/choose
|
||||
random = FALSE
|
||||
|
||||
|
||||
/obj/item/weapon/paper/guardian
|
||||
name = "Holoparasite Guide"
|
||||
icon_state = "alienpaper_words"
|
||||
@@ -724,11 +694,6 @@
|
||||
return
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
///HUD
|
||||
|
||||
/datum/hud/proc/guardian_hud(ui_style = 'icons/mob/screen_midnight.dmi')
|
||||
@@ -761,8 +726,6 @@
|
||||
mymob.client.screen += adding
|
||||
|
||||
|
||||
|
||||
|
||||
//HUD BUTTONS
|
||||
|
||||
/obj/screen/guardian
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
|
||||
faction = list("carp")
|
||||
flying = 1
|
||||
pressure_resistance = 200
|
||||
gold_core_spawnable = 1
|
||||
|
||||
/mob/living/simple_animal/hostile/carp/Process_Spacemove(movement_dir = 0)
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
speak_emote = list("states")
|
||||
gold_core_spawnable = 1
|
||||
del_on_death = 1
|
||||
loot = (/obj/effect/decal/cleanable/robot_debris)
|
||||
loot = list(/obj/effect/decal/cleanable/robot_debris)
|
||||
|
||||
/mob/living/simple_animal/hostile/hivebot/New()
|
||||
..()
|
||||
|
||||
@@ -374,6 +374,8 @@
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/goliath/OpenFire()
|
||||
var/tturf = get_turf(target)
|
||||
if(!(istype(tturf, /turf/simulated)))
|
||||
return
|
||||
if(get_dist(src, target) <= 7)//Screen range check, so you can't get tentacle'd offscreen
|
||||
visible_message("<span class='warning'>The [src.name] digs its tentacles under [target.name]!</span>")
|
||||
new /obj/effect/goliath_tentacle/original(tturf)
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
/mob/living/simple_animal/hostile/nanotrasen
|
||||
name = "Nanotrasen Private Security Officer"
|
||||
desc = "An officer part of Nanotrasen's private security force, he seems rather unpleased to meet you."
|
||||
icon_state = "nanotrasen"
|
||||
icon_living = "nanotrasen"
|
||||
icon_dead = null
|
||||
icon_gib = "syndicate_gib"
|
||||
speak_chance = 25
|
||||
turns_per_move = 5
|
||||
response_help = "pokes"
|
||||
response_disarm = "shoves"
|
||||
response_harm = "hits"
|
||||
speed = 0
|
||||
stat_attack = 1
|
||||
robust_searching = 1
|
||||
maxHealth = 100
|
||||
health = 100
|
||||
harm_intent_damage = 5
|
||||
melee_damage_lower = 10
|
||||
melee_damage_upper = 15
|
||||
attacktext = "punches"
|
||||
attack_sound = 'sound/weapons/punch1.ogg'
|
||||
a_intent = "harm"
|
||||
loot = list(/obj/effect/landmark/mobcorpse/nanotrasensoldier)
|
||||
atmos_requirements = list("min_oxy" = 5, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 1, "min_co2" = 0, "max_co2" = 5, "min_n2" = 0, "max_n2" = 0)
|
||||
unsuitable_atmos_damage = 15
|
||||
faction = list("nanotrasenprivate")
|
||||
status_flags = CANPUSH
|
||||
speak = list("Stop resisting!", "I AM THE LAW!", "Face the wrath of the golden bolt!", "Stop breaking the law, asshole!")
|
||||
search_objects = 1
|
||||
|
||||
|
||||
/mob/living/simple_animal/hostile/nanotrasen/Aggro()
|
||||
..()
|
||||
summon_backup(15)
|
||||
say("411 in progress, requesting backup!")
|
||||
|
||||
|
||||
/mob/living/simple_animal/hostile/nanotrasen/ranged
|
||||
icon_state = "nanotrasenranged"
|
||||
icon_living = "nanotrasenranged"
|
||||
ranged = 1
|
||||
retreat_distance = 3
|
||||
minimum_distance = 5
|
||||
casingtype = /obj/item/ammo_casing/c45
|
||||
projectilesound = 'sound/weapons/Gunshot.ogg'
|
||||
loot = list(/obj/item/weapon/gun/projectile/automatic/pistol/m1911,
|
||||
/obj/effect/landmark/mobcorpse/nanotrasensoldier)
|
||||
|
||||
|
||||
/mob/living/simple_animal/hostile/nanotrasen/ranged/smg
|
||||
icon_state = "nanotrasenrangedsmg"
|
||||
icon_living = "nanotrasenrangedsmg"
|
||||
rapid = 1
|
||||
casingtype = /obj/item/ammo_casing/c46x30mm
|
||||
projectilesound = 'sound/weapons/Gunshot_smg.ogg'
|
||||
loot = list(/obj/item/weapon/gun/projectile/automatic/wt550,
|
||||
/obj/effect/landmark/mobcorpse/nanotrasensoldier)
|
||||
@@ -27,7 +27,7 @@
|
||||
player_list |= src
|
||||
update_Login_details()
|
||||
world.update_status()
|
||||
|
||||
|
||||
client.images = null //remove the images such as AIs being unable to see runes
|
||||
client.screen = list() //remove hud items just in case
|
||||
if(hud_used) qdel(hud_used) //remove the hud objects
|
||||
@@ -37,7 +37,8 @@
|
||||
sight |= SEE_SELF
|
||||
|
||||
..()
|
||||
|
||||
if (key != client.key)
|
||||
key = client.key
|
||||
if(loc && !isturf(loc))
|
||||
client.eye = loc
|
||||
client.perspective = EYE_PERSPECTIVE
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/mob/Logout()
|
||||
SSnano.on_logout(src)
|
||||
SStgui.on_logout(src)
|
||||
player_list -= src
|
||||
log_access("Logout: [key_name(src)]")
|
||||
if(admin_datums[src.ckey])
|
||||
|
||||
@@ -1,365 +0,0 @@
|
||||
/**
|
||||
* NanoUI
|
||||
*
|
||||
* Contains the NanoUI datum, and its procs.
|
||||
*
|
||||
* /tg/station user interface library
|
||||
* thanks to baystation12
|
||||
*
|
||||
* modified by neersighted
|
||||
**/
|
||||
|
||||
/**
|
||||
* NanoUI datum:
|
||||
*
|
||||
* Represents a NanoUI.
|
||||
**/
|
||||
/datum/nanoui
|
||||
var/mob/user // The mob who opened/is using the NanoUI.
|
||||
var/atom/movable/src_object // The object which owns the NanoUI.
|
||||
var/title // The title of te NanoUI.
|
||||
var/ui_key // The ui_key of the NanoUI. This allows multiple UIs for one src_object.
|
||||
var/window_id // The window_id for browse() and onclose().
|
||||
var/width = 0 // The window width.
|
||||
var/height = 0 // The window height
|
||||
var/window_options = list( // Extra options to winset().
|
||||
"focus" = 0,
|
||||
"titlebar" = 1,
|
||||
"can_resize" = 1,
|
||||
"can_minimize" = 1,
|
||||
"can_maximize" = 0,
|
||||
"can_close" = 1,
|
||||
"auto_format" = 0
|
||||
)
|
||||
var/atom/ref = null // An extra ref to call when the window is closed.
|
||||
var/layout = "nanotrasen" // The layout to be used for this UI.
|
||||
var/template // The template to be used for this UI.
|
||||
var/auto_update = 1 // Update the NanoUI every MC tick.
|
||||
var/list/initial_data // The data (and datastructure) used to initialize the NanoUI
|
||||
var/status = NANO_INTERACTIVE // The status/visibility of the NanoUI.
|
||||
var/datum/nano_state/state = null // Topic state used to determine status. Topic states are in interactions/.
|
||||
var/datum/nanoui/master_ui // The parent NanoUI.
|
||||
var/list/datum/nanoui/children = list() // Children of this NanoUI.
|
||||
|
||||
/**
|
||||
* public
|
||||
*
|
||||
* Create a new NanoUI.
|
||||
*
|
||||
* required user mob The mob who opened/is using the NanoUI.
|
||||
* required src_object atom/movable The object which owns the NanoUI.
|
||||
* required ui_key string The ui_key of the NanoUI.
|
||||
* required template string The template to render the NanoUI content with.
|
||||
* optional title string The title of the NanoUI.
|
||||
* optional width int The window width.
|
||||
* optional height int The window height.
|
||||
* optional ref atom An extra ref to use when the window is closed.
|
||||
* optional master_ui datum/nanoui The parent NanoUI.
|
||||
* optional state datum/nano_state The state used to determine status.
|
||||
*
|
||||
* return datum/nanoui The requested NanoUI.
|
||||
**/
|
||||
/datum/nanoui/New(mob/user, atom/movable/src_object, ui_key, template, \
|
||||
title, width = 0, height = 0, \
|
||||
atom/ref = null, datum/nanoui/master_ui = null, \
|
||||
datum/nano_state/state = default_state)
|
||||
src.user = user
|
||||
src.src_object = src_object
|
||||
src.ui_key = ui_key
|
||||
src.window_id = "\ref[src_object]-[ui_key]"
|
||||
|
||||
set_template(template)
|
||||
|
||||
if(title)
|
||||
src.title = sanitize(title)
|
||||
if(width)
|
||||
src.width = width
|
||||
if(height)
|
||||
src.height = height
|
||||
|
||||
if(ref)
|
||||
src.ref = ref
|
||||
|
||||
src.master_ui = master_ui
|
||||
if(master_ui)
|
||||
master_ui.children += src
|
||||
src.state = state
|
||||
|
||||
var/datum/asset/assets = get_asset_datum(/datum/asset/simple/nanoui)
|
||||
assets.send(user)
|
||||
|
||||
/**
|
||||
* public
|
||||
*
|
||||
* Open this NanoUI (and initialize it with data).
|
||||
*
|
||||
* optional data list The data to intialize the UI with.
|
||||
**/
|
||||
/datum/nanoui/proc/open(list/data = null)
|
||||
if(!user.client)
|
||||
return // Bail if there is no client.
|
||||
|
||||
update_status(push = 0) // Update the window status.
|
||||
if(status == NANO_CLOSE)
|
||||
return // Bail if we should close.
|
||||
|
||||
if(!initial_data)
|
||||
if(!data) // If we don't have initial_data and data was not passed, get data from the src_object.
|
||||
data = src_object.get_ui_data(user)
|
||||
set_initial_data(data) // Otherwise use the passed data.
|
||||
|
||||
var/window_size = ""
|
||||
if(width && height) // If we have a width and height, use them.
|
||||
window_size = "size=[width]x[height];"
|
||||
|
||||
user << browse(get_html(), "window=[window_id];[window_size][list2params(window_options)]") // Open the window.
|
||||
winset(user, window_id, "on-close=\"nanoclose \ref[src]\"") // Instruct the client to signal NanoUI when the window is closed.
|
||||
SSnano.on_open(src)
|
||||
|
||||
/**
|
||||
* public
|
||||
*
|
||||
* Reinitialize the NanoUI.
|
||||
* (Possibly with a new template and/or data).
|
||||
*
|
||||
* optional template string The filename of the new template.
|
||||
* optional data list The new initial data.
|
||||
**/
|
||||
/datum/nanoui/proc/reinitialize(template, list/data)
|
||||
if(template)
|
||||
set_template(template) // Set a new template.
|
||||
if(data)
|
||||
set_initial_data(data) // Replace the initial_data.
|
||||
open()
|
||||
|
||||
/**
|
||||
* public
|
||||
*
|
||||
* Close the NanoUI, and all its children.
|
||||
**/
|
||||
/datum/nanoui/proc/close()
|
||||
user << browse(null, "window=[window_id]") // Close the window.
|
||||
SSnano.on_close(src)
|
||||
for(var/datum/nanoui/child in children) // Loop through and close all children.
|
||||
child.close()
|
||||
|
||||
/**
|
||||
* public
|
||||
*
|
||||
* Sets the browse() window options for this NanoUI.
|
||||
*
|
||||
* required window_options list The window options to set.
|
||||
**/
|
||||
/datum/nanoui/proc/set_window_options(list/window_options)
|
||||
src.window_options = window_options
|
||||
|
||||
/**
|
||||
* public
|
||||
*
|
||||
* Set the layout for this NanoUI.
|
||||
* This loads custom layout styles and templates for this NanoUI.
|
||||
*
|
||||
* required layout string The new UI layout.
|
||||
**/
|
||||
/datum/nanoui/proc/set_layout(layout)
|
||||
src.layout = lowertext(layout)
|
||||
|
||||
/**
|
||||
* public
|
||||
*
|
||||
* Set the template for this NanoUI.
|
||||
*
|
||||
* required template string The new UI template.
|
||||
**/
|
||||
/datum/nanoui/proc/set_template(template)
|
||||
src.template = lowertext(template)
|
||||
|
||||
/**
|
||||
* public
|
||||
*
|
||||
* Enable/disable auto-updating of the NanoUI.
|
||||
*
|
||||
* required state bool Enable/disable auto-updating.
|
||||
**/
|
||||
/datum/nanoui/proc/set_auto_update(state = 1)
|
||||
auto_update = state
|
||||
|
||||
/**
|
||||
* private
|
||||
*
|
||||
* Set the data to initialize the NanoUI with.
|
||||
* The datastructure cannot be changed by subsequent updates.
|
||||
*
|
||||
* optional data list The data/datastructure to initialize the NanoUI with.
|
||||
**/
|
||||
/datum/nanoui/proc/set_initial_data(list/data)
|
||||
initial_data = data
|
||||
|
||||
/**
|
||||
* private
|
||||
*
|
||||
* Generate HTML for this NanoUI.
|
||||
*
|
||||
* return string NanoUI HTML output.
|
||||
**/
|
||||
/datum/nanoui/proc/get_html()
|
||||
// Generate JSON.
|
||||
var/list/send_data = get_send_data(initial_data)
|
||||
var/send_data_json = JSON.stringify(send_data)
|
||||
send_data_json = replacetextEx(send_data_json, "'", "'")
|
||||
send_data_json = replacetextEx(send_data_json, "\improper", "")
|
||||
send_data_json = replacetextEx(send_data_json, "ÿ", "")
|
||||
|
||||
// Populate it.
|
||||
var/send_html = replacetextEx(SSnano.html, "\[data]", send_data_json)
|
||||
return send_html
|
||||
|
||||
/**
|
||||
* private
|
||||
*
|
||||
* Get the config data/datastructure to initialize the NanoUI with.
|
||||
*
|
||||
* return list The config data.
|
||||
**/
|
||||
/datum/nanoui/proc/get_config_data()
|
||||
var/list/config_data = list(
|
||||
"title" = title,
|
||||
"status" = status,
|
||||
"layout" = layout,
|
||||
"window" = window_id,
|
||||
"ref" = "\ref[src]",
|
||||
"user" = list(
|
||||
"name" = user.name,
|
||||
"fancy" = user.client.prefs.nanoui_fancy,
|
||||
"ref" = "\ref[user]"
|
||||
),
|
||||
"srcObject" = list(
|
||||
"name" = src_object.name,
|
||||
"ref" = "\ref[src_object]"
|
||||
),
|
||||
"templates" = list(
|
||||
"layout" = "_[layout]",
|
||||
"content" = "[template]"
|
||||
)
|
||||
)
|
||||
return config_data
|
||||
|
||||
/**
|
||||
* private
|
||||
*
|
||||
* Package the data to send to the UI.
|
||||
* This is the (regular) data and config data, bundled together.
|
||||
*
|
||||
* return list The packaged data.
|
||||
**/
|
||||
/datum/nanoui/proc/get_send_data(list/data)
|
||||
var/list/send_data = list()
|
||||
|
||||
send_data["config"] = get_config_data()
|
||||
if(!isnull(data))
|
||||
send_data["data"] = data
|
||||
|
||||
return send_data
|
||||
|
||||
/**
|
||||
* private
|
||||
*
|
||||
* Handle clicks from the NanoUI.
|
||||
* Call the src_object's ui_act() if status is NANO_INTERACTIVE.
|
||||
* If the src_object's ui_act() returns 1, update all UIs attacked to it.
|
||||
**/
|
||||
/datum/nanoui/Topic(href, href_list)
|
||||
update_status(push = 0) // Update the window state.
|
||||
if(status != NANO_INTERACTIVE || user != usr)
|
||||
return // If UI is not interactive or usr calling Topic is not the UI user.
|
||||
|
||||
var/action = href_list["nano"] // Pull the action out.
|
||||
href_list -= "nano"
|
||||
|
||||
var/update = src_object.ui_act(action, href_list, state) // Call ui_act() on the src_object.
|
||||
if(src_object && update)
|
||||
SSnano.update_uis(src_object) // If we have a src_object and its ui_act() told us to update.
|
||||
|
||||
/**
|
||||
* private
|
||||
*
|
||||
* Update the NanoUI. Only updates the contents/layout if update is true,
|
||||
* otherwise only updates the status.
|
||||
*
|
||||
* optional force bool If the UI should be forced to update.
|
||||
**/
|
||||
/datum/nanoui/process(force = 0)
|
||||
if(!src_object || !user) // If the object or user died (or something else), abort.
|
||||
close()
|
||||
return
|
||||
|
||||
if(status && (force || auto_update))
|
||||
update() // Update the UI if the status and update settings allow it.
|
||||
else
|
||||
update_status(push = 1) // Otherwise only update status.
|
||||
|
||||
/**
|
||||
* private
|
||||
*
|
||||
* Push data to an already open NanoUI.
|
||||
*
|
||||
* required data list The data to send.
|
||||
* optional force bool If the update should be sent regardless of state.
|
||||
**/
|
||||
/datum/nanoui/proc/push_data(data, force = 0)
|
||||
update_status(push = 0) // Update the window state.
|
||||
if(status <= NANO_DISABLED && !force)
|
||||
return // Cannot update UI, we have no visibility.
|
||||
|
||||
var/list/send_data = get_send_data(data) // Get the data to send.
|
||||
|
||||
// Send the new data to the recieveUpdate() Javascript function.
|
||||
user << output(url_encode(JSON.stringify(send_data)), "[window_id].browser:receiveUpdate")
|
||||
|
||||
|
||||
/**
|
||||
* private
|
||||
*
|
||||
* Updates the UI by interacting with the src_object again, which will hopefully
|
||||
* call try_ui_update on it.
|
||||
*
|
||||
* optional force_open bool If force_open should be passed to ui_interact.
|
||||
**/
|
||||
/datum/nanoui/proc/update(force_open = 0)
|
||||
src_object.ui_interact(user, ui_key, src, force_open, master_ui, state)
|
||||
|
||||
/**
|
||||
* private
|
||||
*
|
||||
* Update the status/visibility of the NanoUI for its user.
|
||||
*
|
||||
* optional push bool Push an update to the UI (an update is always sent for NANO_DISABLED).
|
||||
**/
|
||||
/datum/nanoui/proc/update_status(push = 0)
|
||||
var/new_status = src_object.nano_state(user, state)
|
||||
if(master_ui)
|
||||
new_status = min(new_status, master_ui.status)
|
||||
|
||||
if(new_status == NANO_CLOSE)
|
||||
close()
|
||||
else
|
||||
set_status(new_status, push)
|
||||
|
||||
/**
|
||||
* private
|
||||
*
|
||||
* Set the status/visibility of the NanoUI.
|
||||
*
|
||||
* required status int The status to set (NANO_CLOSE/NANO_DISABLED/NANO_UPDATE/NANO_INTERACTIVE).
|
||||
* optional push bool Push an update to the UI (an update is always sent for NANO_DISABLED).
|
||||
**/
|
||||
/datum/nanoui/proc/set_status(status, push = 0)
|
||||
if(src.status != status) // Only update if status has changed.
|
||||
if(src.status == NANO_DISABLED)
|
||||
src.status = status
|
||||
if(push)
|
||||
update()
|
||||
else
|
||||
src.status = status
|
||||
if(status == NANO_DISABLED || push) // Update if the UI just because disabled, or a push is requested.
|
||||
push_data(null, force = 1)
|
||||
@@ -1,12 +0,0 @@
|
||||
/**
|
||||
* NanoUI State: admin_state
|
||||
*
|
||||
* Checks that the user is an admin, end-of-story.
|
||||
**/
|
||||
|
||||
/var/global/datum/nano_state/admin_state/admin_state = new()
|
||||
|
||||
/datum/nano_state/admin_state/can_use_topic(atom/movable/src_object, mob/user)
|
||||
if(check_rights_for(user.client, R_ADMIN))
|
||||
return NANO_INTERACTIVE
|
||||
return NANO_CLOSE
|
||||
@@ -1,12 +0,0 @@
|
||||
/**
|
||||
* NanoUI State: conscious_state
|
||||
*
|
||||
* Only checks if the user is conscious.
|
||||
**/
|
||||
|
||||
/var/global/datum/nano_state/conscious_state/conscious_state = new()
|
||||
|
||||
/datum/nano_state/conscious_state/can_use_topic(atom/movable/src_object, mob/user)
|
||||
if(user.stat == CONSCIOUS)
|
||||
return NANO_INTERACTIVE
|
||||
return NANO_CLOSE
|
||||
@@ -1,12 +0,0 @@
|
||||
/**
|
||||
* NanoUI State: contained_state
|
||||
*
|
||||
* Checks that the user is inside the src_object.
|
||||
**/
|
||||
|
||||
/var/global/datum/nano_state/contained_state/contained_state = new()
|
||||
|
||||
/datum/nano_state/contained_state/can_use_topic(atom/movable/src_object, mob/user)
|
||||
if(!src_object.contains(user))
|
||||
return NANO_CLOSE
|
||||
return user.shared_nano_interaction(src_object)
|
||||
@@ -1,12 +0,0 @@
|
||||
/**
|
||||
* NanoUI State: deep_inventory_state
|
||||
*
|
||||
* Checks that the src_object is in the user's fist-level (backpack, webbing, etc) inventory.
|
||||
**/
|
||||
|
||||
/var/global/datum/nano_state/deep_inventory_state/deep_inventory_state = new()
|
||||
|
||||
/datum/nano_state/deep_inventory_state/can_use_topic(atom/movable/src_object, mob/user)
|
||||
if(!user.contains(src_object))
|
||||
return NANO_CLOSE
|
||||
return user.shared_nano_interaction(src_object)
|
||||
@@ -1,20 +0,0 @@
|
||||
/**
|
||||
* NanoUI State: hands_state
|
||||
*
|
||||
* Checks that the src_object is in the user's hands.
|
||||
**/
|
||||
|
||||
/var/global/datum/nano_state/hands_state/hands_state = new()
|
||||
|
||||
/datum/nano_state/hands_state/can_use_topic(atom/movable/src_object, mob/user)
|
||||
. = user.shared_nano_interaction(src_object)
|
||||
if(. > NANO_CLOSE)
|
||||
return min(., user.hands_can_use_topic(src_object))
|
||||
|
||||
/mob/proc/hands_can_use_topic(atom/movable/src_object)
|
||||
return NANO_CLOSE
|
||||
|
||||
/mob/living/hands_can_use_topic(atom/movable/src_object)
|
||||
if(src_object in get_both_hands(src))
|
||||
return NANO_INTERACTIVE
|
||||
return NANO_CLOSE
|
||||
@@ -1,12 +0,0 @@
|
||||
/**
|
||||
* NanoUI State: inventory_state
|
||||
*
|
||||
* Checks that the src_object is in the user's top-level (hand, ear, pocket, belt, etc) inventory.
|
||||
**/
|
||||
|
||||
/var/global/datum/nano_state/inventory_state/inventory_state = new()
|
||||
|
||||
/datum/nano_state/inventory_state/can_use_topic(atom/movable/src_object, mob/user)
|
||||
if(!(src_object in user))
|
||||
return NANO_CLOSE
|
||||
return user.shared_nano_interaction(src_object)
|
||||
@@ -1,21 +0,0 @@
|
||||
/**
|
||||
* NanoUI State: physical_state
|
||||
*
|
||||
* Short-circuits the default state to only check physical distance.
|
||||
**/
|
||||
|
||||
/var/global/datum/nano_state/physical/physical_state = new()
|
||||
|
||||
/datum/nano_state/physical/can_use_topic(atom/movable/src_object, mob/user)
|
||||
. = user.shared_nano_interaction(src_object)
|
||||
if(. > NANO_CLOSE)
|
||||
return min(., user.physical_can_use_topic(src_object))
|
||||
|
||||
/mob/proc/physical_can_use_topic(atom/movable/src_object)
|
||||
return NANO_CLOSE
|
||||
|
||||
/mob/living/physical_can_use_topic(atom/movable/src_object)
|
||||
return shared_living_nano_distance(src_object)
|
||||
|
||||
/mob/living/silicon/physical_can_use_topic(atom/movable/src_object)
|
||||
return max(NANO_UPDATE, shared_living_nano_distance(src_object)) // Silicons can always see.
|
||||
@@ -1,12 +0,0 @@
|
||||
/**
|
||||
* NanoUI State: self_state
|
||||
*
|
||||
* Only checks that the user and src_object are the same.
|
||||
**/
|
||||
|
||||
/var/global/datum/nano_state/self_state/self_state = new()
|
||||
|
||||
/datum/nano_state/self_state/can_use_topic(atom/movable/src_object, mob/user)
|
||||
if(src_object != user)
|
||||
return NANO_CLOSE
|
||||
return user.shared_nano_interaction(src_object)
|
||||
@@ -1,112 +0,0 @@
|
||||
/**
|
||||
* NanoUI States
|
||||
*
|
||||
* Base state and helpers for states. Just does some sanity checks, implement a state for in-depth checks.
|
||||
**/
|
||||
|
||||
/**
|
||||
* public
|
||||
*
|
||||
* Checks if a user can use src_object's NanoUI, under the given state.
|
||||
*
|
||||
* required user mob The mob who opened/is using the NanoUI.
|
||||
* required state datum/nano_state The state to check.
|
||||
*
|
||||
* return NANO_state The state of the UI.
|
||||
**/
|
||||
/atom/proc/nano_state(mob/user, datum/nano_state/state)
|
||||
var/src_object = nano_host()
|
||||
|
||||
if(istype(user, /mob/dead/observer)) // Special-case ghosts.
|
||||
if(check_rights_for(user.client, R_ADMIN))
|
||||
return NANO_INTERACTIVE // Admins can interact anyway.
|
||||
if(get_dist(src_object, src) > user.client.view)
|
||||
return NANO_CLOSE // Keep ghosts from opening too many NanoUIs.
|
||||
return NANO_UPDATE // Ghosts can only view.
|
||||
return state.can_use_topic(src_object, user) // Check if the state allows interaction.
|
||||
|
||||
/**
|
||||
* private
|
||||
*
|
||||
* Checks if a user can use src_object's NanoUI, and returns the state.
|
||||
* Can call a mob proc, which allows overrides for each mob.
|
||||
*
|
||||
* required src_object atom/movable The object which owns the NanoUI.
|
||||
* required user mob The mob who opened/is using the NanoUI.
|
||||
*
|
||||
* return NANO_state The state of the UI.
|
||||
**/
|
||||
/datum/nano_state/proc/can_use_topic(atom/movable/src_object, mob/user)
|
||||
return NANO_CLOSE // Don't allow interaction by default.
|
||||
|
||||
|
||||
/**
|
||||
* public
|
||||
*
|
||||
* Standard interaction/sanity checks. Different mob types may have overrides.
|
||||
*
|
||||
* return NANO_state The state of the UI.
|
||||
**/
|
||||
/mob/proc/shared_nano_interaction(atom/movable/src_object)
|
||||
if(!client || stat) // Close NanoUIs if mindless or dead/unconcious.
|
||||
return NANO_CLOSE
|
||||
// Update NanoUIs if incapicitated but concious.
|
||||
else if(incapacitated() || lying)
|
||||
return NANO_UPDATE
|
||||
return NANO_INTERACTIVE
|
||||
|
||||
/mob/living/carbon/human/shared_nano_interaction(atom/movable/src_object)
|
||||
// If we have telekinesis and remain close enough, allow interaction.
|
||||
if(dna.check_mutation(TK))
|
||||
if(tkMaxRangeCheck(src, src_object))
|
||||
return NANO_INTERACTIVE
|
||||
return ..()
|
||||
|
||||
/mob/living/silicon/ai/shared_nano_interaction(atom/movable/src_object)
|
||||
if(lacks_power()) // Close NanoUIs if the AI is unpowered.
|
||||
return NANO_CLOSE
|
||||
return ..()
|
||||
|
||||
/mob/living/silicon/robot/shared_nano_interaction(atom/movable/src_object)
|
||||
if(cell.charge <= 0) // Close NanoUIs if the Borg is unpowered.
|
||||
return NANO_CLOSE
|
||||
if(lockcharge) // Disable NanoUIs if the Borg is locked.
|
||||
return NANO_DISABLED
|
||||
return ..()
|
||||
|
||||
/**
|
||||
* public
|
||||
*
|
||||
* Check the distance for a living mob.
|
||||
* Really only used for checks outside the context of a mob.
|
||||
* Otherwise, use shared_living_nano_distance().
|
||||
*
|
||||
* required src_object atom/movable The object which owns the NanoUI.
|
||||
* required user mob The mob who opened/is using the NanoUI.
|
||||
*
|
||||
* return NANO_state The state of the UI.
|
||||
**/
|
||||
/atom/proc/contents_nano_distance(atom/movable/src_object, mob/living/user)
|
||||
return user.shared_living_nano_distance(src_object) // Just call this mob's check.
|
||||
|
||||
/**
|
||||
* public
|
||||
*
|
||||
* Distance versus interaction check.
|
||||
*
|
||||
* required src_object atom/movable The object which owns the NanoUI.
|
||||
*
|
||||
* return NANO_state The state of the UI.
|
||||
**/
|
||||
/mob/living/proc/shared_living_nano_distance(atom/movable/src_object)
|
||||
if(!(src_object in view(4, src))) // If the object is out of view, close it.
|
||||
return NANO_CLOSE
|
||||
|
||||
var/dist = get_dist(src_object, src)
|
||||
if(dist <= 1) // Open and interact if 1-0 tiles away.
|
||||
return NANO_INTERACTIVE
|
||||
else if(dist <= 2) // View only if 2-3 tiles away.
|
||||
return NANO_UPDATE
|
||||
else if(dist <= 5) // Disable if 5 tiles away.
|
||||
return NANO_DISABLED
|
||||
return NANO_CLOSE // Otherwise, we got nothing.
|
||||
@@ -131,6 +131,12 @@
|
||||
desc = "A polaroid camera, some say it can see ghosts!"
|
||||
see_ghosts = 1
|
||||
|
||||
/obj/item/device/camera/detective
|
||||
name = "Detective's camera"
|
||||
desc = "A polaroid camera with extra capacity for crime investigations."
|
||||
pictures_max = 30
|
||||
pictures_left = 30
|
||||
|
||||
|
||||
/obj/item/device/camera/siliconcam //camera AI can take pictures with
|
||||
name = "silicon photo camera"
|
||||
|
||||
+16
-13
@@ -626,10 +626,10 @@
|
||||
else
|
||||
ui_interact(user)
|
||||
|
||||
/obj/machinery/power/apc/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, force_open = 0)
|
||||
ui = SSnano.try_update_ui(user, src, ui_key, ui, force_open = force_open)
|
||||
/obj/machinery/power/apc/ui_interact(mob/user, ui_key = "main", var/datum/tgui/ui = null, force_open = 0)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open = force_open)
|
||||
if (!ui)
|
||||
ui = new(user, src, ui_key, "apc", name, 550, 550)
|
||||
ui = new(user, src, ui_key, "apc", name, 460, 520)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/power/apc/get_ui_data(mob/user)
|
||||
@@ -747,12 +747,22 @@
|
||||
if(!can_use(usr, 1))
|
||||
return
|
||||
|
||||
if(locked && !usr.has_unlimited_silicon_privilege)
|
||||
return
|
||||
|
||||
switch(action)
|
||||
if("lock")
|
||||
if(usr.has_unlimited_silicon_privilege)
|
||||
if(emagged || (stat & (BROKEN|MAINT)))
|
||||
usr << "The APC does not respond to the command."
|
||||
else
|
||||
locked = !locked
|
||||
update_icon()
|
||||
if("cover")
|
||||
coverlocked = !coverlocked
|
||||
if ("breaker")
|
||||
if("breaker")
|
||||
toggle_breaker()
|
||||
if("chargemode")
|
||||
if("charge")
|
||||
chargemode = !chargemode
|
||||
if(!chargemode)
|
||||
charging = 0
|
||||
@@ -773,19 +783,12 @@
|
||||
environ = setsubsystem(val)
|
||||
update_icon()
|
||||
update()
|
||||
if("toggleaccess")
|
||||
if(usr.has_unlimited_silicon_privilege)
|
||||
if(emagged || (stat & (BROKEN|MAINT)))
|
||||
usr << "The APC does not respond to the command."
|
||||
else
|
||||
locked = !locked
|
||||
update_icon()
|
||||
if("overload")
|
||||
if(usr.has_unlimited_silicon_privilege)
|
||||
src.overload_lighting()
|
||||
if("hack")
|
||||
var/mob/living/silicon/ai/malfai = usr
|
||||
if(get_malf_status(malfai)==1)
|
||||
if(get_malf_status(malfai) == 1)
|
||||
if (malfai.malfhacking)
|
||||
malfai << "You are already hacking an APC."
|
||||
return 1
|
||||
|
||||
@@ -468,6 +468,7 @@ var/global/list/datum/stack_recipe/cable_coil_recipes = list ( \
|
||||
item_state = "coil_red"
|
||||
max_amount = MAXCOIL
|
||||
amount = MAXCOIL
|
||||
merge_type = /obj/item/stack/cable_coil // This is here to let its children merge between themselves
|
||||
item_color = "red"
|
||||
desc = "A coil of power cable."
|
||||
throwforce = 0
|
||||
|
||||
+20
-15
@@ -256,22 +256,27 @@
|
||||
else
|
||||
if(input_attempt && input_available > 0 && input_available >= input_level)
|
||||
inputting = 1
|
||||
else
|
||||
inputting = 0
|
||||
|
||||
//outputting
|
||||
if(outputting)
|
||||
output_used = min( charge/SMESRATE, output_level) //limit output to that stored
|
||||
if(output_attempt)
|
||||
if(outputting)
|
||||
output_used = min( charge/SMESRATE, output_level) //limit output to that stored
|
||||
|
||||
charge -= output_used*SMESRATE // reduce the storage (may be recovered in /restore() if excessive)
|
||||
charge -= output_used*SMESRATE // reduce the storage (may be recovered in /restore() if excessive)
|
||||
|
||||
add_avail(output_used) // add output to powernet (smes side)
|
||||
add_avail(output_used) // add output to powernet (smes side)
|
||||
|
||||
if(output_used < 0.0001) // either from no charge or set to 0
|
||||
outputting = 0
|
||||
investigate_log("lost power and turned <font color='red'>off</font>","singulo")
|
||||
else if(output_attempt && charge > output_level && output_level > 0)
|
||||
outputting = 1
|
||||
if(output_used < 0.0001) // either from no charge or set to 0
|
||||
outputting = 0
|
||||
investigate_log("lost power and turned <font color='red'>off</font>","singulo")
|
||||
else if(output_attempt && charge > output_level && output_level > 0)
|
||||
outputting = 1
|
||||
else
|
||||
output_used = 0
|
||||
else
|
||||
output_used = 0
|
||||
outputting = 0
|
||||
|
||||
// only update icon if state changed
|
||||
if(last_disp != chargedisplay() || last_chrg != inputting || last_onln != outputting)
|
||||
@@ -324,10 +329,10 @@
|
||||
return
|
||||
ui_interact(user)
|
||||
|
||||
/obj/machinery/power/smes/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 0)
|
||||
ui = SSnano.try_update_ui(user, src, ui_key, ui, force_open = force_open)
|
||||
/obj/machinery/power/smes/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open = force_open)
|
||||
if (!ui)
|
||||
ui = new(user, src, ui_key, "smes", name, 500, 455)
|
||||
ui = new(user, src, ui_key, "smes", name, 340, 440)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/power/smes/get_ui_data()
|
||||
@@ -364,7 +369,7 @@
|
||||
log_smes(usr.ckey)
|
||||
update_icon()
|
||||
if("input")
|
||||
switch(params["set"])
|
||||
switch(params["input"])
|
||||
if("custom")
|
||||
var/custom = input(usr, "What rate would you like this SMES to attempt to charge at? Max is [input_level_max].") as null|num
|
||||
if(custom)
|
||||
@@ -380,7 +385,7 @@
|
||||
input_level = Clamp(input_level, 0, input_level_max)
|
||||
log_smes(usr.ckey)
|
||||
if("output")
|
||||
switch(params["set"])
|
||||
switch(params["output"])
|
||||
if("custom")
|
||||
var/custom = input(usr, "What rate would you like this SMES to attempt to output at? Max is [output_level_max].") as null|num
|
||||
if(custom)
|
||||
|
||||
@@ -369,10 +369,10 @@
|
||||
return
|
||||
ui_interact(user)
|
||||
|
||||
/obj/machinery/power/solar_control/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 0)
|
||||
ui = SSnano.try_update_ui(user, src, ui_key, ui, force_open = force_open)
|
||||
/obj/machinery/power/solar_control/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open = force_open)
|
||||
if (!ui)
|
||||
ui = new(user, src, ui_key, "solar_control", name, 515, 425)
|
||||
ui = new(user, src, ui_key, "solar_control", name, 465, 400)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/power/solar_control/get_ui_data()
|
||||
|
||||
@@ -176,7 +176,7 @@
|
||||
name = "wt550 magazine (4.6x30mm)"
|
||||
icon_state = "46x30mmt-20"
|
||||
ammo_type = /obj/item/ammo_casing/c46x30mm
|
||||
caliber = "4x6x30mm"
|
||||
caliber = "4.6x30mm"
|
||||
max_ammo = 20
|
||||
|
||||
/obj/item/ammo_box/magazine/wt550m9/update_icon()
|
||||
|
||||
@@ -37,7 +37,6 @@
|
||||
if(istype(AM, mag_type))
|
||||
if(magazine)
|
||||
user << "<span class='notice'>You perform a tactical reload on \the [src], replacing the magazine.</span>"
|
||||
user.say(pick("I'M RELOADING!!!", "NEW MAG IN!!!", "CHANGING MAG!!!", "COVER ME! I'M RELOADING!!!", "RELOADING!!!"))
|
||||
magazine.loc = get_turf(src.loc)
|
||||
magazine.update_icon()
|
||||
magazine = null
|
||||
@@ -233,4 +232,4 @@
|
||||
fire_sound = 'sound/weapons/Gunshot_smg.ogg'
|
||||
can_suppress = 0
|
||||
burst_size = 3
|
||||
fire_delay = 1
|
||||
fire_delay = 1
|
||||
@@ -85,10 +85,10 @@
|
||||
return
|
||||
ui_interact(user)
|
||||
|
||||
/obj/machinery/chem_dispenser/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 0)
|
||||
ui = SSnano.try_update_ui(user, src, ui_key, ui, force_open = force_open)
|
||||
/obj/machinery/chem_dispenser/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open = force_open)
|
||||
if (!ui)
|
||||
ui = new(user, src, ui_key, "chem_dispenser", name, 530, 700)
|
||||
ui = new(user, src, ui_key, "chem_dispenser", name, 550, 700)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/chem_dispenser/get_ui_data()
|
||||
@@ -119,7 +119,7 @@
|
||||
for(var/re in dispensable_reagents)
|
||||
var/datum/reagent/temp = chemical_reagents_list[re]
|
||||
if(temp)
|
||||
chemicals.Add(list(list("title" = temp.name, "id" = temp.id, "commands" = list("reagent" = temp.id))))
|
||||
chemicals.Add(list(list("title" = temp.name, "id" = temp.id)))
|
||||
data["chemicals"] = chemicals
|
||||
return data
|
||||
|
||||
@@ -129,7 +129,7 @@
|
||||
|
||||
switch(action)
|
||||
if("amount")
|
||||
amount = round(text2num(params["set"]), 5) // round to nearest 5
|
||||
amount = round(text2num(params["amount"]), 5) // round to nearest 5
|
||||
if (amount < 0) // Since the user can actually type the commands himself, some sanity checking
|
||||
amount = 0
|
||||
if (amount > 100)
|
||||
|
||||
@@ -87,6 +87,7 @@
|
||||
if("temperature")
|
||||
desired_temp = Clamp(input("Please input the target temperature", name) as num, 0, 1000)
|
||||
if("eject")
|
||||
on = FALSE
|
||||
eject_beaker()
|
||||
return 1
|
||||
|
||||
@@ -95,10 +96,10 @@
|
||||
return
|
||||
ui_interact(user)
|
||||
|
||||
/obj/machinery/chem_heater/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 0)
|
||||
ui = SSnano.try_update_ui(user, src, ui_key, ui, force_open = force_open)
|
||||
/obj/machinery/chem_heater/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open = force_open)
|
||||
if (!ui)
|
||||
ui = new(user, src, ui_key, "chem_heater", name, 350, 400)
|
||||
ui = new(user, src, ui_key, "chem_heater", name, 275, 400)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/chem_heater/get_ui_data()
|
||||
|
||||
@@ -141,9 +141,8 @@
|
||||
*/
|
||||
|
||||
/datum/reagent/water/reaction_obj(obj/O, reac_volume)
|
||||
if(istype(O,/obj/item))
|
||||
var/obj/item/Item = O
|
||||
Item.extinguish()
|
||||
if(istype(O))
|
||||
O.extinguish()
|
||||
|
||||
// Monkey cube
|
||||
if(istype(O,/obj/item/weapon/reagent_containers/food/snacks/monkeycube))
|
||||
@@ -163,10 +162,11 @@
|
||||
*/
|
||||
|
||||
/datum/reagent/water/reaction_mob(mob/living/M, method=TOUCH, reac_volume)//Splashing people with water can help put them out!
|
||||
if(!istype(M, /mob/living))
|
||||
if(!istype(M))
|
||||
return
|
||||
if(method == TOUCH)
|
||||
M.adjust_fire_stacks(-(reac_volume / 10))
|
||||
M.ExtinguishMob()
|
||||
..()
|
||||
|
||||
/datum/reagent/water/holywater
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
icon_state = null
|
||||
w_class = 1
|
||||
var/amount_per_transfer_from_this = 5
|
||||
var/list/possible_transfer_amounts = list(5,10,15,25,30)
|
||||
var/list/possible_transfer_amounts = list(5,10,15,20,25,30)
|
||||
var/volume = 30
|
||||
var/list/list_reagents = null
|
||||
var/spawned_disease = null
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/obj/item/weapon/reagent_containers/glass
|
||||
name = "glass"
|
||||
amount_per_transfer_from_this = 10
|
||||
possible_transfer_amounts = list(5, 10, 15, 25, 30, 50)
|
||||
possible_transfer_amounts = list(5, 10, 15, 20, 25, 30, 50)
|
||||
volume = 50
|
||||
flags = OPENCONTAINER
|
||||
spillable = 1
|
||||
@@ -197,7 +197,7 @@
|
||||
materials = list(MAT_GLASS=2500)
|
||||
volume = 100
|
||||
amount_per_transfer_from_this = 10
|
||||
possible_transfer_amounts = list(5,10,15,25,30,50,100)
|
||||
possible_transfer_amounts = list(5,10,15,20,25,30,50,100)
|
||||
flags = OPENCONTAINER
|
||||
|
||||
/obj/item/weapon/reagent_containers/glass/beaker/noreact
|
||||
@@ -216,7 +216,7 @@
|
||||
materials = list(MAT_GLASS=5000)
|
||||
volume = 300
|
||||
amount_per_transfer_from_this = 10
|
||||
possible_transfer_amounts = list(5,10,15,25,30,50,100,300)
|
||||
possible_transfer_amounts = list(5,10,15,20,25,30,50,100,300)
|
||||
flags = OPENCONTAINER
|
||||
|
||||
/obj/item/weapon/reagent_containers/glass/beaker/cryoxadone
|
||||
@@ -253,7 +253,7 @@
|
||||
materials = list(MAT_METAL=200)
|
||||
w_class = 3
|
||||
amount_per_transfer_from_this = 20
|
||||
possible_transfer_amounts = list(10,20,30,50,70)
|
||||
possible_transfer_amounts = list(10,15,20,25,30,50,70)
|
||||
volume = 70
|
||||
flags = OPENCONTAINER | BLOCKHAIR
|
||||
slot_flags = SLOT_HEAD
|
||||
@@ -290,4 +290,4 @@
|
||||
. = ..()
|
||||
slot_equipment_priority.Insert(index, slot_head)
|
||||
return
|
||||
return ..()
|
||||
return ..()
|
||||
|
||||
@@ -114,7 +114,7 @@
|
||||
|
||||
/obj/item/weapon/stock_parts/matter_bin
|
||||
name = "matter bin"
|
||||
desc = "A container for hold compressed matter awaiting re-construction."
|
||||
desc = "A container designed to hold compressed matter awaiting reconstruction."
|
||||
icon_state = "matter_bin"
|
||||
origin_tech = "materials=1"
|
||||
materials = list(MAT_METAL=80)
|
||||
@@ -155,7 +155,7 @@
|
||||
|
||||
/obj/item/weapon/stock_parts/matter_bin/adv
|
||||
name = "advanced matter bin"
|
||||
desc = "A container for hold compressed matter awaiting re-construction."
|
||||
desc = "A container designed to hold compressed matter awaiting reconstruction."
|
||||
icon_state = "advanced_matter_bin"
|
||||
origin_tech = "materials=3"
|
||||
rating = 2
|
||||
@@ -197,7 +197,7 @@
|
||||
|
||||
/obj/item/weapon/stock_parts/matter_bin/super
|
||||
name = "super matter bin"
|
||||
desc = "A container for hold compressed matter awaiting re-construction."
|
||||
desc = "A container designed to hold compressed matter awaiting reconstruction."
|
||||
icon_state = "super_matter_bin"
|
||||
origin_tech = "materials=5"
|
||||
rating = 3
|
||||
@@ -239,7 +239,7 @@
|
||||
|
||||
/obj/item/weapon/stock_parts/matter_bin/bluespace
|
||||
name = "bluespace matter bin"
|
||||
desc = "A container for hold compressed matter awaiting re-construction."
|
||||
desc = "A container designed to hold compressed matter awaiting reconstruction."
|
||||
icon_state = "bluespace_matter_bin"
|
||||
origin_tech = "materials=6"
|
||||
rating = 4
|
||||
@@ -301,4 +301,4 @@
|
||||
icon = 'icons/obj/stock_parts.dmi'
|
||||
icon_state = "capacitor"
|
||||
desc = "A debug item for research."
|
||||
origin_tech = "materials=8;programming=8;magnets=8;powerstorage=8;bluespace=8;combat=8;biotech=8;syndicate=8;engineering=8;plasmatech=8"
|
||||
origin_tech = "materials=8;programming=8;magnets=8;powerstorage=8;bluespace=8;combat=8;biotech=8;syndicate=8;engineering=8;plasmatech=8"
|
||||
|
||||
@@ -1,41 +1,36 @@
|
||||
/**
|
||||
* NanoUI External
|
||||
* tgui external
|
||||
*
|
||||
* Contains all external NanoUI declarations.
|
||||
*
|
||||
* /tg/station user interface library
|
||||
* thanks to baystation12
|
||||
*
|
||||
* modified by neersighted
|
||||
* Contains all external tgui declarations.
|
||||
**/
|
||||
|
||||
/**
|
||||
* public
|
||||
*
|
||||
* Used to open and update NanoUIs.
|
||||
* If this proc is not implemented properly, the NanoUI will not update correctly.
|
||||
* Used to open and update UIs.
|
||||
* If this proc is not implemented properly, the UI will not update correctly.
|
||||
*
|
||||
* required user mob The mob who opened/is using the NanoUI.
|
||||
* optional ui_key string The ui_key of the NanoUI.
|
||||
* optional ui datum/nanoui The UI to be updated, if it exists.
|
||||
* required user mob The mob who opened/is using the UI.
|
||||
* optional ui_key string The ui_key of the UI.
|
||||
* optional ui datum/tgui The UI to be updated, if it exists.
|
||||
* optional force_open bool If the UI should be re-opened instead of updated.
|
||||
* optional master_ui datum/nanoui The parent NanoUI.
|
||||
* optional state datum/nano_state The state used to determine status.
|
||||
* optional master_ui datum/tgui The parent UI.
|
||||
* optional state datum/ui_state The state used to determine status.
|
||||
**/
|
||||
/atom/movable/proc/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, \
|
||||
force_open = 0, datum/nano_ui/master_ui = null, \
|
||||
datum/nano_state/state = default_state)
|
||||
/atom/movable/proc/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, \
|
||||
force_open = 0, datum/tgui/master_ui = null, \
|
||||
datum/ui_state/state = default_state)
|
||||
return -1 // Sorta implemented.
|
||||
|
||||
/**
|
||||
* public
|
||||
*
|
||||
* Data to be sent to the NanoUI.
|
||||
* This must be implemented for a NanoUI to work.
|
||||
* Data to be sent to the UI.
|
||||
* This must be implemented for a UI to work.
|
||||
*
|
||||
* required user mob The mob interacting with the NanoUI.
|
||||
* required user mob The mob interacting with the UI.
|
||||
*
|
||||
* return list Data to be sent to the NanoUI.
|
||||
* return list Data to be sent to the UI.
|
||||
**/
|
||||
/atom/movable/proc/get_ui_data(mob/user)
|
||||
return list() // Not implemented.
|
||||
@@ -44,7 +39,7 @@
|
||||
/**
|
||||
* public
|
||||
*
|
||||
* Called on a NanoUI when the UI receieves a href.
|
||||
* Called on a UI when the UI receieves a href.
|
||||
* Think of this as Topic().
|
||||
*
|
||||
* required action string The action/button that has been invoked by the user.
|
||||
@@ -59,34 +54,34 @@
|
||||
/**
|
||||
* private
|
||||
*
|
||||
* The NanoUI's host object (usually src_object).
|
||||
* Used internally by nano_state(s).
|
||||
* The UI's host object (usually src_object).
|
||||
* Used internally by ui_state(s).
|
||||
**/
|
||||
/atom/proc/nano_host()
|
||||
/atom/proc/ui_host()
|
||||
return src
|
||||
|
||||
/**
|
||||
* global
|
||||
*
|
||||
* Used to track NanoUIs for a mob.
|
||||
* Used to track UIs for a mob.
|
||||
**/
|
||||
/mob/var/list/open_uis = list()
|
||||
|
||||
/**
|
||||
* verb
|
||||
*
|
||||
* Called by NanoUIs when they are closed.
|
||||
* Called by UIs when they are closed.
|
||||
* Must be a verb so winset() can call it.
|
||||
*
|
||||
* required uiref ref The UI that was closed.
|
||||
**/
|
||||
/client/verb/nanoclose(uiref as text)
|
||||
/client/verb/uiclose(uiref as text)
|
||||
// Name the verb, and hide it from the user panel.
|
||||
set name = "nanoclose"
|
||||
set name = "uiclose"
|
||||
set hidden = 1
|
||||
|
||||
// Get the UI based on the ref.
|
||||
var/datum/nanoui/ui = locate(uiref)
|
||||
var/datum/tgui/ui = locate(uiref)
|
||||
|
||||
// If we found the UI, close it.
|
||||
if(istype(ui))
|
||||
@@ -0,0 +1,12 @@
|
||||
/**
|
||||
* tgui state: admin_state
|
||||
*
|
||||
* Checks that the user is an admin, end-of-story.
|
||||
**/
|
||||
|
||||
/var/global/datum/ui_state/admin_state/admin_state = new()
|
||||
|
||||
/datum/ui_state/admin_state/can_use_topic(atom/movable/src_object, mob/user)
|
||||
if(check_rights_for(user.client, R_ADMIN))
|
||||
return UI_INTERACTIVE
|
||||
return UI_CLOSE
|
||||
@@ -0,0 +1,12 @@
|
||||
/**
|
||||
* tgui state: conscious_state
|
||||
*
|
||||
* Only checks if the user is conscious.
|
||||
**/
|
||||
|
||||
/var/global/datum/ui_state/conscious_state/conscious_state = new()
|
||||
|
||||
/datum/ui_state/conscious_state/can_use_topic(atom/movable/src_object, mob/user)
|
||||
if(user.stat == CONSCIOUS)
|
||||
return UI_INTERACTIVE
|
||||
return UI_CLOSE
|
||||
@@ -0,0 +1,12 @@
|
||||
/**
|
||||
* tgui state: contained_state
|
||||
*
|
||||
* Checks that the user is inside the src_object.
|
||||
**/
|
||||
|
||||
/var/global/datum/ui_state/contained_state/contained_state = new()
|
||||
|
||||
/datum/ui_state/contained_state/can_use_topic(atom/movable/src_object, mob/user)
|
||||
if(!src_object.contains(user))
|
||||
return UI_CLOSE
|
||||
return user.shared_ui_interaction(src_object)
|
||||
@@ -0,0 +1,12 @@
|
||||
/**
|
||||
* tgui state: deep_inventory_state
|
||||
*
|
||||
* Checks that the src_object is in the user's fist-level (backpack, webbing, etc) inventory.
|
||||
**/
|
||||
|
||||
/var/global/datum/ui_state/deep_inventory_state/deep_inventory_state = new()
|
||||
|
||||
/datum/ui_state/deep_inventory_state/can_use_topic(atom/movable/src_object, mob/user)
|
||||
if(!user.contains(src_object))
|
||||
return UI_CLOSE
|
||||
return user.shared_ui_interaction(src_object)
|
||||
@@ -1,60 +1,60 @@
|
||||
/**
|
||||
* NanoUI State: default_state
|
||||
* tgui state: default_state
|
||||
*
|
||||
* Checks a number of things -- mostly physical distance for humans and view for robots.
|
||||
**/
|
||||
|
||||
/var/global/datum/nano_state/default/default_state = new()
|
||||
/var/global/datum/ui_state/default/default_state = new()
|
||||
|
||||
/datum/nano_state/default/can_use_topic(atom/movable/src_object, mob/user)
|
||||
/datum/ui_state/default/can_use_topic(atom/movable/src_object, mob/user)
|
||||
return user.default_can_use_topic(src_object) // Call the individual mob-overriden procs.
|
||||
|
||||
/mob/proc/default_can_use_topic(atom/movable/src_object)
|
||||
return NANO_CLOSE // Don't allow interaction by default.
|
||||
return UI_CLOSE // Don't allow interaction by default.
|
||||
|
||||
/mob/living/default_can_use_topic(atom/movable/src_object)
|
||||
. = shared_nano_interaction(src_object)
|
||||
if(. > NANO_CLOSE)
|
||||
. = min(., shared_living_nano_distance(src_object)) // Check the distance...
|
||||
if(. == NANO_INTERACTIVE) // Non-human living mobs can only look, not touch.
|
||||
return NANO_UPDATE
|
||||
. = shared_ui_interaction(src_object)
|
||||
if(. > UI_CLOSE)
|
||||
. = min(., shared_living_ui_distance(src_object)) // Check the distance...
|
||||
if(. == UI_INTERACTIVE) // Non-human living mobs can only look, not touch.
|
||||
return UI_UPDATE
|
||||
|
||||
/mob/living/carbon/human/default_can_use_topic(atom/movable/src_object)
|
||||
. = shared_nano_interaction(src_object)
|
||||
if(. > NANO_CLOSE)
|
||||
. = min(., shared_living_nano_distance(src_object)) // Check the distance...
|
||||
. = shared_ui_interaction(src_object)
|
||||
if(. > UI_CLOSE)
|
||||
. = min(., shared_living_ui_distance(src_object)) // Check the distance...
|
||||
// Derp a bit if we have brain loss.
|
||||
if(prob(getBrainLoss()))
|
||||
return NANO_UPDATE
|
||||
return UI_UPDATE
|
||||
|
||||
/mob/living/silicon/robot/default_can_use_topic(atom/movable/src_object)
|
||||
. = shared_nano_interaction(src_object)
|
||||
if(. <= NANO_DISABLED)
|
||||
. = shared_ui_interaction(src_object)
|
||||
if(. <= UI_DISABLED)
|
||||
return
|
||||
|
||||
// Robots can interact with anything they can see.
|
||||
if(get_dist(src, src_object) <= src.client.view)
|
||||
return NANO_INTERACTIVE
|
||||
return NANO_DISABLED // Otherwise they can keep the UI open.
|
||||
return UI_INTERACTIVE
|
||||
return UI_DISABLED // Otherwise they can keep the UI open.
|
||||
|
||||
/mob/living/silicon/ai/default_can_use_topic(atom/movable/src_object)
|
||||
. = shared_nano_interaction(src_object)
|
||||
if(. < NANO_INTERACTIVE)
|
||||
. = shared_ui_interaction(src_object)
|
||||
if(. < UI_INTERACTIVE)
|
||||
return
|
||||
|
||||
// The AI can interact with anything it can see nearby, or with cameras.
|
||||
if((get_dist(src, src_object) <= src.client.view) || cameranet.checkTurfVis(get_turf_pixel(src_object)))
|
||||
return NANO_INTERACTIVE
|
||||
return NANO_CLOSE
|
||||
return UI_INTERACTIVE
|
||||
return UI_CLOSE
|
||||
|
||||
/mob/living/simple_animal/drone/default_can_use_topic(atom/movable/src_object)
|
||||
. = shared_nano_interaction(src_object)
|
||||
if(. > NANO_CLOSE)
|
||||
. = min(., shared_living_nano_distance(src_object)) // Drones can only use things they're near.
|
||||
. = shared_ui_interaction(src_object)
|
||||
if(. > UI_CLOSE)
|
||||
. = min(., shared_living_ui_distance(src_object)) // Drones can only use things they're near.
|
||||
|
||||
/mob/living/silicon/pai/default_can_use_topic(atom/movable/src_object)
|
||||
// pAIs can only use themselves and the owner's radio.
|
||||
if((src_object == src || src_object == radio) && !stat)
|
||||
return NANO_INTERACTIVE
|
||||
return UI_INTERACTIVE
|
||||
else
|
||||
return ..()
|
||||
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
* tgui state: hands_state
|
||||
*
|
||||
* Checks that the src_object is in the user's hands.
|
||||
**/
|
||||
|
||||
/var/global/datum/ui_state/hands_state/hands_state = new()
|
||||
|
||||
/datum/ui_state/hands_state/can_use_topic(atom/movable/src_object, mob/user)
|
||||
. = user.shared_ui_interaction(src_object)
|
||||
if(. > UI_CLOSE)
|
||||
return min(., user.hands_can_use_topic(src_object))
|
||||
|
||||
/mob/proc/hands_can_use_topic(atom/movable/src_object)
|
||||
return UI_CLOSE
|
||||
|
||||
/mob/living/hands_can_use_topic(atom/movable/src_object)
|
||||
if(src_object in get_both_hands(src))
|
||||
return UI_INTERACTIVE
|
||||
return UI_CLOSE
|
||||
@@ -0,0 +1,12 @@
|
||||
/**
|
||||
* tgui state: inventory_state
|
||||
*
|
||||
* Checks that the src_object is in the user's top-level (hand, ear, pocket, belt, etc) inventory.
|
||||
**/
|
||||
|
||||
/var/global/datum/ui_state/inventory_state/inventory_state = new()
|
||||
|
||||
/datum/ui_state/inventory_state/can_use_topic(atom/movable/src_object, mob/user)
|
||||
if(!(src_object in user))
|
||||
return UI_CLOSE
|
||||
return user.shared_ui_interaction(src_object)
|
||||
@@ -1,22 +1,22 @@
|
||||
/**
|
||||
* NanoUI State: notcontained_state
|
||||
* tgui state: notcontained_state
|
||||
*
|
||||
* Checks that the user is not inside src_object, and then makes the default checks.
|
||||
**/
|
||||
|
||||
/var/global/datum/nano_state/notcontained_state/notcontained_state = new()
|
||||
/var/global/datum/ui_state/notcontained_state/notcontained_state = new()
|
||||
|
||||
/datum/nano_state/notcontained_state/can_use_topic(atom/movable/src_object, mob/user)
|
||||
. = user.shared_nano_interaction(src_object)
|
||||
if(. > NANO_CLOSE)
|
||||
/datum/ui_state/notcontained_state/can_use_topic(atom/movable/src_object, mob/user)
|
||||
. = user.shared_ui_interaction(src_object)
|
||||
if(. > UI_CLOSE)
|
||||
return min(., user.notcontained_can_use_topic(src_object))
|
||||
|
||||
/mob/proc/notcontained_can_use_topic(atom/movable/src_object)
|
||||
return NANO_CLOSE
|
||||
return UI_CLOSE
|
||||
|
||||
/mob/living/notcontained_can_use_topic(atom/movable/src_object)
|
||||
if(src_object.contains(src))
|
||||
return NANO_CLOSE // Close if we're inside it.
|
||||
return UI_CLOSE // Close if we're inside it.
|
||||
return default_can_use_topic(src_object)
|
||||
|
||||
/mob/living/silicon/notcontained_can_use_topic(atom/movable/src_object)
|
||||
@@ -0,0 +1,21 @@
|
||||
/**
|
||||
* tgui state: physical_state
|
||||
*
|
||||
* Short-circuits the default state to only check physical distance.
|
||||
**/
|
||||
|
||||
/var/global/datum/ui_state/physical/physical_state = new()
|
||||
|
||||
/datum/ui_state/physical/can_use_topic(atom/movable/src_object, mob/user)
|
||||
. = user.shared_ui_interaction(src_object)
|
||||
if(. > UI_CLOSE)
|
||||
return min(., user.physical_can_use_topic(src_object))
|
||||
|
||||
/mob/proc/physical_can_use_topic(atom/movable/src_object)
|
||||
return UI_CLOSE
|
||||
|
||||
/mob/living/physical_can_use_topic(atom/movable/src_object)
|
||||
return shared_living_ui_distance(src_object)
|
||||
|
||||
/mob/living/silicon/physical_can_use_topic(atom/movable/src_object)
|
||||
return max(UI_UPDATE, shared_living_ui_distance(src_object)) // Silicons can always see.
|
||||
@@ -0,0 +1,12 @@
|
||||
/**
|
||||
* tgui state: self_state
|
||||
*
|
||||
* Only checks that the user and src_object are the same.
|
||||
**/
|
||||
|
||||
/var/global/datum/ui_state/self_state/self_state = new()
|
||||
|
||||
/datum/ui_state/self_state/can_use_topic(atom/movable/src_object, mob/user)
|
||||
if(src_object != user)
|
||||
return UI_CLOSE
|
||||
return user.shared_ui_interaction(src_object)
|
||||
@@ -0,0 +1,112 @@
|
||||
/**
|
||||
* tgui states
|
||||
*
|
||||
* Base state and helpers for states. Just does some sanity checks, implement a state for in-depth checks.
|
||||
**/
|
||||
|
||||
/**
|
||||
* public
|
||||
*
|
||||
* Checks if a user can use src_object's UI, under the given state.
|
||||
*
|
||||
* required user mob The mob who opened/is using the UI.
|
||||
* required state datum/ui_state The state to check.
|
||||
*
|
||||
* return UI_state The state of the UI.
|
||||
**/
|
||||
/atom/proc/ui_state(mob/user, datum/ui_state/state)
|
||||
var/src_object = ui_host()
|
||||
|
||||
if(istype(user, /mob/dead/observer)) // Special-case ghosts.
|
||||
if(check_rights_for(user.client, R_ADMIN))
|
||||
return UI_INTERACTIVE // Admins can interact anyway.
|
||||
if(get_dist(src_object, src) > user.client.view)
|
||||
return UI_CLOSE // Keep ghosts from opening too many UIs.
|
||||
return UI_UPDATE // Ghosts can only view.
|
||||
return state.can_use_topic(src_object, user) // Check if the state allows interaction.
|
||||
|
||||
/**
|
||||
* private
|
||||
*
|
||||
* Checks if a user can use src_object's UI, and returns the state.
|
||||
* Can call a mob proc, which allows overrides for each mob.
|
||||
*
|
||||
* required src_object atom/movable The object which owns the UI.
|
||||
* required user mob The mob who opened/is using the UI.
|
||||
*
|
||||
* return UI_state The state of the UI.
|
||||
**/
|
||||
/datum/ui_state/proc/can_use_topic(atom/movable/src_object, mob/user)
|
||||
return UI_CLOSE // Don't allow interaction by default.
|
||||
|
||||
|
||||
/**
|
||||
* public
|
||||
*
|
||||
* Standard interaction/sanity checks. Different mob types may have overrides.
|
||||
*
|
||||
* return UI_state The state of the UI.
|
||||
**/
|
||||
/mob/proc/shared_ui_interaction(atom/movable/src_object)
|
||||
if(!client || stat) // Close UIs if mindless or dead/unconcious.
|
||||
return UI_CLOSE
|
||||
// Update UIs if incapicitated but concious.
|
||||
else if(incapacitated() || lying)
|
||||
return UI_UPDATE
|
||||
return UI_INTERACTIVE
|
||||
|
||||
/mob/living/carbon/human/shared_ui_interaction(atom/movable/src_object)
|
||||
// If we have telekinesis and remain close enough, allow interaction.
|
||||
if(dna.check_mutation(TK))
|
||||
if(tkMaxRangeCheck(src, src_object))
|
||||
return UI_INTERACTIVE
|
||||
return ..()
|
||||
|
||||
/mob/living/silicon/ai/shared_ui_interaction(atom/movable/src_object)
|
||||
if(lacks_power()) // Close UIs if the AI is unpowered.
|
||||
return UI_CLOSE
|
||||
return ..()
|
||||
|
||||
/mob/living/silicon/robot/shared_ui_interaction(atom/movable/src_object)
|
||||
if(cell.charge <= 0) // Close UIs if the Borg is unpowered.
|
||||
return UI_CLOSE
|
||||
if(lockcharge) // Disable UIs if the Borg is locked.
|
||||
return UI_DISABLED
|
||||
return ..()
|
||||
|
||||
/**
|
||||
* public
|
||||
*
|
||||
* Check the distance for a living mob.
|
||||
* Really only used for checks outside the context of a mob.
|
||||
* Otherwise, use shared_living_ui_distance().
|
||||
*
|
||||
* required src_object atom/movable The object which owns the UI.
|
||||
* required user mob The mob who opened/is using the UI.
|
||||
*
|
||||
* return UI_state The state of the UI.
|
||||
**/
|
||||
/atom/proc/contents_ui_distance(atom/movable/src_object, mob/living/user)
|
||||
return user.shared_living_ui_distance(src_object) // Just call this mob's check.
|
||||
|
||||
/**
|
||||
* public
|
||||
*
|
||||
* Distance versus interaction check.
|
||||
*
|
||||
* required src_object atom/movable The object which owns the UI.
|
||||
*
|
||||
* return UI_state The state of the UI.
|
||||
**/
|
||||
/mob/living/proc/shared_living_ui_distance(atom/movable/src_object)
|
||||
if(!(src_object in view(4, src))) // If the object is out of view, close it.
|
||||
return UI_CLOSE
|
||||
|
||||
var/dist = get_dist(src_object, src)
|
||||
if(dist <= 1) // Open and interact if 1-0 tiles away.
|
||||
return UI_INTERACTIVE
|
||||
else if(dist <= 2) // View only if 2-3 tiles away.
|
||||
return UI_UPDATE
|
||||
else if(dist <= 5) // Disable if 5 tiles away.
|
||||
return UI_DISABLED
|
||||
return UI_CLOSE // Otherwise, we got nothing.
|
||||
@@ -1,14 +1,14 @@
|
||||
/**
|
||||
* NanoUI State: z_state
|
||||
* tgui state: z_state
|
||||
*
|
||||
* Only checks that the Z-level of the user and src_object are the same.
|
||||
**/
|
||||
|
||||
/var/global/datum/nano_state/z_state/z_state = new()
|
||||
/var/global/datum/ui_state/z_state/z_state = new()
|
||||
|
||||
/datum/nano_state/z_state/can_use_topic(atom/movable/src_object, mob/user)
|
||||
/datum/ui_state/z_state/can_use_topic(atom/movable/src_object, mob/user)
|
||||
var/turf/turf_obj = get_turf(src_object)
|
||||
var/turf/turf_usr = get_turf(user)
|
||||
if(!turf_obj || !turf_usr || !(turf_obj.z == turf_usr.z))
|
||||
return NANO_CLOSE
|
||||
return NANO_INTERACTIVE
|
||||
return UI_CLOSE
|
||||
return UI_INTERACTIVE
|
||||
@@ -1,34 +1,29 @@
|
||||
/**
|
||||
* NanoUI Subsystem
|
||||
* tgui subsystem
|
||||
*
|
||||
* Contains all NanoUI state and subsystem code.
|
||||
*
|
||||
* /tg/station user interface library
|
||||
* thanks to baystation12
|
||||
*
|
||||
* modified by neersighted
|
||||
* Contains all tgui state and subsystem code.
|
||||
**/
|
||||
|
||||
/**
|
||||
* public
|
||||
*
|
||||
* Get a open NanoUI given a user, src_object, and ui_key and try to update it with data.
|
||||
* Get a open UI given a user, src_object, and ui_key and try to update it with data.
|
||||
*
|
||||
* required user mob The mob who opened/is using the NanoUI.
|
||||
* required src_object atom/movable The object which owns the NanoUI.
|
||||
* required ui_key string The ui_key of the NanoUI.
|
||||
* optional ui datum/nanoui The UI to be updated, if it exists.
|
||||
* required user mob The mob who opened/is using the UI.
|
||||
* required src_object atom/movable The object which owns the UI.
|
||||
* required ui_key string The ui_key of the UI.
|
||||
* optional ui datum/tgui The UI to be updated, if it exists.
|
||||
* optional data list The data to update the UI with, if it exists.
|
||||
* optional force_open bool If the UI should be re-opened instead of updated.
|
||||
*
|
||||
* return datum/nanoui The found NanoUI.
|
||||
* return datum/tgui The found UI.
|
||||
**/
|
||||
/datum/subsystem/nano/proc/try_update_ui(mob/user, atom/movable/src_object, ui_key, datum/nanoui/ui, \
|
||||
/datum/subsystem/tgui/proc/try_update_ui(mob/user, atom/movable/src_object, ui_key, datum/tgui/ui, \
|
||||
list/data = null, force_open = 0)
|
||||
if(!data)
|
||||
data = src_object.get_ui_data(user)
|
||||
|
||||
if(isnull(ui)) // No NanoUI was passed, so look for one.
|
||||
if(isnull(ui)) // No UI was passed, so look for one.
|
||||
ui = get_open_ui(user, src_object, ui_key)
|
||||
|
||||
if(!isnull(ui))
|
||||
@@ -43,22 +38,22 @@
|
||||
/**
|
||||
* private
|
||||
*
|
||||
* Get a open NanoUI given a user, src_object, and ui_key.
|
||||
* Get a open UI given a user, src_object, and ui_key.
|
||||
*
|
||||
* required user mob The mob who opened/is using the NanoUI.
|
||||
* required src_object atom/movable The object which owns the NanoUI.
|
||||
* required ui_key string The ui_key of the NanoUI.
|
||||
* required user mob The mob who opened/is using the UI.
|
||||
* required src_object atom/movable The object which owns the UI.
|
||||
* required ui_key string The ui_key of the UI.
|
||||
*
|
||||
* return datum/nanoui The found NanoUI.
|
||||
* return datum/tgui The found UI.
|
||||
**/
|
||||
/datum/subsystem/nano/proc/get_open_ui(mob/user, atom/movable/src_object, ui_key)
|
||||
/datum/subsystem/tgui/proc/get_open_ui(mob/user, atom/movable/src_object, ui_key)
|
||||
var/src_object_key = "\ref[src_object]"
|
||||
if(isnull(open_uis[src_object_key]) || !istype(open_uis[src_object_key], /list))
|
||||
return null // No UIs open.
|
||||
else if(isnull(open_uis[src_object_key][ui_key]) || !istype(open_uis[src_object_key][ui_key], /list))
|
||||
return null // No UIs open for this object.
|
||||
|
||||
for(var/datum/nanoui/ui in open_uis[src_object_key][ui_key]) // Find UIs for this object.
|
||||
for(var/datum/tgui/ui in open_uis[src_object_key][ui_key]) // Find UIs for this object.
|
||||
if(ui.user == user) // Make sure we have the right user
|
||||
return ui
|
||||
|
||||
@@ -67,21 +62,21 @@
|
||||
/**
|
||||
* private
|
||||
*
|
||||
* Update all NanoUIs attached to src_object.
|
||||
* Update all UIs attached to src_object.
|
||||
*
|
||||
* required src_object atom/movable The object which owns the NanoUIs.
|
||||
* required src_object atom/movable The object which owns the UIs.
|
||||
*
|
||||
* return int The number of NanoUIs updated.
|
||||
* return int The number of UIs updated.
|
||||
**/
|
||||
/datum/subsystem/nano/proc/update_uis(atom/movable/src_object)
|
||||
/datum/subsystem/tgui/proc/update_uis(atom/movable/src_object)
|
||||
var/src_object_key = "\ref[src_object]"
|
||||
if(isnull(open_uis[src_object_key]) || !istype(open_uis[src_object_key], /list))
|
||||
return 0 // Couldn't find any UIs for this object.
|
||||
|
||||
var/update_count = 0
|
||||
for(var/ui_key in open_uis[src_object_key])
|
||||
for(var/datum/nanoui/ui in open_uis[src_object_key][ui_key])
|
||||
if(ui && ui.src_object && ui.user && ui.src_object.nano_host()) // Check the UI is valid.
|
||||
for(var/datum/tgui/ui in open_uis[src_object_key][ui_key])
|
||||
if(ui && ui.src_object && ui.user && ui.src_object.ui_host()) // Check the UI is valid.
|
||||
ui.process(force = 1) // Update the UI.
|
||||
update_count++ // Count each UI we update.
|
||||
return update_count
|
||||
@@ -89,21 +84,21 @@
|
||||
/**
|
||||
* private
|
||||
*
|
||||
* Close all NanoUIs attached to src_object.
|
||||
* Close all UIs attached to src_object.
|
||||
*
|
||||
* required src_object atom/movable The object which owns the NanoUIs.
|
||||
* required src_object atom/movable The object which owns the UIs.
|
||||
*
|
||||
* return int The number of NanoUIs closed.
|
||||
* return int The number of UIs closed.
|
||||
**/
|
||||
/datum/subsystem/nano/proc/close_uis(atom/movable/src_object)
|
||||
/datum/subsystem/tgui/proc/close_uis(atom/movable/src_object)
|
||||
var/src_object_key = "\ref[src_object]"
|
||||
if(isnull(open_uis[src_object_key]) || !istype(open_uis[src_object_key], /list))
|
||||
return 0 // Couldn't find any UIs for this object.
|
||||
|
||||
var/close_count = 0
|
||||
for(var/ui_key in open_uis[src_object_key])
|
||||
for(var/datum/nanoui/ui in open_uis[src_object_key][ui_key])
|
||||
if(ui && ui.src_object && ui.user && ui.src_object.nano_host()) // Check the UI is valid.
|
||||
for(var/datum/tgui/ui in open_uis[src_object_key][ui_key])
|
||||
if(ui && ui.src_object && ui.user && ui.src_object.ui_host()) // Check the UI is valid.
|
||||
ui.close() // Close the UI.
|
||||
close_count++ // Count each UI we close.
|
||||
return close_count
|
||||
@@ -111,20 +106,20 @@
|
||||
/**
|
||||
* private
|
||||
*
|
||||
* Update all NanoUIs belonging to a user.
|
||||
* Update all UIs belonging to a user.
|
||||
*
|
||||
* required user mob The mob who opened/is using the NanoUI.
|
||||
* required user mob The mob who opened/is using the UI.
|
||||
* optional src_object atom/movable If provided, only update UIs belonging this atom.
|
||||
* optional ui_key string If provided, only update UIs with this UI key.
|
||||
*
|
||||
* return int The number of NanoUIs updated.
|
||||
* return int The number of UIs updated.
|
||||
**/
|
||||
/datum/subsystem/nano/proc/update_user_uis(mob/user, atom/movable/src_object = null, ui_key = null)
|
||||
/datum/subsystem/tgui/proc/update_user_uis(mob/user, atom/movable/src_object = null, ui_key = null)
|
||||
if(isnull(user.open_uis) || !istype(user.open_uis, /list) || open_uis.len == 0)
|
||||
return 0 // Couldn't find any UIs for this user.
|
||||
|
||||
var/update_count = 0
|
||||
for(var/datum/nanoui/ui in user.open_uis)
|
||||
for(var/datum/tgui/ui in user.open_uis)
|
||||
if((isnull(src_object) || !isnull(src_object) && ui.src_object == src_object) && (isnull(ui_key) || !isnull(ui_key) && ui.ui_key == ui_key))
|
||||
ui.process(force = 1) // Update the UI.
|
||||
update_count++ // Count each UI we upadte.
|
||||
@@ -133,20 +128,20 @@
|
||||
/**
|
||||
* private
|
||||
*
|
||||
* Close all NanoUIs belonging to a user.
|
||||
* Close all UIs belonging to a user.
|
||||
*
|
||||
* required user mob The mob who opened/is using the NanoUI.
|
||||
* required user mob The mob who opened/is using the UI.
|
||||
* optional src_object atom/movable If provided, only update UIs belonging this atom.
|
||||
* optional ui_key string If provided, only update UIs with this UI key.
|
||||
*
|
||||
* return int The number of NanoUIs closed.
|
||||
* return int The number of UIs closed.
|
||||
**/
|
||||
/datum/subsystem/nano/proc/close_user_uis(mob/user, atom/movable/src_object = null, ui_key = null)
|
||||
/datum/subsystem/tgui/proc/close_user_uis(mob/user, atom/movable/src_object = null, ui_key = null)
|
||||
if(isnull(user.open_uis) || !istype(user.open_uis, /list) || open_uis.len == 0)
|
||||
return 0 // Couldn't find any UIs for this user.
|
||||
|
||||
var/close_count = 0
|
||||
for(var/datum/nanoui/ui in user.open_uis)
|
||||
for(var/datum/tgui/ui in user.open_uis)
|
||||
if((isnull(src_object) || !isnull(src_object) && ui.src_object == src_object) && (isnull(ui_key) || !isnull(ui_key) && ui.ui_key == ui_key))
|
||||
ui.close() // Close the UI.
|
||||
close_count++ // Count each UI we close.
|
||||
@@ -155,11 +150,11 @@
|
||||
/**
|
||||
* private
|
||||
*
|
||||
* Add a NanoUI to the list of open UIs.
|
||||
* Add a UI to the list of open UIs.
|
||||
*
|
||||
* required ui datum/nanoui The UI to be added.
|
||||
* required ui datum/tgui The UI to be added.
|
||||
**/
|
||||
/datum/subsystem/nano/proc/on_open(datum/nanoui/ui)
|
||||
/datum/subsystem/tgui/proc/on_open(datum/tgui/ui)
|
||||
var/src_object_key = "\ref[ui.src_object]"
|
||||
if(isnull(open_uis[src_object_key]) || !istype(open_uis[src_object_key], /list))
|
||||
open_uis[src_object_key] = list(ui.ui_key = list()) // Make a list for the ui_key and src_object.
|
||||
@@ -175,13 +170,13 @@
|
||||
/**
|
||||
* private
|
||||
*
|
||||
* Remove a NanoUI from the list of open UIs.
|
||||
* Remove a UI from the list of open UIs.
|
||||
*
|
||||
* required ui datum/nanoui The UI to be removed.
|
||||
* required ui datum/tgui The UI to be removed.
|
||||
*
|
||||
* return bool If the UI was removed or not.
|
||||
**/
|
||||
/datum/subsystem/nano/proc/on_close(datum/nanoui/ui)
|
||||
/datum/subsystem/tgui/proc/on_close(datum/tgui/ui)
|
||||
var/src_object_key = "\ref[ui.src_object]"
|
||||
if(isnull(open_uis[src_object_key]) || !istype(open_uis[src_object_key], /list))
|
||||
return 0 // It wasn't open.
|
||||
@@ -198,35 +193,35 @@
|
||||
/**
|
||||
* private
|
||||
*
|
||||
* Handle client logout, by closing all their NanoUIs.
|
||||
* Handle client logout, by closing all their UIs.
|
||||
*
|
||||
* required user mob The mob which logged out.
|
||||
*
|
||||
* return int The number of NanoUIs closed.
|
||||
* return int The number of UIs closed.
|
||||
**/
|
||||
/datum/subsystem/nano/proc/on_logout(mob/user)
|
||||
/datum/subsystem/tgui/proc/on_logout(mob/user)
|
||||
return close_user_uis(user)
|
||||
|
||||
/**
|
||||
* private
|
||||
*
|
||||
* Handle clients switching mobs, by transfering their NanoUIs.
|
||||
* Handle clients switching mobs, by transfering their UIs.
|
||||
*
|
||||
* required user source The client's original mob.
|
||||
* required user target The client's new mob.
|
||||
*
|
||||
* return bool If the NanoUIs were transferred.
|
||||
* return bool If the UIs were transferred.
|
||||
**/
|
||||
/datum/subsystem/nano/proc/on_transfer(mob/source, mob/target)
|
||||
/datum/subsystem/tgui/proc/on_transfer(mob/source, mob/target)
|
||||
if(!source || isnull(source.open_uis) || !istype(source.open_uis, /list) || open_uis.len == 0)
|
||||
return 0 // The old mob had no open NanoUIs.
|
||||
return 0 // The old mob had no open UIs.
|
||||
|
||||
if(isnull(target.open_uis) || !istype(target.open_uis, /list))
|
||||
target.open_uis = list() // Create a list for the new mob if needed.
|
||||
|
||||
for(var/datum/nanoui/ui in source.open_uis)
|
||||
for(var/datum/tgui/ui in source.open_uis)
|
||||
ui.user = target // Inform the UIs of their new owner.
|
||||
target.open_uis.Add(ui) // Transfer all the NanoUIs.
|
||||
target.open_uis.Add(ui) // Transfer all the UIs.
|
||||
|
||||
source.open_uis.Cut() // Clear the old list.
|
||||
return 1 // Let the caller know we did it.
|
||||
@@ -0,0 +1,349 @@
|
||||
/**
|
||||
* tgui
|
||||
*
|
||||
* /tg/station user interface library
|
||||
**/
|
||||
|
||||
/**
|
||||
* tgui datum (represents a UI).
|
||||
**/
|
||||
/datum/tgui
|
||||
var/mob/user // The mob who opened/is using the UI.
|
||||
var/atom/movable/src_object // The object which owns the UI.
|
||||
var/title // The title of te UI.
|
||||
var/ui_key // The ui_key of the UI. This allows multiple UIs for one src_object.
|
||||
var/window_id // The window_id for browse() and onclose().
|
||||
var/width = 0 // The window width.
|
||||
var/height = 0 // The window height
|
||||
var/window_options = list( // Extra options to winset().
|
||||
"focus" = 0,
|
||||
"titlebar" = 1,
|
||||
"can_resize" = 1,
|
||||
"can_minimize" = 1,
|
||||
"can_maximize" = 0,
|
||||
"can_close" = 1,
|
||||
"auto_format" = 0
|
||||
)
|
||||
var/atom/ref = null // An extra ref to call when the window is closed.
|
||||
var/style = "nanotrasen" // The style to be used for this UI.
|
||||
var/interface // The interface (template) to be used for this UI.
|
||||
var/auto_update = 1 // Update the UI every MC tick.
|
||||
var/list/initial_data // The data (and datastructure) used to initialize the UI.
|
||||
var/status = UI_INTERACTIVE // The status/visibility of the UI.
|
||||
var/datum/ui_state/state = null // Topic state used to determine status/interactability.
|
||||
var/datum/tgui/master_ui // The parent UI.
|
||||
var/list/datum/tgui/children = list() // Children of this UI.
|
||||
|
||||
/**
|
||||
* public
|
||||
*
|
||||
* Create a new UI.
|
||||
*
|
||||
* required user mob The mob who opened/is using the UI.
|
||||
* required src_object atom/movable The object which owns the UI.
|
||||
* required ui_key string The ui_key of the UI.
|
||||
* required interface string The interface used to render the UI.
|
||||
* optional title string The title of the UI.
|
||||
* optional width int The window width.
|
||||
* optional height int The window height.
|
||||
* optional ref atom An extra ref to use when the window is closed.
|
||||
* optional master_ui datum/tgui The parent UI.
|
||||
* optional state datum/ui_state The state used to determine status.
|
||||
*
|
||||
* return datum/tgui The requested UI.
|
||||
**/
|
||||
/datum/tgui/New(mob/user, atom/movable/src_object, ui_key, interface, \
|
||||
title, width = 0, height = 0, \
|
||||
atom/ref = null, datum/tgui/master_ui = null, \
|
||||
datum/ui_state/state = default_state)
|
||||
src.user = user
|
||||
src.src_object = src_object
|
||||
src.ui_key = ui_key
|
||||
src.window_id = "\ref[src_object]-[ui_key]"
|
||||
|
||||
set_interface(interface)
|
||||
|
||||
if(title)
|
||||
src.title = sanitize(title)
|
||||
if(width)
|
||||
src.width = width
|
||||
if(height)
|
||||
src.height = height
|
||||
|
||||
if(ref)
|
||||
src.ref = ref
|
||||
|
||||
src.master_ui = master_ui
|
||||
if(master_ui)
|
||||
master_ui.children += src
|
||||
src.state = state
|
||||
|
||||
var/datum/asset/assets = get_asset_datum(/datum/asset/simple/tgui)
|
||||
assets.send(user)
|
||||
|
||||
/**
|
||||
* public
|
||||
*
|
||||
* Open this UI (and initialize it with data).
|
||||
*
|
||||
* optional data list The data to intialize the UI with.
|
||||
**/
|
||||
/datum/tgui/proc/open(list/data = null)
|
||||
if(!user.client)
|
||||
return // Bail if there is no client.
|
||||
|
||||
update_status(push = 0) // Update the window status.
|
||||
if(status == UI_CLOSE)
|
||||
return // Bail if we should close.
|
||||
|
||||
if(!initial_data)
|
||||
if(!data) // If we don't have initial_data and data was not passed, get data from the src_object.
|
||||
data = src_object.get_ui_data(user)
|
||||
set_initial_data(data) // Otherwise use the passed data.
|
||||
|
||||
var/window_size = ""
|
||||
if(width && height) // If we have a width and height, use them.
|
||||
window_size = "size=[width]x[height];"
|
||||
|
||||
user << browse(get_html(), "window=[window_id];[window_size][list2params(window_options)]") // Open the window.
|
||||
winset(user, window_id, "on-close=\"uiclose \ref[src]\"") // Instruct the client to signal UI when the window is closed.
|
||||
SStgui.on_open(src)
|
||||
|
||||
/**
|
||||
* public
|
||||
*
|
||||
* Reinitialize the UI.
|
||||
* (Possibly with a new interface and/or data).
|
||||
*
|
||||
* optional template string The name of the new interface.
|
||||
* optional data list The new initial data.
|
||||
**/
|
||||
/datum/tgui/proc/reinitialize(interface, list/data)
|
||||
if(interface)
|
||||
set_interface(interface) // Set a new interface.
|
||||
if(data)
|
||||
set_initial_data(data) // Replace the initial_data.
|
||||
open()
|
||||
|
||||
/**
|
||||
* public
|
||||
*
|
||||
* Close the UI, and all its children.
|
||||
**/
|
||||
/datum/tgui/proc/close()
|
||||
user << browse(null, "window=[window_id]") // Close the window.
|
||||
SStgui.on_close(src)
|
||||
for(var/datum/tgui/child in children) // Loop through and close all children.
|
||||
child.close()
|
||||
|
||||
/**
|
||||
* public
|
||||
*
|
||||
* Sets the browse() window options for this UI.
|
||||
*
|
||||
* required window_options list The window options to set.
|
||||
**/
|
||||
/datum/tgui/proc/set_window_options(list/window_options)
|
||||
src.window_options = window_options
|
||||
|
||||
/**
|
||||
* public
|
||||
*
|
||||
* Set the style for this UI.
|
||||
*
|
||||
* required style string The new UI style.
|
||||
**/
|
||||
/datum/tgui/proc/set_style(style)
|
||||
src.style = lowertext(style)
|
||||
|
||||
/**
|
||||
* public
|
||||
*
|
||||
* Set the interface (template) for this UI.
|
||||
*
|
||||
* required interface string The new UI interface.
|
||||
**/
|
||||
/datum/tgui/proc/set_interface(interface)
|
||||
src.interface = lowertext(interface)
|
||||
|
||||
/**
|
||||
* public
|
||||
*
|
||||
* Enable/disable auto-updating of the UI.
|
||||
*
|
||||
* required state bool Enable/disable auto-updating.
|
||||
**/
|
||||
/datum/tgui/proc/set_auto_update(state = 1)
|
||||
auto_update = state
|
||||
|
||||
/**
|
||||
* private
|
||||
*
|
||||
* Set the data to initialize the UI with.
|
||||
* The datastructure cannot be changed by subsequent updates.
|
||||
*
|
||||
* optional data list The data/datastructure to initialize the UI with.
|
||||
**/
|
||||
/datum/tgui/proc/set_initial_data(list/data)
|
||||
initial_data = data
|
||||
|
||||
/**
|
||||
* private
|
||||
*
|
||||
* Generate HTML for this UI.
|
||||
*
|
||||
* return string UI HTML output.
|
||||
**/
|
||||
/datum/tgui/proc/get_html()
|
||||
// Poplate HTML with JSON.
|
||||
return replacetextEx(SStgui.basehtml, "{}", get_json(initial_data))
|
||||
|
||||
/**
|
||||
* private
|
||||
*
|
||||
* Get the config data/datastructure to initialize the UI with.
|
||||
*
|
||||
* return list The config data.
|
||||
**/
|
||||
/datum/tgui/proc/get_config_data()
|
||||
var/list/config_data = list(
|
||||
"title" = title,
|
||||
"status" = status,
|
||||
"style" = style,
|
||||
"interface" = interface,
|
||||
"fancy" = user.client.prefs.tgui_fancy,
|
||||
"locked" = user.client.prefs.tgui_lock,
|
||||
"window" = window_id,
|
||||
"ref" = "\ref[src]",
|
||||
"user" = list(
|
||||
"name" = user.name,
|
||||
"ref" = "\ref[user]"
|
||||
),
|
||||
"srcObject" = list(
|
||||
"name" = src_object.name,
|
||||
"ref" = "\ref[src_object]"
|
||||
)
|
||||
)
|
||||
return config_data
|
||||
|
||||
/**
|
||||
* private
|
||||
*
|
||||
* Package the data to send to the UI, as JSON.
|
||||
* This includes the UI data and config_data.
|
||||
*
|
||||
* return string The packaged JSON.
|
||||
**/
|
||||
/datum/tgui/proc/get_json(list/data)
|
||||
var/list/json_data = list()
|
||||
|
||||
json_data["config"] = get_config_data()
|
||||
if(!isnull(data))
|
||||
json_data["data"] = data
|
||||
|
||||
// Generate the JSON; replace bad characters.
|
||||
var/json = JSON.stringify(json_data)
|
||||
json = replacetextEx(json, "\improper", "")
|
||||
|
||||
return json
|
||||
|
||||
/**
|
||||
* private
|
||||
*
|
||||
* Handle clicks from the UI.
|
||||
* Call the src_object's ui_act() if status is UI_INTERACTIVE.
|
||||
* If the src_object's ui_act() returns 1, update all UIs attacked to it.
|
||||
**/
|
||||
/datum/tgui/Topic(href, href_list)
|
||||
update_status(push = 0) // Update the window state.
|
||||
if(status != UI_INTERACTIVE || user != usr)
|
||||
return // If UI is not interactive or usr calling Topic is not the UI user.
|
||||
|
||||
var/action = href_list["action"] // Pull the action out.
|
||||
href_list -= "action"
|
||||
|
||||
var/update = src_object.ui_act(action, href_list, state) // Call ui_act() on the src_object.
|
||||
if(src_object && update)
|
||||
SStgui.update_uis(src_object) // If we have a src_object and its ui_act() told us to update.
|
||||
|
||||
/**
|
||||
* private
|
||||
*
|
||||
* Update the UI.
|
||||
* Only updates the data if update is true, otherwise only updates the status.
|
||||
*
|
||||
* optional force bool If the UI should be forced to update.
|
||||
**/
|
||||
/datum/tgui/process(force = 0)
|
||||
if(!src_object || !user) // If the object or user died (or something else), abort.
|
||||
close()
|
||||
return
|
||||
|
||||
if(status && (force || auto_update))
|
||||
update() // Update the UI if the status and update settings allow it.
|
||||
else
|
||||
update_status(push = 1) // Otherwise only update status.
|
||||
|
||||
/**
|
||||
* private
|
||||
*
|
||||
* Push data to an already open UI.
|
||||
*
|
||||
* required data list The data to send.
|
||||
* optional force bool If the update should be sent regardless of state.
|
||||
**/
|
||||
/datum/tgui/proc/push_data(data, force = 0)
|
||||
update_status(push = 0) // Update the window state.
|
||||
if(status <= UI_DISABLED && !force)
|
||||
return // Cannot update UI, we have no visibility.
|
||||
|
||||
// Send the new JSON to the recieveUpdate() Javascript function.
|
||||
user << output(url_encode(get_json(data)), "[window_id].browser:receiveUpdate")
|
||||
|
||||
|
||||
/**
|
||||
* private
|
||||
*
|
||||
* Updates the UI by interacting with the src_object again, which will hopefully
|
||||
* call try_ui_update on it.
|
||||
*
|
||||
* optional force_open bool If force_open should be passed to ui_interact.
|
||||
**/
|
||||
/datum/tgui/proc/update(force_open = 0)
|
||||
src_object.ui_interact(user, ui_key, src, force_open, master_ui, state)
|
||||
|
||||
/**
|
||||
* private
|
||||
*
|
||||
* Update the status/visibility of the UI for its user.
|
||||
*
|
||||
* optional push bool Push an update to the UI (an update is always sent for UI_DISABLED).
|
||||
**/
|
||||
/datum/tgui/proc/update_status(push = 0)
|
||||
var/new_status = src_object.ui_state(user, state)
|
||||
if(master_ui)
|
||||
new_status = min(new_status, master_ui.status)
|
||||
|
||||
if(new_status == UI_CLOSE)
|
||||
close()
|
||||
else
|
||||
set_status(new_status, push)
|
||||
|
||||
/**
|
||||
* private
|
||||
*
|
||||
* Set the status/visibility of the UI.
|
||||
*
|
||||
* required status int The status to set (UI_CLOSE/UI_DISABLED/UI_UPDATE/UI_INTERACTIVE).
|
||||
* optional push bool Push an update to the UI (an update is always sent for UI_DISABLED).
|
||||
**/
|
||||
/datum/tgui/proc/set_status(status, push = 0)
|
||||
if(src.status != status) // Only update if status has changed.
|
||||
if(src.status == UI_DISABLED)
|
||||
src.status = status
|
||||
if(push)
|
||||
update()
|
||||
else
|
||||
src.status = status
|
||||
if(status == UI_DISABLED || push) // Update if the UI just because disabled, or a push is requested.
|
||||
push_data(null, force = 1)
|
||||
Reference in New Issue
Block a user