MODULE/TEMPLATE: Verbcoin v1.1 - 19 April 2011 - Now..some new stuff!

Started by monkey0506, Sun 13/02/2011 02:30:28

Previous topic - Next topic

TheRoger

There is no eModeWalkTo function anywhere...used ctrl+f

Maybe it's possible to do, that coin appear only when it is pressed on hotspot/object/npc ?

monkey0506

I'm sorry, but are you using this module or template?

You don't seem to have a grasp on scripting in AGS at all from what you're saying. There's no such thing as a "eModeWalkTo function"..and Ctrl+F does not have a built-in function. Mouse-clicks are still processed through on_mouse_click.

Unless you're using this module, which it seems that you're not, then this discussion really doesn't belong here.

You need to understand how basic game logic works in AGS anyway or you're not going to be able to get any of this to work.

TheRoger

Wow...I did it!!! It's working the way I want  ;D

I know that eModeWalkTo is not a function, I'm not native English speaker, so I didn't knew how to call that.
Ctrl+F means that search box.

Umm...is it possible to make, that when you use "pick up" mode, it wouldn't write hotspot/object name in status bar, just "pick up"

I believe it should be done in repeatedly execute section, these lines:

Code: ags
if (String.IsNullOrEmpty(Verbcoin.ActionText)) lblLocation.Text = Verbcoin.LocationName;
  else lblLocation.Text = String.Format("%s %s", Verbcoin.ActionText, Verbcoin.LocationName);


Also, where is Inventory interaction code? Because I also get VerbCoin in inventory view, when I press on item.

monkey0506

I'm still..confused..but hey, you got it working.

As for your question about pick up mode, that..still comes down to really basic logic:

Code: ags
// repeatedly_execute
  if (String.IsNullOrEmpty(Verbcoin.ActionText)) lblLocation.Text = Verbcoin.LocationName;
  else if (Verbcoin.ActionText == "Pick up") lblLocation.Text = Verbcoin.ActionText;
  else lblLocation.Text = String.Format("%s %s", Verbcoin.ActionText, Verbcoin.LocationName);


The code controlling the verbcoin in relation to the inventory is hard-coded as part of the module. I could make it optional to ignore inventory items, but it's more than just one or two lines of code.

TheRoger

I tried this, it still writes with hotspot name.

I changed PickUp mode to open Inventory, and when I drag mouse there, this is what I get.



It should be just Open Inventory, without PC (object name).

monkey0506

You changed what you wanted to do and wonder why the solution I provided doesn't fit a different problem. How strange.

Do this:

Code: ags
// repeatedly_execute
  if (String.IsNullOrEmpty(Verbcoin.ActionText)) lblLocation.Text = Verbcoin.LocationName;
  else if (GUIControl.GetAtScreenXY(mouse.x, mouse.y) == btnOpenInv) lblLocation.Text = Verbcoin.ActionText;
  else lblLocation.Text = String.Format("%s %s", Verbcoin.ActionText, Verbcoin.LocationName);

TheRoger


monkey0506


silverwolfpet

Here's a challenge!

I've been using this module/template... it's brilliant. Never failed me so far.
However... I'm trying to make a little tweak to it for my game.

If you click on any object, you have USE, LOOK AT and TALK TO.
But how can I change the USE function to PICK UP for certain objects? not all...just for some.

Given that, how can I change the string on the bottom of the screen from
Use rock on fence
to
Smash fence
(or any other sentence I want to show) ?

monkey0506

QuoteGUI* Verbcoin.CoinGUI

  Used to get or set the GUI used as the "coin" of the verbcoin. This GUI *must* be the OwningGUI of any Buttons that
  you want to use on the verbcoin.

  Example:

    Verbcoin.CoinGUI = gVerbcoin;

  You would do something like this in game_start to set up your GUI for the first time, and of course it can be changed
  at runtime if needed.
 
  NOTE: Since all interaction text and mouse modes are linked to their respective Button controls, if the CoinGUI is
  changed at runtime, ALL of this information will be LOST. If you are using more than one GUI in your game, consider
  this carefully when setting up your game. You may want to just rearrange the existing GUI, or possibly use a custom
  function to switch between the GUIs.

  See Also: Verbcoin.AddButton, Verbcoin.RemoveButton, Verbcoin.XOffset, Verbcoin.YOffset

SetActionText functions:
************************

void Character.SetActionText(Button*, String actionText)
void Hotspot.SetActionText(Button*, String actionText)
void InventoryItem.SetActionText(Button*, String actionText)
void Object.SetActionText(Button*, String actionText)

  These four extender methods are provided by the module so that you can set custom interaction text for individual
  items. If the specified button is not in-use by the module then this function is ignored. To disable the custom
  interaction text and use the default instead, simply pass null as the second parameter.

  Example:

    iCracker.SetActionText(btnTalk, "Taste");

  Changes the interaction text for the iCracker inventory item to "Taste". This doesn't affect the default interaction
  text, so other items will still use "Talk to" as the action text, unless they have a custom value supplied.

  See Also: Verbcoin.ActionText, Verbcoin.ButtonActionText, Verbcoin.SetButtonActionText, GetActionText functions

So, seeing as you're using two separate GUIs, you'd need to make some very special provisions when changing from one character to another. What I'd actually recommend you do instead of using two separate GUIs is just to change the button graphics (and possibly the button action text). So, just going off the code I gave you before:

Code: ags
void CopyButtonGraphics(Button *from, Button *to)
{
  to.NormalGraphic = from.NormalGraphic;
  to.MouseOverGraphic = from.MouseOverGraphic;
  to.PushedGraphic = from.PushedGraphic;
  to.Width = from.Width;
  to.Height = from.Height;
}

void SetPlayer(Character *theCharacter)
{
  if (theCharacter == cKauff)
  {
    Verbcoin.CoinGUI.BackgroundGraphic = gKauffVerbcoin.BackgroundGraphic;
    Verbcoin.CoinGUI.SetSize(gKauffVerbcoin.Width, gKauffVerboin.Height);
    Verbcoin.XOffset = gKauffVerbcoin.Width / 2;
    Verbcoin.YOffset = gKauffVerbcoin.Height / 2;
    Verbcoin.SetButtonActionText(btnLook, "Analyze");
    Verbcoin.SetButtonActionText(btnTalk, "Answer Question to");
    CopyButtonGraphics(btnKauffLook, btnLook);
    CopyButtonGraphics(btnKauffTalk, btnTalk);
    CopyButtonGraphics(btnKauffUse, btnUse);
  }
  else if (theCharacter == cGustav)
  {
    Verbcoin.CoinGUI.BackgroundGraphic = gGustavVerbcoin.BackgroundGraphic;
    Verbcoin.CoinGUI.SetSize(gGustavVerbcoin.Width, gGustavVerboin.Height);
    Verbcoin.XOffset = gGustavVerbcoin.Width / 2;
    Verbcoin.YOffset = gGustavVerbcoin.Height / 2;
    Verbcoin.SetButtonActionText(btnLook, "Examine");
    Verbcoin.SetButtonActionText(btnTalk, "Contradict Kauff with");
    CopyButtonGraphics(btnGustavLook, btnLook);
    CopyButtonGraphics(btnGustavTalk, btnTalk);
    CopyButtonGraphics(btnGustavUse, btnUse);
  }
  theCharacter.SetAsPlayer();
}

function game_start()
{
  Verbcoin.CoinGUI = gVerbcoin;
  Verbcoin.AddButton(btnLook, "Analyze", eModeLookat);
  Verbcoin.AddButton(btnTalk, "Answer Question to", eModeTalkto);
  Verbcoin.AddButton(btnUse, "Use", eModeInteract);
  SetPlayer(cKauff);
}


Just create a GUI called gVerbcoin with buttons btnLook, btnTalk, and btnUse and the above code should work pretty much the same as what you were already doing (although it will actually be faster when changing players).

The reason I said to do that is so that you don't have to constantly rewrite the custom interaction text for every item when you're changing between players (because that would just be ridiculous! :P).

From there, to achieve what you wanted, you could do:

Code: ags
// change interaction for object oFence:
oFence.SetActionText(btnUse, "Smash");

// change interaction for character cKauff:
cKauff.SetActionText(btnTalk, "Ridicule");


If you specifically need separate interactions between the two characters, well there wouldn't really be a nice way around that, you'd have to change the text for each item every time you switched players, but hopefully that won't be necessary?

silverwolfpet

Woah!

I should make a copy of the game as it is now, so I don't break something while implementing your code o.O

Thank you so much! I hope I can manage to implement this right.
I'll let you know how it goes. I'll do my best.  ;D

silverwolfpet

Problem...
The three buttons I made... BtnLook, BtnTalk, BtnUse... they changed the initial position of the other buttons (btnKauffLook etc.)
Kauff and Gustav have different positions for those buttons... so if I modify btnLook to make btnKauffLook fit into the right place... btnGustavLook is messed up.

I don't suppose it can let the original buttons as they were, right?

On the other hand, the text-replacing works flawlessly. :)
Haven't tried it on characters yet, but I can finally "Pick up" rock instead of "Use" rock. :p

EDIT: I handled it! I'm awesome! :D  I just made the buttons change positions each time the player switches characters!

Thank you again dude! You're brilliant!! I'll let you know if it works on characters too!

monkey0506

Add the following lines to the CopyButtonGraphics function:

Code: ags
  to.X = from.X;
  to.Y = from.Y;


The reason I said not to use the original buttons is because the module currently requires the coin GUI to be the owning GUI of any buttons it uses (so that it doesn't have to keep track of multiple GUIs and making sure they're turned on and positioned properly, etc., etc.). The next part of the problem arises in that your custom action text, i.e. "Pick up rock" instead of "Use rock", is stored based on a per-button basis, so if you change the coin GUI, then the relation to the buttons is lost, and your custom action text would be destroyed.

Then, if you kept changing between the two characters and switching the GUI, then you'd constantly have to set up your custom action text for everything all over again.

By using only one GUI and changing button graphics instead of using different buttons altogether, you don't lose that information when changing players.

Something I could consider doing is allowing you to keep the custom action text based on the relative button ID as each was added to the verbcoin...and then assume that the relation is kept when new buttons are added. That would require some changes to be made, but it sounds feasible. Don't hold your breath for that though as I have a few higher priority projects underway at the moment. ;)

silverwolfpet

Question:  If I pick up an inventory item from the inventory (let's say the Rock) and want to use it on Gustav... how can I change "Use Rock with Gustav" to "Hit Gustav with Rock" ?

I spent a few days trying to figure this out. The room's repeatedly_execute function seem to solve it partially...but then it messes up the entire room.

Any idea?
I really don't want to be a bother with this and I am giving it my best ^.^

...also, in the inventory panel, it seems that the verbcoin resets itself. How can I change the "Use Rock" to "Eat Rock" having iInvItem1 ? I mean, for the fence, I use object[1].SetActionText bla bla and it works fine... but there isn't any iInvItem1.Set ActionText...is there?

monkey0506

Regarding the first issue I was originally going to say that you should just use Verbcoin.ActiveInventoryActionFormat, but there's one important problem, in that you want the order of the item name and character name to be reversed from what the module expects to be the norm. So, you've got to do a bit more work yourself:

Code: ags
function repeatedly_execute()
{
  Character *cat = Character.GetAtScreenXY(mouse.x, mouse.y);
  if ((player == cKauff) && (player.ActiveInventory == iRock) && (cat == cGustav))
  {
    Verbcoin.ActiveInventoryActionFormat = "%s"; // change the format to use *only* the item name
    lblLocation.Text = String.Format("Hit %s with %s", Verbcoin.LocationName, Verbcoin.ActionText);
  }
  else
  {
    if (cat != null) Verbcoin.ActiveInventoryActionFormat = "Give %s to";
    else Verbcoin.ActiveInventoryActionFormat = "Use %s with";
    if (Verbcoin.ActionText == null) lblLocation.Text = Verbcoin.LocationName;
    else lblLocation.Text = String.Format("%s %s", Verbcoin.ActionText, Verbcoin.LocationName);
  }
}


Regarding the inventory, I'm not sure what you mean when you say that the verbcoin "resets itself". There is an InventoryItem.SetActionText function (implemented by the module). In fact, the example given in the quote from the Verbcoin manual that I posted not that long ago, specifically uses an inventory item. Provided that you're using the single-GUI setup like I've been helping you with, then you should be able to do something like this:

Code: ags
// game_start
// AFTER setting up the Verbcoin and its buttons....
  iRock.SetActionText(btnUse, "Eat");
  iPencil.SetActionText(btnTalk, "Chew");
  // ..etc.


If you're not using the single-GUI setup (and you're still switching between the two GUIs instead of just swapping graphics), then that would explain why it would be "resetting" as you say (which is why I told you to use the single-GUI route). I've actually been thinking about it, and the link between the GUI buttons and the custom action text is created based on the button's ID within the verbcoin, so it would actually be possible to force that to persist the custom text when the GUI is changed. The relation might not make any sense if the buttons were added in a different order, but it would be possible to keep it. That would actually require quite a bit of modifications though, so don't hold your breath.

For now the easiest thing to do is just swap out the graphics, size, and location of the GUIs for multi-coin games.

silverwolfpet

How awesome can one person be? o.O Thank you very very much dude!!

One tiny issue...  The lblLocation.Text  had to be replaced with Label1.Text  (for my script).
Also, you made my "Walk to" disappear :p So I changed the script you gave me, by adding an extra "else if"

Code: ags

function room_RepExec()
{
{  Character *cat = Character.GetAtScreenXY(mouse.x, mouse.y);
  if ((player == cKauff) && (player.ActiveInventory == iInvItem1) && (cat == cGustav))
  {
    Verbcoin.ActiveInventoryActionFormat = "%s"; // change the format to use *only* the item name
    Label1.Text = String.Format("Hit %s with %s", Verbcoin.LocationName, Verbcoin.ActionText);
  }
  else if (Verbcoin.ActionText == null) 
  {
    Label1.Text = String.Format("Walk to %s", Verbcoin.LocationName);
  }
  else    
  {
    if (cat != null) Verbcoin.ActiveInventoryActionFormat = "Give %s to";
    else Verbcoin.ActiveInventoryActionFormat = "Use %s with";
    if (Verbcoin.ActionText == null) Label1.Text = Verbcoin.LocationName;
    else Label1.Text = String.Format("%s %s", Verbcoin.ActionText, Verbcoin.LocationName);
  }
}
}


As for the inventory items, my bad, I explained in a bad way what was happening. Main idea is that you also solved the issue here. All is good now. No, actually, all is PERFECT now.

If I ever finish this game, I may have to marry you.


monkey0506

You didn't need to add an extra else if, you could have just modified the existing if statement (the one that was already checking whether Verbcoin.ActionText is null). Your logic is just a little skewed. Functionally it ends up the same, but you're just doing things kind of redundantly. Like your additional braces inside of your function. Not sure why you felt that was necessary (or indeed doing anything :=) but, in any case I'm glad you got it working.

For the record though:

Code: ags
function room_RepExec()
{
  Character *cat = Character.GetAtScreenXY(mouse.x, mouse.y);
  if ((player == cKauff) && (player.ActiveInventory == iRock) && (cat == cGustav))
  {
    Verbcoin.ActiveInventoryActionFormat = "%s"; // change the format to use *only* the item name
    lblLocation.Text = String.Format("Hit %s with %s", Verbcoin.LocationName, Verbcoin.ActionText);
  }
  else
  {
    if (cat != null) Verbcoin.ActiveInventoryActionFormat = "Give %s to";
    else Verbcoin.ActiveInventoryActionFormat = "Use %s with";
    if (Verbcoin.ActionText == null) lblLocation.Text = String.Format("Walk to %s", Verbcoin.LocationName);
    else lblLocation.Text = String.Format("%s %s", Verbcoin.ActionText, Verbcoin.LocationName);
  }
}


Oh, and the Verbcoin module documentation is now in the wiki, so that might help vs. the plain-text version. The table of contents actually makes a fair argument by itself as to why you might have overlooked something. :P Hopefully that will help you out.

Electroshokker

Quote from: monkey_05_06 on Sun 13/02/2011 02:30:28
Hey there. I don't mean to offend (so sorry if this comes across the wrong way Elecktroshokker), but to me the verbcoin template that is distributed with AGS is somewhat of a mess. I can't tell what most of the functions are for without looking at the manual, because the naming convention is rather odd. Also, I seem to recall that none of the functions the template defines return a value, so you can't read anything back once it's been set..which seems rather unfriendly to me (writeonly??).

So I'm not here to bash the great work that Elecktroshokker has done, I'm here to present my take on the verbcoin interface. It has some similarities to the existing template, but not all of the functionality is the same between the two.

Hi there. I quite agree with you, I wrote the template long ago when I was just beginning to learn AGS. (whereas today I'm programming for a living, and would probably design the entire thing quite differently. The Picaroon interface code for instance is quite different from the verbcoin template.)

So basically: I don't mind at all, I think it's great people are taking that code and rewriting it to fit their needs. After all, it's just an example and can use much improvement, like what you've done.

Maybe once I get Picaroon - part 1 done, I'll take a closer look at your code and see if it would be useful to give you any of the improvements I made in my own code. I'll be in touch,

Cheers,

Tom

monkey0506

I'm glad you see it that way. :)

Merging any of your code directly into the module could be messy, but if there's a specific feature you'd like to see I could work on it. This module internally uses a lot of dynamic memory (through dynamic arrays), and particularly since AGS only supports single-dimension arrays, there's a lot of functions that are there just for the purpose of resizing and reallocating those arrays. The smallest of changes to those functions could make the entire module explode. :=

But I'd be more than happy to take a look at it with you sometime if you're interested.

Cassiebsg

Firstly I wish to thank you for this module! (nod)

Secondly, I'll admit right off the bat that I'm code incompetent and have yet to figure more than half of the module's code. So, yes, I have NO IDEA what am doing. (roll)

On to my "problem": I have changed the verbcoin to the right button and deactivated the default walkto mouse click from the right button (cause I'm using the left button for that). So far so good, only problem is that I have yet to find out how to turn it off when in the inventory window, so that it won't pick anything up if I don't choose an option (I wish to use the left button for that). Could you point me to the line (or lines) that I need to change to accomplish the deactivation of the default when in inv window? (nod)

I've noticed the module also features some "add/remove button" stuff, could that be used for unhandled events?
I just thought this morning, that it would be cool to remove the options from the verbcoin that have no event associated instead of telling the player 100 times "You can't talk to that"... Would it be easy to do, or would it require too much code (that's beyond my current capability?)

Edit: Okay, I ended up using your snip reply to TheRoger and made my own VerbCoin, and after some work of trial and error I finally have it working like I want it now. (nod) Thanks. If anyone needs/wishes my VerbCoin code, just PM and I'll be happy to share it.
There are those who believe that life here began out there...

SMF spam blocked by CleanTalk