2006-04-24 01:14:18 +02:00
|
|
|
#include "precompiled.h"
|
|
|
|
#include "ProductionQueue.h"
|
|
|
|
#include "EntityManager.h"
|
2006-06-09 20:32:00 +02:00
|
|
|
#include "EventHandlers.h"
|
|
|
|
#include "Entity.h"
|
2006-04-24 01:14:18 +02:00
|
|
|
#include <algorithm>
|
|
|
|
|
|
|
|
// CProductionItem
|
|
|
|
|
|
|
|
CProductionItem::CProductionItem( int type, const CStrW& name, float totalTime )
|
|
|
|
: m_type(type), m_name(name), m_totalTime(totalTime), m_elapsedTime(0)
|
|
|
|
{
|
|
|
|
ONCE( ScriptingInit(); );
|
|
|
|
}
|
|
|
|
|
|
|
|
CProductionItem::~CProductionItem()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void CProductionItem::Update( size_t timestep )
|
|
|
|
{
|
2006-09-26 03:44:20 +02:00
|
|
|
m_elapsedTime = std::min( m_totalTime, m_elapsedTime + timestep/1000.0f );
|
2006-04-24 01:14:18 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
bool CProductionItem::IsComplete()
|
|
|
|
{
|
|
|
|
return( m_elapsedTime == m_totalTime );
|
|
|
|
}
|
|
|
|
|
|
|
|
float CProductionItem::GetProgress()
|
|
|
|
{
|
|
|
|
return( m_totalTime==0 ? 1.0 : m_elapsedTime/m_totalTime );
|
|
|
|
}
|
|
|
|
|
|
|
|
jsval CProductionItem::JSI_GetProgress( JSContext* UNUSED(cx) )
|
|
|
|
{
|
|
|
|
return ToJSVal( GetProgress() );
|
|
|
|
}
|
|
|
|
|
|
|
|
void CProductionItem::ScriptingInit()
|
|
|
|
{
|
|
|
|
AddProperty(L"type", &CProductionItem::m_type, true);
|
|
|
|
AddProperty(L"name", &CProductionItem::m_name, true);
|
|
|
|
AddProperty(L"elapsedTime", &CProductionItem::m_elapsedTime, true);
|
|
|
|
AddProperty(L"totalTime", &CProductionItem::m_totalTime, true);
|
2007-05-29 21:01:21 +02:00
|
|
|
AddProperty(L"progress", static_cast<GetFn>(&CProductionItem::JSI_GetProgress));
|
2006-04-24 01:14:18 +02:00
|
|
|
CJSObject<CProductionItem>::ScriptingInit("ProductionItem");
|
|
|
|
}
|
|
|
|
|
|
|
|
// CProductionQueue
|
|
|
|
|
|
|
|
CProductionQueue::CProductionQueue( CEntity* owner )
|
|
|
|
: m_owner(owner)
|
|
|
|
{
|
|
|
|
ONCE( ScriptingInit(); );
|
|
|
|
}
|
|
|
|
|
|
|
|
CProductionQueue::~CProductionQueue()
|
2006-07-21 02:05:56 +02:00
|
|
|
{
|
|
|
|
CancelAll();
|
|
|
|
}
|
|
|
|
|
|
|
|
void CProductionQueue::AddItem( int type, const CStrW& name, float totalTime )
|
|
|
|
{
|
|
|
|
m_items.push_back( new CProductionItem( type, name, totalTime ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
void CProductionQueue::CancelAll()
|
2006-04-24 01:14:18 +02:00
|
|
|
{
|
|
|
|
for( size_t i=0; i < m_items.size(); ++i )
|
|
|
|
{
|
2006-06-10 05:05:16 +02:00
|
|
|
// Cancel production of the item
|
|
|
|
CProductionItem* item = m_items[i];
|
|
|
|
CEventCancelProduction evt( item->m_type, item->m_name );
|
|
|
|
m_owner->DispatchEvent( &evt );
|
|
|
|
|
|
|
|
// Free its memory
|
2006-04-24 01:14:18 +02:00
|
|
|
delete m_items[i];
|
|
|
|
}
|
2006-07-21 02:05:56 +02:00
|
|
|
m_items.clear();
|
2006-04-24 01:14:18 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void CProductionQueue::Update( size_t timestep )
|
|
|
|
{
|
|
|
|
if( !m_items.empty() )
|
|
|
|
{
|
|
|
|
CProductionItem* front = m_items.front();
|
|
|
|
front->Update( timestep );
|
|
|
|
if( front->IsComplete() )
|
|
|
|
{
|
|
|
|
CEventFinishProduction evt( front->m_type, front->m_name );
|
|
|
|
m_owner->DispatchEvent( &evt );
|
|
|
|
m_items.erase( m_items.begin() );
|
|
|
|
delete front;
|
|
|
|
}
|
|
|
|
// TODO: Think about what we want to happen when there are multiple productions
|
|
|
|
// with totalTime=0 at the front (pop them all at once or do one per update?)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
jsval CProductionQueue::JSI_GetLength( JSContext* UNUSED(cx) )
|
|
|
|
{
|
|
|
|
return ToJSVal( (int) m_items.size() );
|
|
|
|
}
|
|
|
|
|
2007-05-29 21:01:21 +02:00
|
|
|
jsval_t CProductionQueue::JSI_Get( JSContext* cx, uintN argc, jsval* argv )
|
2006-04-24 01:14:18 +02:00
|
|
|
{
|
|
|
|
debug_assert( argc == 1 );
|
|
|
|
debug_assert( JSVAL_IS_INT(argv[0]) );
|
|
|
|
|
2007-05-29 21:01:21 +02:00
|
|
|
int index = ToPrimitive<int>( argv[0] );
|
2006-04-24 01:14:18 +02:00
|
|
|
|
|
|
|
if(index < 0 || index >= (int)m_items.size() )
|
|
|
|
{
|
|
|
|
JS_ReportError( cx, "Production queue index out of bounds: %d", index );
|
|
|
|
return JSVAL_NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ToJSVal( m_items[index] );
|
|
|
|
}
|
|
|
|
|
|
|
|
bool CProductionQueue::JSI_Cancel( JSContext* cx, uintN argc, jsval* argv )
|
|
|
|
{
|
|
|
|
debug_assert( argc == 1 );
|
|
|
|
debug_assert( JSVAL_IS_INT(argv[0]) );
|
|
|
|
|
2007-05-29 21:01:21 +02:00
|
|
|
int index = ToPrimitive<int>( argv[0] );
|
2006-04-24 01:14:18 +02:00
|
|
|
|
|
|
|
if(index < 0 || index >= (int)m_items.size() )
|
|
|
|
{
|
|
|
|
JS_ReportError( cx, "Production queue index out of bounds: %d", index );
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
CProductionItem* item = m_items[index];
|
|
|
|
CEventCancelProduction evt( item->m_type, item->m_name );
|
|
|
|
m_owner->DispatchEvent( &evt );
|
|
|
|
m_items.erase( m_items.begin() + index );
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CProductionQueue::ScriptingInit()
|
|
|
|
{
|
2007-05-29 21:01:21 +02:00
|
|
|
AddProperty(L"length", static_cast<GetFn>(&CProductionQueue::JSI_GetLength));
|
|
|
|
AddMethod<jsval_t, &CProductionQueue::JSI_Get>( "get", 1 );
|
2006-04-24 01:14:18 +02:00
|
|
|
AddMethod<bool, &CProductionQueue::JSI_Cancel>( "cancel", 1 );
|
|
|
|
CJSObject<CProductionQueue>::ScriptingInit("ProductionQueue");
|
|
|
|
}
|