Beispiel #1
0
void
player_die(edict_t *self, edict_t *inflictor, edict_t *attacker,
		int damage, vec3_t point /* unused */)
{
	int n;

	if (!self || !inflictor || !attacker)
	{
		return;
	}

	VectorClear(self->avelocity);

	self->takedamage = DAMAGE_YES;
	self->movetype = MOVETYPE_TOSS;

	self->s.modelindex2 = 0; /* remove linked weapon model */

	self->s.angles[0] = 0;
	self->s.angles[2] = 0;

	self->s.sound = 0;
	self->client->weapon_sound = 0;

	self->maxs[2] = -8;

	self->svflags |= SVF_DEADMONSTER;

	if (!self->deadflag)
	{
		self->client->respawn_time = level.time + 1.0;
		LookAtKiller(self, inflictor, attacker);
		self->client->ps.pmove.pm_type = PM_DEAD;
		ClientObituary(self, inflictor, attacker);
		TossClientWeapon(self);

		if (deathmatch->value)
		{
			Cmd_Help_f(self); /* show scores */
		}

		/* clear inventory: this is kind of ugly, but
		   it's how we want to handle keys in coop */
		for (n = 0; n < game.num_items; n++)
		{
			if (coop->value && itemlist[n].flags & IT_KEY)
			{
				self->client->resp.coop_respawn.inventory[n] =
					self->client->pers.inventory[n];
			}

			self->client->pers.inventory[n] = 0;
		}
	}

	/* remove powerups */
	self->client->quad_framenum = 0;
	self->client->invincible_framenum = 0;
	self->client->breather_framenum = 0;
	self->client->enviro_framenum = 0;
	self->flags &= ~FL_POWER_ARMOR;

	if (self->health < -40)
	{
		/* gib */
		gi.sound(self, CHAN_BODY, gi.soundindex(
						"misc/udeath.wav"), 1, ATTN_NORM, 0);

		for (n = 0; n < 4; n++)
		{
			ThrowGib(self, "models/objects/gibs/sm_meat/tris.md2",
					damage, GIB_ORGANIC);
		}

		ThrowClientHead(self, damage);

		self->takedamage = DAMAGE_NO;
	}
	else
	{
		/* normal death */
		if (!self->deadflag)
		{
			static int i;

			i = (i + 1) % 3;

			/* start a death animation */
			self->client->anim_priority = ANIM_DEATH;

			if (self->client->ps.pmove.pm_flags & PMF_DUCKED)
			{
				self->s.frame = FRAME_crdeath1 - 1;
				self->client->anim_end = FRAME_crdeath5;
			}
			else
			{
				switch (i)
				{
					case 0:
						self->s.frame = FRAME_death101 - 1;
						self->client->anim_end = FRAME_death106;
						break;
					case 1:
						self->s.frame = FRAME_death201 - 1;
						self->client->anim_end = FRAME_death206;
						break;
					case 2:
						self->s.frame = FRAME_death301 - 1;
						self->client->anim_end = FRAME_death308;
						break;
				}
			}

			gi.sound(self, CHAN_VOICE, gi.soundindex(va("*death%i.wav",
							(randk() % 4) + 1)), 1, ATTN_NORM, 0);
		}
	}

	self->deadflag = DEAD_DEAD;

	gi.linkentity(self);
}
Beispiel #2
0
/*
 * A brand new game has been started
 */
void
SV_InitGame ( void )
{
	int i;
	edict_t *ent;
	char idmaster [ 32 ];

	if ( svs.initialized )
	{
		/* cause any connected clients to reconnect */
		SV_Shutdown( "Server restarted\n", true );
	}

#ifndef DEDICATED_ONLY
	else
	{
		/* make sure the client is down */
		CL_Drop();
		SCR_BeginLoadingPlaque();
	}
#endif

	/* get any latched variable changes (maxclients, etc) */
	Cvar_GetLatchedVars();

	svs.initialized = true;

	if ( Cvar_VariableValue( "coop" ) && Cvar_VariableValue( "deathmatch" ) )
	{
		Com_Printf( "Deathmatch and Coop both set, disabling Coop\n" );
		Cvar_FullSet( "coop", "0",  CVAR_SERVERINFO | CVAR_LATCH );
	}

	/* dedicated servers can't be single player and are usually DM
	   so unless they explicity set coop, force it to deathmatch */
	if ( dedicated->value )
	{
		if ( !Cvar_VariableValue( "coop" ) )
		{
			Cvar_FullSet( "deathmatch", "1",  CVAR_SERVERINFO | CVAR_LATCH );
		}
	}

	/* init clients */
	if ( Cvar_VariableValue( "deathmatch" ) )
	{
		if ( maxclients->value <= 1 )
		{
			Cvar_FullSet( "maxclients", "8", CVAR_SERVERINFO | CVAR_LATCH );
		}
		else if ( maxclients->value > MAX_CLIENTS )
		{
			Cvar_FullSet( "maxclients", va( "%i", MAX_CLIENTS ), CVAR_SERVERINFO | CVAR_LATCH );
		}
	}
	else if ( Cvar_VariableValue( "coop" ) )
	{
		if ( ( maxclients->value <= 1 ) || ( maxclients->value > 4 ) )
		{
			Cvar_FullSet( "maxclients", "4", CVAR_SERVERINFO | CVAR_LATCH );
		}
	}
	else /* non-deathmatch, non-coop is one player */
	{
		Cvar_FullSet( "maxclients", "1", CVAR_SERVERINFO | CVAR_LATCH );
	}

	svs.spawncount = randk();
	svs.clients = Z_Malloc( sizeof ( client_t ) * maxclients->value );
	svs.num_client_entities = maxclients->value * UPDATE_BACKUP * 64;
	svs.client_entities = Z_Malloc( sizeof ( entity_state_t ) * svs.num_client_entities );

	/* init network stuff */
	NET_Config( ( maxclients->value > 1 ) );

	/* heartbeats will always be sent to the id master */
	svs.last_heartbeat = -99999; /* send immediately */
	Com_sprintf( idmaster, sizeof ( idmaster ), "192.246.40.37:%i", PORT_MASTER );
	NET_StringToAdr( idmaster, &master_adr [ 0 ] );

	/* init game */
	SV_InitGameProgs();

	for ( i = 0; i < maxclients->value; i++ )
	{
		ent = EDICT_NUM( i + 1 );
		ent->s.number = i + 1;
		svs.clients [ i ].edict = ent;
		memset( &svs.clients [ i ].lastcmd, 0, sizeof ( svs.clients [ i ].lastcmd ) );
	}
}
Beispiel #3
0
/*
 * go to a random point, but NOT the two
 * points closest to other players
 */
edict_t *
SelectRandomDeathmatchSpawnPoint(void)
{
	edict_t *spot, *spot1, *spot2;
	int count = 0;
	int selection;
	float range, range1, range2;

	spot = NULL;
	range1 = range2 = 99999;
	spot1 = spot2 = NULL;

	while ((spot = G_Find(spot, FOFS(classname),
					"info_player_deathmatch")) != NULL)
	{
		count++;
		range = PlayersRangeFromSpot(spot);

		if (range < range1)
		{
			range1 = range;
			spot1 = spot;
		}
		else if (range < range2)
		{
			range2 = range;
			spot2 = spot;
		}
	}

	if (!count)
	{
		return NULL;
	}

	if (count <= 2)
	{
		spot1 = spot2 = NULL;
	}
	else
	{
		if (spot1)
		{
			count--;
		}

		if (spot2)
		{
			count--;
		}
	}

	selection = randk() % count;

	spot = NULL;

	do
	{
		spot = G_Find(spot, FOFS(classname), "info_player_deathmatch");

		if ((spot == spot1) || (spot == spot2))
		{
			selection++;
		}
	}
	while (selection--);

	return spot;
}
Beispiel #4
0
void
rocket_touch(edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf)
{
	vec3_t origin;
	int n;

	if (!ent || !other)
	{
		G_FreeEdict(ent);
		return;
	}

	if (other == ent->owner)
	{
		return;
	}

	if (surf && (surf->flags & SURF_SKY))
	{
		G_FreeEdict(ent);
		return;
	}

	if (ent->owner && ent->owner->client)
	{
		PlayerNoise(ent->owner, ent->s.origin, PNOISE_IMPACT);
	}

	/* calculate position for the explosion entity */
	VectorMA(ent->s.origin, -0.02, ent->velocity, origin);

	if (other->takedamage)
	{
		if (plane)
		{
			T_Damage(other, ent, ent->owner, ent->velocity, ent->s.origin,
					plane->normal, ent->dmg, 0, 0, MOD_ROCKET);
		}
		else
		{
			T_Damage(other, ent, ent->owner, ent->velocity, ent->s.origin,
					vec3_origin, ent->dmg, 0, 0, MOD_ROCKET);
		}
	}
	else
	{
		/* don't throw any debris in net games */
		if (!deathmatch->value && !coop->value)
		{
			if ((surf) && !(surf->flags &
				  (SURF_WARP | SURF_TRANS33 | SURF_TRANS66 | SURF_FLOWING)))
			{
				n = randk() % 5;

				while (n--)
				{
					ThrowDebris(ent, "models/objects/debris2/tris.md2",
							2, ent->s.origin);
				}
			}
		}
	}

	T_RadiusDamage(ent, ent->owner, ent->radius_dmg, other, ent->dmg_radius,
			MOD_R_SPLASH);

	gi.WriteByte(svc_temp_entity);

	if (ent->waterlevel)
	{
		gi.WriteByte(TE_ROCKET_EXPLOSION_WATER);
	}
	else
	{
		gi.WriteByte(TE_ROCKET_EXPLOSION);
	}

	gi.WritePosition(origin);
	gi.multicast(ent->s.origin, MULTICAST_PHS);

	G_FreeEdict(ent);
}
Beispiel #5
0
void
CL_AddPacketEntities(frame_t *frame)
{
	entity_t ent = {0};
	entity_state_t *s1;
	float autorotate;
	int i;
	int pnum;
	centity_t *cent;
	int autoanim;
	clientinfo_t *ci;
	unsigned int effects, renderfx;

	/* bonus items rotate at a fixed rate */
	autorotate = anglemod(cl.time * 0.1f);

	/* brush models can auto animate their frames */
	autoanim = 2 * cl.time / 1000;

	for (pnum = 0; pnum < frame->num_entities; pnum++)
	{
		s1 = &cl_parse_entities[(frame->parse_entities +
				pnum) & (MAX_PARSE_ENTITIES - 1)];

		cent = &cl_entities[s1->number];

		effects = s1->effects;
		renderfx = s1->renderfx;

		/* set frame */
		if (effects & EF_ANIM01)
		{
			ent.frame = autoanim & 1;
		}

		else if (effects & EF_ANIM23)
		{
			ent.frame = 2 + (autoanim & 1);
		}

		else if (effects & EF_ANIM_ALL)
		{
			ent.frame = autoanim;
		}

		else if (effects & EF_ANIM_ALLFAST)
		{
			ent.frame = cl.time / 100;
		}

		else
		{
			ent.frame = s1->frame;
		}

		/* quad and pent can do different things on client */
		if (effects & EF_PENT)
		{
			effects &= ~EF_PENT;
			effects |= EF_COLOR_SHELL;
			renderfx |= RF_SHELL_RED;
		}

		if (effects & EF_QUAD)
		{
			effects &= ~EF_QUAD;
			effects |= EF_COLOR_SHELL;
			renderfx |= RF_SHELL_BLUE;
		}

		if (effects & EF_DOUBLE)
		{
			effects &= ~EF_DOUBLE;
			effects |= EF_COLOR_SHELL;
			renderfx |= RF_SHELL_DOUBLE;
		}

		if (effects & EF_HALF_DAMAGE)
		{
			effects &= ~EF_HALF_DAMAGE;
			effects |= EF_COLOR_SHELL;
			renderfx |= RF_SHELL_HALF_DAM;
		}

		ent.oldframe = cent->prev.frame;
		ent.backlerp = 1.0f - cl.lerpfrac;

		if (renderfx & (RF_FRAMELERP | RF_BEAM))
		{
			/* step origin discretely, because the
			   frames do the animation properly */
			VectorCopy(cent->current.origin, ent.origin);
			VectorCopy(cent->current.old_origin, ent.oldorigin);
		}
		else
		{
			/* interpolate origin */
			for (i = 0; i < 3; i++)
			{
				ent.origin[i] = ent.oldorigin[i] = cent->prev.origin[i] + cl.lerpfrac *
				   	(cent->current.origin[i] - cent->prev.origin[i]);
			}
		}

		/* tweak the color of beams */
		if (renderfx & RF_BEAM)
		{
			/* the four beam colors are encoded in 32 bits of skinnum (hack) */
			ent.alpha = 0.30f;
			ent.skinnum = (s1->skinnum >> ((randk() % 4) * 8)) & 0xff;
			ent.model = NULL;
		}
		else
		{
			/* set skin */
			if (s1->modelindex == 255)
Beispiel #6
0
 void
 BossExplode ( edict_t *self )
 {
   vec3_t org;
   q_int32_t n;

   if ( !self ) {
     return;
   }

   self->think = BossExplode;
   VectorCopy ( self->s.origin, org );
   org[2] += 24 + ( randk() & 15 );

   switch ( self->count++ ) {
   case 0:
     org[0] -= 24;
     org[1] -= 24;
     break;
   case 1:
     org[0] += 24;
     org[1] += 24;
     break;
   case 2:
     org[0] += 24;
     org[1] -= 24;
     break;
   case 3:
     org[0] -= 24;
     org[1] += 24;
     break;
   case 4:
     org[0] -= 48;
     org[1] -= 48;
     break;
   case 5:
     org[0] += 48;
     org[1] += 48;
     break;
   case 6:
     org[0] -= 48;
     org[1] += 48;
     break;
   case 7:
     org[0] += 48;
     org[1] -= 48;
     break;
   case 8:
     self->s.sound = 0;

     for ( n = 0; n < 4; n++ ) {
       ThrowGib ( self, "models/objects/gibs/sm_meat/tris.md2",
                  500, GIB_ORGANIC );
     }

     for ( n = 0; n < 8; n++ ) {
       ThrowGib ( self, "models/objects/gibs/sm_metal/tris.md2",
                  500, GIB_METALLIC );
     }

     ThrowGib ( self, "models/objects/gibs/chest/tris.md2",
                500, GIB_ORGANIC );
     ThrowHead ( self, "models/objects/gibs/gear/tris.md2",
                 500, GIB_METALLIC );
     self->deadflag = DEAD_DEAD;
     return;
   }

   gi.WriteByte ( svc_temp_entity );
   gi.WriteByte ( TE_EXPLOSION1 );
   gi.WritePosition ( org );
   gi.multicast ( self->s.origin, MULTICAST_PVS );

   self->nextthink = level.time + 0.1;
 }
Beispiel #7
0
void Weapon_Grenade(edict_t *ent)
{
  if (!ent) {
    return;
  }

  if ((ent->client->newweapon) && (ent->client->weaponstate == WEAPON_READY)) {
    ChangeWeapon(ent);
    return;
  }

  if (ent->client->weaponstate == WEAPON_ACTIVATING) {
    ent->client->weaponstate = WEAPON_READY;
    ent->client->ps.gunframe = 16;
    return;
  }

  if (ent->client->weaponstate == WEAPON_READY) {
    if (((ent->client->latched_buttons | ent->client->buttons) & BUTTON_ATTACK)) {
      ent->client->latched_buttons &= ~BUTTON_ATTACK;

      if (ent->client->pers.inventory[ent->client->ammo_index]) {
        ent->client->ps.gunframe = 1;
        ent->client->weaponstate = WEAPON_FIRING;
        ent->client->grenade_time = 0;
      } else {
        if (level.time >= ent->pain_debounce_time) {
          PF_StartSound(ent, CHAN_VOICE, SV_SoundIndex("weapons/noammo.wav"), 1, ATTN_NORM, 0);
          ent->pain_debounce_time = level.time + 1;
        }

        NoAmmoWeaponChange(ent);
      }

      return;
    }

    if ((ent->client->ps.gunframe == 29) || (ent->client->ps.gunframe == 34) || (ent->client->ps.gunframe == 39) ||
        (ent->client->ps.gunframe == 48)) {
      if (randk() & 15) {
        return;
      }
    }

    if (++ent->client->ps.gunframe > 48) {
      ent->client->ps.gunframe = 16;
    }

    return;
  }

  if (ent->client->weaponstate == WEAPON_FIRING) {
    if (ent->client->ps.gunframe == 5) {
      PF_StartSound(ent, CHAN_WEAPON, SV_SoundIndex("weapons/hgrena1b.wav"), 1, ATTN_NORM, 0);
    }

    if (ent->client->ps.gunframe == 11) {
      if (!ent->client->grenade_time) {
        ent->client->grenade_time = level.time + GRENADE_TIMER + 0.2;
        ent->client->weapon_sound = SV_SoundIndex("weapons/hgrenc1b.wav");
      }

      /* they waited too long, detonate it in their hand */
      if (!ent->client->grenade_blew_up && (level.time >= ent->client->grenade_time)) {
        ent->client->weapon_sound = 0;
        weapon_grenade_fire(ent, true);
        ent->client->grenade_blew_up = true;
      }

      if (ent->client->buttons & BUTTON_ATTACK) {
        return;
      }

      if (ent->client->grenade_blew_up) {
        if (level.time >= ent->client->grenade_time) {
          ent->client->ps.gunframe = 15;
          ent->client->grenade_blew_up = false;
        } else {
          return;
        }
      }
    }

    if (ent->client->ps.gunframe == 12) {
      ent->client->weapon_sound = 0;
      weapon_grenade_fire(ent, false);
    }

    if ((ent->client->ps.gunframe == 15) && (level.time < ent->client->grenade_time)) {
      return;
    }

    ent->client->ps.gunframe++;

    if (ent->client->ps.gunframe == 16) {
      ent->client->grenade_time = 0;
      ent->client->weaponstate = WEAPON_READY;
    }
  }
}
Beispiel #8
0
/*
 * A generic function to handle
 * the basics of weapon thinking
 */
void Weapon_Generic(edict_t *ent, int FRAME_ACTIVATE_LAST, int FRAME_FIRE_LAST, int FRAME_IDLE_LAST,
                    int FRAME_DEACTIVATE_LAST, int *pause_frames, int *fire_frames, void (*fire)(edict_t *ent))
{
  int n;

  if (!ent || !fire_frames || !fire) {
    return;
  }

  if (ent->deadflag || (ent->s.modelindex != 255)) /* VWep animations screw up corpses */
  {
    return;
  }

  if (ent->client->weaponstate == WEAPON_DROPPING) {
    if (ent->client->ps.gunframe == FRAME_DEACTIVATE_LAST) {
      ChangeWeapon(ent);
      return;
    } else if ((FRAME_DEACTIVATE_LAST - ent->client->ps.gunframe) == 4) {
      ent->client->anim_priority = ANIM_REVERSE;

      if (ent->client->ps.pmove.pm_flags & PMF_DUCKED) {
        ent->s.frame = FRAME_crpain4 + 1;
        ent->client->anim_end = FRAME_crpain1;
      } else {
        ent->s.frame = FRAME_pain304 + 1;
        ent->client->anim_end = FRAME_pain301;
      }
    }

    ent->client->ps.gunframe++;
    return;
  }

  if (ent->client->weaponstate == WEAPON_ACTIVATING) {
    if (ent->client->ps.gunframe == FRAME_ACTIVATE_LAST) {
      ent->client->weaponstate = WEAPON_READY;
      ent->client->ps.gunframe = FRAME_IDLE_FIRST;
      return;
    }

    ent->client->ps.gunframe++;
    return;
  }

  if ((ent->client->newweapon) && (ent->client->weaponstate != WEAPON_FIRING)) {
    ent->client->weaponstate = WEAPON_DROPPING;
    ent->client->ps.gunframe = FRAME_DEACTIVATE_FIRST;

    if ((FRAME_DEACTIVATE_LAST - FRAME_DEACTIVATE_FIRST) < 4) {
      ent->client->anim_priority = ANIM_REVERSE;

      if (ent->client->ps.pmove.pm_flags & PMF_DUCKED) {
        ent->s.frame = FRAME_crpain4 + 1;
        ent->client->anim_end = FRAME_crpain1;
      } else {
        ent->s.frame = FRAME_pain304 + 1;
        ent->client->anim_end = FRAME_pain301;
      }
    }

    return;
  }

  if (ent->client->weaponstate == WEAPON_READY) {
    if (((ent->client->latched_buttons | ent->client->buttons) & BUTTON_ATTACK)) {
      ent->client->latched_buttons &= ~BUTTON_ATTACK;

      if ((!ent->client->ammo_index) ||
          (ent->client->pers.inventory[ent->client->ammo_index] >= ent->client->pers.weapon->quantity)) {
        ent->client->ps.gunframe = FRAME_FIRE_FIRST;
        ent->client->weaponstate = WEAPON_FIRING;

        /* start the animation */
        ent->client->anim_priority = ANIM_ATTACK;

        if (ent->client->ps.pmove.pm_flags & PMF_DUCKED) {
          ent->s.frame = FRAME_crattak1 - 1;
          ent->client->anim_end = FRAME_crattak9;
        } else {
          ent->s.frame = FRAME_attack1 - 1;
          ent->client->anim_end = FRAME_attack8;
        }
      } else {
        if (level.time >= ent->pain_debounce_time) {
          PF_StartSound(ent, CHAN_VOICE, SV_SoundIndex("weapons/noammo.wav"), 1, ATTN_NORM, 0);
          ent->pain_debounce_time = level.time + 1;
        }

        NoAmmoWeaponChange(ent);
      }
    } else {
      if (ent->client->ps.gunframe == FRAME_IDLE_LAST) {
        ent->client->ps.gunframe = FRAME_IDLE_FIRST;
        return;
      }

      if (pause_frames) {
        for (n = 0; pause_frames[n]; n++) {
          if (ent->client->ps.gunframe == pause_frames[n]) {
            if (randk() & 15) {
              return;
            }
          }
        }
      }

      ent->client->ps.gunframe++;
      return;
    }
  }

  if (ent->client->weaponstate == WEAPON_FIRING) {
    for (n = 0; fire_frames[n]; n++) {
      if (ent->client->ps.gunframe == fire_frames[n]) {
        fire(ent);
        break;
      }
    }

    if (!fire_frames[n]) {
      ent->client->ps.gunframe++;
    }

    if (ent->client->ps.gunframe == FRAME_IDLE_FIRST + 1) {
      ent->client->weaponstate = WEAPON_READY;
    }
  }
}