Problems with the speed of cursor views

Started by Ezekiel000, Tue 11/08/2009 22:58:05

Previous topic - Next topic

Ezekiel000

I wanted to tint my animated cursors when they are over objects or hotspots that the current cursor can be used on. So if an object has a response to being looked at then the cursor would be tinted red. Using examples around the forum I ended up with this code in the global script under repeatedly execute:

Code: ags

	if (GetLocationType(mouse.x,mouse.y)==eLocationHotspot) {
		Hotspot* h = Hotspot.GetAtScreenXY(mouse.x, mouse.y);
				if (mouse.Mode==eModeTalk) {
					if (h.GetProperty("TALK_A")) {
						mouse.ChangeModeView(eModeTalk, CUR_TALK_A);
						}
					else mouse.ChangeModeView(eModeTalk, CUR_TALK);
					}
				if (mouse.Mode==eModeGrab) {
				  if (h.GetProperty("GRAB_A")) {
				    mouse.ChangeModeView(eModeGrab, CUR_GRAB_A);
						}
				  else mouse.ChangeModeView(eModeGrab, CUR_GRAB);
					}
				if (mouse.Mode==eModeLook) {
				  if (h.GetProperty("LOOK_A")) {
				    mouse.ChangeModeView(eModeLook, CUR_LOOK_A);
						}
				  else mouse.ChangeModeView(eModeLook, CUR_LOOK);
				  }
		}
	if (GetLocationType(mouse.x,mouse.y)==eLocationObject) {
		Object* o = Object.GetAtScreenXY(mouse.x, mouse.y);
				if (mouse.Mode==eModeTalk) {
					if (o.GetProperty("TALK_A")) {
						mouse.ChangeModeView(eModeTalk, CUR_TALK_A);
						}
					else mouse.ChangeModeView(eModeTalk, CUR_TALK);
					}
				if (mouse.Mode==eModeGrab) {
				  if (o.GetProperty("GRAB_A")) {
				    mouse.ChangeModeView(eModeGrab, CUR_GRAB_A);
						}
				  else mouse.ChangeModeView(eModeGrab, CUR_GRAB);
					}
				if (mouse.Mode==eModeLook) {
				  if (o.GetProperty("LOOK_A")) {
				    mouse.ChangeModeView(eModeLook, CUR_LOOK_A);
						}
				  else mouse.ChangeModeView(eModeLook, CUR_LOOK);
				  }
		}
   if (GetLocationType(mouse.x,mouse.y)==eLocationNothing) {
 				if (mouse.Mode==eModeTalk) mouse.ChangeModeView(eModeTalk, CUR_TALK);
				if (mouse.Mode==eModeGrab) mouse.ChangeModeView(eModeGrab, CUR_GRAB);
				if (mouse.Mode==eModeLook) mouse.ChangeModeView(eModeLook, CUR_LOOK);
			  }
		}

Which on the whole works well but now all the cursors animations are running too fast, what is the reason for this? and how and I slow them down to their original speed?

Khris

#1
As soon as you move the mouse over a hotspot/object, mouse.ChangeModeView is called 40 times per second.

Code: ags
// above rep_ex
int old_mouse_view;

//inside
  bool _A;
  String mm = "";
  int v;
  if (mouse.Mode == eModeTalk) { mm = "TALK"; v = CUR_TALK; }
  if (mouse.Mode == eModeGrab) { mm = "GRAB"; v = CUR_GRAB; }
  if (mouse.Mode == eModeLook) { mm = "LOOK"; v = CUR_LOOK; }
  mm = mm.Append("_A");

  int lt = GetLocationType(mouse.x,mouse.y);
  if (lt == eLocationHotspot) {
    Hotspot*h = Hotspot.GetAtScreenXY(mouse.x, mouse.y);
    if (mm.Length == 2) v = CUR_WALK;
    else _A = h.GetProperty(mm);
  }
  else if (lt == eLocationObject) {
    Object*o = Object.GetAtScreenXY(mouse.x, mouse.y);
    _A = o.GetProperty(mm);
  }
  
  if (_A) v++;  // assuming that the tinted view's number is standard view + 1

  if (v != old_mouse_view) {   // only change if necessary
    mouse.ChangeModeView(mouse.Mode, v);
    old_mouse_view = v;
  }


Edit: changed code to avoid crash

Ezekiel000

#2
Ah right I hadn't realised that, I'm not very experienced with scripting/coding.
That seemed to work at first but it called the wrong animations so I reorganised the cursor animations to be what it expected and updated the cursors animation numbers, but now the Look cursor seems to show up as the grab cursor and the grab cursor shows up as the tinted talk cursor.

Edit:
I just loaded it up again to check something and the cursors all seem to be fine now, thank you for your solution.
But the crash on hovering over the door hotspots is still occuring.

Properties Schema
TALK_A Boolean
LOOK_A Boolean
GRAB_A Boolean

The hotspots that crash the game use this script for hover:
Code: ags
 
   mouse.SaveCursorUntilItLeaves();
   mouse.Mode = eModeWalk;
   mouse.UseModeGraphic(eModeWalk);

These hotspots have none of the properties ticked. Any ideas on what I did wrong?

Matti

Please use the [ code ] tags, it's so much easier to read.

The line below is not a link, but a reminder:



Khris

A quick solution:

Code: ags
if (lt == eLocationHotspot) {
    Hotspot*h = Hotspot.GetAtScreenXY(mouse.x, mouse.y);
    if (m.Length == 2) v = CUR_WALK;
    else _A = h.GetProperty(mm);
  }


The crash occurred because as soon as the mouse.Mode was changed to eModeWalk, the line tried to GetProperty("_A") which doesn't exist.
(Please state the exact wording of the error message and the line next time, though :))

Now all you need to do is add a view called CUR_WALK.

Ezekiel000

I wasn't sure where that code should go so I may have stuck it in the wrong place, but I still get the crash.
My global script
Code: ags

// main global script file
bool pressingTAB;
int old_mouse_view;

#sectionstart game_start  // DO NOT EDIT OR REMOVE THIS LINE
function game_start() // called when the game starts, before the first room is loaded
  {
  }
#sectionend game_start  // DO NOT EDIT OR REMOVE THIS LINE


#sectionstart repeatedly_execute  // DO NOT EDIT OR REMOVE THIS LINE
function repeatedly_execute() 
{
  {
  if (IsKeyPressed(9)) {
  if (pressingTAB == false) {
    if (gInventory.Visible == false) gInventory.Visible = true;
    else if (gInventory.Visible == true) gInventory.Visible = false;
  }
  pressingTAB = true;
	}
	else pressingTAB = false;
	}
{
  bool _A;
  String mm = "";
  int v;
  if (mouse.Mode == eModeTalk) { mm = "TALK"; v = CUR_TALK; }
  if (mouse.Mode == eModeGrab) { mm = "GRAB"; v = CUR_GRAB; }
  if (mouse.Mode == eModeLook) { mm = "LOOK"; v = CUR_LOOK; }
  mm = mm.Append("_A");

  int lt = GetLocationType(mouse.x,mouse.y);
  if (lt == eLocationHotspot) {
    Hotspot*h = Hotspot.GetAtScreenXY(mouse.x, mouse.y);
    _A = h.GetProperty(mm);
  }
  else if (lt == eLocationObject) {
    Object*o = Object.GetAtScreenXY(mouse.x, mouse.y);
    _A = o.GetProperty(mm);
  }
	if (lt == eLocationHotspot) {
    Hotspot*h = Hotspot.GetAtScreenXY(mouse.x, mouse.y);
    if (mm.Length == 2) v = CUR_WALK;
    else _A = h.GetProperty(mm);
  }  
  if (_A) v++;  // assuming that the tinted view's number is standard view + 1

  if (v != old_mouse_view) {   // only change if necessary
    mouse.ChangeModeView(mouse.Mode, v);
    old_mouse_view = v;
		}
	}
}
#sectionend repeatedly_execute  // DO NOT EDIT OR REMOVE THIS LINE


#sectionstart on_key_press  // DO NOT EDIT OR REMOVE THIS LINE
function on_key_press(int keycode) // called when a key is pressed. keycode holds the key's ASCII code
  {
  if (IsGamePaused()==1) keycode=0; // game paused, so don't react to keypresses
  if (keycode==17) QuitGame(1); // Ctrl-Q
  if (keycode==363) SaveGameDialog(); // F5
  if (keycode==365) RestoreGameDialog(); // F7
  if (keycode==367) RestartGame(); // F9
  if (keycode==434) SaveScreenShot("scrnshot.pcx");  // F12
  if (keycode==19) Debug(0,0); // Ctrl-S, give all inventory
  if (keycode==22) Debug(1,0); // Ctrl-V, version
  if (keycode==1) Debug(2,0); // Ctrl-A, show walkable areas
  if (keycode==24) Debug(3,0); // Ctrl-X, teleport to room
  }
#sectionend on_key_press  // DO NOT EDIT OR REMOVE THIS LINE
 

#sectionstart on_mouse_click  // DO NOT EDIT OR REMOVE THIS LINE
function on_mouse_click(MouseButton button) // called when a mouse button is clicked. button is either LEFT or RIGHT
  {
  if (IsGamePaused() == 1) // Game is paused, so do nothing (ie. don't allow mouse click)
    {
    }
  else if (button == eMouseLeft) 
    {
    ProcessClick(mouse.x,mouse.y, mouse.Mode);
  }
  else if (mouse.Mode == eModeWalk){ //when right-clicking disabled, do nothing
		}
		else // right-click, so cycle cursor
		{   
			mouse.SelectNextMode();
    }
  }
#sectionend on_mouse_click  // DO NOT EDIT OR REMOVE THIS LINE


#sectionstart interface_click  // DO NOT EDIT OR REMOVE THIS LINE
function interface_click(int interface, int button) 
  {
  }
#sectionend interface_click  // DO NOT EDIT OR REMOVE THIS LINE


The error is:
in Global script (line 37)
Error: GetProperty: no such property found in schema. Make sure you are using the property's name, and not its description, when calling this command.

I added a new view CUR_WALK and a property WALK_A

Mazoliin

Let me just say that your brackets seem to be all over the place. I don't know if they're responsible for the error but it should be fixed:

Code: ags

#sectionstart repeatedly_execute  // DO NOT EDIT OR REMOVE THIS LINE
function repeatedly_execute() 
{
  { //What is this doing here? <------------
  if (IsKeyPressed(9)) {
  if (pressingTAB == false) {
    if (gInventory.Visible == false) gInventory.Visible = true;
    else if (gInventory.Visible == true) gInventory.Visible = false;
  }
  pressingTAB = true;
	}
	else pressingTAB = false;
	} //And this <------------
{ //Not to forget this one <------------
  bool _A;
  String mm = "";
  int v;

  ==== CODE ===

  if (v != old_mouse_view) {   // only change if necessary
    mouse.ChangeModeView(mouse.Mode, v);
    old_mouse_view = v;
		}
	} //Here's one more <------------
}
#sectionend repeatedly_execute  // DO NOT EDIT OR REMOVE THIS LINE


Unless, of course, I'm missing something and is just acting like a idiot...

Khris

The piece of code I posted wasn't meant to be added but to replace the original "if (lt == eLocationHotspot)" block.
I've edited my first reply accordingly.

Ezekiel000

Ah right sorry about that as I said before I'm not very experienced with coding. Although I can't test if it works as it comes up with:
Undefined symbol m in line 37 (which is below)
Code: ags

    if (m.Length == 2) v = CUR_WALK;


I don't understand what m is meant to be so I'm not sure how to go about fixing it.

As for the brackets they seemed sensible at the time I put them in I'll test if they are needed. (I think I went through a phrase of when in doubt enclose in brackets  ???)

Khris

Sorry, it's supposed to be 'mm'.

About indentation: you can pretty much eliminate a whole lot of possible mistakes by choosing one of the established methods of indentation.

I use this one:

Code: ags
function a() {
  do();
  if (b) {
    blah();
    while(c) {
      d;
      e;
      f;
    }
    bleh();
  }
  else {
    bleeh();
  }
  return m;
}


Always keep the closing bracket in the same column as its corresponding opening bracket (there's a school of indentation that says don't but I won't go into why I think that one sucks).

Ezekiel000

Thank you it works perfectly now.
I try to follow that scheme of indentation but after a few I start getting lost  :)

And Mazoliin you were right I didn't need those extra brackets, thanks.

Khris

It's really not that complicated. AGS even does it automatically when you hit enter after either bracket.
Whenever you open a block of code with a "{", indent every subsequent line one more. When you close the block using a "}", put it in the same column as its counterpart, going back one step.
If you strictly follow this, you don't even have to pay attention to the number of steps or brackets. As soon as you get back to no indentation, you've put the last closing bracket (the function body's).

Ezekiel000

How can I modify that code so that if the cursor is anything but those three modes the whole thing is ignored? as I'm getting the same crashes for the use inventory cursor and some other crashes at random times complaining of the same thing, that it can't find that property.

SMF spam blocked by CleanTalk