Exemplo n.º 1
0
/**
 * @brief Stun all members of a giben team.
 */
static void G_StunTeam_f (void)
{
    /* default is to kill all teams */
    int teamToKill = -1;
    edict_t *ent = NULL;

    /* with a parameter we will be able to kill a specific team */
    if (gi.Cmd_Argc() == 2)
        teamToKill = atoi(gi.Cmd_Argv(1));

    if (teamToKill >= 0) {
        while ((ent = G_EdictsGetNextLivingActorOfTeam(ent, teamToKill))) {
            /* stun */
            G_ActorDieOrStun(ent, NULL);

            if (teamToKill == TEAM_ALIEN)
                level.num_stuns[TEAM_PHALANX][TEAM_ALIEN]++;
            else
                level.num_stuns[TEAM_ALIEN][teamToKill]++;
        }
    }

    /* check for win conditions */
    G_MatchEndCheck();
}
Exemplo n.º 2
0
void G_CheckDeathOrKnockout (edict_t *target, edict_t *attacker, const fireDef_t *fd, int damage)
{
	/* Check death/knockout. */
	if (target->HP == 0 || target->HP <= target->STUN) {
		G_SendStats(target);

		if (G_ActorDieOrStun(target, attacker)) {
			G_PrintActorStats(target, attacker, fd);

			/* apply morale changes */
			if (mor_panic->integer)
				G_Morale(ML_DEATH, target, attacker, damage);

			/* Update number of killed/stunned actors for this attacker. */
			G_UpdateCharacterBodycount(attacker, fd, target);
		}
	} else {
		target->chr.minHP = std::min(target->chr.minHP, target->HP);
		if (damage > 0) {
			if (mor_panic->integer)
				G_Morale(ML_WOUND, target, attacker, damage);
		} else { /* medikit, etc. */
			const int hp = GET_HP(target->chr.score.skills[ABILITY_POWER]);
			if (target->HP > hp) {
				target->HP = std::min(std::max(hp, 0), target->chr.maxHP);
			}
		}
		G_SendStats(target);
	}
}
Exemplo n.º 3
0
/**
 * @brief This function does not add statistical values. Because there is no attacker.
 * The same counts for morale states - they are not affected.
 * @note: This is a debug function to let a whole team die
 */
static void G_KillTeam_f (void)
{
    /* default is to kill all teams */
    int teamToKill = -1;
    edict_t *ent = NULL;
    int amount = -1;

    /* with a parameter we will be able to kill a specific team */
    if (gi.Cmd_Argc() >= 2) {
        teamToKill = atoi(gi.Cmd_Argv(1));
        if (gi.Cmd_Argc() == 3)
            amount = atoi(gi.Cmd_Argv(2));
    }

    Com_DPrintf(DEBUG_GAME, "G_KillTeam: kill team %i\n", teamToKill);

    if (teamToKill >= 0) {
        while ((ent = G_EdictsGetNextLivingActorOfTeam(ent, teamToKill))) {
            if (amount == 0)
                break;
            /* die */
            ent->HP = 0;
            G_ActorDieOrStun(ent, NULL);

            if (teamToKill == TEAM_ALIEN)
                level.num_kills[TEAM_PHALANX][TEAM_ALIEN]++;
            else
                level.num_kills[TEAM_ALIEN][teamToKill]++;
            amount--;
        }
    }

    /* check for win conditions */
    G_MatchEndCheck();
}
Exemplo n.º 4
0
void G_CheckDeathOrKnockout (Edict* target, Edict* attacker, const fireDef_t* fd, int damage)
{
	/* Sanity check */
	target->HP = std::min(std::max(target->HP, 0), target->chr.maxHP);
	/* Check death/knockout. */
	if (target->HP == 0 || target->HP <= target->STUN) {
		G_SendStats(*target);

		if (G_ActorDieOrStun(target, attacker)) {
			G_PrintActorStats(target, attacker, fd);

			/* apply morale changes */
			if (mor_panic->integer)
				G_Morale(ML_DEATH, target, attacker, damage);

			/* Update number of killed/stunned actors for this attacker. */
			G_UpdateCharacterBodycount(attacker, fd, target);
		}
	} else {
		target->chr.minHP = std::min(target->chr.minHP, target->HP);
		if (damage > 0) {
			if (mor_panic->integer)
				G_Morale(ML_WOUND, target, attacker, damage);
		}
		G_SendStats(*target);
	}
}
Exemplo n.º 5
0
TEST_F(GameTest, InventoryForDiedAlien)
{
	const char* mapName = "test_game";
	ASSERT_NE(-1, FS_CheckFile("maps/%s.bsp", mapName)) << "Map resource '" << mapName << ".bsp' for test is missing.";
	Actor* diedEnt;
	Actor* actor;
	Edict* floorItems;
	Item* invlist;
	int count;
	SV_Map(true, mapName, nullptr);
	level.activeTeam = TEAM_ALIEN;

	/* first alien that should die and drop its inventory */
	diedEnt = G_EdictsGetNextLivingActorOfTeam(nullptr, TEAM_ALIEN);
	ASSERT_TRUE(nullptr != diedEnt);
	diedEnt->HP = 0;
	ASSERT_TRUE(G_ActorDieOrStun(diedEnt, nullptr));
	ASSERT_TRUE(diedEnt->isDead());

	/* now try to collect the inventory with a second alien */
	actor = G_EdictsGetNextLivingActorOfTeam(nullptr, TEAM_ALIEN);
	ASSERT_TRUE(nullptr != actor);

	/* move to the location of the first died alien to drop the inventory into the same floor container */
	Player& player = actor->getPlayer();
	ASSERT_TRUE(G_IsAIPlayer(&player));
	G_ClientMove(player, 0, actor, diedEnt->pos);
	ASSERT_TRUE(VectorCompare(actor->pos, diedEnt->pos));

	floorItems = G_GetFloorItems(actor);
	ASSERT_TRUE(nullptr != floorItems);
	ASSERT_EQ(floorItems->getFloor(), actor->getFloor());

	/* drop everything to floor to make sure we have space in the backpack */
	G_InventoryToFloor(actor);
	ASSERT_EQ(0, GAMETEST_GetItemCount(actor, CID_BACKPACK));

	invlist = actor->getContainer(CID_BACKPACK);
	ASSERT_TRUE(nullptr == invlist);
	count = GAMETEST_GetItemCount(actor, CID_FLOOR);
	if (count > 0) {
		Item* entryToMove = actor->getFloor();
		int tx, ty;
		actor->chr.inv.findSpace(INVDEF(CID_BACKPACK), entryToMove, &tx, &ty, entryToMove);
		if (tx == NONE)
			return;
		Com_Printf("trying to move item %s from floor into backpack to pos %i:%i\n", entryToMove->def()->name, tx, ty);
		ASSERT_TRUE(G_ActorInvMove(actor, INVDEF(CID_FLOOR), entryToMove, INVDEF(CID_BACKPACK), tx, ty, false));
		ASSERT_EQ(count - 1, GAMETEST_GetItemCount(actor, CID_FLOOR)) << "item " << entryToMove->def()->name << " could not get moved successfully from floor into backpack";
		Com_Printf("item %s was removed from floor\n", entryToMove->def()->name);
		ASSERT_EQ(1, GAMETEST_GetItemCount(actor, CID_BACKPACK)) << "item " << entryToMove->def()->name << " could not get moved successfully from floor into backpack";
		Com_Printf("item %s was moved successfully into the backpack\n", entryToMove->def()->name);
		invlist = actor->getContainer(CID_BACKPACK);
		ASSERT_TRUE(nullptr != invlist);
	}
}
Exemplo n.º 6
0
/**
 * @brief Think function for actors that spawn dead
 * @param ent The actor
 */
static void G_ThinkActorDieAfterSpawn (edict_t *ent)
{
	G_ActorDieOrStun(ent, NULL);
	ent->think = NULL;
}
Exemplo n.º 7
0
static void testInventoryWithTwoDiedAliensOnTheSameGridTile (void)
{
	const char *mapName = "test_game";
	if (FS_CheckFile("maps/%s.bsp", mapName) != -1) {
		edict_t *diedEnt;
		edict_t *diedEnt2;
		edict_t *ent;
		edict_t *floorItems;
		invList_t *invlist;
		int count;
		/* the other tests didn't call the server shutdown function to clean up */
		OBJZERO(*sv);
		SV_Map(true, mapName, NULL);
		level.activeTeam = TEAM_ALIEN;

		/* first alien that should die and drop its inventory */
		diedEnt = G_EdictsGetNextLivingActorOfTeam(NULL, TEAM_ALIEN);
		CU_ASSERT_PTR_NOT_NULL_FATAL(diedEnt);
		diedEnt->HP = 0;
		G_ActorDieOrStun(diedEnt, NULL);
		CU_ASSERT_TRUE_FATAL(G_IsDead(diedEnt));

		/* second alien that should die and drop its inventory */
		diedEnt2 = G_EdictsGetNextLivingActorOfTeam(NULL, TEAM_ALIEN);
		CU_ASSERT_PTR_NOT_NULL_FATAL(diedEnt2);

		/* move to the location of the first died alien to drop the inventory into the same floor container */
		Player &player = diedEnt2->getPlayer();
		CU_ASSERT_TRUE_FATAL(G_IsAIPlayer(&player));
		G_ClientMove(player, 0, diedEnt2, diedEnt->pos);
		CU_ASSERT_TRUE_FATAL(VectorCompare(diedEnt2->pos, diedEnt->pos));

		diedEnt2->HP = 0;
		G_ActorDieOrStun(diedEnt2, NULL);
		CU_ASSERT_TRUE_FATAL(G_IsDead(diedEnt2));

		/* now try to collect the inventory with a third alien */
		ent = G_EdictsGetNextLivingActorOfTeam(NULL, TEAM_ALIEN);
		CU_ASSERT_PTR_NOT_NULL_FATAL(ent);

		player = ent->getPlayer();
		CU_ASSERT_TRUE_FATAL(G_IsAIPlayer(&player));

		G_ClientMove(player, 0, ent, diedEnt->pos);
		CU_ASSERT_TRUE_FATAL(VectorCompare(ent->pos, diedEnt->pos));

		floorItems = G_GetFloorItems(ent);
		CU_ASSERT_PTR_NOT_NULL_FATAL(floorItems);
		CU_ASSERT_PTR_EQUAL(floorItems->getFloor(), ent->getFloor());

		/* drop everything to floor to make sure we have space in the backpack */
		G_InventoryToFloor(ent);
		CU_ASSERT_EQUAL(GAMETEST_GetItemCount(ent, CID_BACKPACK), 0);

		invlist = ent->getContainer(CID_BACKPACK);
		CU_ASSERT_PTR_NULL_FATAL(invlist);

		count = GAMETEST_GetItemCount(ent, CID_FLOOR);
		if (count > 0) {
			invList_t *entryToMove = ent->getFloor();
			int tx, ty;
			ent->chr.inv.findSpace(INVDEF(CID_BACKPACK), entryToMove, &tx, &ty, entryToMove);
			if (tx != NONE) {
				Com_Printf("trying to move item %s from floor into backpack to pos %i:%i\n", entryToMove->def()->name, tx, ty);
				CU_ASSERT_TRUE(G_ActorInvMove(ent, INVDEF(CID_FLOOR), entryToMove, INVDEF(CID_BACKPACK), tx, ty, false));
				UFO_CU_ASSERT_EQUAL_INT_MSG_FATAL(GAMETEST_GetItemCount(ent, CID_FLOOR), count - 1, va("item %s could not get moved successfully from floor into backpack", entryToMove->def()->name));
				Com_Printf("item %s was removed from floor\n", entryToMove->def()->name);
				UFO_CU_ASSERT_EQUAL_INT_MSG_FATAL(GAMETEST_GetItemCount(ent, CID_BACKPACK), 1, va("item %s could not get moved successfully from floor into backpack", entryToMove->def()->name));
				Com_Printf("item %s was moved successfully into the backpack\n", entryToMove->def()->name);
				invlist = ent->getContainer(CID_BACKPACK);
				CU_ASSERT_PTR_NOT_NULL_FATAL(invlist);
			}
		}

		SV_ShutdownGameProgs();
	} else {
		UFO_CU_FAIL_MSG(va("Map resource '%s.bsp' for test is missing.", mapName));
	}
}
Exemplo n.º 8
0
/**
 * @brief Handles the end of a match
 * @param[in] team The winning team number
 * @param[in] nextmap Is there a follow-up map within the same match ?
 * @sa G_RunFrame
 * @sa CL_ParseResults
 */
static void G_MatchSendResults (int team, bool nextmap)
{
	edict_t *ent, *attacker;
	int i, j = 0;

	attacker = NULL;
	ent = NULL;
	/* Calculate new scores/skills for the soldiers. */
	while ((ent = G_EdictsGetNextLivingActor(ent))) {
		if (!G_IsAI(ent))
			G_UpdateCharacterExperience(ent);
		else if (ent->team == team)
			attacker = ent;
	}

	/* if aliens won, make sure every soldier that is not in the rescue zone dies */
	if (team == TEAM_ALIEN) {
		ent = NULL;
		while ((ent = G_EdictsGetNextLivingActor(ent)))
			if (ent->team != team && !G_ActorIsInRescueZone(ent)) {
				ent->HP = 0;
				G_ActorDieOrStun(ent, attacker);
			}
	}

	G_VisMakeEverythingVisible();

	/* send results */
	G_EventAdd(PM_ALL, EV_RESULTS, -1);
	gi.WriteByte(MAX_TEAMS);
	gi.WriteByte(team);
	gi.WriteByte(nextmap);

	for (i = 0; i < MAX_TEAMS; i++) {
		gi.WriteByte(level.num_spawned[i]);
		gi.WriteByte(level.num_alive[i]);
	}

	for (i = 0; i <= MAX_TEAMS; i++)
		for (j = 0; j < MAX_TEAMS; j++)
			gi.WriteByte(level.num_kills[i][j]);

	for (i = 0; i <= MAX_TEAMS; i++)
		for (j = 0; j < MAX_TEAMS; j++)
			gi.WriteByte(level.num_stuns[i][j]);

	/* how many actors */
	j = 0;
	ent = NULL;
	while ((ent = G_EdictsGetNextActor(ent)))
		if (!G_IsAI(ent))
			j++;

	/* number of soldiers */
	gi.WriteByte(j);

	if (j) {
		ent = NULL;
		while ((ent = G_EdictsGetNextActor(ent))) {
			if (!G_IsAI(ent)) {
				G_SendCharacterData(ent);
			}
		}
	}

	G_EventEnd();
}
Exemplo n.º 9
0
/**
 * @brief Handles the end of a match
 * @param[in] team The winning team number
 * @param[in] nextmap Is there a follow-up map within the same match ?
 * @sa G_RunFrame
 * @sa CL_ParseResults
 */
static void G_MatchSendResults (int team, bool nextmap)
{
	Edict* attacker = nullptr;
	Actor* actor = nullptr;
	/* Calculate new scores/skills for the soldiers. */
	while ((actor = G_EdictsGetNextLivingActor(actor))) {
		if (!G_IsAI(actor))
			G_UpdateCharacterExperience(actor);
		else if (actor->getTeam() == team)
			attacker = actor;
	}

	/* if aliens won, make sure every soldier that is not in the rescue zone dies */
	if (team == TEAM_ALIEN) {
		actor = nullptr;
		while ((actor = G_EdictsGetNextLivingActor(actor)))
			if (actor->getTeam() != team && !actor->isInRescueZone()) {
				actor->HP = 0;
				G_ActorDieOrStun(actor, attacker);
			}
	}

	G_VisMakeEverythingVisible();

	/* send results */
	G_EventAdd(PM_ALL, EV_RESULTS, -1);
	gi.WriteByte(MAX_TEAMS);
	gi.WriteByte(team);
	gi.WriteByte(nextmap);

	for (int i = 0; i < MAX_TEAMS; i++) {
		gi.WriteByte(level.num_spawned[i]);
		gi.WriteByte(level.num_alive[i]);
	}

	for (int i = 0; i <= MAX_TEAMS; i++)
		for (int j = 0; j < MAX_TEAMS; j++)
			gi.WriteByte(level.num_kills[i][j]);

	for (int i = 0; i <= MAX_TEAMS; i++)
		for (int j = 0; j < MAX_TEAMS; j++)
			gi.WriteByte(level.num_stuns[i][j]);

	/* how many actors */
	int n  = 0;
	actor = nullptr;
	while ((actor = G_EdictsGetNextActor(actor)))
		if (!G_IsAI(actor))
			n++;

	/* number of soldiers */
	gi.WriteByte(n);

	if (n) {
		actor = nullptr;
		while ((actor = G_EdictsGetNextActor(actor))) {
			if (!G_IsAI(actor)) {
				G_SendCharacterData(actor);
			}
		}
	}

	G_EventEnd();
}