Animate object problem.

Started by Badger, Tue 27/04/2010 17:35:48

Previous topic - Next topic

Badger

I've tried searching for this, but had no hope.

When i click Look at/interact/anyClick this OfficeSafe there's a set response, yet after it's animated there's no response to any kind of click.

Here's the code for the event:
function oOfficeSafe_UseInv()
{
if (SafeOpen ==0){
  if(cHank.ActiveInventory == i$$$$$){
  cHank.Walk(375, 488, eBlock, eWalkableAreas);
cHank.FaceLocation(375, 400);
cHank.LockView(25);
cHank.Animate(3, 5, eOnce, eBlock, eForwards);
oOfficeSafe.SetView(21);
oOfficeSafe.Animate(0, 5, eOnce, eBlock, eForwards);
cHank.UnlockView();
cHank.FaceLocation(375, 400);
cHank.Say("It's open.");
SafeOpen = 1;
}}}

Just wondering how i get around this, and if some of the code above needs editing, or if it's something else.

Any help appreciated :)
(and i realise i've got facelocation twice :P  )

tzachs

Well, can't answer about the look/interact methods, since you didn't post the code to that, but the use inventory will not work twice because when SaveOpen is set to 1 after the first time, you won't get inside the If and you don't have an "Else" clause.

So change the code to something like:
Code: ags

function oOfficeSafe_UseInv()
{
  if (SafeOpen ==0)
  {
    if(cHank.ActiveInventory == i$$$$$)
    {
      cHank.Walk(375, 488, eBlock, eWalkableAreas);
      cHank.FaceLocation(375, 400);
      cHank.LockView(25);
      cHank.Animate(3, 5, eOnce, eBlock, eForwards);
      oOfficeSafe.SetView(21);
      oOfficeSafe.Animate(0, 5, eOnce, eBlock, eForwards);
      cHank.UnlockView();
      cHank.FaceLocation(375, 400);
      cHank.Say("It's open.");
      SafeOpen = 1;
    }
    else
    {
      cHank.Say("Using that on the safe won't help..");
    }
  }
  else
  {
      if(cHank.ActiveInventory == i$$$$$)
      {
         cHank.Say("I've already opened the safe!");
      }
      else
      {
         cHank.Say("That won't do any good...");
      }
  }
}

Khris

Yeah, usually you'd have a separate function for every event (oOfficeSafe_Lookat(), oOfficeSafe_Interact(), oOfficeSafe_AnyClick()).

If you didn't link a function to these events, there won't be a response after a click.
(For generic responses to events without linked functions, look up unhandled_event in the manual.)

Badger

#3
ok, sorry, here's the code for the events in the seperate functions:

function oOfficeSafe_Interact()
{
cHank.Walk(375, 488, eBlock, eWalkableAreas);
cHank.FaceLocation(375, 400);
if (SafeOpen == 0){
cHank.Say("My safe-cracking skills are a little sketchy..maybe later.");}
else {cHank.Say("Erm..It's open.");}}

and:

function oOfficeSafe_AnyClick()
{
if (mouse.Mode == eModeInteract){}
else if (mouse.Mode == eModeLookat){}
else if (cHank.ActiveInventory == iLockSet){}
else {BadClick();}
}

after opening the safe, none of these activate..not even my 'badclick' function.

[EDIT] the 'Erm it's open' works after opening the safe, though the badclick function doesn't, it's copied from objects/hotspots that DO work though :/

Khris

Looking at that AnyClick code, what else do you expect?
Interact, Lookat and UseInv result in nothing, and walkto doesn't trigger AnyClick.
BadClick will only ever get called if you used some non-default cursor mode like PickUp or Pointer or UserModeX.

Just out of interest, does BadClick get called before the safe is unlocked? Because the behavior shouldn't change at all.

Also, keep in mind that unhandled_event is what you're looking for; simply leave the function textfield of events that aren't supposed to do anything empty, and AGS will call it.
In there you can code generic "That doesn't work" responses to all possible cursor mode - hotspot combinations.

Badger

thnks i'll give the unhandled method a look,
Though the anyclick works perfectly before opening the safe..so i don't see how it could change too :/

Badger

#6
Unhandled is great, but i have a few more pointers, and want to use something simple (like anyclick) to use them.

Using unhandled, the extra pointers don't work as unhandled events. Which is a shame.

And I don't want to go down the 'set up pointers' route.

Perhaps i'll use a few unhandled for the safe door, just to sort out that, and any further probs.

Thanks for the help.


Unhandled doesn't work for the opened safe :/ It still seems like the same object as teh @OVERHOTSPOT@ is the same.

Badger

solved it, it was the 'active inventory' part of the any_click;

function oOfficeSafe_AnyClick()
{
if (mouse.Mode == eModeInteract){}
else if (mouse.Mode == eModeLookat){}
else if (mouse.Mode == eModeUseinv){if (cHank.ActiveInventory == iLockSet){}}
else { BadClick();}
}

otherwise, if you had iLockSet as the active inv, but used pick up as mouse.Mode it would exclude.

Khris

I believe that BadClick will now get called even less often. You have changed it so that clicking the save with any inv item will lead to no reaction.

So, getting back to unhandled_event (because your way is error prone, messy and bloated, sorry):

Quote from: Badger on Wed 28/04/2010 15:06:14Unhandled is great, but i have a few more pointers, and want to use something simple (like anyclick) to use them.

Using unhandled, the extra pointers don't work as unhandled events. Which is a shame.

And I don't want to go down the 'set up pointers' route.

You can catch 'eventless' clicks even for cursormodes above 9.
Use IsInteractionAvailable, like this:

Code: ags
// inside on_mouse_click (which must be below unhandled_event!)

  // left click

    int x = mouse.x;
    int y = mouse.y;
    if (mouse.Mode > 9 && !IsInteractionAvailable(x, y, mouse.Mode)) unhandled_event(GetLocationType(x, y), mouse.Mode);

    ProcessClick(...

Badger

Thanks so much for that,

Will clean up my code, sets it up nicely and stops me having to call all the any_clicks.

Cheers..just have to get my head around the unhandles again :P

Badger

That method seems to work for hotspots, though doesn't for objects in unhandled_events.
Any reason why?

code:
function unhandled_event(int what, int type) {

if (what==1){ //hotspot
  if (type==1){ // look hotspot 
  }
  else if (type==2){ //Interact hotspot
  }
  else if (type==3){ //use inv on hotspot
  }
  else if (type==4){ //Talk hotspot
  }
  else if (type==7){ //Pick up hotspot
  }
  else if (type==10){ //sniff hotspot
  }
  else if (type==11){ //hump hotspot
  }
  else if (type==12){ //lick hotspot
  }
  else if (type==13){ //Swear hotspot
}}
else if (what==2){ //object
  if (type==0){ //look at object
  }
  else if (type==1){ Display("interact with object");
  }
  else if (type==2){ Display("Talk to object");
  }
  else if (type==3){ Display("use inv object");
  }
  else if (type==5){ Display("pick up object");
  }
  else if (type==4) { Display("ok?");
  }
  else if (type==9){ Display("ok?");
  }
  else if (type==10){Display("ok?");
  }
  else if (type==11){Display("ok?");
  }
  else if (type==12){Display("ok?");
  }
  else if (type==13){Display("ok?");
  }
  else if (type==14){Display("ok?");
  }
  else if (type==15){Display("ok?");
  }
}
}

the 'ok?' isn't coming up for any of my extra cursors within what==2, but will for what==1..is my code here wrong?

Khris

Wow, I've just noticed that the what and type values in unhandled_event don't correspond to neither LocationType nor mouse.Mode at all!

Looks like you have to do all that manually, i.e. instead of a simple
 unhandled_event(GetLocationType(x, y), mouse.Mode);
you have to translate it to the arbitrary numbers used in unhandled_event.

If you don't mind having two functions, call
 my_unhandled_event(GetLocationType(x, y), mouse.Mode);
and add this:

Code: ags
void my_unhandled_event(LocationType lt, CursorMode cm) {

  if (lt == eLocationObject) {
    if (cm == 9) Display("Mode 9 on obj.");
    if (cm == 10) Display("Mode 10 on obj.");
    ...
  }

  if (lt == eLocationHotspot) {
    ...
  }
  ...
}


Thinking about it, you could handle all cursor modes in a custom function, abandoning the weird numering of the built-in one altogether.

monkey0506

#12
Basically you could just write a function to use LocationType and CursorMode and then use the built-in unhandled_event function to automatically call the new function:

Code: ags
// GlobalScript.ash

import function UnhandledEvent(LocationType where, CursorMode what, InventoryItem *item=0);

// GlobalScript.asc

function UnhandledEvent(LocationType where, CursorMode what, InventoryItem *item)
{
  // put your unhandled event interactions here, i.e.
  if (where == eLocationObject)
  {
    if (what == eModeLookat)
    {
    }
    else if (what == eModeInteract)
    {
      Display("interact with object");
    }
    else if (what == eModeTalkto)
    {
      Display("Talk to object");
    }
    else if (what == eModeUseinv)
    {
      Display("use inv object");
    }
    else if (what == eModePickup)
    {
      Display("pick up object");
    }
    else Display("ok?");
  }
}

function unhandled_event(int what, int type)
{
  if (what == 1) // hotspot
  {
    if (type == 1) UnhandledEvent(eLocationHotspot, eModeLookat);
    else if (type == 2) UnhandledEvent(eLocationHotspot, eModeInteract);
    else if (type == 3) UnhandledEvent(eLocationHotspot, eModeUseinv);
    else if (type == 4) UnhandledEvent(eLocationHotspot, eModeTalkto);
    else if (type == 7) UnhandledEvent(eLocationHotspot, eModePickup);
    else if (type == 8) UnhandledEvent(eLocationHotspot, eModeUsermode1);
    else if (type == 9) UnhandledEvent(eLocationHotspot, eModeUsermode2);
  }
  else if (what == 2) // object
  {
    if (type == 0) UnhandledEvent(eLocationObject, eModeLookat);
    else if (type == 1) UnhandledEvent(eLocationObject, eModeInteract);
    else if (type == 2) UnhandledEvent(eLocationObject, eModeTalkto);
    else if (type == 3) UnhandledEvent(eLocationObject, eModeUseinv);
    else if (type == 5) UnhandledEvent(eLocationObject, eModePickup);
    else if (type == 6) UnhandledEvent(eLocationObject, eModeUsermode1);
    else if (type == 7) UnhandledEvent(eLocationObject, eModeUsermode2);
  }
  else if (what == 3) // character
  {
    if (type == 0) UnhandledEvent(eLocationCharacter, eModeLookat);
    else if (type == 1) UnhandledEvent(eLocationCharacter, eModeInteract);
    else if (type == 2) UnhandledEvent(eLocationCharacter, eModeTalkto);
    else if (type == 3) UnhandledEvent(eLocationCharacter, eModeUseinv);
    else if (type == 5) UnhandledEvent(eLocationCharacter, eModePickup);
    else if (type == 6) UnhandledEvent(eLocationCharacter, eModeUsermode1);
    else if (type == 7) UnhandledEvent(eLocationCharacter, eModeUsermode2);
  }
  else if (what == 4) // nothing
  {
    if (type == 1) UnhandledEvent(eLocationNothing, eModeLookat);
    else if (type == 2) UnhandledEvent(eLocationNothing, eModeInteract);
    else if (type == 3) UnhandledEvent(eLocationNothing, eModeUseinv);
    else if (type == 4) UnhandledEvent(eLocationNothing, eModeTalkto);
  }
  else if (what == 5) // inventory item
  {
    if (type == 0) UnhandledEvent(eLocationNothing, eModeLookat, inventory[game.inv_activated]);
    else if (type == 1) UnhandledEvent(eLocationNothing, eModeInteract, inventory[game.inv_activated]);
    else if (type == 2) UnhandledEvent(eLocationNothing, eModeTalkto, inventory[game.inv_activated]);
    else if (type == 3) UnhandledEvent(eLocationNothing, eModeUseinv, inventory[game.inv_activated]);
    else if (type == 4) // any other click on inventory...
    {
    }
  }
}


The included optional InventoryItem* parameter allows us to check in our new function whether we were actually using nothing or an inventory item (since LocationType does not distinguish between these).

Badger

ok, i've copied in the code (thanks :)), but it seems it has the same flaws as before..
It won't work on my custom cursor (ID 10, Sniff).

Code: ags
else if (what == 2) // object
  {
    if (type == 0) UnhandledEvent(eLocationObject, eModeLookat);
    else if (type == 1) UnhandledEvent(eLocationObject, eModeInteract);
    else if (type == 2) UnhandledEvent(eLocationObject, eModeTalkto);
    else if (type == 3) UnhandledEvent(eLocationObject, eModeUseinv);
    else if (type == 5) UnhandledEvent(eLocationObject, eModePickup);
    else if (type == 6) UnhandledEvent(eLocationObject, eModeUsermode1);
    else if (type == 7) UnhandledEvent(eLocationObject, eModeUsermode2);
    else if (type == 8) UnhandledEvent(eLocationObject, eModeSniff);
  }

and..

function UnhandledEvent(LocationType where, CursorMode what, InventoryItem *item)
{
  // put your unhandled event interactions here, i.e.
  if (where == eLocationObject)
  {
    if (what == eModeLookat)
    {
    }
    else if (what == eModeInteract)
    {
      Display("interact with object");
    }
    else if (what == eModeTalkto)
    {
      Display("Talk to object");
    }
    else if (what == eModeUseinv)
    {
      Display("use inv object");
    }
    else if (what == eModePickup)
    {
      Display("pick up object");
    }
    else if (what == eModeSniff)
    {
      Display("Sniff object");
    }
    else Display("ok?");
  }
}


The sniff won't work on the objects, though the others do.
was i meant to insert another code section to address this? (sorry if the answer is in your post khris, i was thinking monkey's was an easier format to port.)

thanks.

Badger

ok i solved it. Thanks lots for your help guys..what i did was use the earlier post of khris'
Code: ags

 int x = mouse.x;
    int y = mouse.y;
    if (mouse.Mode > 9 && !IsInteractionAvailable(x, y, mouse.Mode)) unhandled_event(GetLocationType(x, y), mouse.Mode);


then just used a basic unhandled_event and ignored the int parameters completely and used my earlier 'badclick' function:
Code: ags

function unhandled_event(int what,  int type){
  if (mouse.Mode == eModeTalkto){
  int talkobj=Random(5);
//my 5 responses to talk
}
}


it was the unhandled_event int parameters that were the biggest pain.

Thankyou so much for the help, learned lots, and glad i figured it out rather than copying :)
cheers guys :D

SMF spam blocked by CleanTalk