00001
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "../client.h"
00026 #include "cl_battlescape.h"
00027 #include "cl_actor.h"
00028
00029 client_state_t cl;
00030
00036 qboolean CL_BattlescapeRunning (void)
00037 {
00038 return cl.spawned;
00039 }
00040
00049 qboolean CL_OnBattlescape (void)
00050 {
00051
00052 if (Com_ServerState())
00053 return qtrue;
00054
00055
00056 if (cls.state >= ca_connected)
00057 return qtrue;
00058
00059 return qfalse;
00060 }
00061
00062
00063 #define LOOKUP_EPSILON 0.0001f
00064
00069 static const float lookup[30]= {
00070 0.0f, 0.1125f, 0.2227f, 0.3286f, 0.4284f, 0.5205f, 0.6039f,
00071 0.6778f, 0.7421f, 0.7969f, 0.8427f, 0.8802f, 0.9103f, 0.9340f,
00072 0.9523f, 0.9661f, 0.9763f, 0.9838f, 0.9891f, 0.9928f, 0.9953f,
00073 0.9970f, 0.9981f, 0.9989f, 0.9993f, 0.9996f, 0.9998f, 0.9999f,
00074 0.9999f, 1.0000f
00075 };
00076
00081 static const float lookupdiff[30]= {
00082 1.1246f, 1.1024f, 1.0592f, 0.9977f, 0.9211f, 0.8336f, 0.7395f,
00083 0.6430f, 0.5481f, 0.4579f, 0.3750f, 0.3011f, 0.2369f, 0.1828f,
00084 0.1382f, 0.1024f, 0.0744f, 0.0530f, 0.0370f, 0.0253f, 0.0170f,
00085 0.0112f, 0.0072f, 0.0045f, 0.0028f, 0.0017f, 0.0010f, 0.0006f,
00086 0.0003f, 0.0002f
00087 };
00088
00098 static float CL_LookupErrorFunction (float z)
00099 {
00100 float ifloat;
00101 int iint;
00102
00103
00104
00105 if (z < LOOKUP_EPSILON)
00106 return 0.0f;
00107 if (z > 2.8f)
00108 return 1.0f;
00109 ifloat = floor(z * 10.0f);
00110 iint = (int)ifloat;
00111 assert(iint < 30);
00112 return lookup[iint] + (z - ifloat / 10.0f) * lookupdiff[iint];
00113 }
00114
00115 static inline qboolean CL_TestLine (const vec3_t start, const vec3_t stop, const int levelmask)
00116 {
00117 return TR_TestLine(cl.mapTiles, start, stop, levelmask);
00118 }
00119
00130 int CL_GetHitProbability (const le_t* actor)
00131 {
00132 vec3_t shooter, target;
00133 float distance, pseudosin, width, height, acc, perpX, perpY, hitchance,
00134 stdevupdown, stdevleftright, crouch, commonfactor;
00135 int distx, disty, n;
00136 le_t *le;
00137 const character_t *chr;
00138 pos3_t toPos;
00139
00140 assert(actor);
00141 assert(actor->fd);
00142
00143 if (IS_MODE_FIRE_PENDING(actor->actorMode))
00144 VectorCopy(actor->mousePendPos, toPos);
00145 else
00146 VectorCopy(mousePos, toPos);
00147
00149 le = LE_GetFromPos(toPos);
00150 if (!le)
00151 return 0;
00152
00153
00154 if (le->selected && !FIRESH_IsMedikit(le->fd))
00155 return 0;
00156
00157 VectorCopy(actor->origin, shooter);
00158 VectorCopy(le->origin, target);
00159
00160
00161 distx = fabs(shooter[0] - target[0]);
00162 disty = fabs(shooter[1] - target[1]);
00163 distance = sqrt(distx * distx + disty * disty);
00164 if (distx > disty)
00165 pseudosin = distance / distx;
00166 else
00167 pseudosin = distance / disty;
00168 width = 2 * PLAYER_WIDTH * pseudosin;
00169 height = LE_IsCrouched(le) ? PLAYER_CROUCHING_HEIGHT : PLAYER_STANDING_HEIGHT;
00170
00171 chr = CL_ActorGetChr(actor);
00172 if (!chr)
00173 Com_Error(ERR_DROP, "No character given for local entity");
00174
00175 acc = GET_ACC(chr->score.skills[ABILITY_ACCURACY],
00176 actor->fd->weaponSkill ? chr->score.skills[actor->fd->weaponSkill] : 0);
00177
00178 crouch = (LE_IsCrouched(actor) && actor->fd->crouch) ? actor->fd->crouch : 1;
00179
00180 commonfactor = crouch * torad * distance * GET_INJURY_MULT(chr->score.skills[ABILITY_MIND], actor->HP, actor->maxHP);
00181 stdevupdown = (actor->fd->spread[0] * (WEAPON_BALANCE + SKILL_BALANCE * acc)) * commonfactor;
00182 stdevleftright = (actor->fd->spread[1] * (WEAPON_BALANCE + SKILL_BALANCE * acc)) * commonfactor;
00183 hitchance = (stdevupdown > LOOKUP_EPSILON ? CL_LookupErrorFunction(height * 0.3536f / stdevupdown) : 1.0f)
00184 * (stdevleftright > LOOKUP_EPSILON ? CL_LookupErrorFunction(width * 0.3536f / stdevleftright) : 1.0f);
00185
00186
00187
00188 n = 0;
00189 height = height / 18;
00190 width = width / 18;
00191 target[2] -= UNIT_HEIGHT / 2;
00192 target[2] += height * 9;
00193 perpX = disty / distance * width;
00194 perpY = 0 - distx / distance * width;
00195
00196 target[0] += perpX;
00197 perpX *= 2;
00198 target[1] += perpY;
00199 perpY *= 2;
00200 target[2] += 6 * height;
00201 if (!CL_TestLine(shooter, target, TL_FLAG_NONE))
00202 n++;
00203 target[0] += perpX;
00204 target[1] += perpY;
00205 target[2] -= 6 * height;
00206 if (!CL_TestLine(shooter, target, TL_FLAG_NONE))
00207 n++;
00208 target[0] += perpX;
00209 target[1] += perpY;
00210 target[2] += 4 * height;
00211 if (!CL_TestLine(shooter, target, TL_FLAG_NONE))
00212 n++;
00213 target[2] += 4 * height;
00214 if (!CL_TestLine(shooter, target, TL_FLAG_NONE))
00215 n++;
00216 target[0] -= perpX * 3;
00217 target[1] -= perpY * 3;
00218 target[2] -= 12 * height;
00219 if (!CL_TestLine(shooter, target, TL_FLAG_NONE))
00220 n++;
00221 target[0] -= perpX;
00222 target[1] -= perpY;
00223 target[2] += 6 * height;
00224 if (!CL_TestLine(shooter, target, TL_FLAG_NONE))
00225 n++;
00226 target[0] -= perpX;
00227 target[1] -= perpY;
00228 target[2] -= 4 * height;
00229 if (!CL_TestLine(shooter, target, TL_FLAG_NONE))
00230 n++;
00231 target[0] -= perpX;
00232 target[1] -= perpY;
00233 target[2] += 10 * height;
00234 if (!CL_TestLine(shooter, target, TL_FLAG_NONE))
00235 n++;
00236
00237 return 100 * (hitchance * (0.125) * n);
00238 }
00239
00240 static const float mapZBorder = -(UNIT_HEIGHT * 5);
00250 qboolean CL_OutsideMap (const vec3_t position, const float delta)
00251 {
00252 if (position[0] < cl.mapData->mapMin[0] - delta || position[0] > cl.mapData->mapMax[0] + delta)
00253 return qtrue;
00254
00255 if (position[1] < cl.mapData->mapMin[1] - delta || position[1] > cl.mapData->mapMax[1] + delta)
00256 return qtrue;
00257
00258
00259
00260
00261
00262 if (position[2] < mapZBorder)
00263 return qtrue;
00264
00265
00266 return qfalse;
00267 }
00268
00269 #ifdef DEBUG
00270
00271 #include "../../common/routing.h"
00272
00277 void Grid_DumpWholeClientMap_f (void)
00278 {
00279 int i;
00280
00281 for (i = 0; i < ACTOR_MAX_SIZE; i++)
00282 RT_DumpWholeMap(cl.mapTiles, &(cl.mapData->map[i]));
00283 }
00284
00289 void Grid_DumpClientRoutes_f (void)
00290 {
00291 ipos3_t wpMins, wpMaxs;
00292 VecToPos(cl.mapData->mapMin, wpMins);
00293 VecToPos(cl.mapData->mapMax, wpMaxs);
00294 RT_WriteCSVFiles(cl.mapData->map, "ufoaiclient", wpMins, wpMaxs);
00295 }
00296 #endif
00297
00298 char *CL_GetConfigString (int index)
00299 {
00300 if (index < 0 || index >= MAX_CONFIGSTRINGS)
00301 Com_Error(ERR_DROP, "Invalid config string index given");
00302 return cl.configstrings[index];
00303 }
00304
00305 int CL_GetConfigStringInteger (int index)
00306 {
00307 if (index < 0 || index >= MAX_CONFIGSTRINGS)
00308 Com_Error(ERR_DROP, "Invalid config string index given");
00309 return atoi(cl.configstrings[index]);
00310 }
00311
00312 char *CL_SetConfigString (int index, struct dbuffer *msg)
00313 {
00314 if (index < 0 || index >= MAX_CONFIGSTRINGS)
00315 Com_Error(ERR_DROP, "Invalid config string index given");
00316
00317
00318
00319
00320 if (index == CS_TILES || index == CS_POSITIONS)
00321 NET_ReadString(msg, cl.configstrings[index], MAX_TOKEN_CHARS * MAX_TILESTRINGS);
00322 else
00323 NET_ReadString(msg, cl.configstrings[index], sizeof(cl.configstrings[index]));
00324
00325 return cl.configstrings[index];
00326 }