Which template for only Use/talk=>LMB and look=>RMB?

Started by Tosek, Thu 06/06/2013 09:30:21

Previous topic - Next topic

Tosek

Hi there,

I am new to AGS (comming from germany) and have a question to cursors/ templates. I serached the forum but did not find the answer.

I am looking for a template (or description) how to implement a command system like this:
Left mouse button (without changing a verb manually):
-  dependung on what is clicked: talk to person, use object, if an inventory item is active => use inventory item on object/person
- the mouse cursor should automatically change to an talk cursor or an use cursor (depending on where it is over)

Right mouse button (always)
- look/ examine person/ object, even if I am in the inventory

Which template can I use for that? (Don't know which adventure game used such an command system, but I think there is more than one)

Thanx in advance
Tosek

san.daniele

look around for something like 2-click-control, you'll find several helpful topics.

when I was in need of the same thing, this topic helped me most: http://www.adventuregamestudio.co.uk/forums/index.php?topic=48051.0
great simple starting point. It's easily understandable, but needs customization to adapt to your needs. So a great way to practice/learn some more scripting.

Ghost

There's always the Beneath A Steel Sky template. It has all you need and is extremely tame in terms of scripting.

Just go over to the resources page http://americangirlscouts.org/agsresources/Templates.html . It's the third entry in the list.

Und willkommen im Club!  (nod)


Khris

There's no current, good template I know of, mostly because implementing this is just a matter of replacing a few blocks of code.

Here's code that'll change cursors automatically:
http://www.adventuregamestudio.co.uk/forums/index.php?topic=48063.msg636451800#msg636451800
(the question was originally about displaying an exit cursor over exit regions, if you don't want that (yet), just remove the two lines with the ALL CAPS stuff for now.)

You will also need to modify the on_mouse_click function in GlobalScript.asc.
In the (button == eMouseRight) block, instead of all the code that changes to the next mode, use
Code: ags
    ProcessClick(mouse.x, mouse.y, eMouseLookat);


Edit:
The BASS template is from 2003. I wouldn't use that.

Ghost

Quote from: Khris on Thu 06/06/2013 11:36:08
The BASS template is from 2003. I wouldn't use that.

It does work though, I have used it with AGS 3.1 and had no problems getting it to work.

I have modified and adjusted it a bit- if there is interest I can easily upload a template. That would be from 2012 then  ;)

Phemar

The code I posted in this topic should work fine.

Code: ags
bool invMode = false;

function on_mouse_click (MouseButton button) {

  int mX = mouse.x,  mY =  mouse.y;

  if (button == eMouseLeft) {
    
    if (invMode) {  // if in inventory mode
      ProcessClick (mX, mY, eModeUseinv); // Run "Use Inventory on" action.
      invMode = false; // Turn off inventory mode
    }
    
    else if (GetLocationType(mX, mY) == eLocationNothing) // No hotspot, so walk
      player.Walk (GetViewportX () + mX, GetViewportY () + mY);
    
    else if (GetLocationType(mX, mY) == eLocationCharacter) // Character, so use 'Talk to'
      ProcessClick (mX, mY, eModeTalkto);

    else // Hotspot, so process click as "Interact"
      ProcessClick (mX, mY, eModeInteract);

  }
  
  else if (button == eMouseRight) {
    
    if (invMode) // If "Use Inventory on", switch it off
      invMode = false;
    
    else {
      
      if (GetLocationType(mX, mY) == eLocationNothing) // No hotspot, so walk
        player.Walk(GetViewportX () + mX, GetViewportY () + mY);
      
      else // Process click as "Look at"
        ProcessClick(mX, mY, eModeLookat);
        
    }
  }
  
  // Inventory click handling:
  
  else if (button == eMouseLeftInv) {
    
    if (!invMode) {  // If not in "Use inventory mode"
      // Set the active inventory and switch inventory mode on
      player.ActiveInventory = inventory[game.inv_activated];
      invMode = true;
    }
    
    else { // The player is inventory mode, run "Use inventory on" interaction
      inventory[game.inv_activated].RunInteraction(4);
      invMode = false;
    }
  }
  
  else if (button == eMouseRightInv) // Else, look at the inventory item
    inventory[game.inv_activated].RunInteraction(1);

}


But, if you're going to be using a system where the modes "Talk to" and "Interact" never overlap, you should probably just abandon Talk and only use Interact.
Then just trick the player into thinking they're using a Talk action by writing your Talk scripts under the "Interact" node, then use a GUI label to change from "Use @overhotspot@" when it's over an object or hotspot to "Talk to @overhotspot@" when it's over a character.

What I like to do actually is create a String property (applied to all hotspots, objects and characters, with a default value of "Use") and then change that to the appropriate verb for the object/character/hotspot.

That way you can have "Climb Tree", "Pick up Small Rock", "Talk to Shopkeeper", etc.

Tosek

Quote from: Ghost on Thu 06/06/2013 11:56:13
I have modified and adjusted it a bit- if there is interest I can easily upload a template. That would be from 2012 then  ;)

Could be a helpful starting point I think. Would you?

Tosek

OK, I downloaded the BASS Template from that site und placed the agt file in the templates directory. But when I start a new game the BASS template is not offered to choose. Only the 4 standard templates are available. What am I doing wrong?

Khris

Since the template is so outdated, AGS can't import it directly.
You can load it in AGS 2.72, save it, then move the game folder to AGS 3.2.1 and open it.

Or PM Ghost and get the template from him.

Adeel

My Recommendation: Use Phemar's template, Tosek. Its simple. Like he said, you don't need to do seperate scripting for TALK and WALK if you want to go with this type of style. Seriously, no one will be able to tell the difference once the game's ready.

Phemar

Quote from: Adeel S. Ahmed on Fri 07/06/2013 15:10:31...you don't need to do seperate scripting for TALK and WALK...

I think you meant TALK and INTERACT ;)

Although if you want the functionality I think you described in your first post, you probably want use code like this:

Script Header:
Code: ags
// Replace this number with the number of the sprite used for talking:
#define MOUSE_TALK_SPRITE 54
// Replace this number with the number of the sprite used for interacting:
#define MOUSE_INTERACT_SPRITE 55
// Replace this number with your normal mouse sprite number:
#define MOUSE_NORMAL_SPRITE 56


Then in repeatedly_execute:
Code: ags
function repeatedly_execute () {
  
  if (GetLocationType(mouse.x, mouse.y) == eLocationCharacter)
    Mouse.ChangeModeGraphic (mouse.Mode, MOUSE_TALK_SPRITE);
  
  else if (GetLocationType(mouse.x, mouse.y) == eLocationHotspot
        || GetLocationType(mouse.x, mouse.y) == eLocationObject)
    Mouse.ChangeModeGraphic (mouse.Mode, MOUSE_INTERACT_SPRITE);
  
  else
    Mouse.ChangeModeGraphic (mouse.Mode, MOUSE_NORMAL_SPRITE);

}

Khris

I think it's much more straightforward to change the actual mouse.Mode in repeatedly_execute, then simply call ProcessClick() in on_mouse_click.

Phemar

Ok, so with changing mouse mode, the full code would probably be something like this:

In repeatedly_execute:
Code: ags
function repeatedly_execute () {
  
  if (GetLocationType(mouse.x, mouse.y) == eLocationCharacter)
    mouse.Mode = eModeTalkto;
  
  else if (GetLocationType(mouse.x, mouse.y) == eLocationHotspot
        || GetLocationType(mouse.x, mouse.y) == eLocationObject)
    mouse.Mode = eModeInteract;
  
  else
    mouse.Mode = eModeWalkto;

}


Then in on_mouse_click:
Code: ags
bool invMode = false;

function on_mouse_click (MouseButton button) {

  int mX = mouse.x,  mY =  mouse.y;

  if (button == eMouseLeft) {
    
    if (invMode) {  // if in inventory mode
      ProcessClick (mX, mY, eModeUseinv); // Run "Use Inventory on" action.
      invMode = false; // Turn off inventory mode
    }
    
    else if (GetLocationType(mX, mY) == eLocationNothing) // No hotspot, so walk
      player.Walk (GetViewportX () + mX, GetViewportY () + mY);

    else // Hotspot, so process click as "Interact"
      ProcessClick (mX, mY, eModeInteract);

  }
  
  else if (button == eMouseRight) {
    
    if (invMode) // If "Use Inventory on", switch it off
      invMode = false;
    
    else {
      
      if (GetLocationType(mX, mY) == eLocationNothing) // No hotspot, so walk
        player.Walk(GetViewportX () + mX, GetViewportY () + mY);
      
      else // Process click as "Look at"
        ProcessClick(mX, mY, eModeLookat);
        
    }
  }
  
  // Inventory click handling:
  
  else if (button == eMouseLeftInv) {
    
    if (!invMode) {  // If not in "Use inventory mode"
      // Set the active inventory and switch inventory mode on
      player.ActiveInventory = inventory[game.inv_activated];
      invMode = true;
    }
    
    else { // The player is inventory mode, run "Use inventory on" interaction
      inventory[game.inv_activated].RunInteraction(4);
      invMode = false;
    }
  }
  
  else if (button == eMouseRightInv) // Else, look at the inventory item
    inventory[game.inv_activated].RunInteraction(1);

}

Snarky

I'd make it so if you right-click over the inventory while holding an inventory item, it drops the item (rather than looking at the item under the cursor). That feels much more consistent to me.

SMF spam blocked by CleanTalk