diff --git a/aurorastation.dme b/aurorastation.dme
index c53c7e1032b..eb29f1cc2b7 100644
--- a/aurorastation.dme
+++ b/aurorastation.dme
@@ -37,6 +37,7 @@
#include "code\__defines\mining.dm"
#include "code\__defines\misc.dm"
#include "code\__defines\mobs.dm"
+#include "code\__defines\modular_guns.dm"
#include "code\__defines\qdel.dm"
#include "code\__defines\radio.dm"
#include "code\__defines\regex.dm"
@@ -1939,6 +1940,7 @@
#include "code\modules\projectiles\guns\energy\lawgiver.dm"
#include "code\modules\projectiles\guns\energy\magic.dm"
#include "code\modules\projectiles\guns\energy\mining.dm"
+#include "code\modules\projectiles\guns\energy\modular.dm"
#include "code\modules\projectiles\guns\energy\nuclear.dm"
#include "code\modules\projectiles\guns\energy\pulse.dm"
#include "code\modules\projectiles\guns\energy\rifle.dm"
@@ -1958,6 +1960,8 @@
#include "code\modules\projectiles\guns\projectile\rifle.dm"
#include "code\modules\projectiles\guns\projectile\shotgun.dm"
#include "code\modules\projectiles\guns\projectile\sniper.dm"
+#include "code\modules\projectiles\modular\laser_base.dm"
+#include "code\modules\projectiles\modular\laser_components.dm"
#include "code\modules\projectiles\projectile\animate.dm"
#include "code\modules\projectiles\projectile\beams.dm"
#include "code\modules\projectiles\projectile\bullets.dm"
diff --git a/code/__defines/modular_guns.dm b/code/__defines/modular_guns.dm
new file mode 100644
index 00000000000..bcd5b490dff
--- /dev/null
+++ b/code/__defines/modular_guns.dm
@@ -0,0 +1,11 @@
+#define CHASSIS_SMALL 2
+#define CHASSIS_MEDIUM 3
+#define CHASSIS_LARGE 4
+
+#define MOD_SILENCE 1
+#define MOD_NUCLEAR_CHARGE 2
+
+#define islasercapacitor(A) istype(A, /obj/item/laser_components/capacitor)
+#define ismodifier(A) istype(A, /obj/item/laser_components/modifier)
+#define ismodulator(A) istype(A, /obj/item/laser_components/modulator)
+#define isfocusinglens(A) istype(A, /obj/item/laser_components/focusing_lens)
\ No newline at end of file
diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm
index d33e36ee4da..ae99218a90a 100644
--- a/code/modules/projectiles/gun.dm
+++ b/code/modules/projectiles/gun.dm
@@ -63,6 +63,7 @@
var/scoped_accuracy = null
var/list/burst_accuracy = list(0) //allows for different accuracies for each shot in a burst. Applied on top of accuracy
var/list/dispersion = list(0)
+ var/reliability = 100
var/next_fire_time = 0
@@ -160,6 +161,11 @@
if(!special_check(user))
return
+ var/failure_chance = 100 - reliability
+ if(failure_chance && prob(failure_chance))
+ handle_reliability_fail(user)
+ return
+
if(world.time < next_fire_time)
if (world.time % 3) //to prevent spam
user << "[src] is not ready to fire again!"
@@ -597,3 +603,26 @@
mob_can_equip(M as mob, slot)
return 0
+
+/obj/item/weapon/gun/proc/handle_reliability_fail(var/mob/user)
+ var/severity = 1
+ if(prob(100-reliability))
+ severity = 2
+ if(prob(100-reliability))
+ severity = 3
+ switch(severity)
+ if(1)
+ small_fail(user)
+ if(2)
+ medium_fail(user)
+ else
+ critical_fail(user)
+
+/obj/item/weapon/gun/proc/small_fail(var/mob/user)
+ return
+
+/obj/item/weapon/gun/proc/medium_fail(var/mob/user)
+ return
+
+/obj/item/weapon/gun/proc/critical_fail(var/mob/user)
+ return
\ No newline at end of file
diff --git a/code/modules/projectiles/guns/energy.dm b/code/modules/projectiles/guns/energy.dm
index 0d5ab24f2eb..0a13bdb333f 100644
--- a/code/modules/projectiles/guns/energy.dm
+++ b/code/modules/projectiles/guns/energy.dm
@@ -55,7 +55,7 @@
. = 1
if (!power_supply || power_supply.charge >= power_supply.maxcharge || !self_recharge)
return 0 // check if we actually need to recharge
-
+
if (use_external_power)
var/obj/item/weapon/cell/external = get_external_power_supply()
if(!external || !external.use(charge_cost)) //Take power from the borg...
@@ -94,7 +94,7 @@
return
/obj/item/weapon/gun/energy/update_icon()
- if(charge_meter && power_supply)
+ if(charge_meter && power_supply && power_supply.maxcharge)
var/ratio = power_supply.charge / power_supply.maxcharge
//make sure that rounding down will not give us the empty state even if we have charge for a shot left.
diff --git a/code/modules/projectiles/guns/energy/modular.dm b/code/modules/projectiles/guns/energy/modular.dm
new file mode 100644
index 00000000000..473a99c40ed
--- /dev/null
+++ b/code/modules/projectiles/guns/energy/modular.dm
@@ -0,0 +1,301 @@
+/obj/item/weapon/gun/energy/laser/prototype
+ name = "laser prototype"
+ desc = "A custom prototype laser weapon."
+ icon_state = "energykill"
+ item_state = "energykill"
+ fire_sound = 'sound/weapons/Laser.ogg'
+ slot_flags = SLOT_BELT|SLOT_BACK
+ w_class = 3
+ force = 10
+ origin_tech = list(TECH_COMBAT = 3, TECH_MAGNET = 2)
+ matter = list(DEFAULT_WALL_MATERIAL = 2000)
+ can_turret = 0
+ zoomdevicename = null
+ max_shots = 0
+ burst_delay = 0
+ var/origin_chassis
+ var/gun_type
+ var/list/gun_mods = list()
+ var/obj/item/laser_components/capacitor/capacitor
+ var/obj/item/laser_components/focusing_lens/focusing_lens
+ var/obj/item/laser_components/modulator/modulator
+ var/chargetime
+ var/is_charging
+ var/criticality = 1 //multiplier for the negative effects of capacitor failures. Not just limited to critical failures.
+ var/named = 0
+ var/described = 0
+
+/obj/item/weapon/gun/energy/laser/prototype/examine(mob/user)
+ ..(user)
+ if(gun_mods.len)
+ for(var/obj/item/laser_components/modifier/modifier in gun_mods)
+ user << "You can see \the [modifier] attached."
+ if(capacitor)
+ user << "You can see \the [capacitor] attached."
+ if(focusing_lens)
+ user << "You can see \the [focusing_lens] attached."
+
+/obj/item/weapon/gun/energy/laser/prototype/attackby(var/obj/item/weapon/D, var/mob/user)
+ if(!isscrewdriver(D))
+ return ..()
+ user << "You disassemble \the [src]."
+ disassemble(user)
+
+/obj/item/weapon/gun/energy/laser/prototype/proc/reset_vars()
+ burst = initial(burst)
+ reliability = initial(reliability)
+ burst_delay = initial(burst_delay)
+ max_shots = initial(max_shots)
+ chargetime = initial(chargetime)
+ accuracy = initial(accuracy)
+ criticality = initial(criticality)
+
+/obj/item/weapon/gun/energy/laser/prototype/proc/updatetype(var/mob/user)
+ reset_vars()
+ if(!focusing_lens || !capacitor || !modulator)
+ disassemble(user)
+ return
+
+ switch(origin_chassis)
+ if(CHASSIS_SMALL)
+ gun_type = CHASSIS_SMALL
+ slot_flags = SLOT_BELT | SLOT_HOLSTER
+ item_state = "retro"
+ if(CHASSIS_MEDIUM)
+ gun_type = CHASSIS_MEDIUM
+ slot_flags = SLOT_BELT | SLOT_BACK
+ item_state = "energystun"
+ if(CHASSIS_LARGE)
+ gun_type = CHASSIS_LARGE
+ slot_flags = SLOT_BACK
+ item_state = "lasercannon"
+
+ if(capacitor.reliability - capacitor.condition <= 0)
+ if(prob(66))
+ capacitor.small_fail(user)
+ else
+ capacitor.medium_fail(user)
+ qdel(capacitor)
+ capacitor = null
+
+ if(focusing_lens.reliability - focusing_lens.condition <= 0)
+ qdel(focusing_lens)
+ focusing_lens = null
+
+ if(!focusing_lens || !capacitor || !modulator)
+ disassemble(user)
+ return
+
+ reliability = (capacitor.reliability - capacitor.condition) + (focusing_lens.reliability - focusing_lens.condition)
+
+ if(modulator.projectile)
+ projectile_type = modulator.projectile
+
+ fire_delay = capacitor.fire_delay
+ max_shots = capacitor.shots
+ power_supply.maxcharge = max_shots*charge_cost
+ dispersion = focusing_lens.dispersion
+ accuracy = focusing_lens.accuracy
+ burst += focusing_lens.burst
+
+ if(gun_mods.len)
+ handle_mod()
+
+ fire_delay_wielded = min(0,(fire_delay - fire_delay*3))
+ accuracy_wielded = accuracy + accuracy/4
+ scoped_accuracy = accuracy_wielded + accuracy/4
+ max_shots = max_shots * burst
+ w_class = gun_type
+ reliability = max(reliability, 1)
+
+/obj/item/weapon/gun/energy/laser/prototype/proc/handle_mod()
+ for(var/obj/item/laser_components/modifier/modifier in gun_mods)
+ switch(modifier.mod_type)
+ if(MOD_SILENCE)
+ silenced = 1
+ if(MOD_NUCLEAR_CHARGE)
+ self_recharge = 1
+ criticality *= 2
+ fire_delay *= modifier.fire_delay
+ reliability += modifier.reliability
+ burst += modifier.burst
+ burst_delay += modifier.burst_delay
+ max_shots *= modifier.shots
+ force += modifier.gun_force
+ chargetime += modifier.chargetime*10
+ accuracy += modifier.accuracy
+ criticality *= modifier.criticality
+ if(modifier.scope_name)
+ zoomdevicename = modifier.scope_name
+
+/obj/item/weapon/gun/energy/laser/prototype/consume_next_projectile()
+ if(!power_supply)
+ return null
+ if(!ispath(projectile_type))
+ return null
+ if(!power_supply.checked_use(charge_cost))
+ return null
+ if (self_recharge)
+ addtimer(CALLBACK(src, .proc/try_recharge), recharge_time * 2 SECONDS, TIMER_UNIQUE)
+ var/obj/item/projectile/beam/A = new projectile_type(src)
+ A.damage = capacitor.damage
+ var/damage_coeff = 1
+ for(var/obj/item/laser_components/modifier/modifier in gun_mods)
+ damage_coeff *= modifier.damage
+ if(burst > 1)
+ A.damage = A.damage/(burst - 1)
+ damage_coeff *= modulator.damage
+ A.damage *= damage_coeff
+ A.damage = min(A.damage, 60) //let's not get too ridiculous here
+ for(var/obj/item/laser_components/modifier/modifier in gun_mods)
+ if(prob((gun_mods.len * 10 * damage_coeff)/(max(1,(burst - 1)))))
+ capacitor.degrade(modifier.malus)
+ if(prob((gun_mods.len * 10 * damage_coeff)/(max(1,(burst - 1)))))
+ focusing_lens.degrade(modifier.malus)
+ if(prob((33 + capacitor.damage)/(max(1,(burst - 1)))))
+ modifier.degrade(1)
+ if((prob(A.damage)/burst))
+ if(prob(A.damage/2))
+ medium_fail(user)
+ else
+ small_fail(user)
+
+ updatetype(user)
+ return A
+
+/obj/item/weapon/gun/energy/laser/prototype/proc/disassemble(var/mob/user)
+ var/atom/A
+ if (user && user.loc)
+ A = user.loc
+ else
+ A = get_turf(src)
+ if(gun_mods.len)
+ for(var/obj/item/laser_components/modifier/modifier in gun_mods)
+ modifier.forceMove(A)
+ gun_mods.Remove(modifier)
+ if(capacitor)
+ capacitor.forceMove(A)
+ capacitor = null
+ if(focusing_lens)
+ focusing_lens.forceMove(A)
+ focusing_lens = null
+ if(modulator)
+ modulator.forceMove(A)
+ modulator = null
+ switch(origin_chassis)
+ if(CHASSIS_SMALL)
+ new /obj/item/device/laser_assembly(A)
+ if(CHASSIS_MEDIUM)
+ new /obj/item/device/laser_assembly/medium(A)
+ if(CHASSIS_LARGE)
+ new /obj/item/device/laser_assembly/large(A)
+ qdel(src)
+
+/obj/item/weapon/gun/energy/laser/prototype/small_fail(var/mob/user)
+ if(capacitor)
+ user << "\The [src]'s [capacitor] short-circuits!"
+ capacitor.small_fail(user, src)
+ return
+
+/obj/item/weapon/gun/energy/laser/prototype/medium_fail(var/mob/user)
+ if(capacitor)
+ user << "\The [src]'s [capacitor] overloads!"
+ capacitor.medium_fail(user, src)
+ return
+
+/obj/item/weapon/gun/energy/laser/prototype/critical_fail(var/mob/user)
+ if(capacitor)
+ user << "\The [src]'s [capacitor] goes critical!"
+ capacitor.critical_fail(user, src)
+ return
+
+/obj/item/weapon/gun/energy/laser/prototype/can_wield()
+ if(origin_chassis >= CHASSIS_MEDIUM)
+ return 1
+ else
+ return 0
+
+/obj/item/weapon/gun/energy/laser/prototype/ui_action_click()
+ if(src in usr)
+ toggle_wield(usr)
+
+/obj/item/weapon/gun/energy/laser/prototype/verb/wield_shotgun()
+ set name = "Wield prototype"
+ set category = "Object"
+ set src in usr
+
+ toggle_wield(usr)
+
+/obj/item/weapon/gun/energy/laser/prototype/verb/scope()
+ set category = "Object"
+ set name = "Use Scope"
+ set popup_menu = 1
+
+ if(zoomdevicename)
+ if(wielded)
+ toggle_scope(2.0, usr)
+ else
+ usr << "You can't look through the scope without stabilizing the rifle!"
+ else
+ usr << "This device does not have a scope installed!"
+
+/obj/item/weapon/gun/energy/laser/prototype/special_check(var/mob/user)
+ ..()
+ if(is_charging && chargetime)
+ user << "\The [src] is already charging!"
+ return 0
+ if(!wielded && (origin_chassis == CHASSIS_LARGE))
+ user << "You require both hands to fire this weapon!"
+ return 0
+ if(chargetime)
+ user.visible_message(
+ "\The [user] begins charging the [src]!",
+ "You begin charging the [src]!",
+ "You hear a low pulsing roar!"
+ )
+ is_charging = 1
+
+ if(!do_after(user, chargetime))
+ is_charging = 0
+ return 0
+
+ is_charging = 0
+
+ if(!istype(user.get_active_hand(), src))
+ return 0
+
+ return 1
+
+/obj/item/weapon/gun/energy/laser/prototype/verb/rename_gun()
+ set name = "Name Prototype"
+ set category = "Object"
+ set desc = "Name your invention so that its glory might be eternal"
+
+ var/mob/M = usr
+ if(!M.mind)
+ return 0
+
+ var/input = sanitizeSafe(input("What do you want to name the gun?", ,""), MAX_NAME_LEN)
+
+ if(src && input && !M.stat && in_range(M,src))
+ name = input
+ M << "You name the gun [input]. Say hello to your new friend."
+ named = 1
+ return 1
+
+/obj/item/weapon/gun/energy/laser/prototype/verb/describe_gun()
+ set name = "Describe Prototype"
+ set category = "Object"
+ set desc = "Describe your invention so that its glory might be eternal"
+
+ var/mob/M = usr
+ if(!M.mind)
+ return 0
+
+ var/input = sanitizeSafe(input("What do you want to name the gun?", ,""))
+
+ if(src && input && !M.stat && in_range(M,src))
+ desc = input
+ M << "You describe the gun as [input]. Say hello to your new friend."
+ described = 1
+ return 1
diff --git a/code/modules/projectiles/guns/energy/nuclear.dm b/code/modules/projectiles/guns/energy/nuclear.dm
index 9aa45b34bf9..bef654a4492 100644
--- a/code/modules/projectiles/guns/energy/nuclear.dm
+++ b/code/modules/projectiles/guns/energy/nuclear.dm
@@ -38,7 +38,7 @@
force = 8 //looks heavier than a pistol
self_recharge = 1
modifystate = null
- var/reliability = 95
+ reliability = 95
turret_sprite_set = "nuclear"
charge_failure_message = "'s charging socket was removed to make room for a minaturized reactor."
@@ -52,27 +52,31 @@
/obj/item/weapon/gun/energy/gun/nuclear/get_cell()
return DEVICE_NO_CELL
-/obj/item/weapon/gun/energy/gun/nuclear/proc/failcheck()
- lightfail = 0
- if (prob(src.reliability)) return 1 //No failure
- if (prob(src.reliability))
- for (var/mob/living/M in range(0,src)) //Only a minor failure, enjoy your radiation if you're in the same tile or carrying it
- if (src in M.contents)
- M << "Your gun feels pleasantly warm for a moment."
- else
- M << "You feel a warm sensation."
- M.apply_effect(rand(3,120), IRRADIATE)
- lightfail = 1
+/obj/item/weapon/gun/energy/gun/nuclear/small_fail(var/mob/user)
+ for (var/mob/living/M in range(0,src)) //Only a minor failure, enjoy your radiation if you're in the same tile or carrying it
+ if (M == user)
+ M << "Your gun feels pleasantly warm for a moment."
+ else
+ M << "You feel a warm sensation."
+ M.apply_effect(rand(3,120), IRRADIATE)
+ return
+
+/obj/item/weapon/gun/energy/gun/nuclear/medium_fail(var/mob/user)
+ if(prob(50))
+ critical_fail(user)
else
- for (var/mob/living/M in range(rand(1,4),src)) //Big failure, TIME FOR RADIATION BITCHES
- if (src in M.contents)
- M << "Your gun's reactor overloads!"
- M << "You feel a wave of heat wash over you."
- M.apply_effect(300, IRRADIATE)
- crit_fail = 1 //break the gun so it stops recharging
- self_recharge = FALSE
- update_icon()
- return 0
+ small_fail(user)
+ return
+
+/obj/item/weapon/gun/energy/gun/nuclear/critical_fail(var/mob/user)
+ user << "Your gun's reactor overloads!"
+ for (var/mob/living/M in range(rand(1,4),src))
+ M << "You feel a wave of heat wash over you."
+ M.apply_effect(300, IRRADIATE)
+ crit_fail = 1 //break the gun so it stops recharging
+ self_recharge = FALSE
+ update_icon()
+ return
/obj/item/weapon/gun/energy/gun/nuclear/proc/update_charge()
if (crit_fail)
@@ -96,9 +100,9 @@
/obj/item/weapon/gun/energy/gun/nuclear/proc/update_mode()
var/datum/firemode/current_mode = firemodes[sel_mode]
switch(current_mode.name)
- if("stun")
+ if("stun")
add_overlay("nucgun-stun")
- if("lethal")
+ if("lethal")
add_overlay("nucgun-kill")
/*
/obj/item/weapon/gun/energy/gun/nuclear/emp_act(severity)
diff --git a/code/modules/projectiles/guns/energy/special.dm b/code/modules/projectiles/guns/energy/special.dm
index eacbe440843..0ad65be8261 100644
--- a/code/modules/projectiles/guns/energy/special.dm
+++ b/code/modules/projectiles/guns/energy/special.dm
@@ -111,8 +111,8 @@
w_class = 3.0
origin_tech = list(TECH_COMBAT = 5, TECH_PHORON = 4)
projectile_type = /obj/item/projectile/energy/phoron
- can_turret = 1
- turret_is_lethal = 0
+ can_turret = 1
+ turret_is_lethal = 0
turret_sprite_set = "net"
/obj/item/weapon/gun/energy/beegun
@@ -158,22 +158,8 @@
/obj/item/weapon/gun/energy/mousegun/handle_post_fire(mob/user, atom/target, var/pointblank=0, var/reflex=0, var/playemote = 1)
var/T = get_turf(user)
spark(T, 3, alldirs)
- failcheck()
..()
-/obj/item/weapon/gun/energy/mousegun/proc/failcheck()
- lightfail = 0
- if (prob(5))
- for (var/mob/living/M in range(rand(1,4),src)) //Big failure, TIME FOR RADIATION BITCHES
- if (src in M.contents)
- M << "[src]'s reactor overloads!"
- M << "You feel a wave of heat wash over you."
- M.apply_effect(300, IRRADIATE)
- //crit_fail = 1 //break the gun so it stops recharging
- STOP_PROCESSING(SSprocessing, src)
- update_icon()
- return 0
-
/obj/item/weapon/gun/energy/net
name = "net gun"
desc = "A gun designed to deploy energy nets to capture animals or unruly crew members."
@@ -275,7 +261,8 @@
"You hear the spin of a rotary gun!"
)
is_charging = 1
- sleep(30)
+ if(!do_after(user, 30))
+ return 0
is_charging = 0
if(!istype(user.get_active_hand(), src))
return
@@ -370,7 +357,8 @@
"You hear a low pulsing roar!"
)
is_charging = 1
- sleep(20)
+ if(!do_after(user, 20))
+ return 0
is_charging = 0
if(!istype(user.get_active_hand(), src))
return
@@ -423,7 +411,8 @@
recharge_time = 1
charge_meter = 1
charge_cost = 50
- can_turret = 1
+ dispersion = list(0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9)
+ can_turret = 1
turret_sprite_set = "thermaldrill"
firemodes = list(
@@ -462,7 +451,8 @@
"You hear a low pulsing roar!"
)
is_charging = 1
- sleep(40)
+ if(!do_after(user, 40))
+ return 0
is_charging = 0
if(!istype(user.get_active_hand(), src))
return
@@ -505,7 +495,8 @@
"You hear a low pulsing roar!"
)
is_charging = 1
- sleep(20)
+ if(!do_after(user, 20))
+ return 0
is_charging = 0
msg_admin_attack("[key_name_admin(user)] shot with \a [src.type] [key_name_admin(src)]'s target (JMP)",ckey=key_name(user),ckey_target=key_name(src))
return 1
diff --git a/code/modules/projectiles/modular/laser_base.dm b/code/modules/projectiles/modular/laser_base.dm
new file mode 100644
index 00000000000..81d9043257d
--- /dev/null
+++ b/code/modules/projectiles/modular/laser_base.dm
@@ -0,0 +1,208 @@
+/obj/item/laser_components
+ icon = 'icons/obj/modular_laser.dmi'
+ icon_state = "bfg"
+ var/reliability = 0
+ var/damage = 1
+ var/fire_delay = 0
+ var/condition = 0 //inverse health of the component. subtracted from reliability.
+ var/shots = 0
+ var/burst = 0
+ var/accuracy = 0
+ var/obj/item/weapon/repair_item
+ var/gun_overlay
+
+/obj/item/laser_components/proc/degrade(var/increment = 1)
+ if(increment)
+ condition += increment
+ if(condition > reliability)
+ condition = reliability
+
+/obj/item/laser_components/attackby(var/obj/item/weapon/D as obj, var/mob/user as mob)
+ if(!istype(D,repair_item))
+ return ..()
+ user << "You begin repairing \the [src]."
+ if(do_after(user,20) && repair_module(D))
+ user << "You repair \the [src]."
+ else
+ user << "You fail to repair \the [src]."
+
+/obj/item/laser_components/proc/repair_module(var/obj/item/weapon/D)
+ return 1
+
+/obj/item/laser_components/modifier
+ name = "modifier"
+ desc = "A basic laser weapon modifier."
+ reliability = -5
+ var/mod_type
+ var/base_malus = 2 //when modifiers get damaged they do not break, but make other components break faster
+ var/malus = 2 //subtracted from weapon's overall reliability everytime it's fired
+ var/gun_force = 0 //melee damage of the gun
+ var/chargetime = 0
+ var/burst_delay = 0
+ var/scope_name
+ var/criticality
+ repair_item = /obj/item/weapon/weldingtool
+
+/obj/item/laser_components/modifier/examine(mob/user)
+ . = ..(user, 1)
+ if(.)
+ if(malus > base_malus)
+ user << "\The [src] appears damaged."
+
+/obj/item/laser_components/modifier/degrade(var/increment = 1)
+ if(increment)
+ malus += increment
+ if(malus > abs(base_malus*2))
+ malus = abs(base_malus*2)
+
+/obj/item/laser_components/modifier/repair_module(var/obj/item/weapon/weldingtool/W)
+ if(istype(W))
+ return
+ if(W.remove_fuel(5))
+ malus = max(malus - 5, base_malus)
+ return 1
+ return 0
+
+/obj/item/laser_components/capacitor
+ name = "capacitor"
+ desc = "A basic laser weapon capacitor."
+ icon_state = "capacitor"
+ shots = 5
+ damage = 10
+ reliability = 50
+ repair_item = /obj/item/stack/cable_coil
+
+/obj/item/laser_components/capacitor/repair_module(var/obj/item/stack/cable_coil/C)
+ if(istype(C))
+ return
+ if(C.use(5))
+ return 1
+ return 0
+
+/obj/item/laser_components/capacitor/examine(mob/user)
+ . = ..(user, 1)
+ if(.)
+ if(condition > 0)
+ user << "\The [src] appears damaged."
+
+/obj/item/laser_components/capacitor/proc/small_fail(var/mob/user, var/obj/item/weapon/gun/energy/laser/prototype/prototype)
+ return
+
+/obj/item/laser_components/capacitor/proc/medium_fail(var/mob/user, var/obj/item/weapon/gun/energy/laser/prototype/prototype)
+ return
+
+/obj/item/laser_components/capacitor/proc/critical_fail(var/mob/user, var/obj/item/weapon/gun/energy/laser/prototype/prototype)
+ qdel(src)
+ return
+
+/obj/item/laser_components/focusing_lens
+ name = "focusing lens"
+ desc = "A basic laser weapon focusing lens."
+ icon_state = "lens"
+ var/list/dispersion = list(0.6,1.0,1.0,1.0,1.2,0.6,1.0,1.0,1.0,1.2,0.6,1.0,1.0,1.0,1.2,0.6,1.0,1.0,1.0,1.2)
+ reliability = 25
+ repair_item = /obj/item/stack/nanopaste
+
+/obj/item/laser_components/focusing_lens/repair_module(var/obj/item/stack/nanopaste/N)
+ if(istype(N))
+ return
+ if(N.use(5))
+ return 1
+ return 0
+
+/obj/item/laser_components/focusing_lens/examine(mob/user)
+ . = ..(user, 1)
+ if(.)
+ if(condition > 0)
+ user << "\The [src] appears damaged."
+
+/obj/item/laser_components/modulator
+ name = "laser modulator"
+ desc = "A modification that modulates the beam into a standard laser beam."
+ icon_state = "laser"
+ var/obj/item/projectile/beam/projectile = /obj/item/projectile/beam
+
+/obj/item/laser_components/modulator/degrade()
+ return
+
+/obj/item/device/laser_assembly
+ name = "laser assembly (small)"
+ desc = "A case for shoving things into. Hopefully they work."
+ w_class = 2
+ icon = 'icons/obj/modular_laser.dmi'
+ icon_state = "small"
+ var/stage = 1
+ var/size = CHASSIS_SMALL
+ var/modifier_cap = 1
+
+ var/list/gun_mods = list()
+ var/obj/item/laser_components/capacitor/capacitor
+ var/obj/item/laser_components/focusing_lens/focusing_lens
+ var/obj/item/laser_components/modulator/modulator
+
+/obj/item/device/laser_assembly/Initialize()
+ . = ..()
+ update_icon()
+
+/obj/item/device/laser_assembly/attackby(var/obj/item/weapon/D as obj, var/mob/user as mob)
+ var/obj/item/laser_components/A = D
+ if(!istype(A))
+ return ..()
+ if(ismodifier(A) && gun_mods.len < modifier_cap)
+ gun_mods += A
+ user.drop_item()
+ A.forceMove(src)
+ else if(islasercapacitor(A) && stage == 1)
+ capacitor = A
+ user.drop_item()
+ A.forceMove(src)
+ stage = 2
+ else if(isfocusinglens(A) && stage == 2)
+ focusing_lens = A
+ user.drop_item()
+ A.forceMove(src)
+ stage = 3
+ else if(ismodulator(A) && stage == 3)
+ modulator = A
+ user.drop_item()
+ A.forceMove(src)
+ else
+ return ..()
+ user << "You insert \the [A] into the assembly."
+ update_icon()
+ check_completion()
+
+/obj/item/device/laser_assembly/update_icon()
+ ..()
+ underlays.Cut()
+ icon_state = "[initial(icon_state)]_[stage]"
+ if(gun_mods.len)
+ for(var/obj/item/laser_components/mod in gun_mods)
+ if(mod.gun_overlay)
+ underlays += mod.gun_overlay
+
+
+/obj/item/device/laser_assembly/proc/check_completion()
+ if(capacitor && focusing_lens && modulator)
+ finish()
+
+/obj/item/device/laser_assembly/proc/finish()
+ var/obj/item/weapon/gun/energy/laser/prototype/A = new /obj/item/weapon/gun/energy/laser/prototype
+ A.origin_chassis = size
+ A.capacitor = capacitor
+ capacitor.forceMove(A)
+ A.focusing_lens = focusing_lens
+ focusing_lens.forceMove(A)
+ A.modulator = modulator
+ modulator.forceMove(A)
+ if(gun_mods.len)
+ for(var/obj/item/laser_components/modifier/mod in gun_mods)
+ A.gun_mods += mod
+ mod.forceMove(A)
+ A.forceMove(get_turf(src))
+ A.icon = getFlatIcon(src)
+ A.updatetype()
+ gun_mods = null
+ focusing_lens = null
+ capacitor = null
+ qdel(src)
diff --git a/code/modules/projectiles/modular/laser_components.dm b/code/modules/projectiles/modular/laser_components.dm
new file mode 100644
index 00000000000..58c71cdf0b7
--- /dev/null
+++ b/code/modules/projectiles/modular/laser_components.dm
@@ -0,0 +1,397 @@
+//Assemblies
+
+/obj/item/device/laser_assembly/medium
+ name = "laser assembly (medium)"
+ icon_state = "medium"
+ w_class = 3
+ size = CHASSIS_MEDIUM
+ modifier_cap = 2
+
+/obj/item/device/laser_assembly/large
+ name = "laser assembly (large)"
+ icon_state = "large"
+ w_class = 4
+ size = CHASSIS_LARGE
+ modifier_cap = 3
+
+/obj/item/device/laser_assembly/admin
+ name = "laser assembly (obscene)"
+ icon_state = "large"
+ w_class = 4
+ size = CHASSIS_LARGE
+ modifier_cap = 25
+
+//Capacitors
+/obj/item/laser_components/capacitor/potato
+ name = "starch capacitor"
+ desc = "A powercell composed of a primarily starch-based conductor."
+ icon_state = "starch_capacitor"
+ reliability = 5
+ shots = 1
+ damage = 5
+
+/obj/item/laser_components/capacitor/reinforced
+ name = "reinforced capacitor"
+ desc = "A reinforced laser weapon capacitor."
+ icon_state = "reinforced_capacitor"
+ reliability = 75
+
+/obj/item/laser_components/capacitor/nuclear
+ name = "uranium-enriched capacitor"
+ desc = "A capacitor built from uranium enriched materials."
+ icon_state = "uranium_capacitor"
+ damage = 20
+ shots = 10
+ reliability = 40
+
+/obj/item/laser_components/capacitor/nuclear/small_fail(var/mob/user, var/obj/item/weapon/gun/energy/laser/prototype/prototype)
+ for (var/mob/living/M in range(0,src)) //Only a minor failure, enjoy your radiation if you're in the same tile or carrying it
+ if (M != user)
+ M << "You feel a warm sensation."
+ M.apply_effect(rand(1,10)*(prototype.criticality+1), IRRADIATE)
+ return
+
+/obj/item/laser_components/capacitor/nuclear/medium_fail(var/mob/user, var/obj/item/weapon/gun/energy/laser/prototype/prototype)
+ for (var/mob/living/M in range(round((prototype.criticality+1)),src)) //Only a minor failure, enjoy your radiation if you're in the same tile or carrying it
+ if (M != user)
+ M << "You feel a warm sensation."
+ M.apply_effect(rand(1,40)*(prototype.criticality+1), IRRADIATE)
+ return
+
+/obj/item/laser_components/capacitor/nuclear/critical_fail(var/mob/user, var/obj/item/weapon/gun/energy/laser/prototype/prototype)
+ for (var/mob/living/M in range(rand(2,6)*(prototype.criticality+1),src))
+ M << "You feel a wave of heat wash over you."
+ M.apply_effect(300*(prototype.criticality+1), IRRADIATE)
+ ..()
+
+/obj/item/laser_components/capacitor/teranium
+ name = "teranium-enriched capacitor"
+ desc = "A capacitor built from teranium enriched materials."
+ icon_state = "teranium_capacitor"
+ damage = 25
+ shots = 15
+ reliability = 40
+
+/obj/item/laser_components/capacitor/teranium/small_fail(var/mob/user, var/obj/item/weapon/gun/energy/laser/prototype/prototype)
+ tesla_zap(prototype, 3, 1000*(prototype.criticality+1))
+ return
+
+/obj/item/laser_components/capacitor/teranium/medium_fail(var/mob/user, var/obj/item/weapon/gun/energy/laser/prototype/prototype)
+ tesla_zap(prototype, round((prototype.criticality+1)*2), 2000*(prototype.criticality+1))
+ return
+
+/obj/item/laser_components/capacitor/teranium/critical_fail(var/mob/user, var/obj/item/weapon/gun/energy/laser/prototype/prototype)
+ for (var/i = 0 to round((prototype.criticality+1)))
+ tesla_zap(prototype, round((prototype.criticality+1)*2,1), 4000*(prototype.criticality+1))
+ ..()
+
+/obj/item/laser_components/capacitor/phoron
+ name = "phoron-enriched capacitor"
+ desc = "A capacitor built from phoron enriched materials."
+ icon_state = "phoron_capacitor"
+ damage = 30
+ shots = 25
+ reliability = 30
+
+/obj/item/laser_components/capacitor/phoron/small_fail(var/mob/user, var/obj/item/weapon/gun/energy/laser/prototype/prototype)
+ for (var/mob/living/M in range(0,src)) //Only a minor failure, enjoy your radiation if you're in the same tile or carrying it
+ if (M != user)
+ M << "You feel a warm sensation."
+ M.apply_effect(rand(1,10)*(prototype.criticality+1), IRRADIATE)
+ return
+
+/obj/item/laser_components/capacitor/phoron/medium_fail(var/mob/user, var/obj/item/weapon/gun/energy/laser/prototype/prototype)
+ empulse(get_turf(src), 0, round((prototype.criticality+1)*3,1))
+ explosion(get_turf(prototype), 0, 0, round((prototype.criticality+1)*2,1))
+ return
+
+/obj/item/laser_components/capacitor/phoron/critical_fail(var/mob/user, var/obj/item/weapon/gun/energy/laser/prototype/prototype)
+ empulse(get_turf(src), round((prototype.criticality+1),1), round((prototype.criticality+1)*4,1))
+ explosion(get_turf(prototype), 0, round((prototype.criticality+1),1), round((prototype.criticality+1)*3,1))
+ ..()
+
+/obj/item/laser_components/capacitor/bluespace
+ name = "bluespace-enriched capacitor"
+ desc = "A capacitor built from bluespace enriched materials."
+ icon_state = "bluespace_capacitor"
+ damage = 35
+ shots = 30
+ reliability = 30
+
+/obj/item/laser_components/capacitor/bluespace/small_fail(var/mob/user, var/obj/item/weapon/gun/energy/laser/prototype/prototype)
+ for (var/mob/living/M in range(round((prototype.criticality+1),1),src))
+ empulse(get_turf(M), 0, round((prototype.criticality+1)*2,1))
+ return
+
+/obj/item/laser_components/capacitor/bluespace/medium_fail(var/mob/user, var/obj/item/weapon/gun/energy/laser/prototype/prototype)
+ for (var/mob/living/M in range(round(3*(prototype.criticality+1),1),src))
+ empulse(get_turf(M), 0, round((prototype.criticality+1)*2,1))
+ do_teleport(M, get_turf(M), rand(1,3)*round((prototype.criticality+1),1), asoundin = 'sound/effects/phasein.ogg')
+ return
+
+/obj/item/laser_components/capacitor/bluespace/critical_fail(var/mob/user, var/obj/item/weapon/gun/energy/laser/prototype/prototype)
+ for (var/mob/living/M in range(round(6*(prototype.criticality+1),1),src))
+ empulse(get_turf(M), 0, round((prototype.criticality+1)*4,1))
+ do_teleport(M, get_turf(M), rand(6,18)*round((prototype.criticality+1),1), asoundin = 'sound/effects/phasein.ogg')
+ ..()
+
+//Lenses
+/obj/item/laser_components/focusing_lens/shotgun
+ name = "splitter lens"
+ desc = "A focusing lens that splits the beam into several sub-beams."
+ icon_state = "splitter_lens"
+ dispersion = list(1,-1,2,-2,3,-3,4,-4,5,-5,6,-6,7,-7,8,-8,9,-9,10,-10,11,-11,12,-12,13,-13,14,-14,15,-15)
+ burst = 4
+ accuracy = -1
+ reliability = 30
+
+/obj/item/laser_components/focusing_lens/sniper
+ name = "precise lens"
+ desc = "A focusing lens that is made of refined crystal, providing enhanced clarity and precision."
+ icon_state = "precise_lens"
+ accuracy = 2
+ reliability = 20
+ dispersion = list(0)
+
+/obj/item/laser_components/focusing_lens/strong
+ name = "reinforced lens"
+ desc = "A focusing lens that is reinforced with stronger material."
+ icon_state = "reinforced_lens"
+ reliability = 50
+
+//Modifiers
+
+/obj/item/laser_components/modifier/silencer
+ name = "energy suppressor"
+ desc = "A sophisticated audio dampener that negates much of the sound produced by an energy weapon."
+ mod_type = MOD_SILENCE
+ icon_state = "energy_silencer"
+
+/obj/item/laser_components/modifier/aeg
+ name = "miniaturized reactor"
+ desc = "An internal nuclear reactor which recharges the energy cell of the weapon. Feels tingly."
+ icon_state = "mini_reactor"
+ mod_type = MOD_NUCLEAR_CHARGE
+ reliability = -10
+ criticality = 1.5
+
+/obj/item/laser_components/modifier/surge
+ name = "surge protector"
+ desc = "A surge protector along the cell minimizes capacitor failure."
+ reliability = 0
+ base_malus = 0 //when modifiers get damaged they do not break, but make other components break faster
+ malus = 0 //subtracted from weapon's overall reliability everytime it's fired
+ criticality = 0.5
+ icon_state = "surge_protector"
+
+/obj/item/laser_components/modifier/repeater
+ name = "pulser"
+ desc = "A modification to the energy cell that permits rudimentary burst fire."
+ base_malus = 0.5 //when modifiers get damaged they do not break, but make other components break faster
+ malus = 0.5 //subtracted from weapon's overall reliability everytime it's fired
+ burst_delay = 1
+ burst = 3
+ fire_delay = 3
+ accuracy = -1
+ icon_state = "pulser"
+
+/obj/item/laser_components/modifier/auxiliarycap
+ name = "auxiliary capacitor"
+ desc = "A string of sub-capacitors along the central cell provide additional bang for your buck."
+ base_malus = 3
+ malus = 3
+ reliability = -10
+ shots = 2
+ damage = 1.5
+ criticality = 1.25
+ icon_state = "aux_capacitor"
+
+/obj/item/laser_components/modifier/overcharge
+ name = "capacitor overcharge"
+ desc = "A bypass to the internal cell's limiter, producing an explosive result."
+ base_malus = 5
+ malus = 5
+ reliability = -25
+ shots = 0.5
+ damage = 2.5
+ criticality = 2
+ icon_state = "capacitor_overcharge"
+
+/obj/item/laser_components/modifier/gatling
+ name = "gatling rotator"
+ desc = "A modification to the lens that permits rapid-fire for extended durations."
+ base_malus = 0.5
+ malus = 0.5
+ burst_delay = 1
+ burst = 10
+ fire_delay = 10
+ chargetime = 3
+ accuracy = -3
+ icon_state = "rotating_lens"
+
+/obj/item/laser_components/modifier/scope
+ name = "telescopic sight"
+ desc = "A modification that adds a zoom function to the prototype."
+ scope_name = "proto-scope"
+ gun_overlay = "scope"
+ icon_state = "telescopic_sight"
+
+/obj/item/laser_components/modifier/barrel
+ name = "reinforced barrel"
+ desc = "Reinforcement along the barrel extends the longevity of the prototype."
+ reliability = 25
+ base_malus = 0
+ malus = 0
+ icon_state = "reinforced_barrel"
+
+/obj/item/laser_components/modifier/vents
+ name = "exhaust venting"
+ desc = "More efficient exhaust venting reduces the impact of firing the prototype."
+ reliability = 0
+ base_malus = -5
+ malus = -5
+ icon_state = "vents"
+
+/obj/item/laser_components/modifier/grip
+ name = "enhanced grip"
+ desc = "A modification that improves the fire delay of the prototype."
+ fire_delay = 0.5
+ gun_overlay = "grip"
+ icon_state = "enhanced_grip"
+
+/obj/item/laser_components/modifier/stock
+ name = "improved stock"
+ desc = "A modification that improves the accuracy."
+ fire_delay = 0.5
+ accuracy = 1
+ gun_overlay = "stock"
+ icon_state = "improved_stock"
+
+/obj/item/laser_components/modifier/bayonet
+ name = "bayonet"
+ desc = "A modification that adds a big knife to your gun. Science."
+ gun_force = 10
+ gun_overlay = "bayonet"
+ icon_state = "bayonet_item"
+
+/obj/item/laser_components/modifier/ebayonet
+ name = "energy bayonet"
+ desc = "A modification that adds a hardlight knife to your gun. Science!"
+ gun_force = 25
+ gun_overlay = "ebayonet"
+ icon_state = "ebayonet_item"
+
+//Projectile modulators
+
+/obj/item/laser_components/modulator/taser
+ name = "TASER modulator"
+ desc = "A modification that modulates the beam into a nonlethal electrical arc."
+ damage = 0
+ projectile = /obj/item/projectile/beam/stun
+ icon_state = "taser"
+
+/obj/item/laser_components/modulator/tesla
+ name = "tesla modulator"
+ desc = "A modification that modulates the beam into a lethal electrical arc."
+ projectile = /obj/item/projectile/energy/tesla
+ icon_state = "tesla"
+
+/obj/item/laser_components/modulator/pulse
+ name = "pulse modulator"
+ desc = "Amplifies the laser beam into a highly lethal pulse beam."
+ projectile = /obj/item/projectile/beam/pulse
+ damage = 1.5
+ icon_state = "pulse"
+
+/obj/item/laser_components/modulator/xray
+ name = "xray modulator"
+ desc = "Modulates the beam into a concentrated x-ray blast."
+ projectile = /obj/item/projectile/beam/sniper
+ icon_state = "xray"
+
+/obj/item/laser_components/modulator/ion
+ name = "ion cannon"
+ desc = "Modulates the prototype to fire disparate ion projectiles."
+ projectile = /obj/item/projectile/ion
+ icon_state = "ion"
+
+/obj/item/laser_components/modulator/floramut
+ name = "floral somatomodulator"
+ desc = "Modulates the beam into firing controlled radiation which induces mutation in plant cells."
+ projectile = /obj/item/projectile/energy/floramut
+ icon_state = "somatoray"
+
+/obj/item/laser_components/modulator/floramut2
+ name = "betaray modulator"
+ desc = "Modulates the beam into firing controlled radiation which induces enhanced reproduction in plant cells."
+ projectile = /obj/item/projectile/energy/florayield
+ icon_state = "betaray"
+
+/obj/item/laser_components/modulator/arodentia
+ name = "arodentia modulator"
+ desc = "Modulates the beam into firing precise electrical arcs designed for pest control."
+ projectile = /obj/item/projectile/beam/mousegun
+ damage = 0
+ icon_state = "pesker"
+
+/obj/item/laser_components/modulator/red
+ name = "red team modulator"
+ desc = "Modulates the beam into firing red team tagger beams."
+ projectile = /obj/item/projectile/beam/lastertag/red
+ damage = 0
+ icon_state = "red"
+
+/obj/item/laser_components/modulator/blue
+ name = "blue team modulator"
+ desc = "Modulates the beam into firing blue team tagger beams."
+ projectile = /obj/item/projectile/beam/lastertag/blue
+ damage = 0
+ icon_state = "blue"
+
+/obj/item/laser_components/modulator/omni
+ name = "omni team modulator"
+ desc = "Modulates the beam into firing omni team tagger beams."
+ projectile = /obj/item/projectile/beam/lastertag/omni
+ damage = 0
+ icon_state = "omni"
+
+/obj/item/laser_components/modulator/practice
+ name = "practice beam modulator"
+ desc = "Modulates the beam into firing nonlethal practice beams."
+ projectile = /obj/item/projectile/beam/practice
+ damage = 0
+ icon_state = "practice"
+
+/obj/item/laser_components/modulator/mindflayer
+ name = "mind flayer modulator"
+ desc = "Modulates the beam into firing \"mind flayer\" beams."
+ projectile = /obj/item/projectile/beam/mindflayer
+ damage = 0.5
+ icon_state = "flayer"
+
+/obj/item/laser_components/modulator/decloner
+ name = "decloner modulator"
+ desc = "Modulates the beam into firing highly radioactive particulates."
+ projectile = /obj/item/projectile/energy/declone
+ damage = 0.5
+ icon_state = "decloner"
+
+/obj/item/laser_components/modulator/ebow
+ name = "dart modulator"
+ desc = "Modulates the beam into firing minute energy darts."
+ projectile = /obj/item/projectile/energy/dart
+ damage = 0.25
+ icon_state = "dart"
+
+/obj/item/laser_components/modulator/blaster
+ name = "blaster-bolt modulator"
+ desc = "Modulates the beam into firing disparate energy bolts."
+ projectile = /obj/item/projectile/energy/blaster
+ icon_state = "lensatic"
+
+/obj/item/laser_components/modulator/bfg
+ name = "bioforce modulator"
+ desc = "Modulates the beam into firing big green balls of death."
+ projectile = /obj/item/projectile/energy/bfg
+ damage = 2
+ icon_state = "bfg"
\ No newline at end of file
diff --git a/code/modules/projectiles/projectile/beams.dm b/code/modules/projectiles/projectile/beams.dm
index fb4cc7d18fa..fc8a9b762b4 100644
--- a/code/modules/projectiles/projectile/beams.dm
+++ b/code/modules/projectiles/projectile/beams.dm
@@ -333,4 +333,4 @@
/obj/item/projectile/beam/energy_net/proc/do_net(var/mob/M)
var/obj/item/weapon/energy_net/net = new (get_turf(M))
- net.throw_impact(M)
+ net.throw_impact(M)
\ No newline at end of file
diff --git a/code/modules/projectiles/projectile/special.dm b/code/modules/projectiles/projectile/special.dm
index 9b310546640..a6fb6e3d6fc 100644
--- a/code/modules/projectiles/projectile/special.dm
+++ b/code/modules/projectiles/projectile/special.dm
@@ -7,8 +7,8 @@
check_armour = "energy"
var/pulse_range = 1
-/obj/item/projectile/ion/on_hit(var/atom/target, var/blocked = 0)
- empulse(target, pulse_range, pulse_range)
+/obj/item/projectile/ion/on_impact(var/atom/A)
+ empulse(A, pulse_range, pulse_range)
return 1
/obj/item/projectile/ion/small
diff --git a/code/modules/research/designs/weapon_designs.dm b/code/modules/research/designs/weapon_designs.dm
index 5f5d3db203d..cd9016e9d43 100644
--- a/code/modules/research/designs/weapon_designs.dm
+++ b/code/modules/research/designs/weapon_designs.dm
@@ -13,19 +13,12 @@
desc = initial(I.desc)
..()
-/datum/design/item/weapon/stunrevolver
- id = "stunrevolver"
- req_tech = list(TECH_COMBAT = 3, TECH_MATERIAL = 3, TECH_POWER = 2)
- materials = list(DEFAULT_WALL_MATERIAL = 4000)
- build_path = /obj/item/weapon/gun/energy/stunrevolver
- sort_string = "TAAAA"
-
-/datum/design/item/weapon/nuclear_gun
- id = "nuclear_gun"
- req_tech = list(TECH_COMBAT = 3, TECH_MATERIAL = 5, TECH_POWER = 3)
- materials = list(DEFAULT_WALL_MATERIAL = 5000, "glass" = 1000, "uranium" = 500)
- build_path = /obj/item/weapon/gun/energy/gun/nuclear
- sort_string = "TAAAB"
+/datum/design/item/weapon/flora_gun
+ id = "flora_gun"
+ req_tech = list(TECH_MATERIAL = 2, TECH_BIO = 3, TECH_POWER = 3)
+ materials = list(DEFAULT_WALL_MATERIAL = 2000, "glass" = 500, "uranium" = 500)
+ build_path = /obj/item/weapon/gun/energy/floragun
+ sort_string = "TBAAA"
/datum/design/item/weapon/phoronpistol
id = "ppistol"
@@ -34,13 +27,6 @@
build_path = /obj/item/weapon/gun/energy/toxgun
sort_string = "TAAAD"
-/datum/design/item/weapon/decloner
- id = "decloner"
- req_tech = list(TECH_COMBAT = 7, TECH_MATERIAL = 7, TECH_BIO = 5, TECH_POWER = 6)
- materials = list("gold" = 5000,"uranium" = 10000)
- build_path = /obj/item/weapon/gun/energy/decloner
- sort_string = "TAAAE"
-
/datum/design/item/weapon/smg
id = "smg"
req_tech = list(TECH_COMBAT = 4, TECH_MATERIAL = 3)
@@ -93,13 +79,6 @@
build_path = /obj/item/weapon/grenade/chem_grenade/large
sort_string = "TACAA"
-/datum/design/item/weapon/flora_gun
- id = "flora_gun"
- req_tech = list(TECH_MATERIAL = 2, TECH_BIO = 3, TECH_POWER = 3)
- materials = list(DEFAULT_WALL_MATERIAL = 2000, "glass" = 500, "uranium" = 500)
- build_path = /obj/item/weapon/gun/energy/floragun
- sort_string = "TBAAA"
-
/datum/design/item/weapon/eglaive
id = "eglaive"
name = "energy glaive"
@@ -109,15 +88,6 @@
build_path = /obj/item/weapon/melee/energy/glaive
sort_string = "TVAAA"
-/datum/design/item/weapon/gatlinglaser
- id = "gatlinglaser"
- name = "gatling laser"
- desc = "A higly sophisticated rapid-fire laser weapon."
- req_tech = list(TECH_COMBAT = 6, TECH_PHORON = 5, TECH_MATERIAL = 6, TECH_POWER = 3)
- materials = list(DEFAULT_WALL_MATERIAL = 18750, "glass" = 7500, "phoron" = 7500, "silver" = 7500, "diamond" = 3000)
- build_path = /obj/item/weapon/gun/energy/vaurca/gatlinglaser
- sort_string = "TVBAA"
-
/datum/design/item/weapon/railgun
id = "railgun"
name = "railgun"
@@ -127,15 +97,6 @@
build_path = /obj/item/weapon/gun/projectile/automatic/railgun
sort_string = "TVCAA"
-/datum/design/item/weapon/zorablaster
- id = "zorablaster"
- name = "zo'ra blaster"
- desc = "A personal defense weapon reverse-engineered from schematics aboard Titan Prime."
- req_tech = list(TECH_COMBAT = 2, TECH_PHORON = 4, TECH_MATERIAL = 2)
- materials = list(DEFAULT_WALL_MATERIAL = 8000, "glass" = 2000, "phoron" = 6000)
- build_path = /obj/item/weapon/gun/energy/vaurca/blaster
- sort_string = "TVDAA"
-
/datum/design/item/weapon/lawgiver
name = "Lawgiver"
desc = "A highly advanced firearm for the modern police force. It has multiple voice-activated firing modes."
@@ -157,17 +118,6 @@
category = "Weapons"
sort_string = "TVFAA"
-/datum/design/item/ebow
- name = "Energy Crossbow"
- desc = "A weapon favoured by infiltration teams."
- id = "ebow"
- req_tech = list(TECH_COMBAT = 4, TECH_ENGINEERING = 3, TECH_MATERIAL = 5, TECH_ILLEGAL = 3, TECH_BIO = 4)
- build_type = PROTOLATHE
- materials = list(DEFAULT_WALL_MATERIAL = 5000, "glass" = 1000, "uranium" = 1000, "silver" = 1000)
- build_path = /obj/item/weapon/gun/energy/crossbow/largecrossbow
- category = "Weapons"
- sort_string = "TVGAA"
-
/datum/design/item/eshield
name = "Energy Shield"
desc = "A shield capable of stopping most projectile and melee attacks. It can be retracted, expanded, and stored anywhere."
@@ -179,28 +129,6 @@
category = "Weapons"
sort_string = "TVHAA"
-/datum/design/item/weapon/lasshotgun
- id = "laser_shotgun"
- req_tech = list(TECH_COMBAT = 3, TECH_MATERIAL = 5, TECH_POWER = 4)
- materials = list(DEFAULT_WALL_MATERIAL = 5000, "glass" = 1500, "uranium" = 500, "diamond" = 500)
- build_path = /obj/item/weapon/gun/energy/laser/shotgun
- sort_string = "TVIAA"
-
-/datum/design/item/weapon/lasercannon
- desc = "The lasing medium of this prototype is enclosed in a tube lined with uranium-235 and subjected to high neutron flux in a nuclear reactor core."
- id = "lasercannon"
- req_tech = list(TECH_COMBAT = 4, TECH_MATERIAL = 3, TECH_POWER = 3)
- materials = list(DEFAULT_WALL_MATERIAL = 10000, "glass" = 1000, "diamond" = 2000)
- build_path = /obj/item/weapon/gun/energy/rifle/laser/heavy
- sort_string = "TVJAA"
-
-/datum/design/item/weapon/mousegun
- id = "mousegun"
- req_tech = list(TECH_MATERIAL = 1, TECH_BIO = 4, TECH_POWER = 3)
- materials = list(DEFAULT_WALL_MATERIAL = 2000, "glass" = 1000, "uranium" = 500)
- build_path = /obj/item/weapon/gun/energy/mousegun
- sort_string = "TVLAA"
-
/datum/design/item/weapon/beegun
id = "beegun"
req_tech = list(TECH_MATERIAL = 6, TECH_BIO = 4, TECH_POWER = 4, TECH_COMBAT = 6, TECH_MAGNET = 4)
@@ -213,4 +141,292 @@
req_tech = list(TECH_COMBAT = 7, TECH_PHORON = 2, TECH_MATERIAL = 7, TECH_MAGNET = 4, TECH_POWER = 5, TECH_ILLEGAL = 3)
materials = list(DEFAULT_WALL_MATERIAL = 15000, "glass" = 9750, "phoron" = 5250, "gold" = 1100)
build_path = /obj/item/ammo_magazine/trodpack
- sort_string = "TVNAA"
\ No newline at end of file
+ sort_string = "TVNAA"
+
+///MODULAR WEAPON COMPONENTS
+/datum/design/item/weapon/modular_small
+ id = "stock_small"
+ req_tech = list(TECH_MATERIAL = 1)
+ materials = list(DEFAULT_WALL_MATERIAL = 2000)
+ build_path = /obj/item/device/laser_assembly
+ sort_string = "TZZAA"
+
+/datum/design/item/weapon/modular_medium
+ id = "stock_medium"
+ req_tech = list(TECH_MATERIAL = 1)
+ materials = list(DEFAULT_WALL_MATERIAL = 4000)
+ build_path = /obj/item/device/laser_assembly/medium
+ sort_string = "TZZAB"
+
+/datum/design/item/weapon/modular_large
+ id = "stock_large"
+ req_tech = list(TECH_MATERIAL = 1, TECH_ENGINEERING = 2)
+ materials = list(DEFAULT_WALL_MATERIAL = 8000)
+ build_path = /obj/item/device/laser_assembly/large
+ sort_string = "TZZAC"
+
+/datum/design/item/weapon/modular_cap
+ id = "stock_capacitor"
+ req_tech = list(TECH_POWER = 2, TECH_ENGINEERING = 2)
+ materials = list(DEFAULT_WALL_MATERIAL = 1000)
+ build_path = /obj/item/laser_components/capacitor
+ sort_string = "TZZBA"
+
+/datum/design/item/weapon/modular_starch
+ id = "stock_starch"
+ req_tech = list(TECH_ENGINEERING = 2)
+ materials = list(DEFAULT_WALL_MATERIAL = 1000)
+ build_path = /obj/item/laser_components/capacitor
+ sort_string = "TZZBB"
+
+/datum/design/item/weapon/modular_reinforced
+ id = "stock_reinforced_cap"
+ req_tech = list(TECH_POWER = 5, TECH_ENGINEERING = 3)
+ materials = list(DEFAULT_WALL_MATERIAL = 4000)
+ build_path = /obj/item/laser_components/capacitor/reinforced
+ sort_string = "TZZBC"
+
+/datum/design/item/weapon/modular_nuke
+ id = "stock_nuke_cap"
+ req_tech = list(TECH_POWER = 5, TECH_ENGINEERING = 5)
+ materials = list(DEFAULT_WALL_MATERIAL = 4000, "uranium" = 1000)
+ build_path = /obj/item/laser_components/capacitor/nuclear
+ sort_string = "TZZBC"
+
+/datum/design/item/weapon/modular_teranium
+ id = "stock_teranium"
+ req_tech = list(TECH_POWER = 6, TECH_ENGINEERING = 4, TECH_MAGNET = 6)
+ materials = list(DEFAULT_WALL_MATERIAL = 4000, "glass" = 1000, "uranium" = 500)
+ build_path = /obj/item/laser_components/capacitor/teranium
+ sort_string = "TZZBD"
+
+/datum/design/item/weapon/modular_phoron
+ id = "stock_teranium"
+ req_tech = list(TECH_POWER = 8, TECH_ENGINEERING = 5, TECH_PHORON = 6)
+ materials = list(DEFAULT_WALL_MATERIAL = 4000, "phoron" = 3000, "uranium" = 500)
+ build_path = /obj/item/laser_components/capacitor/phoron
+ sort_string = "TZZBE"
+
+/datum/design/item/weapon/modular_bs
+ id = "stock_bs"
+ req_tech = list(TECH_POWER = 8, TECH_ENGINEERING = 8, TECH_PHORON = 7, TECH_BLUESPACE = 7)
+ materials = list(DEFAULT_WALL_MATERIAL = 4000, "phoron" = 3000, "uranium" = 500, "diamond" = 1000)
+ build_path = /obj/item/laser_components/capacitor/teranium
+ sort_string = "TZZBF"
+
+/datum/design/item/weapon/modular_lens
+ id = "stock_lens"
+ req_tech = list(TECH_MATERIAL = 1, TECH_ENGINEERING = 1)
+ materials = list(DEFAULT_WALL_MATERIAL = 500, "glass" = 2000)
+ build_path = /obj/item/laser_components/focusing_lens
+ sort_string = "TZZCA"
+
+/datum/design/item/weapon/modular_splitter
+ id = "stock_splitter"
+ req_tech = list(TECH_MATERIAL = 2, TECH_ENGINEERING = 1)
+ materials = list(DEFAULT_WALL_MATERIAL = 750, "glass" = 2000)
+ build_path = /obj/item/laser_components/focusing_lens/shotgun
+ sort_string = "TZZCB"
+
+/datum/design/item/weapon/modular_sniper
+ id = "stock_sniper"
+ req_tech = list(TECH_MATERIAL = 2, TECH_ENGINEERING = 1)
+ materials = list(DEFAULT_WALL_MATERIAL = 750, "glass" = 2000)
+ build_path = /obj/item/laser_components/focusing_lens/sniper
+ sort_string = "TZZCC"
+
+/datum/design/item/weapon/modular_reinforced
+ id = "stock_strong"
+ req_tech = list(TECH_MATERIAL = 2, TECH_ENGINEERING = 1)
+ materials = list(DEFAULT_WALL_MATERIAL = 2000, "glass" = 1000)
+ build_path = /obj/item/laser_components/focusing_lens/strong
+ sort_string = "TZZCD"
+
+/datum/design/item/weapon/modular_silent
+ id = "stock_silence"
+ req_tech = list(TECH_MATERIAL = 2, TECH_ENGINEERING = 2)
+ materials = list(DEFAULT_WALL_MATERIAL = 2000)
+ build_path = /obj/item/laser_components/modifier/silencer
+ sort_string = "TZZDA"
+
+/datum/design/item/weapon/modular_aeg
+ id = "stock_aeg"
+ req_tech = list(TECH_COMBAT = 3, TECH_MATERIAL = 5, TECH_POWER = 3)
+ materials = list(DEFAULT_WALL_MATERIAL = 5000, "glass" = 1000, "uranium" = 500)
+ build_path = /obj/item/laser_components/modifier/aeg
+ sort_string = "TZZDB"
+
+/datum/design/item/weapon/modular_surge
+ id = "stock_surge"
+ req_tech = list(TECH_MATERIAL = 5, TECH_POWER = 3)
+ materials = list(DEFAULT_WALL_MATERIAL = 5000, "glass" = 1000)
+ build_path = /obj/item/laser_components/modifier/surge
+ sort_string = "TZZDC"
+
+/datum/design/item/weapon/modular_repeater
+ id = "stock_repeater"
+ req_tech = list(TECH_MATERIAL = 5, TECH_COMBAT = 3)
+ materials = list(DEFAULT_WALL_MATERIAL = 5000, "glass" = 1000)
+ build_path = /obj/item/laser_components/modifier/repeater
+ sort_string = "TZZDD"
+
+/datum/design/item/weapon/modular_aux
+ id = "stock_aux"
+ req_tech = list(TECH_MATERIAL = 5, TECH_COMBAT = 3, TECH_POWER = 3)
+ materials = list(DEFAULT_WALL_MATERIAL = 5000, "glass" = 1000)
+ build_path = /obj/item/laser_components/modifier/auxiliarycap
+ sort_string = "TZZDE"
+
+/datum/design/item/weapon/modular_overcharge
+ id = "stock_repeater"
+ req_tech = list(TECH_MATERIAL = 5, TECH_COMBAT = 4, TECH_POWER = 4)
+ materials = list(DEFAULT_WALL_MATERIAL = 5000, "glass" = 1000)
+ build_path = /obj/item/laser_components/modifier/overcharge
+ sort_string = "TZZDF"
+
+/datum/design/item/weapon/modular_gatling
+ id = "stock_gat"
+ req_tech = list(TECH_COMBAT = 6, TECH_PHORON = 5, TECH_MATERIAL = 6, TECH_POWER = 3)
+ materials = list(DEFAULT_WALL_MATERIAL = 750, "glass" = 3000, "phoron" = 2000, "silver" = 2000, "diamond" = 1000)
+ build_path = /obj/item/laser_components/modifier/gatling
+ sort_string = "TZZDG"
+
+/datum/design/item/weapon/modular_scope
+ id = "stock_scope"
+ req_tech = list(TECH_COMBAT = 2, TECH_MATERIAL = 2)
+ materials = list(DEFAULT_WALL_MATERIAL = 1000, "glass" = 500)
+ build_path = /obj/item/laser_components/modifier/scope
+ sort_string = "TZZDH"
+
+/datum/design/item/weapon/modular_barrel
+ id = "stock_barrel"
+ req_tech = list(TECH_COMBAT = 2, TECH_MATERIAL = 2)
+ materials = list(DEFAULT_WALL_MATERIAL = 3000)
+ build_path = /obj/item/laser_components/modifier/barrel
+ sort_string = "TZZDI"
+
+/datum/design/item/weapon/modular_vents
+ id = "stock_vents"
+ req_tech = list(TECH_COMBAT = 2, TECH_MATERIAL = 2)
+ materials = list(DEFAULT_WALL_MATERIAL = 3000)
+ build_path = /obj/item/laser_components/modifier/vents
+ sort_string = "TZZDJ"
+
+/datum/design/item/weapon/modular_stock
+ id = "stock_stock"
+ req_tech = list(TECH_COMBAT = 2, TECH_MATERIAL = 2)
+ materials = list(DEFAULT_WALL_MATERIAL = 3000)
+ build_path = /obj/item/laser_components/modifier/stock
+ sort_string = "TZZDK"
+
+/datum/design/item/weapon/modular_bayonet
+ id = "stock_bayonet"
+ req_tech = list(TECH_COMBAT = 2, TECH_MATERIAL = 2)
+ materials = list(DEFAULT_WALL_MATERIAL = 3000)
+ build_path = /obj/item/laser_components/modifier/bayonet
+ sort_string = "TZZDL"
+
+/datum/design/item/weapon/modular_ebayonet
+ id = "stock_ebayonet"
+ req_tech = list(TECH_COMBAT = 2, TECH_MATERIAL = 2, TECH_POWER = 2)
+ materials = list(DEFAULT_WALL_MATERIAL = 3000, "silver" = 500, "phoron" = 500)
+ build_path = /obj/item/laser_components/modifier/ebayonet
+ sort_string = "TZZDM"
+
+/datum/design/item/weapon/modular_taser
+ id = "stock_taser"
+ req_tech = list(TECH_COMBAT = 3, TECH_MATERIAL = 3, TECH_POWER = 2)
+ materials = list(DEFAULT_WALL_MATERIAL = 4000)
+ build_path = /obj/item/laser_components/modulator/taser
+ sort_string = "TZZEA"
+
+/datum/design/item/weapon/modular_tesla
+ id = "stock_supertaser"
+ req_tech = list(TECH_COMBAT = 6, TECH_MATERIAL = 6, TECH_POWER = 4)
+ materials = list(DEFAULT_WALL_MATERIAL = 4000, "silver" = 1000, "phoron" = 2000)
+ build_path = /obj/item/laser_components/modulator/tesla
+ sort_string = "TZZEB"
+
+/datum/design/item/weapon/modular_ion
+ id = "stock_ion"
+ req_tech = list(TECH_COMBAT = 3, TECH_MATERIAL = 3, TECH_POWER = 5)
+ materials = list(DEFAULT_WALL_MATERIAL = 750, "glass" = 500, "phoron" = 2000)
+ build_path = /obj/item/laser_components/modulator/ion
+ sort_string = "TZZEC"
+
+/datum/design/item/weapon/modular_soma
+ id = "stock_soma"
+ req_tech = list(TECH_MATERIAL = 2, TECH_BIO = 3, TECH_POWER = 3)
+ materials = list(DEFAULT_WALL_MATERIAL = 1000, "glass" = 250, "uranium" = 250)
+ build_path = /obj/item/laser_components/modulator/floramut
+ sort_string = "TZZED"
+
+/datum/design/item/weapon/modular_beta
+ id = "stock_beta"
+ req_tech = list(TECH_MATERIAL = 2, TECH_BIO = 3, TECH_POWER = 3)
+ materials = list(DEFAULT_WALL_MATERIAL = 1000, "glass" = 250, "uranium" = 250)
+ build_path = /obj/item/laser_components/modulator/floramut2
+ sort_string = "TZZEE"
+
+/datum/design/item/weapon/modular_pest
+ id = "stock_pest"
+ req_tech = list(TECH_MATERIAL = 1, TECH_BIO = 4, TECH_POWER = 3)
+ materials = list(DEFAULT_WALL_MATERIAL = 2000, "glass" = 1000, "uranium" = 500)
+ build_path = /obj/item/laser_components/modulator/arodentia
+ sort_string = "TZZEF"
+
+/datum/design/item/weapon/modular_tag1
+ id = "stock_tag1"
+ req_tech = list(TECH_COMBAT = 1, TECH_MATERIAL = 1)
+ materials = list(DEFAULT_WALL_MATERIAL = 2000)
+ build_path = /obj/item/laser_components/modulator/red
+ sort_string = "TZZEG"
+
+/datum/design/item/weapon/modular_tag2
+ id = "stock_tag2"
+ req_tech = list(TECH_COMBAT = 1, TECH_MATERIAL = 1)
+ materials = list(DEFAULT_WALL_MATERIAL = 2000)
+ build_path = /obj/item/laser_components/modulator/blue
+ sort_string = "TZZEH"
+
+/datum/design/item/weapon/modular_tag3
+ id = "stock_tag3"
+ req_tech = list(TECH_COMBAT = 2, TECH_MATERIAL = 1)
+ materials = list(DEFAULT_WALL_MATERIAL = 2000)
+ build_path = /obj/item/laser_components/modulator/omni
+ sort_string = "TZZEI"
+
+/datum/design/item/weapon/modular_practice
+ id = "stock_practice"
+ req_tech = list(TECH_MATERIAL = 1)
+ materials = list(DEFAULT_WALL_MATERIAL = 2000)
+ build_path = /obj/item/laser_components/modulator/practice
+ sort_string = "TZZEJ"
+
+/datum/design/item/weapon/modular_decloner
+ id = "stock_declone"
+ req_tech = list(TECH_COMBAT = 5, TECH_PHORON = 4)
+ materials = list(DEFAULT_WALL_MATERIAL = 5000, "glass" = 1000, "phoron" = 3000)
+ build_path = /obj/item/laser_components/modulator/mindflayer
+ sort_string = "TZZEK"
+
+/datum/design/item/weapon/modular_ebow
+ id = "stock_ebow"
+ req_tech = list(TECH_COMBAT = 5, TECH_PHORON = 4)
+ materials = list(DEFAULT_WALL_MATERIAL = 5000, "glass" = 1000, "phoron" = 3000)
+ build_path = /obj/item/laser_components/modulator/mindflayer
+ sort_string = "TZZEL"
+
+/datum/design/item/weapon/modular_blaster
+ id = "stock_blaster"
+ req_tech = list(TECH_COMBAT = 2, TECH_PHORON = 4, TECH_MATERIAL = 2)
+ materials = list(DEFAULT_WALL_MATERIAL = 8000, "glass" = 2000, "phoron" = 6000)
+ build_path = /obj/item/laser_components/modulator/blaster
+ sort_string = "TZZEM"
+
+/datum/design/item/weapon/modular_laser
+ id = "stock_laser"
+ req_tech = list(TECH_COMBAT = 2, TECH_MATERIAL = 3, TECH_POWER = 3)
+ materials = list(DEFAULT_WALL_MATERIAL = 750, "glass" = 500, "phoron" = 1000)
+ build_path = /obj/item/laser_components/modulator
+ sort_string = "TZZEN"
\ No newline at end of file
diff --git a/html/changelogs/sciencebuffs.yml b/html/changelogs/sciencebuffs.yml
new file mode 100644
index 00000000000..42da19b970b
--- /dev/null
+++ b/html/changelogs/sciencebuffs.yml
@@ -0,0 +1,38 @@
+################################
+# Example Changelog File
+#
+# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb.
+#
+# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.)
+# When it is, any changes listed below will disappear.
+#
+# Valid Prefixes:
+# bugfix
+# wip (For works in progress)
+# tweak
+# soundadd
+# sounddel
+# rscadd (general adding of nice things)
+# rscdel (general deleting of nice things)
+# imageadd
+# imagedel
+# maptweak
+# spellcheck (typo fixes)
+# experiment
+# balance
+#################################
+
+# Your name.
+author: LordFowl
+
+# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again.
+delete-after: True
+
+# Any changes you've made. See valid prefix list above.
+# INDENT WITH TWO SPACES. NOT TABS. SPACES.
+# SCREW THIS UP AND IT WON'T WORK.
+# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries.
+# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog.
+changes:
+ - rscdel: "Removes energy weapons (except the Lawgiver MkII) from the RnD protolathe."
+ - rscadd: "Adds components for the construction of modular energy weapons to the RnD protolathe. An energy weapon can be constructed by adding a capacitor, a lens, and a modulator plus any number of modifiers to an appropriate chassis."
diff --git a/icons/obj/modular_laser.dmi b/icons/obj/modular_laser.dmi
new file mode 100644
index 00000000000..815f6e89852
Binary files /dev/null and b/icons/obj/modular_laser.dmi differ