diff --git a/_maps/templates/holodeck_doppler_sword_trainer.dmm b/_maps/templates/holodeck_doppler_sword_trainer.dmm new file mode 100644 index 0000000000000..91743b296245e --- /dev/null +++ b/_maps/templates/holodeck_doppler_sword_trainer.dmm @@ -0,0 +1,435 @@ +//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +"a" = ( +/obj/effect/turf_decal/tile/dark/half{ + dir = 4 + }, +/obj/effect/turf_decal/trimline/yellow/warning{ + dir = 8 + }, +/turf/open/floor/holofloor{ + icon_state = "smooth_large"; + base_icon_state = "smooth_large" + }, +/area/template_noop) +"c" = ( +/obj/effect/turf_decal/tile/dark/half{ + dir = 4 + }, +/obj/effect/turf_decal/trimline/yellow/warning{ + dir = 8 + }, +/turf/open/floor/holofloor{ + base_icon_state = "smooth_half"; + icon_state = "smooth_half"; + dir = 1 + }, +/area/template_noop) +"d" = ( +/obj/effect/turf_decal/tile/neutral/half/contrasted{ + dir = 4 + }, +/turf/open/floor/holofloor{ + base_icon_state = "smooth"; + icon_state = "smooth"; + dir = 1 + }, +/area/template_noop) +"e" = ( +/obj/structure/chair{ + dir = 4 + }, +/turf/open/floor/holofloor{ + base_icon_state = "smooth_half"; + icon_state = "smooth_half"; + dir = 1 + }, +/area/template_noop) +"f" = ( +/obj/effect/turf_decal/arrows/white, +/turf/open/floor/holofloor{ + icon_state = "smooth_large"; + base_icon_state = "smooth_large" + }, +/area/template_noop) +"h" = ( +/obj/effect/turf_decal/bot_white/left, +/turf/open/floor/holofloor{ + icon_state = "smooth_large"; + base_icon_state = "smooth_large" + }, +/area/template_noop) +"k" = ( +/obj/effect/turf_decal/tile/dark/half{ + dir = 8 + }, +/obj/effect/turf_decal/trimline/yellow/warning{ + dir = 4 + }, +/turf/open/floor/holofloor{ + icon_state = "smooth_large"; + base_icon_state = "smooth_large" + }, +/area/template_noop) +"l" = ( +/obj/effect/turf_decal/trimline/neutral/warning{ + dir = 5 + }, +/turf/open/floor/holofloor{ + base_icon_state = "smooth_half"; + icon_state = "smooth_half"; + dir = 1 + }, +/area/template_noop) +"m" = ( +/obj/effect/turf_decal/trimline/neutral/warning{ + dir = 4 + }, +/turf/open/floor/holofloor{ + base_icon_state = "smooth_half"; + icon_state = "smooth_half"; + dir = 1 + }, +/area/template_noop) +"n" = ( +/turf/open/floor/holofloor{ + base_icon_state = "smooth"; + icon_state = "smooth"; + dir = 1 + }, +/area/template_noop) +"o" = ( +/obj/effect/turf_decal/trimline/neutral/warning{ + dir = 6 + }, +/turf/open/floor/holofloor{ + base_icon_state = "smooth_half"; + icon_state = "smooth_half"; + dir = 1 + }, +/area/template_noop) +"q" = ( +/obj/structure/rack, +/obj/item/storage/belt/secsword/training, +/obj/item/storage/belt/secsword/training{ + pixel_y = 4 + }, +/obj/effect/turf_decal/bot_white, +/turf/open/floor/holofloor{ + icon_state = "smooth_large"; + base_icon_state = "smooth_large" + }, +/area/template_noop) +"r" = ( +/obj/effect/turf_decal/tile/neutral/full, +/turf/open/floor/holofloor{ + icon_state = "smooth_large"; + base_icon_state = "smooth_large" + }, +/area/template_noop) +"v" = ( +/obj/effect/turf_decal/trimline/neutral/warning{ + dir = 5 + }, +/obj/machinery/shower/directional/east, +/obj/structure/fluff/shower_drain, +/turf/open/floor/holofloor{ + base_icon_state = "smooth_half"; + icon_state = "smooth_half"; + dir = 1 + }, +/area/template_noop) +"w" = ( +/turf/open/floor/holofloor{ + icon_state = "smooth_large"; + base_icon_state = "smooth_large" + }, +/area/template_noop) +"x" = ( +/obj/effect/turf_decal/arrows/white{ + dir = 1 + }, +/turf/open/floor/holofloor{ + icon_state = "smooth_large"; + base_icon_state = "smooth_large" + }, +/area/template_noop) +"y" = ( +/obj/structure/rack, +/obj/item/shield/riot{ + pixel_x = 2 + }, +/obj/item/shield/riot{ + pixel_y = 4; + pixel_x = 2 + }, +/obj/item/shield/riot{ + pixel_x = -2 + }, +/obj/item/shield/riot{ + pixel_y = 4; + pixel_x = -2 + }, +/obj/structure/railing{ + dir = 5 + }, +/obj/effect/turf_decal/bot_white, +/turf/open/floor/holofloor{ + icon_state = "smooth_large"; + base_icon_state = "smooth_large" + }, +/area/template_noop) +"B" = ( +/turf/open/floor/holofloor{ + base_icon_state = "smooth_half"; + icon_state = "smooth_half"; + dir = 1 + }, +/area/template_noop) +"C" = ( +/obj/effect/turf_decal/delivery/white, +/obj/item/kirbyplants/random/fullysynthetic, +/turf/open/floor/holofloor{ + icon_state = "smooth_large"; + base_icon_state = "smooth_large" + }, +/area/template_noop) +"D" = ( +/obj/structure/railing{ + dir = 5 + }, +/obj/structure/rack, +/obj/item/storage/medkit/frontier, +/obj/item/storage/box/bandages, +/turf/open/floor/holofloor{ + icon_state = "smooth_large"; + base_icon_state = "smooth_large" + }, +/area/template_noop) +"F" = ( +/obj/effect/turf_decal/caution/white{ + dir = 8 + }, +/turf/open/floor/holofloor{ + base_icon_state = "smooth_half"; + icon_state = "smooth_half"; + dir = 1 + }, +/area/template_noop) +"I" = ( +/obj/effect/turf_decal/loading_area/white{ + dir = 4 + }, +/turf/open/floor/holofloor{ + icon_state = "smooth_large"; + base_icon_state = "smooth_large" + }, +/area/template_noop) +"L" = ( +/obj/effect/turf_decal/bot_white/right, +/turf/open/floor/holofloor{ + icon_state = "smooth_large"; + base_icon_state = "smooth_large" + }, +/area/template_noop) +"M" = ( +/obj/structure/railing{ + dir = 4 + }, +/obj/effect/turf_decal/delivery/white, +/obj/item/kirbyplants/random/fullysynthetic, +/turf/open/floor/holofloor{ + icon_state = "smooth_large"; + base_icon_state = "smooth_large" + }, +/area/template_noop) +"P" = ( +/obj/structure/rack, +/obj/item/shield/riot{ + pixel_x = -2 + }, +/obj/item/shield/riot{ + pixel_y = 4; + pixel_x = -2 + }, +/obj/item/shield/riot{ + pixel_x = 2 + }, +/obj/item/shield/riot{ + pixel_y = 4; + pixel_x = 2 + }, +/obj/structure/railing{ + dir = 6 + }, +/obj/effect/turf_decal/bot_white, +/turf/open/floor/holofloor{ + icon_state = "smooth_large"; + base_icon_state = "smooth_large" + }, +/area/template_noop) +"Q" = ( +/obj/effect/turf_decal/delivery/white, +/obj/structure/reagent_dispensers/water_cooler, +/turf/open/floor/holofloor{ + icon_state = "smooth_large"; + base_icon_state = "smooth_large" + }, +/area/template_noop) +"R" = ( +/obj/structure/railing{ + dir = 4 + }, +/obj/effect/turf_decal/delivery/white, +/obj/structure/closet/boxinggloves, +/turf/open/floor/holofloor{ + icon_state = "smooth_large"; + base_icon_state = "smooth_large" + }, +/area/template_noop) +"W" = ( +/obj/effect/turf_decal/trimline/neutral/warning{ + dir = 6 + }, +/obj/machinery/shower/directional/east, +/obj/structure/fluff/shower_drain, +/turf/open/floor/holofloor{ + base_icon_state = "smooth_half"; + icon_state = "smooth_half"; + dir = 1 + }, +/area/template_noop) +"X" = ( +/obj/structure/railing{ + dir = 6 + }, +/obj/structure/table, +/obj/item/clothing/mask/whistle{ + pixel_y = 7 + }, +/turf/open/floor/holofloor{ + icon_state = "smooth_large"; + base_icon_state = "smooth_large" + }, +/area/template_noop) +"Y" = ( +/obj/effect/turf_decal/tile/dark/half{ + dir = 8 + }, +/obj/effect/turf_decal/trimline/yellow/warning{ + dir = 4 + }, +/turf/open/floor/holofloor{ + base_icon_state = "smooth_half"; + icon_state = "smooth_half"; + dir = 1 + }, +/area/template_noop) + +(1,1,1) = {" +Q +m +o +I +v +W +I +l +m +C +"} +(2,1,1) = {" +q +f +x +n +f +x +n +f +x +q +"} +(3,1,1) = {" +q +B +F +h +e +B +L +F +B +q +"} +(4,1,1) = {" +M +P +r +d +D +X +d +r +y +R +"} +(5,1,1) = {" +k +Y +Y +k +Y +Y +k +Y +Y +k +"} +(6,1,1) = {" +n +f +x +n +f +x +n +f +x +n +"} +(7,1,1) = {" +L +B +B +w +B +B +w +B +B +h +"} +(8,1,1) = {" +n +f +x +n +f +x +n +f +x +n +"} +(9,1,1) = {" +a +c +c +a +c +c +a +c +c +a +"} diff --git a/code/game/machinery/recharger.dm b/code/game/machinery/recharger.dm index 226e19bfe84f1..14198f01409dd 100644 --- a/code/game/machinery/recharger.dm +++ b/code/game/machinery/recharger.dm @@ -18,6 +18,7 @@ /obj/item/ammo_box/magazine/recharge, /obj/item/modular_computer, /obj/item/gun/ballistic/automatic/battle_rifle, + /obj/item/melee/baton/doppler_security, // DOPPLER EDIT ADDITION )) /obj/machinery/recharger/RefreshParts() diff --git a/code/game/objects/structures/crates_lockers/closets/secure/security.dm b/code/game/objects/structures/crates_lockers/closets/secure/security.dm index e4488b0b7f436..b3881326668c9 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/security.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/security.dm @@ -67,7 +67,7 @@ new /obj/item/storage/lockbox/loyalty(src) new /obj/item/storage/box/flashbangs(src) new /obj/item/shield/riot/tele(src) - new /obj/item/storage/belt/security/full(src) + new /obj/item/storage/belt/secsword/full(src) // DOPPLER EDIT - new /obj/item/storage/belt/security/full(src) new /obj/item/circuitboard/machine/techfab/department/security(src) new /obj/item/storage/photo_album/hos(src) @@ -92,7 +92,7 @@ new /obj/item/storage/bag/garment/warden(src) new /obj/item/storage/box/zipties(src) new /obj/item/storage/box/flashbangs(src) - new /obj/item/storage/belt/security/full(src) + new /obj/item/storage/belt/secsword/full(src) // DOPPLER EDIT - new /obj/item/storage/belt/security/full(src) new /obj/item/flashlight/seclite(src) new /obj/item/door_remote/head_of_security(src) @@ -115,7 +115,7 @@ /obj/structure/closet/secure_closet/security/sec/PopulateContents() ..() - new /obj/item/storage/belt/security/full(src) + new /obj/item/storage/belt/secsword/full(src) // DOPPLER EDIT - new /obj/item/storage/belt/security/full(src) /obj/structure/closet/secure_closet/security/cargo diff --git a/modular_doppler/modular_weapons/code/sec_swords/baton.dm b/modular_doppler/modular_weapons/code/sec_swords/baton.dm new file mode 100644 index 0000000000000..27be1e35b6f9e --- /dev/null +++ b/modular_doppler/modular_weapons/code/sec_swords/baton.dm @@ -0,0 +1,175 @@ +/obj/item/melee/baton/doppler_security + name = "electro baton" + desc = "A high power baton for incapacitating humans and similar with. Delivers powerful jolts of electricity \ + that may cause bodily harm, but will -- without a doubt -- entice cooperation." + + desc_controls = "Left Click to stun, Right Click to harm." + context_living_rmb_active = "Harmful Stun" + attack_verb_continuous = list("beats") + attack_verb_simple = list("beat") + + icon = 'modular_doppler/modular_weapons/icons/obj/sec_swords.dmi' + icon_state = "baton_two" + lefthand_file = 'modular_doppler/modular_weapons/icons/mob/inhands/melee_lefthand.dmi' + righthand_file = 'modular_doppler/modular_weapons/icons/mob/inhands/melee_righthand.dmi' + inhand_icon_state = "baton_two" + icon_angle = -20 + + on_stun_sound = 'sound/items/weapons/taserhit.ogg' + on_stun_volume = 50 + drop_sound = 'sound/items/baton/stun_baton_active_drop.ogg' + pickup_sound = 'sound/items/baton/stun_baton_active_pickup.ogg' + sound_vary = TRUE + + active = TRUE + force = 10 + wound_bonus = 0 + armor_type = /datum/armor/baton_security + throwforce = 7 + force_say_chance = 50 + stamina_damage = 35 // DOPPLER EDIT - 4 baton crit now (Original: 60) + knockdown_time = 5 SECONDS + clumsy_knockdown_time = 15 SECONDS + cooldown = 2.5 SECONDS + + var/obj/item/stock_parts/power_store/cell + var/preload_cell_type //if not empty the baton starts with this type of cell + var/cell_hit_cost = STANDARD_CELL_CHARGE + +/obj/item/melee/baton/doppler_security/Initialize(mapload) + . = ..() + if(preload_cell_type) + if(!ispath(preload_cell_type, /obj/item/stock_parts/power_store/cell)) + log_mapping("[src] at [AREACOORD(src)] had an invalid preload_cell_type: [preload_cell_type].") + else + cell = new preload_cell_type(src) + +/obj/item/melee/baton/doppler_security/get_cell() + return cell + +/obj/item/melee/baton/doppler_security/suicide_act(mob/living/user) + if(cell?.charge && active) + user.visible_message(span_suicide("[user] is putting the live [name] right to [user.p_their()] heart! It looks like [user.p_theyre()] trying to commit suicide!")) + attack(user, user) + return FIRELOSS + return + +/obj/item/melee/baton/doppler_security/Destroy() + if(cell) + QDEL_NULL(cell) + UnregisterSignal(src, COMSIG_ATOM_ATTACKBY) + return ..() + +/obj/item/melee/baton/doppler_security/examine(mob/user) + . = ..() + if(cell) + . += span_notice("\The [src] is [round(cell.percent())]% charged.") + else + . += span_warning("\The [src] does not have a power source installed.") + +/obj/item/melee/baton/doppler_security/proc/deductcharge(deducted_charge) + if(!cell) + return + //Note this value returned is significant, as it will determine + //if a stun is applied or not + . = cell.use(deducted_charge) + +/obj/item/melee/baton/doppler_security/clumsy_check(mob/living/carbon/human/user) + if(!active || !HAS_TRAIT(user, TRAIT_CLUMSY) || prob(50)) + return FALSE + user.visible_message(span_danger("[user] accidentally touches the prongs of [src]! Fool they are!"), span_userdanger("You accidentally touch the prongs of [src]!")) + + if(iscyborg(user)) + if(affect_cyborg) + user.flash_act(affect_silicon = TRUE) + user.Paralyze(clumsy_knockdown_time) + additional_effects_cyborg(user, user) // user is the target here + if(on_stun_sound) + playsound(get_turf(src), on_stun_sound, on_stun_volume, TRUE, -1) + else + playsound(get_turf(src), 'sound/items/weapons/taserhit.ogg', 10, TRUE) + else + if(ishuman(user)) + var/mob/living/carbon/human/human_user = user + human_user.force_say() + user.Knockdown(clumsy_knockdown_time) + user.apply_damage(stamina_damage, STAMINA) + additional_effects_non_cyborg(user, user) + if(on_stun_sound) + playsound(get_turf(src), on_stun_sound, on_stun_volume, TRUE, -1) + + user.apply_damage(2 * force, BURN, BODY_ZONE_CHEST, attacking_item = src) + + log_combat(user, user, "accidentally stun attacked [user.p_them()]self due to their clumsiness", src) + if(stun_animation) + user.do_attack_animation(user) + SEND_SIGNAL(user, COMSIG_LIVING_MINOR_SHOCK) + deductcharge(cell_hit_cost) + +/// Handles prodding targets with turned off stunbatons and right clicking stun'n'bash +/obj/item/melee/baton/doppler_security/baton_attack(mob/living/target, mob/living/user, modifiers) + . = ..() + if(. != BATON_DO_NORMAL_ATTACK) + return + if(LAZYACCESS(modifiers, RIGHT_CLICK)) + if(active && cooldown_check <= world.time && !check_parried(target, user)) + finalize_baton_attack(target, user, modifiers, in_attack_chain = FALSE) + else if(!user.combat_mode) + target.visible_message(span_warning("[user] prods [target] with [src]. Luckily it was off."), \ + span_warning("[user] prods you with [src]. Luckily it was off.")) + return BATON_ATTACK_DONE + +/obj/item/melee/baton/doppler_security/baton_effect(mob/living/target, mob/living/user, modifiers, stun_override) + if(iscyborg(loc)) + var/mob/living/silicon/robot/robot = loc + if(!robot || !robot.cell || !robot.cell.use(cell_hit_cost)) + return FALSE + else if(!deductcharge(cell_hit_cost)) + return FALSE + stun_override = 0 //Avoids knocking people down prematurely. + return ..() + +/obj/item/melee/baton/doppler_security/additional_effects_non_cyborg(mob/living/target, mob/living/user) + target.set_jitter_if_lower(40 SECONDS) + target.set_stutter_if_lower(16 SECONDS) + if(iscarbon(target)) + var/mob/living/carbon/big_shocker = target + big_shocker.electrocute_act(10, src, 1, jitter_time = 0 SECONDS, stutter_time = 0 SECONDS, stun_duration = 0 SECONDS) + else + target.electrocute_act(10, src, 1) + SEND_SIGNAL(target, COMSIG_LIVING_MINOR_SHOCK) + addtimer(CALLBACK(src, PROC_REF(apply_stun_effect_end), target), 2 SECONDS) + +/// After the initial stun period, we check to see if the target needs to have the stun applied. +/obj/item/melee/baton/doppler_security/proc/apply_stun_effect_end(mob/living/target) + var/trait_check = HAS_TRAIT(target, TRAIT_BATON_RESISTANCE) //var since we check it in out to_chat as well as determine stun duration + if(!target.IsKnockdown()) + to_chat(target, span_warning("Your muscles seize, making you collapse[trait_check ? ", but your body quickly recovers..." : "!"]")) + + if(!trait_check) + target.Knockdown(knockdown_time) + +/obj/item/melee/baton/doppler_security/get_wait_description() + return span_danger("The baton is still charging!") + +/obj/item/melee/baton/doppler_security/get_stun_description(mob/living/target, mob/living/user) + . = list() + + .["visible"] = span_danger("[user] shocks [target] with [src]!") + .["local"] = span_userdanger("[user] shocks you with [src]!") + +/obj/item/melee/baton/doppler_security/get_unga_dunga_cyborg_stun_description(mob/living/target, mob/living/user) + . = list() + + .["visible"] = span_danger("[user] tries to shock [target] with [src], and predictably fails!") + .["local"] = span_userdanger("[user] tries to... shock you with [src]?") + +/obj/item/melee/baton/doppler_security/emp_act(severity) + . = ..() + if (!cell) + return + if (!(. & EMP_PROTECT_SELF)) + deductcharge(STANDARD_CELL_CHARGE / severity) + +/obj/item/melee/baton/doppler_security/loaded //this one starts with a cell pre-installed. + preload_cell_type = /obj/item/stock_parts/power_store/cell/high diff --git a/modular_doppler/modular_weapons/code/sec_swords/big_sword.dm b/modular_doppler/modular_weapons/code/sec_swords/big_sword.dm new file mode 100644 index 0000000000000..4ce45b2d631fc --- /dev/null +++ b/modular_doppler/modular_weapons/code/sec_swords/big_sword.dm @@ -0,0 +1,49 @@ +/obj/item/melee/secblade + name = "security shortblade" + desc = "A utilitarian weapon, handle and blade, with little more. \ + Designed for ease of blade replacement when it inevitably breaks due to mistreatment." + + icon = 'modular_doppler/modular_weapons/icons/obj/sec_swords.dmi' + icon_state = "sec_sword" + lefthand_file = 'modular_doppler/modular_weapons/icons/mob/inhands/melee_lefthand.dmi' + righthand_file = 'modular_doppler/modular_weapons/icons/mob/inhands/melee_righthand.dmi' + inhand_icon_state = "sec_sword" + icon_angle = -20 + + hitsound = 'sound/items/weapons/bladeslice.ogg' + block_sound = 'sound/items/weapons/parry.ogg' + + obj_flags = CONDUCTS_ELECTRICITY + sharpness = SHARP_EDGED + w_class = WEIGHT_CLASS_BULKY + obj_flags = UNIQUE_RENAME + + force = 18 + throwforce = 10 + block_chance = 1 // Nah, I'd win + wound_bonus = 0 + bare_wound_bonus = 20 + + attack_verb_continuous = list("attacks", "slashes", "slices", "tears", "lacerates", "rips", "dices", "rends") + attack_verb_simple = list("attack", "slash", "slice", "tear", "lacerate", "rip", "dice", "rend") + + var/list/alt_continuous = list("stabs", "pierces", "impales") + var/list/alt_simple = list("stab", "pierce", "impale") + +/obj/item/melee/secblade/Initialize(mapload) + . = ..() + AddComponent(/datum/component/butchering, speed = 4 SECONDS, effectiveness = 100) + alt_continuous = string_list(alt_continuous) + alt_simple = string_list(alt_simple) + AddComponent(/datum/component/alternative_sharpness, SHARP_POINTY, alt_continuous, alt_simple, -5) + +/obj/item/melee/secblade/training + name = "training shortblade" + desc = "A utilitarian weapon, handle and blade, with little more. \ + This one doesn't seem completely real, incapable of bloodshed but likely still hurts quite a lot." + + icon_state = "training_sword" + + damtype = STAMINA + wound_bonus = -50 + bare_wound_bonus = -50 diff --git a/modular_doppler/modular_weapons/code/sec_swords/holodeck_trainer.dm b/modular_doppler/modular_weapons/code/sec_swords/holodeck_trainer.dm new file mode 100644 index 0000000000000..1f2eab3526d7d --- /dev/null +++ b/modular_doppler/modular_weapons/code/sec_swords/holodeck_trainer.dm @@ -0,0 +1,4 @@ +/datum/map_template/holodeck/doppler_sword_trainer + name = "Holodeck - Shortblade Trainer" + template_id = "holodeck_doppler_sword_trainer" + mappath = "_maps/templates/holodeck_doppler_sword_trainer.dmm" diff --git a/modular_doppler/modular_weapons/code/sec_swords/sheath.dm b/modular_doppler/modular_weapons/code/sec_swords/sheath.dm new file mode 100644 index 0000000000000..aa070c9405d3c --- /dev/null +++ b/modular_doppler/modular_weapons/code/sec_swords/sheath.dm @@ -0,0 +1,109 @@ +/obj/item/storage/belt/secsword + name = "security weapons sheath" + desc = "A large block of metal made for safely holding on to a shortblade and matching electro baton, \ + along with the rest of an officer's security equipment." + icon = 'modular_doppler/modular_weapons/icons/obj/sec_swords.dmi' + icon_state = "swordcase" + base_icon_state = "swordcase" + worn_icon = 'modular_doppler/modular_weapons/icons/mob/worn/cases.dmi' + worn_icon_state = "swordcase" + w_class = WEIGHT_CLASS_BULKY + interaction_flags_click = parent_type::interaction_flags_click | NEED_DEXTERITY | NEED_HANDS + obj_flags = UNIQUE_RENAME + +/obj/item/storage/belt/secsword/Initialize(mapload) + . = ..() + AddElement(/datum/element/update_icon_updates_onmob) + + atom_storage.max_slots = 5 + atom_storage.do_rustle = FALSE + atom_storage.max_specific_storage = WEIGHT_CLASS_BULKY + atom_storage.max_total_storage = (WEIGHT_CLASS_BULKY + (WEIGHT_CLASS_NORMAL * 4)) // One sword four other things + atom_storage.set_holdable(list( + /obj/item/ammo_box, + /obj/item/ammo_casing/shotgun, + /obj/item/assembly/flash/handheld, + /obj/item/clothing/glasses, + /obj/item/clothing/gloves, + /obj/item/flashlight/seclite, + /obj/item/food/donut, + /obj/item/grenade, + /obj/item/holosign_creator/security, + /obj/item/knife/combat, + /obj/item/melee/baton, + /obj/item/radio, + /obj/item/reagent_containers/spray/pepper, + /obj/item/restraints/handcuffs, + /obj/item/restraints/legcuffs/bola, + /obj/item/melee/secblade, + )) + atom_storage.open_sound = 'sound/items/handling/holster_open.ogg' + atom_storage.open_sound_vary = TRUE + +/obj/item/storage/belt/secsword/examine(mob/user) + . = ..() + if(length(contents)) + . += span_notice("Left Click to draw a stored blade, Right Click to draw a stored baton while wearing.") + +/obj/item/storage/belt/secsword/attack_hand(mob/user, list/modifiers) + if(!(user.get_slot_by_item(src) & ITEM_SLOT_BELT)) + return ..() + for(var/obj/item/melee/secblade/blade_runner in contents) + user.visible_message(span_notice("[user] draws [blade_runner] from [src]."), span_notice("You draw [blade_runner] from [src].")) + user.put_in_hands(blade_runner) + playsound(user, 'sound/items/sheath.ogg', 50, TRUE) + update_appearance() + return + return ..() + +/obj/item/storage/belt/secsword/attack_hand_secondary(mob/user, list/modifiers) + if(!(user.get_slot_by_item(src) & ITEM_SLOT_BELT)) + return ..() + for(var/obj/item/melee/baton/doppler_security/simply_shocking in contents) + user.visible_message(span_notice("[user] draws [simply_shocking] from [src]."), span_notice("You draw [simply_shocking] from [src].")) + user.put_in_hands(simply_shocking) + playsound(user, 'sound/items/sheath.ogg', 50, TRUE) + update_appearance() + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + return ..() + +/obj/item/storage/belt/secsword/update_icon_state() + var/has_sword = FALSE + var/has_baton = FALSE + for(var/obj/thing in contents) + if(has_baton && has_sword) + break + if(istype(thing, /obj/item/melee/baton/doppler_security)) + has_baton = TRUE + if(istype(thing, /obj/item/melee/secblade)) + has_sword = TRUE + + icon_state = initial(icon_state) + worn_icon_state = initial(worn_icon_state) + + var/next_appendage + if(has_sword && has_baton) + next_appendage = "-full" + else if(has_sword) + next_appendage = "-blayde" + else if(has_baton) + next_appendage = "-stun" + + if(next_appendage) + icon_state += next_appendage + worn_icon_state += next_appendage + return ..() + +/obj/item/storage/belt/secsword/full/PopulateContents() + new /obj/item/melee/secblade(src) + new /obj/item/melee/baton/doppler_security/loaded(src) + new /obj/item/restraints/handcuffs(src) + new /obj/item/reagent_containers/spray/pepper(src) + new /obj/item/assembly/flash/handheld(src) + update_appearance() + +/obj/item/storage/belt/secsword/training/PopulateContents() + new /obj/item/melee/secblade/training(src) // No way attack on titan + new /obj/item/melee/secblade/training(src) + new /obj/item/melee/baton/doppler_security/loaded(src) + update_appearance() diff --git a/modular_doppler/modular_weapons/icons/mob/inhands/melee_lefthand.dmi b/modular_doppler/modular_weapons/icons/mob/inhands/melee_lefthand.dmi new file mode 100644 index 0000000000000..d7263232529c3 Binary files /dev/null and b/modular_doppler/modular_weapons/icons/mob/inhands/melee_lefthand.dmi differ diff --git a/modular_doppler/modular_weapons/icons/mob/inhands/melee_righthand.dmi b/modular_doppler/modular_weapons/icons/mob/inhands/melee_righthand.dmi new file mode 100644 index 0000000000000..41680f8b2fe38 Binary files /dev/null and b/modular_doppler/modular_weapons/icons/mob/inhands/melee_righthand.dmi differ diff --git a/modular_doppler/modular_weapons/icons/mob/worn/cases.dmi b/modular_doppler/modular_weapons/icons/mob/worn/cases.dmi index f029c2956292f..eea1dd5794f4a 100644 Binary files a/modular_doppler/modular_weapons/icons/mob/worn/cases.dmi and b/modular_doppler/modular_weapons/icons/mob/worn/cases.dmi differ diff --git a/modular_doppler/modular_weapons/icons/obj/sec_swords.dmi b/modular_doppler/modular_weapons/icons/obj/sec_swords.dmi new file mode 100644 index 0000000000000..adfbab70fd885 Binary files /dev/null and b/modular_doppler/modular_weapons/icons/obj/sec_swords.dmi differ diff --git a/modular_doppler/time_clock/code/console_tgui.dm b/modular_doppler/time_clock/code/console_tgui.dm index a6734b54ee55d..f19069b9305df 100644 --- a/modular_doppler/time_clock/code/console_tgui.dm +++ b/modular_doppler/time_clock/code/console_tgui.dm @@ -2,8 +2,11 @@ #define TIME_CLOCK_RETURN_ITEMS list( \ /obj/item/melee/baton/security, \ /obj/item/melee/baton/security/loaded, \ + /obj/item/melee/baton/doppler_security, \ + /obj/item/melee/baton/doppler_security/loaded, \ /obj/item/melee/baton/telescopic, \ /obj/item/melee/baton, \ + /obj/item/melee/secblade, \ /obj/item/assembly/flash/handheld, \ /obj/item/gun/energy/disabler, \ /obj/item/megaphone/command, \ @@ -25,6 +28,7 @@ /obj/item/clothing/shoes/magboots/advance, \ /obj/item/shield/riot/tele, \ /obj/item/storage/belt/security/full, \ + /obj/item/storage/belt/secsword/full, \ /obj/item/gun/energy/e_gun/hos, \ /obj/item/pinpointer/nuke, \ /obj/item/gun/energy/e_gun, \ diff --git a/tgstation.dme b/tgstation.dme index 73aa5a0c84765..d96b19a59796d 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -7173,6 +7173,10 @@ #include "modular_doppler\modular_weapons\code\gunsets.dm" #include "modular_doppler\modular_weapons\code\jousting.dm" #include "modular_doppler\modular_weapons\code\melee.dm" +#include "modular_doppler\modular_weapons\code\sec_swords\baton.dm" +#include "modular_doppler\modular_weapons\code\sec_swords\big_sword.dm" +#include "modular_doppler\modular_weapons\code\sec_swords\holodeck_trainer.dm" +#include "modular_doppler\modular_weapons\code\sec_swords\sheath.dm" #include "modular_doppler\modular_weapons\company_and_or_faction_based\carwo_defense_systems\gunsets.dm" #include "modular_doppler\modular_weapons\manufacturer_examine\code\gun_company_additions.dm" #include "modular_doppler\modular_weapons\manufacturer_examine\code\manufacturer_element.dm"