setting an attribute equivalent to the result of a function

Hello everyone,

I'm trying to do something like this:

Given an object which has a two attributes, object.length and object.width, I want to write a function CalculateArea(height, width) which, when called will return the area (i.e. length * width), and make it so that object.area is equivalent to the return value of that function.

My function looks like this:

<function name="CalculateArea" parameters="object, length, width" type="int">
    newlength = GetAttribute (object, length)
    newwidth = GetAttribute (object, width)
    areaReturn = newlength * newwidth
    return (areaReturn)
 </function>

The problem is, the attribute itself looks like it is a script rather than an int:

<area type="script">
        CalculateArea (object, length, width)
 </bmi>

Additionally, when trying to test it out in the game by printing the expression "The area is " + object.area, I just get "The area is Script:"

I don't want to just set the area outright, since length and width can change depending on events in the game, and I wanted to be able to update the area attribute automatically. Is this possible? Or should I look for another way/update it manually?


The script that calculates the area, and the value of the area, are different things.

In this case, you want two script attributes:

<changedlength type="script">
  this.area = CalculateArea (this, "length", "width")
</changedlength>

<changedwidth type="script">
  this.area = CalculateArea (this, "length", "width")
</changedwidth>

The special "changed" script attributes are called whenever an attribute changes. So in this case, the area attribute changes automatically whenever the height or width changes.

I have no idea why you are passing the name of the length and width attributes to CalculateArea. This seems really pointless, unless you have some objects where the attributes are named differently, but I've not touched it because I guess you're using this as an example and your real code is more complex.


So how would I call the changedlength/changedwidth attribute scripts? Would I put a line object.changedlength immediately after I change the length?


changedlength is called automatically whenever length is changed.


Ok, thank you so much for the advice!

I think my main problem with using Quest has been approaching it like any other programming language rather than keeping in mind that it functions a lot differently.


(quest actually is not too different from the main programming languages, aside from it also being a text adventure game engine, but you do got to learn it, its syntaxes, and its various features/functionalities, like with any programming language/software)

there's a lot of built-in functionality already for you (and Pixie has been adding in more RPG and whatever useful functionality - which has been lacking), the special built-in 'changedNAME_OF_ATTRIBUTE' Script Attributes are very useful, as they're fired/activated/executed automatically upon that Attribute's Value changing

the other method is using Turnscripts, which fire/activate/execute every internal 'turn' (either an entered command/typed-in-input into the text command box at the bottom of the screen and/or a mouse click upon whatever), so long as the Turnscript is enabled, and if a local Turnscript, if you're in the same room as it, of course.


you could certainly have made your own Script Attribute to call/use/activate/execute your function (however, it by itself is only a single usage, so if you want it to be a multiple/continuous usage, you got to make it be so through various methods):

(modified it into a more simple design for this example... but if you want it the same as your design, let me know)


<object name="new_rectangle">

  <attr name="area" type="int">0</attr>

  <attr name"area_script" type="script">

    this.area = CalculateArea (old_rectangle)

  </attr>

</object>

<object name="old_rectangle">

  <attr name="length" type="int">5</attr>
  <attr name="width" type="int">10</attr>

</object>

<function name="CalculateArea" parameters="object" type="int">

    if (HasInt (object, "length") and HasInt (object, "width")) {
      newlength = GetAttribute (object, "length")
      newwidth = GetAttribute (object, "width")
      areaReturn = newlength * newwidth
      return (areaReturn)
    } else if (HasInt (object, "length")) {
      msg ("ERROR: the inputted " + object.name + " Object doesn't have a 'width' Integer Attribute, which is required")
      return (-1)
    } else {
      msg ("ERROR: the inputted " + object.name + " Object doesn't have a 'length' Integer Attribute, which is required")
      return (-2)
    }

 </function>

and if you want to use a bit more advanced encapsulation design:

(modified it into a more simple design for this example... but if you want it the same as your design, let me know)

('delegates' in quest are basically Function Prototypes, which enable your Objects' Script Attributes to act as Functions: having/using parameters and/or return values)

http://docs.textadventures.co.uk/quest/types/using_delegates.html

if you have a return value, you must use: RunDelegateFunction (XXX)

otherwise, you use: rundelegate (XXX)

<delegate name="area_delegate" parameters="object" type="int" />

<object name="new_rectangle">

  <attr name="area" type="int">0</attr>

  <attr name="area_2" type="int">0</attr>

  <attr name"SetArea" type="script">

    this.area = RunDelegateFunction (old_rectangle, "CalculateArea", old_rectangle)

    this.area_2 = RunDelegateFunction (old_rectangle, "CalculateArea", old_rectangle_2)

  </attr>

</object>

<object name="old_rectangle_2">

  <attr name="length" type="int">8</attr>
  <attr name="width" type="int">3</attr>

</object>

<object name="old_rectangle">

  <attr name="length" type="int">5</attr>
  <attr name="width" type="int">10</attr>

  <attr name="CalculateArea" type="area_delegate">

    if (HasInt (object, "length") and HasInt (object, "width")) {
      newlength = GetAttribute (object, "length")
      newwidth = GetAttribute (object, "width")
      areaReturn = newlength * newwidth
      return (areaReturn)
    } else if (HasInt (object, "length")) {
      msg ("ERROR: the inputted " + object.name + " Object doesn't have a 'width' Integer Attribute, which is required")
      return (-1)
    } else {
      msg ("ERROR: the inputted " + object.name + " Object doesn't have a 'length' Integer Attribute, which is required")
      return (-2)
    }

  </attr>

</object>

This topic is now closed. Topics are closed after 60 days of inactivity.

Support

Forums