Example #1
0
Entity* Bullet_Create(float x, float y,
                      float angle,
                      Weapon* parent)
{
	Entity* bullet = Entity_Spawn();

	bullet->t = Cat_Bullet;
	bullet->sub_category = parent->type;
	bullet->x = x;
	bullet->y = y;
	bullet->movementC = MovementC_Create();
	bullet->angle = angle;
	bullet->movementC->speed = parent->bullet_speed;
    bullet->movementC->dx = cos(angle) * bullet->movementC->speed;
    bullet->movementC->dy = sin(angle) * bullet->movementC->speed;
	bullet->is_ennemy = parent->is_monster;
	bullet->alive_timer = (1/bullet->movementC->speed) * 1500;
	bullet->damage = parent->bullet_damage;


    bullet->box.height = parent->bullet_height;
    bullet->box.width = parent->bullet_width;
    bullet->penetration_chance = parent->bullet_penetration_chance;
    bullet->last_zombie_hit = NULL;
    BoundingBox_Create(bullet, bullet->box.width, bullet->box.height);
	return bullet;
}
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 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;
}
// [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 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;
	}
}
Example #6
0
Entity* Decal_Create(Decal_Type type, float x, float y, float angle)
{
    Entity* decals = Entity_Spawn();
    decals->solid = false;
    decals->t = Cat_Decal;
    decals->sub_category = type;
    //alright so angle shouldn't be in movementC... F**K
    decals->movementC = MovementC_Create();
    decals->angle = angle;

    int width = 40;
    int height = 40;
    switch(type)
    {
    case Decal_Corpse_Normal:
        break;
    case Decal_Corpse_Heavy:
        break;
    case Decal_Corpse_Trooper:
        width = 60;
        height = 45;
        break;
    case Decal_Corpse_Fast:
        break;
    case Decal_Corpse_Huge:
        width = 150;
        height = 150;
        break;
    case Decal_Corpse_Raptor:
        width = 120;
        height = 120;
        break;
    case Decal_Corpse_Destroyer:
        width = 260;
        height = 260;
        break;
    case Decal_Rug_Ancient:
        width = 20;
        height = 60;
        break;
    }

    if(type != Decal_Rug_Ancient )
    {
        decals->is_ennemy = true;
    }


    decals->box = BoundingBox_CreateBetter(x, y, width, height);
    decals->x = x;
    decals->y = y;

    return decals;

}
// [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);
}
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 Hermes_PrimaryAttack(edict_t *ent)
{
	float	*dir;
	edict_t *cloud = Entity_Spawn();

	cloud->v.cClassname = "cloud";
	cloud->v.movetype	= MOVETYPE_FLYMISSILE;
	cloud->Physics.iSolid		= SOLID_TRIGGER;

	cloud->local.hit	= 10;
	cloud->local.eOwner	= ent;

	//SetSize(cloud,-16,-16,-16,16,16,16);
	Entity_SetOrigin(cloud,ent->v.origin);

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

	dir = Engine.Aim(ent);
	cloud->v.velocity[0]	= dir[0]*100;
	cloud->v.velocity[1]	= dir[1]*100;
	cloud->v.velocity[2]	= dir[2]*100;
	cloud->v.dNextThink		= Server.dTime+0.3;
	cloud->v.think			= Hermes_CloudThink;
	cloud->v.TouchFunction	= HermesCloudTouch;

	Math_VectorAddValue(cloud->v.avelocity,300.0f,cloud->v.avelocity);

	if(ent->local.attackb_finished > Server.dTime)	// No attack boost...
		ent->local.dAttackFinished = Server.dTime+0.35;
	else
		ent->local.dAttackFinished = Server.dTime+0.7;

#if 0
	if(rand()%3 == 1)
		//Weapon_Animate(ent,FALSE,12,17,0.07f,10,19,0,FALSE);
	else if(rand()%3 == 2)
		//Weapon_Animate(ent,FALSE,18,23,0.07f,10,19,0,FALSE);
	else
		//Weapon_Animate(ent,FALSE,24,29,0.07f,10,19,0,FALSE);
#endif
}
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());
	}
}
ServerEntity_t *Area_SpawnTriggerField(ServerEntity_t *owner,
                                       PLVector3D mins, PLVector3D maxs,
                                       void (*TriggerFunction)(ServerEntity_t *entity, ServerEntity_t *other)) {
	if ((mins == 0) || (maxs == 0)) {
		g_engine->Con_Warning("Invalid size for trigger field!");
		return NULL;
	}

	ServerEntity_t *field = Entity_Spawn();
	field->v.movetype		= MOVETYPE_NONE;
	field->local.owner		= owner;

	Entity_SetTouchFunction(field, TriggerFunction);
	Entity_SetPhysics(field, SOLID_TRIGGER, 0, 0);
	
	// Set the size of it.
	PLVector3D tmins = mins, tmaxs = maxs;
	tmins.x -= 60;	tmins.y -= 60;	tmins.z -= 8;
	tmaxs.x += 60;	tmaxs.y += 60;	tmaxs.z += 8;
	Entity_SetSizeVector(field, tmins, tmaxs);

	return field;
}
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;
}
void Hermes_PrimaryAttack(ServerEntity_t *ent)
{
	ServerEntity_t *cloud = Entity_Spawn();

	cloud->v.classname = "cloud";
	cloud->v.movetype	= MOVETYPE_FLYMISSILE;
	cloud->Physics.solid		= SOLID_TRIGGER;

	cloud->local.hit	= 10;
	cloud->local.owner	= ent;

	//SetSize(cloud,-16,-16,-16,16,16,16);
	Entity_SetOrigin(cloud,ent->v.origin);

	Weapon_Projectile(ent, cloud, 100.0f);

	cloud->v.nextthink		= Server.time+0.3;
	cloud->v.think			= Hermes_CloudThink;
	cloud->v.TouchFunction	= HermesCloudTouch;

    plAddVector3Df(&cloud->v.avelocity, 300);

	if(ent->local.attackb_finished > Server.time)	// No attack boost...
		ent->local.dAttackFinished = Server.time+0.35;
	else
		ent->local.dAttackFinished = Server.time+0.7;

#if 0
	if(rand()%3 == 1)
		//Weapon_Animate(ent,FALSE,12,17,0.07f,10,19,0,FALSE);
	else if(rand()%3 == 2)
		//Weapon_Animate(ent,FALSE,18,23,0.07f,10,19,0,FALSE);
	else
		//Weapon_Animate(ent,FALSE,24,29,0.07f,10,19,0,FALSE);
#endif
}
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
}
/*	Called when a monster/entity gets killed.
*/
void Monster_Killed(edict_t *eTarget,edict_t *eAttacker)
{
	if(eTarget->monster.iState == STATE_DEAD)
		return;

	if(Entity_IsMonster(eTarget))
	{
		WriteByte(MSG_ALL,SVC_KILLEDMONSTER);

		Server.iMonsters--;
		eAttacker->v.iScore++;

#if 0
		// Update number of frags for client.
		Engine.SetMessageEntity(eAttacker);
		Engine.WriteByte(MSG_ONE,SVC_UPDATESTAT);
		Engine.WriteByte(MSG_ONE,STAT_FRAGS);
		Engine.WriteByte(MSG_ONE,eAttacker->v.iScore);
#endif
	}
	else if(Entity_IsPlayer(eAttacker) && bIsMultiplayer)
	{
		char *cDeathMessage = "%s was killed by %s\n";

		if(eTarget == eAttacker)
		{
			cDeathMessage = "%s killed himself!\n";

			eAttacker->v.iScore--;
		}
		else if(Entity_IsPlayer(eTarget) && bIsCooperative)
		{
			cDeathMessage = "%s was tk'd by %s (what a dick, huh?)";

			eAttacker->v.iScore--;
		}
		// [2/9/2012] Did we kill someone while dead? ~hogsy
		else
		{
			eAttacker->v.iScore++;

			// [15/12/2013] Extra points! ~hogsy
			if(eAttacker->v.iHealth <= 0)
			{
				// [3/10/2012] TODO: Play sound ~hogsy
				Engine.CenterPrint(eAttacker,"FROM BEYOND THE GRAVE!\n");

				cDeathMessage = "%s was killed from beyond the grave by %s\n";

				eAttacker->v.iScore += 2;
			}

			// [15/12/2013] Extra points! ~hogsy
			if(!(eTarget->v.flags & FL_ONGROUND))
			{
				// [25/6/2012] TODO: Play sound ~hogsy
				Engine.CenterPrint(eAttacker,"WATCH THEM DROP!\n");

				cDeathMessage = "%s was shot out of the air by %s\n";

				eAttacker->v.iScore += 2;
			}
		}

		// Update number of frags for client.
		Engine.SetMessageEntity(eAttacker);
		Engine.WriteByte(MSG_ONE,SVC_UPDATESTAT);
		Engine.WriteByte(MSG_ONE,STAT_FRAGS);
		Engine.WriteByte(MSG_ONE,eAttacker->v.iScore);

		// TODO: move Kill messages into mode_deathmatch (?) Create Weapon specific kill messages and more variations! ~eukos
		Engine.Server_BroadcastPrint(cDeathMessage,eTarget->v.netname,eAttacker->v.netname);
	}
	else
		eTarget->v.bTakeDamage = false;

#ifdef GAME_OPENKATANA
    // [22/4/2014] Drop the currently equipped item for the player to pick up! ~hogsy
    {
        Weapon_t *wActive = Weapon_GetCurrentWeapon(eTarget);
        if(wActive && (wActive->iItem != WEAPON_LASERS))
        {
            edict_t *eDroppedItem = Entity_Spawn();

            Math_VectorCopy(eTarget->v.origin,eDroppedItem->v.origin);

            eDroppedItem->local.style = wActive->iItem;

            Item_Spawn(eDroppedItem);
        }
    }
#endif

	if(eTarget->monster.think_die)
		eTarget->monster.think_die(eTarget,eAttacker);

	// Update our current state.
	eTarget->monster.iState = STATE_DEAD;
}
/*	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;
}
Example #17
0
void Level_Load(char* file_name, World* w)
{
    Level_Clear(w);


    FILE *save_file;

    save_file = fopen(file_name, "rb");
    if(!save_file)
    {
        printf("Can't open file");

    }
    printf("gggggg");
    int nb_of_walls = 0;
    fread(&nb_of_walls, sizeof(int), 1, save_file);

    for(int i = 0 ; i < nb_of_walls ; i++)
    {
        Entity* buffer = (Entity*)malloc(sizeof(Entity)); //Entity_Spawn();
        fread(buffer, sizeof(Entity), 1, save_file);
        int position_in_array = buffer->x / TILE_SIZE + ((buffer->y/ TILE_SIZE) * w->map_width);

        w->map[position_in_array] = buffer;

    }


    for(int i = 0 ; i < w->map_size ; i++)
    {
        Entity* buffer = (Entity*)malloc(sizeof(Entity)); //Entity_Spawn();
        fread(buffer, sizeof(Entity), 1, save_file);
        int position_in_array = buffer->x / TILE_SIZE + ((buffer->y/ TILE_SIZE) * w->map_width);

        w->ground_map[position_in_array] = buffer;
    }

    printf("mdr");
    int num_of_events = 0;
    fread(&num_of_events, sizeof(int), 1, save_file);
    for(int i = 0 ; i < num_of_events ; i++)
    {
        Entity* buffer  = Entity_Spawn();
        LevelEditor_ReadEntity(save_file, buffer, w);

        Vector_Push(&w->events_vector, buffer);

    }
printf("mdr");
    int num_of_props = 0;
    fread(&num_of_props, sizeof(int), 1, save_file);
    for(int i = 0 ; i < num_of_props; i++)
    {
        Entity* buffer  = Entity_Spawn();
        LevelEditor_ReadEntity(save_file, buffer, w);

        Vector_Push(&w->props_vector, buffer);

    }

    int num_of_zombies = 0;
    fread(&num_of_zombies, sizeof(int), 1, save_file);

    printf("Loading %d mobs\n", num_of_zombies);
    if(num_of_zombies != 0)
    {
        for(int i = 0 ; i < num_of_zombies ; i++)
        {
            Entity* buffer  = Entity_Spawn();
            LevelEditor_ReadEntity(save_file, buffer, w);
            Vector_Push(&w->monsters_vector, buffer);

        }
    }

    int num_of_decalss = 0;
    fread(&num_of_decalss, sizeof(int), 1, save_file);
        printf("Loading %d decals\n", num_of_decalss);
    for(int i = 0 ; i < num_of_decalss ; i++)
    {
        Entity* buffer  = Entity_Spawn();
        LevelEditor_ReadEntity(save_file, buffer, w);
        Vector_Push(&w->decals_vector, buffer);

    }


    int num_of_bonus = 0;
    fread(&num_of_bonus, sizeof(int), 1, save_file);
    for(int i = 0 ; i < num_of_bonus ; i++)
    {
        Entity* buffer = Entity_Spawn();
        LevelEditor_ReadEntity(save_file, buffer, w);
        Vector_Push(&w->bonus_vector, buffer);

    }



    fclose(save_file);
}
Example #18
0
Entity* Prop_Create(Bonus_type type, float x, float y, float angle)
{
    Entity* prop        = Entity_Spawn();
    prop->x             = x;
    prop->y             = y;
    prop->t             = Cat_Prop;
    prop->sub_category  = type;
    prop->angle         = angle;
    prop->hp            = 10;

    /*bbox changes depending on the angle*/
    int true_x, true_y, true_width, true_height;

    switch(type)
    {
    case Prop_Bed:
        prop->width     = 32;
        prop->height    = 64;
        break;
    case Prop_Desk:
        prop->width     = 25;
        prop->height    = 40;
        break;
    case Prop_Chair:
        prop->width     = 20;
        prop->height    = 20;
        break;
    case Prop_Car_Cool:
        prop->width     = 60;
        prop->height    = 120;
        prop->hp        = 25;
        break;
    case Prop_Bookcase:
        prop->width     = 32;
        prop->height    = 32;
        break;
    case Prop_FileCabinet:
        prop->width     = 32;
        prop->height    = 32;
        break;
    case Prop_BlackChest:
        prop->width     = 32;
        prop->height    = 32;
        break;
    case Prop_Refrigerator:
        prop->width     = 32;
        prop->height    = 32;
        break;
    case Prop_Kitchen_Stove:
        prop->width     = 32;
        prop->height    = 32;
        break;
    case Prop_Kitchen_Table:
        prop->width     = 32;
        prop->height    = 32;
        break;
    case Prop_Couch_Blue:
        prop->width     = 64;
        prop->height    = 32;
        break;
    case Prop_Plant:
        prop->width     = 24;
        prop->height    = 24;
        break;
    case Prop_LivingRoom_TV:
        prop->width     = 64;
        prop->height    = 32;
        break;
    case Prop_Office_Desk_Computer:
        prop->width     = 64;
        prop->height    = 26;
        break;
    case Prop_Bathroom_Sink:
        prop->width     = 32;
        prop->height    = 26;
        break;
    case Prop_Bathtub:
        prop->width     = 64;
        prop->height    = 32;
        break;
    case Prop_WC:
        prop->width     = 32;
        prop->height    = 32;
        break;
    case Prop_Cupboard:
        prop->width     = 64;
        prop->height    = 32;
        break;
    case Prop_Dining_Room_Table_Large:
        prop->width     = 64;
        prop->height    = 96;
        break;
    }

    true_width =  prop->width;
    true_height = prop->height;
    true_x = x;
    true_y = y;
    int xCenter = x + prop->width / 2;
    int yCenter = y + prop->height / 2;

    if(angle > HALF_PI - 0.1 && angle < HALF_PI + 0.1)
    {
        true_x = xCenter - (cos(angle) * (x - xCenter)) + (sin(angle) * (y - yCenter));
        true_y = yCenter + sin(angle) * (x - xCenter) + cos(angle) * (y - yCenter);

        true_width = prop->height;
        true_height = prop->width;

    }
    else if(angle > PI + HALF_PI - 0.1 && angle < PI + HALF_PI + 0.1)
    {
        true_x = xCenter + cos(angle) * (x - xCenter) - sin(angle) * (y - yCenter);
        true_y = yCenter - sin(angle) * (x - xCenter) + cos(angle) * (y - yCenter);
        true_width = prop->height;
        true_height = prop->width;
    }

    prop->box = BoundingBox_CreateBetter(true_x, true_y, true_width, true_height);




    return prop;
}