コード例 #1
0
void Bot_Pain(ServerEntity_t *ent, ServerEntity_t *other, EntityDamageType_t type)
{
	char sound[MAX_QPATH];
	Weapon_t *myweapon, *hisweapon;

	// Let the player know how we're feeling.
	Bot_BroadcastMessage(ent,other);

	// Get both mine and our enemies weapon.
	myweapon    = Weapon_GetCurrentWeapon(ent);
	hisweapon   = Weapon_GetCurrentWeapon(other);
	if(!myweapon || (!Weapon_CheckPrimaryAmmo(myweapon,ent) && myweapon->primary_type != AM_MELEE)) {
		AI_SetThink(ent, AI_THINK_FLEEING);
		return;
	}
	// Otherwise check what we can see our enemy having (don't check ammo since it's unrealistic).
	else if(!hisweapon || hisweapon->primary_type == AM_MELEE) {
		// We see you!
		if(Monster_IsVisible(ent,other))
		{
			AI_SetThink(ent, AI_THINK_ATTACKING);
			return;
		}
	}

#if 0
	// [16/7/2012] Moved to avoid a situation where we try fleeing without a target ~hogsy
	if(	(ent->v.enemy && other->v.health > ent->v.enemy->v.health) ||
		!ent->v.enemy)
		// [15/7/2012] Reckless but change our target to this new enemy ~hogsy
		ent->v.enemy = other;

	mywep	= Weapon_GetCurrentWeapon(ent);
	hisweapon	= Weapon_GetCurrentWeapon(other);

	// [15/7/2012] Check that I have a weapon and ammo ~hogsy
	if(!mywep || ent->v.currentammo <= 0)
	{
		// [15/7/2012] I don't! Find the closest waypoint to move back to a little ~hogsy
		point = Waypoint_GetByVisibility(ent->v.origin);
POINTCHECK:
		if(!point)
			return;
		if(	point->type	== WAYPOINT_WEAPON	||
			point->type == WAYPOINT_COVER	||
			point->type == WAYPOINT_TYPE_DEFAULT)
		{
			AI_SetThink(ent,MONSTER);

			// [15/7/2012] Set the position we'll move to next ~hogsy
			Math_VectorCopy(ent->Monster.target,point->position);
		}
		else
		{
			// [15/7/2012] Keep on checking until we get something ~hogsy
			if(pointchecks >= 5)
			{
				// [15/7/2012] Didn't get anything... ~hogsy
				return;
			}
			pointchecks++;

			point = Waypoint_GetByVisibility(point->position);
			goto POINTCHECK;
		}

		return;
	}
	// [15/7/2012] Okay, he doesn't have a weapon ~hogsy
	else if(!hisweapon)
		// [15/7/2012] Since it's probably not even a player ~hogsy
		return;
#endif

#ifdef GAME_OPENKATANA
	switch(ent->local.style)
	{
	case BOT_COMPANION:
		if(ent->v.watertype == BSP_CONTENTS_WATER && ent->v.waterlevel == 3)
		{
		}
		else
			sprintf(sound,"player/mikiko/mikikodeath%i.wav",rand()%5+1);
		break;
	default:
#endif
		if(ent->v.watertype == BSP_CONTENTS_WATER && ent->v.waterlevel == 3)
		{
			if(rand()%2 == 1)
				sprintf(sound,"player/playerchoke1.wav");
			else
				sprintf(sound,"player/playerchoke3.wav");
		}
		else
			sprintf(sound,"player/playerpain%i.wav",rand()%4+1);
#ifdef GAME_OPENKATANA
	}
#endif

	Sound(ent,CHAN_VOICE,sound,255,ATTN_NORM);
}
コード例 #2
0
void Bot_Think(edict_t *eBot)
{
	// If the bot isn't dead, then add animations.
	if(eBot->monster.iState != STATE_DEAD)
	{
		if(eBot->v.flags & FL_ONGROUND)
		{
			if((	(eBot->v.velocity[0] < -4.0f || eBot->v.velocity[0] > 4.0f)	|| 
					(eBot->v.velocity[1] < -4.0f || eBot->v.velocity[1] > 4.0f))	&& 
					(!eBot->local.dAnimationTime || eBot->local.iAnimationEnd == 9))
				Entity_Animate(eBot,PlayerAnimation_Walk);
			else if((eBot->v.velocity[0] == 0 || eBot->v.velocity[1] == 0) && (!eBot->local.dAnimationTime || eBot->local.iAnimationEnd > 9))
			{
	#ifdef GAME_OPENKATANA
				if(eBot->v.iActiveWeapon == WEAPON_DAIKATANA)
					Entity_Animate(eBot,PlayerAnimation_KatanaIdle);
				else
	#endif
					Entity_Animate(eBot,PlayerAnimation_Idle);
			}
		}
	}

	switch(eBot->monster.iThink)
	{
	case THINK_IDLE:
#if 1
		// Add some random movement. ~hogsy
		if(rand()%120 == 0)
		{
			int	iResult = rand()%3;

			if(iResult == 0)
				eBot->v.velocity[0] += BOT_MIN_SPEED;
			else if(iResult == 1)
				eBot->v.velocity[0] -= BOT_MIN_SPEED;

			iResult = rand()%3;
			if(iResult == 0)
				eBot->v.velocity[1] += BOT_MIN_SPEED;
			else if(iResult == 1)
				eBot->v.velocity[1] -= BOT_MIN_SPEED;

			eBot->v.angles[1] = Math_VectorToYaw(eBot->v.velocity);
		}
		else if(rand()%150 == 0)
		{
			Monster_Jump(eBot,200.0f);

			Entity_Animate(eBot,PlayerAnimation_Jump);
		}
#endif
		break;
	case THINK_WANDERING:
		{
			edict_t		*eTarget;
			Waypoint_t	*wPoint;
//			Weapon_t	*wMyWeapon;
//			vec3_t		vAngle;

			eTarget = Monster_GetTarget(eBot);
			if(eTarget)
			{
				if(Monster_GetRelationship(eBot,eTarget) == RELATIONSHIP_HATE)
				{
					// [22/3/2013] Begin attacking next frame ~hogsy
					Monster_SetThink(eBot,THINK_ATTACKING);
					return;
				}
			}

			if(!eBot->monster.vTarget)
			{
				// [28/7/2012] TODO: Find specific waypoint such as an item ~hogsy
				wPoint = Waypoint_GetByVisibility(eBot->v.origin);
				if(wPoint)
				{
					if(wPoint->bOpen)
					{
						// [22/3/2013] TODO: Tell that current entity it's time to move... ~hogsy
					}

					Math_VectorCopy(wPoint->position,eBot->monster.vTarget);
				}
			}

#if 0
			wMyWeapon = Weapon_GetCurrentWeapon(eBot);
			if(MONSTER_GetRange(eBot,eBot->v.enemy->v.origin) > 4000)
				return;
			else if(wMyWeapon->iPrimaryType == AM_MELEE && MONSTER_GetRange(eBot,eBot->v.enemy->v.origin) > MONSTER_RANGE_MELEE)
				return;
			else if(Monster_IsVisible(eBot,eBot->v.enemy))
			{
				// [5/8/2012] No ammo and it's not a melee weapon? ~hogsy
				if(!Weapon_CheckPrimaryAmmo(eBot) && wMyWeapon->iPrimaryType != AM_MELEE)
				{
					// [5/8/2012] Should probably flee ~hogsy
					Monster_SetThink(eBot,THINK_FLEEING);
					return;
				}

				Math_VectorSubtract(eBot->v.enemy->v.origin,eBot->v.origin,vAngle);

		//		ent->v.ideal_yaw	= VectorToAngles(vAngle);

				ChangeYaw(eBot);
			}
#endif
		}
		break;
	}
}
コード例 #3
0
void Bot_Pain(edict_t *ent,edict_t *other)
{
	char		sound[MAX_QPATH];
	Weapon_t	*wMyWeapon,*wHisWeapon;

	// [4/10/2012] Let the player know how we're feeling :) ~hogsy
	Bot_BroadcastMessage(ent,other);

	// [14/9/2012] Get both mine and our enemies weapon ~hogsy
	wMyWeapon	= Weapon_GetCurrentWeapon(ent);
	wHisWeapon	= Weapon_GetCurrentWeapon(other);
	if(!wMyWeapon || (!Weapon_CheckPrimaryAmmo(wMyWeapon,ent) && wMyWeapon->iPrimaryType != AM_MELEE))
	{
		Monster_SetThink(ent,THINK_FLEEING);
		return;
	}
	// [14/9/2012] Otherwise check what we can see our enemy having (don't check ammo since it's unrealistic) ~hogsy
	else if(!wHisWeapon || wHisWeapon->iPrimaryType == AM_MELEE)
	{
		// [14/9/2012] We see you!! ~hogsy
		if(Monster_IsVisible(ent,other))
		{
			Monster_SetEnemy(other);
			Monster_SetThink(ent,THINK_ATTACKING);
			return;
		}
	}

#if 0
	// [16/7/2012] Moved to avoid a situation where we try fleeing without a target ~hogsy
	if(	(ent->v.enemy && other->v.iHealth > ent->v.enemy->v.iHealth) ||
		!ent->v.enemy)
		// [15/7/2012] Reckless but change our target to this new enemy ~hogsy
		ent->v.enemy = other;

	mywep	= Weapon_GetCurrentWeapon(ent);
	wHisWeapon	= Weapon_GetCurrentWeapon(other);

	// [15/7/2012] Check that I have a weapon and ammo ~hogsy
	if(!mywep || ent->v.currentammo <= 0)
	{
		// [15/7/2012] I don't! Find the closest waypoint to move back to a little ~hogsy
		point = Waypoint_GetByVisibility(ent->v.origin);
POINTCHECK:
		if(!point)
			return;
		if(	point->type	== WAYPOINT_WEAPON	||
			point->type == WAYPOINT_COVER	||
			point->type == WAYPOINT_DEFAULT)
		{
			Monster_SetThink(ent,MONSTER);

			// [15/7/2012] Set the position we'll move to next ~hogsy
			Math_VectorCopy(ent->monster.target,point->position);
		}
		else
		{
			// [15/7/2012] Keep on checking until we get something ~hogsy
			if(pointchecks >= 5)
			{
				// [15/7/2012] Didn't get anything... ~hogsy
				return;
			}
			pointchecks++;

			point = Waypoint_GetByVisibility(point->position);
			goto POINTCHECK;
		}

		return;
	}
	// [15/7/2012] Okay, he doesn't have a weapon ~hogsy
	else if(!wHisWeapon)
		// [15/7/2012] Since it's probably not even a player ~hogsy
		return;
#endif

#ifdef OPENKATANA
	// [26/7/2012] Character-based sounds ~hogsy
	// [29/7/2012] Revised ~hogsy
	switch(ent->local.style)
	{
	case BOT_MIKIKO:
		if(ent->v.watertype == BSP_CONTENTS_WATER && ent->v.waterlevel == 3)
		{
		}
		else
			sprintf(sound,"player/mikiko/mikikodeath%i.wav",rand()%5+1);
		break;
	case BOT_SUPERFLY:
		if(ent->v.watertype == BSP_CONTENTS_WATER && ent->v.waterlevel == 3)
		{
		}
		else
			sprintf(sound,"player/superfly/superflydeath%i.wav",rand()%4+1);
		break;
	default:
#endif
		if(ent->v.watertype == BSP_CONTENTS_WATER && ent->v.waterlevel == 3)
		{
			if(rand()%2 == 1)
				sprintf(sound,"player/playerchoke1.wav");
			else
				sprintf(sound,"player/playerchoke3.wav");
		}
		else
			sprintf(sound,"player/playerpain%i.wav",rand()%4+1);
#ifdef OPENKATANA
	}
#endif

	Sound(ent,CHAN_VOICE,sound,255,ATTN_NORM);
}
コード例 #4
0
/*	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;
}