void SpawnerComponent::OnLoss() { TeamComponent::team_t team = GetTeamComponent().Team(); int newNumSpawns = --level.team[team].numSpawns; ASSERT_GE(newNumSpawns, 0); // Warn if the last spawn is lost and there is a main buildable. if (newNumSpawns == 0 && G_ActiveMainBuildable(team)) { G_BroadcastEvent(EV_NO_SPAWNS, 0, team); } }
void BuildableComponent::HandleDie(gentity_t* killer, meansOfDeath_t meansOfDeath) { // Note that this->state is adjusted in (Alien|Human)BuildableComponent::HandleDie so they have // access to its current value. TeamComponent::team_t team = GetTeamComponent().Team(); // TODO: Move animation code to BuildableComponent. G_SetBuildableAnim(entity.oldEnt, Powered() ? BANIM_DESTROY : BANIM_DESTROY_UNPOWERED, true); G_SetIdleBuildableAnim(entity.oldEnt, BANIM_DESTROYED); entity.oldEnt->killedBy = killer->s.number; G_LogDestruction(entity.oldEnt, killer, meansOfDeath); // TODO: Handle in TaggableComponent. Beacon::DetachTags(entity.oldEnt); // Report an attack to the defending team if the buildable was powered and there is a main // buildable that can report it. Note that the main buildables itself issues its own warnings. if (Powered() && entity.Get<MainBuildableComponent>() == nullptr && G_IsWarnableMOD(meansOfDeath) && G_ActiveMainBuildable(team)) { // Get a nearby location entity. gentity_t *location = GetCloseLocationEntity(entity.oldEnt); // Fall back to fake location entity if necessary. if (!location) location = level.fakeLocation; // Warn if there was no warning for this location recently. if (level.time > location->warnTimer) { bool inBase = G_InsideBase(entity.oldEnt); G_BroadcastEvent(EV_WARN_ATTACK, inBase ? 0 : location->s.number, team); Beacon::NewArea(BCT_DEFEND, entity.oldEnt->s.origin, team); location->warnTimer = level.time + ATTACKWARN_NEARBY_PERIOD; } } // If not deconstructed, add all build points to queue. if (meansOfDeath != MOD_DECONSTRUCT && meansOfDeath != MOD_REPLACE) { G_FreeBudget(team, 0, BG_Buildable(entity.oldEnt->s.modelindex)->buildPoints); } }