openmohaa/code/cgame/cg_swipe.cpp
2023-04-30 14:52:12 +02:00

289 lines
7.8 KiB
C++

/*
===========================================================================
Copyright (C) 2023 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
===========================================================================
*/
// DESCRIPTION:
// General swiping functions
#include "cg_commands.h"
swipething_t m_swipes[MAX_SWIPES];
extern int current_entity_number;
extern refEntity_t *current_entity;
extern dtiki_t* current_tiki;
extern centity_t *current_centity;
void ClientGameCommandManager::SwipeOn
(
Event *ev
)
{
// Make a swipe for this if available
int i;
int freeswipe = -1;
str tagname_start,tagname_end;
qhandle_t shader;
if ( ev->NumArgs () != 4 )
return;
shader = cgi.R_RegisterShader( ev->GetString( 1 ) );
tagname_start = ev->GetString( 2 );
tagname_end = ev->GetString( 3 );
for ( i=0; i < MAX_SWIPES; i++ )
{
swipething_t &swipe = m_swipes[i];
if ( !swipe.enabled ||
(
( swipe.entitynum == current_entity_number ) &&
( tagname_start == swipe.tagname_start ) &&
( tagname_end == swipe.tagname_end ) &&
( shader == swipe.shader )
)
)
{
freeswipe = i;
break;
}
}
if ( freeswipe == -1 )
return;
swipething_t &swipe = m_swipes[freeswipe];
if ( !swipe.enabled )
{
swipe.Init ();
swipe.enabled = qtrue;
swipe.entitynum = current_entity_number;
}
swipe.shader = cgi.R_RegisterShader( ev->GetString( 1 ) );
swipe.tagname_start = ev->GetString ( 2 );
swipe.tagname_end = ev->GetString ( 3 );
swipe.life = ev->GetFloat ( 4 ) * 1000.f;
if ( current_centity )
current_centity->clientFlags |= CF_UPDATESWIPE;
}
void ClientGameCommandManager::SwipeOff
(
Event *ev
)
{
qboolean was_enabled;
int i;
was_enabled = qfalse;
for ( i=0; i < MAX_SWIPES; i++ )
{
swipething_t &swipe = m_swipes[i];
if ( swipe.enabled && swipe.entitynum == current_entity_number )
{
swipe.enabled = qfalse;
was_enabled = qtrue;
}
}
if ( was_enabled )
{
//cgi.R_SwipeBegin ( 0.f, 0.f, -1 );
//cgi.R_SwipeEnd ();
if ( current_centity )
current_centity->clientFlags &= ~CF_UPDATESWIPE;
}
}
void ClientGameCommandManager::Swipe
(
Event *ev
)
{
// This does a swipe effect on the entity
int i,swipenum;
orientation_t or;
int tagnum_start,tagnum_end;
qboolean add_cnt_point = qfalse;
vec3_t tmp;
assert(current_entity);
assert(current_tiki);
if (!current_entity || !current_tiki)
{
return;
}
// Let's find us a new (or current) swipe
for ( swipenum=0; swipenum < MAX_SWIPES; swipenum++ )
{
swipething_t &swipe = m_swipes[swipenum];
if ( swipe.enabled && swipe.entitynum == current_entity_number )
{
while ( swipe.num_live_swipes > 1 )
{
i = ( swipe.first_swipe + 1 ) % MAX_SWIPE_POINTS;
swipepoint_t &swipepoint = swipe.swipepoints[i];
if ( swipepoint.time < cg.time - swipe.life )
{
// then let's delete the previous
swipe.first_swipe = ( swipe.first_swipe + 1 ) % MAX_SWIPE_POINTS;
swipe.num_live_swipes--;
}
else
{
break;
}
}
if ( swipe.num_live_swipes == 1 )
{
swipepoint_t &swipepoint = swipe.swipepoints[swipe.first_swipe];
if ( swipepoint.time < cg.time - swipe.life )
{
swipe.num_live_swipes = 0;
}
}
swipe.cntPoint.time = cg.time;
VectorCopy ( current_entity->origin, swipe.cntPoint.points[0] );
tagnum_start = cgi.Tag_NumForName( current_tiki, swipe.tagname_start.c_str() );
or = cgi.TIKI_Orientation(current_entity, tagnum_start);
// Clear out the points
VectorClear ( tmp );
VectorClear ( swipe.cntPoint.points[0] );
VectorClear ( swipe.cntPoint.points[1] );
if ( ev->NumArgs() > 0 )
VectorCopy( ev->GetVector( 1 ), tmp );
else
VectorCopy ( current_entity->origin, tmp );
// Transform the origin of the tag by the axis of the entity and add it to the origin of the entity
for ( i = 0; i < 3; i++ )
{
VectorMA ( tmp, or.origin[i], current_entity->axis[i], tmp );
}
// Copy tmp into the startpoint
VectorCopy ( tmp, swipe.cntPoint.points[0] );
tagnum_end = cgi.Tag_NumForName( current_tiki, swipe.tagname_end.c_str() );
or = cgi.TIKI_Orientation(current_entity, tagnum_end);
if ( ev->NumArgs() > 0 )
VectorCopy( ev->GetVector( 1 ), tmp );
else
VectorCopy ( current_entity->origin, tmp );
// Transform the origin of the tag by the axis of the entity and add it to the origin of the entity
for ( i = 0; i < 3; i++ )
{
VectorMA ( tmp, or.origin[i], current_entity->axis[i], tmp );
}
// Copy tmp into the startpoint
VectorCopy ( tmp, swipe.cntPoint.points[1] );
if ( swipe.num_live_swipes == 0 )
add_cnt_point = qtrue;
else
{
float deltime = swipe.life / float ( MAX_SWIPES );
swipepoint_t &lastpoint = swipe.swipepoints[ ( swipe.first_swipe + swipe.num_live_swipes - 1 ) % MAX_SWIPE_POINTS];
if ( swipe.cntPoint.time - lastpoint.time >= deltime )
add_cnt_point = qtrue;
}
cgi.R_SwipeBegin ( cg.time, swipe.life, swipe.shader );
if ( add_cnt_point )
{
swipepoint_t &swipepoint = swipe.swipepoints[ ( swipe.first_swipe + swipe.num_live_swipes ) % MAX_SWIPE_POINTS];
swipepoint = swipe.cntPoint;
if ( swipe.num_live_swipes == MAX_SWIPE_POINTS )
swipe.first_swipe = ( swipe.first_swipe + 1 ) % MAX_SWIPE_POINTS;
else
swipe.num_live_swipes++;
}
for ( i = 0; i != swipe.num_live_swipes; i++ )
{
swipepoint_t &swipepoint = swipe.swipepoints[ ( swipe.first_swipe + i ) % MAX_SWIPE_POINTS];
cgi.R_SwipePoint ( swipepoint.points[0], swipepoint.points[1], swipepoint.time );
}
if ( !add_cnt_point )
cgi.R_SwipePoint ( swipe.cntPoint.points[0], swipe.cntPoint.points[1], swipe.cntPoint.time );
cgi.R_SwipeEnd ();
}
}
}
void ClientGameCommandManager::ClearSwipes
(
void
)
{
int i;
for ( i=0; i < MAX_SWIPES; i++ )
{
swipething_t &swipe = m_swipes[i];
swipe.enabled = qfalse;
}
cgi.R_SwipeBegin ( 0.f, 0.f, -1 );
cgi.R_SwipeEnd ();
}
/*
===================
CG_ClearSwipes
This is called at startup and for tournement restarts
===================
*/
void CG_ClearSwipes( void )
{
commandManager.ClearSwipes();
}