public void ArmorHandler(object o)
 {
     try
     {
         var message = o as byte[];
         if (message == null)
         {
             return;
         }
         var armorCompatDefArray = MyAPIGateway.Utilities.SerializeFromBinary <ArmorCompatibilityDef[]>(message);
         if (armorCompatDefArray != null)
         {
             foreach (var armorDef in armorCompatDefArray)
             {
                 if (armorDef.Kind == ArmorCompatibilityDef.ArmorType.Heavy)
                 {
                     CustomArmorSubtypes.Add(MyStringHash.GetOrCompute(armorDef.SubtypeId));
                     CustomHeavyArmorSubtypes.Add(MyStringHash.GetOrCompute(armorDef.SubtypeId));
                 }
                 else if (armorDef.Kind == ArmorCompatibilityDef.ArmorType.Light)
                 {
                     CustomArmorSubtypes.Add(MyStringHash.GetOrCompute(armorDef.SubtypeId));
                 }
             }
         }
     }
     catch (Exception ex) { MyLog.Default.WriteLine($"Exception in ArmorHandler: {ex}"); }
 }
Beispiel #2
0
        private void ComputeEffects(MyCubeGrid grid, AmmoDef ammoDef, float damagePool, ref float healthPool, long attackerId, int sysmteId, List <IMySlimBlock> blocks)
        {
            var largeGrid = grid.GridSizeEnum == MyCubeSize.Large;
            var eWarInfo  = ammoDef.AreaEffect.EwarFields;
            var duration  = (uint)eWarInfo.Duration;
            var stack     = eWarInfo.StackDuration;
            var maxStack  = eWarInfo.MaxStacks;
            var nextTick  = Tick + 1;
            var maxTick   = stack ? (uint)(nextTick + (duration * maxStack)) : nextTick + duration;
            var fieldType = ammoDef.AreaEffect.AreaEffect;
            var sync      = MpActive && (DedicatedServer || IsServer);

            foreach (var block in blocks)
            {
                var cubeBlock = block.FatBlock as MyCubeBlock;
                if (damagePool <= 0 || healthPool <= 0)
                {
                    break;
                }

                IMyFunctionalBlock funcBlock = null;
                if (fieldType != DotField)
                {
                    if (cubeBlock == null || cubeBlock.MarkedForClose)
                    {
                        continue;
                    }

                    funcBlock = cubeBlock as IMyFunctionalBlock;
                    var isConveyor = cubeBlock is MyConveyor;
                    var ewared     = EffectedCubes.ContainsKey(cubeBlock.EntityId);

                    if (funcBlock == null || isConveyor || !cubeBlock.IsWorking && !ewared || ewared && !stack)
                    {
                        continue;
                    }
                }

                var   blockHp       = block.Integrity;
                float damageScale   = 1;
                var   tmpDamagePool = damagePool;
                if (ammoDef.Const.DamageScaling)
                {
                    var d = ammoDef.DamageScales;
                    if (d.MaxIntegrity > 0 && blockHp > d.MaxIntegrity)
                    {
                        continue;
                    }

                    if (d.Grids.Large >= 0 && largeGrid)
                    {
                        damageScale *= d.Grids.Large;
                    }
                    else if (d.Grids.Small >= 0 && !largeGrid)
                    {
                        damageScale *= d.Grids.Small;
                    }

                    MyDefinitionBase blockDef = null;
                    if (ammoDef.Const.ArmorScaling)
                    {
                        blockDef = block.BlockDefinition;
                        var isArmor = AllArmorBaseDefinitions.Contains(blockDef) || CustomArmorSubtypes.Contains(blockDef.Id.SubtypeId);
                        if (isArmor && d.Armor.Armor >= 0)
                        {
                            damageScale *= d.Armor.Armor;
                        }
                        else if (!isArmor && d.Armor.NonArmor >= 0)
                        {
                            damageScale *= d.Armor.NonArmor;
                        }

                        if (isArmor && (d.Armor.Light >= 0 || d.Armor.Heavy >= 0))
                        {
                            var isHeavy = HeavyArmorBaseDefinitions.Contains(blockDef) || CustomHeavyArmorSubtypes.Contains(blockDef.Id.SubtypeId);
                            if (isHeavy && d.Armor.Heavy >= 0)
                            {
                                damageScale *= d.Armor.Heavy;
                            }
                            else if (!isHeavy && d.Armor.Light >= 0)
                            {
                                damageScale *= d.Armor.Light;
                            }
                        }
                    }
                    if (ammoDef.Const.CustomDamageScales)
                    {
                        if (blockDef == null)
                        {
                            blockDef = block.BlockDefinition;
                        }
                        float modifier;
                        var   found = ammoDef.Const.CustomBlockDefinitionBasesToScales.TryGetValue(blockDef, out modifier);

                        if (found)
                        {
                            damageScale *= modifier;
                        }
                        else if (ammoDef.DamageScales.Custom.IgnoreAllOthers)
                        {
                            continue;
                        }
                    }
                }

                var scaledDamage = tmpDamagePool * damageScale;

                var blockDisabled = false;
                if (scaledDamage <= blockHp)
                {
                    tmpDamagePool = 0;
                }
                else
                {
                    blockDisabled  = true;
                    tmpDamagePool -= blockHp;
                }

                if (fieldType == DotField && IsServer)
                {
                    block.DoDamage(scaledDamage, MyDamageType.Explosion, sync, null, attackerId);
                    continue;
                }

                if (funcBlock != null)
                {
                    BlockState blockState;
                    var        cubeId = cubeBlock.EntityId;
                    if (EffectedCubes.TryGetValue(cubeId, out blockState))
                    {
                        if (blockState.Health > 0)
                        {
                            damagePool = tmpDamagePool;
                        }
                        if (!blockDisabled && blockState.Health - scaledDamage > 0)
                        {
                            blockState.Health -= scaledDamage;
                            blockState.Endtick = Tick + (duration + 1);
                        }
                        else if (blockState.Endtick + (duration + 1) < maxTick)
                        {
                            blockState.Health   = 0;
                            healthPool         -= 1;
                            blockState.Endtick += (duration + 1);
                        }
                        else
                        {
                            blockState.Health  = 0;
                            healthPool        -= 1;
                            blockState.Endtick = maxTick;
                        }
                    }
                    else
                    {
                        damagePool            = tmpDamagePool;
                        blockState.FunctBlock = funcBlock;
                        var originState = blockState.FunctBlock.Enabled;
                        blockState.FirstTick  = Tick + 1;
                        blockState.FirstState = originState;
                        blockState.NextTick   = nextTick;
                        blockState.Endtick    = Tick + (duration + 1);
                        blockState.Session    = this;
                        blockState.AmmoDef    = ammoDef;
                        blockState.SystemId   = sysmteId;
                        if (!blockDisabled)
                        {
                            blockState.Health = blockHp - scaledDamage;
                        }
                        else
                        {
                            blockState.Health = 0;
                        }
                    }
                    EffectedCubes[cubeId] = blockState;
                }
            }

            if (!IsServer)
            {
                EffectedCubes.Clear();
            }
        }