[MIRROR] Fixing Energy Gun Weapon Description Runtimes + Miscellaneous Weapon Description Fixes, Take 2 (#6850)

* Fixing Energy Gun Weapon Description Runtimes + Miscellaneous Weapon Description Fixes, Take 2 (#59778)

Fixes a runtime issue cause by the possibility of loaded_projectile being null by changing how projectile stats are obtained on energy weapons, and adds a separate line for energy ammo types that deal stamina damage and regular damage to incorporate both damage types

* Fixing Energy Gun Weapon Description Runtimes + Miscellaneous Weapon Description Fixes, Take 2

Co-authored-by: Beatrice <83368538+SpaceDragon00@users.noreply.github.com>
This commit is contained in:
SkyratBot
2021-07-12 21:45:06 +01:00
committed by GitHub
co-authored by Beatrice
parent 7bf75d0ff0
commit 22a02bc61b
10 changed files with 66 additions and 32 deletions
+9
View File
@@ -101,6 +101,8 @@
make_skyrat_datum_references() //SKYRAT EDIT ADDITION - CUSTOMIZATION
init_crafting_recipes(GLOB.crafting_recipes)
init_subtypes_w_path_keys(/obj/projectile, GLOB.proj_by_path_key)
/// Inits the crafting recipe list, sorting crafting recipe requirements in the process.
/proc/init_crafting_recipes(list/crafting_recipes)
for(var/path in subtypesof(/datum/crafting_recipe))
@@ -127,3 +129,10 @@
L+= path
return L
/// Functions like init_subtypes, but uses the subtype's path as a key for easy access
/proc/init_subtypes_w_path_keys(prototype, list/L)
if(!istype(L))
L = list()
for(var/path as anything in subtypesof(prototype))
L[path] = new path()
return L
+2
View File
@@ -34,3 +34,5 @@ GLOBAL_VAR_INIT(glowshrooms, 0)
/// If drones are blacklisted from certain sensitive machines
GLOBAL_VAR_INIT(drone_machine_blacklist_enabled, TRUE)
GLOBAL_LIST_EMPTY_TYPED(proj_by_path_key, /obj/projectile) // A list of projectile objects, which are keyed by their path
+5 -4
View File
@@ -1,6 +1,7 @@
#define HITS_TO_CRIT(damage) round(100 / damage, 0.1)
/**
*
* The purpose of this element is to widely provide the ability to examine an object and determine its damage, with the ability to add
* The purpose of this element is to widely provide the ability to examine an object and determine its stats, with the ability to add
* additional notes or information based on type or other factors
*
*/
@@ -42,7 +43,7 @@
/datum/element/weapon_description/proc/warning_label(obj/item/item, mob/user, list/examine_texts)
SIGNAL_HANDLER
if(item.force >= 5 || item.throwforce >= 5 || item.override_notes || item.offensive_notes) /// Only show this tag for items that could feasibly be weapons, shields, or those that have special notes
if(item.force >= 5 || item.throwforce >= 5 || item.override_notes || item.offensive_notes || attached_proc) /// Only show this tag for items that could feasibly be weapons, shields, or those that have special notes
examine_texts += span_notice("It appears to have an ever-updating bluespace <a href='?src=[REF(item)];examine=1'>warning label.</a>")
/**
@@ -82,12 +83,12 @@
if(!source.override_notes)
// Make sure not to divide by 0 on accident
if(source.force > 0)
readout += "Our extensive research has shown that it takes a mere [span_warning("[round((100 / source.force), 0.1)]")] hit\s to beat down [victims[rand(1, victims.len)]] with no armor."
readout += "Our extensive research has shown that it takes a mere [span_warning("[HITS_TO_CRIT(source.force)] hit\s")] to beat down [victims[rand(1, victims.len)]] with no armor."
else
readout += "Our extensive research found that you couldn't beat anyone to death with this if you tried."
if(source.throwforce > 0)
readout += "If you decide to throw this object instead, one will take [span_warning("[round((100 / source.throwforce), 0.1)]")] hit\s before collapsing."
readout += "If you decide to throw this object instead, one will take [span_warning("[HITS_TO_CRIT(source.throwforce)] hit\s")] before collapsing."
else
readout += "If you decide to throw this object instead, then you will have trouble damaging anything."
if(source.armour_penetration > 0 || source.block_chance > 0)
+1 -4
View File
@@ -241,10 +241,7 @@ GLOBAL_DATUM_INIT(fire_overlay, /mutable_appearance, mutable_appearance('icons/e
qdel(X)
return ..()
/*
* Adds the weapon_description element, which shows the warning label for especially dangerous objects.
* Made to be overridden by item subtypes that require specific notes outside of the scope of offensive_notes
*/
/// Adds the weapon_description element, which shows the 'warning label' for especially dangerous objects. Override this for item types with special notes.
/obj/item/proc/add_weapon_description()
AddElement(/datum/element/weapon_description)
@@ -167,7 +167,6 @@
icon_locking = "safeb"
icon_sparking = "safespark"
desc = "Excellent for securing things away from grubby hands."
force = 8
w_class = WEIGHT_CLASS_GIGANTIC
anchored = TRUE
density = FALSE
@@ -169,6 +169,8 @@
/obj/structure/closet/proc/take_contents()
var/atom/L = drop_location()
if(!L)
return
for(var/atom/movable/AM in L)
if(AM != src && insert(AM) == LOCKER_FULL) // limit reached
break
@@ -68,20 +68,20 @@
*
*/
/obj/item/ammo_casing/proc/add_notes_ammo()
// Make sure there is actually something IN the casing
if(loaded_projectile)
var/list/readout = list("")
// No dividing by 0
if(loaded_projectile.damage > 0)
readout += "Most monkeys our legal team subjected to these rounds succumbed to their wounds after [span_warning("[round(100 / (loaded_projectile.damage * pellets), 0.1)]")] discharge\s at point-blank, taking [span_warning("[pellets]")] shot\s per round"
if(loaded_projectile.stamina > 0)
readout += "[loaded_projectile.damage == 0 ? "Most Monkeys" : "More Fortunate Monkeys" ] collapsed from exhaustion after [span_warning("[round(100 / ((loaded_projectile.damage + loaded_projectile.stamina) * pellets), 0.1)]")] of these rounds"
if(loaded_projectile.damage == 0 && loaded_projectile.stamina == 0)
return "Our legal team has determined the offensive nature of these rounds to be esoteric"
return readout.Join("\n") // Sending over a single string, rather than the whole list
else
// Labels don't do well with extreme forces
return "The warning label was blown away..."
// Try to get a projectile to derive stats from
var/obj/projectile/exam_proj = GLOB.proj_by_path_key[projectile_type]
if(!istype(exam_proj) || pellets == 0)
return
var/list/readout = list()
// No dividing by 0
if(exam_proj.damage > 0)
readout += "Most monkeys our legal team subjected to these [span_warning(caliber)] rounds succumbed to their wounds after [span_warning("[HITS_TO_CRIT(exam_proj.damage * pellets)] shot\s")] at point-blank, taking [span_warning("[pellets] shot\s")] per round"
if(exam_proj.stamina > 0)
readout += "[!readout.len ? "Most monkeys" : "More fortunate monkeys"] collapsed from exhaustion after [span_warning("[HITS_TO_CRIT(exam_proj.stamina * pellets)] impact\s")] of these [span_warning("[caliber]")] rounds"
if(!readout.len) // Everything else failed, give generic text
return "Our legal team has determined the offensive nature of these [span_warning(caliber)] rounds to be esoteric"
return readout.Join("\n") // Sending over a single string, rather than the whole list
/obj/item/ammo_casing/update_icon_state()
icon_state = "[initial(icon_state)][loaded_projectile ? "-live" : null]"
@@ -14,6 +14,7 @@
w_class = WEIGHT_CLASS_TINY
throw_speed = 3
throw_range = 7
override_notes = TRUE
///list containing the actual ammo within the magazine
var/list/stored_ammo = list()
///type that the magazine will be searching for, rejects if not a subtype of
@@ -41,6 +42,23 @@
if(!start_empty)
top_off(starting=TRUE)
/obj/item/ammo_box/add_weapon_description()
AddElement(/datum/element/weapon_description, attached_proc = .proc/add_notes_box)
/obj/item/ammo_box/proc/add_notes_box()
var/list/readout = list()
if(caliber && max_ammo) // Text references a 'magazine' as only magazines generally have the caliber variable initialized
readout += "Up to [span_warning("[max_ammo] [caliber] rounds")] can be found within this magazine. \
\nAccidentally discharging any of these projectiles may void your insurance contract."
var/obj/item/ammo_casing/mag_ammo = get_round(TRUE)
if(istype(mag_ammo))
readout += "\n[mag_ammo.add_notes_ammo()]"
return readout.Join("\n")
/**
* top_off is used to refill the magazine to max, in case you want to increase the size of a magazine with VV then refill it at once
*
+2 -2
View File
@@ -141,8 +141,8 @@
*
*/
/obj/item/gun/ballistic/proc/add_notes_ballistic()
if(magazine) // Make sure you have a magazine, thats where the warning is!
return "\nBe especially careful around this device, as it can be loaded with [span_warning("[magazine.caliber]")] rounds, which you can inspect for more information."
if(magazine) // Make sure you have a magazine, to get the notes from
return "\n[magazine.add_notes_box()]"
else
return "\nThe warning attached to the magazine is missing..."
+13 -7
View File
@@ -59,19 +59,25 @@
*
*/
/obj/item/gun/energy/proc/add_notes_energy()
var/list/readout = list("")
var/list/readout = list()
// Make sure there is something to actually retrieve
if(!ammo_type)
if(!ammo_type.len)
return
var/obj/projectile/exam_proj
readout += "Standard models of this projectile weapon have [span_warning("[ammo_type.len]")] mode\s"
readout += "\nStandard models of this projectile weapon have [span_warning("[ammo_type.len] mode\s")]"
readout += "Our heroic interns have shown that one can theoretically stay standing after..."
for(var/obj/item/ammo_casing/energy/for_ammo in ammo_type)
exam_proj = for_ammo.loaded_projectile
for(var/obj/item/ammo_casing/energy/for_ammo as anything in ammo_type)
exam_proj = GLOB.proj_by_path_key[for_ammo?.projectile_type]
if(!istype(exam_proj))
continue
if(exam_proj.damage > 0) // Don't divide by 0!!!!!
readout += "[span_warning("[round(100 / exam_proj.damage, 0.1)]")] shot\s on [span_warning("[for_ammo.select_name]")] mode before collapsing from [exam_proj.damage_type == STAMINA ? "immense pain" : "their wounds"]."
readout += "[span_warning("[HITS_TO_CRIT(exam_proj.damage)] shot\s")] on [span_warning("[for_ammo.select_name]")] mode before collapsing from [exam_proj.damage_type == STAMINA ? "immense pain" : "their wounds"]."
if(exam_proj.stamina > 0) // In case a projectile does damage AND stamina damage (Energy Crossbow)
readout += "[span_warning("[HITS_TO_CRIT(exam_proj.stamina)] shot\s")] on [span_warning("[for_ammo.select_name]")] mode before collapsing from immense pain."
else
readout += "an infinite number of shots on [span_warning("[for_ammo.select_name] mode")]."
readout += "a theoretically infinite number of shots on [span_warning("[for_ammo.select_name]")] mode."
return readout.Join("\n") // Sending over the singular string, rather than the whole list
/obj/item/gun/energy/ComponentInitialize()