Merge branch 'master' of https://github.com/PolarisSS13/Polaris into 3/30/2016_dumb_gun_balance

# Conflicts resolved:
#	code/modules/projectiles/projectile/beams.dm
This commit is contained in:
Neerti
2016-04-20 05:41:36 -04:00
222 changed files with 4002 additions and 3123 deletions
+13 -9
View File
@@ -16,7 +16,7 @@ var/global/floorIsLava = 0
var/rendered = "<span class=\"log_message\"><span class=\"prefix\">ATTACK:</span> <span class=\"message\">[text]</span></span>"
for(var/client/C in admins)
if((R_ADMIN|R_MOD) & C.holder.rights)
if(C.is_preference_enabled(/datum/client_preference/admin/show_attack_logs))
if(C.is_preference_enabled(/datum/client_preference/mod/show_attack_logs))
var/msg = rendered
C << msg
@@ -895,22 +895,26 @@ proc/admin_notice(var/message, var/rights)
////////////////////////////////////////////////////////////////////////////////////////////////ADMIN HELPER PROCS
/proc/is_special_character(mob/M as mob) // returns 1 for specail characters and 2 for heroes of gamemode
/proc/is_special_character(var/character) // returns 1 for special characters and 2 for heroes of gamemode
if(!ticker || !ticker.mode)
return 0
if (!istype(M))
return 0
var/datum/mind/M
if (ismob(character))
var/mob/C = character
M = C.mind
else if(istype(character, /datum/mind))
M = character
if(M.mind)
if(M)
if(ticker.mode.antag_templates && ticker.mode.antag_templates.len)
for(var/datum/antagonist/antag in ticker.mode.antag_templates)
if(antag.is_antagonist(M.mind))
if(antag.is_antagonist(M))
return 2
else if(M.mind.special_role)
else if(M.special_role)
return 1
if(isrobot(M))
var/mob/living/silicon/robot/R = M
if(isrobot(character))
var/mob/living/silicon/robot/R = character
if(R.emagged)
return 1
+12 -2
View File
@@ -8,8 +8,9 @@ var/list/admin_verbs_default = list(
/client/proc/debug_variables, //allows us to -see- the variables of any instance in the game. +VAREDIT needed to modify,
// /client/proc/check_antagonists, //shows all antags,
// /client/proc/cmd_mod_say,
/client/proc/cmd_mentor_check_new_players
/client/proc/cmd_mentor_check_new_players,
// /client/proc/deadchat //toggles deadchat on/off,
// /client/proc/toggle_ahelp_sound,
)
var/list/admin_verbs_admin = list(
/client/proc/player_panel_new, //shows an interface for all players, with links to various panels,
@@ -91,7 +92,10 @@ var/list/admin_verbs_admin = list(
/client/proc/change_security_level,
/client/proc/view_chemical_reaction_logs,
/client/proc/makePAI,
/datum/admins/proc/paralyze_mob
/client/proc/toggle_debug_logs,
/client/proc/toggle_attack_logs,
/datum/admins/proc/paralyze_mob,
/client/proc/fixatmos
)
var/list/admin_verbs_ban = list(
/client/proc/unban_panel,
@@ -188,6 +192,7 @@ var/list/admin_verbs_debug = list(
/client/proc/jumptomob,
/client/proc/jumptocoord,
/client/proc/dsay,
/client/proc/toggle_debug_logs,
/client/proc/admin_ghost //allows us to ghost/reenter body at will,
)
@@ -294,6 +299,7 @@ var/list/admin_verbs_mod = list(
/client/proc/check_antagonists,
/client/proc/aooc,
/client/proc/jobbans,
/client/proc/toggle_attack_logs,
/client/proc/cmd_admin_subtle_message, //send an message to somebody as a 'voice in their head',
/datum/admins/proc/paralyze_mob,
/client/proc/cmd_admin_direct_narrate,
@@ -515,12 +521,16 @@ var/list/admin_verbs_mentor = list(
if(holder)
if(holder.fakekey)
holder.fakekey = null
if(istype(src.mob, /mob/new_player))
mob.name = capitalize(ckey)
else
var/new_key = ckeyEx(input("Enter your desired display name.", "Fake Key", key) as text|null)
if(!new_key) return
if(length(new_key) >= 26)
new_key = copytext(new_key, 1, 26)
holder.fakekey = new_key
if(istype(mob, /mob/new_player))
mob.name = new_key
log_admin("[key_name(usr)] has turned stealth mode [holder.fakekey ? "ON" : "OFF"]")
message_admins("[key_name_admin(usr)] has turned stealth mode [holder.fakekey ? "ON" : "OFF"]", 1)
feedback_add_details("admin_verb","SM") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+3 -3
View File
@@ -732,7 +732,7 @@
M.equip_to_slot_or_del(W, slot_wear_id)
if("blue wizard")
M.equip_to_slot_or_del(new /obj/item/clothing/under/lightpurple(M), slot_w_uniform)
M.equip_to_slot_or_del(new /obj/item/clothing/under/color/lightpurple(M), slot_w_uniform)
M.equip_to_slot_or_del(new /obj/item/clothing/suit/wizrobe(M), slot_wear_suit)
M.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal(M), slot_shoes)
M.equip_to_slot_or_del(new /obj/item/device/radio/headset(M), slot_l_ear)
@@ -744,7 +744,7 @@
M.equip_to_slot_or_del(new /obj/item/weapon/storage/box(M), slot_in_backpack)
if("red wizard")
M.equip_to_slot_or_del(new /obj/item/clothing/under/lightpurple(M), slot_w_uniform)
M.equip_to_slot_or_del(new /obj/item/clothing/under/color/lightpurple(M), slot_w_uniform)
M.equip_to_slot_or_del(new /obj/item/clothing/suit/wizrobe/red(M), slot_wear_suit)
M.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal(M), slot_shoes)
M.equip_to_slot_or_del(new /obj/item/device/radio/headset(M), slot_l_ear)
@@ -756,7 +756,7 @@
M.equip_to_slot_or_del(new /obj/item/weapon/storage/box(M), slot_in_backpack)
if("marisa wizard")
M.equip_to_slot_or_del(new /obj/item/clothing/under/lightpurple(M), slot_w_uniform)
M.equip_to_slot_or_del(new /obj/item/clothing/under/color/lightpurple(M), slot_w_uniform)
M.equip_to_slot_or_del(new /obj/item/clothing/suit/wizrobe/marisa(M), slot_wear_suit)
M.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal/marisa(M), slot_shoes)
M.equip_to_slot_or_del(new /obj/item/device/radio/headset(M), slot_l_ear)
+54
View File
@@ -0,0 +1,54 @@
/client/proc/fixatmos()
set category = "Admin"
set name = "Fix Atmospherics Grief"
if(!check_rights(R_ADMIN|R_DEBUG)) return
if(alert("WARNING: Executing this command will perform a full reset of atmosphere. All pipelines will lose any gas that may be in them, and all zones will be reset to contain air mix as on roundstart. The supermatter engine will also be stopped (to prevent overheat due to removal of coolant). Do not use unless the station is suffering serious atmospheric issues due to grief or bug.", "Full Atmosphere Reboot", "No", "Yes") == "No")
return
feedback_add_details("admin_verb","FA")
log_and_message_admins("Full atmosphere reset initiated by [usr].")
world << "<span class = 'danger'>Initiating restart of atmosphere. The server may lag a bit.</span>"
sleep(10)
var/current_time = world.timeofday
// Depower the supermatter, as it would quickly blow up once we remove all gases from the pipes.
for(var/obj/machinery/power/supermatter/S in machines)
S.power = 0
usr << "\[1/5\] - Supermatter depowered"
// Remove all gases from all pipenets
for(var/datum/pipe_network/PN in pipe_networks)
for(var/datum/gas_mixture/G in PN.gases)
G.gas = list()
G.update_values()
usr << "\[2/5\] - All pipenets purged of gas."
// Delete all zones.
for(var/zone/Z in world)
Z.c_invalidate()
usr << "\[3/5\] - All ZAS Zones removed."
var/list/unsorted_overlays = list()
for(var/id in gas_data.tile_overlay)
unsorted_overlays |= gas_data.tile_overlay[id]
for(var/turf/simulated/T in world)
T.air = null
T.overlays.Remove(unsorted_overlays)
T.zone = null
usr << "\[4/5\] - All turfs reset to roundstart values."
qdel(air_master)
air_master = new
air_master.Setup()
spawn air_master.Start()
usr << "\[5/5\] - ZAS Rebooted"
world << "<span class = 'danger'>Atmosphere restart completed in <b>[(world.timeofday - current_time)/10]</b> seconds.</span>"
+2
View File
@@ -46,3 +46,5 @@
var/related_accounts_cid = "Requires database" //So admins know why it isn't working - Used to determine what other accounts previously logged in from this computer id
preload_rsc = 0 // This is 0 so we can set it to an URL once the player logs in and have them download the resources from a different server.
var/global/obj/screen/click_catcher/void
+4
View File
@@ -159,6 +159,10 @@
send_resources()
nanomanager.send_resources(src)
if(!void)
void = new()
screen += void
if(prefs.lastchangelog != changelog_hash) //bolds the changelog button on the interface so we know there are updates.
src << "<span class='info'>You have unread updates in the changelog.</span>"
@@ -409,7 +409,7 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
choice_options = list("Normal","Prosthesis")
var/new_state = input(user, "What state do you wish the limb to be in?") as null|anything in choice_options
if(!new_state && !CanUseTopic(user)) return TOPIC_NOACTION
if(!new_state || !CanUseTopic(user)) return TOPIC_NOACTION
switch(new_state)
if("Normal")
@@ -81,29 +81,33 @@
return ..()
/client/proc/is_preference_enabled(var/preference)
if(ispath(preference))
var/datum/client_preference/cp = get_client_preference_by_type(preference)
preference = cp.key
return (preference in prefs.preferences_enabled)
var/datum/client_preference/cp = get_client_preference(preference)
return cp && (cp.key in prefs.preferences_enabled)
/client/proc/set_preference(var/preference, var/set_preference)
var/datum/client_preference/cp
if(ispath(preference))
cp = get_client_preference_by_type(preference)
else
cp = get_client_preference_by_key(preference)
var/datum/client_preference/cp = get_client_preference(preference)
if(!cp)
return FALSE
preference = cp.key
if(set_preference && !(preference in prefs.preferences_enabled))
return toggle_preference(cp)
else if(!set_preference && (preference in prefs.preferences_enabled))
return toggle_preference(cp)
/client/proc/toggle_preference(var/preference, var/set_preference)
var/datum/client_preference/cp = get_client_preference(preference)
if(!cp)
return FALSE
preference = cp.key
var/enabled
if(set_preference && !(preference in prefs.preferences_enabled))
prefs.preferences_enabled += preference
if(preference in prefs.preferences_disabled)
prefs.preferences_enabled |= preference
prefs.preferences_disabled -= preference
enabled = TRUE
. = TRUE
else if(!set_preference && (preference in prefs.preferences_enabled))
else if(preference in prefs.preferences_enabled)
prefs.preferences_enabled -= preference
prefs.preferences_disabled |= preference
enabled = FALSE
@@ -11,6 +11,13 @@ var/list/_client_preferences_by_type
_client_preferences += new client_type()
return _client_preferences
/proc/get_client_preference(var/datum/client_preference/preference)
if(istype(preference))
return preference
if(ispath(preference))
return get_client_preference_by_type(preference)
return get_client_preference_by_key(preference)
/proc/get_client_preference_by_key(var/preference)
if(!_client_preferences_by_key)
_client_preferences_by_key = list()
@@ -119,20 +126,37 @@ var/list/_client_preferences_by_type
enabled_description = "Show"
disabled_description = "Hide"
/datum/client_preference/show_progress_bar
description ="Progress Bar"
key = "SHOW_PROGRESS"
enabled_description = "Show"
disabled_description = "Hide"
/datum/client_preference/safefiring
description = "Gun Firing Intent Requirement"
key = "SAFE_FIRING"
enabled_description = "Safe"
disabled_description = "Dangerous"
/********************
* Admin Preferences *
* Staff Preferences *
********************/
/datum/client_preference/admin/may_toggle(var/mob/preference_mob)
return check_rights(R_ADMIN, 0, preference_mob)
/datum/client_preference/admin/show_attack_logs
/datum/client_preference/mod/may_toggle(var/mob/preference_mob)
return check_rights(R_MOD|R_ADMIN, 0, preference_mob)
/datum/client_preference/debug/may_toggle(var/mob/preference_mob)
return check_rights(R_DEBUG|R_ADMIN, 0, preference_mob)
/datum/client_preference/mod/show_attack_logs
description = "Attack Log Messages"
key = "CHAT_ATTACKLOGS"
enabled_description = "Show"
disabled_description = "Hide"
enabled_by_default = FALSE
/datum/client_preference/admin/show_debug_logs
/datum/client_preference/debug/show_debug_logs
description = "Debug Log Messages"
key = "CHAT_DEBUGLOGS"
enabled_description = "Show"
@@ -158,4 +182,4 @@ var/list/_client_preferences_by_type
description = "Radio chatter"
key = "CHAT_RADIO"
enabled_description = "Show"
disabled_description = "Hide"
disabled_description = "Hide"
@@ -0,0 +1,144 @@
/datum/gear_tweak/proc/get_contents(var/metadata)
return
/datum/gear_tweak/proc/get_metadata(var/user, var/metadata)
return
/datum/gear_tweak/proc/get_default()
return
/datum/gear_tweak/proc/tweak_gear_data(var/metadata, var/datum/gear_data)
return
/datum/gear_tweak/proc/tweak_item(var/obj/item/I, var/metadata)
return
/*
* Color adjustment
*/
var/datum/gear_tweak/color/gear_tweak_free_color_choice = new()
/datum/gear_tweak/color
var/list/valid_colors
/datum/gear_tweak/color/New(var/list/valid_colors)
src.valid_colors = valid_colors
..()
/datum/gear_tweak/color/get_contents(var/metadata)
return "Color: <font color='[metadata]'>&#9899;</font>"
/datum/gear_tweak/color/get_default()
return valid_colors ? valid_colors[1] : COLOR_GRAY
/datum/gear_tweak/color/get_metadata(var/user, var/metadata)
if(valid_colors)
return input(user, "Choose an item color.", "Character Preference", metadata) as null|anything in valid_colors
return input(user, "Choose an item color.", "Global Preference", metadata) as color|null
/datum/gear_tweak/color/tweak_item(var/obj/item/I, var/metadata)
if(valid_colors && !(metadata in valid_colors))
return
I.color = metadata
/*
* Path adjustment
*/
/datum/gear_tweak/path
var/list/valid_paths
/datum/gear_tweak/path/New(var/list/valid_paths)
src.valid_paths = valid_paths
..()
/datum/gear_tweak/path/get_contents(var/metadata)
return "Type: [metadata]"
/datum/gear_tweak/path/get_default()
return valid_paths[1]
/datum/gear_tweak/path/get_metadata(var/user, var/metadata)
return input(user, "Choose a type.", "Character Preference", metadata) as null|anything in valid_paths
/datum/gear_tweak/path/tweak_gear_data(var/metadata, var/datum/gear_data/gear_data)
if(!(metadata in valid_paths))
return
gear_data.path = valid_paths[metadata]
/*
* Content adjustment
*/
/datum/gear_tweak/contents
var/list/valid_contents
/datum/gear_tweak/contents/New()
valid_contents = args.Copy()
..()
/datum/gear_tweak/contents/get_contents(var/metadata)
return "Contents: [english_list(metadata, and_text = ", ")]"
/datum/gear_tweak/contents/get_default()
. = list()
for(var/i = 1 to valid_contents.len)
. += "Random"
/datum/gear_tweak/contents/get_metadata(var/user, var/list/metadata)
. = list()
for(var/i = metadata.len to valid_contents.len)
metadata += "Random"
for(var/i = 1 to valid_contents.len)
var/entry = input(user, "Choose an entry.", "Character Preference", metadata[i]) as null|anything in (valid_contents[i] + list("Random", "None"))
if(entry)
. += entry
else
return metadata
/datum/gear_tweak/contents/tweak_item(var/obj/item/I, var/list/metadata)
if(metadata.len != valid_contents.len)
return
for(var/i = 1 to valid_contents.len)
var/path
var/list/contents = valid_contents[i]
if(metadata[i] == "Random")
path = pick(contents)
path = contents[path]
else if(metadata[i] == "None")
continue
else
path = contents[metadata[i]]
new path(I)
/*
* Ragent adjustment
*/
/datum/gear_tweak/reagents
var/list/valid_reagents
/datum/gear_tweak/reagents/New(var/list/reagents)
valid_reagents = reagents.Copy()
..()
/datum/gear_tweak/reagents/get_contents(var/metadata)
return "Reagents: [metadata]"
/datum/gear_tweak/reagents/get_default()
return "Random"
/datum/gear_tweak/reagents/get_metadata(var/user, var/list/metadata)
. = input(user, "Choose an entry.", "Character Preference", metadata) as null|anything in (valid_reagents + list("Random", "None"))
if(!.)
return metadata
/datum/gear_tweak/reagents/tweak_item(var/obj/item/I, var/list/metadata)
if(metadata == "None")
return
if(metadata == "Random")
. = valid_reagents[pick(valid_reagents)]
else
. = valid_reagents[metadata]
I.reagents.add_reagent(., I.reagents.get_free_space())
@@ -92,6 +92,7 @@ var/list/gear_datums = list()
var/fcolor = "#3366CC"
if(total_cost < MAX_GEAR_COST)
fcolor = "#E67300"
. += list()
. += "<table align = 'center' width = 500px>"
. += "<tr><td colspan=3><center><b><font color = '[fcolor]'>[total_cost]/[MAX_GEAR_COST]</font> loadout points spent.</b> \[<a href='?src=\ref[src];clear_loadout=1'>Clear Loadout</a>\]</center></td></tr>"
@@ -122,11 +123,33 @@ var/list/gear_datums = list()
for(var/gear_name in LC.gear)
var/datum/gear/G = LC.gear[gear_name]
var/ticked = (G.display_name in pref.gear)
var/obj/item/temp = G.path
. += "<tr><td width=25%><a href='?src=\ref[src];toggle_gear=[G.display_name]'><font color='[ticked ? "#E67300" : "#3366CC"]'>[G.display_name]</font></a></td>"
. += "<td width = 10%>[G.cost]</td>"
. += "<td><font size=2><i>[initial(temp.desc)]</i></font></td></tr>"
. += "<tr style='vertical-align:top'><td width=25%><a href='?src=\ref[src];toggle_gear=[G.display_name]'><font color='[ticked ? "#E67300" : "#3366CC"]'>[G.display_name]</font></a></td>"
. += "<td width = 10% style='vertical-align:top'>[G.cost]</td>"
. += "<td><font size=2><i>[G.description]</i></font></td></tr>"
if(ticked)
. += "<tr><td colspan=3>"
for(var/datum/gear_tweak/tweak in G.gear_tweaks)
. += " <a href='?src=\ref[src];gear=[G.display_name];tweak=\ref[tweak]'>[tweak.get_contents(get_tweak_metadata(G, tweak))]</a>"
. += "</td></tr>"
. += "</table>"
. = jointext(.)
/datum/category_item/player_setup_item/loadout/proc/get_gear_metadata(var/datum/gear/G)
. = pref.gear[G.display_name]
if(!.)
. = list()
pref.gear[G.display_name] = .
/datum/category_item/player_setup_item/loadout/proc/get_tweak_metadata(var/datum/gear/G, var/datum/gear_tweak/tweak)
var/list/metadata = get_gear_metadata(G)
. = metadata["[tweak]"]
if(!.)
. = tweak.get_default()
metadata["[tweak]"] = .
/datum/category_item/player_setup_item/loadout/proc/set_tweak_metadata(var/datum/gear/G, var/datum/gear_tweak/tweak, var/new_metadata)
var/list/metadata = get_gear_metadata(G)
metadata["[tweak]"] = new_metadata
/datum/category_item/player_setup_item/loadout/OnTopic(href, href_list, user)
if(href_list["toggle_gear"])
@@ -141,6 +164,16 @@ var/list/gear_datums = list()
if((total_cost+TG.cost) <= MAX_GEAR_COST)
pref.gear += TG.display_name
return TOPIC_REFRESH
if(href_list["gear"] && href_list["tweak"])
var/datum/gear/gear = gear_datums[href_list["gear"]]
var/datum/gear_tweak/tweak = locate(href_list["tweak"])
if(!tweak || !istype(gear) || !(tweak in gear.gear_tweaks))
return TOPIC_NOACTION
var/metadata = tweak.get_metadata(user, get_tweak_metadata(gear, tweak))
if(!metadata || !CanUseTopic(user))
return TOPIC_NOACTION
set_tweak_metadata(gear, tweak, metadata)
return TOPIC_REFRESH
else if(href_list["select_category"])
current_tab = href_list["select_category"]
return TOPIC_REFRESH
@@ -151,11 +184,34 @@ var/list/gear_datums = list()
/datum/gear
var/display_name //Name/index. Must be unique.
var/description //Description of this gear. If left blank will default to the description of the pathed item.
var/path //Path to item.
var/cost = 1 //Number of points used. Items in general cost 1 point, storage/armor/gloves/special use costs 2 points.
var/slot //Slot to equip to.
var/list/allowed_roles //Roles that can spawn with this item.
var/whitelisted //Term to check the whitelist for..
var/sort_category = "General"
var/list/gear_tweaks = list() //List of datums which will alter the item after it has been spawned.
/datum/gear/New()
..()
if(!description)
var/obj/O = path
description = initial(O.desc)
/datum/gear_data
var/path
var/location
/datum/gear_data/New(var/path, var/location)
src.path = path
src.location = location
/datum/gear/proc/spawn_item(var/location, var/metadata)
var/datum/gear_data/gd = new(path, location)
for(var/datum/gear_tweak/gt in gear_tweaks)
gt.tweak_gear_data(metadata["[gt]"], gd)
var/item = new gd.path(gd.location)
for(var/datum/gear_tweak/gt in gear_tweaks)
gt.tweak_item(item, metadata["[gt]"])
return item
@@ -131,6 +131,11 @@
path = /obj/item/clothing/accessory/storage/black_vest
allowed_roles = list("Security Officer","Head of Security","Warden")
/datum/gear/accessory/white_vest
display_name = "webbing, medical"
path = /obj/item/clothing/accessory/storage/white_vest
allowed_roles = list("Paramedic","Chief Medical Officer","Medical Doctor")
/datum/gear/accessory/webbing
display_name = "webbing, simple"
path = /obj/item/clothing/accessory/storage/webbing
@@ -30,10 +30,34 @@
display_name = "flask"
path = /obj/item/weapon/reagent_containers/food/drinks/flask/barflask
/datum/gear/flask/New()
..()
gear_tweaks += new/datum/gear_tweak/reagents(lunchables_ethanol_reagents())
/datum/gear/vacflask
display_name = "vacuum-flask"
path = /obj/item/weapon/reagent_containers/food/drinks/flask/vacuumflask
/datum/gear/vacflask/New()
..()
gear_tweaks += new/datum/gear_tweak/reagents(lunchables_drink_reagents())
/datum/gear/comb
display_name = "purple comb"
path = /obj/item/weapon/haircomb
path = /obj/item/weapon/haircomb
/datum/gear/lunchbox
display_name = "lunchbox"
description = "A little lunchbox."
cost = 2
path = /obj/item/weapon/storage/toolbox/lunchbox
/datum/gear/lunchbox/New()
..()
var/list/lunchboxes = list()
for(var/lunchbox_type in typesof(/obj/item/weapon/storage/toolbox/lunchbox))
var/obj/item/weapon/storage/toolbox/lunchbox/lunchbox = lunchbox_type
if(!initial(lunchbox.filled))
lunchboxes[initial(lunchbox.name)] = lunchbox_type
gear_tweaks += new/datum/gear_tweak/path(sortAssoc(lunchboxes))
gear_tweaks += new/datum/gear_tweak/contents(lunchables_lunches(), lunchables_snacks(), lunchables_drinks())
@@ -187,253 +187,25 @@
whitelisted = "Tajara"
/datum/gear/head/hijab
display_name = "hijab, black"
display_name = "hijab"
path = /obj/item/clothing/head/hijab
/datum/gear/head/hijab/white
display_name = "hijab, white"
path = /obj/item/clothing/head/hijab/white
/datum/gear/head/hijab/aqua
display_name = "hijab, aqua"
path = /obj/item/clothing/head/hijab/aqua
/datum/gear/head/hijab/blue
display_name = "hijab, blue"
path = /obj/item/clothing/head/hijab/blue
/datum/gear/head/hijab/brown
display_name = "hijab, brown"
path = /obj/item/clothing/head/hijab/brown
/datum/gear/head/hijab/darkblue
display_name = "hijab, dark blue"
path = /obj/item/clothing/head/hijab/darkblue
/datum/gear/head/hijab/darkred
display_name = "hijab, dark red"
path = /obj/item/clothing/head/hijab/darkred
/datum/gear/head/hijab/green
display_name = "hijab, green"
path = /obj/item/clothing/head/hijab/green
/datum/gear/head/hijab/grey
display_name = "hijab, grey"
path = /obj/item/clothing/head/hijab/grey
/datum/gear/head/hijab/lightblue
display_name = "hijab, light blue"
path = /obj/item/clothing/head/hijab/lightblue
/datum/gear/head/hijab/lightbrown
display_name = "hijab, light brown"
path = /obj/item/clothing/head/hijab/lightbrown
/datum/gear/head/hijab/lightgreen
display_name = "hijab, light green"
path = /obj/item/clothing/head/hijab/lightgreen
/datum/gear/head/hijab/lightpurple
display_name = "hijab, light purple"
path = /obj/item/clothing/head/hijab/lightpurple
/datum/gear/head/hijab/lightred
display_name = "hijab, light red"
path = /obj/item/clothing/head/hijab/lightred
/datum/gear/head/hijab/maroon
display_name = "hijab, maroon"
path = /obj/item/clothing/head/hijab/maroon
/datum/gear/head/hijab/orange
display_name = "hijab, orange"
path = /obj/item/clothing/head/hijab/orange
/datum/gear/head/hijab/pink
display_name = "hijab, pink"
path = /obj/item/clothing/head/hijab/pink
/datum/gear/head/hijab/purple
display_name = "hijab, purple"
path = /obj/item/clothing/head/hijab/purple
/datum/gear/head/hijab/red
display_name = "hijab, red"
path = /obj/item/clothing/head/hijab/red
/datum/gear/head/hijab/yellowgreen
display_name = "hijab, yellow green"
path = /obj/item/clothing/head/hijab/yellowgreen
/datum/gear/head/hijab/yellow
display_name = "hijab, yellow"
path = /obj/item/clothing/head/hijab/yellow
/datum/gear/head/hijab/New()
..()
gear_tweaks = list(gear_tweak_free_color_choice)
/datum/gear/head/kippa
display_name = "kippa, black"
display_name = "kippa"
path = /obj/item/clothing/head/kippa
/datum/gear/head/kippa/white
display_name = "kippa, white"
path = /obj/item/clothing/head/kippa/white
/datum/gear/head/kippa/aqua
display_name = "kippa, aqua"
path = /obj/item/clothing/head/kippa/aqua
/datum/gear/head/kippa/blue
display_name = "kippa, blue"
path = /obj/item/clothing/head/kippa/blue
/datum/gear/head/kippa/brown
display_name = "kippa, brown"
path = /obj/item/clothing/head/kippa/brown
/datum/gear/head/kippa/darkblue
display_name = "kippa, dark blue"
path = /obj/item/clothing/head/kippa/darkblue
/datum/gear/head/kippa/darkred
display_name = "kippa, dark red"
path = /obj/item/clothing/head/kippa/darkred
/datum/gear/head/kippa/green
display_name = "kippa, green"
path = /obj/item/clothing/head/kippa/green
/datum/gear/head/kippa/grey
display_name = "kippa, grey"
path = /obj/item/clothing/head/kippa/grey
/datum/gear/head/kippa/lightblue
display_name = "kippa, light blue"
path = /obj/item/clothing/head/kippa/lightblue
/datum/gear/head/kippa/lightbrown
display_name = "kippa, light brown"
path = /obj/item/clothing/head/kippa/lightbrown
/datum/gear/head/kippa/lightgreen
display_name = "kippa, light green"
path = /obj/item/clothing/head/kippa/lightgreen
/datum/gear/head/kippa/lightpurple
display_name = "kippa, light purple"
path = /obj/item/clothing/head/kippa/lightpurple
/datum/gear/head/kippa/lightred
display_name = "kippa, light red"
path = /obj/item/clothing/head/kippa/lightred
/datum/gear/head/kippa/maroon
display_name = "kippa, maroon"
path = /obj/item/clothing/head/kippa/maroon
/datum/gear/head/kippa/orange
display_name = "kippa, orange"
path = /obj/item/clothing/head/kippa/orange
/datum/gear/head/kippa/pink
display_name = "kippa, pink"
path = /obj/item/clothing/head/kippa/pink
/datum/gear/head/kippa/purple
display_name = "kippa, purple"
path = /obj/item/clothing/head/kippa/purple
/datum/gear/head/kippa/red
display_name = "kippa, red"
path = /obj/item/clothing/head/kippa/red
/datum/gear/head/kippa/yellowgreen
display_name = "kippa, yellow green"
path = /obj/item/clothing/head/kippa/yellowgreen
/datum/gear/head/kippa/yellow
display_name = "kippa, yellow"
path = /obj/item/clothing/head/kippa/yellow
/datum/gear/head/kippa/New()
..()
gear_tweaks = list(gear_tweak_free_color_choice)
/datum/gear/head/turban
display_name = "turban, black"
display_name = "turban"
path = /obj/item/clothing/head/turban
/datum/gear/head/turban/white
display_name = "turban, white"
path = /obj/item/clothing/head/turban/white
/datum/gear/head/turban/aqua
display_name = "turban, aqua"
path = /obj/item/clothing/head/turban/aqua
/datum/gear/head/turban/blue
display_name = "turban, blue"
path = /obj/item/clothing/head/turban/blue
/datum/gear/head/turban/brown
display_name = "turban, brown"
path = /obj/item/clothing/head/turban/brown
/datum/gear/head/turban/darkblue
display_name = "turban, dark blue"
path = /obj/item/clothing/head/turban/darkblue
/datum/gear/head/turban/darkred
display_name = "turban, dark red"
path = /obj/item/clothing/head/turban/darkred
/datum/gear/head/turban/green
display_name = "turban, green"
path = /obj/item/clothing/head/turban/green
/datum/gear/head/turban/grey
display_name = "turban, grey"
path = /obj/item/clothing/head/turban/grey
/datum/gear/head/turban/lightblue
display_name = "turban, light blue"
path = /obj/item/clothing/head/turban/lightblue
/datum/gear/head/turban/lightbrown
display_name = "turban, light brown"
path = /obj/item/clothing/head/turban/lightbrown
/datum/gear/head/turban/lightgreen
display_name = "turban, light green"
path = /obj/item/clothing/head/turban/lightgreen
/datum/gear/head/turban/lightpurple
display_name = "turban, light purple"
path = /obj/item/clothing/head/turban/lightpurple
/datum/gear/head/turban/lightred
display_name = "turban, light red"
path = /obj/item/clothing/head/turban/lightred
/datum/gear/head/turban/maroon
display_name = "turban, maroon"
path = /obj/item/clothing/head/turban/maroon
/datum/gear/head/turban/orange
display_name = "turban, orange"
path = /obj/item/clothing/head/turban/orange
/datum/gear/head/turban/pink
display_name = "turban, pink"
path = /obj/item/clothing/head/turban/pink
/datum/gear/head/turban/purple
display_name = "turban, purple"
path = /obj/item/clothing/head/turban/purple
/datum/gear/head/turban/red
display_name = "turban, red"
path = /obj/item/clothing/head/turban/red
/datum/gear/head/turban/yellowgreen
display_name = "turban, yellow green"
path = /obj/item/clothing/head/turban/yellowgreen
/datum/gear/head/turban/yellow
display_name = "turban, yellow"
path = /obj/item/clothing/head/turban/yellow
/datum/gear/head/turban/New()
..()
gear_tweaks = list(gear_tweak_free_color_choice)
@@ -59,48 +59,16 @@
path = /obj/item/clothing/suit/storage/hazardvest
/datum/gear/suit/hoodie
display_name = "hoodie, grey"
display_name = "hoodie selection"
path = /obj/item/clothing/suit/storage/toggle/hoodie
/datum/gear/suit/hoodie/red
display_name = "hoodie, red"
path = /obj/item/clothing/suit/storage/toggle/hoodie/red
/datum/gear/suit/hoodie/blue
display_name = "hoodie, blue"
path = /obj/item/clothing/suit/storage/toggle/hoodie/blue
/datum/gear/suit/hoodie/yellow
display_name = "hoodie, yellow"
path = /obj/item/clothing/suit/storage/toggle/hoodie/yellow
/datum/gear/suit/hoodie/green
display_name = "hoodie, green"
path = /obj/item/clothing/suit/storage/toggle/hoodie/green
/datum/gear/suit/hoodie/orange
display_name = "hoodie, orange"
path = /obj/item/clothing/suit/storage/toggle/hoodie/orange
/datum/gear/suit/hoodie/black
display_name = "hoodie, black"
path = /obj/item/clothing/suit/storage/toggle/hoodie/black
/datum/gear/suit/hoodie/cti
display_name = "hoodie, CTI"
path = /obj/item/clothing/suit/storage/toggle/hoodie/cti
/datum/gear/suit/hoodie/mu
display_name = "hoodie, MU"
path = /obj/item/clothing/suit/storage/toggle/hoodie/mu
/datum/gear/suit/hoodie/nt
display_name = "hoodie, NT"
path = /obj/item/clothing/suit/storage/toggle/hoodie/nt
/datum/gear/suit/hoodie/smw
display_name = "hoodie, Space Mountain Wind"
path = /obj/item/clothing/suit/storage/toggle/hoodie/smw
/datum/gear/suit/hoodie/New()
..()
var/list/hoodies = list()
for(var/hoodie_style in typesof(/obj/item/clothing/suit/storage/toggle/hoodie))
var/obj/item/clothing/suit/storage/toggle/hoodie/hoodie = hoodie_style
hoodies[initial(hoodie.name)] = hoodie
gear_tweaks += new/datum/gear_tweak/path(sortAssoc(hoodies))
/datum/gear/suit/labcoat
display_name = "labcoat"
@@ -145,30 +113,43 @@
cost = 1
/datum/gear/suit/poncho
display_name = "poncho, tan"
display_name = "poncho selection"
path = /obj/item/clothing/suit/poncho
cost = 1
/datum/gear/suit/poncho/blue
display_name = "poncho, blue"
path = /obj/item/clothing/suit/poncho/blue
/datum/gear/suit/poncho/New()
..()
var/list/ponchos = list()
for(var/poncho_style in (typesof(/obj/item/clothing/suit/poncho) - typesof(/obj/item/clothing/suit/poncho/roles)))
var/obj/item/clothing/suit/storage/toggle/hoodie/poncho = poncho_style
ponchos[initial(poncho.name)] = poncho
gear_tweaks += new/datum/gear_tweak/path(sortAssoc(ponchos))
/datum/gear/suit/poncho/green
display_name = "poncho, green"
path = /obj/item/clothing/suit/poncho/green
/datum/gear/suit/poncho/purple
display_name = "poncho, purple"
path = /obj/item/clothing/suit/poncho/purple
/datum/gear/suit/poncho/red
display_name = "poncho, red"
path = /obj/item/clothing/suit/poncho/red
/datum/gear/suit/poncho/security
/datum/gear/suit/poncho/roles/security
display_name = "poncho, security"
path = /obj/item/clothing/suit/poncho/security
path = /obj/item/clothing/suit/poncho/roles/security
allowed_roles = list("Head of Security", "Warden", "Detective", "Security Officer")
/datum/gear/suit/poncho/roles/medical
display_name = "poncho, medical"
path = /obj/item/clothing/suit/poncho/roles/medical
allowed_roles = list("Medical Doctor","Chief Medical Officer","Chemist","Paramedic","Geneticist")
/datum/gear/suit/poncho/roles/engineering
display_name = "poncho, engineering"
path = /obj/item/clothing/suit/poncho/roles/engineering
allowed_roles = list("Chief Engineer","Atmospheric Technician", "Station Engineer")
/datum/gear/suit/poncho/roles/science
display_name = "poncho, science"
path = /obj/item/clothing/suit/poncho/roles/science
allowed_roles = list("Research Director","Scientist", "Roboticist", "Xenobotanist")
/datum/gear/suit/poncho/roles/cargo
display_name = "poncho, cargo"
path = /obj/item/clothing/suit/poncho/roles/cargo
allowed_roles = list("Quartermaster","Cargo Technician")
/datum/gear/suit/unathi_robe
display_name = "roughspun robe"
path = /obj/item/clothing/suit/unathi/robe
@@ -213,4 +194,4 @@
/datum/gear/suit/forensics/red/short
display_name = "forensics, red"
path = /obj/item/clothing/suit/storage/forensics/red
allowed_roles = list("Detective")
allowed_roles = list("Detective")
@@ -33,93 +33,17 @@
display_name = "cut top, red"
path = /obj/item/clothing/under/cuttop/red
/datum/gear/uniform/jumpskirt
display_name = "jumpskirt, black"
path = /obj/item/clothing/under/blackjumpskirt
/datum/gear/uniform/jumpsuit
display_name = "jumpsuit, rainbow"
path = /obj/item/clothing/under/rainbow
/datum/gear/uniform/jumpsuit/black
display_name = "jumpsuit, black"
path = /obj/item/clothing/under/color/black
/datum/gear/uniform/jumpsuit/blackfemale
display_name = "jumpsuit, female-black"
path = /obj/item/clothing/under/color/blackf
/datum/gear/uniform/jumpsuit/blue
display_name = "jumpsuit, blue"
path = /obj/item/clothing/under/color/blue
/datum/gear/uniform/jumpsuit/green
display_name = "jumpsuit, green"
path = /obj/item/clothing/under/color/green
/datum/gear/uniform/jumpsuit/grey
display_name = "jumpsuit, grey"
display_name = "jumpclothes selection"
path = /obj/item/clothing/under/color/grey
/datum/gear/uniform/jumpsuit/pink
display_name = "jumpsuit, pink"
path = /obj/item/clothing/under/color/pink
/datum/gear/uniform/jumpsuit/white
display_name = "jumpsuit, white"
path = /obj/item/clothing/under/color/white
/datum/gear/uniform/jumpsuit/yellow
display_name = "jumpsuit, yellow"
path = /obj/item/clothing/under/color/yellow
/datum/gear/uniform/jumpsuit/lightblue
display_name = "jumpsuit, lightblue"
path = /obj/item/clothing/under/lightblue
/datum/gear/uniform/jumpsuit/red
display_name = "jumpsuit, red"
path = /obj/item/clothing/under/color/red
/datum/gear/uniform/jumpsuit/aqua
display_name = "jumpsuit, aqua"
path = /obj/item/clothing/under/aqua
/datum/gear/uniform/jumpsuit/purple
display_name = "jumpsuit, purple"
path = /obj/item/clothing/under/purple
/datum/gear/uniform/jumpsuit/lightpurple
display_name = "jumpsuit, lightpurple"
path = /obj/item/clothing/under/lightpurple
/datum/gear/uniform/jumpsuit/lightgreen
display_name = "jumpsuit, lightgreen"
path = /obj/item/clothing/under/lightgreen
/datum/gear/uniform/jumpsuit/lightbrown
display_name = "jumpsuit, lightbrown"
path = /obj/item/clothing/under/lightbrown
/datum/gear/uniform/jumpsuit/brown
display_name = "jumpsuit, brown"
path = /obj/item/clothing/under/brown
/datum/gear/uniform/jumpsuit/yellowgreen
display_name = "jumpsuit, yellowgreen"
path = /obj/item/clothing/under/yellowgreen
/datum/gear/uniform/jumpsuit/darkblue
display_name = "jumpsuit, darkblue"
path = /obj/item/clothing/under/darkblue
/datum/gear/uniform/jumpsuit/lightred
display_name = "jumpsuit, lightred"
path = /obj/item/clothing/under/lightred
/datum/gear/uniform/jumpsuit/darkred
display_name = "jumpsuit, darkred"
path = /obj/item/clothing/under/darkred
/datum/gear/uniform/jumpsuit/New()
..()
var/list/jumpclothes = list()
for(var/jump in typesof(/obj/item/clothing/under/color))
var/obj/item/clothing/under/color/jumps = jump
jumpclothes[initial(jumps.name)] = jumps
gear_tweaks += new/datum/gear_tweak/path(sortAssoc(jumpclothes))
/datum/gear/uniform/skirt
display_name = "plaid skirt, blue"
@@ -228,100 +152,28 @@
allowed_roles = list("Quartermaster","Cargo Technician")
/datum/gear/uniform/pants
display_name = "pants, white"
display_name = "pants selection"
path = /obj/item/clothing/under/pants/white
/datum/gear/uniform/pants/red
display_name = "pants, red"
path = /obj/item/clothing/under/pants/red
/datum/gear/uniform/pants/New()
..()
var/list/pants = list()
for(var/pant in typesof(/obj/item/clothing/under/pants))
var/obj/item/clothing/under/pants/pant_type = pant
pants[initial(pant_type.name)] = pant_type
gear_tweaks += new/datum/gear_tweak/path(sortAssoc(pants))
/datum/gear/uniform/pants/black
display_name = "pants, black"
path = /obj/item/clothing/under/pants/black
/datum/gear/uniform/pants/tan
display_name = "pants, tan"
path = /obj/item/clothing/under/pants/tan
/datum/gear/uniform/pants/track
display_name = "pants, track"
path = /obj/item/clothing/under/pants/track
/datum/gear/uniform/pants/khaki
display_name = "pants, khaki"
path = /obj/item/clothing/under/pants/khaki
/datum/gear/uniform/pants/camo
display_name = "pants, camo"
path = /obj/item/clothing/under/pants/camo
/datum/gear/uniform/pants/jeans
display_name = "pants, jeans"
path = /obj/item/clothing/under/pants/jeans
/datum/gear/uniform/pants/jeans/classic
display_name = "pants, classic jeans"
path = /obj/item/clothing/under/pants/classicjeans
/datum/gear/uniform/pants/jeans/mustang
display_name = "pants, mustang jeans"
path = /obj/item/clothing/under/pants/mustangjeans
/datum/gear/uniform/pants/jeans/black
display_name = "pants, black jeans"
path = /obj/item/clothing/under/pants/blackjeans
/datum/gear/uniform/pants/jeans/youngfolks
display_name = "pants, young folks jeans"
path = /obj/item/clothing/under/pants/youngfolksjeans
/datum/gear/uniform/jeans
display_name = "shorts, jeans"
/datum/gear/uniform/shorts
display_name = "shorts selection"
path = /obj/item/clothing/under/shorts/jeans
/datum/gear/uniform/jeans/classic
display_name = "shorts, classic jeans"
path = /obj/item/clothing/under/shorts/jeans/classic
/datum/gear/uniform/jeans/mustang
display_name = "shorts, mustang jeans"
path = /obj/item/clothing/under/shorts/jeans/mustang
/datum/gear/uniform/jeans/youngfolks
display_name = "shorts, young folks jeans"
path = /obj/item/clothing/under/shorts/jeans/youngfolks
/datum/gear/uniform/jeans/black
display_name = "shorts, black jeans"
path = /obj/item/clothing/under/shorts/jeans/black
/datum/gear/uniform/jeans/female
display_name = "shorts, female, jeans"
path = /obj/item/clothing/under/shorts/jeans/female
/datum/gear/uniform/jeans/classic/female
display_name = "shorts, female, classic jeans"
path = /obj/item/clothing/under/shorts/jeans/classic/female
/datum/gear/uniform/jeans/mustang/female
display_name = "shorts, female, mustang jeans"
path = /obj/item/clothing/under/shorts/jeans/mustang/female
/datum/gear/uniform/jeans/youngfolks/female
display_name = "shorts, female, young folks jeans"
path = /obj/item/clothing/under/shorts/jeans/youngfolks/female
/datum/gear/uniform/jeans/black/female
display_name = "shorts, female, black jeans"
path = /obj/item/clothing/under/shorts/jeans/black/female
/datum/gear/uniform/khaki
display_name = "shorts, khaki"
path = /obj/item/clothing/under/shorts/khaki
/datum/gear/uniform/khaki/female
display_name = "shorts, female, khaki"
path = /obj/item/clothing/under/shorts/khaki/female
/datum/gear/uniform/shorts/New()
..()
var/list/shorts = list()
for(var/short in typesof(/obj/item/clothing/under/shorts))
var/obj/item/clothing/under/pants/short_type = short
shorts[initial(short_type.name)] = short_type
gear_tweaks += new/datum/gear_tweak/path(sortAssoc(shorts))
/datum/gear/uniform/suit //amish
display_name = "suit, amish"
@@ -412,6 +264,10 @@
display_name = "scrubs, green"
path = /obj/item/clothing/under/rank/medical/green
/datum/gear/uniform/scrubs/navyblue
display_name = "scrubs, navy blue"
path = /obj/item/clothing/under/rank/medical/navyblue
/datum/gear/uniform/sundress
display_name = "sundress"
path = /obj/item/clothing/under/sundress
@@ -439,6 +295,16 @@
path = /obj/item/clothing/under/rank/security/corp
allowed_roles = list("Security Officer","Head of Security","Warden")
/datum/gear/uniform/corpwarsuit
display_name = "uniform, corporate (Warden)"
path = /obj/item/clothing/under/rank/warden/corp
allowed_roles = list("Head of Security","Warden")
/datum/gear/uniform/corphossuit
display_name = "uniform, corporate (Head of Security)"
path = /obj/item/clothing/under/rank/head_of_security/corp
allowed_roles = list("Head of Security")
/datum/gear/uniform/uniform_hop
display_name = "uniform, HoP's dress"
path = /obj/item/clothing/under/dress/dress_hop
@@ -451,6 +317,16 @@
allowed_roles = list("Head of Personnel")
/datum/gear/uniform/navysecsuit
display_name = "uniform, navyblue (Security)"
display_name = "uniform, navy blue (Security)"
path = /obj/item/clothing/under/rank/security/navyblue
allowed_roles = list("Security Officer","Head of Security","Warden")
allowed_roles = list("Security Officer","Head of Security","Warden")
/datum/gear/uniform/navywarsuit
display_name = "uniform, navy blue (Wardem)"
path = /obj/item/clothing/under/rank/warden/navyblue
allowed_roles = list("Head of Security","Warden")
/datum/gear/uniform/navyhossuit
display_name = "uniform, navy blue (Head of Security)"
path = /obj/item/clothing/under/rank/head_of_security/navyblue
allowed_roles = list("Head of Security")
@@ -62,29 +62,29 @@
display_name = "headtail-wear, female, pink, cloth (Skrell)"
path = /obj/item/clothing/ears/skrell/cloth_female/pink
/datum/gear/uniform/jumpsuit/teshari
/datum/gear/uniform/teshari
display_name = "smock, grey (Teshari)"
path = /obj/item/clothing/under/seromi
whitelisted = "Teshari"
sort_category = "Xenowear"
/datum/gear/uniform/jumpsuit/teshari/yellow
/datum/gear/uniform/teshari/jumpsuit
display_name = "smock, yellow (Teshari)"
path = /obj/item/clothing/under/seromi/yellow
/datum/gear/uniform/jumpsuit/teshari/red
/datum/gear/uniform/teshari/jumpsuit/red
display_name = "smock, red (Teshari)"
path = /obj/item/clothing/under/seromi/red
/datum/gear/uniform/jumpsuit/teshari/white
/datum/gear/uniform/teshari/jumpsuit/white
display_name = "smock, white (Teshari)"
path = /obj/item/clothing/under/seromi/white
/datum/gear/uniform/jumpsuit/teshari/medical
/datum/gear/uniform/teshari/jumpsuit/medical
display_name = "smock, Medical (Teshari)"
path = /obj/item/clothing/under/seromi/medical
/datum/gear/uniform/jumpsuit/teshari/rainbow
/datum/gear/uniform/teshari/jumpsuit/rainbow
display_name = "smock, rainbow (Teshari)"
path = /obj/item/clothing/under/seromi/rainbow
@@ -44,7 +44,7 @@
pref.job_engsec_high = sanitize_integer(pref.job_engsec_high, 0, 65535, initial(pref.job_engsec_high))
pref.job_engsec_med = sanitize_integer(pref.job_engsec_med, 0, 65535, initial(pref.job_engsec_med))
pref.job_engsec_low = sanitize_integer(pref.job_engsec_low, 0, 65535, initial(pref.job_engsec_low))
if(!pref.player_alt_titles) pref.player_alt_titles = new()
if(!(pref.player_alt_titles)) pref.player_alt_titles = new()
if(!job_master)
return
@@ -57,7 +57,7 @@
else if(href_list["preconfigured"])
var/selected = input(user, "Select a skillset", "Skillset") as null|anything in SKILL_PRE
if(!selected && !CanUseTopic(user)) return
if(!selected || !CanUseTopic(user)) return
pref.ZeroSkills(1)
for(var/V in SKILL_PRE[selected])
@@ -0,0 +1,225 @@
//Toggles for preferences, normal clients
/client/verb/toggle_ghost_ears()
set name = "Show/Hide Ghost Ears"
set category = "Preferences"
set desc = "Toggles between seeing all mob speech and nearby mob speech."
var/pref_path = /datum/client_preference/ghost_ears
toggle_preference(pref_path)
src << "You will [ (is_preference_enabled(pref_path)) ? "now" : " no longer"] hear all mob speech as a ghost."
prefs.save_preferences()
feedback_add_details("admin_verb","TGEars") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/verb/toggle_ghost_vision()
set name = "Show/Hide Ghost Vision"
set category = "Preferences"
set desc = "Toggles between seeing all mob emotes and nearby mob emotes."
var/pref_path = /datum/client_preference/ghost_sight
toggle_preference(pref_path)
src << "You will [ (is_preference_enabled(pref_path)) ? "now" : " no longer"] see all emotes as a ghost."
prefs.save_preferences()
feedback_add_details("admin_verb","TGVision") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/verb/toggle_ghost_radio()
set name = "Show/Hide Radio Chatter"
set category = "Preferences"
set desc = "Toggles between seeing all radio chat and nearby radio chatter."
var/pref_path = /datum/client_preference/ghost_radio
toggle_preference(pref_path)
src << "You will [ (is_preference_enabled(pref_path)) ? "now" : "no longer"] hear all radios as a ghost."
prefs.save_preferences()
feedback_add_details("admin_verb","TGRadio") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/verb/toggle_deadchat()
set name = "Show/Hide Deadchat"
set category = "Preferences"
set desc = "Toggles the dead chat channel."
var/pref_path = /datum/client_preference/show_dsay
toggle_preference(pref_path)
src << "You will [ (is_preference_enabled(pref_path)) ? "now" : "no longer"] hear dead chat as a ghost."
prefs.save_preferences()
feedback_add_details("admin_verb","TDeadChat") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/verb/toggle_ooc()
set name = "Show/Hide OOC"
set category = "Preferences"
set desc = "Toggles global out of character chat."
var/pref_path = /datum/client_preference/show_ooc
toggle_preference(pref_path)
src << "You will [ (is_preference_enabled(/datum/client_preference/show_ooc)) ? "now" : "no longer"] hear global out of character chat."
prefs.save_preferences()
feedback_add_details("admin_verb","TOOC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/verb/toggle_looc()
set name = "Show/Hide LOOC"
set category = "Preferences"
set desc = "Toggles local out of character chat."
var/pref_path = /datum/client_preference/show_looc
toggle_preference(pref_path)
src << "You will [ (is_preference_enabled(pref_path)) ? "now" : "no longer"] hear local out of character chat."
prefs.save_preferences()
feedback_add_details("admin_verb","TLOOC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/verb/toggle_typing()
set name = "Show/Hide Typing Indicator"
set category = "Preferences"
set desc = "Toggles the speech bubble typing indicator."
var/pref_path = /datum/client_preference/show_typing_indicator
toggle_preference(pref_path)
src << "You will [ (is_preference_enabled(pref_path)) ? "now" : "no longer"] see the speech indicator."
prefs.save_preferences()
feedback_add_details("admin_verb","TLOOC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/verb/toggle_ahelp_sound()
set name = "Toggle Admin Help Sound"
set category = "Preferences"
set desc = "Toggles the ability to hear a noise broadcasted when you get an admin message."
var/pref_path = /datum/client_preference/holder/play_adminhelp_ping
toggle_preference(pref_path)
src << "You will [ (is_preference_enabled(pref_path)) ? "now" : "no longer"] receive noise from admin messages."
prefs.save_preferences()
feedback_add_details("admin_verb","TAHelp") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/verb/toggle_lobby_music()
set name = "Toggle Lobby Music"
set category = "Preferences"
set desc = "Toggles the music in the lobby."
var/pref_path = /datum/client_preference/play_lobby_music
toggle_preference(pref_path)
src << "You will [ (is_preference_enabled(pref_path)) ? "now" : "no longer"] hear music in the lobby."
prefs.save_preferences()
feedback_add_details("admin_verb","TLobMusic") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/verb/toggle_admin_midis()
set name = "Toggle Admin MIDIs"
set category = "Preferences"
set desc = "Toggles the music in the lobby."
var/pref_path = /datum/client_preference/play_admin_midis
toggle_preference(pref_path)
src << "You will [ (is_preference_enabled(pref_path)) ? "now" : " no longer"] hear MIDIs from admins."
prefs.save_preferences()
feedback_add_details("admin_verb","TAMidis") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/verb/toggle_ambience()
set name = "Toggle Ambience"
set category = "Preferences"
set desc = "Toggles the playing of ambience."
var/pref_path = /datum/client_preference/play_ambiance
toggle_preference(pref_path)
src << "You will [ (is_preference_enabled(pref_path)) ? "now" : " no longer"] hear ambient noise."
prefs.save_preferences()
feedback_add_details("admin_verb","TBeSpecial") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/verb/toggle_be_special(role in be_special_flags)
set name = "Toggle SpecialRole Candidacy"
set category = "Preferences"
set desc = "Toggles which special roles you would like to be a candidate for, during events."
var/role_flag = be_special_flags[role]
if(!role_flag) return
prefs.be_special ^= role_flag
prefs.save_preferences()
src << "You will [(prefs.be_special & role_flag) ? "now" : "no longer"] be considered for [role] events (where possible)."
feedback_add_details("admin_verb","TBeSpecial") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/verb/toggle_safe_firing()
set name = "Toggle Gun Firing Intent Requirement"
set category = "Preferences"
set desc = "Toggles between safe and dangerous firing. Safe requires a non-help intent to fire, dangerous can be fired on help intent."
var/pref_path = /datum/client_preference/safefiring
toggle_preference(pref_path)
prefs.save_preferences()
src << "You will now use [(is_preference_enabled(/datum/client_preference/safefiring)) ? "safe" : "dangerous"] firearms firing."
feedback_add_details("admin_verb","TFiringMode") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
//Toggles for Staff
//Developers
/client/proc/toggle_debug_logs()
set name = "Toggle Debug Logs"
set category = "Preferences"
set desc = "Toggles debug logs."
var/pref_path = /datum/client_preference/debug/show_debug_logs
if(check_rights(R_ADMIN|R_DEBUG))
toggle_preference(pref_path)
src << "You will [ (is_preference_enabled(pref_path)) ? "now" : "no longer"] receive debug logs."
prefs.save_preferences()
feedback_add_details("admin_verb","TBeSpecial") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
//Mods
/client/proc/toggle_attack_logs()
set name = "Toggle Attack Logs"
set category = "Preferences"
set desc = "Toggles attack logs."
var/pref_path = /datum/client_preference/mod/show_attack_logs
if(check_rights(R_ADMIN|R_MOD))
toggle_preference(pref_path)
src << "You will [ (is_preference_enabled(pref_path)) ? "now" : "no longer"] receive attack logs."
prefs.save_preferences()
feedback_add_details("admin_verb","TBeSpecial") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+5 -12
View File
@@ -25,21 +25,14 @@
flags_inv = HIDEEARS
siemens_coefficient = 0.7
action_button_name = "Toggle Visor"
var/flipped = 0 //Piggybacked from cap flipping.
/obj/item/clothing/head/helmet/riot/dropped()
src.icon_state = initial(icon_state)
src.flipped=0
..()
/obj/item/clothing/head/helmet/riot/attack_self(mob/user)
src.flipped = !src.flipped
if(src.flipped)
icon_state = "[icon_state]up"
user << "You flip the visor up."
/obj/item/clothing/head/helmet/riot/attack_self(mob/user as mob)
if(src.icon_state == initial(icon_state))
src.icon_state = "[icon_state]up"
user << "You raise the visor on the riot helmet."
else
src.icon_state = initial(icon_state)
user << "You flip the visor down."
user << "You lower the visor on the riot helmet."
update_clothing_icon() //so our mob-overlays update
/obj/item/clothing/head/helmet/laserproof
+9 -5
View File
@@ -67,7 +67,7 @@
icon_state = "beret_navy_officer"
/obj/item/clothing/head/beret/sec/navy/hos
name = "officer beret"
desc = "A navy blue beret with a commander's rank emblem. For officers that are more inclined towards style than safety."
desc = "A navy blue beret with a head of security's rank emblem. For officers that are more inclined towards style than safety."
icon_state = "beret_navy_hos"
/obj/item/clothing/head/beret/sec/navy/warden
name = "warden beret"
@@ -79,7 +79,7 @@
icon_state = "beret_corporate_officer"
/obj/item/clothing/head/beret/sec/corporate/hos
name = "officer beret"
desc = "A corporate black beret with a commander's rank emblem. For officers that are more inclined towards style than safety."
desc = "A corporate black beret with a head of security's rank emblem. For officers that are more inclined towards style than safety."
icon_state = "beret_corporate_hos"
/obj/item/clothing/head/beret/sec/corporate/warden
name = "warden beret"
@@ -95,11 +95,11 @@
icon_state = "beret_purple"
/obj/item/clothing/head/beret/centcom/officer
name = "officers beret"
desc = "A black beret adorned with the shield - a silver kite shield with an engraved sword - of the corporate security forces."
desc = "A dark blue beret adorned with a silver patch. Worn by NanoTrasen Officials."
icon_state = "beret_centcom_officer"
/obj/item/clothing/head/beret/centcom/captain
name = "captains beret"
desc = "A white beret adorned with the shield - a silver kite shield with an engraved sword - of the corporate security forces."
desc = "A white beret adorned with a blue patch. Worn by NanoTrasen command staff."
icon_state = "beret_centcom_captain"
//Medical
@@ -123,4 +123,8 @@
/obj/item/clothing/head/surgery/black
desc = "A cap surgeons wear during operations. Keeps their hair from tickling your internal organs. This one is black."
icon_state = "surgcap_black"
icon_state = "surgcap_black"
/obj/item/clothing/head/surgery/navyblue
desc = "A cap surgeons wear during operations. Keeps their hair from tickling your internal organs. This one is navy blue."
icon_state = "surgcap_navyblue"
+9 -316
View File
@@ -273,329 +273,22 @@
icon_state = "orange_bandana"
body_parts_covered = 0
//Hijabs
/obj/item/clothing/head/hijab
name = "black hijab"
desc = "A black veil that is wrapped to cover the head and chest"
icon_state = "hijab_black"
name = "hijab"
desc = "A veil that is wrapped to cover the head and chest"
icon_state = "hijab"
body_parts_covered = 0
flags_inv = BLOCKHAIR
/obj/item/clothing/head/hijab/white
name = "white hijab"
desc = "A white veil that is wrapped to cover the head and chest"
icon_state = "hijab_white"
/obj/item/clothing/head/hijab/aqua
name = "aqua hijab"
desc = "An aqua veil that is wrapped to cover the head and chest"
icon_state = "hijab_aqua"
/obj/item/clothing/head/hijab/blue
name = "blue hijab"
desc = "A blue veil that is wrapped to cover the head and chest"
icon_state = "hijab_blue"
/obj/item/clothing/head/hijab/brown
name = "brown hijab"
desc = "A brown veil that is wrapped to cover the head and chest"
icon_state = "hijab_brown"
/obj/item/clothing/head/hijab/darkblue
name = "bark blue hijab"
desc = "A dark blue veil that is wrapped to cover the head and chest"
icon_state = "hijab_darkblue"
/obj/item/clothing/head/hijab/darkred
name = "dark red hijab"
desc = "A dark red veil that is wrapped to cover the head and chest"
icon_state = "hijab_darkred"
/obj/item/clothing/head/hijab/green
name = "green hijab"
desc = "A green veil that is wrapped to cover the head and chest"
icon_state = "hijab_green"
/obj/item/clothing/head/hijab/grey
name = "grey hijab"
desc = "A grey veil that is wrapped to cover the head and chest"
icon_state = "hijab_grey"
/obj/item/clothing/head/hijab/lightblue
name = "light blue hijab"
desc = "A light blue veil that is wrapped to cover the head and chest"
icon_state = "hijab_lightblue"
/obj/item/clothing/head/hijab/lightbrown
name = "light brown hijab"
desc = "A light brown veil that is wrapped to cover the head and chest"
icon_state = "hijab_lightbrown"
/obj/item/clothing/head/hijab/lightgreen
name = "light green hijab"
desc = "A light green veil that is wrapped to cover the head and chest"
icon_state = "hijab_lightgreen"
/obj/item/clothing/head/hijab/lightpurple
name = "light purple hijab"
desc = "A light purple veil that is wrapped to cover the head and chest"
icon_state = "hijab_lightpurple"
/obj/item/clothing/head/hijab/lightred
name = "light red hijab"
desc = "A light red veil that is wrapped to cover the head and chest"
icon_state = "hijab_lightred"
/obj/item/clothing/head/hijab/maroon
name = "maroon hijab"
desc = "A maroon veil that is wrapped to cover the head and chest"
icon_state = "hijab_maroon"
/obj/item/clothing/head/hijab/orange
name = "orange hijab"
desc = "An orange veil that is wrapped to cover the head and chest"
icon_state = "hijab_orange"
/obj/item/clothing/head/hijab/pink
name = "pink hijab"
desc = "A pink veil that is wrapped to cover the head and chest"
icon_state = "hijab_pink"
/obj/item/clothing/head/hijab/purple
name = "purple hijab"
desc = "A purple veil that is wrapped to cover the head and chest"
icon_state = "hijab_purple"
/obj/item/clothing/head/hijab/red
name = "red hijab"
desc = "A red veil that is wrapped to cover the head and chest"
icon_state = "hijab_red"
/obj/item/clothing/head/hijab/yellowgreen
name = "yellow green hijab"
desc = "A yellow green veil that is wrapped to cover the head and chest"
icon_state = "hijab_yellowgreen"
/obj/item/clothing/head/hijab/yellow
name = "yellow hijab"
desc = "A yellow veil that is wrapped to cover the head and chest"
icon_state = "hijab_yellow"
//Kippot
/obj/item/clothing/head/kippa
name = "black kippa"
desc = "A small, brimless cap. It is black."
icon_state = "kippa_black"
name = "kippa"
desc = "A small, brimless cap."
icon_state = "kippa"
body_parts_covered = 0
/obj/item/clothing/head/kippa/aqua
name = "aqua kippa"
desc = "A small, brimless cap. It is aqua."
icon_state = "kippa_aqua"
/obj/item/clothing/head/kippa/blue
name = "blue kippa"
desc = "A small, brimless cap. It is blue."
icon_state = "kippa_blue"
/obj/item/clothing/head/kippa/brown
name = "brown kippa"
desc = "A small, brimless cap. It is blue."
icon_state = "kippa_brown"
/obj/item/clothing/head/kippa/darkblue
name = "dark blue kippa"
desc = "A small, brimless cap. It is dark blue."
icon_state = "kippa_darkblue"
/obj/item/clothing/head/kippa/darkred
name = "dark red kippa"
desc = "A small, brimless cap. It is dark red."
icon_state = "kippa_darkred"
/obj/item/clothing/head/kippa/green
name = "green kippa"
desc = "A small, brimless cap. It is green."
icon_state = "kippa_green"
/obj/item/clothing/head/kippa/grey
name = "grey kippa"
desc = "A small, brimless cap. It is grey."
icon_state = "kippa_grey"
/obj/item/clothing/head/kippa/lightblue
name = "light blue kippa"
desc = "A small, brimless cap. It is light blue."
icon_state = "kippa_lightblue"
/obj/item/clothing/head/kippa/lightbrown
name = "light brown kippa"
desc = "A small, brimless cap. It is light brown."
icon_state = "kippa_lightbrown"
/obj/item/clothing/head/kippa/lightgreen
name = "light green kippa"
desc = "A small, brimless cap. It is light green."
icon_state = "kippa_lightgreen"
/obj/item/clothing/head/kippa/lightpurple
name = "light purple kippa"
desc = "A small, brimless cap. It is light purple."
icon_state = "kippa_lightpurple"
/obj/item/clothing/head/kippa/lightred
name = "light red kippa"
desc = "A small, brimless cap. It is light red."
icon_state = "kippa_lightred"
/obj/item/clothing/head/kippa/maroon
name = "maroon kippa"
desc = "A small, brimless cap. It is maroon."
icon_state = "kippa_maroon"
/obj/item/clothing/head/kippa/orange
name = "orange kippa"
desc = "A small, brimless cap. It is orange."
icon_state = "kippa_orange"
/obj/item/clothing/head/kippa/pink
name = "pink kippa"
desc = "A small, brimless cap. It is pink."
icon_state = "kippa_pink"
/obj/item/clothing/head/kippa/purple
name = "purple kippa"
desc = "A small, brimless cap. It is purple."
icon_state = "kippa_purple"
/obj/item/clothing/head/kippa/red
name = "red kippa"
desc = "A small, brimless cap. It is red."
icon_state = "kippa_red"
/obj/item/clothing/head/kippa/white
name = "white kippa"
desc = "A small, brimless cap. It is white."
icon_state = "kippa_white"
/obj/item/clothing/head/kippa/yellowgreen
name = "yellow green kippa"
desc = "A small, brimless cap. It is yellow green."
icon_state = "kippa_yellowgreen"
/obj/item/clothing/head/kippa/yellow
name = "yellow kippa"
desc = "A small, brimless cap. It is yellow."
icon_state = "kippa_yellow"
//Turbans
/obj/item/clothing/head/turban
name = "black turban"
desc = "A black cloth used to wind around the head"
icon_state = "turban_black"
name = "turban"
desc = "A cloth used to wind around the head"
icon_state = "turban"
body_parts_covered = 0
flags_inv = BLOCKHAIR
/obj/item/clothing/head/turban/aqua
name = "aqua turban"
desc = "An aqua cloth used to wind around the head."
icon_state = "turban_aqua"
/obj/item/clothing/head/turban/blue
name = "blue turban"
desc = "A blue cloth used to wind around the head."
icon_state = "turban_blue"
/obj/item/clothing/head/turban/brown
name = "brown turban"
desc = "A brown cloth used to wind around the head."
icon_state = "turban_brown"
/obj/item/clothing/head/turban/darkblue
name = "dark blue turban"
desc = "A dark blue cloth used to wind around the head."
icon_state = "turban_darkblue"
/obj/item/clothing/head/turban/darkred
name = "dark red turban"
desc = "A dark red cloth used to wind around the head."
icon_state = "turban_darkred"
/obj/item/clothing/head/turban/green
name = "green turban"
desc = "A green cloth used to wind around the head."
icon_state = "turban_green"
/obj/item/clothing/head/turban/grey
name = "grey turban"
desc = "A grey cloth used to wind around the head."
icon_state = "turban_grey"
/obj/item/clothing/head/turban/lightblue
name = "light blue turban"
desc = "A light blue cloth used to wind around the head."
icon_state = "turban_lightblue"
/obj/item/clothing/head/turban/lightbrown
name = "light brown turban"
desc = "A light brown cloth used to wind around the head."
icon_state = "turban_lightbrown"
/obj/item/clothing/head/turban/lightgreen
name = "light green turban"
desc = "A light green cloth used to wind around the head."
icon_state = "turban_lightgreen"
/obj/item/clothing/head/turban/lightpurple
name = "light purple turban"
desc = "A light purple cloth used to wind around the head."
icon_state = "turban_lightpurple"
/obj/item/clothing/head/turban/lightred
name = "light red turban"
desc = "A light red cloth used to wind around the head."
icon_state = "turban_lightred"
/obj/item/clothing/head/turban/maroon
name = "maroon turban"
desc = "A maroon cloth used to wind around the head."
icon_state = "turban_maroon"
/obj/item/clothing/head/turban/orange
name = "orange turban"
desc = "An orange cloth used to wind around the head."
icon_state = "turban_orange"
/obj/item/clothing/head/turban/pink
name = "pink turban"
desc = "A pink cloth used to wind around the head."
icon_state = "turban_pink"
/obj/item/clothing/head/turban/purple
name = "purple turban"
desc = "A purple cloth used to wind around the head."
icon_state = "turban_purple"
/obj/item/clothing/head/turban/red
name = "red turban"
desc = "A red cloth used to wind around the head."
icon_state = "turban_red"
/obj/item/clothing/head/turban/white
name = "white turban"
desc = "A white cloth used to wind around the head."
icon_state = "turban_white"
/obj/item/clothing/head/turban/yellowgreen
name = "yellow green turban"
desc = "A yellow green cloth used to wind around the head."
icon_state = "turban_yellowgreen"
/obj/item/clothing/head/turban/yellow
name = "yellow turban"
desc = "A yellow cloth used to wind around the head."
icon_state = "turban_yellow"
+1 -1
View File
@@ -15,7 +15,7 @@
desc = "A bulky, heavy-duty piece of exclusive corporate armor. YOU are in charge!"
icon_state = "caparmor"
item_state = "capspacesuit"
w_class = 4
w_class = 5
gas_transfer_coefficient = 0.01
permeability_coefficient = 0.02
item_flags = STOPPRESSUREDAMAGE
+1 -1
View File
@@ -14,7 +14,7 @@
slot_flags = SLOT_BACK
req_one_access = list()
req_access = list()
w_class = 4
w_class = 5
// These values are passed on to all component pieces.
armor = list(melee = 40, bullet = 5, laser = 20,energy = 5, bomb = 35, bio = 100, rad = 20)
@@ -51,7 +51,7 @@
desc = "A suit that protects against low pressure environments. \"NORTHERN STAR\" is written in large block letters on the back."
icon_state = "space"
item_state = "s_suit"
w_class = 4//bulky item
w_class = 5 // So you can't fit this in your bag and be prepared at all times.
gas_transfer_coefficient = 0.01
permeability_coefficient = 0.02
item_flags = STOPPRESSUREDAMAGE | THICKMATERIAL
+3 -2
View File
@@ -143,6 +143,7 @@
body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS
allowed = list(/obj/item/weapon/gun,/obj/item/ammo_magazine,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/handcuffs,/obj/item/weapon/tank/emergency_oxygen)
slowdown = 1
w_class = 5
armor = list(melee = 80, bullet = 60, laser = 50,energy = 25, bomb = 50, bio = 100, rad = 100)
flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT
cold_protection = UPPER_TORSO | LOWER_TORSO | LEGS | FEET | ARMS | HANDS
@@ -291,7 +292,7 @@
icon_nobadge = "wardenvest_nobadge"
/obj/item/clothing/suit/storage/vest/hos
name = "commander armor vest"
name = "head of security armor vest"
desc = "A simple kevlar plate carrier. This one has a gold badge clipped to the chest."
icon_state = "hosvest_nobadge"
item_state = "hosvest_nobadge"
@@ -339,7 +340,7 @@
icon_nobadge = "wardenwebvest_nobadge"
/obj/item/clothing/suit/storage/vest/heavy/hos
name = "commander heavy armor vest"
name = "head of security heavy armor vest"
desc = "A heavy kevlar plate carrier with webbing attached. This one has a gold badge clipped to the chest."
icon_state = "hoswebvest_nobadge"
item_state = "hoswebvest_nobadge"
+28 -4
View File
@@ -343,12 +343,36 @@
icon_state = "blueponcho"
item_state = "blueponcho"
/obj/item/clothing/suit/poncho/security
/obj/item/clothing/suit/poncho/roles/security
name = "security poncho"
desc = "A simple, comfortable cloak without sleeves. This one is black and red, standard NanoTrasen Security colors."
icon_state = "secponcho"
item_state = "secponcho"
/obj/item/clothing/suit/poncho/roles/medical
name = "medical poncho"
desc = "A simple, comfortable cloak without sleeves. This one is white with green and blue tint, standard Medical colors."
icon_state = "medponcho"
item_state = "medponcho"
/obj/item/clothing/suit/poncho/roles/engineering
name = "engineering poncho"
desc = "A simple, comfortable cloak without sleeves. This one is yellow and orange, standard Engineering colors."
icon_state = "engiponcho"
item_state = "engiponcho"
/obj/item/clothing/suit/poncho/roles/science
name = "science poncho"
desc = "A simple, comfortable cloak without sleeves. This one is white with purple trim, standard NanoTrasen Science colors."
icon_state = "sciponcho"
item_state = "sciponcho"
/obj/item/clothing/suit/poncho/roles/cargo
name = "cargo poncho"
desc = "A simple, comfortable cloak without sleeves. This one is tan and grey, the colors of Cargo."
icon_state = "cargoponcho"
item_state = "cargoponcho"
/obj/item/clothing/suit/jacket/puffer
name = "puffer jacket"
desc = "A thick jacket with a rubbery, water-resistant shell."
@@ -486,7 +510,7 @@
/obj/item/clothing/suit/storage/toggle/hoodie/cti
name = "CTI hoodie"
desc = "A warm, black sweatshirt. It bears the letters CTI on the back, a lettering to the prestigious university in Tau Ceti, Ceti Technical Institute. There is a blue supernova embroidered on the front, the emblem of CTI."
desc = "A warm, black sweatshirt. It bears the letters ‘CTI’ on the back, a lettering to the prestigious university in Tau Ceti, Ceti Technical Institute. There is a blue supernova embroidered on the front, the emblem of CTI."
icon_state = "cti_hoodie"
item_state = "cti_hoodie"
icon_open = "cti_hoodie_open"
@@ -494,7 +518,7 @@
/obj/item/clothing/suit/storage/toggle/hoodie/mu
name = "mars university hoodie"
desc = "A warm, gray sweatshirt. It bears the letters MU on the front, a lettering to the well-known public college, Mars University."
desc = "A warm, gray sweatshirt. It bears the letters ‘MU’ on the front, a lettering to the well-known public college, Mars University."
icon_state = "mu_hoodie"
item_state = "mu_hoodie"
icon_open = "mu_hoodie_open"
@@ -631,4 +655,4 @@
/obj/item/clothing/suit/storage/hooded/wintercoat/miner
name = "mining winter coat"
icon_state = "coatminer"
armor = list(melee = 10, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0)
armor = list(melee = 10, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0)
-2
View File
@@ -4,7 +4,6 @@
/obj/item/clothing/suit/storage/New()
..()
pockets = new/obj/item/weapon/storage/internal(src)
pockets.storage_slots = 2 //two slots
pockets.max_w_class = 2 //fit only pocket sized items
pockets.max_storage_space = 4
@@ -77,7 +76,6 @@
/obj/item/clothing/suit/storage/vest/heavy/New()
..()
pockets = new/obj/item/weapon/storage/internal(src)
pockets.storage_slots = 4
pockets.max_w_class = 2
pockets.max_storage_space = 8
@@ -12,7 +12,8 @@
/obj/item/clothing/accessory/storage/New()
..()
hold = new/obj/item/weapon/storage/internal(src)
hold.storage_slots = slots
hold.max_storage_space = slots * 2
hold.max_w_class = 2
/obj/item/clothing/accessory/storage/attack_hand(mob/user as mob)
if (has_suit) //if we are part of a suit
@@ -61,6 +62,12 @@
icon_state = "vest_brown"
slots = 5
/obj/item/clothing/accessory/storage/white_vest
name = "white webbing vest"
desc = "Durable white synthcotton vest with lots of pockets to carry essentials."
icon_state = "vest_white"
slots = 5
/obj/item/clothing/accessory/storage/knifeharness
name = "decorated harness"
desc = "A heavily decorated harness of sinew and leather with two knife-loops."
+29 -22
View File
@@ -12,6 +12,13 @@
item_state = "bl_suit"
worn_state = "blackf"
/obj/item/clothing/under/color/blackjumpskirt
name = "black jumpskirt"
desc = "A black jumpskirt, Sol size 0."
icon_state = "blackjumpskirt"
item_state = "bl_suit"
worn_state = "blackjumpskirt"
/obj/item/clothing/under/color/blue
name = "blue jumpsuit"
icon_state = "blue"
@@ -78,89 +85,89 @@
item_state = "psyche"
worn_state = "psyche"
/obj/item/clothing/under/lightblue
/obj/item/clothing/under/color/lightblue
name = "lightblue jumpsuit"
desc = "lightblue"
desc = "A light blue jumpsuit."
icon_state = "lightblue"
item_state = "b_suit"
worn_state = "lightblue"
rolled_sleeves = 0
/obj/item/clothing/under/aqua
/obj/item/clothing/under/color/aqua
name = "aqua jumpsuit"
desc = "aqua"
desc = "An aqua jumpsuit."
icon_state = "aqua"
item_state = "b_suit"
worn_state = "aqua"
rolled_sleeves = 0
/obj/item/clothing/under/purple
/obj/item/clothing/under/color
name = "purple jumpsuit"
desc = "purple"
desc = "The latest in space fashion."
icon_state = "purple"
item_state = "p_suit"
worn_state = "purple"
rolled_sleeves = 0
/obj/item/clothing/under/lightpurple
/obj/item/clothing/under/color/lightpurple
name = "lightpurple jumpsuit"
desc = "lightpurple"
desc = "A light purple jumpsuit."
icon_state = "lightpurple"
item_state = "p_suit"
worn_state = "lightpurple"
rolled_sleeves = 0
/obj/item/clothing/under/lightgreen
/obj/item/clothing/under/color/lightgreen
name = "lightgreen jumpsuit"
desc = "lightgreen"
desc = "A light green jumpsuit."
icon_state = "lightgreen"
item_state = "g_suit"
worn_state = "lightgreen"
rolled_sleeves = 0
/obj/item/clothing/under/lightbrown
/obj/item/clothing/under/color/lightbrown
name = "lightbrown jumpsuit"
desc = "lightbrown"
desc = "A light brown jumpsuit."
icon_state = "lightbrown"
item_state = "lb_suit"
worn_state = "lightbrown"
rolled_sleeves = 0
/obj/item/clothing/under/brown
/obj/item/clothing/under/color/brown
name = "brown jumpsuit"
desc = "brown"
desc = "A brown jumpsuit."
icon_state = "brown"
item_state = "lb_suit"
worn_state = "brown"
rolled_sleeves = 0
/obj/item/clothing/under/yellowgreen
/obj/item/clothing/under/color/yellowgreen
name = "yellowgreen jumpsuit"
desc = "yellowgreen"
desc = "A... yellow green jumpsuit?"
icon_state = "yellowgreen"
item_state = "y_suit"
worn_state = "yellowgreen"
rolled_sleeves = 0
/obj/item/clothing/under/darkblue
/obj/item/clothing/under/color/darkblue
name = "darkblue jumpsuit"
desc = "darkblue"
desc = "A dark blue jumpsuit."
icon_state = "darkblue"
item_state = "b_suit"
worn_state = "darkblue"
rolled_sleeves = 0
/obj/item/clothing/under/lightred
/obj/item/clothing/under/color/lightred
name = "lightred jumpsuit"
desc = "lightred"
desc = "A light red jumpsuit."
icon_state = "lightred"
item_state = "r_suit"
worn_state = "lightred"
rolled_sleeves = 0
/obj/item/clothing/under/darkred
/obj/item/clothing/under/color/darkred
name = "darkred jumpsuit"
desc = "darkred"
desc = "A dark red jumpsuit."
icon_state = "darkred"
item_state = "r_suit"
worn_state = "darkred"
@@ -204,6 +204,14 @@
worn_state = "scrubsblack"
rolled_sleeves = -1
/obj/item/clothing/under/rank/medical/navyblue
name = "medical scrubs"
desc = "It's made of a special fiber that provides minor protection against biohazards. This one is in navy blue."
icon_state = "scrubsnavyblue"
item_state = "b_suit"
worn_state = "scrubsnavyblue"
rolled_sleeves = -1
/obj/item/clothing/under/rank/psych
desc = "A basic white jumpsuit. It has turqouise markings that denote the wearer as a psychiatrist."
name = "psychiatrist's jumpsuit"
+3 -10
View File
@@ -140,9 +140,9 @@
worn_state = "johnny"
item_state = "johnny"
/obj/item/clothing/under/rainbow
name = "rainbow"
desc = "rainbow"
/obj/item/clothing/under/color/rainbow
name = "rainbow jumpsuit"
desc = "A multi-colored jumpsuit."
icon_state = "rainbow"
item_state = "rainbow"
worn_state = "rainbow"
@@ -482,13 +482,6 @@
worn_state = "sundress_white"
body_parts_covered = UPPER_TORSO|LOWER_TORSO
/obj/item/clothing/under/blackjumpskirt
name = "black jumpskirt"
desc = "A black jumpskirt, Sol size 0."
icon_state = "blackjumpskirt"
item_state = "bl_suit"
worn_state = "blackjumpskirt"
/obj/item/clothing/under/captainformal
name = "captain's formal uniform"
desc = "A captain's formal-wear, for special occasions."
+8 -5
View File
@@ -1,4 +1,7 @@
/obj/item/clothing/under/pants
name = "jeans"
desc = "A nondescript pair of tough blue jeans."
icon_state = "jeans"
gender = PLURAL
body_parts_covered = LOWER_TORSO|LEGS
@@ -17,6 +20,11 @@
desc = "Only for those who can pull it off."
icon_state = "jeansblack"
/obj/item/clothing/under/pants/greyjeans
name = "grey jeans"
desc = "Only for those who can pull it off."
icon_state = "jeansgrey"
/obj/item/clothing/under/pants/youngfolksjeans
name = "Young Folks jeans"
desc = "For those tired of boring old jeans. Relive the passion of your youth!"
@@ -47,11 +55,6 @@
desc = "A pair of track pants, for the athletic."
icon_state = "trackpants"
/obj/item/clothing/under/pants/jeans
name = "jeans"
desc = "A nondescript pair of tough blue jeans."
icon_state = "jeans"
/obj/item/clothing/under/pants/khaki
name = "khaki pants"
desc = "A pair of dust beige khaki pants."
+16
View File
@@ -36,6 +36,7 @@
worn_state = "jeans_shorts"
/obj/item/clothing/under/shorts/jeans/female
name = "jeans short shorts"
icon_state = "jeans_shorts_f"
worn_state = "jeans_shorts_f"
@@ -45,6 +46,7 @@
worn_state = "jeansclassic_shorts"
/obj/item/clothing/under/shorts/jeans/classic/female
name = "classic jeans short shorts"
icon_state = "jeansclassic_shorts_f"
worn_state = "jeansclassic_shorts_f"
@@ -54,6 +56,7 @@
worn_state = "jeansmustang_shorts"
/obj/item/clothing/under/shorts/jeans/mustang/female
name = "mustang jeans short shorts"
icon_state = "jeansmustang_shorts_f"
worn_state = "jeansmustang_shorts_f"
@@ -63,6 +66,7 @@
worn_state = "jeansyoungfolks_shorts"
/obj/item/clothing/under/shorts/jeans/youngfolks/female
name = "young folks jeans short shorts"
icon_state = "jeansyoungfolks_shorts_f"
worn_state = "jeansyoungfolks_shorts_f"
@@ -72,9 +76,20 @@
worn_state = "blackpants_shorts"
/obj/item/clothing/under/shorts/jeans/black/female
name = "black jeans short shorts"
icon_state = "black_shorts_f"
worn_state = "black_shorts_f"
/obj/item/clothing/under/shorts/jeans/grey
name = "grey jeans shorts"
icon_state = "greypants_shorts"
worn_state = "greypants_shorts"
/obj/item/clothing/under/shorts/jeans/grey/female
name = "grey jeans short shorts"
icon_state = "grey_shorts_f"
worn_state = "grey_shorts_f"
/obj/item/clothing/under/shorts/khaki
name = "khaki shorts"
desc = "For that island getaway. It's five o'clock somewhere, right?"
@@ -82,5 +97,6 @@
worn_state = "tanpants_shorts"
/obj/item/clothing/under/shorts/khaki/female
name = "khaki short shorts"
icon_state = "khaki_shorts_f"
worn_state = "khaki_shorts_f"
+5 -3
View File
@@ -8,16 +8,18 @@
/obj/item/weapon/storage/box/swabs/New()
..()
for(var/i=0;i<storage_slots,i++) // Fill 'er up.
for(var/i = 1 to storage_slots) // Fill 'er up.
new /obj/item/weapon/forensics/swab(src)
/obj/item/weapon/storage/box/evidence
name = "evidence bag box"
desc = "A box claiming to contain evidence bags."
storage_slots = 7
can_hold = list(/obj/item/weapon/evidencebag)
/obj/item/weapon/storage/box/evidence/New()
..()
for(var/i=0;i<storage_slots,i++)
for(var/i = 1 to storage_slots)
new /obj/item/weapon/evidencebag(src)
/obj/item/weapon/storage/box/fingerprints
@@ -30,5 +32,5 @@
/obj/item/weapon/storage/box/fingerprints/New()
..()
for(var/i=0;i<storage_slots,i++)
for(var/i = 1 to storage_slots)
new /obj/item/weapon/sample/print(src)
+1 -1
View File
@@ -87,7 +87,7 @@ var/global/economy_init = 0
if(economy_init)
return 2
news_network.CreateFeedChannel("The Vir Times", "SolGov Minister of Information", 1, 1)
news_network.CreateFeedChannel("The Vir Times", "Vir Times ExoNode - Northern Star", 1, 1)
news_network.CreateFeedChannel("The Gibson Gazette", "Editor Mike Hammers", 1, 1)
for(var/loc_type in typesof(/datum/trade_destination) - /datum/trade_destination)
+144 -1
View File
@@ -6,6 +6,7 @@
layer = MOB_LAYER
universal_speak = 1
density = 0
var/obj/item/weapon/card/id/botcard = null
var/list/botcard_access = list()
var/on = 1
@@ -13,11 +14,30 @@
var/locked = 1
var/emagged = 0
var/light_strength = 3
var/busy = 0
var/obj/access_scanner = null
var/list/req_access = list()
var/list/req_one_access = list()
var/atom/target = null
var/list/ignore_list = list()
var/list/patrol_path = list()
var/list/target_path = list()
var/turf/obstacle = null
var/wait_if_pulled = 0 // Only applies to moving to the target
var/will_patrol = 0 // Not a setting - whether or no this type of bots patrols at all
var/patrol_speed = 1 // How many times per tick we move when patrolling
var/target_speed = 2 // Ditto for chasing the target
var/min_target_dist = 1 // How close we try to get to the target
var/max_target_dist = 50 // How far we are willing to go
var/max_patrol_dist = 250
var/target_patience = 5
var/frustration = 0
var/max_frustration = 0
/mob/living/bot/New()
..()
update_icons()
@@ -40,6 +60,9 @@
stunned = 0
paralysis = 0
if(on && !client && !busy)
handleAI()
/mob/living/bot/updatehealth()
if(status_flags & GODMODE)
health = maxHealth
@@ -109,6 +132,123 @@
/mob/living/bot/emag_act(var/remaining_charges, var/mob/user)
return 0
/mob/living/bot/proc/handleAI()
if(ignore_list.len)
for(var/atom/A in ignore_list)
if(!A || !A.loc || prob(1))
ignore_list -= A
handleRegular()
if(target && confirmTarget(target))
if(Adjacent(target))
handleAdjacentTarget()
else
handleRangedTarget()
if(!wait_if_pulled || !pulledby)
for(var/i = 1 to target_speed)
stepToTarget()
if(i < target_speed)
sleep(20 / target_speed)
if(max_frustration && frustration > max_frustration * target_speed)
handleFrustrated(1)
else
resetTarget()
lookForTargets()
if(will_patrol && !pulledby && !target)
if(patrol_path.len)
for(var/i = 1 to patrol_speed)
handlePatrol()
if(i < patrol_speed)
sleep(20 / patrol_speed)
if(max_frustration && frustration > max_frustration * patrol_speed)
handleFrustrated(0)
else
startPatrol()
else
handleIdle()
/mob/living/bot/proc/handleRegular()
return
/mob/living/bot/proc/handleAdjacentTarget()
return
/mob/living/bot/proc/handleRangedTarget()
return
/mob/living/bot/proc/stepToTarget()
if(!target || !target.loc)
return
if(get_dist(src, target) > min_target_dist)
if(!target_path.len || get_turf(target) != target_path[target_path.len])
calcTargetPath()
if(makeStep(target_path))
frustration = 0
else if(max_frustration)
++frustration
return
/mob/living/bot/proc/handleFrustrated(var/targ)
obstacle = targ ? target_path[1] : patrol_path[1]
target_path = list()
patrol_path = list()
return
/mob/living/bot/proc/lookForTargets()
return
/mob/living/bot/proc/confirmTarget(var/atom/A)
if(A.invisibility >= INVISIBILITY_LEVEL_ONE)
return 0
if(A in ignore_list)
return 0
if(!A.loc)
return 0
return 1
/mob/living/bot/proc/handlePatrol()
makeStep(patrol_path)
return
/mob/living/bot/proc/startPatrol()
var/turf/T = getPatrolTurf()
if(T)
patrol_path = AStar(get_turf(loc), T, /turf/proc/CardinalTurfsWithAccess, /turf/proc/Distance, 0, max_patrol_dist, id = botcard, exclude = obstacle)
if(!patrol_path)
patrol_path = list()
obstacle = null
return
/mob/living/bot/proc/getPatrolTurf()
return null
/mob/living/bot/proc/handleIdle()
return
/mob/living/bot/proc/calcTargetPath()
target_path = AStar(get_turf(loc), get_turf(target), /turf/proc/CardinalTurfsWithAccess, /turf/proc/Distance, 0, max_target_dist, id = botcard, exclude = obstacle)
if(!target_path)
if(target && target.loc)
ignore_list |= target
resetTarget()
obstacle = null
return
/mob/living/bot/proc/makeStep(var/list/path)
if(!path.len)
return 0
var/turf/T = path[1]
if(get_turf(src) == T)
path -= T
return makeStep(path)
return step_towards(src, T)
/mob/living/bot/proc/resetTarget()
target = null
target_path = list()
frustration = 0
obstacle = null
/mob/living/bot/proc/turn_on()
if(stat)
return 0
@@ -121,6 +261,9 @@
on = 0
set_light(0)
update_icons()
resetTarget()
patrol_path = list()
ignore_list = list()
/mob/living/bot/proc/explode()
qdel(src)
@@ -141,7 +284,7 @@
// for(var/turf/simulated/t in oview(src,1))
for(var/d in cardinal)
var/turf/simulated/T = get_step(src, d)
var/turf/T = get_step(src, d)
if(istype(T) && !T.density)
if(!LinkBlockedWithAccess(src, T, ID))
L.Add(T)
+23 -140
View File
@@ -6,18 +6,8 @@
botcard_access = list(access_janitor, access_maint_tunnels)
locked = 0 // Start unlocked so roboticist can set them to patrol.
var/obj/effect/decal/cleanable/target
var/list/path = list()
var/list/patrol_path = list()
var/list/ignorelist = list()
var/obj/cleanbot_listener/listener = null
var/beacon_freq = 1445 // navigation beacon frequency
var/signal_sent = 0
var/closest_dist
var/next_dest
var/next_dest_loc
wait_if_pulled = 1
min_target_dist = 0
var/cleaning = 0
var/screwloose = 0
@@ -26,48 +16,11 @@
var/blood = 1
var/list/target_types = list()
var/maximum_search_range = 7
/mob/living/bot/cleanbot/New()
..()
get_targets()
listener = new /obj/cleanbot_listener(src)
listener.cleanbot = src
if(radio_controller)
radio_controller.add_object(listener, beacon_freq, filter = RADIO_NAVBEACONS)
/mob/living/bot/cleanbot/proc/handle_target()
if(loc == target.loc)
if(!cleaning)
UnarmedAttack(target)
return 1
if(!path.len)
// spawn(0)
path = AStar(loc, target.loc, /turf/proc/CardinalTurfsWithAccess, /turf/proc/Distance, 0, 30, id = botcard)
if(!path)
custom_emote(2, "[src] can't reach the target and is giving up.")
target = null
path = list()
return
if(path.len)
step_to(src, path[1])
path -= path[1]
return 1
return
/mob/living/bot/cleanbot/Life()
..()
if(!on)
return
if(client)
return
if(cleaning)
return
/mob/living/bot/cleanbot/handleIdle()
if(!screwloose && !oddbutton && prob(5))
custom_emote(2, "makes an excited beeping booping sound!")
@@ -79,68 +32,27 @@
if(oddbutton && prob(5)) // Make a big mess
visible_message("Something flies out of [src]. He seems to be acting oddly.")
var/obj/effect/decal/cleanable/blood/gibs/gib = new /obj/effect/decal/cleanable/blood/gibs(loc)
ignorelist += gib
ignore_list += gib
spawn(600)
ignorelist -= gib
ignore_list -= gib
// Find a target
if(pulledby) // Don't wiggle if someone pulls you
patrol_path = list()
return
var/found_spot
search_loop:
for(var/i=0, i <= maximum_search_range, i++)
for(var/obj/effect/decal/cleanable/D in view(i, src))
if(D in ignorelist)
continue
for(var/T in target_types)
if(istype(D, T))
patrol_path = list()
target = D
found_spot = handle_target()
if (found_spot)
break search_loop
else
target = null
continue // no need to check the other types
if(!found_spot && !target) // No targets in range
if(!patrol_path || !patrol_path.len)
if(!signal_sent || signal_sent > world.time + 200) // Waited enough or didn't send yet
var/datum/radio_frequency/frequency = radio_controller.return_frequency(beacon_freq)
if(!frequency)
return
closest_dist = 9999
next_dest = null
next_dest_loc = null
var/datum/signal/signal = new()
signal.source = src
signal.transmission_method = 1
signal.data = list("findbeakon" = "patrol")
frequency.post_signal(src, signal, filter = RADIO_NAVBEACONS)
signal_sent = world.time
else
if(next_dest)
next_dest_loc = listener.memorized[next_dest]
if(next_dest_loc)
patrol_path = AStar(loc, next_dest_loc, /turf/proc/CardinalTurfsWithAccess, /turf/proc/Distance, 0, 120, id = botcard, exclude = null)
signal_sent = 0
else
if(pulledby) // Don't wiggle if someone pulls you
patrol_path = list()
return
if(patrol_path[1] == loc)
patrol_path -= patrol_path[1]
var/moved = step_towards(src, patrol_path[1])
if(moved)
patrol_path -= patrol_path[1]
/mob/living/bot/cleanbot/lookForTargets()
for(var/obj/effect/decal/cleanable/D in view(world.view, src)) // There was some odd code to make it start with nearest decals, it's unnecessary, this works
if(confirmTarget(D))
target = D
return
/mob/living/bot/cleanbot/confirmTarget(var/obj/effect/decal/cleanable/D)
if(!..())
return 0
for(var/T in target_types)
if(istype(D, T))
return 1
return 0
/mob/living/bot/cleanbot/handleAdjacentTarget()
if(get_turf(target) == src.loc)
UnarmedAttack(target)
/mob/living/bot/cleanbot/UnarmedAttack(var/obj/effect/decal/cleanable/D, var/proximity)
if(!..())
@@ -152,7 +64,7 @@
if(D.loc != loc)
return
cleaning = 1
busy = 1
custom_emote(2, "begins to clean up \the [D]")
update_icons()
var/cleantime = istype(D, /obj/effect/decal/cleanable/dirt) ? 10 : 50
@@ -165,7 +77,7 @@
qdel(D)
if(D == target)
target = null
cleaning = 0
busy = 0
update_icons()
/mob/living/bot/cleanbot/explode()
@@ -185,17 +97,11 @@
return
/mob/living/bot/cleanbot/update_icons()
if(cleaning)
if(busy)
icon_state = "cleanbot-c"
else
icon_state = "cleanbot[on]"
/mob/living/bot/cleanbot/turn_off()
..()
target = null
path = list()
patrol_path = list()
/mob/living/bot/cleanbot/attack_hand(var/mob/user)
var/dat
dat += "<TT><B>Automatic Station Cleaner v1.0</B></TT><BR><BR>"
@@ -230,10 +136,6 @@
if("patrol")
should_patrol = !should_patrol
patrol_path = null
if("freq")
var/freq = text2num(input("Select frequency for navigation beacons", "Frequnecy", num2text(beacon_freq / 10))) * 10
if (freq > 0)
beacon_freq = freq
if("screw")
screwloose = !screwloose
usr << "<span class='notice'>You twiddle the screw.</span>"
@@ -264,25 +166,6 @@
if(blood)
target_types += /obj/effect/decal/cleanable/blood
/* Radio object that listens to signals */
/obj/cleanbot_listener
var/mob/living/bot/cleanbot/cleanbot = null
var/list/memorized = list()
/obj/cleanbot_listener/receive_signal(var/datum/signal/signal)
var/recv = signal.data["beacon"]
var/valid = signal.data["patrol"]
if(!recv || !valid || !cleanbot)
return
var/dist = get_dist(cleanbot, signal.source.loc)
memorized[recv] = signal.source.loc
if(dist < cleanbot.closest_dist) // We check all signals, choosing the closest beakon; then we move to the NEXT one after the closest one
cleanbot.closest_dist = dist
cleanbot.next_dest = signal.data["next_patrol"]
/* Assembly */
/obj/item/weapon/bucket_sensor
+4 -2
View File
@@ -7,7 +7,6 @@
health = 100
maxHealth = 100
bot_version = "2.5"
is_ranged = 1
preparing_arrest_sounds = new()
@@ -20,7 +19,7 @@
var/last_shot = 0
/mob/living/bot/secbot/ed209/update_icons()
if(on && is_attacking)
if(on && busy)
icon_state = "ed209-c"
else
icon_state = "ed209[on]"
@@ -50,6 +49,9 @@
new /obj/effect/decal/cleanable/blood/oil(Tsec)
qdel(src)
/mob/living/bot/secbot/ed209/handleRangedTarget()
RangedAttack(target)
/mob/living/bot/secbot/ed209/RangedAttack(var/atom/A)
if(last_shot + shot_delay > world.time)
src << "You are not ready to fire yet!"
+82 -83
View File
@@ -22,17 +22,12 @@
var/obj/structure/reagent_dispensers/watertank/tank
var/attacking = 0
var/list/path = list()
var/atom/target
var/frustration = 0
/mob/living/bot/farmbot/New()
..()
spawn(5)
tank = locate() in contents
if(!tank)
tank = new /obj/structure/reagent_dispensers/watertank(src)
/mob/living/bot/farmbot/New(var/newloc, var/newTank)
..(newloc)
if(!newTank)
newTank = new /obj/structure/reagent_dispensers/watertank(src)
tank = newTank
tank.forceMove(src)
/mob/living/bot/farmbot/attack_hand(var/mob/user as mob)
. = ..()
@@ -110,63 +105,55 @@
else
icon_state = "farmbot[on]"
/mob/living/bot/farmbot/Life()
..()
if(!on)
return
/mob/living/bot/farmbot/handleRegular()
if(emagged && prob(1))
flick("farmbot_broke", src)
if(client)
return
if(target)
if(Adjacent(target))
UnarmedAttack(target)
path = list()
target = null
else
if(path.len && frustration < 5)
if(path[1] == loc)
path -= path[1]
var/t = step_towards(src, path[1])
if(t)
path -= path[1]
else
++frustration
else
path = list()
target = null
/mob/living/bot/farmbot/handleAdjacentTarget()
UnarmedAttack(target)
/mob/living/bot/farmbot/lookForTargets()
if(emagged)
for(var/mob/living/carbon/human/H in view(7, src))
target = H
return
else
if(emagged)
for(var/mob/living/carbon/human/H in view(7, src))
target = H
break
else
for(var/obj/machinery/portable_atmospherics/hydroponics/tray in view(7, src))
if(process_tray(tray))
target = tray
frustration = 0
break
if(!target && refills_water && tank && tank.reagents.total_volume < tank.reagents.maximum_volume)
for(var/obj/structure/sink/source in view(7, src))
target = source
frustration = 0
break
if(target)
var/t = get_dir(target, src) // Turf with the tray is impassable, so a* can't navigate directly to it
path = AStar(loc, get_step(target, t), /turf/proc/CardinalTurfsWithAccess, /turf/proc/Distance, 0, 30, id = botcard)
if(!path)
path = list()
for(var/obj/machinery/portable_atmospherics/hydroponics/tray in view(7, src))
if(confirmTarget(tray))
target = tray
return
if(!target && refills_water && tank && tank.reagents.total_volume < tank.reagents.maximum_volume)
for(var/obj/structure/sink/source in view(7, src))
target = source
return
/mob/living/bot/farmbot/calcTargetPath() // We need to land NEXT to the tray, because the tray itself is impassable
for(var/trayDir in list(NORTH, SOUTH, EAST, WEST))
target_path = AStar(get_turf(loc), get_step(get_turf(target), trayDir), /turf/proc/CardinalTurfsWithAccess, /turf/proc/Distance, 0, max_target_dist, id = botcard)
if(target_path)
break
if(!target_path)
ignore_list |= target
target = null
target_path = list()
return
/mob/living/bot/farmbot/stepToTarget() // Same reason
var/turf/T = get_turf(target)
if(!target_path.len || !T.Adjacent(target_path[target_path.len]))
calcTargetPath()
makeStep(target_path)
return
/mob/living/bot/farmbot/UnarmedAttack(var/atom/A, var/proximity)
if(!..())
return
if(attacking)
if(busy)
return
if(istype(A, /obj/machinery/portable_atmospherics/hydroponics))
var/obj/machinery/portable_atmospherics/hydroponics/T = A
var/t = process_tray(T)
var/t = confirmTarget(T)
switch(t)
if(0)
return
@@ -174,7 +161,7 @@
action = "water" // Needs a better one
update_icons()
visible_message("<span class='notice'>[src] starts [T.dead? "removing the plant from" : "harvesting"] \the [A].</span>")
attacking = 1
busy = 1
if(do_after(src, 30))
visible_message("<span class='notice'>[src] [T.dead? "removes the plant from" : "harvests"] \the [A].</span>")
T.attack_hand(src)
@@ -182,7 +169,7 @@
action = "water"
update_icons()
visible_message("<span class='notice'>[src] starts watering \the [A].</span>")
attacking = 1
busy = 1
if(do_after(src, 30))
playsound(loc, 'sound/effects/slosh.ogg', 25, 1)
visible_message("<span class='notice'>[src] waters \the [A].</span>")
@@ -191,7 +178,7 @@
action = "hoe"
update_icons()
visible_message("<span class='notice'>[src] starts uprooting the weeds in \the [A].</span>")
attacking = 1
busy = 1
if(do_after(src, 30))
visible_message("<span class='notice'>[src] uproots the weeds in \the [A].</span>")
T.weedlevel = 0
@@ -199,11 +186,11 @@
action = "fertile"
update_icons()
visible_message("<span class='notice'>[src] starts fertilizing \the [A].</span>")
attacking = 1
busy = 1
if(do_after(src, 30))
visible_message("<span class='notice'>[src] waters \the [A].</span>")
visible_message("<span class='notice'>[src] fertilizes \the [A].</span>")
T.reagents.add_reagent("ammonia", 10)
attacking = 0
busy = 0
action = ""
update_icons()
T.update_icon()
@@ -213,20 +200,20 @@
action = "water"
update_icons()
visible_message("<span class='notice'>[src] starts refilling its tank from \the [A].</span>")
attacking = 1
busy = 1
while(do_after(src, 10) && tank.reagents.total_volume < tank.reagents.maximum_volume)
tank.reagents.add_reagent("water", 10)
if(prob(5))
playsound(loc, 'sound/effects/slosh.ogg', 25, 1)
attacking = 0
busy = 0
action = ""
update_icons()
visible_message("<span class='notice'>[src] finishes refilling its tank.</span>")
else if(emagged && ishuman(A))
var/action = pick("weed", "water")
attacking = 1
busy = 1
spawn(50) // Some delay
attacking = 0
busy = 0
switch(action)
if("weed")
flick("farmbot_hoe", src)
@@ -238,7 +225,8 @@
A.attack_generic(src, 5, t)
if("water")
flick("farmbot_water", src)
visible_message("<span class='danger'>[src] splashes [A] with water!</span>") // That's it. RP effect.
visible_message("<span class='danger'>[src] splashes [A] with water!</span>")
tank.reagents.splash(A, 100)
/mob/living/bot/farmbot/explode()
visible_message("<span class='danger'>[src] blows apart!</span>")
@@ -261,8 +249,22 @@
qdel(src)
return
/mob/living/bot/farmbot/proc/process_tray(var/obj/machinery/portable_atmospherics/hydroponics/tray)
if(!tray || !istype(tray))
/mob/living/bot/farmbot/confirmTarget(var/atom/targ)
if(!..())
return 0
if(emagged && ishuman(targ))
if(targ in view(world.view, src))
return 1
return 0
if(istype(targ, /obj/structure/sink))
if(!tank || tank.reagents.total_volume >= tank.reagents.maximum_volume)
return 0
return 1
var/obj/machinery/portable_atmospherics/hydroponics/tray = targ
if(!istype(tray))
return 0
if(tray.closed_system || !tray.seed)
@@ -291,28 +293,28 @@
icon_state = "water_arm"
var/build_step = 0
var/created_name = "Farmbot"
var/obj/tank
w_class = 3.0
New()
..()
spawn(4) // If an admin spawned it, it won't have a watertank it, so lets make one for em!
var tank = locate(/obj/structure/reagent_dispensers/watertank) in contents
if(!tank)
new /obj/structure/reagent_dispensers/watertank(src)
/obj/item/weapon/farmbot_arm_assembly/New(var/newloc, var/theTank)
..(newloc)
if(!theTank) // If an admin spawned it, it won't have a watertank it, so lets make one for em!
tank = new /obj/structure/reagent_dispensers/watertank(src)
else
tank = theTank
tank.forceMove(src)
/obj/structure/reagent_dispensers/watertank/attackby(var/obj/item/robot_parts/S, mob/user as mob)
if ((!istype(S, /obj/item/robot_parts/l_arm)) && (!istype(S, /obj/item/robot_parts/r_arm)))
..()
return
var/obj/item/weapon/farmbot_arm_assembly/A = new /obj/item/weapon/farmbot_arm_assembly(loc)
user << "You add the robot arm to [src]."
loc = A //Place the water tank into the assembly, it will be needed for the finished bot
user.drop_from_inventory(S)
qdel(S)
new /obj/item/weapon/farmbot_arm_assembly(loc, src)
/obj/item/weapon/farmbot_arm_assembly/attackby(obj/item/weapon/W as obj, mob/user as mob)
..()
if((istype(W, /obj/item/device/analyzer/plant_analyzer)) && (build_step == 0))
@@ -339,10 +341,7 @@
else if((isprox(W)) && (build_step == 3))
build_step++
user << "You complete the Farmbot! Beep boop."
var/mob/living/bot/farmbot/S = new /mob/living/bot/farmbot(get_turf(src))
for(var/obj/structure/reagent_dispensers/watertank/wTank in contents)
wTank.loc = S
S.tank = wTank
var/mob/living/bot/farmbot/S = new /mob/living/bot/farmbot(get_turf(src), tank)
S.name = created_name
user.remove_from_mob(W)
qdel(W)
+84 -96
View File
@@ -3,22 +3,20 @@
desc = "A little floor repairing robot, he looks so excited!"
icon_state = "floorbot0"
req_access = list(access_construction)
wait_if_pulled = 1
min_target_dist = 0
var/amount = 10 // 1 for tile, 2 for lattice
var/maxAmount = 60
var/tilemake = 0 // When it reaches 100, bot makes a tile
var/repairing = 0
var/improvefloors = 0
var/eattiles = 0
var/maketiles = 0
var/targetdirection = null
var/list/path = list()
var/list/ignorelist = list()
var/turf/target
var/floor_build_type = /decl/flooring/tiling // Basic steel floor.
/mob/living/bot/floorbot/update_icons()
if(repairing)
if(busy)
icon_state = "floorbot-c"
else if(amount > 0)
icon_state = "floorbot[on]"
@@ -31,7 +29,7 @@
dat += "<TT><B>Automatic Station Floor Repairer v1.0</B></TT><BR><BR>"
dat += "Status: <A href='?src=\ref[src];operation=start'>[src.on ? "On" : "Off"]</A><BR>"
dat += "Maintenance panel is [open ? "opened" : "closed"]<BR>"
//dat += "Tiles left: [amount]<BR>"
dat += "Tiles left: [amount]<BR>"
dat += "Behvaiour controls are [locked ? "locked" : "unlocked"]<BR>"
if(!locked || issilicon(user))
dat += "Improves floors: <A href='?src=\ref[src];operation=improve'>[improvefloors ? "Yes" : "No"]</A><BR>"
@@ -89,100 +87,90 @@
targetdirection = null
attack_hand(usr)
/mob/living/bot/floorbot/turn_off()
..()
target = null
path = list()
ignorelist = list()
/mob/living/bot/floorbot/Life()
..()
if(!on)
return
/mob/living/bot/floorbot/handleRegular()
++tilemake
if(tilemake >= 100)
tilemake = 0
addTiles(1)
if(client)
return
if(prob(5))
if(prob(1))
custom_emote(2, "makes an excited booping beeping sound!")
if(ignorelist.len) // Don't stick forever
for(var/T in ignorelist)
if(prob(1))
ignorelist -= T
if(amount && !emagged)
if(!target && targetdirection) // Building a bridge
var/turf/T = get_step(src, targetdirection)
while(T in range(src))
if(istype(T, /turf/space))
target = T
break
T = get_step(T, targetdirection)
if(!target) // Fixing floors
for(var/turf/T in view(src))
if(T.loc.name == "Space")
continue
if(T in ignorelist)
continue
if(istype(T, /turf/space))
if(get_turf(T) == loc || prob(40)) // So they target the same tile all the time
target = T
if(improvefloors && istype(T, /turf/simulated/floor))
var/turf/simulated/floor/F = T
if(!F.flooring && (get_turf(T) == loc || prob(40)))
target = T
if(emagged) // Time to griff
for(var/turf/simulated/floor/D in view(src))
if(D.loc.name == "Space")
continue
if(D in ignorelist)
continue
target = D
break
if(!target && amount < maxAmount && eattiles || maketiles) // Eat tiles
if(eattiles)
for(var/obj/item/stack/tile/floor/T in view(src))
if(T in ignorelist)
continue
target = T
break
if(maketiles && !target)
for(var/obj/item/stack/material/steel/T in view(src))
if(T in ignorelist)
continue
target = T
break
if(target && get_turf(target) == loc)
/mob/living/bot/floorbot/handleAdjacentTarget()
if(get_turf(target) == src.loc)
UnarmedAttack(target)
if(target && get_turf(target) != loc && !path.len)
spawn(0)
path = AStar(loc, get_turf(target), /turf/proc/AdjacentTurfsSpace, /turf/proc/Distance, 0, 30, id = botcard)
if(!path)
path = list()
ignorelist += target
target = null
/mob/living/bot/floorbot/lookForTargets()
if(emagged) // Time to griff
for(var/turf/simulated/floor/D in view(src))
if(confirmTarget(D))
target = D
return
if(path.len)
step_to(src, path[1])
path -= path[1]
else if(amount)
if(targetdirection) // Building a bridge
var/turf/T = get_step(src, targetdirection)
while(T in range(world.view, src))
if(confirmTarget(T))
target = T
return
T = get_step(T, targetdirection)
else // Fixing floors
for(var/turf/space/T in view(src)) // Breaches are of higher priority
if(confirmTarget(T))
target = T
return
for(var/turf/simulated/mineral/floor/T in view(src)) // Asteroids are of smaller priority
if(confirmTarget(T))
target = T
return
if(improvefloors)
for(var/turf/simulated/floor/T in view(src))
if(confirmTarget(T))
target = T
return
if(amount < maxAmount && (eattiles || maketiles))
for(var/obj/item/stack/S in view(src))
if(confirmTarget(S))
target = S
return
/mob/living/bot/floorbot/confirmTarget(var/atom/A) // The fact that we do some checks twice may seem confusing but remember that the bot's settings may be toggled while it's moving and we want them to stop in that case
if(!..())
return 0
if(istype(A, /obj/item/stack/tile/floor))
return (amount < maxAmount && eattiles)
if(istype(A, /obj/item/stack/material/steel))
return (amount < maxAmount && maketiles)
if(A.loc.name == "Space")
return 0
if(emagged)
return (istype(A, /turf/simulated/floor))
if(!amount)
return 0
if(istype(A, /turf/space))
return 1
if(istype(A, /turf/simulated/mineral/floor))
return 1
var/turf/simulated/floor/T = A
return (istype(T) && improvefloors && !T.flooring && (get_turf(T) == loc || prob(40)))
/mob/living/bot/floorbot/UnarmedAttack(var/atom/A, var/proximity)
if(!..())
return
if(repairing)
if(busy)
return
if(get_turf(A) != loc)
@@ -190,9 +178,9 @@
if(emagged && istype(A, /turf/simulated/floor))
var/turf/simulated/floor/F = A
repairing = 1
busy = 1
update_icons()
if(F.is_plating())
if(F.flooring)
visible_message("<span class='warning'>[src] begins to tear the floor tile from the floor!</span>")
if(do_after(src, 50))
F.break_tile_to_plating()
@@ -203,15 +191,15 @@
F.ReplaceWithLattice()
addTiles(1)
target = null
repairing = 0
busy = 0
update_icons()
else if(istype(A, /turf/space))
else if(istype(A, /turf/space) || istype(A, /turf/simulated/mineral/floor))
var/building = 2
if(locate(/obj/structure/lattice, A))
building = 1
if(amount < building)
return
repairing = 1
busy = 1
update_icons()
visible_message("<span class='notice'>[src] begins to repair the hole.</span>")
if(do_after(src, 50))
@@ -223,12 +211,12 @@
I = PoolOrNew(/obj/item/stack/rods, src)
A.attackby(I, src)
target = null
repairing = 0
busy = 0
update_icons()
else if(istype(A, /turf/simulated/floor))
var/turf/simulated/floor/F = A
if(!F.flooring && amount)
repairing = 1
busy = 1
update_icons()
visible_message("<span class='notice'>[src] begins to improve the floor.</span>")
if(do_after(src, 50))
@@ -236,12 +224,12 @@
F.set_flooring(get_flooring_data(floor_build_type))
addTiles(-1)
target = null
repairing = 0
busy = 0
update_icons()
else if(istype(A, /obj/item/stack/tile/floor) && amount < maxAmount)
var/obj/item/stack/tile/floor/T = A
visible_message("<span class='notice'>[src] begins to collect tiles.</span>")
repairing = 1
busy = 1
update_icons()
if(do_after(src, 20))
if(T)
@@ -249,13 +237,13 @@
T.use(eaten)
addTiles(eaten)
target = null
repairing = 0
busy = 0
update_icons()
else if(istype(A, /obj/item/stack/material) && amount + 4 <= maxAmount)
var/obj/item/stack/material/M = A
if(M.get_material_name() == DEFAULT_WALL_MATERIAL)
visible_message("<span class='notice'>[src] begins to make tiles.</span>")
repairing = 1
busy = 1
update_icons()
if(do_after(50))
if(M)
+37 -63
View File
@@ -3,21 +3,16 @@
desc = "A little medical robot. He looks somewhat underwhelmed."
icon_state = "medibot0"
req_access = list(access_medical)
var/skin = null //Set to "tox", "ointment" or "o2" for the other two firstaid kits.
botcard_access = list(access_medical, access_morgue, access_surgery, access_chemistry, access_virology, access_genetics)
var/skin = null //Set to "tox", "ointment" or "o2" for the other two firstaid kits.
//AI vars
var/frustration = 0
var/list/path = list()
var/mob/living/carbon/human/patient = null
var/mob/ignored = list() // Used by emag
var/last_newpatient_speak = 0
var/vocal = 1
//Healing vars
var/obj/item/weapon/reagent_containers/glass/reagent_glass = null //Can be set to draw from this for reagents.
var/currently_healing = 0
var/injection_amount = 15 //How much reagent do we inject at a time?
var/heal_threshold = 10 //Start healing when they have this much damage in a category
var/use_beaker = 0 //Use reagents in beaker instead of default treatment agents.
@@ -29,49 +24,26 @@
var/treatment_emag = "toxin"
var/declare_treatment = 0 //When attempting to treat a patient, should it notify everyone wearing medhuds?
/mob/living/bot/medbot/Life()
..()
/mob/living/bot/medbot/handleIdle()
if(vocal && prob(1))
var/message = pick("Radar, put a mask on!", "There's always a catch, and it's the best there is.", "I knew it, I should've been a plastic surgeon.", "What kind of medbay is this? Everyone's dropping like dead flies.", "Delicious!")
say(message)
if(!on)
return
/mob/living/bot/medbot/handleAdjacentTarget()
UnarmedAttack(target)
if(!client)
/mob/living/bot/medbot/lookForTargets()
for(var/mob/living/carbon/human/H in view(7, src)) // Time to find a patient!
if(confirmTarget(H))
target = H
if(last_newpatient_speak + 300 < world.time)
var/message = pick("Hey, [H.name]! Hold on, I'm coming.", "Wait [H.name]! I want to help!", "[H.name], you appear to be injured!")
say(message)
custom_emote(1, "points at [H.name].")
last_newpatient_speak = world.time
break
if(vocal && prob(1))
var/message = pick("Radar, put a mask on!", "There's always a catch, and it's the best there is.", "I knew it, I should've been a plastic surgeon.", "What kind of medbay is this? Everyone's dropping like dead flies.", "Delicious!")
say(message)
if(patient)
if(Adjacent(patient))
if(!currently_healing)
UnarmedAttack(patient)
else
if(path.len && (get_dist(patient, path[path.len]) > 2)) // We have a path, but it's off
path = list()
if(!path.len && (get_dist(src, patient) > 1))
spawn(0)
path = AStar(loc, get_turf(patient), /turf/proc/CardinalTurfsWithAccess, /turf/proc/Distance, 0, 30, id = botcard)
if(!path)
path = list()
if(path.len)
step_to(src, path[1])
path -= path[1]
++frustration
if(get_dist(src, patient) > 7 || frustration > 8)
patient = null
else
for(var/mob/living/carbon/human/H in view(7, src)) // Time to find a patient!
if(valid_healing_target(H))
patient = H
frustration = 0
if(last_newpatient_speak + 300 < world.time)
var/message = pick("Hey, [H.name]! Hold on, I'm coming.", "Wait [H.name]! I want to help!", "[H.name], you appear to be injured!")
say(message)
custom_emote(1, "points at [H.name].")
last_newpatient_speak = world.time
break
/mob/living/bot/medbot/UnarmedAttack(var/mob/living/carbon/human/H, var/proximity)
/mob/living/bot/medbot/UnarmedAttack(var/mob/living/carbon/human/H)
if(!..())
return
@@ -81,25 +53,27 @@
if(!istype(H))
return
if(busy)
return
if(H.stat == DEAD)
var/death_message = pick("No! NO!", "Live, damnit! LIVE!", "I... I've never lost a patient before. Not today, I mean.")
say(death_message)
patient = null
target = null
return
var/t = valid_healing_target(H)
var/t = confirmTarget(H)
if(!t)
var/message = pick("All patched up!", "An apple a day keeps me away.", "Feel better soon!")
say(message)
patient = null
target = null
return
icon_state = "medibots"
visible_message("<span class='warning'>[src] is trying to inject [H]!</span>")
if(declare_treatment)
var/area/location = get_area(src)
broadcast_medical_hud_message("[src] is treating <b>[H]</b> in <b>[location]</b>", src)
currently_healing = 1
busy = 1
update_icons()
if(do_mob(src, H, 30))
if(t == 1)
@@ -107,14 +81,14 @@
else
H.reagents.add_reagent(t, injection_amount)
visible_message("<span class='warning'>[src] injects [H] with the syringe!</span>")
currently_healing = 0
busy = 0
update_icons()
/mob/living/bot/medbot/update_icons()
overlays.Cut()
if(skin)
overlays += image('icons/obj/aibots.dmi', "medskin_[skin]")
if(currently_healing)
if(busy)
icon_state = "medibots"
else
icon_state = "medibot[on]"
@@ -226,13 +200,13 @@
user << "<span class='warning'>You short out [src]'s reagent synthesis circuits.</span>"
visible_message("<span class='warning'>[src] buzzes oddly!</span>")
flick("medibot_spark", src)
patient = null
currently_healing = 0
target = null
busy = 0
emagged = 1
on = 1
update_icons()
. = 1
ignored |= user
ignore_list |= user
/mob/living/bot/medbot/explode()
on = 0
@@ -255,15 +229,15 @@
qdel(src)
return
/mob/living/bot/medbot/proc/valid_healing_target(var/mob/living/carbon/human/H)
/mob/living/bot/medbot/confirmTarget(var/mob/living/carbon/human/H)
if(!..())
return 0
if(H.stat == DEAD) // He's dead, Jim
return null
return 0
if(H.suiciding)
return null
if(H in ignored)
return null
return 0
if(emagged)
return treatment_emag
+43 -137
View File
@@ -17,23 +17,22 @@
maxHealth = 150
mob_bump_flag = HEAVY
min_target_dist = 0
max_target_dist = 250
target_speed = 3
max_frustration = 5
botcard_access = list(access_maint_tunnels, access_mailsorting, access_cargo, access_cargo_bot, access_qm, access_mining, access_mining_station)
var/busy = 0
var/mode = MULE_IDLE
var/atom/movable/load
var/paused = 0
var/crates_only = 1
var/auto_return = 1
var/safety = 1
var/list/path = list()
var/frustration = 0
var/turf/target
var/targetName
var/turf/home
var/homeName
var/turf/obstacle
var/global/amount = 0
@@ -71,19 +70,6 @@
dat += "Power: [on ? "On" : "Off"]<BR>"
if(!open)
dat += "Status: "
switch(mode)
if(MULE_IDLE)
dat += "Ready"
if(MULE_MOVING, MULE_UNLOAD, MULE_PATH_DONE)
dat += "Navigating"
if(MULE_UNLOAD)
dat += "Unloading"
if(MULE_LOST)
dat += "Processing commands"
if(MULE_CALC_MIN to MULE_CALC_MAX)
dat += "Calculating navigation path"
dat += "<BR>Current Load: [load ? load.name : "<i>none</i>"]<BR>"
if(locked)
@@ -177,10 +163,9 @@
/mob/living/bot/mulebot/proc/obeyCommand(var/command)
switch(command)
if("Home")
mode = MULE_IDLE
resetTarget()
target = home
targetName = "Home"
mode = MULE_LOST
if("SetD")
var/new_dest
var/list/beaconlist = new()
@@ -192,13 +177,13 @@
else
alert("No destination beacons available.")
if(new_dest)
resetTarget()
target = get_turf(beaconlist[new_dest])
targetName = new_dest
if("GoTD")
if(mode == MULE_IDLE)
mode = MULE_LOST
paused = 0
if("Stop")
mode = MULE_IDLE
paused = 1
/mob/living/bot/mulebot/emag_act(var/remaining_charges, var/user)
locked = !locked
@@ -211,89 +196,49 @@
if(open)
icon_state = "mulebot-hatch"
return
if(mode == MULE_MOVING || mode == MULE_UNLOAD)
if(target_path.len && !paused)
icon_state = "mulebot1"
return
icon_state = "mulebot0"
/mob/living/bot/mulebot/Life()
..()
if(busy)
return
/mob/living/bot/mulebot/handleRegular()
if(!safety && prob(1))
flick("mulebot-emagged", src)
update_icons()
switch(mode)
if(MULE_IDLE) // Idle
return
if(MULE_MOVING) // Moving to target
if(!target) // Return home
if(auto_return && home)
target = home
targetName = "Home"
mode = MULE_LOST
else
mode = MULE_IDLE
update_icons()
return
if(loc == target) // Unload or stop
custom_emote(2, "makes a chiming sound.")
playsound(loc, 'sound/machines/chime.ogg', 50, 0)
mode = MULE_UNLOAD
update_icons()
return
if(path.len) // Move
makeStep()
sleep(10)
if(path.len)
makeStep()
else
mode = MULE_LOST
/mob/living/bot/mulebot/handleFrustrated()
custom_emote(2, "makes a sighing buzz.")
playsound(loc, 'sound/machines/buzz-sigh.ogg', 50, 0)
..()
update_icons()
return
if(MULE_UNLOAD)
unload(dir)
/mob/living/bot/mulebot/handleAdjacentTarget()
if(target == src.loc)
custom_emote(2, "makes a chiming sound.")
playsound(loc, 'sound/machines/chime.ogg', 50, 0)
UnarmedAttack(target)
resetTarget()
if(auto_return && home && (loc != home))
target = home
targetName = "Home"
if(auto_return && home && (loc != home))
target = home
targetName = "Home"
mode = MULE_LOST
else
mode = MULE_IDLE
update_icons()
return
if(MULE_LOST) // Lost my way
if(target)
spawn(0)
calc_path(obstacle)
mode = MULE_CALC_MIN
else
mode = MULE_IDLE
update_icons()
return
if(MULE_CALC_MIN to MULE_CALC_MAX) // Calcing path
if(path.len)
mode = MULE_PATH_DONE
update_icons()
else
++mode
return
if(MULE_PATH_DONE) // Done with path
obstacle = null
if(path.len)
frustration = 0
mode = MULE_MOVING
else
if(home)
target = home
targetName = "Home"
mode = MULE_LOST
else
mode = MULE_IDLE
update_icons()
/mob/living/bot/mulebot/confirmTarget()
return 1
/mob/living/bot/mulebot/calcTargetPath()
..()
if(!target_path.len && target != home) // I presume that target is not null
resetTarget()
target = home
targetName = "Home"
/mob/living/bot/mulebot/stepToTarget()
if(paused)
return
..()
/mob/living/bot/mulebot/UnarmedAttack(var/turf/T)
if(T == src.loc)
unload(dir)
/mob/living/bot/mulebot/Bump(var/mob/living/M)
if(!safety && istype(M))
@@ -302,28 +247,6 @@
M.Weaken(5)
..()
/mob/living/bot/mulebot/proc/makeStep()
var/turf/next = path[1]
if(next == loc)
path -= next
return
var/moved = step_towards(src, next)
if(moved)
frustration = 0
path -= next
else if(frustration < 6)
if(frustration == 3)
custom_emote(2, "makes an annoyed buzzing sound")
playsound(loc, 'sound/machines/buzz-two.ogg', 50, 0)
++frustration
else
custom_emote(2, "makes a sighing buzz.")
playsound(loc, 'sound/machines/buzz-sigh.ogg', 50, 0)
obstacle = next
mode = MULE_LOST
/mob/living/bot/mulebot/proc/runOver(var/mob/living/carbon/human/H)
if(istype(H)) // No safety checks - WILL run over lying humans. Stop ERPing in the maint!
visible_message("<span class='warning'>[src] drives over [H]!</span>")
@@ -362,11 +285,6 @@
new /obj/effect/decal/cleanable/blood/oil(Tsec)
..()
/mob/living/bot/mulebot/proc/calc_path(var/turf/avoid = null)
path = AStar(loc, target, /turf/proc/CardinalTurfsWithAccess, /turf/proc/Distance, 0, 250, id = botcard, exclude = avoid)
if(!path)
path = list()
/mob/living/bot/mulebot/proc/load(var/atom/movable/C)
if(busy || load || get_dist(C, src) > 1 || !isturf(C.loc))
return
@@ -384,10 +302,6 @@
if(istype(crate))
crate.close()
//I'm sure someone will come along and ask why this is here... well people were dragging screen items onto the mule, and that was not cool.
//So this is a simple fix that only allows a selection of item types to be considered. Further narrowing-down is below.
//if(!istype(C,/obj/item) && !istype(C,/obj/machinery) && !istype(C,/obj/structure) && !ismob(C))
// return
busy = 1
C.loc = loc
@@ -428,11 +342,3 @@
AM.layer = initial(AM.layer)
AM.pixel_y = initial(AM.pixel_y)
busy = 0
#undef MULE_IDLE
#undef MULE_MOVING
#undef MULE_UNLOAD
#undef MULE_LOST
#undef MULE_CALC_MIN
#undef MULE_CALC_MAX
#undef MULE_PATH_DONE
+45 -308
View File
@@ -6,8 +6,8 @@
health = 50
req_one_access = list(access_security, access_forensics_lockers)
botcard_access = list(access_security, access_sec_doors, access_forensics_lockers, access_morgue, access_maint_tunnels)
var/mob/target
patrol_speed = 2
target_speed = 3
var/idcheck = 0 // If true, arrests for having weapons without authorization.
var/check_records = 0 // If true, arrests people without a record.
@@ -16,30 +16,9 @@
var/declare_arrests = 0 // If true, announces arrests over sechuds.
var/auto_patrol = 0 // If true, patrols on its own
var/mode = 0
#define SECBOT_IDLE 0 // idle
#define SECBOT_HUNT 1 // found target, hunting
#define SECBOT_ARREST 2 // arresting target
#define SECBOT_START_PATROL 3 // start patrol
#define SECBOT_WAIT_PATROL 4 // waiting for signals
#define SECBOT_PATROL 5 // patrolling
#define SECBOT_SUMMON 6 // summoned by PDA
var/is_attacking = 0
var/is_ranged = 0
var/awaiting_surrender = 0
var/obj/secbot_listener/listener = null
var/beacon_freq = 1445 // Navigation beacon frequency
var/control_freq = BOT_FREQ // Bot control frequency
var/list/path = list()
var/frustration = 0
var/turf/patrol_target = null // This is where we are headed
var/closest_dist // Used to find the closest beakon
var/destination = "__nearest__" // This is the current beacon's ID
var/next_destination = "__nearest__" // This is the next beacon's ID
var/nearest_beacon // Tag of the beakon that we assume to be the closest one
var/bot_version = 1.3
var/list/threat_found_sounds = new('sound/voice/bcriminal.ogg', 'sound/voice/bjustice.ogg', 'sound/voice/bfreeze.ogg')
var/list/preparing_arrest_sounds = new('sound/voice/bgod.ogg', 'sound/voice/biamthelaw.ogg', 'sound/voice/bsecureday.ogg', 'sound/voice/bradio.ogg', 'sound/voice/binsult.ogg', 'sound/voice/bcreep.ogg')
@@ -48,24 +27,8 @@
desc = "It's Officer Beep O'sky! Powered by a potato and a shot of whiskey."
auto_patrol = 1
/mob/living/bot/secbot/New()
..()
listener = new /obj/secbot_listener(src)
listener.secbot = src
spawn(5) // Since beepsky is made on the start... this delay is necessary
if(radio_controller)
radio_controller.add_object(listener, control_freq, filter = RADIO_SECBOT)
radio_controller.add_object(listener, beacon_freq, filter = RADIO_NAVBEACONS)
/mob/living/bot/secbot/turn_off()
..()
target = null
frustration = 0
mode = SECBOT_IDLE
/mob/living/bot/secbot/update_icons()
if(on && is_attacking)
if(on && busy)
icon_state = "secbot-c"
else
icon_state = "secbot[on]"
@@ -78,7 +41,7 @@
/mob/living/bot/secbot/attack_hand(var/mob/user)
user.set_machine(src)
var/dat
dat += "<TT><B>Automatic Security Unit v[bot_version]</B></TT><BR><BR>"
dat += "<TT><B>Automatic Security Unit</B></TT><BR><BR>"
dat += "Status: <A href='?src=\ref[src];power=1'>[on ? "On" : "Off"]</A><BR>"
dat += "Behaviour controls are [locked ? "locked" : "unlocked"]<BR>"
dat += "Maintenance panel is [open ? "opened" : "closed"]"
@@ -89,7 +52,7 @@
dat += "Operating Mode: <A href='?src=\ref[src];operation=switchmode'>[arrest_type ? "Detain" : "Arrest"]</A><BR>"
dat += "Report Arrests: <A href='?src=\ref[src];operation=declarearrests'>[declare_arrests ? "Yes" : "No"]</A><BR>"
dat += "Auto Patrol: <A href='?src=\ref[src];operation=patrol'>[auto_patrol ? "On" : "Off"]</A>"
user << browse("<HEAD><TITLE>Securitron v[bot_version] controls</TITLE></HEAD>[dat]", "window=autosec")
user << browse("<HEAD><TITLE>Securitron controls</TITLE></HEAD>[dat]", "window=autosec")
onclose(user, "autosec")
return
@@ -118,7 +81,6 @@
arrest_type = !arrest_type
if("patrol")
auto_patrol = !auto_patrol
mode = SECBOT_IDLE
if("declarearrests")
declare_arrests = !declare_arrests
attack_hand(usr)
@@ -129,127 +91,47 @@
if(health < curhealth)
target = user
awaiting_surrender = 5
mode = SECBOT_HUNT
/mob/living/bot/secbot/Life()
/mob/living/bot/secbot/startPatrol()
if(!locked) // Stop running away when we set you up
return
..()
if(!on)
return
if(client)
return
if(!target)
scan_view()
/mob/living/bot/secbot/confirmTarget(var/atom/A)
if(!..())
return 0
if(!locked && (mode == SECBOT_START_PATROL || mode == SECBOT_PATROL)) // Stop running away when we set you up
mode = SECBOT_IDLE
return (check_threat(A) > 3)
switch(mode)
if(SECBOT_IDLE)
if(auto_patrol && locked)
mode = SECBOT_START_PATROL
/mob/living/bot/secbot/lookForTargets()
for(var/mob/living/M in view(src))
if(M.stat == DEAD)
continue
if(confirmTarget(M))
var/threat = check_threat(M)
target = M
awaiting_surrender = -1
say("Level [threat] infraction alert!")
custom_emote(1, "points at [M.name]!")
return
if(SECBOT_HUNT) // Target is in the view or has been recently - chase it
if(frustration > 7)
target = null
frustration = 0
awaiting_surrender = 0
mode = SECBOT_IDLE
return
if(target)
var/threat = check_threat(target)
if(threat < 4) // Re-evaluate in case they dropped the weapon or something
target = null
frustration = 0
awaiting_surrender = 0
mode = SECBOT_IDLE
return
if(!(target in view(7, src)))
++frustration
if(Adjacent(target))
mode = SECBOT_ARREST
return
else
if(is_ranged)
RangedAttack(target)
else
step_towards(src, target) // Melee bots chase a bit faster
spawn(8)
if(!Adjacent(target))
step_towards(src, target)
spawn(16)
if(!Adjacent(target))
step_towards(src, target)
/mob/living/bot/secbot/calcTargetPath()
..()
if(awaiting_surrender != -1)
awaiting_surrender = 5 // This implies that a) we have already approached the target and b) it has moved after the warning
if(SECBOT_ARREST) // Target is next to us - attack it
if(!target)
mode = SECBOT_IDLE
if(!Adjacent(target))
awaiting_surrender = 5 // I'm done playing nice
mode = SECBOT_HUNT
return
var/threat = check_threat(target)
if(threat < 4)
target = null
awaiting_surrender = 0
frustration = 0
mode = SECBOT_IDLE
return
if(awaiting_surrender < 5 && ishuman(target) && !target.lying)
if(awaiting_surrender == 0)
say("Down on the floor, [target]! You have five seconds to comply.")
++awaiting_surrender
else
UnarmedAttack(target)
if(ishuman(target) && declare_arrests)
var/area/location = get_area(src)
broadcast_security_hud_message("[src] is [arrest_type ? "detaining" : "arresting"] a level [check_threat(target)] suspect <b>[target]</b> in <b>[location]</b>.", src)
return
if(SECBOT_START_PATROL)
if(path.len && patrol_target)
mode = SECBOT_PATROL
return
else if(patrol_target)
spawn(0)
calc_path()
if(!path.len)
patrol_target = null
mode = SECBOT_IDLE
else
mode = SECBOT_PATROL
if(!patrol_target)
if(next_destination)
find_next_target()
else
find_patrol_target()
say("Engaging patrol mode.")
mode = SECBOT_WAIT_PATROL
return
if(SECBOT_WAIT_PATROL)
if(patrol_target)
mode = SECBOT_START_PATROL
else
++frustration
if(frustration > 120)
frustration = 0
mode = SECBOT_IDLE
if(SECBOT_PATROL)
patrol_step()
spawn(10)
patrol_step()
return
if(SECBOT_SUMMON)
patrol_step()
spawn(8)
patrol_step()
spawn(16)
patrol_step()
return
/mob/living/bot/secbot/handleAdjacentTarget()
if(awaiting_surrender < 5 && ishuman(target) && !target:lying)
if(awaiting_surrender == -1)
say("Down on the floor, [target]! You have five seconds to comply.")
++awaiting_surrender
else
UnarmedAttack(target)
if(ishuman(target) && declare_arrests)
var/area/location = get_area(src)
broadcast_security_hud_message("[src] is [arrest_type ? "detaining" : "arresting"] a level [check_threat(target)] suspect <b>[target]</b> in <b>[location]</b>.", src)
// say("Engaging patrol mode.")
/mob/living/bot/secbot/UnarmedAttack(var/mob/M, var/proximity)
if(!..())
@@ -271,31 +153,33 @@
C.stun_effect_act(0, 60, null)
playsound(loc, 'sound/weapons/Egloves.ogg', 50, 1, -1)
do_attack_animation(C)
is_attacking = 1
busy = 1
update_icons()
spawn(2)
is_attacking = 0
busy = 0
update_icons()
visible_message("<span class='warning'>[C] was prodded by [src] with a stun baton!</span>")
else
playsound(loc, 'sound/weapons/handcuffs.ogg', 30, 1, -2)
visible_message("<span class='warning'>[src] is trying to put handcuffs on [C]!</span>")
busy = 1
if(do_mob(src, C, 60))
if(!C.handcuffed)
C.handcuffed = new /obj/item/weapon/handcuffs(C)
C.update_inv_handcuffed()
if(preparing_arrest_sounds.len)
playsound(loc, pick(preparing_arrest_sounds), 50, 0)
busy = 0
else if(istype(M, /mob/living/simple_animal))
var/mob/living/simple_animal/S = M
S.AdjustStunned(10)
S.adjustBruteLoss(15)
do_attack_animation(M)
playsound(loc, "swing_hit", 50, 1, -1)
is_attacking = 1
busy = 1
update_icons()
spawn(2)
is_attacking = 0
busy = 0
update_icons()
visible_message("<span class='warning'>[M] was beaten by [src] with a stun baton!</span>")
@@ -319,30 +203,8 @@
new /obj/effect/decal/cleanable/blood/oil(Tsec)
qdel(src)
/mob/living/bot/secbot/proc/scan_view()
for(var/mob/living/M in view(7, src))
if(M.invisibility >= INVISIBILITY_LEVEL_ONE)
continue
if(M.stat)
continue
var/threat = check_threat(M)
if(threat >= 4)
target = M
say("Level [threat] infraction alert!")
custom_emote(1, "points at [M.name]!")
mode = SECBOT_HUNT
break
return
/mob/living/bot/secbot/proc/calc_path(var/turf/avoid = null)
path = AStar(loc, patrol_target, /turf/proc/CardinalTurfsWithAccess, /turf/proc/Distance, 0, 120, id=botcard, exclude=avoid)
if(!path)
path = list()
/mob/living/bot/secbot/proc/check_threat(var/mob/living/M)
if(!M || !istype(M) || M.stat || src == M)
if(!M || !istype(M) || M.stat == DEAD || src == M)
return 0
if(emagged)
@@ -350,131 +212,6 @@
return M.assess_perp(access_scanner, 0, idcheck, check_records, check_arrest)
/mob/living/bot/secbot/proc/patrol_step()
if(loc == patrol_target)
patrol_target = null
path = list()
mode = SECBOT_IDLE
return
if(path.len && patrol_target)
var/turf/next = path[1]
if(loc == next)
path -= next
return
var/moved = step_towards(src, next)
if(moved)
path -= next
frustration = 0
else
++frustration
if(frustration > 5) // Make a new path
mode = SECBOT_START_PATROL
return
else
mode = SECBOT_START_PATROL
/mob/living/bot/secbot/proc/find_patrol_target()
send_status()
nearest_beacon = null
next_destination = "__nearest__"
listener.post_signal(beacon_freq, "findbeacon", "patrol")
/mob/living/bot/secbot/proc/find_next_target()
send_status()
nearest_beacon = null
listener.post_signal(beacon_freq, "findbeacon", "patrol")
/mob/living/bot/secbot/proc/send_status()
var/list/kv = list(
"type" = "secbot",
"name" = name,
"loca" = get_area(loc),
"mode" = mode
)
listener.post_signal_multiple(control_freq, kv)
/obj/secbot_listener
var/mob/living/bot/secbot/secbot = null
/obj/secbot_listener/proc/post_signal(var/freq, var/key, var/value) // send a radio signal with a single data key/value pair
post_signal_multiple(freq, list("[key]" = value))
/obj/secbot_listener/proc/post_signal_multiple(var/freq, var/list/keyval) // send a radio signal with multiple data key/values
var/datum/radio_frequency/frequency = radio_controller.return_frequency(freq)
if(!frequency)
return
var/datum/signal/signal = new()
signal.source = secbot
signal.transmission_method = 1
signal.data = keyval.Copy()
if(signal.data["findbeacon"])
frequency.post_signal(secbot, signal, filter = RADIO_NAVBEACONS)
else if(signal.data["type"] == "secbot")
frequency.post_signal(secbot, signal, filter = RADIO_SECBOT)
else
frequency.post_signal(secbot, signal)
/obj/secbot_listener/receive_signal(datum/signal/signal)
if(!secbot || !secbot.on)
return
var/recv = signal.data["command"]
if(recv == "bot_status")
secbot.send_status()
return
if(signal.data["active"] == secbot)
switch(recv)
if("stop")
secbot.mode = SECBOT_IDLE
secbot.auto_patrol = 0
return
if("go")
secbot.mode = SECBOT_IDLE
secbot.auto_patrol = 1
return
if("summon")
secbot.patrol_target = signal.data["target"]
secbot.next_destination = secbot.destination
secbot.destination = null
//secbot.awaiting_beacon = 0
secbot.mode = SECBOT_SUMMON
secbot.calc_path()
secbot.say("Responding.")
return
recv = signal.data["beacon"]
var/valid = signal.data["patrol"]
if(!recv || !valid)
return
if(recv == secbot.next_destination) // This beacon is our target
secbot.destination = secbot.next_destination
secbot.patrol_target = signal.source.loc
secbot.next_destination = signal.data["next_patrol"]
else if(secbot.next_destination == "__nearest__")
var/dist = get_dist(secbot, signal.source.loc)
if(dist <= 1)
return
if(secbot.nearest_beacon)
if(dist < secbot.closest_dist)
secbot.nearest_beacon = recv
secbot.patrol_target = secbot.nearest_beacon
secbot.next_destination = signal.data["next_patrol"]
secbot.closest_dist = dist
return
else
secbot.nearest_beacon = recv
secbot.patrol_target = secbot.nearest_beacon
secbot.next_destination = signal.data["next_patrol"]
secbot.closest_dist = dist
//Secbot Construction
/obj/item/clothing/head/helmet/attackby(var/obj/item/device/assembly/signaler/S, mob/user as mob)
@@ -22,8 +22,15 @@
var/hungry = (500 - nutrition)/5 // So overeat would be 100 and default level would be 80
if (hungry >= 70) tally += hungry/50
if(wear_suit)
tally += wear_suit.slowdown
// Loop through some slots, and add up their slowdowns. Shoes are handled below, unfortunately.
// Includes slots which can provide armor, the back slot, and suit storage.
for(var/obj/item/I in list(wear_suit, w_uniform, back, gloves, head, s_store) )
tally += I.slowdown
// Hands are also included, to make the 'take off your armor instantly and carry it with you to go faster' trick no longer viable.
// This is done seperately to disallow negative numbers.
for(var/obj/item/I in list(r_hand, l_hand) )
tally += max(I.slowdown, 0)
if(istype(buckled, /obj/structure/bed/chair/wheelchair))
for(var/organ_name in list(BP_L_HAND, BP_R_HAND, BP_L_ARM, BP_R_ARM))
+11 -9
View File
@@ -1,4 +1,3 @@
/mob/living/carbon/process_resist()
//drop && roll
@@ -17,9 +16,12 @@
"<span class='notice'>You extinguish yourself.</span>"
)
ExtinguishMob()
return
return TRUE
else if(handcuffed)
if(..())
return TRUE
if(handcuffed)
spawn() escape_handcuffs()
else if(legcuffed)
spawn() escape_legcuffs()
@@ -57,8 +59,8 @@
"<span class='warning'>You attempt to remove \the [HC]. (This will take around [displaytime] minutes and you need to stand still)</span>"
)
if(do_after(src, breakouttime))
if(!handcuffed)
if(do_after(src, breakouttime, incapacitation_flags = INCAPACITATION_DEFAULT & ~INCAPACITATION_RESTRAINED))
if(!handcuffed || buckled)
return
visible_message(
"<span class='danger'>\The [src] manages to remove \the [handcuffed]!</span>",
@@ -91,7 +93,7 @@
"<span class='warning'>You attempt to remove \the [HC]. (This will take around [displaytime] minutes and you need to stand still)</span>"
)
if(do_after(src, breakouttime))
if(do_after(src, breakouttime, incapacitation_flags = INCAPACITATION_DEFAULT & ~INCAPACITATION_RESTRAINED))
if(!legcuffed || buckled)
return
visible_message(
@@ -113,7 +115,7 @@
"<span class='warning'>You attempt to break your [handcuffed.name]. (This will take around 5 seconds and you need to stand still)</span>"
)
if(do_after(src, 50))
if(do_after(src, 5 SECONDS, incapacitation_flags = INCAPACITATION_DEFAULT & ~INCAPACITATION_RESTRAINED))
if(!handcuffed || buckled)
return
@@ -134,7 +136,7 @@
src << "<span class='warning'>You attempt to break your legcuffs. (This will take around 5 seconds and you need to stand still)</span>"
visible_message("<span class='danger'>[src] is trying to break the legcuffs!</span>")
if(do_after(src, 50))
if(do_after(src, 5 SECONDS, incapacitation_flags = INCAPACITATION_DEFAULT & ~INCAPACITATION_RESTRAINED))
if(!legcuffed || buckled)
return
@@ -166,7 +168,7 @@
"<span class='warning'>You attempt to unbuckle yourself. (This will take around 2 minutes and you need to stand still)</span>"
)
if(do_after(usr, 1200))
if(do_after(usr, 2 MINUTES, incapacitation_flags = INCAPACITATION_DEFAULT & ~(INCAPACITATION_RESTRAINED | INCAPACITATION_BUCKLED_FULLY)))
if(!buckled)
return
visible_message("<span class='danger'>[usr] manages to unbuckle themself!</span>",
+2 -2
View File
@@ -10,13 +10,13 @@
// Try put it in their backpack
if(istype(src.back,/obj/item/weapon/storage))
var/obj/item/weapon/storage/backpack = src.back
if(backpack.contents.len < backpack.storage_slots)
if(backpack.can_be_inserted(newitem, 1))
newitem.forceMove(src.back)
return 1
// Try to place it in any item that can store stuff, on the mob.
for(var/obj/item/weapon/storage/S in src.contents)
if (S.contents.len < S.storage_slots)
if (S.can_be_inserted(newitem, 1))
newitem.forceMove(S)
return 1
return 0
+34 -44
View File
@@ -510,52 +510,38 @@ default behaviour is:
if ((get_dist(src, pulling) > 1 || diag))
if (isliving(pulling))
var/mob/living/M = pulling
var/ok = 1
if (locate(/obj/item/weapon/grab, M.grabbed_by))
if (prob(75))
var/obj/item/weapon/grab/G = pick(M.grabbed_by)
if (istype(G, /obj/item/weapon/grab))
for(var/mob/O in viewers(M, null))
O.show_message(text("\red [] has been pulled from []'s grip by []", G.affecting, G.assailant, src), 1)
//G = null
qdel(G)
else
ok = 0
if (locate(/obj/item/weapon/grab, M.grabbed_by.len))
ok = 0
if (ok)
var/atom/movable/t = M.pulling
M.stop_pulling()
var/atom/movable/t = M.pulling
M.stop_pulling()
if(!istype(M.loc, /turf/space))
var/area/A = get_area(M)
if(A.has_gravity)
//this is the gay blood on floor shit -- Added back -- Skie
if (M.lying && (prob(M.getBruteLoss() / 6)))
if(!istype(M.loc, /turf/space))
var/area/A = get_area(M)
if(A.has_gravity)
//this is the gay blood on floor shit -- Added back -- Skie
if (M.lying && (prob(M.getBruteLoss() / 6)))
var/turf/location = M.loc
if (istype(location, /turf/simulated))
location.add_blood(M)
//pull damage with injured people
if(prob(25))
M.adjustBruteLoss(1)
visible_message("<span class='danger'>\The [M]'s [M.isSynthetic() ? "state worsens": "wounds open more"] from being dragged!</span>")
if(M.pull_damage())
if(prob(25))
M.adjustBruteLoss(2)
visible_message("<span class='danger'>\The [M]'s [M.isSynthetic() ? "state" : "wounds"] worsen terribly from being dragged!</span>")
var/turf/location = M.loc
if (istype(location, /turf/simulated))
location.add_blood(M)
//pull damage with injured people
if(prob(25))
M.adjustBruteLoss(1)
visible_message("<span class='danger'>\The [M]'s [M.isSynthetic() ? "state worsens": "wounds open more"] from being dragged!</span>")
if(M.pull_damage())
if(prob(25))
M.adjustBruteLoss(2)
visible_message("<span class='danger'>\The [M]'s [M.isSynthetic() ? "state" : "wounds"] worsen terribly from being dragged!</span>")
var/turf/location = M.loc
if (istype(location, /turf/simulated))
location.add_blood(M)
if(ishuman(M))
var/mob/living/carbon/human/H = M
var/blood_volume = round(H.vessel.get_reagent_amount("blood"))
if(blood_volume > 0)
H.vessel.remove_reagent("blood", 1)
if(ishuman(M))
var/mob/living/carbon/human/H = M
var/blood_volume = round(H.vessel.get_reagent_amount("blood"))
if(blood_volume > 0)
H.vessel.remove_reagent("blood", 1)
step(pulling, get_dir(pulling.loc, T))
if(t)
M.start_pulling(t)
step(pulling, get_dir(pulling.loc, T))
if(t)
M.start_pulling(t)
else
if (pulling)
if (istype(pulling, /obj/structure/window))
@@ -595,11 +581,13 @@ default behaviour is:
//unbuckling yourself
if(buckled)
spawn() escape_buckle()
return TRUE
//Breaking out of a locker?
if( src.loc && (istype(src.loc, /obj/structure/closet)) )
var/obj/structure/closet/C = loc
spawn() C.mob_breakout(src)
return TRUE
/mob/living/proc/escape_inventory(obj/item/weapon/holder/H)
if(H != src.loc) return
@@ -662,7 +650,7 @@ default behaviour is:
src << "<span class='notice'>You are now [resting ? "resting" : "getting up"]</span>"
/mob/living/proc/is_allowed_vent_crawl_item(var/obj/item/carried_item)
return isnull(get_inventory_slot(carried_item))
return (get_inventory_slot(carried_item) == 0)
/mob/living/simple_animal/spiderbot/is_allowed_vent_crawl_item(var/obj/item/carried_item)
if(carried_item == held_item)
@@ -730,10 +718,12 @@ default behaviour is:
return
if(!ignore_items)
var/list/badItems = list()
for(var/obj/item/carried_item in contents)//If the monkey got on objects.
if(is_allowed_vent_crawl_item(carried_item))
continue
src << "<span class='warning'>You can't be carrying items or have items equipped when vent crawling!</span>"
if(!is_allowed_vent_crawl_item(carried_item))
badItems += carried_item.name
if(badItems.len)
src << "<span class='warning'>Your [english_list(badItems)] prevent[badItems.len == 1 ? "s" : ""] you from ventcrawling.</span>"
return
if(isslime(src))
@@ -28,10 +28,9 @@
user << "You activate the analyzer's microlaser, analyzing \the [loaded_item] and breaking it down."
flick("portable_analyzer_scan", src)
playsound(src.loc, 'sound/items/Welder2.ogg', 50, 1)
var/list/temp_tech = ConvertReqString2List(loaded_item.origin_tech)
for(var/T in temp_tech)
files.UpdateTech(T, temp_tech[T])
user << "\The [loaded_item] had level [temp_tech[T]] in [T]."
for(var/T in loaded_item.origin_tech)
files.UpdateTech(T, loaded_item.origin_tech[T])
user << "\The [loaded_item] had level [loaded_item.origin_tech[T]] in [CallTechName(T)]."
loaded_item = null
for(var/obj/I in contents)
for(var/mob/M in I.contents)
@@ -20,6 +20,7 @@ var/global/list/robot_modules = list(
w_class = 100.0
item_state = "electronic"
flags = CONDUCT
var/hide_on_manifest = 0
var/channels = list()
var/networks = list()
var/languages = list(LANGUAGE_SOL_COMMON = 1, LANGUAGE_TRADEBAND = 1, LANGUAGE_UNATHI = 0, LANGUAGE_SIIK_TAJR = 0, LANGUAGE_SKRELLIAN = 0, LANGUAGE_GUTTER = 0)
@@ -617,6 +618,7 @@ var/global/list/robot_modules = list(
/obj/item/weapon/robot_module/syndicate
name = "illegal robot module"
hide_on_manifest = 1
languages = list(
LANGUAGE_SOL_COMMON = 1,
LANGUAGE_TRADEBAND = 1,
@@ -651,6 +653,7 @@ var/global/list/robot_modules = list(
/obj/item/weapon/robot_module/security/combat
name = "combat robot module"
hide_on_manifest = 1
sprites = list("Combat Android" = "droid-combat")
/obj/item/weapon/robot_module/combat/New()
@@ -665,6 +668,7 @@ var/global/list/robot_modules = list(
/obj/item/weapon/robot_module/drone
name = "drone module"
hide_on_manifest = 1
no_slip = 1
networks = list(NETWORK_ENGINEERING)
@@ -747,6 +751,7 @@ var/global/list/robot_modules = list(
/obj/item/weapon/robot_module/drone/construction
name = "construction drone module"
hide_on_manifest = 1
channels = list("Engineering" = 1)
languages = list()
@@ -72,7 +72,8 @@
/mob/living/simple_animal/Login()
if(src && src.client)
src.client.screen = null
src.client.screen = list()
src.client.screen += src.client.void
..()
/mob/living/simple_animal/updatehealth()
+1 -1
View File
@@ -30,7 +30,7 @@
world.update_status()
client.images = null //remove the images such as AIs being unable to see runes
client.screen = null //remove hud items just in case
client.screen = list() //remove hud items just in case
if(hud_used) qdel(hud_used) //remove the hud objects
hud_used = new /datum/hud(src)
+16 -3
View File
@@ -362,6 +362,7 @@
log_game("[usr.key] AM failed due to disconnect.")
return
client.screen.Cut()
client.screen += client.void
if(!client)
log_game("[usr.key] AM failed due to disconnect.")
return
@@ -546,21 +547,33 @@
if(ismob(AM))
if(!can_pull_mobs || !can_pull_size)
src << "<span class='warning'>It won't budge!</span>"
src << "<span class='warning'>They won't budge!</span>"
return
if((mob_size < M.mob_size) && (can_pull_mobs != MOB_PULL_LARGER))
src << "<span class='warning'>It won't budge!</span>"
src << "<span class='warning'>[M] is too large for you to move!</span>"
return
if((mob_size == M.mob_size) && (can_pull_mobs == MOB_PULL_SMALLER))
src << "<span class='warning'>It won't budge!</span>"
src << "<span class='warning'>[M] is too heavy for you to move!</span>"
return
// If your size is larger than theirs and you have some
// kind of mob pull value AT ALL, you will be able to pull
// them, so don't bother checking that explicitly.
if(M.grabbed_by.len)
// Only start pulling when nobody else has a grab on them
. = 1
for(var/obj/item/weapon/grab/G in M.grabbed_by)
if(G.assailant != usr)
. = 0
else
qdel(G)
if(!.)
src << "<span class='warning'>Somebody has a grip on them!</span>"
return
if(!iscarbon(src))
M.LAssailant = null
else
+6 -3
View File
@@ -57,8 +57,14 @@
G.dancing = 1
G.adjust_position()
dancing = 1
//stop pulling the affected
if(assailant.pulling == affecting)
assailant.stop_pulling()
adjust_position()
//Used by throw code to hand over the mob, instead of throwing the grab. The grab is then deleted by the throw code.
/obj/item/weapon/grab/proc/throw_held()
if(affecting)
@@ -91,9 +97,6 @@
assailant.client.screen -= hud
assailant.client.screen += hud
if(assailant.pulling == affecting)
assailant.stop_pulling()
if(state <= GRAB_AGGRESSIVE)
allow_upgrade = 1
//disallow upgrading if we're grabbing more than one person
@@ -66,11 +66,26 @@
icon_state = "seromi_default"
species_allowed = list("Teshari")
teshari_altdefault
name = "Teshari Alt. Default"
icon_state = "seromi_ears"
species_allowed = list("Teshari")
teshari_tight
name = "Teshari Tight"
icon_state = "seromi_tight"
species_allowed = list("Teshari")
teshari_excited
name = "Teshari Spiky"
icon_state = "seromi_spiky"
species_allowed = list("Teshari")
teshari_spike
name = "Teshari Spike"
icon_state = "seromi_spike"
species_allowed = list("Teshari")
teshari_long
name = "Teshari Overgrown"
icon_state = "seromi_long"
@@ -81,7 +96,7 @@
icon_state = "seromi_burst"
species_allowed = list("Teshari")
teshari_burst
teshari_shortburst
name = "Teshari Short Starburst"
icon_state = "seromi_burst_short"
species_allowed = list("Teshari")
+1 -1
View File
@@ -54,7 +54,7 @@
src << "<span class='danger'>Deadchat is globally muted.</span>"
return
if(is_preference_enabled(/datum/client_preference/show_dsay))
if(!is_preference_enabled(/datum/client_preference/show_dsay))
usr << "<span class='danger'>You have deadchat muted.</span>"
return
+21 -21
View File
@@ -1,7 +1,7 @@
// This file is a modified version of https://raw2.github.com/Baystation12/OldCode-BS12/master/code/TakePicture.dm
#define NANOMAP_ICON_SIZE 4
#define NANOMAP_MAX_ICON_DIMENSION 1024
#define NANOMAP_MAX_ICON_DIMENSION 1200
#define NANOMAP_TILES_PER_IMAGE (NANOMAP_MAX_ICON_DIMENSION / NANOMAP_ICON_SIZE)
@@ -19,42 +19,42 @@
/client/proc/nanomapgen_DumpImage()
set name = "Generate NanoUI Map"
set category = "Server"
if(holder)
nanomapgen_DumpTile(1, 1, text2num(input(usr,"Enter the Z level to generate")))
nanomapgen_DumpTile(1, 1, text2num(input(usr,"Enter the Z level to generate")))
/client/proc/nanomapgen_DumpTile(var/startX = 1, var/startY = 1, var/currentZ = 1, var/endX = -1, var/endY = -1)
if (endX < 0 || endX > world.maxx)
endX = world.maxx
if (endY < 0 || endY > world.maxy)
endY = world.maxy
if (currentZ < 0 || currentZ > world.maxz)
usr << "NanoMapGen: <B>ERROR: currentZ ([currentZ]) must be between 1 and [world.maxz]</B>"
sleep(3)
return NANOMAP_TERMINALERR
if (startX > endX)
usr << "NanoMapGen: <B>ERROR: startX ([startX]) cannot be greater than endX ([endX])</B>"
sleep(3)
return NANOMAP_TERMINALERR
if (startY > endX)
usr << "NanoMapGen: <B>ERROR: startY ([startY]) cannot be greater than endY ([endY])</B>"
sleep(3)
return NANOMAP_TERMINALERR
var/icon/Tile = icon(file("nano/mapbase1024.png"))
var/icon/Tile = icon(file("nano/mapbase1200.png"))
if (Tile.Width() != NANOMAP_MAX_ICON_DIMENSION || Tile.Height() != NANOMAP_MAX_ICON_DIMENSION)
world.log << "NanoMapGen: <B>ERROR: BASE IMAGE DIMENSIONS ARE NOT [NANOMAP_MAX_ICON_DIMENSION]x[NANOMAP_MAX_ICON_DIMENSION]</B>"
sleep(3)
return NANOMAP_TERMINALERR
world.log << "NanoMapGen: <B>GENERATE MAP ([startX],[startY],[currentZ]) to ([endX],[endY],[currentZ])</B>"
world.log << "NanoMapGen: <B>GENERATE MAP ([startX],[startY],[currentZ]) to ([endX],[endY],[currentZ])</B>"
usr << "NanoMapGen: <B>GENERATE MAP ([startX],[startY],[currentZ]) to ([endX],[endY],[currentZ])</B>"
var/count = 0;
@@ -62,26 +62,26 @@
for(var/WorldY = startY, WorldY <= endY, WorldY++)
var/atom/Turf = locate(WorldX, WorldY, currentZ)
var/icon/TurfIcon = new(Turf.icon, Turf.icon_state)
TurfIcon.Scale(NANOMAP_ICON_SIZE, NANOMAP_ICON_SIZE)
Tile.Blend(TurfIcon, ICON_OVERLAY, ((WorldX - 1) * NANOMAP_ICON_SIZE), ((WorldY - 1) * NANOMAP_ICON_SIZE))
count++
if (count % 8000 == 0)
world.log << "NanoMapGen: <B>[count] tiles done</B>"
sleep(1)
var/mapFilename = "nanomap_z[currentZ]-new.png"
world.log << "NanoMapGen: <B>sending [mapFilename] to client</B>"
usr << browse(Tile, "window=picture;file=[mapFilename];display=0")
world.log << "NanoMapGen: <B>Done.</B>"
usr << "NanoMapGen: <B>Done. File [mapFilename] uploaded to your cache.</B>"
if (Tile.Width() != NANOMAP_MAX_ICON_DIMENSION || Tile.Height() != NANOMAP_MAX_ICON_DIMENSION)
+5
View File
@@ -56,6 +56,7 @@
var/disfigured = 0 // Scarred/burned beyond recognition.
var/cannot_amputate // Impossible to amputate.
var/cannot_break // Impossible to fracture.
var/cannot_gib // Impossible to gib, distinct from amputation.
var/joint = "joint" // Descriptive string used in dislocation.
var/amputation_point // Descriptive string used in amputation.
var/dislocated = 0 // If you target a joint, you can dislocate the limb, causing temporary damage to the organ.
@@ -727,12 +728,16 @@ Note that amputating the affected organ does in fact remove the infection from t
"<span class='moderate'><b>Your [src.name] goes flying off!</b></span>",\
"<span class='danger'>You hear a terrible sound of [gore_sound].</span>")
if(DROPLIMB_BURN)
if(cannot_gib)
return
var/gore = "[(status & ORGAN_ROBOT) ? "": " of burning flesh"]"
owner.visible_message(
"<span class='danger'>\The [owner]'s [src.name] flashes away into ashes!</span>",\
"<span class='moderate'><b>Your [src.name] flashes away into ashes!</b></span>",\
"<span class='danger'>You hear a crackling sound[gore].</span>")
if(DROPLIMB_BLUNT)
if(cannot_gib)
return
var/gore = "[(status & ORGAN_ROBOT) ? "": " in shower of gore"]"
var/gore_sound = "[(status & ORGAN_ROBOT) ? "rending sound of tortured metal" : "sickening splatter of gore"]"
owner.visible_message(
+21
View File
@@ -104,6 +104,7 @@
icon = 'icons/obj/robot_component.dmi'
icon_state = "camera"
dead_icon = "camera_broken"
verbs |= /obj/item/organ/internal/eyes/proc/change_eye_color
/obj/item/organ/internal/eyes/robot
name = "optical sensor"
@@ -112,6 +113,26 @@
..()
robotize()
/obj/item/organ/internal/eyes/proc/change_eye_color()
set name = "Change Eye Color"
set desc = "Changes your robotic eye color instantly."
set category = "IC"
set src in usr
var/current_color = rgb(eye_colour[1],eye_colour[2],eye_colour[3])
var/new_color = input("Pick a new color for your eyes.","Eye Color", current_color) as null|color
if(new_color && owner)
// input() supplies us with a hex color, which we can't use, so we convert it to rbg values.
var/list/new_color_rgb_list = hex2rgb(new_color)
// First, update mob vars.
owner.r_eyes = new_color_rgb_list[1]
owner.g_eyes = new_color_rgb_list[2]
owner.b_eyes = new_color_rgb_list[3]
// Now sync the organ's eye_colour list.
update_colour()
// Finally, update the eye icon on the mob.
owner.update_eyes()
/obj/item/organ/internal/eyes/replaced(var/mob/living/carbon/human/target)
// Apply our eye colour to the target.
+1
View File
@@ -145,6 +145,7 @@
joint = "jaw"
amputation_point = "neck"
gendered_icon = 1
cannot_gib = 1
encased = "skull"
var/can_intake_reagents = 1
+1 -1
View File
@@ -590,7 +590,7 @@
icon = 'icons/obj/lighting.dmi'
force = 2
throwforce = 5
w_class = 2
w_class = 1
var/status = 0 // LIGHT_OK, LIGHT_BURNED or LIGHT_BROKEN
var/base_state
var/switchcount = 0 // number of times switched
+3 -1
View File
@@ -146,7 +146,7 @@
PreFire(A,user,params) //They're using the new gun system, locate what they're aiming at.
return
if(user && user.a_intent == I_HELP) //regardless of what happens, refuse to shoot if help intent is on
if(user && user.a_intent == I_HELP && user.is_preference_enabled(/datum/client_preference/safefiring)) //regardless of what happens, refuse to shoot if help intent is on
user << "<span class='warning'>You refrain from firing your [src] as your intent is set to help.</span>"
else
Fire(A,user,params) //Otherwise, fire normally.
@@ -164,6 +164,8 @@
add_fingerprint(user)
user.break_cloak()
if(!special_check(user))
return
+1 -1
View File
@@ -5,7 +5,7 @@
desc = "A vicious alien projectile weapon. Parts of it quiver gelatinously, as though the thing is insectile and alive."
var/last_regen = 0
var/spike_gen_time = 100
var/spike_gen_time = 150
var/max_spikes = 3
var/spikes = 3
release_force = 30
@@ -110,7 +110,7 @@ obj/item/weapon/gun/energy/retro
max_shots = 4
fire_delay = 35
force = 10
w_class = 4
w_class = 5 // So it can't fit in a backpack.
accuracy = -3 //shooting at the hip
scoped_accuracy = 0
// requires_two_hands = 1
@@ -3,7 +3,7 @@
desc = "A portable anti-armour rifle fitted with a scope, the HI PTR-7 Rifle was originally designed to used against armoured exosuits. It is capable of punching through windows and non-reinforced walls with ease. Fires armor piercing 14.5mm shells."
icon_state = "heavysniper"
item_state = "l6closednomag" //placeholder
w_class = 4
w_class = 5 // So it can't fit in a backpack.
force = 10
slot_flags = SLOT_BACK
origin_tech = list(TECH_COMBAT = 8, TECH_MATERIAL = 2, TECH_ILLEGAL = 8)
@@ -136,9 +136,6 @@
icon_state = "xray"
damage = 50
armor_penetration = 10
stun = 3
weaken = 3
stutter = 3
muzzle_type = /obj/effect/projectile/xray/muzzle
tracer_type = /obj/effect/projectile/xray/tracer
@@ -23,6 +23,7 @@
owner = newowner
loc = null
verbs.Cut()
toggle_permission(TARGET_CAN_RADIO)
/obj/aiming_overlay/proc/toggle_permission(var/perm)
@@ -202,6 +203,7 @@ obj/aiming_overlay/proc/update_aiming_deferred()
else
owner << "<span class='notice'>You will no longer aim rather than fire.</span>"
owner.client.remove_gun_icons()
owner.gun_setting_icon.icon_state = "gun[active]"
/obj/aiming_overlay/proc/cancel_aiming(var/no_message = 0)
if(!aiming_with || !aiming_at)
@@ -1,4 +1,8 @@
/mob/living/proc/trigger_aiming(var/trigger_type)
//as core click exists at the mob level
/mob/proc/trigger_aiming(var/trigger_type)
return
/mob/living/trigger_aiming(var/trigger_type)
if(!aimed.len)
return
for(var/obj/aiming_overlay/AO in aimed)
@@ -16,14 +20,10 @@
if(!owner.canClick())
return
owner.setClickCooldown(5) // Spam prevention, essentially.
if(owner.a_intent == I_HELP)
if(owner.a_intent == I_HELP && owner.is_preference_enabled(/datum/client_preference/safefiring))
owner << "<span class='warning'>You refrain from firing \the [aiming_with] as your intent is set to help.</span>"
return
owner.visible_message("<span class='danger'>\The [owner] pulls the trigger reflexively!</span>")
var/obj/item/weapon/gun/G = aiming_with
if(istype(G))
G.Fire(aiming_at, owner)
/mob/living/ClickOn(var/atom/A, var/params)
. = ..()
trigger_aiming(TARGET_CAN_CLICK)
+2 -2
View File
@@ -366,13 +366,13 @@
return
if(istype(O,/obj/item/weapon/storage/bag/plants))
var/obj/item/weapon/storage/bag/plants/bag = O
var/failed = 1
for(var/obj/item/G in O.contents)
if(!G.reagents || !G.reagents.total_volume)
continue
failed = 0
O.contents -= G
G.loc = src
bag.remove_from_storage(G, src)
holdingitems += G
if(holdingitems && holdingitems.len >= limit)
break
+1 -1
View File
@@ -55,7 +55,7 @@
return
if(!affects_dead && M.stat == DEAD)
return
if(overdose && (dose > overdose) && (location != CHEM_TOUCH))
if(overdose && (volume > overdose) && (location != CHEM_TOUCH))
overdose(M, alien)
var/removed = metabolism
if(ingest_met && (location == CHEM_INGEST))
@@ -0,0 +1,115 @@
var/list/lunchables_lunches_ = list(/obj/item/weapon/reagent_containers/food/snacks/sandwich,
/obj/item/weapon/reagent_containers/food/snacks/meatbreadslice,
/obj/item/weapon/reagent_containers/food/snacks/tofubreadslice,
/obj/item/weapon/reagent_containers/food/snacks/creamcheesebreadslice,
/obj/item/weapon/reagent_containers/food/snacks/margheritaslice,
/obj/item/weapon/reagent_containers/food/snacks/meatpizzaslice,
/obj/item/weapon/reagent_containers/food/snacks/mushroompizzaslice,
/obj/item/weapon/reagent_containers/food/snacks/vegetablepizzaslice,
/obj/item/weapon/reagent_containers/food/snacks/tastybread,
/obj/item/weapon/reagent_containers/food/snacks/liquidfood,
/obj/item/weapon/reagent_containers/food/snacks/jellysandwich/cherry,
/obj/item/weapon/reagent_containers/food/snacks/tossedsalad)
var/list/lunchables_snacks_ = list(/obj/item/weapon/reagent_containers/food/snacks/donut/jelly,
/obj/item/weapon/reagent_containers/food/snacks/donut/cherryjelly,
/obj/item/weapon/reagent_containers/food/snacks/muffin,
/obj/item/weapon/reagent_containers/food/snacks/popcorn,
/obj/item/weapon/reagent_containers/food/snacks/sosjerky,
/obj/item/weapon/reagent_containers/food/snacks/no_raisin,
/obj/item/weapon/reagent_containers/food/snacks/spacetwinkie,
/obj/item/weapon/reagent_containers/food/snacks/cheesiehonkers,
/obj/item/weapon/reagent_containers/food/snacks/poppypretzel,
/obj/item/weapon/reagent_containers/food/snacks/carrotfries,
/obj/item/weapon/reagent_containers/food/snacks/candiedapple,
/obj/item/weapon/reagent_containers/food/snacks/applepie,
/obj/item/weapon/reagent_containers/food/snacks/cherrypie,
/obj/item/weapon/reagent_containers/food/snacks/plumphelmetbiscuit,
/obj/item/weapon/reagent_containers/food/snacks/appletart,
/obj/item/weapon/reagent_containers/food/snacks/carrotcakeslice,
/obj/item/weapon/reagent_containers/food/snacks/cheesecakeslice,
/obj/item/weapon/reagent_containers/food/snacks/plaincakeslice,
/obj/item/weapon/reagent_containers/food/snacks/orangecakeslice,
/obj/item/weapon/reagent_containers/food/snacks/limecakeslice,
/obj/item/weapon/reagent_containers/food/snacks/lemoncakeslice,
/obj/item/weapon/reagent_containers/food/snacks/chocolatecakeslice,
/obj/item/weapon/reagent_containers/food/snacks/birthdaycakeslice,
/obj/item/weapon/reagent_containers/food/snacks/watermelonslice,
/obj/item/weapon/reagent_containers/food/snacks/applecakeslice,
/obj/item/weapon/reagent_containers/food/snacks/pumpkinpieslice,
/obj/item/weapon/reagent_containers/food/snacks/skrellsnacks)
var/list/lunchables_drinks_ = list(/obj/item/weapon/reagent_containers/food/drinks/cans/cola,
/obj/item/weapon/reagent_containers/food/drinks/cans/waterbottle,
/obj/item/weapon/reagent_containers/food/drinks/cans/space_mountain_wind,
/obj/item/weapon/reagent_containers/food/drinks/cans/dr_gibb,
/obj/item/weapon/reagent_containers/food/drinks/cans/starkist,
/obj/item/weapon/reagent_containers/food/drinks/cans/space_up,
/obj/item/weapon/reagent_containers/food/drinks/cans/lemon_lime,
/obj/item/weapon/reagent_containers/food/drinks/cans/iced_tea,
/obj/item/weapon/reagent_containers/food/drinks/cans/grape_juice,
/obj/item/weapon/reagent_containers/food/drinks/cans/tonic,
/obj/item/weapon/reagent_containers/food/drinks/cans/sodawater)
// This default list is a bit different, it contains items we don't want
var/list/lunchables_drink_reagents_ = list(/datum/reagent/drink/nothing,
/datum/reagent/drink/doctor_delight,
/datum/reagent/drink/dry_ramen,
/datum/reagent/drink/hell_ramen,
/datum/reagent/drink/hot_ramen,
/datum/reagent/drink/nuka_cola,)
// This default list is a bit different, it contains items we don't want
var/list/lunchables_ethanol_reagents_ = list(/datum/reagent/ethanol/acid_spit,
/datum/reagent/ethanol/atomicbomb,
/datum/reagent/ethanol/beepsky_smash,
/datum/reagent/ethanol/coffee,
/datum/reagent/ethanol/hippies_delight,
/datum/reagent/ethanol/hooch,
/datum/reagent/ethanol/thirteenloko,
/datum/reagent/ethanol/manhattan_proj,
/datum/reagent/ethanol/neurotoxin,
/datum/reagent/ethanol/pwine,
/datum/reagent/ethanol/threemileisland,
/datum/reagent/ethanol/toxins_special)
/proc/lunchables_lunches()
if(!(lunchables_lunches_[lunchables_lunches_[1]]))
lunchables_lunches_ = init_lunchable_list(lunchables_lunches_)
return lunchables_lunches_
/proc/lunchables_snacks()
if(!(lunchables_snacks_[lunchables_snacks_[1]]))
lunchables_snacks_ = init_lunchable_list(lunchables_snacks_)
return lunchables_snacks_
/proc/lunchables_drinks()
if(!(lunchables_drinks_[lunchables_drinks_[1]]))
lunchables_drinks_ = init_lunchable_list(lunchables_drinks_)
return lunchables_drinks_
/proc/lunchables_drink_reagents()
if(!(lunchables_drink_reagents_[lunchables_drink_reagents_[1]]))
lunchables_drink_reagents_ = init_lunchable_reagent_list(lunchables_drink_reagents_, /datum/reagent/drink)
return lunchables_drink_reagents_
/proc/lunchables_ethanol_reagents()
if(!(lunchables_ethanol_reagents_[lunchables_ethanol_reagents_[1]]))
lunchables_ethanol_reagents_ = init_lunchable_reagent_list(lunchables_ethanol_reagents_, /datum/reagent/ethanol)
return lunchables_ethanol_reagents_
/proc/init_lunchable_list(var/list/lunches)
. = list()
for(var/lunch in lunches)
var/obj/O = lunch
.[initial(O.name)] = lunch
return sortAssoc(.)
/proc/init_lunchable_reagent_list(var/list/banned_reagents, var/reagent_types)
. = list()
for(var/reagent_type in subtypes(reagent_types))
if(reagent_type in banned_reagents)
continue
var/datum/reagent/reagent = reagent_type
.[initial(reagent.name)] = initial(reagent.id)
return sortAssoc(.)
@@ -2242,6 +2242,12 @@
filling_color = "#FF7575"
bitesize = 2
center_of_mass = list("x"=16, "y"=13)
/obj/item/weapon/reagent_containers/food/snacks/meatbreadslice/New()
..()
if(!(reagents.total_volume))
reagents.add_reagent("protein", 4)
reagents.add_reagent("nutriment", 2)
/obj/item/weapon/reagent_containers/food/snacks/sliceable/xenomeatbread
name = "xenomeatbread loaf"
@@ -2266,6 +2272,12 @@
filling_color = "#8AFF75"
bitesize = 2
center_of_mass = list("x"=16, "y"=13)
/obj/item/weapon/reagent_containers/food/snacks/xenomeatbreadslice/New()
..()
if(!(reagents.total_volume))
reagents.add_reagent("protein", 4)
reagents.add_reagent("nutriment", 2)
/obj/item/weapon/reagent_containers/food/snacks/sliceable/bananabread
name = "Banana-nut bread"
@@ -2290,6 +2302,12 @@
filling_color = "#EDE5AD"
bitesize = 2
center_of_mass = list("x"=16, "y"=8)
/obj/item/weapon/reagent_containers/food/snacks/bananabreadslice/New()
..()
if(!(reagents.total_volume))
reagents.add_reagent("banana", 4)
reagents.add_reagent("nutriment", 4)
/obj/item/weapon/reagent_containers/food/snacks/sliceable/tofubread
name = "Tofubread"
@@ -2313,6 +2331,11 @@
filling_color = "#F7FFE0"
bitesize = 2
center_of_mass = list("x"=16, "y"=13)
/obj/item/weapon/reagent_containers/food/snacks/tofubreadslice/New()
..()
if(!(reagents.total_volume))
reagents.add_reagent("nutriment", 6)
/obj/item/weapon/reagent_containers/food/snacks/sliceable/carrotcake
@@ -2338,6 +2361,12 @@
filling_color = "#FFD675"
bitesize = 2
center_of_mass = list("x"=16, "y"=14)
/obj/item/weapon/reagent_containers/food/snacks/carrotcakeslice/New()
..()
if(!(reagents.total_volume))
reagents.add_reagent("imidazoline", 2)
reagents.add_reagent("nutriment", 5)
/obj/item/weapon/reagent_containers/food/snacks/sliceable/braincake
name = "Brain Cake"
@@ -2363,6 +2392,13 @@
filling_color = "#E6AEDB"
bitesize = 2
center_of_mass = list("x"=16, "y"=12)
/obj/item/weapon/reagent_containers/food/snacks/braincakeslice/New()
..()
if(!(reagents.total_volume))
reagents.add_reagent("protein", 5)
reagents.add_reagent("nutriment", 1)
reagents.add_reagent("alkysine", 2)
/obj/item/weapon/reagent_containers/food/snacks/sliceable/cheesecake
name = "Cheese Cake"
@@ -2387,6 +2423,12 @@
filling_color = "#FAF7AF"
bitesize = 2
center_of_mass = list("x"=16, "y"=14)
/obj/item/weapon/reagent_containers/food/snacks/cheesecakeslice/New()
..()
if(!(reagents.total_volume))
reagents.add_reagent("protein", 3)
reagents.add_reagent("nutriment", 2)
/obj/item/weapon/reagent_containers/food/snacks/sliceable/plaincake
name = "Vanilla Cake"
@@ -2409,6 +2451,11 @@
filling_color = "#F7EDD5"
bitesize = 2
center_of_mass = list("x"=16, "y"=14)
/obj/item/weapon/reagent_containers/food/snacks/plaincakeslice/New()
..()
if(!(reagents.total_volume))
reagents.add_reagent("nutriment", 4)
/obj/item/weapon/reagent_containers/food/snacks/sliceable/orangecake
name = "Orange Cake"
@@ -2431,6 +2478,11 @@
filling_color = "#FADA8E"
bitesize = 2
center_of_mass = list("x"=16, "y"=14)
/obj/item/weapon/reagent_containers/food/snacks/orangecakeslice/New()
..()
if(!(reagents.total_volume))
reagents.add_reagent("nutriment", 4)
/obj/item/weapon/reagent_containers/food/snacks/sliceable/limecake
name = "Lime Cake"
@@ -2453,6 +2505,11 @@
filling_color = "#CBFA8E"
bitesize = 2
center_of_mass = list("x"=16, "y"=14)
/obj/item/weapon/reagent_containers/food/snacks/limecakeslice/New()
..()
if(!(reagents.total_volume))
reagents.add_reagent("nutriment", 4)
/obj/item/weapon/reagent_containers/food/snacks/sliceable/lemoncake
name = "Lemon Cake"
@@ -2475,6 +2532,11 @@
filling_color = "#FAFA8E"
bitesize = 2
center_of_mass = list("x"=16, "y"=14)
/obj/item/weapon/reagent_containers/food/snacks/lemoncakeslice/New()
..()
if(!(reagents.total_volume))
reagents.add_reagent("nutriment", 4)
/obj/item/weapon/reagent_containers/food/snacks/sliceable/chocolatecake
name = "Chocolate Cake"
@@ -2497,6 +2559,11 @@
filling_color = "#805930"
bitesize = 2
center_of_mass = list("x"=16, "y"=14)
/obj/item/weapon/reagent_containers/food/snacks/chocolatecakeslice/New()
..()
if(!(reagents.total_volume))
reagents.add_reagent("nutriment", 4)
/obj/item/weapon/reagent_containers/food/snacks/sliceable/cheesewheel
name = "Cheese wheel"
@@ -2543,6 +2610,12 @@
filling_color = "#FFD6D6"
bitesize = 2
center_of_mass = list("x"=16, "y"=14)
/obj/item/weapon/reagent_containers/food/snacks/birthdaycakeslice/New()
..()
if(!(reagents.total_volume))
reagents.add_reagent("nutriment", 4)
reagents.add_reagent("sprinkles", 2)
/obj/item/weapon/reagent_containers/food/snacks/sliceable/bread
name = "Bread"
@@ -2566,6 +2639,11 @@
filling_color = "#D27332"
bitesize = 2
center_of_mass = list("x"=16, "y"=4)
/obj/item/weapon/reagent_containers/food/snacks/breadslice/New()
..()
if(!(reagents.total_volume))
reagents.add_reagent("nutriment", 1)
/obj/item/weapon/reagent_containers/food/snacks/sliceable/creamcheesebread
@@ -2591,7 +2669,12 @@
filling_color = "#FFF896"
bitesize = 2
center_of_mass = list("x"=16, "y"=13)
/obj/item/weapon/reagent_containers/food/snacks/creamcheesebreadslice/New()
..()
if(!(reagents.total_volume))
reagents.add_reagent("protein", 3)
reagents.add_reagent("nutriment", 1)
/obj/item/weapon/reagent_containers/food/snacks/watermelonslice
name = "Watermelon Slice"
@@ -2600,7 +2683,11 @@
filling_color = "#FF3867"
bitesize = 2
center_of_mass = list("x"=16, "y"=10)
/obj/item/weapon/reagent_containers/food/snacks/watermelonslice/New()
..()
if(!(reagents.total_volume))
reagents.add_reagent("watermelonjuice", 1)
/obj/item/weapon/reagent_containers/food/snacks/sliceable/applecake
name = "Apple Cake"
@@ -2623,6 +2710,11 @@
filling_color = "#EBF5B8"
bitesize = 2
center_of_mass = list("x"=16, "y"=14)
/obj/item/weapon/reagent_containers/food/snacks/applecakeslice/New()
..()
if(!(reagents.total_volume))
reagents.add_reagent("nutriment", 3)
/obj/item/weapon/reagent_containers/food/snacks/sliceable/pumpkinpie
name = "Pumpkin Pie"
@@ -2645,6 +2737,11 @@
filling_color = "#F5B951"
bitesize = 2
center_of_mass = list("x"=16, "y"=12)
/obj/item/weapon/reagent_containers/food/snacks/pumpkinpieslice/New()
..()
if(!(reagents.total_volume))
reagents.add_reagent("nutriment", 3)
/obj/item/weapon/reagent_containers/food/snacks/cracker
name = "Cracker"
@@ -2687,6 +2784,13 @@
filling_color = "#BAA14C"
bitesize = 2
center_of_mass = list("x"=18, "y"=13)
/obj/item/weapon/reagent_containers/food/snacks/margheritaslice/New()
..()
if(!(reagents.total_volume))
reagents.add_reagent("nutriment", 5)
reagents.add_reagent("protein", 1)
reagents.add_reagent("tomatojuice", 1)
/obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/meatpizza
name = "Meatpizza"
@@ -2709,6 +2813,12 @@
filling_color = "#BAA14C"
bitesize = 2
center_of_mass = list("x"=18, "y"=13)
/obj/item/weapon/reagent_containers/food/snacks/meatpizzaslice/New()
..()
if(!(reagents.total_volume))
reagents.add_reagent("protein", 7)
reagents.add_reagent("tomatojuice", 1)
/obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/mushroompizza
name = "Mushroompizza"
@@ -2731,6 +2841,12 @@
filling_color = "#BAA14C"
bitesize = 2
center_of_mass = list("x"=18, "y"=13)
/obj/item/weapon/reagent_containers/food/snacks/mushroompizzaslice/New()
..()
if(!(reagents.total_volume))
reagents.add_reagent("nutriment", 5)
reagents.add_reagent("protein", 1)
/obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/vegetablepizza
name = "Vegetable pizza"
@@ -2755,6 +2871,14 @@
filling_color = "#BAA14C"
bitesize = 2
center_of_mass = list("x"=18, "y"=13)
/obj/item/weapon/reagent_containers/food/snacks/vegetablepizzaslice/New()
..()
if(!(reagents.total_volume))
reagents.add_reagent("nutriment", 4)
reagents.add_reagent("protein", 1)
reagents.add_reagent("tomatojuice", 1)
reagents.add_reagent("imidazoline", 2)
/obj/item/pizzabox
name = "pizza box"
+1 -1
View File
@@ -395,7 +395,7 @@
/datum/design/item/mecha/drill
name = "Drill"
id = "drill"
id = "mech_drill"
build_path = /obj/item/mecha_parts/mecha_equipment/tool/drill
/datum/design/item/mecha/extinguisher
-13
View File
@@ -47,19 +47,6 @@ won't update every console in existence) but it's more of a hassle to do. Also,
req_access = list(access_research) //Data and setting manipulation requires scientist access.
/obj/machinery/computer/rdconsole/proc/CallTechName(var/ID) //A simple helper proc to find the name of a tech with a given ID.
var/datum/tech/check_tech
var/return_name = null
for(var/T in typesof(/datum/tech) - /datum/tech)
check_tech = null
check_tech = new T()
if(check_tech.id == ID)
return_name = check_tech.name
qdel(check_tech)
check_tech = null
break
return return_name
/obj/machinery/computer/rdconsole/proc/CallMaterialName(var/ID)
var/return_name = ID
switch(return_name)
+7
View File
@@ -122,6 +122,13 @@ research holder datum.
KT.level = max(KT.level + 1, level - 1)
return
// A simple helper proc to find the name of a tech with a given ID.
/proc/CallTechName(var/ID)
for(var/T in subtypes(/datum/tech))
var/datum/tech/check_tech = T
if(initial(check_tech.id) == ID)
return initial(check_tech.name)
/***************************************************************
** Technology Datums **
** Includes all the various technoliges and what they make. **
@@ -30,7 +30,6 @@
icon_state = "satchel"
slot_flags = SLOT_BELT | SLOT_POCKET
w_class = 3
storage_slots = 50
max_storage_space = 200 //Doesn't matter what this is, so long as it's more or equal to storage_slots * ore.w_class
max_storage_space = 100
max_w_class = 3
can_hold = list(/obj/item/weapon/fossil)