/// <summary>
        /// Constructor to initalize NaturalFeature as a River.
        /// </summary>
        /// <param name="river_start">The gridcoordinate that the river starts on</param>
        /// <param name="river_end">The gridcoordinate that the river ends on</param>
        /// <param name="deep_thick">The deep water thickness is 1 + up to this #</param>
        /// <param name="shallow_thick">Shallow water thickness is 1 + up to this #</param>
        /// <param name="bank_thick">Shoreline thickness is 1 + up to this #</param>
        public NaturalFeature(gridCoordinate river_start, gridCoordinate river_end, River_Type r_typ,
                              int deep_thick, int shallow_thick, int bank_thick)
        {
            feature_startCoord = river_start;
            feature_endCoord = river_end;
            deepwater_thickness = deep_thick;
            shallow_thickness = shallow_thick;
            banks_thickness = bank_thick;
            my_fType = Feature_Type.River;
            my_rivType = r_typ;

            calculate_crossing_points();
        }
        /// <summary>
        /// Constructor to initialize NaturalFeature as a Chasm.
        /// </summary>
        /// <param name="chasm_start"></param>
        /// <param name="chasm_end"></param>
        /// <param name="max_thickness"></param>
        public NaturalFeature(gridCoordinate chasm_start, gridCoordinate chasm_end, int max_thickness)
        {
            feature_startCoord = chasm_start;
            feature_endCoord = chasm_end;
            maximum_thickness = max_thickness;
            my_fType = Feature_Type.Chasm;

            int a = Math.Abs(feature_startCoord.x - feature_endCoord.x);
            int b = Math.Abs(feature_startCoord.y - feature_endCoord.y);
            chasm_length = (int)Math.Sqrt((a * a) + (b * b));
            Random rGen = new Random();

            int max_length = chasm_length - 3;
            int min_length = Math.Min(4, max_length - 1);

            cavern_point = rGen.Next(min_length, max_length);
            cavern_right = true;
            if (rGen.Next(2) == 0)
                cavern_right = false;
        }
        public Boneyard(gridCoordinate sGridCoord, ContentManager sCont, Texture2D b_texture, int sIndex, bool bossmonster)
            : base(sGridCoord, sCont, b_texture, sIndex, Monster_Size.Large)
        {
            monster_typ = Monster_Type.Boneyard;
            normal_texture = sCont.Load<Texture2D>("Enemies/boneyard");
            bitey_texture = sCont.Load<Texture2D>("Enemies/boneyard_biting");
            my_Texture = normal_texture;

            if (bossmonster)
            {
                max_hitPoints = 250;
                boss_monster = true;

                min_damage = 6;
                max_damage = 18;
                bone_spear_mindmg = 12;
                bone_spear_maxdmg = 18;
                bite_min_damage = 16;
                bite_max_damage = 24;
                blood_spray_mindmg = 6;
                blood_spray_maxdmg = 6;
            }
            else
            {
                max_hitPoints = 60;

                min_damage = 12;
                max_damage = 24;
                bone_spear_mindmg = 12;
                bone_spear_maxdmg = 20;
                bite_min_damage = 20;
                bite_max_damage = 30;
                blood_spray_mindmg = 6;
                blood_spray_maxdmg = 10;
            }
            hitPoints = max_hitPoints;

            //SENSORY
            base_sight_range = 6;
            can_hear = true;
            sounds_i_can_hear.Add(SoundPulse.Sound_Types.Player);
            sounds_i_can_hear.Add(SoundPulse.Sound_Types.Voidwraith_Scream);
            base_listen_threshold.Add(4);
            base_listen_threshold.Add(1);

            set_senses_to_baseline();

            my_name = "Boneyard";
            melee_dodge = 5;
            ranged_dodge = 5;
            set_initial_dodge_values();

            //Other values
            bite_available = true;
            volley_available = true;
            volley_stage = 0;
            bite_stage = 0;
            blind_volley_stage = 0;
            sequence_cooldown = 6;

            have_i_seen_player = false;
            last_seen_player_loc = my_grid_coords[0];
            current_sequence = attack_sequence.None;
        }
 public void fire_singletarget_bonespear(Floor fl, gridCoordinate target_GC)
 {
     fl.addmsg("The Boneyard spits a bone spear at you!");
     Projectile bs = new Projectile(randomly_chosen_personal_coord(), target_GC,
                                    Projectile.projectile_type.Bonespear, ref cont, true,
                                    Scroll.Atk_Area_Type.singleTile);
     bs.set_damage_range(bone_spear_mindmg, bone_spear_maxdmg);
     bs.set_damage_type(bone_spear_dmgtyp);
     fl.create_new_projectile(bs);
 }
Exemple #5
0
        private bool is_on_or_near_wallTile(gridCoordinate target_point)
        {
            bool is_on_or_near = false;
            if (target_point.x < startXPos || target_point.x >= startXPos + roomWidth ||
                target_point.y < startYPos || target_point.y >= startYPos + roomHeight)
                is_on_or_near = true;

            int hi_x = target_point.x + 1;
            int lo_x = target_point.x - 1;
            int hi_y = target_point.y + 1;
            int lo_y = target_point.y - 1;

            if (hi_x < startXPos || hi_x >= startXPos + roomWidth ||
                lo_x < startXPos || lo_x >= startXPos + roomWidth ||
                hi_y < startYPos || hi_y >= startYPos + roomHeight ||
                lo_y < startYPos || lo_y >= startYPos + roomHeight)
                is_on_or_near = true;

            return is_on_or_near;
        }
Exemple #6
0
        public void render_monsters_to_board(ref List<Monster> fl_monsters, 
                                             ref List<Doodad> fl_doodads,
                                             Spawn_Table_Manager spawn_manager,
                                             ContentManager cmgr,
                                             Texture2D blank_texture, FloorBuilder flb)
        {
            List<KeyValuePair<string, gridCoordinate>> final_monster_list = new List<KeyValuePair<string,gridCoordinate>>();
            //Put all monsters onto the final spawning list, with the exception of Schrodingers_hk, which is spawned immediately.
            for (int i = 0; i < monster_list.Count; i++)
            {
                string monster_name = monster_list[i].Key;
                gridCoordinate monster_coord = monster_list[i].Value;
                gridCoordinate new_monster_coord = new gridCoordinate(monster_coord.x + startXPos,
                                                                      monster_coord.y + startYPos);
                if (flb.is_tile_obstructed(new_monster_coord))
                    new_monster_coord = null;

                if (String.Compare(monster_name, "Schrodingers_HK") != 0)
                    final_monster_list.Add(new KeyValuePair<string, gridCoordinate>(monster_name, new_monster_coord));
                else
                {
                    //If the spawn table comes up hollow knight, add it with a normal chance to spawn a red knight
                    //Otherwise add a suit of armor.
                    if (spawn_manager.roll_to_spawn_family(Monster.Monster_Family.SpiritKnight))
                        spawn_manager.place_monster_from_family(Monster.Monster_Family.SpiritKnight, ref fl_monsters, blank_texture,
                                                                new_monster_coord, flb);
                    else
                        if(new_monster_coord != null && !flb.is_tile_obstructed(new_monster_coord))
                            fl_doodads.Add(new Doodad(Doodad.Doodad_Type.ArmorSuit, cmgr, new_monster_coord, fl_doodads.Count));
                }
            }

            //Spawn all monsters placed by family.
            for (int i = 0; i < monster_family_list.Count; i++)
            {
                //Place at perscribed spot
                gridCoordinate new_monster_coord = new gridCoordinate(monster_family_list[i].Value.x + startXPos,
                                                                      monster_family_list[i].Value.y + startYPos);
                //Unless said spot is blocked - then find a new, random position for the monster. This will occur automatically
                //upon a null coordinate being passed.
                if (flb.is_tile_obstructed(new_monster_coord))
                    new_monster_coord = null;

                if (spawn_manager.family_in_table(monster_family_list[i].Key))
                    spawn_manager.place_monster_from_family(monster_family_list[i].Key, ref fl_monsters, blank_texture,
                                                            new_monster_coord, flb);
            }

            //Spawn all monsters
            for (int i = 0; i < final_monster_list.Count; i++)
            {
                spawn_manager.place_specific_monster_byString(final_monster_list[i].Key, ref fl_monsters, blank_texture,
                                                              final_monster_list[i].Value, flb);
            }
        }
Exemple #7
0
        public gridCoordinate find_closest_hall_anchor(gridCoordinate to_this_point)
        {
            int distance_from_anchor = 64000;
            int target_anchor = -1;
            for (int i = 0; i < hallway_anchors.Count; i++)
            {
                gridCoordinate base_anchor = hallway_anchors[i];
                gridCoordinate actual_anchor = new gridCoordinate(base_anchor.x + startXPos, base_anchor.y + startYPos);
                int difference = -1;
                int x_difference = Math.Abs(to_this_point.x - actual_anchor.x);
                int y_difference = Math.Abs(to_this_point.y - actual_anchor.y);
                if (x_difference == 0)
                    difference = y_difference;
                else if (y_difference == 0)
                    difference = x_difference;
                else
                    difference = (int)Math.Sqrt((x_difference * x_difference) + (y_difference * y_difference));
                if (difference < distance_from_anchor)
                {
                    distance_from_anchor = difference;
                    target_anchor = i;
                }
            }

            gridCoordinate base_return_anchor = hallway_anchors[target_anchor];
            return new gridCoordinate(base_return_anchor.x + startXPos, base_return_anchor.y + startYPos);
        }
        private void add_entrance()
        {
            //Then place an entrance.
            while (!entranceplaced)
            {
                gridCoordinate entrance_coord = random_valid_position(current_floorsize, Monster.Monster_Size.Normal,
                                                                      random_coord_restrictions.Entrance);

                Tile.Tile_Type entrance_tile = Tile.Tile_Type.Entrance;
                if (fl_type == Floor.floor_type.Cavern)
                    entrance_tile = Tile.Tile_Type.Cavern_Entrance;

                for (int x = entrance_coord.x - 1; x <= entrance_coord.x + 1; x++)
                    for (int y = entrance_coord.y - 1; y <= entrance_coord.y + 1; y++)
                        if (x < current_floorsize && x > 0 && y < current_floorsize && y > 0 &&
                           (x == entrance_coord.x || y == entrance_coord.y) && !entranceplaced &&
                           floorTiles[x][y].isVoid())
                        {
                            floorTiles[x][y].set_tile_type(entrance_tile, universal_spritesheet, dungeon_specific_spritesheet, general_texture_map);
                            dungeon_entrance_coord = new gridCoordinate(x, y);
                            entranceplaced = true;
                        }
            }
        }
        private void place_corner_corpses()
        {
            for (int i = 0; i < roomlayout.Count; i++)
            {
                if (roomlayout[i].has_corpses())
                {
                    int corners = roomlayout[i].how_many_corners_have_corpses();
                    int roomX = roomlayout[i].startXPos;
                    int roomY = roomlayout[i].startYPos;
                    int roomH = roomlayout[i].roomHeight - 1;
                    int roomW = roomlayout[i].roomWidth - 1;
                    int x_dir_check = 0;
                    int y_dir_check = 0;
                    gridCoordinate top_left = new gridCoordinate(roomX, roomY);
                    gridCoordinate top_right = new gridCoordinate(roomX + roomW, roomY);
                    gridCoordinate bottom_left = new gridCoordinate(roomX, roomY + roomH);
                    gridCoordinate bottom_right = new gridCoordinate(roomX + roomW, roomY + roomH);
                    for (int c = 0; c < corners; c++)
                    {
                        bool corner_valid = false;
                        gridCoordinate target_corner_gc = new gridCoordinate(-1, -1);
                        int tries = 0;
                        while (!corner_valid && tries < 20)
                        {
                            //pick a random corner.
                            int target_corner = randGen.Next(4);
                            if (target_corner == 0)
                            {
                                target_corner_gc = top_left;
                                x_dir_check = -1;
                                y_dir_check = -1;
                            }
                            else if (target_corner == 1)
                            {
                                target_corner_gc = top_right;
                                x_dir_check = 1;
                                y_dir_check = -1;
                            }
                            else if (target_corner == 2)
                            {
                                target_corner_gc = bottom_left;
                                x_dir_check = -1;
                                y_dir_check = 1;
                            }
                            else if (target_corner == 3)
                            {
                                target_corner_gc = bottom_right;
                                x_dir_check = 1;
                                y_dir_check = 1;
                            }

                            //Next, check to see if there's a corpse pile in that corner
                            //Already.
                            corner_valid = true;
                            for (int d = 0; d < props.Count; d++)
                                if (props[d].get_g_coord().x == target_corner_gc.x &&
                                    props[d].get_g_coord().y == target_corner_gc.y)
                                    corner_valid = false;
                            tries++;
                        }

                        if (corner_valid)
                        {
                            int number_of_corpses = randGen.Next(1, 4); //Math.Min(3, 5 - randGen.Next(6));

                            if (!is_tile_obstructed(target_corner_gc) &&
                               is_tile_obstructed(new gridCoordinate(target_corner_gc.x + x_dir_check, target_corner_gc.y)) &&
                               is_tile_obstructed(new gridCoordinate(target_corner_gc.x, target_corner_gc.y + y_dir_check)))
                                props.Add(new Doodad(Doodad.Doodad_Type.CorpsePile, cManager, target_corner_gc, props.Count));
                            if (number_of_corpses >= 2)
                            {
                                gridCoordinate pile_2 = new gridCoordinate(target_corner_gc.x + (x_dir_check * -1), target_corner_gc.y);
                                if (!is_tile_obstructed(pile_2) &&
                                    is_tile_obstructed(new gridCoordinate(pile_2.x, pile_2.y + y_dir_check)))
                                    props.Add(new Doodad(Doodad.Doodad_Type.CorpsePile, cManager, pile_2, props.Count));
                            }
                            if (number_of_corpses == 3)
                            {
                                gridCoordinate pile_3 = new gridCoordinate(target_corner_gc.x, target_corner_gc.y + (y_dir_check * -1));
                                if (!is_tile_obstructed(pile_3) &&
                                    is_tile_obstructed(new gridCoordinate(pile_3.x + x_dir_check, pile_3.y)))
                                    props.Add(new Doodad(Doodad.Doodad_Type.CorpsePile, cManager, pile_3, props.Count));
                            }
                        }
                    }
                }
            }
        }
        private gridCoordinate[] generate_overlay_table()
        {
            gridCoordinate texture_1 = new gridCoordinate(2, 0); //North Edge only
            gridCoordinate texture_2 = new gridCoordinate(0, 0); //East Edge only
            gridCoordinate texture_3 = new gridCoordinate(0, 3); //East Edge + North Edge
            gridCoordinate texture_4 = new gridCoordinate(3, 0); //South Edge only
            gridCoordinate texture_5 = new gridCoordinate(2, 6); //South Edge + North Edge
            gridCoordinate texture_6 = new gridCoordinate(4, 2); //South Edge + East Edge
            gridCoordinate texture_7 = new gridCoordinate(1, 3); //All edges but west
            gridCoordinate texture_8 = new gridCoordinate(1, 0); //Only West Edge
            gridCoordinate texture_9 = new gridCoordinate(6, 2); //West + North Edge
            gridCoordinate texture_10 = new gridCoordinate(3, 6); //East + West Edge
            gridCoordinate texture_11 = new gridCoordinate(3, 3); //All edges but south
            gridCoordinate texture_12 = new gridCoordinate(5, 2); //West + South Edge
            gridCoordinate texture_13 = new gridCoordinate(2, 3); //All edges but east
            gridCoordinate texture_14 = new gridCoordinate(4, 3); //All edges but north
            gridCoordinate texture_15 = new gridCoordinate(5, 3); //All edges

            gridCoordinate texture_16 = new gridCoordinate(3, 2); //NW corner
            gridCoordinate texture_17 = new gridCoordinate(6, 3); //East edge + NW corner
            gridCoordinate texture_18 = new gridCoordinate(4, 4); //Sourth edge + NW corner
            gridCoordinate texture_19 = new gridCoordinate(0, 6); //South Edge + East Edge + NW Corner

            gridCoordinate texture_20 = new gridCoordinate(2, 2); //NE corner
            gridCoordinate texture_21 = new gridCoordinate(3, 4); //South Edge + NE Corner
            gridCoordinate texture_22 = new gridCoordinate(2, 4); //West Edge + NE Corner
            gridCoordinate texture_23 = new gridCoordinate(6, 5); //South Edge + west Edge + NE Corner

            gridCoordinate texture_24 = new gridCoordinate(6, 1); //ne corner + nw corner
            gridCoordinate texture_25 = new gridCoordinate(1, 5); //south edge + ne corner + nw corner

            gridCoordinate texture_26 = new gridCoordinate(1, 2); //SE Corner
            gridCoordinate texture_27 = new gridCoordinate(5, 4); //North Edge + SE corner
            gridCoordinate texture_28 = new gridCoordinate(1, 4); //West Edge + SE corner
            gridCoordinate texture_29 = new gridCoordinate(5, 5); //West Edge + North Edge + SE Corner

            gridCoordinate texture_30 = new gridCoordinate(1, 1); //SE corner + NW corner

            gridCoordinate texture_31 = new gridCoordinate(4, 1); //SE corner + NE corner
            gridCoordinate texture_32 = new gridCoordinate(3, 5); //West Edge + SE Corner + NE corner

            gridCoordinate texture_33 = new gridCoordinate(0, 2); //SE NE NW corners

            gridCoordinate texture_34 = new gridCoordinate(4, 0); //SW Corner
            gridCoordinate texture_35 = new gridCoordinate(6, 4); //North Edge + SW Corner
            gridCoordinate texture_36 = new gridCoordinate(0, 4); //East Edge + SW Corner
            gridCoordinate texture_37 = new gridCoordinate(3, 5); //East Edge + North Edge + SW Corner

            gridCoordinate texture_38 = new gridCoordinate(6, 0); //SW NW Corners
            gridCoordinate texture_39 = new gridCoordinate(2, 5); //East Edge + SW corner + NW Corner

            gridCoordinate texture_40 = new gridCoordinate(2, 1); //SW NE Corners

            gridCoordinate texture_41 = new gridCoordinate(5, 1); //SW NE NW Corners

            gridCoordinate texture_42 = new gridCoordinate(5, 0); //SW SE Corners
            gridCoordinate texture_43 = new gridCoordinate(0, 5); //North Edge + SE + SW Corners

            gridCoordinate texture_44 = new gridCoordinate(0, 1); //SW SE NW Corners

            gridCoordinate texture_45 = new gridCoordinate(3, 1); //SW SE NE Corners

            gridCoordinate texture_46 = new gridCoordinate(1, 6); //All corners

            gridCoordinate[] lookups =
            {  null,       texture_1,  texture_2,  texture_3,  texture_4,  texture_5, texture_6,  texture_7, texture_8,  texture_9,  texture_10, texture_11, texture_12, texture_13, texture_14, texture_15,
               texture_16, texture_1,  texture_17, texture_3,  texture_18, texture_5, texture_19, texture_7, texture_8,  texture_9,  texture_10, texture_11, texture_12, texture_13, texture_14, texture_15, // nw
               texture_20, texture_1,  texture_2,  texture_3,  texture_21, texture_5, texture_6,  texture_7, texture_22, texture_9,  texture_10, texture_11, texture_23, texture_13, texture_14, texture_15, // ne
               texture_24, texture_1,  texture_17, texture_3,  texture_25, texture_5, texture_19, texture_7, texture_22, texture_9,  texture_10, texture_11, texture_23, texture_13, texture_14, texture_15, // ne + nw
               texture_26, texture_27, texture_2,  texture_3,  texture_4,  texture_5, texture_6,  texture_7, texture_28, texture_29, texture_10, texture_11, texture_12, texture_13, texture_14, texture_15, // se
               texture_30, texture_27, texture_17, texture_3,  texture_18, texture_5, texture_19, texture_7, texture_28, texture_29, texture_10, texture_11, texture_12, texture_13, texture_14, texture_15, // se + nw
               texture_31, texture_27, texture_2,  texture_3,  texture_21, texture_5, texture_6,  texture_7, texture_32, texture_29, texture_10, texture_11, texture_23, texture_13, texture_14, texture_15, // se + ne
               texture_33, texture_27, texture_17, texture_3,  texture_25, texture_5, texture_19, texture_7, texture_32, texture_29, texture_10, texture_11, texture_23, texture_13, texture_14, texture_15, // se + ne + nw
               texture_34, texture_35, texture_36, texture_37, texture_4,  texture_5, texture_6,  texture_7, texture_8,  texture_9,  texture_10, texture_11, texture_12, texture_13, texture_14, texture_15, // sw
               texture_38, texture_35, texture_39, texture_37, texture_18, texture_5, texture_19, texture_7, texture_8,  texture_9,  texture_10, texture_11, texture_12, texture_13, texture_14, texture_15, // sw + nw
               texture_40, texture_35, texture_36, texture_37, texture_21, texture_5, texture_6,  texture_7, texture_22, texture_9,  texture_10, texture_11, texture_23, texture_13, texture_14, texture_15, // sw + ne
               texture_41, texture_35, texture_39, texture_37, texture_25, texture_5, texture_19, texture_7, texture_22, texture_9,  texture_10, texture_11, texture_23, texture_13, texture_14, texture_15, // sw + ne + nw
               texture_42, texture_43, texture_36, texture_37, texture_4,  texture_5, texture_6,  texture_7, texture_28, texture_29, texture_10, texture_11, texture_12, texture_13, texture_14, texture_15, // sw + se
               texture_44, texture_43, texture_39, texture_37, texture_18, texture_5, texture_19, texture_7, texture_28, texture_29, texture_10, texture_11, texture_12, texture_13, texture_14, texture_15, // sw + se + nw
               texture_45, texture_43, texture_39, texture_37, texture_21, texture_5, texture_6,  texture_7, texture_32, texture_29, texture_10, texture_11, texture_23, texture_13, texture_14, texture_15, // sw + se + ne
               texture_46, texture_43, texture_39, texture_37, texture_25, texture_5, texture_19, texture_7, texture_32, texture_29, texture_10, texture_11, texture_23, texture_13, texture_14, texture_15, // all corners
            };

            return lookups;
        }
        public void add_door(gridCoordinate target_coord, bool always_locked, List<gridCoordinate> side_coords)
        {
            bool wood_frame_possible = false;
            bool stone_frame_possible = false;

            for (int i = 0; i < side_coords.Count; i++)
            {
                if (get_tile_type_at(side_coords[i]) == Tile.Tile_Type.StoneWall)
                    stone_frame_possible = true;

                if (get_tile_type_at(side_coords[i]) == Tile.Tile_Type.DirtWall)
                    wood_frame_possible = true;
            }

            Doodad.Door_Type d_typ = Doodad.Door_Type.Wood_WoodFrame;
            if (wood_frame_possible && stone_frame_possible && randGen.Next(2) == 0)
                d_typ = Doodad.Door_Type.Wood_StoneFrame;
            else if (!wood_frame_possible && stone_frame_possible)
                d_typ = Doodad.Door_Type.Wood_StoneFrame;

            props.Add(new Doodad(Doodad.Doodad_Type.Door, cManager, target_coord, props.Count, doorType: d_typ));
            int door_state = randGen.Next(5);
            if (always_locked)
                props[props.Count - 1].set_door_state(Doodad.Door_State.Locked);
            else
            {
                if (door_state == 0)
                    props[props.Count - 1].set_door_state(Doodad.Door_State.Locked);
                else if (door_state == 1)
                    props[props.Count - 1].set_door_state(Doodad.Door_State.Stuck);
            }
        }
Exemple #12
0
        public void charge_attack(Floor fl, Weapon lance, gridCoordinate charge_coordinate, int monsterID, int DoodadID)
        {
            bool attacked_Doodad = false;
            bool rolled_max = false;
            gridCoordinate my_original_position = new gridCoordinate(my_grid_coord);
            Weapon c_lance = lance;

            VisionRay attack_ray = null;
            if(fl.badguy_by_monster_id(monsterID) == null)
            {
                attack_ray = new VisionRay(my_grid_coord, fl.Doodad_by_index(DoodadID).get_g_coord());
            }
            else
                attack_ray = new VisionRay(my_grid_coord, charge_coordinate);

            gridCoordinate monster_coord = new gridCoordinate(-1, -1);
            gridCoordinate Doodad_coord = new gridCoordinate(-1, -1);

            bool done = false;
            while (!done)
            {
                int old_xPosition = (int)attack_ray.my_current_position.X / 32;
                int old_yPosition = (int)attack_ray.my_current_position.Y / 32;
                gridCoordinate previous_ray_position = new gridCoordinate(old_xPosition, old_yPosition);

                attack_ray.update();

                int new_xPosition = (int)attack_ray.my_current_position.X / 32;
                int new_yPosition = (int)attack_ray.my_current_position.Y / 32;
                gridCoordinate next_ray_position = new gridCoordinate(new_xPosition, new_yPosition);

                int mon_ID;
                int dood_ID;
                fl.is_monster_here(next_ray_position, out mon_ID);
                fl.is_destroyable_Doodad_here(next_ray_position, out dood_ID);
                if (mon_ID == monsterID && monsterID > -1)
                {
                    monster_coord = new gridCoordinate(charge_coordinate);
                    teleport(previous_ray_position);
                    attack_monster_in_grid(fl, lance, monsterID, charge_coordinate, 1.0, out rolled_max, true);
                    done = true;
                }

                if (dood_ID == DoodadID && DoodadID > -1)
                {
                    attacked_Doodad = true;
                    Doodad_coord = new gridCoordinate(fl.Doodad_by_index(DoodadID).get_g_coord());
                    teleport(previous_ray_position);
                    attack_Doodad_in_grid(fl, lance, DoodadID, fl.Doodad_by_index(DoodadID).get_g_coord(), 1.0, out rolled_max, true);
                    done = true;
                }
            }

            gridCoordinate opposition_coord = new gridCoordinate(-1, -1);
            if (attacked_Doodad)
                opposition_coord = Doodad_coord;
            else
                opposition_coord = monster_coord;

            if (!is_spot_free(fl, my_grid_coord))
            {
                int xdif = my_original_position.x - opposition_coord.x;
                int ydif = my_original_position.y - opposition_coord.y;

                int whocares = -1;
                if (fl.is_monster_here(my_grid_coord, out whocares) || fl.is_destroyable_Doodad_here(my_grid_coord, out whocares))
                {
                    if (xdif == 0)
                        if (my_original_position.x < my_grid_coord.x)
                            my_grid_coord.x--;
                        else
                            my_grid_coord.x++;

                    if (ydif == 0)
                        if (my_original_position.y < my_grid_coord.y)
                            my_grid_coord.y--;
                        else
                            my_grid_coord.y++;

                }
                else if (!fl.is_monster_here(my_grid_coord, out whocares) && !fl.isWalkable(my_grid_coord))
                {
                    int xshift = 0;
                    int yshift = 0;

                    if (xdif < 0)
                        xshift = -1;
                    else
                        xshift = 1;

                    if (ydif < 0)
                        yshift = -1;
                    else
                        yshift = 1;

                    gridCoordinate x_shifted = new gridCoordinate(my_grid_coord.x + xshift, my_grid_coord.y);
                    gridCoordinate y_shifted = new gridCoordinate(my_grid_coord.x, my_grid_coord.y + yshift);
                    bool x_ok = fl.isWalkable(x_shifted);
                    bool y_ok = fl.isWalkable(y_shifted);

                    if (x_ok && !y_ok)
                        my_grid_coord = x_shifted;
                    else if (!x_ok && y_ok)
                        my_grid_coord = y_shifted;
                    else
                    {
                        int go_x = rGen.Next(2);
                        if (go_x == 0)
                            my_grid_coord = x_shifted;
                        else
                            my_grid_coord = y_shifted;
                    }
                }
            }

            reset_my_drawing_position();

            loot(fl);
            total_sound += my_sound_value() + (my_sound_value() / 2);
            total_scent += my_scent_value();

            if (my_class == Chara_Class.Warrior)
            {
                c_energy += 5 + rGen.Next(3);
                if (rolled_max)
                    c_energy += 2;
            }
        }
Exemple #13
0
        //Green text. Function here.
        public Player(ContentManager sCont, gridCoordinate sGridCoord, ref List<string> msgBuffer, 
                      Chara_Class myClass, Character myChara, ref PaperDoll pd)
        {
            //Constructor stuff
            cont = sCont;
            my_grid_coord = new gridCoordinate(sGridCoord);
            my_Position = new Vector2(sGridCoord.x * 32, sGridCoord.y * 32);
            rGen = new Random();
            message_buffer = msgBuffer;
            //!Constructor stuff
            my_gold = 0;
            base_smell_value = 10;
            base_sound_value = 10;
            //Player stuff
            my_class = myClass;
            my_character = myChara;
            base_hp = 3;
            if (my_character == Character.Belia)
                base_hp++; //Belia gets +60 HP to all of her body parts.

            switch (my_character)
            {
                case Character.Falsael:
                    my_Texture = cont.Load<Texture2D>("Player/falsael_sprite");
                    my_dead_texture = cont.Load<Texture2D>("Player/falsael_dead");
                    break;
                case Character.Petaer:
                    my_Texture = cont.Load<Texture2D>("Player/petaer_sprite");
                    my_dead_texture = cont.Load<Texture2D>("Player/petaer_dead");
                    break;
                case Character.Ziktofel:
                    my_Texture = cont.Load<Texture2D>("Player/ziktofel_sprite");
                    my_dead_texture = cont.Load<Texture2D>("Player/ziktofel_dead");
                    break;
                case Character.Halephon:
                    my_Texture = cont.Load<Texture2D>("Player/halephon_sprite");
                    my_dead_texture = cont.Load<Texture2D>("Player/halephon_dead");
                    break;
                case Character.Belia:
                    my_Texture = cont.Load<Texture2D>("Player/belia_sprite");
                    my_dead_texture = cont.Load<Texture2D>("Player/belia_sprite");
                    break;
                default:
                    my_Texture = cont.Load<Texture2D>("Player/lmfaoplayer");
                    my_dead_texture = cont.Load<Texture2D>("Player/playercorpse");
                    break;
            }
            //Health stuff.
            Head = new Limb(ref rGen, "Head", "Head", base_hp - 2);
            Torso = new Limb(ref rGen, "Chest", "Chest", base_hp);
            R_Arm = new Limb(ref rGen, "Right Arm", "RArm", base_hp);
            L_Arm = new Limb(ref rGen, "Left Arm", "LArm", base_hp);
            R_Leg = new Limb(ref rGen, "Right Leg", "RLeg", base_hp);
            L_Leg = new Limb(ref rGen, "Left Leg", "LLeg", base_hp);
            calculate_dodge_chance();
            //Inventory stuff
            inventory = new List<Item>();
            reserved_potion_ids = new List<Tuple<int, int>>();
            for(int i = 1; i <= 3; i++)
                reserved_potion_ids.Add(new Tuple<int,int>(i, new_random_ID_number()));

            add_starting_gear();
            //Character stuff
            BuffDebuffTracker = new List<StatusEffect>();

            pDoll = pd;

            normal_backing = Color.White;
            invis_backing = new Color(255, 255, 255, 75);
        }
Exemple #14
0
        public void cast_spell(Scroll s, Floor fl, gridCoordinate spell_target, int target_monster_ID, int target_Doodad_ID)
        {
            string spell_name = s.get_my_name();
            Projectile.projectile_type prj_type = s.get_assoc_projectile();
            Attack.Damage spell_dmg_type = s.get_damage_type();
            gridCoordinate starting_coord = my_grid_coord;
            Projectile.special_anim spec_prj_anim = s.get_spec_impact_anim();

            c_energy -= s.get_manaCost();
            max_energy += s.get_en_cap_adj();

            if (max_energy > 100)
                max_energy = 100;
            if (max_energy < 0)
                max_energy = 0;

            if (s.get_spell_type() == Scroll.Atk_Area_Type.piercingBolt)
            {
                int spell_range = s.get_range();
                int relative_x = (spell_target.x - my_grid_coord.x) * spell_range;
                int relative_y = (spell_target.y - my_grid_coord.y) * spell_range;
                starting_coord = new gridCoordinate(spell_target);
                spell_target = new gridCoordinate(my_grid_coord.x + relative_x, my_grid_coord.y + relative_y);
            }

            if (s.get_spell_type() != Scroll.Atk_Area_Type.personalBuff)
            {
                Projectile prj = new Projectile(starting_coord, spell_target, prj_type,
                                                 ref cont, false, s.get_spell_type());
                prj.attach_scroll(s);
                prj.set_wall_destroying(s.spell_destroys_walls());
                prj.set_special_anim(spec_prj_anim);

                if (s.get_spell_type() == Scroll.Atk_Area_Type.enemyDebuff)
                {
                    prj.attach_status_effect(s.get_status_effect(), s.get_duration(), s.does_spell_buff_count_down(), s.get_cost_per_turn(), s.get_cost_per_turn_per_turn());
                }

                if (s.get_spell_type() == Scroll.Atk_Area_Type.cloudAOE ||
                    s.get_spell_type() == Scroll.Atk_Area_Type.solidblockAOE ||
                    s.get_spell_type() == Scroll.Atk_Area_Type.randomblockAOE)
                    prj.set_AOE_size(s.get_aoe_size());

                if (s.get_spell_type() == Scroll.Atk_Area_Type.chainedBolt)
                {
                    prj.set_bounce(s.get_range());
                    prj.set_bounces_left(s.get_t_impacts());
                }

                if (String.Compare(s.get_my_name(), "Earthquake") == 0)
                    prj.set_special_anim(Projectile.special_anim.Earthquake);

                prj.set_talisman_effects(s.get_my_equipped_talismans());
                fl.create_new_projectile(prj);
            }
            else
            {
                int base_buff_time = s.get_duration();
                int modified_buff_time = base_buff_time;
                if (my_character == Character.Petaer)
                {
                    double buff_time_bonus = (double)modified_buff_time * .3;
                    modified_buff_time = (int)Math.Ceiling((double)modified_buff_time + buff_time_bonus);
                }
                add_single_statusEffect(new StatusEffect(s.get_status_effect(), modified_buff_time+1, s.does_spell_buff_count_down(), s.get_cost_per_turn(), s.get_cost_per_turn_per_turn(), false));
            }
        }
Exemple #15
0
        public void bow_attack(Floor fl, ref ContentManager Secondary_cManager, gridCoordinate attack_location, int monsterID, int DoodadID)
        {
            Weapon Bow = null;
            if (main_hand != null && (main_hand.get_my_weapon_type() == Weapon.Type.Bow ||
                                     main_hand.get_my_weapon_type() == Weapon.Type.Crossbow))
                Bow = main_hand;
            else if (off_hand != null && (off_hand.get_my_weapon_type() == Weapon.Type.Bow ||
                                          off_hand.get_my_weapon_type() == Weapon.Type.Crossbow))
                Bow = off_hand;

            gridCoordinate opposition_coord = new gridCoordinate(-1, -1);
            if (monsterID != -1)
                opposition_coord = attack_location;
            else
                opposition_coord = fl.Doodad_by_index(DoodadID).get_g_coord();

            int cbow_xsplash = 0;
            int cbow_ysplash = 0;
            if (opposition_coord.x < my_grid_coord.x)
                cbow_xsplash = -1;
            else if (opposition_coord.x > my_grid_coord.x)
                cbow_xsplash = 1;

            if (opposition_coord.y < my_grid_coord.y)
                cbow_ysplash = -1;
            else if (opposition_coord.y > my_grid_coord.y)
                cbow_ysplash = 1;
            gridCoordinate splash_coord = new gridCoordinate(opposition_coord.x + cbow_xsplash, opposition_coord.y + cbow_ysplash);

            int base_min_dmg_to_monster = Bow.specific_damage_val(false);
            int base_max_dmg_to_monster = Bow.specific_damage_val(true);

            int max_dmg_to_monster = (int)base_max_dmg_to_monster;
            int min_dmg_to_monster = (int)base_min_dmg_to_monster;

            if (is_cbow_equipped() && my_character == Character.Falsael)
            {
                max_dmg_to_monster = (int)Math.Ceiling(base_max_dmg_to_monster * 1.2);
                min_dmg_to_monster = (int)Math.Ceiling(base_min_dmg_to_monster * 1.2);
            }

            if (Bow.get_my_weapon_type() == Weapon.Type.Bow)
            {
                Projectile prj = new Projectile(get_my_grid_C(), opposition_coord, Projectile.projectile_type.Arrow, ref Secondary_cManager, false, Scroll.Atk_Area_Type.singleTile);
                prj.attach_weapon(Bow);
                fl.create_new_projectile(prj);
            }
            else if(Bow.get_my_weapon_type() == Weapon.Type.Crossbow)
            {
                Projectile prj = new Projectile(get_my_grid_C(), opposition_coord, Projectile.projectile_type.Crossbow_Bolt, ref Secondary_cManager, false, Scroll.Atk_Area_Type.smallfixedAOE);
                List<gridCoordinate> crossbow_aoe = new List<gridCoordinate>();
                crossbow_aoe.Add(opposition_coord);
                crossbow_aoe.Add(splash_coord);
                prj.set_small_AOE_matrix(crossbow_aoe);
                prj.attach_weapon(Bow);
                fl.create_new_projectile(prj);
            }

            string attack_msg = "";
            if (monsterID != -1)
                attack_msg = "You attack the " + fl.badguy_by_monster_id(monsterID).my_name + " with your " + Bow.get_my_name() + "!";
            else
                attack_msg = "You attack the " + fl.Doodad_by_index(DoodadID).my_name() + " with your " + Bow.get_my_name() + "!";
            message_buffer.Add(attack_msg);

            total_sound += my_sound_value() + (my_sound_value() / 2);
            total_scent += my_scent_value();

            if (my_class == Chara_Class.Warrior)
            {
                c_energy += 6;
            }
        }
        public gridCoordinate valid_hollowKnight_spawn()
        {
            bool goodPosition = false;
            gridCoordinate returnCoord = new gridCoordinate(-1, -1);
            while (!goodPosition)
            {
                gridCoordinate gc = random_valid_position(current_floorsize, restrictions: random_coord_restrictions.Monster);
                List<gridCoordinate> coords = new List<gridCoordinate>();
                coords.Add(new gridCoordinate(gc, gridCoordinate.direction.Left));  //[0] x - 1
                coords.Add(new gridCoordinate(gc, gridCoordinate.direction.Right)); //[1] x + 1
                coords.Add(new gridCoordinate(gc, gridCoordinate.direction.Up));    //[2] y - 1
                coords.Add(new gridCoordinate(gc, gridCoordinate.direction.Down));  //[3] y + 1
                for (int i = 0; i < coords.Count; i++)
                    coords[i].force_safe_value(current_floorsize);

                if ((is_tile_passable(coords[0]) && !is_tile_passable(coords[1]) && //check 0 vs 1
                     get_tile_type_at(coords[1]) != Tile.Tile_Type.Deep_Water) ||
                    (is_tile_passable(coords[1]) && !is_tile_passable(coords[0]) && //check 1 vs 0
                     get_tile_type_at(coords[0]) != Tile.Tile_Type.Deep_Water) ||
                    (is_tile_passable(coords[3]) && !is_tile_passable(coords[2]) && //check 3 vs 2
                     get_tile_type_at(coords[2]) != Tile.Tile_Type.Deep_Water) ||
                    (is_tile_passable(coords[2]) && !is_tile_passable(coords[3]) && //check 2 vs 3
                     get_tile_type_at(coords[3]) != Tile.Tile_Type.Deep_Water))
                {
                    goodPosition = true;
                    returnCoord = gc;
                }
            }
            return returnCoord;
        }
        private void add_all_natural_features(List<NaturalFeature.Feature_Type> features)
        {
            for (int i = 0; i < features.Count; i++)
            {
                if (features[i] == NaturalFeature.Feature_Type.River ||
                    features[i] == NaturalFeature.Feature_Type.Chasm)
                {
                    int feature_length_side1 = randGen.Next(15, 26);
                    int feature_length_side2 = randGen.Next(15, 26);

                    gridCoordinate feature_center = random_valid_position(current_floorsize);
                    gridCoordinate feature_start = new gridCoordinate(-1, -1);
                    gridCoordinate feature_end = new gridCoordinate(-1, -1);
                    bool valid_feature = false;

                    while (!valid_feature)
                    {
                        //Start with a random valid position
                        feature_center = random_valid_position(current_floorsize);
                        //Generate direction vectors for each side of the feature.
                        float side_xVector = (float)Math.Cos(randGen.NextDouble() * Math.PI * 2);
                        float side_yVector = (float)Math.Sin(randGen.NextDouble() * Math.PI * 2);
                        Vector2 side_directionVector = new Vector2(side_xVector, side_yVector);

                        //Adjust the endpoints.
                        feature_start = new gridCoordinate(feature_center);
                        feature_end = new gridCoordinate(feature_center);
                        feature_start.add_vector2(side_directionVector * feature_length_side1);
                        feature_end.add_vector2(side_directionVector * feature_length_side2 * -1);

                        //Force the values to be safe.
                        feature_start.force_safe_value(current_floorsize);
                        feature_end.force_safe_value(current_floorsize);

                        //Check to see whether the values are okay. All river values are accepted
                        //Chasm values are rerolled if they're too close to the edge.
                        if (features[i] == NaturalFeature.Feature_Type.River)
                            valid_feature = true;
                        else if (features[i] == NaturalFeature.Feature_Type.Chasm)
                        {
                            if (feature_start.x > 4 && feature_start.x < 47 &&
                               feature_start.y > 4 && feature_start.y < 47 &&
                               feature_end.x > 4 && feature_end.x < 47 &&
                               feature_end.y > 4 && feature_end.y < 47)
                                valid_feature = true;
                        }
                    }

                    if (features[i] == NaturalFeature.Feature_Type.River)
                    {
                        //Add the new river
                        int deepwater_thickness = randGen.Next(2);
                        int shallows_thickness = 1 + randGen.Next(3);
                        int banks_thickness = 1 + randGen.Next(2);
                        featurelayout.Add(new NaturalFeature(feature_start, feature_end, NaturalFeature.River_Type.Normal,
                                                                                         deepwater_thickness,
                                                                                         shallows_thickness,
                                                                                         banks_thickness));
                    }
                    else if (features[i] == NaturalFeature.Feature_Type.Chasm)
                    {
                        //Add the new chasm
                        int max_thickness = randGen.Next(6, 13);
                        featurelayout.Add(new NaturalFeature(feature_start, feature_end, max_thickness));
                    }
                }
                else if (features[i] == NaturalFeature.Feature_Type.Lake)
                {
                    gridCoordinate feature_center = random_valid_position(current_floorsize);

                    int xSize = randGen.Next(11, 18);
                    int ySize = randGen.Next(11, 18);
                    int room_thickness = 1 + randGen.Next(2);
                    int shore_thickness = 1 + randGen.Next(2);
                    int shallows_thickness = 1 + randGen.Next(2);

                    gridCoordinate feature_start = new gridCoordinate(feature_center.x - xSize / 2, feature_center.y - ySize / 2);
                    gridCoordinate feature_end = new gridCoordinate(feature_center.x + xSize / 2, feature_center.y + ySize / 2);
                    feature_start.force_safe_value(current_floorsize);
                    feature_end.force_safe_value(current_floorsize);

                    featurelayout.Add(new NaturalFeature(feature_start, feature_end, room_thickness, shore_thickness, shallows_thickness));
                }
            }
        }
 public void destroy_tile(gridCoordinate target_coord)
 {
     Tile target_tile = floorTiles[target_coord.x][target_coord.y];
     target_tile.set_tile_type(Tile.Tile_Type.Rubble_Floor, universal_spritesheet, dungeon_specific_spritesheet, general_texture_map);
     replace_surrounding_void(target_tile, false);
 }
        private void add_exit()
        {
            //place an exit adjacent to a random spot.
            while (!exitPlaced)
            {
                gridCoordinate exit_coord = new gridCoordinate(random_valid_position(current_floorsize));
                //if there's not a void tile adjacent to this floor tile, don't place the exit.
                //if there is though, place it and we're done here!
                for (int x = exit_coord.x - 1; x <= exit_coord.x + 1; x++)
                {
                    if (x < current_floorsize && x > 0)
                    {
                        if (floorTiles[x][exit_coord.y].isVoid() && !exitPlaced)
                        {
                            dungeon_exit_coord = new gridCoordinate(x, exit_coord.y);
                            exitPlaced = true;
                        }
                    }
                }

                for (int y = exit_coord.y - 1; y <= exit_coord.y + 1; y++)
                    if (y < current_floorsize && y > 0)
                    {
                        if (floorTiles[exit_coord.x][y].isVoid() && !exitPlaced)
                        {
                            dungeon_exit_coord = new gridCoordinate(exit_coord.x, y);
                            exitPlaced = true;
                        }
                    }

                if (exitPlaced)
                {
                    Tile.Tile_Type exit_type = Tile.Tile_Type.Exit;
                    if (current_floordepth == 12)
                        exit_type = Tile.Tile_Type.Locked_Dungeon_Exit;
                    floorTiles[dungeon_exit_coord.x][dungeon_exit_coord.y].set_tile_type(exit_type,
                        universal_spritesheet, dungeon_specific_spritesheet, general_texture_map);
                }
            }
        }
 public Tile.Tile_Type get_tile_type_at(gridCoordinate target_coord)
 {
     if (!target_coord.is_safe(current_floorsize))
         return Tile.Tile_Type.Void;
     else
         return floorTiles[target_coord.x][target_coord.y].get_my_tile_type();
 }
Exemple #21
0
        public void render_doodads_to_board(ref List<Doodad> fl_doodads, int fl_size, ContentManager cmgr, FloorBuilder flb)
        {
            for (int i = 0; i < doodad_list.Count; i++)
            {
                gridCoordinate doodad_coord = doodad_list[i].Value;
                gridCoordinate new_doodad_coord = new gridCoordinate(doodad_coord.x + startXPos,
                                                                     doodad_coord.y + startYPos);

                if(!flb.is_tile_obstructed(new_doodad_coord))
                    fl_doodads.Add(new Doodad(doodad_list[i].Key, cmgr, new_doodad_coord, fl_doodads.Count));
            }

            if (bonus_gold > 0)
            {
                gridCoordinate tbox_gc = new gridCoordinate(-1, -1);
                List<gridCoordinate> potential_tbox_spots = new List<gridCoordinate>();
                for (int x = 0; x < roomWidth; x++)
                {
                    gridCoordinate target_gc = new gridCoordinate(startXPos + x, startYPos);
                    gridCoordinate target_gc_2 = new gridCoordinate(startXPos + x, startYPos + roomHeight - 1);
                    if(!flb.is_tile_obstructed(target_gc))
                        potential_tbox_spots.Add(target_gc);
                    if (!flb.is_tile_obstructed(target_gc_2))
                        potential_tbox_spots.Add(target_gc_2);
                }

                for (int y = 0; y < roomHeight; y++)
                {
                    gridCoordinate target_gc = new gridCoordinate(startXPos, startYPos + y);
                    gridCoordinate target_gc_2 = new gridCoordinate(startXPos + roomWidth - 1, startYPos + y);
                    if (!flb.is_tile_obstructed(target_gc))
                        potential_tbox_spots.Add(target_gc);
                    if (!flb.is_tile_obstructed(target_gc_2))
                        potential_tbox_spots.Add(target_gc_2);
                }

                if (potential_tbox_spots.Count > 0)
                    tbox_gc = potential_tbox_spots[rGen.Next(potential_tbox_spots.Count)];
                else
                    tbox_gc = flb.random_valid_position(fl_size);

                Doodad treasure_box = new Doodad(Doodad.Doodad_Type.TreasureBox, cmgr, tbox_gc, fl_doodads.Count);
                treasure_box.set_chest_contents(bonus_gold);
                fl_doodads.Add(treasure_box);
            }
        }
        public bool is_tile_obstructed(gridCoordinate target_coord)
        {
            bool obstructed = false;
            for (int i = 0; i < badguys.Count; i++)
            {
                List<gridCoordinate> monster_coords = badguys[i].get_my_grid_coords();
                for (int j = 0; j < monster_coords.Count; j++)
                    if (monster_coords[j].x == target_coord.x && monster_coords[j].y == target_coord.y)
                        obstructed = true;
            }

            for (int i = 0; i < props.Count; i++)
            {
                gridCoordinate prop_coord = props[i].get_g_coord();
                if (prop_coord.x == target_coord.x && prop_coord.y == target_coord.y)
                    obstructed = true;
            }

            for (int i = 0; i < money.Count; i++)
            {
                gridCoordinate money_coord = money[i].get_my_grid_C();
                if (money_coord.x == target_coord.x && money_coord.y == target_coord.y)
                    obstructed = true;
            }

            if (!is_tile_passable(target_coord))
                obstructed = true;

            return obstructed;
        }
Exemple #23
0
        public void render_to_board(List<List<Tile>> board, Texture2D general_sheet, Texture2D dungeon_sheet,
                                    List<KeyValuePair<Tile.Tile_Type, gridCoordinate>> source_map, FloorBuilder flb)
        {
            switch (c_room_type)
            {
                case Room_Type.Generic:
                case Room_Type.GenericCircular:
                    for (int x = startXPos; x < startXPos + roomWidth; x++)
                        for (int y = startYPos; y < startYPos + roomHeight; y++)
                            if (c_room_type == Room_Type.GenericCircular &&
                                circular_room_matrix[x - startXPos][y - startYPos])
                                board[x][y].set_tile_type(c_floor_type, general_sheet, dungeon_sheet, source_map);
                            else
                                board[x][y].set_tile_type(c_floor_type, general_sheet, dungeon_sheet, source_map);
                    if (c_column_type != Column_Pattern.None)
                    {
                        List<gridCoordinate> chosen_points = new List<gridCoordinate>();
                        switch (c_column_type)
                        {
                            case Column_Pattern.Four_Corners:
                                chosen_points.Add(new gridCoordinate(startXPos + 1, startYPos + 1));
                                chosen_points.Add(new gridCoordinate(startXPos + roomWidth - 2, startYPos + 1));
                                chosen_points.Add(new gridCoordinate(startXPos + 1, startYPos + roomHeight - 2));
                                chosen_points.Add(new gridCoordinate(startXPos + roomWidth - 2, startYPos + roomHeight - 2));
                                break;
                            case Column_Pattern.Center_Pillar:
                                chosen_points.Add(findCenter());
                                if (roomWidth % 2 == 0) //Both room width + height are even
                                    chosen_points.Add(new gridCoordinate(findCenter(), gridCoordinate.direction.Left));
                                if(roomHeight % 2 == 0)
                                    chosen_points.Add(new gridCoordinate(findCenter(), gridCoordinate.direction.Up));
                                if(roomWidth % 2 == 0 && roomHeight % 2 == 0)
                                    chosen_points.Add(new gridCoordinate(findCenter(), gridCoordinate.direction.UpLeft));
                                break;
                            //These are by far the two most complicated types of columns to put in rooms.
                            case Column_Pattern.Horizontal_Rows:
                            case Column_Pattern.Vertical_Rows:
                                //"Row 1" is the left or the top row.
                                //"Row 2" is the right or the bottom row.
                                //Row_X_points[0] is "n_point" or the point incremented with a negative value
                                //Row_X_points[1] is "p_point" or the point incremented with a positive value

                                //Assumes the room is an odd size on the axis that's to be incremented. Adjusted if
                                //the room is an even size.
                                bool even_axis_size = false;
                                //All values are set to -1 to force an exception if they're set improperly
                                //By the next section of code.
                                int row_1_x = -1;
                                int row_1_y = -1;
                                int row_2_x = -1;
                                int row_2_y = -1;
                                int x_incr_value = 0;
                                int y_incr_value = 0;
                                if (c_column_type == Column_Pattern.Horizontal_Rows)
                                {
                                    //Set the x & y values.
                                    row_1_x = startXPos + (roomWidth / 2);
                                    row_2_x = startXPos + (roomWidth / 2);
                                    row_1_y = startYPos + 1;
                                    row_2_y = startYPos + roomHeight - 2;

                                    //Set the incr value
                                    x_incr_value = 2;
                                    //I don't like adding a special case here but it's warranted.
                                    //Without this, a 9-wide room looks like this:
                                    //[_][_][X][_][X][_][X][_][_]
                                    //WHICH LOOKS REALLY STRANGE
                                    //The special case fixes it to this: [_][X][_][_][X][_][_][X][_]
                                    //Which looks way better.
                                    if (roomWidth == 9)
                                        x_incr_value += 1;

                                    //Adjust even_axis_size as needed
                                    if (roomWidth % 2 == 0)
                                        even_axis_size = true;
                                }
                                else //Vertical rows
                                {
                                    row_1_x = startXPos + 1;
                                    row_2_x = startXPos + roomWidth - 2;
                                    row_1_y = startYPos + (roomHeight / 2);
                                    row_2_y = startYPos + (roomHeight / 2);

                                    y_incr_value = 2;
                                    if (roomHeight == 9)
                                        y_incr_value += 1;

                                    if (roomHeight % 2 == 0)
                                        even_axis_size = true;
                                }
                                gridCoordinate[] row_1_points = new gridCoordinate[] { new gridCoordinate(row_1_x, row_1_y), new gridCoordinate(row_1_x, row_1_y) };
                                gridCoordinate[] row_2_points = new gridCoordinate[] { new gridCoordinate(row_2_x, row_2_y), new gridCoordinate(row_2_x, row_2_y) };

                                //The starting point of each point is adjusted if the room size is even.
                                if (even_axis_size)
                                {
                                    if (c_column_type == Column_Pattern.Horizontal_Rows)
                                    {
                                        row_1_points[0].x -= 2;
                                        row_2_points[0].x -= 2;
                                        row_1_points[1].x += 1;
                                        row_2_points[1].x += 1;
                                    }
                                    else
                                    {
                                        row_1_points[0].y -= 2;
                                        row_2_points[0].y -= 2;
                                        row_1_points[1].y += 1;
                                        row_2_points[1].y += 1;
                                    }
                                }

                                //While none of the points are on or near a wall tile of the room, we increment as needed
                                //First, declare the points that we're going to be adding to the main values to increment them
                                gridCoordinate p_incr_coord = new gridCoordinate(x_incr_value, y_incr_value);
                                gridCoordinate n_incr_coord = new gridCoordinate(x_incr_value*-1, y_incr_value*-1);
                                while(!is_on_or_near_wallTile(row_1_points[0]) &&
                                      !is_on_or_near_wallTile(row_1_points[1]) &&
                                      !is_on_or_near_wallTile(row_2_points[0]) &&
                                      !is_on_or_near_wallTile(row_2_points[1]))
                                {
                                    chosen_points.Add(new gridCoordinate(row_1_points[0]));
                                    chosen_points.Add(new gridCoordinate(row_1_points[1]));
                                    chosen_points.Add(new gridCoordinate(row_2_points[0]));
                                    chosen_points.Add(new gridCoordinate(row_2_points[1]));
                                    row_1_points[0].combineCoords(n_incr_coord);
                                    row_1_points[1].combineCoords(p_incr_coord);
                                    row_2_points[0].combineCoords(n_incr_coord);
                                    row_2_points[1].combineCoords(p_incr_coord);
                                }

                                break;
                        }
                        for (int i = 0; i < chosen_points.Count; i++)
                            board[chosen_points[i].x][chosen_points[i].y].set_tile_type(Tile.Tile_Type.Void, general_sheet, dungeon_sheet, source_map);
                    }
                    break;
                case Room_Type.SewerShaft:
                case Room_Type.MineShaft:
                    //TODO - add shaft generation code here.
                    Tile.Tile_Type edge_fl_type = Tile.Tile_Type.StoneFloor;
                    Tile.Tile_Type central_fl_type = Tile.Tile_Type.Deep_Sewage;
                    if (c_room_type == Room_Type.MineShaft)
                    {
                        edge_fl_type = Tile.Tile_Type.Natural_Stone_Floor;
                        central_fl_type = Tile.Tile_Type.Gravel;
                    }

                    bool horizontal_shaft = false;
                    if (roomHeight == 3)
                        horizontal_shaft = true;

                    for (int x = startXPos; x < startXPos + roomWidth; x++)
                        for (int y = startYPos; y < startYPos + roomHeight; y++)
                        {
                            if (horizontal_shaft)
                            {
                                if (y == startYPos + 1 && x != startXPos && x != startXPos + roomWidth - 1)
                                    board[x][y].set_tile_type(central_fl_type, general_sheet, dungeon_sheet, source_map);
                                else
                                    board[x][y].set_tile_type(edge_fl_type, general_sheet, dungeon_sheet, source_map);
                            }
                            else
                            {
                                if (x == startXPos + 1 && y != startYPos && y != startYPos + roomHeight - 1)
                                    board[x][y].set_tile_type(central_fl_type, general_sheet, dungeon_sheet, source_map);
                                else
                                    board[x][y].set_tile_type(edge_fl_type, general_sheet, dungeon_sheet, source_map);
                            }
                        }

                    break;
                default:
                    for (int y = startYPos; y < startYPos + roomHeight; y++)
                    {
                        string[] row = room_tiles[y - startYPos].Split(' ');
                        for (int x = startXPos; x < startXPos + roomWidth; x++)
                        {
                            if (String.Compare(row[x - startXPos], "EX") == 0)
                            {
                                flb.set_exit_location(new gridCoordinate(x, y));
                                if (flb.get_current_floor_number() % 12 == 0)
                                    row[x - startXPos] = "DNEX";
                            }

                            if (String.Compare(row[x - startXPos], "EN") == 0)
                                flb.set_entrance_location(new gridCoordinate(x, y));

                            if (String.Compare(row[x - startXPos], "V") != 0)
                                board[x][y].set_tile_type_str(row[x - startXPos], general_sheet, dungeon_sheet, source_map);
                        }
                    }
                    break;
            }
        }
 public bool is_tile_passable(gridCoordinate target_coord)
 {
     if (!target_coord.is_safe(current_floorsize))
         return false;
     else
         return floorTiles[target_coord.x][target_coord.y].isPassable();
 }
 public void bite_alert(Floor fl)
 {
     for (int x = my_grid_coords[0].x - 2; x <= my_grid_coords[1].x + 2; x++)
         for (int y = my_grid_coords[0].y - 2; y <= my_grid_coords[2].y + 2; y++)
         {
             gridCoordinate target_coord = new gridCoordinate(x, y);
             if (x > 0 && x < fl.get_fl_size() &&
                y > 0 && y < fl.get_fl_size() &&
                fl.is_tile_passable(target_coord) &&
                !occupies_tile(target_coord))
                 fl.add_specific_effect(Floor.specific_effect.Alert, new gridCoordinate(x, y));
         }
 }
 public void mossify_tile_at(gridCoordinate target_coord, Texture2D moss_sheet, 
                             List<KeyValuePair<Tile.Tile_Type, gridCoordinate>> moss_map)
 {
     if (target_coord.is_safe(current_floorsize))
     {
         Tile target_tile = floorTiles[target_coord.x][target_coord.y];
         if (target_tile.can_mossify())
             target_tile.mossify(moss_sheet, moss_map);
     }
 }
        public void target_bonespear(Floor fl, gridCoordinate target_loc, bool spear1)
        {
            c_bspear_target_endp = null;
            c_bspear_target_endp_2 = null;

            int pl_x_dir = 0;
            int pl_y_dir = 0;

            gridCoordinate top_left = my_grid_coords[0];
            gridCoordinate bottom_right = my_grid_coords[3];

            int pl_x_c = target_loc.x;
            int pl_y_c = target_loc.y;

            //Determine X direction
            if (pl_x_c > top_left.x && pl_x_c > bottom_right.x)
                pl_x_dir = 1;
            else if (pl_x_c < top_left.x && pl_x_c < bottom_right.x)
                pl_x_dir = -1;

            //Determine Y direction
            if (pl_y_c > top_left.y && pl_y_c > bottom_right.y)
                pl_y_dir = 1;
            else if (pl_y_c < top_left.y && pl_y_c < bottom_right.y)
                pl_y_dir = -1;

            //Okay so these are the easy ways to do it.
            //If these don't work we get messy.
            //Easy way 1.
            if (pl_x_dir == 0)
            {
                int spear_start_xCoord = 0;
                if (pl_x_c == my_grid_coords[0].x)
                    spear_start_xCoord = my_grid_coords[0].x;
                else
                    spear_start_xCoord = my_grid_coords[1].x;

                if (pl_y_dir == 1)
                {
                    if (spear1)
                    {
                        c_bspear_target_startp = new gridCoordinate(spear_start_xCoord, my_grid_coords[3].y + 1);
                        c_bspear_target_endp = new gridCoordinate(spear_start_xCoord, Math.Min(my_grid_coords[3].y + 6, fl.get_fl_size() - 1));
                    }
                    else
                    {
                        c_bspear_target_startp_2 = new gridCoordinate(spear_start_xCoord, my_grid_coords[3].y + 1);
                        c_bspear_target_endp_2 = new gridCoordinate(spear_start_xCoord, Math.Min(my_grid_coords[3].y + 6, fl.get_fl_size() - 1));
                    }
                }
                else
                {
                    if (spear1)
                    {
                        c_bspear_target_startp = new gridCoordinate(spear_start_xCoord, my_grid_coords[0].y - 1);
                        c_bspear_target_endp = new gridCoordinate(spear_start_xCoord, Math.Max(my_grid_coords[0].y - 6, 0));
                    }
                    else
                    {
                        c_bspear_target_startp_2 = new gridCoordinate(spear_start_xCoord, my_grid_coords[0].y - 1);
                        c_bspear_target_endp_2 = new gridCoordinate(spear_start_xCoord, Math.Max(my_grid_coords[0].y - 6, 0));
                    }
                }
            }
            //Easy way 2.
            if (pl_y_dir == 0)
            {
                int spear_start_yCoord = 0;
                if (pl_y_c == my_grid_coords[0].y)
                    spear_start_yCoord = my_grid_coords[0].y;
                else
                    spear_start_yCoord = my_grid_coords[2].y;

                if (pl_x_dir == 1)
                {
                    if (spear1)
                    {
                        c_bspear_target_startp = new gridCoordinate(my_grid_coords[1].x + 1, spear_start_yCoord);
                        c_bspear_target_endp = new gridCoordinate(Math.Min(my_grid_coords[1].x + 6, fl.get_fl_size() - 1), spear_start_yCoord);
                    }
                    else
                    {
                        c_bspear_target_startp_2 = new gridCoordinate(my_grid_coords[1].x + 1, spear_start_yCoord);
                        c_bspear_target_endp_2 = new gridCoordinate(Math.Min(my_grid_coords[1].x + 6, fl.get_fl_size() - 1), spear_start_yCoord);
                    }
                }
                else
                {
                    if (spear1)
                    {
                        c_bspear_target_startp = new gridCoordinate(my_grid_coords[0].x - 1, spear_start_yCoord);
                        c_bspear_target_endp = new gridCoordinate(Math.Max(my_grid_coords[0].x - 6, 0), spear_start_yCoord);
                    }
                    else
                    {
                        c_bspear_target_startp_2 = new gridCoordinate(my_grid_coords[0].x - 1, spear_start_yCoord);
                        c_bspear_target_endp_2 = new gridCoordinate(Math.Max(my_grid_coords[0].x - 6, 0), spear_start_yCoord);
                    }
                }
            }

            //Now, we raycast to see if we can get a good ray that hits the player.
            List<gridCoordinate> endPoints = new List<gridCoordinate>();
            //We first base this on a single coordinate that corresponds to one of the corners of the boneyard
            //for example if the player is above and to the left of the boneyard, we start out with this:
            /* [M] = Monster / [X] = target / [_] = blank spot
             *
             * [X][_][_]
             * [_][M][M]
             * [_][M][M]
             */
            if (pl_x_dir != 0 && pl_y_dir != 0)
            {
                int target_index = -1;
                if (pl_x_dir == -1 && pl_y_dir == -1)
                    target_index = 0;
                else if (pl_x_dir == 1 && pl_y_dir == -1)
                    target_index = 1;
                else if (pl_x_dir == -1 && pl_y_dir == 1)
                    target_index = 2;
                else if (pl_x_dir == 1 && pl_y_dir == 1)
                    target_index = 3;

                gridCoordinate start_coord = new gridCoordinate(my_grid_coords[target_index].x + pl_x_dir,
                                                                my_grid_coords[target_index].y + pl_y_dir);
                if (spear1)
                    c_bspear_target_startp = start_coord;
                else
                    c_bspear_target_startp_2 = start_coord;
                //Then we make a list of endpoints based on that. It will need two for loops;
                //One for the X-axis and one for the Y-axis
                //5/5 offset
                endPoints.Add(new gridCoordinate(start_coord.x + (pl_x_dir * 5), start_coord.y + (pl_y_dir * 5)));
                //5/4 offsets
                endPoints.Add(new gridCoordinate(start_coord.x + (pl_x_dir * 4), start_coord.y + (pl_y_dir * 5)));
                endPoints.Add(new gridCoordinate(start_coord.x + (pl_x_dir * 5), start_coord.y + (pl_y_dir * 4)));
                //5/3 offsets
                endPoints.Add(new gridCoordinate(start_coord.x + (pl_x_dir * 3), start_coord.y + (pl_y_dir * 5)));
                endPoints.Add(new gridCoordinate(start_coord.x + (pl_x_dir * 5), start_coord.y + (pl_y_dir * 3)));
                //5/2 offsets
                endPoints.Add(new gridCoordinate(start_coord.x + (pl_x_dir * 2), start_coord.y + (pl_y_dir * 5)));
                endPoints.Add(new gridCoordinate(start_coord.x + (pl_x_dir * 5), start_coord.y + (pl_y_dir * 2)));
                //5/1 offsets
                endPoints.Add(new gridCoordinate(start_coord.x + (pl_x_dir * 1), start_coord.y + (pl_y_dir * 5)));
                endPoints.Add(new gridCoordinate(start_coord.x + (pl_x_dir * 5), start_coord.y + (pl_y_dir * 1)));
                //I avoided doing this in a for loop because I want the boneyard to prioritize shooting the spear
                //diagonally if it can and doing it with loops would shoot it either vertically or horizontally.

                List<VisionRay> bspear_rays = new List<VisionRay>();
                for (int i = 0; i < endPoints.Count; i++)
                    bspear_rays.Add(new VisionRay(start_coord, endPoints[i]));

                bool found_player = false;
                while (bspear_rays.Count > 0)
                {
                    for (int i = 0; i < bspear_rays.Count; i++)
                    {
                        bool remove = false;
                        int c_x_coord = (int)bspear_rays[i].my_current_position.X / 32;
                        int c_y_coord = (int)bspear_rays[i].my_current_position.Y / 32;
                        gridCoordinate c_coord = new gridCoordinate(c_x_coord, c_y_coord);

                        if (!fl.is_tile_passable(c_coord) || bspear_rays[i].is_at_end())
                            remove = true;

                        if (target_loc.x == c_coord.x && target_loc.y == c_coord.y)
                        {
                            if(spear1)
                                c_bspear_target_endp = new gridCoordinate((int)bspear_rays[i].my_end_position.X / 32,
                                                                          (int)bspear_rays[i].my_end_position.Y / 32);
                            else
                                c_bspear_target_endp_2 = new gridCoordinate((int)bspear_rays[i].my_end_position.X / 32,
                                                                            (int)bspear_rays[i].my_end_position.Y / 32);
                            found_player = true;
                        }

                        if (remove)
                            bspear_rays.RemoveAt(i);
                        else
                            bspear_rays[i].update();

                        if (found_player)
                            bspear_rays.Clear();
                    }
                }
            }

            //Don't try to create a projectile if the endpoint is null. This means that it hasn't found the player.
            if (c_bspear_target_endp != null)
            {
                Projectile prj = new Projectile(c_bspear_target_startp, c_bspear_target_endp, Projectile.projectile_type.Blank,
                                            ref cont, true, Scroll.Atk_Area_Type.piercingBolt, false);
                prj.set_special_anim(Projectile.special_anim.Alert);
                prj.set_damage_range(0, 0);
                prj.set_damage_type(bone_spear_dmgtyp);
                fl.create_new_projectile(prj);
            }

            if (c_bspear_target_endp_2 != null)
            {
                Projectile prj2 = new Projectile(c_bspear_target_startp_2, c_bspear_target_endp_2, Projectile.projectile_type.Blank,
                                            ref cont, true, Scroll.Atk_Area_Type.piercingBolt, false);
                prj2.set_special_anim(Projectile.special_anim.Alert);
                prj2.set_damage_range(0, 0);
                prj2.set_damage_type(bone_spear_dmgtyp);
                fl.create_new_projectile(prj2);
            }
        }
 public void set_entrance_location(gridCoordinate next_location)
 {
     dungeon_entrance_coord = next_location;
     entranceplaced = true;
 }
        public override void Update_Monster(Player pl, Floor fl)
        {
            heal_near_altar(fl);

            detect_player(pl, fl);

            has_moved = false;
            if (!stunned)
            {
                if (can_see_player)
                {
                    last_seen_player_loc = pl.get_my_grid_C();

                    if (sequence_cooldown == 0)
                    {
                        if (!bite_available && !volley_available)
                        {
                            bite_available = true;
                            volley_available = true;
                            bite_stage = 0;
                            volley_stage = 0;
                        }

                        if (bite_available && volley_available)
                        {
                            if (rGen.Next(2) == 0)
                            {
                                current_sequence = attack_sequence.Biting;
                                bite_available = false;
                            }
                            else
                            {
                                current_sequence = attack_sequence.Volley;
                                volley_available = false;
                            }
                            sequence_cooldown = 4;
                        }
                        else
                        {
                            if (!bite_available)
                            {
                                current_sequence = attack_sequence.Volley;
                                volley_available = false;
                            }
                            else
                            {
                                current_sequence = attack_sequence.Biting;
                                bite_available = false;
                            }
                            sequence_cooldown = 4;
                        }
                    }

                    switch (current_sequence)
                    {
                        case attack_sequence.None:
                            if(is_player_within(pl, 1))
                            {
                                fl.addmsg("The Boneyard slashes at you!");
                                Attack dmg = dealDamage();
                                fl.add_effect(dmg_type, pl.get_my_grid_C());
                                pl.take_damage(dmg, fl, "");
                                sequence_cooldown--;
                            }
                            else
                            {
                                advance_towards_single_point(pl.get_my_grid_C(), pl, fl, 1, corporeal);
                                if (!has_moved)
                                    fire_singletarget_bonespear(fl, pl.get_my_grid_C());
                                else
                                    sequence_cooldown--;
                            }
                            break;
                        case attack_sequence.Biting:
                            switch (bite_stage)
                            {
                                case 0:
                                    my_Texture = bitey_texture;
                                    fl.add_new_popup("Roars!", Popup.popup_msg_type.Alert, my_center_coordinate(), false, false);
                                    bloodspray(fl, pl);
                                    bite_stage++;
                                    break;
                                case 1:
                                    bite_alert(fl);
                                    bite_stage++;
                                    break;
                                case 2:
                                    //Bite goes off
                                    execute_bite(fl, pl);
                                    bite_stage = 0;
                                    my_Texture = normal_texture;
                                    current_sequence = attack_sequence.None;
                                    break;
                            }
                            break;
                        case attack_sequence.Volley:
                            switch (volley_stage)
                            {
                                case 0:
                                    //target player
                                    target_bonespear(fl, pl.get_my_grid_C(), true);
                                    fl.add_specific_effect(Floor.specific_effect.Warning_Bracket, pl.get_my_grid_C());
                                    volley_stage++;
                                    break;
                                case 1:
                                    //shoot spear
                                    fire_bonespear(fl, true);
                                    //target player
                                    target_bonespear(fl, pl.get_my_grid_C(), true);
                                    volley_stage++;
                                    break;
                                case 2:
                                    //shoot spear
                                    fire_bonespear(fl, true);
                                    //target player
                                    target_bonespear(fl, pl.get_my_grid_C(), true);
                                    volley_stage++;
                                    break;
                                case 3:
                                    //shoot spear
                                    fire_bonespear(fl, true);
                                    volley_stage = 0;
                                    current_sequence = attack_sequence.None;
                                    break;
                            }
                            break;
                    }
                }
                else if (!can_see_player && have_i_seen_player)
                {
                    advance_towards_single_point(last_seen_player_loc, pl, fl, 0, corporeal);
                    if (occupies_tile(last_seen_player_loc))
                    {
                        last_seen_player_loc = my_grid_coords[0];
                        have_i_seen_player = false;
                    }
                }
                else if (!can_see_player && !have_i_seen_player && heard_something)
                {
                    //If the boneyard has LOS to the sound's origin, fire bone spears at it repeatedly - the AOE kind.
                    //Otherwise, simply move to the sound.
                    if(last_path_to_sound.Count > 0 && can_i_see_point(fl, last_path_to_sound[0]))
                    {
                        switch(blind_volley_stage)
                        {
                            case 0:
                                break;
                            case 1:
                                break;
                        }
                    }
                    else
                    {
                        follow_path_to_sound(fl, pl);
                    }
                }
            }

            base.Update_Monster(pl, fl);
        }
 public void set_exit_location(gridCoordinate next_location)
 {
     dungeon_exit_coord = next_location;
     exitPlaced = true;
 }