Ejemplo n.º 1
0
void CFactory::AssignBuildeeOrders(CUnit* unit) {
	const CFactoryCAI* facAI = (CFactoryCAI*) commandAI;
	const CCommandQueue& newUnitCmds = facAI->newUnitCommands;

	if (newUnitCmds.empty()) {
		SendToEmptySpot(unit);
		return;
	}

	// HACK: when a factory has a rallypoint set far enough away
	// to trigger the non-admissable path estimators, we want to
	// avoid units getting stuck inside by issuing them an extra
	// move-order. However, this order can *itself* cause the PF
	// system to consider the path blocked if the extra waypoint
	// falls within the factory's confines, so use a wide berth.
	const float xs = unitDef->xsize * SQUARE_SIZE * 0.5f;
	const float zs = unitDef->zsize * SQUARE_SIZE * 0.5f;

	float tmpDst = 2.0f;
	float3 tmpPos = unit->pos + (frontdir * this->radius * tmpDst);

	if (buildFacing == FACING_NORTH || buildFacing == FACING_SOUTH) {
		while ((tmpPos.z >= unit->pos.z - zs && tmpPos.z <= unit->pos.z + zs)) {
			tmpDst += 0.5f;
			tmpPos = unit->pos + (frontdir * this->radius * tmpDst);
		}
	} else {
		while ((tmpPos.x >= unit->pos.x - xs && tmpPos.x <= unit->pos.x + xs)) {
			tmpDst += 0.5f;
			tmpPos = unit->pos + (frontdir * this->radius * tmpDst);
		}
	}

	Command c;
		c.id = CMD_MOVE;
		c.params.push_back(tmpPos.x);
		c.params.push_back(tmpPos.y);
		c.params.push_back(tmpPos.z);
	unit->commandAI->GiveCommand(c);

	/*
	const float3 tmpWaypoint = curBuild->pos + frontdir * (this->radius * 2.5f);

	Command c;
		c.id = CMD_MOVE;
		c.params.push_back(tmpWaypoint.x);
		c.params.push_back(tmpWaypoint.y);
		c.params.push_back(tmpWaypoint.z);
	unit->commandAI->GiveCommand(c);
	*/

	for (CCommandQueue::const_iterator ci = newUnitCmds.begin(); ci != newUnitCmds.end(); ++ci) {
		c = *ci;
		c.options |= SHIFT_KEY;
		unit->commandAI->GiveCommand(c);
	}
}
Ejemplo n.º 2
0
void CFactory::Update()
{
	if(beingBuilt){
		CUnit::Update();
		return;
	}

	if(quedBuild && inBuildStance){
		std::vector<long> args;
		args.push_back(0);
		cob->Call("QueryBuildInfo",args);
		float3 relBuildPos=localmodel->GetPiecePos(args[0]);
		float3 buildPos=pos + frontdir*relBuildPos.z + updir*relBuildPos.y + rightdir*relBuildPos.x;

		bool canBuild=true;
		std::vector<CUnit*> units=qf->GetUnitsExact(buildPos,16);
		for(std::vector<CUnit*>::iterator ui=units.begin();ui!=units.end();++ui){
			if((*ui)!=this)
				canBuild=false;
		}
		if(canBuild){
			quedBuild=false;
			CUnit* b=unitLoader.LoadUnit(nextBuild,buildPos+float3(0.01,0.01,0.01),team,true);
			AddDeathDependence(b);
			curBuild=b;

			cob->Call("StartBuilding");

			if(unitDef->sounds.build.id)
				sound->PlaySound(unitDef->sounds.build.id, pos, unitDef->sounds.build.volume);
		} else {
			helper->BuggerOff(buildPos-float3(0.01,0,0.02),radius+8);
		}
	}

	if(curBuild && !beingBuilt){
		lastBuild=gs->frameNum;

		std::vector<long> args;
		args.push_back(0);
		cob->Call("QueryBuildInfo",args);
		CMatrix44f mat=localmodel->GetPieceMatrix(args[0]);
		int h=GetHeadingFromVector(mat[2],mat[10]);
		curBuild->heading=h;
//		if(curBuild->unitDef->canfly){	//hack to get naval air plant to work correctly, how to do it correctly ?
			float3 relBuildPos=localmodel->GetPiecePos(args[0]);
			float3 buildPos=pos + frontdir*relBuildPos.z + updir*relBuildPos.y + rightdir*relBuildPos.x;
			curBuild->pos=buildPos;
			if(curBuild->floatOnWater)
				curBuild->pos.y=ground->GetHeight(buildPos.x,buildPos.z)-curBuild->unitDef->waterline;
			curBuild->midPos=curBuild->pos+UpVector*curBuild->relMidPos.y;
//		}
		if(curBuild->AddBuildPower(buildSpeed,this)){
			std::vector<long> args;
			args.push_back(0);
			cob->Call("QueryNanoPiece",args);
			float3 relWeaponFirePos=localmodel->GetPiecePos(args[0]);
			float3 weaponPos=pos + frontdir*relWeaponFirePos.z + updir*relWeaponFirePos.y + rightdir*relWeaponFirePos.x;

			float3 dif=curBuild->midPos-weaponPos;
			float l=dif.Length();
			dif/=l;
			dif+=gs->randVector()*0.15f;

			new CGfxProjectile(weaponPos,dif,l,float3(0.2f,0.7f,0.2f));
		} else {
			if(!curBuild->beingBuilt){
				if(group)
					curBuild->SetGroup(group);
				Command c;
				c.id=CMD_MOVE_STATE;
				c.options=0;
				c.params.push_back(moveState);
				curBuild->commandAI->GiveCommand(c);
				c.params.clear();
				c.id=CMD_FIRE_STATE;
				c.params.push_back(fireState);
				curBuild->commandAI->GiveCommand(c);
				if(curBuild->commandAI->commandQue.empty() || (dynamic_cast<CMobileCAI*>(curBuild->commandAI) && ((CMobileCAI*)curBuild->commandAI)->unimportantMove)){
					if(((CFactoryCAI*)commandAI)->newUnitCommands.empty()){
						SendToEmptySpot(curBuild);
					} else {
						for(std::deque<Command>::iterator ci=((CFactoryCAI*)commandAI)->newUnitCommands.begin();ci!=((CFactoryCAI*)commandAI)->newUnitCommands.end();++ci)
							curBuild->commandAI->GiveCommand(*ci);
					}
				}
				StopBuild();
			}
		}
	}

	if(lastBuild+200 < gs->frameNum && !quedBuild && opening && uh->CanCloseYard(this)){
		readmap->CloseBlockingYard(this);
		opening=false;
		cob->Call(COBFN_Deactivate);
	}
	CBuilding::Update();
}
Ejemplo n.º 3
0
void CFactory::Update()
{
	if (beingBuilt) {
		// factory under construction
		CUnit::Update();
		return;
	}

	if (quedBuild && !opening && !stunned) {
		cob->Call(COBFN_Activate);
		groundBlockingObjectMap->OpenBlockingYard(this, yardMap);
		opening = true;
	}

	if (quedBuild && inBuildStance && !stunned) {
		// start building a unit
		float3 buildPos = CalcBuildPos();

		bool canBuild = true;
		std::vector<CUnit*> units = qf->GetUnitsExact(buildPos, 16);

		for (std::vector<CUnit*>::iterator ui = units.begin(); ui != units.end(); ++ui) {
			if ((*ui) != this)
				canBuild = false;
		}

		if (canBuild) {
			quedBuild = false;
			CUnit* b = unitLoader.LoadUnit(nextBuild, buildPos + float3(0.01f, 0.01f, 0.01f), team,
											true, buildFacing, this);
			b->lineage = this->lineage;

			if (!unitDef->canBeAssisted) {
				b->soloBuilder = this;
				b->AddDeathDependence(this);
			}

			AddDeathDependence(b);
			curBuild = b;

			cob->Call("StartBuilding");

			int soundIdx = unitDef->sounds.build.getRandomIdx();
			if (soundIdx >= 0) {
				sound->PlaySample(
					unitDef->sounds.build.getID(soundIdx), pos,
					unitDef->sounds.build.getVolume(0));
			}
		} else {
			helper->BuggerOff(buildPos - float3(0.01f, 0, 0.02f), radius + 8);
		}
	}


	if (curBuild && !beingBuilt) {
		if (!stunned) {
			// factory not under construction and
			// nanolathing unit: continue building
			lastBuild = gs->frameNum;
	
			// buildPiece is the rotating platform
			const int buildPiece = GetBuildPiece();
			CMatrix44f mat = localmodel->GetPieceMatrix(buildPiece);
			const int h = GetHeadingFromVector(mat[2], mat[10]);
	
			// rotate unit nanoframe with platform
			curBuild->heading = (h + GetHeadingFromFacing(buildFacing)) & 65535;
	
			const float3 buildPos = CalcBuildPos(buildPiece);
			curBuild->pos = buildPos;
	
			if (curBuild->floatOnWater) {
				curBuild->pos.y  = ground->GetHeight(buildPos.x, buildPos.z);
				curBuild->pos.y -= curBuild->unitDef->waterline;
			}
			curBuild->midPos = curBuild->pos + (UpVector * curBuild->relMidPos.y);
	
			const CCommandQueue& queue = commandAI->commandQue;
	
			if(!queue.empty() && (queue.front().id == CMD_WAIT)) {
				curBuild->AddBuildPower(0, this);
			} else {
				if (curBuild->AddBuildPower(buildSpeed, this)) {
					CreateNanoParticle();
				}
			}
		}

		if (!curBuild->beingBuilt &&
				(!unitDef->fullHealthFactory ||
						(curBuild->health >= curBuild->maxHealth)))
		{
			if (group && curBuild->group == 0) {
				curBuild->SetGroup(group);
			}

			bool userOrders = true;
			if (curBuild->commandAI->commandQue.empty() ||
					(dynamic_cast<CMobileCAI*>(curBuild->commandAI) &&
					 ((CMobileCAI*)curBuild->commandAI)->unimportantMove)) {
				userOrders = false;
				const CFactoryCAI* facAI = (CFactoryCAI*) commandAI;
				const CCommandQueue& newUnitCmds = facAI->newUnitCommands;

				if (newUnitCmds.empty()) {
					SendToEmptySpot(curBuild);
				} else {
					// XXX the pathfinder sometimes... makes mistakes, try to hack around it
					// XXX note this qualifies as HACK HACK HACK
					float3 testpos = curBuild->pos + frontdir * (this->radius - 1.0f);
					Command c;
					c.id = CMD_MOVE;
					c.params.push_back(testpos.x);
					c.params.push_back(testpos.y);
					c.params.push_back(testpos.z);
					curBuild->commandAI->GiveCommand(c);

					for (CCommandQueue::const_iterator ci = newUnitCmds.begin(); ci != newUnitCmds.end(); ++ci) {
						c = *ci;
						c.options |= SHIFT_KEY;
						curBuild->commandAI->GiveCommand(c);
					}
				}
				waitCommandsAI.AddLocalUnit(curBuild, this);
			}
			eventHandler.UnitFromFactory(curBuild, this, userOrders);

			StopBuild();
		}
	}

	if (((lastBuild + 200) < gs->frameNum) && !stunned &&
	    !quedBuild && opening && groundBlockingObjectMap->CanCloseYard(this)) {
		// close the factory after inactivity
		groundBlockingObjectMap->CloseBlockingYard(this, yardMap);
		opening = false;
		cob->Call(COBFN_Deactivate);
	}

	CBuilding::Update();
}
Ejemplo n.º 4
0
void CFactory::Update()
{
	if(beingBuilt){
		CUnit::Update();
		return;
	}

	if(quedBuild && inBuildStance){
		float3 buildPos = CalcBuildPos();

		bool canBuild=true;
		std::vector<CUnit*> units=qf->GetUnitsExact(buildPos,16);
		for(std::vector<CUnit*>::iterator ui=units.begin();ui!=units.end();++ui){
			if((*ui)!=this)
				canBuild=false;
		}
		if(canBuild){
			quedBuild=false;
			CUnit* b=unitLoader.LoadUnit(nextBuild,buildPos+float3(0.01,0.01,0.01),team,true,buildFacing);
			AddDeathDependence(b);
			curBuild=b;

			animator->AnimAction("StartBuilding");

			if(unitDef->sounds.build.id)
				sound->PlaySound(unitDef->sounds.build.id, pos, unitDef->sounds.build.volume);
		} else {
			helper->BuggerOff(buildPos-float3(0.01,0,0.02),radius+8);
		}
	}

	if(curBuild && !beingBuilt){
		lastBuild=gs->frameNum;

		int buildPiece = GetBuildPiece();
		CMatrix44f mat=localmodel->GetPieceMatrix(buildPiece);
		int h=GetHeadingFromVector(mat[2],mat[10]);
		curBuild->heading=h;

		float3 buildPos = curBuild->pos = CalcBuildPos(buildPiece);
		if(curBuild->floatOnWater)
			curBuild->pos.y=ground->GetHeight(buildPos.x,buildPos.z)-curBuild->unitDef->waterline;
		curBuild->midPos=curBuild->pos+UpVector*curBuild->relMidPos.y;

		if(curBuild->AddBuildPower(buildSpeed,this)){
			std::vector<int> args;
			args.push_back(0);
			animator->AnimAction("QueryNanoPiece",args);

			if(unitDef->showNanoSpray){
				float3 relWeaponFirePos=localmodel->GetPiecePos(args[0]);
				float3 weaponPos=pos + frontdir*relWeaponFirePos.z + updir*relWeaponFirePos.y + rightdir*relWeaponFirePos.x;

				float3 dif=curBuild->midPos-weaponPos;
				float l=dif.Length();
				dif/=l;
				dif+=gs->randVector()*0.15f;
				float3 color= unitDef->nanoColor;
				if(gu->teamNanospray){
					unsigned char* tcol=gs->Team(team)->color;
					color = float3(tcol[0]*(1./255.),tcol[1]*(1./255.),tcol[2]*(1./255.));
				}
				new CGfxProjectile(weaponPos,dif,(int)l,color);
			}
		} else {
			if(!curBuild->beingBuilt){
				if(group)
					curBuild->SetGroup(group);
				Command c;
				c.id=CMD_MOVE_STATE;
				c.options=0;
				c.params.push_back(moveState);
				curBuild->commandAI->GiveCommand(c);
				c.params.clear();
				c.id=CMD_FIRE_STATE;
				c.params.push_back(fireState);
				curBuild->commandAI->GiveCommand(c);
				if(curBuild->commandAI->commandQue.empty() || (dynamic_cast<CMobileCAI*>(curBuild->commandAI) && ((CMobileCAI*)curBuild->commandAI)->unimportantMove)){
					if(((CFactoryCAI*)commandAI)->newUnitCommands.empty()){
						SendToEmptySpot(curBuild);
					} else {
						for(std::deque<Command>::iterator ci=((CFactoryCAI*)commandAI)->newUnitCommands.begin();ci!=((CFactoryCAI*)commandAI)->newUnitCommands.end();++ci)
							curBuild->commandAI->GiveCommand(*ci);
					}
				}
				StopBuild();
			}
		}
	}

	if(lastBuild+200 < gs->frameNum && !quedBuild && opening && uh->CanCloseYard(this)){
		readmap->CloseBlockingYard(this);
		opening=false;
		animator->AnimAction(ANIMFN_Deactivate);
	}
	CBuilding::Update();
}
Ejemplo n.º 5
0
void CFactory::AssignBuildeeOrders(CUnit* unit) {
	CCommandAI* unitCAI = unit->commandAI;
	CCommandQueue& unitCmdQue = unitCAI->commandQue;

	const CFactoryCAI* factoryCAI = static_cast<CFactoryCAI*>(commandAI);
	const CCommandQueue& factoryCmdQue = factoryCAI->newUnitCommands;

	if (factoryCmdQue.empty() && unitCmdQue.empty()) {
		SendToEmptySpot(unit);
		return;
	}

	Command c(CMD_MOVE);

	if (!unit->unitDef->canfly) {
		// HACK: when a factory has a rallypoint set far enough away
		// to trigger the non-admissable path estimators, we want to
		// avoid units getting stuck inside by issuing them an extra
		// move-order. However, this order can *itself* cause the PF
		// system to consider the path blocked if the extra waypoint
		// falls within the factory's confines, so use a wide berth.
		const float xs = unitDef->xsize * SQUARE_SIZE * 0.5f;
		const float zs = unitDef->zsize * SQUARE_SIZE * 0.5f;

		float tmpDst = 2.0f;
		float3 tmpPos = unit->pos + (frontdir * this->radius * tmpDst);

		if (buildFacing == FACING_NORTH || buildFacing == FACING_SOUTH) {
			while ((tmpPos.z >= unit->pos.z - zs && tmpPos.z <= unit->pos.z + zs)) {
				tmpDst += 0.5f;
				tmpPos = unit->pos + (frontdir * this->radius * tmpDst);
			}
		} else {
			while ((tmpPos.x >= unit->pos.x - xs && tmpPos.x <= unit->pos.x + xs)) {
				tmpDst += 0.5f;
				tmpPos = unit->pos + (frontdir * this->radius * tmpDst);
			}
		}

		c.PushPos(tmpPos.cClampInBounds());
	} else {
		// dummy rallypoint for aircraft
		c.PushPos(unit->pos);
	}

	if (unitCmdQue.empty()) {
		unitCAI->GiveCommand(c);

		// copy factory orders for new unit
		for (CCommandQueue::const_iterator ci = factoryCmdQue.begin(); ci != factoryCmdQue.end(); ++ci) {
			Command c = *ci;
			c.options |= SHIFT_KEY;

			if (c.GetID() == CMD_MOVE) {
				const float3 p1 = c.GetPos(0);
				const float3 p2 = float3(p1.x + gs->randFloat() * TWOPI, p1.y, p1.z + gs->randFloat() * TWOPI);
				// apply a small amount of random jitter to move commands
				// such that new units do not all share the same goal-pos
				// and start forming a "trail" back to the factory exit
				c.SetPos(0, p2);
			}

			unitCAI->GiveCommand(c);
		}
	} else {
		unitCmdQue.push_front(c);
	}
}