Esempio n. 1
0
/**
 * @brief Make the actor use (as in open/close) a door edict
 * @note Will also check whether the door is still reachable (this might have
 * changed due to the rotation) after the usage
 * @param actor The actor that is using the door
 * @param door The door that should be opened/closed
 */
void G_ActorUseDoor (Edict* actor, Edict* door)
{
	/* check whether it's part of an edict group but not the master */
	if (door->flags & FL_GROUPSLAVE)
		door = door->groupMaster;

	if (!G_ClientUseEdict(actor->getPlayer(), actor, door))
		return;

	/* end this loop here, for the AI this is a) not interesting,
	 * and b) could result in endless loops */
	if (G_IsAI(actor))
		return;

	Edict* closeActor = nullptr;
	while ((closeActor = G_FindRadius(closeActor, door->origin, UNIT_SIZE * 3))) {
		/* check whether the door is still reachable (this might have
		 * changed due to the rotation) or whether an actor can reach it now */
		G_TouchTriggers(closeActor);
	}
}
Esempio n. 2
0
/**
 * @brief Actually does the magic
 */
static void G_weapon_chaingun_Think(g_entity_t *ent) {

	g_entity_t *cg = NULL;
	
	while ((cg = G_Find(cg, EOFS(class_name), "weapon_chaingun"))) {

		// spawn a lightning gun where we are
		g_entity_t *lg = G_AllocEntity_(g_media.items.weapons[WEAPON_LIGHTNING]->class_name);
		VectorCopy(cg->s.origin, lg->s.origin);
		VectorCopy(cg->s.angles, lg->s.angles);
		lg->locals.spawn_flags = cg->locals.spawn_flags;

		G_SpawnItem(lg, g_media.items.weapons[WEAPON_LIGHTNING]);

		// replace nearby bullets with bolts
		g_entity_t *ammo = NULL;

		while ((ammo = G_FindRadius(ammo, lg->s.origin, 128.0))) {
			if (ammo->locals.item && ammo->locals.item == g_media.items.ammo[AMMO_BULLETS]) {

				// hello bolts
				g_entity_t *bolts = G_AllocEntity_(g_media.items.ammo[AMMO_BOLTS]->class_name);
				VectorCopy(ammo->s.origin, bolts->s.origin);
				VectorCopy(ammo->s.angles, bolts->s.angles);
				bolts->locals.spawn_flags = ammo->locals.spawn_flags;

				G_SpawnItem(bolts, g_media.items.ammo[AMMO_BOLTS]);

				// byebye bullets
				G_FreeEntity(ammo);
			}
		}

		// byebye chaingun
		G_FreeEntity(cg);
	}
}
Esempio n. 3
0
void G_HomingMissile(gentity_t * ent)
{
	gentity_t      *target = NULL;
	gentity_t      *blip = NULL;
	vec3_t          dir, blipdir;
	vec_t           angle;
	qboolean        chaff;

	//qboolean        ignorechaff = qfalse;
	const int       HOMING_THINK_TIME = 60;

	// explode after 15 seconds without a hit
	if(ent->spawnTime + 15000 <= level.time)
	{
		G_ExplodeMissile(ent);
		return;
	}

	/*
	if(ent->parent->health <= 0)
	{
		ent->nextthink = level.time + 15000;
		ent->think = G_ExplodeMissile;
		return;
	}
	*/

	/*
	if(ent->parent && ent->parent->client)
	{
		ignorechaff = (ent->parent->client->ps.powerups[PW_ACCURACY] > 0);
	}
	*/

	while((blip = G_FindRadius(blip, ent->r.currentOrigin, 2000)) != NULL)
	{
#if 0
		if(blip->s.weapon == WP_CHAFF)
		{
			if(ignorechaff)
			{
				continue;
			}

			chaff = qtrue;
		}
		else
#endif
		{
			chaff = qfalse;

			if(blip->client == NULL)
				continue;

			if(blip == ent->parent)
				continue;

			if(blip->health <= 0)
				continue;

			if(blip->client->sess.sessionTeam >= TEAM_SPECTATOR)
				continue;

			if((g_gametype.integer == GT_TEAM || g_gametype.integer == GT_CTF) && OnSameTeam(blip, ent->parent))
				continue;
		}

		if(!G_IsVisible(ent, blip->r.currentOrigin))
			continue;

		VectorSubtract(blip->r.currentOrigin, ent->r.currentOrigin, blipdir);

		if(chaff)
		{
			VectorScale(blipdir, 0.5, blipdir);
		}

		if((target == NULL) || (VectorLength(blipdir) < VectorLength(dir)))
		{
			if(chaff)
			{
				VectorScale(blipdir, 2, blipdir);
			}

			angle = AngleBetweenVectors(ent->r.currentAngles, blipdir);

			if(angle < 120.0f)
			{
				// We add it as our target
				target = blip;
				VectorCopy(blipdir, dir);
			}
		}
	}

	if(target == NULL)
	{
		ent->nextthink = level.time + HOMING_THINK_TIME;	// + 10000;
		ent->think = G_HomingMissile;
	}
	else
	{
		// for exact trajectory calculation, set current point to base.
		VectorCopy(ent->r.currentOrigin, ent->s.pos.trBase);

		VectorNormalize(dir);
		// 0.5 is swing rate.
		VectorScale(dir, 0.5, dir);
		VectorAdd(dir, ent->r.currentAngles, dir);

		// turn nozzle to target angle
		VectorNormalize(dir);
		VectorCopy(dir, ent->r.currentAngles);

		// scale direction, put into trDelta
		if(g_rocketAcceleration.integer)
		{
			// use acceleration instead of linear velocity
			ent->s.pos.trType = TR_ACCELERATION;
			ent->s.pos.trAcceleration = g_rocketAcceleration.value;
			VectorScale(dir, g_rocketVelocity.value, ent->s.pos.trDelta);
		}
		else
		{
			ent->s.pos.trType = TR_LINEAR;
			VectorScale(dir, g_rocketVelocity.value * 0.25, ent->s.pos.trDelta);
		}

		ent->s.pos.trTime = level.time;

		SnapVector(ent->s.pos.trDelta);	// save net bandwidth
		ent->nextthink = level.time + HOMING_THINK_TIME;	// decrease this value also makes fast swing
		ent->think = G_HomingMissile;

		//G_Printf("targeting %s\n", target->classname);
	}
}
Esempio n. 4
0
/*
================
G_HomingMissile

From XREAL r3036
================
*/
void G_HomingMissile(gentity_t * ent)
{
	gentity_t      *target = NULL;
	gentity_t      *blip = NULL;
	vec3_t          dir, blipdir;
	vec_t           angle;
	const int		HOMING_THINK_TIME = 60;

#ifdef TA_WEAPSYS // XREAL: spawnTime
	// explode after 15 seconds without a hit
	if (bg_projectileinfo[ent->s.weapon].timetolive != -1
		&& ent->spawnTime + bg_projectileinfo[ent->s.weapon].timetolive <= level.time)
	{
		G_ExplodeMissile(ent);
		return;
	}
#endif

	/*
	if(ent->parent->health <= 0)
	{
		ent->nextthink = level.time + 15000;
		ent->think = G_ExplodeMissile;
		return;
	}
	*/

	while((blip = G_FindRadius(blip, ent->r.currentOrigin, 2000)) != NULL)
	{
		if(blip->player == NULL)
			continue;

		if(blip == ent->parent)
			continue;

		if(blip->health <= 0)
			continue;

		if(blip->flags & FL_NOTARGET)
			continue;

		if(blip->player->sess.sessionTeam >= TEAM_SPECTATOR)
			continue;

		if(OnSameTeam(blip, ent->parent))
			continue;

		if(!G_IsVisible(ent->s.number, ent->r.currentOrigin, blip->r.currentOrigin))
			continue;

		VectorSubtract(blip->r.currentOrigin, ent->r.currentOrigin, blipdir);

		if((target == NULL) || (VectorLength(blipdir) < VectorLength(dir)))
		{
			angle = AngleBetweenVectors(ent->r.currentAngles, blipdir);

			if(angle < 120.0f)
			{
				// We add it as our target
				target = blip;
				VectorCopy(blipdir, dir);
			}
		}
	}

	if (target == NULL)
	{
		ent->nextthink = level.time + HOMING_THINK_TIME;	// + 10000;
		ent->think = G_HomingMissile;
	}
	else
	{
		// for exact trajectory calculation, set current point to base.
		VectorCopy(ent->r.currentOrigin, ent->s.pos.trBase);

		VectorNormalize(dir);
		// 0.5 is swing rate.
		VectorScale(dir, 0.5, dir);
		VectorAdd(dir, ent->r.currentAngles, dir);

		// turn nozzle to target angle
		VectorNormalize(dir);
		VectorCopy(dir, ent->r.currentAngles);

		ent->s.pos.trTime = level.time;
		G_SetMissileVelocity(ent, dir, ent->s.weapon);

		ent->nextthink = level.time + HOMING_THINK_TIME;	// decrease this value also makes fast swing
		ent->think = G_HomingMissile;

		//G_Printf("targeting %s\n", target->classname);
	}
}