Added initial version of building placement cursor, which can be shown with the startPlacing(templateName) JS function.

Also activated depth test for selection outlines so they don't overlap
units.

This was SVN commit r2667.
This commit is contained in:
Matei 2005-09-05 19:48:28 +00:00
parent 84a980a344
commit 1af9aa074e
6 changed files with 178 additions and 2 deletions

View File

@ -214,6 +214,7 @@ static void Frame()
// TODO Where does GameView end and other things begin?
g_Mouseover.update( TimeSinceLastFrame );
g_Selection.update();
g_BuildingPlacer.update( TimeSinceLastFrame );
PROFILE_END( "selection and interaction ui" );
PROFILE_START( "sound update" );

View File

@ -244,10 +244,21 @@ void Render()
}
PROFILE_START( "render selection" );
glEnable( GL_DEPTH_TEST );
g_Mouseover.renderSelectionOutlines();
g_Selection.renderSelectionOutlines();
glDisable( GL_DEPTH_TEST );
PROFILE_END( "render selection" );
PROFILE_START( "render building placement cursor" );
if( g_BuildingPlacer.m_active )
{
//glEnable( GL_DEPTH_TEST );
g_BuildingPlacer.render();
//glDisable( GL_DEPTH_TEST );
}
PROFILE_END( "render building placement cursor" );
glPopAttrib();
}
else
@ -790,6 +801,7 @@ void Init(int argc, char* argv[], bool setup_gfx, bool setup_gui)
new CPathfindEngine;
new CSelectedEntities;
new CMouseoverEntities;
new CBuildingPlacer;
new CSessionManager;

View File

@ -14,6 +14,7 @@
#include "BoundingObjects.h"
#include "Unit.h"
#include "Model.h"
#include "simulation/BaseEntityCollection.h"
#include "scripting/GameEvents.h"
extern CConsole* g_Console;
@ -748,6 +749,12 @@ void MouseButtonUpHandler(const SDL_Event *ev, int clicks)
switch( ev->button.button )
{
case SDL_BUTTON_LEFT:
if( g_BuildingPlacer.m_active )
{
g_BuildingPlacer.mouseReleased();
break;
}
if (customSelectionMode)
break;
@ -777,6 +784,12 @@ void MouseButtonUpHandler(const SDL_Event *ev, int clicks)
else
g_Mouseover.setSelection();
break;
case SDL_BUTTON_RIGHT:
if( g_BuildingPlacer.m_active )
{
g_BuildingPlacer.cancel();
break;
}
}
}
@ -904,11 +917,15 @@ int interactInputHandler( const SDL_Event* ev )
button_down_x = ev->button.x;
button_down_y = ev->button.y;
button_down_time = get_time();
if( g_BuildingPlacer.m_active )
{
g_BuildingPlacer.mousePressed();
}
break;
}
break;
case SDL_MOUSEMOTION:
if( !g_Mouseover.isBandbox() && button_down )
if( !g_Mouseover.isBandbox() && button_down && !g_BuildingPlacer.m_active )
{
int deltax = ev->motion.x - button_down_x;
int deltay = ev->motion.y - button_down_y;
@ -953,3 +970,97 @@ void ResetInteraction()
{
customSelectionMode = false;
}
bool CBuildingPlacer::activate(CStrW& templateName)
{
if(m_active)
{
return false;
}
m_templateName = templateName;
m_active = true;
m_clicked = false;
m_dragged = false;
m_angle = 0;
m_timeSinceClick = 0;
//g_Console->InsertMessage( L"BuildingPlacer: Activated with %ls", m_templateName.c_str() );
return true;
}
void CBuildingPlacer::mousePressed()
{
CCamera &g_Camera=*g_Game->GetView()->GetCamera();
clickPos = g_Camera.GetWorldCoordinates();
m_clicked = true;
//g_Console->InsertMessage( L"BuildingPlacer: Clicked (%f, %f, %f)", clickPos.X, clickPos.Y, clickPos.Z );
}
void CBuildingPlacer::mouseReleased()
{
m_active = false; // do it first in case we fail
CBaseEntity* baseEntity = g_EntityTemplateCollection.getTemplate( m_templateName );
//g_Console->InsertMessage( L"BuildingPlacer: Created %ls at (%f, %f, %f) [%f]",
// m_templateName.c_str(), clickPos.X, clickPos.Y, clickPos.Z, m_angle );
HEntity ent = g_EntityManager.create( baseEntity, clickPos, m_angle );
ent->SetPlayer(g_Game->GetLocalPlayer());
}
void CBuildingPlacer::cancel()
{
//g_Console->InsertMessage( L"BuildingPlacer: Cancelled");
m_active = false;
}
void CBuildingPlacer::update( float timeStep )
{
if(!m_active)
return;
if(m_clicked)
{
m_timeSinceClick += timeStep;
CCamera &g_Camera=*g_Game->GetView()->GetCamera();
CVector3D pos = g_Camera.GetWorldCoordinates();
CVector3D dif = pos - clickPos;
float x = dif.X, z = dif.Z;
if(x*x + z*z < 3*3) {
if(m_dragged || m_timeSinceClick > 0.2f)
{
m_angle += timeStep * PI;
}
}
else
{
m_dragged = true;
m_angle = atan2(x, z);
}
}
}
void CBuildingPlacer::render()
{
if(!m_active)
return;
CVector3D pos;
if(m_clicked)
{
pos = clickPos;
}
else
{
CCamera &g_Camera=*g_Game->GetView()->GetCamera();
pos = g_Camera.GetWorldCoordinates();
}
glBegin(GL_LINE_STRIP);
glColor3f(1,1,1);
glVertex3f(pos.X, pos.Y+6, pos.Z);
glColor3f(1,1,1);
glVertex3f(pos.X, pos.Y, pos.Z);
glColor3f(1,1,1);
glVertex3f(pos.X + 3*sin(m_angle), pos.Y, pos.Z + 3*cos(m_angle));
glEnd();
}

View File

@ -113,6 +113,29 @@ struct CMouseoverEntities : public Singleton<CMouseoverEntities>
void stopBandbox();
};
struct CBuildingPlacer : public Singleton<CBuildingPlacer>
{
CBuildingPlacer()
{
m_active = false;
}
CStrW m_templateName;
bool m_active;
bool m_clicked;
bool m_dragged;
float m_angle;
float m_timeSinceClick;
CVector3D clickPos;
bool activate( CStrW& templateName );
void mousePressed();
void mouseReleased();
void cancel();
void update( float timeStep );
void render();
};
bool isMouseoverType( CEntity* ev, void* userdata );
bool isOnScreen( CEntity* ev, void* userdata );
@ -123,4 +146,5 @@ int interactInputHandler( const SDL_Event* ev );
#define g_Selection CSelectedEntities::GetSingleton()
#define g_Mouseover CMouseoverEntities::GetSingleton()
#define g_BuildingPlacer CBuildingPlacer::GetSingleton()

View File

@ -741,6 +741,33 @@ JSBool getGlobal( JSContext* cx, JSObject* globalObject, uint argc, jsval* argv,
return( JS_TRUE );
}
// Activates the building placement cursor for placing a building.
// params: templateName - the name of the entity to place.
// returns: true if cursor was activated, false if cursor was already active.
JSBool startPlacing( JSContext* cx, JSObject* globalObject, uint argc, jsval* argv, jsval* rval )
{
CStrW name;
if(argc == 0) {
name = L"hele_ho"; // save some typing during testing
}
else {
try
{
name = g_ScriptingHost.ValueToUCString( argv[0] );
}
catch( PSERROR_Scripting_ConversionFailed )
{
*rval = JSVAL_NULL;
JS_ReportError( cx, "Invalid template name argument" );
return( JS_TRUE );
}
}
*rval = g_BuildingPlacer.activate(name) ? JS_TRUE : JS_FALSE;
return( JS_TRUE );
}
//-----------------------------------------------------------------------------
// function table
@ -765,6 +792,7 @@ JSFunctionSpec ScriptFunctionTable[] =
JS_FUNC(getEntityByHandle, getEntityByHandle, 1)
JS_FUNC(getEntityTemplate, getEntityTemplate, 1)
JS_FUNC(issueCommand, issueCommand, 2)
JS_FUNC(startPlacing, startPlacing, 1)
// Camera
JS_FUNC(setCameraTarget, setCameraTarget, 1)

View File

@ -664,7 +664,7 @@ void CEntity::renderSelectionOutline( float alpha )
const SPlayerColour& col = m_player->GetColour();
glColor3f( col.r, col.g, col.b );
}
glBegin( GL_LINE_LOOP );
CVector3D pos = m_graphics_position;