Merge branch 'master' into custom_roundstart_items
This commit is contained in:
@@ -78,7 +78,7 @@
|
||||
//If you specify a value the FIRST ONE is removed
|
||||
/datum/linked_list/proc/Remove(node)
|
||||
var/datum/linked_node/removing
|
||||
if(istype(node,/datum/linked_node))
|
||||
if(istype(node, /datum/linked_node))
|
||||
removing = node
|
||||
else
|
||||
//optimise removing head and tail, no point looping for them, especially the tail
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
diff a/code/__DEFINES/DNA.dm b/code/__DEFINES/DNA.dm (rejected hunks)
|
||||
@@ -114,4 +114,6 @@
|
||||
#define EASYLIMBATTACHMENT 23
|
||||
#define TOXINLOVER 24
|
||||
#define DIGITIGRADE 25 //Uses weird leg sprites. Optional for Lizards, required for ashwalkers. Don't give it to other races unless you make sprites for this (see human_parts_greyscale.dmi)
|
||||
-#define NO_UNDERWEAR 26
|
||||
+#define NO_UNDERWEAR 26
|
||||
+#define NOLIVER 27
|
||||
+#define NOSTOMACH 28
|
||||
@@ -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
|
||||
@@ -67,8 +67,8 @@
|
||||
#define PLASMA_MINIMUM_OXYGEN_NEEDED 2
|
||||
#define PLASMA_MINIMUM_OXYGEN_PLASMA_RATIO 30
|
||||
#define PLASMA_OXYGEN_FULLBURN 10
|
||||
#define MIN_PLASMA_DAMAGE 1
|
||||
#define MAX_PLASMA_DAMAGE 10
|
||||
#define MIN_TOXIC_GAS_DAMAGE 1
|
||||
#define MAX_TOXIC_GAS_DAMAGE 10
|
||||
#define MOLES_PLASMA_VISIBLE 0.5 //Moles in a standard cell after which plasma is visible
|
||||
//Plasma fusion properties
|
||||
#define PLASMA_BINDING_ENERGY 3000000
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
#define ANTAG_HUD_SINTOUCHED 16
|
||||
#define ANTAG_HUD_SOULLESS 17
|
||||
#define ANTAG_HUD_CLOCKWORK 18
|
||||
#define ANTAG_HUD_BORER 19
|
||||
|
||||
// Notification action types
|
||||
#define NOTIFY_JUMP "jump"
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
GLOBAL_VAR_INIT(clockwork_construction_value, 0) //The total value of all structures built by the clockwork cult
|
||||
GLOBAL_VAR_INIT(clockwork_caches, 0) //How many clockwork caches exist in the world (not each individual)
|
||||
GLOBAL_VAR_INIT(clockwork_vitality, 0) //How much Vitality is stored, total
|
||||
GLOBAL_LIST_EMPTY(active_daemons) //A list of all active tinkerer's daemons
|
||||
GLOBAL_LIST_EMPTY(all_clockwork_objects) //All clockwork items, structures, and effects in existence
|
||||
GLOBAL_LIST_EMPTY(all_clockwork_mobs) //All clockwork SERVANTS (not creatures) in existence
|
||||
|
||||
+147
-144
@@ -1,147 +1,150 @@
|
||||
/*ALL DEFINES RELATED TO COMBAT GO HERE*/
|
||||
|
||||
//Damage and status effect defines
|
||||
|
||||
//Damage defines //TODO: merge these down to reduce on defines
|
||||
#define BRUTE "brute"
|
||||
#define BURN "fire"
|
||||
#define TOX "tox"
|
||||
#define OXY "oxy"
|
||||
#define CLONE "clone"
|
||||
#define STAMINA "stamina"
|
||||
//citadel code
|
||||
#define AROUSAL "arousal"
|
||||
|
||||
//bitflag damage defines used for suicide_act
|
||||
#define BRUTELOSS 1
|
||||
#define FIRELOSS 2
|
||||
#define TOXLOSS 4
|
||||
#define OXYLOSS 8
|
||||
#define SHAME 16
|
||||
//citadel code
|
||||
#define AROUSAL 32
|
||||
|
||||
#define STUN "stun"
|
||||
#define KNOCKDOWN "knockdown"
|
||||
#define UNCONSCIOUS "unconscious"
|
||||
#define IRRADIATE "irradiate"
|
||||
#define STUTTER "stutter"
|
||||
#define SLUR "slur"
|
||||
#define EYE_BLUR "eye_blur"
|
||||
#define DROWSY "drowsy"
|
||||
#define JITTER "jitter"
|
||||
|
||||
//Bitflags defining which status effects could be or are inflicted on a mob
|
||||
#define CANSTUN 1
|
||||
#define CANKNOCKDOWN 2
|
||||
#define CANUNCONSCIOUS 4
|
||||
#define CANPUSH 8
|
||||
#define IGNORESLOWDOWN 16
|
||||
#define GOTTAGOFAST 32
|
||||
#define GOTTAGOREALLYFAST 64
|
||||
#define GODMODE 4096
|
||||
#define FAKEDEATH 8192 //Replaces stuff like changeling.changeling_fakedeath
|
||||
#define DISFIGURED 16384 //I'll probably move this elsewhere if I ever get wround to writing a bitflag mob-damage system
|
||||
#define XENO_HOST 32768 //Tracks whether we're gonna be a baby alien's mummy.
|
||||
|
||||
//Health Defines
|
||||
#define HEALTH_THRESHOLD_CRIT 0
|
||||
#define HEALTH_THRESHOLD_DEAD -100
|
||||
|
||||
//Actual combat defines
|
||||
|
||||
//click cooldowns, in tenths of a second, used for various combat actions
|
||||
#define CLICK_CD_MELEE 8
|
||||
#define CLICK_CD_RANGE 4
|
||||
#define CLICK_CD_RAPID 2
|
||||
#define CLICK_CD_CLICK_ABILITY 6
|
||||
#define CLICK_CD_BREAKOUT 100
|
||||
#define CLICK_CD_HANDCUFFED 10
|
||||
#define CLICK_CD_RESIST 20
|
||||
#define CLICK_CD_GRABBING 10
|
||||
|
||||
//Cuff resist speeds
|
||||
#define FAST_CUFFBREAK 1
|
||||
#define INSTANT_CUFFBREAK 2
|
||||
|
||||
//Grab levels
|
||||
#define GRAB_PASSIVE 0
|
||||
#define GRAB_AGGRESSIVE 1
|
||||
#define GRAB_NECK 2
|
||||
#define GRAB_KILL 3
|
||||
|
||||
//Attack types for checking shields/hit reactions
|
||||
#define MELEE_ATTACK 1
|
||||
#define UNARMED_ATTACK 2
|
||||
#define PROJECTILE_ATTACK 3
|
||||
#define THROWN_PROJECTILE_ATTACK 4
|
||||
#define LEAP_ATTACK 5
|
||||
|
||||
//attack visual effects
|
||||
#define ATTACK_EFFECT_PUNCH "punch"
|
||||
#define ATTACK_EFFECT_KICK "kick"
|
||||
#define ATTACK_EFFECT_SMASH "smash"
|
||||
#define ATTACK_EFFECT_CLAW "claw"
|
||||
#define ATTACK_EFFECT_DISARM "disarm"
|
||||
#define ATTACK_EFFECT_BITE "bite"
|
||||
#define ATTACK_EFFECT_MECHFIRE "mech_fire"
|
||||
#define ATTACK_EFFECT_MECHTOXIN "mech_toxin"
|
||||
#define ATTACK_EFFECT_BOOP "boop" //Honk
|
||||
|
||||
//intent defines
|
||||
#define INTENT_HELP "help"
|
||||
#define INTENT_GRAB "grab"
|
||||
#define INTENT_DISARM "disarm"
|
||||
#define INTENT_HARM "harm"
|
||||
//NOTE: INTENT_HOTKEY_* defines are not actual intents!
|
||||
//they are here to support hotkeys
|
||||
#define INTENT_HOTKEY_LEFT "left"
|
||||
#define INTENT_HOTKEY_RIGHT "right"
|
||||
|
||||
//the define for visible message range in combat
|
||||
#define COMBAT_MESSAGE_RANGE 3
|
||||
|
||||
//Combat object defines
|
||||
|
||||
//Embedded objects
|
||||
#define EMBEDDED_PAIN_CHANCE 15 //Chance for embedded objects to cause pain (damage user)
|
||||
#define EMBEDDED_ITEM_FALLOUT 5 //Chance for embedded object to fall out (causing pain but removing the object)
|
||||
#define EMBED_CHANCE 45 //Chance for an object to embed into somebody when thrown (if it's sharp)
|
||||
#define EMBEDDED_PAIN_MULTIPLIER 2 //Coefficient of multiplication for the damage the item does while embedded (this*item.w_class)
|
||||
#define EMBEDDED_FALL_PAIN_MULTIPLIER 5 //Coefficient of multiplication for the damage the item does when it falls out (this*item.w_class)
|
||||
#define EMBEDDED_IMPACT_PAIN_MULTIPLIER 4 //Coefficient of multiplication for the damage the item does when it first embeds (this*item.w_class)
|
||||
#define EMBED_THROWSPEED_THRESHOLD 4 //The minimum value of an item's throw_speed for it to embed (Unless it has embedded_ignore_throwspeed_threshold set to 1)
|
||||
#define EMBEDDED_UNSAFE_REMOVAL_PAIN_MULTIPLIER 8 //Coefficient of multiplication for the damage the item does when removed without a surgery (this*item.w_class)
|
||||
#define EMBEDDED_UNSAFE_REMOVAL_TIME 30 //A Time in ticks, total removal time = (this*item.w_class)
|
||||
|
||||
//Gun Stuff
|
||||
#define SAWN_INTACT 0
|
||||
#define SAWN_OFF 1
|
||||
//Gun weapon weight
|
||||
#define WEAPON_DUAL_WIELD 0
|
||||
#define WEAPON_LIGHT 1
|
||||
#define WEAPON_MEDIUM 2
|
||||
#define WEAPON_HEAVY 3
|
||||
//Gun trigger guards
|
||||
#define TRIGGER_GUARD_ALLOW_ALL -1
|
||||
#define TRIGGER_GUARD_NONE 0
|
||||
#define TRIGGER_GUARD_NORMAL 1
|
||||
|
||||
//Object/Item sharpness
|
||||
#define IS_BLUNT 0
|
||||
#define IS_SHARP 1
|
||||
#define IS_SHARP_ACCURATE 2
|
||||
|
||||
//His Grace.
|
||||
#define HIS_GRACE_SATIATED 0 //He hungers not. If bloodthirst is set to this, His Grace is asleep.
|
||||
#define HIS_GRACE_PECKISH 20 //Slightly hungry.
|
||||
#define HIS_GRACE_HUNGRY 60 //Getting closer. Increases damage up to a minimum of 20.
|
||||
#define HIS_GRACE_FAMISHED 100 //Dangerous. Increases damage up to a minimum of 25 and cannot be dropped.
|
||||
#define HIS_GRACE_STARVING 120 //Incredibly close to breaking loose. Increases damage up to a minimum of 30.
|
||||
#define HIS_GRACE_CONSUME_OWNER 140 //His Grace consumes His owner at this point and becomes aggressive.
|
||||
#define HIS_GRACE_FALL_ASLEEP 160 //If it reaches this point, He falls asleep and resets.
|
||||
|
||||
#define HIS_GRACE_FORCE_BONUS 4 //How much force is gained per kill.
|
||||
/*ALL DEFINES RELATED TO COMBAT GO HERE*/
|
||||
|
||||
//Damage and status effect defines
|
||||
|
||||
//Damage defines //TODO: merge these down to reduce on defines
|
||||
#define BRUTE "brute"
|
||||
#define BURN "fire"
|
||||
#define TOX "tox"
|
||||
#define OXY "oxy"
|
||||
#define CLONE "clone"
|
||||
#define STAMINA "stamina"
|
||||
#define BRAIN "brain"
|
||||
|
||||
//Citadel code
|
||||
#define AROUSAL "arousal"
|
||||
|
||||
//bitflag damage defines used for suicide_act
|
||||
#define BRUTELOSS 1
|
||||
#define FIRELOSS 2
|
||||
#define TOXLOSS 4
|
||||
#define OXYLOSS 8
|
||||
#define SHAME 16
|
||||
|
||||
//Citadel code
|
||||
#define AROUSAL 32
|
||||
|
||||
#define STUN "stun"
|
||||
#define KNOCKDOWN "knockdown"
|
||||
#define UNCONSCIOUS "unconscious"
|
||||
#define IRRADIATE "irradiate"
|
||||
#define STUTTER "stutter"
|
||||
#define SLUR "slur"
|
||||
#define EYE_BLUR "eye_blur"
|
||||
#define DROWSY "drowsy"
|
||||
#define JITTER "jitter"
|
||||
|
||||
//Bitflags defining which status effects could be or are inflicted on a mob
|
||||
#define CANSTUN 1
|
||||
#define CANKNOCKDOWN 2
|
||||
#define CANUNCONSCIOUS 4
|
||||
#define CANPUSH 8
|
||||
#define IGNORESLOWDOWN 16
|
||||
#define GOTTAGOFAST 32
|
||||
#define GOTTAGOREALLYFAST 64
|
||||
#define GODMODE 4096
|
||||
#define FAKEDEATH 8192 //Replaces stuff like changeling.changeling_fakedeath
|
||||
#define DISFIGURED 16384 //I'll probably move this elsewhere if I ever get wround to writing a bitflag mob-damage system
|
||||
#define XENO_HOST 32768 //Tracks whether we're gonna be a baby alien's mummy.
|
||||
|
||||
//Health Defines
|
||||
#define HEALTH_THRESHOLD_CRIT 0
|
||||
#define HEALTH_THRESHOLD_DEAD -100
|
||||
|
||||
//Actual combat defines
|
||||
|
||||
//click cooldowns, in tenths of a second, used for various combat actions
|
||||
#define CLICK_CD_MELEE 8
|
||||
#define CLICK_CD_RANGE 4
|
||||
#define CLICK_CD_RAPID 2
|
||||
#define CLICK_CD_CLICK_ABILITY 6
|
||||
#define CLICK_CD_BREAKOUT 100
|
||||
#define CLICK_CD_HANDCUFFED 10
|
||||
#define CLICK_CD_RESIST 20
|
||||
#define CLICK_CD_GRABBING 10
|
||||
|
||||
//Cuff resist speeds
|
||||
#define FAST_CUFFBREAK 1
|
||||
#define INSTANT_CUFFBREAK 2
|
||||
|
||||
//Grab levels
|
||||
#define GRAB_PASSIVE 0
|
||||
#define GRAB_AGGRESSIVE 1
|
||||
#define GRAB_NECK 2
|
||||
#define GRAB_KILL 3
|
||||
|
||||
//Attack types for checking shields/hit reactions
|
||||
#define MELEE_ATTACK 1
|
||||
#define UNARMED_ATTACK 2
|
||||
#define PROJECTILE_ATTACK 3
|
||||
#define THROWN_PROJECTILE_ATTACK 4
|
||||
#define LEAP_ATTACK 5
|
||||
|
||||
//attack visual effects
|
||||
#define ATTACK_EFFECT_PUNCH "punch"
|
||||
#define ATTACK_EFFECT_KICK "kick"
|
||||
#define ATTACK_EFFECT_SMASH "smash"
|
||||
#define ATTACK_EFFECT_CLAW "claw"
|
||||
#define ATTACK_EFFECT_DISARM "disarm"
|
||||
#define ATTACK_EFFECT_BITE "bite"
|
||||
#define ATTACK_EFFECT_MECHFIRE "mech_fire"
|
||||
#define ATTACK_EFFECT_MECHTOXIN "mech_toxin"
|
||||
#define ATTACK_EFFECT_BOOP "boop" //Honk
|
||||
|
||||
//intent defines
|
||||
#define INTENT_HELP "help"
|
||||
#define INTENT_GRAB "grab"
|
||||
#define INTENT_DISARM "disarm"
|
||||
#define INTENT_HARM "harm"
|
||||
//NOTE: INTENT_HOTKEY_* defines are not actual intents!
|
||||
//they are here to support hotkeys
|
||||
#define INTENT_HOTKEY_LEFT "left"
|
||||
#define INTENT_HOTKEY_RIGHT "right"
|
||||
|
||||
//the define for visible message range in combat
|
||||
#define COMBAT_MESSAGE_RANGE 3
|
||||
|
||||
//Combat object defines
|
||||
|
||||
//Embedded objects
|
||||
#define EMBEDDED_PAIN_CHANCE 15 //Chance for embedded objects to cause pain (damage user)
|
||||
#define EMBEDDED_ITEM_FALLOUT 5 //Chance for embedded object to fall out (causing pain but removing the object)
|
||||
#define EMBED_CHANCE 45 //Chance for an object to embed into somebody when thrown (if it's sharp)
|
||||
#define EMBEDDED_PAIN_MULTIPLIER 2 //Coefficient of multiplication for the damage the item does while embedded (this*item.w_class)
|
||||
#define EMBEDDED_FALL_PAIN_MULTIPLIER 5 //Coefficient of multiplication for the damage the item does when it falls out (this*item.w_class)
|
||||
#define EMBEDDED_IMPACT_PAIN_MULTIPLIER 4 //Coefficient of multiplication for the damage the item does when it first embeds (this*item.w_class)
|
||||
#define EMBED_THROWSPEED_THRESHOLD 4 //The minimum value of an item's throw_speed for it to embed (Unless it has embedded_ignore_throwspeed_threshold set to 1)
|
||||
#define EMBEDDED_UNSAFE_REMOVAL_PAIN_MULTIPLIER 8 //Coefficient of multiplication for the damage the item does when removed without a surgery (this*item.w_class)
|
||||
#define EMBEDDED_UNSAFE_REMOVAL_TIME 30 //A Time in ticks, total removal time = (this*item.w_class)
|
||||
|
||||
//Gun Stuff
|
||||
#define SAWN_INTACT 0
|
||||
#define SAWN_OFF 1
|
||||
//Gun weapon weight
|
||||
#define WEAPON_DUAL_WIELD 0
|
||||
#define WEAPON_LIGHT 1
|
||||
#define WEAPON_MEDIUM 2
|
||||
#define WEAPON_HEAVY 3
|
||||
//Gun trigger guards
|
||||
#define TRIGGER_GUARD_ALLOW_ALL -1
|
||||
#define TRIGGER_GUARD_NONE 0
|
||||
#define TRIGGER_GUARD_NORMAL 1
|
||||
|
||||
//Object/Item sharpness
|
||||
#define IS_BLUNT 0
|
||||
#define IS_SHARP 1
|
||||
#define IS_SHARP_ACCURATE 2
|
||||
|
||||
//His Grace.
|
||||
#define HIS_GRACE_SATIATED 0 //He hungers not. If bloodthirst is set to this, His Grace is asleep.
|
||||
#define HIS_GRACE_PECKISH 20 //Slightly hungry.
|
||||
#define HIS_GRACE_HUNGRY 60 //Getting closer. Increases damage up to a minimum of 20.
|
||||
#define HIS_GRACE_FAMISHED 100 //Dangerous. Increases damage up to a minimum of 25 and cannot be dropped.
|
||||
#define HIS_GRACE_STARVING 120 //Incredibly close to breaking loose. Increases damage up to a minimum of 30.
|
||||
#define HIS_GRACE_CONSUME_OWNER 140 //His Grace consumes His owner at this point and becomes aggressive.
|
||||
#define HIS_GRACE_FALL_ASLEEP 160 //If it reaches this point, He falls asleep and resets.
|
||||
|
||||
#define HIS_GRACE_FORCE_BONUS 4 //How much force is gained per kill.
|
||||
|
||||
#define EXPLODE_NONE 0 //Don't even ask me why we need this.
|
||||
#define EXPLODE_DEVASTATE 1
|
||||
|
||||
@@ -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: ()
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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"
|
||||
|
||||
@@ -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).
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -51,4 +51,11 @@
|
||||
//Engine related
|
||||
#define ENGINE_COEFF_MIN 0.5
|
||||
#define ENGINE_COEFF_MAX 2
|
||||
#define ENGINE_DEFAULT_MAXSPEED_ENGINES 5
|
||||
#define ENGINE_DEFAULT_MAXSPEED_ENGINES 5
|
||||
|
||||
//Docking error flags
|
||||
#define DOCKING_SUCCESS 0
|
||||
#define DOCKING_COMPLETE 1
|
||||
#define DOCKING_BLOCKED 2
|
||||
#define DOCKING_IMMOBILIZED 4
|
||||
#define DOCKING_AREA_EMPTY 8
|
||||
@@ -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
|
||||
|
||||
@@ -53,12 +53,12 @@
|
||||
#define INIT_ORDER_ATOMS 11
|
||||
#define INIT_ORDER_LANGUAGE 10
|
||||
#define INIT_ORDER_MACHINES 9
|
||||
#define INIT_ORDER_SHUTTLE 3
|
||||
#define INIT_ORDER_TIMER 1
|
||||
#define INIT_ORDER_DEFAULT 0
|
||||
#define INIT_ORDER_AIR -1
|
||||
#define INIT_ORDER_MINIMAP -2
|
||||
#define INIT_ORDER_ASSETS -3
|
||||
#define INIT_ORDER_SHUTTLE -2
|
||||
#define INIT_ORDER_MINIMAP -3
|
||||
#define INIT_ORDER_ASSETS -4
|
||||
#define INIT_ORDER_ICON_SMOOTHING -5
|
||||
#define INIT_ORDER_OVERLAY -6
|
||||
#define INIT_ORDER_XKEYSCORE -10
|
||||
|
||||
@@ -175,6 +175,9 @@ Actual Adjacent procs :
|
||||
for(var/obj/structure/window/W in src)
|
||||
if(!W.CanAStarPass(ID, adir))
|
||||
return 1
|
||||
for(var/obj/machinery/door/window/W in src)
|
||||
if(!W.CanAStarPass(ID, adir))
|
||||
return 1
|
||||
for(var/obj/O in T)
|
||||
if(!O.CanAStarPass(ID, rdir, caller))
|
||||
return 1
|
||||
|
||||
@@ -96,6 +96,13 @@
|
||||
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
|
||||
/proc/typecacheof(path, ignore_root_path, only_root_path = FALSE)
|
||||
if(ispath(path))
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -182,3 +182,41 @@ GLOBAL_LIST_INIT(sqrtTable, list(1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4,
|
||||
gaussian_next = R2 * working
|
||||
return (mean + stddev * R1)
|
||||
#undef ACCURACY
|
||||
|
||||
/proc/mouse_angle_from_client(client/client)
|
||||
var/list/mouse_control = params2list(client.mouseParams)
|
||||
if(mouse_control["screen-loc"])
|
||||
var/list/screen_loc_params = splittext(mouse_control["screen-loc"], ",")
|
||||
var/list/screen_loc_X = splittext(screen_loc_params[1],":")
|
||||
var/list/screen_loc_Y = splittext(screen_loc_params[2],":")
|
||||
var/x = (text2num(screen_loc_X[1]) * 32 + text2num(screen_loc_X[2]) - 32)
|
||||
var/y = (text2num(screen_loc_Y[1]) * 32 + text2num(screen_loc_Y[2]) - 32)
|
||||
var/screenview = (client.view * 2 + 1) * world.icon_size //Refer to http://www.byond.com/docs/ref/info.html#/client/var/view for mad maths
|
||||
var/ox = round(screenview/2) - client.pixel_x //"origin" x
|
||||
var/oy = round(screenview/2) - client.pixel_y //"origin" y
|
||||
var/angle = NORM_ROT(Atan2(y - oy, x - ox))
|
||||
return angle
|
||||
|
||||
/proc/get_turf_in_angle(angle, turf/starting, increments)
|
||||
var/pixel_x = 0
|
||||
var/pixel_y = 0
|
||||
for(var/i in 1 to increments)
|
||||
pixel_x += sin(angle)+16*sin(angle)*2
|
||||
pixel_y += cos(angle)+16*cos(angle)*2
|
||||
var/new_x = starting.x
|
||||
var/new_y = starting.y
|
||||
while(pixel_x > 16)
|
||||
pixel_x -= 32
|
||||
new_x++
|
||||
while(pixel_x < -16)
|
||||
pixel_x += 32
|
||||
new_x--
|
||||
while(pixel_y > 16)
|
||||
pixel_y -= 32
|
||||
new_y++
|
||||
while(pixel_y < -16)
|
||||
pixel_y += 32
|
||||
new_y--
|
||||
new_x = Clamp(new_x, 0, world.maxx)
|
||||
new_y = Clamp(new_y, 0, world.maxy)
|
||||
return locate(new_x, new_y, starting.z)
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
//When we get into galloping mode, we stay there until both runs win less often than MIN_GALLOP consecutive times.
|
||||
#define MIN_GALLOP 7
|
||||
|
||||
//This is a global instance to allow much of this code to be reused. The interfaces are kept seperately
|
||||
//This is a global instance to allow much of this code to be reused. The interfaces are kept separately
|
||||
GLOBAL_DATUM_INIT(sortInstance, /datum/sortInstance, new())
|
||||
/datum/sortInstance
|
||||
//The array being sorted.
|
||||
|
||||
@@ -48,7 +48,7 @@ Location where the teleport begins, target that will teleport, distance to go, d
|
||||
Random error in tile placement x, error in tile placement y, and block offset.
|
||||
Block offset tells the proc how to place the box. Behind teleport location, relative to starting location, forward, etc.
|
||||
Negative values for offset are accepted, think of it in relation to North, -x is west, -y is south. Error defaults to positive.
|
||||
Turf and target are seperate in case you want to teleport some distance from a turf the target is not standing on or something.
|
||||
Turf and target are separate in case you want to teleport some distance from a turf the target is not standing on or something.
|
||||
*/
|
||||
|
||||
var/dirx = 0//Generic location finding variable.
|
||||
@@ -491,17 +491,26 @@ Turf and target are seperate in case you want to teleport some distance from a t
|
||||
var/y=arcsin(x/sqrt(1+x*x))
|
||||
return y
|
||||
|
||||
/atom/proc/GetAllContents()
|
||||
/atom/proc/GetAllContents(list/ignore_typecache)
|
||||
var/list/processing_list = list(src)
|
||||
var/list/assembled = list()
|
||||
if(ignore_typecache) //If there's a typecache, use it.
|
||||
while(processing_list.len)
|
||||
var/atom/A = processing_list[1]
|
||||
processing_list -= A
|
||||
if(ignore_typecache[A.type])
|
||||
continue
|
||||
processing_list |= (A.contents - assembled)
|
||||
assembled |= A
|
||||
|
||||
while(processing_list.len)
|
||||
var/atom/A = processing_list[1]
|
||||
processing_list -= A
|
||||
else //If there's none, only make this check once for performance.
|
||||
while(processing_list.len)
|
||||
var/atom/A = processing_list[1]
|
||||
processing_list -= A
|
||||
|
||||
processing_list |= (A.contents - assembled)
|
||||
processing_list |= (A.contents - assembled)
|
||||
|
||||
assembled |= A
|
||||
assembled |= A
|
||||
|
||||
return assembled
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
GLOBAL_LIST_EMPTY(clients) //all clients
|
||||
GLOBAL_LIST_EMPTY(admins) //all clients whom are admins
|
||||
GLOBAL_PROTECT(admins)
|
||||
GLOBAL_LIST_EMPTY(deadmins) //all clients who have used the de-admin verb.
|
||||
GLOBAL_PROTECT(deadmins)
|
||||
GLOBAL_LIST_EMPTY(deadmins) //all ckeys who have used the de-admin verb.
|
||||
|
||||
GLOBAL_LIST_EMPTY(directory) //all ckeys with associated client
|
||||
GLOBAL_LIST_EMPTY(stealthminID) //reference list with IDs that store ckeys, for stealthmins
|
||||
|
||||
@@ -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.
|
||||
@@ -20,7 +20,7 @@ GLOBAL_LIST_EMPTY(tech_list) //list of all /datum/tech datums indexed by id.
|
||||
GLOBAL_LIST_EMPTY(surgeries_list) //list of all surgeries by name, associated with their path.
|
||||
GLOBAL_LIST_EMPTY(crafting_recipes) //list of all table craft recipes
|
||||
GLOBAL_LIST_EMPTY(rcd_list) //list of Rapid Construction Devices.
|
||||
GLOBAL_LIST_EMPTY(apcs_list) //list of all Area Power Controller machines, seperate from machines for powernet speeeeeeed.
|
||||
GLOBAL_LIST_EMPTY(apcs_list) //list of all Area Power Controller machines, separate from machines for powernet speeeeeeed.
|
||||
GLOBAL_LIST_EMPTY(tracked_implants) //list of all current implants that are tracked to work out what sort of trek everyone is on. Sadly not on lavaworld not implemented...
|
||||
GLOBAL_LIST_EMPTY(tracked_chem_implants) //list of implants the prisoner console can track and send inject commands too
|
||||
GLOBAL_LIST_EMPTY(poi_list) //list of points of interest for observe/follow
|
||||
|
||||
+20
-14
@@ -24,17 +24,6 @@
|
||||
active_mousedown_item.onMouseUp(object, location, params, mob)
|
||||
active_mousedown_item = null
|
||||
|
||||
/client/MouseDrag(src_object,atom/over_object,src_location,over_location,src_control,over_control,params)
|
||||
mouseParams = params
|
||||
mouseLocation = over_location
|
||||
mouseObject = over_object
|
||||
mouseControlObject = over_control
|
||||
if(selected_target[1] && over_object && over_object.IsAutoclickable())
|
||||
selected_target[1] = over_object
|
||||
selected_target[2] = params
|
||||
if(active_mousedown_item)
|
||||
active_mousedown_item.onMouseDrag(src_object, over_object, src_location, over_location, params, mob)
|
||||
|
||||
/mob/proc/CanMobAutoclick(object, location, params)
|
||||
|
||||
/mob/living/carbon/CanMobAutoclick(atom/object, location, params)
|
||||
@@ -63,9 +52,6 @@
|
||||
/obj/item/proc/onMouseUp(object, location, params, mob)
|
||||
return
|
||||
|
||||
/obj/item/proc/onMouseDrag(src_object, over_object, src_location, over_location, params, mob)
|
||||
return
|
||||
|
||||
/obj/item
|
||||
var/canMouseDown = FALSE
|
||||
|
||||
@@ -90,3 +76,23 @@
|
||||
mouseLocation = location
|
||||
mouseObject = object
|
||||
mouseControlObject = control
|
||||
if(mob && LAZYLEN(mob.mousemove_intercept_objects))
|
||||
for(var/obj/item/I in mob.mousemove_intercept_objects)
|
||||
I.onMouseMove(object, location, control, params)
|
||||
|
||||
/obj/item/proc/onMouseMove(object, location, control, params)
|
||||
return
|
||||
|
||||
/client/MouseDrag(src_object,atom/over_object,src_location,over_location,src_control,over_control,params)
|
||||
mouseParams = params
|
||||
mouseLocation = over_location
|
||||
mouseObject = over_object
|
||||
mouseControlObject = over_control
|
||||
if(selected_target[1] && over_object && over_object.IsAutoclickable())
|
||||
selected_target[1] = over_object
|
||||
selected_target[2] = params
|
||||
if(active_mousedown_item)
|
||||
active_mousedown_item.onMouseDrag(src_object, over_object, src_location, over_location, params, mob)
|
||||
|
||||
/obj/item/proc/onMouseDrag(src_object, over_object, src_location, over_location, params, mob)
|
||||
return
|
||||
|
||||
+17
-6
@@ -95,7 +95,7 @@
|
||||
if(!modifiers["catcher"] && A.IsObscured())
|
||||
return
|
||||
|
||||
if(istype(loc,/obj/mecha))
|
||||
if(istype(loc, /obj/mecha))
|
||||
var/obj/mecha/M = loc
|
||||
return M.click_action(A,src,params)
|
||||
|
||||
@@ -432,14 +432,26 @@
|
||||
|
||||
/obj/screen/click_catcher
|
||||
icon = 'icons/mob/screen_gen.dmi'
|
||||
icon_state = "click_catcher"
|
||||
icon_state = "flash"
|
||||
plane = CLICKCATCHER_PLANE
|
||||
mouse_opacity = 2
|
||||
screen_loc = "CENTER"
|
||||
|
||||
/obj/screen/click_catcher/New()
|
||||
..()
|
||||
transform = matrix(200, 0, 0, 0, 200, 0)
|
||||
/obj/screen/click_catcher/proc/UpdateGreed(view_size_x = 7, view_size_y = 7)
|
||||
var/icon/newicon = icon('icons/mob/screen_gen.dmi', "flash")
|
||||
if(view_size_x > 16 || view_size_y > 16)
|
||||
newicon.Scale((16 * 2 + 1) * world.icon_size,(16 * 2 + 1) * world.icon_size)
|
||||
icon = newicon
|
||||
var/tx = view_size_x/16
|
||||
var/ty = view_size_y/16
|
||||
var/matrix/M = new
|
||||
M.Scale(tx, ty)
|
||||
transform = M
|
||||
screen_loc = "CENTER-16,CENTER-16"
|
||||
else
|
||||
screen_loc = "CENTER-[view_size_x],CENTER-[view_size_y]"
|
||||
newicon.Scale((view_size_x * 2 + 1) * world.icon_size,(view_size_y * 2 + 1) * world.icon_size)
|
||||
icon = newicon
|
||||
|
||||
/obj/screen/click_catcher/Click(location, control, params)
|
||||
var/list/modifiers = params2list(params)
|
||||
@@ -453,7 +465,6 @@
|
||||
T.Click(location, control, params)
|
||||
. = 1
|
||||
|
||||
|
||||
/* MouseWheelOn */
|
||||
|
||||
/mob/proc/MouseWheelOn(atom/A, delta_x, delta_y, params)
|
||||
|
||||
+36
-16
@@ -56,8 +56,7 @@
|
||||
|
||||
var/obj/item/W = get_active_held_item()
|
||||
|
||||
// Cyborgs have no range-checking unless there is item use
|
||||
if(!W)
|
||||
if(!W && get_dist(src,A) <= remote_range)
|
||||
A.attack_robot(src)
|
||||
return
|
||||
|
||||
@@ -106,38 +105,59 @@
|
||||
/atom/proc/BorgCtrlShiftClick(mob/living/silicon/robot/user) //forward to human click if not overriden
|
||||
CtrlShiftClick(user)
|
||||
|
||||
/obj/machinery/door/airlock/BorgCtrlShiftClick() // Sets/Unsets Emergency Access Override Forwards to AI code.
|
||||
AICtrlShiftClick()
|
||||
/obj/machinery/door/airlock/BorgCtrlShiftClick(mob/living/silicon/robot/user) // Sets/Unsets Emergency Access Override Forwards to AI code.
|
||||
if(get_dist(src,user) <= user.remote_range)
|
||||
AICtrlShiftClick()
|
||||
else
|
||||
..()
|
||||
|
||||
|
||||
/atom/proc/BorgShiftClick(mob/living/silicon/robot/user) //forward to human click if not overriden
|
||||
ShiftClick(user)
|
||||
|
||||
/obj/machinery/door/airlock/BorgShiftClick() // Opens and closes doors! Forwards to AI code.
|
||||
AIShiftClick()
|
||||
/obj/machinery/door/airlock/BorgShiftClick(mob/living/silicon/robot/user) // Opens and closes doors! Forwards to AI code.
|
||||
if(get_dist(src,user) <= user.remote_range)
|
||||
AIShiftClick()
|
||||
else
|
||||
..()
|
||||
|
||||
|
||||
/atom/proc/BorgCtrlClick(mob/living/silicon/robot/user) //forward to human click if not overriden
|
||||
CtrlClick(user)
|
||||
|
||||
/obj/machinery/door/airlock/BorgCtrlClick() // Bolts doors. Forwards to AI code.
|
||||
AICtrlClick()
|
||||
/obj/machinery/door/airlock/BorgCtrlClick(mob/living/silicon/robot/user) // Bolts doors. Forwards to AI code.
|
||||
if(get_dist(src,user) <= user.remote_range)
|
||||
AICtrlClick()
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/machinery/power/apc/BorgCtrlClick() // turns off/on APCs. Forwards to AI code.
|
||||
AICtrlClick()
|
||||
/obj/machinery/power/apc/BorgCtrlClick(mob/living/silicon/robot/user) // turns off/on APCs. Forwards to AI code.
|
||||
if(get_dist(src,user) <= user.remote_range)
|
||||
AICtrlClick()
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/machinery/turretid/BorgCtrlClick() //turret control on/off. Forwards to AI code.
|
||||
AICtrlClick()
|
||||
/obj/machinery/turretid/BorgCtrlClick(mob/living/silicon/robot/user) //turret control on/off. Forwards to AI code.
|
||||
if(get_dist(src,user) <= user.remote_range)
|
||||
AICtrlClick()
|
||||
else
|
||||
..()
|
||||
|
||||
/atom/proc/BorgAltClick(mob/living/silicon/robot/user)
|
||||
AltClick(user)
|
||||
return
|
||||
|
||||
/obj/machinery/door/airlock/BorgAltClick() // Eletrifies doors. Forwards to AI code.
|
||||
AIAltClick()
|
||||
/obj/machinery/door/airlock/BorgAltClick(mob/living/silicon/robot/user) // Eletrifies doors. Forwards to AI code.
|
||||
if(get_dist(src,user) <= user.remote_range)
|
||||
AIAltClick()
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/machinery/turretid/BorgAltClick() //turret lethal on/off. Forwards to AI code.
|
||||
AIAltClick()
|
||||
/obj/machinery/turretid/BorgAltClick(mob/living/silicon/robot/user) //turret lethal on/off. Forwards to AI code.
|
||||
if(get_dist(src,user) <= user.remote_range)
|
||||
AIAltClick()
|
||||
else
|
||||
..()
|
||||
|
||||
/*
|
||||
As with AI, these are not used in click code,
|
||||
|
||||
@@ -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>")
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -143,6 +145,7 @@
|
||||
return 0
|
||||
|
||||
screenmob.client.screen = list()
|
||||
screenmob.client.apply_clickcatcher()
|
||||
|
||||
var/display_hud_version = version
|
||||
if(!display_hud_version) //If 0 or blank, display the next hud version
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
icon_state = "act_equip"
|
||||
|
||||
/obj/screen/human/equip/Click()
|
||||
if(istype(usr.loc,/obj/mecha)) // stops inventory actions in a mech
|
||||
if(istype(usr.loc, /obj/mecha)) // stops inventory actions in a mech
|
||||
return 1
|
||||
var/mob/living/carbon/human/H = usr
|
||||
H.quick_equip()
|
||||
@@ -282,6 +282,7 @@
|
||||
|
||||
//citadel code
|
||||
arousal = new /obj/screen/arousal()
|
||||
arousal.icon_state = (owner.canbearoused == 1 ? "arousal0" : "")
|
||||
infodisplay += arousal
|
||||
|
||||
healthdoll = new /obj/screen/healthdoll()
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -110,7 +110,7 @@
|
||||
|
||||
if(usr.incapacitated())
|
||||
return 1
|
||||
if(istype(usr.loc,/obj/mecha)) // stops inventory actions in a mech
|
||||
if(istype(usr.loc, /obj/mecha)) // stops inventory actions in a mech
|
||||
return 1
|
||||
|
||||
if(hud && hud.mymob && slot_id)
|
||||
@@ -167,7 +167,7 @@
|
||||
return 1
|
||||
if(usr.incapacitated() || isobserver(usr))
|
||||
return 1
|
||||
if (istype(usr.loc,/obj/mecha)) // stops inventory actions in a mech
|
||||
if (istype(usr.loc, /obj/mecha)) // stops inventory actions in a mech
|
||||
return 1
|
||||
|
||||
if(hud.mymob.active_hand_index == held_index)
|
||||
@@ -281,7 +281,7 @@
|
||||
to_chat(H, "<span class='notice'>You are now running on internals from the [H.r_store] in your right pocket.</span>")
|
||||
H.internal = H.r_store
|
||||
|
||||
//Seperate so CO2 jetpacks are a little less cumbersome.
|
||||
//Separate so CO2 jetpacks are a little less cumbersome.
|
||||
if(!C.internal && istype(C.back, /obj/item/weapon/tank))
|
||||
to_chat(C, "<span class='notice'>You are now running on internals from the [C.back] on your back.</span>")
|
||||
C.internal = C.back
|
||||
@@ -350,7 +350,7 @@
|
||||
return 1
|
||||
if(usr.stat || usr.IsUnconscious() || usr.IsKnockdown() || usr.IsStun())
|
||||
return 1
|
||||
if (istype(usr.loc,/obj/mecha)) // stops inventory actions in a mech
|
||||
if (istype(usr.loc, /obj/mecha)) // stops inventory actions in a mech
|
||||
return 1
|
||||
if(master)
|
||||
var/obj/item/I = usr.get_active_held_item()
|
||||
|
||||
@@ -100,7 +100,8 @@
|
||||
"<span class='userdanger'>[name] bites [ML]!</span>")
|
||||
if(armor >= 2)
|
||||
return
|
||||
for(var/datum/disease/D in viruses)
|
||||
for(var/thing in viruses)
|
||||
var/datum/disease/D = thing
|
||||
ML.ForceContractDisease(D)
|
||||
else
|
||||
ML.visible_message("<span class='danger'>[src] has attempted to bite [ML]!</span>")
|
||||
|
||||
@@ -99,7 +99,7 @@
|
||||
if(dna.species.update_arousal_hud())
|
||||
return 0
|
||||
if(!canbearoused)
|
||||
hud_used.arousal.icon_state = "arousal0"
|
||||
hud_used.arousal.icon_state = ""
|
||||
return 0
|
||||
else
|
||||
if(hud_used.arousal)
|
||||
|
||||
@@ -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)
|
||||
@@ -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
|
||||
|
||||
@@ -87,9 +87,8 @@
|
||||
|
||||
var/check_randomizer = 0
|
||||
|
||||
var/allow_panic_bunker_bounce = 0 //Send new players somewhere else
|
||||
var/panic_server_name = "somewhere else"
|
||||
var/panic_address = "byond://" //Reconnect a player this linked server if this server isn't accepting new players
|
||||
var/panic_server_name
|
||||
var/panic_address //Reconnect a player this linked server if this server isn't accepting new players
|
||||
|
||||
//IP Intel vars
|
||||
var/ipintel_email
|
||||
@@ -456,11 +455,12 @@
|
||||
if("cross_comms_name")
|
||||
cross_name = value
|
||||
if("panic_server_name")
|
||||
panic_server_name = value
|
||||
if (value != "\[Put the name here\]")
|
||||
panic_server_name = value
|
||||
if("panic_server_address")
|
||||
panic_address = value
|
||||
if(value != "byond:\\address:port")
|
||||
allow_panic_bunker_bounce = 1
|
||||
if(value != "byond://address:port")
|
||||
panic_address = value
|
||||
|
||||
if("medal_hub_address")
|
||||
global.medal_hub = value
|
||||
if("medal_hub_password")
|
||||
|
||||
@@ -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!")
|
||||
|
||||
@@ -124,7 +124,8 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
|
||||
var/FireHim = FALSE
|
||||
if(istype(BadBoy))
|
||||
msg = null
|
||||
switch(++BadBoy.failure_strikes)
|
||||
LAZYINITLIST(BadBoy.failure_strikes)
|
||||
switch(++BadBoy.failure_strikes[BadBoy.type])
|
||||
if(2)
|
||||
msg = "The [BadBoy.name] subsystem was the last to fire for 2 controller restarts. It will be recovered now and disabled if it happens again."
|
||||
FireHim = TRUE
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
|
||||
var/runlevels = RUNLEVELS_DEFAULT //points of the game at which the SS can fire
|
||||
|
||||
var/static/failure_strikes = 0 //How many times we suspect this subsystem has crashed the MC, 3 strikes and you're out!
|
||||
var/static/list/failure_strikes //How many times we suspect a subsystem type has crashed the MC, 3 strikes and you're out!
|
||||
|
||||
//Do not override
|
||||
/datum/controller/subsystem/New()
|
||||
|
||||
@@ -259,7 +259,6 @@ SUBSYSTEM_DEF(blackbox)
|
||||
|
||||
/datum/feedback_variable/proc/add_details(text)
|
||||
if (istext(text))
|
||||
text = replacetext(text, " ", "_")
|
||||
if (!details)
|
||||
details = text
|
||||
else
|
||||
|
||||
@@ -1,11 +1,8 @@
|
||||
SUBSYSTEM_DEF(disease)
|
||||
name = "Disease"
|
||||
flags = SS_KEEP_TIMING|SS_NO_INIT
|
||||
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
|
||||
|
||||
var/list/currentrun = list()
|
||||
var/list/processing = list()
|
||||
flags = SS_NO_FIRE
|
||||
|
||||
var/list/active_diseases = list() //List of Active disease in all mobs; purely for quick referencing.
|
||||
var/list/diseases
|
||||
var/list/archive_diseases = list()
|
||||
|
||||
@@ -15,27 +12,5 @@ SUBSYSTEM_DEF(disease)
|
||||
if(!diseases)
|
||||
diseases = subtypesof(/datum/disease)
|
||||
|
||||
/datum/controller/subsystem/disease/Recover()
|
||||
currentrun = SSdisease.currentrun
|
||||
processing = SSdisease.processing
|
||||
diseases = SSdisease.diseases
|
||||
archive_diseases = SSdisease.archive_diseases
|
||||
|
||||
/datum/controller/subsystem/disease/stat_entry(msg)
|
||||
..("P:[processing.len]")
|
||||
|
||||
/datum/controller/subsystem/disease/fire(resumed = 0)
|
||||
if(!resumed)
|
||||
src.currentrun = processing.Copy()
|
||||
//cache for sanic speed (lists are references anyways)
|
||||
var/list/currentrun = src.currentrun
|
||||
|
||||
while(currentrun.len)
|
||||
var/datum/thing = currentrun[currentrun.len]
|
||||
currentrun.len--
|
||||
if(thing)
|
||||
thing.process()
|
||||
else
|
||||
processing.Remove(thing)
|
||||
if (MC_TICK_CHECK)
|
||||
return
|
||||
..("P:[active_diseases.len]")
|
||||
@@ -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
|
||||
|
||||
@@ -18,7 +18,7 @@ SUBSYSTEM_DEF(garbage)
|
||||
// refID's are associated with the time at which they time out and need to be manually del()
|
||||
// we do this so we aren't constantly locating them and preventing them from being gc'd
|
||||
|
||||
var/list/tobequeued = list() //We store the references of things to be added to the queue seperately so we can spread out GC overhead over a few ticks
|
||||
var/list/tobequeued = list() //We store the references of things to be added to the queue separately so we can spread out GC overhead over a few ticks
|
||||
|
||||
var/list/didntgc = list() // list of all types that have failed to GC associated with the number of times that's happened.
|
||||
// the types are stored as strings
|
||||
@@ -144,7 +144,7 @@ SUBSYSTEM_DEF(garbage)
|
||||
|
||||
queue[refid] = gctime
|
||||
|
||||
//this is purely to seperate things profile wise.
|
||||
//this is purely to separate things profile wise.
|
||||
/datum/controller/subsystem/garbage/proc/HardDelete(datum/A)
|
||||
var/time = world.timeofday
|
||||
var/tick = world.tick_usage
|
||||
@@ -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.
|
||||
@@ -233,25 +234,7 @@ SUBSYSTEM_DEF(garbage)
|
||||
else if(D.gc_destroyed == GC_CURRENTLY_BEING_QDELETED)
|
||||
CRASH("[D.type] destroy proc was called multiple times, likely due to a qdel loop in the Destroy logic")
|
||||
|
||||
// Default implementation of clean-up code.
|
||||
// This should be overridden to remove all references pointing to the object being destroyed.
|
||||
// Return the appropriate QDEL_HINT; in most cases this is QDEL_HINT_QUEUE.
|
||||
/datum/proc/Destroy(force=FALSE)
|
||||
tag = null
|
||||
var/list/timers = active_timers
|
||||
active_timers = null
|
||||
for(var/thing in timers)
|
||||
var/datum/timedevent/timer = thing
|
||||
if (timer.spent)
|
||||
continue
|
||||
qdel(timer)
|
||||
return QDEL_HINT_QUEUE
|
||||
|
||||
/datum/var/gc_destroyed //Time when this object was destroyed.
|
||||
|
||||
#ifdef TESTING
|
||||
/datum/var/running_find_references
|
||||
/datum/var/last_find_references = 0
|
||||
|
||||
/datum/verb/find_refs()
|
||||
set category = "Debug"
|
||||
@@ -300,13 +283,12 @@ SUBSYSTEM_DEF(garbage)
|
||||
|
||||
/client/verb/purge_all_destroyed_objects()
|
||||
set category = "Debug"
|
||||
if(SSgarbage)
|
||||
while(SSgarbage.queue.len)
|
||||
var/datum/o = locate(SSgarbage.queue[1])
|
||||
if(istype(o) && o.gc_destroyed)
|
||||
del(o)
|
||||
SSgarbage.totaldels++
|
||||
SSgarbage.queue.Cut(1, 2)
|
||||
while(SSgarbage.queue.len)
|
||||
var/datum/o = locate(SSgarbage.queue[1])
|
||||
if(istype(o) && o.gc_destroyed)
|
||||
del(o)
|
||||
SSgarbage.totaldels++
|
||||
SSgarbage.queue.Cut(1, 2)
|
||||
|
||||
/datum/verb/qdel_then_find_references()
|
||||
set category = "Debug"
|
||||
|
||||
@@ -217,10 +217,9 @@ SUBSYSTEM_DEF(job)
|
||||
Debug("Running DO")
|
||||
|
||||
//Holder for Triumvirate is stored in the SSticker, this just processes it
|
||||
if(SSticker)
|
||||
if(SSticker.triai)
|
||||
for(var/datum/job/ai/A in occupations)
|
||||
if(SSticker.triai)
|
||||
A.spawn_positions = 3
|
||||
A.spawn_positions = 3
|
||||
|
||||
//Get the players who are ready
|
||||
for(var/mob/dead/new_player/player in GLOB.player_list)
|
||||
|
||||
@@ -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 = ""
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -103,7 +103,7 @@ SUBSYSTEM_DEF(throwing)
|
||||
finalize()
|
||||
return
|
||||
|
||||
/datum/thrownthing/proc/finalize(hit = FALSE)
|
||||
/datum/thrownthing/proc/finalize(hit = FALSE, target=null)
|
||||
set waitfor = 0
|
||||
SSthrowing.processing -= thrownthing
|
||||
//done throwing, either because it hit something or it finished moving
|
||||
@@ -120,13 +120,15 @@ SUBSYSTEM_DEF(throwing)
|
||||
thrownthing.newtonian_move(init_dir)
|
||||
else
|
||||
thrownthing.newtonian_move(init_dir)
|
||||
|
||||
if(target)
|
||||
thrownthing.throw_impact(target, src)
|
||||
|
||||
if (callback)
|
||||
callback.Invoke()
|
||||
|
||||
/datum/thrownthing/proc/hit_atom(atom/A)
|
||||
thrownthing.throw_impact(A, src)
|
||||
thrownthing.newtonian_move(init_dir)
|
||||
finalize(TRUE)
|
||||
finalize(hit=TRUE, target=A)
|
||||
|
||||
/datum/thrownthing/proc/hitcheck()
|
||||
for (var/thing in get_turf(thrownthing))
|
||||
@@ -134,6 +136,5 @@ SUBSYSTEM_DEF(throwing)
|
||||
if (AM == thrownthing)
|
||||
continue
|
||||
if (AM.density && !(AM.pass_flags & LETPASSTHROW) && !(AM.flags & ON_BORDER))
|
||||
thrownthing.throwing = null
|
||||
thrownthing.throw_impact(AM, src)
|
||||
finalize(hit=TRUE, target=AM)
|
||||
return TRUE
|
||||
|
||||
@@ -476,15 +476,15 @@ SUBSYSTEM_DEF(ticker)
|
||||
if(Player.stat != DEAD && !isbrain(Player))
|
||||
num_survivors++
|
||||
if(station_evacuated) //If the shuttle has already left the station
|
||||
var/area/shuttle_area
|
||||
var/list/area/shuttle_areas
|
||||
if(SSshuttle && SSshuttle.emergency)
|
||||
shuttle_area = SSshuttle.emergency.areaInstance
|
||||
shuttle_areas = SSshuttle.emergency.shuttle_areas
|
||||
if(!Player.onCentcom() && !Player.onSyndieBase())
|
||||
to_chat(Player, "<font color='blue'><b>You managed to survive, but were marooned on [station_name()]...</b></FONT>")
|
||||
else
|
||||
num_escapees++
|
||||
to_chat(Player, "<font color='green'><b>You managed to survive the events on [station_name()] as [Player.real_name].</b></FONT>")
|
||||
if(get_area(Player) == shuttle_area)
|
||||
if(shuttle_areas[get_area(Player)])
|
||||
num_shuttle_escapees++
|
||||
else
|
||||
to_chat(Player, "<font color='green'><b>You managed to survive the events on [station_name()] as [Player.real_name].</b></FONT>")
|
||||
|
||||
@@ -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"
|
||||
@@ -209,7 +210,6 @@ SUBSYSTEM_DEF(timer)
|
||||
timer_id_dict |= SStimer.timer_id_dict
|
||||
bucket_list |= SStimer.bucket_list
|
||||
|
||||
/datum/var/list/active_timers
|
||||
/datum/timedevent
|
||||
var/id
|
||||
var/datum/callback/callBack
|
||||
@@ -225,18 +225,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 +302,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 +383,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 +394,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)
|
||||
|
||||
+21
-5
@@ -10,12 +10,13 @@
|
||||
var/check_flags = 0
|
||||
var/processing = FALSE
|
||||
var/obj/screen/movable/action_button/button = null
|
||||
var/button_icon = 'icons/mob/actions.dmi'
|
||||
var/background_icon_state = ACTION_BUTTON_DEFAULT_BACKGROUND
|
||||
var/buttontooltipstyle = ""
|
||||
|
||||
var/icon_icon = 'icons/mob/actions.dmi'
|
||||
var/button_icon_state = "default"
|
||||
var/button_icon = 'icons/mob/actions/backgrounds.dmi' //This is the file for the BACKGROUND icon
|
||||
var/background_icon_state = ACTION_BUTTON_DEFAULT_BACKGROUND //And this is the state for the background icon
|
||||
|
||||
var/icon_icon = 'icons/mob/actions.dmi' //This is the file for the ACTION icon
|
||||
var/button_icon_state = "default" //And this is the state for the action icon
|
||||
var/mob/owner
|
||||
|
||||
/datum/action/New(Target)
|
||||
@@ -45,6 +46,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 +59,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())
|
||||
@@ -166,6 +169,10 @@
|
||||
|
||||
/datum/action/item_action/toggle_firemode
|
||||
name = "Toggle Firemode"
|
||||
|
||||
/datum/action/item_action/rcl
|
||||
name = "Change Cable Color"
|
||||
button_icon_state = "rcl_rainbow"
|
||||
|
||||
/datum/action/item_action/startchainsaw
|
||||
name = "Pull The Starting Cord"
|
||||
@@ -219,6 +226,7 @@
|
||||
/datum/action/item_action/toggle_unfriendly_fire
|
||||
name = "Toggle Friendly Fire \[ON\]"
|
||||
desc = "Toggles if the club's blasts cause friendly fire."
|
||||
icon_icon = 'icons/mob/actions/actions_items.dmi'
|
||||
button_icon_state = "vortex_ff_on"
|
||||
|
||||
/datum/action/item_action/toggle_unfriendly_fire/Trigger()
|
||||
@@ -252,6 +260,7 @@
|
||||
/datum/action/item_action/vortex_recall
|
||||
name = "Vortex Recall"
|
||||
desc = "Recall yourself, and anyone nearby, to an attuned hierophant beacon at any time.<br>If the beacon is still attached, will detach it."
|
||||
icon_icon = 'icons/mob/actions/actions_items.dmi'
|
||||
button_icon_state = "vortex_recall"
|
||||
|
||||
/datum/action/item_action/vortex_recall/IsAvailable()
|
||||
@@ -262,6 +271,7 @@
|
||||
return ..()
|
||||
|
||||
/datum/action/item_action/clock
|
||||
icon_icon = 'icons/mob/actions/actions_clockcult.dmi'
|
||||
background_icon_state = "bg_clock"
|
||||
buttontooltipstyle = "clockcult"
|
||||
|
||||
@@ -361,6 +371,7 @@
|
||||
|
||||
/datum/action/item_action/toggle_research_scanner
|
||||
name = "Toggle Research Scanner"
|
||||
icon_icon = 'icons/mob/actions/actions_items.dmi'
|
||||
button_icon_state = "scan_mode"
|
||||
var/active = FALSE
|
||||
|
||||
@@ -397,6 +408,7 @@
|
||||
/datum/action/item_action/ninjajaunt
|
||||
name = "Phase Jaunt (10E)"
|
||||
desc = "Utilizes the internal VOID-shift device to rapidly transit in direction facing."
|
||||
icon_icon = 'icons/mob/actions/actions_items.dmi'
|
||||
button_icon_state = "ninja_phase"
|
||||
|
||||
/datum/action/item_action/ninjasmoke
|
||||
@@ -405,6 +417,7 @@
|
||||
button_icon_state = "smoke"
|
||||
|
||||
/datum/action/item_action/ninjaboost
|
||||
check_flags = AB_CHECK_RESTRAINED|AB_CHECK_CONSCIOUS
|
||||
name = "Adrenaline Boost"
|
||||
desc = "Inject a secret chemical that will counteract all movement-impairing effect."
|
||||
button_icon_state = "repulse"
|
||||
@@ -435,6 +448,7 @@
|
||||
/datum/action/item_action/ninja_stealth
|
||||
name = "Toggle Stealth"
|
||||
desc = "Toggles stealth mode on and off."
|
||||
icon_icon = 'icons/mob/actions/actions_items.dmi'
|
||||
button_icon_state = "ninja_cloak"
|
||||
|
||||
/datum/action/item_action/toggle_glove
|
||||
@@ -476,7 +490,7 @@
|
||||
var/obj/effect/proc_holder/spell/S = target
|
||||
S.action = src
|
||||
name = S.name
|
||||
button_icon = S.action_icon
|
||||
icon_icon = S.action_icon
|
||||
button_icon_state = S.action_icon_state
|
||||
background_icon_state = S.action_background_icon_state
|
||||
button.name = name
|
||||
@@ -551,12 +565,14 @@
|
||||
/datum/action/item_action/stickmen
|
||||
name = "Summon Stick Minions"
|
||||
desc = "Allows you to summon faithful stickmen allies to aide you in battle."
|
||||
icon_icon = 'icons/mob/actions/actions_minor_antag.dmi'
|
||||
button_icon_state = "art_summon"
|
||||
|
||||
//surf_ss13
|
||||
/datum/action/item_action/bhop
|
||||
name = "Activate Jump Boots"
|
||||
desc = "Activates the jump boot's internal propulsion system, allowing the user to dash over 4-wide gaps."
|
||||
icon_icon = 'icons/mob/actions/actions_items.dmi'
|
||||
button_icon_state = "jetboot"
|
||||
|
||||
/datum/action/language_menu
|
||||
|
||||
@@ -152,7 +152,7 @@
|
||||
if(!owner||!owner.objectives)
|
||||
return
|
||||
for (var/objective_ in owner.objectives)
|
||||
if(!(istype(objective_, /datum/objective/escape)||istype(objective_,/datum/objective/survive)))
|
||||
if(!(istype(objective_, /datum/objective/escape)||istype(objective_, /datum/objective/survive)))
|
||||
continue
|
||||
remove_objective(objective_)
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
/datum/antagonist/traitor/human
|
||||
should_specialise = FALSE
|
||||
var/should_equip = TRUE
|
||||
|
||||
/datum/antagonist/traitor/human/custom
|
||||
silent = TRUE
|
||||
should_give_codewords = FALSE
|
||||
@@ -31,6 +32,7 @@
|
||||
|
||||
/datum/antagonist/traitor/AI
|
||||
should_specialise = FALSE
|
||||
|
||||
/datum/antagonist/traitor/AI/custom
|
||||
silent = TRUE
|
||||
should_give_codewords = FALSE
|
||||
@@ -38,9 +40,8 @@
|
||||
|
||||
|
||||
/datum/antagonist/traitor/on_body_transfer(mob/living/old_body, mob/living/new_body)
|
||||
if(issilicon(new_body) && issilicon(old_body))
|
||||
..()
|
||||
else
|
||||
// human <-> silicon only
|
||||
if(old_body && issilicon(new_body) ^ issilicon(old_body))
|
||||
silent = TRUE
|
||||
owner.add_antag_datum(base_datum_custom)
|
||||
for(var/datum/antagonist/traitor/new_datum in owner.antag_datums)
|
||||
@@ -49,13 +50,14 @@
|
||||
transfer_important_variables(new_datum)
|
||||
break
|
||||
on_removal()
|
||||
|
||||
|
||||
else
|
||||
..()
|
||||
|
||||
/datum/antagonist/traitor/human/custom //used to give custom objectives
|
||||
silent = TRUE
|
||||
give_objectives = FALSE
|
||||
should_give_codewords = FALSE
|
||||
|
||||
/datum/antagonist/traitor/AI/custom //used to give custom objectives
|
||||
silent = TRUE
|
||||
give_objectives = FALSE
|
||||
@@ -83,7 +85,8 @@
|
||||
if(owner.assigned_role == "Clown")
|
||||
var/mob/living/carbon/human/traitor_mob = owner.current
|
||||
if(traitor_mob&&istype(traitor_mob))
|
||||
if(!silent) to_chat(traitor_mob, "Your training has allowed you to overcome your clownish nature, allowing you to wield weapons without harming yourself.")
|
||||
if(!silent)
|
||||
to_chat(traitor_mob, "Your training has allowed you to overcome your clownish nature, allowing you to wield weapons without harming yourself.")
|
||||
traitor_mob.dna.remove_mutation(CLOWNMUT)
|
||||
|
||||
/datum/antagonist/traitor/remove_innate_effects()
|
||||
@@ -172,10 +175,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 +205,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
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
# Datum Component System (DCS)
|
||||
|
||||
## Concept
|
||||
|
||||
Loosely adapted from /vg/. This is an entity component system for adding behaviours to datums when inheritance doesn't quite cut it. By using signals and events instead of direct inheritance, you can inject behaviours without hacky overloads. It requires a different method of thinking, but is not hard to use correctly. If a behaviour can have application across more than one thing. Make it generic, make it a component. Atom/mob/obj event? Give it a signal, and forward it's arguments with a `SendSignal()` call. Now every component that want's to can also know about this happening.
|
||||
|
||||
### In the code
|
||||
|
||||
#### Slippery things
|
||||
|
||||
At the time of this writing, every object that is slippery overrides atom/Crossed does some checks, then slips the mob. Instead of all those Crossed overrides they could add a slippery component to all these objects. And have the checks in one proc that is run by the Crossed event
|
||||
|
||||
#### Powercells
|
||||
|
||||
A lot of objects have powercells. The `get_cell()` proc was added to give generic access to the cell var if it had one. This is just a specific use case of `GetComponent()`
|
||||
|
||||
#### Radios
|
||||
|
||||
The radio object as it is should not exist, given that more things use the _concept_ of radios rather than the object itself. The actual function of the radio can exist in a component which all the things that use it (Request consoles, actual radios, the SM shard) can add to themselves.
|
||||
|
||||
#### Standos
|
||||
|
||||
Stands have a lot of procs which mimic mob procs. Rather than inserting hooks for all these procs in overrides, the same can be accomplished with signals
|
||||
|
||||
## API
|
||||
|
||||
### Vars
|
||||
|
||||
1. `/datum/var/list/datum_components` (private)
|
||||
* Lazy list of all components a datum has (TODO: Make this a typecache with longer paths overwriting shorter ones maybe? It'd be weird)
|
||||
1. `/datum/component/var/enabled` (protected, boolean)
|
||||
* If the component is enabled. If not, it will not react to signals
|
||||
* TRUE by default
|
||||
1. `/datum/component/var/dupe_mode` (protected, enum)
|
||||
* How multiple components of the exact same type are handled when added to the datum.
|
||||
* `COMPONENT_DUPE_HIGHLANDER` (default): Old component will be deleted, new component will first have `/datum/component/proc/InheritComponent(datum/component/old, FALSE)` on it
|
||||
* `COMPONENT_DUPE_ALLOWED`: The components will be treated as seperate, `GetComponent()` will return the first added
|
||||
* `COMPONENT_DUPE_UNIQUE`: New component will be deleted, old component will first have `/datum/component/proc/InheritComponent(datum/component/new, TRUE)` on it
|
||||
1. `/datum/component/var/list/signal_procs` (private)
|
||||
* Associated lazy list of signals -> callbacks that will be run when the parent datum recieves that signal
|
||||
1. `/datum/component/var/datum/parent` (protected, read-only)
|
||||
* The datum this component belongs to
|
||||
|
||||
### Procs
|
||||
|
||||
1. `/datum/proc/GetComponent(component_type(type)) -> datum/component?` (public, final)
|
||||
* Returns a reference to a component of component_type if it exists in the datum, null otherwise
|
||||
1. `/datum/proc/GetComponents(component_type(type)) -> list` (public, final)
|
||||
* Returns a list of references to all components of component_type that exist in the datum
|
||||
1. `/datum/proc/GetExactComponent(component_type(type)) -> datum/component?` (public, final)
|
||||
* Returns a reference to a component whose type MATCHES component_type if that component exists in the datum, null otherwise
|
||||
1. `GET_COMPONENT(varname, component_type)` OR `GET_COMPONENT_FROM(varname, component_type, src)`
|
||||
* Shorthand for `var/component_type/varname = src.GetComponent(component_type)`
|
||||
1. `/datum/proc/AddComponent(component_type(type), ...) -> datum/component` (public, final)
|
||||
* Creates an instance of `component_type` in the datum and passes `...` to it's `New()` call
|
||||
* Sends the `COMSIG_COMPONENT_ADDED` signal to the datum
|
||||
* All components a datum owns are deleted with the datum
|
||||
* Returns the component that was created. Or the old component in a dupe situation where `COMPONENT_DUPE_UNIQUE` was set
|
||||
1. `/datum/proc/ComponentActivated(datum/component/C)` (abstract)
|
||||
* Called on a component's `parent` after a signal recieved causes it to activate. `src` is the parameter
|
||||
* Will only be called if a component's callback returns `TRUE`
|
||||
1. `/datum/proc/TakeComponent(datum/component/C)` (public, final)
|
||||
* Properly transfers ownership of a component from one datum to another
|
||||
* Singals `COMSIG_COMPONENT_REMOVING` on the parent
|
||||
* Called on the datum you want to own the component with another datum's component
|
||||
1. `/datum/proc/SendSignal(signal, ...)` (public, final)
|
||||
* Call to send a signal to the components of the target datum
|
||||
* Extra arguments are to be specified in the signal definition
|
||||
1. `/datum/component/New(datum/parent, ...)` (protected, virtual)
|
||||
* Forwarded the arguments from `AddComponent()`
|
||||
1. `/datum/component/Destroy()` (virtual)
|
||||
* Sends the `COMSIG_COMPONENT_REMOVING` signal to the parent datum if the `parent` isn't being qdeleted
|
||||
* Properly removes the component from `parent` and cleans up references
|
||||
1. `/datum/component/proc/InheritComponent(datum/component/C, i_am_original(boolean))` (abstract)
|
||||
* Called on a component when a component of the same type was added to the same parent
|
||||
* See `/datum/component/var/dupe_mode`
|
||||
* `C`'s type will always be the same of the called component
|
||||
1. `/datum/component/proc/OnTransfer(datum/new_parent)` (abstract)
|
||||
* Called before the new `parent` is assigned in `TakeComponent()`, after the remove signal, before the added signal
|
||||
* Allows the component to react to ownership transfers
|
||||
1. `/datum/component/proc/_RemoveNoSignal()` (private, final)
|
||||
* Internal, clears the parent var and removes the component from the parents component list
|
||||
1. `/datum/component/proc/RegisterSignal(signal(string), proc_ref(type), override(boolean))` (protected, final) (Consider removing for performance gainz)
|
||||
* Makes a component listen for the specified `signal` on it's `parent` datum.
|
||||
* When that signal is recieved `proc_ref` will be called on the component, along with associated arguments
|
||||
* Example proc ref: `.proc/OnEvent`
|
||||
* If a previous registration is overwritten by the call, a runtime occurs. Setting `override` to TRUE prevents this
|
||||
* These callbacks run asyncronously
|
||||
* Returning `TRUE` from these callbacks will trigger a `TRUE` return from the `SendSignal()` that initiated it
|
||||
1. `/datum/component/proc/ReceiveSignal(signal, ...)` (virtual)
|
||||
* Called when a component recieves any signal and is enabled
|
||||
* Default implementation looks if the signal is registered and runs the appropriate proc
|
||||
|
||||
### See signals and their arguments in __DEFINES\components.dm
|
||||
|
||||
## Examples
|
||||
Material Containers: #29268 (Too many GetComponent calls, but not bad)
|
||||
Slips: #00000 (PR DIS)
|
||||
Powercells: (TODO)
|
||||
@@ -0,0 +1,117 @@
|
||||
/datum/component
|
||||
var/enabled = TRUE
|
||||
var/dupe_mode = COMPONENT_DUPE_HIGHLANDER
|
||||
var/list/signal_procs
|
||||
var/datum/parent
|
||||
|
||||
/datum/component/New(datum/P, ...)
|
||||
var/dm = dupe_mode
|
||||
if(dm != COMPONENT_DUPE_ALLOWED)
|
||||
var/datum/component/old = P.GetExactComponent(type)
|
||||
if(old)
|
||||
switch(dm)
|
||||
if(COMPONENT_DUPE_HIGHLANDER)
|
||||
InheritComponent(old, FALSE)
|
||||
qdel(old)
|
||||
if(COMPONENT_DUPE_UNIQUE)
|
||||
old.InheritComponent(src, TRUE)
|
||||
qdel(src)
|
||||
return
|
||||
P.SendSignal(COMSIG_COMPONENT_ADDED, src)
|
||||
LAZYADD(P.datum_components, src)
|
||||
parent = P
|
||||
|
||||
/datum/component/Destroy()
|
||||
enabled = FALSE
|
||||
var/datum/P = parent
|
||||
if(P)
|
||||
_RemoveNoSignal()
|
||||
P.SendSignal(COMSIG_COMPONENT_REMOVING, src)
|
||||
LAZYCLEARLIST(signal_procs)
|
||||
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)
|
||||
if(QDELETED(src))
|
||||
return
|
||||
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/component/proc/ReceiveSignal(sigtype, ...)
|
||||
var/list/sps = signal_procs
|
||||
var/datum/callback/CB = LAZYACCESS(sps, sigtype)
|
||||
if(!CB)
|
||||
return FALSE
|
||||
var/list/arguments = args.Copy()
|
||||
arguments.Cut(1, 2)
|
||||
return CB.InvokeAsync(arglist(arguments))
|
||||
|
||||
/datum/component/proc/InheritComponent(datum/component/C, i_am_original)
|
||||
return
|
||||
|
||||
/datum/component/proc/OnTransfer(datum/new_parent)
|
||||
return
|
||||
|
||||
/datum/proc/SendSignal(sigtype, ...)
|
||||
var/list/comps = datum_components
|
||||
. = FALSE
|
||||
for(var/I in comps)
|
||||
var/datum/component/C = I
|
||||
if(!C.enabled)
|
||||
continue
|
||||
if(C.ReceiveSignal(arglist(args)))
|
||||
ComponentActivated(C)
|
||||
. = TRUE
|
||||
|
||||
/datum/proc/ComponentActivated(datum/component/C)
|
||||
return
|
||||
|
||||
/datum/proc/GetComponent(c_type)
|
||||
for(var/I in datum_components)
|
||||
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/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/TakeComponent(datum/component/C)
|
||||
if(!C)
|
||||
return
|
||||
var/datum/helicopter = C.parent
|
||||
if(helicopter == src)
|
||||
//wat
|
||||
return
|
||||
C._RemoveNoSignal()
|
||||
helicopter.SendSignal(COMSIG_COMPONENT_REMOVING, C)
|
||||
C.OnTransfer(src)
|
||||
C.parent = src
|
||||
SendSignal(COMSIG_COMPONENT_ADDED, C)
|
||||
@@ -0,0 +1,31 @@
|
||||
/datum
|
||||
var/gc_destroyed //Time when this object was destroyed.
|
||||
var/list/active_timers //for SStimer
|
||||
var/list/datum_components //for /datum/components
|
||||
var/ui_screen = "home" //for tgui
|
||||
|
||||
#ifdef TESTING
|
||||
var/running_find_references
|
||||
var/last_find_references = 0
|
||||
#endif
|
||||
|
||||
// Default implementation of clean-up code.
|
||||
// This should be overridden to remove all references pointing to the object being destroyed.
|
||||
// Return the appropriate QDEL_HINT; in most cases this is QDEL_HINT_QUEUE.
|
||||
/datum/proc/Destroy(force=FALSE)
|
||||
tag = null
|
||||
var/list/timers = active_timers
|
||||
active_timers = null
|
||||
for(var/thing in timers)
|
||||
var/datum/timedevent/timer = thing
|
||||
if (timer.spent)
|
||||
continue
|
||||
qdel(timer)
|
||||
var/list/dc = datum_components
|
||||
for(var/I in dc)
|
||||
var/datum/component/C = I
|
||||
C._RemoveNoSignal()
|
||||
qdel(C)
|
||||
if(dc)
|
||||
dc.Cut()
|
||||
return QDEL_HINT_QUEUE
|
||||
+28
-28
@@ -21,7 +21,7 @@
|
||||
return debug_variable(var_name, vars[var_name], 0, src)
|
||||
|
||||
//please call . = ..() first and append to the result, that way parent items are always at the top and child items are further down
|
||||
//add seperaters by doing . += "---"
|
||||
//add separaters by doing . += "---"
|
||||
/datum/proc/vv_get_dropdown()
|
||||
. = list()
|
||||
. += "---"
|
||||
@@ -62,7 +62,7 @@
|
||||
|
||||
|
||||
|
||||
if(istype(D,/atom))
|
||||
if(istype(D, /atom))
|
||||
var/atom/AT = D
|
||||
if(AT.icon && AT.icon_state)
|
||||
sprite = new /icon(AT.icon, AT.icon_state)
|
||||
@@ -77,7 +77,7 @@
|
||||
sprite_text = "<img src='vv[hash].png'></td><td>"
|
||||
var/list/atomsnowflake = list()
|
||||
|
||||
if(istype(D,/atom))
|
||||
if(istype(D, /atom))
|
||||
var/atom/A = D
|
||||
if(isliving(A))
|
||||
atomsnowflake += "<a href='?_src_=vars;rename=[refid]'><b>[D]</b></a>"
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
|
||||
/mob/proc/HasDisease(datum/disease/D)
|
||||
for(var/datum/disease/DD in viruses)
|
||||
for(var/thing in viruses)
|
||||
var/datum/disease/DD = thing
|
||||
if(D.IsSame(DD))
|
||||
return 1
|
||||
return 0
|
||||
@@ -39,7 +40,7 @@
|
||||
var/datum/disease/DD = new D.type(1, D, 0)
|
||||
viruses += DD
|
||||
DD.affected_mob = src
|
||||
DD.holder = src
|
||||
SSdisease.active_diseases += DD //Add it to the active diseases list, now that it's actually in a mob and being processed.
|
||||
|
||||
//Copy properties over. This is so edited diseases persist.
|
||||
var/list/skipped = list("affected_mob","holder","carrier","stage","type","parent_type","vars","transformed")
|
||||
@@ -147,6 +148,9 @@
|
||||
|
||||
|
||||
/mob/living/carbon/human/CanContractDisease(datum/disease/D)
|
||||
if(dna && (VIRUSIMMUNE in dna.species.species_traits))
|
||||
if(dna && (VIRUSIMMUNE in dna.species.species_traits) && !D.bypasses_immunity)
|
||||
return 0
|
||||
for(var/thing in D.required_organs)
|
||||
if(!((locate(thing) in bodyparts) || (locate(thing) in internal_organs)))
|
||||
return 0
|
||||
return ..()
|
||||
@@ -46,21 +46,23 @@
|
||||
var/stage_prob = 4
|
||||
|
||||
//Other
|
||||
var/longevity = 150 //Time in ticks disease stays in objects, Syringes and such are infinite.
|
||||
var/list/viable_mobtypes = list() //typepaths of viable mobs
|
||||
var/mob/living/carbon/affected_mob = null
|
||||
var/atom/movable/holder = null
|
||||
var/list/cures = list() //list of cures if the disease has the CURABLE flag, these are reagent ids
|
||||
var/infectivity = 65
|
||||
var/cure_chance = 8
|
||||
var/carrier = 0 //If our host is only a carrier
|
||||
var/carrier = FALSE //If our host is only a carrier
|
||||
var/bypasses_immunity = FALSE //Does it skip species virus immunity check? Some things may diseases and not viruses
|
||||
var/permeability_mod = 1
|
||||
var/severity = NONTHREAT
|
||||
var/list/required_organs = list()
|
||||
var/needs_all_cures = TRUE
|
||||
var/list/strain_data = list() //dna_spread special bullshit
|
||||
|
||||
|
||||
/datum/disease/Destroy()
|
||||
affected_mob = null
|
||||
SSdisease.active_diseases.Remove(src)
|
||||
return ..()
|
||||
|
||||
/datum/disease/proc/stage_act()
|
||||
var/cure = has_cure()
|
||||
@@ -93,13 +95,16 @@
|
||||
if(!. || (needs_all_cures && . < cures.len))
|
||||
return 0
|
||||
|
||||
/datum/disease/proc/spread(atom/source, force_spread = 0)
|
||||
|
||||
/datum/disease/proc/spread(force_spread = 0)
|
||||
if(!affected_mob)
|
||||
return
|
||||
|
||||
if((spread_flags & SPECIAL || spread_flags & NON_CONTAGIOUS || spread_flags & BLOOD) && !force_spread)
|
||||
return
|
||||
|
||||
if(affected_mob)
|
||||
if( affected_mob.reagents.has_reagent("spaceacillin") || (affected_mob.satiety > 0 && prob(affected_mob.satiety/10)) )
|
||||
return
|
||||
if(affected_mob.reagents.has_reagent("spaceacillin") || (affected_mob.satiety > 0 && prob(affected_mob.satiety/10)))
|
||||
return
|
||||
|
||||
var/spread_range = 1
|
||||
|
||||
@@ -109,15 +114,9 @@
|
||||
if(spread_flags & AIRBORNE)
|
||||
spread_range++
|
||||
|
||||
if(!source)
|
||||
if(affected_mob)
|
||||
source = affected_mob
|
||||
else
|
||||
return
|
||||
|
||||
var/turf/T = source.loc
|
||||
var/turf/T = affected_mob.loc
|
||||
if(istype(T))
|
||||
for(var/mob/living/carbon/C in oview(spread_range, source))
|
||||
for(var/mob/living/carbon/C in oview(spread_range, affected_mob))
|
||||
var/turf/V = get_turf(C)
|
||||
if(V)
|
||||
while(TRUE)
|
||||
@@ -129,29 +128,6 @@
|
||||
break
|
||||
V = Temp
|
||||
|
||||
/datum/disease/process()
|
||||
if(!holder)
|
||||
SSdisease.processing -= src
|
||||
return
|
||||
|
||||
if(prob(infectivity))
|
||||
spread(holder)
|
||||
|
||||
if(affected_mob)
|
||||
for(var/datum/disease/D in affected_mob.viruses)
|
||||
if(D != src)
|
||||
if(IsSame(D))
|
||||
qdel(D)
|
||||
|
||||
if(holder == affected_mob)
|
||||
if(affected_mob.stat != DEAD)
|
||||
stage_act()
|
||||
|
||||
if(!affected_mob)
|
||||
if(prob(70))
|
||||
if(--longevity<=0)
|
||||
cure()
|
||||
|
||||
|
||||
/datum/disease/proc/cure()
|
||||
if(affected_mob)
|
||||
@@ -161,20 +137,6 @@
|
||||
remove_virus()
|
||||
qdel(src)
|
||||
|
||||
|
||||
/datum/disease/New()
|
||||
if(required_organs && required_organs.len)
|
||||
if(ishuman(affected_mob))
|
||||
var/mob/living/carbon/human/H = affected_mob
|
||||
for(var/obj/item/organ/O in required_organs)
|
||||
if(!locate(O) in H.bodyparts)
|
||||
if(!locate(O) in H.internal_organs)
|
||||
cure()
|
||||
return
|
||||
|
||||
SSdisease.processing += src
|
||||
|
||||
|
||||
/datum/disease/proc/IsSame(datum/disease/D)
|
||||
if(istype(src, D.type))
|
||||
return 1
|
||||
@@ -191,11 +153,6 @@
|
||||
return type
|
||||
|
||||
|
||||
/datum/disease/Destroy()
|
||||
SSdisease.processing.Remove(src)
|
||||
return ..()
|
||||
|
||||
|
||||
/datum/disease/proc/IsSpreadByTouch()
|
||||
if(spread_flags & CONTACT_FEET || spread_flags & CONTACT_HANDS || spread_flags & CONTACT_GENERAL)
|
||||
return 1
|
||||
|
||||
@@ -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)
|
||||
@@ -91,7 +93,7 @@
|
||||
if(!(istype(D, /datum/disease/advance)))
|
||||
return 0
|
||||
|
||||
if(src.GetDiseaseID() != D.GetDiseaseID())
|
||||
if(GetDiseaseID() != D.GetDiseaseID())
|
||||
return 0
|
||||
return 1
|
||||
|
||||
@@ -116,10 +118,10 @@
|
||||
|
||||
// Mix the symptoms of two diseases (the src and the argument)
|
||||
/datum/disease/advance/proc/Mix(datum/disease/advance/D)
|
||||
if(!(src.IsSame(D)))
|
||||
if(!(IsSame(D)))
|
||||
var/list/possible_symptoms = shuffle(D.symptoms)
|
||||
for(var/datum/symptom/S in possible_symptoms)
|
||||
AddSymptom(new S.type)
|
||||
AddSymptom(S.Copy())
|
||||
|
||||
/datum/disease/advance/proc/HasSymptom(datum/symptom/S)
|
||||
for(var/datum/symptom/symp in symptoms)
|
||||
@@ -155,8 +157,7 @@
|
||||
|
||||
return generated
|
||||
|
||||
/datum/disease/advance/proc/Refresh(new_name = 0)
|
||||
//to_chat(world, "[src.name] \ref[src] - REFRESH!")
|
||||
/datum/disease/advance/proc/Refresh(new_name = FALSE)
|
||||
GenerateProperties()
|
||||
AssignProperties()
|
||||
id = null
|
||||
@@ -192,10 +193,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 +262,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 +271,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 +294,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 +321,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
|
||||
@@ -395,7 +411,7 @@
|
||||
D.AssignName(new_name)
|
||||
D.Refresh()
|
||||
|
||||
for(var/datum/disease/advance/AD in SSdisease.processing)
|
||||
for(var/datum/disease/advance/AD in SSdisease.active_diseases)
|
||||
AD.Refresh()
|
||||
|
||||
for(var/mob/living/carbon/human/H in shuffle(GLOB.living_mob_list))
|
||||
@@ -410,13 +426,6 @@
|
||||
name_symptoms += S.name
|
||||
message_admins("[key_name_admin(user)] has triggered a custom virus outbreak of [D.name]! It has these symptoms: [english_list(name_symptoms)]")
|
||||
|
||||
/*
|
||||
/mob/verb/test()
|
||||
|
||||
for(var/datum/disease/D in SSdisease.processing)
|
||||
to_chat(src, "<a href='?_src_=vars;Vars=\ref[D]'>[D.name] - [D.holder]</a>")
|
||||
*/
|
||||
|
||||
|
||||
/datum/disease/advance/proc/totalStageSpeed()
|
||||
return properties["stage_rate"]
|
||||
|
||||
@@ -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,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
|
||||
|
||||
@@ -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/Start(datum/disease/advance/A)
|
||||
..()
|
||||
if(A.properties["stealth"] >= 4)
|
||||
suppress_warning = TRUE
|
||||
if(A.spread_flags &= AIRBORNE) //infect bystanders
|
||||
infective = TRUE
|
||||
if(A.properties["resistance"] >= 3) //strong enough to drop items
|
||||
power = 1.5
|
||||
if(A.properties["resistance"] >= 10) //strong enough to stun (rarely)
|
||||
power = 2
|
||||
if(A.properties["stage_rate"] >= 6) //cough more often
|
||||
symptom_delay_max = 10
|
||||
|
||||
/datum/symptom/cough/Activate(datum/disease/advance/A)
|
||||
..()
|
||||
if(prob(SYMPTOM_ACTIVATION_PROB))
|
||||
var/mob/living/M = A.affected_mob
|
||||
switch(A.stage)
|
||||
if(1, 2, 3)
|
||||
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(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)
|
||||
|
||||
@@ -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)
|
||||
@@ -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
|
||||
|
||||
@@ -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(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(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)
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
@@ -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>")
|
||||
|
||||
@@ -1,39 +1,48 @@
|
||||
/*
|
||||
//////////////////////////////////////
|
||||
|
||||
Sneezing
|
||||
|
||||
Very Noticable.
|
||||
Increases resistance.
|
||||
Doesn't increase stage speed.
|
||||
Very transmittable.
|
||||
Low Level.
|
||||
|
||||
Bonus
|
||||
Forces a spread type of AIRBORNE
|
||||
with extra range!
|
||||
|
||||
//////////////////////////////////////
|
||||
*/
|
||||
|
||||
/datum/symptom/sneeze
|
||||
|
||||
name = "Sneezing"
|
||||
stealth = -2
|
||||
resistance = 3
|
||||
stage_speed = 0
|
||||
transmittable = 4
|
||||
level = 1
|
||||
severity = 1
|
||||
|
||||
/datum/symptom/sneeze/Activate(datum/disease/advance/A)
|
||||
..()
|
||||
if(prob(SYMPTOM_ACTIVATION_PROB))
|
||||
var/mob/living/M = A.affected_mob
|
||||
switch(A.stage)
|
||||
if(1, 2, 3)
|
||||
M.emote("sniff")
|
||||
else
|
||||
M.emote("sneeze")
|
||||
A.spread(A.holder, 5)
|
||||
return
|
||||
/*
|
||||
//////////////////////////////////////
|
||||
|
||||
Sneezing
|
||||
|
||||
Very Noticable.
|
||||
Increases resistance.
|
||||
Doesn't increase stage speed.
|
||||
Very transmittable.
|
||||
Low Level.
|
||||
|
||||
Bonus
|
||||
Forces a spread type of AIRBORNE
|
||||
with extra range!
|
||||
|
||||
//////////////////////////////////////
|
||||
*/
|
||||
|
||||
/datum/symptom/sneeze
|
||||
name = "Sneezing"
|
||||
stealth = -2
|
||||
resistance = 3
|
||||
stage_speed = 0
|
||||
transmittable = 4
|
||||
level = 1
|
||||
severity = 1
|
||||
symptom_delay_min = 5
|
||||
symptom_delay_max = 35
|
||||
|
||||
/datum/symptom/sneeze/Start(datum/disease/advance/A)
|
||||
..()
|
||||
if(A.properties["transmittable"] >= 9) //longer spread range
|
||||
power = 2
|
||||
if(A.properties["stealth"] >= 4)
|
||||
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(5)
|
||||
return
|
||||
|
||||
@@ -13,18 +13,30 @@
|
||||
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
|
||||
for(var/i = 1; i <= S.len; i++)
|
||||
if(src.type == S[i])
|
||||
if(type == S[i])
|
||||
id = "[i]"
|
||||
return
|
||||
CRASH("We couldn't assign an ID!")
|
||||
|
||||
// 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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
@@ -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>")
|
||||
@@ -7,7 +7,7 @@
|
||||
cure_text = "Ethanol"
|
||||
cures = list("ethanol")
|
||||
agent = "Excess Lepidopticides"
|
||||
viable_mobtypes = list(/mob/living/carbon/human,/mob/living/carbon/monkey)
|
||||
viable_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
|
||||
desc = "If left untreated subject will regurgitate butterflies."
|
||||
severity = MEDIUM
|
||||
|
||||
|
||||
@@ -8,11 +8,11 @@
|
||||
permeability_mod = 1
|
||||
desc = "If left untreated the subject will become very weak, and may vomit often."
|
||||
severity = "Dangerous!"
|
||||
longevity = 1000
|
||||
disease_flags = CAN_CARRY|CAN_RESIST
|
||||
spread_flags = NON_CONTAGIOUS
|
||||
visibility_flags = HIDDEN_PANDEMIC
|
||||
required_organs = list(/obj/item/organ/appendix)
|
||||
bypasses_immunity = TRUE // Immunity is based on not having an appendix; this isn't a virus
|
||||
|
||||
/datum/disease/appendicitis/stage_act()
|
||||
..()
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
cure_text = "Sugar"
|
||||
cures = list("sugar")
|
||||
agent = "Apidae Infection"
|
||||
viable_mobtypes = list(/mob/living/carbon/human,/mob/living/carbon/monkey)
|
||||
viable_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
|
||||
desc = "If left untreated subject will regurgitate bees."
|
||||
severity = DANGEROUS
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
viable_mobtypes = list(/mob/living/carbon/human)
|
||||
cure_chance = 15//higher chance to cure, since two reagents are required
|
||||
desc = "This disease destroys the braincells, causing brain fever, brain necrosis and general intoxication."
|
||||
required_organs = list(/obj/item/bodypart/head)
|
||||
required_organs = list(/obj/item/organ/brain)
|
||||
severity = DANGEROUS
|
||||
|
||||
/datum/disease/brainrot/stage_act() //Removed toxloss because damaging diseases are pretty horrible. Last round it killed the entire station because the cure didn't work -- Urist -ACTUALLY Removed rather than commented out, I don't see it returning - RR
|
||||
|
||||
@@ -25,8 +25,8 @@
|
||||
//Absorbs the target DNA.
|
||||
strain_data["dna"] = new affected_mob.dna.type
|
||||
affected_mob.dna.copy_dna(strain_data["dna"])
|
||||
src.carrier = 1
|
||||
src.stage = 4
|
||||
carrier = TRUE
|
||||
stage = 4
|
||||
return
|
||||
|
||||
switch(stage)
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
cure_text = "Synaptizine & Sulfur"
|
||||
cures = list("synaptizine","sulfur")
|
||||
agent = "Gravitokinetic Bipotential SADS-"
|
||||
viable_mobtypes = list(/mob/living/carbon/human,/mob/living/carbon/monkey)
|
||||
viable_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
|
||||
desc = "If left untreated death will occur."
|
||||
severity = BIOHAZARD
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user