Пример #1
0
void salvation_think (edict_t *self)
{
	int		radius;
	edict_t *other=NULL;
	que_t	*slot=NULL;

	// check status of owner
	if (!CheckAuraOwner(self, COST_FOR_SALVATION))
	{
		que_removeent(self->owner->auras, self, true);
		return;
	}

	// use cubes
	if (!(level.framenum % DEFAULT_AURA_FRAMES))
	{
		int cube_cost = DEFAULT_AURA_COST;

		self->owner->client->pers.inventory[power_cube_index] -= cube_cost;
	}
	que_addent(self->owner->auras, self, DEFAULT_AURA_DURATION);
	// move aura with owner
	VectorCopy(self->owner->s.origin,self->s.origin);
	self->nextthink = level.time + FRAMETIME;
	if (level.framenum % DEFAULT_AURA_SCAN_FRAMES)
		return;

	radius = 256;

	// scan for targets
	while ((other = findradius (other, self->s.origin, radius)) != NULL)
	{
		slot = NULL;
		if (other == self->owner)
			continue;
		if (!G_EntExists(other))
			continue;
		if (other->health < 1)
			continue;
		if (OnSameTeam(self->owner, other) < 2)
			continue;
		if (!visible(self->owner, other))
			continue;
		slot = que_findtype(other->auras, slot, AURA_SALVATION);
		if (slot && (slot->ent->owner != self->owner))
			continue;
		que_addent(other->auras, self, DEFAULT_AURA_DURATION);
	}
}
Пример #2
0
void BombPerson (edict_t *target, edict_t *owner, float skill_mult) 
{
	edict_t *bomb;

    gi.sound(target, CHAN_ITEM, gi.soundindex("abilities/meteorlaunch.wav"), 1, ATTN_NORM, 0);
	if ((target->client) && !(target->svflags & SVF_MONSTER))
		safe_cprintf(target, PRINT_HIGH, "SOMEONE SET UP US THE BOMB !!\n");
	//target->cursed |= CURSE_BOMBS;

	bomb=G_Spawn();
	bomb->solid = SOLID_NOT;
	bomb->svflags |= SVF_NOCLIENT;
	VectorClear(bomb->velocity);
	VectorClear(bomb->mins);
	VectorClear(bomb->maxs);
	bomb->owner = owner;
	bomb->enemy = target;
	bomb->delay = level.time + BOMBPERSON_DURATION;
	bomb->dmg = 50 + 10*owner->myskills.abilities[BOMB_SPELL].current_level*skill_mult;
	bomb->mtype = CURSE_BOMBS;
	bomb->nextthink = level.time + 1.0;
	bomb->think = bombperson_think;
	VectorCopy(target->s.origin, bomb->s.origin);
	gi.linkentity(bomb);
	if (!que_addent(target->curses, bomb, BOMBPERSON_DURATION))
		G_FreeEdict(bomb);
}
Пример #3
0
void burn_person (edict_t *target, edict_t *owner, int damage)
{
	edict_t	*flame;
	que_t *slot=NULL;

	if (level.time < pregame_time->value)
		return;
	if (que_typeexists(target->curses, CURSE_FROZEN))
		return; // attacker is frozen!
	if (!G_ValidTarget(owner, target, false))
		return;
	while ((slot = que_findtype(target->curses, slot, CURSE_BURN)) != NULL)
	{
		if (slot->time-level.time >= 9)
			return; // only allow 1 burn per second
	}

	flame = G_Spawn();
	flame->movetype = MOVETYPE_NOCLIP;
	flame->solid = SOLID_NOT;
	VectorClear(flame->mins);
	VectorClear(flame->maxs);
	flame->owner = owner;
	flame->enemy = target;
	flame->mtype = CURSE_BURN;
	flame->delay = level.time + 10;
	flame->nextthink = level.time + FRAMETIME;
	flame->PlasmaDelay = level.time + FRAMETIME;
	flame->think = fire_think;
	flame->classname = "fire";
	flame->s.sound = gi.soundindex ("weapons/bfg__l1a.wav");
	flame->dmg = damage;
	VectorCopy(target->s.origin, flame->s.origin);
	gi.linkentity (flame);

	if (!que_addent(target->curses, flame, 10))
	{
		G_FreeEdict(flame);
		return;
	}

	gi.sound (target, CHAN_ITEM, gi.soundindex ("misc/needlite.wav"), 1, ATTN_NORM, 0);
}
Пример #4
0
void aura_salvation(edict_t *ent) 
{
	edict_t *salvation;

	salvation = G_Spawn();
	salvation->movetype = MOVETYPE_NOCLIP;
	salvation->svflags |= SVF_NOCLIENT;
	salvation->solid = SOLID_NOT;
	VectorClear (salvation->mins);
	VectorClear (salvation->maxs);
	salvation->owner = ent;
	salvation->nextthink = level.time + FRAMETIME;
	salvation->think = salvation_think;
	salvation->classname = "Aura";
	salvation->mtype = AURA_SALVATION;
	VectorCopy(ent->s.origin, salvation->s.origin);

	if (!que_addent(ent->auras, salvation, DEFAULT_AURA_DURATION))
		G_FreeEdict(salvation); // too many auras
}
Пример #5
0
void PlagueCloud (edict_t *ent, edict_t *target)
{
	edict_t *plague;

	plague = G_Spawn();
	plague->movetype = MOVETYPE_NOCLIP;
	plague->svflags |= SVF_NOCLIENT;
	plague->solid = SOLID_NOT;
	plague->enemy = target;
	plague->owner = ent;
//	plague->dmg = damage;
	plague->nextthink = level.time + FRAMETIME;
	plague->think = plague_think;
	plague->classname = "curse";
	plague->mtype = CURSE_PLAGUE;
	VectorCopy(ent->s.origin, plague->s.origin);

	// abort if the target has too many curses
//	if (!AddCurse(ent, target, plague, CURSE_PLAGUE, PLAGUE_DURATION))
	if (!que_addent(target->curses, plague, PLAGUE_DURATION))
		G_FreeEdict(plague);
}
Пример #6
0
void aura_holyfreeze(edict_t *ent) 
{
	edict_t *holyfreeze;

	holyfreeze = G_Spawn();
	holyfreeze->movetype = MOVETYPE_NOCLIP;
	holyfreeze->svflags |= SVF_NOCLIENT;
	holyfreeze->solid = SOLID_NOT;
	VectorClear (holyfreeze->mins);
	VectorClear (holyfreeze->maxs);
	holyfreeze->owner = ent;
	holyfreeze->nextthink = level.time + FRAMETIME;
	holyfreeze->think = holyfreeze_think;
	holyfreeze->classname = "Aura";
	holyfreeze->mtype = AURA_HOLYFREEZE;
	VectorCopy(ent->s.origin, holyfreeze->s.origin);

	if (!que_addent(ent->auras, holyfreeze, DEFAULT_AURA_DURATION))
		G_FreeEdict(holyfreeze); // too many auras

	//que_list(ent->auras);
}
Пример #7
0
void holyfreeze_think (edict_t *self)
{
	int		radius;
	edict_t *target=NULL, *curse=NULL;
	que_t	*slot;

	// check status of owner
	if (!CheckAuraOwner(self, DEFAULT_AURA_COST))
	{
	//gi.dprintf("aura removed itself\n");

		que_removeent(self->owner->auras, self, true);
		return;
	}
	
	// owner has an active aura
	que_addent(self->owner->auras, self, DEFAULT_AURA_DURATION);

	// use cubes
	if (!(level.framenum % DEFAULT_AURA_FRAMES))
	{
		int cube_cost = DEFAULT_AURA_COST;

		self->owner->client->pers.inventory[power_cube_index] -= cube_cost;
	}

	// move aura with owner
	VectorCopy(self->owner->s.origin,self->s.origin);
	self->nextthink = level.time + FRAMETIME;
	if (level.framenum % DEFAULT_AURA_SCAN_FRAMES)
		return;

	// scan for targets
	radius = DEFAULT_AURA_MIN_RADIUS+self->owner->myskills.abilities[HOLY_FREEZE].current_level*DEFAULT_AURA_ADDON_RADIUS;
	if (radius > DEFAULT_AURA_MAX_RADIUS)
		radius = DEFAULT_AURA_MAX_RADIUS;

	while ((target = findradius (target, self->s.origin, radius)) != NULL)
	{
		slot = NULL;
		if (target == self->owner)
			continue;
		if (!G_ValidTarget(self->owner, target, true))
			continue;
		// FIXME: make this into a loop search if we plan to allow
		// more than one curse of the same type
		slot = que_findtype(target->curses, slot, AURA_HOLYFREEZE);
		if (slot && (slot->ent->owner != self->owner))
		{
		//	gi.dprintf("already slowed by someone else\n");
			continue; // already slowed by someone else
		}
		if (!slot) // aura doesn't exist in que or timed out
		{
			if (random() > 0.5)
				gi.sound(target, CHAN_ITEM, gi.soundindex("spells/blue1.wav"), 1, ATTN_NORM, 0);
			else
				gi.sound(target, CHAN_ITEM, gi.soundindex("spells/blue3.wav"), 1, ATTN_NORM, 0);
		}
		que_addent(target->curses, self, DEFAULT_AURA_DURATION);
	}
}
Пример #8
0
qboolean curse_add(edict_t *target, edict_t *caster, int type, int curse_level, float duration)
{
	edict_t *curse;
	que_t	*slot = NULL;
	
	//Find out if this curse already exists
	slot = que_findtype(target->curses, NULL, type);
	if(slot != NULL)
	{
		//If the current curse in effect has a level greater than the caster's curse level
		//if (slot->ent->owner->myskills.abilities[type].current_level > caster->myskills.abilities[type].current_level)
		if (slot->ent->monsterinfo.level > curse_level)//4.4
			//Can't re-curse this player
			return false;
		else
		{
            //Refresh the curse with the new level/ent/duration
			return que_addent(target->curses, slot->ent, duration);
		}
	}

	/*
	//Talent: Evil curse (improves curse duration)
	talentLevel = getTalentLevel(caster, TALENT_EVIL_CURSE);
	if(talentLevel > 0)
	{
		//Curses only
		if(type != BLESS && type != HEALING)
			duration *= 1.0 + 0.25 * talentLevel;
	}
	*/

	//Create the curse entity
	curse=G_Spawn();
	curse->classname = "curse";
	curse->solid = SOLID_NOT;
	curse->svflags |= SVF_NOCLIENT;
	curse->monsterinfo.level = curse_level;//4.2
	curse->monsterinfo.selected_time = duration;//4.2
	VectorClear(curse->velocity);
	VectorClear(curse->mins);
	VectorClear(curse->maxs);

	//Set curse type, target, and caster
	curse->owner = caster;
	curse->enemy = target;
	curse->atype = type;

	//First think in 1/2 a second
	curse->nextthink = level.time + FRAMETIME;
	curse->think = curse_think;

	//Set origin to target's origin
	VectorCopy(target->s.origin, curse->s.origin);
	gi.linkentity(curse);

	//Try to add the curse to the que
	if (!que_addent(target->curses, curse, duration))
	{
		G_FreeEdict(curse);
		return false;
	}
	return true;
}