diff --git a/baystation12.dme b/baystation12.dme index b1e334041d..6229a35ff1 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -872,7 +872,6 @@ #include "code\modules\clothing\spacesuits\rig\modules\computer.dm" #include "code\modules\clothing\spacesuits\rig\modules\modules.dm" #include "code\modules\clothing\spacesuits\rig\modules\ninja.dm" -#include "code\modules\clothing\spacesuits\rig\modules\rig_weapons.dm" #include "code\modules\clothing\spacesuits\rig\modules\utility.dm" #include "code\modules\clothing\spacesuits\rig\modules\vision.dm" #include "code\modules\clothing\spacesuits\rig\suits\alien.dm" @@ -1329,6 +1328,7 @@ #include "code\modules\projectiles\ammunition\bullets.dm" #include "code\modules\projectiles\guns\alien.dm" #include "code\modules\projectiles\guns\energy.dm" +#include "code\modules\projectiles\guns\launcher.dm" #include "code\modules\projectiles\guns\projectile.dm" #include "code\modules\projectiles\guns\energy\laser.dm" #include "code\modules\projectiles\guns\energy\nuclear.dm" @@ -1336,14 +1336,17 @@ #include "code\modules\projectiles\guns\energy\special.dm" #include "code\modules\projectiles\guns\energy\stun.dm" #include "code\modules\projectiles\guns\energy\temperature.dm" +#include "code\modules\projectiles\guns\launcher\crossbow.dm" +#include "code\modules\projectiles\guns\launcher\grenade_launcher.dm" +#include "code\modules\projectiles\guns\launcher\pneumatic.dm" +#include "code\modules\projectiles\guns\launcher\rocket.dm" +#include "code\modules\projectiles\guns\launcher\syringe_gun.dm" #include "code\modules\projectiles\guns\projectile\automatic.dm" -#include "code\modules\projectiles\guns\projectile\crossbow.dm" -#include "code\modules\projectiles\guns\projectile\launcher.dm" +#include "code\modules\projectiles\guns\projectile\dartgun.dm" #include "code\modules\projectiles\guns\projectile\pistol.dm" -#include "code\modules\projectiles\guns\projectile\pneumatic.dm" #include "code\modules\projectiles\guns\projectile\revolver.dm" -#include "code\modules\projectiles\guns\projectile\rocket.dm" #include "code\modules\projectiles\guns\projectile\shotgun.dm" +#include "code\modules\projectiles\guns\projectile\sniper.dm" #include "code\modules\projectiles\projectile\animate.dm" #include "code\modules\projectiles\projectile\beams.dm" #include "code\modules\projectiles\projectile\bullets.dm" @@ -1360,11 +1363,8 @@ #include "code\modules\reagents\Chemistry-Reagents-Antidepressants.dm" #include "code\modules\reagents\Chemistry-Reagents.dm" #include "code\modules\reagents\Chemistry-Recipes.dm" -#include "code\modules\reagents\dartgun.dm" -#include "code\modules\reagents\grenade_launcher.dm" #include "code\modules\reagents\reagent_containers.dm" #include "code\modules\reagents\reagent_dispenser.dm" -#include "code\modules\reagents\syringe_gun.dm" #include "code\modules\reagents\reagent_containers\blood_pack.dm" #include "code\modules\reagents\reagent_containers\borghydro.dm" #include "code\modules\reagents\reagent_containers\dropper.dm" diff --git a/baystation12.int b/baystation12.int index b82874fded..1939a7e9ec 100644 --- a/baystation12.int +++ b/baystation12.int @@ -1,6 +1,11 @@ // BEGIN_INTERNALS /* MAP_ICON_TYPE: 0 +WINDOW: code\ATMOSPHERICS\components\binary_devices\pump.dm;code\ATMOSPHERICS\components\binary_devices\circulator.dm;code\modules\power\generator.dm;code\ATMOSPHERICS\components\unary\heat_exchanger.dm;code\ATMOSPHERICS\components\unary\vent_pump.dm;maps\exodus-1.dmm +LAST_COMPILE_VERSION: 501.1217 +DIR: code code\ATMOSPHERICS code\ATMOSPHERICS\components code\ATMOSPHERICS\components\binary_devices code\ATMOSPHERICS\components\unary code\game code\game\machinery\doors code\game\objects code\game\objects\items code\game\objects\items\weapons code\modules code\modules\power maps +FILE: maps\exodus-1.dmm +LAST_COMPILE_TIME: 1424008581 AUTO_FILE_DIR: OFF */ // END_INTERNALS diff --git a/code/ATMOSPHERICS/components/binary_devices/circulator.dm b/code/ATMOSPHERICS/components/binary_devices/circulator.dm index cb9ecfbdc5..a4b720302b 100644 --- a/code/ATMOSPHERICS/components/binary_devices/circulator.dm +++ b/code/ATMOSPHERICS/components/binary_devices/circulator.dm @@ -1,37 +1,50 @@ //node1, air1, network1 correspond to input //node2, air2, network2 correspond to output +#define ADIABATIC_EXPONENT 0.667 //Actually adiabatic exponent - 1. + /obj/machinery/atmospherics/binary/circulator - name = "circulator/heat exchanger" - desc = "A gas circulator pump and heat exchanger." + name = "circulator" + desc = "A gas circulator turbine and heat exchanger." icon = 'icons/obj/pipes.dmi' icon_state = "circ-off" anchored = 0 + var/kinetic_efficiency = 0.04 //combined kinetic and kinetic-to-electric efficiency + var/volume_ratio = 0.2 + var/recent_moles_transferred = 0 var/last_heat_capacity = 0 var/last_temperature = 0 var/last_pressure_delta = 0 var/last_worldtime_transfer = 0 + var/last_stored_energy_transferred = 0 + var/volume_capacity_used = 0 + var/stored_energy = 0 density = 1 /obj/machinery/atmospherics/binary/circulator/New() ..() - desc = initial(desc) + " Its outlet port is to the [dir2text(dir)]." + desc = initial(desc) + " Its outlet port is to the [dir2text(dir)]." + air1.volume = 400 /obj/machinery/atmospherics/binary/circulator/proc/return_transfer_air() var/datum/gas_mixture/removed - if(anchored && !(stat&BROKEN) ) + if(anchored && !(stat&BROKEN) && network1) var/input_starting_pressure = air1.return_pressure() var/output_starting_pressure = air2.return_pressure() - last_pressure_delta = max(input_starting_pressure - output_starting_pressure + 10, 0) + last_pressure_delta = max(input_starting_pressure - output_starting_pressure - 5, 0) - //only circulate air if there is a pressure difference (plus 10 kPa to represent friction in the machine) - if(air1.temperature > 0 && last_pressure_delta > 0) + //only circulate air if there is a pressure difference (plus 5kPa kinetic, 10kPa static friction) + if(air1.temperature > 0 && last_pressure_delta > 5) //Calculate necessary moles to transfer using PV = nRT - recent_moles_transferred = last_pressure_delta*air2.volume/(air1.temperature * R_IDEAL_GAS_EQUATION) + recent_moles_transferred = (last_pressure_delta*network1.volume/(air1.temperature * R_IDEAL_GAS_EQUATION))/3 //uses the volume of the whole network, not just itself + volume_capacity_used = min( (last_pressure_delta*network1.volume/3)/(input_starting_pressure*air1.volume) , 1) //how much of the gas in the input air volume is consumed + + //Calculate energy generated from kinetic turbine + stored_energy += 1/ADIABATIC_EXPONENT * min(last_pressure_delta * network1.volume , input_starting_pressure*air1.volume) * (1 - volume_ratio**ADIABATIC_EXPONENT) * kinetic_efficiency //Actually transfer the gas removed = air1.remove(recent_moles_transferred) @@ -40,8 +53,7 @@ last_temperature = removed.temperature //Update the gas networks. - if(network1) - network1.update = 1 + network1.update = 1 last_worldtime_transfer = world.time else @@ -50,6 +62,11 @@ update_icon() return removed +/obj/machinery/atmospherics/binary/circulator/proc/return_stored_energy() + last_stored_energy_transferred = stored_energy + stored_energy = 0 + return last_stored_energy_transferred + /obj/machinery/atmospherics/binary/circulator/process() ..() @@ -72,8 +89,11 @@ /obj/machinery/atmospherics/binary/circulator/attackby(obj/item/weapon/W as obj, mob/user as mob) if(istype(W, /obj/item/weapon/wrench)) + playsound(src.loc, 'sound/items/Ratchet.ogg', 75, 1) anchored = !anchored - user << "\blue You [anchored ? "secure" : "unsecure"] the bolts holding [src] to the floor." + user.visible_message("[user.name] [anchored ? "secures" : "unsecures"] the bolts holding [src.name] to the floor.", \ + "You [anchored ? "secure" : "unsecure"] the bolts holding [src] to the floor.", \ + "You hear a ratchet") if(anchored) if(dir & (NORTH|SOUTH)) diff --git a/code/ATMOSPHERICS/components/unary/vent_pump.dm b/code/ATMOSPHERICS/components/unary/vent_pump.dm index ed7290b00f..4961d22e79 100644 --- a/code/ATMOSPHERICS/components/unary/vent_pump.dm +++ b/code/ATMOSPHERICS/components/unary/vent_pump.dm @@ -89,7 +89,7 @@ /obj/machinery/atmospherics/unary/vent_pump/engine name = "Engine Core Vent" power_channel = ENVIRON - power_rating = 15000 //15 kW ~ 20 HP + power_rating = 30000 //15 kW ~ 20 HP /obj/machinery/atmospherics/unary/vent_pump/engine/New() ..() @@ -183,11 +183,11 @@ //JESUS FUCK. THERE ARE LITERALLY 250 OF YOU MOTHERFUCKERS ON ZLEVEL ONE AND YOU DO THIS SHIT EVERY TICK WHEN VERY OFTEN THERE IS NO REASON TO if(pump_direction && pressure_checks == PRESSURE_CHECK_EXTERNAL && controller_iteration > 10) //99% of all vents - //Fucking hibernate because you ain't doing shit. + //Fucking hibernate because you ain't doing shit. hibernate = 1 spawn(rand(100,200)) //hibernate for 10 or 20 seconds randomly - hibernate = 0 - + hibernate = 0 + if (power_draw >= 0) last_power_draw = power_draw diff --git a/code/__HELPERS/text.dm b/code/__HELPERS/text.dm index c14976bb78..27f5f98aa4 100644 --- a/code/__HELPERS/text.dm +++ b/code/__HELPERS/text.dm @@ -329,14 +329,25 @@ proc/TextPreview(var/string,var/len=40) //This means that it doesn't just remove < and > and call it a day. //Also limit the size of the input, if specified. /proc/strip_html_properly(var/input, var/max_length = MAX_MESSAGE_LEN) + if(!input) + return var/opentag = 1 //These store the position of < and > respectively. var/closetag = 1 while(1) opentag = findtext(input, "<") closetag = findtext(input, ">") - if(!closetag || !opentag) + if(closetag && opentag) + if(closetag < opentag) + input = copytext(input, (closetag + 1)) + else + input = copytext(input, 1, opentag) + copytext(input, (closetag + 1)) + else if(closetag || opentag) + if(opentag) + input = copytext(input, 1, opentag) + else + input = copytext(input, (closetag + 1)) + else break - input = copytext(input, 1, opentag) + copytext(input, (closetag + 1)) if(max_length) input = copytext(input,1,max_length) return sanitize(input) diff --git a/code/_onclick/hud/monkey.dm b/code/_onclick/hud/monkey.dm index 65924284b5..0081fbe6b5 100644 --- a/code/_onclick/hud/monkey.dm +++ b/code/_onclick/hud/monkey.dm @@ -226,7 +226,7 @@ if (mymob.client.gun_mode) // If in aim mode, correct the sprite mymob.gun_setting_icon.set_dir(2) for(var/obj/item/weapon/gun/G in mymob) // If targeting someone, display other buttons - if (G.target) + if (G.aim_targets) mymob.item_use_icon = new /obj/screen/gun/item(null) if (mymob.client.target_can_click) mymob.item_use_icon.set_dir(1) diff --git a/code/_onclick/hud/robot.dm b/code/_onclick/hud/robot.dm index 644b811376..2738cf3a7d 100644 --- a/code/_onclick/hud/robot.dm +++ b/code/_onclick/hud/robot.dm @@ -157,7 +157,7 @@ var/obj/screen/robot_inventory if (mymob.client.gun_mode) // If in aim mode, correct the sprite mymob.gun_setting_icon.set_dir(2) for(var/obj/item/weapon/gun/G in mymob) // If targeting someone, display other buttons - if (G.target) + if (G.aim_targets) mymob.item_use_icon = new /obj/screen/gun/item(null) if (mymob.client.target_can_click) mymob.item_use_icon.set_dir(1) diff --git a/code/defines/obj/weapon.dm b/code/defines/obj/weapon.dm index 03be981c12..e8a514e64f 100644 --- a/code/defines/obj/weapon.dm +++ b/code/defines/obj/weapon.dm @@ -56,7 +56,7 @@ icon_state = "bike_horn" item_state = "bike_horn" throwforce = 3 - w_class = 1.0 + w_class = 2 throw_speed = 3 throw_range = 15 attack_verb = list("HONKED") diff --git a/code/defines/procs/announce.dm b/code/defines/procs/announce.dm index b74f7a1c78..d3aef96c45 100644 --- a/code/defines/procs/announce.dm +++ b/code/defines/procs/announce.dm @@ -36,7 +36,7 @@ var/tmp/message_title = new_title ? new_title : title var/tmp/message_sound = new_sound ? sound(new_sound) : sound - message = html_encode(message) + message = trim_strip_html_properly(message) message_title = html_encode(message_title) Message(message, message_title) diff --git a/code/game/gamemodes/factions.dm b/code/game/gamemodes/factions.dm index 1aaa70e2a5..47c8586f6e 100644 --- a/code/game/gamemodes/factions.dm +++ b/code/game/gamemodes/factions.dm @@ -119,7 +119,7 @@ operative_notes = "We'd like to remind our operatives to keep it professional. You are not here to have a good time, you are here to accomplish your objectives. These vile communists must be stopped at all costs. You may collaborate with any friends of the Syndicate coalition, but keep an eye on any of those Tiger punks if they do show up. You are completely free to accomplish your objectives any way you see fit." uplink_contents = {"Highly Visible and Dangerous Weapons; -/obj/item/weapon/gun/projectile:6:Revolver; +/obj/item/weapon/gun/projectile/revolver:6:Revolver; /obj/item/ammo_magazine/a357:2:Ammo-357; /obj/item/weapon/gun/energy/crossbow:5:Energy Crossbow; /obj/item/weapon/melee/energy/sword:4:Energy Sword; diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm index 3f0f8cdd64..8ad2d72288 100644 --- a/code/game/gamemodes/game_mode.dm +++ b/code/game/gamemodes/game_mode.dm @@ -40,7 +40,7 @@ new/datum/uplink_item(/obj/item/weapon/gun/energy/crossbow, 5, "Energy Crossbow", "XB"), new/datum/uplink_item(/obj/item/weapon/storage/box/syndie_kit/g9mm, 5, "Silenced 9mm", "S9"), new/datum/uplink_item(/obj/item/mecha_parts/mecha_equipment/weapon/energy/riggedlaser, 6, "Exosuit Rigged Laser", "RL"), - new/datum/uplink_item(/obj/item/weapon/gun/projectile, 6, "Revolver", "RE"), + new/datum/uplink_item(/obj/item/weapon/gun/projectile/revolver, 6, "Revolver", "RE"), new/datum/uplink_item(/obj/item/weapon/storage/box/syndicate, 10, "Mercenary Bundle", "BU") ), "Stealthy and Inconspicuous Weapons" = list( diff --git a/code/game/gamemodes/wizard/rightandwrong.dm b/code/game/gamemodes/wizard/rightandwrong.dm index ccce7f9bff..1e16da590b 100644 --- a/code/game/gamemodes/wizard/rightandwrong.dm +++ b/code/game/gamemodes/wizard/rightandwrong.dm @@ -26,7 +26,7 @@ if("revolver") new /obj/item/weapon/gun/projectile(get_turf(H)) if("detective") - new /obj/item/weapon/gun/projectile/detective(get_turf(H)) + new /obj/item/weapon/gun/projectile/revolver/detective(get_turf(H)) if("smg") new /obj/item/weapon/gun/projectile/automatic/c20r(get_turf(H)) if("nuclear") @@ -49,7 +49,7 @@ if("combatshotgun") new /obj/item/weapon/gun/projectile/shotgun/pump/combat(get_turf(H)) if("mateba") - new /obj/item/weapon/gun/projectile/mateba(get_turf(H)) + new /obj/item/weapon/gun/projectile/revolver/mateba(get_turf(H)) if("smg") new /obj/item/weapon/gun/projectile/automatic(get_turf(H)) if("uzi") diff --git a/code/game/machinery/autolathe_datums.dm b/code/game/machinery/autolathe_datums.dm index f13c3dc634..38989d2905 100644 --- a/code/game/machinery/autolathe_datums.dm +++ b/code/game/machinery/autolathe_datums.dm @@ -201,6 +201,11 @@ path = /obj/item/weapon/reagent_containers/syringe category = "Medical" +/datum/autolathe/recipe/syringegun_ammo + name = "syringe" + path = /obj/item/weapon/syringe_cartridge + category = "Arms and Ammunition" + /datum/autolathe/recipe/shotgun_blanks name = "ammunition (shotgun, blank)" path = /obj/item/ammo_casing/shotgun/blank @@ -217,13 +222,13 @@ category = "Arms and Ammunition" /datum/autolathe/recipe/magazine_rubber - name = "ammunition (rubber)" - path = /obj/item/ammo_magazine/c45r + name = "ammunition (.45, rubber)" + path = /obj/item/ammo_magazine/c45m/rubber category = "Arms and Ammunition" /datum/autolathe/recipe/magazine_flash - name = "ammunition (flash)" - path = /obj/item/ammo_magazine/c45f + name = "ammunition (.45, flash)" + path = /obj/item/ammo_magazine/c45m/flash category = "Arms and Ammunition" /datum/autolathe/recipe/consolescreen @@ -294,6 +299,24 @@ hidden = 1 category = "Arms and Ammunition" +/datum/autolathe/recipe/magazine_stetchkin + name = "ammunition (9mm)" + path = /obj/item/ammo_magazine/mc9mm + hidden = 1 + category = "Arms and Ammunition" + +/datum/autolathe/recipe/magazine_stetchkin_flash + name = "ammunition (9mm, flash)" + path = /obj/item/ammo_magazine/mc9mm/flash + hidden = 1 + category = "Arms and Ammunition" + +/datum/autolathe/recipe/magazine_c20r + name = "ammunition (12mm)" + path = /obj/item/ammo_magazine/a12mm + hidden = 1 + category = "Arms and Ammunition" + /datum/autolathe/recipe/shotgun name = "ammunition (slug, shotgun)" path = /obj/item/ammo_casing/shotgun @@ -306,6 +329,12 @@ hidden = 1 category = "Arms and Ammunition" +/datum/autolathe/recipe/stunshell + name = "ammunition (stun cartridge, shotgun)" + path = /obj/item/ammo_casing/shotgun/stunshell + hidden = 1 + category = "Arms and Ammunition" + /datum/autolathe/recipe/rcd name = "rapid construction device" path = /obj/item/weapon/rcd diff --git a/code/game/machinery/bots/ed209bot.dm b/code/game/machinery/bots/ed209bot.dm index 24e29e2839..639da55bf5 100644 --- a/code/game/machinery/bots/ed209bot.dm +++ b/code/game/machinery/bots/ed209bot.dm @@ -34,10 +34,10 @@ var/obj/item/weapon/gun/energy/taser/G = new /obj/item/weapon/gun/energy/taser(Tsec) G.power_supply.charge = 0 else if(lasercolor == "b") - var/obj/item/weapon/gun/energy/laser/bluetag/G = new /obj/item/weapon/gun/energy/laser/bluetag(Tsec) + var/obj/item/weapon/gun/energy/lasertag/blue/G = new (Tsec) G.power_supply.charge = 0 else if(lasercolor == "r") - var/obj/item/weapon/gun/energy/laser/redtag/G = new /obj/item/weapon/gun/energy/laser/redtag(Tsec) + var/obj/item/weapon/gun/energy/lasertag/red/G = new (Tsec) G.power_supply.charge = 0 if (prob(50)) new /obj/item/robot_parts/l_leg(Tsec) @@ -137,11 +137,11 @@ if(7) switch(lasercolor) if("b") - if( !istype(W, /obj/item/weapon/gun/energy/laser/bluetag) ) + if( !istype(W, /obj/item/weapon/gun/energy/lasertag/blue) ) return name = "bluetag ED-209 assembly" if("r") - if( !istype(W, /obj/item/weapon/gun/energy/laser/redtag) ) + if( !istype(W, /obj/item/weapon/gun/energy/lasertag/red) ) return name = "redtag ED-209 assembly" if("") diff --git a/code/game/machinery/bots/medbot.dm b/code/game/machinery/bots/medbot.dm index 65a40289d0..a83f59d03f 100644 --- a/code/game/machinery/bots/medbot.dm +++ b/code/game/machinery/bots/medbot.dm @@ -455,7 +455,7 @@ return /obj/machinery/bot/medbot/bullet_act(var/obj/item/projectile/Proj) - if(Proj.flag == "taser") + if(Proj.taser_effect) src.stunned = min(stunned+10,20) ..() diff --git a/code/game/machinery/bots/secbot.dm b/code/game/machinery/bots/secbot.dm index 1dcc02fbb9..6aa43c1b39 100644 --- a/code/game/machinery/bots/secbot.dm +++ b/code/game/machinery/bots/secbot.dm @@ -702,10 +702,10 @@ Auto Patrol: []"}, switch(lasercolor) if("b") target_suit = /obj/item/clothing/suit/redtag - target_weapon = /obj/item/weapon/gun/energy/laser/redtag + target_weapon = /obj/item/weapon/gun/energy/lasertag/red if("r") target_suit = /obj/item/clothing/suit/bluetag - target_weapon = /obj/item/weapon/gun/energy/laser/bluetag + target_weapon = /obj/item/weapon/gun/energy/lasertag/blue if((istype(perp.r_hand, target_weapon)) || (istype(perp.l_hand, target_weapon))) threat += 4 diff --git a/code/game/machinery/computer/communications.dm b/code/game/machinery/computer/communications.dm index f18d906383..a8403bbede 100644 --- a/code/game/machinery/computer/communications.dm +++ b/code/game/machinery/computer/communications.dm @@ -110,7 +110,7 @@ if(message_cooldown) usr << "Please allow at least one minute to pass between announcements" return - var/input = stripped_input(usr, "Please write a message to announce to the station crew.", "Priority Announcement") + var/input = input(usr, "Please write a message to announce to the station crew.", "Priority Announcement") if(!input || !(usr in view(1,src))) return crew_announcement.Announce(input) diff --git a/code/game/machinery/computer3/computers/communications.dm b/code/game/machinery/computer3/computers/communications.dm index bb268ba0c0..527a2e2c5a 100644 --- a/code/game/machinery/computer3/computers/communications.dm +++ b/code/game/machinery/computer3/computers/communications.dm @@ -115,7 +115,7 @@ if(message_cooldown) usr << "Please allow at least one minute to pass between announcements" return - var/input = stripped_input(usr, "Please write a message to announce to the station crew.", "Priority Announcement") + var/input = input(usr, "Please write a message to announce to the station crew.", "Priority Announcement") if(!input || !interactable()) return crew_announcement.Announce(input) diff --git a/code/game/machinery/portable_tag_turret.dm b/code/game/machinery/portable_tag_turret.dm index 13f7032aa3..c9c2331e6d 100644 --- a/code/game/machinery/portable_tag_turret.dm +++ b/code/game/machinery/portable_tag_turret.dm @@ -5,13 +5,13 @@ /obj/machinery/porta_turret/tag // Reasonable defaults, in case someone manually spawns us var/lasercolor = "r" //Something to do with lasertag turrets, blame Sieve for not adding a comment. - installation = /obj/item/weapon/gun/energy/laser/redtag + installation = /obj/item/weapon/gun/energy/lasertag/red /obj/machinery/porta_turret/tag/red /obj/machinery/porta_turret/tag/blue lasercolor = "b" - installation = /obj/item/weapon/gun/energy/laser/bluetag + installation = /obj/item/weapon/gun/energy/lasertag/blue /obj/machinery/porta_turret/tag/New() ..() @@ -19,8 +19,8 @@ /obj/machinery/porta_turret/tag/weapon_setup(var/obj/item/weapon/gun/energy/E) switch(E.type) - if(/obj/item/weapon/gun/energy/laser/bluetag) - eprojectile = /obj/item/weapon/gun/energy/laser/bluetag + if(/obj/item/weapon/gun/energy/lasertag/blue) + eprojectile = /obj/item/weapon/gun/energy/lasertag/blue lasercolor = "b" req_access = list(access_maint_tunnels, access_theatre) check_arrest = 0 @@ -30,8 +30,8 @@ check_anomalies = 0 shot_delay = 30 - if(/obj/item/weapon/gun/energy/laser/redtag) - eprojectile = /obj/item/weapon/gun/energy/laser/redtag + if(/obj/item/weapon/gun/energy/lasertag/red) + eprojectile = /obj/item/weapon/gun/energy/lasertag/red lasercolor = "r" req_access = list(access_maint_tunnels, access_theatre) check_arrest = 0 @@ -86,13 +86,13 @@ ..() if(lasercolor == "b" && disabled == 0) - if(istype(Proj, /obj/item/weapon/gun/energy/laser/redtag)) + if(istype(Proj, /obj/item/weapon/gun/energy/lasertag/red)) disabled = 1 del(Proj) // qdel sleep(100) disabled = 0 if(lasercolor == "r" && disabled == 0) - if(istype(Proj, /obj/item/weapon/gun/energy/laser/bluetag)) + if(istype(Proj, /obj/item/weapon/gun/energy/lasertag/blue)) disabled = 1 del(Proj) // qdel sleep(100) @@ -110,10 +110,10 @@ switch(lasercolor) if("b") target_suit = /obj/item/clothing/suit/redtag - target_weapon = /obj/item/weapon/gun/energy/laser/redtag + target_weapon = /obj/item/weapon/gun/energy/lasertag/red if("r") target_suit = /obj/item/clothing/suit/bluetag - target_weapon = /obj/item/weapon/gun/energy/laser/bluetag + target_weapon = /obj/item/weapon/gun/energy/lasertag/blue if(target_suit)//Lasertag turrets target the opposing team, how great is that? -Sieve diff --git a/code/game/machinery/portable_turret.dm b/code/game/machinery/portable_turret.dm index c531e53f96..a2dda1e400 100644 --- a/code/game/machinery/portable_turret.dm +++ b/code/game/machinery/portable_turret.dm @@ -733,7 +733,7 @@ gun_charge = E.power_supply.charge //the gun's charge is stored in gun_charge user << "You add [I] to the turret." - if(istype(installation, /obj/item/weapon/gun/energy/laser/bluetag) || istype(installation, /obj/item/weapon/gun/energy/laser/redtag)) + if(istype(installation, /obj/item/weapon/gun/energy/lasertag/blue) || istype(installation, /obj/item/weapon/gun/energy/lasertag/red)) target_type = /obj/machinery/porta_turret/tag else target_type = /obj/machinery/porta_turret diff --git a/code/game/mecha/combat/marauder.dm b/code/game/mecha/combat/marauder.dm index cdb3645c62..d7e64c1ece 100644 --- a/code/game/mecha/combat/marauder.dm +++ b/code/game/mecha/combat/marauder.dm @@ -151,6 +151,7 @@ smoke_ready = 1 return +//TODO replace this with zoom code that doesn't increase peripherial vision /obj/mecha/combat/marauder/verb/zoom() set category = "Exosuit Interface" set name = "Zoom" diff --git a/code/game/mecha/equipment/tools/tools.dm b/code/game/mecha/equipment/tools/tools.dm index 5b71a34ec6..8338e2caa7 100644 --- a/code/game/mecha/equipment/tools/tools.dm +++ b/code/game/mecha/equipment/tools/tools.dm @@ -585,7 +585,7 @@ chassis.visible_message("The [chassis.name] armor deflects the projectile") chassis.log_append_to_last("Armor saved.") else - chassis.take_damage(round(Proj.damage*src.damage_coeff),Proj.flag) + chassis.take_damage(round(Proj.damage*src.damage_coeff),Proj.check_armour) chassis.check_for_internal_damage(list(MECHA_INT_FIRE,MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST)) Proj.on_hit(chassis) set_ready_state(0) diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index 4790550700..f57e2e046d 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -487,7 +487,7 @@ /obj/mecha/bullet_act(var/obj/item/projectile/Proj) //wrapper - src.log_message("Hit by projectile. Type: [Proj.name]([Proj.flag]).",1) + src.log_message("Hit by projectile. Type: [Proj.name]([Proj.check_armour]).",1) call((proc_res["dynbulletdamage"]||src), "dynbulletdamage")(Proj) //calls equipment ..() return @@ -506,10 +506,10 @@ var/ignore_threshold if(istype(Proj, /obj/item/projectile/beam/pulse)) ignore_threshold = 1 - src.take_damage(Proj.damage, Proj.flag) + src.take_damage(Proj.damage, Proj.check_armour) if(prob(25)) spark_system.start() src.check_for_internal_damage(list(MECHA_INT_FIRE,MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST,MECHA_INT_SHORT_CIRCUIT),ignore_threshold) - + //AP projectiles have a chance to cause additional damage if(Proj.penetrating) var/distance = get_dist(Proj.starting, get_turf(loc)) @@ -520,9 +520,9 @@ hit_occupant = 0 else src.check_for_internal_damage(list(MECHA_INT_FIRE,MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST,MECHA_INT_SHORT_CIRCUIT), 1) - + Proj.penetrating-- - + if(prob(15)) break //give a chance to exit early diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 1e3cb7547a..63447c5168 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -141,7 +141,6 @@ if(isliving(src.loc)) return user.next_move = max(user.next_move+2,world.time + 2) - add_fingerprint(user) user.put_in_active_hand(src) if(src.loc == user) src.pickup(user) @@ -638,8 +637,8 @@ For zooming with scope or binoculars. This is called from modules/mob/mob_movement.dm if you move you will be zoomed out modules/mob/living/carbon/human/life.dm if you die, you will be zoomed out. */ - -/obj/item/proc/zoom(var/tileoffset = 11,var/viewsize = 12) //tileoffset is client view offset in the direction the user is facing. viewsize is how far out this thing zooms. 7 is normal view +//Looking through a scope or binoculars should /not/ improve your periphereal vision. Still, increase viewsize a tiny bit so that sniping isn't as restricted to NSEW +/obj/item/proc/zoom(var/tileoffset = 14,var/viewsize = 9) //tileoffset is client view offset in the direction the user is facing. viewsize is how far out this thing zooms. 7 is normal view var/devicename @@ -686,14 +685,6 @@ modules/mob/living/carbon/human/life.dm if you die, you will be zoomed out. usr.visible_message("[usr] peers through the [zoomdevicename ? "[zoomdevicename] of the [src.name]" : "[src.name]"].") - /* - if(istype(usr,/mob/living/carbon/human/)) - var/mob/living/carbon/human/H = usr - usr.visible_message("[usr] holds [devicename] up to [H.get_visible_gender() == MALE ? "his" : H.get_visible_gender() == FEMALE ? "her" : "their"] eyes.") - else - usr.visible_message("[usr] holds [devicename] up to its eyes.") - */ - else usr.client.view = world.view if(!usr.hud_used.hud_shown) diff --git a/code/game/objects/items/robot/robot_upgrades.dm b/code/game/objects/items/robot/robot_upgrades.dm index f9d3e356ce..9bc40c779d 100644 --- a/code/game/objects/items/robot/robot_upgrades.dm +++ b/code/game/objects/items/robot/robot_upgrades.dm @@ -121,7 +121,7 @@ usr << "There's no mounting point for the module!" return 0 - var/obj/item/weapon/gun/energy/taser/cyborg/T = locate() in R.module + var/obj/item/weapon/gun/energy/taser/mounted/cyborg/T = locate() in R.module if(!T) T = locate() in R.module.contents if(!T) diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm index 5ee4532e77..1ccca84b77 100644 --- a/code/game/objects/items/toys.dm +++ b/code/game/objects/items/toys.dm @@ -140,7 +140,7 @@ icon_state = "revolver" item_state = "gun" flags = CONDUCT - slot_flags = SLOT_BELT + slot_flags = SLOT_BELT|SLOT_HOLSTER w_class = 3.0 matter = list("glass" = 10,"metal" = 10) diff --git a/code/game/objects/items/weapons/grenades/flashbang.dm b/code/game/objects/items/weapons/grenades/flashbang.dm index a332f6fa92..bda28f83b1 100644 --- a/code/game/objects/items/weapons/grenades/flashbang.dm +++ b/code/game/objects/items/weapons/grenades/flashbang.dm @@ -21,6 +21,7 @@ B.health -= damage B.update_icon() + new/obj/effect/effect/sparks(src.loc) new/obj/effect/effect/smoke/illumination(src.loc, brightness=15) del(src) return diff --git a/code/game/objects/items/weapons/manuals.dm b/code/game/objects/items/weapons/manuals.dm index f64473ba54..f026313034 100644 --- a/code/game/objects/items/weapons/manuals.dm +++ b/code/game/objects/items/weapons/manuals.dm @@ -75,10 +75,10 @@ /obj/item/weapon/book/manual/supermatter_engine - name = "Supermatter Engine User's Guide" + name = "Supermatter Engine Operating Manual" icon_state = "bookSupermatter" - author = "Waleed Asad" - title = "Supermatter Engine User's Guide" + author = "Nanotrasen Central Engineering Division" + title = "Supermatter Engine Operating Manual" /obj/item/weapon/book/manual/supermatter_engine/New() ..() @@ -94,95 +94,56 @@ +

OPERATING MANUAL FOR MK 1 PROTOTYPE THERMOELECTRIC SUPERMATTER ENGINE 'TOMBOLA'


- Engineering notes on the single-stage supermatter engine,
- -Waleed Asad

- - Station,
- Exodus

- - A word of caution, do not enter the engine room for any reason without radiation protection and meson scanners on. The status of the engine may be unpredictable even when you believe it is 'off.' This is an important level of personal protection.

- - The engine has two basic modes of functionality. It has been observed that it is capable of both a safe level of operation and a modified, high output mode.

- -

Heat-Primary Mode

- Notes on starting the basic function mode +

OPERATING PRINCIPLES

+
+
  • The supermatter crystal serves as the fundamental power source of the engine. Upon being charged, it begins to emit large amounts of heat and radiation, as well and oxygen and plasma. As oxygen accelerates the reaction, and plasma carries the risk of fire, these must be filtered out. NOTE: Supermatter radiation will not charge radiation collectors.
  • +
    +
  • Air in the reactor chamber housing the supermatter is circulated through the reactor loop, which passes through the filters and thermoelectric generators. The thermoelectric generators transfer heat from the reactor loop to the colder radiator loop, thereby generating power. Additional power is generated from internal turbines in the circulators.
  • +
    +
  • Air in the radiator loop is circulated through the radiator bank, located in space. This rapidly cools the air, preserving the temperature differential needed for power generation.
  • +
    +
  • The MK 1 Prototype Thermoelectric Supermatter Engine is designed to operate at reactor temperatures of 3000K to 4000K and generate up to 1MW of power. Beyond 1MW, the thermoelectric generators will begin to lose power through electrical discharge, reducing efficiency, but additional power generation remains feasible.
  • +
    +
  • The crystal structure of the supermatter will begin to liquefy if its temperature exceeds 5000K. This eventually results in a massive release of light, heat and radiation, disintegration of both the supermatter crystal and most of the surrounding area, and as as-of-yet poorly documented psychological effects on all animals within a 2km. Appropriate action should be taken to stabilize or eject the supermatter before such occurs.
  • +
    +

    SUPERMATTER HANDLING

    +
  • Do not expose supermatter to oxygen.
  • +
  • Do not touch supermatter without gloves without exosuit protection allow supermatter to contact any solid object apart from specially-designed supporting pallet.
  • +
  • Do not directly view supermatter without meson goggles.
  • +
  • While handles on pallet allow moving the supermatter via pulling, pushing should not be attempted.
  • +
    +

    STARTUP PROCEDURE

      -
    1. Prepare collector arrays: As is standard, begin by wrenching them down, filling six plasma tanks with a plasma canister, and inserting the tank into the collectors one by one. Finally, initialize each collector.
    2. - -
    3. Prepare gas system: Before introducing any gas into the supermatter engine room, it is important to remember the small, but vital steps to preparing this section. First, set the input gas pump and output gas flow pump to 4500 kPa, or maximum flow. Second, switch the digital switching valve into the 'up' position, so the green light is on north side of the valve, in order to circulate the gas back toward the coolers and collectors.
    4. - -
    5. Apply N2 gas: Retrieve the two N2 canisters from storage and bring them to the engine room. Attach one of them to the input section of the engine gas system located next to the collectors. Keep it attached until the N2 pressure is low enough to turn the canister light red. Replace it with the second canister to keep N2 pressure at optimal levels.
    6. - -
    7. Open supermatter shielding: This button is located in the engine room, to the left of the engine monitoring room blast doors. At this point, the supermatter chamber is mostly a gas mixture of N2 and is producing no radiation. It is considered 'safe' up until this point. Do not forget radiation shielding and meson scanners.
    8. - -
    9. Begin primary emitter burst series: Begin by firing four shots into the supermatter using the emitter. It is important to move to this step quickly. The onboard SMES units may not have enough power to run the emitters if left alone too long on-station. This engine can produce enough power on its own to run the entire station, ignoring the SMES units completely, and is wired to do so.
    10. - -
    11. Switch SMES units to primary settings: Maximize input and set the devices to automatically charge, additionally turn their outputs on if they are off unless power is to be saved (Which can be useful in case of later failures).
    12. - -
    13. Begin secondary emitter burst series: Before firing the emitter again, check the power in the line with a multimeter (Do not forget electrical gloves). The engine is running at high efficiency when the value exceeds 200,000 power units.
    14. - -
    15. Maintain engine power: When power in the lines get low, add an additional emitter burst series to bring power to normal levels.
    16. +
    17. Fill reactor loop and radiator loop with two (2) standard canisters of nitrogen gas each.
    18. +
    19. Ensure that pumps and filters are on and operating at maximum power.
    20. +
    21. Fire 5 15 2 UNKNOWN 8-12 pulses from emitter at supermatter crystal. Reactor blast doors must be open for this procedure.
    - - -

    O2-Reaction Mode

    - - The second mode for running the engine uses a gas mixture to produce a reaction within the supermatter. This mode requires the CE's or Atmospheric's help to set up. This is called 'O2-Reaction Mode.'

    - - THIS MODE CAN CAUSE A RUNAWAY REACTION, LEADING TO CATASTROPHIC FAILURE IF NOT MAINTAINED. NEVER FORGET ABOUT THE ENGINE IN THIS MODE.

    - - Additionally, this mode can be used for what is called a 'Cold Start.' If the station has no power in the SMES to run the emitters, using this mode will allow enough power output to run them, and quickly reach an acceptable level of power output.

    - +
    +

    OPERATION AND MAINTENANCE

      -
    1. Prepare collector arrays: As is standard, begin by wrenching them down, filling six plasma tanks with a plasma canister, and inserting the tank into the collectors one by one. Finally, initialize each collector.
    2. - -
    3. Prepare gas system: Before introducing any gas into the supermatter engine room, it is important to remember the small, but vital steps to preparing this section. First, set the input gas pump and output gas flow pump to 4500 kPa, or maximum flow. Second, switch the digital switching valve into the 'up' position, so the green light is on north side of the valve, in order to circulate the gas back toward the coolers and collectors.
    4. - -
    5. Modify the engine room filters: Unlike the Heat-Primary Mode, it is important to change the filters attached to the gas system to stop filtering O2, and start filtering carbon molecules. O2-Reaction Mode produces far more plasma than Heat-Primary, therefore filtering it off is essential.
    6. - -
    7. Switch SMES units to primary settings: Maximize input and set the devices to automatically charge, additionally turn their outputs on if they are off unless power is to be saved (Which can be useful in case of later failures). If you check the power in the system lines at this point, you will find that it is constantly going up. Indeed, with just the addition of O2 to the supermatter, it will begin outputting power.
    8. - -
    9. Begin primary emitter burst series: Begin by firing four shots into the supermatter using the emitter. Do not over power the supermatter. The reaction is self sustaining and propagating. As long as O2 is in the chamber, it will continue outputting MORE power.
    10. - -
    11. Maintain follow up operations: Remember to check the temperature of the core gas and switch to the Heat-Primary function, or vent the core room when problems begin if required.
    12. -

    - -

    Notes on Supermatter Reaction Function and Drawbacks

    - - After several hours of observation, an interesting phenomenon was witnessed. The supermatter undergoes a constant, self-sustaining reaction when given an extremely high O2 concentration. Anything about 80% or higher typically will cause this reaction. The supermatter will continue to react whenever this gas mixture is in the same room as the supermatter.

    - - To understand why O2-Reaction mode is dangerous, the core principle of the supermatter must be understood. The supermatter emits three things when 'not safe,' that is any time it is giving off power. These things are:
    - -
    - - When in Heat-Primary mode, far more heat and plasma are produced than radiation. In O2-Reaction mode, very little heat and only moderate amounts of plasma are produced, however HUGE amounts of energy leaving the supermatter is in the form of radiation.

    - - The O2-Reaction engine mode has a single drawback which has been eluded to more than once so far and that is very simple. The engine room will continue to grow hotter as the constant reaction continues. Eventually, there will be what is called a 'critical gas mixture.' This is the point at which the constant adding of plasma to the mixture of air around the supermatter changes the gas concentration to below the tolerance. When this happens, two things occur. First, the supermatter switches to its primary mode of operation wherein huge amounts of heat are produced by the engine rather than low amounts with high power output. Second, an uncontrollable increase in heat within the supermatter chamber will occur. This will lead to a spark-up, igniting the plasma in the supermatter chamber, wildly increasing both pressure and temperature.

    - - While the O2-Reaction mode is dangerous, it does produce heavy amounts of energy. Consider using this mode only in short amounts to fill the SMES, and switch back later in the shift to keep things flowing normally.

    - - -

    Notes on Supermatter Containment and Emergency Procedures

    - - While a constant vigil on the supermatter is not required, regular checkups are important. Check the temperature of gas leaving the supermatter chamber for unsafe levels and ensure that the plasma in the chamber is at a safe concentration. Of course, also make sure the chamber is not on fire. A fire in the core chamber is very difficult to put out. As any toxin scientist can tell you, even low amounts of plasma can burn at very high temperatures. This burning creates a huge increase in pressure and more importantly, temperature of the crystal itself.

    - - The supermatter is strong, but not invincible. When the supermatter is heated too much, its crystal structure will attempt to liquefy. The change in atomic structure of the supermatter leads to a single reaction, a massive explosion. The computer chip attached to the supermatter core will warn the station when stability is threatened. It will then offer a second warning, when things have become dangerously close to total destruction of the core.

    - - Located both within the CE office and engine room is the engine ventilatory control button. This button allows the core vent controls to be accessed, venting the room to space. Remember however, that this process takes time. If a fire is raging, and the pressure is higher than fathomable, it will take a great deal of time to vent the room. Also located in the CE's office is the emergency core eject button. A new core can be ordered from cargo. It is often not worth the lives of the crew to hold on to it, not to mention the structural damage. However, if by some mistake the supermatter is pushed off or removed from the mass driver it sits on, manual reposition will be required. Which is very dangerous and often leads to death.

    - - The supermatter is extremely dangerous. More dangerous than people give it credit for. It can destroy you in an instant, without hesitation, reducing you to a pile of dust. When working closely with supermatter, it is suggested to get a genetic backup and do not wear any items of value to you. The supermatter core can be pulled if grabbed properly by the base, but pushing is not possible.

    - - -

    In Closing

    - - Remember that the supermatter is dangerous, and the core is dangerous still. Venting the core room is always an option if you are even remotely worried, utilizing Atmospherics to properly ready the room once more for core function. It is always a good idea to check up regularly on the temperature of gas leaving the chamber, as well as the power in the system lines. Lastly, once again remember, never touch the supermatter with anything. Ever.

    - - -Waleed Asad, Senior Engine Technician +
  • Ensure that radiation protection and meson goggles are worn at all times while working in the engine room.
  • +
  • Ensure that reactor and radiator loops are undamaged and unobstructed.
  • +
  • Ensure that plasma and oxygen gas exhaust from filters is properly contained or disposed. Do not allow exhaust pressure to exceed 4500 kPa.
  • +
  • Ensure that engine room Area Power Controller (APC) and engine Superconducting Magnetic Energy Storage unit (SMES) are properly charged.
  • +
  • Ensure that reactor temperature does not exceed 5000K. In event of reactor temperature exceeding 5000K, see EMERGENCY COOLING PROCEDURE.
  • +
  • In event of imminent and/or unavoidable delamination, see EJECTION PROCEDURE.
  • + +
    +

    EMERGENCY COOLING PROCEDURE

    +
      +
    1. Open Emergency Cooling Valve 1 and Emergency Cooling Valve 2.
    2. +
    3. When reactor temperature returns to safe operating levels, close Emergency Cooling Valve 1 and Emergency Cooling Valve 2.
    4. +
    5. If reactor temperature does not return to safe operating levels, see EJECTION PROCEDURE.
    6. +
    +
    +

    EJECTION PROCEDURE

    +
      +
    1. Press Engine Ventilatory Control button to open engine core vent to space.
    2. +
    3. Press Emergency Core Eject button to eject supermatter crystal. NOTE: Attempting crystal ejection while engine core vent is closed will result in ejection failure.
    4. +
    5. In event of ejection failure, pending
    6. +
    "} diff --git a/code/game/objects/items/weapons/storage/boxes.dm b/code/game/objects/items/weapons/storage/boxes.dm index aaa77bf663..3376d3a4f8 100644 --- a/code/game/objects/items/weapons/storage/boxes.dm +++ b/code/game/objects/items/weapons/storage/boxes.dm @@ -79,7 +79,6 @@ /obj/item/weapon/storage/box/syringes name = "box of syringes" desc = "A box full of syringes." - desc = "A biohazard alert warning is printed on the box" icon_state = "syringe" New() @@ -92,6 +91,22 @@ new /obj/item/weapon/reagent_containers/syringe( src ) new /obj/item/weapon/reagent_containers/syringe( src ) +/obj/item/weapon/storage/box/syringegun + name = "box of syringe gun cartridges" + desc = "A box full of compressed gas cartridges." + icon_state = "syringe" + + New() + ..() + new /obj/item/weapon/syringe_cartridge( src ) + new /obj/item/weapon/syringe_cartridge( src ) + new /obj/item/weapon/syringe_cartridge( src ) + new /obj/item/weapon/syringe_cartridge( src ) + new /obj/item/weapon/syringe_cartridge( src ) + new /obj/item/weapon/syringe_cartridge( src ) + new /obj/item/weapon/syringe_cartridge( src ) + + /obj/item/weapon/storage/box/beakers name = "box of beakers" icon_state = "beaker" @@ -176,6 +191,48 @@ new /obj/item/ammo_casing/shotgun/pellet(src) new /obj/item/ammo_casing/shotgun/pellet(src) +/obj/item/weapon/storage/box/flashshells + name = "box of illumination shells" + desc = "It has a picture of a gun and several warning symbols on the front.
    WARNING: Live ammunition. Misuse may result in serious injury or death." + + New() + ..() + new /obj/item/ammo_casing/shotgun/flash(src) + new /obj/item/ammo_casing/shotgun/flash(src) + new /obj/item/ammo_casing/shotgun/flash(src) + new /obj/item/ammo_casing/shotgun/flash(src) + new /obj/item/ammo_casing/shotgun/flash(src) + new /obj/item/ammo_casing/shotgun/flash(src) + new /obj/item/ammo_casing/shotgun/flash(src) + +/obj/item/weapon/storage/box/stunshells + name = "box of stun shells" + desc = "It has a picture of a gun and several warning symbols on the front.
    WARNING: Live ammunition. Misuse may result in serious injury or death." + + New() + ..() + new /obj/item/ammo_casing/shotgun/stunshell(src) + new /obj/item/ammo_casing/shotgun/stunshell(src) + new /obj/item/ammo_casing/shotgun/stunshell(src) + new /obj/item/ammo_casing/shotgun/stunshell(src) + new /obj/item/ammo_casing/shotgun/stunshell(src) + new /obj/item/ammo_casing/shotgun/stunshell(src) + new /obj/item/ammo_casing/shotgun/stunshell(src) + +/obj/item/weapon/storage/box/heavysniperammo + name = "box of 14.5mm AP shells" + desc = "It has a picture of a gun and several warning symbols on the front.
    WARNING: Live ammunition. Misuse may result in serious injury or death." + + New() + ..() + new /obj/item/ammo_casing/a145(src) + new /obj/item/ammo_casing/a145(src) + new /obj/item/ammo_casing/a145(src) + new /obj/item/ammo_casing/a145(src) + new /obj/item/ammo_casing/a145(src) + new /obj/item/ammo_casing/a145(src) + new /obj/item/ammo_casing/a145(src) + /obj/item/weapon/storage/box/flashbangs name = "box of flashbangs (WARNING)" desc = "WARNING: These devices are extremely dangerous and can cause blindness or deafness in repeated use." diff --git a/code/game/objects/items/weapons/storage/uplink_kits.dm b/code/game/objects/items/weapons/storage/uplink_kits.dm index aa66b26f12..9d0a5d8296 100644 --- a/code/game/objects/items/weapons/storage/uplink_kits.dm +++ b/code/game/objects/items/weapons/storage/uplink_kits.dm @@ -26,7 +26,7 @@ return if("guns") - new /obj/item/weapon/gun/projectile(src) + new /obj/item/weapon/gun/projectile/revolver(src) new /obj/item/ammo_magazine/a357(src) new /obj/item/weapon/card/emag(src) new /obj/item/weapon/plastique(src) diff --git a/code/game/objects/structures/crates_lockers/closets/fitness.dm b/code/game/objects/structures/crates_lockers/closets/fitness.dm index 05e7968a93..b42fe3f950 100644 --- a/code/game/objects/structures/crates_lockers/closets/fitness.dm +++ b/code/game/objects/structures/crates_lockers/closets/fitness.dm @@ -54,8 +54,8 @@ /obj/structure/closet/lasertag/red/New() ..() - new /obj/item/weapon/gun/energy/laser/redtag(src) - new /obj/item/weapon/gun/energy/laser/redtag(src) + new /obj/item/weapon/gun/energy/lasertag/red(src) + new /obj/item/weapon/gun/energy/lasertag/red(src) new /obj/item/clothing/suit/redtag(src) new /obj/item/clothing/suit/redtag(src) @@ -68,7 +68,7 @@ /obj/structure/closet/lasertag/blue/New() ..() - new /obj/item/weapon/gun/energy/laser/bluetag(src) - new /obj/item/weapon/gun/energy/laser/bluetag(src) + new /obj/item/weapon/gun/energy/lasertag/blue(src) + new /obj/item/weapon/gun/energy/lasertag/blue(src) new /obj/item/clothing/suit/bluetag(src) new /obj/item/clothing/suit/bluetag(src) diff --git a/code/game/objects/structures/crates_lockers/closets/secure/security.dm b/code/game/objects/structures/crates_lockers/closets/secure/security.dm index 6ee564d76b..672978400c 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/security.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/security.dm @@ -54,6 +54,7 @@ new /obj/item/weapon/storage/box/ids(src) new /obj/item/weapon/storage/box/ids( src ) new /obj/item/weapon/gun/energy/gun(src) + new /obj/item/weapon/gun/projectile/colt/flash(src) new /obj/item/device/flash(src) return @@ -258,10 +259,10 @@ new /obj/item/device/radio/headset/headset_sec(src) new /obj/item/device/detective_scanner(src) new /obj/item/clothing/suit/armor/det_suit(src) - new /obj/item/ammo_magazine/c45r(src) - new /obj/item/ammo_magazine/c45r(src) + new /obj/item/ammo_magazine/c45m/rubber(src) + new /obj/item/ammo_magazine/c45m/rubber(src) new /obj/item/taperoll/police(src) - new /obj/item/weapon/gun/projectile/detective/semiauto(src) + new /obj/item/weapon/gun/projectile/colt/detective(src) new /obj/item/clothing/accessory/holster/armpit(src) return diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm index 7e7cfaca1e..487c442b86 100644 --- a/code/modules/admin/verbs/debug.dm +++ b/code/modules/admin/verbs/debug.dm @@ -595,7 +595,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that M.equip_to_slot_or_del(new /obj/item/weapon/cloaking_device(M), slot_r_store) - M.equip_to_slot_or_del(new /obj/item/weapon/gun/projectile(M), slot_r_hand) + M.equip_to_slot_or_del(new /obj/item/weapon/gun/projectile/revolver(M), slot_r_hand) M.equip_to_slot_or_del(new /obj/item/ammo_magazine/a357(M), slot_l_store) if ("tournament chef") //Steven Seagal FTW @@ -709,7 +709,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that for(var/i=3, i>0, i--) sec_briefcase.contents += new /obj/item/weapon/spacecash/c1000 sec_briefcase.contents += new /obj/item/weapon/gun/energy/crossbow - sec_briefcase.contents += new /obj/item/weapon/gun/projectile/mateba + sec_briefcase.contents += new /obj/item/weapon/gun/projectile/revolver/mateba sec_briefcase.contents += new /obj/item/ammo_magazine/a357 sec_briefcase.contents += new /obj/item/weapon/plastique M.equip_to_slot_or_del(sec_briefcase, slot_l_hand) @@ -891,7 +891,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that M.equip_to_slot_or_del(new /obj/item/clothing/glasses/thermal/eyepatch(M), slot_glasses) M.equip_to_slot_or_del(new /obj/item/clothing/suit/hgpirate(M), slot_wear_suit) M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(M), slot_back) - M.equip_to_slot_or_del(new /obj/item/weapon/gun/projectile/mateba(M), slot_belt) + M.equip_to_slot_or_del(new /obj/item/weapon/gun/projectile/revolver/mateba(M), slot_belt) M.equip_to_slot_or_del(new /obj/item/clothing/under/soviet(M), slot_w_uniform) var/obj/item/weapon/card/id/W = new(M) W.name = "[M.real_name]'s ID Card" diff --git a/code/modules/admin/verbs/striketeam.dm b/code/modules/admin/verbs/striketeam.dm index 36199c0305..9f42da94d9 100644 --- a/code/modules/admin/verbs/striketeam.dm +++ b/code/modules/admin/verbs/striketeam.dm @@ -153,7 +153,7 @@ var/global/sent_strike_team = 0 equip_to_slot_or_del(new /obj/item/weapon/melee/energy/sword(src), slot_l_store) equip_to_slot_or_del(new /obj/item/weapon/grenade/flashbang(src), slot_r_store) equip_to_slot_or_del(new /obj/item/weapon/tank/emergency_oxygen(src), slot_s_store) - equip_to_slot_or_del(new /obj/item/weapon/gun/projectile/mateba(src), slot_belt) + equip_to_slot_or_del(new /obj/item/weapon/gun/projectile/revolver/mateba(src), slot_belt) equip_to_slot_or_del(new /obj/item/weapon/gun/energy/pulse_rifle(src), slot_r_hand) diff --git a/code/modules/admin/verbs/vox_raiders.dm b/code/modules/admin/verbs/vox_raiders.dm index 6676acec32..6c34bb92c6 100644 --- a/code/modules/admin/verbs/vox_raiders.dm +++ b/code/modules/admin/verbs/vox_raiders.dm @@ -37,7 +37,7 @@ var/global/vox_tick = 1 equip_to_slot_or_del(new /obj/item/weapon/storage/belt/utility/full(src), slot_belt) equip_to_slot_or_del(new /obj/item/clothing/glasses/thermal/monocle(src), slot_glasses) // REPLACE WITH CODED VOX ALTERNATIVE. equip_to_slot_or_del(new /obj/item/weapon/card/emag(src), slot_l_store) - equip_to_slot_or_del(new /obj/item/weapon/gun/dartgun/vox/raider(src), slot_r_hand) + equip_to_slot_or_del(new /obj/item/weapon/gun/projectile/dartgun/vox/raider(src), slot_r_hand) equip_to_slot_or_del(new /obj/item/device/multitool(src), slot_l_hand) if(4) // Vox medic! @@ -46,7 +46,7 @@ var/global/vox_tick = 1 equip_to_slot_or_del(new /obj/item/weapon/storage/belt/utility/full(src), slot_belt) // Who needs actual surgical tools? equip_to_slot_or_del(new /obj/item/clothing/glasses/hud/health(src), slot_glasses) // REPLACE WITH CODED VOX ALTERNATIVE. equip_to_slot_or_del(new /obj/item/weapon/circular_saw(src), slot_l_store) - equip_to_slot_or_del(new /obj/item/weapon/gun/dartgun/vox/medical, slot_r_hand) + equip_to_slot_or_del(new /obj/item/weapon/gun/projectile/dartgun/vox/medical, slot_r_hand) equip_to_slot_or_del(new /obj/item/clothing/mask/breath(src), slot_wear_mask) equip_to_slot_or_del(new /obj/item/weapon/tank/nitrogen(src), slot_back) diff --git a/code/modules/clothing/spacesuits/rig/modules/rig_weapons.dm b/code/modules/clothing/spacesuits/rig/modules/rig_weapons.dm deleted file mode 100644 index 792a6ed0d0..0000000000 --- a/code/modules/clothing/spacesuits/rig/modules/rig_weapons.dm +++ /dev/null @@ -1,51 +0,0 @@ -//Weapon types intended to be used with rig modules - -/obj/item/weapon/gun/energy/lasercannon/mounted/load_into_chamber() - if(in_chamber) - return 1 - var/obj/item/rig_module/module = loc - if(!istype(module)) - return 0 - if(module.holder && module.holder.wearer) - var/mob/living/carbon/human/H = module.holder.wearer - if(istype(H) && H.back) - var/obj/item/weapon/rig/suit = H.back - if(istype(suit) && suit.cell && suit.cell.charge >= 250) - suit.cell.use(250) - in_chamber = new /obj/item/projectile/beam/heavylaser(src) - return 1 - return 0 - -/obj/item/weapon/gun/energy/gun/mounted/load_into_chamber() - if(in_chamber) - return 1 - var/obj/item/rig_module/module = loc - if(!istype(module)) - return 0 - if(module.holder && module.holder.wearer) - var/mob/living/carbon/human/H = module.holder.wearer - if(istype(H) && H.back) - var/obj/item/weapon/rig/suit = H.back - if(istype(suit) && suit.cell && suit.cell.charge >= 250) - suit.cell.use(250) - var/prog_path = projectile_type - in_chamber = new prog_path(src) - return 1 - return 0 - -/obj/item/weapon/gun/energy/taser/mounted/load_into_chamber() - if(in_chamber) - return 1 - var/obj/item/rig_module/module = loc - if(!istype(module)) - return 0 - if(module.holder && module.holder.wearer) - var/mob/living/carbon/human/H = module.holder.wearer - if(istype(H) && H.back) - var/obj/item/weapon/rig/suit = H.back - if(istype(suit) && suit.cell && suit.cell.charge >= 250) - suit.cell.use(250) - var/prog_path = projectile_type - in_chamber = new prog_path(src) - return 1 - return 0 \ No newline at end of file diff --git a/code/modules/clothing/suits/armor.dm b/code/modules/clothing/suits/armor.dm index 6a5dd04cb6..acc8443f90 100644 --- a/code/modules/clothing/suits/armor.dm +++ b/code/modules/clothing/suits/armor.dm @@ -196,38 +196,31 @@ slowdown = 1 armor = list(melee = 60, bullet = 60, laser = 60, energy = 40, bomb = 20, bio = 0, rad = 0) siemens_coefficient = 0.7 + var/obj/item/clothing/accessory/holster/holster + +/obj/item/clothing/suit/armor/tactical/New() + ..() + holster = new(src) - /obj/item/clothing/suit/armor/tactical/verb/holster() - set name = "Holster" - set category = "Object" - set src in usr - if(!istype(usr, /mob/living)) return - if(usr.stat) return +/obj/item/clothing/suit/armor/tactical/attackby(obj/item/W as obj, mob/user as mob) + ..() + holster.attackby(W, user) - if(!holstered) - if(!istype(usr.get_active_hand(), /obj/item/weapon/gun)) - usr << "\blue You need your gun equiped to holster it." - return - var/obj/item/weapon/gun/W = usr.get_active_hand() - if (!W.isHandgun()) - usr << "\red This gun won't fit in \the belt!" - return - holstered = usr.get_active_hand() - usr.drop_item() - holstered.loc = src - usr.visible_message("\blue \The [usr] holsters \the [holstered].", "You holster \the [holstered].") - else - if(istype(usr.get_active_hand(),/obj) && istype(usr.get_inactive_hand(),/obj)) - usr << "\red You need an empty hand to draw the gun!" - else - if(usr.a_intent == "hurt") - usr.visible_message("\red \The [usr] draws \the [holstered], ready to shoot!", \ - "\red You draw \the [holstered], ready to shoot!") - else - usr.visible_message("\blue \The [usr] draws \the [holstered], pointing it at the ground.", \ - "\blue You draw \the [holstered], pointing it at the ground.") - usr.put_in_hands(holstered) - holstered = null +/obj/item/clothing/suit/armor/tactical/verb/holster() + set name = "Holster" + set category = "Object" + set src in usr + if(!istype(usr, /mob/living)) return + if(usr.stat) return + + if(!holster.holstered) + var/obj/item/W = usr.get_active_hand() + if(!istype(W, /obj/item)) + usr << "You need your gun equiped to holster it." + return + holster.holster(W, usr) + else + holster.unholster(usr) //Non-hardsuit ERT armor. /obj/item/clothing/suit/armor/vest/ert diff --git a/code/modules/clothing/suits/miscellaneous.dm b/code/modules/clothing/suits/miscellaneous.dm index 09e67ea871..bcca81141c 100644 --- a/code/modules/clothing/suits/miscellaneous.dm +++ b/code/modules/clothing/suits/miscellaneous.dm @@ -15,7 +15,7 @@ item_state = "bluetag" blood_overlay_type = "armor" body_parts_covered = UPPER_TORSO - allowed = list (/obj/item/weapon/gun/energy/laser/bluetag) + allowed = list (/obj/item/weapon/gun/energy/lasertag/blue) siemens_coefficient = 3.0 /obj/item/clothing/suit/redtag @@ -25,7 +25,7 @@ item_state = "redtag" blood_overlay_type = "armor" body_parts_covered = UPPER_TORSO - allowed = list (/obj/item/weapon/gun/energy/laser/redtag) + allowed = list (/obj/item/weapon/gun/energy/lasertag/red) siemens_coefficient = 3.0 /* diff --git a/code/modules/clothing/under/accessories/holster.dm b/code/modules/clothing/under/accessories/holster.dm index af2743e43f..1a18604b6f 100644 --- a/code/modules/clothing/under/accessories/holster.dm +++ b/code/modules/clothing/under/accessories/holster.dm @@ -4,45 +4,40 @@ icon_state = "holster" item_color = "holster" slot = "utility" - var/obj/item/weapon/gun/holstered = null - -//subtypes can override this to specify what can be holstered -/obj/item/clothing/accessory/holster/proc/can_holster(obj/item/weapon/gun/W) - return W.isHandgun() + var/obj/item/holstered = null /obj/item/clothing/accessory/holster/proc/holster(obj/item/I, mob/user as mob) if(holstered) - user << "There is already a [holstered] holstered here!" + user << "There is already \a [holstered] holstered here!" return - if (!istype(I, /obj/item/weapon/gun)) - user << "Only guns can be holstered!" + if (!(I.slot_flags & SLOT_HOLSTER)) + user << "[I] won't fit in [src]!" return - var/obj/item/weapon/gun/W = I - if (!can_holster(W)) - user << "This [W] won't fit in the [src]!" - return - - holstered = W + holstered = I user.drop_from_inventory(holstered) holstered.loc = src holstered.add_fingerprint(user) - user.visible_message("[user] holsters the [holstered].", "You holster the [holstered].") + user.visible_message("[user] holsters \the [holstered].", "You holster \the [holstered].") /obj/item/clothing/accessory/holster/proc/unholster(mob/user as mob) if(!holstered) return if(istype(user.get_active_hand(),/obj) && istype(user.get_inactive_hand(),/obj)) - user << "You need an empty hand to draw the [holstered]!" + user << "You need an empty hand to draw \the [holstered]!" else if(user.a_intent == "hurt") - usr.visible_message("\red [user] draws the [holstered], ready to shoot!", \ - "You draw the [holstered], ready to shoot!") + usr.visible_message( + "\red [user] draws \the [holstered], ready to shoot!", + "You draw \the [holstered], ready to shoot!" + ) else - user.visible_message("[user] draws the [holstered], pointing it at the ground.", \ - "You draw the [holstered], pointing it at the ground.") + user.visible_message( + "[user] draws \the [holstered], pointing it at the ground.", + "You draw \the [holstered], pointing it at the ground." + ) user.put_in_hands(holstered) holstered.add_fingerprint(user) holstered = null @@ -86,6 +81,7 @@ if(!istype(usr, /mob/living)) return if(usr.stat) return + //can't we just use src here? var/obj/item/clothing/accessory/holster/H = null if (istype(src, /obj/item/clothing/accessory/holster)) H = src @@ -98,10 +94,10 @@ usr << "Something is very wrong." if(!H.holstered) - if(!istype(usr.get_active_hand(), /obj/item/weapon/gun)) + var/obj/item/W = usr.get_active_hand() + if(!istype(W, /obj/item)) usr << "You need your gun equiped to holster it." return - var/obj/item/weapon/gun/W = usr.get_active_hand() H.holster(W, usr) else H.unholster(usr) diff --git a/code/modules/customitems/item_defines.dm b/code/modules/customitems/item_defines.dm index 11a3fa03d4..95593385a0 100644 --- a/code/modules/customitems/item_defines.dm +++ b/code/modules/customitems/item_defines.dm @@ -1340,22 +1340,21 @@ desc = "A stun baton used for incapacitating targets; there seems to be a bunch of tally marks set into the handle." ///// Deckard .44 - Callum Leamas - Roaper -/obj/item/weapon/gun/projectile/detective/fluff/callum_leamas +/obj/item/weapon/gun/projectile/revolver/detective/fluff/callum_leamas name = "Deckard .44" desc = "A custom built revolver, based off the semi-popular Detective Special model." icon = 'icons/obj/custom_items.dmi' icon_state = "leamas-empty" + ammo_type = /obj/item/ammo_magazine/c38/rubber -/obj/item/weapon/gun/projectile/detective/fluff/callum_leamas/update_icon() - +/obj/item/weapon/gun/projectile/revolver/detective/fluff/callum_leamas/update_icon() ..() if(loaded.len) icon_state = "leamas-loaded" else icon_state = "leamas-empty" -/obj/item/weapon/gun/projectile/attackby(var/obj/item/A as obj, mob/user as mob) - +/obj/item/weapon/gun/projectile/revolver/detective/fluff/callum_leamas/load_ammo(var/obj/item/A, mob/user) if(istype(A, /obj/item/ammo_magazine)) flick("leamas-reloading",src) ..() diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index dd5bfe7d59..38ffc73f4e 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -1220,10 +1220,11 @@ /mob/living/carbon/human/can_inject(var/mob/user, var/error_msg, var/target_zone) . = 1 - if(!user) - target_zone = pick("chest","chest","chest","left leg","right leg","left arm", "right arm", "head") - else if(!target_zone) - target_zone = user.zone_sel.selecting + if(!target_zone) + if(!user) + target_zone = pick("chest","chest","chest","left leg","right leg","left arm", "right arm", "head") + else + target_zone = user.zone_sel.selecting switch(target_zone) if("head") diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index a45a11f453..399eabcf04 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -304,10 +304,7 @@ emp_act throw_mode_off() return - var/dtype = BRUTE - if(istype(O,/obj/item/weapon)) - var/obj/item/weapon/W = O - dtype = W.damtype + var/dtype = O.damtype var/throw_damage = O.throwforce*(speed/THROWFORCE_SPEED_DIVISOR) var/zone @@ -318,11 +315,11 @@ emp_act zone = ran_zone("chest",75) //Hits a random part of the body, geared towards the chest //check if we hit + var/miss_chance = 15 if (O.throw_source) var/distance = get_dist(O.throw_source, loc) - zone = get_zone_with_miss_chance(zone, src, min(15*(distance-2), 0)) - else - zone = get_zone_with_miss_chance(zone, src, 15) + miss_chance = max(15*(distance-2), 0) + zone = get_zone_with_miss_chance(zone, src, miss_chance) if(!zone) visible_message("\blue \The [O] misses [src] narrowly!") @@ -370,17 +367,21 @@ emp_act affecting.embed(I) // Begin BS12 momentum-transfer code. - if(O.throw_source && speed >= THROWNOBJ_KNOCKBACK_SPEED) - var/obj/item/weapon/W = O - var/momentum = speed/THROWNOBJ_KNOCKBACK_DIVISOR + var/mass = 1.5 + if(istype(O, /obj/item)) + var/obj/item/I = O + mass = I.w_class/THROWNOBJ_KNOCKBACK_DIVISOR + var/momentum = speed*mass + + if(O.throw_source && momentum >= THROWNOBJ_KNOCKBACK_SPEED) var/dir = get_dir(O.throw_source, src) visible_message("\red [src] staggers under the impact!","\red You stagger under the impact!") src.throw_at(get_edge_target_turf(src,dir),1,momentum) + + if(!O || !src) return - if(!W || !src) return - - if(W.loc == src && W.sharp) //Projectile is embedded and suitable for pinning. + if(O.loc == src && O.sharp) //Projectile is embedded and suitable for pinning. var/turf/T = near_wall(dir,2) if(T) @@ -389,6 +390,13 @@ emp_act src.anchored = 1 src.pinned += O +/mob/living/carbon/human/embed(var/obj/O, var/def_zone=null) + if(!def_zone) ..() + + var/datum/organ/external/affecting = get_organ(def_zone) + if(affecting) + affecting.embed(O) + /mob/living/carbon/human/proc/bloody_hands(var/mob/living/source, var/amount = 2) if (gloves) diff --git a/code/modules/mob/living/carbon/human/inventory.dm b/code/modules/mob/living/carbon/human/inventory.dm index b4c2a18c1d..5493c5d603 100644 --- a/code/modules/mob/living/carbon/human/inventory.dm +++ b/code/modules/mob/living/carbon/human/inventory.dm @@ -1,3 +1,16 @@ +/* +Add fingerprints to items when we put them in our hands. +This saves us from having to call add_fingerprint() any time something is put in a human's hands programmatically. + +*/ +/mob/living/carbon/human/put_in_l_hand(var/obj/item/W) + . = ..() + if(.) W.add_fingerprint(src) + +/mob/living/carbon/human/put_in_r_hand(var/obj/item/W) + . = ..() + if(.) W.add_fingerprint(src) + /mob/living/carbon/human/verb/quick_equip() set name = "quick-equip" set hidden = 1 diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm index b33c182b28..eb0c9ce859 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -63,10 +63,10 @@ return //Armor - var/absorb = run_armor_check(def_zone, P.flag) + var/absorb = run_armor_check(def_zone, P.check_armour) var/proj_sharp = is_sharp(P) var/proj_edge = has_edge(P) - if ((proj_sharp || proj_edge) && prob(getarmor(def_zone, P.flag))) + if ((proj_sharp || proj_edge) && prob(getarmor(def_zone, P.check_armour))) proj_sharp = 0 proj_edge = 0 @@ -103,16 +103,13 @@ /mob/living/hitby(atom/movable/AM as mob|obj,var/speed = THROWFORCE_SPEED_DIVISOR)//Standardization and logging -Sieve if(istype(AM,/obj/)) var/obj/O = AM - var/dtype = BRUTE - if(istype(O,/obj/item/weapon)) - var/obj/item/weapon/W = O - dtype = W.damtype + var/dtype = O.damtype var/throw_damage = O.throwforce*(speed/THROWFORCE_SPEED_DIVISOR) var/miss_chance = 15 if (O.throw_source) var/distance = get_dist(O.throw_source, loc) - miss_chance = min(15*(distance-2), 0) + miss_chance = max(15*(distance-2), 0) if (prob(miss_chance)) visible_message("\blue \The [O] misses [src] narrowly!") @@ -136,20 +133,23 @@ msg_admin_attack("[src.name] ([src.ckey]) was hit by a [O], thrown by [M.name] ([assailant.ckey]) (JMP)") // Begin BS12 momentum-transfer code. - if(O.throw_source && speed >= THROWNOBJ_KNOCKBACK_SPEED) - var/obj/item/weapon/W = O - var/momentum = speed/THROWNOBJ_KNOCKBACK_DIVISOR + var/mass = 1.5 + if(istype(O, /obj/item)) + var/obj/item/I = O + mass = I.w_class/THROWNOBJ_KNOCKBACK_DIVISOR + var/momentum = speed*mass + + if(O.throw_source && momentum >= THROWNOBJ_KNOCKBACK_SPEED) var/dir = get_dir(O.throw_source, src) visible_message("\red [src] staggers under the impact!","\red You stagger under the impact!") src.throw_at(get_edge_target_turf(src,dir),1,momentum) - if(!W || !src) return + if(!O || !src) return - if(W.sharp) //Projectile is suitable for pinning. + if(O.sharp) //Projectile is suitable for pinning. //Handles embedding for non-humans and simple_animals. - O.loc = src - src.embedded += O + embed(O) var/turf/T = near_wall(dir,2) @@ -158,7 +158,11 @@ visible_message("[src] is pinned to the wall by [O]!","You are pinned to the wall by [O]!") src.anchored = 1 src.pinned += O - src.verbs += /mob/proc/yank_out_object + +/mob/living/proc/embed(var/obj/O, var/def_zone=null) + O.loc = src + src.embedded += O + src.verbs += /mob/proc/yank_out_object //This is called when the mob is thrown into a dense turf /mob/living/proc/turf_collision(var/turf/T, var/speed) diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index 3278198723..2bc59be196 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -367,7 +367,7 @@ var/list/ai_verbs_default = list( if(message_cooldown) src << "Please allow one minute to pass between announcements." return - var/input = stripped_input(usr, "Please write a message to announce to the station crew.", "A.I. Announcement") + var/input = input(usr, "Please write a message to announce to the station crew.", "A.I. Announcement") if(!input) return diff --git a/code/modules/mob/living/silicon/robot/robot_modules.dm b/code/modules/mob/living/silicon/robot/robot_modules.dm index 3458a5bb47..9f213ad7e5 100644 --- a/code/modules/mob/living/silicon/robot/robot_modules.dm +++ b/code/modules/mob/living/silicon/robot/robot_modules.dm @@ -223,9 +223,9 @@ src.modules += new /obj/item/borg/sight/hud/sec(src) src.modules += new /obj/item/weapon/handcuffs/cyborg(src) src.modules += new /obj/item/weapon/melee/baton/robot(src) - src.modules += new /obj/item/weapon/gun/energy/taser/cyborg(src) + src.modules += new /obj/item/weapon/gun/energy/taser/mounted/cyborg(src) src.modules += new /obj/item/taperoll/police(src) - src.emag = new /obj/item/weapon/gun/energy/laser/cyborg(src) + src.emag = new /obj/item/weapon/gun/energy/laser/mounted(src) return /obj/item/weapon/robot_module/security/respawn_consumable(var/mob/living/silicon/robot/R) @@ -236,7 +236,7 @@ F.icon_state = "flash" else if(F.times_used) F.times_used-- - var/obj/item/weapon/gun/energy/taser/cyborg/T = locate() in src.modules + var/obj/item/weapon/gun/energy/taser/mounted/cyborg/T = locate() in src.modules if(T.power_supply.charge < T.power_supply.maxcharge) T.power_supply.give(T.charge_cost) T.update_icon() @@ -383,11 +383,11 @@ ..() src.modules += new /obj/item/device/flash(src) src.modules += new /obj/item/borg/sight/thermal(src) - src.modules += new /obj/item/weapon/gun/energy/laser/cyborg(src) + src.modules += new /obj/item/weapon/gun/energy/laser/mounted(src) src.modules += new /obj/item/weapon/pickaxe/plasmacutter(src) src.modules += new /obj/item/borg/combat/shield(src) src.modules += new /obj/item/borg/combat/mobility(src) - src.emag = new /obj/item/weapon/gun/energy/lasercannon/cyborg(src) + src.emag = new /obj/item/weapon/gun/energy/lasercannon/mounted(src) return /obj/item/weapon/robot_module/drone diff --git a/code/modules/mob/living/silicon/robot/robot_upgrades.dm b/code/modules/mob/living/silicon/robot/robot_upgrades.dm index 71f22a3029..a6d08bd534 100644 --- a/code/modules/mob/living/silicon/robot/robot_upgrades.dm +++ b/code/modules/mob/living/silicon/robot/robot_upgrades.dm @@ -108,7 +108,7 @@ usr << "There's no mounting point for the module!" return 0 - var/obj/item/weapon/gun/energy/taser/cyborg/T = locate() in R.module + var/obj/item/weapon/gun/energy/taser/mounted/cyborg/T = locate() in R.module if(!T) T = locate() in R.module.contents if(!T) diff --git a/code/modules/mob/living/simple_animal/hostile/russian.dm b/code/modules/mob/living/simple_animal/hostile/russian.dm index b09a6ec548..b96a615170 100644 --- a/code/modules/mob/living/simple_animal/hostile/russian.dm +++ b/code/modules/mob/living/simple_animal/hostile/russian.dm @@ -38,7 +38,7 @@ icon_state = "russianranged" icon_living = "russianranged" corpse = /obj/effect/landmark/mobcorpse/russian/ranged - weapon1 = /obj/item/weapon/gun/projectile/mateba + weapon1 = /obj/item/weapon/gun/projectile/revolver/mateba ranged = 1 projectiletype = /obj/item/projectile/bullet projectilesound = 'sound/weapons/Gunshot.ogg' diff --git a/code/modules/organs/organ_external.dm b/code/modules/organs/organ_external.dm index b45d0aafa7..25e12ebfbf 100644 --- a/code/modules/organs/organ_external.dm +++ b/code/modules/organs/organ_external.dm @@ -159,7 +159,7 @@ //If limb took enough damage, try to cut or tear it off if(body_part != UPPER_TORSO && body_part != LOWER_TORSO) //as hilarious as it is, getting hit on the chest too much shouldn't effectively gib you. if(config.limbs_can_break && brute_dam >= max_damage * config.organ_health_multiplier) - if( (edge && prob(5 * brute)) || (brute > 20 && prob(2 * brute)) ) + if( (edge && prob(5 * brute)) || (brute > 20 && prob(brute)) ) droplimb(1) return diff --git a/code/modules/power/antimatter/control.dm b/code/modules/power/antimatter/control.dm index b6eb7915d2..23c5e0243a 100644 --- a/code/modules/power/antimatter/control.dm +++ b/code/modules/power/antimatter/control.dm @@ -127,7 +127,7 @@ /obj/machinery/power/am_control_unit/bullet_act(var/obj/item/projectile/Proj) - if(Proj.flag != "bullet") + if(Proj.check_armour != "bullet") stability -= Proj.force return 0 diff --git a/code/modules/power/antimatter/shielding.dm b/code/modules/power/antimatter/shielding.dm index bdaeb0c659..5085fb6c85 100644 --- a/code/modules/power/antimatter/shielding.dm +++ b/code/modules/power/antimatter/shielding.dm @@ -117,7 +117,7 @@ proc/cardinalrange(var/center) /obj/machinery/am_shielding/bullet_act(var/obj/item/projectile/Proj) - if(Proj.flag != "bullet") + if(Proj.check_armour != "bullet") stability -= Proj.force/2 return 0 diff --git a/code/modules/power/cell.dm b/code/modules/power/cell.dm index 36ab1047a3..69f0b92a48 100644 --- a/code/modules/power/cell.dm +++ b/code/modules/power/cell.dm @@ -128,7 +128,7 @@ rigged = 1 //broken batterys are dangerous /obj/item/weapon/cell/emp_act(severity) - charge -= 1000 / severity + charge -= maxcharge / severity if (charge < 0) charge = 0 if(reliability != 100 && prob(50/severity)) diff --git a/code/modules/power/generator.dm b/code/modules/power/generator.dm index c574c37ef8..f6f7f135e2 100644 --- a/code/modules/power/generator.dm +++ b/code/modules/power/generator.dm @@ -1,4 +1,3 @@ - /obj/machinery/power/generator name = "thermoelectric generator" desc = "It's a high efficiency thermoelectric generator." @@ -9,15 +8,24 @@ use_power = 1 idle_power_usage = 100 //Watts, I hope. Just enough to do the computer and display things. + var/max_power = 500000 + var/thermal_efficiency = 0.65 + var/obj/machinery/atmospherics/binary/circulator/circ1 var/obj/machinery/atmospherics/binary/circulator/circ2 - var/lastgen = 0 - var/lastgenlev = -1 + var/last_circ1_gen = 0 + var/last_circ2_gen = 0 + var/last_thermal_gen = 0 + var/stored_energy = 0 + var/lastgen1 = 0 + var/lastgen2 = 0 + var/effective_gen = 0 + var/lastgenlev = 0 /obj/machinery/power/generator/New() ..() - + desc = initial(desc) + " Rated for [round(max_power/1000)] kW." spawn(1) reconnect() @@ -31,11 +39,11 @@ circ2 = null if(src.loc && anchored) if(src.dir & (EAST|WEST)) - circ1 = locate(/obj/machinery/atmospherics/binary/circulator) in get_step(src,EAST) - circ2 = locate(/obj/machinery/atmospherics/binary/circulator) in get_step(src,WEST) + circ1 = locate(/obj/machinery/atmospherics/binary/circulator) in get_step(src,WEST) + circ2 = locate(/obj/machinery/atmospherics/binary/circulator) in get_step(src,EAST) if(circ1 && circ2) - if(circ1.dir != SOUTH || circ2.dir != NORTH) + if(circ1.dir != NORTH || circ2.dir != SOUTH) circ1 = null circ2 = null @@ -58,13 +66,19 @@ /obj/machinery/power/generator/process() if(!circ1 || !circ2 || !anchored || stat & (BROKEN|NOPOWER)) + stored_energy = 0 return updateDialog() var/datum/gas_mixture/air1 = circ1.return_transfer_air() var/datum/gas_mixture/air2 = circ2.return_transfer_air() - lastgen = 0 + + lastgen2 = lastgen1 + lastgen1 = 0 + last_thermal_gen = 0 + last_circ1_gen = 0 + last_circ2_gen = 0 if(air1 && air2) var/air1_heat_capacity = air1.heat_capacity() @@ -72,10 +86,9 @@ var/delta_temperature = abs(air2.temperature - air1.temperature) if(delta_temperature > 0 && air1_heat_capacity > 0 && air2_heat_capacity > 0) - var/efficiency = 0.65 var/energy_transfer = delta_temperature*air2_heat_capacity*air1_heat_capacity/(air2_heat_capacity+air1_heat_capacity) - var/heat = energy_transfer*(1-efficiency) - lastgen = energy_transfer*efficiency*0.05 + var/heat = energy_transfer*(1-thermal_efficiency) + last_thermal_gen = energy_transfer*thermal_efficiency if(air2.temperature > air1.temperature) air2.temperature = air2.temperature - energy_transfer/air2_heat_capacity @@ -96,19 +109,29 @@ if(circ2.network2) circ2.network2.update = 1 - // update icon overlays and power usage only if displayed level has changed - if(lastgen > 250000 && prob(10)) + //Exceeding maximum power leads to some power loss + if(effective_gen > max_power && prob(5)) var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread s.set_up(3, 1, src) s.start() - lastgen *= 0.5 - var/genlev = max(0, min( round(11*lastgen / 250000), 11)) - if(lastgen > 100 && genlev == 0) + stored_energy *= 0.5 + + //Power + last_circ1_gen = circ1.return_stored_energy() + last_circ2_gen = circ2.return_stored_energy() + stored_energy += last_thermal_gen + last_circ1_gen + last_circ2_gen + lastgen1 = stored_energy*0.4 //smoothened power generation to prevent slingshotting as pressure is equalized, then restored by pumps + stored_energy -= lastgen1 + effective_gen = (lastgen1 + lastgen2) / 2 + + // update icon overlays and power usage only if displayed level has changed + var/genlev = max(0, min( round(11*effective_gen / max_power), 11)) + if(effective_gen > 100 && genlev == 0) genlev = 1 if(genlev != lastgenlev) lastgenlev = genlev updateicon() - add_avail(lastgen) + add_avail(effective_gen) /obj/machinery/power/generator/attack_ai(mob/user) if(stat & (BROKEN|NOPOWER)) return @@ -116,8 +139,11 @@ /obj/machinery/power/generator/attackby(obj/item/weapon/W as obj, mob/user as mob) if(istype(W, /obj/item/weapon/wrench)) + playsound(src.loc, 'sound/items/Ratchet.ogg', 75, 1) anchored = !anchored - user << "\blue You [anchored ? "secure" : "unsecure"] the bolts holding [src] to the floor." + user.visible_message("[user.name] [anchored ? "secures" : "unsecures"] the bolts holding [src.name] to the floor.", \ + "You [anchored ? "secure" : "unsecure"] the bolts holding [src] to the floor.", \ + "You hear a ratchet") use_power = anchored reconnect() else @@ -137,20 +163,33 @@ user.set_machine(src) - var/t = "
    Thermo-Electric Generator
    " + var/t = "
    Thermoelectric Generator
    " + t += "Total Output: [round(effective_gen/1000)] kW
    " + t += "Thermal Output: [round(last_thermal_gen/1000)] kW
    " + t += "
    " + + var/vertical = 0 + if (dir == NORTH || dir == SOUTH) + vertical = 1 if(circ1 && circ2) - t += "Output : [round(lastgen)] W

    " - - t += "Primary Circulator (top or right)
    " + t += "Primary Circulator ([vertical ? "top" : "left"])
    " + t += "Turbine Output: [round(last_circ1_gen/1000)] kW
    " + t += "Flow Capacity: [round(circ1.volume_capacity_used*100)]%
    " + t += "
    " t += "Inlet Pressure: [round(circ1.air1.return_pressure(), 0.1)] kPa
    " t += "Inlet Temperature: [round(circ1.air1.temperature, 0.1)] K
    " + t += "
    " t += "Outlet Pressure: [round(circ1.air2.return_pressure(), 0.1)] kPa
    " t += "Outlet Temperature: [round(circ1.air2.temperature, 0.1)] K
    " - - t += "Secondary Circulator (bottom or left)
    " + t += "
    " + t += "Secondary Circulator ([vertical ? "bottom" : "right"])
    " + t += "Turbine Output: [round(last_circ2_gen/1000)] kW
    " + t += "Flow Capacity: [round(circ2.volume_capacity_used*100)]%
    " + t += "
    " t += "Inlet Pressure: [round(circ2.air1.return_pressure(), 0.1)] kPa
    " t += "Inlet Temperature: [round(circ2.air1.temperature, 0.1)] K
    " + t += "
    " t += "Outlet Pressure: [round(circ2.air2.return_pressure(), 0.1)] kPa
    " t += "Outlet Temperature: [round(circ2.air2.temperature, 0.1)] K
    " @@ -158,11 +197,11 @@ t += "Unable to connect to circulators.
    " t += "Ensure both are in position and wrenched into place." - t += "
    " + t += "
    " t += "
    " t += "Refresh Close" - user << browse(t, "window=teg;size=460x300") + user << browse(t, "window=teg;size=400x500") onclose(user, "teg") return 1 @@ -201,4 +240,4 @@ if (usr.stat || usr.restrained() || anchored) return - src.set_dir(turn(src.dir, -90)) \ No newline at end of file + src.set_dir(turn(src.dir, -90)) diff --git a/code/modules/power/rust/virtual_particle_catcher.dm b/code/modules/power/rust/virtual_particle_catcher.dm index 2d32a9a785..350d9f66fc 100644 --- a/code/modules/power/rust/virtual_particle_catcher.dm +++ b/code/modules/power/rust/virtual_particle_catcher.dm @@ -42,7 +42,7 @@ name = "collector [mysize] OFF" /obj/effect/rust_particle_catcher/bullet_act(var/obj/item/projectile/Proj) - if(Proj.flag != "bullet" && parent) + if(Proj.check_armour != "bullet" && parent) parent.AddEnergy(Proj.damage * 20, 0, 1) update_icon() return 0 diff --git a/code/modules/projectiles/ammunition.dm b/code/modules/projectiles/ammunition.dm index b4b213972f..d31ba64814 100644 --- a/code/modules/projectiles/ammunition.dm +++ b/code/modules/projectiles/ammunition.dm @@ -6,73 +6,159 @@ flags = CONDUCT slot_flags = SLOT_BELT throwforce = 1 - w_class = 1.0 + w_class = 1 var/caliber = "" //Which kind of guns it can be loaded into var/projectile_type //The bullet type to create when New() is called - var/obj/item/projectile/BB = null //The loaded bullet + var/obj/item/projectile/BB = null //The loaded bullet - make it so that the projectiles are created only when needed? + var/spent_icon = null +/obj/item/ammo_casing/New() + ..() + if(ispath(projectile_type)) + BB = new projectile_type(src) + pixel_x = rand(-10, 10) + pixel_y = rand(-10, 10) - New() - ..() - if(ispath(projectile_type)) - BB = new projectile_type(src) - pixel_x = rand(-10.0, 10) - pixel_y = rand(-10.0, 10) - set_dir(pick(cardinal)) - +//removes the projectile from the ammo casing +/obj/item/ammo_casing/proc/expend() + . = BB + BB = null + set_dir(pick(cardinal)) //spin spent casings + update_icon() /obj/item/ammo_casing/attackby(obj/item/weapon/W as obj, mob/user as mob) if(istype(W, /obj/item/weapon/screwdriver)) - if(BB) - if(initial(BB.name) == "bullet") - var/tmp_label = "" - var/label_text = sanitize(copytext(input(user, "Inscribe some text into \the [initial(BB.name)]","Inscription",tmp_label), 1, MAX_NAME_LEN)) - if(length(label_text) > 20) - user << "\red The inscription can be at most 20 characters long." - else - if(label_text == "") - user << "\blue You scratch the inscription off of [initial(BB)]." - BB.name = initial(BB.name) - else - user << "\blue You inscribe \"[label_text]\" into \the [initial(BB.name)]." - BB.name = "[initial(BB.name)] \"[label_text]\"" - else - user << "\blue You can only inscribe a metal bullet." //because inscribing beanbags is silly - else + if(!BB) user << "\blue There is no bullet in the casing to inscribe anything into." + return + + var/tmp_label = "" + var/label_text = sanitize(copytext(input(user, "Inscribe some text into \the [initial(BB.name)]","Inscription",tmp_label), 1, MAX_NAME_LEN)) + if(length(label_text) > 20) + user << "\red The inscription can be at most 20 characters long." + else if(!label_text) + user << "\blue You scratch the inscription off of [initial(BB)]." + BB.name = initial(BB.name) + else + user << "\blue You inscribe \"[label_text]\" into \the [initial(BB.name)]." + BB.name = "[initial(BB.name)] (\"[label_text]\")" + +/obj/item/ammo_casing/update_icon() + if(spent_icon && !BB) + icon_state = spent_icon /obj/item/ammo_casing/examine(mob/user) ..() if (!BB) user << "This one is spent." -//Boxes of ammo +//Gun loading types +#define SINGLE_CASING 1 //The gun only accepts ammo_casings. ammo_magazines should never have this as their mag_type. +#define SPEEDLOADER 2 //Transfers casings from the mag to the gun when used. +#define MAGAZINE 4 //The magazine item itself goes inside the gun + +//An item that holds casings and can be used to put them inside guns /obj/item/ammo_magazine - name = "ammo box (.357)" - desc = "A box of ammo" + name = "magazine" + desc = "A magazine for some kind of gun." icon_state = "357" icon = 'icons/obj/ammo.dmi' flags = CONDUCT slot_flags = SLOT_BELT item_state = "syringe_kit" - matter = list("metal" = 50000) - throwforce = 2 - w_class = 2.0 + matter = list("metal" = 500) + throwforce = 5 + w_class = 2 throw_speed = 4 throw_range = 10 + var/list/stored_ammo = list() - var/ammo_type = "/obj/item/ammo_casing" + var/mag_type = SPEEDLOADER //ammo_magazines can only be used with compatible guns. This is not a bitflag, the load_method var on guns is. + var/caliber = "357" var/max_ammo = 7 + + var/ammo_type = /obj/item/ammo_casing //ammo type that is initially loaded + var/initial_ammo = null + var/multiple_sprites = 0 + //because BYOND doesn't support numbers as keys in associative lists + var/list/icon_keys = list() //keys + var/list/ammo_states = list() //values +/obj/item/ammo_magazine/New() + if(multiple_sprites) + initialize_magazine_icondata(src) - New() - for(var/i = 1, i <= max_ammo, i++) + if(isnull(initial_ammo)) + initial_ammo = max_ammo + + if(initial_ammo) + for(var/i in 1 to initial_ammo) stored_ammo += new ammo_type(src) + update_icon() + +/obj/item/ammo_magazine/attackby(obj/item/weapon/W as obj, mob/user as mob) + if(istype(W, /obj/item/ammo_casing)) + var/obj/item/ammo_casing/C = W + if(C.caliber != caliber) + user << "[C] does not fit into [src]." + return + if(stored_ammo.len >= max_ammo) + user << "[src] is full!" + return + user.remove_from_mob(C) + C.loc = src + stored_ammo.Insert(1, C) //add to the head of the list update_icon() - +/obj/item/ammo_magazine/attack_self(mob/user) + if(!stored_ammo.len) + user << "[src] is already empty!" + return + user << "You empty [src]." + for(var/obj/item/ammo_casing/C in stored_ammo) + C.loc = user.loc + C.set_dir(pick(cardinal)) + stored_ammo.Cut() update_icon() - if(multiple_sprites) - icon_state = "[initial(icon_state)]-[stored_ammo.len]" - desc = "There are [stored_ammo.len] shell\s left!" + +/obj/item/ammo_magazine/update_icon() + if(multiple_sprites) + //find the lowest key greater than or equal to stored_ammo.len + var/new_state = null + for(var/idx in 1 to icon_keys.len) + var/ammo_count = icon_keys[idx] + if (ammo_count >= stored_ammo.len) + new_state = ammo_states[idx] + break + icon_state = (new_state)? new_state : initial(icon_state) + +/obj/item/ammo_magazine/examine(mob/user) + ..() + user << "There [(stored_ammo.len > 1)? "are" : "is"] [stored_ammo.len] round\s left!" + +//magazine icon state caching +/var/global/list/magazine_icondata_keys = list() +/var/global/list/magazine_icondata_states = list() + +/proc/initialize_magazine_icondata(var/obj/item/ammo_magazine/M) + var/typestr = "[M.type]" + if(!(typestr in magazine_icondata_keys) || !(typestr in magazine_icondata_states)) + magazine_icondata_cache_add(M) + + M.icon_keys = magazine_icondata_keys[typestr] + M.ammo_states = magazine_icondata_states[typestr] + +/proc/magazine_icondata_cache_add(var/obj/item/ammo_magazine/M) + var/list/icon_keys = list() + var/list/ammo_states = list() + var/list/states = icon_states(M.icon) + for(var/i = 0, i <= M.max_ammo, i++) + var/ammo_state = "[M.icon_state]-[i]" + if(ammo_state in states) + icon_keys += i + ammo_states += ammo_state + + magazine_icondata_keys["[M.type]"] = icon_keys + magazine_icondata_states["[M.type]"] = ammo_states + diff --git a/code/modules/projectiles/ammunition/boxes.dm b/code/modules/projectiles/ammunition/boxes.dm index ed33bbfe48..3466f40b48 100644 --- a/code/modules/projectiles/ammunition/boxes.dm +++ b/code/modules/projectiles/ammunition/boxes.dm @@ -1,45 +1,159 @@ /obj/item/ammo_magazine/a357 - name = "ammo box (.357)" - desc = "A box of .357 ammo" - icon_state = "357" - ammo_type = "/obj/item/ammo_casing/a357" + //name = "ammo box (.357)" + //desc = "A box of .357 ammo" + //icon_state = "357" + name = "speed loader (.357)" + icon_state = "T38" + caliber = "357" + ammo_type = /obj/item/ammo_casing/a357 max_ammo = 7 multiple_sprites = 1 /obj/item/ammo_magazine/c38 name = "speed loader (.38)" icon_state = "38" - ammo_type = "/obj/item/ammo_casing/c38" + caliber = "38" + ammo_type = /obj/item/ammo_casing/c38 max_ammo = 6 multiple_sprites = 1 +/obj/item/ammo_magazine/c38/rubber + name = "speed loader (.38 rubber)" + ammo_type = /obj/item/ammo_casing/c38r /obj/item/ammo_magazine/c45m name = "magazine (.45)" icon_state = "45" - ammo_type = "/obj/item/ammo_casing/c45" + mag_type = MAGAZINE + ammo_type = /obj/item/ammo_casing/c45 + caliber = ".45" max_ammo = 7 multiple_sprites = 1 -/obj/item/ammo_magazine/c45/empty - max_ammo = 0 +/obj/item/ammo_magazine/c45m/empty + initial_ammo = 0 -/obj/item/ammo_magazine/c45r +/obj/item/ammo_magazine/c45m/rubber name = "magazine (.45 rubber)" - icon_state = "45" - ammo_type = "/obj/item/ammo_casing/c45r" - max_ammo = 7 - multiple_sprites = 1 + ammo_type = /obj/item/ammo_casing/c45r -/obj/item/ammo_magazine/c45f +/obj/item/ammo_magazine/c45m/flash name = "magazine (.45 flash)" - icon_state = "45" ammo_type = "/obj/item/ammo_casing/c45f" + +/obj/item/ammo_magazine/mc9mm + name = "magazine (9mm)" + icon_state = "9x19p" + origin_tech = "combat=2" + mag_type = MAGAZINE + caliber = "9mm" + ammo_type = /obj/item/ammo_casing/c9mm + max_ammo = 10 + multiple_sprites = 1 + +/obj/item/ammo_magazine/mc9mm/empty + initial_ammo = 0 + +/obj/item/ammo_magazine/mc9mm/flash + ammo_type = /obj/item/ammo_casing/c9mmf + +/obj/item/ammo_magazine/c9mm + name = "ammunition Box (9mm)" + icon_state = "9mm" + origin_tech = "combat=2" + caliber = "9mm" + ammo_type = /obj/item/ammo_casing/c9mm + max_ammo = 30 + +/obj/item/ammo_magazine/c9mm/empty + initial_ammo = 0 + +/obj/item/ammo_magazine/c45 + name = "ammunition Box (.45)" + icon_state = "9mm" + origin_tech = "combat=2" + caliber = ".45" + ammo_type = /obj/item/ammo_casing/c45 + max_ammo = 30 + +/obj/item/ammo_magazine/c9mm/empty + initial_ammo = 0 + +/obj/item/ammo_magazine/a12mm + name = "magazine (12mm)" + icon_state = "12mm" + origin_tech = "combat=2" + mag_type = MAGAZINE + caliber = "12mm" + ammo_type = "/obj/item/ammo_casing/a12mm" + max_ammo = 20 + multiple_sprites = 1 + +/obj/item/ammo_magazine/a12mm/empty + initial_ammo = 0 + +/obj/item/ammo_magazine/a50 + name = "magazine (.50)" + icon_state = "50ae" + origin_tech = "combat=2" + mag_type = MAGAZINE + caliber = ".50" + ammo_type = /obj/item/ammo_casing/a50 max_ammo = 7 multiple_sprites = 1 -/obj/item/ammo_magazine/c45r/empty - max_ammo = 0 +/obj/item/ammo_magazine/a50/empty + initial_ammo = 0 + +/obj/item/ammo_magazine/a75 + name = "ammo magazine (20mm)" + icon_state = "75" + mag_type = MAGAZINE + caliber = "75" + ammo_type = /obj/item/ammo_casing/a75 + multiple_sprites = 1 + max_ammo = 4 + +/obj/item/ammo_magazine/a75/empty + initial_ammo = 0 + +/obj/item/ammo_magazine/a762 + name = "magazine box (7.62mm)" + icon_state = "a762" + origin_tech = "combat=2" + mag_type = MAGAZINE + caliber = "a762" + ammo_type = /obj/item/ammo_casing/a762 + max_ammo = 50 + multiple_sprites = 1 + +/obj/item/ammo_magazine/a762/empty + initial_ammo = 0 + +/obj/item/ammo_magazine/c762 + name = "magazine (7.62mm)" + icon_state = "c762" + mag_type = MAGAZINE + caliber = "a762" + ammo_type = /obj/item/ammo_casing/a762 + max_ammo = 20 + multiple_sprites = 1 + +/obj/item/ammo_magazine/chameleon + name = "magazine (.45)" + icon_state = "45" + mag_type = MAGAZINE + caliber = ".45" + ammo_type = /obj/item/ammo_casing/chameleon + max_ammo = 7 + multiple_sprites = 1 + matter = list() + +/obj/item/ammo_magazine/chameleon/empty + initial_ammo = 0 + +/* +//unused garbage /obj/item/ammo_magazine/a418 name = "ammo box (.418)" @@ -48,116 +162,10 @@ max_ammo = 7 multiple_sprites = 1 - - /obj/item/ammo_magazine/a666 name = "ammo box (.666)" icon_state = "666" ammo_type = "/obj/item/ammo_casing/a666" max_ammo = 4 multiple_sprites = 1 - - -/obj/item/ammo_magazine/mc9mm - name = "magazine (9mm)" - icon_state = "9x19p" - origin_tech = "combat=2" - ammo_type = "/obj/item/ammo_casing/c9mm" - max_ammo = 10 - multiple_sprites = 1 - -/obj/item/ammo_magazine/mc9mm/empty/New() - ..() - stored_ammo = list() - update_icon() - -/obj/item/ammo_magazine/c9mm - name = "Ammunition Box (9mm)" - icon_state = "9mm" - origin_tech = "combat=2" - ammo_type = "/obj/item/ammo_casing/c9mm" - max_ammo = 30 - - - -/obj/item/ammo_magazine/c45 - name = "Ammunition Box (.45)" - icon_state = "9mm" - origin_tech = "combat=2" - ammo_type = "/obj/item/ammo_casing/c45" - max_ammo = 30 - - - -/obj/item/ammo_magazine/a12mm - name = "magazine (12mm)" - icon_state = "12mm" - origin_tech = "combat=2" - ammo_type = "/obj/item/ammo_casing/a12mm" - max_ammo = 20 - multiple_sprites = 1 - - -/obj/item/ammo_magazine/a12mm/empty - name = "magazine (12mm)" - icon_state = "12mm" - ammo_type = "/obj/item/ammo_casing/12mm" - max_ammo = 0 - -/obj/item/ammo_magazine/a50 - name = "magazine (.50)" - icon_state = "50ae" - origin_tech = "combat=2" - ammo_type = "/obj/item/ammo_casing/a50" - max_ammo = 7 - multiple_sprites = 1 - -/obj/item/ammo_magazine/a50/empty - name = "magazine (.50)" - icon_state = "50ae" - ammo_type = "/obj/item/ammo_casing/a50" - max_ammo = 0 - -/obj/item/ammo_magazine/a75 - name = "ammo magazine (.75)" - icon_state = "75" - ammo_type = "/obj/item/ammo_casing/a75" - multiple_sprites = 1 - max_ammo = 8 - -/obj/item/ammo_magazine/a75/empty - name = "ammo magazine (.75)" - icon_state = "75" - ammo_type = "/obj/item/ammo_casing/a75" - max_ammo = 0 - -/obj/item/ammo_magazine/a762 - name = "magazine (a762)" - icon_state = "a762" - origin_tech = "combat=2" - ammo_type = "/obj/item/ammo_casing/a762" - max_ammo = 50 - multiple_sprites = 1 - -/obj/item/ammo_magazine/a762/empty - name = "magazine (a762)" - icon_state = "a762" - ammo_type = "/obj/item/ammo_casing/a762" - max_ammo = 0 - multiple_sprites = 1 - -/obj/item/ammo_magazine/chameleon - name = "magazine (.45)" - icon_state = "45" - ammo_type = "/obj/item/ammo_casing/chameleon" - max_ammo = 7 - multiple_sprites = 1 - matter = list() - -/obj/item/ammo_magazine/chameleon/empty - name = "magazine (.45)" - icon_state = "45" - ammo_type = "/obj/item/ammo_casing/chameleon" - max_ammo = 0 - multiple_sprites = 1 - matter = list() +*/ diff --git a/code/modules/projectiles/ammunition/bullets.dm b/code/modules/projectiles/ammunition/bullets.dm index d0cb2915dc..67308c50f7 100644 --- a/code/modules/projectiles/ammunition/bullets.dm +++ b/code/modules/projectiles/ammunition/bullets.dm @@ -16,6 +16,11 @@ /obj/item/ammo_casing/c38 desc = "A .38 bullet casing." caliber = "38" + projectile_type = /obj/item/projectile/bullet/pistol + +/obj/item/ammo_casing/c38r + desc = "A .38 rubber bullet casing." + caliber = "38" projectile_type = /obj/item/projectile/bullet/pistol/rubber /obj/item/ammo_casing/c9mm @@ -23,6 +28,12 @@ caliber = "9mm" projectile_type = /obj/item/projectile/bullet/pistol +/obj/item/ammo_casing/c9mmf + desc = "A 9mm flash shell casing." + caliber = "9mm" + projectile_type = /obj/item/projectile/energy/flash + + /obj/item/ammo_casing/c45 desc = "A .45 bullet casing." caliber = ".45" @@ -73,36 +84,39 @@ projectile_type = /obj/item/projectile/bullet/shotgun/beanbag matter = list("metal" = 500) +//Can stun in one hit if aimed at the head, but +//is blocked by clothing that stops tasers and is vulnerable to EMP /obj/item/ammo_casing/shotgun/stunshell name = "stun shell" desc = "A 12 gauge taser cartridge." icon_state = "stunshell" + spent_icon = "stunshell-spent" projectile_type = /obj/item/projectile/energy/electrode/stunshot matter = list("metal" = 1250, "glass" = 1250) +/obj/item/ammo_casing/shotgun/stunshell/emp_act(severity) + if(prob(100/severity)) BB = null + update_icon() + +//Does not stun, only blinds, but has area of effect. /obj/item/ammo_casing/shotgun/flash name = "flash shell" - desc = "A flash shell used to provide illumination." + desc = "A chemical shell used to signal distress or provide illumination." icon_state = "fshell" projectile_type = /obj/item/projectile/energy/flash/flare matter = list("metal" = 250, "glass" = 250) -/obj/item/ammo_casing/shotgun/dart - name = "shotgun dart" - desc = "A dart for use in shotguns." - icon_state = "dart" - projectile_type = /obj/item/projectile/energy/dart - matter = list("metal" = 12500) - /obj/item/ammo_casing/a762 desc = "A 7.62mm bullet casing." caliber = "a762" projectile_type = /obj/item/projectile/bullet/rifle/a762 /obj/item/ammo_casing/a145 - name = "\improper AP shell casing" + name = "shell casing" desc = "A 14.5mm AP shell." - icon_state = "slshell" + icon_state = "lcasing" + spent_icon = "lcasing-spent" + caliber = "14.5mm" projectile_type = /obj/item/projectile/bullet/rifle/a145 /obj/item/ammo_casing/rocket @@ -118,6 +132,7 @@ projectile_type = /obj/item/projectile/bullet/chameleon caliber = ".45" +/* /obj/item/ammo_casing/a418 desc = "A .418 bullet casing." caliber = "357" @@ -126,4 +141,5 @@ /obj/item/ammo_casing/a666 desc = "A .666 bullet casing." caliber = "357" - projectile_type = /obj/item/projectile/bullet/cyanideround \ No newline at end of file + projectile_type = /obj/item/projectile/bullet/cyanideround +*/ \ No newline at end of file diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index f4bc1175d5..c2d6266473 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -1,3 +1,4 @@ +//Parent gun type. Guns are weapons that can be aimed at mobs and act over a distance /obj/item/weapon/gun name = "gun" desc = "Its a gun. It's pretty terrible, though." @@ -5,59 +6,88 @@ icon_state = "detective" item_state = "gun" flags = CONDUCT - slot_flags = SLOT_BELT + slot_flags = SLOT_BELT|SLOT_HOLSTER matter = list("metal" = 2000) - w_class = 3.0 + w_class = 3 throwforce = 5 throw_speed = 4 throw_range = 5 - force = 5.0 + force = 5 origin_tech = "combat=1" attack_verb = list("struck", "hit", "bashed") + zoomdevicename = "scope" + var/fire_delay = 6 var/fire_sound = 'sound/weapons/Gunshot.ogg' - var/obj/item/projectile/in_chamber = null - var/caliber = "" + var/fire_sound_text = "gunshot" + var/recoil = 0 //screen shake var/silenced = 0 - var/recoil = 0 - var/ejectshell = 1 - var/clumsy_check = 1 - var/tmp/list/mob/living/target //List of who yer targeting. - var/tmp/lock_time = -100 - var/tmp/mouthshoot = 0 ///To stop people from suiciding twice... >.> - var/automatic = 0 //Used to determine if you can target multiple people. + var/accuracy = 0 //accuracy is measured in tiles. +1 accuracy means that everything is effectively one tile closer for the purpose of miss chance, -1 means the opposite. launchers are not supported, at the moment. + var/scoped_accuracy = null + + var/last_fired = 0 + + //aiming system stuff + var/keep_aim = 1 //1 for keep shooting until aim is lowered + //0 for one bullet after tarrget moves and aim is lowered + var/multi_aim = 0 //Used to determine if you can target multiple people. + var/tmp/list/mob/living/aim_targets //List of who yer targeting. var/tmp/mob/living/last_moved_mob //Used to fire faster at more than one person. var/tmp/told_cant_shoot = 0 //So that it doesn't spam them with the fact they cannot hit them. - var/firerate = 0 //0 for keep shooting until aim is lowered - // 1 for one bullet after tarrget moves and aim is lowered - var/fire_delay = 6 - var/last_fired = 0 + var/tmp/lock_time = -100 - proc/ready_to_fire() - if(world.time >= last_fired + fire_delay) - last_fired = world.time - return 1 - else - return 0 +/obj/item/weapon/gun/New() + ..() + if(isnull(scoped_accuracy)) + scoped_accuracy = accuracy - proc/load_into_chamber() +//Returns 1 if the gun is able to be fired +/obj/item/weapon/gun/proc/ready_to_fire() + if(world.time >= last_fired + fire_delay) + last_fired = world.time + return 1 + else return 0 - proc/special_check(var/mob/M) //Placeholder for any special checks, like detective's revolver. - return 1 +//Checks whether a given mob can use the gun +//Any checks that shouldn't result in handle_click_empty() being called if they fail should go here. +//Otherwise, if you want handle_click_empty() to be called, check in consume_next_projectile() and return null there. +/obj/item/weapon/gun/proc/special_check(var/mob/user) + if(!istype(user, /mob/living)) + return 0 + if(!user.IsAdvancedToolUser()) + return 0 + + var/mob/living/M = user + + if(HULK in M.mutations) + M << "Your fingers are much too large for the trigger guard!" + return 0 + if((CLUMSY in M.mutations) && prob(40)) //Clumsy handling + var/obj/P = consume_next_projectile() + if(P) + if(process_projectile(P, user, user, pick("l_foot", "r_foot"))) + handle_post_fire(user, user) + user.visible_message( + "[user] shoots \himself in the foot with \the [src]!", + "You shoot yourself in the foot with \the [src]!" + ) + M.drop_item() + else + handle_click_empty(user) + return 0 + return 1 - emp_act(severity) - for(var/obj/O in contents) - O.emp_act(severity) - -/obj/item/weapon/gun/afterattack(atom/A as mob|obj|turf|area, mob/living/user as mob|obj, flag, params) - if(flag) return //It's adjacent, is the user, or is on the user's person - if(istype(target, /obj/machinery/recharger) && istype(src, /obj/item/weapon/gun/energy)) return//Shouldnt flag take care of this? +/obj/item/weapon/gun/emp_act(severity) + for(var/obj/O in contents) + O.emp_act(severity) +/obj/item/weapon/gun/afterattack(atom/A, mob/living/user, adjacent, params) + if(adjacent) return //A is adjacent, is the user, or is on the user's person //decide whether to aim or shoot normally var/aiming = 0 - if(user && user.client && !(A in target)) + if(user && user.client && !(A in aim_targets)) var/client/C = user.client //If help intent is on and we have clicked on an eligible target, switch to aim mode automatically if(user.a_intent == "help" && isliving(A) && !C.gun_mode) @@ -72,30 +102,16 @@ else Fire(A,user,params) //Otherwise, fire normally. -/obj/item/weapon/gun/proc/isHandgun() - return 1 +/obj/item/weapon/gun/attack(atom/A, mob/living/user, def_zone) + if (A == user && user.zone_sel.selecting == "mouth" && !mouthshoot) + handle_suicide(user) + else if(user.a_intent == "hurt") //point blank shooting + Fire(A, user, pointblank=1) + else + return ..() //Pistolwhippin' -/obj/item/weapon/gun/proc/Fire(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, params, reflex = 0)//TODO: go over this - //Exclude lasertag guns from the CLUMSY check. - if(!user) return - - if(clumsy_check) - if(istype(user, /mob/living)) - var/mob/living/M = user - if ((CLUMSY in M.mutations) && prob(50)) - M << "[src] blows up in your face." - M.take_organ_damage(0,20) - M.drop_item() - del(src) - return - - if (!user.IsAdvancedToolUser()) - return - if(istype(user, /mob/living)) - var/mob/living/M = user - if (HULK in M.mutations) - M << "Your fingers are much too large for the trigger guard!" - return +/obj/item/weapon/gun/proc/Fire(atom/target, mob/living/user, params, pointblank=0, reflex=0) + if(!user || !target) return add_fingerprint(user) @@ -107,22 +123,68 @@ user << "[src] is not ready to fire again!" return - if(!load_into_chamber()) //CHECK - return click_empty(user) - - if(!in_chamber) + var/obj/projectile = consume_next_projectile(user) + if(!projectile) + handle_click_empty(user) return + user.next_move = world.time + 4 + + if(process_projectile(projectile, user, target, user.zone_sel.selecting, params, pointblank, reflex)) + handle_post_fire(user, target, pointblank, reflex) + + update_icon() + if(user.hand) + user.update_inv_l_hand() + else + user.update_inv_r_hand() + + +//obtains the next projectile to fire +/obj/item/weapon/gun/proc/consume_next_projectile() + return null + +//used by aiming code +/obj/item/weapon/gun/proc/can_hit(atom/target as mob, var/mob/living/user as mob) + if(!special_check(user)) + return 2 + //just assume we can shoot through glass and stuff. No big deal, the player can just choose to not target someone + //on the other side of a window if it makes a difference. Or if they run behind a window, too bad. + return check_trajectory(target, user) + +//called if there was no projectile to shoot +/obj/item/weapon/gun/proc/handle_click_empty(mob/user) + if (user) + user.visible_message("*click click*", "*click*") + else + src.visible_message("*click click*") + playsound(src.loc, 'sound/weapons/empty.ogg', 100, 1) + +//called after successfully firing +/obj/item/weapon/gun/proc/handle_post_fire(mob/user, atom/target, var/pointblank=0, var/reflex=0) if(silenced) playsound(user, fire_sound, 10, 1) else playsound(user, fire_sound, 50, 1) - user.visible_message("[user] fires [src][reflex ? " by reflex":""]!", \ - "You fire [src][reflex ? "by reflex":""]!", \ - "You hear a [istype(in_chamber, /obj/item/projectile/beam) ? "laser blast" : "gunshot"]!") - - user.next_move = world.time + 4 + user.visible_message( + "[user] fires [src][pointblank ? " point blank at [target]":""][reflex ? " by reflex":""]!", + "You fire [src][reflex ? "by reflex":""]!", + "You hear a [fire_sound_text]!" + ) + if(recoil) + spawn() + shake_camera(user, recoil+1, recoil) + update_icon() + +//does the actual shooting +/obj/item/weapon/gun/proc/process_projectile(obj/projectile, mob/user, atom/target, var/target_zone, var/params=null, var/pointblank=0, var/reflex=0) + if(!istype(projectile, /obj/item/projectile)) + return 0 //default behaviour only applies to true projectiles + + var/obj/item/projectile/P = projectile + + //shooting while in shock var/x_offset = 0 var/y_offset = 0 if(istype(user, /mob/living/carbon)) @@ -134,101 +196,68 @@ y_offset = rand(-1,1) x_offset = rand(-1,1) - var/p_x - var/p_y + //Point blank bonus + if(pointblank) P.damage *= 1.3 + + //TODO: accuracy modifiers + if(params) - var/list/mouse_control = params2list(params) - if(mouse_control["icon-x"]) - p_x = text2num(mouse_control["icon-x"]) - if(mouse_control["icon-y"]) - p_y = text2num(mouse_control["icon-y"]) + P.set_clickpoint(params) + + return !P.launch(target, user, src, target_zone, x_offset, y_offset) + +//Suicide handling. +/obj/item/weapon/gun/var/mouthshoot = 0 //To stop people from suiciding twice... >.> +/obj/item/weapon/gun/proc/handle_suicide(mob/living/user) + if(!ishuman(user)) + return + var/mob/living/carbon/human/M = user - if(in_chamber) - var/fail = in_chamber.launch( - target = target, - user = user, - launcher = src, - target_zone = user.zone_sel.selecting, - x_offset = x_offset, - y_offset = y_offset, - px = p_x, - py = p_y - ) - - if(fail) return - - if(recoil) - spawn() - shake_camera(user, recoil + 1, recoil) - - sleep(1) - in_chamber = null - - update_icon() - - if(user.hand) - user.update_inv_l_hand() - else - user.update_inv_r_hand() - -/obj/item/weapon/gun/proc/can_fire() - return load_into_chamber() - -/obj/item/weapon/gun/proc/can_hit(var/mob/living/target as mob, var/mob/living/user as mob) - return in_chamber.check_fire(target,user) - -/obj/item/weapon/gun/proc/click_empty(mob/user = null) - if (user) - user.visible_message("*click click*", "\red *click*") - playsound(user, 'sound/weapons/empty.ogg', 100, 1) - else - src.visible_message("*click click*") - playsound(src.loc, 'sound/weapons/empty.ogg', 100, 1) - -/obj/item/weapon/gun/attack(mob/living/M as mob, mob/living/user as mob, def_zone) - //Suicide handling. - if (M == user && user.zone_sel.selecting == "mouth" && !mouthshoot) - mouthshoot = 1 - M.visible_message("\red [user] sticks their gun in their mouth, ready to pull the trigger...") - if(!do_after(user, 40)) - M.visible_message("\blue [user] decided life was worth living") - mouthshoot = 0 - return - if (load_into_chamber()) - user.visible_message("[user] pulls the trigger.") - if(silenced) - playsound(user, fire_sound, 10, 1) - else - playsound(user, fire_sound, 50, 1) - if(istype(in_chamber, /obj/item/projectile/beam/lastertag)) - user.show_message("You feel rather silly, trying to commit suicide with a toy.") - mouthshoot = 0 - return - - in_chamber.on_hit(M) - if (in_chamber.damage_type != HALLOSS) - user.apply_damage(in_chamber.damage*2.5, in_chamber.damage_type, "head", used_weapon = "Point blank shot in the mouth with \a [in_chamber]", sharp=1) - user.death() - else - user << "Ow..." - user.apply_effect(110,AGONY,0) - del(in_chamber) - mouthshoot = 0 - return + mouthshoot = 1 + M.visible_message("\red [user] sticks their gun in their mouth, ready to pull the trigger...") + if(!do_after(user, 40)) + M.visible_message("\blue [user] decided life was worth living") + mouthshoot = 0 + return + var/obj/item/projectile/in_chamber = consume_next_projectile() + if (istype(in_chamber)) + user.visible_message("[user] pulls the trigger.") + if(silenced) + playsound(user, fire_sound, 10, 1) else - click_empty(user) + playsound(user, fire_sound, 50, 1) + if(istype(in_chamber, /obj/item/projectile/beam/lastertag)) + user.show_message("You feel rather silly, trying to commit suicide with a toy.") mouthshoot = 0 return - if (load_into_chamber()) - //Point blank shooting if on harm intent or target we were targeting. - if(user.a_intent == "hurt") - user.visible_message("\red \The [user] fires \the [src] point blank at [M]!") - if(istype(in_chamber)) in_chamber.damage *= 1.3 - Fire(M,user) - return - else if(target && M in target) - Fire(M,user) ///Otherwise, shoot! - return + in_chamber.on_hit(M) + if (in_chamber.damage_type != HALLOSS) + user.apply_damage(in_chamber.damage*2.5, in_chamber.damage_type, "head", used_weapon = "Point blank shot in the mouth with \a [in_chamber]", sharp=1) + user.death() + else + user << "Ow..." + user.apply_effect(110,AGONY,0) + del(in_chamber) + mouthshoot = 0 + return else - return ..() //Pistolwhippin' + handle_click_empty(user) + mouthshoot = 0 + return + +/obj/item/weapon/gun/proc/toggle_scope(var/zoom_amount=2.0) + //looking through a scope limits your periphereal vision + //still, increase the view size by a tiny amount so that sniping isn't too restricted to NSEW + var/zoom_offset = round(world.view * zoom_amount) + var/view_size = round(world.view + zoom_amount) + var/scoped_accuracy_mod = zoom_offset + + zoom(zoom_offset, view_size) + if(zoom) + accuracy = scoped_accuracy + scoped_accuracy_mod + if(recoil) + recoil = round(recoil*zoom_amount+1) //recoil is worse when looking through a scope + else + accuracy = (accuracy) + recoil = initial(recoil) diff --git a/code/modules/projectiles/guns/alien.dm b/code/modules/projectiles/guns/alien.dm index f9af71acc8..797d0b07c2 100644 --- a/code/modules/projectiles/guns/alien.dm +++ b/code/modules/projectiles/guns/alien.dm @@ -1,6 +1,6 @@ //Vox pinning weapon. /obj/item/weapon/gun/launcher/spikethrower - name = "Vox spike thrower" + name = "vox spike thrower" desc = "A vicious alien projectile weapon. Parts of it quiver gelatinously, as though the thing is insectile and alive." var/last_regen = 0 @@ -24,7 +24,6 @@ ..() /obj/item/weapon/gun/launcher/spikethrower/process() - if(spikes < max_spikes && world.time > last_regen + spike_gen_time) spikes++ last_regen = world.time @@ -32,35 +31,26 @@ /obj/item/weapon/gun/launcher/spikethrower/examine(mob/user) ..(user) - user << "It has [spikes] [spikes == 1 ? "spike" : "spikes"] remaining." + user << "It has [spikes] spike\s remaining." /obj/item/weapon/gun/launcher/spikethrower/update_icon() icon_state = "spikethrower[spikes]" -/obj/item/weapon/gun/launcher/spikethrower/emp_act(severity) - return - /obj/item/weapon/gun/launcher/spikethrower/special_check(user) if(istype(user,/mob/living/carbon/human)) var/mob/living/carbon/human/H = user if(H.species && H.species.name != "Vox" && H.species.name != "Vox Armalis") - user << "\red \The [src] does not respond to you!" + user << "\The [src] does not respond to you!" return 0 - return 1 + return ..() /obj/item/weapon/gun/launcher/spikethrower/update_release_force() return -/obj/item/weapon/gun/launcher/spikethrower/load_into_chamber() - if(in_chamber) return 1 - if(spikes < 1) return 0 - +/obj/item/weapon/gun/launcher/spikethrower/consume_next_projectile() + if(spikes < 1) return null spikes-- - in_chamber = new /obj/item/weapon/spike(src) - return 1 - -/obj/item/weapon/gun/launcher/spikethrower/Fire(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, params, reflex = 0) - if(..()) update_icon() + return new /obj/item/weapon/spike(src) //This gun only functions for armalis. The on-sprite is too huge to render properly on other sprites. /obj/item/weapon/gun/energy/noisecannon @@ -74,7 +64,7 @@ force = 10 projectile_type = /obj/item/projectile/energy/sonic - cell_type = "/obj/item/weapon/cell/super" + cell_type = /obj/item/weapon/cell/super fire_delay = 40 fire_sound = 'sound/effects/basscannon.ogg' @@ -91,13 +81,9 @@ if(H.species.name == "Vox Armalis") ..() return - user << "\red \The [src] is far too large for you to pick up." + user << "\The [src] is far too large for you to pick up." return -/obj/item/weapon/gun/energy/noisecannon/load_into_chamber() //Does not have ammo. - in_chamber = new projectile_type(src) - return 1 - /obj/item/weapon/gun/energy/noisecannon/update_icon() return @@ -108,7 +94,7 @@ icon_state = "particle" damage = 60 damage_type = BRUTE - flag = "bullet" + check_armour = "bullet" pass_flags = PASSTABLE | PASSGLASS | PASSGRILLE embed = 0 diff --git a/code/modules/projectiles/guns/energy.dm b/code/modules/projectiles/guns/energy.dm index 0ed82e9f4a..3cd90347f9 100644 --- a/code/modules/projectiles/guns/energy.dm +++ b/code/modules/projectiles/guns/energy.dm @@ -3,39 +3,78 @@ desc = "A basic energy-based gun." icon_state = "energy" fire_sound = 'sound/weapons/Taser.ogg' + fire_sound_text = "laser blast" var/obj/item/weapon/cell/power_supply //What type of power cell this uses var/charge_cost = 100 //How much energy is needed to fire. - var/cell_type = "/obj/item/weapon/cell" + var/cell_type = /obj/item/weapon/cell var/projectile_type = /obj/item/projectile/beam/practice var/modifystate + var/charge_meter = 1 //if set, the icon state will be chosen based on the current charge + + //self-recharging + var/self_recharge = 0 //if set, the weapon will recharge itself + var/use_external_power = 0 //if set, the weapon will look for an external power source to draw from, otherwise it recharges magically + var/recharge_time = 4 + var/charge_tick = 0 - emp_act(severity) - power_supply.use(round(power_supply.maxcharge / severity)) - update_icon() - ..() - - - New() - ..() - if(cell_type) - power_supply = new cell_type(src) - else - power_supply = new(src) - power_supply.give(power_supply.maxcharge) - return - - - load_into_chamber() - if(in_chamber) return 1 - if(!power_supply) return 0 - if(!power_supply.use(charge_cost)) return 0 - if(!ispath(projectile_type)) return 0 - in_chamber = new projectile_type(src) - return 1 - - +/obj/item/weapon/gun/energy/emp_act(severity) + ..() update_icon() + +/obj/item/weapon/gun/energy/New() + ..() + if(cell_type) + power_supply = new cell_type(src) + power_supply.give(power_supply.maxcharge) + if(self_recharge) + processing_objects.Add(src) + +/obj/item/weapon/gun/energy/Del() + if(self_recharge) + processing_objects.Remove(src) + ..() + +/obj/item/weapon/gun/energy/process() + if(self_recharge) //Every [recharge_time] ticks, recharge a shot for the cyborg + charge_tick++ + if(charge_tick < recharge_time) return 0 + charge_tick = 0 + + if(!power_supply || power_supply.charge >= power_supply.maxcharge) + 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... + return 0 + + power_supply.give(charge_cost) //... to recharge the shot + update_icon() + return 1 + +/obj/item/weapon/gun/energy/consume_next_projectile() + if(!power_supply) return null + if(!ispath(projectile_type)) return null + if(!power_supply.use(charge_cost)) return null + return new projectile_type(src) + +/obj/item/weapon/gun/energy/proc/get_external_power_supply() + if(isrobot(src.loc)) + var/mob/living/silicon/robot/R = src.loc + return R.cell + if(istype(src.loc, /obj/item/rig_module)) + var/obj/item/rig_module/module = src.loc + if(module.holder && module.holder.wearer) + var/mob/living/carbon/human/H = module.holder.wearer + if(istype(H) && H.back) + var/obj/item/weapon/rig/suit = H.back + if(istype(suit)) + return suit.cell + return null + +/obj/item/weapon/gun/energy/update_icon() + if(charge_meter) var/ratio = power_supply.charge / power_supply.maxcharge ratio = round(ratio, 0.25) * 100 if(modifystate) diff --git a/code/modules/projectiles/guns/energy/laser.dm b/code/modules/projectiles/guns/energy/laser.dm index 40a4b06689..2dc1cb65e2 100644 --- a/code/modules/projectiles/guns/energy/laser.dm +++ b/code/modules/projectiles/guns/energy/laser.dm @@ -4,89 +4,53 @@ icon_state = "laser" item_state = "laser" fire_sound = 'sound/weapons/Laser.ogg' - w_class = 3.0 + slot_flags = SLOT_BELT|SLOT_BACK + w_class = 3 + force = 10 //it has a stock, might as well give some kind of perk over the egun matter = list("metal" = 2000) origin_tech = "combat=3;magnets=2" projectile_type = /obj/item/projectile/beam +/obj/item/weapon/gun/energy/laser/mounted + self_recharge = 1 + use_external_power = 1 + /obj/item/weapon/gun/energy/laser/practice name = "practice laser gun" desc = "A modified version of the basic laser gun, this one fires less concentrated energy bolts designed for target practice." projectile_type = /obj/item/projectile/beam/practice - clumsy_check = 0 obj/item/weapon/gun/energy/laser/retro name = "retro laser" icon_state = "retro" desc = "An older model of the basic lasergun, no longer used by Nanotrasen's security or military forces. Nevertheless, it is still quite deadly and easy to maintain, making it a favorite amongst pirates and other outlaws." - -/obj/item/weapon/gun/energy/laser/captain +/obj/item/weapon/gun/energy/captain name = "antique laser gun" icon_state = "caplaser" desc = "This is an antique laser gun. All craftsmanship is of the highest quality. It is decorated with assistant leather and chrome. The object menaces with spikes of energy. On the item is an image of Space Station 13. The station is exploding." - force = 10 + force = 5 + slot_flags = SLOT_BELT origin_tech = null - var/charge_tick = 0 - - - New() - ..() - processing_objects.Add(src) - - - Del() - processing_objects.Remove(src) - ..() - - - process() - charge_tick++ - if(charge_tick < 4) return 0 - charge_tick = 0 - if(!power_supply) return 0 - power_supply.give(100) - update_icon() - return 1 - - - -/obj/item/weapon/gun/energy/laser/cyborg/load_into_chamber() - if(in_chamber) - return 1 - if(isrobot(src.loc)) - var/mob/living/silicon/robot/R = src.loc - if(R && R.cell) - R.cell.use(100) - in_chamber = new/obj/item/projectile/beam(src) - return 1 - return 0 - + self_recharge = 1 /obj/item/weapon/gun/energy/lasercannon name = "laser cannon" - desc = "With the L.A.S.E.R. cannon, the lasing medium is enclosed in a tube lined with uranium-235 and subjected to high neutron flux in a nuclear reactor core. This incredible technology may help YOU achieve high excitation rates with small laser volumes!" + desc = "With the laser cannon, the lasing medium is enclosed in a tube lined with uranium-235 and subjected to high neutron flux in a nuclear reactor core. This incredible technology may help YOU achieve high excitation rates with small laser volumes!" icon_state = "lasercannon" + item_state = "laser" fire_sound = 'sound/weapons/lasercannonfire.ogg' origin_tech = "combat=4;materials=3;powerstorage=3" - projectile_type = "/obj/item/projectile/beam/heavylaser" - + slot_flags = SLOT_BELT|SLOT_BACK + projectile_type = /obj/item/projectile/beam/heavylaser + charge_cost = 250 fire_delay = 20 - isHandgun() - return 0 - -/obj/item/weapon/gun/energy/lasercannon/cyborg/load_into_chamber() - if(in_chamber) - return 1 - if(isrobot(src.loc)) - var/mob/living/silicon/robot/R = src.loc - if(R && R.cell) - R.cell.use(250) - in_chamber = new/obj/item/projectile/beam/heavylaser(src) - return 1 - return 0 +/obj/item/weapon/gun/energy/lasercannon/mounted + self_recharge = 1 + use_external_power = 1 + recharge_time = 25 /obj/item/weapon/gun/energy/xray name = "xray laser gun" @@ -94,80 +58,58 @@ obj/item/weapon/gun/energy/laser/retro icon_state = "xray" fire_sound = 'sound/weapons/laser3.ogg' origin_tech = "combat=5;materials=3;magnets=2;syndicate=2" - projectile_type = "/obj/item/projectile/beam/xray" + projectile_type = /obj/item/projectile/beam/xray charge_cost = 50 +/obj/item/weapon/gun/energy/sniperrifle + name = "\improper L.W.A.P. sniper rifle" + desc = "A high-power laser rifle fitted with a SMART aiming-system scope." + icon_state = "sniper" + item_state = "laser" + fire_sound = 'sound/weapons/marauder.ogg' + origin_tech = "combat=6;materials=5;powerstorage=4" + projectile_type = /obj/item/projectile/beam/sniper + slot_flags = SLOT_BACK + charge_cost = 250 + fire_delay = 35 + force = 10 + w_class = 4 + accuracy = -3 //shooting at the hip + scoped_accuracy = 0 + +/obj/item/weapon/gun/energy/sniperrifle/verb/scope() + set category = "Object" + set name = "Use Scope" + set popup_menu = 1 + + toggle_scope(2.0) ////////Laser Tag//////////////////// -/obj/item/weapon/gun/energy/laser/bluetag +/obj/item/weapon/gun/energy/lasertag name = "laser tag gun" + item_state = "laser" + desc = "Standard issue weapon of the Imperial Guard" + origin_tech = "combat=1;magnets=2" + self_recharge = 1 + matter = list("metal" = 2000) + fire_sound = 'sound/weapons/Laser.ogg' + projectile_type = /obj/item/projectile/beam/lastertag/blue + var/required_vest + +/obj/item/weapon/gun/energy/lasertag/special_check(var/mob/living/carbon/human/M) + if(ishuman(M)) + if(!istype(M.wear_suit, required_vest)) + M << "You need to be wearing your laser tag vest!" + return 0 + return ..() + +/obj/item/weapon/gun/energy/lasertag/blue icon_state = "bluetag" - desc = "Standard issue weapon of the Imperial Guard" - projectile_type = "/obj/item/projectile/beam/lastertag/blue" - origin_tech = "combat=1;magnets=2" - clumsy_check = 0 - var/charge_tick = 0 + projectile_type = /obj/item/projectile/beam/lastertag/blue + required_vest = /obj/item/clothing/suit/bluetag - special_check(var/mob/living/carbon/human/M) - if(ishuman(M)) - if(istype(M.wear_suit, /obj/item/clothing/suit/bluetag)) - return 1 - M << "\red You need to be wearing your laser tag vest!" - return 0 - - New() - ..() - processing_objects.Add(src) - - - Del() - processing_objects.Remove(src) - ..() - - - process() - charge_tick++ - if(charge_tick < 4) return 0 - charge_tick = 0 - if(!power_supply) return 0 - power_supply.give(100) - update_icon() - return 1 - - - -/obj/item/weapon/gun/energy/laser/redtag - name = "laser tag gun" +/obj/item/weapon/gun/energy/lasertag/red icon_state = "redtag" - desc = "Standard issue weapon of the Imperial Guard" - projectile_type = "/obj/item/projectile/beam/lastertag/red" - origin_tech = "combat=1;magnets=2" - clumsy_check = 0 - var/charge_tick = 0 - - special_check(var/mob/living/carbon/human/M) - if(ishuman(M)) - if(istype(M.wear_suit, /obj/item/clothing/suit/redtag)) - return 1 - M << "\red You need to be wearing your laser tag vest!" - return 0 - - New() - ..() - processing_objects.Add(src) - - - Del() - processing_objects.Remove(src) - ..() - - - process() - charge_tick++ - if(charge_tick < 4) return 0 - charge_tick = 0 - if(!power_supply) return 0 - power_supply.give(100) - update_icon() - return 1 + projectile_type = /obj/item/projectile/beam/lastertag/red + required_vest = /obj/item/clothing/suit/redtag diff --git a/code/modules/projectiles/guns/energy/nuclear.dm b/code/modules/projectiles/guns/energy/nuclear.dm index abfd7510a4..e2b97672c7 100644 --- a/code/modules/projectiles/guns/energy/nuclear.dm +++ b/code/modules/projectiles/guns/energy/nuclear.dm @@ -1,6 +1,6 @@ /obj/item/weapon/gun/energy/gun name = "energy gun" - desc = "A basic energy-based gun with two settings: Stun and kill." + desc = "An energy-based gun with two settings: Stun and kill." icon_state = "energystun100" item_state = null //so the human update icon uses the icon_state instead. fire_sound = 'sound/weapons/Taser.ogg' @@ -12,118 +12,108 @@ var/mode = 0 //0 = stun, 1 = kill +/obj/item/weapon/gun/energy/gun/attack_self(mob/living/user as mob) + switch(mode) + if(0) + mode = 1 + charge_cost = 100 + fire_sound = 'sound/weapons/Laser.ogg' + user << "[src.name] is now set to kill." + projectile_type = /obj/item/projectile/beam + modifystate = "energykill" + if(1) + mode = 0 + charge_cost = 100 + fire_sound = 'sound/weapons/Taser.ogg' + user << "[src.name] is now set to stun." + projectile_type = /obj/item/projectile/beam/stun + modifystate = "energystun" + update_icon() + if(user.l_hand == src) + user.update_inv_l_hand() + else + user.update_inv_r_hand() - attack_self(mob/living/user as mob) - switch(mode) - if(0) - mode = 1 - charge_cost = 100 - fire_sound = 'sound/weapons/Laser.ogg' - user << "\red [src.name] is now set to kill." - projectile_type = /obj/item/projectile/beam - modifystate = "energykill" - if(1) - mode = 0 - charge_cost = 100 - fire_sound = 'sound/weapons/Taser.ogg' - user << "\red [src.name] is now set to stun." - projectile_type = /obj/item/projectile/beam/stun - modifystate = "energystun" - update_icon() - if(user.l_hand == src) - user.update_inv_l_hand() - else - user.update_inv_r_hand() +/obj/item/weapon/gun/energy/gun/mounted + self_recharge = 1 + use_external_power = 1 /obj/item/weapon/gun/energy/gun/nuclear name = "advanced energy gun" desc = "An energy gun with an experimental miniaturized reactor." icon_state = "nucgun" - origin_tech = "combat=3;materials=5;powerstorage=3" + origin_tech = "combat=3;materials=5;powerstorage=3" + slot_flags = SLOT_BELT + force = 8 //looks heavier than a pistol + self_recharge = 1 var/lightfail = 0 - var/charge_tick = 0 - New() - ..() - processing_objects.Add(src) +//override for failcheck behaviour +/obj/item/weapon/gun/energy/gun/nuclear/process() + charge_tick++ + if(charge_tick < 4) return 0 + charge_tick = 0 + if(!power_supply) return 0 + if((power_supply.charge / power_supply.maxcharge) != 1) + if(!failcheck()) return 0 + power_supply.give(charge_cost) + update_icon() + return 1 - - Del() +/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 + 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 processing_objects.Remove(src) - ..() + update_icon() + return 0 - process() - charge_tick++ - if(charge_tick < 4) return 0 - charge_tick = 0 - if(!power_supply) return 0 - if((power_supply.charge / power_supply.maxcharge) != 1) - if(!failcheck()) return 0 - power_supply.give(100) - update_icon() - return 1 +/obj/item/weapon/gun/energy/gun/nuclear/proc/update_charge() + if (crit_fail) + overlays += "nucgun-whee" + return + var/ratio = power_supply.charge / power_supply.maxcharge + ratio = round(ratio, 0.25) * 100 + overlays += "nucgun-[ratio]" +/obj/item/weapon/gun/energy/gun/nuclear/proc/update_reactor() + if(crit_fail) + overlays += "nucgun-crit" + return + if(lightfail) + overlays += "nucgun-medium" + else if ((power_supply.charge/power_supply.maxcharge) <= 0.5) + overlays += "nucgun-light" + else + overlays += "nucgun-clean" - 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 << "\red Your gun feels pleasantly warm for a moment." - else - M << "\red You feel a warm sensation." - M.apply_effect(rand(3,120), IRRADIATE) - lightfail = 1 - else - for (var/mob/living/M in range(rand(1,4),src)) //Big failure, TIME FOR RADIATION BITCHES - if (src in M.contents) - M << "\red Your gun's reactor overloads!" - M << "\red You feel a wave of heat wash over you." - M.apply_effect(300, IRRADIATE) - crit_fail = 1 //break the gun so it stops recharging - processing_objects.Remove(src) - update_icon() - return 0 +/obj/item/weapon/gun/energy/gun/nuclear/proc/update_mode() + if (mode == 0) + overlays += "nucgun-stun" + else if (mode == 1) + overlays += "nucgun-kill" +/obj/item/weapon/gun/energy/gun/nuclear/emp_act(severity) + ..() + reliability -= round(15/severity) - update_charge() - if (crit_fail) - overlays += "nucgun-whee" - return - var/ratio = power_supply.charge / power_supply.maxcharge - ratio = round(ratio, 0.25) * 100 - overlays += "nucgun-[ratio]" - - - update_reactor() - if(crit_fail) - overlays += "nucgun-crit" - return - if(lightfail) - overlays += "nucgun-medium" - else if ((power_supply.charge/power_supply.maxcharge) <= 0.5) - overlays += "nucgun-light" - else - overlays += "nucgun-clean" - - - update_mode() - if (mode == 0) - overlays += "nucgun-stun" - else if (mode == 1) - overlays += "nucgun-kill" - - - emp_act(severity) - ..() - reliability -= round(15/severity) - - - update_icon() - overlays.Cut() - update_charge() - update_reactor() - update_mode() +/obj/item/weapon/gun/energy/gun/nuclear/update_icon() + overlays.Cut() + update_charge() + update_reactor() + update_mode() diff --git a/code/modules/projectiles/guns/energy/pulse.dm b/code/modules/projectiles/guns/energy/pulse.dm index f9644779fc..82ab47438b 100644 --- a/code/modules/projectiles/guns/energy/pulse.dm +++ b/code/modules/projectiles/guns/energy/pulse.dm @@ -1,70 +1,57 @@ /obj/item/weapon/gun/energy/pulse_rifle name = "pulse rifle" - desc = "A heavy-duty, pulse-based energy weapon, preferred by front-line combat personnel." + desc = "A weapon that uses advanced pulse-based beam generation technology to emit powerful laser blasts. Because of its complexity and cost, it is rarely seen in use except by specialists." icon_state = "pulse" item_state = null //so the human update icon uses the icon_state instead. + slot_flags = SLOT_BELT|SLOT_BACK force = 10 fire_sound = 'sound/weapons/pulse.ogg' charge_cost = 200 projectile_type = /obj/item/projectile/beam/pulse - cell_type = "/obj/item/weapon/cell/super" + cell_type = /obj/item/weapon/cell/super var/mode = 2 fire_delay = 25 - attack_self(mob/living/user as mob) - switch(mode) - if(2) - mode = 0 - charge_cost = 100 - fire_sound = 'sound/weapons/Taser.ogg' - user << "\red \The [src] is now set to stun." - projectile_type = /obj/item/projectile/beam/stun - if(0) - mode = 1 - charge_cost = 100 - fire_sound = 'sound/weapons/Laser.ogg' - user << "\red \The [src] is now set to kill." - projectile_type = /obj/item/projectile/beam - if(1) - mode = 2 - charge_cost = 200 - fire_sound = 'sound/weapons/pulse.ogg' - user << "\red \The [name] is now set to DESTROY." - projectile_type = /obj/item/projectile/beam/pulse - return - - isHandgun() - return 0 - -/obj/item/weapon/gun/energy/pulse_rifle/cyborg/load_into_chamber() - if(in_chamber) - return 1 - if(isrobot(src.loc)) - var/mob/living/silicon/robot/R = src.loc - if(R && R.cell) - R.cell.use(charge_cost) - in_chamber = new/obj/item/projectile/beam(src) - return 1 - return 0 +/obj/item/weapon/gun/energy/pulse_rifle/attack_self(mob/living/user as mob) + switch(mode) + if(2) + mode = 0 + charge_cost = 100 + fire_sound = 'sound/weapons/Taser.ogg' + user << "[src.name] is now set to stun." + projectile_type = /obj/item/projectile/beam/stun + if(0) + mode = 1 + charge_cost = 100 + fire_sound = 'sound/weapons/Laser.ogg' + user << "[src.name] is now set to kill." + projectile_type = /obj/item/projectile/beam + if(1) + mode = 2 + charge_cost = 200 + fire_sound = 'sound/weapons/pulse.ogg' + user << "[src.name] is now set to DESTROY." + projectile_type = /obj/item/projectile/beam/pulse +/obj/item/weapon/gun/energy/pulse_rifle/mounted + self_recharge = 1 + use_external_power = 1 /obj/item/weapon/gun/energy/pulse_rifle/destroyer name = "pulse destroyer" - desc = "A heavy-duty, pulse-based energy weapon." - cell_type = "/obj/item/weapon/cell/infinite" + desc = "A heavy-duty, pulse-based energy weapon. Because of its complexity and cost, it is rarely seen in use except by specialists." + cell_type = /obj/item/weapon/cell/infinite fire_delay = 10 - attack_self(mob/living/user as mob) - user << "\red \The [src] has three settings, and they are all DESTROY." - +/obj/item/weapon/gun/energy/pulse_rifle/destroyer/attack_self(mob/living/user as mob) + user << "[src.name] has three settings, and they are all DESTROY." +//WHY? /obj/item/weapon/gun/energy/pulse_rifle/M1911 name = "\improper M1911-P" desc = "It's not the size of the gun, it's the size of the hole it puts through people." + slot_flags = SLOT_BELT|SLOT_HOLSTER icon_state = "m1911-p" - cell_type = "/obj/item/weapon/cell/infinite" + cell_type = /obj/item/weapon/cell/infinite fire_delay = 10 - - isHandgun() - return 1 diff --git a/code/modules/projectiles/guns/energy/special.dm b/code/modules/projectiles/guns/energy/special.dm index d1e11d7942..112a33e387 100644 --- a/code/modules/projectiles/guns/energy/special.dm +++ b/code/modules/projectiles/guns/energy/special.dm @@ -5,17 +5,16 @@ fire_sound = 'sound/weapons/Laser.ogg' origin_tech = "combat=2;magnets=4" w_class = 4.0 + force = 10 flags = CONDUCT slot_flags = SLOT_BACK charge_cost = 100 - projectile_type = "/obj/item/projectile/ion" + projectile_type = /obj/item/projectile/ion /obj/item/weapon/gun/energy/ionrifle/emp_act(severity) - if(severity <= 2) - power_supply.use(round(power_supply.maxcharge / severity)) - update_icon() - else - return + if(severity > 2) + return //so it doesn't EMP itself, I guess + ..() /obj/item/weapon/gun/energy/decloner name = "biological demolecularisor" @@ -24,9 +23,89 @@ fire_sound = 'sound/weapons/pulse3.ogg' origin_tech = "combat=5;materials=4;powerstorage=3" charge_cost = 100 - projectile_type = "/obj/item/projectile/energy/declone" + projectile_type = /obj/item/projectile/energy/declone -obj/item/weapon/gun/energy/staff +/obj/item/weapon/gun/energy/floragun + name = "floral somatoray" + desc = "A tool that discharges controlled radiation which induces mutation in plant cells." + icon_state = "floramut100" + item_state = "obj/item/gun.dmi" + fire_sound = 'sound/effects/stealthoff.ogg' + charge_cost = 100 + projectile_type = /obj/item/projectile/energy/floramut + origin_tech = "materials=2;biotech=3;powerstorage=3" + modifystate = "floramut" + self_recharge = 1 + var/mode = 0 //0 = mutate, 1 = yield boost + +/obj/item/weapon/gun/energy/floragun/attack_self(mob/living/user as mob) + switch(mode) + if(0) + mode = 1 + charge_cost = 100 + user << "The [src.name] is now set to increase yield." + projectile_type = /obj/item/projectile/energy/florayield + modifystate = "florayield" + if(1) + mode = 0 + charge_cost = 100 + user << "The [src.name] is now set to induce mutations." + projectile_type = /obj/item/projectile/energy/floramut + modifystate = "floramut" + update_icon() + return + +/obj/item/weapon/gun/energy/floragun/afterattack(obj/target, mob/user, adjacent_flag) + //allow shooting into adjacent hydrotrays regardless of intent + if(adjacent_flag && istype(target,/obj/machinery/portable_atmospherics/hydroponics)) + user.visible_message("\The [user] fires \the [src] into \the [target]!") + Fire(target,user) + return + ..() + +/obj/item/weapon/gun/energy/meteorgun + name = "meteor gun" + desc = "For the love of god, make sure you're aiming this the right way!" + icon_state = "riotgun" + item_state = "c20r" + slot_flags = SLOT_BELT|SLOT_BACK + w_class = 4 + projectile_type = /obj/item/projectile/meteor + charge_cost = 100 + cell_type = /obj/item/weapon/cell/potato + self_recharge = 1 + recharge_time = 5 //Time it takes for shots to recharge (in ticks) + charge_meter = 0 + +/obj/item/weapon/gun/energy/meteorgun/pen + name = "meteor pen" + desc = "The pen is mightier than the sword." + icon = 'icons/obj/bureaucracy.dmi' + icon_state = "pen" + item_state = "pen" + w_class = 1 + slot_flags = SLOT_BELT + + +/obj/item/weapon/gun/energy/mindflayer + name = "mind flayer" + desc = "A prototype weapon recovered from the ruins of Research-Station Epsilon." + icon_state = "xray" + projectile_type = /obj/item/projectile/beam/mindflayer + fire_sound = 'sound/weapons/Laser.ogg' + +/obj/item/weapon/gun/energy/toxgun + name = "phoron pistol" + desc = "A specialized firearm designed to fire lethal bolts of phoron." + icon_state = "toxgun" + fire_sound = 'sound/effects/stealthoff.ogg' + w_class = 3.0 + origin_tech = "combat=5;phorontech=4" + projectile_type = /obj/item/projectile/energy/phoron + +/* Staves */ + +/obj/item/weapon/gun/energy/staff name = "staff of change" desc = "An artefact that spits bolts of coruscating energy which cause the target's very form to reshape itself" icon = 'icons/obj/gun.dmi' @@ -37,209 +116,51 @@ obj/item/weapon/gun/energy/staff slot_flags = SLOT_BACK w_class = 4.0 charge_cost = 200 - projectile_type = "/obj/item/projectile/change" + projectile_type = /obj/item/projectile/change origin_tech = null - clumsy_check = 0 - var/charge_tick = 0 + self_recharge = 1 + charge_meter = 0 - - New() - ..() - processing_objects.Add(src) - - - Del() - processing_objects.Remove(src) - ..() - - - process() - charge_tick++ - if(charge_tick < 4) return 0 - charge_tick = 0 - if(!power_supply) return 0 - power_supply.give(200) - return 1 - - update_icon() - return - - - click_empty(mob/user = null) - if (user) - user.visible_message("*fizzle*", "\red *fizzle*") - else - src.visible_message("*fizzle*") - playsound(src.loc, 'sound/effects/sparks1.ogg', 100, 1) +/obj/item/weapon/gun/energy/staff/handle_click_empty(mob/user = null) + if (user) + user.visible_message("*fizzle*", "*fizzle*") + else + src.visible_message("*fizzle*") + playsound(src.loc, 'sound/effects/sparks1.ogg', 100, 1) /obj/item/weapon/gun/energy/staff/animate name = "staff of animation" desc = "An artefact that spits bolts of life-force which causes objects which are hit by it to animate and come to life! This magic doesn't affect machines." - projectile_type = "/obj/item/projectile/animate" + projectile_type = /obj/item/projectile/animate charge_cost = 100 -/obj/item/weapon/gun/energy/floragun - name = "floral somatoray" - desc = "A tool that discharges controlled radiation which induces mutation in plant cells." - icon_state = "floramut100" - item_state = "obj/item/gun.dmi" - fire_sound = 'sound/effects/stealthoff.ogg' - charge_cost = 100 - projectile_type = "/obj/item/projectile/energy/floramut" - origin_tech = "materials=2;biotech=3;powerstorage=3" - modifystate = "floramut" - var/charge_tick = 0 - var/mode = 0 //0 = mutate, 1 = yield boost - -/obj/item/weapon/gun/energy/floragun/New() - ..() - processing_objects.Add(src) - -/obj/item/weapon/gun/energy/floragun/Del() - processing_objects.Remove(src) - ..() - -/obj/item/weapon/gun/energy/floragun/process() - charge_tick++ - if(charge_tick < 4) return 0 - charge_tick = 0 - if(!power_supply) return 0 - power_supply.give(100) - update_icon() - return 1 - -/obj/item/weapon/gun/energy/floragun/attack_self(mob/living/user as mob) - switch(mode) - if(0) - mode = 1 - charge_cost = 100 - user << "\red The [src.name] is now set to increase yield." - projectile_type = "/obj/item/projectile/energy/florayield" - modifystate = "florayield" - if(1) - mode = 0 - charge_cost = 100 - user << "\red The [src.name] is now set to induce mutations." - projectile_type = "/obj/item/projectile/energy/floramut" - modifystate = "floramut" - update_icon() - return - -/obj/item/weapon/gun/energy/floragun/afterattack(obj/target, mob/user, flag) - - if(flag && istype(target,/obj/machinery/portable_atmospherics/hydroponics)) - var/obj/machinery/portable_atmospherics/hydroponics/tray = target - if(load_into_chamber()) - user.visible_message("\red \The [user] fires \the [src] into \the [tray]!") - Fire(target,user) - return - - ..() - -/obj/item/weapon/gun/energy/meteorgun - name = "meteor gun" - desc = "For the love of god, make sure you're aiming this the right way!" - icon_state = "riotgun" - item_state = "c20r" - w_class = 4 - projectile_type = "/obj/item/projectile/meteor" - charge_cost = 100 - cell_type = "/obj/item/weapon/cell/potato" - clumsy_check = 0 //Admin spawn only, might as well let clowns use it. - var/charge_tick = 0 - var/recharge_time = 5 //Time it takes for shots to recharge (in ticks) - - New() - ..() - processing_objects.Add(src) - - - Del() - processing_objects.Remove(src) - ..() - - process() - charge_tick++ - if(charge_tick < recharge_time) return 0 - charge_tick = 0 - if(!power_supply) return 0 - power_supply.give(100) - - update_icon() - return - - -/obj/item/weapon/gun/energy/meteorgun/pen - name = "meteor pen" - desc = "The pen is mightier than the sword." - icon = 'icons/obj/bureaucracy.dmi' - icon_state = "pen" - item_state = "pen" - w_class = 1 - - -/obj/item/weapon/gun/energy/mindflayer - name = "mind flayer" - desc = "A prototype weapon recovered from the ruins of Research-Station Epsilon." - icon_state = "xray" - projectile_type = "/obj/item/projectile/beam/mindflayer" - fire_sound = 'sound/weapons/Laser.ogg' - obj/item/weapon/gun/energy/staff/focus name = "mental focus" desc = "An artefact that channels the will of the user into destructive bolts of force. If you aren't careful with it, you might poke someone's brain out." icon = 'icons/obj/wizard.dmi' icon_state = "focus" item_state = "focus" - projectile_type = "/obj/item/projectile/forcebolt" + slot_flags = SLOT_BACK + projectile_type = /obj/item/projectile/forcebolt /* attack_self(mob/living/user as mob) if(projectile_type == "/obj/item/projectile/forcebolt") charge_cost = 200 - user << "\red The [src.name] will now strike a small area." + user << "The [src.name] will now strike a small area." projectile_type = "/obj/item/projectile/forcebolt/strong" else charge_cost = 100 - user << "\red The [src.name] will now strike only a single person." + user << "The [src.name] will now strike only a single person." projectile_type = "/obj/item/projectile/forcebolt" */ -/obj/item/weapon/gun/energy/toxgun - name = "phoron pistol" - desc = "A specialized firearm designed to fire lethal bolts of phoron." - icon_state = "toxgun" - fire_sound = 'sound/effects/stealthoff.ogg' - w_class = 3.0 - origin_tech = "combat=5;phorontech=4" - projectile_type = "/obj/item/projectile/energy/phoron" - -/obj/item/weapon/gun/energy/sniperrifle - name = "\improper L.W.A.P. sniper rifle" - desc = "A rifle constructed of lightweight materials, fitted with a SMART aiming-system scope." - icon = 'icons/obj/gun.dmi' - icon_state = "sniper" - fire_sound = 'sound/weapons/marauder.ogg' - origin_tech = "combat=6;materials=5;powerstorage=4" - projectile_type = "/obj/item/projectile/beam/sniper" - slot_flags = SLOT_BACK - charge_cost = 250 - fire_delay = 35 - w_class = 4.0 - zoomdevicename = "scope" - -/obj/item/weapon/gun/energy/sniperrifle/verb/scope() - set category = "Object" - set name = "Use Scope" - set popup_menu = 1 - - zoom() - +/* Adminbus guns */ // Serves as a target spotter for the Icarus. /obj/item/weapon/gun/energy/icarus name = "rubber ducky" desc = "It's a cute rubber duck. With an evil gleam in it's eye." - projectile_type = "/obj/item/projectile/icarus/pointdefense" + projectile_type = /obj/item/projectile/icarus/pointdefense icon = 'icons/obj/watercloset.dmi' icon_state = "rubberducky" item_state = "rubberducky" @@ -247,11 +168,11 @@ obj/item/weapon/gun/energy/staff/focus silenced = 1 /obj/item/weapon/gun/energy/icarus/attack_self(mob/living/user as mob) - if(projectile_type == "/obj/item/projectile/icarus/pointdefense") - projectile_type = "/obj/item/projectile/icarus/guns" + if(projectile_type == /obj/item/projectile/icarus/pointdefense) + projectile_type = /obj/item/projectile/icarus/guns user << "You inform the Icarus to switch to the main guns." else - projectile_type = "/obj/item/projectile/icarus/pointdefense" + projectile_type = /obj/item/projectile/icarus/pointdefense user << "You inform the Icarus to switch to the point-defense lasers." . = ..() @@ -281,5 +202,5 @@ obj/item/weapon/gun/energy/staff/focus var/type = input(user,"What projectile type?","Projectile", null) as null|anything in typesof(/obj/item/projectile) if(!type) return ..() - + projectile_type = type . = ..() diff --git a/code/modules/projectiles/guns/energy/stun.dm b/code/modules/projectiles/guns/energy/stun.dm index c3d6529dcb..6bbc2aed3e 100644 --- a/code/modules/projectiles/guns/energy/stun.dm +++ b/code/modules/projectiles/guns/energy/stun.dm @@ -6,38 +6,15 @@ fire_sound = 'sound/weapons/Taser.ogg' charge_cost = 100 projectile_type = /obj/item/projectile/beam/stun - cell_type = "/obj/item/weapon/cell/crap" + cell_type = /obj/item/weapon/cell/crap -/obj/item/weapon/gun/energy/taser/cyborg - cell_type = "/obj/item/weapon/cell/secborg" - var/charge_tick = 0 - var/recharge_time = 10 //Time it takes for shots to recharge (in ticks) +/obj/item/weapon/gun/energy/taser/mounted + self_recharge = 1 + use_external_power = 1 - New() - ..() - processing_objects.Add(src) - - - Del() - processing_objects.Remove(src) - ..() - - process() //Every [recharge_time] ticks, recharge a shot for the cyborg - charge_tick++ - if(charge_tick < recharge_time) return 0 - charge_tick = 0 - - if(!power_supply) return 0 //sanity - if(power_supply.charge >= power_supply.maxcharge) return 0 // check if we actually need to recharge - - if(isrobot(src.loc)) - var/mob/living/silicon/robot/R = src.loc - if(R && R.cell) - R.cell.use(charge_cost) //Take power from the borg... - power_supply.give(charge_cost) //... to recharge the shot - - update_icon() - return 1 +/obj/item/weapon/gun/energy/taser/mounted/cyborg + cell_type = /obj/item/weapon/cell/secborg + recharge_time = 10 //Time it takes for shots to recharge (in ticks) /obj/item/weapon/gun/energy/stunrevolver @@ -48,8 +25,7 @@ origin_tech = "combat=3;materials=3;powerstorage=2" charge_cost = 125 projectile_type = /obj/item/projectile/beam/stun - cell_type = "/obj/item/weapon/cell" - + cell_type = /obj/item/weapon/cell /obj/item/weapon/gun/energy/crossbow @@ -60,43 +36,22 @@ item_state = "crossbow" matter = list("metal" = 2000) origin_tech = "combat=2;magnets=2;syndicate=5" + slot_flags = SLOT_BELT silenced = 1 fire_sound = 'sound/weapons/Genhit.ogg' projectile_type = /obj/item/projectile/energy/bolt - cell_type = "/obj/item/weapon/cell/crap" - var/charge_tick = 0 - - - New() - ..() - processing_objects.Add(src) - - - Del() - processing_objects.Remove(src) - ..() - - - process() - charge_tick++ - if(charge_tick < 4) return 0 - charge_tick = 0 - if(!power_supply) return 0 - power_supply.give(100) - return 1 - - - update_icon() - return + cell_type = /obj/item/weapon/cell/crap + self_recharge = 1 + charge_meter = 0 /obj/item/weapon/gun/energy/crossbow/ninja name = "energy dart thrower" projectile_type = /obj/item/projectile/energy/dart /obj/item/weapon/gun/energy/crossbow/largecrossbow - name = "Energy Crossbow" + name = "energy crossbow" desc = "A weapon favored by mercenary infiltration teams." - w_class = 4.0 + w_class = 4 force = 10 matter = list("metal" = 200000) projectile_type = /obj/item/projectile/energy/bolt/large diff --git a/code/modules/projectiles/guns/energy/temperature.dm b/code/modules/projectiles/guns/energy/temperature.dm index 1e61590f21..ad4db3d5ca 100644 --- a/code/modules/projectiles/guns/energy/temperature.dm +++ b/code/modules/projectiles/guns/energy/temperature.dm @@ -7,74 +7,73 @@ var/current_temperature = T20C charge_cost = 100 origin_tech = "combat=3;materials=4;powerstorage=3;magnets=2" + slot_flags = SLOT_BELT|SLOT_BACK - projectile_type = "/obj/item/projectile/temp" - cell_type = "/obj/item/weapon/cell/crap" + projectile_type = /obj/item/projectile/temp + cell_type = /obj/item/weapon/cell/crap - New() - ..() - processing_objects.Add(src) +/obj/item/weapon/gun/energy/temperature/New() + ..() + processing_objects.Add(src) - Del() - processing_objects.Remove(src) - ..() +/obj/item/weapon/gun/energy/temperature/Del() + processing_objects.Remove(src) + ..() - attack_self(mob/living/user as mob) - user.set_machine(src) - var/temp_text = "" - if(temperature > (T0C - 50)) - temp_text = "[temperature] ([round(temperature-T0C)]°C) ([round(temperature*1.8-459.67)]°F)" +/obj/item/weapon/gun/energy/temperature/attack_self(mob/living/user as mob) + user.set_machine(src) + var/temp_text = "" + if(temperature > (T0C - 50)) + temp_text = "[temperature] ([round(temperature-T0C)]°C) ([round(temperature*1.8-459.67)]°F)" + else + temp_text = "[temperature] ([round(temperature-T0C)]°C) ([round(temperature*1.8-459.67)]°F)" + + var/dat = {"Freeze Gun Configuration:
    + Current output temperature: [temp_text]
    + Target output temperature: - - - [current_temperature] + + +
    + "} + + user << browse(dat, "window=freezegun;size=450x300;can_resize=1;can_close=1;can_minimize=1") + onclose(user, "window=freezegun", src) + + +/obj/item/weapon/gun/energy/temperature/Topic(href, href_list) + if (..()) + return + usr.set_machine(src) + src.add_fingerprint(usr) + + + + if(href_list["temp"]) + var/amount = text2num(href_list["temp"]) + if(amount > 0) + src.current_temperature = min(500, src.current_temperature+amount) else - temp_text = "[temperature] ([round(temperature-T0C)]°C) ([round(temperature*1.8-459.67)]°F)" - - var/dat = {"Freeze Gun Configuration:
    - Current output temperature: [temp_text]
    - Target output temperature: - - - [current_temperature] + + +
    - "} + src.current_temperature = max(0, src.current_temperature+amount) + if (istype(src.loc, /mob)) + attack_self(src.loc) + src.add_fingerprint(usr) + return - user << browse(dat, "window=freezegun;size=450x300;can_resize=1;can_close=1;can_minimize=1") - onclose(user, "window=freezegun", src) +/obj/item/weapon/gun/energy/temperature/process() + switch(temperature) + if(0 to 100) charge_cost = 1000 + if(100 to 250) charge_cost = 500 + if(251 to 300) charge_cost = 100 + if(301 to 400) charge_cost = 500 + if(401 to 500) charge_cost = 1000 - - Topic(href, href_list) - if (..()) - return - usr.set_machine(src) - src.add_fingerprint(usr) - - - - if(href_list["temp"]) - var/amount = text2num(href_list["temp"]) - if(amount > 0) - src.current_temperature = min(500, src.current_temperature+amount) + if(current_temperature != temperature) + var/difference = abs(current_temperature - temperature) + if(difference >= 10) + if(current_temperature < temperature) + temperature -= 10 else - src.current_temperature = max(0, src.current_temperature+amount) - if (istype(src.loc, /mob)) - attack_self(src.loc) - src.add_fingerprint(usr) - return - - - process() - switch(temperature) - if(0 to 100) charge_cost = 1000 - if(100 to 250) charge_cost = 500 - if(251 to 300) charge_cost = 100 - if(301 to 400) charge_cost = 500 - if(401 to 500) charge_cost = 1000 - - if(current_temperature != temperature) - var/difference = abs(current_temperature - temperature) - if(difference >= 10) - if(current_temperature < temperature) - temperature -= 10 - else - temperature += 10 - else - temperature = current_temperature - return + temperature += 10 + else + temperature = current_temperature diff --git a/code/modules/projectiles/guns/launcher.dm b/code/modules/projectiles/guns/launcher.dm new file mode 100644 index 0000000000..ea86814afa --- /dev/null +++ b/code/modules/projectiles/guns/launcher.dm @@ -0,0 +1,32 @@ +/obj/item/weapon/gun/launcher + name = "launcher" + desc = "A device that launches things." + icon = 'icons/obj/weapons.dmi' + w_class = 5.0 + flags = CONDUCT + slot_flags = SLOT_BACK + + var/release_force = 0 + var/throw_distance = 10 + fire_sound_text = "a launcher firing" + +//This normally uses a proc on projectiles and our ammo is not strictly speaking a projectile. +/obj/item/weapon/gun/launcher/can_hit(var/mob/living/target as mob, var/mob/living/user as mob) + return 1 + +//Override this to avoid a runtime with suicide handling. +/obj/item/weapon/gun/launcher/handle_suicide(mob/living/user) + user << "\red Shooting yourself with \a [src] is pretty tricky. You can't seem to manage it." + return + +/obj/item/weapon/gun/launcher/proc/update_release_force(obj/item/projectile) + return 0 + +/obj/item/weapon/gun/launcher/process_projectile(obj/item/projectile, mob/user, atom/target, var/target_zone, var/params=null, var/pointblank=0, var/reflex=0) + update_release_force(projectile) + projectile.loc = get_turf(user) + projectile.throw_at(target, throw_distance, release_force, user) + return 1 + +/obj/item/weapon/gun/launcher/attack_self(mob/living/user as mob) + return diff --git a/code/modules/projectiles/guns/projectile/crossbow.dm b/code/modules/projectiles/guns/launcher/crossbow.dm similarity index 76% rename from code/modules/projectiles/guns/projectile/crossbow.dm rename to code/modules/projectiles/guns/launcher/crossbow.dm index faa3f8509f..3d3e2f6d86 100644 --- a/code/modules/projectiles/guns/projectile/crossbow.dm +++ b/code/modules/projectiles/guns/launcher/crossbow.dm @@ -51,43 +51,39 @@ icon_state = "crossbow" item_state = "crossbow-solid" fire_sound = 'sound/weapons/punchmiss.ogg' // TODO: Decent THWOK noise. - ejectshell = 0 // No spent shells. - mouthshoot = 1 // No suiciding with this weapon, causes runtimes. fire_sound_text = "a solid thunk" fire_delay = 25 + slot_flags = SLOT_BACK + var/obj/item/bolt var/tension = 0 // Current draw on the bow. var/max_tension = 5 // Highest possible tension. var/release_speed = 5 // Speed per unit of tension. var/obj/item/weapon/cell/cell = null // Used for firing superheated rods. var/current_user // Used to check if the crossbow has changed hands since being drawn. -/obj/item/weapon/gun/launcher/crossbow/emp_act(severity) - if(cell && severity) - cell.use(100*severity) - -/obj/item/weapon/gun/launcher/crossbow/special_check(user) - if(tension <= 0) - user << "\red \The [src] is not drawn back!" - return 0 - return 1 - /obj/item/weapon/gun/launcher/crossbow/update_release_force() release_force = tension*release_speed -/obj/item/weapon/gun/launcher/crossbow/Fire(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, params, reflex = 0) +/obj/item/weapon/gun/launcher/crossbow/consume_next_projectile(mob/user=null) + if(tension <= 0) + user << "\red \The [src] is not drawn back!" + return null + return bolt - if(!..()) return //Only do this on a successful shot. +/obj/item/weapon/gun/launcher/crossbow/handle_post_fire(mob/user, atom/target) + bolt = null icon_state = "crossbow" tension = 0 + ..() /obj/item/weapon/gun/launcher/crossbow/attack_self(mob/living/user as mob) if(tension) - if(in_chamber && in_chamber.loc == src) //Just in case they click it the tick after firing. - user.visible_message("[user] relaxes the tension on [src]'s string and removes [in_chamber].","You relax the tension on [src]'s string and remove [in_chamber].") - in_chamber.loc = get_turf(src) - var/obj/item/weapon/arrow/A = in_chamber - in_chamber = null + if(bolt) + user.visible_message("[user] relaxes the tension on [src]'s string and removes [bolt].","You relax the tension on [src]'s string and remove [bolt].") + bolt.loc = get_turf(src) + var/obj/item/weapon/arrow/A = bolt + bolt = null A.removed(user) else user.visible_message("[user] relaxes the tension on [src]'s string.","You relax the tension on [src]'s string.") @@ -98,7 +94,7 @@ /obj/item/weapon/gun/launcher/crossbow/proc/draw(var/mob/user as mob) - if(!in_chamber) + if(!bolt) user << "You don't have anything nocked to [src]." return @@ -106,50 +102,57 @@ return current_user = user - user.visible_message("[user] begins to draw back the string of [src].","You begin to draw back the string of [src].") + user.visible_message("[user] begins to draw back the string of [src].","You begin to draw back the string of [src].") tension = 1 - spawn(25) increase_tension(user) //TODO: This needs to be changed to something less shit. + + while(bolt && tension && current_user == user) + if(!do_after(user, 25)) //crossbow strings don't just magically pull back on their own. + user.visible_message("[usr] stops drawing and relaxes the string of [src].","You stop drawing back and relax the string of [src].") + tension = 0 + icon_state = "crossbow" + return + + tension++ + icon_state = "crossbow-drawn" + + if(tension >= max_tension) + tension = max_tension + usr << "[src] clunks as you draw the string to its maximum tension!" + return + + user.visible_message("[usr] draws back the string of [src]!","You continue drawing back the string of [src]!") /obj/item/weapon/gun/launcher/crossbow/proc/increase_tension(var/mob/user as mob) - if(!in_chamber || !tension || current_user != user) //Arrow has been fired, bow has been relaxed or user has changed. + if(!bolt || !tension || current_user != user) //Arrow has been fired, bow has been relaxed or user has changed. return - tension++ - icon_state = "crossbow-drawn" - - if(tension>=max_tension) - tension = max_tension - usr << "[src] clunks as you draw the string to its maximum tension!" - else - user.visible_message("[usr] draws back the string of [src]!","You continue drawing back the string of [src]!") - spawn(25) increase_tension(user) /obj/item/weapon/gun/launcher/crossbow/attackby(obj/item/W as obj, mob/user as mob) - if(!in_chamber) + if(!bolt) if (istype(W,/obj/item/weapon/arrow)) user.drop_item() - in_chamber = W - in_chamber.loc = src - user.visible_message("[user] slides [in_chamber] into [src].","You slide [in_chamber] into [src].") + bolt = W + bolt.loc = src + user.visible_message("[user] slides [bolt] into [src].","You slide [bolt] into [src].") icon_state = "crossbow-nocked" return else if(istype(W,/obj/item/stack/rods)) var/obj/item/stack/rods/R = W if (R.use(1)) - in_chamber = new /obj/item/weapon/arrow/rod(src) - in_chamber.fingerprintslast = src.fingerprintslast - in_chamber.loc = src + bolt = new /obj/item/weapon/arrow/rod(src) + bolt.fingerprintslast = src.fingerprintslast + bolt.loc = src icon_state = "crossbow-nocked" - user.visible_message("[user] jams [in_chamber] into [src].","You jam [in_chamber] into [src].") + user.visible_message("[user] jams [bolt] into [src].","You jam [bolt] into [src].") superheat_rod(user) return if(istype(W, /obj/item/weapon/cell)) if(!cell) user.drop_item() - W.loc = src cell = W + cell.loc = src user << "You jam [cell] into [src] and wire it to the firing coil." superheat_rod(user) else @@ -168,14 +171,14 @@ ..() /obj/item/weapon/gun/launcher/crossbow/proc/superheat_rod(var/mob/user) - if(!user || !cell || !in_chamber) return + if(!user || !cell || !bolt) return if(cell.charge < 500) return - if(in_chamber.throwforce >= 15) return - if(!istype(in_chamber,/obj/item/weapon/arrow/rod)) return + if(bolt.throwforce >= 15) return + if(!istype(bolt,/obj/item/weapon/arrow/rod)) return - user << "[in_chamber] plinks and crackles as it begins to glow red-hot." - in_chamber.throwforce = 15 - in_chamber.icon_state = "metal-rod-superheated" + user << "[bolt] plinks and crackles as it begins to glow red-hot." + bolt.throwforce = 15 + bolt.icon_state = "metal-rod-superheated" cell.use(500) diff --git a/code/modules/projectiles/guns/launcher/grenade_launcher.dm b/code/modules/projectiles/guns/launcher/grenade_launcher.dm new file mode 100644 index 0000000000..14e1c2e785 --- /dev/null +++ b/code/modules/projectiles/guns/launcher/grenade_launcher.dm @@ -0,0 +1,82 @@ +/obj/item/weapon/gun/launcher/grenade + name = "grenade launcher" + desc = "A bulky pump-action grenade launcher. Holds up to 5 grenades in a revolving magazine." + icon = 'icons/obj/gun.dmi' + icon_state = "riotgun" + item_state = "riotgun" + w_class = 4 + force = 10 + + fire_sound = 'sound/weapons/empty.ogg' + fire_sound_text = "a metallic thunk" + recoil = 0 + throw_distance = 7 + release_force = 5 + + var/obj/item/weapon/grenade/chambered + var/list/grenades = new/list() + var/max_grenades = 4 //holds this + one in the chamber + matter = list("metal" = 2000) + +//revolves the magazine, allowing players to choose between multiple grenade types +/obj/item/weapon/gun/launcher/grenade/proc/pump(mob/M as mob) + playsound(M, 'sound/weapons/shotgunpump.ogg', 60, 1) + + var/obj/item/weapon/grenade/next + if(grenades.len) + next = grenades[1] //get this first, so that the chambered grenade can still be removed if the grenades list is empty + if(chambered) + grenades += chambered //rotate the revolving magazine + chambered = null + if(next) + grenades -= next //Remove grenade from loaded list. + chambered = next + M << "You pump [src], loading \a [next] into the chamber." + else + M << "You pump [src], but the magazine is empty." + update_icon() + +/obj/item/weapon/gun/launcher/grenade/examine(mob/user) + if(..(user, 2)) + var/grenade_count = grenades.len + (chambered? 1 : 0) + user << "Has [grenade_count] grenade\s remaining." + if(chambered) + user << "\A [chambered] is chambered." + +/obj/item/weapon/gun/launcher/grenade/attack_self(mob/user) + pump(user) + +/obj/item/weapon/gun/launcher/grenade/attackby(obj/item/I, mob/user) + if((istype(I, /obj/item/weapon/grenade))) + if(grenades.len >= max_grenades) + user << "[src] is full." + return + user.remove_from_mob(I) + I.loc = src + grenades.Insert(1, I) //add to the head of the list, so that it is loaded on the next pump + user.visible_message("[user] inserts \a [I] into [src].", "You insert \a [I] into [src].") + else + ..() + +/obj/item/weapon/gun/launcher/grenade/attack_hand(mob/user) + if(user.get_inactive_hand() == src) + if(grenades.len) + var/obj/item/weapon/grenade/G = grenades[grenades.len] + grenades.len-- + user.put_in_hands(G) + user.visible_message("[user] removes \a [G] from [src].", "You remove \a [G] from [src].") + else + user << "[src] is empty." + else + ..() + +/obj/item/weapon/gun/launcher/grenade/consume_next_projectile() + if(chambered) + chambered.det_time = 10 + chambered.activate(null) + return chambered + +/obj/item/weapon/gun/launcher/grenade/handle_post_fire(mob/user) + message_admins("[key_name_admin(user)] fired a grenade ([chambered.name]) from a grenade launcher ([src.name]).") + log_game("[key_name_admin(user)] used a grenade ([chambered.name]).") + chambered = null diff --git a/code/modules/projectiles/guns/projectile/pneumatic.dm b/code/modules/projectiles/guns/launcher/pneumatic.dm similarity index 85% rename from code/modules/projectiles/guns/projectile/pneumatic.dm rename to code/modules/projectiles/guns/launcher/pneumatic.dm index 43a5bc8e9a..712e74e150 100644 --- a/code/modules/projectiles/guns/projectile/pneumatic.dm +++ b/code/modules/projectiles/guns/launcher/pneumatic.dm @@ -4,6 +4,7 @@ icon = 'icons/obj/gun.dmi' icon_state = "pneumatic" item_state = "pneumatic" + slot_flags = SLOT_BELT w_class = 5.0 flags = CONDUCT fire_sound_text = "a loud whoosh of moving air" @@ -61,8 +62,7 @@ icon_state = "pneumatic-tank" item_state = "pneumatic-tank" user.update_icons() - else if(W.w_class <= max_w_class) - + else if(istype(W) && W.w_class <= max_w_class) var/total_stored = 0 for(var/obj/item/O in src.contents) total_stored += O.w_class @@ -79,9 +79,6 @@ /obj/item/weapon/gun/launcher/pneumatic/attack_self(mob/user as mob) if(contents.len > 0) var/obj/item/removing = contents[contents.len] - if(removing == in_chamber) - in_chamber = null - removing.loc = get_turf(src) user.put_in_hands(removing) user << "You remove [removing] from the hopper." @@ -89,12 +86,19 @@ user << "There is nothing to remove in \the [src]." return -/obj/item/weapon/gun/launcher/pneumatic/load_into_chamber() +/obj/item/weapon/gun/launcher/pneumatic/consume_next_projectile(mob/user=null) if(!contents.len) - return 0 + return null + if (!tank) + user << "There is no gas tank in [src]!" + return null - in_chamber = contents[1] - return !isnull(in_chamber) + var/fire_pressure = (tank.air_contents.return_pressure()/100)*pressure_setting + if(fire_pressure < minimum_tank_pressure) + user << "There isn't enough gas in the tank to fire [src]." + return null + + return contents[1] /obj/item/weapon/gun/launcher/pneumatic/examine(mob/user) if(!..(user, 2)) @@ -105,31 +109,21 @@ else user << "Nothing is attached to the tank valve!" -/obj/item/weapon/gun/launcher/pneumatic/special_check(user) +/obj/item/weapon/gun/launcher/pneumatic/update_release_force(obj/item/projectile) + if(tank) + release_force = ((fire_pressure*tank.volume)/projectile.w_class)/force_divisor //projectile speed. + if(release_force > 80) release_force = 80 //damage cap. + else + release_force = 0 - if (!tank) - user << "There is no gas tank in [src]!" - return 0 - - fire_pressure = (tank.air_contents.return_pressure()/100)*pressure_setting - if (fire_pressure < minimum_tank_pressure) - user << "There isn't enough gas in the tank to fire [src]." - return 0 - - return 1 - -/obj/item/weapon/gun/launcher/pneumatic/update_release_force() - if(!in_chamber) return - release_force = ((fire_pressure*tank.volume)/in_chamber.w_class)/force_divisor //projectile speed. - if(release_force >80) release_force = 80 //damage cap. - -/obj/item/weapon/gun/launcher/pneumatic/Fire(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, params, reflex = 0) - - if(!tank || !..()) return //Only do this on a successful shot. - - var/lost_gas_amount = tank.air_contents.total_moles*(pressure_setting/100) - var/datum/gas_mixture/removed = tank.air_contents.remove(lost_gas_amount) - user.loc.assume_air(removed) +/obj/item/weapon/gun/launcher/pneumatic/handle_post_fire() + if(tank) + var/lost_gas_amount = tank.air_contents.total_moles*(pressure_setting/100) + var/datum/gas_mixture/removed = tank.air_contents.remove(lost_gas_amount) + + var/turf/T = get_turf(src.loc) + if(T) T.assume_air(removed) + ..() //Constructable pneumatic cannon. diff --git a/code/modules/projectiles/guns/launcher/rocket.dm b/code/modules/projectiles/guns/launcher/rocket.dm new file mode 100644 index 0000000000..fd86302fb8 --- /dev/null +++ b/code/modules/projectiles/guns/launcher/rocket.dm @@ -0,0 +1,48 @@ +/obj/item/weapon/gun/launcher/rocket + name = "rocket launcher" + desc = "MAGGOT." + icon_state = "rocket" + item_state = "rocket" + w_class = 4.0 + throw_speed = 2 + throw_range = 10 + force = 5.0 + flags = CONDUCT | USEDELAY + slot_flags = 0 + origin_tech = "combat=8;materials=5" + fire_sound = 'sound/effects/bang.ogg' + + release_force = 15 + throw_distance = 30 + var/max_rockets = 1 + var/list/rockets = new/list() + +/obj/item/weapon/gun/launcher/rocket/examine(mob/user) + if(!..(user, 2)) + return + user << "\blue [rockets.len] / [max_rockets] rockets." + +/obj/item/weapon/gun/launcher/rocket/attackby(obj/item/I as obj, mob/user as mob) + if(istype(I, /obj/item/ammo_casing/rocket)) + if(rockets.len < max_rockets) + user.drop_item() + I.loc = src + rockets += I + user << "\blue You put the rocket in [src]." + user << "\blue [rockets.len] / [max_rockets] rockets." + else + usr << "\red [src] cannot hold more rockets." + +/obj/item/weapon/gun/launcher/rocket/consume_next_projectile() + if(rockets.len) + var/obj/item/ammo_casing/rocket/I = rockets[1] + var/obj/item/missile/M = new (src) + M.primed = 1 + rockets -= I + return M + return null + +/obj/item/weapon/gun/launcher/rocket/handle_post_fire(mob/user, atom/target) + message_admins("[key_name_admin(user)] fired a rocket from a rocket launcher ([src.name]) at [target].") + log_game("[key_name_admin(user)] used a rocket launcher ([src.name]) at [target].") + ..() diff --git a/code/modules/projectiles/guns/launcher/syringe_gun.dm b/code/modules/projectiles/guns/launcher/syringe_gun.dm new file mode 100644 index 0000000000..d4d66ac1cd --- /dev/null +++ b/code/modules/projectiles/guns/launcher/syringe_gun.dm @@ -0,0 +1,135 @@ +/obj/item/weapon/syringe_cartridge + name = "syringe gun cartridge" + desc = "An impact-triggered compressed gas cartridge that can fitted to a syringe for rapid injection." + icon = 'icons/obj/ammo.dmi' + icon_state = "syringe-cartridge" + var/icon_flight = "syringe-cartridge-flight" //so it doesn't look so weird when shot + matter = list("metal" = 125, "glass" = 375) + flags = CONDUCT + slot_flags = SLOT_BELT + throwforce = 3 + force = 3 + w_class = 1 + var/obj/item/weapon/reagent_containers/syringe/syringe + +/obj/item/weapon/syringe_cartridge/update_icon() + underlays.Cut() + if(syringe) + underlays += image(syringe.icon, src, syringe.icon_state) + underlays += syringe.filling + +/obj/item/weapon/syringe_cartridge/attackby(obj/item/I, mob/user) + if(istype(I, /obj/item/weapon/reagent_containers/syringe)) + syringe = I + user << "You carefully insert [syringe] into [src]." + user.remove_from_mob(syringe) + syringe.loc = src + sharp = 1 + update_icon() + +/obj/item/weapon/syringe_cartridge/attack_self(mob/user) + if(syringe) + user << "You remove [syringe] from [src]." + user.put_in_hands(syringe) + syringe = null + sharp = initial(sharp) + update_icon() + +/obj/item/weapon/syringe_cartridge/proc/prime() + //the icon state will revert back when update_icon() is called from throw_impact() + icon_state = icon_flight + underlays.Cut() + +/obj/item/weapon/syringe_cartridge/throw_impact(atom/hit_atom, var/speed) + ..() //handles embedding for us. Should have a decent chance if thrown fast enough + if(syringe) + //check speed to see if we hit hard enough to trigger the rapid injection + //incidentally, this means syringe_cartridges can be used with the pneumatic launcher + if(speed >= 10 && isliving(hit_atom)) + var/mob/living/L = hit_atom + //unfortuately we don't know where the dart will actually hit, since that's done by the parent. + if(L.can_inject()) + if(syringe.reagents) + syringe.reagents.trans_to(L, 15) + + syringe.break_syringe(iscarbon(hit_atom)? hit_atom : null) + syringe.update_icon() + + icon_state = initial(icon_state) //reset icon state + update_icon() + +/obj/item/weapon/gun/launcher/syringe + name = "syringe gun" + desc = "A spring loaded rifle designed to fit syringes, designed to incapacitate unruly patients from a distance." + icon = 'icons/obj/gun.dmi' + icon_state = "syringegun" + item_state = "syringegun" + w_class = 3 + force = 7 + matter = list("metal" = 2000) + slot_flags = SLOT_BELT + + fire_sound = 'sound/weapons/empty.ogg' + fire_sound_text = "a metallic thunk" + recoil = 0 + release_force = 10 + throw_distance = 10 + + var/list/darts = list() + var/max_darts = 1 + var/obj/item/weapon/syringe_cartridge/next + +/obj/item/weapon/gun/launcher/syringe/consume_next_projectile() + if(next) + next.prime() + return next + return null + +/obj/item/weapon/gun/launcher/syringe/handle_post_fire() + ..() + darts -= next + next = null + +/obj/item/weapon/gun/launcher/syringe/attack_self(mob/living/user as mob) + if(next) + user.visible_message("[user] unlatches and carefully relaxes the bolt on [src].", "You unlatch and carefully relax the bolt on [src], unloading the spring.") + next = null + else if(darts.len) + playsound(src.loc, 'sound/weapons/flipblade.ogg', 50, 1) + user.visible_message("[user] draws back the bolt on [src], clicking it into place.", "You draw back the bolt on the [src], loading the spring!") + next = darts[1] + add_fingerprint(user) + +/obj/item/weapon/gun/launcher/syringe/attack_hand(mob/living/user as mob) + if(user.get_inactive_hand() == src) + if(!darts.len) + user << "[src] is empty." + return + if(next) + user << "[src]'s cover is locked shut." + return + var/obj/item/weapon/syringe_cartridge/C = darts[1] + darts -= C + user.put_in_hands(C) + user.visible_message("[user] removes \a [C] from [src].", "You remove \a [C] from [src].") + else + ..() + +/obj/item/weapon/gun/launcher/syringe/attackby(var/obj/item/A as obj, mob/user as mob) + if(istype(A, /obj/item/weapon/syringe_cartridge)) + var/obj/item/weapon/syringe_cartridge/C = A + if(darts.len >= max_darts) + user << "[src] is full!" + return + user.remove_from_mob(C) + C.loc = src + darts += C //add to the end + user.visible_message("[user] inserts \a [C] into [src].", "You insert \a [C] into [src].") + else + ..() + +/obj/item/weapon/gun/launcher/syringe/rapid + name = "syringe gun revolver" + desc = "A modification of the syringe gun design, using a rotating cylinder to store up to five syringes. The spring still needs to be drawn between shots." + icon_state = "rapidsyringegun" + max_darts = 5 diff --git a/code/modules/projectiles/guns/projectile.dm b/code/modules/projectiles/guns/projectile.dm index bea28e9c37..5f197d56e6 100644 --- a/code/modules/projectiles/guns/projectile.dm +++ b/code/modules/projectiles/guns/projectile.dm @@ -1,121 +1,191 @@ -#define SPEEDLOADER 0 -#define FROM_BOX 1 -#define MAGAZINE 2 +#define HOLD_CASINGS 0 //do not do anything after firing. Manual action, like pump shotguns, or guns that want to define custom behaviour +#define EJECT_CASINGS 1 //drop spent casings on the ground after firing +#define CYCLE_CASINGS 2 //experimental: cycle casings, like a revolver. Also works for multibarrelled guns /obj/item/weapon/gun/projectile - name = "revolver" - desc = "A classic revolver. Uses .357 ammo" + name = "gun" + desc = "A gun that fires bullets." icon_state = "revolver" - caliber = "357" origin_tech = "combat=2;materials=2" - w_class = 3.0 + w_class = 3 matter = list("metal" = 1000) recoil = 1 - var/ammo_type = "/obj/item/ammo_casing/a357" - var/list/loaded = list() - var/max_shells = 7 - var/load_method = SPEEDLOADER //0 = Single shells or quick loader, 1 = box, 2 = magazine - var/obj/item/ammo_magazine/empty_mag = null - var/mag_type = null + + var/caliber = "357" //determines which casings will fit + var/handle_casings = EJECT_CASINGS //determines how spent casings should be handled + var/load_method = SINGLE_CASING|SPEEDLOADER //1 = Single shells, 2 = box or quick loader, 3 = magazine + var/obj/item/ammo_casing/chambered = null + + //For SINGLE_CASING or SPEEDLOADER guns + var/max_shells = 0 //the number of casings that will fit inside + var/ammo_type = null //the type of ammo that the gun comes preloaded with + var/list/loaded = list() //stored ammo + + //For MAGAZINE guns + var/magazine_type = null //the type of magazine that the gun comes preloaded with + var/obj/item/ammo_magazine/ammo_magazine = null //stored magazine + var/auto_eject = 0 //if the magazine should automatically eject itself when empty. + var/auto_eject_sound = null /obj/item/weapon/gun/projectile/New() ..() - for(var/i = 1, i <= max_shells, i++) - loaded += new ammo_type(src) - if(load_method == MAGAZINE) - empty_mag = new mag_type(src) + if(ispath(ammo_type) && (load_method & (SINGLE_CASING|SPEEDLOADER))) + for(var/i in 1 to max_shells) + loaded += new ammo_type(src) + if(ispath(magazine_type) && (load_method & MAGAZINE)) + ammo_magazine = new magazine_type(src) + update_icon() + +/obj/item/weapon/gun/projectile/consume_next_projectile() + //store the next ammo_casing in a var so that handle_post_fire() knows which one to eject + //also we might as well remove chambered here, so that we don't have to figure out where it came from later + if(loaded.len) + chambered = loaded[1] //load next casing. + if(handle_casings != HOLD_CASINGS) + loaded -= chambered + else if(ammo_magazine && ammo_magazine.stored_ammo.len) + chambered = ammo_magazine.stored_ammo[1] + if(handle_casings != HOLD_CASINGS) + ammo_magazine.stored_ammo -= chambered + return chambered.BB + +/obj/item/weapon/gun/projectile/handle_post_fire() + ..() + if(chambered) + chambered.expend() + + //check chambered again in case it deleted itself + if(chambered && handle_casings != HOLD_CASINGS) + switch(handle_casings) + if(EJECT_CASINGS) //eject casing onto ground. + chambered.loc = get_turf(src) + if(CYCLE_CASINGS) //cycle the casing back to the end. + if(ammo_magazine) + ammo_magazine.stored_ammo += chambered + else + loaded += chambered + chambered = null + + +//Attempts to load A into src, depending on the type of thing being loaded and the load_method +//Maybe this should be broken up into separate procs for each load method? +/obj/item/weapon/gun/projectile/proc/load_ammo(var/obj/item/A, mob/user) + if(istype(A, /obj/item/ammo_magazine)) + var/obj/item/ammo_magazine/AM = A + if(!(load_method & AM.mag_type) || caliber != AM.caliber) + return //incompatible + + switch(AM.mag_type) + if(MAGAZINE) + if(ammo_magazine) + user << "[src] already has a magazine loaded." //already a magazine here + return + user.remove_from_mob(AM) + AM.loc = src + ammo_magazine = AM + user.visible_message("[user] inserts [AM] into [src].", "You insert [AM] into [src].") + playsound(src.loc, 'sound/weapons/flipblade.ogg', 50, 1) + if(SPEEDLOADER) + if(loaded.len >= max_shells) + user << "[src] is full!" + return + var/count = 0 + for(var/obj/item/ammo_casing/C in AM.stored_ammo) + if(loaded.len >= max_shells) + break + if(C.caliber == caliber) + C.loc = src + loaded += C + AM.stored_ammo -= C //should probably go inside an ammo_magazine proc, but I guess less proc calls this way... + count++ + if(count) + user.visible_message("[user] reloads [src].", "You load [count] round\s into [src].") + playsound(src.loc, 'sound/weapons/empty.ogg', 50, 1) + AM.update_icon() + else if(istype(A, /obj/item/ammo_casing)) + var/obj/item/ammo_casing/C = A + if(!(load_method & SINGLE_CASING) || caliber != C.caliber) + return //incompatible + if(loaded.len >= max_shells) + user << "[src] is full." + return + + user.remove_from_mob(C) + C.loc = src + loaded.Insert(1, C) //add to the head of the list + user.visible_message("[user] inserts \a [C] into [src].", "You insert \a [C] into [src].") + playsound(src.loc, 'sound/weapons/empty.ogg', 50, 1) + update_icon() - return -/obj/item/weapon/gun/projectile/load_into_chamber() - if(in_chamber) - return 1 //{R} - - if(!loaded.len) - return 0 - var/obj/item/ammo_casing/AC = loaded[1] //load next casing. - loaded -= AC //Remove casing from loaded list. - if(isnull(AC) || !istype(AC)) - return 0 - AC.loc = get_turf(src) //Eject casing onto ground. - if(AC.BB) - in_chamber = AC.BB //Load projectile into chamber. - AC.BB.loc = src //Set projectile loc to gun. - return 1 - return 0 - +//attempts to unload src. If allow_dump is set to 0, the speedloader unloading method will be disabled +/obj/item/weapon/gun/projectile/proc/unload_ammo(mob/user, var/allow_dump=1) + if(ammo_magazine) + user.put_in_hands(ammo_magazine) + user.visible_message("[user] removes [ammo_magazine] from [src].", "You remove [ammo_magazine] from [src].") + playsound(src.loc, 'sound/weapons/empty.ogg', 50, 1) + ammo_magazine.update_icon() + ammo_magazine = null + else if(loaded.len) + //presumably, if it can be speed-loaded, it can be speed-unloaded. + if(allow_dump && (load_method & SPEEDLOADER)) + var/count = 0 + var/turf/T = get_turf(user) + if(T) + for(var/obj/item/ammo_casing/C in loaded) + C.loc = T + count++ + loaded.Cut() + if(count) + user.visible_message("[user] unloads [src].", "You unload [count] round\s from [src].") + else if(load_method & SINGLE_CASING) + var/obj/item/ammo_casing/C = loaded[loaded.len] + loaded.len-- + user.put_in_hands(C) + user.visible_message("[user] removes \a [C] from [src].", "You remove \a [C] from [src].") + else + user << "[src] is empty." + update_icon() /obj/item/weapon/gun/projectile/attackby(var/obj/item/A as obj, mob/user as mob) - - var/num_loaded = 0 - if(istype(A, /obj/item/ammo_magazine)) - if((load_method == MAGAZINE) && loaded.len) return - var/obj/item/ammo_magazine/AM = A - if(AM.stored_ammo.len <= 0) - user << "The magazine is empty!" - return - for(var/obj/item/ammo_casing/AC in AM.stored_ammo) - if(loaded.len >= max_shells) - break - if(AC.caliber == caliber && loaded.len < max_shells) - AC.loc = src - AM.stored_ammo -= AC - loaded += AC - num_loaded++ - if(load_method == MAGAZINE) - user.remove_from_mob(AM) - empty_mag = AM - empty_mag.loc = src - if(istype(A, /obj/item/ammo_casing) && load_method == SPEEDLOADER) - var/obj/item/ammo_casing/AC = A - if(AC.caliber == caliber && loaded.len < max_shells) - user.drop_item() - AC.loc = src - loaded += AC - num_loaded++ - if(num_loaded) - user << "\blue You load [num_loaded] shell\s into the gun!" - A.update_icon() - update_icon() - return + load_ammo(A, user) /obj/item/weapon/gun/projectile/attack_self(mob/user as mob) - if (target) - return ..() - if (loaded.len) - if (load_method == SPEEDLOADER) - var/obj/item/ammo_casing/AC = loaded[1] - loaded -= AC - AC.loc = get_turf(src) //Eject casing onto ground. - user << "\blue You unload shell from \the [src]!" - if (load_method == MAGAZINE) - var/obj/item/ammo_magazine/AM = empty_mag - for (var/obj/item/ammo_casing/AC in loaded) - AM.stored_ammo += AC - loaded -= AC - AM.loc = get_turf(src) - empty_mag = null - update_icon() - AM.update_icon() - user << "\blue You unload magazine from \the [src]!" + unload_ammo(user) + +/obj/item/weapon/gun/projectile/attack_hand(mob/user as mob) + if(user.get_inactive_hand() == src) + unload_ammo(user, allow_dump=0) else - user << "\red Nothing loaded in \the [src]!" - + return ..() +/obj/item/weapon/gun/projectile/afterattack(atom/A, mob/living/user) + ..() + if(auto_eject && ammo_magazine && ammo_magazine.stored_ammo && !ammo_magazine.stored_ammo.len) + ammo_magazine.loc = get_turf(src.loc) + user.visible_message( + "[ammo_magazine] falls out and clatters on the floor!", + "[ammo_magazine] falls out and clatters on the floor!" + ) + if(auto_eject_sound) + playsound(user, auto_eject_sound, 40, 1) + ammo_magazine = null + update_icon() /obj/item/weapon/gun/projectile/examine(mob/user) ..(user) user << "Has [getAmmo()] round\s remaining." -// if(in_chamber && !loaded.len) -// user << "However, it has a chambered round." -// if(in_chamber && loaded.len) -// user << "It also has a chambered round." {R} + if(ammo_magazine) + user << "It has \a [ammo_magazine] loaded." return /obj/item/weapon/gun/projectile/proc/getAmmo() var/bullets = 0 - for(var/obj/item/ammo_casing/AC in loaded) - if(istype(AC)) - bullets += 1 + if(loaded) + bullets += loaded.len + if(ammo_magazine && ammo_magazine.stored_ammo) + bullets += ammo_magazine.stored_ammo.len + if(chambered) + bullets += 1 return bullets diff --git a/code/modules/projectiles/guns/projectile/automatic.dm b/code/modules/projectiles/guns/projectile/automatic.dm index 0e5f0d68cd..c518a11a57 100644 --- a/code/modules/projectiles/guns/projectile/automatic.dm +++ b/code/modules/projectiles/guns/projectile/automatic.dm @@ -2,67 +2,67 @@ name = "submachine gun" desc = "A lightweight, fast firing gun. Uses 9mm rounds." icon_state = "saber" //ugly - w_class = 3.0 + w_class = 3 + load_method = SPEEDLOADER //yup. until someone sprites a magazine for it. max_shells = 22 caliber = "9mm" - origin_tech = "combat=4;materials=2" - ammo_type = "/obj/item/ammo_casing/c9mm" - automatic = 1 - + origin_tech = "combat=4;materials=2" + slot_flags = SLOT_BELT + ammo_type = /obj/item/ammo_casing/c9mm + multi_aim = 1 fire_delay = 0 - - isHandgun() - return 0 - -/obj/item/weapon/gun/projectile/automatic/test - name = "test gun" - ammo_type = "/obj/item/ammo_casing/a145" - + /obj/item/weapon/gun/projectile/automatic/mini_uzi name = "\improper Uzi" desc = "A lightweight, fast firing gun, for when you want someone dead. Uses .45 rounds." icon_state = "mini-uzi" - w_class = 3.0 - max_shells = 16 + w_class = 3 + load_method = SPEEDLOADER //yup. until someone sprites a magazine for it. + max_shells = 15 caliber = ".45" origin_tech = "combat=5;materials=2;syndicate=8" - ammo_type = "/obj/item/ammo_casing/c45" - - isHandgun() - return 1 - + ammo_type = /obj/item/ammo_casing/c45 /obj/item/weapon/gun/projectile/automatic/c20r name = "\improper C-20r SMG" - desc = "A lightweight, fast firing gun, for when you REALLY need someone dead. Uses 12mm rounds. Has a 'Scarborough Arms - Per falcis, per pravitas' buttstamp" + desc = "A lightweight, fast firing gun, for when you REALLY need someone dead. Uses 12mm pistol rounds. Has a 'Scarborough Arms - Per falcis, per pravitas' buttstamp" icon_state = "c20r" item_state = "c20r" - w_class = 3.0 - max_shells = 20 + w_class = 3 + force = 10 caliber = "12mm" origin_tech = "combat=5;materials=2;syndicate=8" - ammo_type = "/obj/item/ammo_casing/a12mm" + slot_flags = SLOT_BELT|SLOT_BACK fire_sound = 'sound/weapons/Gunshot_smg.ogg' load_method = MAGAZINE - mag_type = /obj/item/ammo_magazine/a12mm/empty + magazine_type = /obj/item/ammo_magazine/a12mm + auto_eject = 1 + auto_eject_sound = 'sound/weapons/smg_empty_alarm.ogg' - afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, flag) - ..() - if(!loaded.len && empty_mag) - empty_mag.loc = get_turf(src.loc) - empty_mag = null - playsound(user, 'sound/weapons/smg_empty_alarm.ogg', 40, 1) - update_icon() - return +/obj/item/weapon/gun/projectile/automatic/c20r/update_icon() + ..() + if(ammo_magazine) + icon_state = "c20r-[round(loaded.len,4)]" + else + icon_state = "c20r" + return +/obj/item/weapon/gun/projectile/automatic/sts35 + name = "\improper STS-35 Automatic Rifle" + desc = "A durable, rugged looking automatic weapon of make popular on the frontier, despite it's bulk. Uses 7.62mm rounds. It is unmarked." + icon_state = "assltrifle" + item_state = "shotgun" + w_class = 4 + force = 10 + caliber = "a762" + origin_tech = "combat=5;materials=1;syndicate=8" + slot_flags = SLOT_BACK + load_method = MAGAZINE + magazine_type = /obj/item/ammo_magazine/c762 - update_icon() - ..() - if(empty_mag) - icon_state = "c20r-[round(loaded.len,4)]" - else - icon_state = "c20r" - return +/obj/item/weapon/gun/projectile/automatic/sts35/update_icon() + ..() + icon_state = (ammo_magazine)? "assltrifle" : "assltrifle-noclip" /obj/item/weapon/gun/projectile/automatic/l6_saw name = "\improper L6 SAW" @@ -70,74 +70,39 @@ icon_state = "l6closed100" item_state = "l6closedmag" w_class = 4 + force = 10 slot_flags = 0 max_shells = 50 caliber = "a762" origin_tech = "combat=5;materials=1;syndicate=2" + slot_flags = SLOT_BACK ammo_type = "/obj/item/ammo_casing/a762" fire_sound = 'sound/weapons/Gunshot_smg.ogg' load_method = MAGAZINE + magazine_type = /obj/item/ammo_magazine/a762 var/cover_open = 0 - var/mag_inserted = 1 - /obj/item/weapon/gun/projectile/automatic/l6_saw/attack_self(mob/user as mob) cover_open = !cover_open user << "You [cover_open ? "open" : "close"] [src]'s cover." update_icon() - /obj/item/weapon/gun/projectile/automatic/l6_saw/update_icon() - icon_state = "l6[cover_open ? "open" : "closed"][mag_inserted ? round(loaded.len, 25) : "-empty"]" + icon_state = "l6[cover_open ? "open" : "closed"][ammo_magazine ? round(loaded.len, 25) : "-empty"]" - -/obj/item/weapon/gun/projectile/automatic/l6_saw/afterattack(atom/target as mob|obj|turf, mob/living/user as mob|obj, flag, params) //what I tried to do here is just add a check to see if the cover is open or not and add an icon_state change because I can't figure out how c-20rs do it with overlays +/obj/item/weapon/gun/projectile/automatic/l6_saw/special_check(mob/user) if(cover_open) - user << "[src]'s cover is open! Close it before firing!" - else - ..() - update_icon() + user << "[src]'s cover is open! Close it before firing!" + return 0 + return ..() - -/obj/item/weapon/gun/projectile/automatic/l6_saw/attack_hand(mob/user as mob) - if(loc != user) - ..() - return //let them pick it up - if(!cover_open || (cover_open && !mag_inserted)) - ..() - else if(cover_open && mag_inserted) - //drop the mag - empty_mag = new /obj/item/ammo_magazine/a762(src) - empty_mag.stored_ammo = loaded - empty_mag.icon_state = "a762-[round(loaded.len, 10)]" - empty_mag.desc = "There are [loaded.len] shells left!" - empty_mag.loc = get_turf(src.loc) - user.put_in_hands(empty_mag) - empty_mag = null - mag_inserted = 0 - loaded = list() - update_icon() - user << "You remove the magazine from [src]." - - -/obj/item/weapon/gun/projectile/automatic/l6_saw/attackby(var/obj/item/A as obj, mob/user as mob) +/obj/item/weapon/gun/projectile/automatic/l6_saw/load_ammo(var/obj/item/A, mob/user) if(!cover_open) - user << "[src]'s cover is closed! You can't insert a new mag!" + user << "You need to open the cover to load [src]." return - else if(cover_open && mag_inserted) - user << "[src] already has a magazine inserted!" - return - else if(cover_open && !mag_inserted) - mag_inserted = 1 - user << "You insert the magazine!" - update_icon() ..() - -/* The thing I found with guns in ss13 is that they don't seem to simulate the rounds in the magazine in the gun. - Afaik, since projectile.dm features a revolver, this would make sense since the magazine is part of the gun. - However, it looks like subsequent guns that use removable magazines don't take that into account and just get - around simulating a removable magazine by adding the casings into the loaded list and spawning an empty magazine - when the gun is out of rounds. Which means you can't eject magazines with rounds in them. The below is a very - rough and poor attempt at making that happen. -Ausops */ - \ No newline at end of file +/obj/item/weapon/gun/projectile/automatic/l6_saw/unload_ammo(mob/user) + if(!cover_open) + return + ..() \ No newline at end of file diff --git a/code/modules/projectiles/guns/projectile/dartgun.dm b/code/modules/projectiles/guns/projectile/dartgun.dm new file mode 100644 index 0000000000..4d90a0fef3 --- /dev/null +++ b/code/modules/projectiles/guns/projectile/dartgun.dm @@ -0,0 +1,202 @@ +/obj/item/projectile/bullet/chemdart + name = "dart" + icon_state = "dart" + damage = 5 + sharp = 1 + embed = 1 //the dart is shot fast enough to pierce space suits, so I guess splintering inside the target can be a thing. Should be rare due to low damage. + var/reagent_amount = 15 + kill_count = 15 //shorter range + +/obj/item/projectile/bullet/chemdart/New() + reagents = new/datum/reagents(reagent_amount) + reagents.my_atom = src + +/obj/item/projectile/bullet/chemdart/on_hit(var/atom/target, var/blocked = 0, var/def_zone = null) + if(blocked < 2 && isliving(target)) + var/mob/living/L = target + if(L.can_inject(target_zone=def_zone)) + reagents.trans_to(L, reagent_amount) + +/obj/item/ammo_casing/chemdart + name = "chemical dart" + desc = "A small hardened, hollow dart." + icon_state = "dart" + caliber = "dart" + projectile_type = /obj/item/projectile/bullet/chemdart + +/obj/item/ammo_casing/chemdart/expend() + del(src) + +/obj/item/ammo_magazine/chemdart + name = "dart cartridge" + desc = "A rack of hollow darts." + icon_state = "darts" + item_state = "rcdammo" + origin_tech = "materials=2" + mag_type = MAGAZINE + caliber = "dart" + ammo_type = /obj/item/ammo_casing/chemdart + max_ammo = 5 + multiple_sprites = 1 + +/obj/item/weapon/gun/projectile/dartgun + name = "dart gun" + desc = "A small gas-powered dartgun, capable of delivering chemical cocktails swiftly across short distances." + icon_state = "dartgun-empty" + + caliber = "dart" + fire_sound = 'sound/weapons/empty.ogg' + fire_sound_text = "a metallic click" + recoil = 0 + silenced = 1 + load_method = MAGAZINE + magazine_type = /obj/item/ammo_magazine/chemdart + auto_eject = 0 + + var/list/beakers = list() //All containers inside the gun. + var/list/mixing = list() //Containers being used for mixing. + var/max_beakers = 3 + var/dart_reagent_amount = 15 + var/container_type = /obj/item/weapon/reagent_containers/glass/beaker + var/list/starting_chems = null + +/obj/item/weapon/gun/projectile/dartgun/dartgun/New() + ..() + if(starting_chems) + for(var/chem in starting_chems) + var/obj/B = new container_type(src) + B.reagents.add_reagent(chem, 60) + beakers += B + update_icon() + +/obj/item/weapon/gun/projectile/dartgun/update_icon() + if(!ammo_magazine) + icon_state = "dartgun-empty" + return 1 + + if(!ammo_magazine.stored_ammo || ammo_magazine.stored_ammo.len) + icon_state = "dartgun-0" + else if(ammo_magazine.stored_ammo.len > 5) + icon_state = "dartgun-5" + else + icon_state = "dartgun-[ammo_magazine.stored_ammo.len]" + return 1 + +/obj/item/weapon/gun/projectile/dartgun/consume_next_projectile() + . = ..() + var/obj/item/projectile/bullet/chemdart/dart = . + if(istype(dart)) + fill_dart(dart) + +/obj/item/weapon/gun/projectile/dartgun/examine(mob/user) + //update_icon() + //if (!..(user, 2)) + // return + ..() + if (beakers.len) + user << "\blue [src] contains:" + for(var/obj/item/weapon/reagent_containers/glass/beaker/B in beakers) + if(B.reagents && B.reagents.reagent_list.len) + for(var/datum/reagent/R in B.reagents.reagent_list) + user << "\blue [R.volume] units of [R.name]" + +/obj/item/weapon/gun/projectile/dartgun/attackby(obj/item/I as obj, mob/user as mob) + if(istype(I, /obj/item/weapon/reagent_containers/glass)) + if(!istype(I, container_type)) + user << "\blue [I] doesn't seem to fit into [src]." + return + if(beakers.len >= max_beakers) + user << "\blue [src] already has [max_beakers] beakers in it - another one isn't going to fit!" + return + var/obj/item/weapon/reagent_containers/glass/beaker/B = I + user.drop_item() + B.loc = src + beakers += B + user << "\blue You slot [B] into [src]." + src.updateUsrDialog() + return 1 + ..() + +//fills the given dart with reagents +/obj/item/weapon/gun/projectile/dartgun/proc/fill_dart(var/obj/item/projectile/bullet/chemdart/dart) + if(mixing.len) + var/mix_amount = dart.reagent_amount/mixing.len + for(var/obj/item/weapon/reagent_containers/glass/beaker/B in mixing) + B.reagents.trans_to(dart, mix_amount) + +/obj/item/weapon/gun/projectile/dartgun/attack_self(mob/user) + user.set_machine(src) + var/dat = "[src] mixing control:

    " + + if (beakers.len) + var/i = 1 + for(var/obj/item/weapon/reagent_containers/glass/beaker/B in beakers) + dat += "Beaker [i] contains: " + if(B.reagents && B.reagents.reagent_list.len) + for(var/datum/reagent/R in B.reagents.reagent_list) + dat += "
    [R.volume] units of [R.name], " + if (check_beaker_mixing(B)) + dat += text("Mixing ") + else + dat += text("Not mixing ") + else + dat += "nothing." + dat += " \[Eject\]
    " + i++ + else + dat += "There are no beakers inserted!

    " + + if(ammo_magazine) + if(ammo_magazine.stored_ammo && ammo_magazine.stored_ammo.len) + dat += "The dart cartridge has [ammo_magazine.stored_ammo.len] shots remaining." + else + dat += "The dart cartridge is empty!" + dat += " \[Eject\]" + + user << browse(dat, "window=dartgun") + onclose(user, "dartgun", src) + +/obj/item/weapon/gun/projectile/dartgun/proc/check_beaker_mixing(var/obj/item/B) + if(!mixing || !beakers) + return 0 + for(var/obj/item/M in mixing) + if(M == B) + return 1 + return 0 + +/obj/item/weapon/gun/projectile/dartgun/Topic(href, href_list) + src.add_fingerprint(usr) + if(href_list["stop_mix"]) + var/index = text2num(href_list["stop_mix"]) + if(index <= beakers.len) + for(var/obj/item/M in mixing) + if(M == beakers[index]) + mixing -= M + break + else if (href_list["mix"]) + var/index = text2num(href_list["mix"]) + if(index <= beakers.len) + mixing += beakers[index] + else if (href_list["eject"]) + var/index = text2num(href_list["eject"]) + if(index <= beakers.len) + if(beakers[index]) + var/obj/item/weapon/reagent_containers/glass/beaker/B = beakers[index] + usr << "You remove [B] from [src]." + mixing -= B + beakers -= B + B.loc = get_turf(src) + else if (href_list["eject_cart"]) + unload_ammo(usr) + src.updateUsrDialog() + return + +/obj/item/weapon/gun/projectile/dartgun/vox + name = "alien dart gun" + desc = "A small gas-powered dartgun, fitted for nonhuman hands." + +/obj/item/weapon/gun/projectile/dartgun/vox/medical + starting_chems = list("kelotane","bicaridine","anti_toxin") + +/obj/item/weapon/gun/projectile/dartgun/vox/raider + starting_chems = list("space_drugs","stoxin","impedrezene") \ No newline at end of file diff --git a/code/modules/projectiles/guns/projectile/launcher.dm b/code/modules/projectiles/guns/projectile/launcher.dm deleted file mode 100644 index 6626d809cd..0000000000 --- a/code/modules/projectiles/guns/projectile/launcher.dm +++ /dev/null @@ -1,89 +0,0 @@ -/obj/item/weapon/gun/launcher - name = "launcher" - desc = "A device that launches things." - icon = 'icons/obj/weapons.dmi' - w_class = 5.0 - flags = CONDUCT - slot_flags = SLOT_BACK - - var/release_force = 0 - var/fire_sound_text = "a launcher firing" - -//Check if we're drawing and if the bow is loaded. -/obj/item/weapon/gun/launcher/load_into_chamber() - return (!isnull(in_chamber)) - -//This should not fit in a combat belt or holster. -/obj/item/weapon/gun/launcher/isHandgun() - return 0 - -//Launchers are mechanical, no other impact. -/obj/item/weapon/gun/launcher/emp_act(severity) - return - -//This normally uses a proc on projectiles and our ammo is not strictly speaking a projectile. -/obj/item/weapon/gun/launcher/can_hit(var/mob/living/target as mob, var/mob/living/user as mob) - return - -//Override this to avoid a runtime with suicide handling. -/obj/item/weapon/gun/launcher/attack(mob/living/M as mob, mob/living/user as mob, def_zone) - if (M == user && user.zone_sel.selecting == "mouth") - user << "\red Shooting yourself with \a [src] is pretty tricky. You can't seem to manage it." - return - ..() - -/obj/item/weapon/gun/launcher/proc/update_release_force() - return 0 - -/obj/item/weapon/gun/launcher/Fire(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, params, reflex = 0) - - if (!user.IsAdvancedToolUser()) - return 0 - - add_fingerprint(user) - - //Make sure target turfs both exist. - var/turf/curloc = get_turf(user) - var/turf/targloc = get_turf(target) - if (!istype(targloc) || !istype(curloc)) - return 0 - - if(!special_check(user)) - return 0 - - if (!ready_to_fire()) - if (world.time % 3) //to prevent spam - user << "[src] is not ready to fire again!" - return 0 - - if(!load_into_chamber()) //CHECK - return click_empty(user) - - if(!in_chamber) - return 0 - - update_release_force() - - playsound(user, fire_sound, 50, 1) - user.visible_message("[user] fires [src][reflex ? " by reflex":""]!", \ - "You fire [src][reflex ? "by reflex":""]!", \ - "You hear [fire_sound_text]!") - - in_chamber.loc = get_turf(user) - in_chamber.throw_at(target,10,release_force) - - sleep(1) - - in_chamber = null - - update_icon() - - if(user.hand) - user.update_inv_l_hand() - else - user.update_inv_r_hand() - - return 1 - -/obj/item/weapon/gun/launcher/attack_self(mob/living/user as mob) - return diff --git a/code/modules/projectiles/guns/projectile/pistol.dm b/code/modules/projectiles/guns/projectile/pistol.dm index a0c6b0e5cb..1d6df6f859 100644 --- a/code/modules/projectiles/guns/projectile/pistol.dm +++ b/code/modules/projectiles/guns/projectile/pistol.dm @@ -1,47 +1,70 @@ +/obj/item/weapon/gun/projectile/colt + name = "\improper Colt M1911" + desc = "A cheap Martian knock-off of a Colt M1911." + magazine_type = /obj/item/ammo_magazine/c45m + icon_state = "colt" + caliber = ".45" + origin_tech = "combat=2;materials=2" + load_method = MAGAZINE + +/obj/item/weapon/gun/projectile/colt/flash + name = "\improper Colt M1911 signal pistol" + desc = "A cheap Martian knock-off of a Colt M1911. Uses .45 signal flash rounds." + magazine_type = /obj/item/ammo_magazine/c45m/flash + +/obj/item/weapon/gun/projectile/colt/detective + desc = "A cheap Martian knock-off of a Colt M1911. Uses less-than-lethal .45 rounds." + magazine_type = /obj/item/ammo_magazine/c45m/rubber + +/obj/item/weapon/gun/projectile/colt/detective/verb/rename_gun() + set name = "Name Gun" + set category = "Object" + set desc = "Rename your gun. If you're the detective." + + var/mob/M = usr + if(!M.mind) return 0 + if(!M.mind.assigned_role == "Detective") + M << "You don't feel cool enough to name this gun, chump." + return 0 + + var/input = stripped_input(usr,"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." + return 1 + /obj/item/weapon/gun/projectile/silenced name = "silenced pistol" desc = "A small, quiet, easily concealable gun. Uses .45 rounds." icon_state = "silenced_pistol" - w_class = 3.0 - max_shells = 12 + w_class = 3 caliber = ".45" silenced = 1 origin_tech = "combat=2;materials=2;syndicate=8" - ammo_type = "/obj/item/ammo_casing/c45" - - + load_method = MAGAZINE + magazine_type = /obj/item/ammo_magazine/c45m /obj/item/weapon/gun/projectile/deagle name = "desert eagle" desc = "A robust handgun that uses .50 AE ammo" icon_state = "deagle" force = 14.0 - max_shells = 7 caliber = ".50" - ammo_type ="/obj/item/ammo_casing/a50" load_method = MAGAZINE - mag_type = /obj/item/ammo_magazine/a50/empty - - afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, flag) - ..() - if(!loaded.len && empty_mag) - empty_mag.loc = get_turf(src.loc) - empty_mag = null - playsound(user, 'sound/weapons/smg_empty_alarm.ogg', 40, 1) - update_icon() - return + magazine_type = /obj/item/ammo_magazine/a50 + auto_eject = 1 /obj/item/weapon/gun/projectile/deagle/gold desc = "A gold plated gun folded over a million times by superior martian gunsmiths. Uses .50 AE ammo." icon_state = "deagleg" item_state = "deagleg" - - /obj/item/weapon/gun/projectile/deagle/camo desc = "A Deagle brand Deagle for operators operating operationally. Uses .50 AE ammo." icon_state = "deaglecamo" item_state = "deagleg" + auto_eject_sound = 'sound/weapons/smg_empty_alarm.ogg' @@ -55,47 +78,35 @@ origin_tech = "combat=3" ammo_type = "/obj/item/ammo_casing/a75" load_method = MAGAZINE - mag_type = /obj/item/ammo_magazine/a75/empty + magazine_type = /obj/item/ammo_magazine/a75 + auto_eject = 1 + auto_eject_sound = 'sound/weapons/smg_empty_alarm.ogg' - afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, flag) - ..() - if(!loaded.len && empty_mag) - empty_mag.loc = get_turf(src.loc) - empty_mag = null - playsound(user, 'sound/weapons/smg_empty_alarm.ogg', 40, 1) - update_icon() - return - - update_icon() - ..() - if(empty_mag) - icon_state = "gyropistolloaded" - else - icon_state = "gyropistol" - return +/obj/item/weapon/gun/projectile/gyropistol/update_icon() + ..() + if(ammo_magazine) + icon_state = "gyropistolloaded" + else + icon_state = "gyropistol" /obj/item/weapon/gun/projectile/pistol name = "\improper Stechtkin pistol" desc = "A small, easily concealable gun. Uses 9mm rounds." icon_state = "pistol" w_class = 2 - max_shells = 10 caliber = "9mm" silenced = 0 origin_tech = "combat=2;materials=2;syndicate=2" - ammo_type = "/obj/item/ammo_casing/c9mm" load_method = MAGAZINE - mag_type = /obj/item/ammo_magazine/mc9mm + magazine_type = /obj/item/ammo_magazine/mc9mm -/obj/item/weapon/gun/projectile/pistol/afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, flag) - ..() - if(!loaded.len && empty_mag) - empty_mag.loc = get_turf(src.loc) - empty_mag = null - return +/obj/item/weapon/gun/projectile/pistol/flash + name = "\improper Stechtkin signal pistol" + desc = "A small, easily concealable gun. Uses 9mm signal flash rounds." + magazine_type = /obj/item/ammo_magazine/mc9mm/flash /obj/item/weapon/gun/projectile/pistol/attack_hand(mob/user as mob) - if(loc == user) + if(user.get_inactive_hand() == src) if(silenced) if(user.l_hand != src && user.r_hand != src) ..() @@ -108,7 +119,6 @@ return ..() - /obj/item/weapon/gun/projectile/pistol/attackby(obj/item/I as obj, mob/user as mob) if(istype(I, /obj/item/weapon/silencer)) if(user.l_hand != src && user.r_hand != src) //if we're not in his hands diff --git a/code/modules/projectiles/guns/projectile/revolver.dm b/code/modules/projectiles/guns/projectile/revolver.dm index 226e6467aa..9bef0c40d3 100644 --- a/code/modules/projectiles/guns/projectile/revolver.dm +++ b/code/modules/projectiles/guns/projectile/revolver.dm @@ -1,186 +1,42 @@ -/obj/item/weapon/gun/projectile/detective +/obj/item/weapon/gun/projectile/revolver + name = "revolver" + desc = "A classic revolver. Uses .357 ammo" + icon_state = "revolver" + caliber = "357" + origin_tech = "combat=2;materials=2" + handle_casings = CYCLE_CASINGS + max_shells = 7 + ammo_type = /obj/item/ammo_casing/a357 + +/obj/item/weapon/gun/projectile/revolver/mateba + name = "mateba" + desc = "When you absolutely, positively need a 10mm hole in the other guy. Uses .357 ammo." //>10mm hole >.357 + icon_state = "mateba" + origin_tech = "combat=2;materials=2" + +/obj/item/weapon/gun/projectile/revolver/detective name = "revolver" desc = "A cheap Martian knock-off of a Smith & Wesson Model 10. Uses .38-Special rounds." icon_state = "detective" max_shells = 6 caliber = "38" origin_tech = "combat=2;materials=2" - ammo_type = "/obj/item/ammo_casing/c38" + ammo_type = /obj/item/ammo_casing/c38 - special_check(var/mob/living/carbon/human/M) - if(caliber == initial(caliber)) - return 1 - if(prob(70 - (loaded.len * 10))) //minimum probability of 10, maximum of 60 - M << "[src] blows up in your face." - M.take_organ_damage(0,20) - M.drop_item() - del(src) - return 0 +/obj/item/weapon/gun/projectile/revolver/detective/verb/rename_gun() + set name = "Name Gun" + set category = "Object" + set desc = "Click to rename your gun. If you're the detective." + + var/mob/M = usr + if(!M.mind) return 0 + if(!M.mind.assigned_role == "Detective") + M << "You don't feel cool enough to name this gun, chump." + return 0 + + var/input = stripped_input(usr,"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." return 1 - - verb/rename_gun() - set name = "Name Gun" - set category = "Object" - set desc = "Click to rename your gun. If you're the detective." - - var/mob/M = usr - if(!M.mind) return 0 - if(!M.mind.assigned_role == "Detective") - M << "You don't feel cool enough to name this gun, chump." - return 0 - - var/input = stripped_input(usr,"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." - return 1 - - attackby(var/obj/item/A as obj, mob/user as mob) - ..() - if(istype(A, /obj/item/weapon/screwdriver)) - if(caliber == "38") - user << "You begin to reinforce the barrel of [src]." - if(loaded.len) - afterattack(user, user) //you know the drill - playsound(user, fire_sound, 50, 1) - user.visible_message("[src] goes off!", "[src] goes off in your face!") - return - if(do_after(user, 30)) - if(loaded.len) - user << "You can't modify it!" - return - caliber = "357" - desc = "The barrel and chamber assembly seems to have been modified." - user << "You reinforce the barrel of [src]! Now it will fire .357 rounds." - else if (caliber == "357") - user << "You begin to revert the modifications to [src]." - if(loaded.len) - afterattack(user, user) //and again - playsound(user, fire_sound, 50, 1) - user.visible_message("[src] goes off!", "[src] goes off in your face!") - return - if(do_after(user, 30)) - if(loaded.len) - user << "You can't modify it!" - return - caliber = "38" - desc = initial(desc) - user << "You remove the modifications on [src]! Now it will fire .38 rounds." - - -/obj/item/weapon/gun/projectile/detective/semiauto - name = "\improper Colt M1911" - desc = "A cheap Martian knock-off of a Colt M1911. Uses less-than-lethal .45 rounds." - icon_state = "colt" - max_shells = 7 - caliber = ".45" - ammo_type = "/obj/item/ammo_casing/c45r" - load_method = MAGAZINE - mag_type = /obj/item/ammo_magazine/c45r/empty - -/obj/item/weapon/gun/projectile/detective/semiauto/flash - ammo_type = "/obj/item/ammo_casing/c45f" - -/obj/item/weapon/gun/projectile/detective/semiauto/colt - desc = "A cheap Martian knock-off of a Colt M1911." - ammo_type = "/obj/item/ammo_casing/c45" - -/obj/item/weapon/gun/projectile/detective/semiauto/afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, flag) - ..() - if(!loaded.len && empty_mag) - empty_mag.loc = get_turf(src.loc) - empty_mag = null - user << "The Magazine falls out and clatters on the floor!" - return - - -/obj/item/weapon/gun/projectile/mateba - name = "mateba" - desc = "When you absolutely, positively need a 10mm hole in the other guy. Uses .357 ammo." //>10mm hole >.357 - icon_state = "mateba" - origin_tech = "combat=2;materials=2" - -// A gun to play Russian Roulette! -// You can spin the chamber to randomize the position of the bullet. - -/obj/item/weapon/gun/projectile/russian - name = "\improper Russian revolver" - desc = "A Russian made revolver. Uses .357 ammo. It has a single slot in it's chamber for a bullet." - max_shells = 6 - origin_tech = "combat=2;materials=2" - -/obj/item/weapon/gun/projectile/russian/New() - Spin() - update_icon() - -/obj/item/weapon/gun/projectile/russian/proc/Spin() - for(var/obj/item/ammo_casing/AC in loaded) - del(AC) - loaded = list() - var/random = rand(1, max_shells) - for(var/i = 1; i <= max_shells; i++) - if(i != random) - loaded += i // Basically null - else - loaded += new ammo_type(src) - - -/obj/item/weapon/gun/projectile/russian/attackby(var/obj/item/A as obj, mob/user as mob) - if(!A) return - - var/num_loaded = 0 - if(istype(A, /obj/item/ammo_magazine)) - - if((load_method == MAGAZINE) && loaded.len) return - var/obj/item/ammo_magazine/AM = A - for(var/obj/item/ammo_casing/AC in AM.stored_ammo) - if(getAmmo() > 0 || loaded.len >= max_shells) - break - if(AC.caliber == caliber && loaded.len < max_shells) - AC.loc = src - AM.stored_ammo -= AC - loaded += AC - num_loaded++ - break - A.update_icon() - - if(num_loaded) - user.visible_message("[user] loads a single bullet into the revolver and spins the chamber.", "You load a single bullet into the chamber and spin it.") - else - user.visible_message("[user] spins the chamber of the revolver.", "You spin the revolver's chamber.") - if(getAmmo() > 0) - Spin() - update_icon() - return - -/obj/item/weapon/gun/projectile/russian/attack_self(mob/user as mob) - user.visible_message("[user] spins the chamber of the revolver.", "You spin the revolver's chamber.") - if(getAmmo() > 0) - Spin() - -/obj/item/weapon/gun/projectile/russian/attack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj) - if(!loaded.len) - user.visible_message("\red *click*", "\red *click*") - playsound(user, 'sound/weapons/empty.ogg', 100, 1) - return - - if(isliving(target) && isliving(user)) - if(target == user) - var/datum/organ/external/affecting = user.zone_sel.selecting - if(affecting == "head") - - var/obj/item/ammo_casing/AC = loaded[1] - if(!load_into_chamber()) - user.visible_message("\red *click*", "\red *click*") - playsound(user, 'sound/weapons/empty.ogg', 100, 1) - return - if(!in_chamber) - return - var/obj/item/projectile/P = new AC.projectile_type - playsound(user, fire_sound, 50, 1) - user.visible_message("[user.name] fires [src] at \his head!", "You fire [src] at your head!", "You hear a [istype(in_chamber, /obj/item/projectile/beam) ? "laser blast" : "gunshot"]!") - if(!P.nodamage) - user.apply_damage(300, BRUTE, affecting, sharp=1) // You are dead, dead, dead. - return - ..() diff --git a/code/modules/projectiles/guns/projectile/rocket.dm b/code/modules/projectiles/guns/projectile/rocket.dm deleted file mode 100644 index 27fb15d571..0000000000 --- a/code/modules/projectiles/guns/projectile/rocket.dm +++ /dev/null @@ -1,51 +0,0 @@ -/obj/item/weapon/gun/rocketlauncher - name = "rocket launcher" - desc = "MAGGOT." - icon_state = "rocket" - item_state = "rocket" - w_class = 4.0 - throw_speed = 2 - throw_range = 10 - force = 5.0 - flags = CONDUCT | USEDELAY - slot_flags = 0 - origin_tech = "combat=8;materials=5" - var/projectile = /obj/item/missile - var/missile_speed = 2 - var/missile_range = 30 - var/max_rockets = 1 - var/list/rockets = new/list() - -/obj/item/weapon/gun/rocketlauncher/examine(mob/user) - if(!..(user, 2)) - return - user << "\blue [rockets.len] / [max_rockets] rockets." - -/obj/item/weapon/gun/rocketlauncher/attackby(obj/item/I as obj, mob/user as mob) - if(istype(I, /obj/item/ammo_casing/rocket)) - if(rockets.len < max_rockets) - user.drop_item() - I.loc = src - rockets += I - user << "\blue You put the rocket in [src]." - user << "\blue [rockets.len] / [max_rockets] rockets." - else - usr << "\red [src] cannot hold more rockets." - -/obj/item/weapon/gun/rocketlauncher/can_fire() - return rockets.len - -/obj/item/weapon/gun/rocketlauncher/Fire(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, params, reflex = 0) - if(rockets.len) - var/obj/item/ammo_casing/rocket/I = rockets[1] - var/obj/item/missile/M = new projectile(user.loc) - playsound(user.loc, 'sound/effects/bang.ogg', 50, 1) - M.primed = 1 - M.throw_at(target, missile_range, missile_speed,user) - message_admins("[key_name_admin(user)] fired a rocket from a rocket launcher ([src.name]).") - log_game("[key_name_admin(user)] used a rocket launcher ([src.name]).") - rockets -= I - del(I) - return - else - usr << "\red [src] is empty." diff --git a/code/modules/projectiles/guns/projectile/shotgun.dm b/code/modules/projectiles/guns/projectile/shotgun.dm index e96c7637e3..77a9867e93 100644 --- a/code/modules/projectiles/guns/projectile/shotgun.dm +++ b/code/modules/projectiles/guns/projectile/shotgun.dm @@ -10,127 +10,79 @@ slot_flags = SLOT_BACK caliber = "shotgun" origin_tech = "combat=4;materials=2" - ammo_type = "/obj/item/ammo_casing/shotgun/pellet" + load_method = SINGLE_CASING + ammo_type = /obj/item/ammo_casing/shotgun/pellet + handle_casings = HOLD_CASINGS var/recentpump = 0 // to prevent spammage - var/pumped = 0 - var/obj/item/ammo_casing/current_shell = null - isHandgun() - return 0 +/obj/item/weapon/gun/projectile/shotgun/pump/consume_next_projectile() + if(chambered) + return chambered.BB + return null - load_into_chamber() - if(in_chamber) - return 1 - return 0 +/obj/item/weapon/gun/projectile/shotgun/pump/attack_self(mob/living/user as mob) + if(world.time >= recentpump + 10) + pump(user) + recentpump = world.time - - attack_self(mob/living/user as mob) - if(recentpump) return - pump(user) - recentpump = 1 - spawn(10) - recentpump = 0 - return - - - proc/pump(mob/M as mob) - playsound(M, 'sound/weapons/shotgunpump.ogg', 60, 1) - pumped = 0 - if(current_shell)//We have a shell in the chamber - current_shell.loc = get_turf(src)//Eject casing - current_shell = null - if(in_chamber) - in_chamber = null - if(!loaded.len) return 0 +/obj/item/weapon/gun/projectile/shotgun/pump/proc/pump(mob/M as mob) + playsound(M, 'sound/weapons/shotgunpump.ogg', 60, 1) + + if(chambered)//We have a shell in the chamber + chambered.loc = get_turf(src)//Eject casing + chambered = null + + if(loaded.len) var/obj/item/ammo_casing/AC = loaded[1] //load next casing. loaded -= AC //Remove casing from loaded list. - current_shell = AC - if(AC.BB) - in_chamber = AC.BB //Load projectile into chamber. - update_icon() //I.E. fix the desc - return 1 + chambered = AC + + update_icon() /obj/item/weapon/gun/projectile/shotgun/pump/combat name = "combat shotgun" icon_state = "cshotgun" - max_shells = 8 origin_tech = "combat=5;materials=2" - ammo_type = "/obj/item/ammo_casing/shotgun" + max_shells = 8 + ammo_type = /obj/item/ammo_casing/shotgun + -//this is largely hacky and bad :( -Pete /obj/item/weapon/gun/projectile/shotgun/doublebarrel name = "double-barreled shotgun" desc = "A true classic." icon_state = "dshotgun" item_state = "shotgun" + //SPEEDLOADER because rapid unloading. + //In principle someone could make a speedloader for it, so it makes sense. + load_method = SINGLE_CASING|SPEEDLOADER + handle_casings = CYCLE_CASINGS max_shells = 2 - w_class = 4.0 + w_class = 4 force = 10 flags = CONDUCT slot_flags = SLOT_BACK caliber = "shotgun" - origin_tech = "combat=3;materials=1" - ammo_type = "/obj/item/ammo_casing/shotgun/beanbag" + origin_tech = "combat=3;materials=1" + ammo_type = /obj/item/ammo_casing/shotgun/beanbag - New() - for(var/i = 1, i <= max_shells, i++) - loaded += new ammo_type(src) - - update_icon() - return - - load_into_chamber() -// if(in_chamber) -// return 1 {R} - if(!loaded.len) - return 0 - - var/obj/item/ammo_casing/AC = loaded[1] //load next casing. - loaded -= AC //Remove casing from loaded list. - AC.desc += " This one is spent." - - if(AC.BB) - in_chamber = AC.BB //Load projectile into chamber. - return 1 - return 0 - - attack_self(mob/living/user as mob) - if(!(locate(/obj/item/ammo_casing/shotgun) in src) && !loaded.len) - user << "\The [src] is empty." - return - - for(var/obj/item/ammo_casing/shotgun/shell in src) //This feels like a hack. //don't code at 3:30am kids!! - if(shell in loaded) - loaded -= shell - shell.loc = get_turf(src.loc) - - user << "You break \the [src]." - update_icon() - - attackby(var/obj/item/A as obj, mob/user as mob) - if(istype(A, /obj/item/ammo_casing) && !load_method) - var/obj/item/ammo_casing/AC = A - if(AC.caliber == caliber && (loaded.len < max_shells) && (contents.len < max_shells)) //forgive me father, for i have sinned - user.drop_item() - AC.loc = src - loaded += AC - user << "You load a shell into \the [src]!" - A.update_icon() - update_icon() - if(istype(A, /obj/item/weapon/circular_saw) || istype(A, /obj/item/weapon/melee/energy) || istype(A, /obj/item/weapon/pickaxe/plasmacutter)) - user << "You begin to shorten the barrel of \the [src]." - if(loaded.len) - afterattack(user, user) //will this work? - afterattack(user, user) //it will. we call it twice, for twice the FUN +//this is largely hacky and bad :( -Pete +/obj/item/weapon/gun/projectile/shotgun/doublebarrel/attackby(var/obj/item/A as obj, mob/user as mob) + if(istype(A, /obj/item/weapon/circular_saw) || istype(A, /obj/item/weapon/melee/energy) || istype(A, /obj/item/weapon/pickaxe/plasmacutter)) + user << "You begin to shorten the barrel of \the [src]." + if(loaded.len) + for(var/i in 1 to max_shells) + afterattack(user, user) //will this work? //it will. we call it twice, for twice the FUN playsound(user, fire_sound, 50, 1) - user.visible_message("The shotgun goes off!", "The shotgun goes off in your face!") - return - if(do_after(user, 30)) //SHIT IS STEALTHY EYYYYY - icon_state = "sawnshotgun" - w_class = 3.0 - item_state = "gun" - slot_flags &= ~SLOT_BACK //you can't sling it on your back - slot_flags |= SLOT_BELT //but you can wear it on your belt (poorly concealed under a trenchcoat, ideally) - name = "sawn-off shotgun" - desc = "Omar's coming!" - user << "You shorten the barrel of \the [src]!" + user.visible_message("The shotgun goes off!", "The shotgun goes off in your face!") + return + if(do_after(user, 30)) //SHIT IS STEALTHY EYYYYY + icon_state = "sawnshotgun" + w_class = 3 + item_state = "gun" + slot_flags &= ~SLOT_BACK //you can't sling it on your back + slot_flags |= (SLOT_BELT|SLOT_HOLSTER) //but you can wear it on your belt (poorly concealed under a trenchcoat, ideally) - or in a holster, why not. + name = "sawn-off shotgun" + desc = "Omar's coming!" + user << "You shorten the barrel of \the [src]!" + else + ..() \ No newline at end of file diff --git a/code/modules/projectiles/guns/projectile/sniper.dm b/code/modules/projectiles/guns/projectile/sniper.dm new file mode 100644 index 0000000000..4bab0678b7 --- /dev/null +++ b/code/modules/projectiles/guns/projectile/sniper.dm @@ -0,0 +1,67 @@ +/obj/item/weapon/gun/projectile/heavysniper + name = "\improper PTRS-7 rifle" + desc = "A portable anti-armour rifle fitted with a scope. Originally designed to used against lightly armoured exosuits, it is capable of punching through non-reinforced walls with ease. Fires 14.5mm AP shells." + icon_state = "heavysniper" + item_state = "sniper0" + w_class = 4 + force = 10 + slot_flags = SLOT_BACK + origin_tech = "combat=8;materials=2;syndicate=8" + caliber = "14.5mm" + recoil = 2 //extra kickback + //fire_sound = 'sound/weapons/sniper.ogg' + handle_casings = HOLD_CASINGS + load_method = SINGLE_CASING + max_shells = 1 + ammo_type = /obj/item/ammo_casing/a145 + //+2 accuracy over the LWAP because only one shot + accuracy = -1 + scoped_accuracy = 2 + var/bolt_open = 0 + +/obj/item/weapon/gun/projectile/heavysniper/update_icon() + if(bolt_open) + icon_state = "heavysniper-open" + else + icon_state = "heavysniper" + +/obj/item/weapon/gun/projectile/heavysniper/attack_self(mob/user as mob) + playsound(src.loc, 'sound/weapons/flipblade.ogg', 50, 1) + bolt_open = !bolt_open + if(bolt_open) + if(chambered) + user << "You work the bolt open, ejecting [chambered]!" + chambered.loc = get_turf(src) + loaded -= chambered + chambered = null + else + user << "You work the bolt open." + else + user << "You work the bolt closed." + bolt_open = 0 + add_fingerprint(user) + update_icon() + +/obj/item/weapon/gun/projectile/heavysniper/special_check(mob/user) + if(bolt_open) + user << "You can't fire [src] while the bolt is open!" + return 0 + return ..() + +/obj/item/weapon/gun/projectile/heavysniper/load_ammo(var/obj/item/A, mob/user) + if(!bolt_open) + return + ..() + +/obj/item/weapon/gun/projectile/heavysniper/unload_ammo(mob/user, var/allow_dump=1) + if(!bolt_open) + return + ..() + +/obj/item/weapon/gun/projectile/heavysniper/verb/scope() + set category = "Object" + set name = "Use Scope" + set popup_menu = 1 + + toggle_scope(2.0) + diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index 0ca1ab93fc..6176a48569 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -37,7 +37,7 @@ var/damage_type = BRUTE //BRUTE, BURN, TOX, OXY, CLONE are the only things that should be in here var/nodamage = 0 //Determines if the projectile will skip any damage inflictions var/taser_effect = 0 //If set then the projectile will apply it's agony damage using stun_effect_act() to mobs it hits, and other damage will be ignored - var/flag = "bullet" //Defines what armor to use when it hits things. Must be set to bullet, laser, energy,or bomb //Cael - bio and rad are also valid + var/check_armour = "bullet" //Defines what armor to use when it hits things. Must be set to bullet, laser, energy,or bomb //Cael - bio and rad are also valid var/projectile_type = /obj/item/projectile var/penetrating = 0 //If greater than zero, the projectile will pass through dense objects as specified by on_penetrate() var/kill_count = 50 //This will de-increment every process(). When 0, it will delete the projectile. @@ -69,20 +69,19 @@ /obj/item/projectile/proc/on_penetrate(var/atom/A) return 1 -/obj/item/projectile/proc/check_fire(var/mob/living/target as mob, var/mob/living/user as mob) //Checks if you can hit them or not. - if(!istype(target) || !istype(user)) - return 0 - var/obj/item/projectile/test/in_chamber = new /obj/item/projectile/test(get_step_to(user,target)) //Making the test.... - in_chamber.target = target - in_chamber.flags = flags //Set the flags... - in_chamber.pass_flags = pass_flags //And the pass flags to that of the real projectile... - in_chamber.firer = user - var/output = in_chamber.process() //Test it! - del(in_chamber) //No need for it anymore - return output //Send it back to the gun! +/obj/item/projectile/proc/check_fire(atom/target as mob, var/mob/living/user as mob) //Checks if you can hit them or not. + check_trajectory(target, user, pass_flags, flags) + +//sets the click point of the projectile using mouse input params +/obj/item/projectile/proc/set_clickpoint(var/params) + var/list/mouse_control = params2list(params) + if(mouse_control["icon-x"]) + p_x = text2num(mouse_control["icon-x"]) + if(mouse_control["icon-y"]) + p_y = text2num(mouse_control["icon-y"]) //called to launch a projectile from a gun -/obj/item/projectile/proc/launch(atom/target, mob/user, obj/item/weapon/gun/launcher, var/target_zone, var/x_offset=0, var/y_offset=0, var/px=null, var/py=null) +/obj/item/projectile/proc/launch(atom/target, mob/user, obj/item/weapon/gun/launcher, var/target_zone, var/x_offset=0, var/y_offset=0) var/turf/curloc = get_turf(user) var/turf/targloc = get_turf(target) if (!istype(targloc) || !istype(curloc)) @@ -93,10 +92,12 @@ if(user == target) //Shooting yourself user.bullet_act(src, target_zone) + on_impact(user) del(src) return 0 - if(targloc == curloc) //Shooting the ground - targloc.bullet_act(src, target_zone) + if(targloc == curloc) //Shooting something in the same turf + target.bullet_act(src, target_zone) + on_impact(target) del(src) return 0 @@ -106,8 +107,6 @@ current = curloc yo = targloc.y - curloc.y + y_offset xo = targloc.x - curloc.x + x_offset - if(!isnull(py)) p_y = py - if(!isnull(px)) p_x = px shot_from = launcher silenced = launcher.silenced @@ -129,15 +128,16 @@ xo = new_x - starting_loc.x //Called when the projectile intercepts a mob. Returns 1 if the projectile hit the mob, 0 if it missed and should keep flying. -/obj/item/projectile/proc/attack_mob(var/mob/living/target_mob, var/distance, var/miss_modifier = -30) +/obj/item/projectile/proc/attack_mob(var/mob/living/target_mob, var/distance, var/miss_modifier) //accuracy bonus from aiming if (istype(shot_from, /obj/item/weapon/gun)) //If you aim at someone beforehead, it'll hit more often. var/obj/item/weapon/gun/daddy = shot_from //Kinda balanced by fact you need like 2 seconds to aim - if (daddy.target && original in daddy.target) //As opposed to no-delay pew pew + miss_modifier -= round(15*daddy.accuracy) + if (daddy.aim_targets && original in daddy.aim_targets) //As opposed to no-delay pew pew miss_modifier += -30 //roll to-hit - var/hit_zone = get_zone_with_miss_chance(def_zone, target_mob, max(miss_modifier + 15*distance, 0)) + var/hit_zone = get_zone_with_miss_chance(def_zone, target_mob, max(miss_modifier + 15*(distance-2), 0)) if(!hit_zone) visible_message("\The [src] misses [target_mob] narrowly!") return 0 @@ -228,10 +228,10 @@ return 1 /obj/item/projectile/process() - if(kill_count < 1) - del(src) - kill_count-- spawn while(src) + if(kill_count-- < 1) + on_impact(src.loc) //for any final impact behaviours + del(src) if((!( current ) || loc == current)) current = locate(min(max(x + xo, 1), world.maxx), min(max(y + yo, 1), world.maxy), z) if((x == 1 || x == world.maxx || y == 1 || y == world.maxy)) @@ -244,7 +244,8 @@ if(!(original in permutated)) Bump(original) sleep(1) - + +//"Tracing" projectile /obj/item/projectile/test //Used to see if you can hit them. invisibility = 101 //Nope! Can't see me! yo = null @@ -285,3 +286,16 @@ M = locate() in get_step(src,target) if(istype(M)) return 1 + +/proc/check_trajectory(atom/target as mob, var/mob/living/user as mob, var/pass_flags=PASSTABLE|PASSGLASS|PASSGRILLE, flags=null) //Checks if you can hit them or not. + if(!istype(target) || !istype(user)) + return 0 + var/obj/item/projectile/test/trace = new /obj/item/projectile/test(get_step_to(user,target)) //Making the test.... + trace.target = target + if(!isnull(flags)) + trace.flags = flags //Set the flags... + trace.pass_flags = pass_flags //And the pass flags to that of the real projectile... + trace.firer = user + var/output = trace.process() //Test it! + del(trace) //No need for it anymore + return output //Send it back to the gun! \ No newline at end of file diff --git a/code/modules/projectiles/projectile/animate.dm b/code/modules/projectiles/projectile/animate.dm index 490227d233..0f92729ad4 100644 --- a/code/modules/projectiles/projectile/animate.dm +++ b/code/modules/projectiles/projectile/animate.dm @@ -4,7 +4,7 @@ damage = 0 damage_type = BURN nodamage = 1 - flag = "energy" + check_armour = "energy" /obj/item/projectile/animate/Bump(var/atom/change) if((istype(change, /obj/item) || istype(change, /obj/structure)) && !is_type_in_list(change, protected_objects)) diff --git a/code/modules/projectiles/projectile/beams.dm b/code/modules/projectiles/projectile/beams.dm index 23ee20e132..b5ce31b168 100644 --- a/code/modules/projectiles/projectile/beams.dm +++ b/code/modules/projectiles/projectile/beams.dm @@ -14,7 +14,7 @@ var/list/beam_master = list() pass_flags = PASSTABLE | PASSGLASS | PASSGRILLE damage = 40 damage_type = BURN - flag = "laser" + check_armour = "laser" eyeblur = 4 var/frequency = 1 @@ -87,7 +87,7 @@ var/list/beam_master = list() pass_flags = PASSTABLE | PASSGLASS | PASSGRILLE damage = 0 damage_type = BURN - flag = "laser" + check_armour = "laser" eyeblur = 2 /obj/item/projectile/beam/heavylaser @@ -121,7 +121,7 @@ var/list/beam_master = list() pass_flags = PASSTABLE | PASSGLASS | PASSGRILLE damage = 0 damage_type = BURN - flag = "laser" + check_armour = "laser" /obj/item/projectile/beam/lastertag/blue/on_hit(var/atom/target, var/blocked = 0) if(istype(target, /mob/living/carbon/human)) @@ -136,7 +136,7 @@ var/list/beam_master = list() pass_flags = PASSTABLE | PASSGLASS | PASSGRILLE damage = 0 damage_type = BURN - flag = "laser" + check_armour = "laser" /obj/item/projectile/beam/lastertag/red/on_hit(var/atom/target, var/blocked = 0) if(istype(target, /mob/living/carbon/human)) @@ -151,7 +151,7 @@ var/list/beam_master = list() pass_flags = PASSTABLE | PASSGLASS | PASSGRILLE damage = 0 damage_type = BURN - flag = "laser" + check_armour = "laser" /obj/item/projectile/beam/lastertag/omni/on_hit(var/atom/target, var/blocked = 0) if(istype(target, /mob/living/carbon/human)) @@ -164,9 +164,9 @@ var/list/beam_master = list() name = "sniper beam" icon_state = "xray" damage = 60 - stun = 5 - weaken = 5 - stutter = 5 + stun = 3 + weaken = 3 + stutter = 3 /obj/item/projectile/beam/stun name = "stun beam" diff --git a/code/modules/projectiles/projectile/bullets.dm b/code/modules/projectiles/projectile/bullets.dm index 5da27e9ef0..e473a11405 100644 --- a/code/modules/projectiles/projectile/bullets.dm +++ b/code/modules/projectiles/projectile/bullets.dm @@ -4,7 +4,7 @@ damage = 60 damage_type = BRUTE nodamage = 0 - flag = "bullet" + check_armour = "bullet" embed = 1 sharp = 1 @@ -21,27 +21,27 @@ if(ismob(A)) if(iscarbon(A)) - //squishy mobs absorb KE - if (damage <= 20) return 0 - damage *= 0.7 + if (damage <= 20 && !prob(damage)) return 0 + damage *= 0.7 //squishy mobs absorb KE return 1 - if(istype(A, /obj/machinery) || istype(A, /obj/structure)) - var/chance = 15 - if(istype(A, /turf/simulated/wall)) - var/turf/simulated/wall/W = A - chance = round(damage/W.damage_cap*100) - else if(istype(A, /obj/machinery/door)) - var/obj/machinery/door/D = A - chance = round(damage/D.maxhealth*100) - else if(istype(A, /obj/structure/girder) || istype(A, /obj/structure/cultgirder)) - chance = 100 - - if(prob(chance)) - if(A.opacity) - //display a message so that people on the other side aren't so confused - A.visible_message("\The [src] pierces through \the [A]!") - return 1 + var/chance = 0 + if(istype(A, /turf/simulated/wall)) + var/turf/simulated/wall/W = A + chance = round(damage/W.damage_cap*180) + else if(istype(A, /obj/machinery/door)) + var/obj/machinery/door/D = A + chance = round(damage/D.maxhealth*100) + else if(istype(A, /obj/structure/girder) || istype(A, /obj/structure/cultgirder)) + chance = 100 + else if(istype(A, /obj/machinery) || istype(A, /obj/structure)) + chance = 15 + + if(prob(chance)) + if(A.opacity) + //display a message so that people on the other side aren't so confused + A.visible_message("\The [src] pierces through \the [A]!") + return 1 return 0 @@ -122,10 +122,13 @@ /* "Rifle" rounds */ /obj/item/projectile/bullet/rifle/a762 - damage = 25 + damage = 30 + penetrating = 1 /obj/item/projectile/bullet/rifle/a145 - damage = 90 + damage = 80 + stun = 3 + weaken = 3 penetrating = 5 /* Miscellaneous */ diff --git a/code/modules/projectiles/projectile/change.dm b/code/modules/projectiles/projectile/change.dm index 215c117342..24e2d4b6ef 100644 --- a/code/modules/projectiles/projectile/change.dm +++ b/code/modules/projectiles/projectile/change.dm @@ -4,7 +4,7 @@ damage = 0 damage_type = BURN nodamage = 1 - flag = "energy" + check_armour = "energy" on_hit(var/atom/change) wabbajack(change) diff --git a/code/modules/projectiles/projectile/energy.dm b/code/modules/projectiles/projectile/energy.dm index 851f691b41..2a114e9067 100644 --- a/code/modules/projectiles/projectile/energy.dm +++ b/code/modules/projectiles/projectile/energy.dm @@ -3,37 +3,42 @@ icon_state = "spark" damage = 0 damage_type = BURN - flag = "energy" + check_armour = "energy" -//releases a very short burst of light on impact, mainly used to blind people +//releases a burst of light on impact or after travelling a distance /obj/item/projectile/energy/flash - name = "shell" //a chemical filled shell or something + name = "chemical shell" icon_state = "bullet" damage = 5 - var/flash_range = 1 - var/brightness = 5 - var/light_duration = 10 - -/obj/item/projectile/energy/flash/on_impact() - var/turf/T = get_turf(src) + kill_count = 15 //if the shell hasn't hit anything after travelling this far it just explodes. + var/flash_range = 0 + var/brightness = 7 + var/light_duration = 5 +/obj/item/projectile/energy/flash/on_impact(var/atom/A) + var/turf/T = flash_range? src.loc : get_turf(A) if(!istype(T)) return - src.visible_message("\The [src] explodes in a bright flash!") + //blind adjacent people for (var/mob/living/carbon/M in viewers(T, flash_range)) if(M.eyecheck() < 1) flick("e_flash", M.flash) + //snap pop playsound(src, 'sound/effects/snap.ogg', 50, 1) - new/obj/effect/effect/smoke/illumination(src.loc, brightness=max(flash_range*2, brightness), lifetime=light_duration) + src.visible_message("\The [src] explodes in a bright flash!") + + new /obj/effect/decal/cleanable/ash(src.loc) //always use src.loc so that ash doesn't end up inside windows + new /obj/effect/effect/sparks(T) + new /obj/effect/effect/smoke/illumination(T, brightness=max(flash_range*2, brightness), lifetime=light_duration) //blinds people like the flash round, but can also be used for temporary illumination /obj/item/projectile/energy/flash/flare damage = 10 flash_range = 1 - brightness = 7 //similar to a flare - light_duration = 150 + brightness = 9 //similar to a flare + light_duration = 200 /obj/item/projectile/energy/electrode name = "electrode" diff --git a/code/modules/projectiles/projectile/force.dm b/code/modules/projectiles/projectile/force.dm index 4dffe4ce89..71b7d34d04 100644 --- a/code/modules/projectiles/projectile/force.dm +++ b/code/modules/projectiles/projectile/force.dm @@ -3,7 +3,7 @@ icon = 'icons/obj/projectiles.dmi' icon_state = "ice_1" damage = 20 - flag = "energy" + check_armour = "energy" /obj/item/projectile/forcebolt/strong name = "force bolt" diff --git a/code/modules/projectiles/projectile/special.dm b/code/modules/projectiles/projectile/special.dm index c7c2c05c4a..fc69f6ec94 100644 --- a/code/modules/projectiles/projectile/special.dm +++ b/code/modules/projectiles/projectile/special.dm @@ -4,7 +4,7 @@ damage = 0 damage_type = BURN nodamage = 1 - flag = "energy" + check_armour = "energy" on_hit(var/atom/target, var/blocked = 0) @@ -16,7 +16,7 @@ name ="explosive bolt" icon_state= "bolter" damage = 50 - flag = "bullet" + check_armour = "bullet" sharp = 1 edge = 1 @@ -30,7 +30,7 @@ damage = 0 damage_type = BURN nodamage = 1 - flag = "energy" + check_armour = "energy" var/temperature = 300 @@ -47,7 +47,7 @@ damage = 0 damage_type = BRUTE nodamage = 1 - flag = "bullet" + check_armour = "bullet" Bump(atom/A as mob|obj|turf|area) if(A == firer) @@ -76,7 +76,7 @@ damage = 0 damage_type = TOX nodamage = 1 - flag = "energy" + check_armour = "energy" on_hit(var/atom/target, var/blocked = 0) var/mob/living/M = target @@ -115,7 +115,7 @@ damage = 0 damage_type = TOX nodamage = 1 - flag = "energy" + check_armour = "energy" on_hit(var/atom/target, var/blocked = 0) var/mob/M = target diff --git a/code/modules/projectiles/targeting.dm b/code/modules/projectiles/targeting.dm index 496455f24e..c3988ff2ff 100644 --- a/code/modules/projectiles/targeting.dm +++ b/code/modules/projectiles/targeting.dm @@ -1,10 +1,10 @@ /obj/item/weapon/gun/verb/toggle_firerate() - set name = "Toggle Firerate" + set name = "Toggle Continue Aiming" set category = "Object" - firerate = !firerate + keep_aim = !keep_aim - if (firerate) + if (keep_aim) loc << "You will now continue firing when your target moves." else loc << "You will now only fire once, then lower your aim, when your target moves." @@ -12,7 +12,7 @@ /obj/item/weapon/gun/verb/lower_aim() set name = "Lower Aim" set category = "Object" - if(target) + if(aim_targets) stop_aim() usr.visible_message("\blue \The [usr] lowers \the [src]...") @@ -34,13 +34,13 @@ user.client.remove_gun_icons() return ..() -//Removes lock fro mall targets +//Removes lock from all targets /obj/item/weapon/gun/proc/stop_aim() - if(target) - for(var/mob/living/M in target) + if(aim_targets) + for(var/mob/living/M in aim_targets) if(M) M.NotTargeted(src) //Untargeting people. - del(target) + del(aim_targets) //Compute how to fire..... //Return 1 if a target was found, 0 otherwise. @@ -49,13 +49,13 @@ if(lock_time > world.time - 2) return user.set_dir(get_cardinal_dir(src, A)) - if(isliving(A) && !(A in target)) + if(isliving(A) && !(A in aim_targets)) Aim(A) //Clicked a mob, aim at them return 1 //Didn't click someone, check if there is anyone along that guntrace var/mob/living/M = GunTrace(usr.x,usr.y,A.x,A.y,usr.z,usr) //Find dat mob. - if(isliving(M) && (M in view(user)) && !(M in target)) + if(isliving(M) && (M in view(user)) && !(M in aim_targets)) Aim(M) //Aha! Aim at them! return 1 @@ -63,13 +63,13 @@ //Aiming at the target mob. /obj/item/weapon/gun/proc/Aim(var/mob/living/M) - if(!target || !(M in target)) + if(!aim_targets || !(M in aim_targets)) lock_time = world.time - if(target && !automatic) //If they're targeting someone and they have a non automatic weapon. - for(var/mob/living/L in target) + if(aim_targets && !multi_aim) //If they're targeting someone and they have a non multi_aim weapon. + for(var/mob/living/L in aim_targets) if(L) L.NotTargeted(src) - del(target) + del(aim_targets) usr.visible_message("\red [usr] turns \the [src] on [M]!") else usr.visible_message("\red [usr] aims \a [src] at [M]!") @@ -90,29 +90,26 @@ return M.last_move_intent = world.time - if(can_fire()) - var/firing_check = can_hit(T,usr) //0 if it cannot hit them, 1 if it is capable of hitting, and 2 if a special check is preventing it from firing. - if(firing_check > 0) - if(firing_check == 1) - Fire(T,usr, reflex = 1) - else if(!told_cant_shoot) - M << "\red They can't be hit from here!" - told_cant_shoot = 1 - spawn(30) - told_cant_shoot = 0 - else - click_empty(M) + var/firing_check = can_hit(T,usr) //0 if it cannot hit them, 1 if it is capable of hitting, and 2 if a special check is preventing it from firing. + if(firing_check > 0) + if(firing_check == 1) + Fire(T,usr, reflex = 1) + else if(!told_cant_shoot) + M << "\red They can't be hit from here!" + told_cant_shoot = 1 + spawn(30) + told_cant_shoot = 0 usr.set_dir(get_cardinal_dir(src, T)) - if (!firerate) // If firerate is set to lower aim after one shot, untarget the target + if (!keep_aim) // If keep_aim is set to lower aim after one shot, untarget the target T.NotTargeted(src) //Yay, math! #define SIGN(X) ((X<0)?-1:1) -proc/GunTrace(X1,Y1,X2,Y2,Z=1,exc_obj,PX1=16,PY1=16,PX2=16,PY2=16) +/proc/GunTrace(X1,Y1,X2,Y2,Z=1,exc_obj,PX1=16,PY1=16,PX2=16,PY2=16) //bluh << "Tracin' [X1],[Y1] to [X2],[Y2] on floor [Z]." var/turf/T var/mob/living/M @@ -150,19 +147,19 @@ proc/GunTrace(X1,Y1,X2,Y2,Z=1,exc_obj,PX1=16,PY1=16,PX2=16,PY2=16) //Targeting management procs -mob/var +/mob/var list/targeted_by target_time = -100 last_move_intent = -100 last_target_click = -5 target_locked = null -mob/living/proc/Targeted(var/obj/item/weapon/gun/I) //Self explanitory. - if(!I.target) - I.target = list(src) - else if(I.automatic && I.target.len < 5) //Automatic weapon, they can hold down a room. - I.target += src - else if(I.target.len >= 5) +/mob/living/proc/Targeted(var/obj/item/weapon/gun/I) //Self explanitory. + if(!I.aim_targets) + I.aim_targets = list(src) + else if(I.multi_aim && I.aim_targets.len < 5) //multi_aim weapon, they can hold down a room. + I.aim_targets += src + else if(I.aim_targets.len >= 5) if(ismob(I.loc)) I.loc << "You can only target 5 people at once!" return @@ -223,43 +220,43 @@ mob/living/proc/Targeted(var/obj/item/weapon/gun/I) //Self explanitory. I.last_moved_mob = src sleep(1) -mob/living/proc/NotTargeted(var/obj/item/weapon/gun/I) +/mob/living/proc/NotTargeted(var/obj/item/weapon/gun/I) if(!I.silenced) for(var/mob/living/M in viewers(src)) M << 'sound/weapons/TargetOff.ogg' targeted_by -= I - I.target.Remove(src) //De-target them - if(!I.target.len) - del(I.target) + I.aim_targets.Remove(src) //De-target them + if(!I.aim_targets.len) + del(I.aim_targets) var/mob/living/T = I.loc //Remove the targeting icons - if(T && ismob(T) && !I.target) + if(T && ismob(T) && !I.aim_targets) T.client.remove_gun_icons() if(!targeted_by.len) del target_locked //Remove the overlay del targeted_by spawn(1) update_targeted() -mob/living/Move() +/mob/living/Move() . = ..() for(var/obj/item/weapon/gun/G in targeted_by) //Handle moving out of the gunner's view. var/mob/living/M = G.loc if(!(M in view(src))) NotTargeted(G) for(var/obj/item/weapon/gun/G in src) //Handle the gunner loosing sight of their target/s - if(G.target) - for(var/mob/living/M in G.target) + if(G.aim_targets) + for(var/mob/living/M in G.aim_targets) if(M && !(M in view(src))) M.NotTargeted(G) //If you move out of range, it isn't going to still stay locked on you any more. -client/var +/client/var target_can_move = 0 target_can_run = 0 target_can_click = 0 gun_mode = 0 //These are called by the on-screen buttons, adjusting what the victim can and cannot do. -client/proc/add_gun_icons() +/client/proc/add_gun_icons() screen += usr.item_use_icon screen += usr.gun_move_icon if (target_can_move) @@ -267,14 +264,15 @@ client/proc/add_gun_icons() -client/proc/remove_gun_icons() +/client/proc/remove_gun_icons() if(!usr) return 1 // Runtime prevention on N00k agents spawning with SMG screen -= usr.item_use_icon screen -= usr.gun_move_icon if (target_can_move) screen -= usr.gun_run_icon -client/verb/ToggleGunMode() +/client/verb/ToggleGunMode() + set name = "Toggle Gun Mode" set hidden = 1 gun_mode = !gun_mode if(gun_mode) @@ -288,7 +286,7 @@ client/verb/ToggleGunMode() usr.gun_setting_icon.icon_state = "gun[gun_mode]" -client/verb/AllowTargetMove() +/client/verb/AllowTargetMove() set hidden=1 //Changing client's permissions @@ -310,8 +308,8 @@ client/verb/AllowTargetMove() //Handling change for all the guns on client for(var/obj/item/weapon/gun/G in usr) G.lock_time = world.time + 5 - if(G.target) - for(var/mob/living/M in G.target) + if(G.aim_targets) + for(var/mob/living/M in G.aim_targets) if(target_can_move) M << "Your character may now walk at the discretion of their targeter." if(!target_can_run) @@ -320,7 +318,7 @@ client/verb/AllowTargetMove() else M << "\red Your character will now be shot if they move." -mob/living/proc/set_m_intent(var/intent) +/mob/living/proc/set_m_intent(var/intent) if (intent != "walk" && intent != "run") return 0 m_intent = intent @@ -346,14 +344,14 @@ client/verb/AllowTargetRun() //Handling change for all the guns on client for(var/obj/item/weapon/gun/G in src) G.lock_time = world.time + 5 - if(G.target) - for(var/mob/living/M in G.target) + if(G.aim_targets) + for(var/mob/living/M in G.aim_targets) if(target_can_run) M << "Your character may now run at the discretion of their targeter." else M << "\red Your character will now be shot if they run." -client/verb/AllowTargetClick() +/client/verb/AllowTargetClick() set hidden=1 //Changing client's permissions @@ -370,8 +368,8 @@ client/verb/AllowTargetClick() //Handling change for all the guns on client for(var/obj/item/weapon/gun/G in src) G.lock_time = world.time + 5 - if(G.target) - for(var/mob/living/M in G.target) + if(G.aim_targets) + for(var/mob/living/M in G.aim_targets) if(target_can_click) M << "Your character may now use items at the discretion of their targeter." else diff --git a/code/modules/reagents/dartgun.dm b/code/modules/reagents/dartgun.dm deleted file mode 100644 index d256f4f5f3..0000000000 --- a/code/modules/reagents/dartgun.dm +++ /dev/null @@ -1,293 +0,0 @@ -/obj/item/weapon/dart_cartridge - name = "dart cartridge" - desc = "A rack of hollow darts." - icon = 'icons/obj/ammo.dmi' - icon_state = "darts-5" - item_state = "rcdammo" - opacity = 0 - density = 0 - anchored = 0.0 - origin_tech = "materials=2" - var/darts = 5 - -/obj/item/weapon/dart_cartridge/update_icon() - if(!darts) - icon_state = "darts-0" - else if(darts > 5) - icon_state = "darts-5" - else - icon_state = "darts-[darts]" - return 1 - -/obj/item/weapon/gun/dartgun - name = "dart gun" - desc = "A small gas-powered dartgun, capable of delivering chemical cocktails swiftly across short distances." - icon_state = "dartgun-empty" - - var/list/beakers = list() //All containers inside the gun. - var/list/mixing = list() //Containers being used for mixing. - var/obj/item/weapon/dart_cartridge/cartridge = null //Container of darts. - var/max_beakers = 3 - var/dart_reagent_amount = 15 - var/container_type = /obj/item/weapon/reagent_containers/glass/beaker - var/list/starting_chems = null - -/obj/item/weapon/gun/dartgun/update_icon() - - if(!cartridge) - icon_state = "dartgun-empty" - return 1 - - if(!cartridge.darts) - icon_state = "dartgun-0" - else if(cartridge.darts > 5) - icon_state = "dartgun-5" - else - icon_state = "dartgun-[cartridge.darts]" - return 1 - -/obj/item/weapon/gun/dartgun/New() - - ..() - if(starting_chems) - for(var/chem in starting_chems) - var/obj/B = new container_type(src) - B.reagents.add_reagent(chem, 50) - beakers += B - cartridge = new /obj/item/weapon/dart_cartridge(src) - update_icon() - -/obj/item/weapon/gun/dartgun/examine(mob/user) - update_icon() - if (!..(user, 2)) - return - if (beakers.len) - user << "\blue [src] contains:" - for(var/obj/item/weapon/reagent_containers/glass/beaker/B in beakers) - if(B.reagents && B.reagents.reagent_list.len) - for(var/datum/reagent/R in B.reagents.reagent_list) - user << "\blue [R.volume] units of [R.name]" - -/obj/item/weapon/gun/dartgun/attackby(obj/item/I as obj, mob/user as mob) - if(istype(I, /obj/item/weapon/dart_cartridge)) - - var/obj/item/weapon/dart_cartridge/D = I - - if(!D.darts) - user << "\blue [D] is empty." - return 0 - - if(cartridge) - if(cartridge.darts <= 0) - src.remove_cartridge() - else - user << "\blue There's already a cartridge in [src]." - return 0 - - user.drop_item() - cartridge = D - D.loc = src - user << "\blue You slot [D] into [src]." - update_icon() - return - if(istype(I, /obj/item/weapon/reagent_containers/glass)) - if(!istype(I, container_type)) - user << "\blue [I] doesn't seem to fit into [src]." - return - if(beakers.len >= max_beakers) - user << "\blue [src] already has [max_beakers] beakers in it - another one isn't going to fit!" - return - var/obj/item/weapon/reagent_containers/glass/beaker/B = I - user.drop_item() - B.loc = src - beakers += B - user << "\blue You slot [B] into [src]." - src.updateUsrDialog() - -/obj/item/weapon/gun/dartgun/can_fire() - if(!cartridge) - return 0 - else - return cartridge.darts - -/obj/item/weapon/gun/dartgun/proc/has_selected_beaker_reagents() - return 0 - -/obj/item/weapon/gun/dartgun/proc/remove_cartridge() - if(cartridge) - usr << "\blue You pop the cartridge out of [src]." - var/obj/item/weapon/dart_cartridge/C = cartridge - C.loc = get_turf(src) - C.update_icon() - cartridge = null - src.update_icon() - -/obj/item/weapon/gun/dartgun/proc/get_mixed_syringe() - if (!cartridge) - return 0 - if(!cartridge.darts) - return 0 - - var/obj/item/weapon/reagent_containers/syringe/dart = new(src) - - if(mixing.len) - var/mix_amount = dart_reagent_amount/mixing.len - for(var/obj/item/weapon/reagent_containers/glass/beaker/B in mixing) - B.reagents.trans_to(dart,mix_amount) - - return dart - -/obj/item/weapon/gun/dartgun/proc/fire_dart(atom/target, mob/user) - if (locate (/obj/structure/table, src.loc)) - return - else - var/turf/trg = get_turf(target) - var/obj/effect/syringe_gun_dummy/D = new/obj/effect/syringe_gun_dummy(get_turf(src)) - var/obj/item/weapon/reagent_containers/syringe/S = get_mixed_syringe() - if(!S) - user << "\red There are no darts in [src]!" - return - if(!S.reagents) - user << "\red There are no reagents available!" - return - cartridge.darts-- - src.update_icon() - S.reagents.trans_to(D, S.reagents.total_volume) - del(S) - D.icon_state = "syringeproj" - D.name = "syringe" - D.flags |= NOREACT - playsound(user.loc, 'sound/items/syringeproj.ogg', 50, 1) - - for(var/i=0, i<6, i++) - if(!D) break - if(D.loc == trg) break - step_towards(D,trg) - - if(D) - for(var/mob/living/carbon/M in D.loc) - if(!istype(M,/mob/living/carbon)) continue - if(M == user) continue - //Syringe gun attack logging by Yvarov - var/R - if(D.reagents) - for(var/datum/reagent/A in D.reagents.reagent_list) - R += A.id + " (" - R += num2text(A.volume) + ")," - if (istype(M, /mob)) - M.attack_log += "\[[time_stamp()]\] [user]/[user.ckey] shot [M]/[M.ckey] with a dartgun ([R])" - user.attack_log += "\[[time_stamp()]\] [user]/[user.ckey] shot [M]/[M.ckey] with a dartgun ([R])" - msg_admin_attack("[user] ([user.ckey]) shot [M] ([M.ckey]) with a dartgun ([R]) (JMP)") - - else - M.attack_log += "\[[time_stamp()]\] UNKNOWN SUBJECT (No longer exists) shot [M]/[M.ckey] with a dartgun ([R])" - msg_admin_attack("UNKNOWN shot [M] ([M.ckey]) with a dartgun ([R]) (JMP)") - - if(D.reagents) - D.reagents.trans_to(M, 15) - M << "You feel a slight prick." - - del(D) - break - if(D) - for(var/atom/A in D.loc) - if(A == user) continue - if(A.density) del(D) - - sleep(1) - - if (D) spawn(10) del(D) - - return - -/obj/item/weapon/gun/dartgun/afterattack(obj/target, mob/user , flag) - if(!isturf(target.loc) || target == user) return - ..() - -/obj/item/weapon/gun/dartgun/can_hit(var/mob/living/target as mob, var/mob/living/user as mob) - return 1 - -/obj/item/weapon/gun/dartgun/attack_self(mob/user) - - user.set_machine(src) - var/dat = "[src] mixing control:

    " - - if (beakers.len) - var/i = 1 - for(var/obj/item/weapon/reagent_containers/glass/beaker/B in beakers) - dat += "Beaker [i] contains: " - if(B.reagents && B.reagents.reagent_list.len) - for(var/datum/reagent/R in B.reagents.reagent_list) - dat += "
    [R.volume] units of [R.name], " - if (check_beaker_mixing(B)) - dat += text("Mixing ") - else - dat += text("Not mixing ") - else - dat += "nothing." - dat += " \[Eject\]
    " - i++ - else - dat += "There are no beakers inserted!

    " - - if(cartridge) - if(cartridge.darts) - dat += "The dart cartridge has [cartridge.darts] shots remaining." - else - dat += "The dart cartridge is empty!" - dat += " \[Eject\]" - - user << browse(dat, "window=dartgun") - onclose(user, "dartgun", src) - -/obj/item/weapon/gun/dartgun/proc/check_beaker_mixing(var/obj/item/B) - if(!mixing || !beakers) - return 0 - for(var/obj/item/M in mixing) - if(M == B) - return 1 - return 0 - -/obj/item/weapon/gun/dartgun/Topic(href, href_list) - src.add_fingerprint(usr) - if(href_list["stop_mix"]) - var/index = text2num(href_list["stop_mix"]) - if(index <= beakers.len) - for(var/obj/item/M in mixing) - if(M == beakers[index]) - mixing -= M - break - else if (href_list["mix"]) - var/index = text2num(href_list["mix"]) - if(index <= beakers.len) - mixing += beakers[index] - else if (href_list["eject"]) - var/index = text2num(href_list["eject"]) - if(index <= beakers.len) - if(beakers[index]) - var/obj/item/weapon/reagent_containers/glass/beaker/B = beakers[index] - usr << "You remove [B] from [src]." - mixing -= B - beakers -= B - B.loc = get_turf(src) - else if (href_list["eject_cart"]) - remove_cartridge() - src.updateUsrDialog() - return - -/obj/item/weapon/gun/dartgun/Fire(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, params, reflex = 0) - if(cartridge) - spawn(0) fire_dart(target,user) - else - usr << "\red [src] is empty." - - -/obj/item/weapon/gun/dartgun/vox - name = "alien dart gun" - desc = "A small gas-powered dartgun, fitted for nonhuman hands." - -/obj/item/weapon/gun/dartgun/vox/medical - starting_chems = list("kelotane","bicaridine","anti_toxin") - -/obj/item/weapon/gun/dartgun/vox/raider - starting_chems = list("space_drugs","stoxin","impedrezene") \ No newline at end of file diff --git a/code/modules/reagents/grenade_launcher.dm b/code/modules/reagents/grenade_launcher.dm deleted file mode 100644 index b96455a178..0000000000 --- a/code/modules/reagents/grenade_launcher.dm +++ /dev/null @@ -1,63 +0,0 @@ - - -/obj/item/weapon/gun/grenadelauncher - name = "grenade launcher" - icon = 'icons/obj/gun.dmi' - icon_state = "riotgun" - item_state = "riotgun" - w_class = 4.0 - throw_speed = 2 - throw_range = 10 - force = 5.0 - var/list/grenades = new/list() - var/max_grenades = 3 - matter = list("metal" = 2000) - - examine(mob/user) - if(..(user, 2)) - user << "\blue [grenades] / [max_grenades] Grenades." - - attackby(obj/item/I as obj, mob/user as mob) - - if((istype(I, /obj/item/weapon/grenade))) - if(grenades.len < max_grenades) - user.drop_item() - I.loc = src - grenades += I - user << "\blue You put the grenade in the grenade launcher." - user << "\blue [grenades.len] / [max_grenades] Grenades." - else - usr << "\red The grenade launcher cannot hold more grenades." - - afterattack(obj/target, mob/user , flag) - - if (istype(target, /obj/item/weapon/storage/backpack )) - return - - else if (locate (/obj/structure/table, src.loc)) - return - - else if(target == user) - return - - if(grenades.len) - spawn(0) fire_grenade(target,user) - else - usr << "\red The grenade launcher is empty." - - proc - fire_grenade(atom/target, mob/user) - for(var/mob/O in viewers(world.view, user)) - O.show_message(text("\red [] fired a grenade!", user), 1) - user << "\red You fire the grenade launcher!" - var/obj/item/weapon/grenade/chem_grenade/F = grenades[1] //Now with less copypasta! - grenades -= F - F.loc = user.loc - F.throw_at(target, 30, 2, user) - message_admins("[key_name_admin(user)] fired a grenade ([F.name]) from a grenade launcher ([src.name]).") - log_game("[key_name_admin(user)] used a grenade ([src.name]).") - F.active = 1 - F.icon_state = initial(icon_state) + "_active" - playsound(user.loc, 'sound/weapons/armbomb.ogg', 75, 1, -3) - spawn(15) - F.prime() \ No newline at end of file diff --git a/code/modules/reagents/reagent_containers/syringes.dm b/code/modules/reagents/reagent_containers/syringes.dm index c1d9b0fdec..8aa34a7dca 100644 --- a/code/modules/reagents/reagent_containers/syringes.dm +++ b/code/modules/reagents/reagent_containers/syringes.dm @@ -18,6 +18,7 @@ w_class = 1 sharp = 1 var/mode = SYRINGE_DRAW + var/image/filling //holds a reference to the current filling overlay on_reagent_change() update_icon() @@ -217,7 +218,7 @@ item_state = "syringe_[rounded_vol]" if(reagents.total_volume) - var/image/filling = image('icons/obj/reagentfillings.dmi', src, "syringe10") + filling = image('icons/obj/reagentfillings.dmi', src, "syringe10") filling.icon_state = "syringe[rounded_vol]" @@ -225,7 +226,7 @@ overlays += filling - /obj/item/weapon/reagent_containers/syringe/proc/syringestab(mob/living/carbon/target as mob, mob/living/carbon/user as mob) + proc/syringestab(mob/living/carbon/target as mob, mob/living/carbon/user as mob) user.attack_log += "\[[time_stamp()]\] Attacked [target.name] ([target.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)])" target.attack_log += "\[[time_stamp()]\] Attacked by [user.name] ([user.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)])" @@ -268,13 +269,19 @@ src.reagents.reaction(target, INGEST) var/syringestab_amount_transferred = rand(0, (reagents.total_volume - 5)) //nerfed by popular demand src.reagents.trans_to(target, syringestab_amount_transferred) + src.break_syringe(target, user) + + proc/break_syringe(mob/living/carbon/target, mob/living/carbon/user) src.desc += " It is broken." src.mode = SYRINGE_BROKEN - src.add_blood(target) - src.add_fingerprint(usr) + if(target) + src.add_blood(target) + if(user) + src.add_fingerprint(user) src.update_icon() + /obj/item/weapon/reagent_containers/ld50_syringe name = "Lethal Injection Syringe" desc = "A syringe used for lethal injections." diff --git a/code/modules/reagents/syringe_gun.dm b/code/modules/reagents/syringe_gun.dm deleted file mode 100644 index faecb79868..0000000000 --- a/code/modules/reagents/syringe_gun.dm +++ /dev/null @@ -1,137 +0,0 @@ - - - -/obj/item/weapon/gun/syringe - name = "syringe gun" - desc = "A spring loaded rifle designed to fit syringes, designed to incapacitate unruly patients from a distance." - icon = 'icons/obj/gun.dmi' - icon_state = "syringegun" - item_state = "syringegun" - w_class = 3.0 - throw_speed = 2 - throw_range = 10 - force = 4.0 - var/list/syringes = new/list() - var/max_syringes = 1 - matter = list("metal" = 2000) - -/obj/item/weapon/gun/syringe/examine(mob/user) - if(..(user, 2)) - user << "\blue [syringes.len] / [max_syringes] syringes." - -/obj/item/weapon/gun/syringe/attackby(obj/item/I as obj, mob/user as mob) - if(istype(I, /obj/item/weapon/reagent_containers/syringe)) - var/obj/item/weapon/reagent_containers/syringe/S = I - if(S.mode != 2)//SYRINGE_BROKEN in syringes.dm - if(syringes.len < max_syringes) - user.drop_item() - I.loc = src - syringes += I - user << "\blue You put the syringe in [src]." - user << "\blue [syringes.len] / [max_syringes] syringes." - else - usr << "\red [src] cannot hold more syringes." - else - usr << "\red This syringe is broken!" - - -/obj/item/weapon/gun/syringe/afterattack(obj/target, mob/user , flag) - if(!isturf(target.loc) || target == user) return - ..() - -/obj/item/weapon/gun/syringe/can_fire() - return syringes.len - -/obj/item/weapon/gun/syringe/can_hit(var/mob/living/target as mob, var/mob/living/user as mob) - return 1 //SHOOT AND LET THE GOD GUIDE IT (probably will hit a wall anyway) - -/obj/item/weapon/gun/syringe/Fire(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, params, reflex = 0) - if(syringes.len) - spawn(0) fire_syringe(target,user) - else - usr << "\red [src] is empty." - -/obj/item/weapon/gun/syringe/proc/fire_syringe(atom/target, mob/user) - if (locate (/obj/structure/table, src.loc)) - return - else - var/turf/trg = get_turf(target) - var/obj/effect/syringe_gun_dummy/D = new/obj/effect/syringe_gun_dummy(get_turf(src)) - var/obj/item/weapon/reagent_containers/syringe/S = syringes[1] - if((!S) || (!S.reagents)) //ho boy! wot runtimes! - return - S.reagents.trans_to(D, S.reagents.total_volume) - syringes -= S - del(S) - D.icon_state = "syringeproj" - D.name = "syringe" - playsound(user.loc, 'sound/items/syringeproj.ogg', 50, 1) - - for(var/i=0, i<6, i++) - if(!D) break - if(D.loc == trg) break - step_towards(D,trg) - - if(D) - for(var/mob/living/carbon/M in D.loc) - if(!istype(M,/mob/living/carbon)) continue - if(M == user) continue - //Syringe gun attack logging by Yvarov - var/R - if(D.reagents) - for(var/datum/reagent/A in D.reagents.reagent_list) - R += A.id + " (" - R += num2text(A.volume) + ")," - if (istype(M, /mob)) - M.attack_log += "\[[time_stamp()]\] [user]/[user.ckey] shot [M]/[M.ckey] with a syringegun ([R])" - user.attack_log += "\[[time_stamp()]\] [user]/[user.ckey] shot [M]/[M.ckey] with a syringegun ([R])" - msg_admin_attack("[user] ([user.ckey]) shot [M] ([M.ckey]) with a syringegun ([R]) (JMP)") - - else - M.attack_log += "\[[time_stamp()]\] UNKNOWN SUBJECT (No longer exists) shot [M]/[M.ckey] with a syringegun ([R])" - msg_admin_attack("UNKNOWN shot [M] ([M.ckey]) with a syringegun ([R]) (JMP)") - - var/mob/living/T - if(istype(M,/mob/living)) - T = M - - M.visible_message("[M] is hit by the syringe!") - - if(T && istype(T) && T.can_inject()) - if(D.reagents) - D.reagents.trans_to(M, 15) - else - M.visible_message("The syringe bounces off [M]!") - - del(D) - break - if(D) - for(var/atom/A in D.loc) - if(A == user) continue - if(A.density) del(D) - - sleep(1) - - if (D) spawn(10) del(D) - - return - -/obj/item/weapon/gun/syringe/rapidsyringe - name = "rapid syringe gun" - desc = "A modification of the syringe gun design, using a rotating cylinder to store up to four syringes." - icon_state = "rapidsyringegun" - max_syringes = 4 - - -/obj/effect/syringe_gun_dummy - name = "" - desc = "" - icon = 'icons/obj/chemical.dmi' - icon_state = "null" - anchored = 1 - density = 0 - - New() - var/datum/reagents/R = new/datum/reagents(15) - reagents = R - R.my_atom = src \ No newline at end of file diff --git a/code/modules/research/designs.dm b/code/modules/research/designs.dm index e04618cf20..9083a47e1c 100644 --- a/code/modules/research/designs.dm +++ b/code/modules/research/designs.dm @@ -451,7 +451,7 @@ datum/design/circuit/tcom/server name = "server mainframe" id = "tcom-server" build_path = /obj/item/weapon/circuitboard/telecomms/server - + datum/design/circuit/tcom/processor name = "processor unit" id = "tcom-processor" @@ -1312,7 +1312,7 @@ datum/design/item/weapon/rapidsyringe id = "rapidsyringe" req_tech = list("combat" = 3, "materials" = 3, "engineering" = 3, "biotech" = 2) materials = list("$metal" = 5000, "$glass" = 1000) - build_path = /obj/item/weapon/gun/syringe/rapidsyringe + build_path = /obj/item/weapon/gun/launcher/syringe/rapid /* datum/design/item/weapon/largecrossbow name = "Energy Crossbow" @@ -1567,7 +1567,7 @@ datum/design/item/mesons req_tech = list("magnets" = 2, "engineering" = 2) materials = list("$metal" = 50, "$glass" = 50) build_path = /obj/item/clothing/glasses/meson - + datum/design/item/binaryencrypt name = "Binary encryption key" desc = "Allows for deciphering the binary channel on-the-fly." diff --git a/code/modules/research/xenoarchaeology/finds/finds.dm b/code/modules/research/xenoarchaeology/finds/finds.dm index 3c2a3dd8e2..b758192bee 100644 --- a/code/modules/research/xenoarchaeology/finds/finds.dm +++ b/code/modules/research/xenoarchaeology/finds/finds.dm @@ -367,7 +367,7 @@ item_type = "gun" if(27) //revolver - var/obj/item/weapon/gun/projectile/new_gun = new /obj/item/weapon/gun/projectile(src.loc) + var/obj/item/weapon/gun/projectile/new_gun = new /obj/item/weapon/gun/projectile/revolver(src.loc) new_item = new_gun new_item.icon_state = "gun[rand(1,4)]" new_item.icon = 'icons/obj/xenoarchaeology.dmi' @@ -383,7 +383,7 @@ if(num_bullets < new_gun.loaded.len) new_gun.loaded.Cut() for(var/i = 1, i <= num_bullets, i++) - var/A = text2path(new_gun.ammo_type) + var/A = new_gun.ammo_type new_gun.loaded += new A(new_gun) else for(var/obj/item/I in new_gun) diff --git a/code/modules/supermatter/supermatter.dm b/code/modules/supermatter/supermatter.dm index de8f5233e6..6cdf0c3e91 100644 --- a/code/modules/supermatter/supermatter.dm +++ b/code/modules/supermatter/supermatter.dm @@ -1,8 +1,8 @@ #define NITROGEN_RETARDATION_FACTOR 0.15 //Higher == N2 slows reaction more -#define THERMAL_RELEASE_MODIFIER 750 //Higher == more heat released during reaction +#define THERMAL_RELEASE_MODIFIER 10000 //Higher == more heat released during reaction #define PHORON_RELEASE_MODIFIER 1500 //Higher == less phoron released by reaction -#define OXYGEN_RELEASE_MODIFIER 1500 //Higher == less oxygen released at high temperature/power +#define OXYGEN_RELEASE_MODIFIER 15000 //Higher == less oxygen released at high temperature/power #define REACTION_POWER_MODIFIER 1.1 //Higher == more overall power /* @@ -18,7 +18,7 @@ //Controls how much power is produced by each collector in range - this is the main parameter for tweaking SM balance, as it basically controls how the power variable relates to the rest of the game. #define POWER_FACTOR 1.0 #define DECAY_FACTOR 700 //Affects how fast the supermatter power decays -#define CRITICAL_TEMPERATURE 800 //K +#define CRITICAL_TEMPERATURE 5000 //K #define CHARGING_FACTOR 0.05 #define DAMAGE_RATE_LIMIT 3 //damage rate cap at power = 300, scales linearly with power @@ -209,7 +209,7 @@ power = max( (removed.temperature * temp_factor) * oxygen + power, 0) //We've generated power, now let's transfer it to the collectors for storing/usage - transfer_energy() + //transfer_energy() var/device_energy = power * REACTION_POWER_MODIFIER @@ -273,6 +273,7 @@ Consume(user) +/* /obj/machinery/power/supermatter/proc/transfer_energy() for(var/obj/machinery/power/rad_collector/R in rad_collectors) var/distance = get_dist(R, src) @@ -280,6 +281,7 @@ //for collectors using standard phoron tanks at 1013 kPa, the actual power generated will be this power*POWER_FACTOR*20*29 = power*POWER_FACTOR*580 R.receive_pulse(power * POWER_FACTOR * (min(3/distance, 1))**2) return +*/ /obj/machinery/power/supermatter/attackby(obj/item/weapon/W as obj, mob/living/user as mob) user.visible_message("\The [user] touches \a [W] to \the [src] as a silence fills the room...",\ diff --git a/code/setup.dm b/code/setup.dm index 5a1a6b4b21..11dd0644a2 100644 --- a/code/setup.dm +++ b/code/setup.dm @@ -83,7 +83,7 @@ #define FIRE_MAX_FIRESUIT_STACKS 20 // If the number of stacks goes above this firesuits won't protect you anymore. If not, you can walk around while on fire like a badass. #define THROWFORCE_SPEED_DIVISOR 5 // The throwing speed value at which the throwforce multiplier is exactly 1. -#define THROWNOBJ_KNOCKBACK_SPEED 15 // The minumum speed of a thrown object that will cause living mobs it hits to be knocked back. +#define THROWNOBJ_KNOCKBACK_SPEED 15 // The minumum speed of a w_class 2 thrown object that will cause living mobs it hits to be knocked back. Heavier objects can cause knockback at lower speeds. #define THROWNOBJ_KNOCKBACK_DIVISOR 2 // Affects how much speed the mob is knocked back with. #define PRESSURE_DAMAGE_COEFFICIENT 4 // The amount of pressure damage someone takes is equal to (pressure / HAZARD_HIGH_PRESSURE)*PRESSURE_DAMAGE_COEFFICIENT, with the maximum of MAX_PRESSURE_DAMAGE. @@ -166,6 +166,7 @@ #define SLOT_DENYPOCKET 4096 // This is to deny items with a w_class of 2 or 1 from fitting in pockets. #define SLOT_TWOEARS 8192 #define SLOT_TIE 16384 +#define SLOT_HOLSTER 32768 //16th bit // Flags bitmasks. #define STOPPRESSUREDAMAGE 1 // This flag is used on the flags variable for SUIT and HEAD items which stop pressure damage. Note that the flag 1 was previous used as ONBACK, so it is possible for some code to use (flags & 1) when checking if something can be put on your back. Replace this code with (inv_flags & SLOT_BACK) if you see it anywhere diff --git a/html/changelog.html b/html/changelog.html index 3092f99714..1dff6048af 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -56,6 +56,15 @@ should be listed in the changelog upon commit though. Thanks. --> +
    +

    16 February 2015

    +

    RavingManiac updated:

    +
      +
    • Say hello to the new Thermoelectric Supermatter Engine. Read the operating manual to get started.
    • +
    +
    + +

    12 February 2015

    Daranz updated:

    diff --git a/icons/mob/back.dmi b/icons/mob/back.dmi index f160af9933..893b58c663 100644 Binary files a/icons/mob/back.dmi and b/icons/mob/back.dmi differ diff --git a/icons/obj/ammo.dmi b/icons/obj/ammo.dmi index b6780ecec3..05f0fbaecf 100644 Binary files a/icons/obj/ammo.dmi and b/icons/obj/ammo.dmi differ diff --git a/icons/obj/gun.dmi b/icons/obj/gun.dmi index 1e03bbe0b7..dd77da454b 100644 Binary files a/icons/obj/gun.dmi and b/icons/obj/gun.dmi differ diff --git a/icons/obj/projectiles.dmi b/icons/obj/projectiles.dmi index 03915794e4..7f3468a363 100644 Binary files a/icons/obj/projectiles.dmi and b/icons/obj/projectiles.dmi differ diff --git a/icons/obj/syringe.dmi b/icons/obj/syringe.dmi index 2adc34b05b..a9a46f6046 100644 Binary files a/icons/obj/syringe.dmi and b/icons/obj/syringe.dmi differ diff --git a/interface/skin.dmf b/interface/skin.dmf index 8eee4e1817..a8ae16d887 100644 --- a/interface/skin.dmf +++ b/interface/skin.dmf @@ -341,6 +341,14 @@ macro "hotkeymode" name = "CTRL+H" command = "holster" is-disabled = false + elem + name = "J" + command = "toggle-gun-mode" + is-disabled = false + elem + name = "CTRL+J" + command = "toggle-gun-mode" + is-disabled = false elem name = "Q" command = ".northwest" diff --git a/maps/exodus-1.dmm b/maps/exodus-1.dmm index 412025adf7..6412a42013 100644 --- a/maps/exodus-1.dmm +++ b/maps/exodus-1.dmm @@ -3592,7 +3592,7 @@ "brd" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/assembly/robotics) "bre" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/assembly/robotics) "brf" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/turf/simulated/floor{icon_state = "white"},/area/assembly/robotics) -"brg" = (/obj/machinery/firealarm{dir = 4; pixel_x = 24},/obj/structure/table/rack{dir = 8; layer = 2.9},/obj/item/weapon/storage/toolbox/electrical{pixel_x = 1; pixel_y = 6},/obj/item/clothing/head/welding{pixel_x = -3; pixel_y = 5},/obj/item/clothing/head/welding{pixel_x = -3; pixel_y = 5},/obj/item/weapon/storage/toolbox/mechanical,/obj/item/weapon/storage/toolbox/mechanical{pixel_x = -2; pixel_y = -1},/turf/simulated/floor{icon_state = "white"},/area/assembly/robotics) +"brg" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/obj/effect/landmark{name = "JoinLateCyborg"},/turf/simulated/floor,/area/assembly/chargebay) "brh" = (/turf/simulated/wall/r_wall,/area/assembly/robotics) "bri" = (/obj/structure/closet/emcloset,/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/turf/simulated/floor{dir = 9; icon_state = "warnwhite"},/area/rnd/research) "brj" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/turf/simulated/floor{icon_state = "white"},/area/rnd/research) @@ -3866,7 +3866,7 @@ "bwr" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk{dir = 8},/turf/simulated/floor,/area/assembly/robotics) "bws" = (/turf/simulated/floor,/area/assembly/robotics) "bwt" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "white"},/area/assembly/robotics) -"bwu" = (/obj/structure/table,/obj/item/device/assembly/prox_sensor{pixel_x = -8; pixel_y = 4},/obj/item/device/assembly/prox_sensor{pixel_x = -8; pixel_y = 4},/obj/item/device/assembly/prox_sensor{pixel_x = -8; pixel_y = 4},/obj/item/device/assembly/prox_sensor{pixel_x = -8; pixel_y = 4},/obj/item/weapon/cell/high{charge = 100; maxcharge = 15000},/obj/item/weapon/cell/high{charge = 100; maxcharge = 15000; pixel_x = 5; pixel_y = -5},/obj/machinery/light{dir = 4; icon_state = "tube1"},/obj/item/weapon/storage/toolbox/mechanical,/turf/simulated/floor{icon_state = "white"},/area/assembly/robotics) +"bwu" = (/obj/machinery/cryopod/robot/right,/turf/simulated/floor,/area/assembly/chargebay) "bwv" = (/obj/machinery/status_display,/turf/simulated/wall/r_wall,/area/assembly/robotics) "bww" = (/turf/simulated/wall/r_wall,/area/rnd/research) "bwx" = (/obj/machinery/door/airlock/research{name = "Research Division Access"; req_access_txt = "47"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "white"},/area/rnd/research) @@ -4102,8 +4102,8 @@ "bAT" = (/obj/machinery/hologram/holopad,/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{dir = 2; icon_state = "whitered_c"; tag = "icon-whitered_c (WEST)"},/area/medical/patient_wing) "bAU" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "white"},/area/medical/patient_wing) "bAV" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/obj/machinery/camera{c_tag = "Medbay Patient Hallway - Starboard"; dir = 1; network = list("SS13")},/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor{icon_state = "white"},/area/medical/patient_wing) -"bAW" = (/obj/machinery/cryopod/robot/right,/turf/simulated/floor,/area/assembly/chargebay) -"bAX" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/obj/effect/landmark{name = "JoinLateCyborg"},/turf/simulated/floor,/area/assembly/chargebay) +"bAW" = (/obj/structure/table,/obj/item/device/assembly/prox_sensor{pixel_x = -8; pixel_y = 4},/obj/item/device/assembly/prox_sensor{pixel_x = -8; pixel_y = 4},/obj/item/device/assembly/prox_sensor{pixel_x = -8; pixel_y = 4},/obj/item/device/assembly/prox_sensor{pixel_x = -8; pixel_y = 4},/obj/item/weapon/cell/high{charge = 100; maxcharge = 15000},/obj/item/weapon/cell/high{charge = 100; maxcharge = 15000; pixel_x = 5; pixel_y = -5},/obj/machinery/light{dir = 4; icon_state = "tube1"},/obj/item/weapon/storage/toolbox/mechanical,/turf/simulated/floor{icon_state = "white"},/area/assembly/robotics) +"bAX" = (/obj/machinery/firealarm{dir = 4; pixel_x = 24},/obj/structure/table/rack{dir = 8; layer = 2.9},/obj/item/weapon/storage/toolbox/electrical{pixel_x = 1; pixel_y = 6},/obj/item/clothing/head/welding{pixel_x = -3; pixel_y = 5},/obj/item/clothing/head/welding{pixel_x = -3; pixel_y = 5},/obj/item/weapon/storage/toolbox/mechanical,/obj/item/weapon/storage/toolbox/mechanical{pixel_x = -2; pixel_y = -1},/turf/simulated/floor{icon_state = "white"},/area/assembly/robotics) "bAY" = (/obj/structure/reagent_dispensers/fueltank,/turf/simulated/floor,/area/assembly/chargebay) "bAZ" = (/obj/machinery/recharge_station,/turf/simulated/floor{icon_state = "bot"},/area/assembly/chargebay) "bBa" = (/obj/structure/table,/obj/item/weapon/storage/box/bodybags{pixel_x = -1; pixel_y = -2},/obj/item/weapon/pen,/turf/simulated/floor{icon_state = "whitehall"; dir = 4},/area/assembly/robotics) @@ -5586,7 +5586,7 @@ "cdv" = (/turf/simulated/floor{icon_state = "bcarpet02"},/area/medical/psych) "cdw" = (/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/turf/simulated/floor{icon_state = "bcarpet03"},/area/medical/psych) "cdx" = (/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/obj/machinery/light/small{dir = 8},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "dark"},/area/medical/biostorage) -"cdy" = (/obj/structure/table,/obj/item/weapon/storage/box/cdeathalarm_kit,/turf/simulated/floor{icon_state = "dark"},/area/medical/biostorage) +"cdy" = (/obj/structure/table,/obj/item/weapon/storage/box/cdeathalarm_kit,/obj/item/bodybag/cryobag{pixel_x = -3},/obj/item/bodybag/cryobag{pixel_x = -3},/turf/simulated/floor{icon_state = "dark"},/area/medical/biostorage) "cdz" = (/obj/machinery/firealarm{dir = 1; pixel_y = -24},/obj/structure/closet/secure_closet/personal/patient,/turf/simulated/floor{dir = 10; icon_state = "whitered"},/area/medical/patient_c) "cdA" = (/obj/machinery/light,/obj/machinery/newscaster{pixel_y = -28},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/obj/machinery/hologram/holopad,/turf/simulated/floor{dir = 3; icon_state = "whitered"},/area/medical/patient_c) "cdB" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1},/turf/simulated/floor/carpet,/area/engineering/break_room) @@ -5795,7 +5795,7 @@ "chw" = (/obj/structure/sign/biohazard,/turf/simulated/wall,/area/medical/virologyaccess) "chx" = (/obj/structure/disposaloutlet,/obj/structure/disposalpipe/trunk{dir = 1},/turf/simulated/floor/plating/airless,/area/medical/virology) "chy" = (/obj/structure/bedsheetbin,/obj/structure/table,/obj/machinery/power/apc{dir = 8; name = "west bump"; pixel_x = -24},/obj/structure/cable/green,/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/turf/simulated/floor{icon_state = "dark"},/area/medical/biostorage) -"chz" = (/obj/structure/table,/obj/item/bodybag/cryobag{pixel_x = -3},/obj/item/bodybag/cryobag{pixel_x = -3},/obj/item/weapon/gun/syringe,/turf/simulated/floor{icon_state = "dark"},/area/medical/biostorage) +"chz" = (/obj/structure/table,/obj/item/weapon/gun/launcher/syringe,/obj/item/weapon/storage/box/syringegun,/turf/simulated/floor{icon_state = "dark"},/area/medical/biostorage) "chA" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating,/area/maintenance/research_port) "chB" = (/turf/simulated/floor/plating,/area/maintenance/research_port) "chC" = (/obj/machinery/door/airlock/medical{autoclose = 0; icon_state = "door_open"; id_tag = "cubicle1"; name = "Cubicle 1"},/turf/simulated/floor{icon_state = "freezerfloor"},/area/medical/patient_wing) @@ -6820,7 +6820,7 @@ "cBh" = (/turf/simulated/floor{dir = 3; icon_state = "whitered"},/area/medical/virology) "cBi" = (/obj/machinery/light,/obj/machinery/atmospherics/pipe/simple/hidden/purple,/turf/simulated/floor{dir = 3; icon_state = "whitered"},/area/medical/virology) "cBj" = (/obj/structure/stool/bed,/obj/item/weapon/bedsheet,/obj/item/device/radio/intercom{freerange = 1; frequency = 1459; name = "Station Intercom (General)"; pixel_x = 30},/turf/simulated/floor{dir = 3; icon_state = "whitered"},/area/medical/virology) -"cBk" = (/obj/structure/disposalpipe/segment,/turf/simulated/floor/plating/airless,/area/space) +"cBk" = (/obj/machinery/light,/obj/structure/extinguisher_cabinet{pixel_x = 5; pixel_y = -32},/obj/machinery/portable_atmospherics/hydroponics,/turf/simulated/floor{dir = 8; icon_state = "whitegreen"},/area/rnd/xenobiology/xenoflora) "cBl" = (/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor{icon_state = "hydrofloor"},/area/rnd/xenobiology) "cBm" = (/obj/machinery/door/window/southright{dir = 1; name = "Containment Pen"; req_access_txt = "47"},/turf/simulated/floor{dir = 1; icon_state = "warning"},/area/rnd/xenobiology) "cBn" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/table/reinforced,/obj/machinery/door_control{id = "xenobio4"; name = "Containment Blast Doors"; pixel_x = 0; pixel_y = 4; req_access_txt = "55"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{dir = 1; icon_state = "warning"},/area/rnd/xenobiology) @@ -6910,7 +6910,7 @@ "cCT" = (/obj/machinery/atmospherics/pipe/tank/air{dir = 8},/turf/simulated/floor/plating,/area/maintenance/engineering) "cCU" = (/obj/machinery/alarm{frequency = 1439; pixel_y = 23},/obj/machinery/power/apc{dir = 8; name = "west bump"; pixel_x = -24},/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor,/area/engineering/engine_airlock) "cCV" = (/obj/structure/closet/radiation,/obj/item/clothing/glasses/meson,/obj/item/clothing/glasses/meson,/obj/machinery/camera{c_tag = "Engine Room Airlock"; dir = 2; network = list("SS13","Supermatter")},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor,/area/engineering/engine_airlock) -"cCW" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/visible,/turf/simulated/floor/plating/airless,/area/space) +"cCW" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plating/airless,/area/space) "cCX" = (/turf/simulated/floor/plating/airless,/area/maintenance/medbay) "cCY" = (/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1379; master_tag = "virology_airlock"; name = "exterior access button"; pixel_x = 20; pixel_y = 20; req_access_txt = "13"},/turf/simulated/floor/plating/airless,/area/maintenance/medbay) "cCZ" = (/obj/structure/stool/bed,/obj/item/weapon/bedsheet/green,/turf/simulated/floor{icon_state = "white"},/area/medical/virology) @@ -7009,7 +7009,7 @@ "cEO" = (/obj/machinery/camera{c_tag = "SMES"; dir = 8; network = list("SS13","Supermatter")},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/turf/simulated/floor,/area/engineering/engine_smes) "cEP" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/turf/simulated/floor{icon_state = "warningcorner"; dir = 1},/area/engineering/engine_smes) "cEQ" = (/obj/structure/table/reinforced,/obj/machinery/camera{c_tag = "Engine Monitoring Room"; dir = 4; network = list("SS13","Supermatter")},/obj/machinery/firealarm{dir = 8; pixel_x = -24},/turf/simulated/floor,/area/engineering/engine_monitoring) -"cER" = (/obj/structure/table/reinforced,/obj/machinery/door_control{desc = "A remote control-switch for the engine control room blast doors."; id = "EngineBlast"; name = "Engine Room Blast Doors"; pixel_x = 0; pixel_y = -3; req_access_txt = "10"},/obj/machinery/door_control{desc = "A remote control-switch for the engine charging port."; id = "EngineEmitterPort"; name = "Engine Charging Port"; pixel_x = -6; pixel_y = 7; req_access_txt = "10"},/obj/machinery/door_control{desc = "A remote control-switch for the engine emitter."; id = "EngineEmitter"; name = "Engine Emitter"; normaldoorcontrol = 2; pixel_x = 6; pixel_y = 7; req_access_txt = "10"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/engineering/engine_monitoring) +"cER" = (/obj/machinery/atmospherics/pipe/simple/visible,/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/turf/simulated/floor/plating/airless,/area/space) "cES" = (/obj/structure/stool/bed/chair/office/dark,/obj/effect/landmark/start{name = "Station Engineer"},/turf/simulated/floor,/area/engineering/engine_monitoring) "cET" = (/obj/structure/table/reinforced,/obj/machinery/light_switch{pixel_x = 27},/turf/simulated/floor,/area/engineering/engine_monitoring) "cEU" = (/obj/machinery/embedded_controller/radio/airlock/advanced_airlock_controller{id_tag = "engine_room_airlock"; name = "Engine Room Airlock"; pixel_x = -24; tag_airpump = "engine_airlock_pump"; tag_chamber_sensor = "eng_al_c_snsr"; tag_exterior_door = "engine_airlock_exterior"; tag_exterior_sensor = "eng_al_ext_snsr"; tag_interior_door = "engine_airlock_interior"; tag_interior_sensor = "eng_al_int_snsr"},/obj/machinery/atmospherics/pipe/simple/hidden{dir = 5; icon_state = "intact"; tag = "icon-intact-f (NORTHEAST)"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 9},/area/engineering/engine_airlock) @@ -7028,7 +7028,7 @@ "cFh" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 9; icon_state = "intact"; tag = "icon-intact-f (NORTHWEST)"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 6},/area/maintenance/engi_shuttle) "cFi" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/maintenance/engi_shuttle) "cFj" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/engineering/drone_fabrication) -"cFk" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/visible{tag = "icon-intact (NORTHEAST)"; icon_state = "intact"; dir = 5},/obj/structure/sign/securearea{desc = "A warning sign which reads 'HOT EXHAUST'."; name = "\improper HOT EXHAUST"; pixel_x = -32},/turf/simulated/floor/plating/airless,/area/space) +"cFk" = (/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/turf/simulated/floor/plating/airless,/area/maintenance/medbay) "cFl" = (/obj/machinery/power/smes/buildable{charge = 1e+007; cur_coils = 4; input_attempt = 1; input_level = 500000; output_level = 500000; RCon_tag = "Engine - Main"},/obj/structure/cable,/turf/simulated/floor{icon_state = "vault"; dir = 8},/area/engineering/engine_smes) "cFm" = (/obj/structure/stool/bed,/obj/item/weapon/bedsheet/green,/obj/machinery/light{icon_state = "tube1"; dir = 8},/turf/simulated/floor{icon_state = "white"},/area/medical/virology) "cFn" = (/obj/machinery/alarm{dir = 1; icon_state = "alarm0"; pixel_y = -22},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/turf/simulated/floor{icon_state = "white"},/area/medical/virology) @@ -7071,16 +7071,16 @@ "cFY" = (/obj/machinery/light{tag = "icon-tube1 (NORTH)"; icon_state = "tube1"; dir = 1},/obj/machinery/atmospherics/binary/pump{dir = 8},/turf/simulated/floor/plating,/area/engineering/engine_room) "cFZ" = (/obj/machinery/door_control{desc = "A remote control-switch for the engine control room blast doors."; id = "EngineEmitterPortWest"; name = "Engine Room Blast Doors"; pixel_x = 0; pixel_y = 25; req_access_txt = "10"},/obj/machinery/atmospherics/portables_connector{dir = 4},/turf/simulated/floor/plating{icon_state = "platebot"},/area/engineering/engine_room) "cGa" = (/obj/machinery/power/terminal{dir = 4},/obj/structure/cable/yellow,/obj/machinery/power/sensor{name = "Powernet Sensor - Engine Output"; name_tag = "Engine Output"},/obj/structure/cable/yellow{d2 = 2; icon_state = "0-2"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 1},/area/engineering/engine_room) -"cGb" = (/obj/machinery/alarm{breach_detection = 0; dir = 2; frequency = 1439; name = "Engine Room Air Alarm"; pixel_y = 23},/obj/machinery/atmospherics/pipe/simple/visible/yellow{dir = 10},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 4},/area/engineering/engine_room) +"cGb" = (/obj/machinery/atmospherics/pipe/simple/visible{tag = "icon-intact (NORTHEAST)"; icon_state = "intact"; dir = 5},/obj/structure/sign/securearea{desc = "A warning sign which reads 'HOT EXHAUST'."; name = "\improper HOT EXHAUST"; pixel_x = -32},/turf/simulated/floor/plating/airless,/area/space) "cGc" = (/obj/structure/cable/cyan{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 8},/area/engineering/engine_room) -"cGd" = (/obj/structure/cable/yellow{d2 = 4; icon_state = "0-4"},/obj/machinery/power/smes/buildable{charge = 2e+006; RCon_tag = "Engine - Core"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 1},/area/engineering/engine_room) +"cGd" = (/obj/structure/table/reinforced,/obj/machinery/door_control{desc = "A remote control-switch for the engine control room blast doors."; id = "EngineBlast"; name = "Engine Monitoring Room Blast Doors"; pixel_x = 0; pixel_y = -3; req_access_txt = "10"},/obj/machinery/door_control{desc = "A remote control-switch for the engine charging port."; id = "SupermatterPort"; name = "Reactor Blast Doors"; pixel_x = -6; pixel_y = 7; req_access_txt = "10"},/obj/machinery/door_control{desc = "A remote control-switch for the engine emitter."; id = "EngineEmitter"; name = "Engine Emitter"; normaldoorcontrol = 2; pixel_x = 6; pixel_y = 7; req_access_txt = "10"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/engineering/engine_monitoring) "cGe" = (/obj/structure/cable/cyan{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/cyan{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/turf/simulated/floor/plating,/area/engineering/engine_room) "cGf" = (/obj/structure/cable/cyan{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/turf/simulated/floor/plating,/area/engineering/engine_room) "cGg" = (/turf/space,/area/shuttle/constructionsite/station) "cGh" = (/obj/structure/cable/cyan{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/engineering/engine_room) "cGi" = (/obj/structure/cable/cyan{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/turf/simulated/floor/plating,/area/engineering/engine_room) "cGj" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/maintenance/engineering) -"cGk" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; icon_state = "space"; layer = 4; name = "EXTERNAL AIRLOCK"; pixel_x = 32; pixel_y = 0},/turf/space,/area/space) +"cGk" = (/obj/machinery/alarm{breach_detection = 0; dir = 2; frequency = 1439; name = "Engine Room Air Alarm"; pixel_y = 23},/obj/machinery/atmospherics/pipe/simple/visible/cyan{dir = 10},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 4},/area/engineering/engine_room) "cGl" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/medical/virology) "cGm" = (/turf/simulated/floor/plating,/area/engineering/engine_room) "cGn" = (/obj/machinery/light_switch{pixel_x = 12; pixel_y = 25},/obj/machinery/power/apc/super{dir = 1; name = "north bump"; pixel_y = 24},/obj/structure/cable/cyan{d2 = 8; icon_state = "0-8"},/obj/machinery/power/sensor{name = "Powernet Sensor - Engine Power"; name_tag = "Engine Power"},/turf/simulated/floor/plating,/area/engineering/engine_room) @@ -7094,11 +7094,11 @@ "cGv" = (/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/window/brigdoor{dir = 8; name = "Engine Waste"; req_access = null; req_access_txt = "0"; req_one_access_txt = "10;24"},/obj/machinery/atmospherics/portables_connector,/turf/simulated/floor/plating{icon_state = "platebot"},/area/engineering/engine_waste) "cGw" = (/obj/machinery/atmospherics/omni/filter{use_power = 0; tag_east = 1; tag_north = 0; tag_south = 4; tag_west = 2},/turf/simulated/floor/plating,/area/engineering/engine_room) "cGx" = (/obj/machinery/atmospherics/pipe/simple/visible/purple{dir = 6},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 8},/area/engineering/engine_room) -"cGy" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 1},/area/engineering/engine_room) -"cGz" = (/obj/machinery/atmospherics/pipe/manifold/visible/yellow{dir = 4},/turf/simulated/floor/plating{dir = 8; icon_state = "warnplatecorner"},/area/engineering/engine_room) +"cGy" = (/obj/structure/cable/yellow{d2 = 4; icon_state = "0-4"},/obj/machinery/power/smes/buildable{charge = 2e+006; input_attempt = 1; input_level = 100000; output_level = 200000; RCon_tag = "Engine - Core"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 1},/area/engineering/engine_room) +"cGz" = (/obj/machinery/atmospherics/pipe/simple/heat_exchanging{tag = "icon-intact (SOUTHWEST)"; icon_state = "intact"; dir = 10},/turf/space,/area/space) "cGA" = (/turf/simulated/floor/plating{dir = 4; icon_state = "warnplatecorner"},/area/engineering/engine_room) -"cGB" = (/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 1},/area/engineering/engine_room) -"cGC" = (/obj/structure/cable/cyan{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/engineering/engine_room) +"cGB" = (/obj/structure/cable/yellow{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 1},/area/engineering/engine_room) +"cGC" = (/obj/machinery/atmospherics/pipe/manifold/visible/cyan{tag = "icon-map (EAST)"; icon_state = "map"; dir = 4},/turf/simulated/floor/plating{dir = 8; icon_state = "warnplatecorner"},/area/engineering/engine_room) "cGD" = (/obj/machinery/atmospherics/binary/pump,/turf/simulated/floor/plating,/area/engineering/engine_room) "cGE" = (/obj/machinery/atmospherics/unary/heat_exchanger{dir = 8},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 9},/area/engineering/engine_waste) "cGF" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'KEEP CLEAR OF DOCKING AREA'."; name = "KEEP CLEAR: DOCKING AREA"; pixel_y = 0},/turf/simulated/wall,/area/maintenance/engineering) @@ -7107,16 +7107,16 @@ "cGI" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold/visible/purple{dir = 1},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 4},/area/engineering/engine_waste) "cGJ" = (/obj/machinery/atmospherics/unary/heat_exchanger{dir = 4},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 5},/area/engineering/engine_waste) "cGK" = (/obj/machinery/door/window/brigdoor{dir = 8; name = "Engine Waste"; req_access = null; req_access_txt = "0"; req_one_access_txt = "10;24"},/obj/machinery/atmospherics/pipe/simple/visible/purple{dir = 9},/turf/simulated/floor/plating{icon_state = "platebot"},/area/engineering/engine_waste) -"cGL" = (/obj/machinery/atmospherics/pipe/manifold/visible/yellow{dir = 8},/turf/simulated/floor/plating,/area/engineering/engine_room) +"cGL" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating{dir = 4; icon_state = "warnplatecorner"},/area/engineering/engine_room) "cGM" = (/obj/machinery/atmospherics/pipe/simple/visible/purple,/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 8},/area/engineering/engine_room) "cGN" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/engineering/engine_room) -"cGO" = (/obj/machinery/atmospherics/pipe/manifold/visible/yellow{dir = 4},/obj/machinery/meter,/turf/simulated/floor/plating,/area/engineering/engine_room) -"cGP" = (/obj/structure/cable/cyan{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/valve/digital/open{dir = 4},/turf/simulated/floor/plating{dir = 2; icon_state = "warnplate"},/area/engineering/engine_room) +"cGO" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 1},/area/engineering/engine_room) +"cGP" = (/obj/structure/cable/cyan{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/engineering/engine_room) "cGQ" = (/obj/machinery/atmospherics/pipe/simple/heat_exchanging{dir = 6},/turf/space,/area/space) "cGR" = (/obj/machinery/atmospherics/pipe/simple/heat_exchanging{dir = 4},/turf/space,/area/space) "cGS" = (/obj/machinery/atmospherics/pipe/simple/heat_exchanging/junction{dir = 8},/obj/structure/lattice,/obj/structure/grille,/turf/space,/area/space) -"cGT" = (/obj/machinery/atmospherics/pipe/simple/visible/yellow{dir = 6},/turf/simulated/floor/plating{dir = 2; icon_state = "warnplatecorner"},/area/engineering/engine_room) -"cGU" = (/obj/machinery/atmospherics/pipe/simple/visible/cyan{tag = "icon-intact (SOUTHWEST)"; icon_state = "intact"; dir = 10},/turf/simulated/floor/plating{dir = 1; icon_state = "warnplatecorner"},/area/engineering/engine_room) +"cGT" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/engineering/engine_room) +"cGU" = (/obj/machinery/atmospherics/binary/pump,/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/engineering/engine_room) "cGV" = (/obj/machinery/atmospherics/pipe/simple/visible/cyan,/turf/simulated/floor/plating,/area/engineering/engine_room) "cGW" = (/obj/structure/grille,/obj/structure/grille,/turf/space,/area/space) "cGX" = (/obj/machinery/atmospherics/unary/heat_exchanger{dir = 8},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 10},/area/engineering/engine_waste) @@ -7127,16 +7127,16 @@ "cHc" = (/obj/machinery/door/window/brigdoor{dir = 8; name = "Engine Waste"; req_access = null; req_access_txt = "0"; req_one_access_txt = "10;24"},/obj/structure/window/reinforced,/obj/machinery/atmospherics/binary/pump{dir = 8; name = "waste pump"},/turf/simulated/floor/plating{icon_state = "platebot"},/area/engineering/engine_waste) "cHd" = (/obj/machinery/atmospherics/omni/filter{use_power = 0; tag_east = 1; tag_north = 4; tag_south = 0; tag_west = 2},/turf/simulated/floor/plating,/area/engineering/engine_room) "cHe" = (/obj/machinery/atmospherics/pipe/manifold/visible/purple,/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 8},/area/engineering/engine_room) -"cHf" = (/obj/machinery/atmospherics/pipe/simple/visible/yellow{dir = 4},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/engineering/engine_room) +"cHf" = (/obj/structure/cable/yellow{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/plating,/area/engineering/engine_room) "cHg" = (/obj/machinery/atmospherics/pipe/manifold/visible/yellow,/turf/simulated/floor/plating,/area/engineering/engine_room) "cHh" = (/obj/machinery/atmospherics/pipe/simple/visible/yellow{dir = 4},/turf/simulated/floor/plating,/area/engineering/engine_room) "cHi" = (/obj/machinery/power/emitter{anchored = 1; id = "EngineEmitter"; state = 2},/obj/structure/cable/cyan,/turf/simulated/floor/plating,/area/engineering/engine_room) -"cHj" = (/obj/machinery/atmospherics/pipe/manifold/visible/yellow{dir = 4},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 4},/area/engineering/engine_room) +"cHj" = (/obj/machinery/atmospherics/pipe/manifold/visible/cyan{dir = 8},/turf/simulated/floor/plating,/area/engineering/engine_room) "cHk" = (/obj/machinery/atmospherics/pipe/simple/visible/cyan{dir = 4; icon_state = "intact"; tag = "icon-intact (EAST)"},/turf/simulated/floor/plating,/area/engineering/engine_room) -"cHl" = (/obj/machinery/atmospherics/pipe/manifold/visible/cyan{dir = 8},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 8},/area/engineering/engine_room) -"cHm" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/atmospherics/pipe/simple/visible/cyan{dir = 4; icon_state = "intact"; tag = "icon-intact (EAST)"},/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "EngineRadiatorViewport"; name = "Engine Radiator Viewport Shutter"; opacity = 0},/turf/simulated/floor/plating,/area/engineering/engine_room) +"cHl" = (/obj/machinery/meter,/obj/machinery/atmospherics/pipe/manifold/visible/cyan{tag = "icon-map (EAST)"; icon_state = "map"; dir = 4},/turf/simulated/floor/plating,/area/engineering/engine_room) +"cHm" = (/obj/structure/cable/cyan{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/visible/cyan{dir = 4; icon_state = "intact"; tag = "icon-intact (EAST)"},/turf/simulated/floor/plating{dir = 2; icon_state = "warnplate"},/area/engineering/engine_room) "cHn" = (/obj/machinery/power/solar{id = "portsolar"; name = "Port Solar Array"},/obj/structure/cable/yellow{d2 = 4; icon_state = "0-4"},/turf/simulated/floor/airless{icon_state = "solarpanel"},/area/solar/port) -"cHo" = (/obj/machinery/atmospherics/pipe/manifold4w/visible/cyan,/obj/machinery/meter,/turf/simulated/floor/plating,/area/engineering/engine_room) +"cHo" = (/obj/machinery/atmospherics/pipe/simple/visible/cyan{tag = "icon-intact (SOUTHEAST)"; icon_state = "intact"; dir = 6},/turf/simulated/floor/plating{dir = 2; icon_state = "warnplatecorner"},/area/engineering/engine_room) "cHp" = (/obj/machinery/power/solar{id = "portsolar"; name = "Port Solar Array"},/obj/structure/cable/yellow{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/airless{icon_state = "solarpanel"},/area/solar/port) "cHq" = (/obj/machinery/atmospherics/pipe/simple/heat_exchanging{dir = 5},/turf/space,/area/space) "cHr" = (/obj/structure/lattice,/obj/machinery/atmospherics/pipe/simple/heat_exchanging{dir = 4},/turf/space,/area/space) @@ -7148,72 +7148,101 @@ "cHx" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating{dir = 8; icon_state = "warnplatecorner"},/area/engineering/engine_waste) "cHy" = (/obj/machinery/alarm{dir = 1; icon_state = "alarm0"; pixel_y = -22},/turf/simulated/floor/plating,/area/engineering/engine_waste) "cHz" = (/obj/machinery/light/small{dir = 4},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 1},/area/engineering/engine_waste) -"cHA" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/yellow{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor/plating{dir = 2; icon_state = "warnplate"},/area/engineering/engine_room) -"cHB" = (/obj/structure/cable/yellow{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor/plating{dir = 2; icon_state = "warnplatecorner"},/area/engineering/engine_room) -"cHC" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating{dir = 2; icon_state = "warnplate"},/area/engineering/engine_room) -"cHD" = (/obj/machinery/light,/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating{dir = 2; icon_state = "warnplate"},/area/engineering/engine_room) -"cHE" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating{dir = 2; icon_state = "warnplate"},/area/engineering/engine_room) -"cHF" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/visible/yellow,/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 6},/area/engineering/engine_room) -"cHG" = (/obj/machinery/door_control{desc = "A remote control-switch for the engine control room blast doors."; id = "EngineBlast"; name = "Engine Room Blast Doors"; pixel_x = 5; pixel_y = -25; req_access_txt = "10"},/obj/machinery/door_control{desc = "A remote control-switch for the engine charging port."; id = "EngineEmitterPort"; name = "Engine Charging Port"; pixel_x = -5; pixel_y = -25; req_access_txt = "10"},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating{dir = 2; icon_state = "warnplate"},/area/engineering/engine_room) -"cHH" = (/obj/machinery/atmospherics/pipe/simple/visible/cyan,/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 10},/area/engineering/engine_room) -"cHI" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_y = -29},/turf/simulated/floor/plating{dir = 2; icon_state = "warnplate"},/area/engineering/engine_room) -"cHJ" = (/obj/structure/cable/yellow{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/plating{dir = 1; icon_state = "warnplatecorner"},/area/engineering/engine_room) +"cHA" = (/obj/machinery/atmospherics/pipe/simple/visible/cyan{dir = 10},/turf/simulated/floor/plating{dir = 1; icon_state = "warnplatecorner"},/area/engineering/engine_room) +"cHB" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/visible/green{tag = "icon-intact (EAST)"; icon_state = "intact"; dir = 4},/turf/simulated/floor/plating,/area/engineering/engine_room) +"cHC" = (/obj/machinery/atmospherics/valve/digital{dir = 4; name = "Emergency Cooling Valve 1"},/turf/simulated/floor/plating,/area/engineering/engine_room) +"cHD" = (/obj/machinery/atmospherics/pipe/manifold/visible/green{tag = "icon-map (EAST)"; icon_state = "map"; dir = 4},/turf/simulated/floor/plating,/area/engineering/engine_room) +"cHE" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'KEEP CLEAR OF DOCKING AREA'."; name = "KEEP CLEAR: DOCKING AREA"; pixel_x = -32; pixel_y = 0},/turf/space,/area/space) +"cHF" = (/obj/machinery/atmospherics/pipe/simple/heat_exchanging,/turf/space,/area/space) +"cHG" = (/obj/machinery/atmospherics/pipe/manifold/visible/cyan,/turf/simulated/floor/plating,/area/engineering/engine_room) +"cHH" = (/obj/machinery/atmospherics/pipe/manifold/visible/cyan{tag = "icon-map (EAST)"; icon_state = "map"; dir = 4},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 4},/area/engineering/engine_room) +"cHI" = (/obj/machinery/atmospherics/pipe/simple/visible/cyan{tag = "icon-intact (NORTHEAST)"; icon_state = "intact"; dir = 5},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 8},/area/engineering/engine_room) +"cHJ" = (/obj/machinery/meter,/obj/machinery/atmospherics/pipe/manifold4w/visible/cyan,/turf/simulated/floor/plating,/area/engineering/engine_room) "cHK" = (/obj/item/stack/rods{amount = 10},/turf/space,/area/space) -"cHL" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/atmospherics/pipe/simple/visible/cyan{dir = 4; icon_state = "intact"; tag = "icon-intact (EAST)"},/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "EngineRadiatorViewport"; name = "Engine Radiator Viewport Shutter"; opacity = 0},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/engineering/engine_room) +"cHL" = (/obj/machinery/atmospherics/pipe/simple/visible/cyan{dir = 10},/turf/simulated/floor/plating,/area/engineering/engine_room) "cHM" = (/obj/machinery/atmospherics/pipe/simple/visible/cyan{tag = "icon-intact (NORTHEAST)"; icon_state = "intact"; dir = 5},/turf/simulated/floor/plating,/area/engineering/engine_room) "cHN" = (/obj/structure/lattice,/obj/machinery/atmospherics/pipe/simple/heat_exchanging{dir = 6},/turf/space,/area/space) "cHO" = (/obj/structure/lattice,/obj/machinery/atmospherics/pipe/simple/heat_exchanging,/turf/space,/area/space) -"cHP" = (/obj/machinery/camera{c_tag = "Engineering Core West"; dir = 8; network = list("SS13","Supermatter")},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 4},/area/engineering/engine_room) -"cHQ" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/blast/regular{icon_state = "pdoor1"; id = "EngineEmitterPort"; layer = 3.3; name = "Engine Blast Doors"},/turf/simulated/floor/plating,/area/engineering/engine_room) +"cHP" = (/obj/machinery/atmospherics/pipe/manifold/visible/green{dir = 1},/obj/machinery/meter,/turf/simulated/floor/plating,/area/engineering/engine_room) +"cHQ" = (/obj/machinery/atmospherics/pipe/manifold/visible/green{dir = 8},/turf/simulated/floor/plating,/area/engineering/engine_room) "cHR" = (/obj/machinery/door/airlock/hatch{icon_state = "door_locked"; id_tag = "engine_access_hatch"; locked = 1; req_access_txt = "10"},/obj/machinery/atmospherics/pipe/simple/visible/yellow,/turf/simulated/floor/plating,/area/engineering/engine_room) "cHS" = (/obj/machinery/door/airlock/hatch{icon_state = "door_locked"; id_tag = "engine_access_hatch"; locked = 1; req_access_txt = "10"},/obj/machinery/atmospherics/pipe/simple/visible/cyan,/turf/simulated/floor/plating,/area/engineering/engine_room) -"cHT" = (/obj/machinery/camera{c_tag = "Engineering Core East"; dir = 4; network = list("SS13","Supermatter")},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 8},/area/engineering/engine_room) -"cHU" = (/obj/machinery/door_control{desc = "A remote control-switch for the engine radiator viewport shutters."; id = "EngineRadiatorViewport"; name = "Engine Radiator Viewport Shutters"; pixel_x = 25; pixel_y = 0; req_access_txt = "10"},/turf/simulated/floor/plating,/area/engineering/engine_room) +"cHT" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "EngineRadiatorViewport"; name = "Engine Radiator Viewport Shutter"; opacity = 0},/obj/machinery/atmospherics/pipe/simple/visible/green{tag = "icon-intact (EAST)"; icon_state = "intact"; dir = 4},/turf/simulated/floor/plating,/area/engineering/engine_room) +"cHU" = (/obj/machinery/atmospherics/binary/pump/high_power{dir = 8},/turf/simulated/floor/plating,/area/engineering/engine_room) "cHV" = (/obj/structure/cable{d2 = 2; icon_state = "0-2"; pixel_y = 0},/obj/machinery/power/smes/buildable{charge = 0; RCon_tag = "Solar - Aft Port"},/turf/simulated/floor/plating,/area/maintenance/portsolar) "cHW" = (/obj/machinery/light{dir = 8},/turf/simulated/floor/plating,/area/engineering/engine_room) -"cHX" = (/obj/machinery/door/blast/regular{icon_state = "pdoor1"; id = "EngineRads"; layer = 3.3; name = "Engine Radiation Collector Access"},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/engineering/engine_room) -"cHY" = (/obj/structure/cable/yellow{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 4},/area/engineering/engine_room) -"cHZ" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/engineering/engine_room) -"cIa" = (/obj/machinery/power/rad_collector,/obj/structure/cable/yellow{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/engineering/engine_room) -"cIb" = (/obj/structure/lattice,/obj/structure/sign/securearea{desc = "A warning sign which reads 'KEEP CLEAR OF DOCKING AREA'."; name = "KEEP CLEAR: DOCKING AREA"; pixel_x = -32; pixel_y = 0},/turf/space,/area/space) +"cHX" = (/obj/machinery/light,/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_y = -29},/turf/simulated/floor/plating{dir = 2; icon_state = "warnplate"},/area/engineering/engine_room) +"cHY" = (/turf/simulated/floor/plating{dir = 2; icon_state = "warnplatecorner"},/area/engineering/engine_room) +"cHZ" = (/turf/simulated/floor/plating{dir = 2; icon_state = "warnplate"},/area/engineering/engine_room) +"cIa" = (/obj/machinery/atmospherics/pipe/simple/visible/cyan,/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 6},/area/engineering/engine_room) +"cIb" = (/obj/machinery/door_control{desc = "A remote control-switch for the engine control room blast doors."; id = "EngineBlast"; name = "Engine Monitoring Room Blast Doors"; pixel_x = 5; pixel_y = -25; req_access_txt = "10"},/obj/machinery/door_control{desc = "A remote control-switch for the engine charging port."; id = "SupermatterPort"; name = "Reactor Blast Doors"; pixel_x = -5; pixel_y = -25; req_access_txt = "10"},/obj/machinery/light,/obj/machinery/atmospherics/pipe/simple/visible/yellow{dir = 4},/turf/simulated/floor/plating{dir = 2; icon_state = "warnplate"},/area/engineering/engine_room) "cIc" = (/obj/item/stack/cable_coil,/turf/space,/area/space) "cId" = (/obj/machinery/air_sensor{frequency = 1438; id_tag = "engine_sensor"; output = 63},/turf/simulated/floor/engine/nitrogen{icon_state = "warnplate"; name = "plating"},/area/engineering/engine_room) -"cIe" = (/obj/machinery/atmospherics/unary/vent_pump/engine{dir = 1; external_pressure_bound = 100; external_pressure_bound_default = 0; frequency = 1438; icon_state = "map_vent_in"; id_tag = "cooling_out"; initialize_directions = 1; use_power = 1; pressure_checks = 1; pressure_checks_default = 1; pump_direction = 0},/turf/simulated/floor/engine/nitrogen{icon_state = "warnplatecorner"; name = "plating"},/area/engineering/engine_room) -"cIf" = (/obj/machinery/atmospherics/unary/outlet_injector{dir = 1; frequency = 1438; icon_state = "map_injector"; id = "cooling_in"; name = "Coolant Injector"; use_power = 1; pixel_y = 1; volume_rate = 700},/turf/simulated/floor/engine/nitrogen{dir = 1; icon_state = "warnplatecorner"; name = "plating"},/area/engineering/engine_room) -"cIg" = (/obj/machinery/power/rad_collector,/obj/structure/cable/yellow{d2 = 4; icon_state = "0-4"},/turf/simulated/floor/plating,/area/engineering/engine_room) -"cIh" = (/obj/structure/cable/yellow{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 8},/area/engineering/engine_room) -"cIi" = (/obj/machinery/light{icon_state = "tube1"; dir = 4},/turf/simulated/floor/plating,/area/engineering/engine_room) -"cIj" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/engineering/engine_room) +"cIe" = (/obj/machinery/atmospherics/pipe/simple/visible/yellow{dir = 6},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 10},/area/engineering/engine_room) +"cIf" = (/obj/machinery/atmospherics/pipe/simple/visible/yellow{dir = 10},/turf/simulated/floor/plating{dir = 1; icon_state = "warnplatecorner"},/area/engineering/engine_room) +"cIg" = (/obj/structure/cable/yellow{d2 = 2; icon_state = "0-2"},/obj/machinery/power/generator{anchored = 1; dir = 4},/obj/structure/cable/yellow,/turf/simulated/floor/plating,/area/engineering/engine_room) +"cIh" = (/obj/machinery/atmospherics/binary/circulator{anchored = 1; dir = 1},/turf/simulated/floor/plating,/area/engineering/engine_room) +"cIi" = (/obj/machinery/atmospherics/pipe/simple/visible/green,/turf/simulated/floor/plating,/area/engineering/engine_room) +"cIj" = (/obj/machinery/atmospherics/binary/circulator{anchored = 1},/turf/simulated/floor/plating,/area/engineering/engine_room) "cIk" = (/obj/machinery/power/supermatter{layer = 4},/obj/machinery/mass_driver{id = "enginecore"},/turf/simulated/floor/engine/nitrogen{icon_state = "gcircuit"; name = "floor"},/area/engineering/engine_room) "cIl" = (/turf/simulated/floor/engine/nitrogen{dir = 4; icon_state = "warnplate"; name = "plating"},/area/engineering/engine_room) "cIm" = (/turf/simulated/floor/engine/nitrogen{dir = 8; icon_state = "warnplate"; name = "plating"},/area/engineering/engine_room) -"cIn" = (/obj/machinery/door_control{id = "EngineVent"; name = "Engine Ventillatory Control"; pixel_x = -25; pixel_y = 0; req_access_txt = "10"},/turf/simulated/floor/plating,/area/engineering/engine_room) -"cIo" = (/obj/machinery/door_control{desc = "A remote control-switch for opening the engines blast doors."; id = "EngineRads"; name = "Radiation Collector Access"; pixel_x = 0; pixel_y = -25; req_access_txt = "10"},/obj/structure/cable/yellow{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 4},/area/engineering/engine_room) -"cIp" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/engineering/engine_room) +"cIn" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "EngineRadiatorViewport"; name = "Engine Radiator Viewport Shutter"; opacity = 0},/obj/structure/window/reinforced,/obj/machinery/atmospherics/pipe/simple/visible/green{tag = "icon-intact (EAST)"; icon_state = "intact"; dir = 4},/turf/simulated/floor/plating,/area/engineering/engine_room) +"cIo" = (/obj/machinery/atmospherics/pipe/simple/visible/purple{dir = 6},/turf/simulated/floor/plating,/area/engineering/engine_room) +"cIp" = (/obj/machinery/camera{c_tag = "Engineering Core West"; dir = 8; network = list("SS13","Supermatter")},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 4},/area/engineering/engine_room) "cIq" = (/turf/simulated/floor/engine/nitrogen,/area/engineering/engine_room) "cIr" = (/obj/machinery/camera{c_tag = "Engineering Core South"; dir = 1; network = list("SS13","Supermatter")},/turf/simulated/floor/engine/nitrogen{dir = 8; icon_state = "warnplate"; name = "plating"},/area/engineering/engine_room) -"cIs" = (/obj/machinery/door_control{desc = "A remote control-switch for opening the engines blast doors."; id = "EngineRads"; name = "Radiation Collector Access"; pixel_x = 0; pixel_y = -25; req_access_txt = "10"},/obj/structure/cable/yellow{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 8},/area/engineering/engine_room) -"cIt" = (/obj/machinery/door/blast/regular{icon_state = "pdoor1"; id = "EngineVent"; name = "Engine Core Vent"; p_open = 0},/turf/simulated/floor/engine,/area/engineering/engine_room) +"cIs" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/blast/regular{dir = 8; icon_state = "pdoor1"; id = "SupermatterPort"; layer = 3.3; name = "Reactor Blast Door"},/turf/simulated/floor/plating,/area/engineering/engine_room) +"cIt" = (/obj/machinery/atmospherics/pipe/simple/visible/cyan,/obj/machinery/atmospherics/pipe/simple/visible/yellow{dir = 4},/turf/simulated/floor/plating,/area/engineering/engine_room) "cIu" = (/obj/structure/lattice,/obj/machinery/atmospherics/pipe/simple/heat_exchanging{dir = 5},/turf/space,/area/space) "cIv" = (/obj/structure/lattice,/obj/machinery/atmospherics/pipe/simple/heat_exchanging{tag = "icon-intact (NORTHWEST)"; icon_state = "intact"; dir = 9},/turf/space,/area/space) -"cIw" = (/obj/effect/landmark{name = "carpspawn"},/obj/structure/grille{density = 0; icon_state = "brokengrille"},/turf/space,/area/space) -"cIx" = (/obj/machinery/light,/obj/structure/extinguisher_cabinet{pixel_x = 5; pixel_y = -32},/obj/machinery/portable_atmospherics/hydroponics,/turf/simulated/floor{dir = 8; icon_state = "whitegreen"},/area/rnd/xenobiology/xenoflora) -"cIy" = (/obj/effect/landmark{name = "JoinLateCyborg"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 8},/area/engineering/drone_fabrication) +"cIw" = (/obj/machinery/camera{c_tag = "Engineering Core East"; dir = 4; network = list("SS13","Supermatter")},/obj/machinery/atmospherics/pipe/manifold/visible/yellow{dir = 8},/obj/machinery/meter,/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 8},/area/engineering/engine_room) +"cIx" = (/obj/effect/landmark{name = "JoinLateCyborg"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 8},/area/engineering/drone_fabrication) +"cIy" = (/obj/machinery/atmospherics/pipe/simple/visible/yellow{dir = 9},/turf/simulated/floor/plating,/area/engineering/engine_room) +"cIz" = (/obj/machinery/atmospherics/pipe/simple/visible/purple{dir = 4},/obj/machinery/atmospherics/pipe/simple/visible/green,/turf/simulated/floor/plating,/area/engineering/engine_room) +"cIA" = (/obj/machinery/atmospherics/pipe/simple/visible/purple{dir = 5},/turf/simulated/floor/plating,/area/engineering/engine_room) +"cIB" = (/obj/machinery/door_control{desc = "A remote control-switch for the engine radiator viewport shutters."; id = "EngineRadiatorViewport"; name = "Engine Radiator Viewport Shutters"; pixel_x = 25; pixel_y = 0; req_access_txt = "10"},/obj/machinery/atmospherics/pipe/manifold/visible/purple{dir = 4},/obj/machinery/meter,/turf/simulated/floor/plating,/area/engineering/engine_room) +"cIC" = (/obj/machinery/atmospherics/pipe/simple/heat_exchanging,/obj/structure/lattice,/turf/space,/area/space) +"cID" = (/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/engineering/engine_room) +"cIE" = (/obj/machinery/door_control{id = "EngineVent"; name = "Reactor Ventillatory Control"; pixel_x = -25; pixel_y = 0; req_access_txt = "10"},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/engineering/engine_room) +"cIF" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/blast/regular{icon_state = "pdoor1"; id = "SupermatterPort"; layer = 3.3; name = "Reactor Blast Door"},/turf/simulated/floor/plating,/area/engineering/engine_room) +"cIG" = (/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 4},/area/engineering/engine_room) +"cIH" = (/obj/machinery/atmospherics/unary/outlet_injector{dir = 1; frequency = 1438; icon_state = "map_injector"; id = "cooling_in"; name = "Coolant Injector"; pixel_y = 1; power_rating = 30000; use_power = 1; volume_rate = 700},/turf/simulated/floor/engine/nitrogen{icon_state = "warnplatecorner"; name = "plating"},/area/engineering/engine_room) +"cII" = (/obj/machinery/atmospherics/unary/vent_pump/engine{dir = 1; external_pressure_bound = 100; external_pressure_bound_default = 0; frequency = 1438; icon_state = "map_vent_in"; id_tag = "cooling_out"; initialize_directions = 1; use_power = 1; pressure_checks = 1; pressure_checks_default = 1; pump_direction = 0},/turf/simulated/floor/engine/nitrogen{dir = 1; icon_state = "warnplatecorner"; name = "plating"},/area/engineering/engine_room) "cIJ" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating/airless,/area/maintenance/portsolar) "cIK" = (/turf/simulated/wall/r_wall,/area/maintenance/portsolar) "cIL" = (/turf/simulated/wall/r_wall,/area/maintenance/engi_engine) "cIM" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/airlock/maintenance{name = "Engine Waste Handling"; req_one_access_txt = "10;24"},/turf/simulated/floor/plating,/area/maintenance/engi_engine) +"cIN" = (/obj/machinery/atmospherics/pipe/simple/visible/yellow,/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 8},/area/engineering/engine_room) +"cIO" = (/obj/machinery/atmospherics/pipe/simple/visible/green{dir = 9; icon_state = "intact"; tag = "icon-intact (SOUTHEAST)"},/turf/simulated/floor/plating,/area/engineering/engine_room) +"cIP" = (/obj/machinery/atmospherics/pipe/simple/visible/green{tag = "icon-intact (SOUTHEAST)"; icon_state = "intact"; dir = 6},/turf/simulated/floor/plating,/area/engineering/engine_room) +"cIQ" = (/obj/machinery/light{icon_state = "tube1"; dir = 4},/obj/machinery/atmospherics/pipe/simple/visible/purple,/turf/simulated/floor/plating,/area/engineering/engine_room) +"cIR" = (/obj/machinery/portable_atmospherics/canister/nitrogen,/turf/simulated/floor/plating{icon_state = "platebot"},/area/engineering/engine_room) +"cIS" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/blast/regular{icon_state = "pdoor1"; id = "SupermatterPort"; layer = 3.3; name = "Reactor Blast Door"},/turf/simulated/floor/plating,/area/engineering/engine_room) +"cIT" = (/obj/machinery/power/generator{anchored = 1; dir = 4},/obj/structure/cable/yellow,/turf/simulated/floor/plating,/area/engineering/engine_room) "cIU" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating/airless,/area/maintenance/portsolar) "cIV" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/turf/simulated/floor/plating/airless,/area/maintenance/portsolar) "cIW" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating/airless,/area/maintenance/portsolar) "cIX" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; icon_state = "space"; layer = 4; name = "EXTERNAL AIRLOCK"; pixel_x = -32; pixel_y = 0},/obj/machinery/atmospherics/portables_connector,/obj/machinery/portable_atmospherics/canister/air/airlock,/turf/simulated/floor/plating{dir = 1; icon_state = "warnplatecorner"},/area/maintenance/portsolar) "cIY" = (/obj/machinery/power/terminal{dir = 4},/obj/machinery/light/small{dir = 1},/obj/structure/cable/yellow{d2 = 2; icon_state = "0-2"},/turf/simulated/floor/plating,/area/maintenance/portsolar) +"cIZ" = (/obj/machinery/atmospherics/pipe/simple/visible/purple,/turf/simulated/floor/plating,/area/engineering/engine_room) "cJa" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'HIGH VOLTAGE'"; icon_state = "shock"; name = "HIGH VOLTAGE"; pixel_y = 0},/turf/simulated/wall/r_wall,/area/maintenance/portsolar) "cJb" = (/obj/structure/closet/wardrobe/black,/obj/machinery/light/small{dir = 8},/turf/simulated/floor/plating{dir = 1; icon_state = "warnplatecorner"},/area/maintenance/engi_engine) "cJc" = (/obj/structure/closet/crate,/obj/item/device/multitool,/obj/item/device/multitool,/obj/item/device/assembly/prox_sensor,/obj/item/device/flashlight,/turf/simulated/floor/plating,/area/maintenance/engi_engine) +"cJd" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/machinery/door/blast/regular{icon_state = "pdoor1"; id = "SupermatterPort"; layer = 3.3; name = "Reactor Blast Door"},/turf/simulated/floor/plating,/area/engineering/engine_room) "cJe" = (/turf/simulated/floor/plating,/area/maintenance/engi_engine) "cJf" = (/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/turf/simulated/floor/plating,/area/maintenance/engi_engine) "cJg" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor/plating,/area/maintenance/engi_engine) +"cJh" = (/obj/machinery/atmospherics/pipe/simple/visible/yellow{tag = "icon-intact (NORTHEAST)"; icon_state = "intact"; dir = 5},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 8},/area/engineering/engine_room) +"cJi" = (/obj/machinery/atmospherics/valve/digital{dir = 4; name = "Emergency Cooling Valve 2"},/turf/simulated/floor/plating,/area/engineering/engine_room) +"cJj" = (/obj/machinery/atmospherics/pipe/simple/visible/purple{dir = 4},/turf/simulated/floor/plating,/area/engineering/engine_room) +"cJk" = (/obj/machinery/atmospherics/pipe/manifold/visible/purple,/turf/simulated/floor/plating,/area/engineering/engine_room) +"cJl" = (/obj/machinery/atmospherics/pipe/simple/visible/purple{dir = 9},/turf/simulated/floor/plating,/area/engineering/engine_room) +"cJm" = (/obj/machinery/door/blast/regular{icon_state = "pdoor1"; id = "EngineVent"; name = "Reactor Vent"; p_open = 0},/turf/simulated/floor/engine,/area/engineering/engine_room) +"cJn" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'EJECTION/VENTING PORT'."; name = "\improper EJECTION/VENTING PORT"; pixel_y = 32},/turf/space,/area/space) +"cJo" = (/obj/machinery/atmospherics/pipe/simple/heat_exchanging{tag = "icon-intact (NORTHWEST)"; icon_state = "intact"; dir = 9},/turf/space,/area/space) +"cJp" = (/obj/machinery/atmospherics/pipe/simple/heat_exchanging{dir = 5},/obj/structure/lattice,/turf/space,/area/space) +"cJq" = (/obj/effect/landmark{name = "carpspawn"},/obj/structure/grille{density = 0; icon_state = "brokengrille"},/obj/structure/lattice,/turf/space,/area/space) "cJz" = (/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "robotics_solar_outer"; locked = 1; name = "Engineering External Access"; req_access = null; req_access_txt = "10;13"},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/maintenance/portsolar) "cJA" = (/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 4; frequency = 1379; id_tag = "robotics_solar_pump"},/obj/machinery/embedded_controller/radio/airlock/airlock_controller{tag_airpump = "robotics_solar_pump"; tag_exterior_door = "robotics_solar_outer"; frequency = 1379; id_tag = "robotics_solar_airlock"; tag_interior_door = "robotics_solar_inner"; layer = 3.3; pixel_x = 0; pixel_y = -25; req_access_txt = "13"; tag_chamber_sensor = "robotics_solar_sensor"},/obj/machinery/airlock_sensor{frequency = 1379; id_tag = "robotics_solar_sensor"; layer = 3.3; pixel_x = 12; pixel_y = -25},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/effect/decal/warning_stripes,/turf/simulated/floor/plating,/area/maintenance/portsolar) "cJB" = (/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "robotics_solar_inner"; locked = 1; name = "Engineering External Access"; req_access = null; req_access_txt = "13"},/obj/machinery/atmospherics/pipe/simple/visible{dir = 4},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/maintenance/portsolar) @@ -7380,13 +7409,13 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaT aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaaaaaaaaabhObhObhObhObhObhObhObhObhObhObhObkKbkLbkMbkNbkObgrbkPbkQbkRbkRbkSbkTbkUbkVbkWbkWbkXbkYbbZbbZbbZbeZbkZbbZbajbajbajbajblaaXeaXeblbblcbldbleblfblgblhblibljblkbdPbllbfmblmbgGblnbgGbloblpblqaSzbctaJeblrblsbltblublvblwblxblybdYbebblzblAblCblBblDblAblEbebbedbedblFblGblHblIbiCblJblKaJiblLblMblNaJiblOblOblOblOblOblOaZzaZzblPblQbZNcdMblQblPaZzaZzaZzaZzaZzaZzaZzaZzaZzaZzblTaZzaZzaZzaZzaZzaZzaVIaZzbewbewblVblWblWblOblOblOblOblOblXblYblYblZblYbewblYblZbmablYbmbblObmcbmcbmcbmdaRZbmeaRZaRZaaaaaaaaaaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaaaaaaaaabhObhObhObhObhObhObhObhObhObhObhObdubdvbjmbjnbmfbgrbmgbjpbmhbmibjpbjpbjpaVAbmjbmkbmkbmlbbZbdDbmmbeZbmnbbZbmobmpbmqbmrbmsbmtbmtbmubmtbmtbmvbdPbmwbmxbfgbmybmzblfbmAbfmbmBbgGbgGbmCbmDbmEblqaSzbmFbmGbmGbmGbmGbmGbmGbmGbmHbmGbdYbebbmIbmJbmKbmLbmKbmMbmNbebbedbedbmObmPbmQbmRbiCbiGbmSaJibcKaRqaRpaJibmTbmUbmVbmWbmXbmYbmZbnabnbbncbndbnebncbnfbngbnhbnibnjbnkbnlbnmbnnbnobnpbnqbnrbnsbntbntbnubYfaVJblOblObZLblObZMbZMblObnzbnAbnBblObZtbZubZtblOblXblYbmbblObZnbZBbZnblObnGbnHbnIbnJbnKbnLbnMaaaaaaaaaaaaaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaaaaaaaaabhObhObhObhObhObhObhObhObhObhOaaabnNbnObnPbeQbnQbgrbnRbjpaZAbnTbnUbnVbjpbnWbnXbnYbnZbmlbbZbbZbbZbbZbbZbbZboabobbocbodboebdPbdPbdPbdPbdPbdPbdPbWqbdPbdPbdPbogbdPbohboibojbgGbgGbgGbokblpblqaSzbolbmGbombonbbEbcEbvGbotbosbotaafbebboubovbowboxboybozboAbebaafbedboBboCboDboEbiCbiGboFaJiboGboHaRpbXHboJboKboLboMboNbYwboPboQboRboRboSboTboUboUboVboWboXboYboZbpabpbbnnbpcbpdbpebpfbpgbphbpfbpibYfaVJbpjbpkbplbpmbpnbpobppbpqbprbpqbpsbptbpubcmblOaZzbpwbpxblObpybpzbpAbpBbpCbpDbnIbpEbpFbpGbnMaaaaaaaaaaacaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaTDaTDaTDaTDaTDaaaaTDaTDaTDaTDaTDaaaaTDaTDaTDaTDaTDaaaaaaaaaaaaaaabgnbgobgpbgqbdvbpHbpHbpHbpIbpHbpJaZVbpKbpLbgrbpMbpNbpObpPbpQbpRbpSaYSaXeaXeaXebpTbkWbpUbkWbkWbkWbkWbpVbpWbpWbpXbpYbdPbpZbqabqbbqcbqdbqebqfbqgbqhbqibqjbqkbmAbqlbojbgGbgGbqmbfmaMbblqbqnbqoaJubqqbqrbqrbxqborbopbxsbotaafbebbebbebbebceebebbebbebbebaafbedbqzboCbqAbqBbqCbqDbqEaJibqFaRqaRpaJibqGbqHbqIbqJaJDbqLboPbqNboUboUboUboUboUboUbqObqPbqQboYbqRbqSbqTbnnbqUbqVbqWbpfbpgbphbpfbqXbYfaVJbpjbqYbqZbqZbrabrbbrcbrdbrdbrdbrebrdbrfbrgbrhbribrjbrkbnIbrlbpCbrmbrnbrobcVbnIbrqbpFbrrbnMaaaaaaaaaaaaaaaaaaaaaaIuaIuaIuaIuaIuaIuaIuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIvaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaTDaTDaTDaTDaTDaaaaTDaTDaTDaTDaTDaaaaTDaTDaTDaTDaTDaaaaaaaaaaaaaaabgnbgobgpbgqbdvbpHbpHbpHbpIbpHbpJaZVbpKbpLbgrbpMbpNbpObpPbpQbpRbpSaYSaXeaXeaXebpTbkWbpUbkWbkWbkWbkWbpVbpWbpWbpXbpYbdPbpZbqabqbbqcbqdbqebqfbqgbqhbqibqjbqkbmAbqlbojbgGbgGbqmbfmaMbblqbqnbqoaJubqqbqrbqrbxqborbopbxsbotaafbebbebbebbebceebebbebbebbebaafbedbqzboCbqAbqBbqCbqDbqEaJibqFaRqaRpaJibqGbqHbqIbqJaJDbqLboPbqNboUboUboUboUboUboUbqObqPbqQboYbqRbqSbqTbnnbqUbqVbqWbpfbpgbphbpfbqXbYfaVJbpjbqYbqZbqZbrabrbbrcbrdbrdbrdbrebrdbrfbAXbrhbribrjbrkbnIbrlbpCbrmbrnbrobcVbnIbrqbpFbrrbnMaaaaaaaaaaaaaaaaaaaaaaIuaIuaIuaIuaIuaIuaIuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIvaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaTDaTDaTDaTDaTDaaaaTDaTDaTDaTDaTDaaaaTDaTDaTDaTDaTDaaaaaaaaaaaaaaaaaaaaaaaaaaabrsbrtbrubrvbrwbrxbrxbrybrzbrAbgrcedbrCbpPbrDbjpbjpbjpbajbrEbrFbrGbrHbrGbrGbrGbrHbrGbajbajbdPbdPbdPbrIbdPbrJbrJbrJbrJbrJbrJbqfbrKbrLbrMbrNbrObrPbrQbrRbrSbrTbrUbrVbrWbrXbrYbrZaHBbsbbqvbsabsebscbotbosbotaafbsibsjbskbslbsmbsnbskbsobsiaafbedbspbsqbspbedbedbedbsraJibssaRqaRpbXHboJboKbstbsubsvbqLbswbqNbsxbsybszbsAbsBbsCbqObsDbnibsEbsFbsGbsHbnnbsIbqVbpebpfbpgbphbpfbpibYfaVJbpjbsJbsKbsLbsMbplbsNbsObsPbsQbsRbsSbsTbsUbrhbsVbsWbsXbnIbsYbsZbtabtbbtcbtdbnIbrqbpFbtebnMaaaaaaaaaaaaaafaafaafaafbcZbcZbcZbcZaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaTDaTDaTDaTDaTDaaaaaaaaaaaaaaaaaaaaaaTDaTDaTDaTDaTDaaaaacaaaaaaaaaaaaaaaaaaaaabrsbtfbtgbthbtibtibtibtjbtibtibgrbtkbtlbtmbpPbjpaaaaaaaaaaafaafbtnbtnbtnbtnbtnbtnbtnaaaaaabtobtpbtqbtrbtsbrJbrJbrJbrJbrJbrJbttbtubtvbtwbtxbtybtzbtAbfmbfmbtBbfmbfmbtCbtDbtEbtFbmGbtHbmGbmGbmGbmGbmGbtIbmGaafbtJbtKbtLbtMbtNbtMbtLbtObtPaafbspbtQbtRbtSbtTbtUbspbtVaJlbtWbbmbtXaJibtYbmUbtZbuabubbucbudbuebufbugbuhbuibujbukbulbumbnibnnbunbuobupbnnbuqburbusbutbuubuubuvbuwbYfaXqbpjbuxbplbplbsMbuybuzbuAbuBbuCbuDbuEbuFbuGbrhbuHbuIbuJbnIbuKbuLbuMbtbbpCbuNbnIbpEbpFbuObnMaaaaaaaaaaaaaafbuPbuQbuRbuQbuRbuQbuSaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabuTbeObuUbuUbuVbpHbuWbgnbgobuXbuWbgrbuYbuZbvabvbbjpaaaaaaaaaaaaaaabtnbtnbtnbtnbtnbtnbtnaaaaaabvcbvdbrJbvebvfbvfbvfbvfbvfbvgbvhbvfbvibvjbvkbvlbvmbvnbvobfmbvpbgGbvqbvrbvsbvtbvubvvbmGbmGbmGbvxbvybvzbvAbvBbvwaafbnybvIbvHbvJbvKbvMbvNbvObnyaafbspbvPbvQbxnbedbvRbspbvSaJlbvTbcLbvUaJibvVbvWbvXbvYbvZbuccdTcdUbwcbwdbwebwebwfbwgcdWcdVbwjbwkbwlbwmbwkbwkbwkbwkbwnbwkbwkaXKaXKaXKaXKaVJbpjbsJbsKbsLbwobwpbwqbwrbwsbwsbwsbsSbwtbwubwvbwwbwxbwybnIbwzbwAbwBbwCbpCbwDbnIbwEbwFbnMbnMaaaaaaaaaaaaaafbwGbwHbwIbwJbwJbwKbwGaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabuTbeObuUbuUbuVbpHbuWbgnbgobuXbuWbgrbuYbuZbvabvbbjpaaaaaaaaaaaaaaabtnbtnbtnbtnbtnbtnbtnaaaaaabvcbvdbrJbvebvfbvfbvfbvfbvfbvgbvhbvfbvibvjbvkbvlbvmbvnbvobfmbvpbgGbvqbvrbvsbvtbvubvvbmGbmGbmGbvxbvybvzbvAbvBbvwaafbnybvIbvHbvJbvKbvMbvNbvObnyaafbspbvPbvQbxnbedbvRbspbvSaJlbvTbcLbvUaJibvVbvWbvXbvYbvZbuccdTcdUbwcbwdbwebwebwfbwgcdWcdVbwjbwkbwlbwmbwkbwkbwkbwkbwnbwkbwkaXKaXKaXKaXKaVJbpjbsJbsKbsLbwobwpbwqbwrbwsbwsbwsbsSbwtbAWbwvbwwbwxbwybnIbwzbwAbwBbwCbpCbwDbnIbwEbwFbnMbnMaaaaaaaaaaaaaafbwGbwHbwIbwJbwJbwKbwGaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabtnbtnbtnbtnbtnbtnbtnbwMbwNbwObwPbrJbwQbrJbwRbwRbwRbwSbwTbrKbrJbrJbrLbwUbwVbwWbwXbwYbwZbxabgGbgGbxbbxcbvtbvubxdbxebxfbUbbnCbxibxjbxkbxlbvwaafbxmbqtbskbxobxpbxobskbqxbxraafbspbqwbxtbnDbedbxvbspbtVaJlbxwbcLaRpaJibxxbxybxzbxAbxBbxCbxDbxEbxCbxFbxGbxHbxFbwkbxIbxJbwkbwkbxKbxLbxMbxNbxObxPbxQbxRbxSaXKbayaYXaXKaVJbpjbxXbqZbqZbxYbxZbppbyabwsbwsbwsbsSbwtbybbwwbnSbUabTQbwwbyfbygbyhbyibpCbyjbnIbrqbykbnMaaaaaaaaaaaaaaaaafbylbymbwIbwJbwIbynbuRaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabtnbtnbtnbtnbtnbtnbtnbyobypbyobyqbyrbwQbrJbrJbrJbysbrJbwTbrKbytbdPbdPbyubgGbrNbwXbyvbywbyxbyybyybyzbyAbyBbyCbyDbvsbyEboobyGbxkbyHbyIbyJbvwaafbxrbxrbyKbtLbyLbskbyMbxrbxraafbyNbyNbyNbyNbyNbyNbyNbyOaJibyPblMblNaJibyQbyRbyRbySbyTbxCbyUbyVbyWbyXbyYbyZbzabwmbzbbzcbzdbzebzfbzgbzgbzhbzibzgbzjbzkbckbaAboObclbdQbcnbzrbzsbztbzubzvbzwbppbzxbpqbpqbzybsSbwtbzzbzAbzBbzCbzDbzAbzEbzFbzGbzHbzIbwwbwwbzJbnMbnMbzKbzLbzLbzLbzMbzNbwGbwJbwIbwJbwJbzObwGaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLaaaaaaaaaaaaaaaaaaaacaaaaaaaaabtnbtnbtnbtnbtnbtnbtnbzPbzQbzPbzRbrJbwQbrJbzSbzSbzSbzSbwTbrKbzTbzUbdPbzVbgGbrNbwXbzWbzXbzYbgGblnbgGbzZbAabAbbAcbAdbyEbpvbAfbxkbxkbxkbAgbvwbAhbAhbAhbxrbAibxpbAibxrbAjbAjbAjbyNbAkbAlbAmbAnbAobApbAqaJibAraRqaRpaJibAsbAtbAubAvbAwbAxbAybAzbAAbABbACbADbAEbAFbAGbAHbAIbAJbAKbAIbqMbAMbANbAObnvblUbsdbnwbsgbsfbaAbPObpjbAWbAXbAYbAZbAZbppbBabBbbBcbppbBdbBebBfbBgbBhbBibBjbBkbBlbBlbBmbBnbBobTHbBqbBrbBsbBtbTIbBvbBwbBwbBxbBybBzbuQbuRbBAbuRbuQbBBaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLaaaaaaaaaaaaaaaaaaaacaaaaaaaaabtnbtnbtnbtnbtnbtnbtnbzPbzQbzPbzRbrJbwQbrJbzSbzSbzSbzSbwTbrKbzTbzUbdPbzVbgGbrNbwXbzWbzXbzYbgGblnbgGbzZbAabAbbAcbAdbyEbpvbAfbxkbxkbxkbAgbvwbAhbAhbAhbxrbAibxpbAibxrbAjbAjbAjbyNbAkbAlbAmbAnbAobApbAqaJibAraRqaRpaJibAsbAtbAubAvbAwbAxbAybAzbAAbABbACbADbAEbAFbAGbAHbAIbAJbAKbAIbqMbAMbANbAObnvblUbsdbnwbsgbsfbaAbPObpjbwubrgbAYbAZbAZbppbBabBbbBcbppbBdbBebBfbBgbBhbBibBjbBkbBlbBlbBmbBnbBobTHbBqbBrbBsbBtbTIbBvbBwbBwbBxbBybBzbuQbuRbBAbuRbuQbBBaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabtnbtnbtnbtnbtnbtnbtnbBCbwNbBDbBEbrJbwQbrJbrJbrJbrJbrJbwTbrKbzTbBFbdPbBGbgGbBHbBIbgGbBJbgFbgGbgGbBKbvsbvtbAbbAcbAdbyEbvwbBLbBMbBNbBMbBObvwbBPbBQbBRbAhbxrbBSbxrbAjbBTbBUbBVbyNbBWbBXbBYbBZbCabCabCbbCcbAraRqaRpaJibCdbCebCebySbCfbxCbCgbChbxCbCibCjbCjbCkbwkbClbCmbwkbwkbwkbwkbwkbwkbCnbwkbwkbwmbCoaXKaXKaXKaXKbSwbpjbwwbzAbzAbzAbzAbzAbzAbzAbzAbzAbzIbCrbCsbCtbBhbCubCvbCwbCxbCxbCxbCybCzbSubCBbCCbCDbCEbTGbCGbCHbCGbCIbCJbzKbzLbzMbCKbzNbCLaaaaafaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabtnbtnbtnbtnbtnbtnbtnbzPbzQbzPbCMbCNbCObrJbrJbrJbCNbrJbwTbrKbzTbCPbdPbCQbgGbrNbwXbgGbqlbCRbgGbgGbCSbxcbvtbAbbCTbxcbCUbvwbCVbrpbCXbCYbxlbvwbCZbDabDbbDcbDdbvFbvEbDgbDhbDibDjbyNbDkbDlbDlbDmbDnbDobDpaJibDqbDrbDsaJibDtbvDbDvbDwbDxbDybDzbDAbyWbDBbvLbCjbDDbwmbDEbDFbwmbDGbDHbDIbDJbDKbDLbDMbCpbDNbDObDPbDQbDRbCpbVLbVMbDUbVAbDWbDXbDXbDYbDZbEabEbbEcbEdbEebEfbEabEgbEhbCvbEibEjbEkbwwbwwbwwbwwbwwbxhbwbbEnbzKbzMbCJbEobEpbEqbErbEsbEtbEubEvaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabtnbtnbtnbtnbtnbtnbtnbEwbExbEwbEybEzbEAbEAbEAbEAbEAbEBbECbEDbzTbEEbdPbEFbEGbEHbEIbEJbtzbEKbELbEMbfmbtCbENbAbbEObEPbyEbvwbEQbERbESbBMbETbvwbEUbEVbEWbAhbEXbvCbEYbAjbFabFbbFcbyNbFdbFebFfbFgbDnbDobFhaJibxwaRqaRpbVjbFjbFkbFlbFmbFnbFobFpbFqbxCbxFbxFbFrbxFbwkbFsbFtbFubFvbFwbFxbDJbFybDLbFzbFAbFBbDObFCbFDbFEbFFbVlbDXbVybVAbFJbDXbDXbFKbFLbFMbFLbFLbFNbFObFPbFQbFRbFSbCvbFTbFUbFVbFWbFXbFYbFZbGabGbbGcbGdaafaafbCJbGebGfbGgbGhbGibGjbGkbCJaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -7412,7 +7441,7 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaaaaafaafaafcfQcfQcfQcfQcfQcfQcfQcfQcfQcfQcfQcfQcfQaaaaaacgScgTcgTcgTcgUcgVcejcfUcfRcgocgicgrcgpcgucgtcgCcgBcgWcgRcgYcgXchacgZchcchbbTPbTPbTPbTPbTPbTPbTPbTPbEZbGDcaqbDfcaqbTFcbIcbIctpctqctrcbIcbIchrchschtcfYcaEcaEcaEcaEcaEcaIchuchvcaIchwccnchwbZychychzbZychAchBbVichCbVichDbYfccobYfbYfccpcdCcdCcdCcdDbYfcdLchIchJchJchKchLchMchNchOchPchQchRchSchTchUchVchWcgIcgIcgIchYcmjcdSchZciachdcgNaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaafaafaafaaaaaaaaaaaaaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaaaaaaaaaaaacfQchechfchecfQchgchhchgcfQchichjchicfQaaaaaaciicgTcgTcgUcgUcijcejchlchkchnchmchpchochGchqcicchHchHcidchHcbBbYSciebYUcifcihcigcilcikcilcimciocincinciAciAciAciAbTFciGciHciIciIciJciKciLciMciXciOciPciQciRciSciSciTciUcaIcaIcaIciVcdEckqbZybZybZybZychBchBbViciYbViciZbYfccobYfaaaaaaaaaaaaaaaaaaaaacdLcjgcjhcjhcipcjjcjkcjlcjmcjncjocjpcjqcgIcgIcjrcjscgIcjtcgIchXcjucdScjvcjwcjxcgNaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaaaaaaaaaaaacfQcheciqchecfQchgcirchgcfQchicischicfQaaaaaaciicgTcgUcgUcgUcjBcjCciucitchncivcixciwciWciycjbcjacjdcjccjecbBbYScjichccjycjAcjzcjDcjDcjDcjEcjGcjFcjHceCcdeceAciAbTFciGckaciIckbckcckdcubckfckgckhctQckjckkcklciSckmciUcknckockpclicdFcdHcdGcdIcdIcdJcdIcdKbVibVibVibVibYfccobYfaaaaaaaaaaaaaaaaaaaaacdLckCckDckDckDckEcdOckFcdOckGckHckIckJckJckKckLckLckMckJckJckNckOcdSckPckQckRcgNaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaaaaaaaaaaaacfQcjIcjKcjJcfQcjLcjNcjMcfQcjOcjQcjPcfQaaaaafciiclbcgTcgUcgUcgUcejcjScjRchnchncjTchnchnchnchncjUchHcjXcjYcbBckecjZckrckickucksckzckzckzckAckBckBckTciAckWcgqclwclxciGclyciIclzclAclBclCclDclEclFclGclHclIclJciSclKciUclLclMclNclOclPclQclNclRclSclTbYfceQcdIcdIcdIcdIcdIckYbYfaaaaaaaaaaaaaaaaaaaaacdLcmacmbcmccmdcdOcmecmfcmgcdScmhcmicmicmicmmcmkcmlcIxcmicmicmicmncdScmocmpcmqcmraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaaaaaaaaaaaacfQcjIcjKcjJcfQcjLcjNcjMcfQcjOcjQcjPcfQaaaaafciiclbcgTcgUcgUcgUcejcjScjRchnchncjTchnchnchnchncjUchHcjXcjYcbBckecjZckrckickucksckzckzckzckAckBckBckTciAckWcgqclwclxciGclyciIclzclAclBclCclDclEclFclGclHclIclJciSclKciUclLclMclNclOclPclQclNclRclSclTbYfceQcdIcdIcdIcdIcdIckYbYfaaaaaaaaaaaaaaaaaaaaacdLcmacmbcmccmdcdOcmecmfcmgcdScmhcmicmicmicmmcmkcmlcBkcmicmicmicmncdScmocmpcmqcmraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaaaaaaaafaafcfQckZclcclacfQcldclcclecfQcldclcclecfQaaaaafcmzcgTcgTcgUcgUcmAcejclhclgclkcljclmcllclnclnclvcltclncmscmtcbBcmvcmucmxcmwcihcmycmycmBckBcmCcmEcmDcmDciAcibceVcmFcqgciGcnbciIcnccndcmGciGcnfciNcmHcfYcmIcnicnjciScnkciUclLclMclNcnlcnmcnlclNaaaaaaaaabYfbYfbYfcnnclSclSclTbYfbYfaaaaaaaaaaaacdOcdOcdOcdOcdOcdOcdOcdOcdOcnocnpcnqcdScdScnrcnscntcdScdScdScdScnucnscntcdScdScnvcnwcnvaafaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIvaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabZSaafaafaafaaaaafcnxaafcnxaafcKBaafcKAaafcKBaafcKAaafaafaaacejcnAcnBcgUcgUcnCcnDcmKcmJcmMcmLcmOcmNcmNcmPcmNcmQcmScmRcmQcmXcngcnecnycnhcnzcnzcnzcnzcnFcnEcnGcnGcnGcgscgscgscgscnSciGcnTcnUcnccnVcnWciGcnfciNcnXciUcnYcnZcnjcoacobciUclLclMclNcoccodcoeclNaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaacdOcofcogcohcwlcojcokcolcomconcoocopcoqcwkaaaaaaaafaafaaaaaaaaaaaaaaaaaaaaaaafcoscotcosaafaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaaaaaaaafcnHcnJcnIcnKcnIcnJcnLcnKcnMcnNcnLcnPcnOcnRcnQcmMcmMcmMcmMcmMcmMcmMcmMcovcoucoxcowcoAcoycoCcoBcoDcmQcoFcoEcoGcmQcoIcoHcoJcnzcoLcoKcoNcoMcoPcoOcoRcoQcoQcoScoTcoTcoRbTFciGciGcpccpdciGciGciGcpeciNcpfciUciUciUcpgcphciUciUclLcpiclNcvmcvncvmclNaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaafaafcdOcplcpmcplcvlcpocppcpqcomcomcprcomcdOcdOaaaaaaaaaaafaafaaaaacaaaaaaaaaaaaaafaaacvtaaaaafaafaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -7428,27 +7457,27 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaafaaaaaaaaacoUcptcqzcptcptcptcvIcptcptcptcvIcptcptcptcptcptcqIcptcxscptcyicvqcptcptcyjcwmcykcylcvvcymcvvcvvcxAcyocyncyqcxDcoIcwxcoIcnzcyscyrcyucytcyvcoPcnzczIczJczJczKczLczMczNczOcvNcxNczPczQcxNczRczSczTcvNczUczVcrGaaaaaaaaaaaaaaaaaacqvczWcuMczXcuVczYczZcAactFcAbcAccsPcyXczWcAdcAecqvaaaaaaaaaaaackEcdOcAfcAgcAgcywcAicAjcAkcAlcAmcAncAocApcAqcokcAraaaaaacrPaafcwjcwjcwjcwjcwjaaackxaafcwjcwjcwjcwjcwjaaacrPaaacyhaaaaaacyhaaaaaacyhcyhcyhcyhcyhcyhcyhaaaaaacyhaaaaaacyhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaaaaaaaaacyxcptcqzcptcyycrjcricrjcyzcrjcricrjcyzcrjcrjcrjcyAcyBcyAcrmcyCcykcyDcyFcyEcyHcyGcyIcvvcyKcyJcvvcvvcvvcvvcvvcyLcngczecngcnzcnzcnzcnzcnzcnzcnzcnzcALczJczJcAMcANcAObPxcAPcvNcAQcARczfcATcAUcAVcAWcvNcAXcAYcrGaaaaaaaaaaaaaaaaaacqvcuQcAZcAectFcBacBbcBcctFcBdcBecBfcBgcBhcBicBjcqvaafaafaaaaaaaaaaaabquaaacdOcBlcBmcBncBocBpcBmcBqcBrcBpcBmcBscdOaaaaaabZSaaaaafaaaaafaaaaafaaackxaaaaafaaaaafaafaafaafcrPaaacyhcyhcyhcyhaaacyhcyhcyhcyhcyhcyhcyhcyhcyhaaacyhcyhcyhcyhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIvaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabZSaaaaaaaaaaaaaamaaaaaaaaaczgcptcqzcptcxscxtcqzcptcxscxtcqzcptcxscxtcptcptcxrcptcxscxtczhczkczjczmczlczocznczpcvvczrczqcztczsczuctuczwczvctuczxctuczycuaczzczBczAczAczDczEcBVcBWcBWcBXcBYcAObPxcBZcvNcvNcCacCbcCccCbcCacCdcvNcrGcCecrGaaaaaaaaaaaaaaaaaacqvctFcCfcuVctFcCgcChcCictFcCjcCkcqycgvcCmcCncCocrHaaaaaaaaaaaaaaaaaacgwaafcdOcCqcluclUcomclsclpclqcomcloclVclWcdOaaaaaacrPaaactXctXctXctXctXaafckxaafctXctXctXctXctXaafcrPaaacyhcyhcyhcyhaaacyhcyhcyhcyhcyhcyhcyhcyhcyhaaacyhcyhcyhcyhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacrPaafaafaafaafaamaafaafaafczgczGczFcAhczHcAucAtcAwcAvcAycAxcAAcAzcAucptczGcABcADcACcAycAEcmMcmMcmMcmMcmMcmMcmMcmMcAHcAFcyLcAIcAJcoIcAKcoIcoIcwxcoIcoIcAScoIcAJcBtcBvcBucBxciCcCNcCOcCPcCQcAObPwcCRcCScCTcCacAGcAVcBwcCacCWaafcCXcCYcCXaaaaaaaaaaaaaaaaaacqvcCZctDcuQcDacDbcuQcDccDdcDeaafaaachxchFchEclXaaaaaaaaaaacaaaaaaaaaaaaaaacdOcDhcplcplcomcDicplcplcomcDicplcplcdOaafaafcrPaafckVckSckSckSckSckyckxckwckvckvckvckvckUaafcrPaaacyhcyhcyhcyhaaacyhcyhcyhcyhcyhcyhcyhcyhcyhaaacyhcyhcyhcyhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYctYctYctYctYctYctYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacrPcByaaaaaaaaaaamaaaaaaaaacBzcBBcBAcBDcBCcBFcBEcBGcBCcBFcBEcBGcBCcBFcBHcBHcBIcBGcBCcBFcBJcmMaaacBLcBKcBNcBMcBPcBOcBRcBQcBScBScBUcBTcCrcCpcCtcCscCpcCtcCrcCucCwcCvcCucyLcyLcAOcDNcDOcDPcDQcAObNUcDRcDScDTcCacCbcDUcCbcCacCWaafaaaaafaaaaaaaaaaaaaaaaaaaaacqvcCZcDVcDWcDXcDXcDWcsPcDYcqvaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacdOcDZcplcplcomcEacplcplcomcEacplcplcdOaaaaaacrPaafcwjcwjcwjcwjcwjaaackxaaacwjcwjcwjcwjcwjaaacrPaaacyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYctYctYctYctYctYctYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacrPcClcqLcqLcqLcpEcpIcpIcpIcqLcpIcpPcpIcpGcpIcpPcpIcpGcpIcpPcpIcpGcpIcqLcpIcpRcpIcpGcpIcqNaafaaacCycCxcCAcCzcCCcCBcBRcCDcBScCEcCGcCFcCIcCHcCKcCJcCMcCLcCIcCUcDgcCVcCuaaaaafcAOcEBcECcEDaafaaabNUbPxbPxbSkcCaclZcEFclYcCacCWaafaafaaaaaaaaaaaaaaaaaaaaaaaacqvcEHcuXcEIcEJcEJcEIcuQcEKcqvaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacdOcplcplcplcomcELcplcplcomcELcplcplcdOaacaaacrPaaaaaaaafaafaafaaaaaacmTaafaaaaaaaafaafaaaaaacrPaaacyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYctYctYctYctYctYctYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacrPaafaafaaaaaaaaqaaaaaaaaaaafcfQcldclccDjcfQcldclccDjcfQcldclccDkcfQaaacfQcDlclccDkcfQaaaaafaaacCycEdcDocDncDmcDpcDrcDqcBScDscDucDtcCIcDvcDxcDwcDzcDycCIcDAcDCcDBcCuaaaaaacAOcFgcFhcFiaaaaaabNUbPxbPxbNUcCacmUcmUcmUcCacFkcmWaaaaaaaaaaaaaaaaaaaaaaaaaaacqvcFmcFncuQcuQcuQcuQcuQcFocqvaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaackEcdOcdOcdOcdOcdOcdOcdOcdOcmYcmYcmYckEaaaaaacrPcrPcrPcrPcrPaaaaaaaaacmZaaaaaaaaacrPcrPcrPbZScrPaaacyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYctYctYctYctYctYctYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacrPaaaaafaafaaaaamaaaaaaaaaaafcfQcDDcDFcDEcfQcDGcDIcDHcfQcDJcDLcDKcfQaafcfQcDMcEccEbcfQaaaaafaaacCycEGcCAcDmcDmcEecEgcEfcEicEhcEkcEjcEmcElcEocEncEqcEpcEscErcEucEtcCuaafaaacFJcDNcFKcAOcFLaaabNUcFMbPxcFNcFOaafaafaafaaacBkaafaafaaaaaaaaaaaaaaaaaaaaaaaacrHcqvcqvcFPcFQcEIcEIcEIcFRcFPaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqpbqpbqpaaaaaaaaaaaaaaaaaaaaaaaaaaacrPaafcfTaafcrPaaaaaaaaaaaaaaaaaaaaacyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYctYctYctYctYctYctYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaamaaaaaaaafaafcfQcEvcEwcEvcfQcExcEycExcfQcEzcEAcEzcfQaaacfQcEzcEzcEEcfQaaaaafaaacCycBKcIycDncDmcCBcEMcCDcBScENcEPcEOcCIcEQcEScERcEScETcCIcEUcEWcEVcCuaaLcGgcGgcGgcGgcGgcGgcGgbNUciEciDcGjaafaaaaaaaafcGkcDfaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacGlcEJcEJcEJcEJcEJcGlaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacrPaaaaafaaacrPaaaaaaaaaaaaaaaaaacyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYctYctYctYctYctYctYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaafaamaaaaafaafaaacfQcEvcEXcEvcfQcExcEYcExcfQcEzcEZcEzcfQaafcfQcEzcEzcEzcfQaafaafaafcFbcFacFdcFccFfcFecFjcCDcBScFlcFqcFpcCIcFrcFtcFscFvcFucCIcFwcFycFxcCuaaacGgcGgcGgcGgcGgcGgcGgcGFcGGcGHbNUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacqvcCmcqxcqxcqxcCocqvaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacrPcrPcrPcrPcrPaaaaaaaaaaaaaaaaaacyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYctYctYctYctYctYctYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafbZSaaaaaacfQcfQcfQcfQcfQcfQcfQcfQcfQcfQcfQcfQcfQaaacFzcfQcfQcfQcfQaaaaaaaaaaaacAFcAFcAFcAFcAFcFBcFAcFAcFAcFAcFCcFAcFDcFFcFEcFFcFGcFAcFAcFHcFAcFAcFAcGgcGgcGgcGgcGgcGgcGgaafaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacyhcyhcyhcyhaaaaaacyhcyhcyhcyhcyhcyhcyhaaaaaacyhcyhcyhcyhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYctYctYctYctYctYctYctYctYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafcrPaaaaaaaafaafaaaaafaafaaaaaaaafaafaafaaaaaaaaaaaaaaaaaaaafaaacGQcGRcGRcGRcGScFIcFTcFScFVcFUcFXcFWcFZcFYcGbcGacGdcGccGfcGecGicGhcGncGmcGmcGocGpcFAcGgcGgcGgcGgcGgcGgcGgaafaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacyhcyhcyhcyhcyhcyhcyhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYctYctYctYctYctYctYctYctYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaafcHncjVcHpaaacHncjVcHpaaacHncjVcHpaafaafaaaaafaafaafaafaafcHqcGRcGRcGRcGScFIcGrcGqcGtcGscGvcGucGxcGwcGzcGycGBcGAcGmcGCcGmcGmcGmcGmcGmcGmcGDcFAcGgcGgcGgcGgcGgcGgcGgaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaacyhcyhcyhcyhcyhcyhcyhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYctYctYctYctYctYctYctYctYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaaacHncjWcHpaaacHncjWcHpaaacHncjWcHpaafaafaaaaafaaaaaacHKaafcGQcGRcGRcGRcGScFIcGrcGEcGJcGIcGKcGucGMcGLcGOcGNcGmcGmcGTcGPcGUcGmcGmcGmcGmcGmcGVcFAcIbaafaaIaafaafaafaafaafaafaafaafaafcGWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacyhcyhcyhcyhcyhcyhcyhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYctYctYctYctYctYctYctYctYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIaafcHncjWcHpaaacHncjWcHpaafcHncjWcHpaafaaaaaaaafaafcIcaaaaafcHqcGRcGRcGRcGScFIcGYcGXcHacGZcHccHbcHecHdcHgcHfcHhcHhcHjcHicHlcHkcHkcHkcHkcHkcHocHmcHscHrcHrcHrcHrcHrcHrcHrcHrcHrcHtaaacGWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacyhcyhcyhcyhcyhcyhcyhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYctYctYctYctYctYctYctYctYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaacHncjWcHpaafcHncjWcHpaaacHncjWcHpaaaaaaaaaaaaaafaafaaaaafaaaaaaaaaaaaaafcHucHwcHvcHycHxcHzcFWcGAcGmcHBcHAcHDcHCcHFcHEcHHcHGcHDcHIcHJcGmcHMcHLcHscHtcHNcHtcHNcHtcHNcHtcHNcHtcHOaafcGWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacyhcyhcyhcyhcyhcyhcyhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYctYctYctYctYctYctYctYctYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaamaaIaafaaacHncjWcHpaafcHncjWcHpaaacHncjWcHpaafaaaaaaaaaaaaaafaafcIJcIKcIKcIKcIKcILcILcILcILcILcIMcILcFAcGmcGmcHPcFAcFAcFAcHRcHQcHScFAcFAcFAcHTcGmcHUcFAaaacHOcHOcHOcHOcHOcHOcHOcHOcHOcHOaafcGWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacyhcyhcyhcyhcyhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYctYctYctYctYctYctYctYctYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaaaaafaaaaafaafczCaafaafaafczCaafaaaaafczCaafaaaaaaaaaaaaaaacIUcIVcIWcIXcIYcHVcJacJbcJcciFcJecJfcJgcJecFAcHWcGmcHYcHXcIacHZcIecIdcIfcHZcIgcHXcIhcGmcIicFAaaacHOcHOcHOcHOcHOcHOcHOcHOcHOcHOaaaaanaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYctYctYctYctYctYctYctYctYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIaafcydcxzcxycxxcxxcxxcxxcxxcxxcxxcxxcxxcxxcxxczicxzcxzcxzcypcJzcJAcJBcJCcJDcJEcJFcJGcJHcJHcJHcJIcJJcJKcFAcGmcGmcHYcHXcIacIjcIlcIkcImcIjcIgcHXcIhcGmcGmcFAaaacHOcHOcHOcHOcHOcHOcHOcHOcHOcHOaafcGWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYaaactYctYctYctYctYaaactYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaaaaafaaaaafaafcxfaafaaaaafcxfaafaaaaafcxfaafaaaaaaaaaaaaaaacIUcIVcJRcJScJTcJUcIKcJVcJWcJecJecJXcJXcJYcFAcIncGmcIocHXcIacIpcIlcIqcIrcIpcIgcHXcIscGmcGmcFAaaacHOcHOcHOcHOcHOcHOcHOcHOcHOcHOaafaamaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYaaactYctYctYctYctYaaactYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaamaaIaafaafcHncwrcHpaaacHncwrcHpaaacHncwrcHpaafaaaaaaaaaaaaaafaafcKfcIKcIKcIKcIKcKgcKhcKicKicKjcKgcKgcFAcFAcFWcFAcFAcFAcFAcFAcItcFAcFAcFAcFAcFAcFWcFAcFAaafcIucIvcIucIvcIucIvcIucIvcIucIvaaaaamaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacHncwrcHpaafcHncwrcHpaaacHncwrcHpaaaaaaaaaaafaaaaafaafaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaafaafaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaafaaaaafaafaaaaaaaafaafaaaaaaaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKlcKlcKlcKlcKlcKlcKlaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIaafcHncwrcHpaaacHncwrcHpaaacHncwrcHpaafaaaaaaaaaaaaaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaafaaaaaaaaLaaaaafaaaaaacGWcGWcGWcIwcGWcGWaancGWcGWaamaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKlcKlcKlcKlcKlcKlcKlcKlcKlaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIaafcHncwrcHpaaacHncwrcHpaafcHncwrcHpaafaafaafaaaaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIaaIaaIbZSbZSaaIaaIaaaaaaaaaaaIaaIaaIaaIaaIaaIaaIaaIaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKlcKlcKlcKlcKlcKlcKlcKlcKlaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacrPaafaafaafaafaamaafaafaafczgczGczFcAhczHcAucAtcAwcAvcAycAxcAAcAzcAucptczGcABcADcACcAycAEcmMcmMcmMcmMcmMcmMcmMcmMcAHcAFcyLcAIcAJcoIcAKcoIcoIcwxcoIcoIcAScoIcAJcBtcBvcBucBxciCcCNcCOcCPcCQcAObPwcCRcCScCTcCacAGcAVcBwcCacERcCWcFkcCYcCXaaaaaaaaaaaaaaaaaacqvcCZctDcuQcDacDbcuQcDccDdcDeaafaaachxchFchEclXaaaaaaaaaaacaaaaaaaaaaaaaaacdOcDhcplcplcomcDicplcplcomcDicplcplcdOaafaafcrPaafckVckSckSckSckSckyckxckwckvckvckvckvckUaafcrPaaacyhcyhcyhcyhaaacyhcyhcyhcyhcyhcyhcyhcyhcyhaaacyhcyhcyhcyhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYctYctYctYctYctYctYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacrPcByaaaaaaaaaaamaaaaaaaaacBzcBBcBAcBDcBCcBFcBEcBGcBCcBFcBEcBGcBCcBFcBHcBHcBIcBGcBCcBFcBJcmMaaacBLcBKcBNcBMcBPcBOcBRcBQcBScBScBUcBTcCrcCpcCtcCscCpcCtcCrcCucCwcCvcCucyLcyLcAOcDNcDOcDPcDQcAObNUcDRcDScDTcCacCbcDUcCbcCacGbcmWcDfaafaaaaaaaaaaaaaaaaaaaaacqvcCZcDVcDWcDXcDXcDWcsPcDYcqvaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacdOcDZcplcplcomcEacplcplcomcEacplcplcdOaaaaaacrPaafcwjcwjcwjcwjcwjaaackxaaacwjcwjcwjcwjcwjaaacrPaaacyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYctYctYctYctYctYctYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacrPcClcqLcqLcqLcpEcpIcpIcpIcqLcpIcpPcpIcpGcpIcpPcpIcpGcpIcpPcpIcpGcpIcqLcpIcpRcpIcpGcpIcqNaafaaacCycCxcCAcCzcCCcCBcBRcCDcBScCEcCGcCFcCIcCHcCKcCJcCMcCLcCIcCUcDgcCVcCuaaaaafcAOcEBcECcEDaafaaabNUbPxbPxbSkcCaclZcEFclYcCaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacqvcEHcuXcEIcEJcEJcEIcuQcEKcqvaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacdOcplcplcplcomcELcplcplcomcELcplcplcdOaacaaacrPaaaaaaaafaafaafaaaaaacmTaafaaaaaaaafaafaaaaaacrPaaacyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYctYctYctYctYctYctYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacrPaafaafaaaaaaaaqaaaaaaaaaaafcfQcldclccDjcfQcldclccDjcfQcldclccDkcfQaaacfQcDlclccDkcfQaaaaafaaacCycEdcDocDncDmcDpcDrcDqcBScDscDucDtcCIcDvcDxcDwcDzcDycCIcDAcDCcDBcCuaaaaaacAOcFgcFhcFiaaaaaabNUbPxbPxbNUcCacmUcmUcmUcCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacqvcFmcFncuQcuQcuQcuQcuQcFocqvaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaackEcdOcdOcdOcdOcdOcdOcdOcdOcmYcmYcmYckEaaaaaacrPcrPcrPcrPcrPaaaaaaaaacmZaaaaaaaaacrPcrPcrPbZScrPaaacyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYctYctYctYctYctYctYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacrPaaaaafaafaaaaamaaaaaaaaaaafcfQcDDcDFcDEcfQcDGcDIcDHcfQcDJcDLcDKcfQaafcfQcDMcEccEbcfQaaaaafaaacCycEGcCAcDmcDmcEecEgcEfcEicEhcEkcEjcEmcElcEocEncEqcEpcEscErcEucEtcCuaafaaacFJcDNcFKcAOcFLaaabNUcFMbPxcFNcFOaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacrHcqvcqvcFPcFQcEIcEIcEIcFRcFPaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqpbqpbqpaaaaaaaaaaaaaaaaaaaaaaaaaaacrPaafcfTaafcrPaaaaaaaaaaaaaaaaaaaaacyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYctYctYctYctYctYctYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaamaaaaaaaafaafcfQcEvcEwcEvcfQcExcEycExcfQcEzcEAcEzcfQaaacfQcEzcEzcEEcfQaaaaafaaacCycBKcIxcDncDmcCBcEMcCDcBScENcEPcEOcCIcEQcEScGdcEScETcCIcEUcEWcEVcCuaaLcGgcGgcGgcGgcGgcGgcGgbNUciEciDcGjaafaaaaaaaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacGlcEJcEJcEJcEJcEJcGlaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacrPaaaaafaaacrPaaaaaaaaaaaaaaaaaacyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYctYctYctYctYctYctYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaafaamaaaaafaafaaacfQcEvcEXcEvcfQcExcEYcExcfQcEzcEZcEzcfQaafcfQcEzcEzcEzcfQaafaafaafcFbcFacFdcFccFfcFecFjcCDcBScFlcFqcFpcCIcFrcFtcFscFvcFucCIcFwcFycFxcCuaaacGgcGgcGgcGgcGgcGgcGgcGFcGGcGHbNUaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacqvcCmcqxcqxcqxcCocqvaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacrPcrPcrPcrPcrPaaaaaaaaaaaaaaaaaacyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYctYctYctYctYctYctYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafbZSaaaaaacfQcfQcfQcfQcfQcfQcfQcfQcfQcfQcfQcfQcfQaaacFzcfQcfQcfQcfQaaaaaaaaaaaacAFcAFcAFcAFcAFcFBcFAcFAcFAcFAcFCcFAcFDcFFcFEcFFcFGcFAcFAcFHcFAcFAcFAcGgcGgcGgcGgcGgcGgcGgaafaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacyhcyhcyhcyhaaaaaacyhcyhcyhcyhcyhcyhcyhaaaaaacyhcyhcyhcyhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYctYctYctYctYctYctYctYctYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafcrPaaaaaaaafaafaaaaafaafaaaaaaaafaafaafaaaaaaaaaaaaaaaaaaaafaaacGQcGRcGRcGRcGScFIcFTcFScFVcFUcFXcFWcFZcFYcGkcGacGycGccGfcGecGicGhcGncGpcGmcGocGpcFAcGgcGgcGgcGgcGgcGgcGgaafaaacGQcGzcGQcGzcGQcGzaafcGWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacyhcyhcyhcyhcyhcyhcyhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYctYctYctYctYctYctYctYctYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaafcHncjVcHpaaacHncjVcHpaaacHncjVcHpaafaafaaaaafaafaafaafaafcHqcGRcGRcGRcGScFIcGrcGqcGtcGscGvcGucGxcGwcGCcGBcGOcGLcGTcGPcGTcGTcGTcGUcGTcHfcGDcFAcGgcGgcGgcGgcGgcGgcGgaafaafcHOcHOcHOcHOcHOcHOaafcGWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaacyhcyhcyhcyhcyhcyhcyhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYctYctYctYctYctYctYctYctYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaaacHncjWcHpaaacHncjWcHpaaacHncjWcHpaafaafaaaaafaaaaaacHKaafcGQcGRcGRcGRcGScFIcGrcGEcGJcGIcGKcGucGMcHjcHlcGmcGmcGmcHocHmcHAcGmcGmcHjcHCcHBcHDcFAcFAcFAcHEaaaaaaaaaaaaaafaaacHFcHFcHFcHFcHFcHFaafcGWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacyhcyhcyhcyhcyhcyhcyhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYctYctYctYctYctYctYctYctYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIaafcHncjWcHpaaacHncjWcHpaafcHncjWcHpaafaaaaaaaafaafcIcaaaaafcHqcGRcGRcGRcGScFIcGYcGXcHacGZcHccHbcHecHdcHGcHkcHkcHkcHHcHicHIcHkcHkcHJcHLcGNcHQcHPcHUcHTcHscHrcHrcHrcHrcHrcHrcIvcIucIvcIucIvcHOaafcGWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacyhcyhcyhcyhcyhcyhcyhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYctYctYctYctYctYctYctYctYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaacHncjWcHpaafcHncjWcHpaaacHncjWcHpaaaaaaaaaaaaaafaafaaaaafaaaaaaaaaaaaaafcHucHwcHvcHycHxcHzcFWcGAcGmcGmcGmcHYcHXcIacHZcIecIbcIfcGVcIhcIgcIjcIicIocIncHscHtcHNcHtcHNcHtcHNcHtcHNcHtcHNcHtcHOaafcGWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacyhcyhcyhcyhcyhcyhcyhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYctYctYctYctYctYctYctYctYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaamaaIaafaaacHncjWcHpaafcHncjWcHpaaacHncjWcHpaafaaaaaaaaaaaaaafaafcIJcIKcIKcIKcIKcILcILcILcILcILcIMcILcFAcHWcGmcGmcGmcIpcFAcHScIscHRcFAcIwcItcIycGNcIAcIzcIBcFAaaacHFcHFcHFcHFcICcHFcHFcHFcHFcHFcHFcHFaafcGWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacyhcyhcyhcyhcyhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYctYctYctYctYctYctYctYctYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaaaaafaaaaafaafczCaafaafaafczCaafaaaaafczCaafaaaaaaaaaaaaaaacIUcIVcIWcIXcIYcHVcJacJbcJcciFcJecJfcJgcJecFAcIEcIDcGmcGmcIGcIFcIHcIdcIIcIFcINcHMcHLcGNcIPcIOcIQcFAaafcHOcHOcHOcHOcHOcHOcHOcHOcHOcHOcHOcHOaafaanaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYctYctYctYctYctYctYctYctYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIaafcydcxzcxycxxcxxcxxcxxcxxcxxcxxcxxcxxcxxcxxczicxzcxzcxzcypcJzcJAcJBcJCcJDcJEcJFcJGcJHcJHcJHcJIcJJcJKcFAcIRcIRcGmcGmcIGcIScIlcIkcImcIScINcGmcIhcITcIjcGmcIZcFAaafcHOcHOcHOcHOcHOcHOcHOcHOcHOcHOcHOcHOaafcGWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYaaactYctYctYctYctYaaactYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaaaaafaaaaafaafcxfaafaaaaafcxfaafaaaaafcxfaafaaaaaaaaaaaaaaacIUcIVcJRcJScJTcJUcIKcJVcJWcJecJecJXcJXcJYcFAcIRcIRcGmcGmcIGcJdcIlcIqcIrcJdcJhcHhcHgcJicJkcJjcJlcFAaaacHFcHFcHFcHFcICcHFcHFcHFcHFcHFcHFcHFaafaamaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYaaactYctYctYctYctYaaactYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaamaaIaafaafcHncwrcHpaaacHncwrcHpaaacHncwrcHpaafaaaaaaaaaaaaaafaafcKfcIKcIKcIKcIKcKgcKhcKicKicKjcKgcKgcFAcFAcFWcFAcFAcFAcFAcFAcJmcFAcFAcFAcFAcFAcFWcFAcFAcFAcFAaafcHOcHOcHOcHOcHOcHOcHOcHOcHOcHOcHOcHOaafaamaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacHncwrcHpaafcHncwrcHpaaacHncwrcHpaaaaaaaaaaafaaaaafaafaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaafaafaaaaaaaaaaaaaaaaafaaacJnaaaaaaaaaaafaaaaaaaaaaaaaaaaafaaaaaacHqcJocHqcJocJpcJocHqcJocHqcJocHqcJoaafaamaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKlcKlcKlcKlcKlcKlcKlaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIaafcHncwrcHpaaacHncwrcHpaaacHncwrcHpaafaaaaaaaaaaaaaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaafaaaaaLaaaaaaaaaaafaafaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKlcKlcKlcKlcKlcKlcKlcKlcKlaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIaafcHncwrcHpaaacHncwrcHpaafcHncwrcHpaafaafaafaaaaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIaaIaaIbZSbZSaaIaaIaaaaaaaaaaaIaaIaaIaaIaaIaaqaaIaaIaaIaaIaaIaaIaaIaaIcJqaaIaaIaaIaaIaaqaaIaaIaaIaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKlcKlcKlcKlcKlcKlcKlcKlcKlaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqaafcHncwncHpaaacHncwncHpaaacHncwncHpaafaaIaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKlcKlcKlcKlcKlcKlcKlcKlcKlaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIaaaaafaaaaaaaaaaafaafaafaaaaaaaafaafaaaaaIaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKncKncKncKncKncKncKnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKlcKlcKlcKlcKlcKlcKlcKlcKlaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaamaaIaamaamaaqaaIaaIaaIaaIaamaaIaaIaamcKoaafaaaaaaaaaaaaaaacKpaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaacHKaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKncKncKncKncKncKncKncKncKnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKlcKlcKlcKlcKlcKlcKlcKlcKlaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa diff --git a/maps/exodus-2.dmm b/maps/exodus-2.dmm index d29a4123b8..4a123b9186 100644 --- a/maps/exodus-2.dmm +++ b/maps/exodus-2.dmm @@ -705,7 +705,7 @@ "nC" = (/obj/structure/closet/secure_closet/freezer/kitchen{req_access = null; req_access_txt = "150"},/turf/unsimulated/floor{icon_state = "white"},/area/syndicate_mothership) "nD" = (/obj/structure/table/reinforced,/obj/item/weapon/tray{pixel_y = 5},/turf/unsimulated/floor{icon_state = "white"},/area/syndicate_mothership) "nE" = (/obj/structure/table/reinforced,/obj/item/weapon/reagent_containers/food/drinks/bottle/vodka{pixel_x = 3; pixel_y = 12},/obj/item/weapon/reagent_containers/food/drinks/bottle/wine{pixel_x = -1; pixel_y = 8},/turf/unsimulated/floor{icon_state = "white"},/area/syndicate_mothership) -"nF" = (/obj/structure/table/rack,/obj/item/weapon/storage/belt/security,/obj/item/weapon/storage/belt/security,/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) +"nF" = (/obj/structure/table/rack,/obj/item/weapon/storage/belt/security,/obj/item/weapon/storage/belt/security,/obj/item/ammo_magazine/mc9mm/flash,/obj/item/weapon/gun/projectile/pistol/flash,/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) "nG" = (/obj/structure/table/rack,/obj/item/clothing/shoes/magboots,/obj/item/clothing/suit/space/syndicate/black/red,/obj/item/clothing/mask/breath,/obj/item/clothing/head/helmet/space/syndicate/black/red,/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership) "nH" = (/turf/simulated/shuttle/wall{icon_state = "wall3"},/area/syndicate_station/start) "nI" = (/obj/structure/table,/obj/machinery/recharger,/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) @@ -1046,7 +1046,7 @@ "uf" = (/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/control) "ug" = (/turf/unsimulated/wall,/area/centcom/test) "uh" = (/turf/unsimulated/floor{icon_state = "vault"; dir = 8},/area/centcom/specops) -"ui" = (/obj/structure/table/rack,/obj/item/weapon/gun/grenadelauncher,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom) +"ui" = (/obj/structure/table/rack,/obj/item/weapon/gun/launcher/grenade,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom) "uj" = (/obj/structure/table/rack,/obj/item/clothing/shoes/magboots,/obj/item/clothing/shoes/magboots,/obj/item/clothing/shoes/magboots,/obj/item/clothing/shoes/magboots,/obj/item/clothing/accessory/storage/black_vest,/obj/item/clothing/accessory/storage/black_vest,/obj/item/clothing/accessory/storage/black_vest,/obj/item/clothing/accessory/storage/black_vest,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom) "uk" = (/obj/structure/table/rack,/obj/item/clothing/suit/armor/vest/ert/security,/obj/item/clothing/suit/armor/vest/ert/security,/obj/item/clothing/suit/armor/vest/ert/security,/obj/item/clothing/suit/armor/vest/ert/security,/obj/item/clothing/head/helmet/ert/security,/obj/item/clothing/head/helmet/ert/security,/obj/item/clothing/head/helmet/ert/security,/obj/item/clothing/head/helmet/ert/security,/obj/item/weapon/storage/backpack/ert/security,/obj/item/weapon/storage/backpack/ert/security,/obj/item/weapon/storage/backpack/ert/security,/obj/item/weapon/storage/backpack/ert/security,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) "ul" = (/obj/structure/table/rack,/obj/item/weapon/rig/ert/security,/obj/item/clothing/accessory/storage/black_vest,/obj/item/weapon/rig/ert/security,/obj/item/clothing/accessory/storage/black_vest,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom) @@ -1093,7 +1093,7 @@ "va" = (/turf/unsimulated/floor{icon_state = "loadingarea"; dir = 8},/area/centcom/specops) "vb" = (/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) "vc" = (/obj/structure/table/reinforced,/obj/item/mecha_parts/mecha_equipment/weapon/energy/ion,/obj/item/mecha_parts/mecha_equipment/weapon/energy/taser,/obj/item/mecha_parts/mecha_equipment/anticcw_armor_booster,/obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) -"vd" = (/obj/structure/table/rack,/obj/item/weapon/rig/ert/engineer,/obj/item/clothing/accessory/storage/brown_vest,/obj/item/weapon/rig/ert/engineer,/obj/item/clothing/accessory/storage/brown_vest,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom) +"vd" = (/obj/structure/table/rack,/obj/item/clothing/head/beret/centcom/officer,/obj/item/clothing/head/beret/centcom/officer,/obj/item/clothing/head/beret/centcom/officer,/obj/item/clothing/head/beret/centcom/officer,/obj/item/clothing/head/beret/centcom/officer,/obj/item/clothing/head/beret/centcom/officer,/obj/item/clothing/mask/balaclava,/obj/item/clothing/mask/balaclava,/obj/item/clothing/mask/balaclava,/obj/item/clothing/mask/balaclava,/obj/item/clothing/mask/balaclava,/obj/item/clothing/mask/balaclava,/obj/item/clothing/accessory/holster/waist,/obj/item/clothing/accessory/holster/waist,/obj/item/clothing/accessory/holster/waist,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) "ve" = (/obj/structure/table/rack,/obj/item/clothing/suit/armor/vest/ert/engineer,/obj/item/clothing/suit/armor/vest/ert/engineer,/obj/item/clothing/suit/armor/vest/ert/engineer,/obj/item/clothing/suit/armor/vest/ert/engineer,/obj/item/clothing/head/helmet/ert/engineer,/obj/item/clothing/head/helmet/ert/engineer,/obj/item/clothing/head/helmet/ert/engineer,/obj/item/clothing/head/helmet/ert/engineer,/obj/item/weapon/storage/backpack/ert/engineer,/obj/item/weapon/storage/backpack/ert/engineer,/obj/item/weapon/storage/backpack/ert/engineer,/obj/item/weapon/storage/backpack/ert/engineer,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom) "vf" = (/obj/structure/table/reinforced,/obj/item/device/multitool,/obj/item/device/multitool,/obj/item/device/flash,/obj/item/device/flash,/obj/item/weapon/rcd,/obj/item/weapon/rcd,/obj/item/weapon/rcd_ammo,/obj/item/weapon/rcd_ammo,/obj/item/weapon/rcd_ammo,/obj/item/weapon/rcd_ammo,/obj/item/weapon/rcd,/obj/item/weapon/rcd,/obj/item/weapon/rcd_ammo,/obj/item/weapon/rcd_ammo,/obj/item/weapon/rcd_ammo,/obj/item/weapon/rcd_ammo,/obj/item/weapon/rcd_ammo,/obj/item/weapon/rcd_ammo,/obj/item/weapon/rcd_ammo,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom) "vg" = (/obj/machinery/pipedispenser/orderable,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom) @@ -1126,10 +1126,10 @@ "vH" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 1},/obj/machinery/camera{c_tag = "Court"; invisibility = 1; network = list("thunder"); pixel_x = 10},/turf/unsimulated/floor{icon_state = "carpet"; dir = 2},/area/centcom/control) "vI" = (/obj/mecha/medical/odysseus/loaded,/turf/unsimulated/floor{icon_state = "delivery"; dir = 6},/area/centcom/specops) "vJ" = (/obj/structure/table/reinforced,/obj/item/mecha_parts/mecha_equipment/tool/sleeper,/obj/item/mecha_parts/mecha_equipment/tool/sleeper,/obj/item/mecha_parts/mecha_equipment/tool/syringe_gun,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) -"vK" = (/obj/structure/table/rack,/obj/item/clothing/shoes/magboots,/obj/item/clothing/shoes/magboots,/obj/item/clothing/shoes/magboots,/obj/item/clothing/shoes/magboots,/obj/item/clothing/accessory/storage/brown_vest,/obj/item/clothing/accessory/storage/brown_vest,/obj/item/clothing/accessory/storage/brown_vest,/obj/item/clothing/accessory/storage/brown_vest,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom) +"vK" = (/obj/structure/table/rack,/obj/item/weapon/rig/ert/engineer,/obj/item/clothing/accessory/storage/brown_vest,/obj/item/weapon/rig/ert/engineer,/obj/item/clothing/accessory/storage/brown_vest,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom) "vL" = (/obj/structure/sign/poster{poster_type = "/datum/poster/bay_50"; pixel_x = -32},/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) "vM" = (/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom) -"vN" = (/obj/structure/table/rack,/obj/item/clothing/shoes/magboots,/obj/item/clothing/accessory/storage/black_vest,/obj/item/weapon/rig/ert,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom) +"vN" = (/obj/structure/table/rack,/obj/item/clothing/shoes/magboots,/obj/item/clothing/shoes/magboots,/obj/item/clothing/shoes/magboots,/obj/item/clothing/shoes/magboots,/obj/item/clothing/accessory/storage/brown_vest,/obj/item/clothing/accessory/storage/brown_vest,/obj/item/clothing/accessory/storage/brown_vest,/obj/item/clothing/accessory/storage/brown_vest,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom) "vO" = (/obj/machinery/vending/tool,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom) "vP" = (/obj/structure/table/rack,/obj/item/clothing/suit/armor/vest/ert/command,/obj/item/clothing/head/helmet/ert/command,/obj/item/weapon/storage/backpack/ert/commander,/turf/unsimulated/floor{icon_state = "vault"; dir = 8},/area/centcom/specops) "vQ" = (/obj/machinery/portable_atmospherics/canister/oxygen,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom) @@ -1152,7 +1152,7 @@ "wh" = (/obj/machinery/door/blast/regular{icon_state = "pdoor1"; id = "ASSAULT1"; name = "Launch Bay #1"; p_open = 0},/turf/unsimulated/floor{name = "plating"},/area/centcom) "wi" = (/obj/machinery/mass_driver{dir = 8; id = "ASSAULT2"; name = "gravpult"},/turf/unsimulated/floor{icon_state = "bot"},/area/centcom/specops) "wj" = (/obj/structure/table/reinforced,/obj/item/mecha_parts/mecha_equipment/teleporter,/obj/item/mecha_parts/mecha_tracking,/obj/item/mecha_parts/mecha_tracking,/obj/item/mecha_parts/mecha_tracking,/obj/item/mecha_parts/mecha_tracking,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) -"wk" = (/obj/structure/table/rack,/obj/item/weapon/rig/ert/medical,/obj/item/clothing/accessory/storage/black_vest,/obj/item/weapon/rig/ert/medical,/obj/item/clothing/accessory/storage/black_vest,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) +"wk" = (/obj/structure/table/rack,/obj/item/clothing/shoes/magboots,/obj/item/clothing/accessory/storage/black_vest,/obj/item/weapon/rig/ert,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom) "wl" = (/obj/machinery/vending/engivend,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom) "wm" = (/turf/unsimulated/floor{icon_state = "dark"},/area/centcom) "wn" = (/turf/unsimulated/floor{icon_state = "vault"; dir = 9},/area/centcom) @@ -1171,7 +1171,7 @@ "wA" = (/obj/structure/table/reinforced,/obj/item/device/aicard,/obj/item/weapon/pinpointer/advpinpointer,/obj/item/weapon/stamp/centcomm,/turf/unsimulated/floor{icon_state = "blue"},/area/centcom) "wB" = (/obj/structure/table/reinforced,/obj/item/device/pda/ert,/turf/unsimulated/floor{icon_state = "vault"; dir = 8},/area/centcom) "wC" = (/obj/structure/table/reinforced,/obj/item/clothing/mask/gas,/obj/item/clothing/mask/gas,/obj/item/clothing/mask/gas,/obj/item/clothing/mask/gas,/obj/item/clothing/mask/gas,/obj/item/clothing/mask/gas,/obj/item/clothing/mask/gas,/obj/item/clothing/mask/gas,/obj/item/clothing/mask/gas,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) -"wD" = (/obj/structure/table/rack,/obj/item/clothing/shoes/magboots,/obj/item/clothing/shoes/magboots,/obj/item/clothing/shoes/magboots,/obj/item/clothing/shoes/magboots,/obj/item/clothing/accessory/storage/black_vest,/obj/item/clothing/accessory/storage/black_vest,/obj/item/clothing/accessory/storage/black_vest,/obj/item/clothing/accessory/storage/black_vest,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) +"wD" = (/obj/structure/table/rack,/obj/item/weapon/rig/ert/medical,/obj/item/clothing/accessory/storage/black_vest,/obj/item/weapon/rig/ert/medical,/obj/item/clothing/accessory/storage/black_vest,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) "wE" = (/obj/machinery/vending/engineering,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom) "wF" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/turf/unsimulated/floor{name = "plating"},/area/centcom/specops) "wG" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/turf/unsimulated/floor{name = "plating"},/area/centcom/specops) @@ -1208,7 +1208,7 @@ "xl" = (/obj/machinery/mech_bay_recharge_port,/turf/unsimulated/floor{icon_state = "bot"},/area/centcom) "xm" = (/obj/mecha/working/hoverpod,/turf/unsimulated/floor{icon_state = "delivery"; dir = 6},/area/centcom) "xn" = (/obj/structure/table/reinforced,/obj/item/mecha_parts/mecha_equipment/tool/hydraulic_clamp,/obj/item/mecha_parts/mecha_equipment/tool/hydraulic_clamp,/obj/item/mecha_parts/mecha_equipment/tool/passenger,/obj/item/mecha_parts/mecha_equipment/tool/passenger,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom) -"xo" = (/obj/structure/table/rack,/obj/item/clothing/head/beret/centcom/officer,/obj/item/clothing/head/beret/centcom/officer,/obj/item/clothing/head/beret/centcom/officer,/obj/item/clothing/head/beret/centcom/officer,/obj/item/clothing/head/beret/centcom/officer,/obj/item/clothing/head/beret/centcom/officer,/obj/item/clothing/mask/balaclava,/obj/item/clothing/mask/balaclava,/obj/item/clothing/mask/balaclava,/obj/item/clothing/mask/balaclava,/obj/item/clothing/mask/balaclava,/obj/item/clothing/mask/balaclava,/obj/item/clothing/accessory/holster/waist,/obj/item/clothing/accessory/holster/waist,/obj/item/clothing/accessory/holster/waist,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) +"xo" = (/obj/structure/table/rack,/obj/item/clothing/shoes/magboots,/obj/item/clothing/shoes/magboots,/obj/item/clothing/shoes/magboots,/obj/item/clothing/shoes/magboots,/obj/item/clothing/accessory/storage/black_vest,/obj/item/clothing/accessory/storage/black_vest,/obj/item/clothing/accessory/storage/black_vest,/obj/item/clothing/accessory/storage/black_vest,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) "xp" = (/obj/structure/table/rack,/obj/item/clothing/mask/breath,/obj/item/clothing/mask/breath,/obj/item/clothing/mask/breath,/obj/item/clothing/mask/breath,/obj/item/clothing/mask/breath,/obj/item/clothing/mask/breath,/obj/item/clothing/mask/breath,/obj/item/clothing/mask/breath,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom) "xq" = (/obj/structure/sign/securearea{name = "\improper ARMORY"; pixel_y = 32},/turf/unsimulated/floor{icon_state = "vault"; dir = 8},/area/centcom) "xr" = (/obj/structure/sign/securearea{name = "ENGINEERING ACCESS"; pixel_y = 32},/turf/unsimulated/floor{icon_state = "vault"; dir = 8},/area/centcom) @@ -1912,7 +1912,7 @@ "KN" = (/obj/machinery/atmospherics/pipe/tank/nitrogen{dir = 1; initialize_directions = 1; start_pressure = 493.6},/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) "KO" = (/obj/machinery/portable_atmospherics/canister/phoron,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) "KP" = (/obj/machinery/portable_atmospherics/canister/nitrogen,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) -"KQ" = (/obj/structure/table/rack,/obj/item/weapon/gun/dartgun/vox/raider,/obj/item/weapon/gun/dartgun/vox/medical,/obj/item/weapon/dart_cartridge,/obj/item/weapon/dart_cartridge,/obj/item/weapon/dart_cartridge,/obj/item/weapon/dart_cartridge,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) +"KQ" = (/obj/structure/table/rack,/obj/item/weapon/gun/projectile/dartgun/vox/raider,/obj/item/weapon/gun/projectile/dartgun/vox/medical,/obj/item/ammo_magazine/chemdart,/obj/item/ammo_magazine/chemdart,/obj/item/ammo_magazine/chemdart,/obj/item/ammo_magazine/chemdart,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) "KR" = (/obj/structure/table/rack,/obj/item/clothing/accessory/storage/black_vest,/obj/item/clothing/suit/space/vox/medic,/obj/item/clothing/head/helmet/space/vox/medic,/obj/item/clothing/mask/breath,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) "KS" = (/obj/structure/table/rack,/obj/item/weapon/gun/launcher/pneumatic,/obj/item/weapon/harpoon,/obj/item/weapon/harpoon,/obj/item/weapon/harpoon,/obj/item/weapon/harpoon,/obj/item/weapon/tank/nitrogen,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) "KT" = (/obj/structure/table/rack,/obj/item/clothing/accessory/storage/black_vest,/obj/item/clothing/suit/space/vox/pressure,/obj/item/clothing/head/helmet/space/vox/pressure,/obj/item/clothing/mask/breath,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) @@ -2215,14 +2215,14 @@ aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMustvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvoNLytZtZtZtZvyoNvztZtZvAoNoNoNtvtvtvtvtvtvtvtvtvtvtvtNtxufufvBvCvCvCvCvCvCvCvCvCvDufufvEvqvqvqvqvqugvFuNuotxurururtxvGvGvHvGvGvvvwvwtxaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumuaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumu aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMustvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvutvIvbvJoNukujulumtZoNoNxatZtZvOoNuyvQoNvRvRvRvRvRvRvSvTcZtvtNtxufufvVvWvXvXvXvXvXvXvXvYueufufugvZwawbwcwdugweuNuptxurururtxwfwfuNwfwfvvvwvwtxaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMwgaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumuaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumu aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMuUuVuVuVuVuVuVuVuVuVuVuVuVuVwWuXuVuVuVuYwWwivavbwjoNtvoNoNoNtZoNvetZtZtZwloNwmwnwowpwpwpwpwpwpwqtvtvtvtvtvufufvVwrwsufwtwuwvufwswrueufufugugugugugugugweuNuptxurururtxwwwwuNwwwwvvvwvwtxaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumumuaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumu -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMustvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvutwxvbwyoNwzwAwBoNtZoNvKvdtZtZwEoNwmvMtvwFwGwGwGwHwGwItvwJwJwJtvufufwKwLwMwNwOwPwQwRwSwLwTufuftxwUwUwUwUwUtxtxuOtxtxtxuOtxtxuNuNuNuNuNvvvwvwtxaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumumumuaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumu +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMustvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvutwxvbwyoNwzwAwBoNtZoNvNvKtZtZwEoNwmvMtvwFwGwGwGwHwGwItvwJwJwJtvufufwKwLwMwNwOwPwQwRwSwLwTufuftxwUwUwUwUwUtxtxuOtxtxtxuOtxtxuNuNuNuNuNvvvwvwtxaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumumumuaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumu aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMwVoVoVoVoVoVoVoVoVoVoVoVoVoVwhoUoVoVoVqVwhwXwYvMwZoNyQtZxboNxcoNoNoNxdoNoNoNwmwnuWxfxfxfxfxfxfxfxgxfxfxfxgufufufxhufufxiufxiufufxhufufufxjurururururxjurururururururxjwwwwwwwwwwvvvwvwtxaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumumumumumuaMaMaMaMaMaMaMaMaMaMaMaMaMaMmu -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMxkoNoNoNoNoNoNoNoNoNoNoNoNoNoNoNoNoNoNoNoNxlxmvMxnoNvPuhvNoNtZxqtZxrtZxsxtxttZxutvxvxwxwxxxyxzxAtvxBxBxBtvufufvBxCxDwNxEufxFwRxGxCvDufufxjurururururxjurururururururxjwwwwwwwwwwtxuOuOtxtxtxtxtxaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumumumumumuaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMxkoNoNoNoNoNoNoNoNoNoNoNoNoNoNoNoNoNoNoNoNxlxmvMxnoNvPuhwkoNtZxqtZxrtZxsxtxttZxutvxvxwxwxxxyxzxAtvxBxBxBtvufufvBxCxDwNxEufxFwRxGxCvDufufxjurururururxjurururururururxjwwwwwwwwwwtxuOuOtxtxtxtxtxaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumumumumumuaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMwVoVoVoVoVoVoVoVoVoVoVoVoVoVxHoUoVoVoVqVxHxIxJvMwnxKuhtZtZxLtZxMtZwmwmxNxNwmwmxutvxOxOxOxPxQxPxRtvtvtvtvtvufufvVwLxSufxiufxiufxSwLueufuftxxTxUxUxUxVtxtxxWtxtxtxuOtxtxtxxXxXxXtxtxurururxYurxZtxaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumumumumumuaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMxkoNoNoNoNoNoNoNoNoNoNoNoNoNoNoNoNoNoNoNoNoNoNLgyaoNoNoNoNoNyboNycwmydyeyWygwmxutvtvyhyiyjykylymyhaMaMaMtxufufvVtxtxynyoufypyqtxtxueufuftxaMaMaMaMaMtxyrystxuNytuNuNyuyvywywywyxtxururuQuQururyyaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumuaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMoNoNoNoNyzyAwDwktZoNxewmydyfyfygwmxpyEyFyhyGyHyIyByKyhaMaMaMtxufufvVtxtxvlvmvmvmvotxtxueufuftxaMaMaMaMaMtxysystxyLyLyLuNyuywywywywyMtxuryNuPuPyOuryPaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMoNoNoNoNyzyAxowDtZoNxewmydyfyfygwmxpyEyFyhyGyHyIyByKyhaMaMaMtxufufvVtxtxvlvmvmvmvotxtxueufuftxaMaMaMaMaMtxysystxyLyLyLuNyuywywywywyMtxuryNuPuPyOuryPaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMoNzitZtZtZtZtZtZoNxetZtZwqwqwmwmwmwmyRyhySyIyIyIyIyhaMaMaMtxufufwKyTyTyTyTyTyTyTyTyTwTufuftxaMaMaMaMaMtxyUystxyLyVyLuNyuyuyuyuyuyutxuryNuPuPyOuryPaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMoNzltZtZtZtZtZLfoNyXtZtZyYtZtZwCxoyJzcyhyIyIyIyIzdyhtxtxtxtxtxtxzetxtxufufufufuftxtxtxtxtxtxaMaMaMaMaMtxzfystxvFuNuNuNyuaMaMaMaMaMtxuryNuPuPyOuryPaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMoNzltZtZtZtZtZLfoNyXtZtZyYtZtZwCvdyJzcyhyIyIyIyIzdyhtxtxtxtxtxtxzetxtxufufufufuftxtxtxtxtxtxaMaMaMaMaMtxzfystxvFuNuNuNyuaMaMaMaMaMtxuryNuPuPyOuryPaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMoNzgzgzhyDyZxazkoNyXzmzmoNznznoNoNoNoNyhyINbzpzqzryhzsztztzszuzvufzwtxtxtxzxtxtxdCaMaMaMaMaMaMaMaMaMaMtxtxtxtxtxtxtxtxyuaMaMaMaMaMzyuryNuPuPyOuryPaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMzzmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtwgmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmt aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMoNoNoNoNoNoNoNoNoNoNoNoNzAzBzBzAaMaMaMyhyIzCzDzEzDyhzszFzFzszGzHufzwtxzIwTufwKzJtxaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMzKururzLzLururzKaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMzMzNzNzNzNzOzOzNzNzPaMyhyIyIyIyIyIyhzsztztzszQzHufzwtxueufufufvVtxaMaMaMaMaMaMaMaMaMaMaMaMzRzSNaNaNazTzUaMaMaMaMaMtxzVururururzWtxaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM diff --git a/sound/weapons/gunshot_smg2.ogg b/sound/weapons/gunshot_smg2.ogg new file mode 100644 index 0000000000..faba955f52 Binary files /dev/null and b/sound/weapons/gunshot_smg2.ogg differ