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)
|
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)")
|
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()
|
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()
|
||||||
ENDIF()
|
ENDIF()
|
||||||
SET(CUSTOM_DATA_INSTALL_PATH_VALUE "-DCUSTOM_DATA_INSTALL_PATH=${CUSTOM_DATA_INSTALL_PATH}")
|
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_DATADIR ${CUSTOM_DATA_INSTALL_PATH_VALUE})
|
||||||
SET(PKG_BINDIR ${MEGAGLEST_BIN_INSTALL_PATH})
|
SET(PKG_BINDIR ${MEGAGLEST_BIN_INSTALL_PATH})
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 7de4b4b6d02ae1933e3964cc02d31aa288d49463
|
Subproject commit 4f05a0177385ce47eb4cfcf5ce6676f59b290d37
|
|
@ -54,11 +54,11 @@ fi
|
||||||
cd $PROJDIR
|
cd $PROJDIR
|
||||||
echo "copying binaries ..."
|
echo "copying binaries ..."
|
||||||
cp -r lib/* "$RELEASEDIR/lib"
|
cp -r lib/* "$RELEASEDIR/lib"
|
||||||
cp *.ico "$RELEASEDIR/"
|
cp {../shared/,}*.ico "$RELEASEDIR/"
|
||||||
cp *.bmp "$RELEASEDIR/"
|
cp *.bmp "$RELEASEDIR/"
|
||||||
cp *.png "$RELEASEDIR/"
|
cp *.png "$RELEASEDIR/"
|
||||||
cp *.xpm "$RELEASEDIR/"
|
cp *.xpm "$RELEASEDIR/"
|
||||||
cp *.ini "$RELEASEDIR/"
|
cp {../shared/,}*.ini "$RELEASEDIR/"
|
||||||
cp megaglest "$RELEASEDIR/"
|
cp megaglest "$RELEASEDIR/"
|
||||||
cp megaglest_editor "$RELEASEDIR/"
|
cp megaglest_editor "$RELEASEDIR/"
|
||||||
cp megaglest_g3dviewer "$RELEASEDIR/"
|
cp megaglest_g3dviewer "$RELEASEDIR/"
|
||||||
|
|
|
@ -148,7 +148,7 @@ case $distribution in
|
||||||
$installcommand
|
$installcommand
|
||||||
if [ $? != 0 ]; then error_during_installation; exit 1; fi
|
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='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
|
$installcommand
|
||||||
if [ $? != 0 ]; then error_during_installation; exit 1; fi
|
if [ $? != 0 ]; then error_during_installation; exit 1; fi
|
||||||
|
@ -167,7 +167,7 @@ case $distribution in
|
||||||
fi
|
fi
|
||||||
case $release in
|
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='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
|
$installcommand
|
||||||
if [ $? != 0 ]; then error_during_installation; exit 1; fi
|
if [ $? != 0 ]; then error_during_installation; exit 1; fi
|
||||||
|
@ -180,7 +180,7 @@ case $distribution in
|
||||||
esac
|
esac
|
||||||
;;
|
;;
|
||||||
|
|
||||||
SuSE|SUSE?LINUX|Opensuse)
|
SuSE|SUSE?LINUX|Opensuse*|openSUSE*)
|
||||||
case $release in
|
case $release in
|
||||||
11.2|11.3|11.4|12.1)
|
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'
|
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
|
$installcommand
|
||||||
if [ $? != 0 ]; then error_during_installation; exit 1; fi
|
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'
|
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
|
unsupported_release
|
||||||
|
|
|
@ -269,6 +269,7 @@
|
||||||
<ClCompile Include="..\..\source\glest_game\types\object_type.cpp" />
|
<ClCompile Include="..\..\source\glest_game\types\object_type.cpp" />
|
||||||
<ClCompile Include="..\..\source\glest_game\types\resource_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\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\tech_tree.cpp" />
|
||||||
<ClCompile Include="..\..\source\glest_game\types\unit_type.cpp" />
|
<ClCompile Include="..\..\source\glest_game\types\unit_type.cpp" />
|
||||||
<ClCompile Include="..\..\source\glest_game\types\upgrade_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\object_type.h" />
|
||||||
<ClInclude Include="..\..\source\glest_game\types\resource_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\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\tech_tree.h" />
|
||||||
<ClInclude Include="..\..\source\glest_game\types\unit_type.h" />
|
<ClInclude Include="..\..\source\glest_game\types\unit_type.h" />
|
||||||
<ClInclude Include="..\..\source\glest_game\types\upgrade_type.h" />
|
<ClInclude Include="..\..\source\glest_game\types\upgrade_type.h" />
|
||||||
|
|
|
@ -1 +1,3 @@
|
||||||
/windows_deps*/
|
/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;
|
*unitIndex= -1;
|
||||||
for(int i=0; i<aiInterface->getMyUnitCount(); ++i){
|
for(int i=0; i<aiInterface->getMyUnitCount(); ++i){
|
||||||
const Unit *unit= aiInterface->getMyUnit(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){
|
if(!idleOnly || !unit->anyCommand() || unit->getCurrCommand()->getCommandType()->getClass()==ccStop){
|
||||||
units.push_back(i);
|
units.push_back(i);
|
||||||
}
|
}
|
||||||
|
@ -553,55 +553,57 @@ vector<int> Ai::findUnitsHarvestingResourceType(const ResourceType *rt) {
|
||||||
Map *map= aiInterface->getMap();
|
Map *map= aiInterface->getMap();
|
||||||
for(int i = 0; i < aiInterface->getMyUnitCount(); ++i) {
|
for(int i = 0; i < aiInterface->getMyUnitCount(); ++i) {
|
||||||
const Unit *unit= aiInterface->getMyUnit(i);
|
const Unit *unit= aiInterface->getMyUnit(i);
|
||||||
if(unit->getType()->hasCommandClass(ccHarvest)) {
|
if(unit->getType()->isCommandable()) {
|
||||||
if(unit->anyCommand() && unit->getCurrCommand()->getCommandType()->getClass() == ccHarvest) {
|
if(unit->getType()->hasCommandClass(ccHarvest)) {
|
||||||
Command *command= unit->getCurrCommand();
|
if(unit->anyCommand() && unit->getCurrCommand()->getCommandType()->getClass() == ccHarvest) {
|
||||||
const HarvestCommandType *hct= dynamic_cast<const HarvestCommandType*>(command->getCommandType());
|
Command *command= unit->getCurrCommand();
|
||||||
if(hct != NULL) {
|
const HarvestCommandType *hct= dynamic_cast<const HarvestCommandType*>(command->getCommandType());
|
||||||
const Vec2i unitTargetPos = unit->getTargetPos();
|
if(hct != NULL) {
|
||||||
SurfaceCell *sc= map->getSurfaceCell(Map::toSurfCoords(unitTargetPos));
|
const Vec2i unitTargetPos = unit->getTargetPos();
|
||||||
Resource *r= sc->getResource();
|
SurfaceCell *sc= map->getSurfaceCell(Map::toSurfCoords(unitTargetPos));
|
||||||
if (r != NULL && r->getType() == rt) {
|
Resource *r= sc->getResource();
|
||||||
units.push_back(i);
|
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
else if(unit->getType()->hasCommandClass(ccProduce)) {
|
||||||
else if(unit->getType()->hasCommandClass(ccBuild)) {
|
if(unit->anyCommand() && unit->getCurrCommand()->getCommandType()->getClass() == ccProduce) {
|
||||||
if(unit->anyCommand() && unit->getCurrCommand()->getCommandType()->getClass() == ccBuild) {
|
Command *command= unit->getCurrCommand();
|
||||||
Command *command= unit->getCurrCommand();
|
const ProduceCommandType *pct= dynamic_cast<const ProduceCommandType*>(command->getCommandType());
|
||||||
const BuildCommandType *bct= dynamic_cast<const BuildCommandType*>(command->getCommandType());
|
if(pct != NULL) {
|
||||||
if(bct != NULL) {
|
const UnitType *ut = pct->getProducedUnit();
|
||||||
for(int j = 0; j < bct->getBuildingCount(); ++j) {
|
|
||||||
const UnitType *ut = bct->getBuilding(j);
|
|
||||||
if(ut != NULL) {
|
if(ut != NULL) {
|
||||||
const Resource *r = ut->getCost(rt);
|
const Resource *r = ut->getCost(rt);
|
||||||
if(r != NULL) {
|
if(r != NULL) {
|
||||||
if (r != NULL && r->getAmount() < 0) {
|
if (r != NULL && r->getAmount() < 0) {
|
||||||
units.push_back(i);
|
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) {
|
for(int i = 0; i < aiInterface->getMyUnitCount(); ++i) {
|
||||||
const Unit *unit= aiInterface->getMyUnit(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) {
|
if(unit->anyCommand() && unit->getCurrCommand()->getCommandType()->getClass() == currentCommand) {
|
||||||
units.push_back(i);
|
units.push_back(i);
|
||||||
}
|
}
|
||||||
|
@ -630,7 +632,7 @@ bool Ai::findAbleUnit(int *unitIndex, CommandClass ability, CommandClass current
|
||||||
*unitIndex= -1;
|
*unitIndex= -1;
|
||||||
for(int i=0; i<aiInterface->getMyUnitCount(); ++i){
|
for(int i=0; i<aiInterface->getMyUnitCount(); ++i){
|
||||||
const Unit *unit= aiInterface->getMyUnit(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){
|
if(unit->anyCommand() && unit->getCurrCommand()->getCommandType()->getClass()==currentCommand){
|
||||||
units.push_back(i);
|
units.push_back(i);
|
||||||
}
|
}
|
||||||
|
|
|
@ -103,21 +103,29 @@ void ChatManager::keyDown(SDL_KeyboardEvent key) {
|
||||||
Config &configKeys = Config::getInstance(std::pair<ConfigType,ConfigType>(cfgMainKeys,cfgUserKeys));
|
Config &configKeys = Config::getInstance(std::pair<ConfigType,ConfigType>(cfgMainKeys,cfgUserKeys));
|
||||||
|
|
||||||
//toggle team mode
|
//toggle team mode
|
||||||
if(editEnabled == false && disableTeamMode == false &&
|
if(editEnabled == false &&
|
||||||
isKeyPressed(configKeys.getSDLKey("ChatTeamMode"),key) == true) {
|
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 (!inMenu) {
|
||||||
if (teamMode == true) {
|
if (teamMode == true) {
|
||||||
teamMode = false;
|
teamMode = false;
|
||||||
console->addLine(lang.getString("ChatMode") + ": " + lang.getString("All"));
|
console->addLine(lang.getString("ChatMode") + ": " + lang.getString("All"));
|
||||||
} else {
|
} else {
|
||||||
teamMode = true;
|
teamMode = true;
|
||||||
console->addLine(lang.getString("ChatMode") + ": " + lang.getString("Team"));
|
console->addLine(lang.getString("ChatMode") + ": " + lang.getString("Team"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if(isKeyPressed(SDLK_RETURN,key, false) == true) {
|
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);
|
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) {
|
for(int i = 0; i < world.getFactionCount(); ++i) {
|
||||||
string factionInfo = this->gameSettings.getNetworkPlayerName(i);
|
string factionInfo = this->gameSettings.getNetworkPlayerName(i);
|
||||||
//factionInfo += " [" + this->gameSettings.getNetworkPlayerUUID(i) + "]";
|
//factionInfo += " [" + this->gameSettings.getNetworkPlayerUUID(i) + "]";
|
||||||
|
float multi=world.getStats()->getResourceMultiplier(i);
|
||||||
|
string multiplier="["+floatToStr(multi,1)+"]";
|
||||||
switch(this->gameSettings.getFactionControl(i)) {
|
switch(this->gameSettings.getFactionControl(i)) {
|
||||||
case ctCpuEasy:
|
case ctCpuEasy:
|
||||||
factionInfo += " CPU Easy";
|
factionInfo += " CPU Easy"+multiplier;
|
||||||
break;
|
break;
|
||||||
case ctCpu:
|
case ctCpu:
|
||||||
factionInfo += " CPU Normal";
|
factionInfo += " CPU Normal"+multiplier;
|
||||||
break;
|
break;
|
||||||
case ctCpuUltra:
|
case ctCpuUltra:
|
||||||
factionInfo += " CPU Ultra";
|
factionInfo += " CPU Ultra"+multiplier;
|
||||||
break;
|
break;
|
||||||
case ctCpuMega:
|
case ctCpuMega:
|
||||||
factionInfo += " CPU Mega";
|
factionInfo += " CPU Mega"+multiplier;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1531,6 +1531,12 @@ int ScriptManager::getUnitFaction(int unitId) {
|
||||||
const string ScriptManager::getUnitName(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__);
|
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);
|
return world->getUnitName(unitId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3414,6 +3420,7 @@ int ScriptManager::getUnitFaction(LuaHandle* luaHandle){
|
||||||
|
|
||||||
return luaArguments.getReturnCount();
|
return luaArguments.getReturnCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
int ScriptManager::getUnitName(LuaHandle* luaHandle){
|
int ScriptManager::getUnitName(LuaHandle* luaHandle){
|
||||||
LuaArguments luaArguments(luaHandle);
|
LuaArguments luaArguments(luaHandle);
|
||||||
try {
|
try {
|
||||||
|
@ -3435,6 +3442,28 @@ int ScriptManager::getUnitName(LuaHandle* luaHandle){
|
||||||
return luaArguments.getReturnCount();
|
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){
|
int ScriptManager::getResourceAmount(LuaHandle* luaHandle){
|
||||||
LuaArguments luaArguments(luaHandle);
|
LuaArguments luaArguments(luaHandle);
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -356,6 +356,7 @@ private:
|
||||||
Vec2i getUnitPosition(int unitId);
|
Vec2i getUnitPosition(int unitId);
|
||||||
int getUnitFaction(int unitId);
|
int getUnitFaction(int unitId);
|
||||||
const string getUnitName(int unitId);
|
const string getUnitName(int unitId);
|
||||||
|
const string getUnitDisplayName(int unitId);
|
||||||
int getResourceAmount(const string &resourceName, int factionIndex);
|
int getResourceAmount(const string &resourceName, int factionIndex);
|
||||||
const string &getLastCreatedUnitName();
|
const string &getLastCreatedUnitName();
|
||||||
int getLastCreatedUnitId();
|
int getLastCreatedUnitId();
|
||||||
|
@ -521,6 +522,7 @@ private:
|
||||||
static int getUnitPosition(LuaHandle* luaHandle);
|
static int getUnitPosition(LuaHandle* luaHandle);
|
||||||
static int getUnitFaction(LuaHandle* luaHandle);
|
static int getUnitFaction(LuaHandle* luaHandle);
|
||||||
static int getUnitName(LuaHandle* luaHandle);
|
static int getUnitName(LuaHandle* luaHandle);
|
||||||
|
static int getUnitDisplayName(LuaHandle* luaHandle);
|
||||||
static int getResourceAmount(LuaHandle* luaHandle);
|
static int getResourceAmount(LuaHandle* luaHandle);
|
||||||
static int getLastCreatedUnitName(LuaHandle* luaHandle);
|
static int getLastCreatedUnitName(LuaHandle* luaHandle);
|
||||||
static int getLastCreatedUnitId(LuaHandle* luaHandle);
|
static int getLastCreatedUnitId(LuaHandle* luaHandle);
|
||||||
|
|
|
@ -3,9 +3,9 @@
|
||||||
//
|
//
|
||||||
// Copyright (C) 2010-2010 Titus Tscharntke
|
// Copyright (C) 2010-2010 Titus Tscharntke
|
||||||
//
|
//
|
||||||
// You can redistribute this code and/or modify it under
|
// You can redistribute this code and/or modify it under
|
||||||
// the terms of the GNU General Public License as published
|
// the terms of the GNU General Public License as published
|
||||||
// by the Free Software Foundation; either version 2 of the
|
// by the Free Software Foundation; either version 2 of the
|
||||||
// License, or (at your option) any later version
|
// License, or (at your option) any later version
|
||||||
// ==============================================================
|
// ==============================================================
|
||||||
|
|
||||||
|
@ -57,6 +57,8 @@ ParticleSystemType::ParticleSystemType() {
|
||||||
size=0;
|
size=0;
|
||||||
sizeNoEnergy=0;
|
sizeNoEnergy=0;
|
||||||
speed=0;
|
speed=0;
|
||||||
|
speedUpRelative=0;
|
||||||
|
speedUpConstant=0;
|
||||||
gravity=0;
|
gravity=0;
|
||||||
emissionRate=0;
|
emissionRate=0;
|
||||||
energyMax=0;
|
energyMax=0;
|
||||||
|
@ -107,6 +109,8 @@ void ParticleSystemType::copyAll(const ParticleSystemType &src) {
|
||||||
this->size = src.size;
|
this->size = src.size;
|
||||||
this->sizeNoEnergy = src.sizeNoEnergy;
|
this->sizeNoEnergy = src.sizeNoEnergy;
|
||||||
this->speed = src.speed;
|
this->speed = src.speed;
|
||||||
|
this->speedUpRelative = src.speedUpRelative;
|
||||||
|
this->speedUpConstant = src.speedUpConstant;
|
||||||
this->gravity = src.gravity;
|
this->gravity = src.gravity;
|
||||||
this->emissionRate = src.emissionRate;
|
this->emissionRate = src.emissionRate;
|
||||||
this->energyMax = src.energyMax;
|
this->energyMax = src.energyMax;
|
||||||
|
@ -160,7 +164,7 @@ void ParticleSystemType::load(const XmlNode *particleSystemNode, const string &d
|
||||||
else {
|
else {
|
||||||
texture= NULL;
|
texture= NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
//model
|
//model
|
||||||
if(particleSystemNode->hasChild("model")){
|
if(particleSystemNode->hasChild("model")){
|
||||||
const XmlNode *modelNode= particleSystemNode->getChild("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);
|
string path= modelNode->getAttribute("path")->getRestrictedValue(currentPath);
|
||||||
model= renderer->newModel(rsGame,path, false, &loadedFileList, &parentLoader);
|
model= renderer->newModel(rsGame,path, false, &loadedFileList, &parentLoader);
|
||||||
loadedFileList[path].push_back(make_pair(parentLoader,modelNode->getAttribute("path")->getRestrictedValue()));
|
loadedFileList[path].push_back(make_pair(parentLoader,modelNode->getAttribute("path")->getRestrictedValue()));
|
||||||
|
|
||||||
if(modelNode->hasChild("cycles")) {
|
if(modelNode->hasChild("cycles")) {
|
||||||
modelCycle = modelNode->getChild("cycles")->getAttribute("value")->getFloatValue();
|
modelCycle = modelNode->getChild("cycles")->getAttribute("value")->getFloatValue();
|
||||||
if(modelCycle < 0.0)
|
if(modelCycle < 0.0)
|
||||||
|
@ -220,6 +224,17 @@ void ParticleSystemType::load(const XmlNode *particleSystemNode, const string &d
|
||||||
const XmlNode *speedNode= particleSystemNode->getChild("speed");
|
const XmlNode *speedNode= particleSystemNode->getChild("speed");
|
||||||
speed= speedNode->getAttribute("value")->getFloatValue()/GameConstants::updateFps;
|
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
|
//gravity
|
||||||
const XmlNode *gravityNode= particleSystemNode->getChild("gravity");
|
const XmlNode *gravityNode= particleSystemNode->getChild("gravity");
|
||||||
gravity= gravityNode->getAttribute("value")->getFloatValue()/GameConstants::updateFps;
|
gravity= gravityNode->getAttribute("value")->getFloatValue()/GameConstants::updateFps;
|
||||||
|
@ -235,7 +250,7 @@ void ParticleSystemType::load(const XmlNode *particleSystemNode, const string &d
|
||||||
//speed
|
//speed
|
||||||
const XmlNode *energyVarNode= particleSystemNode->getChild("energy-var");
|
const XmlNode *energyVarNode= particleSystemNode->getChild("energy-var");
|
||||||
energyVar= energyVarNode->getAttribute("value")->getIntValue();
|
energyVar= energyVarNode->getAttribute("value")->getIntValue();
|
||||||
|
|
||||||
//teamcolorNoEnergy
|
//teamcolorNoEnergy
|
||||||
if(particleSystemNode->hasChild("teamcolorNoEnergy")){
|
if(particleSystemNode->hasChild("teamcolorNoEnergy")){
|
||||||
const XmlNode *teamcolorNoEnergyNode= particleSystemNode->getChild("teamcolorNoEnergy");
|
const XmlNode *teamcolorNoEnergyNode= particleSystemNode->getChild("teamcolorNoEnergy");
|
||||||
|
@ -300,6 +315,8 @@ void ParticleSystemType::setValues(AttackParticleSystem *ats){
|
||||||
ats->setColor(color);
|
ats->setColor(color);
|
||||||
ats->setColorNoEnergy(colorNoEnergy);
|
ats->setColorNoEnergy(colorNoEnergy);
|
||||||
ats->setSpeed(speed);
|
ats->setSpeed(speed);
|
||||||
|
ats->setSpeedUpRelative(speedUpRelative);
|
||||||
|
ats->setSpeedUpConstant(speedUpConstant);
|
||||||
ats->setGravity(gravity);
|
ats->setGravity(gravity);
|
||||||
ats->setParticleSize(size);
|
ats->setParticleSize(size);
|
||||||
ats->setSizeNoEnergy(sizeNoEnergy);
|
ats->setSizeNoEnergy(sizeNoEnergy);
|
||||||
|
@ -328,6 +345,8 @@ void ParticleSystemType::loadGame(const XmlNode *rootNode) {
|
||||||
size = particleSystemTypeNode->getAttribute("size")->getFloatValue();
|
size = particleSystemTypeNode->getAttribute("size")->getFloatValue();
|
||||||
sizeNoEnergy = particleSystemTypeNode->getAttribute("sizeNoEnergy")->getFloatValue();
|
sizeNoEnergy = particleSystemTypeNode->getAttribute("sizeNoEnergy")->getFloatValue();
|
||||||
speed = particleSystemTypeNode->getAttribute("speed")->getFloatValue();
|
speed = particleSystemTypeNode->getAttribute("speed")->getFloatValue();
|
||||||
|
speedUpRelative = particleSystemTypeNode->getAttribute("speedUpRelative")->getFloatValue();
|
||||||
|
speedUpConstant = particleSystemTypeNode->getAttribute("speedUpConstant")->getFloatValue();
|
||||||
gravity = particleSystemTypeNode->getAttribute("gravity")->getFloatValue();
|
gravity = particleSystemTypeNode->getAttribute("gravity")->getFloatValue();
|
||||||
emissionRate = particleSystemTypeNode->getAttribute("emissionRate")->getFloatValue();
|
emissionRate = particleSystemTypeNode->getAttribute("emissionRate")->getFloatValue();
|
||||||
energyMax = particleSystemTypeNode->getAttribute("energyMax")->getIntValue();
|
energyMax = particleSystemTypeNode->getAttribute("energyMax")->getIntValue();
|
||||||
|
@ -379,6 +398,10 @@ void ParticleSystemType::saveGame(XmlNode *rootNode) {
|
||||||
particleSystemTypeNode->addAttribute("sizeNoEnergy",floatToStr(sizeNoEnergy,6), mapTagReplacements);
|
particleSystemTypeNode->addAttribute("sizeNoEnergy",floatToStr(sizeNoEnergy,6), mapTagReplacements);
|
||||||
// float speed;
|
// float speed;
|
||||||
particleSystemTypeNode->addAttribute("speed",floatToStr(speed,6), mapTagReplacements);
|
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;
|
// float gravity;
|
||||||
particleSystemTypeNode->addAttribute("gravity",floatToStr(gravity,6), mapTagReplacements);
|
particleSystemTypeNode->addAttribute("gravity",floatToStr(gravity,6), mapTagReplacements);
|
||||||
// float emissionRate;
|
// float emissionRate;
|
||||||
|
@ -441,7 +464,7 @@ void ParticleSystemTypeProjectile::load(const XmlNode* particleFileNode, const s
|
||||||
particleFileNode->setSuper(particleSystemNode);
|
particleFileNode->setSuper(particleSystemNode);
|
||||||
particleSystemNode= particleFileNode;
|
particleSystemNode= particleFileNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
ParticleSystemType::load(particleSystemNode, dir, renderer, loadedFileList,parentLoader, techtreePath);
|
ParticleSystemType::load(particleSystemNode, dir, renderer, loadedFileList,parentLoader, techtreePath);
|
||||||
|
|
||||||
//trajectory values
|
//trajectory values
|
||||||
|
@ -535,7 +558,7 @@ void ParticleSystemTypeSplash::load(const XmlNode* particleFileNode, const strin
|
||||||
loadedFileList[path].push_back(make_pair(parentLoader,parentLoader));
|
loadedFileList[path].push_back(make_pair(parentLoader,parentLoader));
|
||||||
|
|
||||||
const XmlNode *particleSystemNode= xmlTree.getRootNode();
|
const XmlNode *particleSystemNode= xmlTree.getRootNode();
|
||||||
|
|
||||||
if(particleFileNode){
|
if(particleFileNode){
|
||||||
// immediate children in the particleFileNode will override the particleSystemNode
|
// immediate children in the particleFileNode will override the particleSystemNode
|
||||||
particleFileNode->setSuper(particleSystemNode);
|
particleFileNode->setSuper(particleSystemNode);
|
||||||
|
@ -547,7 +570,7 @@ void ParticleSystemTypeSplash::load(const XmlNode* particleFileNode, const strin
|
||||||
//emission rate fade
|
//emission rate fade
|
||||||
const XmlNode *emissionRateFadeNode= particleSystemNode->getChild("emission-rate-fade");
|
const XmlNode *emissionRateFadeNode= particleSystemNode->getChild("emission-rate-fade");
|
||||||
emissionRateFade= emissionRateFadeNode->getAttribute("value")->getFloatValue();
|
emissionRateFade= emissionRateFadeNode->getAttribute("value")->getFloatValue();
|
||||||
|
|
||||||
//spread values
|
//spread values
|
||||||
const XmlNode *verticalSpreadNode= particleSystemNode->getChild("vertical-spread");
|
const XmlNode *verticalSpreadNode= particleSystemNode->getChild("vertical-spread");
|
||||||
verticalSpreadA= verticalSpreadNode->getAttribute("a")->getFloatValue(0.0f, 1.0f);
|
verticalSpreadA= verticalSpreadNode->getAttribute("a")->getFloatValue(0.0f, 1.0f);
|
||||||
|
|
|
@ -65,6 +65,8 @@ protected:
|
||||||
float size;
|
float size;
|
||||||
float sizeNoEnergy;
|
float sizeNoEnergy;
|
||||||
float speed;
|
float speed;
|
||||||
|
float speedUpRelative;
|
||||||
|
float speedUpConstant;
|
||||||
float gravity;
|
float gravity;
|
||||||
float emissionRate;
|
float emissionRate;
|
||||||
int energyMax;
|
int energyMax;
|
||||||
|
|
|
@ -233,6 +233,8 @@ const void UnitParticleSystemType::setValues(UnitParticleSystem *ups){
|
||||||
ups->setColor(color);
|
ups->setColor(color);
|
||||||
ups->setColorNoEnergy(colorNoEnergy);
|
ups->setColorNoEnergy(colorNoEnergy);
|
||||||
ups->setSpeed(speed);
|
ups->setSpeed(speed);
|
||||||
|
ups->setSpeedUpRelative(speedUpRelative);
|
||||||
|
ups->setSpeedUpConstant(speedUpConstant);
|
||||||
ups->setGravity(gravity);
|
ups->setGravity(gravity);
|
||||||
ups->setParticleSize(size);
|
ups->setParticleSize(size);
|
||||||
ups->setSizeNoEnergy(sizeNoEnergy);
|
ups->setSizeNoEnergy(sizeNoEnergy);
|
||||||
|
|
|
@ -71,6 +71,11 @@ bool Selection::select(Unit *unit) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//check if commandable
|
||||||
|
if(unit->getType()->isCommandable() == false && isEmpty() == false) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
//check if multisel
|
//check if multisel
|
||||||
if(unit->getType()->getMultiSelect() == false && isEmpty() == false) {
|
if(unit->getType()->getMultiSelect() == false && isEmpty() == false) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -181,7 +186,8 @@ bool Selection::isCommandable() const {
|
||||||
return
|
return
|
||||||
isEmpty() == false &&
|
isEmpty() == false &&
|
||||||
isEnemy() == 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 {
|
bool Selection::isCancelable() const {
|
||||||
|
|
|
@ -101,6 +101,14 @@ using namespace Shared::Graphics::Gl;
|
||||||
using namespace Shared::Xml;
|
using namespace Shared::Xml;
|
||||||
using namespace Shared;
|
using namespace Shared;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @namespace Glest
|
||||||
|
* Namespace used for all %Glest related code.
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @namespace Game
|
||||||
|
* Namespace used for game related code.
|
||||||
|
*/
|
||||||
namespace Glest { namespace Game {
|
namespace Glest { namespace Game {
|
||||||
|
|
||||||
static string tempDataLocation = getUserHome();
|
static string tempDataLocation = getUserHome();
|
||||||
|
|
|
@ -1209,7 +1209,7 @@ void Faction::applyCostsOnInterval(const ResourceType *rtApply) {
|
||||||
world->getStats()->die(unit->getFactionIndex(),unit->getType()->getCountUnitDeathInStats());
|
world->getStats()->die(unit->getFactionIndex(),unit->getType()->getCountUnitDeathInStats());
|
||||||
scriptManager->onUnitDied(unit);
|
scriptManager->onUnitDied(unit);
|
||||||
}
|
}
|
||||||
StaticSound *sound= unit->getType()->getFirstStOfClass(scDie)->getSound();
|
StaticSound *sound= static_cast<const DieSkillType *>(unit->getType()->getFirstStOfClass(scDie))->getSound();
|
||||||
if(sound != NULL &&
|
if(sound != NULL &&
|
||||||
(thisFaction == true || world->showWorldForPlayer(world->getThisTeamIndex()) == true)) {
|
(thisFaction == true || world->showWorldForPlayer(world->getThisTeamIndex()) == true)) {
|
||||||
SoundRenderer::getInstance().playFx(sound);
|
SoundRenderer::getInstance().playFx(sound);
|
||||||
|
|
|
@ -666,27 +666,7 @@ Unit::~Unit() {
|
||||||
}
|
}
|
||||||
safeMutex.ReleaseLock();
|
safeMutex.ReleaseLock();
|
||||||
|
|
||||||
// If the unit is not visible we better make sure we cleanup associated particles
|
cleanupAllParticlesystems();
|
||||||
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);
|
|
||||||
|
|
||||||
while(currentAttackBoostEffects.empty() == false) {
|
while(currentAttackBoostEffects.empty() == false) {
|
||||||
//UnitAttackBoostEffect &effect = currentAttackBoostEffects.back();
|
//UnitAttackBoostEffect &effect = currentAttackBoostEffects.back();
|
||||||
|
@ -726,6 +706,29 @@ Unit::~Unit() {
|
||||||
#endif
|
#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 {
|
ParticleSystem * Unit::getFire() const {
|
||||||
if(this->fire != NULL &&
|
if(this->fire != NULL &&
|
||||||
Renderer::getInstance().validateParticleSystemStillExists(this->fire,rsGame) == false) {
|
Renderer::getInstance().validateParticleSystemStillExists(this->fire,rsGame) == false) {
|
||||||
|
@ -1951,13 +1954,32 @@ void Unit::born(const CommandType *ct) {
|
||||||
|
|
||||||
checkItemInVault(&this->hp,this->hp);
|
checkItemInVault(&this->hp,this->hp);
|
||||||
int original_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) {
|
if(original_hp != this->hp) {
|
||||||
//printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__);
|
//printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__);
|
||||||
game->getScriptManager()->onUnitTriggerEvent(this,utet_HPChanged);
|
game->getScriptManager()->onUnitTriggerEvent(this,utet_HPChanged);
|
||||||
//printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__);
|
//printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__);
|
||||||
}
|
}
|
||||||
addItemToVault(&this->hp,this->hp);
|
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() {
|
void Unit::kill() {
|
||||||
|
@ -2611,7 +2633,15 @@ bool Unit::update() {
|
||||||
int64 heightFactor = getHeightFactor(ANIMATION_SPEED_MULTIPLIER);
|
int64 heightFactor = getHeightFactor(ANIMATION_SPEED_MULTIPLIER);
|
||||||
int64 speedDenominator = speedDivider *
|
int64 speedDenominator = speedDivider *
|
||||||
game->getWorld()->getUpdateFps(this->getFactionIndex());
|
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
|
// Ensure we increment at least a value of 1 of the action will be stuck infinitely
|
||||||
if(currSkill->getAnimSpeed() > 0 && heightFactor > 0 && progressIncrease == 0) {
|
if(currSkill->getAnimSpeed() > 0 && heightFactor > 0 && progressIncrease == 0) {
|
||||||
progressIncrease = 1;
|
progressIncrease = 1;
|
||||||
|
@ -2933,7 +2963,7 @@ bool Unit::applyAttackBoost(const AttackBoost *boost, const Unit *source) {
|
||||||
Unit::game->getWorld()->getStats()->die(getFactionIndex(),getType()->getCountUnitDeathInStats());
|
Unit::game->getWorld()->getStats()->die(getFactionIndex(),getType()->getCountUnitDeathInStats());
|
||||||
game->getScriptManager()->onUnitDied(this);
|
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 &&
|
if(sound != NULL &&
|
||||||
(this->getFactionIndex() == Unit::game->getWorld()->getThisFactionIndex() ||
|
(this->getFactionIndex() == Unit::game->getWorld()->getThisFactionIndex() ||
|
||||||
(game->getWorld()->showWorldForPlayer(game->getWorld()->getThisTeamIndex()) == true))) {
|
(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());
|
Unit::game->getWorld()->getStats()->die(getFactionIndex(),getType()->getCountUnitDeathInStats());
|
||||||
game->getScriptManager()->onUnitDied(this);
|
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 &&
|
if(sound != NULL &&
|
||||||
(this->getFactionIndex() == Unit::game->getWorld()->getThisFactionIndex() ||
|
(this->getFactionIndex() == Unit::game->getWorld()->getThisFactionIndex() ||
|
||||||
(game->getWorld()->showWorldForPlayer(game->getWorld()->getThisTeamIndex()) == true))) {
|
(game->getWorld()->showWorldForPlayer(game->getWorld()->getThisTeamIndex()) == true))) {
|
||||||
|
@ -3103,7 +3133,7 @@ void Unit::tick() {
|
||||||
Unit::game->getWorld()->getStats()->die(getFactionIndex(),getType()->getCountUnitDeathInStats());
|
Unit::game->getWorld()->getStats()->die(getFactionIndex(),getType()->getCountUnitDeathInStats());
|
||||||
game->getScriptManager()->onUnitDied(this);
|
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 &&
|
if(sound != NULL &&
|
||||||
(this->getFactionIndex() == Unit::game->getWorld()->getThisFactionIndex() ||
|
(this->getFactionIndex() == Unit::game->getWorld()->getThisFactionIndex() ||
|
||||||
(game->getWorld()->showWorldForPlayer(game->getWorld()->getThisTeamIndex()) == true))) {
|
(game->getWorld()->showWorldForPlayer(game->getWorld()->getThisTeamIndex()) == true))) {
|
||||||
|
@ -3142,7 +3172,7 @@ void Unit::tick() {
|
||||||
Unit::game->getWorld()->getStats()->die(getFactionIndex(),getType()->getCountUnitDeathInStats());
|
Unit::game->getWorld()->getStats()->die(getFactionIndex(),getType()->getCountUnitDeathInStats());
|
||||||
game->getScriptManager()->onUnitDied(this);
|
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 &&
|
if(sound != NULL &&
|
||||||
(this->getFactionIndex() == Unit::game->getWorld()->getThisFactionIndex() ||
|
(this->getFactionIndex() == Unit::game->getWorld()->getThisFactionIndex() ||
|
||||||
(game->getWorld()->showWorldForPlayer(game->getWorld()->getThisTeamIndex()) == true))) {
|
(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);
|
checkItemInVault(&this->hp,this->hp);
|
||||||
int original_hp = this->hp;
|
int original_hp = this->hp;
|
||||||
|
|
|
@ -806,6 +806,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
void cleanupAllParticlesystems();
|
||||||
bool isNetworkCRCEnabled();
|
bool isNetworkCRCEnabled();
|
||||||
string getNetworkCRCDecHpList() const;
|
string getNetworkCRCDecHpList() const;
|
||||||
string getParticleInfo() const;
|
string getParticleInfo() const;
|
||||||
|
|
|
@ -9,6 +9,13 @@
|
||||||
// License, or (at your option) any later version
|
// 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_
|
#ifndef _GLEST_GAME_UPGRADE_H_
|
||||||
#define _GLEST_GAME_UPGRADE_H_
|
#define _GLEST_GAME_UPGRADE_H_
|
||||||
|
|
||||||
|
@ -33,25 +40,32 @@ class Unit;
|
||||||
class UpgradeType;
|
class UpgradeType;
|
||||||
class Faction;
|
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 {
|
enum UpgradeState {
|
||||||
usUpgrading,
|
usUpgrading, /**< The upgrade is currently in progress. */
|
||||||
usUpgraded,
|
usUpgraded, /**< The upgrade is completed. */
|
||||||
|
|
||||||
upgradeStateCount
|
upgradeStateCount // TODO: This should be unnecessary -- there's no need to iterate over this enum
|
||||||
};
|
};
|
||||||
|
|
||||||
class UpgradeManager;
|
class UpgradeManager;
|
||||||
class TotalUpgrade;
|
class TotalUpgrade;
|
||||||
|
|
||||||
// =====================================================
|
/**
|
||||||
// class Upgrade
|
* 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?).
|
||||||
/// A bonus to an UnitType
|
*/
|
||||||
// =====================================================
|
|
||||||
|
|
||||||
class Upgrade {
|
class Upgrade {
|
||||||
private:
|
private:
|
||||||
UpgradeState state;
|
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;
|
int factionIndex;
|
||||||
const UpgradeType *type;
|
const UpgradeType *type;
|
||||||
|
|
||||||
|
@ -59,50 +73,136 @@ private:
|
||||||
|
|
||||||
Upgrade();
|
Upgrade();
|
||||||
public:
|
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);
|
Upgrade(const UpgradeType *upgradeType, int factionIndex);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
//get
|
|
||||||
UpgradeState getState() const;
|
UpgradeState getState() const;
|
||||||
int getFactionIndex() const;
|
int getFactionIndex() const;
|
||||||
const UpgradeType * getType() const;
|
const UpgradeType * getType() const;
|
||||||
|
|
||||||
//set
|
|
||||||
void setState(UpgradeState state);
|
void setState(UpgradeState state);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a string representation of the upgrade (detailing its state, type, and faction).
|
||||||
|
*/
|
||||||
std::string toString() const;
|
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);
|
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);
|
static Upgrade * loadGame(const XmlNode *rootNode,Faction *faction);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
// ===============================
|
* Manages upgrades by starting, stopping, and finishing upgrades. Each faction has their own
|
||||||
// class UpgradeManager
|
* upgrade manager.
|
||||||
// ===============================
|
*/
|
||||||
|
|
||||||
class UpgradeManager{
|
class UpgradeManager{
|
||||||
private:
|
private:
|
||||||
typedef vector<Upgrade*> Upgrades;
|
typedef vector<Upgrade*> Upgrades;
|
||||||
typedef map<const UpgradeType *,int> UgradesLookup;
|
typedef map<const UpgradeType *,int> UgradesLookup;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of upgrades that the upgrade manager is working with (either in progress or finished).
|
||||||
|
*/
|
||||||
Upgrades upgrades;
|
Upgrades upgrades;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maps UpgradeType to the index of the upgrade in UpgradeManager::upgrades.
|
||||||
|
*/
|
||||||
UgradesLookup upgradesLookup;
|
UgradesLookup upgradesLookup;
|
||||||
public:
|
public:
|
||||||
~UpgradeManager();
|
~UpgradeManager();
|
||||||
|
|
||||||
int getUpgradeCount() const {return (int)upgrades.size();}
|
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);
|
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);
|
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);
|
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 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;
|
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);
|
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);
|
void loadGame(const XmlNode *rootNode,Faction *faction);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -288,7 +288,13 @@ string AttackCommandType::getDesc(const TotalUpgrade *totalUpgrade, bool transla
|
||||||
}
|
}
|
||||||
str+="\n";
|
str+="\n";
|
||||||
|
|
||||||
|
//attack speed
|
||||||
str+= lang.getString("AttackSpeed",(translatedValue == true ? "" : "english"))+": "+ intToStr(attackSkillType->getSpeed()) +"\n";
|
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);
|
str+=attackSkillType->getBoostDesc(translatedValue);
|
||||||
return str;
|
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 "renderer.h"
|
||||||
#include "particle_type.h"
|
#include "particle_type.h"
|
||||||
#include "unit_particle_type.h"
|
#include "unit_particle_type.h"
|
||||||
|
#include "projectile_type.h"
|
||||||
#include "tech_tree.h"
|
#include "tech_tree.h"
|
||||||
#include "faction_type.h"
|
#include "faction_type.h"
|
||||||
#include "leak_dumper.h"
|
#include "leak_dumper.h"
|
||||||
|
@ -273,12 +274,27 @@ void AttackBoost::saveGame(XmlNode *rootNode) const {
|
||||||
attackBoostNode->addAttribute("name",name, mapTagReplacements);
|
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
|
// class SkillType
|
||||||
// =====================================================
|
// =====================================================
|
||||||
|
|
||||||
SkillType::~SkillType() {
|
SkillType::~SkillType() {
|
||||||
deleteValues(sounds.getSounds().begin(), sounds.getSounds().end());
|
while(!skillSoundList.empty()) {
|
||||||
|
delete skillSoundList.back();
|
||||||
|
skillSoundList.pop_back();
|
||||||
|
}
|
||||||
//remove unitParticleSystemTypes
|
//remove unitParticleSystemTypes
|
||||||
while(!unitParticleSystemTypes.empty()) {
|
while(!unitParticleSystemTypes.empty()) {
|
||||||
delete unitParticleSystemTypes.back();
|
delete unitParticleSystemTypes.back();
|
||||||
|
@ -488,11 +504,18 @@ void SkillType::load(const XmlNode *sn, const XmlNode *attackBoostsNode,
|
||||||
unitParticleSystemType->load(particleFileNode, dir, currentPath + path, &Renderer::getInstance(),
|
unitParticleSystemType->load(particleFileNode, dir, currentPath + path, &Renderer::getInstance(),
|
||||||
loadedFileList,parentLoader,tt->getPath());
|
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());
|
//printf("*NOTE particle system type has start-time [%f]\n",particleNode->getAttribute("start-time")->getFloatValue());
|
||||||
unitParticleSystemType->setStartTime(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());
|
//printf("*NOTE particle system type has end-time [%f]\n",particleNode->getAttribute("end-time")->getFloatValue());
|
||||||
unitParticleSystemType->setEndTime(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
|
//sound
|
||||||
if(sn->hasChild("sound")) {
|
vector<XmlNode *> soundNodeList = sn->getChildList("sound");
|
||||||
const XmlNode *soundNode= sn->getChild("sound");
|
for(unsigned int i = 0; i < soundNodeList.size(); ++i) {
|
||||||
|
const XmlNode *soundNode= soundNodeList[i];
|
||||||
if(soundNode->getAttribute("enabled")->getBoolValue()) {
|
if(soundNode->getAttribute("enabled")->getBoolValue()) {
|
||||||
soundStartTime= soundNode->getAttribute("start-time")->getFloatValue();
|
float soundStartTime= soundNode->getAttribute("start-time")->getFloatValue();
|
||||||
sounds.resize((int)soundNode->getChildCount());
|
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) {
|
for(int i = 0; i < (int)soundNode->getChildCount(); ++i) {
|
||||||
const XmlNode *soundFileNode= soundNode->getChild("sound-file", i);
|
const XmlNode *soundFileNode= soundNode->getChild("sound-file", i);
|
||||||
string path= soundFileNode->getAttribute("path")->getRestrictedValue(currentPath, true);
|
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();
|
StaticSound *sound= new StaticSound();
|
||||||
sound->load(path);
|
sound->load(path);
|
||||||
loadedFileList[path].push_back(make_pair(parentLoader,soundFileNode->getAttribute("path")->getRestrictedValue()));
|
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;
|
// SoundContainer sounds;
|
||||||
// float soundStartTime;
|
// float soundStartTime;
|
||||||
skillTypeNode->addAttribute("soundStartTime",floatToStr(soundStartTime,6), mapTagReplacements);
|
// skillTypeNode->addAttribute("soundStartTime",floatToStr(soundStartTime,6), mapTagReplacements);
|
||||||
// RandomGen random;
|
// RandomGen random;
|
||||||
skillTypeNode->addAttribute("random",intToStr(random.getLastNumber()), mapTagReplacements);
|
skillTypeNode->addAttribute("random",intToStr(random.getLastNumber()), mapTagReplacements);
|
||||||
// AttackBoost attackBoost;
|
// AttackBoost attackBoost;
|
||||||
|
@ -806,7 +834,7 @@ AttackSkillType::AttackSkillType() {
|
||||||
splashRadius= 0;
|
splashRadius= 0;
|
||||||
spawnUnit="";
|
spawnUnit="";
|
||||||
spawnUnitcount=0;
|
spawnUnitcount=0;
|
||||||
projectileParticleSystemType= NULL;
|
spawnUnitAtTarget=false;
|
||||||
splashParticleSystemType= NULL;
|
splashParticleSystemType= NULL;
|
||||||
|
|
||||||
for(int i = 0; i < fieldCount; ++i) {
|
for(int i = 0; i < fieldCount; ++i) {
|
||||||
|
@ -821,8 +849,8 @@ AttackSkillType::AttackSkillType() {
|
||||||
}
|
}
|
||||||
|
|
||||||
AttackSkillType::~AttackSkillType() {
|
AttackSkillType::~AttackSkillType() {
|
||||||
delete projectileParticleSystemType;
|
|
||||||
projectileParticleSystemType = NULL;
|
deleteValues(projectileTypes.begin(), projectileTypes.end());
|
||||||
|
|
||||||
delete splashParticleSystemType;
|
delete splashParticleSystemType;
|
||||||
splashParticleSystemType = NULL;
|
splashParticleSystemType = NULL;
|
||||||
|
@ -859,11 +887,16 @@ void AttackSkillType::load(const XmlNode *sn, const XmlNode *attackBoostsNode,
|
||||||
|
|
||||||
if (sn->hasChild("unit")) {
|
if (sn->hasChild("unit")) {
|
||||||
spawnUnit = sn->getChild("unit")->getAttribute("value")->getValue();
|
spawnUnit = sn->getChild("unit")->getAttribute("value")->getValue();
|
||||||
spawnUnitcount
|
spawnUnitcount = sn->getChild("unit")->getAttribute("amount")->getIntValue();
|
||||||
= sn->getChild("unit")->getAttribute("amount")->getIntValue();
|
if(sn->getChild("unit")->hasAttribute("spawnAtTarget")) {
|
||||||
|
spawnUnitAtTarget = sn->getChild("unit")->getAttribute("spawnAtTarget")->getBoolValue();
|
||||||
|
} else {
|
||||||
|
spawnUnitAtTarget = false;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
spawnUnit = "";
|
spawnUnit = "";
|
||||||
spawnUnitcount = 0;
|
spawnUnitcount = 0;
|
||||||
|
spawnUnitAtTarget = false;
|
||||||
}
|
}
|
||||||
//attack fields
|
//attack fields
|
||||||
const XmlNode *attackFieldsNode= sn->getChild("attack-fields");
|
const XmlNode *attackFieldsNode= sn->getChild("attack-fields");
|
||||||
|
@ -881,36 +914,81 @@ void AttackSkillType::load(const XmlNode *sn, const XmlNode *attackBoostsNode,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//projectile
|
if(sn->hasChild("projectile")){
|
||||||
const XmlNode *projectileNode= sn->getChild("projectile");
|
//projectile -- backward compatible old behaviour with only one projectile
|
||||||
projectile= projectileNode->getAttribute("value")->getBoolValue();
|
const XmlNode *projectileNode= sn->getChild("projectile");
|
||||||
if(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
|
projSounds.resize((int)soundNode->getChildCount());
|
||||||
const XmlNode *particleNode= projectileNode->getChild("particle");
|
for(int i=0; i < (int)soundNode->getChildCount(); ++i){
|
||||||
bool particleEnabled= particleNode->getAttribute("value")->getBoolValue();
|
const XmlNode *soundFileNode= soundNode->getChild("sound-file", i);
|
||||||
if(particleEnabled){
|
string path= soundFileNode->getAttribute("path")->getRestrictedValue(currentPath, true);
|
||||||
string path= particleNode->getAttribute("path")->getRestrictedValue();
|
//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);
|
||||||
projectileParticleSystemType= new ParticleSystemTypeProjectile();
|
|
||||||
projectileParticleSystemType->load(particleNode, dir, currentPath + path,
|
StaticSound *sound= new StaticSound();
|
||||||
&Renderer::getInstance(), loadedFileList, parentLoader,
|
sound->load(path);
|
||||||
tt->getPath());
|
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
|
if(totalDamagePercentage!=100){
|
||||||
const XmlNode *soundNode= projectileNode->getChild("sound");
|
throw megaglest_runtime_error("Damages percentages of projectiles don't sum up to 100 %");
|
||||||
if(soundNode->getAttribute("enabled")->getBoolValue()){
|
}
|
||||||
|
|
||||||
projSounds.resize((int)soundNode->getChildCount());
|
if(sn->hasChild("hitsound")==true){
|
||||||
for(int i=0; i < (int)soundNode->getChildCount(); ++i){
|
//general hit sounds, individual ones can be set in projectiles
|
||||||
const XmlNode *soundFileNode= soundNode->getChild("sound-file", i);
|
const XmlNode *soundNode= sn->getChild("hitsound");
|
||||||
string path= soundFileNode->getAttribute("path")->getRestrictedValue(currentPath, true);
|
if(soundNode->getAttribute("enabled")->getBoolValue()){
|
||||||
//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();
|
projSounds.resize((int)soundNode->getChildCount());
|
||||||
sound->load(path);
|
for(int i=0; i < (int)soundNode->getChildCount(); ++i){
|
||||||
loadedFileList[path].push_back(make_pair(parentLoader,soundFileNode->getAttribute("path")->getRestrictedValue()));
|
const XmlNode *soundFileNode= soundNode->getChild("sound-file", i);
|
||||||
projSounds[i]= sound;
|
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{
|
string AttackSkillType::toString(bool translatedValue) const{
|
||||||
if(translatedValue == false) {
|
if(translatedValue == false) {
|
||||||
return "Attack";
|
return "Attack";
|
||||||
|
@ -983,12 +1079,15 @@ void AttackSkillType::saveGame(XmlNode *rootNode) {
|
||||||
attackSkillTypeNode->addAttribute("spawnUnit",spawnUnit, mapTagReplacements);
|
attackSkillTypeNode->addAttribute("spawnUnit",spawnUnit, mapTagReplacements);
|
||||||
// int spawnUnitcount;
|
// int spawnUnitcount;
|
||||||
attackSkillTypeNode->addAttribute("spawnUnitcount",intToStr(spawnUnitcount), mapTagReplacements);
|
attackSkillTypeNode->addAttribute("spawnUnitcount",intToStr(spawnUnitcount), mapTagReplacements);
|
||||||
|
// bool spawnUnitAtTarget;
|
||||||
|
attackSkillTypeNode->addAttribute("spawnUnitAtTarget",intToStr(spawnUnitAtTarget), mapTagReplacements);
|
||||||
// bool projectile;
|
// bool projectile;
|
||||||
attackSkillTypeNode->addAttribute("projectile",intToStr(projectile), mapTagReplacements);
|
attackSkillTypeNode->addAttribute("projectile",intToStr(projectile), mapTagReplacements);
|
||||||
// ParticleSystemTypeProjectile* projectileParticleSystemType;
|
// ParticleSystemTypeProjectile* projectileParticleSystemType;
|
||||||
if(projectileParticleSystemType != NULL) {
|
// save a skill_type ????
|
||||||
projectileParticleSystemType->saveGame(attackSkillTypeNode);
|
// if(projectileParticleSystemType != NULL) {
|
||||||
}
|
// projectileParticleSystemType->saveGame(attackSkillTypeNode);
|
||||||
|
// }
|
||||||
// SoundContainer projSounds;
|
// SoundContainer projSounds;
|
||||||
//
|
//
|
||||||
// bool splash;
|
// bool splash;
|
||||||
|
@ -1262,6 +1361,15 @@ void DieSkillType::saveGame(XmlNode *rootNode) {
|
||||||
dieSkillTypeNode->addAttribute("fade",intToStr(fade), mapTagReplacements);
|
dieSkillTypeNode->addAttribute("fade",intToStr(fade), mapTagReplacements);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StaticSound *DieSkillType::getSound() const{
|
||||||
|
if(skillSoundList.size()==0){
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return skillSoundList.front()->getSoundContainer()->getRandSound();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// =====================================================
|
// =====================================================
|
||||||
// class FogOfWarSkillType
|
// class FogOfWarSkillType
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#include "factory.h"
|
#include "factory.h"
|
||||||
#include "sound_container.h"
|
#include "sound_container.h"
|
||||||
#include "particle.h"
|
#include "particle.h"
|
||||||
|
#include "projectile_type.h"
|
||||||
#include "upgrade_type.h"
|
#include "upgrade_type.h"
|
||||||
#include "leak_dumper.h"
|
#include "leak_dumper.h"
|
||||||
|
|
||||||
|
@ -74,6 +75,7 @@ enum SkillClass{
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef list<UnitParticleSystemType*> UnitParticleSystemTypes;
|
typedef list<UnitParticleSystemType*> UnitParticleSystemTypes;
|
||||||
|
typedef list<ProjectileType*> ProjectileTypes;
|
||||||
// =====================================================
|
// =====================================================
|
||||||
// class SkillType
|
// class SkillType
|
||||||
//
|
//
|
||||||
|
@ -123,8 +125,29 @@ public:
|
||||||
int toHp;
|
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 {
|
class SkillType {
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
SkillClass skillClass;
|
SkillClass skillClass;
|
||||||
string name;
|
string name;
|
||||||
|
@ -155,8 +178,7 @@ protected:
|
||||||
vector<Model *> animations;
|
vector<Model *> animations;
|
||||||
vector<AnimationAttributes> animationAttributes;
|
vector<AnimationAttributes> animationAttributes;
|
||||||
|
|
||||||
SoundContainer sounds;
|
SkillSoundList skillSoundList;
|
||||||
float soundStartTime;
|
|
||||||
RandomGen random;
|
RandomGen random;
|
||||||
AttackBoost attackBoost;
|
AttackBoost attackBoost;
|
||||||
|
|
||||||
|
@ -195,14 +217,14 @@ public:
|
||||||
int getSpeed() const {return speed;}
|
int getSpeed() const {return speed;}
|
||||||
int getAnimSpeed() const {return animSpeed;}
|
int getAnimSpeed() const {return animSpeed;}
|
||||||
Model *getAnimation(float animProgress=0, const Unit *unit=NULL, int *lastAnimationIndex=NULL, int *animationRandomCycleCount=NULL) const;
|
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;}
|
float getShakeStartTime() const {return shakeStartTime;}
|
||||||
bool getShake() const {return shake;}
|
bool getShake() const {return shake;}
|
||||||
int getShakeIntensity() const {return shakeIntensity;}
|
int getShakeIntensity() const {return shakeIntensity;}
|
||||||
int getShakeDuration() const {return shakeDuration;}
|
int getShakeDuration() const {return shakeDuration;}
|
||||||
|
|
||||||
|
const SkillSoundList * getSkillSoundList() const {return &skillSoundList;}
|
||||||
|
|
||||||
bool getShakeSelfEnabled() const {return shakeSelfEnabled;}
|
bool getShakeSelfEnabled() const {return shakeSelfEnabled;}
|
||||||
bool getShakeSelfVisible() const {return shakeSelfVisible;}
|
bool getShakeSelfVisible() const {return shakeSelfVisible;}
|
||||||
bool getShakeSelfInCameraView() const {return shakeSelfInCameraView;}
|
bool getShakeSelfInCameraView() const {return shakeSelfInCameraView;}
|
||||||
|
@ -258,6 +280,8 @@ public:
|
||||||
// ===============================
|
// ===============================
|
||||||
|
|
||||||
class AttackSkillType: public SkillType{
|
class AttackSkillType: public SkillType{
|
||||||
|
public:
|
||||||
|
ProjectileTypes projectileTypes;
|
||||||
private:
|
private:
|
||||||
int attackStrength;
|
int attackStrength;
|
||||||
int attackVar;
|
int attackVar;
|
||||||
|
@ -268,8 +292,9 @@ private:
|
||||||
|
|
||||||
string spawnUnit;
|
string spawnUnit;
|
||||||
int spawnUnitcount;
|
int spawnUnitcount;
|
||||||
|
bool spawnUnitAtTarget;
|
||||||
bool projectile;
|
bool projectile;
|
||||||
ParticleSystemTypeProjectile* projectileParticleSystemType;
|
//ParticleSystemTypeProjectile* projectileParticleSystemType;
|
||||||
SoundContainer projSounds;
|
SoundContainer projSounds;
|
||||||
|
|
||||||
bool splash;
|
bool splash;
|
||||||
|
@ -294,10 +319,10 @@ public:
|
||||||
inline float getAttackStartTime() const {return attackStartTime;}
|
inline float getAttackStartTime() const {return attackStartTime;}
|
||||||
inline string getSpawnUnit() const {return spawnUnit;}
|
inline string getSpawnUnit() const {return spawnUnit;}
|
||||||
inline int getSpawnUnitCount() const {return spawnUnitcount;}
|
inline int getSpawnUnitCount() const {return spawnUnitcount;}
|
||||||
|
inline bool getSpawnUnitAtTarget() const {return spawnUnitAtTarget;}
|
||||||
|
|
||||||
//get proj
|
//get proj
|
||||||
inline bool getProjectile() const {return projectile;}
|
inline bool getProjectile() const {return projectile;}
|
||||||
inline ParticleSystemTypeProjectile * getProjParticleType() const {return projectileParticleSystemType;}
|
|
||||||
inline StaticSound *getProjSound() const {return projSounds.getRandSound();}
|
inline StaticSound *getProjSound() const {return projSounds.getRandSound();}
|
||||||
|
|
||||||
//get splash
|
//get splash
|
||||||
|
@ -309,6 +334,8 @@ public:
|
||||||
//misc
|
//misc
|
||||||
int getTotalAttackStrength(const TotalUpgrade *totalUpgrade) const;
|
int getTotalAttackStrength(const TotalUpgrade *totalUpgrade) const;
|
||||||
int getTotalAttackRange(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);
|
virtual void saveGame(XmlNode *rootNode);
|
||||||
};
|
};
|
||||||
|
@ -447,6 +474,7 @@ public:
|
||||||
virtual string toString(bool translatedValue) const;
|
virtual string toString(bool translatedValue) const;
|
||||||
|
|
||||||
virtual void saveGame(XmlNode *rootNode);
|
virtual void saveGame(XmlNode *rootNode);
|
||||||
|
StaticSound *getSound() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
// ===============================
|
// ===============================
|
||||||
|
|
|
@ -89,6 +89,7 @@ UnitType::UnitType() : ProducibleType() {
|
||||||
lightColor= Vec3f(0.f);
|
lightColor= Vec3f(0.f);
|
||||||
light= false;
|
light= false;
|
||||||
multiSelect= false;
|
multiSelect= false;
|
||||||
|
commandable= true;
|
||||||
armorType= NULL;
|
armorType= NULL;
|
||||||
rotatedBuildPos=0;
|
rotatedBuildPos=0;
|
||||||
|
|
||||||
|
@ -125,7 +126,13 @@ UnitType::UnitType() : ProducibleType() {
|
||||||
epRegeneration= 0;
|
epRegeneration= 0;
|
||||||
maxUnitCount= 0;
|
maxUnitCount= 0;
|
||||||
maxHp=0;
|
maxHp=0;
|
||||||
|
startHpValue=0;
|
||||||
|
startHpPercentage=1.0;
|
||||||
|
startHpType=stValue;
|
||||||
maxEp=0;
|
maxEp=0;
|
||||||
|
startEpValue=0;
|
||||||
|
startEpPercentage=0;
|
||||||
|
startEpType=stValue;
|
||||||
armor=0;
|
armor=0;
|
||||||
sight=0;
|
sight=0;
|
||||||
size=0;
|
size=0;
|
||||||
|
@ -247,6 +254,59 @@ void UnitType::loaddd(int id,const string &dir, const TechTree *techTree,
|
||||||
}
|
}
|
||||||
addItemToVault(&(this->epRegeneration),this->epRegeneration);
|
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
|
//maxUnitCount
|
||||||
if(parametersNode->hasChild("max-unit-count")) {
|
if(parametersNode->hasChild("max-unit-count")) {
|
||||||
//checkItemInVault(&(this->maxUnitCount),this->maxUnitCount);
|
//checkItemInVault(&(this->maxUnitCount),this->maxUnitCount);
|
||||||
|
@ -274,6 +334,10 @@ void UnitType::loaddd(int id,const string &dir, const TechTree *techTree,
|
||||||
//multi selection
|
//multi selection
|
||||||
multiSelect= parametersNode->getChild("multi-selection")->getAttribute("value")->getBoolValue();
|
multiSelect= parametersNode->getChild("multi-selection")->getAttribute("value")->getBoolValue();
|
||||||
|
|
||||||
|
//commandable
|
||||||
|
if(parametersNode->hasChild("commandable")){
|
||||||
|
commandable= parametersNode->getChild("commandable")->getAttribute("value")->getBoolValue();
|
||||||
|
}
|
||||||
//cellmap
|
//cellmap
|
||||||
allowEmptyCellMap = false;
|
allowEmptyCellMap = false;
|
||||||
const XmlNode *cellMapNode= parametersNode->getChild("cellmap");
|
const XmlNode *cellMapNode= parametersNode->getChild("cellmap");
|
||||||
|
@ -532,6 +596,65 @@ void UnitType::loaddd(int id,const string &dir, const TechTree *techTree,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sortedItems.clear();
|
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
|
//image
|
||||||
const XmlNode *imageNode= parametersNode->getChild("image");
|
const XmlNode *imageNode= parametersNode->getChild("image");
|
||||||
|
@ -1100,6 +1223,8 @@ std::string UnitType::toString() const {
|
||||||
result += " maxHp = " + intToStr(maxHp);
|
result += " maxHp = " + intToStr(maxHp);
|
||||||
result += " hpRegeneration = " + intToStr(hpRegeneration);
|
result += " hpRegeneration = " + intToStr(hpRegeneration);
|
||||||
result += " maxEp = " + intToStr(maxEp);
|
result += " maxEp = " + intToStr(maxEp);
|
||||||
|
result += " startEpValue = " + intToStr(startEpValue);
|
||||||
|
result += " startEpPercentage = " + intToStr(startEpPercentage);
|
||||||
result += " epRegeneration = " + intToStr(epRegeneration);
|
result += " epRegeneration = " + intToStr(epRegeneration);
|
||||||
result += " maxUnitCount = " + intToStr(getMaxUnitCount());
|
result += " maxUnitCount = " + intToStr(getMaxUnitCount());
|
||||||
|
|
||||||
|
@ -1120,6 +1245,7 @@ std::string UnitType::toString() const {
|
||||||
result += " light = " + intToStr(light);
|
result += " light = " + intToStr(light);
|
||||||
result += " lightColor = " + lightColor.getString();
|
result += " lightColor = " + lightColor.getString();
|
||||||
result += " multiSelect = " + intToStr(multiSelect);
|
result += " multiSelect = " + intToStr(multiSelect);
|
||||||
|
result += " commandable = " + intToStr(commandable);
|
||||||
result += " sight = " + intToStr(sight);
|
result += " sight = " + intToStr(sight);
|
||||||
result += " size = " + intToStr(size);
|
result += " size = " + intToStr(size);
|
||||||
result += " height = " + intToStr(height);
|
result += " height = " + intToStr(height);
|
||||||
|
|
|
@ -63,6 +63,45 @@ public:
|
||||||
static const Level * loadGame(const XmlNode *rootNode, const UnitType *ut);
|
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
|
// class UnitType
|
||||||
//
|
//
|
||||||
|
@ -92,6 +131,11 @@ public:
|
||||||
pCount
|
pCount
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum StartType {
|
||||||
|
stValue,
|
||||||
|
stPercentage
|
||||||
|
};
|
||||||
|
|
||||||
static const char *propertyNames[];
|
static const char *propertyNames[];
|
||||||
DamageParticleSystemTypes damageParticleSystemTypes;
|
DamageParticleSystemTypes damageParticleSystemTypes;
|
||||||
private:
|
private:
|
||||||
|
@ -99,13 +143,20 @@ private:
|
||||||
typedef vector<CommandType*> CommandTypes;
|
typedef vector<CommandType*> CommandTypes;
|
||||||
typedef vector<Resource> StoredResources;
|
typedef vector<Resource> StoredResources;
|
||||||
typedef vector<Level> Levels;
|
typedef vector<Level> Levels;
|
||||||
|
typedef vector<LootableResource> LootableResources;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
//basic
|
//basic
|
||||||
int id;
|
int id;
|
||||||
int maxHp;
|
int maxHp;
|
||||||
|
int startHpValue;
|
||||||
|
int startHpPercentage;
|
||||||
|
StartType startHpType;
|
||||||
int hpRegeneration;
|
int hpRegeneration;
|
||||||
int maxEp;
|
int maxEp;
|
||||||
|
int startEpValue;
|
||||||
|
int startEpPercentage;
|
||||||
|
StartType startEpType;
|
||||||
int epRegeneration;
|
int epRegeneration;
|
||||||
int maxUnitCount;
|
int maxUnitCount;
|
||||||
|
|
||||||
|
@ -120,6 +171,7 @@ private:
|
||||||
bool light;
|
bool light;
|
||||||
Vec3f lightColor;
|
Vec3f lightColor;
|
||||||
bool multiSelect;
|
bool multiSelect;
|
||||||
|
bool commandable;
|
||||||
int sight;
|
int sight;
|
||||||
int size; //size in cells
|
int size; //size in cells
|
||||||
int renderSize; //size to render in cells
|
int renderSize; //size to render in cells
|
||||||
|
@ -140,6 +192,7 @@ private:
|
||||||
CommandTypes commandTypes;
|
CommandTypes commandTypes;
|
||||||
StoredResources storedResources;
|
StoredResources storedResources;
|
||||||
Levels levels;
|
Levels levels;
|
||||||
|
LootableResources lootableResources;
|
||||||
|
|
||||||
//meeting point
|
//meeting point
|
||||||
bool meetingPoint;
|
bool meetingPoint;
|
||||||
|
@ -178,8 +231,14 @@ public:
|
||||||
inline int getId() const {return id;}
|
inline int getId() const {return id;}
|
||||||
inline int getMaxHp() const {return maxHp;}
|
inline int getMaxHp() const {return maxHp;}
|
||||||
inline int getHpRegeneration() const {return hpRegeneration;}
|
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 getMaxEp() const {return maxEp;}
|
||||||
inline int getEpRegeneration() const {return epRegeneration;}
|
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 int getMaxUnitCount() const {return maxUnitCount;}
|
||||||
inline bool getField(Field field) const {return fields[field];}
|
inline bool getField(Field field) const {return fields[field];}
|
||||||
inline Field getField() const {return field;}
|
inline Field getField() const {return field;}
|
||||||
|
@ -197,12 +256,15 @@ public:
|
||||||
inline bool getRotationAllowed() const {return rotationAllowed;}
|
inline bool getRotationAllowed() const {return rotationAllowed;}
|
||||||
inline Vec3f getLightColor() const {return lightColor;}
|
inline Vec3f getLightColor() const {return lightColor;}
|
||||||
inline bool getMultiSelect() const {return multiSelect;}
|
inline bool getMultiSelect() const {return multiSelect;}
|
||||||
|
inline bool isCommandable() const {return commandable;}
|
||||||
inline int getSight() const {return sight;}
|
inline int getSight() const {return sight;}
|
||||||
inline int getSize() const {return size;}
|
inline int getSize() const {return size;}
|
||||||
inline int getRenderSize() const {return renderSize;}
|
inline int getRenderSize() const {return renderSize;}
|
||||||
int getHeight() const {return height;}
|
int getHeight() const {return height;}
|
||||||
int getStoredResourceCount() const {return (int)storedResources.size();}
|
int getStoredResourceCount() const {return (int)storedResources.size();}
|
||||||
inline const Resource *getStoredResource(int i) const {return &storedResources[i];}
|
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;
|
bool getCellMapCell(int x, int y, CardinalDir facing) const;
|
||||||
inline bool getMeetingPoint() const {return meetingPoint;}
|
inline bool getMeetingPoint() const {return meetingPoint;}
|
||||||
inline bool getCountUnitDeathInStats() const {return countUnitDeathInStats;}
|
inline bool getCountUnitDeathInStats() const {return countUnitDeathInStats;}
|
||||||
|
|
|
@ -169,6 +169,19 @@ void UpgradeTypeBase::load(const XmlNode *upgradeNode, string upgradename) {
|
||||||
else {
|
else {
|
||||||
prodSpeed = 0;
|
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 {
|
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 {
|
int UpgradeTypeBase::getProdSpeed(const SkillType *st) const {
|
||||||
if(prodSpeedIsMultiplier == false || st == NULL) {
|
if(prodSpeedIsMultiplier == false || st == NULL) {
|
||||||
return prodSpeed;
|
return prodSpeed;
|
||||||
|
@ -347,6 +374,18 @@ string UpgradeTypeBase::getDesc(bool translatedValue) const{
|
||||||
str+= indent+lang.getString("ProductionSpeed",(translatedValue == true ? "" : "english")) + " +" + intToStr(prodSpeed);
|
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 != "") {
|
if(str != "") {
|
||||||
str += "\n";
|
str += "\n";
|
||||||
}
|
}
|
||||||
|
@ -821,6 +860,9 @@ void TotalUpgrade::reset() {
|
||||||
|
|
||||||
prodSpeed=0;
|
prodSpeed=0;
|
||||||
prodSpeedIsMultiplier=false;
|
prodSpeedIsMultiplier=false;
|
||||||
|
|
||||||
|
attackSpeed=0;
|
||||||
|
attackSpeedIsMultiplier=false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TotalUpgrade::sum(const UpgradeTypeBase *ut, const Unit *unit) {
|
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();
|
attackRangeIsMultiplier = ut->getAttackRangeIsMultiplier();
|
||||||
moveSpeedIsMultiplier = ut->getMoveSpeedIsMultiplier();
|
moveSpeedIsMultiplier = ut->getMoveSpeedIsMultiplier();
|
||||||
prodSpeedIsMultiplier = ut->getProdSpeedIsMultiplier();
|
prodSpeedIsMultiplier = ut->getProdSpeedIsMultiplier();
|
||||||
|
attackSpeedIsMultiplier = ut->getAttackSpeedIsMultiplier();
|
||||||
|
|
||||||
if(ut->getMaxHpIsMultiplier() == true) {
|
if(ut->getMaxHpIsMultiplier() == true) {
|
||||||
//printf("#1 Maxhp maxHp = %d, unit->getHp() = %d ut->getMaxHp() = %d\n",maxHp,unit->getHp(),ut->getMaxHp());
|
//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 {
|
else {
|
||||||
prodSpeed += ut->getProdSpeed(NULL);
|
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) {
|
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);
|
prodSpeed -= ut->getProdSpeed(NULL);
|
||||||
enforceMinimumValue(0,prodSpeed);
|
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) {
|
void TotalUpgrade::incLevel(const UnitType *ut) {
|
||||||
|
@ -1184,6 +1257,16 @@ void TotalUpgrade::saveGame(XmlNode *rootNode) const {
|
||||||
prodSpeedMorphIsMultiplierValueListNode->addAttribute("key",iterMap->first, mapTagReplacements);
|
prodSpeedMorphIsMultiplierValueListNode->addAttribute("key",iterMap->first, mapTagReplacements);
|
||||||
prodSpeedMorphIsMultiplierValueListNode->addAttribute("value",intToStr(iterMap->second), 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) {
|
void TotalUpgrade::loadGame(const XmlNode *rootNode) {
|
||||||
|
@ -1282,6 +1365,16 @@ void TotalUpgrade::loadGame(const XmlNode *rootNode) {
|
||||||
prodSpeedMorphIsMultiplierValueList[node->getAttribute("key")->getValue()] =
|
prodSpeedMorphIsMultiplierValueList[node->getAttribute("key")->getValue()] =
|
||||||
node->getAttribute("value")->getIntValue();
|
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
|
// 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_
|
#ifndef _GLEST_GAME_UPGRADETYPE_H_
|
||||||
#define _GLEST_GAME_UPGRADETYPE_H_
|
#define _GLEST_GAME_UPGRADETYPE_H_
|
||||||
|
|
||||||
|
@ -39,10 +47,9 @@ class MoveSkillType;
|
||||||
class ProduceSkillType;
|
class ProduceSkillType;
|
||||||
class Faction;
|
class Faction;
|
||||||
|
|
||||||
// ===============================
|
/**
|
||||||
// class UpgradeTypeBase
|
* Groups all information used for upgrades. Attack boosts also use this class for modifying stats.
|
||||||
// ===============================
|
*/
|
||||||
|
|
||||||
class UpgradeTypeBase {
|
class UpgradeTypeBase {
|
||||||
protected:
|
protected:
|
||||||
string upgradename;
|
string upgradename;
|
||||||
|
@ -64,23 +71,35 @@ protected:
|
||||||
|
|
||||||
int attackStrength;
|
int attackStrength;
|
||||||
bool attackStrengthIsMultiplier;
|
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;
|
std::map<string,int> attackStrengthMultiplierValueList;
|
||||||
|
|
||||||
int attackRange;
|
int attackRange;
|
||||||
bool attackRangeIsMultiplier;
|
bool attackRangeIsMultiplier;
|
||||||
std::map<string,int> attackRangeMultiplierValueList;
|
std::map<string,int> attackRangeMultiplierValueList; /**< @see #attackStrengthMultiplierValueList */
|
||||||
|
|
||||||
int moveSpeed;
|
int moveSpeed;
|
||||||
bool moveSpeedIsMultiplier;
|
bool moveSpeedIsMultiplier;
|
||||||
std::map<string,int> moveSpeedIsMultiplierValueList;
|
std::map<string,int> moveSpeedIsMultiplierValueList; /**< @see #attackStrengthMultiplierValueList */
|
||||||
|
|
||||||
int prodSpeed;
|
int prodSpeed;
|
||||||
bool prodSpeedIsMultiplier;
|
bool prodSpeedIsMultiplier;
|
||||||
std::map<string,int> prodSpeedProduceIsMultiplierValueList;
|
std::map<string,int> prodSpeedProduceIsMultiplierValueList; /**< @see #attackStrengthMultiplierValueList */
|
||||||
std::map<string,int> prodSpeedUpgradeIsMultiplierValueList;
|
std::map<string,int> prodSpeedUpgradeIsMultiplierValueList; /**< @see #attackStrengthMultiplierValueList */
|
||||||
std::map<string,int> prodSpeedMorphIsMultiplierValueList;
|
std::map<string,int> prodSpeedMorphIsMultiplierValueList; /**< @see #attackStrengthMultiplierValueList */
|
||||||
|
|
||||||
|
int attackSpeed;
|
||||||
|
bool attackSpeedIsMultiplier;
|
||||||
|
std::map<string,int> attackSpeedIsMultiplierValueList;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* Creates an UpgradeTypeBase with values such that there are no stat changes.
|
||||||
|
*/
|
||||||
UpgradeTypeBase() {
|
UpgradeTypeBase() {
|
||||||
maxHp = 0;;
|
maxHp = 0;;
|
||||||
maxHpIsMultiplier = false;
|
maxHpIsMultiplier = false;
|
||||||
|
@ -127,11 +146,30 @@ public:
|
||||||
bool getMoveSpeedIsMultiplier() const {return moveSpeedIsMultiplier;}
|
bool getMoveSpeedIsMultiplier() const {return moveSpeedIsMultiplier;}
|
||||||
int getProdSpeed(const SkillType *st) const;
|
int getProdSpeed(const SkillType *st) const;
|
||||||
bool getProdSpeedIsMultiplier() const {return prodSpeedIsMultiplier;}
|
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);
|
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;
|
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 toString() const {
|
||||||
std::string result = "";
|
std::string result = "";
|
||||||
|
|
||||||
|
@ -163,9 +201,14 @@ public:
|
||||||
return result;
|
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;
|
virtual void saveGame(XmlNode *rootNode) const;
|
||||||
static const UpgradeType * loadGame(const XmlNode *rootNode, Faction *faction);
|
static const UpgradeType * loadGame(const XmlNode *rootNode, Faction *faction);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates a checksum value for the upgrade.
|
||||||
|
*/
|
||||||
Checksum getCRC() {
|
Checksum getCRC() {
|
||||||
Checksum crcForUpgradeType;
|
Checksum crcForUpgradeType;
|
||||||
|
|
||||||
|
@ -207,58 +250,145 @@ public:
|
||||||
crcForUpgradeType.addInt64((int64)prodSpeedUpgradeIsMultiplierValueList.size());
|
crcForUpgradeType.addInt64((int64)prodSpeedUpgradeIsMultiplierValueList.size());
|
||||||
//std::map<string,int> prodSpeedMorphIsMultiplierValueList;
|
//std::map<string,int> prodSpeedMorphIsMultiplierValueList;
|
||||||
crcForUpgradeType.addInt64((int64)prodSpeedMorphIsMultiplierValueList.size());
|
crcForUpgradeType.addInt64((int64)prodSpeedMorphIsMultiplierValueList.size());
|
||||||
|
|
||||||
|
crcForUpgradeType.addInt(attackSpeed);
|
||||||
|
crcForUpgradeType.addInt(attackSpeedIsMultiplier);
|
||||||
|
|
||||||
return crcForUpgradeType;
|
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 {
|
class UpgradeType: public UpgradeTypeBase, public ProducibleType {
|
||||||
private:
|
private:
|
||||||
|
/**
|
||||||
|
* List of unit types (the "classes" of units, eg, swordman) that are affected by this upgrade.
|
||||||
|
*/
|
||||||
vector<const UnitType*> effects;
|
vector<const UnitType*> effects;
|
||||||
|
|
||||||
public:
|
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);
|
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,
|
void load(const string &dir, const TechTree *techTree,
|
||||||
const FactionType *factionType, Checksum* checksum,
|
const FactionType *factionType, Checksum* checksum,
|
||||||
Checksum* techtreeChecksum,
|
Checksum* techtreeChecksum,
|
||||||
std::map<string,vector<pair<string, string> > > &loadedFileList,
|
std::map<string,vector<pair<string, string> > > &loadedFileList,
|
||||||
bool validationMode=false);
|
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;
|
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();}
|
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];}
|
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;
|
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 string getReqDesc(bool translatedValue) const;
|
||||||
|
|
||||||
//virtual void saveGame(XmlNode *rootNode) const;
|
//virtual void saveGame(XmlNode *rootNode) const;
|
||||||
//virtual void loadGame(const XmlNode *rootNode);
|
//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 {
|
class TotalUpgrade: public UpgradeTypeBase {
|
||||||
public:
|
public:
|
||||||
TotalUpgrade();
|
TotalUpgrade();
|
||||||
virtual ~TotalUpgrade() {}
|
virtual ~TotalUpgrade() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resets all stat boosts (so there's effectively no upgrade).
|
||||||
|
*/
|
||||||
void reset();
|
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);
|
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);
|
void incLevel(const UnitType *ut);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Applies the upgrade. Just a delegate to TotalUpgrade::sum.
|
||||||
|
*/
|
||||||
void apply(const UpgradeTypeBase *ut, const Unit *unit);
|
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);
|
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;
|
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);
|
void loadGame(const XmlNode *rootNode);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -78,6 +78,7 @@ Checksum Scenario::load(const string &path) {
|
||||||
|
|
||||||
//parse xml
|
//parse xml
|
||||||
XmlTree xmlTree;
|
XmlTree xmlTree;
|
||||||
|
xmlTree.setSkipUpdatePathClimbingParts(true);
|
||||||
xmlTree.load(path,Properties::getTagReplacementValues());
|
xmlTree.load(path,Properties::getTagReplacementValues());
|
||||||
const XmlNode *scenarioNode= xmlTree.getRootNode();
|
const XmlNode *scenarioNode= xmlTree.getRootNode();
|
||||||
const XmlNode *scriptsNode= scenarioNode->getChild("scripts");
|
const XmlNode *scriptsNode= scenarioNode->getChild("scripts");
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include "network_manager.h"
|
#include "network_manager.h"
|
||||||
#include "object.h"
|
#include "object.h"
|
||||||
#include "particle_type.h"
|
#include "particle_type.h"
|
||||||
|
#include "projectile_type.h"
|
||||||
#include "path_finder.h"
|
#include "path_finder.h"
|
||||||
#include "renderer.h"
|
#include "renderer.h"
|
||||||
#include "sound.h"
|
#include "sound.h"
|
||||||
|
@ -127,16 +128,18 @@ bool UnitUpdater::updateUnit(Unit *unit) {
|
||||||
|
|
||||||
//play skill sound
|
//play skill sound
|
||||||
const SkillType *currSkill= unit->getCurrSkill();
|
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(soundStartTime >= unit->getLastAnimProgressAsFloat() && soundStartTime < unit->getAnimProgressAsFloat()) {
|
||||||
if(map->getSurfaceCell(Map::toSurfCoords(unit->getPos()))->isVisible(world->getThisTeamIndex()) ||
|
if(map->getSurfaceCell(Map::toSurfCoords(unit->getPos()))->isVisible(world->getThisTeamIndex()) ||
|
||||||
(game->getWorld()->showWorldForPlayer(game->getWorld()->getThisTeamIndex()) == true)) {
|
(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()) {
|
if (currSkill->getShake()) {
|
||||||
float shakeStartTime = currSkill->getShakeStartTime();
|
float shakeStartTime = currSkill->getShakeStartTime();
|
||||||
if (shakeStartTime >= unit->getLastAnimProgressAsFloat()
|
if (shakeStartTime >= unit->getLastAnimProgressAsFloat()
|
||||||
|
@ -186,14 +189,24 @@ bool UnitUpdater::updateUnit(Unit *unit) {
|
||||||
float attackStartTime = truncateDecimal<float>(ast->getAttackStartTime(),6);
|
float attackStartTime = truncateDecimal<float>(ast->getAttackStartTime(),6);
|
||||||
float lastAnimProgress = truncateDecimal<float>(unit->getLastAnimProgressAsFloat(),6);
|
float lastAnimProgress = truncateDecimal<float>(unit->getLastAnimProgressAsFloat(),6);
|
||||||
float animProgress = truncateDecimal<float>(unit->getAnimProgressAsFloat(),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]="";
|
char szBuf[8096]="";
|
||||||
snprintf(szBuf,8095,"attackStartTime = %f, lastAnimProgress = %f, animProgress = %f startAttackParticleSystemNow = %d",attackStartTime,lastAnimProgress,animProgress,startAttackParticleSystemNow);
|
snprintf(szBuf,8095,"attackStartTime = %f, lastAnimProgress = %f, animProgress = %f startAttackParticleSystemNow = %d",attackStartTime,lastAnimProgress,animProgress,startAttackParticleSystemNow);
|
||||||
unit->setNetworkCRCParticleLogInfo(szBuf);
|
unit->setNetworkCRCParticleLogInfo(szBuf);
|
||||||
|
|
||||||
if(startAttackParticleSystemNow == true) {
|
if(startAttackParticleSystemNow == true) {
|
||||||
startAttackParticleSystem(unit);
|
startAttackParticleSystem(unit,lastAnimProgress,animProgress);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -257,55 +270,12 @@ bool UnitUpdater::updateUnit(Unit *unit) {
|
||||||
else if(unit->getCommandSize() > 0) {
|
else if(unit->getCommandSize() > 0) {
|
||||||
Command *command= unit->getCurrCommand();
|
Command *command= unit->getCurrCommand();
|
||||||
if(command != NULL) {
|
if(command != NULL) {
|
||||||
const CommandType *ct = command->getCommandType();
|
|
||||||
|
|
||||||
const AttackCommandType *act= dynamic_cast<const AttackCommandType*>(command->getCommandType());
|
const AttackCommandType *act= dynamic_cast<const AttackCommandType*>(command->getCommandType());
|
||||||
if( act != NULL && act->getAttackSkillType() != NULL &&
|
if (act != NULL && act->getAttackSkillType() != NULL
|
||||||
act->getAttackSkillType()->getSpawnUnit() != "" && act->getAttackSkillType()->getSpawnUnitCount() > 0) {
|
&& act->getAttackSkillType()->getSpawnUnit() != ""
|
||||||
|
&& act->getAttackSkillType()->getSpawnUnitCount() > 0) {
|
||||||
const FactionType *ft= unit->getFaction()->getType();
|
spawnAttack(unit,act->getAttackSkillType()->getSpawnUnit(),act->getAttackSkillType()->getSpawnUnitCount(),act->getAttackSkillType()->getSpawnUnitAtTarget());
|
||||||
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());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -343,6 +313,65 @@ bool UnitUpdater::updateUnit(Unit *unit) {
|
||||||
return processUnitCommand;
|
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 ====================
|
// ==================== progress commands ====================
|
||||||
|
|
||||||
//VERY IMPORTANT: compute next state depending on the first order of the list
|
//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 ====================
|
// ==================== attack ====================
|
||||||
|
|
||||||
void UnitUpdater::hit(Unit *attacker){
|
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
|
//hit attack positions
|
||||||
if(ast != NULL && ast->getSplash()) {
|
if(ast != NULL && ast->getSplash()) {
|
||||||
char szBuf[8096]="";
|
char szBuf[8096]="";
|
||||||
|
@ -2511,7 +2540,7 @@ void UnitUpdater::hit(Unit *attacker, const AttackSkillType* ast, const Vec2i &t
|
||||||
|
|
||||||
float distance = pci.getPos().dist(targetPos);
|
float distance = pci.getPos().dist(targetPos);
|
||||||
distance = truncateDecimal<float>(distance,6);
|
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);
|
attacker->addNetworkCRCDecHp(szBuf);
|
||||||
|
|
||||||
if(attacked != NULL) {
|
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) {
|
if(attacker == NULL) {
|
||||||
throw megaglest_runtime_error("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 *= damageMultiplier;
|
||||||
damage = truncateDecimal<float>(damage,6);
|
damage = truncateDecimal<float>(damage,6);
|
||||||
|
|
||||||
|
damage = (damage*damagePercent)/100;
|
||||||
if(damage < 1) {
|
if(damage < 1) {
|
||||||
damage= 1;
|
damage= 1;
|
||||||
}
|
}
|
||||||
|
@ -2573,6 +2603,37 @@ void UnitUpdater::damage(Unit *attacker, const AttackSkillType* ast, Unit *attac
|
||||||
attacker->incKills(attacked->getTeam());
|
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()) {
|
switch(this->game->getGameSettings()->getPathFinderType()) {
|
||||||
case pfBasic:
|
case pfBasic:
|
||||||
break;
|
break;
|
||||||
|
@ -2592,18 +2653,18 @@ void UnitUpdater::damage(Unit *attacker, const AttackSkillType* ast, Unit *attac
|
||||||
//attacker->computeHp();
|
//attacker->computeHp();
|
||||||
}
|
}
|
||||||
|
|
||||||
void UnitUpdater::startAttackParticleSystem(Unit *unit){
|
void UnitUpdater::startAttackParticleSystem(Unit *unit, float lastAnimProgress, float animProgress){
|
||||||
Renderer &renderer= Renderer::getInstance();
|
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) {
|
if(ast == NULL) {
|
||||||
throw megaglest_runtime_error("Start attack particle 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 startPos= unit->getCurrVector();
|
||||||
Vec3f endPos= unit->getTargetVec();
|
Vec3f endPos= unit->getTargetVec();
|
||||||
|
|
||||||
|
@ -2615,39 +2676,51 @@ void UnitUpdater::startAttackParticleSystem(Unit *unit){
|
||||||
visible = true;
|
visible = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//projectile
|
//for(ProjectileParticleSystemTypes::const_iterator pit= unit->getCurrSkill()->projectileParticleSystemTypes.begin(); pit != unit->getCurrSkill()->projectileParticleSystemTypes.end(); ++pit) {
|
||||||
if(pstProj != NULL) {
|
for(ProjectileTypes::const_iterator pt= ast->projectileTypes.begin(); pt != ast->projectileTypes.end(); ++pt) {
|
||||||
psProj= pstProj->create(unit);
|
bool startAttackParticleSystemNow = ((*pt)->getAttackStartTime() >= lastAnimProgress && (*pt)->getAttackStartTime() < animProgress);
|
||||||
psProj->setPath(startPos, endPos);
|
if(startAttackParticleSystemNow){
|
||||||
psProj->setObserver(new ParticleDamager(unit, this, gameCamera));
|
ProjectileParticleSystem *psProj= (*pt)->getProjectileParticleSystemType()->create(unit);
|
||||||
psProj->setVisible(visible);
|
psProj->setPath(startPos, endPos);
|
||||||
if(unit->getFaction()->getTexture()) {
|
psProj->setObserver(new ParticleDamager(unit,(*pt), this, gameCamera));
|
||||||
psProj->setFactionColor(unit->getFaction()->getTexture()->getPixmapConst()->getPixel3f(0,0));
|
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]="";
|
char szBuf[8096]="";
|
||||||
snprintf(szBuf,8095,"Unit hitting [startAttackParticleSystem] no proj");
|
snprintf(szBuf,8095,"Unit hitting [startAttackParticleSystem] no proj");
|
||||||
unit->addNetworkCRCDecHp(szBuf);
|
unit->addNetworkCRCDecHp(szBuf);
|
||||||
|
|
||||||
hit(unit);
|
hit(unit);
|
||||||
}
|
//splash
|
||||||
|
if(pstSplash != NULL) {
|
||||||
//splash
|
SplashParticleSystem *psSplash= pstSplash->create(unit);
|
||||||
if(pstSplash != NULL) {
|
psSplash->setPos(endPos);
|
||||||
SplashParticleSystem *psSplash= pstSplash->create(unit);
|
psSplash->setVisible(visible);
|
||||||
psSplash->setPos(endPos);
|
if(unit->getFaction()->getTexture()) {
|
||||||
psSplash->setVisible(visible);
|
psSplash->setFactionColor(unit->getFaction()->getTexture()->getPixmapConst()->getPixel3f(0,0));
|
||||||
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
|
// 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->gameCamera= gameCamera;
|
||||||
this->attackerRef= attacker;
|
this->attackerRef= attacker;
|
||||||
|
this->projectileType= projectileType;
|
||||||
this->ast= static_cast<const AttackSkillType*>(attacker->getCurrSkill());
|
this->ast= static_cast<const AttackSkillType*>(attacker->getCurrSkill());
|
||||||
this->targetPos= attacker->getTargetPos();
|
this->targetPos= attacker->getTargetPos();
|
||||||
this->targetField= attacker->getTargetField();
|
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);
|
snprintf(szBuf,8095,"Unit hitting [ParticleDamager::update] [%s] targetField = %d",targetPos.getString().c_str(),targetField);
|
||||||
attacker->addNetworkCRCDecHp(szBuf);
|
attacker->addNetworkCRCDecHp(szBuf);
|
||||||
|
|
||||||
unitUpdater->hit(attacker, ast, targetPos, targetField);
|
unitUpdater->hit(attacker, ast, targetPos, targetField, projectileType->getDamagePercentage());
|
||||||
|
|
||||||
//char szBuf[8096]="";
|
//char szBuf[8096]="";
|
||||||
//snprintf(szBuf,8095,"ParticleDamager::update attacker particleSystem before: %s\nafter: %s",auditBeforeHit.c_str(),particleSystem->toString().c_str());
|
//snprintf(szBuf,8095,"ParticleDamager::update attacker particleSystem before: %s\nafter: %s",auditBeforeHit.c_str(),particleSystem->toString().c_str());
|
||||||
//attacker->setNetworkCRCParticleObserverLogInfo(szBuf);
|
//attacker->setNetworkCRCParticleObserverLogInfo(szBuf);
|
||||||
|
|
||||||
//play sound
|
//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) {
|
if(particleSystem->getVisible() && projSound != NULL) {
|
||||||
SoundRenderer::getInstance().playFx(projSound, attacker->getCurrVector(), gameCamera->getPos());
|
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);
|
particleSystem->setObserver(NULL);
|
||||||
delete this;
|
delete this;
|
||||||
|
|
|
@ -103,6 +103,7 @@ public:
|
||||||
|
|
||||||
//update skills
|
//update skills
|
||||||
bool updateUnit(Unit *unit);
|
bool updateUnit(Unit *unit);
|
||||||
|
void spawnAttack(Unit *unit,string spawnUnit,int spawnUnitcount,bool spawnUnitAtTarget,Vec2i targetPos=Vec2i(-10,-10));
|
||||||
|
|
||||||
//update commands
|
//update commands
|
||||||
void updateUnitCommand(Unit *unit, int frameIndex);
|
void updateUnitCommand(Unit *unit, int frameIndex);
|
||||||
|
@ -141,9 +142,9 @@ public:
|
||||||
private:
|
private:
|
||||||
//attack
|
//attack
|
||||||
void hit(Unit *attacker);
|
void hit(Unit *attacker);
|
||||||
void hit(Unit *attacker, const AttackSkillType* ast, const Vec2i &targetPos, Field targetField);
|
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);
|
void damage(Unit *attacker, const AttackSkillType* ast, Unit *attacked, float distance, int damagePercent);
|
||||||
void startAttackParticleSystem(Unit *unit);
|
void startAttackParticleSystem(Unit *unit, float lastAnimProgress, float animProgress);
|
||||||
|
|
||||||
//misc
|
//misc
|
||||||
bool searchForResource(Unit *unit, const HarvestCommandType *hct);
|
bool searchForResource(Unit *unit, const HarvestCommandType *hct);
|
||||||
|
@ -169,13 +170,14 @@ class ParticleDamager: public ParticleObserver {
|
||||||
public:
|
public:
|
||||||
UnitReference attackerRef;
|
UnitReference attackerRef;
|
||||||
const AttackSkillType* ast;
|
const AttackSkillType* ast;
|
||||||
|
const ProjectileType* projectileType;
|
||||||
UnitUpdater *unitUpdater;
|
UnitUpdater *unitUpdater;
|
||||||
const GameCamera *gameCamera;
|
const GameCamera *gameCamera;
|
||||||
Vec2i targetPos;
|
Vec2i targetPos;
|
||||||
Field targetField;
|
Field targetField;
|
||||||
|
|
||||||
public:
|
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 update(ParticleSystem *particleSystem);
|
||||||
|
|
||||||
virtual void saveGame(XmlNode *rootNode);
|
virtual void saveGame(XmlNode *rootNode);
|
||||||
|
|
|
@ -49,6 +49,8 @@ public:
|
||||||
Vec3f pos;
|
Vec3f pos;
|
||||||
Vec3f lastPos;
|
Vec3f lastPos;
|
||||||
Vec3f speed;
|
Vec3f speed;
|
||||||
|
float speedUpRelative;
|
||||||
|
Vec3f speedUpConstant;
|
||||||
Vec3f accel;
|
Vec3f accel;
|
||||||
Vec4f color;
|
Vec4f color;
|
||||||
float size;
|
float size;
|
||||||
|
@ -147,6 +149,8 @@ protected:
|
||||||
int varParticleEnergy;
|
int varParticleEnergy;
|
||||||
float particleSize;
|
float particleSize;
|
||||||
float speed;
|
float speed;
|
||||||
|
float speedUpRelative;
|
||||||
|
float speedUpConstant;
|
||||||
Vec3f factionColor;
|
Vec3f factionColor;
|
||||||
bool teamcolorNoEnergy;
|
bool teamcolorNoEnergy;
|
||||||
bool teamcolorEnergy;
|
bool teamcolorEnergy;
|
||||||
|
@ -192,6 +196,8 @@ public:
|
||||||
void setVarParticleEnergy(int varParticleEnergy);
|
void setVarParticleEnergy(int varParticleEnergy);
|
||||||
void setParticleSize(float particleSize);
|
void setParticleSize(float particleSize);
|
||||||
void setSpeed(float speed);
|
void setSpeed(float speed);
|
||||||
|
void setSpeedUpRelative(float speedUpRelative);
|
||||||
|
void setSpeedUpConstant(float speedUpConstant);
|
||||||
virtual void setActive(bool active);
|
virtual void setActive(bool active);
|
||||||
void setObserver(ParticleObserver *particleObserver);
|
void setObserver(ParticleObserver *particleObserver);
|
||||||
virtual void setVisible(bool visible);
|
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 endPathWithSlash(string &path, bool requireOSSlash=false);
|
||||||
void trimPathWithStartingSlash(string &path);
|
void trimPathWithStartingSlash(string &path);
|
||||||
void updatePathClimbingParts(string &path);
|
void updatePathClimbingParts(string &path,bool processPreviousDirTokenCheck=true);
|
||||||
string formatPath(string path);
|
string formatPath(string path);
|
||||||
|
|
||||||
string replaceAllHTMLEntities(string& context);
|
string replaceAllHTMLEntities(string& context);
|
||||||
|
|
|
@ -100,10 +100,10 @@ public:
|
||||||
|
|
||||||
bool hasString(const string &key) const;
|
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 std::map<string,string> getTagReplacementValues(std::map<string,string> *mapExtraTagReplacementValues=NULL);
|
||||||
static bool isValuePathVariable(const string &value);
|
static bool isValuePathVariable(const string &value);
|
||||||
static void updateValuePathVariable(string &value);
|
static void updateValuePathVariable(string &value, bool skipUpdatePathClimbingParts=false);
|
||||||
|
|
||||||
string getpath() const { return path;}
|
string getpath() const { return path;}
|
||||||
|
|
||||||
|
|
|
@ -124,7 +124,7 @@ public:
|
||||||
static bool isInitialized();
|
static bool isInitialized();
|
||||||
void cleanup();
|
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);
|
void save(const string &path, const XmlNode *node);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -138,6 +138,7 @@ private:
|
||||||
string loadPath;
|
string loadPath;
|
||||||
xml_engine_parser_type engine_type;
|
xml_engine_parser_type engine_type;
|
||||||
bool skipStackCheck;
|
bool skipStackCheck;
|
||||||
|
bool skipUpdatePathClimbingParts;
|
||||||
private:
|
private:
|
||||||
XmlTree(XmlTree&);
|
XmlTree(XmlTree&);
|
||||||
void operator =(XmlTree&);
|
void operator =(XmlTree&);
|
||||||
|
@ -147,6 +148,7 @@ public:
|
||||||
XmlTree(xml_engine_parser_type engine_type = XML_RAPIDXML_ENGINE);
|
XmlTree(xml_engine_parser_type engine_type = XML_RAPIDXML_ENGINE);
|
||||||
~XmlTree();
|
~XmlTree();
|
||||||
|
|
||||||
|
void setSkipUpdatePathClimbingParts(bool value);
|
||||||
void init(const string &name);
|
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 load(const string &path, const std::map<string,string> &mapTagReplacementValues, bool noValidation=false,bool skipStackCheck=false,bool skipStackTrace=false);
|
||||||
void save(const string &path);
|
void save(const string &path);
|
||||||
|
@ -182,7 +184,7 @@ public:
|
||||||
|
|
||||||
#endif
|
#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(const string &name);
|
||||||
~XmlNode();
|
~XmlNode();
|
||||||
|
|
||||||
|
|
|
@ -50,6 +50,10 @@ void Particle::saveGame(XmlNode *rootNode) {
|
||||||
particleNode->addAttribute("lastPos",lastPos.getString(), mapTagReplacements);
|
particleNode->addAttribute("lastPos",lastPos.getString(), mapTagReplacements);
|
||||||
// Vec3f speed;
|
// Vec3f speed;
|
||||||
particleNode->addAttribute("speed",speed.getString(), mapTagReplacements);
|
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;
|
// Vec3f accel;
|
||||||
particleNode->addAttribute("accel",accel.getString(), mapTagReplacements);
|
particleNode->addAttribute("accel",accel.getString(), mapTagReplacements);
|
||||||
// Vec4f color;
|
// Vec4f color;
|
||||||
|
@ -70,6 +74,10 @@ void Particle::loadGame(const XmlNode *rootNode) {
|
||||||
lastPos = Vec3f::strToVec3(particleNode->getAttribute("lastPos")->getValue());
|
lastPos = Vec3f::strToVec3(particleNode->getAttribute("lastPos")->getValue());
|
||||||
// Vec3f speed;
|
// Vec3f speed;
|
||||||
speed = Vec3f::strToVec3(particleNode->getAttribute("speed")->getValue());
|
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;
|
// Vec3f accel;
|
||||||
accel = Vec3f::strToVec3(particleNode->getAttribute("accel")->getValue());
|
accel = Vec3f::strToVec3(particleNode->getAttribute("accel")->getValue());
|
||||||
// Vec4f color;
|
// Vec4f color;
|
||||||
|
@ -290,6 +298,16 @@ void ParticleSystem::setSpeed(float speed){
|
||||||
this->speed = truncateDecimal<float>(this->speed,6);
|
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){
|
void ParticleSystem::setActive(bool active){
|
||||||
this->active= active;
|
this->active= active;
|
||||||
for(int i=getChildCount()-1; i>=0; i--)
|
for(int i=getChildCount()-1; i>=0; i--)
|
||||||
|
@ -1114,6 +1132,7 @@ void UnitParticleSystem::initParticle(Particle *p, int particleIndex){
|
||||||
p->lastPos= pos;
|
p->lastPos= pos;
|
||||||
oldPosition= pos;
|
oldPosition= pos;
|
||||||
p->size= particleSize;
|
p->size= particleSize;
|
||||||
|
p->speedUpRelative= speedUpRelative;
|
||||||
p->accel= Vec3f(0.0f, -gravity, 0.0f);
|
p->accel= Vec3f(0.0f, -gravity, 0.0f);
|
||||||
p->accel.x = truncateDecimal<float>(p->accel.x,6);
|
p->accel.x = truncateDecimal<float>(p->accel.x,6);
|
||||||
p->accel.y = truncateDecimal<float>(p->accel.y,6);
|
p->accel.y = truncateDecimal<float>(p->accel.y,6);
|
||||||
|
@ -1228,6 +1247,8 @@ void UnitParticleSystem::initParticle(Particle *p, int particleIndex){
|
||||||
} break;
|
} break;
|
||||||
default: throw megaglest_runtime_error("bad shape");
|
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(){
|
void UnitParticleSystem::update(){
|
||||||
|
@ -1299,6 +1320,8 @@ void UnitParticleSystem::updateParticle(Particle *p){
|
||||||
p->pos.z = truncateDecimal<float>(p->pos.z,6);
|
p->pos.z = truncateDecimal<float>(p->pos.z,6);
|
||||||
}
|
}
|
||||||
p->speed += p->accel;
|
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.x = truncateDecimal<float>(p->speed.x,6);
|
||||||
p->speed.y = truncateDecimal<float>(p->speed.y,6);
|
p->speed.y = truncateDecimal<float>(p->speed.y,6);
|
||||||
p->speed.z = truncateDecimal<float>(p->speed.z,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->energy= maxParticleEnergy;
|
||||||
p->size= particleSize;
|
p->size= particleSize;
|
||||||
p->color= color;
|
p->color= color;
|
||||||
|
p->speedUpRelative= speedUpRelative;
|
||||||
|
|
||||||
p->speed= Vec3f(horizontalSpreadA * random.randRange(-1.0f, 1.0f) + horizontalSpreadB, verticalSpreadA
|
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)
|
* 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.y = truncateDecimal<float>(p->accel.y,6);
|
||||||
p->accel.z = truncateDecimal<float>(p->accel.z,6);
|
p->accel.z = truncateDecimal<float>(p->accel.z,6);
|
||||||
|
|
||||||
|
p->speedUpConstant= Vec3f(speedUpConstant)*p->speed;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SplashParticleSystem::updateParticle(Particle *p){
|
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.y = truncateDecimal<float>(p->pos.y,6);
|
||||||
p->pos.z = truncateDecimal<float>(p->pos.z,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= p->speed + p->accel;
|
||||||
p->speed.x = truncateDecimal<float>(p->speed.x,6);
|
p->speed.x = truncateDecimal<float>(p->speed.x,6);
|
||||||
p->speed.y = truncateDecimal<float>(p->speed.y,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 /./
|
// Update paths with /./
|
||||||
string::size_type pos = path.find("/./");
|
string::size_type pos = path.find("/./");
|
||||||
if(pos != string::npos && pos != 0) {
|
if(pos != string::npos && pos != 0) {
|
||||||
|
@ -569,9 +569,11 @@ void updatePathClimbingParts(string &path) {
|
||||||
path.erase(pos,2);
|
path.erase(pos,2);
|
||||||
//pos--;
|
//pos--;
|
||||||
|
|
||||||
|
//printf("#1 CHANGE relative path from [%s] to [%s]\n",orig.c_str(),path.c_str());
|
||||||
|
|
||||||
pos = path.find("/./");
|
pos = path.find("/./");
|
||||||
if(pos != string::npos && pos != 0) {
|
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());
|
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;
|
string orig = path;
|
||||||
path.erase(pos,2);
|
path.erase(pos,2);
|
||||||
//pos--;
|
//pos--;
|
||||||
|
//printf("#w CHANGE relative path from [%s] to [%s]\n",orig.c_str(),path.c_str());
|
||||||
|
|
||||||
pos = path.find("\\.\\");
|
pos = path.find("\\.\\");
|
||||||
if(pos != string::npos && pos != 0) {
|
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());
|
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("CHANGED relative path from [%s] to [%s]\n",orig.c_str(),path.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update paths with ..
|
// Update paths with ..
|
||||||
pos = path.find("..");
|
if(processPreviousDirTokenCheck) {
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pos = path.find("..");
|
pos = path.find("..");
|
||||||
if(pos != string::npos && pos != 0) {
|
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") )
|
// if ( !strcmp (params[1], "quit") )
|
||||||
irc_cmd_quit (session, "of course, Master!");
|
// irc_cmd_quit (session, "of course, Master!");
|
||||||
|
//
|
||||||
if ( !strcmp (params[1], "help") ) {
|
// if ( !strcmp (params[1], "help") ) {
|
||||||
irc_cmd_msg (session, params[0], "quit, help, dcc chat, dcc send, ctcp");
|
// irc_cmd_msg (session, params[0], "quit, help, dcc chat, dcc send, ctcp");
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
if ( !strcmp (params[1], "ctcp") ) {
|
// if ( !strcmp (params[1], "ctcp") ) {
|
||||||
irc_cmd_ctcp_request (session, realNick, "PING 223");
|
// irc_cmd_ctcp_request (session, realNick, "PING 223");
|
||||||
irc_cmd_ctcp_request (session, realNick, "FINGER");
|
// irc_cmd_ctcp_request (session, realNick, "FINGER");
|
||||||
irc_cmd_ctcp_request (session, realNick, "VERSION");
|
// irc_cmd_ctcp_request (session, realNick, "VERSION");
|
||||||
irc_cmd_ctcp_request (session, realNick, "TIME");
|
// irc_cmd_ctcp_request (session, realNick, "TIME");
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
if ( !strcmp (params[1], "dcc chat") ) {
|
// if ( !strcmp (params[1], "dcc chat") ) {
|
||||||
irc_dcc_t dccid;
|
// irc_dcc_t dccid;
|
||||||
irc_dcc_chat (session, 0, realNick, dcc_recv_callback, &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(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("DCC chat ID: %d\n", dccid);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
if ( !strcmp (params[1], "dcc send") ) {
|
// if ( !strcmp (params[1], "dcc send") ) {
|
||||||
irc_dcc_t dccid;
|
// irc_dcc_t dccid;
|
||||||
irc_dcc_sendfile (session, 0, realNick, "irctest.c", dcc_file_recv_callback, &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(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("DCC send ID: %d\n", dccid);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
if ( !strcmp (params[1], "topic") ) {
|
// if ( !strcmp (params[1], "topic") ) {
|
||||||
irc_cmd_topic (session, params[0], 0);
|
// irc_cmd_topic (session, params[0], 0);
|
||||||
}
|
// }
|
||||||
else if ( strstr (params[1], "topic ") == params[1] ) {
|
// else if ( strstr (params[1], "topic ") == params[1] ) {
|
||||||
irc_cmd_topic (session, params[0], params[1] + 6);
|
// irc_cmd_topic (session, params[0], params[1] + 6);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
if ( strstr (params[1], "mode ") == params[1] )
|
// if ( strstr (params[1], "mode ") == params[1] )
|
||||||
irc_cmd_channel_mode (session, params[0], params[1] + 5);
|
// irc_cmd_channel_mode (session, params[0], params[1] + 5);
|
||||||
|
//
|
||||||
if ( strstr (params[1], "nick ") == params[1] )
|
// if ( strstr (params[1], "nick ") == params[1] )
|
||||||
irc_cmd_nick (session, params[1] + 5);
|
// irc_cmd_nick (session, params[1] + 5);
|
||||||
|
//
|
||||||
if ( strstr (params[1], "whois ") == params[1] )
|
// if ( strstr (params[1], "whois ") == params[1] )
|
||||||
irc_cmd_whois (session, params[1] + 5);
|
// 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) {
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
void Properties::updateValuePathVariable(string &value) {
|
void Properties::updateValuePathVariable(string &value, bool skipUpdatePathClimbingParts) {
|
||||||
replaceAll(value,"//","/");
|
replaceAll(value,"//","/");
|
||||||
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;
|
string originalValue = value;
|
||||||
bool valueRequiresPathUpdate = Properties::isValuePathVariable(value);
|
bool valueRequiresPathUpdate = Properties::isValuePathVariable(value);
|
||||||
//if(originalValue.find("$APPLICATIONDATAPATH") != string::npos) {
|
//if(originalValue.find("$APPLICATIONDATAPATH") != string::npos) {
|
||||||
|
@ -389,7 +391,7 @@ bool Properties::applyTagsToValue(string &value, const std::map<string,string> *
|
||||||
//}
|
//}
|
||||||
|
|
||||||
if(valueRequiresPathUpdate == true) {
|
if(valueRequiresPathUpdate == true) {
|
||||||
Properties::updateValuePathVariable(value);
|
Properties::updateValuePathVariable(value, skipUpdatePathClimbingParts);
|
||||||
}
|
}
|
||||||
return (originalValue != value);
|
return (originalValue != value);
|
||||||
}
|
}
|
||||||
|
|
|
@ -339,7 +339,8 @@ XmlIoRapid::~XmlIoRapid() {
|
||||||
cleanup();
|
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;
|
bool showPerfStats = SystemFlags::VERBOSE_MODE_ENABLED;
|
||||||
Chrono chrono;
|
Chrono chrono;
|
||||||
chrono.start();
|
chrono.start();
|
||||||
|
@ -388,7 +389,7 @@ XmlNode *XmlIoRapid::load(const string &path, const std::map<string,string> &map
|
||||||
|
|
||||||
// Load data and add terminating 0
|
// Load data and add terminating 0
|
||||||
vector<char> buffer;
|
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));
|
xmlFile.read(&buffer.front(), static_cast<streamsize>(file_size));
|
||||||
buffer[(unsigned int)file_size] = 0;
|
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());
|
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());
|
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->engine_type = engine_type;
|
||||||
this->skipStackCheck = false;
|
this->skipStackCheck = false;
|
||||||
|
this->skipUpdatePathClimbingParts = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void XmlTree::init(const string &name){
|
void XmlTree::init(const string &name){
|
||||||
|
@ -533,6 +535,10 @@ typedef std::vector<XmlTree*> LoadStack;
|
||||||
//static LoadStack loadStack;
|
//static LoadStack loadStack;
|
||||||
static string loadStackCacheName = string(__FILE__) + string("_loadStackCacheName");
|
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) {
|
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);
|
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
|
else
|
||||||
#endif
|
#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());
|
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
|
#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) {
|
if(node == NULL || node->name() == NULL) {
|
||||||
throw megaglest_runtime_error("XML structure seems to be corrupt!");
|
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();
|
for(xml_node<> *currentNode = node->first_node();
|
||||||
currentNode; currentNode = currentNode->next_sibling()) {
|
currentNode; currentNode = currentNode->next_sibling()) {
|
||||||
if(currentNode != NULL && currentNode->type() == node_element) {
|
if(currentNode != NULL && currentNode->type() == node_element) {
|
||||||
XmlNode *xmlNode= new XmlNode(currentNode, mapTagReplacementValues);
|
XmlNode *xmlNode= new XmlNode(currentNode, mapTagReplacementValues, skipUpdatePathClimbingParts);
|
||||||
children.push_back(xmlNode);
|
children.push_back(xmlNode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -696,8 +703,18 @@ XmlNode::XmlNode(xml_node<> *node, const std::map<string,string> &mapTagReplacem
|
||||||
|
|
||||||
//get value
|
//get value
|
||||||
if(node->type() == node_element && children.size() == 0) {
|
if(node->type() == node_element && children.size() == 0) {
|
||||||
text = node->value();
|
string xmlText = node->value();
|
||||||
Properties::applyTagsToValue(this->text,&mapTagReplacementValues);
|
|
||||||
|
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