#I want to limit all grenade launcher

1 messages ยท Page 1 of 1 (latest)

final dragon
#

Lets move this conversation here so we don't spam the main chanel

mild widget
#

Oh yeah, sorry :x

final dragon
#
modded class SCR_InventoryStorageManagerComponent
{
    ref array<IEntity> m_myArray = new ref array<IEntity>();
    
    //------------------------------------------------------------------------------------------------
    override protected void OnItemAdded(BaseInventoryStorageComponent storageOwner, IEntity item)
    {        
        super.OnItemAdded(storageOwner, item);
        
        if(item.GetPrefabData().GetPrefabName() == "<myPyRestrictionPrefab>")
            m_myArray.Insert(item);        
    }

    //------------------------------------------------------------------------------------------------
    override protected void OnItemRemoved(BaseInventoryStorageComponent storageOwner, IEntity item)
    {
        super.OnItemRemoved(storageOwner, item);
        
        if(m_myArray.Find(item)>=0)
            m_myArray.Remove(item);
    }    
    
};
#

then you will be hable to get the "<myPyRestrictionPrefab>".

#

Then somewhere in SCR_InventoryStorageManagerComponent --> Get GameMode entity --> Find your component --> Get the config list

mild widget
#

What do you mean by prefabs and max are seated ?

#

To know how much is max and which prefab are considered limited ?

final dragon
#

This is a custom config file i made

#
[BaseContainerProps(configRoot:true)]
class ARU_ArsenalConfig
{
    [Attribute("ARSENAL 01", desc: "Arsenal Name")]
    protected string m_sDisplayName;
    
    [Attribute(desc: "Editor actions")]
    protected ref array<ref ARU_Arsenal_CategoryList> m_categoriesList;

    //------------------------------------------------------------------------------------------------
    string GetDisplayName()
    {
        return m_sDisplayName;
    }    
    
    //------------------------------------------------------------------------------------------------
    array<ARU_Arsenal_Category> GetCategoryByTypename(typename catListToFind)
    {
        array<ARU_Arsenal_Category> categoriesArray = {};
        foreach(ARU_Arsenal_CategoryList catList : m_categoriesList)
        {
            if(catList.Type() == catListToFind)
            {
                array<ref ARU_Arsenal_Category> catArray = catList.GetCategoryList();
                foreach(ARU_Arsenal_Category cat : catArray)        
                    categoriesArray.Insert(cat);                
                return categoriesArray;                
            }
        }
        return categoriesArray;
    }
}
mild widget
#

Ohw, i didn't knew i needed this. I thought just by only making my script it would work

final dragon
#

Search for BaseContainerProps in script editor and you will se some examples

#

you need to make it some way that is "flexible and easy to use"

mild widget
#

Oh ok i see

#

Hmm.. I don't find anything by the name BaseContainerProps

final dragon
#

Are you searching here?

mild widget
#

Oh ok, i thought it was a file

final dragon
#

this and ricghtclick GoTo Declaration are the most used stuff in workbench XD

mild widget
#

Yeah i'm used to PHPStorm so it ctrl+click :p

#

So if i get this right
I should write some declaration/attribute at the beginning of my class like this

[BaseContainerProps()]
    class MyObjectSpecial: MyObject
    {
        [Attribute("1.2", UIWidgets.EditBox)]
        float Prop4;

        [Attribute("", UIWidgets.Object)]
        ref MyObject Prop5;
    }

The compilation will render a conf file ?

final dragon
#

For step 2 on how to make components, serach for classes using : ScriptComponent

final dragon
mild widget
#

Ok i got the ScriptComponent

final dragon
#

in the component you must have some attribute like these

    [Attribute()]
    protected ref MyObjectSpecial m_myConfig;
#

Then once compiled, you must go to:

  • {0F307326459A1395}Prefabs/MP/Modes/GameMode_Base.et
  • RightClick override in "Addon"
#

It will create the same folder path and prefab

#

open this new prefab and Add your component

final dragon
mild widget
#

Ok, i'll take a look step by step. It's my first time scripting ever (on software) so i'm a bit lost TBH ๐Ÿ˜†

#

Btw thanks a lot

final dragon
#

your are welcome

mild widget
#

Nevermind ahah

#

Just found it

#

I'm sorry but i don't really know what to put in my config file
I don't see how i can tell him i want max 3 of those :

  • Ammo_Grenade_HE_VOG25
  • Ammo_Grenade_HE_M406
  • Ammo_Grenade_HEDP_M433
mild widget
final dragon
#

you will need something similar to this, only missing the quantity attribute

[BaseContainerProps(),SCR_BaseContainerCustomTitleResourceName("m_Prefab", true)]
class ARU_Arsenal_Items
{
    [Attribute("", desc: "Item name shown in UI. (if not set the item name will be used)")]
    protected string m_sDisplayName;    
    
    [Attribute("", UIWidgets.ResourcePickerThumbnail, "", "et")]
    protected ResourceName m_Prefab;        
    
    //------------------------------------------------------------------------------------------------
    string GetDisplayName()
    {
        return m_sDisplayName;
    }
    
    //------------------------------------------------------------------------------------------------
    ResourceName GetItemResourceName()
    {
        return m_Prefab;
    }    
    
    //------------------------------------------------------------------------------------------------
    void SetItem(string displayName, ResourceName resourceName)
    {
        m_sDisplayName = displayName;
        m_Prefab = resourceName;
    }        
}
#

If you GoTo Declaration in UIWidgets you may find some useful properti for int's then you can search UIWidgets.TheIntIWant and get some example from vanilla game

mild widget
#

ok thanks i'll take a look for int

final dragon
#

SCR_BaseContainerCustomTitleResourceName("m_Prefab", true) this is only to dsiplay some text in the config

#

Also, may be better for you to find in world editor some example and serach inside it

#

This will get you to a Int example

final dragon
#

[Attribute(desc: "Editor actions")]
protected ref array<ref ARU_Arsenal_Items> m_categoriesList;

#
[BaseContainerProps()]
    class MyObjectSpecial: MyObject
    {
        [Attribute(desc: "Editor actions")]
    protected ref array<ref ARU_Arsenal_Items> m_categoriesList;
    }

[BaseContainerProps(),SCR_BaseContainerCustomTitleResourceName("m_Prefab", true)]
class ARU_Arsenal_Items
{
    [Attribute("", desc: "Item name shown in UI. (if not set the item name will be used)")]
    protected string m_sDisplayName;    
    
    [Attribute("", UIWidgets.ResourcePickerThumbnail, "", "et")]
    protected ResourceName m_Prefab;        
    
    //------------------------------------------------------------------------------------------------
    string GetDisplayName()
    {
        return m_sDisplayName;
    }
    
    //------------------------------------------------------------------------------------------------
    ResourceName GetItemResourceName()
    {
        return m_Prefab;
    }    
    
    //------------------------------------------------------------------------------------------------
    void SetItem(string displayName, ResourceName resourceName)
    {
        m_sDisplayName = displayName;
        m_Prefab = resourceName;
    }        
}
#

your file should look something like these

mild widget
#

[BaseContainerProps(),SCR_BaseContainerCustomTitleResourceName("m_Prefab", true)]

final dragon
#

yes it does

#

BaseContainerProps()

#

SCR_BaseContainerCustomTitleResourceName("m_Prefab", true) is optional

mild widget
#
[BaseContainerProps()]
modded class SCR_InventoryStorageManagerComponent : ScriptedInventoryStorageManagerComponent

I can't find it :/

mild widget
#

I've modded existing

#

IDK if it's the right way though ?

final dragon
#

[BaseContainerProps()] This is only for the config part not related to this

#

You must create a config file from MyObjectSpecial

#

only one file for now

mild widget
#

Oh ok

#
[BaseContainerProps()]
class MyObjectSpecial
{
    [Attribute(desc: "Editor actions")]
    protected ref array<IEntity> m_categoriesList;
}
#

Like this i guess

final dragon
#

Yes

mild widget
#

And i should find it by the name MyObjectSpecial in the "Choose a class" step of creating a conf file ?

final dragon
#

Also i forget to tell you something. You should have a personal TAG, for example i have SPK (form y personal stuff, Spyke) and ARU (form y mod stuff)

mild widget
#

Ok so it should be LEW_MyObjectSpecial i guess

final dragon
#

yes

#

you need to check if it already exist here

mild widget
#

Nope, no match

final dragon
#

tehn you can register yours there and use it

final dragon
#

you need to compile again Shift+F7
Validate/verify code + Compile --> Shift+F7
Validate/verify code --> F7

mild widget
#
[BaseContainerProps()]
class LEW_MyObjectSpecial
{
    [Attribute(desc: "Editor actions")]
    protected ref array<IEntity> m_categoriesList;
}
#

Stille nothing, that's strange

#

Does it need to be related to my file name ?

#

Don't mind the project name i'll change it later as i could configure it better with your help

#

Made it work, i'll work in the next step a bit later !
If i've got some more question i'll tag you in this thread

Thanks a lot for the time and help โ™ฅ

final dragon
#
[BaseContainerProps()]
class LEW_MyObjectSpeciallList: MyObject
{
  [Attribute(desc: "List")]
  protected ref array<ref LEW_MyObjectSpeciall> m_myObjectList;
}

//Down here your current LEW_MyObjectSpeciall definition
//...
mild widget
#

Oh ok, i get it know

final dragon
#

you should create the config file only from LEW_MyObjectSpeciallList

mild widget
#

One object for the list/array
The other one for association prefab/maxNumber

final dragon
#

don't remove the [BaseContainerProps()] from the other one thou, as it is needed

mild widget
#

Like this

#

To be better, instead of choosing only one prefab, i should have X prefab. Sadly i don't want US player to have an advantage with 2x3 Grenade

final dragon
#

put this in LEW_MyObjectSpeciall now ๐Ÿ˜‰ [BaseContainerProps(),SCR_BaseContainerCustomTitleResourceName("m_Prefab", true)]

#

This will make the prefab name to be shown here

keen oyster
#

@mild widget Everything you need ^^ except i modded SCR_UniversalInventoryStorageComponent

mild widget
#

Thanks a lot @keen oyster I'll base some of my code on this and also Spyke explanation to go further
I liked the idea that Spike said that i've got 1 file managing all my limitation

keen oyster
#

@mild widget If you need me to alter it for config use I can.

#

I literally wrote that specifically for you to use as an example

mild widget
mild widget
#

Hi !
I'm getting back at it

I'm wondering why m_myObjectArrays looks like it's empty. It should be contained all my configs

am i missing something with my config import ?

#
//[BaseContainerProps(configRoot: true, SCR_BaseContainerCustomTitleResourceName("m_Prefab", true))]
[BaseContainerProps(),SCR_BaseContainerCustomTitleResourceName("m_Prefab", true)]
class LEW_MyObjectSpecial
{
    
    [Attribute("", UIWidgets.ResourcePickerThumbnail, "", "et")]
    protected ResourceName m_Prefab;    
            
    [Attribute(desc: "Max number of item")]
    protected int m_maxItemNb;

    string GetPrefabName()
        return m_Prefab;
    
    int GetMaxQuantity()
        return m_maxItemNb;
    
}

[BaseContainerProps(configRoot: true)]
class LEW_MyObjectSpecialList
{
    
    [Attribute(desc: "List")]
    protected ref array<ref LEW_MyObjectSpecial> m_myObjectList;
    
    array<ref LEW_MyObjectSpecial> GetList()
        return m_myObjectList;

}
modded class SCR_InventoryStorageManagerComponent : ScriptedInventoryStorageManagerComponent
{

    [Attribute(desc: "List")]
    protected ref array<ref LEW_MyObjectSpecialList> m_myObjectArrays;
[.......]

    //------------------------------------------------------------------------------------------------
    override protected void OnItemAdded(BaseInventoryStorageComponent storageOwner, IEntity item)
    {        
        super.OnItemAdded(storageOwner, item);
        Print("On item added");
        
        Print(m_myObjectArrays.GetRefCount());
        
        foreach(LEW_MyObjectSpecialList object : m_myObjectArrays)
        {
            Print("FOREACH");
            array<ref LEW_MyObjectSpecial> objsRestricted = object.GetList();
            
            foreach(LEW_MyObjectSpecial objRestricted : objsRestricted)
            {
                if(objRestricted.GetPrefabName() == item.GetPrefabData().GetPrefabName())
                {
                    
                    Print("Item detecte");
                    Print(item.GetPrefabData().GetPrefabName());
                }
            }
            
            
            
        }
        
    }

#

@final dragon @keen oyster

final dragon
#

And then the foreach to this

        foreach(LEW_MyObjectSpecial object : m_myConfig.GetList())
        {
          if(object.GetPrefabName() == item.GetPrefabData().GetPrefabName())
          {
              
              Print("Item detecte");
              Print(item.GetPrefabData().GetPrefabName());
          }
        }
#

After this you need to compile and drag and drop your created config file into the component property

mild widget
#

Ok thanks i'll try it out

final dragon
#

Also in the future it may be better to store m_myConfig in Game mode. Creating a Component and adding it in GameMode base prefab instead (especially if the restriction is going to apply to all players).

mild widget
final dragon
#

yes

mild widget
#

Ok thanks, and i should create a new file or just write attributes in the overrided class i've made ?

mild widget
# final dragon yes

I've tried to make this in a new file:

[EntityEditorProps(category: "GameScripted/Campaign", description: "Help with import config")]
class LEW_ConfigComponentClass : ScriptComponentClass
{
};

//------------------------------------------------------------------------------------------------
class LEW_ConfigComponent : ScriptComponent
{

    
    [Attribute()] 
    protected ref MyObjectSpecial m_myConfig;
};

But i can't see it in the "Add component" on my world editor on GameMode_base.et overrided. Do you have any idea why ?

mild widget
#

Yes

final dragon
#

Try again you should find it, where did you create that file?

#

always follow the vanilla game folder structure

mild widget
#

I've tried to replicate what it's in SCR_CampaignServiceEntityComponent
Ohw, maybe that's my path

final dragon
#

scripts placed outside scripts/game/XXX will not compile

mild widget
#

That's why

final dragon
#

The best way to create files is to go to a similar one in vanilla, duplicate it, workbench will generate the folder path automatically if not created and then rename it to your functionality

#

or atleast this is the way i do it

mild widget
#

Yeah i've moved it to scripts/game and it compiled with error, i'll debug it
I'm afraid that by doing this i'll have a file in a path that it doesn't belong like a script for inventory in weapons folder per example

#

Worked like a charm, i'll test it

final dragon
#

๐Ÿ‘

mild widget
# final dragon ๐Ÿ‘

So i don't know if it's the best way to test it but:

  • I added the component to GameMode_Base
  • I loaded MPTest and duplicate it
  • I added my GameMode override like in my screen

And then i've got nothing (null) in my m_myObjectArrays:

[BaseContainerProps(),SCR_BaseContainerCustomTitleResourceName("m_Prefab", true)]
class LEW_MyObjectSpecial
{
    
    [Attribute("", UIWidgets.ResourcePickerThumbnail, "", "et")]
    protected ResourceName m_Prefab;    
            
    [Attribute(desc: "Max number of item")]
    protected int m_maxItemNb;

    string GetPrefabName()
        return m_Prefab;
    
    int GetMaxQuantity()
        return m_maxItemNb;
    
}

[BaseContainerProps(configRoot: true)]
class LEW_MyObjectSpecialList
{
    
    [Attribute(desc: "List")]
    protected ref array<ref LEW_MyObjectSpecial> m_myObjectList;
    
    array<ref LEW_MyObjectSpecial> GetList()
        return m_myObjectList;

}
modded class SCR_InventoryStorageManagerComponent : ScriptedInventoryStorageManagerComponent
{

    [Attribute(desc: "List")]
    protected ref LEW_MyObjectSpecialList m_myObjectArrays;

    override protected void OnItemAdded(BaseInventoryStorageComponent storageOwner, IEntity item)
    {        
        super.OnItemAdded(storageOwner, item);
        
        Print("On item added");
        
        Print(m_myObjectArrays.ToString());
        //Print(m_myObjectArrays.GetList().ToString());
        //foreach(LEW_MyObjectSpecial object : m_myObjectArrays.GetList())
        //{
        //    Print("FOREACH");
        //    if(object.GetPrefabName() == item.GetPrefabData().GetPrefabName())
        //    {
        //        Print("Item detecte");
        //        Print(item.GetPrefabData().GetPrefabName());
        //    }
        //}
            
            
        
        
    }
}

I guess there is two option:

  • My conf import is not good on my component file
  • My way to test it is not good
    What do you think ?
final dragon
#

I added my GameMode override like in my screen

#

The map has already a GameMode, you don't need to add it

#

If you check that "GameMode_Plain1" you should have your component there as a result of overriding the GameMode_Base

mild widget
final dragon
#

After that:

  1. In your modded SCR_InventoryStorageManagerComponent PostInit: Get the current GameMode instance (GetGame().GetGameMode()).
  2. Then get the component from the game mode: BaseGameMode::FindComponent
  3. Get the config from the component
#
    override protected void OnPostInit(IEntity owner)
    {
        BaseGameMode gameMode = GetGame().GetGameMode();
        LEW_ConfigComponent comp = LEW_ConfigComponent.Cast(gameMode.FindComponent(LEW_ConfigComponent ));
        m_myConfig= comp.GetConfig();
    }
#
//------------------------------------------------------------------------------------------------
class LEW_ConfigComponent : ScriptComponent
{

    
    [Attribute()] 
    protected ref MyObjectSpecial m_myConfig;
    
    //------------------------------------------------------------------------------------------------
    void GetConfig()
    {
        return m_myConfig;
    }        
    
};
#

You need to add a get method in LEW_ConfigComponent in order to get the config

#

With all this OnItemAdded should print some config

mild widget
final dragon
#

ok, then put it on FillInitialPrefabsToStore

    override protected void FillInitialPrefabsToStore(out array<ResourceName> prefabsToSpawn)
    {
        super.FillInitialPrefabsToStore(prefabsToSpawn);
        BaseGameMode gameMode = GetGame().GetGameMode();
        LEW_ConfigComponent comp = LEW_ConfigComponent.Cast(gameMode.FindComponent(LEW_ConfigComponent ));
        m_myConfig= comp.GetConfig();
    }
#

i don't know if this will work

mild widget
#
    
    override protected void FillInitialPrefabsToStore(out array<ResourceName> prefabsToSpawn)
    {
        super.FillInitialPrefabsToStore(prefabsToSpawn);
        Print("INIT");
        
        BaseGameMode gameMode = GetGame().GetGameMode();
        LEW_ConfigComponent comp = LEW_ConfigComponent.Cast(gameMode.FindComponent(LEW_ConfigComponent ));
        m_myObjectArrays= comp.GetConfig();
        
        if(!m_myObjectArrays)
            Print("EMPTY");
    }
    [.....]
    override protected void OnItemAdded(BaseInventoryStorageComponent storageOwner, IEntity item)
    {        
        super.OnItemAdded(storageOwner, item);
        
        Print("On item added");
        
        Print(m_myObjectArrays.ToString());
        //Print(m_myObjectArrays.GetList().ToString());
        //foreach(LEW_MyObjectSpecial object : m_myObjectArrays.GetList())
        //{
        //    Print("FOREACH");
        //    if(object.GetPrefabName() == item.GetPrefabData().GetPrefabName())
        //    {
        //        Print("Item detecte");
        //        Print(item.GetPrefabData().GetPrefabName());
        //    }
        //}
            
            
        
        
    }
final dragon
# mild widget ``` override protected void FillInitialPrefabsToStore(out array<Resourc...

ok then do it like these:

    override protected void OnItemAdded(BaseInventoryStorageComponent storageOwner, IEntity item)
    {        
        super.OnItemAdded(storageOwner, item);
        
        if(!m_myConfig)
        {
          BaseGameMode gameMode = GetGame().GetGameMode();
          if(!gameMode)
            return;
          LEW_ConfigComponent comp = LEW_ConfigComponent.Cast(gameMode.FindComponent(LEW_ConfigComponent));
          if(!comp)
            return;
          m_myConfig= comp.GetConfig();
          if(!m_myConfig)
            return;
        }

        Print("On item added");
        Print(m_myObjectArrays.ToString());
        //Print(m_myObjectArrays.GetList().ToString());
        //foreach(LEW_MyObjectSpecial object : m_myObjectArrays.GetList())
        //{
        //    Print("FOREACH");
        //    if(object.GetPrefabName() == item.GetPrefabData().GetPrefabName())
        //    {
        //        Print("Item detecte");
        //        Print(item.GetPrefabData().GetPrefabName());
        //    }
        //}
    }
#

delete FillInitialPrefabsToStore

#

I udpated it adding some verifications