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

Ports Baystation Click Handling & Build Mode #18896

Merged
merged 9 commits into from
Apr 13, 2024
Merged
Show file tree
Hide file tree
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
13 changes: 12 additions & 1 deletion aurorastation.dme
Original file line number Diff line number Diff line change
Expand Up @@ -1468,6 +1468,18 @@
#include "code\modules\admin\stickyban.dm"
#include "code\modules\admin\ticket.dm"
#include "code\modules\admin\topic.dm"
#include "code\modules\admin\buildmode\advanced.dm"
#include "code\modules\admin\buildmode\basic.dm"
#include "code\modules\admin\buildmode\buildmode.dm"
#include "code\modules\admin\buildmode\buttons.dm"
#include "code\modules\admin\buildmode\click_handler.dm"
#include "code\modules\admin\buildmode\edit.dm"
#include "code\modules\admin\buildmode\ladders.dm"
#include "code\modules\admin\buildmode\light_maker.dm"
#include "code\modules\admin\buildmode\move_into.dm"
#include "code\modules\admin\buildmode\relocate_to.dm"
#include "code\modules\admin\buildmode\room_builder.dm"
#include "code\modules\admin\buildmode\throw_at.dm"
#include "code\modules\admin\callproc\callproc.dm"
#include "code\modules\admin\DB ban\ban_mirroring.dm"
#include "code\modules\admin\DB ban\functions.dm"
Expand Down Expand Up @@ -1515,7 +1527,6 @@
#include "code\modules\admin\verbs\atmosdebug.dm"
#include "code\modules\admin\verbs\bluespacetech.dm"
#include "code\modules\admin\verbs\BrokenInhands.dm"
#include "code\modules\admin\verbs\buildmode.dm"
#include "code\modules\admin\verbs\cinematic.dm"
#include "code\modules\admin\verbs\clear_toxins.dm"
#include "code\modules\admin\verbs\custom_event.dm"
Expand Down
8 changes: 0 additions & 8 deletions code/_onclick/ai.dm
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,6 @@
Note that AI have no need for the adjacency proc, and so this proc is a lot cleaner.
*/
/mob/living/silicon/ai/DblClickOn(var/atom/A, params)
if(client.buildmode) // comes after object.Click to allow buildmode gui objects to be clicked
build_click(src, client.buildmode, params, A)
return

if(control_disabled || stat) return

if(ismob(A))
Expand All @@ -27,10 +23,6 @@
return
next_click = world.time + 1

if(client.buildmode) // comes after object.Click to allow buildmode gui objects to be clicked
build_click(src, client.buildmode, params, A)
return

if(stat)
return

Expand Down
115 changes: 102 additions & 13 deletions code/_onclick/click.dm
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@
*/

/atom/Click(location,control,params)
if(src)
usr.ClickOn(src, params)
var/datum/click_handler/click_handler = usr.GetClickHandler()
click_handler.OnClick(src, params)

/atom/DblClick(var/location, var/control, var/params)
if(src)
usr.DblClickOn(src, params)
var/datum/click_handler/click_handler = usr.GetClickHandler()
click_handler.OnDblClick(src, params)

/atom/proc/allow_click_through(var/atom/A, var/params, var/mob/user)
return FALSE
Expand All @@ -36,10 +36,6 @@
/mob/proc/OnMouseDrag(src_object, over_object, src_location, over_location, src_control, over_control, params)
if(istype(loc, /atom))
var/atom/A = loc
if(client && client.buildmode)
build_click(src, client.buildmode, params, A)
return

if(A.RelayMouseDrag(src_object, over_object, src_location, over_location, src_control, over_control, params, src))
return

Expand All @@ -52,7 +48,7 @@

/**
* Standard mob ClickOn()
* Handles exceptions: Buildmode, middle click, modified clicks, mech actions
* Handles exceptions: middle click, modified clicks, mech actions
*
* After that, mostly just check your state, check whether you're holding an item,
* check whether you're adjacent to the target, then pass off the click to whoever
Expand Down Expand Up @@ -82,10 +78,6 @@
return
return B.ClickOn(A, params)

if(client && client.buildmode)
build_click(src, client.buildmode, params, A)
return

var/list/modifiers = params2list(params)
if(modifiers["shift"] && modifiers["ctrl"])
CtrlShiftClickOn(A)
Expand Down Expand Up @@ -422,3 +414,100 @@ var/global/list/click_catchers
set hidden = 1
set name = ".mouse"
LogMouseMacro(".mouse", params)

/*
Custom Click Handlinig
*/

/mob
var/datum/stack/click_handlers

/mob/Destroy()
if(click_handlers)
click_handlers.QdelClear()
QDEL_NULL(click_handlers)
. = ..()

var/const/CLICK_HANDLER_NONE = 0
var/const/CLICK_HANDLER_REMOVE_ON_MOB_LOGOUT = 1
var/const/CLICK_HANDLER_ALL = (~0)

/datum/click_handler
var/mob/user
var/handler_flags = CLICK_HANDLER_NONE

/datum/click_handler/New(mob/user)
..()
src.user = user
if(handler_flags & CLICK_HANDLER_REMOVE_ON_MOB_LOGOUT)
RegisterSignal(user, COMSIG_MOB_LOGOUT, /datum/click_handler/proc/OnMobLogout, TRUE)

/datum/click_handler/Destroy()
if(handler_flags & CLICK_HANDLER_REMOVE_ON_MOB_LOGOUT)
UnregisterSignal(user, COMSIG_MOB_LOGOUT)
user = null
. = ..()

/datum/click_handler/proc/Enter()
return

/datum/click_handler/proc/Exit()
return


/datum/click_handler/proc/OnMobLogout()
user.RemoveClickHandler(src)

/datum/click_handler/proc/OnClick(var/atom/A, var/params)
return

/datum/click_handler/proc/OnDblClick(var/atom/A, var/params)
return

/datum/click_handler/default/OnClick(var/atom/A, var/params)
user.ClickOn(A, params)

/datum/click_handler/default/OnDblClick(var/atom/A, var/params)
user.DblClickOn(A, params)

/mob/proc/GetClickHandler(var/datum/click_handler/popped_handler)
if(!click_handlers)
click_handlers = new()
if(click_handlers.is_empty())
PushClickHandler(/datum/click_handler/default)
return click_handlers.Top()

/mob/proc/RemoveClickHandler(var/datum/click_handler/click_handler)
if(!click_handlers)
return

var/was_top = click_handlers.Top() == click_handler

if(was_top)
click_handler.Exit()
click_handlers.Remove(click_handler)
qdel(click_handler)

if(!was_top)
return
click_handler = click_handlers.Top()
if(click_handler)
click_handler.Enter()

/mob/proc/PopClickHandler()
if(!click_handlers)
return
RemoveClickHandler(click_handlers.Top())

/mob/proc/PushClickHandler(var/datum/click_handler/new_click_handler_type)
if((initial(new_click_handler_type.handler_flags) & CLICK_HANDLER_REMOVE_ON_MOB_LOGOUT) && !client)
return FALSE
if(!click_handlers)
click_handlers = new()
var/datum/click_handler/click_handler = click_handlers.Top()
if(click_handler)
click_handler.Exit()

click_handler = new new_click_handler_type(src)
click_handler.Enter()
click_handlers.Push(click_handler)
4 changes: 0 additions & 4 deletions code/_onclick/cyborg.dm
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,6 @@
return
next_click = world.time + 1

if(client.buildmode) // comes after object.Click to allow buildmode gui objects to be clicked
build_click(src, client.buildmode, params, A)
return

var/list/modifiers = params2list(params)
if(modifiers["shift"] && modifiers["ctrl"])
CtrlShiftClickOn(A)
Expand Down
6 changes: 0 additions & 6 deletions code/_onclick/observer.dm
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,6 @@
to_chat(src, "<span class='notice'>You will no longer examine things you click on.</span>")

/mob/abstract/observer/DblClickOn(var/atom/A, var/params)
if(client.buildmode)
build_click(src, client.buildmode, params, A)
return
if(can_reenter_corpse && mind && mind.current)
if(A == mind.current || (mind.current in A)) // double click your corpse or whatever holds it
reenter_corpse() // (cloning scanner, body bag, closet, mech, etc)
Expand All @@ -29,9 +26,6 @@
forceMove(get_turf(A))

/mob/abstract/observer/ClickOn(var/atom/A, var/params)
if(client.buildmode)
build_click(src, client.buildmode, params, A)
return
if(!canClick()) return
setClickCooldown(4)
// You are responsible for checking config.ghost_interaction when you override this function
Expand Down
10 changes: 8 additions & 2 deletions code/modules/admin/admin_verbs.dm
Original file line number Diff line number Diff line change
Expand Up @@ -746,8 +746,14 @@ var/list/admin_verbs_cciaa = list(
/client/proc/togglebuildmodeself()
set name = "Toggle Build Mode Self"
set category = "Special Verbs"
if(src.mob)
togglebuildmode(src.mob)

if(!check_rights(R_ADMIN))
return
var/datum/click_handler/handler = mob.GetClickHandler()
if(handler.type == /datum/click_handler/build_mode)
usr.PopClickHandler()
else
usr.PushClickHandler(/datum/click_handler/build_mode)
feedback_add_details("admin_verb","TBMS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!

/client/proc/object_talk(var/msg as text) // -- TLE
Expand Down
46 changes: 46 additions & 0 deletions code/modules/admin/buildmode/advanced.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/datum/build_mode/advanced
name = "Advanced"
icon_state = "buildmode2"
var/build_type

/datum/build_mode/advanced/Help()
to_chat(user, SPAN_NOTICE("***********************************************************"))
to_chat(user, SPAN_NOTICE("Left Click = Create objects"))
to_chat(user, SPAN_NOTICE("Right Click = Delete objects"))
to_chat(user, SPAN_NOTICE("Left Click + Ctrl = Capture object type"))
to_chat(user, SPAN_NOTICE("Middle Click = Capture object type"))
to_chat(user, SPAN_NOTICE("Right Click on Build Mode Button = Select object type"))
to_chat(user, "")
to_chat(user, SPAN_NOTICE("Use the directional button in the upper left corner to"))
to_chat(user, SPAN_NOTICE("change the direction of built objects."))
to_chat(user, SPAN_NOTICE("***********************************************************"))

/datum/build_mode/advanced/Configurate()
SetBuildType(select_subpath(build_type || /obj/structure/closet))

/datum/build_mode/advanced/OnClick(var/atom/A, var/list/parameters)
if(parameters["left"] && !parameters["ctrl"])
if(ispath(build_type,/turf))
var/turf/T = get_turf(A)
T.ChangeTurf(build_type)
else if(ispath(build_type))
var/atom/new_atom = new build_type (get_turf(A))
new_atom.set_dir(host.dir)
Log("Created - [log_info_line(new_atom)]")
else
to_chat(user, SPAN_NOTICE("Select a type to construct."))
else if(parameters["right"])
Log("Deleted - [log_info_line(A)]")
qdel(A)
else if((parameters["left"] && parameters["ctrl"]) || parameters["middle"])
SetBuildType(A.type)

/datum/build_mode/advanced/proc/SetBuildType(var/atom_type)
if(!atom_type || atom_type == build_type)
return

if(ispath(atom_type, /atom))
build_type = atom_type
to_chat(user, SPAN_NOTICE("Will now construct instances of the type [atom_type]."))
else
to_chat(user, SPAN_WARNING("Cannot construct instances of type [atom_type]."))
70 changes: 70 additions & 0 deletions code/modules/admin/buildmode/basic.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/datum/build_mode/basic
the_default = TRUE
name = "Basic"
icon_state = "buildmode1"

/datum/build_mode/basic/Help()
to_chat(user, SPAN_NOTICE("***********************************************************"))
to_chat(user, SPAN_NOTICE("Left Click = Construct / Upgrade"))
to_chat(user, SPAN_NOTICE("Right Click = Deconstruct / Delete / Downgrade"))
to_chat(user, SPAN_NOTICE("Left Click + Ctrl = R-Window"))
to_chat(user, SPAN_NOTICE("Left Click + Alt = Airlock"))
to_chat(user, "")
to_chat(user, SPAN_NOTICE("Use the directional button in the upper left corner to"))
to_chat(user, SPAN_NOTICE("change the direction of built objects."))
to_chat(user, SPAN_NOTICE("***********************************************************"))

/datum/build_mode/basic/OnClick(var/atom/object, var/list/pa)
if(istype(object,/turf) && pa["left"] && !pa["alt"] && !pa["ctrl"] )
if(istype(object,/turf/space))
var/turf/T = object
Log("Upgraded - [log_info_line(object)]")
T.ChangeTurf(/turf/simulated/floor)
return
else if(istype(object,/turf/simulated/floor))
var/turf/T = object
Log("Upgraded - [log_info_line(object)]")
T.ChangeTurf(/turf/simulated/wall)
return
else if(istype(object,/turf/simulated/wall))
var/turf/T = object
Log("Upgraded - [log_info_line(object)]")
T.ChangeTurf(/turf/simulated/wall/r_wall)
return
else if(pa["right"])
if(istype(object,/turf/simulated/wall))
var/turf/T = object
Log("Downgraded - [log_info_line(object)]")
T.ChangeTurf(/turf/simulated/floor)
return
else if(istype(object,/turf/simulated/floor))
var/turf/T = object
Log("Downgraded - [log_info_line(object)]")
T.ChangeTurf(/turf/space)
return
else if(istype(object,/turf/simulated/wall/r_wall))
var/turf/T = object
Log("Downgraded - [log_info_line(object)]")
T.ChangeTurf(/turf/simulated/wall)
return
else if(istype(object,/obj))
Log("Deleted - [log_info_line(object)]")
qdel(object)
return
else if(istype(object,/turf) && pa["alt"] && pa["left"])
var/airlock = new/obj/machinery/door/airlock(get_turf(object))
Log("Created - [log_info_line(airlock)]")
else if(istype(object,/turf) && pa["ctrl"] && pa["left"])
var/obj/structure/window/reinforced/WIN = new/obj/structure/window/reinforced(get_turf(object))
Log("Created - [log_info_line(object)]")
switch(host.dir)
if(NORTH)
WIN.set_dir(NORTH)
if(SOUTH)
WIN.set_dir(SOUTH)
if(EAST)
WIN.set_dir(EAST)
if(WEST)
WIN.set_dir(WEST)
if(NORTHWEST)
WIN.set_dir(NORTHWEST)
Loading
Loading