Decompose rooms.go (refactor step 7)
digRooms splits into digRoom/placeGoneRoom/placeMazeRoom/ placeNormalRoom/roomGold/roomMonster; dig gains digPick/digWallGap; findFloorImpl gains floorChar; enterRoom and leaveRoom gain per-cell helpers. rooms.go is complexity-clean. Behavior and RNG call order unchanged.
This commit is contained in:
184
game/rooms.go
184
game/rooms.go
@@ -38,25 +38,21 @@ func (g *RogueGame) digRooms() {
|
|||||||
}
|
}
|
||||||
// dig and populate all the rooms on the level
|
// dig and populate all the rooms on the level
|
||||||
for i := range g.Level.Rooms {
|
for i := range g.Level.Rooms {
|
||||||
|
g.digRoom(i, bsze)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// digRoom digs and populates one room (the loop body of rooms.c
|
||||||
|
// do_rooms).
|
||||||
|
func (g *RogueGame) digRoom(i int, bsze Coord) {
|
||||||
rp := &g.Level.Rooms[i]
|
rp := &g.Level.Rooms[i]
|
||||||
// Find upper left corner of box that this room goes in
|
// Find upper left corner of box that this room goes in
|
||||||
top := Coord{X: (i%3)*bsze.X + 1, Y: (i / 3) * bsze.Y}
|
top := Coord{X: (i%3)*bsze.X + 1, Y: (i / 3) * bsze.Y}
|
||||||
|
|
||||||
if rp.Flags.Has(Gone) {
|
if rp.Flags.Has(Gone) {
|
||||||
// Place a gone room. Make certain that there is a blank line
|
g.placeGoneRoom(rp, top, bsze)
|
||||||
// for passage drawing.
|
|
||||||
for {
|
|
||||||
rp.Pos.X = top.X + g.rnd(bsze.X-2) + 1
|
|
||||||
rp.Pos.Y = top.Y + g.rnd(bsze.Y-2) + 1
|
|
||||||
rp.Max.X = -NumCols
|
|
||||||
|
|
||||||
rp.Max.Y = -NumLines
|
return
|
||||||
if rp.Pos.Y > 0 && rp.Pos.Y < NumLines-1 {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
// set room type
|
// set room type
|
||||||
if g.rnd(10) < g.Depth-1 {
|
if g.rnd(10) < g.Depth-1 {
|
||||||
@@ -68,6 +64,33 @@ func (g *RogueGame) digRooms() {
|
|||||||
}
|
}
|
||||||
// Find a place and size for a random room
|
// Find a place and size for a random room
|
||||||
if rp.Flags.Has(Maze) {
|
if rp.Flags.Has(Maze) {
|
||||||
|
placeMazeRoom(rp, top, bsze)
|
||||||
|
} else {
|
||||||
|
g.placeNormalRoom(rp, top, bsze)
|
||||||
|
}
|
||||||
|
|
||||||
|
g.drawRoom(rp)
|
||||||
|
g.roomGold(rp)
|
||||||
|
g.roomMonster(rp)
|
||||||
|
}
|
||||||
|
|
||||||
|
// placeGoneRoom places a gone room, making certain that there is a
|
||||||
|
// blank line for passage drawing (rooms.c do_rooms).
|
||||||
|
func (g *RogueGame) placeGoneRoom(rp *Room, top, bsze Coord) {
|
||||||
|
for {
|
||||||
|
rp.Pos.X = top.X + g.rnd(bsze.X-2) + 1
|
||||||
|
rp.Pos.Y = top.Y + g.rnd(bsze.Y-2) + 1
|
||||||
|
rp.Max.X = -NumCols
|
||||||
|
|
||||||
|
rp.Max.Y = -NumLines
|
||||||
|
if rp.Pos.Y > 0 && rp.Pos.Y < NumLines-1 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// placeMazeRoom sizes a maze room to fill its box (rooms.c do_rooms).
|
||||||
|
func placeMazeRoom(rp *Room, top, bsze Coord) {
|
||||||
rp.Max.X = bsze.X - 1
|
rp.Max.X = bsze.X - 1
|
||||||
|
|
||||||
rp.Max.Y = bsze.Y - 1
|
rp.Max.Y = bsze.Y - 1
|
||||||
@@ -79,7 +102,11 @@ func (g *RogueGame) digRooms() {
|
|||||||
rp.Pos.Y++
|
rp.Pos.Y++
|
||||||
rp.Max.Y--
|
rp.Max.Y--
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
|
||||||
|
// placeNormalRoom rolls a place and size for an ordinary room (rooms.c
|
||||||
|
// do_rooms).
|
||||||
|
func (g *RogueGame) placeNormalRoom(rp *Room, top, bsze Coord) {
|
||||||
for {
|
for {
|
||||||
rp.Max.X = g.rnd(bsze.X-4) + 4
|
rp.Max.X = g.rnd(bsze.X-4) + 4
|
||||||
rp.Max.Y = g.rnd(bsze.Y-4) + 4
|
rp.Max.Y = g.rnd(bsze.Y-4) + 4
|
||||||
@@ -87,14 +114,17 @@ func (g *RogueGame) digRooms() {
|
|||||||
|
|
||||||
rp.Pos.Y = top.Y + g.rnd(bsze.Y-rp.Max.Y)
|
rp.Pos.Y = top.Y + g.rnd(bsze.Y-rp.Max.Y)
|
||||||
if rp.Pos.Y != 0 {
|
if rp.Pos.Y != 0 {
|
||||||
break
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
g.drawRoom(rp)
|
// roomGold maybe puts a gold pile in the room (rooms.c do_rooms).
|
||||||
// Put the gold in
|
func (g *RogueGame) roomGold(rp *Room) {
|
||||||
if g.rnd(2) == 0 && (!g.HasAmulet || g.Depth >= g.MaxDepth) {
|
if g.rnd(2) != 0 || (g.HasAmulet && g.Depth < g.MaxDepth) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
gold := newObject()
|
gold := newObject()
|
||||||
rp.GoldVal = g.goldCalc()
|
rp.GoldVal = g.goldCalc()
|
||||||
gold.GoldValue = rp.GoldVal
|
gold.GoldValue = rp.GoldVal
|
||||||
@@ -107,7 +137,10 @@ func (g *RogueGame) digRooms() {
|
|||||||
gold.Kind = KindGold
|
gold.Kind = KindGold
|
||||||
g.Level.AddObject(gold)
|
g.Level.AddObject(gold)
|
||||||
}
|
}
|
||||||
// Put the monster in
|
|
||||||
|
// roomMonster maybe puts a monster in the room; gold attracts them
|
||||||
|
// (rooms.c do_rooms).
|
||||||
|
func (g *RogueGame) roomMonster(rp *Room) {
|
||||||
prob := 25
|
prob := 25
|
||||||
if rp.GoldVal > 0 {
|
if rp.GoldVal > 0 {
|
||||||
prob = 80
|
prob = 80
|
||||||
@@ -120,7 +153,6 @@ func (g *RogueGame) digRooms() {
|
|||||||
g.givePack(tp)
|
g.givePack(tp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// drawRoom draws a box around a room and lays down the floor for normal
|
// drawRoom draws a box around a room and lays down the floor for normal
|
||||||
// rooms; for maze rooms, draws the maze (rooms.c draw_room).
|
// rooms; for maze rooms, draws the maze (rooms.c draw_room).
|
||||||
@@ -182,9 +214,28 @@ func (g *RogueGame) digMaze(rp *Room) {
|
|||||||
// dig digs out from around where we are now, if possible (rooms.c dig).
|
// dig digs out from around where we are now, if possible (rooms.c dig).
|
||||||
func (g *RogueGame) dig(y, x int) {
|
func (g *RogueGame) dig(y, x int) {
|
||||||
m := &g.maze
|
m := &g.maze
|
||||||
del := [4]Coord{{X: 2, Y: 0}, {X: -2, Y: 0}, {X: 0, Y: 2}, {X: 0, Y: -2}}
|
|
||||||
|
|
||||||
for {
|
for {
|
||||||
|
nexty, nextx, ok := g.digPick(y, x)
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
g.accountMaze(y, x, nexty, nextx)
|
||||||
|
g.accountMaze(nexty, nextx, y, x)
|
||||||
|
|
||||||
|
g.putPassage(digWallGap(m, y, x, nexty, nextx))
|
||||||
|
g.putPassage(Coord{Y: nexty + m.starty, X: nextx + m.startx})
|
||||||
|
g.dig(nexty, nextx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// digPick reservoir-picks the next unvisited maze cell; ok is false
|
||||||
|
// when the digger is boxed in (the candidate scan of rooms.c dig).
|
||||||
|
func (g *RogueGame) digPick(y, x int) (int, int, bool) {
|
||||||
|
m := &g.maze
|
||||||
|
del := [4]Coord{{X: 2, Y: 0}, {X: -2, Y: 0}, {X: 0, Y: 2}, {X: 0, Y: -2}}
|
||||||
|
|
||||||
cnt := 0
|
cnt := 0
|
||||||
|
|
||||||
var nexty, nextx int
|
var nexty, nextx int
|
||||||
@@ -207,13 +258,12 @@ func (g *RogueGame) dig(y, x int) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if cnt == 0 {
|
return nexty, nextx, cnt != 0
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
g.accountMaze(y, x, nexty, nextx)
|
// digWallGap picks the wall square to knock out between two maze cells
|
||||||
g.accountMaze(nexty, nextx, y, x)
|
// (rooms.c dig).
|
||||||
|
func digWallGap(m *mazeState, y, x, nexty, nextx int) Coord {
|
||||||
var pos Coord
|
var pos Coord
|
||||||
if nexty == y {
|
if nexty == y {
|
||||||
pos.Y = y + m.starty
|
pos.Y = y + m.starty
|
||||||
@@ -231,12 +281,7 @@ func (g *RogueGame) dig(y, x int) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
g.putPassage(pos)
|
return pos
|
||||||
pos.Y = nexty + m.starty
|
|
||||||
pos.X = nextx + m.startx
|
|
||||||
g.putPassage(pos)
|
|
||||||
g.dig(nexty, nextx)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// accountMaze accounts for maze exits (rooms.c accnt_maze).
|
// accountMaze accounts for maze exits (rooms.c accnt_maze).
|
||||||
@@ -278,13 +323,20 @@ func (g *RogueGame) findFloorIn(rp *Room, limit int, monst bool) (Coord, bool) {
|
|||||||
return g.findFloorImpl(rp, limit, monst, false)
|
return g.findFloorImpl(rp, limit, monst, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// floorChar is what an empty spot looks like in a room: passage in a
|
||||||
|
// maze, floor otherwise (rooms.c find_floor).
|
||||||
|
func floorChar(rp *Room) byte {
|
||||||
|
if rp.Flags.Has(Maze) {
|
||||||
|
return Passage
|
||||||
|
}
|
||||||
|
|
||||||
|
return Floor
|
||||||
|
}
|
||||||
|
|
||||||
func (g *RogueGame) findFloorImpl(rp *Room, limit int, monst, pickroom bool) (Coord, bool) {
|
func (g *RogueGame) findFloorImpl(rp *Room, limit int, monst, pickroom bool) (Coord, bool) {
|
||||||
var compchar byte
|
var compchar byte
|
||||||
if !pickroom {
|
if !pickroom {
|
||||||
compchar = Floor
|
compchar = floorChar(rp)
|
||||||
if rp.Flags.Has(Maze) {
|
|
||||||
compchar = Passage
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cnt := limit
|
cnt := limit
|
||||||
@@ -297,11 +349,7 @@ func (g *RogueGame) findFloorImpl(rp *Room, limit int, monst, pickroom bool) (Co
|
|||||||
|
|
||||||
if pickroom {
|
if pickroom {
|
||||||
rp = &g.Level.Rooms[g.randomRoom()]
|
rp = &g.Level.Rooms[g.randomRoom()]
|
||||||
|
compchar = floorChar(rp)
|
||||||
compchar = Floor
|
|
||||||
if rp.Flags.Has(Maze) {
|
|
||||||
compchar = Passage
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cp := g.randomPos(rp)
|
cp := g.randomPos(rp)
|
||||||
@@ -330,6 +378,15 @@ func (g *RogueGame) enterRoom(cp Coord) {
|
|||||||
g.move(y, rp.Pos.X)
|
g.move(y, rp.Pos.X)
|
||||||
|
|
||||||
for x := rp.Pos.X; x < rp.Max.X+rp.Pos.X; x++ {
|
for x := rp.Pos.X; x < rp.Max.X+rp.Pos.X; x++ {
|
||||||
|
g.enterRoomCell(y, x)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// enterRoomCell draws one square of a room being lit on entry (the loop
|
||||||
|
// body of rooms.c enter_room).
|
||||||
|
func (g *RogueGame) enterRoomCell(y, x int) {
|
||||||
tp := g.Level.MonsterAt(y, x)
|
tp := g.Level.MonsterAt(y, x)
|
||||||
|
|
||||||
ch := g.Level.Char(y, x)
|
ch := g.Level.Char(y, x)
|
||||||
@@ -339,23 +396,24 @@ func (g *RogueGame) enterRoom(cp Coord) {
|
|||||||
} else {
|
} else {
|
||||||
g.move(y, x+1)
|
g.move(y, x+1)
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
tp.OldCh = ch
|
tp.OldCh = ch
|
||||||
if !g.seeMonst(tp) {
|
if g.seeMonst(tp) {
|
||||||
if p.On(SenseMonsters) {
|
g.addch(tp.Disguise)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if g.Player.On(SenseMonsters) {
|
||||||
g.standout()
|
g.standout()
|
||||||
g.addch(tp.Disguise)
|
g.addch(tp.Disguise)
|
||||||
g.standend()
|
g.standend()
|
||||||
} else {
|
} else {
|
||||||
g.addch(ch)
|
g.addch(ch)
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
g.addch(tp.Disguise)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// leaveRoom is the code for when we exit a room (rooms.c leave_room).
|
// leaveRoom is the code for when we exit a room (rooms.c leave_room).
|
||||||
@@ -381,6 +439,16 @@ func (g *RogueGame) leaveRoom(cp Coord) {
|
|||||||
p.Room = &g.Level.Passages[*g.Level.FlagsAt(cp.Y, cp.X)&FPassNum]
|
p.Room = &g.Level.Passages[*g.Level.FlagsAt(cp.Y, cp.X)&FPassNum]
|
||||||
for y := rp.Pos.Y; y < rp.Max.Y+rp.Pos.Y; y++ {
|
for y := rp.Pos.Y; y < rp.Max.Y+rp.Pos.Y; y++ {
|
||||||
for x := rp.Pos.X; x < rp.Max.X+rp.Pos.X; x++ {
|
for x := rp.Pos.X; x < rp.Max.X+rp.Pos.X; x++ {
|
||||||
|
g.leaveRoomCell(floor, y, x)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
g.doorOpen(rp)
|
||||||
|
}
|
||||||
|
|
||||||
|
// leaveRoomCell hides one square of a room being left (the loop body of
|
||||||
|
// rooms.c leave_room).
|
||||||
|
func (g *RogueGame) leaveRoomCell(floor byte, y, x int) {
|
||||||
g.move(y, x)
|
g.move(y, x)
|
||||||
|
|
||||||
switch ch := g.inch(); ch {
|
switch ch := g.inch(); ch {
|
||||||
@@ -391,13 +459,16 @@ func (g *RogueGame) leaveRoom(cp Coord) {
|
|||||||
default:
|
default:
|
||||||
// to check for monster, we have to strip out the standout
|
// to check for monster, we have to strip out the standout
|
||||||
// bit (our Window returns the bare character already)
|
// bit (our Window returns the bare character already)
|
||||||
if isUpper(ch) {
|
if !isUpper(ch) {
|
||||||
if p.On(SenseMonsters) {
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if g.Player.On(SenseMonsters) {
|
||||||
g.standout()
|
g.standout()
|
||||||
g.addch(ch)
|
g.addch(ch)
|
||||||
g.standend()
|
g.standend()
|
||||||
|
|
||||||
break
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
pp := g.Level.At(y, x)
|
pp := g.Level.At(y, x)
|
||||||
@@ -408,8 +479,3 @@ func (g *RogueGame) leaveRoom(cp Coord) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
g.doorOpen(rp)
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user