Merge branch 'master' into upstream-merge-29105

This commit is contained in:
LetterJay
2017-09-02 07:11:32 -05:00
committed by GitHub
1577 changed files with 55829 additions and 215217 deletions
+2 -2
View File
@@ -1,9 +1,9 @@
#define MC_TICK_CHECK ( ( world.tick_usage > Master.current_ticklimit || src.state != SS_RUNNING ) ? pause() : 0 )
#define MC_TICK_CHECK ( ( TICK_USAGE > Master.current_ticklimit || src.state != SS_RUNNING ) ? pause() : 0 )
#define MC_SPLIT_TICK_INIT(phase_count) var/original_tick_limit = Master.current_ticklimit; var/split_tick_phases = ##phase_count
#define MC_SPLIT_TICK \
if(split_tick_phases > 1){\
Master.current_ticklimit = ((original_tick_limit - world.tick_usage) / split_tick_phases) + world.tick_usage;\
Master.current_ticklimit = ((original_tick_limit - TICK_USAGE) / split_tick_phases) + TICK_USAGE;\
--split_tick_phases;\
} else {\
Master.current_ticklimit = original_tick_limit;\
+10
View File
@@ -0,0 +1,10 @@
#define TICK_LIMIT_RUNNING 80
#define TICK_LIMIT_TO_RUN 78
#define TICK_LIMIT_MC 70
#define TICK_LIMIT_MC_INIT_DEFAULT 98
#define TICK_USAGE world.tick_usage //for general usage
#define TICK_USAGE_REAL world.tick_usage //to be used where the result isn't checked
#define TICK_CHECK ( TICK_USAGE > Master.current_ticklimit )
#define CHECK_TICK if TICK_CHECK stoplag()
+3 -3
View File
@@ -1,6 +1,6 @@
//A set of constants used to determine which type of mute an admin wishes to apply:
//Please read and understand the muting/automuting stuff before changing these. MUTE_IC_AUTO etc = (MUTE_IC << 1)
//Therefore there needs to be a gap between the flags for the automute flags
//Therefore there needs to be a gap between the flags_1 for the automute flags_1
#define MUTE_IC 1
#define MUTE_OOC 2
#define MUTE_PRAY 4
@@ -39,7 +39,7 @@
#error Remove the flag below , its been long enough
#endif
//legacy , remove post 512, it was replaced by R_POLL
#define R_REJUVINATE 2
#define R_REJUVINATE 2
#define R_MAXPERMISSION 4096 //This holds the maximum value for a permission. It is used in iteration, so keep it updated.
@@ -50,7 +50,7 @@
#define ADMIN_SM(user) "(<a href='?_src_=holder;subtlemessage=\ref[user]'>SM</a>)"
#define ADMIN_TP(user) "(<a href='?_src_=holder;traitor=\ref[user]'>TP</a>)"
#define ADMIN_KICK(user) "(<a href='?_src_=holder;boot2=\ref[user]'>KICK</a>)"
#define ADMIN_CENTCOM_REPLY(user) "(<a href='?_src_=holder;CentComReply=\ref[user]'>RPLY</a>)"
#define ADMIN_CENTCOM_REPLY(user) "(<a href='?_src_=holder;CentComReply=\ref[user]'>RPLY</a>)"
#define ADMIN_SYNDICATE_REPLY(user) "(<a href='?_src_=holder;SyndicateReply=\ref[user]'>RPLY</a>)"
#define ADMIN_SC(user) "(<a href='?_src_=holder;adminspawncookie=\ref[user]'>SC</a>)"
#define ADMIN_SMITE(user) "(<a href='?_src_=holder;adminsmite=\ref[user]'>SMITE</a>)"
+2
View File
@@ -14,3 +14,5 @@
#define COMSIG_COMPONENT_ADDED "component_added" //when a component is added to a datum: (datum/component)
#define COMSIG_COMPONENT_REMOVING "component_removing" //before a component is removed from a datum because of RemoveComponent: (datum/component)
#define COMSIG_PARENT_QDELETED "parent_qdeleted" //before a datum's Destroy() is called: ()
#define COMSIG_ATOM_ENTERED "atom_entered" //from base of atom/Entered(): (atom/movable, atom)
#define COMSIG_MOVABLE_CROSSED "movable_crossed" //from base of atom/movable/Crossed(): (atom/movable)
+35 -37
View File
@@ -1,5 +1,5 @@
/*
These defines are specific to the atom/flags bitmask
These defines are specific to the atom/flags_1 bitmask
*/
#define ALL ~0 //For convenience.
#define NONE 0
@@ -7,58 +7,58 @@
GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768))
//FLAGS BITMASK
#define STOPSPRESSUREDMAGE 1 //This flag is used on the flags variable for SUIT and HEAD items which stop pressure damage. Note that the flag 1 was previous used as ONBACK, so it is possible for some code to use (flags & 1) when checking if something can be put on your back. Replace this code with (inv_flags & SLOT_BACK) if you see it anywhere
#define STOPSPRESSUREDMAGE_1 1 //This flag is used on the flags_1 variable for SUIT and HEAD items which stop pressure damage. Note that the flag 1 was previous used as ONBACK, so it is possible for some code to use (flags & 1) when checking if something can be put on your back. Replace this code with (inv_flags & SLOT_BACK) if you see it anywhere
//To successfully stop you taking all pressure damage you must have both a suit and head item with this flag.
#define NODROP 2 // This flag makes it so that an item literally cannot be removed at all, or at least that's how it should be. Only deleted.
#define NOBLUDGEON 4 // when an item has this it produces no "X has been hit by Y with Z" message in the default attackby()
#define MASKINTERNALS 8 // mask allows internals
#define HEAR 16 // This flag is what recursive_hear_check() uses to determine wether to add an item to the hearer list or not.
#define CHECK_RICOCHET 32 // Projectiels will check ricochet on things impacted that have this.
#define CONDUCT 64 // conducts electricity (metal etc.)
#define ABSTRACT 128 // for all things that are technically items but used for various different stuff, made it 128 because it could conflict with other flags other way
#define NODECONSTRUCT 128 // For machines and structures that should not break into parts, eg, holodeck stuff
#define OVERLAY_QUEUED 256 //atom queued to SSoverlay
#define ON_BORDER 512 // item has priority to check when entering or leaving
#define NODROP_1 2 // This flag makes it so that an item literally cannot be removed at all, or at least that's how it should be. Only deleted.
#define NOBLUDGEON_1 4 // when an item has this it produces no "X has been hit by Y with Z" message in the default attackby()
#define MASKINTERNALS_1 8 // mask allows internals
#define HEAR_1 16 // This flag is what recursive_hear_check() uses to determine wether to add an item to the hearer list or not.
#define CHECK_RICOCHET_1 32 // Projectiels will check ricochet on things impacted that have this.
#define CONDUCT_1 64 // conducts electricity (metal etc.)
#define ABSTRACT_1 128 // for all things that are technically items but used for various different stuff, made it 128 because it could conflict with other flags other way
#define NODECONSTRUCT_1 128 // For machines and structures that should not break into parts, eg, holodeck stuff
#define OVERLAY_QUEUED_1 256 // atom queued to SSoverlay
#define ON_BORDER_1 512 // item has priority to check when entering or leaving
#define NOSLIP 1024 //prevents from slipping on wet floors, in space etc
#define CLEAN_ON_MOVE 2048
#define NOSLIP_1 1024 //prevents from slipping on wet floors, in space etc
#define CLEAN_ON_MOVE_1 2048
// BLOCK_GAS_SMOKE_EFFECT only used in masks at the moment.
#define BLOCK_GAS_SMOKE_EFFECT 4096 // blocks the effect that chemical clouds would have on a mob --glasses, mask and helmets ONLY!
#define THICKMATERIAL 8192 //prevents syringes, parapens and hypos if the external suit or helmet (if targeting head) has this flag. Example: space suits, biosuit, bombsuits, thick suits that cover your body.
#define DROPDEL 16384 // When dropped, it calls qdel on itself
#define PREVENT_CLICK_UNDER 32768 //Prevent clicking things below it on the same turf eg. doors/ fulltile windows
// BLOCK_GAS_SMOKE_EFFECT_1 only used in masks at the moment.
#define BLOCK_GAS_SMOKE_EFFECT_1 4096 // blocks the effect that chemical clouds would have on a mob --glasses, mask and helmets ONLY!
#define THICKMATERIAL_1 8192 //prevents syringes, parapens and hypos if the external suit or helmet (if targeting head) has this flag. Example: space suits, biosuit, bombsuits, thick suits that cover your body.
#define DROPDEL_1 16384 // When dropped, it calls qdel on itself
#define PREVENT_CLICK_UNDER_1 32768 //Prevent clicking things below it on the same turf eg. doors/ fulltile windows
/* Secondary atom flags, access using the SECONDARY_FLAG macros */
/* Secondary atom flags, for the flags_2 var, denoted with a _2 */
#define SLOWS_WHILE_IN_HAND "slows_while_in_hand"
#define NO_EMP_WIRES "no_emp_wires"
#define HOLOGRAM "hologram"
#define FROZEN "frozen"
#define STATIONLOVING "stationloving"
#define INFORM_ADMINS_ON_RELOCATE "inform_admins_on_relocate"
#define BANG_PROTECT "bang_protect"
#define SLOWS_WHILE_IN_HAND_2 1
#define NO_EMP_WIRES_2 2
#define HOLOGRAM_2 4
#define FROZEN_2 8
#define STATIONLOVING_2 16
#define INFORM_ADMINS_ON_RELOCATE_2 32
#define BANG_PROTECT_2 64
// An item worn in the ear slot with HEALS_EARS will heal your ears each
// Life() tick, even if normally your ears would be too damaged to heal.
#define HEALS_EARS "heals_ears"
#define HEALS_EARS_2 128
// A mob with OMNITONGUE has no restriction in the ability to speak
// languages that they know. So even if they wouldn't normally be able to
// through mob or tongue restrictions, this flag allows them to ignore
// those restrictions.
#define OMNITONGUE "omnitongue"
#define OMNITONGUE_2 256
// TESLA_IGNORE grants immunity from being targeted by tesla-style electricity
#define TESLA_IGNORE "tesla_ignore"
#define TESLA_IGNORE_2 512
//turf-only flags
#define NOJAUNT 1
#define UNUSED_TRANSIT_TURF 2
#define CAN_BE_DIRTY 4 //If a turf can be made dirty at roundstart. This is also used in areas.
#define NO_DEATHRATTLE 16 // Do not notify deadchat about any deaths that occur on this turf.
//#define CHECK_RICOCHET 32 //Same thing as atom flag.
#define NOJAUNT_1 1
#define UNUSED_TRANSIT_TURF_1 2
#define CAN_BE_DIRTY_1 4 // If a turf can be made dirty at roundstart. This is also used in areas.
#define NO_DEATHRATTLE_1 16 // Do not notify deadchat about any deaths that occur on this turf.
//#define CHECK_RICOCHET_1 32 //Same thing as atom flag.
/*
These defines are used specifically with the atom/pass_flags bitmask
@@ -90,5 +90,3 @@ GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 204
#define ACID_PROOF 32 //acid stuck on it doesn't melt it.
#define INDESTRUCTIBLE 64 //doesn't take damage
#define FREEZE_PROOF 128 //can't be frozen
// language secondary flags for atoms
+12
View File
@@ -0,0 +1,12 @@
#define MEAT 1
#define VEGETABLES 2
#define RAW 4
#define JUNKFOOD 8
#define GRAIN 16
#define FRUIT 32
#define DAIRY 64
#define FRIED 128
#define ALCOHOL 256
#define SUGAR 512
#define GROSS 1024
#define TOXIC 2048
+6 -6
View File
@@ -86,7 +86,7 @@
. = SLOT_POCKET
//Bit flags for the flags_inv variable, which determine when a piece of clothing hides another. IE a helmet hiding glasses.
//Bit flags_1 for the flags_inv variable, which determine when a piece of clothing hides another. IE a helmet hiding glasses.
#define HIDEGLOVES 1
#define HIDESUITSTORAGE 2
#define HIDEJUMPSUIT 4 //these first four are only used in exterior suits
@@ -134,17 +134,17 @@
#define THERMAL_PROTECTION_HAND_LEFT 0.025
#define THERMAL_PROTECTION_HAND_RIGHT 0.025
//flags for female outfits: How much the game can safely "take off" the uniform without it looking weird
//flags_1 for female outfits: How much the game can safely "take off" the uniform without it looking weird
#define NO_FEMALE_UNIFORM 0
#define FEMALE_UNIFORM_FULL 1
#define FEMALE_UNIFORM_TOP 2
//flags for alternate styles: These are hard sprited so don't set this if you didn't put the effort in
//flags_1 for alternate styles: These are hard sprited so don't set this if you didn't put the effort in
#define NORMAL_STYLE 0
#define ALT_STYLE 1
#define DIGITIGRADE_STYLE 2
//flags for outfits that have mutantrace variants (try not to use this): Currently only needed if you're trying to add tight fitting bootyshorts
//flags_1 for outfits that have mutantrace variants (try not to use this): Currently only needed if you're trying to add tight fitting bootyshorts
#define NO_MUTANTRACE_VARIATION 0
#define MUTANTRACE_VARIATION 1
@@ -152,9 +152,9 @@
#define FULL_DIGITIGRADE 1
#define SQUISHED_DIGITIGRADE 2
//flags for covering body parts
//flags_1 for covering body parts
#define GLASSESCOVERSEYES 1
#define MASKCOVERSEYES 2 // get rid of some of the other retardation in these flags
#define MASKCOVERSEYES 2 // get rid of some of the other retardation in these flags_1
#define HEADCOVERSEYES 4 // feel free to realloc these numbers for other purposes
#define MASKCOVERSMOUTH 8 // on other items, these are just for mask/head
#define HEADCOVERSMOUTH 16
+4 -4
View File
@@ -137,10 +137,10 @@
#define isorgan(A) (istype(A, /obj/item/organ))
GLOBAL_LIST_INIT(pointed_types, typecacheof(list(
/obj/item/weapon/pen,
/obj/item/weapon/screwdriver,
/obj/item/weapon/reagent_containers/syringe,
/obj/item/weapon/kitchen/fork)))
/obj/item/pen,
/obj/item/screwdriver,
/obj/item/reagent_containers/syringe,
/obj/item/kitchen/fork)))
#define is_pointed(W) (is_type_in_typecache(W, GLOB.pointed_types))
-9
View File
@@ -1,9 +0,0 @@
diff a/code/__DEFINES/logging.dm b/code/__DEFINES/logging.dm (rejected hunks)
@@ -9,6 +9,7 @@
#define INVESTIGATE_SUPERMATTER "supermatter"
#define INVESTIGATE_TELESCI "telesci"
#define INVESTIGATE_WIRES "wires"
+#define INVESTIGATE_HALLUCINATIONS "hallucinations"
//Individual logging defines
#define INDIVIDUAL_ATTACK_LOG "Attack log"
+25 -25
View File
@@ -1,25 +1,25 @@
#define PI 3.1415
#define SPEED_OF_LIGHT 3e8 //not exact but hey!
#define SPEED_OF_LIGHT_SQ 9e+16
#define INFINITY 1e31 //closer then enough
//atmos
#define R_IDEAL_GAS_EQUATION 8.31 //kPa*L/(K*mol)
#define ONE_ATMOSPHERE 101.325 //kPa
#define T0C 273.15 // 0degC
#define T20C 293.15 // 20degC
#define TCMB 2.7 // -270.3degC
//"fancy" math for calculating time in ms from tick_usage percentage and the length of ticks
//percent_of_tick_used * (ticklag * 100(to convert to ms)) / 100(percent ratio)
//collapsed to percent_of_tick_used * tick_lag
#define TICK_DELTA_TO_MS(percent_of_tick_used) ((percent_of_tick_used) * world.tick_lag)
#define TICK_USAGE_TO_MS(starting_tickusage) (TICK_DELTA_TO_MS(world.tick_usage-starting_tickusage))
#define PERCENT(val) (round(val*100, 0.1))
#define CLAMP01(x) (Clamp(x, 0, 1))
//time of day but automatically adjusts to the server going into the next day within the same round.
//for when you need a reliable time number that doesn't depend on byond time.
#define REALTIMEOFDAY (world.timeofday + (MIDNIGHT_ROLLOVER * MIDNIGHT_ROLLOVER_CHECK))
#define MIDNIGHT_ROLLOVER_CHECK ( GLOB.rollovercheck_last_timeofday != world.timeofday ? update_midnight_rollover() : GLOB.midnight_rollovers )
#define PI 3.1415
#define SPEED_OF_LIGHT 3e8 //not exact but hey!
#define SPEED_OF_LIGHT_SQ 9e+16
#define INFINITY 1e31 //closer then enough
//atmos
#define R_IDEAL_GAS_EQUATION 8.31 //kPa*L/(K*mol)
#define ONE_ATMOSPHERE 101.325 //kPa
#define T0C 273.15 // 0degC
#define T20C 293.15 // 20degC
#define TCMB 2.7 // -270.3degC
//"fancy" math for calculating time in ms from tick_usage percentage and the length of ticks
//percent_of_tick_used * (ticklag * 100(to convert to ms)) / 100(percent ratio)
//collapsed to percent_of_tick_used * tick_lag
#define TICK_DELTA_TO_MS(percent_of_tick_used) ((percent_of_tick_used) * world.tick_lag)
#define TICK_USAGE_TO_MS(starting_tickusage) (TICK_DELTA_TO_MS(TICK_USAGE_REAL - starting_tickusage))
#define PERCENT(val) (round(val*100, 0.1))
#define CLAMP01(x) (Clamp(x, 0, 1))
//time of day but automatically adjusts to the server going into the next day within the same round.
//for when you need a reliable time number that doesn't depend on byond time.
#define REALTIMEOFDAY (world.timeofday + (MIDNIGHT_ROLLOVER * MIDNIGHT_ROLLOVER_CHECK))
#define MIDNIGHT_ROLLOVER_CHECK ( GLOB.rollovercheck_last_timeofday != world.timeofday ? update_midnight_rollover() : GLOB.midnight_rollovers )
+15 -3
View File
@@ -315,9 +315,16 @@ GLOBAL_LIST_INIT(ghost_others_options, list(GHOST_OTHERS_SIMPLE, GHOST_OTHERS_DE
#define APPEARANCE_CONSIDER_ALPHA ~RESET_ALPHA
#define APPEARANCE_LONG_GLIDE LONG_GLIDE
// 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
#ifndef PIXEL_SCALE
#define PIXEL_SCALE 0
#if DM_VERSION >= 512
#error HEY, PIXEL_SCALE probably exists now, remove this gross ass shim.
#endif
#endif
// Consider these images/atoms as part of the UI/HUD
#define APPEARANCE_UI_IGNORE_ALPHA RESET_COLOR|RESET_TRANSFORM|NO_CLIENT_COLOR|RESET_ALPHA|PIXEL_SCALE
#define APPEARANCE_UI RESET_COLOR|RESET_TRANSFORM|NO_CLIENT_COLOR
//Just space
#define SPACE_ICON_STATE "[((x + y) ^ ~(x * y) + z) % 25]"
@@ -441,3 +448,8 @@ GLOBAL_LIST_INIT(ghost_others_options, list(GHOST_OTHERS_SIMPLE, GHOST_OTHERS_DE
#define BEAT_NONE 0
#define BEAT_CHANNEL 150
//http://www.byond.com/docs/ref/info.html#/atom/var/mouse_opacity
#define MOUSE_OPACITY_TRANSPARENT 0
#define MOUSE_OPACITY_ICON 1
#define MOUSE_OPACITY_OPAQUE 2
+10 -6
View File
@@ -65,6 +65,12 @@
#define NUTRITION_LEVEL_HUNGRY 250
#define NUTRITION_LEVEL_STARVING 150
//Disgust levels for humans
#define DISGUST_LEVEL_MAXEDOUT 150
#define DISGUST_LEVEL_DISGUSTED 75
#define DISGUST_LEVEL_VERYGROSS 50
#define DISGUST_LEVEL_GROSS 25
//Slime evolution threshold. Controls how fast slimes can split/grow
#define SLIME_EVOLUTION_THRESHOLD 10
@@ -91,13 +97,11 @@
#define AI_IDLE 2
#define AI_OFF 3
//determines if a mob can smash through it
#define ENVIRONMENT_SMASH_NONE 0
#define ENVIRONMENT_SMASH_STRUCTURES 1
#define ENVIRONMENT_SMASH_WALLS 2
#define ENVIRONMENT_SMASH_RWALLS 3
#define ENVIRONMENT_SMASH_STRUCTURES 1 //crates, lockers, ect
#define ENVIRONMENT_SMASH_WALLS 2 //walls
#define ENVIRONMENT_SMASH_RWALLS 4 //rwalls
//SNPCs
+4 -4
View File
@@ -2,10 +2,10 @@
#define LIQUID 2
#define GAS 3
#define INJECTABLE 1024 //Makes reagents addable through droppers and syringes
#define DRAWABLE 2048 //If a syringe can draw from it
#define OPENCONTAINER 4096 //Is an open container for chemistry purposes
#define TRANSPARENT 8192 //Used for non-open containers which you still want to be able to see the reagents off.
#define INJECTABLE_1 1024 //Makes reagents addable through droppers and syringes
#define DRAWABLE_1 2048 //If a syringe can draw from it
#define OPENCONTAINER_1 4096 //Is an open container for chemistry purposes
#define TRANSPARENT_1 8192 //Used for non-open containers which you still want to be able to see the reagents off.
#define TOUCH 1 //splashing
#define INGEST 2 //ingestion
+1 -1
View File
@@ -53,7 +53,7 @@
#define ENGINE_COEFF_MAX 2
#define ENGINE_DEFAULT_MAXSPEED_ENGINES 5
//Docking error flags
//Docking error flags_1
#define DOCKING_SUCCESS 0
#define DOCKING_COMPLETE 1
#define DOCKING_BLOCKED 2
+1 -1
View File
@@ -25,6 +25,6 @@
//for clothing visor toggles, these determine which vars to toggle
#define VISOR_FLASHPROTECT 1
#define VISOR_TINT 2
#define VISOR_VISIONFLAGS 4 //all following flags only matter for glasses
#define VISOR_VISIONFLAGS 4 //all following flags_1 only matter for glasses
#define VISOR_DARKNESSVIEW 8
#define VISOR_INVISVIEW 16
+2
View File
@@ -42,6 +42,8 @@
#define STATUS_EFFECT_BELLIGERENT /datum/status_effect/belligerent //forces the affected to walk, doing damage if they try to run
#define STATUS_EFFECT_GEISTRACKER /datum/status_effect/geis_tracker //if you're using geis, this tracks that and keeps you from using scripture
#define STATUS_EFFECT_MANIAMOTOR /datum/status_effect/maniamotor //disrupts, damages, and confuses the affected as long as they're in range of the motor
#define MAX_MANIA_SEVERITY 100 //how high the mania severity can go
#define MANIA_DAMAGE_TO_CONVERT 90 //how much damage is required before it'll convert affected targets
-7
View File
@@ -1,7 +0,0 @@
#define TICK_LIMIT_RUNNING 80
#define TICK_LIMIT_TO_RUN 78
#define TICK_LIMIT_MC 70
#define TICK_LIMIT_MC_INIT_DEFAULT 98
#define TICK_CHECK ( world.tick_usage > Master.current_ticklimit )
#define CHECK_TICK if TICK_CHECK stoplag()
+1 -2
View File
@@ -97,8 +97,7 @@
WRITE_FILE(GLOB.world_game_log, "\[[time_stamp()]]CHAT: [text]")
/proc/log_sql(text)
if(config.sql_enabled)
WRITE_FILE(GLOB.world_game_log, "\[[time_stamp()]]SQL: [text]")
WRITE_FILE(GLOB.sql_error_log, "\[[time_stamp()]]SQL: [text]")
//This replaces world.log so it displays both in DD and the file
/proc/log_world(text)
-4
View File
@@ -1,4 +0,0 @@
#define HAS_SECONDARY_FLAG(atom, sflag) (atom.secondary_flags ? atom.secondary_flags[sflag] : FALSE)
#define SET_SECONDARY_FLAG(atom, sflag) if(!atom.secondary_flags) { atom.secondary_flags = list(); } atom.secondary_flags[sflag] = TRUE;
#define CLEAR_SECONDARY_FLAG(atom, sflag) if(atom.secondary_flags) atom.secondary_flags[sflag] = null
#define TOGGLE_SECONDARY_FLAG(atom, sflag) if(HAS_SECONDARY_FLAG(atom, sflag)) { CLEAR_SECONDARY_FLAG(atom, sflag); } else {SET_SECONDARY_FLAG(atom, sflag) ; }
+1 -1
View File
@@ -164,7 +164,7 @@
. = list()
while(processing_list.len)
var/atom/A = processing_list[1]
if(A.flags & HEAR)
if(A.flags_1 & HEAR_1)
. += A
processing_list.Cut(1, 2)
processing_list += A.contents
+1 -1
View File
@@ -20,7 +20,7 @@
A non null 'fixed_underlay' list var will skip copying the previous turf appearance and always use the list. If the list is
not set properly, the underlay will default to regular floor plating.
To see an example of a diagonal wall, see '/turf/closed/wall/shuttle' and its subtypes.
To see an example of a diagonal wall, see '/turf/closed/wall/mineral/titanium' and its subtypes.
*/
//Redefinitions of the diagonal directions so they can be stored in one var without conflicts
+4 -4
View File
@@ -978,19 +978,19 @@ GLOBAL_LIST_EMPTY(friendly_animal_types)
// Used to make the frozen item visuals for Freon.
if(resistance_flags & FREEZE_PROOF)
return
if(!HAS_SECONDARY_FLAG(src, FROZEN))
if(!(flags_2 & FROZEN_2))
name = "frozen [name]"
add_atom_colour(list(FROZEN_RED_COLOR, FROZEN_GREEN_COLOR, FROZEN_BLUE_COLOR, rgb(0,0,0)), TEMPORARY_COLOUR_PRIORITY)
alpha -= 25
SET_SECONDARY_FLAG(src, FROZEN)
flags_2 |= FROZEN_2
//Assumes already frozed
/obj/proc/make_unfrozen()
if(HAS_SECONDARY_FLAG(src, FROZEN))
if(flags_2 & FROZEN_2)
name = replacetext(name, "frozen ", "")
remove_atom_colour(TEMPORARY_COLOUR_PRIORITY, list(FROZEN_RED_COLOR, FROZEN_GREEN_COLOR, FROZEN_BLUE_COLOR, rgb(0,0,0)))
alpha += 25
CLEAR_SECONDARY_FLAG(src, FROZEN)
flags_2 &= ~FROZEN_2
#undef FROZEN_RED_COLOR
#undef FROZEN_GREEN_COLOR
+1 -1
View File
@@ -40,7 +40,7 @@
for(var/obj/machinery/computer/communications/C in GLOB.machines)
if(!(C.stat & (BROKEN|NOPOWER)) && C.z == ZLEVEL_STATION)
var/obj/item/weapon/paper/P = new /obj/item/weapon/paper(C.loc)
var/obj/item/paper/P = new /obj/item/paper(C.loc)
P.name = "paper - '[title]'"
P.info = text
C.messagetitle.Add("[title]")
+4 -2
View File
@@ -72,7 +72,9 @@
return .
//Splits the text of a file at seperator and returns them in a list.
/world/proc/file2list(filename, seperator="\n")
/world/proc/file2list(filename, seperator="\n", trim = TRUE)
if (trim)
return splittext(trim(file2text(filename)),seperator)
return splittext(file2text(filename),seperator)
//Turns a direction into text
@@ -551,4 +553,4 @@
return /atom
else
return /datum
return text2path(copytext(string_type, 1, last_slash))
return text2path(copytext(string_type, 1, last_slash))
+31 -3
View File
@@ -357,6 +357,17 @@ Turf and target are separate in case you want to teleport some distance from a t
var/M = E/(SPEED_OF_LIGHT_SQ)
return M
//Takes the value of energy used/produced/ect.
//Returns a text value of that number in W, kW, MW, or GW.
/proc/DisplayPower(var/powerused)
if(powerused < 1000) //Less than a kW
return "[powerused] W"
else if(powerused < 1000000) //Less than a MW
return "[round((powerused * 0.001),0.01)] kW"
else if(powerused < 1000000000) //Less than a GW
return "[round((powerused * 0.000001),0.001)] MW"
return "[round((powerused * 0.000000001),0.0001)] GW"
/proc/key_name(whom, include_link = null, include_name = 1)
var/mob/M
var/client/C
@@ -605,6 +616,18 @@ Turf and target are separate in case you want to teleport some distance from a t
GLOB.sortedAreas.Add(src)
sortTim(GLOB.sortedAreas, /proc/cmp_name_asc)
//Takes: Area type as a text string from a variable.
//Returns: Instance for the area in the world.
/proc/get_area_instance_from_text(areatext)
var/areainstance = null
if(istext(areatext))
areatext = text2path(areatext)
for(var/V in GLOB.sortedAreas)
var/area/A = V
if(A.type == areatext)
areainstance = V
return areainstance
//Takes: Area type as text string or as typepath OR an instance of the area.
//Returns: A list of all areas of that type in the world.
/proc/get_areas(areatype, subtypes=TRUE)
@@ -797,7 +820,7 @@ GLOBAL_LIST_INIT(WALLITEMS, typecacheof(list(
/obj/machinery/status_display, /obj/machinery/requests_console, /obj/machinery/light_switch, /obj/structure/sign,
/obj/machinery/newscaster, /obj/machinery/firealarm, /obj/structure/noticeboard, /obj/machinery/button,
/obj/machinery/computer/security/telescreen, /obj/machinery/embedded_controller/radio/simple_vent_controller,
/obj/item/weapon/storage/secure/safe, /obj/machinery/door_timer, /obj/machinery/flasher, /obj/machinery/keycard_auth,
/obj/item/storage/secure/safe, /obj/machinery/door_timer, /obj/machinery/flasher, /obj/machinery/keycard_auth,
/obj/structure/mirror, /obj/structure/fireaxecabinet, /obj/machinery/computer/security/telescreen/entertainment,
/obj/structure/sign/picture_frame
)))
@@ -1218,7 +1241,7 @@ proc/pick_closest_path(value, list/matches = get_fancy_list_of_atom_types())
//Increases delay as the server gets more overloaded,
//as sleeps aren't cheap and sleeping only to wake up and sleep again is wasteful
#define DELTA_CALC max(((max(world.tick_usage, world.cpu) / 100) * max(Master.sleep_delta,1)), 1)
#define DELTA_CALC max(((max(TICK_USAGE, world.cpu) / 100) * max(Master.sleep_delta,1)), 1)
/proc/stoplag()
if (!Master || !(Master.current_runlevel & RUNLEVELS_DEFAULT))
@@ -1230,7 +1253,7 @@ proc/pick_closest_path(value, list/matches = get_fancy_list_of_atom_types())
. += round(i*DELTA_CALC)
sleep(i*world.tick_lag*DELTA_CALC)
i *= 2
while (world.tick_usage > min(TICK_LIMIT_TO_RUN, Master.current_ticklimit))
while (TICK_USAGE > min(TICK_LIMIT_TO_RUN, Master.current_ticklimit))
#undef DELTA_CALC
@@ -1254,6 +1277,7 @@ proc/pick_closest_path(value, list/matches = get_fancy_list_of_atom_types())
#define RANDOM_COLOUR (rgb(rand(0,255),rand(0,255),rand(0,255)))
#define QDEL_IN(item, time) addtimer(CALLBACK(GLOBAL_PROC, .proc/qdel, item), time, TIMER_STOPPABLE)
#define QDEL_IN_CLIENT_TIME(item, time) addtimer(CALLBACK(GLOBAL_PROC, .proc/qdel, item), time, TIMER_STOPPABLE | TIMER_CLIENT_TIME)
#define QDEL_NULL(item) qdel(item); item = null
#define QDEL_LIST(L) if(L) { for(var/I in L) qdel(I); L.Cut(); }
#define QDEL_LIST_IN(L, time) addtimer(CALLBACK(GLOBAL_PROC, .proc/______qdel_list_wrapper, L), time, TIMER_STOPPABLE)
@@ -1441,3 +1465,7 @@ GLOBAL_PROTECT(valid_HTTPSGet)
var/temp = bitfield - ((bitfield>>1)&46811) - ((bitfield>>2)&37449) //0133333 and 0111111 respectively
temp = ((temp + (temp>>3))&29127) % 63 //070707
return temp
//checks if a turf is in the planet z list.
/proc/turf_z_is_planet(turf/T)
return GLOB.z_is_planet["[T.z]"]
+2 -2
View File
@@ -52,7 +52,7 @@
#define AI_CAMERA_LUMINOSITY 5
#define AI_VOX 1 // Comment out if you don't want VOX to be enabled and have players download the voice sounds.
//Additional code for the above flags.
//Additional code for the above flags_1.
#ifdef TESTING
#warn compiling in TESTING mode. testing() debug messages will be visible.
#endif
@@ -69,7 +69,7 @@
#error You need version 511 or higher
#endif
//Update this whenever the db schema changes
//Update this whenever the db schema changes
//make sure you add an update to the schema_version stable in the db changelog
#define DB_MAJOR_VERSION 3
#define DB_MINOR_VERSION 1
+38 -38
View File
@@ -45,7 +45,7 @@ GLOBAL_LIST_INIT(maintenance_loot, list(
/obj/item/device/multitool = 2,
/obj/item/device/radio/off = 2,
/obj/item/device/t_scanner = 5,
/obj/item/weapon/airlock_painter = 1,
/obj/item/airlock_painter = 1,
/obj/item/stack/cable_coil/random = 4,
/obj/item/stack/cable_coil/random/five = 6,
/obj/item/stack/medical/bruise_pack = 1,
@@ -56,54 +56,54 @@ GLOBAL_LIST_INIT(maintenance_loot, list(
/obj/item/stack/sheet/metal/twenty = 1,
/obj/item/stack/sheet/mineral/plasma = 1,
/obj/item/stack/sheet/rglass = 1,
/obj/item/weapon/book/manual/wiki/engineering_construction = 1,
/obj/item/weapon/book/manual/wiki/engineering_hacking = 1,
/obj/item/book/manual/wiki/engineering_construction = 1,
/obj/item/book/manual/wiki/engineering_hacking = 1,
/obj/item/clothing/head/cone = 1,
/obj/item/weapon/coin/silver = 1,
/obj/item/weapon/coin/twoheaded = 1,
/obj/item/weapon/poster/random_contraband = 1,
/obj/item/weapon/poster/random_official = 1,
/obj/item/weapon/crowbar = 1,
/obj/item/weapon/crowbar/red = 1,
/obj/item/weapon/extinguisher = 11,
//obj/item/weapon/gun/ballistic/revolver/russian = 1, //disabled until lootdrop is a proper world proc.
/obj/item/weapon/hand_labeler = 1,
/obj/item/weapon/paper/crumpled = 1,
/obj/item/weapon/pen = 1,
/obj/item/weapon/reagent_containers/spray/pestspray = 1,
/obj/item/weapon/reagent_containers/glass/rag = 3,
/obj/item/weapon/stock_parts/cell = 3,
/obj/item/weapon/storage/belt/utility = 2,
/obj/item/weapon/storage/box = 2,
/obj/item/weapon/storage/box/cups = 1,
/obj/item/weapon/storage/box/donkpockets = 1,
/obj/item/weapon/storage/box/lights/mixed = 3,
/obj/item/weapon/storage/box/hug/medical = 1,
/obj/item/weapon/storage/fancy/cigarettes/dromedaryco = 1,
/obj/item/weapon/storage/toolbox/mechanical = 1,
/obj/item/weapon/screwdriver = 3,
/obj/item/weapon/tank/internals/emergency_oxygen = 2,
/obj/item/weapon/vending_refill/cola = 1,
/obj/item/weapon/weldingtool = 3,
/obj/item/weapon/wirecutters = 1,
/obj/item/weapon/wrench = 4,
/obj/item/weapon/relic = 3,
/obj/item/coin/silver = 1,
/obj/item/coin/twoheaded = 1,
/obj/item/poster/random_contraband = 1,
/obj/item/poster/random_official = 1,
/obj/item/crowbar = 1,
/obj/item/crowbar/red = 1,
/obj/item/extinguisher = 11,
//obj/item/gun/ballistic/revolver/russian = 1, //disabled until lootdrop is a proper world proc.
/obj/item/hand_labeler = 1,
/obj/item/paper/crumpled = 1,
/obj/item/pen = 1,
/obj/item/reagent_containers/spray/pestspray = 1,
/obj/item/reagent_containers/glass/rag = 3,
/obj/item/stock_parts/cell = 3,
/obj/item/storage/belt/utility = 2,
/obj/item/storage/box = 2,
/obj/item/storage/box/cups = 1,
/obj/item/storage/box/donkpockets = 1,
/obj/item/storage/box/lights/mixed = 3,
/obj/item/storage/box/hug/medical = 1,
/obj/item/storage/fancy/cigarettes/dromedaryco = 1,
/obj/item/storage/toolbox/mechanical = 1,
/obj/item/screwdriver = 3,
/obj/item/tank/internals/emergency_oxygen = 2,
/obj/item/vending_refill/cola = 1,
/obj/item/weldingtool = 3,
/obj/item/wirecutters = 1,
/obj/item/wrench = 4,
/obj/item/relic = 3,
/obj/item/weaponcrafting/receiver = 2,
/obj/item/clothing/head/cone = 2,
/obj/item/weapon/grenade/smokebomb = 2,
/obj/item/grenade/smokebomb = 2,
/obj/item/device/geiger_counter = 3,
/obj/item/weapon/reagent_containers/food/snacks/grown/citrus/orange = 1,
/obj/item/reagent_containers/food/snacks/grown/citrus/orange = 1,
/obj/item/device/radio/headset = 1,
/obj/item/device/assembly/infra = 1,
/obj/item/device/assembly/igniter = 2,
/obj/item/device/assembly/signaler = 2,
/obj/item/device/assembly/mousetrap = 2,
/obj/item/weapon/reagent_containers/syringe = 2,
/obj/item/reagent_containers/syringe = 2,
/obj/item/clothing/gloves/color/random = 8,
/obj/item/clothing/shoes/laceup = 1,
/obj/item/weapon/storage/secure/briefcase = 3,
/obj/item/weapon/storage/toolbox/artistic = 2,
/obj/item/storage/secure/briefcase = 3,
/obj/item/storage/toolbox/artistic = 2,
/obj/item/toy/eightball = 1,
/obj/item/weapon/storage/daki = 3,
/obj/item/storage/daki = 3,
"" = 3
))
+2
View File
@@ -35,3 +35,5 @@ GLOBAL_LIST_EMPTY(wire_color_directory)
GLOBAL_LIST_EMPTY(wire_name_directory)
GLOBAL_LIST_EMPTY(ai_status_displays)
GLOBAL_LIST_EMPTY(mob_spawners) // All mob_spawn objects
+1
View File
@@ -6,5 +6,6 @@
#define POLL_IGNORE_ALIEN_LARVA "alien_larva"
#define POLL_IGNORE_CLOCKWORK_MARAUDER "clockwork_marauder"
#define POLL_IGNORE_SYNDICATE "syndicate"
#define POLL_IGNORE_HOLOPARASITE "holoparasite"
GLOBAL_LIST_EMPTY(poll_ignore)
+2
View File
@@ -12,6 +12,8 @@ GLOBAL_VAR(round_id)
GLOBAL_PROTECT(round_id)
GLOBAL_VAR(config_error_log)
GLOBAL_PROTECT(config_error_log)
GLOBAL_VAR(sql_error_log)
GLOBAL_PROTECT(sql_error_log)
GLOBAL_LIST_EMPTY(bombers)
GLOBAL_PROTECT(bombers)
+14 -15
View File
@@ -25,7 +25,7 @@
* If you are diagonally adjacent, ensure you can pass through at least one of the mutually adjacent square.
* Passing through in this case ignores anything with the LETPASSTHROW pass flag, such as tables, racks, and morgue trays.
*/
/turf/Adjacent(atom/neighbor, atom/target = null, atom/movable/mover = null)
/turf/Adjacent(atom/neighbor, atom/target = null, atom/movable/mover = null)
var/turf/T0 = get_turf(neighbor)
if(T0 == src) //same turf
@@ -37,7 +37,7 @@
// Non diagonal case
if(T0.x == x || T0.y == y)
// Check for border blockages
return T0.ClickCross(get_dir(T0,src), border_only = 1, target_atom = target, mover = mover) && src.ClickCross(get_dir(src,T0), border_only = 1, target_atom = target, mover = mover)
return T0.ClickCross(get_dir(T0,src), border_only = 1, target_atom = target, mover = mover) && src.ClickCross(get_dir(src,T0), border_only = 1, target_atom = target, mover = mover)
// Diagonal case
var/in_dir = get_dir(T0,src) // eg. northwest (1+8) = 9 (00001001)
@@ -45,16 +45,16 @@
var/d2 = in_dir&12 // eg. west (1+8)&12 (0000 1100) = 8 (0000 1000)
for(var/d in list(d1,d2))
if(!T0.ClickCross(d, border_only = 1, target_atom = target, mover = mover))
if(!T0.ClickCross(d, border_only = 1, target_atom = target, mover = mover))
continue // could not leave T0 in that direction
var/turf/T1 = get_step(T0,d)
if(!T1 || T1.density)
continue
if(!T1.ClickCross(get_dir(T1,src), border_only = 0, target_atom = target, mover = mover) || !T1.ClickCross(get_dir(T1,T0), border_only = 0, target_atom = target, mover = mover))
if(!T1 || T1.density)
continue
if(!T1.ClickCross(get_dir(T1,src), border_only = 0, target_atom = target, mover = mover) || !T1.ClickCross(get_dir(T1,T0), border_only = 0, target_atom = target, mover = mover))
continue // couldn't enter or couldn't leave T1
if(!src.ClickCross(get_dir(src,T1), border_only = 1, target_atom = target, mover = mover))
if(!src.ClickCross(get_dir(src,T1), border_only = 1, target_atom = target, mover = mover))
continue // could not enter src
return 1 // we don't care about our own density
@@ -70,7 +70,7 @@
return TRUE
if(!isturf(loc))
return FALSE
if(loc.Adjacent(neighbor,target = neighbor, mover = src))
if(loc.Adjacent(neighbor,target = neighbor, mover = src))
return TRUE
return FALSE
@@ -85,20 +85,19 @@
/*
This checks if you there is uninterrupted airspace between that turf and this one.
This is defined as any dense ON_BORDER object, or any dense object without LETPASSTHROW.
This is defined as any dense ON_BORDER_1 object, or any dense object without LETPASSTHROW.
The border_only flag allows you to not objects (for source and destination squares)
*/
/turf/proc/ClickCross(target_dir, border_only, target_atom = null, atom/movable/mover = null)
/turf/proc/ClickCross(target_dir, border_only, target_atom = null, atom/movable/mover = null)
for(var/obj/O in src)
if((mover && O.CanPass(mover,get_step(src,target_dir))) || (!mover && !O.density))
continue
if(O == target_atom || (O.pass_flags & LETPASSTHROW)) //check if there's a dense object present on the turf
if((mover && O.CanPass(mover,get_step(src,target_dir))) || (!mover && !O.density))
continue
if(O == target_atom || O == mover || (O.pass_flags & LETPASSTHROW)) //check if there's a dense object present on the turf
continue // LETPASSTHROW is used for anything you can click through (or the firedoor special case, see above)
if( O.flags&ON_BORDER) // windows are on border, check them first
if( O.flags_1&ON_BORDER_1) // windows are on border, check them first
if( O.dir & target_dir || O.dir & (O.dir-1) ) // full tile windows are just diagonals mechanically
return 0 //O.dir&(O.dir-1) is false for any cardinal direction, but true for diagonal ones
else if( !border_only ) // dense, not on border, cannot pass over
return 0
return 1
+2 -2
View File
@@ -55,10 +55,10 @@
/obj/item
var/canMouseDown = FALSE
/obj/item/weapon/gun
/obj/item/gun
var/automatic = 0 //can gun use it, 0 is no, anything above 0 is the delay between clicks in ds
/obj/item/weapon/gun/CanItemAutoclick(object, location, params)
/obj/item/gun/CanItemAutoclick(object, location, params)
. = automatic
/atom/proc/IsAutoclickable()
+6 -6
View File
@@ -144,7 +144,7 @@
else
RangedAttack(A,params)
//Is the atom obscured by a PREVENT_CLICK_UNDER object above it
//Is the atom obscured by a PREVENT_CLICK_UNDER_1 object above it
/atom/proc/IsObscured()
if(!isturf(loc)) //This only makes sense for things directly on turfs for now
return FALSE
@@ -152,13 +152,13 @@
if(!T)
return FALSE
for(var/atom/movable/AM in T)
if(AM.flags & PREVENT_CLICK_UNDER && AM.density && AM.layer > layer)
if(AM.flags_1 & PREVENT_CLICK_UNDER_1 && AM.density && AM.layer > layer)
return TRUE
return FALSE
/turf/IsObscured()
for(var/atom/movable/AM in src)
if(AM.flags & PREVENT_CLICK_UNDER && AM.density)
if(AM.flags_1 & PREVENT_CLICK_UNDER_1 && AM.density)
return TRUE
return FALSE
@@ -180,7 +180,7 @@
/atom/proc/CanReachStorage(atom/target,user,depth)
return FALSE
/obj/item/weapon/storage/CanReachStorage(atom/target,user,depth)
/obj/item/storage/CanReachStorage(atom/target,user,depth)
while(target && depth > 0)
target = target.loc
depth--
@@ -355,7 +355,7 @@
else
user.listed_turf = T
user.client.statpanel = T.name
return
user.Stat() //responsive ui pls
/mob/proc/TurfAdjacent(turf/T)
return T.Adjacent(src)
@@ -434,7 +434,7 @@
icon = 'icons/mob/screen_gen.dmi'
icon_state = "flash"
plane = CLICKCATCHER_PLANE
mouse_opacity = 2
mouse_opacity = MOUSE_OPACITY_OPAQUE
screen_loc = "CENTER"
/obj/screen/click_catcher/proc/UpdateGreed(view_size_x = 7, view_size_y = 7)
+20 -19
View File
@@ -1,19 +1,20 @@
/*
MouseDrop:
Called on the atom you're dragging. In a lot of circumstances we want to use the
recieving object instead, so that's the default action. This allows you to drag
almost anything into a trash can.
*/
/atom/MouseDrop(atom/over, src_location, over_location, src_control, over_control, params)
if(!usr || !over) return
if(over == src)
return usr.client.Click(src, src_location, src_control, params)
if(!Adjacent(usr) || !over.Adjacent(usr)) return // should stop you from dragging through windows
over.MouseDrop_T(src,usr)
return
// recieve a mousedrop
/atom/proc/MouseDrop_T(atom/dropping, mob/user)
return
/*
MouseDrop:
Called on the atom you're dragging. In a lot of circumstances we want to use the
recieving object instead, so that's the default action. This allows you to drag
almost anything into a trash can.
*/
/atom/MouseDrop(atom/over, src_location, over_location, src_control, over_control, params)
if(!usr || !over)
return
if(over == src)
return usr.client.Click(src, src_location, src_control, params)
if(!Adjacent(usr) || !over.Adjacent(usr)) return // should stop you from dragging through windows
over.MouseDrop_T(src,usr)
return
// recieve a mousedrop
/atom/proc/MouseDrop_T(atom/dropping, mob/user)
return
+16 -1
View File
@@ -92,7 +92,7 @@
icon_state = "default"
name = "Alert"
desc = "Something seems to have gone wrong with this alert, so report this bug please"
mouse_opacity = 1
mouse_opacity = MOUSE_OPACITY_ICON
var/timeout = 0 //If set to a number, this alert will clear itself after that many deciseconds
var/severity = 0
var/alerttooltipstyle = ""
@@ -166,6 +166,21 @@
desc = "You're severely malnourished. The hunger pains make moving around a chore."
icon_state = "starving"
/obj/screen/alert/gross
name = "Grossed out."
desc = "That was kind of gross..."
icon_state = "gross"
/obj/screen/alert/verygross
name = "Very grossed out."
desc = "I'm not feeling very well.."
icon_state = "gross2"
/obj/screen/alert/disgusted
name = "DISGUSTED"
desc = "ABSOLUTELY DISGUSTIN'"
icon_state = "gross3"
/obj/screen/alert/hot
name = "Too Hot"
desc = "You're flaming hot! Get somewhere cooler and take off any insulating clothing like a fire suit."
+1 -1
View File
@@ -130,7 +130,7 @@
blobpwrdisplay.name = "blob power"
blobpwrdisplay.icon_state = "block"
blobpwrdisplay.screen_loc = ui_health
blobpwrdisplay.mouse_opacity = 0
blobpwrdisplay.mouse_opacity = MOUSE_OPACITY_TRANSPARENT
blobpwrdisplay.layer = ABOVE_HUD_LAYER
blobpwrdisplay.plane = ABOVE_HUD_PLANE
infodisplay += blobpwrdisplay
+1 -1
View File
@@ -67,7 +67,7 @@
screen_loc = "CENTER-7,CENTER-7"
layer = FULLSCREEN_LAYER
plane = FULLSCREEN_PLANE
mouse_opacity = 0
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
var/severity = 0
var/show_when_dead = FALSE
+1 -1
View File
@@ -243,7 +243,7 @@
blend_mode = BLEND_ADD
plane = PLANE_SPACE_PARALLAX
screen_loc = "CENTER-7,CENTER-7"
mouse_opacity = 0
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
/obj/screen/parallax_layer/Initialize(mapload, view)
+2 -2
View File
@@ -26,13 +26,13 @@
name = "lighting plane master"
plane = LIGHTING_PLANE
blend_mode = BLEND_MULTIPLY
mouse_opacity = 0
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
/obj/screen/plane_master/parallax
name = "parallax plane master"
plane = PLANE_SPACE_PARALLAX
blend_mode = BLEND_MULTIPLY
mouse_opacity = FALSE
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
/obj/screen/plane_master/parallax_white
name = "parallax whitifier plane master"
+1 -1
View File
@@ -13,7 +13,7 @@
if(..())
return
var/mob/living/silicon/robot/R = usr
if(R.module.type != /obj/item/weapon/robot_module)
if(R.module.type != /obj/item/robot_module)
R.hud_used.toggle_show_robot_modules()
return 1
R.pick_module()
+16 -16
View File
@@ -33,7 +33,7 @@
/obj/screen/text
icon = null
icon_state = null
mouse_opacity = 0
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
screen_loc = "CENTER-7,CENTER-7"
maptext_height = 480
maptext_width = 480
@@ -182,8 +182,8 @@
name = "close"
/obj/screen/close/Click()
if(istype(master, /obj/item/weapon/storage))
var/obj/item/weapon/storage/S = master
if(istype(master, /obj/item/storage))
var/obj/item/storage/S = master
S.close(usr)
return 1
@@ -258,31 +258,31 @@
var/obj/item/clothing/mask/M = C.wear_mask
if(M.mask_adjusted) // if mask on face but pushed down
M.adjustmask(C) // adjust it back
if( !(M.flags & MASKINTERNALS) )
if( !(M.flags_1 & MASKINTERNALS_1) )
to_chat(C, "<span class='warning'>You are not wearing an internals mask!</span>")
return
var/obj/item/I = C.is_holding_item_of_type(/obj/item/weapon/tank)
var/obj/item/I = C.is_holding_item_of_type(/obj/item/tank)
if(I)
to_chat(C, "<span class='notice'>You are now running on internals from the [I] on your [C.get_held_index_name(C.get_held_index_of_item(I))].</span>")
C.internal = I
else if(ishuman(C))
var/mob/living/carbon/human/H = C
if(istype(H.s_store, /obj/item/weapon/tank))
if(istype(H.s_store, /obj/item/tank))
to_chat(H, "<span class='notice'>You are now running on internals from the [H.s_store] on your [H.wear_suit].</span>")
H.internal = H.s_store
else if(istype(H.belt, /obj/item/weapon/tank))
else if(istype(H.belt, /obj/item/tank))
to_chat(H, "<span class='notice'>You are now running on internals from the [H.belt] on your belt.</span>")
H.internal = H.belt
else if(istype(H.l_store, /obj/item/weapon/tank))
else if(istype(H.l_store, /obj/item/tank))
to_chat(H, "<span class='notice'>You are now running on internals from the [H.l_store] in your left pocket.</span>")
H.internal = H.l_store
else if(istype(H.r_store, /obj/item/weapon/tank))
else if(istype(H.r_store, /obj/item/tank))
to_chat(H, "<span class='notice'>You are now running on internals from the [H.r_store] in your right pocket.</span>")
H.internal = H.r_store
//Separate so CO2 jetpacks are a little less cumbersome.
if(!C.internal && istype(C.back, /obj/item/weapon/tank))
if(!C.internal && istype(C.back, /obj/item/tank))
to_chat(C, "<span class='notice'>You are now running on internals from the [C.back] on your back.</span>")
C.internal = C.back
@@ -468,7 +468,7 @@
name = "dmg"
blend_mode = BLEND_MULTIPLY
screen_loc = "CENTER-7,CENTER-7"
mouse_opacity = 0
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
layer = UI_DAMAGE_LAYER
plane = FULLSCREEN_PLANE
@@ -494,7 +494,7 @@
name = "blob health"
icon_state = "block"
screen_loc = ui_internal
mouse_opacity = 0
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
/obj/screen/healths/blob/naut
name = "health"
@@ -511,13 +511,13 @@
icon = 'icons/mob/guardian.dmi'
icon_state = "base"
screen_loc = ui_health
mouse_opacity = 0
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
/obj/screen/healths/clock
icon = 'icons/mob/actions.dmi'
icon_state = "bg_clock"
screen_loc = ui_health
mouse_opacity = 0
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
/obj/screen/healths/clock/gear
icon = 'icons/mob/clockwork_mobs.dmi'
@@ -529,13 +529,13 @@
icon = 'icons/mob/actions.dmi'
icon_state = "bg_revenant"
screen_loc = ui_health
mouse_opacity = 0
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
/obj/screen/healths/construct
icon = 'icons/mob/screen_construct.dmi'
icon_state = "artificer_health0"
screen_loc = ui_construct_health
mouse_opacity = 0
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
/obj/screen/healthdoll
name = "health doll"
+2 -2
View File
@@ -35,7 +35,7 @@
/obj/item/proc/attack(mob/living/M, mob/living/user)
if(flags & NOBLUDGEON)
if(flags_1 & NOBLUDGEON_1)
return
if(!force)
playsound(loc, 'sound/weapons/tap.ogg', get_clamped_volume(), 1, -1)
@@ -54,7 +54,7 @@
//the equivalent of the standard version of attack() but for object targets.
/obj/item/proc/attack_obj(obj/O, mob/living/user)
if(flags & NOBLUDGEON)
if(flags_1 & NOBLUDGEON_1)
return
user.changeNext_move(CLICK_CD_MELEE)
user.do_attack_animation(O)
+1 -1
View File
@@ -82,7 +82,7 @@
else
to_chat(user, "[src] has no destination.")
/obj/item/weapon/storage/attack_ghost(mob/user)
/obj/item/storage/attack_ghost(mob/user)
orient2hud(user)
show_to(user)
+1 -1
View File
@@ -68,7 +68,7 @@
desc = "Magic"
icon = 'icons/obj/magic.dmi'//Needs sprites
icon_state = "2"
flags = NOBLUDGEON | ABSTRACT | DROPDEL
flags_1 = NOBLUDGEON_1 | ABSTRACT_1 | DROPDEL_1
//item_state = null
w_class = WEIGHT_CLASS_GIGANTIC
layer = ABOVE_HUD_LAYER
+1 -1
View File
@@ -57,7 +57,7 @@ GLOBAL_LIST_EMPTY(cock_shapes_icons) //Associated list for names->icon_states fo
GLOBAL_LIST_EMPTY(breasts_size_list)
GLOBAL_LIST_EMPTY(breasts_shapes_list)
GLOBAL_LIST_EMPTY(vagina_shapes_list)
GLOBAL_LIST_INIT(cum_into_containers_list, list(/obj/item/weapon/reagent_containers/food/snacks/pie)) //Yer fuggin snowflake name list jfc
GLOBAL_LIST_INIT(cum_into_containers_list, list(/obj/item/reagent_containers/food/snacks/pie)) //Yer fuggin snowflake name list jfc
GLOBAL_LIST_INIT(dick_nouns, list("dick","cock","member","shaft"))
GLOBAL_LIST_INIT(cum_id_list,"semen")
GLOBAL_LIST_INIT(milk_id_list,"milk")
+5 -5
View File
@@ -287,7 +287,7 @@
setArousalLoss(min_arousal)
/mob/living/carbon/human/proc/mob_fill_container(obj/item/organ/genital/G, obj/item/weapon/reagent_containers/container, mb_time = 30) //For beaker-filling, beware the bartender
/mob/living/carbon/human/proc/mob_fill_container(obj/item/organ/genital/G, obj/item/reagent_containers/container, mb_time = 30) //For beaker-filling, beware the bartender
var/total_fluids = 0
var/datum/reagents/fluid_source = null
@@ -368,11 +368,11 @@
return input(src, "With whom?", "Sexual partner", null) in partners //pick one, default to null
/mob/living/carbon/human/proc/pick_climax_container()
var/obj/item/weapon/reagent_containers/SC = null
var/obj/item/reagent_containers/SC = null
var/list/containers_list = list()
for(var/obj/item/weapon/reagent_containers/container in held_items)
if(container.is_open_container() || istype(container, /obj/item/weapon/reagent_containers/food/snacks))
for(var/obj/item/reagent_containers/container in held_items)
if(container.is_open_container() || istype(container, /obj/item/reagent_containers/food/snacks))
containers_list += container
if(containers_list.len)
@@ -530,7 +530,7 @@
picked_organ = pick_climax_genitals() //Gotta be climaxable, not just masturbation, to fill with fluids.
if(picked_organ)
//Good, got an organ, time to pick a container
var/obj/item/weapon/reagent_containers/fluid_container = pick_climax_container()
var/obj/item/reagent_containers/fluid_container = pick_climax_container()
if(fluid_container)
mob_fill_container(picked_organ, fluid_container)
return
+3 -3
View File
@@ -1,9 +1,9 @@
//Will include consumable gene mods in the future.
/obj/item/weapon/genemod
/obj/item/genemod
name = "genetic modifier"
desc = "Microbodies which can grow, morph, or otherwise change an organism into something else."
icon = 'icons/obj/items.dmi'
icon = 'icons/obj/items_and_weapons.dmi'
icon_state = "dnainjector"
throw_speed = 3
throw_range = 5
@@ -18,5 +18,5 @@
var/used = 0
/obj/item/weapon/genemod/proc/use(mob/living/carbon/human/target)
/obj/item/genemod/proc/use(mob/living/carbon/human/target)
return
+5 -5
View File
@@ -1,4 +1,4 @@
/obj/item/weapon/gun/energy/laser/carbine
/obj/item/gun/energy/laser/carbine
name = "laser carbine"
desc = "A ruggedized laser carbine featuring much higher capacity and improved handling when compared to a normal laser gun."
icon = 'icons/obj/guns/cit_guns.dmi'
@@ -8,13 +8,13 @@
force = 10
throwforce = 10
ammo_type = list(/obj/item/ammo_casing/energy/lasergun)
cell_type = /obj/item/weapon/stock_parts/cell/lascarbine
cell_type = /obj/item/stock_parts/cell/lascarbine
resistance_flags = FIRE_PROOF | ACID_PROOF
/obj/item/weapon/gun/energy/laser/carbine/nopin
/obj/item/gun/energy/laser/carbine/nopin
pin = null
/obj/item/weapon/stock_parts/cell/lascarbine
/obj/item/stock_parts/cell/lascarbine
name = "laser carbine power supply"
maxcharge = 2500
@@ -25,5 +25,5 @@
req_tech = list("combat" = 5, "magnets" = 5, "powerstorage" = 4)
build_type = PROTOLATHE
materials = list(MAT_GOLD = 2500, MAT_METAL = 5000, MAT_GLASS = 5000)
build_path = /obj/item/weapon/gun/energy/laser/carbine/nopin
build_path = /obj/item/gun/energy/laser/carbine/nopin
category = list("Weapons")
+11 -11
View File
@@ -13,15 +13,15 @@
/obj/item/clothing/under/maid = 5,
/obj/item/clothing/under/stripper_pink = 5,
/obj/item/clothing/under/stripper_green = 5,
/obj/item/weapon/dildo/custom = 5
/obj/item/dildo/custom = 5
)
contraband = list(/obj/item/weapon/restraints/handcuffs/fake/kinky = 5,
contraband = list(/obj/item/restraints/handcuffs/fake/kinky = 5,
/obj/item/clothing/neck/petcollar = 5,
/obj/item/clothing/under/mankini = 1,
/obj/item/weapon/dildo/flared/huge = 1
/obj/item/dildo/flared/huge = 1
)
premium = list()
refill_canister = /obj/item/weapon/vending_refill/kink
refill_canister = /obj/item/vending_refill/kink
/obj/machinery/vending/nazivend
name = "Nazivend"
@@ -42,11 +42,11 @@
/obj/item/clothing/suit/officercoat = 10,
/obj/item/clothing/under/officeruniform = 10,
/obj/item/clothing/suit/space/hardsuit/nazi = 3,
/obj/item/weapon/gun/energy/plasma/MP40k = 4
/obj/item/gun/energy/plasma/MP40k = 4
)
premium = list()
refill_canister = /obj/item/weapon/vending_refill/nazi
refill_canister = /obj/item/vending_refill/nazi
/obj/machinery/vending/sovietvend
name = "KomradeVendtink"
@@ -70,11 +70,11 @@
/obj/item/clothing/suit/russofurcoat = 4,
/obj/item/clothing/head/russofurhat = 4,
/obj/item/clothing/suit/space/hardsuit/soviet = 3,
/obj/item/weapon/gun/energy/laser/LaserAK = 4
/obj/item/gun/energy/laser/LaserAK = 4
)
premium = list()
refill_canister = /obj/item/weapon/vending_refill/soviet
refill_canister = /obj/item/vending_refill/soviet
#undef STANDARD_CHARGE
@@ -82,19 +82,19 @@
#undef COIN_CHARGE
/obj/item/weapon/vending_refill/kink
/obj/item/vending_refill/kink
machine_name = "KinkMate"
icon_state = "refill_kink"
charges = list(8, 5, 0)// of 20 standard, 12 contraband, 0 premium
init_charges = list(8, 5, 0)
/obj/item/weapon/vending_refill/nazi
/obj/item/vending_refill/nazi
machine_name = "nazivend"
icon_state = "refill_nazi"
charges = list(33, 13, 0)
init_charges = list(33, 13, 0)
/obj/item/weapon/vending_refill/soviet
/obj/item/vending_refill/soviet
machine_name = "sovietvend"
icon_state = "refill_soviet"
charges = list(47, 7, 0)
@@ -0,0 +1,2 @@
//For custom items.
@@ -0,0 +1,61 @@
//Proc that does the actual loading of items to mob
/*Itemlists are formatted as
"[typepath]" = number_of_it_to_spawn
*/
#define DROP_TO_FLOOR 0
#define LOADING_TO_HUMAN 1
/proc/handle_roundstart_items(mob/living/M, ckey_override, job_override, special_override)
if(!istype(M) || (!M.ckey && !ckey_override) || (!M.mind && (!job_override || !special_override)))
return FALSE
return load_itemlist_to_mob(M, parse_custom_roundstart_items(ckey_override? ckey_override : M.ckey, M.name, job_override? job_override : M.mind.assigned_role, special_override? special_override : M.mind.special_role), TRUE, TRUE, FALSE)
//Just incase there's extra mob selections in the future.....
/proc/load_itemlist_to_mob(mob/living/L, list/itemlist, drop_on_floor_if_full = TRUE, load_to_all_slots = TRUE, replace_slots = FALSE)
if(!istype(L) || !islist(itemlist))
return FALSE
var/loading_mode = DROP_TO_FLOOR
var/turf/current_turf = get_turf(L)
if(ishuman(L))
loading_mode = LOADING_TO_HUMAN
switch(loading_mode)
if(DROP_TO_FLOOR)
for(var/I in itemlist)
var/typepath = text2path(I)
if(!typepath)
continue
for(var/i = 0, i < itemlist[I], i++)
new typepath(current_turf)
return TRUE
if(LOADING_TO_HUMAN)
return load_itemlist_to_human(L, itemlist, drop_on_floor_if_full, load_to_all_slots, replace_slots)
/proc/load_itemlist_to_human(mob/living/carbon/human/H, list/itemlist, drop_on_floor_if_full = TRUE, load_to_all_slots = TRUE, replace_slots = FALSE)
if(!istype(H) || !islist(itemlist))
return FALSE
var/turf/T = get_turf(H)
for(var/item in itemlist)
var/path = item
if(!ispath(path))
path = text2path(path)
if(!path)
continue
var/amount = itemlist[item]
for(var/i in 1 to amount)
var/atom/movable/loaded_atom = new path
if(!istype(loaded_atom))
QDEL_NULL(loaded_atom)
continue
if(!istype(loaded_atom, /obj/item))
loaded_atom.forceMove(T)
continue
var/obj/item/loaded = loaded_atom
var/obj/item/storage/S = H.get_item_by_slot(slot_back)
if(istype(S))
S.handle_item_insertion(loaded, TRUE, H) //Force it into their backpack
continue
if(!H.put_in_hands(loaded)) //They don't have one/somehow that failed, put it in their hands
loaded.forceMove(T) //Guess we're just dumping it on the floor!
return TRUE
@@ -0,0 +1,71 @@
GLOBAL_LIST(custom_item_list)
//Layered list in form of custom_item_list[ckey][job][items][amounts]
//ckey is key, job is specific jobs, or "ALL" for all jobs, items for items, amounts for amount of item.
//File should be in the format of ckey|exact job name/exact job name/or put ALL instead of any job names|/path/to/item=amount;/path/to/item=amount
//Each ckey should be in a different line
//if there's multiple entries of a single ckey the later ones will add to the earlier definitions.
/proc/reload_custom_roundstart_items_list(custom_filelist)
if(!custom_filelist)
custom_filelist = "config/custom_roundstart_items.txt"
GLOB.custom_item_list = list()
var/list/file_lines = world.file2list(custom_filelist)
for(var/line in file_lines)
if(length(line) == 0) //Emptyline, no one cares.
continue
if(copytext(line,1,3) == "//") //Commented line, ignore.
continue
var/ckey_str_sep = findtext(line, "|") //Process our stuff..
var/char_str_sep = findtext(line, "|", ckey_str_sep+1)
var/job_str_sep = findtext(line, "|", char_str_sep+1)
var/item_str_sep = findtext(line, "|", job_str_sep+1)
var/ckey_str = ckey(copytext(line, 1, ckey_str_sep))
var/char_str = copytext(line, ckey_str_sep+1, char_str_sep)
var/job_str = copytext(line, char_str_sep+1, job_str_sep)
var/item_str = copytext(line, job_str_sep+1, item_str_sep)
if(!ckey_str || !char_str || !job_str || !item_str || !length(ckey_str) || !length(char_str) || !length(job_str) || !length(item_str))
log_admin("Errored custom_items_whitelist line: [line] - Component/separator missing!")
if(!islist(GLOB.custom_item_list[ckey_str]))
GLOB.custom_item_list[ckey_str] = list() //Initialize list for this ckey if it isn't initialized..
var/list/characters = splittext(char_str, "/")
for(var/character in characters)
if(!islist(GLOB.custom_item_list[ckey_str][character]))
GLOB.custom_item_list[ckey_str][character] = list()
var/list/jobs = splittext(job_str, "/")
for(var/job in jobs)
for(var/character in characters)
if(!islist(GLOB.custom_item_list[ckey_str][character][job]))
GLOB.custom_item_list[ckey_str][character][job] = list() //Initialize item list for this job of this ckey if not already initialized.
var/list/item_strings = splittext(item_str, ";") //Get item strings in format of /path/to/item=amount
for(var/item_string in item_strings)
var/path_str_sep = findtext(item_string, "=")
var/path = copytext(item_string, 1, path_str_sep) //Path to spawn
var/amount = copytext(item_string, path_str_sep+1) //Amount to spawn
//world << "DEBUG: Item string [item_string] processed"
amount = text2num(amount)
path = text2path(path)
if(!ispath(path) || !isnum(amount))
log_admin("Errored custom_items_whitelist line: [line] - Path/number for item missing or invalid.")
for(var/character in characters)
for(var/job in jobs)
if(!GLOB.custom_item_list[ckey_str][character][job][path]) //Doesn't exist, make it exist!
GLOB.custom_item_list[ckey_str][character][job][path] = amount
else
GLOB.custom_item_list[ckey_str][character][job][path] += amount //Exists, we want more~
return GLOB.custom_item_list
/proc/parse_custom_roundstart_items(ckey, char_name = "ALL", job_name = "ALL", special_role)
var/list/ret = list()
if(GLOB.custom_item_list[ckey])
for(var/char in GLOB.custom_item_list[ckey])
if((char_name == char) || (char_name == "ALL") || (char == "ALL"))
for(var/job in GLOB.custom_item_list[ckey][char])
if((job_name == job) || (job == "ALL") || (job_name == "ALL") || (special_role && (job == special_role)))
for(var/item_path in GLOB.custom_item_list[ckey][char][job])
if(ret[item_path])
ret[item_path] += GLOB.custom_item_list[ckey][char][job][item_path]
else
ret[item_path] = GLOB.custom_item_list[ckey][char][job][item_path]
return ret
+34 -34
View File
@@ -1,42 +1,42 @@
/obj/item/weapon/robot_module/loader
/obj/item/robot_module/loader
name = "loader robot module"
/obj/item/weapon/robot_module/loader/New()
/obj/item/robot_module/loader/New()
..()
emag = new /obj/item/borg/stun(src)
modules += new /obj/item/weapon/extinguisher(src)
modules += new /obj/item/weapon/weldingtool/largetank/cyborg(src)
modules += new /obj/item/weapon/screwdriver(src)
modules += new /obj/item/weapon/wrench(src)
modules += new /obj/item/weapon/crowbar(src)
modules += new /obj/item/weapon/wirecutters(src)
modules += new /obj/item/extinguisher(src)
modules += new /obj/item/weldingtool/largetank/cyborg(src)
modules += new /obj/item/screwdriver(src)
modules += new /obj/item/wrench(src)
modules += new /obj/item/crowbar(src)
modules += new /obj/item/wirecutters(src)
modules += new /obj/item/device/multitool(src)
modules += new /obj/item/device/t_scanner(src)
modules += new /obj/item/device/analyzer(src)
modules += new /obj/item/device/assembly/signaler
modules += new /obj/item/weapon/soap/nanotrasen(src)
modules += new /obj/item/soap/nanotrasen(src)
fix_modules()
/obj/item/weapon/robot_module/k9
/obj/item/robot_module/k9
name = "Security K-9 Unit module"
/obj/item/weapon/robot_module/k9/New()
/obj/item/robot_module/k9/New()
..()
modules += new /obj/item/weapon/restraints/handcuffs/cable/zipties/cyborg/dog(src)
modules += new /obj/item/weapon/dogborg/jaws/big(src)
modules += new /obj/item/weapon/dogborg/pounce(src)
modules += new /obj/item/restraints/handcuffs/cable/zipties/cyborg/dog(src)
modules += new /obj/item/dogborg/jaws/big(src)
modules += new /obj/item/dogborg/pounce(src)
modules += new /obj/item/clothing/mask/gas/sechailer/cyborg(src)
modules += new /obj/item/weapon/soap/tongue(src)
modules += new /obj/item/soap/tongue(src)
modules += new /obj/item/device/analyzer/nose(src)
modules += new /obj/item/weapon/storage/bag/borgdelivery(src)
modules += new /obj/item/storage/bag/borgdelivery(src)
//modules += new /obj/item/device/assembly/signaler(src)
//modules += new /obj/item/device/detective_scanner(src)
modules += new /obj/item/weapon/gun/energy/disabler/cyborg(src)
emag = new /obj/item/weapon/gun/energy/laser/cyborg(src)
modules += new /obj/item/gun/energy/disabler/cyborg(src)
emag = new /obj/item/gun/energy/laser/cyborg(src)
fix_modules()
/obj/item/weapon/robot_module/security/respawn_consumable(mob/living/silicon/robot/R, coeff = 1)
/obj/item/robot_module/security/respawn_consumable(mob/living/silicon/robot/R, coeff = 1)
..()
var/obj/item/weapon/gun/energy/gun/advtaser/cyborg/T = locate(/obj/item/weapon/gun/energy/gun/advtaser/cyborg) in get_usable_modules()
var/obj/item/gun/energy/gun/advtaser/cyborg/T = locate(/obj/item/gun/energy/gun/advtaser/cyborg) in get_usable_modules()
if(T)
if(T.power_supply.charge < T.power_supply.maxcharge)
var/obj/item/ammo_casing/energy/S = T.ammo_type[T.select]
@@ -46,31 +46,31 @@
T.charge_tick = 0
fix_modules()
/obj/item/weapon/robot_module/borgi
/obj/item/robot_module/borgi
name = "Borgi module"
/obj/item/weapon/robot_module/borgi/New()
/obj/item/robot_module/borgi/New()
..()
modules += new /obj/item/weapon/dogborg/jaws/small(src)
modules += new /obj/item/weapon/storage/bag/borgdelivery(src)
modules += new /obj/item/weapon/soap/tongue(src)
modules += new /obj/item/dogborg/jaws/small(src)
modules += new /obj/item/storage/bag/borgdelivery(src)
modules += new /obj/item/soap/tongue(src)
modules += new /obj/item/device/healthanalyzer(src)
modules += new /obj/item/device/analyzer/nose(src)
emag = new /obj/item/weapon/dogborg/pounce(src)
emag = new /obj/item/dogborg/pounce(src)
fix_modules()
/obj/item/weapon/robot_module/medihound
/obj/item/robot_module/medihound
name = "MediHound module"
/obj/item/weapon/robot_module/medihound/New()
/obj/item/robot_module/medihound/New()
..()
modules += new /obj/item/weapon/dogborg/jaws/small(src)
modules += new /obj/item/weapon/storage/bag/borgdelivery(src)
modules += new /obj/item/dogborg/jaws/small(src)
modules += new /obj/item/storage/bag/borgdelivery(src)
modules += new /obj/item/device/analyzer/nose(src)
modules += new /obj/item/weapon/soap/tongue(src)
modules += new /obj/item/soap/tongue(src)
modules += new /obj/item/device/healthanalyzer(src)
modules += new /obj/item/weapon/dogborg/sleeper(src)
modules += new /obj/item/weapon/twohanded/shockpaddles/hound(src)
modules += new /obj/item/dogborg/sleeper(src)
modules += new /obj/item/twohanded/shockpaddles/hound(src)
modules += new /obj/item/device/sensor_device(src)
emag = new /obj/item/weapon/dogborg/pounce(src)
emag = new /obj/item/dogborg/pounce(src)
fix_modules()
+92 -68
View File
@@ -1,9 +1,9 @@
/obj/item/weapon/dogborg/jaws/big
/obj/item/dogborg/jaws/big
name = "combat jaws"
icon = 'icons/mob/dogborg.dmi'
icon_state = "jaws"
desc = "The jaws of the law."
flags = CONDUCT
flags_1 = CONDUCT_1
force = 12
throwforce = 0
hitsound = 'sound/weapons/bite.ogg'
@@ -11,12 +11,12 @@
w_class = 3
sharpness = IS_SHARP
/obj/item/weapon/dogborg/jaws/small
/obj/item/dogborg/jaws/small
name = "puppy jaws"
icon = 'icons/mob/dogborg.dmi'
icon_state = "smalljaws"
desc = "The jaws of a small dog."
flags = CONDUCT
flags_1 = CONDUCT_1
force = 6
throwforce = 0
hitsound = 'sound/weapons/bite.ogg'
@@ -25,11 +25,11 @@
sharpness = IS_SHARP
var/emagged = 0
/obj/item/weapon/dogborg/jaws/attack(atom/A, mob/living/silicon/robot/user)
/obj/item/dogborg/jaws/attack(atom/A, mob/living/silicon/robot/user)
..()
user.do_attack_animation(A, ATTACK_EFFECT_BITE)
/obj/item/weapon/dogborg/jaws/small/attack_self(mob/user)
/obj/item/dogborg/jaws/small/attack_self(mob/user)
var/mob/living/silicon/robot.R = user
if(R.emagged)
emagged = !emagged
@@ -38,7 +38,7 @@
icon = 'icons/mob/dogborg.dmi'
icon_state = "jaws"
desc = "The jaws of the law."
flags = CONDUCT
flags_1 = CONDUCT_1
force = 12
throwforce = 0
hitsound = 'sound/weapons/bite.ogg'
@@ -50,7 +50,7 @@
icon = 'icons/mob/dogborg.dmi'
icon_state = "smalljaws"
desc = "The jaws of a small dog."
flags = CONDUCT
flags_1 = CONDUCT_1
force = 5
throwforce = 0
hitsound = 'sound/weapons/bite.ogg'
@@ -62,20 +62,20 @@
//Cuffs
/obj/item/weapon/restraints/handcuffs/cable/zipties/cyborg/dog/attack(mob/living/carbon/C, mob/user)
/obj/item/restraints/handcuffs/cable/zipties/cyborg/dog/attack(mob/living/carbon/C, mob/user)
if(!C.handcuffed)
playsound(loc, 'sound/weapons/cablecuff.ogg', 30, 1, -2)
C.visible_message("<span class='danger'>[user] is trying to put zipties on [C]!</span>", \
"<span class='userdanger'>[user] is trying to put zipties on [C]!</span>")
if(do_mob(user, C, 30))
if(!C.handcuffed)
C.handcuffed = new /obj/item/weapon/restraints/handcuffs/cable/zipties/used(C)
C.handcuffed = new /obj/item/restraints/handcuffs/cable/zipties/used(C)
C.update_inv_handcuffed(0)
user << "<span class='notice'>You handcuff [C].</span>"
to_chat(user,"<span class='notice'>You handcuff [C].</span>")
playsound(loc, pick('sound/voice/bgod.ogg', 'sound/voice/biamthelaw.ogg', 'sound/voice/bsecureday.ogg', 'sound/voice/bradio.ogg', 'sound/voice/binsult.ogg', 'sound/voice/bcreep.ogg'), 50, 0)
add_logs(user, C, "handcuffed")
else
user << "<span class='warning'>You fail to handcuff [C]!</span>"
to_chat(user,"<span class='warning'>You fail to handcuff [C]!</span>")
//Boop
@@ -85,7 +85,7 @@
icon = 'icons/mob/dogborg.dmi'
icon_state = "nose"
desc = "The BOOP module"
flags = CONDUCT
flags_1 = CONDUCT_1
force = 0
throwforce = 0
attack_verb = list("nuzzled", "nosed", "booped")
@@ -149,7 +149,7 @@
//Delivery
/obj/item/weapon/storage/bag/borgdelivery
/obj/item/storage/bag/borgdelivery
name = "fetching storage"
desc = "Fetch the thing!"
icon = 'icons/mob/dogborg.dmi'
@@ -161,12 +161,12 @@
storage_slots = 1
collection_mode = 0
can_hold = list() // any
cant_hold = list(/obj/item/weapon/disk/nuclear)
cant_hold = list(/obj/item/disk/nuclear)
//Tongue stuff
/obj/item/weapon/soap/tongue
/obj/item/soap/tongue
name = "synthetic tongue"
desc = "Useful for slurping mess off the floor before affectionally licking the crew members in the face."
icon = 'icons/mob/dogborg.dmi'
@@ -175,9 +175,9 @@
cleanspeed = 80
var/emagged = 0
/obj/item/weapon/soap/tongue/New()
/obj/item/soap/tongue/New()
..()
flags |= NOBLUDGEON //No more attack messages
flags_1 |= NOBLUDGEON_1 //No more attack messages
/obj/item/trash/rkibble
name = "robo kibble"
@@ -185,7 +185,7 @@
icon = 'icons/mob/dogborg.dmi'
icon_state= "kibble"
/obj/item/weapon/soap/tongue/attack_self(mob/user)
/obj/item/soap/tongue/attack_self(mob/user)
var/mob/living/silicon/robot.R = user
if(R.emagged)
emagged = !emagged
@@ -203,15 +203,17 @@
cleanspeed = 80
update_icon()
/obj/item/weapon/soap/tongue/afterattack(atom/target, mob/user, proximity)
/obj/item/soap/tongue/afterattack(atom/target, mob/user, proximity)
if(!proximity || !check_allowed_items(target))
return
if(user.client && (target in user.client.screen))
user << "<span class='warning'>You need to take that [target.name] off before cleaning it!</span>"
to_chat(user, "<span class='warning'>You need to take that [target.name] off before cleaning it!</span>")
else if(istype(target,/obj/effect/decal/cleanable))
user.visible_message("[user] begins to lick off \the [target.name].", "<span class='warning'>You begin to lick off \the [target.name]...</span>")
if(do_after(user, src.cleanspeed, target = target))
user << "<span class='notice'>You finish licking off \the [target.name].</span>"
if(!in_range(src, target)) //Proximity is probably old news by now, do a new check.
return //If they moved away, you can't eat them.
to_chat(user, "<span class='notice'>You finish licking off \the [target.name].</span>")
qdel(target)
var/mob/living/silicon/robot.R = user
R.cell.give(50)
@@ -219,17 +221,21 @@
if(istype(target,/obj/item/trash))
user.visible_message("[user] nibbles away at \the [target.name].", "<span class='warning'>You begin to nibble away at \the [target.name]...</span>")
if(do_after(user, src.cleanspeed, target = target))
user << "<span class='notice'>You finish off \the [target.name].</span>"
if(!in_range(src, target)) //Proximity is probably old news by now, do a new check.
return //If they moved away, you can't eat them.
to_chat(user, "<span class='notice'>You finish off \the [target.name].</span>")
qdel(target)
var/mob/living/silicon/robot.R = user
R.cell.give(250)
return
if(istype(target,/obj/item/weapon/stock_parts/cell))
if(istype(target,/obj/item/stock_parts/cell))
user.visible_message("[user] begins cramming \the [target.name] down its throat.", "<span class='warning'>You begin cramming \the [target.name] down your throat...</span>")
if(do_after(user, 50, target = target))
user << "<span class='notice'>You finish off \the [target.name].</span>"
if(!in_range(src, target)) //Proximity is probably old news by now, do a new check.
return //If they moved away, you can't eat them.
to_chat(user, "<span class='notice'>You finish off \the [target.name].</span>")
var/mob/living/silicon/robot.R = user
var/obj/item/weapon/stock_parts/cell.C = target
var/obj/item/stock_parts/cell.C = target
R.cell.charge = R.cell.charge + (C.charge / 3) //Instant full cell upgrades op idgaf
qdel(target)
return
@@ -237,15 +243,19 @@
if(!I.anchored && src.emagged)
user.visible_message("[user] begins chewing up \the [target.name]. Looks like it's trying to loophole around its diet restriction!", "<span class='warning'>You begin chewing up \the [target.name]...</span>")
if(do_after(user, 100, target = I)) //Nerf dat time yo
if(!in_range(src, target)) //Proximity is probably old news by now, do a new check. Even emags don't make you magically eat things at range.
return //If they moved away, you can't eat them.
visible_message("<span class='warning'>[user] chews up \the [target.name] and cleans off the debris!</span>")
user << "<span class='notice'>You finish off \the [target.name].</span>"
to_chat(user, "<span class='notice'>You finish off \the [target.name].</span>")
qdel(I)
var/mob/living/silicon/robot.R = user
R.cell.give(500)
return
user.visible_message("[user] begins to lick \the [target.name] clean...", "<span class='notice'>You begin to lick \the [target.name] clean...</span>")
if(do_after(user, src.cleanspeed, target = target))
user << "<span class='notice'>You clean \the [target.name].</span>"
if(!in_range(src, target)) //Proximity is probably old news by now, do a new check.
return //If they moved away, you can't clean them.
to_chat(user,"<span class='notice'>You clean \the [target.name].</span>")
var/obj/effect/decal/cleanable/C = locate() in target
qdel(C)
target.clean_blood()
@@ -269,12 +279,16 @@
else if(istype(target, /obj/structure/window))
user.visible_message("[user] begins to lick \the [target.name] clean...", "<span class='notice'>You begin to lick \the [target.name] clean...</span>")
if(do_after(user, src.cleanspeed, target = target))
user << "<span class='notice'>You clean \the [target.name].</span>"
if(!in_range(src, target)) //Proximity is probably old news by now, do a new check.
return //If they moved away, you can't clean them.
to_chat(user, "<span class='notice'>You clean \the [target.name].</span>")
target.color = initial(target.color)
else
user.visible_message("[user] begins to lick \the [target.name] clean...", "<span class='notice'>You begin to lick \the [target.name] clean...</span>")
if(do_after(user, src.cleanspeed, target = target))
user << "<span class='notice'>You clean \the [target.name].</span>"
if(!in_range(src, target)) //Proximity is probably old news by now, do a new check.
return //If they moved away, you can't clean them.
to_chat(user, "<span class='notice'>You clean \the [target.name].</span>")
var/obj/effect/decal/cleanable/C = locate() in target
qdel(C)
target.clean_blood()
@@ -284,7 +298,7 @@
//Defibs
/obj/item/weapon/twohanded/shockpaddles/hound
/obj/item/twohanded/shockpaddles/hound
name = "defibrillator paws"
desc = "MediHound specific shock paws."
icon = 'icons/mob/dogborg.dmi'
@@ -293,7 +307,7 @@
req_defib = 0
wielded = 1
/obj/item/weapon/twohanded/shockpaddles/hound/attack(mob/M, mob/user)
/obj/item/twohanded/shockpaddles/hound/attack(mob/M, mob/user)
var/mob/living/silicon/robot.R = user
if(R.cell.charge < 1000)
user.visible_message("<span class='warning'>You don't have enough charge for this operation!</span class>")
@@ -322,17 +336,17 @@
var/eject_port = "ingestion"
var/list/items_preserved = list()
var/list/important_items = list(
/obj/item/weapon/hand_tele,
/obj/item/weapon/card/id/captains_spare,
/obj/item/hand_tele,
/obj/item/card/id/captains_spare,
/obj/item/device/aicard,
/obj/item/device/paicard,
/obj/item/weapon/gun,
/obj/item/weapon/pinpointer,
/obj/item/gun,
/obj/item/pinpointer,
/obj/item/clothing/shoes/magboots,
/obj/item/clothing/head/helmet/space,
/obj/item/clothing/suit/space,
/obj/item/weapon/reagent_containers/hypospray/CMO,
/obj/item/weapon/tank/jetpack/oxygen/captain,
/obj/item/reagent_containers/hypospray/CMO,
/obj/item/tank/jetpack/oxygen/captain,
/obj/item/clothing/accessory/medal/gold/captain,
/obj/item/clothing/suit/armor,
/obj/item/documents,
@@ -340,11 +354,11 @@
/obj/item/nuke_core_container,
/obj/item/areaeditor/blueprints,
/obj/item/documents/syndicate,
/obj/item/weapon/disk/nuclear)
/obj/item/disk/nuclear)
/obj/item/device/dogborg/sleeper/New()
..()
flags |= NOBLUDGEON //No more attack messages
flags_1 |= NOBLUDGEON_1 //No more attack messages
/obj/item/device/dogborg/sleeper/Exit(atom/movable/O)
return 0
@@ -355,16 +369,20 @@
return
if(!ishuman(target))
return
if(!target.devourable)
to_chat(user, "<span class='warning'>This person is incompatible with our equipment.</span>")
return
if(target.buckled)
user << "<span class='warning'>The user is buckled and can not be put into your [src.name].</span>"
to_chat(user, "<span class='warning'>The user is buckled and can not be put into your [src.name].</span>")
return
if(patient)
user << "<span class='warning'>Your [src.name] is already occupied.</span>"
to_chat(user, "<span class='warning'>Your [src.name] is already occupied.</span>")
return
user.visible_message("<span class='warning'>[hound.name] is ingesting [target.name] into their [src.name].</span>", "<span class='notice'>You start ingesting [target] into your [src]...</span>")
if(!patient && ishuman(target) && !target.buckled && do_after (user, 50, target))
if(!patient && ishuman(target) && !target.buckled && do_after (user, 50, target = target))
if(!proximity) return //If they moved away, you can't eat them.
if(!in_range(src, target)) //Proximity is probably old news by now, do a new check.
return //If they moved away, you can't eat them.
if(patient) return //If you try to eat two people at once, you can only eat one.
@@ -526,7 +544,7 @@
START_PROCESSING(SSobj, src)
sleeperUI(usr)
if(patient)
patient << "<span class='danger'>[hound.name]'s [src.name] fills with caustic enzymes around you!</span>"
to_chat(patient, "<span class='danger'>[hound.name]'s [src.name] fills with caustic enzymes around you!</span>")
return
if(cleaning)
sleeperUI(usr)
@@ -544,9 +562,9 @@
if(href_list["inject"] == "epinephrine" || patient.health > min_health)
inject_chem(usr, href_list["inject"])
else
usr << "<span class='notice'>ERROR: Subject is not in stable condition for injections.</span>"
to_chat(usr, "<span class='notice'>ERROR: Subject is not in stable condition for injections.</span>")
else
usr << "<span class='notice'>ERROR: Subject cannot metabolise chemicals.</span>"
to_chat(usr,"<span class='notice'>ERROR: Subject cannot metabolise chemicals.</span>")
src.updateUsrDialog()
sleeperUI(usr) //Needs a callback to boop the page to refresh.
@@ -556,15 +574,15 @@
if(patient && patient.reagents)
if(chem in injection_chems + "epinephrine")
if(hound.cell.charge < 800) //This is so borgs don't kill themselves with it.
hound << "<span class='notice'>You don't have enough power to synthesize fluids.</span>"
to_chat(hound, "<span class='notice'>You don't have enough power to synthesize fluids.</span>")
return
else if(patient.reagents.get_reagent_amount(chem) + 10 >= 20) //Preventing people from accidentally killing themselves by trying to inject too many chemicals!
hound << "<span class='notice'>Your stomach is currently too full of fluids to secrete more fluids of this kind.</span>"
to_chat(hound, "<span class='notice'>Your stomach is currently too full of fluids to secrete more fluids of this kind.</span>")
else if(patient.reagents.get_reagent_amount(chem) + 10 <= 20) //No overdoses for you
patient.reagents.add_reagent(chem, inject_amount)
drain(750) //-750 charge per injection
var/units = round(patient.reagents.get_reagent_amount(chem))
hound << "<span class='notice'>Injecting [units] unit\s of [injection_chems[chem]] into occupant.</span>" //If they were immersed, the reagents wouldn't leave with them.
to_chat(hound, "<span class='notice'>Injecting [units] unit\s of [injection_chems[chem]] into occupant.</span>") //If they were immersed, the reagents wouldn't leave with them.
/obj/item/device/dogborg/sleeper/process()
@@ -651,11 +669,11 @@
//Belly is entirely empty
if(!length(contents))
hound << "<span class='notice'>Your [src.name] is now clean. Ending self-cleaning cycle.</span>"
to_chat(hound, "<span class='notice'>Your [src.name] is now clean. Ending self-cleaning cycle.</span>")
cleaning = 0
update_patient()
return
//sound effects
for(var/mob/living/M in contents)
if(prob(20))
@@ -663,7 +681,7 @@
playsound(get_turf(hound),"digest_pred",75,0,-6,0,channel=CHANNEL_PRED)
M.stop_sound_channel(CHANNEL_PRED)
M.playsound_local("digest_prey",60)
//If the timing is right, and there are items to be touched
if(SSmobs.times_fired%6==1 && length(touchable_items))
@@ -716,8 +734,8 @@
qdel(T)
//Special case for IDs to make them digested
//else if (istype(T, /obj/item/weapon/card/id))
//var/obj/item/weapon/card/id/ID = T
//else if (istype(T, /obj/item/card/id))
//var/obj/item/card/id/ID = T
//ID.digest() //Need the digest proc, first.
//Anything not perserved, PDA, or ID
@@ -742,9 +760,9 @@
min_health = -100
injection_chems = null //So they don't have all the same chems as the medihound!
/obj/item/weapon/storage/attackby(obj/item/device/dogborg/sleeper/K9, mob/user, proximity)
/obj/item/storage/attackby(obj/item/device/dogborg/sleeper/K9, mob/user, proximity)
K9.afterattack(src, user ,1)
/obj/item/device/dogborg/sleeper/K9/afterattack(var/atom/movable/target, mob/living/silicon/user, proximity)
hound = loc
@@ -766,16 +784,18 @@
to_chat(user,"<span class='warning'>[brigman] is buckled and can not be put into your [src.name].</span>")
return
user.visible_message("<span class='warning'>[hound.name] is ingesting [brigman] into their [src.name].</span>", "<span class='notice'>You start ingesting [brigman] into your [src.name]...</span>")
if(do_after(user, 30, brigman) && !patient && !brigman.buckled)
if(do_after(user, 30, target = brigman) && !patient && !brigman.buckled)
if(!in_range(src, brigman)) //Proximity is probably old news by now, do a new check.
return //If they moved away, you can't eat them.
brigman.forceMove(src)
brigman.reset_perspective(src)
update_patient()
START_PROCESSING(SSobj, src)
user.visible_message("<span class='warning'>[hound.name]'s mobile brig clunks in series as [brigman] slips inside.</span>", "<span class='notice'>Your garbage compactor groans lightly as [brigman] slips inside.</span>")
user.visible_message("<span class='warning'>[hound.name]'s mobile brig clunks in series as [brigman] slips inside.</span>", "<span class='notice'>Your mobile brig groans lightly as [brigman] slips inside.</span>")
playsound(hound, 'sound/effects/bin_close.ogg', 80, 1) // Really don't need ERP sound effects for robots
return
return
/obj/item/device/dogborg/sleeper/compactor //Janihound gut.
name = "garbage processor"
desc = "A mounted garbage compactor unit with fuel processor."
@@ -786,7 +806,7 @@
injection_chems = null //So they don't have all the same chems as the medihound!
var/max_item_count = 32
/obj/item/weapon/storage/attackby(obj/item/device/dogborg/sleeper/compactor, mob/user, proximity) //GIT CIRCUMVENTED YO!
/obj/item/storage/attackby(obj/item/device/dogborg/sleeper/compactor, mob/user, proximity) //GIT CIRCUMVENTED YO!
compactor.afterattack(src, user ,1)
/obj/item/device/dogborg/sleeper/compactor/afterattack(var/atom/movable/target, mob/living/silicon/user, proximity)//GARBO NOMS
@@ -810,7 +830,9 @@
to_chat(user,"<span class='warning'>\The [target] is too large to fit into your [src.name]</span>")
return
user.visible_message("<span class='warning'>[hound.name] is ingesting [target.name] into their [src.name].</span>", "<span class='notice'>You start ingesting [target] into your [src.name]...</span>")
if(do_after(user, 30, target) && length(contents) < max_item_count)
if(do_after(user, 30, target = target) && length(contents) < max_item_count)
if(!in_range(src, target)) //Proximity is probably old news by now, do a new check.
return //If they moved away, you can't eat them. This still applies to items, don't magically eat things I picked up already.
target.forceMove(src)
user.visible_message("<span class='warning'>[hound.name]'s garbage processor groans lightly as [target.name] slips inside.</span>", "<span class='notice'>Your garbage compactor groans lightly as [target] slips inside.</span>")
playsound(hound, 'sound/machines/disposalflush.ogg', 50, 1)
@@ -822,7 +844,7 @@
else if(ishuman(target))
var/mob/living/carbon/human/trashman = target
if (!trashman.devourable)
to_chat(user, "The target registers an error code.")
to_chat(user, "<span class='warning'>\The [target] registers an error code to your [src.name]</span>")
return
if(patient)
to_chat(user,"<span class='warning'>Your [src.name] is already occupied.</span>")
@@ -831,7 +853,9 @@
to_chat(user,"<span class='warning'>[trashman] is buckled and can not be put into your [src.name].</span>")
return
user.visible_message("<span class='warning'>[hound.name] is ingesting [trashman] into their [src.name].</span>", "<span class='notice'>You start ingesting [trashman] into your [src.name]...</span>")
if(do_after(user, 30, trashman) && !patient && !trashman.buckled && length(contents) < max_item_count)
if(do_after(user, 30, target = trashman) && !patient && !trashman.buckled && length(contents) < max_item_count)
if(!in_range(src, trashman)) //Proximity is probably old news by now, do a new check.
return //If they moved away, you can't eat them.
trashman.forceMove(src)
trashman.reset_perspective(src)
update_patient()
@@ -844,7 +868,7 @@
// Pounce stuff for K-9
/obj/item/weapon/dogborg/pounce
/obj/item/dogborg/pounce
name = "pounce"
icon = 'icons/mob/dogborg.dmi'
icon_state = "pounce"
@@ -852,9 +876,9 @@
force = 0
throwforce = 0
/obj/item/weapon/dogborg/pounce/New()
/obj/item/dogborg/pounce/New()
..()
flags |= NOBLUDGEON
flags_1 |= NOBLUDGEON_1
/mob/living/silicon/robot
var/leaping = 0
@@ -868,7 +892,7 @@
#define MAX_K9_LEAP_DIST 4 //because something's definitely borked the pounce functioning from a distance.
/obj/item/weapon/dogborg/pounce/afterattack(atom/A, mob/user)
/obj/item/dogborg/pounce/afterattack(atom/A, mob/user)
var/mob/living/silicon/robot.R = user
R.leap_at(A)
+2 -2
View File
@@ -90,7 +90,7 @@
icon = 'icons/mob/pokemon.dmi'
var/pokeball
pixel_x = -16
butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat/slab = 5)
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab = 5)
ventcrawler = 2
health = 100
maxHealth = 100
@@ -132,7 +132,7 @@
/mob/living/simple_animal/pokemon/leg
icon = 'icons/mob/legendary.dmi'
pixel_x = -32
butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat/slab = 12)
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab = 12)
health = 200
maxHealth = 200
+13 -13
View File
@@ -1,7 +1,7 @@
//////////
//DILDOS//
//////////
obj/item/weapon/dildo
obj/item/dildo
name = "dildo"
desc = "Floppy!"
icon = 'code/citadel/icons/dildo.dmi'
@@ -19,7 +19,7 @@ obj/item/weapon/dildo
var/random_shape = FALSE
//Lists moved to _cit_helpers.dm as globals so they're not instanced individually
obj/item/weapon/dildo/proc/update_appearance()
obj/item/dildo/proc/update_appearance()
icon_state = "[dildo_type]_[dildo_shape]_[dildo_size]"
var/sizeword = ""
switch(dildo_size)
@@ -34,7 +34,7 @@ obj/item/weapon/dildo/proc/update_appearance()
name = "[sizeword][dildo_shape] [can_customize ? "custom " : ""][dildo_type]"
obj/item/weapon/dildo/AltClick(mob/living/user)
obj/item/dildo/AltClick(mob/living/user)
if(QDELETED(src))
return
if(!isliving(user))
@@ -45,7 +45,7 @@ obj/item/weapon/dildo/AltClick(mob/living/user)
return
customize(user)
obj/item/weapon/dildo/proc/customize(mob/living/user)
obj/item/dildo/proc/customize(mob/living/user)
if(!can_customize)
return FALSE
if(src && !user.incapacitated() && in_range(user,src))
@@ -74,7 +74,7 @@ obj/item/weapon/dildo/proc/customize(mob/living/user)
update_appearance()
return TRUE
obj/item/weapon/dildo/Initialize()
obj/item/dildo/Initialize()
. = ..()
if(random_color == TRUE)
var/randcolor = pick(GLOB.dildo_colors)
@@ -90,40 +90,40 @@ obj/item/weapon/dildo/Initialize()
pixel_y = rand(-7,7)
pixel_x = rand(-7,7)
obj/item/weapon/dildo/examine(mob/user)
obj/item/dildo/examine(mob/user)
..()
if(can_customize)
user << "<span class='notice'>Alt-Click \the [src.name] to customize it.</span>"
obj/item/weapon/dildo/random//totally random
obj/item/dildo/random//totally random
name = "random dildo"//this name will show up in vendors and shit so you know what you're vending(or don't, i guess :^))
random_color = TRUE
random_shape = TRUE
random_size = TRUE
obj/item/weapon/dildo/knotted
obj/item/dildo/knotted
dildo_shape = "knotted"
name = "knotted dildo"
obj/item/weapon/dildo/human
obj/item/dildo/human
dildo_shape = "human"
name = "human dildo"
obj/item/weapon/dildo/plain
obj/item/dildo/plain
dildo_shape = "plain"
name = "plain dildo"
obj/item/weapon/dildo/flared
obj/item/dildo/flared
dildo_shape = "flared"
name = "flared dildo"
obj/item/weapon/dildo/flared/huge
obj/item/dildo/flared/huge
name = "literal horse cock"
desc = "THIS THING IS HUGE!"
dildo_size = 4
obj/item/weapon/dildo/custom
obj/item/dildo/custom
name = "customizable dildo"
desc = "Thanks to significant advances in synthetic nanomaterials, this dildo is capable of taking on many different forms to fit the user's preferences! Pricy!"
can_customize = TRUE
+26 -17
View File
@@ -295,9 +295,11 @@
/datum/configuration/proc/Reload()
load("config/config.txt")
load("config/comms.txt", "comms")
load("config/game_options.txt","game_options")
load("config/policies.txt", "policies")
loadsql("config/dbconfig.txt")
reload_custom_roundstart_items_list()
if (maprotation)
loadmaplist("config/maps.txt")
@@ -462,27 +464,12 @@
fps = text2num(value)
if("automute_on")
automute_on = 1
if("comms_key")
global.comms_key = value
if(value != "default_pwd" && length(value) > 6) //It's the default value or less than 6 characters long, warn badmins
global.comms_allowed = 1
if("cross_server_address")
cross_address = value
if(value != "byond:\\address:port")
cross_allowed = 1
if("cross_comms_name")
cross_name = value
if("panic_server_name")
if (value != "\[Put the name here\]")
panic_server_name = value
if("panic_server_address")
if(value != "byond://address:port")
panic_address = value
if("medal_hub_address")
global.medal_hub = value
if("medal_hub_password")
global.medal_pass = value
if("show_irc_name")
showircname = 1
if("see_own_notes")
@@ -567,8 +554,12 @@
if("irc_announce_new_game")
irc_announce_new_game = TRUE
else
WRITE_FILE(GLOB.config_error_log, "Unknown setting in configuration: '[name]'")
#if DM_VERSION > 511
#error Replace the line below with WRITE_FILE(GLOB.config_error_log, "Unknown setting in configuration: '[name]'")
#endif
HandleCommsConfig(name, value) //TODO: Deprecate this eventually
else if(type == "comms")
HandleCommsConfig(name, value)
else if(type == "game_options")
switch(name)
if("damage_multiplier")
@@ -808,6 +799,24 @@
if(fps <= 0)
fps = initial(fps)
/datum/configuration/proc/HandleCommsConfig(name, value)
switch(name)
if("comms_key")
global.comms_key = value
if(value != "default_pwd" && length(value) > 6) //It's the default value or less than 6 characters long, warn badmins
global.comms_allowed = TRUE
if("cross_server_address")
cross_address = value
if(value != "byond:\\address:port")
cross_allowed = TRUE
if("cross_comms_name")
cross_name = value
if("medal_hub_address")
global.medal_hub = value
if("medal_hub_password")
global.medal_pass = value
else
WRITE_FILE(GLOB.config_error_log, "Unknown setting in configuration: '[name]'")
/datum/configuration/proc/loadmaplist(filename)
var/list/Lines = world.file2list(filename)
+2 -2
View File
@@ -68,14 +68,14 @@
/**
* Employee reassignment hook.
* Called in card.dm when someone's card is reassigned at the HoP's desk.
* Parameters: var/obj/item/weapon/card/id
* Parameters: var/obj/item/card/id
*/
/hook/reassign_employee
/**
* Employee terminated hook.
* Called in card.dm when someone's card is terminated at the HoP's desk.
* Parameters: var/obj/item/weapon/card/id
* Parameters: var/obj/item/card/id
*/
/hook/terminate_employee
+15 -11
View File
@@ -60,13 +60,17 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
/datum/controller/master/New()
// Highlander-style: there can only be one! Kill off the old and replace it with the new.
subsystems = list()
var/list/_subsystems = list()
subsystems = _subsystems
if (Master != src)
if (istype(Master))
Recover()
qdel(Master)
else
init_subtypes(/datum/controller/subsystem, subsystems)
var/list/subsytem_types = subtypesof(/datum/controller/subsystem)
sortTim(subsytem_types, /proc/cmp_subsystem_init)
for(var/I in subsytem_types)
_subsystems += new I
Master = src
if(!GLOB)
@@ -284,7 +288,7 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
//if there are mutiple sleeping procs running before us hogging the cpu, we have to run later
// because sleeps are processed in the order received, so longer sleeps are more likely to run first
if (world.tick_usage > TICK_LIMIT_MC)
if (TICK_USAGE > TICK_LIMIT_MC)
sleep_delta += 2
current_ticklimit = TICK_LIMIT_RUNNING * 0.5
sleep(world.tick_lag * (processing + sleep_delta))
@@ -293,7 +297,7 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
sleep_delta = MC_AVERAGE_FAST(sleep_delta, 0)
if (last_run + (world.tick_lag * processing) > world.time)
sleep_delta += 1
if (world.tick_usage > (TICK_LIMIT_MC*0.5))
if (TICK_USAGE > (TICK_LIMIT_MC*0.5))
sleep_delta += 1
if (make_runtime)
@@ -399,13 +403,13 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
//keep running while we have stuff to run and we haven't gone over a tick
// this is so subsystems paused eariler can use tick time that later subsystems never used
while (ran && queue_head && world.tick_usage < TICK_LIMIT_MC)
while (ran && queue_head && TICK_USAGE < TICK_LIMIT_MC)
ran = FALSE
bg_calc = FALSE
current_tick_budget = queue_priority_count
queue_node = queue_head
while (queue_node)
if (ran && world.tick_usage > TICK_LIMIT_RUNNING)
if (ran && TICK_USAGE > TICK_LIMIT_RUNNING)
break
queue_node_flags = queue_node.flags
@@ -417,7 +421,7 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
//(unless we haven't even ran anything this tick, since its unlikely they will ever be able run
// in those cases, so we just let them run)
if (queue_node_flags & SS_NO_TICK_CHECK)
if (queue_node.tick_usage > TICK_LIMIT_RUNNING - world.tick_usage && ran_non_ticker)
if (queue_node.tick_usage > TICK_LIMIT_RUNNING - TICK_USAGE && ran_non_ticker)
queue_node.queued_priority += queue_priority_count * 0.10
queue_priority_count -= queue_node_priority
queue_priority_count += queue_node.queued_priority
@@ -429,7 +433,7 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
current_tick_budget = queue_priority_count_bg
bg_calc = TRUE
tick_remaining = TICK_LIMIT_RUNNING - world.tick_usage
tick_remaining = TICK_LIMIT_RUNNING - TICK_USAGE
if (current_tick_budget > 0 && queue_node_priority > 0)
tick_precentage = tick_remaining / (current_tick_budget / queue_node_priority)
@@ -438,7 +442,7 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
tick_precentage = max(tick_precentage*0.5, tick_precentage-queue_node.tick_overrun)
current_ticklimit = round(world.tick_usage + tick_precentage)
current_ticklimit = round(TICK_USAGE + tick_precentage)
if (!(queue_node_flags & SS_TICKER))
ran_non_ticker = TRUE
@@ -449,9 +453,9 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
queue_node.state = SS_RUNNING
tick_usage = world.tick_usage
tick_usage = TICK_USAGE
var/state = queue_node.ignite(queue_node_paused)
tick_usage = world.tick_usage - tick_usage
tick_usage = TICK_USAGE - tick_usage
if (state == SS_RUNNING)
state = SS_IDLE
+14 -14
View File
@@ -71,65 +71,65 @@ SUBSYSTEM_DEF(air)
/datum/controller/subsystem/air/fire(resumed = 0)
var/timer = world.tick_usage
var/timer = TICK_USAGE_REAL
if(currentpart == SSAIR_PIPENETS || !resumed)
process_pipenets(resumed)
cost_pipenets = MC_AVERAGE(cost_pipenets, TICK_DELTA_TO_MS(world.tick_usage - timer))
cost_pipenets = MC_AVERAGE(cost_pipenets, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer))
if(state != SS_RUNNING)
return
resumed = 0
currentpart = SSAIR_ATMOSMACHINERY
if(currentpart == SSAIR_ATMOSMACHINERY)
timer = world.tick_usage
timer = TICK_USAGE_REAL
process_atmos_machinery(resumed)
cost_atmos_machinery = MC_AVERAGE(cost_atmos_machinery, TICK_DELTA_TO_MS(world.tick_usage - timer))
cost_atmos_machinery = MC_AVERAGE(cost_atmos_machinery, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer))
if(state != SS_RUNNING)
return
resumed = 0
currentpart = SSAIR_ACTIVETURFS
if(currentpart == SSAIR_ACTIVETURFS)
timer = world.tick_usage
timer = TICK_USAGE_REAL
process_active_turfs(resumed)
cost_turfs = MC_AVERAGE(cost_turfs, TICK_DELTA_TO_MS(world.tick_usage - timer))
cost_turfs = MC_AVERAGE(cost_turfs, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer))
if(state != SS_RUNNING)
return
resumed = 0
currentpart = SSAIR_EXCITEDGROUPS
if(currentpart == SSAIR_EXCITEDGROUPS)
timer = world.tick_usage
timer = TICK_USAGE_REAL
process_excited_groups(resumed)
cost_groups = MC_AVERAGE(cost_groups, TICK_DELTA_TO_MS(world.tick_usage - timer))
cost_groups = MC_AVERAGE(cost_groups, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer))
if(state != SS_RUNNING)
return
resumed = 0
currentpart = SSAIR_HIGHPRESSURE
if(currentpart == SSAIR_HIGHPRESSURE)
timer = world.tick_usage
timer = TICK_USAGE_REAL
process_high_pressure_delta(resumed)
cost_highpressure = MC_AVERAGE(cost_highpressure, TICK_DELTA_TO_MS(world.tick_usage - timer))
cost_highpressure = MC_AVERAGE(cost_highpressure, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer))
if(state != SS_RUNNING)
return
resumed = 0
currentpart = SSAIR_HOTSPOTS
if(currentpart == SSAIR_HOTSPOTS)
timer = world.tick_usage
timer = TICK_USAGE_REAL
process_hotspots(resumed)
cost_hotspots = MC_AVERAGE(cost_hotspots, TICK_DELTA_TO_MS(world.tick_usage - timer))
cost_hotspots = MC_AVERAGE(cost_hotspots, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer))
if(state != SS_RUNNING)
return
resumed = 0
currentpart = SSAIR_SUPERCONDUCTIVITY
if(currentpart == SSAIR_SUPERCONDUCTIVITY)
timer = world.tick_usage
timer = TICK_USAGE_REAL
process_super_conductivity(resumed)
cost_superconductivity = MC_AVERAGE(cost_superconductivity, TICK_DELTA_TO_MS(world.tick_usage - timer))
cost_superconductivity = MC_AVERAGE(cost_superconductivity, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer))
if(state != SS_RUNNING)
return
resumed = 0
+6 -6
View File
@@ -30,7 +30,7 @@ SUBSYSTEM_DEF(atoms)
initialized = INITIALIZATION_INNEW_MAPLOAD
LAZYINITLIST(late_loaders)
var/count
var/list/mapload_arg = list(TRUE)
if(atoms)
@@ -60,10 +60,10 @@ SUBSYSTEM_DEF(atoms)
A.LateInitialize()
testing("Late initialized [late_loaders.len] atoms")
late_loaders.Cut()
if(atoms)
. = created_atoms + atoms
created_atoms = null
created_atoms = null
/datum/controller/subsystem/atoms/proc/InitAtom(atom/A, list/arguments)
var/the_type = A.type
@@ -77,7 +77,7 @@ SUBSYSTEM_DEF(atoms)
if(start_tick != world.time)
BadInitializeCalls[the_type] |= BAD_INIT_SLEPT
var/qdeleted = FALSE
if(result != INITIALIZE_HINT_NORMAL)
@@ -92,12 +92,12 @@ SUBSYSTEM_DEF(atoms)
qdeleted = TRUE
else
BadInitializeCalls[the_type] |= BAD_INIT_NO_HINT
if(!A) //possible harddel
qdeleted = TRUE
else if(!A.initialized)
BadInitializeCalls[the_type] |= BAD_INIT_DIDNT_INIT
return qdeleted || QDELING(A)
/datum/controller/subsystem/atoms/proc/map_loader_begin()
+1 -1
View File
@@ -282,4 +282,4 @@ SUBSYSTEM_DEF(blackbox)
return details
/datum/feedback_variable/proc/get_parsed()
return list(variable,value,details)
return list(variable,value,details)
+2 -2
View File
@@ -1,5 +1,5 @@
#define COMMUNICATION_COOLDOWN 600
#define COMMUNICATION_COOLDOWN_AI 600
#define COMMUNICATION_COOLDOWN 300
#define COMMUNICATION_COOLDOWN_AI 300
SUBSYSTEM_DEF(communications)
name = "Communications"
+2 -2
View File
@@ -1,6 +1,6 @@
SUBSYSTEM_DEF(disease)
name = "Disease"
flags = SS_NO_FIRE
flags = SS_NO_FIRE | SS_NO_INIT
var/list/active_diseases = list() //List of Active disease in all mobs; purely for quick referencing.
var/list/diseases
@@ -13,4 +13,4 @@ SUBSYSTEM_DEF(disease)
diseases = subtypesof(/datum/disease)
/datum/controller/subsystem/disease/stat_entry(msg)
..("P:[active_diseases.len]")
..("P:[active_diseases.len]")
+8 -8
View File
@@ -49,12 +49,12 @@ SUBSYSTEM_DEF(explosion)
flame_cap = SSexplosion.flame_cap
dyn_ex_scale = SSexplosion.dyn_ex_scale
/datum/controller/subsystem/explosion/fire()
/datum/controller/subsystem/explosion/fire()
var/list/cached_explosions = explosions
var/num_explosions = cached_explosions.len
if(!num_explosions)
return
//figure exactly how many tick splits are required
var/num_splits
if(rebuild_tick_split_count)
@@ -216,7 +216,7 @@ SUBSYSTEM_DEF(explosion)
started_at = REALTIMEOFDAY
tick_started = world.time
gathered_turfs = list()
calculated_turfs = list()
unsafe_turfs = list()
@@ -332,13 +332,13 @@ SUBSYSTEM_DEF(explosion)
for(var/obj/structure/blob/B in T)
current_exp_block += B.explosion_block
L[T] = current_exp_block
if(MC_TICK_CHECK)
E.gathered_turfs.Cut(1, cut_to)
return FALSE
E.gathered_turfs.Cut()
return done_gathering_turfs
@@ -358,7 +358,7 @@ SUBSYSTEM_DEF(explosion)
var/throw_range_max = E.extent
var/turf/epi = E.epicenter
var/x0 = epi.x
var/y0 = epi.y
@@ -407,7 +407,7 @@ SUBSYSTEM_DEF(explosion)
var/throw_range = rand(throw_dist, throw_range_max)
var/turf/throw_at = get_ranged_target_turf(I, throw_dir, throw_range)
I.throw_speed = 4 //Temporarily change their throw_speed for embedding purposes (Resets when it finishes throwing, regardless of hitting anything)
I.throw_at(throw_at, throw_range, 4)
I.throw_at(throw_at, throw_range, 4)
if(MC_TICK_CHECK)
var/circumference = (PI * (init_dist + 4) * 2) //+4 to radius to prevent shit gaps
@@ -432,7 +432,7 @@ SUBSYSTEM_DEF(explosion)
E.finished_at = REALTIMEOFDAY
E.tick_finished = world.time
return TRUE
/client/proc/check_bomb_impacts()
+3 -3
View File
@@ -1,7 +1,7 @@
SUBSYSTEM_DEF(garbage)
name = "Garbage"
priority = 15
wait = 5
wait = 20
flags = SS_POST_FIRE_TIMING|SS_BACKGROUND|SS_NO_INIT
runlevels = RUNLEVELS_DEFAULT | RUNLEVEL_LOBBY
@@ -147,7 +147,7 @@ SUBSYSTEM_DEF(garbage)
//this is purely to separate things profile wise.
/datum/controller/subsystem/garbage/proc/HardDelete(datum/A)
var/time = world.timeofday
var/tick = world.tick_usage
var/tick = TICK_USAGE
var/ticktime = world.time
var/type = A.type
@@ -155,7 +155,7 @@ SUBSYSTEM_DEF(garbage)
del(A)
tick = (world.tick_usage-tick+((world.time-ticktime)/world.tick_lag*100))
tick = (TICK_USAGE-tick+((world.time-ticktime)/world.tick_lag*100))
if (tick > highest_del_tickusage)
highest_del_tickusage = tick
time = world.timeofday - time
+1 -1
View File
@@ -420,7 +420,7 @@ SUBSYSTEM_DEF(job)
if(job && H)
job.after_spawn(H, M)
handle_roundstart_items(H, M.ckey, H.mind.assigned_role, H.mind.special_role)
return H
+1 -1
View File
@@ -24,7 +24,7 @@ SUBSYSTEM_DEF(lighting)
create_all_lighting_objects()
initialized = TRUE
fire(FALSE, TRUE)
..()
+2 -2
View File
@@ -134,12 +134,12 @@ SUBSYSTEM_DEF(npcpool)
if(facCount == 1 && helpProb)
helpProb = 100
if(prob(helpProb) && candidate.takeDelegate(check,FALSE))
--canBeUsed.len
candidate.eye_color = "yellow"
candidate.update_icons()
if(!currentrun.len || MC_TICK_CHECK) //don't change SS state if it isn't necessary
return
+100 -73
View File
@@ -2,15 +2,13 @@ SUBSYSTEM_DEF(persistence)
name = "Persistence"
init_order = INIT_ORDER_PERSISTENCE
flags = SS_NO_FIRE
var/savefile/secret_satchels
var/list/satchel_blacklist = list() //this is a typecache
var/list/new_secret_satchels = list() //these are objects
var/old_secret_satchels = ""
var/list/old_secret_satchels = list()
var/list/obj/structure/chisel_message/chisel_messages = list()
var/list/saved_messages = list()
var/savefile/trophy_sav
var/list/saved_trophies = list()
/datum/controller/subsystem/persistence/Initialize()
@@ -21,52 +19,51 @@ SUBSYSTEM_DEF(persistence)
..()
/datum/controller/subsystem/persistence/proc/LoadSatchels()
secret_satchels = new /savefile("data/npc_saves/SecretSatchels.sav")
satchel_blacklist = typecacheof(list(/obj/item/stack/tile/plasteel, /obj/item/weapon/crowbar))
secret_satchels[SSmapping.config.map_name] >> old_secret_satchels
var/list/expanded_old_satchels = list()
var/placed_satchels = 0
if(!isnull(old_secret_satchels))
expanded_old_satchels = splittext(old_secret_satchels,"#")
if(PlaceSecretSatchel(expanded_old_satchels))
placed_satchels++
var/placed_satchel = 0
var/path
var/obj/item/storage/backpack/satchel/flat/F = new()
if(fexists("data/npc_saves/SecretSatchels.sav")) //legacy compatability to convert old format to new
var/savefile/secret_satchels = new /savefile("data/npc_saves/SecretSatchels.sav")
var/sav_text
secret_satchels[SSmapping.config.map_name] >> sav_text
fdel("data/npc_saves/SecretSatchels.sav")
if(sav_text)
old_secret_satchels = splittext(sav_text,"#")
if(old_secret_satchels.len >= 20)
var/satchel_string = pick_n_take(old_secret_satchels)
var/list/chosen_satchel = splittext(satchel_string,"|")
if(chosen_satchel.len == 3)
F.x = text2num(chosen_satchel[1])
F.y = text2num(chosen_satchel[2])
F.z = ZLEVEL_STATION
path = text2path(chosen_satchel[3])
else
expanded_old_satchels.len = 0
var/list/free_satchels = list()
for(var/turf/T in shuffle(block(locate(TRANSITIONEDGE,TRANSITIONEDGE,ZLEVEL_STATION), locate(world.maxx-TRANSITIONEDGE,world.maxy-TRANSITIONEDGE,ZLEVEL_STATION)))) //Nontrivially expensive but it's roundstart only
if(isfloorturf(T) && !istype(T, /turf/open/floor/plating/))
free_satchels += new /obj/item/weapon/storage/backpack/satchel/flat/secret(T)
if(!isemptylist(free_satchels) && ((free_satchels.len + placed_satchels) >= (50 - expanded_old_satchels.len) * 0.1)) //up to six tiles, more than enough to kill anything that moves
break
/datum/controller/subsystem/persistence/proc/PlaceSecretSatchel(list/expanded_old_satchels)
var/satchel_string
if(expanded_old_satchels.len >= 20) //guards against low drop pools assuring that one player cannot reliably find his own gear.
satchel_string = pick_n_take(expanded_old_satchels)
old_secret_satchels = jointext(expanded_old_satchels,"#")
WRITE_FILE(secret_satchels[SSmapping.config.map_name], old_secret_satchels)
var/list/chosen_satchel = splittext(satchel_string,"|")
if(!chosen_satchel || isemptylist(chosen_satchel) || chosen_satchel.len != 3) //Malformed
return 0
var/path = text2path(chosen_satchel[3]) //If the item no longer exist, this returns null
if(!path)
return 0
var/obj/item/weapon/storage/backpack/satchel/flat/F = new()
F.x = text2num(chosen_satchel[1])
F.y = text2num(chosen_satchel[2])
F.z = ZLEVEL_STATION
var/json_file = file("data/npc_saves/SecretSatchels[SSmapping.config.map_name].json")
if(!fexists(json_file))
return
var/list/json = list()
json = json_decode(file2text(json_file))
old_secret_satchels = json["data"]
if(old_secret_satchels.len)
if(old_secret_satchels.len >= 20) //guards against low drop pools assuring that one player cannot reliably find his own gear.
var/pos = rand(1, old_secret_satchels.len)
old_secret_satchels.Cut(pos, pos+1)
F.x = old_secret_satchels[pos]["x"]
F.y = old_secret_satchels[pos]["y"]
F.z = ZLEVEL_STATION
path = text2path(old_secret_satchels[pos]["saved_obj"])
if(!ispath(path))
return
if(isfloorturf(F.loc) && !istype(F.loc, /turf/open/floor/plating/))
F.hide(1)
new path(F)
return 1
placed_satchel++
var/list/free_satchels = list()
for(var/turf/T in shuffle(block(locate(TRANSITIONEDGE,TRANSITIONEDGE,ZLEVEL_STATION), locate(world.maxx-TRANSITIONEDGE,world.maxy-TRANSITIONEDGE,ZLEVEL_STATION)))) //Nontrivially expensive but it's roundstart only
if(isfloorturf(T) && !istype(T, /turf/open/floor/plating/))
free_satchels += new /obj/item/storage/backpack/satchel/flat/secret(T)
if(!isemptylist(free_satchels) && ((free_satchels.len + placed_satchel) >= (50 - old_secret_satchels.len) * 0.1)) //up to six tiles, more than enough to kill anything that moves
break
/datum/controller/subsystem/persistence/proc/LoadPoly()
for(var/mob/living/simple_animal/parrot/Poly/P in GLOB.living_mob_list)
@@ -74,14 +71,25 @@ SUBSYSTEM_DEF(persistence)
break //Who's been duping the bird?!
/datum/controller/subsystem/persistence/proc/LoadChiselMessages()
var/savefile/chisel_messages_sav = new /savefile("data/npc_saves/ChiselMessages.sav")
var/saved_json
chisel_messages_sav[SSmapping.config.map_name] >> saved_json
var/list/saved_messages = list()
if(fexists("data/npc_saves/ChiselMessages.sav")) //legacy compatability to convert old format to new
var/savefile/chisel_messages_sav = new /savefile("data/npc_saves/ChiselMessages.sav")
var/saved_json
chisel_messages_sav[SSmapping.config.map_name] >> saved_json
if(!saved_json)
return
saved_messages = json_decode(saved_json)
fdel("data/npc_saves/ChiselMessages.sav")
else
var/json_file = file("data/npc_saves/ChiselMessages[SSmapping.config.map_name].json")
if(!fexists(json_file))
return
var/list/json
json = json_decode(file2text(json_file))
if(!saved_json)
return
var/list/saved_messages = json_decode(saved_json)
if(!json)
return
saved_messages = json["data"]
for(var/item in saved_messages)
if(!islist(item))
@@ -109,20 +117,23 @@ SUBSYSTEM_DEF(persistence)
log_world("Loaded [saved_messages.len] engraved messages on map [SSmapping.config.map_name]")
/datum/controller/subsystem/persistence/proc/LoadTrophies()
trophy_sav = new /savefile("data/npc_saves/TrophyItems.sav")
var/saved_json
trophy_sav >> saved_json
if(!saved_json)
return
var/decoded_json = json_decode(saved_json)
if(!islist(decoded_json))
return
saved_trophies = decoded_json
if(fexists("data/npc_saves/TrophyItems.sav")) //legacy compatability to convert old format to new
var/savefile/S = new /savefile("data/npc_saves/TrophyItems.sav")
var/saved_json
S >> saved_json
if(!saved_json)
return
saved_trophies = json_decode(saved_json)
fdel("data/npc_saves/TrophyItems.sav")
else
var/json_file = file("data/npc_saves/TrophyItems.json")
if(!fexists(json_file))
return
var/list/json = list()
json = json_decode(file2text(json_file))
if(!json)
return
saved_trophies = json["data"]
SetUpTrophies(saved_trophies.Copy())
/datum/controller/subsystem/persistence/proc/SetUpTrophies(list/trophy_items)
@@ -156,8 +167,10 @@ SUBSYSTEM_DEF(persistence)
CollectTrophies()
/datum/controller/subsystem/persistence/proc/CollectSecretSatchels()
var/list/satchels = list()
satchel_blacklist = typecacheof(list(/obj/item/stack/tile/plasteel, /obj/item/crowbar))
for(var/A in new_secret_satchels)
var/obj/item/weapon/storage/backpack/satchel/flat/F = A
var/obj/item/storage/backpack/satchel/flat/F = A
if(QDELETED(F) || F.z != ZLEVEL_STATION || F.invisibility != INVISIBILITY_MAXIMUM)
continue
var/list/savable_obj = list()
@@ -170,25 +183,39 @@ SUBSYSTEM_DEF(persistence)
savable_obj += O.type
if(isemptylist(savable_obj))
continue
old_secret_satchels += "[F.x]|[F.y]|[pick(savable_obj)]#"
WRITE_FILE(secret_satchels[SSmapping.config.map_name], old_secret_satchels)
var/list/data = list()
data["x"] = F.x
data["y"] = F.y
data["saved_obj"] = pick(savable_obj)
satchels += list(data)
var/json_file = file("data/npc_saves/SecretSatchels[SSmapping.config.map_name].json")
var/list/file_data = list()
file_data["data"] = satchels
fdel(json_file)
WRITE_FILE(json_file, json_encode(file_data))
/datum/controller/subsystem/persistence/proc/CollectChiselMessages()
var/savefile/chisel_messages_sav = new /savefile("data/npc_saves/ChiselMessages.sav")
var/json_file = file("data/npc_saves/ChiselMessages[SSmapping.config.map_name].json")
for(var/obj/structure/chisel_message/M in chisel_messages)
saved_messages += list(M.pack())
log_world("Saved [saved_messages.len] engraved messages on map [SSmapping.config.map_name]")
WRITE_FILE(chisel_messages_sav[SSmapping.config.map_name], json_encode(saved_messages))
var/list/file_data = list()
file_data["data"] = saved_messages
fdel(json_file)
WRITE_FILE(json_file, json_encode(file_data))
/datum/controller/subsystem/persistence/proc/SaveChiselMessage(obj/structure/chisel_message/M)
saved_messages += list(M.pack()) // dm eats one list
/datum/controller/subsystem/persistence/proc/CollectTrophies()
WRITE_FILE(trophy_sav, json_encode(saved_trophies))
var/json_file = file("data/npc_saves/TrophyItems.json")
var/list/file_data = list()
file_data["data"] = saved_trophies
fdel(json_file)
WRITE_FILE(json_file, json_encode(file_data))
/datum/controller/subsystem/persistence/proc/SaveTrophy(obj/structure/displaycase/trophy/T)
if(!T.added_roundstart && T.showpiece)
@@ -55,7 +55,7 @@ PROCESSING_SUBSYSTEM_DEF(overlays)
overlays = po
else
overlays.Cut()
flags &= ~OVERLAY_QUEUED
flags_1 &= ~OVERLAY_QUEUED_1
/proc/iconstate2appearance(icon, iconstate)
var/static/image/stringbro = new()
@@ -102,8 +102,8 @@ PROCESSING_SUBSYSTEM_DEF(overlays)
new_overlays[i] = appearance_bro.appearance
return new_overlays
#define NOT_QUEUED_ALREADY (!(flags & OVERLAY_QUEUED))
#define QUEUE_FOR_COMPILE flags |= OVERLAY_QUEUED; SSoverlays.processing += src;
#define NOT_QUEUED_ALREADY (!(flags_1 & OVERLAY_QUEUED_1))
#define QUEUE_FOR_COMPILE flags_1 |= OVERLAY_QUEUED_1; SSoverlays.processing += src;
/atom/proc/cut_overlays(priority = FALSE)
var/list/cached_overlays = our_overlays
var/list/cached_priority = priority_overlays
+1 -1
View File
@@ -33,7 +33,7 @@ SUBSYSTEM_DEF(server_maint)
qdel(C)
if (!(!C || world.time - C.connection_time < PING_BUFFER_TIME || C.inactivity >= (wait-1)))
winset(C, null, "command=.update_ping+[world.time+world.tick_lag*world.tick_usage/100]")
winset(C, null, "command=.update_ping+[world.time+world.tick_lag*TICK_USAGE_REAL/100]")
if (MC_TICK_CHECK) //one day, when ss13 has 1000 people per server, you guys are gonna be glad I added this tick check
return
+5 -5
View File
@@ -84,7 +84,7 @@ SUBSYSTEM_DEF(shuttle)
var/turf/T = i
T.ChangeTurf(/turf/open/space)
transit_turfs += T
T.flags |= UNUSED_TRANSIT_TURF
T.flags_1 |= UNUSED_TRANSIT_TURF_1
#ifdef HIGHLIGHT_DYNAMIC_TRANSIT
/datum/controller/subsystem/shuttle/proc/color_space()
@@ -412,13 +412,13 @@ SUBSYSTEM_DEF(shuttle)
for(var/i in transit_turfs)
CHECK_TICK
var/turf/topleft = i
if(!(topleft.flags & UNUSED_TRANSIT_TURF))
if(!(topleft.flags_1 & UNUSED_TRANSIT_TURF_1))
continue
var/turf/bottomright = locate(topleft.x + transit_width,
topleft.y + transit_height, topleft.z)
if(!bottomright)
continue
if(!(bottomright.flags & UNUSED_TRANSIT_TURF))
if(!(bottomright.flags_1 & UNUSED_TRANSIT_TURF_1))
continue
proposed_zone = block(topleft, bottomright)
@@ -428,7 +428,7 @@ SUBSYSTEM_DEF(shuttle)
var/turf/T = j
if(!T)
continue base
if(!(T.flags & UNUSED_TRANSIT_TURF))
if(!(T.flags_1 & UNUSED_TRANSIT_TURF_1))
continue base
//to_chat(world, "[COORD(topleft)] and [COORD(bottomright)]")
break base
@@ -500,7 +500,7 @@ SUBSYSTEM_DEF(shuttle)
for(var/i in new_transit_dock.assigned_turfs)
var/turf/T = i
T.ChangeTurf(transit_path)
T.flags &= ~(UNUSED_TRANSIT_TURF)
T.flags_1 &= ~(UNUSED_TRANSIT_TURF_1)
M.assigned_transit = new_transit_dock
return TRUE
+1 -1
View File
@@ -27,6 +27,6 @@ SUBSYSTEM_DEF(stickyban)
ban["existing_user_matches_this_round"] = list()
ban["admin_matches_this_round"] = list()
cache[ckey] = ban
for (var/bannedckey in cache)
world.SetConfig("ban", bannedckey, list2stickyban(cache[bannedckey]))
+1 -1
View File
@@ -135,6 +135,6 @@ SUBSYSTEM_DEF(throwing)
var/atom/movable/AM = thing
if (AM == thrownthing)
continue
if (AM.density && !(AM.pass_flags & LETPASSTHROW) && !(AM.flags & ON_BORDER))
if (AM.density && !(AM.pass_flags & LETPASSTHROW) && !(AM.flags_1 & ON_BORDER_1))
finalize(hit=TRUE, target=AM)
return TRUE
+1 -1
View File
@@ -283,7 +283,7 @@ SUBSYSTEM_DEF(ticker)
SSshuttle.lockdown = TRUE
//initialise our cinematic screen object
cinematic = new /obj/screen{icon='icons/effects/station_explosion.dmi';icon_state="station_intact";layer=21;mouse_opacity=0;screen_loc="1,0";}(src)
cinematic = new /obj/screen{icon='icons/effects/station_explosion.dmi';icon_state="station_intact";layer=21;mouse_opacity = MOUSE_OPACITY_TRANSPARENT;screen_loc="1,0";}(src)
for(var/mob/M in GLOB.mob_list)
M.notransform = TRUE //stop everything moving
+4 -4
View File
@@ -50,9 +50,9 @@ SUBSYSTEM_DEF(timer)
var/datum/timedevent/bucket_head = bucket_list[i]
if (!bucket_head)
continue
log_world("Active timers at index [i]:")
var/datum/timedevent/bucket_node = bucket_head
var/anti_loop_check = 1000
do
@@ -230,7 +230,7 @@ SUBSYSTEM_DEF(timer)
src.timeToRun = timeToRun
src.flags = flags
src.hash = hash
if (flags & TIMER_UNIQUE)
SStimer.hashes[hash] = src
if (flags & TIMER_STOPPABLE)
@@ -383,7 +383,7 @@ SUBSYSTEM_DEF(timer)
timeToRun = REALTIMEOFDAY + wait
var/datum/timedevent/timer = new(callback, timeToRun, flags, hash)
return timer.id
return timer.id
/proc/deltimer(id)
if (!id)
+1 -1
View File
@@ -36,7 +36,7 @@ SUBSYSTEM_DEF(title)
break
file_path = "config/title_screens/images/[pick(title_screens)]"
icon = new(fcopy_rsc(file_path))
if(splash_turf)
+14 -16
View File
@@ -172,6 +172,7 @@
/datum/action/item_action/rcl
name = "Change Cable Color"
icon_icon = 'icons/mob/actions/actions_items.dmi'
button_icon_state = "rcl_rainbow"
/datum/action/item_action/startchainsaw
@@ -234,8 +235,8 @@
UpdateButtonIcon()
/datum/action/item_action/toggle_unfriendly_fire/UpdateButtonIcon(status_only = FALSE)
if(istype(target, /obj/item/weapon/hierophant_club))
var/obj/item/weapon/hierophant_club/H = target
if(istype(target, /obj/item/hierophant_club))
var/obj/item/hierophant_club/H = target
if(H.friendly_fire_check)
button_icon_state = "vortex_ff_off"
name = "Toggle Friendly Fire \[OFF\]"
@@ -264,8 +265,8 @@
button_icon_state = "vortex_recall"
/datum/action/item_action/vortex_recall/IsAvailable()
if(istype(target, /obj/item/weapon/hierophant_club))
var/obj/item/weapon/hierophant_club/H = target
if(istype(target, /obj/item/hierophant_club))
var/obj/item/hierophant_club/H = target
if(H.teleporting)
return 0
return ..()
@@ -351,7 +352,7 @@
name = "Toggle Jetpack Stabilization"
/datum/action/item_action/jetpack_stabilization/IsAvailable()
var/obj/item/weapon/tank/jetpack/J = target
var/obj/item/tank/jetpack/J = target
if(!istype(J) || !J.on)
return 0
return ..()
@@ -405,33 +406,30 @@
/datum/action/item_action/initialize_ninja_suit
name = "Toggle ninja suit"
/datum/action/item_action/ninjajaunt
name = "Phase Jaunt (10E)"
desc = "Utilizes the internal VOID-shift device to rapidly transit in direction facing."
icon_icon = 'icons/mob/actions/actions_items.dmi'
button_icon_state = "ninja_phase"
/datum/action/item_action/ninjasmoke
name = "Smoke Bomb"
desc = "Blind your enemies momentarily with a well-placed smoke bomb."
button_icon_state = "smoke"
icon_icon = 'icons/mob/actions/actions_spells.dmi'
/datum/action/item_action/ninjaboost
check_flags = AB_CHECK_RESTRAINED|AB_CHECK_CONSCIOUS
check_flags = NONE
name = "Adrenaline Boost"
desc = "Inject a secret chemical that will counteract all movement-impairing effect."
button_icon_state = "repulse"
icon_icon = 'icons/mob/actions/actions_spells.dmi'
/datum/action/item_action/ninjapulse
name = "EM Burst (25E)"
desc = "Disable any nearby technology with a electro-magnetic pulse."
button_icon_state = "emp"
icon_icon = 'icons/mob/actions/actions_spells.dmi'
/datum/action/item_action/ninjastar
name = "Create Throwing Stars (1E)"
desc = "Creates some throwing stars"
button_icon_state = "throwingstar"
icon_icon = 'icons/obj/weapons.dmi'
icon_icon = 'icons/obj/items_and_weapons.dmi'
/datum/action/item_action/ninjanet
name = "Energy Net (20E)"
@@ -443,13 +441,13 @@
name = "Recall Energy Katana (Variable Cost)"
desc = "Teleports the Energy Katana linked to this suit to its wearer, cost based on distance."
button_icon_state = "energy_katana"
icon_icon = 'icons/obj/weapons.dmi'
icon_icon = 'icons/obj/items_and_weapons.dmi'
/datum/action/item_action/ninja_stealth
name = "Toggle Stealth"
desc = "Toggles stealth mode on and off."
icon_icon = 'icons/mob/actions/actions_items.dmi'
button_icon_state = "ninja_cloak"
icon_icon = 'icons/mob/actions/actions_minor_antag.dmi'
/datum/action/item_action/toggle_glove
name = "Toggle interaction"
@@ -491,7 +489,7 @@
S.action = src
name = S.name
desc = S.desc
button_icon = S.action_icon
icon_icon = S.action_icon
button_icon_state = S.action_icon_state
background_icon_state = S.action_background_icon_state
button.name = name
+3 -3
View File
@@ -320,11 +320,11 @@
//Spawn and equip documents
var/mob/living/carbon/human/mob = owner.current
var/obj/item/weapon/folder/syndicate/folder
var/obj/item/folder/syndicate/folder
if(owner == SSticker.mode.exchange_red)
folder = new/obj/item/weapon/folder/syndicate/red(mob.loc)
folder = new/obj/item/folder/syndicate/red(mob.loc)
else
folder = new/obj/item/weapon/folder/syndicate/blue(mob.loc)
folder = new/obj/item/folder/syndicate/blue(mob.loc)
var/list/slots = list (
"backpack" = slot_in_backpack,
+4 -4
View File
@@ -188,7 +188,7 @@ GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master",
if(form == BLOOD_LIZARD && SOULVALUE < BLOOD_THRESHOLD)
regress_humanoid()
if(SOULVALUE < 0)
remove_spells()
give_appropriate_spells()
to_chat(owner.current, "<span class='warning'>As punishment for your failures, all of your powers except contract creation have been revoked.")
/datum/antagonist/devil/proc/regress_humanoid()
@@ -408,7 +408,7 @@ GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master",
reviveNumber += LOSS_PER_DEATH
update_hud()
if(body)
body.revive(1,0)
body.revive(TRUE, TRUE) //Adminrevive also recovers organs, preventing someone from resurrecting without a heart.
if(istype(body.loc, /obj/effect/dummy/slaughter/))
body.forceMove(get_turf(body))//Fixes dying while jaunted leaving you permajaunted.
if(istype(body, /mob/living/carbon/true_devil))
@@ -437,8 +437,8 @@ GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master",
var/mob/living/carbon/human/H = owner.current
H.equip_to_slot_or_del(new /obj/item/clothing/under/lawyer/black(H), slot_w_uniform)
H.equip_to_slot_or_del(new /obj/item/clothing/shoes/laceup(H), slot_shoes)
H.equip_to_slot_or_del(new /obj/item/weapon/storage/briefcase(H), slot_hands)
H.equip_to_slot_or_del(new /obj/item/weapon/pen(H), slot_l_store)
H.equip_to_slot_or_del(new /obj/item/storage/briefcase(H), slot_hands)
H.equip_to_slot_or_del(new /obj/item/pen(H), slot_l_store)
if(SOULVALUE >= BLOOD_THRESHOLD)
H.set_species(/datum/species/lizard, 1)
H.underwear = "Nude"
+5 -6
View File
@@ -29,7 +29,7 @@
qdel(H.gloves)
var/obj/item/clothing/suit/space/space_ninja/theSuit = new(H)
var/obj/item/weapon/dash/energy_katana/EK = new(H)
var/obj/item/dash/energy_katana/EK = new(H)
theSuit.energyKatana = EK
H.equip_to_slot_or_del(new /obj/item/device/radio/headset(H), slot_ears)
@@ -41,13 +41,12 @@
H.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/space_ninja(H), slot_wear_mask)
H.equip_to_slot_or_del(new /obj/item/clothing/glasses/night(H), slot_glasses)
H.equip_to_slot_or_del(EK, slot_belt)
H.equip_to_slot_or_del(new /obj/item/device/flashlight(H), slot_r_store)
H.equip_to_slot_or_del(new /obj/item/weapon/grenade/plastic/x4(H), slot_l_store)
H.equip_to_slot_or_del(new /obj/item/weapon/tank/internals/emergency_oxygen(H), slot_s_store)
H.equip_to_slot_or_del(new /obj/item/weapon/tank/jetpack/carbondioxide(H), slot_back)
H.equip_to_slot_or_del(new /obj/item/grenade/plastic/x4(H), slot_l_store)
H.equip_to_slot_or_del(new /obj/item/tank/internals/emergency_oxygen(H), slot_s_store)
H.equip_to_slot_or_del(new /obj/item/tank/jetpack/carbondioxide(H), slot_back)
theSuit.randomize_param()
var/obj/item/weapon/implant/explosive/E = new/obj/item/weapon/implant/explosive(H)
var/obj/item/implant/explosive/E = new/obj/item/implant/explosive(H)
E.implant(H)
return 1
+1 -1
View File
@@ -141,7 +141,7 @@
afterDraw()
/obj/effect/ebeam
mouse_opacity = 0
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
anchored = TRUE
var/datum/beam/owner
-62
View File
@@ -1,62 +0,0 @@
diff a/code/datums/callback.dm b/code/datums/callback.dm (rejected hunks)
@@ -100,60 +100,3 @@
if (object == GLOBAL_PROC)
return call(delegate)(arglist(calling_arguments))
return call(object, delegate)(arglist(calling_arguments))
-
-
-/datum/callback_select
- var/list/finished
- var/pendingcount
- var/total
-
-/datum/callback_select/New(count, savereturns)
- total = count
- if (savereturns)
- finished = new(count)
-
-
-/datum/callback_select/proc/invoke_callback(index, datum/callback/callback, list/callback_args, savereturn = TRUE)
- set waitfor = FALSE
- if (!callback || !istype(callback))
- //This check only exists because the alternative is callback_select would block forever if given invalid data
- CRASH("invalid callback passed to invoke_callback")
- if (!length(callback_args))
- callback_args = list()
- pendingcount++
- debug_usr("calling callback")
- var/rtn = callback.Invoke(arglist(callback_args))
- debug_usr("callback returned")
- pendingcount--
- if (savereturn)
- finished[index] = rtn
-
-
-
-
-//runs a list of callbacks asynchronously, returning once all of them return.
-//callbacks can be repeated.
-//callbacks-args is a optional list of argument lists, in the same order as the callbacks,
-// the inner lists will be sent to the callbacks when invoked() as additional args.
-//can optionly save and return a list of return values, in the same order as the original list of callbacks
-//resolution is the number of byond ticks between checks.
-/proc/callback_select(list/callbacks, list/callback_args, savereturns = TRUE, resolution = 1)
- if (!callbacks)
- return
- var/count = length(callbacks)
- if (!count)
- return
- if (!callback_args)
- callback_args = list()
-
- callback_args.len = count
-
- var/datum/callback_select/CS = new(count, savereturns)
- for (var/i in 1 to count)
- CS.invoke_callback(i, callbacks[i], callback_args[i], savereturns)
- debug_usr("starting callbacks: [CS.pendingcount]")
- while(CS.pendingcount)
- debug_usr("callbacks: [CS.pendingcount]")
- sleep(resolution*world.tick_lag)
- return CS.finished
-
+26 -17
View File
@@ -27,17 +27,21 @@ Stands have a lot of procs which mimic mob procs. Rather than inserting hooks fo
### Vars
1. `/datum/var/list/datum_components` (private)
* Lazy list of all components a datum has (TODO: Make this a typecache with longer paths overwriting shorter ones maybe? It'd be weird)
* Lazy associated list of type -> component/list of components.
1. `/datum/component/var/enabled` (protected, boolean)
* If the component is enabled. If not, it will not react to signals
* TRUE by default
* `TRUE` by default
1. `/datum/component/var/dupe_mode` (protected, enum)
* How multiple components of the exact same type are handled when added to the datum.
* How duplicate component types are handled when added to the datum.
* `COMPONENT_DUPE_HIGHLANDER` (default): Old component will be deleted, new component will first have `/datum/component/proc/InheritComponent(datum/component/old, FALSE)` on it
* `COMPONENT_DUPE_ALLOWED`: The components will be treated as seperate, `GetComponent()` will return the first added
* `COMPONENT_DUPE_ALLOWED`: The components will be treated as separate, `GetComponent()` will return the first added
* `COMPONENT_DUPE_UNIQUE`: New component will be deleted, old component will first have `/datum/component/proc/InheritComponent(datum/component/new, TRUE)` on it
1. `/datum/component/var/dupe_type` (protected, type)
* Definition of a duplicate component type
* `null` means exact match on `type`
* Any other type means that and all subtypes
1. `/datum/component/var/list/signal_procs` (private)
* Associated lazy list of signals -> callbacks that will be run when the parent datum recieves that signal
* Associated lazy list of signals -> `/datum/callback`s that will be run when the parent datum recieves that signal
1. `/datum/component/var/datum/parent` (protected, read-only)
* The datum this component belongs to
@@ -52,10 +56,12 @@ Stands have a lot of procs which mimic mob procs. Rather than inserting hooks fo
1. `GET_COMPONENT(varname, component_type)` OR `GET_COMPONENT_FROM(varname, component_type, src)`
* Shorthand for `var/component_type/varname = src.GetComponent(component_type)`
1. `/datum/proc/AddComponent(component_type(type), ...) -> datum/component` (public, final)
* Creates an instance of `component_type` in the datum and passes `...` to it's `New()` call
* Creates an instance of `component_type` in the datum and passes `...` to its `Initialize()` call
* Sends the `COMSIG_COMPONENT_ADDED` signal to the datum
* All components a datum owns are deleted with the datum
* Returns the component that was created. Or the old component in a dupe situation where `COMPONENT_DUPE_UNIQUE` was set
1. `/datum/proc/LoadComponent(component_type(type), ...) -> datum/component` (public, final)
* Equivalent to calling `GetComponent(component_type)` where, if the result would be `null`, returns `AddComponent(component_type, ...)` instead
1. `/datum/proc/ComponentActivated(datum/component/C)` (abstract)
* Called on a component's `parent` after a signal recieved causes it to activate. `src` is the parameter
* Will only be called if a component's callback returns `TRUE`
@@ -66,16 +72,24 @@ Stands have a lot of procs which mimic mob procs. Rather than inserting hooks fo
1. `/datum/proc/SendSignal(signal, ...)` (public, final)
* Call to send a signal to the components of the target datum
* Extra arguments are to be specified in the signal definition
1. `/datum/component/New(datum/parent, ...)` (protected, virtual)
* Forwarded the arguments from `AddComponent()`
1. `/datum/component/Destroy()` (virtual)
1. `/datum/component/New(datum/parent, ...)` (private, final)
* Runs internal setup for the component
* Extra arguments are passed to `Initialize()`
1. `/datum/component/Initialize(...)` (abstract, no-sleep)
* Called by `New()` with the same argments excluding `parent`
* Component does not exist in `parent`'s `datum_components` list yet, although `parent` is set and may be used
* Signals will not be recieved while this function is running
* Component may be deleted after this function completes without being attached
1. `/datum/component/Destroy()` (virtual, no-sleep)
* Sends the `COMSIG_COMPONENT_REMOVING` signal to the parent datum if the `parent` isn't being qdeleted
* Properly removes the component from `parent` and cleans up references
1. `/datum/component/proc/InheritComponent(datum/component/C, i_am_original(boolean))` (abstract)
1. `/datum/component/proc/InheritComponent(datum/component/C, i_am_original(boolean))` (abstract, no-sleep)
* Called on a component when a component of the same type was added to the same parent
* See `/datum/component/var/dupe_mode`
* `C`'s type will always be the same of the called component
1. `/datum/component/proc/OnTransfer(datum/new_parent)` (abstract)
1. `/datum/component/proc/AfterComponentActivated()` (abstract)
* Called on a component that was activated after it's `parent`'s `ComponentActivated()` is called
1. `/datum/component/proc/OnTransfer(datum/new_parent)` (abstract, no-sleep)
* Called before the new `parent` is assigned in `TakeComponent()`, after the remove signal, before the added signal
* Allows the component to react to ownership transfers
1. `/datum/component/proc/_RemoveNoSignal()` (private, final)
@@ -91,9 +105,4 @@ Stands have a lot of procs which mimic mob procs. Rather than inserting hooks fo
* Called when a component recieves any signal and is enabled
* Default implementation looks if the signal is registered and runs the appropriate proc
### See signals and their arguments in __DEFINES\components.dm
## Examples
Material Containers: #29268 (Too many GetComponent calls, but not bad)
Slips: #00000 (PR DIS)
Powercells: (TODO)
### See/Define signals and their arguments in __DEFINES\components.dm
+50 -18
View File
@@ -1,22 +1,36 @@
/datum/component
var/enabled = TRUE
var/dupe_mode = COMPONENT_DUPE_HIGHLANDER
var/dupe_type
var/list/signal_procs
var/datum/parent
/datum/component/New(datum/P, ...)
parent = P
var/list/arguments = args.Copy()
arguments.Cut(1, 2)
Initialize(arglist(arguments))
var/dm = dupe_mode
if(dm != COMPONENT_DUPE_ALLOWED)
var/datum/component/old = P.GetExactComponent(type)
var/dt = dupe_type
var/datum/component/old
if(!dt)
old = P.GetExactComponent(type)
else
old = P.GetComponent(dt)
if(old)
switch(dm)
if(COMPONENT_DUPE_UNIQUE)
old.InheritComponent(src, TRUE)
parent = null //prevent COMPONENT_REMOVING signal
qdel(src)
return
if(COMPONENT_DUPE_HIGHLANDER)
InheritComponent(old, FALSE)
qdel(old)
if(COMPONENT_DUPE_UNIQUE)
old.InheritComponent(src, TRUE)
qdel(src)
return
//let the others know
P.SendSignal(COMSIG_COMPONENT_ADDED, src)
//lazy init the parent's dc list
@@ -26,7 +40,7 @@
//set up the typecache
var/our_type = type
for(var/I in _GetInverseTypeListExceptRoot(our_type))
for(var/I in _GetInverseTypeList(our_type))
var/test = dc[I]
if(test) //already another component of this type here
var/list/components_of_type
@@ -50,7 +64,8 @@
else //only component of this type, no list
dc[I] = src
parent = P
/datum/component/proc/Initialize(...)
return
/datum/component/Destroy()
enabled = FALSE
@@ -66,7 +81,7 @@
if(P)
var/list/dc = P.datum_components
var/our_type = type
for(var/I in _GetInverseTypeListExceptRoot(our_type))
for(var/I in _GetInverseTypeList(our_type))
var/list/components_of_type = dc[I]
if(islist(components_of_type)) //
var/list/subtracted = components_of_type - src
@@ -110,23 +125,35 @@
/datum/component/proc/OnTransfer(datum/new_parent)
return
/datum/component/proc/_GetInverseTypeListExceptRoot(our_type_cached)
var/datum/component/current_type = our_type_cached
. = list()
/datum/component/proc/AfterComponentActivated()
return
/datum/component/proc/_GetInverseTypeList(current_type)
. = list(current_type)
while (current_type != /datum/component)
. += current_type
current_type = type2parent(current_type)
. += current_type
/datum/proc/SendSignal(sigtype, ...)
var/list/comps = datum_components
. = FALSE
for(var/I in comps)
var/datum/component/C = I
if(!C.enabled)
continue
if(C.ReceiveSignal(arglist(args)))
if(!comps)
return
var/target = comps[/datum/component]
if(!islist(target))
var/datum/component/C = target
if(C.enabled && C.ReceiveSignal(arglist(args)))
ComponentActivated(C)
. = TRUE
C.AfterComponentActivated()
return TRUE
else
for(var/I in target)
var/datum/component/C = I
if(!C.enabled)
continue
if(C.ReceiveSignal(arglist(args)))
ComponentActivated(C)
. = TRUE
/datum/proc/ComponentActivated(datum/component/C)
return
@@ -165,6 +192,11 @@
var/datum/component/C = new nt(arglist(args))
return QDELING(C) ? GetComponent(new_type) : C
/datum/proc/LoadComponent(component_type, ...)
. = GetComponent(component_type)
if(!.)
return AddComponent(arglist(args))
/datum/proc/TakeComponent(datum/component/C)
if(!C)
return
-18
View File
@@ -1,18 +0,0 @@
diff a/code/datums/components/component.dm b/code/datums/components/component.dm (rejected hunks)
@@ -22,8 +22,7 @@
//lazy init the parent's dc list
var/list/dc = P.datum_components
if(!dc)
- dc = list()
- P.datum_components = dc
+ P.datum_components = dc = list()
//set up the typecache
var/our_type = type
@@ -179,4 +178,4 @@
helicopter.SendSignal(COMSIG_COMPONENT_REMOVING, C)
C.OnTransfer(src)
C.parent = src
- SendSignal(COMSIG_COMPONENT_ADDED, C)
\ No newline at end of file
+ SendSignal(COMSIG_COMPONENT_ADDED, C)
+21
View File
@@ -0,0 +1,21 @@
/datum/component/slippery
var/intensity
var/lube_flags
var/mob/slip_victim
/datum/component/slippery/Initialize(_intensity, _lube_flags = NONE)
intensity = max(_intensity, 0)
lube_flags = _lube_flags
if(ismovableatom(parent))
RegisterSignal(COMSIG_MOVABLE_CROSSED, .proc/Slip)
else
RegisterSignal(COMSIG_ATOM_ENTERED, .proc/Slip)
/datum/component/slippery/proc/Slip(atom/movable/AM)
var/mob/victim = AM
if(istype(victim) && !victim.is_flying() && victim.slip(intensity, parent, lube_flags))
slip_victim = victim
return TRUE
/datum/component/slippery/AfterComponentActivated()
slip_victim = null
+2 -2
View File
@@ -210,8 +210,8 @@
if(!C)
C = H.client
var/image = get_id_photo(H, C)
var/obj/item/weapon/photo/photo_front = new()
var/obj/item/weapon/photo/photo_side = new()
var/obj/item/photo/photo_front = new()
var/obj/item/photo/photo_side = new()
photo_front.photocreate(null, icon(image, dir = SOUTH))
photo_side.photocreate(null, icon(image, dir = WEST))
+11 -5
View File
@@ -22,10 +22,16 @@
continue
qdel(timer)
var/list/dc = datum_components
for(var/I in dc)
var/datum/component/C = I
C._RemoveNoSignal()
qdel(C)
if(dc)
var/all_components = dc[/datum/component]
if(islist(all_components))
for(var/I in all_components)
var/datum/component/C = I
C._RemoveNoSignal()
qdel(C)
else
var/datum/component/C = all_components
C._RemoveNoSignal()
qdel(C)
dc.Cut()
return QDEL_HINT_QUEUE
return QDEL_HINT_QUEUE
+2 -2
View File
@@ -43,7 +43,7 @@
SSdisease.active_diseases += DD //Add it to the active diseases list, now that it's actually in a mob and being processed.
//Copy properties over. This is so edited diseases persist.
var/list/skipped = list("affected_mob","holder","carrier","stage","type","parent_type","vars","transformed")
var/list/skipped = list("affected_mob","holder","carrier","stage","type","parent_type","vars","transformed","symptoms")
for(var/V in DD.vars)
if(V in skipped)
continue
@@ -92,7 +92,7 @@
switch(target_zone)
if(1)
if(isobj(H.head) && !istype(H.head, /obj/item/weapon/paper))
if(isobj(H.head) && !istype(H.head, /obj/item/paper))
Cl = H.head
passed = prob((Cl.permeability_coefficient*100) - 1)
if(passed && isobj(H.wear_mask))
+1 -3
View File
@@ -57,9 +57,7 @@
symptoms = GenerateSymptoms(0, 2)
else
for(var/datum/symptom/S in D.symptoms)
var/datum/symptom/new_symp = new S.type
new_symp.name = S.name
new_symp.neutered = S.neutered
var/datum/symptom/new_symp = S.Copy()
symptoms += new_symp
Refresh()
+3 -3
View File
@@ -19,7 +19,7 @@
to_chat(affected_mob, "<span class='danger'>You feel a slight shock course through your body.</span>")
if(prob(2))
for(var/obj/M in orange(2,affected_mob))
if(!M.anchored && (M.flags & CONDUCT))
if(!M.anchored && (M.flags_1 & CONDUCT_1))
step_towards(M,affected_mob)
for(var/mob/living/silicon/S in orange(2,affected_mob))
if(isAI(S))
@@ -32,7 +32,7 @@
to_chat(affected_mob, "<span class='danger'>You feel like clowning around.</span>")
if(prob(4))
for(var/obj/M in orange(4,affected_mob))
if(!M.anchored && (M.flags & CONDUCT))
if(!M.anchored && (M.flags_1 & CONDUCT_1))
var/i
var/iter = rand(1,2)
for(i=0,i<iter,i++)
@@ -51,7 +51,7 @@
to_chat(affected_mob, "<span class='danger'>You query upon the nature of miracles.</span>")
if(prob(8))
for(var/obj/M in orange(6,affected_mob))
if(!M.anchored && (M.flags & CONDUCT))
if(!M.anchored && (M.flags_1 & CONDUCT_1))
var/i
var/iter = rand(1,3)
for(i=0,i<iter,i++)
+1 -1
View File
@@ -78,7 +78,7 @@ STI KALY - blind
else
var/mob/living/carbon/H = affected_mob
if(prob(chance))
var/obj/item/weapon/staff/S = new(H)
var/obj/item/staff/S = new(H)
if(!H.put_in_hands(S))
qdel(S)
+1 -1
View File
@@ -38,7 +38,7 @@
msg = replace_pronoun(user, msg)
var/mob/living/L = user
for(var/obj/item/weapon/implant/I in L.implants)
for(var/obj/item/implant/I in L.implants)
I.trigger(key, L)
if(!msg)
+2 -2
View File
@@ -149,10 +149,10 @@
/datum/teleport/instant/science/setPrecision(aprecision)
..()
if(istype(teleatom, /obj/item/weapon/storage/backpack/holding))
if(istype(teleatom, /obj/item/storage/backpack/holding))
precision = rand(1,100)
var/list/bagholding = teleatom.search_contents_for(/obj/item/weapon/storage/backpack/holding)
var/list/bagholding = teleatom.search_contents_for(/obj/item/storage/backpack/holding)
if(bagholding.len)
precision = max(rand(1,100)*bagholding.len,100)
if(isliving(teleatom))
+8 -6
View File
@@ -27,7 +27,7 @@
var/config_max_users = 0
var/config_min_users = 0
var/voteweight = 1
var/allow_custom_shuttles = "yes"
/datum/map_config/New(filename = "data/next_map.json", default_to_box, delete_after)
if(default_to_box)
return
@@ -44,12 +44,12 @@
if(!json)
log_world("Could not open map_config: [filename]")
return
json = file2text(json)
if(!json)
log_world("map_config is not text: [filename]")
return
json = json_decode(json)
if(!json)
log_world("map_config is not json: [filename]")
@@ -58,7 +58,7 @@
if(!ValidateJSON(json))
log_world("map_config failed to validate for above reason: [filename]")
return
config_filename = filename
map_name = json["map_name"]
@@ -66,6 +66,7 @@
map_file = json["map_file"]
minetype = json["minetype"]
allow_custom_shuttles = json["allow_custom_shuttles"]
var/list/jtcl = json["transition_config"]
@@ -74,7 +75,7 @@
for(var/I in jtcl)
transition_config[TransitionStringToEnum(I)] = TransitionStringToEnum(jtcl[I])
defaulted = FALSE
#define CHECK_EXISTS(X) if(!istext(json[X])) { log_world(X + "missing from json!"); return; }
@@ -84,6 +85,7 @@
CHECK_EXISTS("map_file")
CHECK_EXISTS("minetype")
CHECK_EXISTS("transition_config")
CHECK_EXISTS("allow_custom_shuttles")
var/path = GetFullMapPath(json["map_path"], json["map_file"])
if(!fexists(path))
@@ -92,7 +94,7 @@
if(json["transition_config"] != "default")
if(!islist(json["transition_config"]))
log_world("transition_config is not a list!")
log_world("transition_config is not a list!")
return
var/list/jtcl = json["transition_config"]
+2 -2
View File
@@ -181,13 +181,13 @@
to_chat(usr, "<b><i>In addition, by having your throw mode on when being attacked, you enter an active defense mode where you have a chance to block and sometimes even counter attacks done to you.</i></b>")
/obj/item/weapon/cqc_manual
/obj/item/cqc_manual
name = "old manual"
desc = "A small, black manual. There are drawn instructions of tactical hand-to-hand combat."
icon = 'icons/obj/library.dmi'
icon_state ="cqcmanual"
/obj/item/weapon/cqc_manual/attack_self(mob/living/carbon/human/user)
/obj/item/cqc_manual/attack_self(mob/living/carbon/human/user)
if(!istype(user) || !user)
return
to_chat(user, "<span class='boldannounce'>You remember the basics of CQC.</span>")
+2 -2
View File
@@ -93,14 +93,14 @@
to_chat(usr, "<span class='notice'>Throwback</span>: Disarm Harm Disarm. Throws the target and an item at them.")
to_chat(usr, "<span class='notice'>The Plasma Fist</span>: Harm Disarm Disarm Disarm Harm. Knocks the brain out of the opponent and gibs their body.")
/obj/item/weapon/plasma_fist_scroll
/obj/item/plasma_fist_scroll
name = "frayed scroll"
desc = "An aged and frayed scrap of paper written in shifting runes. There are hand-drawn illustrations of pugilism."
icon = 'icons/obj/wizard.dmi'
icon_state ="scroll2"
var/used = 0
/obj/item/weapon/plasma_fist_scroll/attack_self(mob/user)
/obj/item/plasma_fist_scroll/attack_self(mob/user)
if(!ishuman(user))
return
if(!used)
+7 -7
View File
@@ -154,13 +154,13 @@
to_chat(usr, "<span class='notice'>Head Kick</span>: Disarm Harm Harm. Decent damage, forces opponent to drop item in hand.")
to_chat(usr, "<span class='notice'>Elbow Drop</span>: Harm Disarm Harm Disarm Harm. Opponent must be on the ground. Deals huge damage, instantly kills anyone in critical condition.")
/obj/item/weapon/sleeping_carp_scroll
/obj/item/sleeping_carp_scroll
name = "mysterious scroll"
desc = "A scroll filled with strange markings. It seems to be drawings of some sort of martial art."
icon = 'icons/obj/wizard.dmi'
icon_state = "scroll2"
/obj/item/weapon/sleeping_carp_scroll/attack_self(mob/living/carbon/human/user)
/obj/item/sleeping_carp_scroll/attack_self(mob/living/carbon/human/user)
if(!istype(user) || !user)
return
var/message = "<span class='sciradio'>You have learned the ancient martial art of the Sleeping Carp! Your hand-to-hand combat has become much more effective, and you are now able to deflect any projectiles \
@@ -173,7 +173,7 @@
new /obj/effect/decal/cleanable/ash(get_turf(src))
qdel(src)
/obj/item/weapon/twohanded/bostaff
/obj/item/twohanded/bostaff
name = "bo staff"
desc = "A long, tall staff made of polished wood. Traditionally used in ancient old-Earth martial arts. Can be wielded to both kill and incapacitate."
force = 10
@@ -184,17 +184,17 @@
throwforce = 20
throw_speed = 2
attack_verb = list("smashed", "slammed", "whacked", "thwacked")
icon = 'icons/obj/weapons.dmi'
icon = 'icons/obj/items_and_weapons.dmi'
icon_state = "bostaff0"
lefthand_file = 'icons/mob/inhands/weapons/staves_lefthand.dmi'
righthand_file = 'icons/mob/inhands/weapons/staves_righthand.dmi'
block_chance = 50
/obj/item/weapon/twohanded/bostaff/update_icon()
/obj/item/twohanded/bostaff/update_icon()
icon_state = "bostaff[wielded]"
return
/obj/item/weapon/twohanded/bostaff/attack(mob/target, mob/living/user)
/obj/item/twohanded/bostaff/attack(mob/target, mob/living/user)
add_fingerprint(user)
if((CLUMSY in user.disabilities) && prob(50))
to_chat(user, "<span class ='warning'>You club yourself over the head with [src].</span>")
@@ -243,7 +243,7 @@
else
return ..()
/obj/item/weapon/twohanded/bostaff/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
/obj/item/twohanded/bostaff/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
if(wielded)
return ..()
return 0

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