Adventure Game Studio

AGS Support => Beginners' Technical Questions => Topic started by: aventurero on Mon 04/01/2010 23:59:20

Title: Armor and weapons for my RPG
Post by: aventurero on Mon 04/01/2010 23:59:20
How can I make an armor raise the variable "defense" and a sword raise the variable "attack"? Also I need that when the player character has got 2 armors, only the strongest armor will raise the defense, and the same for the sword.
Title: Re: Armor and weapons for my RPG
Post by: Crimson Wizard on Tue 05/01/2010 00:50:32
Simpliest way is to have an array of stats for each possible armor and weapon in the game. Like

int Armors[10];

Then you store current armor as ArmorIndex, and when you need to know its defence value, you get it like:

Armors[ArmorIndex]

Similar for weapons.

Second part is really simple. Just check which Armor has greater value and use it... umm, well. I don't know how you store equipment data, so I can't give some precise piece of code.
Title: Re: Armor and weapons for my RPG
Post by: Khris on Tue 05/01/2010 02:34:17
It'll probably be even easier to use Custom properties. Add properties "att_mod" & "def_mod" of type int, default value 0.
Then enter e.g. 2 or 3 for every inventory item that's a weapon / armor.

Then add the on_event function to Global.asc:

function on_event (EventType event, int data) {

 if (event == eEventAddInventory || eEventLoseInventory) {
   int i;
   int att_mod, def_mod;
   InventoryItem*it;
   // look for biggest modificator
   while (i <= Game.InventoryItemCount) {
     if (player.InventoryQuantity[i] > 0) {
       it = inventory[i];
       if (it.GetProperty("att_mod") > att_mod) att_mod = it.GetProperty("att_mod");
       if (it.GetProperty("def_mod") > def_mod) def_mod = it.GetProperty("def_mod");
     }
     i++;
   }
   attack = base_attack + att_mod;
   defense = base_defense + def_mod;
 }
}


(This code assumes you have created four global ints "attack", "base_attack", "defense" and "base_defense", e.g. by using the Global variables pane.)

Edit: corrected code
Title: Re: Armor and weapons for my RPG
Post by: aventurero on Tue 05/01/2010 15:21:57
Khris, I did everything you said, and so far it worked. But my attack and defense raises without even having the items  :-\. And most important, it doesn't even raises the stats according to the most powerful items. You see, I made "armor" (def_mod: 5), "armor2" (def_mod:10), "sword" (att_mod: 5) and "sword2" (att_mod: 10). Logic dictates that the function will take the values for armor2 and sword2, but it takes the values of armor2 and sword...  :-\ I'm going crazy thinking.

If it's not too much to ask, can you figure out what's the problem? I surrender.  :-[ Thanks anyway, you're very, very helpful.
Title: Re: Armor and weapons for my RPG
Post by: Khris on Tue 05/01/2010 16:45:26
Yeah, sorry, I forgot to check if the item is in possession of the player. The above code should be correct now.

Is sword2 the last item in the list? I forgot that InventoryItems start at index 1 not 0, so my code skipped the last item.
Title: Re: Armor and weapons for my RPG
Post by: aventurero on Tue 05/01/2010 17:34:30
I tried, and an error pops up:
QuoteError: Character.InventoryQuantity: invalid inventory index 0
What does "index" mean? And by the way... I tried modifying this part of the code (just to see what happens):
if (player.InventoryQuantity[i] > 0) {
to this:
if (player.InventoryQuantity[2] > 0) {
and then adding the armor to the inventory. Then, instead of just adding 5 to defense (def_mod of armor), it adds 10 to defense and 5 to attack...

Hell, this is hard.  ???
Title: Re: Armor and weapons for my RPG
Post by: aventurero on Tue 05/01/2010 17:41:06
Oh... I did a little research, and I found out (I know, you already know...  :P) that the index is the number between brackets. Aparently it can't be 0, and our variable "i" was 0.

So I just modified this:
int i;

into this:
int i=1;

So far, it works PERFECTLY. Will I have any problems later on? Thanks   ;D (I'm happy now)

EDIT: Well, I guess I'll never be happy. :P I have a new question. Can I somehow equip this armors and weapons to unleash the effects, instead of just having them in the inventory? Maybe make a new inventory, and a cursor to "equip" them (change them to the other inventory, and then unleash the effects). I don't know if I make myself clear.
That question came to my mind because sometimes you want to equip a weaker armor, in order to enter a place (for example a guard's armor to enter a castle, or something like that), even when having a more powerful piece of equipment.
Title: Re: Armor and weapons for my RPG
Post by: Khris on Tue 05/01/2010 19:59:43
Funny thing is, I was almost suggesting exactly that in my post further up :)

A second inventory sounds like a good idea in theory, and it'll work as long as the player doesn't need to use any of the items (you can't Useinv an item not in the player's possession).

I believe you're using a fight cursor though, so let's try:
Create a dummy character, e.g. cEquipped, and add an InvWindow to an existing or new GUI, e.g. iwEquipped.
Set its CharacterID to cEquipped's ID.

Remove the on_event stuff, and in General Settings, activate that inventory click are handled in script

I'll implement equipping an item by clicking it with the interact cursor:

// inside on_mouse_click

  if (button == eMouseLeftInv && mouse.Mode == eModeInteract) {
    InventoryItem*i = inventory[game.inv_activated], o;

    int m = i.GetProperty("att_mod");
    if (m > 0) {  // click on a weapon?
      o = iwEquipped.ItemAtIndex[0];  // first item in equipment inv, weapon slot
      if (o != null && o.GetProperty("att_mod") > 0) {  // currently, another weapon is equipped
        cEquipped.LoseInventory(o);  // move it back to player's inv
        player.AddInventory(o);
      }
      player.LoseInventory(i);  // equip new weapon
      cEquipped.AddInventory(i, 0);  // put in weapon slot
      attack = base_attack + m;
    }

    int m = i.GetProperty("def_mod");
    if (m > 0) {  // click on armor?
      o = iwEquipped.ItemAtIndex[iwEquipped.ItemCount-1];  // last item in equipment inv, armor slot
      if (o != null && o.GetProperty("def_mod") > 0) {  // currently, another armor is equipped
        cEquipped.LoseInventory(o);  // move it back to player's inv
        player.AddInventory(o);
      }
      player.LoseInventory(i);  // equip new armor
      cEquipped.AddInventory(i, iwEquipped.ItemCount-1);  // put in armor slot
      defense = base_defense + m;
    }
  }
  else inventory[game.inv_activated].RunInteraction(mouse.Mode);

  if (button == eMouseRightInv) on_mouse_click(eMouseRight); // standard behavior for right click on inv


Untested!
Title: Re: Armor and weapons for my RPG
Post by: aventurero on Wed 06/01/2010 02:33:49
I'll test it tomorrow, it's late here in Argentina  :P. But that bunch of codes and stuff seemed right to me  ;D. I'll get back to you.

EDIT: well, I guess I just couldn't wait. I didn't test it, but i've read it twice, and it seems fine. Adding something like a helmet and a shield would be just too much, I don't want neither of ours heads to explode. Oh, and when a weapon/armor is equiped, how will the player know it? We could use a label, like lblArmor and lblWeapon, and change the text on it to the name of the items equipped, right?
Please do it, I'm really slow thinking complicate stuff  :P

EDIT 2: oh and btw, you'll have a great spot on the credits, you can be sure about it.  ;D
Title: Re: Armor and weapons for my RPG
Post by: aventurero on Wed 06/01/2010 12:22:48
Well Khris, I tested it and it "worked". :P

First of all, let's modify this:
int m = i.GetProperty("def_mod");
for this:
m = i.GetProperty("def_mod");
because it's already defined.

The first problem I had was that the items just dissapeared, without coming back to my inv. I solved that by stablishing which player controls which inventory:
//on game start

iwEquipped.CharacterToUse=cEquipped;
invCustomInv.CharacterToUse=cPlayer;// my player character controls the custom inventory


Problem 1- As usual, another problem poped up. The items come back to my inv, but when I try it twice, they just don't.

Problem 2- In addition to that, I can't grab normal items, like a book. The interact cursor just does nothing.

Problem 3 (optional)- It would be good if weapons go to an inventory, and armors to another. That way I could just put 2 tiny squares at the panel, and you could easily see what you're wearing.

Problem 4 (optional)- Oh, an also it would be good to be able to unequip the items from the iwEquipped, since maybe you don't wanna have any armor or weapon, instead of replacing them with another one.

P.S.: Thank god you're german. Here in Argentina it seems no one is able to help anymore, specially when there is no money involved.  :-[
Title: Re: Armor and weapons for my RPG
Post by: Khris on Wed 06/01/2010 14:00:01
Right, I copy pasted that and missed the int declaration.
Setting iwEquipped's owner in the GUIEditor should make the first game_start line obsolete though.

And yes, I imagined you'd add the second inventory to an existing GUI or you'd create one so the player sees the equipped items.
I agree though that my solution isn't exactly the best, but lots of it depends on how exactly you want to implement (un)equipping items, i.e. game design.

Code-wise, it's a lot easier to just have, say, four buttons on a GUI and change their images to the equipped items. No need then to hassle with moving items between inventories.

The most straightforward way of handling this, I think, is to add another Custom int property "inv_type". Leave it to 0 for standard inv items, change it to 1 for weapons, 2 for armor, etc.

Then do something like this:

// above on_mouse_click

function Update_defense() {
 int i = 1;
 defense = base_defense;
 Button*b;
 while (i < 4) {
   b = gEquipment.Controls[i].AsButton;
   defense += b.TextColor;
   i++;
 }
}

// inside on_mouse_click

 if (button == eMouseLeftInv) {

   InventoryItem*i = inventory[game.inv_activated];
   int it = i.GetProperty("inv_type");

   // standard behavior
   if (mouse.Mode != eModeInteract || it == 0) inventory[game.inv_activated].RunInteraction(mouse.Mode);

   else {  // interact with equipment
     Button*b = gEquipment.Controls[it-1].AsButton;
     b.NormalGraphic = i.Graphic;
     if (it == 1) attack = base_attack + i.GetProperty("att_mod");  // weapon
     else {  // armor, helmet, shield
       b.TextColor = i.GetProperty("def_mod");
       Update_defense();
     }
   }
 }

 if (button == eMouseRightInv) on_mouse_click(eMouseRight); // standard behavior for right click on inv


Create a GUI (gEquipment) with four buttons (clear their texts), IDs 0 to 3, 0 for weapons, 1-3 for armor, helmet, shield
Make them the same size as inv items, obviously, and set their OnClick function to this:

function UnEquip(GUIControl*c, MouseButton button) {
 if (button != eMouseLeft) return; // only react to left clicks

 Button*b = c.AsButton;
 b.NormalGraphic = 0; // clear button's image
 int it = c.ID + 1;
 if (it == 1) attack = base_attack;  // weapon
 else { // armor, helmet, shield
   b.TextColor = 0;
   Update_defense();
 }
}


I've used the unused TextColor property (an int) to store the items defense; using a custom function, I update the total defense every time something other than a weapon is (un)equipped.

Edit: corrected code
Title: Re: Armor and weapons for my RPG
Post by: aventurero on Wed 06/01/2010 15:43:53
It doesn't work...  :( first it says "variable b already defined" and then when I put the UnEquip function on the "OnClick" function of the buttons, it says "undefined symbol b". Argh. I don't know what to do. Can't we just forget about the helmet and shield and make it plain and simple?  :P I'm getting frustrated.
Title: Re: Armor and weapons for my RPG
Post by: Crimson Wizard on Wed 06/01/2010 16:12:58
Oh, come on, aventurero! I know you can make it, just try little harder  ;)

Khris has a little mistake in his code, he uses same name for function parameter and local variable. I fixed code a little:


function UnEquip(GUIControl*c, MouseButton button) {
 if (button != eMouseLeft) return; // only react to left clicks

 Button* b = c.AsButton;
 b.NormalGraphic = 0; // clear button's image
 int it = c.ID + 1;
 if (it == 1) attack = base_attack;  // weapon
 else { // armor, helmet, shield
   b.TextColor = 0;
   Update_defense();
 }
}
Title: Re: Armor and weapons for my RPG
Post by: aventurero on Wed 06/01/2010 17:13:03
Thanks Crimson Wizard :D
But apparently I'm a noob at this. I don't know what to put in the "Onclick" function of the buttons. Should I put this?:

UnEquip(GUIControl*c, MouseButton button);

That doesn't seem to work. I'm gonna kill myself.
Just kidding... I will make it, Crimson. I promise. :P

EDIT: it would be nice to communicate in other ways besides the forum. Like msn or something. What do you think guys? It's way too slow this way.  And I miss you :-[ :P
Title: Re: Armor and weapons for my RPG
Post by: Crimson Wizard on Wed 06/01/2010 17:39:36
Quote from: aventurero on Wed 06/01/2010 17:13:03
But apparently I'm a noob at this. I don't know what to put in the "Onclick" function of the buttons. Should I put this?:

UnEquip(GUIControl*c, MouseButton button);
No, simply name of the function, that is:
UnEquip

Quote
EDIT: it would be nice to communicate in other ways besides the forum. Like msn or something. What do you think guys? It's way too slow this way
Well, I am logged in MSN every now and then, so you may catch me there sometimes.
Khris seem to have only ICQ account though.
Title: Re: Armor and weapons for my RPG
Post by: aventurero on Wed 06/01/2010 18:36:04
But I have to write parenthesis, and when I do, it says "not enough parameters to call function" :(
Title: Re: Armor and weapons for my RPG
Post by: Khris on Wed 06/01/2010 18:49:38
Damn, thanks Crimson Wizard.

aventurero:
Don't put anything in the OnClick functions, you don't need them. In the events pane of the buttons, put "UnEquip" into the text field directly.
Title: Re: Armor and weapons for my RPG
Post by: aventurero on Wed 06/01/2010 19:19:57
I did, Khris. And now the items equip, but they don't disappear from my inventory. And they only raise defense. And with some random values I don't understand.  ???
I'm about to cry. :P Forget about the helmet and shield. Let it just be an armor an a weapon. Go back to the 2 inventories set, if it's necessary. This doesn't seem to work and I don't wanna bother you.  :(
Crimson Wizard, if you figure out what's wrong, please tell me. :)
Title: Re: Armor and weapons for my RPG
Post by: Khris on Wed 06/01/2010 23:11:31
I didn't remove equipped items on purpose; to unequip something, click the button showing the item.

Look, please calm down. What's with you and crying?
AGS doesn't have built-in RPG functionality, so some semi-advanced coding is required.
I wrote the functions I posted off the top of my head; I'd be more surprised if they didn't require some adjustments.
You showed already that you're able to fix minor errors yourself, which is really helpful.

I'm going to create a game (in the AGSEditor sense) and test all the stuff I suggested. Then I'll post the working parts, ok?
It's midnight here and I got to work tomorrow, but I might get back here today.

EDIT:
Ok, I tested this. Everything worked absolutely fine, the only thing I forgot to mention is: since I'm using the buttons' TextColor to store the current defense of the item it has to be set to 0 (or the defense modifier of the item initially equipped. Alternatively, run Update_defense once in game_start; you'll have to move the function above game_start in this case though).
Otherwise, until every piece of armor has been unequipped once, defense will get the wrong value.

See, one of the major problems here was that I had only a vague idea of how exactly you wanted this to work. It's a pure game design choice whether equipped items disappear from the inventory or not; after all, the player still has them in his possession, so from a real life point of view, they should stay.
Designing a nice and elegant user interface for an RPG isn't easy; commercial games use tons of different varieties.

If you're unhappy with the current way, I might go back and use inventories. Or you try to do it, you seem to be able to pick up the necessary scripting pretty quickly anyway. It's just that reading posts from you sounding like you're about to kill yourself if somebody doesn't help you in the next five minutes really put me off. Just chill. Sacrificing cool features of a game just because one can't pull them off perfectly from the start is really a bad idea.
Title: Re: Armor and weapons for my RPG
Post by: aventurero on Thu 07/01/2010 01:22:01
Quote from: KhrisOk, I tested this. Everything worked absolutely fine, the only thing I forgot to mention is: since I'm using the buttons' TextColor to store the current defense of the item it has to be set to 0 (or the defense modifier of the item initially equipped).

How do I do that?
Title: Re: Armor and weapons for my RPG
Post by: Crimson Wizard on Thu 07/01/2010 02:40:49
Quote from: aventurero on Thu 07/01/2010 01:22:01
Quote from: KhrisOk, I tested this. Everything worked absolutely fine, the only thing I forgot to mention is: since I'm using the buttons' TextColor to store the current defense of the item it has to be set to 0 (or the defense modifier of the item initially equipped).

How do I do that?

1. Select button on your GUI.
2. In the bottom-right you'll see properties table (property - value).
3. Find "TextColor" line and type in corresponding value (0).
Title: Re: Armor and weapons for my RPG
Post by: aventurero on Thu 07/01/2010 14:38:46
It's already set to 0, and still doesn't work...
Title: Re: Armor and weapons for my RPG
Post by: Khris on Thu 07/01/2010 15:57:31
Did you set the inv_type property correctly? 1 for weapons, 2 for armor, 3 for shields, 4 for helmets.
Also, instead of "doesn't work", please tell us what happens.
Title: Re: Armor and weapons for my RPG
Post by: Crimson Wizard on Thu 07/01/2010 16:06:05
Khris, aventurero sent me game, and from what I see, he just did not do it correctly GUI-wise  ;). Unfortunately, project he uses is a mess at this point, inventory is on one Gui, "equipped" part is on separate gui; and he's got some extra "inventory" guis created for unknown purposes; I suggested he plan how inventory should look first and redo everything from scratch.


EDIT: Owww, just noticed that - he mess up with inventory types, as you guessed ;D
He uses 1 for armor and 2 for weapons.
After I fixed that it worked well.
Title: Re: Armor and weapons for my RPG
Post by: Khris on Thu 07/01/2010 16:59:23
Cool, glad you got it sorted out.

I was thinking about a way how to best realize a nice equipment screen, but it's hard to work on such a vague basis. For quite a while now I'm playing with the idea of creating a full-fledged RPG template, complete with map editor and fight mechanics.
The only problem is that ideally it should be highly customizable, without requiring too much in-depth work on the game designer's part.
Well, maybe next year ;)
Title: Re: Armor and weapons for my RPG
Post by: Ryan Timothy B on Thu 07/01/2010 17:14:30
From reading this thread, sounds like aventurero is a little too ambitious with this project, expecting too much from his understanding of programming and AGS.
You should really work on smaller test games and such (that never get released, only to understand the complete workings of AGS) just to advance your knowledge.  That way none of your errors will make it into the actual game.  And everything you don't understand, read it in the index/manual--that thing is a bible, or search it up in the forums.  Khris and Crimson really shouldn't be relied upon to program your wishes.  This is here for assistance.
:P (that's just my opinion)
Title: Re: Armor and weapons for my RPG
Post by: aventurero on Thu 07/01/2010 17:34:45
Well Ryan, this is actually a test game... And is not so easy to program everything if you speak spanish and the manuals are written in english. Thanks everyone for the help :)
Title: Re: Armor and weapons for my RPG
Post by: Crimson Wizard on Thu 07/01/2010 17:54:16
There's a terribly weird thing that spoils this.

I just found that if you set TextColour to 0 for GUI buttons, on game start these TextColours became 16.
So, you have to make this function:


function init_equipped()
{
 int i = 1;
 Button*b;
 while (i < 4) {
   b = gEquipment.Controls[i].AsButton;
   b.TextColor = 0;
   i++;
 }
}


I never knew AGS can do this thing.  :-\
Title: Re: Armor and weapons for my RPG
Post by: aventurero on Thu 07/01/2010 19:01:02
Well, that solves everything. Crimson and I tried it, and it works perfectly.  8)
Title: Re: Armor and weapons for my RPG
Post by: Khris on Thu 07/01/2010 20:19:22
Ouch!
Guess that's what happens when going for a quick'n'dirty, untested solution ;)
Title: Re: Armor and weapons for my RPG
Post by: suicidal pencil on Tue 12/01/2010 20:44:31
here, try this. I did a little testing, and it should work


InventoryItem* Armor;
InventoryItem* Weapon;

function RemoveArmor()
{
 if(Inventory_Armor.Graphic != g_70x70_ButtonTran)//this obscure variable is just pointing to the sprite I used for transparency
 {
   Inventory_Armor.NormalGraphic = g_70x70_ButtonTran;
   Inventory_Armor.Text = String.Format("Armor");
   player.AddInventory(Armor);
   DefenseModifier = 0;
   Armor = null;
   return 0;
 }
}

function RemoveWeapon()
{
 if(Inventory_Weapon.Graphic != g_70x70_ButtonTran)
 {
   Inventory_Weapon.NormalGraphic = g_70x70_ButtonTran;
   Inventory_Weapon.Text = String.Format("Weapon");
   player.AddInventory(Weapon);
   AttackModifier = 0;
   Weapon = null;
   return 0;
 }
}

function SetArmor(int DefenseValue, InventoryItem* ItemName)
{
 if(Armor != null) RemoveArmor(); //if the slot is already taken, remove it! :)
 DefenseModifier = DefenseValue;
 Armor = ItemName; //Just so I have a reference to the inventory item
 Inventory_Armor.NormalGraphic = ItemName.Graphic;
 Inventory_Armor.Text = String.Format(""); //remove the label text
 player.LoseInventory(ItemName);
 return 0;
}

function SetWeapon(int AttackValue, InventoryItem* ItemName)
{
 if(Weapon != null) RemoveWeapon();
 AttackModifier = AttackValue;
 Weapon = ItemName;
 Inventory_Weapon.NormalGraphic = ItemName.Graphic;
 Inventory_Weapon.Text = String.Format("");
 player.LoseInventory(ItemName);
 return 0;
}