Merge branch 'master' into upstream-merge-29718
This commit is contained in:
@@ -22,7 +22,7 @@
|
||||
#define START_PROCESSING(Processor, Datum) if (!Datum.isprocessing) {Datum.isprocessing = TRUE;Processor.processing += Datum}
|
||||
#define STOP_PROCESSING(Processor, Datum) Datum.isprocessing = FALSE;Processor.processing -= Datum
|
||||
|
||||
//SubSystem flags (Please design any new flags so that the default is off, to make adding flags to subsystems easier)
|
||||
//SubSystem flags_1 (Please design any new flags_1 so that the default is off, to make adding flags_1 to subsystems easier)
|
||||
|
||||
//subsystem does not initialize.
|
||||
#define SS_NO_INIT 1
|
||||
|
||||
@@ -76,7 +76,7 @@
|
||||
#define ACCESS_CENT_STORAGE 106//Generic storage areas.
|
||||
#define ACCESS_CENT_TELEPORTER 107//Teleporter.
|
||||
#define ACCESS_CENT_CAPTAIN 109//Captain's office/ID comp/AI.
|
||||
#define ACCESS_CENT_BAR 110 // The non-existent Centcom Bar
|
||||
#define ACCESS_CENT_BAR 110 // The non-existent CentCom Bar
|
||||
|
||||
//The Syndicate
|
||||
#define ACCESS_SYNDICATE 150//General Syndicate Access
|
||||
@@ -93,4 +93,9 @@
|
||||
#define ACCESS_AWAY_GENERIC1 205//Away generic access
|
||||
#define ACCESS_AWAY_GENERIC2 206
|
||||
#define ACCESS_AWAY_GENERIC3 207
|
||||
#define ACCESS_AWAY_GENERIC4 208
|
||||
#define ACCESS_AWAY_GENERIC4 208
|
||||
|
||||
//Special, for anything that's basically internal
|
||||
#define ACCESS_BLOODCULT 250
|
||||
#define ACCESS_CLOCKCULT 251
|
||||
|
||||
|
||||
@@ -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;CentcommReply=\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>)"
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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))
|
||||
|
||||
|
||||
+11
-10
@@ -1,15 +1,16 @@
|
||||
//Investigate logging defines
|
||||
#define INVESTIGATE_ATMOS "atmos"
|
||||
#define INVESTIGATE_BOTANY "botany"
|
||||
#define INVESTIGATE_CARGO "cargo"
|
||||
#define INVESTIGATE_EXPERIMENTOR "experimentor"
|
||||
#define INVESTIGATE_GRAVITY "gravity"
|
||||
#define INVESTIGATE_RECORDS "records"
|
||||
#define INVESTIGATE_SINGULO "singulo"
|
||||
#define INVESTIGATE_SUPERMATTER "supermatter"
|
||||
#define INVESTIGATE_TELESCI "telesci"
|
||||
#define INVESTIGATE_WIRES "wires"
|
||||
#define INVESTIGATE_ATMOS "atmos"
|
||||
#define INVESTIGATE_BOTANY "botany"
|
||||
#define INVESTIGATE_CARGO "cargo"
|
||||
#define INVESTIGATE_EXPERIMENTOR "experimentor"
|
||||
#define INVESTIGATE_GRAVITY "gravity"
|
||||
#define INVESTIGATE_RECORDS "records"
|
||||
#define INVESTIGATE_SINGULO "singulo"
|
||||
#define INVESTIGATE_SUPERMATTER "supermatter"
|
||||
#define INVESTIGATE_TELESCI "telesci"
|
||||
#define INVESTIGATE_WIRES "wires"
|
||||
#define INVESTIGATE_PORTAL "portals"
|
||||
#define INVESTIGATE_HALLUCINATIONS "hallucinations"
|
||||
|
||||
//Individual logging defines
|
||||
#define INDIVIDUAL_ATTACK_LOG "Attack log"
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
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"
|
||||
@@ -5,7 +5,7 @@ Names of z-level do not matter, but order does greatly, for instances such as ch
|
||||
|
||||
current as of 2016/6/2
|
||||
z1 = station
|
||||
z2 = centcomm
|
||||
z2 = centcom
|
||||
z5 = mining
|
||||
Everything else = randomized space
|
||||
Last space-z level = empty
|
||||
@@ -16,7 +16,7 @@ Last space-z level = empty
|
||||
#define UNAFFECTED 0
|
||||
|
||||
#define MAIN_STATION "Main Station"
|
||||
#define CENTCOMM "CentComm"
|
||||
#define CENTCOM "CentCom"
|
||||
#define EMPTY_AREA_1 "Empty Area 1"
|
||||
#define EMPTY_AREA_2 "Empty Area 2"
|
||||
#define MINING "Mining Asteroid"
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
//You can use these defines to get the typepath of the currently running proc/verb (yes procs + verbs are objects)
|
||||
/* eg:
|
||||
/mob/living/carbon/human/death()
|
||||
world << THIS_PROC_TYPE_STR //You can only output the string versions
|
||||
to_chat(world, THIS_PROC_TYPE_STR) //You can only output the string versions
|
||||
Will print: "/mob/living/carbon/human/death" (you can optionally embed it in a string with () (eg: the _WITH_ARGS defines) to make it look nicer)
|
||||
*/
|
||||
#define THIS_PROC_TYPE .....
|
||||
@@ -46,8 +46,8 @@ Will print: "/mob/living/carbon/human/death" (you can optionally embed it in a s
|
||||
//Human Overlays Indexes/////////
|
||||
//citadel code
|
||||
#define MUTATIONS_LAYER 30 //mutations. Tk headglows, cold resistance glow, etc
|
||||
#define BODY_BEHIND_LAYER 29 //certain mutantrace features (tail when looking south) that must appear behind the body parts
|
||||
#define GENITALS_BEHIND_LAYER 28
|
||||
#define GENITALS_BEHIND_LAYER 29 //Some genitalia needs to be behind everything, such as with taurs (Taurs use body_behind_layer
|
||||
#define BODY_BEHIND_LAYER 28 //certain mutantrace features (tail when looking south) that must appear behind the body parts
|
||||
#define BODYPARTS_LAYER 27 //Initially "AUGMENTS", this was repurposed to be a catch-all bodyparts flag
|
||||
#define BODY_ADJ_LAYER 26 //certain mutantrace features (snout, body markings) that must appear above the body parts
|
||||
#define GENITALS_ADJ_LAYER 25
|
||||
@@ -350,6 +350,7 @@ GLOBAL_LIST_INIT(ghost_others_options, list(GHOST_OTHERS_SIMPLE, GHOST_OTHERS_DE
|
||||
|
||||
//debug printing macros
|
||||
#define debug_world(msg) if (GLOB.Debug2) to_chat(world, "DEBUG: [msg]")
|
||||
#define debug_usr(msg) if (GLOB.Debug2&&usr) to_chat(usr, "DEBUG: [msg]")
|
||||
#define debug_admins(msg) if (GLOB.Debug2) to_chat(GLOB.admins, "DEBUG: [msg]")
|
||||
#define debug_world_log(msg) if (GLOB.Debug2) log_world("DEBUG: [msg]")
|
||||
|
||||
@@ -440,3 +441,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
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -4,6 +4,9 @@
|
||||
|
||||
#define IRC_STATUS_THROTTLE 5
|
||||
|
||||
#define PR_ANNOUNCEMENTS_PER_ROUND 5 //The number of unique PR announcements allowed per round
|
||||
//This makes sure that a single person can only spam 3 reopens and 3 closes before being ignored
|
||||
|
||||
//keep these in sync with TGS3
|
||||
#define SERVICE_WORLD_PARAM "server_service"
|
||||
#define SERVICE_PR_TEST_JSON "..\\..\\prtestjob.json"
|
||||
@@ -17,7 +20,7 @@
|
||||
#define SERVICE_CMD_NAME_CHECK "namecheck"
|
||||
#define SERVICE_CMD_ADMIN_WHO "adminwho"
|
||||
|
||||
//#define SERVICE_CMD_PARAM_KEY //defined in __compile_options.dm
|
||||
#define SERVICE_CMD_PARAM_KEY "serviceCommsKey"
|
||||
#define SERVICE_CMD_PARAM_COMMAND "command"
|
||||
#define SERVICE_CMD_PARAM_MESSAGE "message"
|
||||
#define SERVICE_CMD_PARAM_TARGET "target"
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
#define SHUTTLE_ALREADY_DOCKED "we_are_already_docked"
|
||||
#define SHUTTLE_SOMEONE_ELSE_DOCKED "someone_else_docked"
|
||||
|
||||
//Launching Shuttles to Centcomm
|
||||
//Launching Shuttles to CentCom
|
||||
#define NOLAUNCH -1
|
||||
#define UNLAUNCHED 0
|
||||
#define ENDGAME_LAUNCHED 1
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -91,16 +91,23 @@
|
||||
//returns a new list with only atoms that are in typecache L
|
||||
/proc/typecache_filter_list(list/atoms, list/typecache)
|
||||
. = list()
|
||||
for (var/thing in atoms)
|
||||
for(var/thing in atoms)
|
||||
var/atom/A = thing
|
||||
if (typecache[A.type])
|
||||
. += A
|
||||
|
||||
/proc/typecache_filter_list_reverse(list/atoms, list/typecache)
|
||||
. = list()
|
||||
for (var/thing in atoms)
|
||||
for(var/thing in atoms)
|
||||
var/atom/A = thing
|
||||
if (!typecache[A.type])
|
||||
if(!typecache[A.type])
|
||||
. += A
|
||||
|
||||
/proc/typecache_filter_multi_list_exclusion(list/atoms, list/typecache_include, list/typecache_exclude)
|
||||
. = list()
|
||||
for(var/thing in atoms)
|
||||
var/atom/A = thing
|
||||
if(typecache_include[A.type] && !typecache_exclude[A.type])
|
||||
. += A
|
||||
|
||||
//Like typesof() or subtypesof(), but returns a typecache instead of a list
|
||||
@@ -177,7 +184,11 @@
|
||||
result = first ^ second
|
||||
return result
|
||||
|
||||
//Pretends to pick an element based on its weight but really just seems to pick a random element.
|
||||
//Picks a random element from a list based on a weighting system:
|
||||
//1. Adds up the total of weights for each element
|
||||
//2. Gets a number between 1 and that total
|
||||
//3. For each element in the list, subtracts its weighting from that number
|
||||
//4. If that makes the number 0 or less, return that element.
|
||||
/proc/pickweight(list/L)
|
||||
var/total = 0
|
||||
var/item
|
||||
@@ -309,7 +320,7 @@
|
||||
return r
|
||||
|
||||
// Returns the key based on the index
|
||||
#define KEYBYINDEX(L, index) (((index <= L:len) && (index > 0)) ? L[index] : null)
|
||||
#define KEYBYINDEX(L, index) (((index <= length(L)) && (index > 0)) ? L[index] : null)
|
||||
|
||||
/proc/count_by_type(list/L, type)
|
||||
var/i = 0
|
||||
@@ -457,7 +468,7 @@
|
||||
. |= key_list[key]
|
||||
|
||||
//Picks from the list, with some safeties, and returns the "default" arg if it fails
|
||||
#define DEFAULTPICK(L, default) ((islist(L) && L:len) ? pick(L) : default)
|
||||
#define DEFAULTPICK(L, default) ((islist(L) && length(L)) ? pick(L) : default)
|
||||
#define LAZYINITLIST(L) if (!L) L = list()
|
||||
#define UNSETEMPTY(L) if (L && !L.len) L = null
|
||||
#define LAZYREMOVE(L, I) if(L) { L -= I; if(!L.len) { L = null; } }
|
||||
|
||||
+25
-19
@@ -1,3 +1,10 @@
|
||||
//wrapper macros for easier grepping
|
||||
#define DIRECT_OUTPUT(A, B) A << B
|
||||
#define SEND_IMAGE(target, image) DIRECT_OUTPUT(target, image)
|
||||
#define SEND_SOUND(target, sound) DIRECT_OUTPUT(target, sound)
|
||||
#define SEND_TEXT(target, text) DIRECT_OUTPUT(target, text)
|
||||
#define WRITE_FILE(file, text) DIRECT_OUTPUT(file, text)
|
||||
|
||||
//print a warning message to world.log
|
||||
#define WARNING(MSG) warning("[MSG] in [__FILE__] at line [__LINE__] src: [src] usr: [usr].")
|
||||
/proc/warning(msg)
|
||||
@@ -20,13 +27,13 @@
|
||||
/proc/log_admin(text)
|
||||
GLOB.admin_log.Add(text)
|
||||
if (config.log_admin)
|
||||
GLOB.world_game_log << "\[[time_stamp()]]ADMIN: [text]"
|
||||
WRITE_FILE(GLOB.world_game_log, "\[[time_stamp()]]ADMIN: [text]")
|
||||
|
||||
//Items using this proc are stripped from public logs - use with caution
|
||||
/proc/log_admin_private(text)
|
||||
GLOB.admin_log.Add(text)
|
||||
if (config.log_admin)
|
||||
GLOB.world_game_log << "\[[time_stamp()]]ADMINPRIVATE: [text]"
|
||||
WRITE_FILE(GLOB.world_game_log, "\[[time_stamp()]]ADMINPRIVATE: [text]")
|
||||
|
||||
/proc/log_adminsay(text)
|
||||
if (config.log_adminchat)
|
||||
@@ -38,65 +45,64 @@
|
||||
|
||||
/proc/log_game(text)
|
||||
if (config.log_game)
|
||||
GLOB.world_game_log << "\[[time_stamp()]]GAME: [text]"
|
||||
WRITE_FILE(GLOB.world_game_log, "\[[time_stamp()]]GAME: [text]")
|
||||
|
||||
/proc/log_vote(text)
|
||||
if (config.log_vote)
|
||||
GLOB.world_game_log << "\[[time_stamp()]]VOTE: [text]"
|
||||
WRITE_FILE(GLOB.world_game_log, "\[[time_stamp()]]VOTE: [text]")
|
||||
|
||||
/proc/log_access(text)
|
||||
if (config.log_access)
|
||||
GLOB.world_game_log << "\[[time_stamp()]]ACCESS: [text]"
|
||||
WRITE_FILE(GLOB.world_game_log, "\[[time_stamp()]]ACCESS: [text]")
|
||||
|
||||
/proc/log_say(text)
|
||||
if (config.log_say)
|
||||
GLOB.world_game_log << "\[[time_stamp()]]SAY: [text]"
|
||||
WRITE_FILE(GLOB.world_game_log, "\[[time_stamp()]]SAY: [text]")
|
||||
|
||||
/proc/log_prayer(text)
|
||||
if (config.log_prayer)
|
||||
GLOB.world_game_log << "\[[time_stamp()]]PRAY: [text]"
|
||||
WRITE_FILE(GLOB.world_game_log, "\[[time_stamp()]]PRAY: [text]")
|
||||
|
||||
/proc/log_law(text)
|
||||
if (config.log_law)
|
||||
GLOB.world_game_log << "\[[time_stamp()]]LAW: [text]"
|
||||
WRITE_FILE(GLOB.world_game_log, "\[[time_stamp()]]LAW: [text]")
|
||||
|
||||
/proc/log_ooc(text)
|
||||
if (config.log_ooc)
|
||||
GLOB.world_game_log << "\[[time_stamp()]]OOC: [text]"
|
||||
WRITE_FILE(GLOB.world_game_log, "\[[time_stamp()]]OOC: [text]")
|
||||
|
||||
/proc/log_whisper(text)
|
||||
if (config.log_whisper)
|
||||
GLOB.world_game_log << "\[[time_stamp()]]WHISPER: [text]"
|
||||
WRITE_FILE(GLOB.world_game_log, "\[[time_stamp()]]WHISPER: [text]")
|
||||
|
||||
/proc/log_emote(text)
|
||||
if (config.log_emote)
|
||||
GLOB.world_game_log << "\[[time_stamp()]]EMOTE: [text]"
|
||||
WRITE_FILE(GLOB.world_game_log, "\[[time_stamp()]]EMOTE: [text]")
|
||||
|
||||
/proc/log_attack(text)
|
||||
if (config.log_attack)
|
||||
GLOB.world_attack_log << "\[[time_stamp()]]ATTACK: [text]"
|
||||
WRITE_FILE(GLOB.world_attack_log, "\[[time_stamp()]]ATTACK: [text]")
|
||||
|
||||
/proc/log_pda(text)
|
||||
if (config.log_pda)
|
||||
GLOB.world_game_log << "\[[time_stamp()]]PDA: [text]"
|
||||
WRITE_FILE(GLOB.world_game_log, "\[[time_stamp()]]PDA: [text]")
|
||||
|
||||
/proc/log_comment(text)
|
||||
if (config.log_pda)
|
||||
//reusing the PDA option because I really don't think news comments are worth a config option
|
||||
GLOB.world_game_log << "\[[time_stamp()]]COMMENT: [text]"
|
||||
WRITE_FILE(GLOB.world_game_log, "\[[time_stamp()]]COMMENT: [text]")
|
||||
|
||||
/proc/log_chat(text)
|
||||
if (config.log_pda)
|
||||
GLOB.world_game_log << "\[[time_stamp()]]CHAT: [text]"
|
||||
WRITE_FILE(GLOB.world_game_log, "\[[time_stamp()]]CHAT: [text]")
|
||||
|
||||
/proc/log_sql(text)
|
||||
if(config.sql_enabled)
|
||||
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)
|
||||
GLOB.world_runtime_log << text
|
||||
world.log << text
|
||||
WRITE_FILE(GLOB.world_runtime_log, text)
|
||||
SEND_TEXT(world.log, text)
|
||||
|
||||
// Helper procs for building detailed log lines
|
||||
|
||||
|
||||
@@ -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) ; }
|
||||
@@ -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
|
||||
@@ -418,7 +418,7 @@
|
||||
/proc/showCandidatePollWindow(mob/M, poll_time, Question, list/candidates, ignore_category, time_passed, flashwindow = TRUE)
|
||||
set waitfor = 0
|
||||
|
||||
M << 'sound/misc/notice2.ogg' //Alerting them to their consideration
|
||||
SEND_SOUND(M, 'sound/misc/notice2.ogg') //Alerting them to their consideration
|
||||
if(flashwindow)
|
||||
window_flash(M.client)
|
||||
switch(ignore_category ? askuser(M,Question,"Please answer in [poll_time/10] seconds!","Yes","No","Never for this round", StealFocus=0, Timeout=poll_time) : askuser(M,Question,"Please answer in [poll_time/10] seconds!","Yes","No", StealFocus=0, Timeout=poll_time))
|
||||
@@ -426,7 +426,7 @@
|
||||
to_chat(M, "<span class='notice'>Choice registered: Yes.</span>")
|
||||
if(time_passed + poll_time <= world.time)
|
||||
to_chat(M, "<span class='danger'>Sorry, you answered too late to be considered!</span>")
|
||||
M << 'sound/machines/buzz-sigh.ogg'
|
||||
SEND_SOUND(M, 'sound/machines/buzz-sigh.ogg')
|
||||
candidates -= M
|
||||
else
|
||||
candidates += M
|
||||
|
||||
@@ -48,6 +48,11 @@
|
||||
init_sprite_accessory_subtypes(/datum/sprite_accessory/xeno_dorsal, GLOB.xeno_dorsal_list)
|
||||
//genitals
|
||||
init_sprite_accessory_subtypes(/datum/sprite_accessory/penis, GLOB.cock_shapes_list)
|
||||
|
||||
for(var/K in GLOB.cock_shapes_list)
|
||||
var/datum/sprite_accessory/penis/value = GLOB.cock_shapes_list[K]
|
||||
GLOB.cock_shapes_icons[K] = value.icon_state
|
||||
|
||||
init_sprite_accessory_subtypes(/datum/sprite_accessory/vagina, GLOB.vagina_shapes_list)
|
||||
init_sprite_accessory_subtypes(/datum/sprite_accessory/breasts, GLOB.breasts_shapes_list)
|
||||
GLOB.breasts_size_list = list("a","b","c","d","e") //We need the list to choose from initialized, but it's no longer a sprite_accessory thing.
|
||||
|
||||
@@ -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
|
||||
|
||||
+139
-34
@@ -167,7 +167,7 @@ mob
|
||||
|
||||
Output_Icon()
|
||||
set name = "2. Output Icon"
|
||||
to_chat(src, "Icon is: [bicon(getFlatIcon(src))]")
|
||||
to_chat(src, "Icon is: [icon2base64html(getFlatIcon(src))]")
|
||||
|
||||
Label_Icon()
|
||||
set name = "3. Label Icon"
|
||||
@@ -712,7 +712,8 @@ The _flatIcons list is a cache for generated icon files.
|
||||
if(!current)
|
||||
curIndex++ //Try the next layer
|
||||
continue
|
||||
currentLayer = current:layer
|
||||
var/image/I = current
|
||||
currentLayer = I.layer
|
||||
if(currentLayer<0) // Special case for FLY_LAYER
|
||||
if(currentLayer <= -1000) return flat
|
||||
if(pSet == 0) // Underlay
|
||||
@@ -747,22 +748,22 @@ The _flatIcons list is a cache for generated icon files.
|
||||
// Dimensions of overlay being added
|
||||
var/{addX1;addX2;addY1;addY2}
|
||||
|
||||
for(var/I in layers)
|
||||
|
||||
if(I:alpha == 0)
|
||||
for(var/V in layers)
|
||||
var/image/I = V
|
||||
if(I.alpha == 0)
|
||||
continue
|
||||
|
||||
if(I == copy) // 'I' is an /image based on the object being flattened.
|
||||
curblend = BLEND_OVERLAY
|
||||
add = icon(I:icon, I:icon_state, I:dir)
|
||||
add = icon(I.icon, I.icon_state, I.dir)
|
||||
else // 'I' is an appearance object.
|
||||
add = getFlatIcon(new/image(I), curdir, curicon, curstate, curblend)
|
||||
|
||||
// Find the new dimensions of the flat icon to fit the added overlay
|
||||
addX1 = min(flatX1, I:pixel_x+1)
|
||||
addX2 = max(flatX2, I:pixel_x+add.Width())
|
||||
addY1 = min(flatY1, I:pixel_y+1)
|
||||
addY2 = max(flatY2, I:pixel_y+add.Height())
|
||||
addX1 = min(flatX1, I.pixel_x+1)
|
||||
addX2 = max(flatX2, I.pixel_x+add.Width())
|
||||
addY1 = min(flatY1, I.pixel_y+1)
|
||||
addY2 = max(flatY2, I.pixel_y+add.Height())
|
||||
|
||||
if(addX1!=flatX1 || addX2!=flatX2 || addY1!=flatY1 || addY2!=flatY2)
|
||||
// Resize the flattened icon so the new icon fits
|
||||
@@ -771,7 +772,7 @@ The _flatIcons list is a cache for generated icon files.
|
||||
flatY1=addY1;flatY2=addY2
|
||||
|
||||
// Blend the overlay into the flattened icon
|
||||
flat.Blend(add, blendMode2iconMode(curblend), I:pixel_x + 2 - flatX1, I:pixel_y + 2 - flatY1)
|
||||
flat.Blend(add, blendMode2iconMode(curblend), I.pixel_x + 2 - flatX1, I.pixel_y + 2 - flatY1)
|
||||
|
||||
if(A.color)
|
||||
flat.Blend(A.color, ICON_MULTIPLY)
|
||||
@@ -782,10 +783,11 @@ The _flatIcons list is a cache for generated icon files.
|
||||
|
||||
/proc/getIconMask(atom/A)//By yours truly. Creates a dynamic mask for a mob/whatever. /N
|
||||
var/icon/alpha_mask = new(A.icon,A.icon_state)//So we want the default icon and icon state of A.
|
||||
for(var/I in A.overlays)//For every image in overlays. var/image/I will not work, don't try it.
|
||||
if(I:layer>A.layer)
|
||||
for(var/V in A.overlays)//For every image in overlays. var/image/I will not work, don't try it.
|
||||
var/image/I = V
|
||||
if(I.layer>A.layer)
|
||||
continue//If layer is greater than what we need, skip it.
|
||||
var/icon/image_overlay = new(I:icon,I:icon_state)//Blend only works with icon objects.
|
||||
var/icon/image_overlay = new(I.icon,I.icon_state)//Blend only works with icon objects.
|
||||
//Also, icons cannot directly set icon_state. Slower than changing variables but whatever.
|
||||
alpha_mask.Blend(image_overlay,ICON_OR)//OR so they are lumped together in a nice overlay.
|
||||
return alpha_mask//And now return the mask.
|
||||
@@ -968,32 +970,135 @@ GLOBAL_LIST_EMPTY(friendly_animal_types)
|
||||
/image/proc/setDir(newdir)
|
||||
dir = newdir
|
||||
|
||||
/atom/proc/freeze_icon_index()
|
||||
return "\ref[initial(icon)]-[initial(icon_state)]"
|
||||
#define FROZEN_RED_COLOR "#2E5E69"
|
||||
#define FROZEN_GREEN_COLOR "#60A2A8"
|
||||
#define FROZEN_BLUE_COLOR "#A1AFB1"
|
||||
|
||||
/obj/proc/make_frozen_visual()
|
||||
// Used to make the frozen item visuals for Freon.
|
||||
var/static/list/freeze_item_icons = list()
|
||||
if(resistance_flags & FREEZE_PROOF)
|
||||
return
|
||||
if(!HAS_SECONDARY_FLAG(src, FROZEN) && (initial(icon) && initial(icon_state)))
|
||||
var/index = freeze_icon_index()
|
||||
var/icon/IC
|
||||
var/icon/P = freeze_item_icons[index]
|
||||
if(!P)
|
||||
P = new /icon
|
||||
for(var/iconstate in icon_states(icon))
|
||||
var/icon/O = new('icons/effects/freeze.dmi', "ice_cube")
|
||||
IC = new(icon, iconstate)
|
||||
O.Blend(IC, ICON_ADD)
|
||||
P.Insert(O, iconstate)
|
||||
freeze_item_icons[index] = P
|
||||
icon = P
|
||||
if(!(flags_2 & FROZEN_2))
|
||||
name = "frozen [name]"
|
||||
SET_SECONDARY_FLAG(src, FROZEN)
|
||||
add_atom_colour(list(FROZEN_RED_COLOR, FROZEN_GREEN_COLOR, FROZEN_BLUE_COLOR, rgb(0,0,0)), TEMPORARY_COLOUR_PRIORITY)
|
||||
alpha -= 25
|
||||
flags_2 |= FROZEN_2
|
||||
|
||||
//Assumes already frozed
|
||||
/obj/proc/make_unfrozen()
|
||||
icon = initial(icon)
|
||||
name = replacetext(name, "frozen ", "")
|
||||
CLEAR_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
|
||||
flags_2 &= ~FROZEN_2
|
||||
|
||||
#undef FROZEN_RED_COLOR
|
||||
#undef FROZEN_GREEN_COLOR
|
||||
#undef FROZEN_BLUE_COLOR
|
||||
|
||||
|
||||
//Converts an icon to base64. Operates by putting the icon in the iconCache savefile,
|
||||
// exporting it as text, and then parsing the base64 from that.
|
||||
// (This relies on byond automatically storing icons in savefiles as base64)
|
||||
/proc/icon2base64(icon/icon, iconKey = "misc")
|
||||
if (!isicon(icon))
|
||||
return FALSE
|
||||
WRITE_FILE(GLOB.iconCache[iconKey], icon)
|
||||
var/iconData = GLOB.iconCache.ExportText(iconKey)
|
||||
var/list/partial = splittext(iconData, "{")
|
||||
return replacetext(copytext(partial[2], 3, -5), "\n", "")
|
||||
|
||||
/proc/icon2html(thing, target, icon_state, dir, frame = 1, moving = FALSE)
|
||||
if (!thing)
|
||||
return
|
||||
|
||||
var/key
|
||||
var/icon/I = thing
|
||||
if (!target)
|
||||
return
|
||||
if (target == world)
|
||||
target = GLOB.clients
|
||||
|
||||
var/list/targets
|
||||
if (!islist(target))
|
||||
targets = list(target)
|
||||
else
|
||||
targets = target
|
||||
if (!targets.len)
|
||||
return
|
||||
if (!isicon(I))
|
||||
if (isfile(thing)) //special snowflake
|
||||
var/name = sanitize_filename("[generate_asset_name(thing)].png")
|
||||
register_asset(name, thing)
|
||||
for (var/thing2 in targets)
|
||||
send_asset(thing2, key, FALSE)
|
||||
return "<img class='icon icon-misc' src=\"[url_encode(name)]\">"
|
||||
var/atom/A = thing
|
||||
if (isnull(dir))
|
||||
dir = A.dir
|
||||
if (isnull(icon_state))
|
||||
icon_state = A.icon_state
|
||||
I = A.icon
|
||||
if (ishuman(thing)) // Shitty workaround for a BYOND issue.
|
||||
var/icon/temp = I
|
||||
I = icon()
|
||||
I.Insert(temp, dir = SOUTH)
|
||||
dir = SOUTH
|
||||
else
|
||||
if (isnull(dir))
|
||||
dir = SOUTH
|
||||
if (isnull(icon_state))
|
||||
icon_state = ""
|
||||
|
||||
I = icon(I, icon_state, dir, frame, moving)
|
||||
|
||||
key = "[generate_asset_name(I)].png"
|
||||
register_asset(key, I)
|
||||
for (var/thing2 in targets)
|
||||
send_asset(thing2, key, FALSE)
|
||||
|
||||
return "<img class='icon icon-[icon_state]' src=\"[url_encode(key)]\">"
|
||||
|
||||
/proc/icon2base64html(thing)
|
||||
if (!thing)
|
||||
return
|
||||
var/static/list/bicon_cache = list()
|
||||
if (isicon(thing))
|
||||
var/icon/I = thing
|
||||
var/icon_base64 = icon2base64(I)
|
||||
|
||||
if (I.Height() > world.icon_size || I.Width() > world.icon_size)
|
||||
var/icon_md5 = md5(icon_base64)
|
||||
icon_base64 = bicon_cache[icon_md5]
|
||||
if (!icon_base64) // Doesn't exist yet, make it.
|
||||
bicon_cache[icon_md5] = icon_base64 = icon2base64(I)
|
||||
|
||||
|
||||
return "<img class='icon icon-misc' src='data:image/png;base64,[icon_base64]'>"
|
||||
|
||||
// Either an atom or somebody fucked up and is gonna get a runtime, which I'm fine with.
|
||||
var/atom/A = thing
|
||||
var/key = "[istype(A.icon, /icon) ? "\ref[A.icon]" : A.icon]:[A.icon_state]"
|
||||
|
||||
|
||||
if (!bicon_cache[key]) // Doesn't exist, make it.
|
||||
var/icon/I = icon(A.icon, A.icon_state, SOUTH, 1)
|
||||
if (ishuman(thing)) // Shitty workaround for a BYOND issue.
|
||||
var/icon/temp = I
|
||||
I = icon()
|
||||
I.Insert(temp, dir = SOUTH)
|
||||
|
||||
bicon_cache[key] = icon2base64(I, key)
|
||||
|
||||
return "<img class='icon icon-[A.icon_state]' src='data:image/png;base64,[bicon_cache[key]]'>"
|
||||
|
||||
//Costlier version of icon2html() that uses getFlatIcon() to account for overlays, underlays, etc. Use with extreme moderation, ESPECIALLY on mobs.
|
||||
/proc/costly_icon2html(thing, target)
|
||||
if (!thing)
|
||||
return
|
||||
|
||||
if (isicon(thing))
|
||||
return icon2html(thing, target)
|
||||
|
||||
var/icon/I = getFlatIcon(thing)
|
||||
return icon2html(I, target)
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
//wrapper macro for sending images that makes grepping easy
|
||||
#define SEND_IMAGE(target, image) target << image
|
||||
|
||||
/proc/random_blood_type()
|
||||
return pick(4;"O-", 36;"O+", 3;"A-", 28;"A+", 1;"B-", 20;"B+", 1;"AB-", 5;"AB+")
|
||||
|
||||
@@ -116,6 +113,7 @@
|
||||
"xenohead" = "None",
|
||||
"xenotail" = "None",
|
||||
"exhibitionist" = FALSE,
|
||||
"genitals_use_skintone" = FALSE,
|
||||
"has_cock" = FALSE,
|
||||
"cock_shape" = pick(GLOB.cock_shapes_list),
|
||||
"cock_length" = 6,
|
||||
@@ -158,8 +156,9 @@
|
||||
"womb_cum_rate" = CUM_RATE,
|
||||
"womb_cum_mult" = CUM_RATE_MULT,
|
||||
"womb_efficiency" = CUM_EFFICIENCY,
|
||||
"womb_fluid" = "femcum"))
|
||||
|
||||
"womb_fluid" = "femcum",
|
||||
"flavor_text" = ""))
|
||||
|
||||
/proc/random_hair_style(gender)
|
||||
switch(gender)
|
||||
if(MALE)
|
||||
|
||||
@@ -24,11 +24,12 @@
|
||||
announcement += "<br><span class='alert'>[html_encode(text)]</span><br>"
|
||||
announcement += "<br>"
|
||||
|
||||
var/s = sound(sound)
|
||||
for(var/mob/M in GLOB.player_list)
|
||||
if(!isnewplayer(M) && M.can_hear())
|
||||
to_chat(M, announcement)
|
||||
if(M.client.prefs.toggles & SOUND_ANNOUNCEMENTS)
|
||||
M << sound(sound)
|
||||
SEND_SOUND(M, s)
|
||||
|
||||
/proc/print_command_report(text = "", title = null, announce=TRUE)
|
||||
if(!title)
|
||||
@@ -39,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]")
|
||||
@@ -55,6 +56,6 @@
|
||||
to_chat(M, "<b><font size = 3><font color = red>[title]</font color><BR>[message]</font size></b><BR>")
|
||||
if(M.client.prefs.toggles & SOUND_ANNOUNCEMENTS)
|
||||
if(alert)
|
||||
M << sound('sound/misc/notice1.ogg')
|
||||
SEND_SOUND(M, sound('sound/misc/notice1.ogg'))
|
||||
else
|
||||
M << sound('sound/misc/notice2.ogg')
|
||||
SEND_SOUND(M, sound('sound/misc/notice2.ogg'))
|
||||
|
||||
@@ -45,6 +45,9 @@
|
||||
index = findtext(t, char, index+1)
|
||||
return t
|
||||
|
||||
/proc/sanitize_filename(t)
|
||||
return sanitize_simple(t, list("\n"="", "\t"="", "/"="", "\\"="", "?"="", "%"="", "*"="", ":"="", "|"="", "\""="", "<"="", ">"=""))
|
||||
|
||||
//Runs byond's sanitization proc along-side sanitize_simple
|
||||
/proc/sanitize(t,list/repl_chars = null)
|
||||
return html_encode(sanitize_simple(t,repl_chars))
|
||||
@@ -553,14 +556,14 @@ GLOBAL_LIST_INIT(binary, list("0","1"))
|
||||
|
||||
var/list/tosend = list()
|
||||
tosend["data"] = finalized
|
||||
log << json_encode(tosend)
|
||||
WRITE_FILE(log, json_encode(tosend))
|
||||
|
||||
//Used for applying byonds text macros to strings that are loaded at runtime
|
||||
/proc/apply_text_macros(string)
|
||||
var/next_backslash = findtext(string, "\\")
|
||||
if(!next_backslash)
|
||||
return string
|
||||
|
||||
|
||||
var/leng = length(string)
|
||||
|
||||
var/next_space = findtext(string, " ", next_backslash + 1)
|
||||
|
||||
@@ -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
|
||||
@@ -537,3 +539,18 @@
|
||||
if(!istype(the_matrix) || the_matrix.len != 20)
|
||||
return "#ffffffff"
|
||||
return rgb(the_matrix[1]*255, the_matrix[6]*255, the_matrix[11]*255, the_matrix[16]*255)
|
||||
|
||||
/proc/type2parent(child)
|
||||
var/string_type = "[child]"
|
||||
var/last_slash = findlasttext(string_type, "/")
|
||||
if(last_slash == 1)
|
||||
switch(child)
|
||||
if(/datum)
|
||||
return null
|
||||
if(/obj || /mob)
|
||||
return /atom/movable
|
||||
if(/area || /turf)
|
||||
return /atom
|
||||
else
|
||||
return /datum
|
||||
return text2path(copytext(string_type, 1, last_slash))
|
||||
|
||||
@@ -289,7 +289,7 @@ Turf and target are separate in case you want to teleport some distance from a t
|
||||
var/list/pois = list()
|
||||
for(var/mob/M in mobs)
|
||||
if(skip_mindless && (!M.mind && !M.ckey))
|
||||
if(!isbot(M) && !istype(M, /mob/camera/))
|
||||
if(!isbot(M) && !istype(M, /mob/camera) && !ismegafauna(M))
|
||||
continue
|
||||
if(M.client && M.client.holder && M.client.holder.fakekey) //stealthmins
|
||||
continue
|
||||
@@ -809,7 +809,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
|
||||
)))
|
||||
@@ -857,11 +857,11 @@ GLOBAL_LIST_INIT(WALLITEMS_INVERSE, typecacheof(list(
|
||||
|
||||
/obj/proc/atmosanalyzer_scan(datum/gas_mixture/air_contents, mob/user, obj/target = src)
|
||||
var/obj/icon = target
|
||||
user.visible_message("[user] has used the analyzer on [bicon(icon)] [target].", "<span class='notice'>You use the analyzer on [bicon(icon)] [target].</span>")
|
||||
user.visible_message("[user] has used the analyzer on [icon2html(icon, viewers(src))] [target].", "<span class='notice'>You use the analyzer on [icon2html(icon, user)] [target].</span>")
|
||||
var/pressure = air_contents.return_pressure()
|
||||
var/total_moles = air_contents.total_moles()
|
||||
|
||||
to_chat(user, "<span class='notice'>Results of analysis of [bicon(icon)] [target].</span>")
|
||||
to_chat(user, "<span class='notice'>Results of analysis of [icon2html(icon, user)] [target].</span>")
|
||||
if(total_moles>0)
|
||||
to_chat(user, "<span class='notice'>Pressure: [round(pressure,0.1)] kPa</span>")
|
||||
|
||||
|
||||
@@ -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,9 +69,7 @@
|
||||
#error You need version 511 or higher
|
||||
#endif
|
||||
|
||||
#define SERVICE_CMD_PARAM_KEY "serviceCommsKey"
|
||||
|
||||
//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 0
|
||||
|
||||
@@ -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
|
||||
))
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -85,7 +85,7 @@
|
||||
|
||||
/*
|
||||
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)
|
||||
@@ -95,7 +95,7 @@
|
||||
if(O == target_atom || (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
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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--
|
||||
@@ -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)
|
||||
|
||||
@@ -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."
|
||||
@@ -205,7 +220,7 @@ or something covering your eyes."
|
||||
/obj/screen/alert/embeddedobject
|
||||
name = "Embedded Object"
|
||||
desc = "Something got lodged into your flesh and is causing major bleeding. It might fall out with time, but surgery is the safest way. \
|
||||
If you're feeling frisky, click yourself in help intent to pull the object out."
|
||||
If you're feeling frisky, examine yourself and click the underlined item to pull the object out."
|
||||
icon_state = "embeddedobject"
|
||||
|
||||
/obj/screen/alert/embeddedobject/Click()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -53,10 +53,11 @@ GLOBAL_LIST_EMPTY(xeno_dorsal_list)
|
||||
|
||||
//Genitals and Arousal Lists
|
||||
GLOBAL_LIST_EMPTY(cock_shapes_list)//global_lists.dm for the list initializations //Now also _DATASTRUCTURES globals.dm
|
||||
GLOBAL_LIST_EMPTY(cock_shapes_icons) //Associated list for names->icon_states for cockshapes.
|
||||
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")
|
||||
|
||||
+359
-121
@@ -6,7 +6,7 @@
|
||||
var/arousal_rate = 1 //The base rate that arousal will increase in this mob.
|
||||
var/arousal_loss_rate = 1 //How easily arousal can be relieved for this mob.
|
||||
var/canbearoused = FALSE //Mob-level disabler for arousal. Starts off and can be enabled as features are added for different mob types.
|
||||
var/mb_cd_length = 50 //5 second cooldown for masturbating because fuck spam
|
||||
var/mb_cd_length = 100 //5 second cooldown for masturbating because fuck spam.
|
||||
var/mb_cd_timer = 0 //The timer itself
|
||||
|
||||
/mob/living/carbon/human
|
||||
@@ -150,14 +150,14 @@
|
||||
return 0
|
||||
var/mob/living/M = usr
|
||||
if(M.canbearoused)
|
||||
M.mob_masturbate()
|
||||
M.mob_climax()
|
||||
return 1
|
||||
else
|
||||
M << "<span class='warning'>Arousal is disabled. Feature is unavailable.</span>"
|
||||
to_chat(M, "<span class='warning'>Arousal is disabled. Feature is unavailable.</span>")
|
||||
|
||||
|
||||
|
||||
/mob/living/proc/mob_masturbate()//This is just so I can test this shit without being forced to add actual content to get rid of arousal. Will be a very basic proc for a while.
|
||||
/mob/living/proc/mob_climax()//This is just so I can test this shit without being forced to add actual content to get rid of arousal. Will be a very basic proc for a while.
|
||||
set name = "Masturbate"
|
||||
set category = "IC"
|
||||
if(canbearoused && !restrained() && !stat)
|
||||
@@ -179,128 +179,366 @@
|
||||
PoolOrNew(/obj/effect/decal/cleanable/femcum, loc)
|
||||
*/
|
||||
else
|
||||
src << "<span class='notice'>You aren't aroused enough for that.</span>"
|
||||
to_chat(src, "<span class='notice'>You aren't aroused enough for that.</span>")
|
||||
|
||||
/mob/living/carbon/human/mob_masturbate()
|
||||
if(mb_cd_timer > world.time)
|
||||
src << "<span class='warning'>You need to wait [round((mb_cd_timer - world.time)/(20))] seconds before you can do that again!</span>"
|
||||
return
|
||||
var/list/genitals_list = list()
|
||||
var/obj/item/organ/genital/SG = null//originally selected_genital
|
||||
var/list/containers_list = list()
|
||||
var/obj/item/weapon/reagent_containers/SC = null
|
||||
|
||||
//These are various procs that we'll use later, split up for readability instead of having one, huge proc.
|
||||
//For all of these, we assume the arguments given are proper and have been checked beforehand.
|
||||
/mob/living/carbon/human/proc/mob_masturbate(obj/item/organ/genital/G, mb_time = 30) //Masturbation, keep it gender-neutral
|
||||
var/total_fluids = 0
|
||||
var/datum/reagents/fluid_source = null
|
||||
var/into_container = 0
|
||||
var/arms = get_num_arms()
|
||||
var/free_hands = arms
|
||||
var/total_cum = 0
|
||||
var/finished = 0
|
||||
var/mb_time = 30
|
||||
mb_cd_timer = (world.time + mb_cd_length)
|
||||
if(canbearoused && has_dna())
|
||||
if(restrained())
|
||||
src << "<span class='warning'>You can't do that while restrained!</span>"
|
||||
return
|
||||
if(stat)
|
||||
src << "<span class='warning'>You must be conscious to do that!</span>"
|
||||
return
|
||||
if(getArousalLoss() < 33)//flat number instead of percentage
|
||||
src << "<span class='warning'>You aren't aroused enough for that!</span>"
|
||||
return
|
||||
if(!is_groin_exposed())
|
||||
src << "<span class='warning'>You need to undress, first!</span>"
|
||||
return
|
||||
if(!arms)
|
||||
src << "<span class='warning'>You need at least one arm.</span>"
|
||||
return
|
||||
for(var/helditem in held_items)//how many hands are free
|
||||
if(isobj(helditem))
|
||||
free_hands--
|
||||
if(free_hands <= 0)
|
||||
src << "<span class='warning'>You need at least one free hand.</span>"
|
||||
return
|
||||
for(var/obj/item/organ/genital/G in internal_organs)
|
||||
if(G.can_masturbate_with)//filter out what you can't masturbate with
|
||||
genitals_list += G
|
||||
if(genitals_list.len)
|
||||
SG = input(src, "with what?", "Masturbate") as null|obj in genitals_list
|
||||
if(SG)
|
||||
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/pie))
|
||||
containers_list += container
|
||||
if(containers_list.len)
|
||||
SC = input(src, "Into or onto what?(Cancel for nowhere)", "Masturbate") as null|obj in containers_list
|
||||
if(SC)
|
||||
if(in_range(src, SC))
|
||||
into_container = 1
|
||||
SG.update()
|
||||
switch(SG.type)
|
||||
|
||||
//Penis
|
||||
if(/obj/item/organ/genital/penis)
|
||||
var/obj/item/organ/genital/penis/P = SG
|
||||
if(!P.linked_balls)
|
||||
src << "<span class='warning'>Grow a pair!</span>"
|
||||
return
|
||||
fluid_source = P.linked_balls.reagents
|
||||
total_cum = fluid_source.total_volume
|
||||
if(into_container)//into a glass or beaker or whatever
|
||||
src.visible_message("<span class='danger'>[src] starts [pick("jerking off","stroking")] their [SG] over [SC].</span>", \
|
||||
"<span class='userdanger'>You start jerking off over [SC.name].</span>", \
|
||||
"<span class='userdanger'>You start masturbating.</span>")
|
||||
if(do_after(src, mb_time, target = src) && in_range(src, SC))
|
||||
fluid_source.trans_to(SC, total_cum)
|
||||
src.visible_message("<span class='danger'>[src] orgasms, [pick("cumming into", "emptying themself into")] [SC]!</span>", \
|
||||
"<span class='green'>You cum into [SC].</span>", \
|
||||
"<span class='green'>You have relieved yourself.</span>")
|
||||
finished = 1
|
||||
|
||||
if(/obj/item/organ/genital/vagina)
|
||||
var/obj/item/organ/genital/vagina/V = SG
|
||||
if(!V.linked_womb)
|
||||
src << "<span class='warning'>No womb!</span>"
|
||||
return
|
||||
fluid_source = V.linked_womb.reagents
|
||||
total_cum = fluid_source.total_volume
|
||||
if(into_container)//into a glass or beaker or whatever
|
||||
src.visible_message("<span class='danger'>[src] starts fingering their vagina over [SC].</span>", \
|
||||
"<span class='userdanger'>You start fingering over [SC.name].</span>", \
|
||||
"<span class='userdanger'>You start masturbating.</span>")
|
||||
if(do_after(src, mb_time, target = src) && in_range(src, SC))
|
||||
fluid_source.trans_to(SC, total_cum)
|
||||
src.visible_message("<span class='danger'>[src] orgasms, [pick("cumming into", "emptying themself into")] [SC]!</span>", \
|
||||
"<span class='green'>You cum into [SC].</span>", \
|
||||
"<span class='green'>You have relieved yourself.</span>")
|
||||
finished = 1
|
||||
|
||||
else//not into a container
|
||||
src.visible_message("<span class='danger'>[src] starts fingering their vagina.</span>", \
|
||||
"<span class='userdanger'>You start fingering your vagina.</span>", \
|
||||
"<span class='userdanger'>You start masturbating.</span>")
|
||||
if(do_after(src, mb_time, target = src))
|
||||
if(total_cum > 5)
|
||||
fluid_source.reaction(src.loc, TOUCH, 1, 0)
|
||||
fluid_source.clear_reagents()
|
||||
src.visible_message("<span class='danger'>[src] orgasms, cumming[istype(src.loc, /turf/open/floor) ? " onto [src.loc]" : ""]!</span>", \
|
||||
"<span class='green'>You cum[istype(src.loc, /turf/open/floor) ? " onto [src.loc]" : ""].</span>", \
|
||||
"<span class='green'>You have relieved yourself.</span>")
|
||||
finished = 1
|
||||
if(G.producing) //Can it produce its own fluids, such as breasts?
|
||||
fluid_source = G.reagents
|
||||
else
|
||||
if(!G.linked_organ)
|
||||
to_chat(src, "<span class='warning'>Your [G.name] is unable to produce it's own fluids, it's missing the organs for it.</span>")
|
||||
return
|
||||
fluid_source = G.linked_organ.reagents
|
||||
total_fluids = fluid_source.total_volume
|
||||
if(mb_time)
|
||||
src.visible_message("<span class='danger'>[src] starts to [G.masturbation_verb] [p_their()] [G.name].</span>", \
|
||||
"<span class='green'>You start to [G.masturbation_verb] your [G.name].</span>", \
|
||||
"<span class='green'>You start to [G.masturbation_verb] your [G.name].</span>")
|
||||
|
||||
else//backup message, just in case
|
||||
src.visible_message("<span class='danger'>[src] starts masturbating!</span>", \
|
||||
"<span class='userdanger'>You start masturbating.</span>")
|
||||
if(do_after(src, mb_time, target = src))
|
||||
src.visible_message("<span class='danger'>[src] [pick("relieves themself!", "shudders and moans in orgasm!")]</span>", \
|
||||
"<span class='userdanger'>You have relieved yourself.</span>")
|
||||
finished = 1
|
||||
if(finished)
|
||||
setArousalLoss(min_arousal)
|
||||
if(do_after(src, mb_time, target = src))
|
||||
if(total_fluids > 5)
|
||||
fluid_source.reaction(src.loc, TOUCH, 1, 0)
|
||||
fluid_source.clear_reagents()
|
||||
src.visible_message("<span class='danger'>[src] orgasms, cumming[istype(src.loc, /turf/open/floor) ? " onto [src.loc]" : ""]!</span>", \
|
||||
"<span class='green'>You cum[istype(src.loc, /turf/open/floor) ? " onto [src.loc]" : ""].</span>", \
|
||||
"<span class='green'>You have relieved yourself.</span>")
|
||||
if(G.can_climax)
|
||||
setArousalLoss(min_arousal)
|
||||
|
||||
|
||||
/mob/living/carbon/human/proc/mob_climax_outside(obj/item/organ/genital/G, mb_time = 30) //This is used for forced orgasms and other hands-free climaxes
|
||||
var/total_fluids = 0
|
||||
var/datum/reagents/fluid_source = null
|
||||
var/unable_to_come = FALSE
|
||||
|
||||
if(G.producing) //Can it produce its own fluids, such as breasts?
|
||||
fluid_source = G.reagents
|
||||
total_fluids = fluid_source.total_volume
|
||||
else
|
||||
if(!G.linked_organ)
|
||||
unable_to_come = TRUE
|
||||
else
|
||||
src << "<span class='warning'>You have no genitals!</span>"
|
||||
fluid_source = G.linked_organ.reagents
|
||||
total_fluids = fluid_source.total_volume
|
||||
|
||||
if(unable_to_come)
|
||||
src.visible_message("<span class='danger'>[src] shudders, their [G.name] unable to cum.</span>", \
|
||||
"<span class='userdanger'>Your [G.name] cannot cum, giving no relief.</span>", \
|
||||
"<span class='userdanger'>Your [G.name] cannot cum, giving no relief.</span>")
|
||||
else
|
||||
total_fluids = fluid_source.total_volume
|
||||
if(mb_time) //as long as it's not instant, give a warning
|
||||
src.visible_message("<span class='danger'>[src] looks like they're about to cum.</span>", \
|
||||
"<span class='green'>You feel yourself about to orgasm.</span>", \
|
||||
"<span class='green'>You feel yourself about to orgasm.</span>")
|
||||
if(do_after(src, mb_time, target = src))
|
||||
if(total_fluids > 5)
|
||||
fluid_source.reaction(src.loc, TOUCH, 1, 0)
|
||||
fluid_source.clear_reagents()
|
||||
src.visible_message("<span class='danger'>[src] orgasms[istype(src.loc, /turf/open/floor) ? ", spilling onto [src.loc]" : ""], using [p_their()] [G.name]!</span>", \
|
||||
"<span class='green'>You climax[istype(src.loc, /turf/open/floor) ? ", spilling onto [src.loc]" : ""] with your [G.name].</span>", \
|
||||
"<span class='green'>You climax using your [G.name].</span>")
|
||||
if(G.can_climax)
|
||||
setArousalLoss(min_arousal)
|
||||
|
||||
|
||||
/mob/living/carbon/human/proc/mob_climax_partner(obj/item/organ/genital/G, mob/living/L, spillage = TRUE, mb_time = 30) //Used for climaxing with any living thing
|
||||
var/total_fluids = 0
|
||||
var/datum/reagents/fluid_source = null
|
||||
|
||||
if(G.producing) //Can it produce its own fluids, such as breasts?
|
||||
fluid_source = G.reagents
|
||||
else
|
||||
if(!G.linked_organ)
|
||||
to_chat(src, "<span class='warning'>Your [G.name] is unable to produce it's own fluids, it's missing the organs for it.</span>")
|
||||
return
|
||||
fluid_source = G.linked_organ.reagents
|
||||
total_fluids = fluid_source.total_volume
|
||||
if(mb_time) //Skip warning if this is an instant climax.
|
||||
src.visible_message("[src] is about to climax with [L]!", \
|
||||
"You're about to climax with [L]!", \
|
||||
"<span class='danger'>You're preparing to climax with someone!</span>")
|
||||
if(spillage)
|
||||
if(do_after(src, mb_time, target = src) && in_range(src, L))
|
||||
fluid_source.trans_to(L, total_fluids*G.fluid_transfer_factor)
|
||||
total_fluids -= total_fluids*G.fluid_transfer_factor
|
||||
if(total_fluids > 5)
|
||||
fluid_source.reaction(L.loc, TOUCH, 1, 0)
|
||||
fluid_source.clear_reagents()
|
||||
src.visible_message("<span class='danger'>[src] climaxes with [L][spillage ? ", overflowing and spilling":""], using [p_their()] [G.name]!</span>", \
|
||||
"<span class='green'>You orgasm with [L][spillage ? ", spilling out of them":""], using your [G.name].</span>", \
|
||||
"<span class='green'>You have climaxed with someone[spillage ? ", spilling out of them":""], using your [G.name].</span>")
|
||||
if(G.can_climax)
|
||||
setArousalLoss(min_arousal)
|
||||
else //knots and other non-spilling orgasms
|
||||
if(do_after(src, mb_time, target = src) && in_range(src, L))
|
||||
fluid_source.trans_to(L, total_fluids)
|
||||
total_fluids = 0
|
||||
src.visible_message("<span class='danger'>[src] climaxes with [L], [p_their()] [G.name] spilling nothing!</span>", \
|
||||
"<span class='green'>You ejaculate with [L], your [G.name] spilling nothing.</span>", \
|
||||
"<span class='green'>You have climaxed inside someone, your [G.name] spilling nothing.</span>")
|
||||
if(G.can_climax)
|
||||
setArousalLoss(min_arousal)
|
||||
|
||||
|
||||
/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
|
||||
|
||||
if(G.producing) //Can it produce its own fluids, such as breasts?
|
||||
fluid_source = G.reagents
|
||||
else
|
||||
if(!G.linked_organ)
|
||||
to_chat(src, "<span class='warning'>Your [G.name] is unable to produce it's own fluids, it's missing the organs for it.</span>")
|
||||
return
|
||||
fluid_source = G.linked_organ.reagents
|
||||
total_fluids = fluid_source.total_volume
|
||||
|
||||
//if(!container) //Something weird happened
|
||||
// to_chat(src, "<span class='warning'>You need a container to do this!</span>")
|
||||
// return
|
||||
|
||||
src.visible_message("<span class='danger'>[src] starts to [G.masturbation_verb] their [G.name] over [container].</span>", \
|
||||
"<span class='userdanger'>You start to [G.masturbation_verb] your [G.name] over [container].</span>", \
|
||||
"<span class='userdanger'>You start to [G.masturbation_verb] your [G.name] over something.</span>")
|
||||
if(do_after(src, mb_time, target = src) && in_range(src, container))
|
||||
fluid_source.trans_to(container, total_fluids)
|
||||
src.visible_message("<span class='danger'>[src] uses [p_their()] [G.name] to fill [container]!</span>", \
|
||||
"<span class='green'>You used your [G.name] to fill [container].</span>", \
|
||||
"<span class='green'>You have relieved some pressure.</span>")
|
||||
if(G.can_climax)
|
||||
setArousalLoss(min_arousal)
|
||||
|
||||
/mob/living/carbon/human/proc/pick_masturbate_genitals()
|
||||
var/obj/item/organ/genital/ret_organ
|
||||
var/list/genitals_list = list()
|
||||
var/list/worn_stuff = get_equipped_items()
|
||||
|
||||
for(var/obj/item/organ/genital/G in internal_organs)
|
||||
if(G.can_masturbate_with) //filter out what you can't masturbate with
|
||||
if(G.is_exposed(worn_stuff)) //Nude or through_clothing
|
||||
genitals_list += G
|
||||
if(genitals_list.len)
|
||||
ret_organ = input(src, "with what?", "Masturbate", null) as null|obj in genitals_list
|
||||
return ret_organ
|
||||
return null //error stuff
|
||||
|
||||
|
||||
/mob/living/carbon/human/proc/pick_climax_genitals()
|
||||
var/obj/item/organ/genital/ret_organ
|
||||
var/list/genitals_list = list()
|
||||
var/list/worn_stuff = get_equipped_items()
|
||||
|
||||
for(var/obj/item/organ/genital/G in internal_organs)
|
||||
if(G.can_climax) //filter out what you can't masturbate with
|
||||
if(G.is_exposed(worn_stuff)) //Nude or through_clothing
|
||||
genitals_list += G
|
||||
if(genitals_list.len)
|
||||
ret_organ = input(src, "with what?", "Climax", null) as null|obj in genitals_list
|
||||
return ret_organ
|
||||
return null //error stuff
|
||||
|
||||
|
||||
/mob/living/carbon/human/proc/pick_partner()
|
||||
var/list/partners = list()
|
||||
if(src.pulling)
|
||||
partners += src.pulling //Yes, even objects for now
|
||||
if(src.pulledby)
|
||||
partners += src.pulledby
|
||||
//Now we got both of them, let's check if they're proper
|
||||
for(var/I in partners)
|
||||
if(isliving(I))
|
||||
if(iscarbon(I))
|
||||
var/mob/living/carbon/C = I
|
||||
if(!C.exposed_genitals.len) //Nothing through_clothing
|
||||
if(!C.is_groin_exposed()) //No pants undone
|
||||
if(!C.is_chest_exposed()) //No chest exposed
|
||||
partners -= I //Then not proper, remove them
|
||||
else
|
||||
partners -= I //No fucking objects
|
||||
//NOW the list should only contain correct partners
|
||||
if(!partners.len)
|
||||
return null //No one left.
|
||||
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/reagent_containers/SC = null
|
||||
var/list/containers_list = list()
|
||||
|
||||
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)
|
||||
SC = input(src, "Into or onto what?(Cancel for nowhere)", null) as null|obj in containers_list
|
||||
if(SC)
|
||||
if(in_range(src, SC))
|
||||
return SC
|
||||
return null //If nothing correct, give null.
|
||||
|
||||
|
||||
//Here's the main proc itself
|
||||
/mob/living/carbon/human/mob_climax(forced_climax=FALSE) //Forced is instead of the other proc, makes you cum if you have the tools for it, ignoring restraints
|
||||
if(mb_cd_timer > world.time)
|
||||
if(!forced_climax) //Don't spam the message to the victim if forced to come too fast
|
||||
to_chat(src, "<span class='warning'>You need to wait [round((mb_cd_timer - world.time)/(20))] seconds before you can do that again!</span>")
|
||||
return
|
||||
mb_cd_timer = (world.time + mb_cd_length)
|
||||
|
||||
|
||||
if(canbearoused && has_dna())
|
||||
if(stat==2)
|
||||
to_chat(src, "<span class='warning'>You can't do that while dead!</span>")
|
||||
return
|
||||
if(forced_climax) //Something forced us to cum, this is not a masturbation thing and does not progress to the other checks
|
||||
for(var/obj/item/organ/O in internal_organs)
|
||||
if(istype(O, /obj/item/organ/genital))
|
||||
var/obj/item/organ/genital/G = O
|
||||
if(!G.can_climax) //Skip things like wombs and testicles
|
||||
continue
|
||||
var/mob/living/partner
|
||||
var/check_target
|
||||
var/list/worn_stuff = get_equipped_items()
|
||||
|
||||
if(G.is_exposed(worn_stuff))
|
||||
if(src.pulling) //Are we pulling someone? Priority target, we can't be making option menus for this, has to be quick
|
||||
if(isliving(src.pulling)) //Don't fuck objects
|
||||
check_target = src.pulling
|
||||
if(src.pulledby && !check_target) //prioritise pulled over pulledby
|
||||
if(isliving(src.pulledby))
|
||||
check_target = src.pulledby
|
||||
//Now we should have a partner, or else we have to come alone
|
||||
if(check_target)
|
||||
if(iscarbon(check_target)) //carbons can have clothes
|
||||
var/mob/living/carbon/C = check_target
|
||||
if(C.exposed_genitals.len || C.is_groin_exposed() || C.is_chest_exposed()) //Are they naked enough?
|
||||
partner = C
|
||||
else //A cat is fine too
|
||||
partner = check_target
|
||||
if(partner) //Did they pass the clothing checks?
|
||||
mob_climax_partner(G, partner, mb_time = 0) //Instant climax due to forced
|
||||
continue //You've climaxed once with this organ, continue on
|
||||
//not exposed OR if no partner was found while exposed, climax alone
|
||||
mob_climax_outside(G, mb_time = 0) //removed climax timer for sudden, forced orgasms
|
||||
//Now all genitals that could climax, have.
|
||||
//Since this was a forced climax, we do not need to continue with the other stuff
|
||||
return
|
||||
//If we get here, then this is not a forced climax and we gotta check a few things.
|
||||
|
||||
if(stat==1) //No sleep-masturbation, you're unconscious.
|
||||
to_chat(src, "<span class='warning'>You must be conscious to do that!</span>")
|
||||
return
|
||||
if(getArousalLoss() < 33) //flat number instead of percentage
|
||||
to_chat(src, "<span class='warning'>You aren't aroused enough for that!</span>")
|
||||
return
|
||||
|
||||
/mob/living/carbon/proc/force_orgasm(intensity)
|
||||
if(canbearoused && has_dna() && (has_penis() || has_vagina()))
|
||||
return 1
|
||||
return 0
|
||||
//Ok, now we check what they want to do.
|
||||
var/choice = input(src, "Select sexual activity", "Sexual activity:") in list("Masturbate", "Climax alone", "Climax with partner", "Fill container")
|
||||
|
||||
switch(choice)
|
||||
if("Masturbate")
|
||||
if(restrained(TRUE)) //TRUE ignores grabs
|
||||
to_chat(src, "<span class='warning'>You can't do that while restrained!</span>")
|
||||
return
|
||||
var/free_hands = get_num_arms()
|
||||
if(!free_hands)
|
||||
to_chat(src, "<span class='warning'>You need at least one free arm.</span>")
|
||||
return
|
||||
for(var/helditem in held_items)//how many hands are free
|
||||
if(isobj(helditem))
|
||||
free_hands--
|
||||
if(free_hands <= 0)
|
||||
to_chat(src, "<span class='warning'>You're holding too many things.</span>")
|
||||
return
|
||||
//We got hands, let's pick an organ
|
||||
var/obj/item/organ/genital/picked_organ
|
||||
picked_organ = pick_masturbate_genitals()
|
||||
if(picked_organ)
|
||||
mob_masturbate(picked_organ)
|
||||
return
|
||||
else //They either lack organs that can masturbate, or they didn't pick one.
|
||||
to_chat(src, "<span class='warning'>You cannot masturbate without choosing genitals.</span>")
|
||||
return
|
||||
|
||||
if("Climax alone")
|
||||
if(restrained(TRUE)) //TRUE ignores grabs
|
||||
to_chat(src, "<span class='warning'>You can't do that while restrained!</span>")
|
||||
return
|
||||
var/free_hands = get_num_arms()
|
||||
if(!free_hands)
|
||||
to_chat(src, "<span class='warning'>You need at least one free arm.</span>")
|
||||
return
|
||||
for(var/helditem in held_items)//how many hands are free
|
||||
if(isobj(helditem))
|
||||
free_hands--
|
||||
if(free_hands <= 0)
|
||||
to_chat(src, "<span class='warning'>You're holding too many things.</span>")
|
||||
return
|
||||
//We got hands, let's pick an organ
|
||||
var/obj/item/organ/genital/picked_organ
|
||||
picked_organ = pick_climax_genitals()
|
||||
if(picked_organ)
|
||||
mob_climax_outside(picked_organ)
|
||||
return
|
||||
else //They either lack organs that can masturbate, or they didn't pick one.
|
||||
to_chat(src, "<span class='warning'>You cannot climax without choosing genitals.</span>")
|
||||
return
|
||||
|
||||
if("Climax with partner")
|
||||
//We need no hands, we can be restrained and so on, so let's pick an organ
|
||||
var/obj/item/organ/genital/picked_organ
|
||||
picked_organ = pick_climax_genitals()
|
||||
if(picked_organ)
|
||||
var/mob/living/partner = pick_partner() //Get someone
|
||||
if(partner)
|
||||
var/spillage = input(src, "Would your fluids spill outside?", "Choose overflowing option", "Yes") as anything in list("Yes", "No")
|
||||
if(spillage == "Yes")
|
||||
mob_climax_partner(picked_organ, partner, TRUE)
|
||||
else
|
||||
mob_climax_partner(picked_organ, partner, FALSE)
|
||||
return
|
||||
else
|
||||
to_chat(src, "<span class='warning'>You cannot do this alone.</span>")
|
||||
return
|
||||
else //They either lack organs that can masturbate, or they didn't pick one.
|
||||
to_chat(src, "<span class='warning'>You cannot climax without choosing genitals.</span>")
|
||||
return
|
||||
|
||||
if("Fill container")
|
||||
//We'll need hands and no restraints.
|
||||
if(restrained(TRUE)) //TRUE ignores grabs
|
||||
to_chat(src, "<span class='warning'>You can't do that while restrained!</span>")
|
||||
return
|
||||
var/free_hands = get_num_arms()
|
||||
if(!free_hands)
|
||||
to_chat(src, "<span class='warning'>You need at least one free arm.</span>")
|
||||
return
|
||||
for(var/helditem in held_items)//how many hands are free
|
||||
if(isobj(helditem))
|
||||
free_hands--
|
||||
if(free_hands <= 0)
|
||||
to_chat(src, "<span class='warning'>You're holding too many things.</span>")
|
||||
return
|
||||
//We got hands, let's pick an organ
|
||||
var/obj/item/organ/genital/picked_organ
|
||||
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/reagent_containers/fluid_container = pick_climax_container()
|
||||
if(fluid_container)
|
||||
mob_fill_container(picked_organ, fluid_container)
|
||||
return
|
||||
else
|
||||
to_chat(src, "<span class='warning'>You cannot do this without anything to fill.</span>")
|
||||
return
|
||||
else //They either lack organs that can climax, or they didn't pick one.
|
||||
to_chat(src, "<span class='warning'>You cannot fill anything without choosing genitals.</span>")
|
||||
return
|
||||
else //Somehow another option was taken, maybe something interrupted the selection or it was cancelled
|
||||
return //Just end it in that case.
|
||||
|
||||
@@ -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
|
||||
@@ -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")
|
||||
@@ -105,7 +105,7 @@
|
||||
M.emote(pick("moan","blush"))
|
||||
if(prob(5))
|
||||
var/aroused_message = pick("You feel frisky.", "You're having trouble suppressing your urges.", "You feel in the mood.")
|
||||
M << "<span class='love'>[aroused_message]</span>"
|
||||
to_chat(M, "<span class='love'>[aroused_message]</span>")
|
||||
..()
|
||||
|
||||
/datum/reagent/aphrodisiacplus
|
||||
@@ -128,15 +128,13 @@
|
||||
else
|
||||
M.emote(pick("moan","blush"))
|
||||
if(prob(5))
|
||||
var/aroused_message
|
||||
if(M.getArousalLoss() > 90)
|
||||
var/aroused_message = pick("You need to fuck someone!", "You're bursting with sexual tension!", "You can't get sex off your mind!")
|
||||
M << "<span class='love'>[aroused_message]</span>"
|
||||
aroused_message = pick("You need to fuck someone!", "You're bursting with sexual tension!", "You can't get sex off your mind!")
|
||||
else
|
||||
var/aroused_message = pick("You feel a bit hot.", "You feel strong sexual urges.", "You feel in the mood.", "You're ready to go down on someone.")
|
||||
M << "<span class='love'>[aroused_message]</span>"
|
||||
// if(iscarbon(M) && has_dna(M))
|
||||
// M.force_ejaculation()
|
||||
..()
|
||||
aroused_message = pick("You feel a bit hot.", "You feel strong sexual urges.", "You feel in the mood.", "You're ready to go down on someone.")
|
||||
to_chat(M, "<span class='love'>[aroused_message]</span>")
|
||||
|
||||
/datum/reagent/aphrodisiacplus/addiction_act_stage2(mob/living/M)
|
||||
if(prob(30))
|
||||
M.adjustBrainLoss(2)
|
||||
@@ -152,11 +150,16 @@
|
||||
..()
|
||||
|
||||
/datum/reagent/aphrodisiacplus/overdose_process(mob/living/M)
|
||||
if(prob(66))
|
||||
if(prob(33))
|
||||
if(M.getArousalLoss() >= 100 && ishuman(M) && M.has_dna())
|
||||
var/mob/living/carbon/human/H = M
|
||||
if(prob(50)) //Less spam
|
||||
to_chat(H, "<span class='love'>Your libido is going haywire!</span>")
|
||||
H.mob_climax(forced_climax=TRUE)
|
||||
if(M.min_arousal < 50)
|
||||
M.min_arousal += 1
|
||||
if(M.max_arousal < 200)
|
||||
M.max_arousal += 1
|
||||
if(M.min_arousal < M.max_arousal)
|
||||
M.min_arousal += 1
|
||||
M.adjustArousalLoss(2)
|
||||
..()
|
||||
|
||||
@@ -193,7 +196,7 @@
|
||||
if(prob(33))
|
||||
if(M.min_arousal > 0)
|
||||
M.min_arousal -= 1
|
||||
if(M.max_arousal > 75)
|
||||
if(M.min_arousal > 50)
|
||||
M.min_arousal -= 1
|
||||
M.adjustArousalLoss(-2)
|
||||
..()
|
||||
|
||||
+11
-11
@@ -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)
|
||||
|
||||
+34
-34
@@ -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()
|
||||
@@ -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)
|
||||
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 704 B |
@@ -11,6 +11,10 @@
|
||||
var/amount = 2
|
||||
producing = TRUE
|
||||
shape = "pair"
|
||||
can_masturbate_with = TRUE
|
||||
masturbation_verb = "massage"
|
||||
can_climax = TRUE
|
||||
fluid_transfer_factor =0.5
|
||||
|
||||
/obj/item/organ/genital/breasts/Initialize()
|
||||
. = ..()
|
||||
@@ -54,4 +58,10 @@
|
||||
var/mob/living/carbon/human/H = owner // only human mobs have skin_tone, which we need.
|
||||
color = "#[skintone2hex(H.skin_tone)]"
|
||||
else
|
||||
color = "#[owner.dna.features["breasts_color"]]"
|
||||
color = "#[owner.dna.features["breasts_color"]]"
|
||||
|
||||
/obj/item/organ/genital/breasts/is_exposed()
|
||||
. = ..()
|
||||
if(.)
|
||||
return TRUE
|
||||
return owner.is_chest_exposed()
|
||||
@@ -1,5 +1,5 @@
|
||||
/obj/item/organ/genital/eggsack
|
||||
name = "egg sack"
|
||||
name = "Egg sack"
|
||||
desc = "An egg producing reproductive organ."
|
||||
icon_state = "egg_sack"
|
||||
icon = 'code/citadel/icons/ovipositor.dmi'
|
||||
@@ -7,7 +7,7 @@
|
||||
slot = "testicles"
|
||||
color = null //don't use the /genital color since it already is colored
|
||||
w_class = 3
|
||||
var/internal = TRUE
|
||||
internal = TRUE
|
||||
var/egg_girth = EGG_GIRTH_DEF
|
||||
var/cum_mult = CUM_RATE_MULT
|
||||
var/cum_rate = CUM_RATE
|
||||
|
||||
@@ -3,7 +3,10 @@
|
||||
var/shape = "human"
|
||||
var/sensitivity = 1
|
||||
var/list/genital_flags = list()
|
||||
var/can_masturbate_with = 0
|
||||
var/can_masturbate_with = FALSE
|
||||
var/masturbation_verb = "masturbate"
|
||||
var/can_climax = FALSE
|
||||
var/fluid_transfer_factor = 0.0 //How much would a partner get in them if they climax using this?
|
||||
var/size = 2 //can vary between num or text, just used in icon_state strings
|
||||
var/fluid_id = null
|
||||
var/fluid_max_volume = 50
|
||||
@@ -13,6 +16,9 @@
|
||||
var/producing = FALSE
|
||||
var/aroused_state = FALSE //Boolean used in icon_state strings
|
||||
var/aroused_amount = 50 //This is a num from 0 to 100 for arousal percentage for when to use arousal state icons.
|
||||
var/obj/item/organ/genital/linked_organ
|
||||
var/through_clothes = FALSE
|
||||
var/internal = FALSE
|
||||
|
||||
/obj/item/organ/genital/Initialize()
|
||||
. = ..()
|
||||
@@ -34,6 +40,52 @@
|
||||
update_appearance()
|
||||
update_link()
|
||||
|
||||
//exposure and through-clothing code
|
||||
/mob/living/carbon
|
||||
var/list/exposed_genitals = list() //Keeping track of them so we don't have to iterate through every genitalia and see if exposed
|
||||
|
||||
/obj/item/organ/genital/proc/is_exposed()
|
||||
if(!owner)
|
||||
return FALSE
|
||||
if(internal)
|
||||
return FALSE
|
||||
if(through_clothes)
|
||||
return TRUE
|
||||
|
||||
/obj/item/organ/genital/proc/toggle_through_clothes()
|
||||
if(through_clothes)
|
||||
through_clothes = FALSE
|
||||
owner.exposed_genitals -= src
|
||||
else
|
||||
through_clothes = TRUE
|
||||
owner.exposed_genitals += src
|
||||
if(ishuman(owner)) //recast to use update genitals proc
|
||||
var/mob/living/carbon/human/H = owner
|
||||
H.update_genitals()
|
||||
|
||||
/mob/living/carbon/verb/toggle_genitals()
|
||||
set category = "IC"
|
||||
set name = "Expose/Hide genitals"
|
||||
set desc = "Allows you to toggle which genitals should show through clothes or not."
|
||||
|
||||
var/list/genital_list = list()
|
||||
for(var/obj/item/organ/O in internal_organs)
|
||||
if(istype(O, /obj/item/organ/genital))
|
||||
var/obj/item/organ/genital/G = O
|
||||
if(!G.internal)
|
||||
genital_list += G
|
||||
if(!genital_list.len) //There is nothing to expose
|
||||
return
|
||||
//Full list of exposable genitals created
|
||||
var/obj/item/organ/genital/picked_organ
|
||||
picked_organ = input(src, "Expose/Hide genitals", "Choose which genitalia to expose/hide", null) in genital_list
|
||||
if(picked_organ)
|
||||
picked_organ.toggle_through_clothes()
|
||||
return
|
||||
|
||||
|
||||
|
||||
|
||||
/obj/item/organ/genital/proc/update_size()
|
||||
|
||||
/obj/item/organ/genital/proc/update_appearance()
|
||||
@@ -41,6 +93,9 @@
|
||||
/obj/item/organ/genital/proc/update_link()
|
||||
|
||||
/obj/item/organ/genital/proc/remove_ref()
|
||||
if(linked_organ)
|
||||
linked_organ.linked_organ = null
|
||||
linked_organ = null
|
||||
|
||||
/obj/item/organ/genital/Insert(mob/living/carbon/M, special = 0)
|
||||
..()
|
||||
@@ -58,21 +113,21 @@
|
||||
var/obj/item/organ/genital/GtoClean
|
||||
for(GtoClean in internal_organs)
|
||||
qdel(GtoClean)
|
||||
|
||||
if(dna.features["has_cock"])
|
||||
give_penis()
|
||||
if(dna.features["has_balls"])
|
||||
give_balls()
|
||||
else if(dna.features["has_ovi"])
|
||||
give_ovipositor()
|
||||
if(dna.features["has_eggsack"])
|
||||
give_eggsack()
|
||||
//Order should be very important. FIRST vagina, THEN testicles, THEN penis, as this affects the order they are rendered in.
|
||||
if(dna.features["has_breasts"])
|
||||
give_breasts()
|
||||
if(dna.features["has_vag"])
|
||||
give_vagina()
|
||||
if(dna.features["has_womb"])
|
||||
give_womb()
|
||||
if(dna.features["has_womb"])
|
||||
give_womb()
|
||||
if(dna.features["has_balls"])
|
||||
give_balls()
|
||||
if(dna.features["has_cock"])
|
||||
give_penis()
|
||||
if(dna.features["has_ovi"])
|
||||
give_ovipositor()
|
||||
if(dna.features["has_eggsack"])
|
||||
give_eggsack()
|
||||
|
||||
/mob/living/carbon/human/proc/give_penis()
|
||||
if(!dna)
|
||||
@@ -208,17 +263,15 @@
|
||||
if(H.disabilities & HUSK)
|
||||
return
|
||||
//start scanning for genitals
|
||||
var/list/worn_stuff = H.get_equipped_items()//cache this list so it's not built again
|
||||
if(H.is_groin_exposed(worn_stuff))
|
||||
//ORDER is important here. Vaginas first, theoretical testes after, and penis LAST.
|
||||
//The latter is always drawn on top of the former.
|
||||
if(H.has_vagina())
|
||||
genitals_to_add += H.getorganslot("vagina")
|
||||
if(H.has_penis())
|
||||
genitals_to_add += H.getorganslot("penis")
|
||||
if(H.is_chest_exposed(worn_stuff))
|
||||
if(H.has_breasts())
|
||||
genitals_to_add += H.getorganslot("breasts")
|
||||
//var/list/worn_stuff = H.get_equipped_items()//cache this list so it's not built again
|
||||
|
||||
for(var/obj/item/organ/O in H.internal_organs)
|
||||
if(istype(O, /obj/item/organ/genital))
|
||||
var/obj/item/organ/genital/G = O
|
||||
if(G.is_exposed()) //Checks appropriate clothing slot and if it's through_clothes
|
||||
genitals_to_add += H.getorganslot(G.slot)
|
||||
//Now we added all genitals that aren't internal and should be rendered
|
||||
|
||||
var/image/I
|
||||
//start applying overlays
|
||||
for(var/layer in relevant_layers)
|
||||
@@ -243,8 +296,10 @@
|
||||
G.aroused_state = FALSE
|
||||
icon_string = "[G.slot]_[S.icon_state]_[size]_[G.aroused_state]_[layertext]"
|
||||
I = image("icon" = S.icon, "icon_state" = icon_string, "layer" =- layer)
|
||||
|
||||
if(S.center)
|
||||
I = center_image(I,S.dimension_x,S.dimension_y)
|
||||
|
||||
if(use_skintones && H.dna.features["genitals_use_skintone"])
|
||||
I.color = "#[skintone2hex(H.skin_tone)]"
|
||||
else
|
||||
|
||||
@@ -31,6 +31,33 @@
|
||||
icon_state = "tapered"
|
||||
name = "Tapered"
|
||||
|
||||
////////////////////////
|
||||
// Taur cocks go here //
|
||||
////////////////////////
|
||||
/datum/sprite_accessory/penis/taur_flared
|
||||
icon = 'code/citadel/icons/taur_penis_onmob.dmi' //Needed larger width
|
||||
icon_state = "flared"
|
||||
name = "Taur, Flared"
|
||||
center = TRUE //Center the image 'cause 2-tile wide.
|
||||
dimension_x = 64
|
||||
|
||||
/datum/sprite_accessory/penis/taur_knotted
|
||||
icon = 'code/citadel/icons/taur_penis_onmob.dmi' //Needed larger width
|
||||
icon_state = "knotted"
|
||||
name = "Taur, Knotted"
|
||||
center = TRUE //Center the image 'cause 2-tile wide.
|
||||
dimension_x = 64
|
||||
|
||||
/datum/sprite_accessory/penis/taur_tapered
|
||||
icon = 'code/citadel/icons/taur_penis_onmob.dmi' //Needed larger width
|
||||
icon_state = "tapered"
|
||||
name = "Taur, Tapered"
|
||||
center = TRUE //Center the image 'cause 2-tile wide.
|
||||
dimension_x = 64
|
||||
|
||||
|
||||
|
||||
|
||||
//Vaginas
|
||||
/datum/sprite_accessory/vagina
|
||||
icon = 'code/citadel/icons/vagina_onmob.dmi'
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/obj/item/organ/genital/ovipositor
|
||||
name = "ovipositor"
|
||||
name = "Ovipositor"
|
||||
desc = "An egg laying reproductive organ."
|
||||
icon_state = "ovi_knotted_2"
|
||||
icon = 'code/citadel/icons/ovipositor.dmi'
|
||||
|
||||
@@ -1,21 +1,23 @@
|
||||
/obj/item/organ/genital/penis
|
||||
name = "penis"
|
||||
desc = "A male reproductive organ."
|
||||
icon_state = "penis"
|
||||
icon = 'code/citadel/icons/penis.dmi'
|
||||
zone = "groin"
|
||||
slot = "penis"
|
||||
w_class = 3
|
||||
can_masturbate_with = 1
|
||||
size = 2 //arbitrary value derived from length and girth for sprites.
|
||||
var/length = 6 //inches
|
||||
name = "penis"
|
||||
desc = "A male reproductive organ."
|
||||
icon_state = "penis"
|
||||
icon = 'code/citadel/icons/penis.dmi'
|
||||
zone = "groin"
|
||||
slot = "penis"
|
||||
w_class = 3
|
||||
can_masturbate_with = TRUE
|
||||
masturbation_verb = "stroke"
|
||||
can_climax = TRUE
|
||||
fluid_transfer_factor = 0.5
|
||||
size = 2 //arbitrary value derived from length and girth for sprites.
|
||||
var/length = 6 //inches
|
||||
var/cached_length //used to detect a change in length
|
||||
var/girth = 0
|
||||
var/girth_ratio = COCK_GIRTH_RATIO_DEF //0.73; check citadel_defines.dm
|
||||
var/knot_girth_ratio = KNOT_GIRTH_RATIO_DEF
|
||||
var/list/dickflags = list()
|
||||
var/list/knotted_types = list("knotted", "barbknot")
|
||||
var/obj/item/organ/genital/testicles/linked_balls
|
||||
var/girth = 0
|
||||
var/girth_ratio = COCK_GIRTH_RATIO_DEF //0.73; check citadel_defines.dm
|
||||
var/knot_girth_ratio = KNOT_GIRTH_RATIO_DEF
|
||||
var/list/dickflags = list()
|
||||
var/list/knotted_types = list("knotted", "barbknot")
|
||||
|
||||
/obj/item/organ/genital/penis/update_size()
|
||||
if(length == cached_length)
|
||||
@@ -35,7 +37,7 @@
|
||||
cached_length = length
|
||||
|
||||
/obj/item/organ/genital/penis/update_appearance()
|
||||
var/string = "penis_[lowertext(shape)]_[size]"
|
||||
var/string = "penis_[GLOB.cock_shapes_icons[shape]]_[size]"
|
||||
icon_state = sanitize_text(string)
|
||||
var/lowershape = lowertext(shape)
|
||||
if(lowershape in knotted_types)
|
||||
@@ -55,15 +57,16 @@
|
||||
|
||||
/obj/item/organ/genital/penis/update_link()
|
||||
if(owner)
|
||||
linked_balls = (owner.getorganslot("testicles"))
|
||||
if(linked_balls)
|
||||
linked_balls.linked_penis = src
|
||||
linked_organ = (owner.getorganslot("testicles"))
|
||||
if(linked_organ)
|
||||
linked_organ.linked_organ = src
|
||||
else
|
||||
if(linked_balls)
|
||||
linked_balls.linked_penis = null
|
||||
linked_balls = null
|
||||
if(linked_organ)
|
||||
linked_organ.linked_organ = null
|
||||
linked_organ = null
|
||||
|
||||
/obj/item/organ/genital/penis/remove_ref()
|
||||
if(linked_balls)
|
||||
linked_balls.linked_penis = null
|
||||
linked_balls = null
|
||||
/obj/item/organ/genital/penis/is_exposed()
|
||||
. = ..()
|
||||
if(.)
|
||||
return TRUE
|
||||
return owner.is_groin_exposed()
|
||||
@@ -6,13 +6,12 @@
|
||||
zone = "groin"
|
||||
slot = "testicles"
|
||||
w_class = 3
|
||||
var/internal = FALSE
|
||||
internal = TRUE
|
||||
size = BALLS_SIZE_DEF
|
||||
var/sack_size = BALLS_SACK_SIZE_DEF
|
||||
fluid_id = "semen"
|
||||
producing = TRUE
|
||||
var/sent_full_message = 1 //defaults to 1 since they're full to start
|
||||
var/obj/item/organ/genital/penis/linked_penis
|
||||
|
||||
/obj/item/organ/genital/testicles/Initialize()
|
||||
. = ..()
|
||||
@@ -33,20 +32,20 @@
|
||||
return FALSE
|
||||
sent_full_message = 0
|
||||
update_link()
|
||||
if(!linked_penis)
|
||||
if(!linked_organ)
|
||||
return FALSE
|
||||
reagents.isolate_reagent(fluid_id)//remove old reagents if it changed and just clean up generally
|
||||
reagents.add_reagent(fluid_id, (fluid_mult * fluid_rate))//generate the cum
|
||||
|
||||
/obj/item/organ/genital/testicles/update_link()
|
||||
if(owner && !QDELETED(src))
|
||||
linked_penis = (owner.getorganslot("penis"))
|
||||
if(linked_penis)
|
||||
linked_penis.linked_balls = src
|
||||
linked_organ = (owner.getorganslot("penis"))
|
||||
if(linked_organ)
|
||||
linked_organ.linked_organ = src
|
||||
else
|
||||
if(linked_penis)
|
||||
linked_penis.linked_balls = null
|
||||
linked_penis = null
|
||||
if(linked_organ)
|
||||
linked_organ.linked_organ = null
|
||||
linked_organ = null
|
||||
|
||||
/obj/item/organ/genital/testicles/proc/send_full_message(msg = "Your balls finally feel full, again.")
|
||||
if(owner && istext(msg))
|
||||
|
||||
@@ -6,7 +6,10 @@
|
||||
zone = "groin"
|
||||
slot = "vagina"
|
||||
size = 1 //There is only 1 size right now
|
||||
can_masturbate_with = 1
|
||||
can_masturbate_with = TRUE
|
||||
masturbation_verb = "finger"
|
||||
can_climax = TRUE
|
||||
fluid_transfer_factor = 0.1 //Yes, some amount is exposed to you, go get your AIDS
|
||||
w_class = 3
|
||||
var/cap_length = 8//D E P T H (cap = capacity)
|
||||
var/cap_girth = 12
|
||||
@@ -15,7 +18,6 @@
|
||||
var/clit_diam = 0.25
|
||||
var/clit_len = 0.25
|
||||
var/list/vag_types = list("tentacle", "dentata", "hairy")
|
||||
var/obj/item/organ/genital/womb/linked_womb
|
||||
|
||||
|
||||
/obj/item/organ/genital/vagina/update_appearance()
|
||||
@@ -56,15 +58,16 @@
|
||||
|
||||
/obj/item/organ/genital/vagina/update_link()
|
||||
if(owner)
|
||||
linked_womb = (owner.getorganslot("womb"))
|
||||
if(linked_womb)
|
||||
linked_womb.linked_vag = src
|
||||
linked_organ = (owner.getorganslot("womb"))
|
||||
if(linked_organ)
|
||||
linked_organ.linked_organ = src
|
||||
else
|
||||
if(linked_womb)
|
||||
linked_womb.linked_vag = null
|
||||
linked_womb = null
|
||||
if(linked_organ)
|
||||
linked_organ.linked_organ = null
|
||||
linked_organ = null
|
||||
|
||||
/obj/item/organ/genital/vagina/remove_ref()
|
||||
if(linked_womb)
|
||||
linked_womb.linked_vag = null
|
||||
linked_womb = null
|
||||
/obj/item/organ/genital/vagina/is_exposed()
|
||||
. = ..()
|
||||
if(.)
|
||||
return TRUE
|
||||
return owner.is_groin_exposed()
|
||||
+10
-15
@@ -6,11 +6,11 @@
|
||||
zone = "groin"
|
||||
slot = "womb"
|
||||
w_class = 3
|
||||
var/internal = FALSE
|
||||
internal = TRUE
|
||||
fluid_id = "femcum"
|
||||
producing = TRUE
|
||||
var/obj/item/organ/genital/vagina/linked_vag
|
||||
|
||||
|
||||
|
||||
/obj/item/organ/genital/womb/Initialize()
|
||||
. = ..()
|
||||
reagents.add_reagent(fluid_id, fluid_max_volume)
|
||||
@@ -24,25 +24,20 @@
|
||||
/obj/item/organ/genital/womb/proc/generate_femcum()
|
||||
reagents.maximum_volume = fluid_max_volume
|
||||
update_link()
|
||||
if(!linked_vag)
|
||||
if(!linked_organ)
|
||||
return FALSE
|
||||
reagents.isolate_reagent(fluid_id)//remove old reagents if it changed and just clean up generally
|
||||
reagents.add_reagent(fluid_id, (fluid_mult * fluid_rate))//generate the cum
|
||||
|
||||
/obj/item/organ/genital/womb/update_link()
|
||||
if(owner)
|
||||
linked_vag = (owner.getorganslot("vagina"))
|
||||
if(linked_vag)
|
||||
linked_vag.linked_womb = src
|
||||
linked_organ = (owner.getorganslot("vagina"))
|
||||
if(linked_organ)
|
||||
linked_organ.linked_organ = src
|
||||
else
|
||||
if(linked_vag)
|
||||
linked_vag.linked_womb = null
|
||||
linked_vag = null
|
||||
|
||||
/obj/item/organ/genital/womb/remove_ref()
|
||||
if(linked_vag)
|
||||
linked_vag.linked_womb = null
|
||||
linked_vag = null
|
||||
if(linked_organ)
|
||||
linked_organ.linked_organ = null
|
||||
linked_organ = null
|
||||
|
||||
/obj/item/organ/genital/womb/Destroy()
|
||||
return ..()
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -275,7 +275,7 @@
|
||||
|
||||
if(M.config_tag)
|
||||
if(!(M.config_tag in modes)) // ensure each mode is added only once
|
||||
GLOB.config_error_log << "Adding game mode [M.name] ([M.config_tag]) to configuration."
|
||||
WRITE_FILE(GLOB.config_error_log, "Adding game mode [M.name] ([M.config_tag]) to configuration.")
|
||||
modes += M.config_tag
|
||||
mode_names[M.config_tag] = M.name
|
||||
probabilities[M.config_tag] = M.probability
|
||||
@@ -548,7 +548,7 @@
|
||||
if("irc_announce_new_game")
|
||||
irc_announce_new_game = TRUE
|
||||
else
|
||||
GLOB.config_error_log << "Unknown setting in configuration: '[name]'"
|
||||
WRITE_FILE(GLOB.config_error_log, "Unknown setting in configuration: '[name]'")
|
||||
|
||||
else if(type == "game_options")
|
||||
switch(name)
|
||||
@@ -611,13 +611,13 @@
|
||||
if(mode_name in modes)
|
||||
continuous[mode_name] = 1
|
||||
else
|
||||
GLOB.config_error_log << "Unknown continuous configuration definition: [mode_name]."
|
||||
WRITE_FILE(GLOB.config_error_log, "Unknown continuous configuration definition: [mode_name].")
|
||||
if("midround_antag")
|
||||
var/mode_name = lowertext(value)
|
||||
if(mode_name in modes)
|
||||
midround_antag[mode_name] = 1
|
||||
else
|
||||
GLOB.config_error_log << "Unknown midround antagonist configuration definition: [mode_name]."
|
||||
WRITE_FILE(GLOB.config_error_log, "Unknown midround antagonist configuration definition: [mode_name].")
|
||||
if("midround_antag_time_check")
|
||||
midround_antag_time_check = text2num(value)
|
||||
if("midround_antag_life_check")
|
||||
@@ -633,9 +633,9 @@
|
||||
if(mode_name in modes)
|
||||
min_pop[mode_name] = text2num(mode_value)
|
||||
else
|
||||
GLOB.config_error_log << "Unknown minimum population configuration definition: [mode_name]."
|
||||
WRITE_FILE(GLOB.config_error_log, "Unknown minimum population configuration definition: [mode_name].")
|
||||
else
|
||||
GLOB.config_error_log << "Incorrect minimum population configuration definition: [mode_name] [mode_value]."
|
||||
WRITE_FILE(GLOB.config_error_log, "Incorrect minimum population configuration definition: [mode_name] [mode_value].")
|
||||
if("max_pop")
|
||||
var/pop_pos = findtext(value, " ")
|
||||
var/mode_name = null
|
||||
@@ -647,9 +647,9 @@
|
||||
if(mode_name in modes)
|
||||
max_pop[mode_name] = text2num(mode_value)
|
||||
else
|
||||
GLOB.config_error_log << "Unknown maximum population configuration definition: [mode_name]."
|
||||
WRITE_FILE(GLOB.config_error_log, "Unknown maximum population configuration definition: [mode_name].")
|
||||
else
|
||||
GLOB.config_error_log << "Incorrect maximum population configuration definition: [mode_name] [mode_value]."
|
||||
WRITE_FILE(GLOB.config_error_log, "Incorrect maximum population configuration definition: [mode_name] [mode_value].")
|
||||
if("shuttle_refuel_delay")
|
||||
shuttle_refuel_delay = text2num(value)
|
||||
if("show_game_type_odds")
|
||||
@@ -677,9 +677,9 @@
|
||||
if(prob_name in modes)
|
||||
probabilities[prob_name] = text2num(prob_value)
|
||||
else
|
||||
GLOB.config_error_log << "Unknown game mode probability configuration definition: [prob_name]."
|
||||
WRITE_FILE(GLOB.config_error_log, "Unknown game mode probability configuration definition: [prob_name].")
|
||||
else
|
||||
GLOB.config_error_log << "Incorrect probability configuration definition: [prob_name] [prob_value]."
|
||||
WRITE_FILE(GLOB.config_error_log, "Incorrect probability configuration definition: [prob_name] [prob_value].")
|
||||
|
||||
if("protect_roles_from_antagonist")
|
||||
protect_roles_from_antagonist = 1
|
||||
@@ -726,7 +726,7 @@
|
||||
// Value is in the form "LAWID,NUMBER"
|
||||
var/list/L = splittext(value, ",")
|
||||
if(L.len != 2)
|
||||
GLOB.config_error_log << "Invalid LAW_WEIGHT: " + t
|
||||
WRITE_FILE(GLOB.config_error_log, "Invalid LAW_WEIGHT: " + t)
|
||||
continue
|
||||
var/lawid = L[1]
|
||||
var/weight = text2num(L[2])
|
||||
@@ -781,7 +781,7 @@
|
||||
if("mice_roundstart")
|
||||
mice_roundstart = text2num(value)
|
||||
else
|
||||
GLOB.config_error_log << "Unknown setting in configuration: '[name]'"
|
||||
WRITE_FILE(GLOB.config_error_log, "Unknown setting in configuration: '[name]'")
|
||||
else if(type == "policies")
|
||||
policies[name] = value
|
||||
|
||||
@@ -839,7 +839,7 @@
|
||||
if ("disabled")
|
||||
currentmap = null
|
||||
else
|
||||
GLOB.config_error_log << "Unknown command in map vote config: '[command]'"
|
||||
WRITE_FILE(GLOB.config_error_log, "Unknown command in map vote config: '[command]'")
|
||||
|
||||
|
||||
/datum/configuration/proc/loadsql(filename)
|
||||
@@ -883,7 +883,7 @@
|
||||
if("feedback_tableprefix")
|
||||
global.sqlfdbktableprefix = value
|
||||
else
|
||||
GLOB.config_error_log << "Unknown setting in configuration: '[name]'"
|
||||
WRITE_FILE(GLOB.config_error_log, "Unknown setting in configuration: '[name]'")
|
||||
|
||||
/datum/configuration/proc/pick_mode(mode_name)
|
||||
// I wish I didn't have to instance the game modes in order to look up
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
|
||||
var/static/restart_clear = 0
|
||||
var/static/restart_timeout = 0
|
||||
var/static/restart_count = 0
|
||||
|
||||
|
||||
//current tick limit, assigned before running a subsystem.
|
||||
//used by CHECK_TICK as well so that the procs subsystems call can obey that SS's tick limits
|
||||
var/static/current_ticklimit = TICK_LIMIT_RUNNING
|
||||
@@ -131,7 +131,7 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
|
||||
FireHim = TRUE
|
||||
if(3)
|
||||
msg = "The [BadBoy.name] subsystem seems to be destabilizing the MC and will be offlined."
|
||||
BadBoy.flags |= SS_NO_FIRE
|
||||
BadBoy.flags_1 |= SS_NO_FIRE
|
||||
if(msg)
|
||||
to_chat(GLOB.admins, "<span class='boldannounce'>[msg]</span>")
|
||||
log_world(msg)
|
||||
@@ -167,7 +167,7 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
|
||||
// Initialize subsystems.
|
||||
current_ticklimit = config.tick_limit_mc_init
|
||||
for (var/datum/controller/subsystem/SS in subsystems)
|
||||
if (SS.flags & SS_NO_INIT)
|
||||
if (SS.flags_1 & SS_NO_INIT)
|
||||
continue
|
||||
SS.Initialize(REALTIMEOFDAY)
|
||||
CHECK_TICK
|
||||
@@ -232,13 +232,13 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
|
||||
var/timer = world.time
|
||||
for (var/thing in subsystems)
|
||||
var/datum/controller/subsystem/SS = thing
|
||||
if (SS.flags & SS_NO_FIRE)
|
||||
if (SS.flags_1 & SS_NO_FIRE)
|
||||
continue
|
||||
SS.queued_time = 0
|
||||
SS.queue_next = null
|
||||
SS.queue_prev = null
|
||||
SS.state = SS_IDLE
|
||||
if (SS.flags & SS_TICKER)
|
||||
if (SS.flags_1 & SS_TICKER)
|
||||
tickersubsystems += SS
|
||||
timer += world.tick_lag * rand(1, 5)
|
||||
SS.next_fire = timer
|
||||
@@ -371,7 +371,7 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
|
||||
continue
|
||||
if (SS.next_fire > world.time)
|
||||
continue
|
||||
SS_flags = SS.flags
|
||||
SS_flags = SS.flags_1
|
||||
if (SS_flags & SS_NO_FIRE)
|
||||
subsystemstocheck -= SS
|
||||
continue
|
||||
@@ -408,7 +408,7 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
|
||||
if (ran && world.tick_usage > TICK_LIMIT_RUNNING)
|
||||
break
|
||||
|
||||
queue_node_flags = queue_node.flags
|
||||
queue_node_flags = queue_node.flags_1
|
||||
queue_node_priority = queue_node.queued_priority
|
||||
|
||||
//super special case, subsystems where we can't make them pause mid way through
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
var/wait = 20 //time to wait (in deciseconds) between each call to fire(). Must be a positive integer.
|
||||
var/priority = 50 //When mutiple subsystems need to run in the same tick, higher priority subsystems will run first and be given a higher share of the tick before MC_TICK_CHECK triggers a sleep
|
||||
|
||||
var/flags = 0 //see MC.dm in __DEFINES Most flags must be set on world start to take full effect. (You can also restart the mc to force them to process again)
|
||||
var/flags_1 = 0 //see MC.dm in __DEFINES Most flags_1 must be set on world start to take full effect. (You can also restart the mc to force them to process again)
|
||||
|
||||
//set to 0 to prevent fire() calls, mostly for admin use or subsystems that may be resumed later
|
||||
// use the SS_NO_FIRE flag instead for systems that never fire to keep it from even being added to the list
|
||||
@@ -61,13 +61,13 @@
|
||||
//fire() seems more suitable. This is the procedure that gets called every 'wait' deciseconds.
|
||||
//Sleeping in here prevents future fires until returned.
|
||||
/datum/controller/subsystem/proc/fire(resumed = 0)
|
||||
flags |= SS_NO_FIRE
|
||||
flags_1 |= SS_NO_FIRE
|
||||
throw EXCEPTION("Subsystem [src]([type]) does not fire() but did not set the SS_NO_FIRE flag. Please add the SS_NO_FIRE flag to any subsystem that doesn't fire so it doesn't get added to the processing list and waste cpu.")
|
||||
|
||||
/datum/controller/subsystem/Destroy()
|
||||
dequeue()
|
||||
can_fire = 0
|
||||
flags |= SS_NO_FIRE
|
||||
flags_1 |= SS_NO_FIRE
|
||||
Master.subsystems -= src
|
||||
|
||||
|
||||
@@ -76,14 +76,14 @@
|
||||
// (this lets us sort our run order correctly without having to re-sort the entire already sorted list)
|
||||
/datum/controller/subsystem/proc/enqueue()
|
||||
var/SS_priority = priority
|
||||
var/SS_flags = flags
|
||||
var/SS_flags = flags_1
|
||||
var/datum/controller/subsystem/queue_node
|
||||
var/queue_node_priority
|
||||
var/queue_node_flags
|
||||
|
||||
for (queue_node = Master.queue_head; queue_node; queue_node = queue_node.queue_next)
|
||||
queue_node_priority = queue_node.queued_priority
|
||||
queue_node_flags = queue_node.flags
|
||||
queue_node_flags = queue_node.flags_1
|
||||
|
||||
if (queue_node_flags & SS_TICKER)
|
||||
if (!(SS_flags & SS_TICKER))
|
||||
@@ -170,7 +170,7 @@
|
||||
|
||||
|
||||
|
||||
if(can_fire && !(SS_NO_FIRE in flags))
|
||||
if(can_fire && !(SS_NO_FIRE in flags_1))
|
||||
msg = "[round(cost,1)]ms|[round(tick_usage,1)]%([round(tick_overrun,1)]%)|[round(ticks,0.1)]\t[msg]"
|
||||
else
|
||||
msg = "OFFLINE\t[msg]"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
SUBSYSTEM_DEF(acid)
|
||||
name = "Acid"
|
||||
priority = 40
|
||||
flags = SS_NO_INIT|SS_BACKGROUND
|
||||
flags_1 = SS_NO_INIT|SS_BACKGROUND
|
||||
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
|
||||
|
||||
var/list/currentrun = list()
|
||||
|
||||
@@ -11,7 +11,7 @@ SUBSYSTEM_DEF(air)
|
||||
init_order = INIT_ORDER_AIR
|
||||
priority = 20
|
||||
wait = 5
|
||||
flags = SS_BACKGROUND
|
||||
flags_1 = SS_BACKGROUND
|
||||
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
|
||||
|
||||
var/cost_turfs = 0
|
||||
|
||||
@@ -1,14 +1,17 @@
|
||||
SUBSYSTEM_DEF(assets)
|
||||
name = "Assets"
|
||||
init_order = INIT_ORDER_ASSETS
|
||||
flags = SS_NO_FIRE
|
||||
flags_1 = SS_NO_FIRE
|
||||
var/list/cache = list()
|
||||
var/list/preload = list()
|
||||
|
||||
/datum/controller/subsystem/assets/Initialize(timeofday)
|
||||
for(var/type in typesof(/datum/asset) - list(/datum/asset, /datum/asset/simple))
|
||||
var/datum/asset/A = new type()
|
||||
A.register()
|
||||
|
||||
preload = cache.Copy() //don't preload assets generated during the round
|
||||
|
||||
for(var/client/C in GLOB.clients)
|
||||
addtimer(CALLBACK(GLOBAL_PROC, .proc/getFilesSlow, C, cache, FALSE), 10)
|
||||
addtimer(CALLBACK(GLOBAL_PROC, .proc/getFilesSlow, C, preload, FALSE), 10)
|
||||
..()
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
SUBSYSTEM_DEF(atoms)
|
||||
name = "Atoms"
|
||||
init_order = INIT_ORDER_ATOMS
|
||||
flags = SS_NO_FIRE
|
||||
flags_1 = SS_NO_FIRE
|
||||
|
||||
var/initialized = INITIALIZATION_INSSATOMS
|
||||
var/old_initialized
|
||||
@@ -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,6 +1,6 @@
|
||||
SUBSYSTEM_DEF(augury)
|
||||
name = "Augury"
|
||||
flags = SS_NO_INIT
|
||||
flags_1 = SS_NO_INIT
|
||||
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
|
||||
|
||||
var/list/watchers = list()
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
SUBSYSTEM_DEF(blackbox)
|
||||
name = "Blackbox"
|
||||
wait = 6000
|
||||
flags = SS_NO_TICK_CHECK | SS_NO_INIT
|
||||
flags_1 = SS_NO_TICK_CHECK | SS_NO_INIT
|
||||
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
|
||||
init_order = INIT_ORDER_BLACKBOX
|
||||
|
||||
@@ -253,19 +253,17 @@ SUBSYSTEM_DEF(blackbox)
|
||||
/datum/feedback_variable/proc/get_variable()
|
||||
return variable
|
||||
|
||||
/datum/feedback_variable/proc/set_details(text)
|
||||
if (istext(text))
|
||||
details = text
|
||||
|
||||
/datum/feedback_variable/proc/add_details(text)
|
||||
if (istext(text))
|
||||
if (!details)
|
||||
details = text
|
||||
else
|
||||
details += " [text]"
|
||||
/datum/feedback_variable/proc/set_details(deets)
|
||||
details = "\"[deets]\""
|
||||
|
||||
/datum/feedback_variable/proc/add_details(deets)
|
||||
if (!details)
|
||||
set_details(deets)
|
||||
else
|
||||
details += " | \"[deets]\""
|
||||
|
||||
/datum/feedback_variable/proc/get_details()
|
||||
return details
|
||||
|
||||
/datum/feedback_variable/proc/get_parsed()
|
||||
return list(variable,value,details)
|
||||
return list(variable,value,details)
|
||||
@@ -1,9 +1,9 @@
|
||||
#define COMMUNICATION_COOLDOWN 600
|
||||
#define COMMUNICATION_COOLDOWN_AI 600
|
||||
#define COMMUNICATION_COOLDOWN 300
|
||||
#define COMMUNICATION_COOLDOWN_AI 300
|
||||
|
||||
SUBSYSTEM_DEF(communications)
|
||||
name = "Communications"
|
||||
flags = SS_NO_INIT | SS_NO_FIRE
|
||||
flags_1 = SS_NO_INIT | SS_NO_FIRE
|
||||
|
||||
var/silicon_message_cooldown
|
||||
var/nonsilicon_message_cooldown
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
SUBSYSTEM_DEF(dbcore)
|
||||
name = "Database"
|
||||
flags = SS_NO_INIT|SS_NO_FIRE
|
||||
flags_1 = SS_NO_INIT|SS_NO_FIRE
|
||||
init_order = INIT_ORDER_DBCORE
|
||||
var/const/FAILED_DB_CONNECTION_CUTOFF = 5
|
||||
|
||||
@@ -251,7 +251,7 @@ Delayed insert mode was removed in mysql 7 and only works with MyISAM type table
|
||||
var/table
|
||||
var/position //1-based index into item data
|
||||
var/sql_type
|
||||
var/flags
|
||||
var/flags_1
|
||||
var/length
|
||||
var/max_length
|
||||
//types
|
||||
@@ -275,7 +275,7 @@ Delayed insert mode was removed in mysql 7 and only works with MyISAM type table
|
||||
table = table_handler
|
||||
position = position_handler
|
||||
sql_type = type_handler
|
||||
flags = flag_handler
|
||||
flags_1 = flag_handler
|
||||
length = length_handler
|
||||
max_length = max_length_handler
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
SUBSYSTEM_DEF(disease)
|
||||
name = "Disease"
|
||||
flags = SS_NO_FIRE
|
||||
flags_1 = 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]")
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
SUBSYSTEM_DEF(explosion)
|
||||
priority = 99
|
||||
wait = 1
|
||||
flags = SS_TICKER|SS_NO_INIT
|
||||
flags_1 = SS_TICKER|SS_NO_INIT
|
||||
|
||||
var/list/explosions
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
SUBSYSTEM_DEF(fire_burning)
|
||||
name = "Fire Burning"
|
||||
priority = 40
|
||||
flags = SS_NO_INIT|SS_BACKGROUND
|
||||
flags_1 = SS_NO_INIT|SS_BACKGROUND
|
||||
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
|
||||
|
||||
var/list/currentrun = list()
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
SUBSYSTEM_DEF(garbage)
|
||||
name = "Garbage"
|
||||
priority = 15
|
||||
wait = 5
|
||||
flags = SS_POST_FIRE_TIMING|SS_BACKGROUND|SS_NO_INIT
|
||||
wait = 20
|
||||
flags_1 = SS_POST_FIRE_TIMING|SS_BACKGROUND|SS_NO_INIT
|
||||
runlevels = RUNLEVELS_DEFAULT | RUNLEVEL_LOBBY
|
||||
|
||||
var/collection_timeout = 3000// deciseconds to wait to let running procs finish before we just say fuck it and force del() the object
|
||||
@@ -67,9 +67,9 @@ SUBSYSTEM_DEF(garbage)
|
||||
HandleToBeQueued()
|
||||
if(state == SS_RUNNING)
|
||||
HandleQueue()
|
||||
|
||||
|
||||
if (state == SS_PAUSED) //make us wait again before the next run.
|
||||
state = SS_RUNNING
|
||||
state = SS_RUNNING
|
||||
|
||||
//If you see this proc high on the profile, what you are really seeing is the garbage collection/soft delete overhead in byond.
|
||||
//Don't attempt to optimize, not worth the effort.
|
||||
@@ -114,7 +114,7 @@ SUBSYSTEM_DEF(garbage)
|
||||
var/type = A.type
|
||||
testing("GC: -- \ref[A] | [type] was unable to be GC'd and was deleted --")
|
||||
didntgc["[type]"]++
|
||||
|
||||
|
||||
HardDelete(A)
|
||||
|
||||
++delslasttick
|
||||
@@ -149,12 +149,12 @@ SUBSYSTEM_DEF(garbage)
|
||||
var/time = world.timeofday
|
||||
var/tick = world.tick_usage
|
||||
var/ticktime = world.time
|
||||
|
||||
|
||||
var/type = A.type
|
||||
var/refID = "\ref[A]"
|
||||
|
||||
|
||||
del(A)
|
||||
|
||||
|
||||
tick = (world.tick_usage-tick+((world.time-ticktime)/world.tick_lag*100))
|
||||
if (tick > highest_del_tickusage)
|
||||
highest_del_tickusage = tick
|
||||
@@ -167,7 +167,7 @@ SUBSYSTEM_DEF(garbage)
|
||||
log_game("Error: [type]([refID]) took longer than 1 second to delete (took [time/10] seconds to delete)")
|
||||
message_admins("Error: [type]([refID]) took longer than 1 second to delete (took [time/10] seconds to delete).")
|
||||
postpone(time/5)
|
||||
|
||||
|
||||
/datum/controller/subsystem/garbage/proc/HardQueue(datum/A)
|
||||
if (istype(A) && A.gc_destroyed == GC_CURRENTLY_BEING_QDELETED)
|
||||
tobequeued += A
|
||||
|
||||
@@ -3,7 +3,7 @@ SUBSYSTEM_DEF(icon_smooth)
|
||||
init_order = INIT_ORDER_ICON_SMOOTHING
|
||||
wait = 1
|
||||
priority = 35
|
||||
flags = SS_TICKER
|
||||
flags_1 = SS_TICKER
|
||||
|
||||
var/list/smooth_queue = list()
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
SUBSYSTEM_DEF(inbounds)
|
||||
name = "Inbounds"
|
||||
priority = 40
|
||||
flags = SS_NO_INIT
|
||||
flags_1 = SS_NO_INIT
|
||||
runlevels = RUNLEVEL_GAME
|
||||
|
||||
var/list/processing = list()
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
SUBSYSTEM_DEF(ipintel)
|
||||
name = "XKeyScore"
|
||||
init_order = INIT_ORDER_XKEYSCORE
|
||||
flags = SS_NO_FIRE
|
||||
flags_1 = SS_NO_FIRE
|
||||
var/enabled = 0 //disable at round start to avoid checking reconnects
|
||||
var/throttle = 0
|
||||
var/errors = 0
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
SUBSYSTEM_DEF(job)
|
||||
name = "Jobs"
|
||||
init_order = INIT_ORDER_JOBS
|
||||
flags = SS_NO_FIRE
|
||||
flags_1 = SS_NO_FIRE
|
||||
|
||||
var/list/occupations = list() //List of all jobs
|
||||
var/list/name_occupations = list() //Dict of all jobs, keys are titles
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
SUBSYSTEM_DEF(language)
|
||||
name = "Language"
|
||||
init_order = INIT_ORDER_LANGUAGE
|
||||
flags = SS_NO_FIRE
|
||||
flags_1 = SS_NO_FIRE
|
||||
|
||||
/datum/controller/subsystem/language/Initialize(timeofday)
|
||||
for(var/L in subtypesof(/datum/language))
|
||||
|
||||
@@ -6,7 +6,7 @@ SUBSYSTEM_DEF(lighting)
|
||||
name = "Lighting"
|
||||
wait = 2
|
||||
init_order = INIT_ORDER_LIGHTING
|
||||
flags = SS_TICKER
|
||||
flags_1 = SS_TICKER
|
||||
|
||||
var/initialized = FALSE
|
||||
|
||||
@@ -24,7 +24,7 @@ SUBSYSTEM_DEF(lighting)
|
||||
|
||||
create_all_lighting_objects()
|
||||
initialized = TRUE
|
||||
|
||||
|
||||
fire(FALSE, TRUE)
|
||||
|
||||
..()
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
SUBSYSTEM_DEF(machines)
|
||||
name = "Machines"
|
||||
init_order = INIT_ORDER_MACHINES
|
||||
flags = SS_KEEP_TIMING
|
||||
flags_1 = SS_KEEP_TIMING
|
||||
var/list/processing = list()
|
||||
var/list/currentrun = list()
|
||||
var/list/powernets = list()
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
SUBSYSTEM_DEF(mapping)
|
||||
name = "Mapping"
|
||||
init_order = INIT_ORDER_MAPPING
|
||||
flags = SS_NO_FIRE
|
||||
flags_1 = SS_NO_FIRE
|
||||
|
||||
var/list/nuke_tiles = list()
|
||||
var/list/nuke_threats = list()
|
||||
@@ -84,7 +84,7 @@ SUBSYSTEM_DEF(mapping)
|
||||
C.update_icon()
|
||||
|
||||
/datum/controller/subsystem/mapping/Recover()
|
||||
flags |= SS_NO_INIT
|
||||
flags_1 |= SS_NO_INIT
|
||||
map_templates = SSmapping.map_templates
|
||||
ruins_templates = SSmapping.ruins_templates
|
||||
space_ruins_templates = SSmapping.space_ruins_templates
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
SUBSYSTEM_DEF(minimap)
|
||||
name = "Minimap"
|
||||
init_order = INIT_ORDER_MINIMAP
|
||||
flags = SS_NO_FIRE
|
||||
flags_1 = SS_NO_FIRE
|
||||
var/const/MINIMAP_SIZE = 2048
|
||||
var/const/TILE_SIZE = 8
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
SUBSYSTEM_DEF(mobs)
|
||||
name = "Mobs"
|
||||
priority = 100
|
||||
flags = SS_KEEP_TIMING|SS_NO_INIT
|
||||
flags_1 = SS_KEEP_TIMING|SS_NO_INIT
|
||||
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
|
||||
|
||||
var/list/currentrun = list()
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
SUBSYSTEM_DEF(npcpool)
|
||||
name = "NPC Pool"
|
||||
flags = SS_POST_FIRE_TIMING|SS_NO_INIT|SS_BACKGROUND
|
||||
flags_1 = SS_POST_FIRE_TIMING|SS_NO_INIT|SS_BACKGROUND
|
||||
priority = 20
|
||||
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ SUBSYSTEM_DEF(orbit)
|
||||
name = "Orbits"
|
||||
priority = 35
|
||||
wait = 2
|
||||
flags = SS_NO_INIT|SS_TICKER
|
||||
flags_1 = SS_NO_INIT|SS_TICKER
|
||||
|
||||
var/list/currentrun = list()
|
||||
var/list/processing = list()
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
SUBSYSTEM_DEF(pai)
|
||||
name = "pAI"
|
||||
|
||||
flags = SS_NO_INIT|SS_NO_FIRE
|
||||
flags_1 = SS_NO_INIT|SS_NO_FIRE
|
||||
|
||||
var/list/candidates = list()
|
||||
var/ghost_spam = FALSE
|
||||
@@ -149,7 +149,6 @@ SUBSYSTEM_DEF(pai)
|
||||
continue
|
||||
if(!(ROLE_PAI in G.client.prefs.be_special))
|
||||
continue
|
||||
//G << 'sound/misc/server-ready.ogg' //Alerting them to their consideration
|
||||
to_chat(G, "<span class='ghostalert'>[user] is requesting a pAI personality! Use the pAI button to submit yourself as one.</span>")
|
||||
addtimer(CALLBACK(src, .proc/spam_again), spam_delay)
|
||||
var/list/available = list()
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
SUBSYSTEM_DEF(parallax)
|
||||
name = "Parallax"
|
||||
wait = 2
|
||||
flags = SS_POST_FIRE_TIMING | SS_BACKGROUND | SS_NO_INIT
|
||||
flags_1 = SS_POST_FIRE_TIMING | SS_BACKGROUND | SS_NO_INIT
|
||||
priority = 65
|
||||
runlevels = RUNLEVEL_LOBBY | RUNLEVELS_DEFAULT
|
||||
var/list/currentrun
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
SUBSYSTEM_DEF(persistence)
|
||||
name = "Persistence"
|
||||
init_order = INIT_ORDER_PERSISTENCE
|
||||
flags = SS_NO_FIRE
|
||||
flags_1 = 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
|
||||
@@ -22,7 +22,7 @@ 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))
|
||||
satchel_blacklist = typecacheof(list(/obj/item/stack/tile/plasteel, /obj/item/crowbar))
|
||||
secret_satchels[SSmapping.config.map_name] >> old_secret_satchels
|
||||
|
||||
var/list/expanded_old_satchels = list()
|
||||
@@ -38,7 +38,7 @@ SUBSYSTEM_DEF(persistence)
|
||||
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)
|
||||
free_satchels += new /obj/item/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
|
||||
|
||||
@@ -49,7 +49,7 @@ SUBSYSTEM_DEF(persistence)
|
||||
satchel_string = pick_n_take(expanded_old_satchels)
|
||||
|
||||
old_secret_satchels = jointext(expanded_old_satchels,"#")
|
||||
secret_satchels[SSmapping.config.map_name] << old_secret_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
|
||||
@@ -59,7 +59,7 @@ SUBSYSTEM_DEF(persistence)
|
||||
if(!path)
|
||||
return 0
|
||||
|
||||
var/obj/item/weapon/storage/backpack/satchel/flat/F = new()
|
||||
var/obj/item/storage/backpack/satchel/flat/F = new()
|
||||
F.x = text2num(chosen_satchel[1])
|
||||
F.y = text2num(chosen_satchel[2])
|
||||
F.z = ZLEVEL_STATION
|
||||
@@ -157,7 +157,7 @@ SUBSYSTEM_DEF(persistence)
|
||||
|
||||
/datum/controller/subsystem/persistence/proc/CollectSecretSatchels()
|
||||
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()
|
||||
@@ -171,7 +171,7 @@ SUBSYSTEM_DEF(persistence)
|
||||
if(isemptylist(savable_obj))
|
||||
continue
|
||||
old_secret_satchels += "[F.x]|[F.y]|[pick(savable_obj)]#"
|
||||
secret_satchels[SSmapping.config.map_name] << old_secret_satchels
|
||||
WRITE_FILE(secret_satchels[SSmapping.config.map_name], old_secret_satchels)
|
||||
|
||||
/datum/controller/subsystem/persistence/proc/CollectChiselMessages()
|
||||
var/savefile/chisel_messages_sav = new /savefile("data/npc_saves/ChiselMessages.sav")
|
||||
@@ -181,14 +181,14 @@ SUBSYSTEM_DEF(persistence)
|
||||
|
||||
log_world("Saved [saved_messages.len] engraved messages on map [SSmapping.config.map_name]")
|
||||
|
||||
chisel_messages_sav[SSmapping.config.map_name] << json_encode(saved_messages)
|
||||
WRITE_FILE(chisel_messages_sav[SSmapping.config.map_name], json_encode(saved_messages))
|
||||
|
||||
/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()
|
||||
trophy_sav << json_encode(saved_trophies)
|
||||
WRITE_FILE(trophy_sav, json_encode(saved_trophies))
|
||||
|
||||
/datum/controller/subsystem/persistence/proc/SaveTrophy(obj/structure/displaycase/trophy/T)
|
||||
if(!T.added_roundstart && T.showpiece)
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
SUBSYSTEM_DEF(ping)
|
||||
name = "Ping"
|
||||
wait = 6
|
||||
flags = SS_POST_FIRE_TIMING|SS_FIRE_IN_LOBBY
|
||||
flags_1 = SS_POST_FIRE_TIMING|SS_FIRE_IN_LOBBY
|
||||
priority = 10
|
||||
var/list/currentrun
|
||||
|
||||
|
||||
@@ -2,5 +2,5 @@ PROCESSING_SUBSYSTEM_DEF(fields)
|
||||
name = "Fields"
|
||||
wait = 2
|
||||
priority = 40
|
||||
flags = SS_KEEP_TIMING | SS_NO_INIT
|
||||
flags_1 = SS_KEEP_TIMING | SS_NO_INIT
|
||||
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user