I have two characters. Right now, the mouse graphics default is the same for both. Is there a better way to change the mouse graphics for the 2nd character without putting this in every room?
if (player == cWoman) {
mouse.UseModeGraphic(eModeDapHandU); }
Not sure what you mean by "putting this in every room", the mouse is a global thing. It doesn't reset on a room change.
Anyway, the proper way is to (permanently) change the graphic of the mode when you switch the player character. Like:
function SwitchToWoman() {
Mouse.ChangeModeGraphic(eModeInteract, 123); // sprite slot 123 is woman's interact cursor
Mouse.ChangeModeGraphic(eModeTalkto, 124)); // sprite slot 124 is woman's interact cursor
cWoman.SetAsPlayer();
}
When I make the change it only affects the mouse on an interact area, not the default mouse. I would want it to change for both. The eModeDapHandU is a mouse cursor I set up.
Here was the code in the global script:
function repeatedly_execute() {
// put anything you want to happen every game cycle here
if (GetLocationType(mouse.x,mouse.y) > 0) {
// Mouse.UseModeGraphic(eModePointer); }
if(Mouse.Mode!=eModeUseinv) mouse.UseModeGraphic(eModePointer);}
else {
Mouse.UseDefaultGraphic(); }
Here is what I changed it to:
function repeatedly_execute() {
// put anything you want to happen every game cycle here
if (GetLocationType(mouse.x,mouse.y) > 0) {
// Mouse.UseModeGraphic(eModePointer); }
if(Mouse.Mode!=eModeUseinv) mouse.UseModeGraphic(eModePointer);}
else if (player == cWoman) {
mouse.UseModeGraphic(eModeDapHandU); }
else if (player == cMan) {
Mouse.UseDefaultGraphic(); }
Here's a better way to do this:
bool wasOverActiveArea;
void HandleCursor() {
if (Mouse.Mode == eModeUseinv) return; // do nothing
bool isOverActiveArea = GetLocationType(mouse.x, mouse.y) != eLocationNothing; // compare to enum!
if (isOverActiveArea && !wasOverActiveArea) {
// mouse just moved over active area
Mouse.UseModeGraphic(eModePointer); // pointer for both
}
else if (!isOverActiveArea && wasOverActiveArea) {
// mouse just left active area
if (player == cWoman) Mouse.UseModeGraphic(eModeDapHandU);
else Mouse.UseDefaultGraphic();
}
}
function repeatedly_execute() {
HandleCursor();
// other stuff
}
Hi, I added the change right before the repeatedly_execute and now the mouse for the female player is not working at all but using the default cursor.
Did I do this correctly?
SetGlobalInt(360,0);
SetGlobalInt(370,0);
SetGlobalInt(380,0);
SetGlobalInt(390,0);
SetGlobalInt(400,0);
SetGlobalInt(410,0);
}
#sectionend game_start // DO NOT EDIT OR REMOVE THIS LINE
bool wasOverActiveArea;
void HandleCursor() {
if (Mouse.Mode == eModeUseinv) return; // do nothing
bool isOverActiveArea = GetLocationType(mouse.x, mouse.y) != eLocationNothing; // compare to enum!
if (isOverActiveArea && !wasOverActiveArea) {
// mouse just moved over active area
Mouse.UseModeGraphic(eModePointer); // pointer for both
}
else if (!isOverActiveArea && wasOverActiveArea) {
// mouse just left active area
if (player == cWoman) Mouse.UseModeGraphic(eModeDapHandU);
else Mouse.UseDefaultGraphic();
} }
#sectionstart repeatedly_execute // DO NOT EDIT OR REMOVE THIS LINE
function repeatedly_execute() {
// put anything you want to happen every game cycle here
//if (GetLocationType(mouse.x,mouse.y) > 0) {
// Mouse.UseModeGraphic(eModePointer); }
// if(Mouse.Mode!=eModeUseinv) mouse.UseModeGraphic(eModePointer);}
//else if (player == cWoman) {
// mouse.UseModeGraphic(eModeDapHandU); }
//else if (player == cMan) {
// Mouse.UseDefaultGraphic(); }
HandleCursor();
if (player == cWoman) {
StrFormat(herscore," Puzzles: %d",GetGlobalInt(10));
ScoreHer.SetText(herscore);
ScoreHer.TextColor = cWoman.SpeechColor; }
if (player == cMan) {
StrFormat(hisscore," Puzzles: %d",GetGlobalInt(20));
ScoreHim.SetText(hisscore);
ScoreHim.TextColor = cMan.SpeechColor; }
In my snippet, the relevant lines are 7, 11 and 12.
Over active areas, the cursor should change to a pointer for both characters. Outside active areas, it should use the default one of the player is the man and the custom one when they're a woman.
What exactly fails?
I can't tell what "the mouse for the female player is not working at all" means exactly.
Hi, I got busy and did not have time to test this. I am back on it and can't get it to work.
To refresh. I currently have a blue hand cursor for all the hotspots, objects, etc. and an arrow cursor for when you are just walking around. I want to be able to switch the graphic for the woman character with a red hand. I want this switch whenever the character interacts with a hotspot or object. The cursor "pointer" is the man's blue hand and the cursor "DapHandU" is the woman's red hand. Right now with the script changed, I no longer get the arrow, only the hand, which should only be for hotspots etc.
I added a video to show how it is currently working, before the new changes, for better understanding. You will only see the blue hand in this video no matter who the character is.
https://www.youtube.com/watch?v=X9CLy6HqyYw
Here is the code in the script.
#sectionend game_start // DO NOT EDIT OR REMOVE THIS LINE
//New Area
bool wasOverActiveArea;
void HandleCursor() {
if (Mouse.Mode == eModeUseinv) return; // do nothing
bool isOverActiveArea = GetLocationType(mouse.x, mouse.y) != eLocationNothing; // compare to enum!
if (isOverActiveArea && !wasOverActiveArea) {
// mouse just moved over active area
if (player == cWoman) Mouse.UseModeGraphic(eModeDapHandU);
else if (player == cMan) Mouse.UseModeGraphic (eModePointer);
else Mouse.UseModeGraphic(eModePointer);
else if (!isOverActiveArea && wasOverActiveArea) { Mouse.UseDefaultGraphic(); }
// mouse just left active area
} }
//End New Area
#sectionstart repeatedly_execute // DO NOT EDIT OR REMOVE THIS LINE
function repeatedly_execute() {
// put anything you want to happen every game cycle here
//New Area
HandleCursor();
//End New Area
//Old cursor logic
// if (GetLocationType(mouse.x,mouse.y) > 0) {
// if(Mouse.Mode!=eModeUseinv) mouse.UseModeGraphic(eModePointer);}
// else {
// Mouse.UseDefaultGraphic(); }
//Old cursor logic end
Here's code that switches the cursor mode as opposed to the graphic:
bool wasOverActiveArea;
void HandleCursor() {
if (Mouse.Mode == eModeUseinv) return; // do nothing
bool isOverActiveArea = GetLocationType(mouse.x, mouse.y) != eLocationNothing; // compare to enum!
if (isOverActiveArea && !wasOverActiveArea) {
// mouse just moved over active area
Mouse.Mode = eModeInteract;
else if (!isOverActiveArea && wasOverActiveArea) {
// mouse just left active area
Mouse.Mode = eModeWalkto;
}
}
Switching to the woman should call
Mouse.ChangeModeGraphic(eModeInteract, SPRITE_SLOT_OF_RED_HAND);
and switching to the man should call
Mouse.ChangeModeGraphic(eModeInteract, SPRITE_SLOT_OF_BLUE_HAND);
To recap: moving the mouse only switches cursor modes between walking and interacting, switching the player character changes the sprite of the eModeInteract cursor.
(As an aside, I find the Mouse.UseModeGraphic() command quite problematic. It essentially fools the player, and is used as a quick fix instead of properly coding mouse behavior. It shouldn't be used.)
I must be missing something. Here's my code. Basically the eModeWalkto area is not kicking in. This should be my arrow and it never appears. The correct color is showing for each character now so that means it is working correctly over an active area of the screen. I also want to note that in my global script and in my rooms I have this: mouse.DisableMode(eModeWalkto); probably since it is a first person game. What is the mode that defaults for just moving room to room?
bool wasOverActiveArea;
void HandleCursor() {
if (Mouse.Mode == eModeUseinv) return; // do nothing
bool isOverActiveArea = GetLocationType(mouse.x, mouse.y) != eLocationNothing; // compare to enum!
if (isOverActiveArea && !wasOverActiveArea) {
// mouse just moved over active area
Mouse.Mode = eModeInteract;
if (player == cWoman) Mouse.ChangeModeGraphic(eModeInteract, 485);
if (player == cMan) Mouse.ChangeModeGraphic(eModeInteract, 16); }
else if (!isOverActiveArea && wasOverActiveArea)
Mouse.Mode = eModeWalkto;
Mouse.ChangeModeGraphic(eModeWalkto, 22); {
// mouse just left active area
}
}
Also, I changed the eModeWalkto to Pointer and I get my arrow back but it only shows on the interface dropdown on top of screen. It seems like the whole screen is being read as an active area.
Update: I got it working by removing the "was over active area" statements. On some screens I can see the graphic on the cursor switching images and the buttons on my save/load gui are now unclickable.
//New Area
bool wasOverActiveArea;
void HandleCursor() {
if (Mouse.Mode == eModeUseinv) return; // do nothing
bool isOverActiveArea = GetLocationType(mouse.x, mouse.y) != eLocationNothing; // compare to enum!
// if (isOverActiveArea && !wasOverActiveArea) {
if (isOverActiveArea) {
// mouse just moved over active area
Mouse.Mode = eModeInteract; }
else if (!isOverActiveArea) {
Mouse.Mode = eModePointer;
Mouse.ChangeModeGraphic(eModePointer, 22); }
// mouse just left active area
//End New Area
}
#sectionstart repeatedly_execute // DO NOT EDIT OR REMOVE THIS LINE
function repeatedly_execute() {
// put anything you want to happen every game cycle here
//New Area
HandleCursor();
//End New Area
//Old cursor logic
// if (GetLocationType(mouse.x,mouse.y) > 0) {
// if(Mouse.Mode!=eModeUseinv) mouse.UseModeGraphic(eModePointer);}
// else {
// Mouse.UseDefaultGraphic(); }
//Old cursor logic end
//New cursor logic
if (GetLocationType(mouse.x,mouse.y) > 0) {
if ((Mouse.Mode!=eModeUseinv) && (Mouse.Mode == eModeInteract)) {
if (player == cWoman) Mouse.ChangeModeGraphic(eModeInteract, 485);
else if (player == cMan) Mouse.ChangeModeGraphic(eModeInteract, 16); }
}
//New cursor logic end
The HandleCursor function tracks changes in LocationType. Each time the mouse leaves or enters an active area, the relevant block is triggered and changes the cursor accordingly.
For a first-person game that doesn't use eModeWalkto, the code needs to be adjusted accordingly.
You said the cursor is supposed to be a hand over objects and the like, and a pointer sprite is used for walking around. How did you implement room changes? Because if room exits are hotspots, how does the game differentiate between exits and other hotspots? And which event are you using to process clicks? AnyClick? Or Interact?
1. I went through though the global script and found entries related to the mouse. At the beginning I disable modes Walkto, Talkto and Lookat.
2. I am using this to determine either arrow pointer or finger pointer. I am curious what defines Mouse User Default Graphic.
if (GetLocationType(mouse.x,mouse.y) > 0) {
if(Mouse.Mode!=eModeUseinv) mouse.UseModeGraphic(eModePointer);}
else {
Mouse.UseDefaultGraphic();
3. There are multiple instances on Guis that the Mouse Mode is being selected. Here's a few:
These deal with the Inventory box buttons:
function btnInvOK_Click(GUIControl *control, MouseButton button) {
// They pressed the OK button, close the GUI
gInventory.Visible = false;
mouse.UseDefaultGraphic();
}
#sectionend btnInvOK_Click // DO NOT EDIT OR REMOVE THIS LINE
function btnInvSelect_Click(GUIControl *control, MouseButton button) {
// They pressed SELECT, so switch to the Get cursor
mouse.Mode = eModeInteract;
// But, override the appearance to look like the arrow
mouse.UseModeGraphic(eModePointer);
}
#sectionend btnInvSelect_Click // DO NOT EDIT OR REMOVE THIS LINE
#sectionstart btnIconCurInv_Click // DO NOT EDIT OR REMOVE THIS LINE
function btnIconCurInv_Click(GUIControl *control, MouseButton button) {
if (player.ActiveInventory != null)
mouse.Mode = eModeUseinv;
}
#sectionend btnIconCurInv_Click // DO NOT EDIT OR REMOVE THIS LINE
This is the icon bar or interface bar
// hide the icon bar and show a GUI
function open_gui(GUI* gui_to_open)
{
// if (gui_to_open != gInventory)
// {
// lblOverHotspot.Visible = false;
// }
gGui3.Visible = false;
mouse.UseModeGraphic(eModePointer);
gui_to_open.Visible = true;
}
// hide the GUI and show the icon bar
function close_gui(GUI* gui_to_close)
{
gui_to_close.Visible = false;
mouse.UseDefaultGraphic();
gGui3.Visible = true;
// lblOverHotspot.Visible = true;
// gIconbar.Visible = true;
}
4. For movement in the rooms, when I turn left, right, up or down, and the curser finger pointer turns direction, I have created User modes with the different pointing direction graphic.
Multiple hotspots/entryways
if (Hotspot.GetAtScreenXY(mouse.x, mouse.y) == hrighthall) {
mouse.UseModeGraphic(eModeUsermode2); }
if (Hotspot.GetAtScreenXY(mouse.x, mouse.y) == hlefthall) {
mouse.UseModeGraphic(eModeUsermode3); }
if (Hotspot.GetAtScreenXY(mouse.x, mouse.y) == hdownstairs) {
mouse.UseModeGraphic(eModeUsermode5); }
5. To sum this all up, I think #2 above is the "all control of the pointer vs finger and any changes to that scenario will be notated in the global script or the room script. If this is true, then I don't understand how it works on hotspots and objects based on only GetLocationType.
First of all, this:
if (GetLocationType(mouse.x,mouse.y) > 0) {
might cause issues. Afaik, enum values start at 1 by default, so unless set to 0 by the engine explicitly, eLocationNothing might have a value > 0.
To be safe, change this to
if (GetLocationType(mouse.x,mouse.y) != eLocationNothing) {
Next, the exit arrow stuff doesn't require code in every room if you use a hotspot custom property. Global behavior should never be implemented on a per-room basis, that's just loads of duplicate code. If you use a second property to store the room number the exit is leading to, you don't even need to have event functions for the exit hotspots, just some global code that detects a click on an exit.
Anyway, as far as I can tell you're using just eModeInteract and eModeUseinv and keep changing the cursor sprite.
This approach is fine but could be streamlined a great deal.
For instance the cursor sprite can simply be changed by using Mouse.ChangeModeGraphic(CursorMode, int slot); there's no need to set up custom cursors just to use their assigned sprite.
Ok...so I got this figured out but I still don't understand. See code below. If I use Mouse.UserModeGraphic with my custom cursor mode it works. If I use Mouse.ChangeModeGraphic with the sprite # and with the Interact Mode, I lose my arrow. (see commented out lines)
//New cursor logic
if (GetLocationType(mouse.x,mouse.y) != eLocationNothing) {
if(Mouse.Mode!=eModeUseinv) {
if (player == cWoman) Mouse.UseModeGraphic(eModeDapHandU);
// if (player == cWoman) Mouse.ChangeModeGraphic(eModeInteract, 485);
if (player == cMan) Mouse.UseModeGraphic(eModePointer); } }
// if (player == cMan) Mouse.ChangeModeGraphic(eModeInteract, 16); } }
else { Mouse.UseDefaultGraphic (); }
//New cursor logic end
Here are two videos showing working correctly and incorrectly (when I lose the arrow).
Correct: https://youtu.be/EQFJbFcnn2A
Inccorrect: https://youtu.be/7I21LJAYhQE