Exemplo n.º 1
0
Arquivo: pvb.c Projeto: zardoru/vrxcl
void AddBossExp (edict_t *attacker, edict_t *target)
{
	int		exp_points, credits;
	float	levelmod;
	edict_t *boss;

	//if (!pvb->value)
	//	return;

	attacker = G_GetClient(attacker);

	if (!IsBossTeam(attacker))
		return;

	target = G_GetClient(target);
	if (!target)
		return;

	boss = attacker->owner;

	levelmod = (((float)target->myskills.level+1) / ((float)boss->monsterinfo.level+1));
	exp_points = levelmod*PVB_BOSS_FRAG_EXP;
	credits = levelmod*PVB_BOSS_FRAG_CREDITS;

	// award points and credits
    /*
    attacker->myskills.experience += exp_points;
    attacker->client->resp.score += exp_points;
    vrx_check_for_levelup(attacker);
    */
	attacker->myskills.credits += credits;
	V_AddFinalExp(attacker, exp_points);
}
Exemplo n.º 2
0
void deflect_think (edict_t *self)
{
	edict_t *player = G_GetClient(self->enemy);
	//Find my slot
	que_t *slot = NULL;
	slot = que_findtype(self->enemy->curses, NULL, DEFLECT);

	// Blessing self-terminates if the enemy dies or the duration expires
	if (!slot || !que_valident(slot))
	{
		if (player && level.time >= self->monsterinfo.selected_time)
			gi.cprintf(player, PRINT_HIGH, "Deflect has expired\n");

		que_removeent(self->enemy->curses, self, true);
		return;
	}

	// warn player that deflect is about to expire
//	if (player && !(level.framenum % 10) && (level.time >= slot->time - 5))
//		gi.cprintf(player, PRINT_HIGH, "Deflect will expire in %.0f seconds\n", slot->time - level.time);

	//Stick with the target
	VectorCopy(self->enemy->s.origin, self->s.origin);
	gi.linkentity(self);

	DeflectProjectiles(self->enemy, self->random, false);

	//Next think
	self->nextthink = level.time + FRAMETIME;

}
Exemplo n.º 3
0
void showDebugInfo (edict_t *ent)
{
	edict_t *e;

	gi.dprintf("====================\n");
	gi.dprintf("DEBUG INFORMATION:\n");
	gi.dprintf("====================\n");
	gi.dprintf("Game Time: %.1f\n", level.time);
	gi.dprintf("Ent inuse: %s\n", ent->inuse?"true":"false");
	gi.dprintf("Ent nextthink: %.1f\n", ent->nextthink);
	gi.dprintf("Ent classname: %s\n", ent->classname);

	e = G_GetClient(ent);

	if (e)
		gi.dprintf("Ent was spawned by: %s\n", e->client->pers.netname);
}
Exemplo n.º 4
0
void AddDmgList (edict_t *self, edict_t *other, int damage)
{
	edict_t		*cl_ent;
	dmglist_t	*slot;

	if (damage < 1)
		return;

	// sanity checks
	if (!self || !self->inuse || self->deadflag == DEAD_DEAD)
		return;
	if (!other || !other->inuse || other->deadflag == DEAD_DEAD)
		return;
	
	// don't count self-inflicted damage
	if (other == self)
		return;

	// we're only adding non-spectator clients to this list
	cl_ent = G_GetClient(other);
	if (!validDmgPlayer(cl_ent))
		return;

	// prune list of disconnected clients
	dmgListCleanup(self, false);

	// already in the queue?
	if (slot=findDmgSlot(self, cl_ent))
	{
		slot->damage += damage;
	}
	// add attacker to the queue
	else if (slot=findEmptyDmgSlot(self))
	{
		slot->player = cl_ent;
		slot->damage += damage;
	}

	//gi.dprintf("adding %d damage\n", damage);
	//printDmgList(self);
}
Exemplo n.º 5
0
void dom_fragaward (edict_t *attacker, edict_t *target)
{
	int		points = DOMINATION_FRAG_POINTS;
	float	dist;
	edict_t *carrier, *targ;

	targ = target; // this could possibly be a non-client entity
	attacker = G_GetClient(attacker);
	target = G_GetClient(target);

	if (!DEFENSE_TEAM)
		return;
	if (FLAG_FRAMES < 100)
		return; // flag must be captured for at least 10 seconds
	//if (!G_EntExists(attacker) || !G_EntExists(target))
	//	return;
	// basic sanity checks
	if (!attacker || !attacker->inuse || G_IsSpectator(attacker) 
		|| !target || !target->inuse || G_IsSpectator(target))
		return;
	if (attacker == target)
		return;
	if (attacker->health < 1)
		return;
	
	if (((carrier = dom_flagcarrier()) != NULL) && (carrier != attacker))
	{
		dist = entdist(carrier, targ);
		if (OnSameTeam(attacker, carrier))
		{
			// if we are on the same team as the flag carrier and the
			// enemy was close to the carrier, then award a bonus for
			// protecting the flag
			if (dist <= DOMINATION_DEFEND_RANGE)
			{
				gi.bprintf(PRINT_HIGH, "%s defends the flag carrier!\n", 
					attacker->client->pers.netname);
				points = DOMINATION_DEFEND_BONUS;
				gi.sound(carrier, CHAN_ITEM, gi.soundindex("speech/excelent.wav"), 1, ATTN_NORM, 0);
			}
		}
		else if (carrier == targ)
		{
			// award a bonus for killing the flag carrier
			gi.bprintf(PRINT_HIGH, "%s kills the flag carrier!\n",
				attacker->client->pers.netname);
			points = DOMINATION_CARRIER_BONUS;
			gi.sound(attacker, CHAN_ITEM, gi.soundindex("ctf/flagcap.wav"), 1, ATTN_NORM, 0);
		}
		else if (dist <= DOMINATION_DEFEND_RANGE)
		{
			// award a bonus for killing flag defense
			gi.bprintf(PRINT_HIGH, "%s kills a defender!\n", 
				attacker->client->pers.netname);
			points = DOMINATION_OFFENSE_BONUS;
			gi.sound(attacker, CHAN_ITEM, gi.soundindex("speech/idoasskk.wav"), 1, ATTN_NORM, 0);
		}
	}
	else if (attacker->teamnum == DEFENSE_TEAM)
		return; // no further bonuses available for defense team

	/*
	attacker->myskills.experience += points;
	attacker->client->resp.score += points;
	check_for_levelup(attacker);
	*/
	V_AddFinalExp(attacker, points);
}
Exemplo n.º 6
0
//FIXME since we need to test end position contents here, can we avoid doing
//it again later in catagorize position?
qboolean SV_movestep (edict_t *ent, vec3_t move, qboolean relink)
{
	float		dz;
	vec3_t		oldorg, neworg, end;
	trace_t		trace;//, tr;
	int			i;
	float		stepsize;
	vec3_t		test;
	int			contents;
	int			jump=0;

// try the move	
	VectorCopy (ent->s.origin, oldorg);
	VectorAdd (ent->s.origin, move, neworg);

// flying monsters don't step up
	if ((ent->flags & (FL_SWIM|FL_FLY)) || (ent->waterlevel > 1))
	{
	//	gi.dprintf("trying to swim\n");
	// try one move with vertical motion, then one without
		for (i=0 ; i<2 ; i++)
		{
			VectorAdd (ent->s.origin, move, neworg);
			if (i == 0 && ent->enemy)
			{
				if (!ent->goalentity)
					ent->goalentity = ent->enemy;
				dz = ent->s.origin[2] - ent->goalentity->s.origin[2];
				if (ent->goalentity->client)
				{
					if (dz > 40)
						neworg[2] -= 8;
					if (!((ent->flags & FL_SWIM) && (ent->waterlevel < 2)))
						if (dz < 30)
							neworg[2] += 8;
				}
				else
				{
					if (dz > 8)
						neworg[2] -= 8;
					else if (dz > 0)
						neworg[2] -= dz;
					else if (dz < -8)
						neworg[2] += 8;
					else
						neworg[2] += dz;
				}
			}
			trace = gi.trace (ent->s.origin, ent->mins, ent->maxs, neworg, ent, MASK_MONSTERSOLID);
	
			// fly monsters don't enter water voluntarily
			if (ent->flags & FL_FLY)
			{
				if (!ent->waterlevel)
				{
					test[0] = trace.endpos[0];
					test[1] = trace.endpos[1];
					test[2] = trace.endpos[2] + ent->mins[2] + 1;
					contents = gi.pointcontents(test);
					if (contents & MASK_WATER)
						return false;
				}
			}

			// swim monsters don't exit water voluntarily
			if (ent->flags & FL_SWIM)
			{
				if (ent->waterlevel < 2)
				{
					test[0] = trace.endpos[0];
					test[1] = trace.endpos[1];
					test[2] = trace.endpos[2] + ent->mins[2] + 1;
					contents = gi.pointcontents(test);
					if (!(contents & MASK_WATER))
						return false;
				}
			}

			if (trace.fraction == 1)
			{
				VectorCopy (trace.endpos, ent->s.origin);
				if (relink)
				{
					gi.linkentity (ent);
					G_TouchTriggers (ent);
				}
				return true;
			}
			//gi.dprintf("swim move failed\n");
			
			if (!ent->enemy)
				break;
		}
		
		return false;
	}

// push down from a step height above the wished position
	if (!(ent->monsterinfo.aiflags & AI_NOSTEP))
		stepsize = STEPSIZE;
	else
		stepsize = 1;

	neworg[2] += stepsize;
	VectorCopy (neworg, end);
	end[2] -= stepsize*2;
 
	// this trace checks from a position one step above the entity (at top of bbox)
	// to one step below the entity (bottom of bbox)
	trace = gi.trace (neworg, ent->mins, ent->maxs, end, ent, MASK_MONSTERSOLID);

	// there is an obstruction bigger than a step
	if (trace.allsolid)
//GHz START
	{
		// az: Regular monsters: don't jump on invasion mode...
		if (!G_GetClient(ent) && invasion->value) 
			return false;

		// try to jump over it
		if (G_EntIsAlive(trace.ent) || !CanJumpUp(ent, neworg, end))
			return false;
		else
		{
			jump = 1;
		}
	}
//GHz END

	// not enough room at this height--head of bbox intersects something solid
	// so push down and just try to walk forward at floor height
	else if (trace.startsolid)
	{
		neworg[2] -= stepsize;
		trace = gi.trace (neworg, ent->mins, ent->maxs, end, ent, MASK_MONSTERSOLID);
		if (trace.allsolid || trace.startsolid)
			return false;
	}

	// don't go in to water
	if (ent->waterlevel == 0)
	{
		test[0] = trace.endpos[0];
		test[1] = trace.endpos[1];
		test[2] = trace.endpos[2] + ent->mins[2] + 1;	
		contents = gi.pointcontents(test);

		if (contents & (CONTENTS_LAVA|CONTENTS_SLIME))
			return false;
	}

//GHz 5/8/2010 - don't get stuck on steep little ramps
	if (trace.fraction < 1 && trace.plane.normal[2] < 0.7) // too steep
		return false;

//GHz START
//	if (CanJumpDown(ent, trace.endpos))
//		jump = -1;
//GHz END

//	VectorSubtract(trace.endpos, oldorg, forward);
//	VectorNormalize(forward);
//	VectorMA(oldorg, 32, forward, end);

//	VectorAdd(trace.endpos, move, end);
//	VectorAdd(end, move, end);

	if ((trace.fraction == 1) && (jump != 1))
	{
		//gi.dprintf("going to fall\n");
	// if monster had the ground pulled out, go ahead and fall
	//	VectorSubtract(trace.endpos, oldorg, forward);
	//	VectorMA(oldorg, 64, forward, end);
		if (!CanJumpDown(ent, trace.endpos))
		{
			if ( ent->flags & FL_PARTIALGROUND )
			{
				VectorAdd (ent->s.origin, move, ent->s.origin);
				if (relink)
				{
					gi.linkentity (ent);
					G_TouchTriggers (ent);
				}
				ent->groundentity = NULL;
				return true;
			}
			return false;		// walked off an edge
		}
		else
			jump = -1;
	}

// check point traces down for dangling corners
	//GHz START
	/*
	// fix for monsters walking thru walls
	tr = gi.trace(trace.endpos, ent->mins, ent->maxs, trace.endpos, ent, MASK_SOLID);
	if (tr.contents & MASK_SOLID)
		return false;
	*/
	//GHz END
	
	if (jump != 1)
		VectorCopy (trace.endpos, ent->s.origin);
	
	if (!M_CheckBottom (ent))
	{
		//gi.dprintf("partial ground\n");
		if (ent->flags & FL_PARTIALGROUND)
		{	// entity had floor mostly pulled out from underneath it
			// and is trying to correct
			if (relink)
			{
				gi.linkentity (ent);
				G_TouchTriggers (ent);
			}
			return true;
		}
		if (CanJumpDown(ent, trace.endpos))
			jump = -1;
		if (!jump)
		{
			VectorCopy (oldorg, ent->s.origin);
			return false;
		}
	}
	else if (jump == -1)
		jump = 0;
/*
	if (jump)
	{
		VectorCopy(oldorg, ent->s.origin);
		CanJumpDown(ent, trace.endpos, true);
		VectorCopy(trace.endpos, ent->s.origin);
	}
*/
	
	if ( ent->flags & FL_PARTIALGROUND )
	{
		ent->flags &= ~FL_PARTIALGROUND;
	}

	ent->groundentity = trace.ent;
	if (trace.ent)
		ent->groundentity_linkcount = trace.ent->linkcount;

	if (jump == -1)
	{
		/*
		gi.WriteByte (svc_temp_entity);
		gi.WriteByte (TE_DEBUGTRAIL);
		gi.WritePosition (oldorg);
		gi.WritePosition (end);
		gi.multicast (end, MULTICAST_ALL);
		*/

		//VectorScale(move, 10, ent->velocity);
		//ent->velocity[2] = 200;
	}
	else if (jump == 1)
	{
		ent->velocity[2] = 200;
		//gi.dprintf("jumped at %d\n",level.framenum);
	}

// the move is ok
	if (relink)
	{
		gi.linkentity (ent);
		G_TouchTriggers (ent);
	}
	//gi.dprintf("moved successfully at %d\n", level.framenum);
	return true;
}
Exemplo n.º 7
0
qboolean IsBossTeam (edict_t *ent)
{
	edict_t *e = G_GetClient(ent);

	return (e && IsABoss(e->owner));
}
Exemplo n.º 8
0
void laser_beam_think (edict_t *self)
{
	int		size;
	int		damage;
	vec3_t	forward;
	trace_t tr;

	// can't have a laser beam without an emitter!
	if (!self->creator)
	{
		G_FreeEdict(self);
		return;
	}

	// set beam color
	if (self->health < 1)// emitter burned out
		size = 0;
	else if (self->monsterinfo.level >= 10)// high-level beam is wider
		size = 4;
	else
		size = 2;
	self->s.frame = size;// set
	
	// set beam color
	laser_beam_effects(self);

	// trace from beam emitter out as far as we can go
	AngleVectors(self->s.angles, forward, NULL, NULL);
	VectorMA(self->pos1, 8192, forward, self->pos2);
	tr = gi.trace (self->pos1, NULL, NULL, self->pos2, self->creator, MASK_SHOT);
	VectorCopy(tr.endpos, self->s.origin);
	VectorCopy(self->pos1, self->s.old_origin);

	// set maximum damage output
	if (size)
	{
		damage = self->dmg;
		// don't deal more damage than we have health
		if (damage > self->health)
			damage = self->health;
	}
	else
		damage = 0;// no damage, emitter burned out

	// what is in lasers path?
	if (damage && G_EntExists(tr.ent) && tr.ent != self->activator)
	{
		// remove lasers near spawn positions
		if (tr.ent->client && (tr.ent->client->respawn_time-1.5 > level.time))
		{
			safe_cprintf(self->activator, PRINT_HIGH, "Laser touched respawning player, so it was removed. (%d/%d remain)\n", self->activator->num_lasers, MAX_LASERS);
			laser_remove(self->creator);
			return;
		}

		if (G_GetClient(tr.ent) && invasion->value > 1) // don't deal damage to friends in invasion hard.
			damage = 0;

		// deal damage to anything in the beam's path
		if (!T_Damage(tr.ent, self, self->activator, forward, tr.endpos, 
			vec3_origin, damage, 0, DAMAGE_ENERGY, MOD_LASER_DEFENSE))
			damage = 0; // emitter hasn't burned out yet, but couldn't damage anything, so we're idle
	}
	else
		damage = 0; // emitter is either burned out or hit nothing valid

	// emitter burns out slowly even when idle
	if (size && !damage && !(level.framenum % 10))
	{
		damage = 0.008333 * self->max_health;
		if (damage < 1)
			damage = 1;
	}

	// reduce maximum damage counter
	self->health -= damage;

	// if the counter reaches 0, then shut-down
	if (damage && self->health < 1)
	{
		self->health = 0;
		safe_cprintf(self->activator, PRINT_HIGH, "Laser emitter burned out.\n");
	}

	//gi.dprintf("%d/%d\n", self->health, self->max_health);

	self->nextthink = level.time + FRAMETIME;
}
Exemplo n.º 9
0
void SpawnRune (edict_t *self, edict_t *attacker, qboolean debug)
{
	int		iRandom;
	int		targ_level = 0;
	float	temp = 0;
	gitem_t *item;
	edict_t *rune;

	attacker = G_GetClient(attacker);

	if (!attacker)
		return;

	if(!self->client)
	{
		// is this a world monster?
		if (self->mtype && (self->svflags & SVF_MONSTER) && self->activator && !self->activator->client)
		{
			if (IsABoss(self) || (self->mtype == M_COMMANDER))
			//boss has a 100% chance to spawn a rune
				temp = (float) (self->monsterinfo.level + 1) / (attacker->myskills.level + 1) * 100.0;
			else if (self->monsterinfo.bonus_flags & BF_UNIQUE_LIGHTNING 
				|| self->monsterinfo.bonus_flags & BF_UNIQUE_FIRE)
			// unique monsters have a 50% chance to spawn a rune
				temp = (float) (self->monsterinfo.level + 1) / (attacker->myskills.level + 1) * 75.0;
			else if (self->monsterinfo.bonus_flags & BF_CHAMPION)
			// champion monsters have a 15% chance to spawn a rune
				temp = (float) (self->monsterinfo.level + 1) / (attacker->myskills.level + 1) * 15.0; // from 2%
			else
			// monsters have a 5% chance to spawn a rune NOP MONSTERS DON'T DROP RUNES
				//temp = (float) (self->monsterinfo.level + 1) / (attacker->myskills.level + 1) * 5.0; // from 0.2%
				temp = 1; // 1% to drop runes.
			//gi.dprintf("%.3f\n", temp*RUNE_SPAWN_BASE);

			if (RUNE_SPAWN_BASE * temp < random())
				return;

			//set target level
			targ_level = (self->monsterinfo.level + attacker->myskills.level) / 2;
			// don't allow runes higher than attacker's level
			if (targ_level > attacker->myskills.level)
				targ_level = attacker->myskills.level;
		}
		else
			return;
	}
	else if (attacker != self)
	{
		//boss has a greater chance of dropping a rune
		if (attacker->myskills.boss > 0)
            temp = (float)attacker->myskills.boss * 5;
		else
			temp = (float) (self->myskills.level + 1) * 5.0 / (attacker->myskills.level + 1);
		
		// miniboss has greater chance of dropping a rune
		if (IsNewbieBasher(self))
			temp *= 2;
		
		//boss has a greater chance of dropping a rune
		temp *= 1.0 + ((float)self->myskills.boss / 2.0);
		
		if (RUNE_SPAWN_BASE * temp < random())
			return;
		
		//set target level
		targ_level = (self->myskills.level + attacker->myskills.level) / 2;
	}
	else if (debug == false)
		return;

	item = FindItem("Rune");		// get the item properties
	rune = Drop_Item(self, item);	// create the entity that holds those properties
	V_ItemClear(&rune->vrxitem);	// initialize the rune

	//set target level to 20 if we are debugging
	if (debug == true)
		targ_level = 20;
	
	rune->vrxitem.quantity = 1;

	//Spawn a random rune
    iRandom = GetRandom(0, 1000);

	if (iRandom < CHANCE_UNIQUE)
	{
		//spawn a unique
#ifdef ENABLE_UNIQUES
		if (!spawnUnique(rune, 0))
#endif
			spawnNorm(rune, targ_level, 0);
	}
	else if (iRandom < CHANCE_UNIQUE + CHANCE_CLASS)
	{
		//spawn a class-specific rune
		spawnClassRune(rune, targ_level);
	}
	else if (iRandom < CHANCE_UNIQUE + CHANCE_CLASS + CHANCE_COMBO)
	{
		//spawn a combo rune
		spawnCombo(rune, targ_level);
	}
	else if (iRandom < CHANCE_UNIQUE + CHANCE_CLASS + CHANCE_COMBO + CHANCE_NORM)
	{
		//spawn a normal rune
		spawnNorm(rune, targ_level, 0);
	}
	else
	{
		G_FreeEdict(rune);
		return;
	}

	//Randomize id
	strcpy(rune->vrxitem.id, GetRandomString(16));
}
Exemplo n.º 10
0
edict_t *V_SpawnRune (edict_t *self, edict_t *attacker, float base_drop_chance, float levelmod)
{
	int		iRandom;
	int		targ_level;
	float	temp = 0;
	gitem_t *item;
	edict_t *rune;

	attacker = G_GetClient(attacker);

	if (!attacker || !attacker->client)
		return NULL;

	if(!self->client && self->activator && self->svflags & SVF_MONSTER)
	{
		temp = (float) (self->monsterinfo.level + 1) / (attacker->myskills.level + 1);
		
		if (base_drop_chance * temp < random())
			return NULL;

		//set target level
		targ_level = (self->monsterinfo.level + attacker->myskills.level) / 2;

		// don't allow runes higher than attacker's level
		if (targ_level > attacker->myskills.level)
			targ_level = attacker->myskills.level;
	}
	else if (attacker != self && attacker != world)
	{
		//boss has a greater chance of dropping a rune
		if (attacker->myskills.boss > 0)
            temp = (float)attacker->myskills.boss / 5.0;
		else
			temp = (float) (self->myskills.level + 1) / (attacker->myskills.level + 1);
		
		// miniboss has greater chance of dropping a rune
		if (IsNewbieBasher(self))
			temp *= 2;
		
		//boss has a greater chance of dropping a rune
		temp *= 1.0 + ((float)self->myskills.boss / 2.0);
		
		if (base_drop_chance * temp < random())
			return NULL;
		
		//set target level
		targ_level = (self->myskills.level + attacker->myskills.level) / 2;
	}
	else
		return NULL;

	item = FindItem("Rune");		// get the item properties
	rune = Drop_Item(self, item);	// create the entity that holds those properties
	V_ItemClear(&rune->vrxitem);	// initialize the rune

	if (levelmod)
		targ_level *= levelmod;
	
	rune->vrxitem.quantity = 1;

	//Spawn a random rune
    iRandom = GetRandom(0, 1000);

	if (iRandom < CHANCE_UNIQUE)
	{
		//spawn a unique 
		// vrx chile 1.4 no uniques until someone makes them
		if (!spawnUnique(rune, 0))
			spawnNorm(rune, targ_level, 0);
	}
	else if (iRandom < CHANCE_UNIQUE + CHANCE_CLASS)
	{
		//spawn a class-specific rune
		spawnClassRune(rune, targ_level);
	}
	else if (iRandom < CHANCE_UNIQUE + CHANCE_CLASS + CHANCE_COMBO)
	{
		//spawn a combo rune
		spawnCombo(rune, targ_level);
	}
	else if (iRandom < CHANCE_UNIQUE + CHANCE_CLASS + CHANCE_COMBO + CHANCE_NORM)
	{
		//spawn a normal rune
		spawnNorm(rune, targ_level, 0);
	}
	else
	{
		G_FreeEdict(rune);
		return NULL;
	}

	//Randomize id
	strcpy(rune->vrxitem.id, GetRandomString(16));

	return rune;
}