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

Adds Watchtowers #7754

Open
wants to merge 39 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
0e01aec
a
Git-Nivrak Dec 6, 2024
6762e42
b
Git-Nivrak Dec 6, 2024
ab32443
c
Git-Nivrak Dec 6, 2024
3ad6920
d
Git-Nivrak Dec 6, 2024
b8cdc4e
tabs
Git-Nivrak Dec 6, 2024
31d2850
call parent
Git-Nivrak Dec 6, 2024
d533593
Update watchtower.dm
Git-Nivrak Dec 6, 2024
afa79ec
a
Git-Nivrak Dec 6, 2024
8c9754a
fixes
Git-Nivrak Dec 6, 2024
e66f671
polish
Git-Nivrak Dec 6, 2024
4c5d444
can't build under roof
Git-Nivrak Dec 6, 2024
0702a87
Update girders.dm
Git-Nivrak Dec 6, 2024
cfa5cb4
macros xd
Git-Nivrak Dec 6, 2024
8bbf870
Update girders.dm
Git-Nivrak Dec 7, 2024
f1b6800
replaces shitty blockers with tent blockers
Git-Nivrak Dec 7, 2024
e1caa54
removes space
Git-Nivrak Dec 7, 2024
8ad293d
remove unnecessary qdels
Git-Nivrak Dec 7, 2024
a7bc346
Update watchtower.dm
Git-Nivrak Dec 8, 2024
7cc81f9
rerun checks
Git-Nivrak Dec 8, 2024
86cf740
code review
Git-Nivrak Dec 9, 2024
bc3b88f
review2
Git-Nivrak Dec 9, 2024
bf0ed79
some fixes
Git-Nivrak Dec 10, 2024
848bb50
and a few more
Git-Nivrak Dec 10, 2024
f9b80bd
fixes binocs and linter
Git-Nivrak Dec 10, 2024
8140500
remember to unregister signals
Git-Nivrak Dec 10, 2024
5883639
fixes binoculars
Git-Nivrak Dec 10, 2024
c49bf02
linter moment
Git-Nivrak Dec 10, 2024
127fe8c
fixes layering issues
Git-Nivrak Dec 10, 2024
770a00f
More changes and fixes
Git-Nivrak Dec 10, 2024
37c3542
fixes dirlock for harry
Git-Nivrak Dec 11, 2024
14a79ee
fixes a bug with drag pulling
Git-Nivrak Dec 14, 2024
7c00cc4
Update girders.dm
Git-Nivrak Dec 17, 2024
c67a68d
Apply suggestions from code review
Git-Nivrak Dec 17, 2024
6147957
Update watchtower.dm
Git-Nivrak Dec 18, 2024
3598bc0
review
Git-Nivrak Dec 28, 2024
1c2c49d
fixes
Git-Nivrak Dec 28, 2024
9a5921d
cherry on top
Git-Nivrak Dec 28, 2024
b030df6
sprite fixes
Git-Nivrak Jan 24, 2025
2ca0706
Merge branch 'master' into watchtower
Git-Nivrak Jan 24, 2025
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
3 changes: 3 additions & 0 deletions code/__DEFINES/traits.dm
Original file line number Diff line number Diff line change
Expand Up @@ -509,3 +509,6 @@ GLOBAL_LIST(trait_name_map)
#define HACKED_TRAIT "hacked"
/// traits from chloroform usage
#define CHLOROFORM_TRAIT "chloroform"

// from watchtower.dm
#define TRAIT_ON_WATCHTOWER "on_watchtower"
24 changes: 24 additions & 0 deletions code/datums/elements/bullet_trait/direct_only.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// This trait makes the projectile only hit targets directly clicked

/datum/element/bullet_trait_direct_only
// General bullet trait vars
element_flags = ELEMENT_DETACH|ELEMENT_BESPOKE
id_arg_index = 2

/datum/element/bullet_trait_direct_only/Attach(datum/target)
. = ..()
if(!istype(target, /obj/projectile))
return ELEMENT_INCOMPATIBLE

RegisterSignal(target, COMSIG_BULLET_CHECK_MOB_SKIPPING, PROC_REF(check_distance))

/datum/element/bullet_trait_direct_only/Detach(datum/target)
UnregisterSignal(target, COMSIG_BULLET_CHECK_MOB_SKIPPING)

return ..()

/datum/element/bullet_trait_direct_only/proc/check_distance(obj/projectile/P, mob/living/carbon/human/projectile_target)
SIGNAL_HANDLER

if(P.original != projectile_target)
Git-Nivrak marked this conversation as resolved.
Show resolved Hide resolved
return COMPONENT_SKIP_MOB
29 changes: 29 additions & 0 deletions code/game/objects/structures/girders.dm
Git-Nivrak marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,28 @@
if(STATE_REINFORCED_WALL)
return do_reinforced_wall(W, user)
if(STATE_DISPLACED)
if(HAS_TRAIT(W, TRAIT_TOOL_BLOWTORCH))
var/list/turf/turfs = CORNER_BLOCK(get_turf(src), 2, 2)
var/list/obj/structure/girder/girders = list()

for(var/turf/current_turf in turfs)
var/found_girder = FALSE
for(var/obj/structure/girder/girder in current_turf)
if(girder.state == STATE_DISPLACED)
found_girder = TRUE
girders += girder
if(!found_girder)
return


if(!do_after(user,30, INTERRUPT_ALL|BEHAVIOR_IMMOBILE, BUSY_ICON_BUILD))
Git-Nivrak marked this conversation as resolved.
Show resolved Hide resolved
return

new /obj/structure/watchtower(loc)

for(var/list/obj/structure/girder as anything in girders)
qdel(girder)

if(HAS_TRAIT(W, TRAIT_TOOL_CROWBAR))
var/turf/open/floor = loc
if(!floor.allow_construction)
Expand Down Expand Up @@ -393,6 +415,13 @@
anchored = FALSE
state = STATE_DISPLACED

/obj/structure/girder/broken
health = 0
icon_state = "girder_damaged"
anchored = FALSE
density = FALSE
state = STATE_STANDARD

/obj/structure/girder/reinforced
icon_state = "reinforced"
health = 500
Expand Down
283 changes: 283 additions & 0 deletions code/modules/watchtower/watchtower.dm
Git-Nivrak marked this conversation as resolved.
Show resolved Hide resolved
Git-Nivrak marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,283 @@
/obj/structure/watchtower
name = "watchtower"
icon = 'icons/obj/structures/watchtower.dmi'
icon_state = "stage1"

density = FALSE
bound_width = 64
bound_height = 96

var/stage = 1
var/image/roof_image

/obj/structure/watchtower/Initialize()
var/list/turf/top_turfs = CORNER_BLOCK_OFFSET(get_turf(src), 2, 1, 0, 1)
var/list/turf/blocked_turfs = CORNER_BLOCK(get_turf(src), 2, 1) + CORNER_BLOCK_OFFSET(get_turf(src), 2, 1, 0, 2)
var/list/turf/bottom_turfs = CORNER_OUTLINE(get_turf(src), 2, 3)

for(var/turf/current_turf in top_turfs)
new /obj/structure/blocker/invisible_wall/watchtower(current_turf)

for(var/turf/current_turf in bottom_turfs)
new /obj/structure/blocker/invisible_wall/watchtower/inverse(current_turf)

for(var/turf/current_turf in blocked_turfs)
new /obj/structure/blocker/invisible_wall/throwpass(current_turf)

update_icon()

return ..()

/obj/structure/watchtower/Destroy()
playsound(src, 'sound/effects/metal_crash.ogg', 50, 1)
var/list/turf/all_turfs = CORNER_BLOCK(get_turf(src), 2, 3) + CORNER_OUTLINE(get_turf(src), 2, 3)

for(var/turf/current_turf in all_turfs)
for(var/obj/structure/blocker/invisible_wall in current_turf.contents)
qdel(invisible_wall)

var/list/turf/top_turfs = CORNER_BLOCK_OFFSET(get_turf(src), 2, 1, 0, 1)

for(var/turf/current_turf in top_turfs)
for(var/mob/falling_mob in current_turf.contents)
if(falling_mob.client)
falling_mob.client.change_view(falling_mob.client.view - 2)
var/atom/movable/screen/plane_master/roof/roof_plane = falling_mob.hud_used.plane_masters["[ROOF_PLANE]"]
roof_plane?.invisibility = 0
for(var/obj/item/weapon/gun/gun in falling_mob)
gun.remove_bullet_traits(list("watchtower_arc"))
falling_mob.ex_act(100, 0)

new /obj/structure/girder(get_turf(src))
new /obj/structure/girder/broken(locate(x+1, y, z))
new /obj/structure/girder/broken(locate(x, y+1, z))
new /obj/item/stack/sheet/metal(locate(x+1, y+1, z), 10)
new /obj/item/stack/rods(locate(x+1, y+1, z), 20)

return ..()

/obj/structure/watchtower/update_icon()
. = ..()
icon_state = "stage[stage]"

overlays.Cut()

if(stage >= 5)
overlays += image(icon=icon, icon_state="railings", layer=ABOVE_MOB_LAYER, pixel_y=25)

if (stage == 7)
roof_image = image(icon=icon, icon_state="roof", layer=ABOVE_MOB_LAYER, pixel_y=51)
roof_image.plane = ROOF_PLANE
roof_image.appearance_flags = KEEP_APART
overlays += roof_image

/obj/structure/watchtower/attackby(obj/item/W, mob/user)
if(istool(W) && !skillcheck(user, SKILL_CONSTRUCTION, SKILL_CONSTRUCTION_ENGI))
to_chat(user, SPAN_WARNING("You are not trained to configure [src]..."))
return TRUE

switch(stage)
Git-Nivrak marked this conversation as resolved.
Show resolved Hide resolved
if(1)
if(!istype(W, /obj/item/stack/rods))
return

var/obj/item/stack/rods/rods = W
Git-Nivrak marked this conversation as resolved.
Show resolved Hide resolved

if(!do_after(user, 40 * user.get_skill_duration_multiplier(SKILL_CONSTRUCTION), INTERRUPT_NO_NEEDHAND|BEHAVIOR_IMMOBILE, BUSY_ICON_FRIENDLY, src))
return

if(rods.use(60))
to_chat(user, SPAN_NOTICE("You add connection rods to the watchtower."))
stage = 2
update_icon()
else
to_chat(user, SPAN_NOTICE("You failed to construct the connection rods. You need more rods."))

return
if(2)
Git-Nivrak marked this conversation as resolved.
Show resolved Hide resolved
if(!iswelder(W))
return

if(!HAS_TRAIT(W, TRAIT_TOOL_BLOWTORCH))
to_chat(user, SPAN_WARNING("You need a stronger blowtorch!"))
return

if(!do_after(user,30, INTERRUPT_ALL|BEHAVIOR_IMMOBILE, BUSY_ICON_BUILD))
return

to_chat(user, SPAN_NOTICE("You weld the connection rods to the frame."))
stage = 2.5

return
if(2.5)
if(!HAS_TRAIT(W, TRAIT_TOOL_WRENCH))
return

if(!do_after(user,30, INTERRUPT_ALL|BEHAVIOR_IMMOBILE, BUSY_ICON_BUILD))
return

to_chat(user, SPAN_NOTICE("You elevate the the frame and screw it up top."))
stage = 3
update_icon()

return
if(3)
if(!HAS_TRAIT(W, TRAIT_TOOL_SCREWDRIVER))
return

var/obj/item/stack/sheet/metal/metal = user.get_inactive_hand()
if(!istype(metal))
to_chat(user, SPAN_BOLDWARNING("You need metal sheets in your offhand to continue construction of the watchtower."))
return FALSE

if(!do_after(user,30, INTERRUPT_ALL|BEHAVIOR_IMMOBILE, BUSY_ICON_BUILD))
return

if(metal.use(50))
to_chat(user, SPAN_NOTICE("You construct the watchtower platform."))
stage = 4
update_icon()
else
to_chat(user, SPAN_NOTICE("You failed to construct the watchtower platform, you need more metal sheets in your offhand."))

return
if(4)
if(!HAS_TRAIT(W, TRAIT_TOOL_CROWBAR))
return

var/obj/item/stack/sheet/plasteel/plasteel = user.get_inactive_hand()
if(!istype(plasteel))
to_chat(user, SPAN_BOLDWARNING("You need plasteel sheets in your offhand to continue construction of the watchtower."))
return FALSE

if(!do_after(user,30, INTERRUPT_ALL|BEHAVIOR_IMMOBILE, BUSY_ICON_BUILD))
return

if(plasteel.use(25))
to_chat(user, SPAN_NOTICE("You construct the watchtower railing."))
stage = 5
update_icon()
else
to_chat(user, SPAN_NOTICE("You failed to construct the watchtower railing, you need more plasteel sheets in your offhand."))

return
if(5)
if (!HAS_TRAIT(W, TRAIT_TOOL_WRENCH))
return

var/obj/item/stack/rods/rods = user.get_inactive_hand()
if(!istype(rods))
to_chat(user, SPAN_BOLDWARNING("You need metal rods in your offhand to continue construction of the watchtower."))
return FALSE

if(!do_after(user,30, INTERRUPT_ALL|BEHAVIOR_IMMOBILE, BUSY_ICON_BUILD))
return

if(rods.use(60))
to_chat(user, SPAN_NOTICE("You construct the watchtower support rods."))
stage = 6
update_icon()
else
to_chat(user, SPAN_NOTICE("You failed to construct the watchtower support rods, you need more metal rods in your offhand."))

return
if(6)
if (!iswelder(W))
return

if(!HAS_TRAIT(W, TRAIT_TOOL_BLOWTORCH))
to_chat(user, SPAN_WARNING("You need a stronger blowtorch!"))
return

var/obj/item/stack/sheet/plasteel/plasteel = user.get_inactive_hand()
if(!istype(plasteel))
to_chat(user, SPAN_BOLDWARNING("You need plasteel sheets in your offhand to continue construction of the watchtower."))
return FALSE

if(!do_after(user,30, INTERRUPT_ALL|BEHAVIOR_IMMOBILE, BUSY_ICON_BUILD))
return

if(plasteel.use(25))
to_chat(user, SPAN_NOTICE("You complete the watchtower."))
stage = 7
update_icon()


else
to_chat(user, SPAN_NOTICE("You failed to complete the watchtower, you need more plasteel sheets in your offhand."))

return

/obj/structure/watchtower/attack_hand(mob/user)
if(get_turf(user) == locate(x, y-1, z))
if(!do_after(user,30, INTERRUPT_ALL|BEHAVIOR_IMMOBILE, BUSY_ICON_BUILD))
Git-Nivrak marked this conversation as resolved.
Show resolved Hide resolved
return

var/turf/actual_turf = locate(x, y+1, z)
ADD_TRAIT(user, TRAIT_ON_WATCHTOWER, "watchtower")
user.forceMove(actual_turf)
user.client.change_view(user.client.view + 2)
var/atom/movable/screen/plane_master/roof/roof_plane = user.hud_used.plane_masters["[ROOF_PLANE]"]
roof_plane?.invisibility = INVISIBILITY_MAXIMUM
for(var/obj/item/weapon/gun/gun in user)
gun.add_bullet_traits(list(BULLET_TRAIT_ENTRY_ID("watchtower_arc", /datum/element/bullet_trait_direct_only)))
else if(get_turf(user) == locate(x, y+1, z))
if(!do_after(user,30, INTERRUPT_ALL|BEHAVIOR_IMMOBILE, BUSY_ICON_BUILD))
return

REMOVE_TRAIT(user, TRAIT_ON_WATCHTOWER, "watchtower")
var/turf/actual_turf = locate(x, y-1, z)
user.forceMove(actual_turf)
user.client.change_view(user.client.view - 2)
var/atom/movable/screen/plane_master/roof/roof_plane = user.hud_used.plane_masters["[ROOF_PLANE]"]
roof_plane?.invisibility = 0
for(var/obj/item/weapon/gun/gun in user)
Git-Nivrak marked this conversation as resolved.
Show resolved Hide resolved
gun.remove_bullet_traits(list("watchtower_arc"))

/obj/structure/watchtower/attack_alien(mob/living/carbon/xenomorph/xeno)
if (xeno.mob_size < MOB_SIZE_BIG)
return

if(!do_after(xeno, 100, INTERRUPT_ALL|BEHAVIOR_IMMOBILE, BUSY_ICON_HOSTILE))
return

qdel(src)

/obj/structure/blocker/invisible_wall/throwpass
throwpass = TRUE

/obj/structure/blocker/invisible_wall/watchtower
throwpass = TRUE

/obj/structure/blocker/invisible_wall/watchtower/Collided(atom/movable/AM)
if(HAS_TRAIT(AM, TRAIT_ON_WATCHTOWER))
AM.forceMove(get_turf(src))

/obj/structure/blocker/invisible_wall/watchtower/inverse

/obj/structure/blocker/invisible_wall/watchtower/inverse/Collided(atom/movable/AM)
if(!HAS_TRAIT(AM, TRAIT_ON_WATCHTOWER))
AM.forceMove(get_turf(src))

// For Mappers
/obj/structure/watchtower/stage1
stage = 1
icon_state = "stage1"
/obj/structure/watchtower/stage2
stage = 2
icon_state = "stage2"
/obj/structure/watchtower/stage3
stage = 3
icon_state = "stage3"
/obj/structure/watchtower/stage4
stage = 4
icon_state = "stage4"
/obj/structure/watchtower/stage5
stage = 5
icon_state = "stage5"
/obj/structure/watchtower/stage6
stage = 6
icon_state = "stage6"
/obj/structure/watchtower/complete
stage = 7
icon_state = "stage7

Check failure on line 283 in code/modules/watchtower/watchtower.dm

View workflow job for this annotation

GitHub Actions / Run Linters

unterminated string literal
2 changes: 2 additions & 0 deletions colonialmarines.dme
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,7 @@
#include "code\datums\elements\suturing.dm"
#include "code\datums\elements\yautja_tracked_item.dm"
#include "code\datums\elements\bullet_trait\damage_boost.dm"
#include "code\datums\elements\bullet_trait\direct_only.dm"
#include "code\datums\elements\bullet_trait\iff.dm"
#include "code\datums\elements\bullet_trait\ignored_range.dm"
#include "code\datums\elements\bullet_trait\incendiary.dm"
Expand Down Expand Up @@ -2523,6 +2524,7 @@
#include "code\modules\vox\vox_tgui.dm"
#include "code\modules\vox\vox_sounds\vox.dm"
#include "code\modules\vox\vox_sounds\vox_military.dm"
#include "code\modules\watchtower\watchtower.dm"
#include "interface\fonts.dm"
#include "interface\interface.dm"
#include "interface\skin.dmf"
Expand Down
Binary file added icons/obj/structures/watchtower.dmi
Binary file not shown.
Loading