Waiting for object to finish animation before npc i allowed to move?

Started by myname, Sat 02/02/2008 17:43:40

Previous topic - Next topic

myname

My problem is I have a npc is mopping up blood and once he is given an inventory item to blood which i made an object starts it animation which like 6 frames of it disapearing then the npc is to move somewhere else in the room.  The problem I am having is the npc moves as soon as the animation starts so it appears the bood is being cleaned up by no ne until it is gone.  The npc's idle animation is mopping so if he could just stay put until the blood is finished its animation all would be great.  If anyone can help it would be greatly appreciated.

.M.M.

I think you have in script
Code: ags
 player.Walk (x,y,eBlock) 

replace it by
Code: ags
player.Walk (x,y,eNoBlock) 
.

myname

Thanks for the reply Mirek but I still have the same problem.  Is there maybe  better way I can animate this, I feel like I have maybe taken the lazy way out but I dont know.  Maybe not.

OneDollar

Ok, what you want is to run the blood animation on blocking, which means the rest of the script will wait until the animation has finished before running. I don't know what setup you have, but something like this should do it:

Code: ags

oBlood.SetView(view); //assign the view you used to animate the blood to the object
oBlood.Animate(loop, delay, eOnce, eBlock, eForwards);  //animate the blood being removed
//important parameter here is eBlock which halts the script until the animation is finished
cNPC.Walk(x, y, eBlock);  //continue the script

Look up the functions in the manual if you need more information about what each parameter does.

myname

Thanks for the help Onedollar but now I get an error message that says my oBlood is undefined even though that is what it is labeled as for script name. ???

Khris


myname

Thank you KhrisMUC but it still says it is an undefined token.
BLOOD.SetView(20);
BLOOD.Animate(0, 40, eOnce, eBlock, eForwards);
cJasper.Walk(35, 135, eBlock);

monkey0506

Actually Khris, even in AGS 2.72 it would still have been oBlood in the room script.

Objects are only available to the room they are in, so if you are putting this code in your global script it won't work. You must put it in your room script.

myname

Thanks for the reply monkey but now I get a Parse error unexpected 'if' message. ???


// room script file


#sectionstart room_a  // DO NOT EDIT OR REMOVE THIS LINE
function room_a() {
  // script for Room: Player enters room (after fadein)
cJasper.Animate(cJasper.Loop, 17, eRepeat, eNoBlock);
cNancy.Animate(cNancy.Loop, 22, eRepeat, eNoBlock);
cBigworm.Animate(cBigworm.Loop, 13, eRepeat, eNoBlock);}
if (player.ActiveInventory == inventory[6]) {oBlood.SetView(20);
oBlood.Animate(0, 40, eOnce, eBlock, eForwards);
cJasper.Walk(35, 135, eBlock);}}
#sectionend room_a  // DO NOT EDIT OR REMOVE THIS LINE

VK Dan

You have an extra brace at the end of this line.
Code: ags
  cBigworm.Animate(cBigworm.Loop, 13, eRepeat, eNoBlock);}

myname

Thanks VK Dan I am an idiot.  But now the npc stays in place but the object never starts its animation.   >:(

OneDollar

That's because you're running the if function in the 'player enters room' script, so when your player enters the room it checks to see if their active inventory is item 6 then runs the blood animation bit if it is. What you want to do is move that if function into something like player uses inventory on character.

myname

Thanks OneDollar but the problem I was having befoe with that is that the game does not recognize oBLOOD when out of the roomscript.

OneDollar

Ah, yeah, sorry. Ok, the way around this is to use the function CallRoomScript(). In your global script replace your animation functions with CallRoomScript(1); as below:
Code: ags

function cJasper_UseInv()
{
  if (player.ActiveInventory == inventory[6]) {
    CallRoomScript(1);
    cJasper.Walk(35, 135, eBlock);
  }
}


Then in your room script make a new function as follows:
Code: ags

function on_call (int value) {
  if (value == 1) {
    oBlood.SetView(20);
    oBlood.Animate(0, 40, eOnce, eBlock, eForwards);
  }
}

myname

Dude I'm sorry its still not working I have no idea what to do.  Thanks for trying man.  If you have any other ideas I'll try anything. 

OneDollar

That's alright. How exactly is it not working? What version of AGS are you using?

Edit: Just a thought, but how about replacing the inventory[6] bit with the script name of your inventory like iCloth or something?

Another Edit: I've had a go at building this myself and I've got it working. One other problem is that the CallRoomScript() function runs after the cJasper_UseInv() finishes, so they way I wrote it will cause Jasper to walk before the blood animates. You can fix this by putting the cJasper.Walk line into the on_call function. If you need to do anything more global than just moving a character after the animation, the CallRoomScript sets a game variable called game.roomscript_finished to 1 when it's finished running, so you can put a check for that in your global repeatedly_execute function.

myname

The problem i am having now is that the blood does not run its animation so Jasper is waiting for it to change views so he can move but nothing is happening so he continues idle animation and the blood stays the same.  Thanks a lot for trying to help me OneDollar I might just find another way around this but I havent figured out  better avenue to take in the animation process.  I know I am going to run into similar problems in the future I just wish I knew how to fix this one.

Shane 'ProgZmax' Stevens

You need to understand how things work before messing about.

This:

Code: ags
oBlood.Animate(0, 40, eOnce, eBlock, eForwards);


Runs the blood animation once, only once and stops all other game logic to do so.  This means that you absolutely cannot have your guy doing anything while this is happening.  Move away from eBlock if you want multiple events to occur at once. 

You're also giving people almost no information to work with in order to help you. 

Question 1:

Why exactly is the blood animating anyway?  If it's just on the floor to be mopped up, why does it need to animate?  If you have a static animation of the blood pool REDUCING IN SIZE as it is mopped, a blocked animation is not the way to go at all, and we need to know these things.

Here's an example.

If Jasper's mopping view is JASPERMOP, and if the blood is part of view BLOODPOOL and has 6 frames (frame 0 having a large pool and frame 6 being no blood left), this is how you could reasonably show it being mopped up:

Code: ags

oBlood.SetView(BLOODPOOL);  

cJasper.LockView(JASPERMOP);  //special animations (non -walk, -talk, -idle) must be
                                                   //locked before playback (or set with ChangeView)

cJasper.Animate(0, 5, eRepeat, eNoBlock); //loop 0 has the mop animation in this ex

oBlood.Animate(0, 20, eOnce, eNoBlock); //loop 0 has the blood animation in this ex

//these are now animating at the same time, but we need to make
//AGS wait until we're done

Wait(500);  //adjust the value inside Wait() until the blood is all gone

cJasper.UnlockView();  //ALWAYS unlock locked animations after you are done

//continue on with the game



This is how I would deal with a scene that required multiple things happening at once (but without player involvement).  If you need the player to take out the mop, that is handled before this section of code (and is what triggers it).  Also, you will notice that he is mopping much faster (delay 5) than the blood is disappearing, which is good.  You might need to adjust these values if you want the result to happen faster or slower along with adjusting Wait() to make sure the blood animation completes.

If I understood your post correctly, this should do what you want it to do provided that cJasper is standing over oBlood.



myname

Thanks for the reply ProgzMax before I try it ill explain more like I shuld have to begin with.  Jasper is mopping on  a constant looping animation as sooon as the player enters the room
cJasper.Animate(cJasper.Loop, 17, eRepeat, eNoBlock);
he is constantly over the blod mopping wthout it decreasing but when the player gives an item to Jasper the blood is then supposed to decrease untill gone hich allows Jasper to move elsewhere.  Sorry I thought with ll the replys that people understood the situation.

OneDollar

ProgZ, as long as you run the non-blocking animation before the blocking one, won't they both play? This would mean you could set the blood animation to blocking and get rid of the wait.
Code: ags

oBlood.SetView(BLOODPOOL);  
cJasper.LockView(JASPERMOP);
cJasper.Animate(0, 5, eRepeat, eNoBlock);
oBlood.Animate(0, 20, eOnce, eBlock);
cJasper.UnlockView();
//continue


That's how I understand it anyway. But you know, whatever works.

By the way, this is all the relevant code I have in my mock up, and as far as I understand what you're trying to do, it works fine (AGS 3.0)...

Code: ags

//In the global script

function cJasper_UseInv()
{
  if(player.ActiveInventory==iKey){  //when the correct item is used, call the room script
    CallRoomScript(1);
  }
}

Code: ags

//in the room script

function on_call (int value){
  if (value==1){
    oBlood.SetView(2);  //set blood to the disappearing view
    cJasper.LockView(1);  //lock Jasper's view to mopping
    cJasper.Animate(0, 3, eRepeat, eNoBlock, eForwards);  //animate mopping
    oBlood.Animate(0, 5, eOnce, eBlock, eForwards);  //animate disappearing
    cJasper.UnlockView();
    cJasper.Walk(35, 135, eBlock, eWalkableAreas);  //move after the disappearing has finished
  }
}

function room_AfterFadeIn()
{
  cJasper.Animate(2, 3, eRepeat, eNoBlock, eForwards);  //start mopping after fade-in
}


Obviously it depends on what your items are called and what views your animations are on, but that's the gist of it. ProgZmax's solution is just an extension of the on_call room script using with locking views, but I didn't go that far in my test. I'm wondering if any problems you have are the result of trying to combine several different methods...
Quote
...so Jasper is waiting for it to change views...
...my method doesn't use anything to do with waiting for the correct view, or other suggestions people have put forward, its completely stand alone.

SMF spam blocked by CleanTalk