示例#1
0
文件: magmine.c 项目: zardoru/vrxcl
void magmine_think(edict_t *self) {
    // check for valid position
    if (gi.pointcontents(self->s.origin) & CONTENTS_SOLID) {
        gi.dprintf("WARNING: A mag mine was removed from map due to invalid position.\n");
        safe_cprintf(self->creator, PRINT_HIGH, "Your mag mine was removed.\n");
        self->creator->magmine = NULL;
        G_FreeEdict(self);
        return;
    }

    if (!self->enemy) {
        if (magmine_findtarget(self)) {
            magmine_attack(self);
            magmine_throwsparks(self);
        }
    } else if (G_ValidTarget(self, self->enemy, true)
               && (entdist(self, self->enemy) <= self->dmg_radius)) {
        magmine_attack(self);
        magmine_throwsparks(self);
    } else {
        self->enemy = NULL;
    }

    //magmine_seteffects(self);
    M_SetEffects(self);//4.5
    self->nextthink = level.time + FRAMETIME;
}
示例#2
0
void mytank_reattack_blaster (edict_t *self)
{
	float r, range;

	if (G_ValidTarget(self, self->enemy, true))
	{
		r = random();
		range = entdist(self, self->enemy);

		// medium range = 80% chance to continue attack
		if (range <= 512)
		{
			if (r <= 0.8)
				self->monsterinfo.currentmove = &mytank_move_reattack_blast;
			else
				self->monsterinfo.currentmove = &mytank_move_attack_post_blast;
		}
		// long range = 50% chance to continue attack
		else
		{
			if (r <= 0.5)
				self->monsterinfo.currentmove = &mytank_move_reattack_blast;
			else
				self->monsterinfo.currentmove = &mytank_move_attack_post_blast;
		}
	}
	else
	{
		self->monsterinfo.currentmove = &mytank_move_attack_post_blast;
	}

	// don't call the attack function again for awhile!
	self->monsterinfo.attack_finished = level.time + 2.0 + random();
}
示例#3
0
void gunner_attack (edict_t *self)
{
	float	r = random();
	float	dist = entdist(self, self->enemy);

	// short range (20% chance grenade, 80% chance run and shoot)
	if (dist <= 128)
	{
		if (r <= 0.2)
			self->monsterinfo.currentmove = &mygunner_move_attack_grenade;
		else
			self->monsterinfo.currentmove = &mygunner_move_runandshoot;
	}
	// medium range (100% run and shoot)
	else if (dist <= 512)
	{
		self->monsterinfo.currentmove = &mygunner_move_runandshoot;
	}
	// long range (50% chance chaingun)
	else
	{
		if (r <= 0.5)
			self->monsterinfo.currentmove = &mygunner_move_attack_chain;
		else
			self->monsterinfo.attack_finished = level.time + 2.0;// don't attack, try to get closer
	}
}
示例#4
0
void chick_fire_attack (edict_t *self)
{
	float r = random();
	float range = entdist(self, self->enemy);

	// medium-long range
	if (range <= 768)
	{
		// 30% chance to cast meteor, 70% chance to shoot fireballs
		if (r <= 0.3)
		{
			self->monsterinfo.currentmove = &mychick_move_slash;
		}
		else
		{
			if (self->monsterinfo.aiflags & AI_STAND_GROUND)
				self->monsterinfo.currentmove = &mychick_move_attack1;
			else
				mychick_runandshoot(self);
		}
	}
	// long range
	else
		self->monsterinfo.currentmove = &mychick_move_slash;// always cast meteor

	// don't call the attack function again for awhile!
	self->monsterinfo.attack_finished = level.time + 1;
}
示例#5
0
void mytank_refire_rocket (edict_t *self)
{
	float	r, range;
	
	if (G_ValidTarget(self, self->enemy, true))
	{
		r = random();
		range = entdist(self, self->enemy);

		// medium range
		if (range <= 512)
		{
			if (r <= 0.8)
				self->monsterinfo.currentmove = &mytank_move_attack_fire_rocket;
			else
				self->monsterinfo.currentmove = &mytank_move_attack_post_rocket;
		}
		// long range
		else
		{
			if (r <= 0.5)
				self->monsterinfo.currentmove = &mytank_move_attack_fire_rocket;
			else
				self->monsterinfo.currentmove = &mytank_move_attack_post_rocket;
		}
	}
	// end attack sequence
	else
	{
		self->monsterinfo.currentmove = &mytank_move_attack_post_rocket;
	}

	// don't call the attack function again for awhile!
	self->monsterinfo.attack_finished = level.time + 2.5 + random();
}
示例#6
0
void mytank_chain_refire (edict_t *self)
{
	float	r, range;

	// is enemy still valid?
	if (G_ValidTarget(self, self->enemy, true))
	{
		r = random();
		range = entdist(self, self->enemy);

		// medium range = 50% chance to continue attack
		if (range <= 512)
		{
			if (r <= 0.5)
				self->monsterinfo.currentmove = &mytank_move_attack_chain;
			else
				self->monsterinfo.currentmove = &mytank_move_attack_chain_end;

		}
		// long range = 80% chance to continue attack
		else if (r <= 0.8)
			self->monsterinfo.currentmove = &mytank_move_attack_chain;
		// end attack sequence
		else
			self->monsterinfo.currentmove = &mytank_move_attack_chain_end;
	}
	else
	{
		self->monsterinfo.currentmove = &mytank_move_attack_chain_end;
	}
	
	// don't call the attack function again for awhile!
	self->monsterinfo.attack_finished = level.time + 2.0 + random();
}
示例#7
0
void makron_attack(edict_t *self)
{
	float	r, range;

	r = random();
	range = entdist(self, self->enemy);

	// medium range
	if (range <= 768)
	{
		if (r <= 0.2)
			self->monsterinfo.currentmove = &makron_move_attack5; // railgun
		else if (r <= 0.6)
			self->monsterinfo.currentmove = &makron_move_attack4; // hyperblaster
		else
			self->monsterinfo.currentmove = &makron_move_attack3; // bfg	
	}
	// long range
	else
	{
		if (r <= 0.3)
			self->monsterinfo.currentmove = &makron_move_attack3; // bfg	
		else
			self->monsterinfo.currentmove = &makron_move_attack5; // railgun
	}

	self->monsterinfo.attack_finished = level.time + GetRandom(1, 3);
}
示例#8
0
void gunner_stand_attack (edict_t *self)
{
	if (entdist(self, self->enemy) <= 384 && random() <= 0.8)
		self->monsterinfo.currentmove = &mygunner_move_attack_grenade;
	else
		self->monsterinfo.currentmove = &mygunner_move_attack_chain;
}
示例#9
0
void mymedic_attack(edict_t *self)
{
	float	dist, r;

	if (!self->enemy)
		return;
	if (!self->enemy->inuse)
		return;

	dist = entdist(self, self->enemy);
	r = random();

	if ((self->monsterinfo.aiflags & AI_MEDIC)
		&& ((self->enemy->health < 1 || OnSameTeam(self, self->enemy))))
	{
		if (dist <= 256)
			self->monsterinfo.currentmove = &mymedic_move_attackCable;
		return;
	}

	if (dist <= 256)
	{
		if (r <= 0.2)
			self->monsterinfo.currentmove = &mymedic_move_attackHyperBlaster;
		else
			self->monsterinfo.currentmove = &mymedic_move_attackBlaster;
	}
	else
	{
		if (r <= 0.3)
			self->monsterinfo.currentmove = &mymedic_move_attackBlaster;
		else
			self->monsterinfo.currentmove = &mymedic_move_attackHyperBlaster;
	}
}
示例#10
0
void commander_attack (edict_t *self)
{
	float r = random();
	float range = entdist(self, self->enemy);

	// short range attack
	if (range <= 128 && r <= 0.6)
	{
		self->monsterinfo.currentmove = &mytank_move_strike;
	}
	else
	{
		// try to teleport to enemy if we are not standing ground
		if (!(self->monsterinfo.aiflags & AI_STAND_GROUND))
		{
			if (TeleportNearTarget(self, self->enemy, 16.0))
			{
				if (r <= 0.5)
				{
					self->monsterinfo.currentmove = &mytank_move_strike;
					self->monsterinfo.attack_finished = level.time + 0.5;
					return;
				}

				// recalculate enemy distance
				range = entdist(self, self->enemy);
			}
		}

		// medium range attack
		if (range <= 512)
		{
			if (r <= 0.2)
				self->monsterinfo.currentmove = &mytank_move_attack_blast;
			else
				self->monsterinfo.currentmove = &mytank_move_attack_fire_rocket;
		}
		// long range attack
		else
		{
			self->monsterinfo.currentmove = &mytank_move_attack_blast;
		}
	}

	// don't call attack function for awhile
	self->monsterinfo.attack_finished = level.time + 2.0;
}
示例#11
0
static qboolean parasite_cantarget (edict_t *self, edict_t *target)
{
	int para_range = PARASITE_ATTACK_RANGE;

	return (G_EntExists(target) && !que_typeexists(target->curses, CURSE_FROZEN) 
		&& !OnSameTeam(self, target) && visible(self, target) && nearfov(self, target, 45, 45) 
		&& (entdist(self, target) <= para_range));
}
示例#12
0
void mymedic_cable_continue (edict_t *self)
{
	// if target still needs healing, loop heal frames
	if (M_ValidMedicTarget(self, self->enemy) && (entdist(self, self->enemy) <= 256))
	{
		self->s.frame = 218;
		mymedic_cable_attack(self);
	}
}
示例#13
0
void m_soldier_attack1_refire1 (edict_t *self)
{
	// continue firing if the enemy is still close, or we are standing ground
	if (G_ValidTarget(self, self->enemy, true) && (random() <= 0.9)
		&& ((entdist(self, self->enemy) <= 512) || (self->monsterinfo.aiflags & AI_STAND_GROUND)))
	{
		self->s.frame = FRAME_attak102;
		self->monsterinfo.attack_finished = level.time + 2;
	}
}
示例#14
0
void mygunner_delay (edict_t *self)
{
	if (!self->enemy || !self->enemy->inuse)
		return;

	// delay next attack if we're not standing ground, our enemy isn't within close range
	// (we need to get closer) and we are not a tank commander/boss
	if (!(self->monsterinfo.aiflags & AI_STAND_GROUND) && (entdist(self, self->enemy) > 256))
		self->monsterinfo.attack_finished = level.time + GetRandom(5, 20)*FRAMETIME;
}
示例#15
0
void mybrain_melee (edict_t *self)
{
	if (entdist(self, self->enemy) < MELEE_DISTANCE)
	{
		if (random() <= 0.5)
			self->monsterinfo.currentmove = &mybrain_move_attack1;
		else
			self->monsterinfo.currentmove = &mybrain_move_attack2;
	}
}
示例#16
0
void mygunner_continue (edict_t *self)
{
	if (G_ValidTarget(self, self->enemy, true) && (random() <= 0.9) 
		&& (entdist(self, self->enemy) <= 512))
		self->monsterinfo.currentmove = &mygunner_move_runandshoot;
	else
		self->monsterinfo.currentmove = &mygunnermove_run;

	// don't call the attack function again for awhile!
	self->monsterinfo.attack_finished = level.time + 1.0;
}
示例#17
0
void mymedic_heal (edict_t *self)
{
	// stop healing our target died, if they are fully healed, or
	// they have gone out of range while we are standing ground (can't reach them)
	if (!G_EntIsAlive(self->enemy) || !M_NeedRegen(self->enemy)
		|| ((self->monsterinfo.aiflags & AI_STAND_GROUND) 
		&& (entdist(self, self->enemy) > 256)))
	{
		self->enemy = NULL;
		mymedic_stand(self);
		return;
	}

	// continue healing if our target is still in range and
	// there are no enemies around
	if (OnSameTeam(self, self->enemy) && (entdist(self, self->enemy) <= 256)
		&& !mymedic_findenemy(self))
		self->monsterinfo.currentmove = &mymedic_move_attackCable;
	else
		mymedic_run(self);
}
示例#18
0
void gunner_refire_grenade (edict_t *self)
{
	// continue firing unless enemy is no longer valid or out of range
	if (G_ValidTarget(self, self->enemy, true) && (random() <= 0.8)
		&& (entdist(self, self->enemy) <= 384))
		self->monsterinfo.currentmove = &mygunner_move_attack_grenade;
	else
		self->monsterinfo.currentmove = &mygunner_move_attack_grenade_end;

	// don't call the attack function again for awhile!
	self->monsterinfo.attack_finished = level.time + 0.5;
}
示例#19
0
void minisentry_pain (edict_t *self, edict_t *other, float kick, int damage)
{
	if (!self->enemy && G_ValidTarget(self, other, true) 
		&& (entdist(self, other)<SENTRY_ATTACK_RANGE))
		self->enemy = other;

	if (level.time < self->pain_debounce_time)
		return;

	self->pain_debounce_time = level.time + 2;
	gi.sound (self, CHAN_VOICE, gi.soundindex ("tank/tnkpain2.wav"), 1, ATTN_NORM, 0);	
}
示例#20
0
void m_soldier_runandshoot_continue (edict_t *self)
{
	if (G_ValidTarget(self, self->enemy, true) && (random() <= 0.9) 
		&& (entdist(self, self->enemy) <= 512))
	{
		self->monsterinfo.currentmove = &m_soldier_move_runandshoot;
		self->monsterinfo.attack_finished = level.time + 2;
		return;
	}

	self->monsterinfo.currentmove = &m_soldier_move_run;
}
示例#21
0
void mymedic_refire (edict_t *self)
{
	if (G_ValidTarget(self, self->enemy, true) && (random() <= 0.5) 
		&& (entdist(self, self->enemy) <= 512))
	{
		self->s.frame = FRAME_attack19;
		return;
	}

	self->monsterinfo.currentmove = &mymedic_move_run;
	self->monsterinfo.attack_finished = level.time + random() + 1;

}
示例#22
0
void mygunner_refire_chain(edict_t *self)
{
	// keep firing
	if (G_ValidTarget(self, self->enemy, true) && (random() <= 0.8)
		&& entdist(self, self->enemy) > 128)
		self->monsterinfo.currentmove = &mygunner_move_fire_chain;
	else
		self->monsterinfo.currentmove = &mygunner_move_endfire_chain;

	//mygunner_delay(self);

	// don't call the attack function again for awhile!
	self->monsterinfo.attack_finished = level.time + 0.5;
}
示例#23
0
void mychick_rerocket(edict_t *self)
{
	if (G_ValidTarget(self, self->enemy, true)) 
	{
		if (random() <= 0.8 && (entdist(self, self->enemy) <= 512 || (self->monsterinfo.aiflags & AI_STAND_GROUND)))
			self->monsterinfo.currentmove = &mychick_move_attack1;
		else
			self->monsterinfo.currentmove = &mychick_move_end_attack1;
	}
	else
		self->monsterinfo.currentmove = &mychick_move_end_attack1;

	// don't call the attack function again for awhile!
	self->monsterinfo.attack_finished = level.time + 0.5;
}
示例#24
0
void m_soldier_attack (edict_t *self)
{
	if (self->monsterinfo.aiflags & AI_STAND_GROUND)
	{
		self->monsterinfo.currentmove = &m_soldier_move_attack1;
		return;
	}

	if ((entdist(self, self->enemy) < 128) && (random() <= 0.8))
		self->monsterinfo.currentmove = &m_soldier_move_attack1;
	else
		self->monsterinfo.currentmove = &m_soldier_move_runandshoot;

	self->monsterinfo.attack_finished = level.time + 2;
}
示例#25
0
void mytank_restrike (edict_t *self)
{
	if (G_ValidTarget(self, self->enemy, true) && (random() <= 0.6 || !self->enemy->client)
		&& (entdist(self, self->enemy) < 128))
	{
		self->monsterinfo.currentmove = &mytank_move_strike;
	}
	else
	{
		self->monsterinfo.currentmove = &mytank_move_post_strike;
	}

	// don't call the attack function again for awhile!
	self->monsterinfo.attack_finished = level.time + 0.5 + random();
}
示例#26
0
void gladiator_cleaver_refire (edict_t *self)
{
	if (self->monsterinfo.bonus_flags & BF_UNIQUE_LIGHTNING)
		return;

	if (G_ValidTarget(self, self->enemy, true) 
		&& (entdist(self, self->enemy) <= 96) && (random() <= 0.8))
	{
		self->s.frame = 41;
		gladiator_cleaver_swing(self);
		return;
	}

	self->monsterinfo.melee_finished = level.time + GetRandom(5, 10)*FRAMETIME;
}
示例#27
0
void mychick_reslash(edict_t *self)
{
	if (self->enemy->health > 0)
	{
		if (entdist (self, self->enemy) == 32)
			if (random() <= 0.9)
			{				
				self->monsterinfo.currentmove = &mychick_move_slash;
				return;
			}
			else
			{
				self->monsterinfo.currentmove = &mychick_move_end_slash;
				return;
			}
	}
	self->monsterinfo.currentmove = &mychick_move_end_slash;
}
示例#28
0
void tank_attack (edict_t *self)
{
	float r = random();
	float range = entdist(self, self->enemy);

	//gi.dprintf("%d tank_attack()\n", level.framenum);

	// short range attack (60% strike, then 20% blaster, 80% rocket)
	if (range <= 128)
	{
		if ((!self->enemy->client || r <= 0.6) && self->groundentity)
		{
			self->monsterinfo.currentmove = &mytank_move_strike;
		}
		else
		{
			if (r <= 0.2)
				self->monsterinfo.currentmove = &mytank_move_attack_blast;
			else
				self->monsterinfo.currentmove = &mytank_move_attack_fire_rocket;
		}
	}
	// medium range attack (20% chain, 40% blaster, 40% rocket)
	else if (range <= 512)
	{
		if (r <= 0.2)
			self->monsterinfo.currentmove = &mytank_move_attack_chain;
		else if (r <= 0.6)
			self->monsterinfo.currentmove = &mytank_move_attack_blast;
		else
			self->monsterinfo.currentmove = &mytank_move_attack_fire_rocket;
	}
	// long range attack (20% blaster, 80% chain)
	else
	{
		if (r <= 0.2)
			self->monsterinfo.currentmove = &mytank_move_attack_blast;
		else
			self->monsterinfo.currentmove = &mytank_move_attack_chain;
	}

	// don't call attack function for awhile
	self->monsterinfo.attack_finished = level.time + 2.0;
}
示例#29
0
void CurseRadiusAttack (edict_t *caster, int type, int range, int radius, float duration, qboolean isCurse)
{
	edict_t *e=NULL, *f=NULL;

	// write a nice effect so everyone knows we've cast a spell
	gi.WriteByte (svc_temp_entity);
	gi.WriteByte (TE_TELEPORT_EFFECT);
	gi.WritePosition (caster->s.origin);
	gi.multicast (caster->s.origin, MULTICAST_PVS);

	caster->client->idle_frames = 0;
	caster->client->ability_delay = level.time;// for monster hearing (check if ability was recently used/cast)

	// find a target closest to the caster's reticle
	while ((e = findclosestreticle(e, caster, range)) != NULL)
	{
		if (!CanCurseTarget(caster, e, type, isCurse, true))
			continue;
		if (entdist(caster, e) > range)
			continue;
		if (!infront(caster, e))
			continue;
		if (!curse_add(e, caster, type, 0, duration))
			continue;
		CurseMessage(caster, e, type, duration, isCurse);

		// target anything in-range of this entity
		while ((f = findradius(f, e->s.origin, radius)) != NULL)
		{
			if (!CanCurseTarget(caster, f, type, isCurse, false))
				continue;
			if (f == e)
				continue;
			if (!visible(e, f))
				continue;
			if (!curse_add(f, caster, type, 0, duration))
				continue;
			CurseMessage(caster, f, type, duration, isCurse);
		}

		break;
	}
}
示例#30
0
void mybrain_attack (edict_t *self)
{
	float	dist;

	dist = entdist(self, self->enemy);

	// jump to our enemy if he's close and on even ground
	if ((dist > 256) && (self->enemy->absmin[2]+18 >= self->absmin[2]) 
		&& (self->enemy->absmin[2]-18 <= self->absmin[2]) 
		&& !(self->monsterinfo.aiflags & AI_STAND_GROUND))
		self->monsterinfo.currentmove = &mybrain_move_jumpattack;
	// use sucking attack if enemy is within 256 units and can be moved
	else if ((dist <= 256) && (self->enemy->movetype != MOVETYPE_NONE) 
		&& (self->enemy->movetype != MOVETYPE_TOSS))
		self->monsterinfo.currentmove = &mybrain_move_attack3;
	// use melee attack if we're close
	else if (dist <= MELEE_DISTANCE)
		mybrain_melee(self);
}