g_morale.c

Go to the documentation of this file.
00001 
00005 /*
00006 Copyright (C) 2002-2010 UFO: Alien Invasion.
00007 
00008 This program is free software; you can redistribute it and/or
00009 modify it under the terms of the GNU General Public License
00010 as published by the Free Software Foundation; either version 2
00011 of the License, or (at your option) any later version.
00012 
00013 This program is distributed in the hope that it will be useful,
00014 but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00016 
00017 See the GNU General Public License for more details.
00018 
00019 You should have received a copy of the GNU General Public License
00020 along with this program; if not, write to the Free Software
00021 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00022 
00023 */
00024 
00025 #include "g_local.h"
00026 
00027 
00034 static void G_MoralePanic (edict_t * ent, qboolean sanity)
00035 {
00036     G_ClientPrintf(G_PLAYER_FROM_ENT(ent), PRINT_HUD, _("%s panics!\n"), ent->chr.name);
00037 
00038     /* drop items in hands */
00039     if (!sanity && ent->chr.teamDef->weapons) {
00040         if (RIGHT(ent))
00041             G_ActorInvMove(ent, INVDEF(gi.csi->idRight), RIGHT(ent),
00042                     INVDEF(gi.csi->idFloor), NONE, NONE, qtrue);
00043         if (LEFT(ent))
00044             G_ActorInvMove(ent, INVDEF(gi.csi->idLeft), LEFT(ent),
00045                     INVDEF(gi.csi->idFloor), NONE, NONE, qtrue);
00046     }
00047 
00048     /* get up */
00049     G_RemoveCrouched(ent);
00050     G_ActorSetMaxs(ent);
00051 
00052     /* send panic */
00053     G_SetPanic(ent);
00054     G_SendState(G_VisToPM(ent->visflags), ent);
00055 
00056     /* center view */
00057     G_CenterView(ent);
00058 
00059     /* move around a bit, try to avoid opponents */
00060     AI_ActorThink(G_PLAYER_FROM_ENT(ent), ent);
00061 
00062     /* kill TUs */
00063     G_ActorSetTU(ent, 0);
00064 }
00065 
00074 static void G_MoraleStopPanic (edict_t * ent)
00075 {
00076     if (ent->morale / mor_panic->value > m_panic_stop->value * frand())
00077         G_RemovePanic(ent);
00078     else
00079         G_MoralePanic(ent, qtrue);
00080 }
00081 
00088 static void G_MoraleRage (edict_t * ent, qboolean sanity)
00089 {
00090     if (sanity)
00091         G_SetRage(ent);
00092     else
00093         G_SetInsane(ent);
00094     G_SendState(G_VisToPM(ent->visflags), ent);
00095 
00096     if (sanity)
00097         gi.BroadcastPrintf(PRINT_HUD, _("%s is on a rampage.\n"), ent->chr.name);
00098     else
00099         gi.BroadcastPrintf(PRINT_HUD, _("%s is consumed by mad rage!\n"), ent->chr.name);
00100     AI_ActorThink(G_PLAYER_FROM_ENT(ent), ent);
00101 }
00102 
00111 static void G_MoraleStopRage (edict_t * ent)
00112 {
00113     if (ent->morale / mor_panic->value > m_rage_stop->value * frand()) {
00114         G_RemoveInsane(ent);
00115         G_SendState(G_VisToPM(ent->visflags), ent);
00116     } else
00117         G_MoralePanic(ent, qtrue); /* regains sanity */
00118 }
00119 
00125 static qboolean G_IsMoraleEnabled (void)
00126 {
00127     if (sv_maxclients->integer == 1)
00128         return qtrue;
00129 
00130     if (sv_maxclients->integer >= 2 && sv_enablemorale->integer == 1)
00131         return qtrue;
00132 
00133     return qfalse;
00134 }
00135 
00144 void G_MoraleBehaviour (int team)
00145 {
00146     edict_t *ent = NULL;
00147     int newMorale;
00148 
00149     while ((ent = G_EdictsGetNextInUse(ent))) {
00150         /* this only applies to ET_ACTOR but not to ET_ACTOR2x2 */
00151         if (ent->type == ET_ACTOR && ent->team == team && !G_IsDead(ent)) {
00152             /* civilians have a 1:1 chance to randomly run away in multiplayer */
00153             if (sv_maxclients->integer >= 2 && level.activeTeam == TEAM_CIVILIAN && 0.5 > frand())
00154                 G_MoralePanic(ent, qfalse);
00155             /* multiplayer needs enabled sv_enablemorale */
00156             /* singleplayer has this in every case */
00157             if (G_IsMoraleEnabled()) {
00158                 /* if panic, determine what kind of panic happens: */
00159                 if (ent->morale <= mor_panic->value && !G_IsPaniced(ent) && !G_IsRaged(ent)) {
00160                     qboolean sanity;
00161                     if ((float) ent->morale / mor_panic->value > (m_sanity->value * frand()))
00162                         sanity = qtrue;
00163                     else
00164                         sanity = qfalse;
00165                     if ((float) ent->morale / mor_panic->value > (m_rage->value * frand()))
00166                         G_MoralePanic(ent, sanity);
00167                     else
00168                         G_MoraleRage(ent, sanity);
00169                     /* if shaken, well .. be shaken; */
00170                 } else if (ent->morale <= mor_shaken->value && !G_IsPaniced(ent)
00171                         && !G_IsRaged(ent)) {
00172                     /* shaken is later reset along with reaction fire */
00173                     G_SetShaken(ent);
00174                     G_SetState(ent, STATE_REACTION_MANY);
00175                     G_SendState(G_VisToPM(ent->visflags), ent);
00176                     G_ClientPrintf(G_PLAYER_FROM_ENT(ent), PRINT_HUD, _("%s is currently shaken.\n"),
00177                             ent->chr.name);
00178                 } else {
00179                     if (G_IsPaniced(ent))
00180                         G_MoraleStopPanic(ent);
00181                     else if (G_IsRaged(ent))
00182                         G_MoraleStopRage(ent);
00183                 }
00184             }
00185 
00186             G_ActorSetMaxs(ent);
00187 
00188             /* morale-regeneration, capped at max: */
00189             newMorale = ent->morale + MORALE_RANDOM(mor_regeneration->value);
00190             if (newMorale > GET_MORALE(ent->chr.score.skills[ABILITY_MIND]))
00191                 ent->morale = GET_MORALE(ent->chr.score.skills[ABILITY_MIND]);
00192             else
00193                 ent->morale = newMorale;
00194 
00195             /* send phys data and state: */
00196             G_SendStats(ent);
00197             gi.EndEvents();
00198         }
00199     }
00200 }

Generated by  doxygen 1.6.2