Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

you can now use the mortar during hijack if you are not a coward + custom shell warning for ghosts #5940

Merged
merged 6 commits into from
Mar 29, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
199 changes: 114 additions & 85 deletions code/modules/cm_marines/equipment/mortar/mortars.dm
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@
var/firing = FALSE
/// If set to 1, can't unanchor and move the mortar, used for map spawns and WO
var/fixed = FALSE
/// if true, blows up the shell immediately
var/ship_side = FALSE

var/obj/structure/machinery/computer/cameras/mortar/internal_camera

Expand All @@ -56,28 +58,28 @@
else
return FALSE

/obj/structure/mortar/attack_alien(mob/living/carbon/xenomorph/M)
if(islarva(M))
/obj/structure/mortar/attack_alien(mob/living/carbon/xenomorph/xeno)
if(islarva(xeno))
return XENO_NO_DELAY_ACTION

if(fixed)
to_chat(M, SPAN_XENOWARNING("\The [src]'s supports are bolted and welded into the floor. It looks like it's going to be staying there."))
to_chat(xeno, SPAN_XENOWARNING("\The [src]'s supports are bolted and welded into the floor. It looks like it's going to be staying there."))
return XENO_NO_DELAY_ACTION

if(firing)
M.animation_attack_on(src)
M.flick_attack_overlay(src, "slash")
xeno.animation_attack_on(src)
xeno.flick_attack_overlay(src, "slash")
playsound(src, "acid_hit", 25, 1)
playsound(M, "alien_help", 25, 1)
M.apply_damage(10, BURN)
M.visible_message(SPAN_DANGER("[M] tried to knock the steaming hot [src] over, but burned itself and pulled away!"),
playsound(xeno, "alien_help", 25, 1)
xeno.apply_damage(10, BURN)
xeno.visible_message(SPAN_DANGER("[xeno] tried to knock the steaming hot [src] over, but burned itself and pulled away!"),
SPAN_XENOWARNING("\The [src] is burning hot! Wait a few seconds."))
return XENO_ATTACK_ACTION

M.visible_message(SPAN_DANGER("[M] lashes at \the [src] and knocks it over!"),
xeno.visible_message(SPAN_DANGER("[xeno] lashes at \the [src] and knocks it over!"),
SPAN_DANGER("You knock \the [src] over!"))
M.animation_attack_on(src)
M.flick_attack_overlay(src, "slash")
xeno.animation_attack_on(src)
xeno.flick_attack_overlay(src, "slash")
playsound(loc, 'sound/effects/metalhit.ogg', 25)
var/obj/item/mortar_kit/MK = new /obj/item/mortar_kit(loc)
MK.name = name
Expand Down Expand Up @@ -206,40 +208,47 @@

SStgui.update_uis(src)

/obj/structure/mortar/attackby(obj/item/O, mob/user)
if(istype(O, /obj/item/mortar_shell))
var/obj/item/mortar_shell/mortar_shell = O
/obj/structure/mortar/attackby(obj/item/item, mob/user)
if(istype(item, /obj/item/mortar_shell))
var/obj/item/mortar_shell/mortar_shell = item
var/turf/turf = locate(targ_x + dial_x + offset_x, targ_y + dial_y + offset_y, z)
var/area/area = get_area(turf)
if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_TRAINED))
to_chat(user, SPAN_WARNING("You don't have the training to fire [src]."))
return
if(busy)
to_chat(user, SPAN_WARNING("Someone else is currently using [src]."))
return
if(!is_ground_level(z))
to_chat(user, SPAN_WARNING("You cannot fire [src] here."))
return
if(targ_x == 0 && targ_y == 0) //Mortar wasn't set
to_chat(user, SPAN_WARNING("[src] needs to be aimed first."))
return
var/turf/T = locate(targ_x + dial_x + offset_x, targ_y + dial_y + offset_y, z)
if(!T)
to_chat(user, SPAN_WARNING("You cannot fire [src] to this target."))
return
var/area/A = get_area(T)
if(!istype(A))
to_chat(user, SPAN_WARNING("This area is out of bounds!"))
return
if(CEILING_IS_PROTECTED(A.ceiling, CEILING_PROTECTION_TIER_2) || protected_by_pylon(TURF_PROTECTION_MORTAR, T))
to_chat(user, SPAN_WARNING("You cannot hit the target. It is probably underground."))
return
if(SSticker.mode && MODE_HAS_TOGGLEABLE_FLAG(MODE_LZ_PROTECTION) && A.is_landing_zone)
to_chat(user, SPAN_WARNING("You cannot bomb the landing zone!"))
return

//Small amount of spread so that consecutive mortar shells don't all land on the same tile
var/turf/T1 = locate(T.x + pick(-1,0,0,1), T.y + pick(-1,0,0,1), T.z)
if(T1)
T = T1
if(!ship_side)
if(targ_x == 0 && targ_y == 0) //Mortar wasn't set
to_chat(user, SPAN_WARNING("[src] needs to be aimed first."))
return
if(!turf)
to_chat(user, SPAN_WARNING("You cannot fire [src] to this target."))
return
if(!istype(area))
to_chat(user, SPAN_WARNING("This area is out of bounds!"))
return
if(CEILING_IS_PROTECTED(area.ceiling, CEILING_PROTECTION_TIER_2) || protected_by_pylon(TURF_PROTECTION_MORTAR, turf))
to_chat(user, SPAN_WARNING("You cannot hit the target. It is probably underground."))
return
if(SSticker.mode && MODE_HAS_TOGGLEABLE_FLAG(MODE_LZ_PROTECTION) && area.is_landing_zone)
to_chat(user, SPAN_WARNING("You cannot bomb the landing zone!"))
return

if(!ship_side)
var/turf/T1 = locate(turf.x + pick(-1,0,0,1), turf.y + pick(-1,0,0,1), turf.z) //Small amount of spread so that consecutive mortar shells don't all land on the same tile
if(T1)
turf = T1
else
var/crash_occurred = (SSticker?.mode?.is_in_endgame)
if(crash_occurred)
var/turf/our_turf = get_turf(src)
turf = our_turf
travel_time = 0.5 SECONDS
else
to_chat(user, SPAN_RED("You realize how bad of an idea this is and quickly stop."))
return

user.visible_message(SPAN_NOTICE("[user] starts loading \a [mortar_shell.name] into [src]."),
SPAN_NOTICE("You start loading \a [mortar_shell.name] into [src]."))
Expand All @@ -259,15 +268,15 @@
mortar_shell.cause_data = create_cause_data(initial(mortar_shell.name), user, src)
mortar_shell.forceMove(src)

var/turf/G = get_turf(src)
G.ceiling_debris_check(2)
var/turf/hit_turf = get_turf(src)
hit_turf.ceiling_debris_check(2)

for(var/mob/M in range(7))
shake_camera(M, 3, 1)
for(var/mob/mob in range(7))
shake_camera(mob, 3, 1)

addtimer(CALLBACK(src, PROC_REF(handle_shell), T, mortar_shell), travel_time)
addtimer(CALLBACK(src, PROC_REF(handle_shell), hit_turf, mortar_shell), travel_time)

if(HAS_TRAIT(O, TRAIT_TOOL_WRENCH))
if(HAS_TRAIT(item, TRAIT_TOOL_WRENCH))
if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_TRAINED))
to_chat(user, SPAN_WARNING("You don't have the training to undeploy [src]."))
return
Expand All @@ -287,11 +296,11 @@
user.visible_message(SPAN_NOTICE("[user] undeploys [src]."), \
SPAN_NOTICE("You undeploy [src]."))
playsound(loc, 'sound/items/Deconstruct.ogg', 25, 1)
var/obj/item/mortar_kit/M = new /obj/item/mortar_kit(loc)
M.name = src.name
var/obj/item/mortar_kit/mortar = new /obj/item/mortar_kit(loc)
mortar.name = src.name
qdel(src)

if(HAS_TRAIT(O, TRAIT_TOOL_SCREWDRIVER))
if(HAS_TRAIT(item, TRAIT_TOOL_SCREWDRIVER))
if(do_after(user, 1 SECONDS, INTERRUPT_ALL|BEHAVIOR_IMMOBILE, BUSY_ICON_BUILD))
user.visible_message(SPAN_NOTICE("[user] toggles the targeting computer on [src]."), \
SPAN_NOTICE("You toggle the targeting computer on [src]."))
Expand All @@ -303,41 +312,59 @@
if(EXPLOSION_THRESHOLD_MEDIUM to INFINITY)
qdel(src)

/obj/effect/mortar_effect
icon = 'icons/obj/structures/mortar.dmi'
icon_state = "mortar_ammo_custom"
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
invisibility = INVISIBILITY_MAXIMUM

/obj/structure/mortar/proc/handle_shell(turf/target, obj/item/mortar_shell/shell)
if(protected_by_pylon(TURF_PROTECTION_MORTAR, target))
firing = FALSE
return

playsound(target, 'sound/weapons/gun_mortar_travel.ogg', 50, 1)
var/relative_dir
for(var/mob/M in range(15, target))
if(get_turf(M) == target)
relative_dir = 0
else
relative_dir = Get_Compass_Dir(M, target)
M.show_message( \
SPAN_DANGER("A SHELL IS COMING DOWN [SPAN_UNDERLINE(relative_dir ? uppertext(("TO YOUR " + dir2text(relative_dir))) : uppertext("right above you"))]!"), SHOW_MESSAGE_VISIBLE, \
SPAN_DANGER("YOU HEAR SOMETHING COMING DOWN [SPAN_UNDERLINE(relative_dir ? uppertext(("TO YOUR " + dir2text(relative_dir))) : uppertext("right above you"))]!"), SHOW_MESSAGE_AUDIBLE \
)
sleep(2.5 SECONDS) // Sleep a bit to give a message
for(var/mob/M in range(10, target))
if(get_turf(M) == target)
relative_dir = 0
else
relative_dir = Get_Compass_Dir(M, target)
M.show_message( \
SPAN_HIGHDANGER("A SHELL IS ABOUT TO IMPACT [SPAN_UNDERLINE(relative_dir ? uppertext(("TO YOUR " + dir2text(relative_dir))) : uppertext("right above you"))]!"), SHOW_MESSAGE_VISIBLE, \
SPAN_HIGHDANGER("YOU HEAR SOMETHING VERY CLOSE COMING DOWN [SPAN_UNDERLINE(relative_dir ? uppertext(("TO YOUR " + dir2text(relative_dir))) : uppertext("right above you"))]!"), SHOW_MESSAGE_AUDIBLE \
)
sleep(2 SECONDS) // Wait out the rest of the landing time
target.ceiling_debris_check(2)
if(!protected_by_pylon(TURF_PROTECTION_MORTAR, target))
shell.detonate(target)
qdel(shell)
firing = FALSE
if(ship_side)
var/turf/our_turf = get_turf(src)
shell.detonate(our_turf)
else
if(istype(shell, /obj/item/mortar_shell/custom)) // big shell warning for ghosts
var/obj/effect/effect = new /obj/effect/mortar_effect(target)
QDEL_IN(effect, 5 SECONDS)
notify_ghosts(header = "Custom Shell", message = "A custom mortar shell is about to land at [get_area(target)].", source = effect)

playsound(target, 'sound/weapons/gun_mortar_travel.ogg', 50, 1)
var/relative_dir
for(var/mob/mob in range(15, target))
if(get_turf(mob) == target)
relative_dir = 0
else
relative_dir = Get_Compass_Dir(mob, target)
mob.show_message( \
SPAN_DANGER("A SHELL IS COMING DOWN [SPAN_UNDERLINE(relative_dir ? uppertext(("TO YOUR " + dir2text(relative_dir))) : uppertext("right above you"))]!"), SHOW_MESSAGE_VISIBLE, \
SPAN_DANGER("YOU HEAR SOMETHING COMING DOWN [SPAN_UNDERLINE(relative_dir ? uppertext(("TO YOUR " + dir2text(relative_dir))) : uppertext("right above you"))]!"), SHOW_MESSAGE_AUDIBLE \
)
sleep(2.5 SECONDS) // Sleep a bit to give a message
for(var/mob/mob in range(10, target))
if(get_turf(mob) == target)
relative_dir = 0
else
relative_dir = Get_Compass_Dir(mob, target)
mob.show_message( \
SPAN_HIGHDANGER("A SHELL IS ABOUT TO IMPACT [SPAN_UNDERLINE(relative_dir ? uppertext(("TO YOUR " + dir2text(relative_dir))) : uppertext("right above you"))]!"), SHOW_MESSAGE_VISIBLE, \
SPAN_HIGHDANGER("YOU HEAR SOMETHING VERY CLOSE COMING DOWN [SPAN_UNDERLINE(relative_dir ? uppertext(("TO YOUR " + dir2text(relative_dir))) : uppertext("right above you"))]!"), SHOW_MESSAGE_AUDIBLE \
)
sleep(2 SECONDS) // Wait out the rest of the landing time
target.ceiling_debris_check(2)
if(!protected_by_pylon(TURF_PROTECTION_MORTAR, target))
shell.detonate(target)
qdel(shell)
firing = FALSE

/obj/structure/mortar/proc/can_fire_at(mob/user, test_targ_x = targ_x, test_targ_y = targ_y, test_dial_x, test_dial_y)
var/dialing = test_dial_x || test_dial_y
if(ship_side)
to_chat(user, SPAN_WARNING("You cannot aim the mortar while on a ship."))
return FALSE
if(test_dial_x + test_targ_x > world.maxx || test_dial_x + test_targ_x < 0)
to_chat(user, SPAN_WARNING("You cannot [dialing ? "dial to" : "aim at"] this coordinate, it is outside of the area of operations."))
return FALSE
Expand Down Expand Up @@ -385,21 +412,23 @@
if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_TRAINED))
to_chat(user, SPAN_WARNING("You don't have the training to deploy [src]."))
return
if(!is_ground_level(deploy_turf.z))
to_chat(user, SPAN_WARNING("You cannot deploy [src] here."))
return
var/area/A = get_area(deploy_turf)
if(CEILING_IS_PROTECTED(A.ceiling, CEILING_PROTECTION_TIER_1))
var/area/area = get_area(deploy_turf)
if(CEILING_IS_PROTECTED(area.ceiling, CEILING_PROTECTION_TIER_1) && is_ground_level(deploy_turf.z))
to_chat(user, SPAN_WARNING("You probably shouldn't deploy [src] indoors."))
return
user.visible_message(SPAN_NOTICE("[user] starts deploying [src]."), \
SPAN_NOTICE("You start deploying [src]."))
playsound(deploy_turf, 'sound/items/Deconstruct.ogg', 25, 1)
if(do_after(user, 4 SECONDS, INTERRUPT_ALL|BEHAVIOR_IMMOBILE, BUSY_ICON_BUILD))
user.visible_message(SPAN_NOTICE("[user] deploys [src]."), \
SPAN_NOTICE("You deploy [src]."))
var/obj/structure/mortar/mortar = new /obj/structure/mortar(deploy_turf)
if(!is_ground_level(deploy_turf.z))
mortar.ship_side = TRUE
user.visible_message(SPAN_NOTICE("[user] deploys [src]."), \
SPAN_NOTICE("You deploy [src]. This is a bad idea."))
else
user.visible_message(SPAN_NOTICE("[user] deploys [src]."), \
SPAN_NOTICE("You deploy [src]."))
playsound(deploy_turf, 'sound/weapons/gun_mortar_unpack.ogg', 25, 1)
var/obj/structure/mortar/M = new /obj/structure/mortar(deploy_turf)
M.name = src.name
M.setDir(user.dir)
mortar.name = src.name
mortar.setDir(user.dir)
qdel(src)
Loading