|
|
1.1 ! root 1: #include "g_local.h" ! 2: ! 3: //void plat_CalcMove (edict_t *ent, vec3_t dest, void(*func)(edict_t*)); ! 4: void Move_Calc (edict_t *ent, vec3_t dest, void(*func)(edict_t*)); ! 5: ! 6: void fd_secret_move1(edict_t *self); ! 7: void fd_secret_move2(edict_t *self); ! 8: void fd_secret_move3(edict_t *self); ! 9: void fd_secret_move4(edict_t *self); ! 10: void fd_secret_move5(edict_t *self); ! 11: void fd_secret_move6(edict_t *self); ! 12: void fd_secret_done(edict_t *self); ! 13: ! 14: /* ! 15: ============================================================================= ! 16: ! 17: SECRET DOORS ! 18: ! 19: ============================================================================= ! 20: */ ! 21: ! 22: #define SEC_OPEN_ONCE 1 // stays open ! 23: #define SEC_1ST_LEFT 2 // 1st move is left of arrow ! 24: #define SEC_1ST_DOWN 4 // 1st move is down from arrow ! 25: #define SEC_NO_SHOOT 8 // only opened by trigger ! 26: #define SEC_YES_SHOOT 16 // shootable even if targeted ! 27: #define SEC_MOVE_RIGHT 32 ! 28: #define SEC_MOVE_FORWARD 64 ! 29: ! 30: void fd_secret_use (edict_t *self, edict_t *other, edict_t *activator) ! 31: { ! 32: edict_t *ent; ! 33: ! 34: // gi.dprintf("fd_secret_use\n"); ! 35: if (self->flags & FL_TEAMSLAVE) ! 36: return; ! 37: ! 38: // trigger all paired doors ! 39: for (ent = self ; ent ; ent = ent->teamchain) ! 40: Move_Calc(ent, ent->moveinfo.start_origin, fd_secret_move1); ! 41: ! 42: } ! 43: ! 44: void fd_secret_killed (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point) ! 45: { ! 46: // gi.dprintf("fd_secret_killed\n"); ! 47: self->health = self->max_health; ! 48: self->takedamage = DAMAGE_NO; ! 49: ! 50: if (self->flags & FL_TEAMSLAVE && self->teammaster && self->teammaster->takedamage != DAMAGE_NO) ! 51: fd_secret_killed (self->teammaster, inflictor, attacker, damage, point); ! 52: else ! 53: fd_secret_use (self, inflictor, attacker); ! 54: } ! 55: ! 56: // Wait after first movement... ! 57: void fd_secret_move1(edict_t *self) ! 58: { ! 59: // gi.dprintf("fd_secret_move1\n"); ! 60: self->nextthink = level.time + 1.0; ! 61: self->think = fd_secret_move2; ! 62: } ! 63: ! 64: // Start moving sideways w/sound... ! 65: void fd_secret_move2(edict_t *self) ! 66: { ! 67: // gi.dprintf("fd_secret_move2\n"); ! 68: Move_Calc(self, self->moveinfo.end_origin, fd_secret_move3); ! 69: } ! 70: ! 71: // Wait here until time to go back... ! 72: void fd_secret_move3(edict_t *self) ! 73: { ! 74: // gi.dprintf("fd_secret_move3\n"); ! 75: if (!(self->spawnflags & SEC_OPEN_ONCE)) ! 76: { ! 77: self->nextthink = level.time + self->wait; ! 78: self->think = fd_secret_move4; ! 79: } ! 80: } ! 81: ! 82: // Move backward... ! 83: void fd_secret_move4(edict_t *self) ! 84: { ! 85: // gi.dprintf("fd_secret_move4\n"); ! 86: Move_Calc(self, self->moveinfo.start_origin, fd_secret_move5); ! 87: } ! 88: ! 89: // Wait 1 second... ! 90: void fd_secret_move5(edict_t *self) ! 91: { ! 92: // gi.dprintf("fd_secret_move5\n"); ! 93: self->nextthink = level.time + 1.0; ! 94: self->think = fd_secret_move6; ! 95: } ! 96: ! 97: void fd_secret_move6(edict_t *self) ! 98: { ! 99: // gi.dprintf("fd_secret_move6\n"); ! 100: Move_Calc(self, self->move_origin, fd_secret_done); ! 101: } ! 102: ! 103: void fd_secret_done(edict_t *self) ! 104: { ! 105: // gi.dprintf("fd_secret_done\n"); ! 106: if (!self->targetname || self->spawnflags & SEC_YES_SHOOT) ! 107: { ! 108: self->health = 1; ! 109: self->takedamage = DAMAGE_YES; ! 110: self->die = fd_secret_killed; ! 111: } ! 112: } ! 113: ! 114: void secret_blocked(edict_t *self, edict_t *other) ! 115: { ! 116: if (!(self->flags & FL_TEAMSLAVE)) ! 117: T_Damage (other, self, self, vec3_origin, other->s.origin, vec3_origin, self->dmg, 0, 0, MOD_CRUSH); ! 118: ! 119: // if (time < self->attack_finished) ! 120: // return; ! 121: // self->attack_finished = time + 0.5; ! 122: // T_Damage (other, self, self, self->dmg); ! 123: } ! 124: ! 125: /* ! 126: ================ ! 127: secret_touch ! 128: ! 129: Prints messages ! 130: ================ ! 131: */ ! 132: void secret_touch(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) ! 133: { ! 134: if (other->health <= 0) ! 135: return; ! 136: ! 137: if (!(other->client)) ! 138: return; ! 139: ! 140: if (self->monsterinfo.attack_finished > level.time) ! 141: return; ! 142: ! 143: self->monsterinfo.attack_finished = level.time + 2; ! 144: ! 145: if (self->message) ! 146: { ! 147: gi.centerprintf (other, self->message); ! 148: // fixme - put this sound back?? ! 149: // gi.sound (other, CHAN_BODY, "misc/talk.wav", 1, ATTN_NORM); ! 150: } ! 151: } ! 152: ! 153: ! 154: /*QUAKED func_door_secret2 (0 .5 .8) ? open_once 1st_left 1st_down no_shoot always_shoot slide_right slide_forward ! 155: Basic secret door. Slides back, then to the left. Angle determines direction. ! 156: ! 157: FLAGS: ! 158: open_once = not implemented yet ! 159: 1st_left = 1st move is left/right of arrow ! 160: 1st_down = 1st move is forwards/backwards ! 161: no_shoot = not implemented yet ! 162: always_shoot = even if targeted, keep shootable ! 163: reverse_left = the sideways move will be to right of arrow ! 164: reverse_back = the to/fro move will be forward ! 165: ! 166: VALUES: ! 167: wait = # of seconds before coming back (5 default) ! 168: dmg = damage to inflict when blocked (2 default) ! 169: ! 170: */ ! 171: ! 172: void SP_func_door_secret2 (edict_t *ent) ! 173: { ! 174: vec3_t forward,right,up; ! 175: float lrSize, fbSize; ! 176: ! 177: ent->moveinfo.sound_start = gi.soundindex ("doors/dr1_strt.wav"); ! 178: ent->moveinfo.sound_middle = gi.soundindex ("doors/dr1_mid.wav"); ! 179: ent->moveinfo.sound_end = gi.soundindex ("doors/dr1_end.wav"); ! 180: ! 181: if (!ent->dmg) ! 182: ent->dmg = 2; ! 183: ! 184: AngleVectors(ent->s.angles, forward, right, up); ! 185: VectorCopy(ent->s.origin, ent->move_origin); ! 186: VectorCopy(ent->s.angles, ent->move_angles); ! 187: ! 188: G_SetMovedir (ent->s.angles, ent->movedir); ! 189: ent->movetype = MOVETYPE_PUSH; ! 190: ent->solid = SOLID_BSP; ! 191: gi.setmodel (ent, ent->model); ! 192: ! 193: if(ent->move_angles[1] == 0 || ent->move_angles[1] == 180) ! 194: { ! 195: lrSize = ent->size[1]; ! 196: fbSize = ent->size[0]; ! 197: } ! 198: else if(ent->move_angles[1] == 90 || ent->move_angles[1] == 270) ! 199: { ! 200: lrSize = ent->size[0]; ! 201: fbSize = ent->size[1]; ! 202: } ! 203: else ! 204: { ! 205: gi.dprintf("Secret door not at 0,90,180,270!\n"); ! 206: } ! 207: ! 208: if(ent->spawnflags & SEC_MOVE_FORWARD) ! 209: VectorScale(forward, fbSize, forward); ! 210: else ! 211: { ! 212: VectorScale(forward, fbSize * -1 , forward); ! 213: } ! 214: ! 215: if(ent->spawnflags & SEC_MOVE_RIGHT) ! 216: VectorScale(right, lrSize, right); ! 217: else ! 218: { ! 219: VectorScale(right, lrSize * -1, right); ! 220: } ! 221: ! 222: if(ent->spawnflags & SEC_1ST_DOWN) ! 223: { ! 224: VectorAdd(ent->s.origin, forward, ent->moveinfo.start_origin); ! 225: VectorAdd(ent->moveinfo.start_origin, right, ent->moveinfo.end_origin); ! 226: } ! 227: else ! 228: { ! 229: VectorAdd(ent->s.origin, right, ent->moveinfo.start_origin); ! 230: VectorAdd(ent->moveinfo.start_origin, forward, ent->moveinfo.end_origin); ! 231: } ! 232: ! 233: ent->touch = secret_touch; ! 234: ent->blocked = secret_blocked; ! 235: ent->use = fd_secret_use; ! 236: ent->moveinfo.speed = 50; ! 237: ent->moveinfo.accel = 50; ! 238: ent->moveinfo.decel = 50; ! 239: ! 240: if (!ent->targetname || ent->spawnflags & SEC_YES_SHOOT) ! 241: { ! 242: ent->health = 1; ! 243: ent->max_health = ent->health; ! 244: ent->takedamage = DAMAGE_YES; ! 245: ent->die = fd_secret_killed; ! 246: } ! 247: if (!ent->wait) ! 248: ent->wait = 5; // 5 seconds before closing ! 249: ! 250: gi.linkentity(ent); ! 251: } ! 252: ! 253: // ================================================== ! 254: ! 255: #define FWALL_START_ON 1 ! 256: ! 257: void force_wall_think(edict_t *self) ! 258: { ! 259: if(!self->wait) ! 260: { ! 261: gi.WriteByte (svc_temp_entity); ! 262: gi.WriteByte (TE_FORCEWALL); ! 263: gi.WritePosition (self->pos1); ! 264: gi.WritePosition (self->pos2); ! 265: gi.WriteByte (self->style); ! 266: gi.multicast (self->offset, MULTICAST_PVS); ! 267: } ! 268: ! 269: self->think = force_wall_think; ! 270: self->nextthink = level.time + 0.1; ! 271: } ! 272: ! 273: void force_wall_use (edict_t *self, edict_t *other, edict_t *activator) ! 274: { ! 275: if(!self->wait) ! 276: { ! 277: self->wait = 1; ! 278: self->think = NULL; ! 279: self->nextthink = 0; ! 280: self->solid = SOLID_NOT; ! 281: gi.linkentity( self ); ! 282: } ! 283: else ! 284: { ! 285: self->wait = 0; ! 286: self->think = force_wall_think; ! 287: self->nextthink = level.time + 0.1; ! 288: self->solid = SOLID_BSP; ! 289: KillBox(self); // Is this appropriate? ! 290: gi.linkentity (self); ! 291: } ! 292: } ! 293: ! 294: /*QUAKED func_force_wall (1 0 1) ? start_on ! 295: A vertical particle force wall. Turns on and solid when triggered. ! 296: If someone is in the force wall when it turns on, they're telefragged. ! 297: ! 298: start_on - forcewall begins activated. triggering will turn it off. ! 299: style - color of particles to use. ! 300: 208: green, 240: red, 241: blue, 224: orange ! 301: */ ! 302: void SP_func_force_wall(edict_t *ent) ! 303: { ! 304: gi.setmodel (ent, ent->model); ! 305: ! 306: ent->offset[0] = (ent->absmax[0] + ent->absmin[0]) / 2; ! 307: ent->offset[1] = (ent->absmax[1] + ent->absmin[1]) / 2; ! 308: ent->offset[2] = (ent->absmax[2] + ent->absmin[2]) / 2; ! 309: ! 310: ent->pos1[2] = ent->absmax[2]; ! 311: ent->pos2[2] = ent->absmax[2]; ! 312: if(ent->size[0] > ent->size[1]) ! 313: { ! 314: ent->pos1[0] = ent->absmin[0]; ! 315: ent->pos2[0] = ent->absmax[0]; ! 316: ent->pos1[1] = ent->offset[1]; ! 317: ent->pos2[1] = ent->offset[1]; ! 318: } ! 319: else ! 320: { ! 321: ent->pos1[0] = ent->offset[0]; ! 322: ent->pos2[0] = ent->offset[0]; ! 323: ent->pos1[1] = ent->absmin[1]; ! 324: ent->pos2[1] = ent->absmax[1]; ! 325: } ! 326: ! 327: if(!ent->style) ! 328: ent->style = 208; ! 329: ! 330: ent->movetype = MOVETYPE_NONE; ! 331: ent->wait = 1; ! 332: ! 333: if(ent->spawnflags & FWALL_START_ON) ! 334: { ! 335: ent->solid = SOLID_BSP; ! 336: ent->think = force_wall_think; ! 337: ent->nextthink = level.time + 0.1; ! 338: } ! 339: else ! 340: ent->solid = SOLID_NOT; ! 341: ! 342: ent->use = force_wall_use; ! 343: ! 344: ent->svflags = SVF_NOCLIENT; ! 345: ! 346: gi.linkentity(ent); ! 347: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.