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 001/135] 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 002/135] 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 003/135] 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 004/135] 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 005/135] 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 006/135] 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 007/135] 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 008/135] 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 04f90b749f6a72dfdfa097b41aa8c53c3032e975 Mon Sep 17 00:00:00 2001
From: qweq12yt <45515587+qweq12yt@users.noreply.github.com>
Date: Tue, 30 Mar 2021 12:33:23 -0300
Subject: [PATCH 009/135] fixes material crates not shipping
---
.../closets/secure/secure_closets.dm | 47 +++++++++++++++++++
code/modules/cargo/packs.dm | 5 +-
code/modules/cargo/packs/materials.dm | 16 +++----
code/modules/cargo/packs/misc.dm | 2 +-
code/modules/shuttle/supply.dm | 1 -
5 files changed, 60 insertions(+), 11 deletions(-)
diff --git a/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm b/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm
index 0c314d988c..5b78ca323c 100644
--- a/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm
+++ b/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm
@@ -19,3 +19,50 @@
desc = "A sturdier card-locked storage unit used for bulky shipments."
max_integrity = 500 // Same as crates.
melee_min_damage = 25 // Idem.
+
+/obj/structure/closet/secure_closet/goodies/owned
+ name = "private locker"
+ desc = "A locker designed to only open for who purchased its contents."
+ ///Account of the person buying the crate if private purchasing.
+ var/datum/bank_account/buyer_account
+ ///Department of the person buying the crate if buying via the NIRN app.
+ var/datum/bank_account/department/department_account
+ ///Is the secure crate opened or closed?
+ var/privacy_lock = TRUE
+ ///Is the crate being bought by a person, or a budget card?
+ var/department_purchase = FALSE
+
+/obj/structure/closet/secure_closet/goodies/owned/examine(mob/user)
+ . = ..()
+ . += "It's locked with a privacy lock, and can only be unlocked by the buyer's ID."
+
+/obj/structure/closet/secure_closet/goodies/owned/Initialize(mapload, datum/bank_account/_buyer_account)
+ . = ..()
+ buyer_account = _buyer_account
+ if(istype(buyer_account, /datum/bank_account/department))
+ department_purchase = TRUE
+ department_account = buyer_account
+
+/obj/structure/closet/secure_closet/goodies/owned/togglelock(mob/living/user, silent)
+ if(privacy_lock)
+ if(!broken)
+ var/obj/item/card/id/id_card = user.get_idcard(TRUE)
+ if(id_card)
+ if(id_card.registered_account)
+ if(id_card.registered_account == buyer_account || (department_purchase && (id_card.registered_account?.account_job?.paycheck_department) == (department_account.department_id)))
+ if(iscarbon(user))
+ add_fingerprint(user)
+ locked = !locked
+ user.visible_message("[user] unlocks [src]'s privacy lock.",
+ "You unlock [src]'s privacy lock.")
+ privacy_lock = FALSE
+ update_icon()
+ else if(!silent)
+ to_chat(user, "Bank account does not match with buyer!")
+ else if(!silent)
+ to_chat(user, "No linked bank account detected!")
+ else if(!silent)
+ to_chat(user, "No ID detected!")
+ else if(!silent)
+ to_chat(user, "[src] is broken!")
+ else ..()
diff --git a/code/modules/cargo/packs.dm b/code/modules/cargo/packs.dm
index 7ec3a775a5..db722436ca 100644
--- a/code/modules/cargo/packs.dm
+++ b/code/modules/cargo/packs.dm
@@ -21,7 +21,10 @@
/datum/supply_pack/proc/generate(atom/A, datum/bank_account/paying_account)
var/obj/structure/closet/crate/C
if(paying_account)
- C = new /obj/structure/closet/crate/secure/owned(A, paying_account)
+ if(ispath(crate_type, /obj/structure/closet/secure_closet/goodies))
+ C = new /obj/structure/closet/secure_closet/goodies/owned(A, paying_account)
+ else
+ C = new /obj/structure/closet/crate/secure/owned(A, paying_account)
C.name = "[crate_name] - Purchased by [paying_account.account_holder]"
else
C = new crate_type(A)
diff --git a/code/modules/cargo/packs/materials.dm b/code/modules/cargo/packs/materials.dm
index 86c6b114f0..8b063c1a30 100644
--- a/code/modules/cargo/packs/materials.dm
+++ b/code/modules/cargo/packs/materials.dm
@@ -14,56 +14,56 @@
//////////////////////////////////////////////////////////////////////////////
/datum/supply_pack/materials/cardboard50
- goody = PACK_GOODY_PUBLIC
+ crate_type = /obj/structure/closet/secure_closet/goodies
name = "50 Cardboard Sheets"
desc = "Create a bunch of boxes."
cost = 300 //thrice their export value
contains = list(/obj/item/stack/sheet/cardboard/fifty)
/datum/supply_pack/materials/glass50
- goody = PACK_GOODY_PUBLIC
+ crate_type = /obj/structure/closet/secure_closet/goodies
name = "50 Glass Sheets"
desc = "Let some nice light in with fifty glass sheets!"
cost = 300 //double their export value
contains = list(/obj/item/stack/sheet/glass/fifty)
/datum/supply_pack/materials/metal50
- goody = PACK_GOODY_PUBLIC
+ crate_type = /obj/structure/closet/secure_closet/goodies
name = "50 Metal Sheets"
desc = "Any construction project begins with a good stack of fifty metal sheets!"
cost = 300 //double their export value
contains = list(/obj/item/stack/sheet/metal/fifty)
/datum/supply_pack/materials/plasteel20
- goody = PACK_GOODY_PUBLIC
+ crate_type = /obj/structure/closet/secure_closet/goodies
name = "20 Plasteel Sheets"
desc = "Reinforce the station's integrity with twenty plasteel sheets!"
cost = 4000
contains = list(/obj/item/stack/sheet/plasteel/twenty)
/datum/supply_pack/materials/plastic50
- goody = PACK_GOODY_PUBLIC
+ crate_type = /obj/structure/closet/secure_closet/goodies
name = "50 Plastic Sheets"
desc = "Build a limitless amount of toys with fifty plastic sheets!"
cost = 200 // double their export
contains = list(/obj/item/stack/sheet/plastic/twenty)
/datum/supply_pack/materials/sandstone30
- goody = PACK_GOODY_PUBLIC
+ crate_type = /obj/structure/closet/secure_closet/goodies
name = "30 Sandstone Blocks"
desc = "Neither sandy nor stoney, these thirty blocks will still get the job done."
cost = 150 // five times their export
contains = list(/obj/item/stack/sheet/mineral/sandstone/thirty)
/datum/supply_pack/materials/wood50
- goody = PACK_GOODY_PUBLIC
+ crate_type = /obj/structure/closet/secure_closet/goodies
name = "50 Wood Planks"
desc = "Turn cargo's boring metal groundwork into beautiful panelled flooring and much more with fifty wooden planks!"
cost = 400 // 6-7 planks shy from having equal import/export prices
contains = list(/obj/item/stack/sheet/mineral/wood/twenty)
/datum/supply_pack/materials/rcdammo
- goody = PACK_GOODY_PUBLIC
+ crate_type = /obj/structure/closet/secure_closet/goodies
name = "Large RCD ammo Single-Pack"
desc = "A single large compressed RCD matter pack, to help with any holes or projects people might be working on."
cost = 600
diff --git a/code/modules/cargo/packs/misc.dm b/code/modules/cargo/packs/misc.dm
index 985c827e65..d72ee231a8 100644
--- a/code/modules/cargo/packs/misc.dm
+++ b/code/modules/cargo/packs/misc.dm
@@ -370,7 +370,7 @@
//////////////////////////////////////////////////////////////////////////////
/datum/supply_pack/misc/carpet
- goody = PACK_GOODY_PUBLIC
+ crate_type = /obj/structure/closet/secure_closet/goodies
name = "Classic Carpet Single-Pack"
desc = "Plasteel floor tiles getting on your nerves? This 50 units stack of extra soft carpet will tie any room together."
cost = 200
diff --git a/code/modules/shuttle/supply.dm b/code/modules/shuttle/supply.dm
index 899e2b2f6f..60dfdd53c5 100644
--- a/code/modules/shuttle/supply.dm
+++ b/code/modules/shuttle/supply.dm
@@ -128,7 +128,6 @@ GLOBAL_LIST_INIT(cargo_shuttle_leave_behind_typecache, typecacheof(list(
var/value = 0
var/purchases = 0
var/list/goodies_by_buyer = list() // if someone orders more than GOODY_FREE_SHIPPING_MAX goodies, we upcharge to a normal crate so they can't carry around 20 combat shotties
-
for(var/datum/supply_order/SO in SSshuttle.shoppinglist)
if(!empty_turfs.len)
break
From 2775543c9734078422075b5d2d6e6183c2a7999b Mon Sep 17 00:00:00 2001
From: qweq12yt <45515587+qweq12yt@users.noreply.github.com>
Date: Wed, 31 Mar 2021 00:46:07 -0300
Subject: [PATCH 010/135] additional comments
---
code/modules/cargo/packs.dm | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/code/modules/cargo/packs.dm b/code/modules/cargo/packs.dm
index db722436ca..f35e2d91ea 100644
--- a/code/modules/cargo/packs.dm
+++ b/code/modules/cargo/packs.dm
@@ -21,8 +21,8 @@
/datum/supply_pack/proc/generate(atom/A, datum/bank_account/paying_account)
var/obj/structure/closet/crate/C
if(paying_account)
- if(ispath(crate_type, /obj/structure/closet/secure_closet/goodies))
- C = new /obj/structure/closet/secure_closet/goodies/owned(A, paying_account)
+ if(ispath(crate_type, /obj/structure/closet/secure_closet/goodies)) // lets ensure private orders don't come in crates when the original one comes in lockers
+ C = new /obj/structure/closet/secure_closet/goodies/owned(A, paying_account) // that would lead to infinite money exploits
else
C = new /obj/structure/closet/crate/secure/owned(A, paying_account)
C.name = "[crate_name] - Purchased by [paying_account.account_holder]"
From b97a38f125d1dc22f2b5bd69827bd0da443cb0e5 Mon Sep 17 00:00:00 2001
From: qweq12yt <45515587+qweq12yt@users.noreply.github.com>
Date: Wed, 31 Mar 2021 00:55:14 -0300
Subject: [PATCH 011/135] todo comment
hopefully i will be able to do it in the future, or someone else will implement it
---
code/modules/shuttle/supply.dm | 1 +
1 file changed, 1 insertion(+)
diff --git a/code/modules/shuttle/supply.dm b/code/modules/shuttle/supply.dm
index 60dfdd53c5..74ac0fc166 100644
--- a/code/modules/shuttle/supply.dm
+++ b/code/modules/shuttle/supply.dm
@@ -128,6 +128,7 @@ GLOBAL_LIST_INIT(cargo_shuttle_leave_behind_typecache, typecacheof(list(
var/value = 0
var/purchases = 0
var/list/goodies_by_buyer = list() // if someone orders more than GOODY_FREE_SHIPPING_MAX goodies, we upcharge to a normal crate so they can't carry around 20 combat shotties
+ // var/list/lockers_by_buyer = list() // TODO, combine orders that come in lockers into a single locker to not crowd the shuttle
for(var/datum/supply_order/SO in SSshuttle.shoppinglist)
if(!empty_turfs.len)
break
From 37be0768b3f666aa7aedd718a9bf572f2a0af697 Mon Sep 17 00:00:00 2001
From: qweq12yt <45515587+qweq12yt@users.noreply.github.com>
Date: Wed, 31 Mar 2021 01:08:01 -0300
Subject: [PATCH 012/135] goodbye define - more comments
---
code/__DEFINES/cargo.dm | 5 ++---
code/modules/cargo/packs.dm | 1 +
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/code/__DEFINES/cargo.dm b/code/__DEFINES/cargo.dm
index 40a50fe1e6..85e5e9d2ac 100644
--- a/code/__DEFINES/cargo.dm
+++ b/code/__DEFINES/cargo.dm
@@ -60,6 +60,5 @@ GLOBAL_LIST_INIT(podstyles, list(\
))
//cit
-#define PACK_GOODY_NONE 0
-#define PACK_GOODY_PUBLIC 1 //can be bought by both privates and cargo
-#define PACK_GOODY_PRIVATE 2 //can be bought only by privates
+#define PACK_GOODY_NONE 0 // can be bought by cargo and privates
+#define PACK_GOODY_PRIVATE 1 // can be bought only by privates
diff --git a/code/modules/cargo/packs.dm b/code/modules/cargo/packs.dm
index f35e2d91ea..3e3aeff592 100644
--- a/code/modules/cargo/packs.dm
+++ b/code/modules/cargo/packs.dm
@@ -15,6 +15,7 @@
var/special_enabled = FALSE
var/DropPodOnly = FALSE //only usable by the Bluespace Drop Pod via the express cargo console
var/admin_spawned = FALSE //Can only an admin spawn this crate?
+ // this might be all in all unnecessary with current code if some changes are made
var/goody = PACK_GOODY_NONE //Small items can be grouped into a single crate.They also come in a closet/lockbox instead of a full crate, so the 700 min doesn't apply
var/can_private_buy = TRUE //Can it be purchased privately by each crewmember?
From 6ae984971cfdbc9d72d4c520efe381193babfecd Mon Sep 17 00:00:00 2001
From: Putnam
Date: Tue, 30 Mar 2021 23:25:36 -0700
Subject: [PATCH 013/135] Ported bluespace pipes from yogs
---
code/game/machinery/pipe/construction.dm | 19 ++++
.../atmospherics/machinery/pipes/bluespace.dm | 86 ++++++++++++++++++
.../research/designs/bluespace_designs.dm | 10 ++
.../research/techweb/nodes/bluespace_nodes.dm | 2 +-
icons/obj/atmospherics/pipes/bluespace.dmi | Bin 0 -> 677 bytes
5 files changed, 116 insertions(+), 1 deletion(-)
create mode 100644 code/modules/atmospherics/machinery/pipes/bluespace.dm
create mode 100644 icons/obj/atmospherics/pipes/bluespace.dmi
diff --git a/code/game/machinery/pipe/construction.dm b/code/game/machinery/pipe/construction.dm
index 141afa53e7..d825cb5a23 100644
--- a/code/game/machinery/pipe/construction.dm
+++ b/code/game/machinery/pipe/construction.dm
@@ -236,3 +236,22 @@ Buildable meters
/obj/item/pipe_meter/proc/setAttachLayer(new_layer = PIPING_LAYER_DEFAULT)
piping_layer = new_layer
PIPING_LAYER_DOUBLE_SHIFT(src, piping_layer)
+
+/obj/item/pipe/bluespace
+ pipe_type = /obj/machinery/atmospherics/pipe/bluespace
+ var/bluespace_network_name = "default"
+ icon_state = "bluespace"
+ disposable = FALSE
+
+/obj/item/pipe/bluespace/attack_self(mob/user)
+ var/new_name = input(user, "Enter identifier for bluespace pipe network", "bluespace pipe", bluespace_network_name) as text|null
+ if(!isnull(new_name))
+ bluespace_network_name = new_name
+
+/obj/item/pipe/bluespace/make_from_existing(obj/machinery/atmospherics/pipe/bluespace/make_from)
+ bluespace_network_name = make_from.bluespace_network_name
+ return ..()
+
+/obj/item/pipe/bluespace/build_pipe(obj/machinery/atmospherics/pipe/bluespace/A)
+ A.bluespace_network_name = bluespace_network_name
+ return ..()
diff --git a/code/modules/atmospherics/machinery/pipes/bluespace.dm b/code/modules/atmospherics/machinery/pipes/bluespace.dm
new file mode 100644
index 0000000000..2735a38106
--- /dev/null
+++ b/code/modules/atmospherics/machinery/pipes/bluespace.dm
@@ -0,0 +1,86 @@
+GLOBAL_LIST_EMPTY(bluespace_pipe_networks)
+/obj/machinery/atmospherics/pipe/bluespace
+ name = "bluespace pipe"
+ desc = "Transmits gas across large distances of space. Developed using bluespace technology."
+ icon = 'icons/obj/atmospherics/pipes/bluespace.dmi'
+ icon_state = "map"
+ pipe_state = "bluespace"
+ dir = SOUTH
+ initialize_directions = SOUTH
+ device_type = UNARY
+ can_buckle = FALSE
+ construction_type = /obj/item/pipe/bluespace
+ var/bluespace_network_name
+
+/obj/machinery/atmospherics/pipe/bluespace/New()
+ icon_state = "pipe"
+ if(bluespace_network_name) // in case someone maps one in for some reason
+ if(!GLOB.bluespace_pipe_networks[bluespace_network_name])
+ GLOB.bluespace_pipe_networks[bluespace_network_name] = list()
+ GLOB.bluespace_pipe_networks[bluespace_network_name] |= src
+ ..()
+
+/obj/machinery/atmospherics/pipe/bluespace/on_construction()
+ . = ..()
+ if(bluespace_network_name)
+ if(!GLOB.bluespace_pipe_networks[bluespace_network_name])
+ GLOB.bluespace_pipe_networks[bluespace_network_name] = list()
+ GLOB.bluespace_pipe_networks[bluespace_network_name] |= src
+
+/obj/machinery/atmospherics/pipe/bluespace/Destroy()
+ if(GLOB.bluespace_pipe_networks[bluespace_network_name])
+ GLOB.bluespace_pipe_networks[bluespace_network_name] -= src
+ for(var/p in GLOB.bluespace_pipe_networks[bluespace_network_name])
+ var/obj/machinery/atmospherics/pipe/bluespace/P = p
+ QDEL_NULL(P.parent)
+ P.build_network()
+ return ..()
+
+/obj/machinery/atmospherics/pipe/bluespace/examine(user)
+ . = ..()
+ . += "This one is connected to the \"[html_encode(bluespace_network_name)]\" network."
+
+/obj/machinery/atmospherics/pipe/bluespace/SetInitDirections()
+ initialize_directions = dir
+
+/obj/machinery/atmospherics/pipe/bluespace/pipeline_expansion()
+ return ..() + GLOB.bluespace_pipe_networks[bluespace_network_name] - src
+
+/obj/machinery/atmospherics/pipe/bluespace/hide()
+ update_icon()
+
+/obj/machinery/atmospherics/pipe/bluespace/update_icon(showpipe)
+ underlays.Cut()
+
+ var/turf/T = loc
+ if(level == 2 || !T.intact)
+ showpipe = TRUE
+ plane = GAME_PLANE
+ else
+ showpipe = FALSE
+ plane = FLOOR_PLANE
+
+ if(!showpipe)
+ return //no need to update the pipes if they aren't showing
+
+ var/connected = 0 //Direction bitset
+
+ for(var/i in 1 to device_type) //adds intact pieces
+ if(nodes[i])
+ var/obj/machinery/atmospherics/node = nodes[i]
+ var/image/img = get_pipe_underlay("pipe_intact", get_dir(src, node), node.pipe_color)
+ underlays += img
+ connected |= img.dir
+
+ for(var/direction in GLOB.cardinals)
+ if((initialize_directions & direction) && !(connected & direction))
+ underlays += get_pipe_underlay("pipe_exposed", direction)
+
+/obj/machinery/atmospherics/pipe/bluespace/paint()
+ return FALSE
+
+/obj/machinery/atmospherics/pipe/bluespace/proc/get_pipe_underlay(state, dir, color = null)
+ if(color)
+ . = getpipeimage('icons/obj/atmospherics/components/binary_devices.dmi', state, dir, color)
+ else
+ . = getpipeimage('icons/obj/atmospherics/components/binary_devices.dmi', state, dir)
diff --git a/code/modules/research/designs/bluespace_designs.dm b/code/modules/research/designs/bluespace_designs.dm
index a70449b035..cf6aff5918 100644
--- a/code/modules/research/designs/bluespace_designs.dm
+++ b/code/modules/research/designs/bluespace_designs.dm
@@ -105,3 +105,13 @@
materials = list(/datum/material/iron = 2000, /datum/material/bluespace = 500)
category = list("Bluespace Designs")
departmental_flags = DEPARTMENTAL_FLAG_SERVICE
+
+/datum/design/bluespace_pipe
+ name = "Bluespace Pipe"
+ desc = "A pipe that teleports gases."
+ id = "bluespace_pipe"
+ build_type = PROTOLATHE
+ materials = list(/datum/material/gold = 1000, /datum/material/diamond = 750, /datum/material/uranium = 250, /datum/material/bluespace = 2000)
+ build_path = /obj/item/pipe/bluespace
+ category = list("Bluespace Designs")
+ departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING
diff --git a/code/modules/research/techweb/nodes/bluespace_nodes.dm b/code/modules/research/techweb/nodes/bluespace_nodes.dm
index 6c782456a8..90b69eb28d 100644
--- a/code/modules/research/techweb/nodes/bluespace_nodes.dm
+++ b/code/modules/research/techweb/nodes/bluespace_nodes.dm
@@ -61,7 +61,7 @@
display_name = "Bluespace Travel"
description = "Application of Bluespace for static teleportation technology."
prereq_ids = list("adv_power", "adv_bluespace")
- design_ids = list("tele_station", "tele_hub", "quantumpad", "quantum_keycard", "launchpad", "launchpad_console", "teleconsole", "roastingstick")
+ design_ids = list("tele_station", "tele_hub", "quantumpad", "quantum_keycard", "launchpad", "launchpad_console", "teleconsole", "roastingstick", "bluespace_pipe")
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500)
/datum/techweb_node/unregulated_bluespace
diff --git a/icons/obj/atmospherics/pipes/bluespace.dmi b/icons/obj/atmospherics/pipes/bluespace.dmi
new file mode 100644
index 0000000000000000000000000000000000000000..866e6f9b844f4f4a9c987755618f0d3ca5a9087f
GIT binary patch
literal 677
zcmV;W0$TlvP)V!Y0R8_htE;PQY;6CPVgJl#eSLkvz`zX+
z4PIVegM)*(xVRY^86O`X8X6k4wY41`9b#f)x3{;3hK3s(8(CRdw6wG%F=jRZ0004W
zQchCV=-0C=2JR&a84_w-Y6@%7{?OD!tS%+FJ>
zRWQ*r;NmRLOex6#a*U0*I5Sc+(=$pSoZ^zil2jm5sUWi;Rf&r;C9|j)$Tj5ROe;#v
zO$D*dfTF26iIpH>9g-lz^xVV(?1me1DJ!`8xqzJv05#Dr#k$KneEa!CT?#h!$R^WZnO?Z6-nypoZd+G38!XgQfoq6@ci9H62}G(+w9DyIQ0_?@P`l4G
z5M2s_ra$GMmx8vH225?6X&^ew3KX5iA!PKlf-bF)x-PfEj?)4ZJrL6_qYv-Uv;L0#
zoip4mXY(DrW^FiQc^8sh|G2gR3A4q>z=LcoJ
z81j9J->l?+89!8=QvTQH15)RMw8Nn4vH*2HkP1EjhkLqq1~wnqd|()cVHl6W;R>dI
zjQvQA5QjsYa}CI#pYwf>GMMr`%3#j-D1$lQ!*(#`d)yiP
Date: Tue, 30 Mar 2021 23:35:47 -0700
Subject: [PATCH 014/135] why did this not update
---
tgstation.dme | 1 +
1 file changed, 1 insertion(+)
diff --git a/tgstation.dme b/tgstation.dme
index db49b62864..d3ade0623e 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -1808,6 +1808,7 @@
#include "code\modules\atmospherics\machinery\components\unary_devices\vent_scrubber.dm"
#include "code\modules\atmospherics\machinery\other\meter.dm"
#include "code\modules\atmospherics\machinery\other\miner.dm"
+#include "code\modules\atmospherics\machinery\pipes\bluespace.dm"
#include "code\modules\atmospherics\machinery\pipes\layermanifold.dm"
#include "code\modules\atmospherics\machinery\pipes\manifold.dm"
#include "code\modules\atmospherics\machinery\pipes\manifold4w.dm"
From 68ad5c2e5c6db6badfea8ecd22f50ee5b88bb436 Mon Sep 17 00:00:00 2001
From: Putnam
Date: Tue, 30 Mar 2021 23:56:12 -0700
Subject: [PATCH 015/135] disposability
---
code/game/machinery/pipe/construction.dm | 1 +
code/game/objects/items/RPD.dm | 14 ++++++++------
2 files changed, 9 insertions(+), 6 deletions(-)
diff --git a/code/game/machinery/pipe/construction.dm b/code/game/machinery/pipe/construction.dm
index d825cb5a23..5b30105409 100644
--- a/code/game/machinery/pipe/construction.dm
+++ b/code/game/machinery/pipe/construction.dm
@@ -21,6 +21,7 @@ Buildable meters
level = 2
var/piping_layer = PIPING_LAYER_DEFAULT
var/RPD_type
+ var/disposable = TRUE
/obj/item/pipe/directional
RPD_type = PIPE_UNARY
diff --git a/code/game/objects/items/RPD.dm b/code/game/objects/items/RPD.dm
index 70e4441c66..635ea97902 100644
--- a/code/game/objects/items/RPD.dm
+++ b/code/game/objects/items/RPD.dm
@@ -375,12 +375,14 @@ GLOBAL_LIST_INIT(fluid_duct_recipes, list(
. = TRUE
if((mode & DESTROY_MODE) && istype(A, /obj/item/pipe) || istype(A, /obj/structure/disposalconstruct) || istype(A, /obj/structure/c_transit_tube) || istype(A, /obj/structure/c_transit_tube_pod) || istype(A, /obj/item/pipe_meter))
- to_chat(user, "You start destroying a pipe...")
- playsound(get_turf(src), 'sound/machines/click.ogg', 50, 1)
- if(do_after(user, destroy_speed, target = A))
- activate()
- qdel(A)
- return
+ var/obj/item/pipe/P = A
+ if(!istype(P) || P.disposable)
+ to_chat(user, "You start destroying a pipe...")
+ playsound(get_turf(src), 'sound/machines/click.ogg', 50, 1)
+ if(do_after(user, destroy_speed, target = A))
+ activate()
+ qdel(A)
+ return
if((mode & PAINT_MODE))
if(istype(A, /obj/machinery/atmospherics/pipe) && !istype(A, /obj/machinery/atmospherics/pipe/layer_manifold))
From 43d855c41339c7e16072f5abc41dcdd493b85ff4 Mon Sep 17 00:00:00 2001
From: Blue Wildrose
Date: Sun, 4 Apr 2021 17:05:18 -0700
Subject: [PATCH 016/135] Killable space pirate sleepers
---
.../objects/structures/ghost_role_spawners.dm | 41 ++++++++++++++++++-
1 file changed, 40 insertions(+), 1 deletion(-)
diff --git a/code/game/objects/structures/ghost_role_spawners.dm b/code/game/objects/structures/ghost_role_spawners.dm
index 306868daba..a14c1208cd 100644
--- a/code/game/objects/structures/ghost_role_spawners.dm
+++ b/code/game/objects/structures/ghost_role_spawners.dm
@@ -590,7 +590,7 @@
/obj/effect/mob_spawn/human/pirate
name = "space pirate sleeper"
- desc = "A cryo sleeper smelling faintly of rum."
+ desc = "A cryo sleeper smelling faintly of rum. The sleeper looks unstable. Perhaps the pirate within can be killed with the right tools..."
job_description = "Space Pirate"
random = TRUE
icon = 'icons/obj/machines/sleeper.dmi'
@@ -608,6 +608,45 @@
assignedrole = "Space Pirate"
var/rank = "Mate"
+/obj/effect/mob_spawn/human/pirate/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags)
+ . = ..()
+ if(.)
+ return
+ if(user.mind.has_antag_datum(/datum/antagonist/pirate))
+ to_chat(user, "Your shipmate sails within their dreams for now. Perhaps they may wake up eventually.")
+ else
+ to_chat(user, "If you want to kill the pirate off, something to pry open the sleeper might be the best way to do it.")
+
+
+/obj/effect/mob_spawn/human/pirate/attackby(obj/item/W, mob/user, params)
+ if(W.tool_behaviour == TOOL_CROWBAR && user.a_intent != INTENT_HARM)
+ if(user.mind.has_antag_datum(/datum/antagonist/pirate))
+ to_chat(user,"Why would you want to do that to your shipmate? That'd kill them.")
+ return
+ user.visible_message("[usr.name] pries open the [src], disrupting the sleep of the pirate within and killing them.",
+ "You pry open the [src], disrupting the sleep of the pirate within and killing them.",
+ "You hear prying, followed by the death rattling of bones.")
+ W.play_tool_sound(src)
+ playsound(src.loc, 'modular_citadel/sound/voice/scream_skeleton.ogg', 50, 1, 4, 1.2)
+ if(rank == "Captain") new /obj/effect/mob_spawn/human/pirate/corpse/captain(get_turf(src))
+ else new /obj/effect/mob_spawn/human/pirate/corpse(get_turf(src))
+ qdel(src)
+ else
+ ..()
+
+/obj/effect/mob_spawn/human/pirate/corpse //occurs when someone pries a pirate out of their sleeper.
+ mob_name = "Dead Space Pirate"
+ death = TRUE
+ instant = TRUE
+ random = FALSE
+
+/obj/effect/mob_spawn/human/pirate/corpse/Destroy()
+ return ..()
+/obj/effect/mob_spawn/human/pirate/corpse/captain
+ rank = "Captain"
+ mob_name = "Dead Space Pirate Captain"
+ outfit = /datum/outfit/pirate/space/captain
+
/obj/effect/mob_spawn/human/pirate/special(mob/living/new_spawn)
new_spawn.fully_replace_character_name(new_spawn.real_name,generate_pirate_name())
new_spawn.mind.add_antag_datum(/datum/antagonist/pirate)
From 414d9d43e3802928d2af93c6cbfd4ccd512c7a26 Mon Sep 17 00:00:00 2001
From: Blue Wildrose
Date: Sun, 4 Apr 2021 18:50:11 -0700
Subject: [PATCH 017/135] adding a gap here
---
code/game/objects/structures/ghost_role_spawners.dm | 1 +
1 file changed, 1 insertion(+)
diff --git a/code/game/objects/structures/ghost_role_spawners.dm b/code/game/objects/structures/ghost_role_spawners.dm
index a14c1208cd..9a85a700e2 100644
--- a/code/game/objects/structures/ghost_role_spawners.dm
+++ b/code/game/objects/structures/ghost_role_spawners.dm
@@ -642,6 +642,7 @@
/obj/effect/mob_spawn/human/pirate/corpse/Destroy()
return ..()
+
/obj/effect/mob_spawn/human/pirate/corpse/captain
rank = "Captain"
mob_name = "Dead Space Pirate Captain"
From fb79a2033d68c201e2f2b4b4430defcab894f3e0 Mon Sep 17 00:00:00 2001
From: Blue Wildrose
Date: Sun, 4 Apr 2021 21:34:27 -0700
Subject: [PATCH 018/135] usr.name into user, also adding in do_after.
---
.../objects/structures/ghost_role_spawners.dm | 19 ++++++++++++-------
1 file changed, 12 insertions(+), 7 deletions(-)
diff --git a/code/game/objects/structures/ghost_role_spawners.dm b/code/game/objects/structures/ghost_role_spawners.dm
index 9a85a700e2..2e1f76cefe 100644
--- a/code/game/objects/structures/ghost_role_spawners.dm
+++ b/code/game/objects/structures/ghost_role_spawners.dm
@@ -623,14 +623,19 @@
if(user.mind.has_antag_datum(/datum/antagonist/pirate))
to_chat(user,"Why would you want to do that to your shipmate? That'd kill them.")
return
- user.visible_message("[usr.name] pries open the [src], disrupting the sleep of the pirate within and killing them.",
- "You pry open the [src], disrupting the sleep of the pirate within and killing them.",
- "You hear prying, followed by the death rattling of bones.")
+ user.visible_message("[user] start to pry open the [src]...",
+ "You start to pry open the [src]...",
+ "You hear prying...")
W.play_tool_sound(src)
- playsound(src.loc, 'modular_citadel/sound/voice/scream_skeleton.ogg', 50, 1, 4, 1.2)
- if(rank == "Captain") new /obj/effect/mob_spawn/human/pirate/corpse/captain(get_turf(src))
- else new /obj/effect/mob_spawn/human/pirate/corpse(get_turf(src))
- qdel(src)
+ if(do_after(user, 100*W.toolspeed, target = src))
+ user.visible_message("[user] pries open the [src], disrupting the sleep of the pirate within and killing them.",
+ "You pry open the [src], disrupting the sleep of the pirate within and killing them.",
+ "You hear prying, followed by the death rattling of bones.")
+ W.play_tool_sound(src)
+ playsound(src.loc, 'modular_citadel/sound/voice/scream_skeleton.ogg', 50, 1, 4, 1.2)
+ if(rank == "Captain") new /obj/effect/mob_spawn/human/pirate/corpse/captain(get_turf(src))
+ else new /obj/effect/mob_spawn/human/pirate/corpse(get_turf(src))
+ qdel(src)
else
..()
From f1b45b3839d2c012ffcceffa967bea9eac93babc Mon Sep 17 00:00:00 2001
From: zerothebigboy
Date: Mon, 5 Apr 2021 21:55:17 -0400
Subject: [PATCH 019/135] 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 += "