mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-11 10:43:20 +00:00
Merge branch 'master' of https://github.com/PolarisSS13/Polaris into 3/30/2016_dumb_gun_balance
# Conflicts resolved: # code/modules/projectiles/projectile/beams.dm
This commit is contained in:
@@ -36,4 +36,9 @@ script:
|
||||
- (num=`grep -E '\\\\(red|blue|green|black|b|i[^mc])' **/*.dm | wc -l`; echo "$num escapes (expecting ${MACRO_COUNT} or less)"; [ $num -le ${MACRO_COUNT} ])
|
||||
- source $HOME/BYOND-${BYOND_MAJOR}.${BYOND_MINOR}/byond/bin/byondsetup
|
||||
- python tools/TagMatcher/tag-matcher.py ../..
|
||||
- echo "#define UNIT_TEST 1" > code/_unit_tests.dm
|
||||
- cp config/example/* config/
|
||||
- DreamMaker polaris.dme
|
||||
- DreamDaemon polaris.dmb -invisible -trusted -core 2>&1 | tee log.txt
|
||||
- grep "All Unit Tests Passed" log.txt
|
||||
|
||||
|
||||
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
|
||||
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"
|
||||
@@ -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.is_preference_enabled(/datum/client_preference/admin/show_debug_logs))
|
||||
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()
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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,9 @@
|
||||
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.
|
||||
|
||||
// Things you might plausibly want to follow
|
||||
if((ismob(A) && A != src) || istype(A,/obj/singularity))
|
||||
else 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
|
||||
@@ -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)
|
||||
|
||||
@@ -109,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()
|
||||
@@ -142,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)
|
||||
@@ -182,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
|
||||
@@ -69,23 +69,38 @@
|
||||
break
|
||||
return .
|
||||
|
||||
/datum/recipe/proc/check_items(var/obj/machinery/microwave/container as obj)
|
||||
/datum/recipe/proc/check_items(var/obj/container as obj)
|
||||
. = 1
|
||||
if (items && items.len)
|
||||
var/list/checklist = list()
|
||||
checklist = items.Copy() // You should really trust Copy
|
||||
for(var/obj/O in container.ingredient_list)
|
||||
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,25 +108,39 @@
|
||||
//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
|
||||
|
||||
// food-related
|
||||
/datum/recipe/proc/make_food(var/obj/machinery/microwave/container as obj)
|
||||
/datum/recipe/proc/make_food(var/obj/container as obj)
|
||||
if(!result)
|
||||
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.ingredient_list)) //We no longer need to take result_obj out of the list, since it doesn't exist in the list.
|
||||
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.ingredient_list.Cut() //Trust in Cut().
|
||||
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,
|
||||
@@ -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"
|
||||
@@ -2074,7 +2081,7 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee
|
||||
/obj/item/weapon/cartridge/medical,
|
||||
/obj/item/device/flashlight/pen,
|
||||
/obj/item/weapon/reagent_containers/syringe,
|
||||
/obj/item/clothing/accessory/storage/brown_vest)
|
||||
/obj/item/clothing/accessory/storage/white_vest)
|
||||
cost = 20
|
||||
containertype = "/obj/structure/closet/crate/secure"
|
||||
containername = "Paramedic equipment"
|
||||
|
||||
@@ -129,6 +129,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'
|
||||
|
||||
@@ -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,17 +104,6 @@
|
||||
create_nuke()
|
||||
|
||||
show_objectives(player)
|
||||
|
||||
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
|
||||
|
||||
// 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)
|
||||
|
||||
@@ -37,14 +37,19 @@
|
||||
|
||||
if(!mind)
|
||||
return
|
||||
if(!src.mind.special_role)
|
||||
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)
|
||||
mind.ambitions = 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].")
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
text += get_special_objective_text(P)
|
||||
if(P.ambitions)
|
||||
text += "<br>Their goals for today were..."
|
||||
text += "<br><b>[P.ambitions]</b>"
|
||||
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"
|
||||
|
||||
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
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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>"
|
||||
|
||||
|
||||
@@ -155,8 +155,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")
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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 //
|
||||
|
||||
@@ -487,32 +487,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
|
||||
|
||||
@@ -86,11 +86,17 @@
|
||||
|
||||
// Proc: attackby()
|
||||
// Parameters: 2 (C - Item this object was clicked with, user - Mob which clicked this object)
|
||||
// Description: If we are clicked with crowbar or wielded fire axe, try to manually open the door.
|
||||
// Description: If we are clicked with crowbar, wielded fire axe, or armblade, try to manually open the door.
|
||||
// This only works on broken doors or doors without power. Also allows repair with Plasteel.
|
||||
/obj/machinery/door/blast/attackby(obj/item/weapon/C as obj, mob/user as mob)
|
||||
src.add_fingerprint(user)
|
||||
if(istype(C, /obj/item/weapon/crowbar) || (istype(C, /obj/item/weapon/material/twohanded/fireaxe) && C:wielded == 1))
|
||||
if(istype(C, /obj/item/weapon/crowbar) || istype(C, /obj/item/weapon/material/twohanded/fireaxe) || istype(C, /obj/item/weapon/melee/arm_blade))
|
||||
if(istype(C,/obj/item/weapon/material/twohanded/fireaxe))
|
||||
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
|
||||
|
||||
if(((stat & NOPOWER) || (stat & BROKEN)) && !( src.operating ))
|
||||
force_toggle()
|
||||
else
|
||||
@@ -144,7 +150,7 @@
|
||||
if(stat & BROKEN)
|
||||
stat &= ~BROKEN
|
||||
|
||||
|
||||
|
||||
/obj/machinery/door/blast/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
|
||||
if(air_group) return 1
|
||||
return ..()
|
||||
|
||||
@@ -235,7 +235,7 @@
|
||||
user << "<span class='danger'>\The [src] is welded shut!</span>"
|
||||
return
|
||||
|
||||
if(istype(C, /obj/item/weapon/crowbar) || istype(C,/obj/item/weapon/material/twohanded/fireaxe))
|
||||
if(istype(C, /obj/item/weapon/crowbar) || istype(C,/obj/item/weapon/material/twohanded/fireaxe) || istype(C, /obj/item/weapon/melee/arm_blade))
|
||||
if(operating)
|
||||
return
|
||||
|
||||
|
||||
@@ -18,8 +18,6 @@
|
||||
var/global/list/acceptable_items // List of the items you can put in
|
||||
var/global/list/acceptable_reagents // List of the reagents you can put in
|
||||
var/global/max_n_of_items = 0
|
||||
|
||||
var/list/ingredient_list = list() //MUST BE INTIALIZED OR YOU GET RUNTIME ERRORS
|
||||
|
||||
|
||||
// see code/modules/food/recipes_microwave.dm for recipes
|
||||
@@ -116,13 +114,12 @@
|
||||
user << "<span class='warning'>It's dirty!</span>"
|
||||
return 1
|
||||
else if(is_type_in_list(O,acceptable_items))
|
||||
if (ingredient_list.len>=max_n_of_items)
|
||||
if (contents.len>=(max_n_of_items + component_parts.len)) //Adds component_parts to the maximum number of items.
|
||||
user << "<span class='warning'>This [src] is full of ingredients, you cannot put more.</span>"
|
||||
return 1
|
||||
if(istype(O, /obj/item/stack) && O:get_amount() > 1) // This is bad, but I can't think of how to change it
|
||||
var/obj/item/stack/S = O
|
||||
var/obj/item/stack/K = new O.type (src) //Needed for change into ingredient lists, rather than just contents.
|
||||
ingredient_list += K
|
||||
new O.type (src)
|
||||
S.use(1)
|
||||
user.visible_message( \
|
||||
"<span class='notice'>\The [user] has added one of [O] to \the [src].</span>", \
|
||||
@@ -132,7 +129,6 @@
|
||||
// user.remove_from_mob(O) //This just causes problems so far as I can tell. -Pete
|
||||
user.drop_item()
|
||||
O.loc = src
|
||||
ingredient_list += O
|
||||
user.visible_message( \
|
||||
"<span class='notice'>\The [user] has added \the [O] to \the [src].</span>", \
|
||||
"<span class='notice'>You add \the [O] to \the [src].</span>")
|
||||
@@ -181,7 +177,7 @@
|
||||
var/list/items_counts = new
|
||||
var/list/items_measures = new
|
||||
var/list/items_measures_p = new
|
||||
for (var/obj/O in ingredient_list)
|
||||
for (var/obj/O in (contents-component_parts))
|
||||
var/display_name = O.name
|
||||
if (istype(O,/obj/item/weapon/reagent_containers/food/snacks/egg))
|
||||
items_measures[display_name] = "egg"
|
||||
@@ -241,7 +237,7 @@
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
return
|
||||
start()
|
||||
if (reagents.total_volume==0 && !(locate(/obj) in ingredient_list)) //dry run
|
||||
if (reagents.total_volume==0 && !(locate(/obj) in (contents-component_parts))) //dry run
|
||||
if (!wzhzhzh(10))
|
||||
abort()
|
||||
return
|
||||
@@ -303,7 +299,7 @@
|
||||
return 1
|
||||
|
||||
/obj/machinery/microwave/proc/has_extra_item()
|
||||
for (var/obj/O in ingredient_list)
|
||||
for (var/obj/O in (contents-component_parts))
|
||||
if ( \
|
||||
!istype(O,/obj/item/weapon/reagent_containers/food) && \
|
||||
!istype(O, /obj/item/weapon/grown) \
|
||||
@@ -329,9 +325,8 @@
|
||||
src.updateUsrDialog()
|
||||
|
||||
/obj/machinery/microwave/proc/dispose()
|
||||
for (var/obj/O in ingredient_list)
|
||||
for (var/obj/O in (contents-component_parts))
|
||||
O.loc = src.loc
|
||||
ingredient_list -= O
|
||||
if (src.reagents.total_volume)
|
||||
src.dirty++
|
||||
src.reagents.clear_reagents()
|
||||
@@ -365,7 +360,7 @@
|
||||
/obj/machinery/microwave/proc/fail()
|
||||
var/obj/item/weapon/reagent_containers/food/snacks/badrecipe/ffuu = new(src)
|
||||
var/amount = 0
|
||||
for (var/obj/O in ingredient_list-ffuu)
|
||||
for (var/obj/O in (contents-ffuu)-component_parts)
|
||||
amount++
|
||||
if (O.reagents)
|
||||
var/id = O.reagents.get_master_reagent_id()
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
return
|
||||
|
||||
/obj/effect/spider/attackby(var/obj/item/weapon/W, var/mob/user)
|
||||
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
|
||||
|
||||
if(W.attack_verb.len)
|
||||
visible_message("<span class='warning'>\The [src] have been [pick(W.attack_verb)] with \the [W][(user ? " by [user]." : ".")]</span>")
|
||||
else
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
var/burn_point = null
|
||||
var/burning = null
|
||||
var/hitsound = null
|
||||
var/storage_cost = null
|
||||
var/slot_flags = 0 //This is used to determine on which slots an item can fit.
|
||||
var/no_attack_log = 0 //If it's an item we don't want to log attack_logs with, set this to 1
|
||||
pass_flags = PASSTABLE
|
||||
@@ -358,7 +359,7 @@ var/list/global/slot_flags_enumeration = list(
|
||||
var/allow = 0
|
||||
if(H.back && istype(H.back, /obj/item/weapon/storage/backpack))
|
||||
var/obj/item/weapon/storage/backpack/B = H.back
|
||||
if(B.contents.len < B.storage_slots && w_class <= B.max_w_class)
|
||||
if(B.can_be_inserted(src,1))
|
||||
allow = 1
|
||||
if(!allow)
|
||||
return 0
|
||||
|
||||
@@ -354,12 +354,12 @@
|
||||
var/muleData[0]
|
||||
muleData["name"] = M.suffix
|
||||
muleData["location"] = get_area(M)
|
||||
muleData["mode"] = M.mode
|
||||
muleData["paused"] = M.paused
|
||||
muleData["home"] = M.homeName
|
||||
muleData["target"] = M.targetName
|
||||
muleData["ref"] = "\ref[M]"
|
||||
muleData["load"] = M.load ? M.load.name : "Nothing"
|
||||
|
||||
|
||||
mulebotsData[++mulebotsData.len] = muleData.Copy()
|
||||
|
||||
values["mulebotcount"] = count
|
||||
|
||||
@@ -43,13 +43,30 @@ var/global/list/obj/item/device/communicator/all_communicators = list()
|
||||
node = get_exonet_node()
|
||||
processing_objects |= src
|
||||
//This is a pretty terrible way of doing this.
|
||||
spawn(50) //Wait for our mob to finish spawning.
|
||||
spawn(5 SECONDS) //Wait for our mob to finish spawning.
|
||||
if(ismob(loc))
|
||||
register_device(loc)
|
||||
initialize_exonet(loc)
|
||||
else if(istype(loc, /obj/item/weapon/storage))
|
||||
var/obj/item/weapon/storage/S = loc
|
||||
if(ismob(S.loc))
|
||||
register_device(S.loc)
|
||||
initialize_exonet(S.loc)
|
||||
|
||||
// Proc: initialize_exonet()
|
||||
// Parameters: 1 (user - the person the communicator belongs to)
|
||||
// Description: Sets up the exonet datum, gives the device an address, and then gets a node reference. Afterwards, populates the device
|
||||
// list.
|
||||
/obj/item/device/communicator/proc/initialize_exonet(mob/user)
|
||||
if(!user || !istype(user, /mob/living))
|
||||
return
|
||||
if(!exonet)
|
||||
exonet = new(src)
|
||||
if(!exonet.address)
|
||||
exonet.make_address("communicator-[user.client]-[user.name]")
|
||||
if(!node)
|
||||
node = get_exonet_node()
|
||||
populate_known_devices()
|
||||
|
||||
// Proc: examine()
|
||||
// Parameters: 1 (user - the person examining the device)
|
||||
@@ -139,13 +156,7 @@ var/global/list/obj/item/device/communicator/all_communicators = list()
|
||||
// Description: Makes an exonet datum if one does not exist, allocates an address for it, maintains the lists of all devies, clears the alert icon, and
|
||||
// finally makes NanoUI appear.
|
||||
/obj/item/device/communicator/attack_self(mob/user)
|
||||
if(!exonet)
|
||||
exonet = new(src)
|
||||
if(!exonet.address)
|
||||
exonet.make_address("communicator-[user.client]-[user.name]")
|
||||
if(!node)
|
||||
node = get_exonet_node()
|
||||
populate_known_devices()
|
||||
initialize_exonet(user)
|
||||
alert_called = 0
|
||||
update_icon()
|
||||
ui_interact(user)
|
||||
@@ -292,7 +303,7 @@ var/global/list/obj/item/device/communicator/all_communicators = list()
|
||||
return
|
||||
var/their_address = href_list["dial"]
|
||||
exonet.send_message(their_address, "voice")
|
||||
|
||||
|
||||
if(href_list["disconnect"])
|
||||
var/name_to_disconnect = href_list["disconnect"]
|
||||
for(var/mob/living/voice/V in contents)
|
||||
@@ -304,13 +315,13 @@ var/global/list/obj/item/device/communicator/all_communicators = list()
|
||||
|
||||
if(href_list["copy"])
|
||||
target_address = href_list["copy"]
|
||||
|
||||
|
||||
if(href_list["hang_up"])
|
||||
for(var/mob/living/voice/V in contents)
|
||||
close_connection(usr, V, "[usr] hung up.")
|
||||
for(var/obj/item/device/communicator/comm in communicating)
|
||||
close_connection(usr, comm, "[usr] hung up.")
|
||||
|
||||
|
||||
if(href_list["switch_tab"])
|
||||
selected_tab = href_list["switch_tab"]
|
||||
|
||||
|
||||
@@ -68,6 +68,12 @@
|
||||
/obj/item/weapon/material/twohanded/update_icon()
|
||||
icon_state = "[base_icon][wielded]"
|
||||
item_state = icon_state
|
||||
|
||||
/obj/item/weapon/material/twohanded/dropped()
|
||||
..()
|
||||
if(wielded)
|
||||
spawn(0)
|
||||
update_held_icon()
|
||||
|
||||
/*
|
||||
* Fireaxe
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
)
|
||||
w_class = 4
|
||||
slot_flags = SLOT_BACK
|
||||
max_w_class = 3
|
||||
max_w_class = 4
|
||||
max_storage_space = 28
|
||||
|
||||
/obj/item/weapon/storage/backpack/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
@@ -53,6 +53,7 @@
|
||||
icon_state = "holdingpack"
|
||||
max_w_class = 4
|
||||
max_storage_space = 56
|
||||
storage_cost = 29
|
||||
|
||||
New()
|
||||
..()
|
||||
@@ -77,7 +78,6 @@
|
||||
icon_state = "giftbag0"
|
||||
item_state = "giftbag"
|
||||
w_class = 4.0
|
||||
storage_slots = 20
|
||||
max_w_class = 3
|
||||
max_storage_space = 400 // can store a ton of shit!
|
||||
item_state_slots = null
|
||||
@@ -142,57 +142,84 @@
|
||||
desc = "It's an orange backpack which was designed to hold beakers, pill bottles and bottles."
|
||||
icon_state = "chempack"
|
||||
|
||||
/*
|
||||
* Duffle Types
|
||||
*/
|
||||
|
||||
/obj/item/weapon/storage/backpack/dufflebag
|
||||
name = "dufflebag"
|
||||
desc = "A large dufflebag for holding extra things."
|
||||
icon_state = "duffle"
|
||||
item_state = "duffle"
|
||||
item_state_slots = list(
|
||||
slot_l_hand_str = "duffle",
|
||||
slot_r_hand_str = "duffle",
|
||||
)
|
||||
slowdown = 1
|
||||
max_storage_space = 38
|
||||
storage_slots = 12
|
||||
max_storage_space = 36
|
||||
|
||||
/obj/item/weapon/storage/backpack/dufflebag/syndie
|
||||
name = "black dufflebag"
|
||||
desc = "A large dufflebag for holding extra tactical supplies."
|
||||
icon_state = "duffle_syndie"
|
||||
item_state = "duffle_syndiemed"
|
||||
item_state_slots = list(
|
||||
slot_l_hand_str = "duffle_syndiemed",
|
||||
slot_r_hand_str = "duffle_syndiemed",
|
||||
)
|
||||
slowdown = 0
|
||||
|
||||
/obj/item/weapon/storage/backpack/dufflebag/syndie/med
|
||||
name = "medical dufflebag"
|
||||
desc = "A large dufflebag for holding extra tactical medical supplies."
|
||||
icon_state = "duffle_syndiemed"
|
||||
item_state = "duffle_syndiemed"
|
||||
item_state_slots = list(
|
||||
slot_l_hand_str = "duffle_syndiemed",
|
||||
slot_r_hand_str = "duffle_syndiemed",
|
||||
)
|
||||
|
||||
/obj/item/weapon/storage/backpack/dufflebag/syndie/ammo
|
||||
name = "ammunition dufflebag"
|
||||
desc = "A large dufflebag for holding extra weapons ammunition and supplies."
|
||||
icon_state = "duffle_syndieammo"
|
||||
item_state = "duffle_syndieammo"
|
||||
item_state_slots = list(
|
||||
slot_l_hand_str = "duffle_syndieammo",
|
||||
slot_r_hand_str = "duffle_syndieammo",
|
||||
)
|
||||
|
||||
/obj/item/weapon/storage/backpack/dufflebag/captain
|
||||
name = "captain's dufflebag"
|
||||
desc = "A large dufflebag for holding extra captainly goods."
|
||||
icon_state = "duffle_captain"
|
||||
item_state = "duffle_captain"
|
||||
item_state_slots = list(
|
||||
slot_l_hand_str = "duffle_captain",
|
||||
slot_r_hand_str = "duffle_captain",
|
||||
)
|
||||
|
||||
/obj/item/weapon/storage/backpack/dufflebag/med
|
||||
name = "medical dufflebag"
|
||||
desc = "A large dufflebag for holding extra medical supplies."
|
||||
icon_state = "duffle_med"
|
||||
item_state = "duffle_med"
|
||||
item_state_slots = list(
|
||||
slot_l_hand_str = "duffle_med",
|
||||
slot_r_hand_str = "duffle_med",
|
||||
)
|
||||
|
||||
/obj/item/weapon/storage/backpack/dufflebag/sec
|
||||
name = "security dufflebag"
|
||||
desc = "A large dufflebag for holding extra security supplies and ammunition."
|
||||
icon_state = "duffle_sec"
|
||||
item_state = "duffle_sec"
|
||||
item_state_slots = list(
|
||||
slot_l_hand_str = "duffle_sec",
|
||||
slot_r_hand_str = "duffle_sec",
|
||||
)
|
||||
|
||||
/obj/item/weapon/storage/backpack/dufflebag/eng
|
||||
name = "industrial dufflebag"
|
||||
desc = "A large dufflebag for holding extra tools and supplies."
|
||||
icon_state = "duffle_eng"
|
||||
item_state = "duffle_eng"
|
||||
item_state_slots = list(
|
||||
slot_l_hand_str = "duffle_eng",
|
||||
slot_r_hand_str = "duffle_eng",
|
||||
)
|
||||
|
||||
/*
|
||||
* Satchel Types
|
||||
|
||||
@@ -34,7 +34,6 @@
|
||||
|
||||
w_class = 4
|
||||
max_w_class = 2
|
||||
storage_slots = 21
|
||||
can_hold = list() // any
|
||||
cant_hold = list(/obj/item/weapon/disk/nuclear)
|
||||
|
||||
@@ -61,7 +60,6 @@
|
||||
|
||||
w_class = 4
|
||||
max_w_class = 2
|
||||
storage_slots = 21
|
||||
can_hold = list() // any
|
||||
cant_hold = list(/obj/item/weapon/disk/nuclear)
|
||||
|
||||
@@ -76,8 +74,7 @@
|
||||
icon_state = "satchel"
|
||||
slot_flags = SLOT_BELT | SLOT_POCKET
|
||||
w_class = 3
|
||||
storage_slots = 50
|
||||
max_storage_space = 200 //Doesn't matter what this is, so long as it's more or equal to storage_slots * ore.w_class
|
||||
max_storage_space = 100
|
||||
max_w_class = 3
|
||||
can_hold = list(/obj/item/weapon/ore)
|
||||
|
||||
@@ -90,8 +87,7 @@
|
||||
name = "plant bag"
|
||||
icon = 'icons/obj/hydroponics_machines.dmi'
|
||||
icon_state = "plantbag"
|
||||
storage_slots = 50; //the number of plant pieces it can carry.
|
||||
max_storage_space = 200 //Doesn't matter what this is, so long as it's more or equal to storage_slots * plants.w_class
|
||||
max_storage_space = 100
|
||||
max_w_class = 3
|
||||
w_class = 2
|
||||
can_hold = list(/obj/item/weapon/reagent_containers/food/snacks/grown,/obj/item/seeds,/obj/item/weapon/grown)
|
||||
@@ -111,6 +107,7 @@
|
||||
|
||||
var/capacity = 300; //the number of sheets it can carry.
|
||||
w_class = 3
|
||||
storage_slots = 7
|
||||
|
||||
allow_quick_empty = 1 // this function is superceded
|
||||
New()
|
||||
@@ -193,7 +190,7 @@
|
||||
var/col_count = min(7,storage_slots) -1
|
||||
if (adjusted_contents > 7)
|
||||
row_num = round((adjusted_contents-1) / 7) // 7 is the maximum allowed width.
|
||||
src.standard_orient_objs(row_num, col_count, numbered_contents)
|
||||
src.slot_orient_objs(row_num, col_count, numbered_contents)
|
||||
return
|
||||
|
||||
|
||||
@@ -248,8 +245,7 @@
|
||||
icon = 'icons/obj/storage.dmi'
|
||||
icon_state = "cashbag"
|
||||
desc = "A bag for carrying lots of cash. It's got a big dollar sign printed on the front."
|
||||
storage_slots = 50; //the number of cash pieces it can carry.
|
||||
max_storage_space = 200 //Doesn't matter what this is, so long as it's more or equal to storage_slots * cash.w_class
|
||||
max_storage_space = 100
|
||||
max_w_class = 3
|
||||
w_class = 2
|
||||
can_hold = list(/obj/item/weapon/coin,/obj/item/weapon/spacecash)
|
||||
|
||||
@@ -4,6 +4,9 @@
|
||||
icon = 'icons/obj/clothing/belts.dmi'
|
||||
icon_state = "utilitybelt"
|
||||
item_state = "utility"
|
||||
storage_slots = 7
|
||||
max_storage_space = 28 //This should ensure belts always have enough room to store whatever.
|
||||
max_w_class = 3
|
||||
slot_flags = SLOT_BELT
|
||||
attack_verb = list("whipped", "lashed", "disciplined")
|
||||
sprite_sheets = list("Teshari" = 'icons/mob/species/seromi/belt.dmi')
|
||||
@@ -121,9 +124,7 @@
|
||||
desc = "Can hold security gear like handcuffs and flashes."
|
||||
icon_state = "securitybelt"
|
||||
item_state = "security"
|
||||
storage_slots = 7
|
||||
max_w_class = 3
|
||||
max_storage_space = 28
|
||||
can_hold = list(
|
||||
/obj/item/weapon/grenade,
|
||||
/obj/item/weapon/reagent_containers/spray/pepper,
|
||||
@@ -180,7 +181,13 @@
|
||||
/obj/item/device/megaphone,
|
||||
/obj/item/device/radio/headset,
|
||||
/obj/item/clothing/gloves,
|
||||
/obj/item/taperoll/police
|
||||
/obj/item/taperoll/police,
|
||||
/obj/item/weapon/reagent_containers/spray/pepper,
|
||||
/obj/item/weapon/handcuffs,
|
||||
/obj/item/device/flash,
|
||||
/obj/item/weapon/flame/lighter,
|
||||
/obj/item/weapon/reagent_containers/food/snacks/donut/,
|
||||
/obj/item/ammo_magazine
|
||||
)
|
||||
|
||||
/obj/item/weapon/storage/belt/soulstone
|
||||
@@ -227,3 +234,27 @@
|
||||
desc = "Can hold security gear like handcuffs and flashes, with more pouches for more storage."
|
||||
icon_state = "bandolier"
|
||||
item_state = "bandolier"
|
||||
|
||||
/obj/item/weapon/storage/belt/janitor
|
||||
name = "janitorial belt"
|
||||
desc = "A belt used to hold most janitorial supplies."
|
||||
icon_state = "janibelt"
|
||||
item_state = "janibelt"
|
||||
storage_slots = 7
|
||||
max_w_class = 3
|
||||
can_hold = list(
|
||||
/obj/item/clothing/glasses,
|
||||
/obj/item/device/flashlight,
|
||||
/obj/item/weapon/grenade,
|
||||
/obj/item/device/pda,
|
||||
/obj/item/device/radio/headset,
|
||||
/obj/item/clothing/gloves,
|
||||
/obj/item/clothing/mask/surgical, //sterile mask,
|
||||
/obj/item/device/assembly/mousetrap,
|
||||
/obj/item/weapon/light/bulb,
|
||||
/obj/item/weapon/light/tube,
|
||||
/obj/item/weapon/flame/lighter,
|
||||
/obj/item/device/megaphone,
|
||||
/obj/item/weapon/reagent_containers/spray,
|
||||
/obj/item/weapon/soap
|
||||
)
|
||||
@@ -25,6 +25,7 @@
|
||||
icon_state = "box"
|
||||
item_state = "syringe_kit"
|
||||
var/foldable = /obj/item/stack/material/cardboard // BubbleWrap - if set, can be folded (when empty) into a sheet of cardboard
|
||||
max_w_class = 2
|
||||
|
||||
// BubbleWrap - A box can be folded up to make card
|
||||
/obj/item/weapon/storage/box/attack_self(mob/user as mob)
|
||||
@@ -498,12 +499,11 @@
|
||||
desc = "Drymate brand monkey cubes. Just add water!"
|
||||
icon = 'icons/obj/food.dmi'
|
||||
icon_state = "monkeycubebox"
|
||||
storage_slots = 7
|
||||
can_hold = list(/obj/item/weapon/reagent_containers/food/snacks/monkeycube)
|
||||
New()
|
||||
..()
|
||||
if(src.type == /obj/item/weapon/storage/box/monkeycubes)
|
||||
for(var/i = 1; i <= 5; i++)
|
||||
for(var/i = 1 to 5)
|
||||
new /obj/item/weapon/reagent_containers/food/snacks/monkeycube/wrapped(src)
|
||||
|
||||
/obj/item/weapon/storage/box/monkeycubes/farwacubes
|
||||
@@ -511,7 +511,7 @@
|
||||
desc = "Drymate brand farwa cubes, shipped from Ahdomai. Just add water!"
|
||||
New()
|
||||
..()
|
||||
for(var/i = 1; i <= 5; i++)
|
||||
for(var/i = 1 to 5)
|
||||
new /obj/item/weapon/reagent_containers/food/snacks/monkeycube/wrapped/farwacube(src)
|
||||
|
||||
/obj/item/weapon/storage/box/monkeycubes/stokcubes
|
||||
@@ -519,7 +519,7 @@
|
||||
desc = "Drymate brand stok cubes, shipped from Moghes. Just add water!"
|
||||
New()
|
||||
..()
|
||||
for(var/i = 1; i <= 5; i++)
|
||||
for(var/i = 1 to 5)
|
||||
new /obj/item/weapon/reagent_containers/food/snacks/monkeycube/wrapped/stokcube(src)
|
||||
|
||||
/obj/item/weapon/storage/box/monkeycubes/neaeracubes
|
||||
@@ -527,7 +527,7 @@
|
||||
desc = "Drymate brand neaera cubes, shipped from Jargon 4. Just add water!"
|
||||
New()
|
||||
..()
|
||||
for(var/i = 1; i <= 5; i++)
|
||||
for(var/i = 1 to 5)
|
||||
new /obj/item/weapon/reagent_containers/food/snacks/monkeycube/wrapped/neaeracube(src)
|
||||
|
||||
/obj/item/weapon/storage/box/ids
|
||||
@@ -612,11 +612,10 @@
|
||||
desc = "Eight wrappers of fun! Ages 8 and up. Not suitable for children."
|
||||
icon = 'icons/obj/toy.dmi'
|
||||
icon_state = "spbox"
|
||||
storage_slots = 8
|
||||
can_hold = list(/obj/item/toy/snappop)
|
||||
New()
|
||||
..()
|
||||
for(var/i=1; i <= storage_slots; i++)
|
||||
for(var/i = 1 to 8)
|
||||
new /obj/item/toy/snappop(src)
|
||||
|
||||
/obj/item/weapon/storage/box/matches
|
||||
@@ -625,14 +624,13 @@
|
||||
icon = 'icons/obj/cigarettes.dmi'
|
||||
icon_state = "matchbox"
|
||||
item_state = "zippo"
|
||||
storage_slots = 10
|
||||
w_class = 1
|
||||
slot_flags = SLOT_BELT
|
||||
can_hold = list(/obj/item/weapon/flame/match)
|
||||
|
||||
New()
|
||||
..()
|
||||
for(var/i=1; i <= storage_slots; i++)
|
||||
for(var/i=1 to 10)
|
||||
new /obj/item/weapon/flame/match(src)
|
||||
|
||||
attackby(obj/item/weapon/flame/match/W as obj, mob/user as mob)
|
||||
@@ -650,7 +648,7 @@
|
||||
icon_state = "syringe"
|
||||
New()
|
||||
..()
|
||||
for (var/i; i < storage_slots; i++)
|
||||
for (var/i = 1 to 7)
|
||||
new /obj/item/weapon/reagent_containers/hypospray/autoinjector(src)
|
||||
|
||||
/obj/item/weapon/storage/box/lights
|
||||
@@ -696,7 +694,6 @@
|
||||
icon_state = "portafreezer"
|
||||
item_state = "medicalpack"
|
||||
foldable = null
|
||||
storage_slots=7
|
||||
max_w_class = 3
|
||||
can_hold = list(/obj/item/organ, /obj/item/weapon/reagent_containers/food, /obj/item/weapon/reagent_containers/glass)
|
||||
max_storage_space = 21
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
|
||||
/obj/item/weapon/storage/fancy/egg_box/New()
|
||||
..()
|
||||
for(var/i=1; i <= storage_slots; i++)
|
||||
for(var/i=1 to storage_slots)
|
||||
new /obj/item/weapon/reagent_containers/food/snacks/egg(src)
|
||||
return
|
||||
|
||||
@@ -68,14 +68,13 @@
|
||||
icon_state = "candlebox5"
|
||||
icon_type = "candle"
|
||||
item_state = "candlebox5"
|
||||
storage_slots = 5
|
||||
throwforce = 2
|
||||
slot_flags = SLOT_BELT
|
||||
|
||||
|
||||
/obj/item/weapon/storage/fancy/candle_box/New()
|
||||
..()
|
||||
for(var/i=1; i <= storage_slots; i++)
|
||||
for(var/i=1 to 5)
|
||||
new /obj/item/weapon/flame/candle(src)
|
||||
return
|
||||
|
||||
@@ -89,7 +88,6 @@
|
||||
icon = 'icons/obj/crayons.dmi'
|
||||
icon_state = "crayonbox"
|
||||
w_class = 2.0
|
||||
storage_slots = 6
|
||||
icon_type = "crayon"
|
||||
can_hold = list(
|
||||
/obj/item/weapon/pen/crayon
|
||||
@@ -144,27 +142,42 @@
|
||||
for(var/i = 1 to storage_slots)
|
||||
new /obj/item/clothing/mask/smokable/cigarette(src)
|
||||
create_reagents(15 * storage_slots)//so people can inject cigarettes without opening a packet, now with being able to inject the whole one
|
||||
flags |= OPENCONTAINER
|
||||
|
||||
/obj/item/weapon/storage/fancy/cigarettes/update_icon()
|
||||
icon_state = "[initial(icon_state)][contents.len]"
|
||||
return
|
||||
|
||||
/obj/item/weapon/storage/fancy/cigarettes/remove_from_storage(obj/item/W as obj, atom/new_location)
|
||||
// Don't try to transfer reagents to lighters
|
||||
if(istype(W, /obj/item/clothing/mask/smokable/cigarette))
|
||||
var/obj/item/clothing/mask/smokable/cigarette/C = W
|
||||
if(!istype(C)) return // what
|
||||
reagents.trans_to_obj(C, (reagents.total_volume/contents.len))
|
||||
..()
|
||||
..()
|
||||
|
||||
/obj/item/weapon/storage/fancy/cigarettes/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
|
||||
if(!istype(M, /mob))
|
||||
return
|
||||
|
||||
if(M == user && user.zone_sel.selecting == O_MOUTH && contents.len > 0 && !user.wear_mask)
|
||||
var/obj/item/clothing/mask/smokable/cigarette/W = new /obj/item/clothing/mask/smokable/cigarette(user)
|
||||
reagents.trans_to_obj(W, (reagents.total_volume/contents.len))
|
||||
user.equip_to_slot_if_possible(W, slot_wear_mask)
|
||||
if(M == user && user.zone_sel.selecting == O_MOUTH)
|
||||
// Find ourselves a cig. Note that we could be full of lighters.
|
||||
var/obj/item/clothing/mask/smokable/cigarette/cig = locate() in src
|
||||
|
||||
if(cig == null)
|
||||
user << "<span class='notice'>Looks like the packet is out of cigarettes.</span>"
|
||||
return
|
||||
|
||||
// Instead of running equip_to_slot_if_possible() we check here first,
|
||||
// to avoid dousing cig with reagents if we're not going to equip it
|
||||
if(!cig.mob_can_equip(user, slot_wear_mask))
|
||||
return
|
||||
|
||||
// We call remove_from_storage first to manage the reagent transfer and
|
||||
// UI updates.
|
||||
remove_from_storage(cig, null)
|
||||
user.equip_to_slot(cig, slot_wear_mask)
|
||||
|
||||
reagents.maximum_volume = 15 * contents.len
|
||||
contents.len--
|
||||
user << "<span class='notice'>You take a cigarette out of the pack.</span>"
|
||||
update_icon()
|
||||
else
|
||||
@@ -248,21 +261,6 @@
|
||||
reagents.trans_to_obj(C, (reagents.total_volume/contents.len))
|
||||
..()
|
||||
|
||||
/obj/item/weapon/storage/fancy/cigar/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
|
||||
if(!istype(M, /mob))
|
||||
return
|
||||
|
||||
if(M == user && user.zone_sel.selecting == O_MOUTH && contents.len > 0 && !user.wear_mask)
|
||||
var/obj/item/clothing/mask/smokable/cigarette/cigar/W = new /obj/item/clothing/mask/smokable/cigarette/cigar(user)
|
||||
reagents.trans_to_obj(W, (reagents.total_volume/contents.len))
|
||||
user.equip_to_slot_if_possible(W, slot_wear_mask)
|
||||
reagents.maximum_volume = 15 * contents.len
|
||||
contents.len--
|
||||
user << "<span class='notice'>You take a cigar out of the case.</span>"
|
||||
update_icon()
|
||||
else
|
||||
..()
|
||||
|
||||
/*
|
||||
* Vial Box
|
||||
*/
|
||||
@@ -278,7 +276,7 @@
|
||||
|
||||
/obj/item/weapon/storage/fancy/vials/New()
|
||||
..()
|
||||
for(var/i=1; i <= storage_slots; i++)
|
||||
for(var/i=1 to 6)
|
||||
new /obj/item/weapon/reagent_containers/glass/beaker/vial(src)
|
||||
return
|
||||
|
||||
|
||||
@@ -162,7 +162,6 @@
|
||||
can_hold = list(/obj/item/weapon/reagent_containers/pill,/obj/item/weapon/dice,/obj/item/weapon/paper)
|
||||
allow_quick_gather = 1
|
||||
use_to_pickup = 1
|
||||
storage_slots = 14
|
||||
use_sound = null
|
||||
|
||||
/obj/item/weapon/storage/pill_bottle/antitox
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
w_class = 4
|
||||
max_w_class = 3
|
||||
max_storage_space = 14 //The sum of the w_classes of all the items in this storage item.
|
||||
storage_slots = 4
|
||||
req_access = list(access_armory)
|
||||
var/locked = 1
|
||||
var/broken = 0
|
||||
|
||||
@@ -15,14 +15,13 @@
|
||||
icon = 'icons/obj/food.dmi'
|
||||
icon_state = "donutbox"
|
||||
name = "donut box"
|
||||
storage_slots = 6
|
||||
var/startswith = 6
|
||||
can_hold = list(/obj/item/weapon/reagent_containers/food/snacks/donut)
|
||||
foldable = /obj/item/stack/material/cardboard
|
||||
|
||||
/obj/item/weapon/storage/box/donut/New()
|
||||
..()
|
||||
for(var/i=1; i <= startswith; i++)
|
||||
for(var/i=1 to startswith)
|
||||
new /obj/item/weapon/reagent_containers/food/snacks/donut/normal(src)
|
||||
update_icon()
|
||||
return
|
||||
|
||||
@@ -15,9 +15,15 @@
|
||||
var/list/cant_hold = new/list() //List of objects which this item can't store (in effect only if can_hold isn't set)
|
||||
var/list/is_seeing = new/list() //List of mobs which are currently seeing the contents of this item's storage
|
||||
var/max_w_class = 2 //Max size of objects that this object can store (in effect only if can_hold isn't set)
|
||||
var/max_storage_space = 14 //The sum of the storage costs of all the items in this storage item.
|
||||
var/storage_slots = 7 //The number of storage slots in this container.
|
||||
var/max_storage_space = 8 //The sum of the storage costs of all the items in this storage item.
|
||||
var/storage_slots = null //The number of storage slots in this container. If null, it uses the volume-based storage instead.
|
||||
var/obj/screen/storage/boxes = null
|
||||
var/obj/screen/storage/storage_start = null //storage UI
|
||||
var/obj/screen/storage/storage_continue = null
|
||||
var/obj/screen/storage/storage_end = null
|
||||
var/obj/screen/storage/stored_start = null
|
||||
var/obj/screen/storage/stored_continue = null
|
||||
var/obj/screen/storage/stored_end = null
|
||||
var/obj/screen/close/closer = null
|
||||
var/use_to_pickup //Set this to make it possible to use this item in an inverse way, so you can have the item in your hand and click items on the floor to pick them up.
|
||||
var/display_contents_with_number //Set this to make the storage item group contents of the same type and display them as a number.
|
||||
@@ -29,6 +35,12 @@
|
||||
/obj/item/weapon/storage/Destroy()
|
||||
close_all()
|
||||
qdel(boxes)
|
||||
qdel(src.storage_start)
|
||||
qdel(src.storage_continue)
|
||||
qdel(src.storage_end)
|
||||
qdel(src.stored_start)
|
||||
qdel(src.stored_continue)
|
||||
qdel(src.stored_end)
|
||||
qdel(closer)
|
||||
..()
|
||||
|
||||
@@ -92,11 +104,19 @@
|
||||
if(user.s_active)
|
||||
user.s_active.hide_from(user)
|
||||
user.client.screen -= src.boxes
|
||||
user.client.screen -= src.storage_start
|
||||
user.client.screen -= src.storage_continue
|
||||
user.client.screen -= src.storage_end
|
||||
user.client.screen -= src.closer
|
||||
user.client.screen -= src.contents
|
||||
user.client.screen += src.boxes
|
||||
user.client.screen += src.closer
|
||||
user.client.screen += src.contents
|
||||
if(storage_slots)
|
||||
user.client.screen += src.boxes
|
||||
else
|
||||
user.client.screen += src.storage_start
|
||||
user.client.screen += src.storage_continue
|
||||
user.client.screen += src.storage_end
|
||||
user.s_active = src
|
||||
is_seeing |= user
|
||||
return
|
||||
@@ -106,6 +126,9 @@
|
||||
if(!user.client)
|
||||
return
|
||||
user.client.screen -= src.boxes
|
||||
user.client.screen -= src.storage_start
|
||||
user.client.screen -= src.storage_continue
|
||||
user.client.screen -= src.storage_end
|
||||
user.client.screen -= src.closer
|
||||
user.client.screen -= src.contents
|
||||
if(user.s_active == src)
|
||||
@@ -157,7 +180,7 @@
|
||||
return
|
||||
|
||||
//This proc draws out the inventory and places the items on it. It uses the standard position.
|
||||
/obj/item/weapon/storage/proc/standard_orient_objs(var/rows, var/cols, var/list/obj/item/display_contents)
|
||||
/obj/item/weapon/storage/proc/slot_orient_objs(var/rows, var/cols, var/list/obj/item/display_contents)
|
||||
var/cx = 4
|
||||
var/cy = 2+rows
|
||||
src.boxes.screen_loc = "4:16,2:16 to [4+cols]:16,[2+rows]:16"
|
||||
@@ -183,6 +206,52 @@
|
||||
src.closer.screen_loc = "[4+cols+1]:16,2:16"
|
||||
return
|
||||
|
||||
/obj/item/weapon/storage/proc/space_orient_objs(var/list/obj/item/display_contents)
|
||||
|
||||
var/baseline_max_storage_space = 16 //should be equal to default backpack capacity
|
||||
var/storage_cap_width = 2 //length of sprite for start and end of the box representing total storage space
|
||||
var/stored_cap_width = 4 //length of sprite for start and end of the box representing the stored item
|
||||
var/storage_width = min( round( 224 * max_storage_space/baseline_max_storage_space ,1) ,274) //length of sprite for the box representing total storage space
|
||||
|
||||
storage_start.overlays.Cut()
|
||||
|
||||
var/matrix/M = matrix()
|
||||
M.Scale((storage_width-storage_cap_width*2+3)/32,1)
|
||||
src.storage_continue.transform = M
|
||||
|
||||
src.storage_start.screen_loc = "4:16,2:16"
|
||||
src.storage_continue.screen_loc = "4:[storage_cap_width+(storage_width-storage_cap_width*2)/2+2],2:16"
|
||||
src.storage_end.screen_loc = "4:[19+storage_width-storage_cap_width],2:16"
|
||||
|
||||
var/startpoint = 0
|
||||
var/endpoint = 1
|
||||
|
||||
for(var/obj/item/O in contents)
|
||||
startpoint = endpoint + 1
|
||||
endpoint += storage_width * O.get_storage_cost()/max_storage_space
|
||||
|
||||
var/matrix/M_start = matrix()
|
||||
var/matrix/M_continue = matrix()
|
||||
var/matrix/M_end = matrix()
|
||||
M_start.Translate(startpoint,0)
|
||||
M_continue.Scale((endpoint-startpoint-stored_cap_width*2)/32,1)
|
||||
M_continue.Translate(startpoint+stored_cap_width+(endpoint-startpoint-stored_cap_width*2)/2 - 16,0)
|
||||
M_end.Translate(endpoint-stored_cap_width,0)
|
||||
src.stored_start.transform = M_start
|
||||
src.stored_continue.transform = M_continue
|
||||
src.stored_end.transform = M_end
|
||||
storage_start.overlays += src.stored_start
|
||||
storage_start.overlays += src.stored_continue
|
||||
storage_start.overlays += src.stored_end
|
||||
|
||||
O.screen_loc = "4:[round((startpoint+endpoint)/2)+2],2:16"
|
||||
O.maptext = ""
|
||||
O.layer = 20
|
||||
|
||||
src.closer.screen_loc = "4:[storage_width+19],2:16"
|
||||
return
|
||||
|
||||
|
||||
/datum/numbered_display
|
||||
var/obj/item/sample_object
|
||||
var/number
|
||||
@@ -214,12 +283,14 @@
|
||||
adjusted_contents++
|
||||
numbered_contents.Add( new/datum/numbered_display(I) )
|
||||
|
||||
//var/mob/living/carbon/human/H = user
|
||||
var/row_num = 0
|
||||
var/col_count = min(7,storage_slots) -1
|
||||
if (adjusted_contents > 7)
|
||||
row_num = round((adjusted_contents-1) / 7) // 7 is the maximum allowed width.
|
||||
src.standard_orient_objs(row_num, col_count, numbered_contents)
|
||||
if(storage_slots == null)
|
||||
src.space_orient_objs(numbered_contents)
|
||||
else
|
||||
var/row_num = 0
|
||||
var/col_count = min(7,storage_slots) -1
|
||||
if (adjusted_contents > 7)
|
||||
row_num = round((adjusted_contents-1) / 7) // 7 is the maximum allowed width.
|
||||
src.slot_orient_objs(row_num, col_count, numbered_contents)
|
||||
return
|
||||
|
||||
//This proc return 1 if the item can be picked up and 0 if it can't.
|
||||
@@ -227,12 +298,12 @@
|
||||
/obj/item/weapon/storage/proc/can_be_inserted(obj/item/W as obj, stop_messages = 0)
|
||||
if(!istype(W)) return //Not an item
|
||||
|
||||
if(usr.isEquipped(W) && !usr.canUnEquip(W))
|
||||
if(usr && usr.isEquipped(W) && !usr.canUnEquip(W))
|
||||
return 0
|
||||
|
||||
if(src.loc == W)
|
||||
return 0 //Means the item is already in the storage item
|
||||
if(contents.len >= storage_slots)
|
||||
if(storage_slots != null && contents.len >= storage_slots)
|
||||
if(!stop_messages)
|
||||
usr << "<span class='notice'>[src] is full, make some space.</span>"
|
||||
return 0 //Storage item is full
|
||||
@@ -249,9 +320,9 @@
|
||||
usr << "<span class='notice'>[src] cannot hold [W].</span>"
|
||||
return 0
|
||||
|
||||
if (W.w_class > max_w_class)
|
||||
if (max_w_class != null && W.w_class > max_w_class)
|
||||
if(!stop_messages)
|
||||
usr << "<span class='notice'>[W] is too big for this [src].</span>"
|
||||
usr << "<span class='notice'>[W] is too long for \the [src].</span>"
|
||||
return 0
|
||||
|
||||
var/total_storage_space = W.get_storage_cost()
|
||||
@@ -260,7 +331,7 @@
|
||||
|
||||
if(total_storage_space > max_storage_space)
|
||||
if(!stop_messages)
|
||||
usr << "<span class='notice'>[src] is full, make some space.</span>"
|
||||
usr << "<span class='notice'>[src] is too full, make some space.</span>"
|
||||
return 0
|
||||
|
||||
if(W.w_class >= src.w_class && (istype(W, /obj/item/weapon/storage)))
|
||||
@@ -437,15 +508,51 @@
|
||||
else
|
||||
verbs -= /obj/item/weapon/storage/verb/toggle_gathering_mode
|
||||
|
||||
spawn(5)
|
||||
var/total_storage_space = 0
|
||||
for(var/obj/item/I in contents)
|
||||
total_storage_space += I.get_storage_cost()
|
||||
max_storage_space = max(total_storage_space,max_storage_space) //prevents spawned containers from being too small for their contents
|
||||
|
||||
src.boxes = new /obj/screen/storage( )
|
||||
src.boxes.name = "storage"
|
||||
src.boxes.master = src
|
||||
src.boxes.icon_state = "block"
|
||||
src.boxes.screen_loc = "7,7 to 10,8"
|
||||
src.boxes.layer = 19
|
||||
|
||||
src.storage_start = new /obj/screen/storage( )
|
||||
src.storage_start.name = "storage"
|
||||
src.storage_start.master = src
|
||||
src.storage_start.icon_state = "storage_start"
|
||||
src.storage_start.screen_loc = "7,7 to 10,8"
|
||||
src.storage_start.layer = 19
|
||||
src.storage_continue = new /obj/screen/storage( )
|
||||
src.storage_continue.name = "storage"
|
||||
src.storage_continue.master = src
|
||||
src.storage_continue.icon_state = "storage_continue"
|
||||
src.storage_continue.screen_loc = "7,7 to 10,8"
|
||||
src.storage_continue.layer = 19
|
||||
src.storage_end = new /obj/screen/storage( )
|
||||
src.storage_end.name = "storage"
|
||||
src.storage_end.master = src
|
||||
src.storage_end.icon_state = "storage_end"
|
||||
src.storage_end.screen_loc = "7,7 to 10,8"
|
||||
src.storage_end.layer = 19
|
||||
|
||||
src.stored_start = new /obj //we just need these to hold the icon
|
||||
src.stored_start.icon_state = "stored_start"
|
||||
src.stored_start.layer = 19
|
||||
src.stored_continue = new /obj
|
||||
src.stored_continue.icon_state = "stored_continue"
|
||||
src.stored_continue.layer = 19
|
||||
src.stored_end = new /obj
|
||||
src.stored_end.icon_state = "stored_end"
|
||||
src.stored_end.layer = 19
|
||||
|
||||
src.closer = new /obj/screen/close( )
|
||||
src.closer.master = src
|
||||
src.closer.icon_state = "x"
|
||||
src.closer.icon_state = "storage_close"
|
||||
src.closer.layer = 20
|
||||
orient2hud()
|
||||
return
|
||||
@@ -500,4 +607,19 @@
|
||||
return depth
|
||||
|
||||
/obj/item/proc/get_storage_cost()
|
||||
return 2**(w_class-1) //1,2,4,8,16,...
|
||||
if (storage_cost)
|
||||
return storage_cost
|
||||
else
|
||||
switch(w_class)
|
||||
if(1)
|
||||
return 1
|
||||
if(2)
|
||||
return 2
|
||||
if(3)
|
||||
return 4
|
||||
if(4)
|
||||
return 8
|
||||
if(5)
|
||||
return 16
|
||||
else
|
||||
return 1000
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
throw_range = 7
|
||||
w_class = 4
|
||||
max_w_class = 3
|
||||
max_storage_space = 14 //can hold 7 w_class-2 items or up to 3 w_class-3 items (with 1 w_class-2 item as change).
|
||||
max_storage_space = 14 //enough to hold all starting contents
|
||||
origin_tech = list(TECH_COMBAT = 1)
|
||||
attack_verb = list("robusted")
|
||||
|
||||
@@ -20,48 +20,47 @@
|
||||
icon_state = "red"
|
||||
item_state = "toolbox_red"
|
||||
|
||||
New()
|
||||
..()
|
||||
new /obj/item/weapon/crowbar/red(src)
|
||||
new /obj/item/weapon/extinguisher/mini(src)
|
||||
if(prob(50))
|
||||
new /obj/item/device/flashlight(src)
|
||||
else
|
||||
new /obj/item/device/flashlight/flare(src)
|
||||
new /obj/item/device/radio(src)
|
||||
/obj/item/weapon/storage/toolbox/emergency/New()
|
||||
..()
|
||||
new /obj/item/weapon/crowbar/red(src)
|
||||
new /obj/item/weapon/extinguisher/mini(src)
|
||||
if(prob(50))
|
||||
new /obj/item/device/flashlight(src)
|
||||
else
|
||||
new /obj/item/device/flashlight/flare(src)
|
||||
new /obj/item/device/radio(src)
|
||||
|
||||
/obj/item/weapon/storage/toolbox/mechanical
|
||||
name = "mechanical toolbox"
|
||||
icon_state = "blue"
|
||||
item_state = "toolbox_blue"
|
||||
|
||||
New()
|
||||
..()
|
||||
new /obj/item/weapon/screwdriver(src)
|
||||
new /obj/item/weapon/wrench(src)
|
||||
new /obj/item/weapon/weldingtool(src)
|
||||
new /obj/item/weapon/crowbar(src)
|
||||
new /obj/item/device/analyzer(src)
|
||||
new /obj/item/weapon/wirecutters(src)
|
||||
/obj/item/weapon/storage/toolbox/mechanical/New()
|
||||
..()
|
||||
new /obj/item/weapon/screwdriver(src)
|
||||
new /obj/item/weapon/wrench(src)
|
||||
new /obj/item/weapon/weldingtool(src)
|
||||
new /obj/item/weapon/crowbar(src)
|
||||
new /obj/item/device/analyzer(src)
|
||||
new /obj/item/weapon/wirecutters(src)
|
||||
|
||||
/obj/item/weapon/storage/toolbox/electrical
|
||||
name = "electrical toolbox"
|
||||
icon_state = "yellow"
|
||||
item_state = "toolbox_yellow"
|
||||
|
||||
New()
|
||||
..()
|
||||
var/color = pick("red","yellow","green","blue","pink","orange","cyan","white")
|
||||
new /obj/item/weapon/screwdriver(src)
|
||||
new /obj/item/weapon/wirecutters(src)
|
||||
new /obj/item/device/t_scanner(src)
|
||||
new /obj/item/weapon/crowbar(src)
|
||||
new /obj/item/stack/cable_coil(src,30,color)
|
||||
new /obj/item/stack/cable_coil(src,30,color)
|
||||
if(prob(5))
|
||||
new /obj/item/clothing/gloves/yellow(src)
|
||||
else
|
||||
new /obj/item/stack/cable_coil(src,30,color)
|
||||
/obj/item/weapon/storage/toolbox/electrical/New()
|
||||
..()
|
||||
new /obj/item/weapon/screwdriver(src)
|
||||
new /obj/item/weapon/wirecutters(src)
|
||||
new /obj/item/device/t_scanner(src)
|
||||
new /obj/item/weapon/crowbar(src)
|
||||
new /obj/item/stack/cable_coil/random(src,30)
|
||||
new /obj/item/stack/cable_coil/random(src,30)
|
||||
if(prob(5))
|
||||
new /obj/item/clothing/gloves/yellow(src)
|
||||
else
|
||||
new /obj/item/stack/cable_coil/random(src,30)
|
||||
|
||||
/obj/item/weapon/storage/toolbox/syndicate
|
||||
name = "black and red toolbox"
|
||||
@@ -70,13 +69,104 @@
|
||||
origin_tech = list(TECH_COMBAT = 1, TECH_ILLEGAL = 1)
|
||||
force = 7.0
|
||||
|
||||
New()
|
||||
..()
|
||||
var/color = pick("red","yellow","green","blue","pink","orange","cyan","white")
|
||||
new /obj/item/weapon/screwdriver(src)
|
||||
new /obj/item/weapon/wrench(src)
|
||||
new /obj/item/weapon/weldingtool(src)
|
||||
new /obj/item/weapon/crowbar(src)
|
||||
new /obj/item/stack/cable_coil(src,30,color)
|
||||
new /obj/item/weapon/wirecutters(src)
|
||||
new /obj/item/device/multitool(src)
|
||||
/obj/item/weapon/storage/toolbox/syndicate/New()
|
||||
..()
|
||||
new /obj/item/clothing/gloves/yellow(src)
|
||||
new /obj/item/weapon/screwdriver(src)
|
||||
new /obj/item/weapon/wrench(src)
|
||||
new /obj/item/weapon/weldingtool(src)
|
||||
new /obj/item/weapon/crowbar(src)
|
||||
new /obj/item/weapon/wirecutters(src)
|
||||
new /obj/item/device/multitool(src)
|
||||
|
||||
/obj/item/weapon/storage/toolbox/lunchbox
|
||||
max_storage_space = 8 //slightly smaller than a toolbox
|
||||
name = "rainbow lunchbox"
|
||||
icon_state = "lunchbox_rainbow"
|
||||
item_state = "toolbox_pink"
|
||||
desc = "A little lunchbox. This one is the colors of the rainbow!"
|
||||
w_class = 3
|
||||
max_w_class = 2
|
||||
var/filled = FALSE
|
||||
attack_verb = list("lunched")
|
||||
|
||||
/obj/item/weapon/storage/toolbox/lunchbox/New()
|
||||
..()
|
||||
if(filled)
|
||||
var/list/lunches = lunchables_lunches()
|
||||
var/lunch = lunches[pick(lunches)]
|
||||
new lunch(src)
|
||||
|
||||
var/list/snacks = lunchables_snacks()
|
||||
var/snack = snacks[pick(snacks)]
|
||||
new snack(src)
|
||||
|
||||
var/list/drinks = lunchables_drinks()
|
||||
var/drink = drinks[pick(drinks)]
|
||||
new drink(src)
|
||||
|
||||
/obj/item/weapon/storage/toolbox/lunchbox/filled
|
||||
filled = TRUE
|
||||
|
||||
/obj/item/weapon/storage/toolbox/lunchbox/heart
|
||||
name = "heart lunchbox"
|
||||
icon_state = "lunchbox_lovelyhearts"
|
||||
item_state = "toolbox_pink"
|
||||
desc = "A little lunchbox. This one has cute little hearts on it!"
|
||||
|
||||
/obj/item/weapon/storage/toolbox/lunchbox/heart/filled
|
||||
filled = TRUE
|
||||
|
||||
/obj/item/weapon/storage/toolbox/lunchbox/cat
|
||||
name = "cat lunchbox"
|
||||
icon_state = "lunchbox_sciencecatshow"
|
||||
item_state = "toolbox_green"
|
||||
desc = "A little lunchbox. This one has a cute little science cat from a popular show on it!"
|
||||
|
||||
/obj/item/weapon/storage/toolbox/lunchbox/cat/filled
|
||||
filled = TRUE
|
||||
|
||||
/obj/item/weapon/storage/toolbox/lunchbox/nt
|
||||
name = "Nanotrasen brand lunchbox"
|
||||
icon_state = "lunchbox_nanotrasen"
|
||||
item_state = "toolbox_blue"
|
||||
desc = "A little lunchbox. This one is branded with the Nanotrasen logo!"
|
||||
|
||||
/obj/item/weapon/storage/toolbox/lunchbox/nt/filled
|
||||
filled = TRUE
|
||||
|
||||
/obj/item/weapon/storage/toolbox/lunchbox/mars
|
||||
name = "\improper Mars university lunchbox"
|
||||
icon_state = "lunchbox_marsuniversity"
|
||||
item_state = "toolbox_red"
|
||||
desc = "A little lunchbox. This one is branded with the Mars university logo!"
|
||||
|
||||
/obj/item/weapon/storage/toolbox/lunchbox/mars/filled
|
||||
filled = TRUE
|
||||
|
||||
/obj/item/weapon/storage/toolbox/lunchbox/cti
|
||||
name = "\improper CTI lunchbox"
|
||||
icon_state = "lunchbox_cti"
|
||||
item_state = "toolbox_blue"
|
||||
desc = "A little lunchbox. This one is branded with the CTI logo!"
|
||||
|
||||
/obj/item/weapon/storage/toolbox/lunchbox/cti/filled
|
||||
filled = TRUE
|
||||
|
||||
/obj/item/weapon/storage/toolbox/lunchbox/nymph
|
||||
name = "\improper Diona nymph lunchbox"
|
||||
icon_state = "lunchbox_dionanymph"
|
||||
item_state = "toolbox_yellow"
|
||||
desc = "A little lunchbox. This one is an adorable Diona nymph on the side!"
|
||||
|
||||
/obj/item/weapon/storage/toolbox/lunchbox/nymph/filled
|
||||
filled = TRUE
|
||||
|
||||
/obj/item/weapon/storage/toolbox/lunchbox/syndicate
|
||||
name = "black and red lunchbox"
|
||||
icon_state = "lunchbox_syndie"
|
||||
item_state = "toolbox_syndi"
|
||||
desc = "A little lunchbox. This one is a sleek black and red, made of a durable steel!"
|
||||
|
||||
/obj/item/weapon/storage/toolbox/lunchbox/syndicate/filled
|
||||
filled = TRUE
|
||||
|
||||
@@ -127,7 +127,6 @@
|
||||
/obj/item/weapon/storage/box/syndie_kit/chameleon
|
||||
name = "chameleon kit"
|
||||
desc = "Comes with all the clothes you need to impersonate most people. Acting lessons sold seperately."
|
||||
storage_slots = 10
|
||||
|
||||
/obj/item/weapon/storage/box/syndie_kit/chameleon/New()
|
||||
..()
|
||||
|
||||
@@ -102,7 +102,7 @@
|
||||
usr.visible_message("<span class='warning'>[user] starts climbing onto \the [src]!</span>")
|
||||
climbers |= user
|
||||
|
||||
if(!do_after(user,(issmall(user) ? 30 : 50)))
|
||||
if(!do_after(user,(issmall(user) ? 20 : 34)))
|
||||
climbers -= user
|
||||
return
|
||||
|
||||
|
||||
@@ -79,6 +79,7 @@
|
||||
new /obj/item/weapon/caution(src)
|
||||
new /obj/item/device/lightreplacer(src)
|
||||
new /obj/item/weapon/storage/bag/trash(src)
|
||||
new /obj/item/weapon/storage/belt/janitor(src)
|
||||
new /obj/item/clothing/shoes/galoshes(src)
|
||||
|
||||
/*
|
||||
|
||||
@@ -48,7 +48,13 @@
|
||||
/obj/structure/closet/l3closet/janitor/New()
|
||||
..()
|
||||
new /obj/item/clothing/suit/bio_suit/janitor(src)
|
||||
new /obj/item/clothing/suit/bio_suit/janitor(src)
|
||||
new /obj/item/clothing/head/bio_hood/janitor(src)
|
||||
new /obj/item/clothing/head/bio_hood/janitor(src)
|
||||
new /obj/item/clothing/mask/gas(src)
|
||||
new /obj/item/clothing/mask/gas(src)
|
||||
new /obj/item/weapon/tank/emergency_oxygen/engi(src)
|
||||
new /obj/item/weapon/tank/emergency_oxygen/engi(src)
|
||||
|
||||
|
||||
/obj/structure/closet/l3closet/scientist
|
||||
|
||||
@@ -17,10 +17,7 @@
|
||||
new /obj/item/weapon/storage/backpack/satchel_eng(src)
|
||||
if(prob(50))
|
||||
new /obj/item/weapon/storage/backpack/dufflebag/eng(src)
|
||||
if (prob(70))
|
||||
new /obj/item/clothing/accessory/storage/brown_vest(src)
|
||||
else
|
||||
new /obj/item/clothing/accessory/storage/webbing(src)
|
||||
new /obj/item/clothing/accessory/storage/brown_vest(src)
|
||||
new /obj/item/blueprints(src)
|
||||
new /obj/item/clothing/under/rank/chief_engineer(src)
|
||||
new /obj/item/clothing/under/rank/chief_engineer/skirt(src)
|
||||
@@ -38,6 +35,7 @@
|
||||
new /obj/item/device/flash(src)
|
||||
new /obj/item/taperoll/engineering(src)
|
||||
new /obj/item/clothing/suit/storage/hooded/wintercoat/engineering(src)
|
||||
new /obj/item/weapon/tank/emergency_oxygen/engi(src)
|
||||
return
|
||||
|
||||
|
||||
@@ -118,10 +116,7 @@
|
||||
new /obj/item/weapon/storage/backpack/satchel_eng(src)
|
||||
if(prob(50))
|
||||
new /obj/item/weapon/storage/backpack/dufflebag/eng(src)
|
||||
if (prob(70))
|
||||
new /obj/item/clothing/accessory/storage/brown_vest(src)
|
||||
else
|
||||
new /obj/item/clothing/accessory/storage/webbing(src)
|
||||
new /obj/item/clothing/accessory/storage/brown_vest(src)
|
||||
new /obj/item/weapon/storage/toolbox/mechanical(src)
|
||||
new /obj/item/device/radio/headset/headset_eng(src)
|
||||
new /obj/item/device/radio/headset/headset_eng/alt(src)
|
||||
@@ -131,7 +126,11 @@
|
||||
new /obj/item/weapon/cartridge/engineering(src)
|
||||
new /obj/item/taperoll/engineering(src)
|
||||
new /obj/item/clothing/suit/storage/hooded/wintercoat/engineering(src)
|
||||
new /obj/item/weapon/tank/emergency_oxygen/engi(src)
|
||||
return
|
||||
|
||||
|
||||
|
||||
/obj/structure/closet/secure_closet/atmos_personal
|
||||
name = "technician's locker"
|
||||
req_access = list(access_atmospherics)
|
||||
@@ -151,10 +150,7 @@
|
||||
new /obj/item/weapon/storage/backpack/satchel_eng(src)
|
||||
if(prob(50))
|
||||
new /obj/item/weapon/storage/backpack/dufflebag/eng(src)
|
||||
if (prob(70))
|
||||
new /obj/item/clothing/accessory/storage/brown_vest(src)
|
||||
else
|
||||
new /obj/item/clothing/accessory/storage/webbing(src)
|
||||
new /obj/item/clothing/accessory/storage/brown_vest(src)
|
||||
new /obj/item/clothing/suit/fire/firefighter(src)
|
||||
new /obj/item/device/flashlight(src)
|
||||
new /obj/item/weapon/extinguisher(src)
|
||||
@@ -165,4 +161,5 @@
|
||||
new /obj/item/weapon/cartridge/atmos(src)
|
||||
new /obj/item/taperoll/atmos(src)
|
||||
new /obj/item/clothing/suit/storage/hooded/wintercoat/engineering/atmos(src)
|
||||
new /obj/item/weapon/tank/emergency_oxygen/engi(src)
|
||||
return
|
||||
|
||||
@@ -70,7 +70,7 @@
|
||||
new /obj/item/weapon/storage/backpack/dufflebag/med(src)
|
||||
new /obj/item/clothing/under/rank/nursesuit (src)
|
||||
new /obj/item/clothing/head/nursehat (src)
|
||||
switch(pick("blue", "green", "purple", "black"))
|
||||
switch(pick("blue", "green", "purple", "black", "navyblue"))
|
||||
if ("blue")
|
||||
new /obj/item/clothing/under/rank/medical/blue(src)
|
||||
new /obj/item/clothing/head/surgery/blue(src)
|
||||
@@ -83,7 +83,10 @@
|
||||
if ("black")
|
||||
new /obj/item/clothing/under/rank/medical/black(src)
|
||||
new /obj/item/clothing/head/surgery/black(src)
|
||||
switch(pick("blue", "green", "purple", "black"))
|
||||
if ("navyblue")
|
||||
new /obj/item/clothing/under/rank/medical/navyblue(src)
|
||||
new /obj/item/clothing/head/surgery/navyblue(src)
|
||||
switch(pick("blue", "green", "purple", "black", "navyblue"))
|
||||
if ("blue")
|
||||
new /obj/item/clothing/under/rank/medical/blue(src)
|
||||
new /obj/item/clothing/head/surgery/blue(src)
|
||||
@@ -96,6 +99,9 @@
|
||||
if ("black")
|
||||
new /obj/item/clothing/under/rank/medical/black(src)
|
||||
new /obj/item/clothing/head/surgery/black(src)
|
||||
if ("navyblue")
|
||||
new /obj/item/clothing/under/rank/medical/navyblue(src)
|
||||
new /obj/item/clothing/head/surgery/navyblue(src)
|
||||
new /obj/item/clothing/under/rank/medical(src)
|
||||
new /obj/item/clothing/under/rank/nurse(src)
|
||||
new /obj/item/clothing/under/rank/orderly(src)
|
||||
@@ -144,7 +150,7 @@
|
||||
new /obj/item/weapon/crowbar(src)
|
||||
new /obj/item/weapon/extinguisher/mini(src)
|
||||
new /obj/item/weapon/storage/box/freezer(src)
|
||||
new /obj/item/clothing/accessory/storage/brown_vest(src)
|
||||
new /obj/item/clothing/accessory/storage/white_vest(src)
|
||||
return
|
||||
|
||||
/obj/structure/closet/secure_closet/CMO
|
||||
@@ -168,7 +174,7 @@
|
||||
new /obj/item/clothing/suit/bio_suit/cmo(src)
|
||||
new /obj/item/clothing/head/bio_hood/cmo(src)
|
||||
new /obj/item/clothing/shoes/white(src)
|
||||
switch(pick("blue", "green", "purple", "black"))
|
||||
switch(pick("blue", "green", "purple", "black", "navyblue"))
|
||||
if ("blue")
|
||||
new /obj/item/clothing/under/rank/medical/blue(src)
|
||||
new /obj/item/clothing/head/surgery/blue(src)
|
||||
@@ -181,6 +187,9 @@
|
||||
if ("black")
|
||||
new /obj/item/clothing/under/rank/medical/black(src)
|
||||
new /obj/item/clothing/head/surgery/black(src)
|
||||
if ("navyblue")
|
||||
new /obj/item/clothing/under/rank/medical/navyblue(src)
|
||||
new /obj/item/clothing/head/surgery/navyblue(src)
|
||||
new /obj/item/clothing/under/rank/chief_medical_officer(src)
|
||||
new /obj/item/clothing/under/rank/chief_medical_officer/skirt(src)
|
||||
new /obj/item/clothing/suit/storage/toggle/labcoat/cmo(src)
|
||||
|
||||
@@ -10,31 +10,16 @@
|
||||
|
||||
New()
|
||||
..()
|
||||
if(prob(50))
|
||||
new /obj/item/weapon/storage/backpack/captain(src)
|
||||
else
|
||||
new /obj/item/weapon/storage/backpack/satchel_cap(src)
|
||||
if(prob(50))
|
||||
new /obj/item/weapon/storage/backpack/dufflebag/captain(src)
|
||||
new /obj/item/clothing/suit/captunic(src)
|
||||
new /obj/item/clothing/suit/captunic/capjacket(src)
|
||||
new /obj/item/clothing/head/caphat/cap(src)
|
||||
new /obj/item/clothing/under/rank/captain(src)
|
||||
new /obj/item/weapon/storage/backpack/dufflebag/captain(src)
|
||||
new /obj/item/clothing/suit/storage/vest(src)
|
||||
new /obj/item/weapon/cartridge/captain(src)
|
||||
new /obj/item/clothing/head/helmet/swat(src)
|
||||
new /obj/item/weapon/storage/lockbox/medal(src)
|
||||
new /obj/item/clothing/shoes/brown(src)
|
||||
new /obj/item/device/radio/headset/heads/captain(src)
|
||||
new /obj/item/device/radio/headset/heads/captain/alt(src)
|
||||
new /obj/item/clothing/gloves/captain(src)
|
||||
new /obj/item/weapon/gun/energy/gun(src)
|
||||
new /obj/item/clothing/suit/armor/captain(src)
|
||||
new /obj/item/weapon/melee/telebaton(src)
|
||||
new /obj/item/clothing/under/dress/dress_cap(src)
|
||||
new /obj/item/clothing/head/caphat/formal(src)
|
||||
new /obj/item/clothing/under/captainformal(src)
|
||||
new /obj/item/clothing/suit/storage/hooded/wintercoat/captain(src)
|
||||
return
|
||||
|
||||
|
||||
@@ -51,7 +36,6 @@
|
||||
|
||||
New()
|
||||
..()
|
||||
new /obj/item/clothing/glasses/sunglasses(src)
|
||||
new /obj/item/clothing/suit/storage/vest(src)
|
||||
new /obj/item/clothing/head/helmet(src)
|
||||
new /obj/item/weapon/cartridge/hop(src)
|
||||
@@ -89,6 +73,8 @@
|
||||
new /obj/item/clothing/shoes/white(src)
|
||||
new /obj/item/clothing/under/rank/head_of_personnel_whimsy(src)
|
||||
new /obj/item/clothing/head/caphat/hop(src)
|
||||
new /obj/item/clothing/under/gimmick/rank/head_of_personnel/suit(src)
|
||||
new /obj/item/clothing/glasses/sunglasses(src)
|
||||
return
|
||||
|
||||
|
||||
@@ -273,20 +259,8 @@
|
||||
|
||||
New()
|
||||
..()
|
||||
new /obj/item/clothing/under/det(src)
|
||||
new /obj/item/clothing/under/det/grey(src)
|
||||
new /obj/item/clothing/under/det/black(src)
|
||||
new /obj/item/clothing/under/det/waistcoat(src)
|
||||
new /obj/item/clothing/under/det/grey/waistcoat(src)
|
||||
new /obj/item/clothing/suit/storage/det_trench(src)
|
||||
new /obj/item/clothing/suit/storage/det_trench/grey(src)
|
||||
new /obj/item/clothing/suit/storage/forensics/blue(src)
|
||||
new /obj/item/clothing/suit/storage/forensics/red(src)
|
||||
new /obj/item/clothing/accessory/badge/holo/detective(src)
|
||||
new /obj/item/clothing/gloves/black(src)
|
||||
new /obj/item/clothing/head/det(src)
|
||||
new /obj/item/clothing/head/det/grey(src)
|
||||
new /obj/item/clothing/shoes/laceup(src)
|
||||
new /obj/item/weapon/storage/belt/detective(src)
|
||||
new /obj/item/weapon/storage/box/evidence(src)
|
||||
new /obj/item/device/radio/headset/headset_sec(src)
|
||||
@@ -299,6 +273,7 @@
|
||||
new /obj/item/clothing/accessory/holster/armpit(src)
|
||||
new /obj/item/device/flashlight/maglight(src)
|
||||
new /obj/item/weapon/reagent_containers/food/drinks/flask/detflask(src)
|
||||
new /obj/item/weapon/storage/briefcase/crimekit(src)
|
||||
return
|
||||
|
||||
/obj/structure/closet/secure_closet/detective/update_icon()
|
||||
|
||||
@@ -66,18 +66,32 @@
|
||||
..()
|
||||
new /obj/item/clothing/head/det(src)
|
||||
new /obj/item/clothing/head/det(src)
|
||||
new /obj/item/clothing/shoes/brown(src)
|
||||
new /obj/item/clothing/shoes/brown(src)
|
||||
new /obj/item/clothing/under/det(src)
|
||||
new /obj/item/clothing/under/det(src)
|
||||
new /obj/item/clothing/head/det/grey(src)
|
||||
new /obj/item/clothing/head/det/grey(src)
|
||||
new /obj/item/clothing/shoes/brown(src)
|
||||
new /obj/item/clothing/shoes/brown(src)
|
||||
new /obj/item/clothing/shoes/laceup(src)
|
||||
new /obj/item/clothing/shoes/laceup(src)
|
||||
new /obj/item/clothing/under/det(src)
|
||||
new /obj/item/clothing/under/det(src)
|
||||
new /obj/item/clothing/under/det/waistcoat(src)
|
||||
new /obj/item/clothing/under/det/waistcoat(src)
|
||||
new /obj/item/clothing/under/det/grey(src)
|
||||
new /obj/item/clothing/under/det/grey(src)
|
||||
new /obj/item/clothing/under/det/grey/waistcoat(src)
|
||||
new /obj/item/clothing/under/det/grey/waistcoat(src)
|
||||
new /obj/item/clothing/under/det/black(src)
|
||||
new /obj/item/clothing/under/det/black(src)
|
||||
new /obj/item/clothing/under/det/corporate(src)
|
||||
new /obj/item/clothing/under/det/corporate(src)
|
||||
new /obj/item/clothing/suit/storage/det_trench(src)
|
||||
new /obj/item/clothing/suit/storage/det_trench(src)
|
||||
new /obj/item/clothing/suit/storage/det_trench/grey(src)
|
||||
new /obj/item/clothing/suit/storage/det_trench/grey(src)
|
||||
new /obj/item/clothing/suit/storage/forensics/blue(src)
|
||||
new /obj/item/clothing/suit/storage/forensics/blue(src)
|
||||
new /obj/item/clothing/suit/storage/forensics/red(src)
|
||||
new /obj/item/clothing/suit/storage/forensics/red(src)
|
||||
return
|
||||
|
||||
/obj/structure/closet/wardrobe/pink
|
||||
@@ -280,6 +294,9 @@
|
||||
new /obj/item/clothing/suit/storage/hooded/wintercoat/engineering(src)
|
||||
new /obj/item/clothing/suit/storage/hooded/wintercoat/engineering(src)
|
||||
new /obj/item/clothing/suit/storage/hooded/wintercoat/engineering(src)
|
||||
new /obj/item/clothing/shoes/workboots(src)
|
||||
new /obj/item/clothing/shoes/workboots(src)
|
||||
new /obj/item/clothing/shoes/workboots(src)
|
||||
return
|
||||
|
||||
|
||||
@@ -453,6 +470,8 @@
|
||||
new /obj/item/clothing/under/rank/medical/green(src)
|
||||
new /obj/item/clothing/under/rank/medical/purple(src)
|
||||
new /obj/item/clothing/under/rank/medical/black(src)
|
||||
new /obj/item/clothing/under/rank/medical/navyblue(src)
|
||||
new /obj/item/clothing/head/surgery/navyblue(src)
|
||||
new /obj/item/clothing/head/surgery/purple(src)
|
||||
new /obj/item/clothing/head/surgery/blue(src)
|
||||
new /obj/item/clothing/head/surgery/green(src)
|
||||
@@ -516,7 +535,7 @@
|
||||
new /obj/item/clothing/under/pants/black(src)
|
||||
new /obj/item/clothing/under/pants/tan(src)
|
||||
new /obj/item/clothing/under/pants/track(src)
|
||||
new /obj/item/clothing/under/pants/jeans(src)
|
||||
new /obj/item/clothing/under/pants(src)
|
||||
new /obj/item/clothing/under/pants/khaki(src)
|
||||
new /obj/item/clothing/mask/bandana/blue(src)
|
||||
new /obj/item/clothing/mask/bandana/blue(src)
|
||||
@@ -589,3 +608,29 @@
|
||||
new /obj/item/clothing/under/scratch(src)
|
||||
new /obj/item/weapon/storage/backpack/satchel(src)
|
||||
new /obj/item/weapon/storage/backpack/satchel(src)
|
||||
return
|
||||
|
||||
/obj/structure/closet/wardrobe/captain
|
||||
name = "captain's wardrobe"
|
||||
icon_state = "cabinet_closed"
|
||||
icon_closed = "cabinet_closed"
|
||||
icon_opened = "cabinet_open"
|
||||
|
||||
/obj/structure/closet/wardrobe/captain/New()
|
||||
..()
|
||||
new /obj/item/weapon/storage/backpack/captain(src)
|
||||
new /obj/item/clothing/suit/captunic(src)
|
||||
new /obj/item/clothing/suit/captunic/capjacket(src)
|
||||
new /obj/item/clothing/head/caphat/cap(src)
|
||||
new /obj/item/clothing/under/rank/captain(src)
|
||||
new /obj/item/clothing/shoes/brown(src)
|
||||
new /obj/item/clothing/gloves/captain(src)
|
||||
new /obj/item/clothing/under/dress/dress_cap(src)
|
||||
new /obj/item/weapon/storage/backpack/satchel_cap(src)
|
||||
new /obj/item/clothing/head/caphat/formal(src)
|
||||
new /obj/item/clothing/under/captainformal(src)
|
||||
new /obj/item/clothing/suit/storage/hooded/wintercoat/captain(src)
|
||||
new /obj/item/clothing/head/beret/centcom/captain(src)
|
||||
new /obj/item/clothing/under/gimmick/rank/captain/suit(src)
|
||||
new /obj/item/clothing/glasses/sunglasses(src)
|
||||
return
|
||||
@@ -40,7 +40,7 @@
|
||||
/obj/structure/inflatable/bullet_act(var/obj/item/projectile/Proj)
|
||||
var/proj_damage = Proj.get_structure_damage()
|
||||
if(!proj_damage) return
|
||||
|
||||
|
||||
health -= proj_damage
|
||||
..()
|
||||
if(health <= 0)
|
||||
@@ -248,6 +248,7 @@
|
||||
desc = "Contains inflatable walls and doors."
|
||||
icon_state = "inf_box"
|
||||
item_state = "syringe_kit"
|
||||
w_class = 3
|
||||
max_storage_space = 28
|
||||
can_hold = list(/obj/item/inflatable)
|
||||
|
||||
|
||||
@@ -306,8 +306,8 @@
|
||||
if(istype(W, /obj/item/weapon/crowbar))
|
||||
user << "<span class='notice'>You struggle to pry off the outer sheath.</span>"
|
||||
playsound(src, 'sound/items/Crowbar.ogg', 100, 1)
|
||||
sleep(100)
|
||||
if(!istype(src, /turf/simulated/wall) || !user || !W || !T ) return
|
||||
if(!do_after(user,100) || !istype(src, /turf/simulated/wall) || !user || !W || !T )
|
||||
return
|
||||
if(user.loc == T && user.get_active_hand() == W )
|
||||
user << "<span class='notice'>You pry off the outer sheath.</span>"
|
||||
dismantle_wall()
|
||||
|
||||
@@ -16,7 +16,7 @@ var/global/floorIsLava = 0
|
||||
var/rendered = "<span class=\"log_message\"><span class=\"prefix\">ATTACK:</span> <span class=\"message\">[text]</span></span>"
|
||||
for(var/client/C in admins)
|
||||
if((R_ADMIN|R_MOD) & C.holder.rights)
|
||||
if(C.is_preference_enabled(/datum/client_preference/admin/show_attack_logs))
|
||||
if(C.is_preference_enabled(/datum/client_preference/mod/show_attack_logs))
|
||||
var/msg = rendered
|
||||
C << msg
|
||||
|
||||
@@ -895,22 +895,26 @@ proc/admin_notice(var/message, var/rights)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////ADMIN HELPER PROCS
|
||||
|
||||
/proc/is_special_character(mob/M as mob) // returns 1 for specail characters and 2 for heroes of gamemode
|
||||
/proc/is_special_character(var/character) // returns 1 for special characters and 2 for heroes of gamemode
|
||||
if(!ticker || !ticker.mode)
|
||||
return 0
|
||||
if (!istype(M))
|
||||
return 0
|
||||
var/datum/mind/M
|
||||
if (ismob(character))
|
||||
var/mob/C = character
|
||||
M = C.mind
|
||||
else if(istype(character, /datum/mind))
|
||||
M = character
|
||||
|
||||
if(M.mind)
|
||||
if(M)
|
||||
if(ticker.mode.antag_templates && ticker.mode.antag_templates.len)
|
||||
for(var/datum/antagonist/antag in ticker.mode.antag_templates)
|
||||
if(antag.is_antagonist(M.mind))
|
||||
if(antag.is_antagonist(M))
|
||||
return 2
|
||||
else if(M.mind.special_role)
|
||||
else if(M.special_role)
|
||||
return 1
|
||||
|
||||
if(isrobot(M))
|
||||
var/mob/living/silicon/robot/R = M
|
||||
if(isrobot(character))
|
||||
var/mob/living/silicon/robot/R = character
|
||||
if(R.emagged)
|
||||
return 1
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user