Exemple #1
0
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);
}
Exemple #2
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);
}
Exemple #3
0
static bool Destroy_Camera (Edict* self)
{
	G_SpawnParticle(self->origin, self->spawnflags, self->particle);
	G_FreeEdict(self);
	return true;
}
Exemple #4
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) {
				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);
}
Exemple #5
0
/**
 * @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);
}