E:/Eigene Dateien/Eigene Projekte/c0re/Unit.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 "Unit.h"
00022 
00023 #include "system.h"
00024 #include <GL/gl.h>
00025 #include <GL/glu.h>
00026 #include <fstream>
00027 
00028 #include "myTools.h"
00029 #include "Level.h"
00030 #include "Player.h"
00031 #include "EventUnblockUnit.h"
00032 #include "EventComputeUnit.h"
00033 
00034 int Unit::s_selectedID = -1;
00035 
00036 Unit::Unit(Player *p_player)
00037 {
00038         player = p_player;
00039 }
00040 
00041 Unit::~Unit()
00042 {
00043 
00044 }
00045 
00046 int Unit::load(std::string p_filename)
00047 {
00048         int ret = 0;
00049 
00050         std::string texture;
00051 
00052         std::ifstream fin(p_filename.c_str());
00053         std::string buffer;
00054         std::vector<std::string> values;
00055 
00056         isBlocked = false;
00057         isSettled = false;
00058         size = 0.5;
00059         bonus = 0;
00060 
00061         while (fin.good()) {
00062                 std::getline(fin,buffer,'\n');
00063                 splitLine(values, buffer, "=");
00064                 if (values.size() == 2)
00065                 {
00066                         if (values[0].find("name") != std::string::npos)
00067                         {
00068                                 name = values[1];
00069                                 if (name == "Core")
00070                                         isSettled = true;
00071                         }
00072                         else if (values[0].find("size") != std::string::npos)
00073                         {
00074                                 size = atof(values[1].c_str()) * 0.5;
00075                         }
00076                         else if (values[0].find("move_cost") != std::string::npos)
00077                         {
00078                                 move_cost = atoi(values[1].c_str());
00079                         }
00080                         else if (values[0].find("move_cool") != std::string::npos)
00081                         {
00082                                 move_cooldown = (int)(atof(values[1].c_str()) / (double)Level::roundTime * 1000.0);
00083                         }
00084                         else if (values[0].find("generation_cool") != std::string::npos)
00085                         {
00086                                 generate_cooldown = (int)(atof(values[1].c_str()) / (double)Level::roundTime * 1000.0);
00087                         }
00088                         else if (values[0].find("settle_cost") != std::string::npos)
00089                         {
00090                                 settle_cost = atoi(values[1].c_str());
00091                         }
00092                         else if (values[0] == "absorb")
00093                         {
00094                                 absorb_cost = atoi(values[1].c_str());
00095                         }
00096                         else if (values[0] == "absorb_cool")
00097                         {
00098                                 absorb_cooldown = (int)(atof(values[1].c_str()) / (double)Level::roundTime * 1000.0);
00099                         }
00100                         else if (values[0] == "absorb_cool_core")
00101                         {
00102                                 absorb_cooldown_core = (int)(atof(values[1].c_str()) / (double)Level::roundTime * 1000.0);
00103                         }
00104                         else if (values[0].find("settle_energy") != std::string::npos)
00105                         {
00106                                 settle_energy = atoi(values[1].c_str());
00107                         }
00108                         else if (values[0].find("settle_cool") != std::string::npos)
00109                         {
00110                                 settle_cooldown = (int)(atof(values[1].c_str()) / (double)Level::roundTime * 1000.0);
00111                         }
00112                         else if (values[0].find("generates") != std::string::npos)
00113                         {
00114                                 generates = values[1];
00115                         }
00116                         else if (values[0].find("mutates") != std::string::npos)
00117                         {
00118                                 mutates = values[1];
00119                         }
00120                         else if (values[0].find("sprite") != std::string::npos)
00121                         {
00122                                 texture = values[1];
00123                         }
00124                         else if (values[0].find("settleSprite") != std::string::npos)
00125                         {
00126                                 settleSprite = values[1];
00127                         }
00128                         else if (values[0].find("moving_combatvalue") != std::string::npos)
00129                         {
00130                                 movingCombatValue = atoi(values[1].c_str());
00131                         }
00132                         else if (values[0].find("moving_combatbonus") != std::string::npos)
00133                         {
00134                                 movingCombatBonus = atoi(values[1].c_str());
00135                         }
00136                         else if (values[0].find("moving_combatrandom") != std::string::npos)
00137                         {
00138                                 movingCombatRandom = atoi(values[1].c_str());
00139                         }
00140                         else if (values[0].find("settled_combatvalue") != std::string::npos)
00141                         {
00142                                 settledCombatValue = atoi(values[1].c_str());
00143                         }
00144                         else if (values[0].find("settled_combatbonus") != std::string::npos)
00145                         {
00146                                 settledCombatBonus = atoi(values[1].c_str());
00147                         }
00148                         else if (values[0].find("settled_combatrandom") != std::string::npos)
00149                         {
00150                                 settledCombatRandom = atoi(values[1].c_str());
00151                         }
00152                 }
00153         }
00154         fin.close();
00155 
00156         spawnDestination = -1;
00157 
00158         loadAndBind("textures//" + player->color + "//" + texture, TM_Masked_Blue_To_Red);
00159 
00160         return ret;
00161 }
00162 
00163 int Unit::settle(Level* p_level)
00164 {
00165         int ret = 0;
00166 
00167         //check if player has enough energy
00168         if (player->energy >= settle_cost && !isSettled)
00169         {
00170                 player->energy -= settle_cost; // pay for it
00171                 loadAndBind("textures//" + player->color + "//" + settleSprite, TM_Masked_Blue_To_Red);
00172                 isSettled = true;
00173                 size = 0.5;
00174                 isBlocked = true;
00175                 p_level->eventList[settle_cooldown].push_back(new EventUnblockUnit(this));
00176         }
00177         else //no settle
00178         {
00179                 ret = 1;
00180         }
00181 
00182 
00183         return ret;
00184 }
00185 
00186 int Unit::compute(Field* p_field, Level *p_level)
00187 {
00188         int ret = 0;
00189 
00190         if (generates != "#") //unit only generates no energy is delivered
00191         {
00192                 //now look if energy is needed for generation
00193                 if (settle_energy > 0)
00194                 {
00195                         //yes energy is needed
00196                         if (p_field->energy > 0)
00197                         {
00198                                 //yes energy is there
00199                                 if (generate(p_field, p_level) == 1) //we generated something
00200                                 {       //now pay for it
00201                                         leechEnergy(p_field, p_level); //drop the energy
00202                                 }
00203                         }
00204                 }
00205                 else //no energy needed
00206                 {
00207                         generate(p_field, p_level);
00208                 }
00209         }
00210         else if (isSettled && !isBlocked)//no generation -> energy for the pool
00211         {
00212                 //first enter cooldown, so no problem with mutating
00213                 isBlocked = true;
00214                 p_level->eventList[settle_cooldown].push_back(new EventUnblockUnit(this));
00215 
00216                 player->energy += leechEnergy(p_field, p_level);
00217 
00218                 if (isSettled) //still settled?
00219                         p_level->eventList[settle_cooldown].push_back(new EventComputeUnit(p_field));
00220 
00221         }
00222 
00223         return ret;
00224 }
00225 
00226 int Unit::generate(Field* p_field, Level *p_level)
00227 {
00228         int ret = 0;
00229         
00230         if (isSettled && !isBlocked && (spawnDestination > -1))
00231         {
00232                 if (spawnDestinationField->unit == 0)
00233                 {
00234                         spawnDestinationField->unit = new Unit(player);
00235                         spawnDestinationField->unit->load("units//" + generates);
00236                         isBlocked = true;
00237                         p_level->eventList[generate_cooldown].push_back(new EventUnblockUnit(this));
00238                         p_level->eventList[generate_cooldown].push_back(new EventComputeUnit(p_field));
00239                         ret = 1;
00240                 }
00241                 else //we have to check next round, maybe the unit has been moved away
00242                         p_level->eventList[1].push_back(new EventComputeUnit(p_field));
00243 
00244         }
00245 
00246         return ret;
00247 }
00248 
00249 int Unit::mutate(Level *p_level)
00250 {
00251         int ret = 0;
00252 
00253         if (isSettled)
00254         {
00255                 load("units//" + mutates);
00256                 p_level->bindings["+RMOUSE"] = "!STANDARDACTION";
00257                 p_level->bindings["+S"] = "!SETTLE";
00258                 p_level->bindings["BUTTONSETTLE"] = "!SETTLE";
00259         }
00260 
00261         return ret;
00262 }
00263 
00264 int Unit::leechEnergy(Field* p_field, Level *p_level)
00265 {
00266         int ret = 0;
00267 
00268         if (p_field->energy > 0)
00269         {
00270                 if (p_field->energy >= settle_energy)
00271                         p_field->energy -= settle_energy;
00272                 else 
00273                         p_field->energy = 0;
00274 
00275                 ret = settle_energy;
00276 
00277                 p_field->select(p_field->textureName);
00278                 if (p_field->energy == 0)
00279                 {
00280                         mutate(p_level);
00281                 }
00282         }
00283 
00284         return ret;
00285 }
00286 
00287 int Unit::render(Vector3d p_pos, Level* p_level, double p_deltasize)
00288 {
00289         int ret = 0;
00290         
00291         glPushMatrix();
00292 
00293         //this is needed as the tile is only using 0.87 of the y-size of the square
00294         glTranslated(p_pos.x, p_pos.y + 0.065, p_pos.z);
00295         
00296         //is there a spwanDestination?
00297         if (spawnDestination >= 0)
00298         {
00299                 glPushMatrix();
00300                 glLineWidth(3.0);
00301                 //so we paint a pointer towards it
00302 
00303                 glRotated(60.0 * (double) spawnDestination, 0.0, 0.0, 1.0);
00304                 glScaled(p_deltasize, p_deltasize, p_deltasize);
00305                 double cd = ((1) / generate_cooldown);
00306                 if (cd > 1.0)
00307                         cd = 1.0;
00308                 glBegin(GL_LINES);
00309                         glColor3d (1.0, 1.0, 1.0);
00310                         glVertex3d(0.0, 0.0, 0.0);
00311                         glVertex3d(0.0, 0.2, 0.0);
00312                         glVertex3d(0.0, 0.2, 0.0);
00313                         glColor3d (1.0, cd, cd); 
00314                         glVertex3d(0.0, 0.4, 0.0);
00315                         glVertex3d(0.0, 0.4, 0.0);
00316                         glVertex3d(0.1, 0.3, 0.0);
00317                         glVertex3d(0.0, 0.4, 0.0);
00318                         glVertex3d(-0.1, 0.3, 0.0);
00319                 glEnd();
00320                 glLineWidth(1.0);
00321                 glPopMatrix();
00322         }
00323 
00324         Object::render(Vector3d(0.0, 0.0, 0.0), p_deltasize);
00325 
00326         double x = 0.125;
00327         double y = 4*x - x;
00328 
00329         //if selected -> paint a box around it
00330         if (s_selectedID == id)
00331         {
00332                 glPushMatrix();
00333                 glScaled(p_deltasize, p_deltasize, p_deltasize);
00334                 //if (p_round > lastMove + (long)move_cooldown)
00335                 if (!isBlocked)
00336                         glColor3d (0.5, 1.0, 0.75);
00337                 else
00338                         glColor3d (1.0, 0.5, 0.75);
00339                 glLineWidth(2.0);
00340                 glBegin(GL_LINE_LOOP);
00341                         glVertex3d(x, y, 0.0);
00342                         glVertex3d(y, x, 0.0);
00343                         glVertex3d(y, -x, 0.0);
00344                         glVertex3d(x, -y, 0.0);
00345                         glVertex3d(-x, -y, 0.0);
00346                         glVertex3d(-y, -x, 0.0);
00347                         glVertex3d(-y, x, 0.0);
00348                         glVertex3d(-x, y, 0.0);
00349                 glEnd();
00350                 glLineWidth(1.0);
00351                 glPopMatrix();
00352         }
00353         
00354         //write the Bonus if available
00355         if (((movingCombatBonus != 0) && (!isSettled)) || ((settledCombatBonus != 0) && (isSettled)))
00356         {
00357                 glColor4d(0.8, 0.8, 0.8, 1.0);
00358                 p_level->glPrint2d(0.0, 0.0, "%i", bonus);
00359         }
00360 
00361         glPopMatrix(); //translation
00362 
00363         return ret;
00364 }
00365 
00366 int Unit::getCombatValue(double p_rand)
00367 {
00368         int ret = 0;
00369 
00370         if (isSettled)
00371         {
00372                 ret += settledCombatValue;
00373                 ret += settledCombatBonus * bonus; // selected bonus
00374                 if (settledCombatRandom > 0)
00375                         ret += (int)((double)settledCombatRandom * p_rand + 1.0);
00376         }
00377         else
00378         {
00379                 ret += movingCombatValue;
00380                 ret += movingCombatBonus * bonus; // selected bonus
00381                 if (movingCombatRandom > 0)
00382                         ret += (int)((double)movingCombatRandom * p_rand + 1.0);
00383         }
00384 
00385         //afterwards the bonus is cleared
00386         bonus = 0;
00387 
00388         return ret;
00389 }

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