Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | File List

Packet.cpp

00001 /*
00002 Copyright 2003 - 2005 Elliott Kleinrock, Dan Neely, Kurt W. Over, Damon Domjan
00003 
00004 This file is part of FreeStars, a free clone of the Stars! game.
00005 
00006 FreeStars is free software; you can redistribute it and/or modify
00007 it under the terms of the GNU General Public License as published by
00008 the Free Software Foundation; either version 2 of the License, or
00009 (at your option) any later version.
00010 
00011 FreeStars is distributed in the hope that it will be useful,
00012 but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 GNU General Public License for more details.
00015 
00016 You should have received a copy of the GNU General Public License
00017 along with FreeStars; if not, write to the Free Software
00018 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019 
00020 The full GPL Copyright notice should be in the file COPYING.txt
00021 
00022 Contact:
00023 Email Elliott at 9jm0tjj02@sneakemail.com
00024 */
00025 
00026 #include "FSServer.h"
00027 
00028 #include "Packet.h"
00029 
00030 #ifdef _DEBUG
00031 #define new DEBUG_NEW
00032 #endif
00033 
00034 //dan Neely 7-1-03
00035 
00036 Packet::Packet(const CargoHolder &source, long speed, long driverSpeed, Planet * destination)
00037 :       CargoHolder(source),
00038         mSpeed(speed),
00039         mDriverSpeed(driverSpeed),
00040         mDestination(destination),
00041         mFirstYear(true)
00042 {
00043         mID = TheGalaxy->GetPacketID();
00044 }
00045 
00046 Packet::~Packet()
00047 {
00048 }
00049 
00050 bool Packet::ParseNode(const TiXmlNode * node)
00051 {
00052         mFirstYear = false;
00053         if (!CargoHolder::ParseNode(node))
00054                 return false;
00055 
00056         mSpeed = GetLong(node->FirstChild("Speed"));
00057         if (mSpeed < 0) {
00058                 Message * mess = NCGetOwner()->AddMessage("Error: Invalid packet speed");
00059                 mess->AddLong("Speed", mSpeed);
00060                 return false;
00061         }
00062 
00063         mDestination = TheGalaxy->GetPlanet(GetString(node->FirstChild("Destination")));
00064         if (mDestination == NULL) {
00065                 Message * mess = NCGetOwner()->AddMessage("Error: Invalid packet destination");
00066                 mess->AddItem("Destination", GetString(node->FirstChild("Destination")));
00067                 return false;
00068         }
00069 
00070         TheGame->AddAlsoHere(this);
00071         return true;
00072 }
00073 
00074 TiXmlNode * Packet::WriteNode(TiXmlNode * node, const Player * viewer) const
00075 {
00076         if (viewer != NULL && !SeenBy(viewer))
00077                 return NULL;
00078 
00079         CargoHolder::WriteNode(node, viewer);
00080         AddLong(node, "Speed", mSpeed);
00081         AddString(node, "Destination", mDestination->GetName().c_str());
00082 
00083         return node;
00084 }
00085 
00086 long Packet::GetCloak(const Player *, bool) const
00087 {
00088         return GetOwner()->InherentCloaking(HC_ALL);
00089 }
00090 
00091 long Packet::GetScanPen() const
00092 {
00093         if (GetOwner()->PacketScanning())
00094                 return mSpeed * mSpeed;
00095         else
00096                 return -1;
00097 }
00098 
00099 long Packet::GetScanSpace() const
00100 {
00101         if (GetOwner()->PacketScanning())
00102                 return mSpeed * mSpeed;
00103         else
00104                 return -1;
00105 }
00106 
00107 void Packet::Collide()
00108 {
00109         Message * mess = mDestination->NCGetOwner()->AddMessage("Packet hit", mDestination);
00110 
00111 //Speed
00112 //spdPacket = Packet Warp ^ 2
00113 //spdReceiver = Rcvr Accel ^ 2
00114 
00115 //Percent Caught Safely: The percentage of the packet recovered intact.
00116 //%CaughtSafely = spdReceiver / spdPacket
00117 //Minerals Recovered: The receiver recovers 1/3 of the portion not caught safely.
00118 //(packetkT x %CaughtSafely + packetkT x %remaining x 1/3)
00119         const Ship * defendingStarBase = mDestination->GetBaseDesign();
00120 
00121         long defendingDriver = 0;
00122 
00123         if (defendingStarBase != NULL) {
00124                 long defendingDriver = defendingStarBase->GetDriverSpeed();
00125                 defendingDriver += (defendingStarBase->CountDrivers());
00126                 defendingDriver--;  // could use an if and ++ if two returned but this
00127                 //will generalize for N driver bases.
00128         }
00129         
00130         long catchAs = defendingDriver * defendingDriver;
00131         const Player * defender = mDestination->NCGetOwner();
00132         // used to factor ITs not beign able to safely catch packets at any speed
00133         if (defender != NULL)
00134                 catchAs = long(catchAs * defender->PacketCatchFactor());
00135 
00136         long minsCaught;
00137 
00138         long packetMass = GetCargoMass();
00139         mess->AddLong("Packet size", GetCargoMass());
00140 
00141         double fractionCaught = double(GetSpeed() * GetSpeed()) / catchAs;
00142         for (CargoType i = 0; i < Rules::MaxMinType; i++)
00143         {
00144                 minsCaught = int(GetContain(i) * fractionCaught + .5);
00145                 packetMass -= minsCaught;
00146                 minsCaught += int((GetContain(i) - minsCaught + .5) / 3.0);
00147                 mDestination->AdjustAmounts(i, minsCaught);
00148         }
00149 
00150 //Raw Damage
00151 //dmgRaw = (spdPacket - spdReceiver) x wtPacket / 160
00152         double rawDamage = packetMass / 160;
00153 
00154 //Raw Damage modified by planetary defenses
00155 //dmgRaw2 = dmgRaw x (100% - pctDefCoverage)
00156         rawDamage = rawDamage * (1.0 - mDestination->GetDefenseValue());
00157 
00158 //Colonists Killed: The number colonists killed is the larger (maximum) 
00159 //of the following:
00160 //dmgRaw2 x Population / 1000 
00161 //dmgRaw2 x 100
00162         int killed = max(long(rawDamage * 100), long((rawDamage * mDestination->GetPopulation() + 500) / 1000));
00163         mDestination->AdjustAmounts(POPULATION, -killed);
00164         mess->AddLong("Colonists killed", killed);
00165 
00166         // check if Destination dead is done in Game
00167 
00168 //Destinationary Defenses Destroyed
00169 //#destroyed = #defenses x dmgRaw2 / 1000
00170 //If #destroyed is less than dmgRaw2 / 20, then it is that number.
00171 
00172         long numDefs = mDestination->GetDefenses();
00173         long numDefsDestroyed;
00174         numDefsDestroyed = max(long(numDefs * rawDamage / 1000), long(rawDamage / 20));
00175         numDefsDestroyed = min(numDefsDestroyed, numDefs);
00176 
00177         mDestination->AdjustDefenses(-numDefsDestroyed);
00178         mess->AddLong("Defenses destroyed", numDefsDestroyed);
00179 
00180         if (GetOwner()->PacketTerraform()) {
00181                 // TODO packetforming
00182         }
00183 }
00184 
00185 bool Packet::Move(bool FirstYear)
00186 {
00187         if (FirstYear != mFirstYear)
00188                 return false;
00189 
00190         long distance = mSpeed * mSpeed;
00191         if (mFirstYear)
00192                 distance /= 2;
00193 
00194         double mPX, mPY;
00195         MoveToward(*this, *mDestination, &mPX, &mPY, distance);
00196         Location pt;
00197         pt.SetLocation(long(mPX), long(mPY));
00198 
00199         distance = long(Distance(pt));
00200         SetLocation(pt);
00201 
00202         Decay(distance);
00203         if (GetCargoMass() == 0)
00204                 return true;
00205 
00206         if (IsWith(*mDestination)) {
00207                 Collide();
00208                 return true;
00209         }
00210 
00211         if (mFirstYear) {
00212                 mFirstYear = false;
00213                 TheGame->AddAlsoHere(this);
00214         } else
00215                 TheGame->MoveAlsoHere(this);
00216 
00217         return false;
00218 }
00219 
00220 void Packet::Decay(long distance)
00221 {
00222         double decayRate;
00223         long speed = GetSpeed(); // note will be adjusted for ITs may not be true speed
00224         long firingDriver = GetDriverSpeed();
00225         const Player * owner =NCGetOwner();
00226 
00227         //ITcheck
00228         if (owner->PacketDecayPenalty())
00229                 speed = max(speed, firingDriver) + 1;
00230 
00231         decayRate = (double)Rules::GetArrayFloat("PacketDecayRates", min(3L, speed - this->GetDriverSpeed())) / 100;
00232         decayRate *= owner->PacketDecayFactor(); // PPcheck
00233         if (GetSpeed() * GetSpeed() > distance)
00234                 decayRate *= GetSpeed() * GetSpeed() / distance;        // didn't go full distance
00235 
00236         long decay;
00237         long mindecay = long(Rules::GetConstant("PacketMinimumDecay") * owner->PacketDecayFactor() + .5);
00238         for (int i = 0; i < Rules::MaxMinType; i++) {
00239                 decay = min(GetContain(i), max(mindecay, long(GetContain(i) * decayRate + .5)));
00240                 AdjustAmounts(i, -decay);
00241         }
00242 
00243         mMaxSize = GetCargoMass();
00244 }

Generated on Mon Aug 8 21:33:44 2005 for Freestars by  doxygen 1.4.2-20050421