Beispiel #1
0
        public static ASTNode ResolveInt(DecompileContext ctx, ASTNode intNode, ConditionalAssetType type)
        {
            int value = (intNode.Kind == ASTNode.StatementKind.Int16) ? (intNode as ASTInt16).Value : (intNode as ASTInt32).Value;

            switch (type.Kind)
            {
            case AssetType.Boolean:
                if (value == 0)
                {
                    return(new ASTBoolean(false));
                }
                else if (value == 1)
                {
                    return(new ASTBoolean(true));
                }
                break;

            case AssetType.Object:
                if (intNode.Kind == ASTNode.StatementKind.Int16)
                {
                    return(ResolveObject(ctx, intNode as ASTInt16));
                }
                break;

            case AssetType.Sprite:
                if (value >= 0 && value < ctx.Project.Sprites.Count)
                {
                    return(new ASTAsset(ctx.Project.Sprites[value].Name));
                }
                else if (value == -4)
                {
                    return(new ASTAsset("noone"));
                }
                break;

            case AssetType.Room:
                if (value >= 0 && value < ctx.Project.Rooms.Count)
                {
                    return(new ASTAsset(ctx.Project.Rooms[value].Name));
                }
                else if (value == -4)
                {
                    return(new ASTAsset("noone"));
                }
                break;

            case AssetType.Font:
                if (value >= 0 && value < ctx.Project.Fonts.Count)
                {
                    return(new ASTAsset(ctx.Project.Fonts[value].Name));
                }
                else if (value == -4)
                {
                    return(new ASTAsset("noone"));
                }
                break;

            case AssetType.Sound:
                if (value >= 0 && value < ctx.Project.Sounds.Count)
                {
                    return(new ASTAsset(ctx.Project.Sounds[value].Name));
                }
                else if (value == -4)
                {
                    return(new ASTAsset("noone"));
                }
                break;

            case AssetType.Path:
                if (value >= 0 && value < ctx.Project.Paths.Count)
                {
                    return(new ASTAsset(ctx.Project.Paths[value].Name));
                }
                else if (value == -4)
                {
                    return(new ASTAsset("noone"));
                }
                break;

            case AssetType.Color:
                if (value >= 0)
                {
                    if (ctx.Cache.Types.ColorMacros.TryGetValue(value, out string color))
                    {
                        return(new ASTAsset(color));
                    }
                    return(new ASTAsset((ctx.Data.VersionInfo.IsNumberAtLeast(2) ? "0x" : "$") + value.ToString("X6", CultureInfo.InvariantCulture)));
                }
                break;

            case AssetType.Keyboard:
                if (value >= 0)
                {
                    if (ctx.Cache.Types.KeyboardMacros.TryGetValue(value, out string keyboard))
                    {
                        return(new ASTAsset(keyboard));
                    }
                    if (value >= '0' && value <= 'Z')
                    {
                        return(new ASTAsset("ord(\"" + (char)value + "\")"));
                    }
                }
                break;

            case AssetType.Macro_PathEndAction:
            {
                if (ctx.Cache.Types.PathEndActionMacros.TryGetValue(value, out string macro))
                {
                    return(new ASTAsset(macro));
                }
            }
            break;
            }
            return(intNode);
        }
Beispiel #2
0
        public static ASTNode ResolveAny(DecompileContext ctx, ASTNode node, ASTNode parent, ConditionalAssetType type)
        {
            // Check if this type has a condition that needs to be satisfied
            if (type.Condition != null)
            {
                if (type.Condition.Evaluate(ctx, node, parent))
                {
                    if (type.Condition.EvaluateOnce)
                    {
                        type = new(type); // Make a new type without the condition (it has been satisfied)
                    }
                }
                else
                {
                    // Check if there's any valid alternative type
                    if (type.Alternatives != null)
                    {
                        bool evaluated = false;
                        for (int i = 0; i < type.Alternatives.Length; i++)
                        {
                            var curr = type.Alternatives[i];
                            if (curr.Condition == null || curr.Condition.Evaluate(ctx, node, parent))
                            {
                                evaluated = true;
                                if (curr.Condition != null && curr.Condition.EvaluateOnce)
                                {
                                    type = new(curr); // Make a new type without the condition (it has been satisfied)
                                }
                                else
                                {
                                    type = curr;
                                }
                                break;
                            }
                        }

                        if (!evaluated)
                        {
                            return(node);
                        }
                    }
                    else
                    {
                        return(node);
                    }
                }
            }

            switch (node.Kind)
            {
            case ASTNode.StatementKind.Int16:
            case ASTNode.StatementKind.Int32:
                return(ResolveInt(ctx, node, type));

            case ASTNode.StatementKind.IfStatement:
                if (node.Children.Count == 5)
                {
                    node.Children[3] = ResolveAny(ctx, node.Children[3], node, type);
                    node.Children[4] = ResolveAny(ctx, node.Children[4], node, type);
                }
                break;

            case ASTNode.StatementKind.Binary:
                node.Children[0] = ResolveAny(ctx, node.Children[0], node, type);
                node.Children[1] = ResolveAny(ctx, node.Children[1], node, type);
                break;

            case ASTNode.StatementKind.Function:
                if ((node as ASTFunction).Function.Name.Content == "@@NewGMLArray@@")
                {
                    for (int i = 0; i < node.Children.Count; i++)
                    {
                        node.Children[i] = ResolveAny(ctx, node.Children[i], node, type);
                    }
                }
                break;
            }

            return(node);
        }
Beispiel #3
0
 public ConditionalAssetType(ConditionalAssetType otherWithCondition)
 {
     Kind = otherWithCondition.Kind;
 }