diff --git a/_maps/templates/holodeck_baseball.dmm b/_maps/templates/holodeck_baseball.dmm new file mode 100644 index 00000000000..472c9a11367 --- /dev/null +++ b/_maps/templates/holodeck_baseball.dmm @@ -0,0 +1,326 @@ +//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +"a" = ( +/obj/effect/turf_decal/trimline/white/line{ + dir = 1 + }, +/obj/effect/turf_decal/trimline/white/mid_joiner{ + dir = 1 + }, +/turf/open/floor/holofloor/asteroid, +/area/template_noop) +"b" = ( +/obj/effect/turf_decal/siding/thinplating/dark/corner{ + dir = 8 + }, +/obj/effect/turf_decal/siding/thinplating/dark{ + dir = 1 + }, +/turf/open/floor/holofloor/grass, +/area/template_noop) +"c" = ( +/obj/effect/turf_decal/trimline/white/line{ + dir = 4 + }, +/obj/effect/turf_decal/trimline/white/mid_joiner{ + dir = 4 + }, +/turf/open/floor/holofloor/asteroid, +/area/template_noop) +"d" = ( +/obj/effect/turf_decal/siding/thinplating/dark, +/obj/effect/turf_decal/siding/thinplating/dark{ + dir = 1 + }, +/turf/open/floor/holofloor/grass, +/area/template_noop) +"e" = ( +/obj/effect/turf_decal/siding/thinplating/dark/corner{ + dir = 4 + }, +/obj/effect/turf_decal/siding/thinplating/dark{ + dir = 8 + }, +/turf/open/floor/holofloor/grass, +/area/template_noop) +"h" = ( +/obj/effect/turf_decal/trimline/white/corner{ + dir = 1 + }, +/obj/effect/turf_decal/trimline/white, +/turf/open/floor/holofloor/asteroid, +/area/template_noop) +"l" = ( +/turf/open/floor/holofloor/grass, +/area/template_noop) +"m" = ( +/obj/effect/turf_decal/trimline/white/line{ + dir = 9 + }, +/obj/effect/turf_decal/trimline/white/mid_joiner{ + dir = 1 + }, +/turf/open/floor/holofloor/asteroid, +/area/template_noop) +"p" = ( +/obj/effect/turf_decal/trimline/white, +/turf/open/floor/holofloor/asteroid, +/area/template_noop) +"q" = ( +/obj/effect/turf_decal/siding/thinplating/dark/corner, +/turf/open/floor/holofloor/grass, +/area/template_noop) +"s" = ( +/obj/effect/turf_decal/trimline/white, +/obj/item/clothing/gloves/boxing, +/obj/effect/turf_decal/trimline/white/corner{ + dir = 8 + }, +/obj/effect/turf_decal/trimline/white/corner{ + dir = 4 + }, +/turf/open/floor/holofloor/asteroid, +/area/template_noop) +"u" = ( +/turf/open/floor/holofloor/asteroid, +/area/template_noop) +"w" = ( +/obj/effect/turf_decal/siding/thinplating/dark/corner{ + dir = 1 + }, +/turf/open/floor/holofloor/grass, +/area/template_noop) +"x" = ( +/obj/effect/turf_decal/trimline/white/line{ + dir = 10 + }, +/obj/effect/turf_decal/trimline/white/mid_joiner{ + dir = 8 + }, +/obj/effect/turf_decal/trimline/white/mid_joiner, +/turf/open/floor/holofloor/asteroid, +/area/template_noop) +"y" = ( +/obj/effect/turf_decal/trimline/white, +/obj/item/melee/baseball_bat, +/turf/open/floor/holofloor/asteroid, +/area/template_noop) +"B" = ( +/obj/effect/turf_decal/siding/thinplating/dark{ + dir = 8 + }, +/turf/open/floor/holofloor/grass, +/area/template_noop) +"E" = ( +/obj/effect/turf_decal/siding/thinplating/dark{ + dir = 6 + }, +/obj/effect/turf_decal/siding/thinplating/dark/corner{ + dir = 1 + }, +/turf/open/floor/holofloor/grass, +/area/template_noop) +"F" = ( +/obj/effect/turf_decal/siding/thinplating/dark{ + dir = 9 + }, +/turf/open/floor/holofloor/grass, +/area/template_noop) +"G" = ( +/obj/effect/turf_decal/trimline/white/line{ + dir = 5 + }, +/obj/effect/turf_decal/trimline/white/mid_joiner{ + dir = 1 + }, +/turf/open/floor/holofloor/asteroid, +/area/template_noop) +"J" = ( +/obj/effect/turf_decal/trimline/white/line, +/obj/effect/turf_decal/trimline/white/mid_joiner, +/turf/open/floor/holofloor/asteroid, +/area/template_noop) +"M" = ( +/obj/effect/turf_decal/siding/thinplating/dark{ + dir = 10 + }, +/turf/open/floor/holofloor/grass, +/area/template_noop) +"N" = ( +/obj/effect/turf_decal/trimline/white, +/obj/item/toy/beach_ball/baseball, +/turf/open/floor/holofloor/asteroid, +/area/template_noop) +"O" = ( +/obj/effect/turf_decal/siding/thinplating/dark/corner{ + dir = 4 + }, +/turf/open/floor/holofloor/grass, +/area/template_noop) +"Q" = ( +/obj/effect/turf_decal/trimline/white/line{ + dir = 8 + }, +/obj/effect/turf_decal/trimline/white/mid_joiner{ + dir = 8 + }, +/turf/open/floor/holofloor/asteroid, +/area/template_noop) +"R" = ( +/obj/effect/turf_decal/siding/thinplating/dark/corner{ + dir = 8 + }, +/turf/open/floor/holofloor/grass, +/area/template_noop) +"S" = ( +/obj/effect/turf_decal/siding/thinplating/dark{ + dir = 4 + }, +/turf/open/floor/holofloor/grass, +/area/template_noop) +"T" = ( +/obj/effect/turf_decal/siding/thinplating/dark{ + dir = 6 + }, +/turf/open/floor/holofloor/grass, +/area/template_noop) +"V" = ( +/obj/effect/turf_decal/siding/thinplating/dark, +/turf/open/floor/holofloor/grass, +/area/template_noop) +"W" = ( +/obj/effect/turf_decal/siding/thinplating/dark{ + dir = 4 + }, +/obj/effect/turf_decal/siding/thinplating/dark{ + dir = 8 + }, +/turf/open/floor/holofloor/grass, +/area/template_noop) +"X" = ( +/obj/effect/turf_decal/siding/thinplating/dark{ + dir = 1 + }, +/turf/open/floor/holofloor/grass, +/area/template_noop) +"Y" = ( +/obj/effect/turf_decal/siding/thinplating/dark/corner, +/obj/effect/turf_decal/siding/thinplating/dark{ + dir = 9 + }, +/turf/open/floor/holofloor/grass, +/area/template_noop) +"Z" = ( +/obj/effect/turf_decal/siding/thinplating/dark{ + dir = 5 + }, +/turf/open/floor/holofloor/grass, +/area/template_noop) + +(1,1,1) = {" +T +m +Q +Q +Q +Q +Q +Q +Q +x +"} +(2,1,1) = {" +m +h +Y +W +e +B +B +M +p +J +"} +(3,1,1) = {" +a +Y +E +u +Z +O +l +R +M +J +"} +(4,1,1) = {" +a +d +u +N +u +X +l +l +V +J +"} +(5,1,1) = {" +a +b +M +u +F +w +l +l +V +J +"} +(6,1,1) = {" +a +X +R +B +w +l +l +l +V +J +"} +(7,1,1) = {" +a +Z +O +l +l +l +l +q +T +J +"} +(8,1,1) = {" +a +p +Z +S +S +S +S +T +y +J +"} +(9,1,1) = {" +G +c +c +c +c +c +c +c +c +s +"} diff --git a/code/controllers/subsystem/throwing.dm b/code/controllers/subsystem/throwing.dm index 4516d5aa049..b48c43a5744 100644 --- a/code/controllers/subsystem/throwing.dm +++ b/code/controllers/subsystem/throwing.dm @@ -47,6 +47,8 @@ SUBSYSTEM_DEF(throwing) var/datum/weakref/initial_target ///The turf that the target was on, if it's not a turf itself. var/turf/target_turf + ///The turf that we were thrown from. + var/turf/starting_turf ///If the target happens to be a carbon and that carbon has a body zone aimed at, this is carried on here. var/target_zone ///The initial direction of the thrower of the thrownthing for building the trajectory of the throw. @@ -93,6 +95,7 @@ SUBSYSTEM_DEF(throwing) . = ..() src.thrownthing = thrownthing RegisterSignal(thrownthing, COMSIG_PARENT_QDELETING, .proc/on_thrownthing_qdel) + src.starting_turf = get_turf(thrownthing) src.target_turf = get_turf(target) if(target_turf != target) src.initial_target = WEAKREF(target) diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm index 60aa2e9f61e..a7743e3b067 100644 --- a/code/game/objects/items/toys.dm +++ b/code/game/objects/items/toys.dm @@ -847,11 +847,21 @@ icon_state = "ball" inhand_icon_state = "beachball" w_class = WEIGHT_CLASS_BULKY //Stops people from hiding it in their bags/pockets + item_flags = NO_PIXEL_RANDOM_DROP /obj/item/toy/beach_ball/branded name = "\improper Nanotrasen-brand beach ball" desc = "The simple beach ball is one of Nanotrasen's most popular products. 'Why do we make beach balls? Because we can! (TM)' - Nanotrasen" +/obj/item/toy/beach_ball/baseball + name = "baseball" + desc = "Enter the world of concussions and become who you were destined to be." + icon = 'icons/obj/items_and_weapons.dmi' + icon_state = "baseball" + inhand_icon_state = "baseball" + throw_range = 9 + throw_speed = 0.5 + /* * Clockwork Watch */ diff --git a/code/game/objects/items/weaponry.dm b/code/game/objects/items/weaponry.dm index e493943b90d..30286a28e87 100644 --- a/code/game/objects/items/weaponry.dm +++ b/code/game/objects/items/weaponry.dm @@ -684,8 +684,14 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 attack_verb_simple = list("beat", "smack") custom_materials = list(/datum/material/wood = MINERAL_MATERIAL_AMOUNT * 3.5) w_class = WEIGHT_CLASS_HUGE - var/homerun_ready = 0 - var/homerun_able = 0 + /// Are we able to do a homerun? + var/homerun_able = FALSE + /// Are we ready to do a homerun? + var/homerun_ready = FALSE + /// Can we launch mobs thrown at us away? + var/mob_thrower = FALSE + /// List of all thrown datums we sent. + var/list/thrown_datums = list() /obj/item/melee/baseball_bat/Initialize(mapload) . = ..() @@ -700,25 +706,18 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 AddElement(/datum/element/kneecapping) -/obj/item/melee/baseball_bat/homerun - name = "home run bat" - desc = "This thing looks dangerous... Dangerously good at baseball, that is." - homerun_able = 1 - /obj/item/melee/baseball_bat/attack_self(mob/user) if(!homerun_able) - ..() - return + return ..() if(homerun_ready) to_chat(user, span_warning("You're already ready to do a home run!")) - ..() - return + return ..() to_chat(user, span_warning("You begin gathering strength...")) playsound(get_turf(src), 'sound/magic/lightning_chargeup.ogg', 65, TRUE) - if(do_after(user, 90, target = src)) + if(do_after(user, 9 SECONDS, target = src)) to_chat(user, span_userdanger("You gather power! Time for a home run!")) - homerun_ready = 1 - ..() + homerun_ready = TRUE + return ..() /obj/item/melee/baseball_bat/attack(mob/living/target, mob/living/user) . = ..() @@ -732,12 +731,77 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 target.throw_at(throw_target, rand(8,10), 14, user) SSexplosions.medturf += throw_target playsound(get_turf(src), 'sound/weapons/homerun.ogg', 100, TRUE) - homerun_ready = 0 + homerun_ready = FALSE return else if(!target.anchored) var/whack_speed = (prob(60) ? 1 : 4) target.throw_at(throw_target, rand(1, 2), whack_speed, user, gentle = TRUE) // sorry friends, 7 speed batting caused wounds to absolutely delete whoever you knocked your target into (and said target) +/obj/item/melee/baseball_bat/Destroy(force) + for(var/target in thrown_datums) + var/datum/thrownthing/throw_datum = thrown_datums[target] + throw_datum.callback.Invoke() + thrown_datums.Cut() + return ..() + +/obj/item/melee/baseball_bat/pre_attack(atom/movable/target, mob/living/user, params) + var/turf/target_turf = get_turf(target) + if(!target_turf) + return ..() + for(var/atom/movable/atom as anything in target_turf) + if(!try_launch(atom, user)) + continue + return TRUE + return ..() + +/obj/item/melee/baseball_bat/proc/try_launch(atom/movable/target, mob/living/user) + if(!target.throwing || (ismob(target) && !mob_thrower)) + return FALSE + var/datum/thrownthing/throw_datum = target.throwing + var/datum_throw_speed = throw_datum.speed + var/angle = 0 + var/target_to_user = get_dir(target, user) + if(target.dir & turn(target_to_user, 90)) + angle = 270 + if(target.dir & turn(target_to_user, 270)) + angle = 90 + if(target.dir & turn(target_to_user, 180)) + angle = 180 + if(target.dir & target_to_user) + angle = 360 + var/turf/return_to_sender = get_ranged_target_turf_direct(user, throw_datum.starting_turf, round(target.throw_range * 1.5, 1), offset = angle + (rand(-1, 1) * 10)) + throw_datum.finalize(hit = FALSE) + target.mouse_opacity = MOUSE_OPACITY_TRANSPARENT //dont mess with our ball + target.color = list(1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,3) //make them super light + animate(target, 0.5 SECONDS, color = null, flags = ANIMATION_PARALLEL) + user.color = list(1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,3) + animate(user, 0.5 SECONDS, color = null, flags = ANIMATION_PARALLEL) + playsound(src, 'sound/items/baseballhit.ogg', 100, TRUE) + user.do_attack_animation(target, used_item = src) + ADD_TRAIT(user, TRAIT_IMMOBILIZED, type) + addtimer(CALLBACK(src, .proc/launch_back, target, user, return_to_sender, datum_throw_speed), 0.5 SECONDS) + return TRUE + +/obj/item/melee/baseball_bat/proc/launch_back(atom/movable/target, mob/living/user, turf/target_turf, datum_throw_speed) + playsound(target, 'sound/magic/tail_swing.ogg', 50, TRUE) + REMOVE_TRAIT(user, TRAIT_IMMOBILIZED, type) + target.mouse_opacity = initial(target.mouse_opacity) + target.add_filter("baseball_launch", 3, motion_blur_filter(1, 3)) + target.throwforce *= 2 + target.throw_at(target_turf, get_dist(target, target_turf), datum_throw_speed + 1, user, callback = CALLBACK(src, .proc/on_hit, target)) + thrown_datums[target] = target.throwing + +/obj/item/melee/baseball_bat/proc/on_hit(atom/movable/target) + target.remove_filter("baseball_launch") + target.throwforce *= 0.5 + thrown_datums -= target + +/obj/item/melee/baseball_bat/homerun + name = "home run bat" + desc = "This thing looks dangerous... Dangerously good at baseball, that is." + homerun_able = TRUE + mob_thrower = TRUE + /obj/item/melee/baseball_bat/ablative name = "metal baseball bat" desc = "This bat is made of highly reflective, highly armored material." @@ -745,15 +809,11 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 inhand_icon_state = "baseball_bat_metal" force = 12 throwforce = 15 + mob_thrower = TRUE /obj/item/melee/baseball_bat/ablative/IsReflect()//some day this will reflect thrown items instead of lasers - var/picksound = rand(1,2) - var/turf = get_turf(src) - if(picksound == 1) - playsound(turf, 'sound/weapons/effects/batreflect1.ogg', 50, TRUE) - if(picksound == 2) - playsound(turf, 'sound/weapons/effects/batreflect2.ogg', 50, TRUE) - return 1 + playsound(src, pick('sound/weapons/effects/batreflect1.ogg', 'sound/weapons/effects/batreflect2.ogg'), 50, TRUE) + return TRUE /obj/item/melee/flyswatter name = "flyswatter" diff --git a/code/modules/holodeck/holodeck_map_templates.dm b/code/modules/holodeck/holodeck_map_templates.dm index 5b86392d2b0..4480511977e 100644 --- a/code/modules/holodeck/holodeck_map_templates.dm +++ b/code/modules/holodeck/holodeck_map_templates.dm @@ -119,6 +119,12 @@ description = "benis" mappath = "_maps/templates/holodeck_microwave.dmm" +/datum/map_template/holodeck/baseball + name = "Holodeck - Baseball Field" + template_id = "holodeck_baseball" + description = "benis" + mappath = "_maps/templates/holodeck_baseball.dmm" + //bad evil no good programs /datum/map_template/holodeck/medicalsim diff --git a/icons/mob/inhands/items_lefthand.dmi b/icons/mob/inhands/items_lefthand.dmi index 19d566bf282..1ebc35bbc5c 100644 Binary files a/icons/mob/inhands/items_lefthand.dmi and b/icons/mob/inhands/items_lefthand.dmi differ diff --git a/icons/mob/inhands/items_righthand.dmi b/icons/mob/inhands/items_righthand.dmi index f80eeacdfd3..080164461aa 100644 Binary files a/icons/mob/inhands/items_righthand.dmi and b/icons/mob/inhands/items_righthand.dmi differ diff --git a/icons/obj/items_and_weapons.dmi b/icons/obj/items_and_weapons.dmi index 9209e07422d..108548183e5 100644 Binary files a/icons/obj/items_and_weapons.dmi and b/icons/obj/items_and_weapons.dmi differ diff --git a/sound/items/baseballhit.ogg b/sound/items/baseballhit.ogg new file mode 100644 index 00000000000..b5d67d8e0a7 Binary files /dev/null and b/sound/items/baseballhit.ogg differ