void Inmater_Spawn(ServerEntity_t *eInmater)
{
	Server_PrecacheModel(MODEL_INMATER_BODY);

	Entity_SetPhysics(eInmater, SOLID_SLIDEBOX, 3.0f, 4.5f);

	eInmater->Monster.type = MONSTER_INMATER;
	eInmater->Monster.Frame = Inmater_Think;
	eInmater->Monster.Pain = Inmater_Pain;

	Entity_SetKilledFunction(eInmater, Inmater_Die);

	eInmater->v.takedamage = true;
	eInmater->v.movetype = MOVETYPE_STEP;
	eInmater->v.health = INMATER_MAX_HEALTH;
	eInmater->v.netname = "Inmater";
	eInmater->v.frame = 0;
	eInmater->local.maxhealth = INMATER_MAX_HEALTH;

	AI_SetState(eInmater, AI_STATE_AWAKE);
	AI_SetThink(eInmater, AI_THINK_IDLE);

	Entity_SetModel(eInmater, MODEL_INMATER_BODY);
	Entity_SetSize(eInmater, -16.0f, -16.0f, -24.0f, 16.0f, 16.0f, 32.0f);
	Entity_SetOrigin(eInmater, eInmater->v.origin);

	Entity_DropToFloor(eInmater);
}
void Crossbow_Projectile(ServerEntity_t *ent)
{
	// [11/2/2012] Revised and fixed ~hogsy
	MathVector3f_t mvDirection;
	ServerEntity_t *eArrow;

	eArrow = Entity_Spawn();
	if(eArrow)
	{
		eArrow->local.eOwner = ent;

		eArrow->v.movetype	= MOVETYPE_FLY;

		eArrow->Physics.iSolid	= SOLID_BBOX;

		Math_MVToVector(Weapon_Aim(ent), mvDirection);
		Math_VectorScale(mvDirection, 2000.0f, eArrow->v.velocity);

		Entity_SetModel(eArrow,"models/arrow.md2");
		Entity_SetSizeVector(eArrow,g_mvOrigin3f,g_mvOrigin3f);

		// [25/6/2012] Simplified ~hogsy
		Math_VectorCopy(ent->v.origin,eArrow->v.origin);
		eArrow->v.origin[2] += 15.0f;

		Math_MVToVector(Math_VectorToAngles(ent->v.velocity),ent->v.angles);

		eArrow->v.TouchFunction = arrow_touch;
	}
}
void Area_NoclipSpawn(ServerEntity_t *area) {
	area->v.movetype = MOVETYPE_PUSH;
	area->Physics.solid	= SOLID_NOT;

	Entity_SetModel(area, area->v.model);
	Entity_SetOrigin(area, area->v.origin);
}
// [4/7/2012] Renamed to Discus_SpawnProjectile ~hogsy
void Discus_SpawnProjectile(ServerEntity_t *ent,vec3_t org)
{
	ServerEntity_t *eDiscus;
	MathVector3f_t mvDirection;

	eDiscus = Entity_Spawn();

	eDiscus->v.cClassname = "discus";
	eDiscus->v.movetype = MOVETYPE_FLYBOUNCE;
	eDiscus->Physics.iSolid = SOLID_BBOX;
	eDiscus->v.effects = EF_MOTION_ROTATE;
	eDiscus->v.enemy = ent;

	// [4/8/2012] Updated to use owner instead ~hogsy
	eDiscus->local.eOwner = ent;

	eDiscus->local.hit = 0;

	Math_MVToVector(Weapon_Aim(ent), mvDirection);
	Math_VectorScale(mvDirection, 700.0f, eDiscus->v.velocity);

	Math_MVToVector(Math_VectorToAngles(eDiscus->v.velocity), eDiscus->v.angles);

	eDiscus->v.TouchFunction = Discus_ProjectileTouch;

	Entity_SetModel(eDiscus, "models/w_daedalus.md2");
	Entity_SetSizeVector(eDiscus, g_mvOrigin3f, g_mvOrigin3f);
	Entity_SetOrigin(eDiscus, org);

	Sound(ent,CHAN_WEAPON,"weapons/discus/discusthrow.wav",255,ATTN_NORM);
}
void Shockwave_SpawnProjectile(ServerEntity_t *ent)
{
	ServerEntity_t *eLaser;

	Sound(ent,CHAN_WEAPON,"weapons/shockwave/fire.wav",255,ATTN_NORM);

	ent->v.punchangle[0] -= 10.0f;
	
	eLaser = Entity_Spawn();
	if(eLaser)
	{
		Weapon_Projectile(ent, eLaser, 2000.0f);

		Math_VectorCopy(ent->v.origin,eLaser->v.origin);
		Math_MVToVector(plVectorToAngles(eLaser->v.velocity),eLaser->v.angles);

		eLaser->local.owner = ent;

		eLaser->v.movetype		= MOVETYPE_FLY;
		eLaser->v.TouchFunction = ShockLaser_Touch;
		eLaser->v.origin[2]		+= 25.0f;

		eLaser->Physics.solid	= SOLID_BBOX;

		Entity_SetModel(eLaser,"models/slaser.md2");
		Entity_SetSizeVector(eLaser, pl_origin3f, pl_origin3f);
	}

	ent->local.shockwave_ammo--;
	ent->v.primary_ammo = ent->local.shockwave_ammo;
}
void GreekFire_Throw(edict_t *ent)
{
	float	*dir;
	edict_t *greekfire = Entity_Spawn();

	greekfire->v.cClassname	= "greekfire";
	greekfire->v.movetype	= MOVETYPE_BOUNCE;
	greekfire->v.effects	= EF_DIMLIGHT;

	greekfire->Physics.iSolid = SOLID_BBOX;

	greekfire->local.eOwner = ent;

	dir = Engine.Aim(ent);
	greekfire->v.velocity[0] = dir[0]*800;
	greekfire->v.velocity[1] = dir[1]*800;
	greekfire->v.velocity[2] = dir[2]*800;

	Engine.MakeVectors(greekfire->v.v_angle);

	Entity_SetModel(greekfire,"models/w_greekfire.md2");
	Math_MVToVector(Math_VectorToAngles(greekfire->v.velocity),greekfire->v.angles);

	// [4/7/2012] Simplified ~hogsy
	Math_VectorCopy(ent->v.origin,greekfire->v.origin);

	Entity_SetSizeVector(greekfire,mv3Origin,mv3Origin);

	Engine.LinkEntity(greekfire,false);

	greekfire->v.TouchFunction = GreekfireTouch;
}
void Area_RotateSpawn(ServerEntity_t *area) {
	if(!area->local.speed) {
        area->local.speed = 100;
    }

#if 0
	// [26/7/2012] Check our spawn flags ~hogsy
	if(area->local.style == STYLE_ROTATE_DOOR)
	{
		if(area->v.spawnflags & SPAWNFLAG_ROTATE_REVERSE)
		{
		}

		if(area->v.spawnflags & SPAWNFLAG_ROTATE_X)
			area->v.movedir[0] = 1.0f;
		else if(area->v.spawnflags & SPAWNFLAG_ROTATE_Y)
			area->v.movedir[1] = 1.0f;
		else
			area->v.movedir[2] = 1.0f;

		Math_VectorCopy(area->v.angles,area->local.pos1);
		area->local.pos2[0] = area->local.pos1[0]+area->v.movedir[0]*area->local.distance;

		area->v.TouchFunction = Area_RotateTouch;

		area->local.dMoveFinished = 0;
	}
	else
#endif
	{
		if(area->v.spawnflags & SPAWNFLAG_ROTATE_REVERSE) {
            area->local.speed *= -1;
        }

		if(area->v.spawnflags & SPAWNFLAG_ROTATE_X) {
            area->v.avelocity.x = area->local.speed;
        }

		if(area->v.spawnflags & SPAWNFLAG_ROTATE_Y) {
            area->v.avelocity.y = area->local.speed;
        }

		if(area->v.spawnflags & SPAWNFLAG_ROTATE_Z) {
            area->v.avelocity.z = area->local.speed;
        }
	}

	Entity_SetBlockedFunction(area, Area_RotateBlocked);

	area->v.movetype    = MOVETYPE_PUSH;
	area->v.think       = Area_RotateThink;
	area->v.nextthink  = Server.time + 1000000000.0;	// TODO: This is a hack. A dirty filthy hack. Curse it and its family!

	area->Physics.solid = SOLID_BSP;

	Entity_SetModel(area,area->v.model);
	Entity_SetSizeVector(area,area->v.mins,area->v.maxs);
	Entity_SetOrigin(area,area->v.origin);
}
void Area_ButtonSpawn(ServerEntity_t *eArea)
{
	float	fDist;
	PLVector3D vMoveDir;

	if(!eArea->v.spawnflags)
		eArea->v.spawnflags = 0;

	if(eArea->local.cSoundStart)
		Server_PrecacheSound(eArea->local.cSoundStart);
	if (eArea->local.sound_stop)
		Server_PrecacheSound(eArea->local.sound_stop);
	if(eArea->local.cSoundMoving)
		Server_PrecacheSound(eArea->local.cSoundMoving);
	if(eArea->local.cSoundReturn)
		Server_PrecacheSound(eArea->local.cSoundReturn);

	eArea->v.movetype = MOVETYPE_PUSH;

	eArea->Physics.solid = SOLID_BSP;

	// [18/5/2013] Changed to use ! check instead since it's safer here ~hogsy
	if(eArea->local.lip == 0) {
        eArea->local.lip = 4;
    }

	eArea->local.value = 0;
	eArea->local.flags = STATE_BOTTOM;

	Entity_SetModel(eArea,eArea->v.model);
	Entity_SetOrigin(eArea,eArea->v.origin);
	Entity_SetSizeVector(eArea,eArea->v.mins,eArea->v.maxs);

    eArea->local.pos1 = eArea->v.origin;

	Area_SetMoveDirection(eArea->v.angles,eArea->v.movedir);

    vMoveDir.x = std::fabs(eArea->v.movedir.x);
    vMoveDir.y = std::fabs(eArea->v.movedir.y);
    vMoveDir.z = std::fabs(eArea->v.movedir.z);

	fDist = vMoveDir.x*eArea->v.size.x+
			vMoveDir.y*eArea->v.size.y+
			vMoveDir.z*eArea->v.size.z-
			eArea->local.lip;

	Math_VectorMake(eArea->local.pos1,fDist,eArea->v.movedir,&eArea->local.pos2);

	if(eArea->v.spawnflags != 32) { // Toggle
        eArea->v.TouchFunction = Area_ButtonTouch;
    }

	if (eArea->local.damage) {
        Entity_SetBlockedFunction(eArea, Area_ButtonBlocked);
    }

	eArea->v.use = Area_ButtonUse;
}
void Area_KillSpawn(ServerEntity_t *area) {
	area->Physics.solid = SOLID_TRIGGER;

	Entity_SetModel(area, area->v.model);
	Entity_SetOrigin(area, area->v.origin);
	Entity_SetTouchFunction(area, Area_KillTouch);

	area->v.model = 0;
}
void Area_PlatformSpawn(ServerEntity_t *area) {
	if(!area->v.spawnflags) {
        area->v.spawnflags = 0;
    }

	if(area->local.cSoundStart) {
        Server_PrecacheSound(area->local.cSoundStart);
    }
	if (area->local.sound_stop) {
        Server_PrecacheSound(area->local.sound_stop);
    }
	if(area->local.cSoundMoving) {
        Server_PrecacheSound(area->local.cSoundMoving);
    }
	if(area->local.cSoundReturn) {
        Server_PrecacheSound(area->local.cSoundReturn);
    }

	area->v.movetype = MOVETYPE_PUSH;

	area->Physics.solid = SOLID_BSP;

	if(area->local.count == 0) {
        area->local.count = 100;
    }
	if(area->local.wait == 0) {
        area->local.wait = 3;
    }
	if(area->local.damage == 0) {
        area->local.damage = 20;
    }

	area->local.value = 0;
	area->local.flags = STATE_BOTTOM;

	Entity_SetModel(area,area->v.model);
	Entity_SetOrigin(area,area->v.origin);
	Entity_SetSizeVector(area,area->v.mins,area->v.maxs);

    area->local.pos1 = area->v.origin;
	Area_SetMoveDirection(area->v.angles, area->v.movedir);

	float dist = (float)area->local.count;

	Math_VectorMake(area->local.pos1, dist, area->v.movedir, &area->local.pos2);

	if(area->v.spawnflags != 32) { // Toggle
        area->v.TouchFunction = Area_PlatformTouch;
    }

	if (area->local.damage) {
        Entity_SetBlockedFunction(area, Area_PlatformBlocked);
    }

	area->v.use = Area_PlatformUse;
}
void Area_ClimbSpawn(ServerEntity_t *area) {
	Area_SetMoveDirection(area->v.angles, area->v.movedir);
	area->v.TouchFunction = Area_ClimbTouch;

	area->Physics.solid = SOLID_TRIGGER;

	Entity_SetModel(area,area->v.model);
	Entity_SetOrigin(area,area->v.origin);
	area->v.model = 0;
}
// [4/8/2012] Renamed to SideWinder_SpawnMissle ~hogsy
void SideWinder_SpawnMissle(edict_t *ent,float fSpeed,float ox)
{
	// [26/2/2012] Revised and fixed ~hogsy
	vec3_t	vOrg;
	edict_t *eMissile = Entity_Spawn();

	/*	TODO:
			Spawn a flare at our position too
		~hogsy
	*/

	eMissile->v.cClassname	= "sidewindermissile";
	eMissile->v.movetype	= MOVETYPE_FLYMISSILE;
	eMissile->v.effects		= EF_PARTICLE_SMOKE|EF_DIMLIGHT;

	eMissile->Physics.iSolid	= SOLID_BBOX;
	eMissile->Physics.eIgnore	= ent;

	eMissile->local.speed	= SIDEWINDER_MAXSPEED;
	eMissile->local.eOwner	= ent;
	eMissile->local.count	= 0;
	// [4/8/2012] Change our speed depending on what contents we're within ~hogsy
	eMissile->local.speed	= fSpeed;

	Math_VectorScale(Engine.Aim(ent),eMissile->local.speed,eMissile->v.velocity);

	Math_AngleVectors(ent->v.v_angle,
		// [4/8/2012] Set up our angle vectors ~hogsy
		eMissile->v.vForward,
		eMissile->local.vRight,
		eMissile->local.vUp);
	Math_VectorCopy(ent->v.v_angle,eMissile->v.angles);

	Entity_SetModel(eMissile,"models/sidewinder_missile.md2");

	Math_VectorCopy(ent->v.origin,vOrg);

	vOrg[0] += eMissile->v.vForward[0]*8+eMissile->local.vRight[0]*ox;
	vOrg[1] += eMissile->v.vForward[1]*8+eMissile->local.vRight[1]*ox;
	vOrg[2] += eMissile->v.vForward[2]*24;

	Entity_SetSizeVector(eMissile,mv3Origin,mv3Origin);
	Entity_SetOrigin(eMissile,vOrg);

	// [4/8/2012] Time at which we'll be removed if nothing hit ~hogsy
	eMissile->local.fSpawnDelay = (float)(Server.dTime+8.0);

	eMissile->v.TouchFunction	= SideWinder_MissileExplode;
	eMissile->v.dNextThink		= Server.dTime+0.05;
	eMissile->v.think			= SideWinder_Think;

	// [4/8/2012] Moved so we do this last! ~hogsy
	Engine.LinkEntity(eMissile,false);
}
// 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 Area_PushSpawn(ServerEntity_t *area) {
	if(!area->local.speed)
		area->local.speed = 500.0f;

	Area_SetMoveDirection(area->v.angles, area->v.movedir);

	area->v.TouchFunction = Area_PushTouch;
	area->Physics.solid	= SOLID_TRIGGER;

	Entity_SetModel(area,area->v.model);
	Entity_SetOrigin(area,area->v.origin);
	Entity_SetSizeVector(area,area->v.mins,area->v.maxs);

	area->v.model = 0;
}
示例#15
0
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 Area_WallUse(ServerEntity_t *area) {
	if(area->Physics.solid == SOLID_BSP) {
		area->local.oldmodel	= area->v.model;
		area->local.value		= 0;

		area->Physics.solid = SOLID_NOT;

		area->v.model = 0;
		return;
	}

	area->Physics.solid = SOLID_BSP;
	area->local.value = 1;
	Entity_SetModel(area,area->local.oldmodel);
}
void C4Vizatergo_PrimaryAttack(ServerEntity_t *eOwner)
{
	MathVector3f_t vOrigin;
	MathVector3f_t mvDirection;
	ServerEntity_t *c4ball = Entity_Spawn();

	Sound(eOwner,CHAN_AUTO,"weapons/c4/c4fire.wav",255,ATTN_NORM);
	Sound(eOwner,CHAN_AUTO,"weapons/c4/c4cock.wav",255,ATTN_NORM);

	Weapon_Animate(eOwner,C4Animation_Fire1);
	Weapon_ViewPunch(eOwner, 7, true);

	eOwner->v.iPrimaryAmmo = eOwner->local.iC4Ammo -= 1;

	c4ball->v.cClassname	= "c4ball";
	c4ball->v.movetype		= MOVETYPE_BOUNCE;

	c4ball->local.style = AMMO_C4BOMBS;		// Cleaner way to tell if this can explode or not :V ~hogsy
	c4ball->local.iC4Ammo = 1;				// [11/8/2013] Since style is used for other shit too LAWL ~hogsy
	c4ball->local.eOwner = eOwner;

	// Set the physical properties.
	c4ball->Physics.iSolid = SOLID_BBOX;
	c4ball->Physics.fMass = 0.9f;
	c4ball->Physics.eIgnore = eOwner;
	c4ball->Physics.fGravity = SERVER_GRAVITY;

	Math_MVToVector(Weapon_Aim(eOwner), mvDirection);
	Math_VectorScale(mvDirection, C4VIZATERGO_MAX_RANGE, c4ball->v.velocity);

	c4ball->v.velocity[pY] += 20.0f;

	Math_MVToVector(Math_VectorToAngles(c4ball->v.velocity),c4ball->v.angles);
	Math_VectorCopy(eOwner->v.origin,vOrigin);

	c4ball->v.TouchFunction = C4Vizatergo_C4BallTouch;
	c4ball->v.think = C4Vizatergo_Think;
	c4ball->v.dNextThink = Server.dTime + 2.5;

	Entity_SetModel(c4ball,"models/c4ammo.md2");
	Entity_SetSizeVector(c4ball,g_mvOrigin3f,g_mvOrigin3f);
	Entity_SetOrigin(c4ball,vOrigin);

	if(eOwner->local.attackb_finished > Server.dTime)	// No attack boost...
		eOwner->local.dAttackFinished = Server.dTime+0.6;
	else
		eOwner->local.dAttackFinished = Server.dTime+1.2;
}
void Area_PushableSpawn(ServerEntity_t *area) {
	// TODO: If designed to be breakable, make breakable? ~eukara
/*	if (area->v.health) {
		Area_BreakableSpawn(area);
	}
*/
	//area->Physics.fGravity = cv_server_gravity.value;
    area->v.angles = 0;

	area->Physics.solid = SOLID_SLIDEBOX;
	area->v.movetype = MOVETYPE_STEP;
	Entity_SetModel(area,area->v.model);
	Entity_SetOrigin(area,area->v.origin);
	Entity_SetSizeVector(area,area->v.mins,area->v.maxs);

	area->v.TouchFunction = Area_PushableTouch;
	area->v.think = Area_PushableThink;
}
void Area_TriggerSpawn(ServerEntity_t *area) {
	if(!area->v.targetname) {
		g_engine->Con_Warning("'targetname' not set for trigger! (%i %i %i)\n",
			(int)area->v.origin.x,
			(int)area->v.origin.y,
			(int)area->v.origin.z);
		return;
	}

	area->v.TouchFunction = Area_TriggerTouch;

	area->Physics.solid = SOLID_TRIGGER;

	Entity_SetModel(area,area->v.model);
	Entity_SetOrigin(area,area->v.origin);

	area->v.model = 0;
}
void Area_ChangeLevel(ServerEntity_t *area) {
	if(!area->v.targetname) {
		g_engine->Con_Warning("No targetname set for area_changelevel! (%i %i %i)\n",
			(int)area->v.origin.x,
			(int)area->v.origin.y,
			(int)area->v.origin.z);
		return;
	}

	area->v.TouchFunction	= Area_ChangeLevelTouch;

	area->Physics.solid = SOLID_TRIGGER;

	Entity_SetModel(area,area->v.model);
	Entity_SetOrigin(area,area->v.origin);

	area->v.model = 0;
}
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 Area_CreateGib(ServerEntity_t *area, const char *model) {
	ServerEntity_t *gib = Entity_Spawn();
	if (gib) {
		gib->v.classname = "entity_gib";
		gib->v.movetype = MOVETYPE_BOUNCE;
		gib->v.TouchFunction = Area_BreakableBounce;
		gib->v.think = Entity_Remove;
		gib->v.nextthink = Server.time + 20;
		gib->v.takedamage = false;

		gib->Physics.solid = SOLID_TRIGGER;

		gib->local.style = area->local.style;

		gib->v.velocity.x = gib->v.avelocity.x = (float)(rand() % 5 * area->v.health * 5);
        gib->v.velocity.y = gib->v.avelocity.y = (float)(rand() % 5 * area->v.health * 5);
        gib->v.velocity.z = gib->v.avelocity.z = (float)(rand() % 5 * area->v.health * 5);

		Entity_SetModel(gib, model);
		Entity_SetOrigin(gib, area->v.oldorigin);
		Entity_SetSizeVector(gib, PLVector3D(), PLVector3D());
	}
}
void GreekFire_Throw(ServerEntity_t *ent)
{
	ServerEntity_t *greekfire = Entity_Spawn();

	greekfire->v.cClassname	= "greekfire";
	greekfire->v.movetype	= MOVETYPE_BOUNCE;
	greekfire->v.effects	= EF_DIMLIGHT;

	greekfire->Physics.iSolid = SOLID_BBOX;

	greekfire->local.eOwner = ent;

	Weapon_Projectile(ent,greekfire,800.0f);

	Entity_SetModel(greekfire,"models/w_greekfire.md2");
	Math_MVToVector(Math_VectorToAngles(greekfire->v.velocity),greekfire->v.angles);

	// Use SetOrigin since it automatically links.
	Entity_SetOrigin(greekfire, ent->v.origin);

	Entity_SetSizeVector(greekfire,g_mvOrigin3f,g_mvOrigin3f);

	greekfire->v.TouchFunction = GreekfireTouch;
}
示例#24
0
/*	Uses both primary burst and mega burst!
*/
void IonRifle_PrimaryAttack(edict_t *eOwner)
{
	switch(eOwner->local.iFireMode)
	{
	case 1:
		Weapon_Animate(eOwner,efIonRifleBlastFire);

		eOwner->v.punchangle[0] -= (float)(((rand()%10)+5));

		eOwner->local.ionblaster_ammo -= 5;

		{
			edict_t	*eIonBall = Entity_Spawn();
			if(eIonBall)
			{
				vec3_t	vOrigin;

				eIonBall->v.cClassname		= "ionball";
				eIonBall->v.movetype		= MOVETYPE_FLY;
				eIonBall->v.effects			= EF_LIGHT_GREEN;
				eIonBall->v.TouchFunction	= IonRifle_IonBallTouch;

				eIonBall->Model.fScale = 2.0f;

				eIonBall->Physics.iSolid	= SOLID_BBOX;
				eIonBall->Physics.eIgnore	= eOwner;

				eIonBall->local.eOwner	= eOwner;
				eIonBall->local.style	= 1;		// [29/1/2014] Preserve our firemode ~hogsy

				Math_VectorCopy(eOwner->v.origin,vOrigin);

				vOrigin[2] += 25.0f;

				Entity_SetModel(eIonBall,"models/ionball.md2");
				Entity_SetSizeVector(eIonBall,mv3Origin,mv3Origin);
				Entity_SetOrigin(eIonBall,vOrigin);

				{
					vec_t	*vAim = Engine.Aim(eOwner);

					Math_VectorScale(vAim,IONRIFLE_MAX_RANGE,eIonBall->v.velocity);
					Math_VectorCopy(vAim,eIonBall->v.angles);
				}

				Engine.LinkEntity(eIonBall,false);
			}
		}

		if(eOwner->local.attackb_finished > Server.dTime)
			eOwner->local.dAttackFinished = Server.dTime+0.10;
		else
			eOwner->local.dAttackFinished = Server.dTime+0.5;
		break;
	default:	// Simple bursts
		Sound(eOwner,CHAN_AUTO,"weapons/laser.wav",255,ATTN_NORM);

		switch(eOwner->local.iBarrelCount)
		{
		case 0:
			Weapon_Animate(eOwner,efIonRiflePulseFireA);
			break;
		case 1:
			Weapon_Animate(eOwner,efIonRiflePulseFireB);
			break;
		case 2:
			Weapon_Animate(eOwner,efIonRiflePulseFireC);
			break;
		case 3:
			Weapon_Animate(eOwner,efIonRiflePulseFireD);
			break;
		case 4:
			Weapon_Animate(eOwner,efIonRiflePulseFireE);
		}

		// [25/9/2013] Punch the view back ~hogsy
		eOwner->v.punchangle[0] -= (float)(((rand()%5)+1)/10.0f);

		eOwner->local.ionblaster_ammo--;

		// [29/1/2014] Let us cycle through each barrel on an individual basis ~hogsy
		eOwner->local.iBarrelCount++;
		if(eOwner->local.iBarrelCount >= 4)
			eOwner->local.iBarrelCount = 0;

		{
			edict_t	*eIonBall = Entity_Spawn();
			if(eIonBall)
			{
				vec3_t	vOrigin;

				eIonBall->v.cClassname		= "ionball";
				eIonBall->v.movetype		= MOVETYPE_FLY;
				eIonBall->v.effects			= EF_LIGHT_GREEN;
				eIonBall->v.TouchFunction	= IonRifle_IonBallTouch;

				eIonBall->Model.fScale	= 0.3f;

				eIonBall->Physics.iSolid	= SOLID_BBOX;
				eIonBall->Physics.eIgnore	= eOwner;

				eIonBall->local.eOwner	= eOwner;
				eIonBall->local.style	= 0;		// [29/1/2014] Preserve our firemode ~hogsy

				Math_VectorCopy(eOwner->v.origin,vOrigin);

				vOrigin[2] += 25.0f;

				Entity_SetModel(eIonBall,"models/ionball.md2");
				Entity_SetSizeVector(eIonBall,mv3Origin,mv3Origin);
				Entity_SetOrigin(eIonBall,vOrigin);

				{
					vec_t	*vAim = Engine.Aim(eOwner);

					Math_VectorScale(vAim,IONRIFLE_MAX_RANGE,eIonBall->v.velocity);
					Math_VectorCopy(vAim,eIonBall->v.avelocity);
				}

				Engine.LinkEntity(eIonBall,false);
			}
		}

		if(eOwner->local.attackb_finished > Server.dTime)
			eOwner->local.dAttackFinished = Server.dTime+0.5;
		else
			eOwner->local.dAttackFinished = Server.dTime+0.3;
	}

	// [17/11/2013] Update ammo counts... ~hogsy
	eOwner->v.iPrimaryAmmo = eOwner->local.ionblaster_ammo;
}
示例#25
0
/*	style
		0	Mikiko
		1	Superfly
*/
void Bot_Spawn(edict_t *eBot)
{
	int		iSpawnType;
	edict_t	*eSpawnPoint;

	// [20/1/2013] Don't spawn bots unless it's allowed by admin ~hogsy
	if(!cvServerBots.value)
		return;

	Math_VectorClear(eBot->v.velocity);

	// [29/7/2012] Names are now set here, the otherway was dumb ~hogsy
	switch(eBot->local.style)
	{
	case BOT_DEFAULT:
		iSpawnType = INFO_PLAYER_DEATHMATCH;

		eBot->v.model	= cvServerPlayerModel.string;
		eBot->v.netname	= BotNames[(rand()%pARRAYELEMENTS(BotNames))];

		eBot->monster.iType	= MONSTER_PLAYER;
		break;
#ifdef OPENKATANA
	case BOT_MIKIKO:
		iSpawnType = INFO_PLAYER_MIKIKO;

		Engine.Server_PrecacheResource(RESOURCE_MODEL,"models/mikiko.md2");

		eBot->v.model	= "models/mikiko.md2";
		eBot->v.netname	= "Mikiko Ebihara";

		eBot->monster.iType	= MONSTER_MIKIKO;
		break;
	case BOT_SUPERFLY:
		iSpawnType = INFO_PLAYER_SUPERFLY;

		Engine.Server_PrecacheResource(RESOURCE_MODEL,"models/sprfly.md2");
		Engine.Server_PrecacheResource(RESOURCE_SOUND,"player/superfly/superflydeath1.wav");
		Engine.Server_PrecacheResource(RESOURCE_SOUND,"player/superfly/superflydeath2.wav");
		Engine.Server_PrecacheResource(RESOURCE_SOUND,"player/superfly/superflydeath3.wav");
		Engine.Server_PrecacheResource(RESOURCE_SOUND,"player/superfly/superflydeath4.wav");

		eBot->v.model	= "models/sprfly.md2";
		eBot->v.netname	= "Superfly Johnson";

		eBot->monster.iType	= MONSTER_SUPERFLY;
		break;
#endif
	default:
		// [22/3/2013] Removed multiplayer support ~hogsy
		Engine.Con_Warning("Attempted to spawn unknown bot type! (%i) (%i %i %i)\n",
			eBot->local.style,
			(int)eBot->v.origin[0],
			(int)eBot->v.origin[1],
			(int)eBot->v.origin[2]);

		ENTITY_REMOVE(eBot);
	}

	eBot->v.cClassname	= "bot";
	eBot->v.iHealth		= 100;
	eBot->v.iMaxHealth	= (int)cvServerMaxHealth.value;
	eBot->v.movetype	= MOVETYPE_STEP;
	eBot->v.bTakeDamage	= true;

	eBot->Physics.iSolid	= SOLID_SLIDEBOX;
	eBot->Physics.fGravity	= SERVER_GRAVITY;
	eBot->Physics.fMass		= 1.4f;
	eBot->Physics.fFriction	= 4.0f;

	eBot->local.bBleed	= true;

	eBot->monster.Think = Bot_Think;

    // Mikiko and Superfly are set manually to avoid issues... ~hogsy
	if(eBot->local.style == BOT_DEFAULT)
	{
        // [16/7/2012] Must be set after teams are set up ~hogsy
        eSpawnPoint = Entity_SpawnPoint(eBot,iSpawnType);
        if(!eSpawnPoint)
        {
            Engine.Con_Warning("%s failed to find spawnpoint!\n",eBot->v.netname);
            ENTITY_REMOVE(eBot);
        }

        Entity_SetOrigin(eBot,eSpawnPoint->v.origin);
        SetAngle(eBot,eSpawnPoint->v.angles);
	}

	// [15/7/2012] Set the initial state to awake ~hogsy
	eBot->monster.think_die		= Bot_Die;
	eBot->monster.think_pain	= Bot_Pain;
	eBot->monster.Think			= Bot_Think;

	Entity_SetModel(eBot,eBot->v.model);
	Entity_SetSize(eBot,-16.0f,-16.0f,-24.0f,16.0f,16.0f,32.0f);

	Monster_SetState(eBot,STATE_AWAKE);
	Monster_SetThink(eBot,THINK_IDLE);

	// [6/8/2012] Make sure we're not in the air ~hogsy
	DropToFloor(eBot);
}
void Area_BreakableSpawn(ServerEntity_t *area) {
	if (area->v.health <= 0) {
        area->v.health = 1;
    }

	switch (area->local.style) {
	case BREAKABLE_GLASS:
		Server_PrecacheSound( PHYSICS_SOUND_GLASS0);
		Server_PrecacheSound( PHYSICS_SOUND_GLASS1);
		Server_PrecacheSound( PHYSICS_SOUND_GLASS2);
		Server_PrecacheModel(PHYSICS_MODEL_GLASS0);
		Server_PrecacheModel(PHYSICS_MODEL_GLASS1);
		Server_PrecacheModel(PHYSICS_MODEL_GLASS2);
		break;
	case BREAKABLE_WOOD:
		Server_PrecacheSound( PHYSICS_SOUND_WOOD0);
		Server_PrecacheSound( PHYSICS_SOUND_WOOD1);
		Server_PrecacheSound( PHYSICS_SOUND_WOOD2);
		Server_PrecacheModel(PHYSICS_MODEL_WOOD0);
		Server_PrecacheModel(PHYSICS_MODEL_WOOD1);
		Server_PrecacheModel(PHYSICS_MODEL_WOOD2);
		break;
	case BREAKABLE_ROCK:
		Server_PrecacheSound( PHYSICS_SOUND_ROCK0);
		Server_PrecacheSound( PHYSICS_SOUND_ROCK1);
		Server_PrecacheSound( PHYSICS_SOUND_ROCK2);
		Server_PrecacheModel(PHYSICS_MODEL_ROCK0);
		Server_PrecacheModel(PHYSICS_MODEL_ROCK1);
		Server_PrecacheModel(PHYSICS_MODEL_ROCK2);
		break;
	case BREAKABLE_METAL:
		Server_PrecacheSound( PHYSICS_SOUND_METAL0);
		Server_PrecacheSound( PHYSICS_SOUND_METAL1);
		Server_PrecacheSound( PHYSICS_SOUND_METAL2);
		Server_PrecacheModel(PHYSICS_MODEL_METAL0);
		Server_PrecacheModel(PHYSICS_MODEL_METAL1);
		Server_PrecacheModel(PHYSICS_MODEL_METAL2);
		break;
	default:
		g_engine->Con_Warning("area_breakable: Unknown style\n");
	}

	// If we've been given a name, then set our use function.
	if (area->v.name) {
        area->v.use = Area_BreakableUse;
    }

	area->Physics.solid = SOLID_BSP;

	area->v.movetype = MOVETYPE_PUSH;
	area->v.takedamage = true;

	area->local.bleed = false;

	Entity_SetKilledFunction(area, Area_BreakableDie);

	Entity_SetModel(area, area->v.model);
	Entity_SetOrigin(area, area->v.origin);
	Entity_SetSizeVector(area, area->v.mins, area->v.maxs);

	area->v.oldorigin.x = (area->v.mins.x + area->v.maxs.x) * 0.5f;
	area->v.oldorigin.y = (area->v.mins.y + area->v.maxs.y) * 0.5f;
	area->v.oldorigin.z = (area->v.mins.z + area->v.maxs.z) * 0.5f;
}
/*	style
		0	Mikiko
		1	Superfly
*/
void Bot_Spawn(ServerEntity_t *eBot)
{
	int				iSpawnType;
	ServerEntity_t	*eSpawnPoint;

	// Don't spawn bots unless it's allowed by admin.
	if(!cvServerBots.value)
		return;

	plClearVector3D(&eBot->v.velocity);

	switch(eBot->local.style)
	{
	case BOT_DEFAULT:
		iSpawnType = INFO_PLAYER_DEATHMATCH;

		eBot->v.model = cvServerPlayerModel.string;
		strncpy(eBot->v.netname, BotNames[(rand() % plArrayElements(BotNames))], 64);

		eBot->Monster.type	= MONSTER_PLAYER;
		break;
#ifdef GAME_OPENKATANA
	case BOT_COMPANION:
		iSpawnType = INFO_PLAYER_SUPERFLY;

		Server_PrecacheModel("models/sprfly.md2");					// TODO: Placeholder!
		Server_PrecacheSound("player/superfly/superflydeath1.wav");	// TODO: Placeholder!
		Server_PrecacheSound("player/superfly/superflydeath2.wav");	// TODO: Placeholder!
		Server_PrecacheSound("player/superfly/superflydeath3.wav");	// TODO: Placeholder!
		Server_PrecacheSound("player/superfly/superflydeath4.wav");	// TODO: Placeholder!

		eBot->v.model	= "models/sprfly.md2";	// TODO: Placeholder!
		eBot->v.netname = "Companion Bot";		// TODO: give a proper name??

		eBot->Monster.type = MONSTER_SUPERFLY;
		break;
#endif
	default:
		Engine.Con_Warning("Attempted to spawn unknown bot type! (%i) (%i %i %i)\n",
			eBot->local.style,
			(int)eBot->v.origin.x,
			(int)eBot->v.origin.y,
			(int)eBot->v.origin.z);

		Entity_Remove(eBot);
		return;
	}

	eBot->v.classname		= "bot";
	eBot->v.health			= 100;
	eBot->local.maxhealth = cvServerMaxHealth.iValue;
	eBot->v.movetype		= MOVETYPE_STEP;
	eBot->v.takedamage		= true;

	Entity_SetPhysics(eBot, SOLID_SLIDEBOX, 1.4f, 4.0f);

	eBot->local.bleed	= true;

	eBot->Monster.Frame = Bot_Frame;
	eBot->Monster.Pain	= Bot_Pain;

	// Default bots are purely for MP, so they spawn at player spawns.
	if(eBot->local.style == BOT_DEFAULT)
	{
		// Must be set after teams are set up.
		eSpawnPoint = Player_GetSpawnEntity(eBot, iSpawnType);
		if(!eSpawnPoint)
		{
			Engine.Con_Warning("%s failed to find spawnpoint!\n",eBot->v.netname);

			Entity_Remove(eBot);
			return;
		}

		Entity_SetOrigin(eBot,eSpawnPoint->v.origin);
		SetAngle(eBot,eSpawnPoint->v.angles);
	}

	Entity_SetKilledFunction(eBot, Bot_Die);

	eBot->Monster.Pain = Bot_Pain;
	eBot->Monster.Frame = Bot_Frame;

	Entity_SetModel(eBot,eBot->v.model);
	Entity_SetSize(eBot,-16.0f,-16.0f,-24.0f,16.0f,16.0f,32.0f);

	AI_SetState(eBot, AI_STATE_AWAKE);
	AI_SetThink(eBot, AI_THINK_IDLE);

	// Make sure we're not in the air.
	Entity_DropToFloor(eBot);
}
示例#28
0
void Point_PropSpawn(ServerEntity_t *eEntity)
{
	if(!eEntity->v.model)
		Entity_Remove(eEntity);

	eEntity->v.iHealth = 10;

	if(eEntity->v.iHealth)
	{
		switch(eEntity->local.style)
		{
			case BREAKABLE_GLASS:
				Server_PrecacheSound(PHYSICS_SOUND_GLASS0);
				Server_PrecacheSound(PHYSICS_SOUND_GLASS1);
				Server_PrecacheSound(PHYSICS_SOUND_GLASS2);
				Server_PrecacheModel(PHYSICS_MODEL_GLASS0);
				Server_PrecacheModel(PHYSICS_MODEL_GLASS1);
				Server_PrecacheModel(PHYSICS_MODEL_GLASS2);
				break;
			case BREAKABLE_WOOD:
				Server_PrecacheSound(PHYSICS_SOUND_WOOD0);
				Server_PrecacheSound(PHYSICS_SOUND_WOOD1);
				Server_PrecacheSound(PHYSICS_SOUND_WOOD2);
				Server_PrecacheModel(PHYSICS_MODEL_WOOD0);
				Server_PrecacheModel(PHYSICS_MODEL_WOOD1);
				Server_PrecacheModel(PHYSICS_MODEL_WOOD2);
				break;
			case BREAKABLE_ROCK:
				Server_PrecacheSound(PHYSICS_SOUND_ROCK0);
				Server_PrecacheSound(PHYSICS_SOUND_ROCK1);
				Server_PrecacheSound(PHYSICS_SOUND_ROCK2);
				Server_PrecacheModel("models/gibs/rock_gibs1.md2");
				Server_PrecacheModel("models/gibs/rock_gibs2.md2");
				Server_PrecacheModel("models/gibs/rock_gibs3.md2");
				break;
			case BREAKABLE_METAL:
				Server_PrecacheSound(PHYSICS_SOUND_METAL0);
				Server_PrecacheSound(PHYSICS_SOUND_METAL1);
				Server_PrecacheSound(PHYSICS_SOUND_METAL2);
				Server_PrecacheModel(PHYSICS_MODEL_METAL0);
				Server_PrecacheModel(PHYSICS_MODEL_METAL1);
				Server_PrecacheModel(PHYSICS_MODEL_METAL2);
				break;
			default:
				Engine.Con_Warning("Prop with unknown style! (%i)\n",eEntity->local.style);
		}

		eEntity->v.bTakeDamage = true;
		eEntity->local.bBleed = false;

		Entity_SetKilledFunction(eEntity, Area_BreakableDie);
	}

	Server_PrecacheModel(eEntity->v.model);

	eEntity->v.movetype			= MOVETYPE_BOUNCE;
	eEntity->v.TouchFunction	= Point_PropTouch;

	eEntity->Physics.iSolid		= SOLID_BBOX;
	eEntity->Physics.fGravity	= cvServerGravity.value;
	eEntity->Physics.fMass		= 0.5f;

	Entity_SetModel(eEntity,eEntity->v.model);
	Entity_SetOrigin(eEntity,eEntity->v.origin);
	Entity_SetSize(eEntity,-16.0f,-16.0f,-24.0f,16.0f,16.0f,32.0f);
}
void Area_DoorSpawn(ServerEntity_t *door)
{
	PLVector3D	movedir;

	if (door->local.cSoundStart) {
        Server_PrecacheSound(door->local.cSoundStart);
    }
	if (door->local.sound_stop) {
        Server_PrecacheSound(door->local.sound_stop);
    }
	if (door->local.cSoundMoving) {
        Server_PrecacheSound(door->local.cSoundMoving);
    }
	if (door->local.cSoundReturn) {
        Server_PrecacheSound(door->local.cSoundReturn);
    }

	door->v.movetype = MOVETYPE_PUSH;

	Entity_SetPhysics(door, SOLID_BSP, 1.0f, 1.0f);
	Entity_SetModel(door, door->v.model);
	Entity_SetOrigin(door, door->v.origin);
	Entity_SetSizeVector(door, door->v.mins, door->v.maxs);

	if (door->local.lip == 0) {
        door->local.lip = 4;
    }

    door->local.pos1 = door->v.origin;

	Area_SetMoveDirection(door->v.angles, door->v.movedir);

	movedir.x = std::fabs(door->v.movedir.x);
	movedir.y = std::fabs(door->v.movedir.y);
	movedir.z = std::fabs(door->v.movedir.z);

	float movedist =
		movedir.x * door->v.size.x +
		movedir.y * door->v.size.y +
		movedir.z * door->v.size.z -
		door->local.lip;

#if 0
	Math_VectorMake(door->local.pos1, movedist, door->v.movedir, door->local.pos2);
#else
    door->local.pos2 = door->local.pos1 + (door->v.movedir * movedist);
#endif

	door->local.flags = STATE_BOTTOM;

	// Set the spawn flags up.
	if (door->v.spawnflags & DOOR_FLAG_TRIGGERUSE) {
        door->v.use = Area_DoorUse;
    }
	if (door->v.spawnflags & DOOR_FLAG_TRIGGERTOUCH) {
        door->v.TouchFunction = Area_DoorTouch;
    }
	if (door->v.spawnflags & DOOR_FLAG_TRIGGERAUTO) {

	}
	if (door->v.spawnflags & DOOR_FLAG_TRIGGERDAMAGE) {
		// Give it at least one HP.
		if (!door->v.health) {
            door->v.health = 1;
        }

		door->v.takedamage = true;
		// TODO: add handler for this!
//		Entity_SetDamagedFunction(door, Area_DoorTouch);
	}

	if (door->local.damage) {
        Entity_SetBlockedFunction(door, Area_DoorBlocked);
    }
}
void Waypoint_Spawn(MathVector3f_t vOrigin,WaypointType_t type)
{
#ifdef	DEBUG_WAYPOINT
	char		*cModelName = WAYPOINT_MODEL_BASE;
#endif
	int			iPointContents;
	Waypoint_t	*wPoint;

	/*	TODO
		If we're between two other waypoints
		and they can be seen then slot ourselves
		in so that we act as the last waypoint
		instead.
	*/

	iPointContents = Engine.Server_PointContents(vOrigin);
	// [17/6/2012] Check that this area is safe ~hogsy
	if(iPointContents == BSP_CONTENTS_SOLID)
	{
		Engine.Con_Warning("Failed to place waypoint, position is within a solid!\n");
		return;
	}

	{
		Waypoint_t *wVisibleWaypoint = Waypoint_GetByVisibility(vOrigin);
		// [30/1/2013] Oops! Check we actually have a visible waypoint!! ~hogsy
		if(wVisibleWaypoint)
		{
			MathVector3f_t vDistance;

			Math_VectorSubtract(wVisibleWaypoint->position,vOrigin,vDistance);
			if(Math_VectorLength(vDistance) < MONSTER_RANGE_MEDIUM)
			{
				Engine.Con_Printf("Invalid waypoint position!\n");
				return;
			}
		}
	}

	wPoint = Waypoint_Allocate();
	if(!wPoint)
	{
		Engine.Con_Warning("Failed to allocate waypoint!\n");
		return;
	}

	Math_VectorCopy(vOrigin,wPoint->position);

	wPoint->number	= waypoint_count;
	wPoint->bOpen	= false;
	wPoint->next	= Waypoint_GetByNumber(wPoint->number+1);
	wPoint->last	= Waypoint_GetByNumber(wPoint->number-1);
	wPoint->wType	= type;

	switch(type)
	{
	case WAYPOINT_ITEM:
		wPoint->cName = "item";
#ifdef DEBUG_WAYPOINT
		cModelName	= WAYPOINT_MODEL_ITEM;
#endif
		break;
	case WAYPOINT_CLIMB:
		wPoint->cName = "climb";
		// TODO: Check that there's a ladder nearby.
#ifdef DEBUG_WAYPOINT
		cModelName	= WAYPOINT_MODEL_CLIMB;
#endif
		break;
	case WAYPOINT_COVER:
		wPoint->cName = "cover";
		// [27/12/2012] TODO: Check that this is actually cover ~hogsy
		break;
	case WAYPOINT_TYPE_JUMP:
		wPoint->cName = "jump";
		// [27/12/2012] TODO: Check if this is actually a jump by tracing out ahead ~hogsy
#ifdef DEBUG_WAYPOINT
		cModelName	= WAYPOINT_MODEL_JUMP;
#endif
		break;
	case WAYPOINT_TYPE_SWIM:
		if(iPointContents != BSP_CONTENTS_WATER)
		{
			Engine.Con_Warning("Waypoint with type swim not within water contents (%i %i %i)!",
				(int)vOrigin[0],
				(int)vOrigin[1],
				(int)vOrigin[2]);

			Waypoint_Delete(wPoint);
			return;
		}

		wPoint->cName = "swim";
#ifdef DEBUG_WAYPOINT
		cModelName	= WAYPOINT_MODEL_SWIM;
#endif
		break;
	case WAYPOINT_TYPE_DEFAULT:
		wPoint->cName = "default";
		break;
	case WAYPOINT_SPAWN:
		wPoint->cName = "spawn";
		break;
	default:
		Engine.Con_Warning("Unknown waypoint type (%i)!\n",type);

		Waypoint_Delete(wPoint);
		return;
	}

	// [30/1/2013] Pathetic reordering... Ugh ~hogsy
	if(!wPoint->last)
	{
		wPoint->last = Waypoint_GetByVisibility(vOrigin);
		if(!wPoint->last)
		{
			Engine.Con_Warning("Failed to get another visible waypoint! (%i)\n",wPoint->number);
			return;
		}
	}
	else if(wPoint->last != wPoint && wPoint->last->next)
		wPoint->last->next = wPoint;

#ifdef DEBUG_WAYPOINT
	wPoint->eDebug = Entity_Spawn();
	if(wPoint->eDebug)
	{
		wPoint->eDebug->v.effects = EF_MOTION_ROTATE;

		Entity_SetModel(wPoint->eDebug,cModelName);
		Entity_SetSizeVector(wPoint->eDebug,g_mvOrigin3f,g_mvOrigin3f);
		Entity_SetOrigin(wPoint->eDebug,wPoint->position);
	}

	Engine.Con_DPrintf("Waypoint placed (%i %i %i)\n",
		(int)wPoint->position[0],
		(int)wPoint->position[1],
		(int)wPoint->position[2]);
	Engine.Con_DPrintf(" number: %i\n",wPoint->number);
	Engine.Con_DPrintf(" type:   %i\n",wPoint->wType);
#endif
}