1 // Copyright © 2008-2021 Pioneer Developers. See AUTHORS.txt for details
2 // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt
3 
4 #include "Sector.h"
5 #include "CustomSystem.h"
6 #include "Galaxy.h"
7 #include "StarSystem.h"
8 
9 #include "EnumStrings.h"
10 #include "Factions.h"
11 #include "utils.h"
12 
13 const float Sector::SIZE = 8.f;
14 
15 //////////////////////// Sector
16 
Sector(RefCountedPtr<Galaxy> galaxy,const SystemPath & path,SectorCache * cache)17 Sector::Sector(RefCountedPtr<Galaxy> galaxy, const SystemPath &path, SectorCache *cache) :
18 	sx(path.sectorX),
19 	sy(path.sectorY),
20 	sz(path.sectorZ),
21 	m_galaxy(galaxy),
22 	m_cache(cache) {}
23 
~Sector()24 Sector::~Sector()
25 {
26 	if (m_cache)
27 		m_cache->RemoveFromAttic(SystemPath(sx, sy, sz));
28 }
29 
DistanceBetween(RefCountedPtr<const Sector> a,int sysIdxA,RefCountedPtr<const Sector> b,int sysIdxB)30 float Sector::DistanceBetween(RefCountedPtr<const Sector> a, int sysIdxA, RefCountedPtr<const Sector> b, int sysIdxB)
31 {
32 	PROFILE_SCOPED()
33 	vector3f dv = a->m_systems[sysIdxA].GetPosition() - b->m_systems[sysIdxB].GetPosition();
34 	dv += Sector::SIZE * vector3f(float(a->sx - b->sx), float(a->sy - b->sy), float(a->sz - b->sz));
35 	return dv.Length();
36 }
37 
DistanceBetweenSqr(const RefCountedPtr<const Sector> a,const int sysIdxA,const RefCountedPtr<const Sector> b,const int sysIdxB)38 float Sector::DistanceBetweenSqr(const RefCountedPtr<const Sector> a, const int sysIdxA, const RefCountedPtr<const Sector> b, const int sysIdxB)
39 {
40 	PROFILE_SCOPED()
41 	vector3f dv = a->m_systems[sysIdxA].GetPosition() - b->m_systems[sysIdxB].GetPosition();
42 	dv += Sector::SIZE * vector3f(float(a->sx - b->sx), float(a->sy - b->sy), float(a->sz - b->sz));
43 	return dv.LengthSqr();
44 }
45 
WithinBox(const int Xmin,const int Xmax,const int Ymin,const int Ymax,const int Zmin,const int Zmax) const46 bool Sector::WithinBox(const int Xmin, const int Xmax, const int Ymin, const int Ymax, const int Zmin, const int Zmax) const
47 {
48 	PROFILE_SCOPED()
49 	if (sx >= Xmin && sx <= Xmax) {
50 		if (sy >= Ymin && sy <= Ymax) {
51 			if (sz >= Zmin && sz <= Zmax) {
52 				return true;
53 			}
54 		}
55 	}
56 	return false;
57 }
58 
59 /*	answer whether the system path is in this sector
60 */
Contains(const SystemPath & sysPath) const61 bool Sector::Contains(const SystemPath &sysPath) const
62 {
63 	PROFILE_SCOPED()
64 	if (sx != sysPath.sectorX) return false;
65 	if (sy != sysPath.sectorY) return false;
66 	if (sz != sysPath.sectorZ) return false;
67 	return true;
68 }
69 
SetExplored(StarSystem::ExplorationState e,double time)70 void Sector::System::SetExplored(StarSystem::ExplorationState e, double time)
71 {
72 	if (e != m_explored) {
73 		m_sector->onSetExplorationState.emit(this, e, time);
74 		m_explored = e;
75 		m_exploredTime = time;
76 	}
77 }
78 
Dump(FILE * file,const char * indent) const79 void Sector::Dump(FILE *file, const char *indent) const
80 {
81 	fprintf(file, "Sector(%d,%d,%d) {\n", sx, sy, sz);
82 	fprintf(file, "\t" SIZET_FMT " systems\n", m_systems.size());
83 	for (const Sector::System &sys : m_systems) {
84 		assert(sx == sys.sx && sy == sys.sy && sz == sys.sz);
85 		fprintf(file, "\tSystem(%d,%d,%d,%u) {\n", sys.sx, sys.sy, sys.sz, sys.idx);
86 		fprintf(file, "\t\t\"%s\"\n", sys.GetName().c_str());
87 		fprintf(file, "\t\t%sEXPLORED%s\n", sys.IsExplored() ? "" : "UN", sys.GetCustomSystem() != nullptr ? ", CUSTOM" : "");
88 		fprintf(file, "\t\tfaction %s%s%s\n", sys.GetFaction() ? "\"" : "NONE", sys.GetFaction() ? sys.GetFaction()->name.c_str() : "", sys.GetFaction() ? "\"" : "");
89 		fprintf(file, "\t\tpos (%f, %f, %f)\n", double(sys.GetPosition().x), double(sys.GetPosition().y), double(sys.GetPosition().z));
90 		fprintf(file, "\t\tseed %u\n", sys.GetSeed());
91 		fprintf(file, "\t\tpopulation %.0f\n", sys.GetPopulation().ToDouble() * 1e9);
92 		fprintf(file, "\t\t%d stars%s\n", sys.GetNumStars(), sys.GetNumStars() > 0 ? " {" : "");
93 		for (unsigned i = 0; i < sys.GetNumStars(); ++i)
94 			fprintf(file, "\t\t\t%s\n", EnumStrings::GetString("BodyType", sys.GetStarType(i)));
95 		if (sys.GetNumStars() > 0) fprintf(file, "\t\t}\n");
96 		RefCountedPtr<const StarSystem> ssys = m_galaxy->GetStarSystem(SystemPath(sys.sx, sys.sy, sys.sz, sys.idx));
97 		assert(ssys->GetPath().IsSameSystem(SystemPath(sys.sx, sys.sy, sys.sz, sys.idx)));
98 		assert(ssys->GetNumStars() == sys.GetNumStars());
99 		assert(ssys->GetName() == sys.GetName());
100 		assert(ssys->GetUnexplored() == !sys.IsExplored());
101 		assert(ssys->GetFaction() == sys.GetFaction());
102 		assert(unsigned(ssys->GetSeed()) == sys.GetSeed());
103 		assert(ssys->GetNumStars() == sys.GetNumStars());
104 		for (unsigned i = 0; i < sys.GetNumStars(); ++i)
105 			assert(sys.GetStarType(i) == ssys->GetStars()[i]->GetType());
106 		ssys->Dump(file, "\t\t", true);
107 		fprintf(file, "\t}\n");
108 	}
109 	fprintf(file, "}\n\n");
110 }
111 
DistanceBetween(const System * a,const System * b)112 float Sector::System::DistanceBetween(const System *a, const System *b)
113 {
114 	vector3f dv = a->GetPosition() - b->GetPosition();
115 	dv += Sector::SIZE * vector3f(float(a->sx - b->sx), float(a->sy - b->sy), float(a->sz - b->sz));
116 	return dv.Length();
117 }
118 
AssignFaction() const119 void Sector::System::AssignFaction() const
120 {
121 	assert(m_sector->m_galaxy->GetFactions()->MayAssignFactions());
122 	m_faction = m_sector->m_galaxy->GetFactions()->GetNearestClaimant(this);
123 }
124