Frictional Games Forum (read-only)
Move Player / Remove Timers - Printable Version

+- Frictional Games Forum (read-only) (https://www.frictionalgames.com/forum)
+-- Forum: Amnesia: The Dark Descent (https://www.frictionalgames.com/forum/forum-6.html)
+--- Forum: Custom Stories, TCs & Mods - Development (https://www.frictionalgames.com/forum/forum-38.html)
+---- Forum: Development Support (https://www.frictionalgames.com/forum/forum-39.html)
+---- Thread: Move Player / Remove Timers (/thread-21560.html)

Pages: 1 2


Move Player / Remove Timers - Shirder - 05-20-2013

Hello Forum,

Basically, I want to block a way with a script area. When the player walks into the area, it says something like "You can't go here right now", then the player turns around and can walk again. Everything in-script, no movement enabled.
The script looks like this so far:
Spoiler below!
void ResAreaSign(string &in asParent, string &in asChild, int alState)
{
SetPlayerActive(false);
SetMessage("Thoughts", "RestrictedArea", 5.0);
StartPlayerLookAt("SignArea_1", 5, 5, "");
AddTimer("", 2.0f, "NoWay");
}

void NoWay(string &in asTimer)
{
StartPlayerLookAt("SignArea_3", 5, 5, ""); [180° turn]
AddTimer("", 1.0f, "NoWay2");
}

void NoWay2(string &in asTimer)
{
StopPlayerLookAt();
SetPlayerActive(true);
}

But here comes the problem: The player needs to step out of the area, otherwise he can just walk backwards through it. I would like to add a function which moves the player to specific coordinates. But exactly there is the problem. I just can't get the player to move. AddPlayerBodyForce is not working, neither is the Force and impulses tutorial (No matter what numbers I use, the player does zero movement). I also tried to teleport, but it just looks bad. Creating an invisible wall also does not work and I don't want to use something like this.

Is there any way of moving the player in 'off-control' mode? Like he does a step back while turning around? 'cause that's exactly what I'm trying to do ^^;


RE: Move Player - Slanderous - 05-20-2013

(05-20-2013, 06:10 PM)Shirder Wrote: Hello Forum,

Basically, I want to block a way with a script area. When the player walks into the area, it says something like "You can't go here right now", then the player turns around and can walk again. Everything in-script, no movement enabled.
The script looks like this so far:
Spoiler below!
void ResAreaSign(string &in asParent, string &in asChild, int alState)
{
SetPlayerActive(false);
SetMessage("Thoughts", "RestrictedArea", 5.0);
StartPlayerLookAt("SignArea_1", 5, 5, "");
AddTimer("", 2.0f, "NoWay");
}

void NoWay(string &in asTimer)
{
StartPlayerLookAt("SignArea_3", 5, 5, ""); [180° turn]
AddTimer("", 1.0f, "NoWay2");
}

void NoWay2(string &in asTimer)
{
StopPlayerLookAt();
SetPlayerActive(true);
}

But here comes the problem: The player needs to step out of the area, otherwise he can just walk backwards through it. I would like to add a function which moves the player to specific coordinates. But exactly there is the problem. I just can't get the player to move. AddPlayerBodyForce is not working, neither is the Force and impulses tutorial (No matter what numbers I use, the player does zero movement). I also tried to teleport, but it just looks bad. Creating an invisible wall also does not work and I don't want to use something like this.

Is there any way of moving the player in 'off-control' mode? Like he does a step back while turning around? 'cause that's exactly what I'm trying to do ^^;

I think it should be like this:

"StopPlayerLookAt(SignArea_3);"

But i'm not sure.


RE: Move Player - OriginalUsername - 05-20-2013

(05-20-2013, 06:29 PM)lazz3r Wrote: I think it should be like this:

"StopPlayerLookAt(SignArea_3);"

But i'm not sure.

No, just StopPlayerLookAt(); is enough.

Easiest way to do this is just place a blockbox with an script area in front of it. So the player can't go trough it and the script area for a message like: I can't go there..


RE: Move Player - Adrianis - 05-20-2013

Smoke's suggestion is probably the better way of doing it, however...

In the Justine expansion you have this extra function, shown at the bottom of hte Player section in the engine scripts page

void MovePlayerForward(float afAmount)

“REQUIRES THE 1.2 PATCH: JUSTINE” Moves the player forward. It needs to be called in a timer that updates 60 times / second.

Now, if you set up a script area behind where the player would be if they walked into the area displaying the message, then you can call
void StartPlayerLookAt(string& asEntityName, float afSpeedMul, float afMaxSpeed, string& asAtTargetCallback);
In the definition for the callback function, call StopPlayerLookAt(); [now they should be looking in the direction away from the area they walked into], then call MovePlayerForward in a looping timer function to get them to move away!

I've never done that before so I'm not entirely sure it will work, and I still think Smoke's idea is better/easier to implement, but it might be worth giving it a go!


RE: Move Player - Shirder - 05-20-2013

(05-20-2013, 06:35 PM)Smoke Wrote: Easiest way to do this is just place a blockbox with an script area in front of it. So the player can't go trough it and the script area for a message like: I can't go there..

Well, that's actually what I try to avoid^^ Invisible walls always seem kinda unrealistic. In this case, the protagonist just doesn't want to go there; better than being blocked.


(05-20-2013, 07:08 PM)Adrianis Wrote: In the Justine expansion you have this extra function, shown at the bottom of hte Player section in the engine scripts page

void MovePlayerForward(float afAmount)

That sounds like what I've been looking for all the time! But how do I do a looping timer? When I use this, it tells me "No matching signatures to 'MovePlayerForward(const unit)'". Might have something to do with it...


RE: Move Player - PutraenusAlivius - 05-21-2013

You might have to call it first.
Code:
void FirstTimer(string &in asTimer)
{
MovePlayerForward(1.5f); //Change 1.5f to the amount the player walks. It's like how many steps.
AddTimer("", 1, "LoopTimer");
}

void LoopTimer(string &in asTimer)
{
AddTimer("", 1.0f, "FirstTimer"); //Change 1.0f to how long you want it to loop.
}



RE: Move Player - Adrianis - 05-21-2013

(05-20-2013, 08:41 PM)Shirder Wrote:
Spoiler below!

(05-20-2013, 06:35 PM)Smoke Wrote: Easiest way to do this is just place a blockbox with an script area in front of it. So the player can't go trough it and the script area for a message like: I can't go there..

Well, that's actually what I try to avoid^^ Invisible walls always seem kinda unrealistic. In this case, the protagonist just doesn't want to go there; better than being blocked.


(05-20-2013, 07:08 PM)Adrianis Wrote: In the Justine expansion you have this extra function, shown at the bottom of hte Player section in the engine scripts page

void MovePlayerForward(float afAmount)

That sounds like what I've been looking for all the time! But how do I do a looping timer? When I use this, it tells me "No matching signatures to 'MovePlayerForward(const unit)'". Might have something to do with it...

Well, have you got the Justine expansion pack? The function won't be available if you don't.
That error message, 'No matching signatures to...', means it doesn't recognise the function you are trying to use.

Heres a very simple example of a looping timer

Code:
void OnStart()
{
    AddTimer("Looper", 0.16, "TimerLoop");
}

void TimerLoop(string &in strTimer)
{
    AddTimer("Looper", 0.16, "TimerLoop");
}

So at the start of the game, a timer goes of after 0.16s, which activates the TimerLoop function, which sets a timer for another 0.16s which activates TimerLoop again, and so on and so forth. That will keep looping 60 times a second.

Obviously in your case that first timer should be called when the player collides with a script area, not right at the start of the game, but the principle is exactly the same.

Hope that helps!

EDIT: Gah, ninja'd... oh well, better explanation at least


RE: Move Player - Shirder - 05-21-2013

So it's basically function1 that calls function2 that recalls function1. It seems so easy now that I got that Big Grin
Apparently there aren't many explanations on the internet, but you both made it way easier to understand. Thanks alot for explaining, works like a charme^^

And about that error message: Yep, it was caused by the patch. It wasn't installed properly. But now everything works like it's supposed to and the player moves!
Well, except that I now don't manage to stop him, but that's a different problem I can fix myself^^ At least he finally moves.

So far, many thanks. You helped me alot ;D

[EDIT]: Cheered too soon...
Well, I thought I could simply stop him by using RemoveTimer, but that doesn't have any effect. (At first he didn't walk, now he can't stop. I kinda knew this would happen ^^; )
I did like this: At the moment the player turns around, another timer is called that removes the looping timers 2,5 seconds after they've beed called.
Looks like this now:
Spoiler below!
void ResAreaSign(string &in asParent, string &in asChild, int alState)
{
SetPlayerActive(false);
SetMessage("Thoughts", "RestrictedArea", 5.0);
StartPlayerLookAt("SignArea_1", 5, 5, "");
AddTimer("", 2.0f, "TurnAround");
}

void TurnAround(string &in asTimer)
{
StartPlayerLookAt("SignArea_3", 5, 5, "");
AddTimer("", 0.5f, "StartWalking");
AddTimer("", 3.0f, "StopWalking");
}

void StartWalking(string &in asTimer)
{
MovePlayerForward(5.0f);
AddTimer("", 0.01f, "RepeatWalking");
}

void RepeatWalking(string &in asTimer)
{
AddTimer("RepeatWalk", 0.01f, "StartWalking");
}

void StopWalking(string &in asTimer)
{
RemoveTimer("StartWalking");
RemoveTimer("RepeatWalking");
StopPlayerLookAt();
AddTimer("", 0.5, "GiveControlBack");
}

void GiveControlBack(string &in asTimer)
{
SetPlayerActive(true);
}
Everything else on 'void StopWalking' works, means I can look around and take control - while moving forward.
Putting RemoveTimer into a ScriptArea doesn't work either, same thing here.
How do I remove the timers now?


RE: Move Player / Remove Timers - PutraenusAlivius - 05-22-2013

Spoiler below!
void ResAreaSign(string &in asParent, string &in asChild, int alState)
{
SetPlayerActive(false);
SetMessage("Thoughts", "RestrictedArea", 5.0);
StartPlayerLookAt("SignArea_1", 5, 5, "");
AddTimer("", 2.0f, "TurnAround");
}

void TurnAround(string &in asTimer)
{
StartPlayerLookAt("SignArea_3", 5, 5, "");
AddTimer("", 0.5f, "StartWalking");
}

void StartWalking(string &in asTimer)
{
MovePlayerForward(5.0f);
AddTimer("", 0.01f, "RepeatWalking");
}

void RepeatWalking(string &in asTimer)
{
AddTimer("RepeatWalk", 0.01f, "StartWalking");
AddTimer("", 3.0f, "StopWalking");
}

void StopWalking(string &in asTimer)
{
RemoveTimer("StartWalking");
RemoveTimer("RepeatWalking");
StopPlayerLookAt();
AddTimer("", 0.5, "GiveControlBack");
}

void GiveControlBack(string &in asTimer)
{
SetPlayerActive(true);
}

Try this.


RE: Move Player / Remove Timers - Shirder - 05-22-2013

(05-22-2013, 01:07 AM)JustAnotherPlayer Wrote:
Spoiler below!
void ResAreaSign(string &in asParent, string &in asChild, int alState)
{
SetPlayerActive(false);
SetMessage("Thoughts", "RestrictedArea", 5.0);
StartPlayerLookAt("SignArea_1", 5, 5, "");
AddTimer("", 2.0f, "TurnAround");
}

void TurnAround(string &in asTimer)
{
StartPlayerLookAt("SignArea_3", 5, 5, "");
AddTimer("", 0.5f, "StartWalking");
}

void StartWalking(string &in asTimer)
{
MovePlayerForward(5.0f);
AddTimer("", 0.01f, "RepeatWalking");
}

void RepeatWalking(string &in asTimer)
{
AddTimer("RepeatWalk", 0.01f, "StartWalking");
AddTimer("", 3.0f, "StopWalking");
}

void StopWalking(string &in asTimer)
{
RemoveTimer("StartWalking");
RemoveTimer("RepeatWalking");
StopPlayerLookAt();
AddTimer("", 0.5, "GiveControlBack");
}

void GiveControlBack(string &in asTimer)
{
SetPlayerActive(true);
}

Try this.

Did nothing. But thanks anyway^^

Well, after about one hour of pure trial&error, I got rid of it at last.
I needed to name the timers, and if I want to remove them, it's not RemoveTimer("MyFunc"), but RemoveTimer("TimerName").
Spoiler below!
void TurnAround(string &in asTimer)
{
[...]
AddTimer("Start", 0.5f, "StartWalking");
AddTimer("", 1.5f, "StopEverything");
}

void StartWalking(string &in asTimer)
{
MovePlayerForward(5.0f);
AddTimer("Repeat", 0.01f, "RepeatWalking");
}

void RepeatWalking(string &in asTimer)
{
AddTimer("Start", 0.01f, "StartWalking");
}

void StopEverything(string &in asTimer)
{
[...]
RemoveTimer("Start");
RemoveTimer("Repeat");
}
Now he's standing still after 1,5 seconds. Some more finetuning and I'm done :D

If anybody has the same problem and comes across this thread, here's a brief remark:
I thought it was poorly explained in Game Timers, but if you pay attention, it says "string &in asName", not "string &in asFunction".