void Player::debugDash()
{
	if (status != CharaStatus::NORMAL)
		return;

	isAttacking();
}
BOOL CActorInstance::CanCheckAttacking()
{
	if (isAttacking())
		return true;

	return false;
}
示例#3
0
// 进攻方对方禁区拿球,强制触发一次空中遭遇。
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);
            }
        }
    }
}
示例#4
0
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);
}
示例#5
0
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;
        }
    }
}
示例#6
0
void Game::cancelAttackAndFollow()
{
    if(!canPerformGameAction())
        return;

    if(isAttacking())
        setAttackingCreature(nullptr);
    if(isFollowing())
        setFollowingCreature(nullptr);

    m_protocolGame->sendCancelAttackAndFollow();
}
示例#7
0
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;
}
示例#8
0
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();
}
示例#9
0
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");
}
示例#10
0
文件: Squad.cpp 项目: rarosu/FnulAI
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;
}
示例#11
0
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;
	}
}
示例#12
0
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;
	}
}
示例#13
0
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());
}
示例#14
0
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;
    }
}
示例#15
0
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;
    }
}
示例#16
0
文件: Squad.cpp 项目: rarosu/FnulAI
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);
	}
}
示例#17
0
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);
}
示例#18
0
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);
}
示例#19
0
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;
            }
        }
    }
}
示例#20
0
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();
}
示例#21
0
void Game::processAttackCancel(uint seq)
{
    if(isAttacking() && (seq == 0 || m_seq == seq))
        setAttackingCreature(nullptr);
}
示例#22
0
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;
}
示例#23
0
//---------------------------------------------------------------------------
// ● フレーム更新処理 (オブジェクトに影響を与える処理)
//---------------------------------------------------------------------------
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;
}
示例#24
0
void Game::processAttackCancel(uint seq)
{
    if(isAttacking() && (seq == 0 || m_seq == seq))
        cancelAttack();
}