// There are two kinds, wooden and natural hives. // The natural hives are designed to be placed on a "ceiling", and will not move // until pushed. // The wooden do not need a push to start moving // // Hives release a number of bees, which then pollinate flowers, and hopefully // return to the hive. // Once all of the bees have returned, the hive becomes collectable. // // If [bees] == 0, then the hive is NOT valuable, and can never be collected. // // Attributes determine the number of bees to be released, the initial delay, // the time between releases, the direction of the release, and the // clockwise/anticlockwise nature of the bees. // // While bees mimic Repton's spirits, Repton doens't have a concept similar to a Hive. // // Note. It is good practice to use a Sledge to tell the player when the Hive's // initial delay is about to end. e.g. "I think I hear bees" class Hive : Rock { @CostumeAttribute var wooden = false @Attribute var bees = 0 @Attribute var leftFirst = true // Seconds till 1st bee exits @Attribute var delay = 1 // Period between each bee's exit @Attribute var period = 3 // The direction bees exit the hive. @Attribute var direction = 0 var attached = true var beesReleased = 0 var beesReturned = 0 // We need bees released only when the hive isn't moving, and at regular // intervals. So timerAction does the delays, setting beeDue when a bee is due. // Then myTurn checks the boolean, and releases a bee if needed var beeDue = false var timerAction : Action override fun rounded( direction : int) : boolean { return !wooden || direction == NORTH_EAST || direction == NORTH_WEST } override fun collectable() = bees > 0 && beesReturned == bees // Can bees return to this hive? fun open() = beesReturned < bees override fun begin() { super.begin() attached = !wooden if ( bees > 0 ) { PlayDirector.instance.valuables ++ val foo = this:>setBeeDue.once() then Delay( delay ) timerAction = Delay( delay ) then foo.forever() timerAction.begin() } } fun setBeeDue() { beeDue = true } override fun tick() { if ( timerAction != null ) { timerAction.act() } super.tick() } override fun myTurn() { if ( beeDue ) { val next = look( direction, IMMEDIATELY ) if ( next.isEmpty() ) { beeDue = false val sq = square.neighbour( direction ) val mySquare = square val bee = actor.createChild( "bee" ).role as Bee sq.addOccupant( bee ) mySquare.addOccupant( this ) // The child will have taken over our square! bee.actor.x = sq.worldX() bee.actor.y = sq.worldY() bee.homeless = false bee.leftFirst = leftFirst bee.direction = direction bee.actor.event( "move${Item.directionAbbreviation(direction)}") beesReleased ++ if ( beesReleased >= bees ) { timerAction = null } return } } if ( ! attached ) { super.myTurn() } } override fun canRoll( dx : int ) : boolean = ! wooden && super.canRoll( dx ) override fun invading( movement : Movement ) { if ( movement.item.isPlayer() && collectable() ) { movement.item.speak( "Honey. Yummy!", 3 ) actor.event( "collected" ) replaceAction( ScaleTo( actor, 0.1, 0.2 ) ) PlayDirector.instance.valuables -- } } override fun invaded( movement : Movement ) : boolean { if ( movement.item is Bee ) { beesReturned ++ movement.item.actor.die() return false } else { actor.die() } return true } override fun moved( movement : Movement ) { super.moved( movement ) attached = false } override fun copyable() = false }