Пример #1
0
/**
 * @brief Sends the actual actor turn event over the netchannel
 */
static void G_ClientTurn (player_t * player, edict_t* ent, dvec_t dvec)
{
	const int dir = getDVdir(dvec);

	/* check if action is possible */
	if (!G_ActionCheckForCurrentTeam(player, ent, TU_TURN))
		return;

	/* check if we're already facing that direction */
	if (ent->dir == dir)
		return;

	/* do the turn */
	G_ActorDoTurn(ent, dir);
	G_ActorUseTU(ent, TU_TURN);

	/* send the turn */
	G_EventActorTurn(ent);

	/* send the new TUs */
	G_SendStats(ent);

	/* end the event */
	G_EventEnd();
}
Пример #2
0
/**
 * @brief Sends whole inventory through the network buffer.
 * @param[in] playerMask The player mask to determine which clients should receive the event (@c G_VisToPM(ent->visflags)).
 * @param[in] ent Pointer to an actor or floor container with inventory to send.
 * @sa G_AppearPerishEvent
 * @sa CL_InvAdd
 */
void G_SendInventory (playermask_t playerMask, const edict_t *ent)
{
	invList_t *ic;
	int nr = 0;
	containerIndex_t container;

	/* test for pointless player mask */
	if (!playerMask)
		return;

	for (container = 0; container < gi.csi->numIDs; container++) {
		if (!G_IsItem(ent) && INVDEF(container)->temp)
			continue;
		for (ic = CONTAINER(ent, container); ic; ic = ic->next)
			nr++;
	}

	/* return if no inventory items to send */
	if (nr == 0)
		return;

	G_EventInventoryAdd(ent, playerMask, nr);
	for (container = 0; container < gi.csi->numIDs; container++) {
		if (!G_IsItem(ent) && INVDEF(container)->temp)
			continue;
		for (ic = CONTAINER(ent, container); ic; ic = ic->next) {
			/* send a single item */
			assert(ic->item.item);
			G_WriteItem(&ic->item, INVDEF(container), ic->x, ic->y);
		}
	}
	G_EventEnd();
}
Пример #3
0
void G_EventModelExplode (const Edict& ent, const char* sound)
{
	assert(ent.inuse);
	G_EventAdd(PM_ALL, EV_MODEL_EXPLODE, ent.number);
	gi.WriteString(sound);
	G_EventEnd();
}
Пример #4
0
/**
 * @brief This functions starts the client
 * @sa G_ClientStartMatch
 * @sa CL_StartGame
 */
bool G_ClientBegin (player_t* player)
{
	player->began = true;
	level.numplayers++;

	/* find a team */
	G_GetTeam(player);
	if (!player->began)
		return false;

	gi.ConfigString(CS_PLAYERCOUNT, "%i", level.numplayers);

	/* spawn camera (starts client rendering) */
	G_EventStart(player, sv_teamplay->integer);

	/* send things like doors and breakables */
	G_ClientSendEdictsAndBrushModels(player);

	/* ensure that the start event is send */
	G_EventEnd();

	/* set the net name */
	gi.ConfigString(CS_PLAYERNAMES + player->num, "%s", player->pers.netname);

	/* inform all clients */
	gi.BroadcastPrintf(PRINT_CONSOLE, "%s has joined team %i\n", player->pers.netname, player->pers.team);

	return true;
}
Пример #5
0
/**
 * @brief Let an actor fall down if e.g. the func_breakable the actor was standing on was destroyed.
 * @param[in,out] ent The actor that should fall down
 * @todo Handle cases where the grid position the actor would fall to is occupied by another actor already.
 */
void G_ActorFall (edict_t *ent)
{
	edict_t* entAtPos;
	const int oldZ = ent->pos[2];

	ent->pos[2] = gi.GridFall(gi.routingMap, ent->fieldSize, ent->pos);

	if (oldZ == ent->pos[2])
		return;

	entAtPos = G_GetEdictFromPos(ent->pos, ET_NULL);
	if (entAtPos != NULL && (G_IsBreakable(entAtPos) || G_IsBlockingMovementActor(entAtPos))) {
		const int diff = oldZ - ent->pos[2];
		G_TakeDamage(entAtPos, (int)(FALLING_DAMAGE_FACTOR * (float)diff));
	}

	G_EdictCalcOrigin(ent);
	gi.LinkEdict(ent);

	G_CheckVis(ent);

	G_EventActorFall(ent);

	G_EventEnd();
}
Пример #6
0
/**
 * @brief Send disappear event
 * @param[in] playerMask The bitmask to determine the clients this event is send to
 * @param[in,out] ent The edict that perished
 */
void G_EventEdictPerish (playermask_t playerMask, const Edict& ent)
{
	assert(ent.inuse);
	G_EventAdd(playerMask, EV_ENT_PERISH, ent.number);
	gi.WriteByte(ent.type);
	G_EventEnd();
}
Пример #7
0
void G_EventReset (const player_t *player, int activeTeam)
{
	G_EventAdd(G_PlayerToPM(player), EV_RESET | EVENT_INSTANTLY, -1);
	gi.WriteByte(player->pers.team);
	gi.WriteByte(activeTeam);
	G_EventEnd();
}
Пример #8
0
/**
 * @brief Announce the actor die event for the clients that are seeing the actor
 * @param[in] ent The actor that is dying
 */
void G_EventActorDie (const edict_t* ent)
{
	G_EventAdd(G_VisToPM(ent->visflags), EV_ACTOR_DIE, ent->number);
	gi.WriteShort(ent->state);
	gi.WriteByte(ent->pnum);
	G_EventEnd();
}
Пример #9
0
void G_EventEndRoundAnnounce (const player_t *player)
{
	G_EventAdd(PM_ALL, EV_ENDROUNDANNOUNCE | EVENT_INSTANTLY, -1);
	gi.WriteByte(player->num);
	gi.WriteByte(player->pers.team);
	G_EventEnd();
}
Пример #10
0
/**
 * @brief Send disappear event
 * @param[in] playerMask The bitmask to determine the clients this event is send to
 * @param[in,out] ent The edict that perished
 */
void G_EventEdictPerish (unsigned int playerMask, const edict_t *ent)
{
	assert(ent->inuse);
	G_EventAdd(playerMask, EV_ENT_PERISH, ent->number);
	gi.WriteByte(ent->type);
	G_EventEnd();
}
Пример #11
0
/**
 * @brief Send an appear event to the client.
 * @param playerMask The players to send the event to
 * @param ent The edict that should appear to the players included in the given mask.
 * @note Each following event that is relying on the fact that this edict must already
 * be known in the client, must also adopt the client side parsing of the event times.
 */
void G_EventEdictAppear (unsigned int playerMask, const edict_t *ent)
{
	G_EventAdd(playerMask, EV_ENT_APPEAR, ent->number);
	gi.WriteByte(ent->type);
	gi.WriteGPos(ent->pos);
	G_EventEnd();
}
Пример #12
0
void G_EventReset (const Player& player, int activeTeam)
{
	G_EventAdd(G_PlayerToPM(player), EV_RESET | EVENT_INSTANTLY, -1);
	gi.WriteByte(player.getTeam());
	gi.WriteByte(activeTeam);
	G_EventEnd();
}
Пример #13
0
void G_EventModelExplodeTriggered (const Edict& ent, const char* sound)
{
	assert(ent.inuse);
	G_EventAdd(PM_ALL, EV_MODEL_EXPLODE_TRIGGERED, ent.getIdNum());
	gi.WriteString(sound);
	G_EventEnd();
}
Пример #14
0
/**
 * @brief Send an appear event to the client.
 * @param playerMask The players to send the event to
 * @param ent The edict that should appear to the players included in the given mask.
 * @note Each following event that is relying on the fact that this edict must already
 * be known in the client, must also adopt the client side parsing of the event times.
 */
void G_EventEdictAppear (playermask_t playerMask, const Edict& ent)
{
	G_EventAdd(playerMask, EV_ENT_APPEAR, ent.number);
	gi.WriteByte(ent.type);
	gi.WriteGPos(ent.pos);
	G_EventEnd();
}
Пример #15
0
/**
 * @brief Sets the team, init the TU and sends the player stats.
 * @sa G_SendPlayerStats
 * @sa G_GetTeam
 * @sa G_GiveTimeUnits
 * @sa G_ClientBegin
 * @sa CL_Reset
 */
void G_ClientStartMatch (player_t * player)
{
	G_GetStartingTeam(player);

	/* do all the init events here... */
	/* reset the data */
	G_EventReset(player, level.activeTeam);

	/* show visible actors and add invisible actor */
	G_VisFlagsClear(player->pers.team);
	G_CheckVisPlayer(player, false);
	G_SendInvisible(player);

	/* submit stats */
	G_SendPlayerStats(player);

	/* ensure that the last event is send, too */
	G_EventEnd();

	if (sv_maxclients->integer > 1) {
		/* ensure that we restart the round time limit */
		sv_roundtimelimit->modified = true;
	}

	/* inform all clients */
	gi.BroadcastPrintf(PRINT_CONSOLE, "%s has taken control over team %i.\n", player->pers.netname, player->pers.team);
}
Пример #16
0
void G_EventEndRoundAnnounce (const Player& player)
{
	G_EventAdd(PM_ALL, EV_ENDROUNDANNOUNCE, -1);
	gi.WriteByte(player.getNum());
	gi.WriteByte(player.getTeam());
	G_EventEnd();
}
Пример #17
0
/**
 * Send a particle spawn event to the client
 * @param[in] playerMask The clients that should see the particle
 * @param[in] ent The particle to spawn
 */
void G_EventSendParticle (playermask_t playerMask, const Edict& ent)
{
	G_EventAdd(playerMask, EV_PARTICLE_APPEAR, ent.number);
	gi.WriteShort(ent.spawnflags);
	gi.WritePos(ent.origin);
	gi.WriteString(ent.particle);
	G_EventEnd();
}
Пример #18
0
void G_EventSendState (playermask_t playerMask, const Edict& ent)
{
	G_EventActorStateChange(playerMask & G_TeamToPM(ent.team), ent);

	G_EventAdd(playerMask & ~G_TeamToPM(ent.team), EV_ACTOR_STATECHANGE, ent.number);
	gi.WriteShort(ent.state & STATE_PUBLIC);
	G_EventEnd();
}
Пример #19
0
/**
 * @brief Send the bounding box info to the client.
 * @param[in] ent The edict to send the bounding box for
 */
void G_EventSendEdict (const Edict& ent)
{
	G_EventAdd(PM_ALL, EV_ADD_EDICT, ent.number);
	gi.WriteByte(ent.type);
	gi.WritePos(ent.absBox.mins);
	gi.WritePos(ent.absBox.maxs);
	G_EventEnd();
}
Пример #20
0
/**
 * @brief Send the bounding box info to the client.
 * @param[in] ent The edict to send the bounding box for
 */
void G_EventSendEdict (const edict_t *ent)
{
	G_EventAdd(PM_ALL, EV_ADD_EDICT, ent->number);
	gi.WriteByte(ent->type);
	gi.WritePos(ent->absmin);
	gi.WritePos(ent->absmax);
	G_EventEnd();
}
Пример #21
0
/**
 * Send a particle spawn event to the client
 * @param[in] playerMask The clients that should see the particle
 * @param[in] ent The particle to spawn
 */
void G_EventSendParticle (unsigned int playerMask, const edict_t *ent)
{
	G_EventAdd(playerMask, EV_PARTICLE_APPEAR, ent->number);
	gi.WriteShort(ent->spawnflags);
	gi.WritePos(ent->origin);
	gi.WriteString(ent->particle);
	G_EventEnd();
}
Пример #22
0
/**
 * @brief Announce the actor die event for the clients that are seeing the actor
 * @param[in] ent The actor that is dying
 */
void G_EventActorDie (const Edict& ent, bool attacker)
{
	G_EventAdd(G_VisToPM(ent.visflags), EV_ACTOR_DIE, ent.number);
	gi.WriteShort(ent.state);
	gi.WriteByte(ent.pnum);
	gi.WriteByte(attacker);
	G_EventEnd();
}
Пример #23
0
/**
 * @brief Start the shooting event
 * @param ent The entity that starts the shooting
 * @param teamMask the vis mask of the teams to determine the clients from this event is send to
 * @param shootType The type of the shoot
 * @param at The grid position to target to
 */
void G_EventStartShoot (const Edict& ent, teammask_t teamMask, shoot_types_t shootType, const pos3_t at)
{
	G_EventAdd(G_VisToPM(teamMask), EV_ACTOR_START_SHOOT, ent.number);
	gi.WriteByte(shootType);
	gi.WriteGPos(ent.pos);
	gi.WriteGPos(at);
	G_EventEnd();
}
Пример #24
0
/**
 * @brief Tell the client to remove the item from the container
 * @param[in] ent Pointer to entity having given inventory.
 * @param[in] playerMask The player mask to determine which clients should receive the event (e.g. @c G_VisToPM(ent->visflags))
 * @param[in] containerId Id of the container the item is in.
 * @param[in] x,y Position of item in container.
 */
void G_EventInventoryDelete (const Edict& ent, playermask_t playerMask, const containerIndex_t containerId, int x, int y)
{
	G_EventAdd(playerMask, EV_INV_DEL, ent.number);
	gi.WriteByte(containerId);
	gi.WriteByte(x);
	gi.WriteByte(y);
	G_EventEnd();
}
Пример #25
0
void G_EventSendState (unsigned int playerMask, const edict_t *ent)
{
	G_EventActorStateChange(playerMask & G_TeamToPM(ent->team), ent);

	G_EventAdd(playerMask & ~G_TeamToPM(ent->team), EV_ACTOR_STATECHANGE, ent->number);
	gi.WriteShort(ent->state & STATE_PUBLIC);
	G_EventEnd();
}
Пример #26
0
/**
 * @brief Tell the client to remove the item from the container
 * @param[in] ent Pointer to entity having given inventory.
 * @param[in] playerMask The player mask to determine which clients should receive the event (e.g. @c G_VisToPM(ent->visflags))
 * @param[in] invDef Pointer to inventory definition having given container.
 * @param[in] x Position of item in container.
 * @param[in] y Position of item in container.
 */
void G_EventInventoryDelete (const edict_t* ent, int playerMask, const invDef_t* invDef, int x, int y)
{
	G_EventAdd(playerMask, EV_INV_DEL, ent->number);
	gi.WriteByte(invDef->id);
	gi.WriteByte(x);
	gi.WriteByte(y);
	G_EventEnd();
}
Пример #27
0
/**
 * @brief Start the shooting event
 * @param ent The entity that starts the shooting
 * @param visMask the vis mask of the teams to determine the clients from this event is send to
 * @param shootType The type of the shoot
 * @param at The grid position to target to
 */
void G_EventStartShoot (const edict_t* ent, vismask_t visMask, shoot_types_t shootType, const pos3_t at)
{
	G_EventAdd(G_VisToPM(visMask), EV_ACTOR_START_SHOOT, ent->number);
	gi.WriteByte(shootType);
	gi.WriteGPos(ent->pos);
	gi.WriteGPos(at);
	G_EventEnd();
}
Пример #28
0
void G_EventActorStats (const Edict& ent, playermask_t playerMask)
{
	G_EventAdd(playerMask, EV_ACTOR_STATS, ent.getIdNum());
	gi.WriteByte(ent.TU);
	gi.WriteShort(ent.HP);
	gi.WriteByte(ent.getStun());
	gi.WriteByte(ent.morale);
	G_EventEnd();
}
Пример #29
0
/**
 * @brief Start the shooting event for hidden actors
 * @param teamMask the vis mask to determine the clients from this event is send to
 * @param fd The firedefinition to use for the shoot
 * @param firstShoot Is this the first shoot
 */
void G_EventShootHidden (teammask_t teamMask, const fireDef_t* fd, bool firstShoot)
{
	G_EventAdd(~G_VisToPM(teamMask), EV_ACTOR_SHOOT_HIDDEN, -1);
	gi.WriteByte(firstShoot);
	gi.WriteShort(fd->obj->idx);
	gi.WriteByte(fd->weapFdsIdx);
	gi.WriteByte(fd->fdIdx);
	G_EventEnd();
}
Пример #30
0
void G_EventActorStats (const Edict& ent, playermask_t playerMask)
{
	G_EventAdd(playerMask, EV_ACTOR_STATS, ent.number);
	gi.WriteByte(ent.TU);
	gi.WriteShort(ent.HP);
	gi.WriteByte(ent.STUN);
	gi.WriteByte(ent.morale);
	G_EventEnd();
}