diff --git a/src/action/action_build.cpp b/src/action/action_build.cpp index 9756b6c61..566d7e6e5 100644 --- a/src/action/action_build.cpp +++ b/src/action/action_build.cpp @@ -115,7 +115,7 @@ global void HandleActionBuild(Unit* unit) if( !CanBuildUnitType(unit,type,x,y) ) { // FIXME: use general notify/messages if( unit->Player==ThisPlayer ) { - SetMessage("You cannot build here."); + SetMessage("You cannot build %s here.", type->Name); } else { AiCanNotBuild(unit,type); } @@ -252,7 +252,7 @@ global void HandleActionBuilded(Unit* unit) // FIXME: General message system if( unit->Player==ThisPlayer ) { - SetMessage("Work complete"); + SetMessage2( unit->X, unit->Y, "New %s done", type->Name ); PlayUnitSound(peon,VoiceWorkCompleted); } else { AiWorkComplete(peon,unit); diff --git a/src/action/action_research.cpp b/src/action/action_research.cpp index 4b7fae4b4..fa47c06c8 100644 --- a/src/action/action_research.cpp +++ b/src/action/action_research.cpp @@ -45,7 +45,7 @@ global void HandleActionResearch(Unit* unit) if( unit->Command.Data.Research.Ticks>=upgrade->Costs[TimeCost] ) { // FIXME: should als speak and tell ai - SetMessage("Upgrade complete"); + SetMessage2( unit->X, unit->Y, "%s: Upgrade complete", unit->Type->Name ); UpgradeAcquire(unit->Player,upgrade); diff --git a/src/action/action_train.cpp b/src/action/action_train.cpp index 8897b13cd..b43f02c13 100644 --- a/src/action/action_train.cpp +++ b/src/action/action_train.cpp @@ -101,7 +101,7 @@ global void HandleActionTrain(Unit* unit) // FIXME: GameMessage if( player==ThisPlayer ) { - SetMessage("Training complete"); + SetMessage2( nunit->X, nunit->Y, "New %s ready", nunit->Type->Name); PlayUnitSound(nunit,VoiceReady); } else { AiTrainingComplete(unit,nunit); diff --git a/src/action/action_upgradeto.cpp b/src/action/action_upgradeto.cpp index 50d19222a..47a689e47 100644 --- a/src/action/action_upgradeto.cpp +++ b/src/action/action_upgradeto.cpp @@ -64,7 +64,7 @@ global void HandleActionUpgradeTo(Unit* unit) // FIXME: SendNotify("upgrade-complete"); if( player==ThisPlayer ) { - SetMessage("Upgrade complete"); + SetMessage2( unit->X, unit->Y, "Upgrade to %s complete", unit->Type->Name ); } else { // FIXME: AiUpgradeToComplete(unit,type); } diff --git a/src/include/freecraft.h b/src/include/freecraft.h index 48c0c52d5..05da69698 100644 --- a/src/include/freecraft.h +++ b/src/include/freecraft.h @@ -297,9 +297,11 @@ extern int SyncRand(void); extern int main1(int argc,char* argv[]);/// init freecraft. extern volatile void Exit(int err); /// exit freecraft. -extern void SetMessage(char* message); +extern void SetMessage( char* fmt, ... ); +extern void SetMessage2( int x, int y, char* fmt, ... ); extern void SetMessageDup(const char* message); extern void SetMessageDupCat(const char* message); +extern void CenterOnMessage(); extern void ClearMessage(void); extern void SetStatusLine(char* status); extern void ClearStatusLine(void); diff --git a/src/include/interface.h b/src/include/interface.h index 19c8f873d..3d3b74b81 100644 --- a/src/include/interface.h +++ b/src/include/interface.h @@ -255,7 +255,7 @@ extern void DrawMessage(void); extern void DrawResources(void); extern void DrawMessage(void); -extern void SetMessage(char* message); +extern void SetMessage( char* fmt, ... ); extern void ClearMessage(void); extern void DrawStatusLine(void); extern void DrawCosts(void); diff --git a/src/stratagus/interface.cpp b/src/stratagus/interface.cpp index e4ea523b2..7a8ba8c31 100644 --- a/src/stratagus/interface.cpp +++ b/src/stratagus/interface.cpp @@ -194,6 +194,10 @@ local int CommandKey(int key) ToggleGrabMouse(); break; + case ' ': + CenterOnMessage(); + break; + // TAB toggles minimap. // FIXME: more... case '\t': diff --git a/src/stratagus/player.cpp b/src/stratagus/player.cpp index c88790c7a..b17886f40 100644 --- a/src/stratagus/player.cpp +++ b/src/stratagus/player.cpp @@ -329,7 +329,7 @@ global int PlayerCheckCosts(const Player* player,const int* costs) ,DEFAULT_NAMES[i],DEFAULT_ACTIONS[i],DEFAULT_NAMES[i]); // FIXME: use the general notify function vor this if( player==ThisPlayer ) { - SetMessageDup(buf); + SetMessageDup(buf); //FIXME: vladi: can SetMessage be used instead? } else { DebugLevel3("Ai: %s.\n",buf); } diff --git a/src/ui/mainscr.cpp b/src/ui/mainscr.cpp index a548c1322..791c59831 100644 --- a/src/ui/mainscr.cpp +++ b/src/ui/mainscr.cpp @@ -20,6 +20,7 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <stdarg.h> #include "freecraft.h" #include "video.h" @@ -34,6 +35,7 @@ #include "icons.h" #include "interface.h" #include "ui.h" +#include "map.h" #define OriginalTraining 0 /// 1 for the original training display @@ -474,20 +476,84 @@ global void DrawResources(void) // FIXME: need messages for chat! +#define MESSAGES_TIMEOUT FRAMES_PER_SECOND*2 // two seconds + local char MessageBuffer[40]; // message buffer local char* Message; // message in map window -local int MessageCounter; // how long to display message +local int MessageFrameTimeout; // frame to expire message + +#define MESSAGES_MAX 10 + +local char Messages[ MESSAGES_MAX ][64]; +local int MessagesCount; + +local char MessagesEvent[ MESSAGES_MAX ][64]; +local int MessagesEventX[ MESSAGES_MAX ]; +local int MessagesEventY[ MESSAGES_MAX ]; +local int MessagesEventCount; +local int MessagesEventIndex; /** -** Draw message. +** Shift messages array with one. +** +** +*/ +global void ShiftMessages() +{ + int z; + if ( MessagesCount == 0 ) return; + for ( z = 0; z < MESSAGES_MAX; z++ ) + if ( z < MESSAGES_MAX-1) + { + strcpy( Messages[z], Messages[z+1] ); + } + else + { + strcpy( Messages[z], "" ); + } + MessagesCount--; +} + +/** +** Shift messages events array with one. +** +** +*/ +global void ShiftMessagesEvent() +{ + int z; + if ( MessagesEventCount == 0 ) return; + for ( z = 0; z < MESSAGES_MAX; z++ ) + if ( z < MESSAGES_MAX-1) + { + MessagesEventX[z] = MessagesEventX[z+1]; + MessagesEventY[z] = MessagesEventY[z+1]; + } + else + { + MessagesEventX[z] = -1; + MessagesEventY[z] = -1; + } + MessagesCount--; +} + +/** +** Draw message(s). */ global void DrawMessage(void) { - if( Message ) { - DrawReverseText(TheUI.MapX+10,TheUI.MapHeight-20,GameFont,Message); - if( !--MessageCounter ) { - ClearMessage(); - } + int z; + if ( MessageFrameTimeout < FrameCounter ) + { + ShiftMessages(); + MessageFrameTimeout = FrameCounter + MESSAGES_TIMEOUT; + } + for ( z = 0; z < MessagesCount; z++ ) + { + if ( Messages[z][0] == '*' ) + DrawText(TheUI.MapX+8,TheUI.MapY+8 + z*16,GameFont,Messages[z]+1); + else + DrawReverseText(TheUI.MapX+8,TheUI.MapY+8 + z*16,GameFont,Messages[z]); } } @@ -496,11 +562,50 @@ global void DrawMessage(void) ** ** @param message To be displayed in text overlay. */ -global void SetMessage(char* message) +global void SetMessage( char* fmt, ... ) { - Message=message; + char temp[128]; + va_list va; + va_start( va, fmt ); + vsprintf( temp, fmt, va ); + va_end( va ); + if ( MessagesCount == MESSAGES_MAX ) + ShiftMessages(); + strcpy( Messages[ MessagesCount ], temp ); + MessagesCount++; MustRedraw|=RedrawMessage|RedrawMap; - MessageCounter=FRAMES_PER_SECOND*2; + MessageFrameTimeout = FrameCounter + MESSAGES_TIMEOUT; +} + +/** +** Set message to display. +** +** @param message To be displayed in text overlay. +*/ +global void SetMessage2( int x, int y, char* fmt, ... ) +{ + //FIXME: vladi: I know this can be just separated func w/o msg but + // it is handy to stick all in one call, someone? + + char temp[128]; + va_list va; + va_start( va, fmt ); + vsprintf( temp, fmt, va ); + va_end( va ); + if ( MessagesCount == MESSAGES_MAX ) + ShiftMessages(); + strcpy( Messages[ MessagesCount ], temp ); + MessagesCount++; + + if ( MessagesEventCount == MESSAGES_MAX ) + ShiftMessagesEvent(); + strcpy( MessagesEvent[ MessagesEventCount ], temp ); + MessagesEventX[ MessagesEventCount ] = x; + MessagesEventY[ MessagesEventCount ] = y; + MessagesEventCount++; + + MustRedraw|=RedrawMessage|RedrawMap; + MessageFrameTimeout = FrameCounter + MESSAGES_TIMEOUT; } /** @@ -510,6 +615,9 @@ global void SetMessage(char* message) */ global void SetMessageDup(const char* message) { + //FIXME: is this function correct now? + // it was, before multi-messages support done + strncpy(MessageBuffer,message,sizeof(MessageBuffer)); MessageBuffer[sizeof(MessageBuffer)-1]='\0'; @@ -523,6 +631,9 @@ global void SetMessageDup(const char* message) */ global void SetMessageDupCat(const char* message) { + //FIXME: is this function correct now? + // it was, before multi-messages support done + strncat(MessageBuffer,message,sizeof(MessageBuffer)-strlen(MessageBuffer)); MessageBuffer[sizeof(MessageBuffer)-1]='\0'; @@ -534,9 +645,24 @@ global void SetMessageDupCat(const char* message) */ global void ClearMessage(void) { + //FIXME: is this function correct now? + // it was, before multi-messages support done + Message=NULL; MustRedraw|=RedrawMessage|RedrawMap; - MessageCounter=0; + MessageFrameTimeout = FrameCounter; +} + +global void CenterOnMessage(void) +{ + if ( MessagesEventIndex >= MessagesEventCount ) + MessagesEventIndex = 0; + if ( MessagesEventIndex >= MessagesEventCount ) + return; + MapCenter( MessagesEventX[ MessagesEventIndex ], + MessagesEventY[ MessagesEventIndex ] ); + SetMessage( "*Event: %s", MessagesEvent[ MessagesEventIndex ] ); + MessagesEventIndex++; } /*----------------------------------------------------------------------------