示例#1
0
文件: Factory.cpp 项目: Finkky/spring
void CFactory::StartBuild(const UnitDef* buildeeDef) {
	const float3& buildPos = CalcBuildPos();
	const bool blocked = groundBlockingObjectMap->GroundBlocked(buildPos, this);

	// wait until buildPos is no longer blocked (eg. by a previous buildee)
	//
	// it might rarely be the case that a unit got stuck inside the factory
	// or died right after completion and left some wreckage, but that is up
	// to players to fix (we no longer broadcast BuggerOff directives, since
	// those are indiscriminate and ineffective)
	if (blocked)
		return;

	CUnit* b = unitLoader->LoadUnit(buildeeDef, buildPos, team, true, buildFacing, this);

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

	AddDeathDependence(b, DEPENDENCE_BUILD);
	script->StartBuilding();

	// set curBuildDef to NULL to indicate construction
	// has started, otherwise we would keep being called
	curBuild = b;
	curBuildDef = NULL;

	#if (PLAY_SOUNDS == 1)
	if (losStatus[gu->myAllyTeam] & LOS_INLOS) {
		Channels::General.PlayRandomSample(unitDef->sounds.build, buildPos);
	}
	#endif
}
示例#2
0
文件: Factory.cpp 项目: Finkky/spring
void CFactory::UpdateBuild(CUnit* buildee) {
	if (stunned)
		return;

	// factory not under construction and
	// nanolathing unit: continue building
	lastBuildUpdateFrame = gs->frameNum;

	// buildPiece is the rotating platform
	const int buildPiece = GetBuildPiece();
	const float3& buildPos = CalcBuildPos(buildPiece);
	const CMatrix44f& mat = script->GetPieceMatrix(buildPiece);
	const int h = GetHeadingFromVector(mat[2], mat[10]); //! x.z, z.z

	float3 buildeePos = buildPos;

	// rotate unit nanoframe with platform
	buildee->heading = (-h + GetHeadingFromFacing(buildFacing)) & (SPRING_CIRCLE_DIVS - 1);

	if (buildee->unitDef->floatOnWater && (buildeePos.y <= 0.0f))
		buildeePos.y = -buildee->unitDef->waterline;

	buildee->Move3D(buildeePos, false);
	buildee->UpdateDirVectors(false);
	buildee->UpdateMidAndAimPos();

	const CCommandQueue& queue = commandAI->commandQue;

	if (!queue.empty() && (queue.front().GetID() == CMD_WAIT)) {
		buildee->AddBuildPower(0, this);
	} else {
		if (buildee->AddBuildPower(buildSpeed, this)) {
			CreateNanoParticle();
		}
	}
}
示例#3
0
文件: Factory.cpp 项目: eXLabT/spring
void CFactory::Update()
{
	if (beingBuilt) {
		// factory under construction
		CUnit::Update();
		return;
	}

	if (quedBuild && !opening && !stunned) {
		script->Activate();
		groundBlockingObjectMap->OpenBlockingYard(this, curYardMap);
		opening = true;
	}

	if (quedBuild && inBuildStance && !stunned) {
		// start building a unit
		const float3        buildPos = CalcBuildPos();
		const CSolidObject* solidObj = groundBlockingObjectMap->GroundBlocked(buildPos);

		if (solidObj == NULL || (dynamic_cast<const CUnit*>(solidObj) == this)) {
			quedBuild = false;
			CUnit* b = unitLoader.LoadUnit(nextBuild, buildPos + float3(0.01f, 0.01f, 0.01f), team,
											true, buildFacing, this);

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

			AddDeathDependence(b);
			curBuild = b;

			script->StartBuilding();

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


	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();
			const CMatrix44f& mat = script->GetPieceMatrix(buildPiece);
			const int h = GetHeadingFromVector(mat[2], mat[10]); //! x.z, z.z

			// rotate unit nanoframe with platform
			curBuild->heading = (h + GetHeadingFromFacing(buildFacing)) & 65535;

			const float3 buildPos = CalcBuildPos(buildPiece);
			curBuild->pos = buildPos;

			if (curBuild->floatOnWater) {
				float waterline = ground->GetHeight(buildPos.x, buildPos.z) - curBuild->unitDef->waterline;
				if (waterline > curBuild->pos.y)
					curBuild->pos.y = 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;

				AssignBuildeeOrders(curBuild);
				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, curYardMap);
		opening = false;
		script->Deactivate();
	}

	CBuilding::Update();
}
示例#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();
}
示例#5
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();
}