Merge pull request #13663 from dearmochi/list-memory-optimization

Optimize memory usage by eliminating/changing some lists
This commit is contained in:
Fox McCloud
2020-06-25 13:48:47 -04:00
committed by GitHub
26 changed files with 322 additions and 237 deletions
+2
View File
@@ -690,6 +690,8 @@ proc/dd_sortedObjectList(list/incoming)
// LAZYING PT 2: THE LAZENING
#define LAZYREINITLIST(L) LAZYCLEARLIST(L); LAZYINITLIST(L);
// Lazying Episode 3
#define LAZYSET(L, K, V) LAZYINITLIST(L); L[K] = V;
//same, but returns nothing and acts on list in place
/proc/shuffle_inplace(list/L)
+2 -1
View File
@@ -3,8 +3,9 @@
#define Z_SOUTH 3
#define Z_WEST 4
GLOBAL_LIST_INIT(cardinal, list( NORTH, SOUTH, EAST, WEST ))
GLOBAL_LIST_INIT(cardinal, list(NORTH, SOUTH, EAST, WEST))
GLOBAL_LIST_INIT(alldirs, list(NORTH, SOUTH, EAST, WEST, NORTHEAST, NORTHWEST, SOUTHEAST, SOUTHWEST))
GLOBAL_LIST_INIT(alldirs2, list(NORTHEAST, NORTHWEST, SOUTHEAST, SOUTHWEST, NORTH, SOUTH, EAST, WEST))
GLOBAL_LIST_INIT(diagonals, list(NORTHEAST, NORTHWEST, SOUTHEAST, SOUTHWEST))
// This must exist early on or shit breaks bad
+11 -10
View File
@@ -19,9 +19,8 @@
if(!category)
return
var/obj/screen/alert/alert
if(alerts[category])
alert = alerts[category]
var/obj/screen/alert/alert = LAZYACCESS(alerts, category)
if(alert)
if(alert.override_alerts)
return 0
if(new_master && new_master != alert.master)
@@ -57,7 +56,7 @@
alert.icon_state = "[initial(alert.icon_state)][severity]"
alert.severity = severity
alerts[category] = alert
LAZYSET(alerts, category, alert) // This also creates the list if it doesn't exist
if(client && hud_used)
hud_used.reorganize_alerts()
alert.transform = matrix(32, 6, MATRIX_TRANSLATE)
@@ -72,7 +71,7 @@
// Proc to clear an existing alert.
/mob/proc/clear_alert(category, clear_override = FALSE)
var/obj/screen/alert/alert = alerts[category]
var/obj/screen/alert/alert = LAZYACCESS(alerts, category)
if(!alert)
return 0
if(alert.override_alerts && !clear_override)
@@ -585,12 +584,14 @@ so as to remain in compliance with the most up-to-date laws."
// Re-render all alerts - also called in /datum/hud/show_hud() because it's needed there
/datum/hud/proc/reorganize_alerts()
var/list/alerts = mymob.alerts
if(!alerts)
return FALSE
var/icon_pref
if(!hud_shown)
for(var/i = 1, i <= alerts.len, i++)
for(var/i in 1 to alerts.len)
mymob.client.screen -= alerts[alerts[i]]
return 1
for(var/i = 1, i <= alerts.len, i++)
return TRUE
for(var/i in 1 to alerts.len)
var/obj/screen/alert/alert = alerts[alerts[i]]
if(alert.icon_state == "template")
if(!icon_pref)
@@ -611,10 +612,10 @@ so as to remain in compliance with the most up-to-date laws."
. = ""
alert.screen_loc = .
mymob.client.screen |= alert
return 1
return TRUE
/mob
var/list/alerts = list() // contains /obj/screen/alert only // On /mob so clientless mobs will throw alerts properly
var/list/alerts // lazy list. contains /obj/screen/alert only // On /mob so clientless mobs will throw alerts properly
/obj/screen/alert/Click(location, control, params)
if(!usr || !usr.client)
+66
View File
@@ -0,0 +1,66 @@
#define ARMORID "armor-[melee]-[bullet]-[laser]-[energy]-[bomb]-[bio]-[rad]-[fire]-[acid]"
/proc/getArmor(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 0, acid = 0)
. = locate(ARMORID)
if (!.)
. = new /datum/armor(melee, bullet, laser, energy, bomb, bio, rad, fire, acid)
/datum/armor
var/melee
var/bullet
var/laser
var/energy
var/bomb
var/bio
var/rad
var/fire
var/acid
/datum/armor/New(melee_value = 0, bullet_value = 0, laser_value = 0, energy_value = 0, bomb_value = 0, bio_value = 0, rad_value = 0, fire_value = 0, acid_value = 0)
melee = melee_value
bullet = bullet_value
laser = laser_value
energy = energy_value
bomb = bomb_value
bio = bio_value
rad = rad_value
fire = fire_value
acid = acid_value
tag = ARMORID
/datum/armor/proc/modifyRating(melee_value = 0, bullet_value = 0, laser_value = 0, energy_value = 0, bomb_value = 0, bio_value = 0, rad_value = 0, fire_value = 0, acid_value = 0)
return getArmor(melee + melee_value, bullet + bullet_value, laser + laser_value, energy + energy_value, bomb + bomb_value, bio + bio_value, rad + rad_value, fire + fire_value, acid + acid_value)
/datum/armor/proc/modifyAllRatings(modifier = 0)
return getArmor(melee + modifier, bullet + modifier, laser + modifier, energy + modifier, bomb + modifier, bio + modifier, rad + modifier, fire + modifier, acid + modifier)
/datum/armor/proc/setRating(melee_value, bullet_value, laser_value, energy_value, bomb_value, bio_value, rad_value, fire_value, acid_value)
return getArmor((isnull(melee_value) ? melee : melee_value),\
(isnull(bullet_value) ? bullet : bullet_value),\
(isnull(laser_value) ? laser : laser_value),\
(isnull(energy_value) ? energy : energy_value),\
(isnull(bomb_value) ? bomb : bomb_value),\
(isnull(bio_value) ? bio : bio_value),\
(isnull(rad_value) ? rad : rad_value),\
(isnull(fire_value) ? fire : fire_value),\
(isnull(acid_value) ? acid : acid_value))
/datum/armor/proc/getRating(rating)
return vars[rating]
/datum/armor/proc/getList()
return list("melee" = melee, "bullet" = bullet, "laser" = laser, "energy" = energy, "bomb" = bomb, "bio" = bio, "rad" = rad, "fire" = fire, "acid" = acid)
/datum/armor/proc/attachArmor(datum/armor/AA)
return getArmor(melee + AA.melee, bullet + AA.bullet, laser + AA.laser, energy + AA.energy, bomb + AA.bomb, bio + AA.bio, rad + AA.rad, fire + AA.fire, acid + AA.acid)
/datum/armor/proc/detachArmor(datum/armor/AA)
return getArmor(melee - AA.melee, bullet - AA.bullet, laser - AA.laser, energy - AA.energy, bomb - AA.bomb, bio - AA.bio, rad - AA.rad, fire - AA.fire, acid - AA.acid)
/datum/armor/vv_edit_var(var_name, var_value)
if (var_name == NAMEOF(src, tag))
return FALSE
. = ..()
tag = ARMORID // update tag in case armor values were edited
#undef ARMORID
+66 -75
View File
@@ -14,21 +14,17 @@
var/germ_level = GERM_LEVEL_AMBIENT // The higher the germ level, the more germ on the atom.
var/simulated = TRUE //filter for actions - used by lighting overlays
var/atom_say_verb = "says"
var/dont_save = 0 // For atoms that are temporary by necessity - like lighting overlays
var/dont_save = FALSE // For atoms that are temporary by necessity - like lighting overlays
///Chemistry.
var/container_type = NONE
var/datum/reagents/reagents = null
//This atom's HUD (med/sec, etc) images. Associative list.
var/list/image/hud_list = list()
var/list/image/hud_list
//HUD images that this atom can provide.
var/list/hud_possible
///Chemistry.
//Value used to increment ex_act() if reactionary_explosions is on
var/explosion_block = 0
@@ -38,9 +34,9 @@
//Detective Work, used for allowing a given atom to leave its fibers on stuff. Allowed by default
var/can_leave_fibers = TRUE
var/allow_spin = 1 //Set this to 1 for a _target_ that is being thrown at; if an atom has this set to 1 then atoms thrown AT it will not spin; currently used for the singularity. -Fox
var/allow_spin = TRUE //Set this to 1 for a _target_ that is being thrown at; if an atom has this set to 1 then atoms thrown AT it will not spin; currently used for the singularity. -Fox
var/admin_spawned = 0 //was this spawned by an admin? used for stat tracking stuff.
var/admin_spawned = FALSE //was this spawned by an admin? used for stat tracking stuff.
var/initialized = FALSE
@@ -67,7 +63,6 @@
// we were deleted
return
//Called after New if the map is being loaded. mapload = TRUE
//Called from base of New if the map is not being loaded. mapload = FALSE
//This base must be called or derivatives must set initialized to TRUE
@@ -101,7 +96,6 @@
return INITIALIZE_HINT_NORMAL
//called if Initialize returns INITIALIZE_HINT_LATELOAD
/atom/proc/LateInitialize()
return
@@ -114,34 +108,34 @@
return
/atom/proc/onCentcom()
. = FALSE
var/turf/T = get_turf(src)
if(!T)
return 0
return
if(!is_admin_level(T.z))//if not, don't bother
return 0
return
//check for centcomm shuttles
for(var/centcom_shuttle in list("emergency", "pod1", "pod2", "pod3", "pod4", "ferry"))
var/obj/docking_port/mobile/M = SSshuttle.getShuttle(centcom_shuttle)
if(T in M.areaInstance)
return 1
return TRUE
//finally check for centcom itself
return istype(T.loc,/area/centcom)
return istype(T.loc, /area/centcom)
/atom/proc/onSyndieBase()
. = FALSE
var/turf/T = get_turf(src)
if(!T)
return 0
return
if(!is_admin_level(T.z))//if not, don't bother
return 0
return
if(istype(T.loc, /area/shuttle/syndicate_elite) || istype(T.loc, /area/syndicate_mothership))
return 1
return 0
return TRUE
/atom/Destroy()
if(alternate_appearances)
@@ -202,7 +196,7 @@
else
return null
/atom/proc/check_eye(user)
/atom/proc/check_eye(mob/user)
return
/atom/proc/on_reagent_change()
@@ -217,11 +211,11 @@
/// Is this atom injectable into other atoms
/atom/proc/is_injectable(mob/user, allowmobs = TRUE)
return reagents && (container_type & (INJECTABLE | REFILLABLE))
return reagents && (container_type & (INJECTABLE|REFILLABLE))
/// Can we draw from this atom with an injectable atom
/atom/proc/is_drawable(mob/user, allowmobs = TRUE)
return reagents && (container_type & (DRAWABLE | DRAINABLE))
return reagents && (container_type & (DRAWABLE|DRAINABLE))
/// Can this atoms reagents be refilled
/atom/proc/is_refillable()
@@ -232,12 +226,12 @@
return reagents && (container_type & DRAINABLE)
/atom/proc/CheckExit()
return 1
return TRUE
/atom/proc/HasProximity(atom/movable/AM as mob|obj)
return
/atom/proc/emp_act(var/severity)
/atom/proc/emp_act(severity)
return
/atom/proc/bullet_act(obj/item/projectile/P, def_zone)
@@ -247,13 +241,13 @@
/atom/proc/in_contents_of(container)//can take class or object instance as argument
if(ispath(container))
if(istype(src.loc, container))
return 1
return TRUE
else if(src in container)
return 1
return
return TRUE
return FALSE
/*
* atom/proc/search_contents_for(path,list/filter_path=null)
* atom/proc/search_contents_for(path, list/filter_path = null)
* Recursevly searches all atom contens (including contents contents and so on).
*
* ARGS: path - search atom contents for atoms of this type
@@ -262,7 +256,7 @@
* RETURNS: list of found atoms
*/
/atom/proc/search_contents_for(path,list/filter_path=null)
/atom/proc/search_contents_for(path, list/filter_path = null)
var/list/found = list()
for(var/atom/A in src)
if(istype(A, path))
@@ -274,7 +268,7 @@
if(!pass)
continue
if(A.contents.len)
found += A.search_contents_for(path,filter_path)
found += A.search_contents_for(path, filter_path)
return found
@@ -406,43 +400,47 @@
/atom/proc/after_slip(mob/living/carbon/human/H)
return
/atom/proc/add_hiddenprint(mob/living/M as mob)
if(isnull(M)) return
if(isnull(M.key)) return
/atom/proc/add_hiddenprint(mob/living/M)
if(isnull(M))
return
if(isnull(M.key))
return
if(ishuman(M))
var/mob/living/carbon/human/H = M
if(!istype(H.dna, /datum/dna))
return 0
return FALSE
if(H.gloves)
if(fingerprintslast != H.ckey)
//Add the list if it does not exist.
if(!fingerprintshidden)
fingerprintshidden = list()
fingerprintshidden += text("\[[time_stamp()]\] (Wearing gloves). Real name: [], Key: []",H.real_name, H.key)
fingerprintshidden += text("\[[time_stamp()]\] (Wearing gloves). Real name: [], Key: []", H.real_name, H.key)
fingerprintslast = H.ckey
return 0
return FALSE
if(!fingerprints)
if(fingerprintslast != H.ckey)
//Add the list if it does not exist.
if(!fingerprintshidden)
fingerprintshidden = list()
fingerprintshidden += text("\[[time_stamp()]\] Real name: [], Key: []",H.real_name, H.key)
fingerprintshidden += text("\[[time_stamp()]\] Real name: [], Key: []", H.real_name, H.key)
fingerprintslast = H.ckey
return 1
return TRUE
else
if(fingerprintslast != M.ckey)
//Add the list if it does not exist.
if(!fingerprintshidden)
fingerprintshidden = list()
fingerprintshidden += text("\[[time_stamp()]\] Real name: [], Key: []",M.real_name, M.key)
fingerprintshidden += text("\[[time_stamp()]\] Real name: [], Key: []", M.real_name, M.key)
fingerprintslast = M.ckey
return
//Set ignoregloves to add prints irrespective of the mob having gloves on.
/atom/proc/add_fingerprint(mob/living/M as mob, ignoregloves = 0)
if(isnull(M)) return
if(isnull(M.key)) return
/atom/proc/add_fingerprint(mob/living/M, ignoregloves = FALSE)
if(isnull(M))
return
if(isnull(M.key))
return
if(ishuman(M))
//Add the list if it does not exist.
if(!fingerprintshidden)
@@ -456,7 +454,7 @@
if(fingerprintslast != M.key)
fingerprintshidden += "(Has no fingerprints) Real name: [M.real_name], Key: [M.key]"
fingerprintslast = M.key
return 0 //Now, lets get to the dirty work.
return FALSE //Now, lets get to the dirty work.
//First, make sure their DNA makes sense.
var/mob/living/carbon/human/H = M
if(!istype(H.dna, /datum/dna) || !H.dna.uni_identity || (length(H.dna.uni_identity) != 32))
@@ -469,20 +467,20 @@
if(H.gloves)
var/obj/item/clothing/gloves/G = H.gloves
if(G.transfer_prints)
ignoregloves = 1
ignoregloves = TRUE
//Now, deal with gloves.
if(!ignoregloves)
if(H.gloves && H.gloves != src)
if(fingerprintslast != H.ckey)
fingerprintshidden += text("\[[]\](Wearing gloves). Real name: [], Key: []",time_stamp(), H.real_name, H.key)
fingerprintshidden += text("\[[]\](Wearing gloves). Real name: [], Key: []", time_stamp(), H.real_name, H.key)
fingerprintslast = H.ckey
H.gloves.add_fingerprint(M)
return 0
return FALSE
//More adminstuffz
if(fingerprintslast != H.ckey)
fingerprintshidden += text("\[[]\]Real name: [], Key: []",time_stamp(), H.real_name, H.key)
fingerprintshidden += text("\[[]\]Real name: [], Key: []", time_stamp(), H.real_name, H.key)
fingerprintslast = H.ckey
//Make the list if it does not exist.
@@ -495,18 +493,16 @@
// Add the fingerprints
fingerprints[full_print] = full_print
return 1
return TRUE
else
//Smudge up dem prints some
if(fingerprintslast != M.ckey)
fingerprintshidden += text("\[[]\]Real name: [], Key: []",time_stamp(), M.real_name, M.key)
fingerprintshidden += text("\[[]\]Real name: [], Key: []", time_stamp(), M.real_name, M.key)
fingerprintslast = M.ckey
return
/atom/proc/transfer_fingerprints_to(var/atom/A)
/atom/proc/transfer_fingerprints_to(atom/A)
// Make sure everything are lists.
if(!islist(A.fingerprints))
A.fingerprints = list()
@@ -553,7 +549,7 @@ GLOBAL_LIST_EMPTY(blood_splatter_icons)
/atom/proc/transfer_mob_blood_dna(mob/living/L)
var/new_blood_dna = L.get_blood_dna_list()
if(!new_blood_dna)
return 0
return FALSE
return transfer_blood_dna(new_blood_dna)
/obj/effect/decal/cleanable/blood/splatter/transfer_mob_blood_dna(mob/living/L)
@@ -581,14 +577,13 @@ GLOBAL_LIST_EMPTY(blood_splatter_icons)
var/old_length = blood_DNA.len
blood_DNA |= blood_dna
if(blood_DNA.len > old_length)
return 1//some new blood DNA was added
return TRUE//some new blood DNA was added
//to add blood from a mob onto something, and transfer their dna info
/atom/proc/add_mob_blood(mob/living/M)
var/list/blood_dna = M.get_blood_dna_list()
if(!blood_dna)
return 0
return FALSE
var/bloodcolor = "#A10808"
var/list/b_data = M.get_blood_data(M.get_blood_id())
if(b_data)
@@ -598,7 +593,7 @@ GLOBAL_LIST_EMPTY(blood_splatter_icons)
//to add blood onto something, with blood dna info to include.
/atom/proc/add_blood(list/blood_dna, color)
return 0
return FALSE
/obj/add_blood(list/blood_dna, color)
return transfer_blood_dna(blood_dna)
@@ -606,10 +601,10 @@ GLOBAL_LIST_EMPTY(blood_splatter_icons)
/obj/item/add_blood(list/blood_dna, color)
var/blood_count = !blood_DNA ? 0 : blood_DNA.len
if(!..())
return 0
return FALSE
if(!blood_count)//apply the blood-splatter overlay if it isn't already in there
add_blood_overlay(color)
return 1 //we applied blood to the item
return TRUE //we applied blood to the item
/obj/item/clothing/gloves/add_blood(list/blood_dna, color)
. = ..()
@@ -621,7 +616,7 @@ GLOBAL_LIST_EMPTY(blood_splatter_icons)
B = new /obj/effect/decal/cleanable/blood/splatter(src)
B.transfer_blood_dna(blood_dna) //give blood info to the blood decal.
B.basecolor = color
return 1 //we bloodied the floor
return TRUE //we bloodied the floor
/mob/living/carbon/human/add_blood(list/blood_dna, color)
if(wear_suit)
@@ -652,7 +647,7 @@ GLOBAL_LIST_EMPTY(blood_splatter_icons)
verbs += /mob/living/carbon/human/proc/bloody_doodle
update_inv_gloves() //handles bloody hands overlays and updating
return 1
return TRUE
/obj/item/proc/add_blood_overlay(color)
if(initial(icon) && initial(icon_state))
@@ -690,7 +685,6 @@ GLOBAL_LIST_EMPTY(blood_splatter_icons)
if(.)
transfer_blood = 0
/obj/item/clothing/shoes/clean_blood()
..()
bloody_shoes = list(BLOOD_STATE_HUMAN = 0, BLOOD_STATE_XENO = 0, BLOOD_STATE_NOT_BLOODY = 0)
@@ -699,7 +693,6 @@ GLOBAL_LIST_EMPTY(blood_splatter_icons)
var/mob/M = loc
M.update_inv_shoes()
/mob/living/carbon/human/clean_blood()
if(gloves)
if(gloves.clean_blood())
@@ -713,9 +706,8 @@ GLOBAL_LIST_EMPTY(blood_splatter_icons)
update_inv_gloves()
update_icons() //apply the now updated overlays to the mob
/atom/proc/add_vomit_floor(toxvomit = 0, green = FALSE)
playsound(src, 'sound/effects/splat.ogg', 50, 1)
/atom/proc/add_vomit_floor(toxvomit = FALSE, green = FALSE)
playsound(src, 'sound/effects/splat.ogg', 50, TRUE)
if(!isspaceturf(src))
var/type = green ? /obj/effect/decal/cleanable/vomit/green : /obj/effect/decal/cleanable/vomit
var/vomit_reagent = green ? "green_vomit" : "vomit"
@@ -728,23 +720,24 @@ GLOBAL_LIST_EMPTY(blood_splatter_icons)
// Make toxins vomit look different
if(toxvomit)
this.icon_state = "vomittox_[pick(1,4)]"
this.icon_state = "vomittox_[pick(1, 4)]"
/atom/proc/get_global_map_pos()
if(!islist(GLOB.global_map) || isemptylist(GLOB.global_map)) return
if(!islist(GLOB.global_map) || isemptylist(GLOB.global_map))
return
var/cur_x = null
var/cur_y = null
var/list/y_arr = null
for(cur_x=1,cur_x<=GLOB.global_map.len,cur_x++)
for(cur_x in 1 to GLOB.global_map.len)
y_arr = GLOB.global_map[cur_x]
cur_y = y_arr.Find(src.z)
if(cur_y)
break
// to_chat(world, "X = [cur_x]; Y = [cur_y]")
if(cur_x && cur_y)
return list("x"=cur_x,"y"=cur_y)
return list("x" = cur_x, "y" = cur_y)
else
return 0
return null
// Used to provide overlays when using this atom as a viewing focus
// (cameras, locker tint, etc.)
@@ -757,7 +750,7 @@ GLOBAL_LIST_EMPTY(blood_splatter_icons)
return
/atom/proc/checkpass(passflag)
return pass_flags&passflag
return pass_flags & passflag
/atom/proc/isinspace()
if(isspaceturf(get_turf(src)))
@@ -800,7 +793,7 @@ GLOBAL_LIST_EMPTY(blood_splatter_icons)
return
audible_message("<span class='game say'><span class='name'>[src]</span> [atom_say_verb], \"[message]\"</span>")
/atom/proc/speech_bubble(var/bubble_state = "",var/bubble_loc = src, var/list/bubble_recipients = list())
/atom/proc/speech_bubble(bubble_state = "", bubble_loc = src, list/bubble_recipients = list())
return
/atom/vv_edit_var(var_name, var_value)
@@ -857,7 +850,6 @@ GLOBAL_LIST_EMPTY(blood_splatter_icons)
atom_colours[colour_priority] = coloration
update_atom_colour()
/*
Removes an instance of colour_type from the atom's atom_colours list
*/
@@ -872,7 +864,6 @@ GLOBAL_LIST_EMPTY(blood_splatter_icons)
atom_colours[colour_priority] = null
update_atom_colour()
/*
Resets the atom's color to null, and then sets it to the highest priority
colour available
+2 -2
View File
@@ -86,8 +86,8 @@
is_zombie = TRUE
if(H.wear_suit)
var/obj/item/clothing/suit/armor/A = H.wear_suit
if(A.armor && A.armor["melee"])
maxHealth += A.armor["melee"] //That zombie's got armor, I want armor!
if(A.armor && A.armor.getRating("melee"))
maxHealth += A.armor.getRating("melee") //That zombie's got armor, I want armor!
maxHealth += 40
health = maxHealth
name = "blob zombie"
+1 -1
View File
@@ -176,7 +176,7 @@
return 0
var/armor_protection = 0
if(damage_flag)
armor_protection = armor[damage_flag]
armor_protection = armor.getRating(damage_flag)
damage_amount = round(damage_amount * (100 - armor_protection)*0.01, 0.1)
if(overmind && damage_flag)
damage_amount = overmind.blob_reagent_datum.damage_reaction(src, damage_amount, damage_type, damage_flag)
@@ -25,6 +25,11 @@
var/combat_armor = list("melee" = 50, "bullet" = 50, "laser" = 50, "energy" = 50, "bomb" = 50, "bio" = 50, "rad" = 50, "fire" = 90, "acid" = 90)
sprite_sheets = null
/obj/item/clothing/suit/armor/abductor/vest/Initialize(mapload)
. = ..()
stealth_armor = getArmor(arglist(stealth_armor))
combat_armor = getArmor(arglist(combat_armor))
/obj/item/clothing/suit/armor/abductor/vest/proc/toggle_nodrop()
flags ^= NODROP
if(ismob(loc))
+3 -3
View File
@@ -116,8 +116,8 @@ Class Procs:
var/panel_open = 0
var/area/myArea
var/interact_offline = 0 // Can the machine be interacted with while de-powered.
var/use_log = list()
var/list/settagwhitelist = list()//WHITELIST OF VARIABLES THAT THE set_tag HREF CAN MODIFY, DON'T PUT SHIT YOU DON'T NEED ON HERE, AND IF YOU'RE GONNA USE set_tag (format_tag() proc), ADD TO THIS LIST.
var/list/use_log // Init this list if you wish to add logging to your machine - currently only viewable in VV
var/list/settagwhitelist // (Init this list if needed) WHITELIST OF VARIABLES THAT THE set_tag HREF CAN MODIFY, DON'T PUT SHIT YOU DON'T NEED ON HERE, AND IF YOU'RE GONNA USE set_tag (format_tag() proc), ADD TO THIS LIST.
atom_say_verb = "beeps"
var/siemens_strength = 0.7 // how badly will it shock you?
@@ -224,7 +224,7 @@ Class Procs:
var/obj/item/multitool/P = get_multitool(usr)
if(P && istype(P))
var/update_mt_menu = FALSE
if("set_tag" in href_list)
if("set_tag" in href_list && settagwhitelist)
if(!(href_list["set_tag"] in settagwhitelist))//I see you're trying Href exploits, I see you're failing, I SEE ADMIN WARNING. (seriously though, this is a powerfull HREF, I originally found this loophole, I'm not leaving it in on my PR)
message_admins("set_tag HREF (var attempted to edit: [href_list["set_tag"]]) exploit attempted by [key_name_admin(user)] on [src] (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[x];Y=[y];Z=[z]'>JMP</a>)")
return FALSE
+1
View File
@@ -19,6 +19,7 @@ GLOBAL_DATUM_INIT(fire_overlay, /image, image("icon" = 'icons/goonstation/effect
can_be_hit = FALSE
suicidal_hands = TRUE
var/list/attack_verb //Used in attackby() to say how something was attacked "[x] has been [z.attack_verb] by [y] with [z]"
var/hitsound = null
var/usesound = null
var/throwhitsound
@@ -169,9 +169,9 @@ GLOBAL_LIST_INIT(sinew_recipes, list ( \
return
if(is_type_in_typecache(target, goliath_platable_armor_typecache))
var/obj/item/clothing/C = target
var/list/current_armor = C.armor
if(current_armor["melee"] < 60)
current_armor["melee"] = min(current_armor["melee"] + 10, 60)
var/datum/armor/current_armor = C.armor
if(current_armor.getRating("melee") < 60)
C.armor = current_armor.setRating(melee_value = min(current_armor.getRating("melee") + 10, 60))
to_chat(user, "<span class='info'>You strengthen [target], improving its resistance against melee attacks.</span>")
use(1)
else
@@ -180,9 +180,9 @@ GLOBAL_LIST_INIT(sinew_recipes, list ( \
var/obj/mecha/working/ripley/D = target
if(D.hides < 3)
D.hides++
D.armor["melee"] = min(D.armor["melee"] + 10, 70)
D.armor["bullet"] = min(D.armor["bullet"] + 5, 50)
D.armor["laser"] = min(D.armor["laser"] + 5, 50)
D.armor = D.armor.setRating(melee_value = min(D.armor.getRating("melee") + 10, 70))
D.armor = D.armor.setRating(bullet_value = min(D.armor.getRating("bullet") + 5, 50))
D.armor = D.armor.setRating(laser_value = min(D.armor.getRating("laser") + 5, 50))
to_chat(user, "<span class='info'>You strengthen [target], improving its resistance against melee attacks.</span>")
D.update_icon()
if(D.hides == 3)
+1 -1
View File
@@ -30,7 +30,7 @@
return 0
var/armor_protection = 0
if(damage_flag)
armor_protection = armor[damage_flag]
armor_protection = armor.getRating(damage_flag)
if(armor_protection) //Only apply weak-against-armor/hollowpoint effects if there actually IS armor.
armor_protection = Clamp(armor_protection - armour_penetration, min(armor_protection, 0), 100)
return round(damage_amount * (100 - armor_protection)*0.01, DAMAGE_PRECISION)
+57 -51
View File
@@ -1,15 +1,14 @@
/obj
//var/datum/module/mod //not used
var/origin_tech = null //Used by R&D to determine what research bonuses it grants.
var/crit_fail = 0
var/crit_fail = FALSE
animate_movement = 2
var/list/attack_verb = list() //Used in attackby() to say how something was attacked "[x] has been [z.attack_verb] by [y] with [z]"
var/list/species_exception = null // list() of species types, if a species cannot put items in a certain slot, but species type is in list, it will be able to wear that item
var/sharp = 0 // whether this object cuts
var/in_use = 0 // If we have a user using us, this will be set on. We will check if the user has stopped using us, and thus stop updating and LAGGING EVERYTHING!
var/sharp = FALSE // whether this object cuts
var/in_use = FALSE // If we have a user using us, this will be set on. We will check if the user has stopped using us, and thus stop updating and LAGGING EVERYTHING!
var/damtype = "brute"
var/force = 0
var/list/armor
var/datum/armor/armor
var/obj_integrity //defaults to max_integrity
var/max_integrity = 500
var/integrity_failure = 0 //0 if we have no special broken behavior
@@ -22,9 +21,9 @@
var/can_be_hit = TRUE //can this be bludgeoned by items?
var/Mtoollink = 0 // variable to decide if an object should show the multitool menu linking menu, not all objects use it
var/Mtoollink = FALSE // variable to decide if an object should show the multitool menu linking menu, not all objects use it
var/being_shocked = 0
var/being_shocked = FALSE
var/speed_process = FALSE
var/on_blueprints = FALSE //Are we visible on the station blueprints at roundstart?
@@ -33,8 +32,6 @@
/obj/New()
..()
if(!armor)
armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 0, acid = 0)
if(obj_integrity == null)
obj_integrity = max_integrity
if(on_blueprints && isturf(loc))
@@ -44,25 +41,34 @@
else
T.add_blueprints_preround(src)
/obj/Topic(href, href_list, var/nowindow = 0, var/datum/topic_state/state = GLOB.default_state)
/obj/Initialize(mapload)
. = ..()
if(islist(armor))
armor = getArmor(arglist(armor))
else if(!armor)
armor = getArmor()
else if(!istype(armor, /datum/armor))
stack_trace("Invalid type [armor.type] found in .armor during /obj Initialize()")
/obj/Topic(href, href_list, nowindow = FALSE, datum/topic_state/state = GLOB.default_state)
// Calling Topic without a corresponding window open causes runtime errors
if(!nowindow && ..())
return 1
return TRUE
// In the far future no checks are made in an overriding Topic() beyond if(..()) return
// Instead any such checks are made in CanUseTopic()
if(CanUseTopic(usr, state, href_list) == STATUS_INTERACTIVE)
CouldUseTopic(usr)
return 0
return FALSE
CouldNotUseTopic(usr)
return 1
return TRUE
/obj/proc/CouldUseTopic(var/mob/user)
/obj/proc/CouldUseTopic(mob/user)
var/atom/host = nano_host()
host.add_fingerprint(user)
/obj/proc/CouldNotUseTopic(var/mob/user)
/obj/proc/CouldNotUseTopic(mob/user)
// Nada
/obj/Destroy()
@@ -110,23 +116,23 @@
// null if object handles breathing logic for lifeform
// datum/air_group to tell lifeform to process using that breath return
//DEFAULT: Take air from turf to give to have mob process
if(breath_request>0)
if(breath_request > 0)
return remove_air(breath_request)
else
return null
/obj/proc/updateUsrDialog()
if(in_use)
var/is_in_use = 0
var/is_in_use = FALSE
var/list/nearby = viewers(1, src)
for(var/mob/M in nearby)
if((M.client && M.machine == src))
is_in_use = 1
is_in_use = TRUE
src.attack_hand(M)
if(istype(usr, /mob/living/silicon/ai) || istype(usr, /mob/living/silicon/robot))
if(!(usr in nearby))
if(usr.client && usr.machine==src) // && M.machine == src is omitted because if we triggered this by using the dialog, it doesn't matter if our machine changed in between triggering it and this - the dialog is probably still supposed to refresh.
is_in_use = 1
is_in_use = TRUE
src.attack_ai(usr)
// check for TK users
@@ -134,8 +140,8 @@
if(istype(usr, /mob/living/carbon/human))
if(istype(usr.l_hand, /obj/item/tk_grab) || istype(usr.r_hand, /obj/item/tk_grab/))
if(!(usr in nearby))
if(usr.client && usr.machine==src)
is_in_use = 1
if(usr.client && usr.machine == src)
is_in_use = TRUE
src.attack_hand(usr)
in_use = is_in_use
@@ -143,15 +149,15 @@
// Check that people are actually using the machine. If not, don't update anymore.
if(in_use)
var/list/nearby = viewers(1, src)
var/is_in_use = 0
var/is_in_use = FALSE
for(var/mob/M in nearby)
if((M.client && M.machine == src))
is_in_use = 1
is_in_use = TRUE
src.interact(M)
var/ai_in_use = AutoUpdateAI(src)
if(!ai_in_use && !is_in_use)
in_use = 0
in_use = FALSE
/obj/proc/interact(mob/user)
return
@@ -168,12 +174,12 @@
/atom/movable/proc/on_unset_machine(mob/user)
return
/mob/proc/set_machine(var/obj/O)
/mob/proc/set_machine(obj/O)
if(src.machine)
unset_machine()
src.machine = O
if(istype(O))
O.in_use = 1
O.in_use = TRUE
/obj/item/proc/updateSelfDialog()
var/mob/M = src.loc
@@ -183,48 +189,48 @@
/obj/proc/hide(h)
return
/obj/proc/hear_talk(mob/M, list/message_pieces)
return
/obj/proc/hear_message(mob/M as mob, text)
/obj/proc/hear_message(mob/M, text)
/obj/proc/multitool_menu(var/mob/user,var/obj/item/multitool/P)
/obj/proc/multitool_menu(mob/user, obj/item/multitool/P)
return "<b>NO MULTITOOL_MENU!</b>"
/obj/proc/linkWith(var/mob/user, var/obj/buffer, var/context)
return 0
/obj/proc/linkWith(mob/user, obj/buffer, context)
return FALSE
/obj/proc/unlinkFrom(var/mob/user, var/obj/buffer)
return 0
/obj/proc/unlinkFrom(mob/user, obj/buffer)
return FALSE
/obj/proc/canLink(var/obj/O, var/context)
return 0
/obj/proc/canLink(obj/O, list/context)
return FALSE
/obj/proc/isLinkedWith(var/obj/O)
return 0
/obj/proc/isLinkedWith(obj/O)
return FALSE
/obj/proc/getLink(var/idx)
/obj/proc/getLink(idx)
return null
/obj/proc/linkMenu(var/obj/O)
var/dat=""
/obj/proc/linkMenu(obj/O)
var/dat = ""
if(canLink(O, list()))
dat += " <a href='?src=[UID()];link=1'>\[Link\]</a> "
return dat
/obj/proc/format_tag(var/label,var/varname, var/act="set_tag")
/obj/proc/format_tag(label, varname, act = "set_tag")
var/value = vars[varname]
if(!value || value=="")
value="-----"
if(!value || value == "")
value = "-----"
return "<b>[label]:</b> <a href=\"?src=[UID()];[act]=[varname]\">[value]</a>"
/obj/proc/update_multitool_menu(mob/user as mob)
/obj/proc/update_multitool_menu(mob/user)
var/obj/item/multitool/P = get_multitool(user)
if(!istype(P))
return 0
return FALSE
var/dat = {"<html>
<head>
<title>[name] Configuration</title>
@@ -246,13 +252,13 @@ a {
<h3>[name]</h3>
"}
if(allowed(user))//no, assistants, you're not ruining all vents on the station with just a multitool
dat += multitool_menu(user,P)
dat += multitool_menu(user, P)
if(Mtoollink)
if(P)
if(P.buffer)
var/id = null
if("id_tag" in P.buffer.vars)
id=P.buffer:id_tag
id = P.buffer:id_tag
dat += "<p><b>MULTITOOL BUFFER:</b> [P.buffer] [id ? "([id])" : ""]"
dat += linkMenu(P.buffer)
@@ -309,12 +315,12 @@ a {
/obj/singularity_pull(S, current_size)
..()
if(!anchored || current_size >= STAGE_FIVE)
step_towards(src,S)
step_towards(src, S)
/obj/proc/container_resist(var/mob/living)
/obj/proc/container_resist(mob/living)
return
/obj/proc/CanAStarPass()
/obj/proc/CanAStarPass(ID, dir, caller)
. = !density
/obj/proc/on_mob_move(dir, mob/user)
@@ -343,4 +349,4 @@ a {
.["Make normal process"] = "?_src_=vars;makenormalspeed=[UID()]"
/obj/proc/check_uplink_validity()
return 1
return TRUE
+2 -2
View File
@@ -80,8 +80,8 @@
O.resistance_flags |= FLAMMABLE //Even fireproof things burn up in lava
if(O.resistance_flags & FIRE_PROOF)
O.resistance_flags &= ~FIRE_PROOF
if(O.armor["fire"] > 50) //obj with 100% fire armor still get slowly burned away.
O.armor["fire"] = 50
if(O.armor.getRating("fire") > 50) //obj with 100% fire armor still get slowly burned away.
O.armor = O.armor.setRating(fire_value = 50)
O.fire_act(10000, 1000)
else if(isliving(thing))
+59 -61
View File
@@ -3,7 +3,7 @@
level = 1
luminosity = 1
var/intact = 1
var/intact = TRUE
var/turf/baseturf = /turf/space
var/slowdown = 0 //negative for faster, positive for slower
@@ -33,7 +33,7 @@
var/list/blueprint_data //for the station blueprints, images of objects eg: pipes
var/list/footstep_sounds = list()
var/list/footstep_sounds
var/shoe_running_volume = 50
var/shoe_walking_volume = 20
@@ -68,7 +68,7 @@
if(AA.smooth)
queue_smooth(AA)
log_startup_progress(" Smoothed atoms in [stop_watch(watch)]s.")
return 1
return TRUE
/turf/Destroy()
// Adds the adjacent turfs to the current atmos processing
@@ -85,7 +85,7 @@
user.Move_Pulled(src)
/turf/ex_act(severity)
return 0
return FALSE
/turf/rpd_act(mob/user, obj/item/rpd/our_rpd) //This is the default turf behaviour for the RPD; override it as required
if(our_rpd.mode == RPD_ATMOS_MODE)
@@ -103,55 +103,53 @@
else if(our_rpd.mode == RPD_DELETE_MODE)
our_rpd.delete_all_pipes(user, src)
/turf/bullet_act(var/obj/item/projectile/Proj)
if(istype(Proj ,/obj/item/projectile/beam/pulse))
/turf/bullet_act(obj/item/projectile/Proj)
if(istype(Proj, /obj/item/projectile/beam/pulse))
src.ex_act(2)
..()
return 0
return FALSE
/turf/bullet_act(var/obj/item/projectile/Proj)
if(istype(Proj ,/obj/item/projectile/bullet/gyro))
/turf/bullet_act(obj/item/projectile/Proj)
if(istype(Proj, /obj/item/projectile/bullet/gyro))
explosion(src, -1, 0, 2)
..()
return 0
return FALSE
/turf/Enter(atom/movable/mover as mob|obj, atom/forget as mob|obj|turf|area)
/turf/Enter(atom/movable/mover as mob|obj, atom/forget)
if(!mover)
return 1
return TRUE
// First, make sure it can leave its square
if(isturf(mover.loc))
// Nothing but border objects stop you from leaving a tile, only one loop is needed
for(var/obj/obstacle in mover.loc)
if(!obstacle.CheckExit(mover, src) && obstacle != mover && obstacle != forget)
mover.Bump(obstacle, 1)
return 0
mover.Bump(obstacle, TRUE)
return FALSE
var/list/large_dense = list()
//Next, check objects to block entry that are on the border
for(var/atom/movable/border_obstacle in src)
if(border_obstacle.flags&ON_BORDER)
if(!border_obstacle.CanPass(mover, mover.loc, 1, 0) && (forget != border_obstacle))
mover.Bump(border_obstacle, 1)
return 0
if(border_obstacle.flags & ON_BORDER)
if(!border_obstacle.CanPass(mover, mover.loc, 1) && (forget != border_obstacle))
mover.Bump(border_obstacle, TRUE)
return FALSE
else
large_dense += border_obstacle
//Then, check the turf itself
if(!src.CanPass(mover, src))
mover.Bump(src, 1)
return 0
mover.Bump(src, TRUE)
return FALSE
//Finally, check objects/mobs to block entry that are not on the border
for(var/atom/movable/obstacle in large_dense)
if(!obstacle.CanPass(mover, mover.loc, 1, 0) && (forget != obstacle))
mover.Bump(obstacle, 1)
return 0
return 1 //Nothing found to block so return success!
if(!obstacle.CanPass(mover, mover.loc, 1) && (forget != obstacle))
mover.Bump(obstacle, TRUE)
return FALSE
return TRUE //Nothing found to block so return success!
/turf/Entered(atom/movable/M, atom/OL, ignoreRest = 0)
/turf/Entered(atom/movable/M, atom/OL, ignoreRest = FALSE)
..()
if(ismob(M))
var/mob/O = M
@@ -164,7 +162,7 @@
if(loopsanity == 0)
break
loopsanity--
A.HasProximity(M, 1)
A.HasProximity(M)
// If an opaque movable atom moves around we need to potentially update visibility.
if(M.opacity)
@@ -180,7 +178,7 @@
/turf/space/levelupdate()
for(var/obj/O in src)
if(O.level == 1)
O.hide(0)
O.hide(FALSE)
// Removes all signs of lattice on the pos of the turf -Donkieyo
/turf/proc/RemoveLattice()
@@ -250,7 +248,7 @@
return
// I'm including `ignore_air` because BYOND lacks positional-only arguments
/turf/proc/AfterChange(ignore_air, keep_cabling = FALSE) //called after a turf has been replaced in ChangeTurf()
/turf/proc/AfterChange(ignore_air = FALSE, keep_cabling = FALSE) //called after a turf has been replaced in ChangeTurf()
levelupdate()
CalculateAdjacentTurfs()
@@ -261,7 +259,7 @@
for(var/obj/structure/cable/C in contents)
qdel(C)
/turf/simulated/AfterChange(ignore_air, keep_cabling = FALSE)
/turf/simulated/AfterChange(ignore_air = FALSE, keep_cabling = FALSE)
..()
RemoveLattice()
if(!ignore_air)
@@ -280,7 +278,7 @@
var/turf_count = 0
for(var/direction in GLOB.cardinal)//Only use cardinals to cut down on lag
var/turf/T = get_step(src,direction)
var/turf/T = get_step(src, direction)
if(istype(T, /turf/space))//Counted as no air
turf_count++//Considered a valid turf for air calcs
continue
@@ -315,12 +313,11 @@
/turf/proc/kill_creatures(mob/U = null)//Will kill people/creatures and damage mechs./N
//Useful to batch-add creatures to the list.
for(var/mob/living/M in src)
if(M==U) continue//Will not harm U. Since null != M, can be excluded to kill everyone.
spawn(0)
M.gib()
if(M == U)
continue//Will not harm U. Since null != M, can be excluded to kill everyone.
INVOKE_ASYNC(M, /mob/.proc/gib)
for(var/obj/mecha/M in src)//Mecha are not gibbed but are damaged.
spawn(0)
M.take_damage(100, "brute")
INVOKE_ASYNC(M, /obj/mecha/.proc/take_damage, 100, "brute")
/turf/proc/Bless()
flags |= NOJAUNT
@@ -377,11 +374,11 @@
// Returns the surrounding simulated turfs with open links
// Including through doors openable with the ID
/turf/proc/AdjacentTurfsWithAccess(var/obj/item/card/id/ID = null,var/list/closed)//check access if one is passed
/turf/proc/AdjacentTurfsWithAccess(obj/item/card/id/ID = null, list/closed)//check access if one is passed
var/list/L = new()
var/turf/simulated/T
for(var/dir in list(NORTHWEST,NORTHEAST,SOUTHEAST,SOUTHWEST,NORTH,EAST,SOUTH,WEST)) //arbitrarily ordered list to favor non-diagonal moves in case of ties
T = get_step(src,dir)
for(var/dir in GLOB.alldirs2) //arbitrarily ordered list to favor non-diagonal moves in case of ties
T = get_step(src, dir)
if(T in closed) //turf already proceeded in A*
continue
if(istype(T) && !T.density)
@@ -390,11 +387,11 @@
return L
//Idem, but don't check for ID and goes through open doors
/turf/proc/AdjacentTurfs(var/list/closed)
/turf/proc/AdjacentTurfs(list/closed)
var/list/L = new()
var/turf/simulated/T
for(var/dir in list(NORTHWEST,NORTHEAST,SOUTHEAST,SOUTHWEST,NORTH,EAST,SOUTH,WEST)) //arbitrarily ordered list to favor non-diagonal moves in case of ties
T = get_step(src,dir)
for(var/dir in GLOB.alldirs2) //arbitrarily ordered list to favor non-diagonal moves in case of ties
T = get_step(src, dir)
if(T in closed) //turf already proceeded by A*
continue
if(istype(T) && !T.density)
@@ -403,11 +400,11 @@
return L
// check for all turfs, including unsimulated ones
/turf/proc/AdjacentTurfsSpace(var/obj/item/card/id/ID = null, var/list/closed)//check access if one is passed
/turf/proc/AdjacentTurfsSpace(obj/item/card/id/ID = null, list/closed)//check access if one is passed
var/list/L = new()
var/turf/T
for(var/dir in list(NORTHWEST,NORTHEAST,SOUTHEAST,SOUTHWEST,NORTH,EAST,SOUTH,WEST)) //arbitrarily ordered list to favor non-diagonal moves in case of ties
T = get_step(src,dir)
for(var/dir in GLOB.alldirs2) //arbitrarily ordered list to favor non-diagonal moves in case of ties
T = get_step(src, dir)
if(T in closed) //turf already proceeded by A*
continue
if(istype(T) && !T.density)
@@ -424,20 +421,21 @@
//////////////////////////////
//Distance associates with all directions movement
/turf/proc/Distance(var/turf/T)
return get_dist(src,T)
/turf/proc/Distance(turf/T)
return get_dist(src, T)
// This Distance proc assumes that only cardinal movement is
// possible. It results in more efficient (CPU-wise) pathing
// for bots and anything else that only moves in cardinal dirs.
/turf/proc/Distance_cardinal(turf/T)
if(!src || !T) return 0
if(!src || !T)
return 0
return abs(src.x - T.x) + abs(src.y - T.y)
////////////////////////////////////////////////////
/turf/acid_act(acidpwr, acid_volume)
. = 1
. = TRUE
var/acid_type = /obj/effect/acid
if(acidpwr >= 200) //alien acid power
acid_type = /obj/effect/acid/alien
@@ -462,7 +460,7 @@
if(!forced)
return
if(has_gravity(src))
playsound(src, "bodyfall", 50, 1)
playsound(src, "bodyfall", 50, TRUE)
/turf/singularity_act()
if(intact)
@@ -472,7 +470,7 @@
if(O.invisibility == INVISIBILITY_MAXIMUM)
O.singularity_act()
ChangeTurf(baseturf)
return(2)
return 2
/turf/proc/visibilityChanged()
if(SSticker)
@@ -483,25 +481,25 @@
if(istype(I, /obj/item/stack/cable_coil))
var/obj/item/stack/cable_coil/C = I
for(var/obj/structure/cable/LC in src)
if(LC.d1 == 0 || LC.d2==0)
LC.attackby(C,user)
if(LC.d1 == 0 || LC.d2 == 0)
LC.attackby(C, user)
return
C.place_turf(src, user)
return 1
return TRUE
else if(istype(I, /obj/item/twohanded/rcl))
var/obj/item/twohanded/rcl/R = I
if(R.loaded)
for(var/obj/structure/cable/LC in src)
if(LC.d1 == 0 || LC.d2==0)
if(LC.d1 == 0 || LC.d2 == 0)
LC.attackby(R, user)
return
R.loaded.place_turf(src, user)
R.is_empty(user)
return 0
return FALSE
/turf/proc/can_have_cabling()
return 1
return TRUE
/turf/proc/can_lay_cable()
return can_have_cabling() & !intact
@@ -537,7 +535,7 @@
if(!SSticker || SSticker.current_state != GAME_STATE_PLAYING)
add_blueprints(AM)
/turf/proc/empty(turf_type=/turf/space)
/turf/proc/empty(turf_type = /turf/space)
// Remove all atoms except observers, landmarks, docking ports, and (un)`simulated` atoms (lighting overlays)
var/turf/T0 = src
for(var/X in T0.GetAllContents())
@@ -550,13 +548,13 @@
continue
if(istype(A, /obj/docking_port))
continue
qdel(A, force=TRUE)
qdel(A, force = TRUE)
T0.ChangeTurf(turf_type)
SSair.remove_from_active(T0)
T0.CalculateAdjacentTurfs()
SSair.add_to_active(T0,1)
SSair.add_to_active(T0, TRUE)
/turf/AllowDrop()
return TRUE
+4 -5
View File
@@ -155,9 +155,8 @@
if(piece.siemens_coefficient > siemens_coefficient) //So that insulated gloves keep their insulation.
piece.siemens_coefficient = siemens_coefficient
piece.permeability_coefficient = permeability_coefficient
if(islist(armor))
var/list/L = armor
piece.armor = L.Copy()
if(armor)
piece.armor = armor
update_icon(1)
@@ -286,7 +285,7 @@
if(helmet)
helmet.update_light(wearer)
correct_piece.armor["bio"] = 100
correct_piece.armor = correct_piece.armor.setRating(bio_value = 100)
sealing = FALSE
@@ -389,7 +388,7 @@
if(helmet)
helmet.update_light(wearer)
correct_piece.armor["bio"] = armor["bio"]
correct_piece.armor = correct_piece.armor.setRating(bio_value = armor.getRating("bio"))
sealing = FALSE
@@ -9,13 +9,22 @@
multi *= (100 - chest.damage) / 100 //If we have some breaches, lower the armor value.
//TODO check for other armor mods, likely modules, which need to be coded.
if(!armor) //Did we even give them some armor, if this is the case, the list should be initialized from New()
return
var/datum/armor/A = armor
for(var/obj/item/piece in list(gloves, helmet, boots, chest))
if(!istype(piece)) //Do we have the piece
continue
if(islist(armor)) //Did we even give them some armor, if this is the case, the list should be initialized from New()
var/list/L = armor
for(var/armortype in L)
piece.armor[armortype] = L[armortype]*multi
piece.armor = piece.armor.setRating(melee_value = A.getRating("melee") * multi,
bullet_value = A.getRating("bullet") * multi,
laser_value = A.getRating("laser") * multi,
energy_value = A.getRating("energy") * multi,
bomb_value = A.getRating("bomb") * multi,
bio_value = A.getRating("bio") * multi,
rad_value = A.getRating("rad") * multi,
fire_value = A.getRating("fire") * multi,
acid_value = A.getRating("acidd") * multi)
//Perfect place to also add something like shield modules, or any other hit_reaction modules check.
@@ -37,8 +37,13 @@
var/mob/M = has_suit.loc
A.Grant(M)
for(var/armor_type in armor)
has_suit.armor[armor_type] += armor[armor_type]
if (islist(has_suit.armor) || isnull(has_suit.armor)) // This proc can run before /obj/Initialize has run for U and src,
has_suit.armor = getArmor(arglist(has_suit.armor)) // we have to check that the armor list has been transformed into a datum before we try to call a proc on it
// This is safe to do as /obj/Initialize only handles setting up the datum if actually needed.
if (islist(armor) || isnull(armor))
armor = getArmor(arglist(armor))
has_suit.armor = has_suit.armor.attachArmor(armor)
if(user)
to_chat(user, "<span class='notice'>You attach [src] to [has_suit].</span>")
@@ -56,8 +61,7 @@
var/mob/M = has_suit.loc
A.Remove(M)
for(var/armor_type in armor)
has_suit.armor[armor_type] -= armor[armor_type]
has_suit.armor = has_suit.armor.detachArmor(armor)
has_suit = null
if(user)
@@ -72,8 +72,8 @@
if(istype(H.head, /obj/item/clothing/head) && affecting == "head")
// If their head has an armor value, assign headarmor to it, else give it 0.
if(H.head.armor["melee"])
headarmor = H.head.armor["melee"]
if(H.head.armor.getRating("melee"))
headarmor = H.head.armor.getRating("melee")
else
headarmor = 0
else
@@ -226,7 +226,7 @@ Des: Removes all infected images from the alien.
/mob/living/carbon/alien/handle_footstep(turf/T)
if(..())
if(T.footstep_sounds["xeno"])
if(T.footstep_sounds && T.footstep_sounds["xeno"])
var/S = pick(T.footstep_sounds["xeno"])
if(S)
if(m_intent == MOVE_INTENT_RUN)
@@ -134,7 +134,7 @@ emp_act
if(bp && istype(bp ,/obj/item/clothing))
var/obj/item/clothing/C = bp
if(C.body_parts_covered & def_zone.body_part)
protection += C.armor[type]
protection += C.armor.getRating(type)
return protection
@@ -81,7 +81,7 @@
/mob/living/carbon/human/handle_footstep(turf/T)
if(..())
if(T.footstep_sounds["human"])
if(T.footstep_sounds && T.footstep_sounds["human"])
var/S = pick(T.footstep_sounds["human"])
if(S)
if(m_intent == MOVE_INTENT_RUN)
@@ -153,16 +153,16 @@
if(def_zone)
if(def_zone == "head")
if(inventory_head)
armorval = inventory_head.armor[type]
armorval = inventory_head.armor.getRating(type)
else
if(inventory_back)
armorval = inventory_back.armor[type]
armorval = inventory_back.armor.getRating(type)
return armorval
else
if(inventory_head)
armorval += inventory_head.armor[type]
armorval += inventory_head.armor.getRating(type)
if(inventory_back)
armorval += inventory_back.armor[type]
armorval += inventory_back.armor.getRating(type)
return armorval * 0.5
/mob/living/simple_animal/pet/dog/corgi/attackby(obj/item/O, mob/user, params)
@@ -62,8 +62,8 @@
is_zombie = TRUE
if(H.wear_suit)
var/obj/item/clothing/suit/armor/A = H.wear_suit
if(A.armor && A.armor["melee"])
maxHealth += A.armor["melee"] //That zombie's got armor, I want armor!
if(A.armor && A.armor.getRating("melee"))
maxHealth += A.armor.getRating("melee") //That zombie's got armor, I want armor!
maxHealth += 200
health = maxHealth
name = "zombie"
@@ -24,6 +24,7 @@
wires = new(src)
connected_parts = list()
update_icon()
use_log = list()
/obj/machinery/particle_accelerator/control_box/Destroy()
if(active)
+1
View File
@@ -260,6 +260,7 @@
#include "code\datums\action.dm"
#include "code\datums\ai_law_sets.dm"
#include "code\datums\ai_laws.dm"
#include "code\datums\armor.dm"
#include "code\datums\beam.dm"
#include "code\datums\browser.dm"
#include "code\datums\callback.dm"