Пример #1
0
void CoreScript::UpdateScore(int n)
{
	static const double FACTOR = 0.002;

	if (n) {
		// Tuned - somewhat sleazily - that basic 4 unit, 0 temple is one point.
		double score = CivTech() * double(n) * double(scoreTicker.Period()) * FACTOR;
		achievement.civTechScore += Min(1, int(score));

		int team = ParentChit()->Team();
		CDynArray<int> subTeams;
		if (Team::Instance()->IsController(team, &subTeams)) {
			for (int i = 0; i < subTeams.Size(); ++i) {
				CoreScript* subCore = CoreScript::GetCoreFromTeam(subTeams[i]);
				if (subCore) {
					score += 0.5 * subCore->CivTech() * double(n) * double(scoreTicker.Period()) * FACTOR;
				}
			}
		}

		// Push this to the GameItem, so it can be recorded in the history + census.
		GameItem* gi = ParentChit()->GetItem();
		if (gi) {
			// Score is a 16 bit quantity...
			int s = achievement.civTechScore;
			if (s > 65535) s = 65535;
			gi->keyValues.Set(ISC::score, s);
			gi->UpdateHistory();
		}
	}
	if (ParentChit()->GetItem()) {
		achievement.gold = Max(achievement.gold, ParentChit()->GetItem()->wallet.Gold());
		achievement.population = Max(achievement.population, citizens.Size());
	}
}
Пример #2
0
void LumosGame::CopyFile(const char* src, const char* target)
{
	GLString srcPath;
	GetSystemPath(GAME_APP_DIR, src, &srcPath);

	GLString targetPath;
	GetSystemPath(GAME_SAVE_DIR, target, &targetPath);

	FILE* fp = fopen(srcPath.c_str(), "rb");
	GLASSERT(fp);
	if (fp) {
		FILE* tp = fopen(targetPath.c_str(), "wb");
		GLASSERT(tp);

		if (tp) {
			CDynArray<U8> buf;
			fseek(fp, 0, SEEK_END);
			size_t size = ftell(fp);
			buf.PushArr(size);

			fseek(fp, 0, SEEK_SET);
			size_t didRead = fread(&buf[0], 1, size, fp);
			GLASSERT(didRead == 1);
			if (didRead == 1) {
				fwrite(buf.Mem(), 1, size, tp);
			}

			fclose(tp);
		}
		fclose(fp);
	}
}
Пример #3
0
void TestThreadPool()
{
	CDynArray<int> result;
	{
		// Empty:
		ThreadPool pool;
		pool.Wait(0);
		printf("Empty pool pass.\n");
	}
	{
		int N = 8;
		ThreadPool pool;
		for (int i = 0; i < N; ++i) {
			pool.Add(TFunc, (void*)i);
		}
		pool.Wait(&result);
		result.Sort();
		for (int i = 0; i < N; ++i) {
			GLASSERT(result[i] == i);
		}
		printf("Basic test pass.\n");
	}
	{
		for (int pass = 0; pass < 2; ++pass) {
			int N = 100;
			ThreadPool pool;
			for (int i = 0; i < N; ++i) {
				pool.Add(TFunc, (void*)i);
			}
			pool.Wait(&result);
			result.Sort();
			for (int i = 0; i < N; ++i) {
				GLASSERT(result[i] == i);
			}
			printf("Serial stress %d pass.\n", pass);
		}
	}
	{
		static const int P = 2;
		ThreadPool pool[P];
		int N = 100;
		for (int i = 0; i < N; ++i) {
			for (int pass = 0; pass < P; ++pass) {
				pool[pass].Add(TFunc, (void*)i);
			}
		}
		for (int pass = 0; pass < P; ++pass) {
			pool[pass].Wait(&result);
			result.Sort();
			for (int i = 0; i < N; ++i) {
				GLASSERT(result[i] == i);
			}
		}
		printf("Parallel stress pass.\n");
	}
}
Пример #4
0
void TestSpatialHash()
{
	SpatialHash<int> spatial;
	CDynArray<int> query;

	Vector2I v = { 0, 0 };

	spatial.Add(v, 0);
	spatial.Query(v, &query);
	GLASSERT(query.Size() == 1 && query[0] == 0);
	spatial.Remove(v, 0);
	GLASSERT(spatial.Query(v, &query) == 0);
	GLASSERT(spatial.Empty());

	static int NUM = 2000;
	static int MULT = 7;
	static int MAP = 1024;

	for (int i = 0; i < NUM; ++i) {
		for (int j = 0; j < 4; ++j) {
			Vector2I pos = { (i*MULT) / MAP, (i*MULT) % MAP };
			spatial.Add(pos, j);
		}
	}
	for (int i = 0; i < NUM; ++i) {
		Vector2I pos = { (i*MULT) / MAP, (i*MULT) % MAP };
		spatial.Remove(pos, i%4);
	}
	for (int i = 0; i < NUM; ++i) {
		Vector2I pos = { (i*MULT) / MAP, (i*MULT) % MAP };
		query.Clear();
		spatial.Query(pos, &query);
		GLASSERT(query.Size() == 3);
		for (int j = 0; j < query.Size(); ++j) {
			GLASSERT(query[j] >= 0 && query[j] < 4 && query[j] != (i % 4));
		}
		for (int j = 0; j < query.Size(); ++j) {
			spatial.Remove(pos, query[j]);
		}
	}
	GLASSERT(spatial.Empty());

	printf("Spatial Hash test. nAllocated=%d nProbes=%d nSteps=%d eff=%.3f density=%.3f\n",
		   spatial.NumAllocated(), spatial.NumProbes(), spatial.NumSteps(), spatial.Efficiency(), spatial.Density());
}
Пример #5
0
void MinSpanTree::Calc(const grinliz::Vector2I* points, int n)
{
	nodes.Clear();
	if (n < 1) return;

	Node start;
	start.pos = points[0];
	start.parentPos = points[0];
	nodes.Push(start);

	CDynArray<Vector2I> inSet;
	inSet.Reserve(n-1);
	for (int i = 1; i < n; ++i) {
		inSet.Push(points[i]);
	}

	while (!inSet.Empty()) {
		int bestNode = 0;
		int bestIn = 0;
		int bestScore = INT_MAX;

		for (int i = 0; i < nodes.Size(); ++i) {
			for (int k = 0; k < inSet.Size(); ++k) {
				int score = (inSet[k] - nodes[i].pos).LengthSquared();
				if (score < bestScore) {
					bestScore = score;
					bestNode = i;
					bestIn = k;
				}
			}
		}
		GLASSERT(bestScore != INT_MAX);
		Vector2I vInSet = inSet[bestIn];
		inSet.SwapRemove(bestIn);

		Node newNode;
		newNode.pos = vInSet;
		newNode.parentPos = nodes[bestNode].pos;
		newNode.nextSibling = nodes[bestNode].firstChild;
		nodes[bestNode].firstChild = nodes.Size();
		nodes.Push(newNode);
	}
	RecWalkStr(0, 1.0f);
}
Пример #6
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;
}