@ -57,11 +57,24 @@ static multimap<int32_t, EventHandler> tickQueue;
//TODO: consider unordered_map of pairs, or unordered_map of unordered_set, or whatever
//TODO: consider unordered_map of pairs, or unordered_map of unordered_set, or whatever
static multimap < Plugin * , EventHandler > handlers [ EventType : : EVENT_MAX ] ;
static multimap < Plugin * , EventHandler > handlers [ EventType : : EVENT_MAX ] ;
static int32_t eventLastTick [ EventType : : EVENT_MAX ] ;
static map < EventHandler : : callback_t , int32_t > eventLastTick ;
static const int32_t ticksPerYear = 403200 ;
static const int32_t ticksPerYear = 403200 ;
void DFHack : : EventManager : : registerListener ( EventType : : EventType e , EventHandler handler , Plugin * plugin ) {
void DFHack : : EventManager : : registerListener ( EventType : : EventType e , EventHandler handler , Plugin * plugin ) {
if ( e = = EventType : : TICK ) {
int32_t when = 0 ;
df : : world * world = df : : global : : world ;
if ( world ) {
when = world - > frame_counter + handler . freq ;
} else {
if ( Once : : doOnce ( " EventManager registerListener unhonored absolute=false " ) )
Core : : getInstance ( ) . getConsole ( ) . print ( " EventManager::registerTick: warning! absolute flag=false not honored. \n " ) ;
}
handler . when = when ;
tickQueue . insert ( pair < int32_t , EventHandler > ( handler . when , handler ) ) ;
}
eventLastTick [ handler . eventHandler ] = - 1 ;
handlers [ e ] . insert ( pair < Plugin * , EventHandler > ( plugin , handler ) ) ;
handlers [ e ] . insert ( pair < Plugin * , EventHandler > ( plugin , handler ) ) ;
}
}
@ -75,8 +88,9 @@ int32_t DFHack::EventManager::registerTick(EventHandler handler, int32_t when, P
Core : : getInstance ( ) . getConsole ( ) . print ( " EventManager::registerTick: warning! absolute flag=false not honored. \n " ) ;
Core : : getInstance ( ) . getConsole ( ) . print ( " EventManager::registerTick: warning! absolute flag=false not honored. \n " ) ;
}
}
}
}
handler . freq = when ;
handler . when = when ;
tickQueue . insert ( pair < int32_t , EventHandler > ( handler . freq , handler ) ) ;
tickQueue . insert ( pair < int32_t , EventHandler > ( handler . when , handler ) ) ;
eventLastTick [ handler . eventHandler ] = - 1 ;
handlers [ EventType : : TICK ] . insert ( pair < Plugin * , EventHandler > ( plugin , handler ) ) ;
handlers [ EventType : : TICK ] . insert ( pair < Plugin * , EventHandler > ( plugin , handler ) ) ;
return when ;
return when ;
}
}
@ -103,22 +117,29 @@ void DFHack::EventManager::unregister(EventType::EventType e, EventHandler handl
continue ;
continue ;
}
}
i = handlers [ e ] . erase ( i ) ;
i = handlers [ e ] . erase ( i ) ;
eventLastTick . erase ( handler . eventHandler ) ;
if ( e = = EventType : : TICK )
if ( e = = EventType : : TICK )
removeFromTickQueue ( handler ) ;
removeFromTickQueue ( handler ) ;
}
}
}
}
void DFHack : : EventManager : : unregisterAll ( Plugin * plugin ) {
void DFHack : : EventManager : : unregisterAll ( Plugin * plugin ) {
for ( auto i = handlers [ EventType : : TICK ] . find ( plugin ) ; i ! = handlers [ EventType : : TICK ] . end ( ) ; i + + ) {
for ( auto i = handlers [ EventType : : TICK ] . find ( plugin ) ; i ! = handlers [ EventType : : TICK ] . end ( ) ; + + i ) {
if ( ( * i ) . first ! = plugin )
if ( ( * i ) . first ! = plugin )
break ;
break ;
eventLastTick . erase ( i - > second . eventHandler ) ;
removeFromTickQueue ( ( * i ) . second ) ;
removeFromTickQueue ( ( * i ) . second ) ;
}
}
for ( size_t a = 0 ; a < ( size_t ) EventType : : EVENT_MAX ; a + + ) {
for ( auto & event_type : handlers ) {
handlers [ a ] . erase ( plugin ) ;
for ( auto i = event_type . find ( plugin ) ; i ! = event_type . end ( ) ; + + i ) {
if ( ( * i ) . first ! = plugin )
break ;
eventLastTick . erase ( i - > second . eventHandler ) ;
}
event_type . erase ( plugin ) ;
}
}
return ;
}
}
static void manageTickEvent ( color_ostream & out ) ;
static void manageTickEvent ( color_ostream & out ) ;
@ -294,9 +315,9 @@ void DFHack::EventManager::onStateChange(color_ostream& out, state_change_event
lastReportInteraction = - 1 ;
lastReportInteraction = - 1 ;
reportToRelevantUnitsTime = - 1 ;
reportToRelevantUnitsTime = - 1 ;
reportToRelevantUnits . clear ( ) ;
reportToRelevantUnits . clear ( ) ;
for ( size_t a = 0 ; a < EventType : : EVENT_MAX ; a + + ) {
// for ( size_t a = 0; a < EventType::EVENT_MAX; a++ ) {
eventLastTick [ a ] = - 1 ; //-1000000;
// eventLastTick[a] = -1;//-1000000;
}
// }
for ( size_t a = 0 ; a < df : : global : : world - > history . figures . size ( ) ; a + + ) {
for ( size_t a = 0 ; a < df : : global : : world - > history . figures . size ( ) ; a + + ) {
df : : historical_figure * unit = df : : global : : world - > history . figures [ a ] ;
df : : historical_figure * unit = df : : global : : world - > history . figures [ a ] ;
if ( unit - > id < 0 & & unit - > name . language < 0 )
if ( unit - > id < 0 & & unit - > name . language < 0 )
@ -318,23 +339,21 @@ void DFHack::EventManager::manageEvents(color_ostream& out) {
int32_t tick = df : : global : : world - > frame_counter ;
int32_t tick = df : : global : : world - > frame_counter ;
for ( size_t a = 0 ; a < EventType : : EVENT_MAX ; a + + ) {
for ( size_t type = 0 ; type < EventType : : EVENT_MAX ; type + + ) {
if ( handlers [ a ] . empty ( ) )
if ( handlers [ type ] . empty ( ) )
continue ;
continue ;
int32_t eventFrequency = - 100 ;
bool call_events = false ;
if ( a ! = EventType : : TICK )
for ( auto & iter : handlers [ type ] ) {
for ( auto b = handlers [ a ] . begin ( ) ; b ! = handlers [ a ] . end ( ) ; b + + ) {
EventHandler handler = iter . second ;
EventHandler bob = ( * b ) . second ;
int32_t last_tick = eventLastTick [ handler . eventHandler ] ;
if ( bob . freq < eventFrequency | | eventFrequency = = - 100 )
if ( tick - last_tick > = handler . freq ) {
eventFrequency = bob . freq ;
//todo: integrate into every sub-function
//eventLastTick[handler.eventHandler] = tick;
call_events = true ;
}
}
else eventFrequency = 1 ;
}
if ( call_events )
if ( tick > = eventLastTick [ a ] & & tick - eventLastTick [ a ] < eventFrequency )
eventManager [ type ] ( out ) ;
continue ;
eventManager [ a ] ( out ) ;
eventLastTick [ a ] = tick ;
}
}
}
}
@ -353,14 +372,15 @@ static void manageTickEvent(color_ostream& out) {
}
}
if ( toRemove . empty ( ) )
if ( toRemove . empty ( ) )
return ;
return ;
for ( auto a = handlers [ EventType : : TICK ] . begin ( ) ; a ! = handlers [ EventType : : TICK ] . end ( ) ; ) {
for ( auto iter = handlers [ EventType : : TICK ] . begin ( ) ; iter ! = handlers [ EventType : : TICK ] . end ( ) ; ) {
EventHandler handle = ( * a ) . second ;
EventHandler & handle = iter - > second ;
if ( toRemove . find ( handle ) = = toRemove . end ( ) ) {
if ( toRemove . find ( handle ) = = toRemove . end ( ) ) {
a + + ;
+ + iter ;
continue ;
continue ;
}
}
a = handlers [ EventType : : TICK ] . erase ( a ) ;
iter = handlers [ EventType : : TICK ] . erase ( iter ) ;
toRemove . erase ( handle ) ;
toRemove . erase ( handle ) ;
registerTick ( handle , handle . freq , iter - > first ) ;
if ( toRemove . empty ( ) )
if ( toRemove . empty ( ) )
break ;
break ;
}
}
@ -380,14 +400,20 @@ static void manageJobInitiatedEvent(color_ostream& out) {
return ; //no new jobs
return ; //no new jobs
}
}
multimap < Plugin * , EventHandler > copy ( handlers [ EventType : : JOB_INITIATED ] . begin ( ) , handlers [ EventType : : JOB_INITIATED ] . end ( ) ) ;
multimap < Plugin * , EventHandler > copy ( handlers [ EventType : : JOB_INITIATED ] . begin ( ) , handlers [ EventType : : JOB_INITIATED ] . end ( ) ) ;
int32_t tick = df : : global : : world - > frame_counter ;
for ( auto & iter : copy ) {
auto & handler = iter . second ;
if ( tick - eventLastTick [ handler . eventHandler ] > = handler . freq ) {
eventLastTick [ handler . eventHandler ] = tick ;
for ( df : : job_list_link * link = & df : : global : : world - > jobs . list ; link ! = NULL ; link = link - > next ) {
for ( df : : job_list_link * link = & df : : global : : world - > jobs . list ; link ! = NULL ; link = link - > next ) {
if ( link - > item = = NULL )
if ( link - > item = = NULL )
continue ;
continue ;
if ( link - > item - > id < = lastJobId )
if ( link - > item - > id < = lastJobId )
continue ;
continue ;
for ( auto i = copy . begin ( ) ; i ! = copy . end ( ) ; i + + ) {
( * i ) . second . eventHandler ( out , ( void * ) link - > item ) ;
handler . eventHandler ( out , ( void * ) link - > item ) ;
}
}
}
}
}
@ -406,8 +432,11 @@ TODO: consider checking item creation / experience gain just in case
static void manageJobCompletedEvent ( color_ostream & out ) {
static void manageJobCompletedEvent ( color_ostream & out ) {
if ( ! df : : global : : world )
if ( ! df : : global : : world )
return ;
return ;
int32_t tick0 = eventLastTick [ EventType : : JOB_COMPLETED ] ;
static int32_t last_tick = - 1 ;
int32_t tick1 = df : : global : : world - > frame_counter ;
int32_t tick = df : : global : : world - > frame_counter ;
if ( tick < last_tick ) {
last_tick = tick ;
}
multimap < Plugin * , EventHandler > copy ( handlers [ EventType : : JOB_COMPLETED ] . begin ( ) , handlers [ EventType : : JOB_COMPLETED ] . end ( ) ) ;
multimap < Plugin * , EventHandler > copy ( handlers [ EventType : : JOB_COMPLETED ] . begin ( ) , handlers [ EventType : : JOB_COMPLETED ] . end ( ) ) ;
map < int32_t , df : : job * > nowJobs ;
map < int32_t , df : : job * > nowJobs ;
@ -433,7 +462,7 @@ static void manageJobCompletedEvent(color_ostream& out) {
" completion_timer : %d \n "
" completion_timer : %d \n "
" workerID : %d \n "
" workerID : %d \n "
" time : %d -> %d \n "
" time : %d -> %d \n "
" \n " , job1 . list_link - > item , job1 . id , job1 . job_type , ENUM_ATTR ( job_type , caption , job1 . job_type ) , job1 . flags . bits . working , job1 . completion_timer , getWorkerID ( & job1 ) , tick0 , tick 1 ) ;
" \n " , job1 . list_link - > item , job1 . id , job1 . job_type , ENUM_ATTR ( job_type , caption , job1 . job_type ) , job1 . flags . bits . working , job1 . completion_timer , getWorkerID ( & job1 ) , last_ tick, tick ) ;
}
}
for ( auto i = prevJobs . begin ( ) ; i ! = prevJobs . end ( ) ; i + + ) {
for ( auto i = prevJobs . begin ( ) ; i ! = prevJobs . end ( ) ; i + + ) {
df : : job & job0 = * ( * i ) . second ;
df : : job & job0 = * ( * i ) . second ;
@ -447,7 +476,7 @@ static void manageJobCompletedEvent(color_ostream& out) {
" completion_timer : %d \n "
" completion_timer : %d \n "
" workerID : %d \n "
" workerID : %d \n "
" time : %d -> %d \n "
" time : %d -> %d \n "
, job0 . list_link = = NULL ? 0 : job0 . list_link - > item , job0 . id , job0 . job_type , ENUM_ATTR ( job_type , caption , job0 . job_type ) , job0 . flags . bits . working , job0 . completion_timer , getWorkerID ( & job0 ) , tick0 , tick 1 ) ;
, job0 . list_link = = NULL ? 0 : job0 . list_link - > item , job0 . id , job0 . job_type , ENUM_ATTR ( job_type , caption , job0 . job_type ) , job0 . flags . bits . working , job0 . completion_timer , getWorkerID ( & job0 ) , last_ tick, tick ) ;
continue ;
continue ;
}
}
df : : job & job1 = * ( * j ) . second ;
df : : job & job1 = * ( * j ) . second ;
@ -474,14 +503,18 @@ static void manageJobCompletedEvent(color_ostream& out) {
job0 . flags . bits . working , job1 . flags . bits . working ,
job0 . flags . bits . working , job1 . flags . bits . working ,
job0 . completion_timer , job1 . completion_timer ,
job0 . completion_timer , job1 . completion_timer ,
getWorkerID ( & job0 ) , getWorkerID ( & job1 ) ,
getWorkerID ( & job0 ) , getWorkerID ( & job1 ) ,
tick0 , tick 1
last_ tick, tick
) ;
) ;
}
}
# endif
# endif
for ( auto & iter : copy ) {
auto & handler = iter . second ;
if ( tick - eventLastTick [ handler . eventHandler ] > = handler . freq ) {
eventLastTick [ handler . eventHandler ] = tick ;
for ( auto i = prevJobs . begin ( ) ; i ! = prevJobs . end ( ) ; i + + ) {
for ( auto i = prevJobs . begin ( ) ; i ! = prevJobs . end ( ) ; i + + ) {
//if it happened within a tick, must have been cancelled by the user or a plugin: not completed
//if it happened within a tick, must have been cancelled by the user or a plugin: not completed
if ( tick1 < = tick0 )
if ( tick < = last_ tick )
continue ;
continue ;
if ( nowJobs . find ( ( * i ) . first ) ! = nowJobs . end ( ) ) {
if ( nowJobs . find ( ( * i ) . first ) ! = nowJobs . end ( ) ) {
@ -496,9 +529,7 @@ static void manageJobCompletedEvent(color_ostream& out) {
continue ;
continue ;
//still false positive if cancelled at EXACTLY the right time, but experiments show this doesn't happen
//still false positive if cancelled at EXACTLY the right time, but experiments show this doesn't happen
for ( auto j = copy . begin ( ) ; j ! = copy . end ( ) ; j + + ) {
handler . eventHandler ( out , ( void * ) & job0 ) ;
( * j ) . second . eventHandler ( out , ( void * ) & job0 ) ;
}
continue ;
continue ;
}
}
@ -507,8 +538,8 @@ static void manageJobCompletedEvent(color_ostream& out) {
if ( job0 . flags . bits . repeat | | job0 . completion_timer ! = 0 )
if ( job0 . flags . bits . repeat | | job0 . completion_timer ! = 0 )
continue ;
continue ;
for ( auto j = copy . begin ( ) ; j ! = copy . end ( ) ; j + + ) {
handler . eventHandler ( out , ( void * ) & job0 ) ;
(* j ) . second . eventHandler ( out , ( void * ) & job0 ) ;
}
}
}
}
}
@ -528,12 +559,18 @@ static void manageJobCompletedEvent(color_ostream& out) {
df : : job * newJob = Job : : cloneJobStruct ( ( * j ) . second , true ) ;
df : : job * newJob = Job : : cloneJobStruct ( ( * j ) . second , true ) ;
prevJobs [ newJob - > id ] = newJob ;
prevJobs [ newJob - > id ] = newJob ;
}
}
last_tick = tick ;
}
}
static void manageUnitDeathEvent ( color_ostream & out ) {
static void manageUnitDeathEvent ( color_ostream & out ) {
if ( ! df : : global : : world )
if ( ! df : : global : : world )
return ;
return ;
multimap < Plugin * , EventHandler > copy ( handlers [ EventType : : UNIT_DEATH ] . begin ( ) , handlers [ EventType : : UNIT_DEATH ] . end ( ) ) ;
multimap < Plugin * , EventHandler > copy ( handlers [ EventType : : UNIT_DEATH ] . begin ( ) , handlers [ EventType : : UNIT_DEATH ] . end ( ) ) ;
int32_t tick = df : : global : : world - > frame_counter ;
for ( auto & iter : copy ) {
auto & handler = iter . second ;
if ( tick - eventLastTick [ handler . eventHandler ] > = handler . freq ) {
eventLastTick [ handler . eventHandler ] = tick ;
for ( size_t a = 0 ; a < df : : global : : world - > units . all . size ( ) ; a + + ) {
for ( size_t a = 0 ; a < df : : global : : world - > units . all . size ( ) ; a + + ) {
df : : unit * unit = df : : global : : world - > units . all [ a ] ;
df : : unit * unit = df : : global : : world - > units . all [ a ] ;
//if ( unit->counters.death_id == -1 ) {
//if ( unit->counters.death_id == -1 ) {
@ -545,11 +582,11 @@ static void manageUnitDeathEvent(color_ostream& out) {
if ( livingUnits . find ( unit - > id ) = = livingUnits . end ( ) )
if ( livingUnits . find ( unit - > id ) = = livingUnits . end ( ) )
continue ;
continue ;
for ( auto i = copy . begin ( ) ; i ! = copy . end ( ) ; i + + ) {
handler . eventHandler ( out , ( void * ) intptr_t ( unit - > id ) ) ;
( * i ) . second . eventHandler ( out , ( void * ) intptr_t ( unit - > id ) ) ;
}
livingUnits . erase ( unit - > id ) ;
livingUnits . erase ( unit - > id ) ;
}
}
}
}
}
}
static void manageItemCreationEvent ( color_ostream & out ) {
static void manageItemCreationEvent ( color_ostream & out ) {
@ -562,27 +599,32 @@ static void manageItemCreationEvent(color_ostream& out) {
}
}
multimap < Plugin * , EventHandler > copy ( handlers [ EventType : : ITEM_CREATED ] . begin ( ) , handlers [ EventType : : ITEM_CREATED ] . end ( ) ) ;
multimap < Plugin * , EventHandler > copy ( handlers [ EventType : : ITEM_CREATED ] . begin ( ) , handlers [ EventType : : ITEM_CREATED ] . end ( ) ) ;
int32_t tick = df : : global : : world - > frame_counter ;
size_t index = df : : item : : binsearch_index ( df : : global : : world - > items . all , nextItem , false ) ;
size_t index = df : : item : : binsearch_index ( df : : global : : world - > items . all , nextItem , false ) ;
if ( index ! = 0 ) index - - ;
if ( index ! = 0 ) index - - ;
for ( size_t a = index ; a < df : : global : : world - > items . all . size ( ) ; a + + ) {
for ( auto & iter : copy ) {
auto & handler = iter . second ;
if ( tick - eventLastTick [ handler . eventHandler ] > = handler . freq ) {
eventLastTick [ handler . eventHandler ] = tick ;
for ( size_t a = index ; a < df : : global : : world - > items . all . size ( ) ; a + + ) {
df : : item * item = df : : global : : world - > items . all [ a ] ;
df : : item * item = df : : global : : world - > items . all [ a ] ;
//already processed
//already processed
if ( item - > id < nextItem )
if ( item - > id < nextItem )
continue ;
continue ;
//invaders
//invaders
if ( item - > flags . bits . foreign )
if ( item - > flags . bits . foreign )
continue ;
continue ;
//traders who bring back your items?
//traders who bring back your items?
if ( item - > flags . bits . trader )
if ( item - > flags . bits . trader )
continue ;
continue ;
//migrants
//migrants
if ( item - > flags . bits . owned )
if ( item - > flags . bits . owned )
continue ;
continue ;
//spider webs don't count
//spider webs don't count
if ( item - > flags . bits . spider_web )
if ( item - > flags . bits . spider_web )
continue ;
continue ;
for ( auto i = copy . begin ( ) ; i ! = copy . end ( ) ; i + + ) {
handler . eventHandler ( out , ( void * ) intptr_t ( item - > id ) ) ;
(* i ) . second . eventHandler ( out , ( void * ) intptr_t ( item - > id ) ) ;
}
}
}
}
}
nextItem = * df : : global : : item_next_id ;
nextItem = * df : : global : : item_next_id ;
@ -598,7 +640,12 @@ static void manageBuildingEvent(color_ostream& out) {
* consider looking at jobs : building creation / destruction
* consider looking at jobs : building creation / destruction
* */
* */
multimap < Plugin * , EventHandler > copy ( handlers [ EventType : : BUILDING ] . begin ( ) , handlers [ EventType : : BUILDING ] . end ( ) ) ;
multimap < Plugin * , EventHandler > copy ( handlers [ EventType : : BUILDING ] . begin ( ) , handlers [ EventType : : BUILDING ] . end ( ) ) ;
//first alert people about new buildings
int32_t tick = df : : global : : world - > frame_counter ;
//no more separation between new and destroyed events
for ( auto & iter : copy ) {
auto & handler = iter . second ;
if ( tick - eventLastTick [ handler . eventHandler ] > = handler . freq ) {
eventLastTick [ handler . eventHandler ] = tick ;
for ( int32_t a = nextBuilding ; a < * df : : global : : building_next_id ; a + + ) {
for ( int32_t a = nextBuilding ; a < * df : : global : : building_next_id ; a + + ) {
int32_t index = df : : building : : binsearch_index ( df : : global : : world - > buildings . all , a ) ;
int32_t index = df : : building : : binsearch_index ( df : : global : : world - > buildings . all , a ) ;
if ( index = = - 1 ) {
if ( index = = - 1 ) {
@ -607,10 +654,8 @@ static void manageBuildingEvent(color_ostream& out) {
continue ;
continue ;
}
}
buildings . insert ( a ) ;
buildings . insert ( a ) ;
for ( auto b = copy . begin ( ) ; b ! = copy . end ( ) ; b + + ) {
handler . eventHandler ( out , ( void * ) intptr_t ( a ) ) ;
EventHandler bob = ( * b ) . second ;
bob . eventHandler ( out , ( void * ) intptr_t ( a ) ) ;
}
}
}
nextBuilding = * df : : global : : building_next_id ;
nextBuilding = * df : : global : : building_next_id ;
@ -622,13 +667,11 @@ static void manageBuildingEvent(color_ostream& out) {
a + + ;
a + + ;
continue ;
continue ;
}
}
handler . eventHandler ( out , ( void * ) intptr_t ( id ) ) ;
for ( auto b = copy . begin ( ) ; b ! = copy . end ( ) ; b + + ) {
EventHandler bob = ( * b ) . second ;
bob . eventHandler ( out , ( void * ) intptr_t ( id ) ) ;
}
a = buildings . erase ( a ) ;
a = buildings . erase ( a ) ;
}
}
}
}
}
}
static void manageConstructionEvent ( color_ostream & out ) {
static void manageConstructionEvent ( color_ostream & out ) {
@ -637,6 +680,11 @@ static void manageConstructionEvent(color_ostream& out) {
//unordered_set<df::construction*> constructionsNow(df::global::world->constructions.begin(), df::global::world->constructions.end());
//unordered_set<df::construction*> constructionsNow(df::global::world->constructions.begin(), df::global::world->constructions.end());
multimap < Plugin * , EventHandler > copy ( handlers [ EventType : : CONSTRUCTION ] . begin ( ) , handlers [ EventType : : CONSTRUCTION ] . end ( ) ) ;
multimap < Plugin * , EventHandler > copy ( handlers [ EventType : : CONSTRUCTION ] . begin ( ) , handlers [ EventType : : CONSTRUCTION ] . end ( ) ) ;
int32_t tick = df : : global : : world - > frame_counter ;
for ( auto & iter : copy ) {
auto & handler = iter . second ;
if ( tick - eventLastTick [ handler . eventHandler ] > = handler . freq ) {
eventLastTick [ handler . eventHandler ] = tick ;
for ( auto a = constructions . begin ( ) ; a ! = constructions . end ( ) ; ) {
for ( auto a = constructions . begin ( ) ; a ! = constructions . end ( ) ; ) {
df : : construction & construction = ( * a ) . second ;
df : : construction & construction = ( * a ) . second ;
if ( df : : construction : : find ( construction . pos ) ! = NULL ) {
if ( df : : construction : : find ( construction . pos ) ! = NULL ) {
@ -645,13 +693,9 @@ static void manageConstructionEvent(color_ostream& out) {
}
}
//construction removed
//construction removed
//out.print("Removed construction (%d,%d,%d)\n", construction.pos.x,construction.pos.y,construction.pos.z);
//out.print("Removed construction (%d,%d,%d)\n", construction.pos.x,construction.pos.y,construction.pos.z);
for ( auto b = copy . begin ( ) ; b ! = copy . end ( ) ; b + + ) {
handler . eventHandler ( out , ( void * ) & construction ) ;
EventHandler handle = ( * b ) . second ;
handle . eventHandler ( out , ( void * ) & construction ) ;
}
a = constructions . erase ( a ) ;
a = constructions . erase ( a ) ;
}
}
//for ( auto a = constructionsNow.begin(); a != constructionsNow.end(); a++ ) {
//for ( auto a = constructionsNow.begin(); a != constructionsNow.end(); a++ ) {
for ( auto a = df : : global : : world - > constructions . begin ( ) ; a ! = df : : global : : world - > constructions . end ( ) ; a + + ) {
for ( auto a = df : : global : : world - > constructions . begin ( ) ; a ! = df : : global : : world - > constructions . end ( ) ; a + + ) {
df : : construction * construction = * a ;
df : : construction * construction = * a ;
@ -661,9 +705,8 @@ static void manageConstructionEvent(color_ostream& out) {
continue ;
continue ;
//construction created
//construction created
//out.print("Created construction (%d,%d,%d)\n", construction->pos.x,construction->pos.y,construction->pos.z);
//out.print("Created construction (%d,%d,%d)\n", construction->pos.x,construction->pos.y,construction->pos.z);
for ( auto b = copy . begin ( ) ; b ! = copy . end ( ) ; b + + ) {
handler . eventHandler ( out , ( void * ) construction ) ;
EventHandler handle = ( * b ) . second ;
}
handle . eventHandler ( out , ( void * ) construction ) ;
}
}
}
}
}
}
@ -673,6 +716,11 @@ static void manageSyndromeEvent(color_ostream& out) {
return ;
return ;
multimap < Plugin * , EventHandler > copy ( handlers [ EventType : : SYNDROME ] . begin ( ) , handlers [ EventType : : SYNDROME ] . end ( ) ) ;
multimap < Plugin * , EventHandler > copy ( handlers [ EventType : : SYNDROME ] . begin ( ) , handlers [ EventType : : SYNDROME ] . end ( ) ) ;
int32_t highestTime = - 1 ;
int32_t highestTime = - 1 ;
int32_t tick = df : : global : : world - > frame_counter ;
for ( auto & iter : copy ) {
auto & handler = iter . second ;
if ( tick - eventLastTick [ handler . eventHandler ] > = handler . freq ) {
eventLastTick [ handler . eventHandler ] = tick ;
for ( auto a = df : : global : : world - > units . all . begin ( ) ; a ! = df : : global : : world - > units . all . end ( ) ; a + + ) {
for ( auto a = df : : global : : world - > units . all . begin ( ) ; a ! = df : : global : : world - > units . all . end ( ) ; a + + ) {
df : : unit * unit = * a ;
df : : unit * unit = * a ;
/*
/*
@ -688,9 +736,8 @@ static void manageSyndromeEvent(color_ostream& out) {
continue ;
continue ;
SyndromeData data ( unit - > id , b ) ;
SyndromeData data ( unit - > id , b ) ;
for ( auto c = copy . begin ( ) ; c ! = copy . end ( ) ; c + + ) {
handler . eventHandler ( out , ( void * ) & data ) ;
EventHandler handle = ( * c ) . second ;
}
handle . eventHandler ( out , ( void * ) & data ) ;
}
}
}
}
}
}
@ -706,9 +753,13 @@ static void manageInvasionEvent(color_ostream& out) {
return ;
return ;
nextInvasion = df : : global : : ui - > invasions . next_id ;
nextInvasion = df : : global : : ui - > invasions . next_id ;
for ( auto a = copy . begin ( ) ; a ! = copy . end ( ) ; a + + ) {
int32_t tick = df : : global : : world - > frame_counter ;
EventHandler handle = ( * a ) . second ;
for ( auto & iter : copy ) {
handle . eventHandler ( out , ( void * ) intptr_t ( nextInvasion - 1 ) ) ;
auto & handler = iter . second ;
if ( tick - eventLastTick [ handler . eventHandler ] > = handler . freq ) {
eventLastTick [ handler . eventHandler ] = tick ;
handler . eventHandler ( out , ( void * ) intptr_t ( nextInvasion - 1 ) ) ;
}
}
}
}
}
@ -719,10 +770,14 @@ static void manageEquipmentEvent(color_ostream& out) {
unordered_map < int32_t , InventoryItem > itemIdToInventoryItem ;
unordered_map < int32_t , InventoryItem > itemIdToInventoryItem ;
unordered_set < int32_t > currentlyEquipped ;
unordered_set < int32_t > currentlyEquipped ;
for ( auto a = df : : global : : world - > units . all . begin ( ) ; a ! = df : : global : : world - > units . all . end ( ) ; a + + ) {
int32_t tick = df : : global : : world - > frame_counter ;
for ( auto & iter : copy ) {
auto & handler = iter . second ;
if ( tick - eventLastTick [ handler . eventHandler ] > = handler . freq ) {
eventLastTick [ handler . eventHandler ] = tick ;
for ( auto unit : df : : global : : world - > units . all ) {
itemIdToInventoryItem . clear ( ) ;
itemIdToInventoryItem . clear ( ) ;
currentlyEquipped . clear ( ) ;
currentlyEquipped . clear ( ) ;
df : : unit * unit = * a ;
/*if ( unit->flags1.bits.inactive )
/*if ( unit->flags1.bits.inactive )
continue ;
continue ;
*/
*/
@ -730,69 +785,62 @@ static void manageEquipmentEvent(color_ostream& out) {
auto oldEquipment = equipmentLog . find ( unit - > id ) ;
auto oldEquipment = equipmentLog . find ( unit - > id ) ;
bool hadEquipment = oldEquipment ! = equipmentLog . end ( ) ;
bool hadEquipment = oldEquipment ! = equipmentLog . end ( ) ;
vector < InventoryItem > * temp ;
vector < InventoryItem > * temp ;
if ( hadEquipment ) {
if ( hadEquipment ) {
temp = & ( ( * oldEquipment ) . second ) ;
temp = & ( ( * oldEquipment ) . second ) ;
} else {
} else {
temp = new vector < InventoryItem > ;
temp = new vector < InventoryItem > ;
}
}
//vector<InventoryItem>& v = (*oldEquipment).second;
//vector<InventoryItem>& v = (*oldEquipment).second;
vector < InventoryItem > & v = * temp ;
vector < InventoryItem > & v = * temp ;
for ( auto b = v . begin ( ) ; b ! = v . end ( ) ; b + + ) {
for ( auto & item : v ) {
InventoryItem & i = * b ;
itemIdToInventoryItem [ item . itemId ] = item ;
itemIdToInventoryItem [ i . itemId ] = i ;
}
}
for ( size_t b = 0 ; b < unit - > inventory . size ( ) ; b + + ) {
for ( size_t b = 0 ; b < unit - > inventory . size ( ) ; b + + ) {
df : : unit_inventory_item * dfitem_new = unit - > inventory [ b ] ;
df : : unit_inventory_item * dfitem_new = unit - > inventory [ b ] ;
currentlyEquipped . insert ( dfitem_new - > item - > id ) ;
currentlyEquipped . insert ( dfitem_new - > item - > id ) ;
InventoryItem item_new ( dfitem_new - > item - > id , * dfitem_new ) ;
InventoryItem item_new ( dfitem_new - > item - > id , * dfitem_new ) ;
auto c = itemIdToInventoryItem . find ( dfitem_new - > item - > id ) ;
auto c = itemIdToInventoryItem . find ( dfitem_new - > item - > id ) ;
if ( c = = itemIdToInventoryItem . end ( ) ) {
if ( c = = itemIdToInventoryItem . end ( ) ) {
//new item equipped (probably just picked up)
//new item equipped (probably just picked up)
InventoryChangeData data ( unit - > id , NULL , & item_new ) ;
InventoryChangeData data ( unit - > id , NULL , & item_new ) ;
for ( auto h = copy . begin ( ) ; h ! = copy . end ( ) ; h + + ) {
handler . eventHandler ( out , ( void * ) & data ) ;
EventHandler handle = ( * h ) . second ;
handle . eventHandler ( out , ( void * ) & data ) ;
}
continue ;
continue ;
}
}
InventoryItem item_old = ( * c ) . second ;
InventoryItem item_old = ( * c ) . second ;
df : : unit_inventory_item & item0 = item_old . item ;
df : : unit_inventory_item & item0 = item_old . item ;
df : : unit_inventory_item & item1 = item_new . item ;
df : : unit_inventory_item & item1 = item_new . item ;
if ( item0 . mode = = item1 . mode & & item0 . body_part_id = = item1 . body_part_id & & item0 . wound_id = = item1 . wound_id )
if ( item0 . mode = = item1 . mode & & item0 . body_part_id = = item1 . body_part_id & &
item0 . wound_id = = item1 . wound_id )
continue ;
continue ;
//some sort of change in how it's equipped
//some sort of change in how it's equipped
InventoryChangeData data ( unit - > id , & item_old , & item_new ) ;
InventoryChangeData data ( unit - > id , & item_old , & item_new ) ;
for ( auto h = copy . begin ( ) ; h ! = copy . end ( ) ; h + + ) {
handler . eventHandler ( out , ( void * ) & data ) ;
EventHandler handle = ( * h ) . second ;
handle . eventHandler ( out , ( void * ) & data ) ;
}
}
}
//check for dropped items
//check for dropped items
for ( auto b = v . begin ( ) ; b ! = v . end ( ) ; b + + ) {
for ( auto b = v . begin ( ) ; b ! = v . end ( ) ; b + + ) {
InventoryItem i = * b ;
InventoryItem i = * b ;
if ( currentlyEquipped . find ( i . itemId ) ! = currentlyEquipped . end ( ) )
if ( currentlyEquipped . find ( i . itemId ) ! = currentlyEquipped . end ( ) )
continue ;
continue ;
//TODO: delete ptr if invalid
//TODO: delete ptr if invalid
InventoryChangeData data ( unit - > id , & i , NULL ) ;
InventoryChangeData data ( unit - > id , & i , NULL ) ;
for ( auto h = copy . begin ( ) ; h ! = copy . end ( ) ; h + + ) {
handler . eventHandler ( out , ( void * ) & data ) ;
EventHandler handle = ( * h ) . second ;
handle . eventHandler ( out , ( void * ) & data ) ;
}
}
}
if ( ! hadEquipment )
if ( ! hadEquipment )
delete temp ;
delete temp ;
//update equipment
//update equipment
vector < InventoryItem > & equipment = equipmentLog [ unit - > id ] ;
vector < InventoryItem > & equipment = equipmentLog [ unit - > id ] ;
equipment . clear ( ) ;
equipment . clear ( ) ;
for ( size_t b = 0 ; b < unit - > inventory . size ( ) ; b + + ) {
for ( size_t b = 0 ; b < unit - > inventory . size ( ) ; b + + ) {
df : : unit_inventory_item * dfitem = unit - > inventory [ b ] ;
df : : unit_inventory_item * dfitem = unit - > inventory [ b ] ;
InventoryItem item ( dfitem - > item - > id , * dfitem ) ;
InventoryItem item ( dfitem - > item - > id , * dfitem ) ;
equipment . push_back ( item ) ;
equipment . push_back ( item ) ;
}
}
}
}
}
}
}
}
static void updateReportToRelevantUnits ( ) {
static void updateReportToRelevantUnits ( ) {
@ -827,14 +875,18 @@ static void manageReportEvent(color_ostream& out) {
while ( a < reports . size ( ) & & reports [ a ] - > id < = lastReport ) {
while ( a < reports . size ( ) & & reports [ a ] - > id < = lastReport ) {
a + + ;
a + + ;
}
}
for ( ; a < reports . size ( ) ; a + + ) {
int32_t tick = df : : global : : world - > frame_counter ;
for ( auto & iter : copy ) {
auto & handler = iter . second ;
if ( tick - eventLastTick [ handler . eventHandler ] > = handler . freq ) {
eventLastTick [ handler . eventHandler ] = tick ;
for ( ; a < reports . size ( ) ; a + + ) {
df : : report * report = reports [ a ] ;
df : : report * report = reports [ a ] ;
for ( auto b = copy . begin ( ) ; b ! = copy . end ( ) ; b + + ) {
handler . eventHandler ( out , ( void * ) intptr_t ( report - > id ) ) ;
EventHandler handle = ( * b ) . second ;
handle . eventHandler ( out , ( void * ) intptr_t ( report - > id ) ) ;
}
lastReport = report - > id ;
lastReport = report - > id ;
}
}
}
}
}
}
static df : : unit_wound * getWound ( df : : unit * attacker , df : : unit * defender ) {
static df : : unit_wound * getWound ( df : : unit * attacker , df : : unit * defender ) {
@ -873,8 +925,12 @@ static void manageUnitAttackEvent(color_ostream& out) {
return ;
return ;
updateReportToRelevantUnits ( ) ;
updateReportToRelevantUnits ( ) ;
map < int32_t , map < int32_t , int32_t > > alreadyDone ;
map < int32_t , map < int32_t , int32_t > > alreadyDone ;
for ( auto a = strikeReports . begin ( ) ; a ! = strikeReports . end ( ) ; a + + ) {
int32_t tick = df : : global : : world - > frame_counter ;
int32_t reportId = * a ;
for ( auto & iter : copy ) {
auto & handler = iter . second ;
if ( tick - eventLastTick [ handler . eventHandler ] > = handler . freq ) {
eventLastTick [ handler . eventHandler ] = tick ;
for ( int reportId : strikeReports ) {
df : : report * report = df : : report : : find ( reportId ) ;
df : : report * report = df : : report : : find ( reportId ) ;
if ( ! report )
if ( ! report )
continue ; //TODO: error
continue ; //TODO: error
@ -908,10 +964,7 @@ static void manageUnitAttackEvent(color_ostream& out) {
data . wound = wound1 - > id ;
data . wound = wound1 - > id ;
alreadyDone [ data . attacker ] [ data . defender ] = 1 ;
alreadyDone [ data . attacker ] [ data . defender ] = 1 ;
for ( auto b = copy . begin ( ) ; b ! = copy . end ( ) ; b + + ) {
handler . eventHandler ( out , ( void * ) & data ) ;
EventHandler handle = ( * b ) . second ;
handle . eventHandler ( out , ( void * ) & data ) ;
}
}
}
if ( wound2 & & ! alreadyDone [ unit1 - > id ] [ unit2 - > id ] ) {
if ( wound2 & & ! alreadyDone [ unit1 - > id ] [ unit2 - > id ] ) {
@ -921,10 +974,7 @@ static void manageUnitAttackEvent(color_ostream& out) {
data . wound = wound2 - > id ;
data . wound = wound2 - > id ;
alreadyDone [ data . attacker ] [ data . defender ] = 1 ;
alreadyDone [ data . attacker ] [ data . defender ] = 1 ;
for ( auto b = copy . begin ( ) ; b ! = copy . end ( ) ; b + + ) {
handler . eventHandler ( out , ( void * ) & data ) ;
EventHandler handle = ( * b ) . second ;
handle . eventHandler ( out , ( void * ) & data ) ;
}
}
}
if ( Units : : isKilled ( unit1 ) ) {
if ( Units : : isKilled ( unit1 ) ) {
@ -933,10 +983,7 @@ static void manageUnitAttackEvent(color_ostream& out) {
data . defender = unit1 - > id ;
data . defender = unit1 - > id ;
data . wound = - 1 ;
data . wound = - 1 ;
alreadyDone [ data . attacker ] [ data . defender ] = 1 ;
alreadyDone [ data . attacker ] [ data . defender ] = 1 ;
for ( auto b = copy . begin ( ) ; b ! = copy . end ( ) ; b + + ) {
handler . eventHandler ( out , ( void * ) & data ) ;
EventHandler handle = ( * b ) . second ;
handle . eventHandler ( out , ( void * ) & data ) ;
}
}
}
if ( Units : : isKilled ( unit2 ) ) {
if ( Units : : isKilled ( unit2 ) ) {
@ -945,10 +992,7 @@ static void manageUnitAttackEvent(color_ostream& out) {
data . defender = unit2 - > id ;
data . defender = unit2 - > id ;
data . wound = - 1 ;
data . wound = - 1 ;
alreadyDone [ data . attacker ] [ data . defender ] = 1 ;
alreadyDone [ data . attacker ] [ data . defender ] = 1 ;
for ( auto b = copy . begin ( ) ; b ! = copy . end ( ) ; b + + ) {
handler . eventHandler ( out , ( void * ) & data ) ;
EventHandler handle = ( * b ) . second ;
handle . eventHandler ( out , ( void * ) & data ) ;
}
}
}
if ( ! wound1 & & ! wound2 ) {
if ( ! wound1 & & ! wound2 ) {
@ -961,6 +1005,8 @@ static void manageUnitAttackEvent(color_ostream& out) {
}
}
}
}
}
}
}
}
}
}
static std : : string getVerb ( df : : unit * unit , std : : string reportStr ) {
static std : : string getVerb ( df : : unit * unit , std : : string reportStr ) {
@ -1152,6 +1198,11 @@ static void manageInteractionEvent(color_ostream& out) {
df : : unit * lastAttacker = NULL ;
df : : unit * lastAttacker = NULL ;
//df::unit* lastDefender = NULL;
//df::unit* lastDefender = NULL;
unordered_map < int32_t , unordered_set < int32_t > > history ;
unordered_map < int32_t , unordered_set < int32_t > > history ;
int32_t tick = df : : global : : world - > frame_counter ;
for ( auto & iter : copy ) {
auto & handler = iter . second ;
if ( tick - eventLastTick [ handler . eventHandler ] > = handler . freq ) {
eventLastTick [ handler . eventHandler ] = tick ;
for ( ; a < reports . size ( ) ; a + + ) {
for ( ; a < reports . size ( ) ; a + + ) {
df : : report * report = reports [ a ] ;
df : : report * report = reports [ a ] ;
lastReportInteraction = report - > id ;
lastReportInteraction = report - > id ;
@ -1203,11 +1254,10 @@ static void manageInteractionEvent(color_ostream& out) {
lastAttacker = df : : unit : : find ( data . attacker ) ;
lastAttacker = df : : unit : : find ( data . attacker ) ;
//lastDefender = df::unit::find(data.defender);
//lastDefender = df::unit::find(data.defender);
//fire event
//fire event
for ( auto b = copy . begin ( ) ; b ! = copy . end ( ) ; b + + ) {
handler . eventHandler ( out , ( void * ) & data ) ;
EventHandler handle = ( * b ) . second ;
handle . eventHandler ( out , ( void * ) & data ) ;
}
//TODO: deduce attacker from latest defend event first
//TODO: deduce attacker from latest defend event first
}
}
}
}
}
}