1
0
forked from 0ad/0ad

Bug fixes and more game setup options.

- Added "Screenshot Mode" and "Fog of War" game attributes. (Screenshot
Mode causes units to be initialized to Hold stance instead of Aggress
and also forces LOS to be All Visible. Atlas turn on Screenshot Mode by
default so units don't try to kill each other in there.)
- Modified LOSManager to allow disabling fog of war.
- Removed some debug message spam.
- Enabled line antialiasing for aura rendering and fixed some bugs that
caused strange effects (color was not set properly for the center point,
and when a unit was both mouseover'ed and selected, the aura was drawn
twice).
- Modified Stand stance to allow retaliation on attacks (normally Stand
will attack any enemy in LOS, but this is useful if a neutral unit is in
LOS).
- Modified pathfinder to not take into account terrain slope, which is
an expensive calculation - we'll eventually take into account terrain
type instead.

This was SVN commit r4527.
This commit is contained in:
Matei 2006-10-08 17:39:46 +00:00
parent 0a6c4ae103
commit fa229121ec
19 changed files with 120 additions and 41 deletions

View File

@ -79,14 +79,20 @@ bool CTerrain::Initialize(u32 size,const u16* data)
///////////////////////////////////////////////////////////////////////////////
float CTerrain::getExactGroundLevel(const CVector2D& v) const
{
return getExactGroundLevel(v.x, v.y);
}
bool CTerrain::isOnMap(const CVector2D& v) const
{
return isOnMap(v.x, v.y);
}
float CTerrain::getExactGroundLevel(const CVector2D& v) const
bool CTerrain::isPassable(const CVector2D &tileSpaceLoc) const
{
return getExactGroundLevel(v.x, v.y);
// TODO: Take into account the terrain type at this location
return true;
}
///////////////////////////////////////////////////////////////////////////////

View File

@ -54,8 +54,11 @@ public:
return ((x >= 0.0f) && (x < (float)((m_MapSize-1) * CELL_SIZE))
&& (z >= 0.0f) && (z < (float)((m_MapSize-1) * CELL_SIZE)));
}
bool isOnMap(const CVector2D& v) const;
bool isPassable(const CVector2D& tileSpaceLoc) const;
void clampCoordToMap(int& index) const
{
if(index < 0)

View File

@ -185,7 +185,9 @@ CGameAttributes::CGameAttributes():
m_MapFile("test01.pmp"),
m_ResourceLevel("default"),
m_StartingPhase("default"),
m_LOSSetting(2),
m_LOSSetting(0),
m_FogOfWar(true),
m_ScreenshotMode(false),
m_NumSlots(8),
m_UpdateCB(NULL),
m_PlayerUpdateCB(NULL),
@ -204,6 +206,8 @@ CGameAttributes::CGameAttributes():
AddSynchedProperty(L"startingPhase", &m_StartingPhase);
AddSynchedProperty(L"numSlots", &m_NumSlots, &CGameAttributes::OnNumSlotsUpdate);
AddSynchedProperty(L"losSetting", &m_LOSSetting);
AddSynchedProperty(L"fogOfWar", &m_FogOfWar);
AddSynchedProperty(L"screenshotMode", &m_ScreenshotMode);
CXeromyces XeroFile;
if (XeroFile.Load("temp/players.xml") != PSRETURN_OK)

View File

@ -119,6 +119,8 @@ public:
CStrW m_ResourceLevel;
CStrW m_StartingPhase;
uint m_LOSSetting;
bool m_FogOfWar;
bool m_ScreenshotMode;
// Note: we must use the un-internationalized name of the resource level and starting phase

View File

@ -863,7 +863,10 @@ void CMouseoverEntities::renderSelectionOutlines()
std::vector<SMouseoverFader>::iterator it;
for( it = m_mouseover.begin(); it < m_mouseover.end(); it++ )
it->entity->renderSelectionOutline( it->fade );
{
if( !g_Selection.isSelected(it->entity) )
it->entity->renderSelectionOutline( it->fade );
}
glDisable( GL_BLEND );
}
@ -874,13 +877,19 @@ void CMouseoverEntities::renderAuras()
glEnable(GL_BLEND);
for ( it = m_mouseover.begin(); it != m_mouseover.end(); ++it )
it->entity->renderAuras();
{
if( !g_Selection.isSelected(it->entity) )
it->entity->renderAuras();
}
}
void CMouseoverEntities::renderBars()
{
std::vector<SMouseoverFader>::iterator it;
for( it = m_mouseover.begin(); it < m_mouseover.end(); it++ )
it->entity->renderBars();
{
if( !g_Selection.isSelected(it->entity) )
it->entity->renderBars();
}
}
void CMouseoverEntities::renderHealthBars()

View File

@ -264,7 +264,7 @@ JSBool issueCommand( JSContext* cx, JSObject*, uint argc, jsval* argv, jsval* rv
for ( std::vector<CNetMessage*>::iterator it=messages.begin(); it != messages.end(); it++ )
{
g_Console->InsertMessage(L"issueCommand: %hs", (*it)->GetString().c_str());
//g_Console->InsertMessage(L"issueCommand: %hs", (*it)->GetString().c_str());
g_Game->GetSimulation()->QueueLocalCommand(*it);
*rval = g_ScriptingHost.UCStringToValue((*it)->GetString());
}

View File

@ -28,12 +28,28 @@ void SetFromNetString(int &val, const CStrW& string)
val=string.ToInt();
}
template <>
CStrW ToNetString(const bool &val)
{
return val ? CStrW("true") : CStrW("false");
}
template <>
void SetFromNetString(bool &val, const CStrW& string)
{
val = (string == CStrW("true"));
}
template <>
CStrW ToNetString(const CStrW& data)
{ return data; }
{
return data;
}
template <> void SetFromNetString(CStrW& data, const CStrW& string)
{ data=string; }
{
data=string;
}
template <>
CStrW ToNetString(const SColour &data)

View File

@ -366,11 +366,10 @@ bool AStarGoalLowLevel::isPassable( const CVector2D &loc, CPlayer* player )
return false;
}
CVector2D wloc = TilespaceToWorldspace(loc);
float slope = pTerrain->getSlope(wloc.x, wloc.y);
if ( slope < MAXSLOPE )
if ( pTerrain->isPassable(loc) )
{
// If no entity blocking, return true
CVector2D wloc = TilespaceToWorldspace(loc);
CBoundingBox bounds(wloc.x, wloc.y, 0, CELL_SIZE, CELL_SIZE, 3);
if ( getCollisionObject(&bounds, player) == NULL )
{

View File

@ -206,12 +206,12 @@ void CEntity::initAuraData()
size_t i=0;
for ( AuraTable::iterator it=m_auras.begin(); it!=m_auras.end(); ++it, ++i )
{
m_unsnappedPoints[i].resize(SELECTION_CIRCLE_POINTS);
m_unsnappedPoints[i].resize(AURA_CIRCLE_POINTS);
float radius = it->second->m_radius;
for ( int j=0; j<SELECTION_CIRCLE_POINTS; ++j )
for ( int j=0; j<AURA_CIRCLE_POINTS; ++j )
{
float val = j * 2*PI / (float)SELECTION_CIRCLE_POINTS;
float val = j * 2*PI / (float)AURA_CIRCLE_POINTS;
m_unsnappedPoints[i][j] = CVector2D( cosf(val)*radius,
sinf(val)*radius );
}
@ -675,10 +675,18 @@ bool CEntity::Initialize()
CEventInitialize evt;
if( !DispatchEvent( &evt ) )
{
debug_printf("start construction failed, killing self\n");
//debug_printf("start construction failed, killing self\n");
kill();
return false;
}
if( g_EntityManager.m_screenshotMode )
{
// Stay in Hold stance no matter what the init script wanted us to be
m_stanceName = "hold";
stanceChanged();
}
return true;
}

View File

@ -477,5 +477,6 @@ public:
extern int SELECTION_CIRCLE_POINTS;
extern int SELECTION_BOX_POINTS;
extern int SELECTION_SMOOTHNESS_UNIFIED;
extern int AURA_CIRCLE_POINTS;
#endif

View File

@ -11,12 +11,14 @@
#include "maths/MathUtil.h"
#include "Entity.h"
int AURA_CIRCLE_POINTS;
int SELECTION_CIRCLE_POINTS;
int SELECTION_BOX_POINTS;
int SELECTION_SMOOTHNESS_UNIFIED = 9;
CEntityManager::CEntityManager()
: m_collisionPatches(0)
, m_screenshotMode(false)
, m_entities() // janwas: default-initialize entire array;
// CHandle ctor sets m_entity and m_refcount to 0
{
@ -31,6 +33,7 @@ CEntityManager::CEntityManager()
if( SELECTION_SMOOTHNESS_UNIFIED < 0 ) SELECTION_SMOOTHNESS_UNIFIED = 0;
SELECTION_CIRCLE_POINTS = 7 + 2 * SELECTION_SMOOTHNESS_UNIFIED;
SELECTION_BOX_POINTS = 1 + SELECTION_SMOOTHNESS_UNIFIED;
AURA_CIRCLE_POINTS = 7 + 3 * SELECTION_SMOOTHNESS_UNIFIED;
}

View File

@ -62,7 +62,8 @@ friend class CHandle;
//return m_entities[index].m_refcount && !m_entities[index].m_entity->entf_get(ENTF_DESTROYED);
}
public:
bool m_screenshotMode;
CEntityManager();
~CEntityManager();

View File

@ -225,13 +225,11 @@ void CEntity::renderAuras()
if( !(m_bounds && m_visible && !m_auras.empty()) )
return;
const SPlayerColour& col = m_player->GetColour();
const SPlayerColour& playerCol = m_player->GetColour();
glPushMatrix();
glTranslatef(m_graphics_position.X, m_graphics_position.Y,
m_graphics_position.Z);
glBegin(GL_TRIANGLE_FAN);
glVertex3f(0.0f, getAnchorLevel(m_graphics_position.X,
m_graphics_position.Z)-m_graphics_position.Y+.5f, 0.0f);
size_t i=0;
for ( AuraTable::iterator it=m_auras.begin(); it!=m_auras.end(); ++it, ++i )
@ -243,7 +241,10 @@ void CEntity::renderAuras()
//This starts to break when the radius is bigger
if ( it->second->m_radius < 15.0f )
{
for ( int j=0; j<SELECTION_CIRCLE_POINTS; ++j )
glBegin(GL_TRIANGLE_FAN);
glVertex3f(0.0f, getAnchorLevel(m_graphics_position.X,
m_graphics_position.Z)-m_graphics_position.Y+.5f, 0.0f);
for ( int j=0; j<AURA_CIRCLE_POINTS; ++j )
{
CVector2D ypos( m_unsnappedPoints[i][j].x+m_graphics_position.X,
m_unsnappedPoints[i][j].y+m_graphics_position.Z );
@ -257,12 +258,15 @@ void CEntity::renderAuras()
m_unsnappedPoints[i][0].y+m_graphics_position.Z)-
m_graphics_position.Y+.5f, m_unsnappedPoints[i][0].y );
glVertex3f(pos.X, pos.Y, pos.Z);
glEnd(); // GL_TRIANGLE_FAN
}
glEnd();
//Draw edges
glEnable(GL_LINE_SMOOTH);
glLineWidth(1.0f);
glBegin(GL_LINE_LOOP);
glColor3f( col.r, col.g, col.b );
for ( int j=0; j<SELECTION_CIRCLE_POINTS; ++j )
glColor3f( playerCol.r, playerCol.g, playerCol.b );
for ( int j=0; j<AURA_CIRCLE_POINTS; ++j )
{
CVector2D ypos( m_unsnappedPoints[i][j].x+m_graphics_position.X,
m_unsnappedPoints[i][j].y+m_graphics_position.Z );
@ -271,6 +275,7 @@ void CEntity::renderAuras()
glVertex3f(pos.X, pos.Y, pos.Z);
}
glEnd();
glDisable(GL_LINE_SMOOTH);
#else
if ( it->second->m_radius < 15.0f )
{

View File

@ -15,7 +15,7 @@
#include "lib/timer.h"
CLOSManager::CLOSManager() : m_LOSSetting(0)
CLOSManager::CLOSManager() : m_LOSSetting(0), m_FogOfWar(true)
{
#ifdef _2_los
m_Explored = 0;
@ -38,10 +38,11 @@ CLOSManager::~CLOSManager()
#endif
}
void CLOSManager::Initialize(uint losSetting)
void CLOSManager::Initialize(uint losSetting, bool fogOfWar)
{
// Set special LOS setting
m_LOSSetting = losSetting;
m_FogOfWar = fogOfWar;
CTerrain* terrain = g_Game->GetWorld()->GetTerrain();
m_TilesPerSide = terrain->GetVerticesPerSide() - 1;
@ -68,7 +69,7 @@ void CLOSManager::Initialize(uint losSetting)
u16 vis_value = 0;
if(m_LOSSetting == EXPLORED || m_LOSSetting == ALL_VISIBLE)
for(int i = 0; i < 8; i++) vis_value |= LOS_EXPLORED << (i*2);
if(m_LOSSetting == ALL_VISIBLE)
if(m_LOSSetting == ALL_VISIBLE || (m_LOSSetting == EXPLORED && !m_FogOfWar) )
for(int i = 0; i < 8; i++) vis_value |= LOS_VISIBLE << (i*2);
#endif
for(uint x=0; x<m_TilesPerSide; x++)
@ -96,17 +97,23 @@ void CLOSManager::Update()
// Clear the visible array
#ifdef _2_los
for(int x=0; x<m_TilesPerSide; x++)
if( m_FogOfWar )
{
memset(m_Visible[x], 0, m_TilesPerSide*sizeof(int));
for(int x=0; x<m_TilesPerSide; x++)
{
memset(m_Visible[x], 0, m_TilesPerSide*sizeof(int));
}
}
#else
u16 not_all_vis = 0xFFFF;
for(int i = 0; i < 8; i++)
not_all_vis &= ~(LOS_VISIBLE << (i*2));
for(uint y=0; y<m_TilesPerSide; y++)
for(uint x=0; x<m_TilesPerSide; x++)
m_VisibilityMatrix[y][x] &= not_all_vis;
if( m_FogOfWar )
{
u16 not_all_vis = 0xFFFF;
for(int i = 0; i < 8; i++)
not_all_vis &= ~(LOS_VISIBLE << (i*2));
for(uint y=0; y<m_TilesPerSide; y++)
for(uint x=0; x<m_TilesPerSide; x++)
m_VisibilityMatrix[y][x] &= not_all_vis;
}
#endif
// Set visibility for each entity

View File

@ -64,11 +64,12 @@ public:
static const int ALL_VISIBLE = 2;
int m_LOSSetting;
bool m_FogOfWar;
CLOSManager();
~CLOSManager();
void Initialize(uint losSetting); // 0 = normal, 1 = explored, 2 = all visible
void Initialize(uint losSetting, bool fogOfWar); // 0 = normal, 1 = explored, 2 = all visible
void Update();
// Get LOS status for a tile (in tile coordinates)

View File

@ -56,10 +56,11 @@ int CSimulation::Initialize(CGameAttributes* pAttribs)
g_ScriptingHost.RunScript( "scripts/game_startup.js" );
// [2006-06-26 3647ms]
g_EntityManager.m_screenshotMode = pAttribs->m_ScreenshotMode;
g_EntityManager.InitializeAll();
// [2006-06-26: 61ms]
m_pWorld->GetLOSManager()->Initialize(pAttribs->m_LOSSetting);
m_pWorld->GetLOSManager()->Initialize(pAttribs->m_LOSSetting, pAttribs->m_FogOfWar);
m_pWorld->GetTerritoryManager()->Initialize();

View File

@ -20,7 +20,8 @@ void CAggressStance::onIdle()
void CAggressStance::onDamaged(CEntity *source)
{
if( source && m_Entity->m_orderQueue.empty() )
if( source && m_Entity->m_orderQueue.empty()
&& m_Entity->GetPlayer()->GetDiplomaticStance(source->GetPlayer()) != DIPLOMACY_ALLIED )
CStanceUtils::attack( m_Entity, source );
}
@ -33,6 +34,13 @@ void CStandStance::onIdle()
CStanceUtils::attack( m_Entity, target );
}
void CStandStance::onDamaged(CEntity *source)
{
if( source && m_Entity->m_orderQueue.empty()
&& m_Entity->GetPlayer()->GetDiplomaticStance(source->GetPlayer()) != DIPLOMACY_ALLIED )
CStanceUtils::attack( m_Entity, source );
}
// DefendStance /////////////////////////////////////////////////////
void CDefendStance::onIdle()
@ -46,7 +54,8 @@ void CDefendStance::onIdle()
void CDefendStance::onDamaged(CEntity *source)
{
if( source && m_Entity->m_orderQueue.empty() )
if( source && m_Entity->m_orderQueue.empty()
&& m_Entity->GetPlayer()->GetDiplomaticStance(source->GetPlayer()) != DIPLOMACY_ALLIED )
{
// Retaliate only if we can reach the enemy unit without walking farther than our LOS
// radius away from idlePos.

View File

@ -72,7 +72,7 @@ public:
CStandStance(CEntity* ent): CStance(ent) {};
virtual ~CStandStance() {};
virtual void onIdle();
virtual void onDamaged(CEntity* UNUSED(source)) {}; // Empty because onIdle will ensure we're attacking stuff in LOS
virtual void onDamaged(CEntity* source);
virtual bool allowsMovement() { return false; };
virtual bool checkMovement(CVector2D UNUSED(proposedPos)) { return false; }
};

View File

@ -32,6 +32,10 @@ static void InitGame(std::wstring map)
// Make the whole world visible
g_GameAttributes.m_LOSSetting = 2;
g_GameAttributes.m_FogOfWar = false;
// Disable unit AI (and other things that may interfere with making things look nice)
g_GameAttributes.m_ScreenshotMode = true;
// Initialise the game:
g_Game = new CGame();