public static ConsoleCommandGroup AddUnitFlag(this ConsoleCommandGroup group, string name, Getter <bool> getFunc, Setter <bool> setAction) { group.AddUnit(name, delegate(string[] args) { var noArguments = args.Length == 0; if (noArguments) { var stateString = getFunc() ? "<color=#00ff00ff>on</color>" : "<color=#ff0000ff>off</color>"; NoBrain.Log($"{name} is turned {stateString}!"); } else { var parseSuccess = !bool.TryParse(args[0], out var parsedValue); if (parseSuccess) { NoBrain.Log($"This argument only supports \"true\" or \"false\" as values. (Given: {args[0]})"); } else { setAction(parsedValue); var stateString = parsedValue ? "<color=#00ff00ff>enabled</color>" : "<color=#ff0000ff>disabled</color>"; NoBrain.Log($"{name} has been {stateString}!"); } } }); return(group); }
public void AddStatCommands(PlayerController player, string name, PlayerStats.StatType type) { _SetGroup.AddUnit(name, (args) => SetStat(player, type, float.Parse(args[0]))); _GetGroup.AddUnit(name, (args) => ETGModConsole.Log(GetStat(player, type).ToString())); }
public override void Init() { System.IO.Directory.CreateDirectory("MagicSmokeSaves"); _AutocompletionSettings = new AutocompletionSettings((input) => { List <string> ret = new List <string>(); foreach (var stat in _Stats) { if (stat.Key.AutocompletionMatch(input.ToLower())) { ret.Add(stat.Key); } } return(ret.ToArray()); }); _AutocompletionChests = new AutocompletionSettings((input) => { List <string> ret = new List <string>(); foreach (var stat in _Chests) { if (stat.Key.AutocompletionMatch(input.ToLower())) { ret.Add(stat.Key); } } return(ret.ToArray()); }); _StatGet = (args) => { if (_Stats.ContainsKey(args[0])) { ETGModConsole.Log(_Stats[args[0]] + " value is: <color=#ff0000ff>" + GameManager.Instance.PrimaryPlayer.stats.GetStatValue(_Stats[args[0]]) + "</color>"); } else { ETGModConsole.Log($"Please check your command and try again"); } }; _StatGetAll = (args) => { ETGModConsole.Log("Available stats:"); foreach (var stat in _Stats) { ETGModConsole.Log($"- {stat.Key} <color=#ff0000ff>" + GameManager.Instance.PrimaryPlayer.stats.GetStatValue(stat.Value) + "</color>"); } }; ETGModConsole.Commands.AddGroup("ms", (string[] args) => { ETGModConsole.Log("<size=100><color=#ff0000ff>MagicSmoke v1 by flagmaggot</color></size>", false); ETGModConsole.Log("<size=100><color=#ff0000ff>DOES NOT WORK WHILE IN THE BREACH</color></size>", false); ETGModConsole.Log("<size=100><color=#ff0000ff>--------------------------------</color></size>", false); ETGModConsole.Log("Use \"ms help\" for help!", false); }); ETGModConsole.Commands.GetGroup("ms").AddUnit("help", (string[] args) => { ETGModConsole.Log("<size=100><color=#ff0000ff>MagicSmoke v1 by flagmaggot</color></size>", false); ETGModConsole.Log("<size=100><color=#ff0000ff>DOES NOT WORK WHILE IN THE BREACH</color></size>", false); ETGModConsole.Log("<size=100><color=#ff0000ff>--------------------------------</color></size>", false); ETGModConsole.Log("Magic Smoke Command Reference:", false); ETGModConsole.Log("", false); ETGModConsole.Log("<color=#FFFF33>ms help</color> - Displays this help", false); ETGModConsole.Log("<color=#FFFF33>ms get <stat name></color> - gets the state value", false); ETGModConsole.Log("<color=#FFFF33>ms set <stat name> [arg]</color> - sets the player speed (decimal values)", false); ETGModConsole.Log("<color=#FFFF33>ms getallstats</color> - returns all the stats and their values", false); ETGModConsole.Log("<color=#FFFF33>ms forcedualwield [gunid]</color> - forces the player to dual wield, use gun names, it will autocomplete to help.", false); ETGModConsole.Log("<color=#FFFF33>ms spawnsynergy</color> - spawns synergy chest", false); ETGModConsole.Log("<color=#FFFF33>ms spawnrainbowsynergy</color> - spawns rainbow synergy chest", false); ETGModConsole.Log("<color=#FFFF33>ms savesettings [name</color> - saves player settings to a file [name].json", false); ETGModConsole.Log("<color=#FFFF33>ms loadsettings [name]</color> - loads player settings from a file [name].json", false); ETGModConsole.Log("<color=#FFFF33>ms spawnglitched [arg] [true]</color> - spawns a glitch chest, [arg] can be a,b,c,d,s,red,green,blue,brown,black [use true after if you want to warp to glitched level]", false); ETGModConsole.Log("<color=#FFFF33>ms setmagnificense [arg]</color> - sets the magnificence value", false); ETGModConsole.Log("<color=#FFFF33>ms getmagnificense [arg]</color> - gets the current magnificence value", false); ETGModConsole.Log("<color=#FFFF33>ms saveclipboard</color> - copies the encoded settings to the clipboard", false); ETGModConsole.Log("<color=#FFFF33>ms loadclipboard</color> - loads the settings directly from clipboard", false); ETGModConsole.Log("<color=#FFFF33>ms loadclipboard [arg</color>] - loads the settings based off the encoded pasted data [arg]", false); ETGModConsole.Log("<color=#FFFF33>ms pollthegungeon</color> - Request from YouTuber Hutts, finds all chests on current floor and spawns 3 additional random chests.", false); ETGModConsole.Log("<color=#FFFF33>ms findchests</color> - gives coordinates for all chests currently on the floor (you can teleport to them by using tp <first number> <second number>", false); ETGModConsole.Log("<color=#FFFF33>ms addteleporters</color> - adds teleporters to almost all the rooms on the current dungeon", false); ETGModConsole.Log("<color=#FFFF33>ms visitallrooms</color> - marks all rooms as visited, makes all visible on minimap", false); ETGModConsole.Log("<color=#FFFF33>ms revealrooms</color> - makes all rooms visible (similar to Floor revealed item)", false); ETGModConsole.Log("<color=#FFFF33>ms dropactives</color> - drops all active items", false); ETGModConsole.Log("<color=#FFFF33>ms droppassives</color> - drops all passive items", false); ETGModConsole.Log("<color=#FFFF33>ms dropall</color> - drop all items and guns (except defauilt gun)", false); ETGModConsole.Log("<color=#FFFF33>ms clearall</color> - clears all active and passive items.", false); ETGModConsole.Log("<color=#FFFF33>ms clearpassives</color> - clears passive items", false); ETGModConsole.Log("<color=#FFFF33>ms clearactives</color> - clears active items", false); ETGModConsole.Log("<color=#FFFF33>ms dropguns</color> - drops all guns (except default gun)", false); }); ETGModConsole.Commands.GetGroup("ms").AddUnit("forcedualwield", DualWieldItem, _GiveAutocompletionSettings); _MagnificenceSet = (args) => { float value; if (float.TryParse(args[0], out value)) { GameManager.Instance.PrimaryPlayer.stats.AddFloorMagnificence(value); ETGModConsole.Log("Magnificence set to: <color=#ff0000ff>" + value + "</color>"); } else { ETGModConsole.Log($"Please check your command and try again"); } }; _MagnificenceGet = (args) => { ETGModConsole.Log("Magnificence set to: <color=#ff0000ff>" + GameManager.Instance.PrimaryPlayer.stats.Magnificence + "</color>"); }; _StatSet = (args) => { float value; if (_Stats.ContainsKey(args[0]) && float.TryParse(args[1], out value)) { GameManager.Instance.PrimaryPlayer.stats.SetBaseStatValue(_Stats[args[0]], value, GameManager.Instance.PrimaryPlayer); ETGModConsole.Log(_Stats[args[0]] + " set to: <color=#ff0000ff>" + value + "</color>"); } else { ETGModConsole.Log($"Please check your command and try again"); } }; ETGModConsole.Commands.GetGroup("ms").AddUnit("spawnsynergy", (string[] args) => { Chest synergy_Chest = GameManager.Instance.RewardManager.Synergy_Chest; //if(args.Length != 0) //{ // synergy_Chest.IsRainbowChest = true; //} synergy_Chest.IsRainbowChest = false; synergy_Chest.ForceUnlock(); IntVector2 basePosition = new IntVector2((int)GameManager.Instance.PrimaryPlayer.transform.position.x, (int)GameManager.Instance.PrimaryPlayer.transform.position.y); Chest.Spawn(synergy_Chest, basePosition); synergy_Chest.ForceUnlock(); }); ETGModConsole.Commands.GetGroup("ms").AddUnit("spawnrainbowsynergy", (string[] args) => { Chest synergy_Chest = GameManager.Instance.RewardManager.Synergy_Chest; synergy_Chest.IsRainbowChest = true; IntVector2 basePosition = new IntVector2((int)GameManager.Instance.PrimaryPlayer.transform.position.x, (int)GameManager.Instance.PrimaryPlayer.transform.position.y); Chest.Spawn(synergy_Chest, basePosition); synergy_Chest.ForceUnlock(); }); ETGModConsole.Commands.GetGroup("ms").AddUnit("savesettings", (string[] args) => { SaveSettings(args[0]); ETGModConsole.Log("Settings file saved as: " + args[0] + ".json"); }); ETGModConsole.Commands.GetGroup("ms").AddUnit("saveclipboard", (string[] args) => { SaveSettingsToClipboard(); ETGModConsole.Log("Settings copied to clipboard"); }); //ETGModConsole.Commands.GetGroup("ms").AddUnit("summon", (string[] args) => //{ // //ResourceManager.LoadAssetBundle("./shared_auto_001/Shrine_Mirror55"); // AdvancedShrineController ads = new AdvancedShrineController(); // ads.IsBlankShrine = true; // ads.Start(); // ETGModConsole.Log("No"); //}); ETGModConsole.Commands.GetGroup("ms").AddUnit("zoom", (string[] args) => { if (args.Count() > 0) { float zoomScale; float.TryParse(args[0], out zoomScale); GameManager.Instance.MainCameraController.OverrideZoomScale = zoomScale; ETGModConsole.Log($"Camera zoom set to {zoomScale}"); } }); ETGModConsole.Commands.GetGroup("ms").AddUnit("pollthegungeon", (string[] args) => { List <Chest> chests = new List <Chest>(); chests = StaticReferenceManager.AllChests; foreach (Chest c in chests.ToList()) { RoomHandler room = c.GetAbsoluteParentRoom(); while (room.GetComponentsAbsoluteInRoom <Chest>().Count() < 4) { for (int i = 0; i < 3; i++) { SpawnChests(room); } } } }); ETGModConsole.Commands.GetGroup("ms").AddUnit("findchests", (string[] args) => { List <Chest> chests = StaticReferenceManager.AllChests; foreach (Chest c in chests) { ETGModConsole.Log($"Chest location: <color=#ff0000ff>{c.transform.position}</color>"); } }); //ETGModConsole.Commands.GetGroup("ms").AddUnit("open", (string[] args) => //{ // List<Chest> chests = StaticReferenceManager.AllChests; // foreach (Chest c in chests) // { // ETGModConsole.Log($"Chest location: <color=#ff0000ff>{c.transform.position}</color>"); // } //}); ETGModConsole.Commands.GetGroup("ms").AddUnit("addteleporters", (string[] args) => { List <RoomHandler> rooms = GameManager.Instance.Dungeon.data.rooms; foreach (RoomHandler room in rooms) { try { room.AddProceduralTeleporterToRoom(); } catch (Exception) { //do nothing } } }); ETGModConsole.Commands.GetGroup("ms").AddUnit("visitallrooms", (string[] args) => { List <RoomHandler> rooms = GameManager.Instance.Dungeon.data.rooms; foreach (RoomHandler room in rooms) { room.visibility = RoomHandler.VisibilityStatus.VISITED; } Minimap.Instance.RevealAllRooms(true); }); ETGModConsole.Commands.GetGroup("ms").AddUnit("revealrooms", (string[] args) => { List <RoomHandler> rooms = GameManager.Instance.Dungeon.data.rooms; foreach (RoomHandler room in rooms) { Minimap.Instance.RevealAllRooms(true); } }); ETGModConsole.Commands.GetGroup("ms").AddUnit("getroomname", (string[] args) => { ETGModConsole.Log($"{GameManager.Instance.PrimaryPlayer.GetAbsoluteParentRoom().GetRoomName()}"); }); ETGModConsole.Commands.GetGroup("ms").AddUnit("loadsettings", (string[] args) => { LoadSettings(args[0]); }); ETGModConsole.Commands.GetGroup("ms").AddUnit("dropactives", (string[] args) => { foreach (PlayerItem i in GameManager.Instance.PrimaryPlayer.activeItems.ToList()) { GameManager.Instance.PrimaryPlayer.DropActiveItem(i); } }); ETGModConsole.Commands.GetGroup("ms").AddUnit("droppassives", (string[] args) => { foreach (PassiveItem i in GameManager.Instance.PrimaryPlayer.passiveItems.ToList()) { GameManager.Instance.PrimaryPlayer.DropPassiveItem(i); } }); ETGModConsole.Commands.GetGroup("ms").AddUnit("dropall", (string[] args) => { foreach (PassiveItem i in GameManager.Instance.PrimaryPlayer.passiveItems.ToList()) { GameManager.Instance.PrimaryPlayer.DropPassiveItem(i); } foreach (PlayerItem i in GameManager.Instance.PrimaryPlayer.activeItems.ToList()) { GameManager.Instance.PrimaryPlayer.DropActiveItem(i); } foreach (Gun i in GameManager.Instance.PrimaryPlayer.inventory.AllGuns.ToList()) { GameManager.Instance.PrimaryPlayer.ForceDropGun(i); } }); ETGModConsole.Commands.GetGroup("ms").AddUnit("clearall", (string[] args) => { GameManager.Instance.PrimaryPlayer.RemoveAllActiveItems(); GameManager.Instance.PrimaryPlayer.RemoveAllPassiveItems(); foreach (Gun i in GameManager.Instance.PrimaryPlayer.inventory.AllGuns.ToList()) { GameManager.Instance.PrimaryPlayer.ForceDropGun(i); } }); ETGModConsole.Commands.GetGroup("ms").AddUnit("clearactives", (string[] args) => { GameManager.Instance.PrimaryPlayer.RemoveAllActiveItems(); }); ETGModConsole.Commands.GetGroup("ms").AddUnit("clearpassives", (string[] args) => { GameManager.Instance.PrimaryPlayer.RemoveAllPassiveItems(); }); ETGModConsole.Commands.GetGroup("ms").AddUnit("dropguns", (string[] args) => { foreach (Gun i in GameManager.Instance.PrimaryPlayer.inventory.AllGuns.ToList()) { GameManager.Instance.PrimaryPlayer.ForceDropGun(i); } }); ETGModConsole.Commands.GetGroup("ms").AddUnit("charmall", (string[] args) => { if (args.Count() == 0 || args[0] == "true") { foreach (AIActor actor in StaticReferenceManager.AllEnemies) { //AkSoundEngine.PostEvent("Play_OBJ_enemy_charmed_01", GameManager.Instance.gameObject); AIActor aiactor = actor as AIActor; aiactor.CanTargetEnemies = true; aiactor.CanTargetPlayers = false; } } else if (args[0] == "false") { foreach (AIActor actor in StaticReferenceManager.AllEnemies) { //AkSoundEngine.PostEvent("Play_OBJ_enemy_charmed_01", GameManager.Instance.gameObject); AIActor aiactor = actor as AIActor; aiactor.CanTargetEnemies = false; aiactor.CanTargetPlayers = true; } } }); //ETGModConsole.Commands.GetGroup("ms").AddUnit("removeallcompanions", (string[] args) => //{ // //GameManager.Instance.PrimaryPlayer.companions.RemoveAll(AIActor); // GameManager.Instance.PrimaryPlayer.companions.Clear(); //}); ETGModConsole.Commands.GetGroup("ms").AddUnit("loadclipboard", (string[] args) => { if (args.Count() == 0) { LoadSettingsFromClipBoard(); } else { LoadSettingsFromClipBoard(args[0]); } ETGModConsole.Log("Loading settings from clipboard"); }); _GlitchSpawn = (args) => { if (_Chests.ContainsKey(args[0])) { Chest glitchedchest = _Chests[args[0]]; glitchedchest.ForceGlitchChest = true; glitchedchest.ForceUnlock(); glitchedchest.BecomeGlitchChest(); IntVector2 basePosition = new IntVector2((int)GameManager.Instance.PrimaryPlayer.transform.position.x, (int)GameManager.Instance.PrimaryPlayer.transform.position.y); Chest.Spawn(glitchedchest, basePosition); if (args.Count() == 2) { if (args[1] == "true") { ETGMod.Chest.OnPostOpen += glitchopen; } } } else { ETGModConsole.Log($"Please check your command and try again"); } }; _MsGroup = ETGModConsole.Commands.GetGroup("ms"); _SetGroup = _MsGroup.AddUnit("set", _StatSet, _AutocompletionSettings); _SetGroup = _MsGroup.AddUnit("get", _StatGet, _AutocompletionSettings); _SynergyChestGroup = _MsGroup.AddUnit("spawnglitched", _GlitchSpawn, _AutocompletionChests); _GetGroup = _MsGroup.AddUnit("getallstats", _StatGetAll, _AutocompletionSettings); _SetGroup = _MsGroup.AddUnit("getmagnificence", _MagnificenceGet, _AutocompletionSettings); _SetGroup = _MsGroup.AddUnit("setmagnificence", _MagnificenceSet, _AutocompletionSettings); }
public override void Start() { // GUI GUI = new SGroup { Visible = false, OnUpdateStyle = (SElement elem) => elem.Fill(), Children = { new SGroup { Background = new Color(0f, 0f, 0f, 0f), AutoLayout = (SGroup g) => g.AutoLayoutVertical, ScrollDirection = SGroup.EDirection.Vertical, OnUpdateStyle = delegate(SElement elem) { elem.Fill(); elem.Size -= new Vector2(0f, elem.Backend.LineHeight - 4f); // Command line input space }, Children = { new SLabel("ETGMod <color=#ffffffff>" + ETGMod.BaseUIVersion + "</color>") { Foreground = Color.gray }, new SLabel("Console backend <color=#ffffffff>R" + REVISION + "</color>") { Foreground = Color.gray }, new SLabel("THIS CONSOLE IS <color=#ff0000ff>WORK IN PROGRESS</color>."), new SLabel("Use <color=#ffffffff>help</color> to find out how to use the console.") { Foreground = Color.gray }, new SLabel(), //new SLabel("Wee this text gets randomized in order!") { // With = { // new SRandomLabelModifier() // } //}, // new SLabel(), } }, new STextField { OnUpdateStyle = delegate(SElement elem){ elem.Size.x = elem.Parent.InnerSize.x; elem.Position.x = 0f; elem.Position.y = elem.Parent.InnerSize.y - elem.Size.y; }, OnTextUpdate = delegate(STextField elem, string prevText){ HideAutocomplete(); }, OverrideTab = true, OnKey = delegate(STextField field, bool keyDown, KeyCode keyCode) { if (!keyDown) { return; } if (keyCode == KeyCode.Escape || keyCode == KeyCode.F2 || keyCode == KeyCode.Slash || keyCode == KeyCode.BackQuote) { ETGModGUI.CurrentMenu = ETGModGUI.MenuOpened.None; return; } if (keyCode == KeyCode.Tab) { ShowAutocomplete(); return; } }, OnSubmit = delegate(STextField elem, string text){ if (text.Length == 0) { return; } ParseCommand(text); if (_CloseConsoleOnCommand) { ETGModGUI.CurrentMenu = ETGModGUI.MenuOpened.None; } } } } }; // GLOBAL NAMESPACE Commands .AddUnit("help", delegate(string[] args) { List <List <string> > paths = Commands.ConstructPaths(); for (int i = 0; i < paths.Count; i++) { Log(string.Join(" ", paths[i].ToArray())); } }) .AddUnit("exit", (string[] args) => ETGModGUI.CurrentMenu = ETGModGUI.MenuOpened.None) .AddUnit("screenshake", SetShake) .AddUnit("echo", Echo) .AddUnit("tp", Teleport) .AddUnit("character", SwitchCharacter) .AddUnit("clear", (string[] args) => GUI[0].Children.Clear()) .AddUnit("godmode", godmode) // { // GameManager.Instance.PrimaryPlayer.healthHaver.IsVulnerable = SetBool(args, GameManager.Instance.PrimaryPlayer.healthHaver.IsVulnerable); // GameManager.Instance.PrimaryPlayer.healthHaver.IsVulnerable = SetBool(args, GameManager.Instance.PrimaryPlayer.healthHaver.IsVulnerable); delegate(string[] args // }) .AddGroup("spawn", Spawn, _SpawnAutocompletionSettings); // SPAWN NAMESAPCE Commands.GetGroup("spawn") .AddUnit("chest", SpawnChest) .AddUnit("all", SpawnAll); // GIVE NAMESPACE Commands.AddGroup("give", GiveItem, _GiveAutocompletionSettings); Commands.GetGroup("give") .AddGroup("all", (string[] args) => { foreach (string id in Game.Items.IDs) { if (id != "gungeon:cell_key" /* (bugged!) */) { Game.PrimaryPlayer.GiveItem(id); } } }); // GIVE ALL NAMESPACE Commands.GetGroup("give").GetGroup("all") .AddUnit("guns", (string[] args) => { foreach (string id in Game.Items.IDs) { if (ETGMod.Databases.Items[id] is Gun) { Game.PrimaryPlayer.GiveItem(id); } } }) .AddUnit("passives", (string[] args) => { foreach (string id in Game.Items.IDs) { if (ETGMod.Databases.Items[id] is PassiveItem) { Game.PrimaryPlayer.GiveItem(id); } } }) .AddUnit("actives", (string[] args) => { foreach (string id in Game.Items.IDs) { if (ETGMod.Databases.Items[id] is PlayerItem) { Game.PrimaryPlayer.GiveItem(id); } } }); // STAT NAMESPACE Commands.AddGroup("stat"); Commands.GetGroup("stat") .AddUnit("get", StatGet, _StatAutocompletionSettings) .AddGroup("set", StatSetCurrentCharacter, _StatAutocompletionSettings) .AddUnit("mod", StatMod, _StatAutocompletionSettings) .AddUnit("list", StatList); Commands.GetGroup("stat").GetGroup("set") .AddUnit("session", StatSetSession, _StatAutocompletionSettings); // ROLL NAMESPACE Commands.AddGroup("roll"); Commands.GetGroup("roll") .AddUnit("distance", DodgeRollDistance) .AddUnit("speed", DodgeRollSpeed); // TEST NAMESPACE Commands.AddUnit("test", new ConsoleCommandGroup()); Commands.GetGroup("test") .AddGroup("resources") .AddUnit("skiplevel", delegate(string[] args) { Pixelator.Instance.FadeToBlack(0.5f, false, 0f); GameManager.Instance.DelayedLoadNextLevel(0.5f); }).AddUnit("charselect", delegate(string[] args) { Pixelator.Instance.FadeToBlack(0.5f, false, 0f); GameManager.Instance.DelayedLoadCharacterSelect(0.5f); }); //// TEST.RESOURCES NAMESPACE Commands.GetGroup("test").GetGroup("resources") .AddUnit("load", ResourcesLoad); // DUMP NAMESPACE Commands.AddUnit("dump", new ConsoleCommandGroup()); Commands.GetGroup("dump") .AddGroup("sprites", (args) => SetBool(args, ref ETGMod.Assets.DumpSprites)) .AddUnit("packer", (args) => ETGMod.Assets.Dump.DumpPacker()) .AddUnit("synergies", DumpSynergies) .AddUnit("pickups", DumpPickups); Commands.GetGroup("dump").GetGroup("sprites") .AddUnit("metadata", (args) => SetBool(args, ref ETGMod.Assets.DumpSpritesMetadata)); // CONF NAMESPACE Commands.AddGroup("conf"); Commands.GetGroup("conf") .AddUnit("close_console_on_command", (args) => SetBool(args, ref _CloseConsoleOnCommand)) .AddUnit("cut_input_focus_on_command", (args) => SetBool(args, ref _CutInputFocusOnCommand)) .AddUnit("enable_damage_indicators", (args) => SetBool(args, ref ETGModGUI.UseDamageIndicators)) .AddUnit("match_contains", (args) => SetBool(args, ref AutocompletionSettings.MatchContains)) .AddUnit("enable_stat_set", (args) => SetBool(args, ref StatSetEnabled)) .AddUnit("player", (args) => ETGMod.Player.PlayerReplacement = args.Length == 1 ? args[0] : null) .AddUnit("player_coop", (args) => ETGMod.Player.CoopReplacement = args.Length == 1 ? args[0] : null); }