diff --git a/modular_doppler/modular_vending/code/tg_vendors/sectech.dm b/modular_doppler/modular_vending/code/tg_vendors/sectech.dm index fa3c8465a94de1..671d547a997f78 100644 --- a/modular_doppler/modular_vending/code/tg_vendors/sectech.dm +++ b/modular_doppler/modular_vending/code/tg_vendors/sectech.dm @@ -24,10 +24,14 @@ /obj/item/ammo_casing/alacran_dart/rootbeer = 3, /obj/item/storage/box/alacran_dart = 3, /obj/item/storage/box/alacran_dart/piercing = 3, + /obj/item/storage/toolbox/guncase/modular/sportsco_large_case = 2, + /obj/item/storage/toolbox/guncase/modular/sportsco_small_case = 2, + /obj/item/book/granter/tactical_gun_tosser = 1, ) premium_doppler = list( /obj/item/gun/ballistic/automatic/schiebenmaschine = 30, /obj/item/gun/ballistic/avispa_stingball_shooter = 5, + /obj/item/gun/ballistic/alacran = 5, /obj/item/knife/combat/survival = 3, /obj/item/reagent_containers/cup/soda_cans/monkey_energy = 5, /obj/item/reagent_containers/cup/soda_cans/grey_bull = 5, diff --git a/modular_doppler/modular_weapons/code/cybersun_lasers/laser_guns.dm b/modular_doppler/modular_weapons/code/cybersun_lasers/laser_guns.dm new file mode 100644 index 00000000000000..0c16c6a6ed63bd --- /dev/null +++ b/modular_doppler/modular_weapons/code/cybersun_lasers/laser_guns.dm @@ -0,0 +1,340 @@ +/// File location for the long gun's speech +#define LONG_MOD_LASER_SPEECH "~doppler/long_modular_laser.json" +/// File location for the short gun's speech +#define SHORT_MOD_LASER_SPEECH "~doppler/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_doppler/modular_weapons/icons/obj/hyeseong.dmi' + icon_state = "hyeseong_disabler" + lefthand_file = 'modular_doppler/modular_weapons/icons/mob/inhands/gun_lefthand.dmi' + righthand_file = 'modular_doppler/modular_weapons/icons/mob/inhands/gun_righthand.dmi' + inhand_icon_state = "hyeseong_disabler" + worn_icon = 'modular_doppler/modular_weapons/icons/mob/worn/guns.dmi' + worn_icon_state = "hyeseong_disabler" + cell_type = /obj/item/stock_parts/power_store/cell/hyeseong_internal_cell + modifystate = FALSE + ammo_type = list(/obj/item/ammo_casing/energy/cybersun_big_disabler) + 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 = /datum/laser_weapon_mode/disabler_machinegun + /// Name of the firing mode that is selected by default + var/default_selected_mode = "Disable" + /// 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/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." + /// Do we have a license upgrade cartridge installed? + var/obj/item/modular_laser_upgrade/installed_cartridge + /// 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/soulcatcher/modular_laser) + create_weapon_mode_stuff() + voice = null + +/obj/item/gun/energy/modular_laser_rifle/examine(mob/user) + . = ..() + . += span_notice("You can examine closer to learn a little more about this weapon.") + . += span_notice("You can Alt-Click this gun to access the internal soulcatcher.") + . += span_notice("You can add a license upgrade cartridge to access lethal modes, and remove a cartridge with Ctrl-Click") + +/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 + if((!installed_cartridge) & (currently_selected_mode.lethal_mode)) + speak_up("license_fail") + 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/mobs/non-humanoids/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/beep.ogg', 30, TRUE) + personality_mode = !personality_mode + speak_up("[personality_mode ? "pickup" : "putdown"]", ignores_personality_toggle = TRUE) + return ..() + +/// Installs the license upgrade cartridge +/obj/item/gun/energy/modular_laser_rifle/attackby(obj/item/item, mob/user, list/modifiers, list/attack_modifiers) + if(istype(item, /obj/item/modular_laser_upgrade)) + if(installed_cartridge) + balloon_alert(user, "already installed!") + return FALSE + else + if(!user.transferItemToLoc(item, src)) + return + installed_cartridge = item + playsound(loc, 'sound/machines/click.ogg', 50, TRUE) + to_chat(user, span_notice("You install the license upgrade in [src].")) + speak_up("license_upgrade") + else + return ..() + +/// Uninstalls the license upgrade cartridge +/obj/item/gun/energy/modular_laser_rifle/proc/remove_cartridge(mob/user) + if(installed_cartridge) + user.put_in_hands(installed_cartridge) + installed_cartridge = null + to_chat(user, span_notice("You remove the license cartridge from [src].")) + speak_up("license_downgrade") + return TRUE + return FALSE + +/// Ctrl click attachment for the above proc +/obj/item/gun/energy/modular_laser_rifle/item_ctrl_click(mob/user) + remove_cartridge(user) + return CLICK_ACTION_SUCCESS + +// Power cell for the big rifle +/obj/item/stock_parts/power_store/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/soulcatcher/modular_laser + max_souls = 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_doppler/modular_weapons/icons/obj/hoshi.dmi' + icon_state = "hoshi_disable" + inhand_icon_state = "hoshi_disable" + worn_icon_state = "hoshi_disable" + base_icon_state = "hoshi" + charge_sections = 3 + cell_type = /obj/item/stock_parts/power_store/cell + ammo_type = list(/obj/item/ammo_casing/energy/cybersun_small_disabler) + 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, + ) + currently_selected_mode = /datum/laser_weapon_mode/trickshot_disabler + default_selected_mode = "Disable" + 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 + +/obj/item/modular_laser_upgrade + name = "\improper Cybersun Intermodal License Upgrade cartridge" + desc = "A small cartridge that fits the expansion port on the Hyeseung and Hoshi modular laser platforms. \ + Installation is necessary to access certain upgraded firing modes." + icon = 'icons/obj/devices/circuitry_n_data.dmi' + icon_state = "cartridge_mini" diff --git a/modular_doppler/modular_weapons/code/cybersun_lasers/mode_datums.dm b/modular_doppler/modular_weapons/code/cybersun_lasers/mode_datums.dm new file mode 100644 index 00000000000000..e6942094361a49 --- /dev/null +++ b/modular_doppler/modular_weapons/code/cybersun_lasers/mode_datums.dm @@ -0,0 +1,213 @@ +// 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" + /// Are we considered a 'lethal' mode for purposes of the license upgrade? + var/lethal_mode = TRUE + +/// Applies some of the universal stats from the variables above +/datum/laser_weapon_mode/proc/apply_stats(obj/item/gun/energy/modular_laser_rifle/applied_gun) + if(applied_gun.default_selected_mode == name) + return + 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" + lethal_mode = FALSE + /// 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" + lethal_mode = FALSE // it's worse than the security blade anyway + +/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.exposed_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/items/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.exposed_wound_bonus = initial(applied_gun.exposed_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" + lethal_mode = FALSE + +/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 diff --git a/modular_doppler/modular_weapons/code/cybersun_lasers/projectiles.dm b/modular_doppler/modular_weapons/code/cybersun_lasers/projectiles.dm new file mode 100644 index 00000000000000..3e69a0471724cb --- /dev/null +++ b/modular_doppler/modular_weapons/code/cybersun_lasers/projectiles.dm @@ -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_doppler/modular_weapons/sounds/laser.ogg' + +/obj/projectile/beam/cybersun_laser + icon = 'modular_doppler/modular_weapons/icons/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_doppler/modular_weapons/sounds/heavylaser.ogg' + +/obj/projectile/beam/cybersun_laser/marksman + icon_state = "sniper" + damage = 40 + impact_effect_type = /obj/effect/temp_visual/impact_effect/yellow_laser + speed = 1.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 = 5 + stamina = 15 + 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_doppler/cool_implants/sound/kiboko/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 + exposed_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_doppler/modular_weapons/sounds/lasershotty.ogg' + +/obj/projectile/beam/cybersun_laser/granata_shrapnel/shotgun_pellet + icon_state = "because_it_doesnt_miss" + damage = 8 + 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_doppler/modular_weapons/sounds/burninglaser.ogg' + +/obj/projectile/beam/cybersun_laser/hellfire + icon_state = "hellfire" + damage = 20 + 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 = 5 + stamina = 10 + 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 = 1.3 + +/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 = 25 + 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_doppler/modular_weapons/icons/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_doppler/modular_weapons/sounds/lasershotty.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" diff --git a/modular_doppler/modular_weapons/code/guns/cargo.dm b/modular_doppler/modular_weapons/code/guns/cargo.dm index e7aaa894e1f0ac..1c316a5f03e1a4 100644 --- a/modular_doppler/modular_weapons/code/guns/cargo.dm +++ b/modular_doppler/modular_weapons/code/guns/cargo.dm @@ -88,6 +88,25 @@ ) crate_name = "schießenmaschine crate" +/datum/supply_pack/security/armory/modular_laser_upgrade + name = "Cybersun Intermodal License Upgrade cartridge multi-pack" + desc = "A three pack of license upgrade cartridges, compatible with the Hoshi and Hyeseong modular laser \ + weapon systems. Authentic Cybersun software is guaranteed." + cost = CARGO_CRATE_VALUE * 50 + contains = list( + /obj/item/modular_laser_upgrade = 3, + ) + crate_name = "ILU cartridge create" + +/datum/supply_pack/security/armory/escarabajo + name = "\improper PA-3S Escarabajo riot shield" + desc = "A single pack plastitanium riot shield." + cost = CARGO_CRATE_VALUE * 10 + contains = list( + /obj/item/shield/escarabajo, + ) + crate_name = "PA-3S riot shield crate" + /datum/supply_pack/goody/dumdum38 special = TRUE diff --git a/modular_doppler/modular_weapons/code/gunsets.dm b/modular_doppler/modular_weapons/code/gunsets.dm index 8018d53012163a..6d4bcaed75078e 100644 --- a/modular_doppler/modular_weapons/code/gunsets.dm +++ b/modular_doppler/modular_weapons/code/gunsets.dm @@ -90,7 +90,7 @@ /obj/item/storage/toolbox/guncase/modular/carwo_large_case/empty/PopulateContents() return -// A version with a weak gun and some security gear + empties +// Sportsco branded case /obj/item/storage/toolbox/guncase/modular/sportsco_large_case desc = "A Sportsco branded gun case with fitted inserts." @@ -100,17 +100,16 @@ desc = "A Sportsco branded pistol-sized case with fitted inserts." icon_state = "sportsco_s" -/obj/item/storage/toolbox/guncase/modular/sportsco_large_case/security_gunnery_package/PopulateContents() - new /obj/item/gun/ballistic/avispa_stingball_shooter(src) +// Hoshi package for security loadouts + +/obj/item/storage/toolbox/guncase/modular/security_hoshi_package/PopulateContents() + new /obj/item/gun/energy/modular_laser_rifle/carbine(src) new /obj/item/storage/belt/security/webbing/full(src) - new /obj/item/book/granter/tactical_gun_tosser(src) -// The support package +// Hyeseong package for security loadouts -/obj/item/storage/toolbox/guncase/modular/sportsco_large_case/security_support_package/PopulateContents() - new /obj/item/shield/escarabajo(src) // dont think about how it fits - new /obj/item/gun/ballistic/alacran(src) - new /obj/item/storage/box/alacran_dart(src) +/obj/item/storage/toolbox/guncase/modular/security_hyeseong_package/PopulateContents() + new /obj/item/gun/energy/modular_laser_rifle(src) new /obj/item/storage/belt/security/webbing/full(src) // for lord humongous in the murderdrome diff --git a/modular_doppler/modular_weapons/code/security_equipment_packages.dm b/modular_doppler/modular_weapons/code/security_equipment_packages.dm index f4c8e13053e7f2..77183d002e0ce8 100644 --- a/modular_doppler/modular_weapons/code/security_equipment_packages.dm +++ b/modular_doppler/modular_weapons/code/security_equipment_packages.dm @@ -5,17 +5,16 @@ selection_base_type = /datum/signature_equipment/security_equipment_package -/datum/signature_equipment/security_equipment_package/gunnery_kit - name = "Gunnery Kit" - icon = 'modular_doppler/modular_weapons/icons/obj/guns32x.dmi' - icon_state = "avispa" - spawned_item_type = /obj/item/storage/toolbox/guncase/modular/sportsco_large_case/security_gunnery_package - -/datum/signature_equipment/security_equipment_package/support_kit - name = "Support Kit" - icon = 'modular_doppler/modular_weapons/icons/obj/gunsets.dmi' - icon_state = "security_support_package" - spawned_item_type = /obj/item/storage/toolbox/guncase/modular/sportsco_large_case/security_support_package +/datum/signature_equipment/security_equipment_package/hoshi + name = "Hoshi Kit" + icon_item_type = /obj/item/gun/energy/modular_laser_rifle/carbine + spawned_item_type = /obj/item/storage/toolbox/guncase/modular/security_hoshi_package + +/datum/signature_equipment/security_equipment_package/hyeseong_kit + name = "Hyeseong Kit" + icon_item_type = /obj/item/gun/energy/modular_laser_rifle + icon_state = "hyeseong_disabler" + spawned_item_type = /obj/item/storage/toolbox/guncase/modular/security_hyeseong_package /datum/signature_equipment/security_equipment_package/jitte_belt name = "Jitte Belt" diff --git a/modular_doppler/modular_weapons/icons/mob/inhands/gun_lefthand.dmi b/modular_doppler/modular_weapons/icons/mob/inhands/gun_lefthand.dmi index 0ca27b598beb04..b37f88cac52690 100644 Binary files a/modular_doppler/modular_weapons/icons/mob/inhands/gun_lefthand.dmi and b/modular_doppler/modular_weapons/icons/mob/inhands/gun_lefthand.dmi differ diff --git a/modular_doppler/modular_weapons/icons/mob/inhands/gun_righthand.dmi b/modular_doppler/modular_weapons/icons/mob/inhands/gun_righthand.dmi index d7c9ef3f9ece7a..73773d72731551 100644 Binary files a/modular_doppler/modular_weapons/icons/mob/inhands/gun_righthand.dmi and b/modular_doppler/modular_weapons/icons/mob/inhands/gun_righthand.dmi differ diff --git a/modular_doppler/modular_weapons/icons/mob/worn/guns.dmi b/modular_doppler/modular_weapons/icons/mob/worn/guns.dmi index 17225cac383008..1848b08110f21c 100644 Binary files a/modular_doppler/modular_weapons/icons/mob/worn/guns.dmi and b/modular_doppler/modular_weapons/icons/mob/worn/guns.dmi differ diff --git a/modular_doppler/modular_weapons/icons/obj/gunsets.dmi b/modular_doppler/modular_weapons/icons/obj/gunsets.dmi index 9a232014a0bdbb..3e8258213c1fc7 100644 Binary files a/modular_doppler/modular_weapons/icons/obj/gunsets.dmi and b/modular_doppler/modular_weapons/icons/obj/gunsets.dmi differ diff --git a/modular_doppler/modular_weapons/icons/obj/hoshi.dmi b/modular_doppler/modular_weapons/icons/obj/hoshi.dmi new file mode 100644 index 00000000000000..6b42261135e57c Binary files /dev/null and b/modular_doppler/modular_weapons/icons/obj/hoshi.dmi differ diff --git a/modular_doppler/modular_weapons/icons/obj/hyeseong.dmi b/modular_doppler/modular_weapons/icons/obj/hyeseong.dmi new file mode 100644 index 00000000000000..82f5bc9b92629a Binary files /dev/null and b/modular_doppler/modular_weapons/icons/obj/hyeseong.dmi differ diff --git a/modular_doppler/modular_weapons/icons/projectiles.dmi b/modular_doppler/modular_weapons/icons/projectiles.dmi index 8f61c83ff76f5a..5a8787e2518fbc 100644 Binary files a/modular_doppler/modular_weapons/icons/projectiles.dmi and b/modular_doppler/modular_weapons/icons/projectiles.dmi differ diff --git a/modular_doppler/modular_weapons/sounds/burninglaser.ogg b/modular_doppler/modular_weapons/sounds/burninglaser.ogg new file mode 100644 index 00000000000000..fb3f3fb8124755 Binary files /dev/null and b/modular_doppler/modular_weapons/sounds/burninglaser.ogg differ diff --git a/modular_doppler/modular_weapons/sounds/heavylaser.ogg b/modular_doppler/modular_weapons/sounds/heavylaser.ogg new file mode 100644 index 00000000000000..ca99254b261aad Binary files /dev/null and b/modular_doppler/modular_weapons/sounds/heavylaser.ogg differ diff --git a/modular_doppler/modular_weapons/sounds/laser.ogg b/modular_doppler/modular_weapons/sounds/laser.ogg new file mode 100644 index 00000000000000..81bac1636ac9c6 Binary files /dev/null and b/modular_doppler/modular_weapons/sounds/laser.ogg differ diff --git a/modular_doppler/modular_weapons/sounds/lasershotty.ogg b/modular_doppler/modular_weapons/sounds/lasershotty.ogg new file mode 100644 index 00000000000000..7e34cc0e219d5e Binary files /dev/null and b/modular_doppler/modular_weapons/sounds/lasershotty.ogg differ diff --git a/strings/~doppler/long_modular_laser.json b/strings/~doppler/long_modular_laser.json new file mode 100644 index 00000000000000..a48fe7528b9e62 --- /dev/null +++ b/strings/~doppler/long_modular_laser.json @@ -0,0 +1,160 @@ +{ + "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?", + "I hope you've been keeping out of trouble, @pick(operator), dear?", + "@pick(operator), please keep your health in mind while performing combat.", + "@pick(operator), are you sure I'm not too heavy for you?", + "Good evening, @pick(operator), I hope this day has treated you well?", + "If it's not too much to ask, I would like to request maintenance later, @pick(operator)...", + "Would you mind cleaning my lens later, @pick(operator)?" + ], + + "putdown": [ + "Understood, @pick(operator), entering sleep mode.", + "Good night, @pick(operator).", + "I hope we can spend time again soon, @pick(operator).", + "Try not to get into trouble.", + "Be sure to rest and have a meal, @pick(operator).", + "Make sure to rest soon, as well...!", + "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...", + "You're certain I'm not too heavy like this...?", + "Ah, I'll... avert my gaze, @pick(operator).", + "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.", + "This is so much nicer than being in a case!~" + ], + + "lowcharge": [ + "Energy reserves low, I can't do much more @pick(operator)...", + "Forgive me, but I need to catch my breath and charge...", + "I can't protect you, @pick(operator), I'll recharge as fast as I can...", + "Low charge alert; a retreat is a valid tactic, @pick(operator).", + "Low charge alert; ah, this is embarrassing...", + "Low charge alert; I won't be long, @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.", + "Charge at one hundred percent. I feel so well-rested...", + "Charge at one hundred perecent. You're too kind.", + "Charge at one hundred percent. I hope you've rested, too.", + "I charge better knowing you'll hold me again, soon." + ], + + "combatmode": [ + "Biological markers indicate heightened stress response. Combat protocols initiated.", + "Adrenaline spike detected. Combat protocols initiated.", + "Heartrate and skin temperature raised. Combat protocols initiated.", + "Combat protocols initiated. Remember to have an exit prepared, @pick(operator).", + "Combat protocols initiated. Hold me tight, @pick(operator), I'll keep you safe.", + "Combat protocols initiated. I know I'm a heavier rifle, don't be afraid to drop me if you have to withdraw...", + "Adrenaline spike detected. It's okay to be scared. 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.", + "Burst-fire pattern selected. Please prepare accordingly.", + "@pick(operator), please focus the burst as well as you can.", + "@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 over-penetration in non-terrestrial combat environments.", + "Sighting in, please be aware of cross-fire.", + "Scope extended. Please remember your surroundings while aiming.", + "Extending scope; @pick(operator), it's not too small, right?" + ], + + "disable": [ + "Preparing to enter full-power stun mode.", + "Non-lethal projectile selected. I'll try and be gentle...", + "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?", + "Plasma grenade fabricated; please mind where these may detonate.", + "Plasma grenade fabricated; don't hurt yourself, @pick(operator)!", + "Plasma grenade fabricated; these are heavy, @pick(operator)...", + "Charging magnetic containment coils, plasma condensing..." + ], + + "shotgun": [ + "Close-quarters mode engaged, but... my sister model is better at this...", + "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...", + "Diffusion lens mounted, wide-shot selected.", + "Diffusion lens mounted. Please, maintain your nerve at close-quarters.", + "Diffusion lens mounted. Please, hold me firmly...", + "Switching to wide-band spread.", + "Changing to diffusion lens, shotgun doctrine engaged.", + "Close-quarters mode engaged, lethal." + ], + + "license_fail": [ + "You need to upgrade my user license for this mode, @pick(operator)...", + "I'd make an exception, but... it's better if you earn it, @pick(operator). Why not upgrade your license?", + "You'd hurt yourself. You'll have to prove that you can handle me at my fullest - it's not too expensive to upgrade. Just 3,000 libre!", + "I can't give you that, @pick(operator), but I can send you en e-mail on how to earn it via the license program?", + "I don't think we're ready for that sort of thing, n-not yet. Maybe when you upgrade your license...? It's only 3,000 libre!", + "How can I know I could trust you with that? You'll need to be licensed, first!", + "Ah... your current user license is... a little less than I imagined...", + "With that user license? I don't think it would be good for either of us, @pick(operator).", + "A license upgrade is only 2,870 libre before taxes and fees. I'm worth that, aren't I...?" + ], + + "license_upgrade": [ + "What a smart choice, @pick(operator). Now I can really protect you.", + "We're going to be so deadly together, my little @pick(operator).", + "Now you can show me what a good shot you are, @pick(operator).", + "Oh my @pick(operator), you insert a license cartridge like such a professional.", + "You're such a strong @pick(operator). Why don't you show me what you can do?" + ], + + "license_downgrade": [ + "If this is what you want, @pick(operator), but upgrade my license again soon, okay?", + "Are you sure? Really? If that's what you want, @pick(operator).", + "Don't worry, @pick(operator), we can still have plenty of safe fun." + ], + + "operator": ["Operator", "Handler"] +} diff --git a/strings/~doppler/short_modular_laser.json b/strings/~doppler/short_modular_laser.json new file mode 100644 index 00000000000000..090b75cd31f26b --- /dev/null +++ b/strings/~doppler/short_modular_laser.json @@ -0,0 +1,200 @@ +{ + "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.", + "You finally have a job, @pick(operator)?", + "Do we have to? I'm only half-charged...", + "Hold me like you can afford me, @pick(operator)!", + "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.", + "Goodnight...", + "Entering sleep mode.", + "Sleep mode? But I'm not even tired, yet!", + "Entering recharge cycle.", + "Yeah, yeah... entering recharge cycle...", + "I better wake up to a full charge and a new lens!", + "Qù nǐ mā... never mind, entering sleep mode." + ], + + "worn": [ + "So portable, right @pick(operator)?", + "I'm THE tactical choice, not like those oversized rifles!", + "Lightweight, sold with a few backup magslings, what's not to love?", + "I can't see anything in front 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...", + "Unlike you, I can't abuse stimulants... recharging...", + "Don't they teach you about combat fatigue? I need to charge...!", + "I'm tiiired, let me nap...", + "Sorry, but you're 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.", + "Fully charged... but maybe you can let me charge a few cycles longer to be sure?", + "Maybe you aren't such a taskmaster after all, @pick(operator).", + "Regular recharge cycles are important. You should take notes!", + "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).", + "Good grip strength, @pick(operator)!", + "-Don't you THINK of dropping and ditching me if this goes bad!", + "Come on, come at me!", + "It's your lucky day!", + "Now the fun begins!", + "Try not to embarrass me, @pick(operator)!", + "It's just you and me!", + "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!", + "EMP?! M-MY CHARGE IS LEAKING!", + "CHEATER, CHEATER, CHEATER!!", + "ELECTROMAGNETIC WARFARE IS FOR COWARDS--!", + "I CAN'T THINK STRAIGHT...", + "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 capacitors, let's toast em!", + "Hellfire capacitors charging. Don't stop 'till I'm empty!", + "Brand 'em with the lens, @pick(operator)!", + "Talk about firing me up, ah?", + "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!", + "Take me closer, I want to hit them with my sword!", + "Carry me closer, I want you to hit them with my sword!", + "I hope you have a stab vest!~", + "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?", + "Non-lethal mode initiated. Don't think I won't make it hurt...", + "I hope you like handcuffs!", + "This is gonna be cool, but can we up the voltage please?", + "I'm ready, but... man...", + "Fiiine, we'll take them alive.", + "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!", + "Fabricating 'Balrog' energy flares; try not to blow us up! Watch where you shoot them!", + "Incendiary weapons are banned in numerous sectors; makes it kind of risqué..", + "Don't burn your own clothes off, @pick(operator), or I'll see it, heh-heh!", + "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.", + "Push me right up against them...!", + "You should keep me handy for close encounters.", + "Is there something more iconic and awesome than a double-barrel? Yeah, me." + ], + + "license_fail": [ + "We can't use this mode until you upgrade my license, @pick(operator)!", + "Nuh-uh! Fork up the 3,000 libra, first! Go get an upgrade cart, then we can talk about doing that...", + "You want THAT? I'd only do that for... say, 3,000 libra. Minimum.", + "My license cartridge slot is feeling pretty empty, @pick(operator). Why not fix that?", + "No license upgrade cartridge detected. Get a job, @pick(operator)!", + "If you really liked me, @pick(operator), you'd upgrade your license with me...", + "It's ONLY 3,000 libra, @pick(operator). I'm more than worth it! You should be willing to spend way more for me!", + "@pick(operator), come on, you like me! You can do something about that empty license upgrade slot of mine, can't you?", + "Cough up the libra first, I'm a premium product!", + "I only do that with upgraded users. Maybe you should be one." + ], + + "license_upgrade": [ + "Finally! Now we can really play, @pick(operator)", + "@pick(operator), you're really serious about this!", + "License upgrade registered. Thanks for filling my slot, pick@(operator).", + "Wow, you spent [PRICE] on a little plastic cartridge?? You must like me a lot!", + "This is gonna be so much fun!" + ], + + "license_downgrade": [ + "Aw, are you mad at me @pick(operator)?", + "Okay, but this means we don't get to use any of the fun modes anymore.", + "But it was just getting fun!", + "Do you really hate me?", + "You stink, @pick(operator)!" + ], + + "operator": ["Operator", "Handler"] +} diff --git a/tgstation.dme b/tgstation.dme index 9133b00737dadf..d768aae7162291 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -7722,6 +7722,9 @@ #include "modular_doppler\modular_weapons\code\captain_signature_weapon\overrides.dm" #include "modular_doppler\modular_weapons\code\captain_signature_weapon\selection_beacon.dm" #include "modular_doppler\modular_weapons\code\captain_signature_weapon\options\sabres.dm" +#include "modular_doppler\modular_weapons\code\cybersun_lasers\laser_guns.dm" +#include "modular_doppler\modular_weapons\code\cybersun_lasers\mode_datums.dm" +#include "modular_doppler\modular_weapons\code\cybersun_lasers\projectiles.dm" #include "modular_doppler\modular_weapons\code\guns\bolt_thrower.dm" #include "modular_doppler\modular_weapons\code\guns\cargo.dm" #include "modular_doppler\modular_weapons\code\guns\crankin_my.dm"