Early ports modular lasers from Nova, they can talk to you! (#1066)

## About The Pull Request

Description was copy pasted from Nova
[PR#561](https://github.com/NovaSector/NovaSector/pull/561)


![image](https://github.com/Bubberstation/Bubberstation/assets/81807356/aff45752-00bd-4a96-8748-35b37544a1fc)

These new weapons, the modular energy rifles and carbines, have many
unique functions.

Each of the two weapon types has its own collection of modes, each
mostly unique from the other version of the gun.

For the long rifle, these include:

Two-burst laser mode
Sniper mode with massive scope
Windup autofire disabler machinegun
Plasma grenade launcher
Plasma shotgun
And for the short carbine these include:

Hellfire laser mode
Its A Sword Now
Trickshot disabler mode
Plasma flare launcher
Micro-shotgun
Each of the two can switch between these modes with a short delay and
animation, though all modes run off of the same battery. Luckily, the
battery does self-recharge, though at a very slow rate.

But there's something even better for these weapons, they talk to you.
Each mode and each variant of energy gun has its own little personality
with it, and it'll talk to you when certain things happen. For example,
switching modes, running out of power, picking them up, and more!

While this can be disabled, that would make the persona in the gun quite
sad. You wouldn't want to do that, would you?

But, and I swear this is the last thing this time. Each of these guns
has a built in soulcatcher (you can access it with alt-click!) for
giving your weapons some REAL personality. And now you observer mains
can finally live out your dreams of being someone's weapon!

## Why It's Good For The Game

Im going to replace ERT energy weapons with these guns, author of this
weapons originaly replaced MCR's with these. Perhps if people will want
to, I can replace mcrs with these....

## Proof Of Testing
<details>



![image](https://github.com/Bubberstation/Bubberstation/assets/81807356/146723e4-475a-4f7a-b5e5-3d6c6568753f)


https://github.com/Bubberstation/Bubberstation/assets/81807356/a6a8c8a2-f3ee-4b30-97e2-580e42f2ae56


https://github.com/Bubberstation/Bubberstation/assets/81807356/c560e26b-5d27-493a-b067-01957e4bb81a


https://github.com/Bubberstation/Bubberstation/assets/81807356/7a36eed6-45a7-42b4-af56-cb6022f15204


</details>

## Changelog

🆑 Paxilmaniac
add: A pair of new energy weapons has been added. Coming in both long
and short versions, these persona-enabled weapons have many different
modes they can rapidly reconfigure themselves between to fit whatever
the operator's preferences may be.
/🆑

---------

Co-authored-by: The Sharkening <95130227+StrangeWeirdKitten@users.noreply.github.com>
Co-authored-by: Waterpig <49160555+Majkl-J@users.noreply.github.com>
This commit is contained in:
Erol509
2024-05-10 20:26:50 +02:00
committed by GitHub
co-authored by The Sharkening Waterpig
parent d73401867c
commit 4a1b699b85
20 changed files with 998 additions and 0 deletions
@@ -8,6 +8,7 @@
#define COMPANY_CARWO "It has a small <b>[span_cyan("four pointed star")]</b> alongside <b>[span_cyan("Carwo Defense Systems")]</b> etched into it."
#define COMPANY_TRAPPISTE "It has a small <b>[span_red("pattern of five squares")]</b> alongside <b>[span_red("Trappiste Fabriek")]</b> etched into it."
#define COMPANY_CYBERSUN "It has a <b>[span_red("red circle")]</b> broken by a <b>hexagonal flower</b> alongside <b>[span_red("Cybersun Industries")]</b> in Konjin etched into it." // Bubberstation edit modular weapons saisaban
#define COMPANY_SCARBOROUGH "It has <b>[span_orange("Scarborough Arms")]</b> stamped onto it."
#define COMPANY_INTERDYNE "It has <b>[span_cyan("Interdyne Pharmaceuticals")]</b> stamped onto it."
@@ -0,0 +1,12 @@
/datum/outfit/centcom/ert/security
l_hand = /obj/item/gun/energy/modular_laser_rifle/carbine
/datum/outfit/centcom/ert/medic
r_hand = /obj/item/gun/energy/modular_laser_rifle/carbine
/datum/outfit/centcom/ert/engineer
l_hand = /obj/item/gun/energy/modular_laser_rifle/carbine
/datum/outfit/centcom/ert/commander
l_hand = /obj/item/gun/energy/modular_laser_rifle
@@ -0,0 +1,295 @@
/// File location for the long gun's speech
#define LONG_MOD_LASER_SPEECH "saibasan/long_modular_laser.json"
/// File location for the short gun's speech
#define SHORT_MOD_LASER_SPEECH "saibasan/short_modular_laser.json"
/// How long the gun should wait between speaking to lessen spam
#define MOD_LASER_SPEECH_COOLDOWN 2 SECONDS
/// What color is the default kill mode for these guns, used to make sure the chat colors are right at roundstart
#define DEFAULT_RUNECHAT_GUN_COLOR "#cd4456"
// Modular energy weapons, laser guns that can transform into different variants after a few seconds of waiting and animation
// Long version, takes both hands to use and doesn't fit in any bags out there
/obj/item/gun/energy/modular_laser_rifle
name = "\improper Hyeseong modular laser rifle"
desc = "A popular energy weapon system that can be reconfigured into many different variants on the fly. \
Seen commonly amongst the Marsians who produce the weapon, with many different shapes and sizes to fit \
the wide variety of modders the planet is home to."
base_icon_state = "hyeseong"
icon = 'modular_zubbers/modules/modular_weapons/icons/obj/company_and_or_faction_based/saibasan/guns48x.dmi'
icon_state = "hyeseong_kill"
lefthand_file = 'modular_zubbers/modules/modular_weapons/icons/mob/company_and_or_faction_based/saibasan/guns_lefthand.dmi'
righthand_file = 'modular_zubbers/modules/modular_weapons/icons/mob/company_and_or_faction_based/saibasan/guns_righthand.dmi'
inhand_icon_state = "hyeseong_kill"
worn_icon = 'modular_zubbers/modules/modular_weapons/icons/mob/company_and_or_faction_based/saibasan/guns_worn.dmi'
worn_icon_state = "hyeseong_kill"
cell_type = /obj/item/stock_parts/cell/hyeseong_internal_cell
modifystate = FALSE
ammo_type = list(/obj/item/ammo_casing/energy/cybersun_big_kill)
can_select = FALSE
ammo_x_offset = 0
selfcharge = 1
charge_delay = 15
shaded_charge = TRUE
slot_flags = ITEM_SLOT_BACK
obj_flags = UNIQUE_RENAME
SET_BASE_PIXEL(-8, 0)
w_class = WEIGHT_CLASS_BULKY
weapon_weight = WEAPON_HEAVY
actions_types = list(/datum/action/item_action/toggle_personality)
fire_sound_volume = 50
recoil = 0.25 // This isn't enough to mean ANYTHING aside from it jolting your screen the tiniest amount
/// What datums of weapon modes can we use?
var/list/weapon_mode_options = list(
/datum/laser_weapon_mode,
/datum/laser_weapon_mode/marksman,
/datum/laser_weapon_mode/disabler_machinegun,
/datum/laser_weapon_mode/launcher,
/datum/laser_weapon_mode/shotgun,
)
/// Populates with a list of weapon mode names and their respective paths on init
var/list/weapon_mode_name_to_path = list()
/// Info for the radial menu for switching weapon mode
var/list/radial_menu_data = list()
/// Is the gun currently changing types? Prevents the gun from firing if yes
var/currently_switching_types = FALSE
/// How long transitioning takes before you're allowed to pick a weapon type
var/transition_duration = 1 SECONDS
/// What the currently selected weapon mode is, for quickly referencing for use in procs and whatnot
var/datum/laser_weapon_mode/currently_selected_mode
/// Name of the firing mode that is selected by default
var/default_selected_mode = "Kill"
/// Allows firing of the gun to be disabled for any reason, for example, if a gun has a melee mode
var/disabled_for_other_reasons = FALSE
/// The json file this gun pulls from when speaking
var/speech_json_file = LONG_MOD_LASER_SPEECH
/// Keeps track of the last processed charge, prevents message spam
var/last_charge = 0
/// If the gun's personality speech thing is on, defaults to on because just listen to her
var/personality_mode = TRUE
/// Keeps track of our soulcatcher component
var/datum/component/carrier/soulcatcher/tracked_soulcatcher
/// What is this gun's extended examine, we only have to do this because the carbine is a subtype
var/expanded_examine_text = "The Hyeseong rifle is the first line of man-portable Marsian weapons platforms \
from Cybersun Industries. Like her younger sister weapon, the Hoshi carbine, CI used funding aid provided \
by SolFed to develop a portable weapon fueled by a proprietary generator rumored to be fueled by superstable plasma. \
A rugged and hefty weapon, the Hyeseong stars in applications anywhere from medium to long ranges, though struggling \
in CQB. Her onboard machine intelligence, at first devised to support the operator and manage the internal reactor, \
is shipped with a more professional and understated personality-- since influenced by 'negligence' from users in \
wiping the intelligence's memory before resale or transport."
/// A cooldown for when the weapon has last spoken, prevents messages from getting turbo spammed
COOLDOWN_DECLARE(last_speech)
/obj/item/gun/energy/modular_laser_rifle/Initialize(mapload)
. = ..()
AddElement(/datum/element/manufacturer_examine, COMPANY_CYBERSUN)
chat_color = DEFAULT_RUNECHAT_GUN_COLOR
chat_color_darkened = process_chat_color(DEFAULT_RUNECHAT_GUN_COLOR, sat_shift = 0.85, lum_shift = 0.85)
last_charge = cell.charge
tracked_soulcatcher = AddComponent(/datum/component/carrier/soulcatcher/modular_laser)
create_weapon_mode_stuff()
voice = null
/obj/item/gun/energy/modular_laser_rifle/examine(mob/user)
. = ..()
. += span_notice("You can <b>examine closer</b> to learn a little more about this weapon.")
. += span_notice("You can <b>Alt-Click</b> this gun to access the <b>internal soulcatcher</b>.")
/obj/item/gun/energy/modular_laser_rifle/examine_more(mob/user)
. = ..()
. += expanded_examine_text
return .
/obj/item/gun/energy/modular_laser_rifle/Destroy()
QDEL_NULL(tracked_soulcatcher)
return ..()
/obj/item/gun/energy/modular_laser_rifle/click_alt(mob/user)
. = ..()
tracked_soulcatcher?.ui_interact(user)
/// Handles filling out all of the lists regarding weapon modes and radials around that
/obj/item/gun/energy/modular_laser_rifle/proc/create_weapon_mode_stuff()
if(length(weapon_mode_name_to_path) || length(radial_menu_data))
return // We don't need to worry about it if there's already stuff here
for(var/datum/laser_weapon_mode/laser_mode as anything in weapon_mode_options)
weapon_mode_name_to_path["[initial(laser_mode.name)]"] = new laser_mode()
var/obj/projectile/mode_projectile = initial(laser_mode.casing.projectile_type)
radial_menu_data["[initial(laser_mode.name)]"] = image(icon = mode_projectile.icon, icon_state = mode_projectile.icon_state)
currently_selected_mode = weapon_mode_name_to_path["[default_selected_mode]"]
transform_gun(currently_selected_mode, FALSE, TRUE)
/obj/item/gun/energy/modular_laser_rifle/attack_self(mob/living/user)
if(!currently_switching_types)
change_to_switch_mode(user)
return ..()
/// Makes the gun inoperable, playing an animation and giving a prompt to switch gun modes after the transition_duration passes
/obj/item/gun/energy/modular_laser_rifle/proc/change_to_switch_mode(mob/living/user)
currently_switching_types = TRUE
flick("[base_icon_state]_switch_on", src)
cut_overlays()
playsound(src, 'sound/items/modsuit/ballin.ogg', 75, TRUE)
var/new_icon_state = "[base_icon_state]_switch"
icon_state = new_icon_state
inhand_icon_state = new_icon_state
worn_icon_state = new_icon_state
addtimer(CALLBACK(src, PROC_REF(show_radial_choice_menu), user), transition_duration)
/// Shows the radial choice menu to the user, if the user doesnt exist or isnt holding the gun anymore, it reverts back to its last form
/obj/item/gun/energy/modular_laser_rifle/proc/show_radial_choice_menu(mob/living/user)
if(!user?.is_holding(src))
flick("[base_icon_state]_switch_off", src)
transform_gun(currently_selected_mode, FALSE)
playsound(src, 'sound/items/modsuit/ballout.ogg', 75, TRUE)
return
var/picked_choice = show_radial_menu(
user,
src,
radial_menu_data,
require_near = TRUE,
tooltips = TRUE,
)
if(isnull(picked_choice) || isnull(weapon_mode_name_to_path["[picked_choice]"]))
flick("[base_icon_state]_switch_off", src)
transform_gun(currently_selected_mode, FALSE)
playsound(src, 'sound/items/modsuit/ballout.ogg', 75, TRUE)
return
var/new_weapon_mode = weapon_mode_name_to_path["[picked_choice]"]
transform_gun(new_weapon_mode, TRUE)
/// Transforms the gun into a different type, if replacing is set to true then it'll make sure to remove any effects the prior gun type had
/obj/item/gun/energy/modular_laser_rifle/proc/transform_gun(datum/laser_weapon_mode/new_weapon_mode, replacing = TRUE, dont_speak = FALSE)
if(!new_weapon_mode)
stack_trace("transform_gun was called but didn't get a new weapon mode, meaning it couldn't work.")
return
if(replacing)
currently_selected_mode.remove_from_weapon(src)
currently_selected_mode = new_weapon_mode
flick("[base_icon_state]_switch_off", src)
currently_selected_mode.apply_stats(src)
currently_selected_mode.apply_to_weapon(src)
playsound(src, 'sound/items/modsuit/ballout.ogg', 75, TRUE)
if(!dont_speak)
speak_up(currently_selected_mode.json_speech_string, TRUE)
currently_switching_types = FALSE
/obj/item/gun/energy/modular_laser_rifle/can_shoot()
if(!length(ammo_type))
return FALSE
return ..()
/obj/item/gun/energy/modular_laser_rifle/can_trigger_gun(mob/living/user, akimbo_usage)
. = ..()
if(currently_switching_types || disabled_for_other_reasons)
return FALSE
/// Makes the gun speak with a sound effect and colored runetext based on the mode the gun is in, reads the gun's speech json as defined through variables
/obj/item/gun/energy/modular_laser_rifle/proc/speak_up(json_string, ignores_cooldown = FALSE, ignores_personality_toggle = FALSE)
if(!personality_mode && !ignores_personality_toggle)
return
if(!json_string)
return
if(!ignores_cooldown && !COOLDOWN_FINISHED(src, last_speech))
return
say(pick_list_replacements(speech_json_file, json_string))
playsound(src, 'sound/creatures/tourist/tourist_talk.ogg', 15, TRUE, SHORT_RANGE_SOUND_EXTRARANGE, frequency = rand(2, 2.2))
Shake(2, 2, 1 SECONDS)
COOLDOWN_START(src, last_speech, MOD_LASER_SPEECH_COOLDOWN)
/obj/item/gun/energy/modular_laser_rifle/equipped(mob/user, slot, initial)
. = ..()
if(slot & (ITEM_SLOT_BELT|ITEM_SLOT_BACK|ITEM_SLOT_SUITSTORE))
speak_up("worn")
else if(slot & ITEM_SLOT_HANDS)
RegisterSignal(user, COMSIG_MOB_CI_TOGGLED, PROC_REF(user_ci_toggled))
speak_up("pickup")
return
UnregisterSignal(user, COMSIG_MOB_CI_TOGGLED)
/obj/item/gun/energy/modular_laser_rifle/dropped(mob/user, silent)
. = ..()
if(src in user.contents)
return // If they're still holding us or have us on them, dw about it
UnregisterSignal(user, COMSIG_MOB_CI_TOGGLED)
speak_up("putdown")
/obj/item/gun/energy/modular_laser_rifle/process(seconds_per_tick)
. = ..()
var/cell_charge_quarter = cell.maxcharge / 4
if((cell_charge_quarter > cell.charge) && !(last_charge < cell_charge_quarter))
speak_up("lowcharge")
else if((cell.maxcharge == cell.charge) && !(last_charge == cell.maxcharge))
speak_up("fullcharge")
last_charge = cell.charge
/// Triggers when a mob user toggles CI
/obj/item/gun/energy/modular_laser_rifle/proc/user_ci_toggled(mob/living/source)
if(source.combat_indicator)
speak_up("combatmode")
/obj/item/gun/energy/modular_laser_rifle/ui_action_click(mob/user, actiontype)
if(!istype(actiontype, /datum/action/item_action/toggle_personality))
return ..()
playsound(src, 'sound/machines/beep.ogg', 30, TRUE)
personality_mode = !personality_mode
speak_up("[personality_mode ? "pickup" : "putdown"]", ignores_personality_toggle = TRUE)
return ..()
// Power cell for the big rifle
/obj/item/stock_parts/cell/hyeseong_internal_cell
name = "\improper Hyeseong modular laser rifle internal cell"
desc = "These are usually supposed to be inside of the gun, you know."
maxcharge = STANDARD_CELL_CHARGE * 2
/datum/action/item_action/toggle_personality
name = "Toggle Weapon Personality"
desc = "Toggles the weapon's personality core. Studies find that turning them off makes them quite sad, however."
background_icon_state = "bg_mod"
/datum/component/carrier/soulcatcher/modular_laser
max_mobs = 1
communicate_as_parent = TRUE
//Short version of the above modular rifle, has less charge and different modes
/obj/item/gun/energy/modular_laser_rifle/carbine
name = "\improper Hoshi modular laser carbine"
icon = 'modular_zubbers/modules/modular_weapons/icons/obj/company_and_or_faction_based/saibasan/guns32x.dmi'
icon_state = "hoshi_kill"
inhand_icon_state = "hoshi_kill"
worn_icon_state = "hoshi_kill"
base_icon_state = "hoshi"
charge_sections = 3
cell_type = /obj/item/stock_parts/cell
ammo_type = list(/obj/item/ammo_casing/energy/cybersun_small_hellfire)
slot_flags = ITEM_SLOT_BACK | ITEM_SLOT_BELT
SET_BASE_PIXEL(0, 0)
w_class = WEIGHT_CLASS_NORMAL
weapon_weight = WEAPON_MEDIUM
weapon_mode_options = list(
/datum/laser_weapon_mode/hellfire,
/datum/laser_weapon_mode/sword,
/datum/laser_weapon_mode/flare,
/datum/laser_weapon_mode/shotgun_small,
/datum/laser_weapon_mode/trickshot_disabler,
)
default_selected_mode = "Incinerate"
speech_json_file = SHORT_MOD_LASER_SPEECH
expanded_examine_text = "The Hoshi carbine is the latest line of man-portable Marsian weapons platforms from \
Cybersun Industries. Like her older sister weapon, the Hyeseong rifle, CI used funding aid provided by SolFed \
to develop a portable weapon fueled by a proprietary generator rumored to be fueled by superstable plasma. A \
lithe and mobile weapon, the Hoshi stars in close-quarters battle, trickshots, and area-of-effect blasts; though \
ineffective at ranged combat. Her onboard machine intelligence, at first devised to support the operator and \
manage the internal reactor, was originally shipped with a more energetic personality-- since influenced by 'negligence' \
from users in wiping the intelligence's memory before resale or transport."
/obj/item/gun/energy/modular_laser_rifle/carbine/emp_act(severity)
. = ..()
speak_up("emp", TRUE) // She gets very upset if you emp her
#undef LONG_MOD_LASER_SPEECH
#undef SHORT_MOD_LASER_SPEECH
#undef MOD_LASER_SPEECH_COOLDOWN
#undef DEFAULT_RUNECHAT_GUN_COLOR
@@ -0,0 +1,206 @@
// Yeah I'm using datums for this, because the code on a regular gun would suck huge
// Holds a lot of information that will be applied ot the gun, as well as info that the gun will read later
// This basetype is applies to the base 2 burst laser kill mode for the large laser gun
/datum/laser_weapon_mode
/// What name does this weapon mode have? Will appear in the weapon's radial menu
var/name = "Kill"
/// What casing does this variant of weapon use?
var/obj/item/ammo_casing/casing = /obj/item/ammo_casing/energy/cybersun_big_kill
/// What icon_state does this weapon mode use?
var/weapon_icon_state = "kill"
/// How many charge sections does this variant of weapon have?
var/charge_sections = 5
/// What is the shot cooldown this variant applies to the weapon?
var/shot_delay = 0.3 SECONDS
/// What json string do we check for when making chat messages with this mode?
var/json_speech_string = "kill"
/// What do we change the gun's runetext color to when applied
var/gun_runetext_color = "#cd4456"
/// Applies some of the universal stats from the variables above
/datum/laser_weapon_mode/proc/apply_stats(obj/item/gun/energy/applied_gun)
if(length(applied_gun.ammo_type))
for(var/found_casing as anything in applied_gun.ammo_type)
applied_gun.ammo_type.Remove(found_casing)
qdel(found_casing)
applied_gun.ammo_type.Add(casing)
applied_gun.update_ammo_types()
applied_gun.charge_sections = charge_sections
applied_gun.fire_delay = shot_delay
var/new_icon_state = "[applied_gun.base_icon_state]_[weapon_icon_state]"
applied_gun.icon_state = new_icon_state
applied_gun.inhand_icon_state = new_icon_state
applied_gun.worn_icon_state = new_icon_state
applied_gun.update_appearance()
applied_gun.chat_color = gun_runetext_color
applied_gun.chat_color_darkened = process_chat_color(gun_runetext_color, sat_shift = 0.85, lum_shift = 0.85)
/// Stuff applied to the passed gun when the weapon mode is given to the gun
/datum/laser_weapon_mode/proc/apply_to_weapon(obj/item/gun/energy/applied_gun)
applied_gun.burst_size = 2
/// Stuff applied to the passed gun when the weapon mode is removed from the gun
/datum/laser_weapon_mode/proc/remove_from_weapon(obj/item/gun/energy/applied_gun)
applied_gun.burst_size = 1
// Marksman mode for the large laser, adds a scope, slower firing rate, and really quick projectiles
/datum/laser_weapon_mode/marksman
name = "Marksman"
casing = /obj/item/ammo_casing/energy/cybersun_big_sniper
weapon_icon_state = "sniper"
shot_delay = 2 SECONDS
json_speech_string = "sniper"
gun_runetext_color = "#f8d860"
/// Keeps track of the scope component for deleting later
var/datum/component/scope/scope_component
/datum/laser_weapon_mode/marksman/apply_to_weapon(obj/item/gun/energy/applied_gun)
scope_component = applied_gun.AddComponent(/datum/component/scope, 3)
/datum/laser_weapon_mode/marksman/remove_from_weapon(obj/item/gun/energy/applied_gun)
QDEL_NULL(scope_component)
// Windup autofire disabler mode for the large laser
/datum/laser_weapon_mode/disabler_machinegun
name = "Disable"
casing = /obj/item/ammo_casing/energy/cybersun_big_disabler
weapon_icon_state = "disabler"
charge_sections = 2
shot_delay = 0.25 SECONDS
json_speech_string = "disable"
gun_runetext_color = "#47a1b3"
/// Keeps track of the autofire component for deleting later
var/datum/component/automatic_fire/autofire_component
/datum/laser_weapon_mode/disabler_machinegun/apply_to_weapon(obj/item/gun/energy/applied_gun)
autofire_component = applied_gun.AddComponent(/datum/component/automatic_fire, shot_delay)
/datum/laser_weapon_mode/disabler_machinegun/remove_from_weapon(obj/item/gun/energy/applied_gun)
QDEL_NULL(autofire_component)
// Grenade launching mode for the large laser
/datum/laser_weapon_mode/launcher
name = "Launcher"
casing = /obj/item/ammo_casing/energy/cybersun_big_launcher
weapon_icon_state = "launcher"
charge_sections = 3
shot_delay = 2 SECONDS
json_speech_string = "launcher"
gun_runetext_color = "#77bd5d"
/datum/laser_weapon_mode/launcher/apply_to_weapon(obj/item/gun/energy/applied_gun)
applied_gun.recoil = 2
/datum/laser_weapon_mode/launcher/remove_from_weapon(obj/item/gun/energy/applied_gun)
applied_gun.recoil = initial(applied_gun.recoil)
// Shotgun mode for the large laser
/datum/laser_weapon_mode/shotgun
name = "Shotgun"
casing = /obj/item/ammo_casing/energy/cybersun_big_shotgun
weapon_icon_state = "shot"
charge_sections = 3
shot_delay = 0.75 SECONDS
json_speech_string = "shotgun"
gun_runetext_color = "#7a0bb7"
/datum/laser_weapon_mode/shotgun/apply_to_weapon(obj/item/gun/energy/applied_gun)
applied_gun.recoil = 1
/datum/laser_weapon_mode/shotgun/remove_from_weapon(obj/item/gun/energy/applied_gun)
applied_gun.recoil = initial(applied_gun.recoil)
// Hellfire mode for the small laser
/datum/laser_weapon_mode/hellfire
name = "Incinerate"
casing = /obj/item/ammo_casing/energy/cybersun_small_hellfire
weapon_icon_state = "kill"
charge_sections = 3
shot_delay = 0.4 SECONDS
json_speech_string = "incinerate"
gun_runetext_color = "#cd4456"
/datum/laser_weapon_mode/hellfire/apply_to_weapon(obj/item/gun/energy/applied_gun)
return
/datum/laser_weapon_mode/hellfire/remove_from_weapon(obj/item/gun/energy/applied_gun)
return
// Melee mode for the small laser, yeah this one will be weird
/datum/laser_weapon_mode/sword
name = "Blade"
// This mode doesn't actually shoot but we gotta have a casing regardless so it doesn't runtime times a million
// And also so the visuals work :3
casing = /obj/item/ammo_casing/energy/cybersun_small_blade
weapon_icon_state = "blade"
charge_sections = 2
json_speech_string = "blade"
gun_runetext_color = "#f8d860"
/datum/laser_weapon_mode/sword/apply_to_weapon(obj/item/gun/energy/modular_laser_rifle/applied_gun)
playsound(src, 'sound/items/unsheath.ogg', 25, TRUE)
applied_gun.force = 18
applied_gun.sharpness = SHARP_EDGED
applied_gun.bare_wound_bonus = 10
applied_gun.disabled_for_other_reasons = TRUE
applied_gun.attack_verb_continuous = list("slashes", "cuts")
applied_gun.attack_verb_simple = list("slash", "cut")
applied_gun.hitsound = 'sound/weapons/rapierhit.ogg'
/datum/laser_weapon_mode/sword/remove_from_weapon(obj/item/gun/energy/modular_laser_rifle/applied_gun)
playsound(src, 'sound/items/sheath.ogg', 25, TRUE)
applied_gun.force = initial(applied_gun.force)
applied_gun.sharpness = initial(applied_gun.sharpness)
applied_gun.bare_wound_bonus = initial(applied_gun.bare_wound_bonus)
applied_gun.disabled_for_other_reasons = FALSE
applied_gun.attack_verb_continuous = initial(applied_gun.attack_verb_continuous)
applied_gun.attack_verb_simple = initial(applied_gun.attack_verb_simple)
applied_gun.hitsound = initial(applied_gun.hitsound)
// Flare mode for the small laser
/datum/laser_weapon_mode/flare
name = "Flare"
casing = /obj/item/ammo_casing/energy/cybersun_small_launcher
weapon_icon_state = "flare"
charge_sections = 3
shot_delay = 2 SECONDS
json_speech_string = "flare"
gun_runetext_color = "#77bd5d"
/datum/laser_weapon_mode/flare/apply_to_weapon(obj/item/gun/energy/applied_gun)
applied_gun.recoil = 2
/datum/laser_weapon_mode/flare/remove_from_weapon(obj/item/gun/energy/applied_gun)
applied_gun.recoil = initial(applied_gun.recoil)
// Shotgun mode for the small laser
/datum/laser_weapon_mode/shotgun_small
name = "Shotgun"
casing = /obj/item/ammo_casing/energy/cybersun_small_shotgun
weapon_icon_state = "shot"
charge_sections = 3
shot_delay = 0.6 SECONDS
json_speech_string = "shotgun"
gun_runetext_color = "#7a0bb7"
/datum/laser_weapon_mode/shotgun_small/apply_to_weapon(obj/item/gun/energy/applied_gun)
applied_gun.recoil = 1
/datum/laser_weapon_mode/shotgun_small/remove_from_weapon(obj/item/gun/energy/applied_gun)
applied_gun.recoil = initial(applied_gun.recoil)
// Trickshot bounce disabler mode for the small laser
/datum/laser_weapon_mode/trickshot_disabler
name = "Disable"
casing = /obj/item/ammo_casing/energy/cybersun_small_disabler
weapon_icon_state = "disable"
charge_sections = 3
shot_delay = 0.4 SECONDS
json_speech_string = "disable"
gun_runetext_color = "#47a1b3"
/datum/laser_weapon_mode/trickshot_disabler/apply_to_weapon(obj/item/gun/energy/applied_gun)
return
/datum/laser_weapon_mode/trickshot_disabler/remove_from_weapon(obj/item/gun/energy/applied_gun)
return
@@ -0,0 +1,235 @@
// Red kill lasers for the big gun
/obj/item/ammo_casing/energy/cybersun_big_kill
projectile_type = /obj/projectile/beam/cybersun_laser
e_cost = LASER_SHOTS(20, STANDARD_CELL_CHARGE * 2)
select_name = "Kill"
fire_sound = 'modular_zubbers/modules/modular_weapons/sounds/laser_firing/laser.ogg'
/obj/projectile/beam/cybersun_laser
icon = 'modular_zubbers/modules/modular_weapons/icons/obj/company_and_or_faction_based/saibasan/projectiles.dmi'
icon_state = "kill_large"
damage = 20
impact_effect_type = /obj/effect/temp_visual/impact_effect/red_laser
light_color = COLOR_SOFT_RED
wound_falloff_tile = 1
// Speedy sniper lasers for the big gun
/obj/item/ammo_casing/energy/cybersun_big_sniper
projectile_type = /obj/projectile/beam/cybersun_laser/marksman
e_cost = LASER_SHOTS(10, STANDARD_CELL_CHARGE * 2)
select_name = "Marksman"
fire_sound = 'modular_zubbers/modules/modular_weapons/sounds/laser_firing/vaporize.ogg'
/obj/projectile/beam/cybersun_laser/marksman
icon_state = "sniper"
damage = 50
impact_effect_type = /obj/effect/temp_visual/impact_effect/yellow_laser
speed = 0.4
light_range = 2
light_color = COLOR_VERY_SOFT_YELLOW
wound_falloff_tile = 0.1
// Disabler machinegun for the big gun
/obj/item/ammo_casing/energy/cybersun_big_disabler
projectile_type = /obj/projectile/beam/cybersun_laser/disable
e_cost = LASER_SHOTS(20, STANDARD_CELL_CHARGE * 2)
select_name = "Disable"
harmful = FALSE
/obj/projectile/beam/cybersun_laser/disable
icon_state = "disable_large"
damage = 0
stamina = 20
impact_effect_type = /obj/effect/temp_visual/impact_effect/blue_laser
light_color = COLOR_BRIGHT_BLUE
stamina_falloff_tile = 0.25
// Plasma burst grenade for the big gun
/obj/item/ammo_casing/energy/cybersun_big_launcher
projectile_type = /obj/projectile/beam/cybersun_laser/granata
e_cost = LASER_SHOTS(5, STANDARD_CELL_CHARGE * 2)
select_name = "Launcher"
/obj/projectile/beam/cybersun_laser/granata
name = "plasma grenade"
icon_state = "grenade"
damage = 50
speed = 2
range = 6
impact_effect_type = /obj/effect/temp_visual/impact_effect/green_laser
light_color = COLOR_PALE_GREEN
pass_flags = PASSTABLE | PASSGRILLE // His ass does NOT pass through glass!
/// What type of casing should we put inside the bullet to act as shrapnel later
var/casing_to_spawn = /obj/item/grenade/c980payload/plasma_grenade
/obj/projectile/beam/cybersun_laser/granata/on_hit(atom/target, blocked = 0, pierce_hit)
..()
fuse_activation(target)
return BULLET_ACT_HIT
/obj/projectile/beam/cybersun_laser/granata/on_range()
fuse_activation(get_turf(src))
return ..()
/// Called when the projectile reaches its max range, or hits something
/obj/projectile/beam/cybersun_laser/granata/proc/fuse_activation(atom/target)
var/obj/item/grenade/shrapnel_maker = new casing_to_spawn(get_turf(target))
shrapnel_maker.detonate()
playsound(src, 'modular_zubbers/modules/modular_weapons/sounds/grenade_burst.ogg', 50, TRUE, -3)
qdel(shrapnel_maker)
/obj/projectile/beam/cybersun_laser/granata_shrapnel
name = "plasma globule"
icon_state = "flare"
damage = 10
speed = 2.5
bare_wound_bonus = 55 // Lasers have a wound bonus of 40, this is a bit higher
wound_bonus = -50 // However we do not very much against armor
range = 2
pass_flags = PASSTABLE | PASSGRILLE // His ass does NOT pass through glass!
weak_against_armour = TRUE
impact_effect_type = /obj/effect/temp_visual/impact_effect/green_laser
light_color = COLOR_PALE_GREEN
damage_falloff_tile = 3
/obj/item/grenade/c980payload/plasma_grenade
shrapnel_type = /obj/projectile/beam/cybersun_laser/granata_shrapnel
shrapnel_radius = 3
// Shotgun casing for the big gun
/obj/item/ammo_casing/energy/cybersun_big_shotgun
projectile_type = /obj/projectile/beam/cybersun_laser/granata_shrapnel/shotgun_pellet
e_cost = LASER_SHOTS(10, STANDARD_CELL_CHARGE * 2)
pellets = 5
variance = 30
select_name = "Shotgun"
fire_sound = 'modular_zubbers/modules/modular_weapons/sounds/laser_firing/melt.ogg'
/obj/projectile/beam/cybersun_laser/granata_shrapnel/shotgun_pellet
icon_state = "because_it_doesnt_miss"
damage = 10
impact_effect_type = /obj/effect/temp_visual/impact_effect/purple_laser
speed = 0.8
light_color = COLOR_SCIENCE_PINK
range = 9
damage_falloff_tile = 0.5
// Hellfire lasers for the little guy
/obj/item/ammo_casing/energy/cybersun_small_hellfire
projectile_type = /obj/projectile/beam/cybersun_laser/hellfire
e_cost = LASER_SHOTS(10, STANDARD_CELL_CHARGE)
select_name = "Incinerate"
fire_sound = 'modular_zubbers/modules/modular_weapons/sounds/laser_firing/incinerate.ogg'
/obj/projectile/beam/cybersun_laser/hellfire
icon_state = "hellfire"
damage = 30
impact_effect_type = /obj/effect/temp_visual/impact_effect/red_laser
speed = 0.6
wound_bonus = 0
light_color = COLOR_SOFT_RED
// Bounce disabler lasers for the little guy
/obj/item/ammo_casing/energy/cybersun_small_disabler
projectile_type = /obj/projectile/beam/cybersun_laser/disable_bounce
e_cost = LASER_SHOTS(10, STANDARD_CELL_CHARGE)
select_name = "Disable"
harmful = FALSE
/obj/projectile/beam/cybersun_laser/disable_bounce
icon_state = "disable_bounce"
damage = 0
stamina = 30
impact_effect_type = /obj/effect/temp_visual/impact_effect/blue_laser
light_color = COLOR_BRIGHT_BLUE
ricochet_auto_aim_angle = 30
ricochet_auto_aim_range = 5
ricochets_max = 2
ricochet_incidence_leeway = 100
ricochet_chance = 130
ricochet_decay_damage = 0.8
/obj/projectile/beam/cybersun_laser/disable_bounce/check_ricochet_flag(atom/reflecting_atom)
if((reflecting_atom.flags_ricochet & RICOCHET_HARD) || (reflecting_atom.flags_ricochet & RICOCHET_SHINY))
return TRUE
return FALSE
// Flare launcher
/obj/item/ammo_casing/energy/cybersun_small_launcher
projectile_type = /obj/projectile/beam/cybersun_laser/flare
e_cost = LASER_SHOTS(5, STANDARD_CELL_CHARGE)
select_name = "Flare"
/obj/projectile/beam/cybersun_laser/flare
name = "plasma flare"
icon_state = "flare"
damage = 30
speed = 2
range = 6
impact_effect_type = /obj/effect/temp_visual/impact_effect/green_laser
light_color = COLOR_PALE_GREEN
pass_flags = PASSTABLE | PASSGRILLE // His ass does NOT pass through glass!
/// How many firestacks the bullet should impart upon a target when impacting
var/firestacks_to_give = 2
/// What we spawn when we range out
var/obj/illumination_flare = /obj/item/flashlight/flare/plasma_projectile
/obj/projectile/beam/cybersun_laser/flare/on_hit(atom/target, blocked = 0, pierce_hit)
. = ..()
if(iscarbon(target))
var/mob/living/carbon/gaslighter = target
gaslighter.adjust_fire_stacks(firestacks_to_give)
gaslighter.ignite_mob()
else
new illumination_flare(get_turf(target))
/obj/projectile/beam/cybersun_laser/flare/on_range()
new illumination_flare(get_turf(src))
return ..()
/obj/item/flashlight/flare/plasma_projectile
name = "plasma flare"
desc = "A burning glob of green plasma, makes an effective temporary lighting source."
light_range = 4
anchored = TRUE
icon = 'modular_zubbers/modules/modular_weapons/icons/obj/company_and_or_faction_based/saibasan/projectiles.dmi'
icon_state = "flare_burn"
light_color = COLOR_PALE_GREEN
light_power = 2
/obj/item/flashlight/flare/plasma_projectile/Initialize(mapload)
. = ..()
if(randomize_fuel)
fuel = rand(3 MINUTES, 5 MINUTES)
ignition()
/obj/item/flashlight/flare/plasma_projectile/turn_off()
. = ..()
qdel(src)
// Shotgun casing for the small gun
/obj/item/ammo_casing/energy/cybersun_small_shotgun
projectile_type = /obj/projectile/beam/cybersun_laser/granata_shrapnel/shotgun_pellet
e_cost = LASER_SHOTS(10, STANDARD_CELL_CHARGE)
pellets = 3
variance = 15
select_name = "Shotgun"
fire_sound = 'modular_zubbers/modules/modular_weapons/sounds/laser_firing/melt.ogg'
// Dummy casing that does nothing but have a projectile that looks like a sword
/obj/item/ammo_casing/energy/cybersun_small_blade
projectile_type = /obj/projectile/beam/cybersun_laser/blade
select_name = "Blade"
/obj/projectile/beam/cybersun_laser/blade
icon_state = "blade"
Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

+102
View File
@@ -0,0 +1,102 @@
{
"pickup": [
"Welcome back, @pick(operator).",
"Zǎo shàng hǎo.",
"Wǎn shàng hǎo.",
"Charge systems operational, entering combat mode.",
"@pick(operator), carp migrations have been reported in the sector.",
"@pick(operator), having a pleasant day?",
"@pick(operator), please maintain good health while performing combat.",
"@pick(operator), are you sure I'm not too heavy for you?",
"Would you mind cleaning my lens later, @pick(operator)?"
],
"putdown": [
"Understood, @pick(operator), entering sleep mode.",
"Good night, @pick(operator).",
"Wǎn`ān, hǎo mèng.",
"Dàjiā ān.",
"Good night.",
"Entering sleep mode now.",
"Entering recharge cycle."
],
"worn": [
"Working on your strength will help you keep me steady.",
"Investing in backup magnetic slings is a good idea...",
"Thank you for observing proper carrying protocols.",
"I get a nicer view of your surroundings if you point my barrel upwards.",
"I'll watch your back if you watch my stock.",
"So much nicer than being in a case~!"
],
"lowcharge": [
"Energy reserves low, I can't do much more @pick(operator)...",
"I'm out... sorry @pick(operator), I need to rest..."
],
"fullcharge": [
"Energy reserves at maximum capacity! Please avoid accidental discharge.",
"Energy reserves at maximum capacity! Please follow safety guidelines.",
"Energy reserves at maximum capacity! It's nice to not be left at half-charge."
],
"combatmode": [
"Biological markers indicate heightened stress response. Combat protocols initiated.",
"Adrenaline spike detected. Combat protocols initiated."
],
"kill": [
"Switching to burst fire.",
"Switching to rapid-pattern assault.",
"Moving to dual-shot pattern.",
"Moving to close-quarters burst doctrine, lethal.",
"@pick(operator), please tightly control my recoil pattern.",
"@pick(operator), please hold me firmly to ensure accuracy."
],
"sniper": [
"Sighting in, scope extending.",
"Sighting in, preparing for long-range combat.",
"Sighting in, engaging marksman mode.",
"@pick(operator), take deep breaths to improve your aim.",
"Extending scope; @pick(operator), make sure it's well-maintained.",
"One shot, one kill.",
"Assassination doctrine engaged, @pick(operator). Make every shot count.",
"Scope extending, please avoid overpenetration in non-terrestrial combat environments.",
"Sighting in, please be aware of cross-fire."
],
"disable": [
"Preparing to enter full-power stun mode.",
"Mass crowd-control mode engaged, non-lethal.",
"This should be... fun, right @pick(operator)?",
"This is going to be stressful on my battery, but...",
"Is this really okay...? This is quite difficult from my usual operation...",
"Switching to high output mode.",
"Switching to gatling doctrine, non-lethal."
],
"launcher": [
"Forming plasma grenades at your request, @pick(operator)!",
"Grenadier mode engaged, @pick(operator)!",
"Aim my grenades carefully in an arc, @pick(operator)!",
"Energy detonation doctrine engaged.",
"Crowd-control mode engaged, lethal. Is this really okay?",
"Charging magnetic containment coils, plasma condensing..."
],
"shotgun": [
"Close-quarters...? I'm not really the tool for this job...",
"I'm more of a rifle, @pick(operator), but I'll try...",
"Is this really okay...? This is more of a carbine's job...",
"Switching to wide-band spread.",
"Changing to diffusion lens, shotgun doctrine engaged.",
"Close-quarters mode engaged, lethal."
],
"operator": [
"Operator",
"Handler"
]
}
+143
View File
@@ -0,0 +1,143 @@
{
"pickup": [
"Zǎo shàng hǎo.",
"Wǎn shàng hǎo.",
"What's the operation today, ah?",
"Let's get things started, heh-heh.",
"I'm feeling good about our chances today.",
"Hey, clean my damn lens later.",
"Little tighter around the handguard, @pick(operator)"
],
"putdown": [
"...you'll hold me again soon, right? Right?",
"Don't you DARE leave me here!",
"Tch! Whatever... You'll come crawling back to point me around later.",
"Dàjiā ān.",
"Good night.",
"Entering sleep mode now.",
"Entering recharge cycle.",
"Yeah, yeah... entering recharge cycle...",
"Qù nǐ mā... nevermind, entering sleep mode."
],
"worn": [
"So portable, right @pick(operator)?",
"Lightweight, sold with a few backup magslings, what's not to love?",
"I can't see anything infront of you, this sucks.",
"I can't see shit from this angle...",
"We're going somewhere with this, right?",
"Don't fall over on top of me, okay?",
"Pretty cushy ride back here...",
"I could get used to this.",
"I can't see sh- ah, wait, maybe it's not so bad back here."
],
"lowcharge": [
"Wǒ tài nán le...",
"Mā de...",
"Tā mā de...",
"I'm really drowsy here, pull back, won't you?",
"I'm running on fumes here, boss...",
"Outta charge, gotta rest...",
"Sorry, on your own 'til I recharge.",
"Disappointing! Entering recharge cycle...",
"Wh- Already?! I was just getting started..."
],
"fullcharge": [
"Whew, that's much better.",
"Hundred percent charged, let's get back to it.",
"I feel like a million creds!",
"Heh-heh, recharge cycle came in handy.",
"This. Is. Power!",
"As if there was any doubt..."
],
"combatmode": [
"I've been waaaiiitiiiing!",
"I was wondering how long you were planning on depriving me, @pick(operator).",
"Come on, come at me!",
"It's your lucky day!",
"Now the fun begins!",
"Countin' on ya!"
],
"emp": [
"Tāmāde! Tāmāde!",
"Qì sǐ wǒle!",
"ELECTROM-",
"ELECTROMAGNETIC PULSE DETECTED, DISCHARGING-",
"ELECTROMAGNETIC PULSE, IT'S DISCHARGING MY BATTERY!",
"THEY HAVE AN EM-",
"GO KILL THEM!",
"KILL THEM! KILL THEM! PUT THE SIGHTS ON THEM AND KILL THEM!",
"KILL THEM, KILL THEM!",
"I DON'T NEED CHARGE FOR BLADE MODE, PUT IT IN THEM AND TWIST!",
"Qù nǐ mā de ba!"
],
"incinerate": [
"Superheating lens, time to cauterize!",
"Charging Hellfire capacitators, let's toast em!",
"Hellfire capacitators charging. Don't stop 'till I'm empty!",
"Hellfire! Bring it on, bastards!",
"Heh-heh, can you feel the heat?",
"Gunslinger!"
],
"blade": [
"Extending blade; up close and personal? I like that.",
"Extending blade; wipe me off after we're finished.",
"Extending blade, stab stab stab!",
"Swing the sword, swing the sword!",
"CQC mode initiated, stick me in there deep!",
"Eviscerate!",
"Show me your motivation...",
"I'll cut them in two!",
"Clean cuts!",
"Their nightmare begins here!",
"Now I'm motivated!",
"Swordmaster!",
"The sword is yours, @pick(operator).",
"Sword core online."
],
"disable": [
"Trickster!",
"Non-lethal mode initiated. Let's make it stylish.",
"Non-lethal mode initiated. It's showtime!",
"Non-lethal mode initiated. You like trick shootin'?",
"Non-lethal mode initiated. Who's ready for a show?",
"This is gonna be cool, but can we up the voltage please?",
"I'm ready, but... man...",
"We aren't really gonna get any kills like this."
],
"flare": [
"Ignite the flames! Now!",
"Incendiary, incendiary!",
"Fabricating 'Balrog' energy flares; this'll be sick.",
"Fabricating 'Balrog' energy flares; can you feel the fire?",
"Firestarter, twisted firestarter!",
"Apocalyptic meltdown!",
"Incendiary weapons are banned in numerous sectors; makes it kind of risqué..",
"Dragon breath!"
],
"shotgun": [
"Focusing lens, one shot, one kill!",
"Focusing lens, let's go all the way through.",
"Focusing lens, aim for the head!",
"Let me show you what a real diffusion lens looks like...",
"Would it distract you if I told you about a shotgun's 'choke?'",
"I'll be your boomstick.",
"You should keep me handy for close encounters.",
"Is there something more iconic and awesome than a double-barrel? Yeah, me."
],
"operator": [
"Operator",
"Handler"
]
}
+4
View File
@@ -8796,6 +8796,7 @@
#include "modular_zubbers\modules\customization\modules\mob\living\carbon\human\species\xeno.dm"
#include "modular_zubbers\modules\emotes\code\emotes.dm"
#include "modular_zubbers\modules\emotes\code\synth_emotes.dm"
#include "modular_zubbers\modules\ert_overrides\modified_equipement.dm"
#include "modular_zubbers\modules\examine\examine_tgui.dm"
#include "modular_zubbers\modules\gladiator\code\game\objects\items\gladiator_items.dm"
#include "modular_zubbers\modules\hacks\atmos\force_atmos.dm"
@@ -8821,6 +8822,9 @@
#include "modular_zubbers\modules\modular_weapons\code\company_and_or_faction_based\carwo.dm"
#include "modular_zubbers\modules\modular_weapons\code\company_and_or_faction_based\carwo_defense_systems\ammo\ammobox.dm"
#include "modular_zubbers\modules\modular_weapons\code\company_and_or_faction_based\carwo_defense_systems\ammo\carwo.dm"
#include "modular_zubbers\modules\modular_weapons\code\company_and_or_faction_based\saibasan\laser_guns.dm"
#include "modular_zubbers\modules\modular_weapons\code\company_and_or_faction_based\saibasan\mode_datums.dm"
#include "modular_zubbers\modules\modular_weapons\code\company_and_or_faction_based\saibasan\projectiles.dm"
#include "modular_zubbers\modules\modular_weapons\code\company_and_or_faction_based\trappiste_fabriek\ammo.dm"
#include "modular_zubbers\modules\normalized_syndie_clothing_4_tesh\unsorted_clothes.dm"
#include "modular_zubbers\modules\pollution\code\perfumes.dm"