예제 #1
0
void p_medic_firebolt (edict_t *ent)
{
	int		min_dmg;
	int		damage = MEDIC_BOLT_INITIAL_DMG+MEDIC_BOLT_ADDON_DMG*ent->myskills.abilities[MEDIC].current_level;
	int		speed = MEDIC_BOLT_INITIAL_SPEED+MEDIC_BOLT_ADDON_SPEED*ent->myskills.abilities[MEDIC].current_level;
	vec3_t	forward, right, start;

	// is this a firing frame?
	if (ent->s.frame != 188 && ent->s.frame != 185)
		return;

	// check for adequate ammo
	if (ent->myskills.abilities[MEDIC].ammo < MEDIC_BOLT_AMMO)
		return;
	ent->myskills.abilities[MEDIC].ammo -= MEDIC_BOLT_AMMO;

	AngleVectors(ent->client->v_angle, forward, right, NULL);
	G_ProjectSource(ent->s.origin, monster_flash_offset[MZ2_MEDIC_BLASTER_1], forward, right, start);

	min_dmg = floattoint(0.111*damage);
	damage = GetRandom(min_dmg, damage);

	fire_blaster(ent, start, forward, damage, speed, EF_BLASTER, BLASTER_PROJ_BLAST, MOD_BLASTER, 2.0, false);

	gi.WriteByte (svc_muzzleflash2);
	gi.WriteShort (ent-g_edicts);
	gi.WriteByte (MZ2_MEDIC_BLASTER_1);
	gi.multicast (start, MULTICAST_PVS);

	gi.sound (ent, CHAN_WEAPON, gi.soundindex("weapons/photon.wav"), 1, ATTN_NORM, 0);
}
예제 #2
0
void p_medic_hb_regen (edict_t *ent, int regen_frames, int regen_delay)
{
	int ammo;
	int max = ent->myskills.abilities[MEDIC].max_ammo;
	int *current = &ent->myskills.abilities[MEDIC].ammo;
	int *delay = &ent->myskills.abilities[MEDIC].ammo_regenframe;

	if (*current > max)
		return;

	// don't regenerate ammo if player is firing
	if ((ent->client->buttons & BUTTON_ATTACK) && (ent->client->weapon_mode != 1))
		return;

	if (regen_delay > 0)
	{
		if (level.framenum < *delay)
			return;

		*delay = level.framenum + regen_delay;
	}
	else
		regen_delay = 1;

	ammo = floattoint((float)max / ((float)regen_frames / regen_delay));

	if (ammo < 1)
		ammo = 1;

	*current += ammo;
	if (*current > max)
		*current = max;
}
예제 #3
0
void p_medic_reanimate (edict_t *ent, edict_t *target)
{
	int		skill_level;
	vec3_t	bmin, bmax;
	edict_t *e;

	skill_level = floattoint((1.0+MEDIC_RESURRECT_BONUS)*ent->myskills.abilities[MEDIC].current_level);

	if (!strcmp(target->classname, "drone") 
		&& (ent->num_monsters + target->monsterinfo.control_cost <= MAX_MONSTERS))
	{
		target->monsterinfo.level = skill_level;
		M_SetBoundingBox(target->mtype, bmin, bmax);

		if (G_IsValidLocation(target, target->s.origin, bmin, bmax) && M_Initialize(ent, target))
		{
			// restore this drone
			target->monsterinfo.slots_freed = false; // reset freed flag
			target->health = 0.33*target->max_health;
			target->monsterinfo.power_armor_power = 0.33*target->monsterinfo.max_armor;
			target->monsterinfo.resurrected_time = level.time + 2.0;
			target->activator = ent; // transfer ownership!
			target->nextthink = level.time + MEDIC_RESURRECT_DELAY;
			gi.linkentity(target);
			target->monsterinfo.stand(target);

			ent->num_monsters += target->monsterinfo.control_cost;
			safe_cprintf(ent, PRINT_HIGH, "Resurrected a %s. (%d/%d)\n", 
				target->classname, ent->num_monsters, MAX_MONSTERS);
		}
	}
	else if ((!strcmp(target->classname, "bodyque") || !strcmp(target->classname, "player"))
		&& (ent->num_monsters + 1 <= MAX_MONSTERS))
	{
		int		random=GetRandom(1, 3);
		vec3_t	start;

		e = G_Spawn();

		VectorCopy(target->s.origin, start);

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

		//4.2 random soldier type with different weapons
		if (random == 1)
		{
			// blaster
			e->mtype = M_SOLDIER;
			e->s.skinnum = 0;
		}
		else if (random == 2)
		{
			// rocket
			e->mtype = M_SOLDIERLT;
			e->s.skinnum = 4;
		}
		else
		{
			// shotgun
			e->mtype = M_SOLDIERSS;
			e->s.skinnum = 2;
		}

		e->activator = ent;
		e->monsterinfo.level = skill_level;
		M_Initialize(ent, e);
		e->health = 0.2*e->max_health;
		e->monsterinfo.power_armor_power = 0.2*e->monsterinfo.max_armor;
		e->s.skinnum |= 1; // injured skin

		e->monsterinfo.stand(e);
		
		if (!G_IsValidLocation(target, start, e->mins, e->maxs))
		{
			start[2] += 24;
			if (!G_IsValidLocation(target, start, e->mins, e->maxs))
			{
				G_FreeEdict(e);
				return;
			}
		}

		VectorCopy(start, e->s.origin);
		gi.linkentity(e);
		e->nextthink = level.time + MEDIC_RESURRECT_DELAY;

		ent->num_monsters += e->monsterinfo.control_cost;

		safe_cprintf(ent, PRINT_HIGH, "Resurrected a soldier. (%d/%d)\n", 
			ent->num_monsters, MAX_MONSTERS);
	}
	else if (!strcmp(target->classname, "spiker") && ent->num_spikers + 1 <= SPIKER_MAX_COUNT)
	{
		e = CreateSpiker(ent, skill_level);

		// make sure the new entity fits
		if (!G_IsValidLocation(target, target->s.origin, e->mins, e->maxs))
		{
			ent->num_spikers--;
			G_FreeEdict(e);
			return;
		}
		
		VectorCopy(target->s.angles, e->s.angles);
		e->s.angles[PITCH] = 0;
		e->monsterinfo.cost = target->monsterinfo.cost;
		e->health = 0.33 * e->max_health;
		e->s.frame = 4;
		VectorCopy(target->s.origin, e->s.origin);
		gi.linkentity(e);

		organ_remove(target, false);
	}
	else if (!strcmp(target->classname, "obstacle") && ent->num_obstacle + 1 <= OBSTACLE_MAX_COUNT)
	{
		e = CreateObstacle(ent, skill_level);

		// make sure the new entity fits
		if (!G_IsValidLocation(target, target->s.origin, e->mins, e->maxs))
		{
			ent->num_obstacle--;
			G_FreeEdict(e);
			return;
		}
		
		VectorCopy(target->s.angles, e->s.angles);
		e->s.angles[PITCH] = 0;
		e->monsterinfo.cost = target->monsterinfo.cost;
		e->health = 0.33 * e->max_health;
		e->s.frame = 6;
		VectorCopy(target->s.origin, e->s.origin);
		gi.linkentity(e);

		organ_remove(target, false);
	}
	else if (!strcmp(target->classname, "gasser") && ent->num_gasser + 1 <= GASSER_MAX_COUNT)
	{
		e = CreateGasser(ent, skill_level);

		// make sure the new entity fits
		if (!G_IsValidLocation(target, target->s.origin, e->mins, e->maxs))
		{
			ent->num_gasser--;
			G_FreeEdict(e);
			return;
		}
		
		VectorCopy(target->s.angles, e->s.angles);
		e->s.angles[PITCH] = 0;
		e->monsterinfo.cost = target->monsterinfo.cost;
		e->health = 0.33 * e->max_health;
		e->s.frame = 0;
		VectorCopy(target->s.origin, e->s.origin);
		gi.linkentity(e);

		organ_remove(target, false);
	}
		
}
예제 #4
0
void p_medic_heal (edict_t *ent)
{
	vec3_t	forward,  right, offset, start, end, org;
	trace_t	tr;

	if (!p_medic_healframe(ent))
		return;
	
	if (ent->s.frame == 218)
		gi.sound (ent, CHAN_WEAPON, gi.soundindex("medic/medatck2.wav"), 1, ATTN_NORM, 0);
	else if (ent->s.frame == 227)
		gi.sound (ent, CHAN_WEAPON, gi.soundindex("medic/medatck5.wav"), 1, ATTN_NORM, 0);

	// get muzzle location
	AngleVectors (ent->s.angles, forward, right, NULL);
	VectorCopy(p_medic_cable_offsets[ent->s.frame - 218], offset);
	G_ProjectSource(ent->s.origin, offset, forward, right, org);

	// get end position
	VectorCopy(ent->s.origin, start);
	start[2] += ent->viewheight;
	AngleVectors (ent->client->v_angle, forward, NULL, NULL);
	VectorMA(start, MEDIC_CABLE_RANGE, forward, end);

	tr = gi.trace (org, NULL, NULL, end, ent, MASK_SHOT);

	// bfg laser effect
	gi.WriteByte (svc_temp_entity);
	gi.WriteByte (TE_BFG_LASER);
	gi.WritePosition (org);
	gi.WritePosition (tr.endpos);
	gi.multicast (ent->s.origin, MULTICAST_PHS);

	if (G_EntExists(tr.ent))
	{
		// try to heal them if they are alive
		if ((tr.ent->deadflag != DEAD_DEAD) && (tr.ent->health > 0))
		{
			int frames = floattoint(600/(float)ent->myskills.abilities[MEDIC].current_level);
			
			if (!M_NeedRegen(tr.ent))
				return;

			if (ent->s.frame == 220)
				gi.sound (ent, CHAN_WEAPON, gi.soundindex ("medic/medatck4.wav"), 1, ATTN_NORM, 0);
			
			// heal them
			M_Regenerate(tr.ent, frames, 0, 1.0, true, true, false, &tr.ent->monsterinfo.regen_delay2);

			// hold monsters in-place
			if (tr.ent->svflags & SVF_MONSTER)
				tr.ent->holdtime = level.time + 0.2;

			// remove all curses
			CurseRemove(tr.ent, 0);

			//Give them a short period of curse immunity
			tr.ent->holywaterProtection = level.time + 2.0; //2 seconds immunity
		}
		else
		{
			// try to reanimate/resurrect the corpse
			p_medic_reanimate(ent, tr.ent);
		}
	}
}
예제 #5
0
void AddVote(edict_t *ent, int mode, int mapnum)
{
	v_maplist_t *maplist = GetMapList(mode);

	if (!maplist)
		return;
  
	//check for valid choice
	if (mode && (maplist->nummaps > mapnum))
	{
		char tempBuffer[1024];
		//Add the vote
		voter = ent;
		numVotes = 1;
		ent->client->resp.HasVoted = true;
		strcpy(currentVote.ip, ent->client->pers.current_ip);
		strcpy(currentVote.name, ent->myskills.player_name);
		currentVote.mapindex = mapnum;
		currentVote.mode = mode;
		currentVote.used = true;
		voteTimeLeft = level.time + 90;


		Com_sprintf (tempBuffer, 1024, "%s started a vote for ", ent->myskills.player_name);
		switch(mode)
		{
			case MAPMODE_PVP:	Com_sprintf (tempBuffer, 1024, "%sPlayer vs. Player (PvP) ", tempBuffer);	break;
			case MAPMODE_PVM:	Com_sprintf (tempBuffer, 1024, "%sPlayer vs. Monster (PvM) ", tempBuffer);	break;
			case MAPMODE_DOM:	Com_sprintf (tempBuffer, 1024, "%sDomination ", tempBuffer);			break;
			case MAPMODE_CTF:	Com_sprintf (tempBuffer, 1024, "%sCapture The Flag (CTF) ", tempBuffer);					break;
			case MAPMODE_FFA:	Com_sprintf (tempBuffer, 1024, "%sFree For All (FFA) ", tempBuffer);	break;
			case MAPMODE_INV:	Com_sprintf (tempBuffer, 1024, "%sInvasion ", tempBuffer);
		}
		Com_sprintf (tempBuffer, 1024, "%son %s\n", tempBuffer, maplist->maps[mapnum].name);

		gi.bprintf (PRINT_CHAT, "%s", tempBuffer);
		gi.bprintf (PRINT_HIGH, "Please place your vote by typing 'vote yes' or 'vote no' within the next %d seconds.\n", floattoint(voteTimeLeft-level.time));

	}
	else 
		gi.dprintf("Error in AddVote(): map number = %d, mode number = %d\n", mapnum, mode);
}