Example #1
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);
}
Example #2
0
void SpawnTotem(edict_t *ent, int abilityID)
{
	int			talentLevel, cost=TOTEM_COST;
	edict_t		*totem;
	int			totemType;
	vec3_t		start;//GHz 4.32

	// 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;

	if(!V_CanUseAbilities(ent, abilityID, cost, true))
		return;
	
	if (ctf->value && abilityID == FIRE_TOTEM 
		&& (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;
	}

	//Determine the totem type.
	switch(abilityID)
	{
	case FIRE_TOTEM:		totemType = TOTEM_FIRE;		break;
	case WATER_TOTEM:		totemType = TOTEM_WATER;	break;
	case AIR_TOTEM:			totemType = TOTEM_AIR;		break;
	case EARTH_TOTEM:		totemType = TOTEM_EARTH;	break;
	case DARK_TOTEM:		totemType = TOTEM_DARKNESS;	break;
	case NATURE_TOTEM:		totemType = TOTEM_NATURE;	break;
	default: return;
	}

	//Can't create too many totems.
	if(ent->totem1)
	{
		//Can't have more than one totem without the talent.
		/*if(getTalentLevel(ent, TALENT_TOTEM) < 1)
		{
			safe_cprintf(ent, PRINT_HIGH, "You already have a totem active.\n");
			return;
		}
		//Can't have more than two totems.
		else*/ if(ent->totem2)
		{
			safe_cprintf(ent, PRINT_HIGH, "You already have two totems active.\n");
			return;
		}
		//Can't have two totems of opposite alignment.
		else
		{
			int opposite = 0;
			switch(ent->totem1->mtype)
			{
			case TOTEM_FIRE:		opposite = TOTEM_WATER;		break;
			case TOTEM_WATER:		opposite = TOTEM_FIRE;		break;
			case TOTEM_AIR:			opposite = TOTEM_EARTH;		break;
			case TOTEM_EARTH:		opposite = TOTEM_AIR;		break;
			case TOTEM_DARKNESS:	opposite = TOTEM_NATURE;	break;
			case TOTEM_NATURE:		opposite = TOTEM_DARKNESS;	break;
			}
			if(totemType == opposite)
			{
				safe_cprintf(ent, PRINT_HIGH, "You can't create two totems of opposite elemental alignment.\n");
				return;
			}
			else if(totemType == ent->totem1->mtype)
			{
				safe_cprintf(ent, PRINT_HIGH, "You can't create totems of the same type.\n");
				return;
			}
		}
	}

	//Drop a totem.
	totem = DropTotem(ent);
	totem->mtype = totemType;
	totem->monsterinfo.level = ent->myskills.abilities[abilityID].current_level;
	totem->classname = "totem";
	/*totem->owner =*/ totem->activator = ent;
	totem->think = totem_general_think;
	totem->touch = totem_touch;
	totem->nextthink = level.time + FRAMETIME*2;
	totem->delay = level.time + 0.5;
	totem->die = totem_die;

	//TODO: update this with the new model.
	totem->s.modelindex = gi.modelindex("models/items/mega_h/tris.md2");
	//totem->s.angles[ROLL] = 270;
	VectorSet (totem->mins, -8, -8, -12);
	VectorSet (totem->maxs, 8, 8, 16);
	VectorCopy(ent->s.origin, totem->s.origin);
	
	totem->health = TOTEM_HEALTH_BASE + TOTEM_HEALTH_MULT * totem->monsterinfo.level;

	//Talent: Totemic Focus - increases totem health
	if((talentLevel = getTalentLevel(ent, TALENT_TOTEM)) > 0)
		totem->health *= 1 + 0.1666 * talentLevel;

	if (totemType == TOTEM_FIRE)
	{
		// fire totem is much tougher
		totem->health *= 2;
		// fire totem has a longer delay
		totem->delay = level.time + 2.0;
	}

	totem->max_health = totem->health*2;

	//Not sure if this stuff is needed (Archer)
	totem->svflags |= SVF_MONSTER;
	totem->takedamage = DAMAGE_AIM;
	totem->clipmask = MASK_MONSTERSOLID;

	//Back to stuff we need
	totem->mass = 200;
	totem->movetype = MOVETYPE_TOSS;//MOVETYPE_WALK;
	totem->deadflag = DEAD_NO;
	totem->svflags &= ~SVF_DEADMONSTER;	
	totem->solid = SOLID_BBOX;

	//Graphical effects
	//TODO: update this to make it look better.
	totem->s.effects |= EF_PLASMA | EF_COLOR_SHELL | EF_SPHERETRANS;
	switch(totemType)
	{
	case TOTEM_FIRE:
		totem->s.effects |= 262144;		//red radius light
		totem->s.renderfx |= RF_SHELL_RED;
		break;
	case TOTEM_WATER:
		totem->s.effects |= 524288;		//blue radius light
		totem->s.renderfx |= RF_SHELL_CYAN;
		break;
	case TOTEM_AIR:
		totem->s.effects |= 64;			//bright light radius
		totem->s.renderfx |= RF_SHELL_RED | RF_SHELL_BLUE | RF_SHELL_GREEN;		
		break;
	case TOTEM_EARTH:
		totem->s.renderfx |= RF_SHELL_YELLOW;
		break;
	case TOTEM_DARKNESS:
		totem->s.effects |= 2147483648;		//strange darkness effect
		//totem->s.renderfx |= RF_SHELL_RED | RF_SHELL_BLUE;
		break;
	case TOTEM_NATURE:
		totem->s.effects |= 128;	//green radius light
		totem->s.renderfx |= RF_SHELL_GREEN;
		break;
	}
//GHz 4.32
	if (!G_GetSpawnLocation(ent, 64, totem->mins, totem->maxs, start))
	{
		G_FreeEdict(totem);
		return;
	}

	VectorCopy(start, totem->s.origin);
	gi.linkentity(totem);
//GHz
	if(!ent->totem1)	ent->totem1 = totem;
	else				ent->totem2 = totem;

	ent->client->pers.inventory[ITEM_INDEX(Fdi_POWERCUBE)] -= cost;

	// calling entity made a sound, used to alert monsters
	ent->lastsound = level.framenum;
	ent->client->ability_delay = level.time + 1.3;
}
Example #3
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);
}