• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

C++ FinishCommand函数代码示例

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

本文整理汇总了C++中FinishCommand函数的典型用法代码示例。如果您正苦于以下问题:C++ FinishCommand函数的具体用法?C++ FinishCommand怎么用?C++ FinishCommand使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。



在下文中一共展示了FinishCommand函数的20个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的C++代码示例。

示例1: assert

void CBuilderCAI::ExecuteFight(Command& c)
{
	assert((c.options & INTERNAL_ORDER) || owner->unitDef->canFight);

	if (tempOrder) {
		tempOrder = false;
		inCommand = true;
	}
	if (c.params.size() < 3) { // this shouldnt happen but anyway ...
		LOG_L(L_ERROR,
				"Received a Fight command with less than 3 params on %s in BuilderCAI",
				owner->unitDef->humanName.c_str());
		return;
	}

	if (c.params.size() >= 6) {
		if (!inCommand) {
			commandPos1 = c.GetPos(3);
		}
	} else {
		// Some hackery to make sure the line (commandPos1,commandPos2) is NOT
		// rotated (only shortened) if we reach this because the previous return
		// fight command finished by the 'if((curPos-pos).SqLength2D()<(64*64)){'
		// condition, but is actually updated correctly if you click somewhere
		// outside the area close to the line (for a new command).
		commandPos1 = ClosestPointOnLine(commandPos1, commandPos2, owner->pos);
		if (f3SqDist(owner->pos, commandPos1) > (96 * 96)) {
			commandPos1 = owner->pos;
		}
	}

	float3 pos = c.GetPos(0);
	if (!inCommand) {
		inCommand = true;
		commandPos2 = pos;
	}

	float3 curPosOnLine = ClosestPointOnLine(commandPos1, commandPos2, owner->pos);
	if (c.params.size() >= 6) {
		pos = curPosOnLine;
	}

	if (pos != goalPos) {
		SetGoal(pos, owner->pos);
	}

	const bool resurrectMode = !!(c.options & ALT_KEY);
	const bool reclaimEnemyMode = !!(c.options & META_KEY);
	const bool reclaimEnemyOnlyMode = (c.options & CONTROL_KEY) && (c.options & META_KEY);

	ReclaimOption recopt;
	if (resurrectMode)        recopt |= REC_NONREZ;
	if (reclaimEnemyMode)     recopt |= REC_ENEMY;
	if (reclaimEnemyOnlyMode) recopt |= REC_ENEMYONLY;

	const float searchRadius = (owner->immobile ? 0 : (300 * owner->moveState)) + ownerBuilder->buildDistance;

	if (!reclaimEnemyOnlyMode && (owner->unitDef->canRepair || owner->unitDef->canAssist) && // Priority 1: Repair
	    FindRepairTargetAndRepair(curPosOnLine, searchRadius, c.options, true, resurrectMode)){
		tempOrder = true;
		inCommand = false;
		if (lastPC1 != gs->frameNum) {  //avoid infinite loops
			lastPC1 = gs->frameNum;
			SlowUpdate();
		}
		return;
	}
	if (!reclaimEnemyOnlyMode && resurrectMode && owner->unitDef->canResurrect && // Priority 2: Resurrect (optional)
	    FindResurrectableFeatureAndResurrect(curPosOnLine, searchRadius, c.options, false)) {
		tempOrder = true;
		inCommand = false;
		if (lastPC2 != gs->frameNum) {  //avoid infinite loops
			lastPC2 = gs->frameNum;
			SlowUpdate();
		}
		return;
	}
	if (owner->unitDef->canReclaim && // Priority 3: Reclaim / reclaim non resurrectable (optional) / reclaim enemy units (optional)
	    FindReclaimTargetAndReclaim(curPosOnLine, searchRadius, c.options, recopt)) {
		tempOrder = true;
		inCommand = false;
		if (lastPC3 != gs->frameNum) {  //avoid infinite loops
			lastPC3 = gs->frameNum;
			SlowUpdate();
		}
		return;
	}
	if (f3SqDist(owner->pos, pos) < (64*64)) {
		FinishCommand();
		return;
	}

	if (owner->haveTarget && owner->moveType->progressState != AMoveType::Done) {
		StopMove();
	} else if (owner->moveType->progressState != AMoveType::Active) {
		owner->moveType->StartMoving(goalPos, 8);
	}
}
开发者ID:9heart,项目名称:spring,代码行数:98,代码来源:BuilderCAI.cpp


示例2: FinishCommand

void CAirCAI::SlowUpdate()
{
	if (!commandQue.empty() && commandQue.front().timeOut < gs->frameNum) {
		FinishCommand();
		return;
	}

	if (owner->usingScriptMoveType) {
		return; // avoid the invalid (CAirMoveType*) cast
	}

	AAirMoveType* myPlane=(AAirMoveType*) owner->moveType;

	if(owner->unitDef->maxFuel > 0){
		RefuelIfNeeded();
	}

	if(commandQue.empty()){
		if(myPlane->aircraftState == AAirMoveType::AIRCRAFT_FLYING
			&& !owner->unitDef->DontLand() && myPlane->autoLand){
			StopMove();
//			myPlane->SetState(AAirMoveType::AIRCRAFT_LANDING);
		}

		if(owner->unitDef->canAttack && owner->fireState>=2
				&& owner->moveState != 0 && owner->maxRange > 0){
			if(myPlane->IsFighter()){
				float testRad=1000 * owner->moveState;
				CUnit* enemy=helper->GetClosestEnemyAircraft(
					owner->pos + (owner->speed * 10), testRad, owner->allyteam);
				if(IsValidTarget(enemy)) {
					Command nc;
					nc.id = CMD_ATTACK;
					nc.params.push_back(enemy->id);
					nc.options = 0;
					commandQue.push_front(nc);
					inCommand = false;
					return;
				}
			}
			float testRad = 500 * owner->moveState;
			CUnit* enemy = helper->GetClosestEnemyUnit(
				owner->pos + (owner->speed * 20), testRad, owner->allyteam);
			if(IsValidTarget(enemy)) {
				Command nc;
				nc.id = CMD_ATTACK;
				nc.params.push_back(enemy->id);
				nc.options = 0;
				commandQue.push_front(nc);
				inCommand = false;
				return;
			}
		}
		return;
	}

	Command& c = commandQue.front();

	if (c.id == CMD_WAIT) {
		if ((myPlane->aircraftState == AAirMoveType::AIRCRAFT_FLYING)
		    && !owner->unitDef->DontLand() && myPlane->autoLand) {
			StopMove(); 
//			myPlane->SetState(AAirMoveType::AIRCRAFT_LANDING);
		}
		return;
	}

	if (c.id != CMD_STOP) {
		myPlane->Takeoff();
	}

	float3 curPos=owner->pos;

	switch(c.id){
		case CMD_AREA_ATTACK:{
			ExecuteAreaAttack(c);
			return;
		}
		default:{
			CMobileCAI::Execute();
			return;
		}
	}
}
开发者ID:genxinzou,项目名称:svn-spring-archive,代码行数:84,代码来源:AirCAI.cpp


示例3: assert

void CAirCAI::ExecuteAttack(Command &c)
{
	assert(owner->unitDef->canAttack);
	targetAge++;

	if (tempOrder && owner->moveState == 1) {
		// limit how far away we fly
		if (orderTarget && LinePointDist(commandPos1, commandPos2, orderTarget->pos) > 1500) {
			owner->SetUserTarget(0);
			FinishCommand();
			return;
		}
	}

	if (inCommand) {
		if (targetDied || (c.params.size() == 1 && UpdateTargetLostTimer(int(c.params[0])) == 0)) {
			FinishCommand();
			return;
		}
		if ((c.params.size() == 3) && (owner->commandShotCount < 0) && (commandQue.size() > 1)) {
			owner->AttackGround(float3(c.params[0], c.params[1], c.params[2]), true);
			FinishCommand();
			return;
		}
		if (orderTarget) {
			if (orderTarget->unitDef->canfly && orderTarget->crashing) {
				owner->SetUserTarget(0);
				FinishCommand();
				return;
			}
			if (!(c.options & ALT_KEY) && SkipParalyzeTarget(orderTarget)) {
				owner->SetUserTarget(0);
				FinishCommand();
				return;
			}
		}
	} else {
		targetAge = 0;
		owner->commandShotCount = -1;

		if (c.params.size() == 1) {
			const int targetID     = int(c.params[0]);
			const bool legalTarget = (targetID >= 0 && targetID < MAX_UNITS);
			CUnit* targetUnit      = (legalTarget)? uh->units[targetID]: 0x0;

			if (legalTarget && targetUnit != 0x0 && targetUnit != owner) {
				orderTarget = targetUnit;
				owner->AttackUnit(orderTarget, false);
				AddDeathDependence(orderTarget);
				inCommand = true;
				SetGoal(orderTarget->pos, owner->pos, cancelDistance);
			} else {
				FinishCommand();
				return;
			}
		} else {
			float3 pos(c.params[0], c.params[1], c.params[2]);
			owner->AttackGround(pos, false);
			inCommand = true;
		}
	}

	return;
}
开发者ID:genxinzou,项目名称:svn-spring-archive,代码行数:64,代码来源:AirCAI.cpp


示例4: FinishCommand

void CAirCAI::SlowUpdate()
{
	if (!commandQue.empty() && commandQue.front().timeOut < gs->frameNum) {
		FinishCommand();
		return;
	}

	if (owner->usingScriptMoveType) {
		return; // avoid the invalid (CAirMoveType*) cast
	}

	CAirMoveType* myPlane=(CAirMoveType*) owner->moveType;

	if(owner->unitDef->maxFuel > 0){
		if(myPlane->reservedPad){
			return;
		}else{
			if(owner->currentFuel <= 0){
				owner->userAttackGround=false;
				owner->userTarget=0;
				inCommand=false;

				CAirBaseHandler::LandingPad* lp = airBaseHandler->FindAirBase(
					owner, owner->unitDef->minAirBasePower);
				if(lp){
					myPlane->AddDeathDependence(lp);
					myPlane->reservedPad = lp;
					myPlane->padStatus = 0;
					myPlane->oldGoalPos = myPlane->goalPos;
					return;
				}
				float3 landingPos = airBaseHandler->FindClosestAirBasePos(
					owner, owner->unitDef->minAirBasePower);
				if(landingPos != ZeroVector && owner->pos.distance2D(landingPos) > 300){
					if(myPlane->aircraftState == CAirMoveType::AIRCRAFT_LANDED
							&& owner->pos.distance2D(landingPos) > 800) {
						myPlane->SetState(CAirMoveType::AIRCRAFT_TAKEOFF);
					}
					myPlane->goalPos = landingPos;
				} else {
					if(myPlane->aircraftState == CAirMoveType::AIRCRAFT_FLYING)
						myPlane->SetState(CAirMoveType::AIRCRAFT_LANDING);
				}
				return;
			}
			if(owner->currentFuel < myPlane->repairBelowHealth * owner->unitDef->maxFuel){
				if(commandQue.empty() || commandQue.front().id == CMD_PATROL){
					CAirBaseHandler::LandingPad* lp =
						airBaseHandler->FindAirBase(owner, owner->unitDef->minAirBasePower);
					if(lp){
						owner->userAttackGround=false;
						owner->userTarget=0;
						inCommand=false;
						myPlane->AddDeathDependence(lp);
						myPlane->reservedPad=lp;
						myPlane->padStatus=0;
						myPlane->oldGoalPos=myPlane->goalPos;
						if(myPlane->aircraftState == CAirMoveType::AIRCRAFT_LANDED){
							myPlane->SetState(CAirMoveType::AIRCRAFT_TAKEOFF);
						}
						return;
					}
				}
			}
		}
	}

	if(commandQue.empty()){
		if(myPlane->aircraftState == CAirMoveType::AIRCRAFT_FLYING
				&& !owner->unitDef->DontLand()){
			myPlane->SetState(CAirMoveType::AIRCRAFT_LANDING);
		}

		if(owner->unitDef->canAttack && owner->fireState==2
				&& owner->moveState != 0 && owner->maxRange > 0){
			if(myPlane->isFighter){
				float testRad=1000 * owner->moveState;
				CUnit* enemy=helper->GetClosestEnemyAircraft(
					owner->pos + (owner->speed * 10), testRad, owner->allyteam);
				if(enemy && !enemy->crashing){
					Command nc;
					nc.id = CMD_ATTACK;
					nc.params.push_back(enemy->id);
					nc.options = 0;
					commandQue.push_front(nc);
					inCommand = false;
					return;
				}
			}
			float testRad = 500 * owner->moveState;
			CUnit* enemy = helper->GetClosestEnemyUnit(
				owner->pos + (owner->speed * 20), testRad, owner->allyteam);
			if(enemy && (owner->hasUWWeapons || !enemy->isUnderWater)
					&& !enemy->crashing
					&& (myPlane->isFighter || !enemy->unitDef->canfly)){
				Command nc;
				nc.id = CMD_ATTACK;
				nc.params.push_back(enemy->id);
				nc.options = 0;
				commandQue.push_front(nc);
//.........这里部分代码省略.........
开发者ID:genxinzou,项目名称:svn-spring-archive,代码行数:101,代码来源:AirCAI.cpp


示例5: StopMove

void CMobileCAI::SlowUpdate()
{
    if(owner->unitDef->maxFuel>0 && dynamic_cast<CTAAirMoveType*>(owner->moveType)) {
        CTAAirMoveType* myPlane=(CTAAirMoveType*)owner->moveType;
        if(myPlane->reservedPad) {
            return;
        } else {
            if(owner->currentFuel <= 0) {
                StopMove();
                owner->userAttackGround=false;
                owner->userTarget=0;
                inCommand=false;
                CAirBaseHandler::LandingPad* lp=airBaseHandler->FindAirBase(owner,8000,owner->unitDef->minAirBasePower);
                if(lp) {
                    myPlane->AddDeathDependence(lp);
                    myPlane->reservedPad=lp;
                    myPlane->padStatus=0;
                    myPlane->oldGoalPos=myPlane->goalPos;
                    return;
                }
                float3 landingPos = airBaseHandler->FindClosestAirBasePos(owner,8000,owner->unitDef->minAirBasePower);
                if(landingPos != ZeroVector && owner->pos.distance2D(landingPos) > 300) {
                    inCommand=false;
                    StopMove();
                    SetGoal(landingPos,owner->pos);
                } else {
                    if(myPlane->aircraftState == CTAAirMoveType::AIRCRAFT_FLYING)
                        myPlane->SetState(CTAAirMoveType::AIRCRAFT_LANDING);
                }
                return;
            }
            if(owner->currentFuel < myPlane->repairBelowHealth*owner->unitDef->maxFuel) {
                if(commandQue.empty() || commandQue.front().id==CMD_PATROL) {
                    CAirBaseHandler::LandingPad* lp=airBaseHandler->FindAirBase(owner,8000,owner->unitDef->minAirBasePower);
                    if(lp) {
                        StopMove();
                        owner->userAttackGround=false;
                        owner->userTarget=0;
                        inCommand=false;
                        myPlane->AddDeathDependence(lp);
                        myPlane->reservedPad=lp;
                        myPlane->padStatus=0;
                        myPlane->oldGoalPos=myPlane->goalPos;
                        if(myPlane->aircraftState==CTAAirMoveType::AIRCRAFT_LANDED) {
                            myPlane->SetState(CTAAirMoveType::AIRCRAFT_TAKEOFF);
                        }
                        return;
                    }
                }
            }
        }
    }

    if(!commandQue.empty() && commandQue.front().timeOut<gs->frameNum) {
        StopMove();
        FinishCommand();
        return;
    }

    if(commandQue.empty()) {
//		if(!owner->ai || owner->ai->State() != CHasState::Active) {
        IdleCheck();
//		}
        if(commandQue.empty() || commandQue.front().id==CMD_ATTACK)	//the attack order could terminate directly and thus cause a loop
            return;
    }

    float3 curPos=owner->pos;

    Command& c=commandQue.front();
    switch(c.id) {
    case CMD_STOP: {
        StopMove();
        CCommandAI::SlowUpdate();
        break;
    }
    case CMD_MOVE: {
        float3 pos(c.params[0],c.params[1],c.params[2]);
        if(!(pos==goalPos)) {
            SetGoal(pos,curPos);
        }
        if((curPos-goalPos).SqLength2D()<1024 || owner->moveType->progressState==CMoveType::Failed) {
            FinishCommand();
        }
        break;
    }
    case CMD_PATROL: {
        if(c.params.size()<3) {		//this shouldnt happen but anyway ...
            info->AddLine("Error: got patrol cmd with less than 3 params on %s in mobilecai",
                          owner->unitDef->humanName.c_str());
            return;
        }
        Command temp;
        temp.id = CMD_FIGHT;
        temp.params.push_back(c.params[0]);
        temp.params.push_back(c.params[1]);
        temp.params.push_back(c.params[2]);
        temp.options = c.options|INTERNAL_ORDER;
        commandQue.push_back(c);
        commandQue.pop_front();
//.........这里部分代码省略.........
开发者ID:genxinzou,项目名称:svn-spring-archive,代码行数:101,代码来源:MobileCAI.cpp


示例6: assert

/**
* @brief Executes the Fight command c
*/
void CMobileCAI::ExecuteFight(Command& c)
{
	assert((c.options & INTERNAL_ORDER) || owner->unitDef->canFight);

	if (c.params.size() == 1 && !owner->weapons.empty()) {
		CWeapon* w = owner->weapons.front();

		if ((orderTarget != NULL) && !w->AttackUnit(orderTarget, false)) {
			CUnit* newTarget = CGameHelper::GetClosestValidTarget(owner->pos, owner->maxRange, owner->allyteam, this);

			if ((newTarget != NULL) && w->AttackUnit(newTarget, false)) {
				c.params[0] = newTarget->id;

				inCommand = false;
			} else {
				w->AttackUnit(orderTarget, false);
			}
		}

		ExecuteAttack(c);
		return;
	}

	if (tempOrder) {
		inCommand = true;
		tempOrder = false;
	}
	if (c.params.size() < 3) {
		LOG_L(L_ERROR,
				"Received a Fight command with less than 3 params on %s in MobileCAI",
				owner->unitDef->humanName.c_str());
		return;
	}
	if (c.params.size() >= 6) {
		if (!inCommand) {
			commandPos1 = c.GetPos(3);
		}
	} else {
		// Some hackery to make sure the line (commandPos1,commandPos2) is NOT
		// rotated (only shortened) if we reach this because the previous return
		// fight command finished by the 'if((curPos-pos).SqLength2D()<(64*64)){'
		// condition, but is actually updated correctly if you click somewhere
		// outside the area close to the line (for a new command).
		commandPos1 = ClosestPointOnLine(commandPos1, commandPos2, owner->pos);
		if ((owner->pos - commandPos1).SqLength2D() > (96 * 96)) {
			commandPos1 = owner->pos;
		}
	}

	float3 pos = c.GetPos(0);

	if (!inCommand) {
		inCommand = true;
		commandPos2 = pos;
		lastUserGoal = commandPos2;
	}
	if (c.params.size() >= 6) {
		pos = ClosestPointOnLine(commandPos1, commandPos2, owner->pos);
	}
	if (pos != goalPos) {
		SetGoal(pos, owner->pos);
	}

	if (owner->unitDef->canAttack && owner->fireState >= FIRESTATE_FIREATWILL && !owner->weapons.empty()) {
		const float3 curPosOnLine = ClosestPointOnLine(commandPos1, commandPos2, owner->pos);
		const float searchRadius = owner->maxRange + 100 * owner->moveState * owner->moveState;
		CUnit* enemy = CGameHelper::GetClosestValidTarget(curPosOnLine, searchRadius, owner->allyteam, this);

		if (enemy != NULL) {
			PushOrUpdateReturnFight();

			// make the attack-command inherit <c>'s options
			// NOTE: see AirCAI::ExecuteFight why we do not set INTERNAL_ORDER
			Command c2(CMD_ATTACK, c.options, enemy->id);
			commandQue.push_front(c2);

			inCommand = false;
			tempOrder = true;

			// avoid infinite loops (?)
			if (lastPC != gs->frameNum) {
				lastPC = gs->frameNum;
				SlowUpdate();
			}
			return;
		}
	}

	if ((owner->pos - goalPos).SqLength2D() < (64 * 64)
			|| (owner->moveType->progressState == AMoveType::Failed)){
		FinishCommand();
	}
}
开发者ID:AlexDiede,项目名称:spring,代码行数:96,代码来源:MobileCAI.cpp


示例7: FinishCommand

void CCommandAI::ExecuteRemove(const Command& c)
{
	if ((c.params.size() <= 0) ||
	    (commandQue.size() <= 0)) {
		return;
	}

	// disable repeating during the removals
	const bool prevRepeat = repeatOrders;
	repeatOrders = false;

	CCommandQueue* queue = &commandQue;

	bool facBuildQueue = false;
	CFactoryCAI* facCAI = dynamic_cast<CFactoryCAI*>(this);
	if (facCAI) {
		if (c.options & CONTROL_KEY) {
			// check the build order
			facBuildQueue = true;
		} else {
			// use the new commands
			queue = &facCAI->newUnitCommands;
		}
	}

	// erase commands by a list of command types
	bool active = false;
	for (int p = 0; p < (int)c.params.size(); p++) {
		const int removeValue = (int)c.params[p]; // tag or id
		if (facBuildQueue && (removeValue == 0) && !(c.options & ALT_KEY)) {
			continue; // don't remove tag=0 commands from build queues, they
			          // are used the same way that CMD_STOP is, to void orders
		}
		CCommandQueue::iterator ci;
		do {
			for (ci = queue->begin(); ci != queue->end(); ++ci) {
				const Command& qc = *ci;
				if (c.options & ALT_KEY) {
					if (qc.id != removeValue)  { continue; }
				} else {
					if (qc.tag != removeValue) { continue; }
				}

				if (qc.id == CMD_WAIT) {
					waitCommandsAI.RemoveWaitCommand(owner, qc);
				}

				if (facBuildQueue) {
					facCAI->RemoveBuildCommand(ci);
					ci = queue->begin();
					break; // the removal may have corrupted the iterator
				}

				if (!facCAI && (ci == queue->begin())) {
					if (!active) {
						active = true;
						FinishCommand();
						ci = queue->begin();
						break;
					}
					active = true;
				}
				queue->erase(ci);
				ci = queue->begin();
				break; // the removal may have corrupted the iterator
			}
		}
		while (ci != queue->end());
	}

	repeatOrders = prevRepeat;
	return;
}
开发者ID:genxinzou,项目名称:svn-spring-archive,代码行数:73,代码来源:CommandAI.cpp


示例8: FinishCommand

void CCommandAI::ExecuteRemove(const Command& c)
{
	CCommandQueue* queue = &commandQue;
	CFactoryCAI* facCAI = dynamic_cast<CFactoryCAI*>(this);

	// if false, remove commands by tag
	const bool removeByID = (c.options & ALT_KEY);
	// disable repeating during the removals
	const bool prevRepeat = repeatOrders;

	// erase commands by a list of command types
	bool active = false;
	bool facBuildQueue = false;

	if (facCAI) {
		if (c.options & CONTROL_KEY) {
			// keep using the build-order queue
			facBuildQueue = true;
		} else {
			// use the command-queue for new units
			queue = &facCAI->newUnitCommands;
		}
	}

	if ((c.params.size() <= 0) || (queue->size() <= 0)) {
		return;
	}

	repeatOrders = false;

	for (unsigned int p = 0; p < c.params.size(); p++) {
		const int removeValue = c.params[p]; // tag or id

		if (facBuildQueue && !removeByID && (removeValue == 0)) {
			// don't remove commands with tag 0 from build queues, they
			// are used the same way that CMD_STOP is (to void orders)
			continue;
		}

		CCommandQueue::iterator ci;

		do {
			for (ci = queue->begin(); ci != queue->end(); ++ci) {
				const Command& qc = *ci;

				if (removeByID) {
					if (qc.GetID() != removeValue)  { continue; }
				} else {
					if (qc.tag != removeValue) { continue; }
				}

				if (qc.GetID() == CMD_WAIT) {
					waitCommandsAI.RemoveWaitCommand(owner, qc);
				}

				if (facBuildQueue) {
					// if ci == queue->begin() and !queue->empty(), this pop_front()'s
					// via CFAI::ExecuteStop; otherwise only modifies *ci (not <queue>)
					if (facCAI->RemoveBuildCommand(ci)) {
						ci = queue->begin(); break;
					}
				}

				if (!facCAI && (ci == queue->begin())) {
					if (!active) {
						active = true;
						FinishCommand();
						ci = queue->begin();
						break;
					}
					active = true;
				}

				queue->erase(ci);
				ci = queue->begin();

				// the removal may have corrupted the iterator
				break;
			}
		}
		while (ci != queue->end());
	}

	repeatOrders = prevRepeat;
}
开发者ID:AlexDiede,项目名称:spring,代码行数:85,代码来源:CommandAI.cpp


示例9: StopMove

void CMobileCAI::SlowUpdate()
{
	if(owner->unitDef->maxFuel>0 && dynamic_cast<CTAAirMoveType*>(owner->moveType)){
		CTAAirMoveType* myPlane=(CTAAirMoveType*)owner->moveType;
		if(myPlane->reservedPad){
			return;
		} else {
			if(owner->currentFuel <= 0){
				StopMove();
				owner->userAttackGround=false;
				owner->userTarget=0;
				inCommand=false;
				CAirBaseHandler::LandingPad* lp=airBaseHandler->FindAirBase(owner,8000,owner->unitDef->minAirBasePower);
				if(lp){
					myPlane->AddDeathDependence(lp);
					myPlane->reservedPad=lp;
					myPlane->padStatus=0;
					myPlane->oldGoalPos=myPlane->goalPos;
					return;
				}
				float3 landingPos = airBaseHandler->FindClosestAirBasePos(owner,8000,owner->unitDef->minAirBasePower);
				if(landingPos != ZeroVector && owner->pos.distance2D(landingPos) > 300){
					inCommand=false;
					StopMove();
					SetGoal(landingPos,owner->pos);
				} else {
					if(myPlane->aircraftState == CTAAirMoveType::AIRCRAFT_FLYING)
						myPlane->SetState(CTAAirMoveType::AIRCRAFT_LANDING);	
				}
				return;
			}
			if(owner->currentFuel < myPlane->repairBelowHealth*owner->unitDef->maxFuel){
				if(commandQue.empty() || commandQue.front().id==CMD_PATROL){
					CAirBaseHandler::LandingPad* lp=airBaseHandler->FindAirBase(owner,8000,owner->unitDef->minAirBasePower);
					if(lp){
						StopMove();
						owner->userAttackGround=false;
						owner->userTarget=0;
						inCommand=false;
						myPlane->AddDeathDependence(lp);
						myPlane->reservedPad=lp;
						myPlane->padStatus=0;
						myPlane->oldGoalPos=myPlane->goalPos;
						if(myPlane->aircraftState==CTAAirMoveType::AIRCRAFT_LANDED){
							myPlane->SetState(CTAAirMoveType::AIRCRAFT_TAKEOFF);
						}
						return;
					}		
				}
			}
		}
	}

	if(!commandQue.empty() && commandQue.front().timeOut<gs->frameNum){
		StopMove();
		FinishCommand();
		return;
	}

	if(commandQue.empty()) {
//		if(!owner->ai || owner->ai->State() != CHasState::Active) {
			IdleCheck();
//		}
		if(commandQue.empty() || commandQue.front().id==CMD_ATTACK)	//the attack order could terminate directly and thus cause a loop
			return;
	}

	float3 curPos=owner->pos;
	
	// treat any following CMD_SET_WANTED_MAX_SPEED commands as options
	// to the current command  (and ignore them when it's their turn)
	if (commandQue.size() >= 2) {
		deque<Command>::iterator it = commandQue.begin();
		it++;
		const Command& c = *it;
		if ((c.id == CMD_SET_WANTED_MAX_SPEED) && (c.params.size() >= 1)) {
			const float defMaxSpeed = (owner->unitDef->speed / 30.0f);
			const float newMaxSpeed = min(c.params[0], defMaxSpeed);
			owner->moveType->SetMaxSpeed(newMaxSpeed);
		}
	}	 

	Command& c=commandQue.front();
	switch(c.id){
	case CMD_WAIT:{
		break;
	}
	case CMD_STOP:{
		StopMove();
		CCommandAI::SlowUpdate();
		break;
	}
	case CMD_SET_WANTED_MAX_SPEED:{
	  if (repeatOrders && (commandQue.size() >= 2) &&
	      (commandQue.back().id != CMD_SET_WANTED_MAX_SPEED)) {
	  	commandQue.push_back(commandQue.front());
		}
		commandQue.pop_front();
		SlowUpdate();
		break;
//.........这里部分代码省略.........
开发者ID:genxinzou,项目名称:svn-spring-archive,代码行数:101,代码来源:MobileCAI.cpp


示例10: LOG_L

void CBuilderCAI::ExecuteReclaim(Command& c)
{
	// not all builders are reclaim-capable by default
	if (!owner->unitDef->canReclaim)
		return;

	if (c.params.size() == 1 || c.params.size() == 5) {
		const int signedId = (int) c.params[0];

		if (signedId < 0) {
			LOG_L(L_WARNING, "Trying to reclaim unit or feature with id < 0 (%i), aborting.", signedId);
			return;
		}

		const unsigned int uid = signedId;

		const bool checkForBetterTarget = ((++randomCounter % 5) == 0);
		if (checkForBetterTarget && (c.options & INTERNAL_ORDER) && (c.params.size() >= 5)) {
			// regular check if there is a closer reclaim target
			CSolidObject* obj;
			if (uid >= unitHandler->MaxUnits()) {
				obj = featureHandler->GetFeature(uid - unitHandler->MaxUnits());
			} else {
				obj = unitHandler->GetUnit(uid);
			}
			if (obj) {
				const float3& pos = c.GetPos(1);
				const float radius = c.params[4];
				const float curdist = pos.SqDistance2D(obj->pos);

				const bool recUnits = !!(c.options & META_KEY);
				const bool recEnemyOnly = (c.options & META_KEY) && (c.options & CONTROL_KEY);
				const bool recSpecial = !!(c.options & CONTROL_KEY);

				ReclaimOption recopt = REC_NORESCHECK;
				if (recUnits)     recopt |= REC_UNITS;
				if (recEnemyOnly) recopt |= REC_ENEMYONLY;
				if (recSpecial)   recopt |= REC_SPECIAL;

				const int rid = FindReclaimTarget(pos, radius, c.options, recopt, curdist);
				if ((rid > 0) && (rid != uid)) {
					FinishCommand();
					RemoveUnitFromReclaimers(owner);
					RemoveUnitFromFeatureReclaimers(owner);
					return;
				}
			}
		}

		if (uid >= unitHandler->MaxUnits()) { // reclaim feature
			CFeature* feature = featureHandler->GetFeature(uid - unitHandler->MaxUnits());

			if (feature != NULL) {
				bool featureBeingResurrected = IsFeatureBeingResurrected(feature->id, owner);
				featureBeingResurrected &= (c.options & INTERNAL_ORDER) && !(c.options & CONTROL_KEY);

				if (featureBeingResurrected || !ReclaimObject(feature)) {
					StopMove();
					FinishCommand();
					RemoveUnitFromFeatureReclaimers(owner);
				} else {
					AddUnitToFeatureReclaimers(owner);
				}
			} else {
				StopMove();
				FinishCommand();
				RemoveUnitFromFeatureReclaimers(owner);
			}

			RemoveUnitFromReclaimers(owner);
		} else { // reclaim unit
			CUnit* unit = unitHandler->GetUnit(uid);

			if (unit != NULL && c.params.size() == 5) {
				const float3& pos = c.GetPos(1);
				const float radius = c.params[4] + 100.0f; // do not walk too far outside reclaim area

				const bool outOfReclaimRange =
					(pos.SqDistance2D(unit->pos) > radius * radius) ||
					(ownerBuilder->curReclaim == unit && unit->IsMoving() && !IsInBuildRange(unit));
				const bool busyAlliedBuilder =
					unit->unitDef->builder &&
					!unit->commandAI->commandQue.empty() &&
					teamHandler->Ally(owner->allyteam, unit->allyteam);

				if (outOfReclaimRange || busyAlliedBuilder) {
					StopMove();
					RemoveUnitFromReclaimers(owner);
					FinishCommand();
					RemoveUnitFromFeatureReclaimers(owner);
					return;
				}
			}

			if (unit != NULL && unit != owner && unit->unitDef->reclaimable && UpdateTargetLostTimer(unit->id) && unit->AllowedReclaim(owner)) {
				if (!ReclaimObject(unit)) {
					StopMove();
					FinishCommand();
				} else {
					AddUnitToReclaimers(owner);
//.........这里部分代码省略.........
开发者ID:9heart,项目名称:spring,代码行数:101,代码来源:BuilderCAI.cpp


示例11: UpdateIconName

void CFactoryCAI::SlowUpdate()
{
	if (commandQue.empty() || owner->beingBuilt) {
		return;
	}

	CFactory* fac=(CFactory*)owner;

	unsigned int oldSize;
	do {
		Command& c=commandQue.front();
		oldSize=commandQue.size();
		map<int,BuildOption>::iterator boi;
		if((boi=buildOptions.find(c.id))!=buildOptions.end()){
			const UnitDef *def = unitDefHandler->GetUnitByName(boi->second.name);
			if(building){
				if(!fac->curBuild && !fac->quedBuild){
					building=false;
					if(owner->group)
						owner->group->CommandFinished(owner->id,commandQue.front().id);
					if(!repeatOrders || c.options & DONT_REPEAT)
						boi->second.numQued--;
					UpdateIconName(c.id,boi->second);
					FinishCommand();
				}
				// This can only be true if two factories started building
				// the restricted unit in the same simulation frame
				else if(uh->unitsByDefs[owner->team][def->id].size() > def->maxThisUnit){ //unit restricted?
					CFactory* fac=(CFactory*)owner;
					building = false;
					fac->StopBuild();
					CancelRestrictedUnit(c, boi->second);
				}
			} else {
				const UnitDef *def = unitDefHandler->GetUnitByName(boi->second.name);
				if(luaRules && !luaRules->AllowUnitCreation(def, owner, NULL)) {
					if(!repeatOrders || c.options & DONT_REPEAT){
						boi->second.numQued--;
					}
					UpdateIconName(c.id,boi->second);
					FinishCommand();
				}
				else if(uh->unitsByDefs[owner->team][def->id].size() >= def->maxThisUnit){ //unit restricted?
					CancelRestrictedUnit(c, boi->second);
				}
				else if(uh->maxUnits>teamHandler->Team(owner->team)->units.size()){  //max unitlimit reached?
					fac->StartBuild(boi->second.fullName);
					building=true;
				}
			}
		}
		else {
			switch(c.id){
				case CMD_STOP: {
					ExecuteStop(c);
					break;
				}
				default: {
					CCommandAI::SlowUpdate();
					return;
				}
			}
		}
	} while ((oldSize != commandQue.size()) && !commandQue.empty());

	return;
}
开发者ID:achoum,项目名称:spring,代码行数:67,代码来源:FactoryCAI.cpp


示例12: ExecuteGuard

void CBuilderCAI::ExecuteGuard(Command& c)
{
	if (!owner->unitDef->canGuard)
		return;

	CUnit* guardee = unitHandler->GetUnit(c.params[0]);

	if (guardee == NULL) { FinishCommand(); return; }
	if (guardee == owner) { FinishCommand(); return; }
	if (UpdateTargetLostTimer(guardee->id) == 0) { FinishCommand(); return; }
	if (guardee->outOfMapTime > (GAME_SPEED * 5)) { FinishCommand(); return; }


	if (CBuilder* b = dynamic_cast<CBuilder*>(guardee)) {
		if (b->terraforming) {
			if (MoveInBuildRange(b->terraformCenter, b->terraformRadius * 0.7f)) {
				ownerBuilder->HelpTerraform(b);
			} else {
				StopSlowGuard();
			}
			return;
		} else if (b->curReclaim && owner->unitDef->canReclaim) {
			StopSlowGuard();
			if (!ReclaimObject(b->curReclaim)) {
				StopMove();
			}
			return;
		} else if (b->curResurrect && owner->unitDef->canResurrect) {
			StopSlowGuard();
			if (!ResurrectObject(b->curResurrect)) {
				StopMove();
			}
			return;
		} else {
			ownerBuilder->StopBuild();
		}

		const bool pushRepairCommand =
			(  b->curBuild != NULL) &&
			(  b->curBuild->soloBuilder == NULL || b->curBuild->soloBuilder == owner) &&
			(( b->curBuild->beingBuilt && owner->unitDef->canAssist) ||
			( !b->curBuild->beingBuilt && owner->unitDef->canRepair));

		if (pushRepairCommand) {
			StopSlowGuard();

			Command nc(CMD_REPAIR, c.options, b->curBuild->id);

			commandQue.push_front(nc);
			inCommand = false;
			SlowUpdate();
			return;
		}
	}

	if (CFactory* fac = dynamic_cast<CFactory*>(guardee)) {
		const bool pushRepairCommand =
			(  fac->curBuild != NULL) &&
			(  fac->curBuild->soloBuilder == NULL || fac->curBuild->soloBuilder == owner) &&
			(( fac->curBuild->beingBuilt && owner->unitDef->canAssist) ||
			 (!fac->curBuild->beingBuilt && owner->unitDef->canRepair));

		if (pushRepairCommand) {
			StopSlowGuard();

			Command nc(CMD_REPAIR, c.options, fac->curBuild->id);

			commandQue.push_front(nc);
			inCommand = false;
			// SlowUpdate();
			return;
		}
	}

	if (!(c.options & CONTROL_KEY) && IsUnitBeingReclaimed(guardee, owner))
		return;

	const float3 pos    = guardee->pos;
	const float  radius = (guardee->immobile) ? guardee->radius : guardee->radius * 0.8f; // in case of mobile units reduce radius a bit

	if (MoveInBuildRange(pos, radius)) {
		StartSlowGuard(guardee->moveType->GetMaxSpeed());

		const bool pushRepairCommand =
			(  guardee->health < guardee->maxHealth) &&
			(  guardee->soloBuilder == NULL || guardee->soloBuilder == owner) &&
			(( guardee->beingBuilt && owner->unitDef->canAssist) ||
			 (!guardee->beingBuilt && owner->unitDef->canRepair));

		if (pushRepairCommand) {
			StopSlowGuard();

			Command nc(CMD_REPAIR, c.options, guardee->id);

			commandQue.push_front(nc);
			inCommand = false;
			return;
		} else {
			NonMoving();
		}
//.........这里部分代码省略.........
开发者ID:9heart,项目名称:spring,代码行数:101,代码来源:BuilderCAI.cpp


示例13: FinishCommand

void CBuilderCAI::ExecuteRepair(Command& c)
{
	// not all builders are repair-capable by default
	if (!owner->unitDef->canRepair)
		return;

	if (c.params.size() == 1 || c.params.size() == 5) {
		// repair unit
		CUnit* unit = unitHandler->GetUnit(c.params[0]);

		if (unit == NULL) {
			FinishCommand();
			return;
		}

		if (tempOrder && owner->moveState <= MOVESTATE_MANEUVER) {
			// limit how far away we go when not roaming
			if (LinePointDist(commandPos1, commandPos2, unit->pos) > std::max(500.0f, GetBuildRange(unit->radius))) {
				StopMove();
				FinishCommand();
				return;
			}
		}

		if (c.params.size() == 5) {
			const float3& pos = c.GetPos(1);
			const float radius = c.params[4] + 100.0f; // do not walk too far outside repair area

			if ((pos - unit->pos).SqLength2D() > radius * radius ||
				(unit->IsMoving() && (((c.options & INTERNAL_ORDER) && !TargetInterceptable(unit, unit->speed.Length2D())) || ownerBuilder->curBuild == unit)
				&& !IsInBuildRange(unit))) {
				StopMove();
				FinishCommand();
				return;
			}
		}

		// do not consider units under construction irreparable
		// even if they can be repaired
		bool canRepairUnit = true;
		canRepairUnit &= ((unit->beingBuilt) || (unit->unitDef->repairable && (unit->health < unit->maxHealth)));
		canRepairUnit &= ((unit != owner) || owner->unitDef->canSelfRepair);
		canRepairUnit &= (!unit->soloBuilder || (unit->soloBuilder == owner));
		canRepairUnit &= (!(c.options & INTERNAL_ORDER) || (c.options & CONTROL_KEY) || !IsUnitBeingReclaimed(unit, owner));
		canRepairUnit &= (UpdateTargetLostTimer(unit->id) != 0);

		if (canRepairUnit) {
			if (MoveInBuildRange(unit)) {
				ownerBuilder->SetRepairTarget(unit);
			}
		} else {
			StopMove();
			FinishCommand();
		}
	} else if (c.params.size() == 4) {
		// area repair
		const float3 pos = c.GetPos(0);
		const float radius = c.params[3];

		ownerBuilder->StopBuild();
		if (FindRepairTargetAndRepair(pos, radius, c.options, false, (c.options & META_KEY))) {
			inCommand = false;
			SlowUpdate();
			return;
		}
		if (!(c.options & ALT_KEY)) {
			FinishCommand();
		}
	} else {
		FinishCommand();
	}
}
开发者ID:9heart,项目名称:spring,代码行数:72,代码来源:BuilderCAI.cpp


示例14: abs

void CBuilderCAI::ExecuteBuildCmd(Command& c)
{
	const map<int, string>::const_iterator boi = buildOptions.find(c.GetID());

	if (boi == buildOptions.end())
		return;

	if (!inCommand) {
		BuildInfo bi;
		bi.pos.x = math::floor(c.params[0] / SQUARE_SIZE + 0.5f) * SQUARE_SIZE;
		bi.pos.z = math::floor(c.params[2] / SQUARE_SIZE + 0.5f) * SQUARE_SIZE;
		bi.pos.y = c.params[1];

		if (c.params.size() == 4)
			bi.buildFacing = abs((int)c.params[3]) % NUM_FACINGS;

		bi.def = unitDefHandler->GetUnitDefByName(boi->second);

		CFeature* f = NULL;
		CGameHelper::TestUnitBuildSquare(bi, f, owner->allyteam, true);

		if (f != NULL) {
			if (!bi.def->isFeature || bi.def->wreckName != f->def->name) {
				ReclaimFeature(f);
			} else {
				FinishCommand();
			}
			return;
		}

		inCommand = true;
		build.Parse(c);
	}

	assert(build.def->id == -c.GetID() && build.def->id != 0);
	const float buildeeRadius = GetBuildOptionRadius(build.def, c.GetID());

	if (building) {
		// keep moving until 3D distance to buildPos is LEQ our buildDistance
		MoveInBuildRange(build.pos, 0.0f);

		if (!ownerBuilder->curBuild && !ownerBuilder->terraforming) {
			building = false;
			StopMove(); // cancel the effect of KeepPointingTo
			FinishCommand();
		}
		// This can only be true if two builders started building
		// the restricted unit in the same simulation frame
		else if (unitHandler->unitsByDefs[owner->team][build.def->id].size() > build.def->maxThisUnit) {
			// unit restricted
			building = false;
			ownerBuilder->StopBuild();
			CancelRestrictedUnit(boi->second);
		}
	} else {
		if (unitHandler->unitsByDefs[owner->team][build.def->id].size() >= build.def->maxThisUnit) {
			// unit restricted, don't bother moving all the way
			// to the construction site first before telling us
			// (since greyed-out icons can still be clicked etc,
			// would be better to prevent that but doesn't cover
			// case where limit reached while builder en-route)
			CancelRestrictedUnit(boi->second);
			StopMove();
			return;
		}

		build.pos = CGameHelper::Pos2BuildPos(build, true);

		// keep moving until until 3D distance to buildPos is LEQ our buildDistance
		if (MoveInBuildRange(build.pos, 0.0f, true)) {
			if (IsBuildPosBlocked(build)) {
				StopMove();
				FinishCommand();
				return;
			}

			if (!eventHandler.AllowUnitCreation(build.def, owner, &build)) {
				StopMove(); // cancel KeepPointingTo
				FinishCommand();
				return;
			}

			if (teamHandler->Team(owner->team)->AtUnitLimit()) {
				return;
			}

			CFeature* f = NULL;

			bool waitstance = false;
			if (ownerBuilder->StartBuild(build, f, waitstance) || (++buildRetries > 30)) {
				building = true;
			}
			else if (f != NULL && (!build.def->isFeature || build.def->wreckName != f->def->name)) {
				inCommand = false;
				ReclaimFeature(f);
			}
			else if (!waitstance) {
				const float fpSqRadius = (build.def->xsize * build.def->xsize + build.def->zsize * build.def->zsize);
				const float fpRadius = (math::sqrt(fpSqRadius) * 0.5f) * SQUARE_SIZE;

//.........这里部分代码省略.........
开发者ID:9heart,项目名称:spring,代码行数:101,代码来源:BuilderCAI.cpp


示例15: assert

/**
* @brief Causes this CMobileCAI to execute the attack order c
*/
void CMobileCAI::ExecuteAttack(Command &c)
{
	assert(owner->unitDef->canAttack);

	// limit how far away we fly
	if (tempOrder && (owner->moveState < 2) && orderTarget
			&& LinePointDist(ClosestPointOnLine(commandPos1, commandPos2, owner->pos),
					commandPos2, orderTarget->pos)
			> (500 * owner->moveState + owner->maxRange)) {
		StopMove();
		FinishCommand();
		return;
	}

	// check if we are in direct command of attacker
	if (!inCommand) {
		// don't start counting until the owner->AttackGround() order is given
		owner->commandShotCount = -1;

		if (c.params.size() == 1) {
			const int targetID     = int(c.params[0]);
			const bool legalTarget = (targetID >= 0 && targetID < MAX_UNITS);
			CUnit* targetUnit      = (legalTarget)? uh->units[targetID]: 0x0;

			// check if we have valid target parameter and that we aren't attacking ourselves
			if (legalTarget && targetUnit != 0x0 && targetUnit != owner) {
				float3 fix = targetUnit->pos + owner->posErrorVector * 128;
				float3 diff = float3(fix - owner->pos).Normalize();

				if (owner->moveState > 0 || !tempOrder) {
					SetGoal(fix - diff * targetUnit->radius, owner->pos);
				}

				orderTarget = targetUnit;
				AddDeathDependence(orderTarget);
				inCommand = true;
			} else {
				// unit may not fire on itself, cancel order
				StopMove();
				FinishCommand();
				return;
			}
		}
		else {
			// user gave force-fire attack command
			float3 pos(c.params[0], c.params[1], c.params[2]);
			SetGoal(pos, owner->pos);
			inCommand = true;
		}
	}
	else if ((c.params.size() == 3) && (owner->commandShotCount > 0) && (commandQue.size() > 1)) {
		// the trailing CMD_SET_WANTED_MAX_SPEED in a command pair does not count
		if ((commandQue.size() > 2) || (commandQue.back().id != CMD_SET_WANTED_MAX_SPEED)) {
			StopMove();
			FinishCommand();
			return;
		}
	}

	// if our target is dead or we lost it then stop attacking
	// NOTE: unit should actually just continue to target area!
	if (targetDied || (c.params.size() == 1 && UpdateTargetLostTimer(int(c.params[0])) == 0)) {
		// cancel keeppointingto
		StopMove();
		FinishCommand();
		return;
	}


	// user clicked on enemy unit (note that we handle aircrafts slightly differently)
	if (orderTarget) {
		//bool b1 = owner->AttackUnit(orderTarget, c.id == CMD_DGUN);
		bool b2 = false;
		bool b3 = false;
		bool b4 = false;
		float edgeFactor = 0.f; // percent offset to target center
		float3 diff = owner->pos - orderTarget->midPos;

		if (owner->weapons.size() > 0) {
			if (!(c.options & ALT_KEY) && SkipParalyzeTarget(orderTarget)) {
				StopMove();
				FinishCommand();
				return;
			}
			CWeapon* w = owner->weapons.front();
			// if we have at least one weapon then check if we
			// can hit target with our first (meanest) one
			b2 = w->TryTargetRotate(orderTarget, c.id == CMD_DGUN);
			b3 = Square(w->range - (w->relWeaponPos).Length())
					> (orderTarget->pos.SqDistance(owner->pos));
			b4 = w->TryTargetHeading(GetHeadingFromVector(-diff.x, -diff.z),
					orderTarget->pos, orderTarget != NULL);
			edgeFactor = fabs(w->targetBorder);
		}

		double diffLength2d = diff.Length2D();

//.........这里部分代码省略.........
开发者ID:genxinzou,项目名称:svn-spring-archive,代码行数:101,代码来源:MobileCAI.cpp


示例16: GetUnitRadius


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
C++ Fire函数代码示例发布时间:2022-05-30
下一篇:
C++ Finish函数代码示例发布时间:2022-05-30
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap