123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179 |
- // Copyright (c) ZeniMax Media Inc.
- // Licensed under the GNU General Public License 2.0.
- #include "../g_local.h"
- /*QUAKED rotating_light (0 .5 .8) (-8 -8 -8) (8 8 8) START_OFF ALARM
- "health" if set, the light may be killed.
- */
- // RAFAEL
- // note to self
- // the lights will take damage from explosions
- // this could leave a player in total darkness very bad
- constexpr spawnflags_t SPAWNFLAG_ROTATING_LIGHT_START_OFF = 1_spawnflag;
- constexpr spawnflags_t SPAWNFLAG_ROTATING_LIGHT_ALARM = 2_spawnflag;
- THINK(rotating_light_alarm) (edict_t *self) -> void
- {
- if (self->spawnflags.has(SPAWNFLAG_ROTATING_LIGHT_START_OFF))
- {
- self->think = nullptr;
- self->nextthink = 0_ms;
- }
- else
- {
- gi.sound(self, CHAN_NO_PHS_ADD | CHAN_VOICE, self->moveinfo.sound_start, 1, ATTN_STATIC, 0);
- self->nextthink = level.time + 1_sec;
- }
- }
- DIE(rotating_light_killed) (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, const vec3_t &point, const mod_t &mod) -> void
- {
- gi.WriteByte(svc_temp_entity);
- gi.WriteByte(TE_WELDING_SPARKS);
- gi.WriteByte(30);
- gi.WritePosition(self->s.origin);
- gi.WriteDir(vec3_origin);
- gi.WriteByte(irandom(0xe0, 0xe8));
- gi.multicast(self->s.origin, MULTICAST_PVS, false);
- self->s.effects &= ~EF_SPINNINGLIGHTS;
- self->use = nullptr;
- self->think = G_FreeEdict;
- self->nextthink = level.time + FRAME_TIME_S;
- }
- USE(rotating_light_use) (edict_t *self, edict_t *other, edict_t *activator) -> void
- {
- if (self->spawnflags.has(SPAWNFLAG_ROTATING_LIGHT_START_OFF))
- {
- self->spawnflags &= ~SPAWNFLAG_ROTATING_LIGHT_START_OFF;
- self->s.effects |= EF_SPINNINGLIGHTS;
- if (self->spawnflags.has(SPAWNFLAG_ROTATING_LIGHT_ALARM))
- {
- self->think = rotating_light_alarm;
- self->nextthink = level.time + FRAME_TIME_S;
- }
- }
- else
- {
- self->spawnflags |= SPAWNFLAG_ROTATING_LIGHT_START_OFF;
- self->s.effects &= ~EF_SPINNINGLIGHTS;
- }
- }
- void SP_rotating_light(edict_t *self)
- {
- self->movetype = MOVETYPE_STOP;
- self->solid = SOLID_BBOX;
- self->s.modelindex = gi.modelindex("models/objects/light/tris.md2");
- self->s.frame = 0;
- self->use = rotating_light_use;
- if (self->spawnflags.has(SPAWNFLAG_ROTATING_LIGHT_START_OFF))
- self->s.effects &= ~EF_SPINNINGLIGHTS;
- else
- {
- self->s.effects |= EF_SPINNINGLIGHTS;
- }
- if (!self->speed)
- self->speed = 32;
- // this is a real cheap way
- // to set the radius of the light
- // self->s.frame = self->speed;
- if (!self->health)
- {
- self->health = 10;
- self->max_health = self->health;
- self->die = rotating_light_killed;
- self->takedamage = true;
- }
- else
- {
- self->max_health = self->health;
- self->die = rotating_light_killed;
- self->takedamage = true;
- }
- if (self->spawnflags.has(SPAWNFLAG_ROTATING_LIGHT_ALARM))
- {
- self->moveinfo.sound_start = gi.soundindex("misc/alarm.wav");
- }
- gi.linkentity(self);
- }
- /*QUAKED func_object_repair (1 .5 0) (-8 -8 -8) (8 8 8)
- object to be repaired.
- The default delay is 1 second
- "delay" the delay in seconds for spark to occur
- */
- THINK(object_repair_fx) (edict_t *ent) -> void
- {
- ent->nextthink = level.time + gtime_t::from_sec(ent->delay);
- if (ent->health <= 100)
- ent->health++;
- else
- {
- gi.WriteByte(svc_temp_entity);
- gi.WriteByte(TE_WELDING_SPARKS);
- gi.WriteByte(10);
- gi.WritePosition(ent->s.origin);
- gi.WriteDir(vec3_origin);
- gi.WriteByte(irandom(0xe0, 0xe8));
- gi.multicast(ent->s.origin, MULTICAST_PVS, false);
- }
- }
- THINK(object_repair_dead) (edict_t *ent) -> void
- {
- G_UseTargets(ent, ent);
- ent->nextthink = level.time + 10_hz;
- ent->think = object_repair_fx;
- }
- THINK(object_repair_sparks) (edict_t *ent) -> void
- {
- if (ent->health <= 0)
- {
- ent->nextthink = level.time + 10_hz;
- ent->think = object_repair_dead;
- return;
- }
- ent->nextthink = level.time + gtime_t::from_sec(ent->delay);
- gi.WriteByte(svc_temp_entity);
- gi.WriteByte(TE_WELDING_SPARKS);
- gi.WriteByte(10);
- gi.WritePosition(ent->s.origin);
- gi.WriteDir(vec3_origin);
- gi.WriteByte(irandom(0xe0, 0xe8));
- gi.multicast(ent->s.origin, MULTICAST_PVS, false);
- }
- void SP_object_repair(edict_t *ent)
- {
- ent->movetype = MOVETYPE_NONE;
- ent->solid = SOLID_BBOX;
- ent->classname = "object_repair";
- ent->mins = { -8, -8, 8 };
- ent->maxs = { 8, 8, 8 };
- ent->think = object_repair_sparks;
- ent->nextthink = level.time + 1_sec;
- ent->health = 100;
- if (!ent->delay)
- ent->delay = 1.0;
- }
|