Merge remote-tracking branch 'citadel/master' into minimaps

This commit is contained in:
kevinz000
2020-03-11 17:32:15 -07:00
789 changed files with 217724 additions and 211404 deletions
+20
View File
@@ -34,6 +34,21 @@
#define HIJACK_HIJACKER 1 //Needs to be present for shuttle to be hijacked
#define HIJACK_PREVENT 2 //Prevents hijacking same way as non-antags
//Syndicate Contracts
#define CONTRACT_STATUS_INACTIVE 1
#define CONTRACT_STATUS_ACTIVE 2
#define CONTRACT_STATUS_BOUNTY_CONSOLE_ACTIVE 3
#define CONTRACT_STATUS_EXTRACTING 4
#define CONTRACT_STATUS_COMPLETE 5
#define CONTRACT_STATUS_ABORTED 6
#define CONTRACT_PAYOUT_LARGE 1
#define CONTRACT_PAYOUT_MEDIUM 2
#define CONTRACT_PAYOUT_SMALL 3
#define CONTRACT_UPLINK_PAGE_CONTRACTS "CONTRACTS"
#define CONTRACT_UPLINK_PAGE_HUB "HUB"
//Overthrow time to update heads obj
#define OBJECTIVE_UPDATING_TIME 300
@@ -57,3 +72,8 @@
#define CAT_STRUCTURE "Structures"
#define MARTIALART_HUNTER "hunter-fu"
//Blob
/// blob gets a free reroll every X time
#define BLOB_REROLL_TIME 2400
#define BLOB_REFLECTOR_COST 15
+3 -3
View File
@@ -39,9 +39,9 @@
#define COCK_SIZE_MIN 1
#define COCK_SIZE_MAX 20
#define COCK_GIRTH_RATIO_MAX 1.25
#define COCK_GIRTH_RATIO_DEF 0.75
#define COCK_GIRTH_RATIO_MIN 0.5
#define COCK_DIAMETER_RATIO_MAX 0.42
#define COCK_DIAMETER_RATIO_DEF 0.25
#define COCK_DIAMETER_RATIO_MIN 0.15
#define KNOT_GIRTH_RATIO_MAX 3
#define KNOT_GIRTH_RATIO_DEF 2.1
+20 -1
View File
@@ -47,6 +47,10 @@
#define COMSIG_PARENT_PREQDELETED "parent_preqdeleted" //before a datum's Destroy() is called: (force), returning a nonzero value will cancel the qdel operation
#define COMSIG_PARENT_QDELETING "parent_qdeleting" //just before a datum's Destroy() is called: (force), at this point none of the other components chose to interrupt qdel and Destroy will be called
/// Trait signals
#define COMPONENT_ADD_TRAIT (1<<0)
#define COMPONENT_REMOVE_TRAIT (1<<1)
// /atom signals
#define COMSIG_PARENT_ATTACKBY "atom_attackby" //from base of atom/attackby(): (/obj/item, /mob/living, params)
#define COMPONENT_NO_AFTERATTACK 1 //Return this in response if you don't want afterattack to be called
@@ -202,14 +206,25 @@
#define COMSIG_LIVING_RESIST "living_resist" //from base of mob/living/resist() (/mob/living)
#define COMSIG_LIVING_IGNITED "living_ignite" //from base of mob/living/IgniteMob() (/mob/living)
#define COMSIG_LIVING_EXTINGUISHED "living_extinguished" //from base of mob/living/ExtinguishMob() (/mob/living)
#define COMSIG_LIVING_ELECTROCUTE_ACT "living_electrocute_act" //from base of mob/living/electrocute_act(): (shock_damage)
#define COMSIG_LIVING_ELECTROCUTE_ACT "living_electrocute_act" //from base of mob/living/electrocute_act(): (shock_damage, source, siemens_coeff, flags)
#define COMSIG_LIVING_MINOR_SHOCK "living_minor_shock" //sent by stuff like stunbatons and tasers: ()
#define COMSIG_LIVING_REVIVE "living_revive" //from base of mob/living/revive() (full_heal, admin_revive)
#define COMSIG_MOB_CLIENT_LOGIN "comsig_mob_client_login" //sent when a mob/login() finishes: (client)
#define COMSIG_LIVING_GUN_PROCESS_FIRE "living_gun_process_fire" //from base of /obj/item/gun/proc/process_fire(): (atom/target, params, zone_override)
//ALL OF THESE DO NOT TAKE INTO ACCOUNT WHETHER AMOUNT IS 0 OR LOWER AND ARE SENT REGARDLESS!
#define COMSIG_LIVING_STATUS_STUN "living_stun" //from base of mob/living/Stun() (amount, update, ignore)
#define COMSIG_LIVING_STATUS_KNOCKDOWN "living_knockdown" //from base of mob/living/Knockdown() (amount, update, ignore)
#define COMSIG_LIVING_STATUS_PARALYZE "living_paralyze" //from base of mob/living/Paralyze() (amount, update, ignore)
#define COMSIG_LIVING_STATUS_IMMOBILIZE "living_immobilize" //from base of mob/living/Immobilize() (amount, update, ignore)
#define COMSIG_LIVING_STATUS_UNCONSCIOUS "living_unconscious" //from base of mob/living/Unconscious() (amount, update, ignore)
#define COMSIG_LIVING_STATUS_SLEEP "living_sleeping" //from base of mob/living/Sleeping() (amount, update, ignore)
#define COMSIG_LIVING_STATUS_DAZE "living_daze" //from base of mob/living/Daze() (amount, update, ignore)
#define COMPONENT_NO_STUN 1 //For all of them
// /mob/living/carbon signals
#define COMSIG_CARBON_SOUNDBANG "carbon_soundbang" //from base of mob/living/carbon/soundbang_act(): (list(intensity))
#define COMSIG_CARBON_IDENTITY_TRANSFERRED_TO "carbon_id_transferred_to" //from datum/dna/transfer_identity(): (datum/dna, transfer_SE)
// /mob/living/simple_animal/hostile signals
#define COMSIG_HOSTILE_ATTACKINGTARGET "hostile_attackingtarget"
@@ -233,6 +248,7 @@
#define COMSIG_ITEM_PRE_ATTACK "item_pre_attack" //from base of obj/item/pre_attack(): (atom/target, mob/user, params)
#define COMPONENT_NO_ATTACK 1
#define COMSIG_ITEM_AFTERATTACK "item_afterattack" //from base of obj/item/afterattack(): (atom/target, mob/user, params)
#define COMSIG_ITEM_ALT_AFTERATTACK "item_alt_afterattack" //from base of obj/item/altafterattack(): (atom/target, mob/user, proximity, params)
#define COMSIG_ITEM_EQUIPPED "item_equip" //from base of obj/item/equipped(): (/mob/equipper, slot)
#define COMSIG_ITEM_DROPPED "item_drop" //from base of obj/item/dropped(): (mob/user)
#define COMSIG_ITEM_PICKUP "item_pickup" //from base of obj/item/pickup(): (/mob/taker)
@@ -274,6 +290,9 @@
#define COMSIG_HUMAN_MELEE_UNARMED_ATTACK "human_melee_unarmed_attack" //from mob/living/carbon/human/UnarmedAttack(): (atom/target)
#define COMSIG_HUMAN_MELEE_UNARMED_ATTACKBY "human_melee_unarmed_attackby" //from mob/living/carbon/human/UnarmedAttack(): (mob/living/carbon/human/attacker)
#define COMSIG_HUMAN_DISARM_HIT "human_disarm_hit" //Hit by successful disarm attack (mob/living/carbon/human/attacker,zone_targeted)
#define COMSIG_HUMAN_PREFS_COPIED_TO "human_prefs_copied_to" //from datum/preferences/copy_to(): (datum/preferences, icon_updates, roundstart_checks)
#define COMSIG_HUMAN_HARDSET_DNA "human_hardset_dna" //from mob/living/carbon/human/hardset_dna(): (ui, se, newreal_name, newblood_type, datum/species, newfeatures)
#define COMSIG_HUMAN_ON_RANDOMIZE "humman_on_randomize" //from base of proc/randomize_human()
// /datum/species signals
#define COMSIG_SPECIES_GAIN "species_gain" //from datum/species/on_species_gain(): (datum/species/new_species, datum/species/old_species)
+27
View File
@@ -92,3 +92,30 @@ GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 204
// radiation
#define RAD_PROTECT_CONTENTS (1<<0)
#define RAD_NO_CONTAMINATE (1<<1)
//Mob mobility var flags
/// any flag
#define CHECK_MOBILITY(target, flags) CHECK_BITFIELD(target.mobility_flags, flags)
#define CHECK_ALL_MOBILITY(target, flags) CHECK_MULTIPLE_BITFIELDS(target.mobility_flags, flags)
/// can move
#define MOBILITY_MOVE (1<<0)
/// can, and is, standing up.
#define MOBILITY_STAND (1<<1)
/// can pickup items
#define MOBILITY_PICKUP (1<<2)
/// can use items and interact with world objects like opening closets/etc
#define MOBILITY_USE (1<<3)
/// can use interfaces like consoles
#define MOBILITY_UI (1<<4)
/// can use storage item
#define MOBILITY_STORAGE (1<<5)
/// can pull things
#define MOBILITY_PULL (1<<6)
/// can hold non-nodropped items voluntarily
#define MOBILITY_HOLD (1<<7)
/// Can resist out of buckling, grabs, cuffs, etc, in the usual order (buckle --> cuffs --> grab)
#define MOBILITY_RESIST (1<<8)
#define MOBILITY_FLAGS_DEFAULT (MOBILITY_MOVE | MOBILITY_STAND | MOBILITY_PICKUP | MOBILITY_USE | MOBILITY_UI | MOBILITY_STORAGE | MOBILITY_PULL | MOBILITY_RESIST)
#define MOBILITY_FLAGS_ANY_INTERACTION (MOBILITY_USE | MOBILITY_PICKUP | MOBILITY_UI | MOBILITY_STORAGE)
+1 -4
View File
@@ -4,11 +4,8 @@
/// Hard materials, such as iron or metal
#define MAT_CATEGORY_RIGID "rigid material"
/// Gets the reference for the material type that was given
#define getmaterialref(A) (SSmaterials.materials[A] || A)
/// Flag for atoms, this flag ensures it isn't re-colored by materials. Useful for snowflake icons such as default toolboxes.
#define MATERIAL_COLOR (1<<0)
#define MATERIAL_ADD_PREFIX (1<<1)
#define MATERIAL_NO_EFFECTS (1<<2)
#define MATERIAL_AFFECT_STATISTICS (1<<3)
+1
View File
@@ -407,6 +407,7 @@ GLOBAL_LIST_INIT(pda_reskins, list(PDA_SKIN_CLASSIC = 'icons/obj/pda.dmi', PDA_S
#define DUMMY_HUMAN_SLOT_ADMIN "admintools"
#define DUMMY_HUMAN_SLOT_MANIFEST "dummy_manifest_generation"
#define DUMMY_HUMAN_SLOT_HALLUCINATION "dummy_hallucination"
#define DUMMY_HUMAN_SLOT_EXAMINER "dummy_examiner"
#define PR_ANNOUNCEMENTS_PER_ROUND 5 //The number of unique PR announcements allowed per round
//This makes sure that a single person can only spam 3 reopens and 3 closes before being ignored
+13
View File
@@ -58,8 +58,10 @@
#define BODYPART_DISABLED_DAMAGE 1
#define BODYPART_DISABLED_PARALYSIS 2
#define DEFAULT_BODYPART_ICON 'icons/mob/human_parts.dmi'
#define DEFAULT_BODYPART_ICON_ORGANIC 'icons/mob/human_parts_greyscale.dmi'
#define DEFAULT_BODYPART_ICON_ROBOTIC 'icons/mob/augmentation/augments.dmi'
#define DEFAULT_BODYPART_ICON_CITADEL 'modular_citadel/icons/mob/mutant_bodyparts.dmi'
#define MONKEY_BODYPART "monkey"
#define ALIEN_BODYPART "alien"
@@ -208,6 +210,17 @@
#define MAX_CHICKENS 50
///Flags used by the flags parameter of electrocute act.
///Makes it so that the shock doesn't take gloves into account.
#define SHOCK_NOGLOVES (1 << 0)
///Used when the shock is from a tesla bolt.
#define SHOCK_TESLA (1 << 1)
///Used when an illusion shocks something. Makes the shock deal stamina damage and not trigger certain secondary effects.
#define SHOCK_ILLUSION (1 << 2)
///The shock doesn't stun.
#define SHOCK_NOSTUN (1 << 3)
#define INCORPOREAL_MOVE_BASIC 1
#define INCORPOREAL_MOVE_SHADOW 2 // leaves a trail of shadows
+13 -5
View File
@@ -17,6 +17,9 @@
//ids
#define MOVESPEED_ID_MOB_WALK_RUN_CONFIG_SPEED "MOB_WALK_RUN"
#define MOVESPEED_ID_MOB_GRAB_STATE "MOB_GRAB_STATE"
#define MOVESPEED_ID_MOB_EQUIPMENT "MOB_EQUIPMENT"
#define MOVESPEED_ID_MOB_GRAVITY "MOB_GRAVITY"
#define MOVESPEED_ID_CONFIG_SPEEDMOD "MOB_CONFIG_MODIFIER"
#define MOVESPEED_ID_SLIME_REAGENTMOD "SLIME_REAGENT_MODIFIER"
@@ -28,6 +31,7 @@
#define MOVESPEED_ID_TARANTULA_WEB "TARANTULA_WEB"
#define MOVESPEED_ID_LIVING_TURF_SPEEDMOD "LIVING_TURF_SPEEDMOD"
#define MOVESPEED_ID_LIVING_LIMBLESS "LIVING_LIMBLESS"
#define MOVESPEED_ID_CARBON_SOFTCRIT "CARBON_SOFTCRIT"
#define MOVESPEED_ID_CARBON_OLDSPEED "CARBON_DEPRECATED_SPEED"
@@ -59,15 +63,19 @@
#define MOVESPEED_ID_HUMAN_CARRYING "HUMAN_CARRY"
#define MOVESPEED_ID_SHRINK_RAY "SHRUNKEN_SPEED_MODIFIER"
#define MOVESPEED_ID_TASED_STATUS "TASED"
#define MOVESPEED_ID_SLAUGHTER "SLAUGHTER"
#define MOVESPEED_ID_CYBER_THRUSTER "CYBER_IMPLANT_THRUSTER"
#define MOVESPEED_ID_JETPACK "JETPACK"
#define MOVESPEED_ID_SHOVE "SHOVE"
#define MOVESPEED_ID_MKULTRA "MKULTRA"
#define MOVESPEED_ID_ELECTROSTAFF "ELECTROSTAFF"
#define MOVESPEED_ID_TASED_STATUS "TASED"
#define MOVESPEED_ID_ELECTROSTAFF "ELECTROSTAFF"
#define MOVESPEED_ID_SHOVE "SHOVE"
#define MOVESPEED_ID_FAT "FAT"
#define MOVESPEED_ID_COLD "COLD"
#define MOVESPEED_ID_HUNGRY "HUNGRY"
#define MOVESPEED_ID_DAMAGE_SLOWDOWN "DAMAGE"
#define MOVESPEED_ID_DAMAGE_SLOWDOWN_FLYING "FLYING"
+4
View File
@@ -23,6 +23,10 @@ Ask ninjanomnom if they're around
#define RAD_MOB_MUTATE 1250 // How much stored radiation to check for mutation
#define RAD_MONKEY_GORILLIZE 1650 // How much stored radiation to check for Harambe time.
#define RAD_MOB_GORILLIZE_FACTOR 100
#define RAD_MONKEY_GORILLIZE_EXPONENT 0.5
#define RAD_MOB_VOMIT 2000 // The amount of radiation to check for vomitting
#define RAD_MOB_VOMIT_PROB 1 // Chance per tick of vomitting
+9 -2
View File
@@ -37,10 +37,17 @@
/////////////
// DEBUFFS //
/////////////
/// The affected is unable to move, or to use, hold, or pickup items.
#define STATUS_EFFECT_STUN /datum/status_effect/incapacitating/stun
#define STATUS_EFFECT_STUN /datum/status_effect/incapacitating/stun //the affected is stunned
#define STATUS_EFFECT_KNOCKDOWN /datum/status_effect/incapacitating/knockdown //the affected is unable to stand up
#define STATUS_EFFECT_KNOCKDOWN /datum/status_effect/incapacitating/knockdown //the affected is knocked down
#define STATUS_EFFECT_IMMOBILIZED /datum/status_effect/incapacitating/immobilized //the affected is unable to move
#define STATUS_EFFECT_PARALYZED /datum/status_effect/incapacitating/paralyzed //the affected is unable to move, use items, or stand up.
/// The affected is unable to use or pickup items
#define STATUS_EFFECT_DAZED /datum/status_effect/incapacitating/dazed
#define STATUS_EFFECT_UNCONSCIOUS /datum/status_effect/incapacitating/unconscious //the affected is unconscious
-1
View File
@@ -56,7 +56,6 @@
#define INIT_ORDER_SERVER_MAINT 93
#define INIT_ORDER_INPUT 85
#define INIT_ORDER_VIS 80
#define INIT_ORDER_MATERIALS 76
#define INIT_ORDER_RESEARCH 75
#define INIT_ORDER_EVENTS 70
#define INIT_ORDER_JOBS 65
+22 -2
View File
@@ -1,3 +1,5 @@
#define SIGNAL_TRAIT(trait_ref) "trait [trait_ref]"
// trait accessor defines
#define ADD_TRAIT(target, trait, source) \
do { \
@@ -6,12 +8,14 @@
target.status_traits = list(); \
_L = target.status_traits; \
_L[trait] = list(source); \
SEND_SIGNAL(target, SIGNAL_TRAIT(trait), COMPONENT_ADD_TRAIT); \
} else { \
_L = target.status_traits; \
if (_L[trait]) { \
_L[trait] |= list(source); \
} else { \
_L[trait] = list(source); \
SEND_SIGNAL(target, SIGNAL_TRAIT(trait), COMPONENT_ADD_TRAIT); \
} \
} \
} while (0)
@@ -31,7 +35,8 @@
} \
};\
if (!length(_L[trait])) { \
_L -= trait \
_L -= trait; \
SEND_SIGNAL(target, SIGNAL_TRAIT(trait), COMPONENT_REMOVE_TRAIT); \
}; \
if (!length(_L)) { \
target.status_traits = null \
@@ -46,7 +51,8 @@
for (var/_T in _L) { \
_L[_T] &= _S;\
if (!length(_L[_T])) { \
_L -= _T } \
_L -= _T ; \
SEND_SIGNAL(target, SIGNAL_TRAIT(_T), COMPONENT_REMOVE_TRAIT); } \
};\
if (!length(_L)) { \
target.status_traits = null\
@@ -77,6 +83,7 @@
#define TRAIT_DISFIGURED "disfigured"
#define TRAIT_XENO_HOST "xeno_host" //Tracks whether we're gonna be a baby alien's mummy.
#define TRAIT_STUNIMMUNE "stun_immunity"
#define TRAIT_TASED_RESISTANCE "tased_resistance" //prevents you from suffering most of the effects of being tased
#define TRAIT_SLEEPIMMUNE "sleep_immunity"
#define TRAIT_PUSHIMMUNE "push_immunity"
#define TRAIT_SHOCKIMMUNE "shock_immunity"
@@ -137,6 +144,19 @@
#define TRAIT_NOMARROW "nomarrow" // You don't make blood, with chemicals or nanites.
#define TRAIT_NOPULSE "nopulse" // Your heart doesn't beat.
#define TRAIT_EXEMPT_HEALTH_EVENTS "exempt-health-events"
// mobility flag traits
// IN THE FUTURE, IT WOULD BE NICE TO DO SOMETHING SIMILAR TO https://github.com/tgstation/tgstation/pull/48923/files (ofcourse not nearly the same because I have my.. thoughts on it)
// BUT FOR NOW, THESE ARE HOOKED TO DO update_mobility() VIA COMSIG IN living_mobility.dm
// SO IF YOU ADD MORE, BESURE TO UPDATE IT THERE.
/// Disallow movement
#define TRAIT_MOBILITY_NOMOVE "mobility_nomove"
/// Disallow pickup
#define TRAIT_MOBILITY_NOPICKUP "mobility_nopickup"
/// Disallow item use
#define TRAIT_MOBILITY_NOUSE "mobility_nouse"
#define TRAIT_SWIMMING "swimming" //only applied by /datum/element/swimming, for checking
//non-mob traits
-32
View File
@@ -107,38 +107,6 @@ GLOBAL_VAR_INIT(miscreants_allowed, FALSE)
if(!src.holder) return
message_admins("[key_name_admin(usr)] manually reloaded mentors")
//Flavor Text
/mob/proc/set_flavor()
set name = "Set Flavor Text"
set desc = "Sets an extended description of your character's features."
set category = "IC"
var/new_flavor = stripped_multiline_input(usr, "Set the flavor text in your 'examine' verb. This can also be used for OOC notes and preferences!", "Flavor Text", flavor_text, MAX_FAVOR_LEN, TRUE)
if(!isnull(new_flavor))
flavor_text = html_decode(new_flavor)
to_chat(src, "Your flavor text has been updated.")
//Flavor Text
/mob/proc/set_flavor_2()
set name = "Set Temporary Flavor Text"
set desc = "Sets a description of your character's current appearance. Use this for emotions, poses etc."
set category = "IC"
var/new_flavor = stripped_multiline_input(usr, "Set the temporary flavor text in your 'examine' verb. This should be used only for things pertaining to the current round!", "Short-Term Flavor Text", flavor_text_2, MAX_FAVOR_LEN, TRUE)
if(!isnull(new_flavor))
flavor_text_2 = html_decode(new_flavor)
to_chat(src, "Your temporary flavor text has been updated.")
/mob/proc/print_flavor_text(flavor,temp = FALSE)
if(!flavor)
return
// We are decoding and then encoding to not only get correct amount of characters, but also to prevent partial escaping characters being shown.
var/msg = html_decode(replacetext(flavor, "\n", " "))
if(length_char(msg) <= 40)
return "<span class='notice'>[html_encode(msg)]</span>"
else
return "<span class='notice'>[html_encode(copytext_char(msg, 1, 37))]... <a href='?src=[REF(src)];flavor[temp ? "2" : ""]_more=1'>More...</span></a>"
//LOOC toggles
/client/verb/listen_looc()
set name = "Show/Hide LOOC"
+10 -1
View File
@@ -174,6 +174,15 @@
L[T] = TRUE
return L
/proc/typecacheof_assoc_list(list/pathlist, ignore_root_path = FALSE)
. = list()
if(!istype(pathlist))
return
for(var/P in pathlist)
var/value = pathlist[P]
for(var/T in (ignore_root_path ? subtypesof(P) : typesof(P)))
.[T] = value
//Empties the list by setting the length to 0. Hopefully the elements get garbage collected
/proc/clearlist(list/list)
if(istype(list))
@@ -579,4 +588,4 @@
var/list/ret = list()
for(var/key in input)
ret += key
return ret
return ret
+5
View File
@@ -1,5 +1,10 @@
#define BP_MAX_ROOM_SIZE 300
GLOBAL_LIST_INIT(typecache_powerfailure_safe_areas, typecacheof(/area/engine/engineering, \
/area/engine/supermatter, \
/area/engine/atmospherics_engine, \
/area/ai_monitored/turret_protected/ai))
//Repopulates sortedAreas list
/proc/repopulate_sorted_areas()
GLOB.sortedAreas = list()
+33
View File
@@ -549,3 +549,36 @@
var/pressure = environment.return_pressure()
if(pressure <= LAVALAND_EQUIPMENT_EFFECT_PRESSURE)
. = TRUE
/proc/ispipewire(item)
var/static/list/pipe_wire = list(
/obj/machinery/atmospherics,
/obj/structure/disposalpipe,
/obj/structure/cable
)
return (is_type_in_list(item, pipe_wire))
// Find a obstruction free turf that's within the range of the center. Can also condition on if it is of a certain area type.
/proc/find_obstruction_free_location(var/range, var/atom/center, var/area/specific_area)
var/list/turfs = RANGE_TURFS(range, center)
var/list/possible_loc = list()
for(var/turf/found_turf in turfs)
var/area/turf_area = get_area(found_turf)
if(specific_area) // We check if both the turf is a floor, and that it's actually in the area. // We also want a location that's clear of any obstructions.
if(!istype(turf_area, specific_area))
continue
if(!isspaceturf(found_turf))
if(!is_blocked_turf(found_turf))
possible_loc.Add(found_turf)
if(possible_loc.len < 1) // Need at least one free location.
return FALSE
return pick(possible_loc)
/proc/power_fail(duration_min, duration_max)
for(var/P in GLOB.apcs_list)
var/obj/machinery/power/apc/C = P
if(C.cell && SSmapping.level_trait(C.z, ZTRAIT_STATION))
var/area/A = C.area
if(GLOB.typecache_powerfailure_safe_areas[A.type])
continue
C.energy_fail(rand(duration_min,duration_max))
+30 -14
View File
@@ -47,7 +47,7 @@
init_sprite_accessory_subtypes(/datum/sprite_accessory/underwear/socks, GLOB.socks_list)
return pick(GLOB.socks_list)
/proc/random_features()
/proc/random_features(intendedspecies)
if(!GLOB.tails_list_human.len)
init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/human, GLOB.tails_list_human)
if(!GLOB.tails_list_lizard.len)
@@ -105,6 +105,8 @@
var/datum/sprite_accessory/mam_tails/instance = GLOB.mam_tails_list[mtpath]
if(istype(instance, /datum/sprite_accessory))
var/datum/sprite_accessory/S = instance
if(intendedspecies && S.recommended_species && !S.recommended_species.Find(intendedspecies))
continue
if(!S.ckeys_allowed)
snowflake_mam_tails_list[S.name] = mtpath
var/list/snowflake_markings_list = list()
@@ -112,6 +114,8 @@
var/datum/sprite_accessory/mam_body_markings/instance = GLOB.mam_body_markings_list[mmpath]
if(istype(instance, /datum/sprite_accessory))
var/datum/sprite_accessory/S = instance
if(intendedspecies && S.recommended_species && !S.recommended_species.Find(intendedspecies))
continue
if(!S.ckeys_allowed)
snowflake_markings_list[S.name] = mmpath
var/list/snowflake_ears_list = list()
@@ -119,6 +123,8 @@
var/datum/sprite_accessory/mam_ears/instance = GLOB.mam_ears_list[mepath]
if(istype(instance, /datum/sprite_accessory))
var/datum/sprite_accessory/S = instance
if(intendedspecies && S.recommended_species && !S.recommended_species.Find(intendedspecies))
continue
if(!S.ckeys_allowed)
snowflake_ears_list[S.name] = mepath
var/list/snowflake_mam_snouts_list = list()
@@ -126,8 +132,19 @@
var/datum/sprite_accessory/mam_snouts/instance = GLOB.mam_snouts_list[mspath]
if(istype(instance, /datum/sprite_accessory))
var/datum/sprite_accessory/S = instance
if(intendedspecies && S.recommended_species && !S.recommended_species.Find(intendedspecies))
continue
if(!S.ckeys_allowed)
snowflake_mam_snouts_list[S.name] = mspath
var/list/snowflake_ipc_antenna_list = list()
for(var/mspath in GLOB.ipc_antennas_list)
var/datum/sprite_accessory/mam_snouts/instance = GLOB.ipc_antennas_list[mspath]
if(istype(instance, /datum/sprite_accessory))
var/datum/sprite_accessory/S = instance
if(intendedspecies && S.recommended_species && !S.recommended_species.Find(intendedspecies))
continue
if(!S.ckeys_allowed)
snowflake_ipc_antenna_list[S.name] = mspath
var/color1 = random_short_color()
var/color2 = random_short_color()
var/color3 = random_short_color()
@@ -153,10 +170,10 @@
"insect_fluff" = "None",
"insect_markings" = pick(GLOB.insect_markings_list),
"taur" = "None",
"mam_body_markings" = pick(snowflake_markings_list),
"mam_ears" = pick(snowflake_ears_list),
"mam_snouts" = pick(snowflake_mam_snouts_list),
"mam_tail" = pick(snowflake_mam_tails_list),
"mam_body_markings" = snowflake_markings_list.len ? pick(snowflake_markings_list) : "None",
"mam_ears" = snowflake_ears_list ? pick(snowflake_ears_list) : "None",
"mam_snouts" = snowflake_mam_snouts_list ? pick(snowflake_mam_snouts_list) : "None",
"mam_tail" = snowflake_mam_tails_list ? pick(snowflake_mam_tails_list) : "None",
"mam_tail_animated" = "None",
"xenodorsal" = "Standard",
"xenohead" = "Standard",
@@ -165,7 +182,7 @@
"has_cock" = FALSE,
"cock_shape" = pick(GLOB.cock_shapes_list),
"cock_length" = 6,
"cock_girth_ratio" = COCK_GIRTH_RATIO_DEF,
"cock_diameter_ratio" = COCK_DIAMETER_RATIO_DEF,
"cock_color" = pick("FFFFFF","7F7F7F", "7FFF7F", "7F7FFF", "FF7F7F", "7FFFFF", "FF7FFF", "FFFF7F"),
"has_sheath" = FALSE,
"sheath_color" = pick("FFFFFF","7F7F7F", "7FFF7F", "7F7FFF", "FF7F7F", "7FFFFF", "FF7FFF", "FFFF7F"),
@@ -204,7 +221,7 @@
"womb_cum_rate" = CUM_RATE,
"womb_cum_mult" = CUM_RATE_MULT,
"womb_efficiency" = CUM_EFFICIENCY,
"ipc_screen" = "Sunburst",
"ipc_screen" = snowflake_ipc_antenna_list ? pick(snowflake_ipc_antenna_list) : "None",
"ipc_antenna" = "None",
"flavor_text" = "",
"meat_type" = "Mammalian"
@@ -356,7 +373,7 @@ GLOBAL_LIST_EMPTY(species_list)
checked_health["health"] = health
return ..()
/proc/do_after(mob/user, var/delay, needhand = 1, atom/target = null, progress = 1, datum/callback/extra_checks = null)
/proc/do_after(mob/user, var/delay, needhand = 1, atom/target = null, progress = 1, datum/callback/extra_checks = null, required_mobility_flags = (MOBILITY_USE|MOBILITY_MOVE))
if(!user)
return 0
var/atom/Tloc = null
@@ -384,6 +401,7 @@ GLOBAL_LIST_EMPTY(species_list)
var/endtime = world.time + delay
var/starttime = world.time
. = 1
var/mob/living/L = isliving(user) && user //evals to last thing eval'd
while (world.time < endtime)
stoplag(1)
if (progress)
@@ -393,15 +411,13 @@ GLOBAL_LIST_EMPTY(species_list)
drifting = 0
Uloc = user.loc
if(QDELETED(user) || user.stat || user.IsKnockdown() || user.IsStun() || (!drifting && user.loc != Uloc) || (extra_checks && !extra_checks.Invoke()))
if(L && !CHECK_ALL_MOBILITY(L, required_mobility_flags))
. = 0
break
if(isliving(user))
var/mob/living/L = user
if(L.recoveringstam)
. = 0
break
if(QDELETED(user) || user.stat || (!drifting && user.loc != Uloc) || (extra_checks && !extra_checks.Invoke()))
. = 0
break
if(!QDELETED(Tloc) && (QDELETED(target) || Tloc != target.loc))
if((Uloc != Tloc || Tloc != user) && !drifting)
+1
View File
@@ -354,6 +354,7 @@
roundend_report.set_content(content)
roundend_report.stylesheets = list()
roundend_report.add_stylesheet("roundend", 'html/browser/roundend.css')
roundend_report.add_stylesheet("font-awesome", 'html/font-awesome/css/all.min.css')
roundend_report.open(0)
/datum/controller/subsystem/ticker/proc/personal_report(client/C, popcount)
+15 -1
View File
@@ -49,7 +49,7 @@
alert("Invalid name.")
return ""
return sanitize(t)
/proc/sanitize_filename(t)
return sanitize_simple(t, list("\n"="", "\t"="", "/"="", "\\"="", "?"="", "%"="", "*"="", ":"="", "|"="", "\""="", "<"="", ">"=""))
@@ -798,3 +798,17 @@ GLOBAL_LIST_INIT(binary, list("0","1"))
out += prob(replaceprob)? pick(replacementchars) : char
return out.Join("")
/proc/readable_corrupted_text(text)
var/list/corruption_options = list("..", "£%", "~~\"", "!!", "*", "^", "$!", "-", "}", "?")
var/corrupted_text = ""
for(var/letter_index = 1; letter_index <= length(text); letter_index++) // Have every letter have a chance of creating corruption on either side
var/letter = text[letter_index] // Small chance of letters being removed in place of corruption - still overall readable
if(prob(15))
corrupted_text += pick(corruption_options)
if(prob(95))
corrupted_text += letter
else
corrupted_text += pick(corruption_options)
if(prob(15))
corrupted_text += pick(corruption_options)
return corrupted_text
-111
View File
@@ -1,111 +0,0 @@
/*
// Contains VOREStation based vore description type2type functions
// list2text - takes delimiter and returns text
// text2list - takes delimiter, and creates list
//
*/
// Concatenates a list of strings into a single string. A seperator may optionally be provided.
/proc/list2text(list/ls, sep)
if (ls.len <= 1) // Early-out code for empty or singleton lists.
return ls.len ? ls[1] : ""
var/l = ls.len // Made local for sanic speed.
var/i = 0 // Incremented every time a list index is accessed.
if (sep <> null)
// Macros expand to long argument lists like so: sep, ls[++i], sep, ls[++i], sep, ls[++i], etc...
#define S1 sep, ls[++i]
#define S4 S1, S1, S1, S1
#define S16 S4, S4, S4, S4
#define S64 S16, S16, S16, S16
. = "[ls[++i]]" // Make sure the initial element is converted to text.
// Having the small concatenations come before the large ones boosted speed by an average of at least 5%.
if (l-1 & 0x01) // 'i' will always be 1 here.
. = text("[][][]", ., S1) // Append 1 element if the remaining elements are not a multiple of 2.
if (l-i & 0x02)
. = text("[][][][][]", ., S1, S1) // Append 2 elements if the remaining elements are not a multiple of 4.
if (l-i & 0x04)
. = text("[][][][][][][][][]", ., S4) // And so on....
if (l-i & 0x08)
. = text("[][][][][][][][][][][][][][][][][]", ., S4, S4)
if (l-i & 0x10)
. = text("[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]", ., S16)
if (l-i & 0x20)
. = text("[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]", ., S16, S16)
if (l-i & 0x40)
. = text("[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]", ., S64)
while (l > i) // Chomp through the rest of the list, 128 elements at a time.
. = text("[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]", ., S64, S64)
#undef S64
#undef S16
#undef S4
#undef S1
else
// Macros expand to long argument lists like so: ls[++i], ls[++i], ls[++i], etc...
#define S1 ls[++i]
#define S4 S1, S1, S1, S1
#define S16 S4, S4, S4, S4
#define S64 S16, S16, S16, S16
. = "[ls[++i]]" // Make sure the initial element is converted to text.
if (l-1 & 0x01) // 'i' will always be 1 here.
. += S1 // Append 1 element if the remaining elements are not a multiple of 2.
if (l-i & 0x02)
. = text("[][][]", ., S1, S1) // Append 2 elements if the remaining elements are not a multiple of 4.
if (l-i & 0x04)
. = text("[][][][][]", ., S4) // And so on...
if (l-i & 0x08)
. = text("[][][][][][][][][]", ., S4, S4)
if (l-i & 0x10)
. = text("[][][][][][][][][][][][][][][][][]", ., S16)
if (l-i & 0x20)
. = text("[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]", ., S16, S16)
if (l-i & 0x40)
. = text("[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]", ., S64)
while (l > i) // Chomp through the rest of the list, 128 elements at a time.
. = text("[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]", ., S64, S64)
#undef S64
#undef S16
#undef S4
#undef S1
// Converts a string into a list by splitting the string at each delimiter found. (discarding the seperator)
/proc/text2list(text, delimiter="\n")
var/delim_len = length(delimiter)
if (delim_len < 1)
return list(text)
. = list()
var/last_found = 1
var/found
do
found = findtext(text, delimiter, last_found, 0)
. += copytext(text, last_found, found)
last_found = found + delim_len
while (found)
// Returns true if val is from min to max, inclusive.
/proc/IsInRange(val, min, max)
return (val >= min) && (val <= max)
-39
View File
@@ -1,39 +0,0 @@
/datum/projectile_data
var/src_x
var/src_y
var/time
var/distance
var/power_x
var/power_y
var/dest_x
var/dest_y
/datum/projectile_data/New(var/src_x, var/src_y, var/time, var/distance, \
var/power_x, var/power_y, var/dest_x, var/dest_y)
src.src_x = src_x
src.src_y = src_y
src.time = time
src.distance = distance
src.power_x = power_x
src.power_y = power_y
src.dest_x = dest_x
src.dest_y = dest_y
/proc/projectile_trajectory(src_x, src_y, rotation, angle, power)
// returns the destination (Vx,y) that a projectile shot at [src_x], [src_y], with an angle of [angle],
// rotated at [rotation] and with the power of [power]
// Thanks to VistaPOWA for this function
var/power_x = power * cos(angle)
var/power_y = power * sin(angle)
var/time = 2* power_y / 10 //10 = g
var/distance = time * power_x
var/dest_x = src_x + distance*sin(rotation);
var/dest_y = src_y + distance*cos(rotation);
return new /datum/projectile_data(src_x, src_y, time, distance, power_x, power_y, dest_x, dest_y)
+12 -1
View File
@@ -214,7 +214,7 @@ GLOBAL_LIST_INIT(bitfields, list(
"CAN_MASTURBATE_WITH" = CAN_MASTURBATE_WITH,
"MASTURBATE_LINKED_ORGAN" = MASTURBATE_LINKED_ORGAN,
"CAN_CLIMAX_WITH" = CAN_CLIMAX_WITH
),
"mob_biotypes" = list (
"MOB_ORGANIC" = MOB_ORGANIC,
@@ -227,5 +227,16 @@ GLOBAL_LIST_INIT(bitfields, list(
"MOB_EPIC" = MOB_EPIC,
"MOB_REPTILE" = MOB_REPTILE,
"MOB_SPIRIT" = MOB_SPIRIT
),
"mobility_flags" = list(
"MOBILITY_MOVE" = MOBILITY_MOVE,
"MOBILITY_STAND" = MOBILITY_STAND,
"MOBILITY_PICKUP" = MOBILITY_PICKUP,
"MOBILITY_USE" = MOBILITY_USE,
"MOBILITY_UI" = MOBILITY_UI,
"MOBILITY_STORAGE" = MOBILITY_STORAGE,
"MOBILITY_PULL" = MOBILITY_PULL,
"MOBILITY_HOLD" = MOBILITY_HOLD,
"MOBILITY_RESIST" = MOBILITY_RESIST
)
))
-1
View File
@@ -29,7 +29,6 @@ GLOBAL_LIST_EMPTY(available_ai_shells)
GLOBAL_LIST_INIT(simple_animals, list(list(),list(),list(),list())) // One for each AI_* status define
GLOBAL_LIST_EMPTY(spidermobs) //all sentient spider mobs
GLOBAL_LIST_EMPTY(bots_list)
GLOBAL_LIST_EMPTY(living_cameras)
GLOBAL_LIST_EMPTY(aiEyes)
GLOBAL_LIST_EMPTY(language_datum_instances)
+3 -1
View File
@@ -18,6 +18,7 @@
#define POLL_IGNORE_DEMON "demon"
#define POLL_IGNORE_WIZARD "wizard"
#define POLL_IGNORE_CLONE "clone"
#define POLL_IGNORE_CONTRACTOR_SUPPORT "contractor_support"
GLOBAL_LIST_INIT(poll_ignore_desc, list(
POLL_IGNORE_SENTIENCE_POTION = "Sentience potion",
@@ -37,7 +38,8 @@ GLOBAL_LIST_INIT(poll_ignore_desc, list(
POLL_IGNORE_SPLITPERSONALITY = "Split Personality",
POLL_IGNORE_DEMON = "Demons",
POLL_IGNORE_WIZARD = "Wizards",
POLL_IGNORE_CLONE = "Defective/SDGF clones"
POLL_IGNORE_CLONE = "Defective/SDGF clones",
POLL_IGNORE_CONTRACTOR_SUPPORT = "Contractor Support Unit"
))
GLOBAL_LIST_INIT(poll_ignore, init_poll_ignore())
+2 -2
View File
@@ -14,7 +14,7 @@
if(check_click_intercept(params,A))
return
if(stat || lockcharge || IsKnockdown() || IsStun() || IsUnconscious())
if(stat || locked_down || IsParalyzed() || IsStun() || IsUnconscious())
return
var/list/modifiers = params2list(params)
@@ -66,7 +66,7 @@
if(C.user_unbuckle_mob(C.buckled_mobs[1],src))
return
if(!W && get_dist(src,A) <= interaction_range)
if(!W && (get_dist(src,A) <= interaction_range))
A.attack_robot(src)
return
+2 -2
View File
@@ -273,7 +273,7 @@ or shoot a gun to move around via Newton's 3rd Law of Motion."
if(!istype(L) || !L.can_resist())
return
L.changeNext_move(CLICK_CD_RESIST)
if(L.canmove)
if(CHECK_MOBILITY(L, MOBILITY_MOVE))
return L.resist_fire() //I just want to start a flame in your hearrrrrrtttttt.
@@ -601,7 +601,7 @@ so as to remain in compliance with the most up-to-date laws."
if(!istype(L) || !L.can_resist())
return
L.changeNext_move(CLICK_CD_RESIST)
if((L.canmove) && (L.last_special <= world.time))
if(CHECK_MOBILITY(L, MOBILITY_MOVE) && (L.last_special <= world.time))
return L.resist_restraints()
/obj/screen/alert/restrained/buckled/Click()
+11 -11
View File
@@ -48,7 +48,7 @@
if(isovermind(usr))
var/mob/camera/blob/B = usr
if(!B.placed)
B.place_blob_core(B.base_point_rate, 0)
B.place_blob_core(0)
B.transport_core()
/obj/screen/blob/Blobbernaut
@@ -91,26 +91,26 @@
var/mob/camera/blob/B = usr
B.create_factory()
/obj/screen/blob/ReadaptChemical
/obj/screen/blob/ReadaptStrain
icon_state = "ui_chemswap"
name = "Readapt Chemical (40)"
desc = "Randomly rerolls your chemical for 40 resources."
name = "Readapt Strain (40)"
desc = "Allows you to choose a new strain from 4 random choices for 40 resources."
/obj/screen/blob/ReadaptChemical/MouseEntered(location,control,params)
/obj/screen/blob/ReadaptStrain/MouseEntered(location,control,params)
if(hud && hud.mymob && isovermind(hud.mymob))
var/mob/camera/blob/B = hud.mymob
if(B.free_chem_rerolls)
name = "Readapt Chemical (FREE)"
desc = "Randomly rerolls your chemical for free."
if(B.free_strain_rerolls)
name = "Readapt Strain (FREE)"
desc = "Randomly rerolls your strain for free."
else
name = initial(name)
desc = initial(desc)
..()
/obj/screen/blob/ReadaptChemical/Click()
/obj/screen/blob/ReadaptStrain/Click()
if(isovermind(usr))
var/mob/camera/blob/B = usr
B.chemical_reroll()
B.strain_reroll()
/obj/screen/blob/RelocateCore
icon_state = "ui_swap"
@@ -175,7 +175,7 @@
using.hud = src
static_inventory += using
using = new /obj/screen/blob/ReadaptChemical()
using = new /obj/screen/blob/ReadaptStrain()
using.screen_loc = ui_storage1
using.hud = src
static_inventory += using
+1 -1
View File
@@ -113,7 +113,7 @@
var/mob/living/carbon/tempcarb = user
if(!tempcarb.combatmode)
totitemdamage *= 0.5
if(user.resting)
if(!CHECK_MOBILITY(user, MOBILITY_STAND))
totitemdamage *= 0.5
//CIT CHANGES END HERE
if(user != src && check_shields(I, totitemdamage, "the [I.name]", MELEE_ATTACK, I.armour_penetration))
@@ -335,6 +335,10 @@
config_entry_value = 16
min_val = 0
/datum/config_entry/number/station_space_budget
config_entry_value = 10
min_val = 0
/datum/config_entry/flag/allow_random_events // Enables random events mid-round when set
/datum/config_entry/number/events_min_time_mul // Multipliers for random events minimal starting time and minimal players amounts
+1 -1
View File
@@ -63,7 +63,7 @@
//Sleeping in here prevents future fires until returned.
/datum/controller/subsystem/proc/fire(resumed = 0)
flags |= SS_NO_FIRE
throw EXCEPTION("Subsystem [src]([type]) does not fire() but did not set the SS_NO_FIRE flag. Please add the SS_NO_FIRE flag to any subsystem that doesn't fire so it doesn't get added to the processing list and waste cpu.")
CRASH("Subsystem [src]([type]) does not fire() but did not set the SS_NO_FIRE flag. Please add the SS_NO_FIRE flag to any subsystem that doesn't fire so it doesn't get added to the processing list and waste cpu.")
/datum/controller/subsystem/Destroy()
dequeue()
+3 -3
View File
@@ -83,15 +83,15 @@ SUBSYSTEM_DEF(jukeboxes)
return
for(var/list/jukeinfo in activejukeboxes)
if(!jukeinfo.len)
EXCEPTION("Active jukebox without any associated metadata.")
stack_trace("Active jukebox without any associated metadata.")
continue
var/datum/track/juketrack = jukeinfo[1]
if(!istype(juketrack))
EXCEPTION("Invalid jukebox track datum.")
stack_trace("Invalid jukebox track datum.")
continue
var/obj/jukebox = jukeinfo[3]
if(!istype(jukebox))
EXCEPTION("Nonexistant or invalid object associated with jukebox.")
stack_trace("Nonexistant or invalid object associated with jukebox.")
continue
var/sound/song_played = sound(juketrack.song_path)
var/area/currentarea = get_area(jukebox)
+10
View File
@@ -14,6 +14,7 @@ SUBSYSTEM_DEF(mapping)
var/list/ruins_templates = list()
var/list/space_ruins_templates = list()
var/list/lava_ruins_templates = list()
var/list/station_ruins_templates = list()
var/datum/space_level/isolated_ruins_z //Created on demand during ruin loading.
var/list/shuttle_templates = list()
@@ -94,6 +95,11 @@ SUBSYSTEM_DEF(mapping)
var/list/space_ruins = levels_by_trait(ZTRAIT_SPACE_RUINS)
if (space_ruins.len)
seedRuins(space_ruins, CONFIG_GET(number/space_budget), /area/space, space_ruins_templates)
// Generate station space ruins
var/list/station_ruins = levels_by_trait(ZTRAIT_STATION)
if (station_ruins.len)
seedRuins(station_ruins, CONFIG_GET(number/station_space_budget), /area/space/station_ruins, station_ruins_templates)
SSmapping.seedStation()
loading_ruins = FALSE
#endif
@@ -161,6 +167,7 @@ SUBSYSTEM_DEF(mapping)
ruins_templates = SSmapping.ruins_templates
space_ruins_templates = SSmapping.space_ruins_templates
lava_ruins_templates = SSmapping.lava_ruins_templates
station_ruins_templates = SSmapping.station_ruins_templates
shuttle_templates = SSmapping.shuttle_templates
shelter_templates = SSmapping.shelter_templates
unused_turfs = SSmapping.unused_turfs
@@ -352,6 +359,7 @@ GLOBAL_LIST_EMPTY(the_station_areas)
// Still supporting bans by filename
var/list/banned = generateMapList("[global.config.directory]/lavaruinblacklist.txt")
banned += generateMapList("[global.config.directory]/spaceruinblacklist.txt")
banned += generateMapList("[global.config.directory]/stationruinblacklist.txt")
for(var/item in sortList(subtypesof(/datum/map_template/ruin), /proc/cmp_ruincost_priority))
var/datum/map_template/ruin/ruin_type = item
@@ -372,6 +380,8 @@ GLOBAL_LIST_EMPTY(the_station_areas)
space_ruins_templates[R.name] = R
else if(istype(R, /datum/map_template/ruin/station))
station_room_templates[R.name] = R
else if(istype(R, /datum/map_template/ruin/spacenearstation))
station_ruins_templates[R.name] = R
/datum/controller/subsystem/mapping/proc/preloadShuttleTemplates()
var/list/unbuyable = generateMapList("[global.config.directory]/unbuyableshuttles.txt")
+11 -9
View File
@@ -5,23 +5,25 @@ These materials call on_applied() on whatever item they are applied to, common e
SUBSYSTEM_DEF(materials)
name = "Materials"
flags = SS_NO_FIRE
init_order = INIT_ORDER_MATERIALS
flags = SS_NO_FIRE | SS_NO_INIT
///Dictionary of material.type || material ref
var/list/materials = list()
var/list/materials
///Dictionary of category || list of material refs
var/list/materials_by_category = list()
var/list/materials_by_category
///List of stackcrafting recipes for materials using rigid materials
var/list/rigid_stack_recipes = list(new/datum/stack_recipe("chair", /obj/structure/chair/greyscale, one_per_turf = TRUE, on_floor = TRUE, applies_mats = TRUE))
/datum/controller/subsystem/materials/Initialize(timeofday)
InitializeMaterials()
return ..()
///Ran on initialize, populated the materials and materials_by_category dictionaries with their appropiate vars (See these variables for more info)
/datum/controller/subsystem/materials/proc/InitializeMaterials(timeofday)
/datum/controller/subsystem/materials/proc/InitializeMaterials()
materials = list()
materials_by_category = list()
for(var/type in subtypesof(/datum/material))
var/datum/material/ref = new type
materials[type] = ref
for(var/c in ref.categories)
materials_by_category[c] += list(ref)
/datum/controller/subsystem/materials/proc/GetMaterialRef(datum/material/fakemat)
if(!materials)
InitializeMaterials()
return materials[fakemat] || fakemat
+4 -6
View File
@@ -26,18 +26,16 @@ SUBSYSTEM_DEF(mobs)
var/seconds = wait * 0.1
if (!resumed)
src.currentrun = GLOB.mob_living_list.Copy()
if (GLOB.living_cameras.len)
src.currentrun += GLOB.living_cameras
//cache for sanic speed (lists are references anyways)
var/list/currentrun = src.currentrun
var/times_fired = src.times_fired
while(currentrun.len)
var/mob/M = currentrun[currentrun.len]
var/mob/living/L = currentrun[currentrun.len]
currentrun.len--
if(M)
M.Life(seconds, times_fired)
if(L)
L.Life(seconds, times_fired)
else
GLOB.mob_living_list.Remove(M)
GLOB.mob_living_list.Remove(L)
if (MC_TICK_CHECK)
return
+4 -8
View File
@@ -113,11 +113,8 @@ SUBSYSTEM_DEF(shuttle)
qdel(T, force=TRUE)
CheckAutoEvac()
//Cargo stuff start
var/fire_time_diff = max(0, world.time - last_fire) //Don't want this to be below 0, seriously.
var/point_gain = (fire_time_diff / 600) * passive_supply_points_per_minute
points += point_gain
//Cargo stuff end
if(!(times_fired % CEILING(600/wait, 1)))
points += passive_supply_points_per_minute
var/esETA = emergency?.getModeStr()
emergency_shuttle_stat_text = "[esETA? "[esETA] [emergency.getTimerStr()]" : ""]"
@@ -185,14 +182,13 @@ SUBSYSTEM_DEF(shuttle)
WARNING("requestEvac(): There is no emergency shuttle, but the \
shuttle was called. Using the backup shuttle instead.")
if(!backup_shuttle)
throw EXCEPTION("requestEvac(): There is no emergency shuttle, \
CRASH("requestEvac(): There is no emergency shuttle, \
or backup shuttle! The game will be unresolvable. This is \
possibly a mapping error, more likely a bug with the shuttle \
manipulation system, or badminry. It is possible to manually \
resolve this problem by loading an emergency shuttle template \
manually, and then calling register() on the mobile docking port. \
Good luck.")
return
emergency = backup_shuttle
var/srd = CONFIG_GET(number/shuttle_refuel_delay)
if(world.time - SSticker.round_start_time < srd)
@@ -420,7 +416,7 @@ SUBSYSTEM_DEF(shuttle)
/datum/controller/subsystem/shuttle/proc/request_transit_dock(obj/docking_port/mobile/M)
if(!istype(M))
throw EXCEPTION("[M] is not a mobile docking port")
CRASH("[M] is not a mobile docking port")
if(M.assigned_transit)
return
+4 -3
View File
@@ -370,7 +370,7 @@ SUBSYSTEM_DEF(vote)
var/list/runnable_storytellers = config.get_runnable_storytellers()
for(var/T in runnable_storytellers)
var/datum/dynamic_storyteller/S = T
runnable_storytellers[S] *= scores[initial(S.name)]
runnable_storytellers[S] *= stored_gamemode_votes[initial(S.name)]
var/datum/dynamic_storyteller/S = pickweightAllowZero(runnable_storytellers)
GLOB.dynamic_storyteller_type = S
if("map")
@@ -499,10 +499,11 @@ SUBSYSTEM_DEF(vote)
modes_to_add -= "traitor" // makes it so that traitor is always available
choices.Add(modes_to_add)
if("dynamic")
var/list/probabilities = CONFIG_GET(keyed_list/storyteller_weight)
for(var/T in config.storyteller_cache)
var/datum/dynamic_storyteller/S = T
var/list/probabilities = CONFIG_GET(keyed_list/storyteller_weight)
if(probabilities[initial(S.config_tag)] > 0)
var/probability = ((initial(S.config_tag) in probabilities) ? probabilities[initial(S.config_tag)] : initial(S.weight))
if(probability > 0)
choices.Add(initial(S.name))
choice_descs.Add(initial(S.desc))
if("custom")
+15 -9
View File
@@ -8,6 +8,7 @@
var/desc = null
var/obj/target = null
var/check_flags = 0
var/required_mobility_flags = MOBILITY_USE
var/processing = FALSE
var/obj/screen/movable/action_button/button = null
var/buttontooltipstyle = ""
@@ -96,20 +97,23 @@
/datum/action/proc/IsAvailable()
if(!owner)
return 0
return FALSE
var/mob/living/L = owner
if(istype(L) && !CHECK_ALL_MOBILITY(L, required_mobility_flags))
return FALSE
if(check_flags & AB_CHECK_RESTRAINED)
if(owner.restrained())
return 0
return FALSE
if(check_flags & AB_CHECK_STUN)
if(owner.IsKnockdown() || owner.IsStun())
return 0
if(istype(L) && !CHECK_MOBILITY(L, MOBILITY_USE))
return FALSE
if(check_flags & AB_CHECK_LYING)
if(owner.lying)
return 0
if(istype(L) && !CHECK_MOBILITY(L, MOBILITY_STAND))
return FALSE
if(check_flags & AB_CHECK_CONSCIOUS)
if(owner.stat)
return 0
return 1
return FALSE
return TRUE
/datum/action/proc/UpdateButtonIcon(status_only = FALSE, force = FALSE)
if(button)
@@ -422,6 +426,7 @@
/datum/action/item_action/hands_free
check_flags = AB_CHECK_CONSCIOUS
required_mobility_flags = NONE
/datum/action/item_action/hands_free/activate
name = "Activate"
@@ -430,7 +435,8 @@
name = "Shift Nerves"
/datum/action/item_action/explosive_implant
check_flags = 0
check_flags = NONE
required_mobility_flags = NONE
name = "Activate Explosive Implant"
/datum/action/item_action/toggle_research_scanner
+1 -1
View File
@@ -136,7 +136,7 @@
fall_chance += 2
if(prob(fall_chance) && !owner.lying && !owner.buckled)
to_chat(owner, "<span class='warning'>Your leg gives out!</span>")
owner.Knockdown(35)
owner.DefaultCombatKnockdown(35)
else if(owner.get_active_held_item())
var/drop_chance = 1
+1 -1
View File
@@ -13,7 +13,7 @@
/datum/brain_trauma/special/godwoken/on_life()
..()
if(prob(4))
if(prob(33) && (owner.IsStun() || owner.IsKnockdown() || owner.IsUnconscious()))
if(prob(33) && owner.HighestImmobilityAmount())
speak("unstun", TRUE)
else if(prob(60) && owner.health <= owner.crit_threshold)
speak("heal", TRUE)
+9 -3
View File
@@ -39,12 +39,18 @@
//title_image = ntitle_image
/datum/browser/proc/add_stylesheet(name, file)
if(istype(name, /datum/asset/spritesheet))
if (istype(name, /datum/asset/spritesheet))
var/datum/asset/spritesheet/sheet = name
stylesheets["spritesheet_[sheet.name].css"] = "data/spritesheets/[sheet.name]"
else
stylesheets["[ckey(name)].css"] = file
register_asset("[ckey(name)].css", file)
var/asset_name = "[name].css"
stylesheets[asset_name] = file
if(!SSassets.cache[asset_name])
register_asset(asset_name, file)
/datum/browser/proc/add_script(name, file)
scripts["[ckey(name)].js"] = file
register_asset("[ckey(name)].js", file)
/datum/browser/proc/set_content(ncontent)
content = ncontent
+1 -1
View File
@@ -59,4 +59,4 @@
"<span class='userdanger'>You slide on [A]!</span>")
cooldown = world.time
H.Knockdown(60)
H.DefaultCombatKnockdown(60)
+2 -3
View File
@@ -100,7 +100,7 @@
AM.forceMove(T)
if(isliving(AM))
var/mob/living/L = AM
L.Knockdown(100)
L.DefaultCombatKnockdown(100)
L.adjustBruteLoss(30)
falling_atoms -= AM
@@ -110,8 +110,7 @@
if (isliving(AM))
var/mob/living/L = AM
L.notransform = TRUE
L.Stun(200)
L.resting = TRUE
L.Paralyze(200)
var/oldtransform = AM.transform
var/oldcolor = AM.color
@@ -33,11 +33,17 @@
/obj/item/organ/ears/cat = 1)
category = CAT_CLOTHING
////////
//Huds//
////////
/datum/crafting_recipe/hudsunsec
name = "Security HUDsunglasses"
result = /obj/item/clothing/glasses/hud/security/sunglasses
time = 20
tools = list(TOOL_SCREWDRIVER, TOOL_WIRECUTTER)
parts = list(/obj/item/clothing/glasses/hud/security = 1,
/obj/item/clothing/glasses/sunglasses = 1)
reqs = list(/obj/item/clothing/glasses/hud/security = 1,
/obj/item/clothing/glasses/sunglasses = 1,
/obj/item/stack/cable_coil = 5)
@@ -56,9 +62,11 @@
result = /obj/item/clothing/glasses/hud/health/sunglasses
time = 20
tools = list(TOOL_SCREWDRIVER, TOOL_WIRECUTTER)
parts = list(/obj/item/clothing/glasses/hud/health = 1,
/obj/item/clothing/glasses/sunglasses = 1)
reqs = list(/obj/item/clothing/glasses/hud/health = 1,
/obj/item/clothing/glasses/sunglasses = 1,
/obj/item/stack/cable_coil = 5)
/obj/item/clothing/glasses/sunglasses = 1,
/obj/item/stack/cable_coil = 5)
category = CAT_CLOTHING
/datum/crafting_recipe/hudsunmedremoval
@@ -86,6 +94,27 @@
tools = list(TOOL_SCREWDRIVER, TOOL_WIRECUTTER)
reqs = list(/obj/item/clothing/glasses/sunglasses/reagent = 1)
category = CAT_CLOTHING
/datum/crafting_recipe/diagnostic_sunglasses
name = "Diagnostic HUDsunglasses"
result = /obj/item/clothing/glasses/hud/diagnostic/sunglasses
time = 20
tools = list(TOOL_SCREWDRIVER, TOOL_WIRECUTTER)
parts = list(/obj/item/clothing/glasses/hud/diagnostic = 1,
/obj/item/clothing/glasses/sunglasses = 1)
reqs = list(/obj/item/clothing/glasses/hud/diagnostic = 1,
/obj/item/clothing/glasses/sunglasses = 1,
/obj/item/stack/cable_coil = 5)
category = CAT_CLOTHING
/datum/crafting_recipe/diagnostic_singlasses_removal
name = "Diagnostic HUDsunglasses removal"
result = /obj/item/clothing/glasses/sunglasses
time = 20
tools = list(TOOL_SCREWDRIVER, TOOL_WIRECUTTER)
reqs = list(/obj/item/clothing/glasses/hud/diagnostic/sunglasses = 1)
category = CAT_CLOTHING
/* //Kevinz doesn't want it as a recipe for now, leaving it in if anything ever changes to let it in
/datum/crafting_recipe/stunglasses
name = "Stunglasses"
@@ -130,7 +159,6 @@
reqs = list(/obj/item/stack/sheet/durathread = 7,
/obj/item/stack/sheet/leather = 3)
time = 70
always_availible = TRUE
category = CAT_CLOTHING
/datum/crafting_recipe/durathread_toolbelt
@@ -139,7 +167,6 @@
reqs = list(/obj/item/stack/sheet/durathread = 5,
/obj/item/stack/sheet/leather = 2)
time = 30
always_availible = TRUE
category = CAT_CLOTHING
/datum/crafting_recipe/durathread_bandolier
@@ -148,7 +175,6 @@
reqs = list(/obj/item/stack/sheet/durathread = 6,
/obj/item/stack/sheet/leather = 2)
time = 50
always_availible = TRUE
category = CAT_CLOTHING
/datum/crafting_recipe/durathread_helmet
@@ -157,7 +183,6 @@
reqs = list(/obj/item/stack/sheet/durathread = 4,
/obj/item/stack/sheet/leather = 2)
time = 30
always_availible = TRUE
category = CAT_CLOTHING
/datum/crafting_recipe/durathread_vest
@@ -166,7 +191,6 @@
reqs = list(/obj/item/stack/sheet/durathread = 6,
/obj/item/stack/sheet/leather = 3)
time = 50
always_availible = TRUE
category = CAT_CLOTHING
/datum/crafting_recipe/durathread_wintercoat
@@ -183,5 +207,4 @@
reqs = list(/obj/item/clothing/suit/hooded/wintercoat = 1,
/obj/item/bedsheet/cosmos = 1)
time = 60
always_availible = TRUE
category = CAT_CLOTHING
@@ -119,18 +119,6 @@
category = CAT_WEAPONRY
subcategory = CAT_WEAPON
/datum/crafting_recipe/switchblade_ms
name = "Switchblade"
result = /obj/item/switchblade/crafted
reqs = list(/obj/item/weaponcrafting/stock = 1,
/obj/item/weaponcrafting/receiver = 1,
/obj/item/kitchen/knife = 1,
/obj/item/stack/cable_coil = 2)
tools = list(TOOL_WELDER)
time = 45
category = CAT_WEAPONRY
subcategory = CAT_WEAPON
//////////////////
///BOMB CRAFTING//
//////////////////
@@ -310,19 +298,15 @@
subcategory = CAT_AMMO
/datum/crafting_recipe/ashen_arrow
name = "Bonfire-Hardened Arrow"
name = "Fire Hardened Arrow"
result = /obj/item/ammo_casing/caseless/arrow/ashen
tools = list(/obj/structure/bonfire)
tools = list(TOOL_WELDER)
time = 30
always_availible = FALSE
reqs = list(/obj/item/ammo_casing/caseless/arrow = 1)
category = CAT_WEAPONRY
subcategory = CAT_AMMO
/datum/crafting_recipe/ashen_arrow/welder
name = "Welder-Hardened Arrow"
tools = list(TOOL_WELDER)
/datum/crafting_recipe/smartdart
name = "Medical smartdart"
result = /obj/item/reagent_containers/syringe/dart
+1 -1
View File
@@ -18,7 +18,7 @@
var/mob/living/LM = parent
var/v = volume
var/e = e_range
if(!T.footstep || LM.buckled || LM.lying || !LM.canmove || LM.resting || LM.buckled || LM.throwing || LM.movement_type & (VENTCRAWLING | FLYING))
if(!T.footstep || LM.buckled || !CHECK_MOBILITY(LM, MOBILITY_STAND) || LM.buckled || LM.throwing || (LM.movement_type & (VENTCRAWLING | FLYING)))
if (LM.lying && !LM.buckled && !(!T.footstep || LM.movement_type & (VENTCRAWLING | FLYING))) //play crawling sound if we're lying
playsound(T, 'sound/effects/footstep/crawl1.ogg', 15 * v)
return
+1 -1
View File
@@ -54,7 +54,7 @@
msg += " and knocks [target] [target_buckled? "off of [target.buckled]" : "down"]"
if(target_buckled)
target.buckled.unbuckle_mob(target)
target.Knockdown(knockdown_time)
target.DefaultCombatKnockdown(knockdown_time)
if(length(msg))
user.visible_message("<span class='danger'>[msg]!</span>")
+7 -7
View File
@@ -42,7 +42,7 @@
RegisterSignal(parent, COMSIG_PARENT_EXAMINE, .proc/OnExamine)
for(var/mat in mat_list) //Make the assoc list ref | amount
var/datum/material/M = getmaterialref(mat) || mat
var/datum/material/M = SSmaterials.GetMaterialRef(mat)
materials[M] = 0
/datum/component/material_container/proc/OnExamine(datum/source, mob/user, list/examine_list)
@@ -130,7 +130,7 @@
/// For inserting an amount of material
/datum/component/material_container/proc/insert_amount_mat(amt, var/datum/material/mat)
if(!istype(mat))
mat = getmaterialref(mat)
mat = SSmaterials.GetMaterialRef(mat)
if(amt > 0 && has_space(amt))
var/total_amount_saved = total_amount
if(mat)
@@ -145,7 +145,7 @@
/// Uses an amount of a specific material, effectively removing it.
/datum/component/material_container/proc/use_amount_mat(amt, var/datum/material/mat)
if(!istype(mat))
mat = getmaterialref(mat)
mat = SSmaterials.GetMaterialRef(mat)
var/amount = materials[mat]
if(mat)
if(amount >= amt)
@@ -157,7 +157,7 @@
/// Proc for transfering materials to another container.
/datum/component/material_container/proc/transer_amt_to(var/datum/component/material_container/T, amt, var/datum/material/mat)
if(!istype(mat))
mat = getmaterialref(mat)
mat = SSmaterials.GetMaterialRef(mat)
if((amt==0)||(!T)||(!mat))
return FALSE
if(amt<0)
@@ -190,7 +190,7 @@
for(var/x in mats) //Loop through all required materials
var/datum/material/req_mat = x
if(!istype(req_mat))
req_mat = getmaterialref(req_mat) //Get the ref if necesary
req_mat = SSmaterials.GetMaterialRef(req_mat) //Get the ref if necesary
if(!materials[req_mat]) //Do we have the resource?
return FALSE //Can't afford it
var/amount_required = mats[x] * multiplier
@@ -251,7 +251,7 @@
var/datum/material/req_mat = x
if(!istype(req_mat))
if(ispath(req_mat)) //Is this an actual material, or is it a category?
req_mat = getmaterialref(req_mat) //Get the ref
req_mat = SSmaterials.GetMaterialRef(req_mat) //Get the ref
else // Its a category. (For example MAT_CATEGORY_RIGID)
if(!has_enough_of_category(req_mat, mats[req_mat], multiplier)) //Do we have enough of this category?
@@ -316,5 +316,5 @@
/// Returns the amount of a specific material in this container.
/datum/component/material_container/proc/get_material_amount(var/datum/material/mat)
if(!istype(mat))
mat = getmaterialref(mat)
mat = SSmaterials.GetMaterialRef(mat)
return(materials[mat])
+2 -2
View File
@@ -240,7 +240,7 @@
/datum/component/riding/human/force_dismount(mob/living/user)
var/atom/movable/AM = parent
AM.unbuckle_mob(user)
user.Knockdown(60)
user.DefaultCombatKnockdown(60)
user.visible_message("<span class='warning'>[AM] pushes [user] off of [AM.p_them()]!</span>")
/datum/component/riding/cyborg
@@ -298,7 +298,7 @@
M.Move(targetm)
M.visible_message("<span class='warning'>[M] is thrown clear of [AM]!</span>")
M.throw_at(target, 14, 5, AM)
M.Knockdown(60)
M.DefaultCombatKnockdown(60)
/datum/component/riding/proc/equip_buckle_inhands(mob/living/carbon/human/user, amount_required = 1, mob/living/riding_target_override)
var/list/equipped
+2 -2
View File
@@ -22,7 +22,7 @@
return //undeads are unaffected by the spook-pocalypse.
if(istype(H.dna.species, /datum/species/zombie))
H.adjustStaminaLoss(25)
H.Knockdown(15) //zombies can't resist the doot
H.DefaultCombatKnockdown(15) //zombies can't resist the doot
C.Jitter(35)
C.stuttering = 20
if((!istype(H.dna.species, /datum/species/skeleton)) && (!istype(H.dna.species, /datum/species/golem)) && (!istype(H.dna.species, /datum/species/android)) && (!istype(H.dna.species, /datum/species/jelly)))
@@ -36,7 +36,7 @@
/datum/component/spooky/proc/spectral_change(mob/living/carbon/human/H, mob/user)
if((H.getStaminaLoss() > 95) && (!istype(H.dna.species, /datum/species/skeleton)) && (!istype(H.dna.species, /datum/species/golem)) && (!istype(H.dna.species, /datum/species/android)) && (!istype(H.dna.species, /datum/species/jelly)))
H.Knockdown(20)
H.DefaultCombatKnockdown(20)
H.set_species(/datum/species/skeleton)
H.visible_message("<span class='warning'>[H] has given up on life as a mortal.</span>")
var/T = get_turf(H)
@@ -11,7 +11,7 @@
var/turf/loccheck = get_turf(A)
if(is_reebe(loccheck.z))
user.visible_message("<span class='warning'>An unseen force knocks [user] to the ground!</span>", "<span class='big_brass'>\"I think not!\"</span>")
user.Knockdown(60)
user.DefaultCombatKnockdown(60)
return
if(istype(loccheck.loc, /area/fabric_of_reality))
to_chat(user, "<span class='danger'>You can't do that here!</span>")
@@ -25,7 +25,7 @@
for(var/mob/living/M in T)
if(M.movement_type & FLYING)
M.visible_message("<span class='danger'>The bluespace collapse crushes the air towards it, pulling [M] towards the ground...</span>")
M.Knockdown(5, TRUE, TRUE) //Overrides stun absorbs.
M.DefaultCombatKnockdown(5, TRUE, TRUE) //Overrides stun absorbs.
T.TerraformTurf(/turf/open/chasm/magic, /turf/open/chasm/magic)
for (var/obj/structure/ladder/unbreakable/binary/ladder in GLOB.ladders)
ladder.ActivateAlmonds()
+1 -1
View File
@@ -409,7 +409,7 @@
/datum/component/storage/proc/check_views()
for(var/mob/M in can_see_contents())
if(!isobserver(M) && !M.CanReach(src, view_only = TRUE))
if(!isobserver(M) && !M.CanReach(parent, view_only = TRUE))
close(M)
/datum/component/storage/proc/emp_act(datum/source, severity)
+14 -16
View File
@@ -26,10 +26,10 @@
/datum/proc/vv_get_dropdown()
. = list()
. += "---"
.["Call Proc"] = "?_src_=vars;[HrefToken()];proc_call=[REF(src)]"
.["Mark Object"] = "?_src_=vars;[HrefToken()];mark_object=[REF(src)]"
.["Delete"] = "?_src_=vars;[HrefToken()];delete=[REF(src)]"
.["Show VV To Player"] = "?_src_=vars;[HrefToken(TRUE)];expose=[REF(src)]"
.["Call Proc"] = "?_src_=vars;[HrefToken()];proc_call=\ref[src]"
.["Mark Object"] = "?_src_=vars;[HrefToken()];mark_object=\ref[src]"
.["Delete"] = "?_src_=vars;[HrefToken()];delete=\ref[src]"
.["Show VV To Player"] = "?_src_=vars;[HrefToken(TRUE)];expose=\ref[src]"
/datum/proc/on_reagent_change(changetype)
@@ -54,7 +54,7 @@
return
var/title = ""
var/refid = REF(D)
var/refid = "\ref[D]"
var/icon/sprite
var/hash
@@ -62,8 +62,6 @@
if (!islist)
type = D.type
if(istype(D, /atom))
var/atom/AT = D
if(AT.icon && AT.icon_state)
@@ -410,7 +408,7 @@
/client/proc/vv_update_display(datum/D, span, content)
src << output("[span]:[content]", "variables[REF(D)].browser:replace_span")
src << output("[span]:[content]", "variables\ref[D].browser:replace_span")
#define VV_HTML_ENCODE(thing) ( sanitize ? html_encode(thing) : thing )
@@ -423,9 +421,9 @@
name = DA[name] //name is really the index until this line
else
value = DA[name]
header = "<li style='backgroundColor:white'>(<a href='?_src_=vars;[HrefToken()];listedit=[REF(DA)];index=[index]'>E</a>) (<a href='?_src_=vars;[HrefToken()];listchange=[REF(DA)];index=[index]'>C</a>) (<a href='?_src_=vars;[HrefToken()];listremove=[REF(DA)];index=[index]'>-</a>) "
header = "<li style='backgroundColor:white'>(<a href='?_src_=vars;[HrefToken()];listedit=\ref[DA];index=[index]'>E</a>) (<a href='?_src_=vars;[HrefToken()];listchange=\ref[DA];index=[index]'>C</a>) (<a href='?_src_=vars;[HrefToken()];listremove=\ref[DA];index=[index]'>-</a>) "
else
header = "<li style='backgroundColor:white'>(<a href='?_src_=vars;[HrefToken()];datumedit=[REF(DA)];varnameedit=[name]'>E</a>) (<a href='?_src_=vars;[HrefToken()];datumchange=[REF(DA)];varnamechange=[name]'>C</a>) (<a href='?_src_=vars;[HrefToken()];datummass=[REF(DA)];varnamemass=[name]'>M</a>) "
header = "<li style='backgroundColor:white'>(<a href='?_src_=vars;[HrefToken()];datumedit=\ref[DA];varnameedit=[name]'>E</a>) (<a href='?_src_=vars;[HrefToken()];datumchange=\ref[DA];varnamechange=[name]'>C</a>) (<a href='?_src_=vars;[HrefToken()];datummass=\ref[DA];varnamemass=[name]'>M</a>) "
else
header = "<li>"
@@ -440,7 +438,7 @@
#ifdef VARSICON
var/icon/I = new/icon(value)
var/rnd = rand(1,10000)
var/rname = "tmp[REF(I)][rnd].png"
var/rname = "tmp\ref[I][rnd].png"
usr << browse_rsc(I, rname)
item = "[VV_HTML_ENCODE(name)] = (<span class='value'>[value]</span>) <img class=icon src=\"[rname]\">"
#else
@@ -453,9 +451,9 @@
else if (istype(value, /datum))
var/datum/D = value
if ("[D]" != "[D.type]") //if the thing as a name var, lets use it.
item = "<a href='?_src_=vars;[HrefToken()];Vars=[REF(value)]'>[VV_HTML_ENCODE(name)] [REF(value)]</a> = [D] [D.type]"
item = "<a href='?_src_=vars;[HrefToken()];Vars=\ref[value]'>[VV_HTML_ENCODE(name)] [REF(value)]</a> = [D] [D.type]"
else
item = "<a href='?_src_=vars;[HrefToken()];Vars=[REF(value)]'>[VV_HTML_ENCODE(name)] [REF(value)]</a> = [D.type]"
item = "<a href='?_src_=vars;[HrefToken()];Vars=\ref[value]'>[VV_HTML_ENCODE(name)] [REF(value)]</a> = [D.type]"
else if (islist(value))
var/list/L = value
@@ -473,9 +471,9 @@
items += debug_variable(key, val, level + 1, sanitize = sanitize)
item = "<a href='?_src_=vars;[HrefToken()];Vars=[REF(value)]'>[VV_HTML_ENCODE(name)] = /list ([L.len])</a><ul>[items.Join()]</ul>"
item = "<a href='?_src_=vars;[HrefToken()];Vars=\ref[value]'>[VV_HTML_ENCODE(name)] = /list ([L.len])</a><ul>[items.Join()]</ul>"
else
item = "<a href='?_src_=vars;[HrefToken()];Vars=[REF(value)]'>[VV_HTML_ENCODE(name)] = /list ([L.len])</a>"
item = "<a href='?_src_=vars;[HrefToken()];Vars=\ref[value]'>[VV_HTML_ENCODE(name)] = /list ([L.len])</a>"
else if (name in GLOB.bitfields)
var/list/flags = list()
@@ -587,7 +585,7 @@
var/prompt = alert("Do you want to grant [C] access to view this VV window? (they will not be able to edit or change anything nor open nested vv windows unless they themselves are an admin)", "Confirm", "Yes", "No")
if (prompt != "Yes" || !usr.client)
return
message_admins("[key_name_admin(usr)] Showed [key_name_admin(C)] a <a href='?_src_=vars;[HrefToken(TRUE)];datumrefresh=[REF(thing)]'>VV window</a>")
message_admins("[key_name_admin(usr)] Showed [key_name_admin(C)] a <a href='?_src_=vars;[HrefToken(TRUE)];datumrefresh=\ref[thing]'>VV window</a>")
log_admin("Admin [key_name(usr)] Showed [key_name(C)] a VV window of a [thing]")
to_chat(C, "[usr.client.holder.fakekey ? "an Administrator" : "[usr.client.key]"] has granted you access to view a View Variables window")
C.debug_variables(thing)
@@ -279,7 +279,7 @@
M.emote("deathgasp")
M.fakedeath("regenerative_coma")
M.update_stat()
M.update_canmove()
M.update_mobility()
addtimer(CALLBACK(src, .proc/uncoma, M), 300)
/datum/symptom/heal/coma/proc/uncoma(mob/living/M)
@@ -288,7 +288,7 @@
active_coma = FALSE
M.cure_fakedeath("regenerative_coma")
M.update_stat()
M.update_canmove()
M.update_mobility()
/datum/symptom/heal/coma/Heal(mob/living/carbon/M, datum/disease/advance/A, actual_power)
var/heal_amt = 4 * actual_power
+1 -1
View File
@@ -44,7 +44,7 @@
if(prob(25))
affected_mob.vomit(95)
H.emote("cough")
H.Knockdown(40)
H.DefaultCombatKnockdown(40)
H.losebreath += 4
if(prob(3))
to_chat(H, "<span class='danger'>You feel very weak and dizzy...</span>")
+5 -3
View File
@@ -51,10 +51,11 @@
if(ishuman(destination))
var/mob/living/carbon/human/H = destination
H.give_genitals(TRUE)//This gives the body the genitals of this DNA. Used for any transformations based on DNA
destination.flavor_text = destination.dna.features["flavor_text"] //Update the flavor_text to use new dna text
if(transfer_SE)
destination.dna.struc_enzymes = struc_enzymes
SEND_SIGNAL(destination, COMSIG_CARBON_IDENTITY_TRANSFERRED_TO, src, transfer_SE)
/datum/dna/proc/copy_dna(datum/dna/new_dna)
new_dna.unique_enzymes = unique_enzymes
new_dna.struc_enzymes = struc_enzymes
@@ -218,7 +219,7 @@
unique_enzymes = generate_unique_enzymes()
uni_identity = generate_uni_identity()
struc_enzymes = generate_struc_enzymes()
features = random_features()
features = random_features(species?.id)
/datum/dna/stored //subtype used by brain mob's stored_dna
@@ -284,7 +285,6 @@
if(newfeatures)
dna.features = newfeatures
flavor_text = dna.features["flavor_text"] //Update the flavor_text to use new dna text
if(mrace)
var/datum/species/newrace = new mrace.type
@@ -306,6 +306,8 @@
dna.struc_enzymes = se
domutcheck()
SEND_SIGNAL(src, COMSIG_HUMAN_HARDSET_DNA, ui, se, newreal_name, newblood_type, mrace, newfeatures)
if(mrace || newfeatures || ui)
update_body()
update_hair()
+146
View File
@@ -0,0 +1,146 @@
GLOBAL_LIST_EMPTY(mobs_with_editable_flavor_text) //et tu, hacky code
/datum/element/flavor_text
element_flags = ELEMENT_BESPOKE|ELEMENT_DETACH
id_arg_index = 3
var/flavor_name = "Flavor Text"
var/list/texts_by_atom = list()
var/addendum = "This can also be used for OOC notes and preferences!"
var/always_show = FALSE
var/max_len = MAX_FAVOR_LEN
var/can_edit = TRUE
/datum/element/flavor_text/Attach(datum/target, text = "", _name = "Flavor Text", _addendum, _max_len = MAX_FAVOR_LEN, _always_show = FALSE, _edit = TRUE)
. = ..()
if(. == ELEMENT_INCOMPATIBLE || !isatom(target)) //no reason why this shouldn't work on atoms too.
return ELEMENT_INCOMPATIBLE
if(_max_len)
max_len = _max_len
texts_by_atom[target] = copytext(text, 1, max_len)
if(_name)
flavor_name = _name
if(!isnull(addendum))
addendum = _addendum
always_show = _always_show
can_edit = _edit
RegisterSignal(target, COMSIG_PARENT_EXAMINE, .proc/show_flavor)
if(can_edit && ismob(target)) //but only mobs receive the proc/verb for the time being
var/mob/M = target
LAZYOR(GLOB.mobs_with_editable_flavor_text[M], src)
M.verbs |= /mob/proc/manage_flavor_tests
/datum/element/flavor_text/Detach(atom/A)
. = ..()
UnregisterSignal(A, COMSIG_PARENT_EXAMINE)
texts_by_atom -= A
if(can_edit && ismob(A))
var/mob/M = A
LAZYREMOVE(GLOB.mobs_with_editable_flavor_text[M], src)
if(!GLOB.mobs_with_editable_flavor_text[M])
GLOB.mobs_with_editable_flavor_text -= M
M.verbs -= /mob/proc/manage_flavor_tests
/datum/element/flavor_text/proc/show_flavor(atom/target, mob/user, list/examine_list)
if(!always_show && isliving(target))
var/mob/living/L = target
var/unknown = L.get_visible_name() == "Unknown"
if(!unknown && iscarbon(target))
var/mob/living/carbon/C = L
unknown = (C.wear_mask && (C.wear_mask.flags_inv & HIDEFACE)) || (C.head && (C.head.flags_inv & HIDEFACE))
if(unknown)
if(!("...?" in examine_list)) //can't think of anything better in case of multiple flavor texts.
examine_list += "...?"
return
var/text = texts_by_atom[target]
if(!text)
return
var/msg = replacetext(text, "\n", " ")
if(length_char(msg) <= 40)
examine_list += "<span class='notice'>[html_encode(msg)]</span>"
else
examine_list += "<span class='notice'>[html_encode(copytext_char(msg, 1, 37))]... <a href='?src=[REF(src)];show_flavor=[REF(target)]'>More...</span></a>"
/datum/element/flavor_text/Topic(href, href_list)
. = ..()
if(.)
return
if(href_list["show_flavor"])
var/atom/target = locate(href_list["show_flavor"])
var/text = texts_by_atom[target]
if(text)
usr << browse("<HTML><HEAD><TITLE>[target.name]</TITLE></HEAD><BODY><TT>[replacetext(texts_by_atom[target], "\n", "<BR>")]</TT></BODY></HTML>", "window=[target.name];size=500x200")
onclose(usr, "[target.name]")
return TRUE
/mob/proc/manage_flavor_tests()
set name = "Manage Flavor Texts"
set desc = "Used to manage your various flavor texts."
set category = "IC"
var/list/L = GLOB.mobs_with_editable_flavor_text[src]
if(length(L) == 1)
var/datum/element/flavor_text/F = L[1]
F.set_flavor(src)
return
var/list/choices = list()
for(var/i in L)
var/datum/element/flavor_text/F = i
choices[F.flavor_name] = F
var/chosen = input(src, "Which flavor text would you like to modify?") as null|anything in choices
if(!chosen)
return
var/datum/element/flavor_text/F = choices[chosen]
F.set_flavor(src)
/datum/element/flavor_text/proc/set_flavor(mob/user)
if(!(user in texts_by_atom))
return FALSE
var/lower_name = lowertext(flavor_name)
var/new_text = stripped_multiline_input(user, "Set the [lower_name] displayed on 'examine'. [addendum]", flavor_name, texts_by_atom[usr], max_len, TRUE)
if(!isnull(new_text) && (user in texts_by_atom))
texts_by_atom[user] = html_decode(new_text)
to_chat(src, "Your [lower_name] has been updated.")
return TRUE
return FALSE
//subtypes with additional hooks for DNA and preferences.
/datum/element/flavor_text/carbon
/datum/element/flavor_text/carbon/Attach(datum/target, text = "", _name = "Flavor Text", _addendum, _max_len = MAX_FAVOR_LEN, _always_show = FALSE, _edit = TRUE)
if(!iscarbon(target))
return ELEMENT_INCOMPATIBLE
. = ..()
if(. == ELEMENT_INCOMPATIBLE)
return
RegisterSignal(target, COMSIG_CARBON_IDENTITY_TRANSFERRED_TO, .proc/update_dna_flavor_text)
if(ishuman(target))
RegisterSignal(target, COMSIG_HUMAN_PREFS_COPIED_TO, .proc/update_prefs_flavor_text)
RegisterSignal(target, COMSIG_HUMAN_HARDSET_DNA, .proc/update_dna_flavor_text)
RegisterSignal(target, COMSIG_HUMAN_ON_RANDOMIZE, .proc/unset_flavor)
/datum/element/flavor_text/carbon/Detach(mob/living/carbon/C)
. = ..()
UnregisterSignal(C, list(COMSIG_CARBON_IDENTITY_TRANSFERRED_TO, COMSIG_HUMAN_PREFS_COPIED_TO, COMSIG_HUMAN_HARDSET_DNA, COMSIG_HUMAN_ON_RANDOMIZE))
/datum/element/flavor_text/carbon/proc/update_dna_flavor_text(mob/living/carbon/C)
texts_by_atom[C] = C.dna.features["flavor_text"]
/datum/element/flavor_text/carbon/proc/update_prefs_flavor_text(mob/living/carbon/human/H, datum/preferences/P, icon_updates = TRUE, roundstart_checks = TRUE)
texts_by_atom[H] = P.features["flavor_text"]
/datum/element/flavor_text/carbon/set_flavor(mob/living/carbon/user)
. = ..()
if(. && user.dna)
user.dna.features["flavor_text"] = texts_by_atom[user]
/datum/element/flavor_text/carbon/proc/unset_flavor(mob/living/carbon/user)
texts_by_atom[user] = ""
+18
View File
@@ -0,0 +1,18 @@
/datum/element/sword_point
element_flags = ELEMENT_DETACH
/datum/element/sword_point/Attach(datum/target)
. = ..()
if(. == ELEMENT_INCOMPATIBLE)
return
if(!istype(target))
return ELEMENT_INCOMPATIBLE
RegisterSignal(target, COMSIG_ITEM_ALT_AFTERATTACK, .proc/point)
/datum/element/sword_point/Detach(datum/source)
. = ..()
UnregisterSignal(source, COMSIG_ITEM_ALT_AFTERATTACK)
/datum/element/sword_point/proc/point(datum/source, atom/target, mob/user, proximity_flag, params)
if(!proximity_flag && ismob(target))
user.visible_message("<span class='notice'>[user] points the tip of [src] at [target].</span>", "<span class='notice'>You point the tip of [src] at [target].</span>")
+2 -1
View File
@@ -118,7 +118,8 @@
if(DEAD)
to_chat(user, "<span class='notice'>You cannot [key] while dead.</span>")
return FALSE
if(restraint_check && (user.IsStun() || user.IsKnockdown()))
var/mob/living/L = user
if(restraint_check && (istype(L) && !CHECK_MOBILITY(L, MOBILITY_USE)))
if(!intentional)
return FALSE
to_chat(user, "<span class='notice'>You cannot [key] while stunned.</span>")
+10 -10
View File
@@ -42,19 +42,19 @@
/datum/martial_art/cqc/proc/Slam(mob/living/carbon/human/A, mob/living/carbon/human/D)
if(!can_use(A))
return FALSE
if(!D.stat || !D.IsKnockdown())
if(CHECK_MOBILITY(D, MOBILITY_STAND))
D.visible_message("<span class='warning'>[A] slams [D] into the ground!</span>", \
"<span class='userdanger'>[A] slams you into the ground!</span>")
playsound(get_turf(A), 'sound/weapons/slam.ogg', 50, 1, -1)
D.apply_damage(10, BRUTE)
D.Knockdown(120)
D.DefaultCombatKnockdown(120)
log_combat(A, D, "slammed (CQC)")
return TRUE
/datum/martial_art/cqc/proc/Kick(mob/living/carbon/human/A, mob/living/carbon/human/D)
if(!can_use(A))
return FALSE
if(!D.stat || !D.IsKnockdown())
if(CHECK_MOBILITY(D, MOBILITY_STAND))
D.visible_message("<span class='warning'>[A] kicks [D] back!</span>", \
"<span class='userdanger'>[A] kicks you back!</span>")
playsound(get_turf(A), 'sound/weapons/cqchit1.ogg', 50, 1, -1)
@@ -62,7 +62,7 @@
D.throw_at(throw_target, 1, 14, A)
D.apply_damage(10, BRUTE)
log_combat(A, D, "kicked (CQC)")
if(D.IsKnockdown() && !D.stat)
if(!CHECK_MOBILITY(D, MOBILITY_STAND) && CHECK_MOBILITY(D, MOBILITY_USE))
log_combat(A, D, "knocked out (Head kick)(CQC)")
D.visible_message("<span class='warning'>[A] kicks [D]'s head, knocking [D.p_them()] out!</span>", \
"<span class='userdanger'>[A] kicks your head, knocking you out!</span>")
@@ -119,7 +119,7 @@
D.grabbedby(A, 1)
if(old_grab_state == GRAB_PASSIVE)
D.drop_all_held_items()
A.grab_state = GRAB_AGGRESSIVE //Instant agressive grab if on grab intent
A.setGrabState(GRAB_AGGRESSIVE) //Instant agressive grab if on grab intent
log_combat(A, D, "grabbed", addition="aggressively")
D.visible_message("<span class='warning'>[A] violently grabs [D]!</span>", \
"<span class='userdanger'>[A] violently grabs you!</span>")
@@ -136,7 +136,7 @@
A.do_attack_animation(D)
var/picked_hit_type = pick("CQC'd", "Big Bossed")
var/bonus_damage = 13
if(D.IsKnockdown() || D.resting || D.lying)
if(!CHECK_MOBILITY(D, MOBILITY_STAND))
bonus_damage += 5
picked_hit_type = "stomps on"
D.apply_damage(bonus_damage, BRUTE)
@@ -147,12 +147,12 @@
D.visible_message("<span class='danger'>[A] [picked_hit_type] [D]!</span>", \
"<span class='userdanger'>[A] [picked_hit_type] you!</span>")
log_combat(A, D, "[picked_hit_type] (CQC)")
if(A.resting && !D.stat && !D.IsKnockdown())
if(!CHECK_MOBILITY(A, MOBILITY_STAND) && !D.stat && CHECK_MOBILITY(D, MOBILITY_STAND))
D.visible_message("<span class='warning'>[A] leg sweeps [D]!", \
"<span class='userdanger'>[A] leg sweeps you!</span>")
playsound(get_turf(A), 'sound/effects/hit_kick.ogg', 50, 1, -1)
D.apply_damage(10, BRUTE)
D.Knockdown(60)
D.DefaultCombatKnockdown(60)
log_combat(A, D, "sweeped (CQC)")
return TRUE
@@ -164,7 +164,7 @@
if(check_streak(A,D))
return TRUE
if(prob(65))
if(!D.stat || !D.IsKnockdown() || !restraining)
if(CHECK_MOBILITY(D, MOBILITY_MOVE) || !restraining)
I = D.get_active_held_item()
D.visible_message("<span class='warning'>[A] strikes [D]'s jaw with their hand!</span>", \
"<span class='userdanger'>[A] strikes your jaw, disorienting you!</span>")
@@ -185,7 +185,7 @@
D.SetSleeping(400)
restraining = FALSE
if(A.grab_state < GRAB_NECK)
A.grab_state = GRAB_NECK
A.setGrabState(GRAB_NECK)
else
restraining = FALSE
return FALSE
+3 -3
View File
@@ -96,13 +96,13 @@
return 0
/datum/martial_art/krav_maga/proc/leg_sweep(mob/living/carbon/human/A, mob/living/carbon/human/D)
if(D.lying || D.IsKnockdown())
if(!CHECK_MOBILITY(D, MOBILITY_STAND))
return 0
D.visible_message("<span class='warning'>[A] leg sweeps [D]!</span>", \
"<span class='userdanger'>[A] leg sweeps you!</span>")
playsound(get_turf(A), 'sound/effects/hit_kick.ogg', 50, 1, -1)
D.apply_damage(5, BRUTE)
D.Knockdown(40, override_hardstun = 0.01, override_stamdmg = 25)
D.DefaultCombatKnockdown(40, override_hardstun = 0.01, override_stamdmg = 25)
log_combat(A, D, "leg sweeped")
return 1
@@ -138,7 +138,7 @@
log_combat(A, D, "punched")
var/picked_hit_type = pick("punches", "kicks")
var/bonus_damage = 10
if(D.IsKnockdown() || D.resting || D.lying)
if(CHECK_MOBILITY(D, MOBILITY_STAND))
bonus_damage += 5
picked_hit_type = "stomps on"
D.apply_damage(bonus_damage, BRUTE)
+1 -1
View File
@@ -16,7 +16,7 @@
playsound(D, 'sound/effects/meteorimpact.ogg', 25, 1, -1)
var/throwtarget = get_edge_target_turf(A, get_dir(A, get_step_away(D, A)))
D.throw_at(throwtarget, 4, 2, A)//So stuff gets tossed around at the same time.
D.Knockdown(20)
D.DefaultCombatKnockdown(20)
if(atk_verb)
log_combat(A, D, "[atk_verb] (Mushroom Punch)")
return TRUE
+4 -4
View File
@@ -34,10 +34,10 @@
log_combat(A, D, "grabbed", addition="aggressively")
D.visible_message("<span class='warning'>[A] violently grabs [D]!</span>", \
"<span class='userdanger'>[A] violently grabs you!</span>")
A.grab_state = GRAB_AGGRESSIVE //Instant aggressive grab
A.setGrabState(GRAB_AGGRESSIVE) //Instant aggressive grab
else
log_combat(A, D, "grabbed", addition="passively")
A.grab_state = GRAB_PASSIVE
A.setGrabState(GRAB_PASSIVE)
if(4)
A.do_attack_animation(D, ATTACK_EFFECT_PUNCH)
atk_verb = "headbutts"
@@ -49,7 +49,7 @@
if(!istype(D.head,/obj/item/clothing/head/helmet/) && !istype(D.head,/obj/item/clothing/head/hardhat))
D.adjustOrganLoss(ORGAN_SLOT_BRAIN, 5)
A.Stun(rand(10,45))
D.Knockdown(rand(5,30))//CIT CHANGE - makes stuns from martial arts always use Knockdown instead of Stun for the sake of consistency
D.DefaultCombatKnockdown(rand(5,30))//CIT CHANGE - makes stuns from martial arts always use Knockdown instead of Stun for the sake of consistency
if(5,6)
A.do_attack_animation(D, ATTACK_EFFECT_PUNCH)
atk_verb = pick("punches", "kicks", "hits", "slams into")
@@ -59,7 +59,7 @@
playsound(get_turf(D), 'sound/effects/meteorimpact.ogg', 25, 1, -1)
var/throwtarget = get_edge_target_turf(A, get_dir(A, get_step_away(D, A)))
D.throw_at(throwtarget, 4, 2, A)//So stuff gets tossed around at the same time.
D.Knockdown(60)
D.DefaultCombatKnockdown(60)
if(7,8)
basic_hit(A,D)
+9 -9
View File
@@ -79,7 +79,7 @@
return TRUE
/datum/martial_art/the_rising_bass/proc/sideKick(mob/living/carbon/human/A, mob/living/carbon/human/D)
if(!D.IsKnockdown() || D.lying == 0)
if(CHECK_MOBILITY(D, MOBILITY_STAND))
var/dir = A.dir & (NORTH | SOUTH) ? pick(EAST, WEST) : pick(NORTH, SOUTH)
var/oppdir = dir == NORTH ? SOUTH : dir == SOUTH ? NORTH : dir == EAST ? WEST : EAST
var/turf/H = get_step(D, dir)
@@ -89,7 +89,7 @@
"<span class='userdanger'>[A] kicks you in the side, forcing you to step away!</span>")
playsound(get_turf(A), 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
D.apply_damage(5, BRUTE, BODY_ZONE_CHEST)
D.Knockdown(60)
D.DefaultCombatKnockdown(60)
var/L = !checkfordensity(H,D) ? (!checkfordensity(K,D) ? D.loc : K) : H
D.forceMove(L)
log_combat(A, D, "side kicked (Rising Bass)")
@@ -97,7 +97,7 @@
return basic_hit(A,D)
/datum/martial_art/the_rising_bass/proc/shoulderFlip(mob/living/carbon/human/A, mob/living/carbon/human/D)
if(!D.IsKnockdown() || !D.lying)
if(CHECK_MOBILITY(D, MOBILITY_STAND))
var/turf/H = get_step(A, get_dir(D,A))
var/L = checkfordensity(H,D) ? H : A.loc
A.do_attack_animation(D, ATTACK_EFFECT_PUNCH)
@@ -108,14 +108,14 @@
D.apply_damage(10, BRUTE, BODY_ZONE_CHEST)
D.apply_damage(30, BRUTE, BODY_ZONE_HEAD)
D.Sleeping(60)
D.Knockdown(300)
D.DefaultCombatKnockdown(300)
D.forceMove(L)
log_combat(A, D, "shoulder flipped (Rising Bass)")
return TRUE
return basic_hit(A,D)
/datum/martial_art/the_rising_bass/proc/repulsePunch(mob/living/carbon/human/A, mob/living/carbon/human/D)
if((!D.IsKnockdown() || !D.lying) && repulsecool > world.time)
if(CHECK_MOBILITY(D, MOBILITY_STAND) && repulsecool < world.time)
A.do_attack_animation(D, ATTACK_EFFECT_PUNCH)
D.visible_message("<span class='warning'>[A] smashes [D] in the chest, throwing them away!</span>", \
"<span class='userdanger'>[A] smashes you in the chest, repelling you away!</span>")
@@ -123,14 +123,14 @@
var/atom/F = get_edge_target_turf(D, get_dir(A, get_step_away(D, A)))
D.throw_at(F, 10, 1)
D.apply_damage(10, BRUTE, BODY_ZONE_CHEST)
D.Knockdown(90)
D.DefaultCombatKnockdown(90)
log_combat(A, D, "repulse punched (Rising Bass)")
repulsecool = world.time + 3 SECONDS
return TRUE
return basic_hit(A,D)
/datum/martial_art/the_rising_bass/proc/footSmash(mob/living/carbon/human/A, mob/living/carbon/human/D)
if(!D.IsKnockdown() || !D.lying)
if(CHECK_MOBILITY(D, MOBILITY_STAND))
A.do_attack_animation(D, ATTACK_EFFECT_KICK)
D.visible_message("<span class='warning'>[A] smashes their foot down on [D]'s foot!</span>", \
"<span class='userdanger'>[A] smashes your foot!</span>")
@@ -142,7 +142,7 @@
return basic_hit(A,D)
/datum/martial_art/the_rising_bass/proc/deftSwitch(mob/living/carbon/human/A, mob/living/carbon/human/D)
if(!D.IsKnockdown() || !D.lying)
if(CHECK_MOBILITY(D, MOBILITY_STAND))
if (D.get_active_held_item())
var/obj/item/G = D.get_active_held_item()
if (G && !(G.item_flags & (ABSTRACT|DROPDEL)) && D.temporarilyRemoveItemFromInventory(G))
@@ -205,4 +205,4 @@
deftswitch.Remove(H)
sidekick.Remove(H)
REMOVE_TRAIT(H, TRAIT_NOGUNS, RISING_BASS_TRAIT)
REMOVE_TRAIT(H, TRAIT_AUTO_CATCH_ITEM, RISING_BASS_TRAIT)
REMOVE_TRAIT(H, TRAIT_AUTO_CATCH_ITEM, RISING_BASS_TRAIT)
+13 -13
View File
@@ -37,7 +37,7 @@
return FALSE
/datum/martial_art/the_sleeping_carp/proc/wristWrench(mob/living/carbon/human/A, mob/living/carbon/human/D)
if(!D.stat && !D.IsStun() && !D.IsKnockdown())
if(CHECK_MOBILITY(D, MOBILITY_USE))
log_combat(A, D, "wrist wrenched (Sleeping Carp)")
A.do_attack_animation(D, ATTACK_EFFECT_PUNCH)
D.visible_message("<span class='warning'>[A] grabs [D]'s wrist and wrenches it sideways!</span>", \
@@ -46,19 +46,19 @@
D.emote("scream")
D.dropItemToGround(D.get_active_held_item())
D.apply_damage(5, BRUTE, pick(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM))
D.Knockdown(60)//CIT CHANGE - makes sleepingcarp use knockdown() for its stuns instead of stun()
D.DefaultCombatKnockdown(60)//CIT CHANGE - makes sleepingcarp use knockdown() for its stuns instead of stun()
return TRUE
return basic_hit(A,D)
/datum/martial_art/the_sleeping_carp/proc/backKick(mob/living/carbon/human/A, mob/living/carbon/human/D)
if(!D.stat && !D.IsKnockdown())
if(CHECK_MOBILITY(D, MOBILITY_STAND))
if(A.dir == D.dir)
log_combat(A, D, "back-kicked (Sleeping Carp)")
A.do_attack_animation(D, ATTACK_EFFECT_PUNCH)
D.visible_message("<span class='warning'>[A] kicks [D] in the back!</span>", \
"<span class='userdanger'>[A] kicks you in the back, making you stumble and fall!</span>")
step_to(D,get_step(D,D.dir),1)
D.Knockdown(80)
D.DefaultCombatKnockdown(80)
playsound(get_turf(D), 'sound/weapons/punch1.ogg', 50, 1, -1)
return TRUE
else
@@ -68,20 +68,20 @@
return basic_hit(A,D)
/datum/martial_art/the_sleeping_carp/proc/kneeStomach(mob/living/carbon/human/A, mob/living/carbon/human/D)
if(!D.stat && !D.IsKnockdown())
if(CHECK_MOBILITY(D, MOBILITY_STAND))
log_combat(A, D, "stomach kneed (Sleeping Carp)")
A.do_attack_animation(D, ATTACK_EFFECT_KICK)
D.visible_message("<span class='warning'>[A] knees [D] in the stomach!</span>", \
"<span class='userdanger'>[A] winds you with a knee in the stomach!</span>")
D.audible_message("<b>[D]</b> gags!")
D.losebreath += 3
D.Knockdown(40)//CIT CHANGE - makes sleepingcarp use knockdown() for its stuns instead of stun()
D.DefaultCombatKnockdown(40)//CIT CHANGE - makes sleepingcarp use knockdown() for its stuns instead of stun()
playsound(get_turf(D), 'sound/weapons/punch1.ogg', 50, 1, -1)
return TRUE
return basic_hit(A,D)
/datum/martial_art/the_sleeping_carp/proc/headKick(mob/living/carbon/human/A, mob/living/carbon/human/D)
if(!D.stat && !D.IsKnockdown())
if(CHECK_MOBILITY(D, MOBILITY_STAND))
log_combat(A, D, "head kicked (Sleeping Carp)")
A.do_attack_animation(D, ATTACK_EFFECT_KICK)
D.visible_message("<span class='warning'>[A] kicks [D] in the head!</span>", \
@@ -89,12 +89,12 @@
D.apply_damage(20, BRUTE, BODY_ZONE_HEAD)
D.drop_all_held_items()
playsound(get_turf(D), 'sound/weapons/punch1.ogg', 50, 1, -1)
D.Knockdown(80)//CIT CHANGE - makes sleepingcarp use knockdown() for its stuns instead of stun()
D.DefaultCombatKnockdown(80)//CIT CHANGE - makes sleepingcarp use knockdown() for its stuns instead of stun()
return TRUE
return basic_hit(A,D)
/datum/martial_art/the_sleeping_carp/proc/elbowDrop(mob/living/carbon/human/A, mob/living/carbon/human/D)
if(D.IsKnockdown() || D.resting || D.stat)
if(!CHECK_MOBILITY(D, MOBILITY_STAND))
log_combat(A, D, "elbow dropped (Sleeping Carp)")
A.do_attack_animation(D, ATTACK_EFFECT_PUNCH)
D.visible_message("<span class='warning'>[A] elbow drops [D]!</span>", \
@@ -115,7 +115,7 @@
D.grabbedby(A, 1)
if(old_grab_state == GRAB_PASSIVE)
D.drop_all_held_items()
A.grab_state = GRAB_AGGRESSIVE //Instant agressive grab if on grab intent
A.setGrabState(GRAB_AGGRESSIVE) //Instant agressive grab if on grab intent
log_combat(A, D, "grabbed", addition="aggressively")
D.visible_message("<span class='warning'>[A] violently grabs [D]!</span>", \
"<span class='userdanger'>[A] violently grabs you!</span>")
@@ -134,7 +134,7 @@
playsound(get_turf(D), 'sound/weapons/punch1.ogg', 25, 1, -1)
if(prob(D.getBruteLoss()) && !D.lying)
D.visible_message("<span class='warning'>[D] stumbles and falls!</span>", "<span class='userdanger'>The blow sends you to the ground!</span>")
D.Knockdown(80)
D.DefaultCombatKnockdown(80)
log_combat(A, D, "[atk_verb] (Sleeping Carp)")
return TRUE
@@ -192,7 +192,7 @@
add_fingerprint(user)
if((HAS_TRAIT(user, TRAIT_CLUMSY)) && prob(50))
to_chat(user, "<span class ='warning'>You club yourself over the head with [src].</span>")
user.Knockdown(60)
user.DefaultCombatKnockdown(60)
if(ishuman(user))
var/mob/living/carbon/human/H = user
H.apply_damage(2*force, BRUTE, BODY_ZONE_HEAD)
@@ -226,7 +226,7 @@
if(prob(10))
H.visible_message("<span class='warning'>[H] collapses!</span>", \
"<span class='userdanger'>Your legs give out!</span>")
H.Knockdown(80)
H.DefaultCombatKnockdown(80)
if(H.staminaloss && !H.IsSleeping())
var/total_health = (H.health - H.staminaloss)
if(total_health <= HEALTH_THRESHOLD_CRIT && !H.stat)
+5 -5
View File
@@ -207,7 +207,7 @@
if (T && isturf(T))
if (!D.stat)
D.emote("scream")
D.throw_at(T, 10, 4, A, TRUE, TRUE, callback = CALLBACK(D, /mob/living/carbon/human.proc/Knockdown, 20))
D.throw_at(T, 10, 4, A, TRUE, TRUE, callback = CALLBACK(D, /mob/living/carbon/human.proc/DefaultCombatKnockdown, 20))
log_combat(A, D, "has thrown with wrestling")
return 0
@@ -303,7 +303,7 @@
playsound(A.loc, "swing_hit", 50, 1)
if (!D.stat)
D.emote("scream")
D.Knockdown(40)
D.DefaultCombatKnockdown(40)
switch(rand(1,3))
if (2)
@@ -361,7 +361,7 @@
var/turf/T = get_edge_target_turf(A, get_dir(A, get_step_away(D, A)))
if (T && isturf(T))
D.Knockdown(20)
D.DefaultCombatKnockdown(20)
D.throw_at(T, 3, 2)
log_combat(A, D, "roundhouse-kicked")
@@ -400,7 +400,7 @@
if (falling == 1)
A.visible_message("<span class = 'danger'><B>...and dives head-first into the ground, ouch!</b></span>")
A.adjustBruteLoss(rand(10,20))
A.Knockdown(60)
A.DefaultCombatKnockdown(60)
to_chat(A, "[D] is too far away!")
return 0
@@ -429,7 +429,7 @@
else
D.adjustBruteLoss(rand(20,30))
D.Knockdown(40)
D.DefaultCombatKnockdown(40)
A.pixel_y = 0
+17 -15
View File
@@ -41,20 +41,21 @@ Simple datum which is instanced once per type and is used for every object of sa
///This proc is called when the material is added to an object specifically.
/datum/material/proc/on_applied_obj(var/obj/o, amount, material_flags)
var/new_max_integrity = CEILING(o.max_integrity * integrity_modifier, 1)
o.modify_max_integrity(new_max_integrity)
o.force *= strength_modifier
o.throwforce *= strength_modifier
if(material_flags & MATERIAL_AFFECT_STATISTICS)
var/new_max_integrity = CEILING(o.max_integrity * integrity_modifier, 1)
o.modify_max_integrity(new_max_integrity)
o.force *= strength_modifier
o.throwforce *= strength_modifier
var/list/temp_armor_list = list() //Time to add armor modifiers!
var/list/temp_armor_list = list() //Time to add armor modifiers!
if(!istype(o.armor))
return
var/list/current_armor = o.armor?.getList()
if(!istype(o.armor))
return
var/list/current_armor = o.armor?.getList()
for(var/i in current_armor)
temp_armor_list[i] = current_armor[i] * armor_modifiers[i]
o.armor = getArmor(arglist(temp_armor_list))
for(var/i in current_armor)
temp_armor_list[i] = current_armor[i] * armor_modifiers[i]
o.armor = getArmor(arglist(temp_armor_list))
///This proc is called when the material is removed from an object.
/datum/material/proc/on_removed(atom/source, material_flags)
@@ -71,7 +72,8 @@ Simple datum which is instanced once per type and is used for every object of sa
///This proc is called when the material is removed from an object specifically.
/datum/material/proc/on_removed_obj(var/obj/o, amount, material_flags)
var/new_max_integrity = initial(o.max_integrity)
o.modify_max_integrity(new_max_integrity)
o.force = initial(o.force)
o.throwforce = initial(o.throwforce)
if(material_flags & MATERIAL_AFFECT_STATISTICS)
var/new_max_integrity = initial(o.max_integrity)
o.modify_max_integrity(new_max_integrity)
o.force = initial(o.force)
o.throwforce = initial(o.throwforce)
+4
View File
@@ -617,6 +617,10 @@
if(!(has_antag_datum(/datum/antagonist/traitor)))
add_antag_datum(/datum/antagonist/traitor)
/datum/mind/proc/make_Contractor_Support()
if(!(has_antag_datum(/datum/antagonist/traitor/contractor_support)))
add_antag_datum(/datum/antagonist/traitor/contractor_support)
/datum/mind/proc/make_Changeling()
var/datum/antagonist/changeling/C = has_antag_datum(/datum/antagonist/changeling)
if(!C)
+1 -1
View File
@@ -11,7 +11,7 @@
/datum/progressbar/New(mob/User, goal_number, atom/target)
. = ..()
if (!istype(target))
EXCEPTION("Invalid target given")
CRASH("Invalid target given")
if (goal_number)
goal = goal_number
bar = image('icons/effects/progessbar.dmi', target, "prog_bar_0", HUD_LAYER)
+67
View File
@@ -322,3 +322,70 @@
suffix = "advancedlab.dmm"
name = "Abductor Replication Lab"
description = "Some scientists tried and almost succeeded to recreate abductor tools. Somewhat slower and a bit less modern than their originals, these tools are the best you can get if you aren't an alien."
//Space ruins for the station z
/datum/map_template/ruin/spacenearstation
prefix = "_maps/RandomRuins/SpaceRuinsStation/"
cost = 1
allow_duplicates = FALSE
/datum/map_template/ruin/spacenearstation/roid1
id = "roid1"
suffix = "roid1.dmm"
name = "Mineable Asteroid 1"
description = "Mineral asteroid 1."
allow_duplicates = TRUE
/datum/map_template/ruin/spacenearstation/roid2
id = "roid2"
suffix = "roid2.dmm"
name = "Crab Roid"
description = "Mineral asteroid. Ft. Crabs."
/datum/map_template/ruin/spacenearstation/roid3
id = "roid3"
suffix = "roid3.dmm"
name = "Dorm Roid"
description = "Mineral asteroid. Ft. Dorm."
/datum/map_template/ruin/spacenearstation/roid4
id = "roid4"
suffix = "roid4.dmm"
name = "Mineable Asteroid 2"
description = "Mineral asteroid 2."
/datum/map_template/ruin/spacenearstation/roid5
id = "roid5"
suffix = "roid5.dmm"
name = "Mineable Asteroid 3"
description = "Mineral asteroid. Ft. Holofans."
/datum/map_template/ruin/spacenearstation/roid6
id = "roid6"
suffix = "roid6.dmm"
name = "Mineable Asteroid 4"
description = "Mineral asteroid. Ft. Crashed escape pod."
/datum/map_template/ruin/spacenearstation/roid7
id = "roid7"
suffix = "roid7.dmm"
name = "Mineable Asteroid 5"
description = "Mineral asteroid. Ft. Derelict space bar."
/datum/map_template/ruin/spacenearstation/roid8
id = "roid8"
suffix = "roid8.dmm"
name = "Dead wizard Roid"
description = "Mineral asteroid. Ft. Dead wizard and toilet paradox bag."
/datum/map_template/ruin/spacenearstation/roid9
id = "roid9"
suffix = "roid9.dmm"
name = "Monitoring Roid"
description = "Mineral asteroid. Ft. Station monitoring, syndie toolbox and erp."
/datum/map_template/ruin/spacenearstation/roid10
id = "roid10"
suffix = "roid10.dmm"
name = "Maze Roid"
description = "Mineral asteroid. Ft. Brief maze."
+3 -5
View File
@@ -73,8 +73,7 @@
owner.log_message("gained Vanguard stun immunity", LOG_ATTACK)
owner.add_stun_absorption("vanguard", INFINITY, 1, "'s yellow aura momentarily intensifies!", "Your ward absorbs the stun!", " radiating with a soft yellow light!")
owner.visible_message("<span class='warning'>[owner] begins to faintly glow!</span>", "<span class='brass'>You will absorb all stuns for the next twenty seconds.</span>")
owner.SetStun(0, FALSE)
owner.SetKnockdown(0)
owner.SetAllImmobility(0, FALSE)
owner.setStaminaLoss(0, FALSE)
progbar = new(owner, duration, owner)
progbar.bar.color = list("#FAE48C", "#FAE48C", "#FAE48C", rgb(0,0,0))
@@ -97,7 +96,7 @@
if(owner.stun_absorption[i]["end_time"] > world.time && owner.stun_absorption[i]["priority"] > vanguard["priority"])
otheractiveabsorptions = TRUE
if(!GLOB.ratvar_awakens && stuns_blocked && !otheractiveabsorptions)
owner.Knockdown(stuns_blocked)
owner.DefaultCombatKnockdown(stuns_blocked)
message_to_owner = "<span class='boldwarning'>The weight of the Vanguard's protection crashes down upon you!</span>"
if(stuns_blocked >= 300)
message_to_owner += "\n<span class='userdanger'>You faint from the exertion!</span>"
@@ -226,9 +225,8 @@
return ..()
/datum/status_effect/wish_granters_gift/on_remove()
owner.revive(full_heal = 1, admin_revive = 1)
owner.revive(full_heal = TRUE, admin_revive = TRUE)
owner.visible_message("<span class='warning'>[owner] appears to wake from the dead, having healed all wounds!</span>", "<span class='notice'>You have regenerated.</span>")
owner.update_canmove()
/obj/screen/alert/status_effect/wish_granters_gift
name = "Wish Granter's Immortality"
+25 -6
View File
@@ -12,12 +12,12 @@
. = ..()
if(.)
if(updating_canmove)
owner.update_canmove()
owner.update_mobility()
if(needs_update_stat || issilicon(owner))
owner.update_stat()
/datum/status_effect/incapacitating/on_remove()
owner.update_canmove()
owner.update_mobility()
if(needs_update_stat || issilicon(owner)) //silicons need stat updates in addition to normal canmove updates
owner.update_stat()
@@ -29,10 +29,22 @@
/datum/status_effect/incapacitating/knockdown
id = "knockdown"
/datum/status_effect/incapacitating/knockdown/tick()
//IMMOBILIZED
/datum/status_effect/incapacitating/immobilized
id = "immobilized"
//PARALYZED
/datum/status_effect/incapacitating/paralyzed
id = "paralyzed"
/datum/status_effect/incapacitating/paralyzed/tick()
if(owner.getStaminaLoss())
owner.adjustStaminaLoss(-0.3) //reduce stamina loss by 0.3 per tick, 6 per 2 seconds
//DAZED
/datum/status_effect/incapacitating/dazed
id = "dazed"
//UNCONSCIOUS
/datum/status_effect/incapacitating/unconscious
id = "unconscious"
@@ -116,6 +128,7 @@
/datum/status_effect/electrode
id = "tased"
alert_type = null
var/slowdown = 1.5
var/slowdown_priority = 50 //to make sure the stronger effect overrides
var/affect_crawl = FALSE
@@ -143,7 +156,11 @@
/datum/status_effect/electrode/tick()
var/diff = world.time - last_tick
if(owner)
owner.adjustStaminaLoss(max(0, stamdmg_per_ds * diff)) //if you really want to try to stamcrit someone with a taser alone, you can, but it'll take time and good timing.
var/mob/living/carbon/C = owner
if(HAS_TRAIT(C, TRAIT_TASED_RESISTANCE))
qdel(src)
else
C.adjustStaminaLoss(max(0, stamdmg_per_ds * diff)) //if you really want to try to stamcrit someone with a taser alone, you can, but it'll take time and good timing.
last_tick = world.time
/datum/status_effect/electrode/nextmove_modifier() //why is this a proc. its no big deal since this doesnt get called often at all but literally w h y
@@ -160,6 +177,8 @@
. = ..()
if(iscarbon(owner))
var/mob/living/carbon/C = owner
if(HAS_TRAIT(C, TRAIT_TASED_RESISTANCE))
return
if(C.combatmode)
C.toggle_combat_mode(TRUE)
@@ -211,7 +230,7 @@
if(iscarbon(owner) && !is_servant_of_ratvar(owner) && !owner.anti_magic_check(chargecost = 0) && number_legs)
if(force_damage || owner.m_intent != MOVE_INTENT_WALK)
if(GLOB.ratvar_awakens)
owner.Knockdown(20)
owner.DefaultCombatKnockdown(20)
if(iscultist(owner))
owner.apply_damage(cultist_damage_on_toggle * 0.5, BURN, BODY_ZONE_L_LEG)
owner.apply_damage(cultist_damage_on_toggle * 0.5, BURN, BODY_ZONE_R_LEG)
@@ -558,7 +577,7 @@
var/old_oxyloss
/datum/status_effect/kindle/tick()
owner.Knockdown(15, TRUE, FALSE, 15)
owner.DefaultCombatKnockdown(15, TRUE, FALSE, 15)
if(iscarbon(owner))
var/mob/living/carbon/C = owner
C.silent = max(2, C.silent)
+4 -4
View File
@@ -17,11 +17,11 @@
to_chat(owner, "<span class='userdanger'>You become frozen in a cube!</span>")
cube = icon('icons/effects/freeze.dmi', "ice_cube")
owner.add_overlay(cube)
owner.update_canmove()
owner.update_mobility()
return ..()
/datum/status_effect/freon/tick()
owner.update_canmove()
owner.update_mobility()
if(can_melt && owner.bodytemperature >= BODYTEMP_NORMAL)
qdel(src)
@@ -31,14 +31,14 @@
if(!QDELETED(src))
to_chat(owner, "You break out of the ice cube!")
owner.remove_status_effect(/datum/status_effect/freon)
owner.update_canmove()
owner.update_mobility()
/datum/status_effect/freon/on_remove()
if(!owner.stat)
to_chat(owner, "The cube melts!")
owner.cut_overlay(cube)
owner.adjust_bodytemperature(100)
owner.update_canmove()
owner.update_mobility()
UnregisterSignal(owner, COMSIG_LIVING_RESIST)
/datum/status_effect/freon/watcher
+3 -3
View File
@@ -106,9 +106,9 @@
/datum/quirk/musician/on_spawn()
var/mob/living/carbon/human/H = quirk_holder
var/obj/item/instrument/guitar/guitar = new(get_turf(H))
H.put_in_hands(guitar)
H.equip_to_slot(guitar, SLOT_IN_BACKPACK)
var/obj/item/choice_beacon/music/B = new(get_turf(H))
H.put_in_hands(B)
H.equip_to_slot(B, SLOT_IN_BACKPACK)
var/obj/item/musicaltuner/musicaltuner = new(get_turf(H))
H.put_in_hands(musicaltuner)
H.equip_to_slot(musicaltuner, SLOT_IN_BACKPACK)
@@ -18,7 +18,7 @@
area_type = /area
protected_areas = list(/area/maintenance, /area/ai_monitored/turret_protected/ai_upload, /area/ai_monitored/turret_protected/ai_upload_foyer,
/area/ai_monitored/turret_protected/ai, /area/storage/emergency/starboard, /area/storage/emergency/port, /area/shuttle, /area/security/prison)
/area/ai_monitored/turret_protected/ai, /area/storage/emergency/starboard, /area/storage/emergency/port, /area/shuttle, /area/security/prison, /area/ruin, /area/space/nearstation)
target_trait = ZTRAIT_STATION
immunity_type = "rad"
+2 -2
View File
@@ -22,7 +22,7 @@
status += "The law sync module is [R.lawupdate ? "on" : "off"]."
status += "The intelligence link display shows [R.connected_ai ? R.connected_ai.name : "NULL"]."
status += "The camera light is [!isnull(R.builtInCamera) && R.builtInCamera.status ? "on" : "off"]."
status += "The lockdown indicator is [R.lockcharge ? "on" : "off"]."
status += "The lockdown indicator is [R.locked_down ? "on" : "off"]."
status += "The reset module hardware light is [R.has_module() ? "on" : "off"]."
return status
@@ -54,7 +54,7 @@
R.lawsync()
R.show_laws()
if(WIRE_LOCKDOWN)
R.SetLockdown(!R.lockcharge) // Toggle
R.SetLockdown(!R.locked_down) // Toggle
if(WIRE_RESET_MODULE)
if(R.has_module())
R.visible_message("[R]'s module servos twitch.", "Your module display flickers.")
+2 -1
View File
@@ -172,7 +172,7 @@
.["security_level"] = get_security_level()
.["round_duration"] = SSticker ? round((world.time-SSticker.round_start_time)/10) : 0
// Amount of world's ticks in seconds, useful for calculating round duration
//Time dilation stats.
.["time_dilation_current"] = SStime_track.time_dilation_current
.["time_dilation_avg"] = SStime_track.time_dilation_avg
@@ -187,3 +187,4 @@
if(!key_valid)
GLOB.topic_status_cache = .
+2
View File
@@ -48,6 +48,8 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
icon_state = "space_near"
dynamic_lighting = DYNAMIC_LIGHTING_IFSTARLIGHT
/area/space/station_ruins //Paint this area where you want station ruins to be allowed to spawn
/area/start
name = "start area"
icon_state = "start"
-33
View File
@@ -524,39 +524,6 @@ GLOBAL_LIST_EMPTY(teleportlocs)
/client/proc/ResetAmbiencePlayed()
played = FALSE
/atom/proc/has_gravity(turf/T)
if(!T || !isturf(T))
T = get_turf(src)
if(!T)
return 0
var/list/forced_gravity = list()
SEND_SIGNAL(src, COMSIG_ATOM_HAS_GRAVITY, T, forced_gravity)
if(!forced_gravity.len)
SEND_SIGNAL(T, COMSIG_TURF_HAS_GRAVITY, src, forced_gravity)
if(forced_gravity.len)
var/max_grav
for(var/i in forced_gravity)
max_grav = max(max_grav, i)
if(max_grav)
return max_grav
if(isspaceturf(T)) // Turf never has gravity
return 0
var/area/A = get_area(T)
if(A.has_gravity) // Areas which always has gravity
return A.has_gravity
else
// There's a gravity generator on our z level
if(GLOB.gravity_generators["[T.z]"])
var/max_grav = 0
for(var/obj/machinery/gravity_generator/main/G in GLOB.gravity_generators["[T.z]"])
max_grav = max(G.setting,max_grav)
return max_grav
return SSmapping.level_trait(T.z, ZTRAIT_GRAVITY)
/area/proc/setup(a_name)
name = a_name
power_equip = FALSE
+2
View File
@@ -3,6 +3,8 @@
/area/ruin/space
has_gravity = FALSE
blob_allowed = FALSE //Nope, no winning in space as a blob. Gotta eat the station.
outdoors = TRUE
ambientsounds = SPACE
/area/ruin/space/has_grav
has_gravity = STANDARD_GRAVITY
+54 -8
View File
@@ -28,7 +28,6 @@
var/list/managed_overlays
var/datum/proximity_monitor/proximity_monitor
var/buckle_message_cooldown = 0
var/fingerprintslast
var/list/filter_data //For handling persistent filters
@@ -98,7 +97,7 @@
var/temp_list = list()
for(var/i in custom_materials)
temp_list[getmaterialref(i)] = custom_materials[i] //Get the proper instanced version
temp_list[SSmaterials.GetMaterialRef(i)] = custom_materials[i] //Get the proper instanced version
custom_materials = null //Null the list to prepare for applying the materials properly
set_custom_materials(temp_list)
@@ -361,11 +360,12 @@
. = list()
SEND_SIGNAL(src, COMSIG_ATOM_UPDATE_OVERLAYS, .)
/atom/proc/relaymove(mob/user)
if(buckle_message_cooldown <= world.time)
buckle_message_cooldown = world.time + 50
/atom/proc/relaymove(mob/living/user)
if(!istype(user))
return //why are you buckling nonliving mobs to atoms?
if(user.buckle_message_cooldown <= world.time)
user.buckle_message_cooldown = world.time + 50
to_chat(user, "<span class='warning'>You can't move while buckled to [src]!</span>")
return
/atom/proc/contents_explosion(severity, target)
return //For handling the effects of explosions on contents that would not normally be effected
@@ -904,7 +904,7 @@ Proc for attack log creation, because really why not
if(custom_materials) //Only runs if custom materials existed at first. Should usually be the case but check anyways
for(var/i in custom_materials)
var/datum/material/custom_material = getmaterialref(i)
var/datum/material/custom_material = SSmaterials.GetMaterialRef(i)
custom_material.on_removed(src, material_flags) //Remove the current materials
if(!length(materials))
@@ -913,8 +913,54 @@ Proc for attack log creation, because really why not
custom_materials = list() //Reset the list
for(var/x in materials)
var/datum/material/custom_material = getmaterialref(x)
var/datum/material/custom_material = SSmaterials.GetMaterialRef(x)
if(!(material_flags & MATERIAL_NO_EFFECTS))
custom_material.on_applied(src, materials[custom_material] * multiplier * material_modifier, material_flags)
custom_materials[custom_material] += materials[x] * multiplier
/**
* Returns true if this atom has gravity for the passed in turf
*
* Sends signals COMSIG_ATOM_HAS_GRAVITY and COMSIG_TURF_HAS_GRAVITY, both can force gravity with
* the forced gravity var
*
* Gravity situations:
* * No gravity if you're not in a turf
* * No gravity if this atom is in is a space turf
* * Gravity if the area it's in always has gravity
* * Gravity if there's a gravity generator on the z level
* * Gravity if the Z level has an SSMappingTrait for ZTRAIT_GRAVITY
* * otherwise no gravity
*/
/atom/proc/has_gravity(turf/T)
if(!T || !isturf(T))
T = get_turf(src)
if(!T)
return 0
var/list/forced_gravity = list()
SEND_SIGNAL(src, COMSIG_ATOM_HAS_GRAVITY, T, forced_gravity)
if(!forced_gravity.len)
SEND_SIGNAL(T, COMSIG_TURF_HAS_GRAVITY, src, forced_gravity)
if(forced_gravity.len)
var/max_grav
for(var/i in forced_gravity)
max_grav = max(max_grav, i)
return max_grav
if(isspaceturf(T)) // Turf never has gravity
return 0
var/area/A = get_area(T)
if(A.has_gravity) // Areas which always has gravity
return A.has_gravity
else
// There's a gravity generator on our z level
if(GLOB.gravity_generators["[T.z]"])
var/max_grav = 0
for(var/obj/machinery/gravity_generator/main/G in GLOB.gravity_generators["[T.z]"])
max_grav = max(G.setting,max_grav)
return max_grav
return SSmapping.level_trait(T.z, ZTRAIT_GRAVITY)
+10 -307
View File
@@ -131,7 +131,7 @@
return FALSE
// Are we trying to pull something we are already pulling? Then enter grab cycle and end.
if(AM == pulling)
grab_state = state
setGrabState(state)
if(istype(AM,/mob/living))
var/mob/living/AMob = AM
AMob.grabbedby(src)
@@ -142,7 +142,7 @@
AM.pulledby.stop_pulling() //an object can't be pulled by two mobs at once.
pulling = AM
AM.pulledby = src
grab_state = state
setGrabState(state)
if(ismob(AM))
var/mob/M = AM
log_combat(src, M, "grabbed", addition="passive grab")
@@ -155,10 +155,10 @@
pulling.pulledby = null
var/mob/living/ex_pulled = pulling
pulling = null
grab_state = 0
setGrabState(0)
if(isliving(ex_pulled))
var/mob/living/L = ex_pulled
L.update_canmove()// mob gets up if it was lyng down in a chokehold
L.update_mobility()// mob gets up if it was lyng down in a chokehold
/atom/movable/proc/Move_Pulled(atom/A)
if(!pulling)
@@ -194,160 +194,6 @@
stop_pulling()
return
////////////////////////////////////////
// Here's where we rewrite how byond handles movement except slightly different
// To be removed on step_ conversion
// All this work to prevent a second bump
/atom/movable/Move(atom/newloc, direct=0)
. = FALSE
if(!newloc || newloc == loc)
return
if(!direct)
direct = get_dir(src, newloc)
setDir(direct)
if(!loc.Exit(src, newloc))
return
if(!newloc.Enter(src, src.loc))
return
// Past this is the point of no return
var/atom/oldloc = loc
var/area/oldarea = get_area(oldloc)
var/area/newarea = get_area(newloc)
loc = newloc
. = TRUE
oldloc.Exited(src, newloc)
if(oldarea != newarea)
oldarea.Exited(src, newloc)
for(var/i in oldloc)
if(i == src) // Multi tile objects
continue
var/atom/movable/thing = i
thing.Uncrossed(src)
newloc.Entered(src, oldloc)
if(oldarea != newarea)
newarea.Entered(src, oldloc)
for(var/i in loc)
if(i == src) // Multi tile objects
continue
var/atom/movable/thing = i
thing.Crossed(src)
//
////////////////////////////////////////
/atom/movable/Move(atom/newloc, direct)
var/atom/movable/pullee = pulling
var/turf/T = loc
if(pulling)
if(pullee && get_dist(src, pullee) > 1)
stop_pulling()
if(pullee && pullee.loc != loc && !isturf(pullee.loc) ) //to be removed once all code that changes an object's loc uses forceMove().
log_game("DEBUG:[src]'s pull on [pullee] wasn't broken despite [pullee] being in [pullee.loc]. Pull stopped manually.")
stop_pulling()
if(!loc || !newloc)
return FALSE
var/atom/oldloc = loc
if(loc != newloc)
if (!(direct & (direct - 1))) //Cardinal move
. = ..()
else //Diagonal move, split it into cardinal moves
moving_diagonally = FIRST_DIAG_STEP
var/first_step_dir
// The `&& moving_diagonally` checks are so that a forceMove taking
// place due to a Crossed, Bumped, etc. call will interrupt
// the second half of the diagonal movement, or the second attempt
// at a first half if step() fails because we hit something.
if (direct & NORTH)
if (direct & EAST)
if (step(src, NORTH) && moving_diagonally)
first_step_dir = NORTH
moving_diagonally = SECOND_DIAG_STEP
. = step(src, EAST)
else if (moving_diagonally && step(src, EAST))
first_step_dir = EAST
moving_diagonally = SECOND_DIAG_STEP
. = step(src, NORTH)
else if (direct & WEST)
if (step(src, NORTH) && moving_diagonally)
first_step_dir = NORTH
moving_diagonally = SECOND_DIAG_STEP
. = step(src, WEST)
else if (moving_diagonally && step(src, WEST))
first_step_dir = WEST
moving_diagonally = SECOND_DIAG_STEP
. = step(src, NORTH)
else if (direct & SOUTH)
if (direct & EAST)
if (step(src, SOUTH) && moving_diagonally)
first_step_dir = SOUTH
moving_diagonally = SECOND_DIAG_STEP
. = step(src, EAST)
else if (moving_diagonally && step(src, EAST))
first_step_dir = EAST
moving_diagonally = SECOND_DIAG_STEP
. = step(src, SOUTH)
else if (direct & WEST)
if (step(src, SOUTH) && moving_diagonally)
first_step_dir = SOUTH
moving_diagonally = SECOND_DIAG_STEP
. = step(src, WEST)
else if (moving_diagonally && step(src, WEST))
first_step_dir = WEST
moving_diagonally = SECOND_DIAG_STEP
. = step(src, SOUTH)
if(moving_diagonally == SECOND_DIAG_STEP)
if(!.)
setDir(first_step_dir)
else if (!inertia_moving)
inertia_next_move = world.time + inertia_move_delay
newtonian_move(direct)
moving_diagonally = 0
return
if(!loc || (loc == oldloc && oldloc != newloc))
last_move = 0
return
if(.)
Moved(oldloc, direct)
if(. && pulling && pulling == pullee) //we were pulling a thing and didn't lose it during our move.
if(pulling.anchored)
stop_pulling()
else
var/pull_dir = get_dir(src, pulling)
//puller and pullee more than one tile away or in diagonal position
if(get_dist(src, pulling) > 1 || (moving_diagonally != SECOND_DIAG_STEP && ((pull_dir - 1) & pull_dir)))
pulling.Move(T, get_dir(pulling, T)) //the pullee tries to reach our previous position
if(pulling && get_dist(src, pulling) > 1) //the pullee couldn't keep up
stop_pulling()
if(pulledby && moving_diagonally != FIRST_DIAG_STEP && get_dist(src, pulledby) > 1)//separated from our puller and not in the middle of a diagonal move.
pulledby.stop_pulling()
last_move = direct
setDir(direct)
if(. && has_buckled_mobs() && !handle_buckled_mob_movement(loc,direct)) //movement failed due to buckled mob(s)
return FALSE
//Called after a successful Move(). By this point, we've already moved
/atom/movable/proc/Moved(atom/OldLoc, Dir, Forced = FALSE)
SEND_SIGNAL(src, COMSIG_MOVABLE_MOVED, OldLoc, Dir, Forced)
if (!inertia_moving)
inertia_next_move = world.time + inertia_move_delay
newtonian_move(Dir)
if (length(client_mobs_in_contents))
update_parallax_contents()
return TRUE
/atom/movable/Destroy(force)
QDEL_NULL(proximity_monitor)
QDEL_NULL(language_holder)
@@ -372,143 +218,6 @@
orbiting.end_orbit(src)
orbiting = null
// Make sure you know what you're doing if you call this, this is intended to only be called by byond directly.
// You probably want CanPass()
/atom/movable/Cross(atom/movable/AM)
. = TRUE
SEND_SIGNAL(src, COMSIG_MOVABLE_CROSS, AM)
return CanPass(AM, AM.loc, TRUE)
//oldloc = old location on atom, inserted when forceMove is called and ONLY when forceMove is called!
/atom/movable/Crossed(atom/movable/AM, oldloc)
SEND_SIGNAL(src, COMSIG_MOVABLE_CROSSED, AM)
/atom/movable/Uncross(atom/movable/AM, atom/newloc)
. = ..()
if(SEND_SIGNAL(src, COMSIG_MOVABLE_UNCROSS, AM) & COMPONENT_MOVABLE_BLOCK_UNCROSS)
return FALSE
if(isturf(newloc) && !CheckExit(AM, newloc))
return FALSE
/atom/movable/Uncrossed(atom/movable/AM)
SEND_SIGNAL(src, COMSIG_MOVABLE_UNCROSSED, AM)
/atom/movable/Bump(atom/A)
if(!A)
CRASH("Bump was called with no argument.")
SEND_SIGNAL(src, COMSIG_MOVABLE_BUMP, A)
. = ..()
if(!QDELETED(throwing))
throwing.hit_atom(A)
. = TRUE
if(QDELETED(A))
return
A.Bumped(src)
/atom/movable/proc/forceMove(atom/destination)
. = FALSE
if(destination)
. = doMove(destination)
else
CRASH("No valid destination passed into forceMove")
/atom/movable/proc/moveToNullspace()
return doMove(null)
/atom/movable/proc/doMove(atom/destination)
. = FALSE
if(destination)
if(pulledby)
pulledby.stop_pulling()
var/atom/oldloc = loc
var/same_loc = oldloc == destination
var/area/old_area = get_area(oldloc)
var/area/destarea = get_area(destination)
loc = destination
moving_diagonally = 0
if(!same_loc)
if(oldloc)
oldloc.Exited(src, destination)
if(old_area && old_area != destarea)
old_area.Exited(src, destination)
for(var/atom/movable/AM in oldloc)
AM.Uncrossed(src)
var/turf/oldturf = get_turf(oldloc)
var/turf/destturf = get_turf(destination)
var/old_z = (oldturf ? oldturf.z : null)
var/dest_z = (destturf ? destturf.z : null)
if (old_z != dest_z)
onTransitZ(old_z, dest_z)
destination.Entered(src, oldloc)
if(destarea && old_area != destarea)
destarea.Entered(src, oldloc)
for(var/atom/movable/AM in destination)
if(AM == src)
continue
AM.Crossed(src, oldloc)
Moved(oldloc, NONE, TRUE)
. = TRUE
//If no destination, move the atom into nullspace (don't do this unless you know what you're doing)
else
. = TRUE
if (loc)
var/atom/oldloc = loc
var/area/old_area = get_area(oldloc)
oldloc.Exited(src, null)
if(old_area)
old_area.Exited(src, null)
loc = null
/atom/movable/proc/onTransitZ(old_z,new_z)
SEND_SIGNAL(src, COMSIG_MOVABLE_Z_CHANGED, old_z, new_z)
for (var/item in src) // Notify contents of Z-transition. This can be overridden IF we know the items contents do not care.
var/atom/movable/AM = item
AM.onTransitZ(old_z,new_z)
/atom/movable/proc/setMovetype(newval)
movement_type = newval
//Called whenever an object moves and by mobs when they attempt to move themselves through space
//And when an object or action applies a force on src, see newtonian_move() below
//Return 0 to have src start/keep drifting in a no-grav area and 1 to stop/not start drifting
//Mobs should return 1 if they should be able to move of their own volition, see client/Move() in mob_movement.dm
//movement_dir == 0 when stopping or any dir when trying to move
/atom/movable/proc/Process_Spacemove(movement_dir = 0)
if(has_gravity(src))
return 1
if(pulledby)
return 1
if(throwing)
return 1
if(!isturf(loc))
return 1
if(locate(/obj/structure/lattice) in range(1, get_turf(src))) //Not realistic but makes pushing things in space easier
return 1
return 0
/atom/movable/proc/newtonian_move(direction) //Only moves the object if it's under no gravity
if(!loc || Process_Spacemove(0))
inertia_dir = 0
return 0
inertia_dir = direction
if(!direction)
return 1
inertia_last_loc = loc
SSspacedrift.processing[src] = src
return 1
/atom/movable/proc/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
set waitfor = 0
SEND_SIGNAL(src, COMSIG_MOVABLE_IMPACT, hit_atom, throwingdatum)
@@ -610,17 +319,6 @@
SSthrowing.currentrun[src] = TT
TT.tick()
/atom/movable/proc/handle_buckled_mob_movement(newloc,direct)
for(var/m in buckled_mobs)
var/mob/living/buckled_mob = m
if(!buckled_mob.Move(newloc, direct))
forceMove(buckled_mob.loc)
last_move = buckled_mob.last_move
inertia_dir = last_move
buckled_mob.inertia_dir = last_move
return 0
return 1
/atom/movable/proc/force_pushed(atom/movable/pusher, force = MOVE_FORCE_DEFAULT, direction)
return FALSE
@@ -639,7 +337,7 @@
/atom/movable/CanPass(atom/movable/mover, turf/target)
if(mover in buckled_mobs)
return 1
return TRUE
return ..()
// called when this atom is removed from a storage item, which is passed on as S. The loc variable is already set to the new destination before this is called.
@@ -865,6 +563,11 @@
return FALSE
return TRUE
/// Updates the grab state of the movable
/// This exists to act as a hook for behaviour
/atom/movable/proc/setGrabState(newstate)
grab_state = newstate
/obj/item/proc/do_pickup_animation(atom/target)
set waitfor = FALSE
if(!istype(loc, /turf))
+307
View File
@@ -0,0 +1,307 @@
// File for movement procs for atom/movable
////////////////////////////////////////
// Here's where we rewrite how byond handles movement except slightly different
// To be removed on step_ conversion
// All this work to prevent a second bump
/atom/movable/Move(atom/newloc, direct=0)
. = FALSE
if(!newloc || newloc == loc)
return
if(!direct)
direct = get_dir(src, newloc)
setDir(direct)
if(!loc.Exit(src, newloc))
return
if(!newloc.Enter(src, src.loc))
return
// Past this is the point of no return
var/atom/oldloc = loc
var/area/oldarea = get_area(oldloc)
var/area/newarea = get_area(newloc)
loc = newloc
. = TRUE
oldloc.Exited(src, newloc)
if(oldarea != newarea)
oldarea.Exited(src, newloc)
for(var/i in oldloc)
if(i == src) // Multi tile objects
continue
var/atom/movable/thing = i
thing.Uncrossed(src)
newloc.Entered(src, oldloc)
if(oldarea != newarea)
newarea.Entered(src, oldloc)
for(var/i in loc)
if(i == src) // Multi tile objects
continue
var/atom/movable/thing = i
thing.Crossed(src)
//
////////////////////////////////////////
/atom/movable/Move(atom/newloc, direct)
var/atom/movable/pullee = pulling
var/turf/T = loc
if(pulling)
if(pullee && get_dist(src, pullee) > 1)
stop_pulling()
if(pullee && pullee.loc != loc && !isturf(pullee.loc) ) //to be removed once all code that changes an object's loc uses forceMove().
log_game("DEBUG:[src]'s pull on [pullee] wasn't broken despite [pullee] being in [pullee.loc]. Pull stopped manually.")
stop_pulling()
if(!loc || !newloc)
return FALSE
var/atom/oldloc = loc
if(loc != newloc)
if (!(direct & (direct - 1))) //Cardinal move
. = ..()
else //Diagonal move, split it into cardinal moves
moving_diagonally = FIRST_DIAG_STEP
var/first_step_dir
// The `&& moving_diagonally` checks are so that a forceMove taking
// place due to a Crossed, Bumped, etc. call will interrupt
// the second half of the diagonal movement, or the second attempt
// at a first half if step() fails because we hit something.
if (direct & NORTH)
if (direct & EAST)
if (step(src, NORTH) && moving_diagonally)
first_step_dir = NORTH
moving_diagonally = SECOND_DIAG_STEP
. = step(src, EAST)
else if (moving_diagonally && step(src, EAST))
first_step_dir = EAST
moving_diagonally = SECOND_DIAG_STEP
. = step(src, NORTH)
else if (direct & WEST)
if (step(src, NORTH) && moving_diagonally)
first_step_dir = NORTH
moving_diagonally = SECOND_DIAG_STEP
. = step(src, WEST)
else if (moving_diagonally && step(src, WEST))
first_step_dir = WEST
moving_diagonally = SECOND_DIAG_STEP
. = step(src, NORTH)
else if (direct & SOUTH)
if (direct & EAST)
if (step(src, SOUTH) && moving_diagonally)
first_step_dir = SOUTH
moving_diagonally = SECOND_DIAG_STEP
. = step(src, EAST)
else if (moving_diagonally && step(src, EAST))
first_step_dir = EAST
moving_diagonally = SECOND_DIAG_STEP
. = step(src, SOUTH)
else if (direct & WEST)
if (step(src, SOUTH) && moving_diagonally)
first_step_dir = SOUTH
moving_diagonally = SECOND_DIAG_STEP
. = step(src, WEST)
else if (moving_diagonally && step(src, WEST))
first_step_dir = WEST
moving_diagonally = SECOND_DIAG_STEP
. = step(src, SOUTH)
if(moving_diagonally == SECOND_DIAG_STEP)
if(!.)
setDir(first_step_dir)
else if (!inertia_moving)
inertia_next_move = world.time + inertia_move_delay
newtonian_move(direct)
moving_diagonally = 0
return
if(!loc || (loc == oldloc && oldloc != newloc))
last_move = NONE
return
if(.)
last_move = direct
setDir(direct)
if(has_buckled_mobs() && !handle_buckled_mob_movement(loc,direct)) //movement failed due to buckled mob(s)
return FALSE
if(pulling && pulling == pullee) //we were pulling a thing and didn't lose it during our move.
if(pulling.anchored)
stop_pulling()
else
var/pull_dir = get_dir(src, pulling)
//puller and pullee more than one tile away or in diagonal position
if(get_dist(src, pulling) > 1 || (moving_diagonally != SECOND_DIAG_STEP && ((pull_dir - 1) & pull_dir)))
pulling.Move(T, get_dir(pulling, T)) //the pullee tries to reach our previous position
if(pulling && get_dist(src, pulling) > 1) //the pullee couldn't keep up
stop_pulling()
if(pulledby && moving_diagonally != FIRST_DIAG_STEP && get_dist(src, pulledby) > 1)//separated from our puller and not in the middle of a diagonal move.
pulledby.stop_pulling()
Moved(oldloc, direct)
/atom/movable/proc/handle_buckled_mob_movement(newloc,direct)
for(var/m in buckled_mobs)
var/mob/living/buckled_mob = m
if(!buckled_mob.Move(newloc, direct))
forceMove(buckled_mob.loc)
last_move = buckled_mob.last_move
inertia_dir = last_move
buckled_mob.inertia_dir = last_move
return FALSE
return TRUE
//Called after a successful Move(). By this point, we've already moved
/atom/movable/proc/Moved(atom/OldLoc, Dir, Forced = FALSE)
SEND_SIGNAL(src, COMSIG_MOVABLE_MOVED, OldLoc, Dir, Forced)
if (!inertia_moving)
inertia_next_move = world.time + inertia_move_delay
newtonian_move(Dir)
if (length(client_mobs_in_contents))
update_parallax_contents()
return TRUE
// Make sure you know what you're doing if you call this, this is intended to only be called by byond directly.
// You probably want CanPass()
/atom/movable/Cross(atom/movable/AM)
. = TRUE
SEND_SIGNAL(src, COMSIG_MOVABLE_CROSS, AM)
return CanPass(AM, AM.loc, TRUE)
//oldloc = old location on atom, inserted when forceMove is called and ONLY when forceMove is called!
/atom/movable/Crossed(atom/movable/AM, oldloc)
SEND_SIGNAL(src, COMSIG_MOVABLE_CROSSED, AM)
/atom/movable/Uncross(atom/movable/AM, atom/newloc)
. = ..()
if(SEND_SIGNAL(src, COMSIG_MOVABLE_UNCROSS, AM) & COMPONENT_MOVABLE_BLOCK_UNCROSS)
return FALSE
if(isturf(newloc) && !CheckExit(AM, newloc))
return FALSE
/atom/movable/Uncrossed(atom/movable/AM)
SEND_SIGNAL(src, COMSIG_MOVABLE_UNCROSSED, AM)
/atom/movable/Bump(atom/A)
if(!A)
CRASH("Bump was called with no argument.")
SEND_SIGNAL(src, COMSIG_MOVABLE_BUMP, A)
. = ..()
if(!QDELETED(throwing))
throwing.hit_atom(A)
. = TRUE
if(QDELETED(A))
return
A.Bumped(src)
/atom/movable/proc/onTransitZ(old_z,new_z)
SEND_SIGNAL(src, COMSIG_MOVABLE_Z_CHANGED, old_z, new_z)
for (var/item in src) // Notify contents of Z-transition. This can be overridden IF we know the items contents do not care.
var/atom/movable/AM = item
AM.onTransitZ(old_z,new_z)
/atom/movable/proc/setMovetype(newval)
movement_type = newval
///////////// FORCED MOVEMENT /////////////
/atom/movable/proc/forceMove(atom/destination)
. = FALSE
if(destination)
. = doMove(destination)
else
CRASH("No valid destination passed into forceMove")
/atom/movable/proc/moveToNullspace()
return doMove(null)
/atom/movable/proc/doMove(atom/destination)
. = FALSE
if(destination)
if(pulledby)
pulledby.stop_pulling()
var/atom/oldloc = loc
var/same_loc = oldloc == destination
var/area/old_area = get_area(oldloc)
var/area/destarea = get_area(destination)
loc = destination
moving_diagonally = 0
if(!same_loc)
if(oldloc)
oldloc.Exited(src, destination)
if(old_area && old_area != destarea)
old_area.Exited(src, destination)
for(var/atom/movable/AM in oldloc)
AM.Uncrossed(src)
var/turf/oldturf = get_turf(oldloc)
var/turf/destturf = get_turf(destination)
var/old_z = (oldturf ? oldturf.z : null)
var/dest_z = (destturf ? destturf.z : null)
if (old_z != dest_z)
onTransitZ(old_z, dest_z)
destination.Entered(src, oldloc)
if(destarea && old_area != destarea)
destarea.Entered(src, oldloc)
for(var/atom/movable/AM in destination)
if(AM == src)
continue
AM.Crossed(src, oldloc)
Moved(oldloc, NONE, TRUE)
. = TRUE
//If no destination, move the atom into nullspace (don't do this unless you know what you're doing)
else
. = TRUE
if (loc)
var/atom/oldloc = loc
var/area/old_area = get_area(oldloc)
oldloc.Exited(src, null)
if(old_area)
old_area.Exited(src, null)
loc = null
//Called whenever an object moves and by mobs when they attempt to move themselves through space
//And when an object or action applies a force on src, see newtonian_move() below
//Return 0 to have src start/keep drifting in a no-grav area and 1 to stop/not start drifting
//Mobs should return 1 if they should be able to move of their own volition, see client/Move() in mob_movement.dm
//movement_dir == 0 when stopping or any dir when trying to move
/atom/movable/proc/Process_Spacemove(movement_dir = 0)
if(has_gravity(src))
return 1
if(pulledby)
return 1
if(throwing)
return 1
if(!isturf(loc))
return 1
if(locate(/obj/structure/lattice) in range(1, get_turf(src))) //Not realistic but makes pushing things in space easier
return 1
return 0
/atom/movable/proc/newtonian_move(direction) //Only moves the object if it's under no gravity
if(!loc || Process_Spacemove(0))
inertia_dir = 0
return 0
inertia_dir = direction
if(!direction)
return 1
inertia_last_loc = loc
SSspacedrift.processing[src] = src
return 1
@@ -746,7 +746,7 @@
Mind.add_antag_datum(ninjadatum)
if(Ninja.mind != Mind) //something has gone wrong!
throw EXCEPTION("Ninja created with incorrect mind")
stack_trace("Ninja created with incorrect mind")
message_admins("[ADMIN_LOOKUPFLW(Ninja)] has been made into a ninja by dynamic.")
log_game("[key_name(Ninja)] was spawned as a ninja by dynamic.")
+1 -1
View File
@@ -54,6 +54,6 @@
return
var/mob/living/carbon/human/H = gangster_mind.current // we are sure the dude's human cause it's checked in attack()
H.silent = max(H.silent, 5)
H.Knockdown(100)
H.DefaultCombatKnockdown(100)
gangster_mind.add_antag_datum(/datum/antagonist/gang, gang)
return TRUE
+25 -4
View File
@@ -86,8 +86,10 @@ GLOBAL_LIST_EMPTY(objectives)
if(M)
. += M
/datum/objective/proc/find_target()
/datum/objective/proc/find_target(dupe_search_range, blacklist)
var/list/datum/mind/owners = get_owners()
if(!dupe_search_range)
dupe_search_range = get_owners()
var/list/possible_targets = list()
var/try_target_late_joiners = FALSE
for(var/I in owners)
@@ -96,7 +98,8 @@ GLOBAL_LIST_EMPTY(objectives)
try_target_late_joiners = TRUE
for(var/datum/mind/possible_target in get_crewmember_minds())
if(!(possible_target in owners) && ishuman(possible_target.current) && (possible_target.current.stat != DEAD) && is_unique_objective(possible_target))
possible_targets += possible_target
if(!(possible_target in blacklist))
possible_targets += possible_target
if(try_target_late_joiners)
var/list/all_possible_targets = possible_targets.Copy()
for(var/I in all_possible_targets)
@@ -1075,7 +1078,7 @@ GLOBAL_LIST_EMPTY(cult_contraband)
var/mob/living/carbon/human/H = owner
H.equip_in_one_of_slots(I, list("backpack" = SLOT_IN_BACKPACK))
hoarded_item = I
GLOBAL_LIST_EMPTY(possible_sabotages)
@@ -1092,7 +1095,7 @@ GLOBAL_LIST_EMPTY(possible_sabotages)
if(!GLOB.possible_sabotages.len)//Only need to fill the list when it's needed.
for(var/I in subtypesof(/datum/sabotage_objective))
new I
/datum/objective/sabotage/find_target()
var/list/datum/mind/owners = get_owners()
var/approved_targets = list()
@@ -1155,3 +1158,21 @@ GLOBAL_LIST_EMPTY(possible_sabotages)
/datum/objective/flavor/wizard
flavor_file = "strings/flavor_objectives/wizard.txt"
/datum/objective/contract
var/payout = 0
var/payout_bonus = 0
var/area/dropoff = null
/datum/objective/contract/proc/generate_dropoff() // Generate a random valid area on the station that the dropoff will happen.
var/found = FALSE
while(!found)
var/area/dropoff_area = pick(GLOB.sortedAreas)
if(dropoff_area && is_station_level(dropoff_area.z) && !dropoff_area.outdoors && !istype(dropoff_area, /area/shuttle/))
dropoff = dropoff_area
found = TRUE
/datum/objective/contract/proc/dropoff_check(mob/user, mob/target) // Check if both the contractor and contract target are at the dropoff point.
var/area/user_area = get_area(user)
var/area/target_area = get_area(target)
return (istype(user_area, dropoff) && istype(target_area, dropoff))
+4 -4
View File
@@ -23,18 +23,18 @@
START_PROCESSING(SSprocessing, src)
/datum/sabotage_objective/processing/proc/check_condition_processing()
return 100
return 1
/datum/sabotage_objective/processing/process()
check_condition_processing()
if(won >= 100)
if(won >= 1)
STOP_PROCESSING(SSprocessing,src)
/datum/sabotage_objective/processing/check_conditions()
return won
/datum/sabotage_objective/processing/power_sink
name = "Drain at least 1 gigajoule of power using a power sink."
name = "Drain at least 100 megajoules of power using a power sink."
sabotage_type = "powersink"
special_equipment = list(/obj/item/sbeacondrop/powersink)
var/sink_found = FALSE
@@ -47,7 +47,7 @@
for(var/datum/powernet/PN in GLOB.powernets)
for(var/obj/item/powersink/sink in PN.nodes)
sink_found_this_time = TRUE
won = max(won,sink.power_drained/1e9)
won = max(won,sink.power_drained/1e8)
sink_found = sink_found_this_time
count = 0
return FALSE
+1 -1
View File
@@ -185,7 +185,7 @@ Class Procs:
A.forceMove(T)
if(isliving(A))
var/mob/living/L = A
L.update_canmove()
L.update_mobility()
if(occupant)
SEND_SIGNAL(src, COMSIG_MACHINE_EJECT_OCCUPANT, occupant)
occupant = null
+1 -1
View File
@@ -140,7 +140,7 @@
/obj/machinery/autolathe/proc/AfterMaterialInsert(obj/item/item_inserted, id_inserted, amount_inserted)
if(istype(item_inserted, /obj/item/stack/ore/bluespace_crystal))
use_power(MINERAL_MATERIAL_AMOUNT / 10)
else if(item_inserted.custom_materials?.len && item_inserted.custom_materials[getmaterialref(/datum/material/glass)])
else if(item_inserted.custom_materials?.len && item_inserted.custom_materials[SSmaterials.GetMaterialRef(/datum/material/glass)])
flick("autolathe_r",src)//plays glass insertion animation by default otherwise
else
flick("autolathe_o",src)//plays metal insertion animation
+1 -1
View File
@@ -18,7 +18,7 @@
if(!charging)
return
. += image(charging.icon, charging.icon_state)
. += mutable_appearance(charging.icon, charging.icon_state)
. += "ccharger-on"
if(!(stat & (BROKEN|NOPOWER)))
var/newlevel = round(charging.percent() * 4 / 100)
+7 -7
View File
@@ -491,29 +491,29 @@
/obj/machinery/clonepod/update_overlays()
. = ..()
if(mess)
var/image/gib1 = image(CRYOMOBS, "gibup")
var/image/gib2 = image(CRYOMOBS, "gibdown")
var/mutable_appearance/gib1 = mutable_appearance(CRYOMOBS, "gibup")
var/mutable_appearance/gib2 = mutable_appearance(CRYOMOBS, "gibdown")
gib1.pixel_y = 27 + round(sin(world.time) * 3)
gib1.pixel_x = round(sin(world.time * 3))
gib2.pixel_y = 27 + round(cos(world.time) * 3)
gib2.pixel_x = round(cos(world.time * 3))
. += gib2
. += gib1
. += "cover-on"
else if(occupant)
var/image/occupant_overlay
var/mutable_appearance/occupant_overlay
var/completion = (flesh_number - unattached_flesh.len) / flesh_number
if(unattached_flesh.len <= 0)
occupant_overlay = image(occupant.icon, occupant.icon_state)
occupant_overlay = mutable_appearance(occupant.icon, occupant.icon_state)
occupant_overlay.copy_overlays(occupant)
. += "cover-on"
else
occupant_overlay = image(CRYOMOBS, "clone_meat")
occupant_overlay = mutable_appearance(CRYOMOBS, "clone_meat")
var/matrix/tform = matrix()
tform.Scale(completion)
tform.Turn(cos(world.time * 2) * 3)
occupant_overlay.transform = tform
occupant_overlay.appearance_flags = 0
occupant_overlay.appearance_flags = NONE
occupant_overlay.dir = SOUTH
occupant_overlay.pixel_y = 27 + round(sin(world.time) * 3)
@@ -217,7 +217,7 @@
M.vomit(10, distance = 5)
if(ORION_TRAIL_FLUX)
if(prob(75))
M.Knockdown(60)
M.DefaultCombatKnockdown(60)
say("A sudden gust of powerful wind slams [M] into the floor!")
M.take_bodypart_damage(25)
playsound(loc, 'sound/weapons/genhit.ogg', 100, 1)
+10 -5
View File
@@ -15,6 +15,7 @@
var/message_cooldown = 0
var/ai_message_cooldown = 0
var/tmp_alertlevel = 0
var/static/security_level_cd // used to stop mass spam.
var/const/STATE_DEFAULT = 1
var/const/STATE_CALLSHUTTLE = 2
var/const/STATE_CANCELSHUTTLE = 3
@@ -94,16 +95,18 @@
I = pda.id
if (I && istype(I))
if(ACCESS_CAPTAIN in I.access)
if(security_level_cd > world.time)
to_chat(usr, "<span class='warning'>Security level protocols are currently on cooldown. Please stand by.</span>")
return
var/old_level = GLOB.security_level
if(!tmp_alertlevel)
tmp_alertlevel = SEC_LEVEL_GREEN
if(tmp_alertlevel < SEC_LEVEL_GREEN)
tmp_alertlevel = SEC_LEVEL_GREEN
if(tmp_alertlevel == SEC_LEVEL_BLUE)
tmp_alertlevel = SEC_LEVEL_BLUE
if(tmp_alertlevel > SEC_LEVEL_AMBER)
tmp_alertlevel = SEC_LEVEL_AMBER //Cannot engage delta with this
set_security_level(tmp_alertlevel)
security_level_cd = world.time + 15 SECONDS
if(GLOB.security_level != old_level)
to_chat(usr, "<span class='notice'>Authorization confirmed. Modifying security level.</span>")
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
@@ -376,19 +379,21 @@
if("ai-announce")
make_announcement(usr, 1)
if("ai-securitylevel")
if(security_level_cd > world.time)
to_chat(usr, "<span class='warning'>Security level protocols are currently on cooldown. Please stand by.</span>")
return
tmp_alertlevel = text2num( href_list["newalertlevel"] )
if(!tmp_alertlevel)
tmp_alertlevel = 0
tmp_alertlevel = SEC_LEVEL_GREEN
var/old_level = GLOB.security_level
if(!tmp_alertlevel)
tmp_alertlevel = SEC_LEVEL_GREEN
if(tmp_alertlevel < SEC_LEVEL_GREEN)
tmp_alertlevel = SEC_LEVEL_GREEN
if(tmp_alertlevel == SEC_LEVEL_BLUE)
tmp_alertlevel = SEC_LEVEL_BLUE
if(tmp_alertlevel > SEC_LEVEL_AMBER)
tmp_alertlevel = SEC_LEVEL_AMBER //Cannot engage delta with this
set_security_level(tmp_alertlevel)
security_level_cd = world.time + 15 SECONDS
if(GLOB.security_level != old_level)
//Only notify people if an actual change happened
var/security_level = get_security_level()
+9 -10
View File
@@ -37,12 +37,11 @@
dat += "[R.name] |"
if(R.stat)
dat += " Not Responding |"
else if (!R.canmove)
else if(R.locked_down)
dat += " Locked Down |"
else
dat += " Operating Normally |"
if (!R.canmove)
else if(R.cell)
if(R.cell)
dat += " Battery Installed ([R.cell.charge]/[R.cell.maxcharge]) |"
else
dat += " No Cell Installed |"
@@ -62,7 +61,7 @@
dat += "<A href='?src=[REF(src)];magbot=[REF(R)]'>(<font color=blue><i>Hack</i></font>)</A> "
else if(IsAdminGhost(user) && !R.emagged)
dat += "<A href='?src=[REF(src)];magbot=[REF(R)]'>(<font color=blue><i>Hack</i></font>)</A> "
dat += "<A href='?src=[REF(src)];stopbot=[REF(R)]'>(<font color=green><i>[R.canmove ? "Lockdown" : "Release"]</i></font>)</A> "
dat += "<A href='?src=[REF(src)];stopbot=[REF(R)]'>(<font color=green><i>[R.locked_down? "Lockdown" : "Release"]</i></font>)</A> "
dat += "<A href='?src=[REF(src)];killbot=[REF(R)]'>(<font color=red><i>Destroy</i></font>)</A>"
dat += "<BR>"
@@ -116,14 +115,14 @@
if(src.allowed(usr))
var/mob/living/silicon/robot/R = locate(href_list["stopbot"]) in GLOB.silicon_mobs
if(can_control(usr, R))
var/choice = input("Are you certain you wish to [R.canmove ? "lock down" : "release"] [R.name]?") in list("Confirm", "Abort")
var/choice = input("Are you certain you wish to [R.locked_down? "lock down" : "release"] [R.name]?") in list("Confirm", "Abort")
if(choice == "Confirm" && can_control(usr, R) && !..())
message_admins("<span class='notice'>[ADMIN_LOOKUPFLW(usr)] [R.canmove ? "locked down" : "released"] [key_name(R, R.client)][ADMIN_LOOKUPFLW(R)]!</span>")
log_game("[key_name(usr)] [R.canmove ? "locked down" : "released"] [key_name(R)]!")
R.SetLockdown(!R.lockcharge)
to_chat(R, "[!R.lockcharge ? "<span class='notice'>Your lockdown has been lifted!" : "<span class='alert'>You have been locked down!"]</span>")
message_admins("<span class='notice'>[ADMIN_LOOKUPFLW(usr)] [R.locked_down? "locked down" : "released"] [key_name(R, R.client)][ADMIN_LOOKUPFLW(R)]!</span>")
log_game("[key_name(usr)] [R.locked_down? "locked down" : "released"] [key_name(R)]!")
R.SetLockdown(!R.locked_down)
to_chat(R, "[!R.locked_down ? "<span class='notice'>Your lockdown has been lifted!" : "<span class='alert'>You have been locked down!"]</span>")
if(R.connected_ai)
to_chat(R.connected_ai, "[!R.lockcharge ? "<span class='notice'>NOTICE - Cyborg lockdown lifted" : "<span class='alert'>ALERT - Cyborg lockdown detected"]: <a href='?src=[REF(R.connected_ai)];track=[html_encode(R.name)]'>[R.name]</a></span><br>")
to_chat(R.connected_ai, "[!R.locked_down ? "<span class='notice'>NOTICE - Cyborg lockdown lifted" : "<span class='alert'>ALERT - Cyborg lockdown detected"]: <a href='?src=[REF(R.connected_ai)];track=[html_encode(R.name)]'>[R.name]</a></span><br>")
else
to_chat(usr, "<span class='danger'>Access Denied.</span>")
+21 -13
View File
@@ -287,6 +287,7 @@
#define CRYO_PRESERVE 1
#define CRYO_OBJECTIVE 2
#define CRYO_IGNORE 3
#define CRYO_DESTROY_LATER 4
/obj/machinery/cryopod/proc/should_preserve_item(obj/item/I)
for(var/datum/objective_item/steal/T in control_computer.theft_cache)
@@ -308,8 +309,8 @@
if(iscyborg(mob_occupant))
var/mob/living/silicon/robot/R = mob_occupant
if(R.mmi?.brain)
cryo_items[R.mmi] = CRYO_IGNORE
cryo_items[R.mmi.brain] = CRYO_IGNORE
cryo_items[R.mmi] = CRYO_DESTROY_LATER
cryo_items[R.mmi.brain] = CRYO_DESTROY_LATER
for(var/obj/item/I in R.module) // the tools the borg has; metal, glass, guns etc
for(var/obj/item/O in I) // the things inside the tools, if anything; mainly for janiborg trash bags
cryo_items[O] = should_preserve_item(O)
@@ -318,7 +319,7 @@
//Drop all items into the pod.
for(var/obj/item/I in mob_occupant)
if(cryo_items[I] == CRYO_IGNORE)
if(cryo_items[I] == CRYO_IGNORE || cryo_items[I] ==CRYO_DESTROY_LATER)
continue
cryo_items[I] = should_preserve_item(I)
mob_occupant.transferItemToLoc(I, src, TRUE)
@@ -334,17 +335,19 @@
if(QDELETED(I)) //edge cases and DROPDEL.
continue
var/preserve = cryo_items[I]
if(preserve == CRYO_IGNORE)
if(preserve == CRYO_DESTROY_LATER)
continue
else if(preserve == CRYO_DESTROY)
qdel(I)
else if(control_computer?.allow_items)
control_computer.frozen_items += I
if(preserve == CRYO_OBJECTIVE)
control_computer.objective_items += I
I.moveToNullspace()
else
I.forceMove(loc)
if(preserve != CRYO_IGNORE)
if(preserve == CRYO_DESTROY)
qdel(I)
else if(control_computer?.allow_items)
control_computer.frozen_items += I
if(preserve == CRYO_OBJECTIVE)
control_computer.objective_items += I
I.moveToNullspace()
else
I.forceMove(loc)
cryo_items -= I
//Update any existing objectives involving this mob.
for(var/datum/objective/O in GLOB.objectives)
@@ -405,6 +408,10 @@
mob_occupant.ghostize(FALSE, penalize = TRUE)
QDEL_NULL(occupant)
for(var/I in cryo_items) //only "CRYO_DESTROY_LATER" atoms are left)
var/atom/A = I
if(!QDELETED(A))
qdel(A)
open_machine()
name = initial(name)
@@ -412,6 +419,7 @@
#undef CRYO_PRESERVE
#undef CRYO_OBJECTIVE
#undef CRYO_IGNORE
#undef CRYO_DESTROY_LATER
/obj/machinery/cryopod/MouseDrop_T(mob/living/target, mob/user)
if(!istype(target) || user.incapacitated() || !target.Adjacent(user) || !Adjacent(user) || !ismob(target) || (!ishuman(user) && !iscyborg(user)) || !istype(user.loc, /turf) || target.buckled)
+1 -1
View File
@@ -433,5 +433,5 @@
. = ..()
if(active)
for(var/mob/living/M in rangers)
if(prob(5+(allowed(M)*4)) && M.canmove)
if(prob(5+(allowed(M)*4)) && CHECK_MOBILITY(M, MOBILITY_MOVE))
dance(M)
+3 -3
View File
@@ -428,7 +428,7 @@
else
return FALSE
/obj/machinery/door/airlock/update_icon_state(state=0, override=0)
/obj/machinery/door/airlock/update_icon(state=0, override=0)
if(operating && !override)
return
switch(state)
@@ -769,7 +769,7 @@
if(!istype(H.head, /obj/item/clothing/head/helmet))
H.visible_message("<span class='danger'>[user] headbutts the airlock.</span>", \
"<span class='userdanger'>You headbutt the airlock!</span>")
H.Knockdown(100)
H.DefaultCombatKnockdown(100)
H.apply_damage(10, BRUTE, BODY_ZONE_HEAD)
else
visible_message("<span class='danger'>[user] headbutts the airlock. Good thing [user.p_theyre()] wearing a helmet.</span>")
@@ -1033,7 +1033,7 @@
if(!I.use_tool(src, user, 150, volume=50))
to_chat(user, "<span class='warning'>You slip and [charge] detonates!</span>")
charge.ex_act(EXPLODE_DEVASTATE)
user.Knockdown(60)
user.DefaultCombatKnockdown(60)
return
user.visible_message("<span class='notice'>[user] removes [charge] from [src].</span>", \
"<span class='notice'>You gently pry out [charge] from [src] and unhook its wires.</span>")
+1 -1
View File
@@ -508,7 +508,7 @@
throwtarget = get_edge_target_turf(src, get_dir(src, get_step_away(L, src)))
SEND_SOUND(L, sound(pick('sound/hallucinations/turn_around1.ogg','sound/hallucinations/turn_around2.ogg'),0,1,50))
flash_color(L, flash_color="#960000", flash_time=20)
L.Knockdown(40)
L.DefaultCombatKnockdown(40)
L.throw_at(throwtarget, 5, 1)
return 0
+2 -2
View File
@@ -319,10 +319,10 @@
else if(ishuman(L)) //For humans
L.adjustBruteLoss(DOOR_CRUSH_DAMAGE)
L.emote("scream")
L.Knockdown(100)
L.DefaultCombatKnockdown(100)
else if(ismonkey(L)) //For monkeys
L.adjustBruteLoss(DOOR_CRUSH_DAMAGE)
L.Knockdown(100)
L.DefaultCombatKnockdown(100)
else //for simple_animals & borgs
L.adjustBruteLoss(DOOR_CRUSH_DAMAGE)
var/turf/location = get_turf(src)
+1 -1
View File
@@ -115,7 +115,7 @@
continue
if(L.flash_act(affect_silicon = 1))
L.Knockdown(strength)
L.DefaultCombatKnockdown(strength)
flashed = TRUE
if(flashed)
+2 -1
View File
@@ -138,7 +138,8 @@
limb = new buildpath(loc)
if(selected_category=="human" || selected_category=="lizard") //Species with greyscale parts should be included here
limb.icon = 'icons/mob/human_parts_greyscale.dmi'
limb.should_draw_greyscale = TRUE
limb.base_bp_icon = DEFAULT_BODYPART_ICON_ORGANIC
limb.color_src = MUTCOLORS
else
limb.icon = 'icons/mob/human_parts.dmi'
// Set this limb up using the specias name and body zone

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