+void Simulation::Tick(double dt) {
+ time += dt;
+ for (auto body : bodies) {
+ body->Tick(dt);
+ }
+ for (auto c : alive) {
+ CheckRecords(*c);
+ }
+}
+
+void Simulation::AddBody(Body &b) {
+ b.SetSimulation(*this);
+ bodies.insert(&b);
+}
+
+void Simulation::AddPlanet(Planet &p) {
+ AddBody(p);
+ planets.insert(&p);
+}
+
+void Simulation::AddSun(Sun &s) {
+ AddBody(s);
+ suns.insert(&s);
+}
+
+void Simulation::SetAlive(creature::Creature *c) {
+ alive.push_back(c);
+}
+
+void Simulation::SetDead(creature::Creature *c) {
+ auto entry = std::find(alive.begin(), alive.end(), c);
+ if (entry != alive.end()) {
+ alive.erase(entry);
+ }
+ dead.push_back(c);
+ CheckRecords(*c);
+}
+
+void Simulation::CheckRecords(creature::Creature &c) noexcept {
+ { // age
+ creature::Creature *prev = records[0].rank[0].holder;
+ int rank = records[0].Update(c, c.Age(), time);
+ if (rank == 0 && prev && prev != &c) {
+ LogRecord(records[0]);
+ }
+ }
+ { // mass
+ creature::Creature *prev = records[1].rank[0].holder;
+ int rank = records[1].Update(c, c.Mass(), time);
+ if (rank == 0 && prev && prev != &c) {
+ LogRecord(records[1]);
+ }
+ }
+ { // size
+ creature::Creature *prev = records[2].rank[0].holder;
+ int rank = records[2].Update(c, c.Size(), time);
+ if (rank == 0 && prev && prev != &c) {
+ LogRecord(records[2]);
+ }
+ }
+ { // strength
+ creature::Creature *prev = records[3].rank[0].holder;
+ int rank = records[3].Update(c, c.Strength(), time);
+ if (rank == 0 && prev && prev != &c) {
+ LogRecord(records[3]);
+ }
+ }
+ { // stamina
+ creature::Creature *prev = records[4].rank[0].holder;
+ int rank = records[4].Update(c, c.Stamina(), time);
+ if (rank == 0 && prev && prev != &c) {
+ LogRecord(records[4]);
+ }
+ }
+ { // dexerty
+ creature::Creature *prev = records[5].rank[0].holder;
+ int rank = records[5].Update(c, c.Dexerty(), time);
+ if (rank == 0 && prev && prev != &c) {
+ LogRecord(records[5]);
+ }
+ }
+ { // intelligence
+ creature::Creature *prev = records[6].rank[0].holder;
+ int rank = records[6].Update(c, c.Intelligence(), time);
+ if (rank == 0 && prev && prev != &c) {
+ LogRecord(records[6]);
+ }
+ }
+}
+
+void Simulation::LogRecord(const Record &r) {
+ Log() << "at age " << ui::TimeString(r.rank[0].holder->Age()) << " "
+ << r.rank[0].holder->Name() << " broke the " << r.name << " record of "
+ << r.ValueString(1) << " by " << r.rank[1].holder->Name()
+ << " (established " << ui::TimeString(r.rank[1].time) << ")" << std::endl;
+}