private static IEnumerable <TStatementSyntax> GetCreateAllUnitsHelperFunctionStatements(TBuilder builder)
        {
            var mapInfo = builder.Data.MapInfo;

            foreach (var unit in builder.Data.MapUnits.Where(mapUnit => mapUnit.IsUnit))
            {
                var globalUnitVariableName = $"gg_unit_{unit.TypeId}_{unit.CreationNumber:D4}";

                if (unit.IsRandomUnit)
                {
                    var randomData = unit.RandomData;
                    switch (randomData.Mode)
                    {
                    case 0:
                        if (unit.IsRandomBuilding)
                        {
                            yield return(builder.GenerateAssignmentStatement(
                                             LocalUnitIdVariableName,
                                             builder.GenerateInvocationExpression(
                                                 nameof(War3Api.Common.ChooseRandomNPBuilding))));
                        }
                        else
                        {
                            yield return(builder.GenerateAssignmentStatement(
                                             LocalUnitIdVariableName,
                                             builder.GenerateInvocationExpression(
                                                 nameof(War3Api.Common.ChooseRandomCreep),
                                                 builder.GenerateIntegerLiteralExpression(randomData.Level))));
                        }

                        break;

                    case 1:
                        yield return(builder.GenerateAssignmentStatement(
                                         LocalUnitIdVariableName,
                                         builder.GenerateArrayReferenceExpression(
                                             $"gg_rg_{randomData.UnitGroupTableIndex:D3}",
                                             builder.GenerateIntegerLiteralExpression(randomData.UnitGroupTableColumn))));

                        break;

                    case 2:
                        yield return(builder.GenerateInvocationStatement(nameof(War3Api.Blizzard.RandomDistReset)));

                        var summedChance = 0;
                        foreach (var randomUnitOption in randomData)
                        {
                            summedChance += randomUnitOption.chance;

                            var unitTypeExpression = RandomUnitProvider.IsRandomUnit(randomUnitOption.id, out var level)
                                    ? builder.GenerateInvocationExpression(
                                nameof(War3Api.Common.ChooseRandomCreep),
                                builder.GenerateIntegerLiteralExpression(level))
                                    : builder.GenerateFourCCExpression(new string(randomUnitOption.id));

                            yield return(builder.GenerateInvocationStatement(
                                             nameof(War3Api.Blizzard.RandomDistAddItem),
                                             unitTypeExpression,
                                             builder.GenerateIntegerLiteralExpression(randomUnitOption.chance)));
                        }

                        if (summedChance < 100)
                        {
                            yield return(builder.GenerateInvocationStatement(
                                             nameof(War3Api.Blizzard.RandomDistAddItem),
                                             builder.GenerateIntegerLiteralExpression(-1),
                                             builder.GenerateIntegerLiteralExpression(100 - summedChance)));
                        }

                        yield return(builder.GenerateAssignmentStatement(
                                         LocalUnitIdVariableName,
                                         builder.GenerateInvocationExpression(nameof(War3Api.Blizzard.RandomDistChoose))));

                        break;
                    }

                    yield return(builder.GenerateIfStatement(
                                     builder.GenerateBinaryExpression(
                                         BinaryOperator.NotEquals,
                                         builder.GenerateVariableExpression(LocalUnitIdVariableName),
                                         builder.GenerateIntegerLiteralExpression(-1)),
                                     builder.GenerateAssignmentStatement(
                                         globalUnitVariableName,
                                         builder.GenerateInvocationExpression(
                                             nameof(War3Api.Common.CreateUnit),
                                             builder.GenerateInvocationExpression(
                                                 nameof(War3Api.Common.Player),
                                                 builder.GenerateIntegerLiteralExpression(unit.Owner)),
                                             builder.GenerateVariableExpression(LocalUnitIdVariableName),
                                             builder.GenerateFloatLiteralExpression(unit.PositionX),
                                             builder.GenerateFloatLiteralExpression(unit.PositionY),
                                             builder.GenerateFloatLiteralExpression(unit.FacingDeg)))));
                }
                else
                {
                    var args = new List <TExpressionSyntax>()
                    {
                        builder.GenerateInvocationExpression(
                            nameof(War3Api.Common.Player),
                            builder.GenerateIntegerLiteralExpression(unit.Owner)),
                        builder.GenerateFourCCExpression(unit.TypeId),
                        builder.GenerateFloatLiteralExpression(unit.PositionX),
                        builder.GenerateFloatLiteralExpression(unit.PositionY),
                        builder.GenerateFloatLiteralExpression(unit.FacingDeg),
                    };

                    var hasSkin = (unit.Skin?.Length ?? 0) == 4 && unit.Skin != unit.TypeId;
                    if (hasSkin)
                    {
                        args.Add(builder.GenerateFourCCExpression(unit.Skin));
                    }

                    yield return(builder.GenerateAssignmentStatement(
                                     globalUnitVariableName,
                                     builder.GenerateInvocationExpression(
                                         hasSkin
                                ? nameof(War3Api.Common.BlzCreateUnitWithSkin)
                                : nameof(War3Api.Common.CreateUnit),
                                         args.ToArray())));

                    if (unit.HeroLevel > 1)
                    {
                        yield return(builder.GenerateInvocationStatement(
                                         nameof(War3Api.Common.SetHeroLevel),
                                         builder.GenerateVariableExpression(globalUnitVariableName),
                                         builder.GenerateIntegerLiteralExpression(unit.HeroLevel),
                                         builder.GenerateBooleanLiteralExpression(false)));
                    }

                    if (unit.HeroStrength > 0)
                    {
                        yield return(builder.GenerateInvocationStatement(
                                         nameof(War3Api.Common.SetHeroStr),
                                         builder.GenerateVariableExpression(globalUnitVariableName),
                                         builder.GenerateIntegerLiteralExpression(unit.HeroStrength),
                                         builder.GenerateBooleanLiteralExpression(true)));
                    }

                    if (unit.HeroAgility > 0)
                    {
                        yield return(builder.GenerateInvocationStatement(
                                         nameof(War3Api.Common.SetHeroAgi),
                                         builder.GenerateVariableExpression(globalUnitVariableName),
                                         builder.GenerateIntegerLiteralExpression(unit.HeroAgility),
                                         builder.GenerateBooleanLiteralExpression(true)));
                    }

                    if (unit.HeroIntelligence > 0)
                    {
                        yield return(builder.GenerateInvocationStatement(
                                         nameof(War3Api.Common.SetHeroInt),
                                         builder.GenerateVariableExpression(globalUnitVariableName),
                                         builder.GenerateIntegerLiteralExpression(unit.HeroIntelligence),
                                         builder.GenerateBooleanLiteralExpression(true)));
                    }
                }

                if (unit.Hp != -1)
                {
                    yield return(builder.GenerateInvocationStatement(
                                     nameof(War3Api.Common.SetUnitState),
                                     builder.GenerateVariableExpression(globalUnitVariableName),
                                     builder.GenerateVariableExpression(nameof(War3Api.Common.UNIT_STATE_LIFE)),
                                     builder.GenerateBinaryExpression(
                                         BinaryOperator.Multiplication,
                                         builder.GenerateFloatLiteralExpression(unit.Hp * 0.01f),
                                         builder.GenerateInvocationExpression(
                                             nameof(War3Api.Common.GetUnitState),
                                             builder.GenerateVariableExpression(globalUnitVariableName),
                                             builder.GenerateVariableExpression(nameof(War3Api.Common.UNIT_STATE_LIFE))))));
                }

                if (unit.Mp != -1)
                {
                    yield return(builder.GenerateInvocationStatement(
                                     nameof(War3Api.Common.SetUnitState),
                                     builder.GenerateVariableExpression(globalUnitVariableName),
                                     builder.GenerateVariableExpression(nameof(War3Api.Common.UNIT_STATE_MANA)),
                                     builder.GenerateFloatLiteralExpression(unit.Mp)));
                }

                if (unit.TypeId == "ngol")
                {
                    yield return(builder.GenerateInvocationStatement(
                                     nameof(War3Api.Common.SetResourceAmount),
                                     builder.GenerateVariableExpression(globalUnitVariableName),
                                     builder.GenerateIntegerLiteralExpression(unit.GoldAmount)));
                }

                if (unit.TargetAcquisition != -1)
                {
                    const float CampAcquisitionRange = 200f;
                    yield return(builder.GenerateInvocationStatement(
                                     nameof(War3Api.Common.SetUnitAcquireRange),
                                     builder.GenerateVariableExpression(globalUnitVariableName),
                                     builder.GenerateFloatLiteralExpression(unit.TargetAcquisition == -2 ? CampAcquisitionRange : unit.TargetAcquisition)));
                }

                if (unit.CustomPlayerColor != -1)
                {
                    yield return(builder.GenerateInvocationStatement(
                                     nameof(War3Api.Common.SetUnitColor),
                                     builder.GenerateVariableExpression(globalUnitVariableName),
                                     builder.GenerateInvocationExpression(
                                         nameof(War3Api.Common.ConvertPlayerColor),
                                         builder.GenerateIntegerLiteralExpression(unit.CustomPlayerColor))));
                }

                if (unit.WaygateDestination != -1)
                {
                    var targetRect = builder.Data.MapRegions?.Where(region => region.CreationNumber == unit.WaygateDestination).SingleOrDefault();
                    var targetX    = targetRect?.CenterX ?? 0;
                    var targetY    = targetRect?.CenterY ?? 0;
                    yield return(builder.GenerateInvocationStatement(
                                     nameof(War3Api.Common.WaygateSetDestination),
                                     builder.GenerateVariableExpression(globalUnitVariableName),
                                     builder.GenerateFloatLiteralExpression(targetX),
                                     builder.GenerateFloatLiteralExpression(targetY)));

                    yield return(builder.GenerateInvocationStatement(
                                     nameof(War3Api.Common.WaygateActivate),
                                     builder.GenerateVariableExpression(globalUnitVariableName),
                                     builder.GenerateBooleanLiteralExpression(true)));
                }

                foreach (var ability in unit.AbilityData)
                {
                    for (var i = 0; i < ability.Level; i++)
                    {
                        // TODO: make sure Level is 0 for non-hero abilities (can confirm this by checking second char is uppercase?)
                        yield return(builder.GenerateInvocationStatement(
                                         nameof(War3Api.Common.SelectHeroSkill),
                                         builder.GenerateVariableExpression(globalUnitVariableName),
                                         builder.GenerateFourCCExpression(ability.Id)));
                    }

                    if (ability.IsActive)
                    {
#if false
                        yield return(builder.GenerateInvocationStatement(
                                         nameof(War3Api.Common.IssueImmediateOrder),
                                         builder.GenerateVariableExpression(LocalUnitVariableName),
                                         builder.GenerateStringLiteralExpression(ability.OrderString)));
#else
                        // TODO: test if this works
                        yield return(builder.GenerateInvocationStatement(
                                         nameof(War3Api.Common.IssueImmediateOrderById),
                                         builder.GenerateVariableExpression(globalUnitVariableName),
                                         builder.GenerateFourCCExpression(ability.Id)));
#endif
                    }
                }

                foreach (var item in unit.Inventory)
                {
                    yield return(builder.GenerateInvocationStatement(
                                     nameof(War3Api.Common.UnitAddItemToSlotById),
                                     builder.GenerateVariableExpression(globalUnitVariableName),
                                     builder.GenerateFourCCExpression(item.Id),
                                     builder.GenerateIntegerLiteralExpression(item.Slot)));
                }

                if (unit.MapItemTablePointer != -1 || unit.DroppedItemData.FirstOrDefault() != null)
                {
                    yield return(builder.GenerateAssignmentStatement(
                                     LocalTriggerVariableName,
                                     builder.GenerateInvocationExpression(nameof(War3Api.Common.CreateTrigger))));

                    yield return(builder.GenerateInvocationStatement(
                                     nameof(War3Api.Common.TriggerRegisterUnitEvent),
                                     builder.GenerateVariableExpression(LocalTriggerVariableName),
                                     builder.GenerateVariableExpression(globalUnitVariableName),
                                     builder.GenerateVariableExpression(nameof(War3Api.Common.EVENT_UNIT_DEATH))));

                    yield return(builder.GenerateInvocationStatement(
                                     nameof(War3Api.Common.TriggerRegisterUnitEvent),
                                     builder.GenerateVariableExpression(LocalTriggerVariableName),
                                     builder.GenerateVariableExpression(globalUnitVariableName),
                                     builder.GenerateVariableExpression(nameof(War3Api.Common.EVENT_UNIT_CHANGE_OWNER))));

                    if (unit.MapItemTablePointer != -1)
                    {
                        yield return(builder.GenerateInvocationStatement(
                                         nameof(War3Api.Common.TriggerAddAction),
                                         builder.GenerateVariableExpression(LocalTriggerVariableName),
                                         builder.GenerateFunctionReferenceExpression($"ItemTable{mapInfo.GetItemTable(unit.MapItemTablePointer).Index.ToString("D6")}_DropItems")));
                    }
                    else
                    {
                        yield return(builder.GenerateInvocationStatement(
                                         nameof(War3Api.Common.TriggerAddAction),
                                         builder.GenerateVariableExpression(LocalTriggerVariableName),
                                         builder.GenerateFunctionReferenceExpression($"Unit{unit.CreationNumber.ToString("D6")}_DropItems")));
                    }
                }
            }
        }
示例#2
0
        public static JassFunctionDeclarationSyntax InitRandomGroups(IEnumerable <RandomUnitTable> randomUnitTables)
        {
            const string LocalCurrentSetVariableName = "curset";

            var statements = new List <IStatementSyntax>();

            statements.Add(SyntaxFactory.LocalVariableDeclarationStatement(JassTypeSyntax.Integer, LocalCurrentSetVariableName));
            statements.Add(JassEmptyStatementSyntax.Value);

            foreach (var unitTable in randomUnitTables)
            {
                statements.Add(new JassCommentStatementSyntax($" Group {unitTable.Index} - {unitTable.Name}"));
                statements.Add(SyntaxFactory.CallStatement(nameof(War3Api.Blizzard.RandomDistReset)));

                for (var i = 0; i < unitTable.UnitSets.Count; i++)
                {
                    statements.Add(SyntaxFactory.CallStatement(
                                       nameof(War3Api.Blizzard.RandomDistAddItem),
                                       SyntaxFactory.LiteralExpression(i),
                                       SyntaxFactory.LiteralExpression(unitTable.UnitSets[i].Chance)));
                }

                statements.Add(SyntaxFactory.SetStatement(LocalCurrentSetVariableName, SyntaxFactory.InvocationExpression(nameof(War3Api.Blizzard.RandomDistChoose))));
                statements.Add(JassEmptyStatementSyntax.Value);

                var groupVarName   = unitTable.GetVariableName();
                var ifElseifBlocks = new List <(IExpressionSyntax Condition, IStatementSyntax[] Body)>();
                for (var setIndex = 0; setIndex < unitTable.UnitSets.Count; setIndex++)
                {
                    var set = unitTable.UnitSets[setIndex];

                    var condition      = SyntaxFactory.BinaryEqualsExpression(SyntaxFactory.VariableReferenceExpression(LocalCurrentSetVariableName), SyntaxFactory.LiteralExpression(setIndex));
                    var bodyStatements = new List <IStatementSyntax>();

                    for (var position = 0; position < unitTable.Types.Count; position++)
                    {
                        var id = set?.UnitIds[position] ?? 0;
                        var unitTypeExpression = RandomUnitProvider.IsRandomUnit(id, out var level)
                            ? SyntaxFactory.InvocationExpression(nameof(ChooseRandomCreep), SyntaxFactory.LiteralExpression(level))
                            : id == 0 ? SyntaxFactory.LiteralExpression(-1) : SyntaxFactory.FourCCLiteralExpression(id);

                        bodyStatements.Add(SyntaxFactory.SetStatement(
                                               groupVarName,
                                               SyntaxFactory.LiteralExpression(position),
                                               unitTypeExpression));
                    }

                    ifElseifBlocks.Add((new JassParenthesizedExpressionSyntax(condition), bodyStatements.ToArray()));
                }

                var elseClauseStatements = new List <IStatementSyntax>();
                for (var position = 0; position < unitTable.Types.Count; position++)
                {
                    elseClauseStatements.Add(SyntaxFactory.SetStatement(
                                                 groupVarName,
                                                 SyntaxFactory.LiteralExpression(position),
                                                 SyntaxFactory.LiteralExpression(-1)));
                }

                statements.Add(SyntaxFactory.IfStatement(
                                   ifElseifBlocks.First().Condition,
                                   SyntaxFactory.StatementList(ifElseifBlocks.First().Body),
                                   ifElseifBlocks.Skip(1).Select(elseIf => new JassElseIfClauseSyntax(elseIf.Condition, SyntaxFactory.StatementList(elseIf.Body))),
                                   new JassElseClauseSyntax(SyntaxFactory.StatementList(elseClauseStatements))));

                statements.Add(JassEmptyStatementSyntax.Value);
            }

            return(SyntaxFactory.FunctionDeclaration(SyntaxFactory.FunctionDeclarator(nameof(InitRandomGroups)), statements));
        }
示例#3
0
        private static IEnumerable <TStatementSyntax> GetUnitTableHelperFunctionStatements(TBuilder builder)
        {
            var mapInfo = builder.Data.MapInfo;

            for (var i = 0; i < mapInfo.RandomUnitTableCount; i++)
            {
                var unitTable = mapInfo.GetUnitTable(i);

                yield return(builder.GenerateInvocationStatement(nameof(War3Api.Blizzard.RandomDistReset)));

                var summedChance = 0; // TODO?
                for (var j = 0; j < unitTable.UnitSetCount; j++)
                {
                    yield return(builder.GenerateInvocationStatement(
                                     nameof(War3Api.Blizzard.RandomDistAddItem),
                                     builder.GenerateIntegerLiteralExpression(j),
                                     builder.GenerateIntegerLiteralExpression(unitTable.GetSet(j).Chance)));
                }

                yield return(builder.GenerateAssignmentStatement(
                                 LocalCurrentSetVariableName,
                                 builder.GenerateInvocationExpression(nameof(War3Api.Blizzard.RandomDistChoose))));

                var groupVarName   = $"gg_rg_{unitTable.Index.ToString("D3")}";
                var bodyStatements = new TStatementSyntax[unitTable.UnitSetCount + 1][];
                for (var setIndex = 0; setIndex <= unitTable.UnitSetCount; setIndex++)
                {
                    var set = unitTable.GetSet(setIndex);
                    bodyStatements[setIndex] = new TStatementSyntax[unitTable.Positions];
                    for (var position = 0; position < unitTable.Positions; position++)
                    {
                        var id = set?.GetId(position) ?? new[] { '\0', '\0', '\0', '\0' };
                        var unitTypeExpression = RandomUnitProvider.IsRandomUnit(id, out var level)
                            ? builder.GenerateInvocationExpression(
                            nameof(War3Api.Common.ChooseRandomCreep),
                            builder.GenerateIntegerLiteralExpression(level))
                            : new string(id) == "\0\0\0\0"
                                ? builder.GenerateIntegerLiteralExpression(-1)
                                : builder.GenerateFourCCExpression(new string(id));

                        bodyStatements[setIndex][position] = builder.GenerateAssignmentStatement(
                            groupVarName,
                            builder.GenerateIntegerLiteralExpression(position),
                            unitTypeExpression);
                    }
                }

                var ifStatement = builder.GenerateIfStatement(
                    builder.GenerateBinaryExpression(
                        BinaryOperator.Equals,
                        builder.GenerateVariableExpression(LocalCurrentSetVariableName),
                        builder.GenerateIntegerLiteralExpression(0)),
                    bodyStatements[0]);

                for (var setIndex = 1; setIndex < unitTable.UnitSetCount; setIndex++)
                {
                    ifStatement = builder.GenerateElseClause(
                        ifStatement,
                        builder.GenerateBinaryExpression(
                            BinaryOperator.Equals,
                            builder.GenerateVariableExpression(LocalCurrentSetVariableName),
                            builder.GenerateIntegerLiteralExpression(setIndex)),
                        bodyStatements[setIndex]);
                }

                ifStatement = builder.GenerateElseClause(
                    ifStatement,
                    null,
                    bodyStatements[unitTable.UnitSetCount]);

                yield return(ifStatement);
            }
        }
        private static IEnumerable <TStatementSyntax> GetCreateAllUnitsHelperFunctionStatements(TBuilder builder)
        {
            var mapInfo = builder.Data.MapInfo;

            foreach (var unit in builder.Data.MapUnits.Where(mapUnit => mapUnit.IsUnit))
            {
                if (unit.IsRandomUnit)
                {
                    var randomData = unit.RandomData;
                    switch (randomData.Mode)
                    {
                    case 0:
                        if (unit.IsRandomBuilding)
                        {
                            yield return(builder.GenerateAssignmentStatement(
                                             LocalUnitVariableName,
                                             builder.GenerateInvocationExpression(
                                                 nameof(War3Api.Common.ChooseRandomNPBuilding))));
                        }
                        else
                        {
                            yield return(builder.GenerateAssignmentStatement(
                                             LocalUnitIdVariableName,
                                             builder.GenerateInvocationExpression(
                                                 nameof(War3Api.Common.ChooseRandomCreep),
                                                 builder.GenerateIntegerLiteralExpression(randomData.Level))));
                        }

                        break;

                    case 1:
                        yield return(builder.GenerateAssignmentStatement(
                                         LocalUnitIdVariableName,
                                         builder.GenerateArrayReferenceExpression(
                                             $"gg_rg_{randomData.UnitGroupTableIndex.ToString("D3")}",
                                             builder.GenerateIntegerLiteralExpression(randomData.UnitGroupTableColumn))));

                        break;

                    case 2:
                        yield return(builder.GenerateInvocationStatement(nameof(War3Api.Blizzard.RandomDistReset)));

                        var summedChance = 0;
                        foreach (var randomUnitOption in randomData)
                        {
                            summedChance += randomUnitOption.chance;

                            var unitTypeExpression = RandomUnitProvider.IsRandomUnit(randomUnitOption.id, out var level)
                                    ? builder.GenerateInvocationExpression(
                                nameof(War3Api.Common.ChooseRandomCreep),
                                builder.GenerateIntegerLiteralExpression(level))
                                    : builder.GenerateFourCCExpression(new string(randomUnitOption.id));

                            yield return(builder.GenerateInvocationStatement(
                                             nameof(War3Api.Blizzard.RandomDistAddItem),
                                             unitTypeExpression,
                                             builder.GenerateIntegerLiteralExpression(randomUnitOption.chance)));
                        }

                        if (summedChance < 100)
                        {
                            yield return(builder.GenerateInvocationStatement(
                                             nameof(War3Api.Blizzard.RandomDistAddItem),
                                             builder.GenerateIntegerLiteralExpression(-1),
                                             builder.GenerateIntegerLiteralExpression(100 - summedChance)));
                        }

                        yield return(builder.GenerateAssignmentStatement(
                                         LocalUnitIdVariableName,
                                         builder.GenerateInvocationExpression(nameof(War3Api.Blizzard.RandomDistChoose))));

                        break;
                    }

                    yield return(builder.GenerateIfStatement(
                                     builder.GenerateBinaryExpression(
                                         BinaryOperator.NotEquals,
                                         builder.GenerateVariableExpression(LocalUnitIdVariableName),
                                         builder.GenerateIntegerLiteralExpression(-1)),
                                     builder.GenerateAssignmentStatement(
                                         LocalUnitVariableName,
                                         builder.GenerateInvocationExpression(
                                             nameof(War3Api.Common.CreateUnit),
                                             builder.GenerateInvocationExpression(
                                                 nameof(War3Api.Common.Player),
                                                 builder.GenerateIntegerLiteralExpression(unit.Owner)),
                                             builder.GenerateVariableExpression(LocalUnitIdVariableName),
                                             builder.GenerateFloatLiteralExpression(unit.PositionX),
                                             builder.GenerateFloatLiteralExpression(unit.PositionY),
                                             builder.GenerateFloatLiteralExpression(unit.Facing)))));
                }
                else
                {
                    yield return(builder.GenerateAssignmentStatement(
                                     LocalUnitVariableName,
                                     builder.GenerateInvocationExpression(
                                         nameof(War3Api.Common.CreateUnit),
                                         builder.GenerateInvocationExpression(
                                             nameof(War3Api.Common.Player),
                                             builder.GenerateIntegerLiteralExpression(unit.Owner)),
                                         builder.GenerateFourCCExpression(unit.TypeId),
                                         builder.GenerateFloatLiteralExpression(unit.PositionX),
                                         builder.GenerateFloatLiteralExpression(unit.PositionY),
                                         builder.GenerateFloatLiteralExpression(unit.Facing))));
                }

                // TODO: test which statements cannot be generated for random units, and put them inside the else block above (hero level/stats?)

                if (unit.HeroLevel > 1)
                {
                    yield return(builder.GenerateInvocationStatement(
                                     nameof(War3Api.Common.SetHeroLevel),
                                     builder.GenerateVariableExpression(LocalUnitVariableName),
                                     builder.GenerateIntegerLiteralExpression(unit.HeroLevel),
                                     builder.GenerateBooleanLiteralExpression(false)));
                }

                if (unit.HeroStrength > 0)
                {
                    yield return(builder.GenerateInvocationStatement(
                                     nameof(War3Api.Common.SetHeroStr),
                                     builder.GenerateVariableExpression(LocalUnitVariableName),
                                     builder.GenerateIntegerLiteralExpression(unit.HeroStrength),
                                     builder.GenerateBooleanLiteralExpression(true)));
                }

                if (unit.HeroAgility > 0)
                {
                    yield return(builder.GenerateInvocationStatement(
                                     nameof(War3Api.Common.SetHeroAgi),
                                     builder.GenerateVariableExpression(LocalUnitVariableName),
                                     builder.GenerateIntegerLiteralExpression(unit.HeroAgility),
                                     builder.GenerateBooleanLiteralExpression(true)));
                }

                if (unit.HeroIntelligence > 0)
                {
                    yield return(builder.GenerateInvocationStatement(
                                     nameof(War3Api.Common.SetHeroInt),
                                     builder.GenerateVariableExpression(LocalUnitVariableName),
                                     builder.GenerateIntegerLiteralExpression(unit.HeroIntelligence),
                                     builder.GenerateBooleanLiteralExpression(true)));
                }

                if (unit.Hp != -1)
                {
                    yield return(builder.GenerateInvocationStatement(
                                     nameof(War3Api.Common.SetUnitState),
                                     builder.GenerateVariableExpression(LocalUnitVariableName),
                                     builder.GenerateVariableExpression(nameof(War3Api.Common.UNIT_STATE_LIFE)),
                                     builder.GenerateBinaryExpression(
                                         BinaryOperator.Multiplication,
                                         builder.GenerateFloatLiteralExpression(unit.Hp * 0.01f),
                                         builder.GenerateInvocationExpression(
                                             nameof(War3Api.Common.GetUnitState),
                                             builder.GenerateVariableExpression(LocalUnitVariableName),
                                             builder.GenerateVariableExpression(nameof(War3Api.Common.UNIT_STATE_LIFE))))));
                }

                if (unit.Mp != -1)
                {
                    yield return(builder.GenerateInvocationStatement(
                                     nameof(War3Api.Common.SetUnitState),
                                     builder.GenerateVariableExpression(LocalUnitVariableName),
                                     builder.GenerateVariableExpression(nameof(War3Api.Common.UNIT_STATE_MANA)),
                                     builder.GenerateFloatLiteralExpression(unit.Mp)));
                }

                if (unit.TypeId == "ngol")
                {
                    yield return(builder.GenerateInvocationStatement(
                                     nameof(War3Api.Common.SetResourceAmount),
                                     builder.GenerateVariableExpression(LocalUnitVariableName),
                                     builder.GenerateIntegerLiteralExpression(unit.GoldAmount)));
                }

                if (unit.TargetAcquisition != -1)
                {
                    const float CampAcquisitionRange = 200f;
                    yield return(builder.GenerateInvocationStatement(
                                     nameof(War3Api.Common.SetUnitAcquireRange),
                                     builder.GenerateVariableExpression(LocalUnitVariableName),
                                     builder.GenerateFloatLiteralExpression(unit.TargetAcquisition == -2 ? CampAcquisitionRange : unit.TargetAcquisition)));
                }

                // TODO: CustomPlayerColor
                // TODO: WaygateDestination (requires parsing war3map.w3r)
                // TODO: CreationNumber? (only used to declare global var if unit is referenced in triggers?, ie useless)

                foreach (var ability in unit.AbilityData)
                {
                    for (var i = 0; i < ability.Level; i++)
                    {
                        // TODO: make sure Level is 0 for non-hero abilities (can confirm this by checking second char is uppercase?)
                        yield return(builder.GenerateInvocationStatement(
                                         nameof(War3Api.Common.SelectHeroSkill),
                                         builder.GenerateVariableExpression(LocalUnitVariableName),
                                         builder.GenerateFourCCExpression(ability.Id)));
                    }

                    if (ability.IsActive)
                    {
#if false
                        yield return(builder.GenerateInvocationStatement(
                                         nameof(War3Api.Common.IssueImmediateOrder),
                                         builder.GenerateVariableExpression(LocalUnitVariableName),
                                         builder.GenerateStringLiteralExpression(ability.OrderString)));
#else
                        // TODO: test if this works
                        yield return(builder.GenerateInvocationStatement(
                                         nameof(War3Api.Common.IssueImmediateOrderById),
                                         builder.GenerateVariableExpression(LocalUnitVariableName),
                                         builder.GenerateFourCCExpression(ability.Id)));
#endif
                    }
                }

                foreach (var item in unit.Inventory)
                {
                    yield return(builder.GenerateInvocationStatement(
                                     nameof(War3Api.Common.UnitAddItemToSlotById),
                                     builder.GenerateVariableExpression(LocalUnitVariableName),
                                     builder.GenerateFourCCExpression(item.Id),
                                     builder.GenerateIntegerLiteralExpression(item.Slot)));
                }

                if (unit.MapItemTablePointer != -1 || unit.DroppedItemData.FirstOrDefault() != null)
                {
                    yield return(builder.GenerateAssignmentStatement(
                                     LocalTriggerVariableName,
                                     builder.GenerateInvocationExpression(nameof(War3Api.Common.CreateTrigger))));

                    yield return(builder.GenerateInvocationStatement(
                                     nameof(War3Api.Common.TriggerRegisterUnitEvent),
                                     builder.GenerateVariableExpression(LocalTriggerVariableName),
                                     builder.GenerateVariableExpression(LocalUnitVariableName),
                                     builder.GenerateVariableExpression(nameof(War3Api.Common.EVENT_UNIT_DEATH))));

                    yield return(builder.GenerateInvocationStatement(
                                     nameof(War3Api.Common.TriggerRegisterUnitEvent),
                                     builder.GenerateVariableExpression(LocalTriggerVariableName),
                                     builder.GenerateVariableExpression(LocalUnitVariableName),
                                     builder.GenerateVariableExpression(nameof(War3Api.Common.EVENT_UNIT_CHANGE_OWNER))));

                    if (unit.MapItemTablePointer != -1)
                    {
                        yield return(builder.GenerateInvocationStatement(
                                         nameof(War3Api.Common.TriggerAddAction),
                                         builder.GenerateVariableExpression(LocalTriggerVariableName),
                                         builder.GenerateFunctionReferenceExpression($"ItemTable{mapInfo.GetItemTable(unit.MapItemTablePointer).Index.ToString("D6")}_DropItems")));
                    }
                    else
                    {
                        yield return(builder.GenerateInvocationStatement(
                                         nameof(War3Api.Common.TriggerAddAction),
                                         builder.GenerateVariableExpression(LocalTriggerVariableName),
                                         builder.GenerateFunctionReferenceExpression($"Unit{unit.CreationNumber.ToString("D6")}_DropItems")));
                    }
                }
            }
        }
示例#5
0
        protected virtual JassFunctionDeclarationSyntax InitRandomGroups(Map map)
        {
            if (map is null)
            {
                throw new ArgumentNullException(nameof(map));
            }

            var randomUnitTables = map.Info.RandomUnitTables;

            if (randomUnitTables is null)
            {
                throw new ArgumentException($"Function '{nameof(InitRandomGroups)}' cannot be generated without {nameof(MapInfo.RandomUnitTables)}.", nameof(map));
            }

            var statements = new List <IStatementSyntax>();

            statements.Add(SyntaxFactory.LocalVariableDeclarationStatement(JassTypeSyntax.Integer, VariableName.CurrentSet));
            statements.Add(JassEmptyStatementSyntax.Value);

            foreach (var unitTable in randomUnitTables)
            {
                statements.Add(new JassCommentStatementSyntax($" Group {unitTable.Index} - {unitTable.Name}"));
                statements.Add(SyntaxFactory.CallStatement(FunctionName.RandomDistReset));

                for (var i = 0; i < unitTable.UnitSets.Count; i++)
                {
                    statements.Add(SyntaxFactory.CallStatement(
                                       FunctionName.RandomDistAddItem,
                                       SyntaxFactory.LiteralExpression(i),
                                       SyntaxFactory.LiteralExpression(unitTable.UnitSets[i].Chance)));
                }

                statements.Add(SyntaxFactory.SetStatement(VariableName.CurrentSet, SyntaxFactory.InvocationExpression(FunctionName.RandomDistChoose)));
                statements.Add(JassEmptyStatementSyntax.Value);

                var groupVarName   = unitTable.GetVariableName();
                var ifElseifBlocks = new List <(IExpressionSyntax Condition, IStatementSyntax[] Body)>();
                for (var setIndex = 0; setIndex < unitTable.UnitSets.Count; setIndex++)
                {
                    var set = unitTable.UnitSets[setIndex];

                    var condition      = SyntaxFactory.BinaryEqualsExpression(SyntaxFactory.VariableReferenceExpression(VariableName.CurrentSet), SyntaxFactory.LiteralExpression(setIndex));
                    var bodyStatements = new List <IStatementSyntax>();

                    for (var position = 0; position < unitTable.Types.Count; position++)
                    {
                        var id = set?.UnitIds[position] ?? 0;
                        var unitTypeExpression = RandomUnitProvider.IsRandomUnit(id, out var level)
                            ? SyntaxFactory.InvocationExpression(NativeName.ChooseRandomCreep, SyntaxFactory.LiteralExpression(level))
                            : id == 0 ? SyntaxFactory.LiteralExpression(-1) : SyntaxFactory.FourCCLiteralExpression(id);

                        bodyStatements.Add(SyntaxFactory.SetStatement(
                                               groupVarName,
                                               SyntaxFactory.LiteralExpression(position),
                                               unitTypeExpression));
                    }

                    ifElseifBlocks.Add((new JassParenthesizedExpressionSyntax(condition), bodyStatements.ToArray()));
                }

                var elseClauseStatements = new List <IStatementSyntax>();
                for (var position = 0; position < unitTable.Types.Count; position++)
                {
                    elseClauseStatements.Add(SyntaxFactory.SetStatement(
                                                 groupVarName,
                                                 SyntaxFactory.LiteralExpression(position),
                                                 SyntaxFactory.LiteralExpression(-1)));
                }

                statements.Add(SyntaxFactory.IfStatement(
                                   ifElseifBlocks.First().Condition,
                                   SyntaxFactory.StatementList(ifElseifBlocks.First().Body),
                                   ifElseifBlocks.Skip(1).Select(elseIf => new JassElseIfClauseSyntax(elseIf.Condition, SyntaxFactory.StatementList(elseIf.Body))),
                                   new JassElseClauseSyntax(SyntaxFactory.StatementList(elseClauseStatements))));

                statements.Add(JassEmptyStatementSyntax.Value);
            }

            return(SyntaxFactory.FunctionDeclaration(SyntaxFactory.FunctionDeclarator(nameof(InitRandomGroups)), statements));
        }