diff --git a/code/modules/projectiles/guns/energy/particle.dm b/code/modules/projectiles/guns/energy/particle.dm index bb50366ec7..ab20585b49 100644 --- a/code/modules/projectiles/guns/energy/particle.dm +++ b/code/modules/projectiles/guns/energy/particle.dm @@ -1,11 +1,20 @@ -/obj/item/weapon/gun/energy/particle - name = "Antiparticle projector gun" +/obj/item/weapon/gun/energy/particle //base gun, similar stats to an egun + name = "Antiparticle projector pistol" icon = 'icons/obj/gun_vr.dmi' - icon_state = "particle" - item_state = "particle" - desc = "An unconventional firearm, APP guns generate attogram-scale quantities of antimatter which are then launched using an electromagnetic field." - force = 5 - fire_sound = 'sound/weapons/Laser.ogg' + icon_state = "ppistol" + item_state = "ppistol_item" + icon_override = 'icons/obj/gun_vr.dmi' + item_icons = null + desc = "A Kawashima Material Technology Model 7 anti-particle projector, housed in a rugged casing." + description_info = "An unconventional weapon, APP guns generate attogram-scale quantities of antimatter which \ + are then launched using an electromagnetic field. They are only suitable for use in depressurised environments, \ + else the antimatter pellet is liable to strike the air before it reaches the target. This can result in catastrophic \ + failure, making them unsuitable as military weapons in practical situations as they are prone to backfiring and \ + jamming, though they perform as adequately as any laser weapon in vacuum. Nonetheless, they have found a niche among \ + miners and salvage crews, as their lack of usefulness as a firearm in habitable areas means most authorities do not \ + classify them as dangerous weapons (at least, not dangerous to whoever they're pointed at) - instead, in most \ + jurisdictions including NT space, APP guns are officially classed as mining equipment rather than firearms." + fire_sound = 'sound/weapons/blaster.ogg' slot_flags = SLOT_BELT w_class = ITEMSIZE_NORMAL projectile_type = /obj/item/projectile/bullet/particle @@ -13,8 +22,45 @@ fire_delay = 10 charge_cost = 240 //same cost as lasers var/safetycatch = 0 //if 1, won't let you fire in pressurised environment, rather than malfunctioning + var/obj/item/pressurelock/attached_safety +/obj/item/weapon/gun/energy/particle/advanced //particle equivalent of AEG + name = "Advanced antiparticle rifle" + icon_state = "particle" + item_state = "particle_item" + desc = "An antiparticle projector gun with an enhanced power-generation unit." + slot_flags = SLOT_BELT + force = 8 //looks heavier than a pistol + w_class = ITEMSIZE_LARGE //bigger than a pistol, too. + fire_delay = 6 //This one's not a handgun, it should have the same fire delay as everything else + self_recharge = 1 + modifystate = null + battery_lock = 1 + recharge_time = 15 // every 15 ticks, recharge 2 shots. Rather slower than AEG. + charge_delay = 20 //Starts recharging faster after firing than an AEG, but much slower recharge rate. Balances out for a full charge. + +/obj/item/weapon/gun/energy/particle/cannon //particle version of laser cannon + name = "Anti-particle cannon" + desc = "A giant beast of an antimatter gun, packed with an internal reactor to allow for extreme longevity on remote mining expeditions." + icon_state = "heavyparticle" + item_state = "heavyparticle_item" + fire_sound = 'sound/weapons/lasercannonfire.ogg' + slot_flags = SLOT_BACK + projectile_type = /obj/item/projectile/bullet/particle/heavy + battery_lock = 1 + fire_delay = 20 + w_class = ITEMSIZE_HUGE // So it can't fit in a backpack. + force = 10 + one_handed_penalty = 6 // The thing's heavy and huge. + accuracy = 3 + charge_cost = 480 // 5 shots + self_recharge = 1 + charge_delay = 20 //won't start charging until it's ready to fire again + recharge_time = 20 //100 ticks after that to refill the whole thing. + +//special behaviours for particle guns below + /obj/item/weapon/gun/energy/particle/special_check(var/mob/user) if (..()) var/turf/T = get_turf(src) @@ -32,56 +78,113 @@ return 0 else if (prob(min(pressure, 100))) //pressure% chance of failing var/severity = rand(pressure) - if (severity <= 10) // just doesn't fire. 10% chance in 100 atmo. - user.visible_message("*click*", "\The [src] jams.") - playsound(src.loc, 'sound/weapons/empty.ogg', 100, 1) - else if (severity <= 60) //50% chance of fizzling and wasting a shot - user.visible_message("\The [user] fires \the [src], but the shot fizzles in the air!", "You fire \the [src], but the shot fizzles in the air!") - power_supply.charge -= charge_cost - playsound(src.loc, fire_sound, 100, 1) - var/datum/effect/effect/system/spark_spread/sparks = PoolOrNew(/datum/effect/effect/system/spark_spread) - sparks.set_up(2, 1, T) - sparks.start() - update_icon() - else if (severity <= 80) //20% chance of shorting out and emptying the cell - user.visible_message("\The [user] pulls the trigger, but \the [src] shorts out!", "You pull the trigger, but \the [src] shorts out!") - power_supply.charge = 0 - var/datum/effect/effect/system/spark_spread/sparks = PoolOrNew(/datum/effect/effect/system/spark_spread) - sparks.set_up(2, 1, T) - sparks.start() - update_icon() - else if (severity <= 90) //10% chance of breaking the gun - user.visible_message("\The [user] pulls the trigger, but \the [src] erupts in a shower of sparks!", "You pull the trigger, but \the [src] bursts into a shower of sparks!") - var/datum/effect/effect/system/spark_spread/sparks = PoolOrNew(/datum/effect/effect/system/spark_spread) - sparks.set_up(2, 1, T) - sparks.start() - power_supply.charge = 0 - power_supply.maxcharge = 0 - power_supply.desc += " It seems to be burnt out!" - desc += " The casing is covered in scorch-marks." - fire_delay += fire_delay // even if you swap out the cell for a good one, the gun's cluckety-clucked. - charge_cost += charge_cost - update_icon() - else if (severity <= 150) // 10% chance of exploding - user << "The [src] explodes!" - explosion(T, -1, -1, 1, 1) - qdel(src) - else //can only possibly happen if you're dumb enough to fire it in an OVER pressure environment, over 150kPa - user << "The [src] explodes catastrophically!" - explosion(T, -1, 1, 2, 2) - qdel(src) + pressuremalfunction(severity, user, T) return 0 return 1 return 0 +/obj/item/weapon/gun/energy/particle/proc/pressuremalfunction(severity, var/mob/user, var/turf/T) + if (severity <= 10) // just doesn't fire. 10% chance in 100 atmo. + user.visible_message("*click*", "\The [src] jams.") + playsound(src.loc, 'sound/weapons/empty.ogg', 100, 1) + else if (severity <= 60) //50% chance of fizzling and wasting a shot + user.visible_message("\The [user] fires \the [src], but the shot fizzles in the air!", "You fire \the [src], but the shot fizzles in the air!") + power_supply.charge -= charge_cost + playsound(src.loc, fire_sound, 100, 1) + var/datum/effect/effect/system/spark_spread/sparks = PoolOrNew(/datum/effect/effect/system/spark_spread) + sparks.set_up(2, 1, T) + sparks.start() + update_icon() + else if (severity <= 80) //20% chance of shorting out and emptying the cell + user.visible_message("\The [user] pulls the trigger, but \the [src] shorts out!", "You pull the trigger, but \the [src] shorts out!") + power_supply.charge = 0 + var/datum/effect/effect/system/spark_spread/sparks = PoolOrNew(/datum/effect/effect/system/spark_spread) + sparks.set_up(2, 1, T) + sparks.start() + update_icon() + else if (severity <= 90) //10% chance of breaking the gun + user.visible_message("\The [user] pulls the trigger, but \the [src] erupts in a shower of sparks!", "You pull the trigger, but \the [src] bursts into a shower of sparks!") + var/datum/effect/effect/system/spark_spread/sparks = PoolOrNew(/datum/effect/effect/system/spark_spread) + sparks.set_up(2, 1, T) + sparks.start() + power_supply.charge = 0 + power_supply.maxcharge = 1 //just to avoid div/0 runtimes + power_supply.desc += " It seems to be burnt out!" + desc += " The casing is covered in scorch-marks." + fire_delay += fire_delay // even if you swap out the cell for a good one, the gun's cluckety-clucked. + charge_cost += charge_cost + update_icon() + else if (severity <= 150) // 10% chance of exploding + user.visible_message("\The [user] pulls the trigger, but \the [src] explodes!", "The [src] explodes!") + log_and_message_admins("blew themself up with a particle gun.", user) + explosion(T, -1, -1, 1, 1) + qdel(src) + else //can only possibly happen if you're dumb enough to fire it in an OVER pressure environment, over 150kPa + user.visible_message("\The [user] pulls the trigger, but \the [src] explodes!", "The [src] explodes catastrophically!") + log_and_message_admins("blew their dumb ass up with a particle gun.", user) + explosion(T, -1, 1, 2, 2) + qdel(src) + +/obj/item/weapon/gun/energy/particle/cannon/pressuremalfunction(severity, user, T) + ..(severity*2, user, T) + + +/obj/item/weapon/gun/energy/particle/attackby(var/obj/item/A as obj, mob/user as mob) + if(istype(A, /obj/item/pressurelock)) + if(safetycatch) + user << "\The [src] already has a [attached_safety]." + return + user << "You insert \the [A] into \the [src]." + user.drop_item() + A.loc = src + attached_safety = A + safetycatch = 1 + return + + if(istype(A, /obj/item/weapon/screwdriver)) + if(safetycatch && attached_safety) + user << "You begin removing \the [attached_safety] from \the [src]." + if(do_after(user, 25)) + user << "You remove \the [attached_safety] from \the [src]." + user.put_in_hands(attached_safety) + safetycatch = 0 + attached_safety = null + return + ..() + + +// accessory + +/obj/item/pressurelock + name = "Pressure interlock" + icon = 'icons/obj/gun_vr.dmi' + icon_state = "pressurelock" + desc = "A safety interlock that can be installed in an antiparticle projector. It prevents the weapon from discharging in pressurised environments." + w_class = ITEMSIZE_TINY + // projectiles below /obj/item/projectile/bullet/particle - name = "particle" + name = "antimatter pellet" icon = 'icons/obj/projectiles_vr.dmi' icon_state = "particle" damage = 40 damage_type = BURN check_armour = "energy" embed_chance = 0 + +/obj/item/projectile/bullet/particle/heavy + name = "antimatter slug" + icon_state = "particle-heavy" + damage = 80 // same as a laser cannon + armor_penetration = 25 //it explodes on the surface of things, so less armor pen than the laser cannon + light_range = 3 + light_power = 1 + light_color = "#CCFFFF" + +/turf/simulated/mineral/bullet_act(var/obj/item/projectile/Proj) + if(istype(Proj, /obj/item/projectile/bullet/particle)) + if(prob(Proj.damage)) + GetDrilled() + diff --git a/icons/obj/gun_vr.dmi b/icons/obj/gun_vr.dmi index 48dbdeb4af..a7acc2cad8 100644 Binary files a/icons/obj/gun_vr.dmi and b/icons/obj/gun_vr.dmi differ diff --git a/icons/obj/projectiles_vr.dmi b/icons/obj/projectiles_vr.dmi index e34d3c0c21..0fa44fbec3 100644 Binary files a/icons/obj/projectiles_vr.dmi and b/icons/obj/projectiles_vr.dmi differ