Game Development Community

Did something change in scriping class arrays? Bug maybe?

by Kevin Mitchell · in Torque 3D Professional · 06/08/2009 (2:17 am) · 9 replies

I am porting over everything from my TGEA prototype and my inventory code has decided to just stop working... Apparently the creating of my class array is no longer valid? When did this happen?

$InventoryObject::MyInventory="";
$InventoryObject::InventoryCount=0;
$InventoryObject::ITEM_ENUM=1;
$InventoryObject::ARMOR_ENUM=2;
$InventoryObject::EVENTITEM_ENUM=3;

function InitalizeInventory(){
   
   %sqlite = new SQLiteObject(sqlite);
   if (%sqlite == 0)
   {
      echo("ERROR: Failed to create SQLiteObject. sqliteTest aborted.");
      return;
   }
   // open database
   if (sqlite.openDatabase("Database.db") == 0)
   {
      echo("ERROR: Failed to open database: " @ %dbname);
      echo("       Ensure that the disk is not full or write protected.  sqliteTest aborted.");
      sqlite.delete();
      return;
   }
   %query = "Select ItemID, ArmorID, EventItemID FROM Inventory;";
   %result = sqlite.query(%query, 0);
   if (%result == 0)
   {
      echo("ERROR: Failed to SELECT from users table.");
   }else{
      // attempt to retrieve result data
      %i=0;
      while (!sqlite.endOfResult(%result))
      {
         %ItemID = sqlite.getColumn(%result, "ItemID");
         %ArmorID = sqlite.getColumn(%result, "ArmorID");
         %EventItemID = sqlite.getColumn(%result, "EventItemID");
        $InventoryObject::MyInventory[%i] = new ScriptObject(Inventory){
            Name="";
            ID="";
            Type="";
            TypeID="";
            Quantity="";
            MaxQuantity="";
            Cost="";
            Description="";
            Image="";
         };
         $InventoryObject::InventoryCount=%i;
         %i++;
         sqlite.nextRow(%result);
      }
   }
   sqlite.clearResult(%result);
   sqlite.closeDatabase();
   sqlite.delete();
   PopulateInventory();
}

function PopulateInventory(){
      
   %sqlite = new SQLiteObject(sqlite);
   if (%sqlite == 0)
   {
      echo("ERROR: Failed to create SQLiteObject. sqliteTest aborted.");
      return;
   }
   // open database
   if (sqlite.openDatabase("Database.db") == 0)
   {
      echo("ERROR: Failed to open database: " @ %dbname);
      echo("       Ensure that the disk is not full or write protected.  sqliteTest aborted.");
      sqlite.delete();
      return;
   }
   %query = "Select ItemID, ArmorID, EventItemID, Quantity FROM Inventory;";
   %result = sqlite.query(%query, 0);
   if (%result == 0)
   {
      echo("ERROR: Failed to SELECT from users table.");
   }else{
      // attempt to retrieve result data
      %i=0;
      while (!sqlite.endOfResult(%result))
      {
         %ItemID = sqlite.getColumn(%result, "ItemID");
         %ArmorID = sqlite.getColumn(%result, "ArmorID");
         %EventItemID = sqlite.getColumn(%result, "EventItemID");
         %Quantity = sqlite.getColumn(%result, "Quantity");
         if(%ItemID != 0){
               $InventoryObject::MyInventory[%i].setID(%ItemID);
               $InventoryObject::MyInventory[%i].setType($InventoryObject::ITEM_ENUM);
               $InventoryObject::MyInventory[%i].setQuantity(%Quantity);
         }else if(%ArmorID != 0){
               $InventoryObject::MyInventory[%i].setID(%ArmorID);
               $InventoryObject::MyInventory[%i].setType($InventoryObject::ARMOR_ENUM);
               $InventoryObject::MyInventory[%i].setQuantity(%Quantity);
         }else if(%EventItemID != 0){
               $InventoryObject::MyInventory[%i].setID(%EventItemID);
               $InventoryObject::MyInventory[%i].setType($InventoryObject::EVENTITEM_ENUM);
               $InventoryObject::MyInventory[%i].setQuantity(%Quantity);
        }   
        %i++;
        sqlite.nextRow(%result);
      }
   }
   sqlite.clearResult(%result);
   sqlite.closeDatabase();
   sqlite.delete();
   PopulateInventoryNames();
}


function PopulateInventoryNames(){
   
   %sqlite = new SQLiteObject(sqlite);
   if (%sqlite == 0)
   {
      echo("ERROR: Failed to create SQLiteObject. sqliteTest aborted.");
      return;
   }
   // open database
   if (sqlite.openDatabase("Database.db") == 0)
   {
      echo("ERROR: Failed to open database: " @ %dbname);
      echo("       Ensure that the disk is not full or write protected.  sqliteTest aborted.");
      sqlite.delete();
      return;
   }
   for(%i=0;%i<$InventoryObject::InventoryCount;%i++){
      if($InventoryObject::MyInventory[%i].getType()==1){
           %query2 = "Select Name, ItemTypeID, MaxQuantity, Cost, Description, Image FROM Items where ItemID="@$InventoryObject::MyInventory[%i].getID()@";";
           %result2 = sqlite.query(%query2, 0);
           if (%result2 == 0)
           {
              echo("ERROR: Failed to SELECT from users table.");
           }else{
              $InventoryObject::MyInventory[%i].setName(sqlite.getColumn(%result2, "Name"));
              $InventoryObject::MyInventory[%i].setTypeID(sqlite.getColumn(%result2, "ItemTypeID"));
              $InventoryObject::MyInventory[%i].setMaxQuantity(sqlite.getColumn(%result2, "MaxQuantity"));
              $InventoryObject::MyInventory[%i].setCost(sqlite.getColumn(%result2, "Cost"));
              $InventoryObject::MyInventory[%i].setDescription(sqlite.getColumn(%result2, "Description"));
              $InventoryObject::MyInventory[%i].setImage(sqlite.getColumn(%result2, "Image"));
              sqlite.clearResult(%result2);
           }
      }else if($InventoryObject::MyInventory[%i].getType()==2){
           %query2 = "Select Name, ArmorTypeID, MaxQuantities, Cost, Description, Image FROM Armors where ArmorID="@$InventoryObject::MyInventory[%i].getID()@";";
           %result2 = sqlite.query(%query2, 0);
           if (%result2 == 0)
           {
              echo("ERROR: Failed to SELECT from users table.");
           }else{
              $InventoryObject::MyInventory[%i].setName(sqlite.getColumn(%result2, "Name"));
              $InventoryObject::MyInventory[%i].setTypeID(sqlite.getColumn(%result2, "ArmorTypeID"));
              $InventoryObject::MyInventory[%i].setMaxQuantity(sqlite.getColumn(%result2, "MaxQuantities"));
              $InventoryObject::MyInventory[%i].setCost(sqlite.getColumn(%result2, "Cost"));
              $InventoryObject::MyInventory[%i].setDescription(sqlite.getColumn(%result2, "Description"));
              $InventoryObject::MyInventory[%i].setImage(sqlite.getColumn(%result2, "Image"));
              sqlite.clearResult(%result2);
           }
      }else if($InventoryObject::MyInventory[%i].getType()==3){
           %query2 = "Select Name, Quantity FROM Items where ItemID="@$InventoryObject::MyInventory[%i].getID()@";";
           %result2 = sqlite.query(%query2, 0);
           if (%result2 == 0)
           {
              echo("ERROR: Failed to SELECT from users table.");
           }else{
              $InventoryObject::MyInventory[%i].setName(sqlite.getColumn(%result2, "Name"));
           }
      }
   }
   
   //sqlite.clearResult(%result);
   sqlite.closeDatabase();
   sqlite.delete();
}

function Inventory::getID(%this){
   return %this.ID;  
}

function Inventory::getName(%this){
   return %this.Name;  
}

function Inventory::getType(%this){
   return %this.Type;  
}

function Inventory::getTypeID(%this){
   return %this.TypeID;  
}

function Inventory::getQuantity(%this){
   return %this.Quantity;  
}

function Inventory::setID(%this, %value){
   %this.ID=%value;  
}

function Inventory::setName(%this, %value){
   %this.Name=%value;  
}

function Inventory::setType(%this, %value){
   %this.Type=%value;  
}

function Inventory::setTypeID(%this, %value){
   %this.TypeID=%value;  
}


function Inventory::setQuantity(%this, %value){
   %this.Quantity=%value;  
}

function Inventory::getMaxQuantity(%this){
   return %this.MaxQuantity;  
}

function Inventory::setMaxQuantity(%this, %value){
   %this.MaxQuantity=%value;  
}

function Inventory::getCost(%this){
   return %this.Cost;  
}

function Inventory::setCost(%this, %value){
   %this.Cost=%value;  
}

function Inventory::getDescription(%this){
   return %this.Description;  
}

function Inventory::setDescription(%this, %value){
   %this.Description=%value;  
}
function Inventory::getImage(%this){
   return %this.Image;  
}

function Inventory::setImage(%this, %value){
   %this.Image=%value;  
}

function CheckInventory(%Name){
   %hasItem=false;
   for(%i=0;%i<$InventoryObject::InventoryCount;%i++){
      if(%Name $= $InventoryObject::MyInventory[%i].getName()){
         %hasItem=true;
         return $InventoryObject::MyInventory[%i].getQuantity(); 
      }
   }
   return -1;
}

function AddInventory(%Type,%Name, %Quantity){
   for(%i=0;%i<$InventoryObject::InventoryCount;%i++){
      if(%Name $= $InventoryObject::MyInventory[%i].getName()){
         $InventoryObject::MyInventory[%i].setQuantity($InventoryObject::MyInventory[%i].getQuantity()+%Quantity);
         return;
      }
   }
   InsertInventoryName(%Type,%Name,%Quantity);
}

function InsertInventoryName(%Type,%Name,%Quantity){
   
   %sqlite = new SQLiteObject(sqlite);
   if (%sqlite == 0)
   {
      echo("ERROR: Failed to create SQLiteObject. sqliteTest aborted.");
      return;
   }
   // open database
   if (sqlite.openDatabase("Database.db") == 0)
   {
      echo("ERROR: Failed to open database: " @ %dbname);
      echo("       Ensure that the disk is not full or write protected.  sqliteTest aborted.");
      sqlite.delete();
      return;
   }
   %i=$InventoryObject::InventoryCount;
      if(%Type==1){
           %query2 = "Select Name,ItemID,ItemTypeID,MaxQuantity,Cost, Description, Image FROM Items where Name=""@%Name@"";";
           %result2 = sqlite.query(%query2, 0);
           if (%result2 == 0)
           {
              echo("ERROR: Failed to SELECT from users table.");
           }else{
              $InventoryObject::MyInventory[%i].setName(sqlite.getColumn(%result2, "Name"));
              $InventoryObject::MyInventory[%i].setID(sqlite.getColumn(%result2, "ItemID"));
              $InventoryObject::MyInventory[%i].setType(1);
              $InventoryObject::MyInventory[%i].setTypeID(sqlite.getColumn(%result2, "ItemTypeID"));
              $InventoryObject::MyInventory[%i].setMaxQuantity(sqlite.getColumn(%result2, "MaxQuantity"));
              $InventoryObject::MyInventory[%i].setCost(sqlite.getColumn(%result2, "Cost"));
              $InventoryObject::MyInventory[%i].setDescription(sqlite.getColumn(%result2, "Description"));
              $InventoryObject::MyInventory[%i].setImage(sqlite.getColumn(%result2, "Image"));
              $InventoryObject::MyInventory[%i].setQuantity(%Quantity);
              $InventoryObject::InventoryCount++;
           }
      }else if(%Type==2){
           %query2 = "Select Name, ArmorID, ArmorTypeID, MaxQuantities,Cost, Description, Image FROM Armors where %Name="@%Name@";";
           %result2 = sqlite.query(%query2, 0);
           if (%result2 == 0)
           {
              echo("ERROR: Failed to SELECT from users table.");
           }else{
              $InventoryObject::MyInventory[%i].setName(sqlite.getColumn(%result2, "Name"));
              $InventoryObject::MyInventory[%i].setID(sqlite.getColumn(%result2, "ArmorID"));
              $InventoryObject::MyInventory[%i].setType(2);
              $InventoryObject::MyInventory[%i].setTypeID(sqlite.getColumn(%result2, "ItemTypeID"));
              $InventoryObject::MyInventory[%i].setMaxQuantity(sqlite.getColumn(%result2, "MaxQuantities"));
              $InventoryObject::MyInventory[%i].setCost(sqlite.getColumn(%result2, "Cost"));
              $InventoryObject::MyInventory[%i].setDescription(sqlite.getColumn(%result2, "Description"));
              $InventoryObject::MyInventory[%i].setImage(sqlite.getColumn(%result2, "Image"));
              $InventoryObject::MyInventory[%i].setQuantity(%Quantity);
              $InventoryObject::InventoryCount++;
           }
      }else if(%Type==3){
           %query2 = "Select Name, Quantity FROM Items where ItemID="@%Name@";";
           %result2 = sqlite.query(%query2, 0);
           if (%result2 == 0)
           {
              echo("ERROR: Failed to SELECT from users table.");
           }else{
              $InventoryObject::MyInventory[%i].setName(sqlite.getColumn(%result, "Name"));
           }
      }
   for(%h=0;%h<$InventoryObject::InventoryCount;%h++){
      echo("Echo ItemNumber "@%h@": "@$InventoryObject::MyInventory[%h].getName() @" - "@ $InventoryObject::MyInventory[%h].getTypeID() @" - "@ $InventoryObject::MyInventory[%h].getQuantity());
   }
}


function RemoveInventory(%Name, %Quantity){
   for(%i=0;%i<$InventoryObject::InventoryCount;%i++){
      if(%Name $= $InventoryObject::MyInventory[%i].getName()){
          $InventoryObject::MyInventory[%i].setQuantity($InventoryObject::MyInventory[%i].getQuantity()-%Quantity); 
      }
   }
}

InitalizeInventory();

Errors are:

46: Cannot re-declare object [Inventory].
46: Cannot re-declare object [Inventory].
46: Cannot re-declare object [Inventory].
46: Cannot re-declare object [Inventory].
46: Cannot re-declare object [Inventory].
46: Cannot re-declare object [Inventory].
scripts/client/MainFrame/Inventory.cs (93): Unable to find object: '0' attempting to call function 'setID'
scripts/client/MainFrame/Inventory.cs (94): Unable to find object: '0' attempting to call function 'setType'
scripts/client/MainFrame/Inventory.cs (95): Unable to find object: '0' attempting to call function 'setQuantity'
scripts/client/MainFrame/Inventory.cs (89): Unable to find object: '0' attempting to call function 'setID'
scripts/client/MainFrame/Inventory.cs (90): Unable to find object: '0' attempting to call function 'setType'
scripts/client/MainFrame/Inventory.cs (91): Unable to find object: '0' attempting to call function 'setQuantity'
scripts/client/MainFrame/Inventory.cs (89): Unable to find object: '0' attempting to call function 'setID'
scripts/client/MainFrame/Inventory.cs (90): Unable to find object: '0' attempting to call function 'setType'
scripts/client/MainFrame/Inventory.cs (91): Unable to find object: '0' attempting to call function 'setQuantity'
scripts/client/MainFrame/Inventory.cs (89): Unable to find object: '0' attempting to call function 'setID'
scripts/client/MainFrame/Inventory.cs (90): Unable to find object: '0' attempting to call function 'setType'
scripts/client/MainFrame/Inventory.cs (91): Unable to find object: '0' attempting to call function 'setQuantity'
scripts/client/MainFrame/Inventory.cs (89): Unable to find object: '0' attempting to call function 'setID'
scripts/client/MainFrame/Inventory.cs (90): Unable to find object: '0' attempting to call function 'setType'
scripts/client/MainFrame/Inventory.cs (91): Unable to find object: '0' attempting to call function 'setQuantity'
scripts/client/MainFrame/Inventory.cs (89): Unable to find object: '0' attempting to call function 'setID'
scripts/client/MainFrame/Inventory.cs (90): Unable to find object: '0' attempting to call function 'setType'
scripts/client/MainFrame/Inventory.cs (91): Unable to find object: '0' attempting to call function 'setQuantity'
scripts/client/MainFrame/Inventory.cs (129): Unable to find object: '0' attempting to call function 'getType'
scripts/client/MainFrame/Inventory.cs (144): Unable to find object: '0' attempting to call function 'getType'
scripts/client/MainFrame/Inventory.cs (159): Unable to find object: '0' attempting to call function 'getType'
scripts/client/MainFrame/Inventory.cs (129): Unable to find object: '0' attempting to call function 'getType'
scripts/client/MainFrame/Inventory.cs (144): Unable to find object: '0' attempting to call function 'getType'
scripts/client/MainFrame/Inventory.cs (159): Unable to find object: '0' attempting to call function 'getType'
scripts/client/MainFrame/Inventory.cs (129): Unable to find object: '0' attempting to call function 'getType'
scripts/client/MainFrame/Inventory.cs (144): Unable to find object: '0' attempting to call function 'getType'
scripts/client/MainFrame/Inventory.cs (159): Unable to find object: '0' attempting to call function 'getType'
scripts/client/MainFrame/Inventory.cs (129): Unable to find object: '0' attempting to call function 'getType'
scripts/client/MainFrame/Inventory.cs (144): Unable to find object: '0' attempting to call function 'getType'
scripts/client/MainFrame/Inventory.cs (159): Unable to find object: '0' attempting to call function 'getType'
scripts/client/MainFrame/Inventory.cs (129): Unable to find object: '0' attempting to call function 'getType'
scripts/client/MainFrame/Inventory.cs (144): Unable to find object: '0' attempting to call function 'getType'
scripts/client/MainFrame/Inventory.cs (159): Unable to find object: '0' attempting to call function 'getType'


So its like they took the warning of "warning multiple instances of the same object" and made it into an error where it dosnt even give you a new instance of the object it gives you a null return on your new instance????? There has to be a way around this. Has anyone ran into this when trying to make object arrays?

#1
06/08/2009 (2:54 am)
The script that you pasted looks like that should be the error messages you recieve when you have 6 items in your inventory. Thats if I read all of the error messages. lines 31 through 50. I'm a little tired but I'm trying to understand what you did here.
#2
06/08/2009 (4:06 am)
I'm pretty much loading normally the items that the player has into inventory. Which completely worked in TGEA 1.7.1 The loop of loading instance's of the inventory class is whats not acting right. In TGEA the warning would say "Warning creating multi instances of a class" the T3D it gives an error and never gives u a new handle of the instance.

The first instance works and records and stores the instance correctly but the other 5 instances do not work correctly. So my question is what or where did the Devs change this... I either want to kill the block that's depriving me of my new instance or find out if the have a new way of creating array based classes.
#3
06/08/2009 (5:42 am)

The problem is that with

new ScriptObject(Inventory)

in line 46 you are re-defining the "Inventory" object on each loop. IIRC there was some change here in Torque 3D and it won't allow you to re-define a binding to the same name.

Since you store the objects in an array, simply remove the object name and all should be fine.
#4
06/08/2009 (5:47 am)

Forgot: use the className etc. stuff to bind your methods.
#5
06/08/2009 (6:24 am)
Like:

$InventoryObject::MyInventory[%i] = Inventory;


That?

Would it be different instances of the object though... wont all the variables only exist in the one address?
#6
06/08/2009 (6:28 am)

Sorry, not being clear here. The object name is the thing in the parentheses, so use

%myVar = new ScriptObject() { /* properties /* };

to create an unnamed object. Each 'new' gives a separate object.

The problem above is binding to a single identifier. In fact, even in TGEA, you're repeatedly overwriting the binding to that single name.
#7
06/08/2009 (6:31 am)
No, no. If you try to create an object with the same name of an object that already exists, T3D will deny the creation. So it's returning zero.

Instead, create your objects like this:
$InventoryObject::MyInventory[%i] = new ScriptObject(){
            class = Inventory;
            Name="";
            ID="";
            Type="";
            TypeID="";
            Quantity="";
            MaxQuantity="";
            Cost="";
            Description="";
            Image="";
         };

For classes that don't support the "class" property (each class needs to opt-in in the source) you can trick them into binding by calling setName("") on them right after creation, since they'll keep the namespace binding of their original name.
#8
06/09/2009 (2:10 am)
Hmm i never knew this method was available... thanks so much, I owe you my first born.
#9
06/09/2009 (8:05 am)
There's always superClass, which defines a namespace that becomes parent to the class. You can do this, for example:
%obj = new ScriptObject(){  
 class = InventoryWeapon;  
 superClass = Inventory;
};
And have InventoryWeapon override Inventory methods, or call them using Parent::methodName().

Just be careful because namespace linking is global. This is the main reason why I believe GG disallowed same-name object creation in the first place, since you're likely to have your scripts behave strangely in non-obvious ways if you create two objects of different classes with the same name.