Пример #1
0
bool CoreScript::IsSquaddieOnMission(int chitID, int* squadID, Vector2I* wantToConquer)
{
	if (!CitizenFilter(chitID)) {
		return false;
	}
	for (int i = 0; i < MAX_SQUADS; ++i) {
		if (squads[i].Find(chitID) >= 0) {
			if (squadID) {
				*squadID = i;
			}
			if (wantToConquer) {
				wantToConquer->Zero();
				if (!waypoints[i].Empty()) {
					Vector2I waypoint2i = waypoints[i][waypoints[i].Size() - 1];
					Vector2I waypointSector = ToSector(waypoint2i);
					const SectorData& sd = Context()->worldMap->GetSectorData(waypointSector);
					if (sd.CoreLoc() == waypoint2i) {
						*wantToConquer = waypointSector;
					}
				}
			}
			Chit* chit = Context()->chitBag->GetChit(chitID);
			return !waypoints[i].Empty() || (ToSector(chit->Position()) != ToSector(ParentChit()->Position()));
		}
	}
	return false;
}
Пример #2
0
void CoreScript::OnChitMsg(Chit* chit, const ChitMsg& msg)
{
	// Logic split between Sim::OnChitMsg and CoreScript::OnChitMsg
	if (msg.ID() == ChitMsg::CHIT_DESTROYED && (chit == parentChit)) {
		while (!citizens.Empty()) {
			int citizenID = citizens.Pop();
			Chit* citizen = Context()->chitBag->GetChit(citizenID);
			if (citizen && citizen->GetItem()) {
				// Set to rogue team.
				citizen->GetItem()->SetRogue();
			}
		}

		Vector2I pos2i = ToWorld2I(chit->Position());
		Vector2I sector = ToSector(pos2i);

		if (Team::Instance()->IsController(chit->Team())) {
			NewsEvent news(NewsEvent::SUPERTEAM_DELETED, ToWorld2F(pos2i), chit->GetItemID(), 0);
			Context()->chitBag->GetNewsHistory()->Add(news);
		}
		int controllerTeam = 0;
		if (Team::Instance()->IsControlled(chit->Team(), &controllerTeam)) {
			CoreScript* controller = CoreScript::GetCoreFromTeam(controllerTeam);
			GLASSERT(controller);
			if (controller) {
				NewsEvent news(NewsEvent::SUBTEAM_DELETED, ToWorld2F(pos2i), chit->GetItemID(), controller->ParentChit()->GetItemID());
				Context()->chitBag->GetNewsHistory()->Add(news);
			}
		}

		int deleterID = chit->GetItemComponent() ? chit->GetItemComponent()->LastDamageID() : 0;
		Chit* deleter = Context()->chitBag->GetChit(deleterID);
		int superTeam = 0;
		if (deleter
			&& (deleter->Team() == Team::Instance()->SuperTeam(deleter->Team()))
			&& Team::IsDenizen(deleter->Team())
			&& Team::IsDenizen(chit->Team()))
		{
			superTeam = deleter->Team();
		}

		if (chit->Team() != TEAM_NEUTRAL) {
			if (superTeam) {
				LumosChitBag::CreateCoreData data = { sector, true, chit->Team(), deleter ? deleter->Team() : 0 };
				Context()->chitBag->coreCreateList.Push(data);
			}
			else {
				LumosChitBag::CreateCoreData data = { sector, false, chit->Team(), deleter ? deleter->Team() : 0 };
				Context()->chitBag->coreCreateList.Push(data);
			}
		}
		else {
			// Neutral cores are taken over by wandering over them
			// with enough friend units to have critical mass.
			LumosChitBag::CreateCoreData data = { sector, false, 0, 0 };
			Context()->chitBag->coreCreateList.Push(data);
		}
		Team::Instance()->CoreDestroyed(parentChit->Team());
	}
}
Пример #3
0
int CoreScript::Citizens(CChitArray* arr)
{
	int i=0;

	while (i < citizens.Size()) {
		int id = citizens[i];
		Chit* chit = CitizenFilter(id);
		if (chit) {	// check for team change, throw out of citizens.
			if (arr) arr->Push(chit);
			++i;
		}
		else {
			// Dead and gone.
			citizens.SwapRemove(i);
			// Reset the timer so that there is a little time
			// between a dead citizen and re-spawn
			spawnTick.Reset();
		}
	}
#if 0
	// This is annoying: seeing if cranking down the spawn rate and not
	// destroying the sleep tube achieves success.
	// Also, destroy a sleeptube, so it costs something to replace, and towns can fall.
	if ( sc ) {
		Vector2F pos2 = sc->GetPosition2D();
		Vector2I sector = ToSector( ToWorld2I( pos2 ));
		Chit* bed = scriptContext->chitBag->FindBuilding( ISC::bed, sector, &pos2, LumosChitBag::RANDOM_NEAR, 0, 0 );
		if ( bed && bed->GetItem() ) {
			bed->GetItem()->hp = 0;
			bed->SetTickNeeded();
		}
	}
#endif
	return citizens.Size();
}
Пример #4
0
Chit* LumosChitBag::FindBuilding(	const grinliz::IString&  name, 
									const grinliz::Vector2I& sector, 
									const grinliz::Vector2F* pos, 
									LumosChitBag::EFindMode flags,
									CDynArray<Chit*>* arr,
									IChitAccept* filter )
{
	CDynArray<Chit*>& match = arr ? *arr : findMatch;	// sleazy reference trick to point to either passed in or local.
	match.Clear();
	findWeight.Clear();

	for( MapSpatialComponent* it = mapSpatialHash[sector.y*NUM_SECTORS+sector.x]; it; it = it->nextBuilding ) {
		Chit* chit = it->ParentChit();
		GLASSERT( chit );
		if ( filter && !filter->Accept( chit )) {				// if a filter, check it.
			continue;
		}

		const GameItem* item = chit->GetItem();

		if ( item && ( name.empty() || item->IName() == name )) {	// name, if empty, matches everything
			match.Push( chit );
		}
	}

	// If we found nothing, or we don't care about the position, return early.
	// Else deal with choice / sorting / etc. below.
	if ( match.Empty() )
		return 0;
	if ( !pos )
		return match[0];

	// NEAREST scans and finds the closest one.
	// RANDOM_NEAR chooses one at random, but weighted by the (inverse) of the distance
	if ( flags == EFindMode::NEAREST ) {
		float closest = ( ToWorld2F(match[0]->Position()) - *pos ).LengthSquared();
		int   ci = 0;
		for( int i=1; i<match.Size(); ++i ) {
			float len2 = ( ToWorld2F(match[i]->Position()) - *pos ).LengthSquared();
			if ( len2 < closest ) {
				closest = len2;
				ci = i;
			}
		}
		return match[ci];
	}
	if ( flags == EFindMode::RANDOM_NEAR ) {
		for( int i=0; i<match.Size(); ++i ) {
			float len = ( ToWorld2F(match[i]->Position()) - *pos ).Length();
			if (len < 1) len = 1;
			findWeight.Push( 1.0f/len );
		}
		int index = random.Select( findWeight.Mem(), findWeight.Size() );
		return match[index];
	}

	// Bad flag? Something didn't return?
	GLASSERT( 0 );
	return 0;
}
Пример #5
0
int CameraComponent::DoTick(U32 delta)
{
	float EASE = 0.2f;

	switch (mode) {

		case PAN:
		{
			Vector3F d = (dest - camera->PosWC());
			Vector3F c = camera->PosWC();

			if (d.Length() < 0.01f) {
				camera->SetPosWC(dest.x, dest.y, dest.z);
				mode = DONE;
			}
			else {
				camera->SetPosWC(c.x + EASE*d.x, c.y + EASE*d.y, c.z + EASE*d.z);
			}
		}
		break;

		case TRACK:
		{
			Chit* chit = Context()->chitBag->GetChit(targetChitID);
			if (chit) {

				Vector3F pos = chit->Position();
				pos.y = 0;

				// Scoot the camera to always focus on the target. Removes
				// errors that occur from rotation, drift, etc.
				const Vector3F* eye3 = camera->EyeDir3();
				Vector3F at;
				int result = IntersectRayPlane(camera->PosWC(), eye3[0], 1, 0.0f, &at);
				if (result == INTERSECT) {
					Vector3F t = (camera->PosWC() - at);

					//camera->SetPosWC( pos + t );
					Vector3F c = camera->PosWC();
					Vector3F d = (pos + t) - c;

					// If grid moving, the EASE contributes to jitter.
					if (GET_SUB_COMPONENT(chit, MoveComponent, GridMoveComponent)) {
						EASE = 1.0f;
					}
					camera->SetPosWC(c.x + EASE*d.x, pos.y + t.y, c.z + EASE*d.z);
				}
			}
		}
		break;

		case DONE:
		break;

		default:
		GLASSERT(0);
	}
	return 0;
}
Пример #6
0
Chit* CoreScript::CitizenFilter(int chitID)
{
	Chit* chit = Context()->chitBag->GetChit(chitID);
	if (chit && (chit->Team() == parentChit->Team())) {
		return chit;
	}
	return 0;
}
Пример #7
0
Chit* LumosChitBag::NewGoldChit( const grinliz::Vector3F& pos, Wallet* src )
{
	GLASSERT(src);
	if (src->Gold() == 0) return 0;

	const ChitContext* context = Context();

	Vector2F v2 = { pos.x, pos.z };

	ItemNameFilter goldFilter( ISC::gold);
	this->QuerySpatialHash( &chitList, v2, 1.0f, 0, &goldFilter );
	Chit* chit = 0;

	// Evil bug this: adding gold to a wallet just before
	// deletion. I'm a little concerned where else
	// this could be a problem. Would be nice to make
	// deletion immediate.
	for (int i = 0; i < chitList.Size(); ++i) {
		Chit* c = chitList[i];
		if (c && !IsQueuedForDelete(c) && c->GetWallet() && !c->GetWallet()->Closed()) {
			chit = chitList[i];
			break;
		}
	}

	if ( !chit ) {
		chit = this->NewChit();
		AddItem( "gold", chit, context->engine, 0, 0 );
		chit->Add( new RenderComponent( chit->GetItem()->ResourceName() ));
		chit->SetPosition( pos );
		chit->Add(new GameMoveComponent());
	}
	chit->GetWallet()->Deposit(src, src->Gold());
	return chit;
}
Пример #8
0
int CoreScript::CorePower()
{
	int power = 0;
	for (int i = 0; i < citizens.Size(); ++i) {
		Chit* chit = Context()->chitBag->GetChit(citizens[i]);
		if (chit && chit->GetItemComponent()) {
			power += chit->GetItemComponent()->PowerRating(true);
		}
	}
	return power;
}
Пример #9
0
CameraComponent* LumosChitBag::GetCamera() const
{
	Chit* chit = GetNamedChit(ISC::Camera);
	if (chit) {
		GLASSERT(chit);
		CameraComponent* cc = (CameraComponent*) chit->GetComponent("CameraComponent");
		GLASSERT(cc);
		return cc;
	}
	return 0;
}
Пример #10
0
bool CoreScript::IsCitizenItemID(int id)
{
	for (int i = 0; i < citizens.Size(); ++i) {
		int citizenID = citizens[i];
		Chit* chit = CitizenFilter(citizenID);
		if (chit && chit->GetItemID() == id) {
			return true;
		}
	}
	return false;
}
Пример #11
0
void CoreScript::NewWaypointChits(int id)
{
	for (int i = 0; i < waypoints[id].Size(); ++i) {
		Vector2I v = waypoints[id][i];
		Chit* chit = Context()->chitBag->NewChit();
		chit->Add(new RenderComponent("flag"));
		FlagScript* flagScript = new FlagScript();
		flagScript->Attach(ToSector(parentChit->Position()), id);
		chit->Add(flagScript);
		chit->SetPosition(ToWorld3F(v));
	}
}
Пример #12
0
Chit* CoreScript::PrimeCitizen()
{
	for (int i = 0; i < citizens.Size(); ++i) {
		int id = citizens[i];
		Chit* chit = CitizenFilter(id);
		if (chit && chit->GetItem()) {
			if (chit->GetItem()->keyValues.Has(ISC::prime)) {
				return chit;
			}
		}
	}
	return 0;
}
Пример #13
0
void CoreScript::RemoveFlag(const Vector2I& pos)
{
	Flag f = { pos, 0 };
	int i = flags.Find(f);
	if (i >= 0) {
		if (flags[i].chitID) {
			Chit* chit = Context()->chitBag->GetChit(flags[i].chitID);
			if (chit) {
				chit->QueueDelete();
			}
			flags[i].chitID = 0;
		}
		flags.Remove(i);
	}
}
Пример #14
0
void LumosChitBag::HandleBolt( const Bolt& bolt, const ModelVoxel& mv )
{
	const ChitContext* context = Context();
	Chit* chitShooter = GetChit( bolt.chitID );	// may be null
	int shooterTeam = -1;
	if ( chitShooter && chitShooter->GetItemComponent() ) {
		shooterTeam = chitShooter->GetItemComponent()->GetItem()->Team();
	}
	int explosive = bolt.effect & GameItem::EFFECT_EXPLOSIVE;
 
	if ( !explosive ) {
		if ( mv.Hit() ) {
			Chit* chitHit = mv.ModelHit() ? mv.model->userData : 0;
			DamageDesc dd( bolt.damage, bolt.effect );

			if ( chitHit ) {
				GLASSERT( GetChit( chitHit->ID() ) == chitHit );
				if ( chitHit->GetItemComponent() &&
					 chitHit->GetItemComponent()->GetItem()->Team() == shooterTeam ) 
				{
					// do nothing. don't shoot own team.
				}
				else {
		
					ChitDamageInfo info( dd );
					info.originID = bolt.chitID;
					info.awardXP  = true;
					info.isMelee  = false;
					info.isExplosion = false;
					info.originOfImpact = mv.at;

					ChitMsg msg( ChitMsg::CHIT_DAMAGE, 0, &info );
					chitHit->SendMessage( msg, 0 );
				}
			}
			else if ( mv.VoxelHit() ) {
				context->worldMap->VoxelHit( mv.voxel, dd );
			}
		}
	}
	else {
		// How it used to work. Now only uses radius:
			// Here don't worry about the chit hit. Just ray cast to see
			// who is in range of the explosion and takes damage.
		
			// Back up the origin of the bolt just a bit, so it doesn't keep
			// intersecting the model it hit. Then do ray checks around to 
			// see what gets hit by the explosion.

		float rewind = Min( 0.1f, 0.5f*bolt.len );
		GLASSERT( Equal( bolt.dir.Length(), 1.f, 0.001f ));
		Vector3F origin = mv.at - bolt.dir * rewind;

		DamageDesc dd( bolt.damage, bolt.effect );
		BattleMechanics::GenerateExplosion( dd, origin, bolt.chitID, context->engine, this, context->worldMap );
	}
}
Пример #15
0
bool CoreScript::SquadAtRest(int squadID)
{
	GLASSERT(squadID >= 0 && squadID < MAX_SQUADS);
	if (!waypoints[squadID].Empty()) {
		return false;
	}

	Vector2I sector = ToSector(ParentChit()->Position());
	for (int i = 0; i < squads[squadID].Size(); ++i) {
		int chitID = squads[squadID][i];
		Chit* chit = Context()->chitBag->GetChit(chitID);
		if (chit && ToSector(chit->Position()) != sector) {
			return false;
		}
	}
	return true;
}
Пример #16
0
void CoreScript::AddFlag(const Vector2I& _pos)
{
	Vector2I pos = _pos;
	// A little UI fixup: set the flag to a porch
	// if we click on the switch.
	Chit* building = Context()->chitBag->QueryBuilding(IString(), pos, 0);
	if (building && (building->GetItem()->IName() == ISC::switchOn || building->GetItem()->IName() == ISC::switchOff)) {
		MapSpatialComponent* msc = GET_SUB_COMPONENT(building, SpatialComponent, MapSpatialComponent);
		if (msc) {
			pos = msc->PorchPos().min;
		}
	}

	Flag f = { pos, 0 };
	if (flags.Find(f) < 0) {
		Chit* chit = Context()->chitBag->NewChit();
		RenderComponent* rc = new RenderComponent("flag");
		chit->Add(rc);
		ProcRenderInfo info;
		AssignProcedural(ISC::team,
							false,
							ParentChit()->GetItem()->ID(),
							ParentChit()->Team(),
							false,
							0,
							0,
							&info);
		rc->SetProcedural(0, info);
		chit->SetPosition(ToWorld3F(pos));
		f.chitID = chit->ID();
		flags.Push(f);
	}
}
Пример #17
0
Chit* LumosChitBag::NewVisitor( int visitorIndex, const Web& web)
{
	const ChitContext* context = Context();
	if (web.Empty()) return 0;

	Vector2I startSector = { NUM_SECTORS / 2, NUM_SECTORS / 2 };
	CoreScript* cs = CoreScript::GetCore(startSector);
	if (!cs) return 0;	// cores get deleted, web is cached, etc.
	Vector3F pos = cs->ParentChit()->Position();

	Chit* chit = NewChit();
	const GameItem& rootItem = ItemDefDB::Instance()->Get( "visitor" );

	chit->Add( new RenderComponent( rootItem.ResourceName() ));

	AIComponent* ai = new AIComponent();
	chit->Add( ai );
	GLASSERT( visitorIndex >= 0 && visitorIndex < Visitors::NUM_VISITORS );
	ai->SetVisitorIndex( visitorIndex );
	Visitors::Instance()->visitorData[visitorIndex].Connect();	// initialize.

	// Visitors start at world center, with gridMove, and go from there.
	chit->SetPosition( pos );

	PathMoveComponent* pmc = new PathMoveComponent();
	chit->Add(pmc);

	AddItem( rootItem.Name(), chit, context->engine, TEAM_VISITOR, 0 );
	chit->Add( new HealthComponent());
	//chit->Add( new VisitorStateComponent());
	return chit;
}
Пример #18
0
bool CoreScript::RecruitNeutral()
{
	Vector2I sector = ToSector(parentChit->Position());
	Rectangle2I inner = InnerSectorBounds(sector);

	MOBKeyFilter filter;
	filter.value = ISC::denizen;
	CChitArray arr;
	Context()->chitBag->QuerySpatialHash(&arr, ToWorld2F(inner), 0, &filter);

	for (int i = 0; i < arr.Size(); ++i) {
		Chit* chit = arr[i];
		if (Team::Instance()->GetRelationship(chit, parentChit) != ERelate::ENEMY) {
			if (this->IsCitizen(chit)) continue;
			if (!chit->GetItem()) continue;

			if (Team::IsRogue(chit->Team())) {
				// ronin! denizen without a core.
				this->AddCitizen( chit );
				GLASSERT(chit->GetItem()->Significant());

				NewsEvent news(NewsEvent::ROGUE_DENIZEN_JOINS_TEAM, ToWorld2F(chit->Position()), chit->GetItemID(), 0);
				Context()->chitBag->GetNewsHistory()->Add(news);
				return true;
			}
		}
	}
	return false;
}
Пример #19
0
SectorPort Visitors::ChooseDestination(int index, const Web& web, ChitBag* chitBag, WorldMap* map )
{
	GLASSERT( instance );
	GLASSERT( index >=0 && index <NUM_VISITORS );
	VisitorData* visitor = &visitorData[index];
	Chit* visitorChit = chitBag->GetChit(visitor->id);

	SectorPort sectorPort;
	if (!visitorChit) return sectorPort;

	Vector2I thisSector = ToSector(visitorChit->Position());
	const MinSpanTree::Node* node = web.FindNode(thisSector);
	if (!node || node->firstChild == 0)
		return sectorPort;

	int nChildren = web.CountChildren(*node);
	int which = random.Rand(nChildren);
	const MinSpanTree::Node* child = web.ChildNode(*node, which);
	Vector2I sector = child->pos;

	const SectorData& sd = map->GetSectorData( sector );
	GLASSERT(sd.ports);
	if (!sd.ports) 
		return sectorPort;

	int ports[4] = { 1, 2, 4, 8 };
	int port = 0;

	random.ShuffleArray( ports, 4 );
	for( int i=0; i<4; ++i ) {
		if ( sd.ports & ports[i] ) {
			port = ports[i];
			break;
		}
	}
	sectorPort.sector = sector;
	sectorPort.port   = port;
	return sectorPort;
}
Пример #20
0
void LumosChitBag::BuildingCounts(const Vector2I& sector, int* counts, int n)
{
	BuildScript buildScript;

	for( MapSpatialComponent* it = mapSpatialHash[sector.y*NUM_SECTORS+sector.x]; it; it = it->nextBuilding ) {
		Chit* chit = it->ParentChit();
		GLASSERT( chit );

		const GameItem* item = chit->GetItem();
		if (!item)
			continue;
		const IString& name = item->IName();

		int id = 0;
		if (!name.empty()) {
			buildScript.GetDataFromStructure(name, &id);
			if (id < n) {
				counts[id] += 1;
			}
		}
	}
}
Пример #21
0
void CoreScript::SetWaypoints(int squadID, const grinliz::Vector2I& dest)
{
	GLASSERT(squadID >= 0 && squadID < MAX_SQUADS);
	waypoints[squadID].Clear();
	if (dest.IsZero()) {
		return;
	}

	// Use the first chit to choose the starting location:
	bool startInSameSector = true;
	Vector2I startSector = { 0, 0 };
	CChitArray chitArr;
	Squaddies(squadID, &chitArr);
	if (chitArr.Empty()) return;

	for (int i = 0; i<chitArr.Size(); ++i) {
		Chit* chit = chitArr[i];
		if (startSector.IsZero())
			startSector = ToSector(chit->Position());
		else
			if (startSector != ToSector(chit->Position()))
				startInSameSector = false;
	}

	Vector2I destSector = ToSector(dest);

	// - Current port
	// - grid travel (implies both sector and target port)
	// - dest port (regroup)
	// - destination

	GLOUTPUT(("SetWaypoints: #chits=%d squadID=%d:", chitArr.Size(), squadID));

	if (startSector != destSector) {
		Chit* chit = chitArr[0];
		SectorPort sectorPort;

		if (startInSameSector) {
			// All together, so meet at the STARTING port.
			sectorPort = Context()->worldMap->NearestPort(ToWorld2F(chit->Position()), &ToWorld2F(dest));
		}
		else {
			// Dispersed; meet at the DESTINATION port.
			sectorPort = Context()->worldMap->NearestPort(ToWorld2F(dest), &ToWorld2F(chit->Position()));
		}
		if (!sectorPort.IsValid()) {
			GLOUTPUT(("SetWaypoints: no path.\n"));
			return;
		}
		SectorData sectorData = Context()->worldMap->GetSectorData(sectorPort.sector);
		Vector2I p0 = sectorData.GetPortLoc(sectorPort.port).Center();
		waypoints[squadID].Push(p0);
		GLOUTPUT(("%d,%d [s%c%d]  ", p0.x, p0.y, 'A' + p0.x / SECTOR_SIZE, 1 + p0.y / SECTOR_SIZE));
	}
	GLOUTPUT(("%d,%d [s%c%d]\n", dest.x, dest.y, 'A' + dest.x/SECTOR_SIZE, 1 + dest.y/SECTOR_SIZE));
	waypoints[squadID].Push(dest);
	NewWaypointChits(squadID);
}
Пример #22
0
Chit* LumosChitBag::QueryBuilding( const IString& name, const grinliz::Rectangle2I& bounds, CChitArray* arr )
{
	GLASSERT( MAX_BUILDING_SIZE == 2 );	// else adjust logic
	Vector2I sector = ToSector( bounds.min );

	for( MapSpatialComponent* it = mapSpatialHash[SectorIndex(sector)]; it; it = it->nextBuilding ) {
		if ( it->Bounds().Intersect( bounds )) {
			Chit* chit = it->ParentChit();
			if (name.empty() || (chit->GetItem() && chit->GetItem()->IName() == name)) {
				if (!arr) {
					return chit;
				}
				if (arr->HasCap()) {
					arr->Push(chit);
				}
			}
		}
	}
	if (arr && !arr->Empty()) {
		return (*arr)[0];
	}
	return 0;
}
Пример #23
0
Chit* LumosChitBag::NewItemChit( const grinliz::Vector3F& _pos, GameItem* orphanItem, bool fuzz, bool onGround, int selfDestructTimer )
{
	GLASSERT( !orphanItem->Intrinsic() );
	GLASSERT( !orphanItem->IResourceName().empty() );

	Vector3F pos = _pos;
	if ( fuzz ) {
		pos.x = floorf(pos.x) + random.Uniform();
		pos.z = floorf(pos.z) + random.Uniform();
	}

	Chit* chit = this->NewChit();
	chit->Add( new ItemComponent( orphanItem ));
	chit->Add( new RenderComponent( orphanItem->ResourceName() ));
	chit->Add(new GameMoveComponent());

	if ( onGround ) {
		const ModelResource* res = chit->GetRenderComponent()->MainResource();
		Rectangle3F aabb = res->AABB();
		pos.y = -aabb.min.y;

		if ( aabb.SizeY() < 0.1f ) {
			pos.y += 0.1f;
		}
	}
	chit->SetPosition( pos );
	chit->Add( new HealthComponent());

	if (!selfDestructTimer && orphanItem->keyValues.Has(ISC::selfDestruct)) {
		orphanItem->keyValues.Get("selfDestruct", &selfDestructTimer);
		selfDestructTimer *= 1000;
	}
	if ( selfDestructTimer ) {
		chit->Add( new CountDownScript( selfDestructTimer ));
	}
	return chit;
}
Пример #24
0
Chit* LumosChitBag::NewLawnOrnament(const Vector2I& pos, const char* name, int team)
{
	const ChitContext* context = Context();
	Chit* chit = NewChit();

	GameItem* rootItem = ItemDefDB::Instance()->Get(name).Clone();

	// Hack...how to do this better??
	if (rootItem->IResourceName() == "ruins1.0") {
		CStr<32> str;
		str.Format("ruins1.%d", random.Rand(2));
		rootItem->SetResource(str.c_str());
	}

	int size = 1;
	rootItem->keyValues.Get(ISC::size, &size);

	MapSpatialComponent* msc = new MapSpatialComponent();
	msc->SetBuilding(size, false, 0);
	msc->SetBlocks((rootItem->flags & GameItem::PATH_NON_BLOCKING) ? false : true);
	chit->Add(msc);
	MapSpatialComponent::SetMapPosition(chit, pos.x, pos.y);


	chit->Add(new RenderComponent(rootItem->ResourceName()));
	chit->Add(new HealthComponent());
	AddItem(rootItem, chit, context->engine, team, 0);

	IString proc = rootItem->keyValues.GetIString("procedural");
	if (!proc.empty()) {
		ProcRenderInfo info;
		AssignProcedural(chit->GetItem(), &info);
		chit->GetRenderComponent()->SetProcedural(0, info);
	}
	
	context->engine->particleSystem->EmitPD(ISC::constructiondone, ToWorld3F(pos), V3F_UP, 0);

	if (XenoAudio::Instance()) {
		Vector3F pos3 = ToWorld3F(pos);
		XenoAudio::Instance()->PlayVariation(ISC::rezWAV, random.Rand(), &pos3);
	}

	return chit;
}
Пример #25
0
Chit* LumosChitBag::NewWorkerChit( const Vector3F& pos, int team )
{
	const ChitContext* context = Context();
	Chit* chit = NewChit();
	const GameItem& rootItem = ItemDefDB::Instance()->Get( "worker" );

	chit->Add( new RenderComponent( rootItem.ResourceName() ));
	chit->Add( new PathMoveComponent());
	chit->Add( new AIComponent());
	chit->SetPosition( pos );
	AddItem( rootItem.Name(), chit, context->engine, team, 0 );
	chit->Add( new HealthComponent());
	//chit->Add( new DebugStateComponent());

	if (XenoAudio::Instance()) {
		XenoAudio::Instance()->PlayVariation(ISC::rezWAV, random.Rand(), &pos);
	}
	return chit;
}
Пример #26
0
Chit* LumosChitBag::NewWildFruit(const grinliz::Vector2I& pos)
{
	Vector3F pos3 = ToWorld3F(pos);
	pos3.x = floorf(pos3.x) + random.Uniform();
	pos3.z = floorf(pos3.z) + random.Uniform();

	const GameItem& root = ItemDefDB::Instance()->Get("fruit");
	GameItem* item = root.Clone();
	item->SetProperName(ISC::wildFruit);

	Chit* chit = this->NewChit();
	chit->Add(new ItemComponent(item));
	chit->Add(new RenderComponent(item->ResourceName()));
	chit->Add(new GameMoveComponent());
	chit->Add(new HealthComponent());

	chit->SetPosition(pos3);
	return chit;
}
Пример #27
0
Chit* LumosChitBag::NewCrystalChit( const grinliz::Vector3F& _pos, Wallet* src, bool fuzz )
{
	Vector3F pos = _pos;
	if ( fuzz ) {
		pos.x = floorf(_pos.x) + random.Uniform();
		pos.z = floorf(_pos.z) + random.Uniform();
	}

	int crystal = -1;
	for (int i = 0; i < NUM_CRYSTAL_TYPES; ++i) {
		if (src->Crystal(i)) {
			crystal = i;
			break;
		}
	}

	if (crystal == -1) return 0;	// done

	const char* name = 0;
	switch ( crystal ) {
	case CRYSTAL_GREEN:		name="crystal_green";	break;
	case CRYSTAL_RED:		name="crystal_red";		break;
	case CRYSTAL_BLUE:		name="crystal_blue";	break;
	case CRYSTAL_VIOLET:	name="crystal_violet";	break;
	}

	const ChitContext* context = Context();

	Chit* chit = this->NewChit();
	AddItem( name, chit, context->engine, 0, 0 );
	chit->Add( new RenderComponent( chit->GetItem()->ResourceName() ));
	chit->Add(new GameMoveComponent());

	chit->SetPosition( pos );
	
	int c[NUM_CRYSTAL_TYPES] = { 0 };
	c[crystal] = 1;

	chit->GetWallet()->Deposit(src, 0, c);

	return chit;
}
Пример #28
0
void CoreScript::AssignToSquads()
{
	// First, how many do we actually have?
	// Filter out everyone that has gone away.
	for (int i = 0; i < MAX_SQUADS; ++i) {
		//GL_ARRAY_FILTER(squads[i], (this->IsCitizen(ele)));
		squads[i].Filter(this, [](CoreScript* cs, int id) {
			return cs->IsCitizen(id);
		});
		if (squads[i].Empty()) {
			// Flush out dead squads so they don't have 
			// control flags laying around.
			waypoints[i].Clear();
		}
	}
	int nSquaddies = 0;
	for (int i = 0; i < MAX_SQUADS; ++i) {
		nSquaddies += squads[i].Size();
	}

	CChitArray recruits;
	int nCitizens = Citizens(&recruits);
	int nExpected = nCitizens - CITIZEN_BASE;
	if (nSquaddies >= nExpected) return;

	struct FilterData {
		CoreScript* cs;
		Chit* avatar;;
	};
	FilterData fd = { this, Context()->chitBag->GetAvatar() };

	// Filter to: not in squad AND not player controlled
	recruits.Filter(fd, [](const FilterData& ffd, Chit* chit) {
		return (ffd.cs->SquadID(chit->ID()) < 0 && chit != ffd.avatar);
	});

	// Sort the best recruits to the end.
	// FIXME: better if there was a (working) power approximation
	recruits.Sort([](Chit* a, Chit* b) {
		const GameItem* itemA = a->GetItem();
		const GameItem* itemB = b->GetItem();
		int scoreA = itemA->Traits().Level() * (itemA->GetPersonality().Fighting() == Personality::LIKES ? 2 : 1);
		int scoreB = itemB->Traits().Level() * (itemB->GetPersonality().Fighting() == Personality::LIKES ? 2 : 1);
		
		// Reverse order. Best at end.
		return scoreA > scoreB;
	});

	for (int n = nExpected - nSquaddies; n > 0; --n) {
		for (int i = 0; i < MAX_SQUADS; ++i) {
			if (   (squads[i].Size() < SQUAD_SIZE)
				&& SquadAtRest(i))
			{
				Chit* chit = recruits.Pop();
				squads[i].Push(chit->ID());
				++nSquaddies;
				break;
			}
		}
	}
}
Пример #29
0
void FluidTestScene::Tap3D(const grinliz::Vector2F& view, const grinliz::Ray& world)
{
	Vector3F at = { 0, 0, 0 };
	float t = 0;
	int result = IntersectRayAAPlane(world.origin, world.direction, 1, 0, &at, &t);
	if (result == INTERSECT) {
		Vector2I pos2i = ToWorld2I(at);
		Vector2I sector = { 0, 0 };
		CircuitSim* circuitSim = context.physicsSims->GetCircuitSim(sector);

		if (context.worldMap->Bounds().Contains(pos2i)) {

			bool trigger = false;
			if (!buildButton[BUTTON_DELETE].Down() && !buildButton[BUTTON_ROTATE].Down()) {
				Chit* building = context.chitBag->QueryPorch(pos2i);
				if (!building) {
					building = context.chitBag->QueryBuilding(IString(), pos2i, 0);
				}
				if (building) {
					if (building->GetItem()->IName() == ISC::detector) {
						circuitSim->TriggerDetector(pos2i);
						trigger = true;
					}
					else if (building->GetItem()->IName() == ISC::switchOn 
							 || building->GetItem()->IName() == ISC::switchOff) 
					{
						circuitSim->TriggerSwitch(pos2i);
						trigger = true;
					}
				}
			}

			int id = -1;
			if (!trigger) {
				for (int i = 0; i < NUM_BUTTONS; ++i) {
					if (buildButton[i].Down()) {
						id = i;
						break;
					}
				}
			}
			if (id >= 0) {
				Chit* chit = 0;
				switch (id) {
					case BUTTON_ROCK0:
					case BUTTON_ROCK1:
					case BUTTON_ROCK2:
					case BUTTON_ROCK3:
					context.worldMap->SetRock(pos2i.x, pos2i.y, id - BUTTON_ROCK0, false, WorldGrid::ROCK);
					break;

					case BUTTON_SWITCH_ON:
					chit = context.chitBag->NewBuilding(pos2i, "switchOn", TEAM_HOUSE);
					break;

					case BUTTON_SWITCH_OFF:
					chit = context.chitBag->NewBuilding(pos2i, "switchOff", TEAM_HOUSE);
					break;

					case BUTTON_TEMPLE:
					chit = context.chitBag->NewBuilding(pos2i, "temple", TEAM_HOUSE);
					break;

					case BUTTON_GATE:
					chit = context.chitBag->NewBuilding(pos2i, "gate", TEAM_HOUSE);
					break;

					case BUTTON_TIMED_GATE:
					chit = context.chitBag->NewBuilding(pos2i, "timedGate", TEAM_HOUSE);
					break;

					case BUTTON_DETECTOR:
					chit = context.chitBag->NewBuilding(pos2i, "detector", TEAM_HOUSE);
					break;

					case BUTTON_TURRET:
					chit = context.chitBag->NewBuilding(pos2i, "turret", TEAM_HOUSE);
					break;

					case BUTTON_DELETE:
					{
						Chit* building = context.chitBag->QueryBuilding(IString(), pos2i, 0);
						if (building) {
							building->QueueDelete();
						}
					}
					break;

					case BUTTON_ROTATE:
					{
						Chit* building = context.chitBag->QueryBuilding(IString(), pos2i, 0);
						if (building) {
							Matrix4 m;
							building->Rotation().ToMatrix(&m);
							float r = m.CalcRotationAroundAxis(1);
							r = NormalizeAngleDegrees(r + 90.0f);
							building->SetRotation(Quaternion::MakeYRotation(r));
						}

					}
					break;
				}
				if (chit) {
					MapSpatialComponent* msc = GET_SUB_COMPONENT(chit, SpatialComponent, MapSpatialComponent);
					if (msc) msc->SetNeedsCorePower(false);
				}
			}
		}
	}
}
Пример #30
0
CoreScript* CoreScript::CreateCore( const Vector2I& sector, int team, const ChitContext* context)
{
	// Destroy the existing core.
	// Create a new core, attached to the player.
	CoreScript* cs = CoreScript::GetCore(sector);
	if (cs) {
		Chit* core = cs->ParentChit();
		GLASSERT(core);

		CDynArray< Chit* > queryArr;

		// Tell all the AIs the core is going away.
		ChitHasAIComponent filter;
		Rectangle2F b = ToWorld2F(InnerSectorBounds(sector));
		context->chitBag->QuerySpatialHash(&queryArr, b, 0, &filter);
		for (int i = 0; i < queryArr.Size(); ++i) {
			queryArr[i]->GetAIComponent()->ClearTaskList();
		}

		//context.chitBag->QueueDelete(core);
		// QueueDelete is safer, but all kinds of asserts fire (correctly)
		// if 2 cores are in the same place. This may cause an issue
		// if CreateCore is called during the DoTick()
		// Setting the hp to 0 and then calling DoTick()
		// is a sleazy trick to clean up.
		core->GetItem()->hp = 0;
		if (core->GetHealthComponent()) {
			core->GetHealthComponent()->DoTick(1);
		}
		context->chitBag->DeleteChit(core);
	}

	const SectorData& sd = context->worldMap->GetSectorData(sector);
	if (sd.HasCore()) {
		int group = 0, id = 0;
		Team::SplitID(team, &group, &id);

		// Lots of trouble with this code. Used to assert,
		// but always seemed to be another case. White list
		// groups that *can* take over a core.
		if (team == TEAM_NEUTRAL || team == TEAM_TROLL || Team::IsDeity(team) || Team::IsDenizen(team)) {
			// Okay! take over.
			GLASSERT(!Team::IsDenizen(team) || id);		// make sure rogues got filtered out.
		}
		else {
			team = group = id = 0;
		}
		Chit* chit = context->chitBag->NewBuilding(sd.core, "core", team);

		// 'in use' instead of blocking.
		MapSpatialComponent* ms = GET_SUB_COMPONENT(chit, SpatialComponent, MapSpatialComponent);
		GLASSERT(ms);
		ms->SetBlocks(false);
		
		CoreScript* cs = new CoreScript();
		chit->Add(cs);
		GLASSERT(CoreScript::GetCore(ToSector(sd.core)) == cs);

		if (Team::IsDeity(team))
			chit->GetItem()->SetProperName(Team::Instance()->TeamName(team));
		else
			chit->GetItem()->SetProperName(sd.name);

		if (team != TEAM_NEUTRAL) {
			chit->GetItem()->SetSignificant(context->chitBag->GetNewsHistory(), 
											ToWorld2F(chit->Position()), 
											NewsEvent::DOMAIN_CREATED, NewsEvent::DOMAIN_DESTROYED, 0);


			// Make the dwellers defend the core.
			chit->Add(new GuardScript());

			// Make all buildings to be this team.
			CDynArray<Chit*> buildings;
			Vector2I buildingSector = ToSector(chit->Position());
			context->chitBag->FindBuilding(IString(), buildingSector, 0, LumosChitBag::EFindMode::NEAREST, &buildings, 0);
			
			for (int i = 0; i < buildings.Size(); ++i) {
				Chit* c = buildings[i];
				if (c->GetItem() && c->GetItem()->IName() != ISC::core) {
					c->GetItem()->SetTeam(team);
				}
			}
		}
		return cs;
	}
	return 0;
}