PDA

View Full Version : Array Updating Issue



alvarofer0021
10-03-2011, 07:58 PM
Hello Its me again!.... Again keeping the tread count as low as possible ;)

But i have one issue That is kind of driving me mad

I have an array That contains the player inventory Items

When adding items to the array it updates fine no problems at all

the problem is that when i try to remove an item from the array Appareantly it isnt removed the array stays as the same

Anyway here is the way i remove items from the array

playercontroller.uc




exec function DropItem(String ItemToDrop)
{
local SapituInventory inv;
local StaticMesh sm;

local SapituItem itm;
local int i;
itm = sapitu.getItem(ItemToDrop);
if (itm == none)
{
TeamMessage(none, "No item type exists with id to craft: "$ItemToDrop, 'none');
return;
}
inv = sapitu.createInventory(itm);
if (inv == none)
{
TeamMessage(none, "Error crafting item: "$ItemToDrop, 'none');
return;
}


if (PawnHasItem(ItemToDrop))
{
TeamMessage(none,"Player drop the item"$itm.DisplayName, 'none');

char.RemoveInventory(inv); // HERE is where i remove or thats what i think the item from the array
PickupItem = Spawn(class'Items', self,, Pawn.Location); // code for item spawning
sm = StaticMesh(DynamicLoadObject(itm.ItemModel, class'StaticMesh'));
PickupItem.SetStaticMesh(sm);



}
}

Then on sapituchar.uc

where the item giving and removing is handled and contains the array


function bool removeInventory(SapituInventory item)
{

local int i;
`Log("REMOVE INVENTORY HAS BEEN CALLED ");
i = inventory.find(item);
if (i == INDEX_NONE) return false;
inventory.removeItem(item);
inventoryRecords.removeItem(string(item.name));
`Log("removed a item from the character!! this is from sapitu character ");
return true;
}

and to add items
function bool addInventory(SapituInventory item)
{
local int i;
i = inventory.find(item);
if (i != INDEX_NONE) return false;
inventory.addItem(item);
inventoryRecords.addItem(string(item.name));
return true;
}

pretty much untouched from the sapitu system

The weird thing is that well none of the logs i added on the removeinventory function get called at all And im not quite sure what is causing this problem So if anyone could point me in the right direction i would appreciate it !!!:o

alvarofer0021
10-04-2011, 02:47 PM
Bumping the tread

Spoof
10-04-2011, 03:43 PM
If nothing is being logged then RemoveInventory isn't being called, which suggests the problem is in PawnHasItem(ItemToDrop). Put a log msg in that conditional branch and see if PawnHasItem is ever returning true.

alvarofer0021
10-04-2011, 03:47 PM
It does return true i even did a function that makes no checks for the items and just remove it from the array Still does nothing at all

Spoof
10-04-2011, 04:16 PM
In this situation I would bracket every possibility with a log message to track down the issue, so log calls within each clause...



if ( itm == none )
{
`log("FAILED: itm == none");
//....



if ( inv == none )
{
`log("FAILED: inv == none");
//...



if ( PawnHasItem(ItemToDrop) )
{
`log("SUCCESS: pawn has item");
//...


That will narrow down the issue.

alvarofer0021
10-04-2011, 06:19 PM
Well just did


function bool removeInventory(SapituInventory item)
{

local int i;
`Log("REMOVE INVENTORY HAS BEEN CALLED ");
i = inventory.find(item);
`Log("i = inventory.find(item) called ");
if (i == INDEX_NONE) return false;
`Log("if statement called ");
inventory.removeItem(item);
`Log("Inventory.removeItem has been called ");
inventoryRecords.removeItem(string(item.name));
`Log("removed a item from the character!! this is from sapitu character ");
return true;
}

According to the log it Calls everything till I=Inventory.find(item)

The rest doesnt gets called at all and im not quite sure what could cause this since i used the same method with AddInventory

Spoof
10-04-2011, 06:57 PM
So it's not finding it in the inventory then, and exiting because i == INDEX_NONE?

You may want to show more of the code because I can't figure out your system. I see sapitu and char references, but you have a sapituchar class? That's confusing me :)

alvarofer0021
10-04-2011, 07:58 PM
Sorry about that lol Well here are ALL my sapitu clases I barely have touch them and the removeInventory function its just how it was I dident did any changes to addinventory or removeinventory

Now since Addinventory works and its basicly the same method Why removeinventory doesnt?

Sapitu


/**
* Savegames Are Possible In The UDK. Well, sort of.
*
* By Michiel 'elmuerte' Hendriks for Epic Games, Inc.
*
* You are free to use this example as you see fit, as long as you
* properly attribute the origin.
*/
class Sapitu extends Object dependsOn(SapituItem);

/**
* struct used to cache the list of items
*/
struct ItemRecord
{
var string itemName;
var SapituItem item;
};

/**
* Contains all known items
*/
var array<ItemRecord> items;

/**
* Load a character using it's id
*
* @param charId
* The identifier for the character
* @return The created character, or none if it could not be created/loaded
*/
function SapituCharacter loadCharacter(string charId)
{
local SapituCharacter char;
local SapituItem item;
local SapituInventory inv;
local int i;
local array<string> chars;

chars = getCharacters();
if (chars.find(charId) == INDEX_NONE) return none;

char = new(none, charId) class'SapituCharacter';
if (char == none) return none;
// load the inventory
for (i = 0; i < char.inventoryRecords.length; ++i)
{
inv = new(none, char.inventoryRecords[i]) class'SapituInventory';
if (inv == none) continue;
item = getItem(inv.itemName);
if (item == none) continue;
inv.item = item;
char.inventory.addItem(inv);
}
return char;
}

/**
* Get a list of all existing character ids
*
* @return The list of character ids.
*/
function array<string> getCharacters()
{
local array<string> res;
local int i, idx;
GetPerObjectConfigSections(class'SapituCharacter', res);
// the result contains: "ObjectName ClassName" but we only need the ObjectNames
for (i = 0; i < res.length; ++i)
{
idx = InStr(res[i], " ");
if (idx != INDEX_NONE)
{
res[i] = left(res[i], idx);
}
}
return res;
}

/**
* Create a new character instance. None of it's fields have been initialized.
* It is just created with a proper id, and not saved yet.
*
* @param charId
* Optionally character id to use. This must be unique.
* @return The newly created character
*/
function SapituCharacter createCharacter(optional string charId = "Char_"$TimeStamp()$rand(100)$"_")
{
// note: object names shouldn't end with a number
local SapituCharacter char;
charId -= " ";
charId -= ":";
charId -= "/";
charId -= "-";
char = new(none, charId) class'SapituCharacter';
return char;
}

/**
* Initialize the item database
*/
function loadItemDB()
{
local array<UDKUIResourceDataProvider> ProviderList;
local int i;

if (items.length == 0)
{
// fill the list
class'UDKUIDataStore_MenuItems'.static.GetAllResou rceDataProviders(class'SapituItem', ProviderList);
items.length = ProviderList.length;
for (i = 0; i < ProviderList.length; ++i)
{
items[i].itemName = string(ProviderList[i].name);
items[i].item = SapituItem(ProviderList[i]);
}
}
}

/**
* Get the SapituItem instance for a given name
*
* @param itemName
* The name of the item
* @return The SapituItem instance, or none
*/
function SapituItem getItem(String itemName)
{
local int i;
loadItemDB();

i = items.find('itemName', itemName);
if (i != INDEX_NONE)
{
return items[i].item;
}
return none;
}

/**
* Create a new inventory item.
*
* @param fromItem
* The item to create an inventory item from
* @return
* The inventory item which can be added to the character
*/
function SapituInventory createInventory(SapituItem fromItem)
{
local string invId;
local SapituInventory inv;

// note: object names shouldn't end with a number
invId = string(fromItem.name)$"_"$TimeStamp()$rand(100)$"_";
invId -= " ";
invId -= ":";
invId -= "/";
invId -= "-";
inv = new(none, invId) class'SapituInventory';
inv.item = fromItem;
inv.itemName = string(fromItem.name);
inv.quality = 100;
inv.level = fromItem.level.min+Rand(fromItem.level.max-fromItem.level.min);
inv.characterLevel = fromItem.characterLevel.min+Rand(fromItem.characte rLevel.max-fromItem.characterLevel.min);
//inv.weight = calcValue(inv.level);
inv.value = calcValue(inv.level, fromItem.value);
return inv;
}

/**
* Calculate the value using the given value forumula
*
* @param level
* The level to use as input
* @param form
* The forumula configuration
* @return the value
*/
function int calcValue(int level, ValueFormula form)
{
return form.base + Round(form.levelMult * level) + Round(FRand() * form.randMult);
}


SAPITU CHARACTER


/**
* Savegames Are Possible In The UDK. Well, sort of.
*
* By Michiel 'elmuerte' Hendriks for Epic Games, Inc.
*
* You are free to use this example as you see fit, as long as you
* properly attribute the origin.
*/
class SapituCharacter extends Object config(Sapitu) perobjectconfig;




var config string CharacterName;
var config string CharacterClass;

var config int XP;
var config int XPGatheredForNextLevel;
var config int XPRequiredForNextLevel;
var config int level;
var config float SprintSpeed;
var config float HealthRegenerationSpeed;
var config int SkillPoints;
var config float Stamina;
var config array<string> inventoryRecords; // a array of the items
var array<SapituInventory> inventory;
var config int Thirst;
var config int Sleep;
var config int Hunger;
var config int Weight;
var config int WoodCuttingSkill;
var config int FishingSkill;
var config int CraftingSkill;
var config int cookingskill;
var config int MaxWeight;


/**
* Save this character and it's inventory. Do not use SaveConfig() to save
* the character, because it won't save its inventory.
*/
function save()
{
local int i;
for (i = 0; i < inventory.Length; i++)
{
inventory[i].SaveConfig();
}
SaveConfig();
}

/**
* Add an item to the inventory
*
* @param item
* The item to add.
* @return
* True if the item was added
*/



function bool addInventory(SapituInventory item)
{
local int i;
i = inventory.find(item);
if (i != INDEX_NONE) return false;
inventory.addItem(item);
inventoryRecords.addItem(string(item.name));
return true;
}


/**
* Remove an item from the inventory
* @param item
* The item to remove
* @return
* True if the item was removed
*/
function bool removeInventory(SapituInventory item)
{

local int i;
`Log("REMOVE INVENTORY HAS BEEN CALLED ");
i = inventory.find(item);
`Log("i = inventory.find(item) called ");
if (i == INDEX_NONE) return false;
`Log("if statement called ");
inventory.removeItem(item);
`Log("Inventory.removeItem has been called ");
inventoryRecords.removeItem(string(item.name));
`Log("removed a item from the character!! this is from sapitu character ");
return true;
}


Sapitu inventory


/**
* Savegames Are Possible In The UDK. Well, sort of. An item in the inventory
* of a SapituCharacter. This is an instance of a SapituItem, it contains fixed
* values for certain properties. Everything that is constant for a inventory
* item should be read through the SapituItem instance linked in this class.
*
* By Michiel 'elmuerte' Hendriks for Epic Games, Inc.
*
* You are free to use this example as you see fit, as long as you
* properly attribute the origin.
*/
class SapituInventory extends Object config(Sapitu) perobjectconfig;

/**
* Name of the SapituItem
*/
var config string itemName;



/**
* Quality of the item, between 0 and 100
*/
var config int quality;


/**
* Actual level of this item
*/
var config int level;

/**
* Actual required characterlevel of this item
*/
var config int characterLevel;
// bool variable to determine if this item is eateable or not


/**
* Actual weight of this item
*/
var config int weight;

var config int itemCount;

/**
* Actual value of this item
*/
var config int value;

/**
* The instatiated item
*/
var SapituItem item;



sapitu itemm


/**
* Savegames Are Possible In The UDK. Well, sort of. Database entry for
* world items. These are referenced by SapituInventory instances. These
* items are just base configurations, when an SapituInventory item is created
* it will use the information in this class to produce an actual instance.
*
* By Michiel 'elmuerte' Hendriks for Epic Games, Inc.
*
* You are free to use this example as you see fit, as long as you
* properly attribute the origin.
*/
class SapituItem extends UTUIResourceDataProvider perobjectconfig;

/**
* Defines a range of values.
*/
struct MinMax
{
var int min;
var int max;
};

/**
* The input for the formula to calculate the value based on the given level
* and a random value. The maximum value would be:
* <code>base + level*levelMult + randMult</code>
*/
struct ValueFormula
{
var int base;
var float levelMult;
var int randMult;
};



/**
* The name of this item to show ingame.
*/
var config string DisplayName;
var config bool bFood;



/**
* The description of the item
*/
var config string Description;

// Count of this item

var config int Count;

var config string RequiredItem1;
var config string RequiredItem2;
var config string RequiredItem3;
var config string RequiredItem4;
var config int AmmountToFeed;
/**
* Name of the texture to use for the icon
*/
var config string icon;

/**
* The level range this item can have.
*/
var config MinMax level;

/**
* The level the character has to have to equip this item.
*/
var config MinMax characterLevel;

/**
* The weight of this item
*/
//var config ValueFormula weight;
var config int weight;
/**
* The gold value of this item
*/
var config ValueFormula value;

// the model for this item?
var config string ItemModel;



defaultproperties
{
bSearchAllInis=true
}

Spoof
10-05-2011, 04:49 AM
Hmm. The most obvious thing I see is some confusion over which object actually owns the item in its array.


inv = sapitu.createInventory(itm);

// ... and ...

char.RemoveInventory(inv);

Apparently sapitu.CreateInventory returns a copy of the item to be dropped.

Then char.RemoveInventory(inv) attempts to remove the newly created copy from it's inventory array, which fails because it's not there. The only reference to it is the local var inv.

alvarofer0021
10-05-2011, 08:06 AM
mmmm Then how can i delete The item if The function removeInventory always ask For a sapituInventory?

i just tried
char.AddInventory(inv);
char.RemoveInventory(inv);

And all the code ran fine except the item dident dissapear from the inventory Maybe becouse im adding a second instance of the item so only the second one dissapears instead of the first one?

alvarofer0021
10-06-2011, 06:53 PM
Huge thanks to theflamingsjunk who helped me a lot debugging all the code And we hit the issue

Once the item is picked up And i hit the drop button the item im triying to drop is diferent than the one i picked up So well it gives a error i now need to Find a way to link the Sapitu Inventory instance to every item i pick up

alvarofer0021
10-08-2011, 01:37 PM
Again bumping the tread Im still stuck with the issue So far i tried Creating a instance of sapituInventory and assigning it to every item So the item i drop is the same item i pick up

Still i keep getting the same Issue im not quite sure how else would i go About doing this..

Revelant code that manages item picking up and dropping


exec function GiveItem(String baseItem)
{

local int ItemWeight;
local SapituInventory inv;
local SapituItem itm;
local StaticMesh sm;
itm = sapitu.getItem(baseItem);
if (itm == none)
{
TeamMessage(none, "No item type exists with id: "$baseItem, 'none');
return;
}
inv = sapitu.createInventory(itm);
itm.InventoryClass = inv;
if (inv == none)
{
TeamMessage(none, "Error creating inventory item from: "$baseItem, 'none');
return;
}
ItemWeight += inv.Weight;
GiveWeight(ItemWeight);
if (char.Weight == 50)
{
TeamMessage(none, "No More Space Available in Inventory: ", 'none');
return;
}
TeamMessage(none, "You Have Pickup A "$itm.DisplayName$"with the id (id:"$inv.Name$")", 'none');
TeamMessage(none, "Your total Weight is "$char.Weight, 'none');
//items.addItem(inv);
char.AddInventory(inv);
return;

}




exec function DropItem(String ItemToDrop)
{
local SapituInventory inv;
local StaticMesh sm;

local SapituItem itm;
local int i;
itm = sapitu.getItem(ItemToDrop);
if (itm == none)
{
TeamMessage(none, "No item type exists with id to craft: "$ItemToDrop, 'none');
return;
}
inv = sapitu.createInventory(itm);
//itm.InventoryClass = inv;
if (inv == none)
{
TeamMessage(none, "Error crafting item: "$ItemToDrop, 'none');
return;
}


if (PawnHasItem(ItemToDrop))
{
TeamMessage(none,"Player drop the item"$itm.DisplayName, 'none');
char.removeInventory(itm.InventoryClass);
PickupItem = Spawn(class'Items', self,, Pawn.Location);
sm = StaticMesh(DynamicLoadObject(itm.ItemModel, class'StaticMesh'));
PickupItem.SetStaticMesh(sm);



}
}

those are inside my player controller

Now here is sapitu char where the AddInventory and remove inventory functions are



function bool addInventory(SapituInventory item)
{
local int i;
i = inventory.find(item);
if (i != INDEX_NONE) return false;
inventory.addItem(item);
inventoryRecords.addItem(string(item.name));
return true;
}


/**
* Remove an item from the inventory
* @param item
* The item to remove
* @return
* True if the item was removed
*/
function bool removeInventory(SapituInventory item)
{

local int i;
`Log("REMOVE INVENTORY HAS BEEN CALLED ");
`log(inventory[0]);
`log(item);
i = inventory.find(item);
`log(i);
`Log("i = inventory.find(item) called ");
if (i == INDEX_NONE) return false;
`Log("if statement called ");
`log(inventory[i]);
`log(inventory.length);
inventory.removeItem(item);
`log(inventory.length);
`log(inventory[i]);
`Log("Inventory.removeItem has been called ");
inventoryRecords.removeItem(string(item.name));
`Log("removed a item from the character!! this is from sapitu character ");
return true;
}

Finally main sapitu class where CreateInventory and get item are located


**
* Get the SapituItem instance for a given name
*
* @param itemName
* The name of the item
* @return The SapituItem instance, or none
*/
function SapituItem getItem(String itemName)
{
local int i;
loadItemDB();

i = items.find('itemName', itemName);
if (i != INDEX_NONE)
{
return items[i].item;
}
return none;
}

/**
* Create a new inventory item.
*
* @param fromItem
* The item to create an inventory item from
* @return
* The inventory item which can be added to the character
*/
function SapituInventory createInventory(SapituItem fromItem)
{
local string invId;
local SapituInventory inv;

// note: object names shouldn't end with a number
invId = string(fromItem.name)$"_"$TimeStamp()$rand(100)$"_";
invId -= " ";
invId -= ":";
invId -= "/";
invId -= "-";
inv = new(none, invId) class'SapituInventory';
inv.item = fromItem;
inv.itemName = string(fromItem.name);
inv.quality = 100;
inv.level = fromItem.level.min+Rand(fromItem.level.max-fromItem.level.min);
inv.characterLevel = fromItem.characterLevel.min+Rand(fromItem.characte rLevel.max-fromItem.characterLevel.min);
//inv.weight = calcValue(inv.level);
inv.value = calcValue(inv.level, fromItem.value);
return inv;
}


Seriously this is driving me mad! :mad: So well if anyone is good enough to give it a look I would REALLY appreciate it!

alvarofer0021
10-15-2011, 11:33 AM
Okay i think i almost got it Reading the sapitu inventory i found var SapituItem item; So instead of getting a instance of the item with the string I try to directly Create the inventory and get the item from the player inventory

Doing this




exec function DropItem(String ItemToDrop)
{
local SapituInventory inv;
local StaticMesh sm;
local int i;
local SapituItem itm;



if (PawnHasItem(ItemToDrop)) // if we have the tiem Search it again on the inventory
{
for (i = 0; i < char.inventory.Length; ++i)
{

itm = sapitu.getItem(char.inventory[i].itemName);
inv = sapitu.createInventory(char.inventory[i].item); //create the new item inventory instance from the inventory item




TeamMessage(none,"Player drop the item"$itm.DisplayName, 'none');

char.removeInventory(inv);
`log(char.inventory[i]);
PickupItem = Spawn(class'Items', self,, Pawn.Location);
sm = StaticMesh(DynamicLoadObject(itm.ItemModel, class'StaticMesh'));
PickupItem.SetStaticMesh(sm);


}
}
}

Still Not working for some reason The item that i pick up is diferent than the one im triying to drop This is what the log Output while dropping the item

SWORD1_2011101511020476_
SWORD1_2011101511020728_
1
sword1_2011101511020728_
2
1
Accessed ARRAY ALVARO.inventory out of bounds(1/1)
Function TFP.SapituCharacter.removeinventory:0127
None
sword1_2011101511020476_

as you can see the item that i pick up is not at all the item that im triying to drop

alvarofer0021
10-16-2011, 02:15 PM
bumping the tread

alvarofer0021
10-16-2011, 03:01 PM
I FCKING DID IT!

i just used char.remove.ivnentory(i, 1); instead of removeInventory since apparently its broken

!!


Heres the code if anyone is interesed


exec function DropItem(String ItemToDrop)
{
local SapituInventory inv;
local StaticMesh sm;
local int i;
local SapituItem itm;

if (PawnHasItem(ItemToDrop))
{
for (i = 0; i < char.inventory.Length; ++i)
{
if(char.inventory[i].itemName == ItemToDrop)
{

PickupItem = Spawn(class'Items', self,, Pawn.Location);
sm = StaticMesh(DynamicLoadObject(char.inventory[i].item.itemModel, class'StaticMesh'));
PickupItem.SetStaticMesh(sm);
char.inventory.remove(i, 1);
`log("dropped a item");
`log(char.inventory[i]);
}

}
}
}