1
\$\begingroup\$

I have a base class for Abilities. This is a point and click game, therefore I have Click, Hold and Drag subclasses.

What I need to do is remind myself to set the player's AI state to Ability when it casts, and then back to Idle when the cast is over. The will be needed in various spots of the abilities code depending on how complex it is.

For example, Clicking to dash is easy. I set the AI state to Ability, then Cast dash (one frame), then set the AI state to Idle (reset AI).

But this becomes complicated for something like a leap. I won't set the AI state to Ability until I trigger DragEnd (mouse up after a drag), and I won't set the AI state back to Idle until the animation and damage completes.

Point is, there's no telling where I'll need to set the Ability and Idle AI states. However, I forget to do this pretty often and I can't think of any good way to enforce using these variables/setting these states in C#.

Any ideas?

\$\endgroup\$
4
  • \$\begingroup\$ I would try to automate the process as much as possible, so I wouldn't need to set them for every action. But without a code example, my suggestions can only be a guess, could you try showing an example of code that you have tried? \$\endgroup\$ Commented May 23, 2024 at 8:52
  • \$\begingroup\$ Sounds like a job for delegates and events? \$\endgroup\$ Commented May 23, 2024 at 19:50
  • \$\begingroup\$ Write it as the only thing on a great big whiteboard hanging over your work desk? \$\endgroup\$ Commented May 23, 2024 at 21:50
  • \$\begingroup\$ Even if it was an event, I'd still need to manually know when to fire the start and end states in the dynamic ability code. \$\endgroup\$ Commented May 23, 2024 at 22:58

1 Answer 1

1
\$\begingroup\$

Without seeing your code, I can only make vague statements about the problem. This answer represents my best guess based on the information provided so far.  

Decouple "Commands" from "Abilities"

The problem is that you have the same component responding to user input and driving the character. These are two separate responsibilities and should be two separate objects. The fact that you need to reliably do something in between when you finish receiving the Command and when you start performing the Ability is just one symptom of this.

The answer, I think, is to have the component that handles user input create a Command (or Instruction, or whatever else you want to call it) object, which it sends to the player.

The player would then hold on to the Command in a queued state until it's ready to perform it - for example, if it was in the middle of the animation to pick up an object, you wouldn't want to immediately start another action before that animation finishes and the object is stored in the player's inventory. (The "Queue" here would probably just be one action. If the UI issues 10 commands while the character is busy, the first 9 of them should be discarded leaving only the most recent one in the queue.)

Finally, at the moment when the Command is dequeued, the Player sets its state to Ability. Then it performs whatever command-specific code performs the actions that command is asking for (in some form where its end can be observed). Finally, when that code completes, the Player sets its state back to Idle (unless it has another Command queued in which case it moves on to whatever state is appropriate for that Command).

At no point does the implementation of the ability need to touch the player's state, unless it wants to put the player into a state other than Ability.

\$\endgroup\$
1
  • \$\begingroup\$ Ok, this generally makes sense. I can make an action queue that waits for things to execute and does things on enter and exit. I just didn't think I'd need to abstract this specific concept out so much. The code gets harder to understand as I do this. \$\endgroup\$ Commented May 23, 2024 at 22:57

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.