public void calculateMovement(Object o, Map map) { int left, top; int PCleft, PCtop; //get monster coords left = _posX; top = _posY; Point monsterLocation = new Point((left - 1), (top - 5)); //get Object's coord PCleft = o.getX(); PCtop = o.getY(); Point targetLocation = new Point(PCleft - 1, PCtop - 5); bool[,] b = map.getMapForPathFinding(); //remove himself and target from map b[monsterLocation.X, monsterLocation.Y] = true; b[targetLocation.X, targetLocation.Y] = true; //find path SearchParameters sPams = new SearchParameters(monsterLocation, targetLocation, b); Finder = new PathFinder(sPams); _route = Finder.FindPath(); //if no path was find quit if (_route.Count == 0) { _pathAvaible = false; return; } _pathAvaible = true; //clear movement list if there is something left and recreate it _movement.Clear(); for (int i = 0; i < _route.Count; i++) { if (i == 0) { _movement.Add(Game.calculateDelta(monsterLocation, _route[i])); } else { _movement.Add(Game.calculateDelta(_route[i - 1], _route[i])); } } //save to file to check for errors StreamWriter file = new StreamWriter("log.txt"); file.WriteLine("test for calculating delta for pathfinding"); file.WriteLine("Monster position on map -- X :"+monsterLocation.X+" Y :"+monsterLocation.Y); file.WriteLine("Monster position on screen -- X :"+left+" Y :"+top); file.WriteLine("Delta X :" +(left-monsterLocation.X)+" Delta Y :"+(top-monsterLocation.Y)); file.WriteLine("Object position on map -- X :" + targetLocation.X + " Y :" + targetLocation.Y); file.WriteLine("Object position on screen -- X :" + PCleft + " Y :" + PCtop); file.WriteLine("Delta X :" + (PCleft - targetLocation.X) + " Delta Y :" + (PCtop - targetLocation.Y)); file.WriteLine("_route and _movement:"); for (int i = 0; i < _route.Count; i++) { file.WriteLine("_route\t Pos X : "+_route[i].X+"\tPos Y :"+_route[i].Y+"\t\t\t_movement\t Pos X :"+_movement[i].X+"\tPos Y :"+_movement[i].Y); } file.Close(); }
public void Move(Object o, Map map) { int chance; Random rnd = Game.rndGlobal; if (_Stamina.actualValue < 1) { Rest(Dice.Roll("2d10")); return; } switch (_monsterBehaviur) { case MonsterState.MS_IDLE: { if (_Stamina.actualValue < _Stamina.currentValue) { Rest(Dice.Roll("2d10")); } //there is 25% chance that monster will change its state to NEUTRAL chance = rnd.Next(1, 101); if (chance <= 1) { _monsterBehaviur = MonsterState.MS_NEUTRAL; } break; } // Random monster movement and specified directioms // // 1 2 3 // 4 5 6 // 7 8 9 // // case MonsterState.MS_NEUTRAL: { int top; int left; int dx = 0, dy = 0; MapTile tile; chance = rnd.Next(1, 10); switch (chance) { case 1: { dx = -1; dy = -1; break; } case 2: { dx = 0; dy = -1; break; } case 3: { dx = 1; dy = -1; break; } case 4: { dx = -1; dy = 0; break; } case 5: { return; } case 6: { dx = 1; dy = 0; break; } case 7: { dx = -1; dy = 1; break; } case 8: { dx = 0; dy = 1; break; } case 9: { dx = 1; dy = 1; break; } } left = _posX + dx; top = _posY + dy; //check if new posision is passable tile = map.getMapTile(left, top); if (tile.isPassable()) { //check if on tile is unpassable object if (tile._objects.Count != 0) { foreach (Object obj in tile._objects) { if (!obj.isPassable()) { return; } } } //add monster to new tile tile.addObject(this); //every 30 steps while not in comabat decrease stamina if (_steps % 30 == 0) { ActualStamina -= 1; } //increase step _steps++; //remove from current location tile = map.getMapTile(_posX, _posY); tile.removeObject(this); updatePosition(left, top); } //there is 5% chance that monster will change its state to AGGRESIVE and 25% that he will go back to sleep chance = rnd.Next(1,101); if (chance <= 5) { _monsterBehaviur = MonsterState.MS_AGGRESIVE; } else if (chance > 5 && chance <= 25) { _monsterBehaviur = MonsterState.MS_IDLE; } break; } case MonsterState.MS_AGGRESIVE: { int left, top; int tx, ty; int PCleft, PCtop; MapTile tile; //get monster coords left = _posX; top = _posY; //get Object's coord PCleft = o.getX(); PCtop = o.getY(); Point targetLocation = new Point(PCleft - 1, PCtop - 5); //foreach (Point po in _route) //{ // Console.SetCursorPosition(po.X + 1, po.Y + 5); // Console.Write("x"); //} //check if movement list is empty if (_movement.Count == 0) { //create new movement list calculateMovement(o, map); //if no movement was find change state of moster to idle if (_movement.Count == 0) { _monsterBehaviur = MonsterState.MS_IDLE; return; } goto Move; } if (!_pathAvaible) { _monsterBehaviur = MonsterState.MS_IDLE; return; } //check if target changed his posision since last turn if (PCleft != _route.Last().X && PCtop != _route.Last().Y) { //create new movement list calculateMovement(o, map); goto Move; } if (!_pathAvaible) { _monsterBehaviur = MonsterState.MS_IDLE; return; } Move: //not empty take first element Point p = _movement.First(); tx = _posX + p.X; ty = _posY + p.Y; //remove that first movement from movement list _movement.Remove(_movement.First()); tile = map.getMapTile(tx,ty); //check the tile we want to move on if (tile._objects.Count != 0) { foreach (Object obj in tile._objects) { //do things depending on object type ObjectType type = obj.getType(); switch (type) { case ObjectType.O_PC: { Attack(obj); return; } case ObjectType.O_MONSTER: { //tile is blocked by monster who must entered last turn, recalculate movement list and move again calculateMovement(o, map); goto Move; } default: // everything else move onto that tile { left = tx; top = ty; //everything fine, move onto tile //add monster to new tile tile.addObject(this); //every 30 steps while not in comabat decrease stamina if (_steps % 30 == 0) { ActualStamina -= 1; } //increase step _steps++; //if tile has been seen by player you are visible now if (tile.isSeen()) { _seen = true; } //remove from current location tile = map.getMapTile(_posX, _posY); tile.removeObject(this); updatePosition(left, top); return; } } } } else // empty tile move to it { left = tx; top = ty; //everything fine, move onto tile //add monster to new tile tile.addObject(this); //every 30 steps while not in comabat decrease stamina if (_steps % 30 == 0) { ActualStamina -= 1; } //increase step _steps++; //if tile has been seen by player you are visible now if (tile.isSeen()) { _seen = true; } //remove from current location tile = map.getMapTile(_posX, _posY); tile.removeObject(this); updatePosition(left, top); } break; } } }
public List<MapTile> calculateFOV(Map map) { int cx, cy; //center coords int radius; //radius of fov int ox, oy; //coord of origin point int ex, ey; //coord of end point; MapTile tile; List<MapTile> tilesInRange = new List<MapTile>(); cx = _posX; //on map its cx - offsetx cy = _posY; //on map its cx - offsety radius = _visibilityRange; //check if origin point is in screen boundries if (cx - radius < map.getOffsetX()) { ox = map.getOffsetX(); } else { ox = cx - radius; } if (cy - radius < map.getOffsetY()) { oy = map.getOffsetY(); } else { oy = cy - radius; } //check if endpoint are in screen boundries if (cx + radius >= map.getMapWidth() + map.getOffsetX()) { ex = map.getMapWidth(); } else { ex = cx + radius; } if (cy + radius >= map.getMapHeight() + map.getOffsetY()) { ey = map.getMapHeight() +map.getOffsetY() - 1; } else { ey = cy + radius; } for (int y = oy; y <= ey; y++) { for (int x = ox; x <= ex; x++) { //check if it is in range of fov if (((cx - x) * (cx - x) + (cy - y) * (cy - y)) < (radius * radius)) { //if tile is empty continue tile = map.getMapTile(x, y); if (tile.getType() == tileType.T_EMPTY) { continue; } //check it tile has already been seen //if (tile.isSeen()) //{ // continue; //} //else //{ tilesInRange.Add(tile); //} } } } return calculateLOS(tilesInRange, map); }
private List<MapTile> calculateLOS(List<MapTile> tiles, Map map) { int deltaX, deltaY; int err; int deltaErr; int yStep, xStep; int x, y; int tmpX, tmpY; bool blocked = false; MapTile onMap; List<MapTile> visibleTiles = new List<MapTile>(); //add tile on which player is standing onMap = map.getMapTile(_posX, _posY); onMap.beenSeen(); visibleTiles.Add(onMap); //draw line for each tile in FOV and check if that tile can block vision ans set visibility to false or true foreach (MapTile tile in tiles) { Point start = new Point(_posX, _posY); Point end = new Point(tile.getSX(), tile.getSY()); blocked = false; bool steep = Math.Abs(end.Y - start.Y) > Math.Abs(end.X - start.X); if (steep) { Point tmpPoint = new Point(start.X,start.Y); start = new Point(tmpPoint.Y, tmpPoint.X); tmpPoint = new Point(end.X, end.Y); end = new Point(tmpPoint.Y, tmpPoint.X); } deltaX = Math.Abs(end.X - start.X); deltaY = Math.Abs(end.Y - start.Y); err = 0; deltaErr = deltaY; yStep = 0; xStep = 0; y = start.Y; x = start.X; if (start.Y < end.Y) { yStep = 1; } else { yStep = -1; } if (start.X < end.X) { xStep = 1; } else { xStep = -1; } tmpX = 0; tmpY = 0; while (x != end.X) { x += xStep; err += deltaErr; //if the error exceeds the X delta then //move one along on the Y axis if ((2 * err) > deltaX) { y += yStep; err -= deltaX; } //flip the coords if they're steep if (steep) { tmpX = y; tmpY = x; } else { tmpX = x; tmpY = y; } //get tile with calculated coord onMap = map.getMapTile(tmpX, tmpY); //if current tile was not blocked add it to vision tiles if (!blocked) { onMap.beenSeen(); //set all objects on that tile to seen foreach (Object o in onMap._objects) { o.hasBeenSeen(); } visibleTiles.Add(onMap); } else // was blocked move to next one { continue; } //check if this tile can block vision if (onMap.isBlocingkVision()) { //remember that so next tiles will be out of vision blocked = true; continue; } } } return visibleTiles; }
public void moveUpEast(Map map) { if (ActualStamina < 1 || States[(int)PlayerStates.IMMOBILIZED]) { Game.topTextArea.AddMessage(Game.Lang[StringName.TIRED_TEXT]); return; } int x, y; MapTile tile; x = _posX + 1; y = _posY - 1; tile = map.getMapTile(x, y); if (tile.isPassable()) { //check if on tile is unpassable object if (tile._objects.Count != 0) { foreach (Object o in tile._objects) { //check if it's monster, if yes attack it if (o.getType() == ObjectType.O_MONSTER) { Attack(o as LivingObject); return; } else { if (!o.isPassable()) { return; } } } } //add charcter to new tile tile.addObject(this); //add list of items to textarea Game.topTextArea.AddMessage(tile.GetItemsString()); //use stamina every 5 minutes (ie 30 rounds) if not in comabt if (Game.GC.turnCounter != 0 && Game.GC.turnCounter % 30 == 0) { //while burden you lose stamina twice as fast if (States[(int)PlayerStates.BURDEN]) { ActualStamina -= 2; } else { ActualStamina -= 1; } Game.bottomPanel.needUpdate = true; } //remove character from previous tile tile = map.getMapTile(_posX, _posY); tile.removeObject(this); updatePosition(x, y); } else return; }