Reducing he players weight when putting objects in other objects.

See next post...


I messed up the formatting in the first post so here it is again in a version more easily readable.


I have a system for encumberance. When the player picks something up the weight of that object is added to the total weight of the player, however it only works when I pick something up and when I drop something NOT when I put an object in another object. See example below....

Example of what's working and what's not

When a player pick an object up this happens:
player.weight = Round(player.weight, 2)
player.weight = player.weight + 4.54
encumbered   //this calls the function to check if the player is uncumbered

And when dropping the object:

 player.weight = Round(player.weight, 2)
 player.weight = player.weight - 4.54
marlin.equipped = false

Everything is working like it should BUT when I use the "put" command (instead of drop) it wont reduce the player.weight attribute.

For example: Put marlin in crate will put the weapon in the crate without reducing the total weight of the player.
If I pick it up again it will add the weight of the marlin to the player again. So if I put it in the crate, pick it up, put it back in the crate, pick it up, a couple of times the burden (of nothing) will be so heavy I can't move ('cause that's how the encumbrance function is supposed to work)

I added this

player.weight = player.weight - this.weight

... to the "script to run when trying to add an object" but got this error...
Error running script: Error compiling expression 'player.weight - this.weight': ArithmeticElement: Operation 'Subtract' is not defined for types 'Double' and 'Object'

Any ideas how to make this work?

quickest error/fix: make sure that your 'this.weight' is also a Double Attribute storing a Double Value, as you can't subtract different data types of values: double (4.05) - integer (1) ---> ERROR! and integer (2) - string ("hi") ---> ERROR!

another simple issue/fix is if the problem/issue is just that you're using 'this' when you can't: a scope issue, which we can provide you with alternative workarounds

if these (mis-match of data types or a scope issue with using 'this') aren't the issue... then... got a more difficult issue (something is likely wrong with your code, so we'd need to see possible your entire game code to find the mess up in it) to figure out and fix....

The built in system works more like volume than weight, despite the name, and I pointed this out some years ago.

I would have the encumbered function calculate the current carry weight each time, rather than tracking it.

carried = 0.0
foreach (obj, GetAllChildObjects(game.pov)) {
  if (HasDouble(obj, "weight"))
    carried = carried + obj.weight

And actually I would use integers, but adjust the units to hundreds of a pound, so your marlin weighs 454. It is generally easier using whole numbers.

The INT tip sounds logical... I should probably use that .
I'm not using the built in system though... I wanted to make my own (to... you know, learn =).

So I guess the question remains... is this

player.weight = player.weight - this.weight

(or a version of it)((when putting something into something else)) totally out of the question?

Oh, and thanks for replying Pix!

Totally missed your post Hege!
I'll look into it after putting the kids to sleep.

problem/issue is just that you're using 'this' when you can't:

... well lol, thanks for pointing that out!
'this' was referring to the crate, not the object I was trying to add to it. A super lame mistake I should've been able to spot myself.
Changed it from 'this.weight' to 'object.weight' and, of course, everything is working just swell. xD

Thanks guys!

Nice job cheesemybaby! even though my post was off on what the problem was... you're learning enough of coding, that you realized what was going on with your use of 'this', in that it was the wrong reference/pointer of the object you wanted to use, and the correct reference/pointer of the object you wanted to use is (I'm assuming/presuming) a parameter variable named/labeled/called as 'object'

we're making a coder out of you! wink

I would point out that if you do it this way, you will have to take account of every circumstance in which an item can be added to or removed from the player's inventory. A box you can pick up will have to have code to change your weight for all its contents as well as itself. Potions will have to subtract their own weight when used. If you have a weapon with expendable ammo, do arrows have a weight? A thief stealing an item will have to change the player's weight as well.

You end up with the same code in dozens of places; maybe even hundreds. It would be much simpler to have your encumbered function add up the weight of everything the player is carrying each time it is called.

Or… use the changedparent script attribute. This is called whenever an object is moved from one place to another, regardless of whether it was moved by a command or another script. You could make it something like:

// first find the weight of this object and anything inside it
totalweight = this.weight
foreach (contents, GetAllChildObjects(this)) {
  if (HasAttribute (contents, "weight")) {
    totalweight = totalweight + contents.weight
if (not oldvalue = null) {
  if (oldvalue = player or Contains (player, oldvalue)) {
    player.weight = player.weight - totalweight
if (Contains (player, this)) {
  player.weight = player.weight + totalweight
else {
  this.equipped = false

That would work if you take or drop the object, if you put it inside something else, if a thief steals it, or if it's eaten. Using the changed scripts means that you only have to write that code once, and you don't have to worry about remembering to include it every time you script an encounter that could change the ownership of an item. It's a very useful technique to learn.

There's two short lines of code I need to add to every object the player can pick up.

player.weight = player.weight + [insert weight here]

... and with that said: I know it's not the best way, or smartest or fastest. I'm currently working on Act II of my (first) game. When starting working on Act I I know absolutely nothing about coding. I made an incredible amount of mistakes but I learned from them. I took what I've learned and started working on Act II but I, of course, still have a looooooooooooooooong way to go before I'd consider myself even an mediocre coder. This is the way I learn and even if I didn't follow your tips in this thread I do appreciate and it is bookmarked for future reference! So... thanks! :)

Hehe... that's the plan =)

There's two short lines of code I need to add to every object the player can pick up.

Two lines if the item can be picked up.
Two more if it can be put down.
More if it can be put into a container which can be carried
More if if could be inside a container which is being picked up
Two more if it can be given to an NPC
Two more for every NPC who can give it to the player
More if an item can be stolen from the player
Two more if the item can be sold
Two more if it can be bought
Two more if an item can be eaten or used up in some way.
More if there's any effect which destroys items.
Am I missing some?

Two lines of code for each item wouldn't be a lot. Two lines for every item, for every way in which it can enter or leave the inventory, could be a lot :-p

Another way to do it, in case you're interested

A simpler changedparent script:

if (not oldvalue = null and HasAttribute (oldvalue, "weight")) {
  oldvalue.weight = oldvalue.weight - this.weight
if (not this.parent = null and HasAttribute (this.parent, "weight")) {
  this.parent.weight = this.parent.weight + this.weight

There's two lines of code for picking an object up, and 2 for putting it down :) But in the changed script, they're run whenever the object moves, regardless of whether the command was "get", "drop", "put in", "give to", "eat", or anything else.

Though if there's a crate the player can pick up which can have other objects inside it, you'd also have to give it a changedweight script, so that it will encumber the player appropriately if you put an object in it while carrying it:

if (HasAttribute (this.parent, "weight")) {
  this.parent.weight = this.parent.weight + this.weight - oldvalue

@MRA You didn't read past the example code in my last post did you? =)

... I know it's not the best way, or smartest or fastest....

....This is the way I learn....

even if I didn't follow your tips in this thread I do appreciate and it is bookmarked for future reference

You're absolutely right in everything you're saying though.

About that whole post of yours ending with:

It's a very useful technique to learn.

... that's a really nice way. I don't understand it yet but I'll try to get it all into my thick head.

That's why I was trying to break it down into a simpler script. I figure if you can follow code that's only slightly different from what you've already got, it could be an effective learning tool.

You're using scripts that run when the player uses the "take" and "drop" commands. But there's also a script for "whenever the object is moved", so you don't need to think about all the circumstances that can happen in.
In case it makes it easier to understand, here's a pseudo-code version of the script above:

totalweight = this.weight + [weight of all objects inside this one if it's a container]

if [this object was in the inventory before it moved] {
  player.weight = player.weight - totalweight

if [this object is in the inventory after it moved] {
  player.weight = player.weight + totalweight

@mra Thanks for taking the time! It makes way more sense to me now.

Log in to post a reply.