*** empty log message ***
authorMatthew Mondor <mmondor@pulsar-zone.net>
Sat, 30 Jul 2005 09:02:40 +0000 (09:02 +0000)
committerMatthew Mondor <mmondor@pulsar-zone.net>
Sat, 30 Jul 2005 09:02:40 +0000 (09:02 +0000)
tests/js-test/js/game/objects.js

index 1dbea7b..3b8b134 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: objects.js,v 1.1 2005/07/30 07:30:34 mmondor Exp $ */
+/* $Id: objects.js,v 1.2 2005/07/30 09:02:40 mmondor Exp $ */
 
 /*
  * Copyright (c) 2005, Matthew Mondor
@@ -6,3 +6,163 @@
  */
 
 
+
+/*
+ * Describes a game item or object.
+ */
+
+var unique             = 0;
+
+/* Content types */
+const CT_SOLID         = (1 << 0);
+const CT_LIQUID                = (1 << 1);
+/* And container type flag */
+const CT_EXPAND                = (1 << 2);
+
+function Item(name, description, volume, weight, ctype)
+{
+       this.name = name;
+       this.description = description;
+       this.volume = volume;
+       this.weight = weight;
+       this.ctype = ctype;
+
+       this.index = ++unique;
+}
+
+Item.prototype = {
+       volume: function()
+       {
+               return this.volume;
+       },
+
+       weight: function()
+       {
+               return this.weight;
+       }
+};
+
+
+/*
+ * And an object to handle container Items, inheriting the Item object.
+ */
+
+const E_TOOLARGE       = -1;
+const E_TOOHEAVY       = -2;
+const E_BADTYPE                = -3;
+const E_SELF           = -4;
+const E_NONE           = -5;
+const E_ALREADY                = -6;
+const E_CLOSED         = -7;
+
+function ContainerItem(name, description, volume, weight, ctype,
+    con_neck, con_volume_max, con_weight_max, con_ctype)
+{
+       this.base = Item;
+       this.base(name, description, volume, weight, ctype);
+
+       this.con_neck = con_neck;
+       this.con_volume_max = con_volume_max;
+       this.con_weight_max = con_weight_max;
+       this.con_volume_cur = this.con_weight_cur = 0;
+       this.con_ctype = con_ctype;
+
+       this.con_items = {};
+       this.con_items_cnt = 0;
+       this.con_open = false;
+}
+
+ContainerItem.prototype = {
+       open: function()
+       {
+               this.con_open = true;
+       },
+
+       close: function()
+       {
+               this.con_open = false;
+       },
+
+       volume: function()
+       {
+               /*
+                * Objects which expand, such as bags, need to report proper
+                * volume relating to the volume of the objects they hold.
+                * Objects which do not expand, such as boxes or bottles,
+                * need to always report the same volume.
+                */
+               return ((this.con_ctype & CT_EXPAND) != 0) ?
+                   this.volume + this.con_volume :
+                   this.volume;
+       },
+
+       weight: function()
+       {
+               return this.weight + this.con_weight;
+       },
+
+       add: function(item)
+       {
+               /* Can only add items to open container */
+               if (!this.con_open)
+                       return E_CLOSED;
+               /* We can't add ourself in :) */
+               if (item.index == this.item.index)
+                       return E_SELF;
+               /* Nor items which are already inside */
+               if (this.con_items[item.index] != undefined)
+                       return E_ALREADY;
+               /* We only accept items of proper type */
+               if ((this.con_ctype & item.ctype) == 0)
+                       return E_BADTYPE;
+               /* We can only hold objects which are small enough */
+               if (this.con_neck < item.volume())
+                       return E_TOOLARGE;
+               if (this.con_volume_cur + item.volume() > this.con_volume_max)
+                       return E_TOOLARGE;
+               /* We can only hold objects which are light enough */
+               if (this.con_weight_cur + item.weight() > this.con_weight_max)
+                       return E_TOOHEAVY;
+
+               /*
+                * XXX We need to do something special for container
+                * objects...  We need to adapt their possible volume left, if
+                * they can expand, to the remaining allowed expansion, if
+                * possible, restrained by this container's remaining room...
+                * Should we link items in a parent/child manner to be able to
+                * do this kind of trick?  Hmm or should we just forget about
+                * expandable volume objects to simplify the design?
+                * contents/container would be like children/parent...
+                * Objects would affect their parent container if they are
+                * expandable, whenever objects are added/removed, and would
+                * also verify their parent's volume/weight limits anytime.
+                * We need to do this for weights anyway.
+                *
+                * Also implement a recursive runner which maps all objects,
+                * for instance for inventory purposes, but only recursing
+                * through containers which are in the open state.
+                */
+
+               this.con_items[item.index] = item;
+               this.con_volume_cur += item.volume();
+               this.con_weight_cur += item.weight();
+               this.con_items++;
+
+               return 0;
+       },
+
+       remove: function(item)
+       {
+               /* Can only remove items from open container */
+               if (!this.con_open)
+                       return E_CLOSED;
+               /* We can only remove items which are really inside */
+               if (this.con_items[item.index] == undefined)
+                       return E_NONE;
+
+               this.con_weight_cur -= item.weight();
+               this.con_volume_cur -= item.volume();
+               delete this.con_items[item.index];
+               this.con_items--;
+       }
+};