Merge branch 'master' into upstream-merge-29288
This commit is contained in:
@@ -78,7 +78,7 @@
|
||||
//If you specify a value the FIRST ONE is removed
|
||||
/datum/linked_list/proc/Remove(node)
|
||||
var/datum/linked_node/removing
|
||||
if(istype(node,/datum/linked_node))
|
||||
if(istype(node, /datum/linked_node))
|
||||
removing = node
|
||||
else
|
||||
//optimise removing head and tail, no point looping for them, especially the tail
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
diff a/code/__DEFINES/DNA.dm b/code/__DEFINES/DNA.dm (rejected hunks)
|
||||
@@ -114,4 +114,6 @@
|
||||
#define EASYLIMBATTACHMENT 23
|
||||
#define TOXINLOVER 24
|
||||
#define DIGITIGRADE 25 //Uses weird leg sprites. Optional for Lizards, required for ashwalkers. Don't give it to other races unless you make sprites for this (see human_parts_greyscale.dmi)
|
||||
-#define NO_UNDERWEAR 26
|
||||
+#define NO_UNDERWEAR 26
|
||||
+#define NOLIVER 27
|
||||
+#define NOSTOMACH 28
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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>)"
|
||||
|
||||
@@ -67,8 +67,8 @@
|
||||
#define PLASMA_MINIMUM_OXYGEN_NEEDED 2
|
||||
#define PLASMA_MINIMUM_OXYGEN_PLASMA_RATIO 30
|
||||
#define PLASMA_OXYGEN_FULLBURN 10
|
||||
#define MIN_PLASMA_DAMAGE 1
|
||||
#define MAX_PLASMA_DAMAGE 10
|
||||
#define MIN_TOXIC_GAS_DAMAGE 1
|
||||
#define MAX_TOXIC_GAS_DAMAGE 10
|
||||
#define MOLES_PLASMA_VISIBLE 0.5 //Moles in a standard cell after which plasma is visible
|
||||
//Plasma fusion properties
|
||||
#define PLASMA_BINDING_ENERGY 3000000
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
#define ANTAG_HUD_SINTOUCHED 16
|
||||
#define ANTAG_HUD_SOULLESS 17
|
||||
#define ANTAG_HUD_CLOCKWORK 18
|
||||
#define ANTAG_HUD_BORER 19
|
||||
|
||||
// Notification action types
|
||||
#define NOTIFY_JUMP "jump"
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
GLOBAL_VAR_INIT(clockwork_construction_value, 0) //The total value of all structures built by the clockwork cult
|
||||
GLOBAL_VAR_INIT(clockwork_caches, 0) //How many clockwork caches exist in the world (not each individual)
|
||||
GLOBAL_VAR_INIT(clockwork_vitality, 0) //How much Vitality is stored, total
|
||||
GLOBAL_LIST_EMPTY(active_daemons) //A list of all active tinkerer's daemons
|
||||
GLOBAL_LIST_EMPTY(all_clockwork_objects) //All clockwork items, structures, and effects in existence
|
||||
GLOBAL_LIST_EMPTY(all_clockwork_mobs) //All clockwork SERVANTS (not creatures) in existence
|
||||
|
||||
+147
-144
@@ -1,147 +1,150 @@
|
||||
/*ALL DEFINES RELATED TO COMBAT GO HERE*/
|
||||
|
||||
//Damage and status effect defines
|
||||
|
||||
//Damage defines //TODO: merge these down to reduce on defines
|
||||
#define BRUTE "brute"
|
||||
#define BURN "fire"
|
||||
#define TOX "tox"
|
||||
#define OXY "oxy"
|
||||
#define CLONE "clone"
|
||||
#define STAMINA "stamina"
|
||||
//citadel code
|
||||
#define AROUSAL "arousal"
|
||||
|
||||
//bitflag damage defines used for suicide_act
|
||||
#define BRUTELOSS 1
|
||||
#define FIRELOSS 2
|
||||
#define TOXLOSS 4
|
||||
#define OXYLOSS 8
|
||||
#define SHAME 16
|
||||
//citadel code
|
||||
#define AROUSAL 32
|
||||
|
||||
#define STUN "stun"
|
||||
#define KNOCKDOWN "knockdown"
|
||||
#define UNCONSCIOUS "unconscious"
|
||||
#define IRRADIATE "irradiate"
|
||||
#define STUTTER "stutter"
|
||||
#define SLUR "slur"
|
||||
#define EYE_BLUR "eye_blur"
|
||||
#define DROWSY "drowsy"
|
||||
#define JITTER "jitter"
|
||||
|
||||
//Bitflags defining which status effects could be or are inflicted on a mob
|
||||
#define CANSTUN 1
|
||||
#define CANKNOCKDOWN 2
|
||||
#define CANUNCONSCIOUS 4
|
||||
#define CANPUSH 8
|
||||
#define IGNORESLOWDOWN 16
|
||||
#define GOTTAGOFAST 32
|
||||
#define GOTTAGOREALLYFAST 64
|
||||
#define GODMODE 4096
|
||||
#define FAKEDEATH 8192 //Replaces stuff like changeling.changeling_fakedeath
|
||||
#define DISFIGURED 16384 //I'll probably move this elsewhere if I ever get wround to writing a bitflag mob-damage system
|
||||
#define XENO_HOST 32768 //Tracks whether we're gonna be a baby alien's mummy.
|
||||
|
||||
//Health Defines
|
||||
#define HEALTH_THRESHOLD_CRIT 0
|
||||
#define HEALTH_THRESHOLD_DEAD -100
|
||||
|
||||
//Actual combat defines
|
||||
|
||||
//click cooldowns, in tenths of a second, used for various combat actions
|
||||
#define CLICK_CD_MELEE 8
|
||||
#define CLICK_CD_RANGE 4
|
||||
#define CLICK_CD_RAPID 2
|
||||
#define CLICK_CD_CLICK_ABILITY 6
|
||||
#define CLICK_CD_BREAKOUT 100
|
||||
#define CLICK_CD_HANDCUFFED 10
|
||||
#define CLICK_CD_RESIST 20
|
||||
#define CLICK_CD_GRABBING 10
|
||||
|
||||
//Cuff resist speeds
|
||||
#define FAST_CUFFBREAK 1
|
||||
#define INSTANT_CUFFBREAK 2
|
||||
|
||||
//Grab levels
|
||||
#define GRAB_PASSIVE 0
|
||||
#define GRAB_AGGRESSIVE 1
|
||||
#define GRAB_NECK 2
|
||||
#define GRAB_KILL 3
|
||||
|
||||
//Attack types for checking shields/hit reactions
|
||||
#define MELEE_ATTACK 1
|
||||
#define UNARMED_ATTACK 2
|
||||
#define PROJECTILE_ATTACK 3
|
||||
#define THROWN_PROJECTILE_ATTACK 4
|
||||
#define LEAP_ATTACK 5
|
||||
|
||||
//attack visual effects
|
||||
#define ATTACK_EFFECT_PUNCH "punch"
|
||||
#define ATTACK_EFFECT_KICK "kick"
|
||||
#define ATTACK_EFFECT_SMASH "smash"
|
||||
#define ATTACK_EFFECT_CLAW "claw"
|
||||
#define ATTACK_EFFECT_DISARM "disarm"
|
||||
#define ATTACK_EFFECT_BITE "bite"
|
||||
#define ATTACK_EFFECT_MECHFIRE "mech_fire"
|
||||
#define ATTACK_EFFECT_MECHTOXIN "mech_toxin"
|
||||
#define ATTACK_EFFECT_BOOP "boop" //Honk
|
||||
|
||||
//intent defines
|
||||
#define INTENT_HELP "help"
|
||||
#define INTENT_GRAB "grab"
|
||||
#define INTENT_DISARM "disarm"
|
||||
#define INTENT_HARM "harm"
|
||||
//NOTE: INTENT_HOTKEY_* defines are not actual intents!
|
||||
//they are here to support hotkeys
|
||||
#define INTENT_HOTKEY_LEFT "left"
|
||||
#define INTENT_HOTKEY_RIGHT "right"
|
||||
|
||||
//the define for visible message range in combat
|
||||
#define COMBAT_MESSAGE_RANGE 3
|
||||
|
||||
//Combat object defines
|
||||
|
||||
//Embedded objects
|
||||
#define EMBEDDED_PAIN_CHANCE 15 //Chance for embedded objects to cause pain (damage user)
|
||||
#define EMBEDDED_ITEM_FALLOUT 5 //Chance for embedded object to fall out (causing pain but removing the object)
|
||||
#define EMBED_CHANCE 45 //Chance for an object to embed into somebody when thrown (if it's sharp)
|
||||
#define EMBEDDED_PAIN_MULTIPLIER 2 //Coefficient of multiplication for the damage the item does while embedded (this*item.w_class)
|
||||
#define EMBEDDED_FALL_PAIN_MULTIPLIER 5 //Coefficient of multiplication for the damage the item does when it falls out (this*item.w_class)
|
||||
#define EMBEDDED_IMPACT_PAIN_MULTIPLIER 4 //Coefficient of multiplication for the damage the item does when it first embeds (this*item.w_class)
|
||||
#define EMBED_THROWSPEED_THRESHOLD 4 //The minimum value of an item's throw_speed for it to embed (Unless it has embedded_ignore_throwspeed_threshold set to 1)
|
||||
#define EMBEDDED_UNSAFE_REMOVAL_PAIN_MULTIPLIER 8 //Coefficient of multiplication for the damage the item does when removed without a surgery (this*item.w_class)
|
||||
#define EMBEDDED_UNSAFE_REMOVAL_TIME 30 //A Time in ticks, total removal time = (this*item.w_class)
|
||||
|
||||
//Gun Stuff
|
||||
#define SAWN_INTACT 0
|
||||
#define SAWN_OFF 1
|
||||
//Gun weapon weight
|
||||
#define WEAPON_DUAL_WIELD 0
|
||||
#define WEAPON_LIGHT 1
|
||||
#define WEAPON_MEDIUM 2
|
||||
#define WEAPON_HEAVY 3
|
||||
//Gun trigger guards
|
||||
#define TRIGGER_GUARD_ALLOW_ALL -1
|
||||
#define TRIGGER_GUARD_NONE 0
|
||||
#define TRIGGER_GUARD_NORMAL 1
|
||||
|
||||
//Object/Item sharpness
|
||||
#define IS_BLUNT 0
|
||||
#define IS_SHARP 1
|
||||
#define IS_SHARP_ACCURATE 2
|
||||
|
||||
//His Grace.
|
||||
#define HIS_GRACE_SATIATED 0 //He hungers not. If bloodthirst is set to this, His Grace is asleep.
|
||||
#define HIS_GRACE_PECKISH 20 //Slightly hungry.
|
||||
#define HIS_GRACE_HUNGRY 60 //Getting closer. Increases damage up to a minimum of 20.
|
||||
#define HIS_GRACE_FAMISHED 100 //Dangerous. Increases damage up to a minimum of 25 and cannot be dropped.
|
||||
#define HIS_GRACE_STARVING 120 //Incredibly close to breaking loose. Increases damage up to a minimum of 30.
|
||||
#define HIS_GRACE_CONSUME_OWNER 140 //His Grace consumes His owner at this point and becomes aggressive.
|
||||
#define HIS_GRACE_FALL_ASLEEP 160 //If it reaches this point, He falls asleep and resets.
|
||||
|
||||
#define HIS_GRACE_FORCE_BONUS 4 //How much force is gained per kill.
|
||||
/*ALL DEFINES RELATED TO COMBAT GO HERE*/
|
||||
|
||||
//Damage and status effect defines
|
||||
|
||||
//Damage defines //TODO: merge these down to reduce on defines
|
||||
#define BRUTE "brute"
|
||||
#define BURN "fire"
|
||||
#define TOX "tox"
|
||||
#define OXY "oxy"
|
||||
#define CLONE "clone"
|
||||
#define STAMINA "stamina"
|
||||
#define BRAIN "brain"
|
||||
|
||||
//Citadel code
|
||||
#define AROUSAL "arousal"
|
||||
|
||||
//bitflag damage defines used for suicide_act
|
||||
#define BRUTELOSS 1
|
||||
#define FIRELOSS 2
|
||||
#define TOXLOSS 4
|
||||
#define OXYLOSS 8
|
||||
#define SHAME 16
|
||||
|
||||
//Citadel code
|
||||
#define AROUSAL 32
|
||||
|
||||
#define STUN "stun"
|
||||
#define KNOCKDOWN "knockdown"
|
||||
#define UNCONSCIOUS "unconscious"
|
||||
#define IRRADIATE "irradiate"
|
||||
#define STUTTER "stutter"
|
||||
#define SLUR "slur"
|
||||
#define EYE_BLUR "eye_blur"
|
||||
#define DROWSY "drowsy"
|
||||
#define JITTER "jitter"
|
||||
|
||||
//Bitflags defining which status effects could be or are inflicted on a mob
|
||||
#define CANSTUN 1
|
||||
#define CANKNOCKDOWN 2
|
||||
#define CANUNCONSCIOUS 4
|
||||
#define CANPUSH 8
|
||||
#define IGNORESLOWDOWN 16
|
||||
#define GOTTAGOFAST 32
|
||||
#define GOTTAGOREALLYFAST 64
|
||||
#define GODMODE 4096
|
||||
#define FAKEDEATH 8192 //Replaces stuff like changeling.changeling_fakedeath
|
||||
#define DISFIGURED 16384 //I'll probably move this elsewhere if I ever get wround to writing a bitflag mob-damage system
|
||||
#define XENO_HOST 32768 //Tracks whether we're gonna be a baby alien's mummy.
|
||||
|
||||
//Health Defines
|
||||
#define HEALTH_THRESHOLD_CRIT 0
|
||||
#define HEALTH_THRESHOLD_DEAD -100
|
||||
|
||||
//Actual combat defines
|
||||
|
||||
//click cooldowns, in tenths of a second, used for various combat actions
|
||||
#define CLICK_CD_MELEE 8
|
||||
#define CLICK_CD_RANGE 4
|
||||
#define CLICK_CD_RAPID 2
|
||||
#define CLICK_CD_CLICK_ABILITY 6
|
||||
#define CLICK_CD_BREAKOUT 100
|
||||
#define CLICK_CD_HANDCUFFED 10
|
||||
#define CLICK_CD_RESIST 20
|
||||
#define CLICK_CD_GRABBING 10
|
||||
|
||||
//Cuff resist speeds
|
||||
#define FAST_CUFFBREAK 1
|
||||
#define INSTANT_CUFFBREAK 2
|
||||
|
||||
//Grab levels
|
||||
#define GRAB_PASSIVE 0
|
||||
#define GRAB_AGGRESSIVE 1
|
||||
#define GRAB_NECK 2
|
||||
#define GRAB_KILL 3
|
||||
|
||||
//Attack types for checking shields/hit reactions
|
||||
#define MELEE_ATTACK 1
|
||||
#define UNARMED_ATTACK 2
|
||||
#define PROJECTILE_ATTACK 3
|
||||
#define THROWN_PROJECTILE_ATTACK 4
|
||||
#define LEAP_ATTACK 5
|
||||
|
||||
//attack visual effects
|
||||
#define ATTACK_EFFECT_PUNCH "punch"
|
||||
#define ATTACK_EFFECT_KICK "kick"
|
||||
#define ATTACK_EFFECT_SMASH "smash"
|
||||
#define ATTACK_EFFECT_CLAW "claw"
|
||||
#define ATTACK_EFFECT_DISARM "disarm"
|
||||
#define ATTACK_EFFECT_BITE "bite"
|
||||
#define ATTACK_EFFECT_MECHFIRE "mech_fire"
|
||||
#define ATTACK_EFFECT_MECHTOXIN "mech_toxin"
|
||||
#define ATTACK_EFFECT_BOOP "boop" //Honk
|
||||
|
||||
//intent defines
|
||||
#define INTENT_HELP "help"
|
||||
#define INTENT_GRAB "grab"
|
||||
#define INTENT_DISARM "disarm"
|
||||
#define INTENT_HARM "harm"
|
||||
//NOTE: INTENT_HOTKEY_* defines are not actual intents!
|
||||
//they are here to support hotkeys
|
||||
#define INTENT_HOTKEY_LEFT "left"
|
||||
#define INTENT_HOTKEY_RIGHT "right"
|
||||
|
||||
//the define for visible message range in combat
|
||||
#define COMBAT_MESSAGE_RANGE 3
|
||||
|
||||
//Combat object defines
|
||||
|
||||
//Embedded objects
|
||||
#define EMBEDDED_PAIN_CHANCE 15 //Chance for embedded objects to cause pain (damage user)
|
||||
#define EMBEDDED_ITEM_FALLOUT 5 //Chance for embedded object to fall out (causing pain but removing the object)
|
||||
#define EMBED_CHANCE 45 //Chance for an object to embed into somebody when thrown (if it's sharp)
|
||||
#define EMBEDDED_PAIN_MULTIPLIER 2 //Coefficient of multiplication for the damage the item does while embedded (this*item.w_class)
|
||||
#define EMBEDDED_FALL_PAIN_MULTIPLIER 5 //Coefficient of multiplication for the damage the item does when it falls out (this*item.w_class)
|
||||
#define EMBEDDED_IMPACT_PAIN_MULTIPLIER 4 //Coefficient of multiplication for the damage the item does when it first embeds (this*item.w_class)
|
||||
#define EMBED_THROWSPEED_THRESHOLD 4 //The minimum value of an item's throw_speed for it to embed (Unless it has embedded_ignore_throwspeed_threshold set to 1)
|
||||
#define EMBEDDED_UNSAFE_REMOVAL_PAIN_MULTIPLIER 8 //Coefficient of multiplication for the damage the item does when removed without a surgery (this*item.w_class)
|
||||
#define EMBEDDED_UNSAFE_REMOVAL_TIME 30 //A Time in ticks, total removal time = (this*item.w_class)
|
||||
|
||||
//Gun Stuff
|
||||
#define SAWN_INTACT 0
|
||||
#define SAWN_OFF 1
|
||||
//Gun weapon weight
|
||||
#define WEAPON_DUAL_WIELD 0
|
||||
#define WEAPON_LIGHT 1
|
||||
#define WEAPON_MEDIUM 2
|
||||
#define WEAPON_HEAVY 3
|
||||
//Gun trigger guards
|
||||
#define TRIGGER_GUARD_ALLOW_ALL -1
|
||||
#define TRIGGER_GUARD_NONE 0
|
||||
#define TRIGGER_GUARD_NORMAL 1
|
||||
|
||||
//Object/Item sharpness
|
||||
#define IS_BLUNT 0
|
||||
#define IS_SHARP 1
|
||||
#define IS_SHARP_ACCURATE 2
|
||||
|
||||
//His Grace.
|
||||
#define HIS_GRACE_SATIATED 0 //He hungers not. If bloodthirst is set to this, His Grace is asleep.
|
||||
#define HIS_GRACE_PECKISH 20 //Slightly hungry.
|
||||
#define HIS_GRACE_HUNGRY 60 //Getting closer. Increases damage up to a minimum of 20.
|
||||
#define HIS_GRACE_FAMISHED 100 //Dangerous. Increases damage up to a minimum of 25 and cannot be dropped.
|
||||
#define HIS_GRACE_STARVING 120 //Incredibly close to breaking loose. Increases damage up to a minimum of 30.
|
||||
#define HIS_GRACE_CONSUME_OWNER 140 //His Grace consumes His owner at this point and becomes aggressive.
|
||||
#define HIS_GRACE_FALL_ASLEEP 160 //If it reaches this point, He falls asleep and resets.
|
||||
|
||||
#define HIS_GRACE_FORCE_BONUS 4 //How much force is gained per kill.
|
||||
|
||||
#define EXPLODE_NONE 0 //Don't even ask me why we need this.
|
||||
#define EXPLODE_DEVASTATE 1
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// simple is_type and similar inline helpers
|
||||
|
||||
#define islist(L) (istype(L,/list))
|
||||
#define islist(L) (istype(L, /list))
|
||||
|
||||
#define in_range(source, user) (get_dist(source, user) <= 1)
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
@@ -167,10 +167,6 @@ Will print: "/mob/living/carbon/human/death" (you can optionally embed it in a s
|
||||
#define GAME_STATE_SETTING_UP 2
|
||||
#define GAME_STATE_PLAYING 3
|
||||
#define GAME_STATE_FINISHED 4
|
||||
//SOUND:
|
||||
#define SOUND_MINIMUM_PRESSURE 10
|
||||
#define FALLOFF_SOUNDS 1
|
||||
#define SURROUND_CAP 7
|
||||
|
||||
//FONTS:
|
||||
// Used by Paper and PhotoCopier (and PaperBin once a year).
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
#define CHANNEL_JUKEBOX 1021
|
||||
#define CHANNEL_JUSTICAR_ARK 1020
|
||||
#define CHANNEL_HEARTBEAT 1019 //sound channel for heartbeats
|
||||
#define CHANNEL_AMBIENCE 1018
|
||||
#define CHANNEL_BUZZ 1017
|
||||
#define CHANNEL_BICYCLE 1016
|
||||
|
||||
//Citadel code
|
||||
#define CHANNEL_PRED 1018
|
||||
@@ -12,5 +15,8 @@
|
||||
//THIS SHOULD ALWAYS BE THE LOWEST ONE!
|
||||
//KEEP IT UPDATED
|
||||
|
||||
#define CHANNEL_HIGHEST_AVAILABLE 1017
|
||||
#define CHANNEL_HIGHEST_AVAILABLE 1015
|
||||
|
||||
#define CHANNEL_HIGHEST_AVAILABLE 1017
|
||||
#define SOUND_MINIMUM_PRESSURE 10
|
||||
#define FALLOFF_SOUNDS 0.5
|
||||
|
||||
@@ -175,6 +175,9 @@ Actual Adjacent procs :
|
||||
for(var/obj/structure/window/W in src)
|
||||
if(!W.CanAStarPass(ID, adir))
|
||||
return 1
|
||||
for(var/obj/machinery/door/window/W in src)
|
||||
if(!W.CanAStarPass(ID, adir))
|
||||
return 1
|
||||
for(var/obj/O in T)
|
||||
if(!O.CanAStarPass(ID, rdir, caller))
|
||||
return 1
|
||||
|
||||
@@ -89,12 +89,25 @@
|
||||
return
|
||||
|
||||
//returns a new list with only atoms that are in typecache L
|
||||
//if reversed, return a new list with only atoms that aren't in typecache L
|
||||
/proc/typecache_filter_list(list/atoms, list/typecache, reversed)
|
||||
/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] != reversed) //This assumes typecache[A.type] is either null or TRUE. God help you if it's FALSE
|
||||
if (typecache[A.type])
|
||||
. += A
|
||||
|
||||
/proc/typecache_filter_list_reverse(list/atoms, list/typecache)
|
||||
. = list()
|
||||
for(var/thing in atoms)
|
||||
var/atom/A = thing
|
||||
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
|
||||
@@ -171,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
|
||||
|
||||
@@ -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.
|
||||
|
||||
+15
-19
@@ -968,32 +968,28 @@ 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(!HAS_SECONDARY_FLAG(src, FROZEN))
|
||||
name = "frozen [name]"
|
||||
add_atom_colour(list(FROZEN_RED_COLOR, FROZEN_GREEN_COLOR, FROZEN_BLUE_COLOR, rgb(0,0,0)), TEMPORARY_COLOUR_PRIORITY)
|
||||
alpha -= 25
|
||||
SET_SECONDARY_FLAG(src, FROZEN)
|
||||
|
||||
//Assumes already frozed
|
||||
/obj/proc/make_unfrozen()
|
||||
icon = initial(icon)
|
||||
name = replacetext(name, "frozen ", "")
|
||||
CLEAR_SECONDARY_FLAG(src, FROZEN)
|
||||
if(HAS_SECONDARY_FLAG(src, FROZEN))
|
||||
name = replacetext(name, "frozen ", "")
|
||||
remove_atom_colour(TEMPORARY_COLOUR_PRIORITY, list(FROZEN_RED_COLOR, FROZEN_GREEN_COLOR, FROZEN_BLUE_COLOR, rgb(0,0,0)))
|
||||
alpha += 25
|
||||
CLEAR_SECONDARY_FLAG(src, FROZEN)
|
||||
|
||||
#undef FROZEN_RED_COLOR
|
||||
#undef FROZEN_GREEN_COLOR
|
||||
#undef FROZEN_BLUE_COLOR
|
||||
|
||||
@@ -182,3 +182,41 @@ GLOBAL_LIST_INIT(sqrtTable, list(1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4,
|
||||
gaussian_next = R2 * working
|
||||
return (mean + stddev * R1)
|
||||
#undef ACCURACY
|
||||
|
||||
/proc/mouse_angle_from_client(client/client)
|
||||
var/list/mouse_control = params2list(client.mouseParams)
|
||||
if(mouse_control["screen-loc"])
|
||||
var/list/screen_loc_params = splittext(mouse_control["screen-loc"], ",")
|
||||
var/list/screen_loc_X = splittext(screen_loc_params[1],":")
|
||||
var/list/screen_loc_Y = splittext(screen_loc_params[2],":")
|
||||
var/x = (text2num(screen_loc_X[1]) * 32 + text2num(screen_loc_X[2]) - 32)
|
||||
var/y = (text2num(screen_loc_Y[1]) * 32 + text2num(screen_loc_Y[2]) - 32)
|
||||
var/screenview = (client.view * 2 + 1) * world.icon_size //Refer to http://www.byond.com/docs/ref/info.html#/client/var/view for mad maths
|
||||
var/ox = round(screenview/2) - client.pixel_x //"origin" x
|
||||
var/oy = round(screenview/2) - client.pixel_y //"origin" y
|
||||
var/angle = NORM_ROT(Atan2(y - oy, x - ox))
|
||||
return angle
|
||||
|
||||
/proc/get_turf_in_angle(angle, turf/starting, increments)
|
||||
var/pixel_x = 0
|
||||
var/pixel_y = 0
|
||||
for(var/i in 1 to increments)
|
||||
pixel_x += sin(angle)+16*sin(angle)*2
|
||||
pixel_y += cos(angle)+16*cos(angle)*2
|
||||
var/new_x = starting.x
|
||||
var/new_y = starting.y
|
||||
while(pixel_x > 16)
|
||||
pixel_x -= 32
|
||||
new_x++
|
||||
while(pixel_x < -16)
|
||||
pixel_x += 32
|
||||
new_x--
|
||||
while(pixel_y > 16)
|
||||
pixel_y -= 32
|
||||
new_y++
|
||||
while(pixel_y < -16)
|
||||
pixel_y += 32
|
||||
new_y--
|
||||
new_x = Clamp(new_x, 0, world.maxx)
|
||||
new_y = Clamp(new_y, 0, world.maxy)
|
||||
return locate(new_x, new_y, starting.z)
|
||||
|
||||
@@ -116,6 +116,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 +159,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)
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
//When we get into galloping mode, we stay there until both runs win less often than MIN_GALLOP consecutive times.
|
||||
#define MIN_GALLOP 7
|
||||
|
||||
//This is a global instance to allow much of this code to be reused. The interfaces are kept seperately
|
||||
//This is a global instance to allow much of this code to be reused. The interfaces are kept separately
|
||||
GLOBAL_DATUM_INIT(sortInstance, /datum/sortInstance, new())
|
||||
/datum/sortInstance
|
||||
//The array being sorted.
|
||||
|
||||
@@ -48,7 +48,7 @@ Location where the teleport begins, target that will teleport, distance to go, d
|
||||
Random error in tile placement x, error in tile placement y, and block offset.
|
||||
Block offset tells the proc how to place the box. Behind teleport location, relative to starting location, forward, etc.
|
||||
Negative values for offset are accepted, think of it in relation to North, -x is west, -y is south. Error defaults to positive.
|
||||
Turf and target are seperate in case you want to teleport some distance from a turf the target is not standing on or something.
|
||||
Turf and target are separate in case you want to teleport some distance from a turf the target is not standing on or something.
|
||||
*/
|
||||
|
||||
var/dirx = 0//Generic location finding variable.
|
||||
@@ -491,17 +491,26 @@ Turf and target are seperate in case you want to teleport some distance from a t
|
||||
var/y=arcsin(x/sqrt(1+x*x))
|
||||
return y
|
||||
|
||||
/atom/proc/GetAllContents()
|
||||
/atom/proc/GetAllContents(list/ignore_typecache)
|
||||
var/list/processing_list = list(src)
|
||||
var/list/assembled = list()
|
||||
if(ignore_typecache) //If there's a typecache, use it.
|
||||
while(processing_list.len)
|
||||
var/atom/A = processing_list[1]
|
||||
processing_list -= A
|
||||
if(ignore_typecache[A.type])
|
||||
continue
|
||||
processing_list |= (A.contents - assembled)
|
||||
assembled |= A
|
||||
|
||||
while(processing_list.len)
|
||||
var/atom/A = processing_list[1]
|
||||
processing_list -= A
|
||||
else //If there's none, only make this check once for performance.
|
||||
while(processing_list.len)
|
||||
var/atom/A = processing_list[1]
|
||||
processing_list -= A
|
||||
|
||||
processing_list |= (A.contents - assembled)
|
||||
processing_list |= (A.contents - assembled)
|
||||
|
||||
assembled |= A
|
||||
assembled |= A
|
||||
|
||||
return assembled
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ GLOBAL_LIST_EMPTY(tech_list) //list of all /datum/tech datums indexed by id.
|
||||
GLOBAL_LIST_EMPTY(surgeries_list) //list of all surgeries by name, associated with their path.
|
||||
GLOBAL_LIST_EMPTY(crafting_recipes) //list of all table craft recipes
|
||||
GLOBAL_LIST_EMPTY(rcd_list) //list of Rapid Construction Devices.
|
||||
GLOBAL_LIST_EMPTY(apcs_list) //list of all Area Power Controller machines, seperate from machines for powernet speeeeeeed.
|
||||
GLOBAL_LIST_EMPTY(apcs_list) //list of all Area Power Controller machines, separate from machines for powernet speeeeeeed.
|
||||
GLOBAL_LIST_EMPTY(tracked_implants) //list of all current implants that are tracked to work out what sort of trek everyone is on. Sadly not on lavaworld not implemented...
|
||||
GLOBAL_LIST_EMPTY(tracked_chem_implants) //list of implants the prisoner console can track and send inject commands too
|
||||
GLOBAL_LIST_EMPTY(poi_list) //list of points of interest for observe/follow
|
||||
|
||||
+20
-14
@@ -24,17 +24,6 @@
|
||||
active_mousedown_item.onMouseUp(object, location, params, mob)
|
||||
active_mousedown_item = null
|
||||
|
||||
/client/MouseDrag(src_object,atom/over_object,src_location,over_location,src_control,over_control,params)
|
||||
mouseParams = params
|
||||
mouseLocation = over_location
|
||||
mouseObject = over_object
|
||||
mouseControlObject = over_control
|
||||
if(selected_target[1] && over_object && over_object.IsAutoclickable())
|
||||
selected_target[1] = over_object
|
||||
selected_target[2] = params
|
||||
if(active_mousedown_item)
|
||||
active_mousedown_item.onMouseDrag(src_object, over_object, src_location, over_location, params, mob)
|
||||
|
||||
/mob/proc/CanMobAutoclick(object, location, params)
|
||||
|
||||
/mob/living/carbon/CanMobAutoclick(atom/object, location, params)
|
||||
@@ -63,9 +52,6 @@
|
||||
/obj/item/proc/onMouseUp(object, location, params, mob)
|
||||
return
|
||||
|
||||
/obj/item/proc/onMouseDrag(src_object, over_object, src_location, over_location, params, mob)
|
||||
return
|
||||
|
||||
/obj/item
|
||||
var/canMouseDown = FALSE
|
||||
|
||||
@@ -90,3 +76,23 @@
|
||||
mouseLocation = location
|
||||
mouseObject = object
|
||||
mouseControlObject = control
|
||||
if(mob && LAZYLEN(mob.mousemove_intercept_objects))
|
||||
for(var/obj/item/I in mob.mousemove_intercept_objects)
|
||||
I.onMouseMove(object, location, control, params)
|
||||
|
||||
/obj/item/proc/onMouseMove(object, location, control, params)
|
||||
return
|
||||
|
||||
/client/MouseDrag(src_object,atom/over_object,src_location,over_location,src_control,over_control,params)
|
||||
mouseParams = params
|
||||
mouseLocation = over_location
|
||||
mouseObject = over_object
|
||||
mouseControlObject = over_control
|
||||
if(selected_target[1] && over_object && over_object.IsAutoclickable())
|
||||
selected_target[1] = over_object
|
||||
selected_target[2] = params
|
||||
if(active_mousedown_item)
|
||||
active_mousedown_item.onMouseDrag(src_object, over_object, src_location, over_location, params, mob)
|
||||
|
||||
/obj/item/proc/onMouseDrag(src_object, over_object, src_location, over_location, params, mob)
|
||||
return
|
||||
|
||||
+17
-6
@@ -95,7 +95,7 @@
|
||||
if(!modifiers["catcher"] && A.IsObscured())
|
||||
return
|
||||
|
||||
if(istype(loc,/obj/mecha))
|
||||
if(istype(loc, /obj/mecha))
|
||||
var/obj/mecha/M = loc
|
||||
return M.click_action(A,src,params)
|
||||
|
||||
@@ -432,14 +432,26 @@
|
||||
|
||||
/obj/screen/click_catcher
|
||||
icon = 'icons/mob/screen_gen.dmi'
|
||||
icon_state = "click_catcher"
|
||||
icon_state = "flash"
|
||||
plane = CLICKCATCHER_PLANE
|
||||
mouse_opacity = 2
|
||||
screen_loc = "CENTER"
|
||||
|
||||
/obj/screen/click_catcher/New()
|
||||
..()
|
||||
transform = matrix(200, 0, 0, 0, 200, 0)
|
||||
/obj/screen/click_catcher/proc/UpdateGreed(view_size_x = 7, view_size_y = 7)
|
||||
var/icon/newicon = icon('icons/mob/screen_gen.dmi', "flash")
|
||||
if(view_size_x > 16 || view_size_y > 16)
|
||||
newicon.Scale((16 * 2 + 1) * world.icon_size,(16 * 2 + 1) * world.icon_size)
|
||||
icon = newicon
|
||||
var/tx = view_size_x/16
|
||||
var/ty = view_size_y/16
|
||||
var/matrix/M = new
|
||||
M.Scale(tx, ty)
|
||||
transform = M
|
||||
screen_loc = "CENTER-16,CENTER-16"
|
||||
else
|
||||
screen_loc = "CENTER-[view_size_x],CENTER-[view_size_y]"
|
||||
newicon.Scale((view_size_x * 2 + 1) * world.icon_size,(view_size_y * 2 + 1) * world.icon_size)
|
||||
icon = newicon
|
||||
|
||||
/obj/screen/click_catcher/Click(location, control, params)
|
||||
var/list/modifiers = params2list(params)
|
||||
@@ -453,7 +465,6 @@
|
||||
T.Click(location, control, params)
|
||||
. = 1
|
||||
|
||||
|
||||
/* MouseWheelOn */
|
||||
|
||||
/mob/proc/MouseWheelOn(atom/A, delta_x, delta_y, params)
|
||||
|
||||
+36
-16
@@ -56,8 +56,7 @@
|
||||
|
||||
var/obj/item/W = get_active_held_item()
|
||||
|
||||
// Cyborgs have no range-checking unless there is item use
|
||||
if(!W)
|
||||
if(!W && get_dist(src,A) <= remote_range)
|
||||
A.attack_robot(src)
|
||||
return
|
||||
|
||||
@@ -106,38 +105,59 @@
|
||||
/atom/proc/BorgCtrlShiftClick(mob/living/silicon/robot/user) //forward to human click if not overriden
|
||||
CtrlShiftClick(user)
|
||||
|
||||
/obj/machinery/door/airlock/BorgCtrlShiftClick() // Sets/Unsets Emergency Access Override Forwards to AI code.
|
||||
AICtrlShiftClick()
|
||||
/obj/machinery/door/airlock/BorgCtrlShiftClick(mob/living/silicon/robot/user) // Sets/Unsets Emergency Access Override Forwards to AI code.
|
||||
if(get_dist(src,user) <= user.remote_range)
|
||||
AICtrlShiftClick()
|
||||
else
|
||||
..()
|
||||
|
||||
|
||||
/atom/proc/BorgShiftClick(mob/living/silicon/robot/user) //forward to human click if not overriden
|
||||
ShiftClick(user)
|
||||
|
||||
/obj/machinery/door/airlock/BorgShiftClick() // Opens and closes doors! Forwards to AI code.
|
||||
AIShiftClick()
|
||||
/obj/machinery/door/airlock/BorgShiftClick(mob/living/silicon/robot/user) // Opens and closes doors! Forwards to AI code.
|
||||
if(get_dist(src,user) <= user.remote_range)
|
||||
AIShiftClick()
|
||||
else
|
||||
..()
|
||||
|
||||
|
||||
/atom/proc/BorgCtrlClick(mob/living/silicon/robot/user) //forward to human click if not overriden
|
||||
CtrlClick(user)
|
||||
|
||||
/obj/machinery/door/airlock/BorgCtrlClick() // Bolts doors. Forwards to AI code.
|
||||
AICtrlClick()
|
||||
/obj/machinery/door/airlock/BorgCtrlClick(mob/living/silicon/robot/user) // Bolts doors. Forwards to AI code.
|
||||
if(get_dist(src,user) <= user.remote_range)
|
||||
AICtrlClick()
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/machinery/power/apc/BorgCtrlClick() // turns off/on APCs. Forwards to AI code.
|
||||
AICtrlClick()
|
||||
/obj/machinery/power/apc/BorgCtrlClick(mob/living/silicon/robot/user) // turns off/on APCs. Forwards to AI code.
|
||||
if(get_dist(src,user) <= user.remote_range)
|
||||
AICtrlClick()
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/machinery/turretid/BorgCtrlClick() //turret control on/off. Forwards to AI code.
|
||||
AICtrlClick()
|
||||
/obj/machinery/turretid/BorgCtrlClick(mob/living/silicon/robot/user) //turret control on/off. Forwards to AI code.
|
||||
if(get_dist(src,user) <= user.remote_range)
|
||||
AICtrlClick()
|
||||
else
|
||||
..()
|
||||
|
||||
/atom/proc/BorgAltClick(mob/living/silicon/robot/user)
|
||||
AltClick(user)
|
||||
return
|
||||
|
||||
/obj/machinery/door/airlock/BorgAltClick() // Eletrifies doors. Forwards to AI code.
|
||||
AIAltClick()
|
||||
/obj/machinery/door/airlock/BorgAltClick(mob/living/silicon/robot/user) // Eletrifies doors. Forwards to AI code.
|
||||
if(get_dist(src,user) <= user.remote_range)
|
||||
AIAltClick()
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/machinery/turretid/BorgAltClick() //turret lethal on/off. Forwards to AI code.
|
||||
AIAltClick()
|
||||
/obj/machinery/turretid/BorgAltClick(mob/living/silicon/robot/user) //turret lethal on/off. Forwards to AI code.
|
||||
if(get_dist(src,user) <= user.remote_range)
|
||||
AIAltClick()
|
||||
else
|
||||
..()
|
||||
|
||||
/*
|
||||
As with AI, these are not used in click code,
|
||||
|
||||
@@ -109,17 +109,26 @@
|
||||
|
||||
|
||||
//Gas alerts
|
||||
/obj/screen/alert/oxy
|
||||
/obj/screen/alert/not_enough_oxy
|
||||
name = "Choking (No O2)"
|
||||
desc = "You're not getting enough oxygen. Find some good air before you pass out! \
|
||||
The box in your backpack has an oxygen tank and breath mask in it."
|
||||
icon_state = "oxy"
|
||||
desc = "You're not getting enough oxygen. Find some good air before you pass out! The box in your backpack has an oxygen tank and breath mask in it."
|
||||
icon_state = "not_enough_oxy"
|
||||
|
||||
/obj/screen/alert/too_much_oxy
|
||||
name = "Choking (O2)"
|
||||
desc = "There's too much oxygen in the air, and you're breathing it in! Find some good air before you pass out!"
|
||||
icon_state = "too_much_oxy"
|
||||
|
||||
/obj/screen/alert/not_enough_nitro
|
||||
name = "Choking (No N2)"
|
||||
desc = "You're not getting enough nitrogen. Find some good air before you pass out!"
|
||||
icon_state = "not_enough_nitro"
|
||||
|
||||
/obj/screen/alert/too_much_nitro
|
||||
name = "Choking (N2)"
|
||||
desc = "There's too much nitrogen in the air, and you're breathing it in! Find some good air before you pass out!"
|
||||
icon_state = "too_much_nitro"
|
||||
|
||||
/obj/screen/alert/not_enough_co2
|
||||
name = "Choking (No CO2)"
|
||||
desc = "You're not getting enough carbon dioxide. Find some good air before you pass out!"
|
||||
@@ -135,11 +144,10 @@ The box in your backpack has an oxygen tank and breath mask in it."
|
||||
desc = "You're not getting enough plasma. Find some good air before you pass out!"
|
||||
icon_state = "not_enough_tox"
|
||||
|
||||
/obj/screen/alert/tox_in_air
|
||||
/obj/screen/alert/too_much_tox
|
||||
name = "Choking (Plasma)"
|
||||
desc = "There's highly flammable, toxic plasma in the air and you're breathing it in. Find some fresh air. \
|
||||
The box in your backpack has an oxygen tank and gas mask in it."
|
||||
icon_state = "tox_in_air"
|
||||
desc = "There's highly flammable, toxic plasma in the air and you're breathing it in. Find some fresh air. The box in your backpack has an oxygen tank and gas mask in it."
|
||||
icon_state = "too_much_tox"
|
||||
//End gas alerts
|
||||
|
||||
|
||||
@@ -197,7 +205,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()
|
||||
|
||||
@@ -145,6 +145,7 @@
|
||||
return 0
|
||||
|
||||
screenmob.client.screen = list()
|
||||
screenmob.client.apply_clickcatcher()
|
||||
|
||||
var/display_hud_version = version
|
||||
if(!display_hud_version) //If 0 or blank, display the next hud version
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
icon_state = "act_equip"
|
||||
|
||||
/obj/screen/human/equip/Click()
|
||||
if(istype(usr.loc,/obj/mecha)) // stops inventory actions in a mech
|
||||
if(istype(usr.loc, /obj/mecha)) // stops inventory actions in a mech
|
||||
return 1
|
||||
var/mob/living/carbon/human/H = usr
|
||||
H.quick_equip()
|
||||
|
||||
@@ -110,7 +110,7 @@
|
||||
|
||||
if(usr.incapacitated())
|
||||
return 1
|
||||
if(istype(usr.loc,/obj/mecha)) // stops inventory actions in a mech
|
||||
if(istype(usr.loc, /obj/mecha)) // stops inventory actions in a mech
|
||||
return 1
|
||||
|
||||
if(hud && hud.mymob && slot_id)
|
||||
@@ -167,7 +167,7 @@
|
||||
return 1
|
||||
if(usr.incapacitated() || isobserver(usr))
|
||||
return 1
|
||||
if (istype(usr.loc,/obj/mecha)) // stops inventory actions in a mech
|
||||
if (istype(usr.loc, /obj/mecha)) // stops inventory actions in a mech
|
||||
return 1
|
||||
|
||||
if(hud.mymob.active_hand_index == held_index)
|
||||
@@ -281,7 +281,7 @@
|
||||
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
|
||||
|
||||
//Seperate so CO2 jetpacks are a little less cumbersome.
|
||||
//Separate so CO2 jetpacks are a little less cumbersome.
|
||||
if(!C.internal && istype(C.back, /obj/item/weapon/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
|
||||
@@ -350,7 +350,7 @@
|
||||
return 1
|
||||
if(usr.stat || usr.IsUnconscious() || usr.IsKnockdown() || usr.IsStun())
|
||||
return 1
|
||||
if (istype(usr.loc,/obj/mecha)) // stops inventory actions in a mech
|
||||
if (istype(usr.loc, /obj/mecha)) // stops inventory actions in a mech
|
||||
return 1
|
||||
if(master)
|
||||
var/obj/item/I = usr.get_active_held_item()
|
||||
|
||||
@@ -100,7 +100,8 @@
|
||||
"<span class='userdanger'>[name] bites [ML]!</span>")
|
||||
if(armor >= 2)
|
||||
return
|
||||
for(var/datum/disease/D in viruses)
|
||||
for(var/thing in viruses)
|
||||
var/datum/disease/D = thing
|
||||
ML.ForceContractDisease(D)
|
||||
else
|
||||
ML.visible_message("<span class='danger'>[src] has attempted to bite [ML]!</span>")
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
return
|
||||
new /obj/effect/temp_visual/telekinesis(loc)
|
||||
user.UnarmedAttack(src,0) // attack_hand, attack_paw, etc
|
||||
add_hiddenprint(user)
|
||||
return
|
||||
|
||||
/obj/attack_tk(mob/user)
|
||||
@@ -34,6 +35,7 @@
|
||||
O.tk_user = user
|
||||
if(O.focus_object(src))
|
||||
user.put_in_active_hand(O)
|
||||
add_hiddenprint(user)
|
||||
|
||||
/mob/attack_tk(mob/user)
|
||||
return
|
||||
|
||||
@@ -53,6 +53,7 @@ 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)
|
||||
|
||||
+129
-31
@@ -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,45 +179,93 @@
|
||||
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()
|
||||
/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)
|
||||
src << "<span class='warning'>You need to wait [round((mb_cd_timer - world.time)/(20))] seconds before you can do that again!</span>"
|
||||
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)
|
||||
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
|
||||
var/datum/reagents/fluid_source = null
|
||||
var/into_container = 0
|
||||
var/arms = get_num_arms()
|
||||
var/free_hands = arms
|
||||
var/free_hands = get_num_arms() //arms was only used to know if we had ANY at all
|
||||
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>"
|
||||
if(stat==2)
|
||||
to_chat(src, "<span class='warning'>You can't do that while dead!</span>")
|
||||
return
|
||||
if(stat)
|
||||
src << "<span class='warning'>You must be conscious to do that!</span>"
|
||||
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/genital/G in internal_organs)
|
||||
if(G.can_masturbate_with) //All capable genitals will orgasm with this
|
||||
var/unable_to_come = FALSE
|
||||
switch(G.type)
|
||||
if(/obj/item/organ/genital/penis)
|
||||
var/obj/item/organ/genital/penis/P = G
|
||||
if(!P.linked_balls)
|
||||
unable_to_come = TRUE
|
||||
else
|
||||
fluid_source = P.linked_balls.reagents
|
||||
|
||||
|
||||
if(/obj/item/organ/genital/vagina)
|
||||
var/obj/item/organ/genital/vagina/V = G
|
||||
if(!V.linked_womb)
|
||||
unable_to_come = TRUE
|
||||
else
|
||||
fluid_source = V.linked_womb.reagents
|
||||
else //Weird, undefined genitalia behaviour
|
||||
unable_to_come = TRUE
|
||||
|
||||
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
|
||||
if(fluid_source)
|
||||
total_cum = fluid_source.total_volume
|
||||
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_cum > 5)
|
||||
fluid_source.reaction(src.loc, TOUCH, 1, 0)
|
||||
fluid_source.clear_reagents()
|
||||
fluid_source = null //cleanup so this can be used for the next genitalia
|
||||
|
||||
src.visible_message("<span class='danger'>[src] orgasms, cumming[istype(src.loc, /turf/open/floor) ? " onto [src.loc]" : ""]!</span>", \
|
||||
"<span class='green'>You're forced to cum[istype(src.loc, /turf/open/floor) ? " onto [src.loc]" : ""] with your [G].</span>", \
|
||||
"<span class='green'>Your [G] have been forced to climax.</span>")
|
||||
finished = 1
|
||||
if(finished)
|
||||
setArousalLoss(min_arousal)
|
||||
return //Do not proceed to masturbating if all genitals have been forced to orgasm.
|
||||
if(stat==1) //Sleeping people can be forced chemically or with electrical stimulants, for example.
|
||||
to_chat(src, "<span class='warning'>You must be conscious to do that!</span>")
|
||||
return
|
||||
if(restrained())
|
||||
to_chat(src, "<span class='warning'>You can't do that while restrained!</span>")
|
||||
return
|
||||
if(getArousalLoss() < 33)//flat number instead of percentage
|
||||
src << "<span class='warning'>You aren't aroused enough for that!</span>"
|
||||
to_chat(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>"
|
||||
to_chat(src, "<span class='warning'>You need to undress, first!</span>")
|
||||
return
|
||||
if(!arms)
|
||||
src << "<span class='warning'>You need at least one arm.</span>"
|
||||
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)
|
||||
src << "<span class='warning'>You need at least one free hand.</span>"
|
||||
to_chat(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
|
||||
@@ -240,12 +288,12 @@
|
||||
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>"
|
||||
to_chat(src, "<span class='warning'>You need a pair of testicles to do this.</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>", \
|
||||
src.visible_message("<span class='danger'>[src] starts [pick("jerking off","stroking")] their [SG.name] 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))
|
||||
@@ -254,16 +302,71 @@
|
||||
"<span class='green'>You cum into [SC].</span>", \
|
||||
"<span class='green'>You have relieved yourself.</span>")
|
||||
finished = 1
|
||||
|
||||
else //Not in a container
|
||||
if(src.pulling)
|
||||
if(iscarbon(src.pulling))
|
||||
var/mob/living/carbon/C = src.pulling
|
||||
if(!C.is_groin_exposed())
|
||||
to_chat(src, "<span class='warning'>You must undress someone to climax inside them.</span>")
|
||||
return
|
||||
if(isliving(src.pulling)) //Gotta be alive to fuck it, don't wanna have to code fucking objects that ain't containers...
|
||||
var/mob/living/partner = src.pulling
|
||||
src.visible_message("[src] is about to climax inside [partner]!", \
|
||||
"You're about to climax inside [partner]!", \
|
||||
"<span class='danger'>You're preparing to climax inside someone!</span>")
|
||||
switch(grab_state)
|
||||
if(GRAB_PASSIVE)
|
||||
if(do_after(src, mb_time, target = src) && in_range(src, partner))
|
||||
var/spillage = 0.5 //Leaks a bit on passive grab
|
||||
var/did_spill = FALSE
|
||||
fluid_source.trans_to(partner, total_cum*(1-spillage))
|
||||
total_cum = total_cum*spillage
|
||||
if(total_cum > 5)
|
||||
fluid_source.reaction(partner.loc, TOUCH, 1, 0)
|
||||
did_spill = TRUE
|
||||
fluid_source.clear_reagents()
|
||||
|
||||
src.visible_message("<span class='danger'>[src] ejaculates inside [partner][did_spill ? ", overflowing and spilling":""]!</span>", \
|
||||
"<span class='green'>You ejaculate inside [partner][did_spill ? ", spilling out of them":""].</span>", \
|
||||
"<span class='green'>You have climaxed inside someone[did_spill ? ", spilling out of them":""].</span>")
|
||||
finished = 1
|
||||
else //Aggressive or higher
|
||||
if(do_after(src, mb_time, target = src) && in_range(src, partner))
|
||||
var/spillage = 0.0 //Leakproofing seals
|
||||
fluid_source.trans_to(partner, total_cum*(1-spillage))
|
||||
total_cum = total_cum*spillage
|
||||
if(total_cum > 5)
|
||||
fluid_source.reaction(partner.loc, TOUCH, 1, 0)
|
||||
fluid_source.clear_reagents()
|
||||
|
||||
src.visible_message("<span class='danger'>[src] ejaculates inside [partner], spilling nothing!</span>", \
|
||||
"<span class='green'>You ejaculate inside [partner], spilling nothing.</span>", \
|
||||
"<span class='green'>You have climaxed inside someone, spilling nothing.</span>")
|
||||
finished = 1
|
||||
//Don't care, not coding you fucking a unanchored girder
|
||||
else //No pulling, or pulling non-living things
|
||||
src.visible_message("<span class='danger'>[src] starts [pick("jerking off","stroking")] their [SG].</span>", \
|
||||
"<span class='green'>You start masturbating.</span>", \
|
||||
"<span class='green'>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(/obj/item/organ/genital/vagina)
|
||||
var/obj/item/organ/genital/vagina/V = SG
|
||||
if(!V.linked_womb)
|
||||
src << "<span class='warning'>No womb!</span>"
|
||||
to_chat(src, "<span class='warning'>You need a womb to do this.</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>", \
|
||||
src.visible_message("<span class='danger'>[src] starts fingering their [SG.name] 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))
|
||||
@@ -272,7 +375,7 @@
|
||||
"<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>", \
|
||||
@@ -297,10 +400,5 @@
|
||||
setArousalLoss(min_arousal)
|
||||
|
||||
else
|
||||
src << "<span class='warning'>You have no genitals!</span>"
|
||||
to_chat(src, "<span class='warning'>You have no genitals!</span>")
|
||||
return
|
||||
|
||||
/mob/living/carbon/proc/force_orgasm(intensity)
|
||||
if(canbearoused && has_dna() && (has_penis() || has_vagina()))
|
||||
return 1
|
||||
return 0
|
||||
|
||||
@@ -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,17 @@
|
||||
..()
|
||||
|
||||
/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
|
||||
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
|
||||
to_chat(M, "<span class='love'>You're having a hard time thinkin about things other than sex!</span>")
|
||||
if(M.min_arousal < M.max_arousal)
|
||||
M.min_arousal += 1
|
||||
to_chat(M, "<span class='love'>You feel your libido permanently increasing.</span>")
|
||||
M.adjustArousalLoss(2)
|
||||
..()
|
||||
|
||||
@@ -193,8 +197,10 @@
|
||||
if(prob(33))
|
||||
if(M.min_arousal > 0)
|
||||
M.min_arousal -= 1
|
||||
if(M.max_arousal > 75)
|
||||
to_chat(M, "<span class='notice'>You feel your libido returning to more normal levels.</span>")
|
||||
if(M.min_arousal > 50)
|
||||
M.min_arousal -= 1
|
||||
to_chat(M, "<span class='notice'>You feel like your overactive libido is calming down.</span>")
|
||||
M.adjustArousalLoss(-2)
|
||||
..()
|
||||
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 704 B |
@@ -1,5 +1,5 @@
|
||||
/obj/item/organ/genital/breasts
|
||||
name = "breasts"
|
||||
name = "Breasts"
|
||||
desc = "Female milk producing organs."
|
||||
icon_state = "breasts"
|
||||
icon = 'code/citadel/icons/breasts.dmi'
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -243,8 +243,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,5 +1,5 @@
|
||||
/obj/item/organ/genital/penis
|
||||
name = "penis"
|
||||
name = "Penis"
|
||||
desc = "A male reproductive organ."
|
||||
icon_state = "penis"
|
||||
icon = 'code/citadel/icons/penis.dmi'
|
||||
@@ -35,7 +35,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)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/obj/item/organ/genital/testicles
|
||||
name = "testicles"
|
||||
name = "Testicles"
|
||||
desc = "A male reproductive organ."
|
||||
icon_state = "testicles"
|
||||
icon = 'code/citadel/icons/penis.dmi'
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/obj/item/organ/genital/vagina
|
||||
name = "vagina"
|
||||
name = "Vagina"
|
||||
desc = "A female reproductive organ."
|
||||
icon = 'code/citadel/icons/vagina.dmi'
|
||||
icon_state = "vagina"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/obj/item/organ/genital/womb
|
||||
name = "womb"
|
||||
name = "Womb"
|
||||
desc = "A female reproductive organ."
|
||||
icon = 'code/citadel/icons/vagina.dmi'
|
||||
icon_state = "womb"
|
||||
@@ -10,7 +10,7 @@
|
||||
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)
|
||||
|
||||
@@ -124,7 +124,8 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
|
||||
var/FireHim = FALSE
|
||||
if(istype(BadBoy))
|
||||
msg = null
|
||||
switch(++BadBoy.failure_strikes)
|
||||
LAZYINITLIST(BadBoy.failure_strikes)
|
||||
switch(++BadBoy.failure_strikes[BadBoy.type])
|
||||
if(2)
|
||||
msg = "The [BadBoy.name] subsystem was the last to fire for 2 controller restarts. It will be recovered now and disabled if it happens again."
|
||||
FireHim = TRUE
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
|
||||
var/runlevels = RUNLEVELS_DEFAULT //points of the game at which the SS can fire
|
||||
|
||||
var/static/failure_strikes = 0 //How many times we suspect this subsystem has crashed the MC, 3 strikes and you're out!
|
||||
var/static/list/failure_strikes //How many times we suspect a subsystem type has crashed the MC, 3 strikes and you're out!
|
||||
|
||||
//Do not override
|
||||
/datum/controller/subsystem/New()
|
||||
|
||||
@@ -250,7 +250,7 @@ SUBSYSTEM_DEF(blackbox)
|
||||
return 0
|
||||
return value
|
||||
|
||||
/datum/feedback_variable/proc/get_variable()
|
||||
/datum/feedback_variable/proc/get_variable()
|
||||
return variable
|
||||
|
||||
/datum/feedback_variable/proc/set_details(text)
|
||||
@@ -259,14 +259,13 @@ SUBSYSTEM_DEF(blackbox)
|
||||
|
||||
/datum/feedback_variable/proc/add_details(text)
|
||||
if (istext(text))
|
||||
text = replacetext(text, " ", "_")
|
||||
if (!details)
|
||||
details = text
|
||||
details = "\"[text]\""
|
||||
else
|
||||
details += " [text]"
|
||||
details += " | \"[text]\""
|
||||
|
||||
/datum/feedback_variable/proc/get_details()
|
||||
/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,11 +1,8 @@
|
||||
SUBSYSTEM_DEF(disease)
|
||||
name = "Disease"
|
||||
flags = SS_KEEP_TIMING|SS_NO_INIT
|
||||
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
|
||||
|
||||
var/list/currentrun = list()
|
||||
var/list/processing = list()
|
||||
flags = SS_NO_FIRE
|
||||
|
||||
var/list/active_diseases = list() //List of Active disease in all mobs; purely for quick referencing.
|
||||
var/list/diseases
|
||||
var/list/archive_diseases = list()
|
||||
|
||||
@@ -15,27 +12,5 @@ SUBSYSTEM_DEF(disease)
|
||||
if(!diseases)
|
||||
diseases = subtypesof(/datum/disease)
|
||||
|
||||
/datum/controller/subsystem/disease/Recover()
|
||||
currentrun = SSdisease.currentrun
|
||||
processing = SSdisease.processing
|
||||
diseases = SSdisease.diseases
|
||||
archive_diseases = SSdisease.archive_diseases
|
||||
|
||||
/datum/controller/subsystem/disease/stat_entry(msg)
|
||||
..("P:[processing.len]")
|
||||
|
||||
/datum/controller/subsystem/disease/fire(resumed = 0)
|
||||
if(!resumed)
|
||||
src.currentrun = processing.Copy()
|
||||
//cache for sanic speed (lists are references anyways)
|
||||
var/list/currentrun = src.currentrun
|
||||
|
||||
while(currentrun.len)
|
||||
var/datum/thing = currentrun[currentrun.len]
|
||||
currentrun.len--
|
||||
if(thing)
|
||||
thing.process()
|
||||
else
|
||||
processing.Remove(thing)
|
||||
if (MC_TICK_CHECK)
|
||||
return
|
||||
..("P:[active_diseases.len]")
|
||||
@@ -18,7 +18,7 @@ SUBSYSTEM_DEF(garbage)
|
||||
// refID's are associated with the time at which they time out and need to be manually del()
|
||||
// we do this so we aren't constantly locating them and preventing them from being gc'd
|
||||
|
||||
var/list/tobequeued = list() //We store the references of things to be added to the queue seperately so we can spread out GC overhead over a few ticks
|
||||
var/list/tobequeued = list() //We store the references of things to be added to the queue separately so we can spread out GC overhead over a few ticks
|
||||
|
||||
var/list/didntgc = list() // list of all types that have failed to GC associated with the number of times that's happened.
|
||||
// the types are stored as strings
|
||||
@@ -144,7 +144,7 @@ SUBSYSTEM_DEF(garbage)
|
||||
|
||||
queue[refid] = gctime
|
||||
|
||||
//this is purely to seperate things profile wise.
|
||||
//this is purely to separate things profile wise.
|
||||
/datum/controller/subsystem/garbage/proc/HardDelete(datum/A)
|
||||
var/time = world.timeofday
|
||||
var/tick = world.tick_usage
|
||||
@@ -234,27 +234,7 @@ SUBSYSTEM_DEF(garbage)
|
||||
else if(D.gc_destroyed == GC_CURRENTLY_BEING_QDELETED)
|
||||
CRASH("[D.type] destroy proc was called multiple times, likely due to a qdel loop in the Destroy logic")
|
||||
|
||||
// Default implementation of clean-up code.
|
||||
// This should be overridden to remove all references pointing to the object being destroyed.
|
||||
// Return the appropriate QDEL_HINT; in most cases this is QDEL_HINT_QUEUE.
|
||||
// TODO: Move this and all datum var definitions into code/datums/datum.dm
|
||||
/datum/proc/Destroy(force=FALSE)
|
||||
tag = null
|
||||
var/list/timers = active_timers
|
||||
active_timers = null
|
||||
for(var/thing in timers)
|
||||
var/datum/timedevent/timer = thing
|
||||
if (timer.spent)
|
||||
continue
|
||||
qdel(timer)
|
||||
QDEL_LIST(datum_components)
|
||||
return QDEL_HINT_QUEUE
|
||||
|
||||
/datum/var/gc_destroyed //Time when this object was destroyed.
|
||||
|
||||
#ifdef TESTING
|
||||
/datum/var/running_find_references
|
||||
/datum/var/last_find_references = 0
|
||||
|
||||
/datum/verb/find_refs()
|
||||
set category = "Debug"
|
||||
@@ -303,13 +283,12 @@ SUBSYSTEM_DEF(garbage)
|
||||
|
||||
/client/verb/purge_all_destroyed_objects()
|
||||
set category = "Debug"
|
||||
if(SSgarbage)
|
||||
while(SSgarbage.queue.len)
|
||||
var/datum/o = locate(SSgarbage.queue[1])
|
||||
if(istype(o) && o.gc_destroyed)
|
||||
del(o)
|
||||
SSgarbage.totaldels++
|
||||
SSgarbage.queue.Cut(1, 2)
|
||||
while(SSgarbage.queue.len)
|
||||
var/datum/o = locate(SSgarbage.queue[1])
|
||||
if(istype(o) && o.gc_destroyed)
|
||||
del(o)
|
||||
SSgarbage.totaldels++
|
||||
SSgarbage.queue.Cut(1, 2)
|
||||
|
||||
/datum/verb/qdel_then_find_references()
|
||||
set category = "Debug"
|
||||
|
||||
@@ -217,10 +217,9 @@ SUBSYSTEM_DEF(job)
|
||||
Debug("Running DO")
|
||||
|
||||
//Holder for Triumvirate is stored in the SSticker, this just processes it
|
||||
if(SSticker)
|
||||
if(SSticker.triai)
|
||||
for(var/datum/job/ai/A in occupations)
|
||||
if(SSticker.triai)
|
||||
A.spawn_positions = 3
|
||||
A.spawn_positions = 3
|
||||
|
||||
//Get the players who are ready
|
||||
for(var/mob/dead/new_player/player in GLOB.player_list)
|
||||
|
||||
@@ -14,7 +14,7 @@ SUBSYSTEM_DEF(pai)
|
||||
var/obj/item/device/paicard/card = locate(href_list["device"]) in pai_card_list
|
||||
if(card.pai)
|
||||
return
|
||||
if(istype(card,/obj/item/device/paicard) && istype(candidate,/datum/paiCandidate))
|
||||
if(istype(card, /obj/item/device/paicard) && istype(candidate, /datum/paiCandidate))
|
||||
if(check_ready(candidate) != candidate)
|
||||
return FALSE
|
||||
var/mob/living/silicon/pai/pai = new(card)
|
||||
|
||||
@@ -37,7 +37,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/))
|
||||
if(isfloorturf(T) && !istype(T, /turf/open/floor/plating/))
|
||||
free_satchels += new /obj/item/weapon/storage/backpack/satchel/flat/secret(T)
|
||||
if(!isemptylist(free_satchels) && ((free_satchels.len + placed_satchels) >= (50 - expanded_old_satchels.len) * 0.1)) //up to six tiles, more than enough to kill anything that moves
|
||||
break
|
||||
@@ -63,7 +63,7 @@ SUBSYSTEM_DEF(persistence)
|
||||
F.x = text2num(chosen_satchel[1])
|
||||
F.y = text2num(chosen_satchel[2])
|
||||
F.z = ZLEVEL_STATION
|
||||
if(isfloorturf(F.loc) && !istype(F.loc,/turf/open/floor/plating/))
|
||||
if(isfloorturf(F.loc) && !istype(F.loc, /turf/open/floor/plating/))
|
||||
F.hide(1)
|
||||
new path(F)
|
||||
return 1
|
||||
|
||||
@@ -40,9 +40,15 @@ SUBSYSTEM_DEF(server_maint)
|
||||
|
||||
/datum/controller/subsystem/server_maint/Shutdown()
|
||||
kick_clients_in_lobby("<span class='boldannounce'>The round came to an end with you in the lobby.</span>", TRUE) //second parameter ensures only afk clients are kicked
|
||||
var/server = config.server
|
||||
for(var/thing in GLOB.clients)
|
||||
if(!thing)
|
||||
continue
|
||||
var/client/C = thing
|
||||
if(C && config.server) //if you set a server location in config.txt, it sends you there instead of trying to reconnect to the same world address. -- NeoFite
|
||||
C << link("byond://[config.server]")
|
||||
var/datum/chatOutput/co = C.chatOutput
|
||||
if(co)
|
||||
co.ehjax_send(data = "roundrestart")
|
||||
if(server) //if you set a server location in config.txt, it sends you there instead of trying to reconnect to the same world address. -- NeoFite
|
||||
C << link("byond://[server]")
|
||||
|
||||
#undef PING_BUFFER_TIME
|
||||
|
||||
@@ -34,8 +34,8 @@ SUBSYSTEM_DEF(shuttle)
|
||||
var/obj/docking_port/mobile/supply/supply
|
||||
var/ordernum = 1 //order number given to next order
|
||||
var/points = 5000 //number of trade-points we have
|
||||
var/centcom_message = "" //Remarks from Centcom on how well you checked the last order.
|
||||
var/list/discoveredPlants = list() //Typepaths for unusual plants we've already sent CentComm, associated with their potencies
|
||||
var/centcom_message = "" //Remarks from CentCom on how well you checked the last order.
|
||||
var/list/discoveredPlants = list() //Typepaths for unusual plants we've already sent CentCom, associated with their potencies
|
||||
|
||||
var/list/supply_packs = list()
|
||||
var/list/shoppinglist = list()
|
||||
@@ -185,7 +185,7 @@ SUBSYSTEM_DEF(shuttle)
|
||||
|
||||
switch(emergency.mode)
|
||||
if(SHUTTLE_RECALL)
|
||||
to_chat(user, "The emergency shuttle may not be called while returning to Centcom.")
|
||||
to_chat(user, "The emergency shuttle may not be called while returning to CentCom.")
|
||||
return
|
||||
if(SHUTTLE_CALL)
|
||||
to_chat(user, "The emergency shuttle is already on its way.")
|
||||
@@ -200,7 +200,7 @@ SUBSYSTEM_DEF(shuttle)
|
||||
to_chat(user, "The emergency shuttle is moving away to a safe distance.")
|
||||
return
|
||||
if(SHUTTLE_STRANDED)
|
||||
to_chat(user, "The emergency shuttle has been disabled by Centcom.")
|
||||
to_chat(user, "The emergency shuttle has been disabled by CentCom.")
|
||||
return
|
||||
|
||||
call_reason = trim(html_encode(call_reason))
|
||||
@@ -543,7 +543,7 @@ SUBSYSTEM_DEF(shuttle)
|
||||
|
||||
/datum/controller/subsystem/shuttle/proc/is_in_shuttle_bounds(atom/A)
|
||||
var/area/current = get_area(A)
|
||||
if(istype(current, /area/shuttle) && !istype(current,/area/shuttle/transit))
|
||||
if(istype(current, /area/shuttle) && !istype(current, /area/shuttle/transit))
|
||||
return TRUE
|
||||
for(var/obj/docking_port/mobile/M in mobile)
|
||||
if(M.is_in_shuttle_bounds(A))
|
||||
|
||||
@@ -103,7 +103,7 @@ SUBSYSTEM_DEF(throwing)
|
||||
finalize()
|
||||
return
|
||||
|
||||
/datum/thrownthing/proc/finalize(hit = FALSE)
|
||||
/datum/thrownthing/proc/finalize(hit = FALSE, target=null)
|
||||
set waitfor = 0
|
||||
SSthrowing.processing -= thrownthing
|
||||
//done throwing, either because it hit something or it finished moving
|
||||
@@ -120,13 +120,15 @@ SUBSYSTEM_DEF(throwing)
|
||||
thrownthing.newtonian_move(init_dir)
|
||||
else
|
||||
thrownthing.newtonian_move(init_dir)
|
||||
|
||||
if(target)
|
||||
thrownthing.throw_impact(target, src)
|
||||
|
||||
if (callback)
|
||||
callback.Invoke()
|
||||
|
||||
/datum/thrownthing/proc/hit_atom(atom/A)
|
||||
thrownthing.throw_impact(A, src)
|
||||
thrownthing.newtonian_move(init_dir)
|
||||
finalize(TRUE)
|
||||
finalize(hit=TRUE, target=A)
|
||||
|
||||
/datum/thrownthing/proc/hitcheck()
|
||||
for (var/thing in get_turf(thrownthing))
|
||||
@@ -134,6 +136,5 @@ SUBSYSTEM_DEF(throwing)
|
||||
if (AM == thrownthing)
|
||||
continue
|
||||
if (AM.density && !(AM.pass_flags & LETPASSTHROW) && !(AM.flags & ON_BORDER))
|
||||
thrownthing.throwing = null
|
||||
thrownthing.throw_impact(AM, src)
|
||||
finalize(hit=TRUE, target=AM)
|
||||
return TRUE
|
||||
|
||||
@@ -479,7 +479,7 @@ SUBSYSTEM_DEF(ticker)
|
||||
var/list/area/shuttle_areas
|
||||
if(SSshuttle && SSshuttle.emergency)
|
||||
shuttle_areas = SSshuttle.emergency.shuttle_areas
|
||||
if(!Player.onCentcom() && !Player.onSyndieBase())
|
||||
if(!Player.onCentCom() && !Player.onSyndieBase())
|
||||
to_chat(Player, "<font color='blue'><b>You managed to survive, but were marooned on [station_name()]...</b></FONT>")
|
||||
else
|
||||
num_escapees++
|
||||
|
||||
@@ -210,7 +210,6 @@ SUBSYSTEM_DEF(timer)
|
||||
timer_id_dict |= SStimer.timer_id_dict
|
||||
bucket_list |= SStimer.bucket_list
|
||||
|
||||
/datum/var/list/active_timers
|
||||
/datum/timedevent
|
||||
var/id
|
||||
var/datum/callback/callBack
|
||||
|
||||
+19
-4
@@ -10,12 +10,13 @@
|
||||
var/check_flags = 0
|
||||
var/processing = FALSE
|
||||
var/obj/screen/movable/action_button/button = null
|
||||
var/button_icon = 'icons/mob/actions.dmi'
|
||||
var/background_icon_state = ACTION_BUTTON_DEFAULT_BACKGROUND
|
||||
var/buttontooltipstyle = ""
|
||||
|
||||
var/icon_icon = 'icons/mob/actions.dmi'
|
||||
var/button_icon_state = "default"
|
||||
var/button_icon = 'icons/mob/actions/backgrounds.dmi' //This is the file for the BACKGROUND icon
|
||||
var/background_icon_state = ACTION_BUTTON_DEFAULT_BACKGROUND //And this is the state for the background icon
|
||||
|
||||
var/icon_icon = 'icons/mob/actions.dmi' //This is the file for the ACTION icon
|
||||
var/button_icon_state = "default" //And this is the state for the action icon
|
||||
var/mob/owner
|
||||
|
||||
/datum/action/New(Target)
|
||||
@@ -169,6 +170,10 @@
|
||||
/datum/action/item_action/toggle_firemode
|
||||
name = "Toggle Firemode"
|
||||
|
||||
/datum/action/item_action/rcl
|
||||
name = "Change Cable Color"
|
||||
button_icon_state = "rcl_rainbow"
|
||||
|
||||
/datum/action/item_action/startchainsaw
|
||||
name = "Pull The Starting Cord"
|
||||
|
||||
@@ -221,6 +226,7 @@
|
||||
/datum/action/item_action/toggle_unfriendly_fire
|
||||
name = "Toggle Friendly Fire \[ON\]"
|
||||
desc = "Toggles if the club's blasts cause friendly fire."
|
||||
icon_icon = 'icons/mob/actions/actions_items.dmi'
|
||||
button_icon_state = "vortex_ff_on"
|
||||
|
||||
/datum/action/item_action/toggle_unfriendly_fire/Trigger()
|
||||
@@ -254,6 +260,7 @@
|
||||
/datum/action/item_action/vortex_recall
|
||||
name = "Vortex Recall"
|
||||
desc = "Recall yourself, and anyone nearby, to an attuned hierophant beacon at any time.<br>If the beacon is still attached, will detach it."
|
||||
icon_icon = 'icons/mob/actions/actions_items.dmi'
|
||||
button_icon_state = "vortex_recall"
|
||||
|
||||
/datum/action/item_action/vortex_recall/IsAvailable()
|
||||
@@ -264,6 +271,7 @@
|
||||
return ..()
|
||||
|
||||
/datum/action/item_action/clock
|
||||
icon_icon = 'icons/mob/actions/actions_clockcult.dmi'
|
||||
background_icon_state = "bg_clock"
|
||||
buttontooltipstyle = "clockcult"
|
||||
|
||||
@@ -363,6 +371,7 @@
|
||||
|
||||
/datum/action/item_action/toggle_research_scanner
|
||||
name = "Toggle Research Scanner"
|
||||
icon_icon = 'icons/mob/actions/actions_items.dmi'
|
||||
button_icon_state = "scan_mode"
|
||||
var/active = FALSE
|
||||
|
||||
@@ -399,6 +408,7 @@
|
||||
/datum/action/item_action/ninjajaunt
|
||||
name = "Phase Jaunt (10E)"
|
||||
desc = "Utilizes the internal VOID-shift device to rapidly transit in direction facing."
|
||||
icon_icon = 'icons/mob/actions/actions_items.dmi'
|
||||
button_icon_state = "ninja_phase"
|
||||
|
||||
/datum/action/item_action/ninjasmoke
|
||||
@@ -407,6 +417,7 @@
|
||||
button_icon_state = "smoke"
|
||||
|
||||
/datum/action/item_action/ninjaboost
|
||||
check_flags = AB_CHECK_RESTRAINED|AB_CHECK_CONSCIOUS
|
||||
name = "Adrenaline Boost"
|
||||
desc = "Inject a secret chemical that will counteract all movement-impairing effect."
|
||||
button_icon_state = "repulse"
|
||||
@@ -437,6 +448,7 @@
|
||||
/datum/action/item_action/ninja_stealth
|
||||
name = "Toggle Stealth"
|
||||
desc = "Toggles stealth mode on and off."
|
||||
icon_icon = 'icons/mob/actions/actions_items.dmi'
|
||||
button_icon_state = "ninja_cloak"
|
||||
|
||||
/datum/action/item_action/toggle_glove
|
||||
@@ -478,6 +490,7 @@
|
||||
var/obj/effect/proc_holder/spell/S = target
|
||||
S.action = src
|
||||
name = S.name
|
||||
desc = S.desc
|
||||
button_icon = S.action_icon
|
||||
button_icon_state = S.action_icon_state
|
||||
background_icon_state = S.action_background_icon_state
|
||||
@@ -553,12 +566,14 @@
|
||||
/datum/action/item_action/stickmen
|
||||
name = "Summon Stick Minions"
|
||||
desc = "Allows you to summon faithful stickmen allies to aide you in battle."
|
||||
icon_icon = 'icons/mob/actions/actions_minor_antag.dmi'
|
||||
button_icon_state = "art_summon"
|
||||
|
||||
//surf_ss13
|
||||
/datum/action/item_action/bhop
|
||||
name = "Activate Jump Boots"
|
||||
desc = "Activates the jump boot's internal propulsion system, allowing the user to dash over 4-wide gaps."
|
||||
icon_icon = 'icons/mob/actions/actions_items.dmi'
|
||||
button_icon_state = "jetboot"
|
||||
|
||||
/datum/action/language_menu
|
||||
|
||||
@@ -152,7 +152,7 @@
|
||||
if(!owner||!owner.objectives)
|
||||
return
|
||||
for (var/objective_ in owner.objectives)
|
||||
if(!(istype(objective_, /datum/objective/escape)||istype(objective_,/datum/objective/survive)))
|
||||
if(!(istype(objective_, /datum/objective/escape)||istype(objective_, /datum/objective/survive)))
|
||||
continue
|
||||
remove_objective(objective_)
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
/datum/antagonist/traitor/human
|
||||
should_specialise = FALSE
|
||||
var/should_equip = TRUE
|
||||
|
||||
/datum/antagonist/traitor/human/custom
|
||||
silent = TRUE
|
||||
should_give_codewords = FALSE
|
||||
@@ -31,6 +32,7 @@
|
||||
|
||||
/datum/antagonist/traitor/AI
|
||||
should_specialise = FALSE
|
||||
|
||||
/datum/antagonist/traitor/AI/custom
|
||||
silent = TRUE
|
||||
should_give_codewords = FALSE
|
||||
@@ -38,9 +40,8 @@
|
||||
|
||||
|
||||
/datum/antagonist/traitor/on_body_transfer(mob/living/old_body, mob/living/new_body)
|
||||
if(issilicon(new_body) && issilicon(old_body))
|
||||
..()
|
||||
else
|
||||
// human <-> silicon only
|
||||
if(old_body && issilicon(new_body) ^ issilicon(old_body))
|
||||
silent = TRUE
|
||||
owner.add_antag_datum(base_datum_custom)
|
||||
for(var/datum/antagonist/traitor/new_datum in owner.antag_datums)
|
||||
@@ -49,13 +50,14 @@
|
||||
transfer_important_variables(new_datum)
|
||||
break
|
||||
on_removal()
|
||||
|
||||
|
||||
else
|
||||
..()
|
||||
|
||||
/datum/antagonist/traitor/human/custom //used to give custom objectives
|
||||
silent = TRUE
|
||||
give_objectives = FALSE
|
||||
should_give_codewords = FALSE
|
||||
|
||||
/datum/antagonist/traitor/AI/custom //used to give custom objectives
|
||||
silent = TRUE
|
||||
give_objectives = FALSE
|
||||
@@ -83,7 +85,8 @@
|
||||
if(owner.assigned_role == "Clown")
|
||||
var/mob/living/carbon/human/traitor_mob = owner.current
|
||||
if(traitor_mob&&istype(traitor_mob))
|
||||
if(!silent) to_chat(traitor_mob, "Your training has allowed you to overcome your clownish nature, allowing you to wield weapons without harming yourself.")
|
||||
if(!silent)
|
||||
to_chat(traitor_mob, "Your training has allowed you to overcome your clownish nature, allowing you to wield weapons without harming yourself.")
|
||||
traitor_mob.dna.remove_mutation(CLOWNMUT)
|
||||
|
||||
/datum/antagonist/traitor/remove_innate_effects()
|
||||
|
||||
@@ -100,3 +100,57 @@
|
||||
if (object == GLOBAL_PROC)
|
||||
return call(delegate)(arglist(calling_arguments))
|
||||
return call(object, delegate)(arglist(calling_arguments))
|
||||
|
||||
|
||||
/datum/callback_select
|
||||
var/list/finished
|
||||
var/pendingcount
|
||||
var/total
|
||||
|
||||
/datum/callback_select/New(count, savereturns)
|
||||
total = count
|
||||
if (savereturns)
|
||||
finished = new(count)
|
||||
|
||||
|
||||
/datum/callback_select/proc/invoke_callback(index, datum/callback/callback, list/callback_args, savereturn = TRUE)
|
||||
set waitfor = FALSE
|
||||
if (!callback || !istype(callback))
|
||||
//This check only exists because the alternative is callback_select would block forever if given invalid data
|
||||
CRASH("invalid callback passed to invoke_callback")
|
||||
if (!length(callback_args))
|
||||
callback_args = list()
|
||||
pendingcount++
|
||||
var/rtn = callback.Invoke(arglist(callback_args))
|
||||
pendingcount--
|
||||
if (savereturn)
|
||||
finished[index] = rtn
|
||||
|
||||
|
||||
|
||||
|
||||
//runs a list of callbacks asynchronously, returning once all of them return.
|
||||
//callbacks can be repeated.
|
||||
//callbacks-args is a optional list of argument lists, in the same order as the callbacks,
|
||||
// the inner lists will be sent to the callbacks when invoked() as additional args.
|
||||
//can optionly save and return a list of return values, in the same order as the original list of callbacks
|
||||
//resolution is the number of byond ticks between checks.
|
||||
/proc/callback_select(list/callbacks, list/callback_args, savereturns = TRUE, resolution = 1)
|
||||
if (!callbacks)
|
||||
return
|
||||
var/count = length(callbacks)
|
||||
if (!count)
|
||||
return
|
||||
if (!callback_args)
|
||||
callback_args = list()
|
||||
|
||||
callback_args.len = count
|
||||
|
||||
var/datum/callback_select/CS = new(count, savereturns)
|
||||
for (var/i in 1 to count)
|
||||
CS.invoke_callback(i, callbacks[i], callback_args[i], savereturns)
|
||||
|
||||
while(CS.pendingcount)
|
||||
sleep(resolution*world.tick_lag)
|
||||
return CS.finished
|
||||
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
# Datum Component System (DCS)
|
||||
|
||||
## Concept
|
||||
|
||||
Loosely adapted from /vg/. This is an entity component system for adding behaviours to datums when inheritance doesn't quite cut it. By using signals and events instead of direct inheritance, you can inject behaviours without hacky overloads. It requires a different method of thinking, but is not hard to use correctly. If a behaviour can have application across more than one thing. Make it generic, make it a component. Atom/mob/obj event? Give it a signal, and forward it's arguments with a `SendSignal()` call. Now every component that want's to can also know about this happening.
|
||||
|
||||
### In the code
|
||||
|
||||
#### Slippery things
|
||||
|
||||
At the time of this writing, every object that is slippery overrides atom/Crossed does some checks, then slips the mob. Instead of all those Crossed overrides they could add a slippery component to all these objects. And have the checks in one proc that is run by the Crossed event
|
||||
|
||||
#### Powercells
|
||||
|
||||
A lot of objects have powercells. The `get_cell()` proc was added to give generic access to the cell var if it had one. This is just a specific use case of `GetComponent()`
|
||||
|
||||
#### Radios
|
||||
|
||||
The radio object as it is should not exist, given that more things use the _concept_ of radios rather than the object itself. The actual function of the radio can exist in a component which all the things that use it (Request consoles, actual radios, the SM shard) can add to themselves.
|
||||
|
||||
#### Standos
|
||||
|
||||
Stands have a lot of procs which mimic mob procs. Rather than inserting hooks for all these procs in overrides, the same can be accomplished with signals
|
||||
|
||||
## API
|
||||
|
||||
### Vars
|
||||
|
||||
1. `/datum/var/list/datum_components` (private)
|
||||
* Lazy list of all components a datum has (TODO: Make this a typecache with longer paths overwriting shorter ones maybe? It'd be weird)
|
||||
1. `/datum/component/var/enabled` (protected, boolean)
|
||||
* If the component is enabled. If not, it will not react to signals
|
||||
* TRUE by default
|
||||
1. `/datum/component/var/dupe_mode` (protected, enum)
|
||||
* How multiple components of the exact same type are handled when added to the datum.
|
||||
* `COMPONENT_DUPE_HIGHLANDER` (default): Old component will be deleted, new component will first have `/datum/component/proc/InheritComponent(datum/component/old, FALSE)` on it
|
||||
* `COMPONENT_DUPE_ALLOWED`: The components will be treated as seperate, `GetComponent()` will return the first added
|
||||
* `COMPONENT_DUPE_UNIQUE`: New component will be deleted, old component will first have `/datum/component/proc/InheritComponent(datum/component/new, TRUE)` on it
|
||||
1. `/datum/component/var/list/signal_procs` (private)
|
||||
* Associated lazy list of signals -> callbacks that will be run when the parent datum recieves that signal
|
||||
1. `/datum/component/var/datum/parent` (protected, read-only)
|
||||
* The datum this component belongs to
|
||||
|
||||
### Procs
|
||||
|
||||
1. `/datum/proc/GetComponent(component_type(type)) -> datum/component?` (public, final)
|
||||
* Returns a reference to a component of component_type if it exists in the datum, null otherwise
|
||||
1. `/datum/proc/GetComponents(component_type(type)) -> list` (public, final)
|
||||
* Returns a list of references to all components of component_type that exist in the datum
|
||||
1. `/datum/proc/GetExactComponent(component_type(type)) -> datum/component?` (public, final)
|
||||
* Returns a reference to a component whose type MATCHES component_type if that component exists in the datum, null otherwise
|
||||
1. `GET_COMPONENT(varname, component_type)` OR `GET_COMPONENT_FROM(varname, component_type, src)`
|
||||
* Shorthand for `var/component_type/varname = src.GetComponent(component_type)`
|
||||
1. `/datum/proc/AddComponent(component_type(type), ...) -> datum/component` (public, final)
|
||||
* Creates an instance of `component_type` in the datum and passes `...` to it's `New()` call
|
||||
* Sends the `COMSIG_COMPONENT_ADDED` signal to the datum
|
||||
* All components a datum owns are deleted with the datum
|
||||
* Returns the component that was created. Or the old component in a dupe situation where `COMPONENT_DUPE_UNIQUE` was set
|
||||
1. `/datum/proc/ComponentActivated(datum/component/C)` (abstract)
|
||||
* Called on a component's `parent` after a signal recieved causes it to activate. `src` is the parameter
|
||||
* Will only be called if a component's callback returns `TRUE`
|
||||
1. `/datum/proc/TakeComponent(datum/component/C)` (public, final)
|
||||
* Properly transfers ownership of a component from one datum to another
|
||||
* Singals `COMSIG_COMPONENT_REMOVING` on the parent
|
||||
* Called on the datum you want to own the component with another datum's component
|
||||
1. `/datum/proc/SendSignal(signal, ...)` (public, final)
|
||||
* Call to send a signal to the components of the target datum
|
||||
* Extra arguments are to be specified in the signal definition
|
||||
1. `/datum/component/New(datum/parent, ...)` (protected, virtual)
|
||||
* Forwarded the arguments from `AddComponent()`
|
||||
1. `/datum/component/Destroy()` (virtual)
|
||||
* Sends the `COMSIG_COMPONENT_REMOVING` signal to the parent datum if the `parent` isn't being qdeleted
|
||||
* Properly removes the component from `parent` and cleans up references
|
||||
1. `/datum/component/proc/InheritComponent(datum/component/C, i_am_original(boolean))` (abstract)
|
||||
* Called on a component when a component of the same type was added to the same parent
|
||||
* See `/datum/component/var/dupe_mode`
|
||||
* `C`'s type will always be the same of the called component
|
||||
1. `/datum/component/proc/OnTransfer(datum/new_parent)` (abstract)
|
||||
* Called before the new `parent` is assigned in `TakeComponent()`, after the remove signal, before the added signal
|
||||
* Allows the component to react to ownership transfers
|
||||
1. `/datum/component/proc/_RemoveNoSignal()` (private, final)
|
||||
* Internal, clears the parent var and removes the component from the parents component list
|
||||
1. `/datum/component/proc/RegisterSignal(signal(string), proc_ref(type), override(boolean))` (protected, final) (Consider removing for performance gainz)
|
||||
* Makes a component listen for the specified `signal` on it's `parent` datum.
|
||||
* When that signal is recieved `proc_ref` will be called on the component, along with associated arguments
|
||||
* Example proc ref: `.proc/OnEvent`
|
||||
* If a previous registration is overwritten by the call, a runtime occurs. Setting `override` to TRUE prevents this
|
||||
* These callbacks run asyncronously
|
||||
* Returning `TRUE` from these callbacks will trigger a `TRUE` return from the `SendSignal()` that initiated it
|
||||
1. `/datum/component/proc/ReceiveSignal(signal, ...)` (virtual)
|
||||
* Called when a component recieves any signal and is enabled
|
||||
* Default implementation looks if the signal is registered and runs the appropriate proc
|
||||
|
||||
### See signals and their arguments in __DEFINES\components.dm
|
||||
|
||||
## Examples
|
||||
Material Containers: #29268 (Too many GetComponent calls, but not bad)
|
||||
Slips: #00000 (PR DIS)
|
||||
Powercells: (TODO)
|
||||
@@ -1,8 +1,8 @@
|
||||
/datum/component
|
||||
var/enabled = TRUE // Enables or disables the components
|
||||
var/dupe_mode = COMPONENT_DUPE_HIGHLANDER // How components of the same type are handled in the same parent
|
||||
var/list/signal_procs // list of signals -> callbacks
|
||||
var/datum/parent // parent datum
|
||||
var/enabled = TRUE
|
||||
var/dupe_mode = COMPONENT_DUPE_HIGHLANDER
|
||||
var/list/signal_procs
|
||||
var/datum/parent
|
||||
|
||||
/datum/component/New(datum/P, ...)
|
||||
var/dm = dupe_mode
|
||||
@@ -11,26 +11,34 @@
|
||||
if(old)
|
||||
switch(dm)
|
||||
if(COMPONENT_DUPE_HIGHLANDER)
|
||||
P.RemoveComponent(old)
|
||||
old = null //in case SendSignal() blocks
|
||||
InheritComponent(old, FALSE)
|
||||
qdel(old)
|
||||
if(COMPONENT_DUPE_UNIQUE)
|
||||
old.InheritComponent(src, TRUE)
|
||||
qdel(src)
|
||||
return
|
||||
P.SendSignal(COMSIG_COMPONENT_ADDED, list(src), FALSE)
|
||||
P.SendSignal(COMSIG_COMPONENT_ADDED, src)
|
||||
LAZYADD(P.datum_components, src)
|
||||
parent = P
|
||||
|
||||
/datum/component/Destroy()
|
||||
RemoveNoSignal()
|
||||
enabled = FALSE
|
||||
var/datum/P = parent
|
||||
if(P)
|
||||
_RemoveNoSignal()
|
||||
P.SendSignal(COMSIG_COMPONENT_REMOVING, src)
|
||||
LAZYCLEARLIST(signal_procs)
|
||||
return ..()
|
||||
|
||||
/datum/component/proc/RemoveNoSignal()
|
||||
/datum/component/proc/_RemoveNoSignal()
|
||||
var/datum/P = parent
|
||||
if(P)
|
||||
LAZYREMOVE(P.datum_components, src)
|
||||
parent = null
|
||||
|
||||
/datum/component/proc/RegisterSignal(sig_type, proc_on_self, override = FALSE)
|
||||
if(QDELETED(src))
|
||||
return
|
||||
var/list/procs = signal_procs
|
||||
if(!procs)
|
||||
procs = list()
|
||||
@@ -43,24 +51,34 @@
|
||||
|
||||
procs[sig_type] = CALLBACK(src, proc_on_self)
|
||||
|
||||
/datum/var/list/datum_components //list of /datum/component
|
||||
/datum/component/proc/ReceiveSignal(sigtype, ...)
|
||||
var/list/sps = signal_procs
|
||||
var/datum/callback/CB = LAZYACCESS(sps, sigtype)
|
||||
if(!CB)
|
||||
return FALSE
|
||||
var/list/arguments = args.Copy()
|
||||
arguments.Cut(1, 2)
|
||||
return CB.InvokeAsync(arglist(arguments))
|
||||
|
||||
// Send a signal to all other components in the container.
|
||||
/datum/proc/SendSignal(sigtype, list/sig_args, async = FALSE)
|
||||
/datum/component/proc/InheritComponent(datum/component/C, i_am_original)
|
||||
return
|
||||
|
||||
/datum/component/proc/OnTransfer(datum/new_parent)
|
||||
return
|
||||
|
||||
/datum/proc/SendSignal(sigtype, ...)
|
||||
var/list/comps = datum_components
|
||||
. = FALSE
|
||||
for(var/I in comps)
|
||||
var/datum/component/C = I
|
||||
if(!C.enabled)
|
||||
continue
|
||||
var/list/sps = C.signal_procs
|
||||
var/datum/callback/CB = LAZYACCESS(sps, sigtype)
|
||||
if(!CB)
|
||||
continue
|
||||
if(!async)
|
||||
. |= CB.Invoke(sig_args)
|
||||
else
|
||||
. |= CB.InvokeAsync(sig_args)
|
||||
if(C.ReceiveSignal(arglist(args)))
|
||||
ComponentActivated(C)
|
||||
. = TRUE
|
||||
|
||||
/datum/proc/ComponentActivated(datum/component/C)
|
||||
return
|
||||
|
||||
/datum/proc/GetComponent(c_type)
|
||||
for(var/I in datum_components)
|
||||
@@ -79,19 +97,21 @@
|
||||
if(istype(I, c_type))
|
||||
. += I
|
||||
|
||||
/datum/proc/AddComponents(list/new_types)
|
||||
for(var/new_type in new_types)
|
||||
AddComponent(new_type)
|
||||
|
||||
/datum/proc/AddComponent(new_type, ...)
|
||||
var/nt = new_type
|
||||
args[1] = src
|
||||
var/datum/component/C = new nt(arglist(args))
|
||||
return QDELING(C) ? GetComponent(new_type) : C
|
||||
|
||||
/datum/proc/RemoveComponent(datum/component/C)
|
||||
/datum/proc/TakeComponent(datum/component/C)
|
||||
if(!C)
|
||||
return
|
||||
C.RemoveNoSignal()
|
||||
SendSignal(COMSIG_COMPONENT_REMOVING, list(C), FALSE)
|
||||
qdel(C)
|
||||
var/datum/helicopter = C.parent
|
||||
if(helicopter == src)
|
||||
//wat
|
||||
return
|
||||
C._RemoveNoSignal()
|
||||
helicopter.SendSignal(COMSIG_COMPONENT_REMOVING, C)
|
||||
C.OnTransfer(src)
|
||||
C.parent = src
|
||||
SendSignal(COMSIG_COMPONENT_ADDED, C)
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
/datum
|
||||
var/gc_destroyed //Time when this object was destroyed.
|
||||
var/list/active_timers //for SStimer
|
||||
var/list/datum_components //for /datum/components
|
||||
var/ui_screen = "home" //for tgui
|
||||
|
||||
#ifdef TESTING
|
||||
var/running_find_references
|
||||
var/last_find_references = 0
|
||||
#endif
|
||||
|
||||
// Default implementation of clean-up code.
|
||||
// This should be overridden to remove all references pointing to the object being destroyed.
|
||||
// Return the appropriate QDEL_HINT; in most cases this is QDEL_HINT_QUEUE.
|
||||
/datum/proc/Destroy(force=FALSE)
|
||||
tag = null
|
||||
var/list/timers = active_timers
|
||||
active_timers = null
|
||||
for(var/thing in timers)
|
||||
var/datum/timedevent/timer = thing
|
||||
if (timer.spent)
|
||||
continue
|
||||
qdel(timer)
|
||||
var/list/dc = datum_components
|
||||
for(var/I in dc)
|
||||
var/datum/component/C = I
|
||||
C._RemoveNoSignal()
|
||||
qdel(C)
|
||||
if(dc)
|
||||
dc.Cut()
|
||||
return QDEL_HINT_QUEUE
|
||||
@@ -21,7 +21,7 @@
|
||||
return debug_variable(var_name, vars[var_name], 0, src)
|
||||
|
||||
//please call . = ..() first and append to the result, that way parent items are always at the top and child items are further down
|
||||
//add seperaters by doing . += "---"
|
||||
//add separaters by doing . += "---"
|
||||
/datum/proc/vv_get_dropdown()
|
||||
. = list()
|
||||
. += "---"
|
||||
@@ -62,7 +62,7 @@
|
||||
|
||||
|
||||
|
||||
if(istype(D,/atom))
|
||||
if(istype(D, /atom))
|
||||
var/atom/AT = D
|
||||
if(AT.icon && AT.icon_state)
|
||||
sprite = new /icon(AT.icon, AT.icon_state)
|
||||
@@ -77,7 +77,7 @@
|
||||
sprite_text = "<img src='vv[hash].png'></td><td>"
|
||||
var/list/atomsnowflake = list()
|
||||
|
||||
if(istype(D,/atom))
|
||||
if(istype(D, /atom))
|
||||
var/atom/A = D
|
||||
if(isliving(A))
|
||||
atomsnowflake += "<a href='?_src_=vars;rename=[refid]'><b>[D]</b></a>"
|
||||
@@ -575,7 +575,7 @@
|
||||
return
|
||||
|
||||
var/D = locate(href_list["datumedit"])
|
||||
if(!istype(D,/datum))
|
||||
if(!istype(D, /datum))
|
||||
to_chat(usr, "This can only be used on datums")
|
||||
return
|
||||
|
||||
@@ -586,7 +586,7 @@
|
||||
return
|
||||
|
||||
var/D = locate(href_list["datumchange"])
|
||||
if(!istype(D,/datum))
|
||||
if(!istype(D, /datum))
|
||||
to_chat(usr, "This can only be used on datums")
|
||||
return
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
|
||||
/mob/proc/HasDisease(datum/disease/D)
|
||||
for(var/datum/disease/DD in viruses)
|
||||
for(var/thing in viruses)
|
||||
var/datum/disease/DD = thing
|
||||
if(D.IsSame(DD))
|
||||
return 1
|
||||
return 0
|
||||
@@ -39,7 +40,7 @@
|
||||
var/datum/disease/DD = new D.type(1, D, 0)
|
||||
viruses += DD
|
||||
DD.affected_mob = src
|
||||
DD.holder = src
|
||||
SSdisease.active_diseases += DD //Add it to the active diseases list, now that it's actually in a mob and being processed.
|
||||
|
||||
//Copy properties over. This is so edited diseases persist.
|
||||
var/list/skipped = list("affected_mob","holder","carrier","stage","type","parent_type","vars","transformed")
|
||||
@@ -147,6 +148,9 @@
|
||||
|
||||
|
||||
/mob/living/carbon/human/CanContractDisease(datum/disease/D)
|
||||
if(dna && (VIRUSIMMUNE in dna.species.species_traits))
|
||||
if(dna && (VIRUSIMMUNE in dna.species.species_traits) && !D.bypasses_immunity)
|
||||
return 0
|
||||
for(var/thing in D.required_organs)
|
||||
if(!((locate(thing) in bodyparts) || (locate(thing) in internal_organs)))
|
||||
return 0
|
||||
return ..()
|
||||
@@ -46,21 +46,23 @@
|
||||
var/stage_prob = 4
|
||||
|
||||
//Other
|
||||
var/longevity = 150 //Time in ticks disease stays in objects, Syringes and such are infinite.
|
||||
var/list/viable_mobtypes = list() //typepaths of viable mobs
|
||||
var/mob/living/carbon/affected_mob = null
|
||||
var/atom/movable/holder = null
|
||||
var/list/cures = list() //list of cures if the disease has the CURABLE flag, these are reagent ids
|
||||
var/infectivity = 65
|
||||
var/cure_chance = 8
|
||||
var/carrier = 0 //If our host is only a carrier
|
||||
var/carrier = FALSE //If our host is only a carrier
|
||||
var/bypasses_immunity = FALSE //Does it skip species virus immunity check? Some things may diseases and not viruses
|
||||
var/permeability_mod = 1
|
||||
var/severity = NONTHREAT
|
||||
var/list/required_organs = list()
|
||||
var/needs_all_cures = TRUE
|
||||
var/list/strain_data = list() //dna_spread special bullshit
|
||||
|
||||
|
||||
/datum/disease/Destroy()
|
||||
affected_mob = null
|
||||
SSdisease.active_diseases.Remove(src)
|
||||
return ..()
|
||||
|
||||
/datum/disease/proc/stage_act()
|
||||
var/cure = has_cure()
|
||||
@@ -93,13 +95,16 @@
|
||||
if(!. || (needs_all_cures && . < cures.len))
|
||||
return 0
|
||||
|
||||
/datum/disease/proc/spread(atom/source, force_spread = 0)
|
||||
|
||||
/datum/disease/proc/spread(force_spread = 0)
|
||||
if(!affected_mob)
|
||||
return
|
||||
|
||||
if((spread_flags & SPECIAL || spread_flags & NON_CONTAGIOUS || spread_flags & BLOOD) && !force_spread)
|
||||
return
|
||||
|
||||
if(affected_mob)
|
||||
if( affected_mob.reagents.has_reagent("spaceacillin") || (affected_mob.satiety > 0 && prob(affected_mob.satiety/10)) )
|
||||
return
|
||||
if(affected_mob.reagents.has_reagent("spaceacillin") || (affected_mob.satiety > 0 && prob(affected_mob.satiety/10)))
|
||||
return
|
||||
|
||||
var/spread_range = 1
|
||||
|
||||
@@ -109,15 +114,9 @@
|
||||
if(spread_flags & AIRBORNE)
|
||||
spread_range++
|
||||
|
||||
if(!source)
|
||||
if(affected_mob)
|
||||
source = affected_mob
|
||||
else
|
||||
return
|
||||
|
||||
var/turf/T = source.loc
|
||||
var/turf/T = affected_mob.loc
|
||||
if(istype(T))
|
||||
for(var/mob/living/carbon/C in oview(spread_range, source))
|
||||
for(var/mob/living/carbon/C in oview(spread_range, affected_mob))
|
||||
var/turf/V = get_turf(C)
|
||||
if(V)
|
||||
while(TRUE)
|
||||
@@ -129,29 +128,6 @@
|
||||
break
|
||||
V = Temp
|
||||
|
||||
/datum/disease/process()
|
||||
if(!holder)
|
||||
SSdisease.processing -= src
|
||||
return
|
||||
|
||||
if(prob(infectivity))
|
||||
spread(holder)
|
||||
|
||||
if(affected_mob)
|
||||
for(var/datum/disease/D in affected_mob.viruses)
|
||||
if(D != src)
|
||||
if(IsSame(D))
|
||||
qdel(D)
|
||||
|
||||
if(holder == affected_mob)
|
||||
if(affected_mob.stat != DEAD)
|
||||
stage_act()
|
||||
|
||||
if(!affected_mob)
|
||||
if(prob(70))
|
||||
if(--longevity<=0)
|
||||
cure()
|
||||
|
||||
|
||||
/datum/disease/proc/cure()
|
||||
if(affected_mob)
|
||||
@@ -161,20 +137,6 @@
|
||||
remove_virus()
|
||||
qdel(src)
|
||||
|
||||
|
||||
/datum/disease/New()
|
||||
if(required_organs && required_organs.len)
|
||||
if(ishuman(affected_mob))
|
||||
var/mob/living/carbon/human/H = affected_mob
|
||||
for(var/obj/item/organ/O in required_organs)
|
||||
if(!locate(O) in H.bodyparts)
|
||||
if(!locate(O) in H.internal_organs)
|
||||
cure()
|
||||
return
|
||||
|
||||
SSdisease.processing += src
|
||||
|
||||
|
||||
/datum/disease/proc/IsSame(datum/disease/D)
|
||||
if(istype(src, D.type))
|
||||
return 1
|
||||
@@ -191,11 +153,6 @@
|
||||
return type
|
||||
|
||||
|
||||
/datum/disease/Destroy()
|
||||
SSdisease.processing.Remove(src)
|
||||
return ..()
|
||||
|
||||
|
||||
/datum/disease/proc/IsSpreadByTouch()
|
||||
if(spread_flags & CONTACT_FEET || spread_flags & CONTACT_HANDS || spread_flags & CONTACT_GENERAL)
|
||||
return 1
|
||||
|
||||
@@ -93,7 +93,7 @@
|
||||
if(!(istype(D, /datum/disease/advance)))
|
||||
return 0
|
||||
|
||||
if(src.GetDiseaseID() != D.GetDiseaseID())
|
||||
if(GetDiseaseID() != D.GetDiseaseID())
|
||||
return 0
|
||||
return 1
|
||||
|
||||
@@ -118,7 +118,7 @@
|
||||
|
||||
// Mix the symptoms of two diseases (the src and the argument)
|
||||
/datum/disease/advance/proc/Mix(datum/disease/advance/D)
|
||||
if(!(src.IsSame(D)))
|
||||
if(!(IsSame(D)))
|
||||
var/list/possible_symptoms = shuffle(D.symptoms)
|
||||
for(var/datum/symptom/S in possible_symptoms)
|
||||
AddSymptom(S.Copy())
|
||||
@@ -158,7 +158,6 @@
|
||||
return generated
|
||||
|
||||
/datum/disease/advance/proc/Refresh(new_name = FALSE)
|
||||
//to_chat(world, "[src.name] \ref[src] - REFRESH!")
|
||||
GenerateProperties()
|
||||
AssignProperties()
|
||||
id = null
|
||||
@@ -412,7 +411,7 @@
|
||||
D.AssignName(new_name)
|
||||
D.Refresh()
|
||||
|
||||
for(var/datum/disease/advance/AD in SSdisease.processing)
|
||||
for(var/datum/disease/advance/AD in SSdisease.active_diseases)
|
||||
AD.Refresh()
|
||||
|
||||
for(var/mob/living/carbon/human/H in shuffle(GLOB.living_mob_list))
|
||||
@@ -427,13 +426,6 @@
|
||||
name_symptoms += S.name
|
||||
message_admins("[key_name_admin(user)] has triggered a custom virus outbreak of [D.name]! It has these symptoms: [english_list(name_symptoms)]")
|
||||
|
||||
/*
|
||||
/mob/verb/test()
|
||||
|
||||
for(var/datum/disease/D in SSdisease.processing)
|
||||
to_chat(src, "<a href='?_src_=vars;Vars=\ref[D]'>[D.name] - [D.holder]</a>")
|
||||
*/
|
||||
|
||||
|
||||
/datum/disease/advance/proc/totalStageSpeed()
|
||||
return properties["stage_rate"]
|
||||
|
||||
@@ -24,45 +24,45 @@ BONUS
|
||||
transmittable = 2
|
||||
level = 1
|
||||
severity = 1
|
||||
base_message_chance = 15
|
||||
symptom_delay_min = 2
|
||||
symptom_delay_max = 15
|
||||
var/infective = FALSE
|
||||
base_message_chance = 15
|
||||
symptom_delay_min = 2
|
||||
symptom_delay_max = 15
|
||||
var/infective = FALSE
|
||||
|
||||
/datum/symptom/cough/Start(datum/disease/advance/A)
|
||||
/datum/symptom/cough/Start(datum/disease/advance/A)
|
||||
..()
|
||||
if(A.properties["stealth"] >= 4)
|
||||
suppress_warning = TRUE
|
||||
if(A.spread_flags &= AIRBORNE) //infect bystanders
|
||||
infective = TRUE
|
||||
if(A.properties["resistance"] >= 3) //strong enough to drop items
|
||||
power = 1.5
|
||||
if(A.properties["resistance"] >= 10) //strong enough to stun (rarely)
|
||||
power = 2
|
||||
if(A.properties["stage_rate"] >= 6) //cough more often
|
||||
symptom_delay_max = 10
|
||||
|
||||
/datum/symptom/cough/Activate(datum/disease/advance/A)
|
||||
if(!..())
|
||||
return
|
||||
var/mob/living/M = A.affected_mob
|
||||
switch(A.stage)
|
||||
if(1, 2, 3)
|
||||
if(prob(base_message_chance) && !suppress_warning)
|
||||
if(A.properties["stealth"] >= 4)
|
||||
suppress_warning = TRUE
|
||||
if(A.spread_flags &= AIRBORNE) //infect bystanders
|
||||
infective = TRUE
|
||||
if(A.properties["resistance"] >= 3) //strong enough to drop items
|
||||
power = 1.5
|
||||
if(A.properties["resistance"] >= 10) //strong enough to stun (rarely)
|
||||
power = 2
|
||||
if(A.properties["stage_rate"] >= 6) //cough more often
|
||||
symptom_delay_max = 10
|
||||
|
||||
/datum/symptom/cough/Activate(datum/disease/advance/A)
|
||||
if(!..())
|
||||
return
|
||||
var/mob/living/M = A.affected_mob
|
||||
switch(A.stage)
|
||||
if(1, 2, 3)
|
||||
if(prob(base_message_chance) && !suppress_warning)
|
||||
to_chat(M, "<span notice='warning'>[pick("You swallow excess mucus.", "You lightly cough.")]</span>")
|
||||
else
|
||||
M.emote("cough")
|
||||
if(power >= 1.5)
|
||||
else
|
||||
M.emote("cough")
|
||||
if(power >= 1.5)
|
||||
var/obj/item/I = M.get_active_held_item()
|
||||
if(I && I.w_class == WEIGHT_CLASS_TINY)
|
||||
M.drop_item()
|
||||
if(power >= 2 && prob(10))
|
||||
to_chat(M, "<span notice='userdanger'>[pick("You have a coughing fit!", "You can't stop coughing!")]</span>")
|
||||
M.Stun(20)
|
||||
M.emote("cough")
|
||||
addtimer(CALLBACK(M, /mob/.proc/emote, "cough"), 6)
|
||||
addtimer(CALLBACK(M, /mob/.proc/emote, "cough"), 12)
|
||||
addtimer(CALLBACK(M, /mob/.proc/emote, "cough"), 18)
|
||||
if(infective)
|
||||
A.spread(A.holder, 1)
|
||||
|
||||
if(power >= 2 && prob(10))
|
||||
to_chat(M, "<span notice='userdanger'>[pick("You have a coughing fit!", "You can't stop coughing!")]</span>")
|
||||
M.Stun(20)
|
||||
M.emote("cough")
|
||||
addtimer(CALLBACK(M, /mob/.proc/emote, "cough"), 6)
|
||||
addtimer(CALLBACK(M, /mob/.proc/emote, "cough"), 12)
|
||||
addtimer(CALLBACK(M, /mob/.proc/emote, "cough"), 18)
|
||||
if(infective)
|
||||
A.spread(1)
|
||||
|
||||
|
||||
@@ -63,14 +63,14 @@ Bonus
|
||||
M.adjust_fire_stacks(1 * power)
|
||||
M.adjustFireLoss(3 * power)
|
||||
if(infective)
|
||||
A.spread(A.holder, 2)
|
||||
A.spread(2)
|
||||
return 1
|
||||
|
||||
/datum/symptom/fire/proc/Firestacks_stage_5(mob/living/M, datum/disease/advance/A)
|
||||
M.adjust_fire_stacks(3 * power)
|
||||
M.adjustFireLoss(5 * power)
|
||||
if(infective)
|
||||
A.spread(A.holder, 4)
|
||||
A.spread(4)
|
||||
return 1
|
||||
|
||||
/*
|
||||
|
||||
@@ -1,134 +0,0 @@
|
||||
diff a/code/datums/diseases/advance/symptoms/sensory.dm b/code/datums/diseases/advance/symptoms/sensory.dm (rejected hunks)
|
||||
@@ -23,106 +23,43 @@ Bonus
|
||||
transmittable = -3
|
||||
level = 5
|
||||
severity = 0
|
||||
+ symptom_delay_min = 5
|
||||
+ symptom_delay_max = 10
|
||||
+ var/purge_alcohol = FALSE
|
||||
+ var/brain_heal = FALSE
|
||||
|
||||
-/datum/symptom/sensory_restoration/Activate(var/datum/disease/advance/A)
|
||||
+/datum/symptom/sensory_restoration/Start(datum/disease/advance/A)
|
||||
..()
|
||||
+ if(A.properties["resistance"] >= 6) //heal brain damage
|
||||
+ brain_heal = TRUE
|
||||
+ if(A.properties["transmittable"] >= 8) //purge alcohol
|
||||
+ purge_alcohol = TRUE
|
||||
+
|
||||
+/datum/symptom/sensory_restoration/Activate(var/datum/disease/advance/A)
|
||||
+ if(!..())
|
||||
+ return
|
||||
var/mob/living/M = A.affected_mob
|
||||
if(A.stage >= 2)
|
||||
M.restoreEars()
|
||||
|
||||
if(A.stage >= 3)
|
||||
- M.dizziness = 0
|
||||
- M.drowsyness = 0
|
||||
- M.slurring = 0
|
||||
- M.confused = 0
|
||||
- M.reagents.remove_all_type(/datum/reagent/consumable/ethanol, 3)
|
||||
- if(ishuman(M))
|
||||
- var/mob/living/carbon/human/H = M
|
||||
- H.drunkenness = max(H.drunkenness - 10, 0)
|
||||
+ M.dizziness = max(0, M.dizziness - 2)
|
||||
+ M.drowsyness = max(0, M.drowsyness - 2)
|
||||
+ M.slurring = max(0, M.slurring - 2)
|
||||
+ M.confused = max(0, M.confused - 2)
|
||||
+ if(purge_alcohol)
|
||||
+ M.reagents.remove_all_type(/datum/reagent/consumable/ethanol, 3)
|
||||
+ if(ishuman(M))
|
||||
+ var/mob/living/carbon/human/H = M
|
||||
+ H.drunkenness = max(H.drunkenness - 5, 0)
|
||||
|
||||
if(A.stage >= 4)
|
||||
- M.drowsyness = max(M.drowsyness-5, 0)
|
||||
+ M.drowsyness = max(0, M.drowsyness - 2)
|
||||
if(M.reagents.has_reagent("mindbreaker"))
|
||||
M.reagents.remove_reagent("mindbreaker", 5)
|
||||
if(M.reagents.has_reagent("histamine"))
|
||||
M.reagents.remove_reagent("histamine", 5)
|
||||
M.hallucination = max(0, M.hallucination - 10)
|
||||
|
||||
- if(A.stage >= 5)
|
||||
- M.adjustBrainLoss(-3)
|
||||
-
|
||||
-/*
|
||||
-//////////////////////////////////////
|
||||
-Sensory-Destruction
|
||||
- noticable.
|
||||
- Lowers resistance
|
||||
- Decreases stage speed tremendously.
|
||||
- Decreases transmittablity tremendously.
|
||||
- the drugs hit them so hard they have to focus on not dying
|
||||
-
|
||||
-Bonus
|
||||
- The body generates Sensory destructive chemicals.
|
||||
- You cannot taste anything anymore.
|
||||
- ethanol for extremely drunk victim
|
||||
- mindbreaker to break the mind
|
||||
- impedrezene to ruin the brain
|
||||
-
|
||||
-//////////////////////////////////////
|
||||
-*/
|
||||
-/datum/symptom/sensory_destruction
|
||||
- name = "Sensory destruction"
|
||||
- stealth = -1
|
||||
- resistance = -2
|
||||
- stage_speed = -3
|
||||
- transmittable = -4
|
||||
- level = 6
|
||||
- severity = 5
|
||||
- var/sleepy = 0
|
||||
- var/sleepy_ticks = 0
|
||||
-
|
||||
-/datum/symptom/sensory_destruction/Activate(var/datum/disease/advance/A)
|
||||
- ..()
|
||||
- var/mob/living/M = A.affected_mob
|
||||
- if(prob(SYMPTOM_ACTIVATION_PROB))
|
||||
- switch(A.stage)
|
||||
- if(1)
|
||||
- to_chat(M, "<span class='warning'>You can't feel anything.</span>")
|
||||
- if(2)
|
||||
- to_chat(M, "<span class='warning'>You feel absolutely hammered.</span>")
|
||||
- if(prob(10))
|
||||
- sleepy_ticks += rand(10,14)
|
||||
- if(3)
|
||||
- M.reagents.add_reagent("ethanol",rand(5,7))
|
||||
- to_chat(M, "<span class='warning'>You try to focus on not dying.</span>")
|
||||
- if(prob(15))
|
||||
- sleepy_ticks += rand(10,14)
|
||||
- if(4)
|
||||
- M.reagents.add_reagent("ethanol",rand(6,10))
|
||||
- to_chat(M, "<span class='warning'>u can count 2 potato!</span>")
|
||||
- if(prob(20))
|
||||
- sleepy_ticks += rand(10,14)
|
||||
- if(5)
|
||||
- M.reagents.add_reagent("ethanol",rand(7,13))
|
||||
- if(prob(25))
|
||||
- sleepy_ticks += rand(10,14)
|
||||
-
|
||||
- if(sleepy_ticks)
|
||||
- if(A.stage>=4)
|
||||
- M.hallucination = min(M.hallucination + 10, 50)
|
||||
- if(A.stage>=5)
|
||||
- if(prob(80))
|
||||
- M.adjustBrainLoss(1)
|
||||
- if(prob(50))
|
||||
- M.drowsyness = max(M.drowsyness, 3)
|
||||
- sleepy++
|
||||
- sleepy_ticks--
|
||||
- else
|
||||
- sleepy = 0
|
||||
-
|
||||
- switch(sleepy) //Works like morphine
|
||||
- if(11)
|
||||
- to_chat(M, "<span class='warning'>You start to feel tired...</span>")
|
||||
- if(12 to 24)
|
||||
- M.drowsyness += 1
|
||||
- if(24 to INFINITY)
|
||||
- M.Sleeping(2, 0)
|
||||
+ if(brain_heal && A.stage >= 5)
|
||||
+ M.adjustBrainLoss(-3)
|
||||
\ No newline at end of file
|
||||
@@ -1,34 +1,34 @@
|
||||
/*
|
||||
//////////////////////////////////////
|
||||
|
||||
Sneezing
|
||||
|
||||
Very Noticable.
|
||||
Increases resistance.
|
||||
Doesn't increase stage speed.
|
||||
Very transmittable.
|
||||
Low Level.
|
||||
|
||||
Bonus
|
||||
Forces a spread type of AIRBORNE
|
||||
with extra range!
|
||||
|
||||
//////////////////////////////////////
|
||||
*/
|
||||
|
||||
/datum/symptom/sneeze
|
||||
name = "Sneezing"
|
||||
stealth = -2
|
||||
resistance = 3
|
||||
stage_speed = 0
|
||||
transmittable = 4
|
||||
level = 1
|
||||
severity = 1
|
||||
/*
|
||||
//////////////////////////////////////
|
||||
|
||||
Sneezing
|
||||
|
||||
Very Noticable.
|
||||
Increases resistance.
|
||||
Doesn't increase stage speed.
|
||||
Very transmittable.
|
||||
Low Level.
|
||||
|
||||
Bonus
|
||||
Forces a spread type of AIRBORNE
|
||||
with extra range!
|
||||
|
||||
//////////////////////////////////////
|
||||
*/
|
||||
|
||||
/datum/symptom/sneeze
|
||||
name = "Sneezing"
|
||||
stealth = -2
|
||||
resistance = 3
|
||||
stage_speed = 0
|
||||
transmittable = 4
|
||||
level = 1
|
||||
severity = 1
|
||||
symptom_delay_min = 5
|
||||
symptom_delay_max = 35
|
||||
|
||||
|
||||
/datum/symptom/sneeze/Start(datum/disease/advance/A)
|
||||
..()
|
||||
..()
|
||||
if(A.properties["transmittable"] >= 9) //longer spread range
|
||||
power = 2
|
||||
if(A.properties["stealth"] >= 4)
|
||||
@@ -41,7 +41,8 @@ Bonus
|
||||
switch(A.stage)
|
||||
if(1, 2, 3)
|
||||
if(!suppress_warning)
|
||||
M.emote("sniff")
|
||||
else
|
||||
M.emote("sneeze")
|
||||
A.spread(A.holder, 4 + power)
|
||||
M.emote("sniff")
|
||||
else
|
||||
M.emote("sneeze")
|
||||
A.spread(5)
|
||||
return
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
/datum/symptom/New()
|
||||
var/list/S = SSdisease.list_symptoms
|
||||
for(var/i = 1; i <= S.len; i++)
|
||||
if(src.type == S[i])
|
||||
if(type == S[i])
|
||||
id = "[i]"
|
||||
return
|
||||
CRASH("We couldn't assign an ID!")
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
diff a/code/datums/diseases/advance/symptoms/vision.dm b/code/datums/diseases/advance/symptoms/vision.dm (rejected hunks)
|
||||
@@ -40,7 +40,7 @@ Bonus
|
||||
if(!..())
|
||||
return
|
||||
var/mob/living/carbon/M = A.affected_mob
|
||||
- var/obj/item/organ/eyes = M.getorganslot("eye_sight")
|
||||
+ var/obj/item/organ/eyes/eyes = M.getorganslot("eye_sight")
|
||||
if(istype(eyes))
|
||||
switch(A.stage)
|
||||
if(1, 2)
|
||||
@@ -55,7 +55,7 @@ Bonus
|
||||
M.adjust_eye_damage(5)
|
||||
if(eyes.eye_damage >= 10)
|
||||
M.become_nearsighted()
|
||||
- if(prob(M.eye_damage - 10 + 1))
|
||||
+ if(prob(eyes.eye_damage - 10 + 1))
|
||||
if(!remove_eyes)
|
||||
if(M.become_blind())
|
||||
to_chat(M, "<span class='userdanger'>You go blind!</span>")
|
||||
@@ -1,30 +0,0 @@
|
||||
diff a/code/datums/diseases/advance/symptoms/vomit.dm b/code/datums/diseases/advance/symptoms/vomit.dm (rejected hunks)
|
||||
@@ -32,7 +32,7 @@ Bonus
|
||||
symptom_delay_min = 25
|
||||
symptom_delay_max = 80
|
||||
var/vomit_blood = FALSE
|
||||
- var/proj_vomit = FALSE
|
||||
+ var/proj_vomit = 0
|
||||
|
||||
/datum/symptom/vomit/Start(datum/disease/advance/A)
|
||||
..()
|
||||
@@ -41,7 +41,7 @@ Bonus
|
||||
if(A.properties["resistance"] >= 7) //blood vomit
|
||||
vomit_blood = TRUE
|
||||
if(A.properties["transmittable"] >= 7) //projectile vomit
|
||||
- proj_vomit = TRUE
|
||||
+ proj_vomit = 5
|
||||
|
||||
/datum/symptom/vomit/Activate(datum/disease/advance/A)
|
||||
if(!..())
|
||||
@@ -52,7 +52,7 @@ Bonus
|
||||
if(prob(base_message_chance) && !suppress_warning)
|
||||
to_chat(M, "<span class='warning'>[pick("You feel nauseous.", "You feel like you're going to throw up!")]</span>")
|
||||
else
|
||||
- Vomit(M)
|
||||
+ vomit(M)
|
||||
|
||||
-/datum/symptom/vomit/proc/Vomit(mob/living/carbon/M)
|
||||
- M.vomit(20, vomit_blood, distance = 5 * proj_vomit)
|
||||
+/datum/symptom/vomit/proc/vomit(mob/living/carbon/M)
|
||||
+ M.vomit(20, vomit_blood, distance = proj_vomit)
|
||||
@@ -7,7 +7,7 @@
|
||||
cure_text = "Ethanol"
|
||||
cures = list("ethanol")
|
||||
agent = "Excess Lepidopticides"
|
||||
viable_mobtypes = list(/mob/living/carbon/human,/mob/living/carbon/monkey)
|
||||
viable_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
|
||||
desc = "If left untreated subject will regurgitate butterflies."
|
||||
severity = MEDIUM
|
||||
|
||||
|
||||
@@ -8,11 +8,11 @@
|
||||
permeability_mod = 1
|
||||
desc = "If left untreated the subject will become very weak, and may vomit often."
|
||||
severity = "Dangerous!"
|
||||
longevity = 1000
|
||||
disease_flags = CAN_CARRY|CAN_RESIST
|
||||
spread_flags = NON_CONTAGIOUS
|
||||
visibility_flags = HIDDEN_PANDEMIC
|
||||
required_organs = list(/obj/item/organ/appendix)
|
||||
bypasses_immunity = TRUE // Immunity is based on not having an appendix; this isn't a virus
|
||||
|
||||
/datum/disease/appendicitis/stage_act()
|
||||
..()
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
cure_text = "Sugar"
|
||||
cures = list("sugar")
|
||||
agent = "Apidae Infection"
|
||||
viable_mobtypes = list(/mob/living/carbon/human,/mob/living/carbon/monkey)
|
||||
viable_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
|
||||
desc = "If left untreated subject will regurgitate bees."
|
||||
severity = DANGEROUS
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
viable_mobtypes = list(/mob/living/carbon/human)
|
||||
cure_chance = 15//higher chance to cure, since two reagents are required
|
||||
desc = "This disease destroys the braincells, causing brain fever, brain necrosis and general intoxication."
|
||||
required_organs = list(/obj/item/bodypart/head)
|
||||
required_organs = list(/obj/item/organ/brain)
|
||||
severity = DANGEROUS
|
||||
|
||||
/datum/disease/brainrot/stage_act() //Removed toxloss because damaging diseases are pretty horrible. Last round it killed the entire station because the cure didn't work -- Urist -ACTUALLY Removed rather than commented out, I don't see it returning - RR
|
||||
|
||||
@@ -25,8 +25,8 @@
|
||||
//Absorbs the target DNA.
|
||||
strain_data["dna"] = new affected_mob.dna.type
|
||||
affected_mob.dna.copy_dna(strain_data["dna"])
|
||||
src.carrier = 1
|
||||
src.stage = 4
|
||||
carrier = TRUE
|
||||
stage = 4
|
||||
return
|
||||
|
||||
switch(stage)
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
cure_text = "Synaptizine & Sulfur"
|
||||
cures = list("synaptizine","sulfur")
|
||||
agent = "Gravitokinetic Bipotential SADS-"
|
||||
viable_mobtypes = list(/mob/living/carbon/human,/mob/living/carbon/monkey)
|
||||
viable_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
|
||||
desc = "If left untreated death will occur."
|
||||
severity = BIOHAZARD
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
cures = list("spaceacillin")
|
||||
cure_chance = 10
|
||||
agent = "H13N1 flu virion"
|
||||
viable_mobtypes = list(/mob/living/carbon/human,/mob/living/carbon/monkey)
|
||||
viable_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
|
||||
permeability_mod = 0.75
|
||||
desc = "If left untreated the subject will feel quite unwell."
|
||||
severity = MEDIUM
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
permeability_mod = 0.75
|
||||
desc = "If left untreated the subject will probably drive others to insanity."
|
||||
severity = MEDIUM
|
||||
longevity = 400
|
||||
|
||||
/datum/disease/pierrot_throat/stage_act()
|
||||
..()
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
/datum/disease/rhumba_beat/stage_act()
|
||||
..()
|
||||
if(affected_mob.ckey == "rosham")
|
||||
src.cure()
|
||||
cure()
|
||||
return
|
||||
switch(stage)
|
||||
if(2)
|
||||
|
||||
@@ -73,7 +73,6 @@
|
||||
permeability_mod = 1
|
||||
cure_chance = 1
|
||||
disease_flags = CAN_CARRY|CAN_RESIST
|
||||
longevity = 30
|
||||
desc = "Monkeys with this disease will bite humans, causing humans to mutate into a monkey."
|
||||
severity = BIOHAZARD
|
||||
stage_prob = 4
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
/datum/disease/tuberculosis
|
||||
form = "Disease"
|
||||
name = "Fungal tuberculosis"
|
||||
max_stages = 5
|
||||
spread_text = "Airborne"
|
||||
@@ -8,8 +9,9 @@
|
||||
viable_mobtypes = list(/mob/living/carbon/human)
|
||||
cure_chance = 5//like hell are you getting out of hell
|
||||
desc = "A rare highly transmittable virulent virus. Few samples exist, rumoured to be carefully grown and cultured by clandestine bio-weapon specialists. Causes fever, blood vomiting, lung damage, weight loss, and fatigue."
|
||||
required_organs = list(/obj/item/bodypart/head)
|
||||
required_organs = list(/obj/item/organ/lungs)
|
||||
severity = DANGEROUS
|
||||
bypasses_immunity = TRUE // TB primarily impacts the lungs; it's also bacterial or fungal in nature; viral immunity should do nothing.
|
||||
|
||||
/datum/disease/tuberculosis/stage_act() //it begins
|
||||
..()
|
||||
|
||||
@@ -29,6 +29,10 @@
|
||||
destination.dna.temporary_mutations = temporary_mutations.Copy()
|
||||
if(transfer_SE)
|
||||
destination.dna.struc_enzymes = struc_enzymes
|
||||
if(ishuman(destination))
|
||||
var/mob/living/carbon/human/H = destination
|
||||
H.give_genitals(TRUE)//This gives the body the genitals of this DNA. Used for any transformations based on DNA
|
||||
destination.flavor_text = destination.dna.features["flavor_text"] //Update the flavor_text to use new dna text
|
||||
|
||||
/datum/dna/proc/copy_dna(datum/dna/new_dna)
|
||||
new_dna.unique_enzymes = unique_enzymes
|
||||
@@ -228,6 +232,7 @@
|
||||
|
||||
if(newfeatures)
|
||||
dna.features = newfeatures
|
||||
flavor_text = dna.features["flavor_text"] //Update the flavor_text to use new dna text
|
||||
|
||||
if(mrace)
|
||||
set_species(mrace, icon_update=0)
|
||||
@@ -247,6 +252,8 @@
|
||||
dna.struc_enzymes = se
|
||||
domutcheck()
|
||||
|
||||
give_genitals(TRUE)//Give all genitalia that DNA says you should have, remove any pre-existing ones as this is a hardset!
|
||||
|
||||
if(mrace || newfeatures || ui)
|
||||
update_body()
|
||||
update_hair()
|
||||
|
||||
@@ -68,7 +68,7 @@ GLOBAL_LIST_EMPTY(explosions)
|
||||
//I would make this not ex_act the thing that triggered the explosion,
|
||||
//but everything that explodes gives us their loc or a get_turf()
|
||||
//and somethings expect us to ex_act them so they can qdel()
|
||||
stoplag() //tldr, let the calling proc call qdel(src) before we explode
|
||||
sleep(1) //tldr, let the calling proc call qdel(src) before we explode
|
||||
|
||||
EX_PREPROCESS_EXIT_CHECK
|
||||
|
||||
@@ -96,7 +96,9 @@ GLOBAL_LIST_EMPTY(explosions)
|
||||
|
||||
if(!silent)
|
||||
var/frequency = get_rand_frequency()
|
||||
var/ex_sound = get_sfx("explosion")
|
||||
var/sound/explosion_sound = sound(get_sfx("explosion"))
|
||||
var/sound/far_explosion_sound = sound('sound/effects/explosionfar.ogg')
|
||||
|
||||
for(var/mob/M in GLOB.player_list)
|
||||
// Double check for client
|
||||
var/turf/M_turf = get_turf(M)
|
||||
@@ -104,12 +106,12 @@ GLOBAL_LIST_EMPTY(explosions)
|
||||
var/dist = get_dist(M_turf, epicenter)
|
||||
// If inside the blast radius + world.view - 2
|
||||
if(dist <= round(max_range + world.view - 2, 1))
|
||||
M.playsound_local(epicenter, ex_sound, 100, 1, frequency, falloff = 5)
|
||||
M.playsound_local(epicenter, null, 100, 1, frequency, falloff = 5, S = explosion_sound)
|
||||
// You hear a far explosion if you're outside the blast radius. Small bombs shouldn't be heard all over the station.
|
||||
else if(dist <= far_dist)
|
||||
var/far_volume = Clamp(far_dist, 30, 50) // Volume is based on explosion size and dist
|
||||
far_volume += (dist <= far_dist * 0.5 ? 50 : 0) // add 50 volume if the mob is pretty close to the explosion
|
||||
M.playsound_local(epicenter, 'sound/effects/explosionfar.ogg', far_volume, 1, frequency, falloff = 5)
|
||||
M.playsound_local(epicenter, null, far_volume, 1, frequency, falloff = 5, S = far_explosion_sound)
|
||||
EX_PREPROCESS_CHECK_TICK
|
||||
|
||||
//postpone processing for a bit
|
||||
@@ -273,7 +275,7 @@ GLOBAL_LIST_EMPTY(explosions)
|
||||
|
||||
. = list()
|
||||
var/processed = 0
|
||||
while(!stopped && running)
|
||||
while(running)
|
||||
var/I
|
||||
for(I in (processed + 1) to affected_turfs.len) // we cache the explosion block rating of every turf in the explosion area
|
||||
var/turf/T = affected_turfs[I]
|
||||
|
||||
@@ -84,7 +84,7 @@
|
||||
|
||||
/mob/Collide(atom/A)
|
||||
. = ..()
|
||||
if(force_moving && force_moving.allow_climbing && istype(A,/obj/structure))
|
||||
if(force_moving && force_moving.allow_climbing && istype(A, /obj/structure))
|
||||
var/obj/structure/S = A
|
||||
if(S.climbable)
|
||||
S.do_climb(src)
|
||||
|
||||
@@ -73,12 +73,14 @@
|
||||
return ""
|
||||
. = header ? "The following pull requests are currently test merged:<br>" : ""
|
||||
for(var/line in testmerge)
|
||||
var/details
|
||||
var/details
|
||||
if(world.RunningService())
|
||||
var/cm = testmerge[line]["commit"]
|
||||
details = ": '" + html_encode(testmerge[line]["title"]) + "' by " + html_encode(testmerge[line]["author"]) + " at commit " + html_encode(copytext(cm, 1, min(length(cm), 7)))
|
||||
else if(has_pr_details) //tgs2 support
|
||||
details = ": '" + html_encode(testmerge[line]["title"]) + "' by " + html_encode(testmerge[line]["user"]["login"])
|
||||
if(details && findtext(details, "\[s\]") && (!usr || !usr.client.holder))
|
||||
continue
|
||||
. += "<a href=\"[config.githuburl]/pull/[line]\">#[line][details]</a><br>"
|
||||
|
||||
/client/verb/showrevinfo()
|
||||
@@ -96,7 +98,7 @@
|
||||
to_chat(src, "[prefix]<a href=\"[config.githuburl]/commit/[pc]\">[copytext(pc, 1, min(length(pc), 7))]</a>")
|
||||
else
|
||||
to_chat(src, "Revision unknown")
|
||||
to_chat(src, "<b>Current Infomational Settings:</b>")
|
||||
to_chat(src, "<b>Current Informational Settings:</b>")
|
||||
to_chat(src, "Protect Authority Roles From Traitor: [config.protect_roles_from_antagonist]")
|
||||
to_chat(src, "Protect Assistant Role From Traitor: [config.protect_assistant_from_antagonist]")
|
||||
to_chat(src, "Enforce Human Authority: [config.enforce_human_authority]")
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
return isturf(t) ? t : null
|
||||
|
||||
/datum/topic_input/proc/getAtom(i)
|
||||
return getType(i,/atom)
|
||||
return getType(i, /atom)
|
||||
|
||||
/datum/topic_input/proc/getArea(i)
|
||||
var/t = getAndLocate(i)
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
calling_pad.say("Connection failure.")
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
|
||||
testing("Holocall started")
|
||||
|
||||
//cleans up ALL references :)
|
||||
@@ -49,16 +49,16 @@
|
||||
if(user_good)
|
||||
user.reset_perspective()
|
||||
user.remote_control = null
|
||||
|
||||
|
||||
if(!QDELETED(eye))
|
||||
if(user_good && user.client)
|
||||
for(var/datum/camerachunk/chunk in eye.visibleCameraChunks)
|
||||
chunk.remove(eye)
|
||||
qdel(eye)
|
||||
eye = null
|
||||
|
||||
|
||||
user = null
|
||||
|
||||
|
||||
if(hologram)
|
||||
hologram.HC = null
|
||||
hologram = null
|
||||
@@ -75,7 +75,7 @@
|
||||
if(connected_holopad)
|
||||
connected_holopad.SetLightsAndPower()
|
||||
connected_holopad = null
|
||||
|
||||
|
||||
testing("Holocall destroyed")
|
||||
|
||||
return ..()
|
||||
@@ -123,7 +123,7 @@
|
||||
if(I == H)
|
||||
continue
|
||||
Disconnect(I)
|
||||
|
||||
|
||||
for(var/I in H.holo_calls)
|
||||
var/datum/holocall/HC = I
|
||||
if(HC != src)
|
||||
@@ -155,7 +155,7 @@
|
||||
var/obj/machinery/holopad/H = I
|
||||
if(!H.is_operational())
|
||||
ConnectionFailure(H)
|
||||
|
||||
|
||||
if(QDELETED(src))
|
||||
return FALSE
|
||||
|
||||
@@ -174,6 +174,7 @@
|
||||
|
||||
/datum/action/innate/end_holocall
|
||||
name = "End Holocall"
|
||||
icon_icon = 'icons/mob/actions/actions_silicon.dmi'
|
||||
button_icon_state = "camera_off"
|
||||
var/datum/holocall/hcall
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ GLOBAL_LIST_INIT(huds, list(
|
||||
ANTAG_HUD_SINTOUCHED = new/datum/atom_hud/antag/hidden(),
|
||||
ANTAG_HUD_SOULLESS = new/datum/atom_hud/antag/hidden(),
|
||||
ANTAG_HUD_CLOCKWORK = new/datum/atom_hud/antag(),
|
||||
ANTAG_HUD_BORER = new/datum/atom_hud/antag(),
|
||||
))
|
||||
|
||||
/datum/atom_hud
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
var/minetype = "lavaland"
|
||||
|
||||
var/list/transition_config = list(CENTCOMM = SELFLOOPING,
|
||||
var/list/transition_config = list(CENTCOM = SELFLOOPING,
|
||||
MAIN_STATION = CROSSLINKED,
|
||||
EMPTY_AREA_1 = CROSSLINKED,
|
||||
EMPTY_AREA_2 = CROSSLINKED,
|
||||
@@ -115,8 +115,8 @@
|
||||
return UNAFFECTED
|
||||
if("MAIN_STATION")
|
||||
return MAIN_STATION
|
||||
if("CENTCOMM")
|
||||
return CENTCOMM
|
||||
if("CENTCOM")
|
||||
return CENTCOM
|
||||
if("MINING")
|
||||
return MINING
|
||||
if("EMPTY_AREA_1")
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
/datum/action/neck_chop
|
||||
name = "Neck Chop - Injures the neck, stopping the victim from speaking for a while."
|
||||
icon_icon = 'icons/mob/actions/actions_items.dmi'
|
||||
button_icon_state = "neckchop"
|
||||
|
||||
/datum/action/neck_chop/Trigger()
|
||||
@@ -22,6 +23,7 @@
|
||||
|
||||
/datum/action/leg_sweep
|
||||
name = "Leg Sweep - Trips the victim, knocking them down for a brief moment."
|
||||
icon_icon = 'icons/mob/actions/actions_items.dmi'
|
||||
button_icon_state = "legsweep"
|
||||
|
||||
/datum/action/leg_sweep/Trigger()
|
||||
@@ -38,6 +40,7 @@
|
||||
|
||||
/datum/action/lung_punch//referred to internally as 'quick choke'
|
||||
name = "Lung Punch - Delivers a strong punch just above the victim's abdomen, constraining the lungs. The victim will be unable to breathe for a short time."
|
||||
icon_icon = 'icons/mob/actions/actions_items.dmi'
|
||||
button_icon_state = "lungpunch"
|
||||
|
||||
/datum/action/lung_punch/Trigger()
|
||||
|
||||
@@ -186,6 +186,8 @@
|
||||
attack_verb = list("smashed", "slammed", "whacked", "thwacked")
|
||||
icon = 'icons/obj/weapons.dmi'
|
||||
icon_state = "bostaff0"
|
||||
lefthand_file = 'icons/mob/inhands/weapons/staves_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/weapons/staves_righthand.dmi'
|
||||
block_chance = 50
|
||||
|
||||
/obj/item/weapon/twohanded/bostaff/update_icon()
|
||||
|
||||
@@ -73,7 +73,7 @@
|
||||
/datum/material_container/proc/insert_item(obj/item/I, multiplier = 1)
|
||||
if(!I)
|
||||
return 0
|
||||
if(istype(I,/obj/item/stack))
|
||||
if(istype(I, /obj/item/stack))
|
||||
var/obj/item/stack/S = I
|
||||
return insert_stack(I, S.amount)
|
||||
|
||||
|
||||
+17
-15
@@ -120,6 +120,10 @@
|
||||
transfer_martial_arts(new_character)
|
||||
if(active || force_key_move)
|
||||
new_character.key = key //now transfer the key to link the client to our new body
|
||||
if(isliving(new_character)) //New humans and such are by default enabled arousal. Let's always use the new mind's prefs.
|
||||
var/mob/living/L = new_character
|
||||
L.canbearoused = L.client.prefs.arousable //Technically this should make taking over a character mean the body gain the new minds setting...
|
||||
L.update_arousal_hud() //Removes the old icon
|
||||
|
||||
/datum/mind/proc/store_memory(new_text)
|
||||
memory += "[new_text]<BR>"
|
||||
@@ -629,10 +633,11 @@
|
||||
text = "<i><b>[text]</b></i>: "
|
||||
if (ishuman(current))
|
||||
text += "<a href='?src=\ref[src];monkey=healthy'>healthy</a>|<a href='?src=\ref[src];monkey=infected'>infected</a>|<b>HUMAN</b>|other"
|
||||
else if (ismonkey(current))
|
||||
var/found = 0
|
||||
for(var/datum/disease/D in current.viruses)
|
||||
if(istype(D, /datum/disease/transformation/jungle_fever)) found = 1
|
||||
else if(ismonkey(current))
|
||||
var/found = FALSE
|
||||
for(var/datum/disease/transformation/jungle_fever/JF in current.viruses)
|
||||
found = TRUE
|
||||
break
|
||||
|
||||
if(found)
|
||||
text += "<a href='?src=\ref[src];monkey=healthy'>healthy</a>|<b>INFECTED</b>|<a href='?src=\ref[src];monkey=human'>human</a>|other"
|
||||
@@ -1348,7 +1353,8 @@
|
||||
src = M.mind
|
||||
//to_chat(world, "DEBUG: \"healthy\": M=[M], M.mind=[M.mind], src=[src]!")
|
||||
else if (istype(M) && length(M.viruses))
|
||||
for(var/datum/disease/D in M.viruses)
|
||||
for(var/thing in M.viruses)
|
||||
var/datum/disease/D = thing
|
||||
D.cure(0)
|
||||
if("infected")
|
||||
if (check_rights(R_ADMIN, 0))
|
||||
@@ -1368,10 +1374,9 @@
|
||||
var/mob/living/carbon/human/H = current
|
||||
var/mob/living/carbon/monkey/M = current
|
||||
if (istype(M))
|
||||
for(var/datum/disease/D in M.viruses)
|
||||
if (istype(D,/datum/disease/transformation/jungle_fever))
|
||||
D.cure(0)
|
||||
sleep(0) //because deleting of virus is doing throught spawn(0)
|
||||
for(var/datum/disease/transformation/jungle_fever/JF in M.viruses)
|
||||
JF.cure(0)
|
||||
sleep(0) //because deleting of virus is doing throught spawn(0) //What
|
||||
log_admin("[key_name(usr)] attempting to humanize [key_name(current)]")
|
||||
message_admins("<span class='notice'>[key_name_admin(usr)] attempting to humanize [key_name_admin(current)]</span>")
|
||||
H = M.humanize(TR_KEEPITEMS | TR_KEEPIMPLANTS | TR_KEEPORGANS | TR_KEEPDAMAGE | TR_KEEPVIRUS | TR_DEFAULTMSG)
|
||||
@@ -1598,9 +1603,9 @@
|
||||
agent_landmarks.len = 4
|
||||
scientist_landmarks.len = 4
|
||||
for(var/obj/effect/landmark/abductor/A in GLOB.landmarks_list)
|
||||
if(istype(A,/obj/effect/landmark/abductor/agent))
|
||||
if(istype(A, /obj/effect/landmark/abductor/agent))
|
||||
agent_landmarks[text2num(A.team)] = A
|
||||
else if(istype(A,/obj/effect/landmark/abductor/scientist))
|
||||
else if(istype(A, /obj/effect/landmark/abductor/scientist))
|
||||
scientist_landmarks[text2num(A.team)] = A
|
||||
|
||||
var/obj/effect/landmark/L
|
||||
@@ -1689,10 +1694,7 @@
|
||||
|
||||
else
|
||||
mind = new /datum/mind(key)
|
||||
if(SSticker)
|
||||
SSticker.minds += mind
|
||||
else
|
||||
stack_trace("mind_initialize(): No SSticker ready")
|
||||
SSticker.minds += mind
|
||||
if(!mind.name)
|
||||
mind.name = real_name
|
||||
mind.current = src
|
||||
|
||||
@@ -82,7 +82,7 @@
|
||||
id = "derelict4"
|
||||
suffix = "derelict4.dmm"
|
||||
name = "Derelict 4"
|
||||
description = "Centcom ferries have never crashed, will never crash, there is no current investigation into a crashed ferry, and we will not let Internal Affairs trample over high security \
|
||||
description = "CentCom ferries have never crashed, will never crash, there is no current investigation into a crashed ferry, and we will not let Internal Affairs trample over high security \
|
||||
information in the name of this baseless witchhunt."
|
||||
|
||||
/datum/map_template/ruin/space/derelict5
|
||||
|
||||
@@ -133,7 +133,7 @@
|
||||
/datum/map_template/shuttle/emergency/cramped
|
||||
suffix = "cramped"
|
||||
name = "Secure Transport Vessel 5 (STV5)"
|
||||
description = "Well, looks like Centcomm only had this ship in the area, they probably weren't expecting you to need evac for a while. \
|
||||
description = "Well, looks like CentCom only had this ship in the area, they probably weren't expecting you to need evac for a while. \
|
||||
Probably best if you don't rifle around in whatever equipment they were transporting. I hope you're friendly with your coworkers, because there is very little space in this thing.\n\
|
||||
\n\
|
||||
Contains contraband armory guns, maintenance loot, and abandoned crates!"
|
||||
@@ -181,7 +181,7 @@
|
||||
suffix = "supermatter"
|
||||
name = "Hyperfractal Gigashuttle"
|
||||
description = "\"I dunno, this seems kinda needlessly complicated.\"\n\
|
||||
\"This shuttle has very a very high safety record, according to Centcom Officer Cadet Yins.\"\n\
|
||||
\"This shuttle has very a very high safety record, according to CentCom Officer Cadet Yins.\"\n\
|
||||
\"Are you sure?\"\n\
|
||||
\"Yes, it has a safety record of N-A-N, which is apparently larger than 100%.\""
|
||||
admin_notes = "Supermatter that spawns on shuttle is special anchored 'hugbox' supermatter that cannot take damage and does not take in or emit gas. \
|
||||
@@ -215,7 +215,7 @@
|
||||
/datum/map_template/shuttle/ferry/base
|
||||
suffix = "base"
|
||||
name = "transport ferry"
|
||||
description = "Standard issue Box/Metastation Centcom ferry."
|
||||
description = "Standard issue Box/Metastation CentCom ferry."
|
||||
|
||||
/datum/map_template/shuttle/ferry/meat
|
||||
suffix = "meat"
|
||||
@@ -267,7 +267,7 @@
|
||||
|
||||
/datum/map_template/shuttle/emergency/raven
|
||||
suffix = "raven"
|
||||
name = "Centcomm Raven Battlecruiser"
|
||||
description = "The Centcomm Raven Battlecruiser is currently docked at the Centcomm ship bay awaiting a mission, this Battlecruiser has been reassigned as an emergency escape shuttle for currently unknown reasons. The Centcomm Raven Battlecruiser should comfortably fit a medium to large crew size crew and is complete with all required facitlities including a top of the range Centcomm Medical Bay."
|
||||
name = "CentCom Raven Battlecruiser"
|
||||
description = "The CentCom Raven Battlecruiser is currently docked at the CentCom ship bay awaiting a mission, this Battlecruiser has been reassigned as an emergency escape shuttle for currently unknown reasons. The CentCom Raven Battlecruiser should comfortably fit a medium to large crew size crew and is complete with all required facitlities including a top of the range CentCom Medical Bay."
|
||||
admin_notes = "The long way home"
|
||||
credit_cost = 12500
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user