Merge branch 'master' into upstream-merge-29367

This commit is contained in:
LetterJay
2017-07-31 17:19:31 -05:00
committed by GitHub
669 changed files with 9448 additions and 9994 deletions
+1 -1
View File
@@ -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
+96
View File
@@ -0,0 +1,96 @@
#define ACCESS_SECURITY 1 // Security equipment
#define ACCESS_BRIG 2 // Brig timers and permabrig
#define ACCESS_ARMORY 3
#define ACCESS_FORENSICS_LOCKERS 4
#define ACCESS_MEDICAL 5
#define ACCESS_MORGUE 6
#define ACCESS_TOX 7
#define ACCESS_TOX_STORAGE 8
#define ACCESS_GENETICS 9
#define ACCESS_ENGINE 10
#define ACCESS_ENGINE_EQUIP 11
#define ACCESS_MAINT_TUNNELS 12
#define ACCESS_EXTERNAL_AIRLOCKS 13
#define ACCESS_EMERGENCY_STORAGE 14
#define ACCESS_CHANGE_IDS 15
#define ACCESS_AI_UPLOAD 16
#define ACCESS_TELEPORTER 17
#define ACCESS_EVA 18
#define ACCESS_HEADS 19
#define ACCESS_CAPTAIN 20
#define ACCESS_ALL_PERSONAL_LOCKERS 21
#define ACCESS_CHAPEL_OFFICE 22
#define ACCESS_TECH_STORAGE 23
#define ACCESS_ATMOSPHERICS 24
#define ACCESS_BAR 25
#define ACCESS_JANITOR 26
#define ACCESS_CREMATORIUM 27
#define ACCESS_KITCHEN 28
#define ACCESS_ROBOTICS 29
#define ACCESS_RD 30
#define ACCESS_CARGO 31
#define ACCESS_CONSTRUCTION 32
#define ACCESS_CHEMISTRY 33
#define ACCESS_CARGO_BOT 34
#define ACCESS_HYDROPONICS 35
#define ACCESS_MANUFACTURING 36
#define ACCESS_LIBRARY 37
#define ACCESS_LAWYER 38
#define ACCESS_VIROLOGY 39
#define ACCESS_CMO 40
#define ACCESS_QM 41
#define ACCESS_COURT 42
#define ACCESS_SURGERY 45
#define ACCESS_THEATRE 46
#define ACCESS_RESEARCH 47
#define ACCESS_MINING 48
#define ACCESS_MINING_OFFICE 49 //not in use
#define ACCESS_MAILSORTING 50
#define ACCESS_MINT 51
#define ACCESS_MINT_VAULT 52
#define ACCESS_HEADS_VAULT 53
#define ACCESS_MINING_STATION 54
#define ACCESS_XENOBIOLOGY 55
#define ACCESS_CE 56
#define ACCESS_HOP 57
#define ACCESS_HOS 58
#define ACCESS_RC_ANNOUNCE 59 //Request console announcements
#define ACCESS_KEYCARD_AUTH 60 //Used for events which require at least two people to confirm them
#define ACCESS_TCOMSAT 61 // has access to the entire telecomms satellite / machinery
#define ACCESS_GATEWAY 62
#define ACCESS_SEC_DOORS 63 // Security front doors
#define ACCESS_MINERAL_STOREROOM 64
#define ACCESS_MINISAT 65
#define ACCESS_WEAPONS 66 //Weapon authorization for secbots
#define ACCESS_NETWORK 67
#define ACCESS_CLONING 68 //Cloning room
//BEGIN CENTCOM ACCESS
/*Should leave plenty of room if we need to add more access levels.
Mostly for admin fun times.*/
#define ACCESS_CENT_GENERAL 101//General facilities.
#define ACCESS_CENT_THUNDER 102//Thunderdome.
#define ACCESS_CENT_SPECOPS 103//Special Ops.
#define ACCESS_CENT_MEDICAL 104//Medical/Research
#define ACCESS_CENT_LIVING 105//Living quarters.
#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
//The Syndicate
#define ACCESS_SYNDICATE 150//General Syndicate Access
#define ACCESS_SYNDICATE_LEADER 151//Nuke Op Leader Access
//Away Missions or Ruins
/*For generic away-mission/ruin access. Why would normal crew have access to a long-abandoned derelict
or a 2000 year-old temple? */
#define ACCESS_AWAY_GENERAL 200//General facilities.
#define ACCESS_AWAY_MAINT 201//Away maintenance
#define ACCESS_AWAY_MED 202//Away medical
#define ACCESS_AWAY_SEC 203//Away security
#define ACCESS_AWAY_ENGINE 204//Away engineering
#define ACCESS_AWAY_GENERIC1 205//Away generic access
#define ACCESS_AWAY_GENERIC2 206
#define ACCESS_AWAY_GENERIC3 207
#define ACCESS_AWAY_GENERIC4 208
+2 -2
View File
@@ -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
+147 -144
View File
@@ -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
+9
View File
@@ -0,0 +1,9 @@
diff a/code/__DEFINES/combat.dm b/code/__DEFINES/combat.dm (rejected hunks)
@@ -9,6 +9,7 @@
#define OXY "oxy"
#define CLONE "clone"
#define STAMINA "stamina"
+#define BRAIN "brain"
//bitflag damage defines used for suicide_act
#define BRUTELOSS 1
+16
View File
@@ -0,0 +1,16 @@
//shorthand
#define GET_COMPONENT_FROM(varname, path, target) var##path/##varname = ##target.GetComponent(##path)
#define GET_COMPONENT(varname, path) GET_COMPONENT_FROM(varname, path, src)
// How multiple components of the exact same type are handled in the same datum
#define COMPONENT_DUPE_HIGHLANDER 0 //old component is deleted (default)
#define COMPONENT_DUPE_ALLOWED 1 //duplicates allowed
#define COMPONENT_DUPE_UNIQUE 2 //new component is deleted
// All signals. Format:
// When the signal is called: (signal arguments)
#define COMSIG_COMPONENT_ADDED "component_added" //when a component is added to a datum: (datum/component)
#define COMSIG_COMPONENT_REMOVING "component_removing" //before a component is removed from a datum because of RemoveComponent: (datum/component)
#define COMSIG_PARENT_QDELETED "parent_qdeleted" //before a datum's Destroy() is called: ()
+1
View File
@@ -89,5 +89,6 @@ GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 204
#define UNACIDABLE 16 //acid can't even appear on it, let alone melt it.
#define ACID_PROOF 32 //acid stuck on it doesn't melt it.
#define INDESTRUCTIBLE 64 //doesn't take damage
#define FREEZE_PROOF 128 //can't be frozen
// language secondary flags for atoms
+2 -2
View File
@@ -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)
@@ -23,7 +23,7 @@
#define ismineralturf(A) (istype(A, /turf/closed/mineral))
#define islava(A) (istype(A, /turf/open/floor/plating/lava))
#define islava(A) (istype(A, /turf/open/lava))
//Mobs
#define isliving(A) (istype(A, /mob/living))
+12 -11
View File
@@ -1,18 +1,19 @@
//Investigate logging defines
#define INVESTIGATE_ATMOS "atmos"
#define INVESTIGATE_BOTANY "botany"
#define INVESTIGATE_CARGO "cargo"
#define INVESTIGATE_EXPERIMENTOR "experimentor"
#define INVESTIGATE_GRAVITY "gravity"
#define INVESTIGATE_RECORDS "records"
#define INVESTIGATE_SINGULO "singulo"
#define INVESTIGATE_SUPERMATTER "supermatter"
#define INVESTIGATE_TELESCI "telesci"
#define INVESTIGATE_WIRES "wires"
#define INVESTIGATE_ATMOS "atmos"
#define INVESTIGATE_BOTANY "botany"
#define INVESTIGATE_CARGO "cargo"
#define INVESTIGATE_EXPERIMENTOR "experimentor"
#define INVESTIGATE_GRAVITY "gravity"
#define INVESTIGATE_RECORDS "records"
#define INVESTIGATE_SINGULO "singulo"
#define INVESTIGATE_SUPERMATTER "supermatter"
#define INVESTIGATE_TELESCI "telesci"
#define INVESTIGATE_WIRES "wires"
#define INVESTIGATE_PORTAL "portals"
//Individual logging defines
#define INDIVIDUAL_ATTACK_LOG "Attack log"
#define INDIVIDUAL_SAY_LOG "Say log"
#define INDIVIDUAL_EMOTE_LOG "Emote log"
#define INDIVIDUAL_OOC_LOG "OOC log"
#define INDIVIDUAL_SHOW_ALL_LOG "All logs"
#define INDIVIDUAL_SHOW_ALL_LOG "All logs"
-4
View File
@@ -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).
+1 -1
View File
@@ -43,7 +43,7 @@
#define BODYPART_ROBOTIC 2
#define DEFAULT_BODYPART_ICON_ORGANIC 'icons/mob/human_parts_greyscale.dmi'
#define DEFAULT_BODYPART_ICON_ROBOTIC 'icons/mob/augments.dmi'
#define DEFAULT_BODYPART_ICON_ROBOTIC 'icons/mob/augmentation/augments.dmi'
#define MONKEY_BODYPART "monkey"
#define ALIEN_BODYPART "alien"
+7 -1
View File
@@ -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
+51
View File
@@ -0,0 +1,51 @@
diff a/code/__DEFINES/sound.dm b/code/__DEFINES/sound.dm (rejected hunks)
@@ -5,42 +5,15 @@
#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
//THIS SHOULD ALWAYS BE THE LOWEST ONE!
//KEEP IT UPDATED
-#define CHANNEL_HIGHEST_AVAILABLE 1018
+#define CHANNEL_HIGHEST_AVAILABLE 1015
#define SOUND_MINIMUM_PRESSURE 10
-#define FALLOFF_SOUNDS 0.5
-
-//BYOND Sound Environment defines
-
-#define SOUND_ENV_DEFAULT -1
-#define SOUND_ENV_GENERIC 0
-#define SOUND_ENV_PADDED_CELL 1
-#define SOUND_ENV_ROOM 2
-#define SOUND_ENV_BATHROOM 3
-#define SOUND_ENV_LIVINGROOM 4
-#define SOUND_ENV_STONEROOM 5
-#define SOUND_ENV_AUDITORIUM 6
-#define SOUND_ENV_CONCERT_HALL 7
-#define SOUND_ENV_CAVE 8
-#define SOUND_ENV_ARENA 9
-#define SOUND_ENV_HANGAR 10
-#define SOUND_ENV_CARPETTED_HALLWAY 11
-#define SOUND_ENV_HALLWAY 12
-#define SOUND_ENV_STONE_CORRIDOOR 13
-#define SOUND_ENV_ALLEY 14
-#define SOUND_ENV_FOREST 15
-#define SOUND_ENV_CITY 16
-#define SOUND_ENV_MOUNTAINS 17
-#define SOUND_ENV_QUARRY 18
-#define SOUND_ENV_PLAIN 19
-#define SOUND_ENV_PARKING_LOT 20
-#define SOUND_ENV_SEWER_PIPE 21
-#define SOUND_ENV_UNDERWATER 22
-#define SOUND_ENV_DRUGGED 23
-#define SOUND_ENV_DIZZY 24
-#define SOUND_ENV_PSYCHOTIC 25
\ No newline at end of file
+#define FALLOFF_SOUNDS 0.5
\ No newline at end of file
+1 -1
View File
@@ -88,7 +88,7 @@
L -= V //No return here so that it removes all strings of that type
return
//returns a new list with only atoms that are in typecache L
/proc/typecache_filter_list(list/atoms, list/typecache)
. = list()
for (var/thing in atoms)
-23
View File
@@ -1,23 +0,0 @@
diff a/code/__HELPERS/_lists.dm b/code/__HELPERS/_lists.dm (rejected hunks)
@@ -89,12 +89,18 @@
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=FALSE)
+/proc/typecache_filter_list(list/atoms, list/typecache)
. = list()
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
//Like typesof() or subtypesof(), but returns a typecache instead of a list
+2
View File
@@ -974,6 +974,8 @@ GLOBAL_LIST_EMPTY(friendly_animal_types)
/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
+1
View File
@@ -7,6 +7,7 @@ GLOBAL_VAR(join_motd)
GLOBAL_VAR(station_name)
GLOBAL_VAR_INIT(game_version, "/tg/ Station 13")
GLOBAL_VAR_INIT(changelog_hash, "")
GLOBAL_VAR_INIT(hub_visibility, FALSE)
GLOBAL_VAR_INIT(ooc_allowed, TRUE) // used with admin verbs to disable ooc - not a config option apparently
GLOBAL_VAR_INIT(dooc_allowed, TRUE)
+2
View File
@@ -23,3 +23,5 @@ GLOBAL_LIST_EMPTY(simple_animals)
GLOBAL_LIST_EMPTY(language_datum_instances)
GLOBAL_LIST_EMPTY(all_languages)
GLOBAL_LIST_EMPTY(latejoiners) //All latejoining people, for traitor-target purposes.
+1 -1
View File
@@ -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)
+13 -3
View File
@@ -13,17 +13,21 @@
if(modifiers["shift"])
moved = 0
usr.update_action_buttons() //redraw buttons that are no longer considered "moved"
return 1
return TRUE
if(modifiers["ctrl"])
locked = !locked
to_chat(usr, "<span class='notice'>Action button \"[name]\" [locked ? "" : "un"]locked.</span>")
return TRUE
if(usr.next_click > world.time)
return
usr.next_click = world.time + 1
linked_action.Trigger()
return 1
return TRUE
//Hide/Show Action Buttons ... Button
/obj/screen/movable/action_button/hide_toggle
name = "Hide Buttons"
desc = "Shift-click any button to reset its position. Alt-click to reset all buttons to their default positions."
desc = "Shift-click any button to reset its position, and Control-click it to lock it in place. Alt-click this button to reset all buttons to their default positions."
icon = 'icons/mob/actions.dmi'
icon_state = "bg_default"
var/hidden = 0
@@ -37,11 +41,17 @@
moved = FALSE
usr.update_action_buttons(TRUE)
return TRUE
if(modifiers["ctrl"])
locked = !locked
to_chat(usr, "<span class='notice'>Action button \"[name]\" [locked ? "" : "un"]locked.</span>")
return TRUE
if(modifiers["alt"])
for(var/V in usr.actions)
var/datum/action/A = V
var/obj/screen/movable/action_button/B = A.button
B.moved = FALSE
B.locked = usr.client.prefs.buttons_locked
locked = usr.client.prefs.buttons_locked
moved = FALSE
usr.update_action_buttons(TRUE)
to_chat(usr, "<span class='notice'>Action button positions have been reset.</span>")
+16 -8
View File
@@ -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
+2
View File
@@ -58,6 +58,8 @@
hide_actions_toggle = new
hide_actions_toggle.InitialiseIcon(src)
if(mymob.client)
hide_actions_toggle.locked = mymob.client.prefs.buttons_locked
hand_slots = list()
+1 -1
View File
@@ -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()
@@ -11,6 +11,7 @@
/obj/screen/movable
var/snap2grid = FALSE
var/moved = FALSE
var/locked = FALSE
//Snap Screen Object
//Tied to the grid, snaps to the nearest turf
@@ -20,6 +21,8 @@
/obj/screen/movable/MouseDrop(over_object, src_location, over_location, src_control, over_control, params)
if(locked) //no! I am locked! begone!
return
var/list/PM = params2list(params)
//No screen-loc information? abort.
+3 -3
View File
@@ -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)
@@ -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()
+3
View File
@@ -0,0 +1,3 @@
//Disables the custom emote blacklist from TG that normally applies to slimes.
/datum/emote/living/custom
mob_type_blacklist_typecache = list(/mob/living/brain)
+10
View File
@@ -3,6 +3,8 @@
name = "Semen"
id = "semen"
description = "Sperm from some animal. Useless for anything but insemination, really."
taste_description = "something salty"
taste_mult = 2 //Not very overpowering flavor
data = list("donor"=null,"viruses"=null,"donor_DNA"=null,"blood_type"=null,"resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null)
reagent_state = LIQUID
color = "#FFFFFF" // rgb: 255, 255, 255
@@ -44,6 +46,8 @@
name = "Female Ejaculate"
id = "femcum"
description = "Vaginal lubricant found in most mammals and other animals of similar nature. Where you found this is your own business."
taste_description = "female arousal"
taste_mult = 2
data = list("donor"=null,"viruses"=null,"donor_DNA"=null,"blood_type"=null,"resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null)
reagent_state = LIQUID
color = "#AAAAAA77"
@@ -90,6 +94,8 @@
name = "Crocin"
id = "aphro"
description = "Naturally found in the crocus and gardenia flowers, this drug acts as a natural and safe aphrodisiac."
taste_description = "strawberry roofies"
taste_mult = 2 //Hide the roofies in stronger flavors
color = "#FFADFF"//PINK, rgb(255, 173, 255)
/datum/reagent/aphrodisiac/on_mob_life(mob/living/M)
@@ -108,6 +114,7 @@
description = "Chemically condensed form of basic crocin. This aphrodisiac is extremely powerful and addictive in most animals.\
Addiction withdrawals can cause brain damage and shortness of breath. Overdosage can lead to brain damage and a\
permanent increase in libido (commonly referred to as 'bimbofication')."
taste_description = "liquid desire"
color = "#FF2BFF"//dark pink
addiction_threshold = 20
overdose_threshold = 20
@@ -158,6 +165,8 @@
id = "anaphro"
description = "Naturally found in some species of evergreen trees, camphor is a waxy substance. When injested by most animals, it acts as an anaphrodisiac\
, reducing libido and calming them. Non-habit forming and not addictive."
taste_description = "dull bitterness"
taste_mult = 2
color = "#D9D9D9"//rgb(217, 217, 217)
reagent_state = SOLID
@@ -170,6 +179,7 @@
name = "Hexacamphor"
id = "anaphro+"
description = "Chemically condensed camphor. Causes an extreme reduction in libido and a permanent one if overdosed. Non-addictive."
taste_description = "tranquil celibacy"
color = "#D9D9D9"//rgb(217, 217, 217)
reagent_state = SOLID
overdose_threshold = 20
+12 -9
View File
@@ -52,15 +52,18 @@ GLOBAL_REAL(GLOB, /datum/controller/global_vars)
/datum/controller/global_vars/Initialize()
gvars_datum_init_order = list()
gvars_datum_protected_varlist = list("gvars_datum_protected_varlist")
//See https://github.com/tgstation/tgstation/issues/26954
for(var/I in typesof(/datum/controller/global_vars/proc))
var/CLEANBOT_RETURNS = "[I]"
pass(CLEANBOT_RETURNS)
for(var/I in vars - gvars_datum_in_built_vars)
var/list/global_procs = typesof(/datum/controller/global_vars/proc)
var/expected_len = vars.len - gvars_datum_in_built_vars.len
if(global_procs.len != expected_len)
warning("Unable to detect all global initialization procs! Expected [expected_len] got [global_procs.len]!")
if(global_procs.len)
var/list/expected_global_procs = vars - gvars_datum_in_built_vars
for(var/I in global_procs)
expected_global_procs -= replacetext("[I]", "InitGlobal", "")
log_world("Missing procs: [expected_global_procs.Join(", ")]")
for(var/I in global_procs)
var/start_tick = world.time
call(src, "InitGlobal[I]")()
call(src, I)()
var/end_tick = world.time
if(end_tick - start_tick)
warning("Global [I] slept during initialization!")
warning("Global [replacetext("[I]", "InitGlobal", "")] slept during initialization!")
+1 -1
View File
@@ -111,7 +111,7 @@ SUBSYSTEM_DEF(events)
/area/crew_quarters/heads/chief)
//Need to locate() as it's just a list of paths.
return locate(pick((GLOB.the_station_areas - safe_areas) + danger_areas))
return locate(pick((GLOB.the_station_areas - safe_areas) + danger_areas)) in GLOB.sortedAreas
//allows a client to trigger an event
+3
View File
@@ -189,6 +189,7 @@ SUBSYSTEM_DEF(garbage)
SSgarbage.qdel_list += "[D.type]"
#endif
if(isnull(D.gc_destroyed))
D.SendSignal(COMSIG_PARENT_QDELETED)
D.gc_destroyed = GC_CURRENTLY_BEING_QDELETED
var/start_time = world.time
var/hint = D.Destroy(force) // Let our friend know they're about to get fucked up.
@@ -236,6 +237,7 @@ SUBSYSTEM_DEF(garbage)
// 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
@@ -245,6 +247,7 @@ SUBSYSTEM_DEF(garbage)
if (timer.spent)
continue
qdel(timer)
QDEL_LIST(datum_components)
return QDEL_HINT_QUEUE
/datum/var/gc_destroyed //Time when this object was destroyed.
+4 -4
View File
@@ -10,11 +10,11 @@ SUBSYSTEM_DEF(pai)
/datum/controller/subsystem/pai/Topic(href, href_list[])
if(href_list["download"])
var/datum/paiCandidate/candidate = locate(href_list["candidate"])
var/obj/item/device/paicard/card = locate(href_list["device"])
var/datum/paiCandidate/candidate = locate(href_list["candidate"]) in candidates
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)
@@ -34,7 +34,7 @@ SUBSYSTEM_DEF(pai)
usr << browse(null, "window=findPai")
if(href_list["new"])
var/datum/paiCandidate/candidate = locate(href_list["candidate"])
var/datum/paiCandidate/candidate = locate(href_list["candidate"]) in candidates
var/option = href_list["option"]
var/t = ""
+2 -2
View File
@@ -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
@@ -4,7 +4,7 @@ PROCESSING_SUBSYSTEM_DEF(overlays)
wait = 1
priority = 500
init_order = INIT_ORDER_OVERLAY
runlevels = RUNLEVELS_DEFAULT | RUNLEVEL_SETUP
runlevels = RUNLEVELS_DEFAULT | RUNLEVEL_SETUP
stat_tag = "Ov"
currentrun = null
+1 -1
View File
@@ -11,7 +11,7 @@ SUBSYSTEM_DEF(server_maint)
/datum/controller/subsystem/server_maint/Initialize(timeofday)
if (config.hub)
world.visibility = 1
world.update_hub_visibility(TRUE)
..()
/datum/controller/subsystem/server_maint/fire(resumed = FALSE)
+4 -1
View File
@@ -219,6 +219,9 @@ SUBSYSTEM_DEF(shuttle)
emergency.request(null, signal_origin, html_decode(emergency_reason), 0)
log_game("[key_name(user)] has called the shuttle.")
if(call_reason)
SSblackbox.add_details("shuttle_reason", call_reason)
log_game("Shuttle call reason: [call_reason]")
message_admins("[key_name_admin(user)] has called the shuttle. (<A HREF='?_src_=holder;trigger_centcom_recall=1'>TRIGGER CENTCOM RECALL</A>)")
/datum/controller/subsystem/shuttle/proc/centcom_recall(old_timer, admiral_message)
@@ -540,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))
+13 -8
View File
@@ -1,5 +1,6 @@
#define BUCKET_LEN (world.fps*1*60) //how many ticks should we keep in the bucket. (1 minutes worth)
#define BUCKET_POS(timer) (round((timer.timeToRun - SStimer.head_offset) / world.tick_lag) + 1)
#define TIMER_ID_MAX (2**24) //max float with integer precision
SUBSYSTEM_DEF(timer)
name = "Timer"
@@ -225,18 +226,23 @@ SUBSYSTEM_DEF(timer)
var/static/nextid = 1
/datum/timedevent/New(datum/callback/callBack, timeToRun, flags, hash)
id = nextid++
id = TIMER_ID_NULL
src.callBack = callBack
src.timeToRun = timeToRun
src.flags = flags
src.hash = hash
name = "Timer: [id]: TTR: [timeToRun], Flags: [jointext(bitfield2list(flags, list("TIMER_UNIQUE", "TIMER_OVERRIDE", "TIMER_CLIENT_TIME", "TIMER_STOPPABLE", "TIMER_NO_HASH_WAIT")), ", ")], callBack: \ref[callBack], callBack.object: [callBack.object]\ref[callBack.object]([getcallingtype()]), callBack.delegate:[callBack.delegate]([callBack.arguments ? callBack.arguments.Join(", ") : ""])"
if (flags & TIMER_UNIQUE)
SStimer.hashes[hash] = src
if (flags & TIMER_STOPPABLE)
SStimer.timer_id_dict["timerid[id]"] = src
do
if (nextid >= TIMER_ID_MAX)
nextid = 1
id = nextid++
while(SStimer.timer_id_dict["timerid" + num2text(id, 8)])
SStimer.timer_id_dict["timerid" + num2text(id, 8)] = src
name = "Timer: " + num2text(id, 8) + ", TTR: [timeToRun], Flags: [jointext(bitfield2list(flags, list("TIMER_UNIQUE", "TIMER_OVERRIDE", "TIMER_CLIENT_TIME", "TIMER_STOPPABLE", "TIMER_NO_HASH_WAIT")), ", ")], callBack: \ref[callBack], callBack.object: [callBack.object]\ref[callBack.object]([getcallingtype()]), callBack.delegate:[callBack.delegate]([callBack.arguments ? callBack.arguments.Join(", ") : ""])"
if (callBack.object != GLOBAL_PROC)
LAZYADD(callBack.object.active_timers, src)
@@ -297,7 +303,7 @@ SUBSYSTEM_DEF(timer)
callBack = null
if (flags & TIMER_STOPPABLE)
SStimer.timer_id_dict -= "timerid[id]"
SStimer.timer_id_dict -= "timerid" + num2text(id, 8)
if (flags & TIMER_CLIENT_TIME)
SStimer.clienttime_timers -= src
@@ -378,9 +384,7 @@ SUBSYSTEM_DEF(timer)
timeToRun = REALTIMEOFDAY + wait
var/datum/timedevent/timer = new(callback, timeToRun, flags, hash)
if (flags & TIMER_STOPPABLE)
return timer.id
return TIMER_ID_NULL
return timer.id
/proc/deltimer(id)
if (!id)
@@ -391,6 +395,7 @@ SUBSYSTEM_DEF(timer)
if (istype(id, /datum/timedevent))
qdel(id)
return TRUE
//id is string
var/datum/timedevent/timer = SStimer.timer_id_dict["timerid[id]"]
if (timer && !timer.spent)
qdel(timer)
+2
View File
@@ -45,6 +45,7 @@
M.actions += src
if(M.client)
M.client.screen += button
button.locked = M.client.prefs.buttons_locked
M.update_action_buttons()
else
Remove(owner)
@@ -57,6 +58,7 @@
M.update_action_buttons()
owner = null
button.moved = FALSE //so the button appears in its normal position when given to another owner.
button.locked = FALSE
/datum/action/proc/Trigger()
if(!IsAvailable())
@@ -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_)
+15 -4
View File
@@ -172,10 +172,16 @@
objective_count += forge_single_objective()
for(var/i = objective_count, i < config.traitor_objectives_amount, i++)
var/datum/objective/assassinate/kill_objective = new
kill_objective.owner = owner
kill_objective.find_target()
add_objective(kill_objective)
if(prob(20)) //AI's are less likely to look for a late-joiner than normal traitors
var/datum/objective/assassinate/late/late_objective = new
late_objective.owner = owner
late_objective.find_target()
add_objective(late_objective)
else
var/datum/objective/assassinate/kill_objective = new
kill_objective.owner = owner
kill_objective.find_target()
add_objective(kill_objective)
var/datum/objective/survive/survive_objective = new
survive_objective.owner = owner
@@ -196,6 +202,11 @@
maroon_objective.owner = owner
maroon_objective.find_target()
add_objective(maroon_objective)
else if(prob(50))
var/datum/objective/assassinate/late/late_objective = new
late_objective.owner = owner
late_objective.find_target()
add_objective(late_objective)
else
var/datum/objective/assassinate/kill_objective = new
kill_objective.owner = owner
+97
View File
@@ -0,0 +1,97 @@
/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
/datum/component/New(datum/P, ...)
var/dm = dupe_mode
if(dm != COMPONENT_DUPE_ALLOWED)
var/datum/component/old = P.GetExactComponent(type)
if(old)
switch(dm)
if(COMPONENT_DUPE_HIGHLANDER)
P.RemoveComponent(old)
old = null //in case SendSignal() blocks
if(COMPONENT_DUPE_UNIQUE)
qdel(src)
return
P.SendSignal(COMSIG_COMPONENT_ADDED, list(src), FALSE)
LAZYADD(P.datum_components, src)
parent = P
/datum/component/Destroy()
RemoveNoSignal()
return ..()
/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)
var/list/procs = signal_procs
if(!procs)
procs = list()
signal_procs = procs
if(!override)
. = procs[sig_type]
if(.)
stack_trace("[sig_type] overridden. Use override = TRUE to suppress this warning")
procs[sig_type] = CALLBACK(src, proc_on_self)
/datum/var/list/datum_components //list of /datum/component
// Send a signal to all other components in the container.
/datum/proc/SendSignal(sigtype, list/sig_args, async = FALSE)
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)
/datum/proc/GetComponent(c_type)
for(var/I in datum_components)
if(istype(I, c_type))
return I
/datum/proc/GetExactComponent(c_type)
for(var/I in datum_components)
var/datum/component/C = I
if(C.type == c_type)
return I
/datum/proc/GetComponents(c_type)
. = list()
for(var/I in datum_components)
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)
if(!C)
return
C.RemoveNoSignal()
SendSignal(COMSIG_COMPONENT_REMOVING, list(C), FALSE)
qdel(C)
+27 -27
View File
@@ -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>"
@@ -485,7 +485,7 @@
if(!check_rights(0))
return
var/mob/M = locate(href_list["mob_player_panel"])
var/mob/M = locate(href_list["mob_player_panel"]) in GLOB.mob_list
if(!istype(M))
to_chat(usr, "This can only be used on instances of type /mob")
return
@@ -497,7 +497,7 @@
if(!check_rights(R_ADMIN))
return
var/mob/M = locate(href_list["godmode"])
var/mob/M = locate(href_list["godmode"]) in GLOB.mob_list
if(!istype(M))
to_chat(usr, "This can only be used on instances of type /mob")
return
@@ -540,7 +540,7 @@
if(!check_rights(0))
return
var/mob/M = locate(href_list["regenerateicons"])
var/mob/M = locate(href_list["regenerateicons"]) in GLOB.mob_list
if(!ismob(M))
to_chat(usr, "This can only be done to instances of type /mob")
return
@@ -557,7 +557,7 @@
if(!check_rights(0))
return
var/mob/M = locate(href_list["rename"])
var/mob/M = locate(href_list["rename"]) in GLOB.mob_list
if(!istype(M))
to_chat(usr, "This can only be used on instances of type /mob")
return
@@ -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
@@ -705,7 +705,7 @@
if(!check_rights(0))
return
var/mob/M = locate(href_list["give_spell"])
var/mob/M = locate(href_list["give_spell"]) in GLOB.mob_list
if(!istype(M))
to_chat(usr, "This can only be used on instances of type /mob")
return
@@ -717,7 +717,7 @@
if(!check_rights(0))
return
var/mob/M = locate(href_list["remove_spell"])
var/mob/M = locate(href_list["remove_spell"]) in GLOB.mob_list
if(!istype(M))
to_chat(usr, "This can only be used on instances of type /mob")
return
@@ -729,7 +729,7 @@
if(!check_rights(0))
return
var/mob/M = locate(href_list["give_disease"])
var/mob/M = locate(href_list["give_disease"]) in GLOB.mob_list
if(!istype(M))
to_chat(usr, "This can only be used on instances of type /mob")
return
@@ -741,7 +741,7 @@
if(!check_rights(R_FUN))
return
var/mob/M = locate(href_list["gib"])
var/mob/M = locate(href_list["gib"]) in GLOB.mob_list
if(!istype(M))
to_chat(usr, "This can only be used on instances of type /mob")
return
@@ -752,7 +752,7 @@
if(!check_rights(R_BUILDMODE))
return
var/mob/M = locate(href_list["build_mode"])
var/mob/M = locate(href_list["build_mode"]) in GLOB.mob_list
if(!istype(M))
to_chat(usr, "This can only be used on instances of type /mob")
return
@@ -764,7 +764,7 @@
if(!check_rights(0))
return
var/mob/M = locate(href_list["drop_everything"])
var/mob/M = locate(href_list["drop_everything"]) in GLOB.mob_list
if(!istype(M))
to_chat(usr, "This can only be used on instances of type /mob")
return
@@ -776,7 +776,7 @@
if(!check_rights(0))
return
var/mob/M = locate(href_list["direct_control"])
var/mob/M = locate(href_list["direct_control"]) in GLOB.mob_list
if(!istype(M))
to_chat(usr, "This can only be used on instances of type /mob")
return
@@ -788,7 +788,7 @@
if(!check_rights(0))
return
var/mob/M = locate(href_list["offer_control"])
var/mob/M = locate(href_list["offer_control"]) in GLOB.mob_list
if(!istype(M))
to_chat(usr, "This can only be used on instances of type /mob")
return
@@ -921,7 +921,7 @@
if(!check_rights(0))
return
var/mob/living/carbon/C = locate(href_list["editorgans"])
var/mob/living/carbon/C = locate(href_list["editorgans"]) in GLOB.mob_list
if(!istype(C))
to_chat(usr, "This can only be done to instances of type /mob/living/carbon")
return
@@ -933,7 +933,7 @@
if(!check_rights(R_SPAWN))
return
var/mob/living/carbon/monkey/Mo = locate(href_list["makehuman"])
var/mob/living/carbon/monkey/Mo = locate(href_list["makehuman"]) in GLOB.mob_list
if(!istype(Mo))
to_chat(usr, "This can only be done to instances of type /mob/living/carbon/monkey")
return
@@ -949,7 +949,7 @@
if(!check_rights(R_SPAWN))
return
var/mob/living/carbon/human/H = locate(href_list["makemonkey"])
var/mob/living/carbon/human/H = locate(href_list["makemonkey"]) in GLOB.mob_list
if(!istype(H))
to_chat(usr, "This can only be done to instances of type /mob/living/carbon/human")
return
@@ -965,7 +965,7 @@
if(!check_rights(R_SPAWN))
return
var/mob/living/carbon/human/H = locate(href_list["makerobot"])
var/mob/living/carbon/human/H = locate(href_list["makerobot"]) in GLOB.mob_list
if(!istype(H))
to_chat(usr, "This can only be done to instances of type /mob/living/carbon/human")
return
@@ -981,7 +981,7 @@
if(!check_rights(R_SPAWN))
return
var/mob/living/carbon/human/H = locate(href_list["makealien"])
var/mob/living/carbon/human/H = locate(href_list["makealien"]) in GLOB.mob_list
if(!istype(H))
to_chat(usr, "This can only be done to instances of type /mob/living/carbon/human")
return
@@ -997,7 +997,7 @@
if(!check_rights(R_SPAWN))
return
var/mob/living/carbon/human/H = locate(href_list["makeslime"])
var/mob/living/carbon/human/H = locate(href_list["makeslime"]) in GLOB.mob_list
if(!istype(H))
to_chat(usr, "This can only be done to instances of type /mob/living/carbon/human")
return
@@ -1013,7 +1013,7 @@
if(!check_rights(R_SPAWN))
return
var/mob/living/carbon/H = locate(href_list["makeai"])
var/mob/living/carbon/H = locate(href_list["makeai"]) in GLOB.mob_list
if(!istype(H))
to_chat(usr, "This can only be done to instances of type /mob/living/carbon")
return
@@ -1029,7 +1029,7 @@
if(!check_rights(R_SPAWN))
return
var/mob/living/carbon/human/H = locate(href_list["setspecies"])
var/mob/living/carbon/human/H = locate(href_list["setspecies"]) in GLOB.mob_list
if(!istype(H))
to_chat(usr, "This can only be done to instances of type /mob/living/carbon/human")
return
@@ -1049,7 +1049,7 @@
if(!check_rights(R_SPAWN))
return
var/mob/living/carbon/C = locate(href_list["editbodypart"])
var/mob/living/carbon/C = locate(href_list["editbodypart"]) in GLOB.mob_list
if(!istype(C))
to_chat(usr, "This can only be done to instances of type /mob/living/carbon")
return
@@ -1095,7 +1095,7 @@
if(!check_rights(R_SPAWN))
return
var/mob/living/carbon/human/H = locate(href_list["purrbation"])
var/mob/living/carbon/human/H = locate(href_list["purrbation"]) in GLOB.mob_list
if(!istype(H))
to_chat(usr, "This can only be done to instances of type /mob/living/carbon/human")
return
@@ -1126,7 +1126,7 @@
if(!check_rights(0))
return
var/mob/living/L = locate(href_list["mobToDamage"])
var/mob/living/L = locate(href_list["mobToDamage"]) in GLOB.mob_list
if(!istype(L))
return
+27 -10
View File
@@ -7,7 +7,7 @@
*/
#define SYMPTOM_LIMIT 8
#define SYMPTOM_LIMIT 6
@@ -18,7 +18,6 @@
*/
/datum/disease/advance
name = "Unknown" // We will always let our Virologist name our disease.
desc = "An engineered disease which can contain a multitude of symptoms."
form = "Advance Disease" // Will let med-scanners know that this disease was engineered.
@@ -58,7 +57,10 @@
symptoms = GenerateSymptoms(0, 2)
else
for(var/datum/symptom/S in D.symptoms)
symptoms += new S.type
var/datum/symptom/new_symp = new S.type
new_symp.name = S.name
new_symp.neutered = S.neutered
symptoms += new_symp
Refresh()
..(process, D)
@@ -119,7 +121,7 @@
if(!(src.IsSame(D)))
var/list/possible_symptoms = shuffle(D.symptoms)
for(var/datum/symptom/S in possible_symptoms)
AddSymptom(new S.type)
AddSymptom(S.Copy())
/datum/disease/advance/proc/HasSymptom(datum/symptom/S)
for(var/datum/symptom/symp in symptoms)
@@ -155,7 +157,7 @@
return generated
/datum/disease/advance/proc/Refresh(new_name = 0)
/datum/disease/advance/proc/Refresh(new_name = FALSE)
//to_chat(world, "[src.name] \ref[src] - REFRESH!")
GenerateProperties()
AssignProperties()
@@ -192,10 +194,8 @@
if(properties && properties.len)
switch(properties["stealth"])
if(2,3)
if(2 to INFINITY)
visibility_flags = HIDDEN_SCANNER
if(4 to INFINITY)
visibility_flags = HIDDEN_SCANNER|HIDDEN_PANDEMIC
// The more symptoms we have, the less transmittable it is but some symptoms can make up for it.
SetSpread(Clamp(2 ** (properties["transmittable"] - symptoms.len), BLOOD, AIRBORNE))
@@ -263,7 +263,7 @@
var/s = safepick(GenerateSymptoms(min_level, max_level, 1))
if(s)
AddSymptom(s)
Refresh(1)
Refresh(TRUE)
return
// Randomly remove a symptom.
@@ -272,7 +272,16 @@
var/s = safepick(symptoms)
if(s)
RemoveSymptom(s)
Refresh(1)
Refresh(TRUE)
return
// Randomly neuter a symptom.
/datum/disease/advance/proc/Neuter()
if(symptoms.len)
var/s = safepick(symptoms)
if(s)
NeuterSymptom(s)
Refresh(TRUE)
return
// Name the disease.
@@ -286,6 +295,8 @@
var/list/L = list()
for(var/datum/symptom/S in symptoms)
L += S.id
if(S.neutered)
L += "N"
L = sortList(L) // Sort the list so it doesn't matter which order the symptoms are in.
var/result = jointext(L, ":")
id = result
@@ -311,6 +322,12 @@
symptoms -= S
return
// Neuter a symptom, so it will only affect stats
/datum/disease/advance/proc/NeuterSymptom(datum/symptom/S)
if(!S.neutered)
S.neutered = TRUE
S.name += " (neutered)"
/*
Static Procs
+9 -9
View File
@@ -1,6 +1,6 @@
// Cold
/datum/disease/advance/cold/New(var/process = 1, var/datum/disease/advance/D, var/copy = 0)
/datum/disease/advance/cold/New(var/process = TRUE, var/datum/disease/advance/D, var/copy = FALSE)
if(!D)
name = "Cold"
symptoms = list(new/datum/symptom/sneeze)
@@ -9,7 +9,7 @@
// Flu
/datum/disease/advance/flu/New(var/process = 1, var/datum/disease/advance/D, var/copy = 0)
/datum/disease/advance/flu/New(var/process = TRUE, var/datum/disease/advance/D, var/copy = FALSE)
if(!D)
name = "Flu"
symptoms = list(new/datum/symptom/cough)
@@ -18,7 +18,7 @@
// Voice Changing
/datum/disease/advance/voice_change/New(var/process = 1, var/datum/disease/advance/D, var/copy = 0)
/datum/disease/advance/voice_change/New(var/process = TRUE, var/datum/disease/advance/D, var/copy = FALSE)
if(!D)
name = "Epiglottis Mutation"
symptoms = list(new/datum/symptom/voice_change)
@@ -27,7 +27,7 @@
// Toxin Filter
/datum/disease/advance/heal/New(var/process = 1, var/datum/disease/advance/D, var/copy = 0)
/datum/disease/advance/heal/New(var/process = TRUE, var/datum/disease/advance/D, var/copy = FALSE)
if(!D)
name = "Liver Enhancer"
symptoms = list(new/datum/symptom/heal)
@@ -36,7 +36,7 @@
// Hullucigen
/datum/disease/advance/hullucigen/New(var/process = 1, var/datum/disease/advance/D, var/copy = 0)
/datum/disease/advance/hullucigen/New(var/process = TRUE, var/datum/disease/advance/D, var/copy = FALSE)
if(!D)
name = "Reality Impairment"
symptoms = list(new/datum/symptom/hallucigen)
@@ -44,7 +44,7 @@
// Sensory Restoration
/datum/disease/advance/sensory_restoration/New(var/process = 1, var/datum/disease/advance/D, var/copy = 0)
/datum/disease/advance/sensory_restoration/New(var/process = TRUE, var/datum/disease/advance/D, var/copy = FALSE)
if(!D)
name = "Reality Enhancer"
symptoms = list(new/datum/symptom/sensory_restoration)
@@ -52,8 +52,8 @@
// Sensory Destruction
/datum/disease/advance/sensory_destruction/New(var/process = 1, var/datum/disease/advance/D, var/copy = 0)
/datum/disease/advance/narcolepsy/New(var/process = TRUE, var/datum/disease/advance/D, var/copy = FALSE)
if(!D)
name = "Reality Destruction"
symptoms = list(new/datum/symptom/sensory_destruction)
name = "Experimental Insomnia Cure"
symptoms = list(new/datum/symptom/narcolepsy)
..(process, D, copy)
+23 -22
View File
@@ -23,27 +23,28 @@ BONUS
transmittable = -1
level = 4
severity = 1
symptom_delay_min = 18
symptom_delay_max = 36
/datum/symptom/beard/Activate(datum/disease/advance/A)
..()
if(prob(SYMPTOM_ACTIVATION_PROB))
var/mob/living/M = A.affected_mob
if(ishuman(M))
var/mob/living/carbon/human/H = M
switch(A.stage)
if(1, 2)
to_chat(H, "<span class='warning'>Your chin itches.</span>")
if(H.facial_hair_style == "Shaved")
H.facial_hair_style = "Jensen Beard"
H.update_hair()
if(3, 4)
to_chat(H, "<span class='warning'>You feel tough.</span>")
if(!(H.facial_hair_style == "Dwarf Beard") && !(H.facial_hair_style == "Very Long Beard") && !(H.facial_hair_style == "Full Beard"))
H.facial_hair_style = "Full Beard"
H.update_hair()
else
to_chat(H, "<span class='warning'>You feel manly!</span>")
if(!(H.facial_hair_style == "Dwarf Beard") && !(H.facial_hair_style == "Very Long Beard"))
H.facial_hair_style = pick("Dwarf Beard", "Very Long Beard")
H.update_hair()
return
if(!..())
return
var/mob/living/M = A.affected_mob
if(ishuman(M))
var/mob/living/carbon/human/H = M
switch(A.stage)
if(1, 2)
to_chat(H, "<span class='warning'>Your chin itches.</span>")
if(H.facial_hair_style == "Shaved")
H.facial_hair_style = "Jensen Beard"
H.update_hair()
if(3, 4)
to_chat(H, "<span class='warning'>You feel tough.</span>")
if(!(H.facial_hair_style == "Dwarf Beard") && !(H.facial_hair_style == "Very Long Beard") && !(H.facial_hair_style == "Full Beard"))
H.facial_hair_style = "Full Beard"
H.update_hair()
else
to_chat(H, "<span class='warning'>You feel manly!</span>")
if(!(H.facial_hair_style == "Dwarf Beard") && !(H.facial_hair_style == "Very Long Beard"))
H.facial_hair_style = pick("Dwarf Beard", "Very Long Beard")
H.update_hair()
@@ -24,32 +24,44 @@ Bonus
transmittable = -4
level = 3
severity = 3
base_message_chance = 15
symptom_delay_min = 10
symptom_delay_max = 30
/datum/symptom/choking/Activate(datum/disease/advance/A)
/datum/symptom/choking/Start(datum/disease/advance/A)
..()
if(prob(SYMPTOM_ACTIVATION_PROB))
var/mob/living/M = A.affected_mob
switch(A.stage)
if(1, 2)
if(A.properties["stage_rate"] >= 8)
symptom_delay_min = 7
symptom_delay_max = 24
if(A.properties["stealth"] >= 4)
suppress_warning = TRUE
/datum/symptom/choking/Activate(datum/disease/advance/A)
if(!..())
return
var/mob/living/M = A.affected_mob
switch(A.stage)
if(1, 2)
if(prob(base_message_chance) && !suppress_warning)
to_chat(M, "<span class='warning'>[pick("You're having difficulty breathing.", "Your breathing becomes heavy.")]</span>")
if(3, 4)
to_chat(M, "<span class='warning'><b>[pick("Your windpipe feels like a straw.", "Your breathing becomes tremendously difficult.")]</span>")
Choke_stage_3_4(M, A)
M.emote("gasp")
if(3, 4)
if(!suppress_warning)
to_chat(M, "<span class='warning'>[pick("Your windpipe feels like a straw.", "Your breathing becomes tremendously difficult.")]</span>")
else
to_chat(M, "<span class='userdanger'>[pick("You're choking!", "You can't breathe!")]</span>")
Choke(M, A)
M.emote("gasp")
return
to_chat(M, "<span class='warning'>You feel very [pick("dizzy","woozy","faint")].</span>") //fake bloodloss messages
Choke_stage_3_4(M, A)
M.emote("gasp")
else
to_chat(M, "<span class='userdanger'>[pick("You're choking!", "You can't breathe!")]</span>")
Choke(M, A)
M.emote("gasp")
/datum/symptom/choking/proc/Choke_stage_3_4(mob/living/M, datum/disease/advance/A)
var/get_damage = sqrt(21+A.totalStageSpeed()*0.5)+sqrt(max(16+A.totalStealth(),0))
M.adjustOxyLoss(get_damage)
M.adjustOxyLoss(rand(6,13))
return 1
/datum/symptom/choking/proc/Choke(mob/living/M, datum/disease/advance/A)
var/get_damage = sqrt(21+A.totalStageSpeed()*0.5)+sqrt(max(16+A.totalStealth()*5,0))
M.adjustOxyLoss(get_damage)
M.adjustOxyLoss(rand(10,18))
return 1
/*
@@ -78,38 +90,50 @@ Bonus
transmittable = -2
level = 7
severity = 3
base_message_chance = 15
symptom_delay_min = 14
symptom_delay_max = 30
var/paralysis = FALSE
/datum/symptom/asphyxiation/Activate(datum/disease/advance/A)
/datum/symptom/asphyxiation/Start(datum/disease/advance/A)
..()
if(prob(SYMPTOM_ACTIVATION_PROB))
var/mob/living/M = A.affected_mob
switch(A.stage)
if(3, 4)
to_chat(M, "<span class='warning'><b>[pick("Your windpipe feels thin.", "Your lungs feel small.")]</span>")
Asphyxiate_stage_3_4(M, A)
M.emote("gasp")
else
to_chat(M, "<span class='userdanger'>[pick("Your lungs hurt!", "It hurts to breathe!")]</span>")
Asphyxiate(M, A)
M.emote("gasp")
if(M.getOxyLoss() >= 120)
M.visible_message("<span class='warning'>[M] stops breathing, as if their lungs have totally collapsed!</span>")
Asphyxiate_death(M, A)
if(A.properties["stage_rate"] >= 8)
paralysis = TRUE
if(A.properties["transmission"] >= 8)
power = 2
/datum/symptom/asphyxiation/Activate(datum/disease/advance/A)
if(!..())
return
var/mob/living/M = A.affected_mob
switch(A.stage)
if(3, 4)
to_chat(M, "<span class='warning'><b>[pick("Your windpipe feels thin.", "Your lungs feel small.")]</span>")
Asphyxiate_stage_3_4(M, A)
M.emote("gasp")
else
to_chat(M, "<span class='userdanger'>[pick("Your lungs hurt!", "It hurts to breathe!")]</span>")
Asphyxiate(M, A)
M.emote("gasp")
if(M.getOxyLoss() >= 120)
M.visible_message("<span class='warning'>[M] stops breathing, as if their lungs have totally collapsed!</span>")
Asphyxiate_death(M, A)
return
/datum/symptom/asphyxiation/proc/Asphyxiate_stage_3_4(mob/living/M, datum/disease/advance/A)
var/get_damage = sqrt(abs(21+A.totalStageSpeed()*0.7))+sqrt(abs(16+A.totalStealth()))
var/get_damage = rand(10,15) * power
M.adjustOxyLoss(get_damage)
return 1
/datum/symptom/asphyxiation/proc/Asphyxiate(mob/living/M, datum/disease/advance/A)
var/get_damage = sqrt(abs(21+A.totalStageSpeed()))+sqrt(abs(16+A.totalStealth()*5))
var/get_damage = rand(15,21) * power
M.adjustOxyLoss(get_damage)
M.reagents.add_reagent_list(list("pancuronium" = 2, "sodium_thiopental" = 2))
if(paralysis)
M.reagents.add_reagent_list(list("pancuronium" = 3, "sodium_thiopental" = 3))
return 1
/datum/symptom/asphyxiation/proc/Asphyxiate_death(mob/living/M, datum/disease/advance/A)
var/get_damage = sqrt(abs(21+A.totalStageSpeed()*1.5))+sqrt(abs(16+A.totalStealth()*7))
var/get_damage = rand(25,35) * power
M.adjustOxyLoss(get_damage)
M.adjustBrainLoss(get_damage/2)
return 1
@@ -24,17 +24,33 @@ Bonus
transmittable = 0
level = 4
severity = 2
base_message_chance = 25
symptom_delay_min = 10
symptom_delay_max = 30
var/brain_damage = FALSE
/datum/symptom/confusion/Start(datum/disease/advance/A)
..()
if(A.properties["resistance"] >= 6)
brain_damage = TRUE
if(A.properties["transmittable"] >= 6)
power = 1.5
if(A.properties["stealth"] >= 4)
suppress_warning = TRUE
/datum/symptom/confusion/Activate(datum/disease/advance/A)
..()
if(prob(SYMPTOM_ACTIVATION_PROB))
var/mob/living/carbon/M = A.affected_mob
switch(A.stage)
if(1, 2, 3, 4)
if(!..())
return
var/mob/living/carbon/M = A.affected_mob
switch(A.stage)
if(1, 2, 3, 4)
if(prob(base_message_chance) && !suppress_warning)
to_chat(M, "<span class='warning'>[pick("Your head hurts.", "Your mind blanks for a moment.")]</span>")
else
to_chat(M, "<span class='userdanger'>You can't think straight!</span>")
M.confused = min(100, M.confused + 8)
else
to_chat(M, "<span class='userdanger'>You can't think straight!</span>")
M.confused = min(100 * power, M.confused + 8)
if(brain_damage && M.getBrainLoss()<=80)
M.adjustBrainLoss(5 * power)
M.updatehealth()
return
+36 -8
View File
@@ -24,17 +24,45 @@ BONUS
transmittable = 2
level = 1
severity = 1
base_message_chance = 15
symptom_delay_min = 2
symptom_delay_max = 15
var/infective = FALSE
/datum/symptom/cough/Activate(datum/disease/advance/A)
/datum/symptom/cough/Start(datum/disease/advance/A)
..()
if(prob(SYMPTOM_ACTIVATION_PROB))
var/mob/living/M = A.affected_mob
switch(A.stage)
if(1, 2, 3)
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")
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()
return
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)
@@ -24,14 +24,32 @@ Bonus
transmittable = -3
level = 4
severity = 3
base_message_chance = 100
symptom_delay_min = 25
symptom_delay_max = 80
/datum/symptom/deafness/Start(datum/disease/advance/A)
..()
if(A.properties["stealth"] >= 4)
suppress_warning = TRUE
if(A.properties["resistance"] >= 9) //permanent deafness
power = 2
/datum/symptom/deafness/Activate(datum/disease/advance/A)
..()
if(prob(SYMPTOM_ACTIVATION_PROB))
var/mob/living/M = A.affected_mob
switch(A.stage)
if(3, 4)
if(!..())
return
var/mob/living/carbon/M = A.affected_mob
switch(A.stage)
if(3, 4)
if(prob(base_message_chance) && !suppress_warning)
to_chat(M, "<span class='warning'>[pick("You hear a ringing in your ear.", "Your ears pop.")]</span>")
if(5)
if(5)
if(power > 2)
var/obj/item/organ/ears/ears = M.getorganslot("ears")
if(istype(ears) && ears.ear_damage < UNHEALING_EAR_DAMAGE)
to_chat(M, "<span class='userdanger'>Your ears pop painfully and start bleeding!</span>")
ears.ear_damage = max(ears.ear_damage, UNHEALING_EAR_DAMAGE)
M.emote("scream")
else
to_chat(M, "<span class='userdanger'>Your ears pop and begin ringing loudly!</span>")
M.minimumDeafTicks(20)
+21 -9
View File
@@ -24,15 +24,27 @@ Bonus
transmittable = -1
level = 4
severity = 2
base_message_chance = 50
symptom_delay_min = 15
symptom_delay_max = 40
/datum/symptom/dizzy/Activate(datum/disease/advance/A)
/datum/symptom/dizzy/Start(datum/disease/advance/A)
..()
if(prob(SYMPTOM_ACTIVATION_PROB))
var/mob/living/M = A.affected_mob
switch(A.stage)
if(1, 2, 3, 4)
if(A.properties["stealth"] >= 4)
suppress_warning = TRUE
if(A.properties["transmittable"] >= 6) //druggy
power = 2
/datum/symptom/dizzy/Activate(datum/disease/advance/A)
if(!..())
return
var/mob/living/M = A.affected_mob
switch(A.stage)
if(1, 2, 3, 4)
if(prob(base_message_chance) && !suppress_warning)
to_chat(M, "<span class='warning'>[pick("You feel dizzy.", "Your head spins.")]</span>")
else
to_chat(M, "<span class='userdanger'>A wave of dizziness washes over you!</span>")
M.Dizzy(5)
return
else
to_chat(M, "<span class='userdanger'>A wave of dizziness washes over you!</span>")
M.Dizzy(5)
if(power >= 2)
M.set_drugginess(5)
+25 -9
View File
@@ -24,18 +24,34 @@ Bonus
transmittable = 2
level = 2
severity = 2
base_message_chance = 20
symptom_delay_min = 10
symptom_delay_max = 30
var/unsafe = FALSE //over the heat threshold
/datum/symptom/fever/Activate(datum/disease/advance/A)
/datum/symptom/fever/Start(datum/disease/advance/A)
..()
if(prob(SYMPTOM_ACTIVATION_PROB))
var/mob/living/carbon/M = A.affected_mob
to_chat(M, "<span class='warning'>[pick("You feel hot.", "You feel like you're burning.")]</span>")
if(M.bodytemperature < BODYTEMP_HEAT_DAMAGE_LIMIT)
Heat(M, A)
if(A.properties["resistance"] >= 5) //dangerous fever
power = 1.5
unsafe = TRUE
if(A.properties["resistance"] >= 10)
power = 2.5
return
/datum/symptom/fever/Activate(datum/disease/advance/A)
if(!..())
return
var/mob/living/carbon/M = A.affected_mob
if(!unsafe || A.stage < 4)
to_chat(M, "<span class='warning'>[pick("You feel hot.", "You feel like you're burning.")]</span>")
else
to_chat(M, "<span class='userdanger'>[pick("You feel too hot.", "You feel like your blood is boiling.")]</span>")
if(M.bodytemperature < BODYTEMP_HEAT_DAMAGE_LIMIT || unsafe)
Heat(M, A)
/datum/symptom/fever/proc/Heat(mob/living/M, datum/disease/advance/A)
var/get_heat = (sqrt(max(21,21+A.totalTransmittable()*2)))+(sqrt(max(21,20+A.totalStageSpeed()*3)))
M.bodytemperature = min(M.bodytemperature + (get_heat * A.stage), BODYTEMP_HEAT_DAMAGE_LIMIT - 1)
var/get_heat = 6 * power
if(!unsafe)
M.bodytemperature = min(M.bodytemperature + (get_heat * A.stage), BODYTEMP_HEAT_DAMAGE_LIMIT - 1)
else
M.bodytemperature += (get_heat * A.stage)
return 1
+80 -45
View File
@@ -24,36 +24,53 @@ Bonus
transmittable = -4
level = 6
severity = 5
base_message_chance = 20
symptom_delay_min = 20
symptom_delay_max = 75
var/infective = FALSE
/datum/symptom/fire/Start(datum/disease/advance/A)
..()
if(A.properties["stage_rate"] >= 4)
power = 1.5
if(A.properties["stage_rate"] >= 8)
power = 2
if(A.properties["stealth"] >= 4)
suppress_warning = TRUE
if(A.properties["transmittable"] >= 8) //burning skin spreads the virus through smoke
infective = TRUE
/datum/symptom/fire/Activate(datum/disease/advance/A)
..()
if(prob(SYMPTOM_ACTIVATION_PROB))
var/mob/living/M = A.affected_mob
switch(A.stage)
if(3)
if(!..())
return
var/mob/living/M = A.affected_mob
switch(A.stage)
if(3)
if(prob(base_message_chance) && !suppress_warning)
to_chat(M, "<span class='warning'>[pick("You feel hot.", "You hear a crackling noise.", "You smell smoke.")]</span>")
if(4)
Firestacks_stage_4(M, A)
M.IgniteMob()
to_chat(M, "<span class='userdanger'>Your skin bursts into flames!</span>")
M.emote("scream")
if(5)
Firestacks_stage_5(M, A)
M.IgniteMob()
to_chat(M, "<span class='userdanger'>Your skin erupts into an inferno!</span>")
M.emote("scream")
return
if(4)
Firestacks_stage_4(M, A)
M.IgniteMob()
to_chat(M, "<span class='userdanger'>Your skin bursts into flames!</span>")
M.emote("scream")
if(5)
Firestacks_stage_5(M, A)
M.IgniteMob()
to_chat(M, "<span class='userdanger'>Your skin erupts into an inferno!</span>")
M.emote("scream")
/datum/symptom/fire/proc/Firestacks_stage_4(mob/living/M, datum/disease/advance/A)
var/get_stacks = (sqrt(20+A.totalStageSpeed()*2))-(sqrt(max(0, 16+A.totalStealth())))
M.adjust_fire_stacks(get_stacks)
M.adjustFireLoss(get_stacks/2)
M.adjust_fire_stacks(1 * power)
M.adjustFireLoss(3 * power)
if(infective)
A.spread(A.holder, 2)
return 1
/datum/symptom/fire/proc/Firestacks_stage_5(mob/living/M, datum/disease/advance/A)
var/get_stacks = (sqrt(max(0, 20+A.totalStageSpeed()*3)))-(sqrt(max(0, 16+A.totalStealth())))
M.adjust_fire_stacks(get_stacks)
M.adjustFireLoss(get_stacks)
M.adjust_fire_stacks(3 * power)
M.adjustFireLoss(5 * power)
if(infective)
A.spread(A.holder, 4)
return 1
/*
@@ -83,40 +100,58 @@ Bonus
transmittable = -2
level = 7
severity = 6
base_message_chance = 100
symptom_delay_min = 30
symptom_delay_max = 90
var/chems = FALSE
var/explosion_power = 1
/datum/symptom/alkali/Start(datum/disease/advance/A)
..()
if(A.properties["resistance"] >= 9) //intense but sporadic effect
power = 2
symptom_delay_min = 50
symptom_delay_max = 140
if(A.properties["stage_rate"] >= 8) //serious boom when wet
explosion_power = 2
if(A.properties["transmission"] >= 8) //extra chemicals
chems = TRUE
/datum/symptom/alkali/Activate(datum/disease/advance/A)
..()
if(prob(SYMPTOM_ACTIVATION_PROB))
var/mob/living/M = A.affected_mob
switch(A.stage)
if(3)
if(!..())
return
var/mob/living/M = A.affected_mob
switch(A.stage)
if(3)
if(prob(base_message_chance))
to_chat(M, "<span class='warning'>[pick("Your veins boil.", "You feel hot.", "You smell meat cooking.")]</span>")
if(4)
Alkali_fire_stage_4(M, A)
M.IgniteMob()
to_chat(M, "<span class='userdanger'>Your sweat bursts into flames!</span>")
M.emote("scream")
if(5)
if(4)
Alkali_fire_stage_4(M, A)
M.IgniteMob()
to_chat(M, "<span class='userdanger'>Your sweat bursts into flames!</span>")
M.emote("scream")
if(5)
Alkali_fire_stage_5(M, A)
M.IgniteMob()
to_chat(M, "<span class='userdanger'>Your skin erupts into an inferno!</span>")
M.emote("scream")
if(M.fire_stacks < 0)
M.visible_message("<span class='warning'>[M]'s sweat sizzles and pops on contact with water!</span>")
explosion(get_turf(M),0,0,2 * explosion_power)
Alkali_fire_stage_5(M, A)
M.IgniteMob()
to_chat(M, "<span class='userdanger'>Your skin erupts into an inferno!</span>")
M.emote("scream")
if(M.fire_stacks < 0)
M.visible_message("<span class='warning'>[M]'s sweat sizzles and pops on contact with water!</span>")
explosion(M.loc,0,0,2)
Alkali_fire_stage_5(M, A)
return
/datum/symptom/alkali/proc/Alkali_fire_stage_4(mob/living/M, datum/disease/advance/A)
var/get_stacks = (sqrt(20+A.totalStageSpeed()*5))
var/get_stacks = 6 * power
M.adjust_fire_stacks(get_stacks)
M.adjustFireLoss(get_stacks/2)
M.reagents.add_reagent("clf3", 1)
if(chems)
M.reagents.add_reagent("clf3", 2 * power)
return 1
/datum/symptom/alkali/proc/Alkali_fire_stage_5(mob/living/M, datum/disease/advance/A)
var/get_stacks = (sqrt(20+A.totalStageSpeed()*8))
var/get_stacks = 8 * power
M.adjust_fire_stacks(get_stacks)
M.adjustFireLoss(get_stacks)
M.reagents.add_reagent_list(list("napalm" = 3, "clf3" = 3))
if(chems)
M.reagents.add_reagent_list(list("napalm" = 4 * power, "clf3" = 4 * power))
return 1
@@ -24,22 +24,40 @@ Bonus
transmittable = -4
level = 6
severity = 5
base_message_chance = 50
symptom_delay_min = 15
symptom_delay_max = 60
var/bleed = FALSE
var/pain = FALSE
/datum/symptom/flesh_eating/Activate(datum/disease/advance/A)
/datum/symptom/flesh_eating/Start(datum/disease/advance/A)
..()
if(prob(SYMPTOM_ACTIVATION_PROB))
var/mob/living/M = A.affected_mob
switch(A.stage)
if(2,3)
if(A.properties["resistance"] >= 7) //extra bleeding
bleed = TRUE
if(A.properties["transmittable"] >= 8) //extra stamina damage
pain = TRUE
/datum/symptom/flesh_eating/Activate(datum/disease/advance/A)
if(!..())
return
var/mob/living/M = A.affected_mob
switch(A.stage)
if(2,3)
if(prob(base_message_chance))
to_chat(M, "<span class='warning'>[pick("You feel a sudden pain across your body.", "Drops of blood appear suddenly on your skin.")]</span>")
if(4,5)
to_chat(M, "<span class='userdanger'>[pick("You cringe as a violent pain takes over your body.", "It feels like your body is eating itself inside out.", "IT HURTS.")]</span>")
Flesheat(M, A)
return
if(4,5)
to_chat(M, "<span class='userdanger'>[pick("You cringe as a violent pain takes over your body.", "It feels like your body is eating itself inside out.", "IT HURTS.")]</span>")
Flesheat(M, A)
/datum/symptom/flesh_eating/proc/Flesheat(mob/living/M, datum/disease/advance/A)
var/get_damage = ((sqrt(16-A.totalStealth()))*5)
var/get_damage = rand(15,25) * power
M.adjustBruteLoss(get_damage)
if(pain)
M.adjustStaminaLoss(get_damage)
if(bleed)
if(ishuman(M))
var/mob/living/carbon/human/H = M
H.bleed_rate += 5 * power
return 1
/*
@@ -68,21 +86,37 @@ Bonus
transmittable = -2
level = 7
severity = 6
base_message_chance = 50
symptom_delay_min = 3
symptom_delay_max = 6
var/chems = FALSE
var/zombie = FALSE
/datum/symptom/flesh_death/Activate(datum/disease/advance/A)
/datum/symptom/flesh_death/Start(datum/disease/advance/A)
..()
if(prob(SYMPTOM_ACTIVATION_PROB))
var/mob/living/M = A.affected_mob
switch(A.stage)
if(2,3)
if(A.properties["stealth"] >= 5)
suppress_warning = TRUE
if(A.properties["stage_rate"] >= 7) //bleeding and hunger
chems = TRUE
/datum/symptom/flesh_death/Activate(datum/disease/advance/A)
if(!..())
return
var/mob/living/M = A.affected_mob
switch(A.stage)
if(2,3)
if(prob(base_message_chance) && !suppress_warning)
to_chat(M, "<span class='warning'>[pick("You feel your body break apart.", "Your skin rubs off like dust.")]</span>")
if(4,5)
to_chat(M, "<span class='userdanger'>[pick("You feel your muscles weakening.", "Your skin begins detaching itself.", "You feel sandy.")]</span>")
Flesh_death(M, A)
return
if(4,5)
if(prob(base_message_chance / 2)) //reduce spam
to_chat(M, "<span class='userdanger'>[pick("You feel your muscles weakening.", "Some of your skin detaches itself.", "You feel sandy.")]</span>")
Flesh_death(M, A)
/datum/symptom/flesh_death/proc/Flesh_death(mob/living/M, datum/disease/advance/A)
var/get_damage = ((sqrt(16-A.totalStealth()))*6)
var/get_damage = rand(6,10)
M.adjustBruteLoss(get_damage)
M.reagents.add_reagent_list(list("heparin" = 5, "lipolicide" = 5))
if(chems)
M.reagents.add_reagent_list(list("heparin" = 2, "lipolicide" = 2))
if(zombie)
M.reagents.add_reagent("romerol", 1)
return 1
@@ -26,22 +26,34 @@ Bonus
severity = 3
var/list/possible_mutations
var/archived_dna = null
base_message_chance = 50
symptom_delay_min = 60
symptom_delay_max = 120
var/no_reset = FALSE
/datum/symptom/genetic_mutation/Activate(datum/disease/advance/A)
..()
if(prob(SYMPTOM_ACTIVATION_PROB * 3)) // 15% chance
var/mob/living/carbon/C = A.affected_mob
if(!C.has_dna())
return
switch(A.stage)
if(4, 5)
to_chat(C, "<span class='warning'>[pick("Your skin feels itchy.", "You feel light headed.")]</span>")
C.dna.remove_mutation_group(possible_mutations)
if(!..())
return
var/mob/living/carbon/C = A.affected_mob
if(!C.has_dna())
return
switch(A.stage)
if(4, 5)
to_chat(C, "<span class='warning'>[pick("Your skin feels itchy.", "You feel light headed.")]</span>")
C.dna.remove_mutation_group(possible_mutations)
for(var/i in 1 to power)
C.randmut(possible_mutations)
return
// Archive their DNA before they were infected.
/datum/symptom/genetic_mutation/Start(datum/disease/advance/A)
..()
if(A.properties["stealth"] >= 5) //don't restore dna after curing
no_reset = TRUE
if(A.properties["stage_rate"] >= 10) //mutate more often
symptom_delay_min = 20
symptom_delay_max = 60
if(A.properties["resistance"] >= 8) //mutate twice
power = 2
possible_mutations = (GLOB.bad_mutations | GLOB.not_good_mutations) - GLOB.mutations_list[RACEMUT]
var/mob/living/carbon/M = A.affected_mob
if(M)
@@ -51,9 +63,10 @@ Bonus
// Give them back their old DNA when cured.
/datum/symptom/genetic_mutation/End(datum/disease/advance/A)
var/mob/living/carbon/M = A.affected_mob
if(M && archived_dna)
if(!M.has_dna())
return
M.dna.struc_enzymes = archived_dna
M.domutcheck()
if(!no_reset)
var/mob/living/carbon/M = A.affected_mob
if(M && archived_dna)
if(!M.has_dna())
return
M.dna.struc_enzymes = archived_dna
M.domutcheck()
@@ -24,18 +24,39 @@ Bonus
transmittable = -1
level = 5
severity = 3
base_message_chance = 25
symptom_delay_min = 25
symptom_delay_max = 90
var/fake_healthy = FALSE
/datum/symptom/hallucigen/Activate(datum/disease/advance/A)
/datum/symptom/hallucigen/Start(datum/disease/advance/A)
..()
if(prob(SYMPTOM_ACTIVATION_PROB))
var/mob/living/carbon/M = A.affected_mob
switch(A.stage)
if(1, 2)
to_chat(M, "<span class='warning'>[pick("Something appears in your peripheral vision, then winks out.", "You hear a faint whispher with no source.", "Your head aches.")]</span>")
if(3, 4)
to_chat(M, "<span class='danger'>[pick("Something is following you.", "You are being watched.", "You hear a whisper in your ear.", "Thumping footsteps slam toward you from nowhere.")]</span>")
else
to_chat(M, "<span class='userdanger'>[pick("Oh, your head...", "Your head pounds.", "They're everywhere! Run!", "Something in the shadows...")]</span>")
M.hallucination += 25
if(A.properties["stealth"] >= 4) //fake good symptom messages
fake_healthy = TRUE
base_message_chance = 50
if(A.properties["stage_rate"] >= 7) //stronger hallucinations
power = 2
return
/datum/symptom/hallucigen/Activate(datum/disease/advance/A)
if(!..())
return
var/mob/living/carbon/M = A.affected_mob
var/list/healthy_messages = list("Your lungs feel great.", "You realize you haven't been breathing.", "You don't feel the need to breathe.",\
"Your eyes feel great.", "You are now blinking manually.", "You don't feel the need to blink.")
switch(A.stage)
if(1, 2)
if(prob(base_message_chance))
if(!fake_healthy)
to_chat(M, "<span class='notice'>[pick("Something appears in your peripheral vision, then winks out.", "You hear a faint whispher with no source.", "Your head aches.")]</span>")
else
to_chat(M, "<span class='notice'>[pick(healthy_messages)]</span>")
if(3, 4)
if(prob(base_message_chance))
if(!fake_healthy)
to_chat(M, "<span class='danger'>[pick("Something is following you.", "You are being watched.", "You hear a whisper in your ear.", "Thumping footsteps slam toward you from nowhere.")]</span>")
else
to_chat(M, "<span class='notice'>[pick(healthy_messages)]</span>")
else
if(prob(base_message_chance))
to_chat(M, "<span class='userdanger'>[pick("Oh, your head...", "Your head pounds.", "They're everywhere! Run!", "Something in the shadows...")]</span>")
M.hallucination += (15 * power)
@@ -25,10 +25,31 @@ BONUS
transmittable = 0
level = 1
severity = 1
base_message_chance = 100
symptom_delay_min = 15
symptom_delay_max = 30
/datum/symptom/headache/Activate(datum/disease/advance/A)
/datum/symptom/headache/Start(datum/disease/advance/A)
..()
if(prob(SYMPTOM_ACTIVATION_PROB))
var/mob/living/M = A.affected_mob
to_chat(M, "<span class='warning'>[pick("Your head hurts.", "Your head starts pounding.")]</span>")
return
if(A.properties["stealth"] >= 4)
base_message_chance = 50
if(A.properties["stage_rate"] >= 6) //severe pain
power = 2
if(A.properties["stage_rate"] >= 9) //cluster headaches
symptom_delay_min = 30
symptom_delay_max = 60
power = 3
/datum/symptom/headache/Activate(datum/disease/advance/A)
if(!..())
return
var/mob/living/M = A.affected_mob
if(power < 2)
if(prob(base_message_chance))
to_chat(M, "<span class='warning'>[pick("Your head hurts.", "Your head pounds.")]</span>")
if(power >= 2)
to_chat(M, "<span class='warning'>[pick("Your head hurts a lot.", "Your head pounds incessantly.")]</span>")
M.adjustStaminaLoss(25)
if(power >= 3)
to_chat(M, "<span class='userdanger'>[pick("Your head hurts!", "You feel a burning knife inside your brain!", "A wave of pain fills your head!")]</span>")
M.Stun(35)
+56 -29
View File
@@ -1,7 +1,41 @@
/datum/symptom/heal
name = "Basic Healing (does nothing)" //warning for adminspawn viruses
stealth = 1
resistance = -4
stage_speed = -4
transmittable = -4
level = 0 //not obtainable
base_message_chance = 20 //here used for the overlays
symptom_delay_min = 1
symptom_delay_max = 1
var/hide_healing = FALSE
/datum/symptom/heal/Start(datum/disease/advance/A)
..()
if(A.properties["stealth"] >= 4) //invisible healing
hide_healing = TRUE
if(A.properties["stage_rate"] >= 6) //stronger healing
power = 2
if(A.properties["stage_rate"] >= 11) //even stronger healing
power = 3
/datum/symptom/heal/Activate(datum/disease/advance/A)
if(!..())
return
//100% chance to activate for slow but consistent healing
var/mob/living/M = A.affected_mob
switch(A.stage)
if(4, 5)
Heal(M, A)
return
/datum/symptom/heal/proc/Heal(mob/living/M, datum/disease/advance/A)
return 1
/*
//////////////////////////////////////
Healing
Toxin Filter
Little bit hidden.
Lowers resistance tremendously.
@@ -15,8 +49,7 @@ Bonus
//////////////////////////////////////
*/
/datum/symptom/heal
/datum/symptom/heal/toxin
name = "Toxic Filter"
stealth = 1
resistance = -4
@@ -24,18 +57,9 @@ Bonus
transmittable = -4
level = 6
/datum/symptom/heal/Activate(datum/disease/advance/A)
..()
//100% chance to activate for slow but consistent healing
var/mob/living/M = A.affected_mob
switch(A.stage)
if(4, 5)
Heal(M, A)
return
/datum/symptom/heal/proc/Heal(mob/living/M, datum/disease/advance/A)
var/heal_amt = 0.5
if(M.toxloss > 0 && prob(20))
/datum/symptom/heal/toxin/Heal(mob/living/M, datum/disease/advance/A)
var/heal_amt = 1 * power
if(M.toxloss > 0 && prob(base_message_chance) && !hide_healing)
new /obj/effect/temp_visual/heal(get_turf(M), "#66FF99")
M.adjustToxLoss(-heal_amt)
return 1
@@ -55,7 +79,7 @@ Bonus
//////////////////////////////////////
*/
/datum/symptom/heal/plus
/datum/symptom/heal/toxin/plus
name = "Apoptoxin filter"
stealth = 0
@@ -64,9 +88,9 @@ Bonus
transmittable = -2
level = 8
/datum/symptom/heal/plus/Heal(mob/living/M, datum/disease/advance/A)
var/heal_amt = 1
if(M.toxloss > 0 && prob(20))
/datum/symptom/heal/toxin/plus/Heal(mob/living/M, datum/disease/advance/A)
var/heal_amt = 2 * power
if(M.toxloss > 0 && prob(base_message_chance) && !hide_healing)
new /obj/effect/temp_visual/heal(get_turf(M), "#00FF00")
M.adjustToxLoss(-heal_amt)
return 1
@@ -98,7 +122,7 @@ Bonus
level = 6
/datum/symptom/heal/brute/Heal(mob/living/carbon/M, datum/disease/advance/A)
var/heal_amt = 1
var/heal_amt = 2 * power
var/list/parts = M.get_damaged_bodyparts(1,1) //1,1 because it needs inputs.
@@ -109,7 +133,7 @@ Bonus
if(L.heal_damage(heal_amt/parts.len, 0))
M.update_damage_overlays()
if(prob(20))
if(prob(base_message_chance) && !hide_healing)
new /obj/effect/temp_visual/heal(get_turf(M), "#FF3333")
return 1
@@ -141,14 +165,15 @@ Bonus
level = 8
/datum/symptom/heal/brute/plus/Heal(mob/living/carbon/M, datum/disease/advance/A)
var/heal_amt = 2
var/heal_amt = 4 * power
var/list/parts = M.get_damaged_bodyparts(1,1) //1,1 because it needs inputs.
if(M.getCloneLoss() > 0)
M.adjustCloneLoss(-1)
M.take_bodypart_damage(0, 1) //Deals BURN damage, which is not cured by this symptom
new /obj/effect/temp_visual/heal(get_turf(M), "#33FFCC")
if(!hide_healing)
new /obj/effect/temp_visual/heal(get_turf(M), "#33FFCC")
if(!parts.len)
return
@@ -157,7 +182,7 @@ Bonus
if(L.heal_damage(heal_amt/parts.len, 0))
M.update_damage_overlays()
if(prob(20))
if(prob(base_message_chance) && !hide_healing)
new /obj/effect/temp_visual/heal(get_turf(M), "#CC1100")
return 1
@@ -189,7 +214,7 @@ Bonus
level = 6
/datum/symptom/heal/burn/Heal(mob/living/carbon/M, datum/disease/advance/A)
var/heal_amt = 1
var/heal_amt = 2 * power
var/list/parts = M.get_damaged_bodyparts(1,1) //1,1 because it needs inputs.
@@ -200,7 +225,7 @@ Bonus
if(L.heal_damage(0, heal_amt/parts.len))
M.update_damage_overlays()
if(prob(20))
if(prob(base_message_chance) && !hide_healing)
new /obj/effect/temp_visual/heal(get_turf(M), "#FF9933")
return 1
@@ -231,7 +256,7 @@ Bonus
level = 8
/datum/symptom/heal/burn/plus/Heal(mob/living/carbon/M, datum/disease/advance/A)
var/heal_amt = 2
var/heal_amt = 4 * power
var/list/parts = M.get_damaged_bodyparts(1,1) //1,1 because it needs inputs.
@@ -247,7 +272,7 @@ Bonus
if(L.heal_damage(0, heal_amt/parts.len))
M.update_damage_overlays()
if(prob(20))
if(prob(base_message_chance) && !hide_healing)
new /obj/effect/temp_visual/heal(get_turf(M), "#CC6600")
return 1
@@ -277,9 +302,11 @@ Bonus
stage_speed = 0
transmittable = -3
level = 5
symptom_delay_min = 3
symptom_delay_max = 8
/datum/symptom/heal/dna/Heal(mob/living/carbon/M, datum/disease/advance/A)
var/amt_healed = 1
var/amt_healed = 2 * power
M.adjustBrainLoss(-amt_healed)
//Non-power mutations, excluding race, so the virus does not force monkey -> human transformations.
var/list/unclean_mutations = (GLOB.not_good_mutations|GLOB.bad_mutations) - GLOB.mutations_list[RACEMUT]
@@ -25,10 +25,23 @@ BONUS
transmittable = 1
level = 1
severity = 1
symptom_delay_min = 5
symptom_delay_max = 25
var/scratch = FALSE
/datum/symptom/itching/Activate(datum/disease/advance/A)
/datum/symptom/itching/Start(datum/disease/advance/A)
..()
if(prob(SYMPTOM_ACTIVATION_PROB))
var/mob/living/M = A.affected_mob
to_chat(M, "<span class='warning'>Your [pick("back", "arm", "leg", "elbow", "head")] itches.</span>")
return
if(A.properties["transmittable"] >= 6) //itch more often
symptom_delay_min = 1
symptom_delay_max = 4
if(A.properties["stage_rate"] >= 7) //scratch
scratch = TRUE
/datum/symptom/itching/Activate(datum/disease/advance/A)
if(!..())
return
var/mob/living/M = A.affected_mob
var/can_scratch = scratch && !M.incapacitated()
to_chat(M, "<span class='warning'>Your [pick("back", "arm", "leg", "elbow", "head")] itches. [can_scratch ? " You scratch it." : ""]</span>")
if(can_scratch)
M.adjustBruteLoss(0.5)
@@ -0,0 +1,89 @@
/*
//////////////////////////////////////
Narcolepsy
Noticeable.
Lowers resistance
Decreases stage speed tremendously.
Decreases transmittablity tremendously.
Bonus
Causes drowsiness and sleep.
//////////////////////////////////////
*/
/datum/symptom/narcolepsy
name = "Narcolepsy"
stealth = -1
resistance = -2
stage_speed = -3
transmittable = -4
level = 6
symptom_delay_min = 15
symptom_delay_max = 80
severity = 5
var/sleep_level = 0
var/sleepy_ticks = 0
var/stamina = FALSE
/datum/symptom/narcolepsy/Start(datum/disease/advance/A)
..()
if(A.properties["transmittable"] >= 7) //stamina damage
stamina = TRUE
if(A.properties["resistance"] >= 10) //act more often
symptom_delay_min = 10
symptom_delay_max = 60
/datum/symptom/narcolepsy/Activate(var/datum/disease/advance/A)
var/mob/living/M = A.affected_mob
//this ticks even when on cooldown
switch(sleep_level) //Works sorta like morphine
if(10 to 19)
M.drowsyness += 1
if(20 to INFINITY)
M.Sleeping(30, 0)
sleep_level = 0
sleepy_ticks = 0
if(sleepy_ticks && A.stage>=5)
sleep_level++
sleepy_ticks--
else
sleep_level = 0
if(!..())
return
switch(A.stage)
if(1)
if(prob(10))
to_chat(M, "<span class='warning'>You feel tired.</span>")
if(2)
if(prob(10))
to_chat(M, "<span class='warning'>You feel very tired.</span>")
sleepy_ticks += rand(10,14)
if(stamina)
M.adjustStaminaLoss(10)
if(3)
if(prob(15))
to_chat(M, "<span class='warning'>You try to focus on staying awake.</span>")
sleepy_ticks += rand(10,14)
if(stamina)
M.adjustStaminaLoss(15)
if(4)
if(prob(20))
to_chat(M, "<span class='warning'>You nod off for a moment.</span>")
sleepy_ticks += rand(10,14)
if(stamina)
M.adjustStaminaLoss(20)
if(5)
if(prob(25))
to_chat(M, "<span class='warning'>[pick("So tired...","You feel very sleepy.","You have a hard time keeping your eyes open.","You try to stay awake.")]</span>")
M.drowsyness = max(M.drowsyness, 2)
sleepy_ticks += rand(10,14)
if(stamina)
M.adjustStaminaLoss(30)
@@ -23,16 +23,27 @@ Bonus
stage_speed = -3
transmittable = -4
level = 6
base_message_chance = 5
symptom_delay_min = 1
symptom_delay_max = 1
var/regenerate_blood = FALSE
/datum/symptom/oxygen/Activate(datum/disease/advance/A)
/datum/symptom/oxygen/Start(datum/disease/advance/A)
..()
var/mob/living/M = A.affected_mob
if(A.properties["resistance"] >= 8) //blood regeneration
regenerate_blood = TRUE
/datum/symptom/oxygen/Activate(datum/disease/advance/A)
if(!..())
return
var/mob/living/carbon/M = A.affected_mob
switch(A.stage)
if(4, 5)
M.adjustOxyLoss(-3, 0)
if(M.losebreath >= 4)
M.losebreath -= 2
M.adjustOxyLoss(-7, 0)
M.losebreath = max(0, M.losebreath - 4)
if(regenerate_blood && M.blood_volume < BLOOD_VOLUME_NORMAL)
M.blood_volume += 1
else
if(prob(SYMPTOM_ACTIVATION_PROB * 3))
if(prob(base_message_chance))
to_chat(M, "<span class='notice'>[pick("Your lungs feel great.", "You realize you haven't been breathing.", "You don't feel the need to breathe.")]</span>")
return
@@ -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/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)
if(brain_heal && 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(40)
@@ -0,0 +1,134 @@
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
@@ -2,8 +2,8 @@
//////////////////////////////////////
Alopecia
Noticable.
Decreases resistance slightly.
Not Noticeable.
Increases resistance slightly.
Reduces stage speed slightly.
Transmittable.
Intense Level.
@@ -17,29 +17,34 @@ BONUS
/datum/symptom/shedding
name = "Alopecia"
stealth = -1
resistance = -1
stealth = 0
resistance = 1
stage_speed = -1
transmittable = 2
transmittable = 3
level = 4
severity = 1
base_message_chance = 50
symptom_delay_min = 45
symptom_delay_max = 90
/datum/symptom/shedding/Activate(datum/disease/advance/A)
..()
if(prob(SYMPTOM_ACTIVATION_PROB))
var/mob/living/M = A.affected_mob
if(!..())
return
var/mob/living/M = A.affected_mob
if(prob(base_message_chance))
to_chat(M, "<span class='warning'>[pick("Your scalp itches.", "Your skin feels flakey.")]</span>")
if(ishuman(M))
var/mob/living/carbon/human/H = M
switch(A.stage)
if(3, 4)
if(!(H.hair_style == "Bald") && !(H.hair_style == "Balding Hair"))
to_chat(H, "<span class='warning'>Your hair starts to fall out in clumps...</span>")
addtimer(CALLBACK(src, .proc/Shed, H, FALSE), 50)
if(5)
if(!(H.facial_hair_style == "Shaved") || !(H.hair_style == "Bald"))
to_chat(H, "<span class='warning'>Your hair starts to fall out in clumps...</span>")
addtimer(CALLBACK(src, .proc/Shed, H, TRUE), 50)
if(ishuman(M))
var/mob/living/carbon/human/H = M
switch(A.stage)
if(3, 4)
if(!(H.hair_style == "Bald") && !(H.hair_style == "Balding Hair"))
to_chat(H, "<span class='warning'>Your hair starts to fall out in clumps...</span>")
addtimer(CALLBACK(src, .proc/Shed, H, FALSE), 50)
if(5)
if(!(H.facial_hair_style == "Shaved") || !(H.hair_style == "Bald"))
to_chat(H, "<span class='warning'>Your hair starts to fall out in clumps...</span>")
addtimer(CALLBACK(src, .proc/Shed, H, TRUE), 50)
/datum/symptom/shedding/proc/Shed(mob/living/carbon/human/H, fullbald)
if(fullbald)
@@ -24,17 +24,33 @@ Bonus
transmittable = 2
level = 2
severity = 2
symptom_delay_min = 10
symptom_delay_max = 30
var/unsafe = FALSE //over the cold threshold
/datum/symptom/shivering/Activate(datum/disease/advance/A)
/datum/symptom/fever/Start(datum/disease/advance/A)
..()
if(prob(SYMPTOM_ACTIVATION_PROB))
var/mob/living/carbon/M = A.affected_mob
to_chat(M, "<span class='warning'>[pick("You feel cold.", "You start shivering.")]</span>")
if(M.bodytemperature < BODYTEMP_COLD_DAMAGE_LIMIT)
Chill(M, A)
return
if(A.properties["stage_speed"] >= 5) //dangerous cold
power = 1.5
unsafe = TRUE
if(A.properties["stage_speed"] >= 10)
power = 2.5
/datum/symptom/shivering/Activate(datum/disease/advance/A)
if(!..())
return
var/mob/living/carbon/M = A.affected_mob
if(!unsafe || A.stage < 4)
to_chat(M, "<span class='warning'>[pick("You feel cold.", "You shiver.")]</span>")
else
to_chat(M, "<span class='userdanger'>[pick("You feel your blood run cold.", "You feel ice in your veins.", "You feel like you can't heat up.", "You shiver violently." )]</span>")
if(M.bodytemperature < BODYTEMP_COLD_DAMAGE_LIMIT || unsafe)
Chill(M, A)
/datum/symptom/shivering/proc/Chill(mob/living/M, datum/disease/advance/A)
var/get_cold = (sqrt(16+A.totalStealth()*2))+(sqrt(21+A.totalResistance()*2))
M.bodytemperature = min(M.bodytemperature - (get_cold * A.stage), BODYTEMP_COLD_DAMAGE_LIMIT + 1)
var/get_cold = 6 * power
if(!unsafe)
M.bodytemperature = min(M.bodytemperature - (get_cold * A.stage), BODYTEMP_COLD_DAMAGE_LIMIT + 1)
else
M.bodytemperature -= (get_cold * A.stage)
return 1
+30 -30
View File
@@ -23,23 +23,23 @@ BONUS
transmittable = -2
level = 5
severity = 1
symptom_delay_min = 25
symptom_delay_max = 75
/datum/symptom/vitiligo/Activate(datum/disease/advance/A)
..()
if(prob(SYMPTOM_ACTIVATION_PROB))
var/mob/living/M = A.affected_mob
if(ishuman(M))
var/mob/living/carbon/human/H = M
if(H.skin_tone == "albino")
return
switch(A.stage)
if(5)
H.skin_tone = "albino"
H.update_body(0)
else
H.visible_message("<span class='warning'>[H] looks a bit pale...</span>", "<span class='notice'>Your skin suddenly appears lighter...</span>")
return
if(!..())
return
var/mob/living/M = A.affected_mob
if(ishuman(M))
var/mob/living/carbon/human/H = M
if(H.skin_tone == "albino")
return
switch(A.stage)
if(5)
H.skin_tone = "albino"
H.update_body(0)
else
H.visible_message("<span class='warning'>[H] looks a bit pale...</span>", "<span class='notice'>Your skin suddenly appears lighter...</span>")
/*
@@ -67,20 +67,20 @@ BONUS
transmittable = -2
level = 5
severity = 1
symptom_delay_min = 7
symptom_delay_max = 14
/datum/symptom/revitiligo/Activate(datum/disease/advance/A)
..()
if(prob(SYMPTOM_ACTIVATION_PROB))
var/mob/living/M = A.affected_mob
if(ishuman(M))
var/mob/living/carbon/human/H = M
if(H.skin_tone == "african2")
return
switch(A.stage)
if(5)
H.skin_tone = "african2"
H.update_body(0)
else
H.visible_message("<span class='warning'>[H] looks a bit dark...</span>", "<span class='notice'>Your skin suddenly appears darker...</span>")
return
if(!..())
return
var/mob/living/M = A.affected_mob
if(ishuman(M))
var/mob/living/carbon/human/H = M
if(H.skin_tone == "african2")
return
switch(A.stage)
if(5)
H.skin_tone = "african2"
H.update_body(0)
else
H.visible_message("<span class='warning'>[H] looks a bit dark...</span>", "<span class='notice'>Your skin suddenly appears darker...</span>")
+18 -10
View File
@@ -17,7 +17,6 @@ Bonus
*/
/datum/symptom/sneeze
name = "Sneezing"
stealth = -2
resistance = 3
@@ -25,15 +24,24 @@ Bonus
transmittable = 4
level = 1
severity = 1
symptom_delay_min = 5
symptom_delay_max = 35
/datum/symptom/sneeze/Activate(datum/disease/advance/A)
/datum/symptom/sneeze/Start(datum/disease/advance/A)
..()
if(prob(SYMPTOM_ACTIVATION_PROB))
var/mob/living/M = A.affected_mob
switch(A.stage)
if(1, 2, 3)
if(A.properties["transmittable"] >= 9) //longer spread range
power = 2
if(A.properties["stealth"] >= 4)
suppress_warning = TRUE
/datum/symptom/sneeze/Activate(datum/disease/advance/A)
if(!..())
return
var/mob/living/M = A.affected_mob
switch(A.stage)
if(1, 2, 3)
if(!suppress_warning)
M.emote("sniff")
else
M.emote("sneeze")
A.spread(A.holder, 5)
return
else
M.emote("sneeze")
A.spread(A.holder, 4 + power)
@@ -13,7 +13,18 @@
var/severity = 0
// The hash tag for our diseases, we will add it up with our other symptoms to get a unique id! ID MUST BE UNIQUE!!!
var/id = ""
var/static/SYMPTOM_ACTIVATION_PROB = 5
//Base chance of sending warning messages, so it can be modified
var/base_message_chance = 10
//If the early warnings are suppressed or not
var/suppress_warning = FALSE
//Ticks between each activation
var/next_activation = 0
var/symptom_delay_min = 1
var/symptom_delay_max = 1
//Can be used to multiply virus effects
var/power = 1
//A neutered symptom has no effect, and only affects statistics.
var/neutered = FALSE
/datum/symptom/New()
var/list/S = SSdisease.list_symptoms
@@ -25,6 +36,7 @@
// Called when processing of the advance disease, which holds this symptom, starts.
/datum/symptom/proc/Start(datum/disease/advance/A)
next_activation = world.time + rand(symptom_delay_min * 10, symptom_delay_max * 10) //so it doesn't instantly activate on infection
return
// Called when the advance disease is going to be deleted or when the advance disease stops processing.
@@ -32,5 +44,17 @@
return
/datum/symptom/proc/Activate(datum/disease/advance/A)
return
if(neutered)
return FALSE
if(world.time < next_activation)
return FALSE
else
next_activation = world.time + rand(symptom_delay_min * 10, symptom_delay_max * 10)
return TRUE
/datum/symptom/proc/Copy()
var/datum/symptom/new_symp = new type
new_symp.name = name
new_symp.id = id
new_symp.neutered = neutered
return new_symp
+22 -32
View File
@@ -21,16 +21,6 @@ BONUS
transmittable = 0
level = 3
/datum/symptom/viraladaptation/Activate(datum/disease/advance/A)
..()
if(prob(SYMPTOM_ACTIVATION_PROB))
var/mob/living/M = A.affected_mob
switch(A.stage)
if(1)
to_chat(M, "<span class='notice'>You feel off, but no different from before.</span>")
if(5)
to_chat(M, "<span class='notice'>You feel better, but nothing interesting happens.</span>")
/*
//////////////////////////////////////
Viral evolution
@@ -54,29 +44,19 @@ BONUS
transmittable = 3
level = 3
/datum/symptom/viraladaptation/Activate(datum/disease/advance/A)
..()
if(prob(SYMPTOM_ACTIVATION_PROB))
var/mob/living/M = A.affected_mob
switch(A.stage)
if(1)
to_chat(M, "<span class='notice'>You feel better, but no different from before.</span>")
if(5)
to_chat(M, "<span class='notice'>You feel off, but nothing interesting happens.</span>")
/*
//////////////////////////////////////
Viral aggressive metabolism (ex-Longevity)
Viral aggressive metabolism
No stealth.
Reduced stealth.
Small resistance boost.
Reduced stage speed.
Large transmittablity boost.
High Level.
Increased stage speed.
Small transmittablity boost.
Medium Level.
Bonus
The virus starts at stage 5 and decrease over time until it self cures.
The virus starts at stage 5, but after a certain time will start curing itself.
Stages still increase naturally with stage speed.
//////////////////////////////////////
@@ -85,23 +65,33 @@ Bonus
/datum/symptom/viralreverse
name = "Viral aggressive metabolism"
stealth = 0
stealth = -2
resistance = 1
stage_speed = -2
transmittable = 3
stage_speed = 3
transmittable = 1
level = 3
symptom_delay_min = 1
symptom_delay_max = 1
var/time_to_cure
/datum/symptom/viralreverse/Activate(datum/disease/advance/A)
..()
if(prob(SYMPTOM_ACTIVATION_PROB))
if(!..())
return
if(time_to_cure > 0)
time_to_cure--
else
var/mob/living/M = A.affected_mob
Heal(M, A)
return
/datum/symptom/viralreverse/proc/Heal(mob/living/M, datum/disease/advance/A)
A.stage -= 1
if(A.stage < 2)
to_chat(M, "<span class='notice'>You suddenly feel healthy.</span>")
A.cure()
/datum/symptom/viralreverse/Start(datum/disease/advance/A)
..()
A.stage = 5
if(A.properties["stealth"] >= 4) //more time before it's cured
power = 2
time_to_cure = max(A.properties["resistance"], A.properties["stage_rate"]) * 10 * power
+34 -12
View File
@@ -24,30 +24,48 @@ Bonus
transmittable = -3
level = 5
severity = 4
base_message_chance = 50
symptom_delay_min = 25
symptom_delay_max = 80
var/remove_eyes = FALSE
/datum/symptom/visionloss/Start(datum/disease/advance/A)
..()
if(A.properties["stealth"] >= 4)
suppress_warning = TRUE
if(A.properties["resistance"] >= 12) //goodbye eyes
remove_eyes = TRUE
/datum/symptom/visionloss/Activate(datum/disease/advance/A)
..()
if(prob(SYMPTOM_ACTIVATION_PROB))
var/mob/living/M = A.affected_mob
var/obj/item/organ/eyes/eyes = M.getorganslot("eyes_sight")
if (!eyes)
return
if(!..())
return
var/mob/living/carbon/M = A.affected_mob
var/obj/item/organ/eyes/eyes = M.getorganslot("eye_sight")
if(istype(eyes))
switch(A.stage)
if(1, 2)
to_chat(M, "<span class='warning'>Your eyes itch.</span>")
if(prob(base_message_chance) && !suppress_warning)
to_chat(M, "<span class='warning'>Your eyes itch.</span>")
if(3, 4)
to_chat(M, "<span class='warning'><b>Your eyes burn!</b></span>")
M.blur_eyes(10)
M.adjust_eye_damage(1)
else
to_chat(M, "<span class='userdanger'>Your eyes burn horrificly!</span>")
M.blur_eyes(20)
M.adjust_eye_damage(5)
if(eyes.eye_damage >= 10)
M.become_nearsighted()
if(prob(eyes.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>")
else
M.visible_message("<span class='warning'>[M]'s eyes fall off their sockets!</span>", "<span class='userdanger'>Your eyes fall off their sockets!</span>")
eyes.Remove(M)
eyes.forceMove(get_turf(M))
else
to_chat(M, "<span class='userdanger'>Your eyes burn horrifically!</span>")
/*
@@ -75,11 +93,15 @@ Bonus
stage_speed = -2
transmittable = -4
level = 4
base_message_chance = 7
symptom_delay_min = 1
symptom_delay_max = 1
/datum/symptom/visionaid/Activate(datum/disease/advance/A)
..()
if(!..())
return
var/mob/living/M = A.affected_mob
var/obj/item/organ/eyes/eyes = M.getorganslot("eyes_sight")
var/obj/item/organ/eyes/eyes = M.getorganslot("eye_sight")
if (!eyes)
return
switch(A.stage)
@@ -102,6 +124,6 @@ Bonus
else if(eyes.eye_damage > 0)
M.adjust_eye_damage(-1)
else
if(prob(SYMPTOM_ACTIVATION_PROB * 3))
if(prob(base_message_chance))
to_chat(M, "<span class='notice'>[pick("Your eyes feel great.", "You are now blinking manually.", "You don't feel the need to blink.")]</span>")
return
@@ -0,0 +1,19 @@
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>")
@@ -3,10 +3,10 @@
Voice Change
Very Very noticable.
Lowers resistance considerably.
Noticeable.
Lowers resistance.
Decreases stage speed.
Reduced transmittable.
Increased transmittable.
Fatal Level.
Bonus
@@ -18,31 +18,59 @@ Bonus
/datum/symptom/voice_change
name = "Voice Change"
stealth = -2
resistance = -3
stage_speed = -3
transmittable = -1
stealth = -1
resistance = -2
stage_speed = -2
transmittable = 2
level = 6
severity = 2
base_message_chance = 100
symptom_delay_min = 60
symptom_delay_max = 120
var/scramble_language = FALSE
var/datum/language/current_language
var/datum/language_holder/original_language
/datum/symptom/voice_change/Activate(datum/disease/advance/A)
/datum/symptom/voice_change/Start(datum/disease/advance/A)
..()
if(prob(SYMPTOM_ACTIVATION_PROB))
if(A.properties["stealth"] >= 3)
suppress_warning = TRUE
if(A.properties["stage_rate"] >= 7) //faster change of voice
base_message_chance = 25
symptom_delay_min = 25
symptom_delay_max = 85
if(A.properties["transmittable"] >= 14) //random language
scramble_language = TRUE
var/mob/living/M = A.affected_mob
var/datum/language_holder/mob_language = M.get_language_holder()
original_language = mob_language.copy()
var/mob/living/carbon/M = A.affected_mob
switch(A.stage)
if(1, 2, 3, 4)
/datum/symptom/voice_change/Activate(datum/disease/advance/A)
if(!..())
return
var/mob/living/carbon/M = A.affected_mob
switch(A.stage)
if(1, 2, 3, 4)
if(prob(base_message_chance) && !suppress_warning)
to_chat(M, "<span class='warning'>[pick("Your throat hurts.", "You clear your throat.")]</span>")
else
if(ishuman(M))
var/mob/living/carbon/human/H = M
H.SetSpecialVoice(H.dna.species.random_name(H.gender))
return
else
if(ishuman(M))
var/mob/living/carbon/human/H = M
H.SetSpecialVoice(H.dna.species.random_name(H.gender))
if(scramble_language)
H.remove_language(current_language)
current_language = pick(subtypesof(/datum/language) - /datum/language/common)
H.grant_language(current_language)
var/datum/language_holder/mob_language = H.get_language_holder()
mob_language.only_speaks_language = current_language
/datum/symptom/voice_change/End(datum/disease/advance/A)
..()
if(ishuman(A.affected_mob))
var/mob/living/carbon/human/H = A.affected_mob
H.UnsetSpecialVoice()
return
if(scramble_language)
var/mob/living/M = A.affected_mob
M.copy_known_languages_from(original_language, TRUE)
current_language = null
QDEL_NULL(original_language)
+24 -72
View File
@@ -28,79 +28,31 @@ Bonus
transmittable = 1
level = 3
severity = 4
base_message_chance = 100
symptom_delay_min = 25
symptom_delay_max = 80
var/vomit_blood = FALSE
var/proj_vomit = 0
/datum/symptom/vomit/Start(datum/disease/advance/A)
..()
if(A.properties["stealth"] >= 4)
suppress_warning = TRUE
if(A.properties["resistance"] >= 7) //blood vomit
vomit_blood = TRUE
if(A.properties["transmittable"] >= 7) //projectile vomit
proj_vomit = 5
/datum/symptom/vomit/Activate(datum/disease/advance/A)
..()
if(prob(SYMPTOM_ACTIVATION_PROB / 2))
var/mob/living/M = A.affected_mob
switch(A.stage)
if(1, 2, 3, 4)
if(!..())
return
var/mob/living/M = A.affected_mob
switch(A.stage)
if(1, 2, 3, 4)
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)
else
vomit(M)
return
/datum/symptom/vomit/proc/Vomit(mob/living/carbon/M)
M.vomit(20)
/*
//////////////////////////////////////
Vomiting Blood
Very Very Noticable.
Decreases resistance.
Decreases stage speed.
Little transmittable.
Intense level.
Bonus
Forces the affected mob to vomit blood!
Meaning your disease can spread via
people walking on the blood.
Makes the affected mob lose health.
//////////////////////////////////////
*/
/datum/symptom/vomit/blood
name = "Blood Vomiting"
stealth = -2
resistance = -1
stage_speed = -1
transmittable = 1
level = 4
severity = 5
/datum/symptom/vomit/blood/Vomit(mob/living/carbon/M)
M.vomit(0,TRUE)
/*
//////////////////////////////////////
Projectile Vomiting
Very Very Noticable.
Decreases resistance.
Doesn't increase stage speed.
Little transmittable.
Medium Level.
Bonus
As normal vomiting, except it will spread further,
likely causing more to walk across the vomit.
//////////////////////////////////////
*/
/datum/symptom/vomit/projectile
name = "Projectile Vomiting"
stealth = -2
level = 4
/datum/symptom/vomit/projectile/Vomit(mob/living/carbon/M)
M.vomit(6, distance = 5)
/datum/symptom/vomit/proc/vomit(mob/living/carbon/M)
M.vomit(20, vomit_blood, distance = proj_vomit)
@@ -0,0 +1,30 @@
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)
+44 -31
View File
@@ -24,20 +24,26 @@ Bonus
transmittable = -2
level = 4
severity = 1
base_message_chance = 100
symptom_delay_min = 15
symptom_delay_max = 45
/datum/symptom/weight_gain/Activate(datum/disease/advance/A)
/datum/symptom/weight_gain/Start(datum/disease/advance/A)
..()
if(prob(SYMPTOM_ACTIVATION_PROB))
var/mob/living/M = A.affected_mob
switch(A.stage)
if(1, 2, 3, 4)
to_chat(M, "<span class='warning'>[pick("You feel blubbery.", "Your stomach hurts.")]</span>")
else
M.overeatduration = min(M.overeatduration + 100, 600)
M.nutrition = min(M.nutrition + 100, NUTRITION_LEVEL_FULL)
return
if(A.properties["stealth"] >= 4) //warn less often
base_message_chance = 25
/datum/symptom/weight_gain/Activate(datum/disease/advance/A)
if(!..())
return
var/mob/living/M = A.affected_mob
switch(A.stage)
if(1, 2, 3, 4)
if(prob(base_message_chance))
to_chat(M, "<span class='warning'>[pick("You feel blubbery.", "Your stomach hurts.")]</span>")
else
M.overeatduration = min(M.overeatduration + 100, 600)
M.nutrition = min(M.nutrition + 100, NUTRITION_LEVEL_FULL)
/*
//////////////////////////////////////
@@ -66,20 +72,27 @@ Bonus
transmittable = -2
level = 3
severity = 1
base_message_chance = 100
symptom_delay_min = 15
symptom_delay_max = 45
/datum/symptom/weight_loss/Activate(datum/disease/advance/A)
/datum/symptom/weight_loss/Start(datum/disease/advance/A)
..()
if(prob(SYMPTOM_ACTIVATION_PROB))
var/mob/living/M = A.affected_mob
switch(A.stage)
if(1, 2, 3, 4)
to_chat(M, "<span class='warning'>[pick("You feel hungry.", "You crave for food.")]</span>")
else
to_chat(M, "<span class='warning'><i>[pick("So hungry...", "You'd kill someone for a bite of food...", "Hunger cramps seize you...")]</i></span>")
M.overeatduration = max(M.overeatduration - 100, 0)
M.nutrition = max(M.nutrition - 100, 0)
if(A.properties["stealth"] >= 4) //warn less often
base_message_chance = 25
return
/datum/symptom/weight_loss/Activate(datum/disease/advance/A)
if(!..())
return
var/mob/living/M = A.affected_mob
switch(A.stage)
if(1, 2, 3, 4)
if(prob(base_message_chance))
to_chat(M, "<span class='warning'>[pick("You feel hungry.", "You crave for food.")]</span>")
else
to_chat(M, "<span class='warning'><i>[pick("So hungry...", "You'd kill someone for a bite of food...", "Hunger cramps seize you...")]</i></span>")
M.overeatduration = max(M.overeatduration - 100, 0)
M.nutrition = max(M.nutrition - 100, 0)
/*
//////////////////////////////////////
@@ -108,14 +121,14 @@ Bonus
stage_speed = -2
transmittable = -2
level = 4
symptom_delay_min = 5
symptom_delay_max = 5
/datum/symptom/weight_even/Activate(datum/disease/advance/A)
..()
if(prob(SYMPTOM_ACTIVATION_PROB))
var/mob/living/M = A.affected_mob
switch(A.stage)
if(4, 5)
M.overeatduration = 0
M.nutrition = NUTRITION_LEVEL_WELL_FED + 50
return
if(!..())
return
var/mob/living/M = A.affected_mob
switch(A.stage)
if(4, 5)
M.overeatduration = 0
M.nutrition = NUTRITION_LEVEL_WELL_FED + 50
+29 -28
View File
@@ -23,33 +23,34 @@ BONUS
stage_speed = 4
transmittable = -4
level = 5
base_message_chance = 100
symptom_delay_min = 25
symptom_delay_max = 50
/datum/symptom/youth/Activate(datum/disease/advance/A)
..()
if(prob(SYMPTOM_ACTIVATION_PROB * 2))
var/mob/living/M = A.affected_mob
if(ishuman(M))
var/mob/living/carbon/human/H = M
switch(A.stage)
if(1)
if(H.age > 41)
H.age = 41
to_chat(H, "<span class='notice'>You haven't had this much energy in years!</span>")
if(2)
if(H.age > 36)
H.age = 36
to_chat(H, "<span class='notice'>You're suddenly in a good mood.</span>")
if(3)
if(H.age > 31)
H.age = 31
to_chat(H, "<span class='notice'>You begin to feel more lithe.</span>")
if(4)
if(H.age > 26)
H.age = 26
to_chat(H, "<span class='notice'>You feel reinvigorated.</span>")
if(5)
if(H.age > 21)
H.age = 21
to_chat(H, "<span class='notice'>You feel like you can take on the world!</span>")
return
if(!..())
return
var/mob/living/M = A.affected_mob
if(ishuman(M))
var/mob/living/carbon/human/H = M
switch(A.stage)
if(1)
if(H.age > 41)
H.age = 41
to_chat(H, "<span class='notice'>You haven't had this much energy in years!</span>")
if(2)
if(H.age > 36)
H.age = 36
to_chat(H, "<span class='notice'>You're suddenly in a good mood.</span>")
if(3)
if(H.age > 31)
H.age = 31
to_chat(H, "<span class='notice'>You begin to feel more lithe.</span>")
if(4)
if(H.age > 26)
H.age = 26
to_chat(H, "<span class='notice'>You feel reinvigorated.</span>")
if(5)
if(H.age > 21)
H.age = 21
to_chat(H, "<span class='notice'>You feel like you can take on the world!</span>")
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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
+5 -3
View File
@@ -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
+1 -1
View File
@@ -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)
+2 -2
View File
@@ -206,8 +206,8 @@
continue
if(extended_safety_checks)
if(istype(F, /turf/open/floor/plating/lava)) //chasms aren't /floor, and so are pre-filtered
var/turf/open/floor/plating/lava/L = F
if(istype(F, /turf/open/lava)) //chasms aren't /floor, and so are pre-filtered
var/turf/open/lava/L = F
if(!L.is_safe())
continue
+1 -1
View File
@@ -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)
+1 -1
View File
@@ -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)
+11 -5
View File
@@ -13,7 +13,7 @@
mind.transfer_to(new_mob)
- You must not assign key= or ckey= after transfer_to() since the transfer_to transfers the client for you.
By setting key or ckey explicitly after transfering the mind with transfer_to you will cause bugs like DCing
By setting key or ckey explicitly after transferring the mind with transfer_to you will cause bugs like DCing
the player.
- IMPORTANT NOTE 2, if you want a player to become a ghost, use mob.ghostize() It does all the hard work for you.
@@ -97,7 +97,7 @@
language_holder = mob_holder.copy(src)
if(key)
if(new_character.key != key) //if we're transfering into a body with a key associated which is not ours
if(new_character.key != key) //if we're transferring into a body with a key associated which is not ours
new_character.ghostize(1) //we'll need to ghostize so that key isn't mobless.
else
key = new_character.key
@@ -786,7 +786,7 @@
if(!def_value)//If it's a custom objective, it will be an empty string.
def_value = "custom"
var/new_obj_type = input("Select objective type:", "Objective type", def_value) as null|anything in list("assassinate", "maroon", "debrain", "protect", "destroy", "prevent", "hijack", "escape", "survive", "martyr", "steal", "download", "nuclear", "capture", "absorb", "custom")
var/new_obj_type = input("Select objective type:", "Objective type", def_value) as null|anything in list("assassinate", "late-assassinate", "maroon", "debrain", "protect", "destroy", "prevent", "hijack", "escape", "survive", "martyr", "steal", "download", "nuclear", "capture", "absorb", "custom")
if (!new_obj_type)
return
@@ -821,6 +821,12 @@
//Will display as special role if the target is set as MODE. Ninjas/commandos/nuke ops.
new_objective.update_explanation_text()
if ("late-assassinate")
new_objective = new /datum/objective/assassinate/late
new_objective.owner = src
new_objective.target = null
new_objective.find_target() //This will begin the "find-target" loop and update their explanation text
if ("destroy")
var/list/possible_targets = active_ais(1)
if(possible_targets.len)
@@ -1592,9 +1598,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
+1 -1
View File
@@ -261,7 +261,7 @@
var/turf/next = get_step(ridden, direction)
var/turf/current = get_turf(ridden)
if(istype(next, /turf/open/floor/plating/lava) || istype(current, /turf/open/floor/plating/lava)) //We can move from land to lava, or lava to land, but not from land to land
if(istype(next, /turf/open/lava) || istype(current, /turf/open/lava)) //We can move from land to lava, or lava to land, but not from land to land
..()
else
to_chat(user, "Boats don't go on land!")
+13 -6
View File
@@ -91,14 +91,21 @@
probability = 90
/datum/weather/ash_storm/impact(mob/living/L)
if(istype(L.loc, /obj/mecha))
return
if(ishuman(L))
/datum/weather/ash_storm/proc/is_ash_immune(mob/living/L)
if(istype(L.loc, /obj/mecha)) //Mechs are immune
return TRUE
if(ishuman(L)) //Are you immune?
var/mob/living/carbon/human/H = L
var/thermal_protection = H.get_thermal_protection()
if(thermal_protection >= FIRE_IMMUNITY_SUIT_MAX_TEMP_PROTECT)
return
return TRUE
if(istype(L.loc, /mob/living) && L.loc != L) //Matryoshka check
return is_ash_immune(L.loc)
return FALSE //RIP you
/datum/weather/ash_storm/impact(mob/living/L)
if(is_ash_immune(L))
return
L.adjustFireLoss(4)
/datum/weather/ash_storm/emberfall //Emberfall: An ash storm passes by, resulting in harmless embers falling like snow. 10% to happen in place of an ash storm.
@@ -215,4 +222,4 @@
/datum/weather/acid_rain/impact(mob/living/L)
var/resist = L.getarmor(null, "acid")
if(prob(max(0,100-resist)))
L.acid_act(20,20)
L.acid_act(20,20)
+6 -6
View File
@@ -1240,7 +1240,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
valid_territory = FALSE
/area/storage/tcom
name = "Telecoms Storage"
name = "Telecomms Storage"
icon_state = "green"
valid_territory = FALSE
@@ -1416,7 +1416,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
ambientsounds = list('sound/ambience/ambisin2.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/ambigen10.ogg')
/area/tcommsat/entrance
name = "Telecoms Teleporter"
name = "Telecomms Teleporter"
icon_state = "tcomsatentrance"
/area/tcommsat/chamber
@@ -1424,12 +1424,12 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
icon_state = "tcomsatcham"
/area/ai_monitored/turret_protected/tcomsat
name = "Telecoms Satellite"
name = "Telecomms Satellite"
icon_state = "tcomsatlob"
ambientsounds = list('sound/ambience/ambisin2.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/ambigen10.ogg')
/area/ai_monitored/turret_protected/tcomfoyer
name = "Telecoms Foyer"
name = "Telecomms Foyer"
icon_state = "tcomsatentrance"
ambientsounds = list('sound/ambience/ambisin2.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/ambigen10.ogg')
@@ -1444,11 +1444,11 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
ambientsounds = list('sound/ambience/ambisin2.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/ambigen10.ogg')
/area/tcommsat/computer
name = "Telecoms Control Room"
name = "Telecomms Control Room"
icon_state = "tcomsatcomp"
/area/tcommsat/server
name = "Telecoms Server Room"
name = "Telecomms Server Room"
icon_state = "tcomsatcham"
/area/tcommsat/lounge
+2 -2
View File
@@ -432,7 +432,7 @@ GLOBAL_LIST_EMPTY(teleportlocs)
// Ambience goes down here -- make sure to list each area seperately for ease of adding things in later, thanks! Note: areas adjacent to each other should have the same sounds to prevent cutoff when possible.- LastyScratch
if(L.client && !L.client.ambience_playing && L.client.prefs.toggles & SOUND_SHIP_AMBIENCE)
L.client.ambience_playing = 1
L << sound('sound/ambience/shipambience.ogg', repeat = 1, wait = 0, volume = 35, channel = 2)
L << sound('sound/ambience/shipambience.ogg', repeat = 1, wait = 0, volume = 35, channel = CHANNEL_BUZZ)
if(!(L.client && (L.client.prefs.toggles & SOUND_AMBIENCE)))
return //General ambience check is below the ship ambience so one can play without the other
@@ -441,7 +441,7 @@ GLOBAL_LIST_EMPTY(teleportlocs)
var/sound = pick(ambientsounds)
if(!L.client.played)
L << sound(sound, repeat = 0, wait = 0, volume = 25, channel = 1)
L << sound(sound, repeat = 0, wait = 0, volume = 25, channel = CHANNEL_AMBIENCE)
L.client.played = 1
sleep(600) //ewww - this is very very bad
if(L.&& L.client)
+4 -4
View File
@@ -21,28 +21,28 @@
if(!linked)
return 0
var/area/A = get_area(linked)
ASSERT(!istype(A,/area/holodeck))
ASSERT(!istype(A, /area/holodeck))
return A.powered(chan)
/area/holodeck/usage(var/chan)
if(!linked)
return 0
var/area/A = get_area(linked)
ASSERT(!istype(A,/area/holodeck))
ASSERT(!istype(A, /area/holodeck))
return A.usage(chan)
/area/holodeck/addStaticPower(value, powerchannel)
if(!linked)
return
var/area/A = get_area(linked)
ASSERT(!istype(A,/area/holodeck))
ASSERT(!istype(A, /area/holodeck))
return A.addStaticPower(value,powerchannel)
/area/holodeck/use_power(var/amount, var/chan)
if(!linked)
return 0
var/area/A = get_area(linked)
ASSERT(!istype(A,/area/holodeck))
ASSERT(!istype(A, /area/holodeck))
return A.use_power(amount,chan)
+1 -1
View File
@@ -143,7 +143,7 @@
if(T.z != ZLEVEL_CENTCOM)//if not, don't bother
return 0
if(istype(T.loc,/area/shuttle/syndicate) || istype(T.loc,/area/syndicate_mothership))
if(istype(T.loc, /area/shuttle/syndicate) || istype(T.loc, /area/syndicate_mothership))
return 1
return 0
+10
View File
@@ -0,0 +1,10 @@
diff a/code/game/atoms.dm b/code/game/atoms.dm (rejected hunks)
@@ -126,7 +126,7 @@
return TRUE
//finally check for centcom itself
- return istype(T.loc,/area/centcom)
+ return istype(T.loc, /area/centcom)
/atom/proc/onSyndieBase()
var/turf/T = get_turf(src)
+3 -3
View File
@@ -202,17 +202,17 @@
holder = hud_list[i]
holder.icon_state = null
for(var/obj/item/weapon/implant/I in implants)
if(istype(I,/obj/item/weapon/implant/tracking))
if(istype(I, /obj/item/weapon/implant/tracking))
holder = hud_list[IMPTRACK_HUD]
var/icon/IC = icon(icon, icon_state, dir)
holder.pixel_y = IC.Height() - world.icon_size
holder.icon_state = "hud_imp_tracking"
else if(istype(I,/obj/item/weapon/implant/mindshield))
else if(istype(I, /obj/item/weapon/implant/mindshield))
holder = hud_list[IMPLOYAL_HUD]
var/icon/IC = icon(icon, icon_state, dir)
holder.pixel_y = IC.Height() - world.icon_size
holder.icon_state = "hud_imp_loyal"
else if(istype(I,/obj/item/weapon/implant/chem))
else if(istype(I, /obj/item/weapon/implant/chem))
holder = hud_list[IMPCHEM_HUD]
var/icon/IC = icon(icon, icon_state, dir)
holder.pixel_y = IC.Height() - world.icon_size
+1 -1
View File
@@ -62,7 +62,7 @@
return ..()
/datum/game_mode/proc/auto_declare_completion_blob()
if(istype(SSticker.mode,/datum/game_mode/blob) )
if(istype(SSticker.mode, /datum/game_mode/blob) )
var/datum/game_mode/blob/blob_mode = src
if(blob_mode.blob_overminds.len)
var/text = "<FONT size = 2><B>The blob[(blob_mode.blob_overminds.len > 1 ? "s were" : " was")]:</B></FONT>"
@@ -23,7 +23,7 @@
and tearing!</span>")
user.emote("scream")
user.regenerate_limbs(0, list("head"))
user.regenerate_organs()
user.regenerate_organs()
to_chat(user, "<span class='notice'>We have revived ourselves.</span>")
user.mind.changeling.purchasedpowers -= src
return TRUE
+85
View File
@@ -0,0 +1,85 @@
#define MIN_LATE_TARGET_TIME 600 //lower bound of re-rolled timer, 1 min
#define MAX_LATE_TARGET_TIME 6000 //upper bound of re-rolled timer, 10 min
#define LATE_TARGET_HIT_CHANCE 70 //How often would the find_target succeed, otherwise it re-rolls later and tries again.
//Hit chance is here to avoid people checking github and then hovering around new arrivals within the max minute range every round.
/datum/objective/assassinate/late
martyr_compatible = FALSE
/datum/objective/assassinate/late/find_target()
var/list/possible_targets = list()
for(var/mob/M in GLOB.latejoiners)
var/datum/mind/possible_target = M.mind
if(possible_target != owner && ishuman(possible_target.current) && (possible_target.current.stat != 2) && is_unique_objective(possible_target))
possible_targets += possible_target
if(possible_targets.len > 0 && prob(LATE_TARGET_HIT_CHANCE))
target = pick(possible_targets)
martyr_compatible = TRUE //Might never matter, but I guess if an admin gives another random objective, this should now be compatible
update_explanation_text()
message_admins("[target] has been selected as the assassination target of [owner].")
log_game("[target] has been selected as the assassination target of [owner].")
to_chat(owner, "<span class='italics'>You hear a crackling noise in your ears, as a one-way syndicate message plays:</span>")
to_chat(owner, "<span class='userdanger'><font size=5>You target has been located. To succeed, find and eliminate [target], the [!target_role_type ? target.assigned_role : target.special_role].</font></span>")
return target
else
update_explanation_text()
addtimer(CALLBACK(src, .proc/find_target),rand(MIN_LATE_TARGET_TIME, MAX_LATE_TARGET_TIME))
return null
/datum/objective/assassinate/late/find_target_by_role(role, role_type=0, invert=0)
var/list/possible_targets = list()
for(var/mob/M in GLOB.latejoiners)
var/datum/mind/possible_target = M.mind
if((possible_target != owner) && ishuman(possible_target.current))
var/is_role = 0
if(role_type)
if(possible_target.special_role == role)
is_role++
else
if(possible_target.assigned_role == role)
is_role++
if(invert)
if(is_role)
continue
possible_targets += possible_target
//break
else if(is_role)
possible_targets += possible_target
//break
if(possible_targets && prob(LATE_TARGET_HIT_CHANCE))
target = pick(possible_targets)
update_explanation_text()
message_admins("[target] has been selected as the assassination target of [owner].")
log_game("[target] has been selected as the assassination target of [owner].")
to_chat(owner, "<span class='italics'>You hear a crackling noise in your ears, as a one-way syndicate message plays:</span>")
to_chat(owner, "<span class='userdanger'><font size=5>You target has been located. To succeed, find and eliminate [target], the [!target_role_type ? target.assigned_role : target.special_role].</font></span>")
else
update_explanation_text()
addtimer(CALLBACK(src, .proc/find_target_by_role, role, role_type, invert),rand(MIN_LATE_TARGET_TIME, MAX_LATE_TARGET_TIME))
/datum/objective/assassinate/late/check_completion()
if(target && target.current) //If target WAS assigned
if(target.current.stat == DEAD || issilicon(target.current) || isbrain(target.current) || target.current.z > 6 || !target.current.ckey) //Borgs/brains/AIs count as dead for traitor objectives. --NeoFite
return TRUE
return FALSE
else //If no target was ever given
if(!owner.current || owner.current.stat == DEAD || isbrain(owner.current))
return FALSE
if(!is_special_character(owner.current))
return FALSE
return TRUE
/datum/objective/assassinate/late/update_explanation_text()
//..()
if(target && target.current)
explanation_text = "Assassinate [target.name], the [!target_role_type ? target.assigned_role : target.special_role]."
else
explanation_text = "Stay alive until your target arrives on the station, you will be notified when the target has been identified."
@@ -20,7 +20,7 @@
return ..()
/obj/effect/clockwork/sigil/attack_hand(mob/user)
if(iscarbon(user) && !user.stat && (!is_servant_of_ratvar(user) || (is_servant_of_ratvar(user) && user.a_intent == INTENT_HARM)))
if(iscarbon(user) && !user.stat && !is_servant_of_ratvar(user))
user.visible_message("<span class='warning'>[user] stamps out [src]!</span>", "<span class='danger'>You stomp on [src], scattering it into thousands of particles.</span>")
qdel(src)
return 1
@@ -175,7 +175,7 @@
/obj/effect/clockwork/sigil/transmission
name = "suspicious sigil"
desc = "A glowing orange sigil. The air around it feels staticky."
clockwork_desc = "A sigil that will serve as a battery for clockwork structures."
clockwork_desc = "A sigil that serves as power generation and a battery for clockwork structures."
icon_state = "sigiltransmission"
alpha = 50
color = "#EC8A2D"
@@ -183,7 +183,12 @@
resist_string = "glows faintly"
sigil_name = "Sigil of Transmission"
affects_servants = TRUE
var/power_charge = CLOCKCULT_POWER_UNIT //starts with CLOCKCULT_POWER_UNIT by default
var/power_charge = 0 //starts with no power
var/drain_range = 14
/obj/effect/clockwork/sigil/transmission/Initialize()
. = ..()
update_glow()
/obj/effect/clockwork/sigil/transmission/ex_act(severity)
if(severity == 3)
@@ -199,7 +204,8 @@
for(var/obj/structure/destructible/clockwork/powered/P in range(SIGIL_ACCESS_RANGE, src))
structure_number++
to_chat(user, "<span class='[power_charge ? "brass":"alloy"]'>It is storing <b>[GLOB.ratvar_awakens ? "INFINITY":"[power_charge]"]W</b> of power, \
and <b>[structure_number]</b> Clockwork Structure[structure_number == 1 ? "":"s"] [structure_number == 1 ? "is":"are"] in range.</span>")
and <b>[structure_number]</b> Clockwork Structure[structure_number == 1 ? " is":"s are"] in range.</span>")
to_chat(user, "<span class='brass'>While active, it will gradually drain power from nearby electronics. It is currently [isprocessing ? "active":"disabled"].</span>")
if(iscyborg(user))
to_chat(user, "<span class='brass'>You can recharge from the [sigil_name] by crossing it.</span>")
else if(!GLOB.ratvar_awakens)
@@ -218,6 +224,20 @@
return TRUE
return ..()
/obj/effect/clockwork/sigil/transmission/attack_ai(mob/user)
if(is_servant_of_ratvar(user))
attack_hand(user)
/obj/effect/clockwork/sigil/transmission/attack_hand(mob/user)
if(is_servant_of_ratvar(user))
visible_message("<span class='notice'>[user] [isprocessing ? "de":""]activates [src].</span>", "<span class='brass'>You [isprocessing ? "de":""]activate the [sigil_name].</span>")
if(isprocessing)
STOP_PROCESSING(SSobj, src)
else
START_PROCESSING(SSobj, src)
else
return ..()
/obj/effect/clockwork/sigil/transmission/sigil_effects(mob/living/L)
if(is_servant_of_ratvar(L))
if(iscyborg(L))
@@ -225,6 +245,20 @@
else if(power_charge)
to_chat(L, "<span class='brass'>You feel a slight, static shock.</span>")
/obj/effect/clockwork/sigil/transmission/process()
var/power_drained = 0
for(var/t in spiral_range_turfs(drain_range, src))
var/turf/T = t
for(var/M in T)
var/atom/movable/A = M
power_drained += A.power_drain(TRUE)
CHECK_TICK
modify_charge(-Floor(power_drained, MIN_CLOCKCULT_POWER))
new /obj/effect/temp_visual/ratvar/sigil/transmission(loc, 1 + (power_drained * 0.0035))
/obj/effect/clockwork/sigil/transmission/proc/charge_cyborg(mob/living/silicon/robot/cyborg)
if(!cyborg_checks(cyborg))
return
@@ -259,10 +293,6 @@
return FALSE
return TRUE
/obj/effect/clockwork/sigil/transmission/Initialize()
. = ..()
update_glow()
/obj/effect/clockwork/sigil/transmission/proc/modify_charge(amount)
if(GLOB.ratvar_awakens)
update_glow()
@@ -6,7 +6,7 @@
if(cell && cell.charge)
playsound(src, "sparks", 50, 1)
flick("apc-spark", src)
. = min(cell.charge, 250)
. = min(cell.charge, MIN_CLOCKCULT_POWER*3)
cell.use(.) //Better than a power sink!
if(!cell.charge && !shorted)
shorted = 1
@@ -16,7 +16,7 @@
/obj/machinery/power/smes/power_drain(clockcult_user)
if(charge)
. = min(charge, 250)
. = min(charge, MIN_CLOCKCULT_POWER*3)
charge -= . * 50
if(!charge && !panel_open)
panel_open = TRUE
@@ -27,29 +27,18 @@
/obj/item/weapon/stock_parts/cell/power_drain(clockcult_user)
if(charge)
. = min(charge, 250)
. = min(charge, MIN_CLOCKCULT_POWER*3)
charge = use(.)
update_icon()
/obj/machinery/light/power_drain(clockcult_user)
if(on)
playsound(src, 'sound/effects/light_flicker.ogg', 50, 1)
. = 250
if(prob(50))
burn_out()
/mob/living/silicon/robot/power_drain(clockcult_user)
if((!clockcult_user || !is_servant_of_ratvar(src)) && cell && cell.charge)
. = min(cell.charge, 250)
. = min(cell.charge, MIN_CLOCKCULT_POWER*4)
cell.use(.)
if(prob(20))
to_chat(src, "<span class='userdanger'>ERROR: Power loss detected!</span>")
spark_system.start()
/obj/mecha/power_drain(clockcult_user)
if((!clockcult_user || !occupant || occupant && !is_servant_of_ratvar(occupant)) && cell && cell.charge)
. = min(cell.charge, 250)
if((!clockcult_user || (occupant && !is_servant_of_ratvar(occupant))) && cell && cell.charge)
. = min(cell.charge, MIN_CLOCKCULT_POWER*4)
cell.use(.)
if(prob(20))
occupant_message("<span class='userdanger'>Power loss detected!</span>")
spark_system.start()
@@ -49,7 +49,7 @@
/turf/open/floor/plating/ashplanet/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent)
return FALSE
/turf/open/floor/plating/lava/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent)
/turf/open/lava/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent)
return FALSE
/turf/open/floor/clockwork/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent)
@@ -6,6 +6,7 @@
Clockwork slabs will only make components if held or if inside an item held by a human, and when making a component will prevent all other slabs held from making components.\n\
Hitting a slab, a Servant with a slab, or a cache will <b>transfer</b> this slab's components into the target, the target's slab, or the global cache, respectively."
icon_state = "dread_ipad"
var/inhand_overlay //If applicable, this overlay will be applied to the slab's inhand
slot_flags = SLOT_BELT
w_class = WEIGHT_CLASS_SMALL
var/list/stored_components = list(BELLIGERENT_EYE = 0, VANGUARD_COGWHEEL = 0, GEIS_CAPACITOR = 0, REPLICANT_ALLOY = 0, HIEROPHANT_ANSIBLE = 0)
@@ -50,9 +51,9 @@
maximum_quickbound = 6 //we usually have one or two unique scriptures, so if ratvar is up let us bind one more
actions_types = list()
/obj/item/clockwork/slab/cyborg/engineer //five scriptures, plus a fabricator
/obj/item/clockwork/slab/cyborg/engineer //four scriptures, plus a fabricator
quickbound = list(/datum/clockwork_scripture/create_object/replicant, /datum/clockwork_scripture/create_object/cogscarab, \
/datum/clockwork_scripture/create_object/soul_vessel, /datum/clockwork_scripture/create_object/sigil_of_transmission, /datum/clockwork_scripture/create_object/interdiction_lens)
/datum/clockwork_scripture/create_object/soul_vessel, /datum/clockwork_scripture/create_object/sigil_of_transmission)
/obj/item/clockwork/slab/cyborg/medical //five scriptures, plus a spear
quickbound = list(/datum/clockwork_scripture/ranged_ability/linked_vanguard, /datum/clockwork_scripture/ranged_ability/sentinels_compromise, \
@@ -105,6 +106,12 @@
. = ..()
addtimer(CALLBACK(src, .proc/check_on_mob, user), 1) //dropped is called before the item is out of the slot, so we need to check slightly later
/obj/item/clockwork/slab/worn_overlays(isinhands = FALSE, icon_file)
. = list()
if(isinhands && item_state && inhand_overlay)
var/mutable_appearance/M = mutable_appearance(icon_file, "slab_[inhand_overlay]")
. += M
/obj/item/clockwork/slab/proc/check_on_mob(mob/user)
if(user && !(src in user.held_items) && slab_ability && slab_ability.ranged_ability_user) //if we happen to check and we AREN'T in user's hands, remove whatever ability we have
slab_ability.remove_ranged_ability()
@@ -415,17 +422,16 @@
dat += "<font color=#BE8700><b>Marauder:</b></font> A clockwork marauder, which is a powerful bodyguard that hides in its owner.<br><br>"
dat += "<font color=#BE8700 size=3>Structures (* = requires power)</font><br>"
dat += "<font color=#BE8700><b>Warden:</b></font> An ocular warden, which is a ranged turret that damages non-Servants that see it.<br>"
dat += "<font color=#BE8700><b>Daemon*:</b></font> A tinkerer's daemon, which quickly creates components.<br>"
dat += "<font color=#BE8700><b>Lens*:</b></font> An interdiction lens, which sabotages machinery in a large area to create power.<br>"
dat += "<font color=#BE8700><b>Obelisk*:</b></font> A clockwork obelisk, which can broadcast large messages and allows limited teleportation.<br>"
dat += "<font color=#BE8700><b>Motor*:</b></font> A mania motor, which serves as area-denial through negative effects and eventual conversion.<br>"
dat += "<font color=#BE8700><b>Prism*:</b></font> A prolonging prism, which delays the shuttle for two minutes at a huge power cost.<br><br>"
dat += "<font color=#BE8700><b>Motor*:</b></font> A mania motor, which serves as area-denial through negative effects and eventual conversion.<br>"
dat += "<font color=#BE8700><b>Daemon*:</b></font> A tinkerer's daemon, which quickly creates components.<br>"
dat += "<font color=#BE8700><b>Obelisk*:</b></font> A clockwork obelisk, which can broadcast large messages and allows limited teleportation.<br>"
dat += "<font color=#BE8700 size=3>Sigils</font><br>"
dat += "<i>Note: Sigils can be stacked on top of one another, making certain sigils very effective when paired!</i><br>"
dat += "<font color=#BE8700><b>Transgression:</b></font> Stuns the first non-Servant to cross it for ten seconds and blinds others nearby. Disappears on use.<br>"
dat += "<font color=#BE8700><b>Submission:</b></font> Converts the first non-Servant to stand on the sigil for seven seconds. Disappears on use.<br>"
dat += "<font color=#BE8700><b>Accession:</b></font> Identical to the Sigil of Submission, but doesn't disappear on use. It can also convert a single mindshielded target, but will disappear after doing this.<br>"
dat += "<font color=#BE8700><b>Transmission:</b></font> Stores power for clockwork structures. Feeding it brass sheets will create power.<br><br>"
dat += "<font color=#BE8700><b>Transmission:</b></font> Drains and stores power for clockwork structures. Feeding it brass sheets will create power.<br><br>"
dat += "<font color=#BE8700 size=3>-=-=-=-=-=-</font>"
if("Components")
var/servants = 0 //Calculate the current production time for slab components
@@ -494,12 +500,11 @@
becomes necessary: <b>power</b>. Almost all clockwork structures require power to function in some way. There is nothing special about this power; it's mere electricity, \
and can be harnessed in several ways.<br><br>"
dat += "To begin with, if there is no other source of power nearby, structures will draw from the area's APC, assuming it has one. This is inefficient and ill-advised as \
anything but a last resort. Instead, it is recommended that a <b>sigil of transmission</b> is created. This sigil serves as a sort of battery for nearby clockwork \
anything but a last resort. Instead, it is recommended that a <b>Sigil of Transmission</b> is created. This sigil serves as both battery and power generator for nearby clockwork \
structures, and those structures will happily draw power from the sigil before they resort to pathetic APCs and other sources of energy.<br><br>"
dat += "Generating power is less easy. The most reliable and efficient way is using brass sheets; attacking a sigil of transmission with brass sheets will convert them \
to power, at a rate of <b>[POWER_FLOOR]W</b> per sheet. (Brass sheets are created from replica fabricators, which are explained more in detail in the <b>Conversion</b> \
section.) There are also structures that <i>generate</i> power instead of consuming it; for instance, the interdiction lens sabotages all non-clockwork machines in a \
very large area and creates power from doing so. This allows Servants to simultaneously cripple an entire department as well as fueling their own machinery.<br><br>"
dat += "The most reliable and efficient way to generate power is by using brass sheets; attacking a sigil of transmission with brass sheets will convert them \
to power, at a rate of <b>[POWER_FLOOR]W</b> per sheet. (Brass sheets are created from replica fabricators, which are explained more in detail in the <b>Conversion</b> section.) \
Activating a sigil of transmission will also cause it to drain power from the nearby area, which, while effective, serves as an obvious tell that there is something wrong.<br><br>"
dat += "Without power, many structures will not function, making a base vulnerable to attack. For this reason, it is critical that you keep an eye on your power reserves and \
ensure that they remain comfortably high.<br><br>"
dat += "<font color=#BE8700 size=3>-=-=-=-=-=-</font>"
@@ -259,7 +259,7 @@ Judgement: 12 servants, 5 caches, 300 CV, and any existing AIs are converted or
//Uses a ranged slab ability, returning only when the ability no longer exists(ie, when interrupted) or finishes.
/datum/clockwork_scripture/ranged_ability
var/slab_icon = "dread_ipad"
var/slab_overlay
var/ranged_type = /obj/effect/proc_holder/slab
var/ranged_message = "This is a huge goddamn bug, how'd you cast this?"
var/timeout_time = 0
@@ -271,7 +271,10 @@ Judgement: 12 servants, 5 caches, 300 CV, and any existing AIs are converted or
return ..()
/datum/clockwork_scripture/ranged_ability/scripture_effects()
slab.icon_state = slab_icon
if(slab_overlay)
slab.add_overlay(slab_overlay)
slab.item_state = "clockwork_slab"
slab.inhand_overlay = slab_overlay
slab.slab_ability = new ranged_type(slab)
slab.slab_ability.slab = slab
slab.slab_ability.add_ranged_ability(invoker, ranged_message)
@@ -294,7 +297,9 @@ Judgement: 12 servants, 5 caches, 300 CV, and any existing AIs are converted or
successful = slab.slab_ability.successful
if(!slab.slab_ability.finished)
slab.slab_ability.remove_ranged_ability()
slab.icon_state = "dread_ipad"
slab.cut_overlays()
slab.item_state = initial(slab.item_state)
slab.inhand_overlay = null
if(invoker)
invoker.update_inv_hands()
return successful //slab doesn't look like a word now.

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