Announcement

Collapse
No announcement yet.

From ini file, to flash (Another inventory thread)

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    #16
    I've been trying to get to grips with the Inventory demo for quite a while now, looking through threads and finding bits of information and this thread has probably been the most helpful so far.

    I'm not getting the result I would like though so I thought I would ask instead of just hoping for my questions will be answered somewhere.

    I have a butchered version of the inventory demo, everything is removed except the 8 inventoryslots on the left side with name text field added and renamed. I have no real need for the different types, I just want to populate the list with from an array in the inventory manager class and then be updated when the quantity is changed.

    Here's the inventory class below. I used the code from earlier in the thread so it creates an object and puts it into an array in the flash file.
    Code:
    class Game_GFx_Inventory extends GFxMoviePlayer;
    
    /** Item struct */
    struct ResInvent
    {
        var string Type;
        var string ResourceName;
        var string ResourceIcon;
        var string ResourceQuantity;
    };
    
    var array<ResInvent> ResInventory;
    
    var GFxObject RootMC, Window, Panel;
    
    struct Slot
    {
    	var GFxObject 	SlotMC;
    	var GFxObject   RIndexMC;
    	var GFxObject   IconMC;
    	var GFxObject   NameMC;
    	var GFxObject   AmountMC;
    };
    
    var array<Slot> ResSlot;
    
    var Game_Inventory_Manager Inv;
    
    var int	NumberOfResourceSlots;
    
    var GFxObject	MouseContainer, MouseCursor;
    
    var GFxObject 	WeightBoxMC;
    
    var bool     bInitialized;
    
    function bool Start(optional bool StartPaused = false)
    {	
    	Super.Start(StartPaused);
    	
    	Advance(0);
    
    	if (!bInitialized)
    	{
    		ConfigureInventory();
    	}
    
    	UpdateResource();
    	ListInventory();
    	SetupResourceInventory();
    
    	return true;
    }
    
    function ConfigureInventory()
    {
    	
    	RootMC = GetVariableObject("_root");
    	
    	//When remaking the inventory remove "Panel."
    	Panel = RootMC.GetObject("MainPanel");
    	Window = Panel.GetObject("Inventory");
    	WeightBoxMC = Panel.GetObject("WeightBox");
    	
    	SetupResourceInventory();
            UpdateResource();
    
    	bInitialized = true;
    }
    
    function SetupResourceInventory()
    {
    	local byte i;
    	local GFxObject DataProvider; //DataProvider
    	local GFxObject TempObj;
    	
    	RootMC = GetVariableObject("_root");
    
    	DataProvider = CreateArray();
    	
    	for (i = 0; i < ResInventory.Length; i++)
    	{        
    		
    		TempObj = CreateObject("Object");
    		TempObj.SetString("Type", ResInventory[i].Type);
    		TempObj.SetString("ResourceName", ResInventory[i].ResourceName);
    		TempObj.SetString("ResourceIcon", ResInventory[i].ResourceIcon);
    		TempObj.SetString("ResourceQuantity", ResInventory[i].ResourceQuantity);
    		DataProvider.SetElementObject(i, TempObj);	
    	}
    
    	RootMC.SetObject("ResInventory", DataProvider);  	
    	ShowInventory();
    }
    
    function ShowInventory()
    {
    	ActionScriptVoid("showInventory");
    }
    
    function UpdateResource()
    {
    	local int i;
    	local string ResAmount;
    	local int Number;
    	
    	local Game_Pawn P;
        
    	P = Game_Pawn(GetPC().Pawn);
    	
    	Inv = Game_Inventory_Manager(P.InvManager);	
    	
    	//Look through the ResourceStorage array
    	for (i=0; i < Inv.ResourceStorage.Length; i++)
    	{	
    
    		if(ResInventory.Length > 0)
    		{
    			for(i=0; i <ResInventory.Length; i++)
    			{
    			
    				if(ResInventory[i].ResourceName == Inv.ResourceStorage[i].ResName)
    				{
    					//Will need an if for the MaxAmount at some point
    
    					//Add the various data values to the ResInventory array	
    					ResInventory[i].Type = "Resource";
    					ResInventory[i].ResourceIcon = Inv.ResourceStorage[i].ResourceClass.default.ResourceIcon;
    					ResInventory[i].ResourceName = Inv.ResourceStorage[i].ResName;
    
    					Number = Inv.ResourceStorage[i].Amount;
    
    					ResAmount = string(Number);
    
    					ResInventory[i].ResourceQuantity = ResAmount;
    				}
    				else
    				{
    					ResInventory.Length = ResInventory.Length + 1;
    					
    					//Will need an if for the MaxAmount at some point
    				
    					//Add the various data values to the ResInventory array	
    					ResInventory[i].Type = "Resource";
    					ResInventory[i].ResourceIcon = Inv.ResourceStorage[i].ResourceClass.default.ResourceIcon;
    					ResInventory[i].ResourceName = Inv.ResourceStorage[i].ResName;
    				
    					Number = Inv.ResourceStorage[i].Amount;
    				
    					ResAmount = string(Number);
    				
    					ResInventory[i].ResourceQuantity = ResAmount;
    				}
    			}
    		}	
    		else
    		{
    			ResInventory.Length = ResInventory.Length + 1;
    							
    			//Will need an if for the MaxAmount at some point
    						
    			//Add the various data values to the ResInventory array	
    			ResInventory[i].Type = "Resource";
    			ResInventory[i].ResourceIcon = Inv.ResourceStorage[i].ResourceClass.default.ResourceIcon;
    			ResInventory[i].ResourceName = Inv.ResourceStorage[i].ResName;
    						
    			Number = Inv.ResourceStorage[i].Amount;
    						
    			ResAmount = string(Number);
    						
    			ResInventory[i].ResourceQuantity = ResAmount;
    
                            `Log("##### - ResourceStorage data added to ResInventory");
    
    		}
    		
    		
    		//get the resource weight - causes access none at the moment
    		/**if(Inv.ResourceStorage[i].Weight > 0)
    		{
    			WeightBoxMC.GetObject("CurEncbnce").SetText(Inv.ResourceStorage[i].Weight);
    		}*/
    	}
    }
    
    function ListInventory()
    {
    	
    	`log("Resource Name: " @ RootMC.GetObject("ResInventory").GetElementMemberString(0, "ResourceName"));
    	`log("Resource Type: " @ RootMC.GetObject("ResInventory").GetElementMemberString(0, "Type"));
    	`log("Resource Quantity: " @ RootMC.GetObject("ResInventory").GetElementMemberString(0, "ResourceQuantity"));
    
    	//Log the ResInventory (UScript)
    	`log("UScript Resource Name: " @ResInventory[0].ResourceName);
    	`log("UScript Resource Quantity: "@ResInventory[0].ResourceQuantity);
    	`log("UScript Resource Icon: "@ResInventory[0].ResourceIcon);
    }
    
    
    event UpdateMousePosition(float X, float Y)
    {
    	local MouseInterfacePlayerInput MouseInterfacePlayerInput;
    
    	MouseInterfacePlayerInput = MouseInterfacePlayerInput(GetPC().PlayerInput);
    
    	if (MouseInterfacePlayerInput != None)
    	{
            	MouseInterfacePlayerInput.SetMousePosition(X, Y);
    	}
    }
    
    /** Toggles mouse cursor on/off */
    function ToggleCursor(bool showCursor, float mx, float my)
    {	
    	if (showCursor)
    	{
    		MouseContainer = CreateMouseCursor();
    		MouseCursor = MouseContainer.GetObject("mouseCursor_mc");
    		MouseCursor.SetPosition(mx,my);
    		MouseContainer.SetBool("topmostLevel", true);
    	}
    	else
    	{
    		MouseContainer.Invoke("removeMovieClip", args);
    		MouseContainer = none;	
    	}
    	
    	self.bIgnoreMouseInput = !showCursor;		
    }
    
    function GFxObject CreateMouseCursor()
    {
        return RootMC.AttachMovie("MouseContainer", "MouseCursor");
    }
    
    defaultproperties
    {
    	bEnableGammaCorrection = FALSE
    	rightThreshold = -10.9
    	leftThreshold = -8.34
    	bDisplayWithHudOff = TRUE
    	bInitialized = FALSE
    	MovieInfo=SwfMovie'Game_UI_HUD.Maia_UI_Inventory'
    	
    	//Number of slots in the resource part of the inventory
    	//this is so it doesn't add more items than it can
    	NumberOfResourceSlots = 8
    }
    My flash file is as follows, _root.MainPanel.Inventory.ResSlot0 - 8

    In the _root actions I have the code below, so the object created by Game_GFx_Inventory should be put into the ResInventory:Array right?
    Code:
    var ResInventory:Array = [];
    
    function showInventory()
    {
        for (i:Number = 0; i < ResInventory.length; i++)
        {
    		trace("Name: " + ResInventory[i].ResourceName + " | Type: " + ResInventory[i].Type + " | Quantity: " + ResInventory[i].ResourceQuantity);
        }
    }
    In the Inventory actions I have the code below, so each ResSlot should be populated from the array? This is the bit I'm unsure of.
    Code:
    for (var i:Number = 0; i<8; i++) {
    	this["ResSlot"+i].data = _root.ResInventory[i];
    }
    The problem is, it doesn't work. The trace("Name: " + ResInven.... etc.... in the _root code shows up correctly in the log, when a resource has been added to the ResInventory:Array, trace will tell me the name of the resource, the type and the amount, the logs in the uscript class (`log("Resource Name: " @ RootMC.GetObject("ResInventory").GetElementMemberS tring(0, "ResourceName")) show up correctly too.

    When doing a few tests, I tried adding an element to the array in flash manually, so it looked like this (var ResInventory:Array = [{Type:"Resource", ResourceName:"Metal", ResourceQuantity:"200"}]; and that worked perfectly, the element showed up in ResSlot0, it had the correct name, quantity and I was able to drag it to other slots. So my question is, what do you think I'm doing wrong?

    Sorry about the large amount of code, I think the problem is on the action script side but I'm not sure. Oh, I did change the InventorySlot.as class too. I changed the names of the text fields which reflect the changed names of the text fields in the InventorySlot instance in flash.
    Code:
    private var ResNameFld:TextField;
    private var ResQuantFld:TextField;
    
    
    // Public Methods:
    // Private Methods:	
    	private function update():Void {
    		icons.gotoAndStop(_data == null ? 1 : _data.asset);
    		ResNameFld.text = (_data == null || _data.ResourceName == null ? "" : _data.ResourceName);
    		ResQuantFld.text = (_data == null || _data.ResourceQuantity == null ? "0" : _data.ResourceQuantity);
    	}

    Comment


      #17
      Yeah I'm getting:
      ScriptWarning: Accessed None 'char'

      Guessing that mean char has nothing assigned to it? Because I've got nothing assigned to it in STGFxHUD it's only declared. I thought once loadChar was called from another class, it would be globally stored through out all the classes somehow and all I'd have to do is declare the class that builds the character as char to access the loaded character again. (seems silly to think this now)

      In my playercontroller I have the loadChar class, which seems to set char.
      Code:
      exec function loadChar(String charId)
      {
      	if (len(charId) == 0)
      	{
      		TeamMessage(none, "No character id given", 'none');
      		return;
      	}
      	if (char != none)
      	{
      		TeamMessage(none, "Discarding previous character: "$char.CharacterName$" (id:"$char.Name$")", 'none');
      	}
      	char = sapitu.loadCharacter(charId);
      	if (char == none)
      	{
      		TeamMessage(none, "No character found with id: "$charId, 'none');
      	}
      	else {
      		TeamMessage(none, "Character loaded", 'none');
      		showChar();
      	}
      }
      but all the other functions in my player controller class do not set char, and still work.
      Code:
      exec function showChar()
      {
      	local int i;
      	if (char == none)
      	{
      		TeamMessage(none, "There is no character", 'none');
      	}
      	TeamMessage(none, "ID:        "$char.name, 'none');
      	TeamMessage(none, "Name:      "$char.CharacterName, 'none');
      	TeamMessage(none, "Class:     "$char.CharacterClass, 'none');
      	TeamMessage(none, "Level:     "$char.level, 'none');
      	TeamMessage(none, "Health:    "$char.health$"/"$char.maxHealth, 'none');
      	TeamMessage(none, "Mana:      "$char.mana$"/"$char.maxMana, 'none');
      	TeamMessage(none, "Strength:  "$char.strength, 'none');
      	TeamMessage(none, "Dexterity: "$char.dexterity, 'none');
      	TeamMessage(none, "Magic:     "$char.magic, 'none');
      	TeamMessage(none, "Defense:   "$char.defense, 'none');
      	TeamMessage(none, "Inventory: "$char.inventory.length$" item(s)", 'none');
      	for (i = 0; i < char.inventory.Length; ++i)
      	{
      		TeamMessage(none, "+   Item:       "$char.inventory[i].item.DisplayName, 'none');
      		TeamMessage(none, "    Item level: "$char.inventory[i].level, 'none');
      		TeamMessage(none, "    Quality:    "$char.inventory[i].quality, 'none');
      		TeamMessage(none, "    Weight:     "$char.inventory[i].weight, 'none');
      		TeamMessage(none, "    Value:      "$char.inventory[i].value, 'none');
      	}
      }
      Does that mean with in a class, once char is assigned in a function it can be accessed from any other function, within the same class? (because it was declared outside all other functions).

      and if so, how would I keep the loaded charId through all classes globally to use?

      (Sorry if this is too off-topic from scaleform, I'll re-ask it at the unrealscript forum if it is.)

      Comment


        #18
        Code:
        var string CharName
        var GFxObject CharacterNameTextField
        
        // ill just skeep the get reference from flash code of the textField
        
        function AssignCharacterName()
        {
        local tfpplayercontroller PC;  // change with your player controller
        PC = tfpplayercontroller(GetPC());
        
        CharName = PC.char.CharacterName
        CharacterNameTextField.SetText(CharName);
        
        
        or you could just do
        
        characternametextfield.SetText(PC.char.CharacterName)
        }
        Thats it it should work with that

        Comment


          #19
          Accessed None for "char" means "char" does not exist when it is being called on. So you need to resolve why that is the case. Alvarofer0021 is on to something. I assume char is being created in your playercontroller. In that case, you need to cache a reference to your playercontroller in the GFx Movie Player class to be able to access "char". Something like:

          Code:
          var MyPlayerController PC;
          PC = MyPlayerController(GetPC());
          Then you can do:

          Code:
          PC.char

          Comment


            #20
            phasmatis:

            I can't see any issues with your code. The for iterator looks correct as well. I'd put a trace statement in the for iterator to see what's going on:

            Code:
            for (var i:Number = 0; i<8; i++) {
                trace(_root.ResInventory[i]); // should trace object Object in Flash
                trace(_root.ResInventory[i].ResourceName);
                trace(_root.ResInventory[i].Type);
                this["ResSlot"+i].data = _root.ResInventory[i];
            }
            That being said, if the ResInventory[] array is empty when this for loop is called, nothing will display. It is possible that the for loop executes before you populate the array from UnrealScript. You should probably add this for loop to a function, and call that function when you know the array has been populated.

            Comment


              #21
              Sorry to ask, but what function would GetPC() be refering to? Because all functions in the player controller that actually declare what char is require you pass a charID into them anyway.

              (Here is the loadCharacter function within Sapitu.uc, the other loadChar function is in my last post)
              Code:
              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;
              }

              Comment


                #22
                GetPC() is from \Development\Src\GFxUI\Classes\GFxMoviePlayer.uc. You use it in your class that extends GFxMoviePlayer to get a reference to the PlayerController.

                Code:
                event PlayerController GetPC()
                {
                	local LocalPlayer LocalPlayerOwner;
                	
                	LocalPlayerOwner = GetLP();
                	if (LocalPlayerOwner == none)
                	{
                		return none;
                	}
                	return LocalPlayerOwner.Actor;
                }

                Comment


                  #23
                  Thank you Matt Doyle, it works! I put the for loop in a function like you suggested as it made sense that it was being called before the array was populated, though I did have trouble executing the function until I added the full path "ActionScriptVoid("_root.MainPanel.Inventory.popul ateSlots");".

                  Thanks again!

                  Comment


                    #24
                    Yay, I got it working! Thanks so much for all your help! If I have anymroe questions about the inventory I'll come back to this thread.

                    Thanks again!

                    Comment


                      #25
                      Another question if that's okay.

                      Using InventorySlot.as, how would I find out what slot number I've dropped an item in? So once and item has been dropped in say, slot7, it updates a variable called selectedslot to 7 on the stage.

                      Edit:
                      and I'm going to be splitting the inventory out of the hud flash file and seperating it into it's own. Will this be hard?/recommended

                      Comment


                        #26
                        I've successfully managed to seperate the hud and inventory videos by closing them and starting them in unrealscript.

                        But for the InventorySlot.as thing, I still can't figure out how to get the slot number an item has been dropped into. Is there a command to get the instances name or something?

                        Edit:
                        For those who ever have the same issue as me, I just passed the index number into the slot movieclip as the slotnumber(because it is the slot number). There is probably a better way but this is the only way I could figure out how to do it.

                        Comment

                        Working...
                        X