diff --git a/code/game/gamemodes/changeling/powers/mutations.dm b/code/game/gamemodes/changeling/powers/mutations.dm index f0569db3909..792665a52f3 100644 --- a/code/game/gamemodes/changeling/powers/mutations.dm +++ b/code/game/gamemodes/changeling/powers/mutations.dm @@ -243,7 +243,6 @@ damage_type = BRUTE range = 8 hitsound = 'sound/weapons/thudswoosh.ogg' - var/chain var/obj/item/ammo_casing/magic/tentacle/source //the item that shot it /obj/item/projectile/tentacle/New(obj/item/ammo_casing/magic/tentacle/tentacle_casing) diff --git a/code/game/machinery/portable_turret.dm b/code/game/machinery/portable_turret.dm index a9be1649ff1..1ca2c21fd90 100644 --- a/code/game/machinery/portable_turret.dm +++ b/code/game/machinery/portable_turret.dm @@ -844,6 +844,9 @@ GLOBAL_LIST_EMPTY(turret_icons) if(!user.unEquip(I)) to_chat(user, "\the [I] is stuck to your hand, you cannot put it in \the [src]") return + if(!E.can_fit_in_turrets) + to_chat(user, "[I] will not operate correctly in [src].") + return installation = I.type //installation becomes I.type gun_charge = E.cell.charge //the gun's charge is stored in gun_charge to_chat(user, "You add [I] to the turret.") diff --git a/code/game/objects/effects/temporary_visuals/miscellaneous.dm b/code/game/objects/effects/temporary_visuals/miscellaneous.dm index 298c6686df2..c6de27524c2 100644 --- a/code/game/objects/effects/temporary_visuals/miscellaneous.dm +++ b/code/game/objects/effects/temporary_visuals/miscellaneous.dm @@ -354,3 +354,12 @@ /obj/effect/temp_visual/impact_effect/ion icon_state = "shieldsparkles" duration = 6 + +/obj/effect/temp_visual/bsg_kaboom + name = "bluespace explosion" + icon = 'icons/effects/96x96.dmi' + icon_state = "explosionfast" + color = "blue" + pixel_x = -32 + pixel_y = -32 + duration = 42 diff --git a/code/modules/mining/lavaland/loot/tendril_loot.dm b/code/modules/mining/lavaland/loot/tendril_loot.dm index 2c05393b5a8..642745d78c2 100644 --- a/code/modules/mining/lavaland/loot/tendril_loot.dm +++ b/code/modules/mining/lavaland/loot/tendril_loot.dm @@ -381,7 +381,6 @@ damage_type = BRUTE hitsound = 'sound/effects/splat.ogg' weaken = 3 - var/chain /obj/item/projectile/hook/fire(setAngle) if(firer) diff --git a/code/modules/power/cell.dm b/code/modules/power/cell.dm index ec1184d7837..38575891d07 100644 --- a/code/modules/power/cell.dm +++ b/code/modules/power/cell.dm @@ -354,3 +354,9 @@ desc = "A standard ninja-suit power cell." maxcharge = 10000 materials = list(MAT_GLASS = 60) + +/obj/item/stock_parts/cell/bsg + name = "\improper B.S.G power cell" + desc = "A high capacity, slow charging cell for the B.S.G." + maxcharge = 40000 + chargerate = 2600 // about 30 seconds to charge with a default recharger diff --git a/code/modules/projectiles/ammunition/energy.dm b/code/modules/projectiles/ammunition/energy.dm index 41e2aa0ed2d..18ed273ff23 100644 --- a/code/modules/projectiles/ammunition/energy.dm +++ b/code/modules/projectiles/ammunition/energy.dm @@ -271,6 +271,16 @@ delay = 50 select_name = "snipe" +/obj/item/ammo_casing/energy/bsg + projectile_type = /obj/item/projectile/energy/bsg + muzzle_flash_color = LIGHT_COLOR_DARKBLUE + muzzle_flash_range = MUZZLE_FLASH_RANGE_STRONG + muzzle_flash_strength = MUZZLE_FLASH_STRENGTH_STRONG + fire_sound = 'sound/weapons/wave.ogg' + e_cost = 10000 + select_name = "the experimental setting" + delay = 10 SECONDS //Looooooong cooldown + /obj/item/ammo_casing/energy/teleport projectile_type = /obj/item/projectile/energy/teleport muzzle_flash_color = LIGHT_COLOR_LIGHTBLUE diff --git a/code/modules/projectiles/guns/energy.dm b/code/modules/projectiles/guns/energy.dm index 69eccb2d7a5..6f38c7e2f01 100644 --- a/code/modules/projectiles/guns/energy.dm +++ b/code/modules/projectiles/guns/energy.dm @@ -17,6 +17,8 @@ var/selfcharge = 0 var/charge_tick = 0 var/charge_delay = 4 + /// Do you want the gun to fit into a turret, defaults to true, used for if a energy gun is too strong to be in a turret, or does not make sense to be in one. + var/can_fit_in_turrets = TRUE /obj/item/gun/energy/emp_act(severity) cell.use(round(cell.charge / severity)) diff --git a/code/modules/projectiles/guns/energy/special.dm b/code/modules/projectiles/guns/energy/special.dm index 8d9f50cedd7..09458fd8ba7 100644 --- a/code/modules/projectiles/guns/energy/special.dm +++ b/code/modules/projectiles/guns/energy/special.dm @@ -317,6 +317,121 @@ zoom_amt = 7 //Long range, enough to see in front of you, but no tiles behind you. shaded_charge = 1 +/obj/item/gun/energy/bsg + name = "\improper B.S.G" + desc = "The Blue Space Gun. Uses a flux anomaly core and a bluespace crystal to produce destructive bluespace energy blasts, inspired by Nanotrasen's BSA division." + icon_state = "bsg" + item_state = "bsg" + origin_tech = "combat=6;materials=6;powerstorage=6;bluespace=6;magnets=6" //cutting edge technology, be my guest if you want to deconstruct one instead of use it. + ammo_type = list(/obj/item/ammo_casing/energy/bsg) + weapon_weight = WEAPON_HEAVY + w_class = WEIGHT_CLASS_HUGE + can_holster = FALSE + slot_flags = SLOT_BACK + cell_type = /obj/item/stock_parts/cell/bsg + shaded_charge = TRUE + can_fit_in_turrets = FALSE //Crystal would shatter, or someone would try to put an empty gun in the frame. + var/obj/item/assembly/signaler/anomaly/flux/core = null + var/has_bluespace_crystal = FALSE + var/admin_model = FALSE //For the admin gun, prevents crystal shattering, so anyone can use it, and you dont need to carry backup crystals. + +/obj/item/gun/energy/bsg/Destroy() + QDEL_NULL(core) + return ..() + +/obj/item/gun/energy/bsg/examine(mob/user) + . = ..() + if(core && has_bluespace_crystal) + . += "[src] is fully operational!" + else if(core) + . += "It has a flux anomaly core installed, but no bluespace crystal installed." + else if(has_bluespace_crystal) + . += "It has a bluespace crystal installed, but no flux anomaly core installed." + else + . += "It is missing a flux anomaly core and bluespace crystal to be operational." + +/obj/item/gun/energy/bsg/attackby(obj/item/O, mob/user, params) + if(istype(O, /obj/item/stack/ore/bluespace_crystal)) + if(has_bluespace_crystal) + to_chat(user, "[src] already has a bluespace crystal installed.") + return + var/obj/item/stack/S = O + if(!loc || !S || S.get_amount() < 1) + return + to_chat(user, "You load [O] into [src].") + S.use(1) + has_bluespace_crystal = TRUE + update_icon() + return + + if(istype(O, /obj/item/assembly/signaler/anomaly/flux)) + if(core) + to_chat(user, "[src] already has a [O]!") + return + if(!user.drop_item()) + to_chat(user, "[O] is stuck to your hand!") + return + to_chat(user, "You insert [O] into [src], and [src] starts to warm up.") + O.forceMove(src) + core = O + update_icon() + else + return ..() + +/obj/item/gun/energy/bsg/process_fire(atom/target, mob/living/user, message = TRUE, params, zone_override, bonus_spread = 0) + if(!has_bluespace_crystal) + to_chat(user, "[src] has no bluespace crystal to power it!") + return + if(!core) + to_chat(user, "[src] has no flux anomaly core to power it!") + return + return ..() + +/obj/item/gun/energy/bsg/process_chamber() + if(prob(25)) + shatter() + ..() + update_icon() + +/obj/item/gun/energy/bsg/update_icon() + . = ..() + if(core) + if(has_bluespace_crystal) + icon_state = "bsg_finished" + else + icon_state = "bsg_core" + else if(has_bluespace_crystal) + icon_state = "bsg_crystal" + else + icon_state = "bsg" + +/obj/item/gun/energy/bsg/emp_act(severity) + ..() + if(prob(75 / severity)) + if(has_bluespace_crystal) + shatter() + +/obj/item/gun/energy/bsg/proc/shatter() + if(admin_model) + return + visible_message("[src]'s bluespace crystal shatters!") + playsound(src, 'sound/effects/pylon_shatter.ogg', 50, TRUE) + has_bluespace_crystal = FALSE + update_icon() + +/obj/item/gun/energy/bsg/prebuilt + icon_state = "bsg_finished" + has_bluespace_crystal = TRUE + +/obj/item/gun/energy/bsg/prebuilt/Initialize(mapload) + . = ..() + core = new /obj/item/assembly/signaler/anomaly/flux + update_icon() + +/obj/item/gun/energy/bsg/prebuilt/admin + desc = "The Blue Space Gun. Uses a flux anomaly core and a bluespace crystal to produce destructive bluespace energy blasts, inspired by Nanotrasen's BSA division. This is an executive model, and its bluespace crystal will not shatter." + admin_model = TRUE + // Temperature Gun // /obj/item/gun/energy/temperature name = "temperature gun" diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index 64b0241279f..d341330fb16 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -60,6 +60,9 @@ var/log_override = FALSE //whether print to admin attack logs or just keep it in the diary + /// For when you want your projectile to have a chain coming out of the gun + var/chain = null + /obj/item/projectile/New() permutated = list() return ..() diff --git a/code/modules/projectiles/projectile/energy.dm b/code/modules/projectiles/projectile/energy.dm index 35e3d325c4e..dc6f3fdf2da 100644 --- a/code/modules/projectiles/projectile/energy.dm +++ b/code/modules/projectiles/projectile/energy.dm @@ -80,7 +80,6 @@ var/zap_flags = ZAP_MOB_DAMAGE | ZAP_OBJ_DAMAGE var/zap_range = 3 var/power = 10000 - var/chain /obj/item/ammo_casing/energy/shock_revolver/ready_proj(atom/target, mob/living/user, quiet, zone_override = "") ..() @@ -93,6 +92,62 @@ tesla_zap(src, zap_range, power, zap_flags) qdel(src) +/obj/item/projectile/energy/bsg + name = "orb of pure bluespace energy" + icon_state = "bluespace" + impact_effect_type = /obj/effect/temp_visual/bsg_kaboom + damage = 60 + damage_type = BURN + range = 9 + weaken = 1 //This is going to knock you off your feet + eyeblur = 5 + speed = 2 + alwayslog = TRUE + +/obj/item/ammo_casing/energy/bsg/ready_proj(atom/target, mob/living/user, quiet, zone_override = "") + ..() + var/obj/item/projectile/energy/bsg/P = BB + addtimer(CALLBACK(P, /obj/item/projectile/energy/bsg/.proc/make_chain, P, user), 1) + +/obj/item/projectile/energy/bsg/proc/make_chain(obj/item/projectile/P, mob/user) + P.chain = P.Beam(user, icon_state = "sm_arc_supercharged", icon = 'icons/effects/beam.dmi', time = 10 SECONDS, maxdistance = 30) + +/obj/item/projectile/energy/bsg/on_hit(atom/target) + . = ..() + kaboom() + qdel(src) + +/obj/item/projectile/energy/bsg/on_range() + kaboom() + new /obj/effect/temp_visual/bsg_kaboom(loc) + ..() + +/obj/item/projectile/energy/bsg/proc/kaboom() + playsound(src, 'sound/weapons/bsg_explode.ogg', 75, TRUE) + for(var/mob/living/M in hearers(7, src)) //No stuning people with thermals through a wall. + var/floored = FALSE + if(ishuman(M)) + var/mob/living/carbon/human/H = M + var/obj/item/gun/energy/bsg/N = locate() in H + if(N) + to_chat(H, "[N] deploys an energy shield to project you from [src]'s explosion.") + continue + var/distance = (1 + get_dist(M, src)) + if(prob(min(400 / distance, 100))) //100% chance to hit with the blast up to 3 tiles, after that chance to hit is 80% at 4 tiles, 66.6% at 5, 57% at 6, and 50% at 7 + if(prob(min(150 / distance, 100)))//100% chance to upgraded to a stun as well at a direct hit, 75% at 1 tile, 50% at 2, 37.5% at 3, 30% at 4, 25% at 5, 21% at 6, and finaly 19% at 7. This is calculated after the first hit however. + floored = TRUE + M.apply_damage((rand(15, 30) * (1.1 - distance / 10)), BURN) //reduced by 10% per tile + add_attack_logs(src, M, "Hit heavily by [src]") + if(floored) + to_chat(M, "You see a flash of briliant blue light as [src] explodes, knocking you to the ground and burning you!") + M.Weaken(1) + else + to_chat(M, "You see a flash of briliant blue light as [src] explodes, burning you!") + else + to_chat(M, "You feel the heat of the explosion of [src], but the blast mostly misses you.") + add_attack_logs(src, M, "Hit lightly by [src]") + M.apply_damage(rand(1, 5), BURN) + /obj/item/projectile/energy/toxplasma name = "plasma bolt" icon_state = "energy" diff --git a/icons/mob/back.dmi b/icons/mob/back.dmi index ec7e6827b19..6fffc9e1f57 100644 Binary files a/icons/mob/back.dmi and b/icons/mob/back.dmi differ diff --git a/icons/mob/inhands/guns_lefthand.dmi b/icons/mob/inhands/guns_lefthand.dmi index d69dd8a988b..f05497b5643 100644 Binary files a/icons/mob/inhands/guns_lefthand.dmi and b/icons/mob/inhands/guns_lefthand.dmi differ diff --git a/icons/mob/inhands/guns_righthand.dmi b/icons/mob/inhands/guns_righthand.dmi index 44968461e65..2c541898b08 100644 Binary files a/icons/mob/inhands/guns_righthand.dmi and b/icons/mob/inhands/guns_righthand.dmi differ diff --git a/icons/obj/guns/energy.dmi b/icons/obj/guns/energy.dmi index 812b0bfba23..b4f2c2204ab 100644 Binary files a/icons/obj/guns/energy.dmi and b/icons/obj/guns/energy.dmi differ diff --git a/sound/weapons/bsg_explode.ogg b/sound/weapons/bsg_explode.ogg new file mode 100644 index 00000000000..ac3ff327727 Binary files /dev/null and b/sound/weapons/bsg_explode.ogg differ