/** * @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(); }
/** * @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(); }
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(); }
/** * @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; }
/** * @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(); }
/** * @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(); }
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(); }
/** * @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(); }
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(); }
/** * @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(); }
/** * @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(); }
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(); }
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(); }
/** * @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(); }
/** * @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); }
void G_EventEndRoundAnnounce (const Player& player) { G_EventAdd(PM_ALL, EV_ENDROUNDANNOUNCE, -1); gi.WriteByte(player.getNum()); gi.WriteByte(player.getTeam()); G_EventEnd(); }
/** * 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(); }
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(); }
/** * @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(); }
/** * @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(); }
/** * 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(); }
/** * @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(); }
/** * @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(); }
/** * @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(); }
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(); }
/** * @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(); }
/** * @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(); }
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(); }
/** * @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(); }
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(); }