Problem when using TryAddModule
Hey guys, just signed up to create this thread! Hopefully created it to right category.

I'm developing plugin that makes your rust server racing server with modular cars. This is how I'm spawning vehicle with defined modules;
var entity = GameManager.server.CreateEntity("assets/content/vehicles/modularcar/car_chassis_2module.entity.prefab", spawnPosition, rotation);
var modularCar = entity as ModularCar;
var moduleItem = ItemManager.CreateByItemID(-1501451746);
modularCar.TryAddModule(moduleItem, 0);
moduleItem = ItemManager.CreateByItemID(1559779253);
modularCar.TryAddModule(moduleItem, 1);​

However, I'm having problem when I try insert components in the engine module.. I don't know how to get right container to be added items. Also, if I do this after the code;

modularCar.HasAnyModules;

It returns false.

When I run the code, car with cockpit module and engine module spawns. I am able to mount and drive it if I insert components manually.. Is this right way to add modules to vehicles?

I am very new to C#, but I have some experience on other languages. I have studied at least this and this, and those plugins have helped me a lot. On the "Car Spawn Settings" -plugin there is this code;

 private void MaybeAddEngineParts(ModularCar car)
        {
            if (!pluginConfig.CanHaveEngineParts()) return;

            foreach (var module in car.AttachedModuleEntities)
            {
                var engineModule = module as VehicleModuleEngine;
                if (engineModule != null)
                {
                    var engineStorage = engineModule.GetContainer() as EngineStorage;
                    if (engineStorage != null)
                    {
                        AddPartsToEngineStorage(engineStorage);
                        engineModule.RefreshPerformanceStats(engineStorage);
                    }
                }
            }
        }

        private void AddPartsToEngineStorage(EngineStorage engineStorage)
        {
            if (engineStorage.inventory == null) return;

            var inventory = engineStorage.inventory;
            for (var i = 0; i < inventory.capacity; i++)
            {
                // Do nothing if there is an existing engine part
                var item = inventory.GetSlot(i);
                if (item != null) continue;

                var tier = pluginConfig.GetPossiblyRandomEnginePartTier();
                if (tier > 0)
                    TryAddEngineItem(engineStorage, i, tier);
            }
        }

        private bool TryAddEngineItem(EngineStorage engineStorage, int slot, int tier)
        {
            ItemModEngineItem output;
            if (!engineStorage.allEngineItems.TryGetItem(tier, engineStorage.slotTypes[slot], out output)) return false;

            var component = output.GetComponent<ItemDefinition>();
            var item = ItemManager.Create(component);
            if (item == null) return false;
            
            item.conditionNormalized = pluginConfig.GetRandomNormalizedPartCondition();
            item.MoveToContainer(engineStorage.inventory, slot, allowStack: false);
            return true;
        }

I just can't use "GetContainer" for some reason.

Thank you if you read this far and hopefully you could help me!

-tyse

I'm guessing you are having the issue where adding the module item to the car inventory doesn't create the module entity immediately. The game uses the following code for that.

public override void OnChildAdded(BaseEntity childEntity)
{
    BaseVehicleModule module;
    if ((object)(module = (childEntity as BaseVehicleModule)) != null)
    {
        Action action = delegate
        {
            ModuleEntityAdded(module);
        };
        moduleAddActions[module] = action;
        module.Invoke(action, 0f);
    }
}​

 

To address this, I was originally using NextTick() but that did not work in all cases. I recently updated Car Spawn Settings to use Invoke like the following example.

var entity = GameManager.server.CreateEntity("assets/content/vehicles/modularcar/car_chassis_2module.entity.prefab", spawnPosition, rotation);
var modularCar = entity as ModularCar;
var moduleItem = ItemManager.CreateByItemID(-1501451746);
modularCar.TryAddModule(moduleItem, 0);
moduleItem = ItemManager.CreateByItemID(1559779253);
modularCar.TryAddModule(moduleItem, 1);

modularCar.Invoke(() =>
{
  if (modularCar == null)
    return;

  foreach (var module in modularCar.attachedModuleEntities)
  {
    var engineModule = module as VehicleModuleEngine;
    if (engineModule == null)
      continue;

    var container = engineModule.GetContainer() as EngineStorage;
    if (container == null)
      continue;

    // Add engine parts to container here
  }
}, 0);
​
5f1792699e67b.jpg WhiteThunder
Code and stuff

Huge thanks to you! Problems are solved and development continues :) If somebody else is having same issue and is using code above, you have to replace .attachedModuleEntities with .AttachedModuleEntities.