Ejemplo n.º 1
0
/*
 * @brief Searches all active entities for the next targeted one.
 *
 * Searches beginning at the entity after from, or the beginning if NULL
 * NULL will be returned if the end of the list is reached.
 */
g_entity_t *G_PickTarget(char *target_name) {
	g_entity_t *choice[MAX_TARGETS];
	size_t num_choices = 0;

	if (!target_name) {
		gi.Debug("NULL target_name\n");
		return NULL;
	}

	g_entity_t *ent = NULL;
	while (true) {

		ent = G_Find(ent, LOFS(target_name), target_name);

		if (!ent)
			break;

		choice[num_choices++] = ent;

		if (num_choices == MAX_TARGETS)
			break;
	}

	if (!num_choices) {
		gi.Debug("Target %s not found\n", target_name);
		return NULL;
	}

	return choice[Random() % num_choices];
}
Ejemplo n.º 2
0
	F_STRING, // string on disk, pointer in memory, TAG_LEVEL
	F_VECTOR,
	F_ANGLE
} g_field_type_t;

typedef struct g_field_s {
	char *name;
	ptrdiff_t ofs;
	g_field_type_t type;
	int32_t flags;
} g_field_t;

static const g_field_t fields[] = {
	{ "classname", EOFS(class_name), F_STRING, 0 },
	{ "model", EOFS(model), F_STRING, 0 },
	{ "spawnflags", LOFS(spawn_flags), F_INT, 0 },
	{ "speed", LOFS(speed), F_FLOAT, 0 },
	{ "accel", LOFS(accel), F_FLOAT, 0 },
	{ "decel", LOFS(decel), F_FLOAT, 0 },
	{ "target", LOFS(target), F_STRING, 0 },
	{ "targetname", LOFS(target_name), F_STRING, 0 },
	{ "pathtarget", LOFS(path_target), F_STRING, 0 },
	{ "killtarget", LOFS(kill_target), F_STRING, 0 },
	{ "message", LOFS(message), F_STRING, 0 },
	{ "team", LOFS(team), F_STRING, 0 },
	{ "command", LOFS(command), F_STRING, 0 },
	{ "script", LOFS(script), F_STRING, 0 },
	{ "wait", LOFS(wait), F_FLOAT, 0 },
	{ "delay", LOFS(delay), F_FLOAT, 0 },
	{ "random", LOFS(random), F_FLOAT, 0 },
	{ "style", LOFS(area_portal), F_INT, 0 }, // HACK, this was always overloaded
Ejemplo n.º 3
0
/*
 * @brief Search for all entities that the specified entity targets, and call their
 * use functions. Set their activator to our activator. Print our message,
 * if set, to the activator.
 */
void G_UseTargets(g_entity_t *ent, g_entity_t *activator) {
	g_entity_t *t;

	// check for a delay
	if (ent->locals.delay) {
		// create a temp object to fire at a later time
		t = G_AllocEntity(__func__);
		t->locals.next_think = g_level.time + ent->locals.delay * 1000;
		t->locals.Think = G_UseTargets_Delay;
		t->locals.activator = activator;
		if (!activator)
			gi.Debug("No activator for %s\n", etos(ent));
		t->locals.message = ent->locals.message;
		t->locals.target = ent->locals.target;
		t->locals.kill_target = ent->locals.kill_target;
		return;
	}

	// print the message
	if ((ent->locals.message) && activator->client) {
		gi.WriteByte(SV_CMD_CENTER_PRINT);
		gi.WriteString(ent->locals.message);
		gi.Unicast(activator, true);

		if (ent->locals.noise_index)
			gi.Sound(activator, ent->locals.noise_index, ATTEN_NORM);
		else
			gi.Sound(activator, gi.SoundIndex("misc/chat"), ATTEN_NORM);
	}

	// kill kill_targets
	if (ent->locals.kill_target) {
		t = NULL;
		while ((t = G_Find(t, LOFS(target_name), ent->locals.kill_target))) {
			G_FreeEntity(t);
			if (!ent->in_use) {
				gi.Debug("%s was removed while using kill_targets\n", etos(ent));
				return;
			}
		}
	}

	// doors fire area portals in a specific way
	const _Bool is_door = g_str_has_prefix(ent->class_name, "func_door");

	// fire targets
	if (ent->locals.target) {
		t = NULL;
		while ((t = G_Find(t, LOFS(target_name), ent->locals.target))) {

			if (is_door && !g_strcmp0(t->class_name, "func_areaportal")) {
				continue;
			}

			if (t == ent) {
				gi.Debug("%s tried to use itself\n", etos(ent));
				continue;
			}

			if (t->locals.Use) {
				t->locals.Use(t, ent, activator);
				if (!ent->in_use) { // see if our target freed us
					gi.Debug("%s was removed while using targets\n", etos(ent));
					break;
				}
			}
		}
	}
}