Logo Search packages:      
Sourcecode: val-and-rick version File versions  Download package

stagemanager.d

/*
 * $Id: stagemanager.d,v 1.1.1.1 2005/03/13 16:15:04 kenta Exp $
 *
 * Copyright 2005 Kenta Cho. Some rights reserved.
 */
module abagames.vr.stagemanager;

private import std.string;
private import std.math;
private import bulletml;
private import abagames.util.vector;
private import abagames.util.rand;
private import abagames.vr.enemy;
private import abagames.vr.barrage;
private import abagames.vr.bulletimpl;
private import abagames.vr.bulletactorpool;
private import abagames.vr.shape;
private import abagames.vr.ship;
private import abagames.vr.field;
private import abagames.vr.letter;

/**
 * Manage an enemys' appearance.
 */
00025 public class StageManager {
 private:
  static const float RANK_INC = 0.0018f;
  static const int ZAKO_CHANGE_DIST_BASE = 50;
  Field field;
  EnemyPool enemies;
  Ship ship;
  BulletActorPool bullets;
  Rand rand;
  float zakoChangeDist;
  float rank, baseRank, rankVel;
  ZakoAppearance[] zakoApp;
  EB1Spec eb1Spec;
  int eb1ChangeCnt;
  bool _showRank;

  public this(Field field, EnemyPool enemies, Ship ship, BulletActorPool bullets) {
    this.field = field;
    this.enemies = enemies;
    this.ship = ship;
    this.bullets = bullets;
    rand = new Rand;
    zakoApp = new ZakoAppearance[2];
    foreach (inout ZakoAppearance za; zakoApp)
      za = new ZakoAppearance;
  }

  public void start(long seed) {
    rand.setSeed(seed);
    rank = baseRank = rankVel = 0;
    zakoChangeDist = 0;
    changeZako();
    changeEb1();
  }

  public void move() {
    if (!ship.airMode) {
      rankVel += (field.lastScrollY / ship.scrollSpeedBase - 1) * 0.33f;
      rankVel *= 0.98f;
      rank += RANK_INC * (rankVel + 1);
      rank += (baseRank - rank) * 0.005f;
    } else {
      if (ship.toAir || ship.toGround)
        rank += (baseRank - rank) * 0.05f;
      else
        rank += RANK_INC * 7;
    }
    baseRank += RANK_INC;
    if (!ship.toAir && !ship.toGround)
      foreach (ZakoAppearance za; zakoApp)
        za.move(field, enemies, ship, rand);
    zakoChangeDist -= field.lastScrollY;
    if (zakoChangeDist <= 0)
      changeZako();
  }

  public void addBatteries(Vector[] panelPos, int panelPosNum) {
    if (ship.airMode || rand.nextInt(4) == 0 || panelPosNum <= 0)
      return;
    int ppi = rand.nextInt(panelPosNum);
    Enemy en = enemies.getInstance();
    if (en) {
      Vector p = field.convertToScreenPos(cast(int) panelPos[ppi].x, cast(int) panelPos[ppi].y);
      eb1Spec.setFirstState(en.state, p.x, p.y, cast(int) panelPos[ppi].x, cast(int) panelPos[ppi].y);
      en.set(eb1Spec);
    }
    eb1ChangeCnt--;
    if (eb1ChangeCnt <= 0)
      changeEb1();
  }

  public void close() {
  }

  public void changeZakoForced() {
    zakoChangeDist = 0;
    changeZako();
  }

  private void changeZako() {
    zakoChangeDist += ZAKO_CHANGE_DIST_BASE * (1 + rand.nextSignedFloat(0.2f));
    float zr = rank * 0.2f;
    int apn = cast(int) (4 + rank * 0.33f);
    if (apn > 10)
      apn = 10;
    zakoApp[1].set(null, 0, null, null);
    switch (rand.nextInt(apn)) {
    case 0:
    case 1:
    case 2:
      zakoApp[0].set(new EG1Spec(bullets, field, ship), zr, ship, rand);
      break;
    case 3:
    case 4:
      zakoApp[0].set(new EG2Spec(bullets, field, ship), zr, ship, rand);
      break;
    case 5:
    case 6:
      zr /= 2;
      zakoApp[0].set(new EG1Spec(bullets, field, ship), zr, ship, rand);
      zakoApp[1].set(new EG2Spec(bullets, field, ship), zr, ship, rand);
      break;
    case 7:
      zakoApp[0].set(new EA1Spec(bullets, field, ship), zr, ship, rand, 1.5f);
      break;
    case 8:
      zr /= 2;
      zakoApp[0].set(new EG1Spec(bullets, field, ship), zr, ship, rand);
      zakoApp[1].set(new EA1Spec(bullets, field, ship), zr, ship, rand, 2);
      break;
    case 9:
      zr /= 2;
      zakoApp[0].set(new EG2Spec(bullets, field, ship), zr, ship, rand);
      zakoApp[1].set(new EA1Spec(bullets, field, ship), zr, ship, rand, 2);
      break;
    }
  }

  private void changeEb1() {
    eb1ChangeCnt = 1;
    eb1Spec = new EB1Spec(bullets, field, ship);
    int mbn = cast(int) (rank * 0.2f);
    if (mbn > EnemyState.ENEMY_BIT_MAX)
      mbn = EnemyState.ENEMY_BIT_MAX;
    if (mbn >= 2)
      eb1Spec.bitNum = 1 + rand.nextInt(mbn - 1);
    else
      eb1Spec.bitNum = 1;
    float br = rank / eb1Spec.bitNum;
    int type;
    switch (rand.nextInt(4)) {
    case 0:
    case 1:
      type = 0;
      break;
    case 2:
      type = 1;
      break;
    case 3:
      type = 2;
      break;
    }
    float rad = 0.9f + rand.nextFloat(0.4f) - eb1Spec.bitNum * 0.1f;
    float radInc = 0.5f + rand.nextFloat(0.25f);
    float ad = PI * 2;
    float a, av, dv, s, sv;
    switch (type) {
    case 0:
      if (rand.nextInt(5) == 0)
        ad = PI / 2 + rand.nextFloat(PI / 2);
      a = 0.01f + rand.nextFloat(0.04f);
      av = 0.01f + rand.nextFloat(0.03f);
      dv = 0.01f + rand.nextFloat(0.04f);
      break;
    case 1:
      ad = PI / 3 + rand.nextFloat(PI / 2);
      s = 0.01f + rand.nextFloat(0.02f);
      sv = 0.01f + rand.nextFloat(0.03f);
      break;
    case 2:
      ad = PI / 3 + rand.nextFloat(PI / 2);
      if (rand.nextInt(5) == 0)
        s = 0.01f + rand.nextFloat(0.01f);
      else
        s = 0;
      sv = 0.01f + rand.nextFloat(0.02f);
      break;
    }
    for (int i = 0; i < eb1Spec.bitNum; i++) {
      EnemyBitSpec ebs = eb1Spec.bitSpec[i];
      ebs.moveType = type;
      ebs.radiusBase = rad;
      float sr;
      switch (type) {
      case 0:
        ebs.alignDeg = ad;
        ebs.num = 4 + rand.nextInt(6);
        if (rand.nextInt(2) == 0) {
          if (rand.nextInt(2) == 0)
            ebs.setRoll(dv, 0, 0);
          else
            ebs.setRoll(-dv, 0, 0);
        } else {
          if (rand.nextInt(2) == 0)
            ebs.setRoll(0, a, av);
          else
            ebs.setRoll(0, -a, av);
        }
        if (rand.nextInt(3) == 0)
          ebs.setRadiusAmp(1 + rand.nextFloat(1), 0.01f + rand.nextFloat(0.03f));
        if (rand.nextInt(2) == 0)
          ebs.distRatio = 0.8f + rand.nextSignedFloat(0.3f);
        sr = br / ebs.num;
        break;
      case 1:
        ebs.num = 3 + rand.nextInt(5);
        ebs.alignDeg = ad * (ebs.num * 0.1f + 0.3f);
        if (rand.nextInt(2) == 0)
          ebs.setSwing(s, sv);
        else
          ebs.setSwing(-s, sv);
        if (rand.nextInt(6) == 0)
          ebs.setRadiusAmp(1 + rand.nextFloat(1), 0.01f + rand.nextFloat(0.03f));
        if (rand.nextInt(4) == 0)
          ebs.setAlignAmp(0.25f + rand.nextFloat(0.5f), 0.01f + rand.nextFloat(0.02f));
        sr = br / ebs.num;
        sr *= 0.6f;
        break;
      case 2:
        ebs.num = 3 + rand.nextInt(4);
        ebs.alignDeg = ad * (ebs.num * 0.1f + 0.3f);
        if (rand.nextInt(2) == 0)
          ebs.setSwing(s, sv, true);
        else
          ebs.setSwing(-s, sv, true);
        if (rand.nextInt(4) == 0)
          ebs.setRadiusAmp(1 + rand.nextFloat(1), 0.01f + rand.nextFloat(0.03f));
        if (rand.nextInt(5) == 0)
          ebs.setAlignAmp(0.25f + rand.nextFloat(0.5f), 0.01f + rand.nextFloat(0.02f));
        sr = br / ebs.num;
        sr *= 0.4f;
        break;
      }
      float morphRank = sr * (0.4f + rand.nextSignedFloat(0.2f));
      float ir = (sr - morphRank) * (0.5f + rand.nextSignedFloat(0.2f));
      float pr = sr - morphRank - ir;
      morphRank *= 2;
      if (!ship.airMode)
        ir *= 3;
      else
        ir *= 0.5f;
      pr /= 2;
      if (pr > 2) {
        pr = 2;
        morphRank *= pr / 2;
        ir *= pr / 2;
      }
      ebs.barragePostWait = cast(int) (90 / (ir + 1));
      ebs.barrageSpeed = 0.4f * (pr + 1);
      ebs.barrage = null;
      BulletMLParserTinyXML* bp = BarrageManager.getInstance("basic", "straight.xml");
      ebs.barrage ~= new ParserParam(bp, 1, false, 1);
      BulletMLParserTinyXML*[] ps = BarrageManager.getInstanceList("morph");
      while (morphRank > 1) {
        morphRank /= 3;
        int pi = rand.nextInt(ps.length);
        float mr = morphRank;
        if (mr > 0.75f)
          mr = 0.75f + rand.nextFloat(0.25f);
        ebs.barrage ~= new ParserParam(ps[pi], mr, false, 1);
      }
      rad += radInc;
      ad *= 1 + rand.nextSignedFloat(0.2f);
    }
  }

  public void draw() {
    if(_showRank)
      Letter.drawNum(cast(int) (rank * 100), 8.6f, -10.3f, 1);
  }

  public bool showRank(bool v) {
    return _showRank = v;
  }
}

public class ZakoAppearance {
 private:
  EnemySpec spec;
  float nextAppDist, nextAppDistInterval;
  float bulletMaxSpeed, bulletMinSpeed;

  public void set(EnemySpec s, float rank, Ship ship, Rand rand, float appDistRatio = 1) {
    spec = s;
    if (!spec)
      return;
    nextAppDist = nextAppDistInterval =
      (1 + rand.nextFloat(1)) / (rank * 0.8f + 0.5f) * appDistRatio;
    float br = rank * nextAppDistInterval;
    float ir = br * (0.5 + rand.nextFloat(0.2)) * 0.8f;
    float sr = (br - ir) * 0.4f;
    spec.barrage = null;
    BulletMLParserTinyXML* bp = BarrageManager.getInstance("basic", "straight.xml");
    spec.barrage ~= new ParserParam(bp, 1, false, 1);
    bulletMaxSpeed = 0.51f * (sr + 1);
    bulletMinSpeed = 0.5f / (sr + 1);
    if (ship.airMode) {
      float morphRank = rank * 0.25f;
      BulletMLParserTinyXML*[] ps = BarrageManager.getInstanceList("morph");
      while (morphRank > 1) {
        morphRank /= 3;
        int pi = rand.nextInt(ps.length);
        float mr = morphRank;
        if (mr > 0.75f)
          mr = 0.75f + rand.nextFloat(0.25f);
        spec.barrage ~= new ParserParam(ps[pi], mr, false, 1);
      }
      bulletMaxSpeed *= 3;
      bulletMinSpeed *= 1.75f;
      spec.setBarrageInterval(cast(int) (48 / (ir + 1)) + 1);
      nextAppDistInterval *= 3;
      nextAppDist = nextAppDistInterval;
    } else {
      spec.setBarrageInterval(cast(int) (120 / (ir + 1)) + 1);
    }
    float pr = rank * 0.2f;
    EG1Spec g1s = cast(EG1Spec) spec;
    if (g1s) {
      float ss;
      if (rand.nextInt(4) == 0)
        ss = rand.nextSignedFloat(0.05f);
      else
        ss = 0;
      g1s.setParam(0.5f - 0.5f / (2 + rand.nextFloat(pr)),
                   0.06f * (1 + rand.nextFloat(pr)),
                   ss, 32 + rand.nextSignedInt(12), 32 + rand.nextSignedInt(12));
    }
    EG2Spec g2s = cast(EG2Spec) spec;
    if (g2s)
      g2s.setParam(0.036f * (1 + rand.nextFloat(pr)), 0.02f + rand.nextSignedFloat(0.04f));
    EA1Spec a1s = cast(EA1Spec) spec;
    if (a1s)
      a1s.setParam(0.15f * (1 + rand.nextSignedFloat(0.2f)), 0.15f * (1 + rand.nextSignedFloat(0.2f)));
  }

  public void move(Field field, EnemyPool enemies, Ship ship, Rand rand) {
    if (!spec)
      return;
    nextAppDist -= field.lastScrollY;
    if (nextAppDist <= 0) {
      nextAppDist += nextAppDistInterval;
      appear(enemies, ship, rand);
    }
  }

  private void appear(EnemyPool enemies, Ship ship, Rand rand) {
    Enemy en = enemies.getInstance();
    if (en) {
      spec.setBarrageSpeed(bulletMinSpeed + rand.nextFloat(bulletMaxSpeed - bulletMinSpeed));
      EG1Spec g1s = cast(EG1Spec) spec;
      if (g1s)
        if (g1s.setFirstState(en.state, EnemyState.AppearanceType.TOP))
          en.set(g1s);
      EG2Spec g2s = cast(EG2Spec) spec;
      if (g2s)
        if (g2s.setFirstState(en.state))
          en.set(g2s);
      EA1Spec a1s = cast(EA1Spec) spec;
      if (a1s)
        if (a1s.setFirstState(ship, en.state))
          en.set(a1s);
    }
  }
}

Generated by  Doxygen 1.6.0   Back to index