|
|
1.1 ! root 1: #include "g_local.h" ! 2: ! 3: //========================================================== ! 4: ! 5: /*QUAKED target_steam (1 0 0) (-8 -8 -8) (8 8 8) ! 6: Creates a steam effect (particles w/ velocity in a line). ! 7: ! 8: speed = velocity of particles (default 50) ! 9: count = number of particles (default 32) ! 10: sounds = color of particles (default 8 for steam) ! 11: the color range is from this color to this color + 6 ! 12: wait = seconds to run before stopping (overrides default ! 13: value derived from func_timer) ! 14: ! 15: best way to use this is to tie it to a func_timer that "pokes" ! 16: it every second (or however long you set the wait time, above) ! 17: ! 18: note that the width of the base is proportional to the speed ! 19: good colors to use: ! 20: 6-9 - varying whites (darker to brighter) ! 21: 224 - sparks ! 22: 176 - blue water ! 23: 80 - brown water ! 24: 208 - slime ! 25: 232 - blood ! 26: */ ! 27: ! 28: void use_target_steam (edict_t *self, edict_t *other, edict_t *activator) ! 29: { ! 30: // FIXME - this needs to be a global ! 31: static int nextid; ! 32: vec3_t point; ! 33: ! 34: if (nextid > 20000) ! 35: nextid = nextid %20000; ! 36: ! 37: nextid++; ! 38: ! 39: // automagically set wait from func_timer unless they set it already, or ! 40: // default to 1000 if not called by a func_timer (eek!) ! 41: if (!self->wait) ! 42: if (other) ! 43: self->wait = other->wait * 1000; ! 44: else ! 45: self->wait = 1000; ! 46: ! 47: if (self->enemy) ! 48: { ! 49: VectorMA (self->enemy->absmin, 0.5, self->enemy->size, point); ! 50: VectorSubtract (point, self->s.origin, self->movedir); ! 51: VectorNormalize (self->movedir); ! 52: } ! 53: ! 54: VectorMA (self->s.origin, self->plat2flags*0.5, self->movedir, point); ! 55: if (self->wait > 100) ! 56: { ! 57: gi.WriteByte (svc_temp_entity); ! 58: gi.WriteByte (TE_STEAM); ! 59: gi.WriteShort (nextid); ! 60: gi.WriteByte (self->count); ! 61: gi.WritePosition (self->s.origin); ! 62: gi.WriteDir (self->movedir); ! 63: gi.WriteByte (self->sounds&0xff); ! 64: gi.WriteShort ( (short int)(self->plat2flags) ); ! 65: gi.WriteLong ( (int)(self->wait) ); ! 66: gi.multicast (self->s.origin, MULTICAST_PVS); ! 67: } ! 68: else ! 69: { ! 70: gi.WriteByte (svc_temp_entity); ! 71: gi.WriteByte (TE_STEAM); ! 72: gi.WriteShort ((short int)-1); ! 73: gi.WriteByte (self->count); ! 74: gi.WritePosition (self->s.origin); ! 75: gi.WriteDir (self->movedir); ! 76: gi.WriteByte (self->sounds&0xff); ! 77: gi.WriteShort ( (short int)(self->plat2flags) ); ! 78: gi.multicast (self->s.origin, MULTICAST_PVS); ! 79: } ! 80: } ! 81: ! 82: void target_steam_start (edict_t *self) ! 83: { ! 84: edict_t *ent; ! 85: ! 86: self->use = use_target_steam; ! 87: ! 88: if (self->target) ! 89: { ! 90: ent = G_Find (NULL, FOFS(targetname), self->target); ! 91: if (!ent) ! 92: gi.dprintf ("%s at %s: %s is a bad target\n", self->classname, vtos(self->s.origin), self->target); ! 93: self->enemy = ent; ! 94: } ! 95: else ! 96: { ! 97: G_SetMovedir (self->s.angles, self->movedir); ! 98: } ! 99: ! 100: if (!self->count) ! 101: self->count = 32; ! 102: if (!self->plat2flags) ! 103: self->plat2flags = 75; ! 104: if (!self->sounds) ! 105: self->sounds = 8; ! 106: if (self->wait) ! 107: self->wait *= 1000; // we want it in milliseconds, not seconds ! 108: ! 109: // paranoia is good ! 110: self->sounds &= 0xff; ! 111: self->count &= 0xff; ! 112: ! 113: self->svflags = SVF_NOCLIENT; ! 114: ! 115: gi.linkentity (self); ! 116: } ! 117: ! 118: void SP_target_steam (edict_t *self) ! 119: { ! 120: self->plat2flags = self->speed; ! 121: ! 122: if (self->target) ! 123: { ! 124: self->think = target_steam_start; ! 125: self->nextthink = level.time + 1; ! 126: } ! 127: else ! 128: target_steam_start (self); ! 129: } ! 130: ! 131: ! 132: //========================================================== ! 133: // target_anger ! 134: //========================================================== ! 135: ! 136: void target_anger_use (edict_t *self, edict_t *other, edict_t *activator) ! 137: { ! 138: edict_t *target; ! 139: edict_t *t; ! 140: ! 141: t = NULL; ! 142: target = G_Find (t, FOFS(targetname), self->killtarget); ! 143: ! 144: if (target && self->target) ! 145: { ! 146: // Make whatever a "good guy" so the monster will try to kill it! ! 147: target->monsterinfo.aiflags |= AI_GOOD_GUY; ! 148: target->svflags |= SVF_MONSTER; ! 149: target->health = 300; ! 150: ! 151: t = NULL; ! 152: while ((t = G_Find (t, FOFS(targetname), self->target))) ! 153: { ! 154: if (t == self) ! 155: { ! 156: gi.dprintf ("WARNING: entity used itself.\n"); ! 157: } ! 158: else ! 159: { ! 160: if (t->use) ! 161: { ! 162: if (t->health < 0) ! 163: { ! 164: if ((g_showlogic) && (g_showlogic->value)) ! 165: gi.dprintf ("target_anger with dead monster!\n"); ! 166: return; ! 167: } ! 168: t->enemy = target; ! 169: t->monsterinfo.aiflags |= AI_TARGET_ANGER; ! 170: FoundTarget (t); ! 171: } ! 172: } ! 173: if (!self->inuse) ! 174: { ! 175: gi.dprintf("entity was removed while using targets\n"); ! 176: return; ! 177: } ! 178: } ! 179: } ! 180: ! 181: } ! 182: ! 183: /*QUAKED target_anger (1 0 0) (-8 -8 -8) (8 8 8) ! 184: This trigger will cause an entity to be angry at another entity when a player touches it. Target the ! 185: entity you want to anger, and killtarget the entity you want it to be angry at. ! 186: ! 187: target - entity to piss off ! 188: killtarget - entity to be pissed off at ! 189: */ ! 190: void SP_target_anger (edict_t *self) ! 191: { ! 192: if (!self->target) ! 193: { ! 194: gi.dprintf("target_anger without target!\n"); ! 195: G_FreeEdict (self); ! 196: return; ! 197: } ! 198: if (!self->killtarget) ! 199: { ! 200: gi.dprintf("target_anger without killtarget!\n"); ! 201: G_FreeEdict (self); ! 202: return; ! 203: } ! 204: ! 205: self->use = target_anger_use; ! 206: self->svflags = SVF_NOCLIENT; ! 207: } ! 208: ! 209: // ================ ! 210: // target_spawn ! 211: // ================ ! 212: /* ! 213: extern edict_t *CreateMonster(vec3_t origin, vec3_t angles, char *classname); ! 214: ! 215: void target_spawn_use (edict_t *self, edict_t *other, edict_t *activator) ! 216: { ! 217: edict_t *newEnt; ! 218: ! 219: newEnt = CreateMonster (self->s.origin, self->s.angles, "monster_infantry"); ! 220: if(newEnt) ! 221: newEnt->enemy = other; ! 222: } ! 223: */ ! 224: ! 225: /*Q U AKED target_spawn (1 0 0) (-32 -32 -24) (32 32 72) ! 226: */ ! 227: /* ! 228: void SP_target_spawn (edict_t *self) ! 229: { ! 230: self->use = target_spawn_use; ! 231: self->svflags = SVF_NOCLIENT; ! 232: } ! 233: */ ! 234: ! 235: // *********************************** ! 236: // target_killplayers ! 237: // *********************************** ! 238: ! 239: void target_killplayers_use (edict_t *self, edict_t *other, edict_t *activator) ! 240: { ! 241: int i; ! 242: edict_t *ent, *player; ! 243: ! 244: // kill the players ! 245: for (i=0 ; i<game.maxclients ; i++) ! 246: { ! 247: player = &g_edicts[1+i]; ! 248: if (!player->inuse) ! 249: continue; ! 250: ! 251: // nail it ! 252: T_Damage (player, self, self, vec3_origin, self->s.origin, vec3_origin, 100000, 0, DAMAGE_NO_PROTECTION, MOD_TELEFRAG); ! 253: } ! 254: ! 255: // kill any visible monsters ! 256: for (ent = g_edicts; ent < &g_edicts[globals.num_edicts] ; ent++) ! 257: { ! 258: if (!ent->inuse) ! 259: continue; ! 260: if (ent->health < 1) ! 261: continue; ! 262: if (!ent->takedamage) ! 263: continue; ! 264: ! 265: for(i=0;i<game.maxclients ; i++) ! 266: { ! 267: player = &g_edicts[1+i]; ! 268: if(!player->inuse) ! 269: continue; ! 270: ! 271: if(visible(player, ent)) ! 272: { ! 273: T_Damage (ent, self, self, vec3_origin, ent->s.origin, vec3_origin, ! 274: ent->health, 0, DAMAGE_NO_PROTECTION, MOD_TELEFRAG); ! 275: break; ! 276: } ! 277: } ! 278: } ! 279: ! 280: } ! 281: ! 282: /*QUAKED target_killplayers (1 0 0) (-8 -8 -8) (8 8 8) ! 283: When triggered, this will kill all the players on the map. ! 284: */ ! 285: void SP_target_killplayers (edict_t *self) ! 286: { ! 287: self->use = target_killplayers_use; ! 288: self->svflags = SVF_NOCLIENT; ! 289: } ! 290: ! 291: /*QUAKED target_blacklight (1 0 1) (-16 -16 -24) (16 16 24) ! 292: Pulsing black light with sphere in the center ! 293: */ ! 294: void blacklight_think (edict_t *self) ! 295: { ! 296: self->s.angles[0] = rand()%360; ! 297: self->s.angles[1] = rand()%360; ! 298: self->s.angles[2] = rand()%360; ! 299: self->nextthink = level.time + 0.1; ! 300: } ! 301: ! 302: void SP_target_blacklight(edict_t *ent) ! 303: { ! 304: if (deathmatch->value) ! 305: { // auto-remove for deathmatch ! 306: G_FreeEdict (ent); ! 307: return; ! 308: } ! 309: ! 310: VectorClear (ent->mins); ! 311: VectorClear (ent->maxs); ! 312: ! 313: ent->s.effects |= (EF_TRACKERTRAIL|EF_TRACKER); ! 314: ent->think = blacklight_think; ! 315: ent->s.modelindex = gi.modelindex ("models/items/spawngro2/tris.md2"); ! 316: ent->s.frame = 1; ! 317: ent->nextthink = level.time + 0.1; ! 318: gi.linkentity (ent); ! 319: } ! 320: ! 321: /*QUAKED target_orb (1 0 1) (-16 -16 -24) (16 16 24) ! 322: Translucent pulsing orb with speckles ! 323: */ ! 324: void orb_think (edict_t *self) ! 325: { ! 326: self->s.angles[0] = rand()%360; ! 327: self->s.angles[1] = rand()%360; ! 328: self->s.angles[2] = rand()%360; ! 329: // self->s.effects |= (EF_TRACKERTRAIL|EF_DOUBLE); ! 330: self->nextthink = level.time + 0.1; ! 331: } ! 332: ! 333: void SP_target_orb(edict_t *ent) ! 334: { ! 335: if (deathmatch->value) ! 336: { // auto-remove for deathmatch ! 337: G_FreeEdict (ent); ! 338: return; ! 339: } ! 340: ! 341: VectorClear (ent->mins); ! 342: VectorClear (ent->maxs); ! 343: ! 344: // ent->s.effects |= EF_TRACKERTRAIL; ! 345: ent->think = orb_think; ! 346: ent->nextthink = level.time + 0.1; ! 347: ent->s.modelindex = gi.modelindex ("models/items/spawngro2/tris.md2"); ! 348: ent->s.frame = 2; ! 349: ent->s.effects |= EF_SPHERETRANS; ! 350: gi.linkentity (ent); ! 351: } ! 352:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.