djcev.com

//

Git Repos / fte_dogmode / qc / misc / model.qc

Last update to this file was on 2024-07-03 at 07:20.

Show model.qc

//==============================================================================
// misc_model -- Joshua Skelton -- misc_model.qc requires math.qc
// Author: Joshua Skelton joshua.skelton@gmail.com
// Edited by: Inky 20201219 Minor changes for a better integration with their
// own code
// Edited by: bmFbr for solid and gravity spawnflags and custom bbox sizes
// Edited by: dumptruck_ds to add start and stop animations
//==============================================================================

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

#ifdef SSQC
const float MISC_MODEL_GRAVITY = 1;
const float MISC_MODEL_SOLID = 2;
const float MISC_MODEL_BACK_AND_FORTH = 4;
const float MISC_MODEL_ONLY_ONCE = 8;
const float MISC_MODEL_PLAY_COUNT = 16;
const float MISC_MODEL_STARTOFF = 32;
#endif

#if defined(CSQC) || defined(SSQC)
enumflags
{
MISC_MODEL_NET_ORIGIN, // origin has changed
MISC_MODEL_NET_MINS, // model size has changed
MISC_MODEL_NET_MAXS, // ^^^
MISC_MODEL_NET_MODEL, // .model has changed
MISC_MODEL_NET_FRAME, // frame has changed
MISC_MODEL_NET_FIRSTFRAME, // first frame
MISC_MODEL_NET_LASTFRAME, // last frame
MISC_MODEL_NET_STATE // active, inactive
};
#endif

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

#if defined(CSQC) || defined(SSQC)
.float first_frame; // The starting frame of the animation
.float last_frame; // The ending frame of the animation
#endif

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

// base_misc_model
#ifdef CSQC
void(float isnew) base_misc_model_netreceive;
float() base_misc_model_predraw;
#endif
#ifdef SSQC
float(entity to, float netflags) base_misc_model_netsend;
void() base_misc_model_think;
void() base_misc_model_use;
#endif
#if defined(CSQC) || defined(SSQC)
void(entity e) base_misc_model_init;
#endif

// misc_model
#if defined(CSQC) || defined(SSQC)
void(entity e) misc_model_init;
#endif
#ifdef SSQC
void() misc_model;
#endif

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

//----------------------------------------------------------------------
// class base_misc_model: base_mapentity
// {
#ifdef CSQC
//--------------------------------------------------------------
void(float isnew) base_misc_model_netreceive =
{
local float netflags = ReadFloat ();

if (netflags & MISC_MODEL_NET_ORIGIN)
{
self.origin_x = ReadCoord ();
self.origin_y = ReadCoord ();
self.origin_z = ReadCoord ();
}

if (netflags & MISC_MODEL_NET_MINS)
{
self.mins_x = ReadCoord ();
self.mins_y = ReadCoord ();
self.mins_z = ReadCoord ();
}

if (netflags & MISC_MODEL_NET_MAXS)
{
self.maxs_x = ReadCoord ();
self.maxs_y = ReadCoord ();
self.maxs_z = ReadCoord ();
}

if (netflags & MISC_MODEL_NET_MODEL)
self.modelindex = ReadFloat ();

if (netflags & MISC_MODEL_NET_FRAME)
self.frame = ReadFloat ();

if (netflags & MISC_MODEL_NET_FIRSTFRAME)
self.first_frame = ReadFloat ();

if (netflags & MISC_MODEL_NET_LASTFRAME)
self.last_frame = ReadFloat ();

if (netflags & MISC_MODEL_NET_STATE)
self.state = ReadFloat ();

if (isnew)
if (self.classtype == CT_MISC_MODEL)
misc_model_init (self);
};

//--------------------------------------------------------------
float() base_misc_model_predraw =
{
// TODO CEV interpolation? animate on the client-side?
if (self.state == STATE_ACTIVE)
return PREDRAW_AUTOADD;
else
return PREDRAW_NEXT;
};
#endif

#ifdef SSQC
//--------------------------------------------------------------
float(entity to, float netflags) base_misc_model_netsend =
{
WriteShort (MSG_ENTITY, self.classtype);
WriteFloat (MSG_ENTITY, netflags);

if (netflags & MISC_MODEL_NET_ORIGIN)
{
WriteCoord (MSG_ENTITY, self.origin_x);
WriteCoord (MSG_ENTITY, self.origin_y);
WriteCoord (MSG_ENTITY, self.origin_z);
}

if (netflags & MISC_MODEL_NET_MINS)
{
WriteCoord (MSG_ENTITY, self.mins_x);
WriteCoord (MSG_ENTITY, self.mins_y);
WriteCoord (MSG_ENTITY, self.mins_z);
}

if (netflags & MISC_MODEL_NET_MAXS)
{
WriteCoord (MSG_ENTITY, self.maxs_x);
WriteCoord (MSG_ENTITY, self.maxs_y);
WriteCoord (MSG_ENTITY, self.maxs_z);
}

if (netflags & MISC_MODEL_NET_MODEL)
WriteFloat (MSG_ENTITY, self.modelindex);

if (netflags & MISC_MODEL_NET_FRAME)
WriteFloat (MSG_ENTITY, self.frame);

if (netflags & MISC_MODEL_NET_FIRSTFRAME)
WriteFloat (MSG_ENTITY, self.first_frame);

if (netflags & MISC_MODEL_NET_LASTFRAME)
WriteFloat (MSG_ENTITY, self.last_frame);

if (netflags & MISC_MODEL_NET_STATE)
WriteFloat (MSG_ENTITY, self.state);

return TRUE;
};

//--------------------------------------------------------------
// misc_model_think -- Handles animation for misc_model entity.
//--------------------------------------------------------------
void() base_misc_model_think =
{
self.nextthink = time + fabs (self.speed);
if (self.estate != STATE_ACTIVE)
return;

self.frame = self.frame + sign (self.speed);

if (self.spawnflags & MISC_MODEL_BACK_AND_FORTH &&
self.frame < self.first_frame)
{
self.speed = -1 * self.speed;
self.frame += 2;
}
else if (self.spawnflags & MISC_MODEL_BACK_AND_FORTH
&& self.frame > self.last_frame)
{
self.speed = -1 * self.speed;
self.frame -= 2;
}
else
{
self.frame = wrap (self.frame, self.first_frame,
self.last_frame);
}

// signal CSQC that the frame has changed -- CEV
self.SendFlags = MISC_MODEL_NET_FRAME;

if (self.spawnflags & MISC_MODEL_ONLY_ONCE &&
self.frame == self.last_frame &&
self.last_frame != self.first_frame)
{
self.nextthink = -1;
}

if (self.spawnflags & MISC_MODEL_PLAY_COUNT &&
self.frame == self.last_frame &&
self.last_frame != self.first_frame)
{
if !(self.count)
objerror ("Error: set count to the number of "
" animation cycles!");
self.cnt = self.cnt + 1;
dprint (ftos(self.cnt));
dprint ("\n");
if (self.cnt != self.count)
return FALSE;
else
self.nextthink = -1;
}
};

//--------------------------------------------------------------
void() base_misc_model_use =
{
if (self.state == STATE_ACTIVE)
{
if (self.spawnflags & MISC_MODEL_SOLID)
self.solid = SOLID_NOT;
self.model = "";

self.state = STATE_INVISIBLE;
setorigin (self, self.origin);
}
else
{
if (self.spawnflags & MISC_MODEL_SOLID)
self.solid = SOLID_BBOX;
self.model = self.mdl;

self.state = STATE_ACTIVE;
setorigin (self, self.origin);
}

// update CSQC
self.SendFlags = MISC_MODEL_NET_STATE;
};
#endif

#if defined(CSQC) || defined(SSQC)
//--------------------------------------------------------------
void(entity e) base_misc_model_init =
{
base_mapentity_init (e);
};
#endif
// };

/*QUAKED misc_model (0 0.5 0.8) (-8 -8 -8) (8 8 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
{
model ({"path" : mdl, "skin" : skin, "frame": frame});
}
An entity for displaying models. A frame range can be given to animate the
model.

mdl: The model to display. Can be of type mdl, bsp, or spr.

frame: The frame to display. Can be used to offset the animation.

first_frame: The starting frame of the animation.

last_frame: The last frame of the animation.
*/
//----------------------------------------------------------------------
// class misc_model: base_misc_model
// {
#if defined(CSQC) || defined(SSQC)
//--------------------------------------------------------------
void(entity e) misc_model_init =
{
e.classname = "misc_model";
e.classtype = CT_MISC_MODEL;
base_misc_model_init (e);

local vector vmin, vmax;

#ifdef CSQC
// only SOLID_BBOX misc_model entities are networked -- CEV
e.movetype = MOVETYPE_NONE;
e.solid = SOLID_BBOX;
vmin = e.mins;
vmax = e.maxs;
setmodelindex (e, e.modelindex);
setorigin (e, e.origin);
setsize (e, vmin, vmax);
e.drawmask = DRAWMASK_NORMAL;
e.predraw = base_misc_model_predraw;
#endif

#ifdef SSQC
if (!e.mdl || e.mdl == "")
objerror ("Model not defined");

if (!e.centeroffset)
e.centeroffset = '0 0 0';

if (!e.mdlsz)
e.mdlsz = '32 32 32';

vmin_x = e.centeroffset_x - (e.mdlsz_x / 2);
vmin_y = e.centeroffset_y - (e.mdlsz_y / 2);
vmin_z = e.centeroffset_z - (e.mdlsz_z / 2);

vmax_x = e.centeroffset_x + (e.mdlsz_x / 2);
vmax_y = e.centeroffset_y + (e.mdlsz_y / 2);
vmax_z = e.centeroffset_z + (e.mdlsz_z / 2);

precache_model (e.mdl);
setmodel (e, e.mdl);
setsize (e, vmin, vmax);

if (e.spawnflags & MISC_MODEL_SOLID)
e.solid = SOLID_BBOX;
else
e.solid = SOLID_NOT;

if (e.spawnflags & MISC_MODEL_GRAVITY)
e.movetype = MOVETYPE_TOSS;
else
e.movetype = MOVETYPE_NONE;

if (!e.frame)
e.frame = e.first_frame;

// Make static (not animate) if not given a frame range, and
// not affected by gravity; also remains active if it has a
// targetname (so it can be killtargeted/toggled)
if (!e.last_frame &&
!(e.spawnflags & MISC_MODEL_GRAVITY) &&
!(e.spawnflags & MISC_MODEL_SOLID) &&
!e.targetname &&
!e.targetname2)
// !(e.spawnflags & MISC_MODEL_DONTMAKESTATIC) &&
{
makestatic (e);
}

// Make static (not animate) if not given a frame range, and
// not affected by gravity
// changed by bmFbr
// if (!e.last_frame &&
// !(e.spawnflags & MISC_MODEL_GRAVITY))
// {
// makestatic (e);
// return;
// }

// if it as a custom animation range
if (e.last_frame)
{
// Default animation speed to 10 fps
if (!e.speed)
e.speed = 0.1;
e.think = base_misc_model_think;
e.nextthink = time + e.speed;
}

if (e.spawnflags & MISC_MODEL_STARTOFF)
e.state = STATE_ACTIVE;
else
e.state = STATE_INVISIBLE;

sub_runvoidas (e, base_misc_model_use);

// network solid misc_model entities to CSQC -- CEV
if (e.solid == SOLID_BBOX)
{
e.SendEntity = base_misc_model_netsend;
// send everything (at first)
e.SendFlags = e.SendFlags | MISC_MODEL_NET_ORIGIN |
MISC_MODEL_NET_MINS | MISC_MODEL_NET_MAXS |
MISC_MODEL_NET_MODEL | MISC_MODEL_NET_FRAME |
MISC_MODEL_NET_FIRSTFRAME |
MISC_MODEL_NET_LASTFRAME;
}
#endif
};
#endif

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

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

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

Log model.qc

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