mirror of
https://github.com/PolarisSS13/Polaris.git
synced 2026-01-01 13:02:32 +00:00
Merge branch 'master' into cleanupTwo
This commit is contained in:
@@ -10,6 +10,7 @@
|
||||
anchored = 1
|
||||
use_power = 0
|
||||
idle_power_usage = 5 // 5 Watts for thermostat related circuitry
|
||||
circuit = /obj/item/weapon/circuitboard/unary_atmos/cooler
|
||||
|
||||
var/heatsink_temperature = T20C // The constant temperature reservoir into which the freezer pumps heat. Probably the hull of the station or something.
|
||||
var/internal_volume = 600 // L
|
||||
@@ -24,7 +25,6 @@
|
||||
..()
|
||||
initialize_directions = dir
|
||||
component_parts = list()
|
||||
component_parts += new /obj/item/weapon/circuitboard/unary_atmos/cooler(src)
|
||||
component_parts += new /obj/item/weapon/stock_parts/matter_bin(src)
|
||||
component_parts += new /obj/item/weapon/stock_parts/capacitor(src)
|
||||
component_parts += new /obj/item/weapon/stock_parts/capacitor(src)
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
anchored = 1
|
||||
use_power = 0
|
||||
idle_power_usage = 5 //5 Watts for thermostat related circuitry
|
||||
circuit = /obj/item/weapon/circuitboard/unary_atmos/heater
|
||||
|
||||
var/max_temperature = T20C + 680
|
||||
var/internal_volume = 600 //L
|
||||
@@ -25,7 +26,6 @@
|
||||
initialize_directions = dir
|
||||
|
||||
component_parts = list()
|
||||
component_parts += new /obj/item/weapon/circuitboard/unary_atmos/heater(src)
|
||||
component_parts += new /obj/item/weapon/stock_parts/matter_bin(src)
|
||||
component_parts += new /obj/item/weapon/stock_parts/capacitor(src)
|
||||
component_parts += new /obj/item/weapon/stock_parts/capacitor(src)
|
||||
|
||||
3
code/__defines/appearance.dm
Normal file
3
code/__defines/appearance.dm
Normal file
@@ -0,0 +1,3 @@
|
||||
// Consider these images/atoms as part of the UI/HUD
|
||||
#define APPEARANCE_UI_IGNORE_ALPHA RESET_COLOR|RESET_TRANSFORM|NO_CLIENT_COLOR|RESET_ALPHA
|
||||
#define APPEARANCE_UI RESET_COLOR|RESET_TRANSFORM|NO_CLIENT_COLOR
|
||||
@@ -25,26 +25,6 @@
|
||||
#define PROCESS_KILL 26 // Used to trigger removal from a processing list.
|
||||
#define MAX_GEAR_COST 10 // Used in chargen for accessory loadout limit.
|
||||
|
||||
// Preference toggles.
|
||||
#define SOUND_ADMINHELP 0x1
|
||||
#define SOUND_MIDI 0x2
|
||||
#define SOUND_AMBIENCE 0x4
|
||||
#define SOUND_LOBBY 0x8
|
||||
#define CHAT_OOC 0x10
|
||||
#define CHAT_DEAD 0x20
|
||||
#define CHAT_GHOSTEARS 0x40
|
||||
#define CHAT_GHOSTSIGHT 0x80
|
||||
#define CHAT_PRAYER 0x100
|
||||
#define CHAT_RADIO 0x200
|
||||
#define CHAT_ATTACKLOGS 0x400
|
||||
#define CHAT_DEBUGLOGS 0x800
|
||||
#define CHAT_LOOC 0x1000
|
||||
#define CHAT_GHOSTRADIO 0x2000
|
||||
#define SHOW_TYPING 0x4000
|
||||
#define CHAT_NOICONS 0x8000
|
||||
|
||||
#define TOGGLES_DEFAULT (SOUND_ADMINHELP|SOUND_MIDI|SOUND_AMBIENCE|SOUND_LOBBY|CHAT_OOC|CHAT_DEAD|CHAT_GHOSTEARS|CHAT_GHOSTSIGHT|CHAT_PRAYER|CHAT_RADIO|CHAT_ATTACKLOGS|CHAT_LOOC)
|
||||
|
||||
// For secHUDs and medHUDs and variants. The number is the location of the image on the list hud_list of humans.
|
||||
#define HEALTH_HUD 1 // A simple line rounding the mob's number health.
|
||||
#define STATUS_HUD 2 // Alive, dead, diseased, etc.
|
||||
|
||||
4
code/__defines/unit_tests.dm
Normal file
4
code/__defines/unit_tests.dm
Normal file
@@ -0,0 +1,4 @@
|
||||
#define ASCII_ESC ascii2text(27)
|
||||
#define ASCII_RED "[ASCII_ESC]\[31m"
|
||||
#define ASCII_GREEN "[ASCII_ESC]\[32m"
|
||||
#define ASCII_RESET "[ASCII_ESC]\[0m"
|
||||
@@ -244,7 +244,7 @@
|
||||
var/turf/ear = get_turf(M)
|
||||
if(ear)
|
||||
// Ghostship is magic: Ghosts can hear radio chatter from anywhere
|
||||
if(speaker_coverage[ear] || (istype(M, /mob/observer/dead) && (M.client) && (M.client.prefs.toggles & CHAT_GHOSTRADIO)))
|
||||
if(speaker_coverage[ear] || (istype(M, /mob/observer/dead) && M.is_preference_enabled(/datum/client_preference/ghost_radio)))
|
||||
. |= M // Since we're already looping through mobs, why bother using |= ? This only slows things down.
|
||||
return .
|
||||
|
||||
|
||||
@@ -78,7 +78,13 @@ var/global/list/socks_t = list(
|
||||
"Black knee" = "black_knee", "Black thigh" = "black_thigh", "Thin knee" = "thin_knee",
|
||||
"Thin thigh" = "thin_thigh", "Pantyhose" = "pantyhose", "Striped thigh" = "striped_thigh",
|
||||
"Striped knee" = "striped_knee", "Rainbow knee" = "rainbow_knee", "Rainbow thigh" = "rainbow_thigh",
|
||||
"Fishnets" = "fishnet", "Thin white thigh" = "thinwhite_thigh", "Thin white knee" = "thinwhite_knee", "None")
|
||||
"Fishnets" = "fishnet", "Thin white thigh" = "thinwhite_thigh", "Thin white knee" = "thinwhite_knee",
|
||||
"Green striped thigh" = "gstriped_thigh", "Green striped knee" = "gstriped_knee",
|
||||
"Purple striped thigh" = "pstriped_thigh", "Purple striped knee" = "pstriped_knee",
|
||||
"Blue striped thigh" = "bstriped_thigh", "Blue striped knee" = "bstriped_knee",
|
||||
"Yellow striped thigh" = "ystriped_thigh", "Yellow striped knee" = "ystriped_knee",
|
||||
"Red striped thigh" = "rstriped_thigh", "Red striped knee" = "rstriped_knee",
|
||||
"Orange striped thigh" = "ostriped_thigh", "Orange striped knee" = "ostriped_knee", "None")
|
||||
|
||||
//Backpacks
|
||||
var/global/list/backbaglist = list("Nothing", "Backpack", "Satchel", "Satchel Alt")
|
||||
|
||||
@@ -30,13 +30,6 @@
|
||||
|
||||
return "[output][and_text][input[index]]"
|
||||
|
||||
|
||||
/proc/ConvertReqString2List(var/list/source_list)
|
||||
var/list/temp_list = params2list(source_list)
|
||||
for(var/O in temp_list)
|
||||
temp_list[O] = text2num(temp_list[O])
|
||||
return temp_list
|
||||
|
||||
//Returns list element or null. Should prevent "index out of bounds" error.
|
||||
proc/listgetindex(var/list/list,index)
|
||||
if(istype(list) && list.len)
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
diary << "\[[time_stamp()]]DEBUG: [text][log_end]"
|
||||
|
||||
for(var/client/C in admins)
|
||||
if(C.prefs.toggles & CHAT_DEBUGLOGS)
|
||||
if(C.is_preference_enabled(/datum/client_preference/debug/show_debug_logs))
|
||||
C << "DEBUG: [text]"
|
||||
|
||||
|
||||
@@ -82,6 +82,9 @@
|
||||
/proc/log_misc(text)
|
||||
diary << "\[[time_stamp()]]MISC: [text][log_end]"
|
||||
|
||||
/proc/log_unit_test(text)
|
||||
world.log << "## UNIT_TEST: [text]"
|
||||
|
||||
//pretty print a direction bitflag, can be useful for debugging.
|
||||
/proc/print_dir(var/dir)
|
||||
var/list/comps = list()
|
||||
@@ -91,7 +94,7 @@
|
||||
if(dir & WEST) comps += "WEST"
|
||||
if(dir & UP) comps += "UP"
|
||||
if(dir & DOWN) comps += "DOWN"
|
||||
|
||||
|
||||
return english_list(comps, nothing_text="0", and_text="|", comma_text="|")
|
||||
|
||||
//more or less a logging utility
|
||||
|
||||
@@ -30,13 +30,10 @@ proc/random_hair_style(gender, species = "Human")
|
||||
var/list/valid_hairstyles = list()
|
||||
for(var/hairstyle in hair_styles_list)
|
||||
var/datum/sprite_accessory/S = hair_styles_list[hairstyle]
|
||||
|
||||
if(gender != NEUTER && gender != PLURAL)
|
||||
if(gender == MALE && S.gender == FEMALE)
|
||||
continue
|
||||
if(gender == FEMALE && S.gender == MALE)
|
||||
continue
|
||||
|
||||
if(gender == MALE && S.gender == FEMALE)
|
||||
continue
|
||||
if(gender == FEMALE && S.gender == MALE)
|
||||
continue
|
||||
if( !(species in S.species_allowed))
|
||||
continue
|
||||
valid_hairstyles[hairstyle] = hair_styles_list[hairstyle]
|
||||
@@ -52,13 +49,10 @@ proc/random_facial_hair_style(gender, species = "Human")
|
||||
var/list/valid_facialhairstyles = list()
|
||||
for(var/facialhairstyle in facial_hair_styles_list)
|
||||
var/datum/sprite_accessory/S = facial_hair_styles_list[facialhairstyle]
|
||||
|
||||
if(gender != NEUTER && gender != PLURAL)
|
||||
if(gender == MALE && S.gender == FEMALE)
|
||||
continue
|
||||
if(gender == FEMALE && S.gender == MALE)
|
||||
continue
|
||||
|
||||
if(gender == MALE && S.gender == FEMALE)
|
||||
continue
|
||||
if(gender == FEMALE && S.gender == MALE)
|
||||
continue
|
||||
if( !(species in S.species_allowed))
|
||||
continue
|
||||
|
||||
@@ -171,3 +165,88 @@ Proc for attack log creation, because really why not
|
||||
return 0
|
||||
var/mob/living/silicon/robot/R = thing.loc
|
||||
return (thing in R.module.modules)
|
||||
|
||||
/proc/get_exposed_defense_zone(var/atom/movable/target)
|
||||
var/obj/item/weapon/grab/G = locate() in target
|
||||
if(G && G.state >= GRAB_NECK) //works because mobs are currently not allowed to upgrade to NECK if they are grabbing two people.
|
||||
return pick("head", "l_hand", "r_hand", "l_foot", "r_foot", "l_arm", "r_arm", "l_leg", "r_leg")
|
||||
else
|
||||
return pick("chest", "groin")
|
||||
|
||||
/proc/do_mob(mob/user , mob/target, time = 30, uninterruptible = 0, progress = 1)
|
||||
if(!user || !target)
|
||||
return 0
|
||||
var/user_loc = user.loc
|
||||
var/target_loc = target.loc
|
||||
|
||||
var/holding = user.get_active_hand()
|
||||
var/datum/progressbar/progbar
|
||||
if (progress)
|
||||
progbar = new(user, time, target)
|
||||
|
||||
var/endtime = world.time+time
|
||||
var/starttime = world.time
|
||||
. = 1
|
||||
while (world.time < endtime)
|
||||
sleep(1)
|
||||
if (progress)
|
||||
progbar.update(world.time - starttime)
|
||||
if(!user || !target)
|
||||
. = 0
|
||||
break
|
||||
if(uninterruptible)
|
||||
continue
|
||||
|
||||
if(!user || user.incapacitated() || user.loc != user_loc)
|
||||
. = 0
|
||||
break
|
||||
|
||||
if(target.loc != target_loc)
|
||||
. = 0
|
||||
break
|
||||
|
||||
if(user.get_active_hand() != holding)
|
||||
. = 0
|
||||
break
|
||||
|
||||
if (progbar)
|
||||
qdel(progbar)
|
||||
|
||||
/proc/do_after(mob/user, delay, atom/target = null, needhand = 1, progress = 1, var/incapacitation_flags = INCAPACITATION_DEFAULT)
|
||||
if(!user)
|
||||
return 0
|
||||
var/atom/target_loc = null
|
||||
if(target)
|
||||
target_loc = target.loc
|
||||
|
||||
var/atom/original_loc = user.loc
|
||||
|
||||
var/holding = user.get_active_hand()
|
||||
|
||||
var/datum/progressbar/progbar
|
||||
if (progress)
|
||||
progbar = new(user, delay, target)
|
||||
|
||||
var/endtime = world.time + delay
|
||||
var/starttime = world.time
|
||||
. = 1
|
||||
while (world.time < endtime)
|
||||
sleep(1)
|
||||
if (progress)
|
||||
progbar.update(world.time - starttime)
|
||||
|
||||
if(!user || user.incapacitated(incapacitation_flags) || user.loc != original_loc)
|
||||
. = 0
|
||||
break
|
||||
|
||||
if(target_loc && (!target || target_loc != target.loc))
|
||||
. = 0
|
||||
break
|
||||
|
||||
if(needhand)
|
||||
if(user.get_active_hand() != holding)
|
||||
. = 0
|
||||
break
|
||||
|
||||
if (progbar)
|
||||
qdel(progbar)
|
||||
|
||||
@@ -161,7 +161,7 @@ var/syndicate_code_response//Code response for traitors.
|
||||
Obviously, some people will be better at this than others but in theory, everyone should be able to do it and it only enhances roleplay.
|
||||
Can probably be done through "{ }" but I don't really see the practical benefit.
|
||||
One example of an earlier system is commented below.
|
||||
/N
|
||||
-N
|
||||
*/
|
||||
|
||||
/proc/generate_code_phrase()//Proc is used for phrase and response in master_controller.dm
|
||||
|
||||
@@ -304,7 +304,7 @@ proc/TextPreview(var/string,var/len=40)
|
||||
// to always create it and then throw it out.
|
||||
/var/icon/text_tag_icons = new('./icons/chattags.dmi')
|
||||
/proc/create_text_tag(var/tagname, var/tagdesc = tagname, var/client/C = null)
|
||||
if(C && (C.prefs.toggles & CHAT_NOICONS))
|
||||
if(!(C && C.is_preference_enabled(/datum/client_preference/chat_tags)))
|
||||
return tagdesc
|
||||
return "<IMG src='\ref[text_tag_icons.icon]' class='text_tag' iconstate='[tagname]'" + (tagdesc ? " alt='[tagdesc]'" : "") + ">"
|
||||
|
||||
|
||||
@@ -30,11 +30,21 @@ proc/isDay(var/month, var/day)
|
||||
|
||||
var/next_duration_update = 0
|
||||
var/last_round_duration = 0
|
||||
proc/round_duration()
|
||||
var/round_start_time = 0
|
||||
|
||||
/hook/roundstart/proc/start_timer()
|
||||
round_start_time = world.time
|
||||
return 1
|
||||
|
||||
#define round_duration_in_ticks (round_start_time ? world.time - round_start_time : 0)
|
||||
|
||||
/proc/round_duration_as_text()
|
||||
if(!round_start_time)
|
||||
return "00:00"
|
||||
if(last_round_duration && world.time < next_duration_update)
|
||||
return last_round_duration
|
||||
|
||||
var/mills = world.time // 1/10 of a second, not real milliseconds but whatever
|
||||
var/mills = round_duration_in_ticks // 1/10 of a second, not real milliseconds but whatever
|
||||
//var/secs = ((mills % 36000) % 600) / 10 //Not really needed, but I'll leave it here for refrence.. or something
|
||||
var/mins = round((mills % 36000) / 600)
|
||||
var/hours = round(mills / 36000)
|
||||
|
||||
@@ -149,6 +149,26 @@
|
||||
if (rights & R_MENTOR) . += "[seperator]+MENTOR"
|
||||
return .
|
||||
|
||||
// Converts a hexadecimal color (e.g. #FF0050) to a list of numbers for red, green, and blue (e.g. list(255,0,80) ).
|
||||
/proc/hex2rgb(hex)
|
||||
// Strips the starting #, in case this is ever supplied without one, so everything doesn't break.
|
||||
if(findtext(hex,"#",1,2))
|
||||
hex = copytext(hex, 2)
|
||||
return list(hex2rgb_r(hex), hex2rgb_g(hex), hex2rgb_b(hex))
|
||||
|
||||
// The three procs below require that the '#' part of the hex be stripped, which hex2rgb() does automatically.
|
||||
/proc/hex2rgb_r(hex)
|
||||
var/hex_to_work_on = copytext(hex,1,3)
|
||||
return hex2num(hex_to_work_on)
|
||||
|
||||
/proc/hex2rgb_g(hex)
|
||||
var/hex_to_work_on = copytext(hex,3,5)
|
||||
return hex2num(hex_to_work_on)
|
||||
|
||||
/proc/hex2rgb_b(hex)
|
||||
var/hex_to_work_on = copytext(hex,5,7)
|
||||
return hex2num(hex_to_work_on)
|
||||
|
||||
// heat2color functions. Adapted from: http://www.tannerhelland.com/4435/convert-temperature-rgb-algorithm-code/
|
||||
/proc/heat2color(temp)
|
||||
return rgb(heat2color_r(temp), heat2color_g(temp), heat2color_b(temp))
|
||||
|
||||
@@ -646,47 +646,6 @@ proc/GaussRandRound(var/sigma,var/roundto)
|
||||
|
||||
else return get_step(ref, base_dir)
|
||||
|
||||
/proc/do_mob(var/mob/user, var/mob/target, var/delay = 30, var/numticks = 5, var/needhand = 1) //This is quite an ugly solution but i refuse to use the old request system.
|
||||
if(!user || !target) return 0
|
||||
if(numticks == 0) return 0
|
||||
|
||||
var/delayfraction = round(delay/numticks)
|
||||
var/original_user_loc = user.loc
|
||||
var/original_target_loc = target.loc
|
||||
var/holding = user.get_active_hand()
|
||||
|
||||
for(var/i = 0, i<numticks, i++)
|
||||
sleep(delayfraction)
|
||||
|
||||
if(!user || user.stat || user.weakened || user.stunned || user.loc != original_user_loc)
|
||||
return 0
|
||||
if(!target || target.loc != original_target_loc)
|
||||
return 0
|
||||
if(needhand && !(user.get_active_hand() == holding)) //Sometimes you don't want the user to have to keep their active hand
|
||||
return 0
|
||||
|
||||
return 1
|
||||
|
||||
/proc/do_after(var/mob/user as mob, delay as num, var/numticks = 5, var/needhand = 1)
|
||||
if(!user || isnull(user))
|
||||
return 0
|
||||
if(numticks == 0)
|
||||
return 0
|
||||
|
||||
var/delayfraction = round(delay/numticks)
|
||||
var/original_loc = user.loc
|
||||
var/holding = user.get_active_hand()
|
||||
|
||||
for(var/i = 0, i<numticks, i++)
|
||||
sleep(delayfraction)
|
||||
|
||||
if(!user || user.stat || user.weakened || user.stunned || user.loc != original_loc)
|
||||
return 0
|
||||
if(needhand && !(user.get_active_hand() == holding)) //Sometimes you don't want the user to have to keep their active hand
|
||||
return 0
|
||||
|
||||
return 1
|
||||
|
||||
//Takes: Anything that could possibly have variables and a varname to check.
|
||||
//Returns: 1 if found, 0 if not.
|
||||
/proc/hasvar(var/datum/A, var/varname)
|
||||
@@ -1351,3 +1310,15 @@ var/mob/dview/dview_mob = new
|
||||
// call to generate a stack trace and print to runtime logs
|
||||
/proc/crash_with(msg)
|
||||
CRASH(msg)
|
||||
|
||||
/proc/screen_loc2turf(scr_loc, turf/origin)
|
||||
var/tX = splittext(scr_loc, ",")
|
||||
var/tY = splittext(tX[2], ":")
|
||||
var/tZ = origin.z
|
||||
tY = tY[1]
|
||||
tX = splittext(tX[1], ":")
|
||||
tX = tX[1]
|
||||
tX = max(1, min(world.maxx, origin.x + (text2num(tX) - (world.view + 1))))
|
||||
tY = max(1, min(world.maxy, origin.y + (text2num(tY) - (world.view + 1))))
|
||||
return locate(tX, tY, tZ)
|
||||
|
||||
|
||||
@@ -87,6 +87,7 @@
|
||||
if(in_throw_mode)
|
||||
if(isturf(A) || isturf(A.loc))
|
||||
throw_item(A)
|
||||
trigger_aiming(TARGET_CAN_CLICK)
|
||||
return 1
|
||||
throw_mode_off()
|
||||
|
||||
@@ -94,6 +95,7 @@
|
||||
|
||||
if(W == A) // Handle attack_self
|
||||
W.attack_self(src)
|
||||
trigger_aiming(TARGET_CAN_CLICK)
|
||||
update_inv_active_hand(0)
|
||||
return 1
|
||||
|
||||
@@ -113,6 +115,8 @@
|
||||
if(ismob(A)) // No instant mob attacking
|
||||
setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
|
||||
UnarmedAttack(A, 1)
|
||||
|
||||
trigger_aiming(TARGET_CAN_CLICK)
|
||||
return 1
|
||||
|
||||
if(!isturf(loc)) // This is going to stop you from telekinesing from inside a closet, but I don't shed many tears for that
|
||||
@@ -134,12 +138,15 @@
|
||||
if(ismob(A)) // No instant mob attacking
|
||||
setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
|
||||
UnarmedAttack(A, 1)
|
||||
trigger_aiming(TARGET_CAN_CLICK)
|
||||
return
|
||||
else // non-adjacent click
|
||||
if(W)
|
||||
W.afterattack(A, src, 0, params) // 0: not Adjacent
|
||||
else
|
||||
RangedAttack(A, params)
|
||||
|
||||
trigger_aiming(TARGET_CAN_CLICK)
|
||||
return 1
|
||||
|
||||
/mob/proc/setClickCooldown(var/timeout)
|
||||
@@ -325,3 +332,20 @@
|
||||
else direction = WEST
|
||||
if(direction != dir)
|
||||
facedir(direction)
|
||||
|
||||
/obj/screen/click_catcher
|
||||
icon = 'icons/mob/screen1_full.dmi'
|
||||
icon_state = "passage0"
|
||||
layer = 0
|
||||
mouse_opacity = 2
|
||||
screen_loc = "1,1"
|
||||
|
||||
/obj/screen/click_catcher/Click(location, control, params)
|
||||
var/list/modifiers = params2list(params)
|
||||
if(modifiers["middle"] && istype(usr, /mob/living/carbon))
|
||||
var/mob/living/carbon/C = usr
|
||||
C.swap_hand()
|
||||
else
|
||||
var/turf/T = screen_loc2turf(modifiers["screen-loc"], get_turf(usr))
|
||||
T.Click(location, control, params)
|
||||
return 1
|
||||
|
||||
@@ -130,6 +130,8 @@
|
||||
using.layer = SCREEN_LAYER
|
||||
adding += using
|
||||
|
||||
mymob.client.screen = list()
|
||||
mymob.client.screen += adding + other
|
||||
mymob.client.screen += mymob.client.void
|
||||
|
||||
return
|
||||
@@ -41,6 +41,7 @@
|
||||
mymob.fire.name = "fire"
|
||||
mymob.fire.screen_loc = ui_fire
|
||||
|
||||
mymob.client.screen = null
|
||||
mymob.client.screen = list()
|
||||
mymob.client.screen += list( mymob.healths, mymob.blind, mymob.flash, mymob.fire) //, mymob.rest, mymob.sleep, mymob.mach )
|
||||
mymob.client.screen += src.adding + src.other
|
||||
mymob.client.screen += src.adding + src.other
|
||||
mymob.client.screen += mymob.client.void
|
||||
@@ -361,10 +361,11 @@
|
||||
mymob.radio_use_icon.color = ui_color
|
||||
mymob.radio_use_icon.alpha = ui_alpha
|
||||
|
||||
mymob.client.screen = null
|
||||
mymob.client.screen = list()
|
||||
|
||||
mymob.client.screen += hud_elements
|
||||
mymob.client.screen += src.adding + src.hotkeybuttons
|
||||
mymob.client.screen += mymob.client.void
|
||||
inventory_shown = 0;
|
||||
|
||||
return
|
||||
|
||||
@@ -27,9 +27,10 @@
|
||||
blobhealthdisplay.screen_loc = ui_internal
|
||||
blobhealthdisplay.layer = 20
|
||||
|
||||
mymob.client.screen = null
|
||||
mymob.client.screen = list()
|
||||
|
||||
mymob.client.screen += list(blobpwrdisplay, blobhealthdisplay)
|
||||
mymob.client.screen += mymob.client.void
|
||||
|
||||
/datum/hud/proc/slime_hud(ui_style = 'icons/mob/screen1_Midnight.dmi')
|
||||
|
||||
@@ -94,8 +95,9 @@
|
||||
src.adding += using
|
||||
hurt_intent = using
|
||||
|
||||
mymob.client.screen = null
|
||||
mymob.client.screen = list()
|
||||
mymob.client.screen += src.adding
|
||||
mymob.client.screen += mymob.client.void
|
||||
|
||||
return
|
||||
|
||||
@@ -151,6 +153,7 @@
|
||||
mymob.purged.name = "purged"
|
||||
mymob.purged.screen_loc = ui_construct_purge
|
||||
|
||||
mymob.client.screen = null
|
||||
mymob.client.screen = list()
|
||||
|
||||
mymob.client.screen += list(mymob.fire, mymob.healths, mymob.pullin, mymob.zone_sel, mymob.purged, mymob.flash)
|
||||
mymob.client.screen += mymob.client.void
|
||||
|
||||
@@ -157,10 +157,11 @@ var/obj/screen/robot_inventory
|
||||
mymob.gun_move_icon = new /obj/screen/gun/move(null)
|
||||
mymob.radio_use_icon = new /obj/screen/gun/radio(null)
|
||||
|
||||
mymob.client.screen = null
|
||||
mymob.client.screen = list()
|
||||
|
||||
mymob.client.screen += list( mymob.throw_icon, mymob.zone_sel, mymob.oxygen, mymob.fire, mymob.hands, mymob.healths, mymob:cells, mymob.pullin, mymob.blind, mymob.flash, robot_inventory, mymob.gun_setting_icon)
|
||||
mymob.client.screen += src.adding + src.other
|
||||
mymob.client.screen += mymob.client.void
|
||||
|
||||
return
|
||||
|
||||
|
||||
@@ -17,12 +17,11 @@
|
||||
if(can_reenter_corpse && mind && mind.current)
|
||||
if(A == mind.current || (mind.current in A)) // double click your corpse or whatever holds it
|
||||
reenter_corpse() // (cloning scanner, body bag, closet, mech, etc)
|
||||
return // seems legit.
|
||||
return
|
||||
|
||||
// Things you might plausibly want to follow
|
||||
if((ismob(A) && A != src) || istype(A,/obj/singularity))
|
||||
if(istype(A,/atom/movable))
|
||||
ManualFollow(A)
|
||||
|
||||
// Otherwise jump
|
||||
else
|
||||
following = null
|
||||
|
||||
@@ -55,6 +55,7 @@
|
||||
if(!..())
|
||||
return 0
|
||||
|
||||
setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
|
||||
A.attack_generic(src,rand(5,6),"bitten")
|
||||
|
||||
/*
|
||||
@@ -76,6 +77,9 @@
|
||||
Feedstop()
|
||||
return
|
||||
|
||||
//should have already been set if we are attacking a mob, but it doesn't hurt and will cover attacking non-mobs too
|
||||
setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
|
||||
|
||||
var/mob/living/M = A
|
||||
if (istype(M))
|
||||
|
||||
@@ -144,6 +148,7 @@
|
||||
custom_emote(1,"[friendly] [A]!")
|
||||
return
|
||||
|
||||
setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
|
||||
var/damage = rand(melee_damage_lower, melee_damage_upper)
|
||||
if(A.attack_generic(src,damage,attacktext,environment_smash) && loc && attack_sound)
|
||||
playsound(loc, attack_sound, 50, 1, 1)
|
||||
|
||||
10
code/_unit_tests.dm
Normal file
10
code/_unit_tests.dm
Normal file
@@ -0,0 +1,10 @@
|
||||
/*
|
||||
*
|
||||
* This file is used by Travis to indicate that Unit Tests are to be ran.
|
||||
* Do not add anything but the UNIT_TEST definition here as it will be overwritten by Travis when running tests.
|
||||
*
|
||||
*
|
||||
* Should you wish to edit set UNIT_TEST to 1 like so:
|
||||
* #define UNIT_TEST 1
|
||||
*/
|
||||
#define UNIT_TEST 0
|
||||
@@ -12,6 +12,6 @@ datum/controller/transfer_controller/Destroy()
|
||||
|
||||
datum/controller/transfer_controller/proc/process()
|
||||
currenttick = currenttick + 1
|
||||
if (world.time >= timerbuffer - 600)
|
||||
if (round_duration_in_ticks >= timerbuffer - 1 MINUTE)
|
||||
vote.autotransfer()
|
||||
timerbuffer = timerbuffer + config.vote_autotransfer_interval
|
||||
timerbuffer = timerbuffer + config.vote_autotransfer_interval
|
||||
|
||||
@@ -9,11 +9,11 @@
|
||||
*
|
||||
* To add some code to be called by the hook, define a proc under the type, as so:
|
||||
* @code
|
||||
/hook/foo/proc/bar()
|
||||
if(1)
|
||||
return 1 //Sucessful
|
||||
else
|
||||
return 0 //Error, or runtime.
|
||||
/hook/foo/proc/bar()
|
||||
if(1)
|
||||
return 1 //Sucessful
|
||||
else
|
||||
return 0 //Error, or runtime.
|
||||
* @endcode
|
||||
* All hooks must return nonzero on success, as runtimes will force return null.
|
||||
*/
|
||||
|
||||
@@ -317,9 +317,9 @@ var/global/datum/shuttle_controller/shuttle_controller
|
||||
"Arrivals dock" = "nuke_shuttle_dock_airlock",
|
||||
)
|
||||
|
||||
MS.announcer = "NDV Icarus"
|
||||
MS.arrival_message = "Attention, [station_short], you have a large signature approaching the station - looks unarmed to surface scans. We're too far out to intercept - brace for visitors."
|
||||
MS.departure_message = "Your visitors are on their way out of the system, [station_short], burning delta-v like it's nothing. Good riddance."
|
||||
MS.announcer = "Automated Traffic Control"
|
||||
MS.arrival_message = "Attention. A vessel is approaching the colony."
|
||||
MS.departure_message = "Attention. A vessel is now leaving from the colony."
|
||||
MS.interim = locate(/area/syndicate_station/transit)
|
||||
|
||||
MS.warmup_time = 0
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
usr.client.debug_variables(antag)
|
||||
message_admins("Admin [key_name_admin(usr)] is debugging the [antag.role_text] template.")
|
||||
|
||||
/client/proc/debug_controller(controller in list("Master","Ticker","Ticker Process","Air","Jobs","Sun","Radio","Supply","Shuttles","Emergency Shuttle","Configuration","pAI", "Cameras", "Transfer Controller", "Gas Data","Event","Plants","Alarm","Nano","Chemistry"))
|
||||
/client/proc/debug_controller(controller in list("Master","Ticker","Ticker Process","Air","Jobs","Sun","Radio","Supply","Shuttles","Emergency Shuttle","Configuration","pAI", "Cameras", "Transfer Controller", "Gas Data","Event","Plants","Alarm","Nano","Chemistry","Vote"))
|
||||
set category = "Debug"
|
||||
set name = "Debug Controller"
|
||||
set desc = "Debug the various periodic loop controllers for the game (be careful!)"
|
||||
@@ -92,5 +92,8 @@
|
||||
if("Chemistry")
|
||||
debug_variables(chemistryProcess)
|
||||
feedback_add_details("admin_verb", "DChem")
|
||||
if("Vote")
|
||||
debug_variables(vote)
|
||||
feedback_add_details("admin_verb", "DVote")
|
||||
message_admins("Admin [key_name_admin(usr)] is debugging the [controller] controller.")
|
||||
return
|
||||
|
||||
@@ -1,9 +1,15 @@
|
||||
var/datum/controller/vote/vote = new()
|
||||
|
||||
var/global/list/round_voters = list() //Keeps track of the individuals voting for a given round, for use in forcedrafting.
|
||||
var/global/list/round_voters = list() // Keeps track of the individuals voting for a given round, for use in forcedrafting.
|
||||
|
||||
datum/controller/vote
|
||||
var/initiator = null
|
||||
#define VOTE_RESTART "restart"
|
||||
#define VOTE_GAMEMODE "gamemode"
|
||||
#define VOTE_CREW_TRANSFER "crew_transfer"
|
||||
#define VOTE_ADD_ANTAGONIST "add_antagonist"
|
||||
#define VOTE_CUSTOM "custom"
|
||||
|
||||
/datum/controller/vote
|
||||
var/initiator = null // Key of the one who started the vote or "the server"
|
||||
var/started_time = null
|
||||
var/time_remaining = 0
|
||||
var/mode = null
|
||||
@@ -11,385 +17,366 @@ datum/controller/vote
|
||||
var/list/choices = list()
|
||||
var/list/gamemode_names = list()
|
||||
var/list/voted = list()
|
||||
var/list/voting = list()
|
||||
var/list/current_votes = list()
|
||||
var/list/additional_text = list()
|
||||
var/auto_muted = 0
|
||||
|
||||
New()
|
||||
if(vote != src)
|
||||
if(istype(vote))
|
||||
del(vote)
|
||||
vote = src
|
||||
/datum/controller/vote/New()
|
||||
if(vote != src)
|
||||
if(istype(vote))
|
||||
del(vote)
|
||||
vote = src
|
||||
|
||||
proc/process() //called by master_controller
|
||||
if(mode)
|
||||
// No more change mode votes after the game has started.
|
||||
// 3 is GAME_STATE_PLAYING, but that #define is undefined for some reason
|
||||
if(mode == "gamemode" && ticker.current_state >= 2)
|
||||
world << "<b>Voting aborted due to game start.</b>"
|
||||
src.reset()
|
||||
return
|
||||
/datum/controller/vote/proc/process() //called by master_controller
|
||||
if(mode)
|
||||
// No more change mode votes after the game has started.
|
||||
if(mode == VOTE_GAMEMODE && ticker.current_state >= GAME_STATE_SETTING_UP)
|
||||
world << "<b>Voting aborted due to game start.</b>"
|
||||
src.reset()
|
||||
return
|
||||
|
||||
// Calculate how much time is remaining by comparing current time, to time of vote start,
|
||||
// plus vote duration
|
||||
time_remaining = round((started_time + config.vote_period - world.time)/10)
|
||||
|
||||
if(time_remaining < 0)
|
||||
result()
|
||||
for(var/client/C in voting)
|
||||
if(C)
|
||||
C << browse(null,"window=vote")
|
||||
reset()
|
||||
else
|
||||
for(var/client/C in voting)
|
||||
if(C)
|
||||
C << browse(vote.interface(C),"window=vote")
|
||||
|
||||
voting.Cut()
|
||||
|
||||
proc/autotransfer()
|
||||
initiate_vote("crew_transfer","the server", 1)
|
||||
log_debug("The server has called a crew transfer vote")
|
||||
|
||||
proc/autogamemode()
|
||||
initiate_vote("gamemode","the server", 1)
|
||||
log_debug("The server has called a gamemode vote")
|
||||
|
||||
proc/reset()
|
||||
initiator = null
|
||||
time_remaining = 0
|
||||
mode = null
|
||||
question = null
|
||||
choices.Cut()
|
||||
voted.Cut()
|
||||
voting.Cut()
|
||||
current_votes.Cut()
|
||||
additional_text.Cut()
|
||||
|
||||
proc/get_result()
|
||||
//get the highest number of votes
|
||||
var/greatest_votes = 0
|
||||
var/total_votes = 0
|
||||
for(var/option in choices)
|
||||
var/votes = choices[option]
|
||||
total_votes += votes
|
||||
if(votes > greatest_votes)
|
||||
greatest_votes = votes
|
||||
//default-vote for everyone who didn't vote
|
||||
if(!config.vote_no_default && choices.len)
|
||||
var/non_voters = (clients.len - total_votes)
|
||||
if(non_voters > 0)
|
||||
if(mode == "restart")
|
||||
choices["Continue Playing"] += non_voters
|
||||
if(choices["Continue Playing"] >= greatest_votes)
|
||||
greatest_votes = choices["Continue Playing"]
|
||||
else if(mode == "gamemode")
|
||||
if(master_mode in choices)
|
||||
choices[master_mode] += non_voters
|
||||
if(choices[master_mode] >= greatest_votes)
|
||||
greatest_votes = choices[master_mode]
|
||||
else if(mode == "crew_transfer")
|
||||
var/factor = 0.5
|
||||
switch(world.time / (10 * 60)) // minutes
|
||||
if(0 to 60)
|
||||
factor = 0.5
|
||||
if(61 to 120)
|
||||
factor = 0.8
|
||||
if(121 to 240)
|
||||
factor = 1
|
||||
if(241 to 300)
|
||||
factor = 1.2
|
||||
else
|
||||
factor = 1.4
|
||||
choices["Initiate Crew Transfer"] = round(choices["Initiate Crew Transfer"] * factor)
|
||||
world << "<font color='purple'>Crew Transfer Factor: [factor]</font>"
|
||||
greatest_votes = max(choices["Initiate Crew Transfer"], choices["Continue The Round"])
|
||||
|
||||
|
||||
//get all options with that many votes and return them in a list
|
||||
. = list()
|
||||
if(greatest_votes)
|
||||
for(var/option in choices)
|
||||
if(choices[option] == greatest_votes)
|
||||
. += option
|
||||
return .
|
||||
|
||||
proc/announce_result()
|
||||
var/list/winners = get_result()
|
||||
var/text
|
||||
if(winners.len > 0)
|
||||
if(winners.len > 1)
|
||||
if(mode != "gamemode" || ticker.hide_mode == 0) // Here we are making sure we don't announce potential game modes
|
||||
text = "<b>Vote Tied Between:</b>\n"
|
||||
for(var/option in winners)
|
||||
text += "\t[option]\n"
|
||||
. = pick(winners)
|
||||
|
||||
for(var/key in current_votes)
|
||||
if(choices[current_votes[key]] == .)
|
||||
round_voters += key // Keep track of who voted for the winning round.
|
||||
if((mode == "gamemode" && . == "Extended") || ticker.hide_mode == 0) // Announce Extended gamemode, but not other gamemodes
|
||||
text += "<b>Vote Result: [.]</b>"
|
||||
else
|
||||
if(mode != "gamemode")
|
||||
text += "<b>Vote Result: [.]</b>"
|
||||
else
|
||||
text += "<b>The vote has ended.</b>" // What will be shown if it is a gamemode vote that isn't extended
|
||||
|
||||
else
|
||||
text += "<b>Vote Result: Inconclusive - No Votes!</b>"
|
||||
if(mode == "add_antagonist")
|
||||
antag_add_failed = 1
|
||||
log_vote(text)
|
||||
world << "<font color='purple'>[text]</font>"
|
||||
return .
|
||||
|
||||
proc/result()
|
||||
. = announce_result()
|
||||
var/restart = 0
|
||||
if(.)
|
||||
switch(mode)
|
||||
if("restart")
|
||||
if(. == "Restart Round")
|
||||
restart = 1
|
||||
if("gamemode")
|
||||
if(master_mode != .)
|
||||
world.save_mode(.)
|
||||
if(ticker && ticker.mode)
|
||||
restart = 1
|
||||
else
|
||||
master_mode = .
|
||||
if("crew_transfer")
|
||||
if(. == "Initiate Crew Transfer")
|
||||
init_shift_change(null, 1)
|
||||
if("add_antagonist")
|
||||
if(isnull(.) || . == "None")
|
||||
antag_add_failed = 1
|
||||
else
|
||||
additional_antag_types |= antag_names_to_ids[.]
|
||||
|
||||
if(mode == "gamemode") //fire this even if the vote fails.
|
||||
if(!round_progressing)
|
||||
round_progressing = 1
|
||||
world << "<font color='red'><b>The round will start soon.</b></font>"
|
||||
|
||||
if(restart)
|
||||
world << "World restarting due to vote..."
|
||||
feedback_set_details("end_error","restart vote")
|
||||
if(blackbox) blackbox.save_all_data_to_sql()
|
||||
sleep(50)
|
||||
log_game("Rebooting due to restart vote")
|
||||
world.Reboot()
|
||||
|
||||
return .
|
||||
|
||||
proc/submit_vote(var/ckey, var/vote)
|
||||
if(mode)
|
||||
if(config.vote_no_dead && usr.stat == DEAD && !usr.client.holder)
|
||||
return 0
|
||||
if(vote && vote >= 1 && vote <= choices.len)
|
||||
if(current_votes[ckey])
|
||||
choices[choices[current_votes[ckey]]]--
|
||||
voted += usr.ckey
|
||||
choices[choices[vote]]++ //check this
|
||||
current_votes[ckey] = vote
|
||||
return vote
|
||||
return 0
|
||||
|
||||
proc/initiate_vote(var/vote_type, var/initiator_key, var/automatic = 0)
|
||||
if(!mode)
|
||||
if(started_time != null && !(check_rights(R_ADMIN) || automatic))
|
||||
var/next_allowed_time = (started_time + config.vote_delay)
|
||||
if(next_allowed_time > world.time)
|
||||
return 0
|
||||
// Calculate how much time is remaining by comparing current time, to time of vote start,
|
||||
// plus vote duration
|
||||
time_remaining = round((started_time + config.vote_period - world.time)/10)
|
||||
|
||||
if(time_remaining < 0)
|
||||
result()
|
||||
reset()
|
||||
switch(vote_type)
|
||||
if("restart")
|
||||
choices.Add("Restart Round","Continue Playing")
|
||||
if("gamemode")
|
||||
if(ticker.current_state >= 2)
|
||||
return 0
|
||||
choices.Add(config.votable_modes)
|
||||
for (var/F in choices)
|
||||
var/datum/game_mode/M = gamemode_cache[F]
|
||||
if(!M)
|
||||
continue
|
||||
gamemode_names[M.config_tag] = capitalize(M.name) //It's ugly to put this here but it works
|
||||
additional_text.Add("<td align = 'center'>[M.required_players]</td>")
|
||||
gamemode_names["secret"] = "Secret"
|
||||
if("crew_transfer")
|
||||
if(check_rights(R_ADMIN|R_MOD, 0))
|
||||
question = "End the shift?"
|
||||
choices.Add("Initiate Crew Transfer", "Continue The Round")
|
||||
|
||||
/datum/controller/vote/proc/autotransfer()
|
||||
initiate_vote(VOTE_CREW_TRANSFER, "the server", 1)
|
||||
log_debug("The server has called a crew transfer vote")
|
||||
|
||||
/datum/controller/vote/proc/autogamemode()
|
||||
initiate_vote(VOTE_GAMEMODE, "the server", 1)
|
||||
log_debug("The server has called a gamemode vote")
|
||||
|
||||
/datum/controller/vote/proc/reset()
|
||||
initiator = null
|
||||
time_remaining = 0
|
||||
mode = null
|
||||
question = null
|
||||
choices.Cut()
|
||||
voted.Cut()
|
||||
current_votes.Cut()
|
||||
additional_text.Cut()
|
||||
|
||||
/datum/controller/vote/proc/get_result() // Get the highest number of votes
|
||||
var/greatest_votes = 0
|
||||
var/total_votes = 0
|
||||
|
||||
for(var/option in choices)
|
||||
var/votes = choices[option]
|
||||
total_votes += votes
|
||||
if(votes > greatest_votes)
|
||||
greatest_votes = votes
|
||||
|
||||
if(!config.vote_no_default && choices.len) // Default-vote for everyone who didn't vote
|
||||
var/non_voters = (clients.len - total_votes)
|
||||
if(non_voters > 0)
|
||||
if(mode == VOTE_RESTART)
|
||||
choices["Continue Playing"] += non_voters
|
||||
if(choices["Continue Playing"] >= greatest_votes)
|
||||
greatest_votes = choices["Continue Playing"]
|
||||
else if(mode == VOTE_GAMEMODE)
|
||||
if(master_mode in choices)
|
||||
choices[master_mode] += non_voters
|
||||
if(choices[master_mode] >= greatest_votes)
|
||||
greatest_votes = choices[master_mode]
|
||||
else if(mode == VOTE_CREW_TRANSFER)
|
||||
var/factor = 0.5
|
||||
switch(world.time / (10 * 60)) // minutes
|
||||
if(0 to 60)
|
||||
factor = 0.5
|
||||
if(61 to 120)
|
||||
factor = 0.8
|
||||
if(121 to 240)
|
||||
factor = 1
|
||||
if(241 to 300)
|
||||
factor = 1.2
|
||||
else
|
||||
if (get_security_level() == "red" || get_security_level() == "delta")
|
||||
initiator_key << "The current alert status is too high to call for a crew transfer!"
|
||||
return 0
|
||||
if(ticker.current_state <= 2)
|
||||
return 0
|
||||
initiator_key << "The crew transfer button has been disabled!"
|
||||
question = "End the shift?"
|
||||
choices.Add("Initiate Crew Transfer", "Continue The Round")
|
||||
if("add_antagonist")
|
||||
if(!config.allow_extra_antags || ticker.current_state >= 2)
|
||||
return 0
|
||||
for(var/antag_type in all_antag_types)
|
||||
var/datum/antagonist/antag = all_antag_types[antag_type]
|
||||
if(!(antag.id in additional_antag_types) && antag.is_votable())
|
||||
choices.Add(antag.role_text)
|
||||
choices.Add("None")
|
||||
if("custom")
|
||||
question = sanitizeSafe(input(usr,"What is the vote for?") as text|null)
|
||||
if(!question) return 0
|
||||
for(var/i=1,i<=10,i++)
|
||||
var/option = capitalize(sanitize(input(usr,"Please enter an option or hit cancel to finish") as text|null))
|
||||
if(!option || mode || !usr.client) break
|
||||
choices.Add(option)
|
||||
else
|
||||
return 0
|
||||
mode = vote_type
|
||||
initiator = initiator_key
|
||||
started_time = world.time
|
||||
var/text = "[capitalize(mode)] vote started by [initiator]."
|
||||
if(mode == "custom")
|
||||
text += "\n[question]"
|
||||
factor = 1.4
|
||||
choices["Initiate Crew Transfer"] = round(choices["Initiate Crew Transfer"] * factor)
|
||||
world << "<font color='purple'>Crew Transfer Factor: [factor]</font>"
|
||||
greatest_votes = max(choices["Initiate Crew Transfer"], choices["Continue The Round"])
|
||||
|
||||
log_vote(text)
|
||||
world << "<font color='purple'><b>[text]</b>\nType <b>vote</b> or click <a href='?src=\ref[src]'>here</a> to place your votes.\nYou have [config.vote_period/10] seconds to vote.</font>"
|
||||
switch(vote_type)
|
||||
if("crew_transfer")
|
||||
world << sound('sound/ambience/alarm4.ogg', repeat = 0, wait = 0, volume = 50, channel = 3)
|
||||
if("gamemode")
|
||||
world << sound('sound/ambience/alarm4.ogg', repeat = 0, wait = 0, volume = 50, channel = 3)
|
||||
if("custom")
|
||||
world << sound('sound/ambience/alarm4.ogg', repeat = 0, wait = 0, volume = 50, channel = 3)
|
||||
if(mode == "gamemode" && round_progressing)
|
||||
round_progressing = 0
|
||||
world << "<font color='red'><b>Round start has been delayed.</b></font>"
|
||||
. = list() // Get all options with that many votes and return them in a list
|
||||
if(greatest_votes)
|
||||
for(var/option in choices)
|
||||
if(choices[option] == greatest_votes)
|
||||
. += option
|
||||
|
||||
time_remaining = round(config.vote_period/10)
|
||||
return 1
|
||||
return 0
|
||||
/datum/controller/vote/proc/announce_result()
|
||||
var/list/winners = get_result()
|
||||
var/text
|
||||
if(winners.len > 0)
|
||||
if(winners.len > 1)
|
||||
if(mode != VOTE_GAMEMODE || ticker.hide_mode == 0) // Here we are making sure we don't announce potential game modes
|
||||
text = "<b>Vote Tied Between:</b>\n"
|
||||
for(var/option in winners)
|
||||
text += "\t[option]\n"
|
||||
. = pick(winners)
|
||||
|
||||
proc/interface(var/client/C)
|
||||
if(!C) return
|
||||
var/admin = 0
|
||||
var/trialmin = 0
|
||||
if(C.holder)
|
||||
if(C.holder.rights & R_ADMIN)
|
||||
admin = 1
|
||||
trialmin = 1 // don't know why we use both of these it's really weird, but I'm 2 lasy to refactor this all to use just admin.
|
||||
voting |= C
|
||||
|
||||
. = "<html><head><title>Voting Panel</title></head><body>"
|
||||
if(mode)
|
||||
if(question) . += "<h2>Vote: '[question]'</h2>"
|
||||
else . += "<h2>Vote: [capitalize(mode)]</h2>"
|
||||
. += "Time Left: [time_remaining] s<hr>"
|
||||
. += "<table width = '100%'><tr><td align = 'center'><b>Choices</b></td><td align = 'center'><b>Votes</b></td>"
|
||||
if(capitalize(mode) == "Gamemode") .+= "<td align = 'center'><b>Minimum Players</b></td></tr>"
|
||||
|
||||
for(var/i = 1, i <= choices.len, i++)
|
||||
var/votes = choices[choices[i]]
|
||||
if(!votes) votes = 0
|
||||
. += "<tr>"
|
||||
if(mode == "gamemode")
|
||||
if(current_votes[C.ckey] == i)
|
||||
. += "<td><b><a href='?src=\ref[src];vote=[i]'>[gamemode_names[choices[i]]]</a></b></td><td align = 'center'>[votes]</td>"
|
||||
else
|
||||
. += "<td><a href='?src=\ref[src];vote=[i]'>[gamemode_names[choices[i]]]</a></td><td align = 'center'>[votes]</td>"
|
||||
else
|
||||
if(current_votes[C.ckey] == i)
|
||||
. += "<td><b><a href='?src=\ref[src];vote=[i]'>[choices[i]]</a></b></td><td align = 'center'>[votes]</td>"
|
||||
else
|
||||
. += "<td><a href='?src=\ref[src];vote=[i]'>[choices[i]]</a></td><td align = 'center'>[votes]</td>"
|
||||
if (additional_text.len >= i)
|
||||
. += additional_text[i]
|
||||
. += "</tr>"
|
||||
|
||||
. += "</table><hr>"
|
||||
if(admin)
|
||||
. += "(<a href='?src=\ref[src];vote=cancel'>Cancel Vote</a>) "
|
||||
for(var/key in current_votes)
|
||||
if(choices[current_votes[key]] == .)
|
||||
round_voters += key // Keep track of who voted for the winning round.
|
||||
if(mode != VOTE_GAMEMODE || . == "Extended" || ticker.hide_mode == 0) // Announce Extended gamemode, but not other gamemodes
|
||||
text += "<b>Vote Result: [.]</b>"
|
||||
else
|
||||
. += "<h2>Start a vote:</h2><hr><ul><li>"
|
||||
//restart
|
||||
if(trialmin || config.allow_vote_restart)
|
||||
. += "<a href='?src=\ref[src];vote=restart'>Restart</a>"
|
||||
else
|
||||
. += "<font color='grey'>Restart (Disallowed)</font>"
|
||||
. += "</li><li>"
|
||||
if(trialmin || config.allow_vote_restart)
|
||||
. += "<a href='?src=\ref[src];vote=crew_transfer'>Crew Transfer</a>"
|
||||
else
|
||||
. += "<font color='grey'>Crew Transfer (Disallowed)</font>"
|
||||
if(trialmin)
|
||||
. += "\t(<a href='?src=\ref[src];vote=toggle_restart'>[config.allow_vote_restart?"Allowed":"Disallowed"]</a>)"
|
||||
. += "</li><li>"
|
||||
//gamemode
|
||||
if(trialmin || config.allow_vote_mode)
|
||||
. += "<a href='?src=\ref[src];vote=gamemode'>GameMode</a>"
|
||||
else
|
||||
. += "<font color='grey'>GameMode (Disallowed)</font>"
|
||||
if(trialmin)
|
||||
. += "\t(<a href='?src=\ref[src];vote=toggle_gamemode'>[config.allow_vote_mode?"Allowed":"Disallowed"]</a>)"
|
||||
. += "</li><li>"
|
||||
//extra antagonists
|
||||
if(!antag_add_failed && config.allow_extra_antags)
|
||||
. += "<a href='?src=\ref[src];vote=add_antagonist'>Add Antagonist Type</a>"
|
||||
else
|
||||
. += "<font color='grey'>Restart (Disallowed)</font>"
|
||||
. += "</li>"
|
||||
//custom
|
||||
if(trialmin)
|
||||
. += "<li><a href='?src=\ref[src];vote=custom'>Custom</a></li>"
|
||||
. += "</ul><hr>"
|
||||
. += "<a href='?src=\ref[src];vote=close' style='position:absolute;right:50px'>Close</a></body></html>"
|
||||
return .
|
||||
text += "<b>The vote has ended.</b>"
|
||||
|
||||
else
|
||||
text += "<b>Vote Result: Inconclusive - No Votes!</b>"
|
||||
if(mode == VOTE_ADD_ANTAGONIST)
|
||||
antag_add_failed = 1
|
||||
log_vote(text)
|
||||
world << "<font color='purple'>[text]</font>"
|
||||
|
||||
Topic(href,href_list[],hsrc)
|
||||
if(!usr || !usr.client) return //not necessary but meh...just in-case somebody does something stupid
|
||||
switch(href_list["vote"])
|
||||
if("close")
|
||||
voting -= usr.client
|
||||
usr << browse(null, "window=vote")
|
||||
return
|
||||
if("cancel")
|
||||
if(usr.client.holder)
|
||||
reset()
|
||||
if("toggle_restart")
|
||||
if(usr.client.holder)
|
||||
config.allow_vote_restart = !config.allow_vote_restart
|
||||
if("toggle_gamemode")
|
||||
if(usr.client.holder)
|
||||
config.allow_vote_mode = !config.allow_vote_mode
|
||||
if("restart")
|
||||
if(config.allow_vote_restart || usr.client.holder)
|
||||
initiate_vote("restart",usr.key)
|
||||
if("gamemode")
|
||||
if(config.allow_vote_mode || usr.client.holder)
|
||||
initiate_vote("gamemode",usr.key)
|
||||
if("crew_transfer")
|
||||
if(config.allow_vote_restart || usr.client.holder)
|
||||
initiate_vote("crew_transfer",usr.key)
|
||||
if("add_antagonist")
|
||||
if(config.allow_extra_antags)
|
||||
initiate_vote("add_antagonist",usr.key)
|
||||
if("custom")
|
||||
if(usr.client.holder)
|
||||
initiate_vote("custom",usr.key)
|
||||
/datum/controller/vote/proc/result()
|
||||
. = announce_result()
|
||||
var/restart = 0
|
||||
if(.)
|
||||
switch(mode)
|
||||
if(VOTE_RESTART)
|
||||
if(. == "Restart Round")
|
||||
restart = 1
|
||||
if(VOTE_GAMEMODE)
|
||||
if(master_mode != .)
|
||||
world.save_mode(.)
|
||||
if(ticker && ticker.mode)
|
||||
restart = 1
|
||||
else
|
||||
master_mode = .
|
||||
if(VOTE_CREW_TRANSFER)
|
||||
if(. == "Initiate Crew Transfer")
|
||||
init_shift_change(null, 1)
|
||||
if(VOTE_ADD_ANTAGONIST)
|
||||
if(isnull(.) || . == "None")
|
||||
antag_add_failed = 1
|
||||
else
|
||||
additional_antag_types |= antag_names_to_ids[.]
|
||||
|
||||
if(mode == VOTE_GAMEMODE) //fire this even if the vote fails.
|
||||
if(!round_progressing)
|
||||
round_progressing = 1
|
||||
world << "<font color='red'><b>The round will start soon.</b></font>"
|
||||
|
||||
if(restart)
|
||||
world << "World restarting due to vote..."
|
||||
feedback_set_details("end_error", "restart vote")
|
||||
if(blackbox)
|
||||
blackbox.save_all_data_to_sql()
|
||||
sleep(50)
|
||||
log_game("Rebooting due to restart vote")
|
||||
world.Reboot()
|
||||
|
||||
/datum/controller/vote/proc/submit_vote(var/ckey, var/newVote)
|
||||
if(mode)
|
||||
if(config.vote_no_dead && usr.stat == DEAD && !usr.client.holder)
|
||||
return
|
||||
if(current_votes[ckey])
|
||||
choices[choices[current_votes[ckey]]]--
|
||||
if(newVote && newVote >= 1 && newVote <= choices.len)
|
||||
choices[choices[newVote]]++
|
||||
current_votes[ckey] = newVote
|
||||
else
|
||||
current_votes[ckey] = null
|
||||
|
||||
/datum/controller/vote/proc/initiate_vote(var/vote_type, var/initiator_key, var/automatic = 0)
|
||||
if(!mode)
|
||||
if(started_time != null && !(check_rights(R_ADMIN) || automatic))
|
||||
var/next_allowed_time = (started_time + config.vote_delay)
|
||||
if(next_allowed_time > world.time)
|
||||
return 0
|
||||
|
||||
reset()
|
||||
|
||||
switch(vote_type)
|
||||
if(VOTE_RESTART)
|
||||
choices.Add("Restart Round", "Continue Playing")
|
||||
if(VOTE_GAMEMODE)
|
||||
if(ticker.current_state >= GAME_STATE_SETTING_UP)
|
||||
return 0
|
||||
choices.Add(config.votable_modes)
|
||||
for(var/F in choices)
|
||||
var/datum/game_mode/M = gamemode_cache[F]
|
||||
if(!M)
|
||||
continue
|
||||
gamemode_names[M.config_tag] = capitalize(M.name) //It's ugly to put this here but it works
|
||||
additional_text.Add("<td align = 'center'>[M.required_players]</td>")
|
||||
gamemode_names["secret"] = "Secret"
|
||||
if(VOTE_CREW_TRANSFER)
|
||||
if(!check_rights(R_ADMIN|R_MOD, 0)) // The gods care not for the affairs of the mortals
|
||||
if(get_security_level() == "red" || get_security_level() == "delta")
|
||||
initiator_key << "The current alert status is too high to call for a crew transfer!"
|
||||
return 0
|
||||
if(ticker.current_state <= GAME_STATE_SETTING_UP)
|
||||
initiator_key << "The crew transfer button has been disabled!"
|
||||
return 0
|
||||
question = "End the shift?"
|
||||
choices.Add("Initiate Crew Transfer", "Continue The Round")
|
||||
if(VOTE_ADD_ANTAGONIST)
|
||||
if(!config.allow_extra_antags || ticker.current_state >= GAME_STATE_SETTING_UP)
|
||||
return 0
|
||||
for(var/antag_type in all_antag_types)
|
||||
var/datum/antagonist/antag = all_antag_types[antag_type]
|
||||
if(!(antag.id in additional_antag_types) && antag.is_votable())
|
||||
choices.Add(antag.role_text)
|
||||
choices.Add("None")
|
||||
if(VOTE_CUSTOM)
|
||||
question = sanitizeSafe(input(usr, "What is the vote for?") as text|null)
|
||||
if(!question)
|
||||
return 0
|
||||
for(var/i = 1 to 10)
|
||||
var/option = capitalize(sanitize(input(usr, "Please enter an option or hit cancel to finish") as text|null))
|
||||
if(!option || mode || !usr.client)
|
||||
break
|
||||
choices.Add(option)
|
||||
else
|
||||
var/t = round(text2num(href_list["vote"]))
|
||||
if(t) // It starts from 1, so there's no problem
|
||||
submit_vote(usr.ckey, t)
|
||||
usr.vote()
|
||||
return 0
|
||||
|
||||
mode = vote_type
|
||||
initiator = initiator_key
|
||||
started_time = world.time
|
||||
var/text = "[capitalize(mode)] vote started by [initiator]."
|
||||
if(mode == VOTE_CUSTOM)
|
||||
text += "\n[question]"
|
||||
|
||||
/mob/verb/vote()
|
||||
log_vote(text)
|
||||
|
||||
world << "<font color='purple'><b>[text]</b>\nType <b>vote</b> or click <a href='?src=\ref[src]'>here</a> to place your votes.\nYou have [config.vote_period / 10] seconds to vote.</font>"
|
||||
if(vote_type == VOTE_CREW_TRANSFER || vote_type == VOTE_GAMEMODE || vote_type == VOTE_CUSTOM)
|
||||
world << sound('sound/ambience/alarm4.ogg', repeat = 0, wait = 0, volume = 50, channel = 3)
|
||||
|
||||
if(mode == VOTE_GAMEMODE && round_progressing)
|
||||
round_progressing = 0
|
||||
world << "<font color='red'><b>Round start has been delayed.</b></font>"
|
||||
|
||||
time_remaining = round(config.vote_period / 10)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/datum/controller/vote/proc/interface(var/client/C)
|
||||
if(!istype(C))
|
||||
return
|
||||
var/admin = 0
|
||||
if(C.holder)
|
||||
if(C.holder.rights & R_ADMIN)
|
||||
admin = 1
|
||||
|
||||
. = "<html><head><title>Voting Panel</title></head><body>"
|
||||
if(mode)
|
||||
if(question)
|
||||
. += "<h2>Vote: '[question]'</h2>"
|
||||
else
|
||||
. += "<h2>Vote: [capitalize(mode)]</h2>"
|
||||
. += "Time Left: [time_remaining] s<hr>"
|
||||
. += "<table width = '100%'><tr><td align = 'center'><b>Choices</b></td><td align = 'center'><b>Votes</b></td>"
|
||||
if(mode == VOTE_GAMEMODE)
|
||||
.+= "<td align = 'center'><b>Minimum Players</b></td></tr>"
|
||||
|
||||
for(var/i = 1 to choices.len)
|
||||
var/votes = choices[choices[i]]
|
||||
if(!votes)
|
||||
votes = 0
|
||||
. += "<tr>"
|
||||
var/thisVote = (current_votes[C.ckey] == i)
|
||||
if(mode == VOTE_GAMEMODE)
|
||||
. += "<td>[thisVote ? "<b>" : ""]<a href='?src=\ref[src];vote=[i]'>[gamemode_names[choices[i]]]</a>[thisVote ? "</b>" : ""]</td><td align = 'center'>[votes]</td>"
|
||||
else
|
||||
. += "<td>[thisVote ? "<b>" : ""]<a href='?src=\ref[src];vote=[i]'>[choices[i]]</a>[thisVote ? "</b>" : ""]</td><td align = 'center'>[votes]</td>"
|
||||
if (additional_text.len >= i)
|
||||
. += additional_text[i]
|
||||
. += "</tr>"
|
||||
|
||||
. += "<tr><td><a href='?src=\ref[src];vote=unvote'>Unvote</a></td></tr>"
|
||||
|
||||
. += "</table><hr>"
|
||||
if(admin)
|
||||
. += "(<a href='?src=\ref[src];vote=cancel'>Cancel Vote</a>) "
|
||||
else
|
||||
. += "<h2>Start a vote:</h2><hr><ul><li>"
|
||||
if(admin || config.allow_vote_restart)
|
||||
. += "<a href='?src=\ref[src];vote=restart'>Restart</a>"
|
||||
else
|
||||
. += "<font color='grey'>Restart (Disallowed)</font>"
|
||||
. += "</li><li>"
|
||||
|
||||
if(admin || config.allow_vote_restart)
|
||||
. += "<a href='?src=\ref[src];vote=crew_transfer'>Crew Transfer</a>"
|
||||
else
|
||||
. += "<font color='grey'>Crew Transfer (Disallowed)</font>"
|
||||
|
||||
if(admin)
|
||||
. += "\t(<a href='?src=\ref[src];vote=toggle_restart'>[config.allow_vote_restart ? "Allowed" : "Disallowed"]</a>)"
|
||||
. += "</li><li>"
|
||||
|
||||
if(admin || config.allow_vote_mode)
|
||||
. += "<a href='?src=\ref[src];vote=gamemode'>GameMode</a>"
|
||||
else
|
||||
. += "<font color='grey'>GameMode (Disallowed)</font>"
|
||||
|
||||
if(admin)
|
||||
. += "\t(<a href='?src=\ref[src];vote=toggle_gamemode'>[config.allow_vote_mode ? "Allowed" : "Disallowed"]</a>)"
|
||||
. += "</li><li>"
|
||||
|
||||
if(!antag_add_failed && config.allow_extra_antags)
|
||||
. += "<a href='?src=\ref[src];vote=add_antagonist'>Add Antagonist Type</a>"
|
||||
else
|
||||
. += "<font color='grey'>Add Antagonist (Disallowed)</font>"
|
||||
. += "</li>"
|
||||
|
||||
if(admin)
|
||||
. += "<li><a href='?src=\ref[src];vote=custom'>Custom</a></li>"
|
||||
. += "</ul><hr>"
|
||||
|
||||
. += "<a href='?src=\ref[src];vote=close' style='position:absolute;right:50px'>Close</a></body></html>"
|
||||
|
||||
/datum/controller/vote/Topic(href, href_list[])
|
||||
if(!usr || !usr.client)
|
||||
return
|
||||
switch(href_list["vote"])
|
||||
if("close")
|
||||
usr << browse(null, "window=vote")
|
||||
return
|
||||
|
||||
if("cancel")
|
||||
if(usr.client.holder)
|
||||
reset()
|
||||
if("toggle_restart")
|
||||
if(usr.client.holder)
|
||||
config.allow_vote_restart = !config.allow_vote_restart
|
||||
if("toggle_gamemode")
|
||||
if(usr.client.holder)
|
||||
config.allow_vote_mode = !config.allow_vote_mode
|
||||
|
||||
if(VOTE_RESTART)
|
||||
if(config.allow_vote_restart || usr.client.holder)
|
||||
initiate_vote(VOTE_RESTART, usr.key)
|
||||
if(VOTE_GAMEMODE)
|
||||
if(config.allow_vote_mode || usr.client.holder)
|
||||
initiate_vote(VOTE_GAMEMODE, usr.key)
|
||||
if(VOTE_CREW_TRANSFER)
|
||||
if(config.allow_vote_restart || usr.client.holder)
|
||||
initiate_vote(VOTE_CREW_TRANSFER, usr.key)
|
||||
if(VOTE_ADD_ANTAGONIST)
|
||||
if(config.allow_extra_antags || usr.client.holder)
|
||||
initiate_vote(VOTE_ADD_ANTAGONIST, usr.key)
|
||||
if(VOTE_CUSTOM)
|
||||
if(usr.client.holder)
|
||||
initiate_vote(VOTE_CUSTOM, usr.key)
|
||||
|
||||
if("unvote")
|
||||
submit_vote(usr.ckey, null)
|
||||
|
||||
else
|
||||
var/t = round(text2num(href_list["vote"]))
|
||||
if(t) // It starts from 1, so there's no problem
|
||||
submit_vote(usr.ckey, t)
|
||||
usr.client.vote()
|
||||
|
||||
/client/verb/vote()
|
||||
set category = "OOC"
|
||||
set name = "Vote"
|
||||
|
||||
if(vote)
|
||||
src << browse(vote.interface(client),"window=vote")
|
||||
src << browse(vote.interface(src), "window=vote;size=500x[300 + vote.choices.len * 25]")
|
||||
|
||||
@@ -74,11 +74,21 @@
|
||||
if(real_rank in civilian_positions)
|
||||
civ[name] = rank
|
||||
department = 1
|
||||
if(real_rank in nonhuman_positions)
|
||||
bot[name] = rank
|
||||
department = 1
|
||||
if(!department && !(name in heads))
|
||||
misc[name] = rank
|
||||
|
||||
// Synthetics don't have actual records, so we will pull them from here.
|
||||
for(var/mob/living/silicon/ai/ai in mob_list)
|
||||
bot[ai.name] = "Artificial Intelligence"
|
||||
|
||||
for(var/mob/living/silicon/robot/robot in mob_list)
|
||||
// No combat/syndicate cyborgs, no drones.
|
||||
if(robot.module && robot.module.hide_on_manifest)
|
||||
continue
|
||||
|
||||
bot[robot.name] = "[robot.modtype] [robot.braintype]"
|
||||
|
||||
|
||||
if(heads.len > 0)
|
||||
dat += "<tr><th colspan=3>Heads</th></tr>"
|
||||
for(name in heads)
|
||||
|
||||
@@ -61,10 +61,13 @@
|
||||
|
||||
//put this here for easier tracking ingame
|
||||
var/datum/money_account/initial_account
|
||||
|
||||
|
||||
//used for antag tcrystal trading, more info in code\game\objects\items\telecrystals.dm
|
||||
var/accept_tcrystals = 0
|
||||
|
||||
//used for optional self-objectives that antagonists can give themselves, which are displayed at the end of the round.
|
||||
var/ambitions
|
||||
|
||||
/datum/mind/New(var/key)
|
||||
src.key = key
|
||||
|
||||
@@ -106,6 +109,8 @@
|
||||
output += "<B>Objective #[obj_count]</B>: [objective.explanation_text]"
|
||||
obj_count++
|
||||
|
||||
if(ambitions)
|
||||
output += "<HR><B>Ambitions:</B> [ambitions]<br>"
|
||||
recipient << browse(output,"window=memory")
|
||||
|
||||
/datum/mind/proc/edit_memory()
|
||||
@@ -139,7 +144,8 @@
|
||||
|
||||
else
|
||||
out += "None."
|
||||
out += "<br><a href='?src=\ref[src];obj_add=1'>\[add\]</a>"
|
||||
out += "<br><a href='?src=\ref[src];obj_add=1'>\[add\]</a><br><br>"
|
||||
out += "<b>Ambitions:</b> [ambitions ? ambitions : "None"] <a href='?src=\ref[src];amb_edit=\ref[src]'>\[edit\]</a></br>"
|
||||
usr << browse(out, "window=edit_memory[src]")
|
||||
|
||||
/datum/mind/Topic(href, href_list)
|
||||
@@ -147,7 +153,7 @@
|
||||
|
||||
if(href_list["add_antagonist"])
|
||||
var/datum/antagonist/antag = all_antag_types[href_list["add_antagonist"]]
|
||||
if(antag)
|
||||
if(antag)
|
||||
if(antag.add_antagonist(src, 1, 1, 0, 1, 1)) // Ignore equipment and role type for this.
|
||||
log_admin("[key_name_admin(usr)] made [key_name(src)] into a [antag.role_text].")
|
||||
else
|
||||
@@ -179,6 +185,18 @@
|
||||
if (isnull(new_memo)) return
|
||||
memory = new_memo
|
||||
|
||||
else if (href_list["amb_edit"])
|
||||
var/datum/mind/mind = locate(href_list["amb_edit"])
|
||||
if(!mind)
|
||||
return
|
||||
var/new_ambition = input("Enter a new ambition", "Memory", mind.ambitions) as null|message
|
||||
if(isnull(new_ambition))
|
||||
return
|
||||
if(mind)
|
||||
mind.ambitions = sanitize(new_ambition)
|
||||
mind.current << "<span class='warning'>Your ambitions have been changed by higher powers, they are now: [mind.ambitions]</span>"
|
||||
log_and_message_admins("made [key_name(mind.current)]'s ambitions be '[mind.ambitions]'.")
|
||||
|
||||
else if (href_list["obj_edit"] || href_list["obj_add"])
|
||||
var/datum/objective/objective
|
||||
var/objective_pos
|
||||
|
||||
43
code/datums/progressbar.dm
Normal file
43
code/datums/progressbar.dm
Normal file
@@ -0,0 +1,43 @@
|
||||
/datum/progressbar
|
||||
var/goal = 1
|
||||
var/image/bar
|
||||
var/shown = 0
|
||||
var/mob/user
|
||||
var/client/client
|
||||
|
||||
/datum/progressbar/New(mob/user, goal_number, atom/target)
|
||||
. = ..()
|
||||
if(!target) target = user
|
||||
if (!istype(target))
|
||||
EXCEPTION("Invalid target given")
|
||||
if (goal_number)
|
||||
goal = goal_number
|
||||
bar = image('icons/effects/progessbar.dmi', target, "prog_bar_0")
|
||||
bar.appearance_flags = APPEARANCE_UI_IGNORE_ALPHA
|
||||
bar.pixel_y = 32
|
||||
src.user = user
|
||||
if(user)
|
||||
client = user.client
|
||||
|
||||
/datum/progressbar/Destroy()
|
||||
if (client)
|
||||
client.images -= bar
|
||||
qdel(bar)
|
||||
. = ..()
|
||||
|
||||
/datum/progressbar/proc/update(progress)
|
||||
//world << "Update [progress] - [goal] - [(progress / goal)] - [((progress / goal) * 100)] - [round(((progress / goal) * 100), 5)]"
|
||||
if (!user || !user.client)
|
||||
shown = 0
|
||||
return
|
||||
if (user.client != client)
|
||||
if (client)
|
||||
client.images -= bar
|
||||
shown = 0
|
||||
client = user.client
|
||||
|
||||
progress = Clamp(progress, 0, goal)
|
||||
bar.icon_state = "prog_bar_[round(((progress / goal) * 100), 5)]"
|
||||
if (!shown && user.is_preference_enabled(/datum/client_preference/show_progress_bar))
|
||||
user.client.images += bar
|
||||
shown = 1
|
||||
@@ -74,18 +74,33 @@
|
||||
if (items && items.len)
|
||||
var/list/checklist = list()
|
||||
checklist = items.Copy() // You should really trust Copy
|
||||
for(var/obj/O in container)
|
||||
if(istype(O,/obj/item/weapon/reagent_containers/food/snacks/grown))
|
||||
continue // Fruit is handled in check_fruit().
|
||||
var/found = 0
|
||||
for(var/i = 1; i < checklist.len+1; i++)
|
||||
var/item_type = checklist[i]
|
||||
if (istype(O,item_type))
|
||||
checklist.Cut(i, i+1)
|
||||
found = 1
|
||||
break
|
||||
if (!found)
|
||||
. = 0
|
||||
if(istype(container, /obj/machinery))
|
||||
var/obj/machinery/machine = container
|
||||
for(var/obj/O in (machine.contents - machine.component_parts))
|
||||
if(istype(O,/obj/item/weapon/reagent_containers/food/snacks/grown))
|
||||
continue // Fruit is handled in check_fruit().
|
||||
var/found = 0
|
||||
for(var/i = 1; i < checklist.len+1; i++)
|
||||
var/item_type = checklist[i]
|
||||
if (istype(O,item_type))
|
||||
checklist.Cut(i, i+1)
|
||||
found = 1
|
||||
break
|
||||
if (!found)
|
||||
. = 0
|
||||
else
|
||||
for(var/obj/O in container.contents)
|
||||
if(istype(O,/obj/item/weapon/reagent_containers/food/snacks/grown))
|
||||
continue // Fruit is handled in check_fruit().
|
||||
var/found = 0
|
||||
for(var/i = 1; i < checklist.len+1; i++)
|
||||
var/item_type = checklist[i]
|
||||
if (istype(O,item_type))
|
||||
checklist.Cut(i, i+1)
|
||||
found = 1
|
||||
break
|
||||
if (!found)
|
||||
. = 0
|
||||
if (checklist.len)
|
||||
. = -1
|
||||
return .
|
||||
@@ -93,9 +108,15 @@
|
||||
//general version
|
||||
/datum/recipe/proc/make(var/obj/container as obj)
|
||||
var/obj/result_obj = new result(container)
|
||||
for (var/obj/O in (container.contents-result_obj))
|
||||
O.reagents.trans_to_obj(result_obj, O.reagents.total_volume)
|
||||
qdel(O)
|
||||
if(istype(container, /obj/machinery))
|
||||
var/obj/machinery/machine = container
|
||||
for (var/obj/O in ((machine.contents-result_obj)-machine.component_parts))
|
||||
O.reagents.trans_to_obj(result_obj, O.reagents.total_volume)
|
||||
qdel(O)
|
||||
else
|
||||
for (var/obj/O in (container.contents-result_obj))
|
||||
O.reagents.trans_to_obj(result_obj, O.reagents.total_volume)
|
||||
qdel(O)
|
||||
container.reagents.clear_reagents()
|
||||
return result_obj
|
||||
|
||||
@@ -105,12 +126,21 @@
|
||||
world << "<span class='danger'>Recipe [type] is defined without a result, please bug this.</span>"
|
||||
return
|
||||
var/obj/result_obj = new result(container)
|
||||
for (var/obj/O in (container.contents-result_obj))
|
||||
if (O.reagents)
|
||||
O.reagents.del_reagent("nutriment")
|
||||
O.reagents.update_total()
|
||||
O.reagents.trans_to_obj(result_obj, O.reagents.total_volume)
|
||||
qdel(O)
|
||||
if(istype(container, /obj/machinery))
|
||||
var/obj/machinery/machine = container
|
||||
for (var/obj/O in ((machine.contents-result_obj)-machine.component_parts))
|
||||
if (O.reagents)
|
||||
O.reagents.del_reagent("nutriment")
|
||||
O.reagents.update_total()
|
||||
O.reagents.trans_to_obj(result_obj, O.reagents.total_volume)
|
||||
qdel(O)
|
||||
else
|
||||
for (var/obj/O in (container.contents-result_obj))
|
||||
if (O.reagents)
|
||||
O.reagents.del_reagent("nutriment")
|
||||
O.reagents.update_total()
|
||||
O.reagents.trans_to_obj(result_obj, O.reagents.total_volume)
|
||||
qdel(O)
|
||||
container.reagents.clear_reagents()
|
||||
return result_obj
|
||||
|
||||
|
||||
@@ -221,6 +221,12 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee
|
||||
name = "Janitorial supplies"
|
||||
contains = list(/obj/item/weapon/reagent_containers/glass/bucket,
|
||||
/obj/item/weapon/mop,
|
||||
/obj/item/clothing/under/rank/janitor,
|
||||
/obj/item/weapon/cartridge/janitor,
|
||||
/obj/item/clothing/gloves/black,
|
||||
/obj/item/clothing/head/soft/purple,
|
||||
/obj/item/weapon/storage/belt/janitor,
|
||||
/obj/item/clothing/shoes/galoshes,
|
||||
/obj/item/weapon/caution,
|
||||
/obj/item/weapon/caution,
|
||||
/obj/item/weapon/caution,
|
||||
@@ -609,7 +615,7 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee
|
||||
/obj/item/solar_assembly,
|
||||
/obj/item/solar_assembly,
|
||||
/obj/item/solar_assembly,
|
||||
/obj/item/solar_assembly, // 21 Solar Assemblies. 1 Extra for the controller
|
||||
/obj/item/solar_assembly, // 21 Solar Assemblies. 1 Extra for the controller,
|
||||
/obj/item/weapon/circuitboard/solar_control,
|
||||
/obj/item/weapon/tracker_electronics,
|
||||
/obj/item/weapon/paper/solar)
|
||||
@@ -671,8 +677,8 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee
|
||||
/datum/supply_packs/mecha_ripley
|
||||
name = "Circuit Crate (\"Ripley\" APLU)"
|
||||
contains = list(/obj/item/weapon/book/manual/ripley_build_and_repair,
|
||||
/obj/item/weapon/circuitboard/mecha/ripley/main, //TEMPORARY due to lack of circuitboard printer
|
||||
/obj/item/weapon/circuitboard/mecha/ripley/peripherals) //TEMPORARY due to lack of circuitboard printer
|
||||
/obj/item/weapon/circuitboard/mecha/ripley/main,
|
||||
/obj/item/weapon/circuitboard/mecha/ripley/peripherals)
|
||||
cost = 30
|
||||
containertype = /obj/structure/closet/crate/secure
|
||||
containername = "APLU \"Ripley\" Circuit Crate"
|
||||
@@ -681,8 +687,8 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee
|
||||
|
||||
/datum/supply_packs/mecha_odysseus
|
||||
name = "Circuit Crate (\"Odysseus\")"
|
||||
contains = list(/obj/item/weapon/circuitboard/mecha/odysseus/peripherals, //TEMPORARY due to lack of circuitboard printer
|
||||
/obj/item/weapon/circuitboard/mecha/odysseus/main) //TEMPORARY due to lack of circuitboard printer
|
||||
contains = list(/obj/item/weapon/circuitboard/mecha/odysseus/peripherals,
|
||||
/obj/item/weapon/circuitboard/mecha/odysseus/main)
|
||||
cost = 25
|
||||
containertype = /obj/structure/closet/crate/secure
|
||||
containername = "\"Odysseus\" Circuit Crate"
|
||||
@@ -1001,7 +1007,7 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee
|
||||
containername = "Security barrier crate"
|
||||
group = "Security"
|
||||
|
||||
/datum/supply_packs/securitybarriers
|
||||
/datum/supply_packs/securityshieldgen
|
||||
name = "Wall shield Generators"
|
||||
contains = list(/obj/machinery/shieldwallgen,
|
||||
/obj/machinery/shieldwallgen,
|
||||
@@ -1635,6 +1641,7 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee
|
||||
num_contained = 4
|
||||
contains = list(/obj/item/clothing/accessory/storage/black_vest,
|
||||
/obj/item/clothing/accessory/storage/brown_vest,
|
||||
/obj/item/clothing/accessory/storage/white_vest,
|
||||
/obj/item/clothing/accessory/storage/webbing)
|
||||
cost = 15
|
||||
containertype = "/obj/structure/closet/crate"
|
||||
@@ -1729,7 +1736,8 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee
|
||||
/obj/item/device/camera_film,
|
||||
/obj/item/device/camera_film,
|
||||
/obj/item/weapon/storage/photo_album,
|
||||
/obj/item/device/reagent_scanner)
|
||||
/obj/item/device/reagent_scanner,
|
||||
/obj/item/device/flashlight/maglight)
|
||||
cost = 35
|
||||
containertype = "/obj/structure/closet/crate/secure"
|
||||
containername = "Forensic equipment"
|
||||
@@ -1785,7 +1793,8 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee
|
||||
/obj/item/clothing/accessory/storage/black_vest,
|
||||
/obj/item/clothing/head/soft/sec/corp,
|
||||
/obj/item/clothing/under/rank/security/corp,
|
||||
/obj/item/weapon/gun/energy/taser)
|
||||
/obj/item/weapon/gun/energy/taser,
|
||||
/obj/item/device/flashlight/maglight)
|
||||
cost = 30
|
||||
containertype = "/obj/structure/closet/crate/secure"
|
||||
containername = "Officer equipment"
|
||||
@@ -1811,7 +1820,8 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee
|
||||
/obj/item/weapon/reagent_containers/spray/pepper,
|
||||
/obj/item/weapon/melee/baton/loaded,
|
||||
/obj/item/weapon/storage/box/holobadge,
|
||||
/obj/item/clothing/head/beret/sec/corporate/warden)
|
||||
/obj/item/clothing/head/beret/sec/corporate/warden,
|
||||
/obj/item/device/flashlight/maglight)
|
||||
cost = 45
|
||||
containertype = "/obj/structure/closet/crate/secure"
|
||||
containername = "Warden equipment"
|
||||
@@ -1835,7 +1845,8 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee
|
||||
/obj/item/clothing/accessory/holster/waist,
|
||||
/obj/item/weapon/melee/telebaton,
|
||||
/obj/item/weapon/shield/riot/tele,
|
||||
/obj/item/clothing/head/beret/sec/corporate/hos)
|
||||
/obj/item/clothing/head/beret/sec/corporate/hos,
|
||||
/obj/item/device/flashlight/maglight)
|
||||
cost = 65
|
||||
containertype = "/obj/structure/closet/crate/secure"
|
||||
containername = "Head of security equipment"
|
||||
@@ -2069,7 +2080,8 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee
|
||||
/obj/item/device/healthanalyzer,
|
||||
/obj/item/weapon/cartridge/medical,
|
||||
/obj/item/device/flashlight/pen,
|
||||
/obj/item/weapon/reagent_containers/syringe)
|
||||
/obj/item/weapon/reagent_containers/syringe,
|
||||
/obj/item/clothing/accessory/storage/white_vest)
|
||||
cost = 20
|
||||
containertype = "/obj/structure/closet/crate/secure"
|
||||
containername = "Paramedic equipment"
|
||||
|
||||
@@ -11,7 +11,7 @@ var/const/AALARM_WIRE_AALARM = 16
|
||||
|
||||
/datum/wires/alarm/CanUse(var/mob/living/L)
|
||||
var/obj/machinery/alarm/A = holder
|
||||
if(A.wiresexposed && A.buildstage == 2)
|
||||
if(A.wiresexposed)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
@@ -62,9 +62,8 @@ using /datum/datacore/proc/manifest_inject( ), or manifest_insert( )
|
||||
*/
|
||||
|
||||
var/global/list/PDA_Manifest = list()
|
||||
var/global/ManifestJSON
|
||||
|
||||
/datum/datacore/proc/get_manifest_json()
|
||||
/datum/datacore/proc/get_manifest_list()
|
||||
if(PDA_Manifest.len)
|
||||
return
|
||||
var/heads[0]
|
||||
@@ -146,7 +145,6 @@ var/global/ManifestJSON
|
||||
"bot" = bot,\
|
||||
"misc" = misc\
|
||||
)
|
||||
ManifestJSON = json_encode(PDA_Manifest)
|
||||
return
|
||||
|
||||
|
||||
|
||||
@@ -128,6 +128,13 @@
|
||||
icon_state = "nullrod"
|
||||
item_state = "foldcane"
|
||||
|
||||
/obj/item/weapon/cane/whitecane
|
||||
name = "white cane"
|
||||
desc = "A cane used by the blind."
|
||||
icon = 'icons/obj/weapons.dmi'
|
||||
icon_state = "whitecane"
|
||||
item_state = "whitecane"
|
||||
|
||||
/obj/item/weapon/disk
|
||||
name = "disk"
|
||||
icon = 'icons/obj/items.dmi'
|
||||
@@ -268,21 +275,6 @@
|
||||
throw_range = 5
|
||||
w_class = 2.0
|
||||
|
||||
/obj/item/weapon/wire
|
||||
desc = "This is just a simple piece of regular insulated wire."
|
||||
name = "wire"
|
||||
icon = 'icons/obj/power.dmi'
|
||||
icon_state = "item_wire"
|
||||
var/amount = 1.0
|
||||
var/laying = 0.0
|
||||
var/old_lay = null
|
||||
matter = list(DEFAULT_WALL_MATERIAL = 40)
|
||||
attack_verb = list("whipped", "lashed", "disciplined", "tickled")
|
||||
|
||||
suicide_act(mob/user)
|
||||
viewers(user) << "<span class='warning'><b>[user] is strangling \himself with \the [src]! It looks like \he's trying to commit suicide.</b></span>"
|
||||
return (OXYLOSS)
|
||||
|
||||
/obj/item/weapon/module
|
||||
icon = 'icons/obj/module.dmi'
|
||||
icon_state = "std_module"
|
||||
@@ -598,3 +590,29 @@
|
||||
icon = 'icons/obj/stock_parts.dmi'
|
||||
icon_state = "smes_coil"
|
||||
origin_tech = list(TECH_MATERIAL = 19, TECH_ENGINEERING = 19, TECH_PHORON = 19, TECH_POWER = 19, TECH_BLUESPACE = 19, TECH_BIO = 19, TECH_COMBAT = 19, TECH_MAGNET = 19, TECH_DATA = 19, TECH_ILLEGAL = 19, TECH_ARCANE = 19)
|
||||
|
||||
// Additional construction stock parts
|
||||
|
||||
/obj/item/weapon/stock_parts/gear
|
||||
name = "gear"
|
||||
desc = "A gear used for construction."
|
||||
icon = 'icons/obj/stock_parts.dmi'
|
||||
icon_state = "gear"
|
||||
origin_tech = list(TECH_ENGINEERING = 1)
|
||||
matter = list(DEFAULT_WALL_MATERIAL = 50)
|
||||
|
||||
/obj/item/weapon/stock_parts/motor
|
||||
name = "motor"
|
||||
desc = "A motor used for construction."
|
||||
icon = 'icons/obj/stock_parts.dmi'
|
||||
icon_state = "motor"
|
||||
origin_tech = list(TECH_ENGINEERING = 1)
|
||||
matter = list(DEFAULT_WALL_MATERIAL = 60, "glass" = 10)
|
||||
|
||||
/obj/item/weapon/stock_parts/spring
|
||||
name = "spring"
|
||||
desc = "A spring used for construction."
|
||||
icon = 'icons/obj/stock_parts.dmi'
|
||||
icon_state = "spring"
|
||||
origin_tech = list(TECH_ENGINEERING = 1)
|
||||
matter = list(DEFAULT_WALL_MATERIAL = 40)
|
||||
@@ -30,6 +30,12 @@
|
||||
if(faction_verb && player.current)
|
||||
player.current.verbs |= faction_verb
|
||||
|
||||
spawn(1 SECOND) //Added a delay so that this should pop up at the bottom and not the top of the text flood the new antag gets.
|
||||
player.current << "<span class='notice'>Once you decide on a goal to pursue, you can optionally display it to \
|
||||
everyone at the end of the shift with the <b>Set Ambition</b> verb, located in the IC tab. You can change this at any time, \
|
||||
and it otherwise has no bearing on your round.</span>"
|
||||
player.current.verbs |= /mob/living/proc/write_ambition
|
||||
|
||||
// Handle only adding a mind and not bothering with gear etc.
|
||||
if(nonstandard_role_type)
|
||||
faction_members |= player
|
||||
@@ -50,5 +56,8 @@
|
||||
player.special_role = null
|
||||
update_icons_removed(player)
|
||||
BITSET(player.current.hud_updateflag, SPECIALROLE_HUD)
|
||||
if(!is_special_character(player))
|
||||
player.current.verbs -= /mob/living/proc/write_ambition
|
||||
player.ambitions = ""
|
||||
return 1
|
||||
return 0
|
||||
@@ -104,12 +104,6 @@
|
||||
create_nuke()
|
||||
|
||||
show_objectives(player)
|
||||
|
||||
// Clown clumsiness check, I guess downstream might use it.
|
||||
if (player.current.mind)
|
||||
if (player.current.mind.assigned_role == "Clown")
|
||||
player.current << "You have evolved beyond your clownish nature, allowing you to wield weapons without harming yourself."
|
||||
player.current.mutations.Remove(CLUMSY)
|
||||
return 1
|
||||
|
||||
/datum/antagonist/proc/set_antag_name(var/mob/living/player)
|
||||
|
||||
@@ -30,3 +30,26 @@
|
||||
world << "<span class='danger'><font size = 3>[loss_text]</font></span>"
|
||||
if(loss_feedback_tag) feedback_set_details("round_end_result","[loss_feedback_tag]")
|
||||
|
||||
/mob/living/proc/write_ambition()
|
||||
set name = "Set Ambition"
|
||||
set category = "IC"
|
||||
set src = usr
|
||||
|
||||
if(!mind)
|
||||
return
|
||||
if(!is_special_character(mind))
|
||||
src << "<span class='warning'>While you may perhaps have goals, this verb's meant to only be visible \
|
||||
to antagonists. Please make a bug report!</span>"
|
||||
return
|
||||
var/new_ambitions = input(src, "Write a short sentence of what your character hopes to accomplish \
|
||||
today as an antagonist. Remember that this is purely optional. It will be shown at the end of the \
|
||||
round for everybody else.", "Ambitions", mind.ambitions) as null|message
|
||||
if(isnull(new_ambitions))
|
||||
return
|
||||
mind.ambitions = new_ambitions
|
||||
new_ambitions = sanitize(new_ambitions)
|
||||
if(new_ambitions)
|
||||
src << "<span class='notice'>You've set your goal to be '[new_ambitions]'.</span>"
|
||||
else
|
||||
src << "<span class='notice'>You leave your ambitions behind.</span>"
|
||||
log_and_message_admins("has set their ambitions to now be: [new_ambitions].")
|
||||
|
||||
@@ -7,6 +7,9 @@
|
||||
for(var/datum/mind/P in current_antagonists)
|
||||
text += print_player_full(P)
|
||||
text += get_special_objective_text(P)
|
||||
if(P.ambitions)
|
||||
text += "<br>Their goals for today were..."
|
||||
text += "<br><span class='notice'>[P.ambitions]</span>"
|
||||
if(!global_objectives.len && P.objectives && P.objectives.len)
|
||||
var/failed
|
||||
var/num = 1
|
||||
|
||||
@@ -27,7 +27,7 @@ var/datum/antagonist/raider/raiders
|
||||
/obj/item/clothing/under/serviceoveralls,
|
||||
/obj/item/clothing/under/captain_fly,
|
||||
/obj/item/clothing/under/det,
|
||||
/obj/item/clothing/under/brown,
|
||||
/obj/item/clothing/under/color/brown,
|
||||
)
|
||||
|
||||
var/list/raider_shoes = list(
|
||||
|
||||
@@ -76,7 +76,7 @@ var/datum/antagonist/wizard/wizards
|
||||
return 0
|
||||
|
||||
wizard_mob.equip_to_slot_or_del(new /obj/item/device/radio/headset(wizard_mob), slot_l_ear)
|
||||
wizard_mob.equip_to_slot_or_del(new /obj/item/clothing/under/lightpurple(wizard_mob), slot_w_uniform)
|
||||
wizard_mob.equip_to_slot_or_del(new /obj/item/clothing/under/color/lightpurple(wizard_mob), slot_w_uniform)
|
||||
wizard_mob.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal(wizard_mob), slot_shoes)
|
||||
wizard_mob.equip_to_slot_or_del(new /obj/item/clothing/suit/wizrobe(wizard_mob), slot_wear_suit)
|
||||
wizard_mob.equip_to_slot_or_del(new /obj/item/clothing/head/wizard(wizard_mob), slot_head)
|
||||
|
||||
@@ -838,6 +838,10 @@ area/space/atmosalert()
|
||||
/area/maintenance/engineering
|
||||
name = "Engineering Maintenance"
|
||||
icon_state = "maint_engineering"
|
||||
|
||||
/area/maintenance/engineering/pumpstation
|
||||
name = "Engineering Pump Station"
|
||||
icon_state = "maint_pumpstation"
|
||||
|
||||
/area/maintenance/evahallway
|
||||
name = "\improper EVA Maintenance"
|
||||
@@ -2757,12 +2761,12 @@ var/list/the_station_areas = list (
|
||||
/area/rnd,
|
||||
/area/storage,
|
||||
/area/construction,
|
||||
/area/ai_monitored/storage/eva, //do not try to simplify to "/area/ai_monitored" --rastaf0
|
||||
/area/ai_monitored/storage/eva,
|
||||
/area/ai_monitored/storage/secure,
|
||||
/area/ai_monitored/storage/emergency,
|
||||
/area/ai_upload, //do not try to simplify to "/area" --rastaf0
|
||||
/area/ai_monitored/storage/emergency,
|
||||
/area/ai_upload,
|
||||
/area/ai_upload_foyer,
|
||||
/area/ai,
|
||||
/area/ai
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -243,7 +243,7 @@ var/list/mob/living/forced_ambiance_list = new
|
||||
|
||||
/area/proc/play_ambience(var/mob/living/L)
|
||||
// Ambience goes down here -- make sure to list each area seperately for ease of adding things in later, thanks! Note: areas adjacent to each other should have the same sounds to prevent cutoff when possible.- LastyScratch
|
||||
if(!(L && L.client && (L.client.prefs.toggles & SOUND_AMBIENCE))) return
|
||||
if(!(L && L.is_preference_enabled(/datum/client_preference/play_ambiance))) return
|
||||
|
||||
// If we previously were in an area with force-played ambiance, stop it.
|
||||
if(L in forced_ambiance_list)
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
idle_power_usage = 50
|
||||
active_power_usage = 300
|
||||
interact_offline = 1
|
||||
circuit = /obj/item/weapon/circuitboard/clonescanner
|
||||
var/locked = 0
|
||||
var/mob/living/carbon/occupant = null
|
||||
var/obj/item/weapon/reagent_containers/glass/beaker = null
|
||||
@@ -55,7 +56,6 @@
|
||||
/obj/machinery/dna_scannernew/New()
|
||||
..()
|
||||
component_parts = list()
|
||||
component_parts += new /obj/item/weapon/circuitboard/clonescanner(src)
|
||||
component_parts += new /obj/item/weapon/stock_parts/scanning_module(src)
|
||||
component_parts += new /obj/item/weapon/stock_parts/manipulator(src)
|
||||
component_parts += new /obj/item/weapon/stock_parts/micro_laser(src)
|
||||
|
||||
12
code/game/gamemodes/changeling/absorbed_dna.dm
Normal file
12
code/game/gamemodes/changeling/absorbed_dna.dm
Normal file
@@ -0,0 +1,12 @@
|
||||
/datum/absorbed_dna
|
||||
var/name
|
||||
var/datum/dna/dna
|
||||
var/speciesName
|
||||
var/list/languages
|
||||
|
||||
/datum/absorbed_dna/New(var/newName, var/newDNA, var/newSpecies, var/newLanguages)
|
||||
..()
|
||||
name = newName
|
||||
dna = newDNA
|
||||
speciesName = newSpecies
|
||||
languages = newLanguages
|
||||
@@ -1,5 +1,5 @@
|
||||
/datum/game_mode/changeling
|
||||
name = "changeling"
|
||||
name = "Changeling"
|
||||
round_description = "There are alien changelings on the station. Do not let the changelings succeed!"
|
||||
extended_round_description = "Life always finds a way. However, life can sometimes take a more disturbing route. \
|
||||
Humanity's extensive knowledge of xeno-biological specimens has made them confident and arrogant. Yet \
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
var/global/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","Epsilon","Zeta","Eta","Theta","Iota","Kappa","Lambda","Mu","Nu","Xi","Omicron","Pi","Rho","Sigma","Tau","Upsilon","Phi","Chi","Psi","Omega")
|
||||
|
||||
/datum/changeling //stores changeling powers, changeling recharge thingie, changeling absorbed DNA and changeling ID (for changeling hivemind)
|
||||
var/list/absorbed_dna = list()
|
||||
var/list/absorbed_species = list()
|
||||
var/list/absorbed_languages = list()
|
||||
var/list/datum/absorbed_dna/absorbed_dna = list()
|
||||
var/list/absorbed_languages = list() // Necessary because of set_species stuff
|
||||
var/absorbedcount = 0
|
||||
var/chem_charges = 20
|
||||
var/chem_recharge_rate = 0.5
|
||||
@@ -23,25 +22,36 @@ var/global/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","E
|
||||
|
||||
/datum/changeling/New(var/gender=FEMALE)
|
||||
..()
|
||||
var/honorific = (gender == FEMALE) ? "Ms." : "Mr."
|
||||
if(possible_changeling_IDs.len)
|
||||
changelingID = pick(possible_changeling_IDs)
|
||||
possible_changeling_IDs -= changelingID
|
||||
changelingID = "[honorific] [changelingID]"
|
||||
changelingID = "[changelingID]"
|
||||
else
|
||||
changelingID = "[honorific] [rand(1,999)]"
|
||||
changelingID = "[rand(1,999)]"
|
||||
|
||||
/datum/changeling/proc/regenerate()
|
||||
chem_charges = min(max(0, chem_charges+chem_recharge_rate), chem_storage)
|
||||
geneticdamage = max(0, geneticdamage-1)
|
||||
|
||||
/datum/changeling/proc/GetDNA(var/dna_owner)
|
||||
var/datum/dna/chosen_dna
|
||||
for(var/datum/dna/DNA in absorbed_dna)
|
||||
if(dna_owner == DNA.real_name)
|
||||
chosen_dna = DNA
|
||||
break
|
||||
return chosen_dna
|
||||
for(var/datum/absorbed_dna/DNA in absorbed_dna)
|
||||
if(dna_owner == DNA.name)
|
||||
return DNA
|
||||
|
||||
/mob/proc/absorbDNA(var/datum/absorbed_dna/newDNA)
|
||||
var/datum/changeling/changeling = null
|
||||
if(src.mind && src.mind.changeling)
|
||||
changeling = src.mind.changeling
|
||||
if(!changeling)
|
||||
return
|
||||
|
||||
for(var/language in newDNA.languages)
|
||||
changeling.absorbed_languages |= language
|
||||
|
||||
changeling_update_languages(changeling.absorbed_languages)
|
||||
|
||||
if(!changeling.GetDNA(newDNA.name)) // Don't duplicate - I wonder if it's possible for it to still be a different DNA? DNA code could use a rewrite
|
||||
changeling.absorbed_dna += newDNA
|
||||
|
||||
//Restores our verbs. It will only restore verbs allowed during lesser (monkey) form if we are not human
|
||||
/mob/proc/make_changeling()
|
||||
@@ -70,14 +80,13 @@ var/global/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","E
|
||||
if(!(P in src.verbs))
|
||||
src.verbs += P.verbpath
|
||||
|
||||
mind.changeling.absorbed_dna |= dna
|
||||
for(var/language in languages)
|
||||
mind.changeling.absorbed_languages |= language
|
||||
|
||||
var/mob/living/carbon/human/H = src
|
||||
if(istype(H))
|
||||
mind.changeling.absorbed_species += H.species.name
|
||||
|
||||
for(var/language in languages)
|
||||
mind.changeling.absorbed_languages |= language
|
||||
var/datum/absorbed_dna/newDNA = new(H.real_name, H.dna, H.species.name, H.languages)
|
||||
absorbDNA(newDNA)
|
||||
|
||||
return 1
|
||||
|
||||
@@ -118,10 +127,8 @@ var/global/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","E
|
||||
|
||||
return changeling
|
||||
|
||||
|
||||
//Used to dump the languages from the changeling datum into the actual mob.
|
||||
/mob/proc/changeling_update_languages(var/updated_languages)
|
||||
|
||||
languages = list()
|
||||
for(var/language in updated_languages)
|
||||
languages += language
|
||||
@@ -129,8 +136,6 @@ var/global/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","E
|
||||
//This isn't strictly necessary but just to be safe...
|
||||
add_language("Changeling")
|
||||
|
||||
return
|
||||
|
||||
//////////
|
||||
//STINGS// //They get a pretty header because there's just so fucking many of them ;_;
|
||||
//////////
|
||||
@@ -171,9 +176,3 @@ var/global/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","E
|
||||
if(!T.mind || !T.mind.changeling) return T //T will be affected by the sting
|
||||
T << "<span class='warning'>You feel a tiny prick.</span>"
|
||||
return
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -65,33 +65,21 @@
|
||||
src << "<span class='notice'>We have absorbed [T]!</span>"
|
||||
src.visible_message("<span class='danger'>[src] sucks the fluids from [T]!</span>")
|
||||
T << "<span class='danger'>You have been absorbed by the changeling!</span>"
|
||||
|
||||
T.dna.real_name = T.real_name //Set this again, just to be sure that it's properly set.
|
||||
changeling.absorbed_dna |= T.dna
|
||||
if(src.nutrition < 400)
|
||||
src.nutrition = min((src.nutrition + T.nutrition), 400)
|
||||
changeling.chem_charges += 10
|
||||
// changeling.geneticpoints += 2
|
||||
src.verbs += /mob/proc/changeling_respec
|
||||
src << "<span class='notice'>We can now re-adapt, reverting our evolution so that we may start anew, if needed.</span>"
|
||||
|
||||
//Steal all of their languages!
|
||||
for(var/language in T.languages)
|
||||
if(!(language in changeling.absorbed_languages))
|
||||
changeling.absorbed_languages += language
|
||||
|
||||
changeling_update_languages(changeling.absorbed_languages)
|
||||
|
||||
//Steal their species!
|
||||
if(T.species && !(T.species.name in changeling.absorbed_species))
|
||||
changeling.absorbed_species += T.species.name
|
||||
var/datum/absorbed_dna/newDNA = new(T.real_name, T.dna, T.species.name, T.languages)
|
||||
absorbDNA(newDNA)
|
||||
|
||||
if(T.mind && T.mind.changeling)
|
||||
if(T.mind.changeling.absorbed_dna)
|
||||
for(var/dna_data in T.mind.changeling.absorbed_dna) //steal all their loot
|
||||
for(var/datum/absorbed_dna/dna_data in T.mind.changeling.absorbed_dna) //steal all their loot
|
||||
if(dna_data in changeling.absorbed_dna)
|
||||
continue
|
||||
changeling.absorbed_dna += dna_data
|
||||
absorbDNA(dna_data)
|
||||
changeling.absorbedcount++
|
||||
T.mind.changeling.absorbed_dna.len = 1
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
/obj/item/weapon/melee/arm_blade/dropped(mob/user)
|
||||
visible_message("<span class='warning'>With a sickening crunch, [creator] reforms their arm blade into an arm!</span>",
|
||||
"<span class='notice'>We assimilate the weapon back into our body.</span>",
|
||||
"<span class='italics>You hear organic matter ripping and tearing!</span>")
|
||||
"<span class='italics'>You hear organic matter ripping and tearing!</span>")
|
||||
playsound(src, 'sound/effects/blobattack.ogg', 30, 1)
|
||||
spawn(1)
|
||||
if(src)
|
||||
|
||||
@@ -19,6 +19,9 @@
|
||||
|
||||
var/mob/living/carbon/human/T = changeling_sting(40, /mob/proc/changeling_extract_dna_sting)
|
||||
|
||||
if(!T)
|
||||
return
|
||||
|
||||
if(!istype(T) || T.isSynthetic())
|
||||
src << "<span class='warning'>\The [T] is not compatible with our biology.</span>"
|
||||
return 0
|
||||
@@ -31,10 +34,8 @@
|
||||
src << "<span class='warning'>This creature's DNA is ruined beyond useability!</span>"
|
||||
return 0
|
||||
|
||||
T.dna.real_name = T.real_name
|
||||
changeling.absorbed_dna |= T.dna
|
||||
if(T.species && !(T.species.name in changeling.absorbed_species))
|
||||
changeling.absorbed_species += T.species.name
|
||||
var/datum/absorbed_dna/newDNA = new(T.real_name, T.dna, T.species.name, T.languages)
|
||||
absorbDNA(newDNA)
|
||||
|
||||
feedback_add_details("changeling_powers","ED")
|
||||
return 1
|
||||
@@ -27,9 +27,9 @@ var/list/datum/dna/hivemind_bank = list()
|
||||
if(!changeling) return
|
||||
|
||||
var/list/names = list()
|
||||
for(var/datum/dna/DNA in changeling.absorbed_dna)
|
||||
for(var/datum/absorbed_dna/DNA in changeling.absorbed_dna)
|
||||
if(!(DNA in hivemind_bank))
|
||||
names += DNA.real_name
|
||||
names += DNA.name
|
||||
|
||||
if(names.len <= 0)
|
||||
src << "<span class='notice'>The airwaves already have all of our DNA.</span>"
|
||||
@@ -38,7 +38,7 @@ var/list/datum/dna/hivemind_bank = list()
|
||||
var/S = input("Select a DNA to channel: ", "Channel DNA", null) as null|anything in names
|
||||
if(!S) return
|
||||
|
||||
var/datum/dna/chosen_dna = changeling.GetDNA(S)
|
||||
var/datum/absorbed_dna/chosen_dna = changeling.GetDNA(S)
|
||||
if(!chosen_dna)
|
||||
return
|
||||
|
||||
@@ -57,9 +57,9 @@ var/list/datum/dna/hivemind_bank = list()
|
||||
if(!changeling) return
|
||||
|
||||
var/list/names = list()
|
||||
for(var/datum/dna/DNA in hivemind_bank)
|
||||
for(var/datum/absorbed_dna/DNA in hivemind_bank)
|
||||
if(!(DNA in changeling.absorbed_dna))
|
||||
names[DNA.real_name] = DNA
|
||||
names[DNA.name] = DNA
|
||||
|
||||
if(names.len <= 0)
|
||||
src << "<span class='notice'>There's no new DNA to absorb from the air.</span>"
|
||||
@@ -67,12 +67,12 @@ var/list/datum/dna/hivemind_bank = list()
|
||||
|
||||
var/S = input("Select a DNA absorb from the air: ", "Absorb DNA", null) as null|anything in names
|
||||
if(!S) return
|
||||
var/datum/dna/chosen_dna = names[S]
|
||||
var/datum/absorbed_dna/chosen_dna = names[S]
|
||||
if(!chosen_dna)
|
||||
return
|
||||
|
||||
changeling.chem_charges -= 20
|
||||
changeling.absorbed_dna += chosen_dna
|
||||
absorbDNA(chosen_dna)
|
||||
src << "<span class='notice'>We absorb the DNA of [S] from the air.</span>"
|
||||
feedback_add_details("changeling_powers","HD")
|
||||
return 1
|
||||
@@ -48,7 +48,7 @@
|
||||
new /obj/effect/gibspawner/human(T)
|
||||
visible_message("<span class='warning'>With a sickening squish, [src] reforms their whole body, casting their old parts on the floor!</span>",
|
||||
"<span class='notice'>We reform our body. We are whole once more.</span>",
|
||||
"<span class='italics>You hear organic matter ripping and tearing!</span>")
|
||||
"<span class='italics'>You hear organic matter ripping and tearing!</span>")
|
||||
|
||||
feedback_add_details("changeling_powers","RR")
|
||||
return 1
|
||||
@@ -1,8 +1,8 @@
|
||||
/datum/power/changeling/self_respiration
|
||||
name = "Self Respiration"
|
||||
desc = "We evolve our body to no longer require drawing oxygen from the atmosphere.."
|
||||
desc = "We evolve our body to no longer require drawing oxygen from the atmosphere."
|
||||
helptext = "We will no longer require internals, and we cannot inhale any gas, including harmful ones."
|
||||
genomecost = 1
|
||||
genomecost = 0
|
||||
isVerb = 0
|
||||
verbpath = /mob/proc/changeling_self_respiration
|
||||
|
||||
|
||||
@@ -4,12 +4,6 @@
|
||||
genomecost = 0
|
||||
verbpath = /mob/proc/changeling_transform
|
||||
|
||||
/datum/power/changeling/change_species
|
||||
name = "Change Species"
|
||||
desc = "We take on the apperance of a species that we have absorbed."
|
||||
genomecost = 0
|
||||
verbpath = /mob/proc/changeling_change_species
|
||||
|
||||
//Change our DNA to that of somebody we've absorbed.
|
||||
/mob/proc/changeling_transform()
|
||||
set category = "Changeling"
|
||||
@@ -19,73 +13,42 @@
|
||||
if(!changeling) return
|
||||
|
||||
var/list/names = list()
|
||||
for(var/datum/dna/DNA in changeling.absorbed_dna)
|
||||
names += "[DNA.real_name]"
|
||||
for(var/datum/absorbed_dna/DNA in changeling.absorbed_dna)
|
||||
names += "[DNA.name]"
|
||||
|
||||
var/S = input("Select the target DNA: ", "Target DNA", null) as null|anything in names
|
||||
if(!S) return
|
||||
|
||||
var/datum/dna/chosen_dna = changeling.GetDNA(S)
|
||||
var/datum/absorbed_dna/chosen_dna = changeling.GetDNA(S)
|
||||
if(!chosen_dna)
|
||||
return
|
||||
|
||||
changeling.chem_charges -= 5
|
||||
src.visible_message("<span class='warning'>[src] transforms!</span>")
|
||||
changeling.geneticdamage = 5
|
||||
src.dna = chosen_dna.Clone()
|
||||
|
||||
if(ishuman(src))
|
||||
var/mob/living/carbon/human/H = src
|
||||
var/newSpecies = chosen_dna.speciesName
|
||||
H.set_species(newSpecies,1)
|
||||
|
||||
src.dna = chosen_dna.dna.Clone()
|
||||
src.dna.b_type = "AB+" //This is needed to avoid blood rejection bugs. The fact that the blood type might not match up w/ records could be a *FEATURE* too.
|
||||
if(ishuman(src))
|
||||
var/mob/living/carbon/human/H = src
|
||||
H.b_type = "AB+" //For some reason we have two blood types on the mob.
|
||||
for(var/flavor in H.flavor_texts) //Nulls out flavor text, so we don't keep our previous mob's flavor.
|
||||
flavor = null
|
||||
src.real_name = chosen_dna.real_name
|
||||
src.real_name = chosen_dna.name
|
||||
src.flavor_text = ""
|
||||
src.UpdateAppearance()
|
||||
domutcheck(src, null)
|
||||
changeling_update_languages(changeling.absorbed_languages)
|
||||
|
||||
src.verbs -= /mob/proc/changeling_transform
|
||||
spawn(10) src.verbs += /mob/proc/changeling_transform
|
||||
spawn(10)
|
||||
src.verbs += /mob/proc/changeling_transform
|
||||
src.regenerate_icons()
|
||||
|
||||
feedback_add_details("changeling_powers","TR")
|
||||
return 1
|
||||
|
||||
//Used to switch species based on the changeling datum.
|
||||
/mob/proc/changeling_change_species()
|
||||
|
||||
set category = "Changeling"
|
||||
set name = "Change Species (5)"
|
||||
|
||||
var/mob/living/carbon/human/H = src
|
||||
if(!istype(H))
|
||||
src << "<span class='warning'>We may only use this power while in humanoid form.</span>"
|
||||
return
|
||||
|
||||
var/datum/changeling/changeling = changeling_power(5,1,0)
|
||||
if(!changeling) return
|
||||
|
||||
if(changeling.absorbed_species.len < 2)
|
||||
src << "<span class='warning'>We do not know of any other species genomes to use.</span>"
|
||||
return
|
||||
|
||||
var/S = input("Select the target species: ", "Target Species", null) as null|anything in changeling.absorbed_species
|
||||
if(!S) return
|
||||
|
||||
domutcheck(src, null)
|
||||
|
||||
changeling.chem_charges -= 5
|
||||
changeling.geneticdamage = 5
|
||||
|
||||
src.visible_message("<span class='warning'>[src] transforms!</span>")
|
||||
|
||||
src.verbs -= /mob/proc/changeling_change_species
|
||||
H.set_species(S,1) //Until someone moves body colour into DNA, they're going to have to use the default.
|
||||
|
||||
spawn(10)
|
||||
src.verbs += /mob/proc/changeling_change_species
|
||||
src.regenerate_icons()
|
||||
|
||||
changeling_update_languages(changeling.absorbed_languages)
|
||||
feedback_add_details("changeling_powers","TR")
|
||||
|
||||
return 1
|
||||
@@ -36,7 +36,7 @@
|
||||
desc = "A hood worn by the followers of Nar-Sie."
|
||||
flags_inv = HIDEFACE
|
||||
body_parts_covered = HEAD
|
||||
armor = list(melee = 30, bullet = 10, laser = 5,energy = 5, bomb = 0, bio = 0, rad = 0)
|
||||
armor = list(melee = 50, bullet = 30, laser = 50, energy = 20, bomb = 25, bio = 10, rad = 0)
|
||||
cold_protection = HEAD
|
||||
min_cold_protection_temperature = SPACE_HELMET_MIN_COLD_PROTECTION_TEMPERATURE
|
||||
siemens_coefficient = 0
|
||||
@@ -61,7 +61,7 @@
|
||||
item_state = "cultrobes"
|
||||
body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS
|
||||
allowed = list(/obj/item/weapon/book/tome,/obj/item/weapon/melee/cultblade)
|
||||
armor = list(melee = 50, bullet = 30, laser = 50,energy = 20, bomb = 25, bio = 10, rad = 0)
|
||||
armor = list(melee = 50, bullet = 30, laser = 50, energy = 20, bomb = 25, bio = 10, rad = 0)
|
||||
flags_inv = HIDEJUMPSUIT
|
||||
siemens_coefficient = 0
|
||||
|
||||
@@ -84,7 +84,7 @@
|
||||
name = "cult helmet"
|
||||
desc = "A space worthy helmet used by the followers of Nar-Sie"
|
||||
icon_state = "cult_helmet"
|
||||
armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 30, rad = 30)
|
||||
armor = list(melee = 60, bullet = 50, laser = 30, energy = 15, bomb = 30, bio = 30, rad = 30)
|
||||
siemens_coefficient = 0
|
||||
|
||||
/obj/item/clothing/head/helmet/space/cult/cultify()
|
||||
@@ -98,7 +98,7 @@
|
||||
w_class = 3
|
||||
allowed = list(/obj/item/weapon/book/tome,/obj/item/weapon/melee/cultblade,/obj/item/weapon/tank/emergency_oxygen,/obj/item/device/suit_cooling_unit)
|
||||
slowdown = 1
|
||||
armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 30, rad = 30)
|
||||
armor = list(melee = 60, bullet = 50, laser = 30, energy = 15, bomb = 30, bio = 30, rad = 30)
|
||||
siemens_coefficient = 0
|
||||
body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS|HANDS
|
||||
|
||||
|
||||
@@ -185,7 +185,6 @@ var/global/list/rnwords = list("ire","ego","nahlizet","certum","veri","jatkaa","
|
||||
throw_range = 5
|
||||
w_class = 2.0
|
||||
unique = 1
|
||||
var/notedat = ""
|
||||
var/tomedat = ""
|
||||
var/list/words = list("ire" = "ire", "ego" = "ego", "nahlizet" = "nahlizet", "certum" = "certum", "veri" = "veri", "jatkaa" = "jatkaa", "balaq" = "balaq", "mgar" = "mgar", "karazet" = "karazet", "geeri" = "geeri")
|
||||
|
||||
@@ -285,57 +284,12 @@ var/global/list/rnwords = list("ire","ego","nahlizet","certum","veri","jatkaa","
|
||||
</html>
|
||||
"}
|
||||
|
||||
|
||||
Topic(href,href_list[])
|
||||
if (src.loc == usr)
|
||||
var/number = text2num(href_list["number"])
|
||||
if (usr.stat|| usr.restrained())
|
||||
return
|
||||
switch(href_list["action"])
|
||||
if("clear")
|
||||
words[words[number]] = words[number]
|
||||
if("change")
|
||||
words[words[number]] = input("Enter the translation for [words[number]]", "Word notes") in engwords
|
||||
for (var/w in words)
|
||||
if ((words[w] == words[words[number]]) && (w != words[number]))
|
||||
words[w] = w
|
||||
notedat = {"
|
||||
<br><b>Word translation notes</b> <br>
|
||||
[words[1]] is <a href='byond://?src=\ref[src];number=1;action=change'>[words[words[1]]]</A> <A href='byond://?src=\ref[src];number=1;action=clear'>Clear</A><BR>
|
||||
[words[2]] is <A href='byond://?src=\ref[src];number=2;action=change'>[words[words[2]]]</A> <A href='byond://?src=\ref[src];number=2;action=clear'>Clear</A><BR>
|
||||
[words[3]] is <a href='byond://?src=\ref[src];number=3;action=change'>[words[words[3]]]</A> <A href='byond://?src=\ref[src];number=3;action=clear'>Clear</A><BR>
|
||||
[words[4]] is <a href='byond://?src=\ref[src];number=4;action=change'>[words[words[4]]]</A> <A href='byond://?src=\ref[src];number=4;action=clear'>Clear</A><BR>
|
||||
[words[5]] is <a href='byond://?src=\ref[src];number=5;action=change'>[words[words[5]]]</A> <A href='byond://?src=\ref[src];number=5;action=clear'>Clear</A><BR>
|
||||
[words[6]] is <a href='byond://?src=\ref[src];number=6;action=change'>[words[words[6]]]</A> <A href='byond://?src=\ref[src];number=6;action=clear'>Clear</A><BR>
|
||||
[words[7]] is <a href='byond://?src=\ref[src];number=7;action=change'>[words[words[7]]]</A> <A href='byond://?src=\ref[src];number=7;action=clear'>Clear</A><BR>
|
||||
[words[8]] is <a href='byond://?src=\ref[src];number=8;action=change'>[words[words[8]]]</A> <A href='byond://?src=\ref[src];number=8;action=clear'>Clear</A><BR>
|
||||
[words[9]] is <a href='byond://?src=\ref[src];number=9;action=change'>[words[words[9]]]</A> <A href='byond://?src=\ref[src];number=9;action=clear'>Clear</A><BR>
|
||||
[words[10]] is <a href='byond://?src=\ref[src];number=10;action=change'>[words[words[10]]]</A> <A href='byond://?src=\ref[src];number=10;action=clear'>Clear</A><BR>
|
||||
"}
|
||||
usr << browse("[notedat]", "window=notes")
|
||||
// call(/obj/item/weapon/book/tome/proc/edit_notes)()
|
||||
else
|
||||
usr << browse(null, "window=notes")
|
||||
return
|
||||
|
||||
|
||||
// proc/edit_notes() FUCK IT. Cant get it to work properly. - K0000
|
||||
// world << "its been called! [usr]"
|
||||
// notedat = {"
|
||||
// <br><b>Word translation notes</b> <br>
|
||||
// [words[1]] is <a href='byond://?src=\ref[src];number=1;action=change'>[words[words[1]]]</A> <A href='byond://?src=\ref[src];number=1;action=clear'>Clear</A><BR>
|
||||
// [words[2]] is <A href='byond://?src=\ref[src];number=2;action=change'>[words[words[2]]]</A> <A href='byond://?src=\ref[src];number=2;action=clear'>Clear</A><BR>
|
||||
// [words[3]] is <a href='byond://?src=\ref[src];number=3;action=change'>[words[words[3]]]</A> <A href='byond://?src=\ref[src];number=3;action=clear'>Clear</A><BR>
|
||||
// [words[4]] is <a href='byond://?src=\ref[src];number=4;action=change'>[words[words[4]]]</A> <A href='byond://?src=\ref[src];number=4;action=clear'>Clear</A><BR>
|
||||
// [words[5]] is <a href='byond://?src=\ref[src];number=5;action=change'>[words[words[5]]]</A> <A href='byond://?src=\ref[src];number=5;action=clear'>Clear</A><BR>
|
||||
// [words[6]] is <a href='byond://?src=\ref[src];number=6;action=change'>[words[words[6]]]</A> <A href='byond://?src=\ref[src];number=6;action=clear'>Clear</A><BR>
|
||||
// [words[7]] is <a href='byond://?src=\ref[src];number=7;action=change'>[words[words[7]]]</A> <A href='byond://?src=\ref[src];number=7;action=clear'>Clear</A><BR>
|
||||
// [words[8]] is <a href='byond://?src=\ref[src];number=8;action=change'>[words[words[8]]]</A> <A href='byond://?src=\ref[src];number=8;action=clear'>Clear</A><BR>
|
||||
// [words[9]] is <a href='byond://?src=\ref[src];number=9;action=change'>[words[words[9]]]</A> <A href='byond://?src=\ref[src];number=9;action=clear'>Clear</A><BR>
|
||||
// [words[10]] is <a href='byond://?src=\ref[src];number=10;action=change'>[words[words[10]]]</A> <A href='byond://?src=\ref[src];number=10;action=clear'>Clear</A><BR>
|
||||
// "}
|
||||
// usr << "whatev"
|
||||
// usr << browse(null, "window=tank")
|
||||
New()
|
||||
..()
|
||||
if(!cultwords["travel"])
|
||||
runerandom()
|
||||
for(var/V in cultwords)
|
||||
words[cultwords[V]] = V
|
||||
|
||||
attack(mob/living/M as mob, mob/living/user as mob)
|
||||
|
||||
@@ -378,7 +332,7 @@ var/global/list/rnwords = list("ire","ego","nahlizet","certum","veri","jatkaa","
|
||||
alert("The cloth of reality can't take that much of a strain. Remove some runes first!")
|
||||
return
|
||||
else
|
||||
switch(alert("You open the tome",,"Read it","Scribe a rune", "Notes")) //Fuck the "Cancel" option. Rewrite the whole tome interface yourself if you want it to work better. And input() is just ugly. - K0000
|
||||
switch(alert("You open the tome",,"Read it","Scribe a rune", "Cancel"))
|
||||
if("Cancel")
|
||||
return
|
||||
if("Read it")
|
||||
@@ -386,25 +340,6 @@ var/global/list/rnwords = list("ire","ego","nahlizet","certum","veri","jatkaa","
|
||||
return
|
||||
user << browse("[tomedat]", "window=Arcane Tome")
|
||||
return
|
||||
if("Notes")
|
||||
if(usr.get_active_hand() != src)
|
||||
return
|
||||
notedat = {"
|
||||
<br><b>Word translation notes</b> <br>
|
||||
[words[1]] is <a href='byond://?src=\ref[src];number=1;action=change'>[words[words[1]]]</A> <A href='byond://?src=\ref[src];number=1;action=clear'>Clear</A><BR>
|
||||
[words[2]] is <A href='byond://?src=\ref[src];number=2;action=change'>[words[words[2]]]</A> <A href='byond://?src=\ref[src];number=2;action=clear'>Clear</A><BR>
|
||||
[words[3]] is <a href='byond://?src=\ref[src];number=3;action=change'>[words[words[3]]]</A> <A href='byond://?src=\ref[src];number=3;action=clear'>Clear</A><BR>
|
||||
[words[4]] is <a href='byond://?src=\ref[src];number=4;action=change'>[words[words[4]]]</A> <A href='byond://?src=\ref[src];number=4;action=clear'>Clear</A><BR>
|
||||
[words[5]] is <a href='byond://?src=\ref[src];number=5;action=change'>[words[words[5]]]</A> <A href='byond://?src=\ref[src];number=5;action=clear'>Clear</A><BR>
|
||||
[words[6]] is <a href='byond://?src=\ref[src];number=6;action=change'>[words[words[6]]]</A> <A href='byond://?src=\ref[src];number=6;action=clear'>Clear</A><BR>
|
||||
[words[7]] is <a href='byond://?src=\ref[src];number=7;action=change'>[words[words[7]]]</A> <A href='byond://?src=\ref[src];number=7;action=clear'>Clear</A><BR>
|
||||
[words[8]] is <a href='byond://?src=\ref[src];number=8;action=change'>[words[words[8]]]</A> <A href='byond://?src=\ref[src];number=8;action=clear'>Clear</A><BR>
|
||||
[words[9]] is <a href='byond://?src=\ref[src];number=9;action=change'>[words[words[9]]]</A> <A href='byond://?src=\ref[src];number=9;action=clear'>Clear</A><BR>
|
||||
[words[10]] is <a href='byond://?src=\ref[src];number=10;action=change'>[words[words[10]]]</A> <A href='byond://?src=\ref[src];number=10;action=clear'>Clear</A><BR>
|
||||
"}
|
||||
// call(/obj/item/weapon/book/tome/proc/edit_notes)()
|
||||
user << browse("[notedat]", "window=notes")
|
||||
return
|
||||
if(usr.get_active_hand() != src)
|
||||
return
|
||||
|
||||
@@ -489,21 +424,6 @@ var/global/list/rnwords = list("ire","ego","nahlizet","certum","veri","jatkaa","
|
||||
user << "The book seems full of illegible scribbles. Is this a joke?"
|
||||
return
|
||||
|
||||
attackby(obj/item/weapon/book/tome/T as obj, mob/living/user as mob)
|
||||
if(istype(T, /obj/item/weapon/book/tome)) // sanity check to prevent a runtime error
|
||||
switch(alert("Copy the runes from your tome?",,"Copy", "Cancel"))
|
||||
if("cancel")
|
||||
return
|
||||
// var/list/nearby = viewers(1,src) //- Fuck this as well. No clue why this doesnt work. -K0000
|
||||
// if (T.loc != user)
|
||||
// return
|
||||
// for(var/mob/M in nearby)
|
||||
// if(M == user)
|
||||
for(var/entry in words)
|
||||
words[entry] = T.words[entry]
|
||||
user << "You copy the translation notes from your tome."
|
||||
|
||||
|
||||
examine(mob/user)
|
||||
if(!iscultist(user))
|
||||
user << "An old, dusty tome with frayed edges and a sinister looking cover."
|
||||
|
||||
@@ -423,7 +423,7 @@ var/list/sacrificed = list()
|
||||
L.ajourn=0
|
||||
return
|
||||
else
|
||||
L.take_organ_damage(10, 0)
|
||||
L.take_organ_damage(3, 0)
|
||||
sleep(100)
|
||||
return fizzle()
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/datum/game_mode/epidemic
|
||||
name = "epidemic"
|
||||
name = "Epidemic"
|
||||
config_tag = "epidemic"
|
||||
required_players = 1
|
||||
required_players_secret = 15
|
||||
|
||||
@@ -39,10 +39,6 @@ var/global/list/additional_antag_types = list()
|
||||
|
||||
/datum/game_mode/New()
|
||||
..()
|
||||
// Enforce some formatting.
|
||||
// This will probably break something.
|
||||
name = capitalize(lowertext(name))
|
||||
config_tag = lowertext(config_tag)
|
||||
|
||||
/datum/game_mode/Topic(href, href_list[])
|
||||
if(..())
|
||||
|
||||
@@ -112,7 +112,7 @@ var/global/datum/controller/gameticker/ticker
|
||||
tmpmodes+=M.name
|
||||
tmpmodes = sortList(tmpmodes)
|
||||
if(tmpmodes.len)
|
||||
world << "<B>Possibilities:</B> [english_list(tmpmodes)]"
|
||||
world << "<B>Possibilities:</B> [english_list(tmpmodes, and_text= "; ", comma_text = "; ")]"
|
||||
else
|
||||
src.mode.announce()
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ VOX HEIST ROUNDTYPE
|
||||
var/global/list/obj/cortical_stacks = list() //Stacks for 'leave nobody behind' objective. Clumsy, rewrite sometime.
|
||||
|
||||
/datum/game_mode/heist
|
||||
name = "heist"
|
||||
name = "Heist"
|
||||
config_tag = "heist"
|
||||
required_players = 15
|
||||
required_players_secret = 15
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/datum/game_mode/malfunction
|
||||
name = "AI malfunction"
|
||||
name = "AI Malfunction"
|
||||
round_description = "The AI is behaving abnormally and must be stopped."
|
||||
extended_round_description = "The AI will attempt to hack the APCs around the station in order to gain as much control as possible."
|
||||
config_tag = "malfunction"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/datum/game_mode/conflux
|
||||
name = "conflux"
|
||||
name = "Wizard & Cult"
|
||||
round_description = "A space wizard and a cult have invaded the station!"
|
||||
extended_round_description = "Cultists and wizards spawn during this round."
|
||||
config_tag = "conflux"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/datum/game_mode/infestation
|
||||
name = "infestation"
|
||||
name = "Borers & Changelings"
|
||||
round_description = "There's something in the walls!"
|
||||
extended_round_description = "Two alien antagonists (Cortical Borers or Changelings) spawn during this round."
|
||||
config_tag = "infestation"
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/datum/game_mode/intrigue
|
||||
name = "Intrigue"
|
||||
name = "Traitors & Ninja"
|
||||
round_description = "Crewmembers are contacted by external elements while another infiltrates the colony."
|
||||
extended_round_description = "Traitors and a ninja spawn during this round."
|
||||
config_tag = "intrigue"
|
||||
required_players = 15
|
||||
required_players_secret = 15
|
||||
required_enemies = 4
|
||||
required_players = 6
|
||||
required_players_secret = 8
|
||||
required_enemies = 3
|
||||
end_on_antag_death = 0
|
||||
antag_tags = list(MODE_NINJA, MODE_AUTOTRAITOR)
|
||||
round_autoantag = 1
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/datum/game_mode/lizard
|
||||
name = "lizard"
|
||||
name = "Wizard & Changelings"
|
||||
round_description = "A space wizard and changelings have invaded the station!"
|
||||
extended_round_description = "Changelings and a wizard spawn during this round."
|
||||
config_tag = "lizard"
|
||||
required_players = 15
|
||||
required_players_secret = 15
|
||||
required_enemies = 4
|
||||
required_players = 2
|
||||
required_players_secret = 8
|
||||
required_enemies = 3
|
||||
end_on_antag_death = 0
|
||||
antag_tags = list(MODE_WIZARD, MODE_CHANGELING)
|
||||
require_all_templates = 1
|
||||
11
code/game/gamemodes/mixed/mercrenegade.dm
Normal file
11
code/game/gamemodes/mixed/mercrenegade.dm
Normal file
@@ -0,0 +1,11 @@
|
||||
/datum/game_mode/mercren
|
||||
name = "Mercenaries & Renegades"
|
||||
round_description = "A mercenary team has invaded the station, as well as other having brought their own form protection."
|
||||
extended_round_description = "Mercenaries and traitors spawn during this round."
|
||||
config_tag = "mercren"
|
||||
required_players = 16 //What could possibly go wrong?
|
||||
required_players_secret = 15
|
||||
required_enemies = 8
|
||||
end_on_antag_death = 0
|
||||
antag_tags = list(MODE_MERCENARY, MODE_RENEGADE)
|
||||
require_all_templates = 1
|
||||
11
code/game/gamemodes/mixed/mercwiz.dm
Normal file
11
code/game/gamemodes/mixed/mercwiz.dm
Normal file
@@ -0,0 +1,11 @@
|
||||
/datum/game_mode/mercwiz
|
||||
name = "Mercenaries & Wizard"
|
||||
round_description = "A mercenary team and a wizard have invaded the station!"
|
||||
extended_round_description = "Mercenaries and wizard spawn during this round."
|
||||
config_tag = "mercwiz"
|
||||
required_players = 15 //I don't think we can have it lower and not need an ERT every round.
|
||||
required_players_secret = 15 //I don't think we can have it lower and not need an ERT every round.
|
||||
required_enemies = 7
|
||||
end_on_antag_death = 0
|
||||
antag_tags = list(MODE_MERCENARY, MODE_WIZARD)
|
||||
require_all_templates = 1
|
||||
@@ -1,5 +1,5 @@
|
||||
/datum/game_mode/paranoia
|
||||
name = "paranoia"
|
||||
name = "Malf AI, Renegades & Changelings"
|
||||
round_description = "The AI has malfunctioned, and subversive elements infest the crew..."
|
||||
extended_round_description = "Rampant AIs, renegades and changelings spawn in this mode."
|
||||
config_tag = "paranoia"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/datum/game_mode/traitorling
|
||||
name = "traitorling"
|
||||
name = "Traitors & Changelings"
|
||||
round_description = "There are traitors and alien changelings on the station. Do not let the changelings succeed!"
|
||||
extended_round_description = "Traitors and changelings both spawn during this mode."
|
||||
config_tag = "traitorling"
|
||||
|
||||
11
code/game/gamemodes/mixed/traitorrenegade.dm
Normal file
11
code/game/gamemodes/mixed/traitorrenegade.dm
Normal file
@@ -0,0 +1,11 @@
|
||||
/datum/game_mode/traitorren
|
||||
name = "Traitors & Renegades"
|
||||
round_description = "Subversive elements have invaded the station, and certain individuals are feeling uncertain about their safety."
|
||||
extended_round_description = "Traitors and renegades spawn during this round."
|
||||
config_tag = "traitorren"
|
||||
required_players = 10 //I don't think we can have it lower and not need an ERT every round.
|
||||
required_players_secret = 11 //I don't think we can have it lower and not need an ERT every round.
|
||||
required_enemies = 4
|
||||
end_on_antag_death = 0
|
||||
antag_tags = list(MODE_TRAITOR, MODE_RENEGADE)
|
||||
require_all_templates = 1
|
||||
@@ -1,5 +1,5 @@
|
||||
/datum/game_mode/uprising
|
||||
name = "uprising"
|
||||
name = "Revolution & Cult"
|
||||
config_tag = "uprising"
|
||||
round_description = "Some crewmembers are attempting to start a revolution while a cult plots in the shadows!"
|
||||
extended_round_description = "Cultists and revolutionaries spawn in this round."
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
/datum/game_mode/visitors
|
||||
name = "Visitors"
|
||||
name = "Wizard & Ninja"
|
||||
round_description = "A space wizard and a ninja have invaded the station!"
|
||||
extended_round_description = "A ninja and wizard spawn during this round."
|
||||
config_tag = "visitors"
|
||||
required_players = 10
|
||||
required_players_secret = 10
|
||||
required_players = 6
|
||||
required_players_secret = 6
|
||||
required_enemies = 2
|
||||
end_on_antag_death = 0
|
||||
antag_tags = list(MODE_WIZARD, MODE_NINJA)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/datum/game_mode/ninja
|
||||
name = "ninja"
|
||||
name = "Ninja"
|
||||
round_description = "An agent of the Spider Clan is onboard the station!"
|
||||
extended_round_description = "What was that?! Was that a person or did your eyes just play tricks on you? \
|
||||
You have no idea. That slim-suited, cryptic individual is an enigma to you and all of your knowledge. \
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/datum/game_mode/sandbox
|
||||
name = "sandbox"
|
||||
name = "Sandbox"
|
||||
config_tag = "sandbox"
|
||||
required_players = 0
|
||||
votable = 0
|
||||
|
||||
@@ -19,6 +19,7 @@ var/datum/announcement/minor/captain_announcement = new(do_newscast = 1)
|
||||
minimal_player_age = 14
|
||||
economic_modifier = 20
|
||||
|
||||
minimum_character_age = 25
|
||||
ideal_character_age = 70 // Old geezer captains ftw
|
||||
|
||||
|
||||
@@ -67,6 +68,8 @@ var/datum/announcement/minor/captain_announcement = new(do_newscast = 1)
|
||||
req_admin_notify = 1
|
||||
minimal_player_age = 10
|
||||
economic_modifier = 10
|
||||
|
||||
minimum_character_age = 25
|
||||
ideal_character_age = 50
|
||||
|
||||
access = list(access_security, access_sec_doors, access_brig, access_forensics_lockers,
|
||||
|
||||
@@ -188,12 +188,13 @@
|
||||
department = "Civilian"
|
||||
department_flag = CIVILIAN
|
||||
faction = "Station"
|
||||
total_positions = 1
|
||||
spawn_positions = 1
|
||||
total_positions = 2
|
||||
spawn_positions = 2
|
||||
supervisors = "the head of personnel"
|
||||
selection_color = "#dddddd"
|
||||
access = list(access_janitor, access_maint_tunnels)
|
||||
minimal_access = list(access_janitor, access_maint_tunnels)
|
||||
alt_titles = list("Custodian")
|
||||
|
||||
|
||||
equip(var/mob/living/carbon/human/H)
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
req_admin_notify = 1
|
||||
economic_modifier = 10
|
||||
|
||||
minimum_character_age = 25
|
||||
ideal_character_age = 50
|
||||
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
access_chemistry, access_virology, access_cmo, access_surgery, access_RC_announce,
|
||||
access_keycard_auth, access_sec_doors, access_psychiatrist, access_eva, access_external_airlocks, access_maint_tunnels)
|
||||
|
||||
minimum_character_age = 25
|
||||
minimal_player_age = 10
|
||||
ideal_character_age = 50
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
access_research, access_robotics, access_xenobiology, access_ai_upload, access_tech_storage,
|
||||
access_RC_announce, access_keycard_auth, access_tcomsat, access_gateway, access_xenoarch)
|
||||
|
||||
minimum_character_age = 25
|
||||
minimal_player_age = 14
|
||||
ideal_character_age = 50
|
||||
|
||||
@@ -124,7 +125,7 @@
|
||||
if(H.backbag == 3) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel_norm(H), slot_back)
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/roboticist(H), slot_w_uniform)
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/shoes/black(H), slot_shoes)
|
||||
H.equip_to_slot_or_del(new /obj/item/device/pda/roboticist(H), slot_belt)
|
||||
H.equip_to_slot_or_del(new /obj/item/weapon/storage/toolbox/mechanical(H), slot_l_hand)
|
||||
H.equip_to_slot_or_del(new /obj/item/device/pda/roboticist(H), slot_r_store)
|
||||
H.equip_to_slot_or_del(new /obj/item/weapon/storage/belt/utility/full(H), slot_belt)
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/toggle/labcoat(H), slot_wear_suit)
|
||||
return 1
|
||||
return 1
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
access_forensics_lockers, access_morgue, access_maint_tunnels, access_all_personal_lockers,
|
||||
access_research, access_engine, access_mining, access_medical, access_construction, access_mailsorting,
|
||||
access_heads, access_hos, access_RC_announce, access_keycard_auth, access_gateway, access_external_airlocks)
|
||||
minimum_character_age = 25
|
||||
minimal_player_age = 14
|
||||
|
||||
equip(var/mob/living/carbon/human/H)
|
||||
@@ -92,7 +93,7 @@
|
||||
spawn_positions = 2
|
||||
supervisors = "the head of security"
|
||||
selection_color = "#ffeeee"
|
||||
alt_titles = list("Forensic Technician")
|
||||
alt_titles = list("Forensic Technician","Investigator")
|
||||
access = list(access_security, access_sec_doors, access_forensics_lockers, access_morgue, access_maint_tunnels, access_eva, access_external_airlocks)
|
||||
minimal_access = list(access_security, access_sec_doors, access_forensics_lockers, access_morgue, access_maint_tunnels, access_eva, access_external_airlocks)
|
||||
economic_modifier = 5
|
||||
@@ -119,6 +120,7 @@
|
||||
else
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/det_trench(H), slot_wear_suit)
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/head/det(H), slot_head)
|
||||
H.equip_to_slot_or_del(new /obj/item/weapon/storage/briefcase/crimekit(H), slot_r_hand)
|
||||
return 1
|
||||
|
||||
|
||||
|
||||
@@ -111,7 +111,7 @@ var/global/datum/controller/occupations/job_master
|
||||
if(istype(job, GetJob("Assistant"))) // We don't want to give him assistant, that's boring!
|
||||
continue
|
||||
|
||||
if(job in command_positions) //If you want a command position, select it!
|
||||
if(job.title in command_positions) //If you want a command position, select it!
|
||||
continue
|
||||
|
||||
if(jobban_isbanned(player, job.title))
|
||||
@@ -331,7 +331,6 @@ var/global/datum/controller/occupations/job_master
|
||||
var/list/custom_equip_slots = list() //If more than one item takes the same slot, all after the first one spawn in storage.
|
||||
var/list/custom_equip_leftovers = list()
|
||||
if(H.client.prefs.gear && H.client.prefs.gear.len && job.title != "Cyborg" && job.title != "AI")
|
||||
|
||||
for(var/thing in H.client.prefs.gear)
|
||||
var/datum/gear/G = gear_datums[thing]
|
||||
if(G)
|
||||
@@ -353,10 +352,11 @@ var/global/datum/controller/occupations/job_master
|
||||
if(G.slot && !(G.slot in custom_equip_slots))
|
||||
// This is a miserable way to fix the loadout overwrite bug, but the alternative requires
|
||||
// adding an arg to a bunch of different procs. Will look into it after this merge. ~ Z
|
||||
var/metadata = H.client.prefs.gear[G.display_name]
|
||||
if(G.slot == slot_wear_mask || G.slot == slot_wear_suit || G.slot == slot_head)
|
||||
custom_equip_leftovers += thing
|
||||
else if(H.equip_to_slot_or_del(new G.path(H), G.slot))
|
||||
H << "<span class='notice'>Equipping you with [thing]!</span>"
|
||||
else if(H.equip_to_slot_or_del(G.spawn_item(H, metadata), G.slot))
|
||||
H << "<span class='notice'>Equipping you with \the [thing]!</span>"
|
||||
custom_equip_slots.Add(G.slot)
|
||||
else
|
||||
custom_equip_leftovers.Add(thing)
|
||||
@@ -375,8 +375,9 @@ var/global/datum/controller/occupations/job_master
|
||||
if(G.slot in custom_equip_slots)
|
||||
spawn_in_storage += thing
|
||||
else
|
||||
if(H.equip_to_slot_or_del(new G.path(H), G.slot))
|
||||
H << "<span class='notice'>Equipping you with [thing]!</span>"
|
||||
var/metadata = H.client.prefs.gear[G.display_name]
|
||||
if(H.equip_to_slot_or_del(G.spawn_item(H, metadata), G.slot))
|
||||
H << "<span class='notice'>Equipping you with \the [thing]!</span>"
|
||||
custom_equip_slots.Add(G.slot)
|
||||
else
|
||||
spawn_in_storage += thing
|
||||
@@ -439,9 +440,10 @@ var/global/datum/controller/occupations/job_master
|
||||
|
||||
if(!isnull(B))
|
||||
for(var/thing in spawn_in_storage)
|
||||
H << "<span class='notice'>Placing [thing] in your [B]!</span>"
|
||||
H << "<span class='notice'>Placing \the [thing] in your [B.name]!</span>"
|
||||
var/datum/gear/G = gear_datums[thing]
|
||||
new G.path(B)
|
||||
var/metadata = H.client.prefs.gear[G.display_name]
|
||||
G.spawn_item(B, metadata)
|
||||
else
|
||||
H << "<span class='danger'>Failed to locate a storage object on your mob, either you spawned with no arms and no backpack or this is a bug.</span>"
|
||||
|
||||
|
||||
@@ -54,6 +54,7 @@
|
||||
var/wiresexposed = 0 // If it's been screwdrivered open.
|
||||
var/aidisabled = 0
|
||||
var/shorted = 0
|
||||
circuit = /obj/item/weapon/circuitboard/airalarm
|
||||
|
||||
var/datum/wires/alarm/wires
|
||||
|
||||
@@ -61,7 +62,6 @@
|
||||
var/screen = AALARM_SCREEN_MAIN
|
||||
var/area_uid
|
||||
var/area/alarm_area
|
||||
var/buildstage = 2 //2 is built, 1 is building, 0 is frame.
|
||||
|
||||
var/target_temperature = T0C+20
|
||||
var/regulating_temperature = 0
|
||||
@@ -105,23 +105,8 @@
|
||||
wires = null
|
||||
return ..()
|
||||
|
||||
/obj/machinery/alarm/New(var/loc, var/dir, var/building = 0)
|
||||
/obj/machinery/alarm/New()
|
||||
..()
|
||||
|
||||
if(building)
|
||||
if(loc)
|
||||
src.loc = loc
|
||||
|
||||
if(dir)
|
||||
src.set_dir(dir)
|
||||
|
||||
buildstage = 0
|
||||
wiresexposed = 1
|
||||
pixel_x = (dir & 3)? 0 : (dir == 4 ? -24 : 24)
|
||||
pixel_y = (dir & 3)? (dir ==1 ? -24 : 24) : 0
|
||||
update_icon()
|
||||
return
|
||||
|
||||
first_run()
|
||||
|
||||
/obj/machinery/alarm/proc/first_run()
|
||||
@@ -148,7 +133,7 @@
|
||||
elect_master()
|
||||
|
||||
/obj/machinery/alarm/process()
|
||||
if((stat & (NOPOWER|BROKEN)) || shorted || buildstage != 2)
|
||||
if((stat & (NOPOWER|BROKEN)) || shorted)
|
||||
return
|
||||
|
||||
var/turf/simulated/location = loc
|
||||
@@ -605,9 +590,6 @@
|
||||
data["thresholds"] = thresholds
|
||||
|
||||
/obj/machinery/alarm/CanUseTopic(var/mob/user, var/datum/topic_state/state, var/href_list = list())
|
||||
if(buildstage != 2)
|
||||
return STATUS_CLOSE
|
||||
|
||||
if(aidisabled && isAI(user))
|
||||
user << "<span class='warning'>AI control for \the [src] interface has been disabled.</span>"
|
||||
return STATUS_CLOSE
|
||||
@@ -763,73 +745,43 @@
|
||||
|
||||
/obj/machinery/alarm/attackby(obj/item/W as obj, mob/user as mob)
|
||||
src.add_fingerprint(user)
|
||||
if(istype(W, /obj/item/weapon/screwdriver)) // Opening that Air Alarm up.
|
||||
//user << "You pop the Air Alarm's maintence panel open."
|
||||
wiresexposed = !wiresexposed
|
||||
user << "The wires have been [wiresexposed ? "exposed" : "unexposed"]"
|
||||
update_icon()
|
||||
return
|
||||
|
||||
switch(buildstage)
|
||||
if(2)
|
||||
if(istype(W, /obj/item/weapon/screwdriver)) // Opening that Air Alarm up.
|
||||
//user << "You pop the Air Alarm's maintence panel open."
|
||||
wiresexposed = !wiresexposed
|
||||
user << "The wires have been [wiresexposed ? "exposed" : "unexposed"]"
|
||||
update_icon()
|
||||
return
|
||||
if (wiresexposed && istype(W, /obj/item/weapon/wirecutters))
|
||||
user.visible_message("<span class='warning'>[user] has cut the wires inside \the [src]!</span>", "You have cut the wires inside \the [src].")
|
||||
playsound(src.loc, 'sound/items/Wirecutter.ogg', 50, 1)
|
||||
new/obj/item/stack/cable_coil(get_turf(src), 5)
|
||||
var/obj/structure/frame/A = new /obj/structure/frame( src.loc )
|
||||
var/obj/item/weapon/circuitboard/M = new circuit( A )
|
||||
A.frame_type = "airalarm"
|
||||
A.pixel_x = pixel_x
|
||||
A.pixel_y = pixel_y
|
||||
A.set_dir(dir)
|
||||
A.circuit = M
|
||||
A.anchored = 1
|
||||
for (var/obj/C in src)
|
||||
C.forceMove(loc)
|
||||
A.state = 2
|
||||
A.icon_state = "airalarm_2"
|
||||
M.deconstruct(src)
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
if (wiresexposed && istype(W, /obj/item/weapon/wirecutters))
|
||||
user.visible_message("<span class='warning'>[user] has cut the wires inside \the [src]!</span>", "You have cut the wires inside \the [src].")
|
||||
playsound(src.loc, 'sound/items/Wirecutter.ogg', 50, 1)
|
||||
new/obj/item/stack/cable_coil(get_turf(src), 5)
|
||||
buildstage = 1
|
||||
update_icon()
|
||||
return
|
||||
|
||||
if (istype(W, /obj/item/weapon/card/id) || istype(W, /obj/item/device/pda))// trying to unlock the interface with an ID card
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
user << "It does nothing"
|
||||
return
|
||||
else
|
||||
if(allowed(usr) && !wires.IsIndexCut(AALARM_WIRE_IDSCAN))
|
||||
locked = !locked
|
||||
user << "<span class='notice'>You [ locked ? "lock" : "unlock"] the Air Alarm interface.</span>"
|
||||
else
|
||||
user << "<span class='warning'>Access denied.</span>"
|
||||
if (istype(W, /obj/item/weapon/card/id) || istype(W, /obj/item/device/pda))// trying to unlock the interface with an ID card
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
user << "It does nothing"
|
||||
return
|
||||
|
||||
if(1)
|
||||
if(istype(W, /obj/item/stack/cable_coil))
|
||||
var/obj/item/stack/cable_coil/C = W
|
||||
if (C.use(5))
|
||||
user << "<span class='notice'>You wire \the [src].</span>"
|
||||
buildstage = 2
|
||||
update_icon()
|
||||
first_run()
|
||||
return
|
||||
else
|
||||
user << "<span class='warning'>You need 5 pieces of cable to do wire \the [src].</span>"
|
||||
return
|
||||
|
||||
else if(istype(W, /obj/item/weapon/crowbar))
|
||||
user << "You start prying out the circuit."
|
||||
playsound(src.loc, 'sound/items/Crowbar.ogg', 50, 1)
|
||||
if(do_after(user,20))
|
||||
user << "You pry out the circuit!"
|
||||
var/obj/item/weapon/airalarm_electronics/circuit = new /obj/item/weapon/airalarm_electronics()
|
||||
circuit.loc = user.loc
|
||||
buildstage = 0
|
||||
update_icon()
|
||||
return
|
||||
if(0)
|
||||
if(istype(W, /obj/item/weapon/airalarm_electronics))
|
||||
user << "You insert the circuit!"
|
||||
qdel(W)
|
||||
buildstage = 1
|
||||
update_icon()
|
||||
return
|
||||
|
||||
else if(istype(W, /obj/item/weapon/wrench))
|
||||
user << "You remove the fire alarm assembly from the wall!"
|
||||
new /obj/item/frame/air_alarm(get_turf(user))
|
||||
playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1)
|
||||
qdel(src)
|
||||
|
||||
else
|
||||
if(allowed(usr) && !wires.IsIndexCut(AALARM_WIRE_IDSCAN))
|
||||
locked = !locked
|
||||
user << "<span class='notice'>You [ locked ? "lock" : "unlock"] the Air Alarm interface.</span>"
|
||||
else
|
||||
user << "<span class='warning'>Access denied.</span>"
|
||||
return ..()
|
||||
|
||||
/obj/machinery/alarm/power_change()
|
||||
@@ -839,14 +791,10 @@
|
||||
|
||||
/obj/machinery/alarm/examine(mob/user)
|
||||
..(user)
|
||||
if (buildstage < 2)
|
||||
user << "It is not wired."
|
||||
if (buildstage < 1)
|
||||
user << "The circuit is missing."
|
||||
/*
|
||||
AIR ALARM CIRCUIT
|
||||
Just a object used in constructing air alarms
|
||||
*/
|
||||
|
||||
/obj/item/weapon/airalarm_electronics
|
||||
name = "air alarm electronics"
|
||||
icon = 'icons/obj/doors/door_assembly.dmi'
|
||||
@@ -854,7 +802,7 @@ Just a object used in constructing air alarms
|
||||
desc = "Looks like a circuit. Probably is."
|
||||
w_class = 2.0
|
||||
matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50)
|
||||
|
||||
*/
|
||||
/*
|
||||
FIRE ALARM
|
||||
*/
|
||||
@@ -875,20 +823,13 @@ FIRE ALARM
|
||||
power_channel = ENVIRON
|
||||
var/last_process = 0
|
||||
var/wiresexposed = 0
|
||||
var/buildstage = 2 // 2 = complete, 1 = no wires, 0 = circuit gone
|
||||
var/seclevel
|
||||
circuit = /obj/item/weapon/circuitboard/firealarm
|
||||
|
||||
/obj/machinery/firealarm/update_icon()
|
||||
overlays.Cut()
|
||||
|
||||
if(wiresexposed)
|
||||
switch(buildstage)
|
||||
if(2)
|
||||
icon_state="fire_b2"
|
||||
if(1)
|
||||
icon_state="fire_b1"
|
||||
if(0)
|
||||
icon_state="fire_b0"
|
||||
set_light(0)
|
||||
return
|
||||
|
||||
@@ -932,56 +873,36 @@ FIRE ALARM
|
||||
/obj/machinery/firealarm/attackby(obj/item/W as obj, mob/user as mob)
|
||||
src.add_fingerprint(user)
|
||||
|
||||
if (istype(W, /obj/item/weapon/screwdriver) && buildstage == 2)
|
||||
if (istype(W, /obj/item/weapon/screwdriver))
|
||||
wiresexposed = !wiresexposed
|
||||
update_icon()
|
||||
return
|
||||
|
||||
if(wiresexposed)
|
||||
switch(buildstage)
|
||||
if(2)
|
||||
if (istype(W, /obj/item/device/multitool))
|
||||
src.detecting = !( src.detecting )
|
||||
if (src.detecting)
|
||||
user.visible_message("<span class='notice'>\The [user] has reconnected [src]'s detecting unit!</span>", "<span class='notice'>You have reconnected [src]'s detecting unit.</span>")
|
||||
else
|
||||
user.visible_message("<span class='notice'>\The [user] has disconnected [src]'s detecting unit!</span>", "<span class='notice'>You have disconnected [src]'s detecting unit.</span>")
|
||||
else if (istype(W, /obj/item/weapon/wirecutters))
|
||||
user.visible_message("<span class='notice'>\The [user] has cut the wires inside \the [src]!</span>", "<span class='notice'>You have cut the wires inside \the [src].</span>")
|
||||
new/obj/item/stack/cable_coil(get_turf(src), 5)
|
||||
playsound(src.loc, 'sound/items/Wirecutter.ogg', 50, 1)
|
||||
buildstage = 1
|
||||
update_icon()
|
||||
if(1)
|
||||
if(istype(W, /obj/item/stack/cable_coil))
|
||||
var/obj/item/stack/cable_coil/C = W
|
||||
if (C.use(5))
|
||||
user << "<span class='notice'>You wire \the [src].</span>"
|
||||
buildstage = 2
|
||||
return
|
||||
else
|
||||
user << "<span class='warning'>You need 5 pieces of cable to wire \the [src].</span>"
|
||||
return
|
||||
else if(istype(W, /obj/item/weapon/crowbar))
|
||||
user << "You pry out the circuit!"
|
||||
playsound(src.loc, 'sound/items/Crowbar.ogg', 50, 1)
|
||||
spawn(20)
|
||||
var/obj/item/weapon/firealarm_electronics/circuit = new /obj/item/weapon/firealarm_electronics()
|
||||
circuit.loc = user.loc
|
||||
buildstage = 0
|
||||
update_icon()
|
||||
if(0)
|
||||
if(istype(W, /obj/item/weapon/firealarm_electronics))
|
||||
user << "You insert the circuit!"
|
||||
qdel(W)
|
||||
buildstage = 1
|
||||
update_icon()
|
||||
|
||||
else if(istype(W, /obj/item/weapon/wrench))
|
||||
user << "You remove the fire alarm assembly from the wall!"
|
||||
new /obj/item/frame/fire_alarm(get_turf(user))
|
||||
playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1)
|
||||
qdel(src)
|
||||
if (istype(W, /obj/item/device/multitool))
|
||||
src.detecting = !( src.detecting )
|
||||
if (src.detecting)
|
||||
user.visible_message("<span class='notice'>\The [user] has reconnected [src]'s detecting unit!</span>", "<span class='notice'>You have reconnected [src]'s detecting unit.</span>")
|
||||
else
|
||||
user.visible_message("<span class='notice'>\The [user] has disconnected [src]'s detecting unit!</span>", "<span class='notice'>You have disconnected [src]'s detecting unit.</span>")
|
||||
else if (istype(W, /obj/item/weapon/wirecutters))
|
||||
user.visible_message("<span class='notice'>\The [user] has cut the wires inside \the [src]!</span>", "<span class='notice'>You have cut the wires inside \the [src].</span>")
|
||||
new/obj/item/stack/cable_coil(get_turf(src), 5)
|
||||
playsound(src.loc, 'sound/items/Wirecutter.ogg', 50, 1)
|
||||
var/obj/structure/frame/A = new /obj/structure/frame( src.loc )
|
||||
var/obj/item/weapon/circuitboard/M = new circuit( A )
|
||||
A.frame_type = "firealarm"
|
||||
A.pixel_x = pixel_x
|
||||
A.pixel_y = pixel_y
|
||||
A.set_dir(dir)
|
||||
A.circuit = M
|
||||
A.anchored = 1
|
||||
for (var/obj/C in src)
|
||||
C.forceMove(loc)
|
||||
A.state = 2
|
||||
A.icon_state = "firealarm_2"
|
||||
M.deconstruct(src)
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
src.alarm()
|
||||
@@ -1016,9 +937,6 @@ FIRE ALARM
|
||||
if(user.stat || stat & (NOPOWER|BROKEN))
|
||||
return
|
||||
|
||||
if (buildstage != 2)
|
||||
return
|
||||
|
||||
user.set_machine(src)
|
||||
var/area/A = src.loc
|
||||
var/d1
|
||||
@@ -1061,9 +979,6 @@ FIRE ALARM
|
||||
if (usr.stat || stat & (BROKEN|NOPOWER))
|
||||
return
|
||||
|
||||
if (buildstage != 2)
|
||||
return
|
||||
|
||||
if ((usr.contents.Find(src) || ((get_dist(src, usr) <= 1) && istype(src.loc, /turf))) || (istype(usr, /mob/living/silicon)))
|
||||
usr.set_machine(src)
|
||||
if (href_list["reset"])
|
||||
@@ -1106,23 +1021,6 @@ FIRE ALARM
|
||||
//playsound(src.loc, 'sound/ambience/signal.ogg', 75, 0)
|
||||
return
|
||||
|
||||
|
||||
|
||||
/obj/machinery/firealarm/New(loc, dir, building)
|
||||
..()
|
||||
|
||||
if(loc)
|
||||
src.loc = loc
|
||||
|
||||
if(dir)
|
||||
src.set_dir(dir)
|
||||
|
||||
if(building)
|
||||
buildstage = 0
|
||||
wiresexposed = 1
|
||||
pixel_x = (dir & 3)? 0 : (dir == 4 ? -24 : 24)
|
||||
pixel_y = (dir & 3)? (dir ==1 ? -24 : 24) : 0
|
||||
|
||||
/obj/machinery/firealarm/proc/set_security_level(var/newlevel)
|
||||
if(seclevel != newlevel)
|
||||
seclevel = newlevel
|
||||
@@ -1135,7 +1033,7 @@ FIRE ALARM
|
||||
/*
|
||||
FIRE ALARM CIRCUIT
|
||||
Just a object used in constructing fire alarms
|
||||
*/
|
||||
|
||||
/obj/item/weapon/firealarm_electronics
|
||||
name = "fire alarm electronics"
|
||||
icon = 'icons/obj/doors/door_assembly.dmi'
|
||||
@@ -1143,7 +1041,7 @@ Just a object used in constructing fire alarms
|
||||
desc = "A circuit. It has a label on it, it says \"Can handle heat levels up to 40 degrees celsius!\""
|
||||
w_class = 2.0
|
||||
matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50)
|
||||
|
||||
*/
|
||||
/obj/machinery/partyalarm
|
||||
name = "\improper PARTY BUTTON"
|
||||
desc = "Cuban Pete is in the house!"
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
use_power = 1
|
||||
idle_power_usage = 10
|
||||
active_power_usage = 2000
|
||||
|
||||
circuit = /obj/item/weapon/circuitboard/autolathe
|
||||
var/list/machine_recipes
|
||||
var/list/stored_material = list(DEFAULT_WALL_MATERIAL = 0, "glass" = 0)
|
||||
var/list/storage_capacity = list(DEFAULT_WALL_MATERIAL = 0, "glass" = 0)
|
||||
@@ -30,14 +30,13 @@
|
||||
wires = new(src)
|
||||
//Create parts for lathe.
|
||||
component_parts = list()
|
||||
component_parts += new /obj/item/weapon/circuitboard/autolathe(src)
|
||||
component_parts += new /obj/item/weapon/stock_parts/matter_bin(src)
|
||||
component_parts += new /obj/item/weapon/stock_parts/matter_bin(src)
|
||||
component_parts += new /obj/item/weapon/stock_parts/matter_bin(src)
|
||||
component_parts += new /obj/item/weapon/stock_parts/manipulator(src)
|
||||
component_parts += new /obj/item/weapon/stock_parts/console_screen(src)
|
||||
RefreshParts()
|
||||
|
||||
|
||||
/obj/machinery/autolathe/Destroy()
|
||||
qdel(wires)
|
||||
wires = null
|
||||
|
||||
@@ -158,12 +158,12 @@
|
||||
|
||||
/datum/autolathe/recipe/airalarm
|
||||
name = "air alarm electronics"
|
||||
path = /obj/item/weapon/airalarm_electronics
|
||||
path = /obj/item/weapon/circuitboard/airalarm
|
||||
category = "Engineering"
|
||||
|
||||
/datum/autolathe/recipe/firealarm
|
||||
name = "fire alarm electronics"
|
||||
path = /obj/item/weapon/firealarm_electronics
|
||||
path = /obj/item/weapon/circuitboard/firealarm
|
||||
category = "Engineering"
|
||||
|
||||
/datum/autolathe/recipe/powermodule
|
||||
@@ -171,6 +171,96 @@
|
||||
path = /obj/item/weapon/module/power_control
|
||||
category = "Engineering"
|
||||
|
||||
/datum/autolathe/recipe/statusdisplay
|
||||
name = "status display electronics"
|
||||
path = /obj/item/weapon/circuitboard/status_display
|
||||
category = "Engineering"
|
||||
|
||||
/datum/autolathe/recipe/aistatusdisplay
|
||||
name = "ai status display electronics"
|
||||
path = /obj/item/weapon/circuitboard/ai_status_display
|
||||
category = "Engineering"
|
||||
|
||||
/datum/autolathe/recipe/newscaster
|
||||
name = "newscaster electronics"
|
||||
path = /obj/item/weapon/circuitboard/newscaster
|
||||
category = "Engineering"
|
||||
|
||||
/datum/autolathe/recipe/atm
|
||||
name = "atm electronics"
|
||||
path = /obj/item/weapon/circuitboard/atm
|
||||
category = "Engineering"
|
||||
|
||||
/datum/autolathe/recipe/intercom
|
||||
name = "intercom electronics"
|
||||
path = /obj/item/weapon/circuitboard/intercom
|
||||
category = "Engineering"
|
||||
|
||||
/datum/autolathe/recipe/holopad
|
||||
name = "holopad electronics"
|
||||
path = /obj/item/weapon/circuitboard/holopad
|
||||
category = "Engineering"
|
||||
|
||||
/datum/autolathe/recipe/guestpass
|
||||
name = "guestpass console electronics"
|
||||
path = /obj/item/weapon/circuitboard/guestpass
|
||||
category = "Engineering"
|
||||
|
||||
/datum/autolathe/recipe/entertainment
|
||||
name = "entertainment camera electronics"
|
||||
path = /obj/item/weapon/circuitboard/security/telescreen/entertainment
|
||||
category = "Engineering"
|
||||
|
||||
/datum/autolathe/recipe/keycard
|
||||
name = "keycard authenticator electronics"
|
||||
path = /obj/item/weapon/circuitboard/keycard_auth
|
||||
category = "Engineering"
|
||||
|
||||
/datum/autolathe/recipe/photocopier
|
||||
name = "photocopier electronics"
|
||||
path = /obj/item/weapon/circuitboard/photocopier
|
||||
category = "Engineering"
|
||||
|
||||
/datum/autolathe/recipe/fax
|
||||
name = "fax machine electronics"
|
||||
path = /obj/item/weapon/circuitboard/fax
|
||||
category = "Engineering"
|
||||
|
||||
/datum/autolathe/recipe/conveyor
|
||||
name = "conveyor electronics"
|
||||
path = /obj/item/weapon/circuitboard/conveyor
|
||||
category = "Engineering"
|
||||
|
||||
/datum/autolathe/recipe/microwave
|
||||
name = "microwave electronics"
|
||||
path = /obj/item/weapon/circuitboard/microwave
|
||||
category = "Engineering"
|
||||
|
||||
/datum/autolathe/recipe/vending
|
||||
name = "vending machine electronics"
|
||||
path = /obj/item/weapon/circuitboard/vending
|
||||
category = "Engineering"
|
||||
|
||||
/datum/autolathe/recipe/washing
|
||||
name = "washing machine electronics"
|
||||
path = /obj/item/weapon/circuitboard/washing
|
||||
category = "Engineering"
|
||||
|
||||
/datum/autolathe/recipe/motor
|
||||
name = "motor"
|
||||
path = /obj/item/weapon/stock_parts/motor
|
||||
category = "Engineering"
|
||||
|
||||
/datum/autolathe/recipe/gear
|
||||
name = "gear"
|
||||
path = /obj/item/weapon/stock_parts/gear
|
||||
category = "Engineering"
|
||||
|
||||
/datum/autolathe/recipe/spring
|
||||
name = "spring"
|
||||
path = /obj/item/weapon/stock_parts/spring
|
||||
category = "Engineering"
|
||||
|
||||
/datum/autolathe/recipe/rcd_ammo
|
||||
name = "matter cartridge"
|
||||
path = /obj/item/weapon/rcd_ammo
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
icon_state = "biogen-stand"
|
||||
density = 1
|
||||
anchored = 1
|
||||
circuit = /obj/item/weapon/circuitboard/biogenerator
|
||||
use_power = 1
|
||||
idle_power_usage = 40
|
||||
var/processing = 0
|
||||
@@ -23,7 +24,6 @@
|
||||
beaker = new /obj/item/weapon/reagent_containers/glass/bottle(src)
|
||||
|
||||
component_parts = list()
|
||||
component_parts += new /obj/item/weapon/circuitboard/biogenerator(src)
|
||||
component_parts += new /obj/item/weapon/stock_parts/matter_bin(src)
|
||||
component_parts += new /obj/item/weapon/stock_parts/manipulator(src)
|
||||
|
||||
@@ -106,9 +106,9 @@
|
||||
dat += "<A href='?src=\ref[src];action=create;item=milk;cost=20'>10 milk</A> <FONT COLOR=blue>([round(20/build_eff)])</FONT><BR>"
|
||||
dat += "<A href='?src=\ref[src];action=create;item=meat;cost=50'>Slab of meat</A> <FONT COLOR=blue>([round(50/build_eff)])</FONT><BR>"
|
||||
dat += "Nutrient<BR>"
|
||||
dat += "<A href='?src=\ref[src];action=create;item=ez;cost=10'>E-Z-Nutrient</A> <FONT COLOR=blue>([round(10/build_eff)])</FONT> | <A href='?src=\ref[src];action=create;item=ez5;cost=50'>x5</A><BR>"
|
||||
dat += "<A href='?src=\ref[src];action=create;item=l4z;cost=20'>Left 4 Zed</A> <FONT COLOR=blue>([round(20/build_eff)])</FONT> | <A href='?src=\ref[src];action=create;item=l4z5;cost=100'>x5</A><BR>"
|
||||
dat += "<A href='?src=\ref[src];action=create;item=rh;cost=25'>Robust Harvest</A> <FONT COLOR=blue>([round(25/build_eff)])</FONT> | <A href='?src=\ref[src];action=create;item=rh5;cost=125'>x5</A><BR>"
|
||||
dat += "<A href='?src=\ref[src];action=create;item=ez;cost=60'>E-Z-Nutrient</A> <FONT COLOR=blue>([round(10/build_eff)])</FONT> | <A href='?src=\ref[src];action=create;item=ez5;cost=300'>x5</A><BR>"
|
||||
dat += "<A href='?src=\ref[src];action=create;item=l4z;cost=120'>Left 4 Zed</A> <FONT COLOR=blue>([round(20/build_eff)])</FONT> | <A href='?src=\ref[src];action=create;item=l4z5;cost=600'>x5</A><BR>"
|
||||
dat += "<A href='?src=\ref[src];action=create;item=rh;cost=150'>Robust Harvest</A> <FONT COLOR=blue>([round(25/build_eff)])</FONT> | <A href='?src=\ref[src];action=create;item=rh5;cost=750'>x5</A><BR>"
|
||||
dat += "Leather<BR>"
|
||||
dat += "<A href='?src=\ref[src];action=create;item=wallet;cost=100'>Wallet</A> <FONT COLOR=blue>([round(100/build_eff)])</FONT><BR>"
|
||||
dat += "<A href='?src=\ref[src];action=create;item=gloves;cost=250'>Botanical gloves</A> <FONT COLOR=blue>([round(250/build_eff)])</FONT><BR>"
|
||||
@@ -179,29 +179,29 @@
|
||||
if("meat")
|
||||
new/obj/item/weapon/reagent_containers/food/snacks/meat(loc)
|
||||
if("ez")
|
||||
new/obj/item/weapon/reagent_containers/glass/fertilizer/ez(loc)
|
||||
new/obj/item/weapon/reagent_containers/glass/bottle/eznutrient(loc)
|
||||
if("l4z")
|
||||
new/obj/item/weapon/reagent_containers/glass/fertilizer/l4z(loc)
|
||||
new/obj/item/weapon/reagent_containers/glass/bottle/left4zed(loc)
|
||||
if("rh")
|
||||
new/obj/item/weapon/reagent_containers/glass/fertilizer/rh(loc)
|
||||
new/obj/item/weapon/reagent_containers/glass/bottle/robustharvest(loc)
|
||||
if("ez5") //It's not an elegant method, but it's safe and easy. -Cheridan
|
||||
new/obj/item/weapon/reagent_containers/glass/fertilizer/ez(loc)
|
||||
new/obj/item/weapon/reagent_containers/glass/fertilizer/ez(loc)
|
||||
new/obj/item/weapon/reagent_containers/glass/fertilizer/ez(loc)
|
||||
new/obj/item/weapon/reagent_containers/glass/fertilizer/ez(loc)
|
||||
new/obj/item/weapon/reagent_containers/glass/fertilizer/ez(loc)
|
||||
new/obj/item/weapon/reagent_containers/glass/bottle/eznutrient(loc)
|
||||
new/obj/item/weapon/reagent_containers/glass/bottle/eznutrient(loc)
|
||||
new/obj/item/weapon/reagent_containers/glass/bottle/eznutrient(loc)
|
||||
new/obj/item/weapon/reagent_containers/glass/bottle/eznutrient(loc)
|
||||
new/obj/item/weapon/reagent_containers/glass/bottle/eznutrient(loc)
|
||||
if("l4z5")
|
||||
new/obj/item/weapon/reagent_containers/glass/fertilizer/l4z(loc)
|
||||
new/obj/item/weapon/reagent_containers/glass/fertilizer/l4z(loc)
|
||||
new/obj/item/weapon/reagent_containers/glass/fertilizer/l4z(loc)
|
||||
new/obj/item/weapon/reagent_containers/glass/fertilizer/l4z(loc)
|
||||
new/obj/item/weapon/reagent_containers/glass/fertilizer/l4z(loc)
|
||||
new/obj/item/weapon/reagent_containers/glass/bottle/left4zed(loc)
|
||||
new/obj/item/weapon/reagent_containers/glass/bottle/left4zed(loc)
|
||||
new/obj/item/weapon/reagent_containers/glass/bottle/left4zed(loc)
|
||||
new/obj/item/weapon/reagent_containers/glass/bottle/left4zed(loc)
|
||||
new/obj/item/weapon/reagent_containers/glass/bottle/left4zed(loc)
|
||||
if("rh5")
|
||||
new/obj/item/weapon/reagent_containers/glass/fertilizer/rh(loc)
|
||||
new/obj/item/weapon/reagent_containers/glass/fertilizer/rh(loc)
|
||||
new/obj/item/weapon/reagent_containers/glass/fertilizer/rh(loc)
|
||||
new/obj/item/weapon/reagent_containers/glass/fertilizer/rh(loc)
|
||||
new/obj/item/weapon/reagent_containers/glass/fertilizer/rh(loc)
|
||||
new/obj/item/weapon/reagent_containers/glass/bottle/robustharvest(loc)
|
||||
new/obj/item/weapon/reagent_containers/glass/bottle/robustharvest(loc)
|
||||
new/obj/item/weapon/reagent_containers/glass/bottle/robustharvest(loc)
|
||||
new/obj/item/weapon/reagent_containers/glass/bottle/robustharvest(loc)
|
||||
new/obj/item/weapon/reagent_containers/glass/bottle/robustharvest(loc)
|
||||
if("wallet")
|
||||
new/obj/item/weapon/storage/wallet(loc)
|
||||
if("gloves")
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
desc = "An electronically-lockable pod for growing organic tissue."
|
||||
density = 1
|
||||
anchored = 1
|
||||
circuit = /obj/item/weapon/circuitboard/clonepod
|
||||
icon = 'icons/obj/cloning.dmi'
|
||||
icon_state = "pod_0"
|
||||
req_access = list(access_genetics) //For premature unlocking.
|
||||
@@ -47,7 +48,6 @@
|
||||
/obj/machinery/clonepod/New()
|
||||
..()
|
||||
component_parts = list()
|
||||
component_parts += new /obj/item/weapon/circuitboard/clonepod(src)
|
||||
component_parts += new /obj/item/weapon/stock_parts/manipulator(src)
|
||||
component_parts += new /obj/item/weapon/stock_parts/manipulator(src)
|
||||
component_parts += new /obj/item/weapon/stock_parts/scanning_module(src)
|
||||
|
||||
@@ -393,14 +393,14 @@
|
||||
dat += "<br>You ran out of food and starved."
|
||||
if(emagged)
|
||||
user.nutrition = 0 //yeah you pretty hongry
|
||||
user << "<span class='danger'><font size=3>Your body instantly contracts to that of one who has not eaten in months. Agonizing cramps seize you as you fall to the floor.</span>"
|
||||
user << "<span class='danger'><font size=3>Your body instantly contracts to that of one who has not eaten in months. Agonizing cramps seize you as you fall to the floor.</font></span>"
|
||||
if(fuel <= 0)
|
||||
dat += "<br>You ran out of fuel, and drift, slowly, into a star."
|
||||
if(emagged)
|
||||
var/mob/living/M = user
|
||||
M.adjust_fire_stacks(5)
|
||||
M.IgniteMob() //flew into a star, so you're on fire
|
||||
user << "<span class='danger'><font size=3>You feel an immense wave of heat emanate from \the [src]. Your skin bursts into flames.</span>"
|
||||
user << "<span class='danger'><font size=3>You feel an immense wave of heat emanate from \the [src]. Your skin bursts into flames.</font></span>"
|
||||
dat += "<br><P ALIGN=Right><a href='byond://?src=\ref[src];menu=1'>OK...</a></P>"
|
||||
|
||||
if(emagged)
|
||||
|
||||
@@ -215,7 +215,8 @@
|
||||
icon_screen = "entertainment"
|
||||
light_color = "#FFEEDB"
|
||||
light_range_on = 2
|
||||
circuit = null
|
||||
network = list(NETWORK_THUNDER)
|
||||
circuit = /obj/item/weapon/circuitboard/security/telescreen/entertainment
|
||||
/obj/machinery/computer/security/wooden_tv
|
||||
name = "security camera monitor"
|
||||
desc = "An old TV hooked into the stations camera network."
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
use_power = 1
|
||||
idle_power_usage = 300
|
||||
active_power_usage = 300
|
||||
var/circuit = null //The path to the circuit board type. If circuit==null, the computer can't be disassembled.
|
||||
frame_type = "computer"
|
||||
var/processing = 0
|
||||
|
||||
var/icon_keyboard = "generic_key"
|
||||
@@ -98,23 +98,28 @@
|
||||
|
||||
/obj/machinery/computer/attackby(I as obj, user as mob)
|
||||
if(istype(I, /obj/item/weapon/screwdriver) && circuit)
|
||||
user << "<span class='notice'>You start disconnecting the monitor.</span>"
|
||||
playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1)
|
||||
if(do_after(user, 20))
|
||||
var/obj/structure/computerframe/A = new /obj/structure/computerframe( src.loc )
|
||||
var/obj/structure/frame/A = new /obj/structure/frame( src.loc )
|
||||
var/obj/item/weapon/circuitboard/M = new circuit( A )
|
||||
A.circuit = M
|
||||
A.anchored = 1
|
||||
A.density = 1
|
||||
A.frame_type = M.board_type
|
||||
for (var/obj/C in src)
|
||||
C.loc = src.loc
|
||||
C.forceMove(loc)
|
||||
if (src.stat & BROKEN)
|
||||
user << "<span class='notice'>The broken glass falls out.</span>"
|
||||
new /obj/item/weapon/material/shard( src.loc )
|
||||
A.state = 3
|
||||
A.icon_state = "3"
|
||||
A.icon_state = "[A.frame_type]_3"
|
||||
else
|
||||
user << "<span class='notice'>You disconnect the monitor.</span>"
|
||||
A.state = 4
|
||||
A.icon_state = "4"
|
||||
A.icon_state = "[A.frame_type]_4"
|
||||
A.pixel_x = pixel_x
|
||||
A.pixel_y = pixel_y
|
||||
M.deconstruct(src)
|
||||
qdel(src)
|
||||
else
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
icon_keyboard = null
|
||||
icon_screen = "pass"
|
||||
density = 0
|
||||
circuit = /obj/item/weapon/circuitboard/guestpass
|
||||
|
||||
var/obj/item/weapon/card/id/giver
|
||||
var/list/accesses = list()
|
||||
@@ -60,10 +61,29 @@
|
||||
..()
|
||||
uid = "[rand(100,999)]-G[rand(10,99)]"
|
||||
|
||||
/obj/machinery/computer/guestpass/attackby(obj/O, mob/user)
|
||||
if(istype(O, /obj/item/weapon/card/id))
|
||||
if(!giver && user.removeItem(O, src))
|
||||
giver = O
|
||||
/obj/machinery/computer/guestpass/attackby(obj/I, mob/user)
|
||||
if(istype(I, /obj/item/weapon/screwdriver) && circuit)
|
||||
user << "<span class='notice'>You start disconnecting the monitor.</span>"
|
||||
playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1)
|
||||
if(do_after(user, 20))
|
||||
var/obj/structure/frame/A = new /obj/structure/frame( src.loc )
|
||||
var/obj/item/weapon/circuitboard/M = new circuit( A )
|
||||
A.frame_type = "guestpass"
|
||||
A.pixel_x = pixel_x
|
||||
A.pixel_y = pixel_y
|
||||
A.circuit = M
|
||||
A.anchored = 1
|
||||
for (var/obj/C in src)
|
||||
C.forceMove(loc)
|
||||
user << "<span class='notice'>You disconnect the monitor.</span>"
|
||||
A.state = 4
|
||||
A.icon_state = "guestpass_4"
|
||||
M.deconstruct(src)
|
||||
qdel(src)
|
||||
return
|
||||
if(istype(I, /obj/item/weapon/card/id))
|
||||
if(!giver && user.removeItem(I, src))
|
||||
giver = I
|
||||
updateUsrDialog()
|
||||
else if(giver)
|
||||
user << "<span class='warning'>There is already ID card inside.</span>"
|
||||
@@ -134,8 +154,12 @@
|
||||
var/A = text2num(href_list["access"])
|
||||
if (A in accesses)
|
||||
accesses.Remove(A)
|
||||
else
|
||||
accesses.Add(A)
|
||||
else
|
||||
if(A in giver.access) //Let's make sure the ID card actually has the access.
|
||||
accesses.Add(A)
|
||||
else
|
||||
usr << "<span class='warning'>Invalid selection, please consult technical support if there are any issues.</span>"
|
||||
log_debug("[key_name_admin(usr)] tried selecting an invalid guest pass terminal option.")
|
||||
if (href_list["action"])
|
||||
switch(href_list["action"])
|
||||
if ("id")
|
||||
|
||||
@@ -26,32 +26,6 @@ var/prison_shuttle_timeleft = 0
|
||||
attack_ai(var/mob/user as mob)
|
||||
return src.attack_hand(user)
|
||||
|
||||
attackby(I as obj, user as mob)
|
||||
if(istype(I, /obj/item/weapon/screwdriver))
|
||||
playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1)
|
||||
if(do_after(user, 20))
|
||||
var/obj/structure/computerframe/A = new /obj/structure/computerframe( src.loc )
|
||||
var/obj/item/weapon/circuitboard/prison_shuttle/M = new /obj/item/weapon/circuitboard/prison_shuttle( A )
|
||||
for (var/obj/C in src)
|
||||
C.loc = src.loc
|
||||
A.circuit = M
|
||||
A.anchored = 1
|
||||
|
||||
if (src.stat & BROKEN)
|
||||
user << "<span class='notice'>The broken glass falls out.</span>"
|
||||
new /obj/item/weapon/material/shard( src.loc )
|
||||
A.state = 3
|
||||
A.icon_state = "3"
|
||||
else
|
||||
user << "<span class='notice'>You disconnect the monitor.</span>"
|
||||
A.state = 4
|
||||
A.icon_state = "4"
|
||||
|
||||
qdel(src)
|
||||
else
|
||||
return src.attack_hand(user)
|
||||
|
||||
|
||||
attack_hand(var/mob/user as mob)
|
||||
if(!src.allowed(user) && (!hacked))
|
||||
user << "<span class='warning'>Access Denied.</span>"
|
||||
|
||||
@@ -91,7 +91,7 @@
|
||||
if(!target || !istype(target))
|
||||
return
|
||||
|
||||
var/istraitor = traitors.is_antagonist(target.mind)
|
||||
var/istraitor = target.mind.special_role
|
||||
if (istraitor)
|
||||
target.lockcharge = !target.lockcharge
|
||||
if (target.lockcharge)
|
||||
@@ -187,7 +187,7 @@
|
||||
robot["name"] = R.name
|
||||
if(R.stat)
|
||||
robot["status"] = "Not Responding"
|
||||
else if (!R.canmove)
|
||||
else if (R.lockcharge)
|
||||
robot["status"] = "Lockdown"
|
||||
else
|
||||
robot["status"] = "Operational"
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
// when you had to search the list to find what you had.
|
||||
|
||||
// Mostly decorative, holds the OS rom
|
||||
var/obj/item/part/computer/circuitboard/circuit
|
||||
var/obj/item/part/computer/circuitboard/circuitb
|
||||
|
||||
// Storage
|
||||
var/obj/item/part/computer/storage/hdd/hdd = null
|
||||
@@ -97,11 +97,11 @@
|
||||
overlays += kb
|
||||
|
||||
if(!built)
|
||||
if(!circuit || !istype(circuit))
|
||||
circuit = new(src)
|
||||
if(circuit.OS)
|
||||
os = circuit.OS
|
||||
circuit.OS.computer = src
|
||||
if(!circuitb || !istype(circuitb))
|
||||
circuitb = new(src)
|
||||
if(circuitb.OS)
|
||||
os = circuitb.OS
|
||||
circuitb.OS.computer = src
|
||||
else
|
||||
os = null
|
||||
|
||||
@@ -121,10 +121,10 @@
|
||||
floppy.addfile(P)
|
||||
program = P
|
||||
else
|
||||
circuit.OS = P
|
||||
circuit.OS.computer = src
|
||||
os = circuit.OS
|
||||
circuit.name = "Circuitboard ([P])"
|
||||
circuitb.OS = P
|
||||
circuitb.OS.computer = src
|
||||
os = circuitb.OS
|
||||
circuitb.name = "Circuitboard ([P])"
|
||||
|
||||
|
||||
if(hdd) // Spawn files
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
New()
|
||||
..(built=0)
|
||||
os = program
|
||||
circuit.OS = os
|
||||
circuitb.OS = os
|
||||
|
||||
|
||||
/obj/machinery/computer3/security/mining
|
||||
|
||||
@@ -63,10 +63,9 @@
|
||||
return 1
|
||||
|
||||
/obj/machinery/atmospherics/unary/cryo_cell/relaymove(mob/user as mob)
|
||||
if(user.stat)
|
||||
return
|
||||
go_out()
|
||||
return
|
||||
// note that relaymove will also be called for mobs outside the cell with UI open
|
||||
if(src.occupant == user && !user.stat)
|
||||
go_out()
|
||||
|
||||
/obj/machinery/atmospherics/unary/cryo_cell/attack_hand(mob/user)
|
||||
ui_interact(user)
|
||||
|
||||
@@ -219,7 +219,7 @@
|
||||
var/disallow_occupant_types = list()
|
||||
|
||||
var/mob/occupant = null // Person waiting to be despawned.
|
||||
var/time_till_despawn = 18000 // 30 minutes-ish safe period before being despawned.
|
||||
var/time_till_despawn = 9000 // Down to 15 minutes //30 minutes-ish is too long
|
||||
var/time_entered = 0 // Used to keep track of the safe period.
|
||||
var/obj/item/device/radio/intercom/announce //
|
||||
|
||||
@@ -486,32 +486,33 @@
|
||||
|
||||
if(istype(G, /obj/item/weapon/grab))
|
||||
|
||||
var/obj/item/weapon/grab/grab = G
|
||||
if(occupant)
|
||||
user << "<span class='notice'>\The [src] is in use.</span>"
|
||||
return
|
||||
|
||||
if(!ismob(G:affecting))
|
||||
if(!ismob(grab.affecting))
|
||||
return
|
||||
|
||||
if(!check_occupant_allowed(G:affecting))
|
||||
if(!check_occupant_allowed(grab.affecting))
|
||||
return
|
||||
|
||||
var/willing = null //We don't want to allow people to be forced into despawning.
|
||||
var/mob/M = G:affecting
|
||||
var/mob/M = grab.affecting
|
||||
|
||||
if(M.client)
|
||||
if(alert(M,"Would you like to enter long-term storage?",,"Yes","No") == "Yes")
|
||||
if(!M || !G || !G:affecting) return
|
||||
if(!M || !grab || !grab:affecting) return
|
||||
willing = 1
|
||||
else
|
||||
willing = 1
|
||||
|
||||
if(willing)
|
||||
|
||||
visible_message("[user] starts putting [G:affecting:name] into \the [src].", 3)
|
||||
visible_message("\The [user] starts putting [grab:affecting:name] into \the [src].", 3)
|
||||
|
||||
if(do_after(user, 20))
|
||||
if(!M || !G || !G:affecting) return
|
||||
if(!M || !grab || !grab:affecting) return
|
||||
|
||||
M.forceMove(src)
|
||||
|
||||
|
||||
@@ -808,23 +808,23 @@ About the new airlock wires panel:
|
||||
else
|
||||
spawn(0) close(1)
|
||||
|
||||
else if(istype(C, /obj/item/weapon/material/twohanded/fireaxe) && !arePowerSystemsOn())
|
||||
// Check if we're using a crowbar or armblade, and if the airlock's unpowered for whatever reason (off, broken, etc).
|
||||
else if( (istype(C, /obj/item/weapon/material/twohanded/fireaxe) || istype(C, /obj/item/weapon/melee/arm_blade) ) && !arePowerSystemsOn())
|
||||
if(locked)
|
||||
user << "<span class='notice'>The airlock's bolts prevent it from being forced.</span>"
|
||||
else if( !welded && !operating )
|
||||
if(istype(C, /obj/item/weapon/material/twohanded/fireaxe)) // If this is a fireaxe, make sure it's held in two hands.
|
||||
var/obj/item/weapon/material/twohanded/fireaxe/F = C
|
||||
if(!F.wielded)
|
||||
user << "<span class='warning'>You need to be wielding \the [F] to do that.</span>"
|
||||
return
|
||||
// At this point, it's an armblade or a fireaxe that passed the wielded test, let's try to open it.
|
||||
if(density)
|
||||
var/obj/item/weapon/material/twohanded/fireaxe/F = C
|
||||
if(F.wielded)
|
||||
spawn(0) open(1)
|
||||
else
|
||||
user << "<span class='warning'>You need to be wielding \the [C] to do that.</span>"
|
||||
spawn(0)
|
||||
open(1)
|
||||
else
|
||||
var/obj/item/weapon/material/twohanded/fireaxe/F = C
|
||||
if(F.wielded)
|
||||
spawn(0) close(1)
|
||||
else
|
||||
user << "<span class='warning'>You need to be wielding \the [C] to do that.</span>"
|
||||
|
||||
spawn(0)
|
||||
close(1)
|
||||
else
|
||||
..()
|
||||
return
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user