|
|
1.1 ! root 1: // cl_tent.c -- client side temporary entities ! 2: ! 3: #include "quakedef.h" ! 4: ! 5: int num_temp_entities; ! 6: entity_t cl_temp_entities[MAX_TEMP_ENTITIES]; ! 7: beam_t cl_beams[MAX_BEAMS]; ! 8: ! 9: sfx_t *cl_sfx_wizhit; ! 10: sfx_t *cl_sfx_knighthit; ! 11: sfx_t *cl_sfx_tink1; ! 12: sfx_t *cl_sfx_ric1; ! 13: sfx_t *cl_sfx_ric2; ! 14: sfx_t *cl_sfx_ric3; ! 15: sfx_t *cl_sfx_r_exp3; ! 16: ! 17: /* ! 18: ================= ! 19: CL_ParseTEnt ! 20: ================= ! 21: */ ! 22: void CL_InitTEnts (void) ! 23: { ! 24: cl_sfx_wizhit = S_PrecacheSound ("wizard/hit.wav"); ! 25: cl_sfx_knighthit = S_PrecacheSound ("hknight/hit.wav"); ! 26: cl_sfx_tink1 = S_PrecacheSound ("weapons/tink1.wav"); ! 27: cl_sfx_ric1 = S_PrecacheSound ("weapons/ric1.wav"); ! 28: cl_sfx_ric2 = S_PrecacheSound ("weapons/ric2.wav"); ! 29: cl_sfx_ric3 = S_PrecacheSound ("weapons/ric3.wav"); ! 30: cl_sfx_r_exp3 = S_PrecacheSound ("weapons/r_exp3.wav"); ! 31: } ! 32: ! 33: /* ! 34: ================= ! 35: CL_ParseBeam ! 36: ================= ! 37: */ ! 38: void CL_ParseBeam (model_t *m) ! 39: { ! 40: int ent; ! 41: vec3_t start, end; ! 42: beam_t *b; ! 43: int i; ! 44: ! 45: ent = MSG_ReadShort (); ! 46: ! 47: start[0] = MSG_ReadCoord (); ! 48: start[1] = MSG_ReadCoord (); ! 49: start[2] = MSG_ReadCoord (); ! 50: ! 51: end[0] = MSG_ReadCoord (); ! 52: end[1] = MSG_ReadCoord (); ! 53: end[2] = MSG_ReadCoord (); ! 54: ! 55: // override any beam with the same entity ! 56: for (i=0, b=cl_beams ; i< MAX_BEAMS ; i++, b++) ! 57: if (b->entity == ent) ! 58: { ! 59: b->entity = ent; ! 60: b->model = m; ! 61: b->endtime = cl.time + 0.2; ! 62: VectorCopy (start, b->start); ! 63: VectorCopy (end, b->end); ! 64: return; ! 65: } ! 66: ! 67: // find a free beam ! 68: for (i=0, b=cl_beams ; i< MAX_BEAMS ; i++, b++) ! 69: { ! 70: if (!b->model || b->endtime < cl.time) ! 71: { ! 72: b->entity = ent; ! 73: b->model = m; ! 74: b->endtime = cl.time + 0.2; ! 75: VectorCopy (start, b->start); ! 76: VectorCopy (end, b->end); ! 77: return; ! 78: } ! 79: } ! 80: Con_Printf ("beam list overflow!\n"); ! 81: } ! 82: ! 83: /* ! 84: ================= ! 85: CL_ParseTEnt ! 86: ================= ! 87: */ ! 88: void CL_ParseTEnt (void) ! 89: { ! 90: int type; ! 91: vec3_t pos; ! 92: dlight_t *dl; ! 93: int rnd; ! 94: ! 95: type = MSG_ReadByte (); ! 96: switch (type) ! 97: { ! 98: case TE_WIZSPIKE: // spike hitting wall ! 99: pos[0] = MSG_ReadCoord (); ! 100: pos[1] = MSG_ReadCoord (); ! 101: pos[2] = MSG_ReadCoord (); ! 102: R_RunParticleEffect (pos, vec3_origin, 20, 30); ! 103: S_StartSound (-1, 0, cl_sfx_wizhit, pos, 1, 1); ! 104: break; ! 105: ! 106: case TE_KNIGHTSPIKE: // spike hitting wall ! 107: pos[0] = MSG_ReadCoord (); ! 108: pos[1] = MSG_ReadCoord (); ! 109: pos[2] = MSG_ReadCoord (); ! 110: R_RunParticleEffect (pos, vec3_origin, 226, 20); ! 111: S_StartSound (-1, 0, cl_sfx_knighthit, pos, 1, 1); ! 112: break; ! 113: ! 114: case TE_SPIKE: // spike hitting wall ! 115: pos[0] = MSG_ReadCoord (); ! 116: pos[1] = MSG_ReadCoord (); ! 117: pos[2] = MSG_ReadCoord (); ! 118: R_RunParticleEffect (pos, vec3_origin, 0, 10); ! 119: ! 120: if ( rand() % 5 ) ! 121: S_StartSound (-1, 0, cl_sfx_tink1, pos, 1, 1); ! 122: else ! 123: { ! 124: rnd = rand() & 3; ! 125: if (rnd == 1) ! 126: S_StartSound (-1, 0, cl_sfx_ric1, pos, 1, 1); ! 127: else if (rnd == 2) ! 128: S_StartSound (-1, 0, cl_sfx_ric2, pos, 1, 1); ! 129: else ! 130: S_StartSound (-1, 0, cl_sfx_ric3, pos, 1, 1); ! 131: } ! 132: break; ! 133: case TE_SUPERSPIKE: // super spike hitting wall ! 134: pos[0] = MSG_ReadCoord (); ! 135: pos[1] = MSG_ReadCoord (); ! 136: pos[2] = MSG_ReadCoord (); ! 137: R_RunParticleEffect (pos, vec3_origin, 0, 20); ! 138: ! 139: if ( rand() % 5 ) ! 140: S_StartSound (-1, 0, cl_sfx_tink1, pos, 1, 1); ! 141: else ! 142: { ! 143: rnd = rand() & 3; ! 144: if (rnd == 1) ! 145: S_StartSound (-1, 0, cl_sfx_ric1, pos, 1, 1); ! 146: else if (rnd == 2) ! 147: S_StartSound (-1, 0, cl_sfx_ric2, pos, 1, 1); ! 148: else ! 149: S_StartSound (-1, 0, cl_sfx_ric3, pos, 1, 1); ! 150: } ! 151: break; ! 152: ! 153: case TE_GUNSHOT: // bullet hitting wall ! 154: pos[0] = MSG_ReadCoord (); ! 155: pos[1] = MSG_ReadCoord (); ! 156: pos[2] = MSG_ReadCoord (); ! 157: R_RunParticleEffect (pos, vec3_origin, 0, 20); ! 158: break; ! 159: ! 160: case TE_EXPLOSION: // rocket explosion ! 161: pos[0] = MSG_ReadCoord (); ! 162: pos[1] = MSG_ReadCoord (); ! 163: pos[2] = MSG_ReadCoord (); ! 164: R_ParticleExplosion (pos); ! 165: dl = CL_AllocDlight (); ! 166: VectorCopy (pos, dl->origin); ! 167: dl->radius = 350; ! 168: dl->die = cl.time + 0.5; ! 169: dl->decay = 300; ! 170: S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1); ! 171: break; ! 172: ! 173: case TE_TAREXPLOSION: // tarbaby explosion ! 174: pos[0] = MSG_ReadCoord (); ! 175: pos[1] = MSG_ReadCoord (); ! 176: pos[2] = MSG_ReadCoord (); ! 177: R_BlobExplosion (pos); ! 178: ! 179: S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1); ! 180: break; ! 181: ! 182: case TE_LIGHTNING1: // lightning bolts ! 183: CL_ParseBeam (Mod_ForName("progs/bolt.mdl", true)); ! 184: break; ! 185: ! 186: case TE_LIGHTNING2: // lightning bolts ! 187: CL_ParseBeam (Mod_ForName("progs/bolt2.mdl", true)); ! 188: break; ! 189: ! 190: case TE_LIGHTNING3: // lightning bolts ! 191: CL_ParseBeam (Mod_ForName("progs/bolt3.mdl", true)); ! 192: break; ! 193: ! 194: case TE_LAVASPLASH: ! 195: pos[0] = MSG_ReadCoord (); ! 196: pos[1] = MSG_ReadCoord (); ! 197: pos[2] = MSG_ReadCoord (); ! 198: R_LavaSplash (pos); ! 199: break; ! 200: ! 201: case TE_TELEPORT: ! 202: pos[0] = MSG_ReadCoord (); ! 203: pos[1] = MSG_ReadCoord (); ! 204: pos[2] = MSG_ReadCoord (); ! 205: R_TeleportSplash (pos); ! 206: break; ! 207: ! 208: default: ! 209: Sys_Error ("CL_ParseTEnt: bad type"); ! 210: } ! 211: } ! 212: ! 213: ! 214: /* ! 215: ================= ! 216: CL_NewTempEntity ! 217: ================= ! 218: */ ! 219: entity_t *CL_NewTempEntity (void) ! 220: { ! 221: entity_t *ent; ! 222: ! 223: if (cl_numvisedicts == MAX_VISEDICTS) ! 224: return NULL; ! 225: if (num_temp_entities == MAX_TEMP_ENTITIES) ! 226: return NULL; ! 227: ent = &cl_temp_entities[num_temp_entities]; ! 228: memset (ent, 0, sizeof(*ent)); ! 229: num_temp_entities++; ! 230: cl_visedicts[cl_numvisedicts] = ent; ! 231: cl_numvisedicts++; ! 232: ! 233: ent->colormap = vid.colormap; ! 234: return ent; ! 235: } ! 236: ! 237: ! 238: /* ! 239: ================= ! 240: CL_UpdateTEnts ! 241: ================= ! 242: */ ! 243: void CL_UpdateTEnts (void) ! 244: { ! 245: int i; ! 246: beam_t *b; ! 247: vec3_t dist, org; ! 248: float d; ! 249: entity_t *ent; ! 250: float yaw, pitch; ! 251: float forward; ! 252: ! 253: num_temp_entities = 0; ! 254: ! 255: // update lightning ! 256: for (i=0, b=cl_beams ; i< MAX_BEAMS ; i++, b++) ! 257: { ! 258: if (!b->model || b->endtime < cl.time) ! 259: continue; ! 260: ! 261: // if coming from the player, update the start position ! 262: if (b->entity == cl.viewentity) ! 263: { ! 264: VectorCopy (cl_entities[cl.viewentity].origin, b->start); ! 265: } ! 266: ! 267: // calculate pitch and yaw ! 268: VectorSubtract (b->end, b->start, dist); ! 269: ! 270: if (dist[1] == 0 && dist[0] == 0) ! 271: { ! 272: yaw = 0; ! 273: if (dist[2] > 0) ! 274: pitch = 90; ! 275: else ! 276: pitch = 270; ! 277: } ! 278: else ! 279: { ! 280: yaw = (int) (atan2(dist[1], dist[0]) * 180 / M_PI); ! 281: if (yaw < 0) ! 282: yaw += 360; ! 283: ! 284: forward = sqrt (dist[0]*dist[0] + dist[1]*dist[1]); ! 285: pitch = (int) (atan2(dist[2], forward) * 180 / M_PI); ! 286: if (pitch < 0) ! 287: pitch += 360; ! 288: } ! 289: ! 290: // add new entities for the lightning ! 291: VectorCopy (b->start, org); ! 292: d = VectorNormalize(dist); ! 293: while (d > 0) ! 294: { ! 295: ent = CL_NewTempEntity (); ! 296: if (!ent) ! 297: return; ! 298: VectorCopy (org, ent->origin); ! 299: ent->model = b->model; ! 300: ent->angles[0] = pitch; ! 301: ent->angles[1] = yaw; ! 302: ent->angles[2] = rand()%360; ! 303: ! 304: for (i=0 ; i<3 ; i++) ! 305: org[i] += dist[i]*30; ! 306: d -= 30; ! 307: } ! 308: } ! 309: ! 310: } ! 311: ! 312:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.