I'm trying to script a following scene:
1. After the character has acquired a certain object, he's passing through a meadow - where he attracts the attention of an angry bee - which starts to follow him around.
2. Wherever he goes, it follows. And when he stops, it flies up to him and sits on his forearm - which he's too afraid to move.
3. After he's been idle for 5-7 seconds, it finally stings him.
So, first, I put this:
cBee.FollowCharacter(cGray, 10, 0);
and it does the following around part beautifully. But a problem arises. I wanted him to always face the bee when he's not moving - for obvious reasons, and also because I want it to land on his arm, and it's the closest point to the bee only when he's facing it. The thing is, though, even though I put this:
if (cGray.Moving ==false){
cGray.FaceCharacter(cStrayBee2);}
in Repeat_Exec, he doesn't always turn around. And even if he does, he turns away again even if it's still there.
Also, how do I have the bee land on a specific part of his body? I'm guessing it involves specifying the main character's x and y (meaing where his feet are) plus/minus the distance from that point to the point where the bee should land. Keeping in mind that the x value will differ depending on which direction the character is facing (x - something if he's facing left, and x + something if facing right).
Allllso, I should mention that the character should be able to move around freely if the player wants to - not to make it explicit that they have to wait (be idle) for several seconds, because getting stung is the point of the puzzle, not something to avoid (by the way, is there some sort of a "HasBeenIdle(int how long)" command, and if not, how can I set a required period of idleness before he gets stung?).
I did try to set the bee's baseline to the character's baseline while it's usual flight altitute is at his shoulders' height, so that I could use the IsColidingWithCharacter option - but that only worked nice with cBee.Move and not so much with cBee.FollowCharacter, because that way, it simply bumped into the character and stopped there.
Since this one is quite a toughie, please let me know which script goes where - just to avoid confusion.
I think this might work.
is(player.moving == false) player.facecharacter(cbee, eBlock);
Yeah, that's actually what I did, my mistake was that I copied only one line from that script into the code quote here (edited the post to include all of it - which looks pretty close to yours). Thanks for making me actually notice, though :)
No prob.
Hey,
If you'd like to check if the bee has been on him for a certain amount of time you could use a timer:
bool under_attack = false;
bool idle = false;
int sting = 0;
function repeatedly_execute()
{
if(under_attack && sting == 1)
{
if(!player.Moving && !idle)
{
idle = true;
SetTimer(1, GetGameSpeed()*15);
}
else if(player.Moving && idle)
{
idle = false;
}
if(IsTimerExpired(1) && idle)
{
//execute the sting part
sting = 2;
idle = false;
under_attack = false;
}
}
else if(under_attack && !sting && !player.Moving)
{
player.FaceCharacter(cBee, eNoBlock);
}
}
When the bee attack sequence starts, you set under_attack = true;
When the bee is on the player set sting = 1;
If the bee flies again before it stings, sting = 0; idle = false;
Change the timer from 15 seconds to whatever you want.
And put your code for when it has to sting.
For the bee landing on player I thought moving it over the player would work fine, but maybe you can change the view of the player to have the bee drawn on the sprite instead.
I don't have AGS on this computer atm so tell me if there's any problem.
Where exactly do I put the
bool under_attack = false;
bool idle = false;
int sting = 0;
part? Because right now, wherever I put it (my guesses were first BeforeFadeIn and then GlobalScript), it says it doesn't recognize/understand the under_attack part in the script. Sorry, I'm still confused sometimes about where things go, plus now I'm really really tired.
But the idea with the timer is great, I'm kicking myself for not having thought of that!
Inside Global script this function should already be here. Just add the code inside, and the 3 lines just above:
bool under_attack = false;
bool idle = false;
int sting = 0;
function repeatedly_execute()
{
}
I just tried in AGS without a problem, is there an error? Can you write the error output pls?
I haven't tested but the code is supposed to work the exact same way inside room script I think.
If you use it in room script then all you have to do is copy paste the whole code I wrote previously, since there is no repeatedly_execute inside room script by default.
Now the game started with no problem - except... nothing's happening ;) Might be that I still have my original, room-specific scripts active (if he steps onto a hotspot, the bee goes into FollowCharacter mode, and I think something else, too) - and I don't feel up to tinkering with those at the moment, I'm half asleep right now. The whole sequence is also dependent on a bunch of other factors, like HasInventory and a global variable for what time of the day it is, so I'd rather have a script that I could use within Room events rather than Global Script (which I have used very little so far). And I did use Repeatedly_Execute inside rooms before and it worked just fine.
But as I said, the idea with the timer itself gave me a bunch of ideas - even to refine the whole sequence a bit. Now if only I manage to fix the thing with him facing the bee when idle and get the bee to sit on him, it'll be all good.
When the bee goes into FollowCharacter mode, put this line:
under_attack = true;
When the bee lands on player, put this:
sting = 1;
And put any additional code for when the bee stings inside the code where I put:
//execute the sting part
Setting under_attack to true is what launches the whole event.
When I put the
under_attack = true;
in the Room events (Stand on hotspot, to be exact), it returns this error:
Failed to save room room2.crm; details below
room2.asc(141): Error (line 141): Undefined token 'under_attack'
Make sure you have the 3 lines inside the room script but outside any function. It should work.
bool under_attack = false;
bool idle = false;
int sting = 0;
Or can you post the room code?
Also make sure these lines are written before/above the under_attack = true; code.
Strange: when I copied the three lines into the room script, the game ran fine - but NOTHING happened. The character didn't face the bee but once, even. So I put the whole script again in the room's Repeatedly_Execute again - and still, nada.
I'm thinking this... If I set the bee's baseline to the same as the character's (his feet are at 215) and make cBee.Solid = false, it won't bump into the character. But when the timer expires, I could set to switch it to true, and voila, bumps into him right where I want it to, can't go any further. Then I use IsCollidingWithCharacter and ignite the function.
Except the FaceCharacter doesn't work properly. Darnation :-\ It actually failed me in another situation, too. I wanted the character to face the sun - and what he does is turn away from it, even though he's not even close to being in the same line vertically.
Edit: he actually turns to face the bee for half a second when it ventures as far as some 30-40 pixels away from him. But it seldom goes that far and turns around instantly, and he's turns away the second it does - long before it even get close to him, never mind pass him to reach the opposite end of its restricted area.
bool under_attack = false;
bool idle = false;
int sting = 0;
function hHotspot1_WalkOn()
{
under_attack = true;
cBee.FollowCharacter(player, 10);
}
function room_RepExec()
{
if(under_attack && sting == 1)
{
if(!player.Moving && !idle)
{
idle = true;
SetTimer(1, GetGameSpeed()*15);
}
else if(player.Moving && idle)
{
idle = false;
}
if(IsTimerExpired(1) && idle)
{
//execute the sting part
Display("The bee attacked you!");
sting = 2;
idle = false;
}
}
else if(under_attack && !sting && !player.Moving)
{
player.FaceCharacter(cBee, eNoBlock);
}
}
This is what the room script looks like, you would just need to use "sting = 1;" when the bee lands, then it will wait for player to be idle (not moving) for 15 sec and then display "The bee attacked you".
I just realised I had something wrong in the code, you need to use the event tab of the room to link Room_RepExec() properly. I edited the code.
Sorry I'm a bit tired too, hope this work like you expected.
That's the thing - he doesn't. I checked and there's no other conflicting FaceCharacter command in use in Room script or elsewhere. I thought it was about the FollowCharacter command, but when I changed it to Move (with added waypoints, just to have the bee move from one end of the screen to another), there was absolutely no reaction from the main character. I even tried to work around it with
if (cBee.x > cGray.x + 5) {
cGray.FaceLocation(320, 215) //the farthest point right in the room
and the opposite for him to look left, but that didn't work, either. I might've messed something up in that one, I'm pretty brain dead right now - but the whole FaceCharacter command not working/working weird is bugging the hell out of me.
This is working fine with me , I created a room, a hotspot, a bee character, and put this code in the room script, but you need to link it in the room property panel for it to work (room repeatedly execute).
The hotspot must be linked the same way.
Also make sure you actually walk on the hotspot by adding a Display("test");
Btw I edited the code so pls paste it again.
I *think* I followed all your instructions - and still nothing. I can tell when the hotspot is activated, because if he stands on it, the bee goes into FollowCharacter mode. But other than that, nothing happens. He just stands there, staring in one direction, the bee flies around him to and fro.
That's it for today, though, I need sleep. I'll try something tomorrow - but if I can't get that damn FaceCharacter command to work right, I'll have to figure something else out. And as I mentioned, this isn't the first time it does the exact opposite of what it's expcted to. Could it be that I'm experiencing some sort of a glitch here?
Yeah strange, I can walk and have the bee follow me and whenever I stop it forces me to face it. Please post your room code, this is the easiest way to help you.
Edit: deleted in order to avoid eternal shame ;)
In the repeatedly_execute, try replacing the cstraybee1 line with:
cStrayBee1.Walk(walkx, walky, eNoBlock);
This may interfere with the rest of the code if the functions is blocking.
Does it work if you completely remove the random moving part with cstraybee1 from the rep_exec?
Was the Bee1 moving randomly as expected?
I did. Nothing changed. First time I tried, Bee #2 froze after passing by Gray. The second time, everything went back to the original state. I removed Bee1 random movement. That didn't work, either. The only other things animating constantly are a beehive and a cig - but both are on eRepeat, eNoBlock, in AfterFadeIn/BefoteFadeIn
Can you try to remove everything from rep_exec and just put:
if(!player.Moving)
{
player.FaceCharacter(cStrayBee1, eNoBlock);
Display("I'm facing the bee");
}
If nothing displays when you stop, the function isn't linked properly, in this case just remove the property text in the room event panel, and then hit the "..." button again to re-link it.
Edit: one more thing, you added "sting = 1;" when the sting is supposed to occur. It should be when the bee lands on the player body, then the sting will occur automatically after 15 sec idling.
It displays it right away. Except it blocks every other animation on the screen.
And while I did that, I forgot to paste the original code that was there into any text processor for keeping - and now if went heidi. I knew if I stayed up and keep trying to do something, I would end up messing something up. The good thing is I have the last big scripting session backed up.
I tried another thing: I put your script into a new room, with no scripts in it yet, with a different character there. Gray faces that one alright wherever it goes. But it does nothing aside from that. Just walks to and fro. Could it be that the size here matters? The bee is just 4x4 pixels, the other character is much bigger.
I've sent a PM, regarding your question I don't think the size matters but I'm gonna run a quick test and will edit my post afterward.
I did a little test - I removed almost ALL scripts that resulted in any activity in the room, so there was absolutely nothing else moving or happening. Still, the character didn't face the bee. However, in a similarly empty environment in the other room, he faced the passing character every time.
Yeah there's something strange, that's why I suggested to send the whole game file so I can have a closer look at it, I could hopefully figure out what's going wrong without having to flood the forum :P But I would understand if you don't want to of course.
Edit: The problem was coming from the UP/DOWN loops being just copies of the right and left loops, making the player think he's facing right when he's actually facing up and result in strange behaviour.
Will tweak the code a bit more, because having the character face something is considered as a movement, (Edit) so the trick was to change the character loop to make it look like he's facing without modifying player.Moving variable, so we can detect if player is idle and have him face anything at the same time, also made sure the facing direction is either left or right only.