Merge branch 'master' of https://github.com/Citadel-Station-13/Citadel-Station-13 into contracties
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -208,6 +212,16 @@
|
||||
#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))
|
||||
|
||||
@@ -233,6 +247,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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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\
|
||||
@@ -137,6 +143,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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -165,7 +165,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"),
|
||||
@@ -356,7 +356,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 +384,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 +394,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)
|
||||
|
||||
@@ -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
|
||||
)
|
||||
))
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -6,7 +6,7 @@ SUBSYSTEM_DEF(garbage)
|
||||
runlevels = RUNLEVELS_DEFAULT | RUNLEVEL_LOBBY
|
||||
init_order = INIT_ORDER_GARBAGE
|
||||
|
||||
var/list/collection_timeout = list(0, 2 MINUTES, 10 SECONDS) // deciseconds to wait before moving something up in the queue to the next level
|
||||
var/list/collection_timeout = list(15 SECONDS, 30 SECONDS) // deciseconds to wait before moving something up in the queue to the next level
|
||||
|
||||
//Stat tracking
|
||||
var/delslasttick = 0 // number of del()'s we've done this tick
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
+14
-9
@@ -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)
|
||||
@@ -430,7 +434,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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -59,4 +59,4 @@
|
||||
"<span class='userdanger'>You slide on [A]!</span>")
|
||||
|
||||
cooldown = world.time
|
||||
H.Knockdown(60)
|
||||
H.DefaultCombatKnockdown(60)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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//
|
||||
//////////////////
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>")
|
||||
|
||||
|
||||
@@ -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])
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
return FALSE
|
||||
|
||||
|
||||
if(!(type in D.viable_mobtypes))
|
||||
if(!D.viable_mobtypes[type])
|
||||
return FALSE
|
||||
|
||||
return TRUE
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
var/stage_prob = 4
|
||||
|
||||
//Other
|
||||
var/list/viable_mobtypes = list() //typepaths of viable mobs
|
||||
var/list/viable_mobtypes = list() //typecache of viable mobs
|
||||
var/mob/living/carbon/affected_mob = null
|
||||
var/list/cures = list() //list of cures if the disease has the CURABLE flag, these are reagent ids
|
||||
var/infectivity = 65
|
||||
@@ -34,6 +34,10 @@
|
||||
var/process_dead = FALSE //if this ticks while the host is dead
|
||||
var/copy_type = null //if this is null, copies will use the type of the instance being copied
|
||||
|
||||
/datum/disease/New(make_typecache = TRUE)
|
||||
if(make_typecache && length(viable_mobtypes))
|
||||
viable_mobtypes = typecacheof(viable_mobtypes)
|
||||
|
||||
/datum/disease/Destroy()
|
||||
. = ..()
|
||||
if(affected_mob)
|
||||
|
||||
@@ -80,7 +80,8 @@
|
||||
|
||||
*/
|
||||
|
||||
/datum/disease/advance/New()
|
||||
/datum/disease/advance/New(make_typecache = TRUE)
|
||||
..()
|
||||
Refresh()
|
||||
|
||||
/datum/disease/advance/Destroy()
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
/datum/disease/advance/cold
|
||||
copy_type = /datum/disease/advance
|
||||
|
||||
/datum/disease/advance/cold/New()
|
||||
/datum/disease/advance/cold/New(make_typecache = TRUE)
|
||||
name = "Cold"
|
||||
symptoms = list(new/datum/symptom/sneeze)
|
||||
..()
|
||||
@@ -11,7 +11,7 @@
|
||||
/datum/disease/advance/flu
|
||||
copy_type = /datum/disease/advance
|
||||
|
||||
/datum/disease/advance/flu/New()
|
||||
/datum/disease/advance/flu/New(make_typecache = TRUE)
|
||||
name = "Flu"
|
||||
symptoms = list(new/datum/symptom/cough)
|
||||
..()
|
||||
@@ -21,7 +21,7 @@
|
||||
name = "Experimental Disease"
|
||||
copy_type = /datum/disease/advance
|
||||
|
||||
/datum/disease/advance/random/New(max_symptoms, max_level = 8)
|
||||
/datum/disease/advance/random/New(make_typecache = TRUE, max_symptoms, max_level = 8)
|
||||
if(!max_symptoms)
|
||||
max_symptoms = rand(1, VIRUS_SYMPTOM_LIMIT)
|
||||
var/list/datum/symptom/possible_symptoms = list()
|
||||
@@ -37,6 +37,6 @@
|
||||
if(chosen_symptom)
|
||||
var/datum/symptom/S = new chosen_symptom
|
||||
symptoms += S
|
||||
Refresh()
|
||||
|
||||
name = "Sample #[rand(1,10000)]"
|
||||
name = "Sample #[rand(1,10000)]"
|
||||
..()
|
||||
@@ -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
|
||||
|
||||
@@ -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>")
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
stage_prob = 2
|
||||
var/restcure = 0
|
||||
|
||||
/datum/disease/dna_retrovirus/New()
|
||||
/datum/disease/dna_retrovirus/New(make_typecache = TRUE)
|
||||
..()
|
||||
agent = "Virus class [pick("A","B","C","D","E","F")][pick("A","B","C","D","E","F")]-[rand(50,300)]"
|
||||
if(prob(40))
|
||||
|
||||
@@ -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>")
|
||||
@@ -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>")
|
||||
|
||||
@@ -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>")
|
||||
@@ -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>")
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#define SIDE_KICK_COMBO "DH"
|
||||
#define REPULSE_PUNCH_COMBO "HDHD"
|
||||
#define SHOULDER_FLIP_COMBO "GHDGHH"
|
||||
#define FOOT_SMASH_COMBO "HH"
|
||||
#define SIDE_KICK_COMBO "skick"
|
||||
#define DEFT_SWITCH_COMBO "deft"
|
||||
|
||||
/datum/martial_art/the_rising_bass
|
||||
name = "The Rising Bass"
|
||||
@@ -8,7 +10,7 @@
|
||||
dodge_chance = 100
|
||||
allow_temp_override = FALSE
|
||||
help_verb = /mob/living/carbon/human/proc/rising_bass_help
|
||||
var/datum/action/risingbassmove/repulsepunch = new/datum/action/risingbassmove/repulsepunch()
|
||||
var/datum/action/risingbassmove/sidekick = new/datum/action/risingbassmove/sidekick()
|
||||
var/datum/action/risingbassmove/deftswitch = new/datum/action/risingbassmove/deftswitch()
|
||||
var/repulsecool = 0
|
||||
|
||||
@@ -21,7 +23,7 @@
|
||||
streak = ""
|
||||
shoulderFlip(A,D)
|
||||
return 1
|
||||
if(findtext(streak,"rplse"))
|
||||
if(findtext(streak,REPULSE_PUNCH_COMBO))
|
||||
streak = ""
|
||||
repulsePunch(A,D)
|
||||
return 1
|
||||
@@ -29,7 +31,7 @@
|
||||
streak = ""
|
||||
footSmash(A,D)
|
||||
return 1
|
||||
if(findtext(streak,"deft"))
|
||||
if(findtext(streak,DEFT_SWITCH_COMBO))
|
||||
streak = ""
|
||||
deftSwitch(A,D)
|
||||
return 1
|
||||
@@ -58,42 +60,46 @@
|
||||
to_chat(H,"<span class='danger'>You get ready to use the [name] maneuver!</span>")
|
||||
H.mind.martial_art.streak = "[movestreak]"
|
||||
|
||||
/datum/action/risingbassmove/repulsepunch
|
||||
name = "Repulse Punch"
|
||||
button_icon_state = "repulsepunch"
|
||||
movestreak = "rplse"
|
||||
/datum/action/risingbassmove/sidekick
|
||||
name = "Side Kick"
|
||||
button_icon_state = "sidekick"
|
||||
movestreak = "skick"
|
||||
|
||||
/datum/action/risingbassmove/deftswitch
|
||||
name = "Deft Switch"
|
||||
button_icon_state = "deftswitch"
|
||||
movestreak = "deft"
|
||||
|
||||
/datum/martial_art/the_rising_bass/proc/checkfordensity(turf/T,mob/M)
|
||||
if (T.density)
|
||||
return FALSE
|
||||
for(var/obj/O in T)
|
||||
if(!O.CanPass(M,T))
|
||||
return FALSE
|
||||
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)
|
||||
var/turf/H = get_step(D, A.dir & (NORTH | SOUTH) ? pick(EAST, WEST) : pick(NORTH, SOUTH))
|
||||
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)
|
||||
var/turf/K = get_step(D, oppdir)
|
||||
A.do_attack_animation(D, ATTACK_EFFECT_KICK)
|
||||
D.visible_message("<span class='warning'>[A] kicks [D] in the side, sliding them over!</span>", \
|
||||
"<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)
|
||||
var/L = H
|
||||
for(var/obj/i in H.contents)
|
||||
if(!istype(i,/mob) && i.density == 1)
|
||||
L = D.loc
|
||||
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)")
|
||||
return 1
|
||||
return TRUE
|
||||
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 = H
|
||||
for(var/obj/i in H.contents)
|
||||
if(!istype(i,/mob) && i.density == 1)//(i.anchored == 1 && i.density == 1) || istype(i,/obj/structure) || istype(i,/turf/closed)
|
||||
L = A.loc
|
||||
var/L = checkfordensity(H,D) ? H : A.loc
|
||||
A.do_attack_animation(D, ATTACK_EFFECT_PUNCH)
|
||||
D.visible_message("<span class='warning'>[A] flips [D] over their shoulder, slamming them into the ground!</span>", \
|
||||
"<span class='userdanger'>[A] flips you over their shoulder, slamming you into the ground!</span>")
|
||||
@@ -102,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 1
|
||||
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>")
|
||||
@@ -117,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 1
|
||||
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>")
|
||||
@@ -132,11 +138,11 @@
|
||||
D.apply_damage(5, BRUTE, pick(BODY_ZONE_L_LEG, BODY_ZONE_R_LEG))
|
||||
D.dropItemToGround(D.get_active_held_item())
|
||||
log_combat(A, D, "foot smashed (Rising Bass)")
|
||||
return 1
|
||||
return TRUE
|
||||
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))
|
||||
@@ -144,10 +150,10 @@
|
||||
D.visible_message("<span class='warning'>[A] slaps [D]'s hands, taking [G] from them!</span>", \
|
||||
"<span class='userdanger'>[A] slaps you, taking [G] from you!</span>")
|
||||
log_combat(A, D, "deft switched (Rising Bass)")
|
||||
return 1
|
||||
return TRUE
|
||||
else
|
||||
to_chat(A, "<i>[G] can't be taken out of [D]'s hands!</i>")
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
/datum/martial_art/the_rising_bass/disarm_act(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
add_to_streak("D",D)
|
||||
@@ -168,7 +174,7 @@
|
||||
return ..()
|
||||
|
||||
/datum/martial_art/the_rising_bass/add_to_streak(element,mob/living/carbon/human/D)
|
||||
if (streak == "deft" || streak == "rplse")
|
||||
if (streak == DEFT_SWITCH_COMBO || streak == SIDE_KICK_COMBO)
|
||||
return
|
||||
. = ..()
|
||||
|
||||
@@ -179,24 +185,24 @@
|
||||
|
||||
to_chat(usr, "<b><i>You retreat inward and recall the teachings of the Rising Bass...</i></b>")
|
||||
|
||||
to_chat(usr, "<span class='notice'>Side Kick</span>: Disarm Harm. Forces opponent to step to the side.")
|
||||
to_chat(usr, "<span class='notice'>Side Kick</span>: Forces opponent to step to the side.")
|
||||
to_chat(usr, "<span class='notice'>Shoulder Flip</span>: Grab Harm Disarm Grab Harm Harm. Flips opponent over your shoulder and stuns.")
|
||||
to_chat(usr, "<span class='notice'>Repulse Punch</span>: Grab Harm Grab Harm. Slams the opponent far away from you.")
|
||||
to_chat(usr, "<span class='notice'>Repulse Punch</span>: Harm Disarm Harm Disarm. Slams the opponent far away from you.")
|
||||
to_chat(usr, "<span class='notice'>Foot Smash</span>: Harm Harm. Stuns opponent, minor damage.")
|
||||
to_chat(usr, "<span class='notice'>Deft Switch</span>: Grab Disarm Disarm. Switches the opponent's held item for your own. Most useful with nothing in your hand.")
|
||||
to_chat(usr, "<span class='notice'>Deft Switch</span>: Switches the opponent's held item for your own. Most useful with nothing in your hand.")
|
||||
|
||||
/datum/martial_art/the_rising_bass/teach(mob/living/carbon/human/H, make_temporary = FALSE)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
deftswitch.Grant(H)
|
||||
repulsepunch.Grant(H)
|
||||
sidekick.Grant(H)
|
||||
ADD_TRAIT(H, TRAIT_NOGUNS, RISING_BASS_TRAIT)
|
||||
ADD_TRAIT(H, TRAIT_AUTO_CATCH_ITEM, RISING_BASS_TRAIT)
|
||||
|
||||
/datum/martial_art/the_rising_bass/on_remove(mob/living/carbon/human/H)
|
||||
. = ..()
|
||||
deftswitch.Remove(H)
|
||||
repulsepunch.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)
|
||||
|
||||
@@ -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>", \
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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."
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
@@ -211,7 +223,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 +570,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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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.")
|
||||
|
||||
@@ -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 = .
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
+8
-8
@@ -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,7 +913,7 @@ 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)
|
||||
|
||||
+2
-304
@@ -158,7 +158,7 @@
|
||||
grab_state = 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.
|
||||
|
||||
@@ -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.")
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -145,7 +145,7 @@
|
||||
if(5)
|
||||
dat += "<CENTER><B>Virus Database</B></CENTER>"
|
||||
for(var/Dt in typesof(/datum/disease/))
|
||||
var/datum/disease/Dis = new Dt(0)
|
||||
var/datum/disease/Dis = new Dt(FALSE)
|
||||
if(istype(Dis, /datum/disease/advance))
|
||||
continue // TODO (tm): Add advance diseases to the virus database which no one uses.
|
||||
if(!Dis.desc)
|
||||
@@ -248,7 +248,7 @@
|
||||
|
||||
else if(href_list["vir"])
|
||||
var/type = href_list["vir"]
|
||||
var/datum/disease/Dis = new type(0)
|
||||
var/datum/disease/Dis = new type(FALSE)
|
||||
var/AfS = ""
|
||||
for(var/mob/M in Dis.viable_mobtypes)
|
||||
AfS += " [initial(M.name)];"
|
||||
|
||||
@@ -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>")
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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>")
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -115,7 +115,7 @@
|
||||
continue
|
||||
|
||||
if(L.flash_act(affect_silicon = 1))
|
||||
L.Knockdown(strength)
|
||||
L.DefaultCombatKnockdown(strength)
|
||||
flashed = TRUE
|
||||
|
||||
if(flashed)
|
||||
|
||||
@@ -90,7 +90,8 @@ Buildable meters
|
||||
set name = "Flip Pipe"
|
||||
set src in view(1)
|
||||
|
||||
if ( usr.stat || usr.restrained() || !usr.canmove )
|
||||
var/mob/living/L = usr
|
||||
if(!istype(L) || !CHECK_MOBILITY(L, MOBILITY_USE))
|
||||
return
|
||||
|
||||
do_a_flip()
|
||||
|
||||
@@ -34,7 +34,8 @@
|
||||
/obj/machinery/pipedispenser/Topic(href, href_list)
|
||||
if(..())
|
||||
return 1
|
||||
if(!anchored|| !usr.canmove || usr.stat || usr.restrained() || !in_range(loc, usr))
|
||||
var/mob/living/L = usr
|
||||
if(!anchored || !istype(L) || !CHECK_MOBILITY(L, MOBILITY_USE))
|
||||
usr << browse(null, "window=pipedispenser")
|
||||
return 1
|
||||
usr.set_machine(src)
|
||||
@@ -93,14 +94,14 @@
|
||||
|
||||
|
||||
//Allow you to drag-drop disposal pipes and transit tubes into it
|
||||
/obj/machinery/pipedispenser/disposal/MouseDrop_T(obj/structure/pipe, mob/usr)
|
||||
if(!usr.canmove || usr.stat || usr.restrained())
|
||||
/obj/machinery/pipedispenser/disposal/MouseDrop_T(obj/structure/pipe, mob/living/user)
|
||||
if(!istype(user) || !CHECK_MOBILITY(user, MOBILITY_USE))
|
||||
return
|
||||
|
||||
if (!istype(pipe, /obj/structure/disposalconstruct) && !istype(pipe, /obj/structure/c_transit_tube) && !istype(pipe, /obj/structure/c_transit_tube_pod))
|
||||
return
|
||||
|
||||
if (get_dist(usr, src) > 1 || get_dist(src,pipe) > 1 )
|
||||
if (get_dist(user, src) > 1 || get_dist(src,pipe) > 1 )
|
||||
return
|
||||
|
||||
if (pipe.anchored)
|
||||
|
||||
@@ -705,7 +705,7 @@
|
||||
|
||||
/obj/machinery/porta_turret/syndicate/energy/pirate
|
||||
max_integrity = 260
|
||||
integrity_failure = 20
|
||||
integrity_failure = 0.08
|
||||
armor = list("melee" = 50, "bullet" = 30, "laser" = 30, "energy" = 30, "bomb" = 50, "bio" = 0, "rad" = 0, "fire" = 90, "acid" = 90)
|
||||
|
||||
|
||||
|
||||
@@ -35,8 +35,6 @@
|
||||
|
||||
signal.data["compression"] = 0
|
||||
signal.mark_done()
|
||||
if(signal.data["slow"] > 0)
|
||||
sleep(signal.data["slow"]) // simulate the network lag if necessary
|
||||
signal.broadcast()
|
||||
|
||||
/obj/machinery/telecomms/allinone/attackby(obj/item/P, mob/user, params)
|
||||
|
||||
@@ -41,9 +41,6 @@ GLOBAL_VAR_INIT(message_delay, 0) // To make sure restarting the recentmessages
|
||||
return
|
||||
GLOB.recentmessages.Add(signal_message)
|
||||
|
||||
if(signal.data["slow"] > 0)
|
||||
sleep(signal.data["slow"]) // simulate the network lag if necessary
|
||||
|
||||
signal.broadcast()
|
||||
|
||||
if(!GLOB.message_delay)
|
||||
|
||||
@@ -31,17 +31,10 @@
|
||||
if(relay_information(signal, /obj/machinery/telecomms/processor))
|
||||
return
|
||||
|
||||
// failed to send to a processor, relay information anyway
|
||||
signal.data["slow"] += rand(1, 5) // slow the signal down only slightly
|
||||
|
||||
// Try sending it!
|
||||
var/list/try_send = list(signal.server_type, /obj/machinery/telecomms/hub, /obj/machinery/telecomms/broadcaster)
|
||||
|
||||
var/i = 0
|
||||
for(var/send in try_send)
|
||||
if(i)
|
||||
signal.data["slow"] += rand(0, 1) // slow the signal down only slightly
|
||||
i++
|
||||
if(relay_information(signal, send))
|
||||
break
|
||||
|
||||
@@ -79,4 +72,4 @@
|
||||
/obj/machinery/telecomms/bus/preset_one/birdstation
|
||||
name = "Bus"
|
||||
autolinkers = list("processor1", "common")
|
||||
freq_listening = list()
|
||||
freq_listening = list()
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
if(istype(machine_from, /obj/machinery/telecomms/bus))
|
||||
relay_direct_information(signal, machine_from) // send the signal back to the machine
|
||||
else // no bus detected - send the signal to servers instead
|
||||
signal.data["slow"] += rand(5, 10) // slow the signal down
|
||||
relay_information(signal, signal.server_type)
|
||||
|
||||
//Preset Processors
|
||||
|
||||
@@ -39,11 +39,6 @@ GLOBAL_LIST_EMPTY(telecomms_list)
|
||||
return
|
||||
var/send_count = 0
|
||||
|
||||
// Apply some lag based on traffic rates
|
||||
var/netlag = round(traffic / 50)
|
||||
if(netlag > signal.data["slow"])
|
||||
signal.data["slow"] = netlag
|
||||
|
||||
// Loop through all linked machines and send the signal or copy.
|
||||
for(var/obj/machinery/telecomms/machine in links)
|
||||
if(filter && !istype( machine, filter ))
|
||||
|
||||
@@ -121,7 +121,7 @@
|
||||
return ..()
|
||||
|
||||
/obj/machinery/autoylathe/proc/AfterMaterialInsert(obj/item/item_inserted, id_inserted, amount_inserted)
|
||||
if(item_inserted.custom_materials?.len && item_inserted.custom_materials[getmaterialref(/datum/material/glass)])
|
||||
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
|
||||
|
||||
@@ -226,8 +226,7 @@
|
||||
return
|
||||
if(M.health > 0)
|
||||
M.adjustOxyLoss(-1)
|
||||
M.AdjustStun(-80)
|
||||
M.AdjustKnockdown(-80)
|
||||
M.AdjustAllImmobility(-80)
|
||||
M.AdjustUnconscious(-80)
|
||||
if(M.reagents.get_reagent_amount(/datum/reagent/medicine/epinephrine) < 5)
|
||||
M.reagents.add_reagent(/datum/reagent/medicine/epinephrine, 5)
|
||||
|
||||
@@ -177,7 +177,7 @@
|
||||
M.SetSleeping(0)
|
||||
M.stuttering += 20
|
||||
M.adjustEarDamage(0, 30)
|
||||
M.Knockdown(60)
|
||||
M.DefaultCombatKnockdown(60)
|
||||
if(prob(30))
|
||||
M.Stun(200)
|
||||
M.Unconscious(80)
|
||||
|
||||
@@ -755,7 +755,7 @@
|
||||
AI.cancel_camera()
|
||||
AI.controlled_mech = src
|
||||
AI.remote_control = src
|
||||
AI.canmove = 1 //Much easier than adding AI checks! Be sure to set this back to 0 if you decide to allow an AI to leave a mech somehow.
|
||||
AI.mobility_flags = MOBILITY_FLAGS_DEFAULT //Much easier than adding AI checks! Be sure to set this back to 0 if you decide to allow an AI to leave a mech somehow.
|
||||
AI.can_shunt = 0 //ONE AI ENTERS. NO AI LEAVES.
|
||||
to_chat(AI, AI.can_dominate_mechs ? "<span class='announce'>Takeover of [name] complete! You are now loaded onto the onboard computer. Do not attempt to leave the station sector!</span>" :\
|
||||
"<span class='notice'>You have been uploaded to a mech's onboard computer.</span>")
|
||||
@@ -927,7 +927,7 @@
|
||||
brainmob.forceMove(src) //should allow relaymove
|
||||
brainmob.reset_perspective(src)
|
||||
brainmob.remote_control = src
|
||||
brainmob.update_canmove()
|
||||
brainmob.update_mobility()
|
||||
brainmob.update_mouse_pointer()
|
||||
icon_state = initial(icon_state)
|
||||
update_icon()
|
||||
@@ -941,7 +941,6 @@
|
||||
/obj/mecha/container_resist(mob/living/user)
|
||||
go_out()
|
||||
|
||||
|
||||
/obj/mecha/Exited(atom/movable/M, atom/newloc)
|
||||
if(occupant && occupant == M) // The occupant exited the mech without calling go_out()
|
||||
go_out(TRUE, newloc)
|
||||
@@ -993,7 +992,7 @@
|
||||
L.reset_perspective()
|
||||
mmi.mecha = null
|
||||
mmi.update_icon()
|
||||
L.canmove = 0
|
||||
L.mobility_flags = NONE
|
||||
icon_state = initial(icon_state)+"-open"
|
||||
setDir(dir_in)
|
||||
|
||||
|
||||
@@ -36,8 +36,7 @@
|
||||
|
||||
//procs that handle the actual buckling and unbuckling
|
||||
/atom/movable/proc/buckle_mob(mob/living/M, force = FALSE, check_loc = TRUE)
|
||||
if(!buckled_mobs)
|
||||
buckled_mobs = list()
|
||||
LAZYINITLIST(buckled_mobs)
|
||||
|
||||
if(!istype(M))
|
||||
return FALSE
|
||||
@@ -66,7 +65,7 @@
|
||||
M.buckled = src
|
||||
M.setDir(dir)
|
||||
buckled_mobs |= M
|
||||
M.update_canmove()
|
||||
M.update_mobility()
|
||||
M.throw_alert("buckled", /obj/screen/alert/restrained/buckled)
|
||||
post_buckle_mob(M)
|
||||
|
||||
@@ -85,7 +84,7 @@
|
||||
. = buckled_mob
|
||||
buckled_mob.buckled = null
|
||||
buckled_mob.anchored = initial(buckled_mob.anchored)
|
||||
buckled_mob.update_canmove()
|
||||
buckled_mob.update_mobility()
|
||||
buckled_mob.clear_alert("buckled")
|
||||
buckled_mobs -= buckled_mob
|
||||
SEND_SIGNAL(src, COMSIG_MOVABLE_UNBUCKLE, buckled_mob, force)
|
||||
|
||||
@@ -113,7 +113,7 @@
|
||||
|
||||
/obj/effect/anomaly/grav/proc/gravShock(mob/living/A)
|
||||
if(boing && isliving(A) && !A.stat)
|
||||
A.Knockdown(40)
|
||||
A.DefaultCombatKnockdown(40)
|
||||
var/atom/target = get_edge_target_turf(A, get_dir(src, get_step_away(A, src)))
|
||||
A.throw_at(target, 5, 1)
|
||||
boing = 0
|
||||
|
||||
@@ -409,6 +409,21 @@
|
||||
desc = "A poster advertising a movie about some masked men."
|
||||
icon_state = "poster44"
|
||||
|
||||
/obj/structure/sign/poster/contraband/buzzfuzz
|
||||
name = "Buzz Fuzz"
|
||||
desc = "A poster advertising the newest drink \"Buzz Fuzz\" with its iconic slogan of ~A Hive of Flavour~."
|
||||
icon_state = "poster45"
|
||||
|
||||
/obj/structure/sign/poster/contraband/scum
|
||||
name = "Security are Scum"
|
||||
desc = "Anti-security propaganda. Features a human NanoTrasen security officer being shot in the head, with the words 'Scum' and a short inciteful manifesto. Used to anger security."
|
||||
icon_state = "poster46"
|
||||
|
||||
/obj/structure/sign/poster/contraband/syndicate_logo
|
||||
name = "Syndicate"
|
||||
desc = "A poster decipting a snake shaped into an ominous 'S'!"
|
||||
icon_state = "poster47"
|
||||
|
||||
/obj/structure/sign/poster/official
|
||||
poster_item_name = "motivational poster"
|
||||
poster_item_desc = "An official Nanotrasen-issued poster to foster a compliant and obedient workforce. It comes with state-of-the-art adhesive backing, for easy pinning to any vertical surface."
|
||||
@@ -595,4 +610,49 @@
|
||||
desc = "This informational poster teaches the viewer what carbon dioxide is."
|
||||
icon_state = "poster35_legit"
|
||||
|
||||
/obj/structure/sign/poster/official/spiderlings
|
||||
name = "Spiderlings"
|
||||
desc = "This poster informs the crew of the dangers of spiderlings."
|
||||
icon_state = "poster36_legit"
|
||||
|
||||
/obj/structure/sign/poster/official/duelshotgun
|
||||
name = "Cycler Shotgun Ad"
|
||||
desc = "A poster advertising an advanced dual magazine tubes shotgun, boasting about how easy it is to swap between the two tubes."
|
||||
icon_state = "poster37_legit"
|
||||
|
||||
/obj/structure/sign/poster/official/fashion
|
||||
name = "Fashion!"
|
||||
desc = "An advertisement for 'Fashion!', a popular fashion magazine, depicting a woman with a black dress with a golden trim, she also has a red poppy in her hair."
|
||||
icon_state = "poster38_legit"
|
||||
|
||||
/obj/structure/sign/poster/official/pda_ad600
|
||||
name = "NT PDA600 Ad"
|
||||
desc = "A poster advertising an old discounted Nanotrasen PDA. This is the old 600 model, it has a small screen and suffered from security and networking issues."
|
||||
icon_state = "poster39_legit"
|
||||
|
||||
/obj/structure/sign/poster/official/pda_ad800
|
||||
name = "NT PDA800 Ad"
|
||||
desc = "An advertisement on an old Nanotrasen PDA model. The 800 fixed a lot of security flaws that the 600 had; it also had large touchscreen and hot-swappable cartridges."
|
||||
icon_state = "poster40_legit"
|
||||
|
||||
/obj/structure/sign/poster/official/hydro_ad
|
||||
name = "Hydroponics Tray"
|
||||
desc = "An advertisement for hydroponics trays. Space Station 13's botanical department uses a slightly newer model, but the principles are the same. From left to right: Green means the plant is done, red means the plant is unhealthy, flashing red means pests or weeds, yellow means the plant needs nutriment and blue means the plant needs water."
|
||||
icon_state = "poster41_legit"
|
||||
|
||||
/obj/structure/sign/poster/official/medical_green_cross
|
||||
name = "Medical"
|
||||
desc = "A green cross, one of the interplanetary symbol of health and aid. It has a bunch of common languages at the top with translations." // Didn't the American Heart Foundation trademark red crosses? I'm playing it safe with green, not that they'll notice spacegame13 poster.
|
||||
icon_state = "poster42_legit"
|
||||
|
||||
/obj/structure/sign/poster/official/nt_storm_officer
|
||||
name = "NT Storm Ad"
|
||||
desc = "An advertisement for NanoTrasen Storm. A premium infantry helmet, This is the officer variant. I comes with a better radio, better HUD software and better targeting sensors."
|
||||
icon_state = "poster43_legit"
|
||||
|
||||
/obj/structure/sign/poster/official/nt_storm
|
||||
name = "NT Storm Ad"
|
||||
desc = "An advertisement for NanoTrasen Storm. A premium infantry helmet, It contains a rebreather and full head coverage for use on harsh environments where the air isn't always safe to breathe."
|
||||
icon_state = "poster44_legit"
|
||||
|
||||
#undef PLACE_SPEED
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
if(gibs_reagent_id)
|
||||
reagents.add_reagent(gibs_reagent_id, 5)
|
||||
if(gibs_bloodtype)
|
||||
add_blood_DNA(list("Non-human DNA" = gibs_bloodtype, diseases))
|
||||
add_blood_DNA(list("Non-human DNA" = gibs_bloodtype), diseases)
|
||||
update_icon()
|
||||
|
||||
/obj/effect/decal/cleanable/blood/gibs/update_icon()
|
||||
|
||||
@@ -104,4 +104,5 @@
|
||||
if(explosion_message)
|
||||
location.visible_message("<span class='danger'>The solution violently explodes!</span>", \
|
||||
"<span class='italics'>You hear an explosion!</span>")
|
||||
dyn_explosion(location, amount, flashing_factor)
|
||||
dyn_explosion(location, amount, flashing_factor)
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
|
||||
/obj/effect/mine/stun/mineEffect(mob/living/victim)
|
||||
if(isliving(victim))
|
||||
victim.Knockdown(stun_time)
|
||||
victim.DefaultCombatKnockdown(stun_time)
|
||||
|
||||
/obj/effect/mine/kickmine
|
||||
name = "kick mine"
|
||||
|
||||
@@ -61,10 +61,11 @@
|
||||
if(AM in T.affecting)
|
||||
return
|
||||
|
||||
if(ismob(AM))
|
||||
var/mob/M = AM
|
||||
if(isliving(AM))
|
||||
var/mob/living/M = AM
|
||||
if(immobilize)
|
||||
M.canmove = 0
|
||||
ADD_TRAIT(M, TRAIT_MOBILITY_NOMOVE, src)
|
||||
M.update_mobility()
|
||||
|
||||
affecting.Add(AM)
|
||||
while(AM && !stopthrow)
|
||||
@@ -98,10 +99,11 @@
|
||||
|
||||
affecting.Remove(AM)
|
||||
|
||||
if(ismob(AM))
|
||||
var/mob/M = AM
|
||||
if(isliving(AM))
|
||||
var/mob/living/M = AM
|
||||
if(immobilize)
|
||||
M.canmove = 1
|
||||
REMOVE_TRAIT(M, TRAIT_MOBILITY_NOMOVE, src)
|
||||
M.update_mobility()
|
||||
|
||||
/* Stops things thrown by a thrower, doesn't do anything */
|
||||
|
||||
|
||||
@@ -175,14 +175,13 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
|
||||
set category = "Object"
|
||||
set src in oview(1)
|
||||
|
||||
if(!isturf(loc) || usr.stat || usr.restrained() || !usr.canmove)
|
||||
var/mob/living/L = usr
|
||||
if(!istype(L) || !isturf(loc) || !CHECK_MOBILITY(L, MOBILITY_USE))
|
||||
return
|
||||
|
||||
var/turf/T = src.loc
|
||||
|
||||
src.loc = null
|
||||
|
||||
src.loc = T
|
||||
var/turf/T = loc
|
||||
loc = null
|
||||
loc = T
|
||||
|
||||
/obj/item/examine(mob/user) //This might be spammy. Remove?
|
||||
. = ..()
|
||||
@@ -544,7 +543,7 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
|
||||
to_chat(M, "<span class='danger'>You drop what you're holding and clutch at your eyes!</span>")
|
||||
M.adjust_blurriness(10)
|
||||
M.Unconscious(20)
|
||||
M.Knockdown(40)
|
||||
M.DefaultCombatKnockdown(40)
|
||||
if (prob(eyes.damage - 10 + 1))
|
||||
M.become_blind(EYE_DAMAGE)
|
||||
to_chat(M, "<span class='danger'>You go blind!</span>")
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
name = "rapid cable layer"
|
||||
desc = "A device used to rapidly deploy cables. It has screws on the side which can be removed to slide off the cables. Do not use without insulation!"
|
||||
icon = 'icons/obj/tools.dmi'
|
||||
icon_state = "rcl-empty"
|
||||
item_state = "rcl-0"
|
||||
icon_state = "rcl"
|
||||
item_state = "rcl"
|
||||
var/obj/structure/cable/last
|
||||
var/obj/item/stack/cable_coil/loaded
|
||||
opacity = FALSE
|
||||
@@ -23,6 +23,10 @@
|
||||
var/datum/radial_menu/persistent/wiring_gui_menu
|
||||
var/mob/listeningTo
|
||||
|
||||
/obj/item/twohanded/rcl/Initialize()
|
||||
. = ..()
|
||||
update_icon()
|
||||
|
||||
/obj/item/twohanded/rcl/ComponentInitialize()
|
||||
. = ..()
|
||||
AddElement(/datum/element/update_icon_updates_onmob)
|
||||
@@ -105,7 +109,15 @@
|
||||
. = ..()
|
||||
if(!loaded || !loaded.amount)
|
||||
return
|
||||
var/mutable_appearance/cable_overlay = mutable_appearance(icon, "rcl-[max(CEILING(loaded.amount/(max_amount/3), 1), 3)]")
|
||||
var/mutable_appearance/cable_overlay = mutable_appearance(icon, "[initial(icon_state)]-[CEILING(loaded.amount/(max_amount/3), 1)]")
|
||||
cable_overlay.color = GLOB.cable_colors[colors[current_color_index]]
|
||||
. += cable_overlay
|
||||
|
||||
/obj/item/twohanded/rcl/worn_overlays(isinhands, icon_file, style_flags = NONE)
|
||||
. = ..()
|
||||
if(!isinhands || !(loaded?.amount))
|
||||
return
|
||||
var/mutable_appearance/cable_overlay = mutable_appearance(icon, "rcl-[CEILING(loaded.amount/(max_amount/3), 1)]")
|
||||
cable_overlay.color = GLOB.cable_colors[colors[current_color_index]]
|
||||
. += cable_overlay
|
||||
|
||||
@@ -279,18 +291,6 @@ obj/item/twohanded/rcl/proc/getMobhook(mob/to_hook)
|
||||
|
||||
wiringGuiUpdate(user)
|
||||
|
||||
|
||||
/obj/item/twohanded/rcl/pre_loaded/Initialize() //Comes preloaded with cable, for testing stuff
|
||||
. = ..()
|
||||
loaded = new()
|
||||
loaded.max_amount = max_amount
|
||||
loaded.amount = max_amount
|
||||
update_icon()
|
||||
|
||||
/obj/item/twohanded/rcl/Initialize()
|
||||
. = ..()
|
||||
update_icon()
|
||||
|
||||
/obj/item/twohanded/rcl/ui_action_click(mob/user, action)
|
||||
if(istype(action, /datum/action/item_action/rcl_col))
|
||||
current_color_index++;
|
||||
@@ -309,10 +309,15 @@ obj/item/twohanded/rcl/proc/getMobhook(mob/to_hook)
|
||||
else //open the menu
|
||||
showWiringGui(user)
|
||||
|
||||
/obj/item/twohanded/rcl/pre_loaded/Initialize() //Comes preloaded with cable, for testing stuff
|
||||
loaded = new()
|
||||
loaded.max_amount = max_amount
|
||||
loaded.amount = max_amount
|
||||
return ..()
|
||||
|
||||
/obj/item/twohanded/rcl/ghetto
|
||||
actions_types = list()
|
||||
max_amount = 30
|
||||
name = "makeshift rapid cable layer"
|
||||
icon_state = "rclg"
|
||||
item_state = "rclg"
|
||||
ghetto = TRUE
|
||||
|
||||
@@ -66,8 +66,8 @@
|
||||
if(iswallturf(T))
|
||||
T.attackby(src, user, params)
|
||||
|
||||
var/metal_amt = round(custom_materials[getmaterialref(/datum/material/iron)]/MINERAL_MATERIAL_AMOUNT)
|
||||
var/glass_amt = round(custom_materials[getmaterialref(/datum/material/glass)]/MINERAL_MATERIAL_AMOUNT)
|
||||
var/metal_amt = round(custom_materials[SSmaterials.GetMaterialRef(/datum/material/iron)]/MINERAL_MATERIAL_AMOUNT)
|
||||
var/glass_amt = round(custom_materials[SSmaterials.GetMaterialRef(/datum/material/glass)]/MINERAL_MATERIAL_AMOUNT)
|
||||
|
||||
if(istype(W, /obj/item/wrench) && (metal_amt || glass_amt))
|
||||
to_chat(user, "<span class='notice'>You dismantle [src].</span>")
|
||||
|
||||
@@ -856,7 +856,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
|
||||
if(prob(5))//small chance for the vape to break and deal damage if it's emagged
|
||||
playsound(get_turf(src), 'sound/effects/pop_expl.ogg', 50, 0)
|
||||
M.apply_damage(20, BURN, BODY_ZONE_HEAD)
|
||||
M.Knockdown(300, 1, 0)
|
||||
M.DefaultCombatKnockdown(300, 1, 0)
|
||||
var/datum/effect_system/spark_spread/sp = new /datum/effect_system/spark_spread
|
||||
sp.set_up(5, 1, src)
|
||||
sp.start()
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user