protected PathCheckResult checkSnakeWithOffset(int offset = 0) { if (3 + offset >= path.Count) { return(PathCheckResult.Unknown); } TilePos posIn = path[1 + offset].Pos; TilePos posOut = path[2 + offset].Pos; TileDir dirIn = path[1 + offset].DirIn; TileDir dirOut = path[2 + offset].DirOut; if (null == dirOut || dirOut == TileDir.Zero) { return(PathCheckResult.Unknown); } TileDir dir = new TileDir(posOut.X - posIn.X, posOut.Y - posIn.Y); if (dirIn == dirOut && (dir == dirIn.PerpendicularLeft() || dir == dirIn.PerpendicularRight())) { return(PathCheckResult.Yes); } else { return(PathCheckResult.No); } }
private Vector EndSidePos() { TilePos pos = path[0].Pos; TileDir dir = path[0].DirOut; TileDir normal = new TileDir(0); for (int i = 1; i < Math.Min(5, path.Count); i++) { if (null == path[i].DirOut) { pos = path[0].Pos + dir * 4; break; } if (path[i].DirIn != path[i].DirOut) { normal = path[i].DirOut; break; } pos = path[i].Pos; dir = path[i].DirIn; } if (normal == dir.Negative()) { normal = dir; } return(EndSidePos(pos, dir, normal.Negative())); }
private Material GetMaterial(TileType type, TileDir dir) { string path = "Material/TileGrass"; switch (type) { case TileType.DeapWater: path = "Material/Tile/DeapWater"; break; case TileType.ShallowWater: path = "Material/Tile/ShallowWater"; break; case TileType.Sandbeach: path = "Material/Tile/Sand"; break; case TileType.Grassland: path = "Material/Tile/Grass"; break; case TileType.Forest: path = "Material/Tile/Forest"; break; case TileType.Snow: path = "Material/Tile/Snow"; break; default: Log.LogError("Tile.GetMaterial: failed"); break; } Material mat = Resources.Load(path) as Material; return mat; }
private void runOut(Move move) { if (sign * car.EnginePower > 0 || outStuckTicks > 1) { outStuckTicks++; } if (outStuckTicks > maxTicks) { outStuckTicks = 0; return; } TileDir dir = path[0].DirOut; if (null != saveDir && saveDir != dir) { outStuckTicks = 1; } double timePower = Math.Sin((Math.PI * 0.5) * (double)(maxTicks - outStuckTicks) / maxTicks); timePower = 1.2 * timePower - 0.2; move.EnginePower = sign * timePower; if (timePower < 1.0e-3) { move.IsBrake = true; } double angle = sign * car.GetAngleTo(car.X + dir.X, car.Y + dir.Y) * timePower; move.WheelTurn = (25 * angle / Math.PI); }
public override void execute(Move move) { TileDir dirMove = path[offset].DirOut; TileDir dirEnd = path[1 + offset].DirOut; MovingCalculator calculator = new MovingCalculator(); calculator.setupEnvironment(car, game, world); calculator.setupMapInfo(dirMove, path[0].Pos, path[1 + offset].Pos); calculator.setupDefaultAction(GetWayEnd(path[1 + offset].Pos, TileDir.Zero)); Vector endDir = new Vector(dirEnd.X, dirEnd.Y); calculator.setupAngleReach(endDir); calculator.setupPassageLine(GetWayEnd(path[1 + offset].Pos, dirEnd), new Vector(dirMove.X, dirMove.Y), 0.5); calculator.setupAdditionalPoints(this.additionalPoints); Move needMove = calculator.calculateTurn(endDir); if (needMove.IsBrake) { move.IsBrake = true; } //move.EnginePower = needMove.EnginePower; //move.WheelTurn = needMove.WheelTurn; }
public void CalculatePath(LiMap.Cell firstCellWithTransition, bool hasUnknown) { Logger.instance.Assert(null != pathLastCell, "Don't set last cell. Please call SetupEnvironment"); this.hasUnknown = hasUnknown; if (null != transition && !transition.Cell.Pos.Equals(firstCellWithTransition.Pos)) { pathLastCell = transition.Cell; transition = transition.Next; } if (car.Durability < 1.0e-9 || car.Speed() < 5) { pathLastCell = currentDirLastCell(); transition = null; } beginDir = new TilePos(car.X, car.Y) - pathLastCell.Pos; HashSet <LiMap.Cell> visited = new HashSet <LiMap.Cell>(); int depth = Math.Min(3, (int)(car.Speed() / 10)); transition = mergePath(firstCellWithTransition, pathLastCell, transition, depth); Logger.instance.Assert(null != transition, "Can't find path."); path = createPathFromTransition(transition).ToArray(); Logger.instance.Assert(3 <= path.Length, "Can't find full path."); }
protected PathCheckResult checkAround(int offset = 0) { if (2 + offset >= path.Count) { return(PathCheckResult.Unknown); } TilePos posIn = path[1 + offset].Pos; TilePos posOut = path[2 + offset].Pos; TileDir dirIn = path[1 + offset].DirIn; TileDir dirOut = path[2 + offset].DirOut; if (null == dirOut || dirOut == TileDir.Zero) { return(PathCheckResult.Unknown); } bool isLine = dirIn == path[1 + offset].DirOut || path[2 + offset].DirIn == dirOut; if (!isLine && dirIn == dirOut.Negative() && posIn != posOut) { return(PathCheckResult.Yes); } else { return(PathCheckResult.No); } }
public override bool valid() { offset = 0; TileDir dir = path[offset].DirOut; double minAngle = (path[offset].DirOut == path[offset].DirIn) ? (11 * Math.PI / 18) : (16 * Math.PI / 18); double angle = car.GetAngleTo(car.X + dir.X, car.Y + dir.Y); if (Math.Abs(angle) > minAngle) { return(true); } offset = 1; TileDir dirIn = path[offset].DirIn; TileDir dirOut = path[offset].DirOut; if (dirIn == dirOut.Negative()) { return(true); } return(false); }
public void SetDir(TileDir tileDir, bool reorientate) { if (tileDir == this.tileDir) { if (reorientate && shown) { actor.transform.rotation *= Quaternion.AngleAxis(tileDir.ToAngle(), Vector3.up); } return; } if (removed) { this.tileDir = tileDir; return; } var orig = this.tileDir; this.tileDir = tileDir; if (reorientate && shown) { actor.transform.rotation = Quaternion.Euler(actor.transform.eulerAngles.x, tileDir.ToAngle(), actor.transform.eulerAngles.z); } using (var scope = new Hooks.Scope()) { this.hooks.ForEach <IOnChangeDirection_Unit>(scope, v => v.OnChangeDirection(orig, tileDir)); tile.hooks.ForEach <IOnChangeDirection_Tile>(scope, v => v.OnChangeDirection(this, orig, tileDir)); Game.hooks.ForEach <IOnChangeDirection_Game>(scope, v => v.OnChangeDirection(this, orig, tileDir)); } }
private double tilePriority(TileDir dirIn, TileDir dirOut, TileDir nextDirIn, TileDir nextDirOut) { if (nextDirIn.Negative() == nextDirOut) { return(-4.25); } if (dirIn.Negative() == dirOut) { return(-1); } if (dirIn == dirOut)//line { return(0.42); } if (null == nextDirOut || nextDirIn == nextDirOut)//turn { return(-0.6); } if (dirIn == nextDirOut.Negative() && dirOut == nextDirIn)//around { return(-2.5); } else if (dirIn == nextDirOut && dirOut == nextDirIn)//snake { return(0.45); } return(0); }
private CellTransition calculatePath(LiMap.Cell cell, Cell lastCell, HashSet <LiMap.Cell> visited, int depth) { if (visited.Contains(cell) || depth > Constant.PathMaxDepth) { return(null); } visited.Add(cell); Cell resultCell = new Cell(); resultCell.Pos = cell.Pos; resultCell.DirIn = cell.Pos - lastCell.Pos; CellTransition max = null; foreach (LiMap.Transition transition in cell.Transitions) { TileDir dir = transition.ToCell.Pos - cell.Pos; resultCell.DirOut = dir; CellTransition newTransition = calculatePath(transition.ToCell, resultCell, visited, depth + 1); if (null != newTransition) { newTransition.TransitionPriority = cellTransitionPriority(lastCell, resultCell, newTransition.Cell, transition.Weight); int checkDepth = transition.isCheckpoint ? 0 : 3; if (null == max || newTransition.Priority(checkDepth) > max.Priority(checkDepth)) { max = newTransition; } } } List <TileDir> dirOuts = new List <TileDir>(); foreach (TileDir dir in cell.Dirs) { if (dir != resultCell.DirIn.Negative()) { dirOuts.Add(dir); } } resultCell.DirOuts = dirOuts.ToArray(); resultCell.DirOut = null; if (0 != dirOuts.Count) { if (null != max) { resultCell.DirOut = max.Cell.Pos - cell.Pos; } } CellTransition result = new CellTransition(resultCell, max, cellPriority(resultCell)); visited.Remove(cell); return(result); }
protected Vector GetWayEnd(TilePos wayPos, TileDir dir, double mult = 1) { double distanceToSide = game.TrackTileSize * 0.5 - game.CarHeight * 0.5 - game.TrackTileMargin; double nextWaypointX = (wayPos.X + 0.5) * game.TrackTileSize + dir.X * mult * distanceToSide; double nextWaypointY = (wayPos.Y + 0.5) * game.TrackTileSize + dir.Y * mult * distanceToSide; return(new Vector(nextWaypointX, nextWaypointY)); }
/// <summary> /// 设置方向 /// </summary> /// <param name="dir"></param> public void SetDir(TileDir dir) { int count = Dir - dir; for (int i = 0; i < count; i++) { Rotate(); } }
public static T Create <T>(T source, Tile tile, TileDir tileDir, Team team) where T : Unit { return(Create(source, v => { v.team = team; v.tileDir = tileDir; // Prevent hook being called on spawn v.SetTile(tile, true); v.SetDir(tileDir, true); })); }
public CollisionSide(TilePos tilePos, TileDir tileDirOut) { Vector center = tilePos.ToVector(0.5, 0.5); DirOut = new Vector(tileDirOut.X, tileDirOut.Y); Vector centerToDir = center + DirOut * (tileSize * 0.5 - tileMargin); this.P1 = centerToDir + DirOut.PerpendicularLeft() * tileSize * 0.5; this.P2 = centerToDir + DirOut.PerpendicularRight() * tileSize * 0.5; }
private bool containsDir(TileDir dir, TileDir[] dirs) { bool contains = false; foreach (TileDir iterDir in dirs) { contains |= iterDir.Equals(dir); } return(contains); }
private Cell startLastCell() { Cell resultCell = new Cell(); resultCell.DirIn = TileDir.TileDirByDirection(world.StartingDirection); resultCell.DirOut = resultCell.DirIn; resultCell.DirOuts = new TileDir[] { resultCell.DirOut }; resultCell.Pos = new TilePos(car.X, car.Y) - resultCell.DirOut; return(resultCell); }
private Vector EndSidePos(TilePos pos, TileDir dir, TileDir normal) { double sideDistance = (game.TrackTileSize * 0.5) - game.TrackTileMargin - game.CarHeight * 1.25; double centerX = (pos.X + 0.5) * game.TrackTileSize; double centerY = (pos.Y + 0.5) * game.TrackTileSize; double sideX = centerX + normal.X * sideDistance; double sideY = centerY + normal.Y * sideDistance; return(new Vector(sideX, sideY)); }
private Vector bonusEndPos(Bonus bonus, TileDir dirMove) { Vector center = new TilePos(bonus.X, bonus.Y).ToVector(0.5, 0.5); Vector endPos = new Vector(bonus.X, bonus.Y); Vector perpendicular = new Vector(dirMove.X, dirMove.Y).Perpendicular(); double sign = Math.Sign((endPos - center).Dot(perpendicular)); endPos = endPos - perpendicular * (sign * game.BonusSize * 0.5); return(endPos); }
private Cell currentDirLastCell() { Vector angleDir = Vector.sincos(car.Angle); TileDir[] dirsByPriority = null; if (Math.Abs(angleDir.X) > Math.Abs(angleDir.Y)) { dirsByPriority = new TileDir[4] { new TileDir(Math.Sign(angleDir.X), 0), new TileDir(0, Math.Sign(angleDir.Y)), new TileDir(0, -Math.Sign(angleDir.Y)), new TileDir(-Math.Sign(angleDir.X), 0) }; } else { dirsByPriority = new TileDir[4] { new TileDir(0, Math.Sign(angleDir.Y)), new TileDir(Math.Sign(angleDir.X), 0), new TileDir(-Math.Sign(angleDir.X), 0), new TileDir(0, -Math.Sign(angleDir.Y)) }; } Cell resultCell = new Cell(); TilePos currentPos = new TilePos(car.X, car.Y); for (int i = 0; i < 4; i++) { if (gmap.Dirs(currentPos).Contains(dirsByPriority[i].Negative())) { resultCell.DirOut = dirsByPriority[i]; break; } } resultCell.DirOuts = new TileDir[] { resultCell.DirOut }; resultCell.Pos = currentPos - resultCell.DirOut; for (int i = 3; i >= 0; i--) { if (gmap.Dirs(resultCell.Pos).Contains(dirsByPriority[i])) { resultCell.DirIn = dirsByPriority[i].Negative(); break; } } return(resultCell); }
public override void execute(Move move) { TileDir dirMove = path[offset].DirOut; TileDir dirEnd = path[1 + offset].DirOut; TilePos endTile = path[1 + offset].Pos; MovingCalculator calculator = new MovingCalculator(); calculator.setupEnvironment(car, game, world); calculator.setupMapInfo(dirMove, path[0].Pos, path[1 + offset].Pos); calculator.setupDefaultAction(GetWayEnd(path[1 + offset].Pos, dirEnd.Negative() + dirMove.Negative() * 2)); Vector endDir = new Vector(dirEnd.X - dirMove.X, dirEnd.Y - dirMove.Y).Normalize(); calculator.setupAngleReach(endDir); calculator.setupPassageLine(GetWayEnd(endTile, dirEnd, 1.0), new Vector(dirEnd.X + dirMove.X, dirEnd.Y + dirMove.Y).Normalize(), 0.75); if (0 != offset) { calculator.setupAdditionalPoints(additionalPoints); } Dictionary <TilePos, TileDir[]> selfMap = new Dictionary <TilePos, TileDir[]>(); for (int i = 0; i <= offset; i++) { if (path[i].DirIn == path[i].DirOut) { selfMap.Add(path[i].Pos, new TileDir[2] { dirMove.PerpendicularLeft(), dirMove.PerpendicularRight() }); } else { selfMap.Add(path[i].Pos, new TileDir[3] { path[i].DirIn, path[i].DirOut.Negative(), path[i].DirIn.Negative() + path[i].DirOut }); } } selfMap.Add(endTile, new TileDir[2] { dirEnd.Negative(), dirEnd + dirMove.Negative() }); calculator.setupSelfMapCrash(selfMap); Move needMove = calculator.calculateTurn(endDir); move.IsBrake = needMove.IsBrake; move.EnginePower = needMove.EnginePower; move.WheelTurn = needMove.WheelTurn; }
public bool CanMoveInDir(TileDir dir, UnitPather pather, out Tile dirTile) { var from = this.tile; var to = dirTile = from.GetNeighbor(dir); if (to == null) { return(false); } var edge = from.GetEdge(dir); return(pather(this, from, edge, to)); }
/// <summary> Creates an Edge based on the given source, Tile and direction. </summary> public static T Create <T>(T source, Tile tile, TileDir direction) where T : Edge { return(Create(source, v => { if (tile.GetEdge(direction)) { throw new InvalidOperationException("Edge already created at that position."); } v.direction = direction; var dir = (int)direction; v.hex1 = tile; v.hex2 = tile.hex.GetNeighbor(dir); tile.SetEdge(dir, v); })); }
public override List <Tuple <Vector, double> > GetPoints() { Bonus findedBonus = findBonus(); if (null == findedBonus) { return(null); } TileDir dirMove = path[0].DirOut; return(new List <Tuple <Vector, double> > { new Tuple <Vector, double>(bonusEndPos(findedBonus, dirMove), car.Height * 0.5) }); }
public override void execute(Move move) { TileDir dirMove = path[offset].DirOut; TileDir dirEnd = path[1 + offset].DirOut; MovingCalculator calculator = new MovingCalculator(); calculator.setupEnvironment(car, game, world); calculator.setupMapInfo(dirMove, path[0].Pos, path[1 + offset].Pos); Vector center = GetWayEnd(path[1 + offset].Pos, TileDir.Zero); Vector endPos = center + new Vector(dirEnd.X - dirMove.X, dirEnd.Y - dirMove.Y) * game.TrackTileSize * 0.25; calculator.setupDefaultAction(endPos); Vector endDir = new Vector(dirEnd.X + dirMove.X, dirEnd.Y + dirMove.Y).Normalize(); calculator.setupAngleReach(endDir); calculator.setupPassageLine(endPos, new Vector(dirMove.X - dirEnd.X, dirMove.Y - dirEnd.Y).Normalize(), 0.6); Dictionary <TilePos, TileDir[]> selfMap = new Dictionary <TilePos, TileDir[]>(); for (int i = 0; i <= offset + 1; i++) { if (path[i].DirIn == path[i].DirOut) { selfMap.Add(path[i].Pos, new TileDir[2] { path[i].DirIn.PerpendicularLeft(), path[i].DirIn.PerpendicularRight() }); } else { selfMap.Add(path[i].Pos, new TileDir[3] { path[i].DirIn, path[i].DirOut.Negative(), path[i].DirIn.Negative() + path[i].DirOut }); } } calculator.setupSelfMapCrash(selfMap); calculator.setupAdditionalPoints(this.additionalPoints); Move needMove = calculator.calculateTurn(endDir); move.IsBrake = needMove.IsBrake; move.EnginePower = needMove.EnginePower; move.WheelTurn = needMove.WheelTurn; }
public override void execute(Move move) { TileDir dirMove = path[0].DirOut; Physic.MovingCalculator calculator = new Physic.MovingCalculator(); calculator.setupEnvironment(car, game, world); calculator.setupMapInfo(dirMove, path[0].Pos, null); calculator.setupAngleReach(new Vector(dirMove.X, dirMove.Y)); calculator.setupDefaultAction(EndSidePos()); Dictionary <TilePos, TileDir[]> selfMap = new Dictionary <TilePos, TileDir[]>(); for (int i = 0; i <= 2; i++) { if (path[i].DirIn == path[i].DirOut) { selfMap.Add(path[i].Pos, new TileDir[2] { dirMove.PerpendicularLeft(), dirMove.PerpendicularRight() }); } else if (0 == i) { selfMap.Add(path[i].Pos, new TileDir[1] { path[0].DirIn }); } else { break; } } calculator.setupSelfMapCrash(selfMap); calculator.setupAdditionalPoints(this.additionalPoints); Move needMove = calculator.calculateMove(); move.IsBrake = needMove.IsBrake; move.EnginePower = needMove.EnginePower; move.WheelTurn = needMove.WheelTurn; }
void FindEdgeTileInRooms() { for (int i = 0; i < m_roomList.Count; i++) { Room room = m_roomList[i]; for (int k = 0; k < room.m_tileList.Count; k++) { RandomMapGenerateData data = room.m_tileList[k]; for (int q = 0; q < m_tileDirOffSet.Length; q++) { TileDir dir = (TileDir)q; if (dir == TileDir.NE || dir == TileDir.NW || dir == TileDir.SE || dir == TileDir.SW) { continue; } int x = data.m_xIndex + m_tileDirOffSet[q].m_x; int y = data.m_yIndex + m_tileDirOffSet[q].m_y; if (!IsValidIndex(x, y)) { continue; } RandomMapGenerateData expandData = m_genData[x][y]; if (!expandData.m_isWall) { continue; } room.AddEdgeTile(expandData); } } } }
public override void execute(Move move) { TileDir dirMove = path[0].DirOut; TileDir dirEnd = path[2].DirOut; MovingCalculator calculator = new MovingCalculator(); calculator.setupEnvironment(car, game, world); calculator.setupMapInfo(dirMove, path[0].Pos, path[2].Pos); calculator.setupDefaultAction(GetWayEnd(path[2].Pos, dirEnd.Negative())); Vector endDir = new Vector(dirEnd.X + dirMove.X, dirEnd.Y + dirMove.Y).Normalize(); calculator.setupAngleReach(endDir); calculator.setupPassageLine(GetWayEnd(path[2].Pos, TileDir.Zero), new Vector(dirMove.X, dirMove.Y), 0.5); Dictionary <TilePos, TileDir[]> selfMap = new Dictionary <TilePos, TileDir[]>(); for (int i = 0; i < 2; i++) { selfMap.Add(path[i].Pos, new TileDir[2] { dirMove.PerpendicularLeft(), dirMove.PerpendicularRight() }); } selfMap.Add(path[2].Pos, new TileDir[2] { dirEnd + dirMove.Negative(), dirEnd }); calculator.setupSelfMapCrash(selfMap); calculator.setupAdditionalPoints(this.additionalPoints); Move needMove = calculator.calculateTurn(endDir); move.IsBrake = needMove.IsBrake; move.EnginePower = needMove.EnginePower; move.WheelTurn = needMove.WheelTurn; }
protected PathCheckResult checkTurn(int offset = 0) { if (1 + offset >= path.Count) { return(PathCheckResult.Unknown); } TileDir dirIn = path[offset + 1].DirIn; TileDir dirOut = path[offset + 1].DirOut; if (null == dirOut || dirOut == TileDir.Zero) { return(PathCheckResult.Unknown); } if (dirIn == dirOut.PerpendicularLeft() || dirIn == dirOut.PerpendicularRight()) { return(PathCheckResult.Yes); } else { return(PathCheckResult.No); } }
private void AttachTexture(GameObject go, TileType voxelType, TileDir dir) { Material mat = GetMaterial(tileData.type, tileData.dir); go.GetComponent<Renderer>().material = mat; }
public TileData() { type = TileType.Default; dir = TileDir.Center; x = -1; y = -1; h = 0; }
public static TileDir Offset(this TileDir dir, int offset) { return((TileDir)(int)new CircularInt((int)dir + offset, 6)); }
public static float ToAngle(this TileDir dir) { const float sectorAngle = 360f / 6f; return((int)dir * sectorAngle + 90); }