mirror of
https://github.com/blendogames/thirtyflightsofloving.git
synced 2024-11-15 00:41:21 +00:00
166 lines
4.3 KiB
C
166 lines
4.3 KiB
C
|
/*
|
||
|
Copyright (C) 1997-2001 Id Software, Inc.
|
||
|
Copyright (C) 2000-2002 Mr. Hyde and Mad Dog
|
||
|
|
||
|
This program is free software; you can redistribute it and/or
|
||
|
modify it under the terms of the GNU General Public License
|
||
|
as published by the Free Software Foundation; either version 2
|
||
|
of the License, or (at your option) any later version.
|
||
|
|
||
|
This program is distributed in the hope that it will be useful,
|
||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||
|
|
||
|
See the GNU General Public License for more details.
|
||
|
|
||
|
You should have received a copy of the GNU General Public License
|
||
|
along with this program; if not, write to the Free Software
|
||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||
|
|
||
|
*/
|
||
|
|
||
|
#include "g_local.h"
|
||
|
|
||
|
void func_train_find (edict_t *self);
|
||
|
void SP_model_spawn (edict_t *ent);
|
||
|
void train_blocked (edict_t *self, edict_t *other);
|
||
|
void train_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point);
|
||
|
void train_use (edict_t *self, edict_t *other, edict_t *activator);
|
||
|
|
||
|
#define TRAIN_START_ON 1
|
||
|
#define TRAIN_TOGGLE 2
|
||
|
#define TRAIN_BLOCK_STOPS 4
|
||
|
#define PLAYER_MODEL 8
|
||
|
#define NO_MODEL 16
|
||
|
#define MTRAIN_ROTATE 32
|
||
|
#define MTRAIN_ROTATE_CONSTANT 64
|
||
|
#define TRAIN_SMOOTH 128
|
||
|
|
||
|
void model_train_animator(edict_t *animator)
|
||
|
{
|
||
|
edict_t *train;
|
||
|
|
||
|
train = animator->owner;
|
||
|
if(!train || !train->inuse)
|
||
|
{
|
||
|
G_FreeEdict(animator);
|
||
|
return;
|
||
|
}
|
||
|
if(Q_stricmp(train->classname,"model_train"))
|
||
|
{
|
||
|
G_FreeEdict(animator);
|
||
|
return;
|
||
|
}
|
||
|
animator->nextthink = level.time + FRAMETIME;
|
||
|
if(VectorLength(train->velocity) == 0)
|
||
|
return;
|
||
|
train->s.frame++;
|
||
|
if (train->s.frame >= train->framenumbers)
|
||
|
train->s.frame = train->startframe;
|
||
|
gi.linkentity(train);
|
||
|
}
|
||
|
|
||
|
void SP_model_train (edict_t *self)
|
||
|
{
|
||
|
SP_model_spawn (self);
|
||
|
|
||
|
// self->class_id = ENTITY_MODEL_TRAIN;
|
||
|
|
||
|
// Reset s.sound, which SP_model_spawn may have turned on
|
||
|
self->moveinfo.sound_middle = self->s.sound;
|
||
|
self->s.sound = 0;
|
||
|
|
||
|
if(!self->inuse) return;
|
||
|
|
||
|
// Reset some things from SP_model_spawn
|
||
|
self->delay = 0;
|
||
|
self->think = NULL;
|
||
|
self->nextthink = 0;
|
||
|
if (self->health)
|
||
|
{
|
||
|
self->die = train_die;
|
||
|
self->takedamage = DAMAGE_YES;
|
||
|
}
|
||
|
|
||
|
if(self->framenumbers > self->startframe+1)
|
||
|
{
|
||
|
edict_t *animator;
|
||
|
animator = G_Spawn();
|
||
|
animator->owner = self;
|
||
|
animator->think = model_train_animator;
|
||
|
animator->nextthink = level.time + FRAMETIME;
|
||
|
}
|
||
|
self->s.frame = self->startframe;
|
||
|
self->movetype = MOVETYPE_PUSH;
|
||
|
|
||
|
// Really gross stuff here... translate model_spawn spawnflags
|
||
|
// to func_train spawnflags. PLAYER_MODEL and NO_MODEL have
|
||
|
// already been checked in SP_model_spawn and are never re-used,
|
||
|
// so it's OK to overwrite those.
|
||
|
if(self->spawnflags & MTRAIN_ROTATE)
|
||
|
{
|
||
|
self->spawnflags &= ~MTRAIN_ROTATE;
|
||
|
self->spawnflags |= TRAIN_ROTATE;
|
||
|
}
|
||
|
if(self->spawnflags & MTRAIN_ROTATE_CONSTANT)
|
||
|
{
|
||
|
self->spawnflags &= ~MTRAIN_ROTATE_CONSTANT;
|
||
|
self->spawnflags |= TRAIN_ROTATE_CONSTANT;
|
||
|
}
|
||
|
if( (self->spawnflags & (TRAIN_ROTATE | TRAIN_ROTATE_CONSTANT)) == (TRAIN_ROTATE | TRAIN_ROTATE_CONSTANT))
|
||
|
{
|
||
|
self->spawnflags &= ~(TRAIN_ROTATE | TRAIN_ROTATE_CONSTANT);
|
||
|
self->spawnflags |= TRAIN_SPLINE;
|
||
|
}
|
||
|
if(self->style == 3)
|
||
|
self->spawnflags |= TRAIN_ANIMATE; // 32
|
||
|
if(self->style == 4)
|
||
|
self->spawnflags |= TRAIN_ANIMATE_FAST; // 64
|
||
|
|
||
|
// TRAIN_SMOOTH forces trains to go directly to Move_Done from
|
||
|
// Move_Final rather than slowing down (if necessary) for one
|
||
|
// frame.
|
||
|
if (self->spawnflags & TRAIN_SMOOTH)
|
||
|
self->smooth_movement = true;
|
||
|
else
|
||
|
self->smooth_movement = false;
|
||
|
|
||
|
self->blocked = train_blocked;
|
||
|
if (self->spawnflags & TRAIN_BLOCK_STOPS)
|
||
|
self->dmg = 0;
|
||
|
else
|
||
|
{
|
||
|
if (!self->dmg)
|
||
|
self->dmg = 100;
|
||
|
}
|
||
|
|
||
|
if (!self->speed)
|
||
|
self->speed = 100;
|
||
|
|
||
|
self->moveinfo.speed = self->speed;
|
||
|
self->moveinfo.accel = self->moveinfo.decel = self->moveinfo.speed;
|
||
|
|
||
|
self->use = train_use;
|
||
|
|
||
|
gi.linkentity (self);
|
||
|
|
||
|
if (self->target)
|
||
|
{
|
||
|
// start trains on the second frame, to make sure their targets have had
|
||
|
// a chance to spawn
|
||
|
self->nextthink = level.time + FRAMETIME;
|
||
|
self->think = func_train_find;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
gi.dprintf ("model_train without a target at %s\n", vtos(self->absmin));
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
void SP_model_train_origin (edict_t *self)
|
||
|
{
|
||
|
self->spawnflags |= TRAIN_ORIGIN;
|
||
|
SP_model_train (self);
|
||
|
}
|