package rabbitescape.engine; import static rabbitescape.engine.ChangeDescription.State.*; import java.util.HashMap; import java.util.Map; import java.util.concurrent.ThreadLocalRandom; import rabbitescape.engine.ChangeDescription.State; public class Fire extends Thing { private final State baseVariant; public Fire( int x, int y ) { super( x, y, chooseVariant() ); baseVariant = state; } private static State chooseVariant() { int r = ThreadLocalRandom.current().nextInt( 0, 4 ); switch ( r ) { case 0: return FIRE_A; case 1: return FIRE_B; case 2: return FIRE_C; case 3: return FIRE_D; } throw new RuntimeException( "Random number outside expected range (0 - 3):" + r ); } @Override public void calcNewState( World world ) { // Check if being extinguished. for ( WaterRegion waterRegion : world.waterTable.getItemsAt( x, y ) ) { if ( waterRegion.getContents() > 0 ) { state = FIRE_EXTINGUISHING; return; } } Block blockBelow = world.getBlockAt( x, y + 1 ); // Note: when flatBelow is true may be on a slope with a flat below, // or sitting on the flat boolean flatBelow = BehaviourTools.s_isFlat( blockBelow ); boolean still = ( flatBelow || ( world.getBlockAt( x, y ) != null ) || BridgeTools.someoneIsBridgingAt( world, x, y ) ); if ( still ) { Block onBlock = world.getBlockAt( x, y ); if ( BehaviourTools.isLeftRiseSlope( onBlock ) ) { state = baseVariantSwitch( FIRE_A_RISE_LEFT, FIRE_B_RISE_LEFT, FIRE_C_RISE_LEFT, FIRE_D_RISE_LEFT ); return; } if ( BehaviourTools.isRightRiseSlope( onBlock ) ) { state = baseVariantSwitch( FIRE_A_RISE_RIGHT, FIRE_B_RISE_RIGHT, FIRE_C_RISE_RIGHT, FIRE_D_RISE_RIGHT ); return; } // TODO: check here for fire falling on a bridger. Fire going to a falling state may be OK // as bridger is burnt if ( flatBelow ) { state = baseVariant; return; } } else // Falling { if ( BehaviourTools.isLeftRiseSlope( blockBelow ) ) { state = baseVariantSwitch( FIRE_A_FALL_TO_RISE_LEFT, FIRE_B_FALL_TO_RISE_LEFT, FIRE_C_FALL_TO_RISE_LEFT, FIRE_D_FALL_TO_RISE_LEFT ); return; } if ( BehaviourTools.isRightRiseSlope( blockBelow ) ) { state = baseVariantSwitch( FIRE_A_FALL_TO_RISE_RIGHT, FIRE_B_FALL_TO_RISE_RIGHT, FIRE_C_FALL_TO_RISE_RIGHT, FIRE_D_FALL_TO_RISE_RIGHT ); return; } state = baseVariantSwitch( FIRE_A_FALLING, FIRE_B_FALLING, FIRE_C_FALLING, FIRE_D_FALLING ); return; } } private State baseVariantSwitch( State a, State b, State c, State d ) { switch ( baseVariant ) { case FIRE_A: return a; case FIRE_B: return b; case FIRE_C: return c; case FIRE_D: return d; default: throw new RuntimeException( "Fire not in fire state:" + state ); } } @Override public void step( World world ) { switch ( state ) { case FIRE_A_FALLING: case FIRE_B_FALLING: case FIRE_C_FALLING: case FIRE_D_FALLING: case FIRE_A_FALL_TO_RISE_RIGHT: case FIRE_B_FALL_TO_RISE_RIGHT: case FIRE_C_FALL_TO_RISE_RIGHT: case FIRE_D_FALL_TO_RISE_RIGHT: case FIRE_A_FALL_TO_RISE_LEFT: case FIRE_B_FALL_TO_RISE_LEFT: case FIRE_C_FALL_TO_RISE_LEFT: case FIRE_D_FALL_TO_RISE_LEFT: ++y; if ( y >= world.size.height ) { world.changes.removeFire( this ); } return; case FIRE_EXTINGUISHING: world.changes.removeFire( this ); return; default: return; } } @Override public Map<String, String> saveState() { return new HashMap<String, String>(); } @Override public void restoreFromState( Map<String, String> state ) { } @Override public String overlayText() { return "Fire"; } }