public CommonResponse UpdateLostThingRecord(LostThingsRecord ChangedRecord) { if (ChangedRecord == null) { return(new CommonResponse() { StatusCode = 1504 }); } // 首先检查待更新的对象在数据库中是否存在旧对象 var RecordGUID = ChangedRecord.Id; var OldRecord = thing.GetLostThingsRecord(RecordGUID); if (OldRecord == null) { return(new CommonResponse() { StatusCode = 1501 }); } else { // 然后检查新对象是否修改了不应该修改的Field。 bool UnchangedValidation = ThingHelper.EnsureNotModifyFieldsUnchanged(OldRecord, ChangedRecord); if (!UnchangedValidation) { return(new CommonResponse() { StatusCode = 1502 }); } else { // 校验成功之后,合并新旧对象的Fields,向数据库中写入。 OldRecord.MergeLostThingsRecord(ChangedRecord); if (thing.UpdateLostThingRecord(OldRecord)) { return new CommonResponse() { StatusCode = 0 } } ; else { return new CommonResponse() { StatusCode = 1503 } }; } } }
// NOTe: may need a new TraverseParms object public ThingPath FindPath(IntVec3 start, LocalTargetInfo dest, TraverseParms traverseParms, PathEndMode peMode = PathEndMode.OnCell) { if (DebugSettings.pathThroughWalls) { traverseParms.mode = TraverseMode.PassAllDestroyableThings; } Thing thing = traverseParms.thing; /* * if (pawn != null && pawn.Map != this.map) * { * Log.Error(string.Concat(new object[] * { * "Tried to FindPath for pawn which is spawned in another map. His map PathFinder should have been used, not this one. pawn=", * pawn, * " pawn.Map=", * pawn.Map, * " map=", * this.map * })); * return ThingPath.NotFound; * }*/ if (!start.IsValid) { // TODO: thing goes here Log.Error($"Tried to FindPath with invalid start {start}, thing = "); return(ThingPath.NotFound); } if (!dest.IsValid) { Log.Error($"Tried to FindPath with invalid dest {start}, thing = "); return(ThingPath.NotFound); } /*if (traverseParms.mode == TraverseMode.ByPawn) * { * if (!pawn.CanReach(dest, peMode, Danger.Deadly, traverseParms.canBash, traverseParms.mode)) * return PawnPath.NotFound; * } * else*/ if (!this.map.reachability.CanReach(start, dest, peMode, traverseParms)) { return(ThingPath.NotFound); } this.cellIndices = this.map.cellIndices; this.pathGrid = this.map.pathGrid; this.edificeGrid = this.map.edificeGrid.InnerArray; int x = dest.Cell.x; int z = dest.Cell.z; int num = this.cellIndices.CellToIndex(start); int num2 = this.cellIndices.CellToIndex(dest.Cell); // TODO: avoidgrid //ByteGrid byteGrid = (pawn == null) ? null : pawn.GetAvoidGrid(); bool passAllDestroyableThings = traverseParms.mode == TraverseMode.PassAllDestroyableThings; bool doNotPassAllDestroyableThings = !passAllDestroyableThings; CellRect cellRect = this.CalculateDestinationRect(dest, peMode); bool flag3 = cellRect.Width == 1 && cellRect.Height == 1; int[] array = this.map.pathGrid.pathGrid; EdificeGrid edificeGrid = this.map.edificeGrid; int cellsSearched = 0; int num4 = 0; // TODO: allowedArea //Area allowedArea = this.GetAllowedArea(pawn); // TODO: ShouldCollideWithThings //bool flag4 = pawn != null && PawnUtility.ShouldCollideWithPawns(pawn); bool drawPaths = DebugViewSettings.drawPaths; bool flag6 = !passAllDestroyableThings && start.GetRegion(this.map, RegionType.Set_Passable) != null; bool flag7 = !passAllDestroyableThings || !doNotPassAllDestroyableThings; bool flag8 = false; int num5 = 0; int num6 = 0; float heuristicStrength = 1.75f; //float num7 = this.DetermineHeuristicStrength(pawn, start, dest); int ticksPerMoveCardinal; int ticksPerMoveDiagonal; // TODO: handle ticks per move /*if (pawn != null) * { * ticksPerMoveCardinal = pawn.TicksPerMoveCardinal; * ticksPerMoveDiagonal = pawn.TicksPerMoveDiagonal; * } * else*/ { ticksPerMoveCardinal = 13; ticksPerMoveDiagonal = 18; } this.CalculateAndAddDisallowedCorners(traverseParms, peMode, cellRect); this.InitStatusesAndPushStartNode(ref num, start); while (true) { if (this.openList.Count <= 0) { break; } num5 += this.openList.Count; num6++; ThingPathFinder.CostNode costNode = this.openList.Pop(); num = costNode.index; // TODO: cleanup if (costNode.cost != this.calcGrid[num].costNodeCost) { } else if (this.calcGrid[num].status == this.statusClosedValue) { } else { IntVec3 c = this.cellIndices.IndexToCell(num); int x2 = c.x; int z2 = c.z; if (drawPaths) { this.DebugFlash(c, (float)this.calcGrid[num].knownCost / 1500f, this.calcGrid[num].knownCost.ToString()); } if (flag3) { if (num == num2) { return(this.FinalizedPath(num)); } } else if (cellRect.Contains(c) && !this.disallowedCornerIndices.Contains(num)) { return(this.FinalizedPath(num)); } if (cellsSearched > ThingPathFinder.SearchLimit) { Log.Warning($"{""} pathing from {start} to {dest} hit search limit of {ThingPathFinder.SearchLimit} cells."); return(ThingPath.NotFound); } for (int i = 0; i < 8; i++) { uint num10 = (uint)(x2 + ThingPathFinder.Directions[i]); uint num11 = (uint)(z2 + ThingPathFinder.Directions[i + 8]); if ((ulong)num10 < (ulong)((long)this.mapSizeX) && (ulong)num11 < (ulong)((long)this.mapSizeZ)) { int xPos = (int)num10; int zPos = (int)num11; int num14 = this.cellIndices.CellToIndex(xPos, zPos); if (this.calcGrid[num14].status != this.statusClosedValue || flag8) { int num15 = 0; bool flag9 = false; if (!this.pathGrid.WalkableFast(num14)) { if (!passAllDestroyableThings) { if (drawPaths) { this.DebugFlash(new IntVec3(xPos, 0, zPos), 0.22f, "walk"); } continue; } flag9 = true; num15 += 60; Building building = edificeGrid[num14]; if (building == null) { continue; } if (!PathFinder.IsDestroyable(building)) { continue; } num15 += (int)((float)building.HitPoints * 0.1f); } if (i > 3) { switch (i) { case 4: if (this.BlocksDiagonalMovement(num - this.mapSizeX)) { if (flag7) { if (drawPaths) { this.DebugFlash(new IntVec3(x2, 0, z2 - 1), 0.9f, "corn"); } continue; } num15 += 60; } if (this.BlocksDiagonalMovement(num + 1)) { if (flag7) { if (drawPaths) { this.DebugFlash(new IntVec3(x2 + 1, 0, z2), 0.9f, "corn"); } continue; } num15 += 60; } break; case 5: if (this.BlocksDiagonalMovement(num + this.mapSizeX)) { if (flag7) { if (drawPaths) { this.DebugFlash(new IntVec3(x2, 0, z2 + 1), 0.9f, "corn"); } continue; } num15 += 60; } if (this.BlocksDiagonalMovement(num + 1)) { if (flag7) { if (drawPaths) { this.DebugFlash(new IntVec3(x2 + 1, 0, z2), 0.9f, "corn"); } continue; } num15 += 60; } break; case 6: if (this.BlocksDiagonalMovement(num + this.mapSizeX)) { if (flag7) { if (drawPaths) { this.DebugFlash(new IntVec3(x2, 0, z2 + 1), 0.9f, "corn"); } continue; } num15 += 60; } if (this.BlocksDiagonalMovement(num - 1)) { if (flag7) { if (drawPaths) { this.DebugFlash(new IntVec3(x2 - 1, 0, z2), 0.9f, "corn"); } continue; } num15 += 60; } break; case 7: if (this.BlocksDiagonalMovement(num - this.mapSizeX)) { if (flag7) { if (drawPaths) { this.DebugFlash(new IntVec3(x2, 0, z2 - 1), 0.9f, "corn"); } continue; } num15 += 60; } if (this.BlocksDiagonalMovement(num - 1)) { if (flag7) { if (drawPaths) { this.DebugFlash(new IntVec3(x2 - 1, 0, z2), 0.9f, "corn"); } continue; } num15 += 60; } break; } } int num16 = (i <= 3) ? ticksPerMoveCardinal : ticksPerMoveDiagonal; num16 += num15; if (!flag9) { num16 += array[num14]; } /*if (byteGrid != null) * num16 += (int)(byteGrid[num14] * 8);*/ /*if (allowedArea != null && !allowedArea[num14]) * num16 += 600;*/ if (ThingHelper.AnyThingBlockingPathAt(new IntVec3(xPos, 0, zPos), thing)) { num16 += 175; } Building building2 = this.edificeGrid[num14]; if (building2 != null) { int buildingCost = ThingPathFinder.GetBuildingCost(building2, traverseParms, thing); if (buildingCost == 2147483647) { continue; } num16 += buildingCost; } int num17 = num16 + this.calcGrid[num].knownCost; ushort status = this.calcGrid[num14].status; if (status == this.statusClosedValue || status == this.statusOpenValue) { int num18 = 0; if (status == this.statusClosedValue) { num18 = ticksPerMoveCardinal; } if (this.calcGrid[num14].knownCost <= num17 + num18) { continue; } } if (status != this.statusClosedValue && status != this.statusOpenValue) { if (flag8) { Log.Error("GetPathCostFromDestToRegion unimplemented"); //this.calcGrid[num14].heuristicCost = Mathf.RoundToInt((float)this.regionCostCalculator.GetPathCostFromDestToRegion(num14) * 5f); } else { int dx = Math.Abs(xPos - x); int dz = Math.Abs(zPos - z); int num19 = GenMath.OctileDistance(dx, dz, ticksPerMoveCardinal, ticksPerMoveDiagonal); this.calcGrid[num14].heuristicCost = Mathf.RoundToInt((float)num19 * heuristicStrength); } } int num20 = num17 + this.calcGrid[num14].heuristicCost; this.calcGrid[num14].parentIndex = num; this.calcGrid[num14].knownCost = num17; this.calcGrid[num14].status = this.statusOpenValue; this.calcGrid[num14].costNodeCost = num20; num4++; this.openList.Push(new ThingPathFinder.CostNode(num14, num20)); } } } cellsSearched++; this.calcGrid[num].status = this.statusClosedValue; if (num4 >= 2000 && flag6 && !flag8) { flag8 = true; //this.regionCostCalculator.Init(cellRect, traverseParms, ticksPerMoveCardinal, ticksPerMoveDiagonal, null, null, this.disallowedCornerIndices); this.InitStatusesAndPushStartNode(ref num, start); } } } //string job = (pawn == null || pawn.CurJob == null) ? "null" : pawn.CurJob.ToString(); //string faction = (pawn == null || pawn.Faction == null) ? "null" : pawn.Faction.ToString(); //Log.Warning($"{""} pathing from {start} to {dest} ran of cells to process.\nJob: {job}\nFaction: {faction}"); // TODO Log.Error("Thing Pathing error!"); return(ThingPath.NotFound); }