mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-08-30 00:21:11 +01:00
- balance: "Buffs gattling laser modifier charge time from 3 to 2 seconds. It took so long to charge multiple people thought it was bugged." This modifier was simply a downgrade, you'd be dead by the time it fired. Often people handed gattling guns would think they are bugged and unable to fire. This might help a bit. - balance: "Tweaks material costs, replacing uranium with silver and gold. Uranium was previously used everywhere." Everything used uranium, even things that really didn't make sense. As uranium spawns on station in engineering and the machinists, this is a slight nerf. - bugfix: "Fixed a bug where energy guns would not properly handle reliability failures when the gun was out of charge." - bugfix: "Fixed improvement potential calculations for ions and slimes. You no longer gain improvement shooting monkeys with ions, or for shooting slimes with lasers." - bugfix: "Fixed a bug with bluespace capacitors teleporting items in teleport inhibitor range. This was due to the EMP happening before the teleport and destroying the inhibitor." - bugfix: "Fixed Ion modulators not correctly decreasing the number of shots." Fixes: #22850
625 lines
29 KiB
Plaintext
625 lines
29 KiB
Plaintext
/obj/item/gun/energy/laser/prototype
|
|
name = "laser prototype"
|
|
desc = "A custom prototype laser weapon."
|
|
icon = 'icons/obj/guns/modular_laser.dmi'
|
|
icon_state = "large_3"
|
|
item_state = "large_3"
|
|
contained_sprite = TRUE
|
|
has_icon_ratio = FALSE
|
|
has_item_ratio = FALSE
|
|
fire_sound = 'sound/weapons/laser1.ogg'
|
|
slot_flags = SLOT_BELT|SLOT_BACK
|
|
w_class = WEIGHT_CLASS_NORMAL
|
|
force = 15
|
|
origin_tech = list(TECH_COMBAT = 3, TECH_MAGNET = 2)
|
|
matter = list(MATERIAL_STEEL = 2000)
|
|
can_turret = TRUE
|
|
zoomdevicename = null
|
|
max_shots = 0
|
|
burst_delay = 0
|
|
pin = null
|
|
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
|
|
///All malfunction effects are multiplied by this value. It can be increased by some powerful mods and decreased by safety mods.
|
|
var/criticality = 1 //multiplier for the negative effects of capacitor failures. Not just limited to critical failures.
|
|
///This multiplies the malus of all components, above 1 the gun degrades faster, below 1 it degrades slower.
|
|
var/fragility = 1
|
|
///True if the gun has a custom name.
|
|
var/named = 0
|
|
///True if the gun has a custom description.
|
|
var/described = 0
|
|
///When the weapon is disasembled, this is distributed randomly among its components. When a component with improvement potential is repaired, one appropriate variable gets better by up to improvement potential percent. The actual chance is based on skill level.
|
|
var/improvement_potential = 0 //This is a percentage increase of a single variable on one component, a 100% increase is not a doubling of all stats, it is instead spread out across all components.
|
|
|
|
/obj/item/gun/energy/laser/prototype/mechanics_hints(mob/user, distance, is_adjacent)
|
|
. = list()
|
|
var/skill_level = (GET_SKILL_LEVEL(user, FIREARMS_SKILL_COMPONENT) + GET_SKILL_LEVEL(user, RESEARCH_SKILL_COMPONENT))
|
|
switch(skill_level ? skill_level : 6)
|
|
if(2)
|
|
. += "Your complete lack of skill in firearms and research will hide all information about this weapon from you, you will also be unable to repair it decreasing its reliability."
|
|
if(3)
|
|
. += "Your low familiarity with firearms and research will hide most information about this weapon from you, you will also struggle to repair it without decreasing its reliability."
|
|
if(4)
|
|
. += "Your combined familiarity with firearms and research will show you most information about this weapon, you will also be able to repair it without decreasing its reliability, but are not likely to be able to improve it much."
|
|
if(5)
|
|
. += "Your combined training in firearms and research will show you all information about this weapon, you will also be able to repair it without decreasing its reliability and have a chance to improve it when repairing."
|
|
. += "It can be improved up to its improvement potential, which is increased by firing it. Firing it at players increases it most rapidly, following by firing it at simple mobs, then firing it at objects."
|
|
if(6 to INFINITY)
|
|
. += "Your combined professional expertise in firearms and research will show you all information about this weapon, you will also be able to repair it without decreasing its reliability, and have an excellent chance to improve it when repairing."
|
|
. += "It can be improved up to its improvement potential, which is increased by firing it. Firing it at players increases it most rapidly, following by firing it at simple mobs, then firing it at objects."
|
|
|
|
/obj/item/gun/energy/laser/prototype/Initialize(mapload)
|
|
. = ..()
|
|
RegisterSignal(src, COMSIG_PROJECTILE_ON_HIT, PROC_REF(on_projectile_hit))
|
|
|
|
/obj/item/gun/energy/laser/prototype/Destroy()
|
|
UnregisterSignal(src, COMSIG_PROJECTILE_ON_HIT)
|
|
return ..()
|
|
|
|
///This handles the improvement potential gain from firing the weapon. The actual improvement is handled in repair of the individual compoents, this just determines how much improvement potential is gained.
|
|
/obj/item/gun/energy/laser/prototype/proc/on_projectile_hit(fired_from, atom/movable/firer, atom/target, angle, def_zone, blocked)
|
|
SIGNAL_HANDLER
|
|
if(!target || target == firer)
|
|
return
|
|
|
|
if (istype(target, /obj/structure/machinery/portable_atmospherics/hydroponics))
|
|
if (istype(modulator, /obj/item/laser_components/modulator/floramut) || istype(modulator, /obj/item/laser_components/modulator/floramut2))
|
|
improvement_potential += (1 * IMPROVEMENT_MULTIPLIER) / (max(1, burst))
|
|
return
|
|
|
|
if(isliving(target)) //No improvement unless your target is a mob.
|
|
var/mob/living/target_mob = target
|
|
if(target_mob.stat != DEAD) //No improvement from shooting at dead things. Bring a doctor in to keep your target dummy alive. This also makes it harder to improve more powerful weapons, as you kill your target faster.
|
|
if(ishuman(target_mob))
|
|
var/mob/living/carbon/human/human_target = target
|
|
|
|
if (istype(modulator, /obj/item/laser_components/modulator/taser))
|
|
if (human_target.incapacitated()) //No benefit from tasing someone who's already incapacitated. Get the phramacist to make you oxycomorphine.
|
|
return
|
|
|
|
if(human_target.get_species() == SPECIES_MONKEY)
|
|
improvement_potential += (2 * IMPROVEMENT_MULTIPLIER) / (max(1, burst)) //Monkeys die easily, research only gets two boxes of monkey cubes without xenobiology.
|
|
return
|
|
|
|
if(human_target.client)
|
|
improvement_potential += (10 * IMPROVEMENT_MULTIPLIER) / (max(1, burst)) //10 seems like a lot, but this is a 20% improvement to 1 variable on 1 component. A 5 mod gun (8 total components), with an average of 3 improvable variables would need 120 shots on a player to max out.
|
|
return
|
|
|
|
if (istype(modulator, /obj/item/laser_components/modulator/ion))
|
|
if ((ismech(target_mob)) || (isbot(target_mob)) || (issilicon(target_mob))) //Shooting mechs or bots with ions.
|
|
improvement_potential += (5 * IMPROVEMENT_MULTIPLIER) / (max(1, burst))
|
|
if(!isturf(target)) //From shooting targets on the range.
|
|
improvement_potential += (1 * IMPROVEMENT_MULTIPLIER) / (max(1, burst))
|
|
return
|
|
|
|
if(isslime(target_mob)) //Slimes only give improvement if shot with freeze rays.
|
|
if (istype(modulator, /obj/item/laser_components/modulator/freeze))
|
|
improvement_potential += (2 * IMPROVEMENT_MULTIPLIER) / (max(1, burst))
|
|
if(!isturf(target)) //From shooting targets on the range.
|
|
improvement_potential += (1 * IMPROVEMENT_MULTIPLIER) / (max(1, burst))
|
|
return
|
|
|
|
improvement_potential += (5 * IMPROVEMENT_MULTIPLIER) / (max(1, burst)) //Mechs, protohumans, and any other human mobs without a player.
|
|
|
|
else if(!isturf(target)) //From shooting targets on the range.
|
|
improvement_potential += (1 * IMPROVEMENT_MULTIPLIER) / (max(1, burst))
|
|
|
|
/obj/item/gun/energy/laser/prototype/get_examine_text(mob/user, distance, is_adjacent, infix, suffix)
|
|
. = ..()
|
|
if(distance > 1)
|
|
return
|
|
var/skill_level = (GET_SKILL_LEVEL(user, FIREARMS_SKILL_COMPONENT) + GET_SKILL_LEVEL(user, RESEARCH_SKILL_COMPONENT))
|
|
|
|
if (capacitor.condition > 0 || focusing_lens.condition > 0 || modulator.condition > 0)
|
|
switch(skill_level ? skill_level : 6)
|
|
if (2 to 3) //At this level you can only tell that its damaged, nothing else.
|
|
. += SPAN_WARNING("It appears to be damaged.")
|
|
if (4 to 5) //At this level you can tell when the weapon is damaged and if it could malfunction.
|
|
if (reliability > 100)
|
|
. += SPAN_NOTICE("It appears to be damaged.")
|
|
else
|
|
. += SPAN_WARNING("It appears to be damaged and could malfunction!")
|
|
if (6 to INFINITY) //At this level you can estimate the weapon's reliability, but only if its damaged. This won't help if you build a weapon that's inherently unreliable.
|
|
if(improvement_potential > 2.5)
|
|
. += SPAN_GOOD("You see a few places where damage has revealed design flaws. Correcting them could improve one of the weapon's components by up to [round(improvement_potential, 5)]%.")
|
|
switch(reliability)
|
|
if (0 to 65)
|
|
. += SPAN_HIGHDANGER("It appears to be damaged and could go critical! You estimate it to be around [round(reliability, 5)]% reliable!")
|
|
if (66 to 80)
|
|
. += SPAN_DANGER("It appears to be damaged and could overload! You estimate it to be around [round(reliability, 5)]% reliable!")
|
|
if (81 to 100)
|
|
. += SPAN_WARNING("It appears to be damaged and could malfunction! You estimate it to be around [round(reliability, 5)]% reliable!")
|
|
if (101 to INFINITY)
|
|
. += SPAN_NOTICE("It appears to be damaged. You estimate it to be around [round(reliability, 5)]% reliable.")
|
|
|
|
switch(skill_level ? skill_level : 6)
|
|
if(2) //At this level you get no information about the weapon at all.
|
|
. += "This weapon is completely incomprehensible to you. It seems to be some sort of energy weapon, but you can't make out any details about how it functions."
|
|
if(3) //At this level you can only tell if the weapon has modifications or not, you can't make out what those modifications are.
|
|
if(gun_mods.len)
|
|
. += "This weapon is mostly incomprehensible to you. You can make out that it has some modifications, but the details of how they function are a mystery."
|
|
if(capacitor)
|
|
. += "You can see \a [capacitor] attached."
|
|
if(focusing_lens)
|
|
. += "You can see \a [focusing_lens] attached."
|
|
if(modulator)
|
|
. += "You can see \a [modulator] attached."
|
|
if(4) //At this level you can identify all components and if they're damaged or not.
|
|
if(gun_mods.len)
|
|
for(var/obj/item/laser_components/modifier/modifier in gun_mods)
|
|
. += "You can see \a [icon2html(modifier, user)][modifier] attached. [modifier.malus > modifier.base_malus ? SPAN_WARNING("It appears to be damaged.") : "It appears to be in good condition."]"
|
|
if(capacitor)
|
|
. += "You can see \a [icon2html(capacitor, user)][capacitor] attached. [capacitor.condition > 0 ? SPAN_WARNING("It appears to be damaged.") : "It appears to be in good condition."]"
|
|
if(focusing_lens)
|
|
. += "You can see \a [icon2html(focusing_lens, user)][focusing_lens] attached. [focusing_lens.condition > 0 ? SPAN_WARNING("It appears to be damaged.") : "It appears to be in good condition."]"
|
|
if(modulator)
|
|
. += "You can see \a [icon2html(modulator, user)][modulator] attached. [modulator.condition > 0 ? SPAN_WARNING("It appears to be damaged.") : "It appears to be in good condition."]"
|
|
if(5) //At this level you can identify all parts and can estimate the health of the three components, but not the modifiers, or the improvement potential.
|
|
if(gun_mods.len)
|
|
for(var/obj/item/laser_components/modifier/modifier in gun_mods)
|
|
. += "You can see \a [icon2html(modifier, user)][modifier] attached. [modifier.malus > modifier.base_malus ? SPAN_WARNING("It appears to be damaged.") : "It appears to be in good condition."]"
|
|
if(capacitor)
|
|
. += "You can see \a [icon2html(capacitor, user)][capacitor] attached. [capacitor.condition > 0 ? SPAN_WARNING("It appears to be [round(max(0, min(100, 100 - ((capacitor.condition / capacitor.reliability) * 100))))]% reliable.") : "It is good condition."]"
|
|
if(focusing_lens)
|
|
. += "You can see \a [icon2html(focusing_lens, user)][focusing_lens] attached. [focusing_lens.condition > 0 ? SPAN_WARNING("It appears to be [round(max(0, min(100, 100 - ((focusing_lens.condition / focusing_lens.reliability) * 100))))]% reliable.") : "It is good condition."]"
|
|
if(modulator)
|
|
. += "You can see \a [icon2html(modulator, user)][modulator] attached. [modulator.condition > 0 ? SPAN_WARNING("It appears to be [round(max(0, min(100, 100 - ((modulator.condition / modulator.reliability) * 100))))]% reliable.") : "It is good condition."]"
|
|
if(6 to INFINITY) //At this level you get the health of the gun, all components and the improvement potential.
|
|
if(gun_mods.len)
|
|
for(var/obj/item/laser_components/modifier/modifier in gun_mods)
|
|
. += "You can see \a [icon2html(modifier, user)][modifier] attached. [modifier.malus > modifier.base_malus ? SPAN_WARNING("It appears to be [round(max(0, min(100, 100 - (((modifier.malus - modifier.base_malus) / modifier.base_malus) * 100))))]% reliable.") : "It is good condition."]" //Base malus can be zero, modifiers with no base malus can't get damaged.
|
|
if(capacitor)
|
|
. += "You can see \a [icon2html(capacitor, user)][capacitor] attached. [capacitor.condition > 0 ? SPAN_WARNING("It appears to be [round(max(0, min(100, 100 - ((capacitor.condition / capacitor.reliability) * 100))))]% reliable.") : "It is good condition."]"
|
|
if(focusing_lens)
|
|
. += "You can see \a [icon2html(focusing_lens, user)][focusing_lens] attached. [focusing_lens.condition > 0 ? SPAN_WARNING("It appears to be [round(max(0, min(100, 100 - ((focusing_lens.condition / focusing_lens.reliability) * 100))))]% reliable.") : "It is good condition."]"
|
|
if(modulator)
|
|
. += "You can see \a [icon2html(modulator, user)][modulator] attached. [modulator.condition > 0 ? SPAN_WARNING("It appears to be [round(max(0, min(100, 100 - ((modulator.condition / modulator.reliability) * 100))))]% reliable.") : "It is good condition."]"
|
|
|
|
/obj/item/gun/energy/laser/prototype/attackby(obj/item/attacking_item, mob/user)
|
|
var/skill_level = (GET_SKILL_LEVEL(user, FIREARMS_SKILL_COMPONENT) + GET_SKILL_LEVEL(user, RESEARCH_SKILL_COMPONENT))
|
|
|
|
if(istype(attacking_item, /obj/item/stack/nanopaste)) //Nanopaste can be used for emergency repairs, but its not ideal and will reduce the reliability of the gun.
|
|
var/obj/item/stack/nanopaste/N = attacking_item
|
|
|
|
if (skill_level ? skill_level : 6)
|
|
to_chat(user, "You begin applying \the [N] to \the [src], repairing it in such a slapdash manner will damage it.")
|
|
if(do_after(user, 12/skill_level SECONDS, src, DO_REPAIR_CONSTRUCT))
|
|
repair_components(N, skill_level, user)
|
|
|
|
//TODO: High skilled technicans can add mods to guns after final assembly, requires a rework of the weapon analyzer.
|
|
//if(istype(attacking_item, /obj/item/laser_components/modifier))
|
|
|
|
if(attacking_item.tool_behaviour != TOOL_SCREWDRIVER)
|
|
return ..()
|
|
to_chat(user, "You disassemble \the [src].")
|
|
disassemble(user)
|
|
|
|
/obj/item/gun/energy/laser/prototype/proc/repair_components(var/obj/item/stack/nanopaste/N, var/skill_level, var/mob/user)
|
|
if(capacitor && capacitor.condition > 0)
|
|
if(N.use(1))
|
|
capacitor.condition = max(0, capacitor.condition - 5 * skill_level)
|
|
capacitor.reliability = max(0, capacitor.reliability - 12/skill_level) //Using nanopaste to repair the capacitor reduces its reliability, this is to represent the fact that its a suboptimal repair job, and to prevent players from using nanopaste as a free repair method.
|
|
to_chat(user, "You repair \the [capacitor]. The leftover nanopaste is gumming up the delicate component, reducing its reliability.")
|
|
else if(focusing_lens && focusing_lens.condition > 0)
|
|
if(N.use(1))
|
|
focusing_lens.condition = max(0, focusing_lens.condition - 5 * skill_level)
|
|
focusing_lens.reliability = max(0, focusing_lens.reliability - 12/skill_level)
|
|
to_chat(user, "You repair \the [focusing_lens]. The leftover nanopaste is obscuring the lens, reducing its reliability.")
|
|
else if(modulator && modulator.condition > 0)
|
|
if(N.use(1))
|
|
modulator.condition = max(0, modulator.condition - 5 * skill_level)
|
|
modulator.reliability = max(0, modulator.reliability - 12/skill_level)
|
|
to_chat(user, "You repair \the [modulator]. The leftover nanopaste is blocking \the [modulator]'s emitters, reducing its reliability.")
|
|
else
|
|
to_chat(user, "There is nothing to repair on the gun!")
|
|
|
|
/obj/item/gun/energy/laser/prototype/handle_post_fire(mob/user, atom/target)
|
|
return ..()
|
|
|
|
/obj/item/gun/energy/laser/prototype/update_icon()
|
|
..()
|
|
underlays.Cut()
|
|
if(length(gun_mods))
|
|
for(var/obj/item/laser_components/mod in gun_mods)
|
|
if(mod.gun_overlay)
|
|
underlays += mod.gun_overlay
|
|
underlays.Cut()
|
|
for(var/v in gun_mods)
|
|
var/obj/item/laser_components/modifier/mod = v
|
|
if(mod.gun_overlay)
|
|
underlays += mod.gun_overlay
|
|
|
|
/obj/item/gun/energy/laser/prototype/proc/reset_vars()
|
|
burst = initial(burst)
|
|
reliability = initial(reliability)
|
|
burst_delay = initial(burst_delay)
|
|
max_shots = initial(max_shots)
|
|
charge_cost = initial(charge_cost)
|
|
chargetime = initial(chargetime)
|
|
fire_delay = initial(fire_delay)
|
|
fire_delay_wielded = initial(fire_delay_wielded)
|
|
accuracy = initial(accuracy)
|
|
criticality = initial(criticality)
|
|
fragility = initial(fragility)
|
|
fire_sound = initial(fire_sound)
|
|
force = initial(force)
|
|
is_wieldable = initial(is_wieldable)
|
|
action_button_name = initial(action_button_name)
|
|
|
|
|
|
/obj/item/gun/energy/laser/prototype/proc/delayed_overload(var/mob/user)
|
|
if(capacitor.reliability - capacitor.condition > 0)
|
|
to_chat(user, SPAN_DANGER("\The [src.capacitor] stops overloading, you fixed it just in time."))
|
|
else
|
|
if(prob(50 * criticality))
|
|
critical_fail(user)
|
|
else if(prob(75 * criticality))
|
|
medium_fail(user)
|
|
else
|
|
small_fail(user)
|
|
qdel(capacitor)
|
|
capacitor = null
|
|
disassemble(user)
|
|
|
|
/obj/item/gun/energy/laser/prototype/proc/updatetype(var/mob/user)
|
|
reset_vars() //Reset the gun to its initial values, then recalculate all stats based on the current state of components and mods.
|
|
|
|
if(!focusing_lens || !capacitor || !modulator)
|
|
return
|
|
|
|
update_chassis()
|
|
|
|
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 = round(capacitor.shots)
|
|
max_shots *= modulator.shots
|
|
dispersion = focusing_lens.dispersion
|
|
accuracy = focusing_lens.accuracy
|
|
burst += round(focusing_lens.burst)
|
|
fire_sound = modulator.firing_sound
|
|
fragility = capacitor.malus_multiplier
|
|
|
|
if(gun_mods.len)
|
|
handle_mod()
|
|
|
|
if(capacitor.reliability - capacitor.condition <= 0) //The gun explodes if its capacitor reaches 0 reliability.
|
|
var/overload_delay = 3/criticality
|
|
var/skill_level = (GET_SKILL_LEVEL(user, FIREARMS_SKILL_COMPONENT) + GET_SKILL_LEVEL(user, RESEARCH_SKILL_COMPONENT))
|
|
switch(skill_level ? skill_level : 6)
|
|
if(2 to 3)
|
|
to_chat(user, SPAN_HIGHDANGER("\The [src] hisses ominously!"))
|
|
if(4 to 5)
|
|
overload_delay *= 1.5
|
|
to_chat(user, SPAN_HIGHDANGER("\The [src] hisses ominously as \the [capacitor]'s housing begins to fail, you release the trigger but it's too late! Get rid of it!"))
|
|
if(6 to INFINITY)
|
|
overload_delay *= 2
|
|
to_chat(user, SPAN_HIGHDANGER("You instantly release the trigger as \the [capacitor]'s housing begins to fail! You have less than [round(overload_delay)] seconds to repair \the [src] or throw it away!"))
|
|
|
|
addtimer(CALLBACK(src, PROC_REF(delayed_overload)), overload_delay SECONDS, TIMER_STOPPABLE|TIMER_DELETE_ME)
|
|
animate(src, overload_delay SECONDS + rand(-5, 5), -1, LINEAR_EASING, color = COLOR_RED)
|
|
return
|
|
|
|
if(focusing_lens.reliability - focusing_lens.condition <= 0)
|
|
to_chat(user, SPAN_DANGER("\The [src]'s focusing lens shatters with a loud crack!"))
|
|
qdel(focusing_lens)
|
|
focusing_lens = null
|
|
|
|
power_supply.maxcharge = max_shots*charge_cost
|
|
charge_cost /= max(1, (burst - 1))
|
|
fire_delay_wielded = fire_delay * 0.75
|
|
accuracy_wielded = accuracy + abs(accuracy)/2
|
|
scoped_accuracy = accuracy_wielded + abs(accuracy)
|
|
w_class = gun_type
|
|
reliability = max(reliability, 1)
|
|
|
|
/obj/item/gun/energy/laser/prototype/proc/update_chassis()
|
|
switch(origin_chassis)
|
|
if(CHASSIS_SMALL)
|
|
gun_type = CHASSIS_SMALL
|
|
slot_flags = SLOT_BELT | SLOT_HOLSTER
|
|
item_state = "small_3"
|
|
if(CHASSIS_MEDIUM)
|
|
gun_type = CHASSIS_MEDIUM
|
|
slot_flags = SLOT_BELT | SLOT_BACK
|
|
item_state = "medium_3"
|
|
is_wieldable = TRUE
|
|
if(CHASSIS_LARGE)
|
|
gun_type = CHASSIS_LARGE
|
|
slot_flags = SLOT_BACK
|
|
item_state = "large_3"
|
|
is_wieldable = TRUE
|
|
one_hand_fa_penalty = 12
|
|
|
|
/obj/item/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)
|
|
suppressed = TRUE
|
|
if(MOD_NUCLEAR_CHARGE)
|
|
self_recharge = TRUE
|
|
fire_delay *= modifier.fire_delay
|
|
reliability += modifier.reliability
|
|
burst += modifier.burst
|
|
burst_delay += modifier.burst_delay
|
|
max_shots *= modifier.shots //We want to add all the shot multipliers together, then apply them all at once.
|
|
force = min(force + modifier.gun_force, 40)
|
|
chargetime += modifier.chargetime SECONDS
|
|
accuracy += modifier.accuracy
|
|
criticality *= modifier.criticality
|
|
fragility *= modifier.malus_multiplier
|
|
if(modifier.scope_name)
|
|
zoomdevicename = modifier.scope_name
|
|
|
|
/obj/item/gun/energy/laser/prototype/consume_next_projectile(var/mob/user, var/bypass_degrade = FALSE)
|
|
if(!power_supply)
|
|
return null
|
|
if(!ispath(projectile_type))
|
|
return null
|
|
if(!power_supply.checked_use(charge_cost))
|
|
return null
|
|
if(!capacitor || capacitor.condition >= capacitor.reliability)
|
|
return null
|
|
if (self_recharge)
|
|
addtimer(CALLBACK(src, PROC_REF(try_recharge)), recharge_time * 2 SECONDS, TIMER_UNIQUE)
|
|
var/obj/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(!bypass_degrade)
|
|
for(var/obj/item/laser_components/modifier/modifier in gun_mods) //This repeats for EVERY MOD, fail chance goes up quadratically with the number of mods
|
|
if(prob(max(1,(gun_mods.len * 2 * damage_coeff)/(max(1,(burst))))))
|
|
capacitor.degrade(modifier.malus * fragility)
|
|
if(prob(max(1,(gun_mods.len * damage_coeff)/(max(1,(burst))))))
|
|
focusing_lens.degrade(modifier.malus * fragility)
|
|
if(prob(max(1,(5 + capacitor.condition)/(max(1,(burst)))))) //Firing a gun with a damaged capacitor risks arcing to other components, damaging them
|
|
modifier.degrade(0.2 * fragility)
|
|
|
|
if(burst > 1)
|
|
A.damage = A.damage/(max(1, burst - 1)) //Damage is divided by the number of shots
|
|
damage_coeff *= modulator.damage
|
|
A.damage *= damage_coeff
|
|
A.damage = min(A.damage, 60) //Caps the maximum damage one shot can do, this matches the laser cannon
|
|
|
|
updatetype(ismob(loc) ? loc : null)
|
|
return A
|
|
|
|
/obj/item/gun/energy/laser/prototype/proc/disassemble(var/mob/user)
|
|
var/atom/A = get_turf(src)
|
|
if(!A)
|
|
return
|
|
|
|
var/list/damaged_components = list()
|
|
|
|
if(capacitor && capacitor.condition > 0)
|
|
damaged_components += capacitor
|
|
if(focusing_lens && focusing_lens.condition > 0)
|
|
damaged_components += focusing_lens
|
|
if(modulator && modulator.condition > 0)
|
|
damaged_components += modulator
|
|
for(var/obj/item/laser_components/modifier/modifier in gun_mods)
|
|
if(modifier.malus > modifier.base_malus)
|
|
damaged_components += modifier
|
|
|
|
while(improvement_potential > 0 && damaged_components.len)
|
|
var/list/upgradable_components = list()
|
|
for(var/obj/item/laser_components/component in damaged_components) //Only give it improvement potential if it's damaged.
|
|
if((component.total_improved + component.improvement_potential) < component.improvement_cap) //Only give it improvement potential if it doesn't have enough to hit cap.
|
|
if(component.increasable_stats.len || component.decreaseable_stats.len) //Don't give it to components with nothing to improve.
|
|
upgradable_components += component
|
|
else
|
|
damaged_components.Remove(component) //If a component has reached the improvement cap, it can't be improved anymore.
|
|
|
|
if(!upgradable_components.len)
|
|
to_chat(user, SPAN_WARNING("There's nothing to improve on the components of this gun."))
|
|
break
|
|
|
|
var/obj/item/laser_components/selected_component = pick(upgradable_components)
|
|
var/potential_to_components = min(rand(0, improvement_potential), 30) //Sends up a random amount up to 30 improvement points to the component.
|
|
|
|
if(potential_to_components)
|
|
selected_component.improvement_potential += potential_to_components
|
|
improvement_potential -= potential_to_components
|
|
|
|
// Drop all components to the ground
|
|
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
|
|
if(pin)
|
|
pin.forceMove(A)
|
|
pin.gun = null
|
|
pin = null
|
|
switch(origin_chassis)
|
|
if(CHASSIS_SMALL)
|
|
new /obj/item/laser_assembly(A)
|
|
if(CHASSIS_MEDIUM)
|
|
new /obj/item/laser_assembly/medium(A)
|
|
if(CHASSIS_LARGE)
|
|
new /obj/item/laser_assembly/large(A)
|
|
qdel(src)
|
|
|
|
/obj/item/gun/energy/laser/prototype/small_fail(var/mob/user)
|
|
if(capacitor)
|
|
capacitor.small_fail(user, src)
|
|
return
|
|
|
|
/obj/item/gun/energy/laser/prototype/medium_fail(var/mob/user)
|
|
if(capacitor)
|
|
capacitor.medium_fail(user, src)
|
|
return
|
|
|
|
/obj/item/gun/energy/laser/prototype/critical_fail(var/mob/user)
|
|
if(capacitor)
|
|
capacitor.critical_fail(user, src)
|
|
return
|
|
|
|
/obj/item/gun/energy/laser/prototype/can_wield()
|
|
if(origin_chassis >= CHASSIS_MEDIUM)
|
|
return 1
|
|
else
|
|
return 0
|
|
|
|
/obj/item/gun/energy/laser/prototype/ui_action_click()
|
|
if(src in usr)
|
|
toggle_wield(usr)
|
|
|
|
/obj/item/gun/energy/laser/prototype/verb/scope()
|
|
set category = "Object.Held"
|
|
set name = "Use Scope"
|
|
set src in usr
|
|
|
|
if(zoomdevicename)
|
|
if(wielded)
|
|
toggle_scope(2.0, usr)
|
|
else
|
|
to_chat(usr, SPAN_WARNING("You can't look through the scope without stabilizing the rifle!"))
|
|
else
|
|
to_chat(usr, SPAN_WARNING("This device does not have a scope installed!"))
|
|
|
|
/obj/item/gun/energy/laser/prototype/special_check(var/mob/user)
|
|
if(is_charging && chargetime)
|
|
to_chat(user, SPAN_DANGER("\The [src] is already charging!"))
|
|
return 0
|
|
if(chargetime)
|
|
user.visible_message(
|
|
SPAN_DANGER("\The [user] begins charging the [src]!"),
|
|
SPAN_DANGER("You begin charging the [src]!"),
|
|
SPAN_DANGER("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 ..()
|
|
|
|
/obj/item/gun/energy/laser/prototype/verb/rename_gun()
|
|
set name = "Name Prototype"
|
|
set category = "Object.Held"
|
|
set desc = "Name your invention so that its glory might be eternal"
|
|
set src in usr
|
|
|
|
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
|
|
to_chat(M, "You name the gun [input]. Say hello to your new friend.")
|
|
named = 1
|
|
return 1
|
|
|
|
/obj/item/gun/energy/laser/prototype/verb/describe_gun()
|
|
set name = "Describe Prototype"
|
|
set category = "Object.Held"
|
|
set desc = "Describe your invention so that its glory might be eternal"
|
|
set src in usr
|
|
|
|
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
|
|
to_chat(M, "You describe the gun as [input]. Say hello to your new friend.")
|
|
described = 1
|
|
return 1
|
|
|
|
/obj/item/gun/energy/laser/prototype/get_print_info()
|
|
. = ""
|
|
|
|
var/l_modified_damage = 1 / max(1, burst - 1)
|
|
var/l_modified_max_shots = 1
|
|
for(var/i in list(capacitor, focusing_lens, modulator) + gun_mods)
|
|
var/obj/item/laser_components/l_component = i
|
|
if(!l_component)
|
|
continue
|
|
|
|
if(l_component.damage != 0)
|
|
l_modified_damage *= l_component.damage
|
|
if(l_component.shots != 0)
|
|
l_modified_max_shots *= l_component.shots
|
|
|
|
var/obj/projectile/P = new projectile_type
|
|
. += "Max Shots: [round(l_modified_max_shots)]<br>"
|
|
. += "Recharge Type: [self_recharge ? "self recharging" : "not self recharging"]<br>"
|
|
if(self_recharge)
|
|
. += "Recharge Time: [initial(recharge_time)]<br>"
|
|
. += "<br><b>Primary Projectile</b><br>"
|
|
. += "Damage: [round(min(60, l_modified_damage), 1)]<br>"
|
|
. += "Damage Type: [initial(P.damage_type)]<br>"
|
|
. += "Blocked by Armor Type: [initial(P.check_armor)]<br>"
|
|
. += "Stuns: [initial(P.stun) ? "true" : "false"]<br>"
|
|
if(initial(P.shrapnel_type))
|
|
var/obj/shrapnel = new P.shrapnel_type
|
|
. += "Shrapnel Type: [shrapnel.name]<br>"
|
|
. += "Armor Penetration: [initial(P.armor_penetration)]%<br>"
|
|
. += "Burst: [burst]<br>"
|
|
. += "Reliability: [reliability]<br>"
|
|
|
|
if(secondary_projectile_type)
|
|
var/obj/projectile/P_second = new secondary_projectile_type
|
|
. += "<br><b>Secondary Projectile</b><br>"
|
|
. += "Damage: [initial(P_second.damage)]<br>"
|
|
. += "Damage Type: [initial(P_second.damage_type)]<br>"
|
|
. += "Blocked by Armor Type: [initial(P_second.check_armor)]<br>"
|
|
. += "Stuns: [initial(P_second.stun) ? "true" : "false"]<br>"
|
|
if(initial(P_second.shrapnel_type))
|
|
var/obj/shrapnel_second = new P_second.shrapnel_type
|
|
. += "Shrapnel Type: [shrapnel_second.name]<br>"
|
|
. += "Armor Penetration: [initial(P_second.armor_penetration)]%<br>"
|
|
|
|
. += "<br>"
|
|
|
|
for(var/i in list(capacitor, focusing_lens, modulator) + gun_mods)
|
|
var/obj/item/laser_components/l_component = i
|
|
if(!l_component)
|
|
continue
|
|
|
|
. += "<br>Component Name: [initial(l_component.name)]</br><br>"
|
|
var/l_repair_name = initial(l_component.repair_item.name) ? initial(l_component.repair_item.name) : "nothing"
|
|
if(l_component.reliability != 0)
|
|
. += "Reliability: [round(l_component.reliability, 1)]<br>"
|
|
if(l_component.damage != 1)
|
|
. += "Damage Modifier: [round(l_component.damage, 0.1)]<br>"
|
|
if(l_component.fire_delay != 1)
|
|
. += "Fire Delay Modifier: [round(l_component.fire_delay, 0.1)]<br>"
|
|
if(l_component.shots != 1)
|
|
. += "Shots Modifier: [round(l_component.shots, 0.1)]<br>"
|
|
if(l_component.burst != 0)
|
|
. += "Burst Modifier: [round(l_component.burst, 1)]<br>"
|
|
if(l_component.accuracy != 0)
|
|
. += "Accuracy Modifier: [round(l_component.accuracy, 0.1)]<br>"
|
|
. += "Repair Tool: [l_repair_name]<br>"
|