E:/Eigene Dateien/Eigene Projekte/c0re/FunctionHandler.cpp

Go to the documentation of this file.
00001 /*
00002         This file is part of c0re.
00003 
00004         c0re is a multiplayer RTS on a hexagonal map with an evolving unit concept.
00005     Copyright (C) 2007 Stephan Hofmann
00006 
00007     c0re is free software: you can redistribute it and/or modify
00008     it under the terms of the GNU General Public License as published by
00009     the Free Software Foundation, either version 3 of the License, or
00010     (at your option) any later version.
00011 
00012     This program is distributed in the hope that it will be useful,
00013     but WITHOUT ANY WARRANTY; without even the implied warranty of
00014     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015     GNU General Public License for more details.
00016 
00017     You should have received a copy of the GNU General Public License
00018     along with this program.  If not, see <http://www.gnu.org/licenses/>.
00019 */
00020 
00021 #include "FunctionHandler.h"
00022 
00023 #include <assert.h>
00024 
00025 #include "Level.h"
00026 #include "Window.h"
00027 #include "Player.h"
00028 #include "Button.h"
00029 #include "DAEffect.h"
00030 #include "EventAnimation.h"
00031 #include "EventComputeUnit.h"
00032 #include "EventDeleteEffect.h"
00033 #include "EventDeleteUnit.h"
00034 #include "EventUnblockUnit.h"
00035 
00036 FunctionHandler::FunctionHandler()
00037 {
00038 }   
00039    
00040 FunctionHandler::~FunctionHandler()
00041 {
00042    
00043 }   
00044  
00045 
00046 std::string FunctionHandler::quit(std::vector<std::string>& p_params, Level* level)
00047 {
00048         
00049         return "";
00050 }
00051 
00052 std::string FunctionHandler::zoomIn(std::vector<std::string>& p_params, Level* level)
00053 {
00054         double z = ((level->position.z -3.5) / 1.3 ) + 3.5;
00055         if (z < 4.0)
00056                 z = 4.0;
00057         level->position.z = z;
00058         return "";
00059 }
00060  
00061 std::string FunctionHandler::zoomOut(std::vector<std::string>& p_params, Level* level)
00062 {
00063         double z =  ((level->position.z -3.5) * 1.3 ) + 3.5;
00064         if (z > 40.0)
00065                 z = 40.0;
00066         level->position.z = z;  
00067         return "";
00068 }
00069 
00070 std::string FunctionHandler::scrollUp(std::vector<std::string>& p_params, Level* level)
00071 {
00072         level->position.y -= 0.1;
00073         return "";
00074 }
00075  
00076 std::string FunctionHandler::scrollDown(std::vector<std::string>& p_params, Level* level)
00077 {
00078         level->position.y += 0.1;
00079         return "";
00080 }
00081  
00082 std::string FunctionHandler::scrollLeft(std::vector<std::string>& p_params, Level* level)
00083 {
00084         level->position.x -= 0.1;       
00085         return "";
00086 }
00087  
00088 std::string FunctionHandler::scrollRight(std::vector<std::string>& p_params, Level* level)
00089 {
00090         level->position.x += 0.1;
00091         return "";
00092 }
00093 
00094 std::string FunctionHandler::select(std::vector<std::string>& p_params, Level* level)
00095 {
00096         int id = level->pick();
00097         if (id > 0)
00098         {
00099                 Texture* texture = Texture::get(id);
00100                 if (texture == 0)
00101                         return "";
00102 
00103                 Button *btn = texture->getButton();
00104                 if (btn != 0)
00105                 {
00106                         if (btn->label.find("BUTTONBONUS") != std::string::npos)
00107                                 return FunctionHandler::selectBonus(p_params, level);
00108                         else
00109                                 level->inputMessages.push_back(btn->label);
00110                         return "";
00111                 }
00112 
00113                 //clean cast
00114                 Field * field = texture->getField();
00115                 if (field == 0)
00116                         return "";
00117                 //save the origin
00118                 Field::s_selectedFieldID = field->id;
00119 
00120                 //select the child object
00121                 if (field->unit != 0)
00122                 {
00123                         //now bind new functions
00124                         if (!field->unit->isSettled) //functions for not settled units
00125                         {
00126                                 level->bindings["+RMOUSE"] = "!STANDARDACTION";
00127                                 level->bindings["+S"] = "!SETTLE"; 
00128                                 level->bindings["BUTTONSETTLE"] = "!SETTLE";
00129                         }
00130                         else //functions for settled units
00131                         {
00132                                 level->bindings.erase("+RMOUSE");
00133                                 level->bindings["+T"] = "!TERMINATE";
00134                                 if (field->unit->generates != "#")
00135                                         level->bindings["+RMOUSE"] = "!SETSPAWNDESTINATION";
00136                                 
00137                         }
00138                         Unit::s_selectedID = field->unit->id;
00139                 }
00140                 else 
00141                 {
00142                         //no unit selected -> rebind scrolling
00143                         level->bindings["+RMOUSE"] = "!GRABSCREEN";
00144                         level->bindings["-RMOUSE"] = "!RELEASESCREEN";
00145                         level->bindings.erase("+S");
00146                         level->bindings.erase("BUTTONSETTLE");
00147                         Unit::s_selectedID = -1;
00148                 }
00149         }
00150         
00151         return "";
00152 }
00153 
00154 std::string FunctionHandler::grabScreen(std::vector<std::string>& p_params, Level* level)
00155 {
00156         //at first save mouse coordinates
00157         level->mousePos = level->window->mousePos;
00158         //now we will scroll the window eah time
00159         level->currentCommands.push_back("SCROLLSCREEN");
00160         //o left mousbutton actios!
00161         level->bindings.erase("+LMOUSE");
00162         return "";
00163 }
00164 
00165 std::string FunctionHandler::releaseScreen(std::vector<std::string>& p_params, Level* level)
00166 {
00167         level->currentCommands.remove("SCROLLSCREEN");
00168         //add left mouse button actions
00169         level->bindings["+LMOUSE"] = "!SELECT";
00170         return "";
00171 }
00172 
00173 std::string FunctionHandler::scroll(std::vector<std::string>& p_params, Level* level)
00174 {
00175         Vector3i d_mouse = level->mousePos - level->window->mousePos;
00176         Vector3d d_move;
00177         d_move.x = d_mouse.x / (double) level->window->width;
00178         d_move.y = (-1) * (d_mouse.y / (double) level->window->height);
00179         d_move *= (level->position.z);
00180         level->position += d_move;
00181 
00182         level->mousePos = level->window->mousePos;
00183         return "";
00184 }
00185 
00186 std::string FunctionHandler::standardAction(std::vector<std::string>& p_params, Level* level)
00187 {
00188         //have we picked soething?
00189         int id = level->pick();
00190         if (id <= 0)
00191                 return ""; //no
00192 
00193         //get the destination
00194         Texture* texture = Texture::get(id);
00195         if (texture == 0)
00196                 return "";
00197 
00198         //clean cast
00199         Field * destination = texture->getField();
00200         if (destination == 0)
00201                 return "";
00202 
00203         //get the origin field
00204         texture = Texture::get(Field::s_selectedFieldID);
00205         //clean cast
00206         Field* origin = texture->getField();
00207         if(origin->unit == 0)                   //this function may only be called if an unit has been selected
00208                 return "";                                      //but when so unit has lost.... there is nothing to do :D
00209 
00210         if (origin->unit->isBlocked)            //do nothing if we are in any cooldown
00211                 return "";
00212         
00213         //now test which standard action
00214         if (Field::s_selectedFieldID == destination->id) //same field we are on -> settle
00215                 return FunctionHandler::settle(p_params, level);
00216 
00217         //now check if on the destination field a unit is on
00218         if (destination->unit == 0) //no it is not -> check for moving
00219         {
00220                 //check if it is in range
00221                 if  (isConnected(origin, destination) == -1)
00222                         return ""; //not connected
00223 
00224                 //check if there is enough energy to pay
00225                 if (origin->unit->player->energy < origin->unit->move_cost)
00226                         return "";
00227 
00228                 //we proceed, move the object
00229                 origin->unit->player->energy -= origin->unit->move_cost; //pay for it
00230                 destination->unit = origin->unit;
00231                 origin->unit = 0;
00232                 Field::s_selectedFieldID = destination->id;
00233                 destination->unit->isBlocked = true;
00234                 level->eventList[destination->unit->move_cooldown].push_back(new EventUnblockUnit(destination->unit));
00235 
00236         }
00237         else //there is another unit
00238         {
00239                 //so we check if it is an oponents unit
00240                 if (origin->unit->player == destination->unit->player) //same player?
00241                         return ""; //then we can do nothing
00242 
00243                 if (origin->unit->player->energy < origin->unit->absorb_cost)
00244                         return ""; //not enough energy for DA
00245 
00246                 //check for distance
00247                 int xDif = destination->xCoord - origin->xCoord;
00248                 int yDif = destination->yCoord - origin->yCoord;
00249                 if (! ( ((abs(xDif) == 0) && (abs(yDif) <= 2))
00250                                 ||      ((abs(xDif) <= 2) && (abs(yDif) <= 1))
00251                                 ||      ((abs(xDif) == 1) && (origin->xCoord % 2 == 0) && (yDif == -2))
00252                                 ||      ((abs(xDif) == 1) && (origin->xCoord % 2 == 1) && (yDif == 2)) ))
00253                 {
00254                         return ""; //out of range
00255                 }
00256 
00257 
00258                 /************ attack ************/
00259                 //pay for DA
00260                 origin->unit->player->energy -= origin->unit->absorb_cost;
00261 
00262                 //compute
00263                 int ori_combatvalue = origin->unit->getCombatValue(rand() / (double)RAND_MAX); //combat value of attacker
00264                 int des_combatvalue = destination->unit->getCombatValue(rand() / (double)RAND_MAX); //combatvalue of attacked
00265                 Field* loosing = 0;
00266 
00267                 //now the difference if we fight against a core or not core-combat_value = 99!
00268                 if (des_combatvalue == 99)
00269                 {       
00270                         //we assume that we cannot be attacked by a core
00271                         if (ori_combatvalue != 99)
00272                         {
00273                                 destination->unit->player->energy -= ori_combatvalue;
00274                                 origin->unit->isBlocked = true;
00275                                 level->eventList[origin->unit->absorb_cooldown_core].push_back(new EventUnblockUnit(origin->unit));
00276                                 if (destination->unit->player->energy < 0)
00277                                         loosing = destination; //delete the core if the player is dead
00278                         }
00279                 }
00280                 else //not a core
00281                 {
00282                         if (ori_combatvalue == des_combatvalue) //no patt :)
00283                                 des_combatvalue += ((int)((rand()/(double)RAND_MAX) + 0.5) * 2) - 1;  //50% chance if equal for both
00284                         if (des_combatvalue < ori_combatvalue)
00285                         {       //attacker wins
00286                                 loosing = destination;
00287                                 origin->unit->isBlocked = true;
00288                                 level->eventList[origin->unit->absorb_cooldown].push_back(new EventUnblockUnit(origin->unit));
00289                         }
00290                         else
00291                                 loosing = origin;
00292                 }
00293 
00294                 DAEffect *dae = new DAEffect(Vector3i(origin->xCoord, origin->yCoord, 0), Vector3i(destination->xCoord, destination->yCoord, 0), ori_combatvalue, des_combatvalue, level);
00295                 dae->loadAndBind("textures//dae-seq.png");
00296                 dae->sequenceCount = 4;
00297                 level->effects.push_back(dae);
00298                 //now we will call this event 16 times, but only all 4 rounds
00299                 for (int i = 0; i < 16; i++)
00300                         level->eventList[4*i + 1].push_back(new EventAnimation(dae, 1));
00301                 //and finally we will delete the effect
00302                 level->eventList[65].push_back(new EventDeleteEffect(dae));
00303                 //and also we will delete the unit
00304                 if (loosing != 0)
00305                 {
00306                         level->eventList[65].push_back(new EventDeleteUnit(loosing));
00307                         loosing->unit->isBlocked = true;
00308                 }
00309                 /************ end attack ************/
00310         }
00311 
00312         return "";
00313 }
00314 
00315 std::string FunctionHandler::settle(std::vector<std::string>& p_params, Level* level)
00316 {
00317         //get the origin field
00318         Texture *texture = Texture::get(Field::s_selectedFieldID);
00319         //clean cast
00320         Field* origin = texture->getField();
00321 
00322         assert(origin->unit != 0);
00323 
00324         if (origin->unit->isBlocked)
00325                 return "";
00326 
00327         if (origin->energy == 0)
00328                 return "";
00329 
00330         if (origin->isSettleRange)
00331                 return "";
00332 
00333         //settle
00334         if (origin->unit->settle(level) == 0) //sucessful settled
00335         {
00336                 level->bindings.erase("+S");
00337                 level->bindings.erase("+RMOUSE");
00338                 if (origin->unit->generates != "#")
00339                         level->bindings["+RMOUSE"] = "!SETSPAWNDESTINATION";
00340                 level->eventList[origin->unit->settle_cooldown].push_back(new EventComputeUnit(origin));
00341         }
00342 
00343         return "";
00344 }
00345 
00346 std::string FunctionHandler::terminate(std::vector<std::string>& p_params, Level* level)
00347 {
00348         //get the origin field
00349         Texture *texture = Texture::get(Field::s_selectedFieldID);
00350         //clean cast
00351         Field* origin = texture->getField();
00352                         
00353         bool doIt = false;
00354         
00355         doIt = true;
00356 
00357         if (origin->unit->mutates == "#")
00358                 doIt = false;
00359 
00360         if (doIt)
00361         {//settle
00362                 origin->unit->mutate(level);
00363                 level->bindings["+RMOUSE"] = "!STANDARDACTION";
00364                 level->bindings["+S"] = "!SETTLE";
00365         }
00366 
00367         return "";
00368 }
00369 
00370 std::string FunctionHandler::setSpawnDestination(std::vector<std::string>& p_params, Level* level)
00371 {
00372         //get the origin field
00373         Texture *texture = Texture::get(Field::s_selectedFieldID);
00374         //clean cast
00375         Field* origin = texture->getField();
00376         //and get the settled unit
00377         Unit* unit = origin->unit;
00378         
00379         //now get the field that has been choosen;
00380         int id = level->pick();
00381         //nothing picked
00382         if (id <= 0)
00383                 return "";
00384 
00385         texture = Texture::get(id);
00386         if (texture == 0)
00387         { //nothing selected -> delete spwan point
00388                 unit->s_selectedID = -1;
00389                 return "";
00390         }
00391 
00392         //clean cast
00393         Field * destination = texture->getField();
00394         if (destination == 0)
00395         { //nothing selected -> delete spwan point
00396                 unit->s_selectedID = -1;
00397                 return "";
00398         }
00399 
00400         //now check if they are connected
00401         int spawnDirection = isConnected(origin, destination);
00402         if (spawnDirection == -1) //not connected
00403         {
00404                 //but maybe we can attack it? if we are a core :D
00405                 if (origin->unit->settledCombatValue == 99)
00406                         return FunctionHandler::standardAction(p_params, level);
00407         }
00408 
00409         //check if there is a unit
00410         if (destination->unit != 0)
00411         {
00412                 if (destination->unit->isSettled)       //we cannot spawn if there is something settled
00413                 {
00414                         unit->spawnDestination = -1;
00415                         return "";
00416 
00417                 }
00418                 //is it an enemy unit?
00419                 if (destination->unit->player != unit->player)
00420                 {
00421                         //so we can attack it, if we are a core :D
00422                         if (origin->unit->settledCombatValue == 99)
00423                                 return FunctionHandler::standardAction(p_params, level);
00424                 } //if it is a friedly unit we can set the spawnpoint
00425         }
00426         
00427         //so we can set the spawpoint
00428         unit->spawnDestination = spawnDirection;
00429         unit->spawnDestinationField = destination; // this must only be used if spawnDirection > -1
00430         level->eventList[1].push_back(new EventComputeUnit(origin)); //next round we compute the unit
00431 
00432         return "";
00433 }
00434 
00435 std::string FunctionHandler::selectBonus(std::vector<std::string>& p_params, Level* level)
00436 {
00437         //get the origin field
00438         Texture *texture = Texture::get(Field::s_selectedFieldID);
00439         // if == 0 nothing slected till now
00440         if (texture == 0)
00441                 return ""; //nothing to do
00442         //clean cast
00443         Field* origin = texture->getField();
00444         //and get the settled unit
00445         Unit* unit = origin->unit;
00446         assert(unit != 0);
00447 
00448         //now get the field that has been choosen;
00449         int id = level->pick();
00450         //nothing picked
00451         if (id <= 0)
00452                 return "";
00453         texture = Texture::get(id);
00454         if (texture == 0)
00455                 return ""; //nothing selected
00456         Button *btn = texture->getButton();
00457         if (btn == 0)
00458                 return ""; //it's not a button
00459         if (btn->val == -1)
00460                 return ""; // not a bonus button
00461         if (unit->player->energy < btn->val)
00462                 return ""; //not enough energy
00463         if (unit->bonus == btn->val)
00464                 return ""; //no change
00465         if (((unit->movingCombatBonus == 0) && (!unit->isSettled)) || ((unit->settledCombatBonus == 0) && (unit->isSettled)))
00466                 return ""; //no bonus available
00467         unit->bonus = btn->val;
00468         unit->player->energy -= btn->val;
00469         
00470         return "";
00471 }
00472 
00473 int FunctionHandler::isConnected(Field* origin, Field* destination)
00474 {
00475         int ret = -1;
00476 
00477         int xDif = destination->xCoord - origin->xCoord;
00478         int yDif = destination->yCoord - origin->yCoord;
00479         if ((xDif == 0) && (abs(yDif) == 1))
00480         {
00481                 if (yDif == 1)
00482                         ret = 0;
00483                 else
00484                         ret = 3;
00485         }
00486         if((origin->xCoord % 2) == 0) //if x is even
00487         {
00488                 if ((abs(xDif) == 1) && ((yDif == 0) || (yDif == -1)))
00489                 {
00490                         if (yDif == 0) //upper field
00491                         {
00492                                 if (xDif == -1)
00493                                         ret = 1;
00494                                 else
00495                                         ret = 5;
00496                         }
00497                         else // lower field
00498                                                         {
00499                                 if (xDif == -1)
00500                                         ret = 2;
00501                                 else
00502                                         ret = 4;
00503                         }
00504                 }
00505         }
00506         else    //x is odd
00507         {
00508                 if ((abs(xDif) == 1) && ((yDif == 0) || (yDif == 1)))
00509                 {
00510                         if (yDif == 1) //upper field
00511                         {
00512                                 if (xDif == -1)
00513                                         ret = 1;
00514                                 else
00515                                         ret = 5;
00516                         }
00517                         else // lower field
00518                                                         {
00519                                 if (xDif == -1)
00520                                         ret = 2;
00521                                 else
00522                                         ret = 4;
00523                         }
00524                 }
00525         }
00526         
00527         return ret;
00528 }

Generated on Tue Jul 17 22:02:22 2007 for C0re by  doxygen 1.5.2