public WorldBlock GetBlock(HexXY blockp) { return(wbCache.GetNoCache(blockp)); }
public void RemoveTriggerZoneFrom(HexXY p, uint zone) { triggerZones[p].Remove(zone); }
public HashSet <WorldBlock> RecalcPassabilityOnEdges() { var changedBlocks = new HashSet <WorldBlock>(); foreach (var wb in GetAllBlocks()) { for (int x = 0; x < WorldBlock.sz; x++) { for (int y = 0; y < WorldBlock.sz; y++) { var p = new HexXY(x, y) + wb.Offset; var type = GetCellType(p); var blType = GetPFBlockedMap(p); if (type != TerrainCellType.Empty) { bool isNearEmpty = false; for (int n = 0; n < 6; n++) { if (GetCellType(p + HexXY.neighbours[n]) == TerrainCellType.Empty) { isNearEmpty = true; break; } } if (isNearEmpty) { if (GetPFBlockedMap(p) != WorldBlock.PFBlockType.EdgeBlocked) { if (!changedBlocks.Contains(wb)) { changedBlocks.Add(wb); } SetPFBlockedMap(p, WorldBlock.PFBlockType.EdgeBlocked); } } else if (!isNearEmpty && blType == WorldBlock.PFBlockType.EdgeBlocked) { if (!changedBlocks.Contains(wb)) { changedBlocks.Add(wb); } SetPFBlockedMap(p, WorldBlock.PFBlockType.Unblocked); } } else { if (GetPFBlockedMap(p) != WorldBlock.PFBlockType.EdgeBlocked) { if (!changedBlocks.Contains(wb)) { changedBlocks.Add(wb); } SetPFBlockedMap(p, WorldBlock.PFBlockType.EdgeBlocked); } } } } } return(changedBlocks); }
public void Add(HexXY p, WorldBlock block) { all.Add(p, block); }
bool InterpretPredicate(Spell.CompiledRune predRune) { //Compute connected component and find avatar ref position Spell.CompiledRune avatarRefRune = null; blobFront.Enqueue(predRune); blobAll.Add(predRune); do { var c = blobFront.Dequeue(); additionalInterpretedRunes.Add(c); if (c.type == RuneType.PredicateAvatarRef) { if (avatarRefRune != null) { //Double avatar ref error finishState = FinishedState.PredicateParseError; return(false); } else { avatarRefRune = c; } } foreach (var n in c.neighs) { if (n == null || !IsPredicateRune(n.type) || blobAll.Contains(n)) { continue; } blobFront.Enqueue(n); blobAll.Add(n); } } while (blobFront.Count > 0); HexXY predRefPos; if (avatarRefRune != null) { predRefPos = avatarRefRune.relPos; } else { if (blobAll.Count > 1) { //No avatar reference in predicate with more than one rune finishState = FinishedState.PredicateParseError; return(false); } else { predRefPos = blobAll.First().relPos; } } //Check predicate bool isMatch = true; foreach (var prune in blobAll) { HexXY checkPos = prune.relPos - predRefPos; for (int i = 0; i < dir; i++) { checkPos = checkPos.RotateRight(new HexXY(0, 0)); } checkPos += this.pos; switch (prune.type) { case RuneType.PredicateTileEmpty: { var blType = Level.S.GetPFBlockedMap(checkPos); if (blType != WorldBlock.PFBlockType.Unblocked && blType != WorldBlock.PFBlockType.DynamicBlocked) { isMatch = false; } break; } case RuneType.PredicateTileWall: if (Level.S.GetPFBlockedMap(checkPos) != WorldBlock.PFBlockType.EdgeBlocked && Level.S.GetPFBlockedMap(checkPos) != WorldBlock.PFBlockType.StaticBlocked && Level.S.GetPFBlockedMap(checkPos) != WorldBlock.PFBlockType.DoorBlocked) { isMatch = false; } break; case RuneType.PredicateTileMonster: if (!Level.S.GetEntities(checkPos).Any(e => e is Mob)) { isMatch = false; } break; } if (!isMatch) { break; } } blobAll.Clear(); if (SpellExecuting.isLogging) { Logger.Log("predicate at " + predRune.relPos + " is " + isMatch); } return(isMatch); }
public static HexXY GetBlockCoords(Vector2 coord) { return(GetBlockCoords(HexXY.FromPlaneCoordinates(coord))); }
//Trace first straight line dest and move there void MovePart() { //Debug.Log("MOVEPART " + p); uint?pathLen = Pathfinder.FindPath(pos, dest.Value, pathStorage, distToStop, 10); if (pathLen.HasValue && pathLen.Value > 0) { HexXY firstPathCell = pathStorage[0]; if (!blockedCells.Contains(firstPathCell) && Level.S.GetPFBlockedMap(firstPathCell) != WorldBlock.PFBlockType.Unblocked) { //Even first cell is blocked, just rotate there dest = null; isWalking = false; Interfacing.PerformInterfaceStop(graphicsHandle, pos); Interfacing.PerformInterfaceUpdateRotation(graphicsHandle, (uint)HexXY.neighbours.IndexOf(pathStorage[0] - pos)); } else { //Try to trace a line to these //First line that will be blocked will determine max straight-line destination //Path to first cell should not be blocked so start with second if (pathLen.Value == 1) { interDest = pathStorage[0]; interFracDest = interDest.ToPlaneCoordinates(); } else { for (int i = 1; i < pathLen.Value; i++) { HexXY inter = pathStorage[i]; //Check if straight line backwards is blocked Vector2 linePos = inter.ToPlaneCoordinates(); Vector2 lineDir = (fracPos - linePos).normalized; bool isLineBlocked = false; HexXY traced = inter; do { float minDist = float.MaxValue; float lineShift = 0; HexXY nextTraced = new HexXY(0, 0); for (int n = 0; n < 6; n++) { HexXY np = traced + HexXY.neighbours[n]; Vector2 v = np.ToPlaneCoordinates() - linePos; float lineLen = Vector2.Dot(v, lineDir); if (lineLen < 0) { continue; } float dist = (lineDir * lineLen - v).magnitude; if (dist < 0.8f) //Line intersects cell np (circle approximated, not hexagon though, and larger (should be less than cos(60)) so it will not cut walls) { if (!blockedCells.Contains(np) && Level.S.GetPFBlockedMap(np) != WorldBlock.PFBlockType.Unblocked) { isLineBlocked = true; break; } if (dist < minDist) { minDist = dist; nextTraced = np; lineShift = lineLen; } } } traced = nextTraced; linePos += lineShift * lineDir; } while (!isLineBlocked && traced != pos); if (isLineBlocked) //Choose the previous cell { interDest = pathStorage[i - 1]; interFracDest = interDest.ToPlaneCoordinates(); break; } //Got to the last cell - use it if (i == pathLen.Value - 1) { interDest = inter; interFracDest = interDest.ToPlaneCoordinates(); } } } float timeToGetThere = (fracPos - interFracDest).magnitude / speed; Interfacing.PerformInterfaceMovePrecise(graphicsHandle, interFracDest, timeToGetThere); isWalking = true; } } else { dest = null; isWalking = false; Interfacing.PerformInterfaceStop(graphicsHandle, pos); } }
public static bool IsInRange(HexXY pos) { return(pos.x >= 0 && pos.x < sz && pos.y >= 0 && pos.y < sz); }
void Walking(float dt) { HexXY prevPos = pos; float distToTargetSqr = (interFracDest - fracPos).sqrMagnitude; Vector2 dir = (interFracDest - fracPos).normalized; //Calculate blocking //Debug.Log(distToTargetSqr + " " + (blockForwardDist * blockForwardDist)); if (distToTargetSqr >= blockForwardDist * blockForwardDist) { Vector2 nextBlockPos = fracPos + dir * blockForwardDist; HexXY nextPosCell = HexXY.FromPlaneCoordinates(nextBlockPos); if (!blockedCells.Contains(nextPosCell)) { if (Level.S.GetPFBlockedMap(nextPosCell) != WorldBlock.PFBlockType.Unblocked) { //Blocked by something - stop and move to nearest cell center dest = interDest = pos; //Debug.Log("Blocked dest " + pos); interFracDest = pos.ToPlaneCoordinates(); float timeToGetThere = (fracPos - interFracDest).magnitude / (speed * 0.5f); //at half speed Interfacing.PerformInterfaceMovePrecise(graphicsHandle, interFracDest, timeToGetThere); return; } else { Level.S.SetPFBlockedMap(nextPosCell, WorldBlock.PFBlockType.DynamicBlocked); //G.S.DebugShowCell(nextPosCell); blockedCells.Add(nextPosCell); } } } //Calculate movement Vector2 step = dir * speed * dt; if (step.sqrMagnitude == 0 || step.sqrMagnitude > distToTargetSqr) { fracPos = interFracDest; if (HexXY.Dist(interDest, dest.Value) <= distToStop) { dest = null; isWalking = false; Interfacing.PerformInterfaceStop(graphicsHandle, pos); } else { MovePart(); } } else { fracPos += step; } pos = HexXY.FromPlaneCoordinates(fracPos); if (pos != prevPos) { Level.S.RemoveEntity(prevPos, this); Level.S.AddEntity(pos, this); //Remove blocked cells that are behind us blockedCellsToDelete.Clear(); foreach (var bc in blockedCells) { Vector2 bcFrac = bc.ToPlaneCoordinates(); if (bc != pos && Vector2.Dot(fracPos - bcFrac, dir) > blockBackDist) { blockedCellsToDelete.Add(bc); } } foreach (var dbc in blockedCellsToDelete) { blockedCells.Remove(dbc); Level.S.SetPFBlockedMap(dbc, WorldBlock.PFBlockType.Unblocked); //G.S.DebugHideCell(dbc); } } this.dir = HexXY.GetApproximateDir(dir); }
public Player() : base(EntityClass.Character, (uint)CharacterType.Player) { pathStorage = new HexXY[64]; speed = 3; abilitySpells = new Spell[3]; }
public void OnMove(HexXY from, HexXY to, bool isDrawing) { throw new NotImplementedException(); }
public abstract void StackOn(HexXY pos);
public static int PFGetPassCost(HexXY pos) { return(1); }
public bool OnUpdate(float dt) { if (onTileCenter && shouldRecalcPath) { var pathLen = Pathfinder.FindPath(entity.pos, dest.Value, pathStorage, distToStop, blockedCost); //Logger.Log(pathLen.ToString()); pathStart = 0; shouldRecalcPath = false; isWalkBlocked = false; if (!pathLen.HasValue || pathLen.Value == 0) { pathEnd = 0; if (isWalking) { Interfacing.PerformInterfaceStop(entity.graphicsHandle, entity.pos); isWalking = false; } return(true); } pathEnd = pathLen.Value; } if (pathStart == pathEnd) { return(true); } var nextTile = pathStorage[pathStart]; if (distToNextTile > 0.5) { entity.pos = prevTile; } else { entity.pos = nextTile; } if (onTileCenter) { if (Level.S.GetPFBlockedMap(nextTile) == WorldBlock.PFBlockType.DynamicBlocked) { if (!isWalkBlocked) { isWalkBlocked = true; walkBlockedTime = 0; isWalking = false; Interfacing.PerformInterfaceStop(entity.graphicsHandle, entity.pos); } walkBlockedTime += dt; return(true); } isWalkBlocked = false; Level.S.SetPFBlockedMap(nextTile, WorldBlock.PFBlockType.DynamicBlocked); Level.S.SetPFBlockedMap(prevTile, WorldBlock.PFBlockType.Unblocked); pfBlockedTile = nextTile; Interfacing.PerformInterfaceMove(entity.graphicsHandle, nextTile, distToNextTile * invSpeed); isWalking = true; } float timeLeft = distToNextTile * invSpeed; if (timeLeft > dt) { distToNextTile -= dt * speed; onTileCenter = false; } else { prevTile = nextTile; distToNextTile = 1; onTileCenter = true; ++pathStart; if (pathEnd - pathStart > 0) { OnUpdate(dt - timeLeft); } else { Interfacing.PerformInterfaceStop(entity.graphicsHandle, prevTile); isWalking = false; } } return(true); }
public void OnSpawn(HexXY pos) { }
public override void LoadDerived(BinaryReader reader) { dir = reader.ReadByte(); sourceSpellPos = new HexXY(reader.ReadInt32(), reader.ReadInt32()); }
public TerrainCellType GetCellType(HexXY pos) { return(cellTypes[pos.x, pos.y]); }