diff --git a/code/__DEFINES/admin/keybindings.dm b/code/__DEFINES/admin/keybindings.dm index fcfe7c5e58..e8616fd3ce 100644 --- a/code/__DEFINES/admin/keybindings.dm +++ b/code/__DEFINES/admin/keybindings.dm @@ -1,6 +1,6 @@ // Defines for managed input/keybinding system. /// Max length of a keypress command before it's considered to be a forged packet/bogus command -#define MAX_KEYPRESS_COMMANDLENGTH 32 +#define MAX_KEYPRESS_COMMANDLENGTH 64 /// Maximum keys that can be bound to one button #define MAX_COMMANDS_PER_KEY 5 /// Maximum keys per keybind diff --git a/code/controllers/subsystem/persistence.dm b/code/controllers/subsystem/persistence.dm index 5b60747725..e1b6e6f6e2 100644 --- a/code/controllers/subsystem/persistence.dm +++ b/code/controllers/subsystem/persistence.dm @@ -48,25 +48,6 @@ SUBSYSTEM_DEF(persistence) /datum/controller/subsystem/persistence/proc/LoadSatchels() var/placed_satchel = 0 var/path - if(fexists("data/npc_saves/SecretSatchels.sav")) //legacy conversion. Will only ever run once. - var/savefile/secret_satchels = new /savefile("data/npc_saves/SecretSatchels.sav") - for(var/map in secret_satchels) - var/json_file = file("data/npc_saves/SecretSatchels[map].json") - var/list/legacy_secret_satchels = splittext(secret_satchels[map],"#") - var/list/satchels = list() - for(var/i=1,i<=legacy_secret_satchels.len,i++) - var/satchel_string = legacy_secret_satchels[i] - var/list/chosen_satchel = splittext(satchel_string,"|") - if(chosen_satchel.len == 3) - var/list/data = list() - data["x"] = text2num(chosen_satchel[1]) - data["y"] = text2num(chosen_satchel[2]) - data["saved_obj"] = chosen_satchel[3] - satchels += list(data) - var/list/file_data = list() - file_data["data"] = satchels - WRITE_FILE(json_file, json_encode(file_data)) - fdel("data/npc_saves/SecretSatchels.sav") var/json_file = file("data/npc_saves/SecretSatchels[SSmapping.config.map_name].json") var/list/json = list() diff --git a/code/datums/mutations/_mutations.dm b/code/datums/mutations/_mutations.dm index fb5f6ed5f6..3bddfdaa63 100644 --- a/code/datums/mutations/_mutations.dm +++ b/code/datums/mutations/_mutations.dm @@ -11,7 +11,7 @@ var/lowest_value = 256 * 8 var/text_gain_indication = "" var/text_lose_indication = "" - var/list/mutable_appearance/visual_indicators = list() + var/list/visual_indicators = list() var/obj/effect/proc_holder/spell/power var/layer_used = MUTATIONS_LAYER //which mutation layer to use var/list/species_allowed = list() //to restrict mutation to only certain species diff --git a/code/datums/wires/airlock.dm b/code/datums/wires/airlock.dm index 179adf46bd..9af78b0090 100644 --- a/code/datums/wires/airlock.dm +++ b/code/datums/wires/airlock.dm @@ -71,7 +71,7 @@ /datum/wires/airlock/on_pulse(wire) set waitfor = FALSE var/obj/machinery/door/airlock/A = holder - if(!A.hasSiliconAccessInArea(usr) && A.isElectrified() && A.shock(usr, 100)) + if(usr && !A.hasSiliconAccessInArea(usr) && A.isElectrified() && A.shock(usr, 100)) return FALSE switch(wire) if(WIRE_POWER1, WIRE_POWER2) // Pulse to loose power. @@ -127,7 +127,7 @@ /datum/wires/airlock/on_cut(wire, mend) var/obj/machinery/door/airlock/A = holder - if(!A.hasSiliconAccessInArea(usr) && A.isElectrified() && A.shock(usr, 100)) + if(usr && !A.hasSiliconAccessInArea(usr) && A.isElectrified() && A.shock(usr, 100)) return FALSE switch(wire) if(WIRE_POWER1, WIRE_POWER2) // Cut to loose power, repair all to gain power. diff --git a/code/game/area/Space_Station_13_areas.dm b/code/game/area/Space_Station_13_areas.dm index cbad2f7ab0..5310b24202 100644 --- a/code/game/area/Space_Station_13_areas.dm +++ b/code/game/area/Space_Station_13_areas.dm @@ -43,6 +43,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station outdoors = TRUE ambientsounds = SPACE blob_allowed = FALSE //Eating up space doesn't count for victory as a blob. + considered_hull_exterior = TRUE /area/space/nearstation icon_state = "space_near" @@ -1592,4 +1593,4 @@ NOTE: there are two lists of areas in the end of this file: centcom and station valid_territory = FALSE outdoors = TRUE ambientsounds = SPACE - blob_allowed = FALSE //While part of the station, what good will it do you? \ No newline at end of file + blob_allowed = FALSE //While part of the station, what good will it do you? diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm index 672d5c096f..b9415f3cf8 100644 --- a/code/game/area/areas.dm +++ b/code/game/area/areas.dm @@ -34,6 +34,9 @@ /// If megafauna can be spawned by natural random generation var/megafauna_spawn_allowed = FALSE + /// Considered space for hull shielding + var/considered_hull_exterior = FALSE + var/fire = null var/atmos = TRUE var/atmosalm = FALSE diff --git a/code/game/objects/items/devices/portable_chem_mixer.dm b/code/game/objects/items/devices/portable_chem_mixer.dm index 25ecef5955..3e1b20cfc2 100644 --- a/code/game/objects/items/devices/portable_chem_mixer.dm +++ b/code/game/objects/items/devices/portable_chem_mixer.dm @@ -113,8 +113,7 @@ if (loc != user) return ..() if(SEND_SIGNAL(src, COMSIG_IS_STORAGE_LOCKED)) - ui_interact(user) - return + INVOKE_ASYNC(src, /datum.proc/ui_interact, user) /obj/item/storage/portable_chem_mixer/attack_self(mob/user) if(loc == user) diff --git a/code/game/objects/items/stacks/medical.dm b/code/game/objects/items/stacks/medical.dm index 7ba2196184..a96b0104f1 100644 --- a/code/game/objects/items/stacks/medical.dm +++ b/code/game/objects/items/stacks/medical.dm @@ -269,8 +269,8 @@ to_chat(user, "[M] is at full health.") return FALSE user.visible_message("[user] applies \the [src] on [M].", "You apply \the [src] on [M].") - return heal_carbon(M, user, heal_brute, heal_burn) - + M.heal_bodypart_damage(heal_brute) + return TRUE to_chat(user, "You can't heal [M] with \the [src]!") /obj/item/stack/medical/ointment diff --git a/code/game/objects/obj_defense.dm b/code/game/objects/obj_defense.dm index bcdf509fbe..3de28b38e8 100644 --- a/code/game/objects/obj_defense.dm +++ b/code/game/objects/obj_defense.dm @@ -204,9 +204,6 @@ GLOBAL_DATUM_INIT(acid_overlay, /mutable_appearance, mutable_appearance('icons/e /obj/proc/acid_processing() . = 1 if(!(resistance_flags & ACID_PROOF)) - for(var/armour_value in armor) - if(armour_value != "acid" && armour_value != "fire") - armor = armor.modifyAllRatings(0 - round(sqrt(acid_level)*0.1)) if(prob(33)) playsound(loc, 'sound/items/welder.ogg', 150, 1) take_damage(min(1 + round(sqrt(acid_level)*0.3), 300), BURN, "acid", 0) diff --git a/code/game/turfs/simulated/walls.dm b/code/game/turfs/simulated/walls.dm index 9ff4f668a4..402ab36947 100644 --- a/code/game/turfs/simulated/walls.dm +++ b/code/game/turfs/simulated/walls.dm @@ -138,7 +138,7 @@ if(prob(hardness)) playsound(src, 'sound/effects/meteorimpact.ogg', 100, TRUE) user.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" ), forced = "hulk") - hulk_recoil(arm, user) + //hulk_recoil(arm, user) // citadel edit - no, hulks are already subject to stamina combat dismantle_wall(1) else diff --git a/code/modules/antagonists/bloodsucker/powers/brawn.dm b/code/modules/antagonists/bloodsucker/powers/brawn.dm index cf0393ff3a..5444cccd3f 100644 --- a/code/modules/antagonists/bloodsucker/powers/brawn.dm +++ b/code/modules/antagonists/bloodsucker/powers/brawn.dm @@ -1,7 +1,7 @@ /datum/action/bloodsucker/targeted/brawn - name = "Brawn"//"Cellular Emporium" + name = "Brawn" desc = "Snap restraints with ease, or deal terrible damage with your bare hands." button_icon_state = "power_strength" bloodcost = 10 @@ -107,8 +107,6 @@ if(user_C.handcuffed) var/obj/O = user_C.get_item_by_slot(SLOT_HANDCUFFED) if(istype(O)) - //user_C.visible_message("[user_C] attempts to remove [O]!", \ - // "You snap [O] like it's nothing!") user_C.clear_cuffs(O,TRUE) playsound(get_turf(usr), 'sound/effects/grillehit.ogg', 80, 1, -1) return TRUE @@ -128,8 +126,6 @@ if(user_C.legcuffed) var/obj/O = user_C.get_item_by_slot(SLOT_LEGCUFFED) if(istype(O)) - //user_C.visible_message("[user_C] attempts to remove [O]!", \ - // "You snap [O] like it's nothing!") user_C.clear_cuffs(O,TRUE) playsound(get_turf(usr), 'sound/effects/grillehit.ogg', 80, 1, -1) return TRUE diff --git a/code/modules/antagonists/bloodsucker/powers/feed.dm b/code/modules/antagonists/bloodsucker/powers/feed.dm index caca020b32..81ebdbe4e2 100644 --- a/code/modules/antagonists/bloodsucker/powers/feed.dm +++ b/code/modules/antagonists/bloodsucker/powers/feed.dm @@ -165,8 +165,8 @@ // Broadcast Message if(amSilent) //if (!iscarbon(target)) - // user.visible_message("[user] shifts [target] closer to [user.p_their()] mouth.", \ - // "You secretly slip your fangs into [target]'s flesh.", \ + // user.visible_message("[user] shifts [target] closer to [user.p_their()] mouth.", + // "You secretly slip your fangs into [target]'s flesh.", // vision_distance = 2, ignored_mobs=target) // Only people who AREN'T the target will notice this action. //else var/deadmessage = target.stat == DEAD ? "" : " [target.p_they(TRUE)] looks dazed, and will not remember this." diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index 664e8fc8b4..e62b8c1619 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -1411,6 +1411,9 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) var/obj/item/bodypart/affecting = target.get_bodypart(ran_zone(user.zone_selected)) + if(!affecting) //Maybe the bodypart is missing? Or things just went wrong.. + affecting = target.get_bodypart(BODY_ZONE_CHEST) //target chest instead, as failsafe. Or hugbox? You decide. + var/miss_chance = 100//calculate the odds that a punch misses entirely. considers stamina and brute damage of the puncher. punches miss by default to prevent weird cases if(attackchain_flags & ATTACK_IS_PARRY_COUNTERATTACK) miss_chance = 0 @@ -1626,6 +1629,10 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) /datum/species/proc/spec_attacked_by(obj/item/I, mob/living/user, obj/item/bodypart/affecting, intent, mob/living/carbon/human/H, attackchain_flags = NONE, damage_multiplier = 1) var/totitemdamage = H.pre_attacked_by(I, user) * damage_multiplier + + if(!affecting) //Something went wrong. Maybe the limb is missing? + affecting = H.get_bodypart(BODY_ZONE_CHEST) //If the limb is missing, or something went terribly wrong, just hit the chest instead + // Allows you to put in item-specific reactions based on species if(user != H) var/list/block_return = list() @@ -1637,8 +1644,6 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) return 0 var/hit_area - if(!affecting) //Something went wrong. Maybe the limb is missing? - affecting = H.bodyparts[1] hit_area = affecting.name var/def_zone = affecting.body_zone diff --git a/code/modules/paperwork/ticketmachine.dm b/code/modules/paperwork/ticketmachine.dm index e46ed64971..0e553ced35 100644 --- a/code/modules/paperwork/ticketmachine.dm +++ b/code/modules/paperwork/ticketmachine.dm @@ -162,6 +162,9 @@ /obj/machinery/ticket_machine/attack_hand(mob/living/carbon/user) . = ..() + INVOKE_ASYNC(src, .proc/attempt_ticket, user) + +/obj/machinery/ticket_machine/proc/attempt_ticket(mob/living/carbon/user) if(!ready) to_chat(user,"You press the button, but nothing happens...") return @@ -195,7 +198,7 @@ /obj/item/ticket_machine_ticket name = "Ticket" - desc = "A ticket which shows your place in the Head of Personnel's line. Made from Nanotrasen patented NanoPaper®. Though solid, its form seems to shimmer slightly. Feels (and burns) just like the real thing." + desc = "A ticket which shows your place in the Head of Personnel's line. Made from Nanotrasen patented NanoPaper®. Though solid, its form seems to shimmer slightly. Feels (and burns) just like the real thing." icon = 'icons/obj/bureaucracy.dmi' icon_state = "ticket" maptext_x = 7 diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index 99a0bedc4d..4e81c5aeb6 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -460,6 +460,7 @@ return TRUE //Bullets don't drift in space /obj/item/projectile/process(wait) + set waitfor = FALSE if(!loc || !fired || !trajectory) fired = FALSE return PROCESS_KILL diff --git a/code/modules/recycling/disposal/bin.dm b/code/modules/recycling/disposal/bin.dm index c8da9ab5e3..b106005a15 100644 --- a/code/modules/recycling/disposal/bin.dm +++ b/code/modules/recycling/disposal/bin.dm @@ -263,7 +263,7 @@ . = ..() if(.) return - for(var/obj/item/I in src_object) + for(var/obj/item/I in src_object.contents()) if(user.active_storage != src_object) if(I.on_found(user)) return diff --git a/code/modules/shielding/helpers.dm b/code/modules/shielding/helpers.dm new file mode 100644 index 0000000000..8995cc3b03 --- /dev/null +++ b/code/modules/shielding/helpers.dm @@ -0,0 +1,65 @@ +//////// HELPER FILE FOR SHIELDING ///////// + +// HULL SHIELD GENERATION HELPERS +/** + * Gets hull exterior adjacent tiles of a certain area + * Area method. + * EXPENSIVE. + * If the area itself is already considered exterior, it'll find all tiles inside it that's next to an interior area. + */ +/proc/hull_shielding_get_tiles_around_area(area/instance, check_tick = FALSE) + var/list/cache = list() + var/area/A + if(instance.considered_hull_exterior) + for(var/turf/potential in instance) + for(var/turf/looking in orange(1, potential)) + A = looking.loc + if(!A.considered_hull_exterior) + cache[potential] = TRUE // we're the exterior area, grab the one that's reaching out + if(check_tick) + CHECK_TICK + else + for(var/turf/potential in instance) + for(var/turf/looking in orange(1, potential)) + A = looking.loc + if(A.considered_hull_exterior) + cache[looking] = TRUE // we're not the exterior area, grab the one that's being reached to + if(check_tick) + CHECK_TICK + . = list() + for(var/i in cache) + . += i // strip assoc value + +/** + * Gets hull adjacent exterior tiles of an entire zlevel + * EXPENSIVE. + * Gets the tiles in the exterior area touching to a non-exterior area + */ +/proc/hull_shielding_get_tiles_in_z(zlevel, check_tick = FALSE, recurse = FALSE, list/outlist = list(), list/scanned_zlevels = list()) + . = outlist + if(zlevel in scanned_zlevels) + return + scanned_zlevels |= zlevel + if(recurse) + var/up = SSmapping.level_trait(zlevel, ZTRAIT_UP) + var/down = SSmapping.level_trait(zlevel, ZTRAIT_DOWN) + if(isnum(up) && (up != 0)) + hull_shielding_get_tiles_in_z(up, check_tick, recurse, outlist, scanned_zlevels) + if(isnum(down) && (down != 0)) + hull_shielding_get_tiles_in_z(down, check_tick, recurse, outlist, scanned_zlevels) + // sigh. why. + var/turf/potential + var/area/p_area + var/area/l_area + for(var/x in 1 to world.maxx) + for(var/y in 1 to world.maxy) + if(check_tick) + CHECK_TICK + potential = locate(x, y, zlevel) + p_area = potential.loc + if(!p_area.considered_hull_exterior) + continue + for(var/turf/looking in orange(1, potential)) + l_area = looking.loc + if(!l_area.considered_hull_exterior) + outlist += potential diff --git a/html/changelogs/AutoChangeLog-pr-13382.yml b/html/changelogs/AutoChangeLog-pr-13382.yml new file mode 100644 index 0000000000..2dfa78c540 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-13382.yml @@ -0,0 +1,4 @@ +author: "silicons" +delete-after: True +changes: + - balance: "hulks can smash again (walls no longer break their hands)" diff --git a/html/changelogs/AutoChangeLog-pr-13394.yml b/html/changelogs/AutoChangeLog-pr-13394.yml new file mode 100644 index 0000000000..6fe20032da --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-13394.yml @@ -0,0 +1,5 @@ +author: "DeltaFire15" +delete-after: True +changes: + - bugfix: "Sutures work on simplemobs again." + - bugfix: "Attacking dismembered bodyparts now targets the chest instead, for weapons aswell as unarmed attacks." diff --git a/html/changelogs/AutoChangeLog-pr-13399.yml b/html/changelogs/AutoChangeLog-pr-13399.yml new file mode 100644 index 0000000000..2da88988a0 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-13399.yml @@ -0,0 +1,4 @@ +author: "silicons" +delete-after: True +changes: + - rscdel: "acid no longer degrades armor" diff --git a/html/changelogs/AutoChangeLog-pr-13401.yml b/html/changelogs/AutoChangeLog-pr-13401.yml new file mode 100644 index 0000000000..6bfc8e4e21 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-13401.yml @@ -0,0 +1,4 @@ +author: "MrJWhit" +delete-after: True +changes: + - rscadd: "New sprites for chess pieces! You can craft them in-game with metal sheets." diff --git a/icons/obj/chess.dmi b/icons/obj/chess.dmi index 09d9c766fd..ec9415eab4 100644 Binary files a/icons/obj/chess.dmi and b/icons/obj/chess.dmi differ diff --git a/tgstation.dme b/tgstation.dme index 7c3673bee2..7d30d694b0 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -3284,6 +3284,7 @@ #include "code\modules\ruins\spaceruin_code\whiteshipruin_box.dm" #include "code\modules\security_levels\keycard_authentication.dm" #include "code\modules\security_levels\security_levels.dm" +#include "code\modules\shielding\helpers.dm" #include "code\modules\shuttle\arrivals.dm" #include "code\modules\shuttle\assault_pod.dm" #include "code\modules\shuttle\computer.dm"