mirror of
https://github.com/openmoh/openmohaa.git
synced 2025-04-28 21:57:57 +03:00
1005 lines
20 KiB
C++
1005 lines
20 KiB
C++
/*
|
|
===========================================================================
|
|
Copyright (C) 2015 the OpenMoHAA team
|
|
|
|
This file is part of OpenMoHAA source code.
|
|
|
|
OpenMoHAA source code 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.
|
|
|
|
OpenMoHAA source code 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 OpenMoHAA source code; if not, write to the Free Software
|
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
===========================================================================
|
|
*/
|
|
|
|
// viewthing.cpp: Actor code for the Viewthing.
|
|
//
|
|
|
|
#include "animate.h"
|
|
#include "viewthing.h"
|
|
#include "game.h"
|
|
#include "level.h"
|
|
#include "scriptexception.h"
|
|
|
|
Event EV_ViewThing_Think
|
|
(
|
|
"viewthing_think",
|
|
EV_DEFAULT,
|
|
NULL,
|
|
NULL,
|
|
"Called every frame to process the view thing.",
|
|
EV_NORMAL
|
|
);
|
|
Event EV_ViewThing_ToggleAnimate
|
|
(
|
|
"viewanimate",
|
|
EV_CHEAT,
|
|
NULL,
|
|
NULL,
|
|
"Cycle through the animations modes of the current viewthing\n"
|
|
"No Animation\n"
|
|
"Animation with no motion\n"
|
|
"Animation with looping motion\n"
|
|
"Animation with motion\n",
|
|
EV_NORMAL
|
|
);
|
|
Event EV_ViewThing_SetModel
|
|
(
|
|
"viewmodel",
|
|
EV_CHEAT,
|
|
"s",
|
|
"viewthingModel",
|
|
"Set the model of the current viewthing",
|
|
EV_NORMAL
|
|
);
|
|
Event EV_ViewThing_NextFrame
|
|
(
|
|
"viewnext",
|
|
EV_CHEAT,
|
|
NULL,
|
|
NULL,
|
|
"Advance to the next frame of animation of the current viewthing",
|
|
EV_NORMAL
|
|
);
|
|
Event EV_ViewThing_PrevFrame
|
|
(
|
|
"viewprev",
|
|
EV_CHEAT,
|
|
NULL,
|
|
NULL,
|
|
"Advance to the previous frame of animation of the current viewthing",
|
|
EV_NORMAL
|
|
);
|
|
Event EV_ViewThing_NextAnim
|
|
(
|
|
"viewnextanim",
|
|
EV_CHEAT,
|
|
NULL,
|
|
NULL,
|
|
"Advance to the next animation of the current viewthing",
|
|
EV_NORMAL
|
|
);
|
|
Event EV_ViewThing_PrevAnim
|
|
(
|
|
"viewprevanim",
|
|
EV_CHEAT,
|
|
NULL,
|
|
NULL,
|
|
"Advance to the previous animation of the current viewthing",
|
|
EV_NORMAL
|
|
);
|
|
Event EV_ViewThing_ScaleUp
|
|
(
|
|
"viewscaleup",
|
|
EV_CHEAT,
|
|
NULL,
|
|
NULL,
|
|
"Increase the scale of the current viewthing",
|
|
EV_NORMAL
|
|
);
|
|
Event EV_ViewThing_ScaleDown
|
|
(
|
|
"viewscaledown",
|
|
EV_CHEAT,
|
|
NULL,
|
|
NULL,
|
|
"Decrease the scale of the current viewthing",
|
|
EV_NORMAL
|
|
);
|
|
Event EV_ViewThing_SetScale
|
|
(
|
|
"viewscale",
|
|
EV_CHEAT,
|
|
"f",
|
|
"scale",
|
|
"Set the scale of the current viewthing",
|
|
EV_NORMAL
|
|
);
|
|
Event EV_ViewThing_SetYaw
|
|
(
|
|
"viewyaw",
|
|
EV_CHEAT,
|
|
"f",
|
|
"yaw",
|
|
"Set the yaw of the current viewthing",
|
|
EV_NORMAL
|
|
);
|
|
Event EV_ViewThing_SetPitch
|
|
(
|
|
"viewpitch",
|
|
EV_CHEAT,
|
|
"f",
|
|
"pitch",
|
|
"Set the pitch of the current viewthing",
|
|
EV_NORMAL
|
|
);
|
|
Event EV_ViewThing_SetRoll
|
|
(
|
|
"viewroll",
|
|
EV_CHEAT,
|
|
"f",
|
|
"roll",
|
|
"Set the roll of the current viewthing",
|
|
EV_NORMAL
|
|
);
|
|
Event EV_ViewThing_SetAngles
|
|
(
|
|
"viewangles",
|
|
EV_CHEAT,
|
|
"f[0,360]f[0,360]f[0,360]",
|
|
"pitch yaw roll",
|
|
"Set the angles of the current viewthing",
|
|
EV_NORMAL
|
|
);
|
|
Event EV_ViewThing_Spawn
|
|
(
|
|
"viewspawn",
|
|
EV_CHEAT,
|
|
"s",
|
|
"model",
|
|
"Create a viewthing with the specified model",
|
|
EV_NORMAL
|
|
);
|
|
Event EV_ViewThing_Next
|
|
(
|
|
"viewthingnext",
|
|
EV_CHEAT,
|
|
NULL,
|
|
NULL,
|
|
"Change the active viewthing to the next viewthing",
|
|
EV_NORMAL
|
|
);
|
|
Event EV_ViewThing_Prev
|
|
(
|
|
"viewthingprev",
|
|
EV_CHEAT,
|
|
NULL,
|
|
NULL,
|
|
"Change the active viewthing to the previous viewthing",
|
|
EV_NORMAL
|
|
);
|
|
Event EV_ViewThing_Attach
|
|
(
|
|
"viewattach",
|
|
EV_CHEAT,
|
|
"ss",
|
|
"tagname model",
|
|
"Attach a model the the specified tagname",
|
|
EV_NORMAL
|
|
);
|
|
Event EV_ViewThing_Detach
|
|
(
|
|
"viewdetach",
|
|
EV_CHEAT,
|
|
NULL,
|
|
NULL,
|
|
"Detach the current viewthing from its parent",
|
|
EV_NORMAL
|
|
);
|
|
Event EV_ViewThing_DetachAll
|
|
(
|
|
"viewdetachall",
|
|
EV_CHEAT,
|
|
NULL,
|
|
NULL,
|
|
"Detach all the models attached to the current viewthing",
|
|
EV_NORMAL
|
|
);
|
|
Event EV_ViewThing_Delete
|
|
(
|
|
"viewdelete",
|
|
EV_CHEAT,
|
|
NULL,
|
|
NULL,
|
|
"Delete the current viewthing",
|
|
EV_NORMAL
|
|
);
|
|
Event EV_ViewThing_SetOrigin
|
|
(
|
|
"vieworigin",
|
|
EV_CHEAT,
|
|
"fff",
|
|
"x y z",
|
|
"Set the origin of the current viewthing",
|
|
EV_NORMAL
|
|
);
|
|
Event EV_ViewThing_DeleteAll
|
|
(
|
|
"viewdeleteall",
|
|
EV_CHEAT,
|
|
NULL,
|
|
NULL,
|
|
"Delete all viewthings",
|
|
EV_NORMAL
|
|
);
|
|
Event EV_ViewThing_LastFrame
|
|
(
|
|
"viewlastframe",
|
|
EV_DEFAULT,
|
|
NULL,
|
|
NULL,
|
|
"Called when the view things last animation frame is displayed.",
|
|
EV_NORMAL
|
|
);
|
|
Event EV_ViewThing_SaveOffSurfaces
|
|
(
|
|
"viewsavesurfaces",
|
|
EV_DEFAULT,
|
|
NULL,
|
|
NULL,
|
|
"Called after the model is spawned to save off the models original surfaces.",
|
|
EV_NORMAL
|
|
);
|
|
Event EV_ViewThing_PrintTime
|
|
(
|
|
"_viewthing_printtime",
|
|
EV_DEFAULT,
|
|
NULL,
|
|
NULL,
|
|
"Prints out the current level.time.",
|
|
EV_NORMAL
|
|
);
|
|
Event EV_ViewThing_SetAnim
|
|
(
|
|
"viewsetanim",
|
|
EV_CHEAT,
|
|
"f",
|
|
"animNum",
|
|
"Set the animation absolutely based off a floating point value",
|
|
EV_NORMAL
|
|
);
|
|
|
|
CLASS_DECLARATION( Animate, ViewMaster, NULL )
|
|
{
|
|
{ &EV_ViewThing_Spawn, &ViewMaster::Spawn },
|
|
{ &EV_ViewThing_Next, &ViewMaster::Next },
|
|
{ &EV_ViewThing_Prev, &ViewMaster::Prev },
|
|
{ &EV_ViewThing_SetModel, &ViewMaster::SetModelEvent },
|
|
{ &EV_ViewThing_DeleteAll, &ViewMaster::DeleteAll },
|
|
{ &EV_ViewThing_ToggleAnimate, &ViewMaster::PassEvent },
|
|
{ &EV_ViewThing_NextFrame, &ViewMaster::PassEvent },
|
|
{ &EV_ViewThing_PrevFrame, &ViewMaster::PassEvent },
|
|
{ &EV_ViewThing_NextAnim, &ViewMaster::PassEvent },
|
|
{ &EV_ViewThing_PrevAnim, &ViewMaster::PassEvent },
|
|
{ &EV_ViewThing_ScaleUp, &ViewMaster::PassEvent },
|
|
{ &EV_ViewThing_ScaleDown, &ViewMaster::PassEvent },
|
|
{ &EV_ViewThing_SetScale, &ViewMaster::PassEvent },
|
|
{ &EV_ViewThing_SetYaw, &ViewMaster::PassEvent },
|
|
{ &EV_ViewThing_SetPitch, &ViewMaster::PassEvent },
|
|
{ &EV_ViewThing_SetRoll, &ViewMaster::PassEvent },
|
|
{ &EV_ViewThing_SetAngles, &ViewMaster::PassEvent },
|
|
{ &EV_ViewThing_Attach, &ViewMaster::PassEvent },
|
|
{ &EV_ViewThing_Detach, &ViewMaster::PassEvent },
|
|
{ &EV_ViewThing_DetachAll, &ViewMaster::PassEvent },
|
|
{ &EV_ViewThing_Delete, &ViewMaster::PassEvent },
|
|
{ &EV_ViewThing_SetOrigin, &ViewMaster::PassEvent },
|
|
{ &EV_ViewThing_SetAnim, &ViewMaster::PassEvent },
|
|
{ NULL, NULL }
|
|
};
|
|
|
|
ViewMaster Viewmodel;
|
|
|
|
ViewMaster::ViewMaster()
|
|
{
|
|
current_viewthing = NULL;
|
|
}
|
|
|
|
void ViewMaster::Init( void )
|
|
{
|
|
gi.AddCommand( "viewanimate", NULL );
|
|
gi.AddCommand( "viewmodel", NULL );
|
|
gi.AddCommand( "viewnext", NULL );
|
|
gi.AddCommand( "viewprev", NULL );
|
|
gi.AddCommand( "viewnextanim", NULL );
|
|
gi.AddCommand( "viewprevanim", NULL );
|
|
gi.AddCommand( "viewscaleup", NULL );
|
|
gi.AddCommand( "viewscaledown", NULL );
|
|
gi.AddCommand( "viewscale", NULL );
|
|
gi.AddCommand( "viewyaw", NULL );
|
|
gi.AddCommand( "viewpitch", NULL );
|
|
gi.AddCommand( "viewroll", NULL );
|
|
gi.AddCommand( "viewangles", NULL );
|
|
gi.AddCommand( "viewspawn", NULL );
|
|
gi.AddCommand( "viewthingnext", NULL );
|
|
gi.AddCommand( "viewthingprev", NULL );
|
|
gi.AddCommand( "viewattach", NULL );
|
|
gi.AddCommand( "viewdetach", NULL );
|
|
gi.AddCommand( "viewdetachall", NULL );
|
|
gi.AddCommand( "viewdelete", NULL );
|
|
gi.AddCommand( "vieworigin", NULL );
|
|
gi.AddCommand( "viewdeleteall", NULL );
|
|
gi.AddCommand( "viewsetanim", NULL );
|
|
}
|
|
|
|
void ViewMaster::Next
|
|
(
|
|
Event *ev
|
|
)
|
|
|
|
{
|
|
Viewthing *viewthing;
|
|
Entity * ent;
|
|
|
|
ent = ( Entity * )G_FindClass( current_viewthing, "viewthing" );
|
|
if ( ent )
|
|
{
|
|
current_viewthing = ent;
|
|
|
|
viewthing = ( Viewthing * )( ( Entity * )current_viewthing );
|
|
gi.Printf( "current viewthing model %s.\n", viewthing->model.c_str() );
|
|
viewthing->UpdateCvars();
|
|
}
|
|
else
|
|
{
|
|
gi.Printf( "no more viewthings on map.\n" );
|
|
}
|
|
}
|
|
|
|
void ViewMaster::Prev
|
|
(
|
|
Event *ev
|
|
)
|
|
|
|
{
|
|
Viewthing *viewthing;
|
|
Entity *prev;
|
|
Entity *next;
|
|
|
|
next = NULL;
|
|
do
|
|
{
|
|
prev = next;
|
|
next = ( Entity * )G_FindClass( prev, "viewthing" );
|
|
}
|
|
while( next != current_viewthing );
|
|
|
|
if ( prev )
|
|
{
|
|
current_viewthing = prev;
|
|
|
|
viewthing = ( Viewthing * )( ( Entity * )current_viewthing );
|
|
gi.Printf( "current viewthing model %s.\n", viewthing->model.c_str() );
|
|
viewthing->UpdateCvars();
|
|
}
|
|
else
|
|
{
|
|
gi.Printf( "no more viewthings on map.\n" );
|
|
}
|
|
}
|
|
|
|
void ViewMaster::DeleteAll
|
|
(
|
|
Event *ev
|
|
)
|
|
|
|
{
|
|
Entity *next;
|
|
|
|
for( next = ( Entity * )G_FindClass( NULL, "viewthing" ); next != NULL; next = ( Entity * )G_FindClass( next, "viewthing" ) )
|
|
{
|
|
next->PostEvent( EV_Remove, 0 );
|
|
}
|
|
|
|
current_viewthing = NULL;
|
|
}
|
|
|
|
void ViewMaster::Spawn
|
|
(
|
|
Event *ev
|
|
)
|
|
|
|
{
|
|
Viewthing *viewthing;
|
|
str mdl;
|
|
Vector forward;
|
|
Vector up;
|
|
Vector delta;
|
|
Event *event;
|
|
Entity *ent;
|
|
|
|
mdl = ev->GetString( 1 );
|
|
if ( !mdl || !mdl[ 0 ] )
|
|
{
|
|
ScriptError( "Must specify a model name" );
|
|
return;
|
|
}
|
|
|
|
// Check if we have a client
|
|
ent = g_entities[ 0 ].entity;
|
|
assert( ent );
|
|
if ( !ent )
|
|
{
|
|
return;
|
|
}
|
|
|
|
// create a new viewthing
|
|
viewthing = new Viewthing;
|
|
|
|
// set the current_viewthing
|
|
current_viewthing = viewthing;
|
|
|
|
//FIXME FIXME
|
|
ent->angles.AngleVectors( &forward, NULL, &up );
|
|
|
|
viewthing->baseorigin = ent->origin;
|
|
viewthing->baseorigin += forward * 48;
|
|
viewthing->baseorigin += up * 48;
|
|
|
|
viewthing->setOrigin( viewthing->baseorigin );
|
|
viewthing->droptofloor( 256 );
|
|
|
|
viewthing->baseorigin = viewthing->origin;
|
|
|
|
delta = ent->origin - viewthing->origin;
|
|
viewthing->setAngles( delta.toAngles() );
|
|
|
|
event = new Event( EV_ViewThing_SetModel );
|
|
event->AddString( mdl );
|
|
viewthing->ProcessEvent( event );
|
|
|
|
if( !gi.modeltiki( viewthing->model ) )
|
|
{
|
|
ScriptError( "model %s not found, viewmodel not spawned.", mdl.c_str() );
|
|
delete viewthing;
|
|
current_viewthing = NULL;
|
|
return;
|
|
}
|
|
}
|
|
|
|
void ViewMaster::SetModelEvent
|
|
(
|
|
Event *ev
|
|
)
|
|
|
|
{
|
|
str mdl;
|
|
char str[ 128 ];
|
|
Event *event;
|
|
Viewthing *viewthing;
|
|
|
|
mdl = ev->GetString( 1 );
|
|
if ( !mdl || !mdl[ 0 ] )
|
|
{
|
|
ScriptError( "Must specify a model name" );
|
|
return;
|
|
}
|
|
|
|
if ( !current_viewthing )
|
|
{
|
|
// try to find one on the map
|
|
current_viewthing = ( Entity * )G_FindClass( NULL, "viewthing" );
|
|
if ( !current_viewthing )
|
|
{
|
|
ScriptError( "No viewmodel" );
|
|
return;
|
|
}
|
|
}
|
|
|
|
viewthing = ( Viewthing * )( ( Entity * )current_viewthing );
|
|
|
|
// Prepend 'models/' to make things easier
|
|
str[ 0 ] = 0;
|
|
if ( ( mdl[ 1 ] != ':' ) && Q_stricmpn( mdl, "models", 6 ) )
|
|
{
|
|
strcpy( str, "models/" );
|
|
}
|
|
strcat( str, mdl );
|
|
|
|
event = new Event( EV_ViewThing_SetModel );
|
|
event->AddString( str );
|
|
viewthing->ProcessEvent( event );
|
|
viewthing->UpdateCvars();
|
|
}
|
|
|
|
void ViewMaster::PassEvent
|
|
(
|
|
Event *ev
|
|
)
|
|
|
|
{
|
|
Viewthing *viewthing;
|
|
Event *event;
|
|
|
|
if ( !current_viewthing )
|
|
{
|
|
ScriptError( "No viewmodel" );
|
|
return;
|
|
}
|
|
|
|
viewthing = ( Viewthing * )( ( Entity * )current_viewthing );
|
|
if ( viewthing )
|
|
{
|
|
viewthing->ProcessEvent( *ev );
|
|
}
|
|
}
|
|
|
|
CLASS_DECLARATION( Animate, Viewthing, "viewthing" )
|
|
{
|
|
{ &EV_ViewThing_Think, &Viewthing::ThinkEvent },
|
|
{ &EV_ViewThing_LastFrame, &Viewthing::LastFrameEvent },
|
|
{ &EV_ViewThing_ToggleAnimate, &Viewthing::ToggleAnimateEvent },
|
|
{ &EV_ViewThing_SetModel, &Viewthing::SetModelEvent },
|
|
{ &EV_ViewThing_NextFrame, &Viewthing::NextFrameEvent },
|
|
{ &EV_ViewThing_PrevFrame, &Viewthing::PrevFrameEvent },
|
|
{ &EV_ViewThing_NextAnim, &Viewthing::NextAnimEvent },
|
|
{ &EV_ViewThing_PrevAnim, &Viewthing::PrevAnimEvent },
|
|
{ &EV_ViewThing_ScaleUp, &Viewthing::ScaleUpEvent },
|
|
{ &EV_ViewThing_ScaleDown, &Viewthing::ScaleDownEvent },
|
|
{ &EV_ViewThing_SetScale, &Viewthing::SetScaleEvent },
|
|
{ &EV_ViewThing_SetYaw, &Viewthing::SetYawEvent },
|
|
{ &EV_ViewThing_SetPitch, &Viewthing::SetPitchEvent },
|
|
{ &EV_ViewThing_SetRoll, &Viewthing::SetRollEvent },
|
|
{ &EV_ViewThing_SetAngles, &Viewthing::SetAnglesEvent },
|
|
{ &EV_ViewThing_Attach, &Viewthing::AttachModel },
|
|
{ &EV_ViewThing_Detach, &Viewthing::Delete },
|
|
{ &EV_ViewThing_DetachAll, &Viewthing::DetachAll },
|
|
{ &EV_ViewThing_Delete, &Viewthing::Delete },
|
|
{ &EV_ViewThing_SetOrigin, &Viewthing::ChangeOrigin },
|
|
{ &EV_ViewThing_SaveOffSurfaces, &Viewthing::SaveSurfaces },
|
|
{ &EV_ViewThing_PrintTime, &Viewthing::PrintTime },
|
|
{ &EV_ViewThing_SetAnim, &Viewthing::SetAnim },
|
|
{ NULL, NULL }
|
|
};
|
|
|
|
Viewthing::Viewthing
|
|
(
|
|
void
|
|
)
|
|
|
|
{
|
|
frame = 0;
|
|
animstate = 0;
|
|
setSolidType( SOLID_NOT );
|
|
baseorigin = origin;
|
|
Viewmodel.current_viewthing = this;
|
|
edict->s.eType = ET_MODELANIM;
|
|
edict->s.renderfx |= RF_SHADOW;
|
|
edict->s.renderfx |= RF_SHADOW_PRECISE;
|
|
edict->s.renderfx |= RF_EXTRALIGHT;
|
|
|
|
// save off surfaces once the model is spawned
|
|
PostEvent( EV_ViewThing_SaveOffSurfaces, FRAMETIME );
|
|
|
|
PostEvent( EV_ViewThing_Think, FRAMETIME );
|
|
}
|
|
|
|
void Viewthing::PrintTime
|
|
(
|
|
Event *ev
|
|
)
|
|
|
|
{
|
|
gi.Printf( "ev current frame %d leveltime %.2f\n", ev->GetInteger( 1 ), level.time );
|
|
}
|
|
|
|
void Viewthing::UpdateCvars
|
|
(
|
|
qboolean quiet
|
|
)
|
|
|
|
{
|
|
gi.cvar_set("viewmodelentity", va("%d", edict->s.number));
|
|
}
|
|
|
|
|
|
void Viewthing::ThinkEvent
|
|
(
|
|
Event *ev
|
|
)
|
|
|
|
{
|
|
int f;
|
|
if (animstate >= 2)
|
|
{
|
|
Vector forward;
|
|
Vector left;
|
|
Vector up;
|
|
Vector realmove;
|
|
|
|
angles.AngleVectors(&forward, &left, &up);
|
|
realmove = left * accel[1] + up * accel[2] + forward * accel[0];
|
|
setOrigin(baseorigin + realmove);
|
|
gi.cvar_set("viewthingorigin", va("%0.2f,%0.2f,%0.2f", edict->s.origin[0], edict->s.origin[1], edict->s.origin[2]));
|
|
}
|
|
PostEvent(EV_ViewThing_Think, FRAMETIME);
|
|
if ((animstate > 0) && (Viewmodel.current_viewthing == this))
|
|
{
|
|
f = GetTime() / gi.Anim_Frametime(edict->tiki, CurrentAnim());
|
|
if (f != lastframe)
|
|
{
|
|
float time;
|
|
lastframe = f;
|
|
time = f * AnimTime() / NumFrames();
|
|
gi.Printf("current frame %d time %.2f\n", f, time);
|
|
gi.cvar_set("viewmodeltime", va("%.2f", time));
|
|
gi.cvar_set("viewmodelframe", va("%d", f));
|
|
gi.cvar_set("viewmodelanim", AnimName());
|
|
}
|
|
}
|
|
}
|
|
|
|
void Viewthing::LastFrameEvent
|
|
(
|
|
Event *ev
|
|
)
|
|
|
|
{
|
|
}
|
|
|
|
void Viewthing::ToggleAnimateEvent
|
|
(
|
|
Event *ev
|
|
)
|
|
|
|
{
|
|
animstate = ( animstate + 1 ) % 4;
|
|
setOrigin( baseorigin );
|
|
// reset to a known state
|
|
switch( animstate )
|
|
{
|
|
case 0:
|
|
SetFrame();
|
|
gi.Printf( "Animation stopped.\n" );
|
|
gi.cvar_set( "viewmodelanimmode", "Stopped" );
|
|
break;
|
|
case 1:
|
|
NewAnim( CurrentAnim() );
|
|
gi.Printf( "Animation no motion.\n" );
|
|
gi.cvar_set( "viewmodelanimmode", "No Motion" );
|
|
break;
|
|
case 2:
|
|
NewAnim( CurrentAnim(), EV_ViewThing_LastFrame );
|
|
gi.Printf( "Animation with motion and looping.\n" );
|
|
gi.cvar_set( "viewmodelanimmode", "Motion and Looping" );
|
|
break;
|
|
case 3:
|
|
NewAnim( CurrentAnim(), EV_ViewThing_LastFrame );
|
|
gi.Printf( "Animation with motion no looping.\n" );
|
|
gi.cvar_set( "viewmodelanimmode", "Motion and No Looping" );
|
|
break;
|
|
}
|
|
UpdateCvars( qtrue );
|
|
}
|
|
|
|
void Viewthing::SetModelEvent
|
|
(
|
|
Event *ev
|
|
)
|
|
|
|
{
|
|
str modelname;
|
|
|
|
modelname = ev->GetString( 1 );
|
|
|
|
setModel( modelname );
|
|
|
|
if( gi.modeltiki( model ) )
|
|
{
|
|
NewAnim( 0 );
|
|
SetFrame( );
|
|
}
|
|
UpdateCvars();
|
|
}
|
|
|
|
void Viewthing::NextFrameEvent
|
|
(
|
|
Event *ev
|
|
)
|
|
|
|
{
|
|
int numframes;
|
|
|
|
numframes = NumFrames();
|
|
if ( numframes )
|
|
{
|
|
frame = (frame+1)%numframes;
|
|
SetFrame();
|
|
animstate = 0;
|
|
UpdateCvars();
|
|
}
|
|
}
|
|
|
|
void Viewthing::PrevFrameEvent
|
|
(
|
|
Event *ev
|
|
)
|
|
|
|
{
|
|
int numframes;
|
|
|
|
numframes = NumFrames();
|
|
if ( numframes )
|
|
{
|
|
frame = (frame-1)%numframes;
|
|
SetFrame();
|
|
animstate = 0;
|
|
UpdateCvars();
|
|
}
|
|
}
|
|
|
|
void Viewthing::SetAnim
|
|
(
|
|
Event *ev
|
|
)
|
|
|
|
{
|
|
int numanims, anim;
|
|
|
|
numanims = NumAnims();
|
|
if ( numanims )
|
|
{
|
|
// restore original surfaces
|
|
memcpy( edict->s.surfaces, origSurfaces, sizeof( origSurfaces ) );
|
|
|
|
anim = ev->GetFloat( 1 ) * numanims;
|
|
if ( anim >= numanims )
|
|
anim = numanims - 1;
|
|
NewAnim( anim % numanims );
|
|
frame = 0;
|
|
SetFrame();
|
|
animstate = 0;
|
|
UpdateCvars();
|
|
}
|
|
}
|
|
|
|
|
|
void Viewthing::NextAnimEvent
|
|
(
|
|
Event *ev
|
|
)
|
|
|
|
{
|
|
int numanims;
|
|
|
|
numanims = NumAnims();
|
|
if ( numanims )
|
|
{
|
|
// restore original surfaces
|
|
memcpy( edict->s.surfaces, origSurfaces, sizeof( origSurfaces ) );
|
|
|
|
NewAnim( ( CurrentAnim() + 1 ) % numanims );
|
|
frame = 0;
|
|
SetFrame();
|
|
animstate = 0;
|
|
UpdateCvars();
|
|
}
|
|
}
|
|
|
|
void Viewthing::PrevAnimEvent
|
|
(
|
|
Event *ev
|
|
)
|
|
|
|
{
|
|
int anim;
|
|
int numanims;
|
|
|
|
numanims = NumAnims();
|
|
if ( numanims )
|
|
{
|
|
// restore original surfaces
|
|
memcpy( edict->s.surfaces, origSurfaces, sizeof( origSurfaces ) );
|
|
|
|
anim = CurrentAnim() - 1;
|
|
while( anim < 0 )
|
|
{
|
|
anim += numanims;
|
|
}
|
|
NewAnim( anim );
|
|
frame = 0;
|
|
SetFrame();
|
|
animstate = 0;
|
|
UpdateCvars();
|
|
}
|
|
}
|
|
|
|
void Viewthing::ScaleUpEvent
|
|
(
|
|
Event *ev
|
|
)
|
|
|
|
{
|
|
edict->s.scale += 0.01f;
|
|
UpdateCvars();
|
|
}
|
|
|
|
void Viewthing::ScaleDownEvent
|
|
(
|
|
Event *ev
|
|
)
|
|
|
|
{
|
|
edict->s.scale -= 0.01f;
|
|
UpdateCvars();
|
|
}
|
|
|
|
void Viewthing::SetScaleEvent
|
|
(
|
|
Event *ev
|
|
)
|
|
|
|
{
|
|
float s;
|
|
|
|
if ( ev->NumArgs() )
|
|
{
|
|
s = ev->GetFloat( 1 );
|
|
edict->s.scale = s;
|
|
UpdateCvars();
|
|
}
|
|
else
|
|
{
|
|
gi.Printf( "viewscale = %f\n", edict->s.scale );
|
|
}
|
|
}
|
|
|
|
void Viewthing::SetYawEvent
|
|
(
|
|
Event *ev
|
|
)
|
|
|
|
{
|
|
if ( ev->NumArgs() > 0 )
|
|
{
|
|
angles.setYaw( ev->GetFloat( 1 ) );
|
|
setAngles( angles );
|
|
}
|
|
gi.Printf( "yaw = %f\n", angles.yaw() );
|
|
}
|
|
|
|
void Viewthing::SetPitchEvent
|
|
(
|
|
Event *ev
|
|
)
|
|
|
|
{
|
|
if ( ev->NumArgs() > 0 )
|
|
{
|
|
angles.setPitch( ev->GetFloat( 1 ) );
|
|
setAngles( angles );
|
|
}
|
|
gi.Printf( "pitch = %f\n", angles.pitch() );
|
|
}
|
|
|
|
void Viewthing::SetRollEvent
|
|
(
|
|
Event *ev
|
|
)
|
|
|
|
{
|
|
if ( ev->NumArgs() > 0 )
|
|
{
|
|
angles.setRoll( ev->GetFloat( 1 ) );
|
|
setAngles( angles );
|
|
}
|
|
gi.Printf( "roll = %f\n", angles.roll() );
|
|
}
|
|
|
|
void Viewthing::SetAnglesEvent
|
|
(
|
|
Event *ev
|
|
)
|
|
|
|
{
|
|
if ( ev->NumArgs() > 2 )
|
|
{
|
|
angles.x = ev->GetFloat( 1 );
|
|
angles.y = ev->GetFloat( 2 );
|
|
angles.z = ev->GetFloat( 3 );
|
|
setAngles( angles );
|
|
}
|
|
|
|
gi.Printf( "angles = %f, %f, %f\n", angles.x, angles.y, angles.z );
|
|
}
|
|
|
|
void Viewthing::AttachModel
|
|
(
|
|
Event *ev
|
|
)
|
|
|
|
{
|
|
Event * event;
|
|
Viewthing * child;
|
|
|
|
|
|
child = new Viewthing;
|
|
child->setModel( ev->GetString( 2 ) );
|
|
|
|
//
|
|
// attach the child
|
|
//
|
|
event = new Event( EV_Attach );
|
|
event->AddEntity( this );
|
|
event->AddString( ev->GetString( 1 ) );
|
|
child->ProcessEvent( event );
|
|
}
|
|
|
|
void Viewthing::Delete
|
|
(
|
|
Event *ev
|
|
)
|
|
|
|
{
|
|
Viewmodel.current_viewthing = NULL;
|
|
PostEvent( EV_Remove, 0 );
|
|
Viewmodel.PostEvent( EV_ViewThing_Next, 0 );
|
|
}
|
|
|
|
void Viewthing::DetachAll
|
|
(
|
|
Event *ev
|
|
)
|
|
|
|
{
|
|
int i;
|
|
int num;
|
|
|
|
num = numchildren;
|
|
for (i=0;i<MAX_MODEL_CHILDREN;i++)
|
|
{
|
|
Entity * ent;
|
|
if (!children[i])
|
|
continue;
|
|
ent = ( Entity * )G_GetEntity( children[i] );
|
|
ent->PostEvent( EV_Remove, 0 );
|
|
num--;
|
|
if (!num)
|
|
break;
|
|
}
|
|
}
|
|
|
|
void Viewthing::ChangeOrigin
|
|
(
|
|
Event *ev
|
|
)
|
|
|
|
{
|
|
if ( ev->NumArgs() )
|
|
{
|
|
origin.x = ev->GetFloat( 1 );
|
|
origin.y = ev->GetFloat( 2 );
|
|
origin.z = ev->GetFloat( 3 );
|
|
setOrigin( origin );
|
|
baseorigin = origin;
|
|
UpdateCvars();
|
|
}
|
|
gi.Printf( "vieworigin = x%f y%f z%f\n", origin.x, origin.y, origin.z );
|
|
}
|
|
|
|
void Viewthing::SaveSurfaces
|
|
(
|
|
Event *ev
|
|
)
|
|
|
|
{
|
|
memcpy( origSurfaces, edict->s.surfaces, sizeof( origSurfaces ) );
|
|
}
|
|
|