Пример #1
0
        public TestCave()
        {
            CreateRoomsList();
            CreateConnectionArray();

            cave = new Cave(rooms, connections);
            cave.printCaveLayout();
        }
Пример #2
0
        /// <summary>
        /// Gives the estimated f-cost between two rooms. Uses the manhattan distance.
        /// </summary>
        /// <param name="start"></param>
        /// <param name="end"></param>
        /// <param name="cave"></param>
        /// <returns></returns>
        private static int GetEstimatedScore(Room start, Room end, Cave cave)
        {
            Vector2 startPos = cave.RoomLayout[start.RoomID].RoomPosition;
            Vector2 endPos   = cave.RoomLayout[end.RoomID].RoomPosition;

            // Manhattan distance
            return((Math.Abs(startPos.X - endPos.X) + Math.Abs(startPos.Y - endPos.Y)).ToInt());
        }
Пример #3
0
    private void OpenWindow(Cave cave, PlayerTeam playerTeam)
    {
        Cave = cave;

        team = playerTeam;

        Open();
    }
Пример #4
0
        /*
         * Dump a message describing a monster's reaction to damage
         */
        public static void message_pain(int m_idx, int dam)
        {
            long oldhp, newhp, tmp;
            int  percentage;

            Monster m_ptr = Cave.cave_monster(Cave.cave, m_idx);

            MON_MSG msg_code = MON_MSG.UNHARMED;
            //char m_name[80];
            string m_name;

            /* Get the monster name */
            m_name = m_ptr.monster_desc(0);

            /* Notice non-damage */
            if (dam == 0)
            {
                add_monster_message(m_name, m_idx, msg_code, false);
                return;
            }

            /* Note -- subtle fix -CFT */
            newhp      = (long)(m_ptr.hp);
            oldhp      = newhp + (long)(dam);
            tmp        = (newhp * 100L) / oldhp;
            percentage = (int)(tmp);

            if (percentage > 95)
            {
                msg_code = MON_MSG.MON_MSG_95;
            }
            else if (percentage > 75)
            {
                msg_code = MON_MSG.MON_MSG_75;
            }
            else if (percentage > 50)
            {
                msg_code = MON_MSG.MON_MSG_50;
            }
            else if (percentage > 35)
            {
                msg_code = MON_MSG.MON_MSG_35;
            }
            else if (percentage > 20)
            {
                msg_code = MON_MSG.MON_MSG_20;
            }
            else if (percentage > 10)
            {
                msg_code = MON_MSG.MON_MSG_10;
            }
            else
            {
                msg_code = MON_MSG.MON_MSG_0;
            }

            add_monster_message(m_name, m_idx, msg_code, false);
        }
Пример #5
0
        public Day22()
        {
            InitializeComponent();

            cave = new Cave(depth, target);
            //cave = new Cave(510, new Point(10, 10));

            riskLabel.Text = $"Total risk: {cave.GetRiskLevel()}";
        }
Пример #6
0
 internal void AddDestination(Cave destination)
 {
     if (!ConnectedTo.Contains(destination))
     {
         ConnectedTo.Add(destination);
         //add reverse connection to target
         destination.AddDestination(this);
     }
 }
Пример #7
0
        public void Test_newTopTen()
        {
            HighScoreManagement testList = new HighScoreManagement();
            Cave   testcave   = new Cave("testCave");
            Player testPlayer = new Player("Bob", 100, testcave);

            testList.newTopTen(testPlayer);
            testList.toString();
        }
Пример #8
0
        public void AddConnection(Cave cave)
        {
            if (ConnectedCaves.Contains(cave))
            {
                return;
            }

            ConnectedCaves.Add(cave);
        }
Пример #9
0
    private void CreatePassage(Cave caveA, Cave caveB, Coord tileA, Coord tileB)
    {
        List <Coord> line = GetLine(tileA, tileB);

        foreach (Coord c in line)
        {
            DrawCircle(c, 1);
        }
    }
Пример #10
0
        public int ProcessPath(Cave currentCave, List <Cave> previousExploredCaves, bool processSmallCaveTwice)
        {
            int pathCount = 0;

            foreach (KeyValuePair <string, Cave> connectedCaveInfo in currentCave.ConnectedCaves)
            {
                Cave connectedCave = connectedCaveInfo.Value;
                // If we encounter the start, we continue
                if (connectedCave.IsStart)
                {
                    continue;
                }
                // If we encounter the end, we return one path found
                else if (connectedCave.IsEnd)
                {
                    previousExploredCaves.Add(connectedCave);
                    //Console.WriteLine("Path correct found " + Cave.Log(previousExploredCaves));
                    pathCount += 1;
                }
                else if (connectedCave.IsSmall)
                {
                    // If we encounter the same small cave twice, the path is invalid, except if we can explore one previous small encountered cave
                    if (previousExploredCaves.Contains(connectedCave))
                    {
                        if (!processSmallCaveTwice)
                        {
                            previousExploredCaves.Add(connectedCave);
                            //Console.WriteLine("Path not correct found " + Cave.Log(previousExploredCaves));
                            continue;
                        }
                        else
                        {
                            // We explored a same small cave twice so we can set the previousExploredCaves to false
                            List <Cave> caves = new List <Cave>(previousExploredCaves);
                            caves.Add(connectedCave);
                            pathCount += ProcessPath(connectedCave, caves, false);
                        }
                    }
                    else
                    {
                        // We keep going
                        List <Cave> caves = new List <Cave>(previousExploredCaves);
                        caves.Add(connectedCave);
                        pathCount += ProcessPath(connectedCave, caves, processSmallCaveTwice);
                    }
                }
                else
                {
                    // We keep going
                    List <Cave> caves = new List <Cave>(previousExploredCaves);
                    caves.Add(connectedCave);
                    pathCount += ProcessPath(connectedCave, caves, processSmallCaveTwice);
                }
            }

            return(pathCount);
        }
Пример #11
0
    void generate(OPTIONS op)
    {
        if (GameObject.Find(objectName) != null)
        {
            EditorUtility.DisplayDialog("Error", "Object " + objectName + " already exists", "Ok", "");
        }
        else
        {
            Transform level = new GameObject(objectName).transform;
            if (useRandomSeed)
            {
                seed = Time.time.ToString();
            }
            System.Random rnd = new System.Random(seed.GetHashCode());
            switch (op)
            {
            case OPTIONS.Hauberk:
                Hauberk h = GameObject.Find(objectName).AddComponent <Hauberk> ();
                h.addRooms(rooms);
                h.setSeed(rnd);
                h.setIsRandomSeed(useRandomSeed);
                h.GenerateLevel(mapSize, level, tilePrefab, outlinePercent);
                break;

            case OPTIONS.Cave:
                Cave c = GameObject.Find(objectName).AddComponent <Cave>();
                c.setSeed(rnd);
                c.setIsRandomSeed(useRandomSeed);
                //c.GenerateLevel(level, randomFillPercent, width, height);
                break;

            case OPTIONS.TEST:
                Debug.Log("Testing...");
                Debug.Log(System.IO.Directory.GetCurrentDirectory());

                SimpleProgressBar window1 = new SimpleProgressBar();
                //ProgressBarTest window1 = new ProgressBarTest();
                window1.setup();
                window1.ShowPopup();
                window1.log        = "Initialized builder... v2";
                window1.isBuilding = true;
                window1.listLength = 5;

                window1.doStep();
                window1.doStep();
                window1.doStep();
                window1.doStep();
                window1.doStep();
                break;

            default:
                Debug.LogError("Unrecognized Option");
                break;
            }
        }
    }
Пример #12
0
        internal void AddDestination(string name, ref List <Cave> caves)
        {
            if (!AllCaves.Any(c => c.Name == name))
            {
                AllCaves.Add(new Cave(name, ref caves));
            }
            Cave destination = AllCaves.Where(c => c.Name == name).Single();

            AddDestination(destination);
        }
Пример #13
0
        private Cave reader2Cave(IDataReader reader)
        {
            Cave c = new Cave();

            c.Id      = Convert.ToInt32(reader["IdCave"]);
            c.Nom     = reader["NomCave"].ToString();
            c.Adresse = reader["Adresse"].ToString();
            c.Piece   = reader["Piece"].ToString();
            return(c);
        }
Пример #14
0
    public override string Part1(List <string> input, bool isTestRun)
    {
        List <Cave> caves = ReadInput(input);

        Cave          start    = caves.Where(c => c.Name == "start").Single();
        List <string> pathList = new();
        long          count    = start.Walk("", ref pathList, false);

        return($"{count}");
    }
Пример #15
0
            public SearchNode1(SearchNode1 parent, Cave newCurrent)
            {
                this.cantVisit = new HashSet <Cave>(parent.cantVisit);
                this.Current   = newCurrent;

                if (!parent.Current.isBig)
                {
                    this.cantVisit.Add(parent.Current);
                }
            }
Пример #16
0
        public void TestConstructor()
        {
            Cave CaveTest = new Cave(1);

            for (int i = 0; i < 30; i++)
            {
                Assert.AreEqual(CaveTest.PassRoom(i).RoomNumber(), i + 1);         //testing the roonnumber
            }
            Assert.AreEqual(CaveTest.PassRoom(0).GetTunnelInfo(2).GetToRoom(), 2); //testing the tunnel info
        }
Пример #17
0
        /// <summary>
        /// Initializes a new instance of the Wumpus class.
        /// </summary>
        /// <param name="map"></param>
        public Wumpus(Map map)
        {
            cave     = map.Cave;
            this.map = map;

            ACTIVE_BEHAVIOR  = new ActiveWumpusBehavior(this, map);
            PASSIVE_BEHAVIOR = new PassiveWumpusBehavior(this, map);

            CurrentBehavior = ACTIVE_BEHAVIOR;
        }
Пример #18
0
        /*
         * Attempt to make an object (normal or good/great)
         *
         * This routine plays nasty games to generate the "special artifacts".
         * We assume that the given object has been "wiped". You can optionally
         * receive the object's value in value if you pass a non-null pointer.
         *
         * Returns the whether or not creation worked.
         */
        public static bool make_object(Cave c, ref Object j_ptr, int lev, bool good, bool great, ref int value)
        {
            int         Base;
            Object_Kind kind;

            /* Try to make a special artifact */
            if (Random.one_in_(good ? 10 : 1000))
            {
                if (make_artifact_special(ref j_ptr, lev))
                {
                    if (value != 0)
                    {
                        value = j_ptr.value_real(1, false, true);
                    }
                    return(true);
                }

                /* If we failed to make an artifact, the player gets a great item */
                good = great = true;
            }

            /* Base level for the object */
            Base = (good ? (lev + 10) : lev);

            /* Get the object, prep it and apply magic */
            kind = get_obj_num(Base, good || great);
            if (kind == null)
            {
                return(false);
            }
            j_ptr.prep(kind, lev, aspect.RANDOMISE);
            j_ptr.apply_magic(lev, true, good, great);

            /* Generate multiple items */
            if (kind.gen_mult_prob >= Random.randint1(100))
            {
                j_ptr.number = (byte)Random.randcalc(kind.stack_size, lev, aspect.RANDOMISE);
            }

            if (value != 0)
            {
                value = j_ptr.value_real(j_ptr.number, false, true);
            }

            /* Return value, increased for uncursed out-of-depth objects */
            if (!Object_Flag.cursed_p(j_ptr.flags) && (kind.alloc_min > c.depth))
            {
                if (value != 0)
                {
                    value = (kind.alloc_min - c.depth) * (value / 5);
                }
            }

            return(true);
        }
Пример #19
0
    public void Play()
    {
        switch (toEnum)
        {
        case GameStateMachine.GameStates.Start:

            Console.WriteLine("Please type in your name:");
            name = Console.ReadLine();
            Console.WriteLine("Your Player Name is " + name);

            Console.WriteLine("Play commands: Play, End, Help");

            gameState = Console.ReadLine();

            if (Enum.TryParse(gameState, out toEnum))
            {
                Play();
            }

            break;

        case GameStateMachine.GameStates.Died:
            Console.WriteLine("You Died");
            GameStateMachine.currentGameState = GameStateMachine.GameStates.End;
            Play();
            break;

        case GameStateMachine.GameStates.End:
            Console.WriteLine("Game Over");
            Environment.Exit(0);
            break;

        case GameStateMachine.GameStates.Help:
            Console.WriteLine("There is no help.");
            Play();
            break;

        case GameStateMachine.GameStates.Play:
            while (Game.canPlay)
            {
                Cave.Enter();
                Random randomNum = new Random();
                Cave.Encounter(randomNum.Next(0, Cave.objects.Length), "walked");
                GameTimer();
                Play();
            }

            break;

        default:
            Console.WriteLine(" is not a valid option.");
            Play();
            break;
        }
    }
Пример #20
0
        private void CreateWorld()
        {
            //Resetting monster counter when game restarts
            Monster.MonsterCounter = 0;

            world = new Space[worldSizeX, worldSizeY];


            for (int y = 0; y < world.GetLength(1); y++)
            {
                for (int x = 0; x < world.GetLength(0); x++)
                {
                    if (RandomUtils.TryPercentage(2))
                    {
                        world[x, y] = new Pitfall();
                    }

                    else
                    {
                        Space space;
                        if (RandomUtils.TryPercentage(3))
                        {
                            space = new Cave();
                        }
                        else
                        {
                            space = new Room();
                        }

                        //Skulle kunna lösa placering av creatures/items i metoder för att abstrahera bort det från Space-klassen.
                        if (player.X != x || player.Y != y)
                        {
                            if (RandomUtils.TryPercentage(5))
                            {
                                space.Monster = new Troll();
                            }
                            else if (RandomUtils.TryPercentage(5))
                            {
                                space.Monster = new Teacher("Håkan");
                            }

                            if (RandomUtils.TryPercentage(5))
                            {
                                space.Item = new Apple();
                            }
                            else if (RandomUtils.TryPercentage(1))
                            {
                                space.Item = new Spear(1);
                            }
                        }
                        world[x, y] = space;
                    }
                }
            }
        }
Пример #21
0
        /*
         * Handle player hitting a real trap
         */
        public static void hit_trap(int y, int x)
        {
            bool    ident;
            Feature trap = Misc.f_info[Cave.cave.feat[y][x]];

            /* Disturb the player */
            Cave.disturb(Misc.p_ptr, 0, 0);

            /* Run the effect */
            trap.effect.effect_do(out ident, false, 0, 0, 0);
        }
Пример #22
0
 public CaveInfo(Cave c)
 {
     CaveData    = (c.Data?.ToArray()) ?? new Data[0];
     CaveId      = c.Id;
     Number      = c.CaveNumber;
     Description = c.Description;
     SubType     = c.SubType;
     Locations   = (c.Locations?.ToArray()) ?? new CaveLocation[0];
     Name        = c.Name;
     Notes       = (c.Notes?.ToArray()) ?? new CaveNote[0];
 }
Пример #23
0
        private static void FindPaths(List <Cave> caves)
        {
            Cave startCave = caves.Single(x => x.Name == "start");

            foreach (string nextCave in startCave.OtherCaves)
            {
                FollowPath(startCave.Name, nextCave, caves);
            }

            Console.WriteLine(paths.Count);
        }
Пример #24
0
    IEnumerator loadNextLevel()
    {
        yield return(new WaitForSeconds(5.0f));

        Cave c = (Cave)FindObjectOfType(typeof(Cave));

        c.front.SetActive(false);
        yield return(new WaitForSeconds(1.0f));

        moveLevel(1);
    }
        public async Task <IActionResult> PostCave([FromBody] Cave cave)
        {
            if (!ModelState.IsValid)
            {
                return(BadRequest(ModelState));
            }

            _context.Caves.Add(cave);
            await _context.SaveChangesAsync();

            return(CreatedAtAction("GetCave", new { id = cave.Id }, cave));
        }
Пример #26
0
    //traverse caves recursively
//	private void traverseCaves(Cave currentCave) {
//		//if the number of caves we've gone through is more than the numOfCaves, break so there isn't an error
//		if (cavesTraversed > numOfCaves) {
//			return;
//		}
//
//		//set visited to true because this cave is reachable, and increment traversed
//		currentCave.visited = true;
//		cavesTraversed++;
//
//		//for every single exit in currentcave
//		for (int i = 0; i < currentCave.exits.Length; i++) {
//			//-1 means that there aren't any more exits
//			if (currentCave.exits [i] == -1) {
//				return;
//			}
//
//			int nextCaveNum = findNextCave(currentCave.exits[i], currentCave.caveNum);
//
//			//if nextcave hasn't been visited yet, visit it
//			if (!cave [nextCaveNum].visited) {
//				traverseCaves (cave [nextCaveNum]);
//			}
//		}
//	}

    //returns a possible exit for the currentCave
    private int getPossibleExit(Cave currentCave)
    {
        int exitIndex = -1;

        //Find an exitIndex at where the exit at that location possibleExits isn't already in exits[]
        do
        {
            exitIndex = Random.Range(0, currentCave.possibleExits.Length);
        } while (contains(currentCave.exits, currentCave.possibleExits [exitIndex]));

        return(exitIndex);
    }
Пример #27
0
        public void Part1()
        {
            var cave      = new Cave(_input);
            var numRounds = 0;

            while (!cave.Act())
            {
                numRounds += 1;
            }

            Assert.Equal(0, numRounds * cave.SumHitpoints);
        }
Пример #28
0
        /// <summary>
        /// Adds connections from some rooms on the sides of the cave to the other side.
        /// </summary>
        /// <param name="cave">The cave</param>
        /// <param name="maxRoomConnections">The max amount of connections per room</param>
        private static void AddSideConnections(Cave cave, int maxRoomConnections)
        {
            var layouts = cave.RoomLayout.Values;
            // x => (lowestY, highestY, idLowest, idHighest)
            var xToLowestAndHighestY = new Dictionary <int, Tuple <int, int, int, int> >();

            // Set the dictionary to correct values
            foreach (var layout in layouts)
            {
                // Makes floats less likely to conflict when cast? Probably?
                const int conflictNumber = 10000;
                int       x = (int)(layout.RoomPosition.X * conflictNumber);
                int       y = (int)(layout.RoomPosition.Y * conflictNumber);

                int id = layout.Room.RoomID;

                if (!xToLowestAndHighestY.ContainsKey(x))
                {
                    xToLowestAndHighestY[x] = new Tuple <int, int, int, int>(y, y, id, id);
                    continue;
                }
                if (y < xToLowestAndHighestY[x].Item1)
                {
                    xToLowestAndHighestY[x] = new Tuple <int, int, int, int>(y, xToLowestAndHighestY[x].Item2, id, xToLowestAndHighestY[x].Item4);
                }
                if (y > xToLowestAndHighestY[x].Item2)
                {
                    xToLowestAndHighestY[x] = new Tuple <int, int, int, int>(xToLowestAndHighestY[x].Item1, y, xToLowestAndHighestY[x].Item3, id);
                }
            }
            foreach (var range in xToLowestAndHighestY)
            {
                int idMin = range.Value.Item3;
                int idMax = range.Value.Item4;
                if (cave[idMin].AdjacentRooms.Count(r => r != -1) >= maxRoomConnections ||
                    cave[idMax].AdjacentRooms.Count(r => r != -1) >= maxRoomConnections)
                {
                    continue;
                }
                if (cave[idMin].AdjacentRooms[(int)Direction.North] == -1 && cave[idMax].AdjacentRooms[(int)Direction.South] == -1)
                {
                    if (Rand.Next(100) < 50)
                    {
                        continue;
                    }

                    // Make connection
                    cave[idMin].AdjacentRooms[(int)Direction.North] = idMax;
                    cave[idMax].AdjacentRooms[(int)Direction.South] = idMin;
                }
            }
        }
Пример #29
0
        public static void wr_monsters()
        {
            int i;
            int j;

            if (Misc.p_ptr.is_dead)
            {
                return;
            }

            /* Total monsters */
            wr_u16b((ushort)Cave.cave_monster_max(Cave.cave));

            /* Dump the monsters */
            for (i = 1; i < Cave.cave_monster_max(Cave.cave); i++)
            {
                byte unaware = 0;

                Monster.Monster m_ptr = Cave.cave_monster(Cave.cave, i);

                wr_s16b(m_ptr.r_idx);
                wr_byte(m_ptr.fy);
                wr_byte(m_ptr.fx);
                wr_s16b(m_ptr.hp);
                wr_s16b(m_ptr.maxhp);
                wr_byte(m_ptr.mspeed);
                wr_byte(m_ptr.energy);
                wr_byte((byte)Misc.MON_TMD.MAX);

                for (j = 0; j < (byte)Misc.MON_TMD.MAX; j++)
                {
                    wr_s16b(m_ptr.m_timed[j]);
                }

                if (m_ptr.unaware)
                {
                    unaware |= 0x01;
                }
                wr_byte(unaware);

                for (j = 0; j < Object.Object_Flag.BYTES && j < Object.Object_Flag.SIZE; j++)
                {
                    wr_byte(m_ptr.known_pflags[j]);
                }
                if (j < Object.Object_Flag.BYTES)
                {
                    Savefile.pad_bytes(Object.Object_Flag.BYTES - j);
                }

                wr_byte(0);
            }
        }
Пример #30
0
    public void Play()
    {
        switch (toEnum)
        {
        case GameState.GameStates.Start:
            Console.WriteLine("Please type in your name.");
            name = Console.ReadLine();
            Console.WriteLine("Your Player Name is " + name);
            Console.WriteLine("Play commands: Play, End, Help");
            defineGameState = Console.ReadLine();
            if (Enum.TryParse(defineGameState, out toEnum))
            {
                Console.WriteLine(toEnum);
            }
            Play();
            break;

        case GameState.GameStates.Died:
            Console.WriteLine("You died.");
            GameState.currentGameState = GameState.GameStates.End;
            Play();
            break;

        case GameState.GameStates.End:
            Console.WriteLine("Game Over");
            Environment.Exit(0);
            break;

        case GameState.GameStates.Help:
            Console.WriteLine("What do you need help for? If you can't play this game, you have issues.");
            Play();
            break;

        case GameState.GameStates.Play:
            while (Game.canPlay)
            {
                Cave.Enter();
                Random randomNum = new Random();
                Cave.Encounter(randomNum.Next(0, Cave.objects.Length), "walked");
                GameTimer();
                Play();
            }
            Play();
            break;

        default:
            Console.WriteLine(" is not a valid option.");
            Play();

            break;
        }
    }
Пример #31
0
 public static void hp_colour_change(Game_Event.Event_Type type, Game_Event data, object user)
 {
     /*
      * hack:  redraw player, since the player's color
      * now indicates approximate health.  Note that
      * using this command when graphics mode is on
      * causes the character to be a black square.
      */
     if ((Option.hp_changes_color.value) && (Misc.arg_graphics == Misc.GRAPHICS_NONE))
     {
         Cave.cave_light_spot(Cave.cave, Misc.p_ptr.py, Misc.p_ptr.px);
     }
 }
Пример #32
0
        /*
         * Attempt to make an object (normal or good/great)
         *
         * This routine plays nasty games to generate the "special artifacts".
         * We assume that the given object has been "wiped". You can optionally
         * receive the object's value in value if you pass a non-null pointer.
         *
         * Returns the whether or not creation worked.
         */
        public static bool make_object(Cave c, ref Object j_ptr, int lev, bool good, bool great, ref int value)
        {
            int Base;
            Object_Kind kind;

            /* Try to make a special artifact */
            if (Random.one_in_(good ? 10 : 1000)) {
                if (make_artifact_special(ref j_ptr, lev)) {
                    if (value != 0) value = j_ptr.value_real(1, false, true);
                    return true;
                }

                /* If we failed to make an artifact, the player gets a great item */
                good = great = true;
            }

            /* Base level for the object */
            Base = (good ? (lev + 10) : lev);

            /* Get the object, prep it and apply magic */
            kind = get_obj_num(Base, good || great);
            if (kind == null) return false;
            j_ptr.prep(kind, lev, aspect.RANDOMISE);
            j_ptr.apply_magic(lev, true, good, great);

            /* Generate multiple items */
            if (kind.gen_mult_prob >= Random.randint1(100))
                j_ptr.number = (byte)Random.randcalc(kind.stack_size, lev, aspect.RANDOMISE);

            if(value != 0) value = j_ptr.value_real(j_ptr.number, false, true);

            /* Return value, increased for uncursed out-of-depth objects */
            if (!Object_Flag.cursed_p(j_ptr.flags) && (kind.alloc_min > c.depth)) {
                if (value != 0) value = (kind.alloc_min - c.depth) * (value / 5);
            }

            return true;
        }
Пример #33
0
        private void InitializeCaves()
        {
            for (int caveNumber = 0; caveNumber < MAX_CAVES; caveNumber++)
            {
                _caves[caveNumber] = new Cave();
            }

            _caves[0].Name = "Traveler's Shelter";
            _caves[0].Description = "You are in the well known Traveler's Shelter. You find the cave has been used recently, most likely from a caravan that passed by a week ago.";
            _caves[0].Type = Cave.TypeName.Cave;
            _caves[0].IsLighted = true;
            _caves[0].CanEnter = true;

            _caves[1].Name = "Hidden Cave";
            _caves[1].Description = "You have found a hidden cave. Be cautious there are Goblin footprints on the ground. You peer around the corner and see a goblin sleeping around a campfire, behind a stalagmite you see a poorly hidden chest.";
            _caves[1].Type = Cave.TypeName.Cave;
            _caves[1].IsLighted = true;
            _caves[1].CanEnter = true;
            _caves[1].CaveNPC = new NPC
            {
                Name = "Gork the Stinky",
                Gender = NPC.GenderType.Male,
                Race = NPC.RaceType.Goblin,

            };

            _caves[2].Name = "Abandoned Iron Mine";
            _caves[2].Description = "You are in an abandoned iron mine. The dwarves mined iron here for years, they even found some gold veins, then one day they collapsed the tunnel and moved out in a hurry. Rumor was they found something down there they didn't want to escape. There are some recent signs of active mining. Someone really wants to know whats down there.";
            _caves[2].Type = Cave.TypeName.Mine;
            _caves[2].IsLighted = false;
            _caves[2].CanEnter = true;

            _caves[3].Name = "Beholder's Cavern";
            _caves[3].Description = "You come to a cave entrance, and you attempt to enter but are repelled by an invisible barrier. You need a magical item to enter this cave.";
            _caves[3].Type = Cave.TypeName.Cavern;
            _caves[3].IsLighted = false;
            _caves[3].CanEnter = false;
        }
Пример #34
0
        /*
         * Choose the "best" direction for "flowing"
         *
         * Note that ghosts and rock-eaters are never allowed to "flow",
         * since they should move directly towards the player.
         *
         * Prefer "non-diagonal" directions, but twiddle them a little
         * to angle slightly towards the player's actual location.
         *
         * Allow very perceptive monsters to track old "spoor" left by
         * previous locations occupied by the player.  This will tend
         * to have monsters end up either near the player or on a grid
         * recently occupied by the player (and left via "teleport").
         *
         * Note that if "smell" is turned on, all monsters get vicious.
         *
         * Also note that teleporting away from a location will cause
         * the monsters who were chasing you to converge on that location
         * as long as you are still near enough to "annoy" them without
         * being close enough to chase directly.  I have no idea what will
         * happen if you combine "smell" with low "aaf" values.
         */
        static bool get_moves_aux(Cave c, int m_idx, ref int yp, ref int xp)
        {
            int py = Misc.p_ptr.py;
            int px = Misc.p_ptr.px;

            int i, y, x, y1, x1;

            int when = 0;
            int cost = 999;

            Monster m_ptr = Cave.cave_monster(Cave.cave, m_idx);
            Monster_Race r_ptr = Misc.r_info[m_ptr.r_idx];

            /* Monster can go through rocks */
            if (r_ptr.flags.test(Monster_Flag.PASS_WALL.value, Monster_Flag.KILL_WALL.value)) return (false);

            /* Monster location */
            y1 = m_ptr.fy;
            x1 = m_ptr.fx;

            /* The player is not currently near the monster grid */
            if (c.when[y1][x1] < c.when[py][px])
            {
                /* The player has never been near the monster grid */
                if (c.when[y1][x1] == 0) return (false);

                /* The monster is not allowed to track the player */
                if (!Option.birth_ai_smell.value) return (false);
            }

            /* Monster is too far away to notice the player */
            if (c.cost[y1][x1] > Misc.MONSTER_FLOW_DEPTH) return (false);
            if (c.cost[y1][x1] > r_ptr.aaf) return (false);

            /* Hack -- Player can see us, run towards him */
            if (Cave.player_has_los_bold(y1, x1)) return (false);

            /* Check nearby grids, diagonals first */
            for (i = 7; i >= 0; i--)
            {
                /* Get the location */
                y = y1 + Misc.ddy_ddd[i];
                x = x1 + Misc.ddx_ddd[i];

                /* Ignore illegal locations */
                if (c.when[y][x] == 0) continue;

                /* Ignore ancient locations */
                if (c.when[y][x] < when) continue;

                /* Ignore distant locations */
                if (c.cost[y][x] > cost) continue;

                /* Save the cost and time */
                when = c.when[y][x];
                cost = c.cost[y][x];

                /* Hack -- Save the "twiddled" location */
                yp = py + 16 * Misc.ddy_ddd[i];
                xp = px + 16 * Misc.ddx_ddd[i];
            }

            /* No legal move (?) */
            if (when == 0) return (false);

            /* Success */
            return (true);
        }
Пример #35
0
        /*
         * Choose "logical" directions for monster movement
         *
         * We store the directions in a special "mm" array
         */
        static bool get_moves(Cave c, int m_idx, int[] mm)
        {
            int py = Misc.p_ptr.py;
            int px = Misc.p_ptr.px;

            Monster m_ptr = Cave.cave_monster(Cave.cave, m_idx);
            Monster_Race r_ptr = Misc.r_info[m_ptr.r_idx];

            int y, ay, x, ax;

            int move_val = 0;

            int y2 = py;
            int x2 = px;

            bool done = false;

            /* Flow towards the player */
            get_moves_aux(c, m_idx, ref y2, ref x2);

            /* Extract the "pseudo-direction" */
            y = m_ptr.fy - y2;
            x = m_ptr.fx - x2;

            /* Normal animal packs try to get the player out of corridors. */
            if (Option.birth_ai_packs.value && r_ptr.flags.has(Monster_Flag.FRIENDS.value) &&
                r_ptr.flags.has(Monster_Flag.ANIMAL.value) &&
                !r_ptr.flags.test(Monster_Flag.PASS_WALL.value, Monster_Flag.KILL_WALL.value))
            {
                throw new NotImplementedException();
                //int i, open = 0;

                ///* Count empty grids next to player */
                //for (i = 0; i < 8; i++)
                //{
                //    /* Check grid around the player for room interior (room walls count)
                //       or other empty space */
                //    if ((cave.feat[py + ddy_ddd[i]][px + ddx_ddd[i]] <= FEAT_MORE) ||
                //        (cave.info[py + ddy_ddd[i]][px + ddx_ddd[i]] & (CAVE_ROOM)))
                //    {
                //        /* One more open grid */
                //        open++;
                //    }
                //}

                ///* Not in an empty space and strong player */
                //if ((open < 7) && (p_ptr.chp > p_ptr.mhp / 2))
                //{
                //    /* Find hiding place */
                //    if (find_hiding(m_idx, &y, &x)) done = true;
                //}
            }

            /* Apply fear */
            if (!done && mon_will_run(m_idx))
            {
                /* Try to find safe place */
                if (!(Option.birth_ai_smart.value && find_safety(c, m_idx, out y, out x)))
                {
                    /* This is not a very "smart" method XXX XXX */
                    y = (-y);
                    x = (-x);
                }

                else
                {
                    /* Adjust movement */
                    get_fear_moves_aux(c, m_idx, ref y, ref x);
                }

                done = true;
            }

            /* Monster groups try to surround the player */
            if (!done && Option.birth_ai_packs.value && r_ptr.flags.has(Monster_Flag.FRIENDS.value))
            {
                throw new NotImplementedException();
                //int i;

                ///* If we are not already adjacent */
                //if (m_ptr.cdis > 1)
                //{
                //    /* Find an empty square near the player to fill */
                //    int tmp = randint0(8);
                //    for (i = 0; i < 8; i++)
                //    {
                //        /* Pick squares near player (pseudo-randomly) */
                //        y2 = py + ddy_ddd[(tmp + i) & 7];
                //        x2 = px + ddx_ddd[(tmp + i) & 7];

                //        /* Ignore filled grids */
                //        if (!cave_empty_bold(y2, x2)) continue;

                //        /* Try to fill this hole */
                //        break;
                //    }
                //}
                ///* Extract the new "pseudo-direction" */
                //y = m_ptr.fy - y2;
                //x = m_ptr.fx - x2;
            }

            /* Check for no move */
            if (x == 0 && y == 0) return (false);

            /* Extract the "absolute distances" */
            ax = Math.Abs(x);
            ay = Math.Abs(y);

            /* Do something weird */
            if (y < 0) move_val += 8;
            if (x > 0) move_val += 4;

            /* Prevent the diamond maneuvre */
            if (ay > (ax << 1))
            {
                move_val++;
                move_val++;
            }
            else if (ax > (ay << 1))
            {
                move_val++;
            }

            /* Analyze */
            switch (move_val)
            {
                case 0:
                {
                    mm[0] = 9;
                    if (ay > ax)
                    {
                        mm[1] = 8;
                        mm[2] = 6;
                        mm[3] = 7;
                        mm[4] = 3;
                    }
                    else
                    {
                        mm[1] = 6;
                        mm[2] = 8;
                        mm[3] = 3;
                        mm[4] = 7;
                    }
                    break;
                }

                case 1:
                case 9:
                {
                    mm[0] = 6;
                    if (y < 0)
                    {
                        mm[1] = 3;
                        mm[2] = 9;
                        mm[3] = 2;
                        mm[4] = 8;
                    }
                    else
                    {
                        mm[1] = 9;
                        mm[2] = 3;
                        mm[3] = 8;
                        mm[4] = 2;
                    }
                    break;
                }

                case 2:
                case 6:
                {
                    mm[0] = 8;
                    if (x < 0)
                    {
                        mm[1] = 9;
                        mm[2] = 7;
                        mm[3] = 6;
                        mm[4] = 4;
                    }
                    else
                    {
                        mm[1] = 7;
                        mm[2] = 9;
                        mm[3] = 4;
                        mm[4] = 6;
                    }
                    break;
                }

                case 4:
                {
                    mm[0] = 7;
                    if (ay > ax)
                    {
                        mm[1] = 8;
                        mm[2] = 4;
                        mm[3] = 9;
                        mm[4] = 1;
                    }
                    else
                    {
                        mm[1] = 4;
                        mm[2] = 8;
                        mm[3] = 1;
                        mm[4] = 9;
                    }
                    break;
                }

                case 5:
                case 13:
                {
                    mm[0] = 4;
                    if (y < 0)
                    {
                        mm[1] = 1;
                        mm[2] = 7;
                        mm[3] = 2;
                        mm[4] = 8;
                    }
                    else
                    {
                        mm[1] = 7;
                        mm[2] = 1;
                        mm[3] = 8;
                        mm[4] = 2;
                    }
                    break;
                }

                case 8:
                {
                    mm[0] = 3;
                    if (ay > ax)
                    {
                        mm[1] = 2;
                        mm[2] = 6;
                        mm[3] = 1;
                        mm[4] = 9;
                    }
                    else
                    {
                        mm[1] = 6;
                        mm[2] = 2;
                        mm[3] = 9;
                        mm[4] = 1;
                    }
                    break;
                }

                case 10:
                case 14:
                {
                    mm[0] = 2;
                    if (x < 0)
                    {
                        mm[1] = 3;
                        mm[2] = 1;
                        mm[3] = 6;
                        mm[4] = 4;
                    }
                    else
                    {
                        mm[1] = 1;
                        mm[2] = 3;
                        mm[3] = 4;
                        mm[4] = 6;
                    }
                    break;
                }

                default: /* case 12: */
                {
                    mm[0] = 1;
                    if (ay > ax)
                    {
                        mm[1] = 2;
                        mm[2] = 4;
                        mm[3] = 3;
                        mm[4] = 7;
                    }
                    else
                    {
                        mm[1] = 4;
                        mm[2] = 2;
                        mm[3] = 7;
                        mm[4] = 3;
                    }
                    break;
                }
            }

            /* Want to move */
            return (true);
        }
Пример #36
0
        /*
         * Provide a location to flee to, but give the player a wide berth.
         *
         * A monster may wish to flee to a location that is behind the player,
         * but instead of heading directly for it, the monster should "swerve"
         * around the player so that he has a smaller chance of getting hit.
         */
        static bool get_fear_moves_aux(Cave c, int m_idx, ref int yp, ref int xp)
        {
            int y, x, y1, x1, fy, fx, py, px, gy = 0, gx = 0;
            int when = 0, score = -1;
            int i;

            Monster m_ptr = Cave.cave_monster(Cave.cave, m_idx);
            Monster_Race r_ptr = Misc.r_info[m_ptr.r_idx];

            /* Player location */
            py = Misc.p_ptr.py;
            px = Misc.p_ptr.px;

            /* Monster location */
            fy = m_ptr.fy;
            fx = m_ptr.fx;

            /* Desired destination */
            y1 = fy - yp;
            x1 = fx - xp;

            /* The player is not currently near the monster grid */
            if (c.when[fy][fx] < c.when[py][px])
            {
                /* No reason to attempt flowing */
                return (false);
            }

            /* Monster is too far away to use flow information */
            if (c.cost[fy][fx] > Misc.MONSTER_FLOW_DEPTH) return (false);
            if (c.cost[fy][fx] > r_ptr.aaf) return (false);

            /* Check nearby grids, diagonals first */
            for (i = 7; i >= 0; i--)
            {
                int dis, s;

                /* Get the location */
                y = fy + Misc.ddy_ddd[i];
                x = fx + Misc.ddx_ddd[i];

                /* Ignore illegal locations */
                if (c.when[y][x] == 0) continue;

                /* Ignore ancient locations */
                if (c.when[y][x] < when) continue;

                /* Calculate distance of this grid from our destination */
                dis = Cave.distance(y, x, y1, x1);

                /* Score this grid */
                s = 5000 / (dis + 3) - 500 / (c.cost[y][x] + 1);

                /* No negative scores */
                if (s < 0) s = 0;

                /* Ignore lower scores */
                if (s < score) continue;

                /* Save the score and time */
                when = c.when[y][x];
                score = s;

                /* Save the location */
                gy = y;
                gx = x;
            }

            /* No legal move (?) */
            if (when == 0) return (false);

            /* Find deltas */
            yp = fy - gy;
            xp = fx - gx;

            /* Success */
            return (true);
        }
Пример #37
0
        /*
         * Process all the "live" monsters, once per game turn.
         *
         * During each game turn, we scan through the list of all the "live" monsters,
         * (backwards, so we can excise any "freshly dead" monsters), energizing each
         * monster, and allowing fully energized monsters to move, attack, pass, etc.
         *
         * Note that monsters can never move in the monster array (except when the
         * "compact_monsters()" function is called by "dungeon()" or "save_player()").
         *
         * This function is responsible for at least half of the processor time
         * on a normal system with a "normal" amount of monsters and a player doing
         * normal things.
         *
         * When the player is resting, virtually 90% of the processor time is spent
         * in this function, and its children, "process_monster()" and "make_move()".
         *
         * Most of the rest of the time is spent in "update_view()" and "light_spot()",
         * especially when the player is running.
         *
         * Note the special "MFLAG_NICE" flag, which prevents "nasty" monsters from
         * using any of their spell attacks until the player gets a turn.
         */
        public static void process_monsters(Cave c, byte minimum_energy)
        {
            int i;

            Monster m_ptr;
            Monster_Race r_ptr;

            /* Process the monsters (backwards) */
            for (i = Cave.cave_monster_max(c) - 1; i >= 1; i--)
            {
                /* Handle "leaving" */
                if (Misc.p_ptr.leaving) break;

                /* Get the monster */
                m_ptr = Cave.cave_monster(Cave.cave, i);

                /* Ignore "dead" monsters */
                if (m_ptr.r_idx == 0) continue;

                /* Not enough energy to move */
                if (m_ptr.energy < minimum_energy) continue;

                /* Use up "some" energy */
                m_ptr.energy -= 100;

                /* Heal monster? XXX XXX XXX */

                /* Get the race */
                r_ptr = Misc.r_info[m_ptr.r_idx];

                /*
                 * Process the monster if the monster either:
                 * - can "sense" the player
                 * - is hurt
                 * - can "see" the player (checked backwards)
                 * - can "smell" the player from far away (flow)
                 */
                if ((m_ptr.cdis <= r_ptr.aaf) || (m_ptr.hp < m_ptr.maxhp) ||
                    Cave.player_has_los_bold(m_ptr.fy, m_ptr.fx) || monster_can_flow(c, i))
                {
                    /* Process the monster */
                    process_monster(c, i);
                }
            }
        }
Пример #38
0
 public Task(TaskType type, Cave.Tile concernedTile)
 {
     this.type = type;
     this.concernedTile = concernedTile;
 }
Пример #39
0
        /*
         * Let an object fall to the ground at or near a location.
         *
         * The initial location is assumed to be "in_bounds_fully()".
         *
         * This function takes a parameter "chance".  This is the percentage
         * chance that the item will "disappear" instead of drop.  If the object
         * has been thrown, then this is the chance of disappearance on contact.
         *
         * This function will produce a description of a drop event under the player
         * when "verbose" is true.
         *
         * We check several locations to see if we can find a location at which
         * the object can combine, stack, or be placed.  Artifacts will try very
         * hard to be placed, including "teleporting" to a useful grid if needed.
         */
        public static void drop_near(Cave c, Object j_ptr, int chance, int y, int x, bool verbose)
        {
            int i, k, n, d, s;

            int bs, bn;
            int by, bx;
            int dy, dx;
            int ty, tx;

            Object o_ptr;

            //char o_name[80];
            string o_name;

            bool flag = false;

            bool plural = false;

            /* Extract plural */
            if (j_ptr.number != 1) plural = true;

            /* Describe object */
            o_name = j_ptr.object_desc(Detail.BASE);

            /* Handle normal "breakage" */
            if (j_ptr.artifact == null && (Random.randint0(100) < chance))
            {
                /* Message */
                Utilities.msg("The {0} break{1}.", o_name, Misc.PLURAL(plural));

                /* Failure */
                return;
            }

            /* Score */
            bs = -1;

            /* Picker */
            bn = 0;

            /* Default */
            by = y;
            bx = x;

            /* Scan local grids */
            for (dy = -3; dy <= 3; dy++)
            {
                /* Scan local grids */
                for (dx = -3; dx <= 3; dx++)
                {
                    bool comb = false;

                    /* Calculate actual distance */
                    d = (dy * dy) + (dx * dx);

                    /* Ignore distant grids */
                    if (d > 10) continue;

                    /* Location */
                    ty = y + dy;
                    tx = x + dx;

                    /* Skip illegal grids */
                    if (!Cave.cave.in_bounds_fully(ty, tx)) continue;

                    /* Require line of sight */
                    if (!Cave.los(y, x, ty, tx)) continue;

                    /* Require floor space */
                    if (Cave.cave.feat[ty][tx] != Cave.FEAT_FLOOR) continue;

                    /* No objects */
                    k = 0;
                    n = 0;

                    /* Scan objects in that grid */
                    for (o_ptr = get_first_object(ty, tx); o_ptr != null;
                            o_ptr = get_next_object(o_ptr))
                    {
                        /* Check for possible combination */
                        if (o_ptr.similar(j_ptr, object_stack_t.OSTACK_FLOOR))
                            comb = true;

                        /* Count objects */
                        if (!Squelch.item_ok(o_ptr))
                            k++;
                        else
                            n++;
                    }

                    /* Add new object */
                    if (!comb) k++;

                    /* Option -- disallow stacking */
                    if (Option.birth_no_stacking.value && (k > 1)) continue;

                    /* Paranoia? */
                    if ((k + n) > Misc.MAX_FLOOR_STACK && floor_get_idx_oldest_squelched(ty, tx) == 0) continue;

                    /* Calculate score */
                    s = 1000 - (d + k * 5);

                    /* Skip bad values */
                    if (s < bs) continue;

                    /* New best value */
                    if (s > bs) bn = 0;

                    /* Apply the randomizer to equivalent values */
                    if ((++bn >= 2) && (Random.randint0(bn) != 0)) continue;

                    /* Keep score */
                    bs = s;

                    /* Track it */
                    by = ty;
                    bx = tx;

                    /* Okay */
                    flag = true;
                }
            }

            /* Handle lack of space */
            if (!flag && j_ptr.artifact == null)
            {
                /* Message */
                Utilities.msg("The {0} disappear{1}.", o_name, Misc.PLURAL(plural));

                /* Debug */
                if (Misc.p_ptr.wizard) Utilities.msg("Breakage (no floor space).");

                /* Failure */
                return;
            }

            /* Find a grid */
            for (i = 0; !flag; i++)
            {
                /* Bounce around */
                if (i < 1000)
                {
                    ty = Random.rand_spread(by, 1);
                    tx = Random.rand_spread(bx, 1);
                }

                /* Random locations */
                else
                {
                    ty = Random.randint0(c.height);
                    tx = Random.randint0(c.width);
                }

                /* Require floor space */
                if (Cave.cave.feat[ty][tx] != Cave.FEAT_FLOOR) continue;

                /* Bounce to that location */
                by = ty;
                bx = tx;

                /* Require floor space */
                if (!Cave.cave_clean_bold(by, bx)) continue;

                /* Okay */
                flag = true;
            }

            /* Give it to the floor */
            if (floor_carry(c, by, bx, j_ptr) == 0)
            {
                /* Message */
                Utilities.msg("The {0} disappear{1}.", o_name, Misc.PLURAL(plural));

                /* Debug */
                if (Misc.p_ptr.wizard) Utilities.msg("Breakage (too many objects).");

                if (j_ptr.artifact != null) j_ptr.artifact.created = false;

                /* Failure */
                return;
            }

            /* Sound */
            //sound(MSG_DROP); //Nick: Add this later

            /* Message when an object falls under the player */
            if (verbose && (Cave.cave.m_idx[by][bx] < 0) && !Squelch.item_ok(j_ptr))
            {
                Utilities.msg("You feel something roll beneath your feet.");
            }
        }
Пример #40
0
        /*
         * Process a monster
         *
         * In several cases, we directly update the monster lore
         *
         * Note that a monster is only allowed to "reproduce" if there
         * are a limited number of "reproducing" monsters on the current
         * level.  This should prevent the level from being "swamped" by
         * reproducing monsters.  It also allows a large mass of mice to
         * prevent a louse from multiplying, but this is a small price to
         * pay for a simple multiplication method.
         *
         * XXX Monster fear is slightly odd, in particular, monsters will
         * fixate on opening a door even if they cannot open it.  Actually,
         * the same thing happens to normal monsters when they hit a door
         *
         * In addition, monsters which *cannot* open or bash down a door
         * will still stand there trying to open it...  XXX XXX XXX
         *
         * Technically, need to check for monster in the way combined
         * with that monster being in a wall (or door?) XXX
         */
        public static void process_monster(Cave c, int m_idx)
        {
            Monster m_ptr = Cave.cave_monster(Cave.cave, m_idx);
            Monster_Race r_ptr = Misc.r_info[m_ptr.r_idx];
            Monster_Lore l_ptr = Misc.l_list[m_ptr.r_idx];

            int i, oy, ox, ny, nx;

            int[] mm = new int[5];

            bool woke_up = false;
            bool stagger;

            bool do_turn;
            bool do_move;
            bool do_view;

            bool did_open_door;
            bool did_bash_door;

            /* Handle "sleep" */
            if (m_ptr.m_timed[(int)Misc.MON_TMD.SLEEP] != 0)
            {
                uint notice;

                /* Aggravation */
                if (Misc.p_ptr.check_state(Object_Flag.AGGRAVATE, Misc.p_ptr.state.flags))
                {
                    /* Wake the monster */
                    mon_clear_timed(m_idx, (int)Misc.MON_TMD.SLEEP, Misc.MON_TMD_FLG_NOTIFY, false);

                    /* Notice the "waking up" */
                    if (m_ptr.ml && !m_ptr.unaware)
                    {
                        //char m_name[80];
                        string m_name;

                        /* Get the monster name */
                        m_name = m_ptr.monster_desc(0);
                        //monster_desc(m_name, sizeof(m_name), m_ptr, 0);

                        /* Dump a message */
                        Utilities.msg("%^s wakes up.", m_name);

                        /* Hack -- Update the health bar */
                        if (Misc.p_ptr.health_who == m_idx) Misc.p_ptr.redraw |= (Misc.PR_HEALTH);
                    }

                    /* Efficiency XXX XXX */
                    return;
                }

                /* Anti-stealth */
                notice = (uint)Random.randint0(1024);

                /* Hack -- See if monster "notices" player */
                if ((notice * notice * notice) <= Misc.p_ptr.state.noise)
                {
                    int d = 1;

                    /* Wake up faster near the player */
                    if (m_ptr.cdis < 50) d = (100 / m_ptr.cdis);

                    /* Still asleep */
                    if (m_ptr.m_timed[(int)Misc.MON_TMD.SLEEP] > d)
                    {
                        /* Monster wakes up "a little bit" */
                        mon_dec_timed(m_idx, (int)Misc.MON_TMD.SLEEP, d , (ushort)Misc.MON_TMD_FLG_NOMESSAGE, false);

                        /* Notice the "not waking up" */
                        if (m_ptr.ml && !m_ptr.unaware)
                        {
                            /* Hack -- Count the ignores */
                            if (l_ptr.ignore < Byte.MaxValue)
                            {
                                l_ptr.ignore++;
                            }
                        }
                    }

                    /* Just woke up */
                    else
                    {
                        /* Reset sleep counter */
                        woke_up = mon_clear_timed(m_idx, (int)Misc.MON_TMD.SLEEP, Misc.MON_TMD_FLG_NOMESSAGE, false);

                        /* Notice the "waking up" */
                        if (m_ptr.ml && !m_ptr.unaware)
                        {
                            //char m_name[80];
                            string m_name;

                            /* Get the monster name */
                            m_name = m_ptr.monster_desc(0);

                            /* Dump a message */
                            //Utilities.msg("%^s wakes up.", m_name);
                            Utilities.msg(m_name + " wakes up.");

                            /* Hack -- Update the health bar */
                            if (Misc.p_ptr.health_who == m_idx) Misc.p_ptr.redraw |= (Misc.PR_HEALTH);

                            /* Hack -- Count the wakings */
                            if (l_ptr.wake < byte.MaxValue)
                            {
                                l_ptr.wake++;
                            }
                        }
                    }
                }

                /* Still sleeping */
                if (m_ptr.m_timed[(int)Misc.MON_TMD.SLEEP] != 0) return;
            }

            /* If the monster just woke up, then it doesn't act */
            if (woke_up) return;

            if (m_ptr.m_timed[(int)Misc.MON_TMD.FAST] != 0)
                mon_dec_timed(m_idx, Misc.MON_TMD.FAST, 1, 0, false);

            if (m_ptr.m_timed[(int)Misc.MON_TMD.SLOW] != 0)
                mon_dec_timed(m_idx, Misc.MON_TMD.SLOW, 1, 0, false);

            if (m_ptr.m_timed[(int)Misc.MON_TMD.STUN] != 0)
            {
                throw new NotImplementedException();
                //int d = 1;

                ///* Make a "saving throw" against stun */
                //if (randint0(5000) <= r_ptr.level * r_ptr.level)
                //{
                //    /* Recover fully */
                //    d = m_ptr.m_timed[MON_TMD_STUN];
                //}

                ///* Hack -- Recover from stun */
                //if (m_ptr.m_timed[MON_TMD_STUN] > d)
                //    mon_dec_timed(m_idx, MON_TMD_STUN, 1, MON_TMD_FLG_NOMESSAGE, false);
                //else
                //    mon_clear_timed(m_idx, MON_TMD_STUN, MON_TMD_FLG_NOTIFY, false);

                ///* Still stunned */
                //if (m_ptr.m_timed[MON_TMD_STUN]) return;
            }

            if (m_ptr.m_timed[(int)Misc.MON_TMD.CONF] != 0)
            {
                throw new NotImplementedException();
                //int d = randint1(r_ptr.level / 10 + 1);

                ///* Still confused */
                //if (m_ptr.m_timed[MON_TMD_CONF] > d)
                //    mon_dec_timed(m_idx, MON_TMD_CONF, d , MON_TMD_FLG_NOMESSAGE,
                //        false);
                //else
                //    mon_clear_timed(m_idx, MON_TMD_CONF, MON_TMD_FLG_NOTIFY, false);
            }

            if (m_ptr.m_timed[(int)Misc.MON_TMD.FEAR] != 0)
            {
                /* Amount of "boldness" */
                int d = Random.randint1(r_ptr.level / 10 + 1);

                if (m_ptr.m_timed[(int)Misc.MON_TMD.FEAR] > d)
                    mon_dec_timed(m_idx, Misc.MON_TMD.FEAR, d, Misc.MON_TMD_FLG_NOMESSAGE, false);
                else
                    mon_clear_timed(m_idx, Misc.MON_TMD.FEAR, Misc.MON_TMD_FLG_NOTIFY, false);
            }

            /* Get the origin */
            oy = m_ptr.fy;
            ox = m_ptr.fx;

            /* Attempt to "mutiply" (all monsters are allowed an attempt for lore
             * purposes, even non-breeders)
             */
            if (Misc.num_repro < Misc.MAX_REPRO)
            {
                int k, y, x;

                /* Count the adjacent monsters */
                for (k = 0, y = oy - 1; y <= oy + 1; y++)
                {
                    for (x = ox - 1; x <= ox + 1; x++)
                    {
                        /* Count monsters */
                        if (Cave.cave.m_idx[y][x] > 0) k++;
                    }
                }

                /* Multiply slower in crowded areas */
                if ((k < 4) && (k == 0 || Random.one_in_(k * Misc.MON_MULT_ADJ)))
                {
                    /* Successful breeding attempt, learn about that now */
                    if (m_ptr.ml) l_ptr.flags.on(Monster_Flag.MULTIPLY.value);

                    /* Try to multiply (only breeders allowed) */
                    if (r_ptr.flags.has(Monster_Flag.MULTIPLY.value) && multiply_monster(m_idx))
                    {
                        /* Make a sound */
                        if (m_ptr.ml)
                        {
                            //sound(MSG_MULTIPLY); //TODO: enable sound
                        }

                        /* Multiplying takes energy */
                        return;
                    }
                }
            }

            /* Mimics lie in wait */
            if (is_mimicking(m_idx)) return;

            /* Attempt to cast a spell */
            if (make_attack_spell(m_idx)) return;

            /* Reset */
            stagger = false;

            /* Confused */
            if (m_ptr.m_timed[(int)Misc.MON_TMD.CONF] != 0)
            {
                /* Stagger */
                stagger = true;
            }

            /* Random movement - always attempt for lore purposes */
            else
            {
                int roll = Random.randint0(100);

                /* Random movement (25%) */
                if (roll < 25)
                {
                    /* Learn about small random movement */
                    if (m_ptr.ml) l_ptr.flags.on(Monster_Flag.RAND_25.value);

                    /* Stagger */
                    if (r_ptr.flags.test(Monster_Flag.RAND_25.value, Monster_Flag.RAND_50.value)) stagger = true;
                }

                /* Random movement (50%) */
                else if (roll < 50)
                {
                    /* Learn about medium random movement */
                    if (m_ptr.ml) l_ptr.flags.on(Monster_Flag.RAND_50.value);

                    /* Stagger */
                    if (r_ptr.flags.has(Monster_Flag.RAND_50.value)) stagger = true;
                }

                /* Random movement (75%) */
                else if (roll < 75)
                {
                    /* Stagger */
                    if (r_ptr.flags.test_all(Monster_Flag.RAND_25.value, Monster_Flag.RAND_50.value))
                    {
                        stagger = true;
                    }
                }
            }

            /* Normal movement */
            if (!stagger)
            {
                /* Logical moves, may do nothing */
                if (!get_moves(Cave.cave, m_idx, mm)) return;
            }

            /* Assume nothing */
            do_turn = false;
            do_move = false;
            do_view = false;

            /* Assume nothing */
            did_open_door = false;
            did_bash_door = false;

            /* Process moves */
            for (i = 0; i < 5; i++)
            {
                /* Get the direction (or stagger) */
                int d = (stagger ? Misc.ddd[Random.randint0(8)] : mm[i]);

                /* Get the destination */
                ny = oy + Misc.ddy[d];
                nx = ox + Misc.ddx[d];

                /* Floor is open? */
                if (Cave.cave_floor_bold(ny, nx))
                {
                    /* Go ahead and move */
                    do_move = true;
                }

                /* Permanent wall in the way */
                else if (Cave.cave.feat[ny][nx] >= Cave.FEAT_PERM_EXTRA)
                {
                    /* Nothing */
                }

                /* Normal wall, door, or secret door in the way */
                else
                {
                    /* There's some kind of feature in the way, so learn about
                     * kill-wall and pass-wall now
                     */
                    if (m_ptr.ml)
                    {
                        l_ptr.flags.on(Monster_Flag.PASS_WALL.value);
                        l_ptr.flags.on(Monster_Flag.KILL_WALL.value);
                    }

                    /* Monster moves through walls (and doors) */
                    if (r_ptr.flags.has(Monster_Flag.PASS_WALL.value))
                    {
                        /* Pass through walls/doors/rubble */
                        do_move = true;
                    }

                    /* Monster destroys walls (and doors) */
                    else if (r_ptr.flags.has(Monster_Flag.KILL_WALL.value))
                    {
                        /* Eat through walls/doors/rubble */
                        do_move = true;

                        /* Forget the wall */
                        Cave.cave.info[ny][nx] &= ~(Cave.CAVE_MARK);

                        /* Notice */
                        Cave.cave_set_feat(c, ny, nx, Cave.FEAT_FLOOR);

                        /* Note changes to viewable region */
                        if (Cave.player_has_los_bold(ny, nx)) do_view = true;
                    }

                    /* Handle doors and secret doors */
                    else if (((Cave.cave.feat[ny][nx] >= Cave.FEAT_DOOR_HEAD) &&
                                 (Cave.cave.feat[ny][nx] <= Cave.FEAT_DOOR_TAIL)) ||
                                (Cave.cave.feat[ny][nx] == Cave.FEAT_SECRET))
                    {
                        bool may_bash = true;

                        /* Take a turn */
                        do_turn = true;

                        /* Learn about door abilities */
                        if (m_ptr.ml)
                        {
                            l_ptr.flags.on(Monster_Flag.OPEN_DOOR.value);
                            l_ptr.flags.on(Monster_Flag.BASH_DOOR.value);
                        }

                        /* Creature can open doors. */
                        if (r_ptr.flags.has(Monster_Flag.OPEN_DOOR.value))
                        {
                            /* Closed doors and secret doors */
                            if ((Cave.cave.feat[ny][nx] == Cave.FEAT_DOOR_HEAD) ||
                                     (Cave.cave.feat[ny][nx] == Cave.FEAT_SECRET)) {
                                /* The door is open */
                                did_open_door = true;

                                /* Do not bash the door */
                                may_bash = false;
                            }

                            /* Locked doors (not jammed) */
                            else if (Cave.cave.feat[ny][nx] < Cave.FEAT_DOOR_HEAD + 0x08) {
                                int k;

                                /* Door power */
                                k = ((Cave.cave.feat[ny][nx] - Cave.FEAT_DOOR_HEAD) & 0x07);

                                /* Try to unlock it */
                                if (Random.randint0(m_ptr.hp / 10) > k) {
                                    Utilities.msg("Something fiddles with a lock.");

                                    /* Reduce the power of the door by one */
                                    Cave.cave_set_feat(c, ny, nx, Cave.cave.feat[ny][nx] - 1);

                                    /* Do not bash the door */
                                    may_bash = false;
                                }
                            }
                        }

                        /* Stuck doors -- attempt to bash them down if allowed */
                        if (may_bash && r_ptr.flags.has(Monster_Flag.BASH_DOOR.value))
                        {
                            int k;

                            /* Door power */
                            k = ((Cave.cave.feat[ny][nx] - Cave.FEAT_DOOR_HEAD) & 0x07);

                            /* Attempt to bash */
                            if (Random.randint0(m_ptr.hp / 10) > k) {
                                Utilities.msg("Something slams against a door.");

                                /* Reduce the power of the door by one */
                                Cave.cave_set_feat(c, ny, nx, Cave.cave.feat[ny][nx] - 1);

                                /* If the door is no longer jammed */
                                if (Cave.cave.feat[ny][nx] < Cave.FEAT_DOOR_HEAD + 0x09)	{
                                    Utilities.msg("You hear a door burst open!");

                                    /* Disturb (sometimes) */
                                    Cave.disturb(Misc.p_ptr, 0, 0);

                                    /* The door was bashed open */
                                    did_bash_door = true;

                                    /* Hack -- fall into doorway */
                                    do_move = true;
                                }
                            }
                        }
                    }

                    /* Deal with doors in the way */
                    if (did_open_door || did_bash_door)
                    {
                        /* Break down the door */
                        if (did_bash_door && (Random.randint0(100) < 50))
                        {
                            Cave.cave_set_feat(c, ny, nx, Cave.FEAT_BROKEN);
                        }

                        /* Open the door */
                        else
                        {
                            Cave.cave_set_feat(c, ny, nx, Cave.FEAT_OPEN);
                        }

                        /* Handle viewable doors */
                        if (Cave.player_has_los_bold(ny, nx)) do_view = true;
                    }
                }

                /* Hack -- check for Glyph of Warding */
                if (do_move && (Cave.cave.feat[ny][nx] == Cave.FEAT_GLYPH))
                {
                    /* Assume no move allowed */
                    do_move = false;

                    /* Break the ward */
                    if (Random.randint1(Misc.BREAK_GLYPH) < r_ptr.level)
                    {
                        /* Describe observable breakage */
                        if ((Cave.cave.info[ny][nx] & (Cave.CAVE_MARK)) != 0)
                        {
                            Utilities.msg("The rune of protection is broken!");
                        }

                        /* Forget the rune */
                        Cave.cave.info[ny][nx] &= ~Cave.CAVE_MARK;

                        /* Break the rune */
                        Cave.cave_set_feat(c, ny, nx, Cave.FEAT_FLOOR);

                        /* Allow movement */
                        do_move = true;
                    }
                }

                /* The player is in the way. */
                if (do_move && (Cave.cave.m_idx[ny][nx] < 0))
                {
                    /* Learn about if the monster attacks */
                    if (m_ptr.ml) l_ptr.flags.on(Monster_Flag.NEVER_BLOW.value);

                    /* Some monsters never attack */
                    if (r_ptr.flags.has(Monster_Flag.NEVER_BLOW.value))
                    {
                        /* Do not move */
                        do_move = false;
                    }

                    /* Otherwise, attack the player */
                    else
                    {
                        /* Do the attack */
                        m_ptr.make_attack_normal(Misc.p_ptr);

                        /* Do not move */
                        do_move = false;

                        /* Took a turn */
                        do_turn = true;
                    }
                }

                /* Some monsters never move */
                if (do_move && r_ptr.flags.has(Monster_Flag.NEVER_MOVE.value))
                {
                    /* Learn about lack of movement */
                    if (m_ptr.ml) l_ptr.flags.on(Monster_Flag.NEVER_MOVE.value);

                    /* Do not move */
                    do_move = false;
                }

                /* A monster is in the way */
                if (do_move && (Cave.cave.m_idx[ny][nx] > 0))
                {
                    Monster n_ptr = Cave.cave_monster(Cave.cave, Cave.cave.m_idx[ny][nx]);

                    /* Kill weaker monsters */
                    bool kill_ok = r_ptr.flags.has(Monster_Flag.KILL_BODY.value);

                    /* Move weaker monsters if they can swap places */
                    /* (not in a wall) */
                    bool move_ok = (r_ptr.flags.has(Monster_Flag.MOVE_BODY.value) &&
                                   Cave.cave_floor_bold(m_ptr.fy, m_ptr.fx));

                    /* Assume no movement */
                    do_move = false;

                    if (compare_monsters(m_ptr, n_ptr) > 0)
                    {
                        /* Learn about pushing and shoving */
                        if (m_ptr.ml)
                        {
                            l_ptr.flags.on(Monster_Flag.KILL_BODY.value);
                            l_ptr.flags.on(Monster_Flag.MOVE_BODY.value);
                        }

                        if (kill_ok || move_ok)
                        {
                            /* Get the names of the monsters involved */
                            //char m_name[80];
                            //char n_name[80];
                            string m_name;
                            string n_name;
                            m_name = m_ptr.monster_desc(Desc.IND1);
                            n_name = n_ptr.monster_desc(Desc.IND1);

                            /* Allow movement */
                            do_move = true;

                            /* Monster ate another monster */
                            if (kill_ok)
                            {
                                /* Note if visible */
                                if (m_ptr.ml && (m_ptr.mflag & (Monster_Flag.MFLAG_VIEW)) != 0)
                                {
                                    string name = Char.ToUpper(m_name[0]) + m_name.Substring(1);
                                    Utilities.msg("{0} tramples over {1}.", name, n_name);
                                }

                                throw new NotImplementedException();
                                //delete_monster(ny, nx);
                            }
                            else
                            {
                                /* Note if visible */
                                if (m_ptr.ml && (m_ptr.mflag & (Monster_Flag.MFLAG_VIEW)) != 0)
                                {
                                    string name = Char.ToUpper(m_name[0]) + m_name.Substring(1);
                                    Utilities.msg("{0} pushes past {1}.", name, n_name);
                                }
                            }
                        }
                    }
                }

                /* Creature has been allowed move */
                if (do_move)
                {
                    short this_o_idx, next_o_idx = 0;

                    /* Learn about no lack of movement */
                    if (m_ptr.ml) l_ptr.flags.on(Monster_Flag.NEVER_MOVE.value);

                    /* Take a turn */
                    do_turn = true;

                    /* Move the monster */
                    monster_swap(oy, ox, ny, nx);

                    /* Possible disturb */
                    if (m_ptr.ml && (Option.disturb_move.value ||
                                (((m_ptr.mflag & (Monster_Flag.MFLAG_VIEW)) != 0) && Option.disturb_near.value)))
                    {
                        /* Disturb */
                        Cave.disturb(Misc.p_ptr, 0, 0);
                    }

                    /* Scan all objects in the grid */
                    for (this_o_idx = Cave.cave.o_idx[ny][nx]; this_o_idx != 0; this_o_idx = next_o_idx)
                    {
                        Object.Object o_ptr;

                        /* Get the object */
                        o_ptr = Object.Object.byid(this_o_idx);
                        if(o_ptr == null)
                            continue;

                        /* Get the next object */
                        next_o_idx = o_ptr.next_o_idx;

                        /* Skip gold */
                        if (o_ptr.tval == TVal.TV_GOLD) continue;

                        /* Learn about item pickup behavior */
                        if (m_ptr.ml)
                        {
                            l_ptr.flags.on(Monster_Flag.TAKE_ITEM.value);
                            l_ptr.flags.on(Monster_Flag.KILL_ITEM.value);
                        }

                        /* Take or Kill objects on the floor */
                        if (r_ptr.flags.has(Monster_Flag.TAKE_ITEM.value) || r_ptr.flags.has(Monster_Flag.KILL_ITEM.value))
                        {
                            Bitflag obj_flags = new Bitflag(Object_Flag.SIZE);
                            Bitflag mon_flags = new Bitflag(Monster_Flag.SIZE);

                            //char m_name[80];
                            //char o_name[80];
                            string m_name;
                            string o_name = "";

                            mon_flags.wipe();

                            /* Extract some flags */
                            o_ptr.object_flags(ref obj_flags);

                            /* Get the object name */
                            o_name = o_ptr.object_desc(Object.Object.Detail.PREFIX | Object.Object.Detail.FULL);

                            /* Get the monster name */
                            m_name = m_ptr.monster_desc(Desc.IND1);

                            /* React to objects that hurt the monster */
                            throw new NotImplementedException();
                            //react_to_slay(obj_flags, mon_flags);

                            ///* The object cannot be picked up by the monster */
                            //if (o_ptr.artifact || rf_is_inter(r_ptr.flags, mon_flags))
                            //{
                            //    /* Only give a message for "take_item" */
                            //    if (rf_has(r_ptr.flags, RF_TAKE_ITEM))
                            //    {
                            //        /* Describe observable situations */
                            //        if (m_ptr.ml && Cave.player_has_los_bold(ny, nx) && !squelch_item_ok(o_ptr))
                            //        {
                            //            /* Dump a message */
                            //            msg("%^s tries to pick up %s, but fails.",
                            //                       m_name, o_name);
                            //        }
                            //    }
                            //}

                            ///* Pick up the item */
                            //else if (rf_has(r_ptr.flags, RF_TAKE_ITEM))
                            //{
                            //    Object.Object i_ptr;
                            //    //object_type object_type_body;

                            //    /* Describe observable situations */
                            //    if (player_has_los_bold(ny, nx) && !squelch_item_ok(o_ptr))
                            //    {
                            //        /* Dump a message */
                            //        msg("%^s picks up %s.", m_name, o_name);
                            //    }

                            //    /* Get local object */
                            //    i_ptr = &object_type_body;

                            //    /* Obtain local object */
                            //    object_copy(i_ptr, o_ptr);

                            //    /* Delete the object */
                            //    delete_object_idx(this_o_idx);

                            //    /* Carry the object */
                            //    monster_carry(m_ptr, i_ptr);
                            //}

                            ///* Destroy the item */
                            //else
                            //{
                            //    /* Describe observable situations */
                            //    if (player_has_los_bold(ny, nx) && !squelch_item_ok(o_ptr))
                            //    {
                            //        /* Dump a message */
                            //        msgt(MSG_DESTROY, "%^s crushes %s.", m_name, o_name);
                            //    }

                            //    /* Delete the object */
                            //    delete_object_idx(this_o_idx);
                            //}
                        }
                    }
                }

                /* Stop when done */
                if (do_turn) break;
            }

            /* If we haven't done anything, try casting a spell again */
            if (Option.birth_ai_smart.value && !do_turn && !do_move)
            {
                /* Cast spell */
                if (make_attack_spell(m_idx)) return;
            }

            if (r_ptr.flags.has(Monster_Flag.HAS_LIGHT.value)) do_view = true;

            /* Notice changes in view */
            if (do_view)
            {
                /* Update the visuals */
                Misc.p_ptr.update |= (Misc.PU_UPDATE_VIEW | Misc.PU_MONSTERS);

                /* Fully update the flow XXX XXX XXX */
                Misc.p_ptr.update |= (Misc.PU_FORGET_FLOW | Misc.PU_UPDATE_FLOW);
            }

            /* Hack -- get "bold" if out of options */
            if (!do_turn && !do_move && m_ptr.m_timed[(int)Misc.MON_TMD.FEAR] != 0)
            {
                mon_clear_timed(m_idx, Misc.MON_TMD.FEAR, Misc.MON_TMD_FLG_NOTIFY, false);
            }

            /* If we see an unaware monster do something, become aware of it */
            if(do_turn && m_ptr.unaware) {
                throw new NotImplementedException();
                //become_aware(m_idx);
            }
        }
Пример #41
0
        /*
         * Pick a monster race, make a new monster of that race, then place
         * it in the dungeon.
         */
        public static bool pick_and_place_monster(Cave c, int y, int x, int depth, bool slp, bool grp, Object.Origin origin)
        {
            int r_idx;

            /* Pick a monster race */
            r_idx = get_mon_num(depth);

            /* Handle failure */
            if (r_idx == 0) return (false);

            /* Attempt to place the monster */
            return (place_new_monster(c, y, x, r_idx, slp, grp, origin));
        }
Пример #42
0
        /*
         * Attempt to allocate a random monster in the dungeon.
         *
         * Place the monster at least "dis" distance from the player.
         *
         * Use "slp" to choose the initial "sleep" status
         *
         * Use "depth" for the monster level
         */
        public static bool pick_and_place_distant_monster(Cave c, Loc loc, int dis, bool slp, int depth)
        {
            int py = loc.y;
            int px = loc.x;

            int y = 0, x = 0;
            int	attempts_left = 10000;

            Misc.assert(c != null);

            /* Find a legal, distant, unoccupied, space */
            while (--attempts_left != 0)
            {
                /* Pick a location */
                y = Random.randint0(c.height);
                x = Random.randint0(c.width);

                /* Require "naked" floor grid */
                if (!Cave.cave_isempty(c, y, x)) continue;

                /* Accept far away grids */
                if (Cave.distance(y, x, py, px) > dis) break;
            }

            if (attempts_left == 0)
            {
                if (Option.cheat_xtra.value || Option.cheat_hear.value)
                {
                    Utilities.msg("Warning! Could not allocate a new monster.");
                }

                return false;
            }

            /* Attempt to place the monster, allow groups */
            if (pick_and_place_monster(c, y, x, depth, slp, true, Object.Origin.DROP)) return (true);

            /* Nope */
            return (false);
        }
Пример #43
0
        /*
         * Delete/Remove all the monsters when the player leaves the level
         *
         * This is an efficient method of simulating multiple calls to the
         * "delete_monster()" function, with no visual effects.
         */
        public static void wipe_mon_list(Cave c, Player.Player p)
        {
            int i;

            /* Delete all the monsters */
            for (i = Cave.cave_monster_max(Cave.cave) - 1; i >= 1; i--)
            {
                Monster m_ptr = Cave.cave_monster(Cave.cave, i);

                Monster_Race r_ptr = Misc.r_info[m_ptr.r_idx];

                /* Skip dead monsters */
                if (m_ptr.r_idx == 0) continue;

                /* Hack -- Reduce the racial counter */
                r_ptr.cur_num--;

                /* Monster is gone */
                c.m_idx[m_ptr.fy][m_ptr.fx] = 0;

                /* Wipe the Monster */
                m_ptr.WIPE();
            }

            /* Reset "cave.mon_max" */
            Cave.cave.mon_max = 1;

            /* Reset "mon_cnt" */
            Cave.cave.mon_cnt = 0;

            /* Hack -- reset "reproducer" count */
            Misc.num_repro = 0;

            /* Hack -- no more target */
            Target.set_monster(0);

            /* Hack -- no more tracking */
            Cave.health_track(p, 0);
        }
Пример #44
0
        // XXX Nick: I think there is a better place to put this
        public static void player_place(Cave c, Player.Player p, int y, int x)
        {
            Misc.assert(c.m_idx[y][x] == 0);

            /* Save player location */
            p.py = (short)y;
            p.px = (short)x;

            /* Mark cave grid */
            c.m_idx[y][x] = -1;
        }
    void Start()
    {
        hazard_cap = 2;
        wumpusCave = new Cave();
        player = new Player("Hunter");
        wumpus = new Wumpus("Wumpy");
        bats = new List<Bat>(hazard_cap);
        pits = new List<Pit>(hazard_cap);

           //init bats & pits
           for (int i = 0; i < hazard_cap; i++ ){
           Bat bat = new Bat(i.ToString());
           bats.Add(bat);
           Pit pit = new Pit(i);
           pits.Add(pit);
            }

           positions = new int[6];
           setup(1);

           //assign player references to controllers
           //*I don't like it but I run into Object reference not set to an instance errors otherwise..
           inputController = GetComponent<InputController>();
           guiController =  GameObject.Find("Canvas").GetComponent<GUIController>();
           imgController = GetComponent<ImagePlaneController>();
           inputController.player = player;
           guiController.player = player;
           guiController.gameState = STATE;

           //assign Room prefabs to a room DAO
           Transform Rooms = GameObject.Find("WumpusCave/Rooms").GetComponent<Transform>();
           UnityEngine.Debug.Log(Rooms.childCount);
           for(int i = 0; i < Rooms.childCount; i++)
           Rooms.GetChild(i).GetComponent<RoomBehavior>().room = wumpusCave.rooms[i];
    }
Пример #46
0
        /*
         * Let the floor carry an object, deleting old squelched items if necessary
         */
        public static short floor_carry(Cave c, int y, int x, Object j_ptr)
        {
            int n = 0;

            short o_idx;

            short this_o_idx, next_o_idx = 0;

            /* Scan objects in that grid for combination */
            for (this_o_idx = c.o_idx[y][x]; this_o_idx != 0; this_o_idx = next_o_idx)
            {
                Object o_ptr = byid(this_o_idx);
                if(o_ptr == null)
                    continue;

                /* Get the next object */
                next_o_idx = o_ptr.next_o_idx;

                /* Check for combination */
                if (o_ptr.similar(j_ptr, object_stack_t.OSTACK_FLOOR))
                {
                    /* Combine the items */
                    o_ptr.absorb(j_ptr);

                    /* Result */
                    return (this_o_idx);
                }

                /* Count objects */
                n++;
            }

            /* Option -- disallow stacking */
            if (Option.birth_no_stacking.value && n != 0) return (0);

            /* The stack is already too large */
            if (n >= Misc.MAX_FLOOR_STACK)
            {
                throw new NotImplementedException();
                ///* Squelch the oldest squelched object */
                //short squelch_idx = floor_get_idx_oldest_squelched(y, x);

                //if (squelch_idx)
                //    delete_object_idx(squelch_idx);
                //else
                //    return 0;
            }

            /* Make an object */
            o_idx = o_pop();

            /* Success */
            if (o_idx != 0)
            {
                Object o_ptr;

                /* Get the object */
                o_ptr = byid(o_idx);

                /* Structure Copy */
                o_ptr = j_ptr.copy();

                /* Location */
                o_ptr.iy = (byte)y;
                o_ptr.ix = (byte)x;

                /* Forget monster */
                o_ptr.held_m_idx = 0;

                /* Link the object to the pile */
                o_ptr.next_o_idx = c.o_idx[y][x];

                /* Link the floor to the object */
                c.o_idx[y][x] = o_idx;

                Cave.cave_note_spot(c, y, x);
                Cave.cave_light_spot(c, y, x);
            }

            /* Result */
            return (o_idx);
        }
Пример #47
0
        /*
         * Choose a "safe" location near a monster for it to run toward.
         *
         * A location is "safe" if it can be reached quickly and the player
         * is not able to fire into it (it isn't a "clean shot").  So, this will
         * cause monsters to "duck" behind walls.  Hopefully, monsters will also
         * try to run towards corridor openings if they are in a room.
         *
         * This function may take lots of CPU time if lots of monsters are fleeing.
         *
         * Return true if a safe location is available.
         */
        public static bool find_safety(Cave c, int m_idx, out int yp, out int xp)
        {
            yp = 0;
            xp = 0;

            Monster m_ptr = Cave.cave_monster(Cave.cave, m_idx);

            int fy = m_ptr.fy;
            int fx = m_ptr.fx;

            int py = Misc.p_ptr.py;
            int px = Misc.p_ptr.px;

            int i, y, x, dy, dx, d, dis;
            int gy = 0, gx = 0, gdis = 0;

            int[] y_offsets;
            int[] x_offsets;

            /* Start with adjacent locations, spread further */
            for (d = 1; d < 10; d++)
            {
                /* Get the lists of points with a distance d from (fx, fy) */
                y_offsets = dist_offsets_y[d];
                x_offsets = dist_offsets_x[d];

                /* Check the locations */
                for (i = 0, dx = x_offsets[0], dy = y_offsets[0];
                     dx != 0 || dy != 0;
                     i++, dx = x_offsets[i], dy = y_offsets[i])
                {
                    y = fy + dy;
                    x = fx + dx;

                    /* Skip illegal locations */
                    if (!Cave.cave.in_bounds_fully(y, x)) continue;

                    /* Skip locations in a wall */
                    if (!Cave.cave_floor_bold(y, x)) continue;

                    /* Ignore grids very far from the player */
                    if (c.when[y][x] < c.when[py][px]) continue;

                    /* Ignore too-distant grids */
                    if (c.cost[y][x] > c.cost[fy][fx] + 2 * d) continue;

                    /* Check for absence of shot (more or less) */
                    if (!Cave.player_has_los_bold(y,x))
                    {
                        /* Calculate distance from player */
                        dis = Cave.distance(y, x, py, px);

                        /* Remember if further than previous */
                        if (dis > gdis)
                        {
                            gy = y;
                            gx = x;
                            gdis = dis;
                        }
                    }
                }

                /* Check for success */
                if (gdis > 0)
                {
                    /* Good location */
                    yp = fy - gy;
                    xp = fx - gx;

                    /* Found safe place */
                    return (true);
                }
            }

            /* No safe place */
            return (false);
        }
Пример #48
0
        static bool monster_can_flow(Cave c, int m_idx)
        {
            Monster m_ptr;
            Monster_Race r_ptr;
            int fy, fx;

            Misc.assert(c != null);

            m_ptr = Cave.cave_monster(Cave.cave, m_idx);
            r_ptr = Misc.r_info[m_ptr.r_idx];
            fy = m_ptr.fy;
            fx = m_ptr.fx;

            /* Check the flow (normal aaf is about 20) */
            if ((c.when[fy][fx] == c.when[Misc.p_ptr.py][Misc.p_ptr.px]) &&
                (c.cost[fy][fx] < Misc.MONSTER_FLOW_DEPTH) &&
                (c.cost[fy][fx] < r_ptr.aaf))
                return true;
            return false;
        }
Пример #49
0
        /*
         * Attempt to place a monster of the given race at the given location
         *
         * Note that certain monsters are now marked as requiring "friends".
         * These monsters, if successfully placed, and if the "grp" parameter
         * is true, will be surrounded by a "group" of identical monsters.
         *
         * Note that certain monsters are now marked as requiring an "escort",
         * which is a collection of monsters with similar "race" but lower level.
         *
         * Some monsters induce a fake "group" flag on their escorts.
         *
         * Note the "bizarre" use of non-recursion to prevent annoying output
         * when running a code profiler.
         *
         * Note the use of the new "monster allocation table" code to restrict
         * the "get_mon_num()" function to "legal" escort types.
         */
        public static bool place_new_monster(Cave c, int y, int x, int r_idx, bool slp, bool grp, Object.Origin origin)
        {
            //int i;

            Monster_Race r_ptr = Misc.r_info[r_idx];

            Misc.assert(c != null);

            /* Place one monster, or fail */
            if (!place_new_monster_one(y, x, r_idx, slp, (byte)origin)) return (false);

            /* Require the "group" flag */
            if (!grp) return (true);

            /* Friends for certain monsters */
            if (r_ptr.flags.has(Monster_Flag.FRIEND.value)) {
                int total = group_size_2(r_idx);

                /* Attempt to place a group */
                place_new_monster_group(c, y, x, r_idx, slp, total, (byte)origin);
            }

            /* Friends for certain monsters */
            if (r_ptr.flags.has(Monster_Flag.FRIENDS.value)) {
                int total = group_size_1(r_idx);

                /* Attempt to place a group */
                place_new_monster_group(c, y, x, r_idx, slp, total, (byte)origin);
            }

            /* Escorts for certain monsters */
            if (r_ptr.flags.has(Monster_Flag.ESCORT.value))
            {
                throw new NotImplementedException();
                ///* Try to place several "escorts" */
                //for (i = 0; i < 50; i++)
                //{
                //    int nx, ny, z, d = 3;

                //    /* Pick a location */
                //    scatter(&ny, &nx, y, x, d, 0);

                //    /* Require empty grids */
                //    if (!cave_empty_bold(ny, nx)) continue;

                //    /* Set the escort index */
                //    place_monster_idx = r_idx;

                //    /* Set the escort hook */
                //    get_mon_num_hook = place_monster_okay;

                //    /* Prepare allocation table */
                //    get_mon_num_prep();

                //    /* Pick a random race */
                //    z = get_mon_num(r_ptr.level);

                //    /* Remove restriction */
                //    get_mon_num_hook = null;

                //    /* Prepare allocation table */
                //    get_mon_num_prep();

                //    /* Handle failure */
                //    if (!z) break;

                //    /* Place a single escort */
                //    (void)place_new_monster_one(ny, nx, z, slp, origin);

                //    /* Place a "group" of escorts if needed */
                //    if (rf_has(r_info[z].flags, RF_FRIEND)) {
                //        int total = group_size_2(r_idx);

                //        /* Attempt to place a group */
                //        (void)place_new_monster_group(c, y, x, r_idx, slp, total, origin);
                //    }

                //    if (rf_has(r_info[z].flags, RF_FRIENDS) || rf_has(r_ptr.flags, RF_ESCORTS)) {
                //        int total = group_size_1(r_idx);

                //        /* Place a group of monsters */
                //        (void)place_new_monster_group(c, ny, nx, z, slp, total, origin);
                //    }
                //}
            }

            /* Success */
            return (true);
        }
Пример #50
0
        /*
         * Delete all the items when player leaves the level
         *
         * Note -- we do NOT visually reflect these (irrelevant) changes
         *
         * Hack -- we clear the "cave.o_idx[y][x]" field for every grid,
         * and the "m_ptr.next_o_idx" field for every monster, since
         * we know we are clearing every object.  Technically, we only
         * clear those fields for grids/monsters containing objects,
         * and we clear it once for every such object.
         */
        public static void wipe_o_list(Cave c)
        {
            int i;

            /* Delete the existing objects */
            for (i = 1; i < Misc.o_max; i++)
            {
                Object o_ptr = Object.byid((short)i);
                if (o_ptr == null || o_ptr.kind == null) continue;

                /* Preserve artifacts or mark them as lost in the history */
                if (o_ptr.artifact != null) {
                    throw new NotImplementedException();
                    ///* Preserve if dungeon creation failed, or preserve mode, or items
                    // * carried by monsters, and only artifacts not seen */
                    //if ((!character_dungeon || !OPT(birth_no_preserve) ||
                    //        o_ptr.held_m_idx) && !object_was_sensed(o_ptr))
                    //    o_ptr.artifact.created = false;
                    //else
                    //    history_lose_artifact(o_ptr.artifact);
                }

                /* Monster */
                if (o_ptr.held_m_idx != 0)
                {
                    Monster.Monster m_ptr;

                    /* Monster */
                    m_ptr = Cave.cave_monster(Cave.cave, o_ptr.held_m_idx);

                    /* Hack -- see above */
                    m_ptr.hold_o_idx = 0;
                }

                /* Dungeon */
                else
                {
                    /* Get the location */
                    int y = o_ptr.iy;
                    int x = o_ptr.ix;

                    /* Hack -- see above */
                    c.o_idx[y][x] = 0;
                }

                /* Wipe the object */
                o_ptr.WIPE();
            }

            /* Reset "o_max" */
            Misc.o_max = 1;

            /* Reset "o_cnt" */
            Misc.o_cnt = 0;
        }
Пример #51
0
    void Start()
    {
        constitution = level;
        agility = level;
        strength = level;

        for(int i = 0; i < level - 1; i++) {
            int skill = UnityEngine.Random.Range (1, 5);

            switch(skill) {
            case 1:
                constitution ++;
                break;
            case 2:
                agility ++;
                break;
            case 3:
                strength ++;
                break;
            }
        }

        health = 50.0f + constitution * 10;
        speed = 1.0f + agility * 0.33f;
        hitDamage = 4.0f + strength;

        pathfind = GetComponent<AStar2D>();
        if(pathfind == null) {
            Debug.Log ("Pathfind not found!");
        }

        grid = spawnpoint.GetComponent<HumanSpawnPoint>().grid;
        map = spawnpoint.GetComponent<HumanSpawnPoint>().map;
        resourcesScript = Camera.main.gameObject.GetComponent<ResourcesControl>();
        armyScript = spawnpoint.GetComponent<HumanSpawnPoint>().monsterCore.GetComponent<MonsterCore>().armyScript;
        pathfind.speed = speed;
        pathfind.seeker.StartPath(transform.position, spawnpoint.GetComponent<HumanSpawnPoint>().monsterCore.transform.position, pathfind.OnPathComplete);
    }
Пример #52
0
        /*
         * Attempt to place a "group" of monsters around the given location
         */
        static bool place_new_monster_group(Cave c, int y, int x, int r_idx, bool slp, int total, byte origin)
        {
            int n, i;

            int hack_n;

            byte[] hack_y = new byte[GROUP_MAX];
            byte[] hack_x = new byte[GROUP_MAX];

            /* Start on the monster */
            hack_n = 1;
            hack_x[0] = (byte)x;
            hack_y[0] = (byte)y;

            /* Puddle monsters, breadth first, up to total */
            for (n = 0; (n < hack_n) && (hack_n < total); n++) {
                /* Grab the location */
                int hx = hack_x[n];
                int hy = hack_y[n];

                /* Check each direction, up to total */
                for (i = 0; (i < 8) && (hack_n < total); i++) {
                    int mx = hx + Misc.ddx_ddd[i];
                    int my = hy + Misc.ddy_ddd[i];

                    /* Walls and Monsters block flow */
                    if (!Cave.cave_empty_bold(my, mx)) continue;

                    /* Attempt to place another monster */
                    if (place_new_monster_one(my, mx, r_idx, slp, origin)) {
                        /* Add it to the "hack" set */
                        hack_y[hack_n] = (byte)my;
                        hack_x[hack_n] = (byte)mx;
                        hack_n++;
                    }
                }
            }

            /* Success */
            return (true);
        }
Пример #53
0
    void Start()
    {
        pathfind = GetComponent<AStar2D>();
        if(pathfind == null) {
            Debug.Log ("Pathfind not found!");
        }

        grid = spawnpoint.GetComponent<HumanSpawnPoint>().grid;
        map = spawnpoint.GetComponent<HumanSpawnPoint>().map;
        resourcesScript = Camera.main.gameObject.GetComponent<ResourcesControl>();
        pathfind.speed = 1.5f;
        pathfind.seeker.StartPath(transform.position, spawnpoint.GetComponent<HumanSpawnPoint>().monsterCore.transform.position, pathfind.OnPathComplete);
    }