Example #1
0
void parasite_drain_attack (edict_t *self)
{
	vec3_t	offset, start, f, r, end, dir;
	trace_t	tr;
	int damage;

	AngleVectors (self->s.angles, f, r, NULL);
	VectorSet (offset, 24, 0, 6);
	G_ProjectSource (self->s.origin, offset, f, r, start);

	VectorCopy (self->enemy->s.origin, end);
	if (!parasite_drain_attack_ok(start, end))
	{
		end[2] = self->enemy->s.origin[2] + self->enemy->maxs[2] - 8;
		if (!parasite_drain_attack_ok(start, end))
		{
			end[2] = self->enemy->s.origin[2] + self->enemy->mins[2] + 8;
			if (!parasite_drain_attack_ok(start, end))
				return;
		}
	}
	VectorCopy (self->enemy->s.origin, end);

	tr = gi.trace (start, NULL, NULL, end, self, MASK_SHOT);
	if (tr.ent != self->enemy)
		return;

	if (self->s.frame == FRAME_drain03)
	{
		damage = 5;
		gi.sound (self->enemy, CHAN_AUTO, sound_impact, 1, ATTN_NORM, 0);
	}
	else
	{
		if (self->s.frame == FRAME_drain04)
			gi.sound (self, CHAN_WEAPON, sound_suck, 1, ATTN_NORM, 0);
		damage = 2;
	}

	gi.WriteByte (svc_temp_entity);
	gi.WriteByte (TE_PARASITE_ATTACK);
	gi.WriteShort (self - g_edicts);
	gi.WritePosition (start);
	gi.WritePosition (end);
	gi.multicast (self->s.origin, MULTICAST_PVS);

	VectorSubtract (start, end, dir);
	T_Damage (self->enemy, self, self, dir, self->enemy->s.origin, vec3_origin, damage, 0, DAMAGE_NO_KNOCKBACK, MOD_UNKNOWN);
}
Example #2
0
/*
 * =====================
 * check_shot_blocked
 *
 * chance_attack: 0-1, probability that monster will attack if it has a clear shot
 * =====================
 */
qboolean check_shot_blocked(edict_t *monster, float chance_attack)
{
    // only check for players, and random check
    if (!monster->enemy || !monster->enemy->client || (random() < chance_attack))
    {
        return false;
    }

    // special case for parasite
    if (strcmp(monster->classname, "monster_parasite") == 0)
    {
        trace_t trace;
        vec3_t  forward, right, start, end, probeOffset;
        int     i;

        VectorSet(probeOffset, 24, 0, 6);
        VectorCopy(monster->enemy->s.origin, end);
        AngleVectors(monster->s.angles, forward, right, NULL);
        G_ProjectSource(monster->s.origin, probeOffset, forward, right, start);
        for (i = 0; i < 3; i++)
        {
            switch (i)
            {
            case 0:
                break;

            case 1:
                end[2] = monster->enemy->s.origin[2] + monster->enemy->maxs[2] - 8;
                break;

            case 2:
                end[2] = monster->enemy->s.origin[2] + monster->enemy->mins[2] + 8;
                break;
            }
            if (parasite_drain_attack_ok(start, end))
            {
                break;
            }
            if (i == 2)
            {
                return false;
            }
        }
        VectorCopy(monster->enemy->s.origin, end);

        trace = gi.trace(start, NULL, NULL, end, monster, MASK_SHOT);
        if (trace.ent != monster->enemy)
        {
            monster->monsterinfo.aiflags |= AI_BLOCKED;
            if (monster->monsterinfo.attack)
            {
                monster->monsterinfo.attack(monster);
            }
            monster->monsterinfo.aiflags &= ~AI_BLOCKED;
            return true;
        }
    }
    return false;
}
Example #3
0
qboolean parasite_checkattack (edict_t *self)
{
	vec3_t	f, r, offset, start, end;
	trace_t	tr;
	qboolean retval;

	retval = M_CheckAttack (self);

	if (!retval)
		return false;

	AngleVectors (self->s.angles, f, r, NULL);
	VectorSet (offset, 24, 0, 6);
	G_ProjectSource (self->s.origin, offset, f, r, start);

	VectorCopy (self->enemy->s.origin, end);
	if (!parasite_drain_attack_ok(start, end))
	{
		end[2] = self->enemy->s.origin[2] + self->enemy->maxs[2] - 8;
		if (!parasite_drain_attack_ok(start, end))
		{
			end[2] = self->enemy->s.origin[2] + self->enemy->mins[2] + 8;
			if (!parasite_drain_attack_ok(start, end))
				return false;
		}
	}
	VectorCopy (self->enemy->s.origin, end);

	tr = gi.trace (start, NULL, NULL, end, self, MASK_SHOT);
	if (tr.ent != self->enemy)
	{
		self->monsterinfo.aiflags |= AI_BLOCKED;
		
		if(self->monsterinfo.attack)
			self->monsterinfo.attack(self);
		
		self->monsterinfo.aiflags &= ~AI_BLOCKED;
		return true;
	}
	return true;	// Knightmare- warning fix
}