static void G_SpawnField (edict_t *ent, const char *classname, entity_type_t type, solid_t solid) { vec3_t particleOrigin; ent->classname = classname; ent->type = type; ent->fieldSize = ACTOR_SIZE_NORMAL; ent->solid = solid; VectorSet(ent->maxs, UNIT_SIZE / 2, UNIT_SIZE / 2, UNIT_HEIGHT / 2); VectorSet(ent->mins, -UNIT_SIZE / 2, -UNIT_SIZE / 2, -UNIT_HEIGHT / 2); G_EdictCalcOrigin(ent); ent->think = Think_SmokeAndFire; ent->nextthink = 1; ent->time = level.actualRound; gi.LinkEdict(ent); VectorCopy(ent->origin, particleOrigin); particleOrigin[2] -= GROUND_DELTA; ent->particleLink = G_SpawnParticle(particleOrigin, ent->spawnflags, ent->particle); }
/** * @note Think functions are only executed when the match is running * or in other word, the game has started */ void G_MissionThink (Edict* self) { if (!G_MatchIsRunning()) return; /* when every player has joined the match - spawn the mission target * particle (if given) to mark the trigger */ if (self->particle) { self->link = G_SpawnParticle(self->origin, self->spawnflags, self->particle); /* This is automatically freed on map shutdown */ self->particle = nullptr; } Edict* chain = self->groupMaster; if (!chain) chain = self; while (chain) { if (chain->type == ET_MISSION) { if (chain->item) { const Item* ic; G_GetFloorItems(chain); ic = chain->getFloor(); if (!ic) { /* reset the counter if there is no item */ chain->count = 0; return; } for (; ic; ic = ic->getNext()) { const objDef_t* od = ic->def(); assert(od); /* not the item we are looking for */ if (Q_streq(od->id, chain->item)) break; } if (!ic) { /* reset the counter if it's not the searched item */ chain->count = 0; return; } } if (chain->time) { /* Check that the target zone is still occupied (last defender might have died) */ if (!chain->item && !G_MissionIsTouched(chain)) { chain->count = 0; } const int endTime = level.actualRound - chain->count; const int spawnIndex = (chain->getTeam() + level.teamOfs) % MAX_TEAMS; const int currentIndex = (level.activeTeam + level.teamOfs) % MAX_TEAMS; /* not every edict in the group chain has * been occupied long enough */ if (!chain->count || endTime < chain->time || (endTime == chain->time && spawnIndex < currentIndex)) return; } if (chain->target && !chain->time && !chain->item) { if (!G_MissionIsTouched(chain)) return; } } chain = chain->groupChain; } const bool endMission = self->target == nullptr; /* store team before the edict is released */ const int team = self->getTeam(); chain = self->groupMaster; if (!chain) chain = self; while (chain) { if (chain->type == ET_MISSION) { G_UseEdict(chain, nullptr); if (chain->item != nullptr) { Edict* item = G_GetEdictFromPos(chain->pos, ET_ITEM); if (item != nullptr) { if (!G_InventoryRemoveItemByID(chain->item, item, CID_FLOOR)) { Com_Printf("Could not remove item '%s' from floor edict %i\n", chain->item, item->getIdNum()); } else if (!item->getFloor()) { G_EventPerish(*item); G_FreeEdict(item); } } } if (chain->link != nullptr) { Edict* particle = G_GetEdictFromPos(chain->pos, ET_PARTICLE); if (particle != nullptr) { G_AppearPerishEvent(G_VisToPM(particle->visflags), false, *particle, nullptr); G_FreeEdict(particle); } chain->link = nullptr; } /* Display mission message */ if (G_ValidMessage(chain)) { const char* msg = chain->message; if (msg[0] == '_') ++msg; gi.BroadcastPrintf(PRINT_HUD, "%s", msg); } } Edict* ent = chain->groupChain; /* free the group chain */ G_FreeEdict(chain); chain = ent; } if (endMission) G_MatchEndTrigger(team, level.activeTeam == TEAM_ALIEN ? 10 : 3); }
static bool Destroy_Camera (Edict* self) { G_SpawnParticle(self->origin, self->spawnflags, self->particle); G_FreeEdict(self); return true; }
/** * @note Think functions are only executed when the match is running * or in other word, the game has started */ void G_MissionThink (Edict* self) { if (!G_MatchIsRunning()) return; /* when every player has joined the match - spawn the mission target * particle (if given) to mark the trigger */ if (self->particle) { self->link = G_SpawnParticle(self->origin, self->spawnflags, self->particle); /* This is automatically freed on map shutdown */ self->particle = nullptr; } Edict* chain = self->groupMaster; if (!chain) chain = self; while (chain) { if (chain->type == ET_MISSION) { if (chain->item) { const Item* ic; G_GetFloorItems(chain); ic = chain->getFloor(); if (!ic) { /* reset the counter if there is no item */ chain->count = 0; return; } for (; ic; ic = ic->getNext()) { const objDef_t* od = ic->def(); assert(od); /* not the item we are looking for */ if (Q_streq(od->id, chain->item)) break; } if (!ic) { /* reset the counter if it's not the searched item */ chain->count = 0; return; } } if (chain->time) { const int endTime = level.actualRound - chain->count; const int spawnIndex = (self->getTeam() + level.teamOfs) % MAX_TEAMS; const int currentIndex = (level.activeTeam + level.teamOfs) % MAX_TEAMS; /* not every edict in the group chain has * been occupied long enough */ if (!chain->count || endTime < chain->time || (endTime == level.actualRound && spawnIndex <= currentIndex)) return; } /* not destroyed yet */ if ((chain->flags & FL_DESTROYABLE) && chain->HP) return; } chain = chain->groupChain; } if (self->use) self->use(self, nullptr); /* store team before the edict is released */ const int team = self->getTeam(); chain = self->groupMaster; if (!chain) chain = self; while (chain) { if (chain->item != nullptr) { Edict* item = G_GetEdictFromPos(chain->pos, ET_ITEM); if (item != nullptr) { if (!G_InventoryRemoveItemByID(chain->item, item, CID_FLOOR)) { Com_Printf("Could not remove item '%s' from floor edict %i\n", chain->item, item->getIdNum()); } else if (!item->getFloor()) { G_EventPerish(*item); G_FreeEdict(item); } } } if (chain->link != nullptr) { Edict* particle = G_GetEdictFromPos(chain->pos, ET_PARTICLE); if (particle != nullptr) { G_AppearPerishEvent(PM_ALL, false, *particle, nullptr); G_FreeEdict(particle); } chain->link = nullptr; } Edict* ent = chain->groupChain; /* free the trigger */ if (chain->child()) G_FreeEdict(chain->child()); /* free the group chain */ G_FreeEdict(chain); chain = ent; } self = nullptr; /* still active mission edicts left */ Edict* ent = nullptr; while ((ent = G_EdictsGetNextInUse(ent))) if (ent->type == ET_MISSION && ent->getTeam() == team) return; G_MatchEndTrigger(team, 10); }
/** * @note Think functions are only executed when the match is running * or in other word, the game has started */ void G_MissionThink (edict_t *self) { edict_t *chain = self->groupMaster; edict_t *ent; int team; if (!G_MatchIsRunning()) return; /* when every player has joined the match - spawn the mission target * particle (if given) to mark the trigger */ if (self->particle) { G_SpawnParticle(self->origin, self->spawnflags, self->particle); /* This is automatically freed on map shutdown */ self->particle = NULL; } if (!chain) chain = self; while (chain) { if (chain->type == ET_MISSION) { if (chain->item) { const invList_t *ic; G_GetFloorItems(chain); ic = FLOOR(chain); if (!ic) { /* reset the counter if there is no item */ chain->count = 0; return; } for (; ic; ic = ic->next) { const objDef_t *od = ic->item.t; assert(od); /* not the item we are looking for */ if (Q_streq(od->id, chain->item)) break; } if (!ic) { /* reset the counter if it's not the searched item */ chain->count = 0; return; } } if (chain->time) { /* not every edict in the group chain has * been occupied long enough */ if (!chain->count || level.actualRound - chain->count < chain->time) return; } /* not destroyed yet */ if ((chain->flags & FL_DESTROYABLE) && chain->HP) return; } chain = chain->groupChain; } if (self->use) self->use(self, NULL); /* store team before the edict is released */ team = self->team; chain = self->groupMaster; if (!chain) chain = self; while (chain) { if (chain->item != NULL) { edict_t *item = G_GetEdictFromPos(chain->pos, ET_ITEM); if (item != NULL) { if (!G_InventoryRemoveItemByID(chain->item, item, gi.csi->idFloor)) { Com_Printf("Could not remove item '%s' from floor edict %i\n", chain->item, item->number); } else { G_AppearPerishEvent(G_VisToPM(item->visflags), false, item, NULL); } } } if (chain->particle != NULL) { /** @todo not yet working - particle stays active */ edict_t *particle = G_GetEdictFromPos(chain->pos, ET_PARTICLE); if (particle != NULL) { G_AppearPerishEvent(PM_ALL, false, particle, NULL); G_FreeEdict(particle); } } ent = chain->groupChain; /* free the trigger */ if (chain->child) G_FreeEdict(chain->child); /* free the group chain */ G_FreeEdict(chain); chain = ent; } self = NULL; /* still active mission edicts left */ ent = NULL; while ((ent = G_EdictsGetNextInUse(ent))) if (ent->type == ET_MISSION && ent->team == team) return; G_MatchEndTrigger(team, 10); }