resolved conflicts to upstream/develop
This commit is contained in:
commit
9988ea9cbf
|
@ -272,10 +272,11 @@ IF(CMAKE_COMPILER_IS_GNUCXX OR MINGW)
|
|||
IF(APPLE)
|
||||
SET(CUSTOM_DATA_INSTALL_PATH "'\\\\'${CMAKE_INSTALL_PREFIX}/${MEGAGLEST_DATA_INSTALL_PATH}\\\\''" CACHE STRING "The FULL installation path for data files (this is build automatically by combining CMAKE_INSTALL_PREFIX and MEGAGLEST_DATA_INSTALL_PATH)")
|
||||
ELSE()
|
||||
SET(CUSTOM_DATA_INSTALL_PATH "'\\\"${CMAKE_INSTALL_PREFIX}/${MEGAGLEST_DATA_INSTALL_PATH}\\\"'" CACHE STRING "The FULL installation path for data files (this is build automatically by combining CMAKE_INSTALL_PREFIX and MEGAGLEST_DATA_INSTALL_PATH)")
|
||||
SET(CUSTOM_DATA_INSTALL_PATH "\"${CMAKE_INSTALL_PREFIX}/${MEGAGLEST_DATA_INSTALL_PATH}\"" CACHE STRING "The FULL installation path for data files (this is build automatically by combining CMAKE_INSTALL_PREFIX and MEGAGLEST_DATA_INSTALL_PATH)")
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
SET(CUSTOM_DATA_INSTALL_PATH_VALUE "-DCUSTOM_DATA_INSTALL_PATH=${CUSTOM_DATA_INSTALL_PATH}")
|
||||
ADD_DEFINITIONS("-DCUSTOM_DATA_INSTALL_PATH=${CUSTOM_DATA_INSTALL_PATH}")
|
||||
|
||||
SET(PKG_DATADIR ${CUSTOM_DATA_INSTALL_PATH_VALUE})
|
||||
SET(PKG_BINDIR ${MEGAGLEST_BIN_INSTALL_PATH})
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 7de4b4b6d02ae1933e3964cc02d31aa288d49463
|
||||
Subproject commit 4f05a0177385ce47eb4cfcf5ce6676f59b290d37
|
|
@ -54,11 +54,11 @@ fi
|
|||
cd $PROJDIR
|
||||
echo "copying binaries ..."
|
||||
cp -r lib/* "$RELEASEDIR/lib"
|
||||
cp *.ico "$RELEASEDIR/"
|
||||
cp {../shared/,}*.ico "$RELEASEDIR/"
|
||||
cp *.bmp "$RELEASEDIR/"
|
||||
cp *.png "$RELEASEDIR/"
|
||||
cp *.xpm "$RELEASEDIR/"
|
||||
cp *.ini "$RELEASEDIR/"
|
||||
cp {../shared/,}*.ini "$RELEASEDIR/"
|
||||
cp megaglest "$RELEASEDIR/"
|
||||
cp megaglest_editor "$RELEASEDIR/"
|
||||
cp megaglest_g3dviewer "$RELEASEDIR/"
|
||||
|
|
|
@ -148,7 +148,7 @@ case $distribution in
|
|||
$installcommand
|
||||
if [ $? != 0 ]; then error_during_installation; exit 1; fi
|
||||
;;
|
||||
11.10|12.04|12.10|13.04|13.10)
|
||||
11.10|12.04|12.10|13.04|13.10|14.04)
|
||||
installcommand='apt-get install '"$APT_OPTIONS"' build-essential cmake libsdl1.2-dev libalut-dev libgl1-mesa-dev libglu1-mesa-dev libvorbis-dev libwxbase2.8-dev libwxgtk2.8-dev libx11-dev liblua5.1-0-dev libjpeg-dev libpng12-dev libcurl4-gnutls-dev libxml2-dev libircclient-dev libglew-dev libftgl-dev libfribidi-dev libvlc-dev libcppunit-dev'
|
||||
$installcommand
|
||||
if [ $? != 0 ]; then error_during_installation; exit 1; fi
|
||||
|
@ -167,7 +167,7 @@ case $distribution in
|
|||
fi
|
||||
case $release in
|
||||
|
||||
13|14|15)
|
||||
13|14|15|16)
|
||||
installcommand='apt-get install '"$APT_OPTIONS"' build-essential cmake libsdl1.2-dev libalut-dev libgl1-mesa-dev libglu1-mesa-dev libvorbis-dev libwxbase2.8-dev libwxgtk2.8-dev libx11-dev liblua5.1-0-dev libjpeg-dev libpng12-dev libcurl4-gnutls-dev libxml2-dev libircclient-dev libglew-dev libftgl-dev libfribidi-dev libvlc-dev libcppunit-dev'
|
||||
$installcommand
|
||||
if [ $? != 0 ]; then error_during_installation; exit 1; fi
|
||||
|
@ -180,7 +180,7 @@ case $distribution in
|
|||
esac
|
||||
;;
|
||||
|
||||
SuSE|SUSE?LINUX|Opensuse)
|
||||
SuSE|SUSE?LINUX|Opensuse*|openSUSE*)
|
||||
case $release in
|
||||
11.2|11.3|11.4|12.1)
|
||||
installcommand='zypper install gcc gcc-c++ cmake libSDL-devel MesaGLw-devel freeglut-devel libvorbis-devel wxGTK-devel lua-devel libjpeg-devel libpng14-devel libcurl-devel openal-soft-devel xorg-x11-libX11-devel libxml2-devel libircclient-devel glew-devel ftgl-devel fribidi-devel cppunit-devel'
|
||||
|
@ -192,6 +192,11 @@ case $distribution in
|
|||
$installcommand
|
||||
if [ $? != 0 ]; then error_during_installation; exit 1; fi
|
||||
;;
|
||||
13.1)
|
||||
installcommand='zypper install gcc gcc-c++ cmake libSDL-devel Mesa-libGL-devel freeglut-devel libvorbis-devel wxGTK-devel lua-devel libjpeg-devel libpng-devel libcurl-devel openal-soft-devel xorg-x11-libX11-devel libxml2-devel libircclient-devel glew-devel ftgl-devel fribidi-devel cppunit-devel'
|
||||
$installcommand
|
||||
if [ $? != 0 ]; then error_during_installation; exit 1; fi
|
||||
;;
|
||||
*)
|
||||
installcommand='zypper install gcc gcc-c++ cmake libSDL-devel Mesa-libGL-devel freeglut-devel libvorbis-devel wxGTK-devel lua-devel libjpeg-devel libpng14-devel libcurl-devel openal-soft-devel xorg-x11-libX11-devel libxml2-devel libircclient-devel glew-devel ftgl-devel fribidi-devel cppunit-devel'
|
||||
unsupported_release
|
||||
|
|
|
@ -269,6 +269,7 @@
|
|||
<ClCompile Include="..\..\source\glest_game\types\object_type.cpp" />
|
||||
<ClCompile Include="..\..\source\glest_game\types\resource_type.cpp" />
|
||||
<ClCompile Include="..\..\source\glest_game\types\skill_type.cpp" />
|
||||
<ClCompile Include="..\..\source\glest_game\types\projectile_type.cpp" />
|
||||
<ClCompile Include="..\..\source\glest_game\types\tech_tree.cpp" />
|
||||
<ClCompile Include="..\..\source\glest_game\types\unit_type.cpp" />
|
||||
<ClCompile Include="..\..\source\glest_game\types\upgrade_type.cpp" />
|
||||
|
@ -356,6 +357,7 @@
|
|||
<ClInclude Include="..\..\source\glest_game\types\object_type.h" />
|
||||
<ClInclude Include="..\..\source\glest_game\types\resource_type.h" />
|
||||
<ClInclude Include="..\..\source\glest_game\types\skill_type.h" />
|
||||
<ClInclude Include="..\..\source\glest_game\types\projectile_type.h" />
|
||||
<ClInclude Include="..\..\source\glest_game\types\tech_tree.h" />
|
||||
<ClInclude Include="..\..\source\glest_game\types\unit_type.h" />
|
||||
<ClInclude Include="..\..\source\glest_game\types\upgrade_type.h" />
|
||||
|
|
|
@ -1 +1,3 @@
|
|||
/windows_deps*/
|
||||
/glest_game/facilities/gitversion.h
|
||||
/glest_game/site/
|
File diff suppressed because it is too large
Load Diff
|
@ -531,7 +531,7 @@ bool Ai::findAbleUnit(int *unitIndex, CommandClass ability, bool idleOnly){
|
|||
*unitIndex= -1;
|
||||
for(int i=0; i<aiInterface->getMyUnitCount(); ++i){
|
||||
const Unit *unit= aiInterface->getMyUnit(i);
|
||||
if(unit->getType()->hasCommandClass(ability)){
|
||||
if(unit->getType()->isCommandable() && unit->getType()->hasCommandClass(ability)){
|
||||
if(!idleOnly || !unit->anyCommand() || unit->getCurrCommand()->getCommandType()->getClass()==ccStop){
|
||||
units.push_back(i);
|
||||
}
|
||||
|
@ -553,55 +553,57 @@ vector<int> Ai::findUnitsHarvestingResourceType(const ResourceType *rt) {
|
|||
Map *map= aiInterface->getMap();
|
||||
for(int i = 0; i < aiInterface->getMyUnitCount(); ++i) {
|
||||
const Unit *unit= aiInterface->getMyUnit(i);
|
||||
if(unit->getType()->hasCommandClass(ccHarvest)) {
|
||||
if(unit->anyCommand() && unit->getCurrCommand()->getCommandType()->getClass() == ccHarvest) {
|
||||
Command *command= unit->getCurrCommand();
|
||||
const HarvestCommandType *hct= dynamic_cast<const HarvestCommandType*>(command->getCommandType());
|
||||
if(hct != NULL) {
|
||||
const Vec2i unitTargetPos = unit->getTargetPos();
|
||||
SurfaceCell *sc= map->getSurfaceCell(Map::toSurfCoords(unitTargetPos));
|
||||
Resource *r= sc->getResource();
|
||||
if (r != NULL && r->getType() == rt) {
|
||||
units.push_back(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(unit->getType()->hasCommandClass(ccProduce)) {
|
||||
if(unit->anyCommand() && unit->getCurrCommand()->getCommandType()->getClass() == ccProduce) {
|
||||
Command *command= unit->getCurrCommand();
|
||||
const ProduceCommandType *pct= dynamic_cast<const ProduceCommandType*>(command->getCommandType());
|
||||
if(pct != NULL) {
|
||||
const UnitType *ut = pct->getProducedUnit();
|
||||
if(ut != NULL) {
|
||||
const Resource *r = ut->getCost(rt);
|
||||
if(r != NULL) {
|
||||
if (r != NULL && r->getAmount() < 0) {
|
||||
units.push_back(i);
|
||||
}
|
||||
if(unit->getType()->isCommandable()) {
|
||||
if(unit->getType()->hasCommandClass(ccHarvest)) {
|
||||
if(unit->anyCommand() && unit->getCurrCommand()->getCommandType()->getClass() == ccHarvest) {
|
||||
Command *command= unit->getCurrCommand();
|
||||
const HarvestCommandType *hct= dynamic_cast<const HarvestCommandType*>(command->getCommandType());
|
||||
if(hct != NULL) {
|
||||
const Vec2i unitTargetPos = unit->getTargetPos();
|
||||
SurfaceCell *sc= map->getSurfaceCell(Map::toSurfCoords(unitTargetPos));
|
||||
Resource *r= sc->getResource();
|
||||
if (r != NULL && r->getType() == rt) {
|
||||
units.push_back(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(unit->getType()->hasCommandClass(ccBuild)) {
|
||||
if(unit->anyCommand() && unit->getCurrCommand()->getCommandType()->getClass() == ccBuild) {
|
||||
Command *command= unit->getCurrCommand();
|
||||
const BuildCommandType *bct= dynamic_cast<const BuildCommandType*>(command->getCommandType());
|
||||
if(bct != NULL) {
|
||||
for(int j = 0; j < bct->getBuildingCount(); ++j) {
|
||||
const UnitType *ut = bct->getBuilding(j);
|
||||
else if(unit->getType()->hasCommandClass(ccProduce)) {
|
||||
if(unit->anyCommand() && unit->getCurrCommand()->getCommandType()->getClass() == ccProduce) {
|
||||
Command *command= unit->getCurrCommand();
|
||||
const ProduceCommandType *pct= dynamic_cast<const ProduceCommandType*>(command->getCommandType());
|
||||
if(pct != NULL) {
|
||||
const UnitType *ut = pct->getProducedUnit();
|
||||
if(ut != NULL) {
|
||||
const Resource *r = ut->getCost(rt);
|
||||
if(r != NULL) {
|
||||
if (r != NULL && r->getAmount() < 0) {
|
||||
units.push_back(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(unit->getType()->hasCommandClass(ccBuild)) {
|
||||
if(unit->anyCommand() && unit->getCurrCommand()->getCommandType()->getClass() == ccBuild) {
|
||||
Command *command= unit->getCurrCommand();
|
||||
const BuildCommandType *bct= dynamic_cast<const BuildCommandType*>(command->getCommandType());
|
||||
if(bct != NULL) {
|
||||
for(int j = 0; j < bct->getBuildingCount(); ++j) {
|
||||
const UnitType *ut = bct->getBuilding(j);
|
||||
if(ut != NULL) {
|
||||
const Resource *r = ut->getCost(rt);
|
||||
if(r != NULL) {
|
||||
if (r != NULL && r->getAmount() < 0) {
|
||||
units.push_back(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -614,7 +616,7 @@ vector<int> Ai::findUnitsDoingCommand(CommandClass currentCommand) {
|
|||
|
||||
for(int i = 0; i < aiInterface->getMyUnitCount(); ++i) {
|
||||
const Unit *unit= aiInterface->getMyUnit(i);
|
||||
if(unit->getType()->hasCommandClass(currentCommand)) {
|
||||
if(unit->getType()->isCommandable() && unit->getType()->hasCommandClass(currentCommand)) {
|
||||
if(unit->anyCommand() && unit->getCurrCommand()->getCommandType()->getClass() == currentCommand) {
|
||||
units.push_back(i);
|
||||
}
|
||||
|
@ -630,7 +632,7 @@ bool Ai::findAbleUnit(int *unitIndex, CommandClass ability, CommandClass current
|
|||
*unitIndex= -1;
|
||||
for(int i=0; i<aiInterface->getMyUnitCount(); ++i){
|
||||
const Unit *unit= aiInterface->getMyUnit(i);
|
||||
if(unit->getType()->hasCommandClass(ability)){
|
||||
if(unit->getType()->isCommandable() && unit->getType()->hasCommandClass(ability)){
|
||||
if(unit->anyCommand() && unit->getCurrCommand()->getCommandType()->getClass()==currentCommand){
|
||||
units.push_back(i);
|
||||
}
|
||||
|
|
|
@ -103,21 +103,29 @@ void ChatManager::keyDown(SDL_KeyboardEvent key) {
|
|||
Config &configKeys = Config::getInstance(std::pair<ConfigType,ConfigType>(cfgMainKeys,cfgUserKeys));
|
||||
|
||||
//toggle team mode
|
||||
if(editEnabled == false && disableTeamMode == false &&
|
||||
if(editEnabled == false &&
|
||||
isKeyPressed(configKeys.getSDLKey("ChatTeamMode"),key) == true) {
|
||||
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] key = [%c] [%d]\n",__FILE__,__FUNCTION__,__LINE__,key.keysym.sym,key.keysym.sym);
|
||||
if(disableTeamMode == true) {
|
||||
if (!inMenu) {
|
||||
console->addLine(lang.getString("ChatModeDisabledToAvoidCheating") );
|
||||
}
|
||||
}
|
||||
else {
|
||||
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] key = [%c] [%d]\n",__FILE__,__FUNCTION__,__LINE__,key.keysym.sym,key.keysym.sym);
|
||||
|
||||
if (!inMenu) {
|
||||
if (teamMode == true) {
|
||||
teamMode = false;
|
||||
console->addLine(lang.getString("ChatMode") + ": " + lang.getString("All"));
|
||||
} else {
|
||||
teamMode = true;
|
||||
console->addLine(lang.getString("ChatMode") + ": " + lang.getString("Team"));
|
||||
if (!inMenu) {
|
||||
if (teamMode == true) {
|
||||
teamMode = false;
|
||||
console->addLine(lang.getString("ChatMode") + ": " + lang.getString("All"));
|
||||
} else {
|
||||
teamMode = true;
|
||||
console->addLine(lang.getString("ChatMode") + ": " + lang.getString("Team"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(isKeyPressed(SDLK_RETURN,key, false) == true) {
|
||||
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] key = [%c] [%d]\n",__FILE__,__FUNCTION__,__LINE__,key.keysym.sym,key.keysym.sym);
|
||||
|
||||
|
|
|
@ -5391,18 +5391,20 @@ string Game::getDebugStats(std::map<int,string> &factionDebugInfo) {
|
|||
for(int i = 0; i < world.getFactionCount(); ++i) {
|
||||
string factionInfo = this->gameSettings.getNetworkPlayerName(i);
|
||||
//factionInfo += " [" + this->gameSettings.getNetworkPlayerUUID(i) + "]";
|
||||
float multi=world.getStats()->getResourceMultiplier(i);
|
||||
string multiplier="["+floatToStr(multi,1)+"]";
|
||||
switch(this->gameSettings.getFactionControl(i)) {
|
||||
case ctCpuEasy:
|
||||
factionInfo += " CPU Easy";
|
||||
factionInfo += " CPU Easy"+multiplier;
|
||||
break;
|
||||
case ctCpu:
|
||||
factionInfo += " CPU Normal";
|
||||
factionInfo += " CPU Normal"+multiplier;
|
||||
break;
|
||||
case ctCpuUltra:
|
||||
factionInfo += " CPU Ultra";
|
||||
factionInfo += " CPU Ultra"+multiplier;
|
||||
break;
|
||||
case ctCpuMega:
|
||||
factionInfo += " CPU Mega";
|
||||
factionInfo += " CPU Mega"+multiplier;
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -1531,6 +1531,12 @@ int ScriptManager::getUnitFaction(int unitId) {
|
|||
const string ScriptManager::getUnitName(int unitId) {
|
||||
if(SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) SystemFlags::OutputDebug(SystemFlags::debugLUA,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
|
||||
|
||||
return world->findUnitById(unitId)->getType()->getName(false);
|
||||
}
|
||||
|
||||
const string ScriptManager::getUnitDisplayName(int unitId) {
|
||||
if(SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) SystemFlags::OutputDebug(SystemFlags::debugLUA,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
|
||||
|
||||
return world->getUnitName(unitId);
|
||||
}
|
||||
|
||||
|
@ -3414,6 +3420,7 @@ int ScriptManager::getUnitFaction(LuaHandle* luaHandle){
|
|||
|
||||
return luaArguments.getReturnCount();
|
||||
}
|
||||
|
||||
int ScriptManager::getUnitName(LuaHandle* luaHandle){
|
||||
LuaArguments luaArguments(luaHandle);
|
||||
try {
|
||||
|
@ -3435,6 +3442,28 @@ int ScriptManager::getUnitName(LuaHandle* luaHandle){
|
|||
return luaArguments.getReturnCount();
|
||||
}
|
||||
|
||||
int ScriptManager::getUnitDisplayName(LuaHandle* luaHandle){
|
||||
LuaArguments luaArguments(luaHandle);
|
||||
try {
|
||||
const string unitname = thisScriptManager->getUnitDisplayName(luaArguments.getInt(-1));
|
||||
luaArguments.returnString(unitname);
|
||||
}
|
||||
catch(const megaglest_runtime_error &ex) {
|
||||
char szErrBuf[8096]="";
|
||||
snprintf(szErrBuf,8096,"In [%s::%s %d]",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
|
||||
string sErrBuf = string(szErrBuf) + string("\nThe game may no longer be stable!\nerror [") + string(ex.what()) + string("]\n");
|
||||
|
||||
SystemFlags::OutputDebug(SystemFlags::debugError,sErrBuf.c_str());
|
||||
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,sErrBuf.c_str());
|
||||
|
||||
thisScriptManager->addMessageToQueue(ScriptManagerMessage(sErrBuf.c_str(), "error",-1,-1,true));
|
||||
thisScriptManager->onMessageBoxOk(false);
|
||||
}
|
||||
|
||||
return luaArguments.getReturnCount();
|
||||
}
|
||||
|
||||
|
||||
int ScriptManager::getResourceAmount(LuaHandle* luaHandle){
|
||||
LuaArguments luaArguments(luaHandle);
|
||||
try {
|
||||
|
|
|
@ -356,6 +356,7 @@ private:
|
|||
Vec2i getUnitPosition(int unitId);
|
||||
int getUnitFaction(int unitId);
|
||||
const string getUnitName(int unitId);
|
||||
const string getUnitDisplayName(int unitId);
|
||||
int getResourceAmount(const string &resourceName, int factionIndex);
|
||||
const string &getLastCreatedUnitName();
|
||||
int getLastCreatedUnitId();
|
||||
|
@ -521,6 +522,7 @@ private:
|
|||
static int getUnitPosition(LuaHandle* luaHandle);
|
||||
static int getUnitFaction(LuaHandle* luaHandle);
|
||||
static int getUnitName(LuaHandle* luaHandle);
|
||||
static int getUnitDisplayName(LuaHandle* luaHandle);
|
||||
static int getResourceAmount(LuaHandle* luaHandle);
|
||||
static int getLastCreatedUnitName(LuaHandle* luaHandle);
|
||||
static int getLastCreatedUnitId(LuaHandle* luaHandle);
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
//
|
||||
// Copyright (C) 2010-2010 Titus Tscharntke
|
||||
//
|
||||
// You can redistribute this code 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
|
||||
// You can redistribute this code 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
|
||||
// ==============================================================
|
||||
|
||||
|
@ -57,6 +57,8 @@ ParticleSystemType::ParticleSystemType() {
|
|||
size=0;
|
||||
sizeNoEnergy=0;
|
||||
speed=0;
|
||||
speedUpRelative=0;
|
||||
speedUpConstant=0;
|
||||
gravity=0;
|
||||
emissionRate=0;
|
||||
energyMax=0;
|
||||
|
@ -107,6 +109,8 @@ void ParticleSystemType::copyAll(const ParticleSystemType &src) {
|
|||
this->size = src.size;
|
||||
this->sizeNoEnergy = src.sizeNoEnergy;
|
||||
this->speed = src.speed;
|
||||
this->speedUpRelative = src.speedUpRelative;
|
||||
this->speedUpConstant = src.speedUpConstant;
|
||||
this->gravity = src.gravity;
|
||||
this->emissionRate = src.emissionRate;
|
||||
this->energyMax = src.energyMax;
|
||||
|
@ -160,7 +164,7 @@ void ParticleSystemType::load(const XmlNode *particleSystemNode, const string &d
|
|||
else {
|
||||
texture= NULL;
|
||||
}
|
||||
|
||||
|
||||
//model
|
||||
if(particleSystemNode->hasChild("model")){
|
||||
const XmlNode *modelNode= particleSystemNode->getChild("model");
|
||||
|
@ -172,7 +176,7 @@ void ParticleSystemType::load(const XmlNode *particleSystemNode, const string &d
|
|||
string path= modelNode->getAttribute("path")->getRestrictedValue(currentPath);
|
||||
model= renderer->newModel(rsGame,path, false, &loadedFileList, &parentLoader);
|
||||
loadedFileList[path].push_back(make_pair(parentLoader,modelNode->getAttribute("path")->getRestrictedValue()));
|
||||
|
||||
|
||||
if(modelNode->hasChild("cycles")) {
|
||||
modelCycle = modelNode->getChild("cycles")->getAttribute("value")->getFloatValue();
|
||||
if(modelCycle < 0.0)
|
||||
|
@ -220,6 +224,17 @@ void ParticleSystemType::load(const XmlNode *particleSystemNode, const string &d
|
|||
const XmlNode *speedNode= particleSystemNode->getChild("speed");
|
||||
speed= speedNode->getAttribute("value")->getFloatValue()/GameConstants::updateFps;
|
||||
|
||||
//speedUp
|
||||
if(particleSystemNode->hasChild("speedUp")){
|
||||
const XmlNode *speedUpNode= particleSystemNode->getChild("speedUp");
|
||||
if(speedUpNode->hasAttribute("relative")){
|
||||
speedUpRelative= speedUpNode->getAttribute("relative")->getFloatValue();
|
||||
}
|
||||
if(speedUpNode->hasAttribute("constant")){
|
||||
speedUpConstant= speedUpNode->getAttribute("constant")->getFloatValue();
|
||||
}
|
||||
}
|
||||
|
||||
//gravity
|
||||
const XmlNode *gravityNode= particleSystemNode->getChild("gravity");
|
||||
gravity= gravityNode->getAttribute("value")->getFloatValue()/GameConstants::updateFps;
|
||||
|
@ -235,7 +250,7 @@ void ParticleSystemType::load(const XmlNode *particleSystemNode, const string &d
|
|||
//speed
|
||||
const XmlNode *energyVarNode= particleSystemNode->getChild("energy-var");
|
||||
energyVar= energyVarNode->getAttribute("value")->getIntValue();
|
||||
|
||||
|
||||
//teamcolorNoEnergy
|
||||
if(particleSystemNode->hasChild("teamcolorNoEnergy")){
|
||||
const XmlNode *teamcolorNoEnergyNode= particleSystemNode->getChild("teamcolorNoEnergy");
|
||||
|
@ -300,6 +315,8 @@ void ParticleSystemType::setValues(AttackParticleSystem *ats){
|
|||
ats->setColor(color);
|
||||
ats->setColorNoEnergy(colorNoEnergy);
|
||||
ats->setSpeed(speed);
|
||||
ats->setSpeedUpRelative(speedUpRelative);
|
||||
ats->setSpeedUpConstant(speedUpConstant);
|
||||
ats->setGravity(gravity);
|
||||
ats->setParticleSize(size);
|
||||
ats->setSizeNoEnergy(sizeNoEnergy);
|
||||
|
@ -328,6 +345,8 @@ void ParticleSystemType::loadGame(const XmlNode *rootNode) {
|
|||
size = particleSystemTypeNode->getAttribute("size")->getFloatValue();
|
||||
sizeNoEnergy = particleSystemTypeNode->getAttribute("sizeNoEnergy")->getFloatValue();
|
||||
speed = particleSystemTypeNode->getAttribute("speed")->getFloatValue();
|
||||
speedUpRelative = particleSystemTypeNode->getAttribute("speedUpRelative")->getFloatValue();
|
||||
speedUpConstant = particleSystemTypeNode->getAttribute("speedUpConstant")->getFloatValue();
|
||||
gravity = particleSystemTypeNode->getAttribute("gravity")->getFloatValue();
|
||||
emissionRate = particleSystemTypeNode->getAttribute("emissionRate")->getFloatValue();
|
||||
energyMax = particleSystemTypeNode->getAttribute("energyMax")->getIntValue();
|
||||
|
@ -379,6 +398,10 @@ void ParticleSystemType::saveGame(XmlNode *rootNode) {
|
|||
particleSystemTypeNode->addAttribute("sizeNoEnergy",floatToStr(sizeNoEnergy,6), mapTagReplacements);
|
||||
// float speed;
|
||||
particleSystemTypeNode->addAttribute("speed",floatToStr(speed,6), mapTagReplacements);
|
||||
// float speedUpRelative;
|
||||
particleSystemTypeNode->addAttribute("speedUpRelative",floatToStr(speedUpRelative,6), mapTagReplacements);
|
||||
// float speedUpConstant;
|
||||
particleSystemTypeNode->addAttribute("speedUpConstant",floatToStr(speedUpConstant,6), mapTagReplacements);
|
||||
// float gravity;
|
||||
particleSystemTypeNode->addAttribute("gravity",floatToStr(gravity,6), mapTagReplacements);
|
||||
// float emissionRate;
|
||||
|
@ -441,7 +464,7 @@ void ParticleSystemTypeProjectile::load(const XmlNode* particleFileNode, const s
|
|||
particleFileNode->setSuper(particleSystemNode);
|
||||
particleSystemNode= particleFileNode;
|
||||
}
|
||||
|
||||
|
||||
ParticleSystemType::load(particleSystemNode, dir, renderer, loadedFileList,parentLoader, techtreePath);
|
||||
|
||||
//trajectory values
|
||||
|
@ -535,7 +558,7 @@ void ParticleSystemTypeSplash::load(const XmlNode* particleFileNode, const strin
|
|||
loadedFileList[path].push_back(make_pair(parentLoader,parentLoader));
|
||||
|
||||
const XmlNode *particleSystemNode= xmlTree.getRootNode();
|
||||
|
||||
|
||||
if(particleFileNode){
|
||||
// immediate children in the particleFileNode will override the particleSystemNode
|
||||
particleFileNode->setSuper(particleSystemNode);
|
||||
|
@ -547,7 +570,7 @@ void ParticleSystemTypeSplash::load(const XmlNode* particleFileNode, const strin
|
|||
//emission rate fade
|
||||
const XmlNode *emissionRateFadeNode= particleSystemNode->getChild("emission-rate-fade");
|
||||
emissionRateFade= emissionRateFadeNode->getAttribute("value")->getFloatValue();
|
||||
|
||||
|
||||
//spread values
|
||||
const XmlNode *verticalSpreadNode= particleSystemNode->getChild("vertical-spread");
|
||||
verticalSpreadA= verticalSpreadNode->getAttribute("a")->getFloatValue(0.0f, 1.0f);
|
||||
|
|
|
@ -65,6 +65,8 @@ protected:
|
|||
float size;
|
||||
float sizeNoEnergy;
|
||||
float speed;
|
||||
float speedUpRelative;
|
||||
float speedUpConstant;
|
||||
float gravity;
|
||||
float emissionRate;
|
||||
int energyMax;
|
||||
|
|
|
@ -233,6 +233,8 @@ const void UnitParticleSystemType::setValues(UnitParticleSystem *ups){
|
|||
ups->setColor(color);
|
||||
ups->setColorNoEnergy(colorNoEnergy);
|
||||
ups->setSpeed(speed);
|
||||
ups->setSpeedUpRelative(speedUpRelative);
|
||||
ups->setSpeedUpConstant(speedUpConstant);
|
||||
ups->setGravity(gravity);
|
||||
ups->setParticleSize(size);
|
||||
ups->setSizeNoEnergy(sizeNoEnergy);
|
||||
|
|
|
@ -71,6 +71,11 @@ bool Selection::select(Unit *unit) {
|
|||
return false;
|
||||
}
|
||||
|
||||
//check if commandable
|
||||
if(unit->getType()->isCommandable() == false && isEmpty() == false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//check if multisel
|
||||
if(unit->getType()->getMultiSelect() == false && isEmpty() == false) {
|
||||
return false;
|
||||
|
@ -181,7 +186,8 @@ bool Selection::isCommandable() const {
|
|||
return
|
||||
isEmpty() == false &&
|
||||
isEnemy() == false &&
|
||||
(selectedUnits.size() == 1 && selectedUnits.front()->isAlive() == false) == false;
|
||||
(selectedUnits.size() == 1 && selectedUnits.front()->isAlive() == false) == false &&
|
||||
selectedUnits.front()->getType()->isCommandable();
|
||||
}
|
||||
|
||||
bool Selection::isCancelable() const {
|
||||
|
|
|
@ -101,6 +101,14 @@ using namespace Shared::Graphics::Gl;
|
|||
using namespace Shared::Xml;
|
||||
using namespace Shared;
|
||||
|
||||
/**
|
||||
* @namespace Glest
|
||||
* Namespace used for all %Glest related code.
|
||||
*/
|
||||
/**
|
||||
* @namespace Game
|
||||
* Namespace used for game related code.
|
||||
*/
|
||||
namespace Glest { namespace Game {
|
||||
|
||||
static string tempDataLocation = getUserHome();
|
||||
|
|
|
@ -1209,7 +1209,7 @@ void Faction::applyCostsOnInterval(const ResourceType *rtApply) {
|
|||
world->getStats()->die(unit->getFactionIndex(),unit->getType()->getCountUnitDeathInStats());
|
||||
scriptManager->onUnitDied(unit);
|
||||
}
|
||||
StaticSound *sound= unit->getType()->getFirstStOfClass(scDie)->getSound();
|
||||
StaticSound *sound= static_cast<const DieSkillType *>(unit->getType()->getFirstStOfClass(scDie))->getSound();
|
||||
if(sound != NULL &&
|
||||
(thisFaction == true || world->showWorldForPlayer(world->getThisTeamIndex()) == true)) {
|
||||
SoundRenderer::getInstance().playFx(sound);
|
||||
|
|
|
@ -666,27 +666,7 @@ Unit::~Unit() {
|
|||
}
|
||||
safeMutex.ReleaseLock();
|
||||
|
||||
// If the unit is not visible we better make sure we cleanup associated particles
|
||||
if(this->getVisible() == false) {
|
||||
Renderer::getInstance().cleanupUnitParticleSystems(unitParticleSystems,rsGame);
|
||||
|
||||
Renderer::getInstance().cleanupParticleSystems(fireParticleSystems,rsGame);
|
||||
// Must set this to null of it will be used below in stopDamageParticles()
|
||||
|
||||
if(Renderer::getInstance().validateParticleSystemStillExists(this->fire,rsGame) == false) {
|
||||
this->fire = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// fade(and by this remove) all unit particle systems
|
||||
queuedUnitParticleSystemTypes.clear();
|
||||
while(unitParticleSystems.empty() == false) {
|
||||
if(Renderer::getInstance().validateParticleSystemStillExists(unitParticleSystems.back(),rsGame) == true) {
|
||||
unitParticleSystems.back()->fade();
|
||||
}
|
||||
unitParticleSystems.pop_back();
|
||||
}
|
||||
stopDamageParticles(true);
|
||||
cleanupAllParticlesystems();
|
||||
|
||||
while(currentAttackBoostEffects.empty() == false) {
|
||||
//UnitAttackBoostEffect &effect = currentAttackBoostEffects.back();
|
||||
|
@ -726,6 +706,29 @@ Unit::~Unit() {
|
|||
#endif
|
||||
}
|
||||
|
||||
void Unit::cleanupAllParticlesystems() {
|
||||
|
||||
Renderer::getInstance().cleanupUnitParticleSystems(unitParticleSystems,rsGame);
|
||||
|
||||
Renderer::getInstance().cleanupParticleSystems(fireParticleSystems,rsGame);
|
||||
// Must set this to null of it will be used below in stopDamageParticles()
|
||||
|
||||
if(Renderer::getInstance().validateParticleSystemStillExists(this->fire,rsGame) == false) {
|
||||
this->fire = NULL;
|
||||
}
|
||||
|
||||
// fade(and by this remove) all unit particle systems
|
||||
queuedUnitParticleSystemTypes.clear();
|
||||
while(unitParticleSystems.empty() == false) {
|
||||
if(Renderer::getInstance().validateParticleSystemStillExists(unitParticleSystems.back(),rsGame) == true) {
|
||||
unitParticleSystems.back()->fade();
|
||||
}
|
||||
unitParticleSystems.pop_back();
|
||||
}
|
||||
stopDamageParticles(true);
|
||||
|
||||
}
|
||||
|
||||
ParticleSystem * Unit::getFire() const {
|
||||
if(this->fire != NULL &&
|
||||
Renderer::getInstance().validateParticleSystemStillExists(this->fire,rsGame) == false) {
|
||||
|
@ -1951,13 +1954,32 @@ void Unit::born(const CommandType *ct) {
|
|||
|
||||
checkItemInVault(&this->hp,this->hp);
|
||||
int original_hp = this->hp;
|
||||
this->hp= type->getMaxHp();
|
||||
|
||||
|
||||
//set hp from start hp
|
||||
checkItemInVault(&this->ep,this->ep);
|
||||
if(type->getStartHpType() == UnitType::stValue) {
|
||||
this->hp= type->getStartHpValue();
|
||||
}
|
||||
else {
|
||||
this->hp= type->getTotalMaxHp(&totalUpgrade) * 100 / type->getStartHpPercentage();
|
||||
}
|
||||
|
||||
if(original_hp != this->hp) {
|
||||
//printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__);
|
||||
game->getScriptManager()->onUnitTriggerEvent(this,utet_HPChanged);
|
||||
//printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__);
|
||||
}
|
||||
addItemToVault(&this->hp,this->hp);
|
||||
|
||||
//set ep from start ep
|
||||
checkItemInVault(&this->ep,this->ep);
|
||||
if(type->getStartEpType() == UnitType::stValue) {
|
||||
this->ep= type->getStartEpValue();
|
||||
}
|
||||
else {
|
||||
this->ep= type->getTotalMaxEp(&totalUpgrade) * 100 / type->getStartEpPercentage();
|
||||
}
|
||||
}
|
||||
|
||||
void Unit::kill() {
|
||||
|
@ -2611,7 +2633,15 @@ bool Unit::update() {
|
|||
int64 heightFactor = getHeightFactor(ANIMATION_SPEED_MULTIPLIER);
|
||||
int64 speedDenominator = speedDivider *
|
||||
game->getWorld()->getUpdateFps(this->getFactionIndex());
|
||||
int64 progressIncrease = (currSkill->getAnimSpeed() * heightFactor) / speedDenominator;
|
||||
|
||||
// Override the animation speed for attacks that have upgraded the attack speed
|
||||
int animSpeed = currSkill->getAnimSpeed();
|
||||
if(currSkill->getClass() == scAttack) {
|
||||
int animSpeedBoost = ((AttackSkillType *) currSkill)->getAnimSpeedBoost(&totalUpgrade);
|
||||
animSpeed += animSpeedBoost;
|
||||
}
|
||||
|
||||
int64 progressIncrease = (animSpeed * heightFactor) / speedDenominator;
|
||||
// Ensure we increment at least a value of 1 of the action will be stuck infinitely
|
||||
if(currSkill->getAnimSpeed() > 0 && heightFactor > 0 && progressIncrease == 0) {
|
||||
progressIncrease = 1;
|
||||
|
@ -2933,7 +2963,7 @@ bool Unit::applyAttackBoost(const AttackBoost *boost, const Unit *source) {
|
|||
Unit::game->getWorld()->getStats()->die(getFactionIndex(),getType()->getCountUnitDeathInStats());
|
||||
game->getScriptManager()->onUnitDied(this);
|
||||
|
||||
StaticSound *sound= this->getType()->getFirstStOfClass(scDie)->getSound();
|
||||
StaticSound *sound= static_cast<const DieSkillType *>(this->getType()->getFirstStOfClass(scDie))->getSound();
|
||||
if(sound != NULL &&
|
||||
(this->getFactionIndex() == Unit::game->getWorld()->getThisFactionIndex() ||
|
||||
(game->getWorld()->showWorldForPlayer(game->getWorld()->getThisTeamIndex()) == true))) {
|
||||
|
@ -3031,7 +3061,7 @@ void Unit::deapplyAttackBoost(const AttackBoost *boost, const Unit *source) {
|
|||
Unit::game->getWorld()->getStats()->die(getFactionIndex(),getType()->getCountUnitDeathInStats());
|
||||
game->getScriptManager()->onUnitDied(this);
|
||||
|
||||
StaticSound *sound= this->getType()->getFirstStOfClass(scDie)->getSound();
|
||||
StaticSound *sound= static_cast<const DieSkillType *>(this->getType()->getFirstStOfClass(scDie))->getSound();
|
||||
if(sound != NULL &&
|
||||
(this->getFactionIndex() == Unit::game->getWorld()->getThisFactionIndex() ||
|
||||
(game->getWorld()->showWorldForPlayer(game->getWorld()->getThisTeamIndex()) == true))) {
|
||||
|
@ -3103,7 +3133,7 @@ void Unit::tick() {
|
|||
Unit::game->getWorld()->getStats()->die(getFactionIndex(),getType()->getCountUnitDeathInStats());
|
||||
game->getScriptManager()->onUnitDied(this);
|
||||
}
|
||||
StaticSound *sound= this->getType()->getFirstStOfClass(scDie)->getSound();
|
||||
StaticSound *sound= static_cast<const DieSkillType *>(this->getType()->getFirstStOfClass(scDie))->getSound();
|
||||
if(sound != NULL &&
|
||||
(this->getFactionIndex() == Unit::game->getWorld()->getThisFactionIndex() ||
|
||||
(game->getWorld()->showWorldForPlayer(game->getWorld()->getThisTeamIndex()) == true))) {
|
||||
|
@ -3142,7 +3172,7 @@ void Unit::tick() {
|
|||
Unit::game->getWorld()->getStats()->die(getFactionIndex(),getType()->getCountUnitDeathInStats());
|
||||
game->getScriptManager()->onUnitDied(this);
|
||||
}
|
||||
StaticSound *sound= this->getType()->getFirstStOfClass(scDie)->getSound();
|
||||
StaticSound *sound= static_cast<const DieSkillType *>(this->getType()->getFirstStOfClass(scDie))->getSound();
|
||||
if(sound != NULL &&
|
||||
(this->getFactionIndex() == Unit::game->getWorld()->getThisFactionIndex() ||
|
||||
(game->getWorld()->showWorldForPlayer(game->getWorld()->getThisTeamIndex()) == true))) {
|
||||
|
@ -3553,6 +3583,8 @@ bool Unit::morph(const MorphCommandType *mct) {
|
|||
}
|
||||
}
|
||||
|
||||
//stopDamageParticles(true);
|
||||
cleanupAllParticlesystems();
|
||||
|
||||
checkItemInVault(&this->hp,this->hp);
|
||||
int original_hp = this->hp;
|
||||
|
|
|
@ -806,6 +806,7 @@ public:
|
|||
|
||||
private:
|
||||
|
||||
void cleanupAllParticlesystems();
|
||||
bool isNetworkCRCEnabled();
|
||||
string getNetworkCRCDecHpList() const;
|
||||
string getParticleInfo() const;
|
||||
|
|
|
@ -9,6 +9,13 @@
|
|||
// License, or (at your option) any later version
|
||||
// ==============================================================
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains the Upgrade and UpgradeManager classes. This is what the factions need to manage
|
||||
* upgrades (including starting, canceling, and finishing upgrades, figuring out which
|
||||
* upgrades we have done, etc).
|
||||
*/
|
||||
|
||||
#ifndef _GLEST_GAME_UPGRADE_H_
|
||||
#define _GLEST_GAME_UPGRADE_H_
|
||||
|
||||
|
@ -33,25 +40,32 @@ class Unit;
|
|||
class UpgradeType;
|
||||
class Faction;
|
||||
|
||||
/**
|
||||
* Stores the state of the upgrade (whether or not the upgrading process is complete).
|
||||
*/
|
||||
// TODO: Don't make this global; move it inside Upgrade
|
||||
enum UpgradeState {
|
||||
usUpgrading,
|
||||
usUpgraded,
|
||||
usUpgrading, /**< The upgrade is currently in progress. */
|
||||
usUpgraded, /**< The upgrade is completed. */
|
||||
|
||||
upgradeStateCount
|
||||
upgradeStateCount // TODO: This should be unnecessary -- there's no need to iterate over this enum
|
||||
};
|
||||
|
||||
class UpgradeManager;
|
||||
class TotalUpgrade;
|
||||
|
||||
// =====================================================
|
||||
// class Upgrade
|
||||
//
|
||||
/// A bonus to an UnitType
|
||||
// =====================================================
|
||||
|
||||
/**
|
||||
* An instance of an upgrade. Factions will typically have one upgrade of each type. This object
|
||||
* groups the type, faction, and upgrade state (ie, has the upgrade been obtained yet?).
|
||||
*/
|
||||
class Upgrade {
|
||||
private:
|
||||
UpgradeState state;
|
||||
// TODO: I believe this is unnecessary. As far as I can tell, it's only used for checking
|
||||
// that the unit we're applying UpgradeManager::computeTotalUpgrade to is in this faction. However,
|
||||
// I don't see an circumstances when it wouldn't be (since the UpgradeManager already an aggregate
|
||||
// of a faction and Unit directly gets the UpgradeManager from the faction (so it must have the
|
||||
// same faction as the upgrades in the UpgradeManager).
|
||||
int factionIndex;
|
||||
const UpgradeType *type;
|
||||
|
||||
|
@ -59,50 +73,136 @@ private:
|
|||
|
||||
Upgrade();
|
||||
public:
|
||||
/**
|
||||
* Creates an upgrade. The upgrade state will be set to UpgradeState::usUpgrading.
|
||||
* @param upgradeType The type of the upgrade that this corresponds to. Upgrade types are
|
||||
* essentially "classes" for upgrades.
|
||||
* @param factionIndex The index of the faction that the upgrade belongs to.
|
||||
*/
|
||||
Upgrade(const UpgradeType *upgradeType, int factionIndex);
|
||||
|
||||
private:
|
||||
//get
|
||||
UpgradeState getState() const;
|
||||
int getFactionIndex() const;
|
||||
const UpgradeType * getType() const;
|
||||
|
||||
//set
|
||||
void setState(UpgradeState state);
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves a string representation of the upgrade (detailing its state, type, and faction).
|
||||
*/
|
||||
std::string toString() const;
|
||||
|
||||
|
||||
/**
|
||||
* Saves the object state into the given node.
|
||||
* @param rootNode The UpgradeManager node to save object info to.
|
||||
*/
|
||||
void saveGame(XmlNode *rootNode);
|
||||
|
||||
/**
|
||||
* Loads the object state from the given node.
|
||||
* @param rootNode The UpgradeManager node to retrieve object info from.
|
||||
* @param faction The faction that the upgrade belongs to. Used to convert the upgrade type from
|
||||
* the XML string.
|
||||
*/
|
||||
static Upgrade * loadGame(const XmlNode *rootNode,Faction *faction);
|
||||
};
|
||||
|
||||
|
||||
// ===============================
|
||||
// class UpgradeManager
|
||||
// ===============================
|
||||
|
||||
/**
|
||||
* Manages upgrades by starting, stopping, and finishing upgrades. Each faction has their own
|
||||
* upgrade manager.
|
||||
*/
|
||||
class UpgradeManager{
|
||||
private:
|
||||
private:
|
||||
typedef vector<Upgrade*> Upgrades;
|
||||
typedef map<const UpgradeType *,int> UgradesLookup;
|
||||
|
||||
/**
|
||||
* List of upgrades that the upgrade manager is working with (either in progress or finished).
|
||||
*/
|
||||
Upgrades upgrades;
|
||||
|
||||
/**
|
||||
* Maps UpgradeType to the index of the upgrade in UpgradeManager::upgrades.
|
||||
*/
|
||||
UgradesLookup upgradesLookup;
|
||||
public:
|
||||
~UpgradeManager();
|
||||
|
||||
int getUpgradeCount() const {return (int)upgrades.size();}
|
||||
|
||||
|
||||
/**
|
||||
* Starts an upgrade.
|
||||
* @param upgradeType The type of the upgrade to start.
|
||||
* @param factionIndex Passed to the constructor of the Upgrade.
|
||||
*/
|
||||
void startUpgrade(const UpgradeType *upgradeType, int factionIndex);
|
||||
|
||||
/**
|
||||
* Cancels an upgrade before it is finished. The upgrade is removed from the UpgradeManager.
|
||||
* @param upgradeType The type of the upgrade to remove.
|
||||
* @throws megaglest_runtime_error If there is no upgrade of the desired type in the UpgradeManager.
|
||||
*/
|
||||
void cancelUpgrade(const UpgradeType *upgradeType);
|
||||
|
||||
/**
|
||||
* Sets an Upgrade in the UpgradeManager as finished (ie, the state is UpgradeState::usUpgraded).
|
||||
* @param upgradeType The type of the upgrade to complete.
|
||||
* @throws megaglest_runtime_error If there is no upgrade of the desired type in the UpgradeManager.
|
||||
*/
|
||||
void finishUpgrade(const UpgradeType *upgradeType);
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if an Upgrade of the desired type has state UpgradeState::usUpgraded (ie, is
|
||||
* finished upgrading).
|
||||
* @param upgradeType The type of the upgrade in question.
|
||||
*/
|
||||
bool isUpgraded(const UpgradeType *upgradeType) const;
|
||||
bool isUpgrading(const UpgradeType *upgradeType) const;
|
||||
bool isUpgradingOrUpgraded(const UpgradeType *upgradeType) const;
|
||||
void computeTotalUpgrade(const Unit *unit, TotalUpgrade *totalUpgrade) const;
|
||||
|
||||
/**
|
||||
* Returns true if an Upgrade of the desired type has state UpgradeState::usUpgrading (ie, is
|
||||
* currently in progress).
|
||||
* @param upgradeType The type of the upgrade in question.
|
||||
*/
|
||||
bool isUpgrading(const UpgradeType *upgradeType) const;
|
||||
|
||||
/**
|
||||
* Returns true if an Upgrade of the desired type exists in the UpgradeManager.
|
||||
* @param upgradeType The type of the upgrade in question.
|
||||
*/
|
||||
bool isUpgradingOrUpgraded(const UpgradeType *upgradeType) const;
|
||||
|
||||
/**
|
||||
* [Sums up](@ref TotalUpgrade::sum) the effect of all upgrades for this faction as they apply
|
||||
* to a particular unit.
|
||||
* @param unit The unit that the TotalUpgrade applies to. This is necessary because some
|
||||
* upgrades provide percentage boosts.
|
||||
* @param totalUpgrade The TotalUpgrade object to modify. Note that it is cleared before values
|
||||
* are calculated.
|
||||
*/
|
||||
void computeTotalUpgrade(const Unit *unit, TotalUpgrade *totalUpgrade) const;
|
||||
|
||||
/**
|
||||
* Retrieves a string representation of the UpgradeManager. Contains the contents of
|
||||
* Upgrade::toString for all upgrades in the UpgradeManager.
|
||||
*/
|
||||
std::string toString() const;
|
||||
|
||||
/**
|
||||
* Adds a node for the UpgradeManager that contains all the upgrade nodes, saving the object's
|
||||
* state.
|
||||
* @param rootNode The faction node to add the UpgradeManager node to.
|
||||
* @see Upgrade::saveGame
|
||||
*/
|
||||
void saveGame(XmlNode *rootNode);
|
||||
|
||||
/**
|
||||
* Loads all the upgrades from the UpgradeManager node, effectively reloading the object's
|
||||
* state.
|
||||
* @param rootNode The faction node to get the UpgradeManager node from.
|
||||
* @param faction Only passed to Upgrade::loadGame (which does the actual loading of each
|
||||
* Upgrade object.
|
||||
*/
|
||||
void loadGame(const XmlNode *rootNode,Faction *faction);
|
||||
};
|
||||
|
||||
|
|
|
@ -288,7 +288,13 @@ string AttackCommandType::getDesc(const TotalUpgrade *totalUpgrade, bool transla
|
|||
}
|
||||
str+="\n";
|
||||
|
||||
//attack speed
|
||||
str+= lang.getString("AttackSpeed",(translatedValue == true ? "" : "english"))+": "+ intToStr(attackSkillType->getSpeed()) +"\n";
|
||||
if(totalUpgrade->getAttackSpeed(attackSkillType) != 0) {
|
||||
str+= "+"+intToStr(totalUpgrade->getAttackSpeed(attackSkillType));
|
||||
}
|
||||
str+="\n";
|
||||
|
||||
str+=attackSkillType->getBoostDesc(translatedValue);
|
||||
return str;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,126 @@
|
|||
// ==============================================================
|
||||
// This file is part of Glest (www.glest.org)
|
||||
//
|
||||
// Copyright (C) 2001-2008 Martiño Figueroa
|
||||
//
|
||||
// You can redistribute this code 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
|
||||
// ==============================================================
|
||||
|
||||
#include <cassert>
|
||||
#include "logger.h"
|
||||
#include "lang.h"
|
||||
#include "renderer.h"
|
||||
#include "leak_dumper.h"
|
||||
|
||||
using namespace Shared::Util;
|
||||
|
||||
namespace Glest{ namespace Game{
|
||||
|
||||
ProjectileType::ProjectileType() {
|
||||
|
||||
projectileParticleSystemType=NULL;
|
||||
attackStartTime=0.0f;
|
||||
|
||||
spawnUnit="";
|
||||
spawnUnitcount=0;
|
||||
spawnUnitAtTarget=false;
|
||||
|
||||
shake=false;
|
||||
shakeIntensity=0;
|
||||
shakeDuration=0;
|
||||
|
||||
shakeVisible=true;
|
||||
shakeInCameraView=true;
|
||||
shakeCameraDistanceAffected=false;
|
||||
damagePercentage=100;
|
||||
}
|
||||
|
||||
ProjectileType::~ProjectileType() {
|
||||
deleteValues(hitSounds.getSounds().begin(), hitSounds.getSounds().end());
|
||||
if(projectileParticleSystemType!=NULL){
|
||||
delete projectileParticleSystemType;
|
||||
projectileParticleSystemType = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void ProjectileType::load(const XmlNode *projectileNode, const string &dir, const string &techtreepath, std::map<string,vector<pair<string, string> > > &loadedFileList,
|
||||
string parentLoader){
|
||||
|
||||
string currentPath = dir;
|
||||
endPathWithSlash(currentPath);
|
||||
|
||||
if(projectileNode->hasAttribute("attack-start-time")){
|
||||
attackStartTime =projectileNode->getAttribute("attack-start-time")->getFloatValue();
|
||||
}
|
||||
else
|
||||
{
|
||||
attackStartTime=0.0f;
|
||||
}
|
||||
|
||||
// damage percentage MUST be set!
|
||||
damagePercentage =projectileNode->getAttribute("damage-percentage")->getIntValue();
|
||||
|
||||
|
||||
// projectiles MUST have a particle system.
|
||||
const XmlNode *particleNode= projectileNode->getChild("particle");
|
||||
string path= particleNode->getAttribute("path")->getRestrictedValue();
|
||||
ParticleSystemTypeProjectile* projectileParticleSystemType= new ParticleSystemTypeProjectile();
|
||||
projectileParticleSystemType->load(particleNode, dir, currentPath + path,
|
||||
&Renderer::getInstance(), loadedFileList, parentLoader,
|
||||
techtreepath);
|
||||
loadedFileList[currentPath + path].push_back(make_pair(parentLoader,particleNode->getAttribute("path")->getRestrictedValue()));
|
||||
setProjectileParticleSystemType(projectileParticleSystemType);
|
||||
|
||||
//spawnattack
|
||||
if (projectileNode->hasChild("unit")) {
|
||||
spawnUnit = projectileNode->getChild("unit")->getAttribute("value")->getValue();
|
||||
spawnUnitcount = projectileNode->getChild("unit")->getAttribute("amount")->getIntValue();
|
||||
if(projectileNode->getChild("unit")->hasAttribute("spawnAtTarget")) {
|
||||
spawnUnitAtTarget = projectileNode->getChild("unit")->getAttribute("spawnAtTarget")->getBoolValue();
|
||||
} else {
|
||||
spawnUnitAtTarget = false;
|
||||
}
|
||||
} else {
|
||||
spawnUnit = "";
|
||||
spawnUnitcount = 0;
|
||||
spawnUnitAtTarget = false;
|
||||
}
|
||||
|
||||
|
||||
if(projectileNode->hasChild("hitshake")){
|
||||
const XmlNode *hitShakeNode= projectileNode->getChild("hitshake");
|
||||
shake=hitShakeNode->getAttribute("enabled")->getBoolValue();
|
||||
if(shake){
|
||||
shakeIntensity=hitShakeNode->getAttribute("intensity")->getIntValue();
|
||||
shakeDuration=hitShakeNode->getAttribute("duration")->getIntValue();
|
||||
|
||||
shakeVisible=hitShakeNode->getAttribute("visible")->getBoolValue();
|
||||
shakeInCameraView=hitShakeNode->getAttribute("in-camera-view")->getBoolValue();
|
||||
shakeCameraDistanceAffected=hitShakeNode->getAttribute("camera-distance-affected")->getBoolValue();
|
||||
}
|
||||
}
|
||||
|
||||
if(projectileNode->hasChild("hitsound")){
|
||||
const XmlNode *soundNode= projectileNode->getChild("hitsound");
|
||||
if(soundNode->getAttribute("enabled")->getBoolValue()){
|
||||
|
||||
hitSounds.resize((int)soundNode->getChildCount());
|
||||
for(int i=0; i < (int)soundNode->getChildCount(); ++i){
|
||||
const XmlNode *soundFileNode= soundNode->getChild("sound-file", i);
|
||||
string path= soundFileNode->getAttribute("path")->getRestrictedValue(currentPath, true);
|
||||
//printf("\n\n\n\n!@#$ ---> parentLoader [%s] path [%s] nodeValue [%s] i = %d",parentLoader.c_str(),path.c_str(),soundFileNode->getAttribute("path")->getRestrictedValue().c_str(),i);
|
||||
|
||||
StaticSound *sound= new StaticSound();
|
||||
sound->load(path);
|
||||
loadedFileList[path].push_back(make_pair(parentLoader,soundFileNode->getAttribute("path")->getRestrictedValue()));
|
||||
hitSounds[i]= sound;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}}//end namespace
|
|
@ -0,0 +1,90 @@
|
|||
// ==============================================================
|
||||
// This file is part of Glest (www.glest.org)
|
||||
//
|
||||
// Copyright (C) 2001-2008 Martiño Figueroa
|
||||
//
|
||||
// You can redistribute this code 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
|
||||
// ==============================================================
|
||||
|
||||
#ifndef _GLEST_GAME_PROJEKTILETYPE_H_
|
||||
#define _GLEST_GAME_PROJEKTILETYPE_H_
|
||||
|
||||
#ifdef WIN32
|
||||
#include <winsock2.h>
|
||||
#include <winsock.h>
|
||||
#endif
|
||||
|
||||
#include "sound.h"
|
||||
#include "vec.h"
|
||||
//#include "xml_parser.h"
|
||||
#include "util.h"
|
||||
//#include "element_type.h"
|
||||
#include "factory.h"
|
||||
#include "sound_container.h"
|
||||
#include "particle_type.h"
|
||||
#include "leak_dumper.h"
|
||||
|
||||
using std::vector;
|
||||
using std::string;
|
||||
|
||||
namespace Glest{ namespace Game{
|
||||
// =====================================================
|
||||
// class ProjectileType
|
||||
// =====================================================
|
||||
|
||||
class ProjectileType {
|
||||
protected:
|
||||
ParticleSystemTypeProjectile* projectileParticleSystemType;
|
||||
SoundContainer hitSounds;
|
||||
float attackStartTime;
|
||||
|
||||
string spawnUnit;
|
||||
int spawnUnitcount;
|
||||
bool spawnUnitAtTarget;
|
||||
|
||||
bool shake;
|
||||
int shakeIntensity;
|
||||
int shakeDuration;
|
||||
|
||||
bool shakeVisible;
|
||||
bool shakeInCameraView;
|
||||
bool shakeCameraDistanceAffected;
|
||||
int damagePercentage;
|
||||
|
||||
public:
|
||||
ProjectileType();
|
||||
virtual ~ProjectileType();
|
||||
|
||||
|
||||
void load(const XmlNode *projectileNode, const string &dir, const string &techtreepath, std::map<string,vector<pair<string, string> > > &loadedFileList,
|
||||
string parentLoader);
|
||||
|
||||
//get/set
|
||||
inline StaticSound *getHitSound() const {return hitSounds.getRandSound();}
|
||||
ParticleSystemTypeProjectile* getProjectileParticleSystemType() const { return projectileParticleSystemType;}
|
||||
float getAttackStartTime() const {return attackStartTime;}
|
||||
void setAttackStartTime(float value) {attackStartTime=value;}
|
||||
|
||||
string getSpawnUnit() const{return spawnUnit;}
|
||||
int getSpawnUnitcount() const{return spawnUnitcount;}
|
||||
bool getSpawnUnitAtTarget() const{return spawnUnitAtTarget;}
|
||||
|
||||
bool isShake() const{return shake;}
|
||||
bool isShakeCameraDistanceAffected() const{return shakeCameraDistanceAffected;}
|
||||
int getShakeDuration() const{return shakeDuration;}
|
||||
bool isShakeInCameraView() const{return shakeInCameraView;}
|
||||
int getShakeIntensity() const{return shakeIntensity;}
|
||||
bool isShakeVisible() const{return shakeVisible;}
|
||||
int getDamagePercentage() const {return damagePercentage;}
|
||||
void setDamagePercentage(int value) {damagePercentage=value;}
|
||||
|
||||
void setProjectileParticleSystemType(ParticleSystemTypeProjectile *pointer) {projectileParticleSystemType=pointer;}
|
||||
ParticleSystemTypeProjectile* getProjectileParticleSystemType() {return projectileParticleSystemType;}
|
||||
};
|
||||
|
||||
}}//end namespace
|
||||
|
||||
#endif
|
|
@ -19,6 +19,7 @@
|
|||
#include "renderer.h"
|
||||
#include "particle_type.h"
|
||||
#include "unit_particle_type.h"
|
||||
#include "projectile_type.h"
|
||||
#include "tech_tree.h"
|
||||
#include "faction_type.h"
|
||||
#include "leak_dumper.h"
|
||||
|
@ -273,12 +274,27 @@ void AttackBoost::saveGame(XmlNode *rootNode) const {
|
|||
attackBoostNode->addAttribute("name",name, mapTagReplacements);
|
||||
}
|
||||
|
||||
// =====================================================
|
||||
// class SkillSound
|
||||
// =====================================================
|
||||
SkillSound::SkillSound(){
|
||||
startTime=0.0f;
|
||||
}
|
||||
SkillSound::~SkillSound()
|
||||
{
|
||||
deleteValues(soundContainer.getSounds().begin(), soundContainer.getSounds().end());
|
||||
startTime=0.0f;
|
||||
//soundContainer
|
||||
}
|
||||
// =====================================================
|
||||
// class SkillType
|
||||
// =====================================================
|
||||
|
||||
SkillType::~SkillType() {
|
||||
deleteValues(sounds.getSounds().begin(), sounds.getSounds().end());
|
||||
while(!skillSoundList.empty()) {
|
||||
delete skillSoundList.back();
|
||||
skillSoundList.pop_back();
|
||||
}
|
||||
//remove unitParticleSystemTypes
|
||||
while(!unitParticleSystemTypes.empty()) {
|
||||
delete unitParticleSystemTypes.back();
|
||||
|
@ -488,11 +504,18 @@ void SkillType::load(const XmlNode *sn, const XmlNode *attackBoostsNode,
|
|||
unitParticleSystemType->load(particleFileNode, dir, currentPath + path, &Renderer::getInstance(),
|
||||
loadedFileList,parentLoader,tt->getPath());
|
||||
|
||||
if(particleNode->getAttribute("start-time",false) != NULL) {
|
||||
if (particleNode->getChild(i)->hasAttribute("start-time")) {
|
||||
//printf("*NOTE particle system type has start-time [%f]\n",particleNode->getAttribute("start-time")->getFloatValue());
|
||||
unitParticleSystemType->setStartTime(particleNode->getChild(i)->getAttribute("start-time")->getFloatValue());
|
||||
} else if (particleNode->hasAttribute("start-time")) {
|
||||
//printf("*NOTE particle system type has start-time [%f]\n",particleNode->getAttribute("start-time")->getFloatValue());
|
||||
unitParticleSystemType->setStartTime(particleNode->getAttribute("start-time")->getFloatValue());
|
||||
}
|
||||
if(particleNode->getAttribute("end-time",false) != NULL) {
|
||||
|
||||
if (particleNode->getChild(i)->hasAttribute("end-time")) {
|
||||
//printf("*NOTE particle system type has start-time [%f]\n",particleNode->getAttribute("start-time")->getFloatValue());
|
||||
unitParticleSystemType->setEndTime(particleNode->getChild(i)->getAttribute("end-time")->getFloatValue());
|
||||
} else if (particleNode->hasAttribute("end-time")) {
|
||||
//printf("*NOTE particle system type has end-time [%f]\n",particleNode->getAttribute("end-time")->getFloatValue());
|
||||
unitParticleSystemType->setEndTime(particleNode->getAttribute("end-time")->getFloatValue());
|
||||
}
|
||||
|
@ -504,11 +527,16 @@ void SkillType::load(const XmlNode *sn, const XmlNode *attackBoostsNode,
|
|||
}
|
||||
|
||||
//sound
|
||||
if(sn->hasChild("sound")) {
|
||||
const XmlNode *soundNode= sn->getChild("sound");
|
||||
vector<XmlNode *> soundNodeList = sn->getChildList("sound");
|
||||
for(unsigned int i = 0; i < soundNodeList.size(); ++i) {
|
||||
const XmlNode *soundNode= soundNodeList[i];
|
||||
if(soundNode->getAttribute("enabled")->getBoolValue()) {
|
||||
soundStartTime= soundNode->getAttribute("start-time")->getFloatValue();
|
||||
sounds.resize((int)soundNode->getChildCount());
|
||||
float soundStartTime= soundNode->getAttribute("start-time")->getFloatValue();
|
||||
SkillSound *skillSound = new SkillSound();
|
||||
skillSound->setStartTime(soundStartTime);
|
||||
|
||||
skillSound->getSoundContainer()->resize((int)soundNode->getChildCount());
|
||||
skillSoundList.push_back(skillSound);
|
||||
for(int i = 0; i < (int)soundNode->getChildCount(); ++i) {
|
||||
const XmlNode *soundFileNode= soundNode->getChild("sound-file", i);
|
||||
string path= soundFileNode->getAttribute("path")->getRestrictedValue(currentPath, true);
|
||||
|
@ -516,7 +544,7 @@ void SkillType::load(const XmlNode *sn, const XmlNode *attackBoostsNode,
|
|||
StaticSound *sound= new StaticSound();
|
||||
sound->load(path);
|
||||
loadedFileList[path].push_back(make_pair(parentLoader,soundFileNode->getAttribute("path")->getRestrictedValue()));
|
||||
sounds[i]= sound;
|
||||
(*skillSound->getSoundContainer())[i]= sound;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -743,7 +771,7 @@ void SkillType::saveGame(XmlNode *rootNode) {
|
|||
//
|
||||
// SoundContainer sounds;
|
||||
// float soundStartTime;
|
||||
skillTypeNode->addAttribute("soundStartTime",floatToStr(soundStartTime,6), mapTagReplacements);
|
||||
// skillTypeNode->addAttribute("soundStartTime",floatToStr(soundStartTime,6), mapTagReplacements);
|
||||
// RandomGen random;
|
||||
skillTypeNode->addAttribute("random",intToStr(random.getLastNumber()), mapTagReplacements);
|
||||
// AttackBoost attackBoost;
|
||||
|
@ -806,7 +834,7 @@ AttackSkillType::AttackSkillType() {
|
|||
splashRadius= 0;
|
||||
spawnUnit="";
|
||||
spawnUnitcount=0;
|
||||
projectileParticleSystemType= NULL;
|
||||
spawnUnitAtTarget=false;
|
||||
splashParticleSystemType= NULL;
|
||||
|
||||
for(int i = 0; i < fieldCount; ++i) {
|
||||
|
@ -821,8 +849,8 @@ AttackSkillType::AttackSkillType() {
|
|||
}
|
||||
|
||||
AttackSkillType::~AttackSkillType() {
|
||||
delete projectileParticleSystemType;
|
||||
projectileParticleSystemType = NULL;
|
||||
|
||||
deleteValues(projectileTypes.begin(), projectileTypes.end());
|
||||
|
||||
delete splashParticleSystemType;
|
||||
splashParticleSystemType = NULL;
|
||||
|
@ -859,11 +887,16 @@ void AttackSkillType::load(const XmlNode *sn, const XmlNode *attackBoostsNode,
|
|||
|
||||
if (sn->hasChild("unit")) {
|
||||
spawnUnit = sn->getChild("unit")->getAttribute("value")->getValue();
|
||||
spawnUnitcount
|
||||
= sn->getChild("unit")->getAttribute("amount")->getIntValue();
|
||||
spawnUnitcount = sn->getChild("unit")->getAttribute("amount")->getIntValue();
|
||||
if(sn->getChild("unit")->hasAttribute("spawnAtTarget")) {
|
||||
spawnUnitAtTarget = sn->getChild("unit")->getAttribute("spawnAtTarget")->getBoolValue();
|
||||
} else {
|
||||
spawnUnitAtTarget = false;
|
||||
}
|
||||
} else {
|
||||
spawnUnit = "";
|
||||
spawnUnitcount = 0;
|
||||
spawnUnitAtTarget = false;
|
||||
}
|
||||
//attack fields
|
||||
const XmlNode *attackFieldsNode= sn->getChild("attack-fields");
|
||||
|
@ -881,36 +914,81 @@ void AttackSkillType::load(const XmlNode *sn, const XmlNode *attackBoostsNode,
|
|||
}
|
||||
}
|
||||
|
||||
//projectile
|
||||
const XmlNode *projectileNode= sn->getChild("projectile");
|
||||
projectile= projectileNode->getAttribute("value")->getBoolValue();
|
||||
if(projectile){
|
||||
if(sn->hasChild("projectile")){
|
||||
//projectile -- backward compatible old behaviour with only one projectile
|
||||
const XmlNode *projectileNode= sn->getChild("projectile");
|
||||
projectile= projectileNode->getAttribute("value")->getBoolValue();
|
||||
if(projectile){
|
||||
// create new projectile
|
||||
ProjectileType *projectileType=new ProjectileType();
|
||||
projectileTypes.push_back(projectileType);
|
||||
projectileType->setAttackStartTime(attackStartTime);
|
||||
projectileType->setDamagePercentage(100);
|
||||
//proj particle
|
||||
if(projectileNode->hasChild("particle")){
|
||||
const XmlNode *particleNode= projectileNode->getChild("particle");
|
||||
bool particleEnabled= particleNode->getAttribute("value")->getBoolValue();
|
||||
if(particleEnabled){
|
||||
string path= particleNode->getAttribute("path")->getRestrictedValue();
|
||||
ParticleSystemTypeProjectile* projectileParticleSystemType= new ParticleSystemTypeProjectile();
|
||||
projectileParticleSystemType->load(particleNode, dir, currentPath + path,
|
||||
&Renderer::getInstance(), loadedFileList, parentLoader,
|
||||
tt->getPath());
|
||||
loadedFileList[currentPath + path].push_back(make_pair(parentLoader,particleNode->getAttribute("path")->getRestrictedValue()));
|
||||
projectileType->setProjectileParticleSystemType(projectileParticleSystemType);
|
||||
}
|
||||
}
|
||||
//proj sounds
|
||||
const XmlNode *soundNode= projectileNode->getChild("sound");
|
||||
if(soundNode->getAttribute("enabled")->getBoolValue()){
|
||||
|
||||
//proj particle
|
||||
const XmlNode *particleNode= projectileNode->getChild("particle");
|
||||
bool particleEnabled= particleNode->getAttribute("value")->getBoolValue();
|
||||
if(particleEnabled){
|
||||
string path= particleNode->getAttribute("path")->getRestrictedValue();
|
||||
projectileParticleSystemType= new ParticleSystemTypeProjectile();
|
||||
projectileParticleSystemType->load(particleNode, dir, currentPath + path,
|
||||
&Renderer::getInstance(), loadedFileList, parentLoader,
|
||||
tt->getPath());
|
||||
projSounds.resize((int)soundNode->getChildCount());
|
||||
for(int i=0; i < (int)soundNode->getChildCount(); ++i){
|
||||
const XmlNode *soundFileNode= soundNode->getChild("sound-file", i);
|
||||
string path= soundFileNode->getAttribute("path")->getRestrictedValue(currentPath, true);
|
||||
//printf("\n\n\n\n!@#$ ---> parentLoader [%s] path [%s] nodeValue [%s] i = %d",parentLoader.c_str(),path.c_str(),soundFileNode->getAttribute("path")->getRestrictedValue().c_str(),i);
|
||||
|
||||
StaticSound *sound= new StaticSound();
|
||||
sound->load(path);
|
||||
loadedFileList[path].push_back(make_pair(parentLoader,soundFileNode->getAttribute("path")->getRestrictedValue()));
|
||||
projSounds[i]= sound;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
const XmlNode *projectilesNode= sn->getChild("projectiles");
|
||||
vector<XmlNode *> projectilesNodeList = projectilesNode->getChildList("projectile");
|
||||
int totalDamagePercentage=0;
|
||||
for(unsigned int i = 0; i < projectilesNodeList.size(); ++i) {
|
||||
const XmlNode *projectileNode= projectilesNodeList[i];
|
||||
ProjectileType *projectileType=new ProjectileType();
|
||||
projectileType->load(projectileNode,dir, tt->getPath(), loadedFileList, parentLoader);
|
||||
totalDamagePercentage += projectileType->getDamagePercentage();
|
||||
projectileTypes.push_back(projectileType);
|
||||
projectile=true;
|
||||
}
|
||||
|
||||
//proj sounds
|
||||
const XmlNode *soundNode= projectileNode->getChild("sound");
|
||||
if(soundNode->getAttribute("enabled")->getBoolValue()){
|
||||
if(totalDamagePercentage!=100){
|
||||
throw megaglest_runtime_error("Damages percentages of projectiles don't sum up to 100 %");
|
||||
}
|
||||
|
||||
projSounds.resize((int)soundNode->getChildCount());
|
||||
for(int i=0; i < (int)soundNode->getChildCount(); ++i){
|
||||
const XmlNode *soundFileNode= soundNode->getChild("sound-file", i);
|
||||
string path= soundFileNode->getAttribute("path")->getRestrictedValue(currentPath, true);
|
||||
//printf("\n\n\n\n!@#$ ---> parentLoader [%s] path [%s] nodeValue [%s] i = %d",parentLoader.c_str(),path.c_str(),soundFileNode->getAttribute("path")->getRestrictedValue().c_str(),i);
|
||||
if(sn->hasChild("hitsound")==true){
|
||||
//general hit sounds, individual ones can be set in projectiles
|
||||
const XmlNode *soundNode= sn->getChild("hitsound");
|
||||
if(soundNode->getAttribute("enabled")->getBoolValue()){
|
||||
|
||||
StaticSound *sound= new StaticSound();
|
||||
sound->load(path);
|
||||
loadedFileList[path].push_back(make_pair(parentLoader,soundFileNode->getAttribute("path")->getRestrictedValue()));
|
||||
projSounds[i]= sound;
|
||||
projSounds.resize((int)soundNode->getChildCount());
|
||||
for(int i=0; i < (int)soundNode->getChildCount(); ++i){
|
||||
const XmlNode *soundFileNode= soundNode->getChild("sound-file", i);
|
||||
string path= soundFileNode->getAttribute("path")->getRestrictedValue(currentPath, true);
|
||||
//printf("\n\n\n\n!@#$ ---> parentLoader [%s] path [%s] nodeValue [%s] i = %d",parentLoader.c_str(),path.c_str(),soundFileNode->getAttribute("path")->getRestrictedValue().c_str(),i);
|
||||
|
||||
StaticSound *sound= new StaticSound();
|
||||
sound->load(path);
|
||||
loadedFileList[path].push_back(make_pair(parentLoader,soundFileNode->getAttribute("path")->getRestrictedValue()));
|
||||
projSounds[i]= sound;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -935,6 +1013,24 @@ void AttackSkillType::load(const XmlNode *sn, const XmlNode *attackBoostsNode,
|
|||
}
|
||||
}
|
||||
|
||||
int AttackSkillType::getTotalSpeed(const TotalUpgrade *totalUpgrade) const{
|
||||
int result = speed + totalUpgrade->getAttackSpeed(this);
|
||||
result = max(0,result);
|
||||
return result;
|
||||
}
|
||||
|
||||
// Get the amount to boost the attack animation speed by (based on attack-speed upgrades)
|
||||
int AttackSkillType::getAnimSpeedBoost(const TotalUpgrade *totalUpgrade) const{
|
||||
// Same calculation as in TotalUpgrade::sum, but bypassing the use of the value
|
||||
// list (which is for the attack speed, not animation speed)
|
||||
if(totalUpgrade->getAttackRangeIsMultiplier()) {
|
||||
return animSpeed * (totalUpgrade->getAttackSpeed(NULL) / (double)100);
|
||||
}
|
||||
else {
|
||||
return totalUpgrade->getAttackSpeed(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
string AttackSkillType::toString(bool translatedValue) const{
|
||||
if(translatedValue == false) {
|
||||
return "Attack";
|
||||
|
@ -983,12 +1079,15 @@ void AttackSkillType::saveGame(XmlNode *rootNode) {
|
|||
attackSkillTypeNode->addAttribute("spawnUnit",spawnUnit, mapTagReplacements);
|
||||
// int spawnUnitcount;
|
||||
attackSkillTypeNode->addAttribute("spawnUnitcount",intToStr(spawnUnitcount), mapTagReplacements);
|
||||
// bool spawnUnitAtTarget;
|
||||
attackSkillTypeNode->addAttribute("spawnUnitAtTarget",intToStr(spawnUnitAtTarget), mapTagReplacements);
|
||||
// bool projectile;
|
||||
attackSkillTypeNode->addAttribute("projectile",intToStr(projectile), mapTagReplacements);
|
||||
// ParticleSystemTypeProjectile* projectileParticleSystemType;
|
||||
if(projectileParticleSystemType != NULL) {
|
||||
projectileParticleSystemType->saveGame(attackSkillTypeNode);
|
||||
}
|
||||
// save a skill_type ????
|
||||
// if(projectileParticleSystemType != NULL) {
|
||||
// projectileParticleSystemType->saveGame(attackSkillTypeNode);
|
||||
// }
|
||||
// SoundContainer projSounds;
|
||||
//
|
||||
// bool splash;
|
||||
|
@ -1262,6 +1361,15 @@ void DieSkillType::saveGame(XmlNode *rootNode) {
|
|||
dieSkillTypeNode->addAttribute("fade",intToStr(fade), mapTagReplacements);
|
||||
}
|
||||
|
||||
StaticSound *DieSkillType::getSound() const{
|
||||
if(skillSoundList.size()==0){
|
||||
return NULL;
|
||||
}
|
||||
else {
|
||||
return skillSoundList.front()->getSoundContainer()->getRandSound();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// =====================================================
|
||||
// class FogOfWarSkillType
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "factory.h"
|
||||
#include "sound_container.h"
|
||||
#include "particle.h"
|
||||
#include "projectile_type.h"
|
||||
#include "upgrade_type.h"
|
||||
#include "leak_dumper.h"
|
||||
|
||||
|
@ -74,6 +75,7 @@ enum SkillClass{
|
|||
};
|
||||
|
||||
typedef list<UnitParticleSystemType*> UnitParticleSystemTypes;
|
||||
typedef list<ProjectileType*> ProjectileTypes;
|
||||
// =====================================================
|
||||
// class SkillType
|
||||
//
|
||||
|
@ -123,8 +125,29 @@ public:
|
|||
int toHp;
|
||||
};
|
||||
|
||||
// =====================================================
|
||||
// class SkillSound
|
||||
// holds the start time and a SoundContainer
|
||||
// =====================================================
|
||||
|
||||
class SkillSound{
|
||||
private:
|
||||
SoundContainer soundContainer;
|
||||
float startTime;
|
||||
|
||||
public:
|
||||
SkillSound();
|
||||
~SkillSound();
|
||||
|
||||
SoundContainer *getSoundContainer() {return &soundContainer;}
|
||||
float getStartTime() const {return startTime;}
|
||||
void setStartTime(float value) {startTime=value;}
|
||||
};
|
||||
|
||||
typedef list<SkillSound*> SkillSoundList;
|
||||
|
||||
class SkillType {
|
||||
|
||||
|
||||
protected:
|
||||
SkillClass skillClass;
|
||||
string name;
|
||||
|
@ -155,8 +178,7 @@ protected:
|
|||
vector<Model *> animations;
|
||||
vector<AnimationAttributes> animationAttributes;
|
||||
|
||||
SoundContainer sounds;
|
||||
float soundStartTime;
|
||||
SkillSoundList skillSoundList;
|
||||
RandomGen random;
|
||||
AttackBoost attackBoost;
|
||||
|
||||
|
@ -195,14 +217,14 @@ public:
|
|||
int getSpeed() const {return speed;}
|
||||
int getAnimSpeed() const {return animSpeed;}
|
||||
Model *getAnimation(float animProgress=0, const Unit *unit=NULL, int *lastAnimationIndex=NULL, int *animationRandomCycleCount=NULL) const;
|
||||
StaticSound *getSound() const {return sounds.getRandSound();}
|
||||
float getSoundStartTime() const {return soundStartTime;}
|
||||
|
||||
float getShakeStartTime() const {return shakeStartTime;}
|
||||
bool getShake() const {return shake;}
|
||||
int getShakeIntensity() const {return shakeIntensity;}
|
||||
int getShakeDuration() const {return shakeDuration;}
|
||||
|
||||
const SkillSoundList * getSkillSoundList() const {return &skillSoundList;}
|
||||
|
||||
bool getShakeSelfEnabled() const {return shakeSelfEnabled;}
|
||||
bool getShakeSelfVisible() const {return shakeSelfVisible;}
|
||||
bool getShakeSelfInCameraView() const {return shakeSelfInCameraView;}
|
||||
|
@ -258,6 +280,8 @@ public:
|
|||
// ===============================
|
||||
|
||||
class AttackSkillType: public SkillType{
|
||||
public:
|
||||
ProjectileTypes projectileTypes;
|
||||
private:
|
||||
int attackStrength;
|
||||
int attackVar;
|
||||
|
@ -268,8 +292,9 @@ private:
|
|||
|
||||
string spawnUnit;
|
||||
int spawnUnitcount;
|
||||
bool spawnUnitAtTarget;
|
||||
bool projectile;
|
||||
ParticleSystemTypeProjectile* projectileParticleSystemType;
|
||||
//ParticleSystemTypeProjectile* projectileParticleSystemType;
|
||||
SoundContainer projSounds;
|
||||
|
||||
bool splash;
|
||||
|
@ -294,10 +319,10 @@ public:
|
|||
inline float getAttackStartTime() const {return attackStartTime;}
|
||||
inline string getSpawnUnit() const {return spawnUnit;}
|
||||
inline int getSpawnUnitCount() const {return spawnUnitcount;}
|
||||
inline bool getSpawnUnitAtTarget() const {return spawnUnitAtTarget;}
|
||||
|
||||
//get proj
|
||||
inline bool getProjectile() const {return projectile;}
|
||||
inline ParticleSystemTypeProjectile * getProjParticleType() const {return projectileParticleSystemType;}
|
||||
inline StaticSound *getProjSound() const {return projSounds.getRandSound();}
|
||||
|
||||
//get splash
|
||||
|
@ -309,6 +334,8 @@ public:
|
|||
//misc
|
||||
int getTotalAttackStrength(const TotalUpgrade *totalUpgrade) const;
|
||||
int getTotalAttackRange(const TotalUpgrade *totalUpgrade) const;
|
||||
virtual int getTotalSpeed(const TotalUpgrade *totalUpgrade) const;
|
||||
virtual int getAnimSpeedBoost(const TotalUpgrade *totalUpgrade) const;
|
||||
|
||||
virtual void saveGame(XmlNode *rootNode);
|
||||
};
|
||||
|
@ -447,6 +474,7 @@ public:
|
|||
virtual string toString(bool translatedValue) const;
|
||||
|
||||
virtual void saveGame(XmlNode *rootNode);
|
||||
StaticSound *getSound() const;
|
||||
};
|
||||
|
||||
// ===============================
|
||||
|
|
|
@ -89,6 +89,7 @@ UnitType::UnitType() : ProducibleType() {
|
|||
lightColor= Vec3f(0.f);
|
||||
light= false;
|
||||
multiSelect= false;
|
||||
commandable= true;
|
||||
armorType= NULL;
|
||||
rotatedBuildPos=0;
|
||||
|
||||
|
@ -125,7 +126,13 @@ UnitType::UnitType() : ProducibleType() {
|
|||
epRegeneration= 0;
|
||||
maxUnitCount= 0;
|
||||
maxHp=0;
|
||||
startHpValue=0;
|
||||
startHpPercentage=1.0;
|
||||
startHpType=stValue;
|
||||
maxEp=0;
|
||||
startEpValue=0;
|
||||
startEpPercentage=0;
|
||||
startEpType=stValue;
|
||||
armor=0;
|
||||
sight=0;
|
||||
size=0;
|
||||
|
@ -247,6 +254,59 @@ void UnitType::loaddd(int id,const string &dir, const TechTree *techTree,
|
|||
}
|
||||
addItemToVault(&(this->epRegeneration),this->epRegeneration);
|
||||
|
||||
// Check that we don't use both start-value and start-percentage, as they are mutually
|
||||
// exclusive
|
||||
if(parametersNode->getChild("max-hp")->hasAttribute("start-value") &&
|
||||
parametersNode->getChild("max-hp")->hasAttribute("start-percentage")) {
|
||||
throw megaglest_runtime_error("Unit " + name +
|
||||
" has both start-value and start-percentage for HP", validationMode);
|
||||
}
|
||||
|
||||
//startHpValue -- the *absolute* value to use for starting HP
|
||||
if(parametersNode->getChild("max-hp")->hasAttribute("start-value")) {
|
||||
//checkItemInVault(&(this->startEp),this->startEp);
|
||||
startHpValue= parametersNode->getChild("max-hp")->getAttribute("start-value")->getIntValue();
|
||||
startHpType= stValue;
|
||||
}
|
||||
addItemToVault(&(this->startHpValue),this->startHpValue);
|
||||
|
||||
//startHpPercentage -- the *relative* value to use for starting HP
|
||||
if(parametersNode->getChild("max-hp")->hasAttribute("start-percentage")) {
|
||||
startHpPercentage= parametersNode->getChild("max-hp")->getAttribute("start-percentage")->getIntValue();
|
||||
startHpType= stPercentage;
|
||||
}
|
||||
|
||||
// No start value set; use max HP before upgrades
|
||||
if(!parametersNode->getChild("max-hp")->hasAttribute("start-value") &&
|
||||
!parametersNode->getChild("max-hp")->hasAttribute("start-percentage")) {
|
||||
startHpValue= parametersNode->getChild("max-hp")->getAttribute("value")->getIntValue();
|
||||
startHpType= stValue;
|
||||
}
|
||||
addItemToVault(&(this->startHpPercentage),this->startHpPercentage);
|
||||
|
||||
// Check that we don't use both start-value and start-percentage, as they are mutually
|
||||
// exclusive
|
||||
if(parametersNode->getChild("max-ep")->hasAttribute("start-value") &&
|
||||
parametersNode->getChild("max-ep")->hasAttribute("start-percentage")) {
|
||||
throw megaglest_runtime_error("Unit " + name +
|
||||
" has both start-value and start-percentage for EP", validationMode);
|
||||
}
|
||||
|
||||
//startEpValue -- the *absolute* value to use for starting EP
|
||||
if(parametersNode->getChild("max-ep")->hasAttribute("start-value")) {
|
||||
//checkItemInVault(&(this->startEp),this->startEp);
|
||||
startEpValue= parametersNode->getChild("max-ep")->getAttribute("start-value")->getIntValue();
|
||||
startEpType= stValue;
|
||||
}
|
||||
addItemToVault(&(this->startEpValue),this->startEpValue);
|
||||
|
||||
//startEpPercentage -- the *relative* value to use for starting EP
|
||||
if(parametersNode->getChild("max-ep")->hasAttribute("start-percentage")) {
|
||||
startEpPercentage= parametersNode->getChild("max-ep")->getAttribute("start-percentage")->getIntValue();
|
||||
startEpType= stPercentage;
|
||||
}
|
||||
addItemToVault(&(this->startEpPercentage),this->startEpPercentage);
|
||||
|
||||
//maxUnitCount
|
||||
if(parametersNode->hasChild("max-unit-count")) {
|
||||
//checkItemInVault(&(this->maxUnitCount),this->maxUnitCount);
|
||||
|
@ -274,6 +334,10 @@ void UnitType::loaddd(int id,const string &dir, const TechTree *techTree,
|
|||
//multi selection
|
||||
multiSelect= parametersNode->getChild("multi-selection")->getAttribute("value")->getBoolValue();
|
||||
|
||||
//commandable
|
||||
if(parametersNode->hasChild("commandable")){
|
||||
commandable= parametersNode->getChild("commandable")->getAttribute("value")->getBoolValue();
|
||||
}
|
||||
//cellmap
|
||||
allowEmptyCellMap = false;
|
||||
const XmlNode *cellMapNode= parametersNode->getChild("cellmap");
|
||||
|
@ -532,6 +596,65 @@ void UnitType::loaddd(int id,const string &dir, const TechTree *techTree,
|
|||
}
|
||||
}
|
||||
sortedItems.clear();
|
||||
hasDup = false;
|
||||
|
||||
// Lootable resources (resources given/lost on death)
|
||||
if(parametersNode->hasChild("resources-death")) {
|
||||
const XmlNode *deathResourcesNode= parametersNode->getChild("resources-death");
|
||||
|
||||
for(int i=0; i < deathResourcesNode->getChildCount(); ++i){
|
||||
const XmlNode *resourceNode= deathResourcesNode->getChild("resource", i);
|
||||
string name= resourceNode->getAttribute("name")->getRestrictedValue();
|
||||
|
||||
LootableResource resource;
|
||||
resource.setResourceType(techTree->getResourceType(name));
|
||||
|
||||
// All attributes are optional, although nothing happens if they aren't used. They can
|
||||
// be combined freely. Percentages will take affect before absolute values.
|
||||
if(resourceNode->hasAttribute("amount-value")) {
|
||||
resource.setAmountValue(resourceNode->getAttribute("amount-value")->getIntValue());
|
||||
}
|
||||
else {
|
||||
resource.setAmountValue(0);
|
||||
}
|
||||
|
||||
if(resourceNode->hasAttribute("amount-faction-percent")) {
|
||||
resource.setAmountFactionPercent(resourceNode->getAttribute("amount-faction-percent")->getIntValue());
|
||||
}
|
||||
else {
|
||||
resource.setAmountFactionPercent(0);
|
||||
}
|
||||
|
||||
if(resourceNode->hasAttribute("loss-value")) {
|
||||
resource.setLossValue(resourceNode->getAttribute("loss-value")->getIntValue());
|
||||
}
|
||||
else {
|
||||
resource.setLossValue(0);
|
||||
}
|
||||
|
||||
if(resourceNode->hasAttribute("loss-faction-percent")) {
|
||||
resource.setLossFactionPercent(resourceNode->getAttribute("loss-faction-percent")->getIntValue());
|
||||
}
|
||||
else {
|
||||
resource.setLossFactionPercent(0);
|
||||
}
|
||||
|
||||
if(resourceNode->hasAttribute("allow-negative")) {
|
||||
resource.setNegativeAllowed(resourceNode->getAttribute("allow-negative")->getBoolValue());
|
||||
}
|
||||
else {
|
||||
resource.setNegativeAllowed(false);
|
||||
}
|
||||
|
||||
// Figure out if there are duplicate resources. The value stored in the map is arbitrary,
|
||||
// and exists solely because
|
||||
if(std::find(lootableResources.begin(), lootableResources.end(), resource) != lootableResources.end()) {
|
||||
printf("WARNING, unit type [%s] has one or more duplicate lootable resources\n", this->getName(false).c_str());
|
||||
}
|
||||
|
||||
lootableResources.push_back(resource);
|
||||
}
|
||||
}
|
||||
|
||||
//image
|
||||
const XmlNode *imageNode= parametersNode->getChild("image");
|
||||
|
@ -1100,6 +1223,8 @@ std::string UnitType::toString() const {
|
|||
result += " maxHp = " + intToStr(maxHp);
|
||||
result += " hpRegeneration = " + intToStr(hpRegeneration);
|
||||
result += " maxEp = " + intToStr(maxEp);
|
||||
result += " startEpValue = " + intToStr(startEpValue);
|
||||
result += " startEpPercentage = " + intToStr(startEpPercentage);
|
||||
result += " epRegeneration = " + intToStr(epRegeneration);
|
||||
result += " maxUnitCount = " + intToStr(getMaxUnitCount());
|
||||
|
||||
|
@ -1120,6 +1245,7 @@ std::string UnitType::toString() const {
|
|||
result += " light = " + intToStr(light);
|
||||
result += " lightColor = " + lightColor.getString();
|
||||
result += " multiSelect = " + intToStr(multiSelect);
|
||||
result += " commandable = " + intToStr(commandable);
|
||||
result += " sight = " + intToStr(sight);
|
||||
result += " size = " + intToStr(size);
|
||||
result += " height = " + intToStr(height);
|
||||
|
|
|
@ -63,6 +63,45 @@ public:
|
|||
static const Level * loadGame(const XmlNode *rootNode, const UnitType *ut);
|
||||
};
|
||||
|
||||
// ===============================
|
||||
// class LootResource
|
||||
//
|
||||
/// Stores information about a lootable resource. Lootable resources are stolen by the attacker on death.
|
||||
// ===============================
|
||||
|
||||
class LootableResource {
|
||||
private:
|
||||
const ResourceType *type;
|
||||
int amountValue;
|
||||
int amountFactionPercent;
|
||||
int lossValue;
|
||||
int lossFactionPercent;
|
||||
bool negativeAllowed;
|
||||
|
||||
public:
|
||||
const ResourceType* getResourceType() const {return type;}
|
||||
void setResourceType(const ResourceType *type) {this->type=type;}
|
||||
|
||||
int getAmountValue() const {return amountValue;}
|
||||
void setAmountValue(int amountValue) {this->amountValue=amountValue;}
|
||||
|
||||
int getAmountFactionPercent() const {return amountFactionPercent;}
|
||||
void setAmountFactionPercent(int amountPercentage) {this->amountFactionPercent=amountPercentage;}
|
||||
|
||||
int getLossValue() const {return lossValue;}
|
||||
void setLossValue(int lossValue) {this->lossValue=lossValue;}
|
||||
|
||||
int getLossFactionPercent() const {return lossFactionPercent;}
|
||||
void setLossFactionPercent(int lossPercentage) {this->lossFactionPercent=lossPercentage;}
|
||||
|
||||
bool isNegativeAllowed() const {return negativeAllowed;}
|
||||
void setNegativeAllowed(bool negativeAllowed) {this->negativeAllowed=negativeAllowed;}
|
||||
|
||||
bool operator==(const LootableResource& other) {
|
||||
return type == other.getResourceType();
|
||||
}
|
||||
};
|
||||
|
||||
// ===============================
|
||||
// class UnitType
|
||||
//
|
||||
|
@ -92,6 +131,11 @@ public:
|
|||
pCount
|
||||
};
|
||||
|
||||
enum StartType {
|
||||
stValue,
|
||||
stPercentage
|
||||
};
|
||||
|
||||
static const char *propertyNames[];
|
||||
DamageParticleSystemTypes damageParticleSystemTypes;
|
||||
private:
|
||||
|
@ -99,13 +143,20 @@ private:
|
|||
typedef vector<CommandType*> CommandTypes;
|
||||
typedef vector<Resource> StoredResources;
|
||||
typedef vector<Level> Levels;
|
||||
typedef vector<LootableResource> LootableResources;
|
||||
|
||||
private:
|
||||
//basic
|
||||
int id;
|
||||
int maxHp;
|
||||
int startHpValue;
|
||||
int startHpPercentage;
|
||||
StartType startHpType;
|
||||
int hpRegeneration;
|
||||
int maxEp;
|
||||
int startEpValue;
|
||||
int startEpPercentage;
|
||||
StartType startEpType;
|
||||
int epRegeneration;
|
||||
int maxUnitCount;
|
||||
|
||||
|
@ -120,6 +171,7 @@ private:
|
|||
bool light;
|
||||
Vec3f lightColor;
|
||||
bool multiSelect;
|
||||
bool commandable;
|
||||
int sight;
|
||||
int size; //size in cells
|
||||
int renderSize; //size to render in cells
|
||||
|
@ -140,6 +192,7 @@ private:
|
|||
CommandTypes commandTypes;
|
||||
StoredResources storedResources;
|
||||
Levels levels;
|
||||
LootableResources lootableResources;
|
||||
|
||||
//meeting point
|
||||
bool meetingPoint;
|
||||
|
@ -178,8 +231,14 @@ public:
|
|||
inline int getId() const {return id;}
|
||||
inline int getMaxHp() const {return maxHp;}
|
||||
inline int getHpRegeneration() const {return hpRegeneration;}
|
||||
inline int getStartHpValue() const {return startHpValue;}
|
||||
inline int getStartHpPercentage() const {return startHpPercentage;}
|
||||
inline StartType getStartHpType() const {return startHpType;}
|
||||
inline int getMaxEp() const {return maxEp;}
|
||||
inline int getEpRegeneration() const {return epRegeneration;}
|
||||
inline int getStartEpValue() const {return startEpValue;}
|
||||
inline int getStartEpPercentage() const {return startEpPercentage;}
|
||||
inline StartType getStartEpType() const {return startEpType;}
|
||||
inline int getMaxUnitCount() const {return maxUnitCount;}
|
||||
inline bool getField(Field field) const {return fields[field];}
|
||||
inline Field getField() const {return field;}
|
||||
|
@ -197,12 +256,15 @@ public:
|
|||
inline bool getRotationAllowed() const {return rotationAllowed;}
|
||||
inline Vec3f getLightColor() const {return lightColor;}
|
||||
inline bool getMultiSelect() const {return multiSelect;}
|
||||
inline bool isCommandable() const {return commandable;}
|
||||
inline int getSight() const {return sight;}
|
||||
inline int getSize() const {return size;}
|
||||
inline int getRenderSize() const {return renderSize;}
|
||||
int getHeight() const {return height;}
|
||||
int getStoredResourceCount() const {return (int)storedResources.size();}
|
||||
inline const Resource *getStoredResource(int i) const {return &storedResources[i];}
|
||||
int getLootableResourceCount() const {return lootableResources.size();}
|
||||
inline const LootableResource getLootableResource(int i) const {return lootableResources.at(i);}
|
||||
bool getCellMapCell(int x, int y, CardinalDir facing) const;
|
||||
inline bool getMeetingPoint() const {return meetingPoint;}
|
||||
inline bool getCountUnitDeathInStats() const {return countUnitDeathInStats;}
|
||||
|
|
|
@ -169,6 +169,19 @@ void UpgradeTypeBase::load(const XmlNode *upgradeNode, string upgradename) {
|
|||
else {
|
||||
prodSpeed = 0;
|
||||
}
|
||||
|
||||
attackSpeedIsMultiplier = false;
|
||||
if(upgradeNode->hasChild("attack-speed") == true) {
|
||||
attackSpeed= upgradeNode->getChild("attack-speed")->getAttribute("value")->getIntValue();
|
||||
if(upgradeNode->getChild("attack-speed")->getAttribute(VALUE_PERCENT_MULTIPLIER_KEY_NAME,false) != NULL) {
|
||||
attackSpeedIsMultiplier = upgradeNode->getChild("attack-speed")->getAttribute(VALUE_PERCENT_MULTIPLIER_KEY_NAME)->getBoolValue();
|
||||
|
||||
//printf("Found prodSpeedIsMultiplier = %d\n",prodSpeedIsMultiplier);
|
||||
}
|
||||
}
|
||||
else {
|
||||
attackSpeed = 0;
|
||||
}
|
||||
}
|
||||
|
||||
int UpgradeTypeBase::getAttackStrength(const AttackSkillType *st) const {
|
||||
|
@ -212,6 +225,20 @@ int UpgradeTypeBase::getMoveSpeed(const MoveSkillType *st) const {
|
|||
}
|
||||
}
|
||||
|
||||
int UpgradeTypeBase::getAttackSpeed(const AttackSkillType *st) const {
|
||||
if(attackSpeedIsMultiplier == false || st == NULL) {
|
||||
return attackSpeed;
|
||||
}
|
||||
else {
|
||||
int result = 0;
|
||||
if(attackSpeedIsMultiplierValueList.find(st->getName()) != attackSpeedIsMultiplierValueList.end()) {
|
||||
result = attackSpeedIsMultiplierValueList.find(st->getName())->second;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
int UpgradeTypeBase::getProdSpeed(const SkillType *st) const {
|
||||
if(prodSpeedIsMultiplier == false || st == NULL) {
|
||||
return prodSpeed;
|
||||
|
@ -347,6 +374,18 @@ string UpgradeTypeBase::getDesc(bool translatedValue) const{
|
|||
str+= indent+lang.getString("ProductionSpeed",(translatedValue == true ? "" : "english")) + " +" + intToStr(prodSpeed);
|
||||
}
|
||||
}
|
||||
if(attackSpeed != 0) {
|
||||
if(str != "") {
|
||||
str += "\n";
|
||||
}
|
||||
|
||||
if(attackSpeedIsMultiplier) {
|
||||
str+= indent+lang.getString("AttackSpeed",(translatedValue == true ? "" : "english")) + " *" + intToStr(moveSpeed);
|
||||
}
|
||||
else {
|
||||
str+= indent+lang.getString("AttackSpeed",(translatedValue == true ? "" : "english")) + " +" + intToStr(moveSpeed);
|
||||
}
|
||||
}
|
||||
if(str != "") {
|
||||
str += "\n";
|
||||
}
|
||||
|
@ -821,6 +860,9 @@ void TotalUpgrade::reset() {
|
|||
|
||||
prodSpeed=0;
|
||||
prodSpeedIsMultiplier=false;
|
||||
|
||||
attackSpeed=0;
|
||||
attackSpeedIsMultiplier=false;
|
||||
}
|
||||
|
||||
void TotalUpgrade::sum(const UpgradeTypeBase *ut, const Unit *unit) {
|
||||
|
@ -832,6 +874,7 @@ void TotalUpgrade::sum(const UpgradeTypeBase *ut, const Unit *unit) {
|
|||
attackRangeIsMultiplier = ut->getAttackRangeIsMultiplier();
|
||||
moveSpeedIsMultiplier = ut->getMoveSpeedIsMultiplier();
|
||||
prodSpeedIsMultiplier = ut->getProdSpeedIsMultiplier();
|
||||
attackSpeedIsMultiplier = ut->getAttackSpeedIsMultiplier();
|
||||
|
||||
if(ut->getMaxHpIsMultiplier() == true) {
|
||||
//printf("#1 Maxhp maxHp = %d, unit->getHp() = %d ut->getMaxHp() = %d\n",maxHp,unit->getHp(),ut->getMaxHp());
|
||||
|
@ -941,6 +984,19 @@ void TotalUpgrade::sum(const UpgradeTypeBase *ut, const Unit *unit) {
|
|||
else {
|
||||
prodSpeed += ut->getProdSpeed(NULL);
|
||||
}
|
||||
|
||||
if(ut->getAttackSpeedIsMultiplier() == true) {
|
||||
for(unsigned int i = 0; i < (unsigned int)unit->getType()->getSkillTypeCount(); ++i) {
|
||||
const SkillType *skillType = unit->getType()->getSkillType(i);
|
||||
const AttackSkillType *ast = dynamic_cast<const AttackSkillType *>(skillType);
|
||||
if(ast != NULL) {
|
||||
attackSpeedIsMultiplierValueList[ast->getName()] += ((double)ast->getSpeed() * ((double)ut->getAttackSpeed(NULL) / (double)100));
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
attackSpeed += ut->getAttackSpeed(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void TotalUpgrade::apply(const UpgradeTypeBase *ut, const Unit *unit) {
|
||||
|
@ -1080,6 +1136,23 @@ void TotalUpgrade::deapply(const UpgradeTypeBase *ut,const Unit *unit) {
|
|||
prodSpeed -= ut->getProdSpeed(NULL);
|
||||
enforceMinimumValue(0,prodSpeed);
|
||||
}
|
||||
|
||||
if(ut->getAttackSpeedIsMultiplier() == true) {
|
||||
for(unsigned int i = 0; i < (unsigned int)unit->getType()->getSkillTypeCount(); ++i) {
|
||||
const SkillType *skillType = unit->getType()->getSkillType(i);
|
||||
const AttackSkillType *ast = dynamic_cast<const AttackSkillType *>(skillType);
|
||||
if(ast != NULL) {
|
||||
attackSpeedIsMultiplierValueList[ast->getName()] -= ((double)ast->getSpeed() * ((double)ut->getAttackSpeed(NULL) / (double)100));
|
||||
enforceMinimumValue(0, attackSpeedIsMultiplierValueList[ast->getName()]);
|
||||
}
|
||||
}
|
||||
|
||||
//printf("AFTER Applying moveSpeedIsMultiplier, moveSpeed = %d\n",moveSpeed);
|
||||
}
|
||||
else {
|
||||
attackSpeed -= ut->getAttackSpeed(NULL);
|
||||
enforceMinimumValue(0, attackSpeed);
|
||||
}
|
||||
}
|
||||
|
||||
void TotalUpgrade::incLevel(const UnitType *ut) {
|
||||
|
@ -1184,6 +1257,16 @@ void TotalUpgrade::saveGame(XmlNode *rootNode) const {
|
|||
prodSpeedMorphIsMultiplierValueListNode->addAttribute("key",iterMap->first, mapTagReplacements);
|
||||
prodSpeedMorphIsMultiplierValueListNode->addAttribute("value",intToStr(iterMap->second), mapTagReplacements);
|
||||
}
|
||||
|
||||
upgradeTypeBaseNode->addAttribute("attackSpeed",intToStr(attackSpeed), mapTagReplacements);
|
||||
upgradeTypeBaseNode->addAttribute("attackSpeedIsMultiplier",intToStr(attackSpeedIsMultiplier), mapTagReplacements);
|
||||
for(std::map<string,int>::const_iterator iterMap = attackSpeedIsMultiplierValueList.begin();
|
||||
iterMap != attackSpeedIsMultiplierValueList.end(); ++iterMap) {
|
||||
XmlNode *attackSpeedIsMultiplierValueListNode = upgradeTypeBaseNode->addChild("attackSpeedIsMultiplierValueList");
|
||||
|
||||
attackSpeedIsMultiplierValueListNode->addAttribute("key",iterMap->first, mapTagReplacements);
|
||||
attackSpeedIsMultiplierValueListNode->addAttribute("value",intToStr(iterMap->second), mapTagReplacements);
|
||||
}
|
||||
}
|
||||
|
||||
void TotalUpgrade::loadGame(const XmlNode *rootNode) {
|
||||
|
@ -1282,6 +1365,16 @@ void TotalUpgrade::loadGame(const XmlNode *rootNode) {
|
|||
prodSpeedMorphIsMultiplierValueList[node->getAttribute("key")->getValue()] =
|
||||
node->getAttribute("value")->getIntValue();
|
||||
}
|
||||
|
||||
attackSpeed = upgradeTypeBaseNode->getAttribute("attackSpeed")->getIntValue();
|
||||
attackSpeedIsMultiplier = upgradeTypeBaseNode->getAttribute("attackSpeedIsMultiplier")->getIntValue() != 0;
|
||||
vector<XmlNode *> attackSpeedIsMultiplierValueNodeList = upgradeTypeBaseNode->getChildList("attackSpeedIsMultiplierValueList");
|
||||
for(unsigned int i = 0; i < attackSpeedIsMultiplierValueNodeList.size(); ++i) {
|
||||
XmlNode *node = attackSpeedIsMultiplierValueNodeList[i];
|
||||
|
||||
attackSpeedIsMultiplierValueList[node->getAttribute("key")->getValue()] =
|
||||
node->getAttribute("value")->getIntValue();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -9,6 +9,14 @@
|
|||
// License, or (at your option) any later version
|
||||
// ==============================================================
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Classified the Upgrade type (which is sort of like a class for upgrades). Each upgrade has a
|
||||
* type that details the stats that it boosts and the units that it affects. Also has TotalUpgrade,
|
||||
* which is a sum of all upgrades applied to a particular unit (and is what determines how units
|
||||
* stats are modified by an upgrade.
|
||||
*/
|
||||
|
||||
#ifndef _GLEST_GAME_UPGRADETYPE_H_
|
||||
#define _GLEST_GAME_UPGRADETYPE_H_
|
||||
|
||||
|
@ -39,10 +47,9 @@ class MoveSkillType;
|
|||
class ProduceSkillType;
|
||||
class Faction;
|
||||
|
||||
// ===============================
|
||||
// class UpgradeTypeBase
|
||||
// ===============================
|
||||
|
||||
/**
|
||||
* Groups all information used for upgrades. Attack boosts also use this class for modifying stats.
|
||||
*/
|
||||
class UpgradeTypeBase {
|
||||
protected:
|
||||
string upgradename;
|
||||
|
@ -64,23 +71,35 @@ protected:
|
|||
|
||||
int attackStrength;
|
||||
bool attackStrengthIsMultiplier;
|
||||
/**
|
||||
* List of the values (for each skill type) that the stat was boosted by. This is used so
|
||||
* that we can restore the original values when the upgrade is removed (eg, an attack
|
||||
* boost wears off).
|
||||
*/
|
||||
std::map<string,int> attackStrengthMultiplierValueList;
|
||||
|
||||
int attackRange;
|
||||
bool attackRangeIsMultiplier;
|
||||
std::map<string,int> attackRangeMultiplierValueList;
|
||||
std::map<string,int> attackRangeMultiplierValueList; /**< @see #attackStrengthMultiplierValueList */
|
||||
|
||||
int moveSpeed;
|
||||
bool moveSpeedIsMultiplier;
|
||||
std::map<string,int> moveSpeedIsMultiplierValueList;
|
||||
std::map<string,int> moveSpeedIsMultiplierValueList; /**< @see #attackStrengthMultiplierValueList */
|
||||
|
||||
int prodSpeed;
|
||||
bool prodSpeedIsMultiplier;
|
||||
std::map<string,int> prodSpeedProduceIsMultiplierValueList;
|
||||
std::map<string,int> prodSpeedUpgradeIsMultiplierValueList;
|
||||
std::map<string,int> prodSpeedMorphIsMultiplierValueList;
|
||||
std::map<string,int> prodSpeedProduceIsMultiplierValueList; /**< @see #attackStrengthMultiplierValueList */
|
||||
std::map<string,int> prodSpeedUpgradeIsMultiplierValueList; /**< @see #attackStrengthMultiplierValueList */
|
||||
std::map<string,int> prodSpeedMorphIsMultiplierValueList; /**< @see #attackStrengthMultiplierValueList */
|
||||
|
||||
int attackSpeed;
|
||||
bool attackSpeedIsMultiplier;
|
||||
std::map<string,int> attackSpeedIsMultiplierValueList;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Creates an UpgradeTypeBase with values such that there are no stat changes.
|
||||
*/
|
||||
UpgradeTypeBase() {
|
||||
maxHp = 0;;
|
||||
maxHpIsMultiplier = false;
|
||||
|
@ -127,11 +146,30 @@ public:
|
|||
bool getMoveSpeedIsMultiplier() const {return moveSpeedIsMultiplier;}
|
||||
int getProdSpeed(const SkillType *st) const;
|
||||
bool getProdSpeedIsMultiplier() const {return prodSpeedIsMultiplier;}
|
||||
int getAttackSpeed(const AttackSkillType *st) const;
|
||||
bool getAttackSpeedIsMultiplier() const {return attackSpeedIsMultiplier;}
|
||||
|
||||
/**
|
||||
* Loads the upgrade values (stat boosts and whether or not the boosts use a multiplier) from an
|
||||
* XML node.
|
||||
* @param upgradeNode Node containing the stat boost elements (`max-hp`, `attack-strength`, etc).
|
||||
* @param upgradename Unique identifier for the upgrade.
|
||||
*/
|
||||
|
||||
void load(const XmlNode *upgradeNode, string upgradename);
|
||||
|
||||
|
||||
/**
|
||||
* Creates a string representation of the upgrade. All stat boosts are detailed on their own line
|
||||
* with their corresponding boosts.
|
||||
* @param translatedValue If true, the description is translated. Otherwise the description uses
|
||||
* names as they appear in the XMLs.
|
||||
*/
|
||||
virtual string getDesc(bool translatedValue) const;
|
||||
|
||||
|
||||
/**
|
||||
* Returns a string representation of this object. Lists all the value that the object stores.
|
||||
* For debugging purposes, only.
|
||||
*/
|
||||
std::string toString() const {
|
||||
std::string result = "";
|
||||
|
||||
|
@ -163,9 +201,14 @@ public:
|
|||
return result;
|
||||
}
|
||||
|
||||
// TODO: It's not clear if these save game methods are being used, currently. I think
|
||||
// attack boosts might use the few lines that aren't commented out.
|
||||
virtual void saveGame(XmlNode *rootNode) const;
|
||||
static const UpgradeType * loadGame(const XmlNode *rootNode, Faction *faction);
|
||||
|
||||
/**
|
||||
* Generates a checksum value for the upgrade.
|
||||
*/
|
||||
Checksum getCRC() {
|
||||
Checksum crcForUpgradeType;
|
||||
|
||||
|
@ -207,58 +250,145 @@ public:
|
|||
crcForUpgradeType.addInt64((int64)prodSpeedUpgradeIsMultiplierValueList.size());
|
||||
//std::map<string,int> prodSpeedMorphIsMultiplierValueList;
|
||||
crcForUpgradeType.addInt64((int64)prodSpeedMorphIsMultiplierValueList.size());
|
||||
|
||||
crcForUpgradeType.addInt(attackSpeed);
|
||||
crcForUpgradeType.addInt(attackSpeedIsMultiplier);
|
||||
|
||||
return crcForUpgradeType;
|
||||
}
|
||||
};
|
||||
|
||||
// ===============================
|
||||
// class UpgradeType
|
||||
// ===============================
|
||||
|
||||
/**
|
||||
* Represents the type of upgrade. That is, the single upgrade as it appears in the faction's XML
|
||||
* files. Each upgrade has a single `UpgradeType`. Contains information about what units are
|
||||
* affected by the upgrade.
|
||||
*/
|
||||
class UpgradeType: public UpgradeTypeBase, public ProducibleType {
|
||||
private:
|
||||
/**
|
||||
* List of unit types (the "classes" of units, eg, swordman) that are affected by this upgrade.
|
||||
*/
|
||||
vector<const UnitType*> effects;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Sets the upgrade name to the directory name (the base name of `dir`).
|
||||
* @param dir Path of the upgrade directory.
|
||||
*/
|
||||
void preLoad(const string &dir);
|
||||
|
||||
/**
|
||||
* Loads an upgrade from an XML file.
|
||||
* @param dir Path of the upgrade directory. The file name is determined from this.
|
||||
* @param techTree The techtree that this upgrade is in. Used to access the common data
|
||||
* directory and to access resources.
|
||||
* @param factionType The faction type (a unique type for each faction) that the upgrade belongs
|
||||
* to. Used for accessing unit types that are in the unit requirements list.
|
||||
* @param checksum Will have the checksum of the upgrade path added to it (treated the same way
|
||||
* as the `techtreeChecksum`).
|
||||
* @param techtreeChecksum Cumulative checksum for the techtree. The path of loaded upgrades
|
||||
* is added to this checksum.
|
||||
*/
|
||||
void load(const string &dir, const TechTree *techTree,
|
||||
const FactionType *factionType, Checksum* checksum,
|
||||
Checksum* techtreeChecksum,
|
||||
std::map<string,vector<pair<string, string> > > &loadedFileList,
|
||||
bool validationMode=false);
|
||||
|
||||
|
||||
/**
|
||||
* Obtains the upgrade name.
|
||||
* @param translatedValue If true, the name is translated. Otherwise the name is returned as it
|
||||
* appears in the XMLs.
|
||||
*/
|
||||
virtual string getName(bool translatedValue=false) const;
|
||||
|
||||
//get all
|
||||
/**
|
||||
* Returns the number of UnitTypes affected by this upgrade.
|
||||
*/
|
||||
int getEffectCount() const {return (int)effects.size();}
|
||||
|
||||
/**
|
||||
* Returns a particular unit type affected by this upgrade.
|
||||
* @param i Index of the unit type in the #effects list.
|
||||
*/
|
||||
const UnitType * getEffect(int i) const {return effects[i];}
|
||||
|
||||
/**
|
||||
* Determines if a unit is affected by this upgrade.
|
||||
* @param unitType The UnitType we are checking (to see if they're affected).
|
||||
* @return True if the unit is affected, false otherwise.
|
||||
*/
|
||||
bool isAffected(const UnitType *unitType) const;
|
||||
|
||||
//other methods
|
||||
/**
|
||||
* Creates a description for this upgrade. Lists the affected units.
|
||||
*/
|
||||
virtual string getReqDesc(bool translatedValue) const;
|
||||
|
||||
//virtual void saveGame(XmlNode *rootNode) const;
|
||||
//virtual void loadGame(const XmlNode *rootNode);
|
||||
};
|
||||
|
||||
// ===============================
|
||||
// class TotalUpgrade
|
||||
// ===============================
|
||||
|
||||
/**
|
||||
* Keeps track of the cumulative effects of upgrades on units. This allows us to apply multiple
|
||||
* upgrades to a unit with the effects stacking.
|
||||
*/
|
||||
class TotalUpgrade: public UpgradeTypeBase {
|
||||
public:
|
||||
TotalUpgrade();
|
||||
virtual ~TotalUpgrade() {}
|
||||
|
||||
/**
|
||||
* Resets all stat boosts (so there's effectively no upgrade).
|
||||
*/
|
||||
void reset();
|
||||
|
||||
/**
|
||||
* Adds an upgrade to this one, stacking the effects. Note that multipliers are stacked
|
||||
* by multiplying by the original, unboosted amount, and then adding that to the TotalUpgrade.
|
||||
* @param ut The upgrade to apply.
|
||||
* @param unit The unit this TotalUpgrade is associated with (since when we use a multiplier,
|
||||
* the stats raise by an amount relative to the unit's base stats).
|
||||
*/
|
||||
void sum(const UpgradeTypeBase *ut, const Unit *unit);
|
||||
|
||||
/**
|
||||
* Increases the level of the unit. Doing so results in their HP, EP, and armour going up by
|
||||
* 50% while their sight goes up by 20%.
|
||||
* @param ut The unit type to get the original stats from (so we can determine just how much
|
||||
* to increase the stats by on level up).
|
||||
*/
|
||||
void incLevel(const UnitType *ut);
|
||||
|
||||
/**
|
||||
* Applies the upgrade. Just a delegate to TotalUpgrade::sum.
|
||||
*/
|
||||
void apply(const UpgradeTypeBase *ut, const Unit *unit);
|
||||
|
||||
/**
|
||||
* Removes the effect of an upgrade to a specific unit. Using this after applying the upgrade
|
||||
* is an invariant. ie,
|
||||
*
|
||||
* totalUpgrade->apply(upgrade, unit);
|
||||
* totalUpgrade->deapply(upgrade, unit);
|
||||
* // totalUpgrade is now the same as before the call to apply()
|
||||
*
|
||||
* @param ut The upgrade to remove.
|
||||
* @param unit The unit this TotalUpgrade is associated with (since when we use a multiplier,
|
||||
* the stats were raise by an amount relative to the unit's base stats).
|
||||
*/
|
||||
void deapply(const UpgradeTypeBase *ut, const Unit *unit);
|
||||
|
||||
/**
|
||||
* Creates the XML for the save game file. Essentially just stores everything about its state.
|
||||
* @rootNode The node of the unit that this TotalUpgrade object belongs to.
|
||||
*/
|
||||
void saveGame(XmlNode *rootNode) const;
|
||||
|
||||
/**
|
||||
* Reloads the object's state from a saved game.
|
||||
* @rootNode The node of the unit that this TotalUpgrade object belongs to.
|
||||
*/
|
||||
void loadGame(const XmlNode *rootNode);
|
||||
};
|
||||
|
||||
|
|
|
@ -78,6 +78,7 @@ Checksum Scenario::load(const string &path) {
|
|||
|
||||
//parse xml
|
||||
XmlTree xmlTree;
|
||||
xmlTree.setSkipUpdatePathClimbingParts(true);
|
||||
xmlTree.load(path,Properties::getTagReplacementValues());
|
||||
const XmlNode *scenarioNode= xmlTree.getRootNode();
|
||||
const XmlNode *scriptsNode= scenarioNode->getChild("scripts");
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "network_manager.h"
|
||||
#include "object.h"
|
||||
#include "particle_type.h"
|
||||
#include "projectile_type.h"
|
||||
#include "path_finder.h"
|
||||
#include "renderer.h"
|
||||
#include "sound.h"
|
||||
|
@ -127,16 +128,18 @@ bool UnitUpdater::updateUnit(Unit *unit) {
|
|||
|
||||
//play skill sound
|
||||
const SkillType *currSkill= unit->getCurrSkill();
|
||||
if(currSkill->getSound() != NULL) {
|
||||
float soundStartTime= currSkill->getSoundStartTime();
|
||||
|
||||
for(SkillSoundList::const_iterator it= currSkill->getSkillSoundList()->begin(); it != currSkill->getSkillSoundList()->end(); ++it) {
|
||||
float soundStartTime= (*it)->getStartTime();
|
||||
if(soundStartTime >= unit->getLastAnimProgressAsFloat() && soundStartTime < unit->getAnimProgressAsFloat()) {
|
||||
if(map->getSurfaceCell(Map::toSurfCoords(unit->getPos()))->isVisible(world->getThisTeamIndex()) ||
|
||||
(game->getWorld()->showWorldForPlayer(game->getWorld()->getThisTeamIndex()) == true)) {
|
||||
soundRenderer.playFx(currSkill->getSound(), unit->getCurrVector(), gameCamera->getPos());
|
||||
soundRenderer.playFx((*it)->getSoundContainer()->getRandSound(), unit->getCurrVector(), gameCamera->getPos());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (currSkill->getShake()) {
|
||||
float shakeStartTime = currSkill->getShakeStartTime();
|
||||
if (shakeStartTime >= unit->getLastAnimProgressAsFloat()
|
||||
|
@ -186,14 +189,24 @@ bool UnitUpdater::updateUnit(Unit *unit) {
|
|||
float attackStartTime = truncateDecimal<float>(ast->getAttackStartTime(),6);
|
||||
float lastAnimProgress = truncateDecimal<float>(unit->getLastAnimProgressAsFloat(),6);
|
||||
float animProgress = truncateDecimal<float>(unit->getAnimProgressAsFloat(),6);
|
||||
bool startAttackParticleSystemNow = (attackStartTime >= lastAnimProgress && attackStartTime < animProgress);
|
||||
bool startAttackParticleSystemNow = false;
|
||||
if(ast->projectileTypes.empty() == true ){
|
||||
startAttackParticleSystemNow = (attackStartTime >= lastAnimProgress && attackStartTime < animProgress);
|
||||
}
|
||||
else {// start projectile attack
|
||||
for(ProjectileTypes::const_iterator it= ast->projectileTypes.begin(); it != ast->projectileTypes.end(); ++it) {
|
||||
attackStartTime= (*it)->getAttackStartTime();
|
||||
startAttackParticleSystemNow = (attackStartTime >= lastAnimProgress && attackStartTime < animProgress);
|
||||
if(startAttackParticleSystemNow==true) break;
|
||||
}
|
||||
}
|
||||
|
||||
char szBuf[8096]="";
|
||||
snprintf(szBuf,8095,"attackStartTime = %f, lastAnimProgress = %f, animProgress = %f startAttackParticleSystemNow = %d",attackStartTime,lastAnimProgress,animProgress,startAttackParticleSystemNow);
|
||||
unit->setNetworkCRCParticleLogInfo(szBuf);
|
||||
|
||||
if(startAttackParticleSystemNow == true) {
|
||||
startAttackParticleSystem(unit);
|
||||
startAttackParticleSystem(unit,lastAnimProgress,animProgress);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -257,55 +270,12 @@ bool UnitUpdater::updateUnit(Unit *unit) {
|
|||
else if(unit->getCommandSize() > 0) {
|
||||
Command *command= unit->getCurrCommand();
|
||||
if(command != NULL) {
|
||||
const CommandType *ct = command->getCommandType();
|
||||
|
||||
const AttackCommandType *act= dynamic_cast<const AttackCommandType*>(command->getCommandType());
|
||||
if( act != NULL && act->getAttackSkillType() != NULL &&
|
||||
act->getAttackSkillType()->getSpawnUnit() != "" && act->getAttackSkillType()->getSpawnUnitCount() > 0) {
|
||||
|
||||
const FactionType *ft= unit->getFaction()->getType();
|
||||
const UnitType *spawnUnitType = ft->getUnitType(act->getAttackSkillType()->getSpawnUnit());
|
||||
int spawnCount = act->getAttackSkillType()->getSpawnUnitCount();
|
||||
for (int y=0; y < spawnCount; ++y) {
|
||||
if(spawnUnitType->getMaxUnitCount() > 0) {
|
||||
if(spawnUnitType->getMaxUnitCount() <= unit->getFaction()->getCountForMaxUnitCount(spawnUnitType)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
UnitPathInterface *newpath = NULL;
|
||||
switch(this->game->getGameSettings()->getPathFinderType()) {
|
||||
case pfBasic:
|
||||
newpath = new UnitPathBasic();
|
||||
break;
|
||||
default:
|
||||
throw megaglest_runtime_error("detected unsupported pathfinder type!");
|
||||
}
|
||||
|
||||
Unit *spawned= new Unit(world->getNextUnitId(unit->getFaction()), newpath,
|
||||
Vec2i(0), spawnUnitType, unit->getFaction(),
|
||||
world->getMap(), CardinalDir::NORTH);
|
||||
//SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d] about to place unit for unit [%s]\n",__FILE__,__FUNCTION__,__LINE__,spawned->toString().c_str());
|
||||
if(!world->placeUnit(unit->getCenteredPos(), 10, spawned)) {
|
||||
//SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d] COULD NOT PLACE UNIT for unitID [%d]\n",__FILE__,__FUNCTION__,__LINE__,spawned->getId());
|
||||
|
||||
// This will also cleanup newPath
|
||||
delete spawned;
|
||||
spawned = NULL;
|
||||
}
|
||||
else {
|
||||
spawned->create();
|
||||
spawned->born(ct);
|
||||
world->getStats()->produce(unit->getFactionIndex(),spawned->getType()->getCountUnitProductionInStats());
|
||||
const CommandType *ct= spawned->computeCommandType(command->getPos(),command->getUnit());
|
||||
if(ct != NULL){
|
||||
if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
spawned->giveCommand(new Command(ct, unit->getMeetingPos()));
|
||||
}
|
||||
scriptManager->onUnitCreated(spawned);
|
||||
|
||||
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
|
||||
}
|
||||
}
|
||||
if (act != NULL && act->getAttackSkillType() != NULL
|
||||
&& act->getAttackSkillType()->getSpawnUnit() != ""
|
||||
&& act->getAttackSkillType()->getSpawnUnitCount() > 0) {
|
||||
spawnAttack(unit,act->getAttackSkillType()->getSpawnUnit(),act->getAttackSkillType()->getSpawnUnitCount(),act->getAttackSkillType()->getSpawnUnitAtTarget());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -343,6 +313,65 @@ bool UnitUpdater::updateUnit(Unit *unit) {
|
|||
return processUnitCommand;
|
||||
}
|
||||
|
||||
void UnitUpdater::spawnAttack(Unit *unit,string spawnUnit,int spawnUnitcount,bool spawnUnitAtTarget,Vec2i targetPos) {
|
||||
if(spawnUnit != "" && spawnUnitcount > 0) {
|
||||
|
||||
const FactionType *ft= unit->getFaction()->getType();
|
||||
const UnitType *spawnUnitType = ft->getUnitType(spawnUnit);
|
||||
int spawnCount = spawnUnitcount;
|
||||
for (int y=0; y < spawnCount; ++y) {
|
||||
if(spawnUnitType->getMaxUnitCount() > 0) {
|
||||
if(spawnUnitType->getMaxUnitCount() <= unit->getFaction()->getCountForMaxUnitCount(spawnUnitType)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
UnitPathInterface *newpath = NULL;
|
||||
switch(this->game->getGameSettings()->getPathFinderType()) {
|
||||
case pfBasic:
|
||||
newpath = new UnitPathBasic();
|
||||
break;
|
||||
default:
|
||||
throw megaglest_runtime_error("detected unsupported pathfinder type!");
|
||||
}
|
||||
|
||||
Unit *spawned= new Unit(world->getNextUnitId(unit->getFaction()), newpath,
|
||||
Vec2i(0), spawnUnitType, unit->getFaction(),
|
||||
world->getMap(), CardinalDir::NORTH);
|
||||
//SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d] about to place unit for unit [%s]\n",__FILE__,__FUNCTION__,__LINE__,spawned->toString().c_str());
|
||||
bool placedSpawnUnit=false;
|
||||
if(targetPos==Vec2i(-10,-10)) {
|
||||
targetPos=unit->getTargetPos();
|
||||
}
|
||||
if(spawnUnitAtTarget) {
|
||||
placedSpawnUnit=world->placeUnit(targetPos, 10, spawned);
|
||||
} else {
|
||||
placedSpawnUnit=world->placeUnit(unit->getCenteredPos(), 10, spawned);
|
||||
}
|
||||
if(!placedSpawnUnit) {
|
||||
//SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d] COULD NOT PLACE UNIT for unitID [%d]\n",__FILE__,__FUNCTION__,__LINE__,spawned->getId());
|
||||
|
||||
// This will also cleanup newPath
|
||||
delete spawned;
|
||||
spawned = NULL;
|
||||
}
|
||||
else {
|
||||
spawned->create();
|
||||
spawned->born(NULL);
|
||||
world->getStats()->produce(unit->getFactionIndex(),spawned->getType()->getCountUnitProductionInStats());
|
||||
const CommandType *ct= spawned->getType()->getFirstAttackCommand(unit->getTargetField());
|
||||
if(ct == NULL){
|
||||
ct= spawned->computeCommandType(targetPos,map->getCell(targetPos)->getUnit(unit->getTargetField()));
|
||||
}
|
||||
if(ct != NULL){
|
||||
if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
spawned->giveCommand(new Command(ct, targetPos));
|
||||
}
|
||||
scriptManager->onUnitCreated(spawned);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== progress commands ====================
|
||||
|
||||
//VERY IMPORTANT: compute next state depending on the first order of the list
|
||||
|
@ -2488,10 +2517,10 @@ void UnitUpdater::updateSwitchTeam(Unit *unit, int frameIndex) {
|
|||
// ==================== attack ====================
|
||||
|
||||
void UnitUpdater::hit(Unit *attacker){
|
||||
hit(attacker, dynamic_cast<const AttackSkillType*>(attacker->getCurrSkill()), attacker->getTargetPos(), attacker->getTargetField());
|
||||
hit(attacker, dynamic_cast<const AttackSkillType*>(attacker->getCurrSkill()), attacker->getTargetPos(), attacker->getTargetField(),100);
|
||||
}
|
||||
|
||||
void UnitUpdater::hit(Unit *attacker, const AttackSkillType* ast, const Vec2i &targetPos, Field targetField){
|
||||
void UnitUpdater::hit(Unit *attacker, const AttackSkillType* ast, const Vec2i &targetPos, Field targetField, int damagePercent){
|
||||
//hit attack positions
|
||||
if(ast != NULL && ast->getSplash()) {
|
||||
char szBuf[8096]="";
|
||||
|
@ -2511,7 +2540,7 @@ void UnitUpdater::hit(Unit *attacker, const AttackSkillType* ast, const Vec2i &t
|
|||
|
||||
float distance = pci.getPos().dist(targetPos);
|
||||
distance = truncateDecimal<float>(distance,6);
|
||||
damage(attacker, ast, attacked, distance);
|
||||
damage(attacker, ast, attacked, distance,damagePercent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2524,12 +2553,12 @@ void UnitUpdater::hit(Unit *attacker, const AttackSkillType* ast, const Vec2i &t
|
|||
attacker->addNetworkCRCDecHp(szBuf);
|
||||
|
||||
if(attacked != NULL) {
|
||||
damage(attacker, ast, attacked, 0.f);
|
||||
damage(attacker, ast, attacked, 0.f,damagePercent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UnitUpdater::damage(Unit *attacker, const AttackSkillType* ast, Unit *attacked, float distance) {
|
||||
void UnitUpdater::damage(Unit *attacker, const AttackSkillType* ast, Unit *attacked, float distance, int damagePercent) {
|
||||
if(attacker == NULL) {
|
||||
throw megaglest_runtime_error("attacker == NULL");
|
||||
}
|
||||
|
@ -2555,6 +2584,7 @@ void UnitUpdater::damage(Unit *attacker, const AttackSkillType* ast, Unit *attac
|
|||
damage *= damageMultiplier;
|
||||
damage = truncateDecimal<float>(damage,6);
|
||||
|
||||
damage = (damage*damagePercent)/100;
|
||||
if(damage < 1) {
|
||||
damage= 1;
|
||||
}
|
||||
|
@ -2573,6 +2603,37 @@ void UnitUpdater::damage(Unit *attacker, const AttackSkillType* ast, Unit *attac
|
|||
attacker->incKills(attacked->getTeam());
|
||||
}
|
||||
|
||||
// Perform resource looting iff the attack is from a different faction
|
||||
if(attacker->getFaction() != attacked->getFaction()) {
|
||||
int lootableResourceCount = attacked->getType()->getLootableResourceCount();
|
||||
for(int i = 0; i < lootableResourceCount; i++) {
|
||||
LootableResource resource = attacked->getType()->getLootableResource(i);
|
||||
|
||||
// Figure out how much of the resource in question that the attacked unit's faction has
|
||||
int factionTotalResource = 0;
|
||||
for(int j = 0; j < attacked->getFaction()->getTechTree()->getResourceTypeCount(); j++) {
|
||||
if(attacked->getFaction()->getTechTree()->getResourceType(j) == resource.getResourceType()) {
|
||||
factionTotalResource = attacked->getFaction()->getResource(j)->getAmount();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(resource.isNegativeAllowed()) {
|
||||
attacked->getFaction()->incResourceAmount(resource.getResourceType(), -(factionTotalResource * resource.getLossFactionPercent() / 100));
|
||||
attacked->getFaction()->incResourceAmount(resource.getResourceType(), -resource.getLossValue());
|
||||
attacker->getFaction()->incResourceAmount(resource.getResourceType(), factionTotalResource * resource.getAmountFactionPercent() / 100);
|
||||
attacker->getFaction()->incResourceAmount(resource.getResourceType(), resource.getAmountValue());
|
||||
}
|
||||
// Can't take more resources than the faction has, otherwise we end up in the negatives
|
||||
else {
|
||||
attacked->getFaction()->incResourceAmount(resource.getResourceType(), -(std::min)(factionTotalResource * resource.getLossFactionPercent() / 100, factionTotalResource));
|
||||
attacked->getFaction()->incResourceAmount(resource.getResourceType(), -(std::min)(resource.getLossValue(), factionTotalResource));
|
||||
attacker->getFaction()->incResourceAmount(resource.getResourceType(), (std::min)(factionTotalResource * resource.getAmountFactionPercent() / 100, factionTotalResource));
|
||||
attacker->getFaction()->incResourceAmount(resource.getResourceType(), (std::min)(resource.getAmountValue(), factionTotalResource));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch(this->game->getGameSettings()->getPathFinderType()) {
|
||||
case pfBasic:
|
||||
break;
|
||||
|
@ -2592,18 +2653,18 @@ void UnitUpdater::damage(Unit *attacker, const AttackSkillType* ast, Unit *attac
|
|||
//attacker->computeHp();
|
||||
}
|
||||
|
||||
void UnitUpdater::startAttackParticleSystem(Unit *unit){
|
||||
void UnitUpdater::startAttackParticleSystem(Unit *unit, float lastAnimProgress, float animProgress){
|
||||
Renderer &renderer= Renderer::getInstance();
|
||||
|
||||
ProjectileParticleSystem *psProj = 0;
|
||||
//const AttackSkillType *ast= dynamic_cast<const AttackSkillType*>(unit->getCurrSkill());
|
||||
const AttackSkillType *ast= static_cast<const AttackSkillType*>(unit->getCurrSkill());
|
||||
|
||||
const AttackSkillType *ast= dynamic_cast<const AttackSkillType*>(unit->getCurrSkill());
|
||||
if(ast == NULL) {
|
||||
throw megaglest_runtime_error("Start attack particle ast == NULL!");
|
||||
}
|
||||
ParticleSystemTypeProjectile *pstProj= ast->getProjParticleType();
|
||||
ParticleSystemTypeSplash *pstSplash= ast->getSplashParticleType();
|
||||
|
||||
ParticleSystemTypeSplash *pstSplash= ast->getSplashParticleType();
|
||||
bool hasProjectile = !ast->projectileTypes.empty();
|
||||
Vec3f startPos= unit->getCurrVector();
|
||||
Vec3f endPos= unit->getTargetVec();
|
||||
|
||||
|
@ -2615,39 +2676,51 @@ void UnitUpdater::startAttackParticleSystem(Unit *unit){
|
|||
visible = true;
|
||||
}
|
||||
|
||||
//projectile
|
||||
if(pstProj != NULL) {
|
||||
psProj= pstProj->create(unit);
|
||||
psProj->setPath(startPos, endPos);
|
||||
psProj->setObserver(new ParticleDamager(unit, this, gameCamera));
|
||||
psProj->setVisible(visible);
|
||||
if(unit->getFaction()->getTexture()) {
|
||||
psProj->setFactionColor(unit->getFaction()->getTexture()->getPixmapConst()->getPixel3f(0,0));
|
||||
//for(ProjectileParticleSystemTypes::const_iterator pit= unit->getCurrSkill()->projectileParticleSystemTypes.begin(); pit != unit->getCurrSkill()->projectileParticleSystemTypes.end(); ++pit) {
|
||||
for(ProjectileTypes::const_iterator pt= ast->projectileTypes.begin(); pt != ast->projectileTypes.end(); ++pt) {
|
||||
bool startAttackParticleSystemNow = ((*pt)->getAttackStartTime() >= lastAnimProgress && (*pt)->getAttackStartTime() < animProgress);
|
||||
if(startAttackParticleSystemNow){
|
||||
ProjectileParticleSystem *psProj= (*pt)->getProjectileParticleSystemType()->create(unit);
|
||||
psProj->setPath(startPos, endPos);
|
||||
psProj->setObserver(new ParticleDamager(unit,(*pt), this, gameCamera));
|
||||
psProj->setVisible(visible);
|
||||
if(unit->getFaction()->getTexture()) {
|
||||
psProj->setFactionColor(unit->getFaction()->getTexture()->getPixmapConst()->getPixel3f(0,0));
|
||||
}
|
||||
renderer.manageParticleSystem(psProj, rsGame);
|
||||
unit->addAttackParticleSystem(psProj);
|
||||
|
||||
if(pstSplash!=NULL){
|
||||
SplashParticleSystem *psSplash= pstSplash->create(unit);
|
||||
psSplash->setPos(endPos);
|
||||
psSplash->setVisible(visible);
|
||||
if(unit->getFaction()->getTexture()) {
|
||||
psSplash->setFactionColor(unit->getFaction()->getTexture()->getPixmapConst()->getPixel3f(0,0));
|
||||
}
|
||||
renderer.manageParticleSystem(psSplash, rsGame);
|
||||
unit->addAttackParticleSystem(psSplash);
|
||||
psProj->link(psSplash);
|
||||
}
|
||||
}
|
||||
renderer.manageParticleSystem(psProj, rsGame);
|
||||
unit->addAttackParticleSystem(psProj);
|
||||
}
|
||||
else {
|
||||
|
||||
// if no projectile, still deal damage..
|
||||
if(hasProjectile == false) {
|
||||
char szBuf[8096]="";
|
||||
snprintf(szBuf,8095,"Unit hitting [startAttackParticleSystem] no proj");
|
||||
unit->addNetworkCRCDecHp(szBuf);
|
||||
|
||||
hit(unit);
|
||||
}
|
||||
|
||||
//splash
|
||||
if(pstSplash != NULL) {
|
||||
SplashParticleSystem *psSplash= pstSplash->create(unit);
|
||||
psSplash->setPos(endPos);
|
||||
psSplash->setVisible(visible);
|
||||
if(unit->getFaction()->getTexture()) {
|
||||
psSplash->setFactionColor(unit->getFaction()->getTexture()->getPixmapConst()->getPixel3f(0,0));
|
||||
//splash
|
||||
if(pstSplash != NULL) {
|
||||
SplashParticleSystem *psSplash= pstSplash->create(unit);
|
||||
psSplash->setPos(endPos);
|
||||
psSplash->setVisible(visible);
|
||||
if(unit->getFaction()->getTexture()) {
|
||||
psSplash->setFactionColor(unit->getFaction()->getTexture()->getPixmapConst()->getPixel3f(0,0));
|
||||
}
|
||||
renderer.manageParticleSystem(psSplash, rsGame);
|
||||
unit->addAttackParticleSystem(psSplash);
|
||||
}
|
||||
renderer.manageParticleSystem(psSplash, rsGame);
|
||||
if(pstProj!=NULL){
|
||||
psProj->link(psSplash);
|
||||
}
|
||||
unit->addAttackParticleSystem(psSplash);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3204,9 +3277,10 @@ void UnitUpdater::loadGame(const XmlNode *rootNode) {
|
|||
// class ParticleDamager
|
||||
// =====================================================
|
||||
|
||||
ParticleDamager::ParticleDamager(Unit *attacker, UnitUpdater *unitUpdater, const GameCamera *gameCamera){
|
||||
ParticleDamager::ParticleDamager(Unit *attacker,const ProjectileType* projectileType, UnitUpdater *unitUpdater, const GameCamera *gameCamera){
|
||||
this->gameCamera= gameCamera;
|
||||
this->attackerRef= attacker;
|
||||
this->projectileType= projectileType;
|
||||
this->ast= static_cast<const AttackSkillType*>(attacker->getCurrSkill());
|
||||
this->targetPos= attacker->getTargetPos();
|
||||
this->targetField= attacker->getTargetField();
|
||||
|
@ -3223,17 +3297,45 @@ void ParticleDamager::update(ParticleSystem *particleSystem) {
|
|||
snprintf(szBuf,8095,"Unit hitting [ParticleDamager::update] [%s] targetField = %d",targetPos.getString().c_str(),targetField);
|
||||
attacker->addNetworkCRCDecHp(szBuf);
|
||||
|
||||
unitUpdater->hit(attacker, ast, targetPos, targetField);
|
||||
unitUpdater->hit(attacker, ast, targetPos, targetField, projectileType->getDamagePercentage());
|
||||
|
||||
//char szBuf[8096]="";
|
||||
//snprintf(szBuf,8095,"ParticleDamager::update attacker particleSystem before: %s\nafter: %s",auditBeforeHit.c_str(),particleSystem->toString().c_str());
|
||||
//attacker->setNetworkCRCParticleObserverLogInfo(szBuf);
|
||||
|
||||
//play sound
|
||||
StaticSound *projSound= ast->getProjSound();
|
||||
// Try to use the sound form the projetileType
|
||||
StaticSound *projSound=projectileType->getHitSound();
|
||||
if(projSound == NULL){
|
||||
// use the sound from the skill
|
||||
projSound= ast->getProjSound();
|
||||
}
|
||||
if(particleSystem->getVisible() && projSound != NULL) {
|
||||
SoundRenderer::getInstance().playFx(projSound, attacker->getCurrVector(), gameCamera->getPos());
|
||||
}
|
||||
|
||||
//check for spawnattack
|
||||
if(projectileType->getSpawnUnit()!="" && projectileType->getSpawnUnitcount()>0 ){
|
||||
unitUpdater->spawnAttack(attacker,projectileType->getSpawnUnit(),projectileType->getSpawnUnitcount(),projectileType->getSpawnUnitAtTarget(),targetPos);
|
||||
}
|
||||
|
||||
// check for shake and shake
|
||||
if(projectileType->isShake()==true){
|
||||
World *world=attacker->getFaction()->getWorld();
|
||||
Map* map=world->getMap();
|
||||
Game *game=world->getGame();
|
||||
|
||||
//Unit *attacked= map->getCell(targetPos)->getUnit(targetField);
|
||||
Vec2i surfaceTargetPos=Map::toSurfCoords(targetPos);
|
||||
bool visibility=(!projectileType->isShakeVisible())||(map->getSurfaceCell(surfaceTargetPos)->isVisible(world->getThisTeamIndex()) ||
|
||||
(game->getWorld()->showWorldForPlayer(game->getWorld()->getThisTeamIndex()) == true));
|
||||
|
||||
bool isInCameraView=(!projectileType->isShakeInCameraView()) || Renderer::getInstance().posInCellQuadCache(surfaceTargetPos).first;
|
||||
|
||||
if(visibility && isInCameraView) {
|
||||
game->getGameCameraPtr()->shake( projectileType->getShakeDuration(), projectileType->getShakeIntensity(),projectileType->isShakeCameraDistanceAffected(),map->getSurfaceCell(surfaceTargetPos)->getVertex());
|
||||
}
|
||||
}
|
||||
}
|
||||
particleSystem->setObserver(NULL);
|
||||
delete this;
|
||||
|
|
|
@ -103,6 +103,7 @@ public:
|
|||
|
||||
//update skills
|
||||
bool updateUnit(Unit *unit);
|
||||
void spawnAttack(Unit *unit,string spawnUnit,int spawnUnitcount,bool spawnUnitAtTarget,Vec2i targetPos=Vec2i(-10,-10));
|
||||
|
||||
//update commands
|
||||
void updateUnitCommand(Unit *unit, int frameIndex);
|
||||
|
@ -141,9 +142,9 @@ public:
|
|||
private:
|
||||
//attack
|
||||
void hit(Unit *attacker);
|
||||
void hit(Unit *attacker, const AttackSkillType* ast, const Vec2i &targetPos, Field targetField);
|
||||
void damage(Unit *attacker, const AttackSkillType* ast, Unit *attacked, float distance);
|
||||
void startAttackParticleSystem(Unit *unit);
|
||||
void hit(Unit *attacker, const AttackSkillType* ast, const Vec2i &targetPos, Field targetField, int damagePercent);
|
||||
void damage(Unit *attacker, const AttackSkillType* ast, Unit *attacked, float distance, int damagePercent);
|
||||
void startAttackParticleSystem(Unit *unit, float lastAnimProgress, float animProgress);
|
||||
|
||||
//misc
|
||||
bool searchForResource(Unit *unit, const HarvestCommandType *hct);
|
||||
|
@ -169,13 +170,14 @@ class ParticleDamager: public ParticleObserver {
|
|||
public:
|
||||
UnitReference attackerRef;
|
||||
const AttackSkillType* ast;
|
||||
const ProjectileType* projectileType;
|
||||
UnitUpdater *unitUpdater;
|
||||
const GameCamera *gameCamera;
|
||||
Vec2i targetPos;
|
||||
Field targetField;
|
||||
|
||||
public:
|
||||
ParticleDamager(Unit *attacker, UnitUpdater *unitUpdater, const GameCamera *gameCamera);
|
||||
ParticleDamager(Unit *attacker, const ProjectileType *projectileType, UnitUpdater *unitUpdater, const GameCamera *gameCamera);
|
||||
virtual void update(ParticleSystem *particleSystem);
|
||||
|
||||
virtual void saveGame(XmlNode *rootNode);
|
||||
|
|
|
@ -49,6 +49,8 @@ public:
|
|||
Vec3f pos;
|
||||
Vec3f lastPos;
|
||||
Vec3f speed;
|
||||
float speedUpRelative;
|
||||
Vec3f speedUpConstant;
|
||||
Vec3f accel;
|
||||
Vec4f color;
|
||||
float size;
|
||||
|
@ -147,6 +149,8 @@ protected:
|
|||
int varParticleEnergy;
|
||||
float particleSize;
|
||||
float speed;
|
||||
float speedUpRelative;
|
||||
float speedUpConstant;
|
||||
Vec3f factionColor;
|
||||
bool teamcolorNoEnergy;
|
||||
bool teamcolorEnergy;
|
||||
|
@ -192,6 +196,8 @@ public:
|
|||
void setVarParticleEnergy(int varParticleEnergy);
|
||||
void setParticleSize(float particleSize);
|
||||
void setSpeed(float speed);
|
||||
void setSpeedUpRelative(float speedUpRelative);
|
||||
void setSpeedUpConstant(float speedUpConstant);
|
||||
virtual void setActive(bool active);
|
||||
void setObserver(ParticleObserver *particleObserver);
|
||||
virtual void setVisible(bool visible);
|
||||
|
|
|
@ -227,7 +227,7 @@ bool EndsWith(const string &str, const string& key);
|
|||
|
||||
void endPathWithSlash(string &path, bool requireOSSlash=false);
|
||||
void trimPathWithStartingSlash(string &path);
|
||||
void updatePathClimbingParts(string &path);
|
||||
void updatePathClimbingParts(string &path,bool processPreviousDirTokenCheck=true);
|
||||
string formatPath(string path);
|
||||
|
||||
string replaceAllHTMLEntities(string& context);
|
||||
|
|
|
@ -100,10 +100,10 @@ public:
|
|||
|
||||
bool hasString(const string &key) const;
|
||||
|
||||
static bool applyTagsToValue(string &value, const std::map<string,string> *mapTagReplacementValues=NULL);
|
||||
static bool applyTagsToValue(string &value, const std::map<string,string> *mapTagReplacementValues=NULL, bool skipUpdatePathClimbingParts=false);
|
||||
static std::map<string,string> getTagReplacementValues(std::map<string,string> *mapExtraTagReplacementValues=NULL);
|
||||
static bool isValuePathVariable(const string &value);
|
||||
static void updateValuePathVariable(string &value);
|
||||
static void updateValuePathVariable(string &value, bool skipUpdatePathClimbingParts=false);
|
||||
|
||||
string getpath() const { return path;}
|
||||
|
||||
|
|
|
@ -124,7 +124,7 @@ public:
|
|||
static bool isInitialized();
|
||||
void cleanup();
|
||||
|
||||
XmlNode *load(const string &path, const std::map<string,string> &mapTagReplacementValues,bool noValidation=false,bool skipStackTrace=false);
|
||||
XmlNode *load(const string &path, const std::map<string,string> &mapTagReplacementValues,bool noValidation=false,bool skipStackTrace=false,bool skipUpdatePathClimbingParts=false);
|
||||
void save(const string &path, const XmlNode *node);
|
||||
};
|
||||
|
||||
|
@ -138,6 +138,7 @@ private:
|
|||
string loadPath;
|
||||
xml_engine_parser_type engine_type;
|
||||
bool skipStackCheck;
|
||||
bool skipUpdatePathClimbingParts;
|
||||
private:
|
||||
XmlTree(XmlTree&);
|
||||
void operator =(XmlTree&);
|
||||
|
@ -147,6 +148,7 @@ public:
|
|||
XmlTree(xml_engine_parser_type engine_type = XML_RAPIDXML_ENGINE);
|
||||
~XmlTree();
|
||||
|
||||
void setSkipUpdatePathClimbingParts(bool value);
|
||||
void init(const string &name);
|
||||
void load(const string &path, const std::map<string,string> &mapTagReplacementValues, bool noValidation=false,bool skipStackCheck=false,bool skipStackTrace=false);
|
||||
void save(const string &path);
|
||||
|
@ -182,7 +184,7 @@ public:
|
|||
|
||||
#endif
|
||||
|
||||
XmlNode(xml_node<> *node, const std::map<string,string> &mapTagReplacementValues);
|
||||
XmlNode(xml_node<> *node, const std::map<string,string> &mapTagReplacementValues,bool skipUpdatePathClimbingParts=false);
|
||||
XmlNode(const string &name);
|
||||
~XmlNode();
|
||||
|
||||
|
|
|
@ -50,6 +50,10 @@ void Particle::saveGame(XmlNode *rootNode) {
|
|||
particleNode->addAttribute("lastPos",lastPos.getString(), mapTagReplacements);
|
||||
// Vec3f speed;
|
||||
particleNode->addAttribute("speed",speed.getString(), mapTagReplacements);
|
||||
// Vec3f speedUpRelative;
|
||||
particleNode->addAttribute("speedUpRelative",floatToStr(speedUpRelative,6), mapTagReplacements);
|
||||
// Vec3f speedUpConstant;
|
||||
particleNode->addAttribute("speedUpConstant",speedUpConstant.getString(), mapTagReplacements);
|
||||
// Vec3f accel;
|
||||
particleNode->addAttribute("accel",accel.getString(), mapTagReplacements);
|
||||
// Vec4f color;
|
||||
|
@ -70,6 +74,10 @@ void Particle::loadGame(const XmlNode *rootNode) {
|
|||
lastPos = Vec3f::strToVec3(particleNode->getAttribute("lastPos")->getValue());
|
||||
// Vec3f speed;
|
||||
speed = Vec3f::strToVec3(particleNode->getAttribute("speed")->getValue());
|
||||
// Vec3f speed;
|
||||
speedUpRelative = particleNode->getAttribute("speedUpRelative")->getFloatValue();
|
||||
// Vec3f speed;
|
||||
speedUpConstant = Vec3f::strToVec3(particleNode->getAttribute("speedUpConstant")->getValue());
|
||||
// Vec3f accel;
|
||||
accel = Vec3f::strToVec3(particleNode->getAttribute("accel")->getValue());
|
||||
// Vec4f color;
|
||||
|
@ -290,6 +298,16 @@ void ParticleSystem::setSpeed(float speed){
|
|||
this->speed = truncateDecimal<float>(this->speed,6);
|
||||
}
|
||||
|
||||
void ParticleSystem::setSpeedUpRelative(float speedUpRelative){
|
||||
this->speedUpRelative= speedUpRelative;
|
||||
this->speedUpRelative = truncateDecimal<float>(this->speedUpRelative,6);
|
||||
}
|
||||
|
||||
void ParticleSystem::setSpeedUpConstant(float speedUpConstant){
|
||||
this->speedUpConstant= speedUpConstant;
|
||||
this->speedUpConstant = truncateDecimal<float>(this->speedUpConstant,6);
|
||||
}
|
||||
|
||||
void ParticleSystem::setActive(bool active){
|
||||
this->active= active;
|
||||
for(int i=getChildCount()-1; i>=0; i--)
|
||||
|
@ -1114,6 +1132,7 @@ void UnitParticleSystem::initParticle(Particle *p, int particleIndex){
|
|||
p->lastPos= pos;
|
||||
oldPosition= pos;
|
||||
p->size= particleSize;
|
||||
p->speedUpRelative= speedUpRelative;
|
||||
p->accel= Vec3f(0.0f, -gravity, 0.0f);
|
||||
p->accel.x = truncateDecimal<float>(p->accel.x,6);
|
||||
p->accel.y = truncateDecimal<float>(p->accel.y,6);
|
||||
|
@ -1228,6 +1247,8 @@ void UnitParticleSystem::initParticle(Particle *p, int particleIndex){
|
|||
} break;
|
||||
default: throw megaglest_runtime_error("bad shape");
|
||||
}
|
||||
//need to do that down here because we need p->speed for it.
|
||||
p->speedUpConstant= Vec3f(speedUpConstant)*p->speed;
|
||||
}
|
||||
|
||||
void UnitParticleSystem::update(){
|
||||
|
@ -1299,6 +1320,8 @@ void UnitParticleSystem::updateParticle(Particle *p){
|
|||
p->pos.z = truncateDecimal<float>(p->pos.z,6);
|
||||
}
|
||||
p->speed += p->accel;
|
||||
p->speed += p->speedUpConstant;
|
||||
p->speed=p->speed*(1+p->speedUpRelative);
|
||||
p->speed.x = truncateDecimal<float>(p->speed.x,6);
|
||||
p->speed.y = truncateDecimal<float>(p->speed.y,6);
|
||||
p->speed.z = truncateDecimal<float>(p->speed.z,6);
|
||||
|
@ -2220,6 +2243,7 @@ void SplashParticleSystem::initParticle(Particle *p, int particleIndex){
|
|||
p->energy= maxParticleEnergy;
|
||||
p->size= particleSize;
|
||||
p->color= color;
|
||||
p->speedUpRelative= speedUpRelative;
|
||||
|
||||
p->speed= Vec3f(horizontalSpreadA * random.randRange(-1.0f, 1.0f) + horizontalSpreadB, verticalSpreadA
|
||||
* random.randRange(-1.0f, 1.0f) + verticalSpreadB, horizontalSpreadA * random.randRange(-1.0f, 1.0f)
|
||||
|
@ -2243,6 +2267,7 @@ void SplashParticleSystem::initParticle(Particle *p, int particleIndex){
|
|||
p->accel.y = truncateDecimal<float>(p->accel.y,6);
|
||||
p->accel.z = truncateDecimal<float>(p->accel.z,6);
|
||||
|
||||
p->speedUpConstant= Vec3f(speedUpConstant)*p->speed;
|
||||
}
|
||||
|
||||
void SplashParticleSystem::updateParticle(Particle *p){
|
||||
|
@ -2254,6 +2279,8 @@ void SplashParticleSystem::updateParticle(Particle *p){
|
|||
p->pos.y = truncateDecimal<float>(p->pos.y,6);
|
||||
p->pos.z = truncateDecimal<float>(p->pos.z,6);
|
||||
|
||||
p->speed += p->speedUpConstant;
|
||||
p->speed=p->speed*(1+p->speedUpRelative);
|
||||
p->speed= p->speed + p->accel;
|
||||
p->speed.x = truncateDecimal<float>(p->speed.x,6);
|
||||
p->speed.y = truncateDecimal<float>(p->speed.y,6);
|
||||
|
|
|
@ -561,7 +561,7 @@ void trimPathWithStartingSlash(string &path) {
|
|||
}
|
||||
}
|
||||
|
||||
void updatePathClimbingParts(string &path) {
|
||||
void updatePathClimbingParts(string &path,bool processPreviousDirTokenCheck) {
|
||||
// Update paths with /./
|
||||
string::size_type pos = path.find("/./");
|
||||
if(pos != string::npos && pos != 0) {
|
||||
|
@ -569,9 +569,11 @@ void updatePathClimbingParts(string &path) {
|
|||
path.erase(pos,2);
|
||||
//pos--;
|
||||
|
||||
//printf("#1 CHANGE relative path from [%s] to [%s]\n",orig.c_str(),path.c_str());
|
||||
|
||||
pos = path.find("/./");
|
||||
if(pos != string::npos && pos != 0) {
|
||||
updatePathClimbingParts(path);
|
||||
updatePathClimbingParts(path, processPreviousDirTokenCheck);
|
||||
}
|
||||
|
||||
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("CHANGED relative path from [%s] to [%s]\n",orig.c_str(),path.c_str());
|
||||
|
@ -581,39 +583,65 @@ void updatePathClimbingParts(string &path) {
|
|||
string orig = path;
|
||||
path.erase(pos,2);
|
||||
//pos--;
|
||||
//printf("#w CHANGE relative path from [%s] to [%s]\n",orig.c_str(),path.c_str());
|
||||
|
||||
pos = path.find("\\.\\");
|
||||
if(pos != string::npos && pos != 0) {
|
||||
updatePathClimbingParts(path);
|
||||
updatePathClimbingParts(path, processPreviousDirTokenCheck);
|
||||
}
|
||||
|
||||
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("CHANGED relative path from [%s] to [%s]\n",orig.c_str(),path.c_str());
|
||||
}
|
||||
|
||||
// Update paths with ..
|
||||
pos = path.find("..");
|
||||
if(pos != string::npos && pos != 0) {
|
||||
string orig = path;
|
||||
path.erase(pos,2);
|
||||
pos--;
|
||||
if(path[pos] == '/' || path[pos] == '\\') {
|
||||
path.erase(pos,1);
|
||||
}
|
||||
|
||||
for(int x = (int)pos; x >= 0; --x) {
|
||||
//printf("x [%d][%c] pos [%ld][%c] [%s]\n",x,path[x],(long int)pos,path[pos],path.substr(0,x+1).c_str());
|
||||
|
||||
if((path[x] == '/' || path[x] == '\\') && x != (int)pos) {
|
||||
path.erase(x,pos-x);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(processPreviousDirTokenCheck) {
|
||||
pos = path.find("..");
|
||||
if(pos != string::npos && pos != 0) {
|
||||
updatePathClimbingParts(path);
|
||||
}
|
||||
|
||||
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("CHANGED relative path from [%s] to [%s]\n",orig.c_str(),path.c_str());
|
||||
string orig = path;
|
||||
if(path[pos-1] != ' ' || (path.length() > 2 && path[pos+2] != ' ')) {
|
||||
path.erase(pos,2);
|
||||
|
||||
//printf("#3 [%d] CHANGE relative path from [%s] to [%s]\n",(int)pos,orig.c_str(),path.c_str());
|
||||
|
||||
pos--;
|
||||
//pos = pos -1;
|
||||
|
||||
//printf("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #3b [%d]\n",(int)pos);
|
||||
|
||||
if(path[pos] == '/' || path[pos] == '\\') {
|
||||
path.erase(pos,1);
|
||||
|
||||
//printf("#4 CHANGE relative path from [%s] to [%s]\n",orig.c_str(),path.c_str());
|
||||
}
|
||||
|
||||
for(int x = (int)pos; x >= 0; --x) {
|
||||
//printf("x [%d][%c] pos [%ld][%c] [%s]\n",x,path[x],(long int)pos,path[pos],path.substr(0,x+1).c_str());
|
||||
|
||||
if((path[x] == '/' || path[x] == '\\') && x != (int)pos) {
|
||||
string origLoop = path;
|
||||
path.erase(x,(int)pos-x);
|
||||
|
||||
//printf("#5 [%d] [%d] [%d] CHANGE relative path from [%s] to [%s]\n",(int)pos,(int)x,(int)origLoop.length(),origLoop.c_str(),path.c_str());
|
||||
break;
|
||||
}
|
||||
}
|
||||
pos = path.find("..");
|
||||
}
|
||||
else {
|
||||
//printf("#6a [%d]\n",(int)pos);
|
||||
|
||||
//pos = path.find("..",pos+1);
|
||||
pos = string::npos;
|
||||
|
||||
//printf("#6b [%d]\n",(int)pos);
|
||||
}
|
||||
if(pos != string::npos && pos != 0) {
|
||||
updatePathClimbingParts(path,processPreviousDirTokenCheck);
|
||||
}
|
||||
|
||||
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("CHANGED relative path from [%s] to [%s]\n",orig.c_str(),path.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -317,47 +317,47 @@ void event_channel(irc_session_t * session, const char * event, const char * ori
|
|||
}
|
||||
}
|
||||
|
||||
if ( !strcmp (params[1], "quit") )
|
||||
irc_cmd_quit (session, "of course, Master!");
|
||||
|
||||
if ( !strcmp (params[1], "help") ) {
|
||||
irc_cmd_msg (session, params[0], "quit, help, dcc chat, dcc send, ctcp");
|
||||
}
|
||||
|
||||
if ( !strcmp (params[1], "ctcp") ) {
|
||||
irc_cmd_ctcp_request (session, realNick, "PING 223");
|
||||
irc_cmd_ctcp_request (session, realNick, "FINGER");
|
||||
irc_cmd_ctcp_request (session, realNick, "VERSION");
|
||||
irc_cmd_ctcp_request (session, realNick, "TIME");
|
||||
}
|
||||
|
||||
if ( !strcmp (params[1], "dcc chat") ) {
|
||||
irc_dcc_t dccid;
|
||||
irc_dcc_chat (session, 0, realNick, dcc_recv_callback, &dccid);
|
||||
if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("DCC chat ID: %d\n", dccid);
|
||||
}
|
||||
|
||||
if ( !strcmp (params[1], "dcc send") ) {
|
||||
irc_dcc_t dccid;
|
||||
irc_dcc_sendfile (session, 0, realNick, "irctest.c", dcc_file_recv_callback, &dccid);
|
||||
if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("DCC send ID: %d\n", dccid);
|
||||
}
|
||||
|
||||
if ( !strcmp (params[1], "topic") ) {
|
||||
irc_cmd_topic (session, params[0], 0);
|
||||
}
|
||||
else if ( strstr (params[1], "topic ") == params[1] ) {
|
||||
irc_cmd_topic (session, params[0], params[1] + 6);
|
||||
}
|
||||
|
||||
if ( strstr (params[1], "mode ") == params[1] )
|
||||
irc_cmd_channel_mode (session, params[0], params[1] + 5);
|
||||
|
||||
if ( strstr (params[1], "nick ") == params[1] )
|
||||
irc_cmd_nick (session, params[1] + 5);
|
||||
|
||||
if ( strstr (params[1], "whois ") == params[1] )
|
||||
irc_cmd_whois (session, params[1] + 5);
|
||||
// if ( !strcmp (params[1], "quit") )
|
||||
// irc_cmd_quit (session, "of course, Master!");
|
||||
//
|
||||
// if ( !strcmp (params[1], "help") ) {
|
||||
// irc_cmd_msg (session, params[0], "quit, help, dcc chat, dcc send, ctcp");
|
||||
// }
|
||||
//
|
||||
// if ( !strcmp (params[1], "ctcp") ) {
|
||||
// irc_cmd_ctcp_request (session, realNick, "PING 223");
|
||||
// irc_cmd_ctcp_request (session, realNick, "FINGER");
|
||||
// irc_cmd_ctcp_request (session, realNick, "VERSION");
|
||||
// irc_cmd_ctcp_request (session, realNick, "TIME");
|
||||
// }
|
||||
//
|
||||
// if ( !strcmp (params[1], "dcc chat") ) {
|
||||
// irc_dcc_t dccid;
|
||||
// irc_dcc_chat (session, 0, realNick, dcc_recv_callback, &dccid);
|
||||
// if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("DCC chat ID: %d\n", dccid);
|
||||
// }
|
||||
//
|
||||
// if ( !strcmp (params[1], "dcc send") ) {
|
||||
// irc_dcc_t dccid;
|
||||
// irc_dcc_sendfile (session, 0, realNick, "irctest.c", dcc_file_recv_callback, &dccid);
|
||||
// if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("DCC send ID: %d\n", dccid);
|
||||
// }
|
||||
//
|
||||
// if ( !strcmp (params[1], "topic") ) {
|
||||
// irc_cmd_topic (session, params[0], 0);
|
||||
// }
|
||||
// else if ( strstr (params[1], "topic ") == params[1] ) {
|
||||
// irc_cmd_topic (session, params[0], params[1] + 6);
|
||||
// }
|
||||
//
|
||||
// if ( strstr (params[1], "mode ") == params[1] )
|
||||
// irc_cmd_channel_mode (session, params[0], params[1] + 5);
|
||||
//
|
||||
// if ( strstr (params[1], "nick ") == params[1] )
|
||||
// irc_cmd_nick (session, params[1] + 5);
|
||||
//
|
||||
// if ( strstr (params[1], "whois ") == params[1] )
|
||||
// irc_cmd_whois (session, params[1] + 5);
|
||||
}
|
||||
|
||||
void irc_event_dcc_chat(irc_session_t * session, const char * nick, const char * addr, irc_dcc_t dccid) {
|
||||
|
|
|
@ -285,13 +285,15 @@ bool Properties::isValuePathVariable(const string &value) {
|
|||
}
|
||||
return false;
|
||||
}
|
||||
void Properties::updateValuePathVariable(string &value) {
|
||||
void Properties::updateValuePathVariable(string &value, bool skipUpdatePathClimbingParts) {
|
||||
replaceAll(value,"//","/");
|
||||
replaceAll(value,"\\\\","\\");
|
||||
updatePathClimbingParts(value);
|
||||
if(skipUpdatePathClimbingParts == false) {
|
||||
updatePathClimbingParts(value);
|
||||
}
|
||||
}
|
||||
|
||||
bool Properties::applyTagsToValue(string &value, const std::map<string,string> *mapTagReplacementValues) {
|
||||
bool Properties::applyTagsToValue(string &value, const std::map<string,string> *mapTagReplacementValues,bool skipUpdatePathClimbingParts) {
|
||||
string originalValue = value;
|
||||
bool valueRequiresPathUpdate = Properties::isValuePathVariable(value);
|
||||
//if(originalValue.find("$APPLICATIONDATAPATH") != string::npos) {
|
||||
|
@ -389,7 +391,7 @@ bool Properties::applyTagsToValue(string &value, const std::map<string,string> *
|
|||
//}
|
||||
|
||||
if(valueRequiresPathUpdate == true) {
|
||||
Properties::updateValuePathVariable(value);
|
||||
Properties::updateValuePathVariable(value, skipUpdatePathClimbingParts);
|
||||
}
|
||||
return (originalValue != value);
|
||||
}
|
||||
|
|
|
@ -339,7 +339,8 @@ XmlIoRapid::~XmlIoRapid() {
|
|||
cleanup();
|
||||
}
|
||||
|
||||
XmlNode *XmlIoRapid::load(const string &path, const std::map<string,string> &mapTagReplacementValues,bool noValidation,bool skipStackTrace) {
|
||||
XmlNode *XmlIoRapid::load(const string &path, const std::map<string,string> &mapTagReplacementValues,
|
||||
bool noValidation,bool skipStackTrace,bool skipUpdatePathClimbingParts) {
|
||||
bool showPerfStats = SystemFlags::VERBOSE_MODE_ENABLED;
|
||||
Chrono chrono;
|
||||
chrono.start();
|
||||
|
@ -388,7 +389,7 @@ XmlNode *XmlIoRapid::load(const string &path, const std::map<string,string> &map
|
|||
|
||||
// Load data and add terminating 0
|
||||
vector<char> buffer;
|
||||
buffer.resize((unsigned int)file_size + 1);
|
||||
buffer.resize((unsigned int)file_size + 100);
|
||||
xmlFile.read(&buffer.front(), static_cast<streamsize>(file_size));
|
||||
buffer[(unsigned int)file_size] = 0;
|
||||
|
||||
|
@ -405,7 +406,7 @@ XmlNode *XmlIoRapid::load(const string &path, const std::map<string,string> &map
|
|||
|
||||
if(showPerfStats) printf("In [%s::%s Line: %d] took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis());
|
||||
|
||||
rootNode= new XmlNode(doc.first_node(),mapTagReplacementValues);
|
||||
rootNode= new XmlNode(doc.first_node(),mapTagReplacementValues, skipUpdatePathClimbingParts);
|
||||
|
||||
if(showPerfStats) printf("In [%s::%s Line: %d] took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis());
|
||||
|
||||
|
@ -522,6 +523,7 @@ XmlTree::XmlTree(xml_engine_parser_type engine_type) {
|
|||
|
||||
this->engine_type = engine_type;
|
||||
this->skipStackCheck = false;
|
||||
this->skipUpdatePathClimbingParts = false;
|
||||
}
|
||||
|
||||
void XmlTree::init(const string &name){
|
||||
|
@ -533,6 +535,10 @@ typedef std::vector<XmlTree*> LoadStack;
|
|||
//static LoadStack loadStack;
|
||||
static string loadStackCacheName = string(__FILE__) + string("_loadStackCacheName");
|
||||
|
||||
void XmlTree::setSkipUpdatePathClimbingParts(bool value) {
|
||||
this->skipUpdatePathClimbingParts = value;
|
||||
}
|
||||
|
||||
void XmlTree::load(const string &path, const std::map<string,string> &mapTagReplacementValues, bool noValidation,bool skipStackCheck,bool skipStackTrace) {
|
||||
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] about to load [%s] skipStackCheck = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,path.c_str(),skipStackCheck);
|
||||
|
||||
|
@ -565,7 +571,7 @@ void XmlTree::load(const string &path, const std::map<string,string> &mapTagRepl
|
|||
else
|
||||
#endif
|
||||
{
|
||||
this->rootNode= XmlIoRapid::getInstance().load(path, mapTagReplacementValues, noValidation,skipStackTrace);
|
||||
this->rootNode= XmlIoRapid::getInstance().load(path, mapTagReplacementValues, noValidation,skipStackTrace, this->skipUpdatePathClimbingParts);
|
||||
}
|
||||
|
||||
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] about to load [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,path.c_str());
|
||||
|
@ -661,7 +667,8 @@ XmlNode::XmlNode(DOMNode *node, const std::map<string,string> &mapTagReplacement
|
|||
|
||||
#endif
|
||||
|
||||
XmlNode::XmlNode(xml_node<> *node, const std::map<string,string> &mapTagReplacementValues) : superNode(NULL) {
|
||||
XmlNode::XmlNode(xml_node<> *node, const std::map<string,string> &mapTagReplacementValues,
|
||||
bool skipUpdatePathClimbingParts) : superNode(NULL) {
|
||||
if(node == NULL || node->name() == NULL) {
|
||||
throw megaglest_runtime_error("XML structure seems to be corrupt!");
|
||||
}
|
||||
|
@ -682,7 +689,7 @@ XmlNode::XmlNode(xml_node<> *node, const std::map<string,string> &mapTagReplacem
|
|||
for(xml_node<> *currentNode = node->first_node();
|
||||
currentNode; currentNode = currentNode->next_sibling()) {
|
||||
if(currentNode != NULL && currentNode->type() == node_element) {
|
||||
XmlNode *xmlNode= new XmlNode(currentNode, mapTagReplacementValues);
|
||||
XmlNode *xmlNode= new XmlNode(currentNode, mapTagReplacementValues, skipUpdatePathClimbingParts);
|
||||
children.push_back(xmlNode);
|
||||
}
|
||||
}
|
||||
|
@ -696,8 +703,18 @@ XmlNode::XmlNode(xml_node<> *node, const std::map<string,string> &mapTagReplacem
|
|||
|
||||
//get value
|
||||
if(node->type() == node_element && children.size() == 0) {
|
||||
text = node->value();
|
||||
Properties::applyTagsToValue(this->text,&mapTagReplacementValues);
|
||||
string xmlText = node->value();
|
||||
|
||||
bool debugReplace = false;
|
||||
// if(xmlText.find("{SCENARIOPATH}") != string::npos) {
|
||||
// printf("\n----------------------\n** XML!! WILL REPLACE [%s]\n",xmlText.c_str());
|
||||
// debugReplace = true;
|
||||
// }
|
||||
Properties::applyTagsToValue(xmlText,&mapTagReplacementValues, skipUpdatePathClimbingParts);
|
||||
if(debugReplace) {
|
||||
printf("\n\n** XML!! REPLACED WITH [%s]\n===================\n",xmlText.c_str());
|
||||
}
|
||||
text = xmlText;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue