Adds the razorwire implant. Ready for review into merge (#23911)

* Please merge 23876 first thanks

* whoops / fix

* she snakes on my case till I

* Apply suggestions from code review

Co-authored-by: DGamerL <108773801+DGamerL@users.noreply.github.com>

* deconflicts, ready for TM

* Update code/_onclick/click.dm

Co-authored-by: Luc <89928798+lewcc@users.noreply.github.com>

* lewcs good to them

* icon move and changes

* almost forgot to save this

* Update augments_arms.dm

* Inverted it, it seems.

* fixes lockers

* razorwire failsafes

* fuck

* razorwire one hand

* removes 2hand implant stuff

* Apply suggestions from code review

Co-authored-by: S34N <12197162+S34NW@users.noreply.github.com>

* s34ns changes

* Vampires can gain blood for a minute from people who succumb

* Revert "Vampires can gain blood for a minute from people who succumb"

This reverts commit 50a3cf87fe.

---------

Co-authored-by: DGamerL <108773801+DGamerL@users.noreply.github.com>
Co-authored-by: Luc <89928798+lewcc@users.noreply.github.com>
Co-authored-by: S34N <12197162+S34NW@users.noreply.github.com>
This commit is contained in:
Qwertytoforty
2024-02-21 17:51:33 -05:00
committed by GitHub
parent 599f645ccb
commit ac32162dbc
15 changed files with 172 additions and 34 deletions
-3
View File
@@ -157,9 +157,6 @@
///from base of datum/radiation_wave/check_obstructions(): (datum/radiation_wave, width)
#define COMSIG_ATOM_RAD_WAVE_PASSING "atom_rad_wave_pass"
#define COMPONENT_RAD_WAVE_HANDLED (1<<0)
///from internal loop in atom/movable/proc/CanReach(): (list/next)
#define COMSIG_ATOM_CANREACH "atom_can_reach"
#define COMPONENT_BLOCK_REACH (1<<0)
///from base of atom/screwdriver_act(): (mob/living/user, obj/item/I)
#define COMSIG_ATOM_SCREWDRIVER_ACT "atom_screwdriver_act"
///from base of atom/wrench_act(): (mob/living/user, obj/item/I)
+5
View File
@@ -5,3 +5,8 @@
#define WEIGHT_CLASS_BULKY 4 //Items that can be weilded or equipped but not stored in an inventory, ex: Defibrillator, Backpack, Space Suits
#define WEIGHT_CLASS_HUGE 5 //Usually represents objects that require two hands to operate, ex: Shotgun, Two Handed Melee Weapons
#define WEIGHT_CLASS_GIGANTIC 6 //Essentially means it cannot be picked up or placed in an inventory, ex: Mech Parts, Safe
//Inventory depth: limits how many nested storage items you can access directly.
//1: stuff in mob, 2: stuff in backpack, 3: stuff in box in backpack, etc
#define INVENTORY_DEPTH 3
#define STORAGE_VIEW_DEPTH 2
+78 -23
View File
@@ -129,9 +129,19 @@
return
// operate three levels deep here (item in backpack in src; item in box in backpack in src, not any deeper)
var/sdepth = A.storage_depth(src)
if(A == loc || (A in loc) || (sdepth != -1 && sdepth <= 2))
// No adjacency needed
if(A in direct_access())
if(W)
W.melee_attack_chain(src, A, params)
else
if(ismob(A))
changeNext_move(CLICK_CD_MELEE)
UnarmedAttack(A, 1)
return
if(!isturf(loc)) // This is going to stop you from telekinesing from inside a closet, but I don't shed many tears for that
return TRUE
if(can_reach(A, W))
if(W)
W.melee_attack_chain(src, A, params)
else
@@ -139,30 +149,75 @@
changeNext_move(CLICK_CD_MELEE)
UnarmedAttack(A, 1)
return
else
if(W)
W.afterattack(A, src, 0, params) // 0: not Adjacent
else
RangedAttack(A, params)
if(!isturf(loc)) // This is going to stop you from telekinesing from inside a closet, but I don't shed many tears for that
return TRUE
// Allows you to click on a box's contents, if that box is on the ground, but no deeper than that
sdepth = A.storage_depth_turf()
if(isturf(A) || isturf(A.loc) || (sdepth != -1 && sdepth <= 1))
if(A.Adjacent(src)) // see adjacent.dm
if(W)
W.melee_attack_chain(src, A, params)
else
if(ismob(A))
changeNext_move(CLICK_CD_MELEE)
UnarmedAttack(A, 1)
/**
* A backwards depth-limited breadth-first-search to see if the target is
* logically "in" anything adjacent to us.
*/
/atom/movable/proc/can_reach(atom/ultimate_target, obj/item/tool, view_only = FALSE) //This might break mod storage. If it does, we hardcode mods / funny bag in here
var/list/direct_access = direct_access()
var/depth = 1 + (view_only ? STORAGE_VIEW_DEPTH : INVENTORY_DEPTH)
return
else // non-adjacent click
if(W)
W.afterattack(A,src,0,params) // 0: not Adjacent
else
RangedAttack(A, params)
var/list/closed = list()
var/list/checking = list(ultimate_target)
return
while(length(checking) && depth > 0)
var/list/next = list()
--depth
for(var/atom/target in checking) // will filter out nulls
if(closed[target] || isarea(target)) // avoid infinity situations
continue
if(isturf(target) || isturf(target.loc) || (target in direct_access) || !(target.IsObscured()) || istype(target.loc, /obj/item/storage)) //Directly accessible atoms
if(target.Adjacent(src) || (tool && CheckToolReach(src, target, tool.reach))) //Adjacent or reaching attacks
return TRUE
closed[target] = TRUE
if(!target.loc)
continue
if(istype(target.loc, /obj/item/storage))
next += target.loc
checking = next
return FALSE
/atom/movable/proc/direct_access()
return list(src, loc)
/mob/direct_access(atom/target)
return ..() + contents
/mob/living/direct_access(atom/target)
return ..() + get_contents()
/proc/CheckToolReach(atom/movable/here, atom/movable/there, reach)
if(!here || !there)
return FALSE
switch(reach)
if(0, 1)
return FALSE //here.Adjacent(there)
if(2 to INFINITY)
var/obj/dummy = new(get_turf(here))
dummy.pass_flags |= PASSTABLE
dummy.invisibility = 120
for(var/i in 1 to reach) //Limit it to that many tries
var/turf/T = get_step(dummy, get_dir(dummy, there))
if(dummy.can_reach(there))
qdel(dummy)
return TRUE
if(!dummy.Move(T)) //we're blocked!
qdel(dummy)
return FALSE
qdel(dummy)
/// Can this mob use keybinded click actions? (Altclick, Ctrlclick, ect)
/mob/proc/can_use_clickbinds()
+4 -7
View File
@@ -95,13 +95,10 @@
return
// cyborgs are prohibited from using storage items so we can I think safely remove (A.loc && isturf(A.loc.loc))
if(isturf(A) || isturf(A.loc))
if(A.Adjacent(src)) // see adjacent.dm
W.melee_attack_chain(src, A, params)
return
else
W.afterattack(A, src, 0, params)
return
if(can_reach(A, W))
W.melee_attack_chain(src, A, params)
return
W.afterattack(A, src, 0, params)
return
/mob/living/silicon/robot/MiddleShiftControlClickOn(atom/A)
@@ -817,6 +817,15 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
item = /obj/item/autosurgeon/organ/syndicate/hackerman_deck
cost = 30 // Probably slightly less useful than an emag with heat / cooldown, but I am not going to make it cheaper or everyone picks it over emag
/datum/uplink_item/cyber_implants/razorwire
name = "Razorwire Spool Arm Implant Autoimplanter"
desc = "A long length of monomolecular filament, built into the back of your hand. \
Impossibly thin and flawlessly sharp, it should slice through organic materials with no trouble; \
even from a few steps away. However, results against anything more durable will heavily vary."
reference = "RZR"
item = /obj/item/autosurgeon/organ/syndicate/razorwire
cost = 15
// POINTLESS BADASSERY
/datum/uplink_item/badass
+2
View File
@@ -132,6 +132,8 @@ GLOBAL_DATUM_INIT(welding_sparks, /mutable_appearance, mutable_appearance('icons
var/belt_icon = null
/// Holder var for the item outline filter, null when no outline filter on the item.
var/outline_filter
/// In tiles, how far this weapon can reach; 1 for adjacent, which is default
var/reach = 1
/obj/item/New()
..()
+1 -1
View File
@@ -18,7 +18,7 @@
return armor
if(armor <= 0)
return armor
if(!armour_penetration_flat && armour_penetration_percentage <= 0)
if(!armour_penetration_flat && !armour_penetration_percentage)
to_chat(src, "<span class='userdanger'>[soften_text]</span>")
return armor
@@ -386,6 +386,19 @@
build_path = /obj/item/organ/internal/cyberimp/arm/shell_launcher
category = list("Medical")
/datum/design/cyberimp_razorwire_spool
name = "Razorwire Spool Arm Implant"
desc = "A long length of monomolecular filament, built into the back of your hand. \
Impossibly thin and flawlessly sharp, it should slice through organic materials with no trouble; \
even from a few steps away. However, results against anything more durable will heavily vary."
id = "ci-razorwire-spool"
req_tech = list("combat" = 6, "biotech" = 6, "syndicate" = 3)
build_type = PROTOLATHE | MECHFAB
materials = list(MAT_METAL = 5000, MAT_SILVER = 2000, MAT_DIAMOND = 2000, MAT_BLUESPACE = 2000)
construction_time = 10 SECONDS
build_path = /obj/item/organ/internal/cyberimp/arm/razorwire
category = list("Medical")
/datum/design/cyberimp_toolset_abductor
name = "Abductor Toolset Implant"
desc = "An alien toolset, designed to be installed on subject's arm."
@@ -143,6 +143,7 @@
"<span class='notice'>You extend [holder] from your [parent_organ == "r_arm" ? "right" : "left"] arm.</span>",
"<span class='italics'>You hear a short mechanical noise.</span>")
playsound(get_turf(owner), 'sound/mecha/mechmove03.ogg', 50, 1)
return TRUE
/obj/item/organ/internal/cyberimp/arm/ui_action_click()
if(crit_fail || (!holder && !contents.len))
@@ -454,6 +455,55 @@
action_icon = list(/datum/action/item_action/organ_action/toggle = 'icons/obj/janitor.dmi')
action_icon_state = list(/datum/action/item_action/organ_action/toggle = "advmop")
// Razorwire implant, long reach whip made of extremely thin wire, ouch!
/obj/item/melee/razorwire
name = "implanted razorwire"
desc = "A long length of monomolecular filament, built into the back of your hand. \
Impossibly thin and flawlessly sharp, it should slice through organic materials with no trouble; \
even from a few steps away. However, results against anything more durable will heavily vary."
icon = 'icons/obj/energy_melee.dmi'
righthand_file = 'icons/mob/inhands/implants_righthand.dmi'
lefthand_file = 'icons/mob/inhands/implants_lefthand.dmi'
icon_state = "razorwire_weapon"
item_state = "razorwire"
w_class = WEIGHT_CLASS_BULKY
sharp = TRUE
force = 18
armour_penetration_percentage = -100 //This means that armor twice as effective against it
reach = 2
hitsound = 'sound/weapons/whip.ogg'
attack_verb = list("slashes", "whips", "lashes", "lacerates")
/obj/item/melee/razorwire/examine_more(mob/user)
. = ..()
. += "<i>A byproduct of Cybersun Incorporated's mistakes turned concept, the Razorwire Spool is a remarkable accident in itself. \
It consists of a fine, thread-like laser capable of being manipulated and swung like a whip. Designed for ease of deployment, the wire originates from the wrist, \
allowing users with the implant to perform wide swings and precise cuts against soft targets. It's the same energy found in other common energy weapons, such as swords and daggers.</i>"
. += "<i>Cybersun's investment into energy weapon development inadvertently led to the Razorwire Spool. Initially attempting to create an Energy Sword, \
they ended up with a material that, while superheated and correctly composed, failed to maintain a solid blade shape. Curious about this error, \
Cybersun repeated the process, producing an energy as thin as a wire. After several prototypes, they achieved a long, energy-like thread. \
Further innovation allowed them to conceal this in a forearm-sized container, \
with a hand and wrist replacement made of the same durable material used to contain energy weapons. They would call it, the Razorwire.</i>"
. += "<i>Favored by assassins for their stealth and efficiency, Cybersun exercises discretion in its distribution, favoring clients in their good graces. \
It falls behind other energy weapons due to its thinner and more loose pressure, however it is praised more as a side-arm for unarmored soft targets.</i>"
/obj/item/organ/internal/cyberimp/arm/razorwire
name = "razorwire spool implant"
desc = "An integrated spool of razorwire, capable of being used as a weapon when whipped at your foes. \
Built into the back of your hand, try your best to not get it tangled."
contents = newlist(/obj/item/melee/razorwire)
icon_state = "razorwire"
action_icon = list(/datum/action/item_action/organ_action/toggle = 'icons/obj/surgery.dmi')
action_icon_state = list(/datum/action/item_action/organ_action/toggle = "razorwire")
origin_tech = "combat=5;biotech=5;syndicate=2"
stealth_level = 1 // Hidden from health analyzers
/obj/item/organ/internal/cyberimp/arm/razorwire/examine_more(mob/user)
. = ..()
for(var/obj/I in contents)
return I.examine_more()
// Shell launch system, an arm mounted single-shot shotgun that comes out of your arm
/obj/item/gun/projectile/revolver/doublebarrel/shell_launcher
@@ -93,6 +93,16 @@
uses = 1
starting_organ = /obj/item/organ/internal/eyes/cybernetic/meson
/obj/item/autosurgeon/organ/syndicate/razorwire
desc = "A single use autosurgeon that contains a Razorwire arm implant. A screwdriver can be used to remove it, but implants can't be placed back in."
uses = 1
starting_organ = /obj/item/organ/internal/cyberimp/arm/razorwire
/obj/item/autosurgeon/organ/syndicate/razorwire/examine_more(mob/user)
. = ..()
if(storedorgan)
return storedorgan.examine_more()
/obj/item/autosurgeon/organ/syndicate/hackerman_deck
desc = "A single use autosurgeon that contains a Binyat wireless hacking system. A screwdriver can be used to remove it, but implants can't be placed back in."
uses = 1
Binary file not shown.

Before

Width:  |  Height:  |  Size: 312 B

After

Width:  |  Height:  |  Size: 484 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 315 B

After

Width:  |  Height:  |  Size: 492 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.3 KiB

After

Width:  |  Height:  |  Size: 9.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 75 KiB

After

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 30 KiB