static void SP_misc_message (Edict* ent) { if (!ent->message) { G_FreeEdict(ent); return; } if (!G_ValidMessage(ent)) gi.DPrintf("No translation marker for misc_message set\n"); ent->use = Message_Use; ent->classname = "misc_message"; ent->type = ET_MESSAGE; ent->solid = SOLID_NOT; }
/** * @brief Initializes the human/phalanx mission entity */ static void SP_misc_mission (Edict* ent) { Edict* other; ent->classname = "misc_mission"; ent->type = ET_MISSION; /* maybe this was set to something else for multiplayer */ if (!ent->team) ent->team = TEAM_PHALANX; ent->solid = SOLID_BBOX; if (ent->HP) { ent->flags |= FL_DESTROYABLE; ent->destroy = G_MissionDestroy; } if (!ent->HP && !ent->time && !ent->target) { G_FreeEdict(ent); gi.DPrintf("misc_mission given with no objective\n"); return; } /* think function values */ ent->think = G_MissionThink; ent->nextthink = 1; if (ent->radius <= GRID_WIDTH) { ent->radius = GRID_WIDTH * 3; } VectorSet(ent->absmax, ent->radius, ent->radius, PLAYER_STAND); VectorSet(ent->absmin, -ent->radius, -ent->radius, PLAYER_MIN); if (G_ValidMessage(ent)) G_MissionAddVictoryMessage(ent->message); /* spawn the trigger entity */ other = G_TriggerSpawn(ent); other->touch = G_MissionTouch; if (ent->target) ent->use = G_MissionUse; ent->child = other; gi.LinkEdict(ent); }
/** * @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); }