- first pass of VERY ROUGH crude implementation of 'cell markers'. Need to properly find icons, apply alpha to icon on the map and add support for notes when user hovers over the marker.

This commit is contained in:
Mark Vejvoda 2012-06-12 20:37:00 +00:00
parent c187d4d014
commit 943dcef9fe
13 changed files with 608 additions and 11 deletions

View File

@ -114,7 +114,12 @@ Game::Game() : ProgramState(NULL) {
pauseGamePopupMenuIndex = -1;
saveGamePopupMenuIndex = -1;
loadGamePopupMenuIndex = -1;
markCellPopupMenuIndex = -1;
keyboardSetupPopupMenuIndex = -1;
isMarkCellEnabled = false;
markCellTexture = NULL;
masterserverMode = false;
currentUIState=NULL;
currentAmbientSound=NULL;
@ -161,7 +166,12 @@ void Game::resetMembers() {
pauseGamePopupMenuIndex = -1;
saveGamePopupMenuIndex = -1;
loadGamePopupMenuIndex = -1;
markCellPopupMenuIndex = -1;
keyboardSetupPopupMenuIndex = -1;
isMarkCellEnabled = false;
markCellTexture = NULL;
currentUIState = NULL;
//this->gameSettings= NULL;
@ -728,6 +738,10 @@ void Game::load(int loadTypes) {
loadHudTexture(&gameSettings);
string data_path = getGameReadWritePath(GameConstants::path_data_CacheLookupKey);
const string markCellTextureFilename = data_path + "data/core/misc_textures/mark_cell.png";
markCellTexture = Renderer::findFactionLogoTexture(markCellTextureFilename);
string scenarioDir = "";
if(gameSettings.getScenarioDir() != "") {
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
@ -1137,6 +1151,9 @@ void Game::setupPopupMenus(bool checkClientAdminOverrideOnly) {
joinTeamPopupMenuIndex = menuItems.size()-1;
}
menuItems.push_back(lang.get("MarkCell"));
markCellPopupMenuIndex = menuItems.size()-1;
if(allowAdminMenuItems == true){
menuItems.push_back(lang.get("PauseResumeGame"));
pauseGamePopupMenuIndex= menuItems.size() - 1;
@ -1152,6 +1169,7 @@ void Game::setupPopupMenus(bool checkClientAdminOverrideOnly) {
menuItems.push_back(lang.get("Keyboardsetup"));
keyboardSetupPopupMenuIndex = menuItems.size()-1;
menuItems.push_back(lang.get("Cancel"));
popupMenu.setW(100);
popupMenu.setH(100);
popupMenu.init(lang.get("GameMenuTitle"),menuItems);
@ -1364,6 +1382,8 @@ void Game::update() {
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld [chatManager.updateNetwork]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis());
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start();
updateNetworkMarkedCells();
//check for quiting status
if(NetworkManager::getInstance().getGameNetworkInterface() != NULL &&
NetworkManager::getInstance().getGameNetworkInterface()->getQuit() &&
@ -1531,6 +1551,33 @@ void Game::update() {
}
}
void Game::updateNetworkMarkedCells() {
try {
GameNetworkInterface *gameNetworkInterface= NetworkManager::getInstance().getGameNetworkInterface();
if(gameNetworkInterface != NULL &&
gameNetworkInterface->getMarkedCellList(false).empty() == false) {
Lang &lang= Lang::getInstance();
std::vector<MarkedCell> chatList = gameNetworkInterface->getMarkedCellList(true);
for(int idx = 0; idx < chatList.size(); idx++) {
MarkedCell mc = chatList[idx];
mc.setFaction((const Faction *)world.getFaction(mc.getFactionIndex()));
Map *map= world.getMap();
Vec2i surfaceCellPos = map->toSurfCoords(mc.getTargetPos());
mapMarkedCellList[surfaceCellPos] = mc;
}
}
}
catch(const std::exception &ex) {
char szBuf[1024]="";
sprintf(szBuf,"In [%s::%s %d] error [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what());
SystemFlags::OutputDebug(SystemFlags::debugError,szBuf);
throw megaglest_runtime_error(szBuf);
}
}
void Game::ReplaceDisconnectedNetworkPlayersWithAI(bool isNetworkGame, NetworkRole role) {
if(role == nrServer && isNetworkGame == true &&
difftime(time(NULL),lastNetworkPlayerConnectionCheck) >= NETWORK_PLAYER_CONNECTION_CHECK_SECONDS) {
@ -1868,6 +1915,7 @@ void Game::mouseDownLeft(int x, int y) {
const Metrics &metrics= Metrics::getInstance();
NetworkManager &networkManager= NetworkManager::getInstance();
bool messageBoxClick= false;
bool originalIsMarkCellEnabled = isMarkCellEnabled;
if(popupMenu.mouseClick(x, y)) {
std::pair<int,string> result = popupMenu.mouseClickedMenuItem(x, y);
@ -1964,6 +2012,9 @@ void Game::mouseDownLeft(int x, int y) {
else if(result.first == saveGamePopupMenuIndex){
saveGame();
}
else if(result.first == markCellPopupMenuIndex) {
isMarkCellEnabled = true;
}
}
else if(popupMenuSwitchTeams.mouseClick(x, y)) {
//popupMenuSwitchTeams
@ -2047,6 +2098,27 @@ void Game::mouseDownLeft(int x, int y) {
{
gameCamera.setPos(Vec2f(static_cast<float>(xCell), static_cast<float>(yCell)));
}
if(originalIsMarkCellEnabled == true && isMarkCellEnabled == true) {
Vec2i surfaceCellPos = map->toSurfCoords(Vec2i(xCell,yCell));
SurfaceCell *sc = map->getSurfaceCell(surfaceCellPos);
Vec3f vertex = sc->getVertex();
Vec2i targetPos(vertex.x,vertex.z);
MarkedCell mc(targetPos,world.getThisFaction(),"placeholder for note");
mapMarkedCellList[surfaceCellPos] = mc;
GameNetworkInterface *gameNetworkInterface= NetworkManager::getInstance().getGameNetworkInterface();
gameNetworkInterface->sendMarkCellMessage(mc.getTargetPos(),mc.getFaction()->getIndex(),mc.getNote());
//printf("#1 ADDED in marked list pos [%s] markedCells.size() = %lu\n",surfaceCellPos.getString().c_str(),mapMarkedCellList.size());
isMarkCellEnabled = false;
Renderer &renderer= Renderer::getInstance();
//renderer.updateMarkedCellScreenPosQuadCache(surfaceCellPos);
renderer.forceQuadCacheUpdate();
}
}
}
//display panel
@ -2063,6 +2135,27 @@ void Game::mouseDownLeft(int x, int y) {
//graphics panel
else {
gui.mouseDownLeftGraphics(x, y, false);
if(originalIsMarkCellEnabled == true && isMarkCellEnabled == true) {
Vec2i targetPos;
Vec2i screenPos(x,y);
Renderer &renderer= Renderer::getInstance();
renderer.computePosition(screenPos, targetPos);
Vec2i surfaceCellPos = map->toSurfCoords(targetPos);
MarkedCell mc(targetPos,world.getThisFaction(),"placeholder for note");
mapMarkedCellList[surfaceCellPos] = mc;
GameNetworkInterface *gameNetworkInterface= NetworkManager::getInstance().getGameNetworkInterface();
gameNetworkInterface->sendMarkCellMessage(mc.getTargetPos(),mc.getFaction()->getIndex(),mc.getNote());
//printf("#2 ADDED in marked list pos [%s] markedCells.size() = %lu\n",surfaceCellPos.getString().c_str(),mapMarkedCellList.size());
isMarkCellEnabled = false;
//renderer.updateMarkedCellScreenPosQuadCache(surfaceCellPos);
renderer.forceQuadCacheUpdate();
}
}
}
@ -3143,6 +3236,8 @@ void Game::render2d() {
renderer.renderMinimap();
}
renderer.renderVisibleMarkedCells();
//selection
renderer.renderSelectionQuad();

View File

@ -148,10 +148,14 @@ private:
int pauseGamePopupMenuIndex;
int saveGamePopupMenuIndex;
int loadGamePopupMenuIndex;
int markCellPopupMenuIndex;
int keyboardSetupPopupMenuIndex;
//GLuint statelist3dMenu;
ProgramState *currentUIState;
bool isMarkCellEnabled;
Texture2D *markCellTexture;
std::map<Vec2i, MarkedCell> mapMarkedCellList;
bool masterserverMode;
StrSound *currentAmbientSound;
@ -173,6 +177,10 @@ public:
Game(Program *program, const GameSettings *gameSettings, bool masterserverMode);
~Game();
bool isMarkCellMode() const { return isMarkCellEnabled; }
const Texture2D * getMarkCellTexture() const { return markCellTexture; }
std::map<Vec2i, MarkedCell> getMapMarkedCellList() const { return mapMarkedCellList; }
bool isMasterserverMode() const { return masterserverMode; }
//get
GameSettings *getGameSettings() {return &gameSettings;}
@ -296,6 +304,8 @@ private:
string getDebugStats(std::map<int,string> &factionDebugInfo);
void renderVideoPlayer();
void updateNetworkMarkedCells();
};
}}//end namespace

View File

@ -1582,11 +1582,11 @@ void Renderer::renderMouse2d(int x, int y, int anim, float fade) {
}
// float blue=0.0f;
// float green=0.4f;
if(game!=NULL && game->getGui()!=NULL){
if(game != NULL && game->getGui() != NULL) {
const Gui *gui=game->getGui();
const Display *display=gui->getDisplay();
int downPos= display->getDownSelectedPos();
if(downPos!=Display::invalidPos){
if(downPos != Display::invalidPos){
// in state of doing something
const Texture2D *texture= display->getDownImage(downPos);
renderTextureQuad(x+18,y-50,32,32,texture,0.8f);
@ -1606,6 +1606,11 @@ void Renderer::renderMouse2d(int x, int y, int anim, float fade) {
// }
// }
// }
if(game->isMarkCellMode() == true) {
const Texture2D *texture= game->getMarkCellTexture();
renderTextureQuad(x-18,y-50,32,32,texture,0.8f);
}
}
float color1 = 0.0, color2 = 0.0;
@ -5456,6 +5461,8 @@ void Renderer::renderMinimap(){
}
renderMarkedCellsOnMinimap();
//draw camera
float wRatio= static_cast<float>(metrics.getMinimapW()) / world->getMap()->getW();
float hRatio= static_cast<float>(metrics.getMinimapH()) / world->getMap()->getH();
@ -5503,6 +5510,102 @@ void Renderer::renderMinimap(){
assertGl();
}
void Renderer::renderMarkedCellsOnMinimap() {
// Draw marked cells
std::map<Vec2i, MarkedCell> markedCells = game->getMapMarkedCellList();
if(markedCells.empty() == false) {
const Map *map= game->getWorld()->getMap();
const World *world= game->getWorld();
const Minimap *minimap= world->getMinimap();
if(minimap == NULL || minimap->getTexture() == NULL) {
return;
}
const GameCamera *gameCamera= game->getGameCamera();
const Pixmap2D *pixmap= minimap->getTexture()->getPixmapConst();
const Metrics &metrics= Metrics::getInstance();
const WaterEffects *attackEffects= world->getAttackEffects();
int mx= metrics.getMinimapX();
int my= metrics.getMinimapY();
int mw= metrics.getMinimapW();
int mh= metrics.getMinimapH();
Vec2f zoom= Vec2f(
static_cast<float>(mw)/ pixmap->getW(),
static_cast<float>(mh)/ pixmap->getH());
uint32 unitIdx=0;
vector<Vec2f> unit_vertices;
unit_vertices.resize(markedCells.size()*4);
vector<Vec4f> unit_colors;
unit_colors.resize(markedCells.size()*4);
for(std::map<Vec2i, MarkedCell>::iterator iterMap =markedCells.begin();
iterMap != markedCells.end(); ++iterMap) {
MarkedCell &bm = iterMap->second;
if(bm.getFaction() != NULL && bm.getFaction()->getTeam() == game->getWorld()->getThisFaction()->getTeam()) {
Vec2i pos= bm.getTargetPos() / Map::cellScale;
float size= 0.5f;
//Vec3f color= bm.color;
Vec3f color= bm.getFaction()->getTexture()->getPixmapConst()->getPixel3f(0, 0);
float alpha = 0.65;
unit_colors[unitIdx] = Vec4f(color.x,color.y,color.z,alpha);
unit_vertices[unitIdx] = Vec2f(mx + pos.x*zoom.x, my + mh - (pos.y*zoom.y));
unitIdx++;
unit_colors[unitIdx] = Vec4f(color.x,color.y,color.z,alpha);
unit_vertices[unitIdx] = Vec2f(mx + (pos.x+1)*zoom.x+size, my + mh - (pos.y*zoom.y));
unitIdx++;
unit_colors[unitIdx] = Vec4f(color.x,color.y,color.z,alpha);
unit_vertices[unitIdx] = Vec2f(mx + (pos.x+1)*zoom.x+size, my + mh - ((pos.y+size)*zoom.y));
unitIdx++;
unit_colors[unitIdx] = Vec4f(color.x,color.y,color.z,alpha);
unit_vertices[unitIdx] = Vec2f(mx + pos.x*zoom.x, my + mh - ((pos.y+size)*zoom.y));
unitIdx++;
}
}
if(unitIdx > 0) {
glEnable(GL_BLEND);
glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY);
glColorPointer(4,GL_FLOAT, 0, &unit_colors[0]);
glVertexPointer(2, GL_FLOAT, 0, &unit_vertices[0]);
glDrawArrays(GL_QUADS, 0, unitIdx);
//glDrawArrays(GL_TRIANGLE_STRIP, 0, unitIdx);
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
glDisable(GL_BLEND);
}
}
}
void Renderer::renderVisibleMarkedCells() {
// Draw marked cells
std::map<Vec2i, MarkedCell> markedCells = game->getMapMarkedCellList();
if(markedCells.empty() == false) {
for(std::map<Vec2i, MarkedCell>::iterator iterMap =markedCells.begin();
iterMap != markedCells.end(); ++iterMap) {
MarkedCell &bm = iterMap->second;
if(bm.getFaction() != NULL && bm.getFaction()->getTeam() == game->getWorld()->getThisFaction()->getTeam()) {
const Map *map= game->getWorld()->getMap();
std::pair<bool,Vec3f> bmVisible = posInCellQuadCache(
map->toSurfCoords(bm.getTargetPos()));
if(bmVisible.first == true) {
const Texture2D *texture= game->getMarkCellTexture();
renderTextureQuad(bmVisible.second.x,bmVisible.second.y+10,32,32,texture,0.8f);
}
}
}
}
}
void Renderer::renderDisplay() {
if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
return;
@ -5884,7 +5987,7 @@ void Renderer::renderMenuBackground(Camera *camera, float fade, Model *mainModel
// ==================== computing ====================
bool Renderer::computePosition(const Vec2i &screenPos, Vec2i &worldPos){
bool Renderer::computePosition(const Vec2i &screenPos, Vec2i &worldPos, bool exactCoords) {
assertGl();
const Map* map= game->getWorld()->getMap();
const Metrics &metrics= Metrics::getInstance();
@ -5916,7 +6019,12 @@ bool Renderer::computePosition(const Vec2i &screenPos, Vec2i &worldPos){
&worldX, &worldY, &worldZ);
//conver coords to int
worldPos= Vec2i(static_cast<int>(worldX+0.5f), static_cast<int>(worldZ+0.5f));
if(exactCoords == true) {
worldPos= Vec2i(static_cast<int>(worldX), static_cast<int>(worldZ));
}
else {
worldPos= Vec2i(static_cast<int>(worldX+0.5f), static_cast<int>(worldZ+0.5f));
}
//clamp coords to map size
return map->isInside(worldPos);
@ -7969,6 +8077,8 @@ VisibleQuadContainerCache & Renderer::getQuadCache( bool updateOnDirtyFrame,
//int loops2=0;
std::map<Vec2i, MarkedCell> markedCells = game->getMapMarkedCellList();
const Rect2i mapBounds(0, 0, map->getSurfaceW()-1, map->getSurfaceH()-1);
Quad2i scaledQuad = visibleQuad / Map::cellScale;
PosQuadIterator pqis(map,scaledQuad);
@ -7978,6 +8088,19 @@ VisibleQuadContainerCache & Renderer::getQuadCache( bool updateOnDirtyFrame,
//loops2++;
if(VisibleQuadContainerCache::enableFrustumCalcs == false) {
quadCache.visibleScaledCellList.push_back(pos);
if(markedCells.empty() == false) {
if(markedCells.find(pos) != markedCells.end()) {
//printf("#1 ******** VISIBLE SCALED CELL FOUND in marked list pos [%s] markedCells.size() = %lu\n",pos.getString().c_str(),markedCells.size());
//if(markedCells.empty() == false) {
//SurfaceCell *sc = map->getSurfaceCell(pos);
//quadCache.visibleScaledCellToScreenPosList[pos]=computeScreenPosition(sc->getVertex());
updateMarkedCellScreenPosQuadCache(pos);
}
else {
//printf("#1 VISIBLE SCALED CELL NOT FOUND in marked list pos [%s] markedCells.size() = %lu\n",pos.getString().c_str(),markedCells.size());
}
}
}
else {
SurfaceCell *sc = map->getSurfaceCell(pos);
@ -7987,6 +8110,18 @@ VisibleQuadContainerCache & Renderer::getQuadCache( bool updateOnDirtyFrame,
if(insideQuad == true) {
quadCache.visibleScaledCellList.push_back(pos);
if(markedCells.empty() == false) {
if(markedCells.find(pos) != markedCells.end()) {
//printf("#2 ******** VISIBLE SCALED CELL FOUND in marked list pos [%s] markedCells.size() = %lu\n",pos.getString().c_str(),markedCells.size());
//if(markedCells.empty() == false) {
//quadCache.visibleScaledCellToScreenPosList[pos]=computeScreenPosition(sc->getVertex());
updateMarkedCellScreenPosQuadCache(pos);
}
else {
//printf("#2 VISIBLE SCALED CELL NOT FOUND in marked list pos [%s] markedCells.size() = %lu\n",pos.getString().c_str(),markedCells.size());
}
}
}
}
}
@ -8001,6 +8136,47 @@ VisibleQuadContainerCache & Renderer::getQuadCache( bool updateOnDirtyFrame,
return quadCache;
}
void Renderer::updateMarkedCellScreenPosQuadCache(Vec2i pos) {
const World *world= game->getWorld();
const Map *map= world->getMap();
SurfaceCell *sc = map->getSurfaceCell(pos);
quadCache.visibleScaledCellToScreenPosList[pos]=computeScreenPosition(sc->getVertex());
}
void Renderer::forceQuadCacheUpdate() {
quadCache.cacheFrame = -1;
Vec2i clearPos(-1,-1);
quadCache.lastVisibleQuad.p[0] = clearPos;
quadCache.lastVisibleQuad.p[1] = clearPos;
quadCache.lastVisibleQuad.p[2] = clearPos;
quadCache.lastVisibleQuad.p[3] = clearPos;
}
std::pair<bool,Vec3f> Renderer::posInCellQuadCache(Vec2i pos) {
std::pair<bool,Vec3f> result = make_pair(false,Vec3f());
if(std::find(
quadCache.visibleScaledCellList.begin(),
quadCache.visibleScaledCellList.end(),
pos) != quadCache.visibleScaledCellList.end()) {
result.first = true;
result.second = quadCache.visibleScaledCellToScreenPosList[pos];
}
return result;
}
Vec3f Renderer::getMarkedCellScreenPosQuadCache(Vec2i pos) {
Vec3f result(-1,-1,-1);
if(std::find(
quadCache.visibleScaledCellList.begin(),
quadCache.visibleScaledCellList.end(),
pos) != quadCache.visibleScaledCellList.end()) {
result = quadCache.visibleScaledCellToScreenPosList[pos];
}
return result;
}
void Renderer::beginRenderToTexture(Texture2D **renderToTexture) {
if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
return;

View File

@ -103,6 +103,7 @@ protected:
visibleUnitList = obj.visibleUnitList;
visibleQuadUnitList = obj.visibleQuadUnitList;
visibleScaledCellList = obj.visibleScaledCellList;
visibleScaledCellToScreenPosList = obj.visibleScaledCellToScreenPosList;
lastVisibleQuad = obj.lastVisibleQuad;
frustumData = obj.frustumData;
proj = obj.proj;
@ -140,6 +141,7 @@ public:
inline void clearNonVolatileCacheData() {
visibleObjectList.clear();
visibleScaledCellList.clear();
visibleScaledCellToScreenPosList.clear();
visibleObjectList.reserve(500);
visibleScaledCellList.reserve(500);
@ -156,6 +158,7 @@ public:
std::vector<Unit *> visibleQuadUnitList;
std::vector<Unit *> visibleUnitList;
std::vector<Vec2i> visibleScaledCellList;
std::map<Vec2i,Vec3f> visibleScaledCellToScreenPosList;
static bool enableFrustumCalcs;
vector<vector<float> > frustumData;
@ -519,7 +522,7 @@ public:
void renderMenuBackground(Camera *camera, float fade, Model *mainModel, vector<Model *> characterModels,const Vec3f characterPosition, float anim);
//computing
bool computePosition(const Vec2i &screenPos, Vec2i &worldPos);
bool computePosition(const Vec2i &screenPos, Vec2i &worldPos,bool exactCoords=false);
void computeSelected(Selection::UnitContainer &units, const Object *&obj, const bool withObjectSelection, const Vec2i &posDown, const Vec2i &posUp);
void selectUsingColorPicking(Selection::UnitContainer &units, const Object *&obj,const bool withObjectSelection,const Vec2i &posDown, const Vec2i &posUp);
void selectUsingSelectionBuffer(Selection::UnitContainer &units,const Object *&obj, const bool withObjectSelection,const Vec2i &posDown, const Vec2i &posUp);
@ -574,6 +577,13 @@ public:
inline int getLastRenderFps() const { return lastRenderFps;}
VisibleQuadContainerCache & getQuadCache(bool updateOnDirtyFrame=true,bool forceNew=false);
std::pair<bool,Vec3f> posInCellQuadCache(Vec2i pos);
Vec3f getMarkedCellScreenPosQuadCache(Vec2i pos);
void updateMarkedCellScreenPosQuadCache(Vec2i pos);
void forceQuadCacheUpdate();
void renderVisibleMarkedCells();
void renderMarkedCellsOnMinimap();
void removeObjectFromQuadCache(const Object *o);
void removeUnitFromQuadCache(const Unit *unit);

View File

@ -471,6 +471,20 @@ void ClientInterface::updateLobby() {
}
break;
case nmtMarkCell:
{
NetworkMessageMarkCell networkMessageMarkCell;
if(receiveMessage(&networkMessageMarkCell)) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] got nmtMarkCell\n",__FILE__,__FUNCTION__);
MarkedCell msg(networkMessageMarkCell.getTarget(),
networkMessageMarkCell.getFactionIndex(),
networkMessageMarkCell.getText().c_str());
this->addMarkedCell(msg);
}
}
break;
case nmtLaunch:
case nmtBroadCastSetup:
{
@ -656,12 +670,8 @@ void ClientInterface::updateFrame(int *checkFrame) {
case nmtText:
{
time_t receiveTimeElapsed = time(NULL);
//time_t receiveTimeElapsed = time(NULL);
NetworkMessageText networkMessageText;
// while(receiveMessage(&networkMessageText) == false &&
// isConnected() == true &&
// difftime(time(NULL),receiveTimeElapsed) <= (messageWaitTimeout / 1000)) {
// }
bool gotCmd = receiveMessage(&networkMessageText);
if(gotCmd == false) {
throw megaglest_runtime_error("error retrieving nmtText returned false!");
@ -676,6 +686,20 @@ void ClientInterface::updateFrame(int *checkFrame) {
}
break;
case nmtMarkCell:
{
NetworkMessageMarkCell networkMessageMarkCell;
if(receiveMessage(&networkMessageMarkCell)) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] got nmtMarkCell\n",__FILE__,__FUNCTION__);
MarkedCell msg(networkMessageMarkCell.getTarget(),
networkMessageMarkCell.getFactionIndex(),
networkMessageMarkCell.getText().c_str());
this->addMarkedCell(msg);
}
}
break;
case nmtLaunch:
case nmtBroadCastSetup:
{
@ -1168,6 +1192,14 @@ void ClientInterface::sendTextMessage(const string &text, int teamIndex, bool ec
}
}
void ClientInterface::sendMarkCellMessage(Vec2i targetPos, int factionIndex, string note) {
string humanPlayerName = getHumanPlayerName();
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] humanPlayerName = [%s] playerIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,humanPlayerName.c_str(),playerIndex);
NetworkMessageMarkCell networkMessageMarkCell(targetPos,factionIndex, note);
sendMessage(&networkMessageMarkCell);
}
void ClientInterface::sendPingMessage(int32 pingFrequency, int64 pingTime) {
NetworkMessagePing networkMessagePing(pingFrequency,pingTime);
sendMessage(&networkMessagePing);
@ -1355,6 +1387,20 @@ bool ClientInterface::shouldDiscardNetworkMessage(NetworkMessageType networkMess
this->addChatInfo(msg);
}
break;
case nmtMarkCell:
{
discard = true;
NetworkMessageMarkCell networkMessageMarkCell;
receiveMessage(&networkMessageMarkCell);
MarkedCell msg(networkMessageMarkCell.getTarget(),
networkMessageMarkCell.getFactionIndex(),
networkMessageMarkCell.getText().c_str());
this->addMarkedCell(msg);
}
break;
case nmtSynchNetworkGameData:
{
discard = true;

View File

@ -41,7 +41,6 @@ private:
private:
ClientSocket *clientSocket;
//GameSettings gameSettings;
string serverName;
bool introDone;
bool launchGame;
@ -87,6 +86,8 @@ public:
string targetLanguage);
virtual void quitGame(bool userManuallyQuit);
virtual void sendMarkCellMessage(Vec2i targetPos, int factionIndex, string note);
//misc
virtual string getNetworkStatus() ;

View File

@ -560,6 +560,36 @@ void ConnectionSlot::update(bool checkForNewClients,int lockedSlotIndex) {
}
break;
case nmtMarkCell:
{
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] got nmtMarkCell gotIntro = %d\n",__FILE__,__FUNCTION__,__LINE__,gotIntro);
if(gotIntro == true) {
NetworkMessageMarkCell networkMessageMarkCell;
if(receiveMessage(&networkMessageMarkCell)) {
MarkedCell msg(networkMessageMarkCell.getTarget(),
networkMessageMarkCell.getFactionIndex(),
networkMessageMarkCell.getText().c_str());
this->addMarkedCell(msg);
//gotTextMsg = true;
}
else {
if(SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d]\nInvalid message type before intro handshake [%d]\nDisconnecting socket for slot: %d [%s].\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,networkMessageType,this->playerIndex,this->getIpAddress().c_str());
this->serverInterface->notifyBadClientConnectAttempt(this->getIpAddress());
close();
return;
}
}
else {
if(SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d]\nInvalid message type before intro handshake [%d]\nDisconnecting socket for slot: %d [%s].\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,networkMessageType,this->playerIndex,this->getIpAddress().c_str());
this->serverInterface->notifyBadClientConnectAttempt(this->getIpAddress());
close();
return;
}
}
break;
//command list
case nmtCommandList: {

View File

@ -127,6 +127,25 @@ void NetworkInterface::clearChatInfo() {
}
}
std::vector<MarkedCell> NetworkInterface::getMarkedCellList(bool clearList) {
std::vector<MarkedCell> result;
if(markedCellList.empty() == false) {
result = markedCellList;
if(clearList == true) {
markedCellList.clear();
}
}
return result;
}
void NetworkInterface::clearMarkedCellList() {
if(markedCellList.empty() == false) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] markedCellList.size() = %d\n",__FILE__,__FUNCTION__,__LINE__,markedCellList.size());
markedCellList.clear();
}
}
std::string NetworkInterface::getIpAddress() {
std::string result = "";

View File

@ -82,6 +82,39 @@ public:
};
class MarkedCell {
protected:
Vec2i targetPos;
const Faction *faction;
int factionIndex;
string note;
public:
MarkedCell() {
faction = NULL;
factionIndex = -1;
note = "";
}
MarkedCell(Vec2i targetPos,const Faction *faction,string note) {
this->targetPos = targetPos;
this->faction = faction;
this->factionIndex = -1;
this->note = note;
}
MarkedCell(Vec2i targetPos,int factionIndex,string note) {
this->targetPos = targetPos;
this->faction = NULL;
this->factionIndex = factionIndex;
this->note = note;
}
Vec2i getTargetPos() const { return targetPos; }
const Faction * getFaction() const { return faction; }
void setFaction(const Faction *faction) { this->faction = faction; }
int getFactionIndex() const { return factionIndex; }
string getNote() const { return note; }
};
typedef int (*DisplayMessageFunction)(const char *msg, bool exit);
class NetworkInterface {
@ -97,6 +130,7 @@ protected:
std::vector<ChatMsgInfo> chatTextList;
NetworkMessagePing lastPingInfo;
std::vector<MarkedCell> markedCellList;
static DisplayMessageFunction pCB_DisplayMessage;
void DisplayErrorMessage(string sErr, bool closeSocket=true);
@ -148,6 +182,10 @@ public:
void clearChatInfo();
void addChatInfo(const ChatMsgInfo &msg) { chatTextList.push_back(msg); }
std::vector<MarkedCell> getMarkedCellList(bool clearList);
void clearMarkedCellList();
void addMarkedCell(const MarkedCell &msg) { markedCellList.push_back(msg); }
virtual bool getConnectHasHandshaked() const= 0;
NetworkMessagePing getLastPingInfo() const { return lastPingInfo; }
@ -200,6 +238,8 @@ public:
string targetLanguage)= 0;
virtual void quitGame(bool userManuallyQuit)=0;
virtual void sendMarkCellMessage(Vec2i targetPos, int factionIndex, string note) = 0;
//misc
virtual string getNetworkStatus() = 0;

View File

@ -979,4 +979,39 @@ void NetworkMessageLoadingStatus::send(Socket* socket) const
NetworkMessage::send(socket, &data, sizeof(data));
}
// =====================================================
// class NetworkMessageMarkCell
// =====================================================
NetworkMessageMarkCell::NetworkMessageMarkCell(Vec2i target, int factionIndex, const string &text) {
if(text.length() >= maxTextStringSize) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] WARNING / ERROR - text [%s] length = %d, max = %d\n",__FILE__,__FUNCTION__,__LINE__,text.c_str(),text.length(),maxTextStringSize);
}
data.messageType = nmtMarkCell;
data.text = text;
data.targetX = target.x;
data.targetY = target.y;
data.factionIndex = factionIndex;
}
NetworkMessageMarkCell * NetworkMessageMarkCell::getCopy() const {
NetworkMessageMarkCell *copy = new NetworkMessageMarkCell();
copy->data = this->data;
return copy;
}
bool NetworkMessageMarkCell::receive(Socket* socket){
bool result = NetworkMessage::receive(socket, &data, sizeof(data), true);
data.text.nullTerminate();
return result;
}
void NetworkMessageMarkCell::send(Socket* socket) const{
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] nmtMarkCell\n",__FILE__,__FUNCTION__,__LINE__);
assert(data.messageType == nmtMarkCell);
NetworkMessage::send(socket, &data, sizeof(data));
}
}}//end namespace

View File

@ -43,6 +43,7 @@ enum NetworkMessageType {
nmtSwitchSetupRequest,
nmtPlayerIndexMessage,
nmtLoadingStatusMessage,
nmtMarkCell,
nmtCount
};
@ -729,6 +730,44 @@ public:
#pragma pack(pop)
// =====================================================
// class NetworkMessageText
//
// Mark a Cell message nmtMarkCell
// =====================================================
#pragma pack(push, 1)
class NetworkMessageMarkCell: public NetworkMessage {
private:
static const int maxTextStringSize= 500;
private:
struct Data{
int8 messageType;
int16 targetX;
int16 targetY;
int8 factionIndex;
NetworkString<maxTextStringSize> text;
};
private:
Data data;
public:
NetworkMessageMarkCell(){}
NetworkMessageMarkCell(Vec2i target, int factionIndex, const string &text);
string getText() const { return data.text.getString(); }
Vec2i getTarget() const { return Vec2i(data.targetX,data.targetY); }
int getFactionIndex() const { return data.factionIndex; }
virtual bool receive(Socket* socket);
virtual void send(Socket* socket) const;
NetworkMessageMarkCell * getCopy() const;
};
#pragma pack(pop)
}}//end namespace
#endif

View File

@ -1094,6 +1094,45 @@ void ServerInterface::dispatchPendingChatMessages(std::vector <string> &errorMsg
}
}
void ServerInterface::dispatchPendingMarkCellMessages(std::vector <string> &errorMsgList) {
for(int i= 0; exitServer == false && i < GameConstants::maxPlayers; ++i) {
MutexSafeWrapper safeMutexSlot(slotAccessorMutexes[i],CODE_AT_LINE_X(i));
ConnectionSlot* connectionSlot= slots[i];
if(connectionSlot != NULL &&
connectionSlot->getMarkedCellList(false).empty() == false) {
try {
std::vector<MarkedCell> chatText = connectionSlot->getMarkedCellList(true);
for(int chatIdx = 0;
exitServer == false && slots[i] != NULL &&
chatIdx < chatText.size(); chatIdx++) {
connectionSlot= slots[i];
if(connectionSlot != NULL) {
MarkedCell msg(chatText[chatIdx]);
this->addMarkedCell(msg);
NetworkMessageMarkCell networkMessageMarkCell(msg.getTargetPos(),msg.getFactionIndex(),msg.getNote());
broadcastMessage(&networkMessageMarkCell, connectionSlot->getPlayerIndex(),i);
//if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] after broadcast nmtText chatText [%s] chatTeamIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,newChatText.c_str(),newChatTeamIndex);
}
}
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] i = %d\n",__FILE__,__FUNCTION__,__LINE__,i);
// Its possible that the slot is disconnected here
// so check the original pointer again
if(slots[i] != NULL) {
slots[i]->clearMarkedCellList();
}
}
catch(const exception &ex) {
SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what());
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] error detected [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what());
errorMsgList.push_back(ex.what());
}
}
}
}
void ServerInterface::update() {
Chrono chrono;
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled) chrono.start();
@ -1166,6 +1205,8 @@ void ServerInterface::update() {
dispatchPendingChatMessages(errorMsgList);
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
dispatchPendingMarkCellMessages(errorMsgList);
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took %lld msecs\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
}
else if(gameHasBeenInitiated == true &&
@ -1332,6 +1373,41 @@ bool ServerInterface::shouldDiscardNetworkMessage(NetworkMessageType networkMess
}
break;
case nmtMarkCell:
{
discard = true;
NetworkMessageMarkCell networkMessageMarkCell;
connectionSlot->receiveMessage(&networkMessageMarkCell);
MarkedCell msg(networkMessageMarkCell.getTarget(),
networkMessageMarkCell.getFactionIndex(),
networkMessageMarkCell.getText().c_str());
this->addMarkedCell(msg);
// string newChatText = msg.chatText.c_str();
// //string newChatSender = msg.chatSender.c_str();
// int newChatTeamIndex = msg.chatTeamIndex;
// int newChatPlayerIndex = msg.chatPlayerIndex;
// string newChatLanguage = msg.targetLanguage.c_str();
//
// if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] #1 about to broadcast nmtText chatText [%s] chatTeamIndex = %d, newChatPlayerIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,newChatText.c_str(),newChatTeamIndex,newChatPlayerIndex);
//
// NetworkMessageText networkMessageText(newChatText.c_str(),newChatTeamIndex,newChatPlayerIndex,newChatLanguage);
// broadcastMessage(&networkMessageText, connectionSlot->getPlayerIndex());
NetworkMessageMarkCell networkMessageMarkCellBroadcast(
networkMessageMarkCell.getTarget(),
networkMessageMarkCell.getFactionIndex(),
networkMessageMarkCell.getText().c_str());
broadcastMessage(&networkMessageMarkCellBroadcast, connectionSlot->getPlayerIndex());
//if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] after broadcast nmtMarkCell chatText [%s] chatTeamIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,newChatText.c_str(),newChatTeamIndex);
}
break;
case nmtSynchNetworkGameData:
{
discard = true;
@ -1673,6 +1749,20 @@ void ServerInterface::sendTextMessage(const string& text, int teamIndex, bool ec
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
}
void ServerInterface::sendMarkCellMessage(Vec2i targetPos, int factionIndex, string note) {
sendMarkCellMessage(targetPos, factionIndex, note, -1);
}
void ServerInterface::sendMarkCellMessage(Vec2i targetPos, int factionIndex, string note, int lockedSlotIndex) {
//printf("Line: %d text [%s] echoLocal = %d\n",__LINE__,text.c_str(),echoLocal);
//assert(text.length() > 0);
//if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] text [%s] teamIndex = %d, echoLocal = %d, lockedSlotIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,text.c_str(),teamIndex,echoLocal,lockedSlotIndex);
NetworkMessageMarkCell networkMessageMarkCell(targetPos,factionIndex, note);
broadcastMessage(&networkMessageMarkCell, -1, lockedSlotIndex);
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
}
void ServerInterface::quitGame(bool userManuallyQuit) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
NetworkMessageQuit networkMessageQuit;

View File

@ -113,7 +113,12 @@ public:
virtual void waitUntilReady(Checksum *checksum);
virtual void sendTextMessage(const string & text, int teamIndex, bool echoLocal, string targetLanguage);
void sendTextMessage(const string & text, int teamIndex, bool echoLocal, string targetLanguage, int lockedSlotIndex);
void queueTextMessage(const string & text, int teamIndex, bool echoLocal, string targetLanguage);
virtual void sendMarkCellMessage(Vec2i targetPos, int factionIndex, string note);
void sendMarkCellMessage(Vec2i targetPos, int factionIndex, string note, int lockedSlotIndex);
virtual void quitGame(bool userManuallyQuit);
virtual string getNetworkStatus();
ServerSocket *getServerSocket()
@ -224,6 +229,7 @@ protected:
void checkForLaggingClients(std::map<int,bool> &mapSlotSignalledList, std::map<int,ConnectionSlotEvent> &eventList, std::map<PLATFORM_SOCKET,bool> &socketTriggeredList,std::vector <string> &errorMsgList);
void executeNetworkCommandsFromClients();
void dispatchPendingChatMessages(std::vector <string> &errorMsgList);
void dispatchPendingMarkCellMessages(std::vector <string> &errorMsgList);
void shutdownMasterserverPublishThread();
};