forked from 0ad/0ad
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:
parent
84a980a344
commit
1af9aa074e
@ -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" );
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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();
|
||||
}
|
@ -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()
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user