Instead of using waits, you can reorganise some small things to make it work.
Since you are using states for your workers it should at least from what I can see in the screenshot be fairly easy to do.
In:
function "Move_to_water"
Worker within 0.1 degrees of area.angle
you remove the wait 1 seconds and the function call to "Collecting_water"
instead you do "Worker set FSMState to "collecting_water"" and if you don't already have an variable for your workers to hold the UID of the object they need to interact with. You can make one. So as you change the state of the worker you at the same time set the interaction variable to the Area.UID. Since you have already selected it when you call "Move_to_water" it should be easy.
In the function "Collecting water" you remove the Set state to "Collecting water" as you have already done that.
Then you remove the wait*4 loopindex as well.
So to make it work, you make an event like this:
Every 1 second
Worker state = "Collecting water"
For each Worker
Call function "Collecting water" (Worker.UID, Worker.Interact_UID (Which is the area.UID in this case))
So basically what you do is simplifying you functions and you get those nasty waits out of the way, and move the wait time outside the functions.
The benefit of using an interact.UID for everything that the worker have to interact with, is that it makes it very easy to debug your program. As you can always check that this variable for a given worker is correct. And since it cant interact with more than one thing at the time. You could also use it if the worker for instant need to go eat and do that sitting in a chair. You simply set the interact variable to the chair UID.
Another good idea I think is to use Booleans for states instead of text, not that it wont work with texts. But its just faster to work with as you don't have to remember how you wrote different things.
So you could have a series of Booleans:
FSM_Idle_wait
FSM_Idle
etc.
Another tip is to use "flags" for your units, this will also make it easier and will let you control them a lot better.
For instant if you use path finding to move your workers around.
You can add the "On arrived" however it will trigger whenever a worker arrives at something. But if you use flags you can make it very easy to make them do what you want.
"On arrived at chair"
Worker.flag_going_to_eat = true
Call function "worker eat"
"On arrived at chair"
Worker.flag_going_to_repair = true
Call function "worker repair item"
I always use at least 3 "Checks" when doing AI.
Busy (Boolean) <Whenever a unit is not busy, it will look for something to do. This is the main variable for activating different states>
Type (Boolean) <Can be very useful if you have different types of units, with different state machines. So Enemies use there own state machine)
FSM_<Do something> (Boolean)
Flag_<What action to perform> (Boolean)
<State variable> (Boolean) <Very good if you for instant want to make a priority system, so if workers get hungry when hunger = 0 you can set something like "is_Hungry = true"
For the state machine it self (If we should make one for workers):
Unit type = Worker
Worker is busy = false
For each Worker
<The order in which you set conditions will act as priority system>
Check 1:
Worker is hungry
Worker is not busy
Action 1:
Set worker busy = true
Worker set FSM_look_for_food = true
Check 2:
Worker is tired
Worker is not busy
Action 2:
Set worker busy = true
Worker set FSM_look_for_place_to_sleep = true
Etc.