diff --git a/code/game/objects/effects/decals/Cleanable/misc_cleanables.dm b/code/game/objects/effects/decals/Cleanable/misc_cleanables.dm index e8ec6ac5b0f..428f8bc5797 100644 --- a/code/game/objects/effects/decals/Cleanable/misc_cleanables.dm +++ b/code/game/objects/effects/decals/Cleanable/misc_cleanables.dm @@ -253,6 +253,20 @@ icon = 'icons/effects/tomatodecal.dmi' random_icon_states = list("smashed_pie") +/obj/effect/decal/cleanable/paint_splat + name = "paint splat" + layer = TURF_LAYER + plane = GAME_PLANE + icon = 'icons/effects/splatters.dmi' + icon_state = "splatter-1" + random_icon_states = list("splatter-1", "splatter-2", "splatter-3") + mergeable_decal = FALSE + +/obj/effect/decal/cleanable/paint_splat/Initialize(mapload) + pixel_x = rand(-10, 10) + pixel_y = rand(-10, 10) + return ..() + /obj/effect/decal/cleanable/fungus name = "space fungus" desc = "A fungal growth. Looks pretty nasty." diff --git a/code/modules/mob/living/simple_animal/bot/cleanbot.dm b/code/modules/mob/living/simple_animal/bot/cleanbot.dm index 467ed466a05..49405df2d80 100644 --- a/code/modules/mob/living/simple_animal/bot/cleanbot.dm +++ b/code/modules/mob/living/simple_animal/bot/cleanbot.dm @@ -40,7 +40,8 @@ /obj/effect/decal/cleanable/ash, /obj/effect/decal/cleanable/greenglow, /obj/effect/decal/cleanable/dirt, - /obj/effect/decal/cleanable/glass + /obj/effect/decal/cleanable/glass, + /obj/effect/decal/cleanable/paint_splat ) var/static/list/clean_blood = list( /obj/effect/decal/cleanable/blood, diff --git a/code/modules/projectiles/ammunition/ammo_casings.dm b/code/modules/projectiles/ammunition/ammo_casings.dm index c2933c9faed..6ea5f6c08ae 100644 --- a/code/modules/projectiles/ammunition/ammo_casings.dm +++ b/code/modules/projectiles/ammunition/ammo_casings.dm @@ -409,6 +409,27 @@ muzzle_flash_strength = MUZZLE_FLASH_STRENGTH_NORMAL muzzle_flash_range = MUZZLE_FLASH_RANGE_NORMAL +/obj/item/ammo_casing/caseless/paintball + name = "paintball" + desc = "Do not aim at the eyes." + projectile_type = /obj/projectile/paintball + muzzle_flash_effect = null + caliber = "paintball" + icon = 'icons/obj/projectiles.dmi' + icon_state = "paintball" + harmful = FALSE + +/obj/item/ammo_casing/caseless/pepperball + name = "pepperball" + desc = "Aim at the eyes for maximum effect." + projectile_type = /obj/projectile/pepperball + muzzle_flash_effect = null + caliber = "pepperball" + icon = 'icons/obj/projectiles.dmi' + icon_state = "paintball" + harmful = FALSE + color = "#660000" + /obj/item/ammo_casing/caseless/foam_dart name = "foam dart" desc = "It's nerf or nothing! Ages 8 and up." diff --git a/code/modules/projectiles/ammunition/magazines.dm b/code/modules/projectiles/ammunition/magazines.dm index 248f5a87aa2..8423ee8d60d 100644 --- a/code/modules/projectiles/ammunition/magazines.dm +++ b/code/modules/projectiles/ammunition/magazines.dm @@ -501,6 +501,24 @@ icon_state = "party_drum" ammo_type = /obj/item/ammo_casing/shotgun/confetti +/obj/item/ammo_box/magazine/paintball + name = "paintball magazine" + desc = "A magazine that holds a large amount of paintballs." + icon = 'icons/obj/guns/toy.dmi' + icon_state = "paintballmag" + ammo_type = /obj/item/ammo_casing/caseless/paintball + caliber = "paintball" + max_ammo = 25 + multi_sprite_step = AMMO_BOX_MULTI_SPRITE_STEP_ON_OFF + +/obj/item/ammo_box/magazine/paintball/pepperball + name = "pepperball magazine" + desc = "A magazine that holds a large amount of pepperballs." + icon_state = "pepperballmag" + ammo_type = /obj/item/ammo_casing/caseless/pepperball + caliber = "pepperball" + max_ammo = 10 + /obj/item/ammo_box/magazine/toy name = "foam force META magazine" ammo_type = /obj/item/ammo_casing/caseless/foam_dart diff --git a/code/modules/projectiles/guns/projectile/toy.dm b/code/modules/projectiles/guns/projectile/toy.dm index 37d29a82b24..8b764d44e22 100644 --- a/code/modules/projectiles/guns/projectile/toy.dm +++ b/code/modules/projectiles/guns/projectile/toy.dm @@ -144,3 +144,113 @@ /obj/item/gun/projectile/automatic/sniper_rifle/toy/process_chamber(eject_casing = 0, empty_chamber = 1) ..() + +////////////////////////////// +// MARK: Paintball Guns +////////////////////////////// +#define PAINTBALL_BLUE "blue" +#define PAINTBALL_RED "red" +#define PAINTBALL_GREEN "green" +#define PAINTBALL_YELLOW "yellow" +#define PAINTBALL_CMAGGED "cmag" + +/obj/item/gun/projectile/automatic/paintball_gun + name = "paintball gun" + desc = "A gas-powered gun that shoots small balls of paint! Ages 13 and up. Do not aim at the eyes." + icon = 'icons/obj/guns/toy.dmi' + icon_state = "paintgun" + inhand_icon_state = "paintgun" + can_suppress = FALSE + needs_permit = FALSE + mag_type = /obj/item/ammo_box/magazine/paintball + actions_types = list() + burst_size = 1 + /// What color are we configured at? + var/paintball_color = PAINTBALL_BLUE + +/obj/item/gun/projectile/automatic/paintball_gun/examine(mob/user) + . = ..() + if(HAS_TRAIT(src, TRAIT_CMAGGED)) + . += SPAN_WARNING("The paint selector is covered in yellow sludge!") + else if(istype(magazine, /obj/item/ammo_box/magazine/paintball/pepperball)) + . += SPAN_WARNING("A magazine of pepperballs is loaded!") + else + . += SPAN_NOTICE("It is configured to fire [paintball_color] paintballs.") + if(emagged) + . += SPAN_WARNING("The air compressor sparks dangerously.") + +/obj/item/gun/projectile/automatic/paintball_gun/update_icon_state() + icon_state = "paintgun" + if(istype(magazine, /obj/item/ammo_box/magazine/paintball/pepperball)) + inhand_icon_state = "paintgun-pepper" + return + inhand_icon_state = "paintgun[magazine ? "-[paintball_color]" : ""]" + +/obj/item/gun/projectile/automatic/paintball_gun/update_overlays() + . = ..() + if(istype(magazine, /obj/item/ammo_box/magazine/paintball/pepperball)) + . += "paintgun-pepper[chambered ? "" : "-empty"]" + return + if(magazine) + . += "paintgun-[paintball_color][chambered ? "" : "-empty"]" + +/obj/item/gun/projectile/automatic/paintball_gun/chamber_round() + . = ..() + if(chambered) + color_paintball() + +/obj/item/gun/projectile/automatic/paintball_gun/multitool_act(mob/living/user, obj/item/I) + . = ..() + if(!magazine) + return + if(istype(magazine, /obj/item/ammo_box/magazine/paintball/pepperball)) + return + paintball_color = tgui_input_list(user, "Select a color", src, list(PAINTBALL_BLUE, PAINTBALL_RED, PAINTBALL_GREEN, PAINTBALL_YELLOW)) + color_paintball() + update_icon(UPDATE_OVERLAYS) + +/obj/item/gun/projectile/automatic/paintball_gun/proc/color_paintball() + if(!istype(magazine, /obj/item/ammo_box/magazine/paintball/pepperball)) + switch(paintball_color) + if(PAINTBALL_BLUE) + chambered.color = "#0000CC" + if(PAINTBALL_RED) + chambered.color = "#CC0000" + if(PAINTBALL_GREEN) + chambered.color = "#00CC00" + if(PAINTBALL_YELLOW) + chambered.color = "#CCCC00" + if(PAINTBALL_CMAGGED) + chambered.color = pick("#d41e3c", "#ed7b39", "#fff540", "#77b02a", "#488bd4", "#b0fff1", "#94007a", "#ff417d") + chambered.BB.color = chambered.color + if(emagged) + chambered.BB.damage = 8 + chambered.BB.muzzle_flash_intensity = 2 + +/obj/item/gun/projectile/automatic/paintball_gun/cmag_act(mob/user) + . = ..() + to_chat(user, SPAN_WARNING("You smear bananium over [src]'s paint selector.")) + ADD_TRAIT(src, TRAIT_CMAGGED, CLOWN_EMAG) + paintball_color = PAINTBALL_CMAGGED + update_icon(UPDATE_OVERLAYS) + +/obj/item/gun/projectile/automatic/paintball_gun/emag_act(mob/user) + . = ..() + emagged = TRUE + to_chat(user, SPAN_WARNING("You overcharge [src]'s air compressor.")) + if(magazine) + color_paintball() + +/obj/item/gun/projectile/automatic/paintball_gun/cleaning_act(mob/user, atom/cleaner, cleanspeed, text_verb, text_description, text_targetname) + var/cmagged = HAS_TRAIT(src, TRAIT_CMAGGED) + . = ..() + if(cmagged && .) + paintball_color = PAINTBALL_BLUE + color_paintball() + update_icon(UPDATE_OVERLAYS) + +#undef PAINTBALL_BLUE +#undef PAINTBALL_RED +#undef PAINTBALL_GREEN +#undef PAINTBALL_YELLOW +#undef PAINTBALL_CMAGGED diff --git a/code/modules/projectiles/projectile/special_projectiles.dm b/code/modules/projectiles/projectile/special_projectiles.dm index 09dff497fb0..4cfd3282a07 100644 --- a/code/modules/projectiles/projectile/special_projectiles.dm +++ b/code/modules/projectiles/projectile/special_projectiles.dm @@ -116,6 +116,34 @@ shake_camera(M, 3, 1) qdel(src) +/obj/projectile/paintball + name = "paintball" + icon_state = "paintball" + damage = 1 + +/obj/projectile/paintball/on_hit(atom/target, blocked, hit_zone) + var/obj/effect/decal/cleanable/paint_splat/splat = new /obj/effect/decal/cleanable/paint_splat(get_turf(target)) + splat.color = color + return ..() + +/obj/projectile/pepperball + name = "pepperball" + icon_state = "paintball" + damage = 1 + +/obj/projectile/pepperball/Initialize(mapload) + . = ..() + create_reagents(5) + reagents.set_reacting(FALSE) + reagents.add_reagent("condensedcapsaicin", 5) + +/obj/projectile/pepperball/on_hit(atom/target, blocked, hit_zone) + var/turf/our_turf = get_turf(target) + reagents.reaction(our_turf) + for(var/atom/T in our_turf) + reagents.reaction(T) + return ..() + /obj/projectile/missile icon = 'icons/obj/grenade.dmi' icon_state = "missile" diff --git a/code/modules/research/designs/autolathe_designs.dm b/code/modules/research/designs/autolathe_designs.dm index ea305780bc8..b13763ab953 100644 --- a/code/modules/research/designs/autolathe_designs.dm +++ b/code/modules/research/designs/autolathe_designs.dm @@ -585,6 +585,14 @@ build_path = /obj/item/ammo_box/magazine/detective/speedcharger category = list("initial", "Security") +/datum/design/paintball_magazine + name = "Paintball Magazine" + id = "paintball_mag" + build_type = AUTOLATHE + materials = list(MAT_METAL = 2500) + build_path = /obj/item/ammo_box/magazine/paintball + category = list("initial", "Miscellaneous") + /datum/design/recorder name = "Universal Recorder" id = "recorder" diff --git a/code/modules/supply/supply_packs/pack_miscellaneous.dm b/code/modules/supply/supply_packs/pack_miscellaneous.dm index eea5c788555..0fffb02f166 100644 --- a/code/modules/supply/supply_packs/pack_miscellaneous.dm +++ b/code/modules/supply/supply_packs/pack_miscellaneous.dm @@ -24,6 +24,15 @@ containertype = /obj/structure/largecrate containername = "high-capacity water tank crate" +/datum/supply_packs/misc/paintball_gun + name = "Paintball Crate" + contains = list(/obj/item/gun/projectile/automatic/paintball_gun, + /obj/item/gun/projectile/automatic/paintball_gun, + /obj/item/ammo_box/magazine/paintball, + /obj/item/ammo_box/magazine/paintball) + cost = 300 + containername = "paintball crate" + /datum/supply_packs/misc/lasertag name = "Laser Tag Crate" contains = list(/obj/item/beach_ball/dodgeball, diff --git a/code/modules/supply/supply_packs/pack_security.dm b/code/modules/supply/supply_packs/pack_security.dm index de1b2ec0f98..c80c6a7c3ac 100644 --- a/code/modules/supply/supply_packs/pack_security.dm +++ b/code/modules/supply/supply_packs/pack_security.dm @@ -463,3 +463,14 @@ ) cost = 300 containername = "party ammunition crate" + +/datum/supply_packs/security/pepperball_ammo + name = "Pepperball Ammunition Crate" + contains = list( + /obj/item/ammo_box/magazine/paintball/pepperball, + /obj/item/ammo_box/magazine/paintball/pepperball, + /obj/item/ammo_box/magazine/paintball/pepperball + ) + cost = 150 + containername = "pepperball ammunition crate" + access = ACCESS_ARMORY diff --git a/icons/effects/splatters.dmi b/icons/effects/splatters.dmi new file mode 100644 index 00000000000..46c24ced62e Binary files /dev/null and b/icons/effects/splatters.dmi differ diff --git a/icons/mob/inhands/guns_lefthand.dmi b/icons/mob/inhands/guns_lefthand.dmi index 444a8f0497c..cc2bb7572b0 100644 Binary files a/icons/mob/inhands/guns_lefthand.dmi and b/icons/mob/inhands/guns_lefthand.dmi differ diff --git a/icons/mob/inhands/guns_righthand.dmi b/icons/mob/inhands/guns_righthand.dmi index c754d104e53..20add38ed21 100644 Binary files a/icons/mob/inhands/guns_righthand.dmi and b/icons/mob/inhands/guns_righthand.dmi differ diff --git a/icons/obj/guns/toy.dmi b/icons/obj/guns/toy.dmi index b30a83a0c53..0af398e0fee 100644 Binary files a/icons/obj/guns/toy.dmi and b/icons/obj/guns/toy.dmi differ diff --git a/icons/obj/projectiles.dmi b/icons/obj/projectiles.dmi index 3149a55ae33..21ae65a8526 100644 Binary files a/icons/obj/projectiles.dmi and b/icons/obj/projectiles.dmi differ