mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-10 10:12:45 +00:00
A lot of new defines are now in inventory_sizes.dm, which contains; All the size identifiers (the thing that tells the game if something is bulky, or w/e). Storage costs for all the sizes, which are exponents of two, as previously. A few constants for inventory size. Also changes all storage item's capacity definitions by basing it off of how many 'normal slots' exist for it. This allows one to change the definition for all of the defines in the file, and everything will follow along without needing to change 500 files. In testing, I made all ITEMSIZE_COST_* defines doubled, and nothing had broke. The benefit of doing all of this is that it makes adding new weight classes in the future much simpler, and makes knowing how much space a container has easier, as seeing ITEMSIZE_COST_NORMAL * 7 means it can hold seven normal items.
190 lines
6.3 KiB
Plaintext
190 lines
6.3 KiB
Plaintext
/obj/item/ammo_casing
|
|
name = "bullet casing"
|
|
desc = "A bullet casing."
|
|
icon = 'icons/obj/ammo.dmi'
|
|
icon_state = "s-casing"
|
|
flags = CONDUCT
|
|
slot_flags = SLOT_BELT | SLOT_EARS
|
|
throwforce = 1
|
|
w_class = ITEMSIZE_TINY
|
|
|
|
var/leaves_residue = 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 - 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)
|
|
|
|
//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)
|
|
user << "\blue There is no bullet in the casing to inscribe anything into."
|
|
return
|
|
|
|
var/tmp_label = ""
|
|
var/label_text = sanitizeSafe(input(user, "Inscribe some text into \the [initial(BB.name)]","Inscription",tmp_label), 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*/
|
|
if(!BB) // This is really just a much better way of doing this.
|
|
icon_state = "[initial(icon_state)]-spent"
|
|
|
|
/obj/item/ammo_casing/examine(mob/user)
|
|
..()
|
|
if (!BB)
|
|
user << "This one is spent."
|
|
|
|
//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 = "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(DEFAULT_WALL_MATERIAL = 500)
|
|
throwforce = 5
|
|
w_class = ITEMSIZE_SMALL
|
|
throw_speed = 4
|
|
throw_range = 10
|
|
|
|
var/list/stored_ammo = list()
|
|
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()
|
|
..()
|
|
pixel_x = rand(-5, 5)
|
|
pixel_y = rand(-5, 5)
|
|
if(multiple_sprites)
|
|
initialize_magazine_icondata(src)
|
|
|
|
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 << "<span class='warning'>[C] does not fit into [src].</span>"
|
|
return
|
|
if(stored_ammo.len >= max_ammo)
|
|
user << "<span class='warning'>[src] is full!</span>"
|
|
return
|
|
user.remove_from_mob(C)
|
|
C.loc = src
|
|
stored_ammo.Insert(1, C) //add to the head of the list
|
|
update_icon()
|
|
if(istype(W, /obj/item/ammo_magazine/clip))
|
|
var/obj/item/ammo_magazine/clip/L = W
|
|
if(L.caliber != caliber)
|
|
user << "<span class='warning'>The ammo in [L] does not fit into [src].</span>"
|
|
return
|
|
if(!L.stored_ammo.len)
|
|
user << "<span class='warning'>There's no more ammo [L]!</span>"
|
|
return
|
|
if(stored_ammo.len >= max_ammo)
|
|
user << "<span class='warning'>[src] is full!</span>"
|
|
return
|
|
var/obj/item/ammo_casing/AC = L.stored_ammo[1] //select the next casing.
|
|
L.stored_ammo -= AC //Remove this casing from loaded list of the clip.
|
|
AC.loc = src
|
|
stored_ammo.Insert(1, AC) //add it to the head of our magazine's list
|
|
L.update_icon()
|
|
playsound(user.loc, 'sound/weapons/flipblade.ogg', 50, 1)
|
|
update_icon()
|
|
|
|
/obj/item/ammo_magazine/attack_self(mob/user)
|
|
if(!stored_ammo.len)
|
|
user << "<span class='notice'>[src] is already empty!</span>"
|
|
return
|
|
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()
|
|
|
|
/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)? "is" : "are"] [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
|
|
|