Example #1
0
// the trigger was just activated
// ent->activator should be set to the activator so it can be held through a delay
// so wait for the delay time before firing
void multi_trigger(gentity_t * ent, gentity_t * activator)
{
	ent->activator = activator;
	if(ent->nextthink)
	{
		return;					// can't retrigger until the wait is over
	}

	if(activator->client)
	{
		if(ent->red_only && activator->client->sess.sessionTeam != TEAM_RED)
		{
			return;
		}
		if(ent->blue_only && activator->client->sess.sessionTeam != TEAM_BLUE)
		{
			return;
		}
	}

	G_UseTargets(ent, ent->activator);

#ifdef G_LUA
	// Lua API callbacks
	if(ent->luaTrigger)
	{
		if(activator)
		{
			G_LuaHook_EntityTrigger(ent->luaTrigger, ent->s.number, activator->s.number);
		}
		else
		{
			G_LuaHook_EntityTrigger(ent->luaTrigger, ent->s.number, ENTITYNUM_WORLD);
		}
	}
#endif

	if(ent->wait > 0)
	{
		ent->think = multi_wait;
		ent->nextthink = level.time + (ent->wait + ent->random * crandom()) * 1000;
	}
	else
	{
		// we can't just remove (self) here, because this is a touch function
		// called while looping through area links...
		ent->touch = 0;
		ent->nextthink = level.time + FRAMETIME;
		ent->think = G_FreeEntity;
	}
}
Example #2
0
void hurt_touch(gentity_t * self, gentity_t * other, trace_t * trace)
{
	int             dflags;

	if(!other->takedamage)
		return;

	if(self->timestamp > level.time)
		return;

	if(self->spawnflags & 16)
		self->timestamp = level.time + 1000;
	else
		self->timestamp = level.time + FRAMETIME;

	// play sound
	if(!(self->spawnflags & 4))
		G_Sound(other, CHAN_AUTO, self->soundIndex);

#ifdef G_LUA
	// Lua API callbacks
	if(self->luaTrigger)
	{
		G_LuaHook_EntityTrigger(self->luaTrigger, self->s.number, other->s.number);
	}
#endif

	if(self->spawnflags & 8)
		dflags = DAMAGE_NO_PROTECTION;
	else
		dflags = 0;

	G_Damage(other, self, self, NULL, NULL, self->damage, dflags, MOD_TRIGGER_HURT);
}
Example #3
0
void trigger_teleporter_touch(gentity_t * self, gentity_t * other, trace_t * trace)
{
	gentity_t      *dest;

	if(!other->client)
		return;

	if(other->client->ps.pm_type == PM_DEAD)
		return;

	// Spectators only?
	if((self->spawnflags & 1) && other->client->sess.sessionTeam != TEAM_SPECTATOR)
		return;


	dest = G_PickTarget(self->target);

	if(!dest)
	{
		G_Printf("Couldn't find teleporter destination\n");
		return;
	}

#ifdef G_LUA
	// Lua API callbacks
	if(self->luaTrigger)
	{
		G_LuaHook_EntityTrigger(self->luaTrigger, self->s.number, other->s.number);
	}
#endif

	TeleportPlayer(other, dest->s.origin, dest->s.angles);
}
Example #4
0
void Use_target_push(gentity_t * self, gentity_t * other, gentity_t * activator)
{
	if(!activator->client)
		return;

	if(activator->client->ps.pm_type != PM_NORMAL)
		return;

#ifdef G_LUA
	// Lua API callbacks
	if(self->luaTrigger)
	{
		G_LuaHook_EntityTrigger(self->luaTrigger, self->s.number, activator->s.number);
	}
#endif

	VectorCopy(self->s.origin2, activator->client->ps.velocity);

	// play fly sound every 1.5 seconds
	if(activator->fly_sound_debounce_time < level.time)
	{
		activator->fly_sound_debounce_time = level.time + 1500;
		G_Sound(activator, CHAN_AUTO, self->soundIndex);
	}
}
Example #5
0
static void target_fx_think(gentity_t * self)
{
#ifdef G_LUA
	// Lua API callbacks
	if(self->luaTrigger)
	{
		G_LuaHook_EntityTrigger(self->luaTrigger, self->s.number, self->s.number);
	}
#endif

	G_AddEvent(self, EV_EFFECT, self->s.modelindex);

	if(self->wait > 0)
	{
		//ent->think = multi_wait;
		self->nextthink = level.time + (self->wait + self->random * crandom()) * 1000;
	}
	else
	{
		// we can't just remove (self) here, because this is a touch function
		// called while looping through area links...
		self->touch = NULL;
		self->nextthink = level.time + FRAMETIME;
		self->think = G_FreeEntity;
	}
}
Example #6
0
// the trigger was just activated
// ent->activator should be set to the activator so it can be held through a delay
// so wait for the delay time before firing
void multi_trigger(gentity_t * ent, gentity_t * activator)
{
	ent->activator = activator;
	if(ent->nextthink)
		return;					// can't retrigger until the wait is over

	if(activator->client)
	{
		if((ent->spawnflags & 1) && activator->client->ps.stats[STAT_PTEAM] != PTE_HUMANS)
			return;

		if((ent->spawnflags & 2) && activator->client->ps.stats[STAT_PTEAM] != PTE_ALIENS)
			return;
	}

	G_UseTargets(ent, ent->activator);

#ifdef G_LUA
	// Lua API callbacks
	if(ent->luaTrigger)
	{
		if(activator)
		{
			G_LuaHook_EntityTrigger(ent->luaTrigger, ent->s.number, activator->s.number);
		}
		else
		{
			G_LuaHook_EntityTrigger(ent->luaTrigger, ent->s.number, ENTITYNUM_WORLD);
		}
	}
#endif

	if(ent->wait > 0)
	{
		ent->think = multi_wait;
		ent->nextthink = level.time + (ent->wait + ent->random * crandom()) * 1000;
	}
	else
	{
		// we can't just remove (self) here, because this is a touch function
		// called while looping through area links...
		ent->touch = 0;
		ent->nextthink = level.time + FRAMETIME;
		ent->think = G_FreeEntity;
	}
}
Example #7
0
/*QUAKED target_delay (1 0 0) (-8 -8 -8) (8 8 8)
"wait" seconds to pause before firing targets.
"random" delay variance, total delay = delay +/- random seconds
*/
void Think_Target_Delay(gentity_t * ent)
{
#ifdef G_LUA
	// Lua API callbacks
	if(ent->luaTrigger)
	{
		if(ent->activator)
		{
			G_LuaHook_EntityTrigger(ent->luaTrigger, ent->s.number, ent->activator->s.number);
		}
		else
		{
			G_LuaHook_EntityTrigger(ent->luaTrigger, ent->s.number, ENTITYNUM_WORLD);
		}
	}
#endif
	G_UseTargets(ent, ent->activator);
}
Example #8
0
/*QUAKED func_timer (0.3 0.1 0.6) (-8 -8 -8) (8 8 8) START_ON
This should be renamed trigger_timer...
Repeatedly fires its targets.
Can be turned on or off by using.

"wait"      base time between triggering all targets, default is 1
"random"    wait variance, default is 0
so, the basic time between firing is a random time between
(wait - random) and (wait + random)

*/
void func_timer_think(gentity_t * self)
{
	G_UseTargets(self, self->activator);
#ifdef G_LUA
	// Lua API callbacks
	if(self->luaTrigger)
	{
		if(self->activator)
		{
			G_LuaHook_EntityTrigger(self->luaTrigger, self->s.number, self->activator->s.number);
		}
		else
		{
			G_LuaHook_EntityTrigger(self->luaTrigger, self->s.number, self->s.number);
		}
	}
#endif

	// set time before next firing
	self->nextthink = level.time + 1000 * (self->wait + crandom() * self->random);
}
Example #9
0
void trigger_push_touch(gentity_t * self, gentity_t * other, trace_t * trace)
{
	if(!other->client)
		return;

#ifdef G_LUA
	// Lua API callbacks
	if(self->luaTrigger)
	{
		G_LuaHook_EntityTrigger(self->luaTrigger, self->s.number, other->s.number);
	}
#endif

}
Example #10
0
void trigger_always_think(gentity_t * ent)
{
	G_UseTargets(ent, ent);

#ifdef G_LUA
	// Lua API callbacks
	if(ent->luaTrigger)
	{
		G_LuaHook_EntityTrigger(ent->luaTrigger, ent->s.number, ent->s.number);
	}
#endif

	G_FreeEntity(ent);
}
Example #11
0
void hurt_touch(gentity_t * self, gentity_t * other, trace_t * trace)
{
	int             dflags;

	if(!other->takedamage)
	{
		return;
	}

	if(self->timestamp > level.time)
	{
		return;
	}

	if(self->slow)
	{
		self->timestamp = level.time + 1000;
	}
	else
	{
		self->timestamp = level.time + FRAMETIME;
	}

	// play sound
	if(!self->silent)
	{
		G_Sound(other, CHAN_AUTO, self->soundIndex);
	}

#ifdef G_LUA
	// Lua API callbacks
	if(self->luaTrigger)
	{
		G_LuaHook_EntityTrigger(self->luaTrigger, self->s.number, other->s.number);
	}
#endif

	if(self->no_protection)
		dflags = DAMAGE_NO_PROTECTION;
	else
		dflags = 0;
	G_Damage(other, self, self, NULL, NULL, self->damage, dflags, MOD_TRIGGER_HURT);
}
Example #12
0
/*
===========
ClientSpawn

Called every time a client is placed fresh in the world:
after the first ClientBegin, and after each respawn
Initializes all non-persistant parts of playerState
============
*/
void ClientSpawn(gentity_t * ent)
{
  int             index;
  vec3_t          spawn_origin, spawn_angles;
  gclient_t      *client;
  int             i;
  clientPersistant_t saved;
  clientSession_t savedSess;
  int             persistant[MAX_PERSISTANT];
  gentity_t      *spawnPoint;
  int             flags;
  int             savedPing;

//  char    *savedAreaBits;
  int             accuracy_hits, accuracy_shots;
  int             eventSequence;
  char            userinfo[MAX_INFO_STRING];

  index = ent - g_entities;
  client = ent->client;

  // find a spawn point
  // do it before setting health back up, so farthest
  // ranging doesn't count this client
  if(client->sess.sessionTeam == TEAM_SPECTATOR)
  {
    spawnPoint = SelectSpectatorSpawnPoint(spawn_origin, spawn_angles);
  }
  else if(g_gametype.integer >= GT_CTF)
  {
    // all base oriented team games use the CTF spawn points
    spawnPoint = SelectCTFSpawnPoint(client->sess.sessionTeam, client->pers.teamState.state, spawn_origin, spawn_angles);
  }
  else
  {
    do
    {
      // the first spawn should be at a good looking spot
      if(!client->pers.initialSpawn && client->pers.localClient)
      {
        client->pers.initialSpawn = qtrue;
        spawnPoint = SelectInitialSpawnPoint(spawn_origin, spawn_angles);
      }
      else
      {
        // don't spawn near existing origin if possible
        spawnPoint = SelectSpawnPoint(client->ps.origin, spawn_origin, spawn_angles);
      }

      // Tim needs to prevent bots from spawning at the initial point
      // on q3dm0...
      if((spawnPoint->flags & FL_NO_BOTS) && (ent->r.svFlags & SVF_BOT))
      {
        continue;		// try again
      }
      // just to be symetric, we have a nohumans option...
      if((spawnPoint->flags & FL_NO_HUMANS) && !(ent->r.svFlags & SVF_BOT))
      {
        continue;		// try again
      }

      break;

    } while(1);
  }
  client->pers.teamState.state = TEAM_ACTIVE;

  // always clear the kamikaze flag
  ent->s.eFlags &= ~EF_KAMIKAZE;

  // toggle the teleport bit so the client knows to not lerp
  // and never clear the voted flag
  flags = ent->client->ps.eFlags & (EF_TELEPORT_BIT | EF_VOTED | EF_TEAMVOTED);
  flags ^= EF_TELEPORT_BIT;

  // clear everything but the persistant data

  saved = client->pers;
  savedSess = client->sess;
  savedPing = client->ps.ping;
//  savedAreaBits = client->areabits;
  accuracy_hits = client->accuracy_hits;
  accuracy_shots = client->accuracy_shots;
  for(i = 0; i < MAX_PERSISTANT; i++)
  {
    persistant[i] = client->ps.persistant[i];
  }
  eventSequence = client->ps.eventSequence;

  Com_Memset(client, 0, sizeof(*client));

  client->pers = saved;
  client->sess = savedSess;
  client->ps.ping = savedPing;
//  client->areabits = savedAreaBits;
  client->accuracy_hits = accuracy_hits;
  client->accuracy_shots = accuracy_shots;
  client->lastkilled_client = -1;

  for(i = 0; i < MAX_PERSISTANT; i++)
  {
    client->ps.persistant[i] = persistant[i];
  }
  client->ps.eventSequence = eventSequence;
  // increment the spawncount so the client will detect the respawn
  client->ps.persistant[PERS_SPAWN_COUNT]++;
  client->ps.persistant[PERS_TEAM] = client->sess.sessionTeam;

  client->airOutTime = level.time + 12000;

  trap_GetUserinfo(index, userinfo, sizeof(userinfo));
  // set max health
  client->pers.maxHealth = atoi(Info_ValueForKey(userinfo, "handicap"));
  if(client->pers.maxHealth < 1 || client->pers.maxHealth > 100)
  {
    client->pers.maxHealth = 100;
  }
  // clear entity values
  client->ps.stats[STAT_MAX_HEALTH] = client->pers.maxHealth;
  client->ps.eFlags = flags;

  ent->s.groundEntityNum = ENTITYNUM_NONE;
  ent->client = &level.clients[index];
  ent->takedamage = qtrue;
  ent->inuse = qtrue;
  ent->classname = "player";
  ent->r.contents = CONTENTS_BODY;
  ent->clipmask = MASK_PLAYERSOLID;
  ent->die = player_die;
  ent->waterlevel = 0;
  ent->watertype = 0;
  ent->flags = 0;

  VectorCopy(playerMins, ent->r.mins);
  VectorCopy(playerMaxs, ent->r.maxs);

  client->ps.clientNum = index;

  /*
  client->ps.stats[STAT_WEAPONS] = (1 << WP_MACHINEGUN);
  if(g_gametype.integer == GT_TEAM)
  {
    client->ps.ammo[WP_MACHINEGUN] = 50;
  }
  else
  {
    client->ps.ammo[WP_MACHINEGUN] = 100;
  }
  */

  /*
  client->ps.stats[STAT_WEAPONS] |= (1 << WP_GAUNTLET);
  client->ps.ammo[WP_GAUNTLET] = -1;
  */

  // health will count down towards max_health
  ent->health = client->ps.stats[STAT_HEALTH] = client->ps.stats[STAT_MAX_HEALTH] + 25;
  client->ps.stats[STAT_ARMOR] = client->ps.stats[STAT_MAX_HEALTH];

  G_SetOrigin(ent, spawn_origin);
  VectorCopy(spawn_origin, client->ps.origin);

  // the respawned flag will be cleared after the attack and jump keys come up
  client->ps.pm_flags |= PMF_RESPAWNED;

  trap_GetUsercmd(client - level.clients, &ent->client->pers.cmd);
  SetClientViewAngle(ent, spawn_angles);

  if(ent->client->sess.sessionTeam == TEAM_SPECTATOR)
  {

  }
  else
  {
    G_KillBox(ent);
    trap_LinkEntity(ent);

    // force the base weapon up
    //client->ps.weapon = WP_MACHINEGUN;
    client->ps.weaponstate = WEAPON_READY;

  }

  // don't allow full run speed for a bit
  client->ps.pm_flags |= PMF_TIME_KNOCKBACK;
  client->ps.pm_time = 100;

  client->respawnTime = level.time;
  client->inactivityTime = level.time + g_inactivity.integer * 1000;
  client->latched_buttons = 0;

  // set default animations
  client->ps.torsoAnim = TORSO_STAND;
  client->ps.legsAnim = LEGS_IDLE;

  if(level.intermissiontime)
  {
    MoveClientToIntermission(ent);
  }
  else
  {
    // fire the targets of the spawn point
    G_UseTargets(spawnPoint, ent);
#ifdef G_LUA
    // Lua API callbacks
    if(spawnPoint && spawnPoint->luaTrigger)
    {
      G_LuaHook_EntityTrigger(spawnPoint->luaTrigger, spawnPoint->s.number, ent->s.number);
    }
#endif

    // select the highest weapon number available, after any
    // spawn given items have fired
    client->ps.weapon = 0;
    for(i = WP_NUM_WEAPONS - 1; i > 0; i--)
    {
      if(client->ps.stats[STAT_WEAPONS] & (1 << i))
      {
        client->ps.weapon = i;
        break;
      }
    }
  }

#if defined(ACEBOT)
  if(ent->r.svFlags & SVF_BOT)
  {
    ACESP_SetupBotState(ent);
  }
#endif

#ifdef G_LUA
  // Lua API callbacks
  G_LuaHook_ClientSpawn(ent->s.number);
#endif

  // run a client frame to drop exactly to the floor,
  // initialize animations and other things
  client->ps.commandTime = level.time - 100;
  ent->client->pers.cmd.serverTime = level.time;
  ClientThink(ent - g_entities);

  // positively link the client, even if the command times are weird
  if(ent->client->sess.sessionTeam != TEAM_SPECTATOR)
  {
    BG_PlayerStateToEntityState(&client->ps, &ent->s, qtrue);
    VectorCopy(ent->client->ps.origin, ent->r.currentOrigin);
    trap_LinkEntity(ent);
  }

  // run the presend to set anything else
  ClientEndFrame(ent);

  // clear entity state values
  BG_PlayerStateToEntityState(&client->ps, &ent->s, qtrue);
}