CoreScript* LumosChitBag::TakeOverCore(const Vector2I& sector, Chit* conquerer)
{
	int conqueringTeam = conquerer->Team();
	int teamID = Team::Instance()->GenTeam(Team::Group(conqueringTeam));
	bool isSubDomain = !Team::IsRogue(conqueringTeam);

	if (isSubDomain) {
		Team::Instance()->AddSubteam(conqueringTeam, teamID);
	}
	CoreScript* newCore = CoreScript::CreateCore(sector, teamID, Context());
	GLASSERT(CoreScript::GetCore(sector) == newCore);
	newCore->ParentChit()->Add(DomainAI::Factory(teamID));

	CDynArray<Chit*> arr;
	// After takeover, all the citizens are rogue and buildings are neutral.
	// As a first pass, simply takeover everything that meets that criteria.

	ChitAcceptAll filter;
	BuildingFilter buildingFilter;
	Context()->chitBag->QuerySpatialHash(&arr, InnerSectorBounds(sector), 0, &filter);

	for (Chit* c : arr) {
		if (c->PlayerControlled()) 
			continue;
		GameItem* mainItem = c->GetItem();
		if (!mainItem) 
			continue;

		if (mainItem->IsDenizen() && Team::IsRogue(mainItem->Team())) {
			newCore->AddCitizen(c);
		}
		else if (buildingFilter.Accept(c) && mainItem->IName() != ISC::core) {
			c->GetItem()->SetTeam(teamID);
		}
	}
	// Finally, give this new core a chance. 
	// Transfer money from Conquering domain.
	CoreScript* conqueringCore = CoreScript::GetCoreFromTeam(conquerer->Team());
	if (conqueringCore) {
		int gold = conqueringCore->ParentChit()->GetWallet()->Gold() / 4;
		gold = Min(gold, GOLD_XFER_TAKEOVER);
		newCore->ParentChit()->GetWallet()->Deposit(conqueringCore->ParentChit()->GetWallet(), gold);
	}

	NewsEvent news(isSubDomain ? NewsEvent::DOMAIN_CONQUER : NewsEvent::DOMAIN_TAKEOVER,
				   ToWorld2F(newCore->ParentChit()->Position()),
				   newCore->ParentChit()->GetItemID(),
				   conquerer->GetItemID());
	Context()->chitBag->GetNewsHistory()->Add(news);

	return newCore;
}
bool MOBIshFilter::Accept(Chit* chit)
{
	// If it can move and has a team...?
	// Mostly a good metric. Doesn't account for dummy targets.
	PathMoveComponent* pmc = GET_SUB_COMPONENT(chit, MoveComponent, PathMoveComponent);
	if (pmc && chit->Team()) {
		return RelationshipFilter::Accept(chit);
	}
	GameItem* item = chit->GetItem();
	if (item && item->IName() == ISC::dummyTarget) {
		return RelationshipFilter::Accept(chit);
	}
	return false;
}
Exemple #3
0
void RebuildAIComponent::OnChitMsg(Chit* chit, const ChitMsg& msg)
{
	if (   msg.ID() == ChitMsg::CHIT_DESTROYED 
		&& (chit != ParentChit())
		&& ToSector(chit->Position()) == ToSector(ParentChit()->Position())
		&& chit->Team() == this->ParentChit()->Team())
	{
		BuildingFilter buildingFilter;
		if (buildingFilter.Accept(chit))
		{
			GameItem* gi = chit->GetItem();
			WorkItem* wi = workItems.PushArr(1);
			wi->structure = gi->IName();
			MapSpatialComponent* msc = GET_SUB_COMPONENT(chit, SpatialComponent, MapSpatialComponent);
			if (msc) {
				wi->pos = msc->Bounds().min;
				wi->rot = LRint(YRotation(chit->Rotation()));
				GLOUTPUT(("ReBuild: Structure %s at %d,%d r=%d to rebuild queue.\n", wi->structure.safe_str(), wi->pos.x, wi->pos.y, int(wi->rot)));
			}
		}
	}
	super::OnChitMsg(chit, msg);
}