public void CanConvertMonthToYear() { var entry = new BudgetEntry(true, "Test", "Group", 1M, 1, Period.Month); var output = entry.ConvertTo(Period.Year); Assert.Equal(12M, output); }
public static void UpdateBudgetEntry(BudgetEntry budgetEntry) { using (var hdc = new HotelDataEntryDataContext()) { try { var entry = hdc.BudgetEntries.Single(item => item.BudgetId == budgetEntry.BudgetId); entry.OccupancyRoom = budgetEntry.OccupancyRoom; entry.RoomBudget = budgetEntry.RoomBudget; entry.FBBudget = budgetEntry.FBBudget; entry.SpaBudget = budgetEntry.SpaBudget; entry.Others = budgetEntry.Others; entry.Total = budgetEntry.Total; entry.UpdateDateTime = DateTime.Now; entry.UpdateUser = budgetEntry.UpdateUser; hdc.SubmitChanges(); } catch (SqlException ex) { if (ex.Number == 2601 || ex.Number == 2627) { throw; } } } }
public static void UpdateBudgetEntry(BudgetEntry budgetEntry) { using (var hdc = new HotelDataEntryDataContext()) { try { var entry = hdc.BudgetEntries.Single(item => item.BudgetId == budgetEntry.BudgetId); entry.OccupancyRoom = budgetEntry.OccupancyRoom; entry.RoomBudget = budgetEntry.RoomBudget; entry.FBBudget = budgetEntry.FBBudget; entry.SpaBudget = budgetEntry.SpaBudget; entry.Others = budgetEntry.Others; entry.Total = budgetEntry.Total; entry.UpdateDateTime = DateTime.Now; entry.UpdateUser = budgetEntry.UpdateUser; hdc.SubmitChanges(); } catch (SqlException ex) { if (ex.Number == 2601 || ex.Number == 2627) { throw; } } } }
public async Task <IActionResult> PutBudget([FromRoute] int id, [FromBody] BudgetEntry budget) { if (!ModelState.IsValid) { return(BadRequest(ModelState)); } if (id != budget.id) { return(BadRequest()); } _context.Entry(budget).State = EntityState.Modified; try { await _context.SaveChangesAsync(); } catch (DbUpdateConcurrencyException) { if (!BudgetExists(id)) { return(NotFound()); } else { throw; } } return(NoContent()); }
public static void SerializeBudgetEntry(EndianStream stream, BudgetEntry entry) { stream.WriteUInt32(entry.TagIndex); stream.WriteUInt8(entry.RuntimeMin); stream.WriteUInt8(entry.RuntimeMax); stream.WriteUInt8(entry.CountOnMap); stream.WriteUInt8(entry.DesignTimeMax); stream.WriteFloat(entry.Cost); }
public async Task <IActionResult> PostBudget([FromBody] BudgetEntry budget) { if (!ModelState.IsValid) { return(BadRequest(ModelState)); } _context.Budget.Add(budget); await _context.SaveChangesAsync(); return(CreatedAtAction("GetBudget", new { id = budget.id }, budget)); }
public static BudgetEntry DeserializeBudgetEntry(EndianStream stream) { var entry = new BudgetEntry(); entry.TagIndex = stream.ReadUInt32(); entry.RuntimeMin = stream.ReadUInt8(); entry.RuntimeMax = stream.ReadUInt8(); entry.CountOnMap = stream.ReadUInt8(); entry.DesignTimeMax = stream.ReadUInt8(); entry.Cost = stream.ReadFloat(); return(entry); }
public static BudgetEntry Deserialize(StreamHelper streamHelper) { var entry = new BudgetEntry(); entry.tagIndex = streamHelper.ReadInt32(); entry.runtimeMin = streamHelper.ReadUInt8(); entry.runtimeMax = streamHelper.ReadUInt8(); entry.countOnMap = streamHelper.ReadUInt8(); entry.designTimeMax = streamHelper.ReadUInt8(); entry.cost = streamHelper.ReadFloat(); return(entry); }
public async Task <IActionResult> OnGetAsync(int?id) { if (id == null) { return(NotFound()); } BudgetEntry = await _context.Budget .Include(b => b.Category).SingleOrDefaultAsync(m => m.ID == id); if (BudgetEntry == null) { return(NotFound()); } return(Page()); }
public IEnumerable <BudgetEntry> GetEntries(Stream stream) { using (var excelPackage = new ExcelPackage(stream)) { foreach (var worksheet in excelPackage.Workbook.Worksheets) { var categoryLookup = GetCategoryLookup(worksheet); var monthLookup = GetMonthLookup(worksheet); var year = Convert.ToInt32(worksheet.Name); for (var column = StartColumn; column <= EndColumn; column++) { if (!monthLookup.TryGetValue(column, out var month)) { continue; } for (var row = StartRow; row <= EndRow; row++) { if (!categoryLookup.TryGetValue(row, out var category)) { continue; } var cell = worksheet.Cells[row, column]; if (!(cell.Value is double amount)) { continue; } var entry = new BudgetEntry { Date = new DateTime(year, month, 1), Category = category, Currency = GetCurrency(cell.Text), Amount = Convert.ToDecimal(amount), IsCredit = CreditRows.Contains(row), Comments = GetComments(cell) }; yield return(entry); } } } } }
public async Task <IActionResult> OnPostAsync(int?id) { if (id == null) { return(NotFound()); } BudgetEntry = await _context.Budget.FindAsync(id); if (BudgetEntry != null) { _context.Budget.Remove(BudgetEntry); await _context.SaveChangesAsync(); } return(RedirectToPage("./Index")); }
public async Task <IActionResult> OnGetAsync(int?id) { if (id == null) { return(NotFound()); } BudgetEntry = await _context.Budget .Include(b => b.Category).SingleOrDefaultAsync(m => m.ID == id); if (BudgetEntry == null) { return(NotFound()); } ViewData["ApplicationUserID"] = new SelectList(_context.Set <ApplicationUser>(), "Id", "Id"); ViewData["CategoriesID"] = new SelectList(_context.Categories, "ID", "ID"); return(Page()); }
protected void JqGridDataEntry_RowEditing(object sender, JQGridRowEditEventArgs e) { var budgetEntryId = e.RowKey; var hotelEntryId = e.RowData["HotelEntryId"] == "" ? 0 : Convert.ToInt32(e.RowData["HotelEntryId"]); var roomBudget = string.IsNullOrEmpty(e.RowData["RoomBudget"]) ? 0.00 : Convert.ToDouble(e.RowData["RoomBudget"]); var fbBudget = string.IsNullOrEmpty(e.RowData["FBBudget"]) ? 0.00 : Convert.ToDouble(e.RowData["FBBudget"]); var spa = string.IsNullOrEmpty(e.RowData["SpaBudget"]) ? 0.00 : Convert.ToDouble(e.RowData["SpaBudget"]); var others = string.IsNullOrEmpty(e.RowData["Others"]) ? 0.00 : Convert.ToDouble(e.RowData["Others"]); var occupancyRoom = 0.0; if (string.IsNullOrEmpty(e.RowData["OccupancyRoom"])) { occupancyRoom = 0; } else { var strOccupancy = ""; strOccupancy = e.RowData["OccupancyRoom"].Contains("%") ? e.RowData["OccupancyRoom"].Remove(e.RowData["OccupancyRoom"].Length - 1, 1) : e.RowData["OccupancyRoom"]; occupancyRoom = Convert.ToDouble(strOccupancy); } var revenueEntry = new BudgetEntry() { BudgetId = Convert.ToInt32(budgetEntryId), HotelBudgetId = hotelEntryId, OccupancyRoom = occupancyRoom, RoomBudget = roomBudget, FBBudget = fbBudget, SpaBudget = spa, Others = others, UpdateUser = Session["UserSession"].ToString(), Total = roomBudget + fbBudget + spa + others }; BudgetHelper.UpdateBudgetEntry(revenueEntry); }
public static void ConvertUsermap(string srcFileName, string destFileName) { using (var srcStream = new EndianStream(File.Open(srcFileName, FileMode.Open, FileAccess.ReadWrite), EndianStream.EndianType.LittleEndian)) using (var outStream = new EndianStream(File.Open(destFileName, FileMode.Create, FileAccess.ReadWrite), EndianStream.EndianType.LittleEndian)) { SandboxMap srcMap = Usermap.DeserializeSandboxMap(srcStream); if (!File.Exists(GetCanvasFileName(srcMap.MapId))) { return; } using (var canvasStream = new EndianStream(File.OpenRead(GetCanvasFileName(srcMap.MapId)), EndianStream.EndianType.LittleEndian)) { var canvasMap = Usermap.DeserializeSandboxMap(canvasStream); var newBudgetEntries = new List <BudgetEntry>(); var newPlacements = new List <SandboxPlacement>(); for (int i = 0; i < 640; i++) { newPlacements.Add(canvasMap.Placements[i].Clone()); } for (int i = 0; i < srcMap.ScnrObjectCount; i++) { var srcPlacement = srcMap.Placements[i]; if (srcPlacement.BudgetIndex == -1) { continue; } var tagIndex = srcMap.Budget[srcPlacement.BudgetIndex].TagIndex; var newBudgetIndex = canvasMap.Budget.FindIndex(e => e.TagIndex == tagIndex); var substitutePlacements = canvasMap.Placements .Where((x, j) => (int)(newPlacements[j].PlacementFlags & (1 << 5)) != 0 && // deleted x.BudgetIndex == newBudgetIndex).ToList(); var newPlacementIndex2 = canvasMap.Placements.IndexOf(substitutePlacements.FirstOrDefault()); if (newPlacementIndex2 == -1) { continue; } newPlacements[newPlacementIndex2] = srcPlacement.Clone(); newPlacements[newPlacementIndex2].PlacementFlags |= (1 << 1); //touched } var newPlacementIndex = canvasMap.ScnrObjectCount; for (var i = srcMap.ScnrObjectCount; i < 640; i++, newPlacementIndex++) { var srcPlacement = srcMap.Placements[i]; if (srcPlacement.BudgetIndex == -1) { continue; } var tagIndex = srcMap.Budget[srcPlacement.BudgetIndex].TagIndex; var newBudgetIndex = canvasMap.Budget.FindIndex(e => e.TagIndex == tagIndex); if (newBudgetIndex == -1) { var n = newBudgetEntries.FindIndex(e => e.TagIndex == tagIndex); if (n == -1) { var entry = new BudgetEntry() { TagIndex = tagIndex, Cost = -1, RuntimeMin = 0, RuntimeMax = 0, CountOnMap = 0, DesignTimeMax = 0 }; newBudgetIndex = canvasMap.BudgetEntryCount + newBudgetEntries.Count(); newBudgetEntries.Add(entry); Console.WriteLine("injecting 0x{0} {1}", tagIndex.ToString("X"), newBudgetIndex); } else { newBudgetIndex = canvasMap.BudgetEntryCount + n; } } var newPlacement = newPlacements[newPlacementIndex] = srcPlacement.Clone(); newPlacement.BudgetIndex = newBudgetIndex; } canvasStream.SeekTo(0); canvasStream.Stream.CopyTo(outStream.Stream); outStream.SeekTo(0x30); srcStream.SeekTo(0x30); outStream.WriteBytes(srcStream.ReadBytes(0x108)); //chdr outStream.WriteBytes(srcStream.ReadBytes(0x140)); //map outStream.SeekTo(0x242); outStream.WriteInt16(canvasMap.ScnrObjectCount); outStream.WriteInt16((short)(canvasMap.ScnrObjectCount + (srcMap.TotalObjectCount - srcMap.ScnrObjectCount))); outStream.WriteInt16((short)(canvasMap.BudgetEntryCount + newBudgetEntries.Count + 1)); outStream.SeekTo(0x278); foreach (var placement in newPlacements) { Usermap.SerializePlacement(outStream, placement); } outStream.SeekTo(0xD498 + canvasMap.BudgetEntryCount * 0xc); foreach (var entry in newBudgetEntries) { Usermap.SerializeBudgetEntry(outStream, entry); } } } }
public string EditBudgetEntry(BudgetEntry inCategory) { SqlCommand command = CommonDAL.SetUpStoredProcedure(connection, "budget.UpdateBudgetEntry"); return("Edit Budget Entry"); }
public static MapVariant Deserialize(StreamHelper streamHelper) { MapVariant mapVariant = new MapVariant(); streamHelper.Skip(4); //mapVariant._blf = streamHelper.ReadInt32(); mapVariant.blfUnknown = streamHelper.ReadBytes(0x2C); streamHelper.Skip(4); //mapVariant.chdr = streamHelper.ReadInt32(); mapVariant.chdrHeaderUnknown1 = streamHelper.ReadBytes(0x14); mapVariant.chdrHeaderName = streamHelper.ReadUTF16(0x20); mapVariant.chdrHeaderDescription = streamHelper.ReadAscii(0x80); mapVariant.chdrHeaderAuthor = streamHelper.ReadAscii(0x10); mapVariant.chdrHeaderSize = streamHelper.ReadInt64(); mapVariant.chdrHeaderCreationDate = streamHelper.ReadInt64(); mapVariant.chdrHeaderUnknown2 = streamHelper.ReadInt64(); mapVariant.chdrHeaderUnknown3 = streamHelper.ReadInt32(); mapVariant.chdrHeaderUnknown4 = streamHelper.ReadInt32(); mapVariant.chdrHeaderUnknown5 = streamHelper.ReadInt32(); mapVariant.chdrHeaderUnknown6 = streamHelper.ReadInt32(); mapVariant.chdrHeaderMapID = streamHelper.ReadInt32(); mapVariant.chdrHeaderUnknown7 = streamHelper.ReadInt32(); mapVariant.chdrHeaderUnknown8 = streamHelper.ReadInt32(); mapVariant.chdrHeaderUnknown9 = streamHelper.ReadBytes(0xC); streamHelper.Skip(4);//mapVariant.mapv = streamHelper.ReadInt32(); mapVariant.mapvHeaderUnknown1 = streamHelper.ReadBytes(0x14); mapVariant.mapvHeaderName = streamHelper.ReadUTF16(0x20); mapVariant.mapvHeaderDescription = streamHelper.ReadAscii(0x80); mapVariant.mapvHeaderAuthor = streamHelper.ReadAscii(0x10); mapVariant.mapvHeaderSize = streamHelper.ReadInt64(); mapVariant.mapvHeaderCreationDate = streamHelper.ReadInt64(); mapVariant.mapvHeaderUnknown2 = streamHelper.ReadInt64(); mapVariant.mapvHeaderUnknown3 = streamHelper.ReadInt32(); mapVariant.mapvHeaderUnknown4 = streamHelper.ReadInt32(); mapVariant.mapvHeaderUnknown5 = streamHelper.ReadInt32(); mapVariant.mapvHeaderUnknown6 = streamHelper.ReadInt32(); mapVariant.mapvHeaderMapID = streamHelper.ReadInt32(); mapVariant.mapvHeaderUnknown7 = streamHelper.ReadInt32(); mapVariant.mapvHeaderUnknown8 = streamHelper.ReadInt32(); mapVariant.mapvHeaderUnknown9 = streamHelper.ReadBytes(0xC); mapVariant.scnrObjectsCount = streamHelper.ReadInt16(); mapVariant.totalObjectsCount = streamHelper.ReadInt16(); mapVariant.budgetEntriesCount = streamHelper.ReadInt16(); mapVariant.sandboxPlacementsCount = streamHelper.ReadInt16(); mapVariant.mapID = streamHelper.ReadInt32(); mapVariant.worldBoundsX = streamHelper.ReadVector2(); mapVariant.worldBoundsY = streamHelper.ReadVector2(); mapVariant.worldBoundsZ = streamHelper.ReadVector2(); mapVariant.unknown1 = streamHelper.ReadInt32(); mapVariant.maxBudget = streamHelper.ReadFloat(); mapVariant.currentBudget = streamHelper.ReadFloat(); mapVariant.unknown2 = streamHelper.ReadInt32(); mapVariant.unknown3 = streamHelper.ReadInt32(); mapVariant.sandboxPlacements = new List <SandboxPlacement>(); for (int i = 0; i < 640; i++) { mapVariant.sandboxPlacements.Add(SandboxPlacement.Deserialize(streamHelper)); } mapVariant.unknown4 = streamHelper.ReadBytes(0x38); mapVariant.budgetEntries = new List <BudgetEntry>(); for (int i = 0; i < 256; i++) { mapVariant.budgetEntries.Add(BudgetEntry.Deserialize(streamHelper)); } mapVariant.unknownPad = streamHelper.ReadBytes(0x140); streamHelper.Skip(4); //mapVariant._eof = streamHelper.ReadInt32(); mapVariant.unknown5 = streamHelper.ReadBytes(0xC); mapVariant.emptyPad = streamHelper.ReadBytes(0xE1C); return(mapVariant); }
public static void ConvertUsermap(string srcFileName, string destFileName) { var tagMap = LoadTagMap(); UsermapConversion.addStatus("Opening " + srcFileName); using (var srcStream = new EndianStream(File.Open(srcFileName, FileMode.Open, FileAccess.ReadWrite), EndianStream.EndianType.LittleEndian)) using (var outStream = new EndianStream(File.Open(destFileName, FileMode.Create, FileAccess.ReadWrite), EndianStream.EndianType.LittleEndian)) { SandboxMap srcMap = Usermap.DeserializeSandboxMap(srcStream); if (!File.Exists(GetCanvasFileName(srcMap.MapId))) { return; } using (var canvasStream = new EndianStream(File.OpenRead(GetCanvasFileName(srcMap.MapId)), EndianStream.EndianType.LittleEndian)) { var canvasMap = Usermap.DeserializeSandboxMap(canvasStream); var newBudgetEntries = new List <BudgetEntry>(); var newPlacements = new List <SandboxPlacement>(); for (int i = 0; i < 640; i++) { newPlacements.Add(canvasMap.Placements[i].Clone()); } UsermapConversion.addStatus("Source map has " + srcMap.ScnrObjectCount + " scenario objects"); // This first loop, I believe, is for so-called "scenario objects" for (int i = 0; i < srcMap.ScnrObjectCount; i++) { var srcPlacement = srcMap.Placements[i]; if (srcPlacement.BudgetIndex == -1) { continue; } var tagIndex = srcMap.Budget[srcPlacement.BudgetIndex].TagIndex; var tagIndexDiscarded = false; uint?newTagIndex; if (tagMap.TryGetValue(tagIndex, out newTagIndex)) // If the map contains this tagIndex, it means there was a change. If not, nevermind this, just move along. { if (newTagIndex.HasValue) // If new tag index isn't empty, it has to be mapped to a new value { UsermapConversion.addStatus(tagIndex.ToString("X") + " mapped to " + ((uint)newTagIndex).ToString("X")); tagIndex = (uint)newTagIndex; } else // Else it simply doesn't exist anymore and has to be discarded { UsermapConversion.addStatus(tagIndex.ToString("X") + " discarded"); tagIndexDiscarded = true; } } if (tagIndexDiscarded) { continue; } var newBudgetIndex = canvasMap.Budget.FindIndex(e => e.TagIndex == tagIndex); UsermapConversion.addStatus("SCENARIO OBJECT: Using new budget index " + newBudgetIndex + " (tagindex " + tagIndex.ToString("X") + ")"); var substitutePlacements = canvasMap.Placements .Where((x, j) => (int)(newPlacements[j].PlacementFlags & (1 << 5)) != 0 && // deleted x.BudgetIndex == newBudgetIndex).ToList(); var newPlacementIndex2 = canvasMap.Placements.IndexOf(substitutePlacements.FirstOrDefault()); if (newPlacementIndex2 == -1) { continue; } newPlacements[newPlacementIndex2] = srcPlacement.Clone(); newPlacements[newPlacementIndex2].PlacementFlags |= (1 << 1); //touched } var newPlacementIndex = canvasMap.ScnrObjectCount; short?emptyPlacementIndex = null; // If a placement index is unused, I can use it for the map options // This one is for the normal placements I believe for (var i = srcMap.ScnrObjectCount; i < 640; i++, newPlacementIndex++) { var srcPlacement = srcMap.Placements[i]; if (srcPlacement.BudgetIndex == -1) { if (!emptyPlacementIndex.HasValue) { emptyPlacementIndex = newPlacementIndex; UsermapConversion.addStatus("Unused placement index " + emptyPlacementIndex + " will be used for map options"); } continue; } var tagIndex = srcMap.Budget[srcPlacement.BudgetIndex].TagIndex; var tagIndexDiscarded = false; uint?newTagIndex; if (tagMap.TryGetValue(tagIndex, out newTagIndex)) // If the map contains this tagIndex, it means there was a change. If not, nevermind this, just move along. { if (newTagIndex.HasValue) // If new tag index isn't empty, it has to be mapped to a new value { UsermapConversion.addStatus(tagIndex.ToString("X") + " mapped to " + ((uint)newTagIndex).ToString("X")); tagIndex = (uint)newTagIndex; } else // Else it simply doesn't exist anymore and has to be discarded { UsermapConversion.addStatus(tagIndex.ToString("X") + " discarded"); tagIndexDiscarded = true; } } if (tagIndexDiscarded) { if (!emptyPlacementIndex.HasValue) { emptyPlacementIndex = newPlacementIndex; UsermapConversion.addStatus("Unused placement index " + emptyPlacementIndex + " will be used for map options"); } continue; } var newBudgetIndex = canvasMap.Budget.FindIndex(e => e.TagIndex == tagIndex); if (newBudgetIndex == -1) { var n = newBudgetEntries.FindIndex(e => e.TagIndex == tagIndex); if (n == -1) { var entry = new BudgetEntry() { TagIndex = tagIndex, Cost = 1, RuntimeMin = 0, RuntimeMax = 255, CountOnMap = 1, DesignTimeMax = 255 }; newBudgetIndex = canvasMap.BudgetEntryCount + newBudgetEntries.Count(); newBudgetEntries.Add(entry); UsermapConversion.addStatus("injecting 0x" + tagIndex.ToString("X") + " " + newBudgetIndex); Console.WriteLine("injecting 0x{0} {1}", tagIndex.ToString("X"), newBudgetIndex); } else { newBudgetIndex = canvasMap.BudgetEntryCount + n; UsermapConversion.addStatus("Changing count of newly injected tag by +1 to " + (++newBudgetEntries[n].CountOnMap).ToString() + ". Tagindex: " + newBudgetEntries[n].TagIndex.ToString("X") + " New Budget Index(on top of original budget): " + newBudgetIndex); } } else { UsermapConversion.addStatus("NON-SCENARIO OBJECT: Using new (already existing) budget index " + newBudgetIndex); } var newPlacement = newPlacements[newPlacementIndex] = srcPlacement.Clone(); newPlacement.BudgetIndex = newBudgetIndex; } // Copy over map options (hex tag index 5728) from the canvas map (necessary because of the map barriers, may be leading to crashes in out of bound maps) var mapOptionsTagIndex = uint.Parse("5728", NumberStyles.HexNumber); for (var i = 0; i < 640; i++) { var canvasPlacement = canvasMap.Placements[i]; if (canvasPlacement.BudgetIndex != -1) { var tagIndex = canvasMap.Budget[canvasPlacement.BudgetIndex].TagIndex; if (tagIndex == mapOptionsTagIndex) { if (emptyPlacementIndex.HasValue) { UsermapConversion.addStatus("Placing map options (0x5728) with disabled barriers in placement index " + emptyPlacementIndex); newPlacements[(int)emptyPlacementIndex] = canvasPlacement.Clone(); } else { // There is no space to place map options. Sucks. Will either have to overwrite one element or ditch them. } } } } canvasStream.SeekTo(0); canvasStream.Stream.CopyTo(outStream.Stream); outStream.SeekTo(0x30); srcStream.SeekTo(0x30); outStream.WriteBytes(srcStream.ReadBytes(0x108)); //chdr outStream.WriteBytes(srcStream.ReadBytes(0x140)); //map outStream.SeekTo(0x242); outStream.WriteInt16(canvasMap.ScnrObjectCount); outStream.WriteInt16((short)(canvasMap.ScnrObjectCount + (srcMap.TotalObjectCount - srcMap.ScnrObjectCount))); outStream.WriteInt16((short)(canvasMap.BudgetEntryCount + newBudgetEntries.Count + 1)); outStream.SeekTo(0x278); foreach (var placement in newPlacements) { Usermap.SerializePlacement(outStream, placement); } outStream.SeekTo(0xD498 + canvasMap.BudgetEntryCount * 0xc); foreach (var entry in newBudgetEntries) { Usermap.SerializeBudgetEntry(outStream, entry); } } } }
public static void RemoveInvisSpawns(string srcFileName, string destFileName) { var tagMap = LoadTagMap(); UsermapConversion.addStatus("Opening " + srcFileName); using (var srcStream = new EndianStream(File.Open(srcFileName, FileMode.Open, FileAccess.ReadWrite), EndianStream.EndianType.LittleEndian)) using (var outStream = new EndianStream(File.Open(destFileName, FileMode.Create, FileAccess.ReadWrite), EndianStream.EndianType.LittleEndian)) { SandboxMap srcMap = Usermap.DeserializeSandboxMap(srcStream); if (!File.Exists(GetCanvasFileName(srcMap.MapId))) { return; } using (var canvasStream = new EndianStream(File.OpenRead(GetCanvasFileName(srcMap.MapId)), EndianStream.EndianType.LittleEndian)) { var canvasMap = Usermap.DeserializeSandboxMap(canvasStream); UsermapConversion.addStatus("Map has a " + srcMap.TotalObjectCount + " total objects and " + srcMap.BudgetEntryCount + " budget entries and " + srcMap.ScnrObjectCount + " scenario objects"); var newBudgetEntries = new List <BudgetEntry>(); var newPlacements = new List <SandboxPlacement>(); var totalObjectCount = srcMap.TotalObjectCount; var budgetEntryCount = srcMap.BudgetEntryCount; // copy everything 1:1, then remove invis spawns for (int i = 0; i < 640; i++) { newPlacements.Add(srcMap.Placements[i].Clone()); } for (int i = 0; i < 256; i++) { newBudgetEntries.Add(srcMap.Budget[i].Clone()); } // Find empty placement from canvasMap to use for replacing the invis spawn placements var placementFlagsForRemovedInvisSpawns = ushort.Parse("29", NumberStyles.HexNumber); SandboxPlacement emptyPlacement = null; for (int i = 0; i < 640; i++) { var canvasPlacement = canvasMap.Placements[i]; //UsermapConversion.addStatus(canvasPlacement.PlacementFlags.ToString("X") + " " + canvasPlacement.Unknown_1.ToString("X") + " " + canvasPlacement.ObjectDatumHandle.ToString("X") + " " + canvasPlacement.GizmoDatumHandle.ToString("X") + " " + canvasPlacement.BudgetIndex + " " + canvasPlacement.Unknown_2.ToString("X") + " " + canvasPlacement.Unknown_3.ToString("X") + " " + canvasPlacement.EngineFlags.ToString("X") + " " + canvasPlacement.Flags.ToString("X") + " " + canvasPlacement.Team + " " + canvasPlacement.Extra + " " + canvasPlacement.RespawnTime + " " + canvasPlacement.ObjectType + " " + canvasPlacement.ZoneShape + " " + canvasPlacement.ZoneRadiusWidth + " " + canvasPlacement.ZoneDepth + " " + canvasPlacement.ZoneTop + " " + canvasPlacement.ZoneBottom + " " + +i); //UsermapConversion.addStatus(canvasPlacement.PlacementFlags.ToString("X") + " " + canvasPlacement.Unknown_1.ToString("X") + " " + canvasPlacement.ObjectDatumHandle.ToString("X") + " " + canvasPlacement.GizmoDatumHandle.ToString("X") + " " + canvasPlacement.BudgetIndex + " " + canvasPlacement.Position + " " + canvasPlacement.RightVector + " " + canvasPlacement.UpVector + " " + canvasPlacement.Unknown_2.ToString("X") + " " + canvasPlacement.Unknown_3.ToString("X") + " " + canvasPlacement.EngineFlags.ToString("X") + " " + canvasPlacement.Flags.ToString("X") + " " + canvasPlacement.Team + " " + canvasPlacement.Extra + " " + canvasPlacement.RespawnTime + " " + canvasPlacement.ObjectType + " " + canvasPlacement.ZoneShape + " " + canvasPlacement.ZoneRadiusWidth + " " + canvasPlacement.ZoneDepth + " " + canvasPlacement.ZoneTop + " " + canvasPlacement.ZoneBottom + " " + + i); if (canvasPlacement.BudgetIndex == -1 && placementFlagsForRemovedInvisSpawns == canvasPlacement.PlacementFlags) // this is to find empty placements. The first objects in each file have a placementflags set to 29 (hex), despite budgetindex being -1. I am not yet sure which one is needed moar here, I'll go with the default empty one for now { UsermapConversion.addStatus("Empty reference placement found at index " + i); UsermapConversion.addStatus(canvasPlacement.PlacementFlags.ToString("X") + " " + canvasPlacement.Unknown_1.ToString("X") + " " + canvasPlacement.ObjectDatumHandle.ToString("X") + " " + canvasPlacement.GizmoDatumHandle.ToString("X") + " " + canvasPlacement.BudgetIndex + " " + canvasPlacement.Unknown_2.ToString("X") + " " + canvasPlacement.Unknown_3.ToString("X") + " " + canvasPlacement.EngineFlags.ToString("X") + " " + canvasPlacement.Flags.ToString("X") + " " + canvasPlacement.Team + " " + canvasPlacement.Extra + " " + canvasPlacement.RespawnTime + " " + canvasPlacement.ObjectType + " " + canvasPlacement.ZoneShape + " " + canvasPlacement.ZoneRadiusWidth + " " + canvasPlacement.ZoneDepth + " " + canvasPlacement.ZoneTop + " " + canvasPlacement.ZoneBottom + " " + +i); emptyPlacement = canvasPlacement.Clone(); break; } } var emptyBudgetEntry = new BudgetEntry() // Values found by analyzing actual empty entries in sandbox.map files { TagIndex = 0xFFFFFFFF, RuntimeMin = 0, RuntimeMax = 0, CountOnMap = 0, DesignTimeMax = 255, Cost = -1 }; /*for (int i = 0; i < 256; i++) * { * var canvasBudgetEntry = canvasMap.Budget[i]; * UsermapConversion.addStatus(canvasBudgetEntry.TagIndex.ToString("X")+" "+canvasBudgetEntry.RuntimeMin + " " + canvasBudgetEntry.RuntimeMax + " " + canvasBudgetEntry.CountOnMap + " " + canvasBudgetEntry.DesignTimeMax + " " + canvasBudgetEntry.Cost+ " " + i); * }*/ var invisSpawnTagIndex = uint.Parse("2EA6", NumberStyles.HexNumber); for (int i = 0; i < 640; i++) { var placement = newPlacements[i]; if (placement.BudgetIndex == -1) { continue; } if (newBudgetEntries.ElementAtOrDefault(placement.BudgetIndex) != null) { var tagIndex = newBudgetEntries[placement.BudgetIndex].TagIndex; if (tagIndex == invisSpawnTagIndex) { UsermapConversion.addStatus("Found invisible spawn at placement index " + i + ", budget index " + placement.BudgetIndex + ", removing now. Likely remaining invis spawn points: " + newBudgetEntries[placement.BudgetIndex].CountOnMap--); //totalObjectCount--; // Don't reduce total object count, as apparently it isn't really influenced by how many objects are actually spawned. Weird as it sounds. Or maybe it just isn't influenced by these invis spawns. Either way, better withotu changing it for now. newPlacements[i] = emptyPlacement.Clone(); } } } for (int i = 0; i < 256; i++) { var budgetEntry = newBudgetEntries[i]; if (budgetEntry.TagIndex == invisSpawnTagIndex) { newBudgetEntries[i] = emptyBudgetEntry.Clone(); //budgetEntryCount--; // Let's try not changing it once. } } srcStream.SeekTo(0); srcStream.Stream.CopyTo(outStream.Stream); outStream.SeekTo(0x30); srcStream.SeekTo(0x30); outStream.WriteBytes(srcStream.ReadBytes(0x108)); //chdr outStream.WriteBytes(srcStream.ReadBytes(0x140)); //map outStream.SeekTo(0x242); outStream.WriteInt16(srcMap.ScnrObjectCount); outStream.WriteInt16((short)totalObjectCount); outStream.WriteInt16((short)budgetEntryCount); outStream.SeekTo(0x278); foreach (var placement in newPlacements) { Usermap.SerializePlacement(outStream, placement); } outStream.SeekTo(0xD498); foreach (var entry in newBudgetEntries) { Usermap.SerializeBudgetEntry(outStream, entry); } } } }
// Budget Entries public string AddBudgetEntry(BudgetEntry inEntry) { SqlCommand command = CommonDAL.SetUpStoredProcedure(connection, "budget.InsertBudgetEntry"); return("Add Budget Entry"); }