Main Menu
  • Welcome to The RPG Maker Resource Kit.

Item Weight?

Started by shintashi, September 13, 2011, 07:42:29 PM

0 Members and 1 Guest are viewing this topic.

shintashi

I was wondering if there was a way to give items mass or weight, to make more uses of a strength stat. I was thinking the weight could be listed as part of the description or something, and then some kind of sorter would search for the first or last characters in description, or some kind of code indicator like "/%450%/" and display "450". I don't know, I'm not too good at string related script.

cozziekuns

Sounds like your want to run a REGEXP check in the item's description. You can read up on REGEXP here: http://sites.google.com/site/zeriabsjunk/tutorials/regexp-in-rgss

In your example, you would want to check the item's description for:


/\%(\d+)%/\/

shintashi

#2
Quote from: cozziekuns on September 13, 2011, 10:49:00 PM
Sounds like your want to run a REGEXP check in the item's description. You can read up on REGEXP here: http://sites.google.com/site/zeriabsjunk/tutorials/regexp-in-rgss

In your example, you would want to check the item's description for:


/\%(\d+)%/\/


holy crap that's complicated O_O

edit:

ok, so how do I read it? I mean that "d+" thing, if I have a string that has the following two pieces of info:

"450" and "Metal Safe" 

what kind of mess am I looking at to print something like

"Metal Safe______450 lb"

and to have some kind indicator that the 450 belongs to each metal safe?

i.e., if I have 2 safes, and each are '450' then the total encumbrance = '900'.

pacdiggity

#3
Keeping in mind my tiny REGEXP skills, shouldn't that be/\%(\d+)%\//or am I using backslashes instead of slashes? (I think that would be easier to handle anyway)
And to read the (\d+), you would use $1.to_i. I.e.,
weight = self.description[/\%(\d+)%\//].nil? ? 0 : $1.to_ior something.
it's like a metaphor or something i don't know

cozziekuns

#4
Oh yeah I messed up, but Pacman has the right idea. It should be:

/\/%(\d+)%\//

You can convert REGEXP  by using a gsub command. So, keeping with your example, if my item's description was "Metal Safe /%450%/", and I parsed it through the following somewhat pseudocode:


final_description = item.description.gsub(/\/%(\d+)%\//) {"#{$1.to_i} lb"}
weight = $1.to_i


I could retrieve the final description, which would read "Metal Safe 450 lb", and the weight, which would be 450. You can then play around with those values.

shintashi

how much crud, like "/%" do I need? I'm just looking for the simplest way to indicate 'this is the weight' separate from something else.

In other words, if I've got something like

"10000 year old dragon scale" with a weight of "1 lb" and I'm entering the description and weight,

I don't want this:
"1 10000 year old dragon scale"  or worse, "110000 year old dragon scale" + error weight or worse
"110000 lbs" + "year old dragon scale"

That's why I'm wondering what's some good programming crud to stick around my "1" pound. In my safe example, I used /%450%/, which means following the same line of thought, /%1%/ would equal one pound,

thus I might type the following in description

/%1%/ 10000 year old dragon scale

but that's four extra characters, if I only need one or two extra characters, like

*1 10000 year old dragon scale

or

^1/ 10000 year old dragon scale

then that's cool too.

cozziekuns

Depends on the irregularity of the symbol you are parsing. For example, you could run a check for the carrot sign (^) and a number, but then if you had an item that had the description "Power is HP^2", then it would read as "Power is HP 2 lb". I would say that enclosing your text in braces {} or maybe <> is the safest method.

shintashi

Quote from: cozziekuns on September 14, 2011, 12:14:31 AM
Oh yeah I messed up, but Pacman has the right idea. It should be:

/\/%(\d+)%\//

You can convert REGEXP  by using a gsub command. So, keeping with your example, if my item's description was "Metal Safe /%450%/", and I parsed it through the following somewhat pseudocode:


final_description = item.description.gsub(/\/%(\d+)%\//) {"#{$1.to_i} lb"}
weight = $1.to_i


I could retrieve the final description, which would read "Metal Safe 450 lb", and the weight, which would be 450. You can then play around with those values.

I stuck the code in my Item Window/Hep description and it worked - items without the code didn't display weight while items with the code did.

What do I have to do to get the numbers from these items?

like if I wanted a running total from two safes (450x2) and a gold brick (100 x1), what might I have to string together? I.E., where are my variables?

cozziekuns

You would have to make new variables in RPG::Item, corresponding to the weights. E.g:
class RPG::Item
  def weight
    return self.description[REGEXP CHECK].nil ? 0 : $1.to_i
  end
end


Where you replace REGEXP with the REGEXP check above. You can then check an item's weight by checking item.weight. Item's with no specified weight will return weight as zero.

pacdiggity

The sucky thing with that is that you would have to do it individually for each kind of item (i.e., item, weapon and armor). I'm going a bit crazy, trying something silly out here, so don't blame me if it doesn't work. I'm blind at the moment. I needed to try something like this out anyway.
["Item", "Weapon", "Armor"].each { |klass|
item_weight_checker = %Q(
class RPG::#{klass}
  def weight
    #cozzie's method or however you choose to do it
  end
end
)
eval(item_weight_checker)
}
I have no idea if that would work, but I reckon it's the shortest way you could express such a method for all three classes (or your could just do it manually, but that's not as fun).
it's like a metaphor or something i don't know

shintashi

I just realized in order to make this whole thing worth while, in the long run, the inventory list should be subordinate to the actor class. Right now, it's independent. That got me thinking "horse" and "carriage" objects could act as both actors and containers, which opens up a whole can of worms for objects.

I think the first step though is probably just moving the items under actors, but I don't that such a thing is possible.

What sort of is possible is A) community distribution comparison, and B) equipment comparison

step 1:
create a weight allowance for each actor based on strength.
Generic example: Strength = kilograms
A more complex equation for this value is not necessarily harder over all. For example,
Strength * strength = kg
or
(Strength/10)*(Strength/5) or whatever is just a difference in number and depends on what your attribute scale is going to be.

Anyway, the point is you need to add all these values together from all actors in the party. Let's say the total is "400" for sake of argument.

Then that figure is the max encumbrance for the group. Exceeding it might have side effects such as
1. you cannot pick up anything else unless the listed weight is 0
2. your map sprite movement speed starts going down, possibly to zero until you drop something


Alternatively,
if we are only measuring equipped weight, then we can do completely different things with it. For example, the character cannot "attack/dodge" if their armor/weapons weigh too much. The character might not be able to "swim", or you might charge a bonus equal to their weight in Mana to "levitate" as a defense from "earthquake" type spells.

Super heavy items like legendary swords or Hammers might require strength to "move".

As a short cut, perhaps using "equipment" weight vs. actors, and "community weight" vs. inventory would work, and then you could have negative equipment/inventory weights by having horses, packmules, or carriages?

Like if you had a horse in your equipment list, and you are a knight, it allows you to wear an extra 100 pounds of metal armor and weapons, by having a -100 weight?

Then by putting that horse in your "inventory" it counts as a group -100 weight pack horse?

I think this is easier than subordinating the inventory to individual actors.

What do you guys think?

shintashi

Quote from: cozziekuns on September 14, 2011, 05:20:02 AM
You would have to make new variables in RPG::Item, corresponding to the weights. E.g:
class RPG::Item
  def weight
    return self.description[REGEXP CHECK].nil ? 0 : $1.to_i
  end
end


Where you replace REGEXP with the REGEXP check above. You can then check an item's weight by checking item.weight. Item's with no specified weight will return weight as zero.

Where/What do I install that?

I tried sticking it above Main, and tried a basic "p $data_items[1].weight" looking for either a zero or a number,

but then I got this error:

Quote
Script 'Main' line 3: NameError occurred.
uninitialized constant RPG::Item::CHECK

pacdiggity

You're supposed to replace that with the regexp code.
class RPG::Item
  def weight
    return self.description[/\/%(\d+)%\//].nil? 0 : $1.to_i
  end
end
p $data_items[1].weight

You can then use the method to your delight.
it's like a metaphor or something i don't know

shintashi

Quote from: Pacman on September 17, 2011, 08:58:48 PM
You're supposed to replace that with the regexp code.
class RPG::Item
  def weight
    return self.description[/\/%(\d+)%\//].nil? 0 : $1.to_i
  end
end
p $data_items[1].weight

You can then use the method to your delight.

where am I supposed to put it? it crashed before opening on line 3 of main (where I put it)

pacdiggity

Anywhere above main. Like a normal script; use it as part of your system.
it's like a metaphor or something i don't know

shintashi

Quote from: Pacman on September 18, 2011, 01:27:15 PM
Anywhere above main. Like a normal script; use it as part of your system.

I get an error on Main line 3: syntax error occurred.

cozziekuns

Pac's syntax was a little off, it should be:


class RPG::Item
  def weight
    return self.description[/\/%(\d+)%\//].nil? ? 0 : $1.to_i
  end
end


EDIT: $data_items before main won't work because it hasn't been initialized yet :V

pacdiggity

Woops. I forgot the second ?. Silly me.
it's like a metaphor or something i don't know

shintashi

#18
the fix works, for the most part. Is there a way to put in fractional weights, like 0.1 lbs? That would be useful for things like gem and ammo weight.

edit: i basically tried things like "1.0 * ... " but it said something about fixnum and true false not being compatible. I was thinknig as a work around I could set everything to 100 times greater and then use a decimal divide for window display.

shintashi

I fixed a little glitch caused by having "No items" at all. I didn't notice until I tried installing the code in weapon/equipment windows.



  def update_help
if self.item == nil   
    final_description = ""
  else
    final_description = item.description.gsub(/\/%(\d+)%\//) {"#{$1.to_i} lb"}
end 
weight = $1.to_i
        @help_window.set_text(self.item == nil ? "" : final_description)
  end
end



edit: what is
weight = $1.to_i

for?

cozziekuns

Quote
Contains the subpattern from the corresponding set of parentheses in the last successful pattern matched, or nil if the last pattern match failed.

Basically it contains what was described in the parentheses of the REGEXP. For example, in your REGEXP Code, the \d+ that was wrapped around in the parentheses would be interpreted into an string representation. We change that string to an integer by using .to_i. Each subsequent parenthesis has a different $number ranging from $1 to $9. E.g:

"1.2.3.4.8"[/(\d+)\.(\d+)\.(\d+)\.(\d+)\.(\d+)/]
p $1 # => "1"
p $2 # => "2"
p $3 # => "3"
p $4 # => "4"
p $5 # => "8"

shintashi

using something like

    "for i in 1...$data_items.size" and "if $game_party.item_number(i) > 0", is there a way to add up the total weights of inventory objects? It seems adding up equipment weight is fairly straight forward, i.e. a.weight +b.weight+c.weight = x.weight...

but how can I check for the existence of all items, then multiply each weight by their item_number? It sounds like a short for loop, but I'm terrible at them.

Here's my pseudocode:


for i in 1...$data_items.size
if $game_party.item_number(i) > 0
subtotal(i) = $game_party.item_weight(i) * $game_party.item_number(i)
return subtotal.inject(0){|b,i| b+i}
end


or something like that.

cozziekuns

#22
The total weight of all the items in the inventory would be:


total_weight = 0
for item_id in $game_party.keys
  num = $game_party.item_number(item_id)
  weight = $data_items[item_id].weight
  total_weight += (weight * num)
end
return total_weight


Edit: I just saw your decimal value problem, and here's a quick solution I made up:


(/\/%(\d+(\.\d+)?)%\//)


Try using that as your REGEXP, and replace .to_i with .to_f, or to float.

shintashi

#23
I get an error with "$game_party.keys"


edit: your decimal fix works perfectly ^^

here are the relevant codes:

Sample description

Restores HP to one ally. /%1.1%/


output:
Quote
Restores HP to one ally. 1.1 lb



at the bottom of : "Window_Item", "Window_EquipRight", and "Window_EquipItem"

def update_help
if self.item == nil   
    final_description = ""
  else
final_description = item.description.gsub(/\/%(\d+(\.\d+)?)%\//) {"#{$1.to_f} lb"}       
end 
weight = $1.to_f
        @help_window.set_text(self.item == nil ? "" : final_description)
  end
end



Above Main

class RPG::Item
  def weight
    return self.description[/\/%(\d+(\.\d+)?)%\//].nil? ? 0 : $1.to_f
  end
end

class RPG::Weapon
  def weight
        return self.description[/\/%(\d+(\.\d+)?)%\//].nil? ? 0 : $1.to_f
  end
end

class RPG::Armor
  def weight
        return self.description[/\/%(\d+(\.\d+)?)%\//].nil? ? 0 : $1.to_f
  end
end


and here's a sample generic strength calculation, entered above Dexterity in Game_Battler_1:


#--------------------------------------------------------------------------
  # * Get Encumbrance (ENC)
  #--------------------------------------------------------------------------
  def enc
    n = [[str * 4, 0].max, 9999].min
    return n
  end


and here's the related window display stuff, above "equipment" in Window_Status:


#=============================================================   
# ***   Encumbrance ***

self.contents.font.color = system_color
    self.contents.draw_text(320, 112, 120, 32, "Carry")

self.contents.font.color = normal_color
    carry = 0
self.contents.draw_text(320 + 80, 112, 84, 32, carry.to_s + "/" + @actor.enc.to_s, 2)
   
#==============================================================   



cozziekuns

$game_party.items.keys.

I was writing it blind; apologies.