djcev.com

//

Git Repos / fte_dogmode / qc / misc / modeltrain.qc

Last update to this file was on 2025-08-13 at 05:20.

Show modeltrain.qc

//==============================================================================
// misc_modeltrain -- was plats.qc
//==============================================================================

//======================================================================
// constants
//======================================================================

#ifdef SSQC
//----------------------------------------------------------------------
typedef enum
{
MISC_MODELTRAIN_STYLE_SINGLEANIM = 1 // modeltrain with one animation
} misc_modeltrain_styles;

//----------------------------------------------------------------------
typedef enum
{
MISC_MODELTRAIN_ANIMTYPE_FORWARD = 1,
MISC_MODELTRAIN_ANIMTYPE_BACKFORTH = 2
} misc_modeltrain_animtypes;
#endif

//======================================================================
// fields
//======================================================================

#ifdef SSQC
.float first_frame2;
.float last_frame2;
.float frtime;
.float frtime2;
.float animtype;
.float animtype2;
.float multiplier;

.vector cmins;
.vector cmaxs;

.entity animcontroller;
.entity rotatecontroller;
#endif

//======================================================================
// forward declarations
//======================================================================

#ifdef SSQC
// temp_anim_controller
void() temp_anim_controller_think;
entity(entity own) spawn_temp_anim_controller;
void(entity e) temp_anim_controller_init;
strip void() temp_anim_controller;
#endif

#ifdef SSQC
// temp_rotate_controller
entity(entity own) spawn_temp_rotate_controller;
void(entity e) temp_rotate_controller_init;
strip void() temp_rotate_controller;
#endif

// misc_modeltrain
#if defined(CSQC) || defined(SSQC)
void(entity e) misc_modeltrain_init;
#endif
#ifdef SSQC
void() misc_modeltrain;
#endif

//------------------------------------------------------------------------------

#ifdef SSQC
//----------------------------------------------------------------------
// class temp_anim_controller: base_tempentity
// {
//--------------------------------------------------------------
void() temp_anim_controller_think =
{
local float first, last, step, atype, dir, nextframe;

// train just went from stopped to moving or vice-versa,
// and have both animations set
if ((self.stateflags & STATE_WAITING) !=
(self.owner.stateflags & STATE_WAITING) &&
self.owner.style != MISC_MODELTRAIN_STYLE_SINGLEANIM)
{
if (!(self.owner.stateflags & STATE_WAITING))
// just started moving
self.owner.frame = zeroconvert (
self.owner.first_frame2);
else
// just stopped
self.owner.frame = zeroconvert (
self.owner.first_frame);

// reset back/forth status
self.owner.distance = 1;

if (self.owner.stateflags & STATE_WAITING)
self.stateflags |= STATE_WAITING;
else
self.stateflags &= ~STATE_WAITING;
}
else
{
if (!(self.stateflags & STATE_WAITING) &&
self.owner.style !=
MISC_MODELTRAIN_STYLE_SINGLEANIM)
{
// moving train animation, if set
first = zeroconvert (self.owner.first_frame2);
last = zeroconvert (self.owner.last_frame2);
atype = self.owner.animtype2;
}
else
{
// stopped/default train animation
first = zeroconvert (self.owner.first_frame);
last = zeroconvert (self.owner.last_frame);
atype = self.owner.animtype;
}

if (first > last)
// reverse direction
step = dir = -1;
else
step = dir = 1;

// back-and-forth is going the other way, so invert
// the step's signal
if (self.owner.distance < 0)
step = step * (-1);

nextframe = self.owner.frame + step;

if (atype == MISC_MODELTRAIN_ANIMTYPE_BACKFORTH)
{
if (dir > 0 && (nextframe > last ||
nextframe < first) ||
dir < 0 && (nextframe > first ||
nextframe < last))
{
nextframe = self.owner.frame - step;
self.owner.distance =
self.owner.distance * (-1);
}
}

if (dir > 0)
nextframe = wrap (nextframe, first, last);
else
nextframe = wrap (nextframe, last, first);

self.owner.frame = nextframe;
}

self.think = temp_anim_controller_think;

if (!(self.stateflags & STATE_WAITING) ||
self.owner.style == MISC_MODELTRAIN_STYLE_SINGLEANIM)
{
self.nextthink = time + self.owner.frtime;
}
else
{
self.nextthink = time + self.owner.frtime2;
}
};

//--------------------------------------------------------------
entity(entity own) spawn_temp_anim_controller =
{
local entity e = spawn ();
e.owner = own;
temp_anim_controller_init (e);
return e;
};

//--------------------------------------------------------------
void(entity e) temp_anim_controller_init =
{
e.classname = "animcontroller";
e.classtype = CT_TEMP_ANIM_CONTROLLER;
e.stateflags |= STATE_WAITING;
base_tempentity_init (e);

if (!e.owner)
objerror ("temp_anim_controller_init: no owner!\n");

e.think = temp_anim_controller_think;
e.nextthink = time + 0.2;
};

//--------------------------------------------------------------
strip void() temp_anim_controller =
{
temp_anim_controller_init (self);
};
// };
#endif

#ifdef SSQC
//----------------------------------------------------------------------
// class temp_rotate_controller: base_tempentity
// {
//--------------------------------------------------------------
entity(entity own) spawn_temp_rotate_controller =
{
local entity e = spawn ();
e.owner = own;
temp_rotate_controller_init (e);
return e;
};

//--------------------------------------------------------------
void(entity e) temp_rotate_controller_init =
{
e.classname = "rotatecontroller";
e.classtype = CT_TEMP_ROTATE_CONTROLLER;
base_tempentity_init (e);
};

//--------------------------------------------------------------
strip void() temp_rotate_controller =
{
temp_rotate_controller_init (self);
};
// };
#endif

//----------------------------------------------------------------------
// class misc_modeltrain: base_func_train
// {
#if defined(CSQC) || defined(SSQC)
//--------------------------------------------------------------
void(entity e) misc_modeltrain_init =
{
e.classname = "misc_modeltrain";
e.classtype = CT_MISC_MODELTRAIN;

#ifdef SSQC
precache_model (e.mdl);
base_func_train_init (e);

// TODO CEV func_train spawnflag in misc_modeltrain
if (e.spawnflags & SPAWNFLAG_FUNC_TRAIN_NONSOLID)
{
e.solid = SOLID_NOT;
}
else
{
e.solid = SOLID_BBOX;
if (e.cmins == '0 0 0')
e.cmins = '-8 -8 -8';
if (e.cmaxs == '0 0 0')
e.cmaxs = '8 8 8';
}

e.movetype = MOVETYPE_NOCLIP;
setmodel (e, e.mdl);
setsize (e, e.cmins , e.cmaxs);
setorigin (e, e.origin);

e.rotatecontroller = spawn_temp_rotate_controller (e);
e.animcontroller = spawn_temp_anim_controller (e);

e.distance = 1;

if (!e.frtime)
e.frtime = 0.1;
if (!e.frtime2)
e.frtime2 = e.frtime;
if (!e.multiplier)
e.multiplier = 1;

// make sure all first and last frame fields are filled
if (e.first_frame && !e.last_frame)
e.last_frame = e.first_frame;
else if (!e.first_frame && e.last_frame)
e.first_frame = e.last_frame;

if (e.first_frame2 && !e.last_frame2)
e.last_frame2 = e.first_frame2;
else if (!e.first_frame2 && e.last_frame2)
e.first_frame2 = e.last_frame2;

if (e.first_frame2 == 0)
e.style = MISC_MODELTRAIN_STYLE_SINGLEANIM;

if (!e.animtype)
e.animtype = MISC_MODELTRAIN_ANIMTYPE_FORWARD;
if (!e.animtype2)
e.animtype2 = e.animtype;

e.frame = e.first_frame;

// always spawn waiting -- CEV
e.stateflags |= STATE_WAITING;
#endif
};
#endif

#ifdef SSQC
//--------------------------------------------------------------
void() misc_modeltrain =
{
// new spawnflags for all entities -- iw
if (SUB_Inhibit())
return;

misc_modeltrain_init (self);
};
#endif
// };

Return to the top of this page or return to the overview of this repo.

Log modeltrain.qc

Return to the top of this page or return to the overview of this repo.