example/bundle.js
// returns true if the tunneler is alive
returns true if the tunneler is alive
returns true if the tunneler is alive
step() {
    let changeDir, direction
    if (this.steps >= this.maxSteps) {
      const diceRoll = random.next() * 100
      if (diceRoll < this.joinProb) {
        const roomSize = this._getRoomSizeExcavation()
        changeDir = random.next() * 100
        if (changeDir <= this.changeDirectionProb) {
          direction = turn90Random(this.direction)
        } else {
          ({ direction } = this)
        }
        const r = new Roomie(this, this.generation, direction, this.level, this.design, roomSize)
        this.level.workers.push(r)
      }
      return DEAD
    }
    this.steps++
    const t = new Tunnel(this.level, this.parentTunnel)
    let pos = this._getNewTunnelerPosition(this.parentTunnel, this.tunnelWidth, this.direction)
    const state = t.excavate(pos, this.direction, this.stepLength, this.tunnelWidth)
    if ([ 'DUNGEON-OVERLAP', 'PREFAB-OVERLAP', 'ROOM-CORNER-OVERLAP' ].indexOf(state) >= 0) {
      if (!this.isLastChanceTunneler) {
        this._spawnLastChanceTunneler()
      }
      return DEAD
    }
    if (t.width && t.height) {
      this.level.addEntity(t)
      this.parentTunnel = t 
    }
    if ([ 'ANTEROOM', 'ROOM', 'TUNNEL', 'DOOR' ].indexOf(state) >= 0) {
      return DEAD
    }
    const tunnelEndpos = t.getEndPosition()
    this.x = tunnelEndpos.x
    this.y = tunnelEndpos.y
    let changedDirection = false
    let anteroom = null
    this.lastDirection = this.direction
    let babies = []
    changeDir = random.next() * 100
    if (changeDir <= this.changeDirectionProb) {
      this.direction = turn90Random(this.direction)
      changedDirection = true
      babies = this._spawnTunnelers(this.turnDoubleSpawnProb, t)
    } else {
      babies = this._spawnTunnelers(this.straightDoubleSpawnProb, t)
    }
    if (changedDirection || babies.length) {
      const probability = getValue(this.design.anteroomProbability, this.tunnelWidth)
      anteroom = this._spawnAnteroom(probability, t)
    }
    if (anteroom) {
      const newPos = anteroom.getCenteredExit(this.direction)
      this.x = newPos.x
      this.y = newPos.y
      this.level.addEntity(anteroom)
    }
    for (let baby of Array.from(babies)) {
      if (anteroom) {
        pos = anteroom.getCenteredExit(baby.direction)
        baby.x = pos.x
        baby.y = pos.y
      }
      this.level.workers.push(baby)
    }
    if (changedDirection) {
      pos = this._getNewTunnelerPosition(t, this.tunnelWidth, this.direction)
      this.x = pos.x
      this.y = pos.y
    }
    this._addRoomies(t, changedDirection, anteroom)
    return ALIVE
  }
step ( ) { let changeDir , direction if ( this . steps >= this . maxSteps ) { const diceRoll = random . next ( ) * 100 if ( diceRoll < this . joinProb ) { const roomSize = this . _getRoomSizeExcavation ( ) changeDir = random . next ( ) * 100 if ( changeDir <= this . changeDirectionProb ) { direction = turn90Random ( this . direction ) } else { ( { direction } = this ) } const r = new Roomie ( this , this . generation , direction , this . level , this . design , roomSize ) this . level . workers . push ( r ) } return DEAD } this . steps ++ const t = new Tunnel ( this . level , this . parentTunnel ) let pos = this . _getNewTunnelerPosition ( this . parentTunnel , this . tunnelWidth , this . direction ) const state = t . excavate ( pos , this . direction , this . stepLength , this . tunnelWidth ) if ( [ 'DUNGEON-OVERLAP' , 'PREFAB-OVERLAP' , 'ROOM-CORNER-OVERLAP' ] . indexOf ( state ) >= 0 ) { if ( ! this . isLastChanceTunneler ) { this . _spawnLastChanceTunneler ( ) } return DEAD } if ( t . width && t . height ) { this . level . addEntity ( t ) this . parentTunnel = t } if ( [ 'ANTEROOM' , 'ROOM' , 'TUNNEL' , 'DOOR' ] . indexOf ( state ) >= 0 ) { return DEAD } const tunnelEndpos = t . getEndPosition ( ) this . x = tunnelEndpos . x this . y = tunnelEndpos . y let changedDirection = false let anteroom = null this . lastDirection = this . direction let babies = [ ] changeDir = random . next ( ) * 100 if ( changeDir <= this . changeDirectionProb ) { this . direction = turn90Random ( this . direction ) changedDirection = true babies = this . _spawnTunnelers ( this . turnDoubleSpawnProb , t ) } else { babies = this . _spawnTunnelers ( this . straightDoubleSpawnProb , t ) } if ( changedDirection || babies . length ) { const probability = getValue ( this . design . anteroomProbability , this . tunnelWidth ) anteroom = this . _spawnAnteroom ( probability , t ) } if ( anteroom ) { const newPos = anteroom . getCenteredExit ( this . direction ) this . x = newPos . x this . y = newPos . y this . level . addEntity ( anteroom ) } for ( let baby of Array . from ( babies ) ) { if ( anteroom ) { pos = anteroom . getCenteredExit ( baby . direction ) baby . x = pos . x baby . y = pos . y } this . level . workers . push ( baby ) } if ( changedDirection ) { pos = this . _getNewTunnelerPosition ( t , this . tunnelWidth , this . direction ) this . x = pos . x this . y = pos . y } this . _addRoomies ( t , changedDirection , anteroom ) return ALIVE }
returns true if the tunneler is alive
returns true if the tunneler is alive
// tunneler has expired // tunnelers that end without hitting anything have a chance to spawn a room // don't allow last chance tunnelers that fail to spawn again. Otherwise, we get into // infinite loop situations. for example, when a tunneler that creates a wide tunnel hits the // level edge and can't turn or do anything. // if the tunnel has height and width, it was (at least partially) // excavated, so add it to the level // update the new parent tunnel for dis shiz // update tunneler's position to the end of the excavated tunnel // at this point, state must be CLOSED (the tunnel fully excavated without hitting any open space) // TODO: since the last chance tunneler succeeded (fully excavated,) mark it as no longer a last chance? //@isLastChanceTunneler = false // move the tunneler to an anteroom exit based on direction and anteroom size /*
      * reduce the newly created tunnel's dimensions to not overlap with the new anteroom
      if t.direction is 'EAST'
        amount = Math.ceil(anteroom.width / 2)
        t.width -= amount
      if t.direction is 'WEST'
        amount = Math.ceil(anteroom.width / 2)
        t.x += amount
        t.width -= amount
      if t.direction is 'NORTH'
        amount = Math.ceil(anteroom.height / 2)
        t.height -= amount
        t.y += amount
      if t.direction is 'SOUTH'
        amount = Math.ceil(anteroom.height / 2)
        t.height -= amount
      */ // if an anteroom was created move the baby tunnelers to the anteroom's // exit in the direction of the baby tunnelers future excavation