Beispiel #1
0
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;
}
Beispiel #2
0
/**
 * @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);
}
Beispiel #3
0
/**
 * @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);
}