public void ReassignGUIDs(string GUID, uint ObjectIndex) { int eventIdx = (int)Enum.Parse(typeof(EventType), "Collision"); for (var i = 0; i < Data.GameObjects.Count; i++) { UndertaleGameObject obj = Data.GameObjects[i]; try { foreach (UndertaleGameObject.Event evnt in obj.Events[eventIdx]) { foreach (UndertaleGameObject.EventAction action in evnt.Actions) { if (action.CodeId.Name.Content.Contains(GUID)) { evnt.EventSubtype = ObjectIndex; } } } } catch { // Silently ignore, some values can be null along the way } } }
public List <uint> GetCollisionValueFromCodeNameGUID(string codeName) { int eventIdx = (int)Enum.Parse(typeof(EventType), "Collision"); List <uint> possible_values = new List <uint>(); for (var i = 0; i < Data.GameObjects.Count; i++) { UndertaleGameObject obj = Data.GameObjects[i]; try { foreach (UndertaleGameObject.Event evnt in obj.Events[eventIdx]) { foreach (UndertaleGameObject.EventAction action in evnt.Actions) { if (action.CodeId.Name.Content == codeName) { if (Data.GameObjects[(int)evnt.EventSubtype] != null) { possible_values.Add(evnt.EventSubtype); return(possible_values); } } } } } catch { // Silently ignore, some values can be null along the way } } possible_values = GetCollisionValueFromGUID(GetGUIDFromCodeName(codeName)); return(possible_values); }
private void Canvas_Drop(object sender, DragEventArgs e) { UndertaleObject sourceItem = e.Data.GetData(e.Data.GetFormats()[e.Data.GetFormats().Length - 1]) as UndertaleObject; e.Effects = e.AllowedEffects.HasFlag(DragDropEffects.Link) && sourceItem != null && (sourceItem is UndertaleGameObject || sourceItem is UndertalePath) ? DragDropEffects.Link : DragDropEffects.None; if (e.Effects == DragDropEffects.Link) { if (sourceItem is UndertaleGameObject) { UndertaleGameObject droppedObject = sourceItem as UndertaleGameObject; var mousePos = e.GetPosition(RoomGraphics); UndertaleRoom room = this.DataContext as UndertaleRoom; var obj = new UndertaleRoom.GameObject() { X = (int)mousePos.X, Y = (int)mousePos.Y, ObjectDefinition = droppedObject, InstanceID = (Application.Current.MainWindow as MainWindow).Data.GeneralInfo.LastObj++ }; room.GameObjects.Add(obj); SelectObject(obj); } if (sourceItem is UndertalePath) { PreviewPath = sourceItem as UndertalePath; } } e.Handled = true; }
private void Canvas_Drop(object sender, DragEventArgs e) { UndertaleObject sourceItem = e.Data.GetData(e.Data.GetFormats()[e.Data.GetFormats().Length - 1]) as UndertaleObject; e.Effects = e.AllowedEffects.HasFlag(DragDropEffects.Link) && sourceItem != null && (sourceItem is UndertaleGameObject || sourceItem is UndertalePath) ? DragDropEffects.Link : DragDropEffects.None; if (e.Effects == DragDropEffects.Link) { if (sourceItem is UndertaleBackground) { } else if (sourceItem is UndertaleGameObject) { UndertaleGameObject droppedObject = sourceItem as UndertaleGameObject; var mousePos = e.GetPosition(RoomGraphics); UndertaleRoom room = this.DataContext as UndertaleRoom; UndertaleRoom.Layer layer = ObjectEditor.Content as UndertaleRoom.Layer; if ((Application.Current.MainWindow as MainWindow).IsGMS2 == Visibility.Visible && layer == null) { MessageBox.Show("Must have a layer selected", "UndertaleModTool", MessageBoxButton.OK, MessageBoxImage.Error); return; } if (layer != null && layer.InstancesData == null) { MessageBox.Show("Must be on an instances layer", "UndertaleModTool", MessageBoxButton.OK, MessageBoxImage.Error); return; } var obj = new UndertaleRoom.GameObject() { X = (int)mousePos.X, Y = (int)mousePos.Y, ObjectDefinition = droppedObject, InstanceID = (Application.Current.MainWindow as MainWindow).Data.GeneralInfo.LastObj++ }; room.GameObjects.Add(obj); if (layer != null) { layer.InstancesData.Instances.Add(obj); } SelectObject(obj); } if (sourceItem is UndertalePath) { PreviewPath = sourceItem as UndertalePath; } } e.Handled = true; (this.DataContext as UndertaleRoom)?.SetupRoom(); }
/// <summary> /// Replaces the enemies with a random version provided that enemy is safe to replace /// </summary> static void ReplaceEnemies() { Console.WriteLine("Replacing enemies"); var blockingList = new List <Pair <string, ObjDesc> >(); foreach (UndertaleRoom room in data.Rooms) { if (!ignoredRooms.Contains(room.Name.Content)) { foreach (var obj in room.GameObjects) { if (enemyDefs.ContainsKey(obj.ObjectDefinition.Name.Content)) { if (HasBlockedEnemyInRoom(room.Name.Content)) { if (blockingList.Count == 0) { blockingList = blockedEnemies.FindAll(s => s.First == room.Name.Content); } if (IsBlockedObject(blockingList, obj)) { continue; } } if (stairRooms.Contains(room.Name.Content)) { UndertaleGameObject chosen = ChooseEnemy(); if (chosen.Name.Content == "obj_enemy_sci") { obj.ObjectDefinition = enemyDefs["obj_enemy_cop"]; } else { obj.ObjectDefinition = chosen; } } else { obj.ObjectDefinition = ChooseEnemy(); } } else if (hardmodeEnemyDefs.ContainsKey(obj.ObjectDefinition.Name.Content)) { obj.ObjectDefinition = ChooseEnemyHard(); } } } blockingList.Clear(); } }
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { uint val = System.Convert.ToUInt32(value); UndertaleGameObject returnObj = null; if (val < (Application.Current.MainWindow as MainWindow).Data.GameObjects.Count) { returnObj = (Application.Current.MainWindow as MainWindow).Data.GameObjects[(int)val]; return(returnObj); } else { return(returnObj); } }
public List <uint> GetCollisionValueFromGUID(string guid) { int eventIdx = (int)Enum.Parse(typeof(EventType), "Collision"); List <uint> possibleValues = new List <uint>(); for (var i = 0; i < Data.GameObjects.Count; i++) { UndertaleGameObject obj = Data.GameObjects[i]; try { foreach (UndertaleGameObject.Event evnt in obj.Events[eventIdx]) { foreach (UndertaleGameObject.EventAction action in evnt.Actions) { if (action.CodeId.Name.Content.Contains(guid)) { if (!possibleValues.Contains(evnt.EventSubtype)) { possibleValues.Add(evnt.EventSubtype); } } } } } catch { // Silently ignore, some values can be null along the way } } if (possibleValues.Count == 0) { possibleValues.Add(uint.MaxValue); return(possibleValues); } else { return(possibleValues); } }
public static void ClockPatches(UndertaleData data) { UndertaleGameObject go = new UndertaleGameObject(); go.Name = data.Strings.MakeString("obj_clock"); go.Sprite = null; go.Persistent = true; go.CollisionShape = 0; go.Depth = -1; go.Awake = true; go.Visible = true; CreateEvent(RabbitRunCode.coinstants, data, go, EventType.Create, 0u); CreateEvent(RabbitRunCode.yote, data, go, EventType.Other, (uint)EventSubtypeOther.RoomEnd); CreateEvent(RabbitRunCode.rabstart, data, go, EventType.Other, (uint)EventSubtypeOther.RoomStart); CreateEvent(RabbitRunCode.constantDrawer, data, go, EventType.Draw, (uint)EventSubtypeDraw.DrawGUIEnd); CreateEvent(RabbitRunCode.constantStepper, data, go, EventType.Step, (uint)EventSubtypeStep.Step); CreateEvent(RabbitRunCode.doneThisShit, data, go, EventType.Other, (uint)EventSubtypeOther.User0); data.GameObjects.Add(go); data.Code.ByName("gml_Script_pausegame").AppendGML("instance_activate_object(obj_clock);", data); UndertaleCode c = data.Code.ByName("gml_Script_goto_mainmenu"); c.AppendGML(RabbitRunCode.gohomebyebye, data); UndertaleCode endingCutscene = data.Code.ByName("gml_RoomCC_rm_n4_760_Create"); ReplaceInGML("t_scene_info = [", @"t_scene_info = [[cutscene_checkiflist, obj_constant.flagList, 191, 1, 1],[cutscene_activate_userevent, obj_clock,0],", data.Code.ByName("gml_RoomCC_rm_n4_760_Create"), data); ReplaceInGML("t_scene_info = [", @"t_scene_info = [[cutscene_activate_userevent, obj_clock,0],", data.Code.ByName("gml_RoomCC_rm_n5_33_Create"), data); var house = data.Rooms.ByName("rm_init"); UndertaleRoom.GameObject rogo = new UndertaleRoom.GameObject { ObjectDefinition = go, InstanceID = 108990u, GMS2_2_2 = true }; house.GameObjects.Add(rogo); house.Layers.Single((layer) => layer.LayerName.Content == "Instances").InstancesData.Instances.Add(rogo); }
void ImportCode(string codeName, string gmlCode, bool IsGML = true, bool doParse = true, bool destroyASM = true, bool CheckDecompiler = false) { bool SkipPortions = false; UndertaleCode code = Data.Code.ByName(codeName); if (Data.Code.ByName(codeName) == null) { code = new UndertaleCode(); code.Name = Data.Strings.MakeString(codeName); Data.Code.Add(code); } if (Data?.GeneralInfo.BytecodeVersion > 14 && Data.CodeLocals.ByName(codeName) == null) { UndertaleCodeLocals locals = new UndertaleCodeLocals(); locals.Name = code.Name; UndertaleCodeLocals.LocalVar argsLocal = new UndertaleCodeLocals.LocalVar(); argsLocal.Name = Data.Strings.MakeString("arguments"); argsLocal.Index = 0; locals.Locals.Add(argsLocal); code.LocalsCount = 1; code.GenerateLocalVarDefinitions(code.FindReferencedLocalVars(), locals); // Dunno if we actually need this line, but it seems to work? Data.CodeLocals.Add(locals); } if (doParse) { // This portion links code. if (codeName.Substring(0, 10).Equals("gml_Script")) { // Add code to scripts section. if (Data.Scripts.ByName(codeName.Substring(11)) == null) { UndertaleScript scr = new UndertaleScript(); scr.Name = Data.Strings.MakeString(codeName.Substring(11)); scr.Code = code; Data.Scripts.Add(scr); } else { UndertaleScript scr = Data.Scripts.ByName(codeName.Substring(11)); scr.Code = code; } } else if (codeName.Substring(0, 16).Equals("gml_GlobalScript")) { // Add code to global init section. UndertaleGlobalInit init_entry = null; // This doesn't work, have to do it the hard way: UndertaleGlobalInit init_entry = Data.GlobalInitScripts.ByName(scr_dup_code_name_con); foreach (UndertaleGlobalInit globalInit in Data.GlobalInitScripts) { if (globalInit.Code.Name.Content == codeName) { init_entry = globalInit; break; } } if (init_entry == null) { UndertaleGlobalInit NewInit = new UndertaleGlobalInit(); NewInit.Code = code; Data.GlobalInitScripts.Add(NewInit); } else { UndertaleGlobalInit NewInit = init_entry; NewInit.Code = code; } } else if (codeName.Substring(0, 10).Equals("gml_Object")) { string afterPrefix = codeName.Substring(11); int underCount = 0; string methodNumberStr = "", methodName = "", objName = ""; for (int i = afterPrefix.Length - 1; i >= 0; i--) { if (afterPrefix[i] == '_') { underCount++; if (underCount == 1) { methodNumberStr = afterPrefix.Substring(i + 1); } else if (underCount == 2) { objName = afterPrefix.Substring(0, i); methodName = afterPrefix.Substring(i + 1, afterPrefix.Length - objName.Length - methodNumberStr.Length - 2); break; } } } int methodNumber = 0; try { methodNumber = int.Parse(methodNumberStr); if (methodName == "Collision" && (methodNumber >= Data.GameObjects.Count || methodNumber < 0)) { bool doNewObj = ScriptQuestion("Object of ID " + methodNumber.ToString() + " was not found.\nAdd new object?"); if (doNewObj) { UndertaleGameObject gameObj = new UndertaleGameObject(); gameObj.Name = Data.Strings.MakeString(SimpleTextInput("Enter object name", "Enter object name", "This is a single text line input box test.", false)); Data.GameObjects.Add(gameObj); } else { // It *needs* to have a valid value, make the user specify one. List <uint> possible_values = new List <uint>(); possible_values.Add(uint.MaxValue); methodNumber = (int)ReduceCollisionValue(possible_values); } } } catch { if (afterPrefix.LastIndexOf("_Collision_") != -1) { string s2 = "_Collision_"; objName = afterPrefix.Substring(0, (afterPrefix.LastIndexOf("_Collision_"))); methodNumberStr = afterPrefix.Substring(afterPrefix.LastIndexOf("_Collision_") + s2.Length, afterPrefix.Length - (afterPrefix.LastIndexOf("_Collision_") + s2.Length)); methodName = "Collision"; // GMS 2.3+ use the object name for the one colliding, which is rather useful. if (Data.GMS2_3) { if (Data.GameObjects.ByName(methodNumberStr) != null) { for (var i = 0; i < Data.GameObjects.Count; i++) { if (Data.GameObjects[i].Name.Content == methodNumberStr) { methodNumber = i; break; } } } else { bool doNewObj = ScriptQuestion("Object " + objName + " was not found.\nAdd new object called " + objName + "?"); if (doNewObj) { UndertaleGameObject gameObj = new UndertaleGameObject(); gameObj.Name = Data.Strings.MakeString(objName); Data.GameObjects.Add(gameObj); } } if (Data.GameObjects.ByName(methodNumberStr) != null) { // It *needs* to have a valid value, make the user specify one, silly. List <uint> possible_values = new List <uint>(); possible_values.Add(uint.MaxValue); ReassignGUIDs(methodNumberStr, ReduceCollisionValue(possible_values)); } } else { // Let's try to get this going methodNumber = (int)ReduceCollisionValue(GetCollisionValueFromCodeNameGUID(codeName)); ReassignGUIDs(methodNumberStr, ReduceCollisionValue(GetCollisionValueFromCodeNameGUID(codeName))); } } } UndertaleGameObject obj = Data.GameObjects.ByName(objName); if (obj == null) { bool doNewObj = ScriptQuestion("Object " + objName + " was not found.\nAdd new object called " + objName + "?"); if (doNewObj) { UndertaleGameObject gameObj = new UndertaleGameObject(); gameObj.Name = Data.Strings.MakeString(objName); Data.GameObjects.Add(gameObj); } else { SkipPortions = true; } } if (!(SkipPortions)) { obj = Data.GameObjects.ByName(objName); int eventIdx = (int)Enum.Parse(typeof(EventTypes), methodName); bool duplicate = false; try { foreach (UndertaleGameObject.Event evnt in obj.Events[eventIdx]) { foreach (UndertaleGameObject.EventAction action in evnt.Actions) { if (action.CodeId?.Name?.Content == codeName) { duplicate = true; } } } } catch { // Something went wrong, but probably because it's trying to check something non-existent // Just keep going } if (duplicate == false) { UndertalePointerList <UndertaleGameObject.Event> eventList = obj.Events[eventIdx]; UndertaleGameObject.EventAction action = new UndertaleGameObject.EventAction(); UndertaleGameObject.Event evnt = new UndertaleGameObject.Event(); action.ActionName = code.Name; action.CodeId = code; evnt.EventSubtype = (uint)methodNumber; evnt.Actions.Add(action); eventList.Add(evnt); } } } } SafeImport(codeName, gmlCode, IsGML, destroyASM, CheckDecompiler); }
public static void CreateEvent(string gml, UndertaleData data, UndertaleGameObject obj, EventType type, uint subtype) { UndertaleCode c = obj.EventHandlerFor(type, subtype, data.Strings, data.Code, data.CodeLocals); c.ReplaceGML(gml, data); }