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); }
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); }
public ConditionalAssetType(ConditionalAssetType otherWithCondition) { Kind = otherWithCondition.Kind; }