void Player::debugDash() { if (status != CharaStatus::NORMAL) return; isAttacking(); }
BOOL CActorInstance::CanCheckAttacking() { if (isAttacking()) return true; return false; }
// 进攻方对方禁区拿球,强制触发一次空中遭遇。 void CFBMatch::checkEncounterInPenaltyArea() { // TODO: 仅当传球,二过一,随机球 刚刚结束,否则直接返回。二过一和随机球还未做判断 if (m_recentEndedFlow != FBDefs::MATCH_FLOW_TYPE::PASSBALL) return; if (m_menuType != FBDefs::MENU_TYPE::NONE) return; auto team = this->getAttackingTeam(); auto side = team->getSide(); auto ballPos = getBallPosition(); if (m_pitch->isInPenaltyArea(ballPos, m_pitch->getOtherSide(side))) { m_encounterTime = -1; m_isAir = true; auto conTeam = getControlSideTeam(); if (conTeam->isAttacking()) { m_menuType = FBDefs::MENU_TYPE::ENCOUNTER_ATK_OPPSITE_A; m_involvePlayerIds.clear(); m_involvePlayerIds.push_back(conTeam->getHilightPlayerId()); } else { m_menuType = FBDefs::MENU_TYPE::ENCOUNTER_DEF_SELF_A; m_involvePlayerIds.clear(); for (auto p : m_defendPlayerIds) { m_involvePlayerIds.push_back(p); } } } }
void Game::follow(const CreaturePtr& creature) { if(!canPerformGameAction() || creature == m_localPlayer || creature == m_followingCreature) return; if(creature && isAttacking()) cancelAttack(); setFollowingCreature(creature); m_protocolGame->sendFollow(creature ? creature->getId() : 0, ++m_seq); }
void CTestClient::run(float dt) { if (m_state == STATE::Running) { switch (m_caseState) { case CASE_STATE::Start: syncCase(); if (isAttacking() && m_testCase->active) { CJsonT msg; msg.setChild("cmd", (unsigned int)m_testCase->m_atk[0]->instruction); if (isAttacking() && m_testCase->m_atk.size() > 1) { msg.setChild("targetPlayerId", (unsigned int)m_testCase->m_atk[1]->playerNumber); } m_pomelo->request("match.matchHandler.menuCmd", msg, [this](Node* node, void* resp){ CCPomeloReponse* ccpomeloresp = (CCPomeloReponse*)resp; CJsonT docs(ccpomeloresp->docs); }); msg.release(); } m_caseState = CASE_STATE::WaitEncounter; break; case CASE_STATE::WaitEncounter: break; case CASE_STATE::Encounter: break; case CASE_STATE::None: m_syncTime -= dt; if (m_syncTime <= 0) { syncNormal(); m_syncTime = 1.f; } break; } } }
void Game::cancelAttackAndFollow() { if(!canPerformGameAction()) return; if(isAttacking()) setAttackingCreature(nullptr); if(isFollowing()) setFollowingCreature(nullptr); m_protocolGame->sendCancelAttackAndFollow(); }
void CTestClient::onResumeMatch(Node* node, void* resp) { if (isAttacking()) { MT->printA("resume match"); } else { MT->printD("resume match"); } log("case done"); m_caseState = CASE_STATE::None; }
void CTestClient::onInstructionResult(Node* node, void* resp) { if (isAttacking()) { MT->printA("movie end"); } else { MT->printD("movie end"); } CJsonT msg; m_pomelo->notify("match.matchHandler.instructionMovieEnd", msg, [](Node* node, void* resp){}); msg.release(); }
void Game::cancelAttackAndFollow() { if(!canPerformGameAction()) return; if(isFollowing()) setFollowingCreature(nullptr); if(isAttacking()) setAttackingCreature(nullptr); m_localPlayer->stopAutoWalk(); m_protocolGame->sendCancelAttackAndFollow(); g_lua.callGlobalField("g_game", "onCancelAttackAndFollow"); }
bool Squad::hasGoal() { int elapsed = Broodwar->getFrameCount() - goalSetFrame; if (elapsed >= 600) { if (!isAttacking()) { goal = TilePosition(-1, -1); } } if (goal.x() < 0 || goal.y() < 0) { return false; } return true; }
static void grab(int val) { Entity *e; if (self->thinkTime <= 0 && game.status == IN_GAME && (player.flags & ON_GROUND) && isAttacking() == FALSE && player.element != WATER) { setCustomAction(&player, &helpless, 2, 0, 0); playerStand(); player.dirX = 0; e = getFreeEntity(); if (e == NULL) { showErrorAndExit("No free slots to add an Extend-O-Grab"); } loadProperties(self->name, e); setEntityAnimation(e, "WALK"); e->flags |= FLY; e->x = player.x + player.w / 2; e->y = player.y + player.h / 2 - e->h / 2; e->dirX = player.face == LEFT ? -self->speed : self->speed; e->startX = e->x; e->face = player.face; e->action = &extend; e->touch = &touch; e->draw = &draw; e->health = 1; self->thinkTime = self->maxThinkTime; } }
void CActorInstance::__MotionEventProcess(BOOL isPC) { if (isAttacking()) { DWORD dwNextFrame = DWORD(GetAttackingElapsedTime() * g_fGameFPS); for (; m_kCurMotNode.dwcurFrame < dwNextFrame; ++m_kCurMotNode.dwcurFrame) { MotionEventProcess(); SoundEventProcess(!isPC); } } else { MotionEventProcess(); SoundEventProcess(!isPC); ++m_kCurMotNode.dwcurFrame; } }
void CFBMatch::syncTeam() { auto team = m_teamsInMatch[(int)SIDE::SELF]; vector<float> v; int num = team->getPlayerNumber(); for (int i = 0; i < num; ++i) { auto player = team->getPlayer(i); auto& pos = player->getPosition(); v.push_back(pos.x); v.push_back(pos.y); auto& vec = player->getMovingVector(); v.push_back(vec.x); v.push_back(vec.y); } m_proxy->sendTeamPosition(v, team->isAttacking() ? team->getHilightPlayerId() : -1, (unsigned int)team->getSide()); }
void CFBMatch::checkEncounterInDribble() { if (m_menuType != FBDefs::MENU_TYPE::NONE) return; auto size = m_defendPlayerIds.size(); if (size > 0) { if (size >= 4) { m_encounterTime = -1; } else if (m_encounterTime > FBDefs::PLAYER_ENCOUNTER_TRIGGER_TIME) { m_encounterTime = FBDefs::PLAYER_ENCOUNTER_TRIGGER_TIME; } auto team = getControlSideTeam(); if (team->isAttacking()) { m_menuType = FBDefs::MENU_TYPE::ENCOUNTER_ATK_G; m_involvePlayerIds.clear(); m_involvePlayerIds.push_back(team->getHilightPlayerId()); } else { m_menuType = FBDefs::MENU_TYPE::ENCOUTNER_DEF_G; m_involvePlayerIds.clear(); for (auto p : m_defendPlayerIds) { m_involvePlayerIds.push_back(p); } } m_isAir = false; } else { m_encounterTime = FLT_MAX; m_menuType = FBDefs::MENU_TYPE::NONE; } }
void CTestClient::startCase(CTestCase* tc) { CCLOG("start case"); m_testCase = tc; if (isAttacking()) { CJsonT msg; msg.setChild("side", (int)m_side); msg.setChild("playerNumber", tc->ballPos); m_pomelo->notify("match.matchHandler.setBall", msg, [&](Node* node, void* resp){ m_caseState = CASE_STATE::Start; }); msg.release(); } else { m_caseState = CASE_STATE::Start; } }
void Squad::setGoal(TilePosition mGoal) { if (isAttacking()) { if (goal.x() != -1) { return; } } if (mGoal.x() != goal.x() || mGoal.y() != goal.y()) { goalSetFrame = Broodwar->getFrameCount(); if (isGround()) { int d = (int)goal.getDistance(mGoal); if (d >= 10) { if ((int)agents.size() > 0) { Pathfinder::Instance().requestPath(getCenter(), mGoal); if (!Pathfinder::Instance().isReady(getCenter(), mGoal)) { return; } path = Pathfinder::Instance().getPath(getCenter(), mGoal); arrivedFrame = -1; pathIndex = 10; if (path.size() == 0) return; } } } this->goal = mGoal; setMemberGoals(goal); } }
void Game::follow(CreaturePtr creature) { if(!canPerformGameAction() || creature == m_localPlayer) return; // cancel when following again if(creature && creature == m_followingCreature) creature = nullptr; if(creature && isAttacking()) cancelAttack(); setFollowingCreature(creature); m_localPlayer->stopAutoWalk(); if(m_protocolVersion >= 963) { if(creature) m_seq = creature->getId(); } else m_seq++; m_protocolGame->sendFollow(creature ? creature->getId() : 0, m_seq); }
void Player::handPosZDistance() { float distance_z = LEAPHANDS.GetHandCenterPos().z - before_hand_pos.z; // 手のz軸に対しての移動量が満たなかった場合はじく if (distance_z < dash_range) return; ci::Vec3f hand_distance = before_hand_pos - LEAPHANDS.GetHandCenterPos(); float distance = std::sqrtf((hand_distance.x * hand_distance.x) + (hand_distance.y * hand_distance.y) + (hand_distance.z * hand_distance.z)); if (distance < dash_range * 2.0f) return; if (!isAttacking()) return; ci::Vec2f dash_move = before_hand_pos.xy() - LEAPHANDS.GetHandCenterPos().xy(); (dash_move).normalize(); moving(transform.position.xy() + dash_move * 10000.0f); }
void CTestClient::onTriggerMenu(Node* node, void* resp) { MT->print("case encounter"); m_caseState = CASE_STATE::Encounter; CCPomeloReponse* ccpomeloresp = (CCPomeloReponse*)resp; CJsonT docs(ccpomeloresp->docs); int type = docs.getInt("menuType"); if (type == (int)FBDefs::MENU_TYPE::NONE) { return; } CC_ASSERT(type >= 0 && type < (unsigned int)FBDefs::MENU_TYPE::NONE); json_t* players = nullptr; decltype(m_testCase->m_atk)* tpInfo = nullptr; if (isAttacking()) { players = docs.getChild("attackPlayers"); tpInfo = &(m_testCase->m_atk); CCLOG("attack"); } else { players = docs.getChild("defendplayers"); tpInfo = &(m_testCase->m_def); CCLOG("def"); } CJsonTArray ja(players); for (int i = 0; i < ja.size(); ++i) { auto playerId = ja.get(i).toInt(); MT->print("playerId: %d", playerId); for (auto info : *tpInfo) { if (info->playerNumber == playerId) { // 发送命令 CJsonT msg; if (isAttacking()) { MT->printA("%s", CTestPlayerInfo::ins_str[(int)info->instruction].c_str()); } log("ins: %d", (unsigned int)info->instruction); msg.setChild("cmd", (unsigned int)info->instruction); if (isAttacking() && (*tpInfo).size() > 1) { msg.setChild("targetPlayerId", (unsigned int)(*tpInfo)[1]->playerNumber); } m_pomelo->request("match.matchHandler.menuCmd", msg, [this](Node* node, void* resp){ CCPomeloReponse* ccpomeloresp = (CCPomeloReponse*)resp; CJsonT docs(ccpomeloresp->docs); }); msg.release(); break; } } } }
void CTestClient::syncCase() { CJsonT msg; CJsonTArray ja; typedef decltype(m_testCase->m_atk) DC; DC* pV; if (isAttacking()) { pV = &m_testCase->m_atk; MT->printA("attack side sync: "); } else { pV = &m_testCase->m_def; MT->printD("defend side sync: "); } for (int i = 0; i < 11; ++i) { DC::value_type tpi = nullptr; for (auto it = pV->begin(); it != pV->end(); ++it) { if ((*it)->playerNumber == i) { tpi = (*it); break; } } switch (m_side) { case FBDefs::SIDE::LEFT: if (tpi) { ja.append(tpi->position.x); ja.append(tpi->position.y); if (isAttacking()) { MT->printA("x: %f, y: %f", tpi->position.x, tpi->position.y); } else { MT->printD("x: %f, y: %f", tpi->position.x, tpi->position.y); } } else { ja.append(CJsonT((float)0)); ja.append(CJsonT((float)0)); } ja.append(CJsonT((float)0)); ja.append(CJsonT((float)0)); break; case FBDefs::SIDE::RIGHT: if (tpi) { ja.append(CJsonT(tpi->position.x)); ja.append(CJsonT(tpi->position.y)); if (m_ballPos != -1) { MT->printA("x: %f, y: %f", tpi->position.x, tpi->position.y); } else { MT->printD("x: %f, y: %f", tpi->position.x, tpi->position.y); } } else { ja.append(CJsonT((float)FBDefs::PITCH_WIDTH-1)); ja.append(CJsonT(0)); } ja.append(CJsonT((float)0)); ja.append(CJsonT((float)0)); break; default: break; } } msg.setChild("teamPos", ja); msg.setChild("side", (int)m_side); msg.setChild("ballPosPlayerId", m_ballPos); msg.setChild("timeStamp", 0); m_pomelo->notify("match.matchHandler.sync", msg, [](Node*, void*){}); msg.release(); }
void Game::processAttackCancel(uint seq) { if(isAttacking() && (seq == 0 || m_seq == seq)) setAttackingCreature(nullptr); }
void Bait::DetermineTactic() { //std::cout << std::abs(m_state->m_memory->player_one_x - m_state->m_memory->player_two_x) << std::endl; //Determine how many frames of lag our opponent has during the LANDING_SPECIAL action // Unfortunately, the game reuses LANDING_SPECIAL for both landing from an UP-B and from a wavedash // So it's non-trivial to figure out which it is. if(m_state->m_memory->player_one_action == LANDING_SPECIAL) { if(m_lastAction == DEAD_FALL || m_lastAction == UP_B) { m_state->setLandingState(true); } if(m_lastAction == AIRDODGE) { m_state->setLandingState(false); } } //Update the attack frame if the enemy started a new action if((m_lastAction != (ACTION)m_state->m_memory->player_one_action) || (m_state->m_memory->player_one_action_counter > m_lastActionCount) || (m_state->m_memory->player_one_action_frame == 1)) { m_lastActionCount = m_state->m_memory->player_one_action_counter; m_shieldedAttack = false; m_actionChanged = true; m_lastAction = (ACTION)m_state->m_memory->player_one_action; if(isAttacking((ACTION)m_state->m_memory->player_one_action)) { m_attackFrame = m_state->m_memory->frame; } } //Continuing same previous action else { m_actionChanged = false; if(m_state->m_memory->player_two_action == SHIELD_STUN || m_state->m_memory->player_two_action == SPOTDODGE || m_state->m_memory->player_two_action == EDGE_GETUP_QUICK || m_state->m_memory->player_two_action == EDGE_GETUP_SLOW) { m_shieldedAttack = true; } } if(!isAttacking((ACTION)m_state->m_memory->player_one_action)) { m_attackFrame = 0; } //If we're not in a state to interupt, just continue with what we've got going if((m_tactic != NULL) && (!m_tactic->IsInterruptible())) { m_tactic->DetermineChain(); return; } //If we're still warping in at the start of the match, then just hang out and do nothing if(m_state->m_memory->player_two_action == ENTRY || m_state->m_memory->player_two_action == ENTRY_START || m_state->m_memory->player_two_action == ENTRY_END) { CreateTactic(Wait); m_tactic->DetermineChain(); return; } //Calculate distance between players double distance = pow(m_state->m_memory->player_one_x - m_state->m_memory->player_two_x, 2); distance += pow(m_state->m_memory->player_one_y - m_state->m_memory->player_two_y, 2); distance = sqrt(distance); //If we're able to upsmash our opponent, let's do that bool player_two_is_to_the_left = (m_state->m_memory->player_two_x - m_state->m_memory->player_one_x > 0); if((m_state->m_memory->player_one_action == SPOTDODGE || m_state->m_memory->player_one_action == MARTH_COUNTER || m_state->m_memory->player_one_action == MARTH_COUNTER_FALLING || m_state->m_memory->player_one_action == LANDING_SPECIAL) && distance < FOX_UPSMASH_RANGE-2 && m_state->m_memory->player_two_facing != player_two_is_to_the_left) { CreateTactic(Punish); m_tactic->DetermineChain(); return; } //If our opponent is stuck in the windup for an attack, let's hit them with something harder than shine if(isAttacking((ACTION)m_state->m_memory->player_one_action) && distance < FOX_UPSMASH_RANGE-2 && m_state->m_memory->player_two_facing != player_two_is_to_the_left) { //How many frames do we have until the attack lands? If it's at least 3, then we can start a Punish int frames_left = m_state->firstHitboxFrame((CHARACTER)m_state->m_memory->player_one_character, (ACTION)m_state->m_memory->player_one_action) - m_state->m_memory->player_one_action_frame - 1; if(frames_left > 3) { CreateTactic(Punish); m_tactic->DetermineChain(); return; } } //If our opponent is rolling, punish it on the other end if(m_state->m_memory->player_one_action == ROLL_FORWARD || m_state->m_memory->player_one_action == ROLL_BACKWARD || m_state->m_memory->player_one_action == EDGE_ROLL_SLOW || m_state->m_memory->player_one_action == EDGE_ROLL_QUICK || m_state->m_memory->player_one_action == EDGE_GETUP_QUICK || m_state->m_memory->player_one_action == EDGE_GETUP_SLOW || m_state->m_memory->player_two_action == LANDING_SPECIAL) { CreateTactic(Punish); m_tactic->DetermineChain(); return; } //If we're hanging on the egde, and they are falling above the stage, punish it if(m_state->m_memory->player_one_action == DEAD_FALL && m_state->m_memory->player_two_action == EDGE_HANGING && std::abs(m_state->m_memory->player_one_x) < m_state->getStageEdgeGroundPosition() + .001) { CreateTactic(Punish); m_tactic->DetermineChain(); return; } //How many frames do we have until the attack is over? int frames_left = m_state->totalActionFrames((CHARACTER)m_state->m_memory->player_one_character, (ACTION)m_state->m_memory->player_one_action) - m_state->m_memory->player_one_action_frame - 1; //If our oponnent is stuck in a laggy ending animation, punish it if(isAttacking((ACTION)m_state->m_memory->player_one_action) && m_state->m_memory->player_one_action_frame > m_state->lastHitboxFrame((CHARACTER)m_state->m_memory->player_one_character, (ACTION)m_state->m_memory->player_one_action)) { if(frames_left > 3) { //Unless we need to wavedash in, then give us more time if(m_state->m_memory->player_two_action != SHIELD_RELEASE || frames_left > 10) { CreateTactic(Punish); m_tactic->DetermineChain(); return; } } } //If we're able to shine p1 right now, let's do that if(std::abs(distance) < FOX_SHINE_RADIUS) { //Are we in a state where we can shine? if(ReadyForAction(m_state->m_memory->player_two_action)) { //Is the opponent in a state where they can get hit by shine? if(m_state->m_memory->player_one_action != SHIELD && m_state->m_memory->player_one_action != SHIELD_REFLECT && m_state->m_memory->player_one_action != MARTH_COUNTER && m_state->m_memory->player_one_action != MARTH_COUNTER_FALLING && m_state->m_memory->player_one_action != EDGE_CATCHING && m_state->m_memory->player_one_action != SPOTDODGE) { CreateTactic(ShineCombo); m_tactic->DetermineChain(); return; } } } //If we need to defend against an attack, that's next priority. Unless we've already shielded this attack if(!m_shieldedAttack && distance < MARTH_FSMASH_RANGE) { //Don't bother parrying if the attack is in the wrong direction bool player_one_is_to_the_left = (m_state->m_memory->player_one_x - m_state->m_memory->player_two_x > 0); if(m_state->m_memory->player_one_facing != player_one_is_to_the_left || (isReverseHit((ACTION)m_state->m_memory->player_one_action))) { if(isAttacking((ACTION)m_state->m_memory->player_one_action)) { //If the p1 action changed, scrap the old Parry and make a new one. if(m_actionChanged) { delete m_tactic; m_tactic = NULL; } CreateTactic2(Parry, m_attackFrame); m_tactic->DetermineChain(); return; } } } //If we're far away, just laser if(std::abs(m_state->m_memory->player_one_x - m_state->m_memory->player_two_x) > 90 && std::abs(m_state->m_memory->player_one_x) < 130) { CreateTactic(Laser); m_tactic->DetermineChain(); return; } //If the opponent is off the stage, let's edgeguard them //NOTE: Sometimes players can get a little below 0 in Y coordinates without being off the stage if(std::abs(m_state->m_memory->player_one_x) > m_state->getStageEdgeGroundPosition() + .001 || m_state->m_memory->player_one_y < -5.5 || m_state->m_memory->player_one_action == EDGE_CATCHING || m_state->m_memory->player_one_action == EDGE_HANGING) { CreateTactic(Edgeguard); m_tactic->DetermineChain(); return; } //If we're not in shine range, get in close if(std::abs(m_state->m_memory->player_one_x - m_state->m_memory->player_two_x) > FOX_SHINE_RADIUS) { CreateTactic(CloseDistance); m_tactic->DetermineChain(); return; } //If we're in close and p2 is sheilding, just wait if(m_state->m_memory->player_one_action == ACTION::SHIELD) { CreateTactic(Wait); m_tactic->DetermineChain(); return; } //TODO: For now, just default to waiting if nothing else fits CreateTactic(Wait); m_tactic->DetermineChain(); return; }
//--------------------------------------------------------------------------- // ● フレーム更新処理 (オブジェクトに影響を与える処理) //--------------------------------------------------------------------------- bool Valfirle::UpdateSelf() { //死んだ際に持っている武器を落とす if(this->mLife <= 0 && !this->m_bCreateWeapon) { this->m_bCreateWeapon = true; } bool right = false; bool left = false; bool button_A = false; bool button_B = false; bool Up = false; bool UpTrigger = false; bool Down = false; bool DownTrigger = false; bool Guard = false; bool GuardTrigger = false; Player *pPlayer = GameManager::getInstance()->getPlayer(); //AI switch(this->m_eAction) { //未定義 case ENEMY_ACT_UNDEF: this->m_eAction = ENEMY_ACT_WAIT; break; //待機 case ENEMY_ACT_WAIT: //フェーズの移行をチェックする this->ChangePhase(); //範囲内探索を行う if(this->SearchPlayer()) { //範囲内であれば追跡を開始する this->m_eAction = ENEMY_ACT_CHASE; break; } //散歩を開始する if(this->m_nWalkIntvCnt > this->scm_nWalkIntv) { this->m_nWalkRangeCnt = ::rand() % this->scm_nWalkRange; //散歩距離の設定 this->m_nWalkIntvCnt = 0; this->m_bWalkDir = static_cast<bool>(::rand() % 2); this->m_eAction = ENEMY_ACT_WALK; } else { ++this->m_nWalkIntvCnt; } break; //散歩 case ENEMY_ACT_WALK: //散歩を行っている if(this->m_nWalkRangeCnt) { if(this->m_bWalkDir) right = true; else left = true; --this->m_nWalkRangeCnt; } //散歩終わり else { this->m_eAction = ENEMY_ACT_WAIT; } break; //追跡 case ENEMY_ACT_CHASE: //フェーズの移行をチェックする this->ChangePhase(); //プレイヤーが探索範囲内である if(this->SearchPlayer()) { //Playerは右にいる if(this->mPosition.x - pPlayer->getPosition().x < 0) { right = true; } //Playerは左にいる else { left = true; } //まれにジャンプする if(!(::rand() % scg_nValfirleJumpRatio[GameManager::getInstance()->getRank()])) { button_B = true; } //プレイヤーが観察範囲内である if(::abs(this->mPosition.x + ::rand() % this->scm_nSearchRand - pPlayer->getPosition().x) <= this->scm_nStandbyRange) { //ランダムで観察を開始する if(!(::rand() % scg_nValfirleStandbyRatio[GameManager::getInstance()->getRank()])) { this->m_nStandbyCnt = ::rand() % this->scm_nStandbyIntv; this->m_eAction = ENEMY_ACT_STANDBY; break; } } //プレイヤーが攻撃範囲内である if(this->SearchAttack1Range()) { this->m_eAction = ENEMY_ACT_ATTACK_RANGE; break; } } else { //探索範囲外であれば待機に戻す this->m_eAction = ENEMY_ACT_WAIT; } break; //観察 case ENEMY_ACT_STANDBY: //プレイヤーがジャンプした瞬間対空攻撃を行う if(pPlayer->getCharaState() == CHARASTATE_JUMP) { //this->m_nStandbyCnt = 0; break; } //観察を行う if(this->m_nStandbyCnt) { --this->m_nStandbyCnt; } else { this->m_eAction = ENEMY_ACT_WAIT; } break; //逃走 case ENEMY_ACT_ESCAPE: if(this->m_nEscapeRangeCnt) { //Playerは右にいる if(this->mPosition.x - pPlayer->getPosition().x < 0) { left = true; } //Playerは左にいる else { right = true; } --this->m_nEscapeRangeCnt; } else { this->m_eAction = ENEMY_ACT_WAIT; } break; //攻撃範囲内 case ENEMY_ACT_ATTACK_RANGE: if(this->SearchAttack1Range()) { //ランダムで攻撃を開始する if(!(::rand() % scg_nValfirleAttackRatio[GameManager::getInstance()->getRank()])) { this->m_eAction = ENEMY_ACT_ATTACK; break; } //ランダムで防御を開始する if(!(::rand() % scg_nValfirleGuardRatio[GameManager::getInstance()->getRank()])) { this->m_nGuardCnt = ::rand() % this->scm_nGuardIntv; this->m_eAction = ENEMY_ACT_GUARD; break; } //ランダムで観察を開始する if(!(::rand() % scg_nValfirleStandbyRatio[GameManager::getInstance()->getRank()])) { this->m_nStandbyCnt = ::rand() % this->scm_nStandbyIntv; this->m_eAction = ENEMY_ACT_STANDBY; break; } //ランダムでしゃがみガードを開始する if(!(::rand() % scg_nValfirleSquatGuardRatio[GameManager::getInstance()->getRank()])) { this->m_nGuardCnt = ::rand() % this->scm_nGuardIntv; this->m_eAction = ENEMY_ACT_SQUAT_GUARD; break; } //ランダムでしゃがみを開始する if(!(::rand() % scg_nValfirleSquatRatio[GameManager::getInstance()->getRank()])) { this->m_nSquatCnt = ::rand() % this->scm_nStandbyIntv; this->m_eAction = ENEMY_ACT_SQUAT; break; } //ランダムで逃走を開始する if(!(::rand() % scg_nValfirleEscapeRatio[GameManager::getInstance()->getRank()])) { this->m_nEscapeRangeCnt = ::rand() % this->scm_nEscapeRange; this->m_eAction = ENEMY_ACT_ESCAPE; break; } } //攻撃範囲外 else { this->m_eAction = ENEMY_ACT_CHASE; } break; //攻撃中 case ENEMY_ACT_ATTACK: if(this->SearchAttack1Range()) { switch(this->m_eCharaState) { case CHARASTATE_ATTACK_SQUAT_ATTACK: case CHARASTATE_ATTACK_JUMP_ATTACK: case CHARASTATE_ATTACK_ANTIAIR_ATTACK: case CHARASTATE_ATTACK_DUSH_ATTACK: //特殊攻撃後は待機に戻す this->m_eAction = ENEMY_ACT_WAIT; break; case CHARASTATE_ATTACK_1: //通常攻撃2段目 if(scg_bValfirleAttack2Permission[GameManager::getInstance()->getRank()] && (::rand() % scg_nValfirleAttack2Ratio[GameManager::getInstance()->getRank()])) button_A = true; else this->m_eAction = ENEMY_ACT_WAIT; break; case CHARASTATE_ATTACK_2: //通常攻撃3段目 if(scg_bValfirleAttack3Permission[GameManager::getInstance()->getRank()] && (::rand() % scg_nValfirleAttack3Ratio[GameManager::getInstance()->getRank()])) button_A = true; else this->m_eAction = ENEMY_ACT_WAIT; break; default: //ジャンプ攻撃は事前にジャンプする if(!(::rand() % scg_nValfirleJumpAttackRatio[GameManager::getInstance()->getRank()])) { button_B = true; break; } //しゃがみ攻撃 if(!(::rand() % scg_nValfirleSquatAttackRatio[GameManager::getInstance()->getRank()])) { Down = true; } //通常攻撃1段目 button_A = true; break; } //Player座標が上であれば、対空攻撃をする if(this->mPosition.y < pPlayer->getPosition().y) { Up = true; } } else { this->m_eAction = ENEMY_ACT_CHASE; } break; //防御 case ENEMY_ACT_GUARD: if(this->m_nGuardCnt) { Guard = true; --this->m_nGuardCnt; } else { this->m_eAction = ENEMY_ACT_WAIT; } break; //しゃがみガード case ENEMY_ACT_SQUAT_GUARD: if(this->m_nGuardCnt) { GuardTrigger = true; Guard = true; Down = true; --this->m_nGuardCnt; } else { this->m_eAction = ENEMY_ACT_WAIT; } break; //しゃがみ case ENEMY_ACT_SQUAT: if(this->m_nSquatCnt) { Down = true; --this->m_nSquatCnt; } else { this->m_eAction = ENEMY_ACT_WAIT; } break; default: this->m_eAction = ENEMY_ACT_WAIT; break; } //AI end // 死亡 (死亡モーション中) は入力を受け付けない if ( isDead() ) { return true; } // 移動できる場合 (のけぞり中等ではない) if ( mStunFrame == 0 ) { //------------------------------------------------------ // 攻撃動作中の場合 if ( isAttacking() ) { // 行動制限解除(=出し終わり)してないと操作不可 if ( !mAttackLocked ) { // 連続攻撃 if ( button_A ) { // 行動制限 this->AttackLock(); switch( m_eCharaState ) { case CHARASTATE_ATTACK_1: if(scg_bValfirleAttack2Permission[GameManager::getInstance()->getRank()]) getManager()->postEvent( getHandle(), EV_ACTION_ATTACK_2, NULL, 0 ); break; case CHARASTATE_ATTACK_2: if(scg_bValfirleAttack3Permission[GameManager::getInstance()->getRank()]) getManager()->postEvent( getHandle(), EV_ACTION_ATTACK_3, NULL, 0 ); break; default: // 万が一おかしい値になったらロック解除 this->AttackUnLock(); break; } } } } //------------------------------------------------------ // 攻撃動作中ではない場合 else { // 攻撃開始 if ( button_A && m_eCharaState != EV_ACTION_ATTACK_1 ) // 後ろのは仮 { // ジャンプ中の場合 if ( mJump ) { this->AttackLock(); getManager()->postEvent( getHandle(), EV_ACTION_ATTACK_JUMP_ATTACK, NULL, 0 ); } // しゃがみ中の場合 else if ( Down ) { this->AttackLock(); getManager()->postEvent( getHandle(), EV_ACTION_ATTACK_SQUAT_ATTACK, NULL, 0 ); } // 上を押しながらの場合 else if ( !mTouchLadder && Up ) { this->AttackLock(); getManager()->postEvent( getHandle(), EV_ACTION_ATTACK_ANTIAIR_ATTACK, NULL, 0 ); this->m_nAttackDelay = 0; } // 以上以外は通常攻撃 else { // 攻撃のため行動制限 if(scg_bValfirleAttack1Permission[GameManager::getInstance()->getRank()]) { this->AttackLock(); getManager()->postEvent( getHandle(), EV_ACTION_ATTACK_1, NULL, 0 ); } } return true; } // ガード if ( !Down && Guard && mOnGround && !mClimbLadder && m_eCharaState != CHARASTATE_GUARD ) { getManager()->postEvent( getHandle(), EV_ACTION_GUARD, NULL, 0 ); return true; } // 向きを変えるための処理 if ( right ) { setDirection( CHARADIR_RIGHT ); } else if ( left ) { setDirection( CHARADIR_LEFT ); } // 右移動 //if ( !mClimbLadder && right && ( m_eCharaState != CHARASTATE_RUN || m_eDirection != CHARADIR_RIGHT ) ) //{ // // 方向をつけて EV_ACTION_RUN イベントを送る。 // // このあと、HandleEvent() で実際に移動を開始する。 // // このイベントはキューイングせず、即座に HandleEvent() に送られる。 // //u32 dir = CHARADIR_RIGHT; // if ( !Down ) // getManager()->postEvent( getHandle(), EV_ACTION_RUN, NULL, 0 ); // // getManager()->postEvent( getHandle(), EV_ACTION_RUN, &dir, sizeof( u32 ) ); //} //// 左移動 //else if( !mClimbLadder && left && ( m_eCharaState != CHARASTATE_RUN || m_eDirection != CHARADIR_LEFT ) ) //{ // //u32 dir = CHARADIR_LEFT; // 移動 if ( ( !Guard && !this->mClimbLadder && right && !left && ( m_eCharaState != CHARASTATE_RUN || m_eDirection != CHARADIR_RIGHT ) ) || ( !Guard && !this->mClimbLadder && left && !right && ( m_eCharaState != CHARASTATE_RUN || m_eDirection != CHARADIR_LEFT ) ) ) { if ( !Down ) getManager()->postEvent( getHandle(), EV_ACTION_RUN, NULL, 0 ); } // 左右のいずれも押されていない場合は待機にする // 梯子離したときも待機で。 // (後ろの mState != CHARASTATE_WAIT は、待機中に連続でイベントが送られないようにするために必要) else if ( ( !Guard && this->mOnGround && ( ( !right && !left ) || ( right && left ) ) && !Down && !this->mClimbLadder && m_eCharaState != CHARASTATE_WAIT ) || this->mNewTouchObj != OBJ_LADDER && this->mOldTouchObj == OBJ_LADDER && m_eCharaState != CHARASTATE_WAIT && m_eCharaState != CHARASTATE_JUMP && m_eCharaState != CHARASTATE_RUN ) { getManager()->postEvent( getHandle(), EV_ACTION_WAIT, NULL, 0 ); } // ジャンプ開始 if ( button_B && m_eCharaState != CHARASTATE_JUMP && ( this->mOnGround || this->mClimbLadder ) ) { getManager()->postEvent( getHandle(), EV_ACTION_JUMP, NULL, 0 ); return true; } // しゃがみ開始 if ( Down && this->mOnGround && !this->mTouchLadder ) { // しゃがみながらガードした場合 // ガードしながらしゃがんだ場合 if ( ( ( GuardTrigger ) || ( DownTrigger && Guard ) ) && m_eCharaState != CHARASTATE_SQGUARD ) { getManager()->postEvent( getHandle(), EV_ACTION_SQUAT_GUARD, NULL, 0 ); } else if ( !Guard && m_eCharaState != CHARASTATE_SQUAT ) { getManager()->postEvent( getHandle(), EV_ACTION_SQUAT, NULL, 0 ); } } // はしごつかみ if ( mTouchLadder && m_eCharaState != CHARASTATE_LADDER_UP && m_eCharaState != CHARASTATE_LADDER_DOWN && m_eCharaState != CHARASTATE_LADDER_WAIT ) { bool Catch = false; if ( UpTrigger && mDistance.y > 0 ) Catch = true; if ( DownTrigger && mDistance.y < 0 ) Catch = true; if ( Catch ) { this->mPosition.set( mPosition.x + mDistance.x, mPosition.y, mPosition.z ); mClimbLadder = true; } } // はしご上昇 if ( Up && m_eCharaState != CHARASTATE_LADDER_UP && mClimbLadder ) { getManager()->postEvent( getHandle(), EV_ACTION_LADDER_UP, NULL, 0 ); return true; } // はしご下降 else if ( Down && m_eCharaState != CHARASTATE_LADDER_DOWN && mClimbLadder ) { getManager()->postEvent( getHandle(), EV_ACTION_LADDER_DOWN, NULL, 0 ); return true; } // はしご待機 else if ( !Up && !Down && mClimbLadder && m_eCharaState != CHARASTATE_LADDER_WAIT ) { getManager()->postEvent( getHandle(), EV_ACTION_LADDER_WAIT, NULL, 0 ); return true; } } } return true; }
void Game::processAttackCancel(uint seq) { if(isAttacking() && (seq == 0 || m_seq == seq)) cancelAttack(); }