/*************************************************************************** guicommandline.cpp - description ------------------- begin : lun mar 04 14:59:00 CET 2002 copyright : (C) 2002 by Romain Vinot email : vinot@aist.enst.fr ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifdef _WIN32 #pragma warning (disable : 4786) #endif #include #include #include #include using namespace std; #include "guicommandline.h" #include "board.h" #include "gamemanager.h" #include "datastoring.h" #include "guicreature.h" #include "guiboard.h" #include "sessionmanager.h" #include "network.h" GUICommandLine::GUICommandLine(GUIBoard *b, GUICreature *c) : guiboard(b), guicrea(c), state(GUI_WAITING) {} GUICommandLine::~GUICommandLine() {} void GUICommandLine::setState(interfaceState s) { state=s; } void GUICommandLine::getFiringCommand(QString command) { int xcoord, ycoord; int nb = sscanf(command.latin1(), "%d %d",&xcoord, &ycoord); if (nb==2) { // If you click on a marine, you stop the fire and view the marine. set *obj=board->getObject(xcoord+ycoord*board->Xmax); bool continueFire=false; if (obj) { continueFire=true; for (set::iterator it=obj->begin();it!=obj->end(); it++) { if ((*it)->isMarinePlayer()) continueFire=false; } } if (continueFire) { QString cmd; cmd.sprintf("fire %d %d", xcoord, ycoord); getAllCommands(cmd); } else getAllCommands(command); } else getAllCommands(command); } void GUICommandLine::getShootingCommand(QString command) { int xcoord, ycoord; int nb = sscanf(command.latin1(), "%d %d",&xcoord, &ycoord); if (nb==2) { set *obj=board->getObject(xcoord+ycoord*board->Xmax); bool continueFire=false; if (obj) { continueFire=true; for (set::iterator it=obj->begin();it!=obj->end(); it++) { if ((*it)->isMarinePlayer()) continueFire=false; } } if (continueFire) { QString cmd; cmd.sprintf("shoot %d %d", xcoord, ycoord); getAllCommands(cmd); } else getAllCommands(command); } else getAllCommands(command); } void GUICommandLine::getCommand(QString command) { if (!getMainCommands(command)) { man->recordCommand(command); switch(state) { case GUI_SHOOT: getShootingCommand(command); break; case GUI_FIRE: getFiringCommand(command); break; default: getAllCommands(command); } } DrawInterface(); } // The usual getCommand must be called only by the GUI thread. // GetRecordCommand is used when commands are given by the main thread void GUICommandLine::getReplayCommand(QString command) { GUICommandLine::getCommand(command); } bool GUICommandLine::getMainCommands(QString cmd) { if (cmd.startsWith("exit") || cmd.startsWith("quit")) { cout << "Exit the game. We hope you enjoy playing it !\n"; endOfExecution(); } else if (cmd.startsWith("newgame")) commandNewGame(cmd); else if (cmd.startsWith("view")) Write(commandView(cmd)); else return false; return true; } void GUICommandLine::getAllCommands(QString cmd) { const char *command = cmd.latin1(); cout << "Command given: [" << command << "].\n"; if (cmd.isEmpty()) return; QString temp = "> "; temp += cmd; Write(temp, true); if (cmd.startsWith("undo")) Write(commandUndo(cmd)); man->disableUndo(); if (cmd.startsWith("select")) Write(commandSelect(cmd)); else if (cmd.startsWith("move")) Write(commandMove(cmd)); else if (cmd.startsWith("turn")) Write(commandTurn(cmd)); else if (cmd.startsWith("enter")) Write(commandEnter(cmd)); else if (cmd.startsWith("revert")) Write(commandRevert(cmd)); else if (cmd.startsWith("open")) Write(commandOpen(cmd)); else if (cmd.startsWith("close")) Write(commandClose(cmd)); else if (cmd.startsWith("attack")) Write(commandAttack(cmd)); else if (cmd.startsWith("overwatch")) Write(commandOverwatch(cmd)); else if (cmd.startsWith("shoot")) Write(commandShoot(cmd)); else if (cmd.startsWith("fire")) Write(commandFire(cmd)); else if (cmd.startsWith("stop")) Write(commandStop(cmd)); else if (cmd.startsWith("unjam")) Write(commandUnjam(cmd)); else if (cmd.startsWith("reload")) Write(commandLoadFlamer(cmd)); else if (cmd.startsWith("endturn")) Write(commandEndTurn(cmd)); else if (cmd.startsWith("takeordrop")) Write(commandTakeOrDrop(cmd)); else if (cmd.startsWith("save")) Write(commandSave(cmd)); else if (cmd.startsWith("load")) Write(commandLoad(cmd)); else if (cmd.startsWith("message")) Write(commandMessage(cmd)); else if (cmd.startsWith("connect")) Write(commandConnect(cmd)); else if (cmd.startsWith("record")) Write(commandRecord(cmd)); else if (cmd.startsWith("network")) Write(commandNetwork(cmd)); else if (cmd.startsWith("undo")) ;// Do nothing : it has already been done but we need to recognize the cmd. else if (cmd.startsWith("help")) Write(commandHelp(cmd)); else { int xcoord, ycoord; int nb = sscanf(command, "%d %d",&xcoord, &ycoord); if (nb==2) man->setOnView(xcoord+ycoord*board->Xmax); else { Write("Cannot recognized the command. Type 'help' for list of " "commands.\n"); man->removeLatestRecord(); } } previous = cmd; man->CheckNonVisibleBlip(); } QString GUICommandLine::getPreviousCommand(void) {return previous;} void GUICommandLine::commandNewGame(QString &command) { session->NewGameStep1(); } QString GUICommandLine::commandSelect(QString &command) { QString str; QTextStream res(&str,IO_WriteOnly); int creatureId; int ycoord; int resb = sscanf(command.latin1(), "%*s %d %d", &creatureId, &ycoord); if (resb==2) { // The user try to select a square. if (man->selectCreature(creatureId+board->Xmax*ycoord)) { Creature *crea = man->getSelected(); res << "Creature " << creatureId << " selected."; crea->printInfo(2); } else res << "You can't select a creature there."; } else { Creature *crea = man->getCreature(creatureId); if (crea != 0) { if (man->selectCreature(crea)) { res << "Creature " << creatureId << " selected."; crea->printInfo(2); } else { res << "Creature " << creatureId << " cannot be selected."; } } else { res << "The creature " << creatureId << " does not exist."; } } state=GUI_WAITING; return str; } QString GUICommandLine::commandMove(QString &command) { man->initUndo(); QString res; Creature *crea = man->getSelected(); if (crea == 0) { res = "There is no selected creature. Please select one before moving"; } else { char direction[20]; sscanf(command.latin1(), "%*s %s",direction); bool resb=crea->Move(getDirectionType(direction)); if (resb) { man->CheckExit(); man->CheckOverwatchTarget(); res = "The creature has moved."; } else { res = "The creature cannot move to that direction."; man->removeLatestRecord(); } } state=GUI_WAITING; return res; } QString GUICommandLine::commandTurn(QString &command) { man->initUndo(); QString str; QTextStream res(&str,IO_WriteOnly); Creature *crea = man->getSelected(); if (crea == 0) { res << "There is no selected creature. Please select one before moving"; } else { char dir; sscanf(command.latin1(), "%*s %c",&dir); Direction direction; switch (dir) { case 'n': direction=NORTH; break; case 'e': direction=EAST; break; case 's': direction=SOUTH; break; case 'w': direction=WEST; break; default: direction=NODIRECTION; break; } bool resb=crea->TurnOrientation(direction); if (resb) { man->CheckOverwatchTarget(); res << "Creature has been turned to direction : " << dir2string(direction) << "."; } else { res << "Movement is not possible."; man->removeLatestRecord(); } } state=GUI_WAITING; return str; } QString GUICommandLine::commandView(QString &command) { QString str; QTextStream res(&str,IO_WriteOnly); char what[20]; int id=0; int Yid=0; sscanf(command.latin1(), "%*s %s %d %d",what, &id, &Yid); if ((what[0]=='m' && what[1]=='a')|| strcmp(what,"map")==0) guiboard->printBoard(); else if (what[0]=='s' || strcmp(what,"selected")==0) { Creature *crea = man->getSelected(); if (crea==0) return "No creature selected."; crea->printInfo(0); } else if ((what[0]=='c' && what[1]=='r') || strcmp(what,"creature")==0) { Creature *crea = man->getCreature(id); if (crea != 0) crea->printInfo(0); else res << "Creature " << id << " does not exist."; } else if ((what[0]=='c' && what[1]=='a') || strcmp(what,"case")==0) { set *objs = board->getObject(id+board->Xmax*Yid); if (objs==0) res << "Square " << id << " " << Yid << " is a wall."; else if (objs->size()==0) res << "Square " << id << " " << Yid << " is an empty square."; else for (set::iterator it=objs->begin(); it!=objs->end(); it++) (*it)->printInfo(0); } else if (what[0]=='l' || strcmp(what,"list")==0) { man->printAllCreaturesInfo(); } else if ((what[0]=='m' && what[1]=='i')|| strcmp(what,"missiondescription")) printLevelInfo(); else res << "command view not understood."; state=GUI_WAITING; return str; } QString GUICommandLine::commandEnter(QString &command) { QString res; Creature *crea = man->getSelected(); if (crea == 0) res = "There is no selected creature. Please select one before moving."; else { bool resb=crea->Enter(); if (resb) { res = "The creature has enter the board."; man->CheckOverwatchTarget(); } else { res = "The creature cannot enter the board."; man->removeLatestRecord(); } } state=GUI_WAITING; return res; } QString GUICommandLine::commandRevert(QString &command) { QString res; Creature *crea = man->getSelected(); if (crea == 0) res = "There is no selected creature.Please select one before moving."; else { bool resb=crea->Revert(); if (resb) { res = "Blip has been reverted."; man->RevertBlip((Blip *) crea, true); } else { res = "Creature cannot be reverted."; man->removeLatestRecord(); } } state=GUI_WAITING; return res; } QString GUICommandLine::commandEndTurn(QString &command) { state=GUI_WAITING; session->EndOfTurn(); return (""); } QString GUICommandLine::commandOpen(QString &command) { QString res; Creature *crea = man->getSelected(); if (crea == 0) { res = "There is no selected creature. Please select one before."; } else { int xcoord, ycoord; int nb = sscanf(command.latin1(), "%*s %d %d",&xcoord, &ycoord); bool resb; if (nb<2) resb = crea->OpenDoor(); else resb = crea->OpenDoor(xcoord+ycoord*board->Xmax); if (resb) { res = "Door open."; man->CheckOverwatchTarget(); } else { res = "Cannot open door."; man->removeLatestRecord(); } } state=GUI_WAITING; return res; } QString GUICommandLine::commandClose(QString &command) { QString res; Creature *crea = man->getSelected(); if (crea == 0) { res = "There is no selected creature. Please select one before."; } else { int xcoord, ycoord; int nb = sscanf(command.latin1(), "%*s %d %d",&xcoord, &ycoord); bool resb; if (nb<2) resb = crea->CloseDoor(); else resb = crea->CloseDoor(xcoord+ycoord*board->Xmax); if (resb) { res = "Door closed."; } else { res = "Cannot close door."; man->removeLatestRecord(); } } state=GUI_WAITING; return res; } QString GUICommandLine::commandAttack(QString &command) { QString res; Creature *crea = man->getSelected(); if (crea == 0) { res = "There is no selected creature. Please select one before."; } else { int resi = man->Attack(crea); switch (resi) { case 0: res = "Cannot attack."; man->removeLatestRecord(); break; case 1: res = "Defenser and attacker had equal score. Nothing happens."; break; case 2: res = "Defenser was better : you were killed."; break; case 3: res = "Defenser was better but attack was not frontal..."; break; case 4: res = "Attack is successful, you killed the creature."; break; default: res = "Error during attack command."; } if (resi!=0) man->CheckOverwatchTarget(); } state=GUI_WAITING; return res; } QString GUICommandLine::commandShoot(QString &command) { QString res; Creature *crea = man->getSelected(); if (crea == 0) { res = "There is no selected creature. Please select one before."; } else { int xcoord, ycoord; int nb = sscanf(command.latin1(), "%*s %d %d",&xcoord, &ycoord); if (nb<2) { res = "Please choose the target you want to shoot."; setState(GUI_SHOOT); return res; } int resi = man->Shoot(crea, xcoord+ycoord*board->Xmax); switch (resi) { case -1: res = "Cannot shoot."; man->removeLatestRecord(); break; case 0: res = "Shoot has failed. Nothing happens."; break; case 1: res = "Good Shot! Creature killed."; break; case 2: res = "Perfect shot! Two creatures were killed."; break; default: res = "Error during shoot command."; } } return res; } QString GUICommandLine::commandOverwatch(QString &command) { QString res; Creature *crea = man->getSelected(); if (crea == 0) { res = "There is no selected creature. Please select one before."; } else { bool resb = crea->Overwatch(); if (resb) res = "Marine is now on Overwatch mode."; else { res = "Creature cannot be put on Overwatch mode."; } } state=GUI_WAITING; return res; } QString GUICommandLine::commandUnjam(QString &command) { QString res; Creature *crea = man->getSelected(); if (crea == 0) { res = "There is no selected creature. Please select one before."; } else { bool resb = crea->Unjam(); if (resb) res = "Marine has cleared his jammed bolter."; else { res = "Creature cannot clear his bolter."; man->removeLatestRecord(); } } state=GUI_WAITING; return res; } QString GUICommandLine::commandFire(QString &command) { QString res; Creature *crea = man->getSelected(); if (crea == 0) { res = "There is no selected creature. Please select one before."; } else { int xcoord, ycoord; int nb = sscanf(command.latin1(), "%*s %d %d",&xcoord, &ycoord); if (nb<2) { res = "Please choose the case you want to flame."; setState(GUI_FIRE); return res; } bool resb = crea->Fire(xcoord+ycoord*board->Xmax); if (resb) res = "Flamer Marine has fired."; else { res = "Creature cannot use the flame-thrower."; man->removeLatestRecord(); } } return res; } QString GUICommandLine::commandStop(QString &command) { state=GUI_WAITING; return("returning in normal mode."); } QString GUICommandLine::commandLoadFlamer(QString &command) { QString res; Creature *crea = man->getSelected(); if (crea == 0) { res = "There is no selected creature. Please select one before."; } else { bool resb = crea->Reload(); if (resb) res = "Flamer Marine has reload his flamer."; else { res = "Creature cannot reload his flamer."; man->removeLatestRecord(); } } state=GUI_WAITING; return res; } QString GUICommandLine::commandTakeOrDrop(QString &command) { QString res; Creature *crea = man->getSelected(); if (crea == 0) { res = "There is no selected creature. Please select one before."; } else { if (crea->hasAnObject()) { crea->dropTakenObject(); res = "Your creature has dropped the object."; } else { if (crea->takeObject()) res = "Your marine has taken the object."; else res = "Creature cannot take any object."; } } state=GUI_WAITING; return res; } QString GUICommandLine::commandMessage(QString &command) { if (man->isInReplayMode()) { QString msg = command.right(command.length()-8); // bad hack... printPopupMessage(msg); return "Message shown."; } else if (man->isInRecordMode()) return "The message has been correctly stored."; return "You can't use this action now. You must be in a recording mode."; } QString GUICommandLine::commandRecord(QString &command) { char cmd[10]; sscanf(command.latin1(), "%*s %s",cmd); if (strcmp(cmd,"begin")==0) { if (man->getGameType()==PBEM) return "You can't record your actions during a PBEM game."; man->InitPBEM(); return "All your actions will now be recorded."; } else if (strcmp(cmd,"end")==0) { if (session->SaveRecording()) return "You have saved your recording actions."; return "A problem has occured. The recorded game cannot be saved."; } return "The command record must be followed by the keyword begin or end."; } QString GUICommandLine::commandUndo(QString &command) { if (man->Undo()) return "Last command has been undone."; else return "Only move and turn can be undone."; } QString GUICommandLine::commandSave(QString &command) { int i = command.find(' '); QString filename = command.right(command.length()-i-1); session->Save(filename); //For this command, the returned message is done in SessionManager. return ""; } QString GUICommandLine::commandLoad(QString &command) { int i = command.find(' '); QString filename = command.right(command.length()-i-1); session->LoadFromFilename(filename); //For this command, the returned message is done in SessionManager. return ""; } QString GUICommandLine::commandConnect(QString &command) { man->Connect(); return "Connection in progress...\n"; } QString GUICommandLine::commandNetwork(QString &command) { char cmd[64]; int sock; sscanf(command.latin1(), "%*s %s %d",cmd,&sock); if (strcmp(cmd,"init")==0) { session->NewGameStep2(); } else if (strcmp(cmd,"filereceived")==0) { QString content = man->net->getFileContent(); session->LoadFromContent(content); } return ""; } FullDirection GUICommandLine::getDirectionType(char *d) { state=GUI_WAITING; if (strcmp(d,"north")==0 || strcmp(d,"n")==0) return NORTHNORTH; if (strcmp(d,"north-east")==0 || strcmp(d,"n-e")==0) return NORTHEAST; if (strcmp(d,"east")==0 || strcmp(d,"e")==0) return EASTEAST; if (strcmp(d,"south-east")==0 || strcmp(d,"s-e")==0) return SOUTHEAST; if (strcmp(d,"south")==0 || strcmp(d,"s")==0) return SOUTHSOUTH; if (strcmp(d,"south-west")==0 || strcmp(d,"s-w")==0) return SOUTHWEST; if (strcmp(d,"west")==0 || strcmp(d,"w")==0) return WESTWEST; if (strcmp(d,"north-west")==0 || strcmp(d,"n-w")==0) return NORTHWEST; return NORTHNORTH; } QString GUICommandLine::commandHelp(QString &command) { QString str; QTextStream res(&str,IO_WriteOnly); res << "List of commands :" << endl; res << " View List : get list of all creatures.\n"; res << " View Map : get an ASCII representation of the map.\n"; res << " View Selected : get infos on current selected creature.\n"; res << " View Creature : get infos on creature of id .\n"; res << " View Case : get infos on what is on square .\n"; res << " View Missiondescription: get infos on current mission.\n\n"; res << " Select : select creature .\n"; res << " Select : select creature in square .\n"; res << " Move : move to direction dir (n|e|w|s|n-w|n-e|s-w|s-e).\n"; res << " TUurn .\n"; res << " Enter : enter your selected creature from an entry zone into game.\n"; res << " Revert : revert your selected blip into genestealers.\n"; res << " Open : open door.\n"; res << " Close : close door.\n\n"; res << " Attack : attack creature or door (specify dir only for blip).\n"; res << " Shoot : shoot at creature or door on square (only for marine).\n"; res << " Fire : put a flame on square (only for flamer).\n"; res << " StOp: stop firing or shooting mode.\n"; res << " Reload: reload the flamer ammunitions.\n"; res << " Overwatch: put your selected creature in a overwatch state.\n"; res << " Unjam: clear the jammed bolter of your selected marine.\n"; res << " Takeordrop: take or drop object (for specific level).\n"; res << " Endturn: change player turn.\n"; res << " Save save current game in .\n"; res << " Message For pbem, it will add a message which will be shown" "\nduring replay.\n"; res << " Connect To connect to a player for network play.\n"; res << "\n is one of (n,s,e,w).\n"; return str; }