void Point_MultiTriggerSpawn(ServerEntity_t *eEntity)
{
	if(!eEntity->v.targetname)
	{
		Engine.Con_Warning("No targetname set for point_multitrigger! (%i %i %i)\n",
			(int)eEntity->v.origin[0],
			(int)eEntity->v.origin[1],
			(int)eEntity->v.origin[2]);

		Entity_Remove(eEntity);
		return;
	}

	if(!eEntity->v.message)
	{
		Engine.Con_Warning("No message set for point_multitrigger! (%i %i %i)\n",
			(int)eEntity->v.origin[0],
			(int)eEntity->v.origin[1],
			(int)eEntity->v.origin[2]);

		Entity_Remove(eEntity);
		return;
	}

	if(!eEntity->local.style)
		eEntity->local.style = 0;

	eEntity->v.use = Point_MultiTriggerUse;

	Entity_SetOrigin(eEntity,eEntity->v.origin);
}
void C4Vizatergo_Explode(ServerEntity_t *eVizatergo)
{
	Sound(eVizatergo,CHAN_AUTO,va("fx/explosion%i.wav",rand()%6+1),255,ATTN_NORM);

	Entity_RadiusDamage(eVizatergo,MONSTER_RANGE_NEAR,40,DAMAGE_TYPE_EXPLODE);
	Entity_Remove(eVizatergo);
}
// [4/8/2012] Added SideWinder_Think ~hogsy
void SideWinder_Think(edict_t *eSideWinder)
{
	// [31/8/2012] Complete rewrite ~hogsy
	int	iContents = Engine.Server_PointContents(eSideWinder->v.origin);

	// [4/8/2012] Check if the contents have changed ~hogsy
	if(iContents ==	(BSP_CONTENTS_WATER || CONTENT_SLIME	|| CONTENT_LAVA))
		eSideWinder->local.speed = SIDEWINDER_MINSPEED;
	// [31/8/2012] Don't let us explode in the sky... ~hogsy
	else if(iContents == CONTENT_SKY)
	{
		Entity_Remove(eSideWinder);
		// [15/8/2013] Oops! Return here! ~hogsy
		return;
	}
	else
		eSideWinder->local.speed = SIDEWINDER_MAXSPEED;

	if(eSideWinder->local.count > 12)
		eSideWinder->local.count = 0;

//	eSideWinder->v.velocity[X]	*= ((float)sin(Server.dTime*1.5f)*5.5f)/10.0f;
//	eSideWinder->v.velocity[Y]	*= -((float)sin(Server.dTime*1.5f)*5.5f)/10.0f;
//	eSideWinder->v.velocity[Z]	*= eSideWinder->v.velocity[X]/eSideWinder->v.velocity[Y];

	if(Server.dTime >= eSideWinder->local.fSpawnDelay)
	{
		SideWinder_MissileExplode(eSideWinder,NULL);
		return;
	}

	eSideWinder->v.dNextThink = Server.dTime+0.05;
}
void Discus_Catch(ServerEntity_t *ent, ServerEntity_t *discus)
{
	// [4/7/2012] Simplified ~hogsy
	ent->v.iPrimaryAmmo = ent->local.discus_ammo2++;

	Sound(ent,CHAN_WEAPON,"weapons/discus/discuscatch.wav",255,ATTN_NORM);

	Entity_Remove(discus);
}
void Point_MonsterSpawn(ServerEntity_t *eMonster)
{
	if (cvServerMonsters.value <= 0)
	{
		Entity_Remove(eMonster);
		return;
	}

	// Set its origin and angles...
	Entity_SetOrigin(eMonster, eMonster->v.origin);
	Entity_SetAngles(eMonster, eMonster->v.angles);

	Server.iMonsters++;

	switch(eMonster->local.style)
	{
#ifdef GAME_OPENKATANA
	case MONSTER_PRISONER:
		eMonster->v.cClassname = "monster_prisoner";
		Prisoner_Spawn(eMonster);
		break;
	case MONSTER_LASERGAT:
		eMonster->v.cClassname = "monster_lasergat";
		LaserGat_Spawn(eMonster);
		break;
	case MONSTER_INMATER:
		eMonster->v.cClassname = "monster_inmater";
		Inmater_Spawn(eMonster);
		break;
#elif GAME_ADAMAS
	case MONSTER_HURLER:
		eMonster->v.cClassname = "monster_hurler";
		Hurler_Spawn(eMonster);
		break;
#endif
	default:
		Engine.Con_Warning("Invalid monster type (%i)!\n",eMonster->local.style);

		// Reduce the monster count. ~hogsy
		Server.iMonsters--;

		Entity_Remove(eMonster);
	}
}
void Point_SpriteSpawn(ServerEntity_t *seSprite)
{
#if 0
	Engine.WriteByte(MSG_BROADCAST, SVC_SPRITE);
	Engine.WriteCoord(MSG_BROADCAST, seSprite->v.origin[0]);
	Engine.WriteCoord(MSG_BROADCAST, seSprite->v.origin[1]);
	Engine.WriteCoord(MSG_BROADCAST, seSprite->v.origin[2]);
#endif
	Entity_Remove(seSprite);
}
void Point_NullSpawn(ServerEntity_t *eEntity)
{
	// Remove if there is no name given!
	if (!eEntity->v.cName || (eEntity->v.cName[0] == ' '))
	{
		Entity_Remove(eEntity);
		return;
	}

	Entity_SetOrigin(eEntity,eEntity->v.origin);
}
// Just for the compiler ~eukara
void Area_DetailSpawn(ServerEntity_t *area) {
	if(!area->v.model) {
		g_engine->Con_Warning("Area entity with no model!\n");

		Entity_Remove(area);
		return;
	}

	Entity_SetModel(area,area->v.model);
	Entity_SetOrigin(area,area->v.origin);
}
void IonRifle_IonBallTouch(edict_t *eIonBall,edict_t *eOther)
{
	if(eOther == eIonBall->local.eOwner)
		return;	// [29/1/2014] Should never even happen, but it does. Shit. ~hogsy
	else if(Engine.Server_PointContents(eIonBall->v.origin) == CONTENT_SKY)
	{
		Entity_Remove(eIonBall);
		return;
	}

	if(eOther->v.bTakeDamage)
	{
		if(!eIonBall->local.style)
			MONSTER_Damage(eOther,eIonBall->local.eOwner,25,0);
		else
			MONSTER_Damage(eOther,eIonBall->local.eOwner,50,0);
	}

	Entity_Remove(eIonBall);
}
void Area_PushTouch(ServerEntity_t *area, ServerEntity_t *other) {
	// [9/12/2013] TODO: Make this optional? Would be cool to throw monsters and other crap around... ~hogsy
	if(!Entity_IsPlayer(other)) {
        return;
    }

    other->v.velocity = area->v.movedir * (area->local.speed * 10);

	if(area->v.spawnflags & AREA_PUSH_ONCE) {
        Entity_Remove(area);
    }
}
void Point_ExplodeUse(ServerEntity_t *ePoint)
{
	Entity_RadiusDamage(ePoint, MONSTER_RANGE_NEAR, ePoint->local.iDamage, DAMAGE_TYPE_EXPLODE);

	if (Engine.Server_PointContents(ePoint->v.origin) <= BSP_CONTENTS_WATER)
		Sound(ePoint, CHAN_AUTO, SOUND_EXPLODE_UNDERWATER0, 255, ATTN_NORM);
	else
		Sound(ePoint, CHAN_AUTO, SOUND_EXPLODE, 255, ATTN_NORM);

	if (ePoint->v.spawnflags & EXPLODE_FLAG_REMOVE)
		Entity_Remove(ePoint);
}
void Point_MessageSpawn(ServerEntity_t *eEntity)
{
	if(!eEntity->v.message)
	{
		Engine.Con_Warning("Parameter 'message' not set! (%s) (%i %i %i)\n",
			eEntity->v.cClassname,
			(int)eEntity->v.origin[0],
			(int)eEntity->v.origin[1],
			(int)eEntity->v.origin[2]);

		Entity_Remove(eEntity);
		return;
	}

	Entity_SetOrigin(eEntity,eEntity->v.origin);

	switch(eEntity->local.style)
	{
	case POINT_MSG_CENTER:
		eEntity->v.use = Point_MessageCenter;
		break;
	case POINT_MSG_LOCALMESSAGE:
		eEntity->v.use = Point_MessageLocal;
		break;
	case POINT_MSG_SERVERMESSAGE:
		eEntity->v.use = Point_MessageServer;
		break;
	case POINT_MSG_INFOMESSAGE:
		eEntity->v.use = Point_InfoMessage;
		break;
	default:
		Engine.Con_Warning("Parameter 'style' not set! (%s) (%i %i %i)\n",
			eEntity->v.cClassname,
			(int)eEntity->v.origin[0],
			(int)eEntity->v.origin[1],
			(int)eEntity->v.origin[2]);

		Entity_Remove(eEntity);
	}
}
void Point_LogicSpawn(ServerEntity_t *eEntity)
{
	if(!eEntity->local.cTarget1)
	{
		Engine.Con_Warning("No target1 set for point_logic! (%i %i %i)\n",
			(int)eEntity->v.origin[0],
			(int)eEntity->v.origin[1],
			(int)eEntity->v.origin[2]);

		Entity_Remove(eEntity);
		return;
	}

	if(!eEntity->local.cTarget2 && eEntity->local.style != 3)
	{
		Engine.Con_Warning("No target2 set for point_logic! (%i %i %i)\n",
			(int)eEntity->v.origin[0],
			(int)eEntity->v.origin[1],
			(int)eEntity->v.origin[2]);

		Entity_Remove(eEntity);
		return;
	}

	if(!eEntity->local.style)
		eEntity->local.style = 1;

	if(!eEntity->local.dWait)
		eEntity->local.dWait = 1;

	if(eEntity->local.style != 3)
		eEntity->local.iValue = 0;
	else
		eEntity->local.iValue = 1;

	Entity_SetOrigin(eEntity,eEntity->v.origin);

	eEntity->v.think		= Point_LogicThink;
	eEntity->v.dNextThink	= Server.dTime+1.0f;
}
void Area_TriggerTouch(ServerEntity_t *area, ServerEntity_t *other) {
	if(area->v.nextthink || ((area->Monster.type != MONSTER_PLAYER) && other->v.health <= 0)) {
        return;
    }

	area->v.nextthink = Server.time + area->local.wait;

	UseTargets(area,other);

	if(area->local.wait < 0) {
        Entity_Remove(area);
    }
}
void Point_VehicleSpawn(ServerEntity_t *eVehicle)
{
	switch(eVehicle->local.style)
	{
#ifdef GAME_ICTUS
	case VEHICLE_TYPE_ROVER:
		Rover_Spawn(eVehicle);
		break;
#endif
	default:
		Engine.Con_Warning("Invalid vehicle type! (%)\n",eVehicle->local.style);
		Entity_Remove(eVehicle);
	}
}
void Point_SkyCameraSpawn(ServerEntity_t *entity)
{
	if (Server.skycam)
	{
		Engine.Con_Warning("Multiple sky cameras on level! (%i %i %i)\n", (int)entity->v.origin[0], (int)entity->v.origin[1], (int)entity->v.origin[2]);
		return;
	}

	Math_VectorCopy(entity->v.origin, Server.skycam_position);

	// Enable skycam, which in turn will let us know to inform the client about it.
	Server.skycam = true;

	Entity_Remove(entity);
}
void Point_DecorationSpawn(ServerEntity_t *eDecoration)
{
	if (eDecoration->v.model[0] == ' ')
	{
		Entity_Remove(eDecoration);
		return;
	}

	Server_PrecacheModel(eDecoration->v.model);

	Entity_SetModel(eDecoration,eDecoration->v.model);

	if(eDecoration->v.spawnflags & DECORATION_DROPTOFLOOR)
		Entity_DropToFloor(eDecoration);
}
void Waypoint_Delete(Waypoint_t *wPoint)
{
	if(!wPoint)
		return;

#ifdef	DEBUG_WAYPOINT
	// [23/3/2013] If we have an entity set for debugging, then remove it! ~hogsy
	if(wPoint->eDebug)
		Entity_Remove(wPoint->eDebug);
#endif

	free((void*)wPoint);

	waypoint_count--;
	waypoint_allocated--;
}
Beispiel #19
0
// OBSOLETE
bool Game_Init(int state,edict_t *ent,double dTime)
{
	Server.dTime = dTime;

	switch(state)
	{
	case SERVER_CLIENTPOSTTHINK:
		// [8/6/2012] Revised ~hogsy
		Player_PostThink(ent);
		break;
	case SERVER_PLAYERPRETHINK:
		// [8/6/2012] Revised ~hogsy
		Player_PreThink(ent);
		break;
	case SERVER_CLIENTCONNECT:
		Server.iClients++;

		Engine.Server_BroadcastPrint("%s connected\n",ent->v.netname);
		break;
	case SERVER_CLIENTDISCONNECT:
		Server.iClients--;

		Engine.Server_BroadcastPrint("%s disconnected\n",ent->v.netname);

		Entity_Remove(ent);
		break;
	case SERVER_SETCHANGEPARMS:
		if(ent->v.iHealth <= 0)
			break;
		else if(ent->v.iHealth < 50)
			ent->v.iHealth = 50;

		// TODO: Set all necessary parms...
		break;
	case SERVER_SETNEWPARMS:
		if(!Server.bActive)
			Server.bActive = true;

		iRedScore	=
		iBlueScore	= 0;
		break;
	}

	return true;
}
void Hermes_CloudThink(ServerEntity_t *ent)
{
	MathVector3f_t vel;

	if (!ent->local.hit)
	{
		Entity_Remove(ent);
		return;
	}

	ent->local.hit -= 2;

	Math_VectorClear(vel);

	Engine.Particle(ent->v.origin,vel,12,"poison",8);

	ent->v.think		= Hermes_CloudThink;
	ent->v.dNextThink	= Server.dTime+0.3;
}
void Hermes_CloudThink(ServerEntity_t *ent)
{
	PLVector3D vel;

	if (!ent->local.hit)
	{
		Entity_Remove(ent);
		return;
	}

	ent->local.hit -= 2;

	plClearVector3D(&vel);

	Engine.Particle(ent->v.origin,vel,12,"poison",8);

	ent->v.think		= Hermes_CloudThink;
	ent->v.nextthink	= Server.time+0.3;
}
void Area_WallSpawn(ServerEntity_t *area) {
	if(!area->v.model) {
		g_engine->Con_Warning("Area entity with no model!\n");

		Entity_Remove(area);
		return;
	}

	if(area->v.name) {
        area->v.use = Area_WallUse;
    }

	area->v.movetype = MOVETYPE_PUSH;

	area->local.value = 1;

	Entity_SetModel(area,area->v.model);
	Entity_SetOrigin(area,area->v.origin);
}
void GreekfireTouch(ServerEntity_t *ent, ServerEntity_t *other)
{
	vec3_t vel;

	if (other == ent->local.eOwner)
		return;

	if(other->v.bTakeDamage)
		Entity_Damage(other, ent, 50, 0);

	Math_VectorCopy(ent->v.velocity,vel);
	Math_VectorInverse(vel);

	Engine.Particle(ent->v.origin,vel,5,"spark",17);

	Math_VectorClear(ent->v.velocity);

	Entity_Remove(ent);
}
void Point_TimedTriggerSpawn(ServerEntity_t *eEntity)
{
	if(!eEntity->v.targetname)
	{
		Engine.Con_Warning("No targetname set for point_timedtrigger (%f %f %f)!\n",
			eEntity->v.origin[0],
			eEntity->v.origin[1],
			eEntity->v.origin[2]);

		Entity_Remove(eEntity);
		return;
	}

	eEntity->v.use = Point_TimedTriggerUse;

	if(eEntity->v.spawnflags & 32)
		eEntity->v.use(eEntity);

	Entity_SetOrigin(eEntity,eEntity->v.origin);
}
void ShockLaser_Touch(ServerEntity_t *ent, ServerEntity_t *other)
{
	char	*cSound;

	if(!other || (other == ent->local.owner))
		return;

	if(other->v.takedamage)
	{
		// burning flesh sound
		cSound = "weapons/shockwave/burn.wav";

		Entity_Damage(other, ent, 100, 0);
	}
	else
		cSound = "weapons/shockwave/fade.wav";

	Sound(ent,CHAN_ITEM,cSound,255,ATTN_NORM);

	Entity_Remove(ent);
}
void Point_AmbientSpawn(ServerEntity_t *eEntity)
{
	int iAttenuation;

	if(!eEntity->local.volume)
		eEntity->local.volume = 255;

	if(!eEntity->v.noise)
	{
		Engine.Con_Warning("No sound set for point_ambient! (%i %i %i)\n",
			(int)eEntity->v.origin[0],
			(int)eEntity->v.origin[1],
			(int)eEntity->v.origin[2]);

		Entity_Remove(eEntity);
		return;
	}

	switch(eEntity->local.style)
	{
		case AMBIENT_RADIUS_EVERYWHERE:
			iAttenuation = ATTN_NONE;
			break;
		case AMBIENT_RADIUS_SMALL:
			iAttenuation = ATTN_IDLE;
			break;
		case AMBIENT_RADIUS_MEDIUM:
			iAttenuation = ATTN_STATIC;
			break;
		case AMBIENT_RADIUS_LARGE:
			iAttenuation = ATTN_NORM;
			break;
		default:
			iAttenuation = ATTN_NORM;
	}

	Server_PrecacheSound(eEntity->v.noise);

	Engine.Server_AmbientSound(eEntity->v.origin,eEntity->v.noise,eEntity->local.volume,iAttenuation);
}
void Inmater_Die(ServerEntity_t *eInmater, ServerEntity_t *eOther, EntityDamageType_t type)
{
	if(eInmater->v.health < INMATER_MIN_HEALTH)
	{
		int	iGibs = (rand()%5)+5,
			i;

		Sound(eInmater,CHAN_VOICE,"misc/gib1.wav",255,ATTN_NORM);

		// [13/9/2012] Updated paths ~hogsy
		for(i = 0; i < iGibs; i++)
		{
			char			cModel[64];
			int				j;
			PLVector3D	vOrigin,vGibVelocity;

			vOrigin.x = eInmater->v.origin.x + ((eInmater->v.mins.x + eInmater->v.maxs.x) * (rand()%10));
			vOrigin.y = eInmater->v.origin.y + ((eInmater->v.mins.y + eInmater->v.maxs.y) * (rand()%10));
			vOrigin.z = eInmater->v.origin.z + ((eInmater->v.mins.z + eInmater->v.maxs.z) * (rand()%10));

			// [26/2/2014] Add some random velocity on top of the velocity that the inmater already has ~hogsy
            vGibVelocity = eInmater->v.velocity;
			plAddVector3Df(&vGibVelocity, (float)(rand() % 5));

			PHYSICS_MODEL_METAL(cModel);

			ThrowGib(vOrigin, vGibVelocity, cModel, (float)eInmater->v.health*-1, true);
		}

		Engine.Particle(eInmater->v.origin,eInmater->v.velocity,10.0f,"blood",20);

		Entity_Remove(eInmater);
		return;
	}

	Entity_Animate(eInmater,efInmaterDeath);

	AI_SetState(eInmater, AI_STATE_DEAD);
}
void Point_SoundSpawn(ServerEntity_t *eEntity)
{
	if(!eEntity->v.noise)
	{
		Engine.Con_Warning("No noise not set for %i (%i %i %i)!\n",
			eEntity->v.cClassname,
			(int)eEntity->v.origin[0],
			(int)eEntity->v.origin[1],
			(int)eEntity->v.origin[2]);

		Entity_Remove(eEntity);
		return;
	}
	else if(!eEntity->local.volume)
		eEntity->local.volume = 255;

	Server_PrecacheSound(eEntity->v.noise);

	Entity_SetOrigin(eEntity,eEntity->v.origin);

	eEntity->v.use = Point_SoundUse;
}
// [2/8/2012] Renamed to SideWinder_MissileExplode ~hogsy
void SideWinder_MissileExplode(edict_t *ent,edict_t *other)
{
	vec3_t	vVelocity;

	if(other && (other == ent->local.eOwner))
	{
		SideWinder_Think(ent);
		return;
	}

	Entity_RadiusDamage(ent,MONSTER_RANGE_NEAR,30,1);

	// [4/8/2012] Simplified ~hogsy
	Math_VectorNegate(ent->v.velocity,vVelocity);

	// [4/8/2012] TODO: Underwater explosion too! ~hogsy
	Sound(ent,CHAN_AUTO,va("fx/explosion%i.wav",rand()%6+1),255,ATTN_NORM);

	Engine.Particle(ent->v.origin,vVelocity,1.0f,"spark2",25);

	Entity_Remove(ent);
}
void Point_LightstyleSpawn(ServerEntity_t *eEntity)
{
	if(eEntity->v.noise)
		Server_PrecacheSound(eEntity->v.noise);

	if(!eEntity->v.message)
		eEntity->v.message = "a";

	if(!eEntity->local.style)
	{
		Engine.Con_Warning("No style set for point_lightstyle! (%i %i %i)\n",
			(int)eEntity->v.origin[0],
			(int)eEntity->v.origin[1],
			(int)eEntity->v.origin[2]);

		Entity_Remove(eEntity);
		return;
	}

	eEntity->v.use = Point_LightstyleUse;

	Entity_SetOrigin(eEntity,eEntity->v.origin);
}