Kills /obj/item/melee/transforming, replaces it with a transforming weapon component (#60761)

This PR kills off the transforming subtype of /obj/item/melee and replaces it with a component to handle the transforming behavior, /datum/component/transforming.

The transforming component handles updating the variables of an item when it's transformed. Things like force, sharpness, whetstone force bonus, and attack verbs. Similar to the two-handed component, but instead of transforming into a two-hander it remains a one handed weapon.

The "nemesis" behavior (dealing addition damage to certain factions) of the transforming subtype was moved to the cleaving saw only, since it was the only transforming item that used it. In the future, this can be made into a bespoke element/component as well.

The following weapons and items have been updated to use this component:

    Energy Swords / Sabers / Bananium Energy Sword
    Energy Circular Saw
    Energy Dagger
    Energy Axe
    Toy Energy Sword
    Holographic Energy Sword
    Switchblade
    Advanced Medical Tools (Laser scalpel, Mechanical Pinches, Searing Tool)
    Advanced Engineering Tools (Hand Drill, Jaws of Life / Syndicate Jaws of Life)
    Combat Wrench
    Cleaving Saw
    Telescopic Batons / Contractor Batons
    Roasting Stick
    Telescopic Riot Shield
    Energy Shield / Bananium Energy Shield

This PR also touches up the code around the various above items.
This commit is contained in:
MrMelbert
2021-08-23 11:45:54 -07:00
committed by GitHub
parent d8a1f27fff
commit b3e8eebdc9
76 changed files with 1084 additions and 835 deletions
+1 -1
View File
@@ -160,7 +160,7 @@
return 1
/obj/item/dualsaber/ignition_effect(atom/A, mob/user)
// same as /obj/item/melee/transforming/energy, mostly
// same as /obj/item/melee/energy, mostly
if(!wielded)
return ""
var/in_mouth = ""
+199 -128
View File
@@ -1,57 +1,74 @@
/obj/item/melee/transforming/energy
/obj/item/melee/energy
icon = 'icons/obj/transforming_energy.dmi'
hitsound_on = 'sound/weapons/blade1.ogg'
heat = 3500
max_integrity = 200
armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 100, ACID = 30)
attack_verb_continuous = list("hits", "taps", "pokes")
attack_verb_simple = list("hit", "tap", "poke")
resistance_flags = FIRE_PROOF
light_system = MOVABLE_LIGHT
light_range = 3
light_power = 1
light_on = FALSE
var/sword_color
bare_wound_bonus = 20
stealthy_audio = TRUE
w_class = WEIGHT_CLASS_SMALL
/obj/item/melee/transforming/energy/Initialize()
/// The color of this energy based sword, for use in editing the icon_state.
var/sword_color_icon
/// Whether our blade is active or not.
var/blade_active = FALSE
/// Force while active.
var/active_force = 30
/// Throwforce while active.
var/active_throwforce = 20
/// Sharpness while active.
var/active_sharpness = SHARP_EDGED
/// Hitsound played attacking while active.
var/active_hitsound = 'sound/weapons/blade1.ogg'
/// Weight class while active.
var/active_w_class = WEIGHT_CLASS_BULKY
/// The heat given off when active.
var/active_heat = 3500
/obj/item/melee/energy/Initialize()
. = ..()
if(active)
START_PROCESSING(SSobj, src)
make_transformable()
AddComponent(/datum/component/butchering, _speed = 5 SECONDS, _butcher_sound = active_hitsound)
/obj/item/melee/transforming/energy/Destroy()
/obj/item/melee/energy/Destroy()
STOP_PROCESSING(SSobj, src)
return ..()
/obj/item/melee/transforming/energy/suicide_act(mob/user)
if(!active)
transform_weapon(user, TRUE)
/*
* Gives our item the transforming component, passing in our various vars.
*/
/obj/item/melee/energy/proc/make_transformable()
AddComponent(/datum/component/transforming, \
force_on = active_force, \
throwforce_on = active_throwforce, \
throw_speed_on = 4, \
sharpness_on = active_sharpness, \
hitsound_on = active_hitsound, \
w_class_on = active_w_class, \
attack_verb_continuous_on = list("attacks", "slashes", "stabs", "slices", "tears", "lacerates", "rips", "dices", "cuts"), \
attack_verb_simple_on = list("attack", "slash", "stab", "slice", "tear", "lacerate", "rip", "dice", "cut"))
RegisterSignal(src, COMSIG_TRANSFORMING_ON_TRANSFORM, .proc/on_transform)
/obj/item/melee/energy/suicide_act(mob/user)
if(!blade_active)
attack_self(user)
user.visible_message(span_suicide("[user] is [pick("slitting [user.p_their()] stomach open with", "falling on")] [src]! It looks like [user.p_theyre()] trying to commit seppuku!"))
return (BRUTELOSS|FIRELOSS)
/obj/item/melee/transforming/energy/add_blood_DNA(list/blood_dna)
/obj/item/melee/energy/add_blood_DNA(list/blood_dna)
return FALSE
/obj/item/melee/transforming/energy/get_sharpness()
return active * sharpness
/obj/item/melee/energy/process(delta_time)
if(heat)
open_flame()
/obj/item/melee/transforming/energy/process()
open_flame()
/obj/item/melee/transforming/energy/transform_weapon(mob/living/user, supress_message_text)
. = ..()
if(.)
if(active)
if(sword_color)
icon_state = "sword[sword_color]"
START_PROCESSING(SSobj, src)
else
STOP_PROCESSING(SSobj, src)
set_light_on(active)
/obj/item/melee/transforming/energy/get_temperature()
return active * heat
/obj/item/melee/transforming/energy/ignition_effect(atom/A, mob/user)
if(!active)
/obj/item/melee/energy/ignition_effect(atom/A, mob/user)
if(!heat && !blade_active)
return ""
var/in_mouth = ""
@@ -63,180 +80,234 @@
playsound(loc, hitsound, get_clamped_volume(), TRUE, -1)
add_fingerprint(user)
/obj/item/melee/transforming/energy/axe
/*
* Signal proc for [COMSIG_TRANSFORMING_ON_TRANSFORM].
*
* Updates our icon to have the correct color,
* updates the amount of heat our item gives out,
* enables / disables embedding, and
* starts / stops processing.
*
* Also gives feedback to the user and activates or deactives the glow.
*/
/obj/item/melee/energy/proc/on_transform(obj/item/source, mob/user, active)
SIGNAL_HANDLER
blade_active = active
if(active)
if(sword_color_icon)
icon_state = "[icon_state]_[sword_color_icon]"
if(embedding)
updateEmbedding()
heat = active_heat
START_PROCESSING(SSobj, src)
else
if(embedding)
disableEmbedding()
heat = initial(heat)
STOP_PROCESSING(SSobj, src)
balloon_alert(user, "[name] [active ? "enabled":"disabled"]")
playsound(user ? user : src, active ? 'sound/weapons/saberon.ogg' : 'sound/weapons/saberoff.ogg', 35, TRUE)
set_light_on(active)
return COMPONENT_NO_DEFAULT_MESSAGE
/// Energy axe - extremely strong.
/obj/item/melee/energy/axe
name = "energy axe"
desc = "An energized battle axe."
icon_state = "axe0"
icon_state = "axe"
lefthand_file = 'icons/mob/inhands/weapons/axes_lefthand.dmi'
righthand_file = 'icons/mob/inhands/weapons/axes_righthand.dmi'
force = 40
force_on = 150
throwforce = 25
throwforce_on = 30
hitsound = 'sound/weapons/bladeslice.ogg'
attack_verb_continuous = list("attacks", "chops", "cleaves", "tears", "lacerates", "cuts")
attack_verb_simple = list("attack", "chop", "cleave", "tear", "lacerate", "cut")
force = 40
throwforce = 25
throw_speed = 3
throw_range = 5
w_class = WEIGHT_CLASS_NORMAL
w_class_on = WEIGHT_CLASS_HUGE
flags_1 = CONDUCT_1
armour_penetration = 100
attack_verb_off = list("attacks", "chops", "cleaves", "tears", "lacerates", "cuts")
attack_verb_on = list()
sharpness = SHARP_EDGED
w_class = WEIGHT_CLASS_NORMAL
flags_1 = CONDUCT_1
light_color = LIGHT_COLOR_LIGHT_CYAN
/obj/item/melee/transforming/energy/axe/suicide_act(mob/user)
active_force = 150
active_throwforce = 30
active_w_class = WEIGHT_CLASS_HUGE
/obj/item/melee/energy/axe/make_transformable()
AddComponent(/datum/component/transforming, \
force_on = active_force, \
throwforce_on = active_throwforce, \
throw_speed_on = throw_speed, \
sharpness_on = sharpness, \
w_class_on = active_w_class)
RegisterSignal(src, COMSIG_TRANSFORMING_ON_TRANSFORM, .proc/on_transform)
/obj/item/melee/energy/axe/suicide_act(mob/user)
user.visible_message(span_suicide("[user] swings [src] towards [user.p_their()] head! It looks like [user.p_theyre()] trying to commit suicide!"))
return (BRUTELOSS|FIRELOSS)
/obj/item/melee/transforming/energy/sword
/// Energy swords.
/obj/item/melee/energy/sword
name = "energy sword"
desc = "May the force be within you."
icon_state = "sword0"
icon_state = "e_sword"
lefthand_file = 'icons/mob/inhands/weapons/swords_lefthand.dmi'
righthand_file = 'icons/mob/inhands/weapons/swords_righthand.dmi'
hitsound = "swing_hit"
force = 3
throwforce = 5
hitsound = "swing_hit" //it starts deactivated
attack_verb_off = list("taps", "pokes")
throw_speed = 3
throw_range = 5
sharpness = SHARP_EDGED
embedding = list("embed_chance" = 75, "impact_pain_mult" = 10)
armour_penetration = 35
block_chance = 50
embedding = list("embed_chance" = 75, "impact_pain_mult" = 10)
/obj/item/melee/transforming/energy/sword/transform_weapon(mob/living/user, supress_message_text)
. = ..()
if(. && active && sword_color)
icon_state = "sword[sword_color]"
/obj/item/melee/transforming/energy/sword/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
if(active)
/obj/item/melee/energy/sword/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
if(blade_active)
return ..()
return 0
return FALSE
/obj/item/melee/transforming/energy/sword/cyborg
sword_color = "red"
/obj/item/melee/energy/sword/cyborg
name = "cyborg energy sword"
sword_color_icon = "red"
/// The cell cost of hitting something.
var/hitcost = 50
/obj/item/melee/transforming/energy/sword/cyborg/attack(mob/M, mob/living/silicon/robot/R)
if(R.cell)
var/obj/item/stock_parts/cell/C = R.cell
if(active && !(C.use(hitcost)))
attack_self(R)
to_chat(R, span_notice("It's out of charge!"))
return
return ..()
/obj/item/melee/energy/sword/cyborg/attack(mob/target, mob/living/silicon/robot/user)
if(!user.cell)
return
/obj/item/melee/transforming/energy/sword/cyborg/saw //Used by medical Syndicate cyborgs
var/obj/item/stock_parts/cell/our_cell = user.cell
if(blade_active && !(our_cell.use(hitcost)))
attack_self(user)
to_chat(user, span_notice("It's out of charge!"))
return
return ..()
/obj/item/melee/energy/sword/cyborg/cyborg_unequip(mob/user)
if(!blade_active)
return
attack_self(user)
/obj/item/melee/energy/sword/cyborg/saw //Used by medical Syndicate cyborgs
name = "energy saw"
desc = "For heavy duty cutting. It has a carbon-fiber blade in addition to a toggleable hard-light edge to dramatically increase sharpness."
force_on = 30
force = 18 //About as much as a spear
hitsound = 'sound/weapons/circsawhit.ogg'
icon = 'icons/obj/surgery.dmi'
icon_state = "esaw_0"
icon_state_on = "esaw_1"
sword_color = null //stops icon from breaking when turned on.
hitcost = 75 //Costs more than a standard cyborg esword
icon_state = "esaw"
hitsound = 'sound/weapons/circsawhit.ogg'
force = 18
hitcost = 75 // Costs more than a standard cyborg esword.
w_class = WEIGHT_CLASS_NORMAL
sharpness = SHARP_EDGED
light_color = LIGHT_COLOR_LIGHT_CYAN
tool_behaviour = TOOL_SAW
toolspeed = 0.7 //faster as a saw
toolspeed = 0.7 // Faster than a normal saw.
/obj/item/melee/transforming/energy/sword/cyborg/saw/cyborg_unequip(mob/user)
if(!active)
return
transform_weapon(user, TRUE)
active_force = 30
sword_color_icon = null // Stops icon from breaking when turned on.
/obj/item/melee/transforming/energy/sword/cyborg/saw/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
return 0
/obj/item/melee/energy/sword/cyborg/saw/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
return FALSE
/obj/item/melee/transforming/energy/sword/saber
var/list/possible_colors = list("red" = COLOR_SOFT_RED, "blue" = LIGHT_COLOR_LIGHT_CYAN, "green" = LIGHT_COLOR_GREEN, "purple" = LIGHT_COLOR_LAVENDER)
// The colored energy swords we all know and love.
/obj/item/melee/energy/sword/saber
/// Assoc list of all possible saber colors to color define.
var/list/possible_colors = list(
"red" = COLOR_SOFT_RED,
"blue" = LIGHT_COLOR_LIGHT_CYAN,
"green" = LIGHT_COLOR_GREEN,
"purple" = LIGHT_COLOR_LAVENDER,
)
/// Whether this saber has beel multitooled.
var/hacked = FALSE
/obj/item/melee/transforming/energy/sword/saber/Initialize(mapload)
/obj/item/melee/energy/sword/saber/Initialize(mapload)
. = ..()
if(LAZYLEN(possible_colors))
var/set_color = pick(possible_colors)
sword_color = set_color
set_light_color(possible_colors[set_color])
if(!sword_color_icon && LAZYLEN(possible_colors))
sword_color_icon = pick(possible_colors)
/obj/item/melee/transforming/energy/sword/saber/process()
if(sword_color_icon)
set_light_color(possible_colors[sword_color_icon])
/obj/item/melee/energy/sword/saber/process()
. = ..()
if(hacked)
var/set_color = pick(possible_colors)
set_light_color(possible_colors[set_color])
set_light_color(possible_colors[pick(possible_colors)])
/obj/item/melee/transforming/energy/sword/saber/red
possible_colors = list("red" = COLOR_SOFT_RED)
/obj/item/melee/energy/sword/saber/red
sword_color_icon = "red"
/obj/item/melee/transforming/energy/sword/saber/blue
possible_colors = list("blue" = LIGHT_COLOR_LIGHT_CYAN)
/obj/item/melee/energy/sword/saber/blue
sword_color_icon = "blue"
/obj/item/melee/transforming/energy/sword/saber/green
possible_colors = list("green" = LIGHT_COLOR_GREEN)
/obj/item/melee/energy/sword/saber/green
sword_color_icon = "green"
/obj/item/melee/transforming/energy/sword/saber/purple
possible_colors = list("purple" = LIGHT_COLOR_LAVENDER)
/obj/item/melee/energy/sword/saber/purple
sword_color_icon = "purple"
/obj/item/melee/transforming/energy/sword/saber/attackby(obj/item/W, mob/living/user, params)
if(W.tool_behaviour == TOOL_MULTITOOL)
if(!hacked)
hacked = TRUE
sword_color = "rainbow"
to_chat(user, span_warning("RNBW_ENGAGE"))
if(active)
icon_state = "swordrainbow"
user.update_inv_hands()
else
/obj/item/melee/energy/sword/saber/attackby(obj/item/weapon, mob/living/user, params)
if(weapon.tool_behaviour == TOOL_MULTITOOL)
if(hacked)
to_chat(user, span_warning("It's already fabulous!"))
else
hacked = TRUE
sword_color_icon = "rainbow"
to_chat(user, span_warning("RNBW_ENGAGE"))
if(force >= active_force)
icon_state = "[initial(icon_state)]_on_rainbow"
user.update_inv_hands()
else
return ..()
/obj/item/melee/transforming/energy/sword/pirate
/obj/item/melee/energy/sword/pirate
name = "energy cutlass"
desc = "Arrrr matey."
icon_state = "cutlass0"
icon_state = "e_cutlass"
lefthand_file = 'icons/mob/inhands/weapons/swords_lefthand.dmi'
righthand_file = 'icons/mob/inhands/weapons/swords_righthand.dmi'
icon_state_on = "cutlass1"
light_color = COLOR_RED
/obj/item/melee/transforming/energy/blade
/// Energy blades, which are effectively perma-extended energy swords
/obj/item/melee/energy/blade
name = "energy blade"
desc = "A concentrated beam of energy in the shape of a blade. Very stylish... and lethal."
icon_state = "blade"
lefthand_file = 'icons/mob/inhands/weapons/swords_lefthand.dmi'
righthand_file = 'icons/mob/inhands/weapons/swords_righthand.dmi'
force = 30 //Normal attacks deal esword damage
hitsound = 'sound/weapons/blade1.ogg'
active = 1
throwforce = 1 //Throwing or dropping the item deletes it.
attack_verb_continuous = list("attacks", "slashes", "stabs", "slices", "tears", "lacerates", "rips", "dices", "cuts")
attack_verb_simple = list("attack", "slash", "stab", "slice", "tear", "lacerate", "rip", "dice", "cut")
force = 30
throwforce = 1 // Throwing or dropping the item deletes it.
throw_speed = 3
throw_range = 1
w_class = WEIGHT_CLASS_BULKY//So you can't hide it in your pocket or some such.
var/datum/effect_system/spark_spread/spark_system
sharpness = SHARP_EDGED
heat = 3500
w_class = WEIGHT_CLASS_BULKY
blade_active = TRUE
/// Our linked spark system that emits from our sword.
var/datum/effect_system/spark_spread/spark_system
//Most of the other special functions are handled in their own files. aka special snowflake code so kewl
/obj/item/melee/transforming/energy/blade/Initialize()
/obj/item/melee/energy/blade/Initialize()
. = ..()
spark_system = new /datum/effect_system/spark_spread()
spark_system.set_up(5, 0, src)
spark_system.attach(src)
START_PROCESSING(SSobj, src)
/obj/item/melee/transforming/energy/blade/Destroy()
/obj/item/melee/energy/blade/Destroy()
QDEL_NULL(spark_system)
return ..()
/obj/item/melee/transforming/energy/blade/transform_weapon(mob/living/user, supress_message_text)
return
/obj/item/melee/energy/blade/make_transformable()
return FALSE
/obj/item/melee/transforming/energy/blade/hardlight
/obj/item/melee/energy/blade/hardlight
name = "hardlight blade"
desc = "An extremely sharp blade made out of hard light. Packs quite a punch."
icon_state = "lightblade"
+94 -105
View File
@@ -183,9 +183,12 @@
slot_flags = ITEM_SLOT_BELT
force = 12 //9 hit crit
w_class = WEIGHT_CLASS_NORMAL
wound_bonus = 15
var/cooldown_check = 0 // Used interally, you don't want to modify
/// Whether this baton is active or not
var/extended = TRUE
/// Used interally, you don't want to modify
var/cooldown_check = 0
/// Default wait time until can stun again.
var/cooldown = (4 SECONDS)
/// The length of the knockdown applied to a struck living, non-cyborg mob.
@@ -196,23 +199,11 @@
var/stamina_damage = 55
/// Can we stun cyborgs?
var/affect_cyborg = FALSE
/// "On" sound, played when switching between able to stun or not.
var/on_sound
/// The path of the default sound to play when we stun something.
var/on_stun_sound = 'sound/effects/woodhit.ogg'
/// Do we animate the "hit" when stunning something?
var/stun_animation = TRUE
/// Are we on or off?
var/on = TRUE
var/on_icon_state // What is our sprite when turned on
var/off_icon_state // What is our sprite when turned off
var/on_inhand_icon_state // What is our in-hand sprite when turned on
var/force_on // Damage when on - not stunning
var/force_off // Damage when off - not stunning
var/weight_class_on // What is the new size class when turned on
wound_bonus = 15
/obj/item/melee/classic_baton/Initialize()
. = ..()
@@ -224,15 +215,6 @@
/obj/item/melee/classic_baton/proc/get_wait_description()
return
/// Description for when turning the baton "on".
/obj/item/melee/classic_baton/proc/get_on_description()
. = list()
.["local_on"] = "<span class ='warning'>You extend the baton.</span>"
.["local_off"] = "<span class ='notice'>You collapse the baton.</span>"
return .
/// Default message for stunning a living, non-cyborg mob.
/obj/item/melee/classic_baton/proc/get_stun_description(mob/living/target, mob/living/user)
. = list()
@@ -269,7 +251,7 @@
return
/obj/item/melee/classic_baton/attack(mob/living/target, mob/living/user, params)
if(!on)
if(!extended)
return ..()
add_fingerprint(user)
@@ -361,94 +343,91 @@
name = "telescopic baton"
desc = "A compact yet robust personal defense weapon. Can be concealed when folded."
icon = 'icons/obj/items_and_weapons.dmi'
icon_state = "telebaton_0"
icon_state = "telebaton"
lefthand_file = 'icons/mob/inhands/weapons/melee_lefthand.dmi'
righthand_file = 'icons/mob/inhands/weapons/melee_righthand.dmi'
inhand_icon_state = null
attack_verb_continuous = list("hits", "pokes")
attack_verb_simple = list("hit", "poke")
worn_icon_state = "tele_baton"
slot_flags = ITEM_SLOT_BELT
w_class = WEIGHT_CLASS_SMALL
item_flags = NONE
force = 0
on = FALSE
on_sound = 'sound/weapons/batonextend.ogg'
on_icon_state = "telebaton_1"
off_icon_state = "telebaton_0"
on_inhand_icon_state = "nullrod"
force_on = 10
force_off = 0
weight_class_on = WEIGHT_CLASS_BULKY
bare_wound_bonus = 5
extended = FALSE
/// The sound effecte played when our baton is extended.
var/on_sound = 'sound/weapons/batonextend.ogg'
/// The inhand iconstate used when our baton is extended.
var/on_inhand_icon_state = "nullrod"
/// The force on extension.
var/active_force = 10
/obj/item/melee/classic_baton/telescopic/Initialize()
. = ..()
AddComponent(/datum/component/transforming, \
force_on = active_force, \
hitsound_on = hitsound, \
w_class_on = WEIGHT_CLASS_NORMAL, \
clumsy_check = FALSE, \
attack_verb_continuous_on = list("smacks", "strikes", "cracks", "beats"), \
attack_verb_simple_on = list("smack", "strike", "crack", "beat"))
RegisterSignal(src, COMSIG_TRANSFORMING_ON_TRANSFORM, .proc/on_transform)
/obj/item/melee/classic_baton/telescopic/suicide_act(mob/user)
var/mob/living/carbon/human/H = user
var/obj/item/organ/brain/B = H.getorgan(/obj/item/organ/brain)
var/mob/living/carbon/human/human_user = user
var/obj/item/organ/brain/our_brain = human_user.getorgan(/obj/item/organ/brain)
user.visible_message(span_suicide("[user] stuffs [src] up [user.p_their()] nose and presses the 'extend' button! It looks like [user.p_theyre()] trying to clear [user.p_their()] mind."))
if(!on)
src.attack_self(user)
else
if(extended)
playsound(src, on_sound, 50, TRUE)
add_fingerprint(user)
else
attack_self(user)
sleep(3)
if (!QDELETED(H))
if(!QDELETED(B))
H.internal_organs -= B
qdel(B)
new /obj/effect/gibspawner/generic(H.drop_location(), H)
if (!QDELETED(human_user))
if(!QDELETED(our_brain))
human_user.internal_organs -= our_brain
qdel(our_brain)
new /obj/effect/gibspawner/generic(human_user.drop_location(), human_user)
return (BRUTELOSS)
/obj/item/melee/classic_baton/telescopic/attack_self(mob/user)
on = !on
var/list/desc = get_on_description()
/*
* Signal proc for [COMSIG_TRANSFORMING_ON_TRANSFORM].
*
* Gives feedback to the user and makes it show up inhand.
*/
/obj/item/melee/classic_baton/telescopic/proc/on_transform(obj/item/source, mob/user, active)
SIGNAL_HANDLER
if(on)
to_chat(user, desc["local_on"])
icon_state = on_icon_state
inhand_icon_state = on_inhand_icon_state
w_class = weight_class_on
force = force_on
attack_verb_continuous = list("smacks", "strikes", "cracks", "beats")
attack_verb_simple = list("smack", "strike", "crack", "beat")
else
to_chat(user, desc["local_off"])
icon_state = off_icon_state
inhand_icon_state = null //no sprite for concealment even when in hand
slot_flags = ITEM_SLOT_BELT
w_class = WEIGHT_CLASS_SMALL
force = force_off
attack_verb_continuous = list("hits", "pokes")
attack_verb_simple = list("hit", "poke")
playsound(src.loc, on_sound, 50, TRUE)
add_fingerprint(user)
extended = active
inhand_icon_state = active ? on_inhand_icon_state : null // When inactive, there is no inhand icon_state.
balloon_alert(user, "[active ? "extended" : "collapsed"] [src]")
playsound(user ? user : src, on_sound, 50, TRUE)
return COMPONENT_NO_DEFAULT_MESSAGE
/obj/item/melee/classic_baton/telescopic/contractor_baton
name = "contractor baton"
desc = "A compact, specialised baton assigned to Syndicate contractors. Applies light electrical shocks to targets."
icon = 'icons/obj/items_and_weapons.dmi'
icon_state = "contractor_baton_0"
icon_state = "contractor_baton"
worn_icon_state = "contractor_baton"
lefthand_file = 'icons/mob/inhands/weapons/melee_lefthand.dmi'
righthand_file = 'icons/mob/inhands/weapons/melee_righthand.dmi'
inhand_icon_state = null
slot_flags = ITEM_SLOT_BELT
w_class = WEIGHT_CLASS_SMALL
item_flags = NONE
force = 5
cooldown = 25
stamina_damage = 85
affect_cyborg = TRUE
on_sound = 'sound/weapons/contractorbatonextend.ogg'
on_stun_sound = 'sound/effects/contractorbatonhit.ogg'
on_icon_state = "contractor_baton_1"
off_icon_state = "contractor_baton_0"
on_inhand_icon_state = "contractor_baton"
force_on = 16
force_off = 5
weight_class_on = WEIGHT_CLASS_NORMAL
on_inhand_icon_state = "contractor_baton_on"
on_sound = 'sound/weapons/contractorbatonextend.ogg'
active_force = 16
/obj/item/melee/classic_baton/telescopic/contractor_baton/get_wait_description()
return span_danger("The baton is still charging!")
@@ -582,8 +561,8 @@
/obj/item/melee/roastingstick
name = "advanced roasting stick"
desc = "A telescopic roasting stick with a miniature shield generator designed to ensure entry into various high-tech shielded cooking ovens and firepits."
icon_state = "roastingstick_0"
inhand_icon_state = "null"
icon_state = "roastingstick"
inhand_icon_state = null
worn_icon_state = "tele_baton"
slot_flags = ITEM_SLOT_BELT
w_class = WEIGHT_CLASS_SMALL
@@ -591,33 +570,55 @@
force = 0
attack_verb_continuous = list("hits", "pokes")
attack_verb_simple = list("hit", "poke")
/// The sausage attatched to our stick.
var/obj/item/food/sausage/held_sausage
/// Static list of things our roasting stick can interact with.
var/static/list/ovens
var/on = FALSE
/// The beam that links to the oven we use
var/datum/beam/beam
/// Whether or stick is extended and can recieve sausage
var/extended = FALSE
/obj/item/melee/roastingstick/Initialize()
. = ..()
if (!ovens)
ovens = typecacheof(list(/obj/singularity, /obj/energy_ball, /obj/machinery/power/supermatter_crystal, /obj/structure/bonfire))
AddComponent(/datum/component/transforming, \
hitsound_on = hitsound, \
clumsy_check = FALSE)
RegisterSignal(src, COMSIG_TRANSFORMING_PRE_TRANSFORM, .proc/attempt_transform)
RegisterSignal(src, COMSIG_TRANSFORMING_ON_TRANSFORM, .proc/on_transform)
/obj/item/melee/roastingstick/attack_self(mob/user)
on = !on
if(on)
extend(user)
else
if (held_sausage)
to_chat(user, span_warning("You can't retract [src] while [held_sausage] is attached!"))
return
retract(user)
/*
* Signal proc for [COMSIG_TRANSFORMING_PRE_TRANSFORM].
*
* If there is a sausage attached, returns COMPONENT_BLOCK_TRANSFORM.
*/
/obj/item/melee/roastingstick/proc/attempt_transform(obj/item/source, mob/user, active)
SIGNAL_HANDLER
playsound(src.loc, 'sound/weapons/batonextend.ogg', 50, TRUE)
add_fingerprint(user)
if(held_sausage)
to_chat(user, span_warning("You can't retract [src] while [held_sausage] is attached!"))
return COMPONENT_BLOCK_TRANSFORM
/*
* Signal proc for [COMSIG_TRANSFORMING_ON_TRANSFORM].
*
* Gives feedback on stick extension.
*/
/obj/item/melee/roastingstick/proc/on_transform(obj/item/source, mob/user, active)
SIGNAL_HANDLER
extended = active
inhand_icon_state = active ? "nullrod" : null
balloon_alert(user, "[active ? "extended" : "collapsed"] [src]")
playsound(user ? user : src, 'sound/weapons/batonextend.ogg', 50, TRUE)
return COMPONENT_NO_DEFAULT_MESSAGE
/obj/item/melee/roastingstick/attackby(atom/target, mob/user)
..()
if (istype(target, /obj/item/food/sausage))
if (!on)
if (!extended)
to_chat(user, span_warning("You must extend [src] to attach anything to it!"))
return
if (held_sausage)
@@ -641,18 +642,6 @@
if(held_sausage)
. += mutable_appearance(icon, "roastingstick_sausage")
/obj/item/melee/roastingstick/proc/extend(user)
to_chat(user, span_warning("You extend [src]."))
icon_state = "roastingstick_1"
inhand_icon_state = "nullrod"
w_class = WEIGHT_CLASS_BULKY
/obj/item/melee/roastingstick/proc/retract(user)
to_chat(user, span_notice("You collapse [src]."))
icon_state = "roastingstick_0"
inhand_icon_state = null
w_class = WEIGHT_CLASS_SMALL
/obj/item/melee/roastingstick/handle_atom_del(atom/target)
if (target == held_sausage)
held_sausage = null
@@ -660,7 +649,7 @@
/obj/item/melee/roastingstick/afterattack(atom/target, mob/user, proximity)
. = ..()
if (!on)
if (!extended)
return
if (is_type_in_typecache(target, ovens))
if (held_sausage?.roasted)
@@ -1,101 +0,0 @@
/obj/item/melee/transforming
sharpness = SHARP_EDGED
bare_wound_bonus = 20
stealthy_audio = TRUE //Most of these are antag weps so we dont want them to be /too/ overt.
var/active = FALSE
var/force_on = 30 //force when active
var/faction_bonus_force = 0 //Bonus force dealt against certain factions
var/throwforce_on = 20
var/icon_state_on = "axe1"
var/hitsound_on = 'sound/weapons/blade1.ogg'
var/list/attack_verb_on = list("attacks", "slashes", "stabs", "slices", "tears", "lacerates", "rips", "dices", "cuts")
var/list/attack_verb_off = list("attacks", "slashes", "stabs", "slices", "tears", "lacerates", "rips", "dices", "cuts")
w_class = WEIGHT_CLASS_SMALL
var/bonus_active = FALSE //If the faction damage bonus is active
var/list/nemesis_factions //Any mob with a faction that exists in this list will take bonus damage/effects
var/w_class_on = WEIGHT_CLASS_BULKY
var/clumsy_check = TRUE
/// If we get sharpened with a whetstone, save the bonus here for later use if we un/redeploy
var/sharpened_bonus
/obj/item/melee/transforming/Initialize()
. = ..()
if(active)
if(attack_verb_on.len)
attack_verb_continuous = attack_verb_on
else
if(attack_verb_off.len)
attack_verb_continuous = attack_verb_off
if(embedding)
updateEmbedding()
if(sharpness)
AddComponent(/datum/component/butchering, 50, 100, 0, hitsound)
RegisterSignal(src, COMSIG_ITEM_SHARPEN_ACT, .proc/on_sharpen)
/obj/item/melee/transforming/attack_self(mob/living/carbon/user)
if(transform_weapon(user))
clumsy_transform_effect(user)
/obj/item/melee/transforming/attack(mob/living/target, mob/living/carbon/human/user)
var/nemesis_faction = FALSE
if(LAZYLEN(nemesis_factions))
for(var/F in target.faction)
if(F in nemesis_factions)
nemesis_faction = TRUE
force += faction_bonus_force
nemesis_effects(user, target)
break
. = ..()
if(nemesis_faction)
force -= faction_bonus_force
/obj/item/melee/transforming/proc/transform_weapon(mob/living/user, supress_message_text)
active = !active
if(active)
force = force_on + sharpened_bonus
throwforce = throwforce_on + sharpened_bonus
hitsound = hitsound_on
throw_speed = 4
if(attack_verb_on.len)
attack_verb_continuous = attack_verb_on
icon_state = icon_state_on
w_class = w_class_on
if(embedding)
updateEmbedding()
else
force = initial(force) + (get_sharpness() ? sharpened_bonus : 0)
throwforce = initial(throwforce) + (get_sharpness() ? sharpened_bonus : 0)
hitsound = initial(hitsound)
throw_speed = initial(throw_speed)
if(attack_verb_off.len)
attack_verb_continuous = attack_verb_off
icon_state = initial(icon_state)
w_class = initial(w_class)
if(embedding)
disableEmbedding()
transform_messages(user, supress_message_text)
add_fingerprint(user)
return TRUE
/obj/item/melee/transforming/proc/nemesis_effects(mob/living/user, mob/living/target)
return
/obj/item/melee/transforming/proc/transform_messages(mob/living/user, supress_message_text)
playsound(user, active ? 'sound/weapons/saberon.ogg' : 'sound/weapons/saberoff.ogg', 35, TRUE) //changed it from 50% volume to 35% because deafness
if(!supress_message_text)
to_chat(user, span_notice("[src] [active ? "is now active":"can now be concealed"]."))
/obj/item/melee/transforming/proc/clumsy_transform_effect(mob/living/user)
if(clumsy_check && HAS_TRAIT(user, TRAIT_CLUMSY) && prob(50))
to_chat(user, span_warning("You accidentally cut yourself with [src], like a doofus!"))
user.take_bodypart_damage(5,5)
/obj/item/melee/transforming/proc/on_sharpen(datum/source, increment, max)
SIGNAL_HANDLER
if(sharpened_bonus)
return COMPONENT_BLOCK_SHARPEN_ALREADY
if(force_on + increment > max)
return COMPONENT_BLOCK_SHARPEN_MAXED
sharpened_bonus = increment
+1 -1
View File
@@ -33,7 +33,7 @@
if(requires_sharpness && !I.get_sharpness())
to_chat(user, span_warning("You can only sharpen items that are already sharp, such as knives!"))
return
if(is_type_in_list(I, list(/obj/item/melee/transforming/energy, /obj/item/dualsaber))) //You can't sharpen the photons in energy meelee weapons
if(is_type_in_list(I, list(/obj/item/melee/energy, /obj/item/dualsaber))) //You can't sharpen the photons in energy meelee weapons
to_chat(user, span_warning("You don't think \the [I] will be the thing getting modified if you use it on \the [src]!"))
return
+61 -53
View File
@@ -191,6 +191,7 @@
/obj/item/shield/energy
name = "energy combat shield"
desc = "A shield that reflects almost all energy projectiles, but is useless against physical attacks. It can be retracted, expanded, and stored anywhere."
icon_state = "eshield"
lefthand_file = 'icons/mob/inhands/equipment/shields_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi'
w_class = WEIGHT_CLASS_TINY
@@ -200,50 +201,51 @@
force = 3
throwforce = 3
throw_speed = 3
base_icon_state = "eshield" // [base_icon_state]1 for expanded, [base_icon_state]0 for contracted
var/on_force = 10
var/on_throwforce = 8
var/on_throw_speed = 2
var/active = 0
var/clumsy_check = TRUE
/// Whether the shield is currently extended and protecting the user.
var/enabled = FALSE
/// Force of the shield when active.
var/active_force = 10
/// Throwforce of the shield when active.
var/active_throwforce = 8
/// Throwspeed of ethe shield when active.
var/active_throw_speed = 2
/// Whether clumsy people can transform this without side effects.
var/can_clumsy_use = FALSE
/obj/item/shield/energy/Initialize()
. = ..()
icon_state = "[base_icon_state]0"
AddComponent(/datum/component/transforming, \
force_on = active_force, \
throwforce_on = active_throwforce, \
throw_speed_on = active_throw_speed, \
hitsound_on = hitsound, \
clumsy_check = !can_clumsy_use)
RegisterSignal(src, COMSIG_TRANSFORMING_ON_TRANSFORM, .proc/on_transform)
/obj/item/shield/energy/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
return 0
return FALSE
/obj/item/shield/energy/IsReflect()
return (active)
return enabled
/obj/item/shield/energy/attack_self(mob/living/carbon/human/user)
if(clumsy_check && HAS_TRAIT(user, TRAIT_CLUMSY) && prob(50))
to_chat(user, span_userdanger("You beat yourself in the head with [src]!"))
user.take_bodypart_damage(5)
active = !active
icon_state = "[base_icon_state][active]"
/*
* Signal proc for [COMSIG_TRANSFORMING_ON_TRANSFORM].
*/
/obj/item/shield/energy/proc/on_transform(obj/item/source, mob/user, active)
SIGNAL_HANDLER
if(active)
force = on_force
throwforce = on_throwforce
throw_speed = on_throw_speed
w_class = WEIGHT_CLASS_BULKY
playsound(user, 'sound/weapons/saberon.ogg', 35, TRUE)
to_chat(user, span_notice("[src] is now active."))
else
force = initial(force)
throwforce = initial(throwforce)
throw_speed = initial(throw_speed)
w_class = WEIGHT_CLASS_TINY
playsound(user, 'sound/weapons/saberoff.ogg', 35, TRUE)
to_chat(user, span_notice("[src] can now be concealed."))
add_fingerprint(user)
enabled = active
balloon_alert(user, "[name] [active ? "activated":"deactivated"]")
playsound(user ? user : src, active ? 'sound/weapons/saberon.ogg' : 'sound/weapons/saberoff.ogg', 35, TRUE)
return COMPONENT_NO_DEFAULT_MESSAGE
/obj/item/shield/riot/tele
name = "telescopic shield"
desc = "An advanced riot shield made of lightweight materials that collapses for easy storage."
icon_state = "teleriot0"
icon_state = "teleriot"
worn_icon_state = "teleriot"
lefthand_file = 'icons/mob/inhands/equipment/shields_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi'
custom_materials = list(/datum/material/iron = 3600, /datum/material/glass = 3600, /datum/material/silver = 270, /datum/material/titanium = 180)
@@ -253,30 +255,36 @@
throw_speed = 3
throw_range = 4
w_class = WEIGHT_CLASS_NORMAL
var/active = 0
/// Whether the shield is extended and protecting the user..
var/extended = FALSE
/obj/item/shield/riot/tele/Initialize()
. = ..()
AddComponent(/datum/component/transforming, \
force_on = 8, \
throwforce_on = 5, \
throw_speed_on = 2, \
hitsound_on = hitsound, \
w_class_on = WEIGHT_CLASS_NORMAL, \
attack_verb_continuous_on = list("smacks", "strikes", "cracks", "beats"), \
attack_verb_simple_on = list("smack", "strike", "crack", "beat"))
RegisterSignal(src, COMSIG_TRANSFORMING_ON_TRANSFORM, .proc/on_transform)
/obj/item/shield/riot/tele/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
if(active)
if(extended)
return ..()
return 0
return FALSE
/obj/item/shield/riot/tele/attack_self(mob/living/user)
active = !active
icon_state = "teleriot[active]"
playsound(src.loc, 'sound/weapons/batonextend.ogg', 50, TRUE)
/*
* Signal proc for [COMSIG_TRANSFORMING_ON_TRANSFORM].
*
* Allows it to be placed on back slot when active.
*/
/obj/item/shield/riot/tele/proc/on_transform(obj/item/source, mob/user, active)
SIGNAL_HANDLER
if(active)
force = 8
throwforce = 5
throw_speed = 2
w_class = WEIGHT_CLASS_BULKY
slot_flags = ITEM_SLOT_BACK
to_chat(user, span_notice("You extend \the [src]."))
else
force = 3
throwforce = 3
throw_speed = 3
w_class = WEIGHT_CLASS_NORMAL
slot_flags = null
to_chat(user, span_notice("[src] can now be concealed."))
add_fingerprint(user)
extended = active
slot_flags = active ? ITEM_SLOT_BACK : null
playsound(user ? user : src, 'sound/weapons/batonextend.ogg', 50, TRUE)
balloon_alert(user, "[active ? "extended" : "collapsed"] [src]")
return COMPONENT_NO_DEFAULT_MESSAGE
@@ -89,7 +89,7 @@
new /obj/item/encryptionkey/syndicate(src)
if(KIT_MURDER)
new /obj/item/melee/transforming/energy/sword/saber(src)
new /obj/item/melee/energy/sword/saber(src)
new /obj/item/clothing/glasses/thermal/syndi(src)
new /obj/item/card/emag(src)
new /obj/item/clothing/shoes/chameleon/noslip(src)
@@ -236,7 +236,7 @@
new /obj/item/dnainjector/geladikinesis(src)
new /obj/item/dnainjector/cryokinesis(src)
new /obj/item/gun/energy/temperature/security(src)
new /obj/item/melee/transforming/energy/sword/saber/blue(src) //see see it fits the theme bc its blue and ice is blue
new /obj/item/melee/energy/sword/saber/blue(src) //see see it fits the theme bc its blue and ice is blue
if(KIT_TRAITOR_2006) //A kit so old, it's probably older than you. //This bundle is filled with the entire unlink contents traitors had access to in 2006, from OpenSS13. Notably the esword was not a choice but existed in code.
new /obj/item/storage/toolbox/emergency/old/ancientbundle(src) //Items fit neatly into a classic toolbox just to remind you what the theme is.
+25 -30
View File
@@ -62,7 +62,7 @@
/obj/item/crowbar/power
name = "jaws of life"
desc = "A set of jaws of life, compressed through the magic of science."
icon_state = "jaws_pry"
icon_state = "jaws"
inhand_icon_state = "jawsoflife"
worn_icon_state = "jawsoflife"
lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi'
@@ -73,10 +73,33 @@
toolspeed = 0.7
force_opens = TRUE
/obj/item/crowbar/power/Initialize()
. = ..()
AddComponent(/datum/component/transforming, \
force_on = force, \
throwforce_on = throwforce, \
hitsound_on = hitsound, \
w_class_on = w_class, \
clumsy_check = FALSE)
RegisterSignal(src, COMSIG_TRANSFORMING_ON_TRANSFORM, .proc/on_transform)
/*
* Signal proc for [COMSIG_TRANSFORMING_ON_TRANSFORM].
*
* Toggles between crowbar and wirecutters and gives feedback to the user.
*/
/obj/item/crowbar/power/proc/on_transform(obj/item/source, mob/user, active)
SIGNAL_HANDLER
tool_behaviour = (active ? TOOL_WIRECUTTER : TOOL_CROWBAR)
balloon_alert(user, "attached [active ? "cutting" : "prying"]")
playsound(user ? user : src, 'sound/items/change_jaws.ogg', 50, TRUE)
return COMPONENT_NO_DEFAULT_MESSAGE
/obj/item/crowbar/power/syndicate
name = "Syndicate jaws of life"
desc = "A re-engineered copy of Nanotrasen's standard jaws of life. Can be used to force open airlocks in its crowbar configuration."
icon_state = "jaws_pry_syndie"
icon_state = "jaws_syndie"
toolspeed = 0.5
force_opens = TRUE
@@ -99,34 +122,6 @@
playsound(loc, "desecration", 50, TRUE, -1)
return (BRUTELOSS)
/obj/item/crowbar/power/attack_self(mob/user)
playsound(get_turf(user), 'sound/items/change_jaws.ogg', 50, TRUE)
if(tool_behaviour == TOOL_CROWBAR)
tool_behaviour = TOOL_WIRECUTTER
balloon_alert(user, "attached cutting jaws")
usesound = 'sound/items/jaws_cut.ogg'
update_appearance()
else
tool_behaviour = TOOL_CROWBAR
balloon_alert(user, "attached prying jaws")
usesound = 'sound/items/jaws_pry.ogg'
update_appearance()
/obj/item/crowbar/power/update_icon_state()
if(tool_behaviour == TOOL_WIRECUTTER)
icon_state = "jaws_cutter"
else
icon_state = "jaws_pry"
return ..()
/obj/item/crowbar/power/syndicate/update_icon_state()
if(tool_behaviour == TOOL_WIRECUTTER)
icon_state = "jaws_cutter_syndie"
else
icon_state = "jaws_pry_syndie"
return ..()
/obj/item/crowbar/power/attack(mob/living/carbon/C, mob/user)
if(istype(C) && C.handcuffed && tool_behaviour == TOOL_WIRECUTTER)
user.visible_message(span_notice("[user] cuts [C]'s restraints with [src]!"))
+27 -12
View File
@@ -72,7 +72,8 @@
/obj/item/screwdriver/power
name = "hand drill"
desc = "A simple powered hand drill."
icon_state = "drill_screw"
icon_state = "drill"
belt_icon_state = null
inhand_icon_state = "drill"
worn_icon_state = "drill"
lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi'
@@ -89,9 +90,34 @@
usesound = 'sound/items/drill_use.ogg'
toolspeed = 0.7
random_color = FALSE
greyscale_config = null
greyscale_config_belt = null
greyscale_config_inhand_left = null
greyscale_config_inhand_right = null
/obj/item/screwdriver/power/Initialize()
. = ..()
AddComponent(/datum/component/transforming, \
force_on = force, \
throwforce_on = throwforce, \
hitsound_on = hitsound, \
w_class_on = w_class, \
clumsy_check = FALSE)
RegisterSignal(src, COMSIG_TRANSFORMING_ON_TRANSFORM, .proc/on_transform)
/*
* Signal proc for [COMSIG_TRANSFORMING_ON_TRANSFORM].
*
* Toggles between crowbar and wirecutters and gives feedback to the user.
*/
/obj/item/screwdriver/power/proc/on_transform(obj/item/source, mob/user, active)
SIGNAL_HANDLER
tool_behaviour = (active ? TOOL_WRENCH : TOOL_SCREWDRIVER)
balloon_alert(user, "attached [active ? "bolt bit" : "screw bit"]")
playsound(user ? user : src, 'sound/items/change_drill.ogg', 50, TRUE)
return COMPONENT_NO_DEFAULT_MESSAGE
/obj/item/screwdriver/power/examine()
. = ..()
. += " It's fitted with a [tool_behaviour == TOOL_SCREWDRIVER ? "screw" : "bolt"] bit."
@@ -104,17 +130,6 @@
playsound(loc, 'sound/items/drill_use.ogg', 50, TRUE, -1)
return(BRUTELOSS)
/obj/item/screwdriver/power/attack_self(mob/user)
playsound(get_turf(user), 'sound/items/change_drill.ogg', 50, TRUE)
if(tool_behaviour == TOOL_SCREWDRIVER)
tool_behaviour = TOOL_WRENCH
balloon_alert(user, "attached bolt bit")
icon_state = "drill_bolt"
else
tool_behaviour = TOOL_SCREWDRIVER
balloon_alert(user, "attached screw bit")
icon_state = "drill_screw"
/obj/item/screwdriver/cyborg
name = "automated screwdriver"
desc = "A powerful automated screwdriver, designed to be both precise and quick."
+24 -30
View File
@@ -82,43 +82,37 @@
name = "combat wrench"
desc = "It's like a normal wrench but edgier. Can be found on the battlefield."
icon_state = "wrench_combat"
inhand_icon_state = "wrench_combat"
belt_icon_state = "wrench_combat"
attack_verb_continuous = list("devastates", "brutalizes", "commits a war crime against", "obliterates", "humiliates")
attack_verb_simple = list("devastate", "brutalize", "commit a war crime against", "obliterate", "humiliate")
tool_behaviour = null
toolspeed = null
var/on = FALSE
/obj/item/wrench/combat/ComponentInitialize()
/obj/item/wrench/combat/Initialize()
. = ..()
AddElement(/datum/element/update_icon_updates_onmob)
AddComponent(/datum/component/transforming, \
force_on = 6, \
throwforce_on = 8, \
hitsound_on = hitsound, \
w_class_on = WEIGHT_CLASS_NORMAL, \
clumsy_check = FALSE)
RegisterSignal(src, COMSIG_TRANSFORMING_ON_TRANSFORM, .proc/on_transform)
/obj/item/wrench/combat/attack_self(mob/living/user)
if(on)
on = FALSE
force = initial(force)
w_class = initial(w_class)
throwforce = initial(throwforce)
tool_behaviour = initial(tool_behaviour)
toolspeed = initial(toolspeed)
playsound(user, 'sound/weapons/saberoff.ogg', 5, TRUE)
to_chat(user, span_warning("[src] can now be kept at bay."))
else
on = TRUE
force = 6
w_class = WEIGHT_CLASS_NORMAL
throwforce = 8
/*
* Signal proc for [COMSIG_TRANSFORMING_ON_TRANSFORM].
*
* Gives it wrench behaviors when active.
*/
/obj/item/wrench/combat/proc/on_transform(obj/item/source, mob/user, active)
SIGNAL_HANDLER
if(active)
tool_behaviour = TOOL_WRENCH
toolspeed = 1
playsound(user, 'sound/weapons/saberon.ogg', 5, TRUE)
to_chat(user, span_warning("[src] is now active. Woe onto your enemies!"))
update_appearance()
/obj/item/wrench/combat/update_icon_state()
if(on)
icon_state = "[initial(icon_state)]_on"
inhand_icon_state = "[initial(inhand_icon_state)]1"
else
icon_state = "[initial(icon_state)]"
inhand_icon_state = "[initial(inhand_icon_state)]"
return ..()
tool_behaviour = initial(tool_behaviour)
toolspeed = initial(toolspeed)
balloon_alert(user, "[name] [active ? "active, woe!":"restrained"]")
playsound(user ? user : src, active ? 'sound/weapons/saberon.ogg' : 'sound/weapons/saberoff.ogg', 5, TRUE)
return COMPONENT_NO_DEFAULT_MESSAGE
+46 -41
View File
@@ -325,63 +325,68 @@
/obj/item/toy/sword
name = "toy sword"
desc = "A cheap, plastic replica of an energy sword. Realistic sounds! Ages 8 and up."
icon_state = "e_sword"
icon = 'icons/obj/transforming_energy.dmi'
icon_state = "sword0"
inhand_icon_state = "sword0"
lefthand_file = 'icons/mob/inhands/weapons/swords_lefthand.dmi'
righthand_file = 'icons/mob/inhands/weapons/swords_righthand.dmi'
var/active = 0
w_class = WEIGHT_CLASS_SMALL
attack_verb_continuous = list("attacks", "strikes", "hits")
attack_verb_simple = list("attack", "strike", "hit")
/// Whether our sword has been multitooled to rainbow
var/hacked = FALSE
var/saber_color
/// The color of our fake energy sword
var/saber_color = "blue"
/obj/item/toy/sword/attack_self(mob/user)
active = !( active )
if (active)
to_chat(user, span_notice("You extend the plastic blade with a quick flick of your wrist."))
playsound(user, 'sound/weapons/saberon.ogg', 20, TRUE)
if(hacked)
icon_state = "swordrainbow"
inhand_icon_state = "swordrainbow"
else
icon_state = "swordblue"
inhand_icon_state = "swordblue"
w_class = WEIGHT_CLASS_BULKY
else
to_chat(user, span_notice("You push the plastic blade back down into the handle."))
playsound(user, 'sound/weapons/saberoff.ogg', 20, TRUE)
icon_state = "sword0"
inhand_icon_state = "sword0"
w_class = WEIGHT_CLASS_SMALL
add_fingerprint(user)
/obj/item/toy/sword/Initialize()
. = ..()
AddComponent(/datum/component/transforming, \
throw_speed_on = throw_speed, \
hitsound_on = hitsound, \
clumsy_check = FALSE)
RegisterSignal(src, COMSIG_TRANSFORMING_ON_TRANSFORM, .proc/on_transform)
// Copied from /obj/item/melee/transforming/energy/sword/attackby
/obj/item/toy/sword/attackby(obj/item/W, mob/living/user, params)
if(istype(W, /obj/item/toy/sword))
if(HAS_TRAIT(W, TRAIT_NODROP) || HAS_TRAIT(src, TRAIT_NODROP))
to_chat(user, span_warning("\the [HAS_TRAIT(src, TRAIT_NODROP) ? src : W] is stuck to your hand, you can't attach it to \the [HAS_TRAIT(src, TRAIT_NODROP) ? W : src]!"))
/*
* Signal proc for [COMSIG_TRANSFORMING_ON_TRANSFORM].
*
* Updates our icon to have the correct color, and give some feedback.
*/
/obj/item/toy/sword/proc/on_transform(obj/item/source, mob/user, active)
SIGNAL_HANDLER
if(active)
icon_state = "[icon_state]_[saber_color]"
balloon_alert(user, "[active ? "flicked out":"pushed in"] [src]")
playsound(user ? user : src, active ? 'sound/weapons/saberon.ogg' : 'sound/weapons/saberoff.ogg', 20, TRUE)
return COMPONENT_NO_DEFAULT_MESSAGE
// Copied from /obj/item/melee/energy/sword/attackby
/obj/item/toy/sword/attackby(obj/item/weapon, mob/living/user, params)
if(istype(weapon, /obj/item/toy/sword))
var/obj/item/toy/sword/attatched_sword = weapon
if(HAS_TRAIT(weapon, TRAIT_NODROP))
to_chat(user, span_warning("[weapon] is stuck to your hand, you can't attach it to [src]!"))
return
else if(HAS_TRAIT(src, TRAIT_NODROP))
to_chat(user, span_warning("[src] is stuck to your hand, you can't attach it to [weapon]!"))
return
else
to_chat(user, span_notice("You attach the ends of the two plastic swords, making a single double-bladed toy! You're fake-cool."))
var/obj/item/dualsaber/toy/newSaber = new /obj/item/dualsaber/toy(user.loc)
if(hacked) // That's right, we'll only check the "original" "sword".
newSaber.hacked = TRUE
newSaber.saber_color = "rainbow"
qdel(W)
var/obj/item/dualsaber/toy/new_saber = new /obj/item/dualsaber/toy(user.loc)
if(attatched_sword.hacked || hacked)
new_saber.hacked = TRUE
new_saber.saber_color = "rainbow"
qdel(weapon)
qdel(src)
else if(W.tool_behaviour == TOOL_MULTITOOL)
if(!hacked)
user.put_in_hands(new_saber)
else if(weapon.tool_behaviour == TOOL_MULTITOOL)
if(hacked)
to_chat(user, span_warning("It's already fabulous!"))
else
hacked = TRUE
saber_color = "rainbow"
to_chat(user, span_warning("RNBW_ENGAGE"))
if(active)
icon_state = "swordrainbow"
user.update_inv_hands()
else
to_chat(user, span_warning("It's already fabulous!"))
else
return ..()
+13 -31
View File
@@ -364,48 +364,30 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
attack_verb_continuous = list("stubs", "pokes")
attack_verb_simple = list("stub", "poke")
resistance_flags = FIRE_PROOF
var/extended = FALSE
/// Whether the switchblade starts extended or not.
var/start_extended = FALSE
/obj/item/switchblade/Initialize()
. = ..()
AddElement(/datum/element/update_icon_updates_onmob)
AddComponent(/datum/component/butchering, 7 SECONDS, 100)
set_extended(extended)
/obj/item/switchblade/attack_self(mob/user)
playsound(src.loc, 'sound/weapons/batonextend.ogg', 50, TRUE)
set_extended(!extended)
/obj/item/switchblade/update_icon_state()
icon_state = "[base_icon_state][extended ? "_ext" : ""]"
return ..()
/obj/item/switchblade/proc/set_extended(new_extended)
extended = new_extended
update_icon_state()
if(extended)
force = 20
w_class = WEIGHT_CLASS_NORMAL
throwforce = 23
attack_verb_continuous = list("slashes", "stabs", "slices", "tears", "lacerates", "rips", "dices", "cuts")
attack_verb_simple = list("slash", "stab", "slice", "tear", "lacerate", "rip", "dice", "cut")
hitsound = 'sound/weapons/bladeslice.ogg'
sharpness = SHARP_EDGED
else
force = 3
w_class = WEIGHT_CLASS_SMALL
throwforce = 5
attack_verb_continuous = list("stubs", "pokes")
attack_verb_simple = list("stub", "poke")
hitsound = 'sound/weapons/genhit.ogg'
sharpness = NONE
AddComponent(/datum/component/transforming, \
start_transformed = start_extended, \
force_on = 20, \
throwforce_on = 23, \
throw_speed_on = throw_speed, \
sharpness_on = SHARP_EDGED, \
hitsound_on = 'sound/weapons/bladeslice.ogg', \
w_class_on = WEIGHT_CLASS_NORMAL, \
attack_verb_continuous_on = list("slashes", "stabs", "slices", "tears", "lacerates", "rips", "dices", "cuts"), \
attack_verb_simple_on = list("slash", "stab", "slice", "tear", "lacerate", "rip", "dice", "cut"))
/obj/item/switchblade/suicide_act(mob/user)
user.visible_message(span_suicide("[user] is slitting [user.p_their()] own throat with [src]! It looks like [user.p_theyre()] trying to commit suicide!"))
return (BRUTELOSS)
/obj/item/switchblade/extended
extended = TRUE
start_extended = TRUE
/obj/item/phone
name = "red phone"