Merge remote-tracking branch 'citadel/master' into shield_refactor
This commit is contained in:
@@ -121,25 +121,25 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
"taur" = "None",
|
||||
"genitals_use_skintone" = FALSE,
|
||||
"has_cock" = FALSE,
|
||||
"cock_shape" = "Human",
|
||||
"cock_length" = 6,
|
||||
"cock_shape" = DEF_COCK_SHAPE,
|
||||
"cock_length" = COCK_SIZE_DEF,
|
||||
"cock_diameter_ratio" = COCK_DIAMETER_RATIO_DEF,
|
||||
"cock_color" = "fff",
|
||||
"has_balls" = FALSE,
|
||||
"balls_internal" = FALSE,
|
||||
"balls_color" = "fff",
|
||||
"balls_shape" = "Single",
|
||||
"balls_shape" = DEF_BALLS_SHAPE,
|
||||
"balls_size" = BALLS_SIZE_DEF,
|
||||
"balls_cum_rate" = CUM_RATE,
|
||||
"balls_cum_mult" = CUM_RATE_MULT,
|
||||
"balls_efficiency" = CUM_EFFICIENCY,
|
||||
"has_breasts" = FALSE,
|
||||
"breasts_color" = "fff",
|
||||
"breasts_size" = "C",
|
||||
"breasts_shape" = "Pair",
|
||||
"breasts_size" = BREASTS_SIZE_DEF,
|
||||
"breasts_shape" = DEF_BREASTS_SHAPE,
|
||||
"breasts_producing" = FALSE,
|
||||
"has_vag" = FALSE,
|
||||
"vag_shape" = "Human",
|
||||
"vag_shape" = DEF_VAGINA_SHAPE,
|
||||
"vag_color" = "fff",
|
||||
"vag_clits" = 1,
|
||||
"vag_clit_diam" = 0.25,
|
||||
|
||||
@@ -544,6 +544,18 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
features["insect_fluff"] = sanitize_inlist(features["insect_fluff"], GLOB.insect_fluffs_list)
|
||||
features["insect_markings"] = sanitize_inlist(features["insect_markings"], GLOB.insect_markings_list, "None")
|
||||
features["insect_wings"] = sanitize_inlist(features["insect_wings"], GLOB.insect_wings_list)
|
||||
|
||||
features["breasts_size"] = sanitize_inlist(features["breasts_size"], GLOB.breasts_size_list, BREASTS_SIZE_DEF)
|
||||
features["breasts_shape"] = sanitize_inlist(features["breasts_shape"], GLOB.breasts_shapes_list, DEF_BREASTS_SHAPE)
|
||||
features["cock_shape"] = sanitize_inlist(features["cock_shape"], GLOB.cock_shapes_list, DEF_COCK_SHAPE)
|
||||
features["cock_length"] = sanitize_integer(features["cock_length"], COCK_SIZE_MIN, COCK_SIZE_MAX, COCK_SIZE_DEF)
|
||||
features["balls_shape"] = sanitize_inlist(features["balls_shape"], GLOB.balls_shapes_list, DEF_BALLS_SHAPE)
|
||||
features["vag_shape"] = sanitize_inlist(features["vag_shape"], GLOB.vagina_shapes_list, DEF_VAGINA_SHAPE)
|
||||
features["breasts_color"] = sanitize_hexcolor(features["breasts_color"], 3, FALSE, "FFF")
|
||||
features["cock_color"] = sanitize_hexcolor(features["cock_color"], 3, FALSE, "FFF")
|
||||
features["balls_color"] = sanitize_hexcolor(features["balls_color"], 3, FALSE, "FFF")
|
||||
features["vag_color"] = sanitize_hexcolor(features["vag_color"], 3, FALSE, "FFF")
|
||||
|
||||
features["flavor_text"] = copytext(features["flavor_text"], 1, MAX_FLAVOR_LEN)
|
||||
|
||||
joblessrole = sanitize_integer(joblessrole, 1, 3, initial(joblessrole))
|
||||
|
||||
@@ -447,7 +447,7 @@
|
||||
permeability_coefficient = 0.01
|
||||
flags_cover = MASKCOVERSEYES | MASKCOVERSMOUTH
|
||||
|
||||
var/vchange = 1
|
||||
var/voice_change = 1 ///This determines if the voice changer is on or off.
|
||||
|
||||
var/datum/action/item_action/chameleon/change/chameleon_action
|
||||
|
||||
@@ -470,15 +470,14 @@
|
||||
chameleon_action.emp_randomise(INFINITY)
|
||||
|
||||
/obj/item/clothing/mask/chameleon/attack_self(mob/user)
|
||||
vchange = !vchange
|
||||
to_chat(user, "<span class='notice'>The voice changer is now [vchange ? "on" : "off"]!</span>")
|
||||
|
||||
voice_change = !voice_change
|
||||
to_chat(user, "<span class='notice'>The voice changer is now [voice_change ? "on" : "off"]!</span>")
|
||||
|
||||
/obj/item/clothing/mask/chameleon/drone
|
||||
//Same as the drone chameleon hat, undroppable and no protection
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0)
|
||||
// Can drones use the voice changer part? Let's not find out.
|
||||
vchange = 0
|
||||
voice_change = 0
|
||||
|
||||
/obj/item/clothing/mask/chameleon/drone/Initialize()
|
||||
. = ..()
|
||||
|
||||
@@ -82,6 +82,7 @@
|
||||
icon_state = "nvgmeson"
|
||||
item_state = "nvgmeson"
|
||||
darkness_view = 8
|
||||
flash_protect = -2
|
||||
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
|
||||
glass_colour_type = /datum/client_colour/glass_colour/green
|
||||
|
||||
@@ -119,10 +120,11 @@
|
||||
|
||||
/obj/item/clothing/glasses/night
|
||||
name = "night vision goggles"
|
||||
desc = "You can totally see in the dark now!"
|
||||
desc = "You can totally see in the dark now! Just don't look too closely at bright lights. This lacks any flash correction."
|
||||
icon_state = "night"
|
||||
item_state = "glasses"
|
||||
darkness_view = 8
|
||||
flash_protect = -2
|
||||
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
|
||||
glass_colour_type = /datum/client_colour/glass_colour/green
|
||||
|
||||
@@ -130,6 +132,12 @@
|
||||
name = "prescription night vision goggles"
|
||||
desc = "NVGs but for those with nearsightedness."
|
||||
vision_correction = 1
|
||||
|
||||
/obj/item/clothing/glasses/night/syndicate
|
||||
name = "combat night vision goggles"
|
||||
desc = "See everything, without fear."
|
||||
flash_protect = 1
|
||||
vision_correction = 1
|
||||
|
||||
/obj/item/clothing/glasses/science/suicide_act(mob/living/carbon/user)
|
||||
user.visible_message("<span class='suicide'>[user] is tightening \the [src]'s straps around [user.p_their()] neck! It looks like [user.p_theyre()] trying to commit suicide!</span>")
|
||||
|
||||
@@ -63,12 +63,19 @@
|
||||
|
||||
/obj/item/clothing/glasses/hud/health/night
|
||||
name = "night vision health scanner HUD"
|
||||
desc = "An advanced medical head-up display that allows doctors to find patients in complete darkness."
|
||||
desc = "An advanced medical heads-up display that allows doctors to find patients in complete darkness."
|
||||
icon_state = "healthhudnight"
|
||||
item_state = "glasses"
|
||||
darkness_view = 8
|
||||
flash_protect = -2
|
||||
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE
|
||||
glass_colour_type = /datum/client_colour/glass_colour/green
|
||||
|
||||
/obj/item/clothing/glasses/hud/health/night/syndicate
|
||||
name = "combat night vision health scanner HUD"
|
||||
desc = "An advanced shielded medical heads-up display that allows soldiers to approximate how much lead poisoning their allies have suffered in complete darkness."
|
||||
flash_protect = 1
|
||||
vision_correction = 1
|
||||
|
||||
/obj/item/clothing/glasses/hud/health/sunglasses
|
||||
name = "medical HUDSunglasses"
|
||||
@@ -126,6 +133,7 @@
|
||||
icon_state = "diagnostichudnight"
|
||||
item_state = "glasses"
|
||||
darkness_view = 8
|
||||
flash_protect = -2
|
||||
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE
|
||||
glass_colour_type = /datum/client_colour/glass_colour/green
|
||||
|
||||
@@ -199,6 +207,7 @@
|
||||
desc = "An advanced heads-up display which provides id data and vision in complete darkness."
|
||||
icon_state = "securityhudnight"
|
||||
darkness_view = 8
|
||||
flash_protect = -2 //You either are flashproof or you can see in the dark, pick one.
|
||||
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE
|
||||
glass_colour_type = /datum/client_colour/glass_colour/green
|
||||
|
||||
|
||||
@@ -35,10 +35,10 @@
|
||||
return
|
||||
if(slot != SLOT_GLASSES)
|
||||
return
|
||||
RegisterSignal(user, COMSIG_COMBAT_TOGGLED, .proc/injectadrenaline)
|
||||
RegisterSignal(user, COMSIG_LIVING_COMBAT_ENABLED, .proc/injectadrenaline)
|
||||
|
||||
/obj/item/clothing/glasses/phantomthief/syndicate/dropped(mob/user)
|
||||
. = ..()
|
||||
if(!istype(user))
|
||||
return
|
||||
UnregisterSignal(user, COMSIG_COMBAT_TOGGLED)
|
||||
UnregisterSignal(user, COMSIG_LIVING_COMBAT_ENABLED)
|
||||
|
||||
@@ -194,7 +194,7 @@
|
||||
|
||||
/obj/item/clothing/gloves/color/latex
|
||||
name = "latex gloves"
|
||||
desc = "Cheap sterile gloves made from latex."
|
||||
desc = "Cheap sterile gloves made from latex. Transfers basic paramedical knowledge to the wearer via the use of nanochips."
|
||||
icon_state = "latex"
|
||||
item_state = "lgloves"
|
||||
siemens_coefficient = 0.3
|
||||
@@ -202,14 +202,34 @@
|
||||
item_color="mime"
|
||||
transfer_prints = TRUE
|
||||
resistance_flags = NONE
|
||||
var/carrytrait = TRAIT_QUICK_CARRY
|
||||
|
||||
/obj/item/clothing/gloves/color/latex/equipped(mob/user, slot)
|
||||
..()
|
||||
if(slot == SLOT_GLOVES)
|
||||
ADD_TRAIT(user, carrytrait, CLOTHING_TRAIT)
|
||||
|
||||
/obj/item/clothing/gloves/color/latex/dropped(mob/user)
|
||||
..()
|
||||
REMOVE_TRAIT(user, carrytrait, CLOTHING_TRAIT)
|
||||
|
||||
/obj/item/clothing/gloves/color/latex/nitrile
|
||||
name = "nitrile gloves"
|
||||
desc = "Pricy sterile gloves that are stronger than latex."
|
||||
desc = "Pricy sterile gloves that are stronger than latex. Transfers advanced paramedical knowledge to the wearer via the use of nanochips."
|
||||
icon_state = "nitrile"
|
||||
item_state = "nitrilegloves"
|
||||
item_color = "cmo"
|
||||
transfer_prints = FALSE
|
||||
carrytrait = TRAIT_QUICKER_CARRY
|
||||
|
||||
/obj/item/clothing/gloves/color/latex/nitrile/infiltrator
|
||||
name = "insidious combat gloves"
|
||||
desc = "Specialized combat gloves for carrying people around. Transfers tactical kidnapping knowledge to the user via the use of nanochips."
|
||||
icon_state = "infiltrator"
|
||||
item_state = "infiltrator"
|
||||
siemens_coefficient = 0
|
||||
permeability_coefficient = 0.3
|
||||
resistance_flags = FIRE_PROOF | ACID_PROOF
|
||||
|
||||
/obj/item/clothing/gloves/color/white
|
||||
name = "white gloves"
|
||||
|
||||
@@ -256,6 +256,21 @@
|
||||
strip_delay = 100
|
||||
mutantrace_variation = STYLE_MUZZLE
|
||||
|
||||
/obj/item/clothing/head/helmet/infiltrator
|
||||
name = "insidious helmet"
|
||||
desc = "An insidious armored combat helmet signed with Syndicate insignia. The visor is coated with a resistant paste guaranteed to withstand bright flashes perfectly."
|
||||
icon_state = "infiltrator"
|
||||
item_state = "infiltrator"
|
||||
armor = list("melee" = 40, "bullet" = 40, "laser" = 30, "energy" = 40, "bomb" = 70, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100)
|
||||
resistance_flags = FIRE_PROOF | ACID_PROOF
|
||||
flash_protect = 2
|
||||
flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR|HIDESNOUT
|
||||
flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH
|
||||
dynamic_hair_suffix = ""
|
||||
dynamic_fhair_suffix = ""
|
||||
strip_delay = 80
|
||||
mutantrace_variation = STYLE_MUZZLE
|
||||
|
||||
//LightToggle
|
||||
|
||||
/obj/item/clothing/head/helment/ComponentInitialize()
|
||||
|
||||
@@ -12,6 +12,20 @@
|
||||
/obj/item/clothing/mask/balaclava/attack_self(mob/user)
|
||||
adjustmask(user)
|
||||
|
||||
/obj/item/clothing/mask/infiltrator
|
||||
name = "insidious balaclava"
|
||||
desc = "An incredibly suspicious balaclava made with Syndicate nanofibers to absorb impacts slightly while obfuscating the voice and face using a garbled vocoder."
|
||||
icon_state = "syndicate_balaclava"
|
||||
item_state = "syndicate_balaclava"
|
||||
clothing_flags = ALLOWINTERNALS
|
||||
flags_cover = HEADCOVERSEYES
|
||||
flags_inv = HIDEFACE|HIDEHAIR|HIDEFACIALHAIR
|
||||
visor_flags_inv = HIDEFACE|HIDEFACIALHAIR
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
armor = list("melee" = 10, "bullet" = 5, "laser" = 5,"energy" = 5, "bomb" = 0, "bio" = 0, "rad" = 10, "fire" = 100, "acid" = 40)
|
||||
resistance_flags = FIRE_PROOF | ACID_PROOF
|
||||
var/voice_unknown = TRUE ///This makes it so that your name shows up as unknown when wearing the mask.
|
||||
|
||||
/obj/item/clothing/mask/luchador
|
||||
name = "Luchador Mask"
|
||||
desc = "Worn by robust fighters, flying high to defeat their foes!"
|
||||
|
||||
@@ -19,6 +19,14 @@
|
||||
permeability_coefficient = 0.05 //Thick soles, and covers the ankle
|
||||
pocket_storage_component_path = /datum/component/storage/concrete/pockets/shoes
|
||||
|
||||
/obj/item/clothing/shoes/combat/sneakboots
|
||||
name = "insidious sneakboots"
|
||||
desc = "A pair of insidious boots with special noise muffling soles which very slightly drown out your footsteps. They would be absolutely perfect for stealth operations were it not for the iconic Syndicate flairs."
|
||||
icon_state = "sneakboots"
|
||||
item_state = "sneakboots"
|
||||
resistance_flags = FIRE_PROOF | ACID_PROOF
|
||||
clothing_flags = TRAIT_SILENT_STEP
|
||||
|
||||
/obj/item/clothing/shoes/combat/swat //overpowered boots for death squads
|
||||
name = "\improper SWAT boots"
|
||||
desc = "High speed, no drag combat boots."
|
||||
|
||||
@@ -192,6 +192,15 @@
|
||||
. = ..()
|
||||
allowed = GLOB.detective_vest_allowed
|
||||
|
||||
/obj/item/clothing/suit/armor/vest/infiltrator
|
||||
name = "insidious combat vest"
|
||||
desc = "An insidious combat vest designed using Syndicate nanofibers to absorb the supreme majority of kinetic blows. Although it doesn't look like it'll do too much for energy impacts."
|
||||
icon_state = "infiltrator"
|
||||
item_state = "infiltrator"
|
||||
armor = list("melee" = 30, "bullet" = 40, "laser" = 20, "energy" = 30, "bomb" = 70, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100)
|
||||
resistance_flags = FIRE_PROOF | ACID_PROOF
|
||||
strip_delay = 80
|
||||
|
||||
//All of the armor below is mostly unused
|
||||
|
||||
/obj/item/clothing/suit/armor/centcom
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
var/can_adjust = TRUE
|
||||
var/adjusted = NORMAL_STYLE
|
||||
var/alt_covers_chest = FALSE // for adjusted/rolled-down jumpsuits, FALSE = exposes chest and arms, TRUE = exposes arms only
|
||||
var/dummy_thick = FALSE // is able to hold accessories on its item
|
||||
var/obj/item/clothing/accessory/attached_accessory
|
||||
var/mutable_appearance/accessory_overlay
|
||||
mutantrace_variation = STYLE_DIGITIGRADE
|
||||
@@ -83,6 +84,10 @@
|
||||
if(user)
|
||||
to_chat(user, "<span class='warning'>[src] already has an accessory.</span>")
|
||||
return
|
||||
if(dummy_thick)
|
||||
if(user)
|
||||
to_chat(user, "<span class='warning'>[src] is too bulky and cannot have accessories attached to it!</span>")
|
||||
return
|
||||
else
|
||||
if(user && !user.temporarilyRemoveItemFromInventory(I))
|
||||
return
|
||||
|
||||
@@ -19,6 +19,25 @@
|
||||
alt_covers_chest = TRUE
|
||||
fitted = FEMALE_UNIFORM_TOP
|
||||
|
||||
/obj/item/clothing/under/syndicate/bloodred
|
||||
name = "blood-red sneaksuit"
|
||||
desc = "An insidious armored jumpsuit lined with Syndicate nanofibers and prototype platings, slightly resistant to most forms of damage, but is far too bulky to have anything attached to it. It still counts as stealth if there are no witnesses."
|
||||
icon_state = "bloodred_pajamas"
|
||||
item_state = "bl_suit"
|
||||
item_color = "bloodred_pajamas"
|
||||
dummy_thick = TRUE
|
||||
armor = list("melee" = 10, "bullet" = 10, "laser" = 10,"energy" = 10, "bomb" = 0, "bio" = 0, "rad" = 10, "fire" = 50, "acid" = 40)
|
||||
resistance_flags = FIRE_PROOF | ACID_PROOF
|
||||
can_adjust = FALSE
|
||||
|
||||
/obj/item/clothing/under/syndicate/bloodred/sleepytime
|
||||
name = "blood-red pajamas"
|
||||
desc = "Do operatives dream of nuclear sheep?"
|
||||
icon_state = "bloodred_pajamas"
|
||||
item_state = "bl_suit"
|
||||
item_color = "bloodred_pajamas"
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 40)
|
||||
|
||||
/obj/item/clothing/under/syndicate/tacticool
|
||||
name = "tacticool turtleneck"
|
||||
desc = "Just looking at it makes you want to buy an SKS, go into the woods, and -operate-."
|
||||
@@ -75,7 +94,7 @@
|
||||
item_color = "rus_under"
|
||||
can_adjust = FALSE
|
||||
armor = list("melee" = 5, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0)
|
||||
resistance_flags = NONE
|
||||
resistance_flags = NONE
|
||||
|
||||
/obj/item/clothing/under/syndicate/baseball
|
||||
name = "major league, number unknown"
|
||||
|
||||
@@ -4,6 +4,6 @@
|
||||
toggle_throw_mode()
|
||||
return
|
||||
if("C")
|
||||
toggle_combat_mode()
|
||||
user_toggle_intentional_combat_mode()
|
||||
return
|
||||
return ..()
|
||||
@@ -59,11 +59,11 @@
|
||||
switch(_key)
|
||||
if("Shift")
|
||||
if(!user.prefs.sprint_spacebar)
|
||||
user.prefs.sprint_toggle ? togglesprint() : sprint_hotkey(TRUE) //Yes, this looks hacky. Yes, this works.
|
||||
user.prefs.sprint_toggle ? default_toggle_sprint() : sprint_hotkey(TRUE) //Yes, this looks hacky. Yes, this works.
|
||||
return
|
||||
if("Space")
|
||||
if(user.prefs.sprint_spacebar)
|
||||
user.prefs.sprint_toggle ? togglesprint() : sprint_hotkey(TRUE)
|
||||
user.prefs.sprint_toggle ? default_toggle_sprint() : sprint_hotkey(TRUE)
|
||||
return
|
||||
return ..()
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ In all, this is a lot like the monkey code. /N
|
||||
return
|
||||
switch(M.a_intent)
|
||||
if (INTENT_HELP)
|
||||
if(!recoveringstam)
|
||||
if(!(combat_flags & COMBAT_FLAG_HARD_STAMCRIT))
|
||||
set_resting(FALSE, TRUE, FALSE)
|
||||
AdjustAllImmobility(-60, FALSE)
|
||||
AdjustUnconscious(-60, FALSE)
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
else
|
||||
if(stat == UNCONSCIOUS)
|
||||
stat = CONSCIOUS
|
||||
if(!recoveringstam)
|
||||
if(!(combat_flags & COMBAT_FLAG_HARD_STAMCRIT))
|
||||
set_resting(FALSE, TRUE)
|
||||
adjust_blindness(-1)
|
||||
update_mobility()
|
||||
|
||||
@@ -153,7 +153,7 @@
|
||||
return
|
||||
|
||||
//CIT CHANGES - makes it impossible to throw while in stamina softcrit
|
||||
if(getStaminaLoss() >= STAMINA_SOFTCRIT)
|
||||
if(IS_STAMCRIT(src))
|
||||
to_chat(src, "<span class='warning'>You're too exhausted.</span>")
|
||||
return
|
||||
var/random_turn = a_intent == INTENT_HARM
|
||||
@@ -448,7 +448,7 @@
|
||||
modifier -= 40 //Clumsy people are more likely to hit themselves -Honk!
|
||||
|
||||
//CIT CHANGES START HERE
|
||||
else if(combatmode)
|
||||
else if(combat_flags & COMBAT_FLAG_COMBAT_ACTIVE)
|
||||
modifier += 50
|
||||
|
||||
if(modifier < 100)
|
||||
@@ -820,15 +820,13 @@
|
||||
return
|
||||
if(IsUnconscious() || IsSleeping() || getOxyLoss() > 50 || (HAS_TRAIT(src, TRAIT_DEATHCOMA)) || (health <= HEALTH_THRESHOLD_FULLCRIT && !HAS_TRAIT(src, TRAIT_NOHARDCRIT)))
|
||||
stat = UNCONSCIOUS
|
||||
disable_intentional_combat_mode(FALSE, FALSE)
|
||||
if(!eye_blind)
|
||||
blind_eyes(1)
|
||||
if(combatmode)
|
||||
toggle_combat_mode(TRUE, TRUE)
|
||||
else
|
||||
if(health <= crit_threshold && !HAS_TRAIT(src, TRAIT_NOSOFTCRIT))
|
||||
stat = SOFT_CRIT
|
||||
if(combatmode)
|
||||
toggle_combat_mode(TRUE, TRUE)
|
||||
disable_intentional_combat_mode(FALSE, FALSE)
|
||||
else
|
||||
stat = CONSCIOUS
|
||||
adjust_blindness(-1)
|
||||
@@ -1011,8 +1009,7 @@
|
||||
return TRUE
|
||||
|
||||
/mob/living/carbon/transfer_ckey(mob/new_mob, send_signal = TRUE)
|
||||
if(combatmode)
|
||||
toggle_combat_mode(TRUE, TRUE)
|
||||
disable_intentional_combat_mode(TRUE, FALSE)
|
||||
return ..()
|
||||
|
||||
/mob/living/carbon/can_see_reagents()
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
/mob/living/carbon/enable_intentional_combat_mode()
|
||||
. = ..()
|
||||
if(.)
|
||||
if(voremode)
|
||||
toggle_vore_mode()
|
||||
|
||||
@@ -79,13 +79,11 @@
|
||||
/mob/living/carbon/attacked_by(obj/item/I, mob/living/user)
|
||||
//CIT CHANGES START HERE - combatmode and resting checks
|
||||
var/totitemdamage = I.force
|
||||
if(iscarbon(user))
|
||||
var/mob/living/carbon/tempcarb = user
|
||||
if(!tempcarb.combatmode)
|
||||
totitemdamage *= 0.5
|
||||
if(!(user.combat_flags & COMBAT_FLAG_COMBAT_ACTIVE))
|
||||
totitemdamage *= 0.5
|
||||
if(!CHECK_MOBILITY(user, MOBILITY_STAND))
|
||||
totitemdamage *= 0.5
|
||||
if(!combatmode)
|
||||
if(!(combat_flags & COMBAT_FLAG_COMBAT_ACTIVE))
|
||||
totitemdamage *= 1.5
|
||||
//CIT CHANGES END HERE
|
||||
var/impacting_zone = (user == src)? check_zone(user.zone_selected) : ran_zone(user.zone_selected)
|
||||
@@ -345,7 +343,7 @@
|
||||
AdjustAllImmobility(-60, FALSE)
|
||||
AdjustUnconscious(-60, FALSE)
|
||||
AdjustSleeping(-100, FALSE)
|
||||
if(recoveringstam)
|
||||
if(combat_flags & COMBAT_FLAG_HARD_STAMCRIT)
|
||||
adjustStaminaLoss(-15)
|
||||
else
|
||||
set_resting(FALSE, FALSE)
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
/// Sprint buffer ///
|
||||
/mob/living/carbon/doSprintLossTiles(tiles)
|
||||
doSprintBufferRegen(FALSE) //first regen.
|
||||
if(sprint_buffer)
|
||||
var/use = min(tiles, sprint_buffer)
|
||||
sprint_buffer -= use
|
||||
tiles -= use
|
||||
update_hud_sprint_bar()
|
||||
if(!tiles) //we had enough, we're done!
|
||||
return
|
||||
adjustStaminaLoss(tiles * sprint_stamina_cost) //use stamina to cover deficit.
|
||||
|
||||
/mob/living/carbon/proc/doSprintBufferRegen(updating = TRUE)
|
||||
var/diff = world.time - sprint_buffer_regen_last
|
||||
sprint_buffer_regen_last = world.time
|
||||
sprint_buffer = min(sprint_buffer_max, sprint_buffer + sprint_buffer_regen_ds * diff)
|
||||
if(updating)
|
||||
update_hud_sprint_bar()
|
||||
@@ -7,8 +7,8 @@
|
||||
|
||||
if(!gibbed)
|
||||
emote("deathgasp")
|
||||
if(combatmode)
|
||||
toggle_combat_mode(TRUE, TRUE)
|
||||
|
||||
disable_intentional_combat_mode(TRUE, FALSE)
|
||||
|
||||
. = ..()
|
||||
|
||||
@@ -67,6 +67,5 @@
|
||||
BP.throw_at(get_edge_target_turf(src,pick(GLOB.alldirs)),rand(1,3),5)
|
||||
|
||||
/mob/living/carbon/ghostize(can_reenter_corpse = TRUE, special = FALSE, penalize = FALSE, voluntary = FALSE)
|
||||
if(combatmode)
|
||||
toggle_combat_mode(TRUE, TRUE)
|
||||
disable_intentional_combat_mode(TRUE, FALSE)
|
||||
return ..()
|
||||
|
||||
@@ -90,7 +90,7 @@
|
||||
if(digitalcamo)
|
||||
. += "[t_He] [t_is] moving [t_his] body in an unnatural and blatantly unsimian manner."
|
||||
|
||||
if(combatmode)
|
||||
if(combat_flags & COMBAT_FLAG_COMBAT_ACTIVE)
|
||||
. += "[t_He] [t_is] visibly tense[CHECK_MOBILITY(src, MOBILITY_STAND) ? "." : ", and [t_is] standing in combative stance."]"
|
||||
|
||||
var/trait_exam = common_trait_examine()
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
. = ..()
|
||||
|
||||
if(CONFIG_GET(flag/disable_stambuffer))
|
||||
togglesprint()
|
||||
enable_intentional_sprint_mode()
|
||||
|
||||
RegisterSignal(src, COMSIG_COMPONENT_CLEAN_ACT, /atom.proc/clean_blood)
|
||||
|
||||
@@ -880,10 +880,20 @@
|
||||
return (ishuman(target) && !CHECK_MOBILITY(target, MOBILITY_STAND))
|
||||
|
||||
/mob/living/carbon/human/proc/fireman_carry(mob/living/carbon/target)
|
||||
if(can_be_firemanned(target))
|
||||
visible_message("<span class='notice'>[src] starts lifting [target] onto their back...</span>",
|
||||
"<span class='notice'>You start lifting [target] onto your back...</span>")
|
||||
if(do_after(src, 30, TRUE, target))
|
||||
var/carrydelay = 50 //if you have latex you are faster at grabbing
|
||||
var/skills_space = "" //cobby told me to do this
|
||||
if(HAS_TRAIT(src, TRAIT_QUICKER_CARRY))
|
||||
carrydelay = 30
|
||||
skills_space = "expertly"
|
||||
else if(HAS_TRAIT(src, TRAIT_QUICK_CARRY))
|
||||
carrydelay = 40
|
||||
skills_space = "quickly"
|
||||
if(can_be_firemanned(target) && !incapacitated(FALSE, TRUE))
|
||||
visible_message("<span class='notice'>[src] starts [skills_space] lifting [target] onto their back..</span>",
|
||||
//Joe Medic starts quickly/expertly lifting Grey Tider onto their back..
|
||||
"<span class='notice'>[carrydelay < 35 ? "Using your gloves' nanochips, you" : "You"] [skills_space] start to lift [target] onto your back[carrydelay == 40 ? ", while assisted by the nanochips in your gloves.." : "..."]</span>")
|
||||
//(Using your gloves' nanochips, you/You) ( /quickly/expertly) start to lift Grey Tider onto your back(, while assisted by the nanochips in your gloves../...)
|
||||
if(do_after(src, carrydelay, TRUE, target))
|
||||
//Second check to make sure they're still valid to be carried
|
||||
if(can_be_firemanned(target) && !incapacitated(FALSE, TRUE))
|
||||
target.set_resting(FALSE, TRUE)
|
||||
|
||||
@@ -6,6 +6,9 @@
|
||||
can_buckle = TRUE
|
||||
buckle_lying = FALSE
|
||||
mob_biotypes = MOB_ORGANIC|MOB_HUMANOID
|
||||
/// Enable stamina combat
|
||||
combat_flags = COMBAT_FLAGS_DEFAULT
|
||||
|
||||
//Hair colour and style
|
||||
var/hair_color = "000"
|
||||
var/hair_style = "Bald"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/mob/living/carbon/human/resist_a_rest(automatic = FALSE, ignoretimer = FALSE)
|
||||
if(!resting || stat || attemptingstandup)
|
||||
if(!resting || stat || (combat_flags & COMBAT_FLAG_RESISTING_REST))
|
||||
return FALSE
|
||||
if(ignoretimer)
|
||||
set_resting(FALSE, FALSE)
|
||||
@@ -13,10 +13,10 @@
|
||||
return FALSE
|
||||
else
|
||||
var/totaldelay = 3 //A little bit less than half of a second as a baseline for getting up from a rest
|
||||
if(getStaminaLoss() >= STAMINA_SOFTCRIT)
|
||||
if(IS_STAMCRIT(src))
|
||||
to_chat(src, "<span class='warning'>You're too exhausted to get up!")
|
||||
return FALSE
|
||||
attemptingstandup = TRUE
|
||||
combat_flags |= COMBAT_FLAG_RESISTING_REST
|
||||
var/health_deficiency = max((maxHealth - (health - getStaminaLoss()))*0.5, 0)
|
||||
if(!has_gravity())
|
||||
health_deficiency = health_deficiency*0.2
|
||||
@@ -37,10 +37,11 @@
|
||||
visible_message("<span class='notice'>[standupwarning]</span>", usernotice, vision_distance = 5)
|
||||
if(do_after(src, totaldelay, target = src, required_mobility_flags = MOBILITY_RESIST))
|
||||
set_resting(FALSE, TRUE)
|
||||
attemptingstandup = FALSE
|
||||
|
||||
combat_flags &= ~COMBAT_FLAG_RESISTING_REST
|
||||
return TRUE
|
||||
else
|
||||
attemptingstandup = FALSE
|
||||
combat_flags &= ~COMBAT_FLAG_RESISTING_REST
|
||||
if(resting) //we didn't shove ourselves up or something
|
||||
visible_message("<span class='notice'>[src] falls right back down.</span>", "<span class='notice'>You fall right back down.</span>")
|
||||
if(has_gravity())
|
||||
|
||||
@@ -9,6 +9,13 @@
|
||||
|
||||
/mob/living/carbon/human/movement_delay()
|
||||
. = ..()
|
||||
if(CHECK_MOBILITY(src, MOBILITY_STAND) && m_intent == MOVE_INTENT_RUN && (combat_flags & COMBAT_FLAG_SPRINT_ACTIVE))
|
||||
var/static/datum/config_entry/number/movedelay/sprint_speed_increase/SSI
|
||||
if(!SSI)
|
||||
SSI = CONFIG_GET_ENTRY(number/movedelay/sprint_speed_increase)
|
||||
. -= SSI.config_entry_value
|
||||
if(wrongdirmovedelay)
|
||||
. += 1
|
||||
if (m_intent == MOVE_INTENT_WALK && HAS_TRAIT(src, TRAIT_SPEEDY_STEP))
|
||||
. -= 1.5
|
||||
|
||||
@@ -42,10 +49,18 @@
|
||||
return ((shoes && shoes.negates_gravity()) || (dna.species.negates_gravity(src)))
|
||||
|
||||
/mob/living/carbon/human/Move(NewLoc, direct)
|
||||
var/oldpseudoheight = pseudo_z_axis
|
||||
. = ..()
|
||||
for(var/datum/mutation/human/HM in dna.mutations)
|
||||
HM.on_move(src, NewLoc)
|
||||
|
||||
if(. && (combat_flags & COMBAT_FLAG_SPRINT_ACTIVE) && !(movement_type & FLYING) && CHECK_ALL_MOBILITY(src, MOBILITY_MOVE|MOBILITY_STAND) && m_intent == MOVE_INTENT_RUN && has_gravity(loc) && !pulledby)
|
||||
if(!HAS_TRAIT(src, TRAIT_FREESPRINT))
|
||||
doSprintLossTiles(1)
|
||||
if((oldpseudoheight - pseudo_z_axis) >= 8)
|
||||
to_chat(src, "<span class='warning'>You trip off of the elevated surface!</span>")
|
||||
for(var/obj/item/I in held_items)
|
||||
accident(I)
|
||||
DefaultCombatKnockdown(80)
|
||||
if(shoes)
|
||||
if(!lying && !buckled)
|
||||
if(loc == NewLoc)
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
/mob/living/carbon/human/GetVoice()
|
||||
if(istype(wear_mask, /obj/item/clothing/mask/chameleon))
|
||||
var/obj/item/clothing/mask/chameleon/V = wear_mask
|
||||
if(V.vchange && wear_id)
|
||||
if(V.voice_change && wear_id)
|
||||
var/obj/item/card/id/idcard = wear_id.GetID()
|
||||
if(istype(idcard))
|
||||
return idcard.registered_name
|
||||
@@ -21,6 +21,12 @@
|
||||
return real_name
|
||||
else
|
||||
return real_name
|
||||
if(istype(wear_mask, /obj/item/clothing/mask/infiltrator))
|
||||
var/obj/item/clothing/mask/infiltrator/V = wear_mask
|
||||
if(V.voice_unknown)
|
||||
return ("Unknown")
|
||||
else
|
||||
return real_name
|
||||
if(mind)
|
||||
var/datum/antagonist/changeling/changeling = mind.has_antag_datum(/datum/antagonist/changeling)
|
||||
if(changeling && changeling.mimicing )
|
||||
|
||||
@@ -1450,15 +1450,11 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
target.grabbedby(user)
|
||||
return 1
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/datum/species/proc/harm(mob/living/carbon/human/user, mob/living/carbon/human/target, datum/martial_art/attacker_style)
|
||||
if(!attacker_style && HAS_TRAIT(user, TRAIT_PACIFISM))
|
||||
to_chat(user, "<span class='warning'>You don't want to harm [target]!</span>")
|
||||
return FALSE
|
||||
if(user.getStaminaLoss() >= STAMINA_SOFTCRIT) //CITADEL CHANGE - makes it impossible to punch while in stamina softcrit
|
||||
if(IS_STAMCRIT(user)) //CITADEL CHANGE - makes it impossible to punch while in stamina softcrit
|
||||
to_chat(user, "<span class='warning'>You're too exhausted.</span>") //CITADEL CHANGE - ditto
|
||||
return FALSE //CITADEL CHANGE - ditto
|
||||
if(target.check_martial_melee_block())
|
||||
@@ -1487,11 +1483,11 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
var/damage = rand(user.dna.species.punchdamagelow, user.dna.species.punchdamagehigh)
|
||||
|
||||
//CITADEL CHANGES - makes resting and disabled combat mode reduce punch damage, makes being out of combat mode result in you taking more damage
|
||||
if(!target.combatmode && damage < user.dna.species.punchstunthreshold)
|
||||
if(!(target.combat_flags & COMBAT_FLAG_COMBAT_ACTIVE) && damage < user.dna.species.punchstunthreshold)
|
||||
damage = user.dna.species.punchstunthreshold - 1
|
||||
if(!CHECK_MOBILITY(user, MOBILITY_STAND))
|
||||
damage *= 0.5
|
||||
if(!user.combatmode)
|
||||
if(!(user.combat_flags & COMBAT_FLAG_COMBAT_ACTIVE))
|
||||
damage *= 0.25
|
||||
//END OF CITADEL CHANGES
|
||||
|
||||
@@ -1542,10 +1538,13 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
|
||||
if(target.check_martial_melee_block()) //END EDIT
|
||||
target.visible_message("<span class='warning'>[target] blocks [user]'s disarm attempt!</span>")
|
||||
return 0
|
||||
else if(user.getStaminaLoss() >= STAMINA_SOFTCRIT)
|
||||
return FALSE
|
||||
if(IS_STAMCRIT(user))
|
||||
to_chat(user, "<span class='warning'>You're too exhausted!</span>")
|
||||
return FALSE
|
||||
else if(target.check_block())
|
||||
target.visible_message("<span class='warning'>[target] blocks [user]'s disarm attempt!</span>")
|
||||
return FALSE
|
||||
|
||||
else if(aim_for_mouth && ( target_on_help || target_restrained || target_aiming_for_mouth))
|
||||
playsound(target.loc, 'sound/weapons/slap.ogg', 50, 1, -1)
|
||||
@@ -1605,11 +1604,11 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
target.forcesay(GLOB.hit_appends)
|
||||
log_combat(user, target, "pushed over")
|
||||
return*/
|
||||
if(!target.combatmode) // CITADEL CHANGE
|
||||
if(!(target.combat_flags & COMBAT_FLAG_COMBAT_ACTIVE)) // CITADEL CHANGE
|
||||
randn += -10 //CITADEL CHANGE - being out of combat mode makes it easier for you to get disarmed
|
||||
if(!CHECK_MOBILITY(user, MOBILITY_STAND)) //CITADEL CHANGE
|
||||
randn += 100 //CITADEL CHANGE - No kosher disarming if you're resting
|
||||
if(!user.combatmode) //CITADEL CHANGE
|
||||
if(!(target.combat_flags & COMBAT_FLAG_COMBAT_ACTIVE)) //CITADEL CHANGE
|
||||
randn += 25 //CITADEL CHANGE - Makes it harder to disarm outside of combat mode
|
||||
if(user.pulling == target)
|
||||
randn += -20 //If you have the time to get someone in a grab, you should have a greater chance at snatching the thing in their hand. Will be made completely obsolete by the grab rework but i've got a poor track record for releasing big projects on time so w/e i guess
|
||||
@@ -1686,14 +1685,12 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
var/Iforce = I.force //to avoid runtimes on the forcesay checks at the bottom. Some items might delete themselves if you drop them. (stunning yourself, ninja swords)
|
||||
//CIT CHANGES START HERE - combatmode and resting checks
|
||||
var/totitemdamage = I.force
|
||||
if(iscarbon(user))
|
||||
var/mob/living/carbon/tempcarb = user
|
||||
if(!tempcarb.combatmode)
|
||||
totitemdamage *= 0.5
|
||||
if(!(user.combat_flags & COMBAT_FLAG_COMBAT_ACTIVE))
|
||||
totitemdamage *= 0.5
|
||||
if(!CHECK_MOBILITY(user, MOBILITY_STAND))
|
||||
totitemdamage *= 0.5
|
||||
if(istype(H))
|
||||
if(!H.combatmode)
|
||||
if(!(H.combat_flags & COMBAT_FLAG_COMBAT_ACTIVE))
|
||||
totitemdamage *= 1.5
|
||||
//CIT CHANGES END HERE
|
||||
var/weakness = H.check_weakness(I, user)
|
||||
@@ -1803,9 +1800,12 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
|
||||
/datum/species/proc/althelp(mob/living/carbon/human/user, mob/living/carbon/human/target, datum/martial_art/attacker_style)
|
||||
if(user == target && istype(user))
|
||||
if(user.getStaminaLoss() >= STAMINA_SOFTCRIT)
|
||||
if(IS_STAMCRIT(user))
|
||||
to_chat(user, "<span class='warning'>You're too exhausted for that.</span>")
|
||||
return
|
||||
if(!(user.combat_flags & COMBAT_FLAG_COMBAT_ACTIVE))
|
||||
to_chat(user, "<span class='warning'>You need combat mode to be active to that!</span>")
|
||||
return
|
||||
if(user.IsKnockdown() || user.IsParalyzed() || user.IsStun())
|
||||
to_chat(user, "<span class='warning'>You can't seem to force yourself up right now!</span>")
|
||||
return
|
||||
@@ -1818,7 +1818,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
playsound(user, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
|
||||
|
||||
/datum/species/proc/altdisarm(mob/living/carbon/human/user, mob/living/carbon/human/target, datum/martial_art/attacker_style)
|
||||
if(user.getStaminaLoss() >= STAMINA_SOFTCRIT)
|
||||
if(IS_STAMCRIT(user))
|
||||
to_chat(user, "<span class='warning'>You're too exhausted.</span>")
|
||||
return FALSE
|
||||
if(target.check_martial_melee_block())
|
||||
|
||||
@@ -507,10 +507,10 @@ GLOBAL_LIST_INIT(ballmer_windows_me_msg, list("Yo man, what if, we like, uh, put
|
||||
//this updates all special effects: stun, sleeping, knockdown, druggy, stuttering, etc..
|
||||
/mob/living/carbon/handle_status_effects()
|
||||
..()
|
||||
if(getStaminaLoss() && !combatmode)//CIT CHANGE - prevents stamina regen while combat mode is active
|
||||
adjustStaminaLoss(!CHECK_MOBILITY(src, MOBILITY_STAND) ? (recoveringstam ? -7.5 : -6) : -3)//CIT CHANGE - decreases adjuststaminaloss to stop stamina damage from being such a joke
|
||||
if(getStaminaLoss() && !(combat_flags & COMBAT_FLAG_COMBAT_ACTIVE)) //CIT CHANGE - prevents stamina regen while combat mode is active
|
||||
adjustStaminaLoss(!CHECK_MOBILITY(src, MOBILITY_STAND) ? ((combat_flags & COMBAT_FLAG_HARD_STAMCRIT) ? -7.5 : -6) : -3)//CIT CHANGE - decreases adjuststaminaloss to stop stamina damage from being such a joke
|
||||
|
||||
if(!recoveringstam && incomingstammult != 1)
|
||||
if(!(combat_flags & COMBAT_FLAG_HARD_STAMCRIT) && incomingstammult != 1)
|
||||
incomingstammult = max(0.01, incomingstammult)
|
||||
incomingstammult = min(1, incomingstammult*2)
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
gorillize()
|
||||
return
|
||||
if(radiation > RAD_MOB_KNOCKDOWN && prob(RAD_MOB_KNOCKDOWN_PROB))
|
||||
if(!recoveringstam)
|
||||
if(!(combat_flags & COMBAT_FLAG_HARD_STAMCRIT))
|
||||
emote("collapse")
|
||||
DefaultCombatKnockdown(RAD_MOB_KNOCKDOWN_AMOUNT)
|
||||
to_chat(src, "<span class='danger'>You feel weak.</span>")
|
||||
|
||||
@@ -118,22 +118,22 @@
|
||||
if(!CHECK_MOBILITY(src, MOBILITY_STAND) && CHECK_MOBILITY(L, MOBILITY_STAND))
|
||||
var/origtargetloc = L.loc
|
||||
if(!pulledby)
|
||||
if(attemptingcrawl)
|
||||
if(combat_flags & COMBAT_FLAG_ATTEMPTING_CRAWL)
|
||||
return TRUE
|
||||
if(getStaminaLoss() >= STAMINA_SOFTCRIT)
|
||||
if(IS_STAMCRIT(src))
|
||||
to_chat(src, "<span class='warning'>You're too exhausted to crawl under [L].</span>")
|
||||
return TRUE
|
||||
attemptingcrawl = TRUE
|
||||
ENABLE_BITFIELD(combat_flags, COMBAT_FLAG_ATTEMPTING_CRAWL)
|
||||
visible_message("<span class='notice'>[src] is attempting to crawl under [L].</span>", "<span class='notice'>You are now attempting to crawl under [L].</span>")
|
||||
if(!do_after(src, CRAWLUNDER_DELAY, target = src) || CHECK_MOBILITY(src, MOBILITY_STAND))
|
||||
attemptingcrawl = FALSE
|
||||
DISABLE_BITFIELD(combat_flags, COMBAT_FLAG_ATTEMPTING_CRAWL)
|
||||
return TRUE
|
||||
var/src_passmob = (pass_flags & PASSMOB)
|
||||
pass_flags |= PASSMOB
|
||||
Move(origtargetloc)
|
||||
if(!src_passmob)
|
||||
pass_flags &= ~PASSMOB
|
||||
attemptingcrawl = FALSE
|
||||
DISABLE_BITFIELD(combat_flags, COMBAT_FLAG_ATTEMPTING_CRAWL)
|
||||
return TRUE
|
||||
//END OF CIT CHANGES
|
||||
|
||||
@@ -368,9 +368,8 @@
|
||||
to_chat(src, "<span class='notice'>You have given up life and succumbed to death.</span>")
|
||||
death()
|
||||
|
||||
|
||||
/mob/living/incapacitated(ignore_restraints = FALSE, ignore_grab = FALSE, check_immobilized = FALSE)
|
||||
if(stat || IsUnconscious() || IsStun() || IsParalyzed() || recoveringstam || (check_immobilized && IsImmobilized()) || (!ignore_restraints && restrained(ignore_grab)))
|
||||
if(stat || IsUnconscious() || IsStun() || IsParalyzed() || (combat_flags & COMBAT_FLAG_HARD_STAMCRIT) || (check_immobilized && IsImmobilized()) || (!ignore_restraints && restrained(ignore_grab)))
|
||||
return TRUE
|
||||
|
||||
/mob/living/canUseStorage()
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
/mob/living/ComponentInitialize()
|
||||
. = ..()
|
||||
RegisterSignal(src, SIGNAL_TRAIT(TRAIT_COMBAT_MODE_LOCKED), .proc/update_combat_lock)
|
||||
|
||||
/mob/living/proc/update_combat_lock()
|
||||
var/locked = HAS_TRAIT(src, TRAIT_COMBAT_MODE_LOCKED)
|
||||
var/desired = (combat_flags & COMBAT_FLAG_COMBAT_TOGGLED)
|
||||
var/actual = (combat_flags & COMBAT_FLAG_COMBAT_ACTIVE)
|
||||
if(actual)
|
||||
if(locked)
|
||||
disable_combat_mode(FALSE, TRUE, FALSE, FALSE)
|
||||
else if(!desired)
|
||||
disable_combat_mode(TRUE, TRUE, FALSE, FALSE)
|
||||
else
|
||||
if(desired && !locked)
|
||||
enable_combat_mode(FALSE, TRUE, FALSE, FALSE)
|
||||
update_combat_mode_icon()
|
||||
|
||||
/mob/living/proc/disable_combat_mode(silent = TRUE, was_forced = FALSE, visible = FALSE, update_icon = TRUE)
|
||||
if(!(combat_flags & COMBAT_FLAG_COMBAT_ACTIVE))
|
||||
return
|
||||
DISABLE_BITFIELD(combat_flags, COMBAT_FLAG_COMBAT_ACTIVE)
|
||||
SEND_SIGNAL(src, COMSIG_LIVING_COMBAT_DISABLED, was_forced)
|
||||
if(visible)
|
||||
visible_message("<span class='warning'>[src] goes limp.</span>", "<span class='warning'>Your muscles are forcibly relaxed!</span>")
|
||||
else if(!silent)
|
||||
to_chat(src, was_forced? "<span class='warning'>Your muscles are forcibly relaxed!</span>" : "<span class='warning'>You relax your muscles.</span>")
|
||||
if(update_icon)
|
||||
update_combat_mode_icon()
|
||||
|
||||
/mob/living/proc/enable_combat_mode(silent = TRUE, was_forced = FALSE, visible = FALSE, update_icon = TRUE)
|
||||
if(combat_flags & COMBAT_FLAG_COMBAT_ACTIVE)
|
||||
return
|
||||
ENABLE_BITFIELD(combat_flags, COMBAT_FLAG_COMBAT_ACTIVE)
|
||||
SEND_SIGNAL(src, COMSIG_LIVING_COMBAT_ENABLED, was_forced)
|
||||
if(visible)
|
||||
visible_message("<span class='warning'>[src] drops into a combative stance!</span>", "<span class='warning'>You drop into a combative stance!</span>")
|
||||
else if(!silent)
|
||||
to_chat(src, was_forced? "<span class='warning'>Your muscles reflexively tighten!</span>" : "<span class='warning'>You tighten your muscles.</span>")
|
||||
if(update_icon)
|
||||
update_combat_mode_icon()
|
||||
|
||||
/// Updates the combat mode HUD icon.
|
||||
/mob/living/proc/update_combat_mode_icon()
|
||||
var/obj/screen/combattoggle/T = locate() in hud_used?.static_inventory
|
||||
T?.update_icon_state()
|
||||
|
||||
/// Enables intentionally being in combat mode. Please try not to use this proc for feedback whenever possible.
|
||||
/mob/living/proc/enable_intentional_combat_mode(silent = TRUE, visible = FALSE)
|
||||
if((combat_flags & COMBAT_FLAG_COMBAT_TOGGLED) && (combat_flags & COMBAT_FLAG_COMBAT_ACTIVE))
|
||||
return
|
||||
ENABLE_BITFIELD(combat_flags, COMBAT_FLAG_COMBAT_TOGGLED)
|
||||
if(!HAS_TRAIT(src, TRAIT_COMBAT_MODE_LOCKED) && !(combat_flags & COMBAT_FLAG_COMBAT_ACTIVE))
|
||||
enable_combat_mode(silent, FALSE, visible, FALSE)
|
||||
update_combat_mode_icon()
|
||||
client?.show_popup_menus = FALSE
|
||||
return TRUE
|
||||
|
||||
/// Disables intentionally being in combat mode. Please try not to use this proc for feedback whenever possible.
|
||||
/mob/living/proc/disable_intentional_combat_mode(silent = TRUE, visible = FALSE)
|
||||
if(!(combat_flags & COMBAT_FLAG_COMBAT_TOGGLED) && !(combat_flags & COMBAT_FLAG_COMBAT_ACTIVE))
|
||||
return
|
||||
DISABLE_BITFIELD(combat_flags, COMBAT_FLAG_COMBAT_TOGGLED)
|
||||
if(combat_flags & COMBAT_FLAG_COMBAT_ACTIVE)
|
||||
disable_combat_mode(silent, FALSE, visible, FALSE)
|
||||
update_combat_mode_icon()
|
||||
client?.show_popup_menus = TRUE
|
||||
return TRUE
|
||||
|
||||
/// Toggles whether the user is intentionally in combat mode. THIS should be the proc you generally use! Has built in visual/to other player feedback, as well as an audible cue to ourselves.
|
||||
/mob/living/proc/user_toggle_intentional_combat_mode(visible = TRUE)
|
||||
var/old = (combat_flags & COMBAT_FLAG_COMBAT_TOGGLED)
|
||||
if(old)
|
||||
disable_intentional_combat_mode()
|
||||
playsound_local(src, 'sound/misc/ui_toggleoff.ogg', 50, FALSE, pressure_affected = FALSE) //Slightly modified version of the above!
|
||||
else if(CAN_TOGGLE_COMBAT_MODE(src))
|
||||
enable_intentional_combat_mode()
|
||||
var/current = (combat_flags & COMBAT_FLAG_COMBAT_ACTIVE) //because we could be locked
|
||||
if(current != old) //only sound effect if you succeeded. Could have the feedback system be better but shrug, someone else can do it.
|
||||
if(current)
|
||||
playsound_local(src, 'sound/misc/ui_toggle.ogg', 50, FALSE, pressure_affected = FALSE) //Sound from interbay!
|
||||
if(visible)
|
||||
if(world.time >= combatmessagecooldown)
|
||||
combatmessagecooldown = world.time + 10 SECONDS
|
||||
if(a_intent != INTENT_HELP)
|
||||
visible_message("<span class='warning'>[src] [resting ? "tenses up" : (prob(95)? "drops into a combative stance" : (prob(95)? "poses aggressively" : "asserts dominance with their pose"))].</span>")
|
||||
else
|
||||
visible_message("<span class='notice'>[src] [pick("looks","seems","goes")] [pick("alert","attentive","vigilant")].</span>")
|
||||
@@ -118,3 +118,22 @@
|
||||
|
||||
/// Next world.time when we can get the "you can't move while buckled to [thing]" message.
|
||||
var/buckle_message_cooldown = 0
|
||||
|
||||
//// CITADEL STATION COMBAT ////
|
||||
/// See __DEFINES/combat.dm
|
||||
var/combat_flags = COMBAT_FLAGS_STAMSYSTEM_EXEMPT
|
||||
/// Next world.time when we will show a visible message on entering combat mode voluntarily again.
|
||||
var/combatmessagecooldown = 0
|
||||
|
||||
var/incomingstammult = 1
|
||||
var/bufferedstam = 0
|
||||
var/stambuffer = 20
|
||||
var/stambufferregentime
|
||||
|
||||
//Sprint buffer---
|
||||
var/sprint_buffer = 42 //Tiles
|
||||
var/sprint_buffer_max = 42
|
||||
var/sprint_buffer_regen_ds = 0.3 //Tiles per world.time decisecond
|
||||
var/sprint_buffer_regen_last = 0 //last world.time this was regen'd for math.
|
||||
var/sprint_stamina_cost = 0.70 //stamina loss per tile while insufficient sprint buffer.
|
||||
//---End
|
||||
|
||||
@@ -33,9 +33,9 @@
|
||||
set name = "Rest"
|
||||
set category = "IC"
|
||||
if(client?.prefs?.autostand)
|
||||
intentionalresting = !intentionalresting
|
||||
to_chat(src, "<span class='notice'>You are now attempting to [intentionalresting ? "[!resting ? "lay down and ": ""]stay down" : "[resting ? "get up and ": ""]stay up"].</span>")
|
||||
if(intentionalresting && !resting)
|
||||
TOGGLE_BITFIELD(combat_flags, COMBAT_FLAG_INTENTIONALLY_RESTING)
|
||||
to_chat(src, "<span class='notice'>You are now attempting to [(combat_flags & COMBAT_FLAG_INTENTIONALLY_RESTING) ? "[!resting ? "lay down and ": ""]stay down" : "[resting ? "get up and ": ""]stay up"].</span>")
|
||||
if((combat_flags & COMBAT_FLAG_INTENTIONALLY_RESTING) && !resting)
|
||||
set_resting(TRUE, FALSE)
|
||||
else
|
||||
resist_a_rest()
|
||||
@@ -71,8 +71,8 @@
|
||||
var/restrained = restrained()
|
||||
var/pinned = resting && pulledby && pulledby.grab_state >= GRAB_AGGRESSIVE // Cit change - adds pinning for aggressive-grabbing people on the ground
|
||||
var/has_limbs = has_arms || ignore_legs || has_legs
|
||||
var/canmove = !immobilize && !stun && conscious && !paralyze && (!stat_softcrit || !pulledby) && !chokehold && !IsFrozen() && has_limbs && !pinned && !recoveringstam
|
||||
var/canresist = !stun && conscious && !stat_softcrit && !paralyze && has_limbs && !recoveringstam
|
||||
var/canmove = !immobilize && !stun && conscious && !paralyze && (!stat_softcrit || !pulledby) && !chokehold && !IsFrozen() && has_limbs && !pinned && !(combat_flags & COMBAT_FLAG_HARD_STAMCRIT)
|
||||
var/canresist = !stun && conscious && !stat_softcrit && !paralyze && has_limbs && !(combat_flags & COMBAT_FLAG_HARD_STAMCRIT)
|
||||
|
||||
if(canmove)
|
||||
mobility_flags |= MOBILITY_MOVE
|
||||
@@ -84,7 +84,7 @@
|
||||
else
|
||||
mobility_flags &= ~MOBILITY_RESIST
|
||||
|
||||
var/canstand_involuntary = conscious && !stat_softcrit && !knockdown && !chokehold && !paralyze && (ignore_legs || has_legs) && !(buckled && buckled.buckle_lying) && !recoveringstam
|
||||
var/canstand_involuntary = conscious && !stat_softcrit && !knockdown && !chokehold && !paralyze && (ignore_legs || has_legs) && !(buckled && buckled.buckle_lying) && !(combat_flags & COMBAT_FLAG_HARD_STAMCRIT)
|
||||
var/canstand = canstand_involuntary && !resting
|
||||
|
||||
var/should_be_lying = !canstand
|
||||
@@ -107,7 +107,7 @@
|
||||
else
|
||||
mobility_flags |= MOBILITY_UI|MOBILITY_PULL
|
||||
|
||||
var/canitem_general = !paralyze && !stun && conscious && !(stat_softcrit) && !chokehold && !restrained && has_arms && !recoveringstam
|
||||
var/canitem_general = !paralyze && !stun && conscious && !(stat_softcrit) && !chokehold && !restrained && has_arms && !(combat_flags & COMBAT_FLAG_HARD_STAMCRIT)
|
||||
if(canitem_general)
|
||||
mobility_flags |= (MOBILITY_USE | MOBILITY_PICKUP | MOBILITY_STORAGE | MOBILITY_HOLD)
|
||||
else
|
||||
@@ -149,7 +149,7 @@
|
||||
lying_prev = lying
|
||||
|
||||
//Handle citadel autoresist
|
||||
if(CHECK_MOBILITY(src, MOBILITY_MOVE) && !intentionalresting && canstand_involuntary && iscarbon(src) && client?.prefs?.autostand)//CIT CHANGE - adds autostanding as a preference
|
||||
if(CHECK_MOBILITY(src, MOBILITY_MOVE) && !(combat_flags & COMBAT_FLAG_INTENTIONALLY_RESTING) && canstand_involuntary && iscarbon(src) && client?.prefs?.autostand)//CIT CHANGE - adds autostanding as a preference
|
||||
addtimer(CALLBACK(src, .proc/resist_a_rest, TRUE), 0) //CIT CHANGE - ditto
|
||||
|
||||
// Movespeed mods based on arms/legs quantity
|
||||
|
||||
@@ -31,8 +31,16 @@
|
||||
|
||||
/mob/living/update_config_movespeed()
|
||||
update_move_intent_slowdown()
|
||||
sprint_buffer_max = CONFIG_GET(number/movedelay/sprint_buffer_max)
|
||||
sprint_buffer_regen_ds = CONFIG_GET(number/movedelay/sprint_buffer_regen_per_ds)
|
||||
sprint_stamina_cost = CONFIG_GET(number/movedelay/sprint_stamina_cost)
|
||||
return ..()
|
||||
|
||||
/mob/living/movement_delay(ignorewalk = 0)
|
||||
. = ..()
|
||||
if(!CHECK_MOBILITY(src, MOBILITY_STAND))
|
||||
. += 6
|
||||
|
||||
/// whether or not we can slide under another living mob. defaults to if we're not dense. CanPass should check "overriding circumstances" like buckled mobs/having PASSMOB flag, etc.
|
||||
/mob/living/proc/can_move_under_living(mob/living/other)
|
||||
return !density
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
/mob/living/ComponentInitialize()
|
||||
. = ..()
|
||||
RegisterSignal(src, SIGNAL_TRAIT(TRAIT_SPRINT_LOCKED), .proc/update_sprint_lock)
|
||||
|
||||
/mob/living/proc/update_sprint_icon()
|
||||
var/obj/screen/sprintbutton/S = locate() in hud_used?.static_inventory
|
||||
S?.update_icon_state()
|
||||
|
||||
/mob/living/proc/update_hud_sprint_bar()
|
||||
hud_used?.sprint_buffer?.update_to_mob(src)
|
||||
|
||||
/mob/living/proc/update_sprint_lock()
|
||||
var/locked = HAS_TRAIT(src, TRAIT_SPRINT_LOCKED)
|
||||
var/current = (combat_flags & COMBAT_FLAG_SPRINT_ACTIVE)
|
||||
var/desired = (combat_flags & COMBAT_FLAG_SPRINT_TOGGLED)
|
||||
if(locked)
|
||||
if(current)
|
||||
disable_sprint_mode(FALSE)
|
||||
else
|
||||
if(current)
|
||||
if(!desired)
|
||||
disable_sprint_mode(FALSE)
|
||||
else
|
||||
if(desired)
|
||||
enable_sprint_mode(FALSE)
|
||||
update_sprint_icon()
|
||||
|
||||
/mob/living/proc/enable_sprint_mode(update_icon = TRUE)
|
||||
if(combat_flags & COMBAT_FLAG_SPRINT_ACTIVE)
|
||||
return
|
||||
ENABLE_BITFIELD(combat_flags, COMBAT_FLAG_SPRINT_ACTIVE)
|
||||
if(update_icon)
|
||||
update_sprint_icon()
|
||||
|
||||
/mob/living/proc/disable_sprint_mode(update_icon = TRUE)
|
||||
if(!(combat_flags & COMBAT_FLAG_SPRINT_ACTIVE))
|
||||
return
|
||||
DISABLE_BITFIELD(combat_flags, COMBAT_FLAG_SPRINT_ACTIVE)
|
||||
if(update_icon)
|
||||
update_sprint_icon()
|
||||
|
||||
/mob/living/proc/enable_intentional_sprint_mode()
|
||||
if((combat_flags & COMBAT_FLAG_SPRINT_TOGGLED) && (combat_flags & COMBAT_FLAG_SPRINT_ACTIVE))
|
||||
return
|
||||
ENABLE_BITFIELD(combat_flags, COMBAT_FLAG_SPRINT_TOGGLED)
|
||||
if(!HAS_TRAIT(src, TRAIT_SPRINT_LOCKED) && !(combat_flags & COMBAT_FLAG_SPRINT_ACTIVE))
|
||||
enable_sprint_mode(FALSE)
|
||||
update_sprint_icon()
|
||||
return TRUE
|
||||
|
||||
/mob/living/proc/disable_intentional_sprint_mode()
|
||||
if(!(combat_flags & COMBAT_FLAG_SPRINT_TOGGLED) && !(combat_flags & COMBAT_FLAG_SPRINT_ACTIVE))
|
||||
return
|
||||
DISABLE_BITFIELD(combat_flags, COMBAT_FLAG_SPRINT_TOGGLED)
|
||||
if(combat_flags & COMBAT_FLAG_SPRINT_ACTIVE)
|
||||
disable_sprint_mode(FALSE)
|
||||
update_sprint_icon()
|
||||
|
||||
/mob/living/proc/user_toggle_intentional_sprint_mode()
|
||||
var/old = (combat_flags & COMBAT_FLAG_SPRINT_TOGGLED)
|
||||
if(old)
|
||||
disable_intentional_sprint_mode()
|
||||
if((m_intent == MOVE_INTENT_RUN) && CHECK_ALL_MOBILITY(src, MOBILITY_STAND|MOBILITY_MOVE))
|
||||
playsound_local(src, 'sound/misc/sprintdeactivate.ogg', 50, FALSE, pressure_affected = FALSE)
|
||||
else
|
||||
enable_intentional_sprint_mode()
|
||||
if((m_intent == MOVE_INTENT_RUN) && CHECK_ALL_MOBILITY(src, MOBILITY_STAND|MOBILITY_MOVE))
|
||||
playsound_local(src, 'sound/misc/sprintactivate.ogg', 50, FALSE, pressure_affected = FALSE)
|
||||
|
||||
/mob/living/proc/sprint_hotkey(targetstatus)
|
||||
if(targetstatus != FORCE_BOOLEAN(combat_flags & COMBAT_FLAG_SPRINT_ACTIVE))
|
||||
default_toggle_sprint()
|
||||
|
||||
/mob/living/proc/doSprintLossTiles(amount)
|
||||
return
|
||||
|
||||
// Silicons have snowflake behavior.
|
||||
/mob/living/proc/default_toggle_sprint()
|
||||
return user_toggle_intentional_sprint_mode()
|
||||
@@ -12,3 +12,15 @@
|
||||
/mob/living/silicon/robot/experience_pressure_difference(pressure_difference, direction)
|
||||
if(!magpulse)
|
||||
return ..()
|
||||
|
||||
/mob/living/silicon/robot/Move(NewLoc, direct)
|
||||
. = ..()
|
||||
if(. && (combat_flags & COMBAT_FLAG_SPRINT_ACTIVE) && !(movement_type & FLYING) && CHECK_ALL_MOBILITY(src, MOBILITY_STAND | MOBILITY_MOVE))
|
||||
if(!(cell?.use(25)))
|
||||
default_toggle_sprint(TRUE)
|
||||
|
||||
/mob/living/silicon/robot/movement_delay()
|
||||
. = ..()
|
||||
if(!resting && !(combat_flags & COMBAT_FLAG_SPRINT_ACTIVE))
|
||||
. += 1
|
||||
. += speed
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
/mob/living/silicon/robot/default_toggle_sprint(shutdown = FALSE)
|
||||
var/current = (combat_flags & COMBAT_FLAG_SPRINT_ACTIVE)
|
||||
if(current || shutdown || !cell || (cell.charge < 25) || !cansprint)
|
||||
disable_intentional_sprint_mode()
|
||||
if(CHECK_MULTIPLE_BITFIELDS(mobility_flags, MOBILITY_STAND|MOBILITY_MOVE))
|
||||
if(shutdown)
|
||||
playsound_local(src, 'sound/effects/light_flicker.ogg', 50, FALSE, pressure_affected = FALSE)
|
||||
playsound_local(src, 'sound/misc/sprintdeactivate.ogg', 50, FALSE, pressure_affected = FALSE)
|
||||
else
|
||||
enable_intentional_sprint_mode()
|
||||
if(CHECK_MULTIPLE_BITFIELDS(mobility_flags, MOBILITY_STAND|MOBILITY_MOVE))
|
||||
playsound_local(src, 'sound/misc/sprintactivate.ogg', 50, FALSE, pressure_affected = FALSE)
|
||||
@@ -15,6 +15,8 @@
|
||||
speech_span = SPAN_ROBOT
|
||||
flags_1 = PREVENT_CONTENTS_EXPLOSION_1 | HEAR_1
|
||||
no_vore = TRUE
|
||||
/// Enable sprint system but not stamina
|
||||
combat_flags = COMBAT_FLAGS_STAMEXEMPT_YESSPRINT
|
||||
|
||||
var/datum/ai_laws/laws = null//Now... THEY ALL CAN ALL HAVE LAWS
|
||||
var/last_lawchange_announce = 0
|
||||
|
||||
@@ -276,7 +276,7 @@ Auto Patrol[]"},
|
||||
if(BOT_PREP_ARREST) // preparing to arrest target
|
||||
|
||||
// see if he got away. If he's no no longer adjacent or inside a closet or about to get up, we hunt again.
|
||||
if(!Adjacent(target) || !isturf(target.loc) || !target.recoveringstam || target.getStaminaLoss() <= 120) // CIT CHANGE - replaces amountknockdown with recoveringstam and staminaloss checks
|
||||
if(!Adjacent(target) || !isturf(target.loc) || !(target.combat_flags & COMBAT_FLAG_HARD_STAMCRIT) || target.getStaminaLoss() <= 120) // CIT CHANGE - replaces amountknockdown with recoveringstam and staminaloss checks
|
||||
back_to_hunt()
|
||||
return
|
||||
|
||||
@@ -303,7 +303,7 @@ Auto Patrol[]"},
|
||||
back_to_idle()
|
||||
return
|
||||
|
||||
if(!Adjacent(target) || !isturf(target.loc) || (target.loc != target_lastloc && !target.recoveringstam && target.getStaminaLoss() <= 120)) //if he's changed loc and about to get up or not adjacent or got into a closet, we prep arrest again. CIT CHANGE - replaces amountknockdown with recoveringstam and staminaloss checks
|
||||
if(!Adjacent(target) || !isturf(target.loc) || (target.loc != target_lastloc && !(target.combat_flags & COMBAT_FLAG_HARD_STAMCRIT) && target.getStaminaLoss() <= 120)) //if he's changed loc and about to get up or not adjacent or got into a closet, we prep arrest again. CIT CHANGE - replaces amountknockdown with recoveringstam and staminaloss checks
|
||||
back_to_hunt()
|
||||
return
|
||||
else
|
||||
|
||||
@@ -312,7 +312,7 @@ Auto Patrol: []"},
|
||||
if(BOT_PREP_ARREST) // preparing to arrest target
|
||||
|
||||
// see if he got away. If he's no no longer adjacent or inside a closet or about to get up, we hunt again.
|
||||
if( !Adjacent(target) || !isturf(target.loc) || target.getStaminaLoss() <= 120 || !target.recoveringstam) //CIT CHANGE - replaces amountknockdown with checks for stamina so secbots dont run into an infinite loop
|
||||
if( !Adjacent(target) || !isturf(target.loc) || target.getStaminaLoss() <= 120 || !(target.combat_flags & COMBAT_FLAG_HARD_STAMCRIT)) //CIT CHANGE - replaces amountknockdown with checks for stamina so secbots dont run into an infinite loop
|
||||
back_to_hunt()
|
||||
return
|
||||
|
||||
@@ -339,7 +339,7 @@ Auto Patrol: []"},
|
||||
back_to_idle()
|
||||
return
|
||||
|
||||
if(!Adjacent(target) || !isturf(target.loc) || (target.loc != target_lastloc && !target.recoveringstam && target.getStaminaLoss() <= 120)) //if he's changed loc and about to get up or not adjacent or got into a closet, we prep arrest again. CIT CHANGE - replaces amountknockdown with recoveringstam and staminaloss check
|
||||
if(!Adjacent(target) || !isturf(target.loc) || (target.loc != target_lastloc && !(target.combat_flags & COMBAT_FLAG_HARD_STAMCRIT) && target.getStaminaLoss() <= 120)) //if he's changed loc and about to get up or not adjacent or got into a closet, we prep arrest again. CIT CHANGE - replaces amountknockdown with recoveringstam and staminaloss check
|
||||
back_to_hunt()
|
||||
return
|
||||
else //Try arresting again if the target escapes.
|
||||
|
||||
@@ -39,7 +39,8 @@
|
||||
animal_species = /mob/living/simple_animal/hostile/asteroid/gutlunch
|
||||
childtype = list(/mob/living/simple_animal/hostile/asteroid/gutlunch/gubbuck = 45, /mob/living/simple_animal/hostile/asteroid/gutlunch/guthen = 55)
|
||||
|
||||
wanted_objects = list(/obj/effect/decal/cleanable/blood/gibs/xeno, /obj/effect/decal/cleanable/blood/gibs/)
|
||||
wanted_objects = list(/obj/effect/decal/cleanable/blood/gibs/xeno, /obj/effect/decal/cleanable/blood/gibs/, /obj/item/bodypart, /obj/item/organ/appendix, /obj/item/organ/ears, /obj/item/organ/eyes, /obj/item/organ/heart, /obj/item/organ/liver, \
|
||||
/obj/item/organ/lungs, /obj/item/organ/stomach, /obj/item/organ/tongue) // So we dont eat implants or brains. Still can eat robotic stuff thats subtyped of base line but thats a issue for a nother day.
|
||||
var/obj/item/udder/gutlunch/udder = null
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/gutlunch/Initialize()
|
||||
|
||||
@@ -30,45 +30,48 @@
|
||||
/mob/living/proc/Stun(amount, updating = TRUE, ignore_canstun = FALSE) //Can't go below remaining duration
|
||||
if(SEND_SIGNAL(src, COMSIG_LIVING_STATUS_STUN, amount, updating, ignore_canstun) & COMPONENT_NO_STUN)
|
||||
return
|
||||
if(((status_flags & CANSTUN) && !HAS_TRAIT(src, TRAIT_STUNIMMUNE)) || ignore_canstun)
|
||||
if(absorb_stun(amount, ignore_canstun))
|
||||
return
|
||||
var/datum/status_effect/incapacitating/stun/S = IsStun()
|
||||
if(S)
|
||||
S.duration = max(world.time + amount, S.duration)
|
||||
else if(amount > 0)
|
||||
S = apply_status_effect(STATUS_EFFECT_STUN, amount, updating)
|
||||
return S
|
||||
if(!ignore_canstun && (!(status_flags & CANSTUN) || HAS_TRAIT(src, TRAIT_STUNIMMUNE)))
|
||||
return
|
||||
if(absorb_stun(amount, ignore_canstun))
|
||||
return
|
||||
var/datum/status_effect/incapacitating/stun/S = IsStun()
|
||||
if(S)
|
||||
S.duration = max(world.time + amount, S.duration)
|
||||
else if(amount > 0)
|
||||
S = apply_status_effect(STATUS_EFFECT_STUN, amount, updating)
|
||||
return S
|
||||
|
||||
/mob/living/proc/SetStun(amount, updating = TRUE, ignore_canstun = FALSE) //Sets remaining duration
|
||||
if(SEND_SIGNAL(src, COMSIG_LIVING_STATUS_STUN, amount, updating, ignore_canstun) & COMPONENT_NO_STUN)
|
||||
return
|
||||
if(((status_flags & CANSTUN) && !HAS_TRAIT(src, TRAIT_STUNIMMUNE)) || ignore_canstun)
|
||||
var/datum/status_effect/incapacitating/stun/S = IsStun()
|
||||
if(amount <= 0)
|
||||
if(S)
|
||||
qdel(S)
|
||||
if(!ignore_canstun && (!(status_flags & CANSTUN) || HAS_TRAIT(src, TRAIT_STUNIMMUNE)))
|
||||
return
|
||||
var/datum/status_effect/incapacitating/stun/S = IsStun()
|
||||
if(amount <= 0)
|
||||
if(S)
|
||||
qdel(S)
|
||||
else
|
||||
if(absorb_stun(amount, ignore_canstun))
|
||||
return
|
||||
if(S)
|
||||
S.duration = world.time + amount
|
||||
else
|
||||
if(absorb_stun(amount, ignore_canstun))
|
||||
return
|
||||
if(S)
|
||||
S.duration = world.time + amount
|
||||
else
|
||||
S = apply_status_effect(STATUS_EFFECT_STUN, amount, updating)
|
||||
return S
|
||||
S = apply_status_effect(STATUS_EFFECT_STUN, amount, updating)
|
||||
return S
|
||||
|
||||
/mob/living/proc/AdjustStun(amount, updating = TRUE, ignore_canstun = FALSE) //Adds to remaining duration
|
||||
if(SEND_SIGNAL(src, COMSIG_LIVING_STATUS_STUN, amount, updating, ignore_canstun) & COMPONENT_NO_STUN)
|
||||
return
|
||||
if(((status_flags & CANSTUN) && !HAS_TRAIT(src, TRAIT_STUNIMMUNE)) || ignore_canstun)
|
||||
if(absorb_stun(amount, ignore_canstun))
|
||||
return
|
||||
var/datum/status_effect/incapacitating/stun/S = IsStun()
|
||||
if(S)
|
||||
S.duration += amount
|
||||
else if(amount > 0)
|
||||
S = apply_status_effect(STATUS_EFFECT_STUN, amount, updating)
|
||||
return S
|
||||
if(!ignore_canstun && (!(status_flags & CANSTUN) || HAS_TRAIT(src, TRAIT_STUNIMMUNE)))
|
||||
return
|
||||
if(absorb_stun(amount, ignore_canstun))
|
||||
return
|
||||
var/datum/status_effect/incapacitating/stun/S = IsStun()
|
||||
if(S)
|
||||
S.duration += amount
|
||||
else if(amount > 0)
|
||||
S = apply_status_effect(STATUS_EFFECT_STUN, amount, updating)
|
||||
return S
|
||||
|
||||
///////////////////////////////// KNOCKDOWN /////////////////////////////////////
|
||||
|
||||
@@ -84,45 +87,48 @@
|
||||
/mob/living/proc/Knockdown(amount, updating = TRUE, ignore_canstun = FALSE) //Can't go below remaining duration
|
||||
if(SEND_SIGNAL(src, COMSIG_LIVING_STATUS_KNOCKDOWN, amount, updating, ignore_canstun) & COMPONENT_NO_STUN)
|
||||
return
|
||||
if(((status_flags & CANKNOCKDOWN) && !HAS_TRAIT(src, TRAIT_STUNIMMUNE)) || ignore_canstun)
|
||||
if(absorb_stun(amount, ignore_canstun))
|
||||
return
|
||||
var/datum/status_effect/incapacitating/knockdown/K = IsKnockdown()
|
||||
if(K)
|
||||
K.duration = max(world.time + amount, K.duration)
|
||||
else if(amount > 0)
|
||||
K = apply_status_effect(STATUS_EFFECT_KNOCKDOWN, amount, updating)
|
||||
return K
|
||||
if(!ignore_canstun && (!(status_flags & CANKNOCKDOWN) || HAS_TRAIT(src, TRAIT_STUNIMMUNE)))
|
||||
return
|
||||
if(absorb_stun(amount, ignore_canstun))
|
||||
return
|
||||
var/datum/status_effect/incapacitating/knockdown/K = IsKnockdown()
|
||||
if(K)
|
||||
K.duration = max(world.time + amount, K.duration)
|
||||
else if(amount > 0)
|
||||
K = apply_status_effect(STATUS_EFFECT_KNOCKDOWN, amount, updating)
|
||||
return K
|
||||
|
||||
/mob/living/proc/SetKnockdown(amount, updating = TRUE, ignore_canstun = FALSE) //Sets remaining duration
|
||||
if(SEND_SIGNAL(src, COMSIG_LIVING_STATUS_KNOCKDOWN, amount, updating, ignore_canstun) & COMPONENT_NO_STUN)
|
||||
return
|
||||
if(((status_flags & CANKNOCKDOWN) && !HAS_TRAIT(src, TRAIT_STUNIMMUNE)) || ignore_canstun)
|
||||
var/datum/status_effect/incapacitating/knockdown/K = IsKnockdown()
|
||||
if(amount <= 0)
|
||||
if(K)
|
||||
qdel(K)
|
||||
if(!ignore_canstun && (!(status_flags & CANKNOCKDOWN) || HAS_TRAIT(src, TRAIT_STUNIMMUNE)))
|
||||
return
|
||||
var/datum/status_effect/incapacitating/knockdown/K = IsKnockdown()
|
||||
if(amount <= 0)
|
||||
if(K)
|
||||
qdel(K)
|
||||
else
|
||||
if(absorb_stun(amount, ignore_canstun))
|
||||
return
|
||||
if(K)
|
||||
K.duration = world.time + amount
|
||||
else
|
||||
if(absorb_stun(amount, ignore_canstun))
|
||||
return
|
||||
if(K)
|
||||
K.duration = world.time + amount
|
||||
else
|
||||
K = apply_status_effect(STATUS_EFFECT_KNOCKDOWN, amount, updating)
|
||||
return K
|
||||
K = apply_status_effect(STATUS_EFFECT_KNOCKDOWN, amount, updating)
|
||||
return K
|
||||
|
||||
/mob/living/proc/AdjustKnockdown(amount, updating = TRUE, ignore_canstun = FALSE) //Adds to remaining duration
|
||||
if(SEND_SIGNAL(src, COMSIG_LIVING_STATUS_KNOCKDOWN, amount, updating, ignore_canstun) & COMPONENT_NO_STUN)
|
||||
return
|
||||
if(((status_flags & CANKNOCKDOWN) && !HAS_TRAIT(src, TRAIT_STUNIMMUNE)) || ignore_canstun)
|
||||
if(absorb_stun(amount, ignore_canstun))
|
||||
return
|
||||
var/datum/status_effect/incapacitating/knockdown/K = IsKnockdown()
|
||||
if(K)
|
||||
K.duration += amount
|
||||
else if(amount > 0)
|
||||
K = apply_status_effect(STATUS_EFFECT_KNOCKDOWN, amount, updating)
|
||||
return K
|
||||
if(!ignore_canstun && (!(status_flags & CANKNOCKDOWN) || HAS_TRAIT(src, TRAIT_STUNIMMUNE)))
|
||||
return
|
||||
if(absorb_stun(amount, ignore_canstun))
|
||||
return
|
||||
var/datum/status_effect/incapacitating/knockdown/K = IsKnockdown()
|
||||
if(K)
|
||||
K.duration += amount
|
||||
else if(amount > 0)
|
||||
K = apply_status_effect(STATUS_EFFECT_KNOCKDOWN, amount, updating)
|
||||
return K
|
||||
|
||||
///////////////////////////////// IMMOBILIZED ////////////////////////////////////
|
||||
/mob/living/proc/IsImmobilized() //If we're immobilized
|
||||
@@ -137,45 +143,48 @@
|
||||
/mob/living/proc/Immobilize(amount, updating = TRUE, ignore_canstun = FALSE) //Can't go below remaining duration
|
||||
if(SEND_SIGNAL(src, COMSIG_LIVING_STATUS_IMMOBILIZE, amount, updating, ignore_canstun) & COMPONENT_NO_STUN)
|
||||
return
|
||||
if(((status_flags & CANKNOCKDOWN) && !HAS_TRAIT(src, TRAIT_STUNIMMUNE)) || ignore_canstun)
|
||||
if(absorb_stun(amount, ignore_canstun))
|
||||
return
|
||||
var/datum/status_effect/incapacitating/immobilized/I = IsImmobilized()
|
||||
if(I)
|
||||
I.duration = max(world.time + amount, I.duration)
|
||||
else if(amount > 0)
|
||||
I = apply_status_effect(STATUS_EFFECT_IMMOBILIZED, amount, updating)
|
||||
return I
|
||||
if(!ignore_canstun && (!(status_flags & CANKNOCKDOWN) || HAS_TRAIT(src, TRAIT_STUNIMMUNE)))
|
||||
return
|
||||
if(absorb_stun(amount, ignore_canstun))
|
||||
return
|
||||
var/datum/status_effect/incapacitating/immobilized/I = IsImmobilized()
|
||||
if(I)
|
||||
I.duration = max(world.time + amount, I.duration)
|
||||
else if(amount > 0)
|
||||
I = apply_status_effect(STATUS_EFFECT_IMMOBILIZED, amount, updating)
|
||||
return I
|
||||
|
||||
/mob/living/proc/SetImmobilized(amount, updating = TRUE, ignore_canstun = FALSE) //Sets remaining duration
|
||||
if(SEND_SIGNAL(src, COMSIG_LIVING_STATUS_IMMOBILIZE, amount, updating, ignore_canstun) & COMPONENT_NO_STUN)
|
||||
return
|
||||
if(((status_flags & CANKNOCKDOWN) && !HAS_TRAIT(src, TRAIT_STUNIMMUNE)) || ignore_canstun)
|
||||
var/datum/status_effect/incapacitating/immobilized/I = IsImmobilized()
|
||||
if(amount <= 0)
|
||||
if(I)
|
||||
qdel(I)
|
||||
if(!ignore_canstun && (!(status_flags & CANKNOCKDOWN) || HAS_TRAIT(src, TRAIT_STUNIMMUNE)))
|
||||
return
|
||||
var/datum/status_effect/incapacitating/immobilized/I = IsImmobilized()
|
||||
if(amount <= 0)
|
||||
if(I)
|
||||
qdel(I)
|
||||
else
|
||||
if(absorb_stun(amount, ignore_canstun))
|
||||
return
|
||||
if(I)
|
||||
I.duration = world.time + amount
|
||||
else
|
||||
if(absorb_stun(amount, ignore_canstun))
|
||||
return
|
||||
if(I)
|
||||
I.duration = world.time + amount
|
||||
else
|
||||
I = apply_status_effect(STATUS_EFFECT_IMMOBILIZED, amount, updating)
|
||||
return I
|
||||
I = apply_status_effect(STATUS_EFFECT_IMMOBILIZED, amount, updating)
|
||||
return I
|
||||
|
||||
/mob/living/proc/AdjustImmobilized(amount, updating = TRUE, ignore_canstun = FALSE) //Adds to remaining duration
|
||||
if(SEND_SIGNAL(src, COMSIG_LIVING_STATUS_IMMOBILIZE, amount, updating, ignore_canstun) & COMPONENT_NO_STUN)
|
||||
return
|
||||
if(((status_flags & CANKNOCKDOWN) && !HAS_TRAIT(src, TRAIT_STUNIMMUNE)) || ignore_canstun)
|
||||
if(absorb_stun(amount, ignore_canstun))
|
||||
return
|
||||
var/datum/status_effect/incapacitating/immobilized/I = IsImmobilized()
|
||||
if(I)
|
||||
I.duration += amount
|
||||
else if(amount > 0)
|
||||
I = apply_status_effect(STATUS_EFFECT_IMMOBILIZED, amount, updating)
|
||||
return I
|
||||
if(!ignore_canstun && (!(status_flags & CANKNOCKDOWN) || HAS_TRAIT(src, TRAIT_STUNIMMUNE)))
|
||||
return
|
||||
if(absorb_stun(amount, ignore_canstun))
|
||||
return
|
||||
var/datum/status_effect/incapacitating/immobilized/I = IsImmobilized()
|
||||
if(I)
|
||||
I.duration += amount
|
||||
else if(amount > 0)
|
||||
I = apply_status_effect(STATUS_EFFECT_IMMOBILIZED, amount, updating)
|
||||
return I
|
||||
|
||||
///////////////////////////////// PARALYZED //////////////////////////////////
|
||||
/mob/living/proc/IsParalyzed() //If we're immobilized
|
||||
@@ -190,45 +199,48 @@
|
||||
/mob/living/proc/Paralyze(amount, updating = TRUE, ignore_canstun = FALSE) //Can't go below remaining duration
|
||||
if(SEND_SIGNAL(src, COMSIG_LIVING_STATUS_PARALYZE, amount, updating, ignore_canstun) & COMPONENT_NO_STUN)
|
||||
return
|
||||
if(((status_flags & CANKNOCKDOWN) && !HAS_TRAIT(src, TRAIT_STUNIMMUNE)) || ignore_canstun)
|
||||
if(absorb_stun(amount, ignore_canstun))
|
||||
return
|
||||
var/datum/status_effect/incapacitating/paralyzed/P = IsParalyzed(FALSE)
|
||||
if(P)
|
||||
P.duration = max(world.time + amount, P.duration)
|
||||
else if(amount > 0)
|
||||
P = apply_status_effect(STATUS_EFFECT_PARALYZED, amount, updating)
|
||||
return P
|
||||
if(!ignore_canstun && (!(status_flags & CANKNOCKDOWN) || HAS_TRAIT(src, TRAIT_STUNIMMUNE)))
|
||||
return
|
||||
if(absorb_stun(amount, ignore_canstun))
|
||||
return
|
||||
var/datum/status_effect/incapacitating/paralyzed/P = IsParalyzed(FALSE)
|
||||
if(P)
|
||||
P.duration = max(world.time + amount, P.duration)
|
||||
else if(amount > 0)
|
||||
P = apply_status_effect(STATUS_EFFECT_PARALYZED, amount, updating)
|
||||
return P
|
||||
|
||||
/mob/living/proc/SetParalyzed(amount, updating = TRUE, ignore_canstun = FALSE) //Sets remaining duration
|
||||
if(SEND_SIGNAL(src, COMSIG_LIVING_STATUS_PARALYZE, amount, updating, ignore_canstun) & COMPONENT_NO_STUN)
|
||||
return
|
||||
if(((status_flags & CANKNOCKDOWN) && !HAS_TRAIT(src, TRAIT_STUNIMMUNE)) || ignore_canstun)
|
||||
var/datum/status_effect/incapacitating/paralyzed/P = IsParalyzed(FALSE)
|
||||
if(amount <= 0)
|
||||
if(P)
|
||||
qdel(P)
|
||||
if(!ignore_canstun && (!(status_flags & CANKNOCKDOWN) || HAS_TRAIT(src, TRAIT_STUNIMMUNE)))
|
||||
return
|
||||
var/datum/status_effect/incapacitating/paralyzed/P = IsParalyzed(FALSE)
|
||||
if(amount <= 0)
|
||||
if(P)
|
||||
qdel(P)
|
||||
else
|
||||
if(absorb_stun(amount, ignore_canstun))
|
||||
return
|
||||
if(P)
|
||||
P.duration = world.time + amount
|
||||
else
|
||||
if(absorb_stun(amount, ignore_canstun))
|
||||
return
|
||||
if(P)
|
||||
P.duration = world.time + amount
|
||||
else
|
||||
P = apply_status_effect(STATUS_EFFECT_PARALYZED, amount, updating)
|
||||
return P
|
||||
P = apply_status_effect(STATUS_EFFECT_PARALYZED, amount, updating)
|
||||
return P
|
||||
|
||||
/mob/living/proc/AdjustParalyzed(amount, updating = TRUE, ignore_canstun = FALSE) //Adds to remaining duration
|
||||
if(SEND_SIGNAL(src, COMSIG_LIVING_STATUS_PARALYZE, amount, updating, ignore_canstun) & COMPONENT_NO_STUN)
|
||||
return
|
||||
if(((status_flags & CANKNOCKDOWN) && !HAS_TRAIT(src, TRAIT_STUNIMMUNE)) || ignore_canstun)
|
||||
if(absorb_stun(amount, ignore_canstun))
|
||||
return
|
||||
var/datum/status_effect/incapacitating/paralyzed/P = IsParalyzed(FALSE)
|
||||
if(P)
|
||||
P.duration += amount
|
||||
else if(amount > 0)
|
||||
P = apply_status_effect(STATUS_EFFECT_PARALYZED, amount, updating)
|
||||
return P
|
||||
if(!ignore_canstun && (!(status_flags & CANKNOCKDOWN) || HAS_TRAIT(src, TRAIT_STUNIMMUNE)))
|
||||
return
|
||||
if(absorb_stun(amount, ignore_canstun))
|
||||
return
|
||||
var/datum/status_effect/incapacitating/paralyzed/P = IsParalyzed(FALSE)
|
||||
if(P)
|
||||
P.duration += amount
|
||||
else if(amount > 0)
|
||||
P = apply_status_effect(STATUS_EFFECT_PARALYZED, amount, updating)
|
||||
return P
|
||||
|
||||
///////////////////////////////// DAZED ////////////////////////////////////
|
||||
/mob/living/proc/IsDazed() //If we're Dazed
|
||||
@@ -243,45 +255,104 @@
|
||||
/mob/living/proc/Daze(amount, updating = TRUE, ignore_canstun = FALSE) //Can't go below remaining duration
|
||||
if(SEND_SIGNAL(src, COMSIG_LIVING_STATUS_DAZE, amount, updating, ignore_canstun) & COMPONENT_NO_STUN)
|
||||
return
|
||||
if(((status_flags & CANKNOCKDOWN) && !HAS_TRAIT(src, TRAIT_STUNIMMUNE)) || ignore_canstun)
|
||||
if(absorb_stun(amount, ignore_canstun))
|
||||
return
|
||||
var/datum/status_effect/incapacitating/dazed/I = IsDazed()
|
||||
if(I)
|
||||
I.duration = max(world.time + amount, I.duration)
|
||||
else if(amount > 0)
|
||||
I = apply_status_effect(STATUS_EFFECT_DAZED, amount, updating)
|
||||
return I
|
||||
if(!ignore_canstun && (!(status_flags & CANKNOCKDOWN) || HAS_TRAIT(src, TRAIT_STUNIMMUNE)))
|
||||
return
|
||||
if(absorb_stun(amount, ignore_canstun))
|
||||
return
|
||||
var/datum/status_effect/incapacitating/dazed/I = IsDazed()
|
||||
if(I)
|
||||
I.duration = max(world.time + amount, I.duration)
|
||||
else if(amount > 0)
|
||||
I = apply_status_effect(STATUS_EFFECT_DAZED, amount, updating)
|
||||
return I
|
||||
|
||||
/mob/living/proc/SetDazed(amount, updating = TRUE, ignore_canstun = FALSE) //Sets remaining duration
|
||||
if(SEND_SIGNAL(src, COMSIG_LIVING_STATUS_DAZE, amount, updating, ignore_canstun) & COMPONENT_NO_STUN)
|
||||
return
|
||||
if(((status_flags & CANKNOCKDOWN) && !HAS_TRAIT(src, TRAIT_STUNIMMUNE)) || ignore_canstun)
|
||||
var/datum/status_effect/incapacitating/dazed/I = IsDazed()
|
||||
if(amount <= 0)
|
||||
if(I)
|
||||
qdel(I)
|
||||
if(!ignore_canstun && (!(status_flags & CANKNOCKDOWN) || HAS_TRAIT(src, TRAIT_STUNIMMUNE)))
|
||||
return
|
||||
var/datum/status_effect/incapacitating/dazed/I = IsDazed()
|
||||
if(amount <= 0)
|
||||
if(I)
|
||||
qdel(I)
|
||||
else
|
||||
if(absorb_stun(amount, ignore_canstun))
|
||||
return
|
||||
if(I)
|
||||
I.duration = world.time + amount
|
||||
else
|
||||
if(absorb_stun(amount, ignore_canstun))
|
||||
return
|
||||
if(I)
|
||||
I.duration = world.time + amount
|
||||
else
|
||||
I = apply_status_effect(STATUS_EFFECT_DAZED, amount, updating)
|
||||
return I
|
||||
I = apply_status_effect(STATUS_EFFECT_DAZED, amount, updating)
|
||||
return I
|
||||
|
||||
/mob/living/proc/AdjustDazed(amount, updating = TRUE, ignore_canstun = FALSE) //Adds to remaining duration
|
||||
if(SEND_SIGNAL(src, COMSIG_LIVING_STATUS_DAZE, amount, updating, ignore_canstun) & COMPONENT_NO_STUN)
|
||||
return
|
||||
if(((status_flags & CANKNOCKDOWN) && !HAS_TRAIT(src, TRAIT_STUNIMMUNE)) || ignore_canstun)
|
||||
if(!ignore_canstun && (!(status_flags & CANKNOCKDOWN) || HAS_TRAIT(src, TRAIT_STUNIMMUNE)))
|
||||
return
|
||||
if(absorb_stun(amount, ignore_canstun))
|
||||
return
|
||||
var/datum/status_effect/incapacitating/dazed/I = IsDazed()
|
||||
if(I)
|
||||
I.duration += amount
|
||||
else if(amount > 0)
|
||||
I = apply_status_effect(STATUS_EFFECT_DAZED, amount, updating)
|
||||
return I
|
||||
|
||||
///////////////////////////////// STAGGERED ////////////////////////////////////
|
||||
/mob/living/proc/IsStaggered() //If we're Staggered
|
||||
return has_status_effect(STATUS_EFFECT_STAGGERED)
|
||||
|
||||
/mob/living/proc/AmountStaggered() //How many deciseconds remain in our Staggered status effect
|
||||
var/datum/status_effect/staggered/I = IsStaggered()
|
||||
if(I)
|
||||
return I.duration - world.time
|
||||
return 0
|
||||
|
||||
/mob/living/proc/Stagger(amount, updating = TRUE, ignore_canstun = FALSE) //Can't go below remaining duration
|
||||
if(SEND_SIGNAL(src, COMSIG_LIVING_STATUS_STAGGER, amount, updating, ignore_canstun) & COMPONENT_NO_STUN)
|
||||
return
|
||||
if(!ignore_canstun && (!(status_flags & CANKNOCKDOWN) || HAS_TRAIT(src, TRAIT_STUNIMMUNE)))
|
||||
return
|
||||
if(absorb_stun(amount, ignore_canstun))
|
||||
return
|
||||
var/datum/status_effect/staggered/I = IsStaggered()
|
||||
if(I)
|
||||
I.duration = max(world.time + amount, I.duration)
|
||||
else if(amount > 0)
|
||||
I = apply_status_effect(STATUS_EFFECT_STAGGERED, amount, updating)
|
||||
return I
|
||||
|
||||
/mob/living/proc/SetStaggered(amount, updating = TRUE, ignore_canstun = FALSE) //Sets remaining duration
|
||||
if(SEND_SIGNAL(src, COMSIG_LIVING_STATUS_STAGGER, amount, updating, ignore_canstun) & COMPONENT_NO_STUN)
|
||||
return
|
||||
if(!ignore_canstun && (!(status_flags & CANKNOCKDOWN) || HAS_TRAIT(src, TRAIT_STUNIMMUNE)))
|
||||
return
|
||||
var/datum/status_effect/staggered/I = IsStaggered()
|
||||
if(amount <= 0)
|
||||
if(I)
|
||||
qdel(I)
|
||||
else
|
||||
if(absorb_stun(amount, ignore_canstun))
|
||||
return
|
||||
var/datum/status_effect/incapacitating/dazed/I = IsDazed()
|
||||
if(I)
|
||||
I.duration += amount
|
||||
else if(amount > 0)
|
||||
I = apply_status_effect(STATUS_EFFECT_DAZED, amount, updating)
|
||||
return I
|
||||
I.duration = world.time + amount
|
||||
else
|
||||
I = apply_status_effect(STATUS_EFFECT_STAGGERED, amount, updating)
|
||||
return I
|
||||
|
||||
/mob/living/proc/AdjustStaggered(amount, updating = TRUE, ignore_canstun = FALSE) //Adds to remaining duration
|
||||
if(SEND_SIGNAL(src, COMSIG_LIVING_STATUS_STAGGER, amount, updating, ignore_canstun) & COMPONENT_NO_STUN)
|
||||
return
|
||||
if(!ignore_canstun && (!(status_flags & CANKNOCKDOWN) || HAS_TRAIT(src, TRAIT_STUNIMMUNE)))
|
||||
return
|
||||
if(absorb_stun(amount, ignore_canstun))
|
||||
return
|
||||
var/datum/status_effect/staggered/I = IsStaggered()
|
||||
if(I)
|
||||
I.duration += amount
|
||||
else if(amount > 0)
|
||||
I = apply_status_effect(STATUS_EFFECT_STAGGERED, amount, updating)
|
||||
return I
|
||||
|
||||
//Blanket
|
||||
/mob/living/proc/AllImmobility(amount, updating, ignore_canstun = FALSE)
|
||||
@@ -290,6 +361,7 @@
|
||||
Stun(amount, FALSE, ignore_canstun)
|
||||
Immobilize(amount, FALSE, ignore_canstun)
|
||||
Daze(amount, FALSE, ignore_canstun)
|
||||
Stagger(amount, FALSE, ignore_canstun)
|
||||
if(updating)
|
||||
update_mobility()
|
||||
|
||||
@@ -299,6 +371,7 @@
|
||||
SetStun(amount, FALSE, ignore_canstun)
|
||||
SetImmobilized(amount, FALSE, ignore_canstun)
|
||||
SetDazed(amount, FALSE, ignore_canstun)
|
||||
SetStaggered(amount, FALSE, ignore_canstun)
|
||||
if(updating)
|
||||
update_mobility()
|
||||
|
||||
@@ -308,6 +381,7 @@
|
||||
AdjustStun(amount, FALSE, ignore_canstun)
|
||||
AdjustImmobilized(amount, FALSE, ignore_canstun)
|
||||
AdjustDazed(amount, FALSE, ignore_canstun)
|
||||
AdjustStaggered(amount, FALSE, ignore_canstun)
|
||||
if(updating)
|
||||
update_mobility()
|
||||
|
||||
@@ -323,11 +397,13 @@
|
||||
SetImmobilized(amount, FALSE, ignore_canstun)
|
||||
if(AmountDazed() > amount)
|
||||
SetImmobilized(amount, FALSE, ignore_canstun)
|
||||
if(AmountStaggered() > amount)
|
||||
SetStaggered(amount, FALSE, ignore_canstun)
|
||||
if(updating)
|
||||
update_mobility()
|
||||
|
||||
/mob/living/proc/HighestImmobilityAmount()
|
||||
return max(max(max(max(AmountStun(), AmountKnockdown()), AmountParalyzed()), AmountImmobilized()), AmountDazed())
|
||||
return max(AmountStun(), AmountKnockdown(), AmountParalyzed(), AmountImmobilized(), AmountDazed(), AmountStaggered())
|
||||
|
||||
//////////////////UNCONSCIOUS
|
||||
/mob/living/proc/IsUnconscious() //If we're unconscious
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
name = "Space Ninja"
|
||||
uniform = /obj/item/clothing/under/color/black/trackless
|
||||
suit = /obj/item/clothing/suit/space/space_ninja
|
||||
glasses = /obj/item/clothing/glasses/night
|
||||
glasses = /obj/item/clothing/glasses/night/syndicate
|
||||
mask = /obj/item/clothing/mask/gas/space_ninja
|
||||
head = /obj/item/clothing/head/helmet/space/space_ninja
|
||||
ears = /obj/item/radio/headset
|
||||
|
||||
@@ -168,7 +168,7 @@
|
||||
return
|
||||
if(firing)
|
||||
return
|
||||
if(user.getStaminaLoss() >= STAMINA_SOFTCRIT) //respect stamina softcrit
|
||||
if(IS_STAMCRIT(user)) //respect stamina softcrit
|
||||
to_chat(user, "<span class='warning'>You are too exhausted to fire [src]!</span>")
|
||||
return
|
||||
if(flag) //It's adjacent, is the user, or is on the user's person
|
||||
@@ -562,11 +562,11 @@
|
||||
update_icon()
|
||||
|
||||
/obj/item/gun/proc/getinaccuracy(mob/living/user)
|
||||
if(!iscarbon(user))
|
||||
if(!isliving(user))
|
||||
return FALSE
|
||||
else
|
||||
var/mob/living/carbon/holdingdude = user
|
||||
if(istype(holdingdude) && holdingdude.combatmode)
|
||||
return (max((holdingdude.lastdirchange + weapon_weight * 25) - world.time,0) * inaccuracy_modifier)
|
||||
var/mob/living/holdingdude = user
|
||||
if(istype(holdingdude) && (holdingdude.combat_flags & COMBAT_FLAG_COMBAT_ACTIVE))
|
||||
return 0
|
||||
else
|
||||
return ((weapon_weight * 25) * inaccuracy_modifier)
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
/obj/item/gun/ballistic/shotgun/attack_self(mob/living/user)
|
||||
if(recentpump > world.time)
|
||||
return
|
||||
if(istype(user) && user.getStaminaLoss() >= STAMINA_SOFTCRIT)//CIT CHANGE - makes pumping shotguns impossible in stamina softcrit
|
||||
if(IS_STAMCRIT(user))//CIT CHANGE - makes pumping shotguns impossible in stamina softcrit
|
||||
to_chat(user, "<span class='warning'>You're too exhausted for that.</span>")//CIT CHANGE - ditto
|
||||
return//CIT CHANGE - ditto
|
||||
pump(user, TRUE)
|
||||
|
||||
@@ -114,9 +114,12 @@
|
||||
|
||||
/datum/chemical_reaction/emp_pulse/on_reaction(datum/reagents/holder, multiplier)
|
||||
var/location = get_turf(holder.my_atom)
|
||||
// 100 multiplier = 4 heavy range & 7 light range. A few tiles smaller than traitor EMP grandes.
|
||||
// 200 multiplier = 8 heavy range & 14 light range. 4 tiles larger than traitor EMP grenades.
|
||||
empulse(location, round(multiplier / 12), round(multiplier / 7), 1)
|
||||
// 50 multiplier = 4 heavy range & 7 light range. A few tiles smaller than traitor EMP grandes.
|
||||
// 100 multiplier = 5 heavy range & 10 light range.
|
||||
// 200 multiplier = 7 heavy range & 14 light range. 4 tiles larger than traitor EMP grenades.
|
||||
// 300 multiplier = 8 heavy range & 17 light range. Still rather significant, considering that you can get dozens of bluespace beakers 30 minutes in with a competent crew.
|
||||
// 900 multiplier = 12 heavy range & 30 light range. Still less than 300 before this commit.
|
||||
empulse(location, round(multiplier ** (3/8)), round(multiplier ** (1/2)), 1)
|
||||
holder.clear_reagents()
|
||||
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
REMOVE_TRAIT(owner, TRAIT_PACIFISM, "slimestatus")
|
||||
owner.visible_message("<span class='notice'>[owner] stops glowing, the rainbow light fading away.</span>",
|
||||
"<span class='warning'>You no longer feel protected...</span>")
|
||||
return ..()
|
||||
|
||||
/obj/screen/alert/status_effect/slimeskin
|
||||
name = "Adamantine Slimeskin"
|
||||
@@ -56,6 +57,7 @@
|
||||
H.physiology.damage_resistance -= 10
|
||||
owner.visible_message("<span class='warning'>[owner]'s gel coating liquefies and dissolves away.</span>",
|
||||
"<span class='notice'>Your gel second-skin dissolves!</span>")
|
||||
return ..()
|
||||
|
||||
/datum/status_effect/slimerecall
|
||||
id = "slime_recall"
|
||||
@@ -87,6 +89,7 @@
|
||||
"<span class='warning'>The unknown force snatches briefly you from reality, and deposits you next to [target]!</span>")
|
||||
do_sparks(3, TRUE, owner)
|
||||
owner.forceMove(target.loc)
|
||||
return ..()
|
||||
|
||||
/obj/screen/alert/status_effect/freon/stasis
|
||||
desc = "You're frozen inside of a protective ice cube! While inside, you can't do anything, but are immune to harm! Resist to get out."
|
||||
@@ -117,6 +120,7 @@
|
||||
qdel(cube)
|
||||
owner.status_flags &= ~GODMODE
|
||||
UnregisterSignal(owner, COMSIG_LIVING_RESIST)
|
||||
return ..()
|
||||
|
||||
/datum/status_effect/slime_clone
|
||||
id = "slime_cloned"
|
||||
@@ -156,6 +160,7 @@
|
||||
if(clone)
|
||||
clone.unequip_everything()
|
||||
qdel(clone)
|
||||
return ..()
|
||||
|
||||
/obj/screen/alert/status_effect/clone_decay
|
||||
name = "Clone Decay"
|
||||
@@ -195,6 +200,7 @@
|
||||
|
||||
/datum/status_effect/bloodchill/on_remove()
|
||||
owner.remove_movespeed_modifier("bloodchilled")
|
||||
return ..()
|
||||
|
||||
/obj/screen/alert/status_effect/bloodchill
|
||||
name = "Bloodchilled"
|
||||
@@ -218,6 +224,7 @@
|
||||
|
||||
/datum/status_effect/bonechill/on_remove()
|
||||
owner.remove_movespeed_modifier("bonechilled")
|
||||
return ..()
|
||||
|
||||
/obj/screen/alert/status_effect/bonechill
|
||||
name = "Bonechilled"
|
||||
@@ -249,6 +256,7 @@ datum/status_effect/rebreathing/tick()
|
||||
|
||||
/datum/status_effect/firecookie/on_remove()
|
||||
REMOVE_TRAIT(owner, TRAIT_RESISTCOLD,"firecookie")
|
||||
return ..()
|
||||
|
||||
/datum/status_effect/watercookie
|
||||
id = "watercookie"
|
||||
@@ -266,6 +274,7 @@ datum/status_effect/rebreathing/tick()
|
||||
|
||||
/datum/status_effect/watercookie/on_remove()
|
||||
REMOVE_TRAIT(owner, TRAIT_NOSLIPWATER,"watercookie")
|
||||
return ..()
|
||||
|
||||
/datum/status_effect/metalcookie
|
||||
id = "metalcookie"
|
||||
@@ -283,6 +292,7 @@ datum/status_effect/rebreathing/tick()
|
||||
if(ishuman(owner))
|
||||
var/mob/living/carbon/human/H = owner
|
||||
H.physiology.brute_mod /= 0.9
|
||||
return ..()
|
||||
|
||||
/datum/status_effect/sparkcookie
|
||||
id = "sparkcookie"
|
||||
@@ -302,6 +312,7 @@ datum/status_effect/rebreathing/tick()
|
||||
if(ishuman(owner))
|
||||
var/mob/living/carbon/human/H = owner
|
||||
H.physiology.siemens_coeff = original_coeff
|
||||
return ..()
|
||||
|
||||
/datum/status_effect/toxincookie
|
||||
id = "toxincookie"
|
||||
@@ -315,6 +326,7 @@ datum/status_effect/rebreathing/tick()
|
||||
|
||||
/datum/status_effect/toxincookie/on_remove()
|
||||
REMOVE_TRAIT(owner, TRAIT_TOXINLOVER,"toxincookie")
|
||||
return ..()
|
||||
|
||||
/datum/status_effect/timecookie
|
||||
id = "timecookie"
|
||||
@@ -332,6 +344,7 @@ datum/status_effect/rebreathing/tick()
|
||||
if(ishuman(owner))
|
||||
var/mob/living/carbon/human/H
|
||||
H.physiology.do_after_speed /= 0.95
|
||||
return ..()
|
||||
|
||||
/datum/status_effect/lovecookie
|
||||
id = "lovecookie"
|
||||
@@ -377,6 +390,7 @@ datum/status_effect/rebreathing/tick()
|
||||
|
||||
/datum/status_effect/tarfoot/on_remove()
|
||||
owner.remove_movespeed_modifier(MOVESPEED_ID_TARFOOT)
|
||||
return ..()
|
||||
|
||||
/datum/status_effect/spookcookie
|
||||
id = "spookcookie"
|
||||
@@ -392,6 +406,7 @@ datum/status_effect/rebreathing/tick()
|
||||
|
||||
/datum/status_effect/spookcookie/on_remove()
|
||||
owner.remove_alt_appearance("spookyscary")
|
||||
return ..()
|
||||
|
||||
/datum/status_effect/peacecookie
|
||||
id = "peacecookie"
|
||||
@@ -415,6 +430,7 @@ datum/status_effect/rebreathing/tick()
|
||||
|
||||
/datum/status_effect/plur/on_remove()
|
||||
REMOVE_TRAIT(owner, TRAIT_PACIFISM, "peacecookie")
|
||||
return ..()
|
||||
|
||||
/datum/status_effect/adamantinecookie
|
||||
id = "adamantinecookie"
|
||||
@@ -432,6 +448,7 @@ datum/status_effect/rebreathing/tick()
|
||||
if(ishuman(owner))
|
||||
var/mob/living/carbon/human/H = owner
|
||||
H.physiology.burn_mod /= 0.9
|
||||
return ..()
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
//////////////////STABILIZED EXTRACTS//////////////////
|
||||
@@ -513,6 +530,7 @@ datum/status_effect/rebreathing/tick()
|
||||
|
||||
datum/status_effect/stabilized/blue/on_remove()
|
||||
REMOVE_TRAIT(owner, TRAIT_NOSLIPWATER, "slimestatus")
|
||||
return ..()
|
||||
|
||||
/datum/status_effect/stabilized/metal
|
||||
id = "stabilizedmetal"
|
||||
@@ -536,7 +554,6 @@ datum/status_effect/stabilized/blue/on_remove()
|
||||
to_chat(owner, "<span class='notice'>[linked_extract] adds a layer of slime to [S], which metamorphosizes into another sheet of material!</span>")
|
||||
return ..()
|
||||
|
||||
|
||||
/datum/status_effect/stabilized/yellow
|
||||
id = "stabilizedyellow"
|
||||
colour = "yellow"
|
||||
@@ -591,6 +608,7 @@ datum/status_effect/stabilized/blue/on_remove()
|
||||
/datum/status_effect/stabilized/darkpurple/on_remove()
|
||||
REMOVE_TRAIT(owner, TRAIT_RESISTHEATHANDS, "slimestatus")
|
||||
qdel(fire)
|
||||
return ..()
|
||||
|
||||
/datum/status_effect/stabilized/darkblue
|
||||
id = "stabilizeddarkblue"
|
||||
@@ -638,6 +656,7 @@ datum/status_effect/stabilized/blue/on_remove()
|
||||
if(ishuman(owner))
|
||||
var/mob/living/carbon/human/H = owner
|
||||
H.physiology.hunger_mod /= 0.8
|
||||
return ..()
|
||||
|
||||
//Bluespace has an icon because it's kinda active.
|
||||
/obj/screen/alert/status_effect/bluespaceslime
|
||||
@@ -697,6 +716,7 @@ datum/status_effect/stabilized/blue/on_remove()
|
||||
|
||||
/datum/status_effect/stabilized/sepia/on_remove()
|
||||
owner.remove_movespeed_modifier(MOVESPEED_ID_SEPIA)
|
||||
return ..()
|
||||
|
||||
/datum/status_effect/stabilized/cerulean
|
||||
id = "stabilizedcerulean"
|
||||
@@ -733,6 +753,7 @@ datum/status_effect/stabilized/blue/on_remove()
|
||||
clone.visible_message("<span class='warning'>[clone] dissolves into a puddle of goo!</span>")
|
||||
clone.unequip_everything()
|
||||
qdel(clone)
|
||||
return ..()
|
||||
|
||||
/datum/status_effect/stabilized/pyrite
|
||||
id = "stabilizedpyrite"
|
||||
@@ -749,6 +770,7 @@ datum/status_effect/stabilized/blue/on_remove()
|
||||
|
||||
/datum/status_effect/stabilized/pyrite/on_remove()
|
||||
owner.color = originalcolor
|
||||
return ..()
|
||||
|
||||
/datum/status_effect/stabilized/red
|
||||
id = "stabilizedred"
|
||||
@@ -760,6 +782,7 @@ datum/status_effect/stabilized/blue/on_remove()
|
||||
|
||||
/datum/status_effect/stabilized/red/on_remove()
|
||||
owner.unignore_slowdown("slimestatus")
|
||||
return ..()
|
||||
|
||||
/datum/status_effect/stabilized/green
|
||||
id = "stabilizedgreen"
|
||||
@@ -791,6 +814,7 @@ datum/status_effect/stabilized/blue/on_remove()
|
||||
originalDNA.transfer_identity(H)
|
||||
H.real_name = originalname
|
||||
H.updateappearance(mutcolor_update=1)
|
||||
return ..()
|
||||
|
||||
/datum/status_effect/brokenpeace
|
||||
id = "brokenpeace"
|
||||
@@ -854,6 +878,7 @@ datum/status_effect/stabilized/blue/on_remove()
|
||||
for(var/i in owner.faction)
|
||||
if(i == faction_name)
|
||||
owner.faction -= faction_name
|
||||
return ..()
|
||||
|
||||
/datum/status_effect/stabilized/oil
|
||||
id = "stabilizedoil"
|
||||
@@ -947,6 +972,7 @@ datum/status_effect/stabilized/blue/on_remove()
|
||||
/datum/status_effect/stabilized/gold/on_remove()
|
||||
if(familiar)
|
||||
qdel(familiar)
|
||||
return ..()
|
||||
|
||||
/datum/status_effect/stabilized/adamantine/on_apply()
|
||||
if(ishuman(owner))
|
||||
@@ -958,6 +984,7 @@ datum/status_effect/stabilized/blue/on_remove()
|
||||
if(ishuman(owner))
|
||||
var/mob/living/carbon/human/H = owner
|
||||
H.physiology.damage_resistance -= 5
|
||||
return ..()
|
||||
|
||||
/datum/status_effect/stabilized/rainbow
|
||||
id = "stabilizedrainbow"
|
||||
|
||||
@@ -76,6 +76,15 @@
|
||||
cost = 2
|
||||
illegal_tech = FALSE
|
||||
|
||||
/datum/uplink_item/badass/tactical_naptime
|
||||
name = "Sleepy Time Pajama Bundle"
|
||||
desc = "Even soldiers need to get a good nights rest. Comes with some cozy as heck sleeping wear, a blankie to keep yourself warm in deep space, a hot mug of cocoa for you and your fuzzy friend."
|
||||
item = /obj/item/storage/box/syndie_kit/sleepytime
|
||||
cost = 4
|
||||
limited_stock = 1
|
||||
cant_discount = TRUE
|
||||
include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops)
|
||||
|
||||
/datum/uplink_item/badass/shades
|
||||
name = "Big Sunglasses"
|
||||
desc = "Prevents flashes and looks badbass with some Smokes."
|
||||
|
||||
@@ -9,18 +9,28 @@
|
||||
|
||||
/datum/uplink_item/suits/turtlenck
|
||||
name = "Tactical Turtleneck"
|
||||
desc = "A slightly armored suit that has no sensor on them, if someone sees you in this hope they think its a fake."
|
||||
desc = "A slightly armored conspicious jumpsuit that has no suit sensors attached to them, if someone sees you in this hope they think its a fake."
|
||||
item = /obj/item/clothing/under/syndicate
|
||||
cost = 1
|
||||
exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) //They already get these
|
||||
|
||||
/datum/uplink_item/suits/turtlenck_skirt
|
||||
name = "Tactical Skirtleneck"
|
||||
desc = "A slightly armored suit that has no sensor on them, if someone sees you in this hope they think its a fake."
|
||||
desc = "A slightly armored conspicious jumpsuit that has no suit sensors attached to them, if someone sees you in this hope they think its a fake."
|
||||
item = /obj/item/clothing/under/syndicate/skirt
|
||||
cost = 1
|
||||
exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) //They already get these
|
||||
|
||||
/datum/uplink_item/suits/infiltrator_bundle
|
||||
name = "Insidious Infiltration Gear Case"
|
||||
desc = "Developed by Roseus Galactic in conjunction with the Gorlex Marauders to produce a functional suit for urban operations, \
|
||||
this suit proves to be cheaper than your standard issue hardsuit, with none of the movement restrictions (or the space proofing) of the outdated spacesuits employed by the company. \
|
||||
Comes with an armored vest, helmet, blood-red sneaksuit, sneakboots, specialized combat gloves and a high-tech balaclava which obfuscates both your voice and your face. The case is also rather useful as a storage container and bludgeoning implement."
|
||||
item = /obj/item/storage/toolbox/infiltrator
|
||||
cost = 3
|
||||
limited_stock = 1 //you only get one so you don't end up with too many gun cases
|
||||
exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops)
|
||||
|
||||
/datum/uplink_item/suits/padding
|
||||
name = "Soft Padding"
|
||||
desc = "An inconspicious soft padding meant to be worn underneath jumpsuits, will cushion the user from melee harm."
|
||||
|
||||
@@ -139,7 +139,7 @@
|
||||
name = "Headset Upgrader"
|
||||
desc = "A device that can be used to make one headset immune to flashbangs."
|
||||
item = /obj/item/headsetupgrader
|
||||
cost = 3
|
||||
cost = 1
|
||||
|
||||
/datum/uplink_item/device_tools/medgun
|
||||
name = "Medbeam Gun"
|
||||
|
||||
@@ -27,9 +27,9 @@
|
||||
|
||||
/obj/vehicle/ridden/secway/relaymove(mob/user, direction)
|
||||
var/new_speed = normalspeed
|
||||
if(ishuman(user))
|
||||
var/mob/living/carbon/human/H = user
|
||||
if(H.sprinting && charge)
|
||||
if(isliving(user))
|
||||
var/mob/living/L = user
|
||||
if((L.combat_flags & COMBAT_FLAG_SPRINT_TOGGLED) && charge)
|
||||
charge--
|
||||
new_speed = chargespeed
|
||||
var/datum/component/riding/D = GetComponent(/datum/component/riding)
|
||||
|
||||
Reference in New Issue
Block a user