int CoreScript::DoTick(U32 delta) { int nScoreTicks = scoreTicker.Delta(delta); int nAITicks = aiTicker.Delta(delta); Citizens(0); // if someone was deleted, the spawn tick will reset. int nSpawnTicks = spawnTick.Delta(delta); // Clean rock off the core. Vector2I pos2i = ToWorld2I(parentChit->Position()); const WorldGrid& wg = Context()->worldMap->GetWorldGrid(pos2i); if (wg.RockHeight()) { Context()->worldMap->SetRock(pos2i.x, pos2i.y, 0, false, 0); } if (InUse()) { DoTickInUse(delta, nSpawnTicks); UpdateScore(nScoreTicks); } else { DoTickNeutral(delta, nSpawnTicks); } workQueue->DoTick(); if (nAITicks) { UpdateAI(); } for (int i = 0; i < MAX_SQUADS; ++i) { if (squads[i].Empty()) { waypoints[i].Clear(); } } if (strategicTicker.Delta(delta)) { if (this->InUse() && Context()->chitBag->GetHomeCore() != this) { DoStrategicTick(); } } RenderComponent* rc = parentChit->GetRenderComponent(); if (rc) { int team = parentChit->Team(); CStr<40> str = ""; if (this->InUse() && Team::IsDenizen(team)) { IString teamName = Team::Instance()->TeamName(team); str.Format("%s", teamName.safe_str()); } rc->SetDecoText(str.safe_str()); } return Min(spawnTick.Next(), aiTicker.Next(), scoreTicker.Next()); }
Chit* LumosChitBag::NewDenizen( const grinliz::Vector2I& pos, int team ) { const ChitContext* context = Context(); IString itemName; switch (Team::Group(team)) { case TEAM_HOUSE: itemName = (random.Bit()) ? ISC::humanFemale : ISC::humanMale; break; case TEAM_GOB: itemName = ISC::gobman; break; case TEAM_KAMAKIRI: itemName = ISC::kamakiri; break; default: GLASSERT(0); break; } Chit* chit = NewChit(); const GameItem& root = ItemDefDB::Instance()->Get(itemName.safe_str()); chit->Add( new RenderComponent(root.ResourceName())); chit->Add( new PathMoveComponent()); const char* altName = 0; if (Team::Group(team) == TEAM_HOUSE) { altName = "human"; } AddItem(root.Name(), chit, context->engine, team, 0, 0, altName); ReserveBank::Instance()->WithdrawDenizen(chit->GetWallet()); chit->GetItem()->GetTraitsMutable()->Roll( random.Rand() ); chit->GetItem()->GetPersonalityMutable()->Roll( random.Rand(), &chit->GetItem()->Traits() ); chit->GetItem()->FullHeal(); IString nameGen = chit->GetItem()->keyValues.GetIString( "nameGen" ); if ( !nameGen.empty() ) { LumosChitBag* chitBag = chit->Context()->chitBag; if ( chitBag ) { chit->GetItem()->SetProperName(chitBag->NameGen(nameGen.c_str(), chit->ID())); } } AIComponent* ai = new AIComponent(); chit->Add( ai ); chit->Add( new HealthComponent()); chit->SetPosition( (float)pos.x+0.5f, 0, (float)pos.y+0.5f ); chit->GetItem()->SetSignificant(GetNewsHistory(), ToWorld2F(pos), NewsEvent::DENIZEN_CREATED, NewsEvent::DENIZEN_KILLED, 0); if (XenoAudio::Instance()) { Vector3F pos3 = ToWorld3F(pos); XenoAudio::Instance()->PlayVariation(ISC::rezWAV, random.Rand(), &pos3); } return chit; }
void CoreScript::DoTickNeutral( int delta, int nSpawnTicks ) { int lesser, greater, denizen; const Census& census = Context()->chitBag->census; census.NumByType(&lesser, &greater, &denizen); IString defaultSpawn = Context()->worldMap->GetSectorData(sector).defaultSpawn; int typical = 0; int numOf = census.NumOf(defaultSpawn, &typical); bool lesserPossible = (lesser < TYPICAL_LESSER) && (!typical || numOf < typical * 2); Vector2I pos2i = ToWorld2I(parentChit->Position()); Vector2I sector = ToSector(pos2i); if (nSpawnTicks && lesserPossible) { #if SPAWN_MOBS > 0 int spawnEnabled = Context()->chitBag->GetSim()->SpawnEnabled() & Sim::SPAWN_LESSER; if (Context()->chitBag->GetSim() && spawnEnabled && !defaultSpawn.empty()) { Vector3F pf = { (float)pos2i.x + 0.5f, 0, (float)pos2i.y + 0.5f }; int nSpawn = (defaultSpawn == ISC::trilobyte) ? 4 : 1; int team = Team::GetTeam(defaultSpawn); GLASSERT(team != TEAM_NEUTRAL); for (int i = 0; i < nSpawn; ++i) { Context()->chitBag->NewMonsterChit(pf, defaultSpawn.safe_str(), team); pf.x += 0.05f; } } #endif } // Clear the work queue - chit is gone that controls this. if (!workQueue || workQueue->HasJob()) { delete workQueue; workQueue = new WorkQueue(); workQueue->InitSector(parentChit, ToSector(parentChit->Position())); } }
void NewsEvent::Console(GLString* str, ChitBag* chitBag, int shortNameID) const { *str = ""; Vector2I sector = ToSector(ToWorld2I(pos)); const GameItem* first = ItemDB::Instance()->Active(firstItemID); // const GameItem* second = ItemDB::Instance()->Active(secondItemID); IString firstName = IDToName(firstItemID, firstItemID == shortNameID); IString secondName = IDToName(secondItemID, secondItemID == shortNameID); if (firstName.empty()) firstName = StringPool::Intern("[unknown]"); if (secondName.empty()) secondName = StringPool::Intern("[unknown]"); float age = float(double(date) / double(AGE_IN_MSEC)); IString domain; if (chitBag->Context()->worldMap) { const SectorData& sd = chitBag->Context()->worldMap->GetSectorData(sector); domain = sd.name; } IString firstTeamName = Team::IsCoreController(firstTeam) ? Team::Instance()->TeamName(firstTeam) : IString(); IString secondTeamName = Team::IsCoreController(secondTeam) ? Team::Instance()->TeamName(secondTeam) : IString(); switch (what) { case DENIZEN_CREATED: str->Format("%.2f: Denizen %s " MOB_created " at %s with %s.", age, firstName.c_str(), domain.safe_str(), firstTeamName.safe_str()); break; case DENIZEN_KILLED: str->Format("%.2f: Denizen %s (%s) " MOB_destroyed " at %s by %s.", age, firstName.safe_str(), Team::IsRogue(firstTeam) ? "rogue" : firstTeamName.safe_str(), domain.safe_str(), secondName.safe_str()); break; case GREATER_MOB_CREATED: // They get created at the center, then sent. So the domain is meaningless. str->Format("%.2f: %s " MOB_created ".", age, firstName.safe_str()); break; case DOMAIN_CREATED: // "taken over" is interesting; a domain getting created is not. *str = ""; break; case ROGUE_DENIZEN_JOINS_TEAM: str->Format("%.2f: Rogue Denizen %s joins at %s with %s.", age, firstName.safe_str(), domain.safe_str(), firstTeamName.safe_str() ); break; case GREATER_MOB_KILLED: str->Format("%.2f: %s " MOB_destroyed " at %s by %s.", age, firstName.safe_str(), domain.safe_str(), secondName.safe_str()); break; case DOMAIN_DESTROYED: GLASSERT(firstTeam); // how is a neutral destroyed?? str->Format("%.2f: %s domain %s " MOB_destroyed " by %s.", age, firstTeamName.safe_str(), domain.safe_str(), secondName.safe_str()); break; // Neutral domains are taken over. // Subdomains are conquored. case DOMAIN_TAKEOVER: str->Format("%.2f: %s occupied by %s.", age, domain.safe_str(), firstTeamName.safe_str()); break; case DOMAIN_CONQUER: str->Format("%.2f: %s is conquered by %s.", age, domain.safe_str(), firstTeamName.safe_str() ); break; case SUPERTEAM_DELETED: GLASSERT(firstTeam); str->Format("%.2f: %s super domain %s " MOB_destroyed ". Sub-domains are now self controlled.", age, firstTeamName.safe_str(), domain.safe_str()); break; case SUBTEAM_DELETED: GLASSERT(firstTeam); GLASSERT(secondTeam); str->Format("%.2f: %s no longer controlled by %s.", age, firstTeamName.safe_str(), secondTeamName.safe_str()); break; case FORGED: str->Format("%.2f: %s forged %s at %s.", age, secondName.safe_str(), firstName.c_str(), domain.safe_str()); break; case UN_FORGED: str->Format("%.2f: %s " MOB_destroyed " %s at %s.", age, secondName.c_str(), firstName.c_str(), domain.c_str()); break; case PURCHASED: if (first) { str->Format("%.2f: %s purchased %s at %s for %d (%d tax).", age, secondName.c_str(), firstName.c_str(), domain.c_str(), first->GetValue(), int(first->GetValue() * SALES_TAX)); } else { str->Format("%.2f: %s purchased %s at %s.", age, secondName.c_str(), firstName.c_str(), domain.c_str()); } break; case STARVATION: str->Format("%.2f: %s has been overcome by starvation at %s.", age, firstName.c_str(), domain.c_str()); break; case BLOOD_RAGE: str->Format("%.2f: a distraught %s is overcome by blood rage at %s.", age, firstName.c_str(), domain.c_str()); break; case VISION_QUEST: str->Format("%.2f: %s is consumed by despair at %s and leaves for a vision quest.", age, firstName.c_str(), domain.c_str()); break; case GREATER_SUMMON_TECH: str->Format("%.2f: %s is called to %s by the siren song of Tech.", age, firstName.c_str(), domain.c_str()); break; case ATTITUDE_FRIEND: str->Format("%.2f: %s sees %s with friendly intent.", age, firstName.safe_str(), secondName.safe_str()); break; case ATTITUDE_NEUTRAL: str->Format("%.2f: %s sees %s with neutral regard.", age, firstName.safe_str(), secondName.safe_str()); break; case ATTITUDE_ENEMY: str->Format("%.2f: %s sees %s as an enemy.", age, firstName.safe_str(), secondName.safe_str()); break; default: GLASSERT(0); } }