Still more simple_mob conversions (#5523)

* Fixes 6 pAI faces

PAIs are no longer coded to only recognize 9 emotions. This enables the use of the neutral, silly, nose, smirk, exclamation points, and question mark faces as a pAI. Before, those buttons did nothing.

* Fixes the PDA Halogen Scanner's tendency to be number one.

* Unfolded pAIs can be picked up

Because who doesn't want a robotic cat on their head? Adds in the missing code to allow pAIs to actually be picked up, and held sprites for the newer 4 chassis options.

* Adds the Gigaphone, a suped-up Megaphone.

* Constant Chip has a sprite

* Fireaxe cabinets find their fireaxes in initialize(), rather than new()

* Speeds up alcohol

* fixed mining cloak not being in loadouts

* Admin Supermatter Setup now closes the monitoring room shutters (#5442)

* Admin Supermatter Setup now closes the monitoring room shutters

* Fixes a copy-paste error

* Begins work on lightning.

* Fixes #5447 (Deadspy submap not overwriting mapgen) (#5448)

* Map fix

* fixed deadspy.dmm

* Added Squid plushies of varying colours

I added a few Squid plushies in different colours, changing the files code/game/objects/items/toys.dm
and obj/toy.dmi

* Added hat functionality to Squid plushies

I added the ability to wear my Squid plushies as hats. They're damn good hats.

* Replaces Skrell namegen (#5453)

Created a first name list for Skrell, to replace the syllable assembler.

Created a surname list for Skrell to replace the syllable assembler.

Replaced the Skrell namegen with pre-written namelists, instead of the old syllable assembler.

* Mechoid makes mistakes. Fix telepathic gigaphones.

* Lets people be colorblind

Adds four types of colorblindness to the traits in the setup menu - protanopia, deuteranopia, tritanopia, and monochromacy. Previously, there were ones defined in the code, but not actually usable to players.

* Whoops, worded that wrong

* Adds beams to the Type var list for View Variables.

* Unfuck my Master

* Adds beams to the Type var selection in View Variables.

* Finishes thunderstorms.

* Adds logging.

* APC Sprite Change

- Port from Virgo recolored slightly to match closer to the old sprite
- Addition of directional sprites for the APCs

* Refactors supply controller.
Supply consoles now run nanoUI

* Missing '

* [Excitedly updates changelog]

* btw i use arc

* Removes supermatters from cave PoIs.

* Holomap Port

- Port of Holomaps from Virgo

* Changing species (via ling or admin button) should no longer ruin your HUD

* Converts most istype(thing,tool) procs into an appropriate thing.is_tool() format

* Removes empty file, gives the QM a control console again (Was replaced with an ordering console)

* Hopefully fixes some tool-conversion things

* Makes the Northern Star still compile

* Keeps NS up to date

* Taj and Unathi should have explorer mask sprites now

* Corgi rune now summons the corgi in a flash of harmless lightning

* Forces mech construction to work with the is_tool() procs

* Various things and floors no longer associate with dirt

* MultiZ falling tweaks

* Fixes the clusterbang grenade

* Added new hairstyles

* Added new hairstyles

* Fixes spelling of Strike in Lightning Strike admin verb

* I don't know how we keep breaking falling

* Hallucinations now use the old system again, but with the more modern components.

* Ambience Refactor (#5476)

* Refactors how ambience is assigned, removes bad ambience, ports good ambience from tg

* Apparently that file is still used, not worth the salt to remove it.

* Changelog

* The speed-related chem effects are no longer a one-or-none affair, oxy causes slowdown

* Corrects noted issues

* Add some missing sprites for xenoarch excavation.

* Become thwarted, thot.

* Fixes the Ultra AC2's burstfire bug.

* The Major Bill's shuttle is actually contagious now.

* penguins are from earth

capitalize this, anewbe, i dare you

* Mechoid's a butt

* Adds new job/department specific teshari clothing to the loadout (#5481)

* adding the new department specific teshari outfits

* Slightly cleans up hooded suit code (#5471)

* FBPs can have brute damage repaired externally again

* Windoors fix

* Cleans up some largecrate code

* Weather refactor.

* NanoUI makes me sad.

* Drinking more booze gets you drunk faster

* Ports the supermatter grenade, supporting code

* May or may not make movement seem smoother

* Fixes the Sleepy Ring

* Partially ports the GLOB system

* Fixes the bug(s) that allow meat bodies to have metal brains

* ports VOREStation/VOREStation#4165 - i forgot to check if advanced who was a thing here

* Optimizes supply UI

* Transfer shuttle grammar fixes

* Fixes borked E and W fish sprites

* Fixes incorrect ETA in crew transfer announcement

* Mech Mini 'Revamp'. Will need playtesting. (#5480)

* Exosuits are now capable of holding more equipment, of specific types.

* Tweaks regarding feedback in staffside thread, other concerns.

* Tweak to be more consistent. Why did the Odysseus have two universals. Tweak to weapon restriction on Med - > Odyss

* Weapons only fit in universal combat slots.

* Adds smart magazine, magazine functionality

* Adds a new subset of grenades that shoot projectiles

* Low alpha now makes HUDs and tooltips not show up on you

* Fixes a UI bug with emptying currently-open bags into smartfridges...hopefully. (#5515)

* Update smartfridge.dm

* actually indicates which line solves the bug

* Adds a whole bunch of Exosuit weapons and other miscellaneous parts.

* Minifrags now use the small fragments mainly as they should.

* Iced beer no longer freezes you to 3 degrees C, which is enough to seriously burn a Skrell. Seriously, that's weird.

* Touch stuff in reference to responses.

* NanoUI now processes again

* Converts more simple_animal mobs to simple_mob

* Submap correction
This commit is contained in:
Anewbe
2018-08-28 11:25:33 -07:00
committed by Atermonera
parent 6a40982a48
commit 0c0246e3fa
289 changed files with 4825 additions and 2220 deletions
+29 -9
View File
@@ -86,6 +86,8 @@
var/ammo_type = /obj/item/ammo_casing //ammo type that is initially loaded
var/initial_ammo = null
var/can_remove_ammo = TRUE // Can this thing have bullets removed one-by-one? As of first implementation, only affects smart magazines
var/multiple_sprites = 0
//because BYOND doesn't support numbers as keys in associative lists
var/list/icon_keys = list() //keys
@@ -117,7 +119,7 @@
return
user.remove_from_mob(C)
C.loc = src
stored_ammo.Insert(1, C) //add to the head of the list
stored_ammo.Add(C)
update_icon()
if(istype(W, /obj/item/ammo_magazine/clip))
var/obj/item/ammo_magazine/clip/L = W
@@ -138,16 +140,34 @@
playsound(user.loc, 'sound/weapons/flipblade.ogg', 50, 1)
update_icon()
// This dumps all the bullets right on the floor
/obj/item/ammo_magazine/attack_self(mob/user)
if(!stored_ammo.len)
to_chat(user, "<span class='notice'>[src] is already empty!</span>")
if(can_remove_ammo)
if(!stored_ammo.len)
to_chat(user, "<span class='notice'>[src] is already empty!</span>")
return
to_chat(user, "<span class='notice'>You empty [src].</span>")
for(var/obj/item/ammo_casing/C in stored_ammo)
C.loc = user.loc
C.set_dir(pick(cardinal))
stored_ammo.Cut()
update_icon()
else
to_chat(user, "<span class='notice'>\The [src] is not designed to be unloaded.</span>")
return
to_chat(user, "<span class='notice'>You empty [src].</span>")
for(var/obj/item/ammo_casing/C in stored_ammo)
C.loc = user.loc
C.set_dir(pick(cardinal))
stored_ammo.Cut()
update_icon()
// This puts one bullet from the magazine into your hand
/obj/item/ammo_magazine/attack_hand(mob/user)
if(can_remove_ammo) // For Smart Magazines
if(user.get_inactive_hand() == src)
if(stored_ammo.len)
var/obj/item/ammo_casing/C = stored_ammo[stored_ammo.len]
stored_ammo-=C
user.put_in_hands(C)
user.visible_message("\The [user] removes \a [C] from [src].", "<span class='notice'>You remove \a [C] from [src].</span>")
update_icon()
return
..()
/obj/item/ammo_magazine/update_icon()
if(multiple_sprites)
@@ -51,7 +51,7 @@
/obj/item/ammo_magazine/s38/rubber
name = "speedloader (.38 rubber)"
icon_state = "T38"
ammo_type = /obj/item/ammo_casing/a38r
ammo_type = /obj/item/ammo_casing/a38/rubber
/obj/item/ammo_magazine/s38/emp
name = "speedloader (.38 haywire)"
@@ -74,19 +74,19 @@
/obj/item/ammo_magazine/m45/rubber
name = "magazine (.45 rubber)"
ammo_type = /obj/item/ammo_casing/a45r
ammo_type = /obj/item/ammo_casing/a45/rubber
/obj/item/ammo_magazine/m45/practice
name = "magazine (.45 practice)"
ammo_type = /obj/item/ammo_casing/a45p
ammo_type = /obj/item/ammo_casing/a45/practice
/obj/item/ammo_magazine/m45/flash
name = "magazine (.45 flash)"
ammo_type = /obj/item/ammo_casing/a45f
ammo_type = /obj/item/ammo_casing/a45/flash
/obj/item/ammo_magazine/m45/ap
name = "magazine (.45 AP)"
ammo_type = /obj/item/ammo_casing/a45ap
ammo_type = /obj/item/ammo_casing/a45/ap
/obj/item/ammo_magazine/box/emp/b45
name = "ammunition box (.45 haywire)"
@@ -116,7 +116,7 @@
/obj/item/ammo_magazine/m45tommy/ap
name = "tommygun magazine (.45 AP)"
ammo_type = /obj/item/ammo_casing/a45ap
ammo_type = /obj/item/ammo_casing/a45/ap
/obj/item/ammo_magazine/m45tommy/empty
initial_ammo = 0
@@ -133,7 +133,7 @@
/obj/item/ammo_magazine/m45tommydrum/ap
name = "tommygun drum magazine (.45 AP)"
ammo_type = /obj/item/ammo_casing/a45ap
ammo_type = /obj/item/ammo_casing/a45/ap
/obj/item/ammo_magazine/m45tommydrum/empty
initial_ammo = 0
@@ -150,15 +150,15 @@
/obj/item/ammo_magazine/clip/c45/rubber
name = "ammo clip (.45 rubber)"
ammo_type = /obj/item/ammo_casing/a45r
ammo_type = /obj/item/ammo_casing/a45/rubber
/obj/item/ammo_magazine/clip/c45/practice
name = "ammo clip (.45 practice)"
ammo_type = /obj/item/ammo_casing/a45p
ammo_type = /obj/item/ammo_casing/a45/practice
/obj/item/ammo_magazine/clip/c45/flash
name = "ammo clip (.45 flash)"
ammo_type = /obj/item/ammo_casing/a45f
ammo_type = /obj/item/ammo_casing/a45/flash
/obj/item/ammo_magazine/s45
name = "speedloader (.45)"
@@ -174,19 +174,19 @@
/obj/item/ammo_magazine/s45/rubber
name = "speedloader (.45 rubber)"
ammo_type = /obj/item/ammo_casing/a45r
ammo_type = /obj/item/ammo_casing/a45/rubber
/obj/item/ammo_magazine/s45/practice
name = "speedloader (.45 practice)"
ammo_type = /obj/item/ammo_casing/a45p
ammo_type = /obj/item/ammo_casing/a45/practice
/obj/item/ammo_magazine/s45/flash
name = "speedloader (.45 flash)"
ammo_type = /obj/item/ammo_casing/a45f
ammo_type = /obj/item/ammo_casing/a45/flash
/obj/item/ammo_magazine/s45/ap
name = "speedloader (.45 AP)"
ammo_type = /obj/item/ammo_casing/a45ap
ammo_type = /obj/item/ammo_casing/a45/ap
///////// 9mm /////////
@@ -215,15 +215,15 @@
/obj/item/ammo_magazine/m9mm/flash
name = "magazine (9mm flash)"
ammo_type = /obj/item/ammo_casing/a9mmf
ammo_type = /obj/item/ammo_casing/a9mm/flash
/obj/item/ammo_magazine/m9mm/rubber
name = "magazine (9mm rubber)"
ammo_type = /obj/item/ammo_casing/a9mmr
ammo_type = /obj/item/ammo_casing/a9mm/rubber
/obj/item/ammo_magazine/m9mm/practice
name = "magazine (9mm practice)"
ammo_type = /obj/item/ammo_casing/a9mmp
ammo_type = /obj/item/ammo_casing/a9mm/practice
// Compact
/obj/item/ammo_magazine/m9mm/compact
@@ -242,15 +242,15 @@
/obj/item/ammo_magazine/m9mm/compact/flash
name = "compact magazine (9mm flash)"
ammo_type = /obj/item/ammo_casing/a9mmf
ammo_type = /obj/item/ammo_casing/a9mm/flash
/obj/item/ammo_magazine/m9mm/compact/rubber
name = "compact magazine (9mm rubber)"
ammo_type = /obj/item/ammo_casing/a9mmr
ammo_type = /obj/item/ammo_casing/a9mm/rubber
/obj/item/ammo_magazine/m9mm/compact/practice
name = "compact magazine (9mm practice)"
ammo_type = /obj/item/ammo_casing/a9mmp
ammo_type = /obj/item/ammo_casing/a9mm/practice
// SMG
/obj/item/ammo_magazine/m9mmt
@@ -268,15 +268,15 @@
/obj/item/ammo_magazine/m9mmt/rubber
name = "top mounted magazine (9mm rubber)"
ammo_type = /obj/item/ammo_casing/a9mmr
ammo_type = /obj/item/ammo_casing/a9mm/rubber
/obj/item/ammo_magazine/m9mmt/flash
name = "top mounted magazine (9mm flash)"
ammo_type = /obj/item/ammo_casing/a9mmf
ammo_type = /obj/item/ammo_casing/a9mm/flash
/obj/item/ammo_magazine/m9mmt/practice
name = "top mounted magazine (9mm practice)"
ammo_type = /obj/item/ammo_casing/a9mmp
ammo_type = /obj/item/ammo_casing/a9mm/practice
/obj/item/ammo_magazine/m9mmp90
name = "large capacity top mounted magazine (9mm armor-piercing)"
@@ -303,15 +303,15 @@
/obj/item/ammo_magazine/clip/c9mm/rubber
name = "ammo clip (.45 rubber)"
ammo_type = /obj/item/ammo_casing/a9mmr
ammo_type = /obj/item/ammo_casing/a9mm/rubber
/obj/item/ammo_magazine/clip/c9mm/practice
name = "ammo clip (.45 practice)"
ammo_type = /obj/item/ammo_casing/a9mmp
ammo_type = /obj/item/ammo_casing/a9mm/practice
/obj/item/ammo_magazine/clip/c9mm/flash
name = "ammo clip (.45 flash)"
ammo_type = /obj/item/ammo_casing/a9mmf
ammo_type = /obj/item/ammo_casing/a9mm/flash
/obj/item/ammo_magazine/box/c9mm // Made by RnD for Prototype SMG and should probably be removed because why does it require DIAMONDS to make bullets?
name = "ammunition Box (9mm)"
@@ -406,7 +406,7 @@
/obj/item/ammo_magazine/m545/practice
name = "magazine (5.45mm practice)"
ammo_type = /obj/item/ammo_casing/a545p
ammo_type = /obj/item/ammo_casing/a545/practice
/obj/item/ammo_magazine/m545/practice/ext
name = "extended magazine (5.45mm practice)"
@@ -439,7 +439,7 @@
/obj/item/ammo_magazine/m545/small/practice
name = "magazine (5.45mm practice)"
ammo_type = /obj/item/ammo_casing/a545p
ammo_type = /obj/item/ammo_casing/a545/practice
/obj/item/ammo_magazine/m545/small/ap
name = "magazine (5.45mm armor-piercing)"
@@ -534,7 +534,7 @@
/obj/item/ammo_magazine/s44/rubber
name = "speedloader (.44 rubber)"
icon_state = "R44"
ammo_type = /obj/item/ammo_casing/a44r
ammo_type = /obj/item/ammo_casing/a44/rubber
///////// 7.62mm /////////
@@ -604,7 +604,7 @@
/obj/item/ammo_magazine/clip/c762/practice
name = "rifle clip (7.62mm practice)"
ammo_type = /obj/item/ammo_casing/a762p
ammo_type = /obj/item/ammo_casing/a762/practice
/obj/item/ammo_magazine/clip/c762/hunter
name = "rifle clip (7.62mm hunting)"
+32 -25
View File
@@ -27,6 +27,7 @@
desc = "A .357 bullet casing."
caliber = ".357"
projectile_type = /obj/item/projectile/bullet/pistol/strong
matter = list(DEFAULT_WALL_MATERIAL = 210)
/*
* .38
@@ -36,10 +37,10 @@
desc = "A .38 bullet casing."
caliber = ".38"
projectile_type = /obj/item/projectile/bullet/pistol
matter = list(DEFAULT_WALL_MATERIAL = 60)
/obj/item/ammo_casing/a38r
/obj/item/ammo_casing/a38/rubber
desc = "A .38 rubber bullet casing."
caliber = ".38"
icon_state = "r-casing"
projectile_type = /obj/item/projectile/bullet/pistol/rubber
@@ -58,12 +59,13 @@
desc = "A .44 bullet casing."
caliber = ".44"
projectile_type = /obj/item/projectile/bullet/pistol/strong
matter = list(DEFAULT_WALL_MATERIAL = 210)
/obj/item/ammo_casing/a44r
/obj/item/ammo_casing/a44/rubber
icon_state = "r-casing"
desc = "A .44 rubber bullet casing."
caliber = ".44"
projectile_type = /obj/item/projectile/bullet/pistol/rubber/strong
matter = list(DEFAULT_WALL_MATERIAL = 60)
/*
* .75 (aka Gyrojet Rockets, aka admin abuse)
@@ -73,6 +75,7 @@
desc = "A .75 gyrojet rocket sheathe."
caliber = ".75"
projectile_type = /obj/item/projectile/bullet/gyro
matter = list(DEFAULT_WALL_MATERIAL = 4000)
/*
* 9mm
@@ -82,26 +85,25 @@
desc = "A 9mm bullet casing."
caliber = "9mm"
projectile_type = /obj/item/projectile/bullet/pistol
matter = list(DEFAULT_WALL_MATERIAL = 60)
/obj/item/ammo_casing/a9mm/ap
desc = "A 9mm armor-piercing bullet casing."
projectile_type = /obj/item/projectile/bullet/pistol/ap
matter = list(DEFAULT_WALL_MATERIAL = 80)
/obj/item/ammo_casing/a9mmf
/obj/item/ammo_casing/a9mm/flash
desc = "A 9mm flash shell casing."
caliber = "9mm"
icon_state = "r-casing"
projectile_type = /obj/item/projectile/energy/flash
/obj/item/ammo_casing/a9mmr
/obj/item/ammo_casing/a9mm/rubber
desc = "A 9mm rubber bullet casing."
caliber = "9mm"
icon_state = "r-casing"
projectile_type = /obj/item/projectile/bullet/pistol/rubber
/obj/item/ammo_casing/a9mmp
/obj/item/ammo_casing/a9mm/practice
desc = "A 9mm practice bullet casing."
caliber = "9mm"
icon_state = "r-casing"
projectile_type = /obj/item/projectile/bullet/pistol/practice
@@ -113,30 +115,30 @@
desc = "A .45 bullet casing."
caliber = ".45"
projectile_type = /obj/item/projectile/bullet/pistol/medium
matter = list(DEFAULT_WALL_MATERIAL = 75)
/obj/item/ammo_casing/a45ap
/obj/item/ammo_casing/a45/ap
desc = "A .45 Armor-Piercing bullet casing."
caliber = ".45"
icon_state = "r-casing"
projectile_type = /obj/item/projectile/bullet/pistol/medium/ap
/obj/item/ammo_casing/a45p
/obj/item/ammo_casing/a45/practice
desc = "A .45 practice bullet casing."
caliber = ".45"
icon_state = "r-casing"
projectile_type = /obj/item/projectile/bullet/pistol/practice
matter = list(DEFAULT_WALL_MATERIAL = 60)
/obj/item/ammo_casing/a45r
/obj/item/ammo_casing/a45/rubber
desc = "A .45 rubber bullet casing."
caliber = ".45"
icon_state = "r-casing"
projectile_type = /obj/item/projectile/bullet/pistol/rubber
matter = list(DEFAULT_WALL_MATERIAL = 60)
/obj/item/ammo_casing/a45f
/obj/item/ammo_casing/a45/flash
desc = "A .45 flash shell casing."
caliber = ".45"
icon_state = "r-casing"
projectile_type = /obj/item/projectile/energy/flash
matter = list(DEFAULT_WALL_MATERIAL = 60)
/obj/item/ammo_casing/a45/emp
name = ".45 haywire round"
@@ -149,7 +151,6 @@
desc = "A .45 hollow-point bullet casing."
projectile_type = /obj/item/projectile/bullet/pistol/medium/hollow
/*
* 10mm
*/
@@ -158,6 +159,7 @@
desc = "A 10mm bullet casing."
caliber = "10mm"
projectile_type = /obj/item/projectile/bullet/pistol/medium
matter = list(DEFAULT_WALL_MATERIAL = 75)
/obj/item/ammo_casing/a10mm/emp
name = "10mm haywire round"
@@ -183,7 +185,6 @@
desc = "A 12 gauge shell."
icon_state = "gshell"
projectile_type = /obj/item/projectile/bullet/pellet/shotgun
matter = list(DEFAULT_WALL_MATERIAL = 360)
/obj/item/ammo_casing/a12g/blank
name = "shotgun shell"
@@ -197,7 +198,7 @@
desc = "A practice shell."
icon_state = "pshell"
projectile_type = /obj/item/projectile/bullet/shotgun/practice
matter = list("metal" = 90)
matter = list(DEFAULT_WALL_MATERIAL = 90)
/obj/item/ammo_casing/a12g/beanbag
name = "beanbag shell"
@@ -244,16 +245,18 @@
caliber = "7.62mm"
icon_state = "rifle-casing"
projectile_type = /obj/item/projectile/bullet/rifle/a762
matter = list(DEFAULT_WALL_MATERIAL = 200)
/obj/item/ammo_casing/a762/ap
desc = "A 7.62mm armor-piercing bullet casing."
projectile_type = /obj/item/projectile/bullet/rifle/a762/ap
matter = list(DEFAULT_WALL_MATERIAL = 300)
/obj/item/ammo_casing/a762p
/obj/item/ammo_casing/a762/practice
desc = "A 7.62mm practice bullet casing."
caliber = "7.62mm"
icon_state = "rifle-casing" // Need to make an icon for these
projectile_type = /obj/item/projectile/bullet/rifle/practice
matter = list(DEFAULT_WALL_MATERIAL = 90)
/obj/item/ammo_casing/a762/blank
desc = "A blank 7.62mm bullet casing."
@@ -288,16 +291,18 @@
caliber = "5.45mm"
icon_state = "rifle-casing"
projectile_type = /obj/item/projectile/bullet/rifle/a545
matter = list(DEFAULT_WALL_MATERIAL = 180)
/obj/item/ammo_casing/a545/ap
desc = "A 5.45mm armor-piercing bullet casing."
projectile_type = /obj/item/projectile/bullet/rifle/a545/ap
matter = list(DEFAULT_WALL_MATERIAL = 270)
/obj/item/ammo_casing/a545p
/obj/item/ammo_casing/a545/practice
desc = "A 5.45mm practice bullet casing."
caliber = "5.45mm"
icon_state = "rifle-casing" // Need to make an icon for these
projectile_type = /obj/item/projectile/bullet/rifle/practice
matter = list(DEFAULT_WALL_MATERIAL = 90)
/obj/item/ammo_casing/a545/blank
desc = "A blank 5.45mm bullet casing."
@@ -322,6 +327,7 @@
icon_state = "rocketshell"
projectile_type = /obj/item/missile
caliber = "rocket"
matter = list(DEFAULT_WALL_MATERIAL = 10000)
/obj/item/ammo_casing/cap
name = "cap"
@@ -330,6 +336,7 @@
icon_state = "r-casing"
color = "#FF0000"
projectile_type = /obj/item/projectile/bullet/pistol/cap
matter = list(DEFAULT_WALL_MATERIAL = 85)
/obj/item/ammo_casing/spent // For simple hostile mobs only, so they don't cough up usable bullets when firing. This is for literally nothing else.
icon_state = "s-casing-spent"
@@ -0,0 +1,226 @@
///////// Smart Mags /////////
/obj/item/ammo_magazine/smart
name = "smart magazine"
icon_state = "smartmag-empty"
desc = "A Hephaistos Industries brand Smart Magazine. It uses advanced matter manipulation technology to create bullets from energy. Simply present your loaded gun or magazine to the Smart Magazine."
multiple_sprites = 1
max_ammo = 5
mag_type = MAGAZINE
caliber = null //Set later
ammo_type = null //Set later
initial_ammo = 0 //Ensure no problems with no ammo_type or caliber set
can_remove_ammo = FALSE // Interferes with batteries
var/production_time = 6 SECONDS // Delay in between bullets forming
var/last_production_time = 0 // Used in determining if we should make a new bullet
var/production_cost = null // Set when an ammo type is scanned in
var/production_modifier = 2 // Multiplier on the ammo_casing's matter cost
var/production_delay = 75 // If we're in a gun, how long since it last shot do we need to wait before making bullets?
var/obj/item/weapon/gun/holding_gun = null // What gun are we in, if any?
var/obj/item/weapon/cell/device/attached_cell = null // What cell are we using, if any?
var/emagged = 0 // If you emag the smart mag, you can get the bullets out by clicking it
/obj/item/ammo_magazine/smart/New()
processing_objects |= src
..()
/obj/item/ammo_magazine/smart/Destroy()
processing_objects -= src
..()
/obj/item/ammo_magazine/smart/process()
if(!holding_gun) // Yes, this is awful, sorry. Don't know a better way to figure out if we've been moved into or out of a gun.
if(istype(src.loc, /obj/item/weapon/gun))
holding_gun = src.loc
if(caliber && ammo_type && attached_cell)
if(stored_ammo.len == max_ammo)
last_production_time = world.time // Otherwise the max_ammo var is basically always off by 1
return
if(holding_gun && world.time < holding_gun.last_shot + production_delay) // Same as recharging energy weapons.
return
if(world.time > last_production_time + production_time)
last_production_time = world.time
produce()
/obj/item/ammo_magazine/smart/examine(mob/user)
..()
if(attached_cell)
to_chat(user, "<span class='notice'>\The [src] is loaded with a [attached_cell.name]. It is [round(attached_cell.percent())]% charged.</span>")
else
to_chat(user, "<span class='warning'>\The [src] does not appear to have a power source installed.</span>")
/obj/item/ammo_magazine/smart/update_icon()
if(attached_cell)
icon_state = "smartmag-filled"
else
icon_state = "smartmag-empty"
// Emagging lets you remove bullets from your bullet-making magazine
/obj/item/ammo_magazine/smart/emag_act(var/remaining_charges, var/mob/user)
if(!emagged)
to_chat(user, "<span class='notice'>You overload \the [src]'s security measures causing widespread destabilisation. It is likely you could empty \the [src] now.</span>")
emagged = TRUE
can_remove_ammo = TRUE
return TRUE
return FALSE
/obj/item/ammo_magazine/smart/attackby(var/obj/item/I as obj, mob/user)
if(istype(I, /obj/item/weapon/cell/device))
if(attached_cell)
to_chat(user, "<span class='notice'>\The [src] already has a [attached_cell.name] attached.</span>")
return
else
to_chat(user, "You begin inserting \the [I] into \the [src].")
if(do_after(user, 25))
user.drop_item()
I.forceMove(src)
attached_cell = I
user.visible_message("[user] installs a cell in \the [src].", "You install \the [I] into \the [src].")
update_icon()
return
else if(I.is_screwdriver())
if(attached_cell)
to_chat(user, "You begin removing \the [attached_cell] from \the [src].")
if(do_after(user, 10)) // Faster than doing it by hand
attached_cell.update_icon()
attached_cell.forceMove(get_turf(src.loc))
attached_cell = null
user.visible_message("[user] removes a cell from \the [src].", "You remove \the [attached_cell] from \the [src].")
update_icon()
return
else if(istype(I, /obj/item/ammo_magazine) || istype(I, /obj/item/ammo_casing))
scan_ammo(I, user)
..()
/obj/item/ammo_magazine/smart/afterattack(atom/target, mob/user, proximity_flag, click_parameters)
if(src.loc == user)
scan_ammo(target, user)
..()
// You can remove the power cell from the magazine by hand, but it's way slower than using a screwdriver
/obj/item/ammo_magazine/smart/attack_hand(mob/user)
if(user.get_inactive_hand() == src)
if(attached_cell)
to_chat(user, "You struggle to remove \the [attached_cell] from \the [src].")
if(do_after(user, 40))
attached_cell.update_icon()
user.put_in_hands(attached_cell)
attached_cell = null
user.visible_message("[user] removes a cell from \the [src].", "You remove \the [attached_cell] from \the [src].")
update_icon()
return
..()
// Classic emp_act, just drains the battery
/obj/item/ammo_magazine/smart/emp_act(severity)
..()
if(attached_cell)
attached_cell.emp_act(severity)
// Finds the cell for the magazine, used by rechargers
/obj/item/ammo_magazine/smart/get_cell()
return attached_cell
// Removes energy from the attached cell when creating new bullets
/obj/item/ammo_magazine/smart/proc/chargereduction()
return attached_cell && attached_cell.checked_use(production_cost)
// Sets how much energy is drained to make each bullet
/obj/item/ammo_magazine/smart/proc/set_production_cost(var/obj/item/ammo_casing/A)
var/list/matters = ammo_repository.get_materials_from_object(A)
var/tempcost
for(var/key in matters)
var/value = matters[key]
tempcost += value * production_modifier
production_cost = tempcost
// Scans a magazine or ammo casing and tells the smart mag to start making those, if it can
/obj/item/ammo_magazine/smart/proc/scan_ammo(atom/target, mob/user)
var/new_caliber = caliber // Tracks what our new caliber will be
var/new_ammo_type = ammo_type // Tracks what our new ammo_type will be
if(istype(target, /obj/item/ammo_magazine))
var/obj/item/ammo_magazine/M = target
if(!new_caliber)
new_caliber = M.caliber // If caliber isn't set, set it now
if(new_caliber && new_caliber != M.caliber) // If we still don't have a caliber, or if our caliber doesn't match the thing we're scanning, give up
return
else
new_ammo_type = M.ammo_type
if(istype(target, /obj/item/ammo_casing))
var/obj/item/ammo_casing/C = target
if(!new_caliber)
new_caliber = C.caliber // If caliber isn't set, set it now
if(new_caliber && new_caliber != C.caliber) // If we still don't have a caliber, or if our caliber doesn't match the thing we're scanning, give up
return
else
new_ammo_type = C.type
var/change = FALSE // If we've changed caliber or ammo_type, display the built message.
var/msg = "You scan \the [target] with \the [src], copying \the [target]'s "
if(new_caliber != caliber) // This should never happen without the ammo_type switching too
change = TRUE
msg += "caliber and "
if(new_ammo_type != ammo_type)
change = TRUE
msg += "ammunition type."
if(change)
to_chat(user, "<span class='notice'>[msg]</span>")
caliber = new_caliber
ammo_type = new_ammo_type
set_production_cost(ammo_type) // Update our cost
return
// Actually makes the bullets
/obj/item/ammo_magazine/smart/proc/produce()
if(chargereduction())
var/obj/item/ammo_casing/W = new ammo_type(src)
stored_ammo.Insert(1, W) //add to the head of the list
return 1
return 0
// This verb clears out the smart mag's copied data, but only if it's empty
/obj/item/ammo_magazine/smart/verb/clear_ammo_data()
set name = "Clear Ammo Data"
set category = "Object"
set src in usr
if(!istype(src.loc, /mob/living)) // Needs to be in your hands to reset
return
var/mob/living/carbon/human/H = usr
if(!istype(H))
return
if(H.stat)
return
if(LAZYLEN(stored_ammo))
to_chat(usr, "<span class='warning'>You can't reset \the [src] unless it's empty!</span>")
return
to_chat(usr, "<span class='notice'>You clear \the [src]'s data buffers.</span>")
caliber = null
ammo_type = null
production_cost = null
return
+4 -5
View File
@@ -91,6 +91,7 @@
var/obj/item/dnalockingchip/attached_lock
var/last_shot = 0 //records the last shot fired
/obj/item/weapon/gun/New()
..()
for(var/i in 1 to firemodes.len)
@@ -376,9 +377,11 @@
last_shot = world.time
/* // Commented out for quality control and testing.
/*
// Commented out for quality control and testing.
shooting = 0
*/
// We do this down here, so we don't get the message if we fire an empty gun.
if(user.item_is_in_hands(src) && user.hands_are_full())
if(one_handed_penalty >= 20)
@@ -478,8 +481,6 @@
if(muzzle_flash)
set_light(0)
//obtains the next projectile to fire
/obj/item/weapon/gun/proc/consume_next_projectile()
return null
@@ -552,7 +553,6 @@
shake_camera(user, recoil+1, recoil)
update_icon()
/obj/item/weapon/gun/proc/process_point_blank(obj/projectile, mob/user, atom/target)
var/obj/item/projectile/P = projectile
if(!istype(P))
@@ -641,7 +641,6 @@
return launched
/obj/item/weapon/gun/proc/play_fire_sound(var/mob/user, var/obj/item/projectile/P)
var/shot_sound = (istype(P) && P.fire_sound)? P.fire_sound : fire_sound
if(silenced)
@@ -31,9 +31,9 @@
/obj/item/weapon/gun/magnetic/Destroy()
processing_objects.Remove(src)
qdel_null(cell)
qdel_null(loaded)
qdel_null(capacitor)
QDEL_NULL(cell)
QDEL_NULL(loaded)
QDEL_NULL(capacitor)
. = ..()
/obj/item/weapon/gun/magnetic/get_cell()
+2 -1
View File
@@ -41,6 +41,7 @@
loaded += new ammo_type(src)
if(ispath(magazine_type) && (load_method & MAGAZINE))
ammo_magazine = new magazine_type(src)
allowed_magazines += /obj/item/ammo_magazine/smart
update_icon()
/obj/item/weapon/gun/projectile/consume_next_projectile()
@@ -50,7 +51,7 @@
if(handle_casings != HOLD_CASINGS)
loaded -= chambered
else if(ammo_magazine && ammo_magazine.stored_ammo.len)
chambered = ammo_magazine.stored_ammo[1]
chambered = ammo_magazine.stored_ammo[ammo_magazine.stored_ammo.len]
if(handle_casings != HOLD_CASINGS)
ammo_magazine.stored_ammo -= chambered
@@ -15,7 +15,7 @@
/obj/item/weapon/gun/projectile/shotgun/pump/rifle/practice // For target practice
desc = "A bolt-action rifle with a lightweight synthetic wood stock, designed for competitive shooting. Comes shipped with practice rounds pre-loaded into the gun. Popular among professional marksmen. Uses 7.62mm rounds."
ammo_type = /obj/item/ammo_casing/a762p
ammo_type = /obj/item/ammo_casing/a762/practice
/obj/item/weapon/gun/projectile/shotgun/pump/rifle/ceremonial
name = "ceremonial bolt-action rifle"
@@ -266,8 +266,8 @@
var/global/list/ammo_types = list(
/obj/item/ammo_casing/a357 = ".357",
/obj/item/ammo_casing/a9mmf = "9mm",
/obj/item/ammo_casing/a45f = ".45",
/obj/item/ammo_casing/a9mm = "9mm",
/obj/item/ammo_casing/a45 = ".45",
/obj/item/ammo_casing/a10mm = "10mm",
/obj/item/ammo_casing/a12g = "12g",
/obj/item/ammo_casing/a12g = "12g",
@@ -74,7 +74,7 @@
caliber = ".45"
origin_tech = list(TECH_COMBAT = 2, TECH_MATERIAL = 2)
fire_sound = 'sound/weapons/gunshot_heavy.ogg'
ammo_type = /obj/item/ammo_casing/a45r
ammo_type = /obj/item/ammo_casing/a45/rubber
max_shells = 7
+6 -1
View File
@@ -20,7 +20,7 @@
return ..()
/obj/item/projectile/arc/Destroy()
qdel_null(shadow)
QDEL_NULL(shadow)
return ..()
/obj/item/projectile/arc/Bump(atom/A, forced=0)
@@ -110,6 +110,11 @@
/obj/item/projectile/arc/fragmentation/on_impact(turf/T)
fragmentate(T, fragment_amount, spread_range, fragment_types)
/obj/item/projectile/arc/fragmentation/mortar
icon_state = "mortar"
fragment_amount = 10
spread_range = 3
// EMP arc shot
/obj/item/projectile/arc/emp_blast
name = "emp blast"
@@ -58,6 +58,16 @@
tracer_type = /obj/effect/projectile/laser_heavy/tracer
impact_type = /obj/effect/projectile/laser_heavy/impact
/obj/item/projectile/beam/heavylaser/fakeemitter
name = "emitter beam"
icon_state = "emitter"
fire_sound = 'sound/weapons/emitter.ogg'
light_color = "#00CC33"
muzzle_type = /obj/effect/projectile/emitter/muzzle
tracer_type = /obj/effect/projectile/emitter/tracer
impact_type = /obj/effect/projectile/emitter/impact
/obj/item/projectile/beam/heavylaser/cannon
damage = 80
armor_penetration = 50
+5 -60
View File
@@ -62,66 +62,6 @@
return 0
//For projectiles that actually represent clouds of projectiles
/obj/item/projectile/bullet/pellet
name = "shrapnel" //'shrapnel' sounds more dangerous (i.e. cooler) than 'pellet'
damage = 20
//icon_state = "bullet" //TODO: would be nice to have it's own icon state
var/pellets = 4 //number of pellets
var/range_step = 2 //projectile will lose a fragment each time it travels this distance. Can be a non-integer.
var/base_spread = 90 //lower means the pellets spread more across body parts. If zero then this is considered a shrapnel explosion instead of a shrapnel cone
var/spread_step = 10 //higher means the pellets spread more across body parts with distance
/obj/item/projectile/bullet/pellet/Bumped()
. = ..()
bumped = 0 //can hit all mobs in a tile. pellets is decremented inside attack_mob so this should be fine.
/obj/item/projectile/bullet/pellet/proc/get_pellets(var/distance)
var/pellet_loss = round((distance - 1)/range_step) //pellets lost due to distance
return max(pellets - pellet_loss, 1)
/obj/item/projectile/bullet/pellet/attack_mob(var/mob/living/target_mob, var/distance, var/miss_modifier)
if (pellets < 0) return 1
var/total_pellets = get_pellets(distance)
var/spread = max(base_spread - (spread_step*distance), 0)
//shrapnel explosions miss prone mobs with a chance that increases with distance
var/prone_chance = 0
if(!base_spread)
prone_chance = max(spread_step*(distance - 2), 0)
var/hits = 0
for (var/i in 1 to total_pellets)
if(target_mob.lying && target_mob != original && prob(prone_chance))
continue
//pellet hits spread out across different zones, but 'aim at' the targeted zone with higher probability
//whether the pellet actually hits the def_zone or a different zone should still be determined by the parent using get_zone_with_miss_chance().
var/old_zone = def_zone
def_zone = ran_zone(def_zone, spread)
if (..()) hits++
def_zone = old_zone //restore the original zone the projectile was aimed at
pellets -= hits //each hit reduces the number of pellets left
if (hits >= total_pellets || pellets <= 0)
return 1
return 0
/obj/item/projectile/bullet/pellet/get_structure_damage()
var/distance = get_dist(loc, starting)
return ..() * get_pellets(distance)
/obj/item/projectile/bullet/pellet/Move()
. = ..()
//If this is a shrapnel explosion, allow mobs that are prone to get hit, too
if(. && !base_spread && isturf(loc))
for(var/mob/living/M in loc)
if(M.lying || !M.CanPass(src, loc)) //Bump if lying or if we would normally Bump.
if(Bump(M)) //Bump will make sure we don't hit a mob multiple times
return
/* short-casing projectiles, like the kind used in pistols or SMGs */
/obj/item/projectile/bullet/pistol
@@ -189,6 +129,11 @@
range_step = 1
spread_step = 10
/obj/item/projectile/bullet/pellet/shotgun/flak
damage = 2 //The main weapon using these fires four at a time, usually with different destinations. Usually.
range_step = 2
spread_step = 30
armor_penetration = 10
//EMP shotgun 'slug', it's basically a beanbag that pops a tiny emp when it hits. //Not currently used
/obj/item/projectile/bullet/shotgun/ion
@@ -0,0 +1,110 @@
//For projectiles that actually represent clouds of projectiles
/obj/item/projectile/bullet/pellet
name = "shrapnel" //'shrapnel' sounds more dangerous (i.e. cooler) than 'pellet'
damage = 20
//icon_state = "bullet" //TODO: would be nice to have it's own icon state
var/pellets = 4 //number of pellets
var/range_step = 2 //projectile will lose a fragment each time it travels this distance. Can be a non-integer.
var/base_spread = 90 //lower means the pellets spread more across body parts. If zero then this is considered a shrapnel explosion instead of a shrapnel cone
var/spread_step = 10 //higher means the pellets spread more across body parts with distance
/obj/item/projectile/bullet/pellet/Bumped()
. = ..()
bumped = 0 //can hit all mobs in a tile. pellets is decremented inside attack_mob so this should be fine.
/obj/item/projectile/bullet/pellet/proc/get_pellets(var/distance)
var/pellet_loss = round((distance - 1)/range_step) //pellets lost due to distance
return max(pellets - pellet_loss, 1)
/obj/item/projectile/bullet/pellet/attack_mob(var/mob/living/target_mob, var/distance, var/miss_modifier)
if (pellets < 0) return 1
var/total_pellets = get_pellets(distance)
var/spread = max(base_spread - (spread_step*distance), 0)
//shrapnel explosions miss prone mobs with a chance that increases with distance
var/prone_chance = 0
if(!base_spread)
prone_chance = max(spread_step*(distance - 2), 0)
var/hits = 0
for (var/i in 1 to total_pellets)
if(target_mob.lying && target_mob != original && prob(prone_chance))
continue
//pellet hits spread out across different zones, but 'aim at' the targeted zone with higher probability
//whether the pellet actually hits the def_zone or a different zone should still be determined by the parent using get_zone_with_miss_chance().
var/old_zone = def_zone
def_zone = ran_zone(def_zone, spread)
if (..()) hits++
def_zone = old_zone //restore the original zone the projectile was aimed at
pellets -= hits //each hit reduces the number of pellets left
if (hits >= total_pellets || pellets <= 0)
return 1
return 0
/obj/item/projectile/bullet/pellet/get_structure_damage()
var/distance = get_dist(loc, starting)
return ..() * get_pellets(distance)
/obj/item/projectile/bullet/pellet/Move()
. = ..()
//If this is a shrapnel explosion, allow mobs that are prone to get hit, too
if(. && !base_spread && isturf(loc))
for(var/mob/living/M in loc)
if(M.lying || !M.CanPass(src, loc)) //Bump if lying or if we would normally Bump.
if(Bump(M)) //Bump will make sure we don't hit a mob multiple times
return
//Explosive grenade projectile, borrowed from fragmentation grenade code.
/obj/item/projectile/bullet/pellet/fragment
damage = 10
armor_penetration = 30
range_step = 2 //projectiles lose a fragment each time they travel this distance. Can be a non-integer.
base_spread = 0 //causes it to be treated as a shrapnel explosion instead of cone
spread_step = 20
silenced = 1 //embedding messages are still produced so it's kind of weird when enabled.
no_attack_log = 1
muzzle_type = null
/obj/item/projectile/bullet/pellet/fragment/strong
damage = 15
armor_penetration = 20
/obj/item/projectile/bullet/pellet/fragment/weak
damage = 4
armor_penetration = 40
// Tank rupture fragments
/obj/item/projectile/bullet/pellet/fragment/tank
name = "metal fragment"
damage = 9 //Big chunks flying off.
range_step = 2 //controls damage falloff with distance. projectiles lose a "pellet" each time they travel this distance. Can be a non-integer.
base_spread = 0 //causes it to be treated as a shrapnel explosion instead of cone
spread_step = 20
armor_penetration = 20
silenced = 1
no_attack_log = 1
muzzle_type = null
pellets = 3
/obj/item/projectile/bullet/pellet/fragment/tank/small
name = "small metal fragment"
damage = 6
armor_penetration = 5
pellets = 5
/obj/item/projectile/bullet/pellet/fragment/tank/big
name = "large metal fragment"
damage = 17
armor_penetration = 10
range_step = 5 //controls damage falloff with distance. projectiles lose a "pellet" each time they travel this distance. Can be a non-integer.
pellets = 1