Ejemplo n.º 1
0
void boss_locktarget (edict_t *self, int flash_number, vec3_t forward, vec3_t start)
{
	int		i;
	vec3_t	v;

	if (self->owner->client->weapon_mode) // secondary attack
	{
		VectorCopy(self->enemy->s.origin, v);
		v[2]-=100; // aim at floor
		VectorSubtract(v, self->s.origin, forward);
	}
	else
	{
		MonsterAim(self, -1, TANK_ROCKET_SPEED, true, flash_number, forward, start);
	}

	VectorNormalize(forward);
	vectoangles(forward, forward);
	ValidateAngles(forward);

	// set view angles to target
	for (i = 0 ; i < 3 ; i++)
		self->owner->client->ps.pmove.delta_angles[i] = ANGLE2SHORT(forward[i]-self->owner->client->resp.cmd_angles[i]);
	VectorCopy(forward, self->owner->client->ps.viewangles);
	VectorCopy(forward, self->owner->client->v_angle);
}
Ejemplo n.º 2
0
void BombArea (edict_t *ent, float skill_mult, float cost_mult)
{
	vec3_t	angles, offset;
	vec3_t	forward, right, start, end;
	trace_t	tr;
	edict_t *bomb;
	int		cost=COST_FOR_BOMB*cost_mult;

#ifdef OLD_NOLAG_STYLE
	// 3.5 don't allow bomb area to prevent lag
	if (nolag->value)
	{
		safe_cprintf(ent, PRINT_HIGH, "Bomb area is temporarily disabled to prevent lag.\n");
		return;
	}
#endif

	AngleVectors (ent->client->v_angle, forward, right, NULL);
	VectorSet(offset, 0, 7, ent->viewheight-8);
	P_ProjectSource(ent->client, ent->s.origin, offset, forward, right, start);
	VectorMA(start, 8192, forward, end);
	tr = gi.trace(start, NULL, NULL, end, ent, MASK_SOLID);

	// make sure this is a floor
	vectoangles(tr.plane.normal, angles);
	ValidateAngles(angles);
	if (angles[PITCH] == FLOOR_PITCH)
	{
		VectorCopy(tr.endpos, start);
		VectorCopy(tr.endpos, end);
		end[2] += BOMBAREA_FLOOR_HEIGHT;
		tr = gi.trace(start, NULL, NULL, end, ent, MASK_SOLID);
	}
	else if (angles[PITCH] != CEILING_PITCH)
	{
		safe_cprintf(ent, PRINT_HIGH, "You must look at a ceiling or floor to cast this spell.\n");
		return;
	}

	bomb = G_Spawn();
	bomb->solid = SOLID_NOT;
	bomb->svflags |= SVF_NOCLIENT;
	VectorClear(bomb->velocity);
	VectorClear(bomb->mins);
	VectorClear(bomb->maxs);
	bomb->owner = ent;
	bomb->delay = level.time + BOMBAREA_DURATION + BOMBAREA_STARTUP_DELAY;
	bomb->nextthink = level.time + BOMBAREA_STARTUP_DELAY;
	bomb->dmg = 50 + 10*ent->myskills.abilities[BOMB_SPELL].current_level*skill_mult;
	bomb->think = bombarea_think;
	VectorCopy(tr.endpos, bomb->s.origin);
	VectorCopy(tr.endpos, bomb->s.old_origin);
	VectorCopy(angles, bomb->s.angles);
	gi.linkentity(bomb);

    gi.sound(bomb, CHAN_WEAPON, gi.soundindex("abilities/meteorlaunch_short.wav"), 1, ATTN_NORM, 0);
	ent->client->pers.inventory[power_cube_index] -= cost;

	ent->client->ability_delay = level.time + (DELAY_BOMB * cost_mult);
}
Ejemplo n.º 3
0
void BuildSupplyStation (edict_t *ent, int cost, float skill_mult, float delay_mult)
{
	vec3_t	angles, forward, end;
	edict_t *station;
	trace_t	tr;

	station = G_Spawn();
	station->creator = ent;
	station->think = supplystation_think;
	station->nextthink = level.time + STATION_BUILD_TIME * delay_mult;
	station->s.modelindex = gi.modelindex ("models/objects/dmspot/tris.md2");
	station->s.effects |= EF_PLASMA;
	station->s.renderfx |= RF_IR_VISIBLE;
	station->solid = SOLID_BBOX;
	station->movetype = MOVETYPE_TOSS;
	station->clipmask = MASK_MONSTERSOLID;
	station->mass = 500;
	station->mtype = SUPPLY_STATION;
	station->classname = "supplystation";
	station->takedamage = DAMAGE_YES;
	station->health = 1000;
	station->monsterinfo.level = ent->myskills.abilities[SUPPLY_STATION].current_level * skill_mult;
	station->touch = V_Touch;
	station->die = supplystation_die;
	VectorSet(station->mins, -32, -32, -24);
	VectorSet(station->maxs, 32, 32, -16);
	station->s.skinnum = 1;
	// starting position for station
	AngleVectors (ent->client->v_angle, forward, NULL, NULL);
	VectorMA(ent->s.origin, 128, forward, end);
	tr = gi.trace(ent->s.origin, NULL, NULL, end, ent, MASK_SOLID);
	VectorCopy(tr.endpos, end);
	vectoangles(tr.plane.normal, angles);
	ValidateAngles(angles);
	// player is aiming at the ground
	if ((tr.fraction != 1.0) && (tr.endpos[2] < ent->s.origin[2]) && (angles[PITCH] == 270))
		end[2] += abs(station->mins[2])+1;
	// make sure station doesn't spawn in a solid
	tr = gi.trace(end, station->mins, station->maxs, end, NULL, MASK_SHOT);
	if (tr.contents & MASK_SHOT)
	{
		safe_cprintf (ent, PRINT_HIGH, "Can't build supply station there.\n");
		G_FreeEdict(station);
		return;
	}
	VectorCopy(tr.endpos, station->s.origin);
	gi.linkentity(station);

	ent->supplystation = station;
	ent->client->ability_delay = level.time + STATION_DELAY * delay_mult;
	ent->client->pers.inventory[power_cube_index] -= cost;
	ent->holdtime = level.time + STATION_BUILD_TIME * delay_mult;
	gi.sound(station, CHAN_ITEM, gi.soundindex("weapons/repair.wav"), 1, ATTN_NORM, 0);
}
Ejemplo n.º 4
0
void minisentry_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
{
	V_Touch(self, other, plane, surf);

	//4.2 if this is a player-monster (morph), then we should be looking at the client/player
	if (PM_MonsterHasPilot(other))
		other = other->activator;

	if (other && other->inuse && (other == self->creator) && (level.time > self->random))
	{
		safe_cprintf(self->creator, PRINT_HIGH, "Rotating sentry gun 45 degrees.\n");

		VectorCopy(self->move_angles, self->s.angles); // reset angles to default
		self->s.angles[YAW]+=45;
		ValidateAngles(self->s.angles);
		VectorCopy(self->s.angles, self->move_angles); // update default angles
		self->random = level.time + 1;
		self->nextthink = level.time + 2;
	}
}
Ejemplo n.º 5
0
void minisentry_lockon (edict_t *self)
{
	float	max, temp;
	vec3_t	angles, v;

	// curse causes minisentry to fail to lock-on to enemy
	if ((que_typeexists(self->curses, CURSE)) && random() <= 0.8)
		return;

	temp = self->yaw_speed;
	self->yaw_speed *= 3;
	VectorSubtract(self->enemy->s.origin, self->s.origin, v);
	vectoangles(v, angles);
	self->ideal_yaw = vectoyaw(v);
	M_ChangeYaw(self);
	self->yaw_speed = temp; // restore original yaw speed
	self->s.angles[PITCH] = angles[PITCH];
	ValidateAngles(self->s.angles);
	// maximum pitch is 65 degrees in either direction
	if (self->enemy->s.origin[2] > self->s.origin[2]) // if the enemy is above
	{	
		if (self->owner && self->owner->style == SENTRY_FLIPPED)
			max = 340; // allow 20 degrees up
		else
			max = 315; // allow 45 degrees up
		if (self->s.angles[PITCH] < max)
			self->s.angles[PITCH] = max;
	}
	else
	{
		if (self->owner && self->owner->style == SENTRY_FLIPPED)
			max = 45; // allow 45 degrees down
		else
			max = 20; // allow 20 degrees down
		if (self->s.angles[PITCH] > max)
			self->s.angles[PITCH] = max;
	}
}
Ejemplo n.º 6
0
void P_FollowWall (edict_t *ent)
{
	int		turns=0, num=90;
	vec3_t	forward, right, start, end;
	vec3_t	offset, angles;
	trace_t	tr;
	
	AngleVectors (ent->client->v_angle, forward, right, NULL);
	VectorSet(offset, 0, 7,  ent->viewheight-8);
	P_ProjectSource(ent->client, ent->s.origin, offset, forward, right, start);
	VectorMA(start, 8192, forward, end);
	tr = gi.trace(start, NULL, NULL, end, ent, MASK_SOLID);
	VectorCopy(tr.endpos, end);
	vectoangles(tr.plane.normal, angles);
	ValidateAngles(angles);
	VectorCopy(tr.endpos, start);

	gi.WriteByte (svc_temp_entity);
	gi.WriteByte (TE_BFG_LASER);
	gi.WritePosition (ent->s.origin);
	gi.WritePosition (tr.endpos);
	gi.multicast (ent->s.origin, MULTICAST_PHS);

	while (turns < 10)
	{
		angles[YAW] += num;	
		forward[0] = cos(DEG2RAD(angles[YAW]));
		forward[1] = sin(DEG2RAD(angles[YAW]));
		forward[2] = 0;
		VectorMA(start, 8192, forward, end);
		tr = gi.trace(start, NULL, NULL, end, ent, MASK_SOLID);

		if (tr.startsolid || tr.allsolid)
		{
			num = -90;
			gi.dprintf("fail\n");
			continue;
		}

		gi.WriteByte (svc_temp_entity);
		gi.WriteByte (TE_BFG_LASER);
		gi.WritePosition (start);
		gi.WritePosition (tr.endpos);
		gi.multicast (start, MULTICAST_PHS);

		VectorCopy(tr.endpos, start);
		vectoangles(tr.plane.normal, angles);
		ValidateAngles(angles);
		turns++;
		//gi.dprintf("turn %d %d degrees\n", turns, (int)angles[YAW]);
	}
/*
	while (1)
	{
		angles[YAW] += num;	
		forward[0] = cos(DEG2RAD(angles[YAW]));
		forward[1] = sin(DEG2RAD(angles[YAW]));
		forward[2] = 0;
		VectorMA(start, 48, forward, end);
		tr = gi.trace(start, NULL, NULL, end, ent, MASK_SOLID);
		if (tr.fraction < 1)
		{
			if (num == -180)
				break;
			num = -180;
			continue;
		}
		gi.WriteByte (svc_temp_entity);
		gi.WriteByte (TE_BFG_LASER);
		gi.WritePosition (start);
		gi.WritePosition (tr.endpos);
		gi.multicast (start, MULTICAST_PHS);
		break;
	}
*/
}
Ejemplo n.º 7
0
/*
===============
M_walkmove
===============
*/
qboolean M_walkmove (edict_t *ent, float yaw, float dist)
{
	float	original_yaw=yaw;//GHz
	vec3_t	move;
	
	if (!ent->groundentity && !(ent->flags & (FL_FLY|FL_SWIM)))
		return false;

	yaw = yaw*M_PI*2 / 360;
	
	move[0] = cos(yaw)*dist;
	move[1] = sin(yaw)*dist;
	move[2] = 0;
	
	if (IsABoss(ent) || ent->mtype == P_TANK)
	{
		//return M_Move(ent, move, true);
		if (!M_Move(ent, move, true))
		{
			float	angle1, angle2, delta1, delta2, cl_yaw, ideal_yaw, mult;
			vec3_t	start, end, angles, right;
			trace_t tr;

			// get monster angles
			AngleVectors(ent->s.angles, NULL, right, NULL);
			//vectoangles(forward, forward);
			vectoangles(right, right);

			// get client yaw (FIXME: use mons yaw instead?)
			cl_yaw = ent->s.angles[YAW];
			AngleCheck(&cl_yaw);

			// trace from monster to wall
			VectorCopy(ent->s.origin, start);
			VectorMA(start, 64, move, end);
			tr = gi.trace(start, ent->mins, ent->maxs, end, ent, MASK_SHOT);

			// get monster angles in relation to wall
			VectorCopy(tr.plane.normal, angles);
			vectoangles(angles, angles);

			// monster is moving sideways, so use sideways vector instead
			if ((int)original_yaw==(int)right[YAW])
			{
				cl_yaw = right[YAW];
				AngleCheck(&cl_yaw);
			}

			// delta between monster yaw and wall yaw should be no more than 90 degrees
			// else, turn wall angles around 180 degrees
			if (fabs(cl_yaw-angles[YAW]) > 90)
				angles[YAW]+=180;
			ValidateAngles(angles);

			// possible escape angle 1
			angle1 = angles[YAW]+90;
			AngleCheck(&angle1);
			delta1 = fabs(angle1-cl_yaw);
			// possible escape angle 2
			angle2 = angles[YAW]-90;
			AngleCheck(&angle2);
			delta2 = fabs(angle2-cl_yaw);

			// take the shorter route
			if (delta1 > delta2)
			{
				ideal_yaw = angle2;
				mult = 1.0-delta2/90.0;
			}
			else
			{
				ideal_yaw = angle1;
				mult = 1.0-delta1/90.0;
			}
			
			// go full speed if we are turned at least half way towards ideal yaw
			if (mult >= 0.5)
				mult = 1.0;

			// modify speed
			dist*=mult;

			// recalculate with new heading
			yaw = ideal_yaw*M_PI*2 / 360;
			move[0] = cos(yaw)*dist;
			move[1] = sin(yaw)*dist;
			move[2] = 0;
				
			//gi.dprintf("can't walk wall@%.1f you@%.1f ideal@%.1f\n", angles[YAW], cl_yaw, ideal_yaw);

			return M_Move(ent, move, true);
		}
		return true;
	}
	else if (level.time > ent->holdtime) // stay in-place for medic healing
		return SV_movestep(ent, move, true);
	else
		return false;
}