/** The ship is not allowed to go beyond the dome Droplets fall down from the top of the dome. */ class Dome : ActionRole() { @Attribute var rainPeriod = 3.0 // Used to test if ships/cargo are outside of an ellipse bounded by this rectangle. val rect = Rect() override fun begin() { Play.instance.dome = this // Make rect a bit SMALLER than the true rectangle, by the radius of cargo/ship (ish) // Therefore [isOutside] will be closer to perfect. // Without this margin, ships/cargo will explode when their CENTERS are outside of the dome. rect.set( actor.appearance.worldRect()) val margin = 30 rect.left += margin rect.right -= margin rect.top -= margin prepareDrip() } fun prepareDrip() { if (rainPeriod > 0) { val period = rainPeriod + Rand.plusMinus( rainPeriod/2 ) replaceAction( Delay( period ) thenOnce this:>drip ) } } fun drip() { val event = if (Options.instance.moreAcid == 2) "acidDrip" else "drip" val dripA = actor.createChild( event ) val dx = Rand.plusMinus( 0.5 ) val dy = Math.sqrt( 1 - dx * dx ) dripA.position.x += dx * actor.appearance.width() /2 * actor.scale.x dripA.position.y += dy * actor.appearance.height() * actor.scale.y - 40 prepareDrip() } fun isOutside( other : Actor ) : bool { val domeY = actor.y val otherY = other.y if ( otherY > domeY ) { // Check if other's actor's center is outside of the ellipse bounded by [rect] // [rect] is slightly smaller than the dome, to help compensate for the size of the ship/cargo. // If we have BIG ships/cargo, then the ship/cargo will be able to poke through a little bit. val otherX = other.x val domeX = actor.x val dx = (otherX - domeX) / rect.width * 2 val dy = (otherY - domeY) / rect.height return (dx*dx + dy*dy > 1.0) } return false } }