#include "stdafx.h"
#include "EnemyDuna.h"

#include "jp/ggaf/dxcore/actor/supporter/GgafDxAlphaFader.h"
#include "jp/ggaf/dxcore/actor/supporter/GgafDxKurokoA.h"
#include "jp/ggaf/dxcore/actor/supporter/GgafDxSeTransmitterForActor.h"
#include "jp/ggaf/dxcore/model/GgafDxModel.h"
#include "jp/ggaf/dxcore/actor/supporter/GgafDxMorpher.h"
#include "jp/ggaf/lib/util/CollisionChecker3D.h"
#include "jp/gecchi/VioletVreath/GameGlobal.h"
#include "jp/gecchi/VioletVreath/God.h"
#include "jp/gecchi/VioletVreath/scene/Universe/World/GameScene/MyShipScene.h"
#include "jp/gecchi/VioletVreath/util/MyStgUtil.h"
#include "jp/ggaf/dxcore/actor/supporter/GgafDxKurokoB.h"

using namespace GgafCore;
using namespace GgafDxCore;
using namespace GgafLib;
using namespace VioletVreath;

#define REV_TURN_ANGVELO (D_ANG(30))
#define LARGE_SEMIARC_ANGVELO (D_ANG(3))
#define SMALL_SEMIARC_ANGVELO (D_ANG(6))
#define SEMIARC_ANG (D_ANG(200))
EnemyDuna::EnemyDuna(const char* prm_name) :
        DefaultMorphMeshActor(prm_name, "1/Duna", STATUS(EnemyDuna)) {
    _class_name = "EnemyDuna";
    _pSeTx->set(SE_EXPLOSION, "WAVE_EXPLOSION_001");
    effectBlendOne(); //壛嶼崌惉
    setScaleR(0.3);
    useProgress(PROG_CLOSE);
}

void EnemyDuna::onCreateModel() {
    _pModel->setSpecular(5.0, 1.0);
}

void EnemyDuna::initialize() {
    _pColliChecker->makeCollision(1);
    _pColliChecker->setColliAAB_Cube(0, 40000);
}

void EnemyDuna::onActive() {
    _pStatus->reset();
    _pProg->reset(PROG_INIT);
}

void EnemyDuna::processBehavior() {
    //壛嶼儔儞僋億僀儞僩傪尭彮
    _pStatus->mul(STAT_AddRankPoint, _pStatus->getDouble(STAT_AddRankPoint_Reduction));

//    if (_pProg->isJustChanged()) {
//        _TRACE_("EnemyDuna::"<<_pProg->getFromProgOnChange()<<"仺"<<_pProg->get()<<"");
//    }

    MyShip* pMyShip = P_MYSHIP;
    if (_pProg->isJustChanged()) {
        _pKurokoB->execGravitationMvSequenceTwd(pMyShip, PX_C(3), 30, PX_C(1));
    }

    switch (_pProg->get()) {
        case PROG_INIT: {
            setHitAble(false);
            _pAFader->setAlpha(0);
            _pKurokoA->relateMvFaceAng(false);
            _pKurokoA->keepOnTurningFaceAngTwd(pMyShip,
                                               D_ANG(2), 0, TURN_CLOSE_TO,false);
            //_pKurokoA->setMvVelo(RF_EnemyDuna_MvVelo(G_RANK));
                         _pKurokoA->setMvVelo(PX_C(6));
            _pKurokoA->setRzRyMvAng(0, D90ANG);
            _pKurokoA->setRzMvAngVelo(D_ANG(12));
            _pKurokoA->setRzMvAngAcce(D_ANG(0.05));
            _pMorpher->setWeight(0.0);
            UTIL::activateEntryEffectOf(this);
            _pProg->changeNext();
            break;
        }
         case PROG_ENTRY_EFFECT: {
             if (_pProg->getFrameInProgress() == 60) {
                 _pAFader->fadeLinerUntil(1.0, 60);
             }
             if (getAlpha() > 0.5) {
                 setHitAble(true);
                 _pProg->changeNext();
             }
             break;
         }
         case PROG_ENTRY_MOVE01: {
             if (_pProg->isJustChanged()) {
             }
             _X -= PX_C(10);
             if (_X  < pMyShip->_X + PX_C(1000)) {
                 _pProg->changeNext();
             }
             break;
         }
         case PROG_ENTRY_MOVE02: {
             if (_pProg->isJustChanged()) {
                 _pKurokoA->turnRzRyMvAngTo(0, D180ANG, D_ANG(5), 0, TURN_CLOSE_TO,false);
                 _pKurokoA->turnRzRyFaceAngTo(0, D180ANG, D_ANG(5), 0, TURN_CLOSE_TO,false);
             }
             if (!_pKurokoA->isTurningMvAng() && !_pKurokoA->isTurningFaceAng()) {
                 _pKurokoA->relateMvFaceAng(true);
                 progress next = EnemyDuna::getProgressProbability(
                                      0, PROG_MOVE_ORDER_LARGE_SEMIARC_CW,
                                    250, PROG_MOVE_ORDER_LARGE_SEMIARC_CCW,
                                    250, PROG_MOVE_REV_LARGE_SEMIARC_CW,
                                      0, PROG_MOVE_REV_LARGE_SEMIARC_CCW,
                                      0, PROG_MOVE_ORDER_SMALL_SEMIARC_CW,
                                    250, PROG_MOVE_ORDER_SMALL_SEMIARC_CCW,
                                    250, PROG_MOVE_REV_SMALL_SEMIARC_CW,
                                      0, PROG_MOVE_REV_SMALL_SEMIARC_CCW
                                 );
                 _pProg->change(next);
             }
             break;
         }

         //  捈慜偺堏摦偑
         //
         //      | 仾        伀 |        |仾  伀|
         //       乢          乛    or    乢仼乛
         //         乢  仼  乛              丳
         //           丳丳丳
         //  偩偭偨応崌
         //             仺
         //           丵丵丵                         仺
         //         乛  仼  乢                       丵
         //       乛          乢                   乛仼乢
         //   仾 | 伀        仾 | 伀           仾 |伀  仾| 伀
         //   嘆             嘇                嘍      嘐
         //
         //
         //   嘋             嘊                嘒      嘑
         //   伀 | 仾        伀 |  仾          伀 |仾  伀| 仾
         //       乢          乛                   乢仼乛
         //         乢  仼  乛                       丳
         //           丳丳丳                         仺
         //             仺
         //
         //  嘆 丒丒丒 PROG_MOVE_ORDER_LARGE_SEMIARC_CW       弴曽岦丄  戝墌屖堏摦丄帪寁夞傝
         //  嘇 丒丒丒 PROG_MOVE_ORDER_LARGE_SEMIARC_CCW      弴曽岦丄  戝墌屖堏摦丄敿帪寁夞傝
         //  嘊 丒丒丒 PROG_MOVE_REV_LARGE_SEMIARC_CW         曽岦斀揮丄戝墌屖堏摦丄帪寁夞傝
         //  嘋 丒丒丒 PROG_MOVE_REV_LARGE_SEMIARC_CCW        曽岦斀揮丄戝墌屖堏摦丄敿帪寁夞傝
         //  嘍 丒丒丒 PROG_MOVE_ORDER_SMALL_SEMIARC_CW       弴曽岦丄  彫墌屖堏摦丄帪寁夞傝
         //  嘐 丒丒丒 PROG_MOVE_ORDER_SMALL_SEMIARC_CCW      弴曽岦丄  彫墌屖堏摦丄敿帪寁夞傝
         //  嘑 丒丒丒 PROG_MOVE_REV_SMALL_SEMIARC_CW         曽岦斀揮丄彫墌屖堏摦丄帪寁夞傝
         //  嘒 丒丒丒 PROG_MOVE_REV_SMALL_SEMIARC_CCW        曽岦斀揮丄彫墌屖堏摦丄敿帪寁夞傝

         case PROG_MOVE_ORDER_LARGE_SEMIARC_CW: {  //嘆
             if (_pProg->isJustChanged()) {
                 _pKurokoA->turnRzMvAngTo(_pKurokoA->_angRzMv - SEMIARC_ANG,
                                          LARGE_SEMIARC_ANGVELO, 0, TURN_CLOCKWISE);
             }
             if (!_pKurokoA->isTurningMvAng()) {
                 //嘆偺師偺摦嶌
                 progress next = EnemyDuna::getProgressProbability(
                                       0, PROG_MOVE_ORDER_LARGE_SEMIARC_CW,  //  嘆
                                     100, PROG_MOVE_ORDER_LARGE_SEMIARC_CCW, //  嘇
                                       0, PROG_MOVE_REV_LARGE_SEMIARC_CW,    //  嘊
                                       0, PROG_MOVE_REV_LARGE_SEMIARC_CCW,   //  嘋
                                     300, PROG_MOVE_ORDER_SMALL_SEMIARC_CW,  //  嘍
                                     300, PROG_MOVE_ORDER_SMALL_SEMIARC_CCW, //  嘐
                                     150, PROG_MOVE_REV_SMALL_SEMIARC_CW,    //  嘑
                                     150, PROG_MOVE_REV_SMALL_SEMIARC_CCW    //  嘒
                                 );
                 _pProg->change(next);
             }
             break;
         }

         case PROG_MOVE_ORDER_LARGE_SEMIARC_CCW: { //嘇
             if (_pProg->isJustChanged()) {
                 //墌屖堏摦
                 _pKurokoA->turnRzMvAngTo(_pKurokoA->_angRzMv + SEMIARC_ANG,
                                          LARGE_SEMIARC_ANGVELO, 0, TURN_COUNTERCLOCKWISE);
             }
             if (!_pKurokoA->isTurningMvAng()) {
                 //嘇偺師偺摦嶌
                 progress next = EnemyDuna::getProgressProbability(
                                     100, PROG_MOVE_ORDER_LARGE_SEMIARC_CW,  //  嘆
                                       0, PROG_MOVE_ORDER_LARGE_SEMIARC_CCW, //  嘇
                                       0, PROG_MOVE_REV_LARGE_SEMIARC_CW,    //  嘊
                                       0, PROG_MOVE_REV_LARGE_SEMIARC_CCW,   //  嘋
                                     300, PROG_MOVE_ORDER_SMALL_SEMIARC_CW,  //  嘍
                                     300, PROG_MOVE_ORDER_SMALL_SEMIARC_CCW, //  嘐
                                     150, PROG_MOVE_REV_SMALL_SEMIARC_CW,    //  嘑
                                     150, PROG_MOVE_REV_SMALL_SEMIARC_CCW    //  嘒
                                 );
                 _pProg->change(next);
             }
             break;
         }
         case PROG_MOVE_REV_LARGE_SEMIARC_CW: {  //嘊
             if (_pProg->isJustChanged()) {
                 //傑偢奐巒忬懺偺恀棤曽岦偵岦偔
                 _pKurokoA->turnRzMvAngTo(_pKurokoA->_angRzMv - D180ANG,
                                          REV_TURN_ANGVELO, 0, TURN_CLOSE_TO);
                 nprog_ = 0;
             }
             if (nprog_ == 0 && !_pKurokoA->isTurningMvAng()) {
                 //墌屖堏摦
                 _pKurokoA->turnRzMvAngTo(_pKurokoA->_angRzMv - SEMIARC_ANG,
                                          LARGE_SEMIARC_ANGVELO, 0, TURN_CLOCKWISE);
                 nprog_ = 1;
             }
             if (nprog_ == 1 && !_pKurokoA->isTurningMvAng()) {
                 //嘊偺師偺摦嶌
                 progress next = EnemyDuna::getProgressProbability(
                                       0, PROG_MOVE_ORDER_LARGE_SEMIARC_CW,  //  嘆
                                     100, PROG_MOVE_ORDER_LARGE_SEMIARC_CCW, //  嘇
                                       0, PROG_MOVE_REV_LARGE_SEMIARC_CW,    //  嘊
                                       0, PROG_MOVE_REV_LARGE_SEMIARC_CCW,   //  嘋
                                     300, PROG_MOVE_ORDER_SMALL_SEMIARC_CW,  //  嘍
                                     300, PROG_MOVE_ORDER_SMALL_SEMIARC_CCW, //  嘐
                                     150, PROG_MOVE_REV_SMALL_SEMIARC_CW,    //  嘑
                                     150, PROG_MOVE_REV_SMALL_SEMIARC_CCW    //  嘒
                                 );
                 _pProg->change(next);
             }
             break;
         }
         case PROG_MOVE_REV_LARGE_SEMIARC_CCW: {  //嘋
             if (_pProg->isJustChanged()) {
                 //傑偢奐巒忬懺偺恀棤曽岦偵岦偔
                 _pKurokoA->turnRzMvAngTo(_pKurokoA->_angRzMv + D180ANG,
                                          REV_TURN_ANGVELO, 0, TURN_CLOSE_TO);
                 nprog_ = 0;
             }
             if (nprog_ == 0 && !_pKurokoA->isTurningMvAng()) {
                 //墌屖堏摦
                 _pKurokoA->turnRzMvAngTo(_pKurokoA->_angRzMv + SEMIARC_ANG,
                                          LARGE_SEMIARC_ANGVELO, 0, TURN_COUNTERCLOCKWISE);
                 nprog_ = 1;
             }
             if (nprog_ == 1 && !_pKurokoA->isTurningMvAng()) {
                 //嘋偺師偺摦嶌
                 progress next = EnemyDuna::getProgressProbability(
                                     100, PROG_MOVE_ORDER_LARGE_SEMIARC_CW,  //  嘆
                                       0, PROG_MOVE_ORDER_LARGE_SEMIARC_CCW, //  嘇
                                       0, PROG_MOVE_REV_LARGE_SEMIARC_CW,    //  嘊
                                       0, PROG_MOVE_REV_LARGE_SEMIARC_CCW,   //  嘋
                                     300, PROG_MOVE_ORDER_SMALL_SEMIARC_CW,  //  嘍
                                     300, PROG_MOVE_ORDER_SMALL_SEMIARC_CCW, //  嘐
                                     150, PROG_MOVE_REV_SMALL_SEMIARC_CW,    //  嘑
                                     150, PROG_MOVE_REV_SMALL_SEMIARC_CCW    //  嘒
                                 );
                 _pProg->change(next);
             }
             break;
         }





         case PROG_MOVE_ORDER_SMALL_SEMIARC_CW: {  //嘍
             if (_pProg->isJustChanged()) {
                 _pKurokoA->turnRzMvAngTo(_pKurokoA->_angRzMv - SEMIARC_ANG,
                                          SMALL_SEMIARC_ANGVELO, 0, TURN_CLOCKWISE);
             }
             if (!_pKurokoA->isTurningMvAng()) {
                 //嘍偺師偺摦嶌
                 progress next = EnemyDuna::getProgressProbability(
                                       0, PROG_MOVE_ORDER_LARGE_SEMIARC_CW,  //  嘆
                                     400, PROG_MOVE_ORDER_LARGE_SEMIARC_CCW, //  嘇
                                       0, PROG_MOVE_REV_LARGE_SEMIARC_CW,    //  嘊
                                     300, PROG_MOVE_REV_LARGE_SEMIARC_CCW,   //  嘋
                                       0, PROG_MOVE_ORDER_SMALL_SEMIARC_CW,  //  嘍
                                     300, PROG_MOVE_ORDER_SMALL_SEMIARC_CCW, //  嘐
                                       0, PROG_MOVE_REV_SMALL_SEMIARC_CW,    //  嘑
                                       0, PROG_MOVE_REV_SMALL_SEMIARC_CCW    //  嘒
                                 );
                 _pProg->change(next);
             }
             break;
         }

         case PROG_MOVE_ORDER_SMALL_SEMIARC_CCW: { //嘐
             if (_pProg->isJustChanged()) {
                 //墌屖堏摦
                 _pKurokoA->turnRzMvAngTo(_pKurokoA->_angRzMv + SEMIARC_ANG,
                                          SMALL_SEMIARC_ANGVELO, 0, TURN_COUNTERCLOCKWISE);
             }
             if (!_pKurokoA->isTurningMvAng()) {
                 //嘐偺師偺摦嶌
                 progress next = EnemyDuna::getProgressProbability(
                                     400, PROG_MOVE_ORDER_LARGE_SEMIARC_CW,  //  嘆
                                       0, PROG_MOVE_ORDER_LARGE_SEMIARC_CCW, //  嘇
                                     300, PROG_MOVE_REV_LARGE_SEMIARC_CW,    //  嘊
                                       0, PROG_MOVE_REV_LARGE_SEMIARC_CCW,   //  嘋
                                     300, PROG_MOVE_ORDER_SMALL_SEMIARC_CW,  //  嘍
                                       0, PROG_MOVE_ORDER_SMALL_SEMIARC_CCW, //  嘐
                                       0, PROG_MOVE_REV_SMALL_SEMIARC_CW,    //  嘑
                                       0, PROG_MOVE_REV_SMALL_SEMIARC_CCW    //  嘒
                                 );
                 _pProg->change(next);
             }
             break;
         }
         case PROG_MOVE_REV_SMALL_SEMIARC_CW: {  //嘑
             if (_pProg->isJustChanged()) {
                 //傑偢奐巒忬懺偺恀棤曽岦偵岦偔
                 _pKurokoA->turnRzMvAngTo(_pKurokoA->_angRzMv - D180ANG,
                                          REV_TURN_ANGVELO, 0, TURN_CLOSE_TO);
                 nprog_ = 0;
             }
             if (nprog_ == 0 && !_pKurokoA->isTurningMvAng()) {
                 //墌屖堏摦
                 _pKurokoA->turnRzMvAngTo(_pKurokoA->_angRzMv - SEMIARC_ANG,
                                          SMALL_SEMIARC_ANGVELO, 0, TURN_CLOCKWISE);
                 nprog_ = 1;
             }
             if (nprog_ == 1 && !_pKurokoA->isTurningMvAng()) {
                 //嘑偺師偺摦嶌
                 progress next = EnemyDuna::getProgressProbability(
                                       0, PROG_MOVE_ORDER_LARGE_SEMIARC_CW,  //  嘆
                                     400, PROG_MOVE_ORDER_LARGE_SEMIARC_CCW, //  嘇
                                       0, PROG_MOVE_REV_LARGE_SEMIARC_CW,    //  嘊
                                     300, PROG_MOVE_REV_LARGE_SEMIARC_CCW,   //  嘋
                                       0, PROG_MOVE_ORDER_SMALL_SEMIARC_CW,  //  嘍
                                     300, PROG_MOVE_ORDER_SMALL_SEMIARC_CCW, //  嘐
                                       0, PROG_MOVE_REV_SMALL_SEMIARC_CW,    //  嘑
                                       0, PROG_MOVE_REV_SMALL_SEMIARC_CCW    //  嘒
                                 );
                 _pProg->change(next);
             }
             break;
         }
         case PROG_MOVE_REV_SMALL_SEMIARC_CCW: {  //嘒
             if (_pProg->isJustChanged()) {
                 //傑偢奐巒忬懺偺恀棤曽岦偵岦偔
                 _pKurokoA->turnRzMvAngTo(_pKurokoA->_angRzMv + D180ANG,
                                          REV_TURN_ANGVELO, 0, TURN_CLOSE_TO);
                 nprog_ = 0;
             }
             if (nprog_ == 0 && !_pKurokoA->isTurningMvAng()) {
                 //墌屖堏摦
                 _pKurokoA->turnRzMvAngTo(_pKurokoA->_angRzMv + SEMIARC_ANG,
                                          SMALL_SEMIARC_ANGVELO, 0, TURN_COUNTERCLOCKWISE);
                 nprog_ = 1;
             }
             if (nprog_ == 1 && !_pKurokoA->isTurningMvAng()) {
                 //嘒偺師偺摦嶌
                 progress next = EnemyDuna::getProgressProbability(
                                     400, PROG_MOVE_ORDER_LARGE_SEMIARC_CW,  //  嘆
                                       0, PROG_MOVE_ORDER_LARGE_SEMIARC_CCW, //  嘇
                                     300, PROG_MOVE_REV_LARGE_SEMIARC_CW,    //  嘊
                                       0, PROG_MOVE_REV_LARGE_SEMIARC_CCW,   //  嘋
                                     300, PROG_MOVE_ORDER_SMALL_SEMIARC_CW,  //  嘍
                                       0, PROG_MOVE_ORDER_SMALL_SEMIARC_CCW, //  嘐
                                       0, PROG_MOVE_REV_SMALL_SEMIARC_CW,    //  嘑
                                       0, PROG_MOVE_REV_SMALL_SEMIARC_CCW    //  嘒
                                 );
                 _pProg->change(next);
             }
             break;
         }
         default:
             break;
     }

    _pKurokoA->behave();
    _pKurokoB->behave();
    _pMorpher->behave();
    _pAFader->behave();
//_TRACE_("EnemyDuna f:"<<getBehaveingFrame()<<"  pProg="<<_pProg->get()<<"   X,Y,Z="<<_X<<","<<_Y<<","<<_Z<<" ");
}

void EnemyDuna::processJudgement() {
    if (isOutOfUniverse()) {
        sayonara();
    }
}

void EnemyDuna::onHit(GgafActor* prm_pOtherActor) {
    bool was_destroyed = UTIL::proceedEnemyHit(this, (GgafDxGeometricActor*)prm_pOtherActor);
    if (was_destroyed) {
        //攋夡帪
        _pSeTx->play3D(SE_EXPLOSION);
    } else {
        //旕攋夡帪
    }
}

void EnemyDuna::onInactive() {
}

void EnemyDuna::onDispatchedShot(GgafDxCore::GgafDxDrawableActor* prm_pActor, int prm_dispatch_num, int prm_set_index, int prm_way_index) {
    prm_pActor->activateDelay(prm_way_index*5 + 1); //activate 忋彂偒丅num_fire_*5 偺 5 偲摨偠抣偵偡傞偙偲
}

progress EnemyDuna::getProgressProbability(int p1, progress prog1,
                                           int p2, progress prog2,
                                           int p3, progress prog3,
                                           int p4, progress prog4,
                                           int p5, progress prog5,
                                           int p6, progress prog6,
                                           int p7, progress prog7,
                                           int p8, progress prog8) {
    int r = RND(1,1000);
    if (r <= p1) {
        return prog1;
    } else if ( p1 < r && r <= (p1+p2) ) {
        return prog2;
    } else if ( (p1+p2) < r && r <= (p1+p2+p3) ) {
        return prog3;
    } else if ( (p1+p2+p3) < r && r <= (p1+p2+p3+p4) ) {
        return prog4;
    } else if ( (p1+p2+p3+p4) < r && r <= (p1+p2+p3+p4+p5) ) {
        return prog5;
    } else if ( (p1+p2+p3+p4+p5) < r && r <= (p1+p2+p3+p4+p5+p6) ) {
        return prog6;
    } else if ( (p1+p2+p3+p4+p5+p6) < r && r <= (p1+p2+p3+p4+p5+p6+p7) ) {
        return prog7;
    } else if ( (p1+p2+p3+p4+p5+p6+p7) < r && r <= (p1+p2+p3+p4+p5+p6+p7+p8) ) {
        return prog8;
    } else {
        throwGgafCriticalException("getProgressProbability r="<<r<<"偱楻傟傑偟偨丅堷悢偺妋棪偺崌寁傪 100 偵偟偰壓偝偄丅");
    }
}

EnemyDuna::~EnemyDuna() {
}
