Exemplo n.º 1
0
/*
==============
Team_DroppedFlagThink

Automatically set in Launch_Item if the item is one of the flags

Flags are unique in that if they are dropped, the base flag must be respawned when they time out
==============
*/
void Team_DroppedFlagThink(gentity_t *ent) {
	if (ent->item->giTag == PW_REDFLAG) {
		G_Script_ScriptEvent(&g_entities[ent->s.otherEntityNum], "trigger", "returned");

		Team_ReturnFlagSound(ent, TEAM_AXIS);
		Team_ResetFlag(ent);

		if (level.gameManager) {
			G_Script_ScriptEvent(level.gameManager, "trigger", "axis_object_returned");
		}

		// Nico, bugfix: removed left printf
		// http://games.chruker.dk/enemy_territory/modding_project_bugfix.php?bug_id=058
		// trap_SendServerCommand( -1, "cp \"Axis have returned the objective!\" 2" );
	} else if (ent->item->giTag == PW_BLUEFLAG) {
		G_Script_ScriptEvent(&g_entities[ent->s.otherEntityNum], "trigger", "returned");

		Team_ReturnFlagSound(ent, TEAM_ALLIES);
		Team_ResetFlag(ent);

		if (level.gameManager) {
			G_Script_ScriptEvent(level.gameManager, "trigger", "allied_object_returned");
		}
	}
	// Reset Flag will delete this entity
}
Exemplo n.º 2
0
/**
 * @brief Automatically set in Launch_Item if the item is one of the flags
 *
 * @details Flags are unique in that if they are dropped, the base flag must be respawned when they time out
 *
 * @param[in] ent
 */
void Team_DroppedFlagThink(gentity_t *ent)
{
	if (ent->item->giTag == PW_REDFLAG)
	{
		G_Script_ScriptEvent(&g_entities[ent->s.otherEntityNum], "trigger", "returned");

		Team_ReturnFlagSound(ent, TEAM_AXIS);
		Team_ResetFlag(ent);

		if (level.gameManager)
		{
			G_Script_ScriptEvent(level.gameManager, "trigger", "axis_object_returned");
		}
	}
	else if (ent->item->giTag == PW_BLUEFLAG)
	{
		G_Script_ScriptEvent(&g_entities[ent->s.otherEntityNum], "trigger", "returned");

		Team_ReturnFlagSound(ent, TEAM_ALLIES);
		Team_ResetFlag(ent);

		if (level.gameManager)
		{
			G_Script_ScriptEvent(level.gameManager, "trigger", "allied_object_returned");
		}
	}
	// Reset Flag will delete this entity
}
Exemplo n.º 3
0
/*
===============
G_CallSpawn

Finds the spawn function for the entity and calls it,
returning qfalse if not found
===============
*/
qboolean G_CallSpawn(gentity_t *ent)
{
	spawn_t *s;
	gitem_t *item;

	if (!ent->classname)
	{
		G_Printf("G_CallSpawn: NULL classname\n");
		return qfalse;
	}

	// check item spawn functions
	for (item = bg_itemlist + 1 ; item->classname ; item++)
	{
		if (!strcmp(item->classname, ent->classname))
		{
			// found it
			if (g_gametype.integer != GT_WOLF_LMS)     // lets not have items in last man standing for the moment
			{
				G_SpawnItem(ent, item);

				G_Script_ScriptParse(ent);
				G_Script_ScriptEvent(ent, "spawn", "");
			}
			else
			{
				return qfalse;
			}
			return qtrue;
		}
	}

	// check normal spawn functions
	for (s = spawns ; s->name ; s++)
	{
		if (!strcmp(s->name, ent->classname))
		{
			// found it
			s->spawn(ent);

			// entity scripting
			if (/*ent->s.number >= MAX_CLIENTS &&*/ ent->scriptName)
			{
				G_Script_ScriptParse(ent);
				G_Script_ScriptEvent(ent, "spawn", "");
			}

			return qtrue;
		}
	}

	// hack: this avoids spammy prints on start, bsp uses obsolete classnames!
	// bot_sniper_spot (railgun)
	if (Q_stricmp(ent->classname, "bot_sniper_spot"))
	{
		G_Printf("%s doesn't have a spawn function\n", ent->classname);
	}

	return qfalse;
}
Exemplo n.º 4
0
/*QUAKED target_script_trigger (1 .7 .2) (-8 -8 -8) (8 8 8)
must have an aiName
must have a target

when used it will fire its targets
*/
void target_script_trigger_use(gentity_t *ent, gentity_t *other, gentity_t *activator) {
// START	Mad Doctor I changes, 8/16/2002
	qboolean found = qfalse;

	// Nico, silent GCC
	(void)activator;

	// Are we using ainame to find another ent instead of using scriptname for this one?
	if (ent->aiName) {
		gentity_t *trent = NULL;

		// Find the first entity with this name
		trent = G_Find(trent, FOFS(scriptName), ent->aiName);

		// Was there one?
		if (trent) {
			// We found it
			found = qtrue;

			// Play the script
			G_Script_ScriptEvent(trent, "trigger", ent->target);

		} // if (trent)...

	} // if (ent->aiName)...

	// Use the old method if we didn't find an entity with the ainame
	if (!found && ent->scriptName) {
		G_Script_ScriptEvent(ent, "trigger", ent->target);
	}

	G_UseTargets(ent, other);
}
Exemplo n.º 5
0
void Touch_flagonly( gentity_t *ent, gentity_t *other, trace_t *trace ) {

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

	if ( ent->spawnflags & RED_FLAG && other->client->ps.powerups[ PW_REDFLAG ] ) {

		AddScore( other, ent->accuracy ); // JPW NERVE set from map, defaults to 20

		G_Script_ScriptEvent( ent, "death", "" );

		// Removes itself
		ent->touch = 0;
		ent->nextthink = level.time + FRAMETIME;
		ent->think = G_FreeEntity;
	} else if ( ent->spawnflags & BLUE_FLAG && other->client->ps.powerups[ PW_BLUEFLAG ] )   {

		AddScore( other, ent->accuracy ); // JPW NERVE set from map, defaults to 20

		G_Script_ScriptEvent( ent, "death", "" );

		// Removes itself
		ent->touch = 0;
		ent->nextthink = level.time + FRAMETIME;
		ent->think = G_FreeEntity;
	}
}
Exemplo n.º 6
0
int Team_TouchOurFlag(gentity_t *ent, gentity_t *other, int team) {
	gclient_t *cl = other->client;

	if (ent->flags & FL_DROPPED_ITEM) {
		// hey, its not home.  return it by teleporting it back
		if (cl->sess.sessionTeam == TEAM_AXIS) {
			if (level.gameManager) {
				G_Script_ScriptEvent(level.gameManager, "trigger", "axis_object_returned");
			}
			G_Script_ScriptEvent(&g_entities[ent->s.otherEntityNum], "trigger", "returned");
		} else {
			if (level.gameManager) {
				G_Script_ScriptEvent(level.gameManager, "trigger", "allied_object_returned");
			}
			G_Script_ScriptEvent(&g_entities[ent->s.otherEntityNum], "trigger", "returned");
		}
		// dhm
// jpw 800 672 2420
		//ResetFlag will remove this entity!  We must return zero
		Team_ReturnFlagSound(ent, team);
		Team_ResetFlag(ent);
		return 0;
	}

	// DHM - Nerve :: GT_WOLF doesn't support capturing the flag
	return 0;
}
Exemplo n.º 7
0
void Touch_flagonly (gentity_t *ent, gentity_t *other, trace_t *trace) {
	gentity_t* tmp;

	if (!other->client)
		return;
	

	if ( ent->spawnflags & RED_FLAG && other->client->ps.powerups[ PW_REDFLAG ] ) {

		if( ent->spawnflags & 4 ) {
			other->client->ps.powerups[ PW_REDFLAG ] = 0;
			other->client->speedScale = 0;
		}

		AddScore(other, ent->accuracy); // JPW NERVE set from map, defaults to 20
		//G_AddExperience( other, 2.f );

		tmp = ent->parent;
		ent->parent = other;

		G_Script_ScriptEvent( ent, "death", "" );

		G_Script_ScriptEvent( &g_entities[other->client->flagParent], "trigger", "captured" );

		ent->parent = tmp;

		// Removes itself
		ent->touch = NULL;
		ent->nextthink = level.time + FRAMETIME;
		ent->think = G_FreeEntity;
	} else if ( ent->spawnflags & BLUE_FLAG && other->client->ps.powerups[ PW_BLUEFLAG ] ) {

		if( ent->spawnflags & 4 ) {
			other->client->ps.powerups[ PW_BLUEFLAG ] = 0;
			other->client->speedScale = 0;
		}

		AddScore(other, ent->accuracy); // JPW NERVE set from map, defaults to 20

		//G_AddExperience( other, 2.f );

		tmp = ent->parent;
		ent->parent = other;

		G_Script_ScriptEvent( ent, "death", "" );

		G_Script_ScriptEvent( &g_entities[other->client->flagParent], "trigger", "captured" );

		ent->parent = tmp;

		// Removes itself
		ent->touch = NULL;
		ent->nextthink = level.time + FRAMETIME;
		ent->think = G_FreeEntity;
	}
}
Exemplo n.º 8
0
/*
===============
G_CallSpawn

Finds the spawn function for the entity and calls it,
returning qfalse if not found
===============
*/
qboolean G_CallSpawn(gentity_t * ent)
{
	spawn_t        *s;
	gitem_t        *item;

	if(!ent->classname)
	{
		G_Printf("G_CallSpawn: NULL classname\n");
		return qfalse;
	}

	// check item spawn functions
	for(item = bg_itemlist + 1; item->classname; item++)
	{
		if(!strcmp(item->classname, ent->classname))
		{
			// found it
			if(g_gametype.integer != GT_WOLF_LMS)
			{					// Gordon: lets not have items in last man standing for the moment
				G_SpawnItem(ent, item);

				G_Script_ScriptParse(ent);
				G_Script_ScriptEvent(ent, "spawn", "");
			}
			else
			{
				return qfalse;
			}
			return qtrue;
		}
	}

	// check normal spawn functions
	for(s = spawns; s->name; s++)
	{
		if(!strcmp(s->name, ent->classname))
		{
			// found it
			s->spawn(ent);

			// RF, entity scripting
			if( /*ent->s.number >= MAX_CLIENTS && */ ent->scriptName)
			{
				G_Script_ScriptParse(ent);
				G_Script_ScriptEvent(ent, "spawn", "");
			}

			return qtrue;
		}
	}
	G_Printf("%s doesn't have a spawn function\n", ent->classname);
	return qfalse;
}
Exemplo n.º 9
0
int Team_TouchEnemyFlag(gentity_t *ent, gentity_t *other, int team) {
	gclient_t *cl = other->client;
	gentity_t *tmp;

	ent->s.density--;

	tmp         = ent->parent;
	ent->parent = other;

	if (cl->sess.sessionTeam == TEAM_AXIS) {
		gentity_t *pm = G_PopupMessage(PM_OBJECTIVE);
		pm->s.effect3Time = G_StringIndex(ent->message);
		pm->s.effect2Time = TEAM_AXIS;
		pm->s.density     = 0; // 0 = stolen

		if (level.gameManager) {
			G_Script_ScriptEvent(level.gameManager, "trigger", "allied_object_stolen");
		}
		G_Script_ScriptEvent(ent, "trigger", "stolen");
	} else {
		gentity_t *pm = G_PopupMessage(PM_OBJECTIVE);
		pm->s.effect3Time = G_StringIndex(ent->message);
		pm->s.effect2Time = TEAM_ALLIES;
		pm->s.density     = 0; // 0 = stolen

		if (level.gameManager) {
			G_Script_ScriptEvent(level.gameManager, "trigger", "axis_object_stolen");
		}
		G_Script_ScriptEvent(ent, "trigger", "stolen");
	}

	ent->parent = tmp;

	if (team == TEAM_AXIS) {
		cl->ps.powerups[PW_REDFLAG] = INT_MAX;
	} else {
		cl->ps.powerups[PW_BLUEFLAG] = INT_MAX;
	} // flags never expire

	// store the entitynum of our original flag spawner
	if (ent->flags & FL_DROPPED_ITEM) {
		cl->flagParent = ent->s.otherEntityNum;
	} else {
		cl->flagParent = ent->s.number;
	}

	other->client->speedScale = ent->splashDamage; // Alter player speed

	if (ent->s.density > 0) {
		return 1; // We have more flags to give out, spawn back quickly
	}
	return -1; // Do not respawn this automatically, but do delete it if it was FL_DROPPED
}
Exemplo n.º 10
0
void Touch_flagonly(gentity_t *ent, gentity_t *other, trace_t *trace) {
	gentity_t *tmp;

	// Nico, silent GCC
	(void)trace;

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


	if (ent->spawnflags & RED_FLAG && other->client->ps.powerups[PW_REDFLAG]) {

		if (ent->spawnflags & 4) {
			other->client->ps.powerups[PW_REDFLAG] = 0;
			other->client->speedScale              = 0;
		}

		tmp         = ent->parent;
		ent->parent = other;

		G_Script_ScriptEvent(ent, "death", "");

		G_Script_ScriptEvent(&g_entities[other->client->flagParent], "trigger", "captured");

		ent->parent = tmp;

		// Removes itself
		ent->touch     = NULL;
		ent->nextthink = level.time + FRAMETIME;
		ent->think     = G_FreeEntity;
	} else if (ent->spawnflags & BLUE_FLAG && other->client->ps.powerups[PW_BLUEFLAG]) {

		if (ent->spawnflags & 4) {
			other->client->ps.powerups[PW_BLUEFLAG] = 0;
			other->client->speedScale               = 0;
		}

		tmp         = ent->parent;
		ent->parent = other;

		G_Script_ScriptEvent(ent, "death", "");

		G_Script_ScriptEvent(&g_entities[other->client->flagParent], "trigger", "captured");

		ent->parent = tmp;

		// Removes itself
		ent->touch     = NULL;
		ent->nextthink = level.time + FRAMETIME;
		ent->think     = G_FreeEntity;
	}
}
Exemplo n.º 11
0
void Touch_flagonly_multiple(gentity_t * ent, gentity_t * other, trace_t * trace)
{
	gentity_t      *tmp;

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

	if(ent->spawnflags & RED_FLAG && other->client->ps.powerups[PW_REDFLAG])
	{

		other->client->ps.powerups[PW_REDFLAG] = 0;
		other->client->speedScale = 0;

		AddScore(other, ent->accuracy);	// JPW NERVE set from map, defaults to 20
		//G_AddExperience( other, 2.f );

		tmp = ent->parent;
		ent->parent = other;

		G_Script_ScriptEvent(ent, "death", "");

		G_Script_ScriptEvent(&g_entities[other->client->flagParent], "trigger", "captured");
#ifdef OMNIBOT
		Bot_Util_SendTrigger(ent, NULL, va("Allies captured %s", ent->scriptName), "");
#endif

		ent->parent = tmp;
	}
	else if(ent->spawnflags & BLUE_FLAG && other->client->ps.powerups[PW_BLUEFLAG])
	{

		other->client->ps.powerups[PW_BLUEFLAG] = 0;
		other->client->speedScale = 0;

		AddScore(other, ent->accuracy);	// JPW NERVE set from map, defaults to 20

		//G_AddExperience( other, 2.f );

		tmp = ent->parent;
		ent->parent = other;

		G_Script_ScriptEvent(ent, "death", "");

		G_Script_ScriptEvent(&g_entities[other->client->flagParent], "trigger", "captured");
#ifdef OMNIBOT
		Bot_Util_SendTrigger(ent, NULL, va("Axis captured %s", ent->scriptName), "");
#endif

		ent->parent = tmp;
	}
}
Exemplo n.º 12
0
void checkpoint_touch(gentity_t *self, gentity_t *other, trace_t *trace) {
	// Nico, silent GCC
	(void)trace;

	if (self->count == (int)other->client->sess.sessionTeam) {
		return;
	}

	// Set controlling team
	self->count = other->client->sess.sessionTeam;

	// Set animation
	if (self->count == TEAM_AXIS) {
		if (self->s.frame == WCP_ANIM_NOFLAG) {
			self->s.frame = WCP_ANIM_RAISE_AXIS;
		} else if (self->s.frame == WCP_ANIM_AMERICAN_RAISED) {
			self->s.frame = WCP_ANIM_AMERICAN_TO_AXIS;
		} else {
			self->s.frame = WCP_ANIM_AXIS_RAISED;
		}
	} else {
		if (self->s.frame == WCP_ANIM_NOFLAG) {
			self->s.frame = WCP_ANIM_RAISE_AMERICAN;
		} else if (self->s.frame == WCP_ANIM_AXIS_RAISED) {
			self->s.frame = WCP_ANIM_AXIS_TO_AMERICAN;
		} else {
			self->s.frame = WCP_ANIM_AMERICAN_RAISED;
		}
	}

	self->parent = other;

	// Gordon: reset player disguise on touching flag
	// Run script trigger
	if (self->count == TEAM_AXIS) {
		self->health = 0;
		G_Script_ScriptEvent(self, "trigger", "axis_capture");
	} else {
		self->health = 10;
		G_Script_ScriptEvent(self, "trigger", "allied_capture");
	}

	// Play a sound
	G_AddEvent(self, EV_GENERAL_SOUND, self->soundPos1);

	// Don't allow touch again until animation is finished
	self->touch = NULL;

	self->think     = checkpoint_think;
	self->nextthink = level.time + 1000;
}
Exemplo n.º 13
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;

	G_Script_ScriptEvent(ent, "activate", NULL);

	if(ent->nextthink)
	{
		return;					// can't retrigger until the wait is over
	}

	G_UseTargets(ent, ent->activator);

	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;
	}
}
Exemplo n.º 14
0
/**
 * @brief Team_TouchOurFlag
 * @param[in] ent
 * @param[in] other
 * @param[in] team
 * @return
 */
int Team_TouchOurFlag(gentity_t *ent, gentity_t *other, int team)
{
	gclient_t *cl = other->client;

	if (ent->flags & FL_DROPPED_ITEM)
	{
		// hey, its not home.  return it by teleporting it back
		AddScore(other, WOLF_SECURE_OBJ_BONUS);

		if (cl->sess.sessionTeam == TEAM_AXIS)
		{
			if (level.gameManager)
			{
				G_Script_ScriptEvent(level.gameManager, "trigger", "axis_object_returned");
			}
			G_Script_ScriptEvent(&g_entities[ent->s.otherEntityNum], "trigger", "returned");
#ifdef FEATURE_OMNIBOT
			{
				const char *pName = ent->message ? ent->message : _GetEntityName(ent);
				Bot_Util_SendTrigger(ent, NULL, va("Axis have returned %s!", pName ? pName : ""), "returned");
			}
#endif
		}
		else
		{
			if (level.gameManager)
			{
				G_Script_ScriptEvent(level.gameManager, "trigger", "allied_object_returned");
			}
			G_Script_ScriptEvent(&g_entities[ent->s.otherEntityNum], "trigger", "returned");
#ifdef FEATURE_OMNIBOT
			{
				const char *pName = ent->message ? ent->message : _GetEntityName(ent);
				Bot_Util_SendTrigger(ent, NULL, va("Allies have returned %s!", pName ? pName : ""), "returned");
			}
#endif
		}

		//ResetFlag will remove this entity!  We must return zero
		Team_ReturnFlagSound(ent, team);
		Team_ResetFlag(ent);
		return 0;
	}

	// GT_WOLF doesn't support capturing the flag
	return 0;
}
Exemplo n.º 15
0
/*
===============
G_CallSpawn

Finds the spawn function for the entity and calls it,
returning qfalse if not found
===============
*/
qboolean G_CallSpawn( gentity_t *ent ) {
	spawn_t *s;
	gitem_t *item;
	int hash;

	if ( !ent->classname ) {
		G_Printf( "G_CallSpawn: NULL classname\n" );
		return qfalse;
	}

	if ( g_deathmatch.integer ) {
		if ( !strcmp( "func_explosive", ent->classname ) ) {
			return qfalse;
		}

		if ( !strcmp( "trigger_hurt", ent->classname ) ) {
			return qfalse;
		}

		// don't spawn the flags in cp
		if ( g_gametype.integer == 7 && !strcmp( "team_WOLF_checkpoint", ent->classname ) ) {
			return qfalse;
		}
	}

	// check item spawn functions
	for ( item = bg_itemlist + 1 ; item->classname ; item++ ) {
		if ( !strcmp( item->classname, ent->classname ) ) {
			// found it
			// DHM - Nerve :: allow flags in GTWOLF
			if ( item->giType == IT_TEAM && ( g_gametype.integer != GT_CTF && g_gametype.integer < GT_WOLF ) ) {
				return qfalse;
			}
			G_SpawnItem( ent, item );
			return qtrue;
		}
	}

	// check normal spawn functions
	hash = BG_StringHashValue( ent->classname );
	for ( s = spawns ; s->name ; s++ ) {
		if ( s->hash == hash ) {
			// found it
			s->spawn( ent );

			// RF, entity scripting
			if ( ent->s.number >= MAX_CLIENTS && ent->scriptName ) {
				G_Script_ScriptParse( ent );
				G_Script_ScriptEvent( ent, "spawn", "" );
			}

			return qtrue;
		}
	}
	G_Printf( "%s doesn't have a spawn function\n", ent->classname );
	return qfalse;
}
Exemplo n.º 16
0
void checkpoint_touch( gentity_t *self, gentity_t *other, trace_t *trace ) {

	if ( self->count == other->client->sess.sessionTeam ) {
		return;
	}

	// Set controlling team
	self->count = other->client->sess.sessionTeam;

	// Set animation
	if ( self->count == TEAM_RED ) {
		if ( self->s.frame == WCP_ANIM_NOFLAG ) {
			self->s.frame = WCP_ANIM_RAISE_NAZI;
		} else if ( self->s.frame == WCP_ANIM_AMERICAN_RAISED ) {
			self->s.frame = WCP_ANIM_AMERICAN_TO_NAZI;
		} else {
			self->s.frame = WCP_ANIM_NAZI_RAISED;
		}
	} else {
		if ( self->s.frame == WCP_ANIM_NOFLAG ) {
			self->s.frame = WCP_ANIM_RAISE_AMERICAN;
		} else if ( self->s.frame == WCP_ANIM_NAZI_RAISED ) {
			self->s.frame = WCP_ANIM_NAZI_TO_AMERICAN;
		} else {
			self->s.frame = WCP_ANIM_AMERICAN_RAISED;
		}
	}

	// Run script trigger
	if ( self->count == TEAM_RED ) {
		G_Script_ScriptEvent( self, "trigger", "axis_capture" );
	} else {
		G_Script_ScriptEvent( self, "trigger", "allied_capture" );
	}

	// Play a sound
	G_AddEvent( self, EV_GENERAL_SOUND, self->soundPos1 );

	// Don't allow touch again until animation is finished
	self->touch = NULL;

	self->think = checkpoint_think;
	self->nextthink = level.time + 1000;
}
Exemplo n.º 17
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->numPlayers > 1)
	{
		gentity_t *tnt;   // temp ent for counting players
		int       i;
		int       entList[MAX_GENTITIES];   // list of entities
		int       cnt     = trap_EntitiesInBox(ent->r.mins, ent->r.maxs, entList, MAX_GENTITIES);
		int       players = 0;   // number of ents in trigger

		for (i = 0; i < cnt; i++)
		{
			tnt = &g_entities[entList[i]];

			if (tnt->client)
			{
				players++;
			}
		}

		// not enough players, return
		if (players < ent->numPlayers)
		{
			return;
		}
	}

	G_Script_ScriptEvent(ent, "activate", NULL);

	if (ent->nextthink)
	{
		return;     // can't retrigger until the wait is over
	}

	G_UseTargets(ent, ent->activator);

	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;
	}
}
Exemplo n.º 18
0
void script_mover_die(gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int damage, int mod) {
	G_Script_ScriptEvent( self, "death", "" );

	if (!(self->spawnflags & 8)) {
		G_FreeEntity( self );
	}

	if( self->tankLink ) {
		G_LeaveTank( self->tankLink, qtrue );
	}

	self->die = NULL;
}
Exemplo n.º 19
0
/*
===============
G_CallSpawn

Finds the spawn function for the entity and calls it,
returning qfalse if not found
===============
*/
qboolean G_CallSpawn(gentity_t *ent) {
	spawn_t *s;
	gitem_t *item;

	if (!ent->classname) {
		G_DPrintf("G_CallSpawn: NULL classname\n");
		return qfalse;
	}

	// check item spawn functions
	for (item = bg_itemlist + 1 ; item->classname ; ++item) {
		if (!strcmp(item->classname, ent->classname)) {
			// found it
			G_SpawnItem(ent, item);

			G_Script_ScriptParse(ent);
			G_Script_ScriptEvent(ent, "spawn", "");
			return qtrue;
		}
	}

	// check normal spawn functions
	for (s = spawns ; s->name ; ++s) {
		if (!strcmp(s->name, ent->classname)) {
			// found it
			s->spawn(ent);

			// RF, entity scripting
			if (ent->scriptName) {
				G_Script_ScriptParse(ent);
				G_Script_ScriptEvent(ent, "spawn", "");
			}

			return qtrue;
		}
	}
	G_DPrintf("%s doesn't have a spawn function\n", ent->classname);
	return qfalse;
}
Exemplo n.º 20
0
void Touch_flagonly_multiple(gentity_t *ent, gentity_t *other, trace_t *trace) {
	gentity_t *tmp;

	// Nico, silent GCC
	(void)trace;

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

	if (ent->spawnflags & RED_FLAG && other->client->ps.powerups[PW_REDFLAG]) {

		other->client->ps.powerups[PW_REDFLAG] = 0;
		other->client->speedScale              = 0;

		tmp         = ent->parent;
		ent->parent = other;

		G_Script_ScriptEvent(ent, "death", "");

		G_Script_ScriptEvent(&g_entities[other->client->flagParent], "trigger", "captured");

		ent->parent = tmp;
	} else if (ent->spawnflags & BLUE_FLAG && other->client->ps.powerups[PW_BLUEFLAG]) {

		other->client->ps.powerups[PW_BLUEFLAG] = 0;
		other->client->speedScale               = 0;

		tmp         = ent->parent;
		ent->parent = other;

		G_Script_ScriptEvent(ent, "death", "");

		G_Script_ScriptEvent(&g_entities[other->client->flagParent], "trigger", "captured");

		ent->parent = tmp;
	}
}
Exemplo n.º 21
0
void script_mover_use(gentity_t *ent, gentity_t *other, gentity_t *activator) {
	if(ent->spawnflags & 8) {
		if(ent->count) {
			ent->health = ent->count;
			ent->s.dl_intensity = ent->health;

			G_Script_ScriptEvent( ent, "rebirth", "" );
			
			ent->die = script_mover_die;
		}
	} else {
		script_mover_spawn(ent);
	}
}
Exemplo n.º 22
0
/*
QUAKED target_script_trigger (1 .7 .2) (-8 -8 -8) (8 8 8)
must have an aiName
must have a target

when used it will fire its targets
*/
void target_script_trigger_use(gentity_t *ent, gentity_t *other, gentity_t *activator)
{
	qboolean found = qfalse;
	// for all entities/bots with this ainame
	gentity_t *trent = NULL;

	// Are we using ainame to find another ent instead of using scriptname for this one?
	if (ent->aiName)
	{
		// Find the first entity with this name
		trent = G_Find(trent, FOFS(scriptName), ent->aiName);

		// Was there one?
		if (trent)
		{
			// We found it
			found = qtrue;

			// Play the script
			G_Script_ScriptEvent(trent, "trigger", ent->target);

		} // if (trent)...

	} // if (ent->aiName)...

	// Use the old method if we didn't find an entity with the ainame
	if (!found)
	{
		if (ent->scriptName)
		{
			G_Script_ScriptEvent(ent, "trigger", ent->target);
		}
	}

	G_UseTargets(ent, other);
}
Exemplo n.º 23
0
/*QUAKED target_script_trigger (1 .7 .2) (-8 -8 -8) (8 8 8)
must have an aiName
must have a target

when used it will fire its targets 
*/
void target_script_trigger_use (gentity_t *ent, gentity_t *other, gentity_t *activator )
{
	gentity_t	*player;

	if (ent->aiName) {
		player = AICast_FindEntityForName("player");
		if (player)
			AICast_ScriptEvent( AICast_GetCastState(player->s.number), "trigger", ent->target );
	}

	// DHM - Nerve :: In multiplayer, we use the brush scripting only
	if ( g_gametype.integer >= GT_WOLF && ent->scriptName ) {
		G_Script_ScriptEvent( ent, "trigger", ent->target );
	}

	G_UseTargets ( ent, other);	

}
Exemplo n.º 24
0
/*
=================
G_ScriptAction_Trigger

  syntax: trigger <aiName/scriptName> <trigger>

  Calls the specified trigger for the given ai character or script entity
=================
*/
qboolean G_ScriptAction_Trigger( gentity_t *ent, char *params )
{
	gentity_t *trent;
	char *pString, name[MAX_QPATH], trigger[MAX_QPATH], *token;
	int oldId;

	// get the cast name
	pString = params;
	token = COM_ParseExt( &pString, qfalse );
	Q_strncpyz( name, token, sizeof(name) );
	if (!name[0])
	{
		G_Error( "G_Scripting: trigger must have a name and an identifier\n" );
	}

	token = COM_ParseExt( &pString, qfalse );
	Q_strncpyz( trigger, token, sizeof(trigger) );
	if (!trigger[0])
	{
		G_Error( "G_Scripting: trigger must have a name and an identifier\n" );
	}

//	trent = AICast_FindEntityForName( name );
		trent = NULL;
	if (trent)
	{	// we are triggering an AI
		//oldId = trent->scriptStatus.scriptId;
//		AICast_ScriptEvent( AICast_GetCastState( trent->s.number ), "trigger", trigger );
		return qtrue;
	}

	// look for an entity
	trent = G_Find( &g_entities[MAX_CLIENTS], FOFS(scriptName), name );
	if (trent) {
		oldId = trent->scriptStatus.scriptId;
		G_Script_ScriptEvent( trent, "trigger", trigger );
		// if the script changed, return false so we don't muck with it's variables
		return ((trent != ent) || (oldId == trent->scriptStatus.scriptId));
	}

	G_Error( "G_Scripting: trigger has unknown name: %s\n", name );
	return qfalse;	// shutup the compiler
}
Exemplo n.º 25
0
void script_mover_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int damage, int mod ) {
	if ( self->spawnflags & 4 ) {
		switch ( mod ) {
		case MOD_GRENADE:
		case MOD_GRENADE_SPLASH:
		case MOD_ROCKET:
		case MOD_ROCKET_SPLASH:
		case MOD_AIRSTRIKE:
			break;
		default:    // no death from this weapon
			self->health += damage;
			return;
		}
	}

	G_Script_ScriptEvent( self, "death", "" );
	self->die = NULL;

	trap_UnlinkEntity( self );
	G_FreeEntity( self );
}
Exemplo n.º 26
0
/*QUAKED target_script_trigger (1 .7 .2) (-8 -8 -8) (8 8 8)
must have an aiName
must have a target

when used it will fire its targets 
*/
void target_script_trigger_use (gentity_t *ent, gentity_t *other, gentity_t *activator )
{
//	gentity_t	*player;

	if (ent->aiName) {
//		player = AICast_FindEntityForName("player");
//		if (player)
//			AICast_ScriptEvent( AICast_GetCastState(player->s.number), "trigger", ent->target );
	}

	// DHM - Nerve :: In multiplayer, we use the brush scripting only
	if ( g_gametype.integer >= GT_WOLF && ent->scriptName ) {
#ifdef OMNIBOT
		Bot_Util_SendTrigger(ent, NULL, ent->scriptName, ent->target );
#endif 
		G_Script_ScriptEvent( ent, "trigger", ent->target );
	}

	G_UseTargets ( ent, other);	

}
Exemplo n.º 27
0
/*
===============
G_CallSpawn

Finds the spawn function for the entity and calls it,
returning qfalse if not found
===============
*/
qboolean G_CallSpawn( gentity_t *ent ) {
	spawn_t *s;
	gitem_t *item;

	if ( !ent->classname ) {
		G_Printf( "G_CallSpawn: NULL classname\n" );
		return qfalse;
	}

	// check item spawn functions
	for ( item = bg_itemlist + 1 ; item->classname ; item++ ) {
		if ( !strcmp( item->classname, ent->classname ) ) {
			// found it
			// DHM - Nerve :: allow flags in GTWOLF
			if ( item->giType == IT_TEAM && ( g_gametype.integer != GT_CTF && g_gametype.integer < GT_WOLF ) ) {
				return qfalse;
			}
			G_SpawnItem( ent, item );
			return qtrue;
		}
	}

	// check normal spawn functions
	for ( s = spawns ; s->name ; s++ ) {
		if ( !strcmp( s->name, ent->classname ) ) {
			// found it
			s->spawn( ent );

			// RF, entity scripting
			if ( ent->s.number >= MAX_CLIENTS && ent->scriptName ) {
				G_Script_ScriptParse( ent );
				G_Script_ScriptEvent( ent, "spawn", "" );
			}

			return qtrue;
		}
	}
	G_Printf( "%s doesn't have a spawn function\n", ent->classname );
	return qfalse;
}
Exemplo n.º 28
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
// Nico, note: ent->random is effect less on this entity
void multi_trigger(gentity_t *ent, gentity_t *activator) {
	ent->activator = activator;
	G_Script_ScriptEvent(ent, "activate", NULL);

	// Nico, #todo: handle case when ent->triggerTime[activator->client->ps.clientNum] = 0
	if (ent->wait > 0) {
		if (activator->client && ent->triggerTime[activator->client->ps.clientNum] + ent->wait * 1000 > level.time) {
			// Client has to wait before triggering this entity!
			return;
		}
		G_UseTargets(ent, ent->activator);
		if (activator->client) {
			ent->triggerTime[activator->client->ps.clientNum] = level.time;
		}
	} else {
		// Nico, #todo: update ent->triggerTime[activator->client->ps.clientNum]???
		G_UseTargets(ent, ent->activator);
		// 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;
	}
}
Exemplo n.º 29
0
void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker,
			   vec3_t dir, vec3_t point, int damage, int dflags, int mod ) {
	gclient_t   *client;
	int take;
	int save;
	int asave;
	int knockback;

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

	// the intermission has allready been qualified for, so don't
	// allow any extra scoring
	if ( level.intermissionQueued || g_gamestate.integer != GS_PLAYING ) {
		return;
	}

	if ( !inflictor ) {
		inflictor = &g_entities[ENTITYNUM_WORLD];
	}
	if ( !attacker ) {
		attacker = &g_entities[ENTITYNUM_WORLD];
	}

// JPW NERVE
	if ( ( targ->waterlevel >= 3 ) && ( mod == MOD_FLAMETHROWER ) ) {
		return;
	}
// jpw

	// shootable doors / buttons don't actually have any health
	if ( targ->s.eType == ET_MOVER && !( targ->aiName ) && !( targ->isProp ) && !targ->scriptName ) {
		if ( targ->use && targ->moverState == MOVER_POS1 ) {
			targ->use( targ, inflictor, attacker );
		}
		return;
	}

	if ( targ->s.eType == ET_MOVER && targ->aiName && !( targ->isProp ) && !targ->scriptName ) {
		switch ( mod ) {
		case MOD_GRENADE:
		case MOD_GRENADE_SPLASH:
		case MOD_ROCKET:
		case MOD_ROCKET_SPLASH:
			break;
		default:
			return; // no damage from other weapons
		}
	} else if ( targ->s.eType == ET_EXPLOSIVE )   {
		// 32 Explosive
		// 64 Dynamite only
		if ( ( targ->spawnflags & 32 ) || ( targ->spawnflags & 64 ) ) {
			switch ( mod ) {
			case MOD_GRENADE:
			case MOD_GRENADE_SPLASH:
			case MOD_ROCKET:
			case MOD_ROCKET_SPLASH:
			case MOD_AIRSTRIKE:
			case MOD_GRENADE_PINEAPPLE:
			case MOD_MORTAR:
			case MOD_MORTAR_SPLASH:
			case MOD_EXPLOSIVE:
				if ( targ->spawnflags & 64 ) {
					return;
				}

				break;

			case MOD_DYNAMITE:
			case MOD_DYNAMITE_SPLASH:
				break;

			default:
				return;
			}
		}
	}

	client = targ->client;

	if ( client ) {
		if ( client->noclip ) {
			return;
		}
	}

	if ( !dir ) {
		dflags |= DAMAGE_NO_KNOCKBACK;
	} else {
		VectorNormalize( dir );
	}

	knockback = damage;
	if ( knockback > 200 ) {
		knockback = 200;
	}
	if ( targ->flags & FL_NO_KNOCKBACK ) {
		knockback = 0;
	}
	if ( dflags & DAMAGE_NO_KNOCKBACK ) {
		knockback = 0;
	}

	// figure momentum add, even if the damage won't be taken
	if ( knockback && targ->client && ( g_friendlyFire.integer || !OnSameTeam( targ, attacker ) ) ) {
		vec3_t kvel;
		float mass;

		mass = 200;

		if ( mod == MOD_LIGHTNING && !( ( level.time + targ->s.number * 50 ) % 400 ) ) {
			knockback = 60;
			dir[2] = 0.3;
		}

		VectorScale( dir, g_knockback.value * (float)knockback / mass, kvel );
		VectorAdd( targ->client->ps.velocity, kvel, targ->client->ps.velocity );

		if ( targ == attacker && !(  mod != MOD_ROCKET &&
									 mod != MOD_ROCKET_SPLASH &&
									 mod != MOD_GRENADE &&
									 mod != MOD_GRENADE_SPLASH &&
									 mod != MOD_DYNAMITE ) ) {
			targ->client->ps.velocity[2] *= 0.25;
		}

		// set the timer so that the other client can't cancel
		// out the movement immediately
		if ( !targ->client->ps.pm_time ) {
			int t;

			t = knockback * 2;
			if ( t < 50 ) {
				t = 50;
			}
			if ( t > 200 ) {
				t = 200;
			}
			targ->client->ps.pm_time = t;
			targ->client->ps.pm_flags |= PMF_TIME_KNOCKBACK;
		}
	}

	// check for completely getting out of the damage
	if ( !( dflags & DAMAGE_NO_PROTECTION ) ) {

		// if TF_NO_FRIENDLY_FIRE is set, don't do damage to the target
		// if the attacker was on the same team
		if ( targ != attacker && OnSameTeam( targ, attacker )  ) {
			if ( !g_friendlyFire.integer ) {
				return;
			}
		}

		// check for godmode
		if ( targ->flags & FL_GODMODE ) {
			return;
		}

		// RF, warzombie defense position is basically godmode for the time being
		if ( targ->flags & FL_DEFENSE_GUARD ) {
			return;
		}

		// check for invulnerability // (SA) moved from below so DAMAGE_NO_PROTECTION will still work
		if ( client && client->ps.powerups[PW_INVULNERABLE] ) { //----(SA)	added
			return;
		}

	}

	// battlesuit protects from all radius damage (but takes knockback)
	// and protects 50% against all damage
	if ( client && client->ps.powerups[PW_BATTLESUIT] ) {
		G_AddEvent( targ, EV_POWERUP_BATTLESUIT, 0 );
		if ( dflags & DAMAGE_RADIUS ) {
			return;
		}
		damage *= 0.5;
	}

	// add to the attacker's hit counter
	if ( attacker->client && targ != attacker && targ->health > 0 ) {
		if ( OnSameTeam( targ, attacker ) ) {
			attacker->client->ps.persistant[PERS_HITS] -= damage;
		} else {
			attacker->client->ps.persistant[PERS_HITS] += damage;
		}
	}

	if ( damage < 1 ) {
		damage = 1;
	}
	take = damage;
	save = 0;

	// save some from armor
	asave = CheckArmor( targ, take, dflags );
	take -= asave;

	if ( IsHeadShot( targ, qfalse, dir, point, mod ) ) {

		if ( take * 2 < 50 ) { // head shots, all weapons, do minimum 50 points damage
			take = 50;
		} else {
			take *= 2; // sniper rifles can do full-kill (and knock into limbo)

		}
		if ( !( targ->client->ps.eFlags & EF_HEADSHOT ) ) {  // only toss hat on first headshot
			G_AddEvent( targ, EV_LOSE_HAT, DirToByte( dir ) );
		}

		targ->client->ps.eFlags |= EF_HEADSHOT;
	}

	if ( g_debugDamage.integer ) {
		G_Printf( "client:%i health:%i damage:%i armor:%i\n", targ->s.number,
				  targ->health, take, asave );
	}

	// add to the damage inflicted on a player this frame
	// the total will be turned into screen blends and view angle kicks
	// at the end of the frame
	if ( client ) {
		if ( attacker ) {
			client->ps.persistant[PERS_ATTACKER] = attacker->s.number;
		} else {
			client->ps.persistant[PERS_ATTACKER] = ENTITYNUM_WORLD;
		}
		client->damage_armor += asave;
		client->damage_blood += take;
		client->damage_knockback += knockback;

		if ( dir ) {
			VectorCopy( dir, client->damage_from );
			client->damage_fromWorld = qfalse;
		} else {
			VectorCopy( targ->r.currentOrigin, client->damage_from );
			client->damage_fromWorld = qtrue;
		}
	}

	// See if it's the player hurting the emeny flag carrier
	Team_CheckHurtCarrier( targ, attacker );

	if ( targ->client ) {
		// set the last client who damaged the target
		targ->client->lasthurt_client = attacker->s.number;
		targ->client->lasthurt_mod = mod;
	}

	// do the damage
	if ( take ) {
		targ->health = targ->health - take;

		// Ridah, can't gib with bullet weapons (except VENOM)
		if ( mod != MOD_VENOM && attacker == inflictor && targ->health <= GIB_HEALTH ) {
			if ( targ->aiCharacter != AICHAR_ZOMBIE ) { // zombie needs to be able to gib so we can kill him (although he doesn't actually GIB, he just dies)
				targ->health = GIB_HEALTH + 1;
			}
		}

// JPW NERVE overcome previous chunk of code for making grenades work again
		if ( ( g_gametype.integer != GT_SINGLE_PLAYER ) && ( take > 190 ) ) { // 190 is greater than 2x mauser headshot, so headshots don't gib
			targ->health = GIB_HEALTH - 1;
		}
// jpw
		//G_Printf("health at: %d\n", targ->health);
		if ( targ->health <= 0 ) {
			if ( client ) {
				targ->flags |= FL_NO_KNOCKBACK;
// JPW NERVE -- repeated shooting sends to limbo
				if ( g_gametype.integer >= GT_WOLF ) {
					if ( ( targ->health < FORCE_LIMBO_HEALTH ) && ( targ->health > GIB_HEALTH ) && ( !( targ->client->ps.pm_flags & PMF_LIMBO ) ) ) {
						limbo( targ, qtrue );
					}
				}
// jpw
			}

			if ( targ->health < -999 ) {
				targ->health = -999;
			}

			targ->enemy = attacker;
			if ( targ->die ) { // Ridah, mg42 doesn't have die func (FIXME)
				targ->die( targ, inflictor, attacker, take, mod );
			}

			// if we freed ourselves in death function
			if ( !targ->inuse ) {
				return;
			}

			// RF, entity scripting
			if ( targ->s.number >= MAX_CLIENTS && targ->health <= 0 ) { // might have revived itself in death function
				G_Script_ScriptEvent( targ, "death", "" );
			}

		} else if ( targ->pain ) {
			if ( dir ) {  // Ridah, had to add this to fix NULL dir crash
				VectorCopy( dir, targ->rotate );
				VectorCopy( point, targ->pos3 ); // this will pass loc of hit
			} else {
				VectorClear( targ->rotate );
				VectorClear( targ->pos3 );
			}

			targ->pain( targ, attacker, take, point );

			// RF, entity scripting
			if ( targ->s.number >= MAX_CLIENTS ) {
				G_Script_ScriptEvent( targ, "pain", va( "%d %d", targ->health, targ->health + take ) );
			}
		}

		//G_ArmorDamage(targ);	//----(SA)	moved out to separate routine

		// Ridah, this needs to be done last, incase the health is altered in one of the event calls
		if ( targ->client ) {
			targ->client->ps.stats[STAT_HEALTH] = targ->health;
		}
	}

}
Exemplo n.º 30
0
void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker,  vec3_t dir, vec3_t point, int damage, int dflags, int mod ) {
	gclient_t	*client;
	int			take;
	int			save;
	int			knockback;
	qboolean	headShot;
	qboolean	wasAlive;
	hitRegion_t	hr = HR_NUM_HITREGIONS;

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

#ifdef SAVEGAME_SUPPORT
	if( g_gametype.integer == GT_SINGLE_PLAYER && ( g_reloading.integer || saveGamePending ) )
		return;
#endif // SAVEGAME_SUPPORT

//	trap_SendServerCommand( -1, va("print \"%i\n\"\n", targ->health) );

	// the intermission has allready been qualified for, so don't
	// allow any extra scoring
	if ( level.intermissionQueued || (g_gamestate.integer != GS_PLAYING && match_warmupDamage.integer == 0)) {
		return;
	}

	if ( !inflictor ) {
		inflictor = &g_entities[ENTITYNUM_WORLD];
	}
	if ( !attacker ) {
		attacker = &g_entities[ENTITYNUM_WORLD];
	}

	// Arnout: invisible entities can't be damaged
	if( targ->entstate == STATE_INVISIBLE ||
		targ->entstate == STATE_UNDERCONSTRUCTION ) {
		return;
	}

	// xkan, 12/23/2002 - was the bot alive before applying any damage?
	wasAlive = (targ->health > 0);

	// Arnout: combatstate
	if( targ->client && attacker && attacker->client && attacker != targ ) {
		/*vec_t dist = -1.f;

		if( targ->client->combatState < COMBATSTATE_HOT ) {
			vec3_t shotvec;

			VectorSubtract( targ->r.currentOrigin, attacker->r.currentOrigin, shotvec );
			dist = VectorLengthSquared( shotvec );

			if( dist < Square(1500.f) && targ->client->combatState == COMBATSTATE_WARM )
				targ->client->combatState = COMBATSTATE_HOT;
		}

		if( attacker->client->combatState < COMBATSTATE_HOT ) {
			if( dist < 0.f ) {
				vec3_t shotvec;

				VectorSubtract( targ->r.currentOrigin, attacker->r.currentOrigin, shotvec );
				dist = VectorLengthSquared( shotvec );
			}

			if( dist > Square(1500.f) )
				attacker->client->combatState = COMBATSTATE_WARM;
			else if( attacker->client->combatState == COMBATSTATE_WARM )
				attacker->client->combatState = COMBATSTATE_HOT;
		}*/

		if( g_gamestate.integer == GS_PLAYING ) {
			if( !OnSameTeam( attacker, targ ) ) {
				targ->client->combatState |= (1<<COMBATSTATE_DAMAGERECEIVED);
				attacker->client->combatState |= (1<<COMBATSTATE_DAMAGEDEALT);
			}
		}
	}

// JPW NERVE
	if ((targ->waterlevel >= 3) && (mod == MOD_FLAMETHROWER))
		return;
// jpw

	// shootable doors / buttons don't actually have any health
	if ( targ->s.eType == ET_MOVER && !(targ->isProp) && !targ->scriptName) {
		if ( targ->use && targ->moverState == MOVER_POS1 ) {
			G_UseEntity( targ, inflictor, attacker );
		}
		return;
	}


	// TAT 11/22/2002
	//		In the old code, this check wasn't done for props, so I put that check back in to make props_statue properly work	
	// 4 means destructible
	if ( targ->s.eType == ET_MOVER && (targ->spawnflags & 4) && !targ->isProp ) 
	{
		/*switch (mod) {
		case MOD_GRENADE:
		case MOD_GRENADE_LAUNCHER:
		case MOD_ROCKET:
		case MOD_AIRSTRIKE:
		case MOD_ARTY:
		case MOD_GRENADE_PINEAPPLE:
		case MOD_MAPMORTAR:
		case MOD_EXPLOSIVE:
		case MOD_DYNAMITE:
		case MOD_LANDMINE:
		case MOD_GPG40:
		case MOD_M7:
		case MOD_TELEFRAG:
		case MOD_PANZERFAUST:
		case MOD_SATCHEL:
			break;
		default:
			return;	// no damage from other weapons
		}*/
		if( !G_WeaponIsExplosive( mod ) ) {
			return;
		}

		// check for team
		if( G_GetTeamFromEntity( inflictor ) == G_GetTeamFromEntity( targ ) ) {
			return;
		}
	} else if ( targ->s.eType == ET_EXPLOSIVE ) {
		/*// 32 Explosive
		// 64 Dynamite only
		// 256 Airstrike/artillery only
		// 512 Satchel only
		if ((targ->spawnflags & 32) || (targ->spawnflags & 64) || (targ->spawnflags & 256) || (targ->spawnflags & 512))
		{
			switch (mod) {
			case MOD_GRENADE:
			case MOD_GRENADE_LAUNCHER:
			case MOD_ROCKET:
			case MOD_GRENADE_PINEAPPLE:
			case MOD_MAPMORTAR:
			case MOD_EXPLOSIVE:
			case MOD_LANDMINE:
			case MOD_GPG40:
			case MOD_M7:
				if( !(targ->spawnflags & 32) )
					return;
				break;
			case MOD_SATCHEL:
				if( !(targ->spawnflags & 512) )
					return;
				break;
			case MOD_ARTY:
			case MOD_AIRSTRIKE:
				if( !(targ->spawnflags & 256) )
					return;
				break;
			case MOD_DYNAMITE:
				if( !(targ->spawnflags & 64) )
					return;
				break;
			default: 
				return;
			}

			// check for team
			if( targ->s.teamNum == inflictor->s.teamNum ) {
				return;
			}
		}*/
		
		if( targ->parent && G_GetWeaponClassForMOD( mod ) == 2 ) {
			return;
		}

		// check for team
//		if( G_GetWeaponClassForMOD( mod ) != -1 && targ->s.teamNum == inflictor->s.teamNum ) {
//			return;
//		}
		if( G_GetTeamFromEntity( inflictor ) == G_GetTeamFromEntity( targ ) ) {
			return;
		}

		if( G_GetWeaponClassForMOD( mod ) < targ->constructibleStats.weaponclass ) {
			return;
		}
	}
	else if ( targ->s.eType == ET_MISSILE && targ->methodOfDeath == MOD_LANDMINE ) {
		if( targ->s.modelindex2 ) {
			if( G_WeaponIsExplosive( mod ) ) {
				mapEntityData_t	*mEnt;

				if((mEnt = G_FindMapEntityData(&mapEntityData[0], targ-g_entities)) != NULL) {
					G_FreeMapEntityData( &mapEntityData[0], mEnt );
				}

				if((mEnt = G_FindMapEntityData(&mapEntityData[1], targ-g_entities)) != NULL) {
					G_FreeMapEntityData( &mapEntityData[1], mEnt );
				}

				if( attacker && attacker->client ) {
					AddScore( attacker, 1 );
					//G_AddExperience( attacker, 1.f );
				}

				G_ExplodeMissile(targ);
			}
		}
		return;
	} else if ( targ->s.eType == ET_CONSTRUCTIBLE ) {

		if( G_GetTeamFromEntity( inflictor ) == G_GetTeamFromEntity( targ ) ) {
			return;
		}

		if( G_GetWeaponClassForMOD( mod ) < targ->constructibleStats.weaponclass ) {
			return;
		}
	}

	client = targ->client;

	if ( client ) {
		if ( client->noclip || client->ps.powerups[PW_INVULNERABLE] ) {
			return;
		}
	}

	// check for godmode
	if ( targ->flags & FL_GODMODE ) {
		return;
	}

	if ( !dir ) {
		dflags |= DAMAGE_NO_KNOCKBACK;
	} else {
		VectorNormalize(dir);
	}

	knockback = damage;
	if ( knockback > 200 ) {
		knockback = 200;
	}
	if ( targ->flags & FL_NO_KNOCKBACK ) {
		knockback = 0;
	}
	if ( dflags & DAMAGE_NO_KNOCKBACK ) {
		knockback = 0;
	} else if( dflags & DAMAGE_HALF_KNOCKBACK ) {
		knockback *= 0.5f;
	}
	
	// ydnar: set weapons means less knockback
	if( client && (client->ps.weapon == WP_MORTAR_SET || client->ps.weapon == WP_MOBILE_MG42_SET) )
		knockback *= 0.5;

	if( targ->client && g_friendlyFire.integer && OnSameTeam(targ, attacker) ) {
		knockback = 0;
	}
	
	// figure momentum add, even if the damage won't be taken
	if ( knockback && targ->client ) {
		vec3_t	kvel;
		float	mass;

		mass = 200;

		VectorScale (dir, g_knockback.value * (float)knockback / mass, kvel);
		VectorAdd (targ->client->ps.velocity, kvel, targ->client->ps.velocity);

		/*if( mod == MOD_GRENADE ||
			mod == MOD_GRENADE_LAUNCHER ||
			mod == MOD_DYNAMITE ||
			mod == MOD_GPG40 ||
			mod == MOD_M7 ||
 			mod == MOD_LANDMINE ) {
			targ->client->ps.velocity[2] *= 2.f;				// gimme air baby!
			targ->client->ps.groundEntityNum = ENTITYNUM_NONE;	// flying high!
		} else if( mod == MOD_ROCKET ) {
			targ->client->ps.velocity[2] *= .75f;				// but not to the moon please!
			targ->client->ps.groundEntityNum = ENTITYNUM_NONE;	// flying high!
		}*/

		if (targ == attacker && !(	mod != MOD_ROCKET &&
									mod != MOD_GRENADE &&
									mod != MOD_GRENADE_LAUNCHER &&
									mod != MOD_DYNAMITE
									&& mod != MOD_GPG40
									&& mod != MOD_M7
									&& mod != MOD_LANDMINE
									))
		{
			targ->client->ps.velocity[2] *= 0.25;
		}

		// set the timer so that the other client can't cancel
		// out the movement immediately
		if ( !targ->client->ps.pm_time ) {
			int		t;

			t = knockback * 2;
			if ( t < 50 ) {
				t = 50;
			}
			if ( t > 200 ) {
				t = 200;
			}
			targ->client->ps.pm_time = t;
			targ->client->ps.pm_flags |= PMF_TIME_KNOCKBACK;
		}
	}

	// check for completely getting out of the damage
	if ( !(dflags & DAMAGE_NO_PROTECTION) ) {

		// if TF_NO_FRIENDLY_FIRE is set, don't do damage to the target
		// if the attacker was on the same team
		if ( targ != attacker && OnSameTeam (targ, attacker)  ) {
			if ( (g_gamestate.integer != GS_PLAYING && match_warmupDamage.integer == 1)) {
				return;
			}
			else if (!g_friendlyFire.integer)
			{
				return;
			}
		}
	}

	// add to the attacker's hit counter
	if ( attacker->client && targ != attacker && targ->health > 0 ) {
		if ( OnSameTeam( targ, attacker ) ) {
			attacker->client->ps.persistant[PERS_HITS] -= damage;
		} else {
			attacker->client->ps.persistant[PERS_HITS] += damage;
		}
	}

	if ( damage < 1 ) {
		damage = 1;
	}
	take = damage;
	save = 0;

	// adrenaline junkie!
	if( targ->client && targ->client->ps.powerups[PW_ADRENALINE] ) {
		take *= .5f;
	}

	// save some from flak jacket
	if( targ->client && targ->client->sess.skill[SK_EXPLOSIVES_AND_CONSTRUCTION] >= 4 && targ->client->sess.playerType == PC_ENGINEER ) {
		if( mod == MOD_GRENADE ||
			mod == MOD_GRENADE_LAUNCHER ||
			mod == MOD_ROCKET ||
			mod == MOD_GRENADE_PINEAPPLE ||
			mod == MOD_MAPMORTAR ||
			mod == MOD_MAPMORTAR_SPLASH || 
			mod == MOD_EXPLOSIVE ||
			mod == MOD_LANDMINE ||
			mod == MOD_GPG40 ||
			mod == MOD_M7 ||
			mod == MOD_SATCHEL ||
			mod == MOD_ARTY ||
			mod == MOD_AIRSTRIKE ||
			mod == MOD_DYNAMITE ||
			mod == MOD_MORTAR ||
			mod == MOD_PANZERFAUST ||
			mod == MOD_MAPMORTAR ) {
			take -= take * .5f;
		}
	}

	headShot = IsHeadShot(targ, dir, point, mod);
	if ( headShot ) {
		if( take * 2 < 50 ) // head shots, all weapons, do minimum 50 points damage
			take = 50;
		else
			take *= 2; // sniper rifles can do full-kill (and knock into limbo)

		if( dflags & DAMAGE_DISTANCEFALLOFF ) {
			vec_t dist;
			vec3_t shotvec;

			VectorSubtract( point, muzzleTrace, shotvec );
			dist = VectorLength( shotvec );

			if( dist > 1500.f ) {
				if( dist > 2500.f ) {
					take *= 0.2f;
				} else {
					float scale = 1.f - 0.2f * (1000.f / (dist - 1000.f));

					take *= scale;
				}
			}
		}

		if( !(targ->client->ps.eFlags & EF_HEADSHOT) ) {	// only toss hat on first headshot
			G_AddEvent( targ, EV_LOSE_HAT, DirToByte(dir) );

			if( mod != MOD_K43_SCOPE &&
				mod != MOD_GARAND_SCOPE ) {
				take *= .8f;	// helmet gives us some protection
			}
		}

		targ->client->ps.eFlags |= EF_HEADSHOT;

		// OSP - Record the headshot
		if(client && attacker && attacker->client
#ifndef DEBUG_STATS
		  && attacker->client->sess.sessionTeam != targ->client->sess.sessionTeam
#endif
		  ) {
			G_addStatsHeadShot(attacker, mod);
		}

		if( g_debugBullets.integer ) {
			trap_SendServerCommand( attacker-g_entities, "print \"Head Shot\n\"\n");
		}
		G_LogRegionHit( attacker, HR_HEAD );
		hr = HR_HEAD;
	} else if ( IsLegShot(targ, dir, point, mod) ) {
		G_LogRegionHit( attacker, HR_LEGS );
		hr = HR_LEGS;
		if( g_debugBullets.integer ) {
			trap_SendServerCommand( attacker-g_entities, "print \"Leg Shot\n\"\n");
		}
	} else if ( IsArmShot(targ, attacker, point, mod) ) {
		G_LogRegionHit( attacker, HR_ARMS );
		hr = HR_ARMS;
		if( g_debugBullets.integer ) {
			trap_SendServerCommand( attacker-g_entities, "print \"Arm Shot\n\"\n");
		}
	} else if (targ->client && targ->health > 0 && IsHeadShotWeapon( mod ) ) {
		G_LogRegionHit( attacker, HR_BODY );
		hr = HR_BODY;
		if( g_debugBullets.integer ) {
			trap_SendServerCommand( attacker-g_entities, "print \"Body Shot\n\"\n");
		}
	}

#ifndef DEBUG_STATS
	if ( g_debugDamage.integer )
#endif
	{
		G_Printf( "client:%i health:%i damage:%i mod:%s\n", targ->s.number, targ->health, take, modNames[mod] );
	}

	// add to the damage inflicted on a player this frame
	// the total will be turned into screen blends and view angle kicks
	// at the end of the frame
	if ( client ) {
		if ( attacker ) {
			client->ps.persistant[PERS_ATTACKER] = attacker->s.number;
		} else {
			client->ps.persistant[PERS_ATTACKER] = ENTITYNUM_WORLD;
		}
		client->damage_blood += take;
		client->damage_knockback += knockback;

		if ( dir ) {
			VectorCopy ( dir, client->damage_from );
			client->damage_fromWorld = qfalse;
		} else {
			VectorCopy ( targ->r.currentOrigin, client->damage_from );
			client->damage_fromWorld = qtrue;
		}
	}

	// See if it's the player hurting the emeny flag carrier
//	Team_CheckHurtCarrier(targ, attacker);

	if (targ->client) {
		// set the last client who damaged the target
		targ->client->lasthurt_client = attacker->s.number;
		targ->client->lasthurt_mod = mod;
	}

	// do the damage
	if( take ) {
		targ->health -= take;

		// Gordon: don't ever gib POWS
		if( ( targ->health <= 0 ) && ( targ->r.svFlags & SVF_POW ) ) {
			targ->health = -1;
		}

		// Ridah, can't gib with bullet weapons (except VENOM)
		// Arnout: attacker == inflictor can happen in other cases as well! (movers trying to gib things)
		//if ( attacker == inflictor && targ->health <= GIB_HEALTH) {
		if( targ->health <= GIB_HEALTH ) {
			if( !G_WeaponIsExplosive( mod ) ) {
				targ->health = GIB_HEALTH + 1;
			}
		}

// JPW NERVE overcome previous chunk of code for making grenades work again
//		if ((take > 190)) // 190 is greater than 2x mauser headshot, so headshots don't gib
		// Arnout: only player entities! messes up ents like func_constructibles and func_explosives otherwise
		if( ( (targ->s.number < MAX_CLIENTS) && (take > 190) ) && !(targ->r.svFlags & SVF_POW) ) {
			targ->health = GIB_HEALTH - 1;
		}

		if( targ->s.eType == ET_MOVER && !Q_stricmp( targ->classname, "script_mover" ) ) {
			targ->s.dl_intensity = 255.f * (targ->health / (float)targ->count);	// send it to the client
		}

		//G_Printf("health at: %d\n", targ->health);
		if( targ->health <= 0 ) {
			if( client && !wasAlive ) {
				targ->flags |= FL_NO_KNOCKBACK;
				// OSP - special hack to not count attempts for body gibbage
				if( targ->client->ps.pm_type == PM_DEAD ) {
					G_addStats(targ, attacker, take, mod);
				}

				if( (targ->health < FORCE_LIMBO_HEALTH) && (targ->health > GIB_HEALTH) ) {
					limbo(targ, qtrue);
				}

				// xkan, 1/13/2003 - record the time we died.
				if (!client->deathTime)
					client->deathTime = level.time;
			} else {


				targ->sound1to2 = hr;
				targ->sound2to1 = mod;
				targ->sound2to3 = (dflags & DAMAGE_RADIUS) ? 1 : 0;

				if( client ) {
					if( G_GetTeamFromEntity( inflictor ) != G_GetTeamFromEntity( targ ) ) {
						G_AddKillSkillPoints( attacker, mod, hr, (dflags & DAMAGE_RADIUS) );
					}
				}

				if( targ->health < -999 ) {
					targ->health = -999;
				}


				targ->enemy = attacker;
				targ->deathType = mod;

				// Ridah, mg42 doesn't have die func (FIXME)
				if( targ->die ) {	
					// Kill the entity.  Note that this funtion can set ->die to another
					// function pointer, so that next time die is applied to the dead body.
					targ->die( targ, inflictor, attacker, take, mod );
					// OSP - kill stats in player_die function
				}

				if( targ->s.eType == ET_MOVER && !Q_stricmp( targ->classname, "script_mover" ) && (targ->spawnflags & 8) ) {
					return;	// reseructable script mover doesn't unlink itself but we don't want a second death script to be called
				}

				// if we freed ourselves in death function
				if (!targ->inuse)
					return;

				// RF, entity scripting
				if (targ->health <= 0)
				{	// might have revived itself in death function
					if ((targ->s.eType != ET_CONSTRUCTIBLE && targ->s.eType != ET_EXPLOSIVE) ||	(targ->s.eType == ET_CONSTRUCTIBLE && !targ->desstages))
					{ // call manually if using desstages
						G_Script_ScriptEvent( targ, "death", "" );
					}
				}
			}

		}
		else if ( targ->pain )
		{
			if (dir) {	// Ridah, had to add this to fix NULL dir crash
				VectorCopy (dir, targ->rotate);
				VectorCopy (point, targ->pos3); // this will pass loc of hit
			} else {
				VectorClear( targ->rotate );
				VectorClear( targ->pos3 );
			}

			targ->pain (targ, attacker, take, point);
		} else {
			// OSP - update weapon/dmg stats
			G_addStats(targ, attacker, take, mod);
			// OSP
		}

		// RF, entity scripting
		G_Script_ScriptEvent( targ, "pain", va("%d %d", targ->health, targ->health+take) );

		// Ridah, this needs to be done last, incase the health is altered in one of the event calls
		if ( targ->client ) {
			targ->client->ps.stats[STAT_HEALTH] = targ->health;
		}
	}
}