Merge remote-tracking branch 'origin/master' into kevinz000-patch-70
This commit is contained in:
@@ -98,7 +98,16 @@
|
||||
#define DRINKSBLOOD 15
|
||||
#define NOEYES 16
|
||||
#define MARKINGS 17
|
||||
#define MUTCOLORS2 18
|
||||
#define MUTCOLORS3 19
|
||||
#define NOAROUSAL 20 //Stops all arousal effects
|
||||
#define NOGENITALS 21 //Cannot create, use, or otherwise have genitals
|
||||
#define MATRIXED 22 //if icon is color matrix'd
|
||||
#define SKINTONE 23 //uses skin tones
|
||||
#define HORNCOLOR 24
|
||||
#define WINGCOLOR 25
|
||||
|
||||
//organ slots
|
||||
#define ORGAN_SLOT_BRAIN "brain"
|
||||
#define ORGAN_SLOT_APPENDIX "appendix"
|
||||
#define ORGAN_SLOT_RIGHT_ARM_AUG "r_arm_device"
|
||||
@@ -122,3 +131,8 @@
|
||||
#define ORGAN_SLOT_BRAIN_ANTISTUN "brain_antistun"
|
||||
#define ORGAN_SLOT_TAIL "tail"
|
||||
#define ORGAN_SLOT_PENIS "penis"
|
||||
|
||||
////organ defines
|
||||
#define STANDARD_ORGAN_THRESHOLD 100
|
||||
#define STANDARD_ORGAN_HEALING 0.001
|
||||
#define STANDARD_ORGAN_DECAY 0.00222 //designed to fail organs when left to decay for ~15 minutes
|
||||
@@ -6,7 +6,7 @@
|
||||
#define ACCESS_MORGUE 6
|
||||
#define ACCESS_TOX 7 //R&D department, R&D console, burn chamber on some maps
|
||||
#define ACCESS_TOX_STORAGE 8 //Toxins storage, burn chamber on some maps
|
||||
#define ACCESS_GENETICS 9
|
||||
#define ACCESS_GENETICS 9
|
||||
#define ACCESS_ENGINE 10 //Engineering area, power monitor, power flow control console
|
||||
#define ACCESS_ENGINE_EQUIP 11 //APCs, EngiVend/YouTool, engineering equipment lockers
|
||||
#define ACCESS_MAINT_TUNNELS 12
|
||||
@@ -64,6 +64,8 @@
|
||||
#define ACCESS_WEAPONS 66 //Weapon authorization for secbots
|
||||
#define ACCESS_NETWORK 67 //NTnet diagnostics/monitoring software
|
||||
#define ACCESS_CLONING 68 //Cloning room and clone pod ejection
|
||||
#define ACCESS_ENTER_GENPOP 69
|
||||
#define ACCESS_LEAVE_GENPOP 70
|
||||
|
||||
//BEGIN CENTCOM ACCESS
|
||||
/*Should leave plenty of room if we need to add more access levels.
|
||||
|
||||
@@ -81,3 +81,10 @@
|
||||
|
||||
#define SPAM_TRIGGER_WARNING 5 //Number of identical messages required before the spam-prevention will warn you to stfu
|
||||
#define SPAM_TRIGGER_AUTOMUTE 10 //Number of identical messages required before the spam-prevention will automute you
|
||||
|
||||
///Max length of a keypress command before it's considered to be a forged packet/bogus command
|
||||
#define MAX_KEYPRESS_COMMANDLENGTH 16
|
||||
///Max amount of keypress messages per second over two seconds before client is autokicked
|
||||
#define MAX_KEYPRESS_AUTOKICK 100
|
||||
///Length of held key rolling buffer
|
||||
#define HELD_KEY_BUFFER_LENGTH 15
|
||||
|
||||
@@ -38,5 +38,5 @@
|
||||
|
||||
//Gangshit
|
||||
#define NOT_DOMINATING -1
|
||||
#define MAX_LEADERS_GANG 3
|
||||
#define MAX_LEADERS_GANG 4
|
||||
#define INITIAL_DOM_ATTEMPTS 3
|
||||
|
||||
@@ -23,8 +23,9 @@
|
||||
#define AI_DETECT_HUD "19"
|
||||
#define NANITE_HUD "20"
|
||||
#define DIAG_NANITE_FULL_HUD "21"
|
||||
#define RAD_HUD "22" //radation alerts for medical huds
|
||||
//for antag huds. these are used at the /mob level
|
||||
#define ANTAG_HUD "22"
|
||||
#define ANTAG_HUD "23"
|
||||
|
||||
//by default everything in the hud_list of an atom is an image
|
||||
//a value in hud_list with one of these will change that behavior
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
#define BALLS_SACK_SIZE_DEF 8
|
||||
#define BALLS_SACK_SIZE_MAX 40
|
||||
|
||||
#define CUM_RATE 5
|
||||
#define CUM_RATE 0.035
|
||||
#define CUM_RATE_MULT 1
|
||||
#define CUM_EFFICIENCY 1//amount of nutrition required per life()
|
||||
|
||||
@@ -89,17 +89,6 @@
|
||||
//Damage stuffs
|
||||
#define AROUSAL "arousal"
|
||||
|
||||
//DNA stuffs. Remember to change this if upstream adds more snowflake options
|
||||
|
||||
|
||||
//Species stuffs. Remember to change this if upstream updates species flags
|
||||
#define MUTCOLORS2 35
|
||||
#define MUTCOLORS3 36
|
||||
#define NOAROUSAL 37 //Stops all arousal effects
|
||||
#define NOGENITALS 38 //Cannot create, use, or otherwise have genitals
|
||||
#define MATRIXED 39 //if icon is color matrix'd
|
||||
#define SKINTONE 40 //uses skin tones
|
||||
|
||||
//Citadel istypes
|
||||
#define isgenital(A) (istype(A, /obj/item/organ/genital))
|
||||
|
||||
@@ -123,7 +112,6 @@
|
||||
#define STAMINA_CRIT 140 //crit for stamina damage. forces a rest, and stops movement until stamina goes back to stamina softcrit
|
||||
#define STAMINA_SOFTCRIT_TRADITIONAL 0 //same as STAMINA_SOFTCRIT except for the more traditional health calculations
|
||||
#define STAMINA_CRIT_TRADITIONAL -40 //ditto, but for STAMINA_CRIT
|
||||
#define MIN_MELEE_STAMCOST 1.25 //Minimum cost for swinging items around. Will be extra useful when stats and skills are introduced.
|
||||
|
||||
#define CRAWLUNDER_DELAY 30 //Delay for crawling under a standing mob
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
GLOBAL_VAR_INIT(clockwork_construction_value, 0) //The total value of all structures built by the clockwork cult
|
||||
GLOBAL_VAR_INIT(clockwork_vitality, 0) //How much Vitality is stored, total
|
||||
GLOBAL_VAR_INIT(clockwork_power, 0) //How many watts of power are globally available to the clockwork cult
|
||||
GLOBAL_VAR_INIT(neovgre_exists, 0) //Does neovgre exist?
|
||||
|
||||
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
|
||||
|
||||
@@ -4,15 +4,15 @@
|
||||
#define COLOR_INPUT_ENABLED "#D3B5B5"
|
||||
|
||||
#define COLOR_DARKMODE_INFO_BUTTONS_BG "#40628A"
|
||||
#define COLOR_DARKMODE_ISSUE_BUTTON_BG "#ce4242"
|
||||
#define COLOR_DARKMODE_BACKGROUND "#202020"
|
||||
#define COLOR_DARKMODE_DARKBACKGROUND "#171717"
|
||||
#define COLOR_DARKMODE_TEXT "#f0f0f0"
|
||||
#define COLOR_DARKMODE_ISSUE_BUTTON_BG "#A92C2C"
|
||||
#define COLOR_DARKMODE_BACKGROUND "#272727"
|
||||
#define COLOR_DARKMODE_DARKBACKGROUND "#242424"
|
||||
#define COLOR_DARKMODE_TEXT "#E0E0E0"
|
||||
|
||||
#define COLOR_WHITEMODE_INFO_BUTTONS_BG "#90b3dd"
|
||||
#define COLOR_WHITEMODE_ISSUE_BUTTON_BG "#ef7f7f"
|
||||
#define COLOR_WHITEMODE_BACKGROUND "#ffffff"
|
||||
#define COLOR_WHITEMODE_DARKBACKGROUND "#eeeeee"
|
||||
#define COLOR_WHITEMODE_INFO_BUTTONS_BG "#90B3DD"
|
||||
#define COLOR_WHITEMODE_ISSUE_BUTTON_BG "#EF7F7F"
|
||||
#define COLOR_WHITEMODE_BACKGROUND "#F0F0F0"
|
||||
#define COLOR_WHITEMODE_DARKBACKGROUND "#E6E6E6"
|
||||
#define COLOR_WHITEMODE_TEXT "#000000"
|
||||
|
||||
#define COLOR_FLOORTILE_GRAY "#8D8B8B"
|
||||
|
||||
@@ -183,4 +183,16 @@ GLOBAL_LIST_INIT(shove_disarming_types, typecacheof(list(
|
||||
#define BODY_ZONE_PRECISE_R_FOOT "r_foot"
|
||||
|
||||
//We will round to this value in damage calculations.
|
||||
#define DAMAGE_PRECISION 0.1
|
||||
#define DAMAGE_PRECISION 0.1
|
||||
|
||||
//items total mass, used to calculate their attacks' stamina costs. If not defined, the cost will be (w_class * 1.25)
|
||||
#define TOTAL_MASS_TINY_ITEM 1.25
|
||||
#define TOTAL_MASS_SMALL_ITEM 2.5
|
||||
#define TOTAL_MASS_NORMAL_ITEM 3.75
|
||||
#define TOTAL_MASS_BULKY_ITEM 5
|
||||
#define TOTAL_MASS_HUGE_ITEM 6.25
|
||||
#define TOTAL_MASS_GIGANTIC_ITEM 7.5
|
||||
|
||||
#define TOTAL_MASS_HAND_REPLACEMENT 5 //standard punching stamina cost. most hand replacements are huge items anyway.
|
||||
#define TOTAL_MASS_MEDIEVAL_WEAPON 3.6 //very, very generic average sword/warpick/etc. weight in pounds.
|
||||
#define TOTAL_MASS_TOY_SWORD 1.5
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
// start global signals with "!", this used to be necessary but now it's just a formatting choice
|
||||
#define COMSIG_GLOB_NEW_Z "!new_z" //from base of datum/controller/subsystem/mapping/proc/add_new_zlevel(): (list/args)
|
||||
#define COMSIG_GLOB_VAR_EDIT "!var_edit" //called after a successful var edit somewhere in the world: (list/args)
|
||||
|
||||
#define COMSIG_GLOB_LIVING_SAY_SPECIAL "!say_special" //global living say plug - use sparingly: (mob/speaker , message)
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
// /datum signals
|
||||
@@ -121,8 +121,13 @@
|
||||
#define COMSIG_MOVABLE_HEAR "movable_hear" //from base of atom/movable/Hear(): (message, atom/movable/speaker, message_language, raw_message, radio_freq, list/spans, message_mode)
|
||||
#define COMSIG_MOVABLE_DISPOSING "movable_disposing" //called when the movable is added to a disposal holder object for disposal movement: (obj/structure/disposalholder/holder, obj/machinery/disposal/source)
|
||||
|
||||
// /mind signals
|
||||
#define COMSIG_MIND_TRANSFER "mind_transfer" //from base of mind/transfer_to(): (new_character, old_character)
|
||||
|
||||
// /mob signals
|
||||
#define COMSIG_MOB_DEATH "mob_death" //from base of mob/death(): (gibbed)
|
||||
#define COMSIG_MOB_GHOSTIZE "mob_ghostize" //from base of mob/Ghostize() (can_reenter_corpse)
|
||||
#define COMPONENT_BLOCK_GHOSTING 1
|
||||
#define COMSIG_MOB_ALLOWED "mob_allowed" //from base of obj/allowed(mob/M): (/obj) returns bool, if TRUE the mob has id access to the obj
|
||||
#define COMSIG_MOB_RECEIVE_MAGIC "mob_receive_magic" //from base of mob/anti_magic_check(): (magic, holy, protection_sources)
|
||||
#define COMPONENT_BLOCK_MAGIC 1
|
||||
@@ -132,6 +137,7 @@
|
||||
#define COMSIG_MOB_ITEM_AFTERATTACK "mob_item_afterattack" //from base of obj/item/afterattack(): (atom/target, mob/user, proximity_flag, click_parameters)
|
||||
#define COMSIG_MOB_ATTACK_RANGED "mob_attack_ranged" //from base of mob/RangedAttack(): (atom/A, params)
|
||||
#define COMSIG_MOB_THROW "mob_throw" //from base of /mob/throw_item(): (atom/target)
|
||||
#define COMSIG_MOB_KEY_CHANGE "mob_key_change" //from base of /mob/transfer_ckey()
|
||||
#define COMSIG_MOB_UPDATE_SIGHT "mob_update_sight" //from base of /mob/update_sight(): ()
|
||||
#define COMSIG_MOB_SAY "mob_say" // from /mob/living/say(): (proc args list)
|
||||
#define COMPONENT_UPPERCASE_SPEECH 1
|
||||
@@ -159,6 +165,9 @@
|
||||
#define COMSIG_OBJ_BREAK "obj_break" //from base of /obj/obj_break(): (damage_flag)
|
||||
#define COMSIG_OBJ_SETANCHORED "obj_setanchored" //called in /obj/structure/setAnchored(): (value)
|
||||
|
||||
// /machinery signals
|
||||
#define COMSIG_MACHINE_EJECT_OCCUPANT "eject_occupant" //from base of obj/machinery/dropContents() (occupant)
|
||||
|
||||
// /obj/item signals
|
||||
#define COMSIG_ITEM_ATTACK "item_attack" //from base of obj/item/attack(): (/mob/living/target, /mob/living/user)
|
||||
#define COMSIG_ITEM_ATTACK_SELF "item_attack_self" //from base of obj/item/attack_self(): (/mob)
|
||||
@@ -188,6 +197,7 @@
|
||||
#define COMPONENT_DELETE_OLD_IMPLANT 4
|
||||
#define COMSIG_IMPLANT_EXISTING_UPLINK "implant_uplink_exists" //called on implants being implanted into someone with an uplink implant: (datum/component/uplink)
|
||||
//This uses all return values of COMSIG_IMPLANT_OTHER
|
||||
#define COMSIG_IMPLANT_REMOVING "implant_removing" //from base of /obj/item/implant/proc/removed() (list/args)
|
||||
|
||||
// /obj/item/pda signals
|
||||
#define COMSIG_PDA_CHANGE_RINGTONE "pda_change_ringtone" //called on pda when the user changes the ringtone: (mob/living/user, new_ringtone)
|
||||
@@ -221,6 +231,8 @@
|
||||
//Mood
|
||||
#define COMSIG_ADD_MOOD_EVENT "add_mood" //Called when you send a mood event from anywhere in the code.
|
||||
#define COMSIG_CLEAR_MOOD_EVENT "clear_mood" //Called when you clear a mood event from anywhere in the code.
|
||||
#define COMSIG_INCREASE_SANITY "decrease_sanity" //Called when you want to increase sanity from anywhere in the code.
|
||||
#define COMSIG_DECREASE_SANITY "increase_sanity" //Same as above but to decrease sanity instead.
|
||||
|
||||
//NTnet
|
||||
#define COMSIG_COMPONENT_NTNET_RECEIVE "ntnet_receive" //called on an object by its NTNET connection component on receive. (sending_id(number), sending_netname(text), data(datum/netdata))
|
||||
|
||||
@@ -109,3 +109,5 @@
|
||||
#define RCD_AIRLOCK 2
|
||||
#define RCD_DECONSTRUCT 3
|
||||
#define RCD_WINDOWGRILLE 4
|
||||
#define RCD_MACHINE 8
|
||||
#define RCD_COMPUTER 16
|
||||
@@ -0,0 +1,18 @@
|
||||
#define DONATOR_GROUP_TIER_1_CONFIG_PATH /datum/config_entry/keyed_list/donator_group/tier_1_donators
|
||||
#define DONATOR_GROUP_TIER_2_CONFIG_PATH /datum/config_entry/keyed_list/donator_group/tier_2_donators
|
||||
#define DONATOR_GROUP_TIER_3_CONFIG_PATH /datum/config_entry/keyed_list/donator_group/tier_3_donators
|
||||
|
||||
#define DONATOR_GROUP_TIER_1_CONFIG_SUBPATH keyed_list/donator_group/tier_1_donators
|
||||
#define DONATOR_GROUP_TIER_2_CONFIG_SUBPATH keyed_list/donator_group/tier_2_donators
|
||||
#define DONATOR_GROUP_TIER_3_CONFIG_SUBPATH keyed_list/donator_group/tier_3_donators
|
||||
|
||||
#define TIER_1_DONATORS CONFIG_GET(DONATOR_GROUP_TIER_1_CONFIG_SUBPATH)
|
||||
#define TIER_2_DONATORS CONFIG_GET(DONATOR_GROUP_TIER_2_CONFIG_SUBPATH)
|
||||
#define TIER_3_DONATORS CONFIG_GET(DONATOR_GROUP_TIER_3_CONFIG_SUBPATH)
|
||||
|
||||
//flags
|
||||
#define DONATOR_GROUP_TIER_1 "T1"
|
||||
#define DONATOR_GROUP_TIER_2 "T2"
|
||||
#define DONATOR_GROUP_TIER_3 "T3"
|
||||
|
||||
#define IS_CKEY_DONATOR_GROUP(ckey, groupid) is_donator_group(ckey, groupid)
|
||||
@@ -10,6 +10,8 @@
|
||||
#define CHECK_BITFIELD(variable, flag) (variable & (flag))
|
||||
#define TOGGLE_BITFIELD(variable, flag) (variable ^= (flag))
|
||||
|
||||
#define CHECK_MULTIPLE_BITFIELDS(flagvar, flags) (((flagvar) & (flags)) == (flags))
|
||||
|
||||
GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768))
|
||||
|
||||
// for /datum/var/datum_flags
|
||||
|
||||
@@ -234,3 +234,6 @@ GLOBAL_LIST_INIT(security_wintercoat_allowed, typecacheof(list(
|
||||
/obj/item/tank/internals/emergency_oxygen,
|
||||
/obj/item/tank/internals/plasmaman,
|
||||
/obj/item/toy)))
|
||||
|
||||
//Internals checker
|
||||
#define GET_INTERNAL_SLOTS(C) list(C.head, C.wear_mask)
|
||||
|
||||
@@ -50,15 +50,16 @@
|
||||
#define isgolem(A) (is_species(A, /datum/species/golem))
|
||||
#define islizard(A) (is_species(A, /datum/species/lizard))
|
||||
#define isplasmaman(A) (is_species(A, /datum/species/plasmaman))
|
||||
#define ispodperson(A) (is_species(A, /datum/species/podperson))
|
||||
#define ispodperson(A) (is_species(A, /datum/species/pod))
|
||||
#define isflyperson(A) (is_species(A, /datum/species/fly))
|
||||
#define isjellyperson(A) (is_species(A, /datum/species/jelly))
|
||||
#define isslimeperson(A) (is_species(A, /datum/species/jelly/slime))
|
||||
#define isluminescent(A) (is_species(A, /datum/species/jelly/luminescent))
|
||||
#define iszombie(A) (is_species(A, /datum/species/zombie))
|
||||
#define ismoth(A) (is_species(A, /datum/species/moth))
|
||||
#define ismoth(A) (is_species(A, /datum/species/insect))
|
||||
#define ishumanbasic(A) (is_species(A, /datum/species/human))
|
||||
#define iscatperson(A) (ishumanbasic(A) && istype(A.dna.species, /datum/species/human/felinid) )
|
||||
#define isdwarf(A) (is_species(A, /datum/species/dwarf))
|
||||
|
||||
//more carbon mobs
|
||||
#define ismonkey(A) (istype(A, /mob/living/carbon/monkey))
|
||||
|
||||
@@ -48,3 +48,42 @@
|
||||
#define JOB_UNAVAILABLE_PLAYTIME 3
|
||||
#define JOB_UNAVAILABLE_ACCOUNTAGE 4
|
||||
#define JOB_UNAVAILABLE_SLOTFULL 5
|
||||
#define JOB_UNAVAILABLE_SPECIESLOCK 6
|
||||
|
||||
#define DEFAULT_RELIGION "Christianity"
|
||||
#define DEFAULT_DEITY "Space Jesus"
|
||||
|
||||
#define JOB_DISPLAY_ORDER_DEFAULT 0
|
||||
|
||||
#define JOB_DISPLAY_ORDER_ASSISTANT 1
|
||||
#define JOB_DISPLAY_ORDER_CAPTAIN 2
|
||||
#define JOB_DISPLAY_ORDER_HEAD_OF_PERSONNEL 3
|
||||
#define JOB_DISPLAY_ORDER_BARTENDER 4
|
||||
#define JOB_DISPLAY_ORDER_COOK 5
|
||||
#define JOB_DISPLAY_ORDER_BOTANIST 6
|
||||
#define JOB_DISPLAY_ORDER_JANITOR 7
|
||||
#define JOB_DISPLAY_ORDER_CLOWN 8
|
||||
#define JOB_DISPLAY_ORDER_MIME 9
|
||||
#define JOB_DISPLAY_ORDER_CURATOR 10
|
||||
#define JOB_DISPLAY_ORDER_LAWYER 11
|
||||
#define JOB_DISPLAY_ORDER_CHAPLAIN 12
|
||||
#define JOB_DISPLAY_ORDER_QUARTERMASTER 13
|
||||
#define JOB_DISPLAY_ORDER_CARGO_TECHNICIAN 14
|
||||
#define JOB_DISPLAY_ORDER_SHAFT_MINER 15
|
||||
#define JOB_DISPLAY_ORDER_CHIEF_ENGINEER 16
|
||||
#define JOB_DISPLAY_ORDER_STATION_ENGINEER 17
|
||||
#define JOB_DISPLAY_ORDER_ATMOSPHERIC_TECHNICIAN 18
|
||||
#define JOB_DISPLAY_ORDER_CHIEF_MEDICAL_OFFICER 19
|
||||
#define JOB_DISPLAY_ORDER_MEDICAL_DOCTOR 20
|
||||
#define JOB_DISPLAY_ORDER_CHEMIST 21
|
||||
#define JOB_DISPLAY_ORDER_GENETICIST 22
|
||||
#define JOB_DISPLAY_ORDER_VIROLOGIST 23
|
||||
#define JOB_DISPLAY_ORDER_RESEARCH_DIRECTOR 24
|
||||
#define JOB_DISPLAY_ORDER_SCIENTIST 25
|
||||
#define JOB_DISPLAY_ORDER_ROBOTICIST 26
|
||||
#define JOB_DISPLAY_ORDER_HEAD_OF_SECURITY 27
|
||||
#define JOB_DISPLAY_ORDER_WARDEN 28
|
||||
#define JOB_DISPLAY_ORDER_DETECTIVE 29
|
||||
#define JOB_DISPLAY_ORDER_SECURITY_OFFICER 30
|
||||
#define JOB_DISPLAY_ORDER_AI 31
|
||||
#define JOB_DISPLAY_ORDER_CYBORG 32
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
#define DOOR_HELPER_LAYER 2.71 //keep this above OPEN_DOOR_LAYER
|
||||
#define PROJECTILE_HIT_THRESHHOLD_LAYER 2.75 //projectiles won't hit objects at or below this layer if possible
|
||||
#define TABLE_LAYER 2.8
|
||||
#define TRAY_LAYER 2.85
|
||||
#define BELOW_OBJ_LAYER 2.9
|
||||
#define LOW_ITEM_LAYER 2.95
|
||||
//#define OBJ_LAYER 3 //For easy recordkeeping; this is a byond define
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#define INVESTIGATE_EXONET "exonet"
|
||||
#define INVESTIGATE_NANITES "nanites"
|
||||
#define INVESTIGATE_CIRCUIT "circuit"
|
||||
#define INVESTIGATE_FERMICHEM "fermichem"
|
||||
#define INVESTIGATE_RCD "rcd"
|
||||
|
||||
// Logging types for log_message()
|
||||
@@ -34,6 +35,7 @@
|
||||
#define LOG_GAME (1 << 12)
|
||||
#define LOG_ADMIN_PRIVATE (1 << 13)
|
||||
#define LOG_ASAY (1 << 14)
|
||||
#define LOG_VIRUS (1 << 15)
|
||||
|
||||
//Individual logging panel pages
|
||||
#define INDIVIDUAL_ATTACK_LOG (LOG_ATTACK)
|
||||
|
||||
@@ -201,4 +201,10 @@
|
||||
|
||||
return list(region_x1 & region_x2, region_y1 & region_y2)
|
||||
|
||||
#define EXP_DISTRIBUTION(desired_mean) ( -(1/(1/desired_mean)) * log(rand(1, 1000) * 0.001) )
|
||||
|
||||
#define LORENTZ_DISTRIBUTION(x, s) ( s*TAN(TODEGREES(PI*(rand()-0.5))) + x )
|
||||
#define LORENTZ_CUMULATIVE_DISTRIBUTION(x, y, s) ( (1/PI)*TORADIANS(arctan((x-y)/s)) + 1/2 )
|
||||
|
||||
#define RULE_OF_THREE(a, b, x) ((a*x)/b)
|
||||
// )
|
||||
|
||||
+10
-5
@@ -57,7 +57,7 @@ Will print: "/mob/living/carbon/human/death" (you can optionally embed it in a s
|
||||
#define BODYPARTS_LAYER 28 //Initially "AUGMENTS", this was repurposed to be a catch-all bodyparts flag
|
||||
#define MARKING_LAYER 27 //Matrixed body markings because clashing with snouts?
|
||||
#define BODY_ADJ_LAYER 26 //certain mutantrace features (snout, body markings) that must appear above the body parts
|
||||
#define GENITALS_ADJ_LAYER 25
|
||||
#define GENITALS_FRONT_LAYER 25 //Draws some genitalia above clothes and the TAUR body if need be.
|
||||
#define BODY_LAYER 24 //underwear, undershirts, socks, eyes, lips(makeup)
|
||||
#define FRONT_MUTATIONS_LAYER 23 //mutations that should appear above body, body_adj and bodyparts layer (e.g. laser eyes)
|
||||
#define DAMAGE_LAYER 22 //damage indicators (cuts and burns)
|
||||
@@ -69,7 +69,6 @@ Will print: "/mob/living/carbon/human/death" (you can optionally embed it in a s
|
||||
#define EARS_LAYER 17
|
||||
#define BODY_TAUR_LAYER 16
|
||||
#define SUIT_LAYER 15
|
||||
#define GENITALS_FRONT_LAYER 14 //Draws some genitalia above clothes and the TAUR body if need be.
|
||||
#define GLASSES_LAYER 13
|
||||
#define BELT_LAYER 12 //Possible make this an overlay of somethign required to wear a belt?
|
||||
#define SUIT_STORE_LAYER 11
|
||||
@@ -83,7 +82,7 @@ Will print: "/mob/living/carbon/human/death" (you can optionally embed it in a s
|
||||
#define HANDS_LAYER 3
|
||||
#define BODY_FRONT_LAYER 2
|
||||
#define FIRE_LAYER 1 //If you're on fire
|
||||
#define TOTAL_LAYERS 31 //KEEP THIS UP-TO-DATE OR SHIT WILL BREAK ;_;
|
||||
#define TOTAL_LAYERS 30 //KEEP THIS UP-TO-DATE OR SHIT WILL BREAK ;_;
|
||||
|
||||
//Human Overlay Index Shortcuts for alternate_worn_layer, layers
|
||||
//Because I *KNOW* somebody will think layer+1 means "above"
|
||||
@@ -315,7 +314,7 @@ GLOBAL_LIST_INIT(pda_reskins, list(PDA_SKIN_CLASSIC = 'icons/obj/pda.dmi', PDA_S
|
||||
#define MAP_MAXZ 6
|
||||
|
||||
// Defib stats
|
||||
#define DEFIB_TIME_LIMIT 120
|
||||
#define DEFIB_TIME_LIMIT 1500
|
||||
#define DEFIB_TIME_LOSS 60
|
||||
|
||||
// Diagonal movement
|
||||
@@ -473,6 +472,9 @@ GLOBAL_LIST_INIT(pda_reskins, list(PDA_SKIN_CLASSIC = 'icons/obj/pda.dmi', PDA_S
|
||||
|
||||
#define EGG_LAYING_MESSAGES list("lays an egg.","squats down and croons.","begins making a huge racket.","begins clucking raucously.")
|
||||
|
||||
// list of all null rod weapons
|
||||
#define HOLY_WEAPONS /obj/item/nullrod, /obj/item/twohanded/dualsaber/hypereutactic/chaplain, /obj/item/gun/energy/laser/redtag/hitscan/chaplain, /obj/item/multitool/chaplain, /obj/item/melee/baseball_bat/chaplain
|
||||
|
||||
// Used by PDA and cartridge code to reduce repetitiveness of spritesheets
|
||||
#define PDAIMG(what) {"<span class="pda16x16 [#what]"></span>"}
|
||||
|
||||
@@ -496,4 +498,7 @@ GLOBAL_LIST_INIT(pda_reskins, list(PDA_SKIN_CLASSIC = 'icons/obj/pda.dmi', PDA_S
|
||||
#define PREF_SAVELOAD_COOLDOWN 5
|
||||
|
||||
#define VOMIT_TOXIC 1
|
||||
#define VOMIT_PURPLE 2
|
||||
#define VOMIT_PURPLE 2
|
||||
|
||||
//Misc text define. Does 4 spaces. Used as a makeshift tabulator.
|
||||
#define FOURSPACES " "
|
||||
|
||||
+12
-3
@@ -116,6 +116,7 @@
|
||||
#define BIOWARE_GENERIC "generic"
|
||||
#define BIOWARE_NERVES "nerves"
|
||||
#define BIOWARE_CIRCULATION "circulation"
|
||||
#define BIOWARE_LIGAMENTS "ligaments"
|
||||
|
||||
//Health hud screws for carbon mobs
|
||||
#define SCREWYHUD_NONE 0
|
||||
@@ -203,8 +204,6 @@
|
||||
|
||||
#define MAX_CHICKENS 50
|
||||
|
||||
#define UNHEALING_EAR_DAMAGE 100
|
||||
|
||||
|
||||
#define INCORPOREAL_MOVE_BASIC 1
|
||||
#define INCORPOREAL_MOVE_SHADOW 2 // leaves a trail of shadows
|
||||
@@ -233,11 +232,15 @@
|
||||
#define OFFSET_S_STORE "s_store"
|
||||
#define OFFSET_FACEMASK "mask"
|
||||
#define OFFSET_HEAD "head"
|
||||
#define OFFSET_FACE "face"
|
||||
#define OFFSET_EYES "eyes"
|
||||
#define OFFSET_LIPS "lips"
|
||||
#define OFFSET_BELT "belt"
|
||||
#define OFFSET_BACK "back"
|
||||
#define OFFSET_SUIT "suit"
|
||||
#define OFFSET_NECK "neck"
|
||||
#define OFFSET_HAIR "hair"
|
||||
#define OFFSET_FHAIR "fhair"
|
||||
#define OFFSET_MUTPARTS "mutantparts"
|
||||
|
||||
//MINOR TWEAKS/MISC
|
||||
#define AGE_MIN 18 //youngest a character can be //CITADEL EDIT - 17 --> 18
|
||||
@@ -256,6 +259,9 @@
|
||||
|
||||
#define MAX_QUIRKS 6 //The maximum amount of quirks one character can have at roundstart
|
||||
|
||||
#define MAX_REVIVE_FIRE_DAMAGE 180
|
||||
#define MAX_REVIVE_BRUTE_DAMAGE 180
|
||||
|
||||
// AI Toggles
|
||||
#define AI_CAMERA_LUMINOSITY 5
|
||||
#define AI_VOX // Comment out if you don't want VOX to be enabled and have players download the voice sounds.
|
||||
@@ -264,3 +270,6 @@
|
||||
#define BODYPART_LIFE_UPDATE_HEALTH (1<<0)
|
||||
|
||||
#define HUMAN_FIRE_STACK_ICON_NUM 3
|
||||
|
||||
#define PULL_PRONE_SLOWDOWN 0.6
|
||||
#define HUMAN_CARRY_SLOWDOWN 0
|
||||
@@ -28,4 +28,11 @@
|
||||
#define MOVESPEED_ID_SIMPLEMOB_VARSPEED "SIMPLEMOB_VARSPEED_MODIFIER"
|
||||
#define MOVESPEED_ID_ADMIN_VAREDIT "ADMIN_VAREDIT_MODIFIER"
|
||||
|
||||
#define MOVESPEED_ID_PAI_SPACEWALK_SPEEDMOD "PAI_SPACEWALK_MODIFIER"
|
||||
#define MOVESPEED_ID_PAI_SPACEWALK_SPEEDMOD "PAI_SPACEWALK_MODIFIER"
|
||||
|
||||
#define MOVESPEED_ID_SANITY "MOOD_SANITY"
|
||||
|
||||
#define MOVESPEED_ID_PRONE_DRAGGING "PRONE_DRAG"
|
||||
#define MOVESPEED_ID_HUMAN_CARRYING "HUMAN_CARRY"
|
||||
|
||||
#define MOVESPEED_ID_TASED_STATUS "TASED"
|
||||
@@ -10,6 +10,7 @@
|
||||
#define UNIQUE_RENAME (1<<6) // can you customize the description/name of the thing?
|
||||
#define USES_TGUI (1<<7) //put on things that use tgui on ui_interact instead of custom/old UI.
|
||||
#define FROZEN (1<<8)
|
||||
#define SHOVABLE_ONTO (1<<9) //called on turf.shove_act() to consider whether an object should have a niche effect (defined in their own shove_act()) when someone is pushed onto it, or do a sanity CanPass() check.
|
||||
|
||||
// If you add new ones, be sure to add them to /obj/Initialize as well for complete mapping support
|
||||
|
||||
@@ -33,8 +34,17 @@
|
||||
#define LAVAPROTECT (1<<0)
|
||||
#define STOPSPRESSUREDAMAGE (1<<1) //SUIT and HEAD items which stop pressure damage. To stop you taking all pressure damage you must have both a suit and head item with this flag.
|
||||
#define BLOCK_GAS_SMOKE_EFFECT (1<<2) // blocks the effect that chemical clouds would have on a mob --glasses, mask and helmets ONLY!
|
||||
#define MASKINTERNALS (1<<3) // mask allows internals
|
||||
#define ALLOWINTERNALS (1<<3) // mask allows internals
|
||||
#define NOSLIP (1<<4) //prevents from slipping on wet floors, in space etc
|
||||
#define THICKMATERIAL (1<<5) //prevents syringes, parapens and hypos if the external suit or helmet (if targeting head) has this flag. Example: space suits, biosuit, bombsuits, thick suits that cover your body.
|
||||
#define VOICEBOX_TOGGLABLE (1<<6) // The voicebox in this clothing can be toggled.
|
||||
#define VOICEBOX_DISABLED (1<<7) // The voicebox is currently turned off.
|
||||
|
||||
// Flags for the organ_flags var on /obj/item/organ
|
||||
|
||||
#define ORGAN_SYNTHETIC (1<<0) //Synthetic organs, or cybernetic organs. Reacts to EMPs and don't deteriorate or heal
|
||||
#define ORGAN_FROZEN (1<<1) //Frozen organs, don't deteriorate
|
||||
#define ORGAN_FAILING (1<<2) //Failing organs perform damaging effects until replaced or fixed
|
||||
#define ORGAN_EXTERNAL (1<<3) //Was this organ implanted/inserted/etc, if true will not be removed during species change.
|
||||
#define ORGAN_VITAL (1<<4) //Currently only the brain
|
||||
#define ORGAN_NO_SPOIL (1<<5) //Do not spoil under any circumstances
|
||||
|
||||
@@ -69,4 +69,9 @@
|
||||
//Flags in the players table in the db
|
||||
#define DB_FLAG_EXEMPT 1
|
||||
|
||||
#define DEFAULT_CYBORG_NAME "Default Cyborg Name"
|
||||
#define DEFAULT_CYBORG_NAME "Default Cyborg Name"
|
||||
|
||||
//Job preferences levels
|
||||
#define JP_LOW 1
|
||||
#define JP_MEDIUM 2
|
||||
#define JP_HIGH 3
|
||||
|
||||
+12
-38
@@ -25,46 +25,20 @@
|
||||
#define NOBLIUM_FORMATION_ENERGY 2e9 //1 Mole of Noblium takes the planck energy to condense.
|
||||
//Research point amounts
|
||||
#define NOBLIUM_RESEARCH_AMOUNT 1000
|
||||
#define BZ_RESEARCH_AMOUNT 150
|
||||
#define BZ_RESEARCH_SCALE 4
|
||||
#define BZ_RESEARCH_MAX_AMOUNT 400
|
||||
#define MIASMA_RESEARCH_AMOUNT 160
|
||||
#define STIMULUM_RESEARCH_AMOUNT 50
|
||||
//Plasma fusion properties
|
||||
#define FUSION_ENERGY_THRESHOLD 3e9 //Amount of energy it takes to start a fusion reaction
|
||||
#define FUSION_TEMPERATURE_THRESHOLD 1000 //Temperature required to start a fusion reaction
|
||||
#define FUSION_MOLE_THRESHOLD 250 //Mole count required (tritium/plasma) to start a fusion reaction
|
||||
#define FUSION_RELEASE_ENERGY_SUPER 3e9 //Amount of energy released in the fusion process, super tier
|
||||
#define FUSION_RELEASE_ENERGY_HIGH 1e9 //Amount of energy released in the fusion process, high tier
|
||||
#define FUSION_RELEASE_ENERGY_MID 5e8 //Amount of energy released in the fusion process, mid tier
|
||||
#define FUSION_RELEASE_ENERGY_LOW 1e8 //Amount of energy released in the fusion process, low tier
|
||||
#define FUSION_MEDIATION_FACTOR 80 //Arbitrary
|
||||
#define FUSION_SUPER_TIER_THRESHOLD 50 //anything above this is super tier
|
||||
#define FUSION_HIGH_TIER_THRESHOLD 20 //anything above this and below 50 is high tier
|
||||
#define FUSION_MID_TIER_THRESHOLD 5 //anything above this and below 20 is mid tier - below this is low tier, but that doesnt need a define
|
||||
#define FUSION_ENERGY_DIVISOR_SUPER 25 //power_ratio is divided by this during energy calculations
|
||||
#define FUSION_ENERGY_DIVISOR_HIGH 20
|
||||
#define FUSION_ENERGY_DIVISOR_MID 10
|
||||
#define FUSION_ENERGY_DIVISOR_LOW 2
|
||||
#define FUSION_GAS_CREATION_FACTOR_TRITIUM 0.40 //trit - one gas rather than two, so think about that when calculating stuff - 40% in total
|
||||
#define FUSION_GAS_CREATION_FACTOR_STIM 0.05 //stim percentage creation from high tier - 5%, 60% in total with pluox
|
||||
#define FUSION_GAS_CREATION_FACTOR_PLUOX 0.55 //pluox percentage creation from high tier - 55%, 60% in total with stim
|
||||
#define FUSION_GAS_CREATION_FACTOR_NITRYL 0.20 //nitryl and N2O - 80% in total
|
||||
#define FUSION_GAS_CREATION_FACTOR_N2O 0.60 //nitryl and N2O - 80% in total
|
||||
#define FUSION_GAS_CREATION_FACTOR_BZ 0.05 //BZ - 5% - 90% in total with CO2
|
||||
#define FUSION_GAS_CREATION_FACTOR_CO2 0.85 //CO2 - 85% - 90% in total with BZ
|
||||
#define FUSION_MID_TIER_RAD_PROB_FACTOR 2 //probability of radpulse is power ratio * this for whatever tier
|
||||
#define FUSION_LOW_TIER_RAD_PROB_FACTOR 5
|
||||
#define FUSION_EFFICIENCY_BASE 60 //used in the fusion efficiency calculations
|
||||
#define FUSION_EFFICIENCY_DIVISOR 0.6 //ditto
|
||||
#define FUSION_RADIATION_FACTOR 15000 //horizontal asymptote
|
||||
#define FUSION_RADIATION_CONSTANT 30 //equation is form of (ax) / (x + b), where a = radiation factor and b = radiation constant and x = power ratio (https://www.desmos.com/calculator/4i1f296phl)
|
||||
#define FUSION_ZAP_POWER_ASYMPTOTE 50000 //maximum value - not enough to instacrit but it'll still hurt like shit
|
||||
#define FUSION_ZAP_POWER_CONSTANT 75 //equation is of from [ax / (x + b)] + c, where a = zap power asymptote, b = zap power constant, c = zap power base and x = power ratio
|
||||
#define FUSION_ZAP_POWER_BASE 1000 //(https://www.desmos.com/calculator/vvbmhf4unm)
|
||||
#define FUSION_ZAP_RANGE_SUPER 9 //range of the tesla zaps that occur from fusion
|
||||
#define FUSION_ZAP_RANGE_HIGH 7
|
||||
#define FUSION_ZAP_RANGE_MID 5
|
||||
#define FUSION_ZAP_RANGE_LOW 3
|
||||
#define FUSION_PARTICLE_FACTOR_SUPER 4 //# of particles fired out is equal to rand(3,6) * this for whatever tier
|
||||
#define FUSION_PARTICLE_FACTOR_HIGH 3
|
||||
#define FUSION_PARTICLE_FACTOR_MID 2
|
||||
#define FUSION_PARTICLE_FACTOR_LOW 1
|
||||
#define FUSION_TRITIUM_CONVERSION_COEFFICIENT (1e-10)
|
||||
#define INSTABILITY_GAS_POWER_FACTOR 0.003
|
||||
#define FUSION_TRITIUM_MOLES_USED 1
|
||||
#define PLASMA_BINDING_ENERGY 20000000
|
||||
#define TOROID_VOLUME_BREAKEVEN 1000
|
||||
#define FUSION_TEMPERATURE_THRESHOLD 10000
|
||||
#define PARTICLE_CHANCE_CONSTANT (-20000000)
|
||||
#define FUSION_RAD_MAX 2000
|
||||
#define FUSION_RAD_COEFFICIENT (-1000)
|
||||
#define FUSION_INSTABILITY_ENDOTHERMALITY 2
|
||||
|
||||
@@ -2,7 +2,13 @@
|
||||
#define LIQUID 2
|
||||
#define GAS 3
|
||||
|
||||
// reagents_flags defines
|
||||
//reagents reaction var defines
|
||||
#define REAGENT_NORMAL_PH 7.000
|
||||
#define REAGENT_PH_ACCURACY 0.001
|
||||
#define REAGENT_PURITY_ACCURACY 0.001
|
||||
#define DEFAULT_SPECIFIC_HEAT 200
|
||||
|
||||
// container_type defines
|
||||
#define INJECTABLE (1<<0) // Makes it possible to add reagents through droppers and syringes.
|
||||
#define DRAWABLE (1<<1) // Makes it possible to remove reagents through syringes.
|
||||
|
||||
@@ -28,3 +34,17 @@
|
||||
#define DEL_REAGENT 1 // reagent deleted (fully cleared)
|
||||
#define ADD_REAGENT 2 // reagent added
|
||||
#define REM_REAGENT 3 // reagent removed (may still exist)
|
||||
|
||||
//reagent bitflags, used for altering how they works
|
||||
#define REAGENT_DEAD_PROCESS (1<<0) //calls on_mob_dead() if present in a dead body
|
||||
#define REAGENT_DONOTSPLIT (1<<1) //Do not split the chem at all during processing
|
||||
#define REAGENT_ONLYINVERSE (1<<2) //Only invert chem, no splitting
|
||||
#define REAGENT_ONMOBMERGE (1<<3) //Call on_mob_life proc when reagents are merging.
|
||||
#define REAGENT_INVISIBLE (1<<4) //Doesn't appear on handheld health analyzers.
|
||||
#define REAGENT_FORCEONNEW (1<<5) //Forces a on_new() call without a data overhead
|
||||
#define REAGENT_SNEAKYNAME (1<<6) //When inverted, the inverted chem uses the name of the original chem
|
||||
#define REAGENT_SPLITRETAINVOL (1<<7) //Retains initial volume of chem when splitting
|
||||
|
||||
//Chemical reaction flags, for determining reaction specialties
|
||||
#define REACTION_CLEAR_IMPURE (1<<0) //Convert into impure/pure on reaction completion
|
||||
#define REACTION_CLEAR_INVERSE (1<<1) //Convert into inverse on reaction completion when purity is low enough
|
||||
|
||||
@@ -50,3 +50,7 @@
|
||||
#define ASSEMBLY_THIRD_STEP 2
|
||||
#define ASSEMBLY_FOURTH_STEP 3
|
||||
#define ASSEMBLY_FIFTH_STEP 4
|
||||
|
||||
|
||||
//Checks to determine borg availability depending on the server's config. These are defines in the interest of reducing copypasta
|
||||
#define BORG_SEC_AVAILABLE (!CONFIG_GET(flag/disable_secborg) && GLOB.security_level >= CONFIG_GET(number/minimum_secborg_alert))
|
||||
@@ -8,6 +8,9 @@
|
||||
#define UNCONSCIOUS 2
|
||||
#define DEAD 3
|
||||
|
||||
//Maximum healthiness an individual can have
|
||||
#define MAX_SATIETY 600
|
||||
|
||||
// bitflags for machine stat variable
|
||||
#define BROKEN (1<<0)
|
||||
#define NOPOWER (1<<1)
|
||||
|
||||
@@ -44,6 +44,10 @@
|
||||
|
||||
#define STATUS_EFFECT_SLEEPING /datum/status_effect/incapacitating/sleeping //the affected is asleep
|
||||
|
||||
#define STATUS_EFFECT_TASED /datum/status_effect/electrode //the affected has been tased, preventing fine muscle control
|
||||
|
||||
#define STATUS_EFFECT_PACIFY /datum/status_effect/pacify //the affected is pacified, preventing direct hostile actions
|
||||
|
||||
#define STATUS_EFFECT_BELLIGERENT /datum/status_effect/belligerent //forces the affected to walk, doing damage if they try to run
|
||||
|
||||
#define STATUS_EFFECT_GEISTRACKER /datum/status_effect/geis_tracker //if you're using geis, this tracks that and keeps you from using scripture
|
||||
|
||||
@@ -83,7 +83,9 @@
|
||||
#define INIT_ORDER_SHUTTLE -21
|
||||
#define INIT_ORDER_MINOR_MAPPING -40
|
||||
#define INIT_ORDER_PATH -50
|
||||
#define INIT_ORDER_PERSISTENCE -100
|
||||
#define INIT_ORDER_PERSISTENCE -95
|
||||
#define INIT_ORDER_CHAT -100 //Should be last to ensure chat remains smooth during init.
|
||||
|
||||
|
||||
// Subsystem fire priority, from lowest to highest priority
|
||||
// If the subsystem isn't listed here it's either DEFAULT or PROCESS (if it's a processing subsystem child)
|
||||
@@ -93,6 +95,7 @@
|
||||
#define FIRE_PRIORITY_SERVER_MAINT 10
|
||||
#define FIRE_PRIORITY_RESEARCH 10
|
||||
#define FIRE_PRIORITY_VIS 10
|
||||
#define FIRE_PRIORITY_VORE 10
|
||||
#define FIRE_PRIORITY_GARBAGE 15
|
||||
#define FIRE_PRIORITY_WET_FLOORS 20
|
||||
#define FIRE_PRIORITY_AIR 20
|
||||
@@ -113,6 +116,7 @@
|
||||
#define FIRE_PRIORITY_MOBS 100
|
||||
#define FIRE_PRIORITY_TGUI 110
|
||||
#define FIRE_PRIORITY_TICKER 200
|
||||
#define FIRE_PRIORITY_CHAT 400
|
||||
#define FIRE_PRIORITY_OVERLAYS 500
|
||||
#define FIRE_PRIORITY_INPUT 1000 // This must always always be the max highest priority. Player input must never be lost.
|
||||
|
||||
|
||||
@@ -31,4 +31,4 @@ When using time2text(), please use "DDD" to find the weekday. Refrain from using
|
||||
#define WORLDTIMEOFDAY2TEXT(format) GAMETIMESTAMP(format, world.timeofday)
|
||||
#define TIME_STAMP(format, showds) showds ? "[WORLDTIMEOFDAY2TEXT(format)]:[world.timeofday % 10]" : WORLDTIMEOFDAY2TEXT(format)
|
||||
#define STATION_TIME(display_only) ((((world.time - SSticker.round_start_time) * SSticker.station_time_rate_multiplier) + SSticker.gametime_offset) % 864000) - (display_only? GLOB.timezoneOffset : 0)
|
||||
#define STATION_TIME_TIMESTAMP(format) time2text(STATION_TIME(TRUE), format)
|
||||
#define STATION_TIME_TIMESTAMP(format) time2text(STATION_TIME(TRUE), format)
|
||||
|
||||
@@ -8,6 +8,12 @@
|
||||
#define TOOL_ANALYZER "analyzer"
|
||||
#define TOOL_MINING "mining"
|
||||
#define TOOL_SHOVEL "shovel"
|
||||
#define TOOL_RETRACTOR "retractor"
|
||||
#define TOOL_HEMOSTAT "hemostat"
|
||||
#define TOOL_CAUTERY "cautery"
|
||||
#define TOOL_DRILL "drill"
|
||||
#define TOOL_SCALPEL "scalpel"
|
||||
#define TOOL_SAW "saw"
|
||||
|
||||
|
||||
// If delay between the start and the end of tool operation is less than MIN_TOOL_SOUND_DELAY,
|
||||
|
||||
@@ -81,6 +81,7 @@
|
||||
#define TRAIT_PUSHIMMUNE "push_immunity"
|
||||
#define TRAIT_SHOCKIMMUNE "shock_immunity"
|
||||
#define TRAIT_STABLEHEART "stable_heart"
|
||||
#define TRAIT_STABLELIVER "stable_liver"
|
||||
#define TRAIT_RESISTHEAT "resist_heat"
|
||||
#define TRAIT_RESISTHEATHANDS "resist_heat_handsonly" //For when you want to be able to touch hot things, but still want fire to be an issue.
|
||||
#define TRAIT_RESISTCOLD "resist_cold"
|
||||
@@ -95,6 +96,8 @@
|
||||
#define TRAIT_NOHUNGER "no_hunger"
|
||||
#define TRAIT_EASYDISMEMBER "easy_dismember"
|
||||
#define TRAIT_LIMBATTACHMENT "limb_attach"
|
||||
#define TRAIT_NOLIMBDISABLE "no_limb_disable"
|
||||
#define TRAIT_EASYLIMBDISABLE "easy_limb_disable"
|
||||
#define TRAIT_TOXINLOVER "toxinlover"
|
||||
#define TRAIT_NOBREATH "no_breath"
|
||||
#define TRAIT_ANTIMAGIC "anti_magic"
|
||||
@@ -108,6 +111,9 @@
|
||||
#define TRAIT_NOHARDCRIT "nohardcrit"
|
||||
#define TRAIT_NOSOFTCRIT "nosoftcrit"
|
||||
#define TRAIT_MINDSHIELD "mindshield"
|
||||
#define TRAIT_DISSECTED "dissected"
|
||||
#define TRAIT_FEARLESS "fearless"
|
||||
#define TRAIT_UNSTABLE "unstable"
|
||||
#define TRAIT_PARALYSIS_L_ARM "para-l-arm" //These are used for brain-based paralysis, where replacing the limb won't fix it
|
||||
#define TRAIT_PARALYSIS_R_ARM "para-r-arm"
|
||||
#define TRAIT_PARALYSIS_L_LEG "para-l-leg"
|
||||
@@ -116,6 +122,10 @@
|
||||
#define TRAIT_LAW_ENFORCEMENT_METABOLISM "law-enforcement-metabolism"
|
||||
#define TRAIT_STRONG_GRABBER "strong_grabber"
|
||||
#define TRAIT_CALCIUM_HEALER "calcium_healer"
|
||||
#define TRAIT_CAPTAIN_METABOLISM "captain-metabolism"
|
||||
#define TRAIT_ABDUCTOR_TRAINING "abductor-training"
|
||||
#define TRAIT_ABDUCTOR_SCIENTIST_TRAINING "abductor-scientist-training"
|
||||
#define TRAIT_SURGEON "surgeon"
|
||||
|
||||
//non-mob traits
|
||||
#define TRAIT_PARALYSIS "paralysis" //Used for limb-based paralysis, where replacing the limb will fix it
|
||||
@@ -128,6 +138,7 @@
|
||||
#define TRAIT_HEAVY_SLEEPER "heavy_sleeper"
|
||||
#define TRAIT_NIGHT_VISION "night_vision"
|
||||
#define TRAIT_LIGHT_STEP "light_step"
|
||||
#define TRAIT_SILENT_STEP "silent_step"
|
||||
#define TRAIT_SPEEDY_STEP "speedy_step"
|
||||
#define TRAIT_SPIRITUAL "spiritual"
|
||||
#define TRAIT_VORACIOUS "voracious"
|
||||
@@ -143,12 +154,15 @@
|
||||
#define TRAIT_CROCRIN_IMMUNE "crocin_immune"
|
||||
#define TRAIT_NYMPHO "nymphomania"
|
||||
#define TRAIT_MASO "masochism"
|
||||
#define TRAIT_HIGH_BLOOD "high_blood"
|
||||
#define TRAIT_PHARMA "hepatic_pharmacokinesis"
|
||||
#define TRAIT_PARA "paraplegic"
|
||||
#define TRAIT_EMPATH "empath"
|
||||
#define TRAIT_FRIENDLY "friendly"
|
||||
#define TRAIT_ASSBLASTUSA "assblastusa"
|
||||
#define TRAIT_CULT_EYES "cult_eyes"
|
||||
|
||||
|
||||
// common trait sources
|
||||
#define TRAIT_GENERIC "generic"
|
||||
#define EYE_DAMAGE "eye_damage"
|
||||
@@ -156,6 +170,7 @@
|
||||
#define OBESITY "obesity"
|
||||
#define MAGIC_TRAIT "magic"
|
||||
#define TRAUMA_TRAIT "trauma"
|
||||
#define DISEASE_TRAIT "disease"
|
||||
#define SPECIES_TRAIT "species"
|
||||
#define ORGAN_TRAIT "organ"
|
||||
#define JOB_TRAIT "job"
|
||||
@@ -169,6 +184,7 @@
|
||||
|
||||
// unique trait sources, still defines
|
||||
#define STATUE_MUTE "statue"
|
||||
#define CLONING_POD_TRAIT "cloning-pod"
|
||||
#define CHANGELING_DRAIN "drain"
|
||||
#define CHANGELING_HIVEMIND_MUTE "ling_mute"
|
||||
#define ABYSSAL_GAZE_BLIND "abyssal_gaze"
|
||||
@@ -197,4 +213,5 @@
|
||||
#define FLIGHTSUIT_TRAIT "flightsuit"
|
||||
#define LOCKED_HELMET_TRAIT "locked-helmet"
|
||||
#define NINJA_SUIT_TRAIT "ninja-suit"
|
||||
#define ANTI_DROP_IMPLANT_TRAIT "anti-drop-implant"
|
||||
#define ANTI_DROP_IMPLANT_TRAIT "anti-drop-implant"
|
||||
#define ABDUCTOR_ANTAGONIST "abductor-antagonist"
|
||||
@@ -20,7 +20,7 @@ GLOBAL_LIST_INIT(player_sizes_list, list("Macro" = SIZESCALE_HUGE, "Big" = SIZES
|
||||
// Edited to make the new travis check go away
|
||||
*/
|
||||
|
||||
GLOBAL_LIST_INIT(vore_sounds, list(
|
||||
GLOBAL_LIST_INIT(pred_vore_sounds, list(
|
||||
"Gulp" = 'sound/vore/pred/swallow_01.ogg',
|
||||
"Swallow" = 'sound/vore/pred/swallow_02.ogg',
|
||||
"Insertion1" = 'sound/vore/pred/insertion_01.ogg',
|
||||
@@ -40,7 +40,27 @@ GLOBAL_LIST_INIT(vore_sounds, list(
|
||||
"None" = null
|
||||
))
|
||||
|
||||
GLOBAL_LIST_INIT(release_sounds, list(
|
||||
GLOBAL_LIST_INIT(prey_vore_sounds, list(
|
||||
"Gulp" = 'sound/vore/prey/swallow_01.ogg',
|
||||
"Swallow" = 'sound/vore/prey/swallow_02.ogg',
|
||||
"Insertion1" = 'sound/vore/prey/insertion_01.ogg',
|
||||
"Insertion2" = 'sound/vore/prey/insertion_02.ogg',
|
||||
"Tauric Swallow" = 'sound/vore/prey/taurswallow.ogg',
|
||||
"Stomach Move" = 'sound/vore/prey/stomachmove.ogg',
|
||||
"Schlorp" = 'sound/vore/prey/schlorp.ogg',
|
||||
"Squish1" = 'sound/vore/prey/squish_01.ogg',
|
||||
"Squish2" = 'sound/vore/prey/squish_02.ogg',
|
||||
"Squish3" = 'sound/vore/prey/squish_03.ogg',
|
||||
"Squish4" = 'sound/vore/prey/squish_04.ogg',
|
||||
"Rustle (cloth)" = 'sound/effects/rustle5.ogg',
|
||||
"Rustle 2 (cloth)" = 'sound/effects/rustle2.ogg',
|
||||
"Rustle 3 (cloth)" = 'sound/effects/rustle3.ogg',
|
||||
"Rustle 4 (cloth)" = 'sound/effects/rustle4.ogg',
|
||||
"Rustle 5 (cloth)" = 'sound/effects/rustle5.ogg',
|
||||
"None" = null
|
||||
))
|
||||
|
||||
GLOBAL_LIST_INIT(pred_release_sounds, list(
|
||||
"Rustle (cloth)" = 'sound/effects/rustle1.ogg',
|
||||
"Rustle 2 (cloth)" = 'sound/effects/rustle2.ogg',
|
||||
"Rustle 3 (cloth)" = 'sound/effects/rustle3.ogg',
|
||||
@@ -51,3 +71,15 @@ GLOBAL_LIST_INIT(release_sounds, list(
|
||||
"Splatter" = 'sound/effects/splat.ogg',
|
||||
"None" = null
|
||||
))
|
||||
|
||||
GLOBAL_LIST_INIT(prey_release_sounds, list(
|
||||
"Rustle (cloth)" = 'sound/effects/rustle1.ogg',
|
||||
"Rustle 2 (cloth)" = 'sound/effects/rustle2.ogg',
|
||||
"Rustle 3 (cloth)" = 'sound/effects/rustle3.ogg',
|
||||
"Rustle 4 (cloth)" = 'sound/effects/rustle4.ogg',
|
||||
"Rustle 5 (cloth)" = 'sound/effects/rustle5.ogg',
|
||||
"Stomach Move" = 'sound/vore/prey/stomachmove.ogg',
|
||||
"Pred Escape" = 'sound/vore/prey/escape.ogg',
|
||||
"Splatter" = 'sound/effects/splat.ogg',
|
||||
"None" = null
|
||||
))
|
||||
|
||||
@@ -58,6 +58,7 @@ GLOBAL_LIST_EMPTY(ipc_antennas_list)
|
||||
//Genitals and Arousal Lists
|
||||
GLOBAL_LIST_EMPTY(cock_shapes_list)//global_lists.dm for the list initializations //Now also _DATASTRUCTURES globals.dm
|
||||
GLOBAL_LIST_EMPTY(cock_shapes_icons) //Associated list for names->icon_states for cockshapes.
|
||||
GLOBAL_LIST_EMPTY(gentlemans_organ_names)
|
||||
GLOBAL_LIST_EMPTY(balls_shapes_list)
|
||||
GLOBAL_LIST_EMPTY(balls_shapes_icons)
|
||||
GLOBAL_LIST_EMPTY(breasts_size_list)
|
||||
@@ -93,6 +94,12 @@ GLOBAL_LIST_INIT(dildo_colors, list(//mostly neon colors
|
||||
"Purple" = "#e300ff"//purple
|
||||
))
|
||||
|
||||
GLOBAL_LIST_INIT(meat_types, list(
|
||||
"Mammalian" = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/mammal,
|
||||
"Aquatic" = /obj/item/reagent_containers/food/snacks/carpmeat/aquatic,
|
||||
"Avian" = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/avian,
|
||||
"Inesct" = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/insect))
|
||||
|
||||
//Crew objective and miscreants stuff
|
||||
GLOBAL_VAR_INIT(miscreants_allowed, FALSE)
|
||||
|
||||
|
||||
@@ -58,6 +58,10 @@
|
||||
if (CONFIG_GET(flag/log_game))
|
||||
WRITE_LOG(GLOB.world_game_log, "GAME: [text]")
|
||||
|
||||
/proc/log_virus(text)
|
||||
if (CONFIG_GET(flag/log_virus))
|
||||
WRITE_LOG(GLOB.world_virus_log, "VIRUS: [text]")
|
||||
|
||||
/proc/log_access(text)
|
||||
if (CONFIG_GET(flag/log_access))
|
||||
WRITE_LOG(GLOB.world_game_log, "ACCESS: [text]")
|
||||
|
||||
@@ -81,3 +81,6 @@ GLOBAL_VAR_INIT(cmp_field, "name")
|
||||
|
||||
/proc/cmp_advdisease_resistance_asc(datum/disease/advance/A, datum/disease/advance/B)
|
||||
return A.totalResistance() - B.totalResistance()
|
||||
|
||||
/proc/cmp_job_display_asc(datum/job/A, datum/job/B)
|
||||
return A.display_order - B.display_order
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
Current specifications:
|
||||
|
||||
Donator groups in __DEFINES/donator_groupings.dm, config entries in controllers/configuration/entries/donator.dm
|
||||
|
||||
3 groups, Tier 1/2/3
|
||||
Each tier includes the one before it (ascending)
|
||||
For fast lookups, this is generated using regenerate_donator_grouping_list()
|
||||
|
||||
*/
|
||||
|
||||
/proc/is_donator_group(ckey, group)
|
||||
ckey = ckey(ckey) //make sure it's ckey'd.
|
||||
var/list/L = GLOB.donators_by_group[group]
|
||||
return L && L.Find(ckey)
|
||||
|
||||
/proc/regenerate_donator_grouping_list()
|
||||
GLOB.donators_by_group = list() //reinit everything
|
||||
var/list/donator_list = GLOB.donators_by_group //cache
|
||||
var/list/tier_1 = TIER_1_DONATORS
|
||||
donator_list[DONATOR_GROUP_TIER_1] = tier_1.Copy() //The .Copy() is to "decouple"/make a new list, rather than letting the global list impact the config list.
|
||||
var/list/tier_2 = tier_1 + TIER_2_DONATORS //Using + on lists implies making new lists, so we don't need to manually Copy().
|
||||
donator_list[DONATOR_GROUP_TIER_2] = tier_2
|
||||
var/list/tier_3 = tier_2 + TIER_3_DONATORS
|
||||
donator_list[DONATOR_GROUP_TIER_3] = tier_3
|
||||
@@ -3,7 +3,7 @@
|
||||
for(var/file in args)
|
||||
src << browse_rsc(file)
|
||||
|
||||
/client/proc/browse_files(root="data/logs/", max_iterations=10, list/valid_extensions=list("txt","log","htm", "html"))
|
||||
/client/proc/browse_files(root="data/logs/", max_iterations=10, list/valid_extensions=list("txt","log","htm", "html", "md"))
|
||||
var/path = root
|
||||
|
||||
for(var/i=0, i<max_iterations, i++)
|
||||
|
||||
+39
-1
@@ -159,6 +159,44 @@
|
||||
processing_list.Cut(1, 2)
|
||||
processing_list += A.contents
|
||||
|
||||
/** recursive_organ_check
|
||||
* inputs: O (object to start with)
|
||||
* outputs:
|
||||
* description: A pseudo-recursive loop based off of the recursive mob check, this check looks for any organs held
|
||||
* within 'O', toggling their frozen flag. This check excludes items held within other safe organ
|
||||
* storage units, so that only the lowest level of container dictates whether we do or don't decompose
|
||||
*/
|
||||
/proc/recursive_organ_check(atom/O)
|
||||
|
||||
var/list/processing_list = list(O)
|
||||
var/list/processed_list = list()
|
||||
var/index = 1
|
||||
var/obj/item/organ/found_organ
|
||||
|
||||
while(index <= length(processing_list))
|
||||
|
||||
var/atom/A = processing_list[index]
|
||||
|
||||
if(istype(A, /obj/item/organ))
|
||||
found_organ = A
|
||||
found_organ.organ_flags ^= ORGAN_FROZEN
|
||||
|
||||
else if(istype(A, /mob/living/carbon))
|
||||
var/mob/living/carbon/Q = A
|
||||
for(var/organ in Q.internal_organs)
|
||||
found_organ = organ
|
||||
found_organ.organ_flags ^= ORGAN_FROZEN
|
||||
|
||||
for(var/atom/B in A) //objects held within other objects are added to the processing list, unless that object is something that can hold organs safely
|
||||
if(!processed_list[B] && !istype(B, /obj/structure/closet/crate/freezer) && !istype(B, /obj/structure/closet/secure_closet/freezer))
|
||||
processing_list+= B
|
||||
|
||||
index++
|
||||
processed_list[A] = A
|
||||
|
||||
return
|
||||
|
||||
|
||||
// Better recursive loop, technically sort of not actually recursive cause that shit is retarded, enjoy.
|
||||
//No need for a recursive limit either
|
||||
/proc/recursive_mob_check(atom/O,client_check=1,sight_check=1,include_radio=1)
|
||||
@@ -473,7 +511,7 @@
|
||||
|
||||
G_found.client.prefs.copy_to(new_character)
|
||||
new_character.dna.update_dna_identity()
|
||||
new_character.key = G_found.key
|
||||
G_found.transfer_ckey(new_character, FALSE)
|
||||
|
||||
return new_character
|
||||
|
||||
|
||||
@@ -30,7 +30,9 @@
|
||||
init_sprite_accessory_subtypes(/datum/sprite_accessory/legs, GLOB.legs_list)
|
||||
init_sprite_accessory_subtypes(/datum/sprite_accessory/wings, GLOB.r_wings_list,roundstart = TRUE)
|
||||
init_sprite_accessory_subtypes(/datum/sprite_accessory/caps, GLOB.caps_list)
|
||||
init_sprite_accessory_subtypes(/datum/sprite_accessory/moth_wings, GLOB.moth_wings_list)
|
||||
init_sprite_accessory_subtypes(/datum/sprite_accessory/insect_wings, GLOB.insect_wings_list)
|
||||
init_sprite_accessory_subtypes(/datum/sprite_accessory/insect_fluff, GLOB.insect_fluffs_list)
|
||||
init_sprite_accessory_subtypes(/datum/sprite_accessory/deco_wings, GLOB.deco_wings_list)
|
||||
|
||||
//CIT CHANGES START HERE, ADDS SNOWFLAKE BODYPARTS AND MORE
|
||||
//mammal bodyparts (fucking furries)
|
||||
@@ -44,6 +46,9 @@
|
||||
init_sprite_accessory_subtypes(/datum/sprite_accessory/xeno_head, GLOB.xeno_head_list)
|
||||
init_sprite_accessory_subtypes(/datum/sprite_accessory/xeno_tail, GLOB.xeno_tail_list)
|
||||
init_sprite_accessory_subtypes(/datum/sprite_accessory/xeno_dorsal, GLOB.xeno_dorsal_list)
|
||||
//ipcs
|
||||
init_sprite_accessory_subtypes(/datum/sprite_accessory/screen, GLOB.ipc_screens_list, roundstart = TRUE)
|
||||
init_sprite_accessory_subtypes(/datum/sprite_accessory/antenna, GLOB.ipc_antennas_list, roundstart = TRUE)
|
||||
//genitals
|
||||
init_sprite_accessory_subtypes(/datum/sprite_accessory/penis, GLOB.cock_shapes_list)
|
||||
for(var/K in GLOB.cock_shapes_list)
|
||||
@@ -52,7 +57,12 @@
|
||||
|
||||
init_sprite_accessory_subtypes(/datum/sprite_accessory/vagina, GLOB.vagina_shapes_list)
|
||||
init_sprite_accessory_subtypes(/datum/sprite_accessory/breasts, GLOB.breasts_shapes_list)
|
||||
GLOB.breasts_size_list = list("a","b","c","d","e") //We need the list to choose from initialized, but it's no longer a sprite_accessory thing.
|
||||
GLOB.breasts_size_list = list ("a", "b", "c", "d", "e") //We need the list to choose from initialized, but it's no longer a sprite_accessory thing.
|
||||
GLOB.gentlemans_organ_names = list("phallus", "willy", "dick", "prick", "member", "tool", "gentleman's organ",
|
||||
"cock", "wang", "knob", "dong", "joystick", "pecker", "johnson", "weenie", "tadger", "schlong", "thirsty ferret",
|
||||
"baloney pony", "schlanger", "Mutton dagger", "old blind bob","Hanging Johnny", "fishing rod", "Tally whacker", "polly rocket",
|
||||
"One eyed trouser trout", "Ding dong", "ankle spanker", "Pork sword", "engine cranker", "Harry hot dog", "Davy Crockett",
|
||||
"Kidney cracker", "Heat seeking moisture missile", "Giggle stick", "love whistle", "Tube steak", "Uncle Dick", "Purple helmet warrior")
|
||||
for(var/K in GLOB.breasts_shapes_list)
|
||||
var/datum/sprite_accessory/breasts/value = GLOB.breasts_shapes_list[K]
|
||||
GLOB.breasts_shapes_icons[K] = value.icon_state
|
||||
@@ -61,6 +71,7 @@
|
||||
for(var/K in GLOB.balls_shapes_list)
|
||||
var/datum/sprite_accessory/testicles/value = GLOB.balls_shapes_list[K]
|
||||
GLOB.balls_shapes_icons[K] = value.icon_state
|
||||
|
||||
//END OF CIT CHANGES
|
||||
|
||||
//Species
|
||||
|
||||
+37
-22
@@ -59,7 +59,7 @@
|
||||
if(!GLOB.horns_list.len)
|
||||
init_sprite_accessory_subtypes(/datum/sprite_accessory/horns, GLOB.horns_list)
|
||||
if(!GLOB.ears_list.len)
|
||||
init_sprite_accessory_subtypes(/datum/sprite_accessory/ears, GLOB.horns_list)
|
||||
init_sprite_accessory_subtypes(/datum/sprite_accessory/ears, GLOB.ears_list)
|
||||
if(!GLOB.frills_list.len)
|
||||
init_sprite_accessory_subtypes(/datum/sprite_accessory/frills, GLOB.frills_list)
|
||||
if(!GLOB.spines_list.len)
|
||||
@@ -70,8 +70,12 @@
|
||||
init_sprite_accessory_subtypes(/datum/sprite_accessory/body_markings, GLOB.body_markings_list)
|
||||
if(!GLOB.wings_list.len)
|
||||
init_sprite_accessory_subtypes(/datum/sprite_accessory/wings, GLOB.wings_list)
|
||||
if(!GLOB.moth_wings_list.len)
|
||||
init_sprite_accessory_subtypes(/datum/sprite_accessory/moth_wings, GLOB.moth_wings_list)
|
||||
if(!GLOB.deco_wings_list.len)
|
||||
init_sprite_accessory_subtypes(/datum/sprite_accessory/deco_wings, GLOB.deco_wings_list)
|
||||
if(!GLOB.insect_wings_list.len)
|
||||
init_sprite_accessory_subtypes(/datum/sprite_accessory/insect_wings, GLOB.insect_wings_list)
|
||||
if(!GLOB.insect_fluffs_list.len)
|
||||
init_sprite_accessory_subtypes(/datum/sprite_accessory/insect_fluff, GLOB.insect_fluffs_list)
|
||||
|
||||
//CIT CHANGES - genitals and such
|
||||
if(!GLOB.cock_shapes_list.len)
|
||||
@@ -130,22 +134,24 @@
|
||||
|
||||
//CIT CHANGE - changes this entire return to support cit's snowflake parts
|
||||
return(list(
|
||||
"mcolor" = color1,
|
||||
"mcolor2" = color2,
|
||||
"mcolor3" = color3,
|
||||
"tail_lizard" = pick(GLOB.tails_list_lizard),
|
||||
"tail_human" = "None",
|
||||
"wings" = "None",
|
||||
"snout" = pick(GLOB.snouts_list),
|
||||
"horns" = pick(GLOB.horns_list),
|
||||
"ears" = "None",
|
||||
"frills" = pick(GLOB.frills_list),
|
||||
"spines" = pick(GLOB.spines_list),
|
||||
"body_markings" = pick(GLOB.body_markings_list),
|
||||
"legs" = pick("Normal Legs","Digitigrade Legs"),
|
||||
"caps" = pick(GLOB.caps_list),
|
||||
"moth_wings" = pick(GLOB.moth_wings_list),
|
||||
"taur" = "None",
|
||||
"mcolor" = color1,
|
||||
"mcolor2" = color2,
|
||||
"mcolor3" = color3,
|
||||
"tail_lizard" = pick(GLOB.tails_list_lizard),
|
||||
"tail_human" = "None",
|
||||
"wings" = "None",
|
||||
"deco_wings" = "None",
|
||||
"snout" = pick(GLOB.snouts_list),
|
||||
"horns" = pick(GLOB.horns_list),
|
||||
"ears" = "None",
|
||||
"frills" = pick(GLOB.frills_list),
|
||||
"spines" = pick(GLOB.spines_list),
|
||||
"body_markings" = pick(GLOB.body_markings_list),
|
||||
"legs" = pick("Plantigrade","Digitigrade"),
|
||||
"caps" = pick(GLOB.caps_list),
|
||||
"insect_wings" = pick(GLOB.insect_wings_list),
|
||||
"insect_fluff" = "None",
|
||||
"taur" = "None",
|
||||
"mam_body_markings" = pick(snowflake_markings_list),
|
||||
"mam_ears" = pick(snowflake_ears_list),
|
||||
"mam_snouts" = pick(snowflake_mam_snouts_list),
|
||||
@@ -189,6 +195,7 @@
|
||||
"breasts_size" = pick(GLOB.breasts_size_list),
|
||||
"breasts_shape" = "Pair",
|
||||
"breasts_fluid" = "milk",
|
||||
"breasts_producing" = FALSE,
|
||||
"has_vag" = FALSE,
|
||||
"vag_shape" = pick(GLOB.vagina_shapes_list),
|
||||
"vag_color" = pick("FFFFFF","7F7F7F", "7FFF7F", "7F7FFF", "FF7F7F", "7FFFFF", "FF7FFF", "FFFF7F"),
|
||||
@@ -200,9 +207,11 @@
|
||||
"womb_cum_mult" = CUM_RATE_MULT,
|
||||
"womb_efficiency" = CUM_EFFICIENCY,
|
||||
"womb_fluid" = "femcum",
|
||||
"ipc_screen" = "Sunburst",
|
||||
"ipc_antenna" = "None",
|
||||
"flavor_text" = ""))
|
||||
"ipc_screen" = "Sunburst",
|
||||
"ipc_antenna" = "None",
|
||||
"flavor_text" = "",
|
||||
"meat_type" = "Mammalian"
|
||||
))
|
||||
|
||||
/proc/random_hair_style(gender)
|
||||
switch(gender)
|
||||
@@ -391,6 +400,12 @@ GLOBAL_LIST_EMPTY(species_list)
|
||||
. = 0
|
||||
break
|
||||
|
||||
if(isliving(user))
|
||||
var/mob/living/L = user
|
||||
if(L.recoveringstam)
|
||||
. = 0
|
||||
break
|
||||
|
||||
if(!QDELETED(Tloc) && (QDELETED(target) || Tloc != target.loc))
|
||||
if((Uloc != Tloc || Tloc != user) && !drifting)
|
||||
. = 0
|
||||
|
||||
+18
-11
@@ -280,34 +280,41 @@
|
||||
if(GLOB.round_id)
|
||||
var/statspage = CONFIG_GET(string/roundstatsurl)
|
||||
var/info = statspage ? "<a href='?action=openLink&link=[url_encode(statspage)][GLOB.round_id]'>[GLOB.round_id]</a>" : GLOB.round_id
|
||||
parts += "[GLOB.TAB]Round ID: <b>[info]</b>"
|
||||
parts += "[FOURSPACES]Round ID: <b>[info]</b>"
|
||||
|
||||
var/list/voting_results = SSvote.stored_gamemode_votes
|
||||
|
||||
if(length(voting_results))
|
||||
parts += "[GLOB.TAB]Voting: "
|
||||
parts += "[FOURSPACES]Voting: "
|
||||
var/total_score = 0
|
||||
for(var/choice in voting_results)
|
||||
var/score = voting_results[choice]
|
||||
total_score += score
|
||||
parts += "[GLOB.TAB][GLOB.TAB][choice]: [score]"
|
||||
parts += "[FOURSPACES][FOURSPACES][choice]: [score]"
|
||||
|
||||
parts += "[GLOB.TAB]Shift Duration: <B>[DisplayTimeText(world.time - SSticker.round_start_time)]</B>"
|
||||
parts += "[GLOB.TAB]Station Integrity: <B>[mode.station_was_nuked ? "<span class='redtext'>Destroyed</span>" : "[popcount["station_integrity"]]%"]</B>"
|
||||
parts += "[FOURSPACES]Shift Duration: <B>[DisplayTimeText(world.time - SSticker.round_start_time)]</B>"
|
||||
parts += "[FOURSPACES]Station Integrity: <B>[mode.station_was_nuked ? "<span class='redtext'>Destroyed</span>" : "[popcount["station_integrity"]]%"]</B>"
|
||||
var/total_players = GLOB.joined_player_list.len
|
||||
if(total_players)
|
||||
parts+= "[GLOB.TAB]Total Population: <B>[total_players]</B>"
|
||||
parts+= "[FOURSPACES]Total Population: <B>[total_players]</B>"
|
||||
if(station_evacuated)
|
||||
parts += "<BR>[GLOB.TAB]Evacuation Rate: <B>[popcount[POPCOUNT_ESCAPEES]] ([PERCENT(popcount[POPCOUNT_ESCAPEES]/total_players)]%)</B>"
|
||||
parts += "[GLOB.TAB](on emergency shuttle): <B>[popcount[POPCOUNT_SHUTTLE_ESCAPEES]] ([PERCENT(popcount[POPCOUNT_SHUTTLE_ESCAPEES]/total_players)]%)</B>"
|
||||
parts += "[GLOB.TAB]Survival Rate: <B>[popcount[POPCOUNT_SURVIVORS]] ([PERCENT(popcount[POPCOUNT_SURVIVORS]/total_players)]%)</B>"
|
||||
parts += "<BR>[FOURSPACES]Evacuation Rate: <B>[popcount[POPCOUNT_ESCAPEES]] ([PERCENT(popcount[POPCOUNT_ESCAPEES]/total_players)]%)</B>"
|
||||
parts += "[FOURSPACES](on emergency shuttle): <B>[popcount[POPCOUNT_SHUTTLE_ESCAPEES]] ([PERCENT(popcount[POPCOUNT_SHUTTLE_ESCAPEES]/total_players)]%)</B>"
|
||||
parts += "[FOURSPACES]Survival Rate: <B>[popcount[POPCOUNT_SURVIVORS]] ([PERCENT(popcount[POPCOUNT_SURVIVORS]/total_players)]%)</B>"
|
||||
if(SSblackbox.first_death)
|
||||
var/list/ded = SSblackbox.first_death
|
||||
if(ded.len)
|
||||
parts += "[GLOB.TAB]First Death: <b>[ded["name"]], [ded["role"]], at [ded["area"]]. Damage taken: [ded["damage"]].[ded["last_words"] ? " Their last words were: \"[ded["last_words"]]\"" : ""]</b>"
|
||||
parts += "[FOURSPACES]First Death: <b>[ded["name"]], [ded["role"]], at [ded["area"]]. Damage taken: [ded["damage"]].[ded["last_words"] ? " Their last words were: \"[ded["last_words"]]\"" : ""]</b>"
|
||||
//ignore this comment, it fixes the broken sytax parsing caused by the " above
|
||||
else
|
||||
parts += "[GLOB.TAB]<i>Nobody died this shift!</i>"
|
||||
parts += "[FOURSPACES]<i>Nobody died this shift!</i>"
|
||||
if(istype(SSticker.mode, /datum/game_mode/dynamic))
|
||||
var/datum/game_mode/dynamic/mode = SSticker.mode
|
||||
parts += "[FOURSPACES]Threat level: [mode.threat_level]"
|
||||
parts += "[FOURSPACES]Threat left: [mode.threat]"
|
||||
parts += "[FOURSPACES]Executed rules:"
|
||||
for(var/datum/dynamic_ruleset/rule in mode.executed_rules)
|
||||
parts += "[FOURSPACES][FOURSPACES][rule.ruletype] - <b>[rule.name]</b>: -[rule.cost] threat"
|
||||
return parts.Join("<br>")
|
||||
|
||||
/client/proc/roundend_report_file()
|
||||
|
||||
@@ -791,3 +791,6 @@ GLOBAL_LIST_INIT(binary, list("0","1"))
|
||||
rearranged += cword
|
||||
message = "[prefix][jointext(rearranged," ")]"
|
||||
. = message
|
||||
|
||||
#define is_alpha(X) ((text2ascii(X) <= 122) && (text2ascii(X) >= 97))
|
||||
#define is_digit(X) ((length(X) == 1) && (length(text2num(X)) == 1))
|
||||
@@ -73,3 +73,11 @@ GLOBAL_VAR_INIT(rollovercheck_last_timeofday, 0)
|
||||
|
||||
/proc/daysSince(realtimev)
|
||||
return round((world.realtime - realtimev) / (24 HOURS))
|
||||
|
||||
/proc/worldtime2text()
|
||||
return gameTimestamp("hh:mm:ss", world.time)
|
||||
|
||||
/proc/gameTimestamp(format = "hh:mm:ss", wtime=null)
|
||||
if(!wtime)
|
||||
wtime = world.time
|
||||
return time2text(wtime - GLOB.timezoneOffset, format)
|
||||
|
||||
@@ -1487,6 +1487,7 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new)
|
||||
/obj/item/reagent_containers/food/snacks/grown/nettle, // base type
|
||||
/obj/item/reagent_containers/food/snacks/deepfryholder,
|
||||
/obj/item/reagent_containers/food/snacks/grown/shell,
|
||||
/obj/item/reagent_containers/food/snacks/clothing,
|
||||
/obj/item/reagent_containers/food/snacks/store/bread
|
||||
)
|
||||
blocked |= typesof(/obj/item/reagent_containers/food/snacks/customizable)
|
||||
|
||||
@@ -32,6 +32,7 @@ GLOBAL_LIST_INIT(bitfields, list(
|
||||
"UNIQUE_RENAME" = UNIQUE_RENAME,
|
||||
"USES_TGUI" = USES_TGUI,
|
||||
"FROZEN" = FROZEN,
|
||||
"SHOVABLE_ONTO" = SHOVABLE_ONTO
|
||||
),
|
||||
"datum_flags" = list(
|
||||
"DF_USE_TAG" = DF_USE_TAG,
|
||||
@@ -136,7 +137,7 @@ GLOBAL_LIST_INIT(bitfields, list(
|
||||
"LAVAPROTECT" = LAVAPROTECT,
|
||||
"STOPSPRESSUREDAMAGE" = STOPSPRESSUREDAMAGE,
|
||||
"BLOCK_GAS_SMOKE_EFFECT" = BLOCK_GAS_SMOKE_EFFECT,
|
||||
"MASKINTERNALS" = MASKINTERNALS,
|
||||
"ALLOWINTERNALS" = ALLOWINTERNALS,
|
||||
"NOSLIP" = NOSLIP,
|
||||
"THICKMATERIAL" = THICKMATERIAL,
|
||||
"VOICEBOX_TOGGLABLE" = VOICEBOX_TOGGLABLE,
|
||||
@@ -171,10 +172,32 @@ GLOBAL_LIST_INIT(bitfields, list(
|
||||
"rad_flags" = list(
|
||||
"RAD_PROTECT_CONTENTS" = RAD_PROTECT_CONTENTS,
|
||||
"RAD_NO_CONTAMINATE" = RAD_NO_CONTAMINATE,
|
||||
),
|
||||
),
|
||||
"disease_flags" = list(
|
||||
"CURABLE" = CURABLE,
|
||||
"CAN_CARRY" = CAN_CARRY,
|
||||
"CAN_RESIST" = CAN_RESIST
|
||||
),
|
||||
))
|
||||
),
|
||||
"chemical_flags" = list(
|
||||
"REAGENT_DEAD_PROCESS" = REAGENT_DEAD_PROCESS,
|
||||
"REAGENT_DONOTSPLIT" = REAGENT_DONOTSPLIT,
|
||||
"REAGENT_ONLYINVERSE" = REAGENT_ONLYINVERSE,
|
||||
"REAGENT_ONMOBMERGE" = REAGENT_ONMOBMERGE,
|
||||
"REAGENT_INVISIBLE" = REAGENT_INVISIBLE,
|
||||
"REAGENT_FORCEONNEW" = REAGENT_FORCEONNEW,
|
||||
"REAGENT_SNEAKYNAME" = REAGENT_SNEAKYNAME,
|
||||
"REAGENT_SPLITRETAINVOL" = REAGENT_SPLITRETAINVOL
|
||||
),
|
||||
"clear_conversion" = list(
|
||||
"REACTION_CLEAR_IMPURE" = REACTION_CLEAR_IMPURE,
|
||||
"REACTION_CLEAR_INVERSE" = REACTION_CLEAR_INVERSE
|
||||
),
|
||||
"organ_flags" = list(
|
||||
"ORGAN_SYNTHETIC" = ORGAN_SYNTHETIC,
|
||||
"ORGAN_FROZEN" = ORGAN_FROZEN,
|
||||
"ORGAN_FAILING" = ORGAN_FAILING,
|
||||
"ORGAN_EXTERNAL" = ORGAN_EXTERNAL,
|
||||
"ORGAN_VITAL" = ORGAN_VITAL,
|
||||
"ORGAN_NO_SPOIL" = ORGAN_NO_SPOIL
|
||||
),
|
||||
))
|
||||
|
||||
@@ -33,8 +33,10 @@ GLOBAL_LIST_EMPTY(animated_tails_list_human)
|
||||
GLOBAL_LIST_EMPTY(ears_list)
|
||||
GLOBAL_LIST_EMPTY(wings_list)
|
||||
GLOBAL_LIST_EMPTY(wings_open_list)
|
||||
GLOBAL_LIST_EMPTY(deco_wings_list)
|
||||
GLOBAL_LIST_EMPTY(r_wings_list)
|
||||
GLOBAL_LIST_EMPTY(moth_wings_list)
|
||||
GLOBAL_LIST_EMPTY(insect_wings_list)
|
||||
GLOBAL_LIST_EMPTY(insect_fluffs_list)
|
||||
GLOBAL_LIST_EMPTY(caps_list)
|
||||
|
||||
GLOBAL_LIST_INIT(ghost_forms_with_directions_list, list("ghost")) //stores the ghost forms that support directional sprites
|
||||
|
||||
@@ -107,9 +107,10 @@ GLOBAL_LIST_INIT(maintenance_loot, list(
|
||||
/obj/item/storage/toolbox/artistic = 2,
|
||||
/obj/item/toy/eightball = 1,
|
||||
/obj/item/reagent_containers/pill/floorpill = 1,
|
||||
/obj/item/reagent_containers/food/snacks/cannedpeaches/maint = 1,
|
||||
/obj/item/reagent_containers/food/snacks/cannedpeaches/maint = 2,
|
||||
/obj/item/storage/daki = 3, //VERY IMPORTANT CIT CHANGE - adds bodypillows to maint
|
||||
/obj/item/storage/pill_bottle/penis_enlargement = 2,
|
||||
/obj/item/storage/pill_bottle/breast_enlargement = 2,
|
||||
/obj/item/clothing/shoes/wheelys = 1,
|
||||
/obj/item/clothing/shoes/kindleKicks = 1,
|
||||
/obj/item/autosurgeon/penis = 1,
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
GLOBAL_LIST_EMPTY(donators_by_group) //group id = donator list of ckeys
|
||||
@@ -13,6 +13,7 @@
|
||||
#define POLL_IGNORE_GOLEM "golem"
|
||||
#define POLL_IGNORE_SWARMER "swarmer"
|
||||
#define POLL_IGNORE_DRONE "drone"
|
||||
#define POLL_IGNORE_CLONE "clone"
|
||||
|
||||
GLOBAL_LIST_INIT(poll_ignore_desc, list(
|
||||
POLL_IGNORE_SENTIENCE_POTION = "Sentience potion",
|
||||
@@ -28,6 +29,7 @@ GLOBAL_LIST_INIT(poll_ignore_desc, list(
|
||||
POLL_IGNORE_GOLEM = "Golems",
|
||||
POLL_IGNORE_SWARMER = "Swarmer shells",
|
||||
POLL_IGNORE_DRONE = "Drone shells",
|
||||
POLL_IGNORE_CLONE = "Defective/SDGF clones"
|
||||
))
|
||||
GLOBAL_LIST_INIT(poll_ignore, init_poll_ignore())
|
||||
|
||||
|
||||
@@ -26,6 +26,8 @@ GLOBAL_VAR(query_debug_log)
|
||||
GLOBAL_PROTECT(query_debug_log)
|
||||
GLOBAL_VAR(world_job_debug_log)
|
||||
GLOBAL_PROTECT(world_job_debug_log)
|
||||
GLOBAL_VAR(world_virus_log)
|
||||
GLOBAL_PROTECT(world_virus_log)
|
||||
|
||||
GLOBAL_LIST_EMPTY(bombers)
|
||||
GLOBAL_PROTECT(bombers)
|
||||
|
||||
@@ -6,8 +6,6 @@ GLOBAL_VAR_INIT(timezoneOffset, 0) // The difference betwen midnight (of the hos
|
||||
// However it'd be ok to use for accessing attack logs and such too, which are even laggier.
|
||||
GLOBAL_VAR_INIT(fileaccess_timer, 0)
|
||||
|
||||
GLOBAL_VAR_INIT(TAB, " ")
|
||||
|
||||
GLOBAL_DATUM_INIT(data_core, /datum/datacore, new)
|
||||
|
||||
GLOBAL_VAR_INIT(CELLRATE, 0.002) // conversion ratio between a watt-tick and kilojoule
|
||||
|
||||
@@ -67,7 +67,7 @@
|
||||
/mob/proc/ClickOn( atom/A, params )
|
||||
if(world.time <= next_click)
|
||||
return
|
||||
next_click = world.time + 1
|
||||
next_click = world.time + world.tick_lag
|
||||
|
||||
if(check_click_intercept(params,A))
|
||||
return
|
||||
|
||||
@@ -55,6 +55,17 @@
|
||||
|
||||
var/obj/item/W = get_active_held_item()
|
||||
|
||||
if(!W && A.Adjacent(src) && (isobj(A) || ismob(A)))
|
||||
var/atom/movable/C = A
|
||||
if(C.can_buckle && C.has_buckled_mobs())
|
||||
if(C.buckled_mobs.len > 1)
|
||||
var/unbuckled = input(src, "Who do you wish to unbuckle?","Unbuckle Who?") as null|mob in C.buckled_mobs
|
||||
if(C.user_unbuckle_mob(unbuckled,src))
|
||||
return
|
||||
else
|
||||
if(C.user_unbuckle_mob(C.buckled_mobs[1],src))
|
||||
return
|
||||
|
||||
if(!W && get_dist(src,A) <= interaction_range)
|
||||
A.attack_robot(src)
|
||||
return
|
||||
|
||||
@@ -157,7 +157,7 @@
|
||||
var/image/item_overlay = image(holding)
|
||||
item_overlay.alpha = 92
|
||||
|
||||
if(!user.can_equip(holding, slot_id, disable_warning = TRUE))
|
||||
if(!user.can_equip(holding, slot_id, TRUE))
|
||||
item_overlay.color = "#FF0000"
|
||||
else
|
||||
item_overlay.color = "#00ff00"
|
||||
@@ -290,16 +290,19 @@
|
||||
icon_state = "internal0"
|
||||
else
|
||||
if(!C.getorganslot(ORGAN_SLOT_BREATHING_TUBE))
|
||||
if(!istype(C.wear_mask, /obj/item/clothing/mask))
|
||||
var/obj/item/clothing/check
|
||||
var/internals = FALSE
|
||||
|
||||
for(check in GET_INTERNAL_SLOTS(C))
|
||||
if(istype(check, /obj/item/clothing/mask))
|
||||
var/obj/item/clothing/mask/M = check
|
||||
if(M.mask_adjusted)
|
||||
M.adjustmask(C)
|
||||
if(CHECK_BITFIELD(check.clothing_flags, ALLOWINTERNALS))
|
||||
internals = TRUE
|
||||
if(!internals)
|
||||
to_chat(C, "<span class='warning'>You are not wearing an internals mask!</span>")
|
||||
return 1
|
||||
else
|
||||
var/obj/item/clothing/mask/M = C.wear_mask
|
||||
if(M.mask_adjusted) // if mask on face but pushed down
|
||||
M.adjustmask(C) // adjust it back
|
||||
if( !(M.clothing_flags & MASKINTERNALS) )
|
||||
to_chat(C, "<span class='warning'>You are not wearing an internals mask!</span>")
|
||||
return
|
||||
return
|
||||
|
||||
var/obj/item/I = C.is_holding_item_of_type(/obj/item/tank)
|
||||
if(I)
|
||||
|
||||
@@ -171,3 +171,7 @@
|
||||
if(prob(2))
|
||||
playsound(src, 'sound/weapons/dink.ogg', 30, 1)
|
||||
return 1
|
||||
|
||||
/obj/item/proc/getweight()
|
||||
return total_mass || w_class * 1.25
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
var/abstract_type = /datum/config_entry //do not instantiate if type matches this
|
||||
|
||||
var/vv_VAS = TRUE //Force validate and set on VV. VAS proccall guard will run regardless.
|
||||
var/postload_required = FALSE //requires running OnPostload()
|
||||
|
||||
var/dupes_allowed = FALSE
|
||||
|
||||
@@ -72,6 +73,9 @@
|
||||
/datum/config_entry/proc/DeprecationUpdate(value)
|
||||
return
|
||||
|
||||
/datum/config_entry/proc/OnPostload()
|
||||
return
|
||||
|
||||
/datum/config_entry/string
|
||||
config_entry_value = ""
|
||||
abstract_type = /datum/config_entry/string
|
||||
@@ -80,7 +84,7 @@
|
||||
/datum/config_entry/string/vv_edit_var(var_name, var_value)
|
||||
return var_name != "auto_trim" && ..()
|
||||
|
||||
/datum/config_entry/string/ValidateAndSet(str_val)
|
||||
/datum/config_entry/string/ValidateAndSet(str_val, during_load)
|
||||
if(!VASProcCallGuard(str_val))
|
||||
return FALSE
|
||||
config_entry_value = auto_trim ? trim(str_val) : str_val
|
||||
|
||||
@@ -101,6 +101,7 @@
|
||||
log_config("Loading config file [filename]...")
|
||||
var/list/lines = world.file2list("[directory]/[filename]")
|
||||
var/list/_entries = entries
|
||||
var/list/postload_required = list()
|
||||
for(var/L in lines)
|
||||
L = trim(L)
|
||||
if(!L)
|
||||
@@ -157,18 +158,24 @@
|
||||
else
|
||||
warning("[new_ver.type] is deprecated but gave no proper return for DeprecationUpdate()")
|
||||
|
||||
var/validated = E.ValidateAndSet(value)
|
||||
var/validated = E.ValidateAndSet(value, TRUE)
|
||||
if(!validated)
|
||||
log_config("Failed to validate setting \"[value]\" for [entry]")
|
||||
else
|
||||
if(E.modified && !E.dupes_allowed)
|
||||
log_config("Duplicate setting for [entry] ([value], [E.resident_file]) detected! Using latest.")
|
||||
if(E.postload_required)
|
||||
postload_required[E] = TRUE
|
||||
|
||||
E.resident_file = filename
|
||||
|
||||
if(validated)
|
||||
E.modified = TRUE
|
||||
|
||||
for(var/i in postload_required)
|
||||
var/datum/config_entry/E = i
|
||||
E.OnPostload()
|
||||
|
||||
++.
|
||||
|
||||
/datum/controller/configuration/can_vv_get(var_name)
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
/datum/config_entry/keyed_list/donator_group
|
||||
key_mode = KEY_MODE_TEXT
|
||||
value_mode = VALUE_MODE_FLAG
|
||||
abstract_type = /datum/config_entry/keyed_list/donator_group
|
||||
|
||||
//If we're in the middle of a config load, only do the regeneration afterwards to prevent this from wasting a massive amount of CPU for list regenerations.
|
||||
/datum/config_entry/keyed_list/donator_group/ValidateAndSet(str_val, during_load)
|
||||
. = ..()
|
||||
if(. && during_load)
|
||||
regenerate_donator_grouping_list()
|
||||
|
||||
/datum/config_entry/keyed_list/donator_group/OnPostload()
|
||||
. = ..()
|
||||
regenerate_donator_grouping_list()
|
||||
|
||||
//This is kinda weird in that the config entries are defined here but all the handling/calculations are in __HELPERS/donator_groupings.dm
|
||||
|
||||
/datum/config_entry/keyed_list/donator_group/tier_1_donators
|
||||
|
||||
/datum/config_entry/keyed_list/donator_group/tier_2_donators
|
||||
|
||||
/datum/config_entry/keyed_list/donator_group/tier_3_donators
|
||||
@@ -70,6 +70,9 @@
|
||||
|
||||
/datum/config_entry/flag/disable_peaceborg
|
||||
|
||||
/datum/config_entry/number/minimum_secborg_alert //Minimum alert level for secborgs to be chosen.
|
||||
config_entry_value = 3
|
||||
|
||||
/datum/config_entry/number/traitor_scaling_coeff //how much does the amount of players get divided by to determine traitors
|
||||
config_entry_value = 6
|
||||
min_val = 1
|
||||
|
||||
@@ -39,6 +39,8 @@
|
||||
|
||||
/datum/config_entry/flag/log_game // log game events
|
||||
|
||||
/datum/config_entry/flag/log_virus // log virology data
|
||||
|
||||
/datum/config_entry/flag/log_vote // log voting
|
||||
|
||||
/datum/config_entry/flag/log_whisper // log client whisper
|
||||
@@ -173,6 +175,9 @@
|
||||
/datum/config_entry/string/banappeals
|
||||
|
||||
/datum/config_entry/string/wikiurl
|
||||
config_entry_value = "https://katlin.dog/citadel-wiki"
|
||||
|
||||
/datum/config_entry/string/wikiurltg
|
||||
config_entry_value = "http://www.tgstation13.org/wiki"
|
||||
|
||||
/datum/config_entry/string/forumurl
|
||||
|
||||
@@ -6,7 +6,17 @@ SUBSYSTEM_DEF(assets)
|
||||
var/list/preload = list()
|
||||
|
||||
/datum/controller/subsystem/assets/Initialize(timeofday)
|
||||
for(var/type in typesof(/datum/asset))
|
||||
|
||||
var/list/priority_assets = list(
|
||||
/datum/asset/simple/oui_theme_nano,
|
||||
/datum/asset/simple/goonchat
|
||||
)
|
||||
|
||||
for(var/type in priority_assets)
|
||||
var/datum/asset/A = new type()
|
||||
A.register()
|
||||
|
||||
for(var/type in typesof(/datum/asset) - (priority_assets | list(/datum/asset, /datum/asset/simple)))
|
||||
var/datum/asset/A = type
|
||||
if (type != initial(A._abstract))
|
||||
get_asset_datum(type)
|
||||
|
||||
@@ -294,7 +294,7 @@ Versioning
|
||||
var/lakey = L.lastattackerckey
|
||||
var/sqlbrute = L.getBruteLoss()
|
||||
var/sqlfire = L.getFireLoss()
|
||||
var/sqlbrain = L.getBrainLoss()
|
||||
var/sqlbrain = L.getOrganLoss(ORGAN_SLOT_BRAIN)
|
||||
var/sqloxy = L.getOxyLoss()
|
||||
var/sqltox = L.getToxLoss()
|
||||
var/sqlclone = L.getCloneLoss()
|
||||
@@ -308,7 +308,7 @@ Versioning
|
||||
|
||||
if(!SSdbcore.Connect())
|
||||
return
|
||||
|
||||
|
||||
sqlname = sanitizeSQL(sqlname)
|
||||
sqlkey = sanitizeSQL(sqlkey)
|
||||
sqljob = sanitizeSQL(sqljob)
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
SUBSYSTEM_DEF(chat)
|
||||
name = "Chat"
|
||||
flags = SS_TICKER|SS_NO_INIT
|
||||
wait = 1
|
||||
priority = FIRE_PRIORITY_CHAT
|
||||
init_order = INIT_ORDER_CHAT
|
||||
var/list/payload = list()
|
||||
|
||||
|
||||
/datum/controller/subsystem/chat/fire()
|
||||
for(var/i in payload)
|
||||
var/client/C = i
|
||||
C << output(payload[C], "browseroutput:output")
|
||||
payload -= C
|
||||
|
||||
if(MC_TICK_CHECK)
|
||||
return
|
||||
|
||||
|
||||
/datum/controller/subsystem/chat/proc/queue(target, message, handle_whitespace = TRUE)
|
||||
if(!target || !message)
|
||||
return
|
||||
|
||||
if(!istext(message))
|
||||
stack_trace("to_chat called with invalid input type")
|
||||
return
|
||||
|
||||
if(target == world)
|
||||
target = GLOB.clients
|
||||
|
||||
//Some macros remain in the string even after parsing and fuck up the eventual output
|
||||
message = replacetext(message, "\improper", "")
|
||||
message = replacetext(message, "\proper", "")
|
||||
if(handle_whitespace)
|
||||
message = replacetext(message, "\n", "<br>")
|
||||
message = replacetext(message, "\t", "[FOURSPACES][FOURSPACES]")
|
||||
message += "<br>"
|
||||
|
||||
|
||||
//url_encode it TWICE, this way any UTF-8 characters are able to be decoded by the Javascript.
|
||||
//Do the double-encoding here to save nanoseconds
|
||||
var/twiceEncoded = url_encode(url_encode(message))
|
||||
|
||||
if(islist(target))
|
||||
for(var/I in target)
|
||||
var/client/C = CLIENT_FROM_VAR(I) //Grab us a client if possible
|
||||
|
||||
if(!C?.chatOutput || C.chatOutput.broken) //A player who hasn't updated his skin file.
|
||||
continue
|
||||
|
||||
if(!C.chatOutput.loaded) //Client still loading, put their messages in a queue
|
||||
C.chatOutput.messageQueue += message
|
||||
continue
|
||||
|
||||
payload[C] += twiceEncoded
|
||||
|
||||
else
|
||||
var/client/C = CLIENT_FROM_VAR(target) //Grab us a client if possible
|
||||
|
||||
if(!C?.chatOutput || C.chatOutput.broken) //A player who hasn't updated his skin file.
|
||||
return
|
||||
|
||||
if(!C.chatOutput.loaded) //Client still loading, put their messages in a queue
|
||||
C.chatOutput.messageQueue += message
|
||||
return
|
||||
|
||||
payload[C] += twiceEncoded
|
||||
@@ -23,7 +23,7 @@ SUBSYSTEM_DEF(input)
|
||||
// This is for when macro sets are eventualy datumized
|
||||
/datum/controller/subsystem/input/proc/setup_default_macro_sets()
|
||||
var/list/static/default_macro_sets
|
||||
|
||||
|
||||
if(default_macro_sets)
|
||||
macro_sets = default_macro_sets
|
||||
return
|
||||
@@ -49,6 +49,7 @@ SUBSYSTEM_DEF(input)
|
||||
"old_hotkeys" = list(
|
||||
"Tab" = "\".winset \\\"mainwindow.macro=old_default input.focus=true input.background-color=[COLOR_INPUT_ENABLED]\\\"\"",
|
||||
"O" = "ooc",
|
||||
"L" = "looc",
|
||||
"T" = "say",
|
||||
"M" = "me",
|
||||
"Back" = "\".winset \\\"input.text=\\\"\\\"\\\"\"", // This makes it so backspace can remove default inputs
|
||||
|
||||
@@ -110,13 +110,16 @@ SUBSYSTEM_DEF(job)
|
||||
if(job.required_playtime_remaining(player.client))
|
||||
JobDebug("FOC player not enough xp, Player: [player]")
|
||||
continue
|
||||
if(!player.client.prefs.pref_species.qualifies_for_rank(job.title, player.client.prefs.features))
|
||||
JobDebug("FOC non-human failed, Player: [player]")
|
||||
continue
|
||||
if(flag && (!(flag in player.client.prefs.be_special)))
|
||||
JobDebug("FOC flag failed, Player: [player], Flag: [flag], ")
|
||||
continue
|
||||
if(player.mind && job.title in player.mind.restricted_roles)
|
||||
JobDebug("FOC incompatible with antagonist role, Player: [player]")
|
||||
continue
|
||||
if(player.client.prefs.GetJobDepartment(job, level) & job.flag)
|
||||
if(player.client.prefs.job_preferences["[job.title]"] == level)
|
||||
JobDebug("FOC pass, Player: [player], Level:[level]")
|
||||
candidates += player
|
||||
return candidates
|
||||
@@ -145,6 +148,10 @@ SUBSYSTEM_DEF(job)
|
||||
JobDebug("GRJ player not old enough, Player: [player]")
|
||||
continue
|
||||
|
||||
if(!player.client.prefs.pref_species.qualifies_for_rank(job.title, player.client.prefs.features))
|
||||
JobDebug("GRJ non-human failed, Player: [player]")
|
||||
continue
|
||||
|
||||
if(job.required_playtime_remaining(player.client))
|
||||
JobDebug("GRJ player not enough xp, Player: [player]")
|
||||
continue
|
||||
@@ -182,7 +189,7 @@ SUBSYSTEM_DEF(job)
|
||||
if((job.current_positions >= job.total_positions) && job.total_positions != -1)
|
||||
continue
|
||||
var/list/candidates = FindOccupationCandidates(job, level)
|
||||
if(!candidates.len)
|
||||
if(!candidates?.len)
|
||||
continue
|
||||
var/mob/dead/new_player/candidate = pick(candidates)
|
||||
if(AssignRole(candidate, command_position))
|
||||
@@ -200,7 +207,7 @@ SUBSYSTEM_DEF(job)
|
||||
if((job.current_positions >= job.total_positions) && job.total_positions != -1)
|
||||
continue
|
||||
var/list/candidates = FindOccupationCandidates(job, level)
|
||||
if(!candidates.len)
|
||||
if(!candidates?.len)
|
||||
continue
|
||||
var/mob/dead/new_player/candidate = pick(candidates)
|
||||
AssignRole(candidate, command_position)
|
||||
@@ -228,7 +235,7 @@ SUBSYSTEM_DEF(job)
|
||||
* fills var "assigned_role" for all ready players.
|
||||
* This proc must not have any side effect besides of modifying "assigned_role".
|
||||
**/
|
||||
/datum/controller/subsystem/job/proc/DivideOccupations()
|
||||
/datum/controller/subsystem/job/proc/DivideOccupations(list/required_jobs)
|
||||
//Setup new player list and get the jobs list
|
||||
JobDebug("Running DO")
|
||||
|
||||
@@ -241,14 +248,14 @@ SUBSYSTEM_DEF(job)
|
||||
|
||||
//Get the players who are ready
|
||||
for(var/mob/dead/new_player/player in GLOB.player_list)
|
||||
if(player.ready == PLAYER_READY_TO_PLAY && player.mind && !player.mind.assigned_role)
|
||||
if(player.ready == PLAYER_READY_TO_PLAY && player.check_preferences() && player.mind && !player.mind.assigned_role)
|
||||
unassigned += player
|
||||
|
||||
initial_players_to_assign = unassigned.len
|
||||
|
||||
JobDebug("DO, Len: [unassigned.len]")
|
||||
JobDebug("DO, Len: [unassigned?.len]")
|
||||
if(unassigned.len == 0)
|
||||
return 0
|
||||
return validate_required_jobs(required_jobs)
|
||||
|
||||
//Scale number of open security officer slots to population
|
||||
setup_officer_positions()
|
||||
@@ -269,8 +276,8 @@ SUBSYSTEM_DEF(job)
|
||||
//People who wants to be the overflow role, sure, go on.
|
||||
JobDebug("DO, Running Overflow Check 1")
|
||||
var/datum/job/overflow = GetJob(SSjob.overflow_role)
|
||||
var/list/overflow_candidates = FindOccupationCandidates(overflow, 3)
|
||||
JobDebug("AC1, Candidates: [overflow_candidates.len]")
|
||||
var/list/overflow_candidates = FindOccupationCandidates(overflow, JP_LOW)
|
||||
JobDebug("AC1, Candidates: [overflow_candidates?.len]")
|
||||
for(var/mob/dead/new_player/player in overflow_candidates)
|
||||
JobDebug("AC1 pass, Player: [player]")
|
||||
AssignRole(player, SSjob.overflow_role)
|
||||
@@ -297,7 +304,8 @@ SUBSYSTEM_DEF(job)
|
||||
|
||||
// Loop through all levels from high to low
|
||||
var/list/shuffledoccupations = shuffle(occupations)
|
||||
for(var/level = 1 to 3)
|
||||
var/list/levels = list(JP_HIGH,JP_MEDIUM,JP_LOW)
|
||||
for(var/level in levels)
|
||||
//Check the head jobs first each level
|
||||
CheckHeadPositions(level)
|
||||
|
||||
@@ -326,13 +334,17 @@ SUBSYSTEM_DEF(job)
|
||||
if(job.required_playtime_remaining(player.client))
|
||||
JobDebug("DO player not enough xp, Player: [player], Job:[job.title]")
|
||||
continue
|
||||
|
||||
if(!player.client.prefs.pref_species.qualifies_for_rank(job.title, player.client.prefs.features))
|
||||
JobDebug("DO non-human failed, Player: [player], Job:[job.title]")
|
||||
continue
|
||||
|
||||
if(player.mind && job.title in player.mind.restricted_roles)
|
||||
JobDebug("DO incompatible with antagonist role, Player: [player], Job:[job.title]")
|
||||
continue
|
||||
|
||||
// If the player wants that job on this level, then try give it to him.
|
||||
if(player.client.prefs.GetJobDepartment(job, level) & job.flag)
|
||||
if(player.client.prefs.job_preferences["[job.title]"] == level)
|
||||
// If the job isn't filled
|
||||
if((job.current_positions < job.spawn_positions) || job.spawn_positions == -1)
|
||||
JobDebug("DO pass, Player: [player], Level:[level], Job:[job.title]")
|
||||
@@ -351,9 +363,28 @@ SUBSYSTEM_DEF(job)
|
||||
//Mop up people who can't leave.
|
||||
for(var/mob/dead/new_player/player in unassigned) //Players that wanted to back out but couldn't because they're antags (can you feel the edge case?)
|
||||
if(!GiveRandomJob(player))
|
||||
AssignRole(player, SSjob.overflow_role) //If everything is already filled, make them an assistant
|
||||
if(!AssignRole(player, SSjob.overflow_role)) //If everything is already filled, make them an assistant
|
||||
return FALSE //Living on the edge, the forced antagonist couldn't be assigned to overflow role (bans, client age) - just reroll
|
||||
|
||||
return 1
|
||||
return validate_required_jobs(required_jobs)
|
||||
|
||||
/datum/controller/subsystem/job/proc/validate_required_jobs(list/required_jobs)
|
||||
if(!required_jobs.len)
|
||||
return TRUE
|
||||
for(var/required_group in required_jobs)
|
||||
var/group_ok = TRUE
|
||||
for(var/rank in required_group)
|
||||
var/datum/job/J = GetJob(rank)
|
||||
if(!J)
|
||||
SSticker.mode.setup_error = "Invalid job [rank] in gamemode required jobs."
|
||||
return FALSE
|
||||
if(J.current_positions < required_group[rank])
|
||||
group_ok = FALSE
|
||||
break
|
||||
if(group_ok)
|
||||
return TRUE
|
||||
SSticker.mode.setup_error = "Required jobs not present."
|
||||
return FALSE
|
||||
|
||||
//We couldn't find a job from prefs for this guy.
|
||||
/datum/controller/subsystem/job/proc/HandleUnassigned(mob/dead/new_player/player)
|
||||
@@ -406,7 +437,7 @@ SUBSYSTEM_DEF(job)
|
||||
if(length(GLOB.jobspawn_overrides[rank]))
|
||||
S = pick(GLOB.jobspawn_overrides[rank])
|
||||
if(S)
|
||||
SendToAtom(H, S, buckle = FALSE)
|
||||
S.JoinPlayerHere(H, FALSE)
|
||||
if(!S) //if there isn't a spawnpoint send them to latejoin, if there's no latejoin go yell at your mapper
|
||||
log_world("Couldn't find a round start spawn point for [rank]")
|
||||
SendToLateJoin(H)
|
||||
@@ -418,7 +449,7 @@ SUBSYSTEM_DEF(job)
|
||||
if(job)
|
||||
if(!job.dresscodecompliant)// CIT CHANGE - dress code compliance
|
||||
equip_loadout(N, H) // CIT CHANGE - allows players to spawn with loadout items
|
||||
var/new_mob = job.equip(H, null, null, joined_late)
|
||||
var/new_mob = job.equip(H, null, null, joined_late , null, M.client)
|
||||
if(ismob(new_mob))
|
||||
H = new_mob
|
||||
if(!joined_late)
|
||||
@@ -428,12 +459,18 @@ SUBSYSTEM_DEF(job)
|
||||
|
||||
SSpersistence.antag_rep_change[M.client.ckey] += job.GetAntagRep()
|
||||
|
||||
/* if(M.client.holder)
|
||||
if(CONFIG_GET(flag/auto_deadmin_players) || (M.client.prefs?.toggles & DEADMIN_ALWAYS))
|
||||
M.client.holder.auto_deadmin()
|
||||
else
|
||||
handle_auto_deadmin_roles(M.client, rank) */
|
||||
|
||||
to_chat(M, "<b>You are the [rank].</b>")
|
||||
if(job)
|
||||
to_chat(M, "<b>As the [rank] you answer directly to [job.supervisors]. Special circumstances may change this.</b>")
|
||||
to_chat(M, "<b>To speak on your departments radio, use the :h button. To see others, look closely at your headset.</b>")
|
||||
job.radio_help_message(M)
|
||||
if(job.req_admin_notify)
|
||||
to_chat(M, "<b>You are playing a job that is important for Game Progression. If you have to disconnect, please notify the admins via adminhelp.</b>")
|
||||
to_chat(M, "<b>You are playing a job that is important for Game Progression. If you have to disconnect immediately, please notify the admins via adminhelp. Otherwise put your locker gear back into the locker and cryo out.</b>")
|
||||
if(job.custom_spawn_text)
|
||||
to_chat(M, "<b>[job.custom_spawn_text]</b>")
|
||||
if(CONFIG_GET(number/minimal_access_threshold))
|
||||
@@ -446,12 +483,24 @@ SUBSYSTEM_DEF(job)
|
||||
equip_loadout(N, H, TRUE)//CIT CHANGE - makes players spawn with in-backpack loadout items properly. A little hacky but it works
|
||||
|
||||
return H
|
||||
|
||||
/*
|
||||
/datum/controller/subsystem/job/proc/handle_auto_deadmin_roles(client/C, rank)
|
||||
if(!C?.holder)
|
||||
return TRUE
|
||||
var/datum/job/job = GetJob(rank)
|
||||
if(!job)
|
||||
return
|
||||
if((job.auto_deadmin_role_flags & DEADMIN_POSITION_HEAD) && (CONFIG_GET(flag/auto_deadmin_heads) || (C.prefs?.toggles & DEADMIN_POSITION_HEAD)))
|
||||
return C.holder.auto_deadmin()
|
||||
else if((job.auto_deadmin_role_flags & DEADMIN_POSITION_SECURITY) && (CONFIG_GET(flag/auto_deadmin_security) || (C.prefs?.toggles & DEADMIN_POSITION_SECURITY)))
|
||||
return C.holder.auto_deadmin()
|
||||
else if((job.auto_deadmin_role_flags & DEADMIN_POSITION_SILICON) && (CONFIG_GET(flag/auto_deadmin_silicons) || (C.prefs?.toggles & DEADMIN_POSITION_SILICON))) //in the event there's ever psuedo-silicon roles added, ie synths.
|
||||
return C.holder.auto_deadmin()*/
|
||||
|
||||
/datum/controller/subsystem/job/proc/setup_officer_positions()
|
||||
var/datum/job/J = SSjob.GetJob("Security Officer")
|
||||
if(!J)
|
||||
throw EXCEPTION("setup_officer_positions(): Security officer job is missing")
|
||||
CRASH("setup_officer_positions(): Security officer job is missing")
|
||||
|
||||
var/ssc = CONFIG_GET(number/security_scaling_coeff)
|
||||
if(ssc > 0)
|
||||
@@ -502,13 +551,15 @@ SUBSYSTEM_DEF(job)
|
||||
if(job.required_playtime_remaining(player.client))
|
||||
young++
|
||||
continue
|
||||
if(player.client.prefs.GetJobDepartment(job, 1) & job.flag)
|
||||
high++
|
||||
else if(player.client.prefs.GetJobDepartment(job, 2) & job.flag)
|
||||
medium++
|
||||
else if(player.client.prefs.GetJobDepartment(job, 3) & job.flag)
|
||||
low++
|
||||
else never++ //not selected
|
||||
switch(player.client.prefs.job_preferences["[job.title]"])
|
||||
if(JP_HIGH)
|
||||
high++
|
||||
if(JP_MEDIUM)
|
||||
medium++
|
||||
if(JP_LOW)
|
||||
low++
|
||||
else
|
||||
never++
|
||||
SSblackbox.record_feedback("nested tally", "job_preferences", high, list("[job.title]", "high"))
|
||||
SSblackbox.record_feedback("nested tally", "job_preferences", medium, list("[job.title]", "medium"))
|
||||
SSblackbox.record_feedback("nested tally", "job_preferences", low, list("[job.title]", "low"))
|
||||
@@ -551,51 +602,61 @@ SUBSYSTEM_DEF(job)
|
||||
newjob.spawn_positions = J.spawn_positions
|
||||
newjob.current_positions = J.current_positions
|
||||
|
||||
/datum/controller/subsystem/job/proc/SendToAtom(mob/M, atom/A, buckle)
|
||||
if(buckle && isliving(M) && istype(A, /obj/structure/chair))
|
||||
var/obj/structure/chair/C = A
|
||||
if(C.buckle_mob(M, FALSE, FALSE))
|
||||
return
|
||||
M.forceMove(get_turf(A))
|
||||
/atom/proc/JoinPlayerHere(mob/M, buckle)
|
||||
// By default, just place the mob on the same turf as the marker or whatever.
|
||||
M.forceMove(get_turf(src))
|
||||
|
||||
/obj/structure/chair/JoinPlayerHere(mob/M, buckle)
|
||||
// Placing a mob in a chair will attempt to buckle it, or else fall back to default.
|
||||
if (buckle && isliving(M) && buckle_mob(M, FALSE, FALSE))
|
||||
return
|
||||
..()
|
||||
|
||||
/datum/controller/subsystem/job/proc/SendToLateJoin(mob/M, buckle = TRUE)
|
||||
var/atom/destination
|
||||
if(M.mind && M.mind.assigned_role && length(GLOB.jobspawn_overrides[M.mind.assigned_role])) //We're doing something special today.
|
||||
SendToAtom(M,pick(GLOB.jobspawn_overrides[M.mind.assigned_role]),FALSE)
|
||||
destination = pick(GLOB.jobspawn_overrides[M.mind.assigned_role])
|
||||
destination.JoinPlayerHere(M, FALSE)
|
||||
return
|
||||
|
||||
if(latejoin_trackers.len)
|
||||
SendToAtom(M, pick(latejoin_trackers), buckle)
|
||||
else
|
||||
//bad mojo
|
||||
var/area/shuttle/arrival/A = GLOB.areas_by_type[/area/shuttle/arrival]
|
||||
if(A)
|
||||
//first check if we can find a chair
|
||||
var/obj/structure/chair/C = locate() in A
|
||||
if(C)
|
||||
SendToAtom(M, C, buckle)
|
||||
return
|
||||
else //last hurrah
|
||||
var/list/avail = list()
|
||||
for(var/turf/T in A)
|
||||
if(!is_blocked_turf(T, TRUE))
|
||||
avail += T
|
||||
if(avail.len)
|
||||
SendToAtom(M, pick(avail), FALSE)
|
||||
return
|
||||
destination = pick(latejoin_trackers)
|
||||
destination.JoinPlayerHere(M, buckle)
|
||||
return
|
||||
|
||||
//pick an open spot on arrivals and dump em
|
||||
var/list/arrivals_turfs = shuffle(get_area_turfs(/area/shuttle/arrival))
|
||||
if(arrivals_turfs.len)
|
||||
for(var/turf/T in arrivals_turfs)
|
||||
if(!is_blocked_turf(T, TRUE))
|
||||
SendToAtom(M, T, FALSE)
|
||||
return
|
||||
//last chance, pick ANY spot on arrivals and dump em
|
||||
SendToAtom(M, arrivals_turfs[1], FALSE)
|
||||
else
|
||||
var/msg = "Unable to send mob [M] to late join!"
|
||||
message_admins(msg)
|
||||
CRASH(msg)
|
||||
//bad mojo
|
||||
var/area/shuttle/arrival/A = GLOB.areas_by_type[/area/shuttle/arrival]
|
||||
if(A)
|
||||
//first check if we can find a chair
|
||||
var/obj/structure/chair/C = locate() in A
|
||||
if(C)
|
||||
C.JoinPlayerHere(M, buckle)
|
||||
return
|
||||
|
||||
//last hurrah
|
||||
var/list/avail = list()
|
||||
for(var/turf/T in A)
|
||||
if(!is_blocked_turf(T, TRUE))
|
||||
avail += T
|
||||
if(avail.len)
|
||||
destination = pick(avail)
|
||||
destination.JoinPlayerHere(M, FALSE)
|
||||
return
|
||||
|
||||
//pick an open spot on arrivals and dump em
|
||||
var/list/arrivals_turfs = shuffle(get_area_turfs(/area/shuttle/arrival))
|
||||
if(arrivals_turfs.len)
|
||||
for(var/turf/T in arrivals_turfs)
|
||||
if(!is_blocked_turf(T, TRUE))
|
||||
T.JoinPlayerHere(M, FALSE)
|
||||
return
|
||||
//last chance, pick ANY spot on arrivals and dump em
|
||||
destination = arrivals_turfs[1]
|
||||
destination.JoinPlayerHere(M, FALSE)
|
||||
else
|
||||
var/msg = "Unable to send mob [M] to late join!"
|
||||
message_admins(msg)
|
||||
CRASH(msg)
|
||||
|
||||
|
||||
///////////////////////////////////
|
||||
@@ -637,4 +698,4 @@ SUBSYSTEM_DEF(job)
|
||||
. |= player.mind
|
||||
|
||||
/datum/controller/subsystem/job/proc/JobDebug(message)
|
||||
log_job_debug(message)
|
||||
log_job_debug(message)
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
PROCESSING_SUBSYSTEM_DEF(chemistry)
|
||||
wait = 5
|
||||
flags = SS_KEEP_TIMING
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ PROCESSING_SUBSYSTEM_DEF(quirks)
|
||||
runlevels = RUNLEVEL_GAME
|
||||
|
||||
var/list/quirks = list() //Assoc. list of all roundstart quirk datum types; "name" = /path/
|
||||
var/list/quirk_names_by_path = list()
|
||||
var/list/quirk_points = list() //Assoc. list of quirk names and their "point cost"; positive numbers are good traits, and negative ones are bad
|
||||
var/list/quirk_objects = list() //A list of all quirk objects in the game, since some may process
|
||||
|
||||
@@ -22,11 +23,68 @@ PROCESSING_SUBSYSTEM_DEF(quirks)
|
||||
var/datum/quirk/T = V
|
||||
quirks[initial(T.name)] = T
|
||||
quirk_points[initial(T.name)] = initial(T.value)
|
||||
quirk_names_by_path[T] = initial(T.name)
|
||||
|
||||
/datum/controller/subsystem/processing/quirks/proc/AssignQuirks(mob/living/user, client/cli, spawn_effects)
|
||||
/datum/controller/subsystem/processing/quirks/proc/AssignQuirks(mob/living/user, client/cli, spawn_effects, roundstart = FALSE, datum/job/job, silent = FALSE, mob/to_chat_target)
|
||||
GenerateQuirks(cli)
|
||||
for(var/V in cli.prefs.character_quirks)
|
||||
var/list/quirks = cli.prefs.character_quirks.Copy()
|
||||
var/list/cut
|
||||
if(job && job.blacklisted_quirks)
|
||||
cut = filter_quirks(quirks, job)
|
||||
for(var/V in quirks)
|
||||
user.add_quirk(V, spawn_effects)
|
||||
if(!silent && LAZYLEN(cut))
|
||||
to_chat(to_chat_target || user, "<span class='boldwarning'>All of your non-neutral character quirks have been cut due to these quirks conflicting with your job assignment: [english_list(cut)].</span>")
|
||||
|
||||
/datum/controller/subsystem/processing/quirks/proc/quirk_path_by_name(name)
|
||||
return quirks[name]
|
||||
|
||||
/datum/controller/subsystem/processing/quirks/proc/quirk_points_by_name(name)
|
||||
return quirk_points[name]
|
||||
|
||||
/datum/controller/subsystem/processing/quirks/proc/quirk_name_by_path(path)
|
||||
return quirk_names_by_path[path]
|
||||
|
||||
/datum/controller/subsystem/processing/quirks/proc/total_points(list/quirk_names)
|
||||
. = 0
|
||||
for(var/i in quirk_names)
|
||||
. += quirk_points_by_name(i)
|
||||
|
||||
/datum/controller/subsystem/processing/quirks/proc/filter_quirks(list/quirks, datum/job/job)
|
||||
var/list/cut = list()
|
||||
var/list/banned_names = list()
|
||||
for(var/i in job.blacklisted_quirks)
|
||||
var/name = quirk_name_by_path(i)
|
||||
if(name)
|
||||
banned_names += name
|
||||
var/list/blacklisted = quirks & banned_names
|
||||
if(length(blacklisted))
|
||||
for(var/i in blacklisted)
|
||||
quirks -= i
|
||||
cut += i
|
||||
|
||||
/* //Code to automatically reduce positive quirks until balance is even.
|
||||
var/points_used = total_points(quirks)
|
||||
if(points_used > 0)
|
||||
//they owe us points, let's collect.
|
||||
for(var/i in quirks)
|
||||
var/points = quirk_points_by_name(i)
|
||||
if(points > 0)
|
||||
cut += i
|
||||
quirks -= i
|
||||
points_used -= points
|
||||
if(points_used <= 0)
|
||||
break
|
||||
*/
|
||||
|
||||
//Nah, let's null all non-neutrals out.
|
||||
if(cut.len)
|
||||
for(var/i in quirks)
|
||||
if(quirk_points_by_name(i) != 0)
|
||||
//cut += i -- Commented out: Only show the ones that triggered the quirk purge.
|
||||
quirks -= i
|
||||
|
||||
return cut
|
||||
|
||||
/datum/controller/subsystem/processing/quirks/proc/GenerateQuirks(client/user)
|
||||
if(user.prefs.character_quirks.len)
|
||||
|
||||
@@ -255,7 +255,7 @@ SUBSYSTEM_DEF(ticker)
|
||||
var/can_continue = 0
|
||||
can_continue = src.mode.pre_setup() //Choose antagonists
|
||||
CHECK_TICK
|
||||
SSjob.DivideOccupations() //Distribute jobs
|
||||
can_continue = can_continue && SSjob.DivideOccupations(mode.required_jobs) //Distribute jobs
|
||||
CHECK_TICK
|
||||
|
||||
if(!GLOB.Debug2)
|
||||
@@ -385,7 +385,7 @@ SUBSYSTEM_DEF(ticker)
|
||||
if(player.mind.assigned_role != player.mind.special_role)
|
||||
SSjob.EquipRank(N, player.mind.assigned_role, 0)
|
||||
if(CONFIG_GET(flag/roundstart_traits) && ishuman(N.new_character))
|
||||
SSquirks.AssignQuirks(N.new_character, N.client, TRUE)
|
||||
SSquirks.AssignQuirks(N.new_character, N.client, TRUE, TRUE, SSjob.GetJob(player.mind.assigned_role), FALSE, N)
|
||||
CHECK_TICK
|
||||
if(captainless)
|
||||
for(var/mob/dead/new_player/N in GLOB.player_list)
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
SUBSYSTEM_DEF(bellies)
|
||||
name = "Bellies"
|
||||
priority = 5
|
||||
priority = FIRE_PRIORITY_VORE
|
||||
wait = 1 SECONDS
|
||||
flags = SS_KEEP_TIMING|SS_NO_INIT
|
||||
runlevels = RUNLEVEL_GAME|RUNLEVEL_POSTGAME
|
||||
|
||||
@@ -87,17 +87,20 @@ SUBSYSTEM_DEF(vote)
|
||||
/datum/controller/subsystem/vote/proc/announce_result()
|
||||
var/list/winners = get_result()
|
||||
var/text
|
||||
var/was_roundtype_vote = mode == "roundtype"
|
||||
if(winners.len > 0)
|
||||
if(question)
|
||||
text += "<b>[question]</b>"
|
||||
else
|
||||
text += "<b>[capitalize(mode)] Vote</b>"
|
||||
stored_gamemode_votes = list()
|
||||
if(was_roundtype_vote)
|
||||
stored_gamemode_votes = list()
|
||||
for(var/i=1,i<=choices.len,i++)
|
||||
var/votes = choices[choices[i]]
|
||||
if(!votes)
|
||||
votes = 0
|
||||
stored_gamemode_votes[choices[i]] = votes
|
||||
if(was_roundtype_vote)
|
||||
stored_gamemode_votes[choices[i]] = votes
|
||||
text += "\n<b>[choices[i]]:</b> [obfuscated ? "???" : votes]" //CIT CHANGE - adds obfuscated votes
|
||||
if(mode != "custom")
|
||||
if(winners.len > 1 && !obfuscated) //CIT CHANGE - adds obfuscated votes
|
||||
|
||||
+18
-11
@@ -494,6 +494,7 @@
|
||||
else
|
||||
to_chat(owner, "<span class='cultitalic'>Your hands are full!</span>")
|
||||
|
||||
//MGS Box
|
||||
/datum/action/item_action/agent_box
|
||||
name = "Deploy Box"
|
||||
desc = "Find inner peace, here, in the box."
|
||||
@@ -502,21 +503,27 @@
|
||||
icon_icon = 'icons/mob/actions/actions_items.dmi'
|
||||
button_icon_state = "deploy_box"
|
||||
var/cooldown = 0
|
||||
var/obj/structure/closet/cardboard/agent/box
|
||||
var/boxtype = /obj/structure/closet/cardboard/agent
|
||||
|
||||
//Handles open and closing the box
|
||||
/datum/action/item_action/agent_box/Trigger()
|
||||
if(!..())
|
||||
. = ..()
|
||||
if(!.)
|
||||
return FALSE
|
||||
if(QDELETED(box))
|
||||
if(cooldown < world.time - 100)
|
||||
box = new(owner.drop_location())
|
||||
owner.forceMove(box)
|
||||
cooldown = world.time
|
||||
owner.playsound_local(box, 'sound/misc/box_deploy.ogg', 50, TRUE)
|
||||
else
|
||||
owner.forceMove(box.drop_location())
|
||||
if(istype(owner.loc, /obj/structure/closet/cardboard/agent))
|
||||
var/obj/structure/closet/cardboard/agent/box = owner.loc
|
||||
owner.playsound_local(box, 'sound/misc/box_deploy.ogg', 50, TRUE)
|
||||
box.open()
|
||||
return
|
||||
//Box closing from here on out.
|
||||
if(!isturf(owner.loc)) //Don't let the player use this to escape mechs/welded closets.
|
||||
to_chat(owner, "<span class = 'notice'>You need more space to activate this implant.</span>")
|
||||
return
|
||||
if(cooldown < world.time - 100)
|
||||
var/box = new boxtype(owner.drop_location())
|
||||
owner.forceMove(box)
|
||||
cooldown = world.time
|
||||
owner.playsound_local(box, 'sound/misc/box_deploy.ogg', 50, TRUE)
|
||||
QDEL_NULL(box)
|
||||
|
||||
//Preset for spells
|
||||
/datum/action/spell_action
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
/datum/brain_trauma/hypnosis
|
||||
name = "Hypnosis"
|
||||
desc = "Patient's unconscious is completely enthralled by a word or sentence, focusing their thoughts and actions on it."
|
||||
scan_desc = "looping thought pattern"
|
||||
gain_text = ""
|
||||
lose_text = ""
|
||||
resilience = TRAUMA_RESILIENCE_SURGERY
|
||||
var/hypnotic_phrase = ""
|
||||
var/regex/target_phrase
|
||||
|
||||
/datum/brain_trauma/hypnosis/New(phrase, quirk = FALSE)
|
||||
if(!phrase)
|
||||
qdel(src)
|
||||
if(quirk == TRUE)
|
||||
hypnotic_phrase = phrase
|
||||
else
|
||||
friendliify(phrase)
|
||||
if(IsAdminAdvancedProcCall())
|
||||
to_chat(usr, "<span class='danger'>Hypnosis New() skipped due to try/catch incompatibility with admin proccalling.</span>")
|
||||
qdel(src)
|
||||
try
|
||||
target_phrase = new("(\\b[hypnotic_phrase]\\b)","ig")
|
||||
catch(var/exception/e)
|
||||
stack_trace("[e] on [e.file]:[e.line]")
|
||||
qdel(src)
|
||||
..()
|
||||
|
||||
/datum/brain_trauma/hypnosis/proc/friendliify(phrase)
|
||||
phrase = replacetext(lowertext(phrase), "kill", "hug")
|
||||
phrase = replacetext(lowertext(phrase), "murder", "cuddle")
|
||||
phrase = replacetext(lowertext(phrase), "harm", "snuggle")
|
||||
phrase = replacetext(lowertext(phrase), "decapitate", "headpat")
|
||||
phrase = replacetext(lowertext(phrase), "strangle", "meow at")
|
||||
phrase = replacetext(lowertext(phrase), "suicide", "self-love")
|
||||
phrase = replacetext(lowertext(phrase), "lynch", "kiss")
|
||||
hypnotic_phrase = phrase
|
||||
|
||||
/datum/brain_trauma/hypnosis/on_gain()
|
||||
message_admins("[ADMIN_LOOKUPFLW(owner)] was hypnotized with the phrase '[hypnotic_phrase]'.")
|
||||
log_game("[key_name(owner)] was hypnotized with the phrase '[hypnotic_phrase]'.")
|
||||
to_chat(owner, "<span class='reallybig hypnophrase'>[hypnotic_phrase]</span>")
|
||||
to_chat(owner, "<span class='notice'>[pick("You feel your thoughts focusing on this phrase... you can't seem to get it out of your head.",\
|
||||
"Your head hurts, but this is all you can think of. It must be vitally important.",\
|
||||
"You feel a part of your mind repeating this over and over. You need to follow these words.",\
|
||||
"Something about this sounds... right, for some reason. You feel like you should follow these words.",\
|
||||
"These words keep echoing in your mind. You find yourself completely fascinated by them.")]</span>")
|
||||
if(!HAS_TRAIT(owner, "hypnotherapy"))
|
||||
to_chat(owner, "<span class='boldwarning'>You've been hypnotized by this sentence. You must follow these words. If it isn't a clear order, you can freely interpret how to do so,\
|
||||
as long as you act like the words are your highest priority.</span>")
|
||||
else
|
||||
to_chat(owner, "<span class='boldwarning'>You've been hypnotized by this sentence. You feel an incredible desire to follow these words, but are able to resist it somewhat. If it isn't a clear order, you can freely interpret how to do so,\
|
||||
however this does not take precedence over your other objectives.</span>")
|
||||
..()
|
||||
|
||||
/datum/brain_trauma/hypnosis/on_lose()
|
||||
message_admins("[ADMIN_LOOKUPFLW(owner)] is no longer hypnotized with the phrase '[hypnotic_phrase]'.")
|
||||
log_game("[key_name(owner)] is no longer hypnotized with the phrase '[hypnotic_phrase]'.")
|
||||
to_chat(owner, "<span class='userdanger'>You suddenly snap out of your fixation. The phrase '[hypnotic_phrase]' no longer feels important to you.</span>")
|
||||
..()
|
||||
|
||||
/datum/brain_trauma/hypnosis/on_life()
|
||||
..()
|
||||
if(prob(2))
|
||||
switch(rand(1,2))
|
||||
if(1)
|
||||
to_chat(owner, "<i>...[lowertext(hypnotic_phrase)]...</i>")
|
||||
if(2)
|
||||
new /datum/hallucination/chat(owner, TRUE, FALSE, "<span class='hypnophrase'>[hypnotic_phrase]</span>")
|
||||
|
||||
/datum/brain_trauma/hypnosis/on_hear(message, speaker, message_language, raw_message, radio_freq)
|
||||
message = target_phrase.Replace(message, "<span class='hypnophrase'>$1</span>")
|
||||
return message
|
||||
@@ -46,7 +46,7 @@
|
||||
var/list/mob/dead/observer/candidates = pollCandidatesForMob("Do you want to play as [owner]'s imaginary friend?", ROLE_PAI, null, null, 75, friend)
|
||||
if(LAZYLEN(candidates))
|
||||
var/mob/dead/observer/C = pick(candidates)
|
||||
friend.key = C.key
|
||||
C.transfer_ckey(friend, FALSE)
|
||||
friend_initialized = TRUE
|
||||
else
|
||||
qdel(src)
|
||||
|
||||
@@ -31,6 +31,8 @@
|
||||
|
||||
/datum/brain_trauma/mild/phobia/on_life()
|
||||
..()
|
||||
if(HAS_TRAIT(owner, TRAIT_FEARLESS))
|
||||
return
|
||||
if(is_blind(owner))
|
||||
return
|
||||
if(world.time > next_check && world.time > next_scare)
|
||||
@@ -70,6 +72,8 @@
|
||||
/datum/brain_trauma/mild/phobia/on_hear(message, speaker, message_language, raw_message, radio_freq)
|
||||
if(!owner.can_hear() || world.time < next_scare) //words can't trigger you if you can't hear them *taps head*
|
||||
return message
|
||||
if(HAS_TRAIT(owner, TRAIT_FEARLESS))
|
||||
return message
|
||||
for(var/word in trigger_words)
|
||||
var/reg = regex("(\\b|\\A)[REGEX_QUOTE(word)]'?s*(\\b|\\Z)", "i")
|
||||
|
||||
@@ -79,6 +83,8 @@
|
||||
return message
|
||||
|
||||
/datum/brain_trauma/mild/phobia/handle_speech(datum/source, list/speech_args)
|
||||
if(HAS_TRAIT(owner, TRAIT_FEARLESS))
|
||||
return
|
||||
for(var/word in trigger_words)
|
||||
var/reg = regex("(\\b|\\A)[REGEX_QUOTE(word)]'?s*(\\b|\\Z)", "i")
|
||||
|
||||
|
||||
@@ -254,3 +254,20 @@
|
||||
/datum/brain_trauma/severe/pacifism/on_lose()
|
||||
REMOVE_TRAIT(owner, TRAIT_PACIFISM, TRAUMA_TRAIT)
|
||||
..()
|
||||
|
||||
//ported from TG
|
||||
/datum/brain_trauma/severe/hypnotic_stupor
|
||||
name = "Hypnotic Stupor"
|
||||
desc = "Patient is prone to episodes of extreme stupor that leaves them extremely suggestible."
|
||||
scan_desc = "oneiric feedback loop"
|
||||
gain_text = "<span class='warning'>You feel somewhat dazed.</span>"
|
||||
lose_text = "<span class='notice'>You feel like a fog was lifted from your mind.</span>"
|
||||
|
||||
/datum/brain_trauma/severe/hypnotic_stupor/on_lose() //hypnosis must be cleared separately, but brain surgery should get rid of both anyway
|
||||
..()
|
||||
owner.remove_status_effect(/datum/status_effect/trance)
|
||||
|
||||
/datum/brain_trauma/severe/hypnotic_stupor/on_life()
|
||||
..()
|
||||
if(prob(1) && !owner.has_status_effect(/datum/status_effect/trance))
|
||||
owner.apply_status_effect(/datum/status_effect/trance, rand(100,300), FALSE)
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
var/list/mob/dead/observer/candidates = pollCandidatesForMob("Do you want to play as [owner]'s split personality?", ROLE_PAI, null, null, 75, stranger_backseat)
|
||||
if(LAZYLEN(candidates))
|
||||
var/mob/dead/observer/C = pick(candidates)
|
||||
stranger_backseat.key = C.key
|
||||
C.transfer_ckey(stranger_backseat, FALSE)
|
||||
log_game("[key_name(stranger_backseat)] became [key_name(owner)]'s split personality.")
|
||||
message_admins("[ADMIN_LOOKUPFLW(stranger_backseat)] became [ADMIN_LOOKUPFLW(owner)]'s split personality.")
|
||||
else
|
||||
@@ -184,7 +184,7 @@
|
||||
var/list/mob/dead/observer/candidates = pollCandidatesForMob("Do you want to play as [owner]'s brainwashed mind?", null, null, null, 75, stranger_backseat)
|
||||
if(LAZYLEN(candidates))
|
||||
var/mob/dead/observer/C = pick(candidates)
|
||||
stranger_backseat.key = C.key
|
||||
C.transfer_ckey(stranger_backseat, FALSE)
|
||||
else
|
||||
qdel(src)
|
||||
|
||||
|
||||
@@ -37,9 +37,9 @@
|
||||
if(O.status == BODYPART_ROBOTIC)
|
||||
return
|
||||
|
||||
var/feetCover = (H.wear_suit && (H.wear_suit.body_parts_covered & FEET)) || (H.w_uniform && (H.w_uniform.body_parts_covered & FEET))
|
||||
var/feetCover = (H.wear_suit && (H.wear_suit.body_parts_covered & FEET)) || (H.w_uniform && (H.w_uniform.body_parts_covered & FEET) || (H.shoes && (H.shoes.body_parts_covered & FEET)))
|
||||
|
||||
if(!(flags & CALTROP_BYPASS_SHOES) && (H.shoes || feetCover))
|
||||
if(!(flags & CALTROP_BYPASS_SHOES) && feetCover)
|
||||
return
|
||||
|
||||
if((H.movement_type & FLYING) || H.buckled)
|
||||
|
||||
@@ -26,5 +26,5 @@
|
||||
if(!HAS_TRAIT(wearer, TRAIT_DEAF))
|
||||
var/obj/item/organ/ears/ears = wearer.getorganslot(ORGAN_SLOT_EARS)
|
||||
if (ears)
|
||||
ears.deaf = max(ears.deaf - 1, (ears.ear_damage < UNHEALING_EAR_DAMAGE ? 0 : 1)) // Do not clear deafness while above the unhealing ear damage threshold
|
||||
ears.ear_damage = max(ears.ear_damage - 0.1, 0)
|
||||
ears.deaf = max(ears.deaf - 1, (ears.damage < ears.maxHealth ? 0 : 1)) // Do not clear deafness if our ears are too damaged
|
||||
ears.damage = max(ears.damage - 0.1, 0)
|
||||
|
||||
+107
-104
@@ -1,105 +1,108 @@
|
||||
/datum/component/footstep
|
||||
var/steps = 0
|
||||
var/volume
|
||||
var/e_range
|
||||
|
||||
/datum/component/footstep/Initialize(volume_ = 0.5, e_range_ = -1)
|
||||
if(!isliving(parent))
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
volume = volume_
|
||||
e_range = e_range_
|
||||
RegisterSignal(parent, list(COMSIG_MOVABLE_MOVED), .proc/play_footstep)
|
||||
|
||||
/datum/component/footstep/proc/play_footstep()
|
||||
var/turf/open/T = get_turf(parent)
|
||||
if(!istype(T))
|
||||
return
|
||||
|
||||
var/mob/living/LM = parent
|
||||
var/v = volume
|
||||
var/e = e_range
|
||||
if(!T.footstep || LM.buckled || LM.lying || !LM.canmove || LM.resting || LM.buckled || LM.throwing || LM.movement_type & (VENTCRAWLING | FLYING))
|
||||
if (LM.lying && !(!T.footstep || LM.movement_type & (VENTCRAWLING | FLYING))) //play crawling sound if we're lying
|
||||
playsound(T, 'sound/effects/footstep/crawl1.ogg', 15 * v)
|
||||
return
|
||||
|
||||
if(iscarbon(LM))
|
||||
var/mob/living/carbon/C = LM
|
||||
if(!C.get_bodypart(BODY_ZONE_L_LEG) && !C.get_bodypart(BODY_ZONE_R_LEG))
|
||||
return
|
||||
if(ishuman(C) && C.m_intent == MOVE_INTENT_WALK)
|
||||
v /= 2
|
||||
e -= 5
|
||||
steps++
|
||||
|
||||
if(steps >= 3)
|
||||
steps = 0
|
||||
|
||||
else
|
||||
return
|
||||
|
||||
if(prob(80) && !LM.has_gravity(T)) // don't need to step as often when you hop around
|
||||
return
|
||||
|
||||
//begin playsound shenanigans//
|
||||
|
||||
//for barefooted non-clawed mobs like monkeys
|
||||
if(isbarefoot(LM))
|
||||
playsound(T, pick(GLOB.barefootstep[T.barefootstep][1]),
|
||||
GLOB.barefootstep[T.barefootstep][2] * v,
|
||||
TRUE,
|
||||
GLOB.barefootstep[T.barefootstep][3] + e)
|
||||
return
|
||||
|
||||
//for xenomorphs, dogs, and other clawed mobs
|
||||
if(isclawfoot(LM))
|
||||
if(isalienadult(LM)) //xenos are stealthy and get quieter footsteps
|
||||
v /= 3
|
||||
e -= 5
|
||||
|
||||
playsound(T, pick(GLOB.clawfootstep[T.clawfootstep][1]),
|
||||
GLOB.clawfootstep[T.clawfootstep][2] * v,
|
||||
TRUE,
|
||||
GLOB.clawfootstep[T.clawfootstep][3] + e)
|
||||
return
|
||||
|
||||
//for megafauna and other large and imtimidating mobs such as the bloodminer
|
||||
if(isheavyfoot(LM))
|
||||
playsound(T, pick(GLOB.heavyfootstep[T.heavyfootstep][1]),
|
||||
GLOB.heavyfootstep[T.heavyfootstep][2] * v,
|
||||
TRUE,
|
||||
GLOB.heavyfootstep[T.heavyfootstep][3] + e)
|
||||
return
|
||||
|
||||
//for slimes
|
||||
if(isslime(LM))
|
||||
playsound(T, 'sound/effects/footstep/slime1.ogg', 15 * v)
|
||||
return
|
||||
|
||||
//for (simple) humanoid mobs (clowns, russians, pirates, etc.)
|
||||
if(isshoefoot(LM))
|
||||
if(!ishuman(LM))
|
||||
playsound(T, pick(GLOB.footstep[T.footstep][1]),
|
||||
GLOB.footstep[T.footstep][2] * v,
|
||||
TRUE,
|
||||
GLOB.footstep[T.footstep][3] + e)
|
||||
return
|
||||
if(ishuman(LM)) //for proper humans, they're special
|
||||
var/mob/living/carbon/human/H = LM
|
||||
var/feetCover = (H.wear_suit && (H.wear_suit.body_parts_covered & FEET)) || (H.w_uniform && (H.w_uniform.body_parts_covered & FEET))
|
||||
|
||||
if (H.dna.features["taur"] == "Naga" || H.dna.features["taur"] == "Tentacle") //are we a naga or tentacle taur creature
|
||||
playsound(T, 'sound/effects/footstep/crawl1.ogg', 15 * v)
|
||||
return
|
||||
|
||||
if(H.shoes || feetCover) //are we wearing shoes
|
||||
playsound(T, pick(GLOB.footstep[T.footstep][1]),
|
||||
GLOB.footstep[T.footstep][2] * v,
|
||||
TRUE,
|
||||
GLOB.footstep[T.footstep][3] + e)
|
||||
|
||||
if((!H.shoes && !feetCover)) //are we NOT wearing shoes
|
||||
playsound(T, pick(GLOB.barefootstep[T.barefootstep][1]),
|
||||
GLOB.barefootstep[T.barefootstep][2] * v,
|
||||
TRUE,
|
||||
/datum/component/footstep
|
||||
var/steps = 0
|
||||
var/volume
|
||||
var/e_range
|
||||
|
||||
/datum/component/footstep/Initialize(volume_ = 0.5, e_range_ = -1)
|
||||
if(!isliving(parent))
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
volume = volume_
|
||||
e_range = e_range_
|
||||
RegisterSignal(parent, list(COMSIG_MOVABLE_MOVED), .proc/play_footstep)
|
||||
|
||||
/datum/component/footstep/proc/play_footstep()
|
||||
var/turf/open/T = get_turf(parent)
|
||||
if(!istype(T))
|
||||
return
|
||||
|
||||
var/mob/living/LM = parent
|
||||
var/v = volume
|
||||
var/e = e_range
|
||||
if(!T.footstep || LM.buckled || LM.lying || !LM.canmove || LM.resting || LM.buckled || LM.throwing || LM.movement_type & (VENTCRAWLING | FLYING))
|
||||
if (LM.lying && !LM.buckled && !(!T.footstep || LM.movement_type & (VENTCRAWLING | FLYING))) //play crawling sound if we're lying
|
||||
playsound(T, 'sound/effects/footstep/crawl1.ogg', 15 * v)
|
||||
return
|
||||
|
||||
if(HAS_TRAIT(LM, TRAIT_SILENT_STEP))
|
||||
return
|
||||
|
||||
if(iscarbon(LM))
|
||||
var/mob/living/carbon/C = LM
|
||||
if(!C.get_bodypart(BODY_ZONE_L_LEG) && !C.get_bodypart(BODY_ZONE_R_LEG))
|
||||
return
|
||||
if(ishuman(C) && C.m_intent == MOVE_INTENT_WALK)
|
||||
v /= 2
|
||||
e -= 5
|
||||
steps++
|
||||
|
||||
if(steps >= 3)
|
||||
steps = 0
|
||||
|
||||
else
|
||||
return
|
||||
|
||||
if(prob(80) && !LM.has_gravity(T)) // don't need to step as often when you hop around
|
||||
return
|
||||
|
||||
//begin playsound shenanigans//
|
||||
|
||||
//for barefooted non-clawed mobs like monkeys
|
||||
if(isbarefoot(LM))
|
||||
playsound(T, pick(GLOB.barefootstep[T.barefootstep][1]),
|
||||
GLOB.barefootstep[T.barefootstep][2] * v,
|
||||
TRUE,
|
||||
GLOB.barefootstep[T.barefootstep][3] + e)
|
||||
return
|
||||
|
||||
//for xenomorphs, dogs, and other clawed mobs
|
||||
if(isclawfoot(LM))
|
||||
if(isalienadult(LM)) //xenos are stealthy and get quieter footsteps
|
||||
v /= 3
|
||||
e -= 5
|
||||
|
||||
playsound(T, pick(GLOB.clawfootstep[T.clawfootstep][1]),
|
||||
GLOB.clawfootstep[T.clawfootstep][2] * v,
|
||||
TRUE,
|
||||
GLOB.clawfootstep[T.clawfootstep][3] + e)
|
||||
return
|
||||
|
||||
//for megafauna and other large and imtimidating mobs such as the bloodminer
|
||||
if(isheavyfoot(LM))
|
||||
playsound(T, pick(GLOB.heavyfootstep[T.heavyfootstep][1]),
|
||||
GLOB.heavyfootstep[T.heavyfootstep][2] * v,
|
||||
TRUE,
|
||||
GLOB.heavyfootstep[T.heavyfootstep][3] + e)
|
||||
return
|
||||
|
||||
//for slimes
|
||||
if(isslime(LM))
|
||||
playsound(T, 'sound/effects/footstep/slime1.ogg', 15 * v)
|
||||
return
|
||||
|
||||
//for (simple) humanoid mobs (clowns, russians, pirates, etc.)
|
||||
if(isshoefoot(LM))
|
||||
if(!ishuman(LM))
|
||||
playsound(T, pick(GLOB.footstep[T.footstep][1]),
|
||||
GLOB.footstep[T.footstep][2] * v,
|
||||
TRUE,
|
||||
GLOB.footstep[T.footstep][3] + e)
|
||||
return
|
||||
if(ishuman(LM)) //for proper humans, they're special
|
||||
var/mob/living/carbon/human/H = LM
|
||||
var/feetCover = (H.wear_suit && (H.wear_suit.body_parts_covered & FEET)) || (H.w_uniform && (H.w_uniform.body_parts_covered & FEET) || (H.shoes && (H.shoes.body_parts_covered & FEET)))
|
||||
|
||||
if (H.dna.features["taur"] == "Naga" || H.dna.features["taur"] == "Tentacle") //are we a naga or tentacle taur creature
|
||||
playsound(T, 'sound/effects/footstep/crawl1.ogg', 15 * v)
|
||||
return
|
||||
|
||||
if(feetCover) //are we wearing shoes
|
||||
playsound(T, pick(GLOB.footstep[T.footstep][1]),
|
||||
GLOB.footstep[T.footstep][2] * v,
|
||||
TRUE,
|
||||
GLOB.footstep[T.footstep][3] + e)
|
||||
|
||||
if(!feetCover) //are we NOT wearing shoes
|
||||
playsound(T, pick(GLOB.barefootstep[T.barefootstep][1]),
|
||||
GLOB.barefootstep[T.barefootstep][2] * v,
|
||||
TRUE,
|
||||
GLOB.barefootstep[T.barefootstep][3] + e)
|
||||
@@ -6,6 +6,7 @@
|
||||
var/sanity = 100 //Current sanity
|
||||
var/shown_mood //Shown happiness, this is what others can see when they try to examine you, prevents antag checking by noticing traitors are always very happy.
|
||||
var/mood_level = 5 //To track what stage of moodies they're on
|
||||
var/sanity_level = 5 //To track what stage of sanity they're on
|
||||
var/mood_modifier = 1 //Modifier to allow certain mobs to be less affected by moodlets
|
||||
var/datum/mood_event/list/mood_events = list()
|
||||
var/insanity_effect = 0 //is the owner being punished for low mood? If so, how much?
|
||||
@@ -20,6 +21,8 @@
|
||||
|
||||
RegisterSignal(parent, COMSIG_ADD_MOOD_EVENT, .proc/add_event)
|
||||
RegisterSignal(parent, COMSIG_CLEAR_MOOD_EVENT, .proc/clear_event)
|
||||
RegisterSignal(parent, COMSIG_INCREASE_SANITY, .proc/IncreaseSanity)
|
||||
RegisterSignal(parent, COMSIG_DECREASE_SANITY, .proc/DecreaseSanity)
|
||||
|
||||
RegisterSignal(parent, COMSIG_MOB_HUD_CREATED, .proc/modify_hud)
|
||||
var/mob/living/owner = parent
|
||||
@@ -118,6 +121,8 @@
|
||||
if(owner.client && owner.hud_used)
|
||||
if(sanity < 25)
|
||||
screen_obj.icon_state = "mood_insane"
|
||||
else if (owner.has_status_effect(/datum/status_effect/chem/enthrall))//Fermichem enthral chem, maybe change?
|
||||
screen_obj.icon_state = "mood_entrance"
|
||||
else
|
||||
screen_obj.icon_state = "mood[mood_level]"
|
||||
|
||||
@@ -126,23 +131,23 @@
|
||||
|
||||
switch(mood_level)
|
||||
if(1)
|
||||
DecreaseSanity(0.2)
|
||||
DecreaseSanity(src, 0.2)
|
||||
if(2)
|
||||
DecreaseSanity(0.125, SANITY_CRAZY)
|
||||
DecreaseSanity(src, 0.125, SANITY_CRAZY)
|
||||
if(3)
|
||||
DecreaseSanity(0.075, SANITY_UNSTABLE)
|
||||
DecreaseSanity(src, 0.075, SANITY_UNSTABLE)
|
||||
if(4)
|
||||
DecreaseSanity(0.025, SANITY_DISTURBED)
|
||||
DecreaseSanity(src, 0.025, SANITY_DISTURBED)
|
||||
if(5)
|
||||
IncreaseSanity(0.1)
|
||||
IncreaseSanity(src, 0.1)
|
||||
if(6)
|
||||
IncreaseSanity(0.15)
|
||||
IncreaseSanity(src, 0.15)
|
||||
if(7)
|
||||
IncreaseSanity(0.20)
|
||||
IncreaseSanity(src, 0.20)
|
||||
if(8)
|
||||
IncreaseSanity(0.25, SANITY_GREAT)
|
||||
IncreaseSanity(src, 0.25, SANITY_GREAT)
|
||||
if(9)
|
||||
IncreaseSanity(0.4, SANITY_GREAT)
|
||||
IncreaseSanity(src, 0.4, SANITY_GREAT)
|
||||
|
||||
if(insanity_effect != holdmyinsanityeffect)
|
||||
if(insanity_effect > holdmyinsanityeffect)
|
||||
@@ -163,9 +168,61 @@
|
||||
|
||||
HandleNutrition(owner)
|
||||
|
||||
/datum/component/mood/proc/DecreaseSanity(amount, minimum = SANITY_INSANE)
|
||||
/datum/component/mood/proc/setSanity(amount, minimum=SANITY_INSANE, maximum=SANITY_NEUTRAL)//I'm sure bunging this in here will have no negative repercussions.
|
||||
var/mob/living/master = parent
|
||||
|
||||
if(amount == sanity)
|
||||
return
|
||||
// If we're out of the acceptable minimum-maximum range move back towards it in steps of 0.5
|
||||
// If the new amount would move towards the acceptable range faster then use it instead
|
||||
if(sanity < minimum && amount < sanity + 0.5)
|
||||
amount = sanity + 0.5
|
||||
else if(sanity > maximum && amount > sanity - 0.5)
|
||||
amount = sanity - 0.5
|
||||
|
||||
// Disturbed stops you from getting any more sane
|
||||
if(HAS_TRAIT(master, TRAIT_UNSTABLE))
|
||||
sanity = min(amount,sanity)
|
||||
else
|
||||
sanity = amount
|
||||
|
||||
switch(sanity)
|
||||
if(SANITY_INSANE to SANITY_CRAZY)
|
||||
setInsanityEffect(MAJOR_INSANITY_PEN)
|
||||
master.add_movespeed_modifier(MOVESPEED_ID_SANITY, TRUE, 100, override=TRUE, multiplicative_slowdown=1.5) //Did we change something ? movetypes is runtiming, movetypes=(~FLYING))
|
||||
sanity_level = 6
|
||||
if(SANITY_CRAZY to SANITY_UNSTABLE)
|
||||
setInsanityEffect(MINOR_INSANITY_PEN)
|
||||
master.add_movespeed_modifier(MOVESPEED_ID_SANITY, TRUE, 100, override=TRUE, multiplicative_slowdown=1)//, movetypes=(~FLYING))
|
||||
sanity_level = 5
|
||||
if(SANITY_UNSTABLE to SANITY_DISTURBED)
|
||||
setInsanityEffect(0)
|
||||
master.add_movespeed_modifier(MOVESPEED_ID_SANITY, TRUE, 100, override=TRUE, multiplicative_slowdown=0.5)//, movetypes=(~FLYING))
|
||||
sanity_level = 4
|
||||
if(SANITY_DISTURBED to SANITY_NEUTRAL)
|
||||
setInsanityEffect(0)
|
||||
master.remove_movespeed_modifier(MOVESPEED_ID_SANITY, TRUE)
|
||||
sanity_level = 3
|
||||
if(SANITY_NEUTRAL+1 to SANITY_GREAT+1) //shitty hack but +1 to prevent it from responding to super small differences
|
||||
setInsanityEffect(0)
|
||||
master.remove_movespeed_modifier(MOVESPEED_ID_SANITY, TRUE)
|
||||
sanity_level = 2
|
||||
if(SANITY_GREAT+1 to INFINITY)
|
||||
setInsanityEffect(0)
|
||||
master.remove_movespeed_modifier(MOVESPEED_ID_SANITY, TRUE)
|
||||
sanity_level = 1
|
||||
//update_mood_icon()
|
||||
|
||||
/datum/component/mood/proc/setInsanityEffect(newval)//More code so that the previous proc works
|
||||
if(newval == insanity_effect)
|
||||
return
|
||||
var/mob/living/master = parent
|
||||
master.crit_threshold = (master.crit_threshold - insanity_effect) + newval
|
||||
insanity_effect = newval
|
||||
|
||||
/datum/component/mood/proc/DecreaseSanity(datum/source, amount, minimum = SANITY_INSANE)
|
||||
if(sanity < minimum) //This might make KevinZ stop fucking pinging me.
|
||||
IncreaseSanity(0.5)
|
||||
IncreaseSanity(src, 0.5)
|
||||
else
|
||||
sanity = max(minimum, sanity - amount)
|
||||
if(sanity < SANITY_UNSTABLE)
|
||||
@@ -174,9 +231,13 @@
|
||||
else
|
||||
insanity_effect = (MINOR_INSANITY_PEN)
|
||||
|
||||
/datum/component/mood/proc/IncreaseSanity(amount, maximum = SANITY_NEUTRAL)
|
||||
/datum/component/mood/proc/IncreaseSanity(datum/source, amount, maximum = SANITY_NEUTRAL)
|
||||
// Disturbed stops you from getting any more sane - I'm just gonna bung this in here
|
||||
var/mob/living/owner = parent
|
||||
if(HAS_TRAIT(owner, TRAIT_UNSTABLE))
|
||||
return
|
||||
if(sanity > maximum)
|
||||
DecreaseSanity(0.5) //Removes some sanity to go back to our current limit.
|
||||
DecreaseSanity(src, 0.5) //Removes some sanity to go back to our current limit.
|
||||
else
|
||||
sanity = min(maximum, sanity + amount)
|
||||
if(sanity > SANITY_CRAZY)
|
||||
@@ -195,7 +256,7 @@
|
||||
if(the_event.timeout)
|
||||
addtimer(CALLBACK(src, .proc/clear_event, null, category), the_event.timeout, TIMER_UNIQUE|TIMER_OVERRIDE)
|
||||
return 0 //Don't have to update the event.
|
||||
the_event = new type(src, param)
|
||||
the_event = new type(src, param)//This causes a runtime for some reason, was this me? No - there's an event floating around missing a definition.
|
||||
|
||||
mood_events[category] = the_event
|
||||
update_mood()
|
||||
@@ -203,6 +264,8 @@
|
||||
if(the_event.timeout)
|
||||
addtimer(CALLBACK(src, .proc/clear_event, null, category), the_event.timeout, TIMER_UNIQUE|TIMER_OVERRIDE)
|
||||
|
||||
return the_event
|
||||
|
||||
/datum/component/mood/proc/clear_event(datum/source, category)
|
||||
var/datum/mood_event/event = mood_events[category]
|
||||
if(!event)
|
||||
|
||||
@@ -162,12 +162,12 @@
|
||||
if(!Process_Spacemove(direction) || !isturf(AM.loc))
|
||||
return
|
||||
step(AM, direction)
|
||||
|
||||
|
||||
if((direction & (direction - 1)) && (AM.loc == next)) //moved diagonally
|
||||
last_move_diagonal = TRUE
|
||||
else
|
||||
last_move_diagonal = FALSE
|
||||
|
||||
|
||||
handle_vehicle_layer()
|
||||
handle_vehicle_offsets()
|
||||
else
|
||||
@@ -195,21 +195,47 @@
|
||||
. = ..()
|
||||
RegisterSignal(parent, COMSIG_HUMAN_MELEE_UNARMED_ATTACK, .proc/on_host_unarmed_melee)
|
||||
|
||||
/datum/component/riding/human/vehicle_mob_unbuckle(datum/source, mob/living/M, force = FALSE)
|
||||
var/mob/living/carbon/human/H = parent
|
||||
H.remove_movespeed_modifier(MOVESPEED_ID_HUMAN_CARRYING)
|
||||
. = ..()
|
||||
|
||||
/datum/component/riding/human/vehicle_mob_buckle(datum/source, mob/living/M, force = FALSE)
|
||||
. = ..()
|
||||
var/mob/living/carbon/human/H = parent
|
||||
H.add_movespeed_modifier(MOVESPEED_ID_HUMAN_CARRYING, multiplicative_slowdown = HUMAN_CARRY_SLOWDOWN)
|
||||
|
||||
/datum/component/riding/human/proc/on_host_unarmed_melee(atom/target)
|
||||
var/mob/living/carbon/human/AM = parent
|
||||
if(AM.a_intent == INTENT_DISARM && (target in AM.buckled_mobs))
|
||||
var/mob/living/carbon/human/H = parent
|
||||
if(H.a_intent == INTENT_DISARM && (target in H.buckled_mobs))
|
||||
force_dismount(target)
|
||||
|
||||
/datum/component/riding/human/handle_vehicle_layer()
|
||||
var/atom/movable/AM = parent
|
||||
if(AM.buckled_mobs && AM.buckled_mobs.len)
|
||||
if(AM.dir == SOUTH)
|
||||
AM.layer = ABOVE_MOB_LAYER
|
||||
for(var/mob/M in AM.buckled_mobs) //ensure proper layering of piggyback and carry, sometimes weird offsets get applied
|
||||
M.layer = MOB_LAYER
|
||||
if(!AM.buckle_lying)
|
||||
if(AM.dir == SOUTH)
|
||||
AM.layer = ABOVE_MOB_LAYER
|
||||
else
|
||||
AM.layer = OBJ_LAYER
|
||||
else
|
||||
AM.layer = OBJ_LAYER
|
||||
if(AM.dir == NORTH)
|
||||
AM.layer = OBJ_LAYER
|
||||
else
|
||||
AM.layer = ABOVE_MOB_LAYER
|
||||
else
|
||||
AM.layer = MOB_LAYER
|
||||
|
||||
/datum/component/riding/human/get_offsets(pass_index)
|
||||
var/mob/living/carbon/human/H = parent
|
||||
if(H.buckle_lying)
|
||||
return list(TEXT_NORTH = list(0, 6), TEXT_SOUTH = list(0, 6), TEXT_EAST = list(0, 6), TEXT_WEST = list(0, 6))
|
||||
else
|
||||
return list(TEXT_NORTH = list(0, 6), TEXT_SOUTH = list(0, 6), TEXT_EAST = list(-6, 4), TEXT_WEST = list( 6, 4))
|
||||
|
||||
|
||||
/datum/component/riding/human/force_dismount(mob/living/user)
|
||||
var/atom/movable/AM = parent
|
||||
AM.unbuckle_mob(user)
|
||||
@@ -273,12 +299,15 @@
|
||||
M.throw_at(target, 14, 5, AM)
|
||||
M.Knockdown(60)
|
||||
|
||||
/datum/component/riding/proc/equip_buckle_inhands(mob/living/carbon/human/user, amount_required = 1)
|
||||
/datum/component/riding/proc/equip_buckle_inhands(mob/living/carbon/human/user, amount_required = 1, riding_target_override = null)
|
||||
var/atom/movable/AM = parent
|
||||
var/amount_equipped = 0
|
||||
for(var/amount_needed = amount_required, amount_needed > 0, amount_needed--)
|
||||
var/obj/item/riding_offhand/inhand = new /obj/item/riding_offhand(user)
|
||||
inhand.rider = user
|
||||
if(!riding_target_override)
|
||||
inhand.rider = user
|
||||
else
|
||||
inhand.rider = riding_target_override
|
||||
inhand.parent = AM
|
||||
if(user.put_in_hands(inhand, TRUE))
|
||||
amount_equipped++
|
||||
@@ -318,7 +347,7 @@
|
||||
. = ..()
|
||||
|
||||
/obj/item/riding_offhand/equipped()
|
||||
if(loc != rider)
|
||||
if(loc != rider && loc != parent)
|
||||
selfdeleting = TRUE
|
||||
qdel(src)
|
||||
. = ..()
|
||||
|
||||
@@ -36,3 +36,4 @@
|
||||
/datum/component/storage/concrete/emergency/proc/unlock_me(datum/source)
|
||||
if(locked)
|
||||
set_locked(source, FALSE)
|
||||
return TRUE
|
||||
|
||||
@@ -52,18 +52,18 @@
|
||||
. = ..()
|
||||
cant_hold = typecacheof(list(/obj/item/screwdriver/power))
|
||||
can_hold = typecacheof(list(
|
||||
/obj/item/kitchen/knife, /obj/item/switchblade, /obj/item/pen,
|
||||
/obj/item/kitchen/knife, /obj/item/switchblade, /obj/item/pen, /obj/item/melee/cultblade/dagger,
|
||||
/obj/item/scalpel, /obj/item/reagent_containers/syringe, /obj/item/dnainjector,
|
||||
/obj/item/reagent_containers/hypospray/medipen, /obj/item/reagent_containers/dropper,
|
||||
/obj/item/implanter, /obj/item/screwdriver, /obj/item/weldingtool/mini,
|
||||
/obj/item/firing_pin
|
||||
/obj/item/firing_pin, /obj/item/gun/ballistic/automatic/pistol/mag
|
||||
))
|
||||
|
||||
/datum/component/storage/concrete/pockets/shoes/clown/Initialize()
|
||||
. = ..()
|
||||
cant_hold = typecacheof(list(/obj/item/screwdriver/power))
|
||||
can_hold = typecacheof(list(
|
||||
/obj/item/kitchen/knife, /obj/item/switchblade, /obj/item/pen,
|
||||
/obj/item/kitchen/knife, /obj/item/switchblade, /obj/item/pen, /obj/item/melee/cultblade/dagger,
|
||||
/obj/item/scalpel, /obj/item/reagent_containers/syringe, /obj/item/dnainjector,
|
||||
/obj/item/reagent_containers/hypospray/medipen, /obj/item/reagent_containers/dropper,
|
||||
/obj/item/implanter, /obj/item/screwdriver, /obj/item/weldingtool/mini,
|
||||
|
||||
@@ -234,7 +234,7 @@
|
||||
|
||||
/datum/component/storage/proc/quick_empty(mob/M)
|
||||
var/atom/A = parent
|
||||
if((!ishuman(M) && (A.loc != M)) || (M.stat != CONSCIOUS) || M.restrained() || !M.canmove)
|
||||
if(!M.canUseStorage() || !A.Adjacent(M) || M.incapacitated())
|
||||
return
|
||||
if(check_locked(null, M, TRUE))
|
||||
return FALSE
|
||||
|
||||
@@ -24,8 +24,9 @@ GLOBAL_LIST_EMPTY(uplinks)
|
||||
var/unlock_note
|
||||
var/unlock_code
|
||||
var/failsafe_code
|
||||
var/datum/ui_state/checkstate
|
||||
|
||||
/datum/component/uplink/Initialize(_owner, _lockable = TRUE, _enabled = FALSE, datum/game_mode/_gamemode, starting_tc = 20)
|
||||
/datum/component/uplink/Initialize(_owner, _lockable = TRUE, _enabled = FALSE, datum/game_mode/_gamemode, starting_tc = 20, datum/ui_state/_checkstate)
|
||||
if(!isitem(parent))
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
|
||||
@@ -57,6 +58,7 @@ GLOBAL_LIST_EMPTY(uplinks)
|
||||
active = _enabled
|
||||
gamemode = _gamemode
|
||||
telecrystals = starting_tc
|
||||
checkstate = _checkstate
|
||||
if(!lockable)
|
||||
active = TRUE
|
||||
locked = FALSE
|
||||
@@ -115,6 +117,7 @@ GLOBAL_LIST_EMPTY(uplinks)
|
||||
|
||||
/datum/component/uplink/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
|
||||
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.inventory_state)
|
||||
state = checkstate ? checkstate : state
|
||||
active = TRUE
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
@@ -123,6 +126,12 @@ GLOBAL_LIST_EMPTY(uplinks)
|
||||
ui.set_style("syndicate")
|
||||
ui.open()
|
||||
|
||||
/datum/component/uplink/ui_host(mob/user)
|
||||
if(istype(parent, /obj/item/implant)) //implants are like organs, not really located inside mobs codewise.
|
||||
var/obj/item/implant/I = parent
|
||||
return I.imp_in
|
||||
return ..()
|
||||
|
||||
/datum/component/uplink/ui_data(mob/user)
|
||||
if(!user.mind)
|
||||
return
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
/datum/component/virtual_reality
|
||||
dupe_mode = COMPONENT_DUPE_ALLOWED //mindswap memes, shouldn't stack up otherwise.
|
||||
var/datum/mind/mastermind // where is my mind t. pixies
|
||||
var/datum/mind/current_mind
|
||||
var/obj/machinery/vr_sleeper/vr_sleeper
|
||||
var/datum/action/quit_vr/quit_action
|
||||
var/you_die_in_the_game_you_die_for_real = FALSE
|
||||
var/datum/component/virtual_reality/inception //The component works on a very fragile link betwixt mind, ckey and death.
|
||||
|
||||
/datum/component/virtual_reality/Initialize(mob/M, obj/machinery/vr_sleeper/gaming_pod, yolo = FALSE, new_char = TRUE)
|
||||
if(!ismob(parent) || !istype(M))
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
var/mob/vr_M = parent
|
||||
mastermind = M.mind
|
||||
RegisterSignal(M, list(COMSIG_MOB_DEATH, COMSIG_PARENT_QDELETED), .proc/game_over)
|
||||
RegisterSignal(M, COMSIG_MOB_KEY_CHANGE, .proc/switch_player)
|
||||
RegisterSignal(mastermind, COMSIG_MIND_TRANSFER, .proc/switch_player)
|
||||
you_die_in_the_game_you_die_for_real = yolo
|
||||
quit_action = new()
|
||||
if(gaming_pod)
|
||||
vr_sleeper = gaming_pod
|
||||
RegisterSignal(vr_sleeper, COMSIG_ATOM_EMAG_ACT, .proc/you_only_live_once)
|
||||
RegisterSignal(vr_sleeper, COMSIG_MACHINE_EJECT_OCCUPANT, .proc/revert_to_reality)
|
||||
vr_M.ckey = M.ckey
|
||||
var/datum/component/virtual_reality/clusterfk = M.GetComponent(/datum/component/virtual_reality)
|
||||
if(clusterfk && !clusterfk.inception)
|
||||
clusterfk.inception = src
|
||||
SStgui.close_user_uis(M, src)
|
||||
|
||||
/datum/component/virtual_reality/RegisterWithParent()
|
||||
var/mob/M = parent
|
||||
current_mind = M.mind
|
||||
quit_action.Grant(M)
|
||||
RegisterSignal(quit_action, COMSIG_ACTION_TRIGGER, .proc/revert_to_reality)
|
||||
RegisterSignal(M, list(COMSIG_MOB_DEATH, COMSIG_PARENT_QDELETED), .proc/game_over)
|
||||
RegisterSignal(M, COMSIG_MOB_GHOSTIZE, .proc/be_a_quitter)
|
||||
RegisterSignal(M, COMSIG_MOB_KEY_CHANGE, .proc/pass_me_the_remote)
|
||||
RegisterSignal(current_mind, COMSIG_MIND_TRANSFER, .proc/pass_me_the_remote)
|
||||
mastermind.current.audiovisual_redirect = M
|
||||
if(vr_sleeper)
|
||||
vr_sleeper.vr_mob = M
|
||||
|
||||
/datum/component/virtual_reality/UnregisterFromParent()
|
||||
quit_action.Remove(parent)
|
||||
UnregisterSignal(parent, list(COMSIG_MOB_DEATH, COMSIG_PARENT_QDELETED, COMSIG_MOB_KEY_CHANGE, COMSIG_MOB_GHOSTIZE))
|
||||
UnregisterSignal(current_mind, COMSIG_MIND_TRANSFER)
|
||||
UnregisterSignal(quit_action, COMSIG_ACTION_TRIGGER)
|
||||
current_mind = null
|
||||
mastermind.current.audiovisual_redirect = null
|
||||
|
||||
/datum/component/virtual_reality/proc/switch_player(datum/source, mob/new_mob, mob/old_mob)
|
||||
if(vr_sleeper || !new_mob.mind)
|
||||
// Machineries currently don't deal up with the occupant being polymorphed et similar... Or did something fuck up?
|
||||
revert_to_reality()
|
||||
return
|
||||
old_mob.audiovisual_redirect = null
|
||||
new_mob.audiovisual_redirect = parent
|
||||
|
||||
/datum/component/virtual_reality/proc/action_trigger(datum/signal_source, datum/action/source)
|
||||
if(source != quit_action)
|
||||
return COMPONENT_ACTION_BLOCK_TRIGGER
|
||||
revert_to_reality(signal_source)
|
||||
|
||||
/datum/component/virtual_reality/proc/you_only_live_once()
|
||||
if(you_die_in_the_game_you_die_for_real || vr_sleeper?.only_current_user_can_interact)
|
||||
return FALSE
|
||||
you_die_in_the_game_you_die_for_real = TRUE
|
||||
return TRUE
|
||||
|
||||
/datum/component/virtual_reality/proc/pass_me_the_remote(datum/source, mob/new_mob)
|
||||
if(new_mob == mastermind.current)
|
||||
revert_to_reality(source)
|
||||
return TRUE
|
||||
new_mob.TakeComponent(src)
|
||||
return TRUE
|
||||
|
||||
/datum/component/virtual_reality/PostTransfer()
|
||||
if(!ismob(parent))
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
|
||||
/datum/component/virtual_reality/proc/revert_to_reality(datum/source)
|
||||
quit_it()
|
||||
|
||||
/datum/component/virtual_reality/proc/game_over(datum/source)
|
||||
quit_it(TRUE, TRUE)
|
||||
|
||||
/datum/component/virtual_reality/proc/be_a_quitter(datum/source, can_reenter_corpse)
|
||||
quit_it()
|
||||
return COMPONENT_BLOCK_GHOSTING
|
||||
|
||||
/datum/component/virtual_reality/proc/virtual_reality_in_a_virtual_reality(mob/player, killme = FALSE, datum/component/virtual_reality/yo_dawg)
|
||||
var/mob/M = parent
|
||||
quit_it(FALSE, killme, player, yo_dawg)
|
||||
yo_dawg.inception = null
|
||||
if(killme)
|
||||
M.death(FALSE)
|
||||
|
||||
/datum/component/virtual_reality/proc/quit_it(deathcheck = FALSE, cleanup = FALSE, mob/override)
|
||||
var/mob/M = parent
|
||||
var/mob/dreamer = override ? override : mastermind.current
|
||||
if(!mastermind)
|
||||
to_chat(M, "<span class='warning'>You feel a dreadful sensation, something terrible happened. You try to wake up, but you find yourself unable to...</span>")
|
||||
else
|
||||
var/key_transfer = FALSE
|
||||
if(inception?.parent)
|
||||
inception.virtual_reality_in_a_virtual_reality(dreamer, cleanup, src)
|
||||
else
|
||||
key_transfer = TRUE
|
||||
if(key_transfer)
|
||||
M.transfer_ckey(dreamer, FALSE)
|
||||
dreamer.stop_sound_channel(CHANNEL_HEARTBEAT)
|
||||
dreamer.audiovisual_redirect = null
|
||||
if(deathcheck && you_die_in_the_game_you_die_for_real)
|
||||
to_chat(mastermind, "<span class='warning'>You feel everything fading away...</span>")
|
||||
dreamer.death(FALSE)
|
||||
if(cleanup)
|
||||
var/obj/effect/vr_clean_master/cleanbot = locate() in get_area(M)
|
||||
if(cleanbot)
|
||||
LAZYADD(cleanbot.corpse_party, M)
|
||||
if(vr_sleeper)
|
||||
vr_sleeper.vr_mob = null
|
||||
vr_sleeper = null
|
||||
qdel(src)
|
||||
|
||||
/datum/component/virtual_reality/Destroy()
|
||||
var/datum/action/quit_vr/delet_me = quit_action
|
||||
. = ..()
|
||||
qdel(delet_me)
|
||||
@@ -94,10 +94,23 @@
|
||||
TOXIN:<font size='1'><a href='?_src_=vars;[HrefToken()];mobToDamage=[refid];adjustDamage=toxin' id='toxin'>[M.getToxLoss()]</a>
|
||||
OXY:<font size='1'><a href='?_src_=vars;[HrefToken()];mobToDamage=[refid];adjustDamage=oxygen' id='oxygen'>[M.getOxyLoss()]</a>
|
||||
CLONE:<font size='1'><a href='?_src_=vars;[HrefToken()];mobToDamage=[refid];adjustDamage=clone' id='clone'>[M.getCloneLoss()]</a>
|
||||
BRAIN:<font size='1'><a href='?_src_=vars;[HrefToken()];mobToDamage=[refid];adjustDamage=brain' id='brain'>[M.getBrainLoss()]</a>
|
||||
BRAIN:<font size='1'><a href='?_src_=vars;[HrefToken()];mobToDamage=[refid];adjustDamage=brain' id='brain'>[M.getOrganLoss(ORGAN_SLOT_BRAIN)]</a>
|
||||
STAMINA:<font size='1'><a href='?_src_=vars;[HrefToken()];mobToDamage=[refid];adjustDamage=stamina' id='stamina'>[M.getStaminaLoss()]</a>
|
||||
AROUSAL:<font size='1'><a href='?_src_=vars;[HrefToken()];mobToDamage=[refid];adjustDamage=arousal' id='arousal'>[M.getArousalLoss()]</a>
|
||||
</font>
|
||||
"}
|
||||
if(GLOB.Debug2)
|
||||
atomsnowflake += {"
|
||||
HEART:<font size='1'><a href='?_src_=vars;[HrefToken()];mobToDamage=[refid];adjustDamage=heart' id='heart'>[M.getOrganLoss(ORGAN_SLOT_HEART)]</a>
|
||||
LIVER:<font size='1'><a href='?_src_=vars;[HrefToken()];mobToDamage=[refid];adjustDamage=liver' id='liver'>[M.getOrganLoss(ORGAN_SLOT_LIVER)]</a>
|
||||
LUNGS:<font size='1'><a href='?_src_=vars;[HrefToken()];mobToDamage=[refid];adjustDamage=lungs' id='lungs'>[M.getOrganLoss(ORGAN_SLOT_LUNGS)]</a>
|
||||
EYES:<font size='1'><a href='?_src_=vars;[HrefToken()];mobToDamage=[refid];adjustDamage=eye_sight' id='eye_sight'>[M.getOrganLoss(ORGAN_SLOT_EYES)]</a>
|
||||
EARS:<font size='1'><a href='?_src_=vars;[HrefToken()];mobToDamage=[refid];adjustDamage=ears' id='ears'>[M.getOrganLoss(ORGAN_SLOT_EARS)]</a>
|
||||
STOMACH:<font size='1'><a href='?_src_=vars;[HrefToken()];mobToDamage=[refid];adjustDamage=stomach' id='stomach'>[M.getOrganLoss(ORGAN_SLOT_STOMACH)]</a>
|
||||
TONGUE:<font size='1'><a href='?_src_=vars;[HrefToken()];mobToDamage=[refid];adjustDamage=tongue' id='tongue'>[M.getOrganLoss(ORGAN_SLOT_TONGUE)]</a>
|
||||
APPENDIX:<font size='1'><a href='?_src_=vars;[HrefToken()];mobToDamage=[refid];adjustDamage=appendix' id='appendix'>[M.getOrganLoss(ORGAN_SLOT_APPENDIX)]</a>
|
||||
"}
|
||||
atomsnowflake += {"
|
||||
</font>
|
||||
"}
|
||||
else
|
||||
atomsnowflake += "<a href='?_src_=vars;[HrefToken()];datumedit=[refid];varnameedit=name'><b id='name'>[D]</b></a>"
|
||||
@@ -1334,8 +1347,8 @@
|
||||
L.adjustOxyLoss(amount)
|
||||
newamt = L.getOxyLoss()
|
||||
if("brain")
|
||||
L.adjustBrainLoss(amount)
|
||||
newamt = L.getBrainLoss()
|
||||
L.adjustOrganLoss(ORGAN_SLOT_BRAIN, amount)
|
||||
newamt = L.getOrganLoss(ORGAN_SLOT_BRAIN)
|
||||
if("clone")
|
||||
L.adjustCloneLoss(amount)
|
||||
newamt = L.getCloneLoss()
|
||||
@@ -1345,6 +1358,30 @@
|
||||
if("arousal")
|
||||
L.adjustArousalLoss(amount)
|
||||
newamt = L.getArousalLoss()
|
||||
if("heart")
|
||||
L.adjustOrganLoss(ORGAN_SLOT_HEART, amount)
|
||||
newamt = L.getOrganLoss(ORGAN_SLOT_HEART)
|
||||
if("liver")
|
||||
L.adjustOrganLoss(ORGAN_SLOT_LIVER, amount)
|
||||
newamt = L.getOrganLoss(ORGAN_SLOT_LIVER)
|
||||
if("lungs")
|
||||
L.adjustOrganLoss(ORGAN_SLOT_LUNGS, amount)
|
||||
newamt = L.getOrganLoss(ORGAN_SLOT_LUNGS)
|
||||
if("eye_sight")
|
||||
L.adjustOrganLoss(ORGAN_SLOT_EYES, amount)
|
||||
newamt = L.getOrganLoss(ORGAN_SLOT_EYES)
|
||||
if("ears")
|
||||
L.adjustOrganLoss(ORGAN_SLOT_EARS, amount)
|
||||
newamt = L.getOrganLoss(ORGAN_SLOT_EARS)
|
||||
if("stomach")
|
||||
L.adjustOrganLoss(ORGAN_SLOT_STOMACH, amount)
|
||||
newamt = L.getOrganLoss(ORGAN_SLOT_STOMACH)
|
||||
if("tongue")
|
||||
L.adjustOrganLoss(ORGAN_SLOT_TONGUE, amount)
|
||||
newamt = L.getOrganLoss(ORGAN_SLOT_TONGUE)
|
||||
if("appendix")
|
||||
L.adjustOrganLoss(ORGAN_SLOT_APPENDIX, amount)
|
||||
newamt = L.getOrganLoss(ORGAN_SLOT_APPENDIX)
|
||||
else
|
||||
to_chat(usr, "You caused an error. DEBUG: Text:[Text] Mob:[L]")
|
||||
return
|
||||
@@ -1360,4 +1397,4 @@
|
||||
return
|
||||
var/mob/living/carbon/human/H = locate(href_list["copyoutfit"]) in GLOB.carbon_list
|
||||
if(istype(H))
|
||||
H.copy_outfit()
|
||||
H.copy_outfit()
|
||||
|
||||
@@ -144,3 +144,9 @@
|
||||
if(!((locate(thing) in bodyparts) || (locate(thing) in internal_organs)))
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/mob/living/proc/CanSpreadAirborneDisease()
|
||||
return !is_mouth_covered()
|
||||
|
||||
/mob/living/carbon/CanSpreadAirborneDisease()
|
||||
return !((head && (head.flags_cover & HEADCOVERSMOUTH) && (head.armor.getRating("bio") >= 25)) || (wear_mask && (wear_mask.flags_cover & MASKCOVERSMOUTH) && (wear_mask.armor.getRating("bio") >= 25)))
|
||||
@@ -55,6 +55,13 @@
|
||||
D.after_add()
|
||||
infectee.med_hud_set_status()
|
||||
|
||||
var/turf/source_turf = get_turf(infectee)
|
||||
log_virus("[key_name(infectee)] was infected by virus: [src.admin_details()] at [loc_name(source_turf)]")
|
||||
|
||||
//Return a string for admin logging uses, should describe the disease in detail
|
||||
/datum/disease/proc/admin_details()
|
||||
return "[src.name] : [src.type]"
|
||||
|
||||
/datum/disease/proc/stage_act()
|
||||
var/cure = has_cure()
|
||||
|
||||
@@ -65,15 +72,17 @@
|
||||
|
||||
if(!cure)
|
||||
if(prob(stage_prob))
|
||||
stage = min(stage + 1,max_stages)
|
||||
update_stage(min(stage + 1,max_stages))
|
||||
else
|
||||
if(prob(cure_chance))
|
||||
stage = max(stage - 1, 1)
|
||||
update_stage(max(stage - 1, 1))
|
||||
|
||||
if(disease_flags & CURABLE)
|
||||
if(cure && prob(cure_chance))
|
||||
cure()
|
||||
|
||||
/datum/disease/proc/update_stage(new_stage)
|
||||
stage = new_stage
|
||||
|
||||
/datum/disease/proc/has_cure()
|
||||
if(!(disease_flags & CURABLE))
|
||||
|
||||
@@ -31,13 +31,43 @@
|
||||
var/id = ""
|
||||
var/processing = FALSE
|
||||
var/mutable = TRUE //set to FALSE to prevent most in-game methods of altering the disease via virology
|
||||
var/oldres //To prevent setting new cures unless resistance changes.
|
||||
|
||||
// The order goes from easy to cure to hard to cure.
|
||||
// The order goes from easy to cure to hard to cure. Keep in mind that sentient diseases pick two cures from tier 6 and up, ensure they wont react away in bodies.
|
||||
var/static/list/advance_cures = list(
|
||||
"sodiumchloride", "sugar", "orangejuice",
|
||||
"spaceacillin", "salglu_solution", "ethanol",
|
||||
"leporazine", "synaptizine", "lipolicide",
|
||||
"silver", "gold"
|
||||
list( // level 1
|
||||
"copper", "silver", "iodine", "iron", "carbon"
|
||||
),
|
||||
list( // level 2
|
||||
"potassium", "ethanol", "lithium", "silicon", "bromine"
|
||||
),
|
||||
list( // level 3
|
||||
"sodiumchloride", "sugar", "orangejuice", "tomatojuice", "milk"
|
||||
),
|
||||
list( //level 4
|
||||
"spaceacillin", "salglu_solution", "epinephrine", "charcoal"
|
||||
),
|
||||
list( //level 5
|
||||
"oil", "synaptizine", "mannitol", "space_drugs", "cryptobiolin"
|
||||
),
|
||||
list( // level 6
|
||||
"phenol", "inacusiate", "oculine", "antihol"
|
||||
),
|
||||
list( // level 7
|
||||
"leporazine", "mindbreaker", "corazone"
|
||||
),
|
||||
list( // level 8
|
||||
"pax", "happiness", "ephedrine"
|
||||
),
|
||||
list( // level 9
|
||||
"lipolicide", "sal_acid"
|
||||
),
|
||||
list( // level 10
|
||||
"haloperidol", "aranesp", "diphenhydramine"
|
||||
),
|
||||
list( //level 11
|
||||
"modafinil", "anacea"
|
||||
)
|
||||
)
|
||||
|
||||
/*
|
||||
@@ -80,15 +110,22 @@
|
||||
return
|
||||
|
||||
if(symptoms && symptoms.len)
|
||||
|
||||
if(!processing)
|
||||
processing = TRUE
|
||||
for(var/datum/symptom/S in symptoms)
|
||||
S.Start(src)
|
||||
if(S.Start(src)) //this will return FALSE if the symptom is neutered
|
||||
S.next_activation = world.time + rand(S.symptom_delay_min * 10, S.symptom_delay_max * 10)
|
||||
S.on_stage_change(src)
|
||||
|
||||
for(var/datum/symptom/S in symptoms)
|
||||
S.Activate(src)
|
||||
|
||||
// Tell symptoms stage changed
|
||||
/datum/disease/advance/update_stage(new_stage)
|
||||
..()
|
||||
for(var/datum/symptom/S in symptoms)
|
||||
S.on_stage_change(src)
|
||||
|
||||
// Compares type then ID.
|
||||
/datum/disease/advance/IsSame(datum/disease/advance/D)
|
||||
|
||||
@@ -108,9 +145,18 @@
|
||||
A.properties = properties.Copy()
|
||||
A.id = id
|
||||
A.mutable = mutable
|
||||
A.oldres = oldres
|
||||
//this is a new disease starting over at stage 1, so processing is not copied
|
||||
return A
|
||||
|
||||
//Describe this disease to an admin in detail (for logging)
|
||||
/datum/disease/advance/admin_details()
|
||||
var/list/name_symptoms = list()
|
||||
for(var/datum/symptom/S in symptoms)
|
||||
name_symptoms += S.name
|
||||
return "[name] sym:[english_list(name_symptoms)] r:[totalResistance()] s:[totalStealth()] ss:[totalStageSpeed()] t:[totalTransmittable()]"
|
||||
|
||||
|
||||
/*
|
||||
|
||||
NEW PROCS
|
||||
@@ -161,6 +207,10 @@
|
||||
/datum/disease/advance/proc/Refresh(new_name = FALSE)
|
||||
GenerateProperties()
|
||||
AssignProperties()
|
||||
if(processing && symptoms && symptoms.len)
|
||||
for(var/datum/symptom/S in symptoms)
|
||||
S.Start(src)
|
||||
S.on_stage_change(src)
|
||||
id = null
|
||||
|
||||
var/the_id = GetDiseaseID()
|
||||
@@ -250,7 +300,10 @@
|
||||
/datum/disease/advance/proc/GenerateCure()
|
||||
if(properties && properties.len)
|
||||
var/res = CLAMP(properties["resistance"] - (symptoms.len / 2), 1, advance_cures.len)
|
||||
cures = list(advance_cures[res])
|
||||
if(res == oldres)
|
||||
return
|
||||
cures = list(pick(advance_cures[res]))
|
||||
oldres = res
|
||||
|
||||
// Get the cure name from the cure_id
|
||||
var/datum/reagent/D = GLOB.chemical_reagents_list[cures[1]]
|
||||
@@ -309,28 +362,28 @@
|
||||
return id
|
||||
|
||||
|
||||
// Add a symptom, if it is over the limit (with a small chance to be able to go over)
|
||||
// we take a random symptom away and add the new one.
|
||||
// Add a symptom, if it is over the limit we take a random symptom away and add the new one.
|
||||
/datum/disease/advance/proc/AddSymptom(datum/symptom/S)
|
||||
|
||||
if(HasSymptom(S))
|
||||
return
|
||||
|
||||
if(symptoms.len < (VIRUS_SYMPTOM_LIMIT - 1) + rand(-1, 1))
|
||||
symptoms += S
|
||||
else
|
||||
if(!(symptoms.len < (VIRUS_SYMPTOM_LIMIT - 1) + rand(-1, 1)))
|
||||
RemoveSymptom(pick(symptoms))
|
||||
symptoms += S
|
||||
symptoms += S
|
||||
S.OnAdd(src)
|
||||
|
||||
// Simply removes the symptom.
|
||||
/datum/disease/advance/proc/RemoveSymptom(datum/symptom/S)
|
||||
symptoms -= S
|
||||
S.OnRemove(src)
|
||||
|
||||
// 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)"
|
||||
S.OnRemove(src)
|
||||
|
||||
/*
|
||||
|
||||
@@ -384,7 +437,7 @@
|
||||
|
||||
var/i = VIRUS_SYMPTOM_LIMIT
|
||||
|
||||
var/datum/disease/advance/D = new(0, null)
|
||||
var/datum/disease/advance/D = new()
|
||||
D.symptoms = list()
|
||||
|
||||
var/list/symptoms = list()
|
||||
@@ -412,9 +465,6 @@
|
||||
D.AssignName(new_name)
|
||||
D.Refresh()
|
||||
|
||||
for(var/datum/disease/advance/AD in SSdisease.active_diseases)
|
||||
AD.Refresh()
|
||||
|
||||
for(var/mob/living/carbon/human/H in shuffle(GLOB.alive_mob_list))
|
||||
if(!is_station_level(H.z))
|
||||
continue
|
||||
@@ -425,8 +475,8 @@
|
||||
var/list/name_symptoms = list()
|
||||
for(var/datum/symptom/S in D.symptoms)
|
||||
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)]")
|
||||
|
||||
message_admins("[key_name_admin(user)] has triggered a custom virus outbreak of [D.admin_details()]")
|
||||
log_virus("[key_name(user)] has triggered a custom virus outbreak of [D.admin_details()]!")
|
||||
|
||||
/datum/disease/advance/proc/totalStageSpeed()
|
||||
return properties["stage_rate"]
|
||||
|
||||
@@ -144,5 +144,5 @@ Bonus
|
||||
/datum/symptom/asphyxiation/proc/Asphyxiate_death(mob/living/M, datum/disease/advance/A)
|
||||
var/get_damage = rand(25,35) * power
|
||||
M.adjustOxyLoss(get_damage)
|
||||
M.adjustBrainLoss(get_damage/2)
|
||||
M.adjustOrganLoss(ORGAN_SLOT_BRAIN, get_damage/2)
|
||||
return 1
|
||||
|
||||
@@ -55,7 +55,7 @@ Bonus
|
||||
to_chat(M, "<span class='userdanger'>You can't think straight!</span>")
|
||||
M.confused = min(100 * power, M.confused + 8)
|
||||
if(brain_damage)
|
||||
M.adjustBrainLoss(3 * power, 80)
|
||||
M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 3 * power, 80)
|
||||
M.updatehealth()
|
||||
|
||||
return
|
||||
|
||||
@@ -70,6 +70,6 @@ BONUS
|
||||
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)
|
||||
if(infective && M.CanSpreadAirborneDisease())
|
||||
A.spread(1)
|
||||
|
||||
|
||||
@@ -50,9 +50,9 @@ Bonus
|
||||
if(5)
|
||||
if(power > 2)
|
||||
var/obj/item/organ/ears/ears = M.getorganslot(ORGAN_SLOT_EARS)
|
||||
if(istype(ears) && ears.ear_damage < UNHEALING_EAR_DAMAGE)
|
||||
if(istype(ears) && ears.damage < ears.maxHealth)
|
||||
to_chat(M, "<span class='userdanger'>Your ears pop painfully and start bleeding!</span>")
|
||||
ears.ear_damage = max(ears.ear_damage, UNHEALING_EAR_DAMAGE)
|
||||
ears.damage = max(ears.damage, ears.maxHealth)
|
||||
M.emote("scream")
|
||||
else
|
||||
to_chat(M, "<span class='userdanger'>Your ears pop and begin ringing loudly!</span>")
|
||||
|
||||
@@ -219,8 +219,10 @@
|
||||
level = 8
|
||||
passive_message = "<span class='notice'>The pain from your wounds makes you feel oddly sleepy...</span>"
|
||||
var/deathgasp = FALSE
|
||||
var/stabilize = FALSE
|
||||
var/active_coma = FALSE //to prevent multiple coma procs
|
||||
threshold_desc = "<b>Stealth 2:</b> Host appears to die when falling into a coma.<br>\
|
||||
<b>Resistance 4:</b> The virus also stabilizes the host while they are in critical condition.<br>\
|
||||
<b>Stage Speed 7:</b> Increases healing speed."
|
||||
|
||||
/datum/symptom/heal/coma/Start(datum/disease/advance/A)
|
||||
@@ -228,9 +230,25 @@
|
||||
return
|
||||
if(A.properties["stage_rate"] >= 7)
|
||||
power = 1.5
|
||||
if(A.properties["resistance"] >= 4)
|
||||
stabilize = TRUE
|
||||
if(A.properties["stealth"] >= 2)
|
||||
deathgasp = TRUE
|
||||
|
||||
/datum/symptom/heal/coma/on_stage_change(datum/disease/advance/A) //mostly copy+pasted from the code for self-respiration's TRAIT_NOBREATH stuff
|
||||
if(!..())
|
||||
return FALSE
|
||||
if(A.stage >= 4 && stabilize)
|
||||
ADD_TRAIT(A.affected_mob, TRAIT_NOCRITDAMAGE, DISEASE_TRAIT)
|
||||
else
|
||||
REMOVE_TRAIT(A.affected_mob, TRAIT_NOCRITDAMAGE, DISEASE_TRAIT)
|
||||
return TRUE
|
||||
|
||||
/datum/symptom/heal/coma/End(datum/disease/advance/A)
|
||||
if(!..())
|
||||
return
|
||||
REMOVE_TRAIT(A.affected_mob, TRAIT_NOCRITDAMAGE, DISEASE_TRAIT)
|
||||
|
||||
/datum/symptom/heal/coma/CanHeal(datum/disease/advance/A)
|
||||
var/mob/living/M = A.affected_mob
|
||||
if(HAS_TRAIT(M, TRAIT_DEATHCOMA))
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
if(!..())
|
||||
return
|
||||
var/mob/living/carbon/M = A.affected_mob
|
||||
SEND_SIGNAL(M, COMSIG_NANITE_ADJUST_VOLUME, src, power)
|
||||
SEND_SIGNAL(M, COMSIG_NANITE_ADJUST_VOLUME, power)
|
||||
if(reverse_boost && SEND_SIGNAL(M, COMSIG_HAS_NANITES))
|
||||
if(prob(A.stage_prob))
|
||||
A.stage = min(A.stage + 1,A.max_stages)
|
||||
|
||||
@@ -44,9 +44,25 @@ Bonus
|
||||
if(4, 5)
|
||||
M.adjustOxyLoss(-7, 0)
|
||||
M.losebreath = max(0, M.losebreath - 4)
|
||||
if(regenerate_blood && M.blood_volume < BLOOD_VOLUME_NORMAL)
|
||||
if(regenerate_blood && M.blood_volume < (BLOOD_VOLUME_NORMAL * M.blood_ratio))
|
||||
M.blood_volume += 1
|
||||
else
|
||||
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
|
||||
|
||||
/datum/symptom/oxygen/on_stage_change(datum/disease/advance/A)
|
||||
if(!..())
|
||||
return FALSE
|
||||
var/mob/living/carbon/M = A.affected_mob
|
||||
if(A.stage >= 4)
|
||||
ADD_TRAIT(M, TRAIT_NOBREATH, DISEASE_TRAIT)
|
||||
else
|
||||
REMOVE_TRAIT(M, TRAIT_NOBREATH, DISEASE_TRAIT)
|
||||
return TRUE
|
||||
|
||||
/datum/symptom/oxygen/End(datum/disease/advance/A)
|
||||
if(!..())
|
||||
return
|
||||
if(A.stage >= 4)
|
||||
REMOVE_TRAIT(A.affected_mob, TRAIT_NOBREATH, DISEASE_TRAIT)
|
||||
@@ -51,7 +51,7 @@
|
||||
M.hallucination = max(0, M.hallucination - 10)
|
||||
|
||||
if(A.stage >= 5)
|
||||
M.adjustBrainLoss(-3)
|
||||
M.adjustOrganLoss(ORGAN_SLOT_BRAIN, -3)
|
||||
if(trauma_heal_mild && iscarbon(M))
|
||||
var/mob/living/carbon/C = M
|
||||
if(prob(10))
|
||||
@@ -100,8 +100,8 @@
|
||||
else if(M.eye_blind || M.eye_blurry)
|
||||
M.set_blindness(0)
|
||||
M.set_blurriness(0)
|
||||
else if(eyes.eye_damage > 0)
|
||||
M.adjust_eye_damage(-1)
|
||||
else if(eyes.damage > 0)
|
||||
eyes.applyOrganDamage(-1)
|
||||
else
|
||||
if(prob(base_message_chance))
|
||||
to_chat(M, "<span class='notice'>[pick("Your eyes feel great.","You feel like your eyes can focus more clearly.", "You don't feel the need to blink.","Your ears feel great.","Your healing feels more acute.")]</span>")
|
||||
to_chat(M, "<span class='notice'>[pick("Your eyes feel great.","You feel like your eyes can focus more clearly.", "You don't feel the need to blink.","Your ears feel great.","Your healing feels more acute.")]</span>")
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user