From 6ebc9119378f50a0e50a9fdddd1d6e7a20e9a226 Mon Sep 17 00:00:00 2001 From: necromanceranne <40847847+necromanceranne@users.noreply.github.com> Date: Tue, 16 Mar 2021 04:48:55 +1100 Subject: [PATCH 01/75] Batons knockdown and slowdown on rightclick, otherwise they stagger, but always do damage. Damage respects melee armor, but power cells grant armor pen based on max charge. --- code/__DEFINES/traits.dm | 1 + code/_globalvars/traits.dm | 2 +- code/game/objects/items/stunbaton.dm | 72 ++++++++++++++------- code/game/objects/items/teleprod.dm | 2 +- code/game/objects/structures/watercloset.dm | 2 +- 5 files changed, 53 insertions(+), 26 deletions(-) diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm index 8e0886a30d..9b4e5a0ada 100644 --- a/code/__DEFINES/traits.dm +++ b/code/__DEFINES/traits.dm @@ -215,6 +215,7 @@ #define TRAIT_NO_STAMINA_BUFFER_REGENERATION "block_stamina_buffer_regen" /// Prevents stamina buffer regeneration #define TRAIT_NO_STAMINA_REGENERATION "block_stamina_regen" /// Prevents stamina regeneration #define TRAIT_ARMOR_BROKEN "armor_broken" //acts as if you are wearing no clothing when taking damage, does not affect non-clothing sources of protection +#define TRAIT_IWASBATONED "iwasbatoned" //some dastardly fellow has struck you with a baton and thought to use another to strike you again, the rogue /// forces update_density to make us not dense #define TRAIT_LIVING_NO_DENSITY "living_no_density" /// forces us to not render our overlays diff --git a/code/_globalvars/traits.dm b/code/_globalvars/traits.dm index ac6ea4e25c..26e0197deb 100644 --- a/code/_globalvars/traits.dm +++ b/code/_globalvars/traits.dm @@ -123,7 +123,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_HIGH_BLOOD" = TRAIT_HIGH_BLOOD, "TRAIT_EMPATH" = TRAIT_EMPATH, "TRAIT_FRIENDLY" = TRAIT_FRIENDLY, - "TRAIT_NICE_SHOT" = TRAIT_NICE_SHOT + "TRAIT_IWASBATONED" = TRAIT_IWASBATONED ), /obj/item/bodypart = list( "TRAIT_PARALYSIS" = TRAIT_PARALYSIS diff --git a/code/game/objects/items/stunbaton.dm b/code/game/objects/items/stunbaton.dm index cc01e6aaee..ece3341eae 100644 --- a/code/game/objects/items/stunbaton.dm +++ b/code/game/objects/items/stunbaton.dm @@ -16,17 +16,20 @@ armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 50, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 80) attack_speed = CLICK_CD_MELEE - var/stamforce = 35 + var/stamina_loss_amount = 35 var/turned_on = FALSE var/knockdown = TRUE var/obj/item/stock_parts/cell/cell var/hitcost = 750 var/throw_hit_chance = 35 var/preload_cell_type //if not empty the baton starts with this type of cell + var/cooldown_duration = 5 SECONDS //How long our baton rightclick goes on cooldown for after applying a knockdown + var/status_duration = 5 SECONDS //how long our status effects last for otherwise + COOLDOWN_DECLARE(shove_cooldown) /obj/item/melee/baton/examine(mob/user) . = ..() - . += "Right click attack while in combat mode to disarm instead of stun." + . += "Right click attack while in combat mode to knockdown, but only once per [cooldown_duration / 10] seconds." /obj/item/melee/baton/get_cell() . = cell @@ -74,6 +77,16 @@ //we're below minimum, turn off switch_status(FALSE) +///Check for our cell to determine how much penetration our weapon does. +/obj/item/melee/baton/proc/get_cell_zap_pen() + var/obj/item/stock_parts/cell/copper_top = get_cell() + if(copper_top) + var/chargepower = copper_top.maxcharge + var/zap_penetration = (chargepower/1000) //This is our effective penetration. Every 1000 max charge, we get 1 pen power. A high capacity cell is equal to 10 armor pen, as an example. + return zap_penetration + else + return 0 + /obj/item/melee/baton/proc/switch_status(new_status = FALSE, silent = FALSE) if(turned_on != new_status) turned_on = new_status @@ -101,6 +114,7 @@ var/obj/item/stock_parts/cell/copper_top = get_cell() if(copper_top) . += "\The [src] is [round(copper_top.percent())]% charged." + . += "\The [src] currently can penetrate [round(copper_top.maxcharge/1000)]% of enemy armor thanks to it's loaded cell." else . += "\The [src] does not have a power source installed." @@ -150,10 +164,10 @@ /obj/item/melee/baton/alt_pre_attack(atom/A, mob/living/user, params) if(!user.CheckActionCooldown(CLICK_CD_MELEE)) return - . = common_baton_melee(A, user, TRUE) //return true (attackchain interrupt) if this also returns true. no harm-disarming. + . = common_baton_melee(A, user, TRUE) //return true (attackchain interrupt) if this also returns true. no harm-shoving. //return TRUE to interrupt attack chain. -/obj/item/melee/baton/proc/common_baton_melee(mob/M, mob/living/user, disarming = FALSE) +/obj/item/melee/baton/proc/common_baton_melee(mob/M, mob/living/user, shoving = FALSE) if(iscyborg(M) || !isliving(M)) //can't baton cyborgs return FALSE if(turned_on && HAS_TRAIT(user, TRAIT_CLUMSY) && prob(50)) @@ -167,21 +181,26 @@ if(check_martial_counter(L, user)) return TRUE if(turned_on) - if(baton_stun(M, user, disarming)) + if(baton_stun(M, user, shoving)) user.do_attack_animation(M) else if(user.a_intent != INTENT_HARM) //they'll try to bash in the last proc. M.visible_message("[user] has prodded [M] with [src]. Luckily it was off.", \ "[user] has prodded you with [src]. Luckily it was off") - return disarming || (user.a_intent != INTENT_HARM) + return shoving || (user.a_intent != INTENT_HARM) -/obj/item/melee/baton/proc/baton_stun(mob/living/L, mob/living/user, disarming = FALSE) +/obj/item/melee/baton/proc/baton_stun(mob/living/L, mob/living/user, shoving = FALSE) var/list/return_list = list() if(L.mob_run_block(src, 0, "[user]'s [name]", ATTACK_TYPE_MELEE, 0, user, null, return_list) & BLOCK_SUCCESS) //No message; check_shields() handles that playsound(L, 'sound/weapons/genhit.ogg', 50, 1) return FALSE - var/stunpwr = stamforce - stunpwr = block_calculate_resultant_damage(stunpwr, return_list) + var/final_stamina_loss_amount = stamina_loss_amount //Our stunning power for the baton + var/shoved = FALSE //Did we succeed on knocking our target over? + var/zap_penetration = get_cell_zap_pen() //Find out what kind of cell we have, and calculating the resultant armor pen we get from it + var/zap_block = L.run_armor_check(BODY_ZONE_CHEST, "melee", null, null, zap_penetration) //armor check, including calculation for armor penetration, for our attack + final_stamina_loss_amount = block_calculate_resultant_damage(final_stamina_loss_amount, return_list) + var/obj/item/stock_parts/cell/our_cell = get_cell() + if(!our_cell) switch_status(FALSE) return FALSE @@ -194,29 +213,34 @@ L.visible_message("[user] has prodded [L] with [src]. Luckily it was out of charge.", \ "[user] has prodded you with [src]. Luckily it was out of charge.") return FALSE - stunpwr *= round(stuncharge/hitcost, 0.1) + final_stamina_loss_amount *= round(stuncharge/hitcost, 0.1) if(user && !user.UseStaminaBuffer(getweight(user, STAM_COST_BATON_MOB_MULT), warn = TRUE)) return FALSE - if(!disarming) - if(knockdown) - L.DefaultCombatKnockdown(50, override_stamdmg = 0) //knockdown - L.adjustStaminaLoss(stunpwr) - else - L.drop_all_held_items() //no knockdown/stamina damage, instead disarm. + if(shoving && COOLDOWN_FINISHED(src, shove_cooldown) && !HAS_TRAIT(L, TRAIT_IWASBATONED)) //Rightclicking applies a knockdown, but only once every couple of seconds, based on the cooldown_duration var. If they were recently knocked down, they can't be knocked down again by a baton. + L.DefaultCombatKnockdown(50, override_stamdmg = 0) + L.apply_status_effect(STATUS_EFFECT_TASED_WEAK, status_duration) //Even if they shove themselves up, they're still slowed. + shoved = TRUE + COOLDOWN_START(src, shove_cooldown, cooldown_duration) + else //If we cannot/don't knock down the target, we apply a stagger, which keeps them from just running off + L.apply_status_effect(STATUS_EFFECT_STAGGERED, status_duration) - L.apply_effect(EFFECT_STUTTER, stamforce) + L.apply_damage (final_stamina_loss_amount, STAMINA, BODY_ZONE_CHEST, zap_block) + L.apply_effect(EFFECT_STUTTER, stamina_loss_amount) SEND_SIGNAL(L, COMSIG_LIVING_MINOR_SHOCK) if(user) L.lastattacker = user.real_name L.lastattackerckey = user.ckey - L.visible_message("[user] has [disarming? "disarmed" : "stunned"] [L] with [src]!", \ - "[user] has [disarming? "disarmed" : "stunned"] you with [src]!") - log_combat(user, L, disarming? "disarmed" : "stunned") + L.visible_message("[user] has [shoved ? "knocked to the floor" : "stunned"] [L] with [src]!", \ + "[user] has [shoved ? "knocked you to the floor" : "stunned you"] with [src]!") + log_combat(user, L, shoved ? "stunned and attempted knockdown" : "stunned") playsound(loc, 'sound/weapons/egloves.ogg', 50, 1, -1) + ADD_TRAIT(L, TRAIT_IWASBATONED, STATUS_EFFECT_TRAIT) //Prevents swapping to a new baton to avoid the cooldown by just acquiring more batons + addtimer(TRAIT_CALLBACK_REMOVE(L, TRAIT_IWASBATONED, STATUS_EFFECT_TRAIT), cooldown_duration) + if(ishuman(L)) var/mob/living/carbon/human/H = L H.forcesay(GLOB.hit_appends) @@ -228,7 +252,7 @@ user.visible_message("[user] accidentally hits [user.p_them()]self with [src]!", \ "You accidentally hit yourself with [src]!") SEND_SIGNAL(user, COMSIG_LIVING_MINOR_SHOCK) - user.DefaultCombatKnockdown(stamforce*6) + user.DefaultCombatKnockdown(stamina_loss_amount*6) playsound(loc, 'sound/weapons/egloves.ogg', 50, 1, -1) deductcharge(hitcost) @@ -306,16 +330,18 @@ w_class = WEIGHT_CLASS_BULKY force = 3 throwforce = 5 - stamforce = 25 + stamina_loss_amount = 25 hitcost = 1000 throw_hit_chance = 10 slot_flags = ITEM_SLOT_BACK + cooldown_duration = 7 SECONDS //It's a little on the weak side + status_duration = 2 //Slows someone for a tiny bit var/obj/item/assembly/igniter/sparkler /obj/item/melee/baton/cattleprod/Initialize() . = ..() sparkler = new (src) - sparkler.activate_cooldown = 5 + sparkler.activate_cooldown = 7 //Helps visualize the knockdown /obj/item/melee/baton/cattleprod/baton_stun() sparkler?.activate() diff --git a/code/game/objects/items/teleprod.dm b/code/game/objects/items/teleprod.dm index 63bde36976..ac853cae56 100644 --- a/code/game/objects/items/teleprod.dm +++ b/code/game/objects/items/teleprod.dm @@ -16,7 +16,7 @@ user.visible_message("[user] accidentally hits [user.p_them()]self with [src]!", \ "You accidentally hit yourself with [src]!") SEND_SIGNAL(user, COMSIG_LIVING_MINOR_SHOCK) - user.DefaultCombatKnockdown(stamforce * 6) + user.DefaultCombatKnockdown(stamina_loss_amount * 6) playsound(loc, 'sound/weapons/egloves.ogg', 50, 1, -1) if(do_teleport(user, get_turf(user), 50, channel = TELEPORT_CHANNEL_BLUESPACE)) deductcharge(hitcost) diff --git a/code/game/objects/structures/watercloset.dm b/code/game/objects/structures/watercloset.dm index dba8d5de45..01c62a7901 100644 --- a/code/game/objects/structures/watercloset.dm +++ b/code/game/objects/structures/watercloset.dm @@ -554,7 +554,7 @@ if(B.cell) if(B.cell.charge > 0 && B.turned_on) flick("baton_active", src) - var/stunforce = B.stamforce + var/stunforce = B.stamina_loss_amount user.DefaultCombatKnockdown(stunforce * 2) user.stuttering = stunforce/20 B.deductcharge(B.hitcost) From 29a28d4ed8fc68aa9d3ee6bf288c8cd76c98fecd Mon Sep 17 00:00:00 2001 From: necromanceranne <40847847+necromanceranne@users.noreply.github.com> Date: Tue, 16 Mar 2021 05:52:38 +1100 Subject: [PATCH 02/75] keeps knockdown on rng throw, because you deserve it if you land it --- code/game/objects/items/stunbaton.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/objects/items/stunbaton.dm b/code/game/objects/items/stunbaton.dm index ece3341eae..9ebe13ca9d 100644 --- a/code/game/objects/items/stunbaton.dm +++ b/code/game/objects/items/stunbaton.dm @@ -57,7 +57,7 @@ ..() //Only mob/living types have stun handling if(turned_on && prob(throw_hit_chance) && iscarbon(hit_atom)) - baton_stun(hit_atom) + baton_stun(hit_atom, shoving = TRUE) /obj/item/melee/baton/loaded //this one starts with a cell pre-installed. preload_cell_type = /obj/item/stock_parts/cell/high/plus From 832fb7a6f846e8efa95b99fda9f211b27f5d2723 Mon Sep 17 00:00:00 2001 From: necromanceranne <40847847+necromanceranne@users.noreply.github.com> Date: Tue, 16 Mar 2021 06:03:22 +1100 Subject: [PATCH 03/75] oops, this should fix that failed check...I hope --- code/game/objects/items/stunbaton.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/game/objects/items/stunbaton.dm b/code/game/objects/items/stunbaton.dm index 9ebe13ca9d..9ba22ab0c6 100644 --- a/code/game/objects/items/stunbaton.dm +++ b/code/game/objects/items/stunbaton.dm @@ -56,8 +56,8 @@ /obj/item/melee/baton/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) ..() //Only mob/living types have stun handling - if(turned_on && prob(throw_hit_chance) && iscarbon(hit_atom)) - baton_stun(hit_atom, shoving = TRUE) + if(turned_on && prob(throw_hit_chance) && iscarbon(hit_atom) && thrownby) + baton_stun(hit_atom, thrownby, shoving = TRUE) /obj/item/melee/baton/loaded //this one starts with a cell pre-installed. preload_cell_type = /obj/item/stock_parts/cell/high/plus From 1de69e0dec29c23515db2d3fbb1ea1bb163ad296 Mon Sep 17 00:00:00 2001 From: necromanceranne <40847847+necromanceranne@users.noreply.github.com> Date: Tue, 16 Mar 2021 06:14:49 +1100 Subject: [PATCH 04/75] uuuuh if you say so boss --- code/game/objects/items/stunbaton.dm | 6 +++--- code/game/objects/items/teleprod.dm | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/code/game/objects/items/stunbaton.dm b/code/game/objects/items/stunbaton.dm index 9ba22ab0c6..189cb2fd83 100644 --- a/code/game/objects/items/stunbaton.dm +++ b/code/game/objects/items/stunbaton.dm @@ -343,7 +343,7 @@ sparkler = new (src) sparkler.activate_cooldown = 7 //Helps visualize the knockdown -/obj/item/melee/baton/cattleprod/baton_stun() +/obj/item/melee/baton/cattleprod/baton_stun(mob/living/L, mob/living/carbon/user, shoving = FALSE) sparkler?.activate() . = ..() @@ -370,8 +370,8 @@ /obj/item/melee/baton/boomerang/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) if(turned_on) var/caught = hit_atom.hitby(src, FALSE, FALSE, throwingdatum=throwingdatum) - if(ishuman(hit_atom) && !caught && prob(throw_hit_chance))//if they are a carbon and they didn't catch it - baton_stun(hit_atom) + if(ishuman(hit_atom) && !caught && prob(throw_hit_chance) && thrownby)//if they are a carbon and they didn't catch it + baton_stun(hit_atom, thrownby, shoving = TRUE) if(thrownby && !caught) sleep(1) if(!QDELETED(src)) diff --git a/code/game/objects/items/teleprod.dm b/code/game/objects/items/teleprod.dm index ac853cae56..94eb6fc85b 100644 --- a/code/game/objects/items/teleprod.dm +++ b/code/game/objects/items/teleprod.dm @@ -6,7 +6,7 @@ item_state = "teleprod" slot_flags = null -/obj/item/melee/baton/cattleprod/teleprod/baton_stun(mob/living/L, mob/living/carbon/user)//handles making things teleport when hit +/obj/item/melee/baton/cattleprod/teleprod/baton_stun(mob/living/L, mob/living/carbon/user, shoving = FALSE)//handles making things teleport when hit . = ..() if(!. || L.anchored) return From a61ac1fc684a09fc606b72c662a528b6aab4553e Mon Sep 17 00:00:00 2001 From: necromanceranne <40847847+necromanceranne@users.noreply.github.com> Date: Sat, 20 Mar 2021 04:23:23 +1100 Subject: [PATCH 05/75] Applies off balance on right click, allowing you to shove a weapon out of someones hands --- code/game/objects/items/stunbaton.dm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/code/game/objects/items/stunbaton.dm b/code/game/objects/items/stunbaton.dm index 189cb2fd83..ea4ee8f822 100644 --- a/code/game/objects/items/stunbaton.dm +++ b/code/game/objects/items/stunbaton.dm @@ -30,6 +30,7 @@ /obj/item/melee/baton/examine(mob/user) . = ..() . += "Right click attack while in combat mode to knockdown, but only once per [cooldown_duration / 10] seconds." + . += "This knockdown will also put them off balance for [status_duration / 2] seconds, allowing you to shove a weapon out of their hand with a right click in Disarm intent." /obj/item/melee/baton/get_cell() . = cell @@ -221,6 +222,7 @@ if(shoving && COOLDOWN_FINISHED(src, shove_cooldown) && !HAS_TRAIT(L, TRAIT_IWASBATONED)) //Rightclicking applies a knockdown, but only once every couple of seconds, based on the cooldown_duration var. If they were recently knocked down, they can't be knocked down again by a baton. L.DefaultCombatKnockdown(50, override_stamdmg = 0) L.apply_status_effect(STATUS_EFFECT_TASED_WEAK, status_duration) //Even if they shove themselves up, they're still slowed. + L.apply_status_effect(STATUS_EFFECT_OFF_BALANCE, status_duration * 0.5) //They're very likely to drop items if shoved briefly after a knockdown. shoved = TRUE COOLDOWN_START(src, shove_cooldown, cooldown_duration) else //If we cannot/don't knock down the target, we apply a stagger, which keeps them from just running off From 6a752cfd5d43d7f3b2f199d1219215fa83f0da45 Mon Sep 17 00:00:00 2001 From: necromanceranne <40847847+necromanceranne@users.noreply.github.com> Date: Sat, 20 Mar 2021 04:28:20 +1100 Subject: [PATCH 06/75] Not quite right --- code/game/objects/items/stunbaton.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/objects/items/stunbaton.dm b/code/game/objects/items/stunbaton.dm index ea4ee8f822..9e08edf032 100644 --- a/code/game/objects/items/stunbaton.dm +++ b/code/game/objects/items/stunbaton.dm @@ -30,7 +30,7 @@ /obj/item/melee/baton/examine(mob/user) . = ..() . += "Right click attack while in combat mode to knockdown, but only once per [cooldown_duration / 10] seconds." - . += "This knockdown will also put them off balance for [status_duration / 2] seconds, allowing you to shove a weapon out of their hand with a right click in Disarm intent." + . += "This knockdown will also put them off balance for [status_duration / 20] seconds, allowing you to shove a weapon out of their hand with a right click in Disarm intent." /obj/item/melee/baton/get_cell() . = cell From 45340ef1ac317c80bbffc5e6a9b4bbaf161ed452 Mon Sep 17 00:00:00 2001 From: necromanceranne <40847847+necromanceranne@users.noreply.github.com> Date: Thu, 25 Mar 2021 09:27:33 +1100 Subject: [PATCH 07/75] Makes shove off-balancing remove any active item, not just guns. Makes baton knockdowns not go on cooldown from normal hits, makes baton offbalance trait share a duration. Gives the stunprod a little more oomph to keep it comparable to unarmed. --- code/__DEFINES/combat.dm | 3 --- code/datums/status_effects/debuffs.dm | 3 +-- code/game/objects/items/stunbaton.dm | 10 +++++----- code/modules/mob/living/carbon/human/species.dm | 2 -- 4 files changed, 6 insertions(+), 12 deletions(-) diff --git a/code/__DEFINES/combat.dm b/code/__DEFINES/combat.dm index d12fe77448..d219736abe 100644 --- a/code/__DEFINES/combat.dm +++ b/code/__DEFINES/combat.dm @@ -159,9 +159,6 @@ #define SHOVE_STAGGER_DURATION 35 /// how long they're off balance for #define SHOVE_OFFBALANCE_DURATION 30 -//Shove disarming item list -GLOBAL_LIST_INIT(shove_disarming_types, typecacheof(list( - /obj/item/gun))) //Embedded objects diff --git a/code/datums/status_effects/debuffs.dm b/code/datums/status_effects/debuffs.dm index fe59bbe14a..10e183a8c8 100644 --- a/code/datums/status_effects/debuffs.dm +++ b/code/datums/status_effects/debuffs.dm @@ -108,8 +108,7 @@ /datum/status_effect/off_balance/on_remove() var/active_item = owner.get_active_held_item() - if(is_type_in_typecache(active_item, GLOB.shove_disarming_types)) - owner.visible_message("[owner.name] regains their grip on \the [active_item]!", "You regain your grip on \the [active_item]", null, COMBAT_MESSAGE_RANGE) + owner.visible_message("[owner.name] regains their grip on \the [active_item]!", "You regain your grip on \the [active_item]", null, COMBAT_MESSAGE_RANGE) return ..() /obj/screen/alert/status_effect/asleep diff --git a/code/game/objects/items/stunbaton.dm b/code/game/objects/items/stunbaton.dm index 9e08edf032..9c5b911376 100644 --- a/code/game/objects/items/stunbaton.dm +++ b/code/game/objects/items/stunbaton.dm @@ -222,9 +222,12 @@ if(shoving && COOLDOWN_FINISHED(src, shove_cooldown) && !HAS_TRAIT(L, TRAIT_IWASBATONED)) //Rightclicking applies a knockdown, but only once every couple of seconds, based on the cooldown_duration var. If they were recently knocked down, they can't be knocked down again by a baton. L.DefaultCombatKnockdown(50, override_stamdmg = 0) L.apply_status_effect(STATUS_EFFECT_TASED_WEAK, status_duration) //Even if they shove themselves up, they're still slowed. - L.apply_status_effect(STATUS_EFFECT_OFF_BALANCE, status_duration * 0.5) //They're very likely to drop items if shoved briefly after a knockdown. + L.apply_status_effect(STATUS_EFFECT_OFF_BALANCE, status_duration) //They're very likely to drop items if shoved briefly after a knockdown. shoved = TRUE COOLDOWN_START(src, shove_cooldown, cooldown_duration) + ADD_TRAIT(L, TRAIT_IWASBATONED, STATUS_EFFECT_TRAIT) //Prevents swapping to a new baton to avoid the cooldown by just acquiring more batons + addtimer(TRAIT_CALLBACK_REMOVE(L, TRAIT_IWASBATONED, STATUS_EFFECT_TRAIT), cooldown_duration) + playsound(loc, 'sound/weapons/zapbang.ogg', 50, 1, -1) else //If we cannot/don't knock down the target, we apply a stagger, which keeps them from just running off L.apply_status_effect(STATUS_EFFECT_STAGGERED, status_duration) @@ -240,9 +243,6 @@ playsound(loc, 'sound/weapons/egloves.ogg', 50, 1, -1) - ADD_TRAIT(L, TRAIT_IWASBATONED, STATUS_EFFECT_TRAIT) //Prevents swapping to a new baton to avoid the cooldown by just acquiring more batons - addtimer(TRAIT_CALLBACK_REMOVE(L, TRAIT_IWASBATONED, STATUS_EFFECT_TRAIT), cooldown_duration) - if(ishuman(L)) var/mob/living/carbon/human/H = L H.forcesay(GLOB.hit_appends) @@ -337,7 +337,7 @@ throw_hit_chance = 10 slot_flags = ITEM_SLOT_BACK cooldown_duration = 7 SECONDS //It's a little on the weak side - status_duration = 2 //Slows someone for a tiny bit + status_duration = 3 //Slows someone for a tiny bit var/obj/item/assembly/igniter/sparkler /obj/item/melee/baton/cattleprod/Initialize() diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index 986fc38cd3..89e9f61d6f 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -2039,8 +2039,6 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) user, "You shove [target.name]!") target.Stagger(SHOVE_STAGGER_DURATION) var/obj/item/target_held_item = target.get_active_held_item() - if(!is_type_in_typecache(target_held_item, GLOB.shove_disarming_types)) - target_held_item = null if(!target.has_status_effect(STATUS_EFFECT_OFF_BALANCE)) if(target_held_item) if(!HAS_TRAIT(target_held_item, TRAIT_NODROP)) From 8091844a1ca62cc80b874fe5ae84be1b0e7c3855 Mon Sep 17 00:00:00 2001 From: necromanceranne <40847847+necromanceranne@users.noreply.github.com> Date: Sat, 27 Mar 2021 14:06:41 +1100 Subject: [PATCH 08/75] Urist McGreyshit regains their grip on the ! --- code/datums/status_effects/debuffs.dm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/code/datums/status_effects/debuffs.dm b/code/datums/status_effects/debuffs.dm index 10e183a8c8..0341e243a8 100644 --- a/code/datums/status_effects/debuffs.dm +++ b/code/datums/status_effects/debuffs.dm @@ -108,7 +108,8 @@ /datum/status_effect/off_balance/on_remove() var/active_item = owner.get_active_held_item() - owner.visible_message("[owner.name] regains their grip on \the [active_item]!", "You regain your grip on \the [active_item]", null, COMBAT_MESSAGE_RANGE) + if(active_item) + owner.visible_message("[owner.name] regains their grip on \the [active_item]!", "You regain your grip on \the [active_item]", null, COMBAT_MESSAGE_RANGE) return ..() /obj/screen/alert/status_effect/asleep From f1b45b3839d2c012ffcceffa967bea9eac93babc Mon Sep 17 00:00:00 2001 From: zerothebigboy Date: Mon, 5 Apr 2021 21:55:17 -0400 Subject: [PATCH 09/75] eatshitanddie --- code/modules/admin/verbs/randomverbs.dm | 49 +++ .../simple_animal/hostile/megafauna/drake.dm | 330 ++++++++++++------ 2 files changed, 269 insertions(+), 110 deletions(-) diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm index e5390bc457..199004abed 100644 --- a/code/modules/admin/verbs/randomverbs.dm +++ b/code/modules/admin/verbs/randomverbs.dm @@ -1547,6 +1547,55 @@ GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits msg += "" src << browse(msg.Join(), "window=Player_playtime_check") +/obj/effect/temp_visual/fireball + icon = 'icons/obj/wizard.dmi' + icon_state = "fireball" + name = "fireball" + desc = "Get out of the way!" + layer = FLY_LAYER + randomdir = FALSE + duration = 9 + pixel_z = 270 + +/obj/effect/temp_visual/fireball/Initialize() + . = ..() + animate(src, pixel_z = 0, time = duration) + +/obj/effect/temp_visual/target + icon = 'icons/mob/actions/actions_items.dmi' + icon_state = "sniper_zoom" + layer = BELOW_MOB_LAYER + light_range = 2 + duration = 9 + +/obj/effect/temp_visual/target/ex_act() + return + +/obj/effect/temp_visual/target/Initialize(mapload, list/flame_hit) + . = ..() + INVOKE_ASYNC(src, .proc/fall, flame_hit) + +/obj/effect/temp_visual/target/proc/fall(list/flame_hit) + var/turf/T = get_turf(src) + playsound(T,'sound/magic/fleshtostone.ogg', 80, 1) + new /obj/effect/temp_visual/fireball(T) + sleep(duration) + if(ismineralturf(T)) + var/turf/closed/mineral/M = T + M.gets_drilled() + playsound(T, "explosion", 80, 1) + new /obj/effect/hotspot(T) + T.hotspot_expose(700, 50, 1) + for(var/mob/living/L in T.contents) + if(istype(L, /mob/living/simple_animal/hostile/megafauna/dragon)) + continue + if(islist(flame_hit) && !flame_hit[L]) + L.adjustFireLoss(40) + to_chat(L, "You're hit by the drake's fire breath!") + flame_hit[L] = TRUE + else + L.adjustFireLoss(10) //if we've already hit them, do way less damage + /datum/admins/proc/cmd_show_exp_panel(client/client_to_check) if(!check_rights(R_ADMIN)) return diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm index 9dd2441829..769946bb6c 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm @@ -63,7 +63,7 @@ Difficulty: Medium butcher_results = list(/obj/item/stack/ore/diamond = 5, /obj/item/stack/sheet/sinew = 5, /obj/item/stack/sheet/bone = 30) guaranteed_butcher_results = list(/obj/item/stack/sheet/animalhide/ashdrake = 10) var/swooping = NONE - var/swoop_cooldown = 0 + var/player_cooldown = 0 achievement_type = /datum/award/achievement/boss/drake_kill crusher_achievement_type = /datum/award/achievement/boss/drake_crusher score_achievement_type = /datum/award/score/drake_score @@ -116,66 +116,167 @@ Difficulty: Medium ranged_cooldown = world.time + ranged_cooldown_time if(prob(15 + anger_modifier) && !client) - if(health < maxHealth/2) - INVOKE_ASYNC(src, .proc/swoop_attack, TRUE, null, 50) + if(health < maxHealth*0.5) + swoop_attack(lava_arena = TRUE) else - fire_rain() + lava_swoop() else if(prob(10+anger_modifier) && !client) - if(health > maxHealth/2) - INVOKE_ASYNC(src, .proc/swoop_attack) + if(health < maxHealth*0.5) + mass_fire() else - INVOKE_ASYNC(src, .proc/triple_swoop) + fire_cone() else - fire_walls() + if(prob(50) && !client) + INVOKE_ASYNC(src, .proc/lava_pools, 10, 2) + fire_cone() -/mob/living/simple_animal/hostile/megafauna/dragon/proc/fire_rain() +/mob/living/simple_animal/hostile/megafauna/dragon/proc/lava_pools(var/amount, var/delay = 0.8) if(!target) return - target.visible_message("Fire rains from the sky!") - for(var/turf/turf in range(9,get_turf(target))) - if(prob(11)) - new /obj/effect/temp_visual/target(turf) - -/mob/living/simple_animal/hostile/megafauna/dragon/proc/fire_walls() - playsound(get_turf(src),'sound/magic/fireball.ogg', 200, 1) - - for(var/d in GLOB.cardinals) - INVOKE_ASYNC(src, .proc/fire_wall, d) - -/mob/living/simple_animal/hostile/megafauna/dragon/proc/fire_wall(dir) - var/list/hit_things = list(src) - var/turf/E = get_edge_target_turf(src, dir) - var/range = 10 - var/turf/previousturf = get_turf(src) - for(var/turf/J in getline(src,E)) - if(!range || (J != previousturf && (!previousturf.atmos_adjacent_turfs || !previousturf.atmos_adjacent_turfs[J]))) + target.visible_message("Lava starts to pool up around you!") + while(amount > 0) + if(!target) break - range-- - new /obj/effect/hotspot(J) - J.hotspot_expose(DRAKE_FIRE_TEMP, DRAKE_FIRE_EXPOSURE, 1) - for(var/mob/living/L in J.contents - hit_things) - if(istype(L, /mob/living/simple_animal/hostile/megafauna/dragon)) + var/turf/T = pick(RANGE_TURFS(1, target)) + new /obj/effect/temp_visual/lava_warning(T, 60) // longer reset time for the lava + amount-- + sleep(delay) + +/mob/living/simple_animal/hostile/megafauna/dragon/proc/lava_swoop(var/amount = 30) + INVOKE_ASYNC(src, .proc/lava_pools, amount) + swoop_attack(FALSE, target, 1000) // longer cooldown until it gets reset below + fire_cone() + if(health < maxHealth*0.5) + sleep(10) + fire_cone() + sleep(10) + fire_cone() + SetRecoveryTime(40) + +/mob/living/simple_animal/hostile/megafauna/dragon/proc/mass_fire(var/spiral_count = 12, var/range = 15, var/times = 3) + for(var/i = 1 to times) + SetRecoveryTime(50) + playsound(get_turf(src),'sound/magic/fireball.ogg', 200, 1) + var/increment = 360 / spiral_count + for(var/j = 1 to spiral_count) + var/list/turfs = line_target(j * increment + i * increment / 2, range, src) + INVOKE_ASYNC(src, .proc/fire_line, turfs) + sleep(25) + SetRecoveryTime(30) + +/mob/living/simple_animal/hostile/megafauna/dragon/proc/lava_arena() + if(!target) + return + target.visible_message("[src] encases you in an arena of fire!") + var/amount = 3 + var/turf/center = get_turf(target) + var/list/walled = RANGE_TURFS(3, center) - RANGE_TURFS(2, center) + var/list/drakewalls = list() + for(var/turf/T in walled) + drakewalls += new /obj/effect/temp_visual/drakewall(T) // no people with lava immunity can just run away from the attack for free + var/list/indestructible_turfs = list() + for(var/turf/T in RANGE_TURFS(2, center)) + if(istype(T, /turf/open/indestructible)) + continue + if(!istype(T, /turf/closed/indestructible)) + T.ChangeTurf(/turf/open/floor/plating/asteroid/basalt/lava_land_surface) + else + indestructible_turfs += T + sleep(10) // give them a bit of time to realize what attack is actually happening + + var/list/turfs = RANGE_TURFS(2, center) + while(amount > 0) + var/list/empty = indestructible_turfs.Copy() // can't place safe turfs on turfs that weren't changed to be open + var/any_attack = 0 + for(var/turf/T in turfs) + for(var/mob/living/L in T.contents) + if(L.client) + empty += pick(((RANGE_TURFS(2, L) - RANGE_TURFS(1, L)) & turfs) - empty) // picks a turf within 2 of the creature not outside or in the shield + any_attack = 1 + for(var/obj/mecha/M in T.contents) + empty += pick(((RANGE_TURFS(2, M) - RANGE_TURFS(1, M)) & turfs) - empty) + any_attack = 1 + if(!any_attack) + for(var/obj/effect/temp_visual/drakewall/D in drakewalls) + qdel(D) + return 0 // nothing to attack in the arena time for enraged attack if we still have a target + for(var/turf/T in turfs) + if(!(T in empty)) + new /obj/effect/temp_visual/lava_warning(T) + else if(!istype(T, /turf/closed/indestructible)) + new /obj/effect/temp_visual/lava_safe(T) + amount-- + sleep(24) + return 1 // attack finished completely + +/mob/living/simple_animal/hostile/megafauna/dragon/proc/arena_escape_enrage() // you ran somehow / teleported away from my arena attack now i'm mad fucker + SetRecoveryTime(80) + visible_message("[src] starts to glow vibrantly as its wounds close up!") + adjustBruteLoss(-250) // yeah you're gonna pay for that, don't run nerd + add_atom_colour(rgb(255, 255, 0), TEMPORARY_COLOUR_PRIORITY) + move_to_delay = move_to_delay / 2 + light_range = 10 + sleep(10) // run. + mass_fire(20, 15, 3) + remove_atom_colour(TEMPORARY_COLOUR_PRIORITY) + move_to_delay = initial(move_to_delay) + light_range = initial(light_range) + +/mob/living/simple_animal/hostile/megafauna/dragon/proc/fire_cone(var/atom/at = target) + playsound(get_turf(src),'sound/magic/fireball.ogg', 200, 1) + if(QDELETED(src) || stat == DEAD) // we dead no fire + return + var/range = 15 + var/list/turfs = list() + turfs = line_target(-40, range, at) + INVOKE_ASYNC(src, .proc/fire_line, turfs) + turfs = line_target(0, range, at) + INVOKE_ASYNC(src, .proc/fire_line, turfs) + turfs = line_target(40, range, at) + INVOKE_ASYNC(src, .proc/fire_line, turfs) + +/mob/living/simple_animal/hostile/megafauna/dragon/proc/line_target(var/offset, var/range, var/atom/at = target) + if(!at) + return + var/angle = ATAN2(at.x - src.x, at.y - src.y) + offset + var/turf/T = get_turf(src) + for(var/i in 1 to range) + var/turf/check = locate(src.x + cos(angle) * i, src.y + sin(angle) * i, src.z) + if(!check) + break + T = check + return (getline(src, T) - get_turf(src)) + +/mob/living/simple_animal/hostile/megafauna/dragon/proc/fire_line(var/list/turfs) + var/list/hit_list = list() + for(var/turf/T in turfs) + if(istype(T, /turf/closed)) + break + new /obj/effect/hotspot(T) + T.hotspot_expose(700,50,1) + for(var/mob/living/L in T.contents) + if(L in hit_list || L == src) continue + hit_list += L L.adjustFireLoss(20) - to_chat(L, "You're hit by the drake's fire breath!") - hit_things += L - previousturf = J - sleep(1) + to_chat(L, "You're hit by [src]'s fire breath!") -/mob/living/simple_animal/hostile/megafauna/dragon/proc/triple_swoop() - swoop_attack(swoop_duration = 30) - swoop_attack(swoop_duration = 30) - swoop_attack(swoop_duration = 30) + // deals damage to mechs + for(var/obj/mecha/M in T.contents) + if(M in hit_list) + continue + hit_list += M + M.take_damage(45, BRUTE, "melee", 1) + sleep(1.5) -/mob/living/simple_animal/hostile/megafauna/dragon/proc/swoop_attack(fire_rain, atom/movable/manual_target, swoop_duration = 40) +/mob/living/simple_animal/hostile/megafauna/dragon/proc/swoop_attack(lava_arena = FALSE, atom/movable/manual_target, var/swoop_cooldown = 30) if(stat || swooping) return if(manual_target) target = manual_target if(!target) return - swoop_cooldown = world.time + 200 stop_automated_movement = TRUE swooping |= SWOOP_DAMAGEABLE density = FALSE @@ -209,32 +310,16 @@ Difficulty: Medium swooping |= SWOOP_INVULNERABLE mouse_opacity = MOUSE_OPACITY_TRANSPARENT sleep(7) - var/list/flame_hit = list() - while(swoop_duration > 0) - if(!target && !FindTarget()) - break //we lost our target while chasing it down and couldn't get a new one - if(swoop_duration < 7) - fire_rain = FALSE //stop raining fire near the end of the swoop - if(loc == get_turf(target)) - if(!fire_rain) - break //we're not spewing fire at our target, slam they - if(isliving(target)) - var/mob/living/L = target - if(L.stat == DEAD) - break //target is dead and we're on em, slam they - if(fire_rain) - new /obj/effect/temp_visual/target(loc, flame_hit) + + while(target && loc != get_turf(target)) forceMove(get_step(src, get_dir(src, target))) - if(loc == get_turf(target)) - if(!fire_rain) - break - if(isliving(target)) - var/mob/living/L = target - if(L.stat == DEAD) - break - var/swoop_speed = 1.5 - swoop_duration -= swoop_speed - sleep(swoop_speed) + sleep(0.5) + + // Ash drake flies onto its target and rains fire down upon them + var/descentTime = 10; + var/lava_success = 1 + if(lava_arena) + lava_success = lava_arena() //ensure swoop direction continuity. if(negative) @@ -245,8 +330,8 @@ Difficulty: Medium negative = TRUE new /obj/effect/temp_visual/dragon_flight/end(loc, negative) new /obj/effect/temp_visual/dragon_swoop(loc) - animate(src, alpha = 255, transform = oldtransform, time = 5) - sleep(5) + animate(src, alpha = 255, transform = oldtransform, descentTime) + sleep(descentTime) swooping &= ~SWOOP_INVULNERABLE mouse_opacity = initial(mouse_opacity) icon_state = "dragon" @@ -264,6 +349,8 @@ Difficulty: Medium var/throwtarget = get_edge_target_turf(src, throw_dir) L.throw_at(throwtarget, 3) visible_message("[L] is thrown clear of [src]!") + for(var/obj/mecha/M in orange(1, src)) + M.take_damage(75, BRUTE, "melee", 1) for(var/mob/M in range(7, src)) shake_camera(M, 15, 1) @@ -271,16 +358,20 @@ Difficulty: Medium density = TRUE sleep(1) swooping &= ~SWOOP_DAMAGEABLE - SetRecoveryTime(MEGAFAUNA_DEFAULT_RECOVERY_TIME) + SetRecoveryTime(swoop_cooldown) + if(!lava_success) + arena_escape_enrage() /mob/living/simple_animal/hostile/megafauna/dragon/AltClickOn(atom/movable/A) if(!istype(A)) AltClickNoInteract(src, A) return - if(swoop_cooldown >= world.time) - to_chat(src, "You need to wait 20 seconds between swoop attacks!") + if(player_cooldown >= world.time) + to_chat(src, "You need to wait [(player_cooldown - world.time) / 10] seconds before swooping again!") return - swoop_attack(TRUE, A, 25) + swoop_attack(FALSE, A) + lava_pools(10, 2) // less pools but longer delay before spawns + player_cooldown = world.time + 200 // needs seperate cooldown or cant use fire attacks /obj/item/gps/internal/dragon icon_state = null @@ -289,54 +380,63 @@ Difficulty: Medium invisibility = 100 -/obj/effect/temp_visual/fireball - icon = 'icons/obj/wizard.dmi' - icon_state = "fireball" - name = "fireball" - desc = "Get out of the way!" - layer = FLY_LAYER - randomdir = FALSE - duration = 9 - pixel_z = DRAKE_SWOOP_HEIGHT - -/obj/effect/temp_visual/fireball/Initialize() - . = ..() - animate(src, pixel_z = 0, time = duration) - -/obj/effect/temp_visual/target - icon = 'icons/mob/actions/actions_items.dmi' - icon_state = "sniper_zoom" +/obj/effect/temp_visual/lava_warning + icon_state = "lavastaff_warn" layer = BELOW_MOB_LAYER light_range = 2 - duration = 9 + duration = 13 -/obj/effect/temp_visual/target/ex_act() +/obj/effect/temp_visual/lava_warning/ex_act() return -/obj/effect/temp_visual/target/Initialize(mapload, list/flame_hit) +/obj/effect/temp_visual/lava_warning/Initialize(mapload, var/reset_time = 10) . = ..() - INVOKE_ASYNC(src, .proc/fall, flame_hit) + INVOKE_ASYNC(src, .proc/fall, reset_time) + src.alpha = 63.75 + animate(src, alpha = 255, time = duration) -/obj/effect/temp_visual/target/proc/fall(list/flame_hit) +/obj/effect/temp_visual/lava_warning/proc/fall(var/reset_time) var/turf/T = get_turf(src) playsound(T,'sound/magic/fleshtostone.ogg', 80, 1) - new /obj/effect/temp_visual/fireball(T) sleep(duration) - if(ismineralturf(T)) - var/turf/closed/mineral/M = T - M.gets_drilled() - playsound(T, "explosion", 80, 1) - new /obj/effect/hotspot(T) - T.hotspot_expose(700, 50, 1) + playsound(T,'sound/magic/fireball.ogg', 200, 1) + for(var/mob/living/L in T.contents) if(istype(L, /mob/living/simple_animal/hostile/megafauna/dragon)) continue - if(islist(flame_hit) && !flame_hit[L]) - L.adjustFireLoss(40) - to_chat(L, "You're hit by the drake's fire breath!") - flame_hit[L] = TRUE - else - L.adjustFireLoss(10) //if we've already hit them, do way less damage + L.adjustFireLoss(10) + to_chat(L, "You fall directly into the pool of lava!") + + // deals damage to mechs + for(var/obj/mecha/M in T.contents) + M.take_damage(45, BRUTE, "melee", 1) + + // changes turf to lava temporarily + if(!istype(T, /turf/closed) && !istype(T, /turf/open/lava)) + var/lava_turf = /turf/open/lava/smooth + var/reset_turf = T.type + T.ChangeTurf(lava_turf) + sleep(reset_time) + T.ChangeTurf(reset_turf) + +/obj/effect/temp_visual/drakewall + desc = "An ash drakes true flame." + name = "Fire Barrier" + icon = 'icons/effects/fire.dmi' + icon_state = "1" + anchored = TRUE + opacity = 0 + density = TRUE + CanAtmosPass = ATMOS_PASS_DENSITY + duration = 82 + color = COLOR_DARK_ORANGE + +/obj/effect/temp_visual/lava_safe + icon = 'icons/obj/hand_of_god_structures.dmi' + icon_state = "trap-earth" + layer = BELOW_MOB_LAYER + light_range = 2 + duration = 13 /obj/effect/temp_visual/dragon_swoop name = "certain death" @@ -347,7 +447,7 @@ Difficulty: Medium pixel_x = -32 pixel_y = -32 color = "#FF0000" - duration = 5 + duration = 10 /obj/effect/temp_visual/dragon_flight icon = 'icons/mob/lavaland/64x64megafauna.dmi' @@ -376,7 +476,7 @@ Difficulty: Medium /obj/effect/temp_visual/dragon_flight/end pixel_x = DRAKE_SWOOP_HEIGHT pixel_z = DRAKE_SWOOP_HEIGHT - duration = 5 + duration = 10 /obj/effect/temp_visual/dragon_flight/end/flight(negative) if(negative) @@ -399,6 +499,16 @@ Difficulty: Medium crusher_loot = list() butcher_results = list(/obj/item/stack/ore/diamond = 5, /obj/item/stack/sheet/sinew = 5, /obj/item/stack/sheet/bone = 30) +/mob/living/simple_animal/hostile/megafauna/dragon/lesser/AltClickOn(atom/movable/A) + if(!istype(A)) + return + if(player_cooldown >= world.time) + to_chat(src, "You need to wait [(player_cooldown - world.time) / 10] seconds before swooping again!") + return + swoop_attack(FALSE, A) + lava_pools(10, 2) // less pools but longer delay before spawns + player_cooldown = world.time + 200 // needs seperate cooldown or cant use fire attacks + /mob/living/simple_animal/hostile/megafauna/dragon/lesser/transformed //ash drake balanced around player control name = "transformed ash drake" desc = "A sentient being transformed into an ash drake" From 5327bd399a41b7dad5769279a7d44264bb9e816f Mon Sep 17 00:00:00 2001 From: WanderingFox95 <75953558+WanderingFox95@users.noreply.github.com> Date: Sun, 18 Apr 2021 04:47:05 +0200 Subject: [PATCH 10/75] Modifies Parrots They spawn from hostile triggers, not as friendly pets now. --- code/modules/mob/living/simple_animal/parrot.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mob/living/simple_animal/parrot.dm b/code/modules/mob/living/simple_animal/parrot.dm index d146bb855f..f7e586763b 100644 --- a/code/modules/mob/living/simple_animal/parrot.dm +++ b/code/modules/mob/living/simple_animal/parrot.dm @@ -64,7 +64,7 @@ friendly_verb_simple = "groom" mob_size = MOB_SIZE_SMALL movement_type = FLYING - gold_core_spawnable = FRIENDLY_SPAWN + gold_core_spawnable = HOSTILE_SPAWN var/parrot_damage_upper = 10 var/parrot_state = PARROT_WANDER //Hunt for a perch when created From 8cb23baa926f5ee81c560a295b41358eaa2d64c6 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Tue, 20 Apr 2021 06:53:02 -0500 Subject: [PATCH 11/75] Automatic changelog generation for PR #14443 [ci skip] --- html/changelogs/AutoChangeLog-pr-14443.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-14443.yml diff --git a/html/changelogs/AutoChangeLog-pr-14443.yml b/html/changelogs/AutoChangeLog-pr-14443.yml new file mode 100644 index 0000000000..a145903c14 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-14443.yml @@ -0,0 +1,10 @@ +author: "necromanceranne" +delete-after: True +changes: + - balance: "Stun batons (not police batons/telebatons) no longer knockdown on leftclick." + - balance: "Stun batons apply a knockdown and tase effect on right click, but once every few seconds (they still don't disarm). They are vulnerable to a shove disarm briefly, however. Standard batons have a cooldown of 5 seconds. Stun prods have a cooldown of 7 seconds." + - balance: "Taser resistance prevents the knockdown, so any chem that grants this (like adrenals) protects you from this knockdown." + - balance: "Stun batons apply a stagger when they hit someone, preventing sprinting for a few seconds." + - balance: "Stun batons respect melee armor for their stamina damage, but their cells, based on max charge, grant armor penetration. For every 1000 charge, they gain 1 armor pen. (Roundstart batons have 15 pen, just fyi)" + - balance: "Shoves can disarm you of any item, not just guns." + - bugfix: "Removes a duplicate trait definition for TRAIT_NICE_SHOT." From 8510542260301e2b2b89d42924dc2f9a437d4201 Mon Sep 17 00:00:00 2001 From: silicons <2003111+silicons@users.noreply.github.com> Date: Tue, 20 Apr 2021 04:55:00 -0700 Subject: [PATCH 12/75] Update autobunker.dm --- code/modules/client/verbs/autobunker.dm | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/code/modules/client/verbs/autobunker.dm b/code/modules/client/verbs/autobunker.dm index 03200c5f0b..620854b9ed 100644 --- a/code/modules/client/verbs/autobunker.dm +++ b/code/modules/client/verbs/autobunker.dm @@ -3,6 +3,10 @@ set desc = "Authorizes your account in the panic bunker of any servers connected to this function." set category = "OOC" + if(!(prefs.db_flags & DB_FLAG_AGE_CONFIRMATION_INCOMPLETE)) + to_chat(src, "You are not age verified.") + return + if(autobunker_last_try + 5 SECONDS > world.time) to_chat(src, "Function on cooldown, try again in 5 seconds.") return From ac96276f8ea50294b0a75365de8f6ad4c0a34fd0 Mon Sep 17 00:00:00 2001 From: DrPainis <79603707+DrPainis@users.noreply.github.com> Date: Tue, 20 Apr 2021 16:20:44 -0400 Subject: [PATCH 13/75] literally just changes one letter --- .../mob/living/simple_animal/hostile/megafauna/bubblegum.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm index 72a72d3683..4d54487244 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm @@ -23,7 +23,7 @@ Difficulty: Hard */ /mob/living/simple_animal/hostile/megafauna/bubblegum - name = "bubblegum" + name = "Bubblegum" desc = "In what passes for a hierarchy among slaughter demons, this one is king." health = 2500 maxHealth = 2500 From 00db1679fc9513bfb89d89a5203c96d1f40c5899 Mon Sep 17 00:00:00 2001 From: Changelogs Date: Wed, 21 Apr 2021 00:06:45 +0000 Subject: [PATCH 14/75] Automatic changelog compile [ci skip] --- html/changelog.html | 12 ++++++++++++ html/changelogs/.all_changelog.yml | 16 ++++++++++++++++ html/changelogs/AutoChangeLog-pr-14443.yml | 10 ---------- 3 files changed, 28 insertions(+), 10 deletions(-) delete mode 100644 html/changelogs/AutoChangeLog-pr-14443.yml diff --git a/html/changelog.html b/html/changelog.html index fdd5b3c80d..0661780413 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -50,6 +50,18 @@ -->
+

21 April 2021

+

necromanceranne updated:

+
    +
  • Stun batons (not police batons/telebatons) no longer knockdown on leftclick.
  • +
  • Stun batons apply a knockdown and tase effect on right click, but once every few seconds (they still don't disarm). They are vulnerable to a shove disarm briefly, however. Standard batons have a cooldown of 5 seconds. Stun prods have a cooldown of 7 seconds.
  • +
  • Taser resistance prevents the knockdown, so any chem that grants this (like adrenals) protects you from this knockdown.
  • +
  • Stun batons apply a stagger when they hit someone, preventing sprinting for a few seconds.
  • +
  • Stun batons respect melee armor for their stamina damage, but their cells, based on max charge, grant armor penetration. For every 1000 charge, they gain 1 armor pen. (Roundstart batons have 15 pen, just fyi)
  • +
  • Shoves can disarm you of any item, not just guns.
  • +
  • Removes a duplicate trait definition for TRAIT_NICE_SHOT.
  • +
+

20 April 2021

BlueWildrose updated:

    diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml index 78391070a8..4070c6af4f 100644 --- a/html/changelogs/.all_changelog.yml +++ b/html/changelogs/.all_changelog.yml @@ -29107,3 +29107,19 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py. users zeroisthebiggay: - rscdel: the box ghost burger +2021-04-21: + necromanceranne: + - balance: Stun batons (not police batons/telebatons) no longer knockdown on leftclick. + - balance: Stun batons apply a knockdown and tase effect on right click, but once + every few seconds (they still don't disarm). They are vulnerable to a shove + disarm briefly, however. Standard batons have a cooldown of 5 seconds. Stun + prods have a cooldown of 7 seconds. + - balance: Taser resistance prevents the knockdown, so any chem that grants this + (like adrenals) protects you from this knockdown. + - balance: Stun batons apply a stagger when they hit someone, preventing sprinting + for a few seconds. + - balance: Stun batons respect melee armor for their stamina damage, but their cells, + based on max charge, grant armor penetration. For every 1000 charge, they gain + 1 armor pen. (Roundstart batons have 15 pen, just fyi) + - balance: Shoves can disarm you of any item, not just guns. + - bugfix: Removes a duplicate trait definition for TRAIT_NICE_SHOT. diff --git a/html/changelogs/AutoChangeLog-pr-14443.yml b/html/changelogs/AutoChangeLog-pr-14443.yml deleted file mode 100644 index a145903c14..0000000000 --- a/html/changelogs/AutoChangeLog-pr-14443.yml +++ /dev/null @@ -1,10 +0,0 @@ -author: "necromanceranne" -delete-after: True -changes: - - balance: "Stun batons (not police batons/telebatons) no longer knockdown on leftclick." - - balance: "Stun batons apply a knockdown and tase effect on right click, but once every few seconds (they still don't disarm). They are vulnerable to a shove disarm briefly, however. Standard batons have a cooldown of 5 seconds. Stun prods have a cooldown of 7 seconds." - - balance: "Taser resistance prevents the knockdown, so any chem that grants this (like adrenals) protects you from this knockdown." - - balance: "Stun batons apply a stagger when they hit someone, preventing sprinting for a few seconds." - - balance: "Stun batons respect melee armor for their stamina damage, but their cells, based on max charge, grant armor penetration. For every 1000 charge, they gain 1 armor pen. (Roundstart batons have 15 pen, just fyi)" - - balance: "Shoves can disarm you of any item, not just guns." - - bugfix: "Removes a duplicate trait definition for TRAIT_NICE_SHOT." From 0a5b58730400903e9aff2fcb7a197adf33124c2a Mon Sep 17 00:00:00 2001 From: necromanceranne <40847847+necromanceranne@users.noreply.github.com> Date: Wed, 21 Apr 2021 12:06:34 +1000 Subject: [PATCH 15/75] Adds fake blindfolds. For reasons. --- code/modules/clothing/glasses/_glasses.dm | 6 ++++++ modular_citadel/code/modules/client/loadout/glasses.dm | 4 ++++ 2 files changed, 10 insertions(+) diff --git a/code/modules/clothing/glasses/_glasses.dm b/code/modules/clothing/glasses/_glasses.dm index c79dee926c..01d27531e1 100644 --- a/code/modules/clothing/glasses/_glasses.dm +++ b/code/modules/clothing/glasses/_glasses.dm @@ -358,6 +358,12 @@ ..() user.cure_blind("blindfold_[REF(src)]") +/obj/item/clothing/glasses/fakeblindfold + name = "thin blindfold" + desc = "Covers the eyes, but not thick enough to obscure vision. Mostly for aesthetic." + icon_state = "blindfoldwhite" + item_state = "blindfoldwhite" + /obj/item/clothing/glasses/sunglasses/blindfold/white name = "blind personnel blindfold" desc = "Indicates that the wearer suffers from blindness." diff --git a/modular_citadel/code/modules/client/loadout/glasses.dm b/modular_citadel/code/modules/client/loadout/glasses.dm index b0eecbbf28..f3b07657f4 100644 --- a/modular_citadel/code/modules/client/loadout/glasses.dm +++ b/modular_citadel/code/modules/client/loadout/glasses.dm @@ -6,6 +6,10 @@ name = "Blindfold" path = /obj/item/clothing/glasses/sunglasses/blindfold +/datum/gear/glasses/fakeblindfold + name = "Fake Blindfold" + path = /obj/item/clothing/glasses/fakeblindfold + /datum/gear/glasses/cold name = "Cold goggles" path = /obj/item/clothing/glasses/cold From 57e0056ffcab1b4a46d1e9a637067f56f8dbda4e Mon Sep 17 00:00:00 2001 From: The0bserver Date: Wed, 21 Apr 2021 01:46:33 -0400 Subject: [PATCH 16/75] Spain without the S (Initial Commit) --- code/modules/cargo/packs/security.dm | 5 +---- code/modules/projectiles/guns/ballistic/automatic.dm | 4 ++-- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/code/modules/cargo/packs/security.dm b/code/modules/cargo/packs/security.dm index cf9cc5e0d1..5256240704 100644 --- a/code/modules/cargo/packs/security.dm +++ b/code/modules/cargo/packs/security.dm @@ -80,7 +80,7 @@ /datum/supply_pack/security/russianclothing name = "Russian Surplus Clothing" - desc = "An old russian crate full of surplus armor that they used to use! Has two sets of bulletproff armor, a few union suits and some warm hats!" + desc = "An old russian crate full of surplus armor that they used to use! Has two sets of bulletproof armor, a few union suits and some warm hats!" contraband = TRUE cost = 5750 // Its basicly sec suits, good boots/gloves contains = list(/obj/item/clothing/suit/armor/navyblue/russian, @@ -98,13 +98,11 @@ /obj/item/clothing/mask/gas, /obj/item/clothing/mask/gas) crate_name = "surplus russian clothing" - crate_type = /obj/structure/closet/crate/internals /datum/supply_pack/security/russian_partisan name = "Russian Partisan Gear" desc = "An old russian partisan equipment crate, comes with a full russian outfit, a loaded surplus rifle and a second magazine." contraband = TRUE - access = FALSE cost = 6500 contains = list(/obj/item/clothing/suit/armor/navyblue/russian, /obj/item/clothing/shoes/combat, @@ -114,7 +112,6 @@ /obj/item/clothing/gloves/tackler/combat/insulated, /obj/item/clothing/mask/gas) crate_name = "surplus russian gear" - crate_type = /obj/structure/closet/crate/internals /datum/supply_pack/security/russian_partisan/fill(obj/structure/closet/crate/C) ..() diff --git a/code/modules/projectiles/guns/ballistic/automatic.dm b/code/modules/projectiles/guns/ballistic/automatic.dm index e8d53ddeb8..a3985c8f42 100644 --- a/code/modules/projectiles/guns/ballistic/automatic.dm +++ b/code/modules/projectiles/guns/ballistic/automatic.dm @@ -407,11 +407,11 @@ fire_sound = 'sound/weapons/rifleshot.ogg' weapon_weight = WEAPON_HEAVY mag_type = /obj/item/ammo_box/magazine/m10mm/rifle - fire_delay = 30 + fire_delay = 10 burst_size = 1 can_unsuppress = TRUE can_suppress = TRUE - w_class = WEIGHT_CLASS_HUGE + w_class = WEIGHT_CLASS_BULKY slot_flags = ITEM_SLOT_BACK automatic_burst_overlay = FALSE actions_types = list() From 4e3ab78ebdb2e57ab5a24ba157e2a18957cf6c55 Mon Sep 17 00:00:00 2001 From: The0bserver Date: Wed, 21 Apr 2021 02:25:55 -0400 Subject: [PATCH 17/75] Best to look the part. --- code/modules/cargo/packs/security.dm | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/code/modules/cargo/packs/security.dm b/code/modules/cargo/packs/security.dm index 5256240704..5b0766b460 100644 --- a/code/modules/cargo/packs/security.dm +++ b/code/modules/cargo/packs/security.dm @@ -83,12 +83,12 @@ desc = "An old russian crate full of surplus armor that they used to use! Has two sets of bulletproof armor, a few union suits and some warm hats!" contraband = TRUE cost = 5750 // Its basicly sec suits, good boots/gloves - contains = list(/obj/item/clothing/suit/armor/navyblue/russian, - /obj/item/clothing/suit/armor/navyblue/russian, + contains = list(/obj/item/clothing/under/syndicate/rus_army, + /obj/item/clothing/under/syndicate/rus_army, /obj/item/clothing/shoes/combat, /obj/item/clothing/shoes/combat, - /obj/item/clothing/head/ushanka, - /obj/item/clothing/head/ushanka, + /obj/item/clothing/head/helmet/rus_helmet, + /obj/item/clothing/head/helmet/rus_helmet, /obj/item/clothing/suit/armor/bulletproof, /obj/item/clothing/suit/armor/bulletproof, /obj/item/clothing/head/helmet/alt, @@ -110,6 +110,7 @@ /obj/item/clothing/suit/armor/bulletproof, /obj/item/clothing/head/helmet/alt, /obj/item/clothing/gloves/tackler/combat/insulated, + /obj/item/clothing/under/syndicate/rus_army, /obj/item/clothing/mask/gas) crate_name = "surplus russian gear" From 7102ec121c1b08b1837d4273c7e677b3e350bd6b Mon Sep 17 00:00:00 2001 From: The0bserver Date: Wed, 21 Apr 2021 02:31:08 -0400 Subject: [PATCH 18/75] missed one. --- code/modules/cargo/packs/security.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/cargo/packs/security.dm b/code/modules/cargo/packs/security.dm index 5b0766b460..fd5238fb44 100644 --- a/code/modules/cargo/packs/security.dm +++ b/code/modules/cargo/packs/security.dm @@ -106,7 +106,7 @@ cost = 6500 contains = list(/obj/item/clothing/suit/armor/navyblue/russian, /obj/item/clothing/shoes/combat, - /obj/item/clothing/head/ushanka, + /obj/item/clothing/head/helmet/rus_helmet, /obj/item/clothing/suit/armor/bulletproof, /obj/item/clothing/head/helmet/alt, /obj/item/clothing/gloves/tackler/combat/insulated, From 892dcaf9769219f5259d4f98d8e09157cb9a7b2e Mon Sep 17 00:00:00 2001 From: The0bserver Date: Wed, 21 Apr 2021 02:31:44 -0400 Subject: [PATCH 19/75] dumdum crate now dumdum crate dumdum --- code/modules/cargo/packs/security.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/cargo/packs/security.dm b/code/modules/cargo/packs/security.dm index fd5238fb44..8fc1275e4a 100644 --- a/code/modules/cargo/packs/security.dm +++ b/code/modules/cargo/packs/security.dm @@ -239,7 +239,7 @@ access = FALSE access_any = list(ACCESS_SECURITY, ACCESS_FORENSICS_LOCKERS) contains = list(/obj/item/ammo_box/c38/dumdum) - crate_name = ".38 match crate" + crate_name = ".38 dumdum crate" /datum/supply_pack/security/match name = ".38 Match Grade Speedloader" From 71915b87670a13d405aad887036e11dd906216bb Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Wed, 21 Apr 2021 14:50:50 -0500 Subject: [PATCH 20/75] Automatic changelog generation for PR #14573 [ci skip] --- html/changelogs/AutoChangeLog-pr-14573.yml | 32 ++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-14573.yml diff --git a/html/changelogs/AutoChangeLog-pr-14573.yml b/html/changelogs/AutoChangeLog-pr-14573.yml new file mode 100644 index 0000000000..af1f398cc8 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-14573.yml @@ -0,0 +1,32 @@ +author: "Whoneedspacee" +delete-after: True +changes: + - rscadd: "new arena attack where ash drake summons lava around you" + - rscdel: "removed old swooping above you, instead flies above you instantly" + - balance: "ash drake now spawns temporary lava pools instead of meteors falling down" + - balance: "ash drake takes twice as long to swoop down now that he instantly goes above you" + - balance: "ash drake now moves twice as fast" + - balance: "increases the odds of lava spawns in the lava pool attack" + - balance: "increases fire line damage and decreases lava attacks direct damage +tweak: ash drake fire now shoots in the direction of the target +tweak: changes times of certain animations +tweak: changes sounds of meteor falling to lava creation" + - bugfix: "a bug where ash drakes attacks did not damage mechs" + - imageadd: "changes meteor icon to lava creation animation from lava staff" + - rscadd: "Mass fire attack, sends fire out from the ash drake in all directions" + - rscadd: "Adds an enraged attack for ash drake, heals him as well as making him glow and go faster, spawning massive amounts of fire in all directions" + - rscdel: "Removes the old triple swoop with lava pools attack +tweak: Lava pools can now spawn with the normal fire breath attack sometimes +tweak: Lava pools now have changed delays for lesser amounts so they don't all just place around one area +tweak: Increases default swoop delay" + - balance: "Teleporting out of the lava arena now has some actual consequences by enraging the ash drake" + - bugfix: "Makes lava arena a bit less laggy by not recalculating range_turfs every time" + - bugfix: "Fixes the arena attack selecting inaccessible tiles as the safe tile though this will not change the turfs to basalt temporarily to prevent moving through indestructible walls" + - bugfix: "Fire lines would not spawn if their range would place their final turf location outside of the map" + - bugfix: "The arena attack will no longer destroy indestructible open turfs" + - balance: "ash drake fire does less damage now" + - balance: "ash drake takes longer to swoop down now" + - balance: "tiles take longer to fully convert into lava now, slowing down the arena attack as well" + - balance: "fire breath now moves slower" + - balance: "triple fire breath for the lava swoop only happens below half health now" + - bugfix: "The arena attack not making safespots when you fight it in a mech" From 0404d5890af6b6039e34a156f8fd9d05ec9661d4 Mon Sep 17 00:00:00 2001 From: Changelogs Date: Thu, 22 Apr 2021 00:07:28 +0000 Subject: [PATCH 21/75] Automatic changelog compile [ci skip] --- html/changelog.html | 59 ++++++++++------------ html/changelogs/.all_changelog.yml | 41 +++++++++++++++ html/changelogs/AutoChangeLog-pr-14573.yml | 32 ------------ 3 files changed, 69 insertions(+), 63 deletions(-) delete mode 100644 html/changelogs/AutoChangeLog-pr-14573.yml diff --git a/html/changelog.html b/html/changelog.html index 0661780413..f14078b376 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -50,6 +50,34 @@ -->
    +

    22 April 2021

    +

    Whoneedspacee updated:

    +
      +
    • new arena attack where ash drake summons lava around you
    • +
    • removed old swooping above you, instead flies above you instantly
    • +
    • ash drake now spawns temporary lava pools instead of meteors falling down
    • +
    • ash drake takes twice as long to swoop down now that he instantly goes above you
    • +
    • ash drake now moves twice as fast
    • +
    • increases the odds of lava spawns in the lava pool attack
    • +
    • increases fire line damage and decreases lava attacks direct damage tweak: ash drake fire now shoots in the direction of the target tweak: changes times of certain animations tweak: changes sounds of meteor falling to lava creation
    • +
    • a bug where ash drakes attacks did not damage mechs
    • +
    • changes meteor icon to lava creation animation from lava staff
    • +
    • Mass fire attack, sends fire out from the ash drake in all directions
    • +
    • Adds an enraged attack for ash drake, heals him as well as making him glow and go faster, spawning massive amounts of fire in all directions
    • +
    • Removes the old triple swoop with lava pools attack tweak: Lava pools can now spawn with the normal fire breath attack sometimes tweak: Lava pools now have changed delays for lesser amounts so they don't all just place around one area tweak: Increases default swoop delay
    • +
    • Teleporting out of the lava arena now has some actual consequences by enraging the ash drake
    • +
    • Makes lava arena a bit less laggy by not recalculating range_turfs every time
    • +
    • Fixes the arena attack selecting inaccessible tiles as the safe tile though this will not change the turfs to basalt temporarily to prevent moving through indestructible walls
    • +
    • Fire lines would not spawn if their range would place their final turf location outside of the map
    • +
    • The arena attack will no longer destroy indestructible open turfs
    • +
    • ash drake fire does less damage now
    • +
    • ash drake takes longer to swoop down now
    • +
    • tiles take longer to fully convert into lava now, slowing down the arena attack as well
    • +
    • fire breath now moves slower
    • +
    • triple fire breath for the lava swoop only happens below half health now
    • +
    • The arena attack not making safespots when you fight it in a mech
    • +
    +

    21 April 2021

    necromanceranne updated:

      @@ -863,37 +891,6 @@
      • staring into pierced realities is now logged
      - -

      18 February 2021

      -

      BlueWildrose updated:

      -
        -
      • Admins now receive messages regarding certain holodeck actions.
      • -
      -

      Hatterhat updated:

      -
        -
      • Free Golem Ship GPSes now start as disabled. Like they were supposed to.
      • -
      -

      LetterN updated:

      -
        -
      • No more liver damage when you opt out of "hornychems"
      • -
      -

      SmArtKar updated:

      -
        -
      • Added a new TCG card game
      • -
      -

      dzahlus updated:

      -
        -
      • Removed maroon objective due to toxic gameplay behaviour
      • -
      -

      shellspeed1 updated:

      -
        -
      • floor bots place plating before tiles now.
      • -
      • gets rid of another tile duplication issue.
      • -
      -

      silicons updated:

      -
        -
      • priviledge --> privilege
      • -
    GoonStation 13 Development Team diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml index 4070c6af4f..21084be59e 100644 --- a/html/changelogs/.all_changelog.yml +++ b/html/changelogs/.all_changelog.yml @@ -29123,3 +29123,44 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py. 1 armor pen. (Roundstart batons have 15 pen, just fyi) - balance: Shoves can disarm you of any item, not just guns. - bugfix: Removes a duplicate trait definition for TRAIT_NICE_SHOT. +2021-04-22: + Whoneedspacee: + - rscadd: new arena attack where ash drake summons lava around you + - rscdel: removed old swooping above you, instead flies above you instantly + - balance: ash drake now spawns temporary lava pools instead of meteors falling + down + - balance: ash drake takes twice as long to swoop down now that he instantly goes + above you + - balance: ash drake now moves twice as fast + - balance: increases the odds of lava spawns in the lava pool attack + - balance: 'increases fire line damage and decreases lava attacks direct damage + tweak: ash drake fire now shoots in the direction of the target tweak: changes + times of certain animations tweak: changes sounds of meteor falling to lava + creation' + - bugfix: a bug where ash drakes attacks did not damage mechs + - imageadd: changes meteor icon to lava creation animation from lava staff + - rscadd: Mass fire attack, sends fire out from the ash drake in all directions + - rscadd: Adds an enraged attack for ash drake, heals him as well as making him + glow and go faster, spawning massive amounts of fire in all directions + - rscdel: 'Removes the old triple swoop with lava pools attack tweak: Lava pools + can now spawn with the normal fire breath attack sometimes tweak: Lava pools + now have changed delays for lesser amounts so they don''t all just place around + one area tweak: Increases default swoop delay' + - balance: Teleporting out of the lava arena now has some actual consequences by + enraging the ash drake + - bugfix: Makes lava arena a bit less laggy by not recalculating range_turfs every + time + - bugfix: Fixes the arena attack selecting inaccessible tiles as the safe tile though + this will not change the turfs to basalt temporarily to prevent moving through + indestructible walls + - bugfix: Fire lines would not spawn if their range would place their final turf + location outside of the map + - bugfix: The arena attack will no longer destroy indestructible open turfs + - balance: ash drake fire does less damage now + - balance: ash drake takes longer to swoop down now + - balance: tiles take longer to fully convert into lava now, slowing down the arena + attack as well + - balance: fire breath now moves slower + - balance: triple fire breath for the lava swoop only happens below half health + now + - bugfix: The arena attack not making safespots when you fight it in a mech diff --git a/html/changelogs/AutoChangeLog-pr-14573.yml b/html/changelogs/AutoChangeLog-pr-14573.yml deleted file mode 100644 index af1f398cc8..0000000000 --- a/html/changelogs/AutoChangeLog-pr-14573.yml +++ /dev/null @@ -1,32 +0,0 @@ -author: "Whoneedspacee" -delete-after: True -changes: - - rscadd: "new arena attack where ash drake summons lava around you" - - rscdel: "removed old swooping above you, instead flies above you instantly" - - balance: "ash drake now spawns temporary lava pools instead of meteors falling down" - - balance: "ash drake takes twice as long to swoop down now that he instantly goes above you" - - balance: "ash drake now moves twice as fast" - - balance: "increases the odds of lava spawns in the lava pool attack" - - balance: "increases fire line damage and decreases lava attacks direct damage -tweak: ash drake fire now shoots in the direction of the target -tweak: changes times of certain animations -tweak: changes sounds of meteor falling to lava creation" - - bugfix: "a bug where ash drakes attacks did not damage mechs" - - imageadd: "changes meteor icon to lava creation animation from lava staff" - - rscadd: "Mass fire attack, sends fire out from the ash drake in all directions" - - rscadd: "Adds an enraged attack for ash drake, heals him as well as making him glow and go faster, spawning massive amounts of fire in all directions" - - rscdel: "Removes the old triple swoop with lava pools attack -tweak: Lava pools can now spawn with the normal fire breath attack sometimes -tweak: Lava pools now have changed delays for lesser amounts so they don't all just place around one area -tweak: Increases default swoop delay" - - balance: "Teleporting out of the lava arena now has some actual consequences by enraging the ash drake" - - bugfix: "Makes lava arena a bit less laggy by not recalculating range_turfs every time" - - bugfix: "Fixes the arena attack selecting inaccessible tiles as the safe tile though this will not change the turfs to basalt temporarily to prevent moving through indestructible walls" - - bugfix: "Fire lines would not spawn if their range would place their final turf location outside of the map" - - bugfix: "The arena attack will no longer destroy indestructible open turfs" - - balance: "ash drake fire does less damage now" - - balance: "ash drake takes longer to swoop down now" - - balance: "tiles take longer to fully convert into lava now, slowing down the arena attack as well" - - balance: "fire breath now moves slower" - - balance: "triple fire breath for the lava swoop only happens below half health now" - - bugfix: "The arena attack not making safespots when you fight it in a mech" From 0f04bbb23b4c94ebf1dcd305a1fb12c47677fd91 Mon Sep 17 00:00:00 2001 From: necromanceranne <40847847+necromanceranne@users.noreply.github.com> Date: Thu, 22 Apr 2021 13:06:31 +1000 Subject: [PATCH 22/75] Ports a significant amount of the tg cybernetic organ code while making some additional changes to their power --- code/__DEFINES/_flags/item_flags.dm | 1 + code/game/objects/items/miscellaneous.dm | 4 +- code/modules/cargo/exports/organs_robotics.dm | 15 ++- .../research/designs/medical_designs.dm | 121 ++++++++++++------ .../research/techweb/nodes/medical_nodes.dm | 15 ++- code/modules/surgery/organs/heart.dm | 74 +++++++---- code/modules/surgery/organs/liver.dm | 36 ++++-- code/modules/surgery/organs/lungs.dm | 51 +++++--- code/modules/surgery/organs/organ_internal.dm | 4 + code/modules/surgery/organs/stomach.dm | 34 +++++ icons/obj/surgery.dmi | Bin 44539 -> 45213 bytes 11 files changed, 252 insertions(+), 103 deletions(-) diff --git a/code/__DEFINES/_flags/item_flags.dm b/code/__DEFINES/_flags/item_flags.dm index 7da71e22cb..529499127d 100644 --- a/code/__DEFINES/_flags/item_flags.dm +++ b/code/__DEFINES/_flags/item_flags.dm @@ -51,3 +51,4 @@ #define ORGAN_NO_SPOIL (1<<5) //Do not spoil under any circumstances #define ORGAN_NO_DISMEMBERMENT (1<<6) //Immune to disembowelment. #define ORGAN_EDIBLE (1<<7) //is a snack? :D +#define ORGAN_SYNTHETIC_EMP (1<<6) //Synthetic organ affected by an EMP. Deteriorates over time. diff --git a/code/game/objects/items/miscellaneous.dm b/code/game/objects/items/miscellaneous.dm index 224c4ffb9b..80466832a6 100644 --- a/code/game/objects/items/miscellaneous.dm +++ b/code/game/objects/items/miscellaneous.dm @@ -135,8 +135,8 @@ /obj/item/organ/cyberimp/arm/toolset, /obj/item/organ/cyberimp/arm/surgery, /obj/item/organ/cyberimp/chest/thrusters, - /obj/item/organ/lungs/cybernetic, - /obj/item/organ/liver/cybernetic) //cyberimplants range from a nice bonus to fucking broken bullshit so no subtypesof + /obj/item/organ/lungs/cybernetic/tier3, + /obj/item/organ/liver/cybernetic/tier3) //cyberimplants range from a nice bonus to fucking broken bullshit so no subtypesof for(var/V in templist) var/atom/A = V augment_list[initial(A.name)] = A diff --git a/code/modules/cargo/exports/organs_robotics.dm b/code/modules/cargo/exports/organs_robotics.dm index b65cf28949..08340e6a56 100644 --- a/code/modules/cargo/exports/organs_robotics.dm +++ b/code/modules/cargo/exports/organs_robotics.dm @@ -75,7 +75,7 @@ cost = 250 unit_name = "heart" export_types = list(/obj/item/organ/heart) - exclude_types = list(/obj/item/organ/heart/cursed, /obj/item/organ/heart/cybernetic) + exclude_types = list(/obj/item/organ/heart/cursed, /obj/item/organ/heart/cybernetic/tier2, /obj/item/organ/heart/cybernetic/tier3) /datum/export/organs/tongue cost = 75 @@ -92,29 +92,30 @@ cost = 50 //can be replaced unit_name = "stomach" export_types = list(/obj/item/organ/stomach) + exclude_types = list(/obj/item/organ/stomach/cybernetic/tier2, /obj/item/organ/stomach/cybernetic/tier3) /datum/export/organs/lungs cost = 150 unit_name = "lungs" - export_types = list(/obj/item/organ/lungs) - exclude_types = list(/obj/item/organ/lungs/cybernetic, /obj/item/organ/lungs/cybernetic/upgraded) + export_types = list(/obj/item/organ/lungs,) + exclude_types = list(/obj/item/organ/lungs/cybernetic/tier2, /obj/item/organ/lungs/cybernetic/tier3) /datum/export/organs/liver cost = 175 unit_name = "liver" export_types = list(/obj/item/organ/liver) - exclude_types = list(/obj/item/organ/liver/cybernetic, /obj/item/organ/liver/cybernetic/upgraded) + exclude_types = list(/obj/item/organ/liver/cybernetic/tier2, /obj/item/organ/liver/cybernetic/tier3) /datum/export/organs/cybernetic cost = 225 unit_name = "cybernetic organ" - export_types = list(/obj/item/organ/liver/cybernetic, /obj/item/organ/lungs/cybernetic, /obj/item/organ/eyes/robotic, /obj/item/organ/heart/cybernetic) - exclude_types = list(/obj/item/organ/lungs/cybernetic/upgraded, /obj/item/organ/liver/cybernetic/upgraded) + export_types = list(/obj/item/organ/liver/cybernetic/tier2, /obj/item/organ/lungs/cybernetic/tier2, /obj/item/organ/eyes/robotic/shield, /obj/item/organ/eyes/robotic/glow, /obj/item/organ/stomach/cybernetic/tier2, /obj/item/organ/heart/cybernetic/tier2) + exclude_types = list(/obj/item/organ/liver/cybernetic/tier3, /obj/item/organ/lungs/cybernetic/tier3, /obj/item/organ/eyes/robotic/xray, /obj/item/organ/eyes/robotic/thermals, /obj/item/organ/stomach/cybernetic/tier3, /obj/item/organ/heart/cybernetic/tier3) /datum/export/organs/upgraded cost = 275 unit_name = "upgraded cybernetic organ" - export_types = list(/obj/item/organ/lungs/cybernetic/upgraded, /obj/item/organ/liver/cybernetic/upgraded) + export_types = list(/obj/item/organ/liver/cybernetic/tier3, /obj/item/organ/lungs/cybernetic/tier3, /obj/item/organ/eyes/robotic/xray, /obj/item/organ/eyes/robotic/thermals, /obj/item/organ/stomach/cybernetic/tier3, /obj/item/organ/heart/cybernetic/tier3) /datum/export/organs/tail // yeah have fun pulling this off someone without catching a bwoink cost = 500 diff --git a/code/modules/research/designs/medical_designs.dm b/code/modules/research/designs/medical_designs.dm index e45434cec4..bb5989e5c6 100644 --- a/code/modules/research/designs/medical_designs.dm +++ b/code/modules/research/designs/medical_designs.dm @@ -644,66 +644,109 @@ //Cybernetic organs /datum/design/cybernetic_liver - name = "Cybernetic Liver" - desc = "A cybernetic liver" + name = "Basic Cybernetic Liver" + desc = "A basic cybernetic liver." id = "cybernetic_liver" build_type = PROTOLATHE | MECHFAB + construction_time = 40 materials = list(/datum/material/iron = 500, /datum/material/glass = 500) build_path = /obj/item/organ/liver/cybernetic - category = list("Misc","Medical Designs") - departmental_flags = DEPARTMENTAL_FLAG_MEDICAL - -/datum/design/cybernetic_heart - name = "Cybernetic Heart" - desc = "A cybernetic heart" - id = "cybernetic_heart" - build_type = PROTOLATHE | MECHFAB - materials = list(/datum/material/iron = 500, /datum/material/glass = 500) - build_path = /obj/item/organ/heart/cybernetic - category = list("Misc","Medical Designs") - departmental_flags = DEPARTMENTAL_FLAG_MEDICAL - -/datum/design/cybernetic_heart_u - name = "Upgraded Cybernetic Heart" - desc = "An upgraded cybernetic heart" - id = "cybernetic_heart_u" - build_type = PROTOLATHE | MECHFAB - construction_time = 50 - materials = list(/datum/material/iron = 500, /datum/material/glass = 500, /datum/material/silver = 500) - build_path = /obj/item/organ/heart/cybernetic/upgraded category = list("Misc", "Medical Designs") departmental_flags = DEPARTMENTAL_FLAG_MEDICAL -/datum/design/cybernetic_liver_u - name = "Upgraded Cybernetic Liver" - desc = "An upgraded cybernetic liver" - id = "cybernetic_liver_u" - build_type = PROTOLATHE | MECHFAB +/datum/design/cybernetic_liver/tier2 + name = "Cybernetic Liver" + desc = "A cybernetic liver." + id = "cybernetic_liver_tier2" materials = list(/datum/material/iron = 500, /datum/material/glass = 500) - build_path = /obj/item/organ/liver/cybernetic/upgraded - category = list("Misc","Medical Designs") + build_path = /obj/item/organ/liver/cybernetic/tier2 + +/datum/design/cybernetic_liver/tier3 + name = "Upgraded Cybernetic Liver" + desc = "An upgraded cybernetic liver." + id = "cybernetic_liver_tier3" + construction_time = 50 + materials = list(/datum/material/iron = 500, /datum/material/glass = 500, /datum/material/silver = 600, /datum/material/gold = 600, /datum/material/plasma = 1000, /datum/material/diamond = 2000) + build_path = /obj/item/organ/liver/cybernetic/tier3 + +/datum/design/cybernetic_heart + name = "Basic Cybernetic Heart" + desc = "A basic cybernetic heart." + id = "cybernetic_heart" + build_type = PROTOLATHE | MECHFAB + construction_time = 40 + materials = list(/datum/material/iron = 500, /datum/material/glass = 500) + build_path = /obj/item/organ/heart/cybernetic + category = list("Misc", "Medical Designs") departmental_flags = DEPARTMENTAL_FLAG_MEDICAL +/datum/design/cybernetic_heart/tier2 + name = "Cybernetic Heart" + desc = "A cybernetic heart." + id = "cybernetic_heart_tier2" + materials = list(/datum/material/iron = 500, /datum/material/glass = 500) + build_path = /obj/item/organ/heart/cybernetic/tier2 + +/datum/design/cybernetic_heart/tier3 + name = "Upgraded Cybernetic Heart" + desc = "An upgraded cybernetic heart." + id = "cybernetic_heart_tier3" + construction_time = 50 + materials = list(/datum/material/iron = 500, /datum/material/glass = 500, /datum/material/silver = 600, /datum/material/gold = 600, /datum/material/plasma = 1000, /datum/material/diamond = 2000) + build_path = /obj/item/organ/heart/cybernetic/tier3 + /datum/design/cybernetic_lungs - name = "Cybernetic Lungs" - desc = "A pair of cybernetic lungs." + name = "Basic Cybernetic Lungs" + desc = "A basic pair of cybernetic lungs." id = "cybernetic_lungs" build_type = PROTOLATHE | MECHFAB + construction_time = 40 materials = list(/datum/material/iron = 500, /datum/material/glass = 500) build_path = /obj/item/organ/lungs/cybernetic - category = list("Misc","Medical Designs") + category = list("Misc", "Medical Designs") departmental_flags = DEPARTMENTAL_FLAG_MEDICAL -/datum/design/cybernetic_lungs_u +/datum/design/cybernetic_lungs/tier2 + name = "Cybernetic Lungs" + desc = "A pair of cybernetic lungs." + id = "cybernetic_lungs_tier2" + materials = list(/datum/material/iron = 500, /datum/material/glass = 500) + build_path = /obj/item/organ/lungs/cybernetic/tier2 + +/datum/design/cybernetic_lungs/tier3 name = "Upgraded Cybernetic Lungs" desc = "A pair of upgraded cybernetic lungs." - id = "cybernetic_lungs_u" + id = "cybernetic_lungs_tier3" + construction_time = 50 + materials = list(/datum/material/iron = 500, /datum/material/glass = 500, /datum/material/silver = 600, /datum/material/gold = 600, /datum/material/plasma = 1000, /datum/material/diamond = 2000) + build_path = /obj/item/organ/lungs/cybernetic/tier3 + +/datum/design/cybernetic_stomach + name = "Basic Cybernetic Stomach" + desc = "A basic cybernetic stomach." + id = "cybernetic_stomach" build_type = PROTOLATHE | MECHFAB - materials = list(/datum/material/iron = 500, /datum/material/glass = 500, /datum/material/silver = 500) - build_path = /obj/item/organ/lungs/cybernetic/upgraded - category = list("Misc","Medical Designs") + construction_time = 40 + materials = list(/datum/material/iron = 500, /datum/material/glass = 500) + build_path = /obj/item/organ/stomach/cybernetic + category = list("Misc", "Medical Designs") departmental_flags = DEPARTMENTAL_FLAG_MEDICAL +/datum/design/cybernetic_stomach/tier2 + name = "Cybernetic Stomach" + desc = "A cybernetic stomach." + id = "cybernetic_stomach_tier2" + materials = list(/datum/material/iron = 500, /datum/material/glass = 500) + build_path = /obj/item/organ/stomach/cybernetic/tier2 + +/datum/design/cybernetic_stomach/tier3 + name = "Upgraded Cybernetic Stomach" + desc = "An upgraded cybernetic stomach." + id = "cybernetic_stomach_tier3" + construction_time = 50 + materials = list(/datum/material/iron = 500, /datum/material/glass = 500, /datum/material/silver = 600, /datum/material/gold = 600, /datum/material/plasma = 1000, /datum/material/diamond = 2000) + build_path = /obj/item/organ/stomach/cybernetic/tier3 + /datum/design/cybernetic_tongue name = "Cybernetic tongue" desc = "A fancy cybernetic tongue." @@ -711,7 +754,7 @@ build_type = PROTOLATHE | MECHFAB materials = list(/datum/material/iron = 500, /datum/material/glass = 500) build_path = /obj/item/organ/tongue/cybernetic - category = list("Misc","Medical Designs") + category = list("Misc", "Medical Designs") departmental_flags = DEPARTMENTAL_FLAG_MEDICAL /datum/design/cybernetic_ears diff --git a/code/modules/research/techweb/nodes/medical_nodes.dm b/code/modules/research/techweb/nodes/medical_nodes.dm index 0eca3ea877..1d7d579dad 100644 --- a/code/modules/research/techweb/nodes/medical_nodes.dm +++ b/code/modules/research/techweb/nodes/medical_nodes.dm @@ -67,20 +67,27 @@ design_ids = list("implanter", "implantcase", "implant_chem", "implant_tracking", "locator", "c38_trac") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) +/datum/techweb_node/basic_cyber_organs + id = "basic_cyber_organs" + starting_node = TRUE + display_name = "Basic Cybernetic Organs" + description = "We have the techinology to force him to live a disgusting halflife." + design_ids = list("cybernetic_liver", "cybernetic_heart", "cybernetic_lungs", "cybernetic_stomach") + /datum/techweb_node/cyber_organs id = "cyber_organs" display_name = "Cybernetic Organs" description = "We have the technology to rebuild him." - prereq_ids = list("adv_biotech") - design_ids = list("cybernetic_ears", "cybernetic_heart", "cybernetic_liver", "cybernetic_lungs", "cybernetic_tongue") + prereq_ids = list("biotech") + design_ids = list("cybernetic_ears", "cybernetic_heart_tier2", "cybernetic_liver_tier2", "cybernetic_lungs_tier2", "cybernetic_stomach_tier2") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 1000) /datum/techweb_node/cyber_organs_upgraded id = "cyber_organs_upgraded" display_name = "Upgraded Cybernetic Organs" description = "We have the technology to upgrade him." - prereq_ids = list("cyber_organs") - design_ids = list("cybernetic_ears_u", "cybernetic_heart_u", "cybernetic_liver_u", "cybernetic_lungs_u", "ipc_stomach") + prereq_ids = list("adv_biotech", "cyber_organs") + design_ids = list("cybernetic_ears_u", "cybernetic_heart_tier3", "cybernetic_liver_tier3", "cybernetic_lungs_tier3", "cybernetic_stomach_tier3") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 1500) /datum/techweb_node/cyber_implants diff --git a/code/modules/surgery/organs/heart.dm b/code/modules/surgery/organs/heart.dm index 4dba68ada3..2079e729f4 100644 --- a/code/modules/surgery/organs/heart.dm +++ b/code/modules/surgery/organs/heart.dm @@ -197,45 +197,67 @@ colour = "red" /obj/item/organ/heart/cybernetic - name = "cybernetic heart" - desc = "An electronic device designed to mimic the functions of an organic human heart. Offers no benefit over an organic heart other than being easy to make." + name = "basic cybernetic heart" + desc = "A basic electronic device designed to mimic the functions of an organic human heart." icon_state = "heart-c" organ_flags = ORGAN_SYNTHETIC + maxHealth = STANDARD_ORGAN_THRESHOLD*0.75 //This also hits defib timer, so a bit higher than its less important counterparts + + var/dose_available = FALSE + var/rid = /datum/reagent/medicine/epinephrine + var/ramount = 10 + var/emp_vulnerability = 80 //Chance of permanent effects if emp-ed. + +/obj/item/organ/heart/cybernetic/tier2 + name = "cybernetic heart" + desc = "An electronic device designed to mimic the functions of an organic human heart. Also holds an emergency dose of epinephrine, used automatically after facing severe trauma." + icon_state = "heart-c-u" + maxHealth = 1.5 * STANDARD_ORGAN_THRESHOLD + dose_available = TRUE + emp_vulnerability = 40 + +/obj/item/organ/heart/cybernetic/tier3 + name = "upgraded cybernetic heart" + desc = "An electronic device designed to mimic the functions of an organic human heart. Also holds an emergency dose of epinephrine, used automatically after facing severe trauma. This upgraded model can regenerate its dose after use." + icon_state = "heart-c-u2" + maxHealth = 2 * STANDARD_ORGAN_THRESHOLD + dose_available = TRUE + rid = /datum/reagent/medicine/atropine + ramount = 5 + emp_vulnerability = 20 /obj/item/organ/heart/cybernetic/emp_act(severity) . = ..() + + // If the owner doesn't need a heart, we don't need to do anything with it. + if(!owner.needs_heart()) + return + if(. & EMP_PROTECT_SELF) return - Stop() - addtimer(CALLBACK(src, .proc/Restart), 0.2*severity SECONDS) - damage += severity + if(!COOLDOWN_FINISHED(src, severe_cooldown)) //So we cant just spam emp to kill people. + owner.Dizzy(10) + owner.losebreath += 10 + COOLDOWN_START(src, severe_cooldown, 20 SECONDS) + if(prob(emp_vulnerability/severity)) //Chance of permanent effects + organ_flags |= ORGAN_SYNTHETIC_EMP //Starts organ faliure - gonna need replacing soon. + Stop() + owner.visible_message("[owner] clutches at [owner.p_their()] chest as if [owner.p_their()] heart is stopping!", \ + "You feel a terrible pain in your chest, as if your heart has stopped!") + addtimer(CALLBACK(src, .proc/Restart), 10 SECONDS) -/obj/item/organ/heart/cybernetic/upgraded - name = "upgraded cybernetic heart" - desc = "An electronic device designed to mimic the functions of an organic human heart. Also holds an emergency dose of epinephrine, used automatically after facing severe trauma. This upgraded model can regenerate its dose after use." - icon_state = "heart-c-u" - maxHealth = 2 * STANDARD_ORGAN_THRESHOLD - - //I put it on upgraded for now. - var/dose_available = TRUE - var/rid = /datum/reagent/medicine/epinephrine - var/ramount = 10 - -/obj/item/organ/heart/cybernetic/upgraded/on_life() +/obj/item/organ/heart/cybernetic/on_life(delta_time, times_fired) . = ..() - if(!.) - return if(dose_available && owner.health <= owner.crit_threshold && !owner.reagents.has_reagent(rid)) - owner.reagents.add_reagent(rid, ramount) used_dose() - if(ramount < 10) //eats your nutrition to regen epinephrine - var/regen_amount = owner.nutrition/2000 - owner.adjust_nutrition(-regen_amount) - ramount += regen_amount -/obj/item/organ/heart/cybernetic/upgraded/proc/used_dose() +/obj/item/organ/heart/cybernetic/proc/used_dose() + owner.reagents.add_reagent(rid, ramount) + dose_available = FALSE + +/obj/item/organ/heart/cybernetic/tier3/used_dose() + . = ..() addtimer(VARSET_CALLBACK(src, dose_available, TRUE), 5 MINUTES) - ramount = 0 /obj/item/organ/heart/ipc name = "IPC heart" diff --git a/code/modules/surgery/organs/liver.dm b/code/modules/surgery/organs/liver.dm index 749f5a8c38..afc770efae 100755 --- a/code/modules/surgery/organs/liver.dm +++ b/code/modules/surgery/organs/liver.dm @@ -98,23 +98,41 @@ icon_state = "liver-c" /obj/item/organ/liver/cybernetic - name = "cybernetic liver" + name = "basic cybernetic liver" icon_state = "liver-c" - desc = "An electronic device designed to mimic the functions of a human liver. It has no benefits over an organic liver, but is easy to produce." + desc = "A very basic device designed to mimic the functions of a human liver. Handles toxins slightly worse than an organic liver." organ_flags = ORGAN_SYNTHETIC - maxHealth = 1.1 * STANDARD_ORGAN_THRESHOLD + toxTolerance = 0.3 * LIVER_DEFAULT_TOX_TOLERANCE //little less than 1u of toxin purging + toxLethality = 1.1 * LIVER_DEFAULT_TOX_LETHALITY + maxHealth = STANDARD_ORGAN_THRESHOLD*0.5 -/obj/item/organ/liver/cybernetic/upgraded - name = "upgraded cybernetic liver" + var/emp_vulnerability = 80 //Chance of permanent effects if emp-ed. + +/obj/item/organ/liver/cybernetic/tier2 + name = "cybernetic liver" icon_state = "liver-c-u" - desc = "An upgraded version of the cybernetic liver, designed to improve upon organic livers. It is resistant to alcohol poisoning and is very robust at filtering toxins." + desc = "An electronic device designed to mimic the functions of a human liver. Handles toxins slightly better than an organic liver." + maxHealth = 1.5 * STANDARD_ORGAN_THRESHOLD + toxTolerance = 2 * LIVER_DEFAULT_TOX_TOLERANCE //6 units of toxin purging + toxLethality = 0.8 * LIVER_DEFAULT_TOX_LETHALITY //20% less damage than a normal liver + emp_vulnerability = 40 + +/obj/item/organ/liver/cybernetic/tier3 + name = "upgraded cybernetic liver" + icon_state = "liver-c-u2" + desc = "An upgraded version of the cybernetic liver, designed to improve further upon organic livers. It is resistant to alcohol poisoning and is very robust at filtering toxins." alcohol_tolerance = 0.001 maxHealth = 2 * STANDARD_ORGAN_THRESHOLD - toxTolerance = 15 //can shrug off up to 15u of toxins - toxLethality = 0.008 //20% less damage than a normal liver + toxTolerance = 5 * LIVER_DEFAULT_TOX_TOLERANCE //15 units of toxin purging + toxLethality = 0.4 * LIVER_DEFAULT_TOX_LETHALITY //60% less damage than a normal liver + emp_vulnerability = 20 /obj/item/organ/liver/cybernetic/emp_act(severity) . = ..() if(. & EMP_PROTECT_SELF) return - damage += severity + if(!COOLDOWN_FINISHED(src, severe_cooldown)) //So we cant just spam emp to kill people. + owner.adjustToxLoss(10) + COOLDOWN_START(src, severe_cooldown, 10 SECONDS) + if(prob(emp_vulnerability/severity)) //Chance of permanent effects + organ_flags |= ORGAN_SYNTHETIC_EMP //Starts organ faliure - gonna need replacing soon. diff --git a/code/modules/surgery/organs/lungs.dm b/code/modules/surgery/organs/lungs.dm index 083c71fda2..73fbe3412c 100644 --- a/code/modules/surgery/organs/lungs.dm +++ b/code/modules/surgery/organs/lungs.dm @@ -547,33 +547,52 @@ maxHealth = INFINITY//I don't understand how plamamen work, so I'm not going to try t give them special lungs atm /obj/item/organ/lungs/cybernetic - name = "cybernetic lungs" - desc = "A cybernetic version of the lungs found in traditional humanoid entities. It functions the same as an organic lung and is merely meant as a replacement." + name = "basic cybernetic lungs" + desc = "A basic cybernetic version of the lungs found in traditional humanoid entities." icon_state = "lungs-c" organ_flags = ORGAN_SYNTHETIC - maxHealth = 400 - safe_oxygen_min = 13 + maxHealth = STANDARD_ORGAN_THRESHOLD * 0.5 -/obj/item/organ/lungs/cybernetic/emp_act() - . = ..() - if(. & EMP_PROTECT_SELF) - return - owner.losebreath = 20 - owner.adjustOrganLoss(ORGAN_SLOT_LUNGS, 25) + var/emp_vulnerability = 80 //Chance of permanent effects if emp-ed. -/obj/item/organ/lungs/cybernetic/upgraded - name = "upgraded cybernetic lungs" - desc = "A more advanced version of the stock cybernetic lungs. They are capable of filtering out lower levels of toxins and carbon dioxide." +/obj/item/organ/lungs/cybernetic/tier2 + name = "cybernetic lungs" + desc = "A cybernetic version of the lungs found in traditional humanoid entities. Allows for greater intakes of oxygen than organic lungs, requiring slightly less pressure." icon_state = "lungs-c-u" - safe_toxins_max = 20 - safe_co2_max = 20 - safe_oxygen_max = 250 + maxHealth = 1.5 * STANDARD_ORGAN_THRESHOLD + safe_oxygen_min = 13 + safe_oxygen_max = 100 + emp_vulnerability = 40 + +/obj/item/organ/lungs/cybernetic/tier3 + name = "upgraded cybernetic lungs" + desc = "A more advanced version of the stock cybernetic lungs. Features the ability to filter out various airbourne toxins and carbon dioxide even at heavy levels." + icon_state = "lungs-c-u2" + maxHealth = 2 * STANDARD_ORGAN_THRESHOLD + safe_oxygen_min = 4 //You could literally be breathing the thinnest amount of oxygen and be fine + safe_oxygen_max = 250 //Or be in an enriched oxygen room for that matter + safe_toxins_max = 50 + safe_co2_max = 50 + SA_para_min = 50 + SA_sleep_min = 100 + BZ_trip_balls_min = 50 + emp_vulnerability = 20 cold_level_1_threshold = 200 cold_level_2_threshold = 140 cold_level_3_threshold = 100 maxHealth = 550 +/obj/item/organ/lungs/cybernetic/emp_act(severity) + . = ..() + if(. & EMP_PROTECT_SELF) + return + if(!COOLDOWN_FINISHED(src, severe_cooldown)) //So we cant just spam emp to kill people. + owner.losebreath += 20 + COOLDOWN_START(src, severe_cooldown, 30 SECONDS) + if(prob(emp_vulnerability/severity)) //Chance of permanent effects + organ_flags |= ORGAN_SYNTHETIC_EMP //Starts organ faliure - gonna need replacing soon. + /obj/item/organ/lungs/ashwalker name = "ash lungs" desc = "blackened lungs identical from specimens recovered from lavaland, unsuited to higher air pressures." diff --git a/code/modules/surgery/organs/organ_internal.dm b/code/modules/surgery/organs/organ_internal.dm index cb4de69fbd..6cdeadcbb3 100644 --- a/code/modules/surgery/organs/organ_internal.dm +++ b/code/modules/surgery/organs/organ_internal.dm @@ -16,6 +16,7 @@ var/decay_factor = 0 //same as above but when without a living owner, set to 0 for generic organs var/high_threshold = STANDARD_ORGAN_THRESHOLD * 0.45 //when severe organ damage occurs var/low_threshold = STANDARD_ORGAN_THRESHOLD * 0.1 //when minor organ damage occurs + var/severe_cooldown //cooldown for severe effects, used for synthetic organ emp effects. ///Organ variables for determining what we alert the owner with when they pass/clear the damage thresholds var/prev_damage = 0 @@ -153,6 +154,9 @@ /obj/item/organ/proc/on_life() //repair organ damage if the organ is not failing or synthetic if(organ_flags & ORGAN_FAILING || !owner) return FALSE + if(organ_flags & ORGAN_SYNTHETIC_EMP) //Synthetic organ has been emped, is now failing. + applyOrganDamage(maxHealth * decay_factor) + return if(!is_cold() && damage) ///Damage decrements by a percent of its maxhealth var/healing_amount = -(maxHealth * healing_factor) diff --git a/code/modules/surgery/organs/stomach.dm b/code/modules/surgery/organs/stomach.dm index ba7b950602..f286c294fc 100644 --- a/code/modules/surgery/organs/stomach.dm +++ b/code/modules/surgery/organs/stomach.dm @@ -93,6 +93,40 @@ icon_state = "stomach-p" desc = "A strange crystal that is responsible for metabolizing the unseen energy force that feeds plasmamen." +/obj/item/organ/stomach/cybernetic + name = "basic cybernetic stomach" + icon_state = "stomach-c" + desc = "A basic device designed to mimic the functions of a human stomach" + organ_flags = ORGAN_SYNTHETIC + maxHealth = STANDARD_ORGAN_THRESHOLD * 0.5 + var/emp_vulnerability = 80 //Chance of permanent effects if emp-ed. + +/obj/item/organ/stomach/cybernetic/tier2 + name = "cybernetic stomach" + icon_state = "stomach-c-u" + desc = "An electronic device designed to mimic the functions of a human stomach. Handles disgusting food a bit better." + maxHealth = 1.5 * STANDARD_ORGAN_THRESHOLD + disgust_metabolism = 2 + emp_vulnerability = 40 + +/obj/item/organ/stomach/cybernetic/tier3 + name = "upgraded cybernetic stomach" + icon_state = "stomach-c-u2" + desc = "An upgraded version of the cybernetic stomach, designed to improve further upon organic stomachs. Handles disgusting food very well." + maxHealth = 2 * STANDARD_ORGAN_THRESHOLD + disgust_metabolism = 3 + emp_vulnerability = 20 + +/obj/item/organ/stomach/cybernetic/emp_act(severity) + . = ..() + if(. & EMP_PROTECT_SELF) + return + if(!COOLDOWN_FINISHED(src, severe_cooldown)) //So we cant just spam emp to kill people. + owner.vomit(stun = FALSE) + COOLDOWN_START(src, severe_cooldown, 10 SECONDS) + if(prob(emp_vulnerability/severity)) //Chance of permanent effects + organ_flags |= ORGAN_SYNTHETIC_EMP //Starts organ faliure - gonna need replacing soon. + /obj/item/organ/stomach/ipc name = "ipc cell" icon_state = "stomach-ipc" diff --git a/icons/obj/surgery.dmi b/icons/obj/surgery.dmi index 0460934eee163988b724d4398cf7cade6593aadd..52172bbe292a5303fda2eaa53d57428de1d43aa0 100755 GIT binary patch literal 45213 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 ZNBJ{g!`6M7mjnWSo;=joEYYwI`yU6Nb`Agl literal 44539 zcmbrlbx<8m6g@b&1_+DH?hZSA zKdIf?{bRSbim9a_G-SQcW-p4u#|A?66!}{Ay>ZE?obM-wnwIf|pAd zA>!W+MmCuD2kdIxAA{=WhTMnc+5M!gt|RK=6DO-o2-)^42|Y^HTD=DaeetIo>f}F4 zZN(S}2hh%zuyDRdDJDoL=nK;sIgFOSxR$f#q3iXq^&}9P`?W4a5sSeP+5e{a0qU}W zOX)&9#jg5sVe@mc0iNTrazf$QD%mS~h1yPm#DwMI9>(+eWa3`L5tLg>e~YPQ)%=Tw z5Ui;t5j+jc$f<|zu;C~=yLObyLa~tSd<-GZ2toH?5_;U0kk|!}c7#02563Z2UADqB zB5zf-=|e8eFa+x7!fm+dRNHKs!gI|U$4*5);M*z$&Do3bhB%U6pQG&SfBdHa2%}Q$ zSo<$LhP|Lbjj|3c5~grYVn>fh(4dntCCw7|v5VjNp_tWMj7HroRpG>&%T-T^#J5%M zp8H6qG@pw$}-NtDK%pcCDZ_pm;MI-Le0LLs}6+)fc1f;a=^yfh)4Cs-f6 zwN+Q)&R!}rV6$^wUEgvwR)}xf-KE3s>kDa8uMU6b=aBQ!D$7}J&(17_Re&o=p$V7A z8Kx*6vvQnAnM-?PDXB`80%MuWR{9t}!9Kn2=(sN>_B~>j)K*~n(`_x8snruuV&^@{ z`r$6(=VUQQ?#uAA`A?G4w*o#)dWmVbFwOTrEy?*)+pu_9{YLK=*{aoUMj##pv*DfO zgjeUYK8?)UEkCuL0yY+}e(T3)i;sONmr`zUM9evlJd9M&N~NnK&aFY*o?PYod(qEb z$L*^raK;_H`jfcC+;o;QNg7oKiQ?K?%(hRGl1|l_=M^owwNP~)Y4y%;)SGhs(DR6# zRaKiq>&W1uBk3$c8DRc330JCNHXG-|mvRskU!?GH+tePu&9?FPG?H zV{@gBVfGZIy>x+ifT2BMuP%&-V|pnoZJoZQ$*CXS)#tc;PWbay+N>pWcy6$A zn-t+9*pXf6#q9p#Sjqlw|Jf}ER^GK9FTqX`08j%8Z=^K6viEa5{qQXw`z2(2Xwekj z($^=jhK|F3rBbG0mX(xLm2AeF?ncfgZ=4bdL}$=SmYEPqSwqWYjEr(GL=763ek(1F zk!4Svb6$IQ|ClbCG(S>&v`=^J4>j^0IpnE3%UQ}9_U%~N&d}{-N(iDx4W>rjGh+$l zz6+YACo3@+mDW*(A{+nN-428qE@A*`#L4Kuwd@XBmCECbjzjlR)2|j;N;rs8IG)If z5G#peVT>J0>XElC*+@V_Q^s2UL72-!&X)|0AbbZ7eB`38vLp#!^_MT?W64I|c7c!e zEXAzi55#Pc35jAZoRj|<9_S5fFUiVAB0?^r8MVU)e>^b84(q*c_A#Df;6@jyTF!rW zjrG-db`TTrxj>g4UcTB9p+^n2hL@w?8Te}&iMj^|2)fb1tsj!mDWqHVd_whw?>_l) zo;=j_mHWK+TF^kCa3bg@g?iq{yH7d8TO<0^`mQ8($)Q6$B6Ffo_h%nK8^my3cA`+t z2_X}or|Jku;e;*_qv>Sj(kg4PTPbXA_uYn^`E(!y0}mEF!0OLe%FVe21DCkW;|U+P zNAw}bk!mp%^JDw>Gu7_9lmAGjO3q5am;OF#XK;5$|H$i_Kpp83&qjTDCWnPBbAQD2 z++L=%I?lsfsYz*r4!9+RRkEG1d=n?@DYwGikr;!IMkAr}J7R)4_h=T4%=wxm=|fGg z2IDB^u}7tF0Fx1x>U44vb7TiOITQdD6BRHY9{(zXq7QsXjgrDa{7TqZ`~rMw;jqA& z?Q6hfQMC$VOrkwV77M$(O}-!1N_ENPbhnr-g4lR8lT0;|Q5ShDUD0E%`X!LcW%4G+ zLPLY2fq6#5EtLnjUJb!M$PIk-R%qn08s4EsmEQC{LgQBn8XhmDMsz_r-i%nR^u29G z+1^7ZV)Jsm+_rVXo)G?=l29H6w( zaY>k$mUew(vPh|{frNy@R&mmYSr#w!?O5)E3(2-Pf+W17)$~hFA`U>I3uxP za3XCL%b5hud;^l}`-_~ell7tWmW!yP1Cg1!EEc1{_4Ukc>;~bjBBchB^N}n8JbMQR z3W@p4+*oQ>tH>yL^I<>|V7(GY`_}$mb9H4a;0hz$ajGr`Oh_OoTNoJSx-SJx-z z0OUiNw&|AG5dH(E?*;k?*9!oW-hPDEA5Vqw#M9eJuU2#5bvbXPbl_L^>lZiT?iOkehRcUkF>B{ z$GiYPMhK-$tEvJ+gYNwF?}wy5?pmYNqBry;Y}IZ8HtWB18kos_}<%py2(KCl0=rp*w;Lss1?P-jp+wz)VF`O^fE8e z&9q>C^>uSiO1$9)9YlB<;|!vhonmb#JNvR)yC`w2*QTW!TI3+z#=7Wy+6`##!I>Hhc8)@&>1qC1 zBpd++iyCaby1Kg8daQu+DlACO_^gl2iQ05l;-w2M8Cv5ZV}9oy%3fa8nshK1*|l_3Bp*XI#eWXdGTQJp9#xv`wU`XQx*CDv8Gn zK~w2D6)wGhe&z0vVgr9uiE=KQ>M)r{-W&QtfAPC%3qMQo#qw+c#k&< z2Q>QC=_ek6VZ#abF*-hOi#G2+XW9Kn+S6&wVbQ2MqC08^eWK(m$j2^Uxpf@z)p2yE z>EbYj?{RIUA(Q*_rKh)-L^&&JF=bH_+q1{GCH7n9?Bn%%Jdn&JD}NW>d8vL9xX?hY zZM%}1WxA^-H?XO1pmp`$Pn$ucVB2bx{tp+)@$D;YPQYs;NMcp({zJ^?eXP!2g7QLQ z7{Vl1Neg!)5)eVOBK0Bv#qs%j8)OUEg}LzDKh;1ZR7w1aJ&r1MgN`cb4ZO#L7k*k5 zMasfv#&eIVZKl%F1)PG+3JNM-9FZ+MC8mJRonK$CiCYyBfx>S1)17|{Rvc7n&p6>I z^ywcyAXze{;Gj|bjw@5Z>)1r0vO(~#ogo3hAjz*f7_gd`{g7bZPwj=&*_dtW(&t?y z4fj2zO6bHjYN(VBEl(&7faXiGstFU;*M5@ zQP|VtHU=gczci_P?`GM@&)V!OM2|jw4q6PfWxc6tnaET(1%@);qh&&esQI@6m3x zD-nHW0zcU4AT9n?B#+Iatf?mcQ8k^EKv-)j=rbo48j*HQbGFspv! zyPpVJQc`fK9LD13OP(uY>S}5LFm4%X(VY3d0brd%fH5pC+Z{6!Z1E%r2@2+a`_{F8 z-|l6%m*NB4uL&G&N&S6cg!4lxlJu)~b)#SKT zSS~{Zvm3$-K)>t)PEkh8)=rINf1?B6vHe#%}%E@VbjT=iF9y&CE z6i;KLF;d)8p~R%5kw!aSQk$IOv&<}lw6v7ftqYbN-1oj=N(q7ajD|q4F%S$`e;)(4j|#F+c8_Y1yUJSglcf+ zDQk8-tgRw*`r!Hy=zO%lE9kk=Ot)g(cweWGN08>^4?5gJgWbjG-b_W-`CQxhY~9w| z=H~A>pVM%^3J~K=^WbM_PbCFy4e#6JDX)|7285K)5T*q#>U1@PD>+# zciuh#`P&=-11))O&;!DjteS}lN`7VNO^|nQ6v6dzH#S*}?EIFBBs9A%X=>(Zx4oSexi zDPO-AqWb@|aaLkj7UC{j)v9Y6Ap|;h%^=zg#@63x67mcoS=vtZpBL3m?Q~KKf9SrV z`cv5VsY7`r0FL@0>J*B=GzRfSo_T5=Q|#Qt03L2H+=!}Bj7Ddi{IyplCQVd&o@pY$ z%9DPHQKeG@4{*{jD<-ZcGif*Zw_ zYl9BFz4M=MfUO5$W| z4hhLA+o<9U;URmeY1NG5P#&P#(}g?E_&u^O5rbxGGD(Bm4ZqcDO51t)gmvL5R|LlN zq?seu)2~+Qa#5mJH<4W7<2XcgM#|FODH7xd?mNpxBCcmyS7LMUpdkYlI*8WSotF|U zKiu%sE!>n?q@P za3_@%Td5o@EHW!_2-QwcaQiDzs=KQrflMb(Vov|tb72x^6&0*TrBm0Z!!!NKrv@|;thNZ>^_8U#CRkpC23k6zXuQ{bd)3v|>|^wPiR+g@wc zSkJ0;Smb|>XNiY%jU;397wA5pWYtl`&PP=kubdHB4L0E+ca#qzdlI%fbw*R!wRKF& zY!U)Qv2y11hZ`FkmR6lWwXi^^^}K~byN=h93h?H}sNID?yDDY9{oC|bZ19#rOneAv zLIZ8_&!ycb1tM@j8jmdpoS^F}>*e86NL!mhVIf`j$_f?qDL^xGYjbn$bdxt*)Vr(Z z=TB0fcFGto;&eDS&wVzOlq$T4J4q~59$gJmR1`i70{C8jX z{-+&LXsNAa6-sHTnuSwD5SS)629u6YPJ#*wXiLk=zGP&e<)|>k=B5~Tbk)=mVL$d2 z4gExjn2sCE@G&7XlUHfAThE%*;xSPrLpjGhM25rckE2BS=P}YqI)#~T)p}pkg4tYj zx~aoFw3%oK4e$@4EzmGyE55(v z?8YpW8Ud9AM;JRKJMrEask#n}*AFETFUU;YyFRjI`i8s^_bU4_v?5}I3&2LE@I*ZJ zVJV<;aQh``$w{1$n;SQpBho!OiiI4aGh^=vH8CG5qX_JqIG9|Qxb`yDQ?vTL1{JAp z0>n&4u3Z;wk@wf}04jeZ6RT*->h8w9i@d_7@EP<5u6HQLgD7fzZ`@=Z^ky3Ij|hs; zhbk}3PPa$A{o6geYWcUTj`06uQCSg?HL=K z*XNYLIrb8iWeOqH$x%;-ux0oo6fN2Snc+;nGG$BH6(y0< zd1EEk@!2H-S$tk7-yu>3;s^nqaR-ydo>iXzjJ>b4G(2R+s(&Pzw81KG#yU(H7T23ySTWZ;#NI45Z=$) zHzVd`_jJB~w*8_Ll#OCFMR**vGH6`W)=NSj2GiUJW|BN}m98VK{iU5xKNZgonpQw4 z`8M(qrXpdF?_u6CpOkXRxZ<$b_=<_?$MVfLy1lNdexp_ohXSsD`u(4$5lRD%f;FhS zsgEXxn|z6WU|)j;pWg!S9Hw!d{L8(IE+dY>a>sb#%LzpqC`HKv0~|zA3U@FEf zrZT72i&|(}Y0Dy^^u_ z{Q6(S6~?T%R$e2Waekvjvp3X22IteO!P0(E?#JfNYD+st_8~55;bg=2;)!_^+8^ve z(7+lFJm)B6Pro=q-uU&HtMZ-Oro};HHk^_tqHvCzPP6v~@?aWRL{p0eg$PK!M`PKE zUcL;9j6|)Qcl7XRs$!psrKSm_lU?=zmv=so>OD*~*cU=SdkF@1V9d+!}k9M{#Vu}Ec zDR;`AworCL3H{4I#|V$=&MFOo0ncxm6}{B}zbp<2ZrqinhIuMp*Ww9_h<8LHp^e#8miB$MzS)@@#G?>)hjf|%+_pvK$uU-7za4fbi*|v8ygXz2JS%2%CB~lm8>RQx=XEB5Y(433Bn~ejsQ=<0Z`VTW`=PA9n$5k296oeLjo+GJh5E`yHZHNO6Oo2f}QCR5rI+dac_t)2@U z3Ky!OQ8>M^Sc=6RL7;Hbw$W3*o))Lm6aZJK$OhTh{0pgp!aqD@7h%%ChWC7%tf!qdjpQx53K+= z3JU(Pc$G-Y!%@m~AuDDT%2vpi^+)PK?X0i8_>lLCh;by#4xj;WBgS!`HX z?)T5yv9(rc?Y@6;d5S?b>1J}#>kbicg17d+Apvqf-XYzPs9k@Yv#X1o zt^!jjGqb53$Bfa&DH|*68w(41^aRtI>$)S|1j|2TES8=3T;}$Sf!TR^PEG!ImnKRn z`LVYUyIVi)6@<3d9+Y{R+TJiPesU5tLK5s(;OKV=(LIWGtr?#t%{J@CX`e$hn%)$Pv>7Pk?zrevA zG9aEOAeHiEJT+>C4o)6B@}obBr%bb42n^;pFwh*{b}!oOiI3Nj52IG-uo^Xda~ZoR zn2>HV!O;!&($Nu|i|qrMJ3?t`>3EH~yiLaGsjH@zmYx9&!f09(*ksDeWDGF+N`8L` z{zvBCo1vu*o1dTe+N)?{We0Qlq0u#rMO#1>pJ=myu>_GIS6H}_H|aGRF%EtCuCd5u zNqs$LQ?w#yzSH+<4;fF4mKLNaRPZKi;Ni{=Dj3RSWMp6n3yO#ofCaFZa0q>AuYN}q zama8}AU!Za7_Q&3t-4L30M&km{Et_bh@-i6{gB6$l%DDzWxzs9)Htgr_Oc|Nk?7*eoVz*_eED9*fb5GOoV1vaQ}8e=Tc=8|3h zzAV?*u}V%()i>-Q$42D#^*!m@`1MN>Xf8lBD8Zg1FHWQW@{D>5q7}HD)QWQ@(R0{Y z{_FgJ&WC54K3=ONI@vvgj_-DkXZ~+nF1HE)^9&F@>$&v&S$-jWM(YxM!+CQyQ(4!N z;J#;dvepYYes3pv##6M4(fn+wA9y<&Lb->@V|-{MHO@YfYIW zUeuUkD8gh7fg;uz3e6Og_Hb1oaNiB}%WK}%YJ<>zF|kJ0um-;1``{)|(WeC;Ece%F zO){Bms~a**--Ue<18=S)nQ2tSlY?KPTz-uwTuF#T3vMQB@hiqp8%tg@*m^;SZ`>!* z`1lUjF{1uE;=#N>cj+i)Cp3?eUdJaSQ@X@`MTiz_zZ*pSayh@zt%jO%CrSLpHh!&? zoZPjQr4zKh(}R4r{qsC%+G7VreV9MkR$s7tSzA9N2e(;X=B4G0Su6uU_E1|833lk; z2BE9<=Z#7~Fm>zY0m5Qx+jp1<9%W9r$w|VJeK+2OR@!mw%f=H)lL1ygR=Ab*$+JAaq=WSeYlC-U&#@f-O{I=l4?c9bi z_6cm+yXB)_LonCBCpXU>UX;?GE1!yIJ|!6jjaws8WYULVD!150|E``2u>@9}SI+k6 zE^v3;^}22AN&vr=h`LUOKzLEJQxBKj*OC$eGJF3Ro)dqugbqAtB*{!CaE|$aEsOd> zD-REBiHmgGGSK2b9Y&A!l9Bu~ozB(Bj@Zkfz#;h;l)WYjz%GWd2-7%;s$!pr3oiGE zbaytg;mMx320Fmn9(Zi#g64K&>x0c@J8L_oW{`{x;^esP6ae(f-Vi1^o1ZE(cErqX z{V}#$ezK^j-?`f+;p7lI>v!ch7LGjV&C~Uh*tomv3^^ed;h(f#9&U2QIZG69wHyug ze1{1PJ#qZ`agxQhTAogGJ>uTY)=mMB=>b6QosYci-a6a5V@X#o!puYv|HD)6e;xZty;L7PD>d5d3_RaCoT%e-*;sB-mOqc#7L`Tx8j zB2)qZwY3=P)zhwdVNJ@Y>uZ~do6pk%$=CqnFD9w5lF>DIeufp)+1!NaleA!3)Y^-t zX4H}vb~87be#MhJ6!#x>F}UzscfS2`6fSp{4mJxosrSa#EGO7Dyu?Y_tjcUJq4V_C z&g6LuSkK+#e|C8Eck<2R;}ZbTxd8r zG4fg^+e^C-1v0J{_+cFZmPmj0A=+u=%1NaoN0^Z25f^ZW6y#u$WK@6m+e}Y7;>(fv z`4>l62tmPy^4J~fsDAT{i@_Lpt0IghiO&H<4{FD?)SmqruMtf1E{OA^HSjg_tto2C zPYqog+KK-OuO-ZGs+-A&Y6rSDyok4+&+>dRI^gVOTK_>2CgL%MZ%|J%8EEoM7wmc* zB9+qIo81*kE-k;qr$IAMe*ZzX>oo$c&JcbG*0%r0S^z@?%ugHong)o#K2Lex{!_*7e*;$@U(>_f&t_jSjmU7__$-EUY730{Y+^*NeR$si4x2ZXz4XbZ@M(kl z&Afr%6r8pqHcYSKpLzN9UYQQKFSz`)$8R>4D<-F5*C!C$ZZ$?JyJqaQMgRPR=Hp={ zxr4nKhn`olebx(_nK^KQmp6)Vc?c}2em$owiV57VYHr#S%pjQlH3huuAwgo^x#YgjsLEapYnm7_X0T`jR(As^0Q@1) z`cc|(xTgfYGqSkk90E_~dt>8T(Rt8D$&zNjCZfRCZ7LGW4E2I^Ue%ZvMB$$#F&#jpS>IW{veE zh`v39Z`~Jn(p}IVKDQC~gl3i31 z-^K4nrR>PymFhe*U z;|^do;mFB7zc$rRs2EqPwyNP(Go;1&<}$%=k>U9{hUe!X7n?&TUdF85y80dD?51`@ zO%+@tpI%OB?ZJ3Vah>nNp22n^F48@F_?ntC_eELC7rcs)|1OTM;v!3)I`sdigcn|c zt;--q=tLco`kzYKdgACmt&BJ!{C^Y4{|}J-|3zbSPB`ioeAc><+sYid(~LcG!24!< z&kcRyPU{_PjYMbi&9GJuZ-kH|qaZVsFYBttW{KhZYg3S97VnC^;X}K65otCS(;U|U zr%q=YZ2by+V5!U1O*6J?s*Kd=Qz~ml6}W7G`P=2-Yz|Hy;-9z-L1+FX)uYC1PZ2$b z%+iyq{rLi0zlK&|`Vd~d6(iVM>_7{~(oU1^XX`+I`jFvQicHmh8#6JzVE<$vJCRIX z9%gwaPDoy8L<9o|J4;mDfDf%~2}w!^S-(L5VlC9!*$GB>Qf@9*ei?7WYcPrLI9iZ2 zoP_+v7;Hrg zpSRL}%mrA3fX{#9=LVt(PBmY!82>gUu;vN%8YFkw`e|KUABvGWin9i~nL2_Mz_*q& z;~y;Ob|wzqU=jTkd{`=Rc0`GY|M@Pr_zDM*bbXJiq1Q#ky&f7%Rxk(3q8gV1#%1L! zemG!jB-%_-L5KFv{;YJQiDi&f`Jf}kINhnyP@&Di7OL+}6xy~l`P|U1?(U-P&!0a} z4yFnkqTSq&*qLY0KOG%yTr0CnIe|am2XQfe%q!!h|GsM22>~QSss0JC-a04;`o`9Q zp70Zy_!;pB)Z&FL^7t~X`?f#5;M8ej-EhF`GFTG*x+{jb^-H{sybwI7bj&4W!#Lpx z1nDU%HnzN%S2LZE2HdH|=1|jRt2JW>dfRD_qZiejCEg*+}rKQrSJ*q%Ho<``B(~a`a z2LRaaGz{CA>)zj)C}{S%D4jSh-mB5PpVXMmuKy=%wvVm_^x9o4(_J?>Vb zMT^k;qA)6_jRVjt0?5}i;@S)q(2Sv(=m0nl{l8LJ-~blw8OuPw#~jk9lEFICn6Yhv z2oEmQ=%bzG${d`)9{?CQ1)bU;10`JJAb>44Bu$*A22)K32TLbpyW`3V(aVKYxt`ld zyG|+~B83sNt>|Uf5-Pc-9T`MmQz55O$@7@kJ6|80rt2GZP%44be%pfBhqfozh_52@ z{_LDX%2p8nu(!R?hN8(GD0ZnHg45@6a>)50c+%1$#4J<k(Y%XH;K2Y76S1YNu~tGW0}&d|RUd%q;EnjEq31@VdFC z<(`)L<#z*)$I-r?gI*3r8|Zb--mQ{TzLDpu)EsDy;oArq$wH?&WxiL3#6qrxnwLn_ zDIxN4c_pRIU${>?M8T@0PLoZGGb-peBBt#_8 zp4nJ3SxU>}Ywx-*$hSIak$N7g7)yHAPVSK3aNVrpxt$_Gl+swA=J(Fmw*Sq- z32M+c3N1vTwDEi}^G%g%Nuo;4LRhL`z4pA6v7AH#B>!2|U<>l>!rzPBNqMp;O(aRM z8wX_nU8%8YO#~+|OGeRBTlkA~njFn3w$tr2qGU*wa}cKt^flBA5f3Qv%xfm9K>tim zO;H@HvNQx|o;%v8be6GzB8wtI5g?0lATdb=9*4(x8JpFq>gW@j#d8wx>3L&6R}BYd zzqjw+@sc1Jifj)3N^?568dvk1k}^^3*>;|1_wj<)@{z56PD8hA8z}A3KNPNQ_lySm zk#*qN7r(Ef9eYWn$|8YxX*N+FqEjTn6ot>)u)pKPt`E8^SOQiGfrnd;-DHutHu_oEeX{P$>cjM2%i|Th){NpzRmhxHwR?C%ilOy%K+WVSg9O+w zgLle_bbBlF*x>QAH@nt-k~<*MNMa2*)lSwhqnppq$JrHO|Hbs5mSXie|q)vVfL%dc~S#`Sl8RN+c8v5(BTTB4GlP<(b5*mBOI} zP}<4NfqCA$zsF?hXDl%pUI=I^05(_i1vW< zuvO0WcvNYrDKxZrpw+>|gt$SRmago1{4E<7bjP>`hy{7}rPyRVtyn=F4iFov~yk1dVH-iISz2xah=RUC{=@~Mc z#7#~*8tg`a100vxfqzj%)%P7J)4x2I+q?mYY4__Hq1BU++M-Ps`NXQPHV3KUN;BuT zXSWM%%KjOZi6qX$O3Rbx8Yg_yl%QtZ61SVbc0EBsL`-+c6I5@xKK;ef*O%^8_2Zt8 zFCeK3A(cu;BHrO&8LLc1sFGdY(5?T-NYh6@4R9IB%I%gucYyzQZ(2;4umJpX7!3JxzeRV2V5x#s=p!AE@--J1)j4umNf*H=-t)q_j{Z=-> z_|iD{CN71I)`@Cr`1)W=jy#q^hs}SLuc!tgtD%r(J3~Mmo>MPVFUuy{2&h)hWDc{j ztPvKFTE*qJ)j*vZE;ZT3e0AWzE=8D1SVcZH+-LAXZt!8OKJZA|G8?k4UcS&c6FQht zLa_97RvLu)l~iR|OZeokdo5pX72-|U&A1KE>dqEx&b5o^l345(i>$e8L%kndjmVcN zayXy<9)NH_a`Pn14dhDqTOVP{u`7;<@1`xrG8}^ad>H!1MrJ_I$X98dWH87s-y2E5l$gBTBM<*9m&^ zd)Z`9RZ3Att^C(2pKc<%GpTSGD_>%cbs+DiQNQAH{EbSS>i?qYM4nwVU|lUz zUMi&n0xP5cYgDA`>pSCDh|OQ6tK{cap0L{`ZgAqv zQ4j#;bjC$ROW1`I|KIzy67@k$6OtzNA60VnJd$;fGWQpMTR3Np|Ku|InjoJ zVHYiQ9=NuWeT!c)>3f=9CKS?;8#M(t8;!+j{Dn`*Z6KF5db_M_)!9SQ-SuzTK1dZ+ zh0Tbj;S&WPK?xy8=jc5d$k({OynVP;(&R>{y?Vd`oT)?*ZBWbs-~%6b<>X!si~(`L z5t>mwr5cSSiO&`IC-sI}CV_61yl3J5lAnOxATTgcw`|UXYcIL<$nDpFkp17Tu(@_$ zf#R6#?f}uB4NHE9pxm+Jov=T>b_VE7*GA38?aHXHTWC)9o>niNO1?BZk&(;400P>A ztm7p$|COm7FWR62!f}+LUEL)vdoZ-!3wTJ6{~|Ty^SrA_gcZ#1-}#i;-`#9-#Fhw7 zU_7-%_xuT}DUvRPl9BeSej>hlvB@dR-w-T51vx>s5%!{*zJ6-_R2d+aEY=~1f7HPv zp?LHawAu{e#$AcT0~+-4mc`!QzS{Y(G;ko_rA&AX)=A}dAO2Wbp(@@TyzBP90i5}Fo$VL!I+(hV+nS|A!g)&`M$?0WHt!ys7fjAP0LC!5gO@N7j_N%4aP;Y-Rm_llXd zQzT$JU!$uHI-9EFM72Xd;^yfY(b_5k`tgY~ z_(s(0+p>eUe%CkaZB9>5&*5w#Jg{SBdRdb+nRKh53ep9|$+;*Om-@daf)bWjc~EZ$ zRt?3j(^|Ix(~fzMF5&b`4!zdlA6oY-ZCcgQzXjBDe-q4VG(?t7n(1UyOoq|ev*-0Y zdTW{K>JE*;C?c+8CTi*i#K^IMIsa?47-P_V@)Jo`g}+H40RzAEPGkmA!ez zgCHCS&cybQb~(HWM8#1%nTjVY`-IeLOANGqNu+5IvwXd7_hL(NL@MqTX51kv7J64l zwZz)zmF51SR7~5h;=mcj&ENE8b7Xr)_A|bIp9YyP`y`&MYQ`)UcI1hP9{O_f(hZO9 z2UWQxMY-kz=D2J8DMc;oDZN)XIOL6oxdUPwitg7ZD!P)txaqumhl!4kUVS#l-)nAF zl3ad@=H^|~uxB#^-Fy{`Y@V1@v<-?-#2ZQ0shd>G*w>jU7ki)iA}y`#A!M_z6TO8? zdbr{>yDthtp2oea^gf8&f~%3K3YFW8vGcR#rEX@ zcfHaK7VCMx+d5A%qMg|f&~Zy^j|=;?;j;ljxN!uk6w#hPBCWJO$CATOro@Xo-fgmr z?~M$R?!NlN0kY6M1VocvJhxScJqUWSeDB1R2@b%SOeOY$GZ&i&6<$ra`em8 zj$nCS(XzM!vmdcRJE!;Q$2N5JuDaLC((#7yWE2CT-Fy#u1#GMzC0Th;grexT9iZ*; z^MN{1Mt93{3FfF8G#Ko^u`EMS`e#Lb%VhU<))}g!byM$H(J?S$YY%Qy)zRG^U~P0G zMIxrF_{CF9jc6CA&!*jYS(lM`%C_`~=$3o=1GZ_0h9;l{lTgkL;{rfcUgNr{IP6cT z(^AWSw|SOg0@{_$h#Mto)*+bMT@uG$-RMIc4?lcqyD-hshHek5FS$-hd8n$rPl&9h z{2Kllq=Sr7i5#$V3X2{i5O^B<0M0mvoP ziff7!9a4*H0NzGQMN*nPFg*h6^rlB)roTI*dQ?dt*_EJ$vJGX}9{oAJrEyzVRaW4d zLp6B6^D`NH_Yxd?`@iYKe^$n%fmPh!L-;+51V0r=<;E{-U9`a@q3EALc&AufDu&k!V8|lKr!rr1d zyIk7Gh@TVGlKRUI{iR>W=0?2q(>kj)25@+`h$i|~MVW*?m3|7TZKQh4<8(NuE$`ST z!r@uBDWEb<{S~lzenK|f?6vs-JM}KksBTafK5KvaeS7E9ciEcva4$y$K+ft_v)U*| zeq!zh<*YQ?2G|LjBg8yHw$XaVJbC8y zcXDfrkz12GWmCF@Lpr?keidJ-51SPO8E9T?F{#%_y-zRWHU50P-MwNKwq19;v?+)w zevwF>b`;x5Hut;b$yAr>zOQohA--_&c@+BYO;MNKZ09XrrVK+|EhU#fyL~r726G7j zc!c;A1e2)!s0#NlL>6KgrQPlkntL%xebwW=kt-OTjkj%QR1)F;@kk3AC=@StN!)S! zk7Z+P3m!0ffgy8WX$bU`U-^W?Dy@jEx>I|Wmni|~>vXRx4hdspL=>bTtG+GNtJsgH zHg1ey7;GVH@Zvy`0FOO;$zX(MlXeuAyl_`ef`Pp2)Ql@z7AWKNFF z#J`(Rf`8SU<$k#Q1N`5t+-M$tSVP&Ysg)CorO6KYYJ8B7 zMPq054Ylbeqe5F?`cuqt#LXD$y^xc}Yhg~059n)do(0|fCicJSVn)q^&${j^aPzF7 zfLg_DL47k~Q)yI!^BFpgpKpFdI}vyGBmo&J{a8Rm^C$U0{lGt^%-qbf`ofPD`eBTf zdc+57xX~lq2_pmKV9RX zmUx5*Ry7sanKR%@6kXME@*mu2?FWI<7F3y zqQe5ki0aY&^p|q*|5JtsJy$ZQkc>(@G-^$jXZP^7PQTfNnSvHa6tAMkb*#ts+R_(# zyG$c4UO17@k;la^r&oL=zeXJ<0~UTPI(b%p1!=f76;pyb8}%Hc^T(gXbg^=Y%4AJy z0sV;IEofbeZ#X#ww7nJc~+F>jF0X@LCpkbIc}!Zn1s zO}uZ8+EXJV`Y};PryJ*g3eIQ&if1nR#&MA!#YVNGt?oZG$x}ZJKGiO*(3yuVUJ^Qt z5j84wbxkh6Tc^WncG)G0dJCK|sI2+@5IluOfoW;BVB?-16(~LT(d0rvA2kRCsDG4? zujR>qmT6q2F+``c?5qk8``TY=7-i9R@ul*&VtjlN1^xy+mMf;Ig@uK)t7{@M{mt$5 zYLT`P+;KIZz*!vZcgx}DLX{Gp7AE;6?=9~2%SeMtRk4fdUq_ct$;-1KshJCWx?B0} z*RoaFst(uRw!tRW0nYYKuGiFBY#jLEXo2;C^gDYufsz1Aq@UfL%W$JAD$NdH6An9~=>u1Sl6CYfpOU3_O{>1XqQi8Ue-p0S(cTqVO8{KyMx!ZZ~ zKj(-r3%)en96_cAqVq#k;H@GvudRR&=B7B_)Vtg0-dunX z%eHDjqQjq?&&T7}H>?aLsCAYjdfvzPV{AUqSadY1x;JT3MtMe@hB+ic$mc&bsmu@@J-dN4 z!=CX~*1kpziP-IW(b?KrnK0X_F3IVOB1X%U>ajSvCyl2!x$Rmy=O=GHG>q*vYaL%~ zEw8v^TIBpOm^k`^nw*?QD`Xh`ZIatBPw#02_wda-jzK1H4L_ORToJElXm}_!FCF3? z$3AXw{;-9jCy!_8N9Dh16mV;dR+8kADGv^VrLiJG7kjf+l>~KyIAtwdqy*KT?<%ab zlHh!w3lGDPGmNvZQME{2ME;FeevQkvbJ{Top25C8AD!r((&Zwg@}}% z?~5L2e09IW+kez{%I9jK6n(0rCi2j*IlqEzg8#~B!wbA=$y|=&28Rl0p#2K2U|{o6 z`jukzQjY8=ShunMB^qqa7L6{)Z8y;HYi8E__1+Iw*S+-Z?y5R<`p7=J&fX;r7G^jC?#Vt-+o%hP_x3%L zx=7sghPhTZUOyg0utTn1I|p;3e+Rt_H#+j_l0>KEsjvR#!));hY%8X!gjIMAe%PVB zsfo}D#Xvzplb9RJ0DTrwGxfJW?bl!p?+j!p4!%A0B5LTCN!PScB%`4hz(#sO_-G7Bo{tJZs|As%!|0lb8oSyKDhCuI+3x}0bTQhU!f51`oI?X;{ z6>}VkfY%0?Hvy=BUXvO9C%Q9fU;4I^b_@K6;mh-rwf(2>d4jLV<@{Cf0&!jae14C& zAI_z*O1(_O2O)4$EvG&8%_ zW@*7weAm|3o7zN%kAScihQIB?1H9!2om}h}M)HZ&>2ktGfU2?R0hQ^-6bjkih{vAsAqHyo0pMH=0V`aVaaH z#dXI=aFqmx`U*RT5gv~VSm?@p@r-nH6;=6rK5IQavx+C`^iHY0`p;Q0dEUF7!ubeI zA9-3O?;*cHH>wR2m23HLi~x9RAmGDvPL-Zzt!-lZ)Li!$Sd_+p81|VJ)>|szcb_a^)cA{7Kc|^tTh}~idxB0*@80! zJ{MG1;{GI$#|A7(_KlQPc3TFat({Fni~aG(kb6l^9=v99ktVIKxV5Ie0;W!%Yk4_? zb$V;|6{zp`GGMC3+il(x_}Q)f$!o<+5*4op*jQNn-UId^^`?g6=$1-5$-ktLqN_3f zSex(gFXZL#X7DMP4j!*Cwe-Km%+?;F)!=Ca0Z1?b{}pW~lge?^B%ZiKilh0alBk+5 zjXLe@B4dT*6YMRwb%l0ICYui~jpCoctfM;tXV2pW7 zMmSBiYVzh-ZMPpVw3k7WR96E45){*Si!>d>m
      @~0KohCAw9Xanx`)0FFt!W-4K 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 Oeh)SE?iH!qz5ZXZ9mN0u From c924d479119b7b9c42a6afd7681a8a8bcd844278 Mon Sep 17 00:00:00 2001 From: necromanceranne <40847847+necromanceranne@users.noreply.github.com> Date: Thu, 22 Apr 2021 13:13:10 +1000 Subject: [PATCH 23/75] brings the values down even further --- code/modules/surgery/organs/lungs.dm | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/code/modules/surgery/organs/lungs.dm b/code/modules/surgery/organs/lungs.dm index 73fbe3412c..4d19d847f6 100644 --- a/code/modules/surgery/organs/lungs.dm +++ b/code/modules/surgery/organs/lungs.dm @@ -571,11 +571,11 @@ maxHealth = 2 * STANDARD_ORGAN_THRESHOLD safe_oxygen_min = 4 //You could literally be breathing the thinnest amount of oxygen and be fine safe_oxygen_max = 250 //Or be in an enriched oxygen room for that matter - safe_toxins_max = 50 - safe_co2_max = 50 - SA_para_min = 50 - SA_sleep_min = 100 - BZ_trip_balls_min = 50 + safe_toxins_max = 30 + safe_co2_max = 30 + SA_para_min = 30 + SA_sleep_min = 50 + BZ_trip_balls_min = 30 emp_vulnerability = 20 cold_level_1_threshold = 200 From 5bb6078def29eb43a6989f74bf328906a2857c3c Mon Sep 17 00:00:00 2001 From: SandPoot Date: Thu, 22 Apr 2021 20:39:21 -0300 Subject: [PATCH 24/75] upload files --- code/__DEFINES/vv.dm | 3 + code/__HELPERS/icons.dm | 5 +- code/datums/dna.dm | 5 +- code/datums/outfit.dm | 351 +++++++++++++++--- code/modules/admin/admin_verbs.dm | 4 +- code/modules/admin/outfit_editor.dm | 196 ++++++++++ code/modules/admin/outfit_manager.dm | 73 ++++ code/modules/admin/outfits.dm | 32 ++ code/modules/admin/verbs/debug.dm | 66 ++-- code/modules/admin/verbs/randomverbs.dm | 2 - code/modules/admin/verbs/selectequipment.dm | 226 +++++++++++ code/modules/client/preferences.dm | 2 + code/modules/client/preferences_savefile.dm | 11 + code/modules/clothing/chameleon.dm | 3 +- code/modules/mob/living/carbon/human/dummy.dm | 48 ++- code/modules/mob/living/carbon/human/human.dm | 10 +- .../mob/living/carbon/human/human_helpers.dm | 6 + tgstation.dme | 4 + tgui/packages/common/collections.js | 4 + tgui/packages/tgui/interfaces/ListInput.js | 206 ++++++++++ tgui/packages/tgui/interfaces/OutfitEditor.js | 146 ++++++++ .../packages/tgui/interfaces/OutfitManager.js | 81 ++++ .../tgui/interfaces/SelectEquipment.js | 214 +++++++++++ 23 files changed, 1578 insertions(+), 120 deletions(-) create mode 100644 code/modules/admin/outfit_editor.dm create mode 100644 code/modules/admin/outfit_manager.dm create mode 100644 code/modules/admin/outfits.dm create mode 100644 code/modules/admin/verbs/selectequipment.dm create mode 100644 tgui/packages/tgui/interfaces/ListInput.js create mode 100644 tgui/packages/tgui/interfaces/OutfitEditor.js create mode 100644 tgui/packages/tgui/interfaces/OutfitManager.js create mode 100644 tgui/packages/tgui/interfaces/SelectEquipment.js diff --git a/code/__DEFINES/vv.dm b/code/__DEFINES/vv.dm index 99a2e9d0ab..a04f02bd6a 100644 --- a/code/__DEFINES/vv.dm +++ b/code/__DEFINES/vv.dm @@ -136,3 +136,6 @@ // paintings #define VV_HK_REMOVE_PAINTING "remove_painting" + +//outfits +#define VV_HK_TO_OUTFIT_EDITOR "outfit_editor" diff --git a/code/__HELPERS/icons.dm b/code/__HELPERS/icons.dm index 1d37f639bf..ce6bbf48c3 100644 --- a/code/__HELPERS/icons.dm +++ b/code/__HELPERS/icons.dm @@ -1065,10 +1065,9 @@ GLOBAL_LIST_EMPTY(friendly_animal_types) var/icon/out_icon = icon('icons/effects/effects.dmi', "nothing") + COMPILE_OVERLAYS(body) for(var/D in showDirs) - body.setDir(D) - COMPILE_OVERLAYS(body) - var/icon/partial = getFlatIcon(body) + var/icon/partial = getFlatIcon(body, defdir=D) out_icon.Insert(partial,dir=D) humanoid_icon_cache[icon_id] = out_icon diff --git a/code/datums/dna.dm b/code/datums/dna.dm index b6b93bdddc..248b669ab1 100644 --- a/code/datums/dna.dm +++ b/code/datums/dna.dm @@ -329,12 +329,13 @@ uni_identity = generate_uni_identity() unique_enzymes = generate_unique_enzymes() -/datum/dna/proc/initialize_dna(newblood_type) +/datum/dna/proc/initialize_dna(newblood_type, skip_index = FALSE) if(newblood_type) blood_type = newblood_type unique_enzymes = generate_unique_enzymes() uni_identity = generate_uni_identity() - generate_dna_blocks() + if(!skip_index) //I hate this + generate_dna_blocks() features = random_features(species?.id, holder?.gender) diff --git a/code/datums/outfit.dm b/code/datums/outfit.dm index da379b9851..0b46629365 100755 --- a/code/datums/outfit.dm +++ b/code/datums/outfit.dm @@ -1,71 +1,185 @@ +/** + * # Outfit datums + * + * This is a clean system of applying outfits to mobs, if you need to equip someone in a uniform + * this is the way to do it cleanly and properly. + * + * You can also specify an outfit datum on a job to have it auto equipped to the mob on join + * + * /mob/living/carbon/human/proc/equipOutfit(outfit) is the mob level proc to equip an outfit + * and you pass it the relevant datum outfit + * + * outfits can also be saved as json blobs downloadable by a client and then can be uploaded + * by that user to recreate the outfit, this is used by admins to allow for custom event outfits + * that can be restored at a later date + */ /datum/outfit + ///Name of the outfit (shows up in the equip admin verb) var/name = "Naked" - var/uniform = null - var/suit = null - var/toggle_helmet = TRUE - var/back = null - var/belt = null - var/gloves = null - var/shoes = null - var/head = null - var/mask = null - var/neck = null - var/ears = null - var/glasses = null + /// Type path of item to go in the idcard slot var/id = null - var/l_pocket = null - var/r_pocket = null + + /// Type path of item to go in uniform slot + var/uniform = null + + /// Type path of item to go in suit slot + var/suit = null + + /** + * Type path of item to go in suit storage slot + * + * (make sure it's valid for that suit) + */ var/suit_store = null - var/r_hand = null + + /// Type path of item to go in back slot + var/back = null + + /** + * list of items that should go in the backpack of the user + * + * Format of this list should be: list(path=count,otherpath=count) + */ + var/list/backpack_contents = null + + /// Type path of item to go in belt slot + var/belt = null + + /// Type path of item to go in ears slot + var/ears = null + + /// Type path of item to go in the glasses slot + var/glasses = null + + /// Type path of item to go in gloves slot + var/gloves = null + + /// Type path of item to go in head slot + var/head = null + + /// Type path of item to go in mask slot + var/mask = null + + /// Type path of item to go in neck slot + var/neck = null + + /// Type path of item to go in shoes slot + var/shoes = null + + /// Type path of item for left pocket slot + var/l_pocket = null + + /// Type path of item for right pocket slot + var/r_pocket = null + + ///Type path of item to go in the right hand var/l_hand = null - var/internals_slot = null //ID of slot containing a gas tank - var/list/backpack_contents = null // In the list(path=count,otherpath=count) format - var/box // Internals box. Will be inserted at the start of backpack_contents - var/list/implants = null + + //Type path of item to go in left hand + var/r_hand = null + + /// Any clothing accessory item var/accessory = null - var/can_be_admin_equipped = TRUE // Set to FALSE if your outfit requires runtime parameters - var/list/chameleon_extras //extra types for chameleon outfit changes, mostly guns + /// Internals box. Will be inserted at the start of backpack_contents + var/box + /** + * extra types for chameleon outfit changes, mostly guns + * + * Format of this list is (typepath, typepath, typepath) + * + * These are all added and returns in the list for get_chamelon_diguise_info proc + */ + var/list/chameleon_extras + + /** + * Any implants the mob should start implanted with + * + * Format of this list is (typepath, typepath, typepath) + */ + var/list/implants = null + + ///ID of the slot containing a gas tank + var/internals_slot = null + + /// Should the toggle helmet proc be called on the helmet during equip + var/toggle_helmet = TRUE + + /// Any undershirt. While on humans it is a string, here we use paths to stay consistent with the rest of the equips. + var/datum/sprite_accessory/undershirt = null + +/** + * Called at the start of the equip proc + * + * Override to change the value of the slots depending on client prefs, species and + * other such sources of change + * + * Extra Arguments + * * visualsOnly true if this is only for display (in the character setup screen) + * + * If visualsOnly is true, you can omit any work that doesn't visually appear on the character sprite + */ /datum/outfit/proc/pre_equip(mob/living/carbon/human/H, visualsOnly = FALSE, client/preference_source) //to be overridden for customization depending on client prefs,species etc return +/** + * Called after the equip proc has finished + * + * All items are on the mob at this point, use this proc to toggle internals + * fiddle with id bindings and accesses etc + * + * Extra Arguments + * * visualsOnly true if this is only for display (in the character setup screen) + * + * If visualsOnly is true, you can omit any work that doesn't visually appear on the character sprite + */ /datum/outfit/proc/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE, client/preference_source) //to be overridden for toggling internals, id binding, access etc return +/** + * Equips all defined types and paths to the mob passed in + * + * Extra Arguments + * * visualsOnly true if this is only for display (in the character setup screen) + * + * If visualsOnly is true, you can omit any work that doesn't visually appear on the character sprite + */ /datum/outfit/proc/equip(mob/living/carbon/human/H, visualsOnly = FALSE, client/preference_source) pre_equip(H, visualsOnly, preference_source) //Start with uniform,suit,backpack for additional slots if(uniform) - H.equip_to_slot_or_del(new uniform(H),SLOT_W_UNIFORM) + H.equip_to_slot_or_del(new uniform(H), SLOT_W_UNIFORM, TRUE) if(suit) - H.equip_to_slot_or_del(new suit(H),SLOT_WEAR_SUIT) + H.equip_to_slot_or_del(new suit(H), SLOT_WEAR_SUIT, TRUE) if(back) - H.equip_to_slot_or_del(new back(H),SLOT_BACK) + H.equip_to_slot_or_del(new back(H), SLOT_BACK, TRUE) if(belt) - H.equip_to_slot_or_del(new belt(H),SLOT_BELT) + H.equip_to_slot_or_del(new belt(H), SLOT_BELT, TRUE) if(gloves) - H.equip_to_slot_or_del(new gloves(H),SLOT_GLOVES) + H.equip_to_slot_or_del(new gloves(H), SLOT_GLOVES, TRUE) if(shoes) - H.equip_to_slot_or_del(new shoes(H),SLOT_SHOES) + H.equip_to_slot_or_del(new shoes(H), SLOT_SHOES, TRUE) if(head) - H.equip_to_slot_or_del(new head(H),SLOT_HEAD) + H.equip_to_slot_or_del(new head(H), SLOT_HEAD, TRUE) if(mask) - H.equip_to_slot_or_del(new mask(H),SLOT_WEAR_MASK) + H.equip_to_slot_or_del(new mask(H), SLOT_WEAR_MASK, TRUE) if(neck) - H.equip_to_slot_or_del(new neck(H),SLOT_NECK) + H.equip_to_slot_or_del(new neck(H), SLOT_NECK, TRUE) if(ears) - H.equip_to_slot_or_del(new ears(H),SLOT_EARS) + H.equip_to_slot_or_del(new ears(H), SLOT_EARS, TRUE) if(glasses) - H.equip_to_slot_or_del(new glasses(H),SLOT_GLASSES) + H.equip_to_slot_or_del(new glasses(H), SLOT_GLASSES, TRUE) if(id) - H.equip_to_slot_or_del(new id(H),SLOT_WEAR_ID) + H.equip_to_slot_or_del(new id(H), SLOT_WEAR_ID, TRUE) if(suit_store) - H.equip_to_slot_or_del(new suit_store(H),SLOT_S_STORE) + H.equip_to_slot_or_del(new suit_store(H), SLOT_S_STORE, TRUE) + if(undershirt) + H.undershirt = initial(undershirt.name) if(accessory) var/obj/item/clothing/under/U = H.w_uniform @@ -81,9 +195,9 @@ if(!visualsOnly) // Items in pockets or backpack don't show up on mob's icon. if(l_pocket) - H.equip_to_slot_or_del(new l_pocket(H),SLOT_L_STORE) + H.equip_to_slot_or_del(new l_pocket(H), SLOT_L_STORE, TRUE) if(r_pocket) - H.equip_to_slot_or_del(new r_pocket(H),SLOT_R_STORE) + H.equip_to_slot_or_del(new r_pocket(H), SLOT_R_STORE, TRUE) if(box) if(!backpack_contents) @@ -97,7 +211,7 @@ if(!isnum(number))//Default to 1 number = 1 for(var/i in 1 to number) - H.equip_to_slot_or_del(new path(H),SLOT_IN_BACKPACK) + H.equip_to_slot_or_del(new path(H), SLOT_IN_BACKPACK, TRUE) if(!H.head && toggle_helmet && istype(H.wear_suit, /obj/item/clothing/suit/space/hardsuit)) var/obj/item/clothing/suit/space/hardsuit/HS = H.wear_suit @@ -112,55 +226,178 @@ H.update_action_buttons_icon() if(implants) for(var/implant_type in implants) - var/obj/item/implant/I = new implant_type + var/obj/item/implant/I = new implant_type(H) I.implant(H, null, TRUE) H.update_body() return TRUE +/** + * Apply a fingerprint from the passed in human to all items in the outfit + * + * Used for forensics setup when the mob is first equipped at roundstart + * essentially calls add_fingerprint to every defined item on the human + * + */ /datum/outfit/proc/apply_fingerprints(mob/living/carbon/human/H) if(!istype(H)) return if(H.back) - H.back.add_fingerprint(H,1) //The 1 sets a flag to ignore gloves + H.back.add_fingerprint(H, ignoregloves = TRUE) for(var/obj/item/I in H.back.contents) - I.add_fingerprint(H,1) + I.add_fingerprint(H, ignoregloves = TRUE) if(H.wear_id) - H.wear_id.add_fingerprint(H,1) + H.wear_id.add_fingerprint(H, ignoregloves = TRUE) if(H.w_uniform) - H.w_uniform.add_fingerprint(H,1) + H.w_uniform.add_fingerprint(H, ignoregloves = TRUE) if(H.wear_suit) - H.wear_suit.add_fingerprint(H,1) + H.wear_suit.add_fingerprint(H, ignoregloves = TRUE) if(H.wear_mask) - H.wear_mask.add_fingerprint(H,1) + H.wear_mask.add_fingerprint(H, ignoregloves = TRUE) if(H.wear_neck) - H.wear_neck.add_fingerprint(H,1) + H.wear_neck.add_fingerprint(H, ignoregloves = TRUE) if(H.head) - H.head.add_fingerprint(H,1) + H.head.add_fingerprint(H, ignoregloves = TRUE) if(H.shoes) - H.shoes.add_fingerprint(H,1) + H.shoes.add_fingerprint(H, ignoregloves = TRUE) if(H.gloves) - H.gloves.add_fingerprint(H,1) + H.gloves.add_fingerprint(H, ignoregloves = TRUE) if(H.ears) - H.ears.add_fingerprint(H,1) + H.ears.add_fingerprint(H, ignoregloves = TRUE) if(H.glasses) - H.glasses.add_fingerprint(H,1) + H.glasses.add_fingerprint(H, ignoregloves = TRUE) if(H.belt) - H.belt.add_fingerprint(H,1) + H.belt.add_fingerprint(H, ignoregloves = TRUE) for(var/obj/item/I in H.belt.contents) - I.add_fingerprint(H,1) + I.add_fingerprint(H, ignoregloves = TRUE) if(H.s_store) - H.s_store.add_fingerprint(H,1) + H.s_store.add_fingerprint(H, ignoregloves = TRUE) if(H.l_store) - H.l_store.add_fingerprint(H,1) + H.l_store.add_fingerprint(H, ignoregloves = TRUE) if(H.r_store) - H.r_store.add_fingerprint(H,1) + H.r_store.add_fingerprint(H, ignoregloves = TRUE) for(var/obj/item/I in H.held_items) - I.add_fingerprint(H,1) - return 1 + I.add_fingerprint(H, ignoregloves = TRUE) + return TRUE +/// Return a list of all the types that are required to disguise as this outfit type /datum/outfit/proc/get_chameleon_disguise_info() var/list/types = list(uniform, suit, back, belt, gloves, shoes, head, mask, neck, ears, glasses, id, l_pocket, r_pocket, suit_store, r_hand, l_hand) types += chameleon_extras listclearnulls(types) return types + +/// Return a json list of this outfit +/datum/outfit/proc/get_json_data() + . = list() + .["outfit_type"] = type + .["name"] = name + .["uniform"] = uniform + .["suit"] = suit + .["toggle_helmet"] = toggle_helmet + .["back"] = back + .["belt"] = belt + .["gloves"] = gloves + .["shoes"] = shoes + .["head"] = head + .["mask"] = mask + .["neck"] = neck + .["ears"] = ears + .["glasses"] = glasses + .["id"] = id + .["l_pocket"] = l_pocket + .["r_pocket"] = r_pocket + .["suit_store"] = suit_store + .["r_hand"] = r_hand + .["l_hand"] = l_hand + .["internals_slot"] = internals_slot + .["backpack_contents"] = backpack_contents + .["box"] = box + .["implants"] = implants + .["accessory"] = accessory + +/// Copy most vars from another outfit to this one +/datum/outfit/proc/copy_from(datum/outfit/target) + name = target.name + uniform = target.uniform + suit = target.suit + toggle_helmet = target.toggle_helmet + back = target.back + belt = target.belt + gloves = target.gloves + shoes = target.shoes + head = target.head + mask = target.mask + neck = target.neck + ears = target.ears + glasses = target.glasses + id = target.id + l_pocket = target.l_pocket + r_pocket = target.r_pocket + suit_store = target.suit_store + r_hand = target.r_hand + l_hand = target.l_hand + internals_slot = target.internals_slot + backpack_contents = target.backpack_contents + box = target.box + implants = target.implants + accessory = target.accessory + +/// Prompt the passed in mob client to download this outfit as a json blob +/datum/outfit/proc/save_to_file(mob/admin) + var/stored_data = get_json_data() + var/json = json_encode(stored_data) + //Kinda annoying but as far as i can tell you need to make actual file. + var/f = file("data/TempOutfitUpload") + fdel(f) + WRITE_FILE(f,json) + admin << ftp(f,"[name].json") + +/// Create an outfit datum from a list of json data +/datum/outfit/proc/load_from(list/outfit_data) + //This could probably use more strict validation + name = outfit_data["name"] + uniform = text2path(outfit_data["uniform"]) + suit = text2path(outfit_data["suit"]) + toggle_helmet = outfit_data["toggle_helmet"] + back = text2path(outfit_data["back"]) + belt = text2path(outfit_data["belt"]) + gloves = text2path(outfit_data["gloves"]) + shoes = text2path(outfit_data["shoes"]) + head = text2path(outfit_data["head"]) + mask = text2path(outfit_data["mask"]) + neck = text2path(outfit_data["neck"]) + ears = text2path(outfit_data["ears"]) + glasses = text2path(outfit_data["glasses"]) + id = text2path(outfit_data["id"]) + l_pocket = text2path(outfit_data["l_pocket"]) + r_pocket = text2path(outfit_data["r_pocket"]) + suit_store = text2path(outfit_data["suit_store"]) + r_hand = text2path(outfit_data["r_hand"]) + l_hand = text2path(outfit_data["l_hand"]) + internals_slot = outfit_data["internals_slot"] + var/list/backpack = outfit_data["backpack_contents"] + backpack_contents = list() + for(var/item in backpack) + var/itype = text2path(item) + if(itype) + backpack_contents[itype] = backpack[item] + box = text2path(outfit_data["box"]) + var/list/impl = outfit_data["implants"] + implants = list() + for(var/I in impl) + var/imptype = text2path(I) + if(imptype) + implants += imptype + accessory = text2path(outfit_data["accessory"]) + return TRUE + +/datum/outfit/vv_get_dropdown() + . = ..() + VV_DROPDOWN_OPTION("", "---") + VV_DROPDOWN_OPTION(VV_HK_TO_OUTFIT_EDITOR, "Outfit Editor") + +/datum/outfit/vv_do_topic(list/href_list) + . = ..() + if(href_list[VV_HK_TO_OUTFIT_EDITOR]) + usr.client.open_outfit_editor(src) diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index f22ceb6a2d..96eb4e4a0f 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -93,7 +93,7 @@ GLOBAL_PROTECT(admin_verbs_ban) GLOBAL_LIST_INIT(admin_verbs_sounds, list(/client/proc/play_local_sound, /client/proc/play_sound, /client/proc/manual_play_web_sound, /client/proc/set_round_end_sound)) GLOBAL_PROTECT(admin_verbs_sounds) GLOBAL_LIST_INIT(admin_verbs_fun, list( - /client/proc/cmd_admin_dress, + /client/proc/cmd_select_equipment, /client/proc/cmd_admin_gib_self, /client/proc/drop_bomb, /client/proc/set_dynex_scale, @@ -232,7 +232,7 @@ GLOBAL_LIST_INIT(admin_verbs_hideable, list( /client/proc/play_local_sound, /client/proc/play_sound, /client/proc/set_round_end_sound, - /client/proc/cmd_admin_dress, + /client/proc/cmd_select_equipment, /client/proc/cmd_admin_gib_self, /client/proc/drop_bomb, /client/proc/drop_dynex_bomb, diff --git a/code/modules/admin/outfit_editor.dm b/code/modules/admin/outfit_editor.dm new file mode 100644 index 0000000000..9a99d8b20e --- /dev/null +++ b/code/modules/admin/outfit_editor.dm @@ -0,0 +1,196 @@ + +/client/proc/open_outfit_editor(datum/outfit/target) + var/datum/outfit_editor/ui = new(usr, target) + ui.ui_interact(usr) + +#define OUTFIT_EDITOR_NAME "Outfit-O-Tron 9000" +/datum/outfit_editor + var/client/owner + + var/dummy_key + + var/datum/outfit/drip + +/datum/outfit_editor/New(user, datum/outfit/target) + owner = CLIENT_FROM_VAR(user) + + if(ispath(target)) + drip = new /datum/outfit + drip.copy_from(new target) + else if(istype(target)) + drip = target + else + drip = new /datum/outfit + drip.name = "New Outfit" + +/datum/outfit_editor/ui_state(mob/user) + return GLOB.admin_state + +/datum/outfit_editor/ui_status(mob/user, datum/ui_state/state) + if(QDELETED(drip)) + return UI_CLOSE + return ..() + +/datum/outfit_editor/ui_close(mob/user) + clear_human_dummy(dummy_key) + qdel(src) + +/datum/outfit_editor/proc/init_dummy() + dummy_key = "outfit_editor_[owner]" + generate_dummy_lookalike(dummy_key, owner.mob) + unset_busy_human_dummy(dummy_key) + +/datum/outfit_editor/ui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "OutfitEditor", OUTFIT_EDITOR_NAME) + ui.open() + ui.set_autoupdate(FALSE) + +/datum/outfit_editor/proc/entry(data) + if(ispath(data, /obj/item)) + var/obj/item/item = data + return list( + "path" = item, + "name" = initial(item.name), + "desc" = initial(item.desc), + // at this point initializing the item is probably faster tbh + "sprite" = icon2base64(icon(initial(item.icon), initial(item.icon_state))), + ) + + return data + +/datum/outfit_editor/proc/serialize_outfit() + var/list/outfit_slots = drip.get_json_data() + . = list() + for(var/key in outfit_slots) + var/val = outfit_slots[key] + . += list("[key]" = entry(val)) + +/datum/outfit_editor/ui_data(mob/user) + var/list/data = list() + + data["outfit"] = serialize_outfit() + data["saveable"] = !GLOB.custom_outfits.Find(drip) + + if(!dummy_key) + init_dummy() + var/icon/dummysprite = get_flat_human_icon(null, + dummy_key = dummy_key, + showDirs = list(SOUTH), + outfit_override = drip) + data["dummy64"] = icon2base64(dummysprite) + + return data + + +/datum/outfit_editor/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state) + if(..()) + return + . = TRUE + + var/slot = params["slot"] + switch(action) + if("click") + choose_item(slot) + if("ctrlClick") + choose_any_item(slot) + if("clear") + if(drip.vars.Find(slot)) + drip.vars[slot] = null + + if("rename") + var/newname = stripped_input(owner, "What do you want to name this outfit?", OUTFIT_EDITOR_NAME) + if(newname) + drip.name = newname + if("save") + GLOB.custom_outfits |= drip + SStgui.update_user_uis(owner.mob) + if("delete") + GLOB.custom_outfits -= drip + SStgui.update_user_uis(owner.mob) + if("vv") + owner.debug_variables(drip) + + +/datum/outfit_editor/proc/set_item(slot, obj/item/choice) + if(!choice) + return + if(!ispath(choice)) + alert(owner, "Invalid item", OUTFIT_EDITOR_NAME, "oh no") + return + if(initial(choice.icon_state) == null) //hacky check copied from experimentor code + var/msg = "Warning: This item's icon_state is null, indicating it is very probably not actually a usable item." + if(alert(owner, msg, OUTFIT_EDITOR_NAME, "Use it anyway", "Cancel") != "Use it anyway") + return + + if(drip.vars.Find(slot)) + drip.vars[slot] = choice + +/datum/outfit_editor/proc/choose_any_item(slot) + var/obj/item/choice = pick_closest_path(FALSE) + + if(!choice) + return + + set_item(slot, choice) + +//this proc will try to give a good selection of items that the user can choose from +//it does *not* give a selection of all items that can fit in a slot because lag; +//most notably the hand and pocket slots because they accept pretty much anything +//also stuff that fits in the belt and back slots are scattered pretty much all over the place +/datum/outfit_editor/proc/choose_item(slot) + var/list/options = list() + + switch(slot) + if("head") + options = typesof(/obj/item/clothing/head) + if("glasses") + options = typesof(/obj/item/clothing/glasses) + if("ears") + options = typesof(/obj/item/radio/headset) + + if("neck") + options = typesof(/obj/item/clothing/neck) + if("mask") + options = typesof(/obj/item/clothing/mask) + + if("uniform") + options = typesof(/obj/item/clothing/under) + if("suit") + options = typesof(/obj/item/clothing/suit) + if("gloves") + options = typesof(/obj/item/clothing/gloves) + + if("suit_store") + var/obj/item/clothing/suit/suit = drip.suit + if(suit) + suit = new suit //initial() doesn't like lists + options = suit.allowed + if(!options.len) //nothing will happen, but don't let the user think it's broken + to_chat(owner, "No options available for the current suit.") + + if("belt") + options = typesof(/obj/item/storage/belt) + if("id") + options = typesof(/obj/item/card/id) + + if("l_hand") + choose_any_item(slot) + if("back") + options = typesof(/obj/item/storage/backpack) + if("r_hand") + choose_any_item(slot) + + if("l_pocket") + choose_any_item(slot) + if("shoes") + options = typesof(/obj/item/clothing/shoes) + if("r_pocket") + choose_any_item(slot) + + if(length(options)) + set_item(slot, tgui_input_list(owner, "Choose an item", OUTFIT_EDITOR_NAME, options)) + + +#undef OUTFIT_EDITOR_NAME diff --git a/code/modules/admin/outfit_manager.dm b/code/modules/admin/outfit_manager.dm new file mode 100644 index 0000000000..9d20b64547 --- /dev/null +++ b/code/modules/admin/outfit_manager.dm @@ -0,0 +1,73 @@ +/client/proc/outfit_manager() + set category = "Debug" + set name = "Outfit Manager" + + if(!check_rights(R_DEBUG)) + return + var/datum/outfit_manager/ui = new(usr) + ui.ui_interact(usr) + + +/datum/outfit_manager + var/client/owner + +/datum/outfit_manager/New(user) + owner = CLIENT_FROM_VAR(user) + +/datum/outfit_manager/ui_state(mob/user) + return GLOB.admin_state + +/datum/outfit_manager/ui_close(mob/user) + qdel(src) + +/datum/outfit_manager/ui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "OutfitManager") + ui.open() + +/datum/outfit_manager/proc/entry(datum/outfit/outfit) + var/vv = FALSE + var/datum/outfit/varedit/varoutfit = outfit + if(istype(varoutfit)) + vv = length(varoutfit.vv_values) + return list( + "name" = "[outfit.name] [vv ? "(VV)" : ""]", + "ref" = REF(outfit), + ) + +/datum/outfit_manager/ui_data(mob/user) + var/list/data = list() + + var/list/outfits = list() + for(var/datum/outfit/custom_outfit in GLOB.custom_outfits) + outfits += list(entry(custom_outfit)) + data["outfits"] = outfits + + return data + +/datum/outfit_manager/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state) + if(..()) + return + . = TRUE + + switch(action) + if("new") + owner.open_outfit_editor(new /datum/outfit) + if("load") + owner.holder.load_outfit(owner.mob) + if("copy") + var/datum/outfit/outfit = tgui_input_list(owner, "Pick an outfit to copy from", "Outfit Manager", subtypesof(/datum/outfit)) + if(ispath(outfit)) + owner.open_outfit_editor(new outfit) + + var/datum/outfit/target_outfit = locate(params["outfit"]) + if(!istype(target_outfit)) + return + switch(action) //wow we're switching through action again this is horrible optimization smh + if("edit") + owner.open_outfit_editor(target_outfit) + if("save") + owner.holder.save_outfit(owner.mob, target_outfit) + if("delete") + owner.holder.delete_outfit(owner.mob, target_outfit) diff --git a/code/modules/admin/outfits.dm b/code/modules/admin/outfits.dm new file mode 100644 index 0000000000..1b615e3d62 --- /dev/null +++ b/code/modules/admin/outfits.dm @@ -0,0 +1,32 @@ +GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits + +/datum/admins/proc/save_outfit(mob/admin, datum/outfit/O) + O.save_to_file(admin) + SStgui.update_user_uis(admin) + +/datum/admins/proc/delete_outfit(mob/admin, datum/outfit/O) + GLOB.custom_outfits -= O + qdel(O) + to_chat(admin,"Outfit deleted.") + SStgui.update_user_uis(admin) + +/datum/admins/proc/load_outfit(mob/admin) + var/outfit_file = input("Pick outfit json file:", "File") as null|file + if(!outfit_file) + return + var/filedata = file2text(outfit_file) + var/json = json_decode(filedata) + if(!json) + to_chat(admin,"JSON decode error.") + return + var/otype = text2path(json["outfit_type"]) + if(!ispath(otype,/datum/outfit)) + to_chat(admin,"Malformed/Outdated file.") + return + var/datum/outfit/O = new otype + if(!O.load_from(json)) + to_chat(admin,"Malformed/Outdated file.") + return + GLOB.custom_outfits += O + SStgui.update_user_uis(admin) + diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm index 2c1ddc4e0a..a123d73e62 100644 --- a/code/modules/admin/verbs/debug.dm +++ b/code/modules/admin/verbs/debug.dm @@ -484,74 +484,52 @@ set name = "Test Areas (ALL)" cmd_admin_areatest(FALSE) -/client/proc/cmd_admin_dress(mob/M in GLOB.mob_list) - set category = "Admin.Events" - set name = "Select equipment" - if(!(ishuman(M) || isobserver(M))) - alert("Invalid mob") - return - - var/dresscode = robust_dress_shop() - - if(!dresscode) - return - - var/delete_pocket - var/mob/living/carbon/human/H - if(isobserver(M)) - H = M.change_mob_type(/mob/living/carbon/human, null, null, TRUE) - else - H = M - if(alert("Drop Items in Pockets? No will delete them.", "Robust quick dress shop", "Yes", "No") == "No") - delete_pocket = TRUE - - SSblackbox.record_feedback("tally", "admin_verb", 1, "Select Equipment") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - for (var/obj/item/I in H.get_equipped_items(delete_pocket)) - qdel(I) - if(dresscode != "Naked") - H.equipOutfit(dresscode) - - H.regenerate_icons() - - log_admin("[key_name(usr)] changed the equipment of [key_name(H)] to [dresscode].") - message_admins("[key_name_admin(usr)] changed the equipment of [ADMIN_LOOKUPFLW(H)] to [dresscode].") - /client/proc/robust_dress_shop() - var/list/outfits = list("Cancel","Naked","Custom","As Job...") - var/list/paths = subtypesof(/datum/outfit) - typesof(/datum/outfit/job) + + var/list/baseoutfits = list("Naked","Custom","As Job...", "As Plasmaman...") + var/list/outfits = list() + var/list/paths = subtypesof(/datum/outfit) - typesof(/datum/outfit/job) - typesof(/datum/outfit/plasmaman) + for(var/path in paths) var/datum/outfit/O = path //not much to initalize here but whatever - if(initial(O.can_be_admin_equipped)) - outfits[initial(O.name)] = path + outfits[initial(O.name)] = path - var/dresscode = input("Select outfit", "Robust quick dress shop") as null|anything in outfits + var/dresscode = input("Select outfit", "Robust quick dress shop") as null|anything in baseoutfits + sortList(outfits) if (isnull(dresscode)) return if (outfits[dresscode]) dresscode = outfits[dresscode] - if(dresscode == "Cancel") - return - if (dresscode == "As Job...") var/list/job_paths = subtypesof(/datum/outfit/job) var/list/job_outfits = list() for(var/path in job_paths) var/datum/outfit/O = path - if(initial(O.can_be_admin_equipped)) - job_outfits[initial(O.name)] = path + job_outfits[initial(O.name)] = path - dresscode = input("Select job equipment", "Robust quick dress shop") as null|anything in job_outfits + dresscode = input("Select job equipment", "Robust quick dress shop") as null|anything in sortList(job_outfits) dresscode = job_outfits[dresscode] if(isnull(dresscode)) return + if (dresscode == "As Plasmaman...") + var/list/plasmaman_paths = typesof(/datum/outfit/plasmaman) + var/list/plasmaman_outfits = list() + for(var/path in plasmaman_paths) + var/datum/outfit/O = path + plasmaman_outfits[initial(O.name)] = path + + dresscode = input("Select plasmeme equipment", "Robust quick dress shop") as null|anything in sortList(plasmaman_outfits) + dresscode = plasmaman_outfits[dresscode] + if(isnull(dresscode)) + return + if (dresscode == "Custom") var/list/custom_names = list() for(var/datum/outfit/D in GLOB.custom_outfits) custom_names[D.name] = D - var/selected_name = input("Select outfit", "Robust quick dress shop") as null|anything in custom_names + var/selected_name = input("Select outfit", "Robust quick dress shop") as null|anything in sortList(custom_names) dresscode = custom_names[selected_name] if(isnull(dresscode)) return diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm index 199004abed..7e7bac9ff0 100644 --- a/code/modules/admin/verbs/randomverbs.dm +++ b/code/modules/admin/verbs/randomverbs.dm @@ -879,8 +879,6 @@ Traitors and the like can also be revived with the previous role mostly intact. message_admins("[ADMIN_LOOKUPFLW(usr)] [N.timing ? "activated" : "deactivated"] a nuke at [ADMIN_VERBOSEJMP(N)].") SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Toggle Nuke", "[N.timing]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! -GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits - /client/proc/create_outfits() set category = "Debug" set name = "Create Custom Outfit" diff --git a/code/modules/admin/verbs/selectequipment.dm b/code/modules/admin/verbs/selectequipment.dm new file mode 100644 index 0000000000..4184fed68f --- /dev/null +++ b/code/modules/admin/verbs/selectequipment.dm @@ -0,0 +1,226 @@ +/client/proc/cmd_select_equipment(mob/target in GLOB.mob_list) + set category = "Admin.Events" + set name = "Select equipment" + + + var/datum/select_equipment/ui = new(usr, target) + ui.ui_interact(usr) + +/* + * This is the datum housing the select equipment UI. + * + * You may notice some oddities about the way outfits are passed to the UI and vice versa here. + * That's because it handles both outfit typepaths (for normal outfits) *and* outfit objects (for custom outfits). + * + * Custom outfits need to be objects as they're created in runtime. + * "Then just handle the normal outfits as objects too and simplify the handling" - you may say. + * There are about 300 outfit types at the time of writing this. Initializing all of these to objects would be a huge waste. + * + */ + +/datum/select_equipment + var/client/user + var/mob/target_mob + + var/dummy_key + + //static list to share all the outfit typepaths between all instances of this datum. + var/static/list/cached_outfits + + //a typepath if the selected outfit is a normal outfit; + //an object if the selected outfit is a custom outfit + var/datum/outfit/selected_outfit = /datum/outfit + //serializable string for the UI to keep track of which outfit is selected + var/selected_identifier = "/datum/outfit" + +/datum/select_equipment/New(_user, mob/target) + user = CLIENT_FROM_VAR(_user) + + if(!ishuman(target) && !isobserver(target)) + alert("Invalid mob") + return + target_mob = target + +/datum/select_equipment/ui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "SelectEquipment", "Select Equipment") + ui.open() + ui.set_autoupdate(FALSE) + +/datum/select_equipment/ui_state(mob/user) + return GLOB.admin_state + +/datum/select_equipment/ui_status(mob/user, datum/ui_state/state) + if(QDELETED(target_mob)) + return UI_CLOSE + return ..() + +/datum/select_equipment/ui_close(mob/user) + clear_human_dummy(dummy_key) + qdel(src) + +/datum/select_equipment/proc/init_dummy() + dummy_key = "selectequipmentUI_[target_mob]" + generate_dummy_lookalike(dummy_key, target_mob) + unset_busy_human_dummy(dummy_key) + return + +/** + * Packs up data about an outfit as an assoc list to send to the UI as an outfit entry. + * + * Args: + * * category (string) - The tab it will be under + * + * * identifier (typepath or ref) - This will sent this back to ui_act to preview or spawn in an outfit. + * * Must be unique between all entries. + * + * * name (string) - Will be the text on the button + * + * * priority (bool)(optional) - If True, the UI will sort the entry to the top, right below favorites. + * + * * custom_entry (bool)(optional) - Send the identifier with a "ref" keyword instead of "path", + * * for the UI to tell apart custom outfits from normal ones. + * + * Returns (list) An outfit entry + */ + +/datum/select_equipment/proc/outfit_entry(category, identifier, name, priority=FALSE, custom_entry=FALSE) + if(custom_entry) + return list("category" = category, "ref" = identifier, "name" = name, "priority" = priority) + return list("category" = category, "path" = identifier, "name" = name, "priority" = priority) + +/datum/select_equipment/proc/make_outfit_entries(category="General", list/outfit_list) + var/list/entries = list() + for(var/path as anything in outfit_list) + var/datum/outfit/outfit = path + entries += list(outfit_entry(category, path, initial(outfit.name))) + return entries + +//GLOB.custom_outfits lists outfit *objects* so we'll need to do some custom handling for it +/datum/select_equipment/proc/make_custom_outfit_entries(list/outfit_list) + var/list/entries = list() + for(var/datum/outfit/outfit as anything in outfit_list) + entries += list(outfit_entry("Custom", REF(outfit), outfit.name, custom_entry=TRUE)) //it's either this or special handling on the UI side + return entries + +/datum/select_equipment/ui_data(mob/user) + var/list/data = list() + if(!dummy_key) + init_dummy() + + var/icon/dummysprite = get_flat_human_icon(null, + dummy_key = dummy_key, + outfit_override = selected_outfit) + data["icon64"] = icon2base64(dummysprite) + data["name"] = target_mob + + var/datum/preferences/prefs = user?.client?.prefs + data["favorites"] = list() + if(prefs) + data["favorites"] = prefs.favorite_outfits + + var/list/custom + custom += make_custom_outfit_entries(GLOB.custom_outfits) + data["custom_outfits"] = custom + data["current_outfit"] = selected_identifier + return data + + +/datum/select_equipment/ui_static_data(mob/user) + var/list/data = list() + if(!cached_outfits) + cached_outfits = list() + cached_outfits += list(outfit_entry("General", /datum/outfit, "Naked", priority=TRUE)) + cached_outfits += make_outfit_entries("General", subtypesof(/datum/outfit) - typesof(/datum/outfit/job) - typesof(/datum/outfit/plasmaman)) + cached_outfits += make_outfit_entries("Jobs", typesof(/datum/outfit/job)) + cached_outfits += make_outfit_entries("Plasmamen Outfits", typesof(/datum/outfit/plasmaman)) + + data["outfits"] = cached_outfits + return data + + +/datum/select_equipment/proc/resolve_outfit(text) + + var/path = text2path(text) + if(ispath(path, /datum/outfit)) + return path + + else //don't bail yet - could be a custom outfit + var/datum/outfit/custom_outfit = locate(text) + if(istype(custom_outfit)) + return custom_outfit + + +/datum/select_equipment/ui_act(action, params) + if(..()) + return + . = TRUE + switch(action) + if("preview") + var/datum/outfit/new_outfit = resolve_outfit(params["path"]) + + if(ispath(new_outfit)) //got a typepath - that means we're dealing with a normal outfit + selected_identifier = new_outfit //these are keyed by type + //by the way, no, they can't be keyed by name because many of them have duplicate names + + else if(istype(new_outfit)) //got an initialized object - means it's a custom outfit + selected_identifier = REF(new_outfit) //and the outfit will be keyed by its ref (cause its type will always be /datum/outfit) + + else //we got nothing and should bail + return + + selected_outfit = new_outfit + + if("applyoutfit") + var/datum/outfit/new_outfit = resolve_outfit(params["path"]) + if(new_outfit && ispath(new_outfit)) //initialize it + new_outfit = new new_outfit + if(!istype(new_outfit)) + return + user.admin_apply_outfit(target_mob, new_outfit) + + if("customoutfit") + user.outfit_manager() + + if("togglefavorite") + var/datum/outfit/outfit_path = resolve_outfit(params["path"]) + if(!ispath(outfit_path)) //we do *not* want custom outfits (i.e objects) here, they're not even persistent + return + + if(user.prefs.favorite_outfits.Find(outfit_path)) //already there, remove it + user.prefs.favorite_outfits -= outfit_path + else //not there, add it + user.prefs.favorite_outfits += outfit_path + user.prefs.save_preferences() + +/client/proc/admin_apply_outfit(mob/target, dresscode) + if(!ishuman(target) && !isobserver(target)) + alert("Invalid mob") + return + + if(!dresscode) + return + + var/delete_pocket + var/mob/living/carbon/human/human_target + if(isobserver(target)) + human_target = target.change_mob_type(/mob/living/carbon/human, delete_old_mob = TRUE) + else + human_target = target + if(human_target.l_store || human_target.r_store || human_target.s_store) //saves a lot of time for admins and coders alike + if(alert("Drop Items in Pockets? No will delete them.", "Robust quick dress shop", "Yes", "No") == "No") + delete_pocket = TRUE + + SSblackbox.record_feedback("tally", "admin_verb", 1, "Select Equipment") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + for(var/obj/item/item in human_target.get_equipped_items(delete_pocket)) + qdel(item) + if(dresscode != "Naked") + human_target.equipOutfit(dresscode) + + human_target.regenerate_icons() + + log_admin("[key_name(usr)] changed the equipment of [key_name(human_target)] to [dresscode].") + message_admins("[key_name_admin(usr)] changed the equipment of [ADMIN_LOOKUPFLW(human_target)] to [dresscode].") + + return dresscode diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index 3e4b962bc4..81d267fcf1 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -227,6 +227,8 @@ GLOBAL_LIST_EMPTY(preferences_datums) var/persistent_scars = TRUE ///If we want to broadcast deadchat connect/disconnect messages var/broadcast_login_logout = TRUE + ///What outfit typepaths we've favorited in the SelectEquipment menu + var/list/favorite_outfits = list() /// We have 5 slots for persistent scars, if enabled we pick a random one to load (empty by default) and scars at the end of the shift if we survived as our original person var/list/scars_list = list("1" = "", "2" = "", "3" = "", "4" = "", "5" = "") /// Which of the 5 persistent scar slots we randomly roll to load for this round, if enabled. Actually rolled in [/datum/preferences/proc/load_character(slot)] diff --git a/code/modules/client/preferences_savefile.dm b/code/modules/client/preferences_savefile.dm index b8959d93aa..864bf5335a 100644 --- a/code/modules/client/preferences_savefile.dm +++ b/code/modules/client/preferences_savefile.dm @@ -385,6 +385,15 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car S["auto_ooc"] >> auto_ooc S["no_tetris_storage"] >> no_tetris_storage + //favorite outfits + S["favorite_outfits"] >> favorite_outfits + + var/list/parsed_favs = list() + for(var/typetext in favorite_outfits) + var/datum/outfit/path = text2path(typetext) + if(ispath(path)) //whatever typepath fails this check probably doesn't exist anymore + parsed_favs += path + favorite_outfits = uniqueList(parsed_favs) //try to fix any outdated data if necessary if(needs_update >= 0) @@ -434,6 +443,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car no_tetris_storage = sanitize_integer(no_tetris_storage, 0, 1, initial(no_tetris_storage)) key_bindings = sanitize_islist(key_bindings, list()) modless_key_bindings = sanitize_islist(modless_key_bindings, list()) + favorite_outfits = SANITIZE_LIST(favorite_outfits) verify_keybindings_valid() // one of these days this will runtime and you'll be glad that i put it in a different proc so no one gets their saves wiped @@ -535,6 +545,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car WRITE_FILE(S["pda_skin"], pda_skin) WRITE_FILE(S["key_bindings"], key_bindings) WRITE_FILE(S["modless_key_bindings"], modless_key_bindings) + WRITE_FILE(S["favorite_outfits"], favorite_outfits) //citadel code WRITE_FILE(S["screenshake"], screenshake) diff --git a/code/modules/clothing/chameleon.dm b/code/modules/clothing/chameleon.dm index 6e570e595a..008772663d 100644 --- a/code/modules/clothing/chameleon.dm +++ b/code/modules/clothing/chameleon.dm @@ -83,8 +83,7 @@ standard_outfit_options = list() for(var/path in subtypesof(/datum/outfit/job)) var/datum/outfit/O = path - if(initial(O.can_be_admin_equipped)) - standard_outfit_options[initial(O.name)] = path + standard_outfit_options[initial(O.name)] = path sortTim(standard_outfit_options, /proc/cmp_text_asc) outfit_options = standard_outfit_options diff --git a/code/modules/mob/living/carbon/human/dummy.dm b/code/modules/mob/living/carbon/human/dummy.dm index ed1ba3852f..3074abd070 100644 --- a/code/modules/mob/living/carbon/human/dummy.dm +++ b/code/modules/mob/living/carbon/human/dummy.dm @@ -24,7 +24,12 @@ INITIALIZE_IMMEDIATE(/mob/living/carbon/human/dummy) /mob/living/carbon/human/dummy/proc/wipe_state() delete_equipment() icon_render_key = null - cut_overlays() + cut_overlays(TRUE) + +/mob/living/carbon/human/dummy/setup_human_dna() + create_dna(src) + randomize_human(src) + dna.initialize_dna(skip_index = TRUE) //Skip stuff that requires full round init. //Inefficient pooling/caching way. GLOBAL_LIST_EMPTY(human_dummy_list) @@ -42,13 +47,48 @@ GLOBAL_LIST_EMPTY(dummy_mob_list) D = new GLOB.human_dummy_list[slotkey] = D GLOB.dummy_mob_list += D + else + D.regenerate_icons() //they were cut in wipe_state() D.in_use = TRUE return D -/proc/unset_busy_human_dummy(slotnumber) - if(!slotnumber) +/proc/generate_dummy_lookalike(slotkey, mob/target) + if(!istype(target)) + return generate_or_wait_for_human_dummy(slotkey) + + var/mob/living/carbon/human/dummy/copycat = generate_or_wait_for_human_dummy(slotkey) + + if(iscarbon(target)) + var/mob/living/carbon/carbon_target = target + carbon_target.dna.transfer_identity(copycat, transfer_SE = TRUE) + + if(ishuman(target)) + var/mob/living/carbon/human/human_target = target + human_target.copy_clothing_prefs(copycat) + + copycat.updateappearance(icon_update=TRUE, mutcolor_update=TRUE, mutations_overlay_update=TRUE) + else + //even if target isn't a carbon, if they have a client we can make the + //dummy look like what their human would look like based on their prefs + target?.client?.prefs?.copy_to(copycat, icon_updates=TRUE, roundstart_checks=FALSE) + + return copycat + +/proc/unset_busy_human_dummy(slotkey) + if(!slotkey) return - var/mob/living/carbon/human/dummy/D = GLOB.human_dummy_list[slotnumber] + var/mob/living/carbon/human/dummy/D = GLOB.human_dummy_list[slotkey] if(istype(D)) D.wipe_state() D.in_use = FALSE + +/proc/clear_human_dummy(slotkey) + if(!slotkey) + return + + var/mob/living/carbon/human/dummy/dummy = GLOB.human_dummy_list[slotkey] + + GLOB.human_dummy_list -= slotkey + if(istype(dummy)) + GLOB.dummy_mob_list -= dummy + qdel(dummy) diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 8660e115a6..c2014cbe41 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -14,10 +14,7 @@ //initialize limbs first create_bodyparts() - //initialize dna. for spawned humans; overwritten by other code - create_dna(src) - randomize_human(src) - dna.initialize_dna() + setup_human_dna() if(dna.species) set_species(dna.species.type) @@ -36,6 +33,11 @@ RegisterSignal(src, COMSIG_COMPONENT_CLEAN_ACT, /atom.proc/clean_blood) GLOB.human_list += src +/mob/living/carbon/human/proc/setup_human_dna() + //initialize dna. for spawned humans; overwritten by other code + create_dna(src) + randomize_human(src) + dna.initialize_dna() /mob/living/carbon/human/ComponentInitialize() . = ..() diff --git a/code/modules/mob/living/carbon/human/human_helpers.dm b/code/modules/mob/living/carbon/human/human_helpers.dm index 3e65bb6e66..7e3b2ab015 100644 --- a/code/modules/mob/living/carbon/human/human_helpers.dm +++ b/code/modules/mob/living/carbon/human/human_helpers.dm @@ -176,3 +176,9 @@ /mob/living/carbon/human/get_biological_state() return dna.species.get_biological_state() + +///copies over clothing preferences like underwear to another human +/mob/living/carbon/human/proc/copy_clothing_prefs(mob/living/carbon/human/destination) + destination.underwear = underwear + destination.undershirt = undershirt + destination.socks = socks diff --git a/tgstation.dme b/tgstation.dme index d13020e2e5..017bd393e7 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -1416,6 +1416,9 @@ #include "code\modules\admin\ipintel.dm" #include "code\modules\admin\IsBanned.dm" #include "code\modules\admin\NewBan.dm" +#include "code\modules\admin\outfit_editor.dm" +#include "code\modules\admin\outfit_manager.dm" +#include "code\modules\admin\outfits.dm" #include "code\modules\admin\permissionedit.dm" #include "code\modules\admin\player_panel.dm" #include "code\modules\admin\sound_emitter.dm" @@ -1456,6 +1459,7 @@ #include "code\modules\admin\verbs\randomverbs.dm" #include "code\modules\admin\verbs\reestablish_db_connection.dm" #include "code\modules\admin\verbs\secrets.dm" +#include "code\modules\admin\verbs\selectequipment.dm" #include "code\modules\admin\verbs\shuttlepanel.dm" #include "code\modules\admin\verbs\spawnobjasmob.dm" #include "code\modules\admin\verbs\tripAI.dm" diff --git a/tgui/packages/common/collections.js b/tgui/packages/common/collections.js index 7b4540e730..5c0b3d0893 100644 --- a/tgui/packages/common/collections.js +++ b/tgui/packages/common/collections.js @@ -171,6 +171,8 @@ export const sortBy = (...iterateeFns) => array => { return mappedArray; }; +export const sort = sortBy(); + /** * A fast implementation of reduce. */ @@ -235,6 +237,8 @@ export const uniqBy = iterateeFn => array => { return result; }; +export const uniq = uniqBy(); + /** * Creates an array of grouped elements, the first of which contains * the first elements of the given arrays, the second of which contains diff --git a/tgui/packages/tgui/interfaces/ListInput.js b/tgui/packages/tgui/interfaces/ListInput.js new file mode 100644 index 0000000000..721ac4f5ac --- /dev/null +++ b/tgui/packages/tgui/interfaces/ListInput.js @@ -0,0 +1,206 @@ +/** + * @file + * @copyright 2020 watermelon914 (https://github.com/watermelon914) + * @license MIT + */ + +import { clamp01 } from 'common/math'; +import { useBackend, useLocalState } from '../backend'; +import { Box, Button, Section, Input, Stack } from '../components'; +import { Window } from '../layouts'; + +const ARROW_KEY_UP = 38; +const ARROW_KEY_DOWN = 40; + +let lastScrollTime = 0; + +export const ListInput = (props, context) => { + const { act, data } = useBackend(context); + const { + title, + message, + buttons, + timeout, + } = data; + + // Search + const [showSearchBar, setShowSearchBar] = useLocalState( + context, 'search_bar', false); + const [displayedArray, setDisplayedArray] = useLocalState( + context, 'displayed_array', buttons); + + // KeyPress + const [searchArray, setSearchArray] = useLocalState( + context, 'search_array', []); + const [searchIndex, setSearchIndex] = useLocalState( + context, 'search_index', 0); + const [lastCharCode, setLastCharCode] = useLocalState( + context, 'last_char_code', null); + + // Selected Button + const [selectedButton, setSelectedButton] = useLocalState( + context, 'selected_button', buttons[0]); + + const handleKeyDown = e => { + e.preventDefault(); + if (lastScrollTime > performance.now()) { + return; + } + lastScrollTime = performance.now() + 125; + + if (e.keyCode === ARROW_KEY_UP || e.keyCode === ARROW_KEY_DOWN) { + let direction = 1; + if (e.keyCode === ARROW_KEY_UP) direction = -1; + + let index = 0; + for (index; index < buttons.length; index++) { + if (buttons[index] === selectedButton) break; + } + index += direction; + if (index < 0) index = buttons.length - 1; + else if (index >= buttons.length) index = 0; + setSelectedButton(buttons[index]); + setLastCharCode(null); + document.getElementById(buttons[index]).focus(); + return; + } + + const charCode = String.fromCharCode(e.keyCode).toLowerCase(); + if (!charCode) return; + + let foundValue; + if (charCode === lastCharCode && searchArray.length > 0) { + const nextIndex = searchIndex + 1; + + if (nextIndex < searchArray.length) { + foundValue = searchArray[nextIndex]; + setSearchIndex(nextIndex); + } + else { + foundValue = searchArray[0]; + setSearchIndex(0); + } + } + else { + const resultArray = displayedArray.filter(value => + value.substring(0, 1).toLowerCase() === charCode + ); + + if (resultArray.length > 0) { + setSearchArray(resultArray); + setSearchIndex(0); + foundValue = resultArray[0]; + } + } + + if (foundValue) { + setLastCharCode(charCode); + setSelectedButton(foundValue); + document.getElementById(foundValue).focus(); + } + }; + + return ( + + {timeout !== undefined && } + + + +
      { + setShowSearchBar(!showSearchBar); + setDisplayedArray(buttons); + }} + /> + )}> + {displayedArray.map(button => ( + + ))} +
      +
      + {showSearchBar && ( + + setDisplayedArray( + buttons.filter(val => ( + val.toLowerCase().search(value.toLowerCase()) !== -1 + )) + )} + /> + + )} + + + + + + {currItem?.sprite && ( + <> + + act("clear", { slot })} /> + + )} + + + {currItem?.name || "Empty"} + + + ); +}; diff --git a/tgui/packages/tgui/interfaces/OutfitManager.js b/tgui/packages/tgui/interfaces/OutfitManager.js new file mode 100644 index 0000000000..2ffe8cd520 --- /dev/null +++ b/tgui/packages/tgui/interfaces/OutfitManager.js @@ -0,0 +1,81 @@ +import { useBackend } from '../backend'; +import { Button, Section, Stack } from '../components'; +import { Window } from '../layouts'; + +export const OutfitManager = (props, context) => { + const { act, data } = useBackend(context); + const { outfits } = data; + return ( + + +
      +
      +
      +
      + ); +}; + diff --git a/tgui/packages/tgui/interfaces/SelectEquipment.js b/tgui/packages/tgui/interfaces/SelectEquipment.js new file mode 100644 index 0000000000..e7abf709bc --- /dev/null +++ b/tgui/packages/tgui/interfaces/SelectEquipment.js @@ -0,0 +1,214 @@ +import { filter, map, sortBy, uniq } from 'common/collections'; +import { flow } from 'common/fp'; +import { createSearch } from 'common/string'; +import { useBackend, useLocalState } from '../backend'; +import { Box, Button, Icon, Input, Section, Stack, Tabs } from '../components'; +import { Window } from '../layouts'; + +// here's an important mental define: +// custom outfits give a ref keyword instead of path +const getOutfitKey = outfit => outfit.path || outfit.ref; + +const useOutfitTabs = (context, categories) => { + return useLocalState(context, 'selected-tab', categories[0]); +}; + +export const SelectEquipment = (props, context) => { + const { act, data } = useBackend(context); + const { + name, + icon64, + current_outfit, + favorites, + } = data; + + const isFavorited = entry => favorites?.includes(entry.path); + + const outfits = map(entry => ({ + ...entry, + favorite: isFavorited(entry), + }))([ + ...data.outfits, + ...data.custom_outfits, + ]); + + // even if no custom outfits were sent, we still want to make sure there's + // at least a 'Custom' tab so the button to create a new one pops up + const categories = uniq([ + ...outfits.map(entry => entry.category), + 'Custom', + ]); + const [tab] = useOutfitTabs(context, categories); + + const [searchText, setSearchText] = useLocalState( + context, 'searchText', ''); + const searchFilter = createSearch(searchText, entry => ( + entry.name + entry.path + )); + + const visibleOutfits = flow([ + filter(entry => entry.category === tab), + filter(searchFilter), + sortBy( + entry => !entry.favorite, + entry => !entry.priority, + entry => entry.name + ), + ])(outfits); + + const getOutfitEntry = current_outfit => outfits.find(outfit => ( + getOutfitKey(outfit) === current_outfit + )); + + const currentOutfitEntry = getOutfitEntry(current_outfit); + + return ( + + + + + + + setSearchText(value)} /> + + + + + + + + + + + + +
      + +
      +
      + +
      + +
      +
      +
      +
      +
      +
      +
      + ); +}; + +const DisplayTabs = (props, context) => { + const { categories } = props; + const [tab, setTab] = useOutfitTabs(context, categories); + return ( + + {categories.map(category => ( + setTab(category)}> + {category} + + ))} + + ); +}; + +const OutfitDisplay = (props, context) => { + const { act, data } = useBackend(context); + const { current_outfit } = data; + const { entries, currentTab } = props; + return ( +
      + {entries.map(entry => ( + + )} +
      + ); +}; + +const CurrentlySelectedDisplay = (props, context) => { + const { act, data } = useBackend(context); + const { current_outfit } = data; + const { entry } = props; + return ( + + {entry?.path && ( + + act('togglefavorite', { + path: entry.path, + })} /> + + )} + + + Currently selected: + + + {entry?.name} + + + + + + + ); +}; From 358085c284c9e1bb52589cbc2837e6a26fdd4f3e Mon Sep 17 00:00:00 2001 From: Changelogs Date: Fri, 23 Apr 2021 00:06:34 +0000 Subject: [PATCH 25/75] Automatic changelog compile [ci skip] --- html/changelog.html | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/html/changelog.html b/html/changelog.html index f14078b376..8e88c39201 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -881,16 +881,6 @@
      • stops people using Message All on PDAs when their cartridge doesn't allow it
      - -

      19 February 2021

      -

      Putnam3145 updated:

      -
        -
      • Buzz Fuzz's addiction threshold is now a can and a sip as intended.
      • -
      -

      timothyteakettle updated:

      -
        -
      • staring into pierced realities is now logged
      • -
GoonStation 13 Development Team From c819879473e0d90a9baff1ff83b1687fddc99bde Mon Sep 17 00:00:00 2001 From: necromanceranne <40847847+necromanceranne@users.noreply.github.com> Date: Fri, 23 Apr 2021 12:06:24 +1000 Subject: [PATCH 26/75] Changes the space adaptation sprite to something more subtle. --- code/datums/mutations/space_adaptation.dm | 2 +- icons/effects/genetics.dmi | Bin 22667 -> 23497 bytes 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/code/datums/mutations/space_adaptation.dm b/code/datums/mutations/space_adaptation.dm index a3a2f10f2f..8b2263c2f2 100644 --- a/code/datums/mutations/space_adaptation.dm +++ b/code/datums/mutations/space_adaptation.dm @@ -11,7 +11,7 @@ /datum/mutation/human/space_adaptation/New(class_ = MUT_OTHER, timer, datum/mutation/human/copymut) ..() if(!(type in visual_indicators)) - visual_indicators[type] = list(mutable_appearance('icons/effects/genetics.dmi', "fire", -MUTATIONS_LAYER)) + visual_indicators[type] = list(mutable_appearance('icons/effects/genetics.dmi', "space_adapt", -MUTATIONS_LAYER)) /datum/mutation/human/space_adaptation/get_visual_indicator() return visual_indicators[type][1] diff --git a/icons/effects/genetics.dmi b/icons/effects/genetics.dmi index 373a9de623b7bfabc4f6fed86f82e6234e588964..16ceb1f18cd0ad71deb57e2d1596bf2eb473617f 100644 GIT binary patch delta 4595 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 delta 3765 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 Date: Fri, 23 Apr 2021 12:17:13 +1000 Subject: [PATCH 27/75] Changes emp_vulnerability from the probably to the division of the emp severity. Higher is better. --- code/modules/surgery/organs/heart.dm | 8 ++++---- code/modules/surgery/organs/liver.dm | 8 ++++---- code/modules/surgery/organs/lungs.dm | 8 ++++---- code/modules/surgery/organs/stomach.dm | 8 ++++---- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/code/modules/surgery/organs/heart.dm b/code/modules/surgery/organs/heart.dm index 2079e729f4..6263284584 100644 --- a/code/modules/surgery/organs/heart.dm +++ b/code/modules/surgery/organs/heart.dm @@ -206,7 +206,7 @@ var/dose_available = FALSE var/rid = /datum/reagent/medicine/epinephrine var/ramount = 10 - var/emp_vulnerability = 80 //Chance of permanent effects if emp-ed. + var/emp_vulnerability = 1 //The value the severity of emps are divided by to determine the likelihood of permanent damage. /obj/item/organ/heart/cybernetic/tier2 name = "cybernetic heart" @@ -214,7 +214,7 @@ icon_state = "heart-c-u" maxHealth = 1.5 * STANDARD_ORGAN_THRESHOLD dose_available = TRUE - emp_vulnerability = 40 + emp_vulnerability = 2 /obj/item/organ/heart/cybernetic/tier3 name = "upgraded cybernetic heart" @@ -224,7 +224,7 @@ dose_available = TRUE rid = /datum/reagent/medicine/atropine ramount = 5 - emp_vulnerability = 20 + emp_vulnerability = 3 /obj/item/organ/heart/cybernetic/emp_act(severity) . = ..() @@ -239,7 +239,7 @@ owner.Dizzy(10) owner.losebreath += 10 COOLDOWN_START(src, severe_cooldown, 20 SECONDS) - if(prob(emp_vulnerability/severity)) //Chance of permanent effects + if(prob(severity/emp_vulnerability)) //Chance of permanent effects organ_flags |= ORGAN_SYNTHETIC_EMP //Starts organ faliure - gonna need replacing soon. Stop() owner.visible_message("[owner] clutches at [owner.p_their()] chest as if [owner.p_their()] heart is stopping!", \ diff --git a/code/modules/surgery/organs/liver.dm b/code/modules/surgery/organs/liver.dm index afc770efae..2037547d36 100755 --- a/code/modules/surgery/organs/liver.dm +++ b/code/modules/surgery/organs/liver.dm @@ -106,7 +106,7 @@ toxLethality = 1.1 * LIVER_DEFAULT_TOX_LETHALITY maxHealth = STANDARD_ORGAN_THRESHOLD*0.5 - var/emp_vulnerability = 80 //Chance of permanent effects if emp-ed. + var/emp_vulnerability = 1 //The value the severity of emps are divided by to determine the likelihood of permanent damage. /obj/item/organ/liver/cybernetic/tier2 name = "cybernetic liver" @@ -115,7 +115,7 @@ maxHealth = 1.5 * STANDARD_ORGAN_THRESHOLD toxTolerance = 2 * LIVER_DEFAULT_TOX_TOLERANCE //6 units of toxin purging toxLethality = 0.8 * LIVER_DEFAULT_TOX_LETHALITY //20% less damage than a normal liver - emp_vulnerability = 40 + emp_vulnerability = 2 /obj/item/organ/liver/cybernetic/tier3 name = "upgraded cybernetic liver" @@ -125,7 +125,7 @@ maxHealth = 2 * STANDARD_ORGAN_THRESHOLD toxTolerance = 5 * LIVER_DEFAULT_TOX_TOLERANCE //15 units of toxin purging toxLethality = 0.4 * LIVER_DEFAULT_TOX_LETHALITY //60% less damage than a normal liver - emp_vulnerability = 20 + emp_vulnerability = 3 /obj/item/organ/liver/cybernetic/emp_act(severity) . = ..() @@ -134,5 +134,5 @@ if(!COOLDOWN_FINISHED(src, severe_cooldown)) //So we cant just spam emp to kill people. owner.adjustToxLoss(10) COOLDOWN_START(src, severe_cooldown, 10 SECONDS) - if(prob(emp_vulnerability/severity)) //Chance of permanent effects + if(prob(severity/emp_vulnerability)) //Chance of permanent effects organ_flags |= ORGAN_SYNTHETIC_EMP //Starts organ faliure - gonna need replacing soon. diff --git a/code/modules/surgery/organs/lungs.dm b/code/modules/surgery/organs/lungs.dm index 4d19d847f6..c94fb16add 100644 --- a/code/modules/surgery/organs/lungs.dm +++ b/code/modules/surgery/organs/lungs.dm @@ -553,7 +553,7 @@ organ_flags = ORGAN_SYNTHETIC maxHealth = STANDARD_ORGAN_THRESHOLD * 0.5 - var/emp_vulnerability = 80 //Chance of permanent effects if emp-ed. + var/emp_vulnerability = 1 //The value the severity of emps are divided by to determine the likelihood of permanent damage. /obj/item/organ/lungs/cybernetic/tier2 name = "cybernetic lungs" @@ -562,7 +562,7 @@ maxHealth = 1.5 * STANDARD_ORGAN_THRESHOLD safe_oxygen_min = 13 safe_oxygen_max = 100 - emp_vulnerability = 40 + emp_vulnerability = 2 /obj/item/organ/lungs/cybernetic/tier3 name = "upgraded cybernetic lungs" @@ -576,7 +576,7 @@ SA_para_min = 30 SA_sleep_min = 50 BZ_trip_balls_min = 30 - emp_vulnerability = 20 + emp_vulnerability = 3 cold_level_1_threshold = 200 cold_level_2_threshold = 140 @@ -590,7 +590,7 @@ if(!COOLDOWN_FINISHED(src, severe_cooldown)) //So we cant just spam emp to kill people. owner.losebreath += 20 COOLDOWN_START(src, severe_cooldown, 30 SECONDS) - if(prob(emp_vulnerability/severity)) //Chance of permanent effects + if(prob(severity/emp_vulnerability)) //Chance of permanent effects organ_flags |= ORGAN_SYNTHETIC_EMP //Starts organ faliure - gonna need replacing soon. /obj/item/organ/lungs/ashwalker diff --git a/code/modules/surgery/organs/stomach.dm b/code/modules/surgery/organs/stomach.dm index f286c294fc..defb062f1a 100644 --- a/code/modules/surgery/organs/stomach.dm +++ b/code/modules/surgery/organs/stomach.dm @@ -99,7 +99,7 @@ desc = "A basic device designed to mimic the functions of a human stomach" organ_flags = ORGAN_SYNTHETIC maxHealth = STANDARD_ORGAN_THRESHOLD * 0.5 - var/emp_vulnerability = 80 //Chance of permanent effects if emp-ed. + var/emp_vulnerability = 1 //The value the severity of emps are divided by to determine the likelihood of permanent damage. /obj/item/organ/stomach/cybernetic/tier2 name = "cybernetic stomach" @@ -107,7 +107,7 @@ desc = "An electronic device designed to mimic the functions of a human stomach. Handles disgusting food a bit better." maxHealth = 1.5 * STANDARD_ORGAN_THRESHOLD disgust_metabolism = 2 - emp_vulnerability = 40 + emp_vulnerability = 2 /obj/item/organ/stomach/cybernetic/tier3 name = "upgraded cybernetic stomach" @@ -115,7 +115,7 @@ desc = "An upgraded version of the cybernetic stomach, designed to improve further upon organic stomachs. Handles disgusting food very well." maxHealth = 2 * STANDARD_ORGAN_THRESHOLD disgust_metabolism = 3 - emp_vulnerability = 20 + emp_vulnerability = 3 /obj/item/organ/stomach/cybernetic/emp_act(severity) . = ..() @@ -124,7 +124,7 @@ if(!COOLDOWN_FINISHED(src, severe_cooldown)) //So we cant just spam emp to kill people. owner.vomit(stun = FALSE) COOLDOWN_START(src, severe_cooldown, 10 SECONDS) - if(prob(emp_vulnerability/severity)) //Chance of permanent effects + if(prob(severity/emp_vulnerability)) //Chance of permanent effects organ_flags |= ORGAN_SYNTHETIC_EMP //Starts organ faliure - gonna need replacing soon. /obj/item/organ/stomach/ipc From e6c23728eb7c7c6ae51b99372374ad89c5914ca2 Mon Sep 17 00:00:00 2001 From: SandPoot Date: Fri, 23 Apr 2021 12:56:11 -0300 Subject: [PATCH 28/75] upload files --- code/__HELPERS/global_lists.dm | 1 + code/__HELPERS/mobs.dm | 2 + code/__HELPERS/reagents.dm | 6 + code/game/machinery/limbgrower.dm | 429 +++++++++++--------- tgui/packages/tgui/interfaces/Limbgrower.js | 109 +++++ 5 files changed, 352 insertions(+), 195 deletions(-) create mode 100644 tgui/packages/tgui/interfaces/Limbgrower.js diff --git a/code/__HELPERS/global_lists.dm b/code/__HELPERS/global_lists.dm index b8c009ff4f..9719157d4d 100644 --- a/code/__HELPERS/global_lists.dm +++ b/code/__HELPERS/global_lists.dm @@ -68,6 +68,7 @@ for(var/spath in subtypesof(/datum/species)) var/datum/species/S = new spath() GLOB.species_list[S.id] = spath + GLOB.species_datums[S.id] = S //Surgeries for(var/path in subtypesof(/datum/surgery)) diff --git a/code/__HELPERS/mobs.dm b/code/__HELPERS/mobs.dm index 513437e57e..92cf7050e0 100644 --- a/code/__HELPERS/mobs.dm +++ b/code/__HELPERS/mobs.dm @@ -320,6 +320,8 @@ GLOBAL_LIST_INIT(nonstandard_skin_tones, list("orange")) GLOBAL_LIST_EMPTY(species_list) +GLOBAL_LIST_EMPTY(species_datums) + /proc/age2agedescription(age) switch(age) if(0 to 1) diff --git a/code/__HELPERS/reagents.dm b/code/__HELPERS/reagents.dm index de225b3b53..fa655efce4 100644 --- a/code/__HELPERS/reagents.dm +++ b/code/__HELPERS/reagents.dm @@ -95,3 +95,9 @@ if("I'm feeling lucky") chosen_id = pick(subtypesof(/datum/reagent)) return chosen_id + +/proc/find_reagent_object_from_type(input) + if(GLOB.chemical_reagents_list[input]) //prefer IDs! + return GLOB.chemical_reagents_list[input] + else + return null diff --git a/code/game/machinery/limbgrower.dm b/code/game/machinery/limbgrower.dm index aa1d05884e..dc87322b57 100644 --- a/code/game/machinery/limbgrower.dm +++ b/code/game/machinery/limbgrower.dm @@ -1,9 +1,5 @@ -#define LIMBGROWER_MAIN_MENU 1 -#define LIMBGROWER_CATEGORY_MENU 2 -#define LIMBGROWER_CHEMICAL_MENU 3 -//use these for the menu system - - +/// The limbgrower. Makes organd and limbs with synthflesh and chems. +/// See [limbgrower_designs.dm] for everything we can make. /obj/machinery/limbgrower name = "limb grower" desc = "It grows new limbs using Synthflesh." @@ -15,161 +11,235 @@ active_power_usage = 100 circuit = /obj/item/circuitboard/machine/limbgrower - var/operating = FALSE - var/disabled = FALSE + /// The category of limbs we're browing in our UI. + var/selected_category = "human" + /// If we're currently printing something. var/busy = FALSE - var/prod_coeff = 1 + /// How efficient our machine is. Better parts = less chemicals used and less power used. Range of 1 to 0.25. + var/production_coefficient = 1 + /// How long it takes for us to print a limb. Affected by production_coefficient. + var/production_speed = 3 SECONDS + /// The design we're printing currently. var/datum/design/being_built + /// Our internal techweb for limbgrower designs. var/datum/techweb/stored_research - var/selected_category - var/screen = 1 + /// All the categories of organs we can print. var/list/categories = list( - "human" = /datum/species/human, - "lizard" = /datum/species/lizard, - "mammal" = /datum/species/mammal, - "insect" = /datum/species/insect, - "fly" = /datum/species/fly, - "plasmaman" = /datum/species/plasmaman, - "xeno" = /datum/species/xeno, - "other" = /datum/species, - ) - var/list/stored_species = list() + "human", + "lizard", + "mammal", + "insect", + "fly", + "plasmaman", + "xeno", + "other", + ) var/obj/item/disk/data/dna_disk /obj/machinery/limbgrower/Initialize() create_reagents(100, OPENCONTAINER) stored_research = new /datum/techweb/specialized/autounlocking/limbgrower - for(var/i in categories) - var/species = categories[i] - stored_species[i] = new species() . = ..() + AddComponent(/datum/component/plumbing/simple_demand) + AddComponent(/datum/component/simple_rotation, ROTATION_WRENCH | ROTATION_CLOCKWISE, null, CALLBACK(src, .proc/can_be_rotated)) -/obj/machinery/limbgrower/ui_interact(mob/user) +/obj/machinery/limbgrower/ui_interact(mob/user, datum/tgui/ui) . = ..() - if(!is_operational()) - return + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "Limbgrower", src) + ui.open() - var/dat = main_win(user) +/obj/machinery/limbgrower/ui_data(mob/user) + var/list/data = list() - switch(screen) - if(LIMBGROWER_MAIN_MENU) - dat = main_win(user) - if(LIMBGROWER_CATEGORY_MENU) - dat = category_win(user,selected_category) - if(LIMBGROWER_CHEMICAL_MENU) - dat = chemical_win(user) + for(var/datum/reagent/reagent_id in reagents.reagent_list) + var/list/reagent_data = list( + reagent_name = reagent_id.name, + reagent_amount = reagent_id.volume, + reagent_type = reagent_id.type + ) + data["reagents"] += list(reagent_data) - var/datum/browser/popup = new(user, "Limb Grower", name, 400, 500) - popup.set_content(dat) - popup.open() + data["total_reagents"] = reagents.total_volume + data["max_reagents"] = reagents.maximum_volume + data["busy"] = busy + var/list/disk_data = list() + disk_data["disk"] = dna_disk //Do i, the machine, have a disk? + disk_data["name"] = dna_disk?.fields["name"] //Name for the human saved if there is one + data["disk"] = disk_data + + return data + +/obj/machinery/limbgrower/ui_static_data(mob/user) + var/list/data = list() + data["categories"] = list() + + var/species_categories = categories.Copy() + for(var/species in species_categories) + species_categories[species] = list() + for(var/design_id in stored_research.researched_designs) + var/datum/design/limb_design = SSresearch.techweb_design_by_id(design_id) + for(var/found_category in species_categories) + if(found_category in limb_design.category) + species_categories[found_category] += limb_design + + for(var/category in species_categories) + var/list/category_data = list( + name = category, + designs = list(), + ) + for(var/datum/design/found_design in species_categories[category]) + var/list/all_reagents = list() + for(var/reagent_typepath in found_design.reagents_list) + var/datum/reagent/reagent_id = find_reagent_object_from_type(reagent_typepath) + var/list/reagent_data = list( + name = reagent_id.name, + amount = (found_design.reagents_list[reagent_typepath] * production_coefficient), + ) + all_reagents += list(reagent_data) + + category_data["designs"] += list(list( + parent_category = category, + name = found_design.name, + id = found_design.id, + needed_reagents = all_reagents, + )) + + data["categories"] += list(category_data) + + return data /obj/machinery/limbgrower/on_deconstruction() - for(var/obj/item/reagent_containers/glass/G in component_parts) - reagents.trans_to(G, G.reagents.maximum_volume) + for(var/obj/item/reagent_containers/glass/our_beaker in component_parts) + reagents.trans_to(our_beaker, our_beaker.reagents.maximum_volume) ..() -/obj/machinery/limbgrower/attackby(obj/item/O, mob/user, params) - if(busy) +/obj/machinery/limbgrower/attackby(obj/item/user_item, mob/living/user, params) + if (busy) to_chat(user, "\The [src] is busy. Please wait for completion of previous operation.") return - if(default_deconstruction_screwdriver(user, "limbgrower_panelopen", "limbgrower_idleoff", O)) - updateUsrDialog() + if(default_deconstruction_screwdriver(user, "limbgrower_panelopen", "limbgrower_idleoff", user_item)) + ui_close(user) return - if(panel_open && default_deconstruction_crowbar(O)) - return - - if(user.a_intent == INTENT_HARM) //so we can hit the machine + if(user_item.tool_behaviour == TOOL_WRENCH && panel_open) return ..() - if(istype(O, /obj/item/disk)) + if(panel_open && default_deconstruction_crowbar(user_item)) + return + + if(istype(user_item, /obj/item/disk)) if(dna_disk) to_chat(user, "\The [src] already has a dna disk, take it out first!") return else - O.forceMove(src) - dna_disk = O - to_chat(user, "You insert \the [O] into \the [src].") + user_item.forceMove(src) + dna_disk = user_item + to_chat(user, "You insert \the [user_item] into \the [src].") + playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, 0) return -/obj/machinery/limbgrower/Topic(href, href_list) - if(..()) + if(user.a_intent != INTENT_HELP) + return ..() + +/obj/machinery/limbgrower/proc/can_be_rotated() + if(panel_open) + return TRUE + return FALSE + +/obj/machinery/limbgrower/ui_act(action, list/params) + . = ..() + if(.) return - if (!busy) - if(href_list["menu"]) - screen = text2num(href_list["menu"]) - if(href_list["category"]) - selected_category = href_list["category"] + if (busy) + to_chat(usr, "\The [src] is busy. Please wait for completion of previous operation.") + return - if(href_list["disposeI"]) //Get rid of a reagent incase you add the wrong one by mistake - reagents.del_reagent(text2path(href_list["disposeI"])) + switch(action) - if(href_list["make"]) + if("empty_reagent") + reagents.del_reagent(text2path(params["reagent_type"])) + . = TRUE - ///////////////// - //href protection - being_built = stored_research.isDesignResearchedID(href_list["make"]) //check if it's a valid design + if("eject_disk") + eject_disk(usr) + + if("make_limb") + being_built = stored_research.isDesignResearchedID(params["design_id"]) if(!being_built) - return + CRASH("[src] was passed an invalid design id!") + /// All the reagents we're using to make our organ. + var/list/consumed_reagents_list = being_built.reagents_list.Copy() + /// The amount of power we're going to use, based on how much reagent we use. + var/power = 0 - var/synth_cost = being_built.reagents_list[/datum/reagent/medicine/synthflesh]*prod_coeff - var/power = max(2000, synth_cost/5) + for(var/reagent_id in consumed_reagents_list) + consumed_reagents_list[reagent_id] *= production_coefficient + if(!reagents.has_reagent(reagent_id, consumed_reagents_list[reagent_id])) + audible_message("\The [src] buzzes.") + playsound(src, 'sound/machines/buzz-sigh.ogg', 50, FALSE) + return - if(reagents.has_reagent(/datum/reagent/medicine/synthflesh, being_built.reagents_list[/datum/reagent/medicine/synthflesh]*prod_coeff)) - busy = TRUE - use_power(power) - flick("limbgrower_fill",src) - icon_state = "limbgrower_idleon" - addtimer(CALLBACK(src, .proc/build_item),32*prod_coeff) + power = max(2000, (power + consumed_reagents_list[reagent_id])) - if(href_list["dna_disk"]) - var/mob/living/carbon/user = usr - if(istype(user)) - if(!dna_disk) - var/obj/item/disk/diskette = user.get_active_held_item() - if(istype(diskette)) - diskette.forceMove(src) - dna_disk = diskette - to_chat(user, "You insert \the [diskette] into \the [src].") - else - dna_disk.forceMove(src.loc) - user.put_in_active_hand(dna_disk) - to_chat(user, "You remove \the [dna_disk] from \the [src].") - dna_disk = null - else - to_chat(user, "You are unable to grasp \the [dna_disk] disk from \the [src].") - else - to_chat(usr, "\The [src] is busy. Please wait for completion of previous operation.") + busy = TRUE + use_power(power) + flick("limbgrower_fill",src) + icon_state = "limbgrower_idleon" + selected_category = params["active_tab"] + addtimer(CALLBACK(src, .proc/build_item, consumed_reagents_list), production_speed * production_coefficient) + . = TRUE - updateUsrDialog() return -/obj/machinery/limbgrower/proc/build_item() - if(reagents.has_reagent(/datum/reagent/medicine/synthflesh, being_built.reagents_list[/datum/reagent/medicine/synthflesh]*prod_coeff)) //sanity check, if this happens we are in big trouble - reagents.remove_reagent(/datum/reagent/medicine/synthflesh, being_built.reagents_list[/datum/reagent/medicine/synthflesh]*prod_coeff) - var/buildpath = being_built.build_path - if(ispath(buildpath, /obj/item/bodypart)) //This feels like spaghetti code, but i need to initiliaze a limb somehow - build_limb(buildpath) - else if(ispath(buildpath, /obj/item/organ/genital)) //genitals are uhh... customizable - build_genital(buildpath) - else - //Just build whatever it is - new buildpath(loc) - else - src.visible_message(" Something went very wrong and there isnt enough synthflesh anymore!") - busy = FALSE - flick("limbgrower_unfill",src) - icon_state = "limbgrower_idleoff" - updateUsrDialog() +/* + * The process of beginning to build a limb or organ. + * Goes through and sanity checks that we actually have enough reagent to build our item. + * Then, remove those reagents from our reagents datum. + * + * After the reagents are handled, we can proceede with making the limb or organ. (Limbs are handled in a separate proc) + * + * modified_consumed_reagents_list - the list of reagents we will consume on build, modified by the production coefficient. + */ +/obj/machinery/limbgrower/proc/build_item(list/modified_consumed_reagents_list) + for(var/reagent_id in modified_consumed_reagents_list) + if(!reagents.has_reagent(reagent_id, modified_consumed_reagents_list[reagent_id])) + audible_message("\The [src] buzzes.") + playsound(src, 'sound/machines/buzz-sigh.ogg', 50, FALSE) + break -/obj/machinery/limbgrower/proc/build_limb(buildpath) + reagents.remove_reagent(reagent_id, modified_consumed_reagents_list[reagent_id]) + + var/built_typepath = being_built.build_path + // If we have a bodypart, we need to initialize the limb on its own. Otherwise we can build it here. + if(ispath(built_typepath, /obj/item/bodypart)) + build_limb(built_typepath) + else if(ispath(built_typepath, /obj/item/organ/genital)) //genitals are uhh... customizable + build_genital(built_typepath) + else + new built_typepath(loc) + + busy = FALSE + flick("limbgrower_unfill", src) + icon_state = "limbgrower_idleoff" + +/* + * The process of putting together a limb. + * This is called from after we remove the reagents, so this proc is just initializing the limb type. + * + * This proc handles skin / mutant color, greyscaling, names and descriptions, and various other limb creation steps. + * + * built_typepath - the path of the bodypart we're building. + */ +/obj/machinery/limbgrower/proc/build_limb(built_typepath) //i need to create a body part manually using a set icon (otherwise it doesnt appear) var/obj/item/bodypart/limb - var/datum/species/selected = stored_species[selected_category] - limb = new buildpath(loc) + var/datum/species/selected = GLOB.species_datums[selected_category] + limb = new built_typepath(loc) limb.base_bp_icon = selected.icon_limbs || DEFAULT_BODYPART_ICON_ORGANIC limb.species_id = selected.limbs_id limb.color_src = (MUTCOLORS in selected.species_traits ? MUTCOLORS : (selected.use_skintones ? SKINTONE : FALSE)) @@ -189,135 +259,103 @@ BP.name = "\improper synthetic [lowertext(selected.name)] [limb.name]" BP.desc = "A synthetic [selected_category] limb that will morph on its first use in surgery. This one is for the [parse_zone(limb.body_zone)]." -/obj/machinery/limbgrower/proc/build_genital(buildpath) +/* + * Builds genitals, modifies to be the same + * as the person's cloning data on the data disk + */ +/obj/machinery/limbgrower/proc/build_genital(built_typepath) //i needed to create a way to customize gene tools using dna var/list/features = dna_disk?.fields["features"] if(length(features)) - switch(buildpath) + switch(built_typepath) if(/obj/item/organ/genital/penis) var/obj/item/organ/genital/penis/penis = new(loc) if(features["has_cock"]) penis.shape = features["cock_shape"] penis.length = features["cock_shape"] penis.diameter_ratio = features["cock_diameter_ratio"] - penis.color = sanitize_hexcolor(features["cock_color"], 6) - penis.update_icon() + penis.color = sanitize_hexcolor(features["cock_color"], 6, TRUE) + penis.update() if(/obj/item/organ/genital/testicles) var/obj/item/organ/genital/testicles/balls = new(loc) if(features["has_balls"]) - balls.color = sanitize_hexcolor(features["balls_color"], 6) + balls.color = sanitize_hexcolor(features["balls_color"], 6, TRUE) balls.shape = features["balls_shape"] balls.size = features["balls_size"] balls.fluid_rate = features["balls_cum_rate"] balls.fluid_mult = features["balls_cum_mult"] balls.fluid_efficiency = features["balls_efficiency"] + balls.update() if(/obj/item/organ/genital/vagina) var/obj/item/organ/genital/vagina/vegana = new(loc) - if(features["has_vagina"]) - vegana.color = sanitize_hexcolor(features["vag_color"], 6) + if(features["has_vag"]) + vegana.color = sanitize_hexcolor(features["vag_color"], 6, TRUE) vegana.shape = features["vag_shape"] + vegana.update() if(/obj/item/organ/genital/breasts) var/obj/item/organ/genital/breasts/boobs = new(loc) if(features["has_breasts"]) - boobs.color = sanitize_hexcolor(features["breasts_color"], 6) + boobs.color = sanitize_hexcolor(features["breasts_color"], 6, TRUE) boobs.size = features["breasts_size"] boobs.shape = features["breasts_shape"] if(!features["breasts_producing"]) boobs.genital_flags &= ~(GENITAL_FUID_PRODUCTION|CAN_CLIMAX_WITH|CAN_MASTURBATE_WITH) + boobs.update() else - new buildpath(loc) + new built_typepath(loc) else - new buildpath(loc) + new built_typepath(loc) /obj/machinery/limbgrower/RefreshParts() reagents.maximum_volume = 0 - for(var/obj/item/reagent_containers/glass/G in component_parts) - reagents.maximum_volume += G.volume - G.reagents.trans_to(src, G.reagents.total_volume) - var/T=1.2 - for(var/obj/item/stock_parts/manipulator/M in component_parts) - T -= M.rating*0.2 - prod_coeff = min(1,max(0,T)) // Coeff going 1 -> 0,8 -> 0,6 -> 0,4 + for(var/obj/item/reagent_containers/glass/our_beaker in component_parts) + reagents.maximum_volume += our_beaker.volume + our_beaker.reagents.trans_to(src, our_beaker.reagents.total_volume) + production_coefficient = 1.2 + for(var/obj/item/stock_parts/manipulator/our_manipulator in component_parts) + production_coefficient -= our_manipulator.rating * 0.2 + production_coefficient = clamp(production_coefficient, 0, 1) // coefficient goes from 1 -> 0.8 -> 0.6 -> 0.4 /obj/machinery/limbgrower/examine(mob/user) . = ..() + if(!panel_open) + . += "It looks like as if the panel were open you could rotate it with a wrench." + else + . += "The panel is open." if(in_range(user, src) || isobserver(user)) - . += "The status display reads: Storing up to [reagents.maximum_volume]u of synthflesh.
Synthflesh consumption at [prod_coeff*100]%." + . += "The status display reads: Storing up to [reagents.maximum_volume]u of reagents.
Reagent consumption rate at [production_coefficient * 100]%.
" -/obj/machinery/limbgrower/proc/main_win(mob/user) - var/dat = "

[src] Menu:


" - dat += "[dna_disk ? "Remove" : "Insert"] cloning data disk" - dat += "
" - dat += "Chemical Storage" - dat += materials_printout() - dat += "" - - for(var/C in categories) - dat += "" - dat += "" - //one category per line - - dat += "
[C]
" - return dat - -/obj/machinery/limbgrower/proc/category_win(mob/user,selected_category) - var/dat = "Return to main menu" - dat += "

Browsing [selected_category]:


" - dat += materials_printout() - - for(var/v in stored_research.researched_designs) - var/datum/design/D = SSresearch.techweb_design_by_id(v) - if(!(selected_category in D.category)) - continue - if(disabled || !can_build(D)) - dat += "[D.name]" - else - dat += "[D.name]" - dat += "[get_design_cost(D)]
" - - dat += "
" - return dat - - -/obj/machinery/limbgrower/proc/chemical_win(mob/user) - var/dat = "Return to main menu" - dat += "

Browsing Chemical Storage:


" - dat += materials_printout() - - for(var/datum/reagent/R in reagents.reagent_list) - dat += "[R.name]: [R.volume]" - dat += "Purge
" - - dat += "
" - return dat - -/obj/machinery/limbgrower/proc/materials_printout() - var/dat = "Total amount:> [reagents.total_volume] / [reagents.maximum_volume] cm3
" - return dat - -/obj/machinery/limbgrower/proc/can_build(datum/design/D) - return (reagents.has_reagent(/datum/reagent/medicine/synthflesh, D.reagents_list[/datum/reagent/medicine/synthflesh]*prod_coeff)) //Return whether the machine has enough synthflesh to produce the design - -/obj/machinery/limbgrower/proc/get_design_cost(datum/design/D) - var/dat - if(D.reagents_list[/datum/reagent/medicine/synthflesh]) - dat += "[D.reagents_list[/datum/reagent/medicine/synthflesh] * prod_coeff] Synthetic flesh " - return dat +/* + * Checks our reagent list to see if a design can be built. + * + * limb_design - the design we're checking for buildability. + * + * returns TRUE if we have enough reagent to build it. Returns FALSE if we do not. + */ +/obj/machinery/limbgrower/proc/can_build(datum/design/limb_design) + for(var/datum/reagent/reagent_id in limb_design.reagents_list) + if(!reagents.has_reagent(reagent_id, limb_design.reagents_list[reagent_id] * production_coefficient)) + return FALSE + return TRUE +/// Emagging a limbgrower allows you to build synthetic armblades. /obj/machinery/limbgrower/emag_act(mob/user) . = ..() if(obj_flags & EMAGGED) return - for(var/id in SSresearch.techweb_designs) - var/datum/design/D = SSresearch.techweb_design_by_id(id) - if((D.build_type & LIMBGROWER) && ("emagged" in D.category)) - stored_research.add_design(D) + for(var/design_id in SSresearch.techweb_designs) + var/datum/design/found_design = SSresearch.techweb_design_by_id(design_id) + if((found_design.build_type & LIMBGROWER) && ("emagged" in found_design.category)) + stored_research.add_design(found_design) to_chat(user, "A warning flashes onto the screen, stating that safety overrides have been deactivated!") obj_flags |= EMAGGED - return TRUE + update_static_data(user) /obj/machinery/limbgrower/AltClick(mob/living/user) . = ..() + eject_disk(user) + +/obj/machinery/limbgrower/proc/eject_disk(mob/user) if(istype(user) && user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK)) if(busy) to_chat(user, "\The [src] is busy. Please wait for completion of previous operation.") @@ -326,6 +364,7 @@ dna_disk.forceMove(src.loc) user.put_in_active_hand(dna_disk) to_chat(user, "You remove \the [dna_disk] from \the [src].") + playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, 0) dna_disk = null else to_chat(user, "\The [src] has doesn't have a disk on it!") diff --git a/tgui/packages/tgui/interfaces/Limbgrower.js b/tgui/packages/tgui/interfaces/Limbgrower.js new file mode 100644 index 0000000000..61aa5c8a02 --- /dev/null +++ b/tgui/packages/tgui/interfaces/Limbgrower.js @@ -0,0 +1,109 @@ +import { useBackend, useSharedState } from '../backend'; +import { Box, Button, Dimmer, Icon, LabeledList, Section, Tabs } from '../components'; +import { Window } from '../layouts'; + +export const Limbgrower = (props, context) => { + const { act, data } = useBackend(context); + const { + reagents = [], + total_reagents, + max_reagents, + categories = [], + busy, + disk = [], + } = data; + const [tab, setTab] = useSharedState( + context, 'category', categories[0]?.name); + const designList = categories + .find(category => category.name === tab) + ?.designs; + + return ( + + {!!busy && ( + + + {' Building...'} + + )} + +
act('eject_disk')} + disabled={!disk['disk']} + /> + }> + {disk['name'] ? ( +
+ Containing data for {disk['name']},
+ Attempting to create genitalia will use the disk's data. +
+ ) : disk['disk'] ? "No data." : "No disk."} +
+
+ + {total_reagents} / {max_reagents} reagent capacity used. + + + {reagents.map(reagent => ( + act('empty_reagent', { + reagent_type: reagent.reagent_type, + })} /> + )}> + {reagent.reagent_amount}u + + ))} + +
+
+ + {categories.map(category => ( + setTab(category.name)}> + {category.name} + + ))} + + + {designList.map(design => ( + act('make_limb', { + design_id: design.id, + active_tab: design.parent_category, + })} /> + )}> + {design.needed_reagents.map(reagent => ( + + {reagent.name}: {reagent.amount}u + + ))} + + ))} + +
+
+
+ ); +}; From b386d3826aaaccd6d76938484db623d6b28e1b96 Mon Sep 17 00:00:00 2001 From: SandPoot Date: Fri, 23 Apr 2021 13:22:59 -0300 Subject: [PATCH 29/75] tgui part 1 --- tgui/packages/tgui/interfaces/Limbgrower.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tgui/packages/tgui/interfaces/Limbgrower.js b/tgui/packages/tgui/interfaces/Limbgrower.js index 61aa5c8a02..b91c7e4b45 100644 --- a/tgui/packages/tgui/interfaces/Limbgrower.js +++ b/tgui/packages/tgui/interfaces/Limbgrower.js @@ -36,14 +36,14 @@ export const Limbgrower = (props, context) => { icon="eject" onClick={() => act('eject_disk')} disabled={!disk['disk']} - /> + /> }> {disk['name'] ? (
Containing data for {disk['name']},
- Attempting to create genitalia will use the disk's data. + Attempting to create genitalia will use the disk's data.
- ) : disk['disk'] ? "No data." : "No disk."} + ) : disk['disk'] ? "No data." : "No disk."}
From 1d42e9f4e0aae2542eddbe3d4d8c19ee115f7926 Mon Sep 17 00:00:00 2001 From: WanderingFox95 <75953558+WanderingFox95@users.noreply.github.com> Date: Fri, 23 Apr 2021 23:12:58 +0200 Subject: [PATCH 30/75] Adjusts projectile count and delay --- code/modules/projectiles/guns/misc/chem_gun.dm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/code/modules/projectiles/guns/misc/chem_gun.dm b/code/modules/projectiles/guns/misc/chem_gun.dm index dcabc13989..779ab64bc2 100644 --- a/code/modules/projectiles/guns/misc/chem_gun.dm +++ b/code/modules/projectiles/guns/misc/chem_gun.dm @@ -13,9 +13,9 @@ custom_materials = list(/datum/material/iron=2000) clumsy_check = FALSE fire_sound = 'sound/items/syringeproj.ogg' - var/time_per_syringe = 250 - var/syringes_left = 4 - var/max_syringes = 4 + var/time_per_syringe = 300 + var/syringes_left = 5 + var/max_syringes = 5 var/last_synth = 0 /obj/item/gun/chem/Initialize() From 4e0bf12c0c8c4e970ddc0839e805100da8ce6277 Mon Sep 17 00:00:00 2001 From: WanderingFox95 <75953558+WanderingFox95@users.noreply.github.com> Date: Fri, 23 Apr 2021 23:15:40 +0200 Subject: [PATCH 31/75] Modifies dart size and properties They inject less but pierce again --- code/modules/projectiles/ammunition/special/syringe.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/modules/projectiles/ammunition/special/syringe.dm b/code/modules/projectiles/ammunition/special/syringe.dm index 10e4402856..caf5da3562 100644 --- a/code/modules/projectiles/ammunition/special/syringe.dm +++ b/code/modules/projectiles/ammunition/special/syringe.dm @@ -25,7 +25,7 @@ /obj/item/ammo_casing/chemgun name = "dart synthesiser" desc = "A high-power spring, linked to an energy-based dart synthesiser." - projectile_type = /obj/item/projectile/bullet/dart + projectile_type = /obj/item/projectile/bullet/dart/piercing firing_effect_type = null /obj/item/ammo_casing/chemgun/ready_proj(atom/target, mob/living/user, quiet, zone_override = "") @@ -35,7 +35,7 @@ var/obj/item/gun/chem/CG = loc if(CG.syringes_left <= 0) return - CG.reagents.trans_to(BB, 15) + CG.reagents.trans_to(BB, 10) BB.name = "chemical dart" CG.syringes_left-- ..() From 35269554bb7c6a4af5f88738c6a09aaa623816fa Mon Sep 17 00:00:00 2001 From: WanderingFox95 <75953558+WanderingFox95@users.noreply.github.com> Date: Fri, 23 Apr 2021 23:18:13 +0200 Subject: [PATCH 32/75] Adjusts TC cost Shouldn't be over half your TC, if the Dart Pistol is only 2 TC and infinitely more useful under non-role restricted circumstances --- code/modules/uplink/uplink_items/uplink_roles.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/modules/uplink/uplink_items/uplink_roles.dm b/code/modules/uplink/uplink_items/uplink_roles.dm index 4edbe2f2c7..253e8d0f85 100644 --- a/code/modules/uplink/uplink_items/uplink_roles.dm +++ b/code/modules/uplink/uplink_items/uplink_roles.dm @@ -210,7 +210,7 @@ name = "Reagent Dartgun" desc = "A heavily modified syringe gun which is capable of synthesizing its own chemical darts using input reagents. Can hold 100u of reagents." item = /obj/item/gun/chem - cost = 12 + cost = 10 restricted_roles = list("Chemist", "Chief Medical Officer") /datum/uplink_item/role_restricted/reverse_bear_trap @@ -257,4 +257,4 @@ item = /obj/item/storage/toolbox/emergency/turret cost = 11 restricted_roles = list("Station Engineer") - + From bda28655304379a4fe5bf238c75b31359e323ed2 Mon Sep 17 00:00:00 2001 From: WanderingFox95 <75953558+WanderingFox95@users.noreply.github.com> Date: Fri, 23 Apr 2021 23:24:41 +0200 Subject: [PATCH 33/75] Made the description actually describe the limitaitons --- code/modules/uplink/uplink_items/uplink_roles.dm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/code/modules/uplink/uplink_items/uplink_roles.dm b/code/modules/uplink/uplink_items/uplink_roles.dm index 253e8d0f85..774c2d9794 100644 --- a/code/modules/uplink/uplink_items/uplink_roles.dm +++ b/code/modules/uplink/uplink_items/uplink_roles.dm @@ -208,7 +208,8 @@ /datum/uplink_item/role_restricted/chemical_gun name = "Reagent Dartgun" - desc = "A heavily modified syringe gun which is capable of synthesizing its own chemical darts using input reagents. Can hold 100u of reagents." + desc = "A heavily modified syringe gun which is capable of synthesizing its own chemical darts using input reagents. \ + Synthesizes one piercing 10 unit dart every 30 seconds up to a maximum of five. Can hold 100u of reagents." item = /obj/item/gun/chem cost = 10 restricted_roles = list("Chemist", "Chief Medical Officer") From f40f4c8257498cfc09c9749449604e70c312f355 Mon Sep 17 00:00:00 2001 From: SandPoot Date: Fri, 23 Apr 2021 19:30:28 -0300 Subject: [PATCH 34/75] upload files --- code/game/objects/items/airlock_painter.dm | 8 +- code/modules/asset_cache/asset_list_items.dm | 8 ++ icons/turf/decals.dmi | Bin 56641 -> 56569 bytes tgui/packages/tgui/interfaces/DecalPainter.js | 72 +++++++++++++++--- 4 files changed, 76 insertions(+), 12 deletions(-) diff --git a/code/game/objects/items/airlock_painter.dm b/code/game/objects/items/airlock_painter.dm index b28de437ed..8edd1c2a76 100644 --- a/code/game/objects/items/airlock_painter.dm +++ b/code/game/objects/items/airlock_painter.dm @@ -157,7 +157,7 @@ to_chat(user, "You need to get closer!") return if(use_paint(user) && isturf(F)) - F.AddElement(/datum/element/decal, 'icons/turf/decals.dmi', stored_decal_total, turn(stored_dir, -dir2angle(F.dir)), CLEAN_STRONG, color, null, null, alpha) + F.AddElement(/datum/element/decal, 'icons/turf/decals.dmi', stored_decal_total, stored_dir, CLEAN_STRONG, color, null, null, alpha) /obj/item/airlock_painter/decal/attack_self(mob/user) if((ink) && (ink.charges >= 1)) @@ -180,6 +180,11 @@ stored_decal_total = "[stored_decal][yellow_fix][stored_color]" return +/obj/item/airlock_painter/decal/ui_assets(mob/user) + return list( + get_asset_datum(/datum/asset/spritesheet/decals) + ) + /obj/item/airlock_painter/decal/ui_interact(mob/user, datum/tgui/ui) ui = SStgui.try_update_ui(user, src, ui) if(!ui) @@ -189,6 +194,7 @@ /obj/item/airlock_painter/decal/ui_data(mob/user) var/list/data = list() data["decal_direction"] = stored_dir + data["decal_dir_text"] = dir2text(stored_dir) data["decal_color"] = stored_color data["decal_style"] = stored_decal data["decal_list"] = list() diff --git a/code/modules/asset_cache/asset_list_items.dm b/code/modules/asset_cache/asset_list_items.dm index e32fcee639..8eedd640a7 100644 --- a/code/modules/asset_cache/asset_list_items.dm +++ b/code/modules/asset_cache/asset_list_items.dm @@ -345,6 +345,14 @@ InsertAll("", each, GLOB.alldirs) ..() +/datum/asset/spritesheet/decals + name = "decals" + +/datum/asset/spritesheet/decals/register() + for(var/each in list('icons/turf/decals.dmi')) + InsertAll("", each, GLOB.alldirs) + ..() + /datum/asset/spritesheet/supplypods name = "supplypods" diff --git a/icons/turf/decals.dmi b/icons/turf/decals.dmi index 2b2b62a99c26bf77583794fa5acdbec25b8d0fb7..4ed8c8db9a7c770241611f7da0eb678447fff02b 100644 GIT binary patch literal 56569 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%0ARrr~ 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π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

1^Y-oM?}IcwWz zA0r*CmL2;(SJi27oE!BEXW#+`5II_Nlrr^%T)c@>M9BL`qF087Js{VWsk#^5$ceek zW8Hvc=elv~?6MCBP{A1~&pJ%S4NCw%tgMX@1_@*QS5cda@?ZgxCzv?i=g*j3yH;wH zHnMT%^m$!h1Q;gJ}yKdl!ObDOyCsx$wG(_$SIYk(P-GTz)0V0Mc=;0ak;tnzd3<^w}dCr;0zC zOgHk_!UK%$IZ&Z%Wj{ZaptdW<^3E#U-a%lelHCVzfH&K5j5(+L=R58TUyJ?yoL znn%no$-213nq2%6>dQ#_Lt?k`)@6NQB0itqtUpprzcR1ec_da;)RxLs{BCN+B|ogoA80Aeqw#gN zyfgH;ZC$*mnq5_#yW%eE_cU2(J7$2T@9U7=Qi*^==1a^VHBs_acycS2Yna4$h~(W! z#A;o%Uq>|3RB$|YKCHc;;1*THX&5@dI9)kUoA8^UdE8bB`?Oz_+0haKn|%Y3jW3$| zws^d6iuaWaJ@*|^@UL}-;L{23rgj%PTs@VWTfyc>^lYE2-?4Y!QG=9ZtEQ>0YP!o2 zv|-0yyB!X0A0up+dqf6dq7MlR1vefN-J#l_JT5P|S0yI)945rP5Q7r^FmGYB!KKw!Xf$^7u7I*J`eyZ0?cG{U&x23GreIVL? z&mnSLa9T*61i&C#AT91}y}~&d9eir`?LO@vWNPZu`w_4`kSsreal(Dy)$LlI`@FpN zd5Bh|Nc>CBYVZdU{{gtDty6O2N016_S^Ta~%1%wMlS(^QZCsk#FLCiYxxRd(Y5xhr; zhlKvz8_LKa>Byj>;akje! LJe;d`1~LB$)W@eb diff --git a/tgui/packages/tgui/interfaces/DecalPainter.js b/tgui/packages/tgui/interfaces/DecalPainter.js index 90ab589208..7ca080f5e5 100644 --- a/tgui/packages/tgui/interfaces/DecalPainter.js +++ b/tgui/packages/tgui/interfaces/DecalPainter.js @@ -1,6 +1,7 @@ import { useBackend } from '../backend'; -import { Button, Section } from '../components'; +import { Box, Button, Section } from '../components'; import { Window } from '../layouts'; +import { classes } from 'common/react'; export const DecalPainter = (props, context) => { const { act, data } = useBackend(context); @@ -16,11 +17,25 @@ export const DecalPainter = (props, context) => { {decal_list.map(decal => ( ))}

@@ -28,15 +43,29 @@ export const DecalPainter = (props, context) => { return ( ); })}
@@ -45,7 +74,12 @@ export const DecalPainter = (props, context) => { return ( ); })} From 3438da2b445c9d0d2a6db75647c8e25fb3f8ee66 Mon Sep 17 00:00:00 2001 From: SandPoot Date: Fri, 23 Apr 2021 19:43:20 -0300 Subject: [PATCH 35/75] indentation part 1 --- tgui/packages/tgui/interfaces/DecalPainter.js | 58 +++++++++---------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/tgui/packages/tgui/interfaces/DecalPainter.js b/tgui/packages/tgui/interfaces/DecalPainter.js index 7ca080f5e5..c28ba8b4f1 100644 --- a/tgui/packages/tgui/interfaces/DecalPainter.js +++ b/tgui/packages/tgui/interfaces/DecalPainter.js @@ -27,14 +27,14 @@ export const DecalPainter = (props, context) => { onClick={() => act('select decal', { decals: decal.decal, })}> - + ))} @@ -49,22 +49,22 @@ export const DecalPainter = (props, context) => { padding: 0, }} tooltip={color.colors === "red" - ? "Red" - : color.colors === "white" - ? "White" - : "Yellow"} + ? "Red" + : color.colors === "white" + ? "White" + : "Yellow"} selected={color.colors === data.decal_color} onClick={() => act('select color', { colors: color.colors, })}> - + ); })} @@ -90,10 +90,10 @@ export const DecalPainter = (props, context) => { onClick={() => act('selected direction', { dirs: dir.dirs, })}> - { ? "east" : "west") + '-' + data.decal_style + (data.decal_color ? '_' + data.decal_color : ''), - ])} - style={{ - transform: 'scale(1.5) translate(17%, 17%)', - }} /> - + ])} + style={{ + transform: 'scale(1.5) translate(17%, 17%)', + }} /> + ); })} From 24d0b8f108a9eb5555bbaa8624a2dc4a710684cd Mon Sep 17 00:00:00 2001 From: Changelogs Date: Sat, 24 Apr 2021 00:06:57 +0000 Subject: [PATCH 36/75] Automatic changelog compile [ci skip] --- html/changelog.html | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/html/changelog.html b/html/changelog.html index 8e88c39201..241394e803 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -857,30 +857,6 @@
  • the query for checking mentors now gets properly deleted
  • vampires no longer burn in the chapel if they signed up as the chaplain
  • - -

    20 February 2021

    -

    Adelphon updated:

    -
      -
    • polychromic pants
    • -
    • urban coat made polychromic
    • -
    -

    Chiirno updated:

    -
      -
    • Synthflesh now unhusks with 100u instead of requiring 101u.
    • -
    -

    SmArtKar updated:

    -
      -
    • Added some QoL changes to TCG
    • -
    • Fixed TCG cards not saving
    • -
    -

    TyrianTyrell updated:

    -
      -
    • fixed the signed language so that you can actually use it, and that it's unusable when it's meant to be.
    • -
    -

    timothyteakettle updated:

    -
      -
    • stops people using Message All on PDAs when their cartridge doesn't allow it
    • -
    GoonStation 13 Development Team From aebca1767efe03536a2cb960e38b00090e115e58 Mon Sep 17 00:00:00 2001 From: The0bserver Date: Fri, 23 Apr 2021 23:20:16 -0400 Subject: [PATCH 37/75] In a station full of bad ideas, these costs were.. --- .../boxes_magazines/external/pistol.dm | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/modular_citadel/code/modules/projectiles/boxes_magazines/external/pistol.dm b/modular_citadel/code/modules/projectiles/boxes_magazines/external/pistol.dm index c39c66578b..65dc14a0f5 100644 --- a/modular_citadel/code/modules/projectiles/boxes_magazines/external/pistol.dm +++ b/modular_citadel/code/modules/projectiles/boxes_magazines/external/pistol.dm @@ -3,8 +3,7 @@ desc = "A gun magazine. Loaded with rounds which ignite the target.." id = "10mminc" build_type = PROTOLATHE - materials = list(/datum/material/plasma = 50000, /datum/material/iron = 18000) - reagents_list = list(/datum/reagent/toxin/plasma = 120, /datum/reagent/napalm = 240) + materials = list(/datum/material/plasma = 5000, /datum/material/iron = 7500) build_path = /obj/item/ammo_box/magazine/m10mm/fire category = list("Weapons") departmental_flags = DEPARTMENTAL_FLAG_SECURITY @@ -14,7 +13,7 @@ desc = "A gun magazine." id = "10mm" build_type = PROTOLATHE - materials = list(/datum/material/iron = 55000) + materials = list(/datum/material/iron = 6000) build_path = /obj/item/ammo_box/magazine/m10mm category = list("Ammo") departmental_flags = DEPARTMENTAL_FLAG_SECURITY @@ -24,8 +23,7 @@ desc = "A gun magazine. Loaded with hollow-point rounds, extremely effective against unarmored targets, but nearly useless against protective clothing." id = "10mmhp" build_type = PROTOLATHE - materials = list(/datum/material/iron = 40000, /datum/material/glass = 50000) - reagents_list = list(/datum/reagent/sonic_powder = 280) + materials = list(/datum/material/iron = 7500, /datum/material/glass = 5000) build_path = /obj/item/ammo_box/magazine/m10mm/hp category = list("Ammo") departmental_flags = DEPARTMENTAL_FLAG_SECURITY @@ -35,7 +33,7 @@ desc = "A gun magazine. Loaded with rounds which penetrate armour, but are less effective against normal targets." id = "10mmap" build_type = PROTOLATHE - materials = list(/datum/material/iron = 40000, /datum/material/titanium = 60000) + materials = list(/datum/material/iron = 7500, /datum/material/titanium = 6500) build_path = /obj/item/ammo_box/magazine/m10mm/ap category = list("Ammo") departmental_flags = DEPARTMENTAL_FLAG_SECURITY @@ -54,7 +52,7 @@ name = "handgun magazine (.45)" id = "m45" build_type = PROTOLATHE - materials = list(/datum/material/iron = 80000) + materials = list(/datum/material/iron = 8000) build_path = /obj/item/ammo_box/magazine/m45 category = list("Ammo") departmental_flags = DEPARTMENTAL_FLAG_SECURITY @@ -64,7 +62,7 @@ desc = "A gun magazine." id = "pistolm9mm" build_type = PROTOLATHE - materials = list(/datum/material/iron = 80000) + materials = list(/datum/material/iron = 7500) build_path = /obj/item/ammo_box/magazine/pistolm9mm category = list("Ammo") departmental_flags = DEPARTMENTAL_FLAG_SECURITY @@ -84,7 +82,7 @@ desc = "A revolver speedloader. Cuts through like a hot knife through butter." id = "sl357ap" build_type = PROTOLATHE - materials = list(/datum/material/iron = 30000, /datum/material/titanium = 45000) + materials = list(/datum/material/iron = 30000, /datum/material/titanium = 5000) build_path = /obj/item/ammo_box/a357/ap category = list("Ammo") departmental_flags = DEPARTMENTAL_FLAG_SECURITY From c7b231637e064f130a1034aa8502c661cec85202 Mon Sep 17 00:00:00 2001 From: The0bserver Date: Sat, 24 Apr 2021 00:53:57 -0400 Subject: [PATCH 38/75] boxes of ammo, also fire not weapon is bullet --- .../research/techweb/nodes/syndicate_nodes.dm | 2 +- .../boxes_magazines/external/pistol.dm | 32 ++++++++++++++++++- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/code/modules/research/techweb/nodes/syndicate_nodes.dm b/code/modules/research/techweb/nodes/syndicate_nodes.dm index e659e49ac7..5a3c0f541f 100644 --- a/code/modules/research/techweb/nodes/syndicate_nodes.dm +++ b/code/modules/research/techweb/nodes/syndicate_nodes.dm @@ -21,7 +21,7 @@ id = "advanced_illegal_ballistics" display_name = "Advanced Non-Standard Ballistics" description = "Ballistic ammunition for non-standard firearms. Usually the ones you don't have nor want to be involved with." - design_ids = list("10mm","10mmap","10mminc","10mmhp","sl357","sl357ap","pistolm9mm","m45","bolt_clip") + design_ids = list("10mm","10mmap","10mminc","10mmhp","sl357","sl357ap","pistolm9mm","m45","bolt_clip","m10apbox","m10firebox","m10hpbox") prereq_ids = list("ballistic_weapons","syndicate_basic","explosive_weapons") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 25000) //This gives sec lethal mags/clips for guns from traitors, space, or anything in between. diff --git a/modular_citadel/code/modules/projectiles/boxes_magazines/external/pistol.dm b/modular_citadel/code/modules/projectiles/boxes_magazines/external/pistol.dm index 65dc14a0f5..394ffcc58d 100644 --- a/modular_citadel/code/modules/projectiles/boxes_magazines/external/pistol.dm +++ b/modular_citadel/code/modules/projectiles/boxes_magazines/external/pistol.dm @@ -5,7 +5,7 @@ build_type = PROTOLATHE materials = list(/datum/material/plasma = 5000, /datum/material/iron = 7500) build_path = /obj/item/ammo_box/magazine/m10mm/fire - category = list("Weapons") + category = list("Ammo") departmental_flags = DEPARTMENTAL_FLAG_SECURITY /datum/design/m10mm @@ -86,3 +86,33 @@ build_path = /obj/item/ammo_box/a357/ap category = list("Ammo") departmental_flags = DEPARTMENTAL_FLAG_SECURITY + +/datum/design/m10apbox + name = "ammo box (10mm Armour Piercing)" + desc = "A box of ammo containing 20 rounds designed to penetrate armor, at the cost of raw damage." + id = "10apbox" + build_type = PROTOLATHE + materials = list(/datum/material/iron = 30000, /datum/material/titanium = 5000) + build_path = /obj/item/ammo_box/c10mm/ap + category = list("Ammo") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY + +/datum/design/m10firebox + name = "ammo box (10mm Incendiary)" + desc = "A box of ammo containing 20 rounds designed to set people ablaze, at the cost of raw damage." + id = "10apbox" + build_type = PROTOLATHE + materials = list(/datum/material/iron = 30000, /datum/material/titanium = 5000) + build_path = /obj/item/ammo_box/c10mm/fire + category = list("Ammo") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY + +/datum/design/m10hpbox + name = "ammo box (10mm Hollowpoint)" + desc = "A box of ammo containing 20 rounds designed to tear through unarmored opponents, while being completely ineffective against armor." + id = "10apbox" + build_type = PROTOLATHE + materials = list(/datum/material/iron = 30000, /datum/material/titanium = 5000) + build_path = /obj/item/ammo_box/c10mm/hp + category = list("Ammo") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY From 42ed17d2aff128d396525a8c08e2f0172b655580 Mon Sep 17 00:00:00 2001 From: The0bserver Date: Sat, 24 Apr 2021 00:54:56 -0400 Subject: [PATCH 39/75] this too --- .../modules/projectiles/boxes_magazines/external/pistol.dm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modular_citadel/code/modules/projectiles/boxes_magazines/external/pistol.dm b/modular_citadel/code/modules/projectiles/boxes_magazines/external/pistol.dm index 394ffcc58d..eb8da2726e 100644 --- a/modular_citadel/code/modules/projectiles/boxes_magazines/external/pistol.dm +++ b/modular_citadel/code/modules/projectiles/boxes_magazines/external/pistol.dm @@ -92,7 +92,7 @@ desc = "A box of ammo containing 20 rounds designed to penetrate armor, at the cost of raw damage." id = "10apbox" build_type = PROTOLATHE - materials = list(/datum/material/iron = 30000, /datum/material/titanium = 5000) + materials = list(/datum/material/iron = 30000, /datum/material/titanium = 6000) build_path = /obj/item/ammo_box/c10mm/ap category = list("Ammo") departmental_flags = DEPARTMENTAL_FLAG_SECURITY @@ -102,7 +102,7 @@ desc = "A box of ammo containing 20 rounds designed to set people ablaze, at the cost of raw damage." id = "10apbox" build_type = PROTOLATHE - materials = list(/datum/material/iron = 30000, /datum/material/titanium = 5000) + materials = list(/datum/material/iron = 30000, /datum/material/plasma = 6000) build_path = /obj/item/ammo_box/c10mm/fire category = list("Ammo") departmental_flags = DEPARTMENTAL_FLAG_SECURITY @@ -112,7 +112,7 @@ desc = "A box of ammo containing 20 rounds designed to tear through unarmored opponents, while being completely ineffective against armor." id = "10apbox" build_type = PROTOLATHE - materials = list(/datum/material/iron = 30000, /datum/material/titanium = 5000) + materials = list(/datum/material/iron = 30000, /datum/material/glass = 6000) build_path = /obj/item/ammo_box/c10mm/hp category = list("Ammo") departmental_flags = DEPARTMENTAL_FLAG_SECURITY From 00f50713eb77c641a6541b7143f0edff10b3674d Mon Sep 17 00:00:00 2001 From: The0bserver Date: Sat, 24 Apr 2021 02:04:21 -0400 Subject: [PATCH 40/75] The fault in my stars --- .../modules/projectiles/boxes_magazines/external/pistol.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modular_citadel/code/modules/projectiles/boxes_magazines/external/pistol.dm b/modular_citadel/code/modules/projectiles/boxes_magazines/external/pistol.dm index eb8da2726e..8737c4593f 100644 --- a/modular_citadel/code/modules/projectiles/boxes_magazines/external/pistol.dm +++ b/modular_citadel/code/modules/projectiles/boxes_magazines/external/pistol.dm @@ -100,7 +100,7 @@ /datum/design/m10firebox name = "ammo box (10mm Incendiary)" desc = "A box of ammo containing 20 rounds designed to set people ablaze, at the cost of raw damage." - id = "10apbox" + id = "10firebox" build_type = PROTOLATHE materials = list(/datum/material/iron = 30000, /datum/material/plasma = 6000) build_path = /obj/item/ammo_box/c10mm/fire @@ -110,7 +110,7 @@ /datum/design/m10hpbox name = "ammo box (10mm Hollowpoint)" desc = "A box of ammo containing 20 rounds designed to tear through unarmored opponents, while being completely ineffective against armor." - id = "10apbox" + id = "10hpbox" build_type = PROTOLATHE materials = list(/datum/material/iron = 30000, /datum/material/glass = 6000) build_path = /obj/item/ammo_box/c10mm/hp From 87eee1e15ea5c25534b4aed43717e4fd975256ce Mon Sep 17 00:00:00 2001 From: The0bserver Date: Sat, 24 Apr 2021 02:22:43 -0400 Subject: [PATCH 41/75] Why do I do this to myself at 2:22 AM --- .../modules/projectiles/boxes_magazines/external/pistol.dm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modular_citadel/code/modules/projectiles/boxes_magazines/external/pistol.dm b/modular_citadel/code/modules/projectiles/boxes_magazines/external/pistol.dm index 8737c4593f..858fe8fd5f 100644 --- a/modular_citadel/code/modules/projectiles/boxes_magazines/external/pistol.dm +++ b/modular_citadel/code/modules/projectiles/boxes_magazines/external/pistol.dm @@ -90,7 +90,7 @@ /datum/design/m10apbox name = "ammo box (10mm Armour Piercing)" desc = "A box of ammo containing 20 rounds designed to penetrate armor, at the cost of raw damage." - id = "10apbox" + id = "m10apbox" build_type = PROTOLATHE materials = list(/datum/material/iron = 30000, /datum/material/titanium = 6000) build_path = /obj/item/ammo_box/c10mm/ap @@ -100,7 +100,7 @@ /datum/design/m10firebox name = "ammo box (10mm Incendiary)" desc = "A box of ammo containing 20 rounds designed to set people ablaze, at the cost of raw damage." - id = "10firebox" + id = "m10firebox" build_type = PROTOLATHE materials = list(/datum/material/iron = 30000, /datum/material/plasma = 6000) build_path = /obj/item/ammo_box/c10mm/fire @@ -110,7 +110,7 @@ /datum/design/m10hpbox name = "ammo box (10mm Hollowpoint)" desc = "A box of ammo containing 20 rounds designed to tear through unarmored opponents, while being completely ineffective against armor." - id = "10hpbox" + id = "m10hpbox" build_type = PROTOLATHE materials = list(/datum/material/iron = 30000, /datum/material/glass = 6000) build_path = /obj/item/ammo_box/c10mm/hp From 80f4f1b4b3094fb1ddd98574d9d5636b9beef18d Mon Sep 17 00:00:00 2001 From: WanderingFox95 <75953558+WanderingFox95@users.noreply.github.com> Date: Sat, 24 Apr 2021 11:36:49 +0200 Subject: [PATCH 42/75] Cleaning up something annoying --- code/modules/mob/living/simple_animal/parrot.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mob/living/simple_animal/parrot.dm b/code/modules/mob/living/simple_animal/parrot.dm index f7e586763b..d146bb855f 100644 --- a/code/modules/mob/living/simple_animal/parrot.dm +++ b/code/modules/mob/living/simple_animal/parrot.dm @@ -64,7 +64,7 @@ friendly_verb_simple = "groom" mob_size = MOB_SIZE_SMALL movement_type = FLYING - gold_core_spawnable = HOSTILE_SPAWN + gold_core_spawnable = FRIENDLY_SPAWN var/parrot_damage_upper = 10 var/parrot_state = PARROT_WANDER //Hunt for a perch when created From 0534f70ccd3f2610d0b9594aecc0a9e380e1b324 Mon Sep 17 00:00:00 2001 From: silicons <2003111+silicons@users.noreply.github.com> Date: Sat, 24 Apr 2021 13:29:53 -0600 Subject: [PATCH 43/75] Update bitfields.dm (#14645) --- code/_globalvars/bitfields.dm | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/code/_globalvars/bitfields.dm b/code/_globalvars/bitfields.dm index d44a4b3898..9c6f16e724 100644 --- a/code/_globalvars/bitfields.dm +++ b/code/_globalvars/bitfields.dm @@ -49,7 +49,12 @@ GLOBAL_LIST_INIT(bitfields, list( "UNIQUE_RENAME" = UNIQUE_RENAME, "USES_TGUI" = USES_TGUI, "FROZEN" = FROZEN, - "SHOVABLE_ONTO" = SHOVABLE_ONTO + "SHOVABLE_ONTO" = SHOVABLE_ONTO, + "BLOCK_Z_OUT_DOWN" = BLOCK_Z_OUT_DOWN, + "BLOCK_Z_OUT_UP" = BLOCK_Z_OUT_UP, + "BLOCK_Z_IN_DOWN" = BLOCK_Z_IN_DOWN, + "BLOCK_Z_IN_UP" = BLOCK_Z_IN_UP, + "EXAMINE_SKIP" = EXAMINE_SKIP ), "datum_flags" = list( "DF_USE_TAG" = DF_USE_TAG, From 7d6cb67c9148a2f40ee4e06b4afd529dd8e74dd0 Mon Sep 17 00:00:00 2001 From: DrPainis <79603707+DrPainis@users.noreply.github.com> Date: Sat, 24 Apr 2021 15:40:41 -0400 Subject: [PATCH 44/75] literally just changes one letter (#14634) --- .../mob/living/simple_animal/hostile/megafauna/bubblegum.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm index 72a72d3683..4d54487244 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm @@ -23,7 +23,7 @@ Difficulty: Hard */ /mob/living/simple_animal/hostile/megafauna/bubblegum - name = "bubblegum" + name = "Bubblegum" desc = "In what passes for a hierarchy among slaughter demons, this one is king." health = 2500 maxHealth = 2500 From 2e5f56152ec9f02e61b2bd37a1f554c322dc1c9e Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Sat, 24 Apr 2021 14:40:43 -0500 Subject: [PATCH 45/75] Automatic changelog generation for PR #14634 [ci skip] --- html/changelogs/AutoChangeLog-pr-14634.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-14634.yml diff --git a/html/changelogs/AutoChangeLog-pr-14634.yml b/html/changelogs/AutoChangeLog-pr-14634.yml new file mode 100644 index 0000000000..508a2515a1 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-14634.yml @@ -0,0 +1,4 @@ +author: "DrPainis" +delete-after: True +changes: + - spellcheck: "Bubblegum is now capitalized." From ace2f522fb75af16e53dab516b16112c46b6a556 Mon Sep 17 00:00:00 2001 From: WanderingFox95 <75953558+WanderingFox95@users.noreply.github.com> Date: Sat, 24 Apr 2021 21:47:04 +0200 Subject: [PATCH 46/75] No more Suicidal Parrots! (Ready) (#14628) * Modifies Parrots They spawn from hostile triggers, not as friendly pets now. * Removes Parrots from Gold Extracts altogether --- code/modules/mob/living/simple_animal/parrot.dm | 1 - 1 file changed, 1 deletion(-) diff --git a/code/modules/mob/living/simple_animal/parrot.dm b/code/modules/mob/living/simple_animal/parrot.dm index d146bb855f..bd45c482a2 100644 --- a/code/modules/mob/living/simple_animal/parrot.dm +++ b/code/modules/mob/living/simple_animal/parrot.dm @@ -64,7 +64,6 @@ friendly_verb_simple = "groom" mob_size = MOB_SIZE_SMALL movement_type = FLYING - gold_core_spawnable = FRIENDLY_SPAWN var/parrot_damage_upper = 10 var/parrot_state = PARROT_WANDER //Hunt for a perch when created From d07f1f3d30bbc40893ad2fcb8696231fe8802f64 Mon Sep 17 00:00:00 2001 From: silicons <2003111+silicons@users.noreply.github.com> Date: Sat, 24 Apr 2021 13:51:53 -0600 Subject: [PATCH 47/75] Update radioactive.dm (#14615) --- code/datums/components/radioactive.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/datums/components/radioactive.dm b/code/datums/components/radioactive.dm index 8afa4353b2..4c418bb8dc 100644 --- a/code/datums/components/radioactive.dm +++ b/code/datums/components/radioactive.dm @@ -52,7 +52,7 @@ return strength -= strength / hl3_release_date if(strength <= RAD_BACKGROUND_RADIATION) - return PROCESS_KILL + qdel(src) /datum/component/radioactive/proc/glow_loop(atom/movable/master) From 7cc8e5ea33ef967766d02d8c2a00415c04449609 Mon Sep 17 00:00:00 2001 From: Changelogs Date: Sun, 25 Apr 2021 00:06:57 +0000 Subject: [PATCH 48/75] Automatic changelog compile [ci skip] --- html/changelog.html | 25 ++++++---------------- html/changelogs/.all_changelog.yml | 3 +++ html/changelogs/AutoChangeLog-pr-14634.yml | 4 ---- 3 files changed, 9 insertions(+), 23 deletions(-) delete mode 100644 html/changelogs/AutoChangeLog-pr-14634.yml diff --git a/html/changelog.html b/html/changelog.html index 241394e803..3b965b74e8 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -50,6 +50,12 @@ -->
    +

    25 April 2021

    +

    DrPainis updated:

    +
      +
    • Bubblegum is now capitalized.
    • +
    +

    22 April 2021

    Whoneedspacee updated:

      @@ -838,25 +844,6 @@
    • Added pain emote to getting wounded
    • added a new pain emote sounds
    - -

    21 February 2021

    -

    Hatterhat updated:

    -
      -
    • Anomaly announcements and brand intelligence now always announce instead of having some ham-fisted chance of being a command report.
    • -
    -

    IronEleven updated:

    -
      -
    • Raises Space Vine Population Requirement from 10 to 20
    • -
    -

    MrJWhit updated:

    -
      -
    • Removes an unnecessary % on the seed extractor.
    • -
    -

    timothyteakettle updated:

    -
      -
    • the query for checking mentors now gets properly deleted
    • -
    • vampires no longer burn in the chapel if they signed up as the chaplain
    • -
    GoonStation 13 Development Team diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml index 21084be59e..ddc88f8afc 100644 --- a/html/changelogs/.all_changelog.yml +++ b/html/changelogs/.all_changelog.yml @@ -29164,3 +29164,6 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py. - balance: triple fire breath for the lava swoop only happens below half health now - bugfix: The arena attack not making safespots when you fight it in a mech +2021-04-25: + DrPainis: + - spellcheck: Bubblegum is now capitalized. diff --git a/html/changelogs/AutoChangeLog-pr-14634.yml b/html/changelogs/AutoChangeLog-pr-14634.yml deleted file mode 100644 index 508a2515a1..0000000000 --- a/html/changelogs/AutoChangeLog-pr-14634.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "DrPainis" -delete-after: True -changes: - - spellcheck: "Bubblegum is now capitalized." From 90661d36879ab877fd8ce5eb7da04501a4185b80 Mon Sep 17 00:00:00 2001 From: SandPoot Date: Sat, 24 Apr 2021 21:37:01 -0300 Subject: [PATCH 49/75] upload files --- code/__HELPERS/icons.dm | 4 ++-- code/modules/admin/verbs/selectequipment.dm | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/code/__HELPERS/icons.dm b/code/__HELPERS/icons.dm index ce6bbf48c3..c9b011d0e4 100644 --- a/code/__HELPERS/icons.dm +++ b/code/__HELPERS/icons.dm @@ -1051,7 +1051,7 @@ GLOBAL_LIST_EMPTY(friendly_animal_types) return 0 //For creating consistent icons for human looking simple animals -/proc/get_flat_human_icon(icon_id, datum/job/J, datum/preferences/prefs, dummy_key, showDirs = GLOB.cardinals, outfit_override = null) +/proc/get_flat_human_icon(icon_id, datum/job/J, datum/preferences/prefs, dummy_key, showDirs = GLOB.cardinals, outfit_override = null, no_anim = FALSE) var/static/list/humanoid_icon_cache = list() if(!icon_id || !humanoid_icon_cache[icon_id]) var/mob/living/carbon/human/dummy/body = generate_or_wait_for_human_dummy(dummy_key) @@ -1067,7 +1067,7 @@ GLOBAL_LIST_EMPTY(friendly_animal_types) var/icon/out_icon = icon('icons/effects/effects.dmi', "nothing") COMPILE_OVERLAYS(body) for(var/D in showDirs) - var/icon/partial = getFlatIcon(body, defdir=D) + var/icon/partial = getFlatIcon(body, defdir=D, no_anim) out_icon.Insert(partial,dir=D) humanoid_icon_cache[icon_id] = out_icon diff --git a/code/modules/admin/verbs/selectequipment.dm b/code/modules/admin/verbs/selectequipment.dm index 4184fed68f..eb75df9ac1 100644 --- a/code/modules/admin/verbs/selectequipment.dm +++ b/code/modules/admin/verbs/selectequipment.dm @@ -111,7 +111,8 @@ var/icon/dummysprite = get_flat_human_icon(null, dummy_key = dummy_key, - outfit_override = selected_outfit) + outfit_override = selected_outfit, + no_anim = TRUE) data["icon64"] = icon2base64(dummysprite) data["name"] = target_mob From c2b7140ddd67147a6bcd088c46d35d1135e87112 Mon Sep 17 00:00:00 2001 From: SandPoot Date: Sat, 24 Apr 2021 21:43:12 -0300 Subject: [PATCH 50/75] upload icons.dm --- code/__HELPERS/icons.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/__HELPERS/icons.dm b/code/__HELPERS/icons.dm index c9b011d0e4..fabe70c929 100644 --- a/code/__HELPERS/icons.dm +++ b/code/__HELPERS/icons.dm @@ -1067,7 +1067,7 @@ GLOBAL_LIST_EMPTY(friendly_animal_types) var/icon/out_icon = icon('icons/effects/effects.dmi', "nothing") COMPILE_OVERLAYS(body) for(var/D in showDirs) - var/icon/partial = getFlatIcon(body, defdir=D, no_anim) + var/icon/partial = getFlatIcon(body, defdir = D, no_anim = no_anim) out_icon.Insert(partial,dir=D) humanoid_icon_cache[icon_id] = out_icon From cf69e0fb69921d43ea08843f0874e10345dae9dc Mon Sep 17 00:00:00 2001 From: silicons <2003111+silicons@users.noreply.github.com> Date: Sun, 25 Apr 2021 04:55:46 -0600 Subject: [PATCH 51/75] Rename emergency_airless.dmm to emergency_construction.dmm (#14656) --- .../{emergency_airless.dmm => emergency_construction.dmm} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename _maps/shuttles/{emergency_airless.dmm => emergency_construction.dmm} (100%) diff --git a/_maps/shuttles/emergency_airless.dmm b/_maps/shuttles/emergency_construction.dmm similarity index 100% rename from _maps/shuttles/emergency_airless.dmm rename to _maps/shuttles/emergency_construction.dmm From e313fed033a49357687bfa7c43136f470c18c31b Mon Sep 17 00:00:00 2001 From: DrPainis <79603707+DrPainis@users.noreply.github.com> Date: Sun, 25 Apr 2021 19:04:07 -0400 Subject: [PATCH 52/75] hallucinations are capitalized too --- .../mob/living/simple_animal/hostile/megafauna/bubblegum.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm index 4d54487244..b1441ce55f 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm @@ -443,7 +443,7 @@ Difficulty: Hard charge(chargeat, delay, chargepast) /mob/living/simple_animal/hostile/megafauna/bubblegum/hallucination - name = "bubblegum's hallucination" + name = "Bubblegum's hallucination" desc = "Is that really just a hallucination?" health = 1 maxHealth = 1 From 44c2a9eecdc5b062a5a8de1161f820f8a2f096f1 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Sun, 25 Apr 2021 18:10:11 -0500 Subject: [PATCH 53/75] Automatic changelog generation for PR #14642 [ci skip] --- html/changelogs/AutoChangeLog-pr-14642.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-14642.yml diff --git a/html/changelogs/AutoChangeLog-pr-14642.yml b/html/changelogs/AutoChangeLog-pr-14642.yml new file mode 100644 index 0000000000..675d5418d5 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-14642.yml @@ -0,0 +1,5 @@ +author: "Trigg, stylemistake and SandPoot" +delete-after: True +changes: + - admin: "Admins just got a new TGUI Select Equipment menu +tweak: Prevents the window from creating sprites for any animated version there might be. (this guarantees consistant sprite size/amount)" From 3fac51374f709b2e6558f624495c0f61bbff2594 Mon Sep 17 00:00:00 2001 From: Changelogs Date: Mon, 26 Apr 2021 00:06:42 +0000 Subject: [PATCH 54/75] Automatic changelog compile [ci skip] --- html/changelog.html | 38 ++++------------------ html/changelogs/.all_changelog.yml | 5 +++ html/changelogs/AutoChangeLog-pr-14642.yml | 5 --- 3 files changed, 11 insertions(+), 37 deletions(-) delete mode 100644 html/changelogs/AutoChangeLog-pr-14642.yml diff --git a/html/changelog.html b/html/changelog.html index 3b965b74e8..13ef3c5443 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -50,6 +50,12 @@ -->
    +

    26 April 2021

    +

    Trigg, stylemistake and SandPoot updated:

    +
      +
    • Admins just got a new TGUI Select Equipment menu tweak: Prevents the window from creating sprites for any animated version there might be. (this guarantees consistant sprite size/amount)
    • +
    +

    25 April 2021

    DrPainis updated:

      @@ -812,38 +818,6 @@
      • banning panel prioritises mobs with clients now when trying to find them if they're in the game
      - -

      22 February 2021

      -

      Putnam3145 updated:

      -
        -
      • (Hexa)crocin
      • -
      • (Hexa)camphor
      • -
      • Nymphomaniac quirk
      • -
      • All climaxes and arousals are now logged, as well as genital exposure.
      • -
      -

      SandPoot updated:

      -
        -
      • Cyborg tablets and it's special app for self-management.
      • -
      • In the case of a doomsday device being created outside of an AI it will delete itself.
      • -
      • Some sprites for it have been added and the borg's hud light toggles been changed to only on-off (made by yours truly)
      • -
      • A lot of borg code was changed
      • -
      • Tools no longer use istype checks and actually check for their behavior.
      • -
      -

      Vynzill updated:

      -
        -
      • cursed rice hat that's hard to find and obtain, along with a couple other hats
      • -
      • a replacement toy gun for donksoft lmg
      • -
      • gorillas to the jungle gateway, friendly, even when attacked.
      • -
      • couple mapping errors I noticed, most importantly a missing window in the chapel.
      • -
      • shotgun and donksoft lmg removed, captain coat nerfed armor values.
      • -
      • leaper healthpool from 450 to 550 hopefully making it more of a struggle, and gives it a name.
      • -
      • leaper pit is more wider. The hidden room south is now more obvious to find
      • -
      -

      dzahlus updated:

      -
        -
      • Added pain emote to getting wounded
      • -
      • added a new pain emote sounds
      • -
    GoonStation 13 Development Team diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml index ddc88f8afc..d1d5cc31d6 100644 --- a/html/changelogs/.all_changelog.yml +++ b/html/changelogs/.all_changelog.yml @@ -29167,3 +29167,8 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py. 2021-04-25: DrPainis: - spellcheck: Bubblegum is now capitalized. +2021-04-26: + Trigg, stylemistake and SandPoot: + - admin: 'Admins just got a new TGUI Select Equipment menu tweak: Prevents the window + from creating sprites for any animated version there might be. (this guarantees + consistant sprite size/amount)' diff --git a/html/changelogs/AutoChangeLog-pr-14642.yml b/html/changelogs/AutoChangeLog-pr-14642.yml deleted file mode 100644 index 675d5418d5..0000000000 --- a/html/changelogs/AutoChangeLog-pr-14642.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "Trigg, stylemistake and SandPoot" -delete-after: True -changes: - - admin: "Admins just got a new TGUI Select Equipment menu -tweak: Prevents the window from creating sprites for any animated version there might be. (this guarantees consistant sprite size/amount)" From 03fa382f368a20e874f35ee537e23e88766975a9 Mon Sep 17 00:00:00 2001 From: silicons <2003111+silicons@users.noreply.github.com> Date: Mon, 26 Apr 2021 13:57:34 -0700 Subject: [PATCH 55/75] Update autobunker.dm --- code/modules/client/verbs/autobunker.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/client/verbs/autobunker.dm b/code/modules/client/verbs/autobunker.dm index 620854b9ed..367f1944cc 100644 --- a/code/modules/client/verbs/autobunker.dm +++ b/code/modules/client/verbs/autobunker.dm @@ -3,7 +3,7 @@ set desc = "Authorizes your account in the panic bunker of any servers connected to this function." set category = "OOC" - if(!(prefs.db_flags & DB_FLAG_AGE_CONFIRMATION_INCOMPLETE)) + if(prefs.db_flags & DB_FLAG_AGE_CONFIRMATION_INCOMPLETE) to_chat(src, "You are not age verified.") return From 810eba15ed9d9c06b7ca9b8eb459a24a7316fcbf Mon Sep 17 00:00:00 2001 From: Changelogs Date: Tue, 27 Apr 2021 00:06:17 +0000 Subject: [PATCH 56/75] Automatic changelog compile [ci skip] --- html/changelog.html | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/html/changelog.html b/html/changelog.html index 13ef3c5443..44ed1c8e5d 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -807,17 +807,6 @@
    • xeno cube makes hostile xenos now, and drops a sentinel instead of a drone.
    - -

    23 February 2021

    -

    keronshb updated:

    -
      -
    • Hyperblade to uplink with poplock
    • -
    • Removes combination of two Dragon Tooth Swords while keeping it for regular eutactics.
    • -
    -

    timothyteakettle updated:

    -
      -
    • banning panel prioritises mobs with clients now when trying to find them if they're in the game
    • -
    GoonStation 13 Development Team From 604d5e2fbceb0abefe424c71ea06efa9cd7b05cf Mon Sep 17 00:00:00 2001 From: Changelogs Date: Wed, 28 Apr 2021 00:06:38 +0000 Subject: [PATCH 57/75] Automatic changelog compile [ci skip] --- html/changelog.html | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/html/changelog.html b/html/changelog.html index 44ed1c8e5d..fa46c13a87 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -797,16 +797,6 @@
    • Traitor / Ling objective amount should now be correct again.
    - -

    24 February 2021

    -

    SandPoot updated:

    -
      -
    • Regular crowbars no longer open powered airlocks.
    • -
    -

    silicons updated:

    -
      -
    • xeno cube makes hostile xenos now, and drops a sentinel instead of a drone.
    • -
    GoonStation 13 Development Team From 6d86809616cedb3c563ea7d087256df35556e39a Mon Sep 17 00:00:00 2001 From: keronshb <54602815+keronshb@users.noreply.github.com> Date: Wed, 28 Apr 2021 08:09:37 -0400 Subject: [PATCH 58/75] Removes the Reinforcement Chromosome from Genetics. (#14641) * Removes Mutadone Proof from Genetics This might be a bit too good. * Fixes so mutadone actually works Oops * Removes the reinforcement chromosome Removes the reinforcement chromosome --- code/game/objects/items/chromosome.dm | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/code/game/objects/items/chromosome.dm b/code/game/objects/items/chromosome.dm index 3acf3cfe5c..f5b693879b 100644 --- a/code/game/objects/items/chromosome.dm +++ b/code/game/objects/items/chromosome.dm @@ -75,18 +75,3 @@ desc = "A chromosome that reduces action based mutation cooldowns by by 50%." icon_state = "energy" energy_coeff = 0.5 - -/obj/item/chromosome/reinforcer - name = "reinforcement chromosome" - desc = "A chromosome that renders mutations immune to mutadone." - icon_state = "reinforcer" - weight = 3 - -/obj/item/chromosome/reinforcer/can_apply(datum/mutation/human/HM) - if(!HM || !(HM.can_chromosome == CHROMOSOME_NONE)) - return FALSE - return !HM.mutadone_proof - -/obj/item/chromosome/reinforcer/apply(datum/mutation/human/HM) - HM.mutadone_proof = TRUE - ..() From b19a2cd9753a7d3912eb1d16c5d0b292b87477d3 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Wed, 28 Apr 2021 07:09:39 -0500 Subject: [PATCH 59/75] Automatic changelog generation for PR #14641 [ci skip] --- html/changelogs/AutoChangeLog-pr-14641.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-14641.yml diff --git a/html/changelogs/AutoChangeLog-pr-14641.yml b/html/changelogs/AutoChangeLog-pr-14641.yml new file mode 100644 index 0000000000..0e4b0ebbb2 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-14641.yml @@ -0,0 +1,4 @@ +author: "keronshb" +delete-after: True +changes: + - balance: "Removes the Reinforcement Chromosome from Genetics." From 3afb80103664a46abb3b5aff537f9ff3dba62096 Mon Sep 17 00:00:00 2001 From: qweq12yt <45515587+qweq12yt@users.noreply.github.com> Date: Wed, 28 Apr 2021 15:41:20 -0300 Subject: [PATCH 60/75] huh --- code/modules/clothing/suits/armor.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/clothing/suits/armor.dm b/code/modules/clothing/suits/armor.dm index 6732f1c86c..254ed60c03 100644 --- a/code/modules/clothing/suits/armor.dm +++ b/code/modules/clothing/suits/armor.dm @@ -145,7 +145,7 @@ /obj/item/clothing/suit/armor/riot name = "riot suit" desc = "A suit of semi-flexible polycarbonate body armor with heavy padding to protect against melee attacks. Helps the wearer resist shoving in close quarters." - icon_state = "riot" + icon_state = "swat" item_state = "swat_suit" body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS cold_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS From 8f14424a63020aeba8ca216134e2bc5b7a5da9d5 Mon Sep 17 00:00:00 2001 From: Putnam3145 Date: Wed, 28 Apr 2021 13:56:15 -0700 Subject: [PATCH 61/75] Fixes a couple runtimes in activity tracking (#14666) --- code/controllers/subsystem/activity.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/controllers/subsystem/activity.dm b/code/controllers/subsystem/activity.dm index 24cd1802f0..0a8d248e58 100644 --- a/code/controllers/subsystem/activity.dm +++ b/code/controllers/subsystem/activity.dm @@ -61,14 +61,14 @@ SUBSYSTEM_DEF(activity) for(var/threat in threat_history) . = max(threat_history[threat], .) -/datum/controller/subsystem/activity/proc/on_explosion(atom/epicenter, devastation_range, heavy_impact_range, light_impact_range, took, orig_dev_range, orig_heavy_range, orig_light_range) +/datum/controller/subsystem/activity/proc/on_explosion(datum/source, atom/epicenter, devastation_range, heavy_impact_range, light_impact_range, took, orig_dev_range, orig_heavy_range, orig_light_range) if(!("explosions" in deferred_threats)) deferred_threats["explosions"] = 0 var/area/A = get_area(epicenter) if(is_station_level(epicenter.z) && (A.area_flags & BLOBS_ALLOWED) && !istype(A, /area/asteroid)) deferred_threats["explosions"] += devastation_range**2 + heavy_impact_range**2 / 4 + light_impact_range**2 / 8 // 75 for a maxcap -/datum/controller/subsystem/activity/proc/on_death(mob/M, gibbed) +/datum/controller/subsystem/activity/proc/on_death(datum/source, mob/M, gibbed) if(!("crew_deaths" in deferred_threats)) deferred_threats["crew_deaths"] = 0 if(M?.mind && SSjob.GetJob(M.mind.assigned_role)) From 85ec8aa5a08cf7500205a5e42120acbc35539177 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Wed, 28 Apr 2021 15:56:18 -0500 Subject: [PATCH 62/75] Automatic changelog generation for PR #14666 [ci skip] --- html/changelogs/AutoChangeLog-pr-14666.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-14666.yml diff --git a/html/changelogs/AutoChangeLog-pr-14666.yml b/html/changelogs/AutoChangeLog-pr-14666.yml new file mode 100644 index 0000000000..40591d9026 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-14666.yml @@ -0,0 +1,4 @@ +author: "Putnam3145" +delete-after: True +changes: + - bugfix: "Fixed a couple runtimes in activity (threat) tracking" From a331f2412102e865723b2dae34a813f15202adf7 Mon Sep 17 00:00:00 2001 From: Changelogs Date: Thu, 29 Apr 2021 00:06:31 +0000 Subject: [PATCH 63/75] Automatic changelog compile [ci skip] --- html/changelog.html | 16 ++++++++++------ html/changelogs/.all_changelog.yml | 5 +++++ html/changelogs/AutoChangeLog-pr-14641.yml | 4 ---- html/changelogs/AutoChangeLog-pr-14666.yml | 4 ---- 4 files changed, 15 insertions(+), 14 deletions(-) delete mode 100644 html/changelogs/AutoChangeLog-pr-14641.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-14666.yml diff --git a/html/changelog.html b/html/changelog.html index fa46c13a87..2c4f8c0144 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -50,6 +50,16 @@ -->
    +

    29 April 2021

    +

    Putnam3145 updated:

    +
      +
    • Fixed a couple runtimes in activity (threat) tracking
    • +
    +

    keronshb updated:

    +
      +
    • Removes the Reinforcement Chromosome from Genetics.
    • +
    +

    26 April 2021

    Trigg, stylemistake and SandPoot updated:

      @@ -791,12 +801,6 @@
      • All machine-frame based tool-use actions now have state-checking callbacks.
      - -

      25 February 2021

      -

      DeltaFire15 updated:

      -
        -
      • Traitor / Ling objective amount should now be correct again.
      • -
    GoonStation 13 Development Team diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml index d1d5cc31d6..3f58b0ce2b 100644 --- a/html/changelogs/.all_changelog.yml +++ b/html/changelogs/.all_changelog.yml @@ -29172,3 +29172,8 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py. - admin: 'Admins just got a new TGUI Select Equipment menu tweak: Prevents the window from creating sprites for any animated version there might be. (this guarantees consistant sprite size/amount)' +2021-04-29: + Putnam3145: + - bugfix: Fixed a couple runtimes in activity (threat) tracking + keronshb: + - balance: Removes the Reinforcement Chromosome from Genetics. diff --git a/html/changelogs/AutoChangeLog-pr-14641.yml b/html/changelogs/AutoChangeLog-pr-14641.yml deleted file mode 100644 index 0e4b0ebbb2..0000000000 --- a/html/changelogs/AutoChangeLog-pr-14641.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "keronshb" -delete-after: True -changes: - - balance: "Removes the Reinforcement Chromosome from Genetics." diff --git a/html/changelogs/AutoChangeLog-pr-14666.yml b/html/changelogs/AutoChangeLog-pr-14666.yml deleted file mode 100644 index 40591d9026..0000000000 --- a/html/changelogs/AutoChangeLog-pr-14666.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Putnam3145" -delete-after: True -changes: - - bugfix: "Fixed a couple runtimes in activity (threat) tracking" From 82d166017ce47157a8b493cd86913f87aff759a8 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Wed, 28 Apr 2021 22:16:53 -0500 Subject: [PATCH 64/75] Automatic changelog generation for PR #14643 [ci skip] --- html/changelogs/AutoChangeLog-pr-14643.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-14643.yml diff --git a/html/changelogs/AutoChangeLog-pr-14643.yml b/html/changelogs/AutoChangeLog-pr-14643.yml new file mode 100644 index 0000000000..d344957d55 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-14643.yml @@ -0,0 +1,4 @@ +author: "akada" +delete-after: True +changes: + - imageadd: "Changes the space adaptation sprite to something less intrusive and more subtle." From 152c88fe46b2de523ce970e1df3841cfdd5a4832 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Wed, 28 Apr 2021 22:17:00 -0500 Subject: [PATCH 65/75] Automatic changelog generation for PR #14636 [ci skip] --- html/changelogs/AutoChangeLog-pr-14636.yml | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-14636.yml diff --git a/html/changelogs/AutoChangeLog-pr-14636.yml b/html/changelogs/AutoChangeLog-pr-14636.yml new file mode 100644 index 0000000000..fe17a4aa17 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-14636.yml @@ -0,0 +1,6 @@ +author: "TheObserver-sys" +delete-after: True +changes: + - bugfix: "Restores the access lock on crates that should have them, given the goods inside." + - bugfix: "Makes the 10MM Surplus Rifle a less awful thing to use." + - bugfix: "replaces unarmored things with their armored versions." From 86ad5fd32de65b1391049159ab192205e199e72f Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Wed, 28 Apr 2021 22:17:08 -0500 Subject: [PATCH 66/75] Automatic changelog generation for PR #14635 [ci skip] --- html/changelogs/AutoChangeLog-pr-14635.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-14635.yml diff --git a/html/changelogs/AutoChangeLog-pr-14635.yml b/html/changelogs/AutoChangeLog-pr-14635.yml new file mode 100644 index 0000000000..cbb91a249c --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-14635.yml @@ -0,0 +1,4 @@ +author: "necromanceranne" +delete-after: True +changes: + - rscadd: "Fake blindfolds in the loadout. They don't obscure vision, for better or worse." From fc2bf6c24dab56960a6b46a7e4ef01752a3244df Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Wed, 28 Apr 2021 22:17:17 -0500 Subject: [PATCH 67/75] Automatic changelog generation for PR #14659 [ci skip] --- html/changelogs/AutoChangeLog-pr-14659.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-14659.yml diff --git a/html/changelogs/AutoChangeLog-pr-14659.yml b/html/changelogs/AutoChangeLog-pr-14659.yml new file mode 100644 index 0000000000..c836c3de3e --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-14659.yml @@ -0,0 +1,4 @@ +author: "DrPainis" +delete-after: True +changes: + - spellcheck: "Bubblegum's hallucinations are capitalized." From 914a5c793053b8010553f7aae8324463b45b9eaa Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Wed, 28 Apr 2021 22:17:38 -0500 Subject: [PATCH 68/75] Automatic changelog generation for PR #14651 [ci skip] --- html/changelogs/AutoChangeLog-pr-14651.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-14651.yml diff --git a/html/changelogs/AutoChangeLog-pr-14651.yml b/html/changelogs/AutoChangeLog-pr-14651.yml new file mode 100644 index 0000000000..27ed8f303e --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-14651.yml @@ -0,0 +1,4 @@ +author: "WanderingFox95" +delete-after: True +changes: + - balance: "There's finally a reason for the reagent dart gun to exist and be used!" From 74a5e0d051f4ca6c82bebbec4fa6ad35276560d1 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Wed, 28 Apr 2021 22:17:58 -0500 Subject: [PATCH 69/75] Automatic changelog generation for PR #14649 [ci skip] --- html/changelogs/AutoChangeLog-pr-14649.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-14649.yml diff --git a/html/changelogs/AutoChangeLog-pr-14649.yml b/html/changelogs/AutoChangeLog-pr-14649.yml new file mode 100644 index 0000000000..c54af36a4c --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-14649.yml @@ -0,0 +1,5 @@ +author: "TheObserver-sys" +delete-after: True +changes: + - balance: "Illegal Tech Ammo actually is fucking reasonable, now." + - balance: "Expensive Illegal Tech Ammo Boxes are now constructible, with actually justifiable prices." From b69b2bc72c769cfb7cd415b4582052639b9460b5 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Wed, 28 Apr 2021 22:20:04 -0500 Subject: [PATCH 70/75] Automatic changelog generation for PR #14647 [ci skip] --- html/changelogs/AutoChangeLog-pr-14647.yml | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-14647.yml diff --git a/html/changelogs/AutoChangeLog-pr-14647.yml b/html/changelogs/AutoChangeLog-pr-14647.yml new file mode 100644 index 0000000000..a59e47811d --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-14647.yml @@ -0,0 +1,8 @@ +author: "Melbert, SandPoot" +delete-after: True +changes: + - refactor: "TGUI Limbgrower" + - refactor: "Refactored the limbgrower to modernize the code and allow for more types of designs." + - rscadd: "The limbgrower now supports plumbing ducts." + - bugfix: "Fixes genitals not actually getting data from disks." + - code_imp: "Adds two special helpers." From 29aee4005c3f25772519a5136b795007a175c8e2 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Wed, 28 Apr 2021 22:20:26 -0500 Subject: [PATCH 71/75] Automatic changelog generation for PR #14648 [ci skip] --- html/changelogs/AutoChangeLog-pr-14648.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-14648.yml diff --git a/html/changelogs/AutoChangeLog-pr-14648.yml b/html/changelogs/AutoChangeLog-pr-14648.yml new file mode 100644 index 0000000000..e2320ec5fe --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-14648.yml @@ -0,0 +1,5 @@ +author: "SandPoot" +delete-after: True +changes: + - rscadd: "The decal painter now has visible previews for your tile painting funs." + - bugfix: "Fixes decal painter painting in the opposite direction." From 0c803e02329b741cb65d38fd845e1854bf6b061c Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Wed, 28 Apr 2021 22:20:59 -0500 Subject: [PATCH 72/75] Automatic changelog generation for PR #14639 [ci skip] --- html/changelogs/AutoChangeLog-pr-14639.yml | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-14639.yml diff --git a/html/changelogs/AutoChangeLog-pr-14639.yml b/html/changelogs/AutoChangeLog-pr-14639.yml new file mode 100644 index 0000000000..ada372a811 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-14639.yml @@ -0,0 +1,7 @@ +author: "necromanceranne" +delete-after: True +changes: + - rscadd: "Basic cybernetic organs: they're worse than organic! Basic stomachs, hearts, lungs and livers! For when you hate someone enough to not bother harvesting organs from a monkeyhuman!" + - rscadd: "Cybernetic organs have been adjusted into three tiers: 1 (basic), 2 (standard, better than organic) and 3 (absolutely better than organic but expensive to print)" + - rscadd: "Cybernetic organs that are emp'd instead suffer different effects based on the severity of the emp. The bigger the emp, the worse the effect is." + - rscadd: "Rather than outright bricking, severely emp'd cyberorgans degrade over time very quickly, requiring replacement in the near future." From 2cb353890eac45e9790cf41fb2de40ed94bc2719 Mon Sep 17 00:00:00 2001 From: Changelogs Date: Fri, 30 Apr 2021 00:25:57 +0000 Subject: [PATCH 73/75] Automatic changelog compile [ci skip] --- html/changelog.html | 49 +++++++++++++++++++--- html/changelogs/.all_changelog.yml | 39 +++++++++++++++++ html/changelogs/AutoChangeLog-pr-14635.yml | 4 -- html/changelogs/AutoChangeLog-pr-14636.yml | 6 --- html/changelogs/AutoChangeLog-pr-14639.yml | 7 ---- html/changelogs/AutoChangeLog-pr-14643.yml | 4 -- html/changelogs/AutoChangeLog-pr-14647.yml | 8 ---- html/changelogs/AutoChangeLog-pr-14648.yml | 5 --- html/changelogs/AutoChangeLog-pr-14649.yml | 5 --- html/changelogs/AutoChangeLog-pr-14651.yml | 4 -- html/changelogs/AutoChangeLog-pr-14659.yml | 4 -- 11 files changed, 82 insertions(+), 53 deletions(-) delete mode 100644 html/changelogs/AutoChangeLog-pr-14635.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-14636.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-14639.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-14643.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-14647.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-14648.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-14649.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-14651.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-14659.yml diff --git a/html/changelog.html b/html/changelog.html index 2c4f8c0144..9b0cdd68bb 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -50,6 +50,49 @@ -->
    +

    30 April 2021

    +

    DrPainis updated:

    +
      +
    • Bubblegum's hallucinations are capitalized.
    • +
    +

    Melbert, SandPoot updated:

    +
      +
    • TGUI Limbgrower
    • +
    • Refactored the limbgrower to modernize the code and allow for more types of designs.
    • +
    • The limbgrower now supports plumbing ducts.
    • +
    • Fixes genitals not actually getting data from disks.
    • +
    • Adds two special helpers.
    • +
    +

    SandPoot updated:

    +
      +
    • The decal painter now has visible previews for your tile painting funs.
    • +
    • Fixes decal painter painting in the opposite direction.
    • +
    +

    TheObserver-sys updated:

    +
      +
    • Restores the access lock on crates that should have them, given the goods inside.
    • +
    • Makes the 10MM Surplus Rifle a less awful thing to use.
    • +
    • replaces unarmored things with their armored versions.
    • +
    • Illegal Tech Ammo actually is fucking reasonable, now.
    • +
    • Expensive Illegal Tech Ammo Boxes are now constructible, with actually justifiable prices.
    • +
    +

    WanderingFox95 updated:

    +
      +
    • There's finally a reason for the reagent dart gun to exist and be used!
    • +
    +

    akada updated:

    +
      +
    • Changes the space adaptation sprite to something less intrusive and more subtle.
    • +
    +

    necromanceranne updated:

    +
      +
    • Basic cybernetic organs: they're worse than organic! Basic stomachs, hearts, lungs and livers! For when you hate someone enough to not bother harvesting organs from a monkeyhuman!
    • +
    • Cybernetic organs have been adjusted into three tiers: 1 (basic), 2 (standard, better than organic) and 3 (absolutely better than organic but expensive to print)
    • +
    • Cybernetic organs that are emp'd instead suffer different effects based on the severity of the emp. The bigger the emp, the worse the effect is.
    • +
    • Rather than outright bricking, severely emp'd cyberorgans degrade over time very quickly, requiring replacement in the near future.
    • +
    • Fake blindfolds in the loadout. They don't obscure vision, for better or worse.
    • +
    +

    29 April 2021

    Putnam3145 updated:

      @@ -795,12 +838,6 @@
      • chaplain arrythmic knives can no longer be abused for infinite speed.
      - -

      26 February 2021

      -

      DeltaFire15 updated:

      -
        -
      • All machine-frame based tool-use actions now have state-checking callbacks.
      • -
    GoonStation 13 Development Team diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml index 3f58b0ce2b..0698eeaddc 100644 --- a/html/changelogs/.all_changelog.yml +++ b/html/changelogs/.all_changelog.yml @@ -29177,3 +29177,42 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py. - bugfix: Fixed a couple runtimes in activity (threat) tracking keronshb: - balance: Removes the Reinforcement Chromosome from Genetics. +2021-04-30: + DrPainis: + - spellcheck: Bubblegum's hallucinations are capitalized. + Melbert, SandPoot: + - refactor: TGUI Limbgrower + - refactor: Refactored the limbgrower to modernize the code and allow for more types + of designs. + - rscadd: The limbgrower now supports plumbing ducts. + - bugfix: Fixes genitals not actually getting data from disks. + - code_imp: Adds two special helpers. + SandPoot: + - rscadd: The decal painter now has visible previews for your tile painting funs. + - bugfix: Fixes decal painter painting in the opposite direction. + TheObserver-sys: + - bugfix: Restores the access lock on crates that should have them, given the goods + inside. + - bugfix: Makes the 10MM Surplus Rifle a less awful thing to use. + - bugfix: replaces unarmored things with their armored versions. + - balance: Illegal Tech Ammo actually is fucking reasonable, now. + - balance: Expensive Illegal Tech Ammo Boxes are now constructible, with actually + justifiable prices. + WanderingFox95: + - balance: There's finally a reason for the reagent dart gun to exist and be used! + akada: + - imageadd: Changes the space adaptation sprite to something less intrusive and + more subtle. + necromanceranne: + - rscadd: 'Basic cybernetic organs: they''re worse than organic! Basic stomachs, + hearts, lungs and livers! For when you hate someone enough to not bother harvesting + organs from a monkeyhuman!' + - rscadd: 'Cybernetic organs have been adjusted into three tiers: 1 (basic), 2 (standard, + better than organic) and 3 (absolutely better than organic but expensive to + print)' + - rscadd: Cybernetic organs that are emp'd instead suffer different effects based + on the severity of the emp. The bigger the emp, the worse the effect is. + - rscadd: Rather than outright bricking, severely emp'd cyberorgans degrade over + time very quickly, requiring replacement in the near future. + - rscadd: Fake blindfolds in the loadout. They don't obscure vision, for better + or worse. diff --git a/html/changelogs/AutoChangeLog-pr-14635.yml b/html/changelogs/AutoChangeLog-pr-14635.yml deleted file mode 100644 index cbb91a249c..0000000000 --- a/html/changelogs/AutoChangeLog-pr-14635.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "necromanceranne" -delete-after: True -changes: - - rscadd: "Fake blindfolds in the loadout. They don't obscure vision, for better or worse." diff --git a/html/changelogs/AutoChangeLog-pr-14636.yml b/html/changelogs/AutoChangeLog-pr-14636.yml deleted file mode 100644 index fe17a4aa17..0000000000 --- a/html/changelogs/AutoChangeLog-pr-14636.yml +++ /dev/null @@ -1,6 +0,0 @@ -author: "TheObserver-sys" -delete-after: True -changes: - - bugfix: "Restores the access lock on crates that should have them, given the goods inside." - - bugfix: "Makes the 10MM Surplus Rifle a less awful thing to use." - - bugfix: "replaces unarmored things with their armored versions." diff --git a/html/changelogs/AutoChangeLog-pr-14639.yml b/html/changelogs/AutoChangeLog-pr-14639.yml deleted file mode 100644 index ada372a811..0000000000 --- a/html/changelogs/AutoChangeLog-pr-14639.yml +++ /dev/null @@ -1,7 +0,0 @@ -author: "necromanceranne" -delete-after: True -changes: - - rscadd: "Basic cybernetic organs: they're worse than organic! Basic stomachs, hearts, lungs and livers! For when you hate someone enough to not bother harvesting organs from a monkeyhuman!" - - rscadd: "Cybernetic organs have been adjusted into three tiers: 1 (basic), 2 (standard, better than organic) and 3 (absolutely better than organic but expensive to print)" - - rscadd: "Cybernetic organs that are emp'd instead suffer different effects based on the severity of the emp. The bigger the emp, the worse the effect is." - - rscadd: "Rather than outright bricking, severely emp'd cyberorgans degrade over time very quickly, requiring replacement in the near future." diff --git a/html/changelogs/AutoChangeLog-pr-14643.yml b/html/changelogs/AutoChangeLog-pr-14643.yml deleted file mode 100644 index d344957d55..0000000000 --- a/html/changelogs/AutoChangeLog-pr-14643.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "akada" -delete-after: True -changes: - - imageadd: "Changes the space adaptation sprite to something less intrusive and more subtle." diff --git a/html/changelogs/AutoChangeLog-pr-14647.yml b/html/changelogs/AutoChangeLog-pr-14647.yml deleted file mode 100644 index a59e47811d..0000000000 --- a/html/changelogs/AutoChangeLog-pr-14647.yml +++ /dev/null @@ -1,8 +0,0 @@ -author: "Melbert, SandPoot" -delete-after: True -changes: - - refactor: "TGUI Limbgrower" - - refactor: "Refactored the limbgrower to modernize the code and allow for more types of designs." - - rscadd: "The limbgrower now supports plumbing ducts." - - bugfix: "Fixes genitals not actually getting data from disks." - - code_imp: "Adds two special helpers." diff --git a/html/changelogs/AutoChangeLog-pr-14648.yml b/html/changelogs/AutoChangeLog-pr-14648.yml deleted file mode 100644 index e2320ec5fe..0000000000 --- a/html/changelogs/AutoChangeLog-pr-14648.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "SandPoot" -delete-after: True -changes: - - rscadd: "The decal painter now has visible previews for your tile painting funs." - - bugfix: "Fixes decal painter painting in the opposite direction." diff --git a/html/changelogs/AutoChangeLog-pr-14649.yml b/html/changelogs/AutoChangeLog-pr-14649.yml deleted file mode 100644 index c54af36a4c..0000000000 --- a/html/changelogs/AutoChangeLog-pr-14649.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "TheObserver-sys" -delete-after: True -changes: - - balance: "Illegal Tech Ammo actually is fucking reasonable, now." - - balance: "Expensive Illegal Tech Ammo Boxes are now constructible, with actually justifiable prices." diff --git a/html/changelogs/AutoChangeLog-pr-14651.yml b/html/changelogs/AutoChangeLog-pr-14651.yml deleted file mode 100644 index 27ed8f303e..0000000000 --- a/html/changelogs/AutoChangeLog-pr-14651.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "WanderingFox95" -delete-after: True -changes: - - balance: "There's finally a reason for the reagent dart gun to exist and be used!" diff --git a/html/changelogs/AutoChangeLog-pr-14659.yml b/html/changelogs/AutoChangeLog-pr-14659.yml deleted file mode 100644 index c836c3de3e..0000000000 --- a/html/changelogs/AutoChangeLog-pr-14659.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "DrPainis" -delete-after: True -changes: - - spellcheck: "Bubblegum's hallucinations are capitalized." From 567d43c9dda6d012d674710d7b5ca5ecff6cfabb Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Thu, 29 Apr 2021 22:24:03 -0500 Subject: [PATCH 74/75] Automatic changelog generation for PR #14668 [ci skip] --- html/changelogs/AutoChangeLog-pr-14668.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-14668.yml diff --git a/html/changelogs/AutoChangeLog-pr-14668.yml b/html/changelogs/AutoChangeLog-pr-14668.yml new file mode 100644 index 0000000000..1ff2454a4d --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-14668.yml @@ -0,0 +1,4 @@ +author: "qweq12yt" +delete-after: True +changes: + - bugfix: "Restores the sprite for the Riot Suit." From d59dbfbfdadb31eb9c970c522a38d421cca62b47 Mon Sep 17 00:00:00 2001 From: Changelogs Date: Sat, 1 May 2021 00:27:12 +0000 Subject: [PATCH 75/75] Automatic changelog compile [ci skip] --- html/changelog.html | 38 ++++------------------ html/changelogs/.all_changelog.yml | 3 ++ html/changelogs/AutoChangeLog-pr-14668.yml | 4 --- 3 files changed, 9 insertions(+), 36 deletions(-) delete mode 100644 html/changelogs/AutoChangeLog-pr-14668.yml diff --git a/html/changelog.html b/html/changelog.html index 9b0cdd68bb..08c4ae4a47 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -50,6 +50,12 @@ -->
    +

    01 May 2021

    +

    qweq12yt updated:

    +
      +
    • Restores the sprite for the Riot Suit.
    • +
    +

    30 April 2021

    DrPainis updated:

      @@ -806,38 +812,6 @@
      • fixes toxinlovers dying from heretic stuff that should heal them instead
      - -

      27 February 2021

      -

      Hatterhat updated:

      -
        -
      • Lingfists (trait_mauler) now deal no stam damage and lost their 15(!!!) armor penetration.
      • -
      -

      Putnam3145 updated:

      -
        -
      • Tablets now protect their contents from rads.
      • -
      -

      TheObserver-sys updated:

      -
        -
      • Chems that should have been usable are now usable, try some cryoxadone on a plant today!!!
      • -
      -

      kappa-sama updated:

      -
        -
      • cards and card binders are now small-class items
      • -
      -

      keronshb updated:

      -
        -
      • 16 > 10 unlock cost for stronger abilities
      • -
      • Made nearly all other abilities for free.
      • -
      -

      kiwedespars updated:

      -
        -
      • reverted the pr that absolutely gutted pugilism and made it worse than base unarmed, also gives it a second long stagger
      • -
      • removed the ability to parry while horizontal, because that's dumb and makes it easy to just time the parries right.
      • -
      -

      silicons updated:

      -
        -
      • chaplain arrythmic knives can no longer be abused for infinite speed.
      • -
    GoonStation 13 Development Team diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml index 0698eeaddc..1212e88f23 100644 --- a/html/changelogs/.all_changelog.yml +++ b/html/changelogs/.all_changelog.yml @@ -29216,3 +29216,6 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py. time very quickly, requiring replacement in the near future. - rscadd: Fake blindfolds in the loadout. They don't obscure vision, for better or worse. +2021-05-01: + qweq12yt: + - bugfix: Restores the sprite for the Riot Suit. diff --git a/html/changelogs/AutoChangeLog-pr-14668.yml b/html/changelogs/AutoChangeLog-pr-14668.yml deleted file mode 100644 index 1ff2454a4d..0000000000 --- a/html/changelogs/AutoChangeLog-pr-14668.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "qweq12yt" -delete-after: True -changes: - - bugfix: "Restores the sprite for the Riot Suit."