Ejemplo n.º 1
0
void Cmd_Amnesia(edict_t *ent)
{
	int radius, talentLevel, cost=AMNESIA_COST;
	float duration;
	edict_t *target = NULL;

	if (debuginfo->value)
		gi.dprintf("DEBUG: %s just called Cmd_Amnesia()\n", ent->client->pers.netname);

	if(ent->myskills.abilities[AMNESIA].disable)
		return;

	//Talent: Cheaper Curses
	if ((talentLevel = getTalentLevel(ent, TALENT_CHEAPER_CURSES)) > 0)
		cost *= 1.0 - 0.1 * talentLevel;

	if (!G_CanUseAbilities(ent, ent->myskills.abilities[AMNESIA].current_level, cost))
		return;

	radius = SHAMAN_CURSE_RADIUS_BASE + (SHAMAN_CURSE_RADIUS_BONUS * ent->myskills.abilities[AMNESIA].current_level);
	duration = AMNESIA_DURATION_BASE + (AMNESIA_DURATION_BONUS * ent->myskills.abilities[AMNESIA].current_level);

	//Talent: Evil curse
	talentLevel = getTalentLevel(ent, TALENT_EVIL_CURSE);
	if(talentLevel > 0)
		duration *= 1.0 + 0.25 * talentLevel;

	target = curse_Attack(ent, AMNESIA, radius, duration, true);
	if (target != NULL)
	{
		//Finish casting the spell
		ent->client->ability_delay = level.time + AMNESIA_DELAY;
		ent->client->pers.inventory[power_cube_index] -= cost;

		//disable some abilities if the player was using them
		V_DisableAllSkills(ent);

		//Notify the target
		if ((target->client) && !(target->svflags & SVF_MONSTER))
		{
			gi.cprintf(target, PRINT_HIGH, "YOU HAVE BEEN CURSED WITH AMNESIA!! (%0.1f seconds)\n", duration);
			gi.cprintf(ent, PRINT_HIGH, "Cursed %s with amnesia for %0.1f seconds.\n", target->myskills.player_name, duration);
		}
		else
		{
			gi.cprintf(ent, PRINT_HIGH, "Cursed %s with amnesia for %0.1f seconds.\n", target->classname, duration);
		}
		//Play the spell sound!
		gi.sound(target, CHAN_ITEM, gi.soundindex("curses/amnesia.wav"), 1, ATTN_NORM, 0);
	}
}
Ejemplo n.º 2
0
void Cmd_BuildLaser (edict_t *ent)
{
	int talentLevel, cost=LASER_COST;
	float skill_mult=1.0, cost_mult=1.0, delay_mult=1.0;//Talent: Rapid Assembly & Precision Tuning

	if(ent->myskills.abilities[BUILD_LASER].disable)
		return;

	if (Q_strcasecmp (gi.args(), "remove") == 0)
	{
		RemoveLasers(ent);
		gi.cprintf(ent, PRINT_HIGH, "All lasers removed.\n");
		return;
	}

	// cost is doubled if you are a flyer or cacodemon below skill level 5
	if ((ent->mtype == MORPH_FLYER && ent->myskills.abilities[FLYER].current_level < 5) 
		|| (ent->mtype == MORPH_CACODEMON && ent->myskills.abilities[CACODEMON].current_level < 5))
		cost *= 2;

	//Talent: Rapid Assembly
	talentLevel = getTalentLevel(ent, TALENT_RAPID_ASSEMBLY);
	if (talentLevel > 0)
		delay_mult -= 0.1 * talentLevel;
	//Talent: Precision Tuning
	else if ((talentLevel = getTalentLevel(ent, TALENT_PRECISION_TUNING)) > 0)
	{
		cost_mult += PRECISION_TUNING_COST_FACTOR * talentLevel;
		delay_mult += PRECISION_TUNING_DELAY_FACTOR * talentLevel;
		skill_mult += PRECISION_TUNING_SKILL_FACTOR * talentLevel;
	}
	cost *= cost_mult;

	if (!G_CanUseAbilities(ent, ent->myskills.abilities[BUILD_LASER].current_level, cost))
		return;

	if (ent->num_lasers >= MAX_LASERS)
	{
		gi.cprintf(ent, PRINT_HIGH, "Can't build any more lasers.\n");
		return;
	}

	if (ctf->value && (CTF_DistanceFromBase(ent, NULL, CTF_GetEnemyTeam(ent->teamnum)) < CTF_BASE_DEFEND_RANGE))
	{
		gi.cprintf(ent, PRINT_HIGH, "Can't build in enemy base!\n");
		return;
	}

	SpawnLaser(ent, cost, skill_mult, delay_mult);
}
Ejemplo n.º 3
0
void Cmd_SpawnMagmine_f (edict_t *ent)
{
	int talentLevel,cost=MAGMINE_COST;
	float skill_mult=1.0, cost_mult=1.0, delay_mult=1.0;//Talent: Rapid Assembly & Precision Tuning
	char *opt = gi.argv(1);

	if (ent->myskills.abilities[MAGMINE].disable)
		return;

	//Talent: Rapid Assembly
	talentLevel = getTalentLevel(ent, TALENT_RAPID_ASSEMBLY);
	if (talentLevel > 0)
		delay_mult -= 0.1 * talentLevel;
	//Talent: Precision Tuning
	else if ((talentLevel = getTalentLevel(ent, TALENT_PRECISION_TUNING)) > 0)
	{
		cost_mult += PRECISION_TUNING_COST_FACTOR * talentLevel;
		delay_mult += PRECISION_TUNING_DELAY_FACTOR * talentLevel;
		skill_mult += PRECISION_TUNING_SKILL_FACTOR * talentLevel;
	}
	cost *= cost_mult;

	if (!G_CanUseAbilities(ent, ent->myskills.abilities[MAGMINE].current_level, cost))
		return;

	if (!strcmp(opt, "self"))
	{
		if (getTalentLevel(ent, TALENT_MAGMINESELF))
		{
			ent->automag = !ent->automag;
			safe_cprintf(ent, PRINT_HIGH, "Auto Magmine %s\n", ent->automag? "enabled" : "disabled");
		}else
			safe_cprintf(ent, PRINT_HIGH, "You haven't upgraded this talent.\n");

		return;
	}

	if (ent->magmine && ent->magmine->inuse)
	{
		safe_cprintf(ent, PRINT_HIGH, "Removed mag mine.\n");
		BecomeExplosion1(ent->magmine);
		ent->magmine = NULL;
		return;
	}

	magmine_spawn(ent, cost, skill_mult, delay_mult);
}
Ejemplo n.º 4
0
void Cmd_Salvation(edict_t *ent)
{
	que_t		*slot=NULL;
	qboolean	sameaura=false;

	if (debuginfo->value)
		gi.dprintf("DEBUG: %s just called Cmd_Salvation()\n", ent->client->pers.netname);

	if(ent->myskills.abilities[SALVATION].disable)
		return;
	if (!G_CanUseAbilities(ent, ent->myskills.abilities[SALVATION].current_level, 0))
		return;

	// if we already had an aura on, remove it
	if ((slot = que_findtype(ent->auras, slot, AURA_SALVATION)) != NULL)
	{
		// owner is turning off his own aura
		if (slot->ent && slot->ent->owner 
			&& slot->ent->owner->inuse && slot->ent->owner == ent)
		{
			AuraRemove(ent, AURA_SALVATION);
			safe_cprintf(ent, PRINT_HIGH, "Salvation removed.\n");
			return;
		}

		AuraRemove(ent, AURA_SALVATION);
	}

	ent->client->ability_delay = level.time + DEFAULT_AURA_DELAY;
	// do we have enough power cubes?
	if (ent->client->pers.inventory[power_cube_index] < DEFAULT_AURA_INIT_COST)
	{
		safe_cprintf(ent, PRINT_HIGH, "You need more %d power cubes to use this ability.\n", 
			DEFAULT_AURA_INIT_COST-ent->client->pers.inventory[power_cube_index]);
		return;
	}
	ent->client->pers.inventory[power_cube_index] -= DEFAULT_AURA_INIT_COST;
	gi.sound(ent, CHAN_ITEM, gi.soundindex("auras/salvation.wav"), 1, ATTN_NORM, 0);
	safe_cprintf(ent, PRINT_HIGH, "Now using salvation aura.\n");
	aura_salvation(ent);
}
Ejemplo n.º 5
0
void ApplyThrust (edict_t *ent)
{
	int talentLevel, cost = JETPACK_AMMO;
    vec3_t forward, right;
    vec3_t pack_pos, jet_vector;

	if(ent->myskills.abilities[JETPACK].disable && level.time > pregame_time->value)
		return;

	//Talent: Flight
	if ((talentLevel = getTalentLevel(ent, TALENT_FLIGHT)) > 0)
	{
		int num;
		
		num = 0.4 * talentLevel;
		if (num < 1)
			num = 1;
		cost -= num;
	}

	//4.0 better jetpack check.
	if ((level.time > pregame_time->value) && !trading->value)  // allow jetpack in pregame and trading
		if (!G_CanUseAbilities (ent, ent->myskills.abilities[JETPACK].current_level, cost) )
			return;
	//can't use abilities (spawning sentry gun/drone/etc...)
	if (ent->holdtime > level.time)
		return;
	//4.07 can't use jetpack while being hurt
	if (ent->lasthurt+DAMAGE_ESCAPE_DELAY > level.time)
		return;
	//amnesia disables jetpack
	if (que_findtype(ent->curses, NULL, AMNESIA) != NULL)
		return;

	if (HasFlag(ent))
	{
		safe_cprintf(ent, PRINT_HIGH, "Can't use this ability while carrying the flag!\n");
		return;
	}

	if (ent->client->snipertime >= level.time)
	{
		safe_cprintf(ent, PRINT_HIGH, "You can't use jetpack while trying to snipe!\n");
		return;
	}

	if (ent->client->pers.inventory[power_cube_index] >= cost || level.time < pregame_time->value) // pregame.
	{
		ent->client->thrustdrain ++;
		if (ent->client->thrustdrain == JETPACK_DRAIN)
		{
			if (level.time > pregame_time->value) // not pregame
				ent->client->pers.inventory[power_cube_index] -= cost;
			ent->client->thrustdrain = 0;
		}
	}
	else
	{
		ent->client->thrusting=0;
		return;
	}

	if (ent->velocity[2] < 350)
	{
		if (ent->groundentity)
			ent->velocity[2] = 150;
		ent->velocity[2] += 150;
	}

    AngleVectors(ent->client->v_angle, forward, right, NULL);
    VectorScale (forward, -7, pack_pos);
    VectorAdd (pack_pos, ent->s.origin, pack_pos);
    pack_pos[2] += (ent->viewheight);

    VectorScale (forward, -50, jet_vector);

    if (ent->client->next_thrust_sound < level.time)
    {
		// wow this check is stupid.
		/*if (ent->client) */
            gi.sound (ent, CHAN_BODY, gi.soundindex("weapons/rockfly.wav"), 1, ATTN_NORM, 0);
            ent->client->next_thrust_sound=level.time+1.0;
    }

	ent->lastsound = level.framenum;
}
Ejemplo n.º 6
0
void Cmd_CorpseExplode(edict_t *ent)
{
	int		damage, min_dmg, max_dmg, slvl;
	float	fraction, radius;
	vec3_t	start, end, forward, right, offset;
	trace_t	tr;
	edict_t *e=NULL;

	if (debuginfo->value)
		gi.dprintf("DEBUG: %s just called Cmd_CorpseExplode()\n", ent->client->pers.netname);

	if(ent->myskills.abilities[CORPSE_EXPLODE].disable)
		return;

	if (!G_CanUseAbilities(ent, ent->myskills.abilities[CORPSE_EXPLODE].current_level, COST_FOR_CORPSEEXPLODE))
		return;

	slvl = ent->myskills.abilities[CORPSE_EXPLODE].current_level;
	radius = CORPSE_EXPLOSION_INITIAL_RADIUS + CORPSE_EXPLOSION_ADDON_RADIUS * slvl;

	// calculate starting position
	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, CORPSE_EXPLOSION_MAX_RANGE, forward, end);
	tr = gi.trace(start, NULL, NULL, end, ent, MASK_SOLID);

	while ((e = findclosestradius (e, tr.endpos, CORPSE_EXPLOSION_SEARCH_RADIUS)) != NULL)
	{
		if (!G_EntExists(e))
			continue;
		if (e->health > 0)
			continue;
		if (e->max_health < 1)
			continue;

		// kill the corpse
		T_Damage(e, e, ent, vec3_origin, e->s.origin, vec3_origin, 10000, 0, DAMAGE_NO_PROTECTION, MOD_CORPSEEXPLODE);

		// inflict damage
		fraction = 0.1 * GetRandom(5, 10);
		damage = fraction * e->max_health;
		
		// calculate min/max damage range
		min_dmg = CORPSE_EXPLOSION_INITIAL_DAMAGE + CORPSE_EXPLOSION_ADDON_DAMAGE * slvl;
		max_dmg = 5 * min_dmg;

		if (damage < min_dmg)
			damage = min_dmg;
		else if (damage > max_dmg)
			damage = max_dmg;

		T_RadiusDamage (e, ent, damage, NULL, radius, MOD_CORPSEEXPLODE);

		//gi.dprintf("fraction %.1f, damage %d, max_health: %d\n", fraction, damage, e->max_health);

		//Spells like corpse explode shouldn't display 10000 damage, so show the corpse damage instead
		ent->client->ps.stats[STAT_ID_DAMAGE] = damage;

		gi.sound(e, CHAN_ITEM, gi.soundindex("spells/corpseexplodecast.wav"), 1, ATTN_NORM, 0);
		ent->client->pers.inventory[power_cube_index] -= COST_FOR_CORPSEEXPLODE;
		ent->client->ability_delay = level.time + DELAY_CORPSEEXPLODE;
		safe_cprintf(ent, PRINT_HIGH, "Corpse exploded for %d damage!\n", damage);

		//decino: explosion effect
		gi.WriteByte (svc_temp_entity);
		gi.WriteByte (TE_GRENADE_EXPLOSION);
		gi.WritePosition (e->s.origin);
		gi.multicast (e->s.origin, MULTICAST_PVS);

		//decino: shoot 6 gibs that deal damage
		//az: todo, more copypaste.
		/*for (i = 0; i < 10; i++)
		{
			e->s.angles[YAW] += 36;
			AngleCheck(&e->s.angles[YAW]);

			AngleVectors(e->s.angles, forward, NULL, up);
			fire_gib(ent, e->s.origin, forward, dmg, 0, 1000);
		}*/

		// calling entity made a sound, used to alert monsters
		ent->lastsound = level.framenum;

		break;
	}
}
Ejemplo n.º 7
0
void Cmd_MiniSentry_f (edict_t *ent)
{
	int talentLevel, sentries=0, cost=SENTRY_COST;
	float skill_mult=1.0, cost_mult=1.0, delay_mult=1.0;//Talent: Rapid Assembly & Precision Tuning
	edict_t *scan=NULL;

	if (debuginfo->value)
		gi.dprintf("%s just called Cmd_MiniSentry_f\n", ent->client->pers.netname);

	if (ent->myskills.abilities[BUILD_SENTRY].disable)
		return;

	if (!Q_strcasecmp(gi.args(), "remove"))
	{
		RemoveMiniSentries(ent);
		return;
	}

	// 3.9 double sentry cost if there are too many sentries in CTF
	if (ctf->value)
	{
		sentries += 2*CTF_GetNumSummonable("Sentry_Gun", ent->teamnum);
		sentries += CTF_GetNumSummonable("msentrygun", ent->teamnum);

		if (sentries > MAX_MINISENTRIES)
			cost *= 2;
	}

	// cost is doubled if you are a flyer or cacodemon below skill level 5
	if ((ent->mtype == MORPH_FLYER && ent->myskills.abilities[FLYER].current_level < 5) 
		|| (ent->mtype == MORPH_CACODEMON && ent->myskills.abilities[CACODEMON].current_level < 5))
		cost *= 2;

	//Talent: Rapid Assembly
	talentLevel = getTalentLevel(ent, TALENT_RAPID_ASSEMBLY);
	if (talentLevel > 0)
		delay_mult -= 0.1 * talentLevel;
	//Talent: Precision Tuning
	else if ((talentLevel = getTalentLevel(ent, TALENT_PRECISION_TUNING)) > 0)
	{
		cost_mult += PRECISION_TUNING_COST_FACTOR * talentLevel;
		delay_mult += PRECISION_TUNING_DELAY_FACTOR * talentLevel;
		skill_mult += PRECISION_TUNING_SKILL_FACTOR * talentLevel;
	}
	cost *= cost_mult;

	if (!G_CanUseAbilities(ent, ent->myskills.abilities[BUILD_SENTRY].current_level, cost))
		return;

	if (ent->num_sentries >= MAX_MINISENTRIES)
	{
		safe_cprintf(ent, PRINT_HIGH, "You have reached the max of %d sentries\n", MAX_MINISENTRIES);
		return;
	}

	if (ctf->value && (CTF_DistanceFromBase(ent, NULL, CTF_GetEnemyTeam(ent->teamnum)) < CTF_BASE_DEFEND_RANGE))
	{
		safe_cprintf(ent, PRINT_HIGH, "Can't build in enemy base!\n");
		return;
	}

	SpawnMiniSentry(ent, cost, skill_mult, delay_mult);
}
Ejemplo n.º 8
0
void Cmd_Healing(edict_t *ent)
{
	int radius;
	float duration;
	edict_t *target = NULL;

	if (debuginfo->value)
		gi.dprintf("DEBUG: %s just called Cmd_Healing()\n", ent->client->pers.netname);

	if(ent->myskills.abilities[HEALING].disable)
		return;

	if (!G_CanUseAbilities(ent, ent->myskills.abilities[HEALING].current_level, HEALING_COST))
		return;

	radius = SHAMAN_CURSE_RADIUS_BASE + (SHAMAN_CURSE_RADIUS_BONUS * ent->myskills.abilities[HEALING].current_level);
	duration = HEALING_DURATION_BASE + (HEALING_DURATION_BONUS * ent->myskills.abilities[HEALING].current_level);

	//Blessing self?
	if (Q_strcasecmp(gi.argv(1), "self") == 0)
	{
		if (!curse_add(ent, ent, HEALING, 0, duration))
		{
			gi.cprintf(ent, PRINT_HIGH, "Unable to bless self.\n");
			return;
		}
		target = ent;
	}
	else
	{
		target = curse_Attack(ent, HEALING, radius, duration, false);
	}
	if (target != NULL)
	{
		que_t *slot = NULL;
		//Finish casting the spell
		ent->client->ability_delay = level.time + HEALING_DELAY;
		ent->client->pers.inventory[power_cube_index] -= HEALING_COST;

		//Change the curse think to the healing think
		slot = que_findtype(target->curses, NULL, HEALING);
		if (slot)
		{
			slot->ent->think = Healing_think;
			slot->ent->nextthink = level.time + FRAMETIME;
		}

		//Notify the target
		if (target == ent)
		{
			gi.cprintf(target, PRINT_HIGH, "YOU HAVE BEEN BLESSED WITH %0.1f seconds OF HEALING!!\n", duration);
		}
		else if ((target->client) && !(target->svflags & SVF_MONSTER))
		{
			gi.cprintf(target, PRINT_HIGH, "YOU HAVE BEEN BLESSED WITH %0.1f seconds OF HEALING!!\n", duration);
			gi.cprintf(ent, PRINT_HIGH, "Blessed %s with healing for %0.1f seconds.\n", target->myskills.player_name, duration);
		}
		else
		{
			gi.cprintf(ent, PRINT_HIGH, "Blessed %s with healing for %0.1f seconds.\n", target->classname, duration);
		}
		//Play the spell sound!
		gi.sound(target, CHAN_ITEM, gi.soundindex("curses/prayer.wav"), 1, ATTN_NORM, 0);
	}
}