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

[MIRROR] Fixes issues with multitools on power objects #2714

Merged
merged 1 commit into from
Apr 3, 2024

Conversation

Steals-The-PRs
Copy link
Collaborator

Mirrored on Nova: NovaSector/NovaSector#1783
Original PR: tgstation/tgstation#82389

About The Pull Request

So at some point the power object's multitool_act(...) proc was set to always block, for what I could find to be no discernable reason.

The Main Thing

https://github.com/tgstation/tgstation/blob/d38f9385b863e49f83455a227764d302629e2867/code/modules/power/power.dm#L62-L74
Now, of course, it shouldn't, because this cuts the entire chain short and thus blocks any other multitool interactions. Like opening the wires panel with a multitool, in this case. Even if can_change_cable_layer were to be false and thus the object would never actually care about having this interaction, it'd still block it.

So we don't do that. But what do we do?
I decided to just split off the actual cable changing part into its own proc, cable_layer_act(...).

/obj/machinery/power/proc/cable_layer_act(mob/living/user, obj/item/tool)
	var/choice = tgui_input_list(user, "Select Power Line For Operation", "Select Cable Layer", GLOB.cable_name_to_layer)
	if(isnull(choice))
		return ITEM_INTERACT_BLOCKING

	cable_layer = GLOB.cable_name_to_layer[choice]
	balloon_alert(user, "now operating on the [choice]")
	return ITEM_INTERACT_SUCCESS

Which is then called on multitool_act(...), if can_change_cable_layer is true.

/obj/machinery/power/multitool_act(mob/living/user, obj/item/tool)
	if(can_change_cable_layer)
		return cable_layer_act(user, tool)

Which continues with the chain if we can't change layers by default, and otherwise lets cable_layer_act(...) work out whether we should block or continue.
Notably, we've removed the cable_layer_change_checks(...) proc from the equation, and just let inheritors override it to add their own preconditions and what flags they should return.
On its own this fixes the APC wire panel interactions, but also lets us just return NONE when we need to.

/obj/machinery/power/emitter/cable_layer_act(mob/living/user, obj/item/tool)
	if(panel_open)
		return NONE
	if(welded)
		balloon_alert(user, "unweld first!")
		return ITEM_INTERACT_BLOCKING
	return ..()

The OTHER Things

While doing this I noticed there's actually very little sanity checks after we close our input list.

var/choice = tgui_input_list(user, "Select Power Line For Operation", "Select Cable Layer", GLOB.cable_name_to_layer)
if(isnull(choice))
	return ITEM_INTERACT_BLOCKING

We only care about whether we made a choice!
Testing this, lo and behold, this can cause runtimes if the power object gets qdeleted before you close the menu.
As a funny side, it also doesn't care about whether you're on the other side of the station, while your multitool is on a different z-level, or just doesn't exist anymore.
So we just add a few basic sanity checks while we're at it.

var/choice = tgui_input_list(user, "Select Power Line For Operation", "Select Cable Layer", GLOB.cable_name_to_layer)
if(isnull(choice) || QDELETED(src) || QDELETED(user) || QDELETED(tool) || !user.Adjacent(src) || !user.is_holding(tool))
	return ITEM_INTERACT_BLOCKING

That's all. Having done some basic testing, I believe the behaviour is otherwise unaffected.

Why It's Good For The Game

It's annoying to need to swap to an empty hand or wirecutters to interact with APC, emitter, or tesla coil wires.
This fixes that. (Fixes #81745.)
...and then a few other tidbits I realized existed.

Changelog

🆑 00-Steven
fix: Fix using a multitool on a power object with wires not actually opening the wires menu when it should.
fix: Fix a runtime from a power object being deleted before selecting what cable layer to put it at.
fix: Fix power object cable changing not caring about whether you were still adjacent, still holding your multitool, or whether it even still existed after the selection menu was closed.
/:cl:

* Fixes issues with multitools on power objects (#82389)

## About The Pull Request

So at some point the power object's `multitool_act(...)` proc was set to
_always_ block, for what I could find to be no discernable reason.

### The Main Thing


https://github.com/tgstation/tgstation/blob/d38f9385b863e49f83455a227764d302629e2867/code/modules/power/power.dm#L62-L74
Now, of course, it shouldn't, because this cuts the entire chain short
and thus blocks any other multitool interactions. Like opening the wires
panel with a multitool, in this case. Even if `can_change_cable_layer`
were to be false and thus the object would never actually care about
having this interaction, it'd _still_ block it.

So we don't do that. But what _do_ we do?
I decided to just split off the actual cable changing part into its own
proc, `cable_layer_act(...)`.
```dm
/obj/machinery/power/proc/cable_layer_act(mob/living/user, obj/item/tool)
	var/choice = tgui_input_list(user, "Select Power Line For Operation", "Select Cable Layer", GLOB.cable_name_to_layer)
	if(isnull(choice))
		return ITEM_INTERACT_BLOCKING

	cable_layer = GLOB.cable_name_to_layer[choice]
	balloon_alert(user, "now operating on the [choice]")
	return ITEM_INTERACT_SUCCESS
```
Which is then called on `multitool_act(...)`, if
`can_change_cable_layer` is true.
```dm
/obj/machinery/power/multitool_act(mob/living/user, obj/item/tool)
	if(can_change_cable_layer)
		return cable_layer_act(user, tool)
```
Which continues with the chain if we can't change layers by default, and
otherwise lets `cable_layer_act(...)` work out whether we should block
or continue.
Notably, we've removed the `cable_layer_change_checks(...)` proc from
the equation, and just let inheritors override it to add their own
preconditions and what flags they should return.
On its own this fixes the APC wire panel interactions, but also lets us
just return `NONE` when we need to.
```dm
/obj/machinery/power/emitter/cable_layer_act(mob/living/user, obj/item/tool)
	if(panel_open)
		return NONE
	if(welded)
		balloon_alert(user, "unweld first!")
		return ITEM_INTERACT_BLOCKING
	return ..()
```

### The OTHER Things

While doing this I noticed there's actually very little sanity checks
after we close our input list.
```dm
var/choice = tgui_input_list(user, "Select Power Line For Operation", "Select Cable Layer", GLOB.cable_name_to_layer)
if(isnull(choice))
	return ITEM_INTERACT_BLOCKING
```
We only care about whether we made a choice!
Testing this, lo and behold, this can cause runtimes if the power object
gets qdeleted before you close the menu.
As a funny side, it _also_ doesn't care about whether you're on the
other side of the station, while your multitool is on a different
z-level, or just doesn't exist anymore.
So we just add a few basic sanity checks while we're at it.
```dm
var/choice = tgui_input_list(user, "Select Power Line For Operation", "Select Cable Layer", GLOB.cable_name_to_layer)
if(isnull(choice) || QDELETED(src) || QDELETED(user) || QDELETED(tool) || !user.Adjacent(src) || !user.is_holding(tool))
	return ITEM_INTERACT_BLOCKING
```
That's all. Having done some basic testing, I believe the behaviour is
otherwise unaffected.
## Why It's Good For The Game

It's annoying to need to swap to an empty hand or wirecutters to
interact with APC, emitter, or tesla coil wires.
This fixes that. (Fixes #81745.)
...and then a few other tidbits I realized existed.
## Changelog
:cl:
fix: Fix using a multitool on a power object with wires not actually
opening the wires menu when it should.
fix: Fix a runtime from a power object being deleted before selecting
what cable layer to put it at.
fix: Fix power object cable changing not caring about whether you were
still adjacent, still holding your multitool, or whether it even still
existed after the selection menu was closed.
/:cl:

* Fixes issues with multitools on power objects

---------

Co-authored-by: _0Steven <[email protected]>
@mogeoko mogeoko merged commit 06f3088 into master Apr 3, 2024
24 checks passed
@mogeoko mogeoko deleted the upstream-mirror-1783 branch April 3, 2024 16:20
AnywayFarus added a commit that referenced this pull request Apr 3, 2024
Iajret pushed a commit that referenced this pull request May 29, 2024
…nside of a non-turf atom (#2714)

* Fix issues resulting from an elevated object being created inside of a non-turf atom (#83498)

## About The Pull Request

If an elevated object is initialized inside of a non-turf atom, it'll
still make the turf it is on elevated. Permanently. Which is weird.

## Why It's Good For The Game

Randomly elevated turfs are bad. Bugs bad.

## Changelog
:cl:
fix: Fix a rare issue where a turf would remain permanently "elevated"
if an elevated object was initialized inside of a non-turf object.
/:cl:

* Fix issues resulting from an elevated object being created inside of a non-turf atom

---------

Co-authored-by: Lucy <[email protected]>
Co-authored-by: NovaBot13 <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants