Beispiel #1
0
void G_EventReactionFireAddTarget (const Edict& shooter, const Edict& target, int tus, int step)
{
	gi.QueueEvent(G_PlayerToPM(shooter.getPlayer()), EV_ACTOR_REACTIONFIREADDTARGET, shooter.getIdNum());
	gi.QueueWriteShort(target.getIdNum());
	gi.QueueWriteByte(tus);
	gi.QueueWriteByte(step);
}
Beispiel #2
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();
}
Beispiel #3
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();
}
Beispiel #4
0
void G_EventReactionFireTargetUpdate (const Edict& shooter, const Edict& target, int tus, int step)
{
	gi.QueueEvent(G_PlayerToPM(shooter.getPlayer()), EV_ACTOR_REACTIONFIRETARGETUPDATE, shooter.number);
	gi.QueueWriteShort(target.number);
	gi.QueueWriteByte(tus);
	gi.QueueWriteByte(step);
}
Beispiel #5
0
/**
 * @brief Will inform the player about the real TU reservation
 * @param ent The actors edict.
 */
void G_EventActorSendReservations (const edict_t *ent)
{
	G_EventAdd(G_PlayerToPM(G_PLAYER_FROM_ENT(ent)), EV_ACTOR_RESERVATIONCHANGE, ent->number);
	gi.WriteShort(ent->chr.reservedTus.reaction);
	gi.WriteShort(ent->chr.reservedTus.shot);
	gi.WriteShort(ent->chr.reservedTus.crouch);

	G_EventEnd();
}
Beispiel #6
0
/**
 * @brief Actor has been wounded/treated
 * @param[in] ent The actor whose wound status has changed
 * @note This event is sent to the player this actor belongs to
 */
void G_EventActorWound (const edict_t *ent, const int bodyPart)
{
	const int mask = G_PlayerToPM(G_PLAYER_FROM_ENT(ent));
	G_EventAdd(mask, EV_ACTOR_WOUND, ent->number);
	gi.WriteByte(bodyPart);
	gi.WriteByte(ent->chr.wounds.woundLevel[bodyPart]);
	gi.WriteByte(ent->chr.wounds.treatmentLevel[bodyPart]);
	G_EventEnd();
}
Beispiel #7
0
/**
 * @brief Send info about an actor's wounds to the client.
 * @param[in] ent The actor whose wound status we are sending.
 * @param[in] bodyPart The body part index we are sending wound info about.
 * @note This event is sent to the player this actor belongs to
 */
void G_EventActorWound (const Edict& ent, const int bodyPart)
{
	const int mask = G_PlayerToPM(ent.getPlayer());
	G_EventAdd(mask, EV_ACTOR_WOUND, ent.number);
	gi.WriteByte(bodyPart);
	const woundInfo_t& wounds = ent.chr.wounds;
	gi.WriteByte(wounds.woundLevel[bodyPart]);
	gi.WriteByte(wounds.treatmentLevel[bodyPart]);
	G_EventEnd();
}
Beispiel #8
0
/**
 * @brief Sets visible edict on player spawn
 * @sa G_ClientStartMatch
 * @sa G_CheckVisTeam
 * @sa G_AppearPerishEvent
 */
void G_CheckVisPlayer (Player& player, const vischeckflags_t visFlags)
{
	Edict* ent = nullptr;

	/* check visibility */
	while ((ent = G_EdictsGetNextInUse(ent))) {
		/* check if he's visible */
		G_DoTestVis(player.getTeam(), ent, visFlags, G_PlayerToPM(player), nullptr);
	}
}
Beispiel #9
0
/**
 * @brief Will inform the player about the real TU reservation
 * @param ent The actors edict.
 */
void G_EventActorSendReservations (const Edict& ent)
{
	G_EventAdd(G_PlayerToPM(ent.getPlayer()), EV_ACTOR_RESERVATIONCHANGE, ent.number);
	const chrReservations_t& reservedTUs = ent.chr.reservedTus;
	gi.WriteShort(reservedTUs.reaction);
	gi.WriteShort(reservedTUs.shot);
	gi.WriteShort(reservedTUs.crouch);

	G_EventEnd();
}
Beispiel #10
0
/**
 * @brief Write player stats to network buffer
 * @sa G_SendStats
 */
void G_SendPlayerStats (const Player& player)
{
	Edict* ent = nullptr;

	while ((ent = G_EdictsGetNextActor(ent)))
		if (ent->team == player.getTeam()) {
			G_EventActorStats(*ent, G_PlayerToPM(player));
			G_SendWoundStats(ent);
		}
}
Beispiel #11
0
void G_EventReactionFireChange (const edict_t* ent)
{
	const objDef_t *od = ent->chr.RFmode.weapon;

	G_EventAdd(G_PlayerToPM(G_PLAYER_FROM_ENT(ent)), EV_ACTOR_REACTIONFIRECHANGE, ent->number);
	gi.WriteByte(ent->chr.RFmode.fmIdx);
	gi.WriteByte(ent->chr.RFmode.getHand());
	gi.WriteShort(od ? od->idx : NONE);

	G_EventEnd();
}
Beispiel #12
0
void G_EventReactionFireChange (const Edict& ent)
{
	const FiremodeSettings& fireMode = ent.chr.RFmode;
	const objDef_t* od = fireMode.getWeapon();

	G_EventAdd(G_PlayerToPM(ent.getPlayer()), EV_ACTOR_REACTIONFIRECHANGE, ent.number);
	gi.WriteByte(fireMode.getFmIdx());
	gi.WriteByte(fireMode.getHand());
	gi.WriteShort(od ? od->idx : NONE);

	G_EventEnd();
}
Beispiel #13
0
/**
 * @brief Sets visible edict on player spawn
 * @sa G_ClientStartMatch
 * @sa G_CheckVisTeam
 * @sa G_AppearPerishEvent
 */
int G_CheckVisPlayer (player_t* player, bool perish)
{
	int status = 0;
	edict_t* ent = NULL;

	/* check visibility */
	while ((ent = G_EdictsGetNextInUse(ent))) {
		/* check if he's visible */
		status |= G_DoTestVis(player->pers.team, ent, perish, G_PlayerToPM(player), NULL);
	}

	return status;
}
Beispiel #14
0
/**
 * @brief Converts player mask to vis mask
 * @param[in] playerMask The player bit mask (contains the player numbers) that
 * is converted to a vis mask
 * @return Returns a vis mask for all the teams of the connected players that
 * are marked in the given @c playerMask.
 */
teammask_t G_PMToVis (playermask_t playerMask)
{
	player_t *p;
	teammask_t teamMask = 0;

	/* don't handle the ai players, here */
	p = NULL;
	while ((p = G_PlayerGetNextActiveHuman(p))) {
		if (playerMask & G_PlayerToPM(p))
			teamMask |= G_TeamToVisMask(p->pers.team);
	}

	return teamMask;
}
Beispiel #15
0
/**
 * @brief Converts vis mask to player mask
 * @param[in] vis_mask The visibility bit mask (contains the team numbers) that
 * is converted to a player mask
 * @return Returns a playermask for all the teams of the connected players that
 * are marked in the given @c vis_mask.
 */
unsigned int G_VisToPM (vismask_t vis_mask)
{
	player_t *p;
	unsigned int playerMask;

	playerMask = 0;

	/* don't handle the ai players, here */
	p = NULL;
	while ((p = G_PlayerGetNextActiveHuman(p))) {
		if (vis_mask & G_TeamToVisMask(p->pers.team))
			playerMask |= G_PlayerToPM(p);
	}

	return playerMask;
}
Beispiel #16
0
/**
 * @brief Generates the player bit mask for a given team
 * @param[in] team The team to create the player bit mask for
 * @note E.g. multiplayer team play can have more than one human player on the
 * same team.
 */
playermask_t G_TeamToPM (int team)
{
	player_t *p;
	playermask_t playerMask;

	playerMask = 0;

	/* don't handle the ai players, here */
	p = NULL;
	while ((p = G_PlayerGetNextHuman(p))) {
		if (p->inuse && team == p->pers.team)
			playerMask |= G_PlayerToPM(p);
	}

	return playerMask;
}
Beispiel #17
0
/**
 * @brief This function sends all the actors to the client that are not visible
 * initially - this is needed because an actor can e.g. produce sounds that are
 * send over the net. And the client can only handle them if he knows the
 * @c le_t (local entity) already
 * @note Call this for the first @c G_CheckVis call for every new
 * actor or player
 * @sa G_CheckVis
 * @sa CL_ActorAdd
 */
void G_SendInvisible (const player_t* player)
{
	const int team = player->pers.team;

	assert(team != TEAM_NO_ACTIVE);
	if (level.num_alive[team]) {
		edict_t* ent = NULL;
		/* check visibility */
		while ((ent = G_EdictsGetNextActor(ent))) {
			if (ent->team != team) {
				/* not visible for this team - so add the le only */
				if (!G_IsVisibleForTeam(ent, team)) {
					G_EventActorAdd(G_PlayerToPM(player), ent);
				}
			}
		}
	}
}
Beispiel #18
0
/**
 * @brief Send brush models for entities like func_breakable and func_door and triggers
 * with their bounding boxes to the client and let him know about them.
 * There are also entities that are announced here, but fully handled clientside - like
 * func_rotating.
 * @sa CL_AddBrushModel
 * @sa EV_ADD_BRUSH_MODEL
 * @param[in] player The player the edicts are send to
 */
static void G_ClientSendEdictsAndBrushModels (const player_t *player)
{
	const int mask = G_PlayerToPM(player);
	/* skip the world */
	edict_t *ent = G_EdictsGetFirst();

	/* make SOLID_BSP edicts visible to the client */
	while ((ent = G_EdictsGetNextInUse(ent))) {
		/* brush models that have a type - not the world - keep in
		 * mind that there are several world edicts in the list in case of
		 * a map assembly */
		if (ent->solid != SOLID_BSP)
			continue;

		/* skip the world(s) in case of map assembly */
		if (ent->type > ET_NULL) {
			G_EventAddBrushModel(mask, ent);
			G_VisFlagsAdd(ent, ~ent->visflags);
		}
	}
}
Beispiel #19
0
/**
 * @brief Checks whether the connection is valid or invalid and set some
 * user info keys.
 * @param[in,out] player The player that is trying to connect to the game
 * @param[in,out] userinfo The userinfo data that is checked and changed
 * @param[in] userinfoSize The size of the userinfo buffer
 * @sa G_ClientDisconnect
 * @sa CL_ConnectionlessPacket
 * @todo Check if the teamnum preference has already reached maxsoldiers
 * and reject connection if so
 * @return @c false if the connection is refused, @c true otherwise
 */
bool G_ClientConnect (player_t * player, char *userinfo, size_t userinfoSize)
{
	const char *value;

	value = Info_ValueForKey(userinfo, "ip");

	Com_Printf("connection attempt from %s\n", value);

	/* check to see if they are on the banned IP list */
	if (SV_FilterPacket(value)) {
		Info_SetValueForKey(userinfo, userinfoSize, "rejmsg", REJ_BANNED);
		return false;
	}

	if (!G_PlayerToPM(player)) {
		Info_SetValueForKey(userinfo, userinfoSize, "rejmsg", "Server is full");
		return false;
	}

	value = Info_ValueForKey(userinfo, "password");
	if (password->string[0] != '\0' && !Q_streq(password->string, "none") && !Q_streq(password->string, value)) {
		Info_SetValueForKey(userinfo, userinfoSize, "rejmsg", REJ_PASSWORD_REQUIRED_OR_INCORRECT);
		return false;
	}

	/* fix for fast reconnects after a disconnect */
	if (player->inuse) {
		gi.BroadcastPrintf(PRINT_CONSOLE, "%s already in use.\n", player->pers.netname);
		G_ClientDisconnect(player);
	}

	/* reset persistent data */
	OBJZERO(player->pers);
	G_ClientUserinfoChanged(player, userinfo);

	gi.BroadcastPrintf(PRINT_CONSOLE, "%s is connecting...\n", player->pers.netname);
	return true;
}
Beispiel #20
0
/**
 * @brief Hurt trigger
 * @sa SP_trigger_hurt
 */
bool Touch_HurtTrigger (Edict* self, Edict* activator)
{
	/* Dead actors should really not be able to trigger this - they can't be hurt anymore anyway */
	if (!G_IsLivingActor(activator))
		return false;

	/* If no damage is dealt don't count it as triggered */
	const int damage = G_ApplyProtection(activator, self->dmgtype, self->dmg);
	if (damage == 0)
		return false;

	const bool stunEl = (self->dmgtype == gi.csi->damStunElectro);
	const bool stunGas = (self->dmgtype == gi.csi->damStunGas);
	const bool shock = (self->dmgtype == gi.csi->damShock);
	const bool isRobot = activator->chr.teamDef->robot;
	Actor* actor = makeActor(activator);

	if (stunEl || (stunGas && !isRobot)) {
		actor->addStun(damage);
	} else if (shock) {
		/** @todo Handle dazed via trigger_hurt */
	} else {
		G_TakeDamage(actor, damage);
	}
	/* Play hurt sound unless this is shock damage -- it doesn't do anything
	 * because we don't actually handle it above yet */
	if (!shock) {
		const teamDef_t* teamDef = activator->chr.teamDef;
		const int gender = activator->chr.gender;
		const char* sound = teamDef->getActorSound(gender, SND_HURT);
		G_EventSpawnSound(G_PlayerToPM(activator->getPlayer()), *activator, nullptr, sound);
	}

	G_CheckDeathOrKnockout(actor, nullptr, nullptr, damage);

	return true;
}
Beispiel #21
0
/**
 * @brief Reset the client actions for the given entity
 * @param[in] ent The entity to reset the client action for
 * @note This event is send to the player this edict belongs to
 */
void G_EventResetClientAction (const edict_t* ent)
{
	const int playerMask = G_PlayerToPM(G_PLAYER_FROM_ENT(ent));
	G_EventAdd(playerMask, EV_RESET_CLIENT_ACTION, ent->number);
	G_EventEnd();
}
Beispiel #22
0
void G_EventReactionFireAbortShot (const Edict& shooter, const Edict& target, int step)
{
	gi.QueueEvent(G_PlayerToPM(shooter.getPlayer()), EV_ACTOR_REACTIONFIREABORTSHOT, shooter.getIdNum());
	gi.QueueWriteShort(target.getIdNum());
	gi.QueueWriteByte(step);
}
Beispiel #23
0
void G_EventStart (const Player& player, bool teamplay)
{
	G_EventAdd(G_PlayerToPM(player), EV_START | EVENT_INSTANTLY, -1);
	gi.WriteByte(teamplay);
	G_EventEnd();
}
Beispiel #24
0
void G_EventReactionFireRemoveTarget (const Edict& shooter, const Edict& target, int step)
{
	gi.QueueEvent(G_PlayerToPM(shooter.getPlayer()), EV_ACTOR_REACTIONFIREREMOVETARGET, shooter.number);
	gi.QueueWriteShort(target.number);
	gi.QueueWriteByte(step);
}
Beispiel #25
0
/**
 * @brief Reset the client actions for the given entity
 * @param[in] ent The entity to reset the client action for
 * @note This event is send to the player this edict belongs to
 */
void G_EventResetClientAction (const Edict& ent)
{
	const int playerMask = G_PlayerToPM(ent.getPlayer());
	G_EventAdd(playerMask, EV_RESET_CLIENT_ACTION, ent.number);
	G_EventEnd();
}