예제 #1
0
        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;
                    }
            }
        }
예제 #2
0
        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);
        }
예제 #3
0
        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;
        }
예제 #4
0
        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;
        }