From 0a17a2d0f127ef9ae1c4e815ab7b341f974fafd3 Mon Sep 17 00:00:00 2001 From: Pickle-Coding <58013024+Pickle-Coding@users.noreply.github.com> Date: Sun, 10 Mar 2024 19:49:26 +0000 Subject: [PATCH] Adds and improves logging for various shit. (#81738) ## About The Pull Request Adds logging for RCD construction and deconstruction. Hallucinated projectiles no longer causes logs. Flamethrowers log gas mixture information, the flamethrower, the gas tank, tank distribution pressure and whether it was lit. Adds a lot more logging to records consoles. Frozen objects now log when they get shattered. ## Why It's Good For The Game Closes #68452 Closes #71798 Closes #78008 Closes #81098 Closes #81130 ## Changelog :cl: Pickle-Coding and Rhials admin: RCD construction and deconstruction are logged. admin: Hallucinated projectiles no longer log. admin: Gives more detail to flamethrower logging. admin: More actions are logged for records consoles usage. admin: Frozen object shattering is logged. /:cl: --------- Co-authored-by: Rhials --- code/__HELPERS/atmospherics.dm | 7 +++ code/__HELPERS/logging/atmos.dm | 54 ++++++++++++++++--- code/datums/elements/frozen.dm | 6 ++- .../machinery/computer/records/records.dm | 2 + .../machinery/computer/records/security.dm | 15 ++++-- code/game/objects/items/flamethrower.dm | 3 +- code/game/objects/items/rcd/RCD.dm | 5 +- code/game/objects/items/tanks/tanks.dm | 4 +- .../atmospherics/gasmixtures/gas_mixture.dm | 4 +- code/modules/hallucination/stray_bullet.dm | 1 + code/modules/projectiles/projectile.dm | 15 +++--- 11 files changed, 92 insertions(+), 24 deletions(-) diff --git a/code/__HELPERS/atmospherics.dm b/code/__HELPERS/atmospherics.dm index 940418f2ebc..3ac3bfaed56 100644 --- a/code/__HELPERS/atmospherics.dm +++ b/code/__HELPERS/atmospherics.dm @@ -199,3 +199,10 @@ GLOBAL_LIST_EMPTY(gas_handbook) if(boundaries && boundaries[1] > 0) return FALSE return TRUE + +/proc/print_gas_mixture(datum/gas_mixture/gas_mixture) + var/message = "TEMPERATURE: [gas_mixture.temperature]K, QUANTITY: [gas_mixture.total_moles()] mols, VOLUME: [gas_mixture.volume]L; " + for(var/key in gas_mixture.gases) + var/list/gaslist = gas_mixture.gases[key] + message += "[gaslist[GAS_META][META_GAS_ID]]=[gaslist[MOLES]] mols;" + return message diff --git a/code/__HELPERS/logging/atmos.dm b/code/__HELPERS/logging/atmos.dm index 0fcded5c7ab..644c9e65625 100644 --- a/code/__HELPERS/logging/atmos.dm +++ b/code/__HELPERS/logging/atmos.dm @@ -1,8 +1,48 @@ /// Logs the contents of the gasmix to the game log, prefixed by text -/proc/log_atmos(text, datum/gas_mixture/mix) - var/message = text - message += "TEMP=[mix.temperature], MOL=[mix.total_moles()], VOL=[mix.volume] " - for(var/key in mix.gases) - var/list/gaslist = mix.gases[key] - message += "[gaslist[GAS_META][META_GAS_ID]]=[gaslist[MOLES]];" - log_game(message) +/proc/log_atmos(text, datum/gas_mixture/gas_mixture) + var/message = "[text]\"[print_gas_mixture(gas_mixture)]\"" + //Cache commonly accessed information. + var/list/gases = gas_mixture.gases //List of gas datum paths that are associated with a list of information related to the gases. + var/heat_capacity = gas_mixture.heat_capacity() + var/temperature = gas_mixture.return_temperature() + var/thermal_energy = temperature * heat_capacity + var/volume = gas_mixture.return_volume() + var/pressure = gas_mixture.return_pressure() + var/total_moles = gas_mixture.total_moles() + ///The total value of the gas mixture in credits. + var/total_value = 0 + var/list/specific_gas_data = list() + + //Gas specific information assigned to each gas. + for(var/datum/gas/gas_path as anything in gases) + var/list/gas = gases[gas_path] + var/moles = gas[MOLES] + var/composition = moles / total_moles + var/energy = temperature * moles * gas[GAS_META][META_GAS_SPECIFIC_HEAT] + var/value = initial(gas_path.base_value) * moles + total_value += value + specific_gas_data[gas[GAS_META][META_GAS_NAME]] = list( + "moles" = moles, + "composition" = composition, + "molar concentration" = moles / volume, + "partial pressure" = composition * pressure, + "energy" = energy, + "energy density" = energy / volume, + "value" = value, + ) + + log_game( + message, + data = list( + "total moles" = total_moles, + "volume" = volume, + "molar density" = total_moles / volume, + "temperature" = temperature, + "pressure" = pressure, + "heat capacity" = heat_capacity, + "energy" = thermal_energy, + "energy density" = thermal_energy / volume, + "value" = total_value, + "gases" = specific_gas_data, + ) + ) diff --git a/code/datums/elements/frozen.dm b/code/datums/elements/frozen.dm index b88cc2afa22..434968dd4d5 100644 --- a/code/datums/elements/frozen.dm +++ b/code/datums/elements/frozen.dm @@ -55,9 +55,13 @@ GLOBAL_LIST_INIT(freon_color_matrix, list("#2E5E69", "#60A2A8", "#A1AFB1", rgb(0 Detach(source) ///signal handler for COMSIG_MOVABLE_POST_THROW that shatters our target after impacting after a throw -/datum/element/frozen/proc/shatter_on_throw(datum/target) +/datum/element/frozen/proc/shatter_on_throw(datum/target, datum/thrownthing/throwingdatum) SIGNAL_HANDLER var/obj/obj_target = target + if(ismob(throwingdatum.thrower)) + log_combat(throwingdatum.thrower, target, "shattered", addition = "from being thrown due to [target] being frozen.") + else + log_combat(throwingdatum.thrower, target, "launched", addition = "shattering it due to being frozen.") obj_target.visible_message(span_danger("[obj_target] shatters into a million pieces!")) obj_target.obj_flags |= NO_DECONSTRUCTION // disable item spawning obj_target.deconstruct(FALSE) // call pre-deletion specialized code -- internals release gas etc diff --git a/code/game/machinery/computer/records/records.dm b/code/game/machinery/computer/records/records.dm index a1292bb5e86..76ee1f19bca 100644 --- a/code/game/machinery/computer/records/records.dm +++ b/code/game/machinery/computer/records/records.dm @@ -35,6 +35,7 @@ return FALSE var/value = trim(params["value"], MAX_BROADCAST_LEN) + investigate_log("[key_name(usr)] changed the field: \"[field]\" with value: \"[target.vars[field]]\" to new value: \"[value || "Unknown"]\"", INVESTIGATE_RECORDS) target.vars[field] = value || "Unknown" return TRUE @@ -56,6 +57,7 @@ if("login") authenticated = secure_login(usr) + investigate_log("[key_name(usr)] [authenticated ? "successfully logged" : "failed to log"] into the [src].", INVESTIGATE_RECORDS) return TRUE if("logout") diff --git a/code/game/machinery/computer/records/security.dm b/code/game/machinery/computer/records/security.dm index 27b8e75e545..6e44d112b4b 100644 --- a/code/game/machinery/computer/records/security.dm +++ b/code/game/machinery/computer/records/security.dm @@ -159,6 +159,7 @@ return TRUE if("delete_record") + investigate_log("[usr] deleted record: \"[target]\".", INVESTIGATE_RECORDS) qdel(target) return TRUE @@ -175,8 +176,9 @@ return TRUE if("set_note") - var/note = params["note"] - target.security_note = trim(note, MAX_MESSAGE_LEN) + var/note = trim(params["note"], MAX_MESSAGE_LEN) + investigate_log("[usr] has changed the security note of record: \"[target]\" from \"[target.security_note]\" to \"[note]\".") + target.security_note = note return TRUE if("set_wanted") @@ -239,14 +241,19 @@ return FALSE if(user != editing_crime.author && !has_armory_access(user)) // only warden/hos/command can edit crimes they didn't author + investigate_log("[user] attempted to edit crime: \"[editing_crime.name]\" for target: \"[target.name]\" but failed due to lacking armoury access and not being the author of the crime.", INVESTIGATE_RECORDS) return FALSE if(params["name"] && length(params["name"]) > 2 && params["name"] != editing_crime.name) - editing_crime.name = trim(params["name"], MAX_CRIME_NAME_LEN) + var/new_name = trim(params["name"], MAX_CRIME_NAME_LEN) + investigate_log("[user] edited crime: \"[editing_crime.name]\" for target: \"[target.name]\", changing the name to: \"[new_name]\".", INVESTIGATE_RECORDS) + editing_crime.name = new_name return TRUE if(params["details"] && length(params["description"]) > 2 && params["name"] != editing_crime.name) - editing_crime.details = trim(params["details"], MAX_MESSAGE_LEN) + var/new_details = trim(params["details"], MAX_MESSAGE_LEN) + investigate_log("[user] edited crime \"[editing_crime.name]\" for target: \"[target.name]\", changing the details to: \"[new_details]\" from: \"[editing_crime.details]\".", INVESTIGATE_RECORDS) + editing_crime.details = new_details return TRUE return FALSE diff --git a/code/game/objects/items/flamethrower.dm b/code/game/objects/items/flamethrower.dm index f7ed18da053..1564e4e4029 100644 --- a/code/game/objects/items/flamethrower.dm +++ b/code/game/objects/items/flamethrower.dm @@ -85,12 +85,13 @@ return // too close if(HAS_TRAIT(user, TRAIT_PACIFISM)) to_chat(user, span_warning("You can't bring yourself to fire \the [src]! You don't want to risk harming anyone...")) + log_combat(user, target, "attempted to flamethrower", src, "with gas mixture: {[print_gas_mixture(ptank.return_analyzable_air())]}, flamethrower: \"[name]\" ([src]), igniter: \"[igniter.name]\", tank: \"[ptank.name]\" and tank distribution pressure: \"[siunit(1000 * ptank.distribute_pressure, unit = "Pa", maxdecimals = INFINITY)]\"" + lit ? " while lit" : "" + " but failed due to pacifism.") return if(user && user.get_active_held_item() == src) // Make sure our user is still holding us var/turf/target_turf = get_turf(target) if(target_turf) var/turflist = get_line(user, target_turf) - log_combat(user, target, "flamethrowered", src) + log_combat(user, target, "flamethrowered", src, "with gas mixture: {[print_gas_mixture(ptank.return_analyzable_air())]}, flamethrower: \"[name]\", igniter: \"[igniter.name]\", tank: \"[ptank.name]\" and tank distribution pressure: \"[siunit(1000 * ptank.distribute_pressure, unit = "Pa", maxdecimals = INFINITY)]\"" + lit ? " while lit." : ".") flame_turf(turflist) /obj/item/flamethrower/wrench_act(mob/living/user, obj/item/tool) diff --git a/code/game/objects/items/rcd/RCD.dm b/code/game/objects/items/rcd/RCD.dm index 9570614b400..025571a90a7 100644 --- a/code/game/objects/items/rcd/RCD.dm +++ b/code/game/objects/items/rcd/RCD.dm @@ -219,7 +219,10 @@ delay *= FREQUENT_USE_DEBUFF_MULTIPLIER current_active_effects += 1 - _rcd_create_effect(target, user, delay, rcd_results) + var/target_name = target.name //Store the name before it gets mutated due to deconstruction. + var/target_path = target.type + if(_rcd_create_effect(target, user, delay, rcd_results)) + log_tool("used RCD with design path: \"[rcd_results["[RCD_DESIGN_MODE]"] == RCD_DECONSTRUCT ? "deconstruction" : rcd_results["[RCD_DESIGN_PATH]"]]\" with delay: \"[delay / (1 SECONDS)]s\" at target: \"[target_name] ([target_path])\" in location: \"[AREACOORD(target)]\".", user) current_active_effects -= 1 /** diff --git a/code/game/objects/items/tanks/tanks.dm b/code/game/objects/items/tanks/tanks.dm index a670a966805..e198f7d75d7 100644 --- a/code/game/objects/items/tanks/tanks.dm +++ b/code/game/objects/items/tanks/tanks.dm @@ -440,7 +440,7 @@ if(LAZYLEN(assembly.assemblies) == igniter_count) return - + if(isitem(loc)) // we are in a storage item balloon_alert(user, "can't reach!") return @@ -553,7 +553,7 @@ var/turf/T = get_turf(src) if(!T) return - log_atmos("[type] released its contents of ", air_contents) + log_atmos("[type] released its contents of ", removed) T.assume_air(removed) #undef ASSEMBLY_BOMB_BASE diff --git a/code/modules/atmospherics/gasmixtures/gas_mixture.dm b/code/modules/atmospherics/gasmixtures/gas_mixture.dm index 87523034f3e..cfb87ce7cb3 100644 --- a/code/modules/atmospherics/gasmixtures/gas_mixture.dm +++ b/code/modules/atmospherics/gasmixtures/gas_mixture.dm @@ -184,7 +184,7 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache()) if(amount <= 0) return null var/ratio = amount / sum - var/datum/gas_mixture/removed = new type + var/datum/gas_mixture/removed = new type(volume) var/list/removed_gases = removed.gases //accessing datum vars is slower than proc vars removed.temperature = temperature @@ -206,7 +206,7 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache()) ratio = min(ratio, 1) var/list/cached_gases = gases - var/datum/gas_mixture/removed = new type + var/datum/gas_mixture/removed = new type(volume) var/list/removed_gases = removed.gases //accessing datum vars is slower than proc vars removed.temperature = temperature diff --git a/code/modules/hallucination/stray_bullet.dm b/code/modules/hallucination/stray_bullet.dm index 97f75f95061..9281bc65343 100644 --- a/code/modules/hallucination/stray_bullet.dm +++ b/code/modules/hallucination/stray_bullet.dm @@ -34,6 +34,7 @@ damage = 0 projectile_type = /obj/projectile/hallucination log_override = TRUE + do_not_log = TRUE /// Our parent hallucination that's created us var/datum/hallucination/parent /// The image that represents our projectile itself diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index 682baac7927..d1dd5364477 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -182,6 +182,8 @@ var/catastropic_dismemberment = FALSE //If TRUE, this projectile deals its damage to the chest if it dismembers a limb. var/impact_effect_type //what type of impact effect to show when hitting something var/log_override = FALSE //is this type spammed enough to not log? (KAs) + /// If true, the projectile won't cause any logging. Used for hallucinations and shit. + var/do_not_log = FALSE /// We ignore mobs with these factions. var/list/ignored_factions @@ -359,7 +361,7 @@ if(reagents?.reagent_list) reagent_note = "REAGENTS: [pretty_string_from_reagent_list(reagents.reagent_list)]" - if(ismob(firer)) + if(ismob(firer) && !do_not_log) log_combat(firer, living_target, "shot", src, reagent_note) return BULLET_ACT_HIT @@ -369,11 +371,12 @@ var/list/logging_mobs = firing_vehicle.return_controllers_with_flag(VEHICLE_CONTROL_EQUIPMENT) if(!LAZYLEN(logging_mobs)) logging_mobs = firing_vehicle.return_drivers() - for(var/mob/logged_mob as anything in logging_mobs) - log_combat(logged_mob, living_target, "shot", src, "from inside [firing_vehicle][logging_mobs.len > 1 ? " with multiple occupants" : null][reagent_note ? " and contained [reagent_note]" : null]") + if(!do_not_log) + for(var/mob/logged_mob as anything in logging_mobs) + log_combat(logged_mob, living_target, "shot", src, "from inside [firing_vehicle][logging_mobs.len > 1 ? " with multiple occupants" : null][reagent_note ? " and contained [reagent_note]" : null]") return BULLET_ACT_HIT - - living_target.log_message("has been shot by [firer] with [src][reagent_note ? " containing [reagent_note]" : null]", LOG_ATTACK, color="orange") + if(!do_not_log) + living_target.log_message("has been shot by [firer] with [src][reagent_note ? " containing [reagent_note]" : null]", LOG_ATTACK, color="orange") return BULLET_ACT_HIT /obj/projectile/proc/vol_by_damage() @@ -771,7 +774,7 @@ SEND_SIGNAL(fired_from, COMSIG_PROJECTILE_BEFORE_FIRE, src, original) if(firer) SEND_SIGNAL(firer, COMSIG_PROJECTILE_FIRER_BEFORE_FIRE, src, fired_from, original) - if(!log_override && firer && original) + if(!log_override && firer && original && !do_not_log) log_combat(firer, original, "fired at", src, "from [get_area_name(src, TRUE)]") //note: mecha projectile logging is handled in /obj/item/mecha_parts/mecha_equipment/weapon/action(). try to keep these messages roughly the sameish just for consistency's sake. if(direct_target && (get_dist(direct_target, get_turf(src)) <= 1)) // point blank shots