Microfusion Energy Guns (#9638)

* RELOADING!

* Update skillchip.dm

* a

* Update master.dm

* Update master.dm

* Part one

* E

* E

* EOR

* Oops

* EEEH

* Fixes.

* begone oldcode from old times

* fixes

* cell attatchments

* haha u cant spell

* Gun attachments!

* Fastest gun in the west

* Update multi_cell_charger.dm

* ESA

* Stability

* phase emitters

* foixes

* More fixes

* Update microfusion_gun_attachments.dm

* Update microfusion_gun_attachments.dm

* eee

* Intermediate interactions.

* Update microfusion_energy_master.dm

* wooh

* EEE

* Update microfusion_cell.dm

* Map edits

* Merge branch 'master' into gun_reloads

* E

* attachment removal

* Update _basemap.dm

* proper parent gun interactions

* Update code/game/machinery/recharger.dm

Co-authored-by: Tom <8881105+tf-4@users.noreply.github.com>

* E

* Update modular_skyrat/modules/gunsgalore/code/guns/ballistic_master.dm

Co-authored-by: Tom <8881105+tf-4@users.noreply.github.com>

* Update modular_skyrat/modules/microfusion/code/microfusion_cell.dm

Co-authored-by: Tom <8881105+tf-4@users.noreply.github.com>

* Update modular_skyrat/modules/microfusion/code/microfusion_cell.dm

Co-authored-by: Tom <8881105+tf-4@users.noreply.github.com>

* Review comments pt2

* review comments pt2

* review part 3

* review part 4

* review 4.1

* review fixes

* Update microfusion_designs.dm

* ffs

* Update code/__DEFINES/~skyrat_defines/traits.dm

Co-authored-by: GoldenAlpharex <58045821+GoldenAlpharex@users.noreply.github.com>

* Nearly there

* final review commit

* Update multi_cell_charger.dm

* Update microfusion_energy_master.dm

* E

* insight

* Fixes, rgb, remove instability on cells

* de epic

* Update _basemap.dm

* TGUI in the houise

* Update MicrofusionGunControl.js

* FULL STEAM AHEAD CHOO CHOO (Adds zooming)

* FUU bayonets and flights

* e

* Nearly

* microCHANGES

* Update gun.dm

* Minidate.

- Shooting the gun while it's overheating can cause it to [REDACTED].
- Shooting the gun while it's overheating will burn your hand!
- Some cells will now notify you when they're empty using an alarm sound.
- Gun barrel attachments now change the sound of the laser!
- An overheating emitter slows down!
- Emitters now control fire time more!

* 0

* owo

* FFF

* Update code/game/machinery/recharger.dm

Co-authored-by: GoldenAlpharex <58045821+GoldenAlpharex@users.noreply.github.com>

* Update modular_skyrat/modules/gunhud/code/gun_hud_component.dm

Co-authored-by: GoldenAlpharex <58045821+GoldenAlpharex@users.noreply.github.com>

* no spolsion

* Generally we want the cell in our hands

* 0

* Update microfusion_gun_attachments.dm

* E

* E

* FINAL

* superheater

* Update projectiles.dm

* Update microfusion_energy_master.dm

* Update projectiles.dm

* Update microfusion_gun40x32.dmi

* Update laser_1.ogg

* E

* whoop

* Cargo crates!

* Review plus material updates

* Update microfusion_designs.dm

* E

* E

* E

* E

* EEEE

* Update gun_spawns.dm

* Some fine tuining

* Update gun_spawns.dm

* Update recharger.dm

* E

* Update microfusion_gun_attachments.dm

* E

* E

* Update microfusion_gun_attachments.dmi

* Update code/game/machinery/recharger.dm

Co-authored-by: Tom <8881105+tf-4@users.noreply.github.com>

* E

* You can now actually insert different cells into advanced guns!

* 0

* E

* Update microfusion_gun_attachments.dm

* Update microfusion_energy_master.dm

* Update modular_skyrat/modules/microfusion/code/microfusion_cell.dm

Co-authored-by: GoldenAlpharex <58045821+GoldenAlpharex@users.noreply.github.com>

* Update modular_skyrat/modules/microfusion/code/microfusion_cell.dm

Co-authored-by: GoldenAlpharex <58045821+GoldenAlpharex@users.noreply.github.com>

* E

* Update microfusion_energy_master.dm

* Update microfusion_gun_attachments.dm

Co-authored-by: Tom <8881105+tf-4@users.noreply.github.com>
Co-authored-by: GoldenAlpharex <58045821+GoldenAlpharex@users.noreply.github.com>
This commit is contained in:
Gandalf
2021-12-03 22:38:08 +00:00
committed by GitHub
co-authored by GoldenAlpharex Tom
parent 41abcc3bac
commit f3020a7f42
50 changed files with 2732 additions and 85 deletions
@@ -7337,7 +7337,7 @@
/obj/effect/turf_decal/delivery,
/obj/structure/rack/gunrack,
/obj/machinery/airalarm/directional/south,
/obj/effect/spawner/armory_spawn/rifles,
/obj/effect/spawner/armory_spawn/microfusion,
/turf/open/floor/iron,
/area/ai_monitored/security/armory)
"cev" = (
@@ -20604,7 +20604,7 @@
/obj/effect/turf_decal/delivery,
/obj/structure/rack/gunrack,
/obj/machinery/firealarm/directional/south,
/obj/effect/spawner/armory_spawn/rifles,
/obj/effect/spawner/armory_spawn/microfusion,
/turf/open/floor/iron/dark/corner{
dir = 8
},
@@ -9627,7 +9627,7 @@
dir = 8
},
/obj/structure/rack/gunrack,
/obj/effect/spawner/armory_spawn/rifles,
/obj/effect/spawner/armory_spawn/microfusion,
/turf/open/floor/iron/dark,
/area/ai_monitored/security/armory)
"bEx" = (
@@ -625,7 +625,7 @@
"agU" = (
/obj/structure/rack/gunrack,
/obj/effect/turf_decal/delivery/blue,
/obj/effect/spawner/armory_spawn/rifles,
/obj/effect/spawner/armory_spawn/microfusion,
/obj/machinery/light/directional/east,
/turf/open/floor/iron/dark,
/area/ai_monitored/security/armory)
@@ -62743,7 +62743,7 @@
"uom" = (
/obj/machinery/airalarm/directional/north,
/obj/structure/rack/gunrack,
/obj/effect/spawner/armory_spawn/rifles,
/obj/effect/spawner/armory_spawn/microfusion,
/obj/effect/turf_decal/delivery/red,
/turf/open/floor/iron/smooth,
/area/ai_monitored/security/armory)
+1 -1
View File
@@ -37168,7 +37168,7 @@
"dZT" = (
/obj/machinery/airalarm/directional/north,
/obj/structure/rack/gunrack,
/obj/effect/spawner/armory_spawn/rifles,
/obj/effect/spawner/armory_spawn/microfusion,
/obj/effect/turf_decal/delivery/red,
/turf/open/floor/iron/smooth,
/area/ai_monitored/security/armory)
@@ -19863,7 +19863,7 @@
/area/security/detectives_office)
"eog" = (
/obj/structure/rack/gunrack,
/obj/effect/spawner/armory_spawn/rifles,
/obj/effect/spawner/armory_spawn/microfusion,
/turf/open/floor/iron/smooth,
/area/ai_monitored/security/armory)
"eoj" = (
+4
View File
@@ -191,6 +191,7 @@ GLOBAL_LIST_INIT(security_hardsuit_allowed, typecacheof(list(
/obj/item/reagent_containers/spray/pepper,
/obj/item/restraints/handcuffs,
/obj/item/tank/internals,
/obj/item/gun/microfusion, //SKYRAT EDIT ADDITION
)))
GLOBAL_LIST_INIT(detective_vest_allowed, typecacheof(list(
@@ -210,6 +211,7 @@ GLOBAL_LIST_INIT(detective_vest_allowed, typecacheof(list(
/obj/item/tank/internals/plasmaman,
/obj/item/storage/belt/holster/detective,
/obj/item/storage/belt/holster/nukie,
/obj/item/gun/microfusion, //SKYRAT EDIT ADDITION
)))
GLOBAL_LIST_INIT(security_vest_allowed, typecacheof(list(
@@ -226,6 +228,7 @@ GLOBAL_LIST_INIT(security_vest_allowed, typecacheof(list(
/obj/item/tank/internals/plasmaman,
/obj/item/storage/belt/holster/detective,
/obj/item/storage/belt/holster/nukie,
/obj/item/gun/microfusion, //SKYRAT EDIT ADDITION
)))
GLOBAL_LIST_INIT(security_wintercoat_allowed, typecacheof(list(
@@ -238,6 +241,7 @@ GLOBAL_LIST_INIT(security_wintercoat_allowed, typecacheof(list(
/obj/item/restraints/handcuffs,
/obj/item/storage/belt/holster/detective,
/obj/item/storage/belt/holster/nukie,
/obj/item/gun/microfusion, //SKYRAT EDIT ADDITION
)))
/// String for items placed into the left pocket.
+3
View File
@@ -23,6 +23,9 @@
#define TRAIT_ASH_ASPECT "ash_aspect"
#define TRAIT_SPARKLE_ASPECT "sparkle_aspect"
/// Allows the user to instantly reload.
#define TRAIT_INSTANT_RELOAD "instant_reload"
// Trait sources
#define GHOSTROLE_TRAIT "ghostrole" // SKYRAT EDIT ADDITION -- Ghost Cafe Traits
+6 -1
View File
@@ -43,6 +43,12 @@
if(charging)
to_chat(user, span_warning("There is already a cell in the charger!"))
return
//SKYRAT EDIT ADDITION
var/obj/item/stock_parts/cell/inserting_cell = W
if(inserting_cell.chargerate <= 0)
to_chat(user, span_warning("[inserting_cell] cannot be recharged!"))
return
//SKYRAT EDIT END
else
var/area/a = loc.loc // Gets our locations location, like a dream within a dream
if(!isarea(a))
@@ -125,7 +131,6 @@
/obj/machinery/cell_charger/process(delta_time)
if(!charging || !anchored || (machine_stat & (BROKEN|NOPOWER)))
return
if(charging.percent() >= 100)
return
+15
View File
@@ -16,6 +16,8 @@
var/finished_recharging = FALSE
var/static/list/allowed_devices = typecacheof(list(
/obj/item/stock_parts/cell/microfusion, //SKYRAT EDIT ADDITION
/obj/item/gun/microfusion, // SKYRAT EDIT ADDITION
/obj/item/gun/energy,
/obj/item/melee/baton/security,
/obj/item/ammo_box/magazine/recharge,
@@ -86,6 +88,19 @@
to_chat(user, span_notice("Your gun has no external power connector."))
return 1
//SKYRAT EDIT ADDITION
if (istype(G, /obj/item/gun/microfusion))
var/obj/item/gun/microfusion/microfusion_gun = G
if(microfusion_gun.cell?.chargerate <= 0)
to_chat(user, span_notice("[microfusion_gun] cannot be recharged!"))
return TRUE
if(istype(G, /obj/item/stock_parts/cell/microfusion))
var/obj/item/stock_parts/cell/microfusion/inserting_cell = G
if(inserting_cell.chargerate <= 0)
to_chat(user, span_notice("[inserting_cell] cannot be recharged!"))
return TRUE
//SKYRAT EDIT END
if(!user.transferItemToLoc(G, src))
return 1
setCharging(G)
+2 -1
View File
@@ -254,7 +254,8 @@
/obj/item/radio,
/obj/item/clothing/gloves,
/obj/item/restraints/legcuffs/bola,
/obj/item/holosign_creator/security
/obj/item/holosign_creator/security,
/obj/item/stock_parts/cell/microfusion, //SKYRAT EDIT ADDITION
))
/obj/item/storage/belt/security/full/PopulateContents()
+11 -1
View File
@@ -46,8 +46,10 @@
if (override_maxcharge)
maxcharge = override_maxcharge
charge = maxcharge
/* SKYRAT EDIT REMOVAL
if(ratingdesc)
desc += " This one has a rating of [display_energy(maxcharge)], and you should not swallow it."
*/ // SKYRAT EDIT END
update_appearance()
/obj/item/stock_parts/cell/create_reagents(max_vol, flags)
@@ -67,7 +69,7 @@
. += mutable_appearance('icons/obj/power.dmi', "grown_wires")
if(charge < 0.01)
return
. += mutable_appearance('modular_skyrat/modules/aesthetics/cells/cell.dmi', "cell-o[((charge / maxcharge) >= 0.995) ? 2 : 1]") //SKYRAT EDIT CHANGE
. += mutable_appearance(charge_overlay_icon, "cell-o[((charge / maxcharge) >= 0.995) ? 2 : 1]") //SKYRAT EDIT CHANGE
/obj/item/stock_parts/cell/proc/percent() // return % charge of cell
return 100*charge/maxcharge
@@ -97,8 +99,16 @@
/obj/item/stock_parts/cell/examine(mob/user)
. = ..()
// SKYRAT EDIT ADDITION
if(ratingdesc && !microfusion_readout)
. += "This one has a rating of [display_energy(maxcharge)], and you should not swallow it."
// SKYRAT EDIT END
if(rigged)
. += span_danger("This power cell seems to be faulty!")
// SKYRAT EDIT ADDITION
else if(microfusion_readout)
. += "The charge meter reads [charge]/[maxcharge] MF."
// SKYRAT EDIT END
else
. += "The charge meter reads [round(src.percent() )]%."
+2 -25
View File
@@ -33,8 +33,6 @@
var/use_cyborg_cell = FALSE
///set to true so the gun is given an empty cell
var/dead_cell = FALSE
///Does this gun support swapping energy cells?
var/supports_swapping_cells = FALSE
/obj/item/gun/energy/emp_act(severity)
. = ..()
@@ -106,6 +104,7 @@
ammo_type[i] = shot
shot = ammo_type[select]
fire_sound = shot.fire_sound
fire_sound_volume = shot.fire_sound_volume //SKYRAT EDIT ADDITION
fire_delay = shot.delay
/obj/item/gun/energy/Destroy()
@@ -180,6 +179,7 @@
select = 1
var/obj/item/ammo_casing/energy/shot = ammo_type[select]
fire_sound = shot.fire_sound
fire_sound_volume = shot.fire_sound_volume //SKYRAT EDIT ADDITION
fire_delay = shot.delay
if (shot.select_name && user)
balloon_alert(user, "set to [shot.select_name]")
@@ -208,29 +208,6 @@
worn_icon_state = temp_icon_to_use
return ..()
// SKYRAT ADDITION START
/obj/item/gun/energy/attackby(obj/item/A, mob/user, params)
. = ..()
if (.)
return
if(!supports_swapping_cells)
return
if(istype(A, /obj/item/stock_parts/cell))
if(!cell)
to_chat(user, span_notice("You insert [A] into [src]."))
cell = A
A.forceMove(src)
cut_overlays()
update_overlays()
return
to_chat(user, span_notice("You swap [cell] for [A] in [src]."))
cell.forceMove(get_turf(src))
cell = A
A.forceMove(src)
cut_overlays()
update_overlays()
// SKYRAT ADDITION END
/obj/item/gun/energy/update_overlays()
. = ..()
// SKYRAT EDIT START
@@ -61,8 +61,11 @@
var/obj/item/flashlight/seclite/gun_light
var/datum/action/item_action/toggle_gunlight/alight
var/gunlight_state = "flight"
var/gunlight_icon = 'icons/obj/guns/flashlights.dmi'
var/can_bayonet = FALSE //if a bayonet can be added or removed if it already has one.
var/bayonet_state = "bayonet"
var/bayonet_icon = 'icons/obj/guns/bayonets.dmi'
var/obj/item/knife/bayonet
var/knife_x_offset = 0
var/knife_y_offset = 0
@@ -728,20 +731,19 @@
if(gun_light)
var/mutable_appearance/flashlight_overlay
var/state = "[gunlight_state][gun_light.on? "_on":""]" //Generic state.
if(gun_light.icon_state in icon_states('icons/obj/guns/flashlights.dmi')) //Snowflake state?
if(gun_light.icon_state in icon_states(gunlight_icon)) //Snowflake state?
state = gun_light.icon_state
flashlight_overlay = mutable_appearance('icons/obj/guns/flashlights.dmi', state)
flashlight_overlay = mutable_appearance(gunlight_icon, state)
flashlight_overlay.pixel_x = flight_x_offset
flashlight_overlay.pixel_y = flight_y_offset
. += flashlight_overlay
if(bayonet)
var/mutable_appearance/knife_overlay
var/state = "bayonet" //Generic state.
if(bayonet.icon_state in icon_states('icons/obj/guns/bayonets.dmi')) //Snowflake state?
var/state = bayonet_state
if(bayonet.icon_state in icon_states(bayonet_icon)) //Snowflake state?
state = bayonet.icon_state
var/icon/bayonet_icons = 'icons/obj/guns/bayonets.dmi'
knife_overlay = mutable_appearance(bayonet_icons, state)
knife_overlay = mutable_appearance(bayonet_icon, state)
knife_overlay.pixel_x = knife_x_offset
knife_overlay.pixel_y = knife_y_offset
. += knife_overlay
@@ -1,5 +1,7 @@
/obj/item/stock_parts/cell
icon = 'modular_skyrat/modules/aesthetics/cells/cell.dmi'
/// The charge overlay icon file for the cell charge lights
var/charge_overlay_icon = 'modular_skyrat/modules/aesthetics/cells/cell.dmi'
/obj/machinery/cell_charger
icon = 'modular_skyrat/modules/aesthetics/cells/cell.dmi'
@@ -48,7 +48,6 @@
ammo_type = list(/obj/item/ammo_casing/energy/laser/hardlight_bullet/vintorez)
shaded_charge = TRUE
cell_type = /obj/item/stock_parts/cell/super
supports_swapping_cells = TRUE
/obj/item/ammo_casing/energy/laser/hardlight_bullet/vintorez
name = "hardlight bullet vintorez casing"
@@ -85,7 +84,6 @@
fire_delay = 10
shaded_charge = TRUE
cell_type = /obj/item/stock_parts/cell/super
supports_swapping_cells = TRUE
/obj/item/ammo_casing/energy/laser/hardlight_bullet/norwind
name = "hardlight bullet norwind casing"
@@ -114,8 +112,6 @@
can_bayonet = TRUE
ammo_type = list(/obj/item/ammo_casing/energy/laser/hardlight_bullet/ostwind)
cell_type = /obj/item/stock_parts/cell/super
supports_swapping_cells = TRUE
/obj/item/ammo_casing/energy/laser/hardlight_bullet/ostwind
name = "hardlight bullet norostwindwind casing"
projectile_type = /obj/projectile/beam/laser/hardlight_bullet/ostwind
@@ -146,7 +142,6 @@
ammo_type = list(/obj/item/ammo_casing/energy/laser/hardlight_bullet/pitbull)
shaded_charge = TRUE
cell_type = /obj/item/stock_parts/cell/super
supports_swapping_cells = TRUE
/obj/item/ammo_casing/energy/laser/hardlight_bullet/pitbull
name = "hardlight bullet pitbull casing"
@@ -175,7 +170,6 @@
ammo_type = list(/obj/item/ammo_casing/energy/laser/hardlight_bullet/pcr)
shaded_charge = TRUE
cell_type = /obj/item/stock_parts/cell/super
supports_swapping_cells = TRUE
/obj/item/ammo_casing/energy/laser/hardlight_bullet/pcr
name = "hardlight bullet pcr casing"
@@ -196,7 +190,6 @@
fire_delay = 2 SECONDS
ammo_type = list(/obj/item/ammo_casing/energy/laser/hardlight_bullet/peacemaker)
shaded_charge = TRUE
supports_swapping_cells = FALSE
/obj/item/ammo_casing/energy/laser/hardlight_bullet/peacemaker
name = "hardlight bullet peacemaker casing"
@@ -208,14 +201,3 @@
damage = 60
*/
//////////////RIFLE SPAWNER
/obj/effect/spawner/armory_spawn/rifles
icon_state = "random_rifle"
gun_count = 4
guns = list(
/obj/item/gun/energy/pcr,
/obj/item/gun/energy/pitbull,
/obj/item/gun/energy/ostwind,
/obj/item/gun/energy/norwind,
/obj/item/gun/energy/vintorez,
)
@@ -152,6 +152,44 @@
oth_h = "h9"
hud.set_hud(backing_color, oth_o, oth_t, oth_h, indicator)
else if(istype(parent, /obj/item/gun/microfusion))
var/obj/item/gun/microfusion/parent_gun = parent
if(!parent_gun.phase_emitter)
hud.icon_state = "microfusion_counter_no_emitter"
hud.maptext = null
return
if(parent_gun.phase_emitter.damaged)
hud.icon_state = "microfusion_counter_damaged"
hud.maptext = null
return
if(!parent_gun.cell)
hud.icon_state = "microfusion_counter_no_emitter"
hud.maptext = null
return
if(!parent_gun.cell.charge)
hud.icon_state = "microfusion_counter_no_emitter"
hud.maptext = null
return
var/phase_emitter_state = parent_gun.phase_emitter.get_heat_icon_state()
hud.icon_state = "microfusion_counter_[phase_emitter_state]"
hud.cut_overlays()
hud.maptext_x = -12
var/obj/item/ammo_casing/energy/shot = parent_gun.microfusion_lens
var/battery_percent = FLOOR(clamp(parent_gun.cell.charge / parent_gun.cell.maxcharge, 0, 1) * 100, 1)
var/shot_cost_percent = FLOOR(clamp(shot.e_cost / parent_gun.cell.maxcharge, 0, 1) * 100, 1)
if(battery_percent > 99 || shot_cost_percent > 99)
hud.maptext_x = -12
else
hud.maptext_x = -8
if(!parent_gun.can_shoot())
hud.icon_state = "microfusion_counter_no_emitter"
return
if(battery_percent <= 25)
hud.maptext = span_maptext("<div align='center' valign='middle' style='position:relative'><font color='[COLOR_YELLOW]'>[battery_percent]%</font><br><font color='[COLOR_CYAN]'>[shot_cost_percent]%</font></div>")
return
hud.maptext = span_maptext("<div align='center' valign='middle' style='position:relative'><font color='[COLOR_VIBRANT_LIME]'>[battery_percent]%</font><br><font color='[COLOR_CYAN]'>[shot_cost_percent]%</font></div>")
/obj/item/gun/ballistic/ComponentInitialize()
. = ..()
AddComponent(/datum/component/ammo_hud)
Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.2 KiB

After

Width:  |  Height:  |  Size: 11 KiB

@@ -1,15 +1,28 @@
/obj/item/gun/ballistic
var/alt_icons = FALSE //Does this gun have mag and nomag on mob variance?
var/alt_icon_state //What the icon state is for the on-back guns
var/realistic = FALSE //realistic guns that use reliability and dirt
var/jammed = FALSE //Is it jammed?
var/dirt_level = 0 //how dirty a gun is.
var/dirt_modifier = 0.1 //Tied in with how good a gun is, if firing it causes a lot of dirt to form, then change this accordingly.
var/jam_chance = 0 //Used when calculating if a gun will jam or not.
var/unjam_time = 0 //Used when calculating how long a gun takes to unjam.
/// Does this gun have mag and nomag on mob variance?
var/alt_icons = FALSE
/// What the icon state is for the on-back guns
var/alt_icon_state
/// Realistic guns that use reliability and dirt
var/realistic = FALSE
/// Is it jammed?
var/jammed = FALSE
/// How dirty a gun is.
var/dirt_level = 0
/// Tied in with how good a gun is, if firing it causes a lot of dirt to form, then change this accordingly.
var/dirt_modifier = 0.1
/// Used when calculating if a gun will jam or not.
var/jam_chance = 0
/// Used when calculating how long a gun takes to unjam.
var/unjam_time = 0
/// Tracking gun base spred.
var/base_spread = 0
var/durability = 100 //How used this gun is.
var/durability_factor = 0.1 //How quickly a gun will degrade. 0.1 = 1000 shots. Edit this to change a guns base reliability.
/// How used this gun is.
var/durability = 100
/// How quickly a gun will degrade. 0.1 = 1000 shots. Edit this to change a guns base reliability.
var/durability_factor = 0.1
/// How long it takes to reload a magazine.
var/reload_time = 2 SECONDS
/obj/item/gun/ballistic/Initialize()
@@ -40,6 +53,14 @@
inhand_icon_state = "[initial(icon_state)]"
worn_icon_state = "[initial(icon_state)]"
/obj/item/gun/ballistic/insert_magazine(mob/user, obj/item/ammo_box/magazine/AM, display_message)
if(reload_time && !HAS_TRAIT(user, TRAIT_INSTANT_RELOAD) && magazine) //This only happens when you're attempting a tactical reload, e.g. there's a mag already inserted.
to_chat(user, span_notice("You start to insert the magazine into [src]!"))
if(!do_after(user, reload_time, src))
to_chat(user, span_danger("You fail to insert the magazine into [src]!"))
return
. = ..()
/obj/item/gun/ballistic/assault_rifle
rack_sound = 'modular_skyrat/modules/gunsgalore/sound/guns/interact/ltrifle_cock.ogg'
load_sound = 'modular_skyrat/modules/gunsgalore/sound/guns/interact/ltrifle_magin.ogg'
@@ -134,6 +155,8 @@
if(jammed)
jam(TRUE, user)
return
if(!internal_magazine && magazine && user.Adjacent(src))
eject_magazine(user)
. = ..()
/obj/item/gun/ballistic/examine(mob/user)
@@ -0,0 +1,9 @@
/obj/item/skillchip/chameleon/reload
name = "T.A.C.T.I.C00L skillchip"
desc = "If used, allows the user to perform tactical and instant reloads on all weapons with a magazine."
auto_traits = list(TRAIT_INSTANT_RELOAD)
skill_name = "Tactical Reloading"
skill_description = "Fine tune motor skills when performing reloads on weapons to reduce time taken."
skill_icon = "sitemap"
activate_message = span_notice("You suddenly learn the art of tactical reloading.")
deactivate_message = span_danger("You suddenly lose the ability to tactically reload.")
@@ -0,0 +1,52 @@
/// The amount of cell charge drained during a drain failure.
#define MICROFUSION_CELL_DRAIN_FAILURE 500
/// The heavy EMP range for when a cell suffers an EMP failure.
#define MICROFUSION_CELL_EMP_HEAVY_FAILURE 2
/// The light EMP range for when a cell suffers an EMP failure.
#define MICROFUSION_CELL_EMP_LIGHT_FAILURE 4
/// The radiation range for when a cell suffers a radiation failure.
#define MICROFUSION_CELL_RADIATION_RANGE_FAILURE 1
/// The lower most time for a microfusion cell meltdown.
#define MICROFUSION_CELL_FAILURE_LOWER 10 SECONDS
/// The upper most time for a microfusion cell meltdown.
#define MICROFUSION_CELL_FAILURE_UPPER 15 SECONDS
/// A charge drain failure.
#define MICROFUSION_CELL_FAILURE_TYPE_CHARGE_DRAIN 1
/// A small explosion failure.
#define MICROFUSION_CELL_FAILURE_TYPE_EXPLOSION 2
/// EMP failure.
#define MICROFUSION_CELL_FAILURE_TYPE_EMP 3
/// Radiation failure.
#define MICROFUSION_CELL_FAILURE_TYPE_RADIATION 4
/// Returned when the phase emtiter process is successful.
#define SHOT_SUCCESS "success"
/// Returned when a gun is fired but there is no phase emitter.
#define SHOT_FAILURE_NO_EMITTER "No phase emitter installed!"
/// The error message returned when the phase emitter is processed but damaged.
#define PHASE_FAILURE_DAMAGED "PHASE EMITTER: Emitter damaged!"
/// The error message returned when the phase emitter has reached it's htermal throttle.
#define PHASE_FAILURE_THROTTLE "PHASE EMITTER: Thermal throttle active!"
/// The heat dissipation bonus of an emitter being in space!
#define PHASE_HEAT_DISSIPATION_BONUS_SPACE 30
/// The heat dissipation bonus of an emitter being in air!
#define PHASE_HEAT_DISSIPATION_BONUS_AIR 10
// Slot defines for the gun.
/// The gun barrel slot.
#define GUN_SLOT_BARREL "barrel"
/// The gun underbarrel slot.
#define GUN_SLOT_UNDERBARREL "underbarrel"
/// The gun rail slot.
#define GUN_SLOT_RAIL "rail"
/// Unique slots, can hold as many as you want.
#define GUN_SLOT_UNIQUE "unique"
/// Max name size for changing names
#define GUN_MAX_NAME_CHARS 20
/// Min name size for changing names
#define GUN_MIN_NAME_CHARS 3
@@ -0,0 +1,51 @@
/datum/supply_pack/security/armory/mcr01
name = "MCR-01 Microfusion Crate"
desc = "Micron Control Systems Incorporated supplied MCR-01 Microfusion weapons platform. Comes with 4 guns and 4 advanced cells!"
cost = CARGO_CRATE_VALUE * 20
contains = list(
/obj/item/gun/microfusion/mcr01/advanced,
/obj/item/gun/microfusion/mcr01/advanced,
/obj/item/gun/microfusion/mcr01/advanced,
/obj/item/gun/microfusion/mcr01/advanced,
/obj/item/storage/box/ammo_box/microfusion/advanced,
/obj/item/storage/box/ammo_box/microfusion/advanced,
/obj/item/storage/box/ammo_box/microfusion/advanced,
/obj/item/storage/box/ammo_box/microfusion/advanced,
)
crate_name = "MCR-01 Microfusion Crate"
/datum/supply_pack/security/microfusion
name = "Assorted Microfusion Cell Crate"
desc = "Micron Control Systems Incorporated supplied Microfusion cells and attachments!"
cost = CARGO_CRATE_VALUE * 5
contains = list(
/obj/item/stock_parts/cell/microfusion/advanced,
/obj/item/stock_parts/cell/microfusion/advanced,
/obj/item/stock_parts/cell/microfusion/advanced,
/obj/item/stock_parts/cell/microfusion/advanced,
/obj/item/stock_parts/cell/microfusion/advanced,
/obj/item/stock_parts/cell/microfusion/advanced,
/obj/item/microfusion_cell_attachment/rechargeable,
/obj/item/microfusion_cell_attachment/rechargeable,
/obj/item/microfusion_cell_attachment/rechargeable,
/obj/item/microfusion_cell_attachment/rechargeable,
/obj/item/microfusion_cell_attachment/rechargeable,
/obj/item/microfusion_cell_attachment/rechargeable,
)
crate_name = "Microfusion Cell Crate"
/datum/supply_pack/security/mcr01_attachments
name = "MCR-01 Military Attachments Crate"
desc = "Micron Control Systems Incorporated supplied MCR-01 Military spec attachments!"
cost = CARGO_CRATE_VALUE * 15
contains = list(
/obj/item/microfusion_gun_attachment/scope,
/obj/item/microfusion_gun_attachment/scope,
/obj/item/microfusion_gun_attachment/grip,
/obj/item/microfusion_gun_attachment/grip,
/obj/item/microfusion_gun_attachment/rail,
/obj/item/microfusion_gun_attachment/rail,
/obj/item/microfusion_gun_attachment/repeater,
/obj/item/microfusion_gun_attachment/repeater,
)
crate_name = "MCR-01 Military Attachments Crate"
@@ -0,0 +1,41 @@
/obj/item/gun/microfusion/mcr01
name = "MCR-01"
desc = "An advanced, modular energy weapon produced by Allstar Lasers Incorporated. These cutting edge weapons differ from traditional beam weaponry in producing individual bolts, as well as utilizing hotswapped cells rather than being tied to immobile power sources."
icon_state = "mcr01"
inhand_icon_state = "mcr01"
shaded_charge = TRUE
/// Gun for cargo crates.
/obj/item/gun/microfusion/mcr01/advanced
name = "Advanced MCR-01"
cell_type = /obj/item/stock_parts/cell/microfusion/advanced
phase_emitter_type = /obj/item/microfusion_phase_emitter/advanced
/obj/item/gun/microfusion/mcr01/nanocarbon
name = "Nanocarbon Destroyer"
desc = "The pinnacle of the Nanocarbon weapon line. This weapon is the ultimate in power and performance. It is capable of firing a wide variety of beams, including a wide range of energy types, and is capable of firing a wide variety of frequencies."
icon_state = "mcr01"
inhand_icon_state = "mcr01"
shaded_charge = TRUE
/obj/item/storage/box/ammo_box/microfusion/advanced
name = "advanced microfusion cell container"
desc = "A box filled with microfusion cells."
/obj/item/storage/box/ammo_box/microfusion/advanced/PopulateContents()
new /obj/item/storage/bag/ammo(src)
new /obj/item/stock_parts/cell/microfusion/advanced(src)
new /obj/item/stock_parts/cell/microfusion/advanced(src)
new /obj/item/stock_parts/cell/microfusion/advanced(src)
//////////////MICROFUSION SPAWNERS
/obj/effect/spawner/armory_spawn/microfusion
icon_state = "random_rifle"
gun_count = 4
guns = list(
/obj/item/gun/microfusion/mcr01,
/obj/item/gun/microfusion/mcr01,
/obj/item/gun/microfusion/mcr01,
/obj/item/gun/microfusion/mcr01,
)
@@ -0,0 +1,189 @@
/*
MICROFUSION CELL SYSTEM
Microfusion cells are small battery units that house controlled nuclear fusion within, and that fusion is converted into useable energy.
They cannot be charged as standard, and require upgrades to do so.
These are basically advanced cells.
*/
/obj/item/stock_parts/cell/microfusion //Just a standard cell.
name = "microfusion cell"
desc = "A standard-issue microfusion cell, produced by Micron Control Systems. Smaller than a can of soda, these fulfill the need for a power source where plugging into a recharger is inconvenient or unavailable; although they will eventually run dry due to being shipped without a fuel source."
icon = 'modular_skyrat/modules/microfusion/icons/microfusion_cells.dmi'
charge_overlay_icon = 'modular_skyrat/modules/microfusion/icons/microfusion_cells.dmi'
icon_state = "microfusion"
w_class = WEIGHT_CLASS_NORMAL
maxcharge = 1200 //12 shots
chargerate = 0 //Standard microfusion cells can't be recharged, they're single use.
microfusion_readout = TRUE
/// A hard referenced list of upgrades currently attached to the weapon.
var/list/attachments = list()
/// Are we melting down? For icon stuffs.
var/meltdown = FALSE
/// How many upgrades can you have on this cell?
var/max_attachments = 1
/// Hard ref to the parent gun.
var/obj/item/gun/microfusion/parent_gun
/// Do we play an alarm when empty?
var/empty_alarm = TRUE
/// What sound do we play when empty?
var/empty_alarm_sound = 'sound/weapons/gun/general/empty_alarm.ogg'
/// Do we have the self charging upgrade?
var/self_charging = FALSE
/obj/item/stock_parts/cell
/// Is this cell stabilised? (used in microfusion guns)
var/stabilised = FALSE
/// Do we show the microfusion readout instead of KJ?
var/microfusion_readout = FALSE
/obj/item/stock_parts/cell/microfusion/Destroy()
if(attachments.len)
for(var/obj/item/iterating_item as anything in attachments)
iterating_item.forceMove(get_turf(src))
attachments = null
parent_gun = null
return ..()
/obj/item/stock_parts/cell/microfusion/attackby(obj/item/attacking_item, mob/living/user, params)
if(istype(attacking_item, /obj/item/microfusion_cell_attachment))
add_attachment(attacking_item, user)
return
return ..()
/obj/item/stock_parts/cell/microfusion/emp_act(severity)
var/prob_percent = charge / 100 * severity
if(prob(prob_percent) && !meltdown && !stabilised && parent_gun)
process_instability()
/obj/item/stock_parts/cell/microfusion/use(amount)
if(charge >= amount)
var/check_if_empty = charge - amount
if(check_if_empty < amount && empty_alarm && !self_charging)
playsound(src, empty_alarm_sound, 50)
return ..()
/obj/item/stock_parts/cell/microfusion/proc/process_instability()
var/seconds_to_explode = rand(MICROFUSION_CELL_FAILURE_LOWER, MICROFUSION_CELL_FAILURE_UPPER)
meltdown = TRUE
say("Malfunction in [seconds_to_explode] seconds!")
playsound(src, 'sound/machines/warning-buzzer.ogg', 30, FALSE, FALSE)
add_filter("rad_glow", 2, list("type" = "outline", "color" = "#ff5e0049", "size" = 2))
addtimer(CALLBACK(src, .proc/process_failure), seconds_to_explode)
/obj/item/stock_parts/cell/microfusion/proc/process_failure()
var/fuckup_type = rand(1, 4)
remove_filter("rad_glow")
playsound(src, 'sound/effects/spray.ogg', 70)
switch(fuckup_type)
if(MICROFUSION_CELL_FAILURE_TYPE_CHARGE_DRAIN)
charge = clamp(charge - MICROFUSION_CELL_DRAIN_FAILURE, 0, maxcharge)
if(MICROFUSION_CELL_FAILURE_TYPE_EXPLOSION)
explode()
if(MICROFUSION_CELL_FAILURE_TYPE_EMP)
empulse(get_turf(src), MICROFUSION_CELL_EMP_HEAVY_FAILURE, MICROFUSION_CELL_EMP_LIGHT_FAILURE, FALSE)
if(MICROFUSION_CELL_FAILURE_TYPE_RADIATION)
radiation_pulse(src, MICROFUSION_CELL_RADIATION_RANGE_FAILURE, RAD_MEDIUM_INSULATION)
meltdown = FALSE
/obj/item/stock_parts/cell/microfusion/update_overlays()
. = ..()
for(var/obj/item/microfusion_cell_attachment/microfusion_cell_attachment as anything in attachments)
. += microfusion_cell_attachment.attachment_overlay_icon_state
/obj/item/stock_parts/cell/microfusion/screwdriver_act(mob/living/user, obj/item/tool)
if(!attachments.len)
to_chat(user, span_danger("There are no attachments to remove!"))
return
remove_attachments()
playsound(src, 'sound/items/screwdriver.ogg', 70, TRUE)
to_chat(user, span_notice("You remove the upgrades from [src]."))
/obj/item/stock_parts/cell/microfusion/process(delta_time)
for(var/obj/item/microfusion_cell_attachment/microfusion_cell_attachment as anything in attachments)
microfusion_cell_attachment.process_attachment(src, delta_time)
/obj/item/stock_parts/cell/microfusion/examine(mob/user)
. = ..()
. += span_notice("It can hold [max_attachments] attachment(s).")
if(attachments.len)
for(var/obj/item/microfusion_cell_attachment/microfusion_cell_attachment as anything in attachments)
. += span_notice("It has a [microfusion_cell_attachment.name] installed.")
. += span_notice("Use a <b>screwdriver</b> to remove the attachments.")
/obj/item/stock_parts/cell/microfusion/proc/add_attachment(obj/item/microfusion_cell_attachment/microfusion_cell_attachment, mob/living/user)
if(attachments.len >= max_attachments)
to_chat(user, span_warning("[src] cannot fit any more attachments!"))
return FALSE
if(is_type_in_list(microfusion_cell_attachment, attachments))
to_chat(user, span_warning("[src] already has [microfusion_cell_attachment] installed!"))
return FALSE
attachments += microfusion_cell_attachment
microfusion_cell_attachment.forceMove(src)
microfusion_cell_attachment.add_attachment(src)
to_chat(user, span_notice("You successfully install [microfusion_cell_attachment] onto [src]!"))
playsound(src, 'sound/effects/structure_stress/pop2.ogg', 70, TRUE)
update_appearance()
return TRUE
/obj/item/stock_parts/cell/microfusion/proc/remove_attachments()
for(var/obj/item/microfusion_cell_attachment/microfusion_cell_attachment in attachments)
microfusion_cell_attachment.remove_attachment(src)
microfusion_cell_attachment.forceMove(get_turf(src))
attachments -= microfusion_cell_attachment
update_appearance()
/datum/crafting_recipe/makeshift/microfusion_cell
name = "Makeshift Microfusion Cell"
tool_behaviors = list(TOOL_SCREWDRIVER, TOOL_WIRECUTTER, TOOL_WELDER)
result = /obj/item/stock_parts/cell/microfusion/makeshift
reqs = list(/obj/item/trash/can = 1,
/obj/item/stack/sheet/iron = 1,
/obj/item/stack/cable_coil = 1)
time = 12 SECONDS
category = CAT_MISC
//WHY WOULD YOU MAKE THIS?
/obj/item/stock_parts/cell/microfusion/makeshift
name = "makeshift microfusion cell"
desc = "An... Apparatus, comprised of an everyday aluminum can with several civilian-grade batteries tightly packed together and plugged in. This vaguely resembles a microfusion cell, if you tilt your head to a precise fifty degree angle. While the effects on enemy combatants may be dubious, it will certainly do incredible damage to the gun's warranty. What the hell were you thinking when you came up with this?"
icon_state = "microfusion_makeshift"
maxcharge = 600
max_attachments = 0
/// The probability of the cell failing
var/fail_prob = 10
/obj/item/stock_parts/cell/microfusion/makeshift/use(amount)
if(prob(fail_prob))
process_instability()
return ..()
/obj/item/stock_parts/cell/microfusion/enhanced
name = "enhanced microfusion cell"
desc = "A second generation microfusion cell, weighing about the same as the standard-issue cell and having the same space for attachments; however, it has a higher capacity."
icon_state = "microfusion_enhanced"
maxcharge = 1500
/obj/item/stock_parts/cell/microfusion/advanced
name = "advanced microfusion cell"
desc = "A third generation microfusion cell, boasting a much higher shot count. Additionally, these come with support for up to three modifications to the cell itself."
icon_state = "microfusion_advanced"
maxcharge = 1700
max_attachments = 3
/obj/item/stock_parts/cell/microfusion/bluespace
name = "bluespace microfusion cell"
desc = "A fourth generation microfusion cell, employing bluespace technology to store power in a medium that's bigger on the inside. This has the highest capacity of any man-portable cell, and has flexibility for four different attachments to the cell itself."
icon_state = "microfusion_bluespace"
maxcharge = 2000
max_attachments = 4
/obj/item/stock_parts/cell/microfusion/nanocarbon
name = "nanocarbon fusion cell"
desc = "This cell combines both top-of-the-line nanotech and advanced microfusion power to brute force the most common issue of Nanotrasen Asset Protection operatives, ammunition, through sheer volume. Intended for use with Nanotrasen-brand capacitor arrays only. Warranty void if dropped in toilet."
icon_state = "microfusion_nanocarbon"
maxcharge = 30000
max_attachments = 420
@@ -0,0 +1,132 @@
/*
MICROFUSION CELL UPGRADE ATTACHMENTS
For adding unique abilities to microfusion cells. These cannot directly interact with the gun.
*/
/obj/item/microfusion_cell_attachment
name = "microfusion cell attachment"
desc = "broken"
icon = 'modular_skyrat/modules/microfusion/icons/microfusion_cells.dmi'
w_class = WEIGHT_CLASS_NORMAL
/// The overlay that will be automatically added, must be in the cells icon.
var/attachment_overlay_icon_state
/// Does this attachment process with the cell?
var/processing_attachment = FALSE
/obj/item/microfusion_cell_attachment/proc/add_attachment(obj/item/stock_parts/cell/microfusion/microfusion_cell)
SHOULD_CALL_PARENT(TRUE)
START_PROCESSING(SSobj, microfusion_cell)
return
/obj/item/microfusion_cell_attachment/proc/process_attachment(obj/item/stock_parts/cell/microfusion/microfusion_cell, delta_time)
return PROCESS_KILL
/obj/item/microfusion_cell_attachment/proc/remove_attachment(obj/item/stock_parts/cell/microfusion/microfusion_cell)
SHOULD_CALL_PARENT(TRUE)
STOP_PROCESSING(SSobj, microfusion_cell)
return
/*
rechargeable ATTACHMENT
Allows the cell to be recharged at a gun recharger OR cell recharger.
*/
/obj/item/microfusion_cell_attachment/rechargeable
name = "rechargeable microfusion cell attachment"
desc = "An adapter meant to be plugged into a microfusion cell, allowing the cell to be recharged at recharge stations for both weapons and civilian-grade batteries. Neither Allstar Lasers Incorporated or Micron Control Systems Incorporated suggest licking the prongs."
icon_state = "attachment_rechargeable"
attachment_overlay_icon_state = "microfusion_rechargeable"
/// The bonus charge rate by adding this attachment.
var/bonus_charge_rate = 300
/obj/item/microfusion_cell_attachment/rechargeable/add_attachment(obj/item/stock_parts/cell/microfusion/microfusion_cell)
. = ..()
microfusion_cell.chargerate += bonus_charge_rate
/obj/item/microfusion_cell_attachment/rechargeable/remove_attachment(obj/item/stock_parts/cell/microfusion/microfusion_cell)
. = ..()
microfusion_cell.chargerate -= bonus_charge_rate
/*
OVERCAPACITY ATTACHMENT
Increases the cell capacity by a set percentage.
*/
/obj/item/microfusion_cell_attachment/overcapacity
name = "overcapacity microfusion cell attachment"
desc = "An attachment which increases the capacity of the microfusion cell it's attached to. These are an additional, smaller capacitor, using a system to automatically switch from the cell to the capacitor as it's depleted, maximizing the weapon's charge."
icon_state = "attachment_overcapacity"
attachment_overlay_icon_state = "microfusion_overcapacity"
/// How much the attachment increases the cell's capacity by, as a percentage
var/capacity_increase = 20
/// The initial capacity of the cell before this upgrade is added!
var/initial_charge_capacity = 0
/obj/item/microfusion_cell_attachment/overcapacity/add_attachment(obj/item/stock_parts/cell/microfusion/microfusion_cell)
. = ..()
initial_charge_capacity = microfusion_cell.maxcharge
var/capacity_to_add = microfusion_cell.maxcharge / 100 * capacity_increase
microfusion_cell.maxcharge += capacity_to_add
/obj/item/microfusion_cell_attachment/overcapacity/remove_attachment(obj/item/stock_parts/cell/microfusion/microfusion_cell)
. = ..()
microfusion_cell.charge = min(microfusion_cell.charge, initial_charge_capacity)
microfusion_cell.maxcharge = initial_charge_capacity
initial_charge_capacity = 0
/*
STABILISER ATTACHMENT
The cell is stable and will not emit sparks when firing.
*/
/obj/item/microfusion_cell_attachment/stabiliser
name = "stabilising microfusion cell attachment"
desc = "A stabilizer system attachment combining a grounding system with additional containment coils for self-charging purposes, this gives additional safety to the cell it's attached to; preventing both sparks and leakage."
icon_state = "attachment_stabiliser"
attachment_overlay_icon_state = "microfusion_stabiliser"
/obj/item/microfusion_cell_attachment/stabiliser/add_attachment(obj/item/stock_parts/cell/microfusion/microfusion_cell)
. = ..()
microfusion_cell.stabilised = TRUE
/obj/item/microfusion_cell_attachment/stabiliser/remove_attachment(obj/item/stock_parts/cell/microfusion/microfusion_cell)
. = ..()
microfusion_cell.stabilised = FALSE
/*
SELFCHARGE ATTACHMENT
The cell will charge itself.
If the cell isn't stabilised by a stabiliser, it may emit a radiation pulse.
*/
/obj/item/microfusion_cell_attachment/selfcharging
name = "self-charging microfusion cell attachment"
desc = "While microfusion cells are normally shipped without their fuel source, this attachment comes with fifteen grams of hydrogen fuel; allowing the cell to sustain a small, yet active reaction to self-charge. These can keep going for weeks to months in ideal conditions, making them more than enough for most campaigns."
icon_state = "attachment_selfcharge"
attachment_overlay_icon_state = "microfusion_selfcharge"
/// The amount of charge this cell will passively gain!
var/self_charge_amount = 20
/obj/item/microfusion_cell_attachment/selfcharging/examine(mob/user)
. = ..()
. += span_warning("WARNING: May cause radiation burns and weapon instability if not stabilized with recommended attachment!")
/obj/item/microfusion_cell_attachment/selfcharging/add_attachment(obj/item/stock_parts/cell/microfusion/microfusion_cell)
. = ..()
microfusion_cell.self_charging = TRUE
/obj/item/microfusion_cell_attachment/selfcharging/remove_attachment(obj/item/stock_parts/cell/microfusion/microfusion_cell)
. = ..()
microfusion_cell.self_charging = FALSE
/obj/item/microfusion_cell_attachment/selfcharging/process_attachment(obj/item/stock_parts/cell/microfusion/microfusion_cell, delta_time)
if(microfusion_cell.charge < microfusion_cell.maxcharge)
microfusion_cell.charge = clamp(microfusion_cell.charge + (self_charge_amount * delta_time), 0, microfusion_cell.maxcharge)
if(microfusion_cell.parent_gun)
microfusion_cell.parent_gun.update_appearance()
if(!microfusion_cell.stabilised && DT_PROB(1, delta_time))
radiation_pulse(src, 1, RAD_MEDIUM_INSULATION)
@@ -0,0 +1,218 @@
// CELLS AND EMITTERS
/datum/design/basic_microfusion_cell
name = "Basic Microfusion Cell"
desc = "A basic microfusion cell with a capacity of 1200 MF and and 1 attachment points."
id = "basic_microfusion_cell"
build_type = PROTOLATHE | AWAY_LATHE | AUTOLATHE
materials = list(/datum/material/iron = 1000, /datum/material/glass = 200)
construction_time = 10 SECONDS
build_path = /obj/item/stock_parts/cell/microfusion
category = list("Misc", "Power Designs", "Machinery", "initial")
/datum/design/microfusion_phase_emitter_undercharger
name = "Microfusion Phase Emitter Undercharger"
desc = "Inverts the output beam of the phase emitter, popular amongst law enforcement as a non-lethal upgrade."
id = "microfusion_phase_emitter_undercharger"
build_type = PROTOLATHE | AWAY_LATHE | AUTOLATHE
materials = list(/datum/material/iron = 1000, /datum/material/glass = 200)
construction_time = 10 SECONDS
build_path = /obj/item/microfusion_gun_attachment/undercharger
category = list("Misc", "Power Designs", "Machinery", "initial")
/datum/design/enhanced_microfusion_cell
name = "Enhanced Microfusion Cell"
desc = "An enhanced microfusion cell with a capacity of 1500 MF and 2 attachment points."
id = "enhanced_microfusion_cell"
build_type = PROTOLATHE | AWAY_LATHE | MECHFAB
materials = list(/datum/material/iron = 1000, /datum/material/glass = 200, /datum/material/uranium = 200)
construction_time = 10 SECONDS
build_path = /obj/item/stock_parts/cell/microfusion/enhanced
category = list("Misc", "Power Designs")
departmental_flags = DEPARTMENTAL_FLAG_SECURITY | DEPARTMENTAL_FLAG_SCIENCE
/datum/design/enhanced_microfusion_phase_emitter
name = "Enhanced Microfusion Phase Emitter"
desc = "The core of a microfusion projection weapon, produces the laser."
id = "enhanced_microfusion_phase_emitter"
build_type = PROTOLATHE | AWAY_LATHE | MECHFAB
materials = list(/datum/material/iron = 1000, /datum/material/glass = 1000, /datum/material/silver = 500)
construction_time = 10 SECONDS
build_path = /obj/item/microfusion_phase_emitter/enhanced
category = list("Misc", "Power Designs")
departmental_flags = DEPARTMENTAL_FLAG_SECURITY | DEPARTMENTAL_FLAG_SCIENCE
/datum/design/advanced_microfusion_cell
name = "Advanced Microfusion Cell"
desc = "An advanced microfusion cell with a capacity of 1700 MF and 3 attachment points."
id = "advanced_microfusion_cell"
build_type = PROTOLATHE | AWAY_LATHE | MECHFAB
materials = list(/datum/material/iron = 1000, /datum/material/gold = 300, /datum/material/silver = 300, /datum/material/glass = 300, /datum/material/uranium = 300)
construction_time = 10 SECONDS
build_path = /obj/item/stock_parts/cell/microfusion/advanced
category = list("Misc", "Power Designs")
departmental_flags = DEPARTMENTAL_FLAG_SECURITY | DEPARTMENTAL_FLAG_SCIENCE
/datum/design/advanced_microfusion_phase_emitter
name = "Advanced Microfusion Phase Emitter"
desc = "The core of a microfusion projection weapon, produces the laser."
id = "advanced_microfusion_phase_emitter"
build_type = PROTOLATHE | AWAY_LATHE | MECHFAB
materials = list(/datum/material/iron = 1000, /datum/material/glass = 1000, /datum/material/silver = 500, /datum/material/gold = 500)
construction_time = 10 SECONDS
build_path = /obj/item/microfusion_phase_emitter/advanced
category = list("Misc", "Power Designs")
departmental_flags = DEPARTMENTAL_FLAG_SECURITY | DEPARTMENTAL_FLAG_SCIENCE
/datum/design/bluespace_microfusion_cell
name = "Bluespace Microfusion Cell"
desc = "A bluespace microfusion cell with a capacity of 2000 MF and 4 attachment points."
id = "bluespace_microfusion_cell"
build_type = PROTOLATHE | AWAY_LATHE | MECHFAB
materials = list(/datum/material/iron = 1000, /datum/material/gold = 300, /datum/material/glass = 300, /datum/material/diamond = 300, /datum/material/uranium = 300, /datum/material/titanium = 300, /datum/material/bluespace = 300)
construction_time = 10 SECONDS
build_path = /obj/item/stock_parts/cell/microfusion/bluespace
category = list("Misc", "Power Designs")
departmental_flags = DEPARTMENTAL_FLAG_SECURITY | DEPARTMENTAL_FLAG_SCIENCE
/datum/design/bluespace_microfusion_phase_emitter
name = "Bluespace Microfusion Phase Emitter"
desc = "The core of a microfusion projection weapon, produces the laser."
id = "bluespace_microfusion_phase_emitter"
build_type = PROTOLATHE | AWAY_LATHE | MECHFAB
materials = list(/datum/material/iron = 1000, /datum/material/glass = 1000, /datum/material/silver = 500, /datum/material/gold = 500, /datum/material/diamond = 500)
construction_time = 10 SECONDS
build_path = /obj/item/microfusion_phase_emitter/bluespace
category = list("Misc", "Power Designs")
departmental_flags = DEPARTMENTAL_FLAG_SECURITY | DEPARTMENTAL_FLAG_SCIENCE
// CELL UPGRADES
/datum/design/microfusion_cell_attachment_rechargeable
name = "Rechargeable Microfusion Cell Attachment"
desc = "An attachment for microfusion cells that allows conversion of KJ to MF in standard chargers."
id = "microfusion_cell_attachment_rechargeable"
build_type = PROTOLATHE | AWAY_LATHE | MECHFAB
materials = list(/datum/material/iron = 1000, /datum/material/glass = 1000, /datum/material/gold = 1000)
build_path = /obj/item/microfusion_cell_attachment/rechargeable
category = list("Misc", "Power Designs")
departmental_flags = DEPARTMENTAL_FLAG_SECURITY | DEPARTMENTAL_FLAG_SCIENCE
/datum/design/microfusion_cell_attachment_stabiliser
name = "Stabilising Microfusion Cell Attachment"
desc = "Stabilises the internal fusion reaction of microfusion cells."
id = "microfusion_cell_attachment_stabiliser"
build_type = PROTOLATHE | AWAY_LATHE | MECHFAB
materials = list(/datum/material/iron = 1000, /datum/material/glass = 1000, /datum/material/plasma = 1000)
build_path = /obj/item/microfusion_cell_attachment/stabiliser
category = list("Misc", "Power Designs")
departmental_flags = DEPARTMENTAL_FLAG_SECURITY | DEPARTMENTAL_FLAG_SCIENCE
/datum/design/microfusion_cell_attachment_overcapacity
name = "Overcapacity Microfusion Cell Attachment"
desc = "An attachment for microfusion cells that increases MF capacity."
id = "microfusion_cell_attachment_overcapacity"
build_type = PROTOLATHE | AWAY_LATHE | MECHFAB
materials = list(/datum/material/iron = 1000, /datum/material/glass = 1000, /datum/material/plasma = 500, /datum/material/gold = 500)
build_path = /obj/item/microfusion_cell_attachment/overcapacity
category = list("Misc", "Power Designs")
departmental_flags = DEPARTMENTAL_FLAG_SECURITY | DEPARTMENTAL_FLAG_SCIENCE
/datum/design/microfusion_cell_attachment_selfcharging
name = "Self-Charging Microfusion Cell Attachment"
desc = "Contains a small amount of infinitely decaying nuclear material, causing the fusion reaction to be self sustaining. WARNING: May cause radiation burns if not stabilised."
id = "microfusion_cell_attachment_selfcharging"
build_type = PROTOLATHE | AWAY_LATHE | MECHFAB
materials = list(/datum/material/iron = 1000, /datum/material/glass = 1000, /datum/material/diamond = 500, /datum/material/uranium = 1000)
build_path = /obj/item/microfusion_cell_attachment/selfcharging
category = list("Misc", "Power Designs")
departmental_flags = DEPARTMENTAL_FLAG_SECURITY | DEPARTMENTAL_FLAG_SCIENCE
// GUN UPGRADES
/datum/design/microfusion_gun_attachment_grip
name = "Microfusion Weapon Grip"
desc = "A grip... for microfusion weapon platforms."
id = "microfusion_gun_attachment_grip"
build_type = PROTOLATHE | AWAY_LATHE | MECHFAB
materials = list(/datum/material/iron = 1000, /datum/material/glass = 1000, /datum/material/silver = 500)
build_path = /obj/item/microfusion_gun_attachment/grip
category = list("Weapons")
departmental_flags = DEPARTMENTAL_FLAG_SECURITY | DEPARTMENTAL_FLAG_SCIENCE
/datum/design/microfusion_gun_attachment_scope
name = "Microfusion Weapon Scope"
desc = "A scope... for microfusion weapon platforms."
id = "microfusion_gun_attachment_scope"
build_type = PROTOLATHE | AWAY_LATHE | MECHFAB
materials = list(/datum/material/iron = 1000, /datum/material/glass = 1000, /datum/material/silver = 500)
build_path = /obj/item/microfusion_gun_attachment/scope
category = list("Weapons")
departmental_flags = DEPARTMENTAL_FLAG_SECURITY | DEPARTMENTAL_FLAG_SCIENCE
/datum/design/microfusion_gun_attachment_black_camo
name = "Black Camo Microfusion Frame"
desc = "A frame modification for the MCR-10, changing the color of the gun to black."
id = "microfusion_gun_attachment_black_camo"
build_type = PROTOLATHE | AWAY_LATHE | MECHFAB
materials = list(/datum/material/iron = 1000, /datum/material/glass = 1000, /datum/material/gold = 500)
build_path = /obj/item/microfusion_gun_attachment/black_camo
category = list("Weapons")
departmental_flags = DEPARTMENTAL_FLAG_SECURITY | DEPARTMENTAL_FLAG_SCIENCE
/datum/design/microfusion_gun_attachment_rail
name = "Microfusion Weapon Rail"
desc = "A rail system for any additional attachments, such as a torch."
id = "microfusion_gun_attachment_rail"
build_type = PROTOLATHE | AWAY_LATHE | MECHFAB
materials = list(/datum/material/iron = 1000, /datum/material/glass = 1000, /datum/material/silver = 500, /datum/material/gold = 500)
build_path = /obj/item/microfusion_gun_attachment/rail
category = list("Weapons")
departmental_flags = DEPARTMENTAL_FLAG_SECURITY | DEPARTMENTAL_FLAG_SCIENCE
/datum/design/microfusion_gun_attachment_heatsink
name = "Phase Emitter Heatsink"
desc = "A heatsink attachment for your microfusion weapon. Massively increases cooling potential."
id = "microfusion_gun_attachment_heatsink"
build_type = PROTOLATHE | AWAY_LATHE | MECHFAB
materials = list(/datum/material/iron = 1000, /datum/material/glass = 1000, /datum/material/silver = 500, /datum/material/bronze = 500)
build_path = /obj/item/microfusion_gun_attachment/heatsink
category = list("Weapons")
departmental_flags = DEPARTMENTAL_FLAG_SECURITY | DEPARTMENTAL_FLAG_SCIENCE
/datum/design/microfusion_gun_attachment_scatter
name = "Diffuser Microfusion Lens Attachment"
desc = "Splits the microfusion laser beam entering the lens!"
id = "microfusion_gun_attachment_scatter"
build_type = PROTOLATHE | AWAY_LATHE | MECHFAB
materials = list(/datum/material/iron = 1000, /datum/material/glass = 1000, /datum/material/diamond = 500, /datum/material/silver = 500)
build_path = /obj/item/microfusion_gun_attachment/scatter
category = list("Weapons")
departmental_flags = DEPARTMENTAL_FLAG_SECURITY | DEPARTMENTAL_FLAG_SCIENCE
/datum/design/microfusion_gun_attachment_superheat
name = "Superheating Phase Emitter Upgrade"
desc = "Superheats the beam, causing targets to ignite!"
id = "microfusion_gun_attachment_superheat"
build_type = PROTOLATHE | AWAY_LATHE | MECHFAB
materials = list(/datum/material/iron = 1000, /datum/material/glass = 1000, /datum/material/diamond = 500, /datum/material/plasma = 500)
build_path = /obj/item/microfusion_gun_attachment/superheat
category = list("Weapons")
departmental_flags = DEPARTMENTAL_FLAG_SECURITY | DEPARTMENTAL_FLAG_SCIENCE
/datum/design/microfusion_gun_attachment_repeater
name = "Repeating Phase Emitter Upgrade"
desc = "Upgrades the central phase emitter to repeat twice."
id = "microfusion_gun_attachment_repeater"
build_type = PROTOLATHE | AWAY_LATHE | MECHFAB
materials = list(/datum/material/iron = 1000, /datum/material/glass = 1000, /datum/material/diamond = 500, /datum/material/bluespace = 500)
build_path = /obj/item/microfusion_gun_attachment/repeater
category = list("Weapons")
departmental_flags = DEPARTMENTAL_FLAG_SECURITY | DEPARTMENTAL_FLAG_SCIENCE
/datum/design/microfusion_gun_attachment_xray
name = "Phase Inverter Emitter Array"
desc = "Experimental technology that inverts the central phase emitter causing the wave frequency to shift into X-ray. CAUTION: Phase emitter heats up very quickly."
id = "microfusion_gun_attachment_xray"
build_type = PROTOLATHE | AWAY_LATHE | MECHFAB
materials = list(/datum/material/iron = 1000, /datum/material/glass = 1000, /datum/material/diamond = 1000, /datum/material/uranium = 500, /datum/material/bluespace = 500)
build_path = /obj/item/microfusion_gun_attachment/xray
category = list("Weapons")
departmental_flags = DEPARTMENTAL_FLAG_SECURITY | DEPARTMENTAL_FLAG_SCIENCE
@@ -0,0 +1,806 @@
#define DUALWIELD_PENALTY_EXTRA_MULTIPLIER 1.4
// Master file for cell loadable energy guns. PROCS ONLY YOU MONKEYS!
// This file is a copy/paste of _energy.dm with extensive modification.
/obj/item/gun/microfusion
name = "prototype detatchable cell energy projection aparatus"
desc = "The coders have obviously failed to realise this is broken."
icon = 'modular_skyrat/modules/microfusion/icons/microfusion_gun40x32.dmi'
icon_state = "mcr01"
bayonet_icon = 'modular_skyrat/modules/microfusion/icons/microfusion_gun40x32.dmi'
gunlight_icon = 'modular_skyrat/modules/microfusion/icons/microfusion_gun40x32.dmi'
lefthand_file = 'modular_skyrat/modules/microfusion/icons/guns_lefthand.dmi'
righthand_file = 'modular_skyrat/modules/microfusion/icons/guns_lefthand.dmi'
has_gun_safety = TRUE
can_flashlight = FALSE
can_bayonet = FALSE
w_class = WEIGHT_CLASS_BULKY
/// What type of power cell this uses
var/obj/item/stock_parts/cell/microfusion/cell
/// The cell we will spawn with
var/cell_type = /obj/item/stock_parts/cell/microfusion
/// The cell type we check when inserting a cell
var/base_cell_type = /obj/item/stock_parts/cell/microfusion
/// If the weapon has custom icons for individual ammo types it can switch between. ie disabler beams, taser, laser/lethals, ect.
var/modifystate = FALSE
/// Can it be charged in a recharger?
var/can_charge = TRUE
/// How many charge sections do we have?
var/charge_sections = 4
ammo_x_offset = 2
/// if this gun uses a stateful charge bar for more detail
var/shaded_charge = FALSE
/// If this gun has a "this is loaded with X" overlay alongside chargebars and such
var/single_shot_type_overlay = TRUE
/// Should we give an overlay to empty guns?
var/display_empty = TRUE
/// whether the gun's cell drains the cyborg user's cell to recharge
var/dead_cell = FALSE
// MICROFUSION SPECIFIC VARS
/// The microfusion lens used for generating the beams.
var/obj/item/ammo_casing/energy/laser/microfusion/microfusion_lens
/// The time it takes for someone to (tactically) reload this gun. In deciseconds.
var/reload_time = 2 SECONDS
/// The sound played when you insert a cell.
var/sound_cell_insert = 'modular_skyrat/modules/microfusion/sound/mag_insert.ogg'
/// Should the insertion sound played vary?
var/sound_cell_insert_vary = TRUE
/// The volume at which we will play the insertion sound.
var/sound_cell_insert_volume = 50
/// The sound played when you remove a cell.
var/sound_cell_remove = 'modular_skyrat/modules/microfusion/sound/mag_insert.ogg'
/// Should the removal sound played vary?
var/sound_cell_remove_vary = TRUE
/// The volume at which we will play the removal sound.
var/sound_cell_remove_volume = 50
/// A list of attached upgrades
var/list/attachments = list()
/// The starting phase emitter in this weapon.
var/phase_emitter_type = /obj/item/microfusion_phase_emitter
/// The base emitter type that we check when putting a new emitter in.
var/base_phase_emitter_type = /obj/item/microfusion_phase_emitter
/// The phase emitter that this gun currently has.
var/obj/item/microfusion_phase_emitter/phase_emitter
/// The amount of heat produced per shot
var/heat_per_shot = 100
/// The heat dissipation bonus granted by the weapon.
var/heat_dissipation_bonus = 0
/// What slots does this gun have?
var/attachment_slots = list(GUN_SLOT_BARREL, GUN_SLOT_UNDERBARREL, GUN_SLOT_RAIL, GUN_SLOT_UNIQUE)
/// Our base firedelay.
var/base_fire_delay = 0
/// Do we use more power because of attachments?
var/extra_power_usage = 0
/obj/item/gun/microfusion/emp_act(severity)
. = ..()
if(!(. & EMP_PROTECT_CONTENTS))
cell.use(round(cell.charge / severity))
chambered = null //we empty the chamber
recharge_newshot() //and try to charge a new shot
update_appearance()
/obj/item/gun/microfusion/Initialize(mapload)
. = ..()
if(cell_type)
cell = new cell_type(src)
else
cell = new(src)
cell.parent_gun = src
if(!dead_cell)
cell.give(cell.maxcharge)
if(phase_emitter_type)
phase_emitter = new phase_emitter_type(src)
else
phase_emitter = new(src)
phase_emitter.parent_gun = src
update_microfusion_lens()
recharge_newshot(TRUE)
update_appearance()
AddComponent(/datum/component/ammo_hud)
RegisterSignal(src, COMSIG_ITEM_RECHARGED, .proc/instant_recharge)
base_fire_delay = fire_delay
/obj/item/gun/microfusion/ComponentInitialize()
. = ..()
AddElement(/datum/element/update_icon_updates_onmob)
/obj/item/gun/microfusion/add_weapon_description()
AddElement(/datum/element/weapon_description, attached_proc = .proc/add_notes_energy)
/obj/item/gun/microfusion/Destroy()
if(microfusion_lens)
QDEL_NULL(microfusion_lens)
if(cell)
cell.parent_gun = null
QDEL_NULL(cell)
if(attachments.len)
for(var/obj/item/iterating_item in attachments)
qdel(iterating_item)
attachments = null
if(phase_emitter)
QDEL_NULL(phase_emitter)
STOP_PROCESSING(SSobj, src)
return ..()
/obj/item/gun/microfusion/handle_atom_del(atom/to_handle)
if(to_handle == cell)
cell = null
update_appearance()
if(to_handle == phase_emitter)
phase_emitter = null
update_appearance()
return ..()
/obj/item/gun/microfusion/can_shoot()
return !QDELETED(cell) ? (cell.charge >= microfusion_lens.e_cost) : FALSE
/obj/item/gun/microfusion/recharge_newshot()
if (!microfusion_lens || !cell || !phase_emitter)
return
chambered = microfusion_lens
if(!chambered.loaded_projectile)
chambered.newshot()
/obj/item/gun/microfusion/handle_chamber()
if(chambered && !chambered.loaded_projectile && cell) //if loaded_projectile is null, i.e the shot has been fired...
var/obj/item/ammo_casing/energy/shot = chambered
cell.use(shot.e_cost + extra_power_usage)//... drain the cell
chambered = null //either way, released the prepared shot
recharge_newshot() //try to charge a new shot
/obj/item/gun/microfusion/process_fire(atom/target, mob/living/user, message = TRUE, params = null, zone_override = "", bonus_spread = 0)
if(!chambered && can_shoot())
process_chamber() // If the gun was drained and then recharged, load a new shot.
return ..()
/obj/item/gun/microfusion/update_icon_state()
var/skip_inhand = initial(inhand_icon_state) //only build if we aren't using a preset inhand icon
var/skip_worn_icon = initial(worn_icon_state) //only build if we aren't using a preset worn icon
if(skip_inhand && skip_worn_icon) //if we don't have either, don't do the math.
return ..()
var/ratio = get_charge_ratio()
var/temp_icon_to_use = initial(icon_state)
if(modifystate)
temp_icon_to_use += "[microfusion_lens.select_name]"
temp_icon_to_use += "[ratio]"
if(!skip_inhand)
inhand_icon_state = temp_icon_to_use
if(!skip_worn_icon)
worn_icon_state = temp_icon_to_use
return ..()
/obj/item/gun/microfusion/update_overlays()
. = ..()
SEND_SIGNAL(src, COMSIG_UPDATE_AMMO_HUD) //update the ammo hud since it's heavily dependent on the gun's state
if(!phase_emitter)
. += "[icon_state]_phase_emitter_missing"
else if(phase_emitter.damaged)
. += "[icon_state]_phase_emitter_damaged"
else if(cell)
var/ratio = get_charge_ratio()
if(ratio == 0 && display_empty)
. += "[icon_state]_empty"
else if(shaded_charge)
. += "[icon_state]_charge[ratio]_[phase_emitter.icon_state]"
else
. += "[icon_state]_phase_emitter_missing"
for(var/obj/item/microfusion_gun_attachment/microfusion_gun_attachment in attachments)
. += "[icon_state]_[microfusion_gun_attachment.attachment_overlay_icon_state]"
/obj/item/gun/microfusion/ignition_effect(atom/to_ignite, mob/living/user)
if(!can_shoot() || !microfusion_lens)
shoot_with_empty_chamber()
. = ""
else
var/obj/projectile/energy/loaded_projectile = microfusion_lens.loaded_projectile
if(!loaded_projectile)
. = ""
else if(loaded_projectile.nodamage || !loaded_projectile.damage || loaded_projectile.damage_type == STAMINA)
user.visible_message(span_danger("[user] tries to light [to_ignite.loc == user ? "[user.p_their()] [to_ignite.name]" : to_ignite] with [src], but it doesn't do anything. Dumbass."))
playsound(user, microfusion_lens.fire_sound, 50, TRUE)
playsound(user, loaded_projectile.hitsound, 50, TRUE)
cell.use(microfusion_lens.e_cost)
. = ""
else if(loaded_projectile.damage_type != BURN)
user.visible_message(span_danger("[user] tries to light [to_ignite.loc == user ? "[user.p_their()] [to_ignite.name]" : to_ignite] with [src], but only succeeds in utterly destroying it. Dumbass."))
playsound(user, microfusion_lens.fire_sound, 50, TRUE)
playsound(user, loaded_projectile.hitsound, 50, TRUE)
cell.use(microfusion_lens.e_cost)
qdel(to_ignite)
. = ""
else
playsound(user, microfusion_lens.fire_sound, 50, TRUE)
playsound(user, loaded_projectile.hitsound, 50, TRUE)
cell.use(microfusion_lens.e_cost)
. = span_danger("[user] casually lights [to_ignite.loc == user ? "[user.p_their()] [to_ignite.name]" : to_ignite] with [src]. Damn.")
/obj/item/gun/microfusion/attackby(obj/item/attacking_item, mob/user, params)
. = ..()
if (.)
return
if(istype(attacking_item, base_cell_type))
insert_cell(user, attacking_item)
if(istype(attacking_item, /obj/item/microfusion_gun_attachment))
add_attachment(attacking_item, user)
if(istype(attacking_item, base_phase_emitter_type))
insert_emitter(attacking_item, user)
/obj/item/gun/microfusion/process_chamber(empty_chamber, from_firing, chamber_next_round)
. = ..()
if(!cell?.stabilised && prob(40))
do_sparks(2, FALSE, src) //Microfusion guns create sparks!
/obj/item/gun/microfusion/attack_hand(mob/user, list/modifiers)
if(loc == user && user.is_holding(src) && cell)
eject_cell(user)
return
return ..()
/obj/item/gun/microfusion/crowbar_act(mob/living/user, obj/item/tool)
if(!phase_emitter)
to_chat(user, span_danger("There is no phase emitter for you to remove!"))
return
playsound(src, 'sound/items/crowbar.ogg', 70, TRUE)
remove_emitter()
/obj/item/gun/microfusion/AltClick(mob/user)
. = ..()
if(can_interact(user))
var/obj/item/microfusion_gun_attachment/to_remove = input(user, "Please select what part you'd like to remove.", "Remove attachment") as null|obj in sort_names(attachments)
if(!to_remove)
return
remove_attachment(to_remove, user)
/obj/item/gun/microfusion/proc/remove_all_attachments()
if(attachments.len)
for(var/obj/item/microfusion_gun_attachment/attachment in attachments)
attachment.remove_attachment(src)
attachment.forceMove(get_turf(src))
attachments -= attachment
update_appearance()
/obj/item/gun/microfusion/examine(mob/user)
. = ..()
if(attachments.len)
for(var/obj/item/microfusion_gun_attachment/microfusion_gun_attachment in attachments)
. += span_notice("It has a [microfusion_gun_attachment.name] installed.")
. += span_notice("<b>Alt+click</b> it to remove an upgrade.")
if(phase_emitter)
. += span_notice("It has a [phase_emitter.name] installed, at <b>[phase_emitter.get_heat_percent()]%</b> heat capacity.")
. += span_notice("The [phase_emitter.name] is at <b>[phase_emitter.integrity]%</b> integrity.")
. += span_notice("The [phase_emitter.name] will thermal throttle at <b>[phase_emitter.throttle_percentage]%</b> heat capacity.")
. += span_notice("Use a crowbar to remove the phase emitter.")
else
. += span_danger("It does not have a phase emitter installed!")
if(cell)
. += span_notice("It has a [cell.name] installed, with a capacity of <b>[cell.charge]/[cell.maxcharge] MF</b>.")
/obj/item/gun/microfusion/suicide_act(mob/living/user)
if (istype(user) && can_shoot() && can_trigger_gun(user) && user.get_bodypart(BODY_ZONE_HEAD))
user.visible_message(span_suicide("[user] is putting the barrel of [src] in [user.p_their()] mouth. It looks like [user.p_theyre()] trying to commit suicide!"))
sleep(25)
if(user.is_holding(src))
user.visible_message(span_suicide("[user] melts [user.p_their()] face off with [src]!"))
playsound(loc, fire_sound, 50, TRUE, -1)
cell.use(microfusion_lens.e_cost)
update_appearance()
return(FIRELOSS)
else
user.visible_message(span_suicide("[user] panics and starts choking to death!"))
return(OXYLOSS)
else
user.visible_message(span_suicide("[user] is pretending to melt [user.p_their()] face off with [src]! It looks like [user.p_theyre()] trying to commit suicide!</b>"))
playsound(src, dry_fire_sound, 30, TRUE)
return (OXYLOSS)
// To maintain modularity, I am moving this proc override here.
/obj/item/gun/microfusion/fire_gun(atom/target, mob/living/user, flag, params)
if(QDELETED(target))
return
if(firing_burst)
return
if(flag) //It's adjacent, is the user, or is on the user's person
if(target in user.contents) //can't shoot stuff inside us.
return
if(!ismob(target) || user.combat_mode) //melee attack
return
if(target == user && user.zone_selected != BODY_ZONE_PRECISE_MOUTH) //so we can't shoot ourselves (unless mouth selected)
return
if(iscarbon(target))
var/mob/living/carbon/carbon = target
for(var/i in carbon.all_wounds)
var/datum/wound/W = i
if(W.try_treating(src, user))
return // another coward cured!
if(istype(user))//Check if the user can use the gun, if the user isn't alive(turrets) assume it can.
var/mob/living/living = user
if(!can_trigger_gun(living))
return
if(flag)
if(user.zone_selected == BODY_ZONE_PRECISE_MOUTH)
handle_suicide(user, target, params)
return
if(!can_shoot()) //Just because you can pull the trigger doesn't mean it can shoot.
shoot_with_empty_chamber(user)
return
if(check_botched(user))
return
var/obj/item/bodypart/other_hand = user.has_hand_for_held_index(user.get_inactive_hand_index()) //returns non-disabled inactive hands
if(weapon_weight == WEAPON_HEAVY && (user.get_inactive_held_item() || !other_hand))
to_chat(user, span_warning("You need two hands to fire [src]!"))
return
var/attempted_shot = process_emitter()
if(attempted_shot != SHOT_SUCCESS)
if(attempted_shot)
to_chat(user, span_danger(attempted_shot))
return
//DUAL (or more!) WIELDING
var/bonus_spread = 0
var/loop_counter = 0
if(ishuman(user) && user.combat_mode)
var/mob/living/carbon/human/H = user
for(var/obj/item/gun/gun in H.held_items)
if(gun == src || gun.weapon_weight >= WEAPON_MEDIUM)
continue
else if(gun.can_trigger_gun(user))
bonus_spread += dual_wield_spread
loop_counter++
addtimer(CALLBACK(gun, /obj/item/gun.proc/process_fire, target, user, TRUE, params, null, bonus_spread), loop_counter)
return process_fire(target, user, TRUE, params, null, bonus_spread)
// To maintain modularity, I am moving this proc override here.
/obj/item/gun/microfusion/process_fire(atom/target, mob/living/user, message = TRUE, params = null, zone_override = "", bonus_spread = 0)
if(user)
SEND_SIGNAL(user, COMSIG_MOB_FIRED_GUN, user, target, params, zone_override)
SEND_SIGNAL(src, COMSIG_GUN_FIRED, user, target, params, zone_override)
add_fingerprint(user)
if(semicd)
return
//Vary by at least this much
var/base_bonus_spread = 0
var/calculated_spread = 0
var/randomized_gun_spread = 0
var/random_spread = rand()
if(user && HAS_TRAIT(user, TRAIT_POOR_AIM)) //Nice job hotshot
bonus_spread += 35
base_bonus_spread += 10
if(spread)
randomized_gun_spread = rand(0,spread)
var/randomized_bonus_spread = rand(base_bonus_spread, bonus_spread)
if(burst_size > 1)
firing_burst = TRUE
var/fire_delay_to_add = 0
if(phase_emitter)
fire_delay_to_add = phase_emitter.fire_delay
for(var/i = 1 to burst_size)
addtimer(CALLBACK(src, .proc/process_burst, user, target, message, params, zone_override, calculated_spread, randomized_gun_spread, randomized_bonus_spread, random_spread, i), (fire_delay + fire_delay_to_add) * (i - 1))
else
if(chambered)
if(HAS_TRAIT(user, TRAIT_PACIFISM)) // If the user has the pacifist trait, then they won't be able to fire [src] if the round chambered inside of [src] is lethal.
if(chambered.harmful) // Is the bullet chambered harmful?
to_chat(user, span_warning("[src] is lethally chambered! You don't want to risk harming anyone..."))
return
calculated_spread = round((rand(0, 1) - 0.5) * DUALWIELD_PENALTY_EXTRA_MULTIPLIER * (randomized_gun_spread + randomized_bonus_spread))
before_firing(target,user)
process_microfusion()
if(!chambered.fire_casing(target, user, params, , suppressed, zone_override, calculated_spread, src))
shoot_with_empty_chamber(user)
return
else
if(get_dist(user, target) <= 1) //Making sure whether the target is in vicinity for the pointblank shot
shoot_live_shot(user, 1, target, message)
else
shoot_live_shot(user, 0, target, message)
else
shoot_with_empty_chamber(user)
return
process_chamber()
update_appearance()
semicd = TRUE
var/fire_delay_to_add = 0
if(phase_emitter)
fire_delay_to_add = phase_emitter.fire_delay
addtimer(CALLBACK(src, .proc/reset_semicd), fire_delay + fire_delay_to_add)
if(user)
user.update_inv_hands()
SSblackbox.record_feedback("tally", "gun_fired", 1, type)
SEND_SIGNAL(src, COMSIG_UPDATE_AMMO_HUD)
return TRUE
// Same goes for this!
/obj/item/gun/microfusion/process_burst(mob/living/user, atom/target, message = TRUE, params=null, zone_override = "", calculated_spread = 0, randomized_gun_spread = 0, randomized_bonus_spread = 0, random_spread= 0, iteration = 0)
if(!user || !firing_burst)
firing_burst = FALSE
return FALSE
if(!can_shoot())
firing_burst = FALSE
return FALSE
if(!chambered)
process_chamber() // Ditto.
if(!issilicon(user))
if(iteration > 1 && !(user.is_holding(src))) //for burst firing
firing_burst = FALSE
return FALSE
if(chambered?.loaded_projectile)
if(HAS_TRAIT(user, TRAIT_PACIFISM)) // If the user has the pacifist trait, then they won't be able to fire [src] if the round chambered inside of [src] is lethal.
if(chambered.harmful) // Is the bullet chambered harmful?
to_chat(user, span_warning("[src] is lethally chambered! You don't want to risk harming anyone..."))
return
if(randomspread)
calculated_spread = round((rand(0, 1) - 0.5) * DUALWIELD_PENALTY_EXTRA_MULTIPLIER * (randomized_gun_spread + randomized_bonus_spread))
else //Smart spread
calculated_spread = round((((random_spread/burst_size) * iteration) - (0.5 + (random_spread * 0.25))) * (randomized_gun_spread + randomized_bonus_spread))
before_firing(target,user)
process_microfusion()
if(!chambered.fire_casing(target, user, params, ,suppressed, zone_override, calculated_spread, src))
shoot_with_empty_chamber(user)
firing_burst = FALSE
return FALSE
else
if(get_dist(user, target) <= 1) //Making sure whether the target is in vicinity for the pointblank shot
shoot_live_shot(user, 1, target, message)
else
shoot_live_shot(user, 0, target, message)
if (iteration >= burst_size)
firing_burst = FALSE
else
shoot_with_empty_chamber(user)
firing_burst = FALSE
return FALSE
process_chamber()
update_appearance()
SEND_SIGNAL(src, COMSIG_UPDATE_AMMO_HUD)
return TRUE
/obj/item/gun/microfusion/shoot_live_shot(mob/living/user, pointblank, atom/pbtarget, message)
if(recoil)
shake_camera(user, recoil + 1, recoil)
var/sound_freq_to_add = 0
if(phase_emitter && phase_emitter.sound_freq > 1)
sound_freq_to_add = phase_emitter.sound_freq
if(suppressed)
playsound(user, suppressed_sound, suppressed_volume, vary_fire_sound, ignore_walls = FALSE, extrarange = SILENCED_SOUND_EXTRARANGE, frequency = sound_freq_to_add, falloff_distance = 0)
else
playsound(user, fire_sound, fire_sound_volume, vary_fire_sound, frequency = sound_freq_to_add)
if(message)
if(pointblank)
user.visible_message(span_danger("[user] fires [src] point blank at [pbtarget]!"), \
span_danger("You fire [src] point blank at [pbtarget]!"), \
span_hear("You hear a gunshot!"), COMBAT_MESSAGE_RANGE, pbtarget)
to_chat(pbtarget, span_userdanger("[user] fires [src] point blank at you!"))
if(pb_knockback > 0 && ismob(pbtarget))
var/mob/PBT = pbtarget
var/atom/throw_target = get_edge_target_turf(PBT, user.dir)
PBT.throw_at(throw_target, pb_knockback, 2)
else
user.visible_message(span_danger("[user] fires [src]!"), \
span_danger("You fire [src]!"), \
span_hear("You hear a gunshot!"), COMBAT_MESSAGE_RANGE)
if(user.resting)
user.Immobilize(20, TRUE)
phase_emitter.add_heat(heat_per_shot)
if(phase_emitter.current_heat > phase_emitter.max_heat)
if(ishuman(user))
var/mob/living/carbon/human/human = user
var/obj/item/bodypart/affecting = human.get_bodypart("[(user.active_hand_index % 2 == 0) ? "r" : "l" ]_arm")
if(affecting?.receive_damage( 0, 5 )) // 1 burn damage
to_chat(user, span_warning("[src] burns your hand, it's too hot!"))
/obj/item/gun/microfusion/proc/process_microfusion()
if(attachments.len)
for(var/obj/item/microfusion_gun_attachment/attachment in attachments)
attachment.process_fire(src, chambered)
return TRUE
/obj/item/gun/microfusion/proc/process_emitter()
if(!phase_emitter)
return SHOT_FAILURE_NO_EMITTER
var/phase_emitter_process = phase_emitter.check_emitter()
if(phase_emitter_process != SHOT_SUCCESS)
return phase_emitter_process
return SHOT_SUCCESS
/obj/item/gun/microfusion/proc/instant_recharge()
SIGNAL_HANDLER
if(!cell)
return
cell.charge = cell.maxcharge
recharge_newshot()
update_appearance()
///Used by update_icon_state() and update_overlays()
/obj/item/gun/microfusion/proc/get_charge_ratio()
return can_shoot() ? CEILING(clamp(cell.charge / cell.maxcharge, 0, 1) * charge_sections, 1) : 0
// Sets the ratio to 0 if the gun doesn't have enough charge to fire, or if its power cell is removed.
/**
*
* Outputs type-specific weapon stats for energy-based firearms based on its firing modes
* and the stats of those firing modes. Esoteric firing modes like ion are currently not supported
* but can be added easily
*
*/
/obj/item/gun/microfusion/proc/add_notes_energy()
var/list/readout = list()
// Make sure there is something to actually retrieve
if(!microfusion_lens)
return
var/obj/projectile/exam_proj
readout += "Our heroic interns have shown that one can theoretically stay standing after..."
exam_proj = GLOB.proj_by_path_key[microfusion_lens?.projectile_type]
if(!istype(exam_proj))
return readout.Join("\n")
if(exam_proj.damage > 0) // Don't divide by 0!!!!!
readout += "[span_warning("[HITS_TO_CRIT(exam_proj.damage * microfusion_lens.pellets)] shot\s")] on [span_warning("[microfusion_lens.select_name]")] mode before collapsing from [exam_proj.damage_type == STAMINA ? "immense pain" : "their wounds"]."
if(exam_proj.stamina > 0) // In case a projectile does damage AND stamina damage (Energy Crossbow)
readout += "[span_warning("[HITS_TO_CRIT(exam_proj.stamina * microfusion_lens.pellets)] shot\s")] on [span_warning("[microfusion_lens.select_name]")] mode before collapsing from immense pain."
else
readout += "a theoretically infinite number of shots on [span_warning("[microfusion_lens.select_name]")] mode."
return readout.Join("\n") // Sending over the singular string, rather than the whole list
/obj/item/gun/microfusion/proc/update_microfusion_lens()
if(!microfusion_lens)
microfusion_lens = new(src)
fire_sound = microfusion_lens.fire_sound
fire_sound_volume = microfusion_lens.fire_sound_volume
fire_delay = microfusion_lens.delay
// Cell, emitter and upgrade interactions
/obj/item/gun/microfusion/proc/remove_emitter(mob/user)
playsound(src, sound_cell_insert, 50, TRUE)
phase_emitter.forceMove(get_turf(src))
if(user)
user.put_in_hands(phase_emitter)
to_chat(user, span_notice("You remove [phase_emitter] from [src]!"))
phase_emitter.parent_gun = null
phase_emitter = null
update_appearance()
/obj/item/gun/microfusion/proc/insert_emitter(obj/item/microfusion_phase_emitter/inserting_phase_emitter, mob/living/user)
if(phase_emitter)
to_chat(user, span_danger("There is already a phase emitter installed!"))
return FALSE
to_chat(user, span_notice("You carefully insert [inserting_phase_emitter] into the slot."))
playsound(src, sound_cell_remove, 50, TRUE)
inserting_phase_emitter.forceMove(src)
phase_emitter = inserting_phase_emitter
phase_emitter.parent_gun = src
update_appearance()
/// Try to insert the cell into the gun, if successful, return TRUE
/obj/item/gun/microfusion/proc/insert_cell(mob/user, obj/item/stock_parts/cell/microfusion/inserting_cell, display_message = TRUE)
var/tactical_reload = FALSE //We need to do this so that cells don't fall on the ground.
var/obj/item/stock_parts/cell/old_cell = cell
if(cell)
if(reload_time && !HAS_TRAIT(user, TRAIT_INSTANT_RELOAD)) //This only happens when you're attempting a tactical reload, e.g. there's a mag already inserted.
if(display_message)
to_chat(user, span_notice("You start to insert [inserting_cell] into [src]!"))
if(!do_after(user, reload_time, src))
if(display_message)
to_chat(user, span_warning("You fail to insert [inserting_cell] into [src]!"))
return FALSE
if(display_message)
to_chat(user, span_notice("You tactically reload [src], replacing [cell] inside!"))
tactical_reload = TRUE
eject_cell(user, FALSE, FALSE)
else if(display_message)
to_chat(user, span_notice("You insert [inserting_cell] into [src]!"))
if(sound_cell_insert)
playsound(src, sound_cell_insert, sound_cell_insert_volume, sound_cell_insert_vary)
cell = inserting_cell
inserting_cell.forceMove(src)
cell.parent_gun = src
if(tactical_reload)
user.put_in_hands(old_cell)
recharge_newshot()
update_appearance()
return TRUE
/// Ejecting a cell.
/obj/item/gun/microfusion/proc/eject_cell(mob/user, display_message = TRUE, put_in_hands = TRUE)
var/obj/item/stock_parts/cell/microfusion/old_cell = cell
old_cell.forceMove(get_turf(src))
if(user)
if(put_in_hands)
user.put_in_hands(old_cell)
if(display_message)
to_chat(user, span_notice("You remove [old_cell] from [src]!"))
if(sound_cell_remove)
playsound(src, sound_cell_remove, sound_cell_remove_volume, sound_cell_remove_vary)
old_cell.update_appearance()
cell.parent_gun = null
cell = null
update_appearance()
/// Attatching an upgrade.
/obj/item/gun/microfusion/proc/add_attachment(obj/item/microfusion_gun_attachment/microfusion_gun_attachment, mob/living/user)
if(is_type_in_list(microfusion_gun_attachment, attachments))
to_chat(user, span_warning("[src] already has [microfusion_gun_attachment] installed!"))
return FALSE
if(!(microfusion_gun_attachment.slot in attachment_slots))
to_chat(user, span_warning("[src] cannot install [microfusion_gun_attachment]!"))
return FALSE
for(var/obj/item/microfusion_gun_attachment/iterating_attachment in attachments)
if(is_type_in_list(microfusion_gun_attachment, iterating_attachment.incompatable_attachments))
to_chat(user, span_warning("[microfusion_gun_attachment] is not compatible with [iterating_attachment]!"))
return FALSE
if(iterating_attachment.slot != GUN_SLOT_UNIQUE && iterating_attachment.slot == microfusion_gun_attachment.slot)
to_chat(user, span_warning("[microfusion_gun_attachment] cannot be installed in the same slot as [iterating_attachment]!"))
return FALSE
attachments += microfusion_gun_attachment
microfusion_gun_attachment.forceMove(src)
microfusion_gun_attachment.run_attachment(src)
to_chat(user, span_notice("You successfully install [microfusion_gun_attachment] onto [src]!"))
playsound(src, 'sound/effects/structure_stress/pop2.ogg', 70, TRUE)
return TRUE
/obj/item/gun/microfusion/proc/remove_attachment(obj/item/microfusion_gun_attachment/microfusion_gun_attachment, mob/living/user)
to_chat(user, span_notice("You remove [microfusion_gun_attachment] from [src]!"))
playsound(src, 'sound/items/screwdriver.ogg', 70)
microfusion_gun_attachment.forceMove(get_turf(src))
attachments -= microfusion_gun_attachment
microfusion_gun_attachment.remove_attachment(src)
user?.put_in_hands(microfusion_gun_attachment)
update_appearance()
/obj/item/gun/microfusion/proc/change_name(mob/user)
var/new_name = input(user, "Enter new name:", "Change gun name") as null|text
if(!new_name)
return
var/name_length = length(new_name)
if(name_length > GUN_MAX_NAME_CHARS && name_length < GUN_MIN_NAME_CHARS)
to_chat(user, span_warning("New name cannot be longer than 20 or shorter than 5 characters!"))
return
name = sanitize(new_name)
update_appearance()
// UI CONTROL
/obj/item/gun/microfusion/ui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "MicrofusionGunControl")
ui.open()
/obj/item/gun/microfusion/ui_data(mob/user)
var/list/data = list()
data["gun_name"] = name
data["gun_desc"] = desc
data["gun_heat_dissipation"] = heat_dissipation_bonus
if(phase_emitter)
data["has_emitter"] = TRUE
data["phase_emitter_data"] = list(
"type" = capitalize(phase_emitter.name),
"integrity" = phase_emitter.integrity,
"current_heat" = phase_emitter.current_heat,
"throttle_percentage" = phase_emitter.throttle_percentage,
"heat_dissipation_per_tick" = phase_emitter.heat_dissipation_per_tick,
"max_heat" = phase_emitter.max_heat,
"damaged" = phase_emitter.damaged,
"hacked" = phase_emitter.hacked,
"heat_percent" = phase_emitter.get_heat_percent(),
"process_time" = phase_emitter.fire_delay,
"cooling_system" = phase_emitter.cooling_system,
"cooling_system_rate" = phase_emitter.cooling_system_rate,
)
else
data["has_emitter"] = FALSE
if(cell)
var/list/attachments = list()
for(var/obj/item/microfusion_cell_attachment/attachment in cell.attachments)
attachments += attachment.name
data["has_cell"] = TRUE
data["cell_data"] = list(
"type" = capitalize(cell.name),
"charge" = cell.charge,
"max_charge" = cell.maxcharge,
"status" = cell.meltdown,
"attachments" = attachments,
)
else
data["has_cell"] = FALSE
if(attachments.len)
data["has_attachments"] = TRUE
data["attachments"] = list()
for(var/obj/item/microfusion_gun_attachment/attachment in attachments)
var/list/attachment_functions = attachment.get_modify_data()
var/has_modifications = FALSE
if(attachment_functions?.len > 0)
has_modifications = TRUE
data["attachments"] += list(list(
"name" = uppertext(attachment.name),
"desc" = attachment.desc,
"slot" = capitalize(attachment.slot),
"information" = attachment.get_information_data(),
"has_modifications" = has_modifications,
"modify" = attachment_functions,
"ref" = REF(attachment),
))
else
data["has_attachments"] = FALSE
return data
/obj/item/gun/microfusion/ui_act(action, list/params)
. = ..()
if(.)
return
switch(action)
if("eject_cell")
if(!cell)
return
eject_cell(usr)
if("change_gun_name")
change_name(usr)
if("overclock_emitter")
if(!phase_emitter)
return
if(!phase_emitter.hacked)
return
phase_emitter.set_overclock(usr)
if("eject_emitter")
if(!phase_emitter)
return
remove_emitter(usr)
if("remove_attachment")
var/obj/item/microfusion_gun_attachment/to_remove = locate(params["attachment_ref"]) in src
if(!to_remove)
return
remove_attachment(to_remove, usr)
if("modify_attachment")
var/obj/item/microfusion_gun_attachment/to_modify = locate(params["attachment_ref"]) in src
if(!to_modify)
return
to_modify.run_modify_data(params["modify_ref"], usr, src)
if("toggle_cooling_system")
if(!phase_emitter)
return
phase_emitter.toggle_cooling_system(usr)
@@ -0,0 +1,447 @@
/**
*MICROFUSION GUN UPGRADE ATTACHMENTS
*For adding unique abilities to microfusion guns, these can directly interact with the gun!
*/
/obj/item/microfusion_gun_attachment
name = "microfusion gun attachment"
desc = "broken"
icon = 'modular_skyrat/modules/microfusion/icons/microfusion_gun_attachments.dmi'
w_class = WEIGHT_CLASS_NORMAL
/// The attachment overlay icon state.
var/attachment_overlay_icon_state
/// Any incompatable upgrade types.
var/list/incompatable_attachments = list()
/// The added heat produced by having this module installed.
var/heat_addition = 0
/// The slot this attachment is installed in.
var/slot = GUN_SLOT_UNIQUE
/// How much extra power do we use?
var/power_usage = 0
/obj/item/microfusion_gun_attachment/examine(mob/user)
. = ..()
. += "Compatible slot: <b>[slot]</b>."
/obj/item/microfusion_gun_attachment/proc/run_attachment(obj/item/gun/microfusion/microfusion_gun)
SHOULD_CALL_PARENT(TRUE)
microfusion_gun.heat_per_shot += heat_addition
microfusion_gun.update_appearance()
microfusion_gun.extra_power_usage += power_usage
return
/obj/item/microfusion_gun_attachment/proc/process_attachment(obj/item/gun/microfusion/microfusion_gun)
return
//Firing the gun right before we let go of it, tis is called.
/obj/item/microfusion_gun_attachment/proc/process_fire(obj/item/gun/microfusion/microfusion_gun, obj/item/ammo_casing/chambered)
return
/obj/item/microfusion_gun_attachment/proc/remove_attachment(obj/item/gun/microfusion/microfusion_gun)
SHOULD_CALL_PARENT(TRUE)
microfusion_gun.heat_per_shot -= heat_addition
microfusion_gun.update_appearance()
microfusion_gun.extra_power_usage -= power_usage
return
/*
Returns a list of modifications of this attachment, it must return a list within a list list(list()).
All of the following must be returned.
list(list("title" = "Toggle [toggle ? "OFF" : "ON"]", "icon" = "power-off", "color" = "blue" "reference" = "toggle_on_off"))
title - The title of the modification button
icon - The icon of the modification button
color - The color of the modification button
reference - The reference of the modification button, this is used to call the proc when the run modify data proc is called.
*/
/obj/item/microfusion_gun_attachment/proc/get_modify_data()
return
/obj/item/microfusion_gun_attachment/proc/run_modify_data(params, mob/living/user, obj/item/gun/microfusion/microfusion_gun)
return
/obj/item/microfusion_gun_attachment/proc/get_information_data()
return
/*
SCATTER ATTACHMENT
The cell is stable and will not emit sparks when firing.
*/
/obj/item/microfusion_gun_attachment/scatter
name = "diffuser microfusion lens upgrade"
desc = "A diffusing lens system capable of splitting one beam into three. However, the additional ionizing of the air will cause higher recoil."
icon_state = "attachment_scatter"
attachment_overlay_icon_state = "attachment_scatter"
slot = GUN_SLOT_BARREL
/// How many pellets are we going to add to the existing amount on the gun?
var/pellets_to_add = 2
/// The variation in pellet scatter.
var/variance_to_add = 20
/// How much recoil are we adding?
var/recoil_to_add = 1
/// The spread to add.
var/spread_to_add = 10
/obj/item/microfusion_gun_attachment/scatter/run_attachment(obj/item/gun/microfusion/microfusion_gun)
. = ..()
microfusion_gun.recoil += recoil_to_add
microfusion_gun.spread += spread_to_add
microfusion_gun.microfusion_lens.pellets += pellets_to_add
microfusion_gun.microfusion_lens.variance += variance_to_add
/obj/item/microfusion_gun_attachment/scatter/process_fire(obj/item/gun/microfusion/microfusion_gun, obj/item/ammo_casing/chambered)
. = ..()
chambered.loaded_projectile?.damage = chambered.loaded_projectile.damage / chambered.pellets
/obj/item/microfusion_gun_attachment/scatter/remove_attachment(obj/item/gun/microfusion/microfusion_gun)
. = ..()
microfusion_gun.recoil -= recoil_to_add
microfusion_gun.spread -= spread_to_add
microfusion_gun.microfusion_lens.pellets -= microfusion_gun.microfusion_lens.pellets
microfusion_gun.microfusion_lens.variance -= microfusion_gun.microfusion_lens.variance
/*
REPEATER ATTACHMENT
The gun can fire volleys of shots.
*/
/obj/item/microfusion_gun_attachment/superheat
name = "superheating phase emitter upgrade"
desc = "A barrel attachment hooked to the phase emitter, this adjusts the beam's wavelength to carry an intense wave of heat; causing targets to ignite."
icon_state = "attachment_superheat"
attachment_overlay_icon_state = "attachment_superheat"
incompatable_attachments = list(/obj/item/microfusion_gun_attachment/scatter)
heat_addition = 70
slot = GUN_SLOT_BARREL
var/projectile_override =/obj/projectile/beam/laser/microfusion/superheated
/obj/item/microfusion_gun_attachment/superheat/run_attachment(obj/item/gun/microfusion/microfusion_gun)
. = ..()
microfusion_gun.fire_sound = 'modular_skyrat/modules/microfusion/sound/vaporize.ogg'
/obj/item/microfusion_gun_attachment/superheat/remove_attachment(obj/item/gun/microfusion/microfusion_gun)
. = ..()
microfusion_gun.fire_sound = microfusion_gun.chambered?.fire_sound
/obj/item/microfusion_gun_attachment/superheat/process_fire(obj/item/gun/microfusion/microfusion_gun, obj/item/ammo_casing/chambered)
. = ..()
chambered.loaded_projectile = new projectile_override
/*
REPEATER ATTACHMENT
The gun can fire volleys of shots.
*/
/obj/item/microfusion_gun_attachment/repeater
name = "repeating phase emitter upgrade"
desc = "This barrel attachment upgrades the central phase emitter to fire off two beams in quick succession. While offering an increased rate of fire, the heat output and recoil rises too."
icon_state = "attachment_repeater"
attachment_overlay_icon_state = "attachment_repeater"
heat_addition = 40
slot = GUN_SLOT_BARREL
/// The spread to add to the gun.
var/spread_to_add = 15
/// The recoil to add to the gun.
var/recoil_to_add = 1
/// The burst to add to the gun.
var/burst_to_add = 1
/// The delay to add to the firing.
var/delay_to_add = 2
/obj/item/microfusion_gun_attachment/repeater/run_attachment(obj/item/gun/microfusion/microfusion_gun)
. = ..()
microfusion_gun.recoil += recoil_to_add
microfusion_gun.burst_size += burst_to_add
microfusion_gun.fire_delay += delay_to_add
microfusion_gun.spread += spread_to_add
/obj/item/microfusion_gun_attachment/repeater/remove_attachment(obj/item/gun/microfusion/microfusion_gun)
. = ..()
microfusion_gun.recoil -= recoil_to_add
microfusion_gun.burst_size -= burst_to_add
microfusion_gun.fire_delay -= delay_to_add
microfusion_gun.spread -= spread_to_add
/*
X-RAY ATTACHMENT
The gun can fire X-RAY shots.
*/
/obj/item/microfusion_gun_attachment/xray
name = "quantum phase inverter array" //Yes quantum makes things sound cooler.
desc = "An experimental barrel attachment that modifies the central phase emitter, causing the wave frequency to shift into X-ray. Capable of penetrating both glass and solid matter with ease, though the bolts don't carry a greater effect against armor, due to going through the target and doing more minimal internal damage. These attachments are power-hungry and overheat easily, though engineers have deemed the costs necessary drawbacks."
icon_state = "attachment_xray"
slot = GUN_SLOT_BARREL
attachment_overlay_icon_state = "attachment_xray"
heat_addition = 90
power_usage = 50
/obj/item/microfusion_gun_attachment/xray/examine(mob/user)
. = ..()
. += span_warning("CAUTION: Phase emitter heats up extremely quickly, sustained fire not recommended!")
/obj/item/microfusion_gun_attachment/xray/run_attachment(obj/item/gun/microfusion/microfusion_gun)
. = ..()
microfusion_gun.fire_sound = 'modular_skyrat/modules/microfusion/sound/incinerate.ogg'
/obj/item/microfusion_gun_attachment/xray/remove_attachment(obj/item/gun/microfusion/microfusion_gun)
. = ..()
microfusion_gun.fire_sound = microfusion_gun.chambered?.fire_sound
/obj/item/microfusion_gun_attachment/xray/process_fire(obj/item/gun/microfusion/microfusion_gun, obj/item/ammo_casing/chambered)
. = ..()
chambered.loaded_projectile.icon_state = "laser_greyscale"
chambered.loaded_projectile.color = COLOR_GREEN
chambered.loaded_projectile.light_color = COLOR_GREEN
chambered.loaded_projectile.projectile_piercing = PASSCLOSEDTURF|PASSGRILLE|PASSGLASS
/*
GRIP ATTACHMENT
Greatly reduces recoil and spread.
*/
/obj/item/microfusion_gun_attachment/grip
name = "grip attachment"
desc = "A simple grip that increases accuracy."
icon_state = "attachment_grip"
attachment_overlay_icon_state = "attachment_grip"
slot = GUN_SLOT_UNDERBARREL
/// How much recoil are we removing?
var/recoil_to_remove = 1
/// How much spread are we removing?
var/spread_to_remove = 10
/obj/item/microfusion_gun_attachment/grip/run_attachment(obj/item/gun/microfusion/microfusion_gun)
. = ..()
microfusion_gun.recoil -= recoil_to_remove
microfusion_gun.spread -= spread_to_remove
/obj/item/microfusion_gun_attachment/grip/remove_attachment(obj/item/gun/microfusion/microfusion_gun)
. = ..()
microfusion_gun.recoil += recoil_to_remove
microfusion_gun.spread += spread_to_remove
/*
HEATSINK ATTACHMENT
"Greatly increases the phase emitter cooling rate."
*/
/obj/item/microfusion_gun_attachment/heatsink
name = "phase emitter heatsink"
desc = "Greatly increases the phase emitter cooling rate."
icon_state = "attachment_heatsink"
attachment_overlay_icon_state = "attachment_heatsink"
slot = GUN_SLOT_UNDERBARREL
/// Coolant bonus
var/cooling_rate_increase = 50
/obj/item/microfusion_gun_attachment/heatsink/run_attachment(obj/item/gun/microfusion/microfusion_gun)
. = ..()
microfusion_gun.heat_dissipation_bonus += cooling_rate_increase
/obj/item/microfusion_gun_attachment/heatsink/remove_attachment(obj/item/gun/microfusion/microfusion_gun)
. = ..()
microfusion_gun.heat_dissipation_bonus -= cooling_rate_increase
/*
UNDERCHARGER ATTACHMENT
Massively decreases the output beam of the phase emitter.
Converts shots to STAMNINA damage.
*/
/obj/item/microfusion_gun_attachment/undercharger
name = "phase emitter undercharger"
desc = "An underbarrel system hooked to the phase emitter, this allows the weapon to also fire an electron bolt, producing a short-lived underpowered electric charge capable of stunning targets. These shots are less demanding on the weapon, leading to an increase in cooling rate."
icon_state = "attachment_undercharger"
attachment_overlay_icon_state = "attachment_undercharger"
slot = GUN_SLOT_UNDERBARREL
var/toggle = FALSE
var/cooling_rate_increase = 10
/// The projectile we override
var/projectile_override = /obj/projectile/beam/microfusion_disabler
/// How much recoil are we removing?
var/recoil_to_remove = 1
/// How much spread are we removing?
var/spread_to_remove = 10
/obj/item/microfusion_gun_attachment/undercharger/get_modify_data()
return list(list("title" = "Turn [toggle ? "OFF" : "ON"]", "icon" = "power-off", "color" = "[toggle ? "red" : "green"]", "reference" = "toggle_on_off"))
/obj/item/microfusion_gun_attachment/undercharger/run_modify_data(params, mob/living/user, obj/item/gun/microfusion/microfusion_gun)
if(params == "toggle_on_off")
toggle(microfusion_gun, user)
/obj/item/microfusion_gun_attachment/undercharger/proc/toggle(obj/item/gun/microfusion/microfusion_gun, mob/user)
if(toggle)
toggle = FALSE
microfusion_gun.heat_dissipation_bonus -= cooling_rate_increase
microfusion_gun.recoil -= recoil_to_remove
microfusion_gun.spread -= spread_to_remove
else
toggle = TRUE
microfusion_gun.heat_dissipation_bonus += cooling_rate_increase
microfusion_gun.recoil += recoil_to_remove
microfusion_gun.spread += spread_to_remove
if(user)
to_chat(user, span_notice("You toggle [src] [toggle ? "ON" : "OFF"]."))
/obj/item/microfusion_gun_attachment/undercharger/run_attachment(obj/item/gun/microfusion/microfusion_gun)
. = ..()
microfusion_gun.fire_sound = 'modular_skyrat/modules/microfusion/sound/burn.ogg'
/obj/item/microfusion_gun_attachment/undercharger/process_fire(obj/item/gun/microfusion/microfusion_gun, obj/item/ammo_casing/chambered)
. = ..()
if(toggle)
chambered.loaded_projectile = new projectile_override
/obj/item/microfusion_gun_attachment/undercharger/remove_attachment(obj/item/gun/microfusion/microfusion_gun)
. = ..()
if(toggle)
microfusion_gun.heat_dissipation_bonus -= cooling_rate_increase
microfusion_gun.recoil -= recoil_to_remove
microfusion_gun.spread -= spread_to_remove
microfusion_gun.fire_sound = microfusion_gun.chambered?.fire_sound
/*
RGB ATTACHMENT
Enables you to change the light color of the laser.
*/
/obj/item/microfusion_gun_attachment/rgb
name = "phase emitter spectrograph"
desc = "An attachment hooked up to the phase emitter, allowing the user to adjust the color of the beam outputted. This has seen widespread use by various factions capable of getting their hands on microfusion weapons, whether as a calling card or simply for entertainment."
icon_state = "attachment_rgb"
attachment_overlay_icon_state = "attachment_rgb"
/// What color are we changing the sprite to?
var/color_to_apply = COLOR_MOSTLY_PURE_RED
/obj/item/microfusion_gun_attachment/rgb/process_fire(obj/item/gun/microfusion/microfusion_gun, obj/item/ammo_casing/chambered)
. = ..()
chambered?.loaded_projectile.icon_state = "laser_greyscale"
chambered?.loaded_projectile.color = color_to_apply
chambered?.loaded_projectile.light_color = color_to_apply
/obj/item/microfusion_gun_attachment/rgb/proc/select_color(mob/living/user)
var/new_color = input(user, "Please select your new projectile color", "Laser color", color_to_apply) as null|color
if(!new_color)
return
color_to_apply = new_color
/obj/item/microfusion_gun_attachment/rgb/attack_self(mob/user, modifiers)
. = ..()
select_color(user)
/obj/item/microfusion_gun_attachment/rgb/get_modify_data()
return list(list("title" = "Change Color", "icon" = "wrench", "reference" = "color", "color" = "blue"))
/obj/item/microfusion_gun_attachment/rgb/run_modify_data(params, mob/living/user)
if(params == "color")
select_color(user)
/*
RAIL ATTACHMENT
Allows for flashlights bayonets and adds 1 slot to equipment.
*/
/obj/item/microfusion_gun_attachment/rail
name = "gun rail attachment"
desc = "A simple set of rails that attaches to weapon hardpoints. Allows for 3 more attachment slots and the instillation of a flashlight or bayonet."
icon_state = "attachment_rail"
attachment_overlay_icon_state = "attachment_rail"
slot = GUN_SLOT_RAIL
/obj/item/microfusion_gun_attachment/rail/run_attachment(obj/item/gun/microfusion/microfusion_gun)
. = ..()
microfusion_gun.can_flashlight = TRUE
microfusion_gun.can_bayonet = TRUE
/obj/item/microfusion_gun_attachment/rail/remove_attachment(obj/item/gun/microfusion/microfusion_gun)
. = ..()
microfusion_gun.gun_light = initial(microfusion_gun.can_flashlight)
if(microfusion_gun.gun_light)
microfusion_gun.gun_light.forceMove(get_turf(microfusion_gun))
microfusion_gun.clear_gunlight()
microfusion_gun.can_bayonet = initial(microfusion_gun.can_bayonet)
if(microfusion_gun.bayonet)
microfusion_gun.bayonet.forceMove(get_turf(microfusion_gun))
microfusion_gun.clear_bayonet()
microfusion_gun.remove_all_attachments()
/*
SCOPE ATTACHMENT
Allows for a scope to be attached to the gun.
DANGER: SNOWFLAKE ZONE
*/
/obj/item/microfusion_gun_attachment/scope
name = "scope attachment"
desc = "A simple telescopic scope, allowing for long-ranged use of the weapon. However, these do not provide any night vision."
icon_state = "attachment_scope"
attachment_overlay_icon_state = "attachment_scope"
slot = GUN_SLOT_RAIL
/obj/item/microfusion_gun_attachment/scope/run_attachment(obj/item/gun/microfusion/microfusion_gun)
. = ..()
if(microfusion_gun.azoom)
return
microfusion_gun.azoom = new()
microfusion_gun.azoom.gun = microfusion_gun
microfusion_gun.update_action_buttons()
/obj/item/microfusion_gun_attachment/scope/remove_attachment(obj/item/gun/microfusion/microfusion_gun)
. = ..()
if(microfusion_gun.azoom)
microfusion_gun.azoom.Remove(microfusion_gun.azoom.owner)
QDEL_NULL(microfusion_gun.azoom)
microfusion_gun.update_action_buttons()
/*
BLACK CAMO ATTACHMENT
Allows for a black camo to be applied to the gun.
All tactical, all the time.
*/
/obj/item/microfusion_gun_attachment/black_camo
name = "black camo microfusion frame"
desc = "A frame modification for the MCR-10, changing the color of the gun to black."
icon_state = "attachment_black"
attachment_overlay_icon_state = "attachment_black"
/*
PULSE ATTACHMENT
The gun can fire PULSE shots.
*/
/obj/item/microfusion_gun_attachment/pulse
name = "pulse induction carriage"
desc = "A cutting-edge bluespace capacitor array and distributing lens overhaul produced in laboratories by Nanotrasen scientists that allow microfusion rifles to fire military-grade pulse rounds. Comes equipped with cyclic cooling to ensure maximum combat efficiency, a munitions counter, and an extra-secure drop cage for the power source. May shorten trigger lifetime."
icon_state = "attachment_pulse"
slot = GUN_SLOT_BARREL
attachment_overlay_icon_state = "attachment_pulse"
heat_addition = 150
power_usage = 50
var/added_burst_size = 2
var/added_fire_delay = 2
/obj/item/microfusion_gun_attachment/pulse/examine(mob/user)
. = ..()
. += span_warning("CAUTION: Phase emitter heats up extremely quickly, sustained fire not recommended!")
/obj/item/microfusion_gun_attachment/pulse/run_attachment(obj/item/gun/microfusion/microfusion_gun)
. = ..()
microfusion_gun.burst_size += added_burst_size
microfusion_gun.fire_delay += added_fire_delay
/obj/item/microfusion_gun_attachment/pulse/remove_attachment(obj/item/gun/microfusion/microfusion_gun)
. = ..()
microfusion_gun.burst_size -= added_burst_size
microfusion_gun.fire_delay -= added_fire_delay
/obj/item/microfusion_gun_attachment/pulse/process_fire(obj/item/gun/microfusion/microfusion_gun, obj/item/ammo_casing/chambered)
. = ..()
chambered.loaded_projectile = new /obj/projectile/beam/pulse
@@ -0,0 +1,87 @@
/datum/techweb_node/basic_microfusion
id = "basic_microfusion"
starting_node = TRUE
display_name = "Basic Microfusion Technology"
description = "Basic microfusion technology allowing for basic microfusion designs."
design_ids = list(
"basic_microfusion_cell",
"microfusion_phase_emitter_undercharger",
)
//Enhanced microfusion
/datum/techweb_node/enhanced_microfusion
id = "enhanced_microfusion"
display_name = "Enhanced Microfusion Technology"
description = "Enhanced microfusion technology allowing for upgraded basic microfusion!"
prereq_ids = list(
"basic_microfusion",
"engineering",
"weaponry",
"high_efficiency",
)
design_ids = list(
"enhanced_microfusion_cell",
"microfusion_cell_attachment_rechargeable",
"enhanced_microfusion_phase_emitter",
"microfusion_gun_attachment_black_camo",
)
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 3500)
//Advanced microfusion
/datum/techweb_node/advanced_microfusion
id = "advanced_microfusion"
display_name = "Advanced Microfusion Technology"
description = "Advanced microfusion technology allowing for advanced microfusion!"
prereq_ids = list(
"enhanced_microfusion",
"adv_engi",
"adv_weaponry",
"adv_power",
"adv_plasma",
)
design_ids = list(
"advanced_microfusion_cell",
"microfusion_cell_attachment_overcapacity",
"microfusion_cell_attachment_stabiliser",
"microfusion_gun_attachment_scatter",
"microfusion_gun_attachment_superheat",
"advanced_microfusion_phase_emitter",
"microfusion_gun_attachment_grip",
"microfusion_gun_attachment_rail",
"microfusion_gun_attachment_scope",
)
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 5000)
// Bluespace microfusion
/datum/techweb_node/bluespace_microfusion
id = "bluespace_microfusion"
display_name = "Bluespace Microfusion Technology"
description = "Bluespace tinkering plus microfusion technology!"
prereq_ids = list(
"advanced_microfusion",
"bluespace_power",
"beam_weapons",
"explosive_weapons",
)
design_ids = list(
"bluespace_microfusion_cell",
"microfusion_gun_attachment_repeater",
"bluespace_microfusion_phase_emitter",
"microfusion_cell_attachment_selfcharging",
)
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 10000)
// Bluespace microfusion
/datum/techweb_node/quantum_microfusion
id = "quantum_microfusion"
display_name = "Quantum Microfusion Technology"
description = "Bleeding edge microfusion tech, making use of the latest in materials and components, bluespace or otherwise."
prereq_ids = list(
"bluespace_microfusion",
"alientech",
)
design_ids = list(
"microfusion_gun_attachment_xray",
)
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 15000)
@@ -0,0 +1,211 @@
////////////////////////////////////////////////////////////// PHASE EMITTERS
/*
Basically the heart of the gun, can be upgraded.
*/
/obj/item/microfusion_phase_emitter
name = "basic microfusion phase emitter"
desc = "A first-generation phase emitter, this is the core of the weapon and the source of the beam."
icon = 'modular_skyrat/modules/microfusion/icons/microfusion_gun_attachments.dmi'
icon_state = "phase_emitter"
base_icon_state = "phase_emitter"
w_class = WEIGHT_CLASS_NORMAL
/// Max heat before it breaks
var/max_heat = 2000
/// Current heat level
var/current_heat = 0
/// Thermal throttle percentage
var/throttle_percentage = 80
/// How much heat it dissipates passively
var/heat_dissipation_per_tick = 30
/// Active cooling system
var/cooling_system = FALSE
/// How quickly does the active cooling system cool - 1/1 ratio of cell charge to cooling point
var/cooling_system_rate = 30
/// What is our dynamic integrity?
var/integrity = 100
/// Are we fucked?
var/damaged = FALSE
/// Hard ref to the gun.
var/obj/item/gun/microfusion/parent_gun
/// Are we "hacked" thus allowing overclocking?
var/hacked = FALSE
/// The fire delay this emitter adds to the gun.
var/fire_delay = 0
/// The sound playback speed, used for overheating sound effects on fire.
var/sound_freq = 0
/obj/item/microfusion_phase_emitter/Initialize(mapload)
. = ..()
START_PROCESSING(SSobj, src)
/obj/item/microfusion_phase_emitter/Destroy()
parent_gun = null
return ..()
/obj/item/microfusion_phase_emitter/process(delta_time)
if(current_heat == 0)
return
var/calculated_heat_dissipation_per_tick = heat_dissipation_per_tick
if(isspaceturf(get_turf(src)))
calculated_heat_dissipation_per_tick += PHASE_HEAT_DISSIPATION_BONUS_SPACE // Passive cooling in space boost!
if(parent_gun)
calculated_heat_dissipation_per_tick += parent_gun.heat_dissipation_bonus
else
calculated_heat_dissipation_per_tick += PHASE_HEAT_DISSIPATION_BONUS_AIR //We get some passive cooling from being out of the gun.
if(cooling_system && parent_gun && parent_gun.cell && parent_gun.cell.use(cooling_system_rate))
calculated_heat_dissipation_per_tick += cooling_system_rate
current_heat = clamp(current_heat - (calculated_heat_dissipation_per_tick * delta_time) * 0.5, 0, INFINITY)
if(current_heat > max_heat)
integrity = integrity - current_heat / 1000 * delta_time * 0.5
process_fire_delay_and_sound()
if(integrity <= 0)
kill()
update_appearance()
parent_gun?.update_appearance()
/obj/item/microfusion_phase_emitter/proc/toggle_cooling_system(mob/user)
if(!parent_gun)
return
if(!cooling_system && !parent_gun.cell)
if(user)
to_chat(user, span_warning("You need a cell to turn on the cooling system."))
return
if(cooling_system)
cooling_system = FALSE
else
cooling_system = TRUE
if(user)
to_chat(user, span_notice("You toggle the cooling system [cooling_system ? "ON" : "OFF"]."))
/obj/item/microfusion_phase_emitter/multitool_act(mob/living/user, obj/item/tool)
if(hacked)
to_chat(user, span_warning("[src] is already unlocked!"))
return
to_chat(user, span_notice("You begin to override the thermal overclock safety..."))
if(do_after(user, 5 SECONDS, src))
hacked = TRUE
to_chat(user, span_notice("You override the thermal overclock safety."))
/obj/item/microfusion_phase_emitter/proc/set_overclock(mob/living/user)
if(!hacked)
return
var/new_throttle = clamp(input(user, "Please input a new thermal throttle percentage(0-300):", "Phase Emitter Overclock") as null|num, 1, 300)
to_chat(user, span_notice("Thermal throttle percent set to: [new_throttle]."))
if(new_throttle > 100)
to_chat(user, span_danger("WARNING: You have input a throttle percentage of more than 100, this may cause emitter damage."))
throttle_percentage = new_throttle
/obj/item/microfusion_phase_emitter/update_icon_state()
. = ..()
if(damaged)
icon_state = "[base_icon_state]_damaged"
else
switch(get_heat_percent())
if(40 to 69)
icon_state = "[base_icon_state]_hot"
if(70 to INFINITY)
icon_state = "[base_icon_state]_critical"
else
icon_state = base_icon_state
/obj/item/microfusion_phase_emitter/proc/process_fire_delay_and_sound()
var/fire_delay_to_add = 0
if(integrity < 100)
fire_delay_to_add = fire_delay_to_add + (100 - integrity) / 10
if(current_heat > max_heat)
fire_delay_to_add = fire_delay_to_add + (current_heat - max_heat) / 100 //Holy shit this emitter is tanking
fire_delay = round(fire_delay_to_add, 1.45)
/obj/item/microfusion_phase_emitter/proc/get_heat_icon_state()
switch(get_heat_percent())
if(40 to 69)
return "hot"
if(70 to INFINITY)
return "critical"
else
return "normal"
/obj/item/microfusion_phase_emitter/examine(mob/user)
. = ..()
if(damaged)
. += span_danger("It is damaged beyond repair.")
else
. += span_notice("It has a thermal rating of: [max_heat] C")
. += span_notice("It dissipates heat at: [heat_dissipation_per_tick] C")
. += span_notice("Heat capacity: [get_heat_percent()]%")
. += span_notice("Integrity: [integrity]%")
. += span_notice("Thermal throttle: [throttle_percentage]%")
. += span_notice("Cooling system: [cooling_system ? "enabled, cooling at [cooling_system_rate] C/s" : "disabled"].")
/obj/item/microfusion_phase_emitter/proc/get_heat_percent()
return round(current_heat / max_heat * 100)
/obj/item/microfusion_phase_emitter/proc/check_emitter()
if(damaged)
return PHASE_FAILURE_DAMAGED
if(get_heat_percent() >= throttle_percentage)
return PHASE_FAILURE_THROTTLE
return SHOT_SUCCESS
/obj/item/microfusion_phase_emitter/proc/add_heat(heat_to_add)
current_heat += heat_to_add
update_appearance()
/obj/item/microfusion_phase_emitter/proc/kill()
damaged = TRUE
name = "damaged [name]"
playsound(src, 'modular_skyrat/modules/microfusion/sound/overheat.ogg', 70)
say("ERROR: Integrity failure!")
STOP_PROCESSING(SSobj, src)
/obj/item/microfusion_phase_emitter/enhanced
name = "enhanced microfusion phase emitter"
desc = "A second-generation phase emitter, this one is made of more robust materials which allow for a higher capacity for heat, a faster dissipation and cooling of it, and more capacity for thermal throttling."
max_heat = 3000
throttle_percentage = 85
heat_dissipation_per_tick = 40
cooling_system_rate = 40
integrity = 120
color = "#ffffcc"
/obj/item/microfusion_phase_emitter/advanced
name = "advanced microfusion phase emitter"
desc = "A third-generation phase emitter, boasting a high capacity for heat, greater dissipation and cooling, and is built using higher-grade materials for more durability."
max_heat = 4000
throttle_percentage = 90
heat_dissipation_per_tick = 50
cooling_system_rate = 50
integrity = 150
color = "#99ffcc"
/obj/item/microfusion_phase_emitter/bluespace
name = "bluespace microfusion phase emitter"
desc = "A fourth-generation phase emitter, utilizing a bluespace medium to store and manage heat, allowing for much cooler temperatures than realspace would allow. This is made of nothing but the latest materials, leading to the highest durability of any phase emitter on the market."
max_heat = 5000
throttle_percentage = 95
heat_dissipation_per_tick = 60
cooling_system_rate = 60
integrity = 200
color = "#66ccff"
/obj/item/microfusion_phase_emitter/nanocarbon
name = "nanocarbon microfusion phase emitter"
desc = "An experimental phase emitter, made of nanocarbon, which is the most durable material on the market. It is capable of storing and managing heat, and is capable of cooling at a much higher rate than the other phase emitters."
max_heat = 15000
throttle_percentage = 95
heat_dissipation_per_tick = 130
cooling_system_rate = 60
integrity = 500
color = "#6966ff"
@@ -0,0 +1,44 @@
/obj/item/ammo_casing
///What volume should the sound play at?
var/fire_sound_volume = 50
/obj/item/ammo_casing/energy/laser/microfusion
name = "microfusion energy lens"
projectile_type = /obj/projectile/beam/laser/microfusion
e_cost = 100 // 10 shots with a normal cell.
select_name = "laser"
fire_sound = 'modular_skyrat/modules/microfusion/sound/laser_1.ogg'
fire_sound_volume = 100
/obj/projectile/beam/laser/microfusion
name = "microfusion laser"
icon = 'modular_skyrat/modules/microfusion/icons/projectiles.dmi'
/obj/projectile/beam/microfusion_disabler
name = "microfusion disabler laser"
icon = 'modular_skyrat/modules/microfusion/icons/projectiles.dmi'
icon_state = "disabler"
damage = 41
damage_type = STAMINA
flag = ENERGY
hitsound = 'sound/weapons/tap.ogg'
eyeblur = 0
impact_effect_type = /obj/effect/temp_visual/impact_effect/blue_laser
light_color = LIGHT_COLOR_BLUE
tracer_type = /obj/effect/projectile/tracer/disabler
muzzle_type = /obj/effect/projectile/muzzle/disabler
impact_type = /obj/effect/projectile/impact/disabler
/obj/projectile/beam/laser/microfusion/superheated
name = "superheated microfusion laser"
icon_state = "laser_greyscale"
color = LIGHT_COLOR_FIRE
light_color = LIGHT_COLOR_FIRE
/obj/projectile/beam/laser/microfusion/superheated/on_hit(atom/target, blocked)
. = ..()
if(isliving(target))
var/mob/living/living = target
living.fire_stacks += 2
living.IgniteMob()
Binary file not shown.

After

Width:  |  Height:  |  Size: 840 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 814 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 416 B

Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -15,7 +15,7 @@
STR.max_combined_w_class = 30
STR.max_items = 3
STR.display_numerical_stacking = FALSE
STR.can_hold = typecacheof(list(/obj/item/ammo_box/magazine, /obj/item/ammo_casing, /obj/item/ammo_box/revolver))
STR.can_hold = typecacheof(list(/obj/item/ammo_box/magazine, /obj/item/ammo_casing, /obj/item/ammo_box/revolver, /obj/item/stock_parts/cell/microfusion))
/obj/item/storage/bag/material
name = "material pouch"
@@ -59,6 +59,10 @@
if(!anchored)
to_chat(user, span_warning("[src] isn't attached to the ground!"))
return
var/obj/item/stock_parts/cell/inserting_cell = tool
if(inserting_cell.chargerate <= 0)
to_chat(user, span_warning("[inserting_cell] cannot be recharged!"))
return
if(charging_batteries.len >= 4)
to_chat(user, span_warning("[src] is full, and cannot hold anymore cells!"))
return
@@ -23,6 +23,7 @@
rack_sound = 'modular_skyrat/modules/robohand/sound/slide.ogg'
fire_sound_volume = 100
bolt_wording = "fuckin' slide"
reload_time = 0 //FAST AS FUCK BOIS!
//Gun actions
@@ -15,24 +15,33 @@
/// Do we want to angle it so that it is horizontal?
var/vertical_guns = TRUE
/obj/structure/rack/shelf
/obj/effect/spawner/armory_spawn/Initialize(mapload)
..()
for(var/gun in guns) // 11/20/21: Gun spawners now spawn 1 of each gun in it's list no matter what, so as to reduce the RNG of the armory stock.
var/obj/item/gun/spawned_gun = new gun(loc)
if(guns)
var/current_offset = -10
var/offset_percent = 20 / guns.len
for(var/gun in guns) // 11/20/21: Gun spawners now spawn 1 of each gun in it's list no matter what, so as to reduce the RNG of the armory stock.
var/obj/item/gun/spawned_gun = new gun(loc)
if(vertical_guns)
spawned_gun.place_on_rack()
spawned_gun.pixel_x = rand(-10, 10)
if(vertical_guns)
spawned_gun.place_on_rack()
spawned_gun.pixel_x = current_offset
current_offset += offset_percent
if(istype(spawned_gun, /obj/item/gun/ballistic))
var/obj/item/gun/ballistic/spawned_ballistic_gun = spawned_gun
if(spawned_ballistic_gun.magazine && !istype(spawned_ballistic_gun.magazine, /obj/item/ammo_box/magazine/internal))
var/obj/item/storage/box/ammo_box/spawned_box = new(loc)
spawned_box.name = "ammo box - [spawned_ballistic_gun.name]"
if(istype(spawned_gun, /obj/item/gun/ballistic))
var/obj/item/gun/ballistic/spawned_ballistic_gun = spawned_gun
if(spawned_ballistic_gun.magazine && !istype(spawned_ballistic_gun.magazine, /obj/item/ammo_box/magazine/internal))
var/obj/item/storage/box/ammo_box/spawned_box = new(loc)
spawned_box.name = "ammo box - [spawned_ballistic_gun.name]"
for(var/i in 1 to mags_to_spawn)
new spawned_ballistic_gun.mag_type (spawned_box)
if(istype(spawned_gun, /obj/item/gun/microfusion))
var/obj/item/gun/microfusion/spawned_microfusion_gun = spawned_gun
var/obj/item/storage/box/ammo_box/microfusion/spawned_box = new(loc)
for(var/i in 1 to mags_to_spawn)
new spawned_ballistic_gun.mag_type (spawned_box)
new spawned_microfusion_gun.cell_type (spawned_box)
return INITIALIZE_HINT_QDEL
@@ -60,9 +69,12 @@
illustration = null
layer = 2.9
/obj/item/storage/box/ammo_box/PopulateContents()
/obj/item/storage/box/ammo_box/microfusion
name = "microfusion cell container"
desc = "A box filled with microfusion cells."
/obj/item/storage/box/ammo_box/microfusion/PopulateContents()
new /obj/item/storage/bag/ammo(src)
new /obj/item/gun_maintenance_supplies(src)
/obj/effect/spawner/armory_spawn/centcom_rifles
+13 -1
View File
@@ -4633,8 +4633,9 @@
#include "modular_skyrat\modules\gunpoint\code\gunpoint_radial.dm"
#include "modular_skyrat\modules\gunsafety\code\gun_safety.dm"
#include "modular_skyrat\modules\gunsgalore\code\ammo\ammo.dm"
#include "modular_skyrat\modules\gunsgalore\code\guns\ballistic_master.dm"
#include "modular_skyrat\modules\gunsgalore\code\guns\energy.dm"
#include "modular_skyrat\modules\gunsgalore\code\guns\master.dm"
#include "modular_skyrat\modules\gunsgalore\code\guns\skillchip.dm"
#include "modular_skyrat\modules\gunsgalore\code\guns\akm\akm.dm"
#include "modular_skyrat\modules\gunsgalore\code\guns\fg42\fg42.dm"
#include "modular_skyrat\modules\gunsgalore\code\guns\m16\m16.dm"
@@ -4782,6 +4783,17 @@
#include "modular_skyrat\modules\mentor\code\mentorpm.dm"
#include "modular_skyrat\modules\mentor\code\mentorsay.dm"
#include "modular_skyrat\modules\mentor\code\mentorwho.dm"
#include "modular_skyrat\modules\microfusion\code\_microfusion_defines.dm"
#include "modular_skyrat\modules\microfusion\code\cargo_stuff.dm"
#include "modular_skyrat\modules\microfusion\code\gun_types.dm"
#include "modular_skyrat\modules\microfusion\code\microfusion_cell.dm"
#include "modular_skyrat\modules\microfusion\code\microfusion_cell_attachments.dm"
#include "modular_skyrat\modules\microfusion\code\microfusion_designs.dm"
#include "modular_skyrat\modules\microfusion\code\microfusion_energy_master.dm"
#include "modular_skyrat\modules\microfusion\code\microfusion_gun_attachments.dm"
#include "modular_skyrat\modules\microfusion\code\microfusion_techweb.dm"
#include "modular_skyrat\modules\microfusion\code\phase_emitter.dm"
#include "modular_skyrat\modules\microfusion\code\projectiles.dm"
#include "modular_skyrat\modules\Midroundtraitor\code\datum_traitor.dm"
#include "modular_skyrat\modules\Midroundtraitor\code\event.dm"
#include "modular_skyrat\modules\modular_ert\code\engineer\engineer.dm"
@@ -0,0 +1,269 @@
import { toFixed } from 'common/math';
import { useBackend } from '../backend';
import { NoticeBox, Section, Stack, Button, LabeledList, ProgressBar } from '../components';
import { Window } from '../layouts';
export const MicrofusionGunControl = (props, context) => {
const { act, data } = useBackend(context);
const { cell_data } = data;
const { phase_emitter_data } = data;
const {
gun_name,
gun_desc,
gun_heat_dissipation,
has_cell,
has_emitter,
has_attachments,
attachments = [],
} = data;
return (
<Window
title={'Micron Control Systems Incorporated: ' + gun_name}
width={500}
height={700}>
<Window.Content>
<Stack vertical grow>
<Stack.Item>
<Section
title={'Gun Info'}
buttons={(
<Button
icon="pen"
content="Change Name"
onClick={() => act('change_gun_name')} />
)}>
<LabeledList>
<LabeledList.Item label="Name">
{gun_name}
</LabeledList.Item>
<LabeledList.Item label="Description">
{gun_desc}
</LabeledList.Item>
<LabeledList.Item label="Active Heat Dissipation">
{gun_heat_dissipation + ' C/s'}
</LabeledList.Item>
</LabeledList>
</Section>
</Stack.Item>
<Stack.Item>
<Section
title="Power Cell"
buttons={(
<Button
icon="eject"
content="Eject Cell"
disabled={!has_cell}
onClick={() => act('eject_cell')} />
)}>
{has_cell ? (
<LabeledList>
<LabeledList.Item label="Cell Type">
{cell_data.type}
</LabeledList.Item>
<LabeledList.Item label="Cell Status">
{cell_data.status ? 'ERROR' : 'Nominal'}
</LabeledList.Item>
<LabeledList.Item label="Cell Charge">
<ProgressBar
value={cell_data.charge}
minValue={0}
maxValue={cell_data.max_charge}
ranges={{
"good": [cell_data.max_charge * 0.85, cell_data.max_charge],
"average": [cell_data.max_charge * 0.25, cell_data.max_charge * 0.85],
"bad": [0, cell_data.max_charge * 0.25],
}}>
{cell_data.charge + '/' + cell_data.max_charge + 'MF'}
</ProgressBar>
</LabeledList.Item>
{!!cell_data.charge <= 0 && (
<LabeledList.Item>
<Section>
<NoticeBox color="bad">
Charge depleted!
</NoticeBox>
</Section>
</LabeledList.Item>
)}
</LabeledList>
) : (
<NoticeBox color="bad">
No cell installed!
</NoticeBox>
)}
</Section>
</Stack.Item>
<Stack.Item>
<Section
title="Phase Emitter"
buttons={(
<Button
icon="eject"
content="Eject Emitter"
disabled={!has_emitter}
onClick={() => act('eject_emitter')} />
)}>
{has_emitter ? (
phase_emitter_data.damaged ? (
<NoticeBox color="bad">
Phase emitter is damaged!
</NoticeBox>
) : (
<LabeledList>
<LabeledList.Item label="Emitter Type">
{phase_emitter_data.type}
</LabeledList.Item>
<LabeledList.Item label="Temperature">
<ProgressBar
value={phase_emitter_data.current_heat}
minValue={0}
maxValue={phase_emitter_data.max_heat}
ranges={{
"bad": [phase_emitter_data.max_heat * 0.85, phase_emitter_data.max_heat * 2],
"average": [phase_emitter_data.max_heat * 0.25, phase_emitter_data.max_heat * 0.85],
"good": [0, phase_emitter_data.max_heat * 0.25],
}}>
{toFixed(phase_emitter_data.current_heat) + ' C' + ' (' + phase_emitter_data.heat_percent + '%)'}
</ProgressBar>
</LabeledList.Item>
<LabeledList.Item label="Maximum Temperature">
{phase_emitter_data.max_heat + ' C'}
</LabeledList.Item>
<LabeledList.Item label="Temperature Throttle Percent">
{phase_emitter_data.throttle_percentage + '% '}
<Button
icon="wrench"
content="Overclock"
color="bad"
disabled={!phase_emitter_data.hacked}
onClick={() => act('overclock_emitter')} />
</LabeledList.Item>
<LabeledList.Item label="Passive Heat Dissipation">
{phase_emitter_data.heat_dissipation_per_tick + ' C/s'}
</LabeledList.Item>
<LabeledList.Item label="Cooling System">
<Button
icon="snowflake"
content={phase_emitter_data.cooling_system ? "ONLINE" : "OFFLINE"}
color={phase_emitter_data.cooling_system ? "blue" : "bad"}
disabled={!has_cell}
onClick={() => act('toggle_cooling_system')} />
{' Cooling System Rate: ' + phase_emitter_data.cooling_system_rate + ' C/s'}
</LabeledList.Item>
<LabeledList.Item label="Total Heat Dissipation">
{phase_emitter_data.cooling_system ? (
phase_emitter_data.heat_dissipation_per_tick + gun_heat_dissipation + phase_emitter_data.cooling_system_rate + ' C/s'
) : (
phase_emitter_data.heat_dissipation_per_tick + gun_heat_dissipation + ' C/s'
)}
</LabeledList.Item>
<LabeledList.Item label="Integrity">
<ProgressBar
value={phase_emitter_data.integrity}
minValue={0}
maxValue={100}
ranges={{
"good": [85, 100],
"average": [25, 85],
"bad": [0, 25],
}}>
{phase_emitter_data.integrity + '%'}
</ProgressBar>
</LabeledList.Item>
<LabeledList.Item label="Process Time Per Shot">
<ProgressBar
value={phase_emitter_data.process_time}
minValue={0}
maxValue={5}
ranges={{
"good": [0, 1],
"average": [1, 3],
"bad": [3, 5],
}}>
{phase_emitter_data.process_time / 10 + 's'}
</ProgressBar>
</LabeledList.Item>
{phase_emitter_data.heat_percent
>= phase_emitter_data.throttle_percentage && (
<LabeledList.Item>
<NoticeBox color="orange">
Thermal throttle active!
</NoticeBox>
</LabeledList.Item>
)}
{phase_emitter_data.current_heat
>= phase_emitter_data.max_heat && (
<LabeledList.Item>
<NoticeBox color="bad">
Overheating!
</NoticeBox>
</LabeledList.Item>
)}
</LabeledList>
)
) : (
<NoticeBox color="bad">
No phase emitter installed!
</NoticeBox>
)}
</Section>
</Stack.Item>
<Stack.Item>
<Section title={"Attachments"}>
{has_attachments ? (
attachments.map((attachment, index) => (
<Section
key={index}
title={attachment.name}
buttons={(
<Button
icon="eject"
content="Eject Attachment"
onClick={() => act('remove_attachment', {
attachment_ref: attachment.ref,
})} />
)}>
<LabeledList>
<LabeledList.Item label="Description">
{attachment.desc}
</LabeledList.Item>
<LabeledList.Item label="Slot">
{attachment.slot}
</LabeledList.Item>
{attachment.information && (
<LabeledList.Item label="Information">
{attachment.information}
</LabeledList.Item>
)}
{!!attachment.has_modifications && (
attachment.modify.map((mod, index) => (
<LabeledList.Item
key={index}
buttons={(
<Button
key={index}
icon={mod.icon}
color={mod.color}
content={mod.title}
onClick={() => act('modify_attachment', {
attachment_ref: attachment.ref,
modify_ref: mod.reference,
})} />
)} />
))
)}
</LabeledList>
</Section>
))
) : (
<NoticeBox color="blue">
No attachments installed!
</NoticeBox>
)}
</Section>
</Stack.Item>
</Stack>
</Window.Content>
</Window>
);
};