/** * @brief Applies morale behaviour on actors * @note only called when mor_panic is not zero * @sa G_MoralePanic * @sa G_MoraleRage * @sa G_MoraleStopRage * @sa G_MoraleStopPanic */ void G_MoraleBehaviour (int team) { bool enabled = G_IsMoraleEnabled(team); if (!enabled) return; Edict* ent = nullptr; while ((ent = G_EdictsGetNextLivingActorOfTeam(ent, team)) != nullptr) { /* this only applies to ET_ACTOR but not to ET_ACTOR2x2 */ if (ent->type != ET_ACTOR || CHRSH_IsTeamDefRobot(ent->chr.teamDef)) continue; /* if panic, determine what kind of panic happens: */ if (!G_IsPanicked(ent) && !G_IsRaged(ent)) { if (ent->morale <= mor_panic->integer) { const float ratio = (float) ent->morale / mor_panic->value; const bool sanity = ratio > (m_sanity->value * frand()); if (!sanity) G_SetInsane(ent); if (ratio > (m_rage->value * frand())) G_MoralePanic(ent); else G_MoraleRage(ent); /* if shaken, well .. be shaken; */ } else if (ent->morale <= mor_shaken->integer) { /* shaken is later reset along with reaction fire */ G_SetShaken(ent); G_ClientStateChange(ent->getPlayer(), ent, STATE_REACTION, false); G_EventSendState(G_VisToPM(ent->visflags), *ent); G_ClientPrintf(ent->getPlayer(), PRINT_HUD, _("%s is currently shaken."), ent->chr.name); G_PrintStats("%s is shaken (entnum %i).", ent->chr.name, ent->getIdNum()); } } else { if (G_IsPanicked(ent)) G_MoraleStopPanic(ent); else if (G_IsRaged(ent)) G_MoraleStopRage(ent); } G_ActorSetMaxs(ent); /* morale-regeneration, capped at max: */ int newMorale = ent->morale + MORALE_RANDOM(mor_regeneration->value); const int maxMorale = GET_MORALE(ent->chr.score.skills[ABILITY_MIND]); if (newMorale > maxMorale) ent->morale = maxMorale; else ent->morale = newMorale; /* send phys data and state: */ G_SendStats(*ent); } }
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); }
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); }
/** * @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(); }
/** * @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(); }
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(); }
/** * @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(); }
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); }
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); }