1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-11-28 08:48:48 +02:00

* Final commit

This commit is contained in:
beegee1 2011-12-13 21:35:28 +00:00
parent 7f04ed990b
commit cce814c41b
76 changed files with 5877 additions and 4618 deletions

2
AI/EmptyAI/StdInc.cpp Normal file
View File

@ -0,0 +1,2 @@
// Creates the precompiled header
#include "StdInc.h"

325
AI/EmptyAI/StdInc.h Normal file
View File

@ -0,0 +1,325 @@
#pragma once
// Standard include file
// Should be treated as a precompiled header file in the compiler settings
// We generate a .PCH file for every project due to simplicity and some annoying bugs in VisualStudio
// This file shouldn't be changed, except if there is a important header file which is missing.
/*
* StdInc.h, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#include <cstdio>
#include <stdio.h>
#ifdef _WIN32
#include <tchar.h>
#else
#include "../../tchar_amigaos4.h"
#endif
#include <cmath>
#include <cassert>
#include <assert.h>
#include <vector>
#include <string>
#include <map>
#include <queue>
#include <set>
#include <utility>
#include <numeric>
#include <iostream>
#include <fstream>
#include <sstream>
#include <iomanip>
#include <algorithm>
#include <memory>
#include <cstdlib>
//filesystem version 3 causes problems (and it's default as of boost 1.46)
#define BOOST_FILESYSTEM_VERSION 2
#include <boost/algorithm/string.hpp>
#include <boost/assert.hpp>
#include <boost/assign.hpp>
#include <boost/bind.hpp>
#include <boost/cstdint.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/filesystem.hpp>
#include <boost/foreach.hpp>
#include <boost/format.hpp>
#include <boost/function.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/logic/tribool.hpp>
#include <boost/program_options.hpp>
#include <boost/thread.hpp>
#include <boost/unordered_set.hpp>
#ifdef ANDROID
#include <android/log.h>
#endif
// Integral data types
typedef boost::uint64_t ui64; //unsigned int 64 bits (8 bytes)
typedef boost::uint32_t ui32; //unsigned int 32 bits (4 bytes)
typedef boost::uint16_t ui16; //unsigned int 16 bits (2 bytes)
typedef boost::uint8_t ui8; //unsigned int 8 bits (1 byte)
typedef boost::int64_t si64; //signed int 64 bits (8 bytes)
typedef boost::int32_t si32; //signed int 32 bits (4 bytes)
typedef boost::int16_t si16; //signed int 16 bits (2 bytes)
typedef boost::int8_t si8; //signed int 8 bits (1 byte)
// Import + Export macro declarations
#ifdef _WIN32
#define DLL_EXPORT __declspec(dllexport)
#else
#if defined(__GNUC__) && __GNUC__ >= 4
#define DLL_EXPORT __attribute__ ((visibility("default")))
#else
#define DLL_EXPORT
#endif
#endif
#ifdef _WIN32
#define DLL_IMPORT __declspec(dllimport)
#else
#if defined(__GNUC__) && __GNUC__ >= 4
#define DLL_IMPORT __attribute__ ((visibility("default")))
#else
#define DLL_IMPORT
#endif
#endif
#ifdef VCMI_DLL
#define DLL_LINKAGE DLL_EXPORT
#else
#define DLL_LINKAGE DLL_IMPORT
#endif
//a normal std::map with a const operator[] for sanity
template<typename KeyT, typename ValT>
class bmap : public std::map<KeyT, ValT>
{
public:
const ValT & operator[](KeyT key) const
{
return find(key)->second;
}
ValT & operator[](KeyT key)
{
return static_cast<std::map<KeyT, ValT> &>(*this)[key];
}
template <typename Handler> void serialize(Handler &h, const int version)
{
h & static_cast<std::map<KeyT, ValT> &>(*this);
}
};
namespace vstd
{
//returns true if container c contains item i
template <typename Container, typename Item>
bool contains(const Container & c, const Item &i)
{
return std::find(c.begin(),c.end(),i) != c.end();
}
//returns true if map c contains item i
template <typename V, typename Item, typename Item2>
bool contains(const std::map<Item,V> & c, const Item2 &i)
{
return c.find(i)!=c.end();
}
//returns true if bmap c contains item i
template <typename V, typename Item, typename Item2>
bool contains(const bmap<Item,V> & c, const Item2 &i)
{
return c.find(i)!=c.end();
}
//returns true if unordered set c contains item i
template <typename Item>
bool contains(const boost::unordered_set<Item> & c, const Item &i)
{
return c.find(i)!=c.end();
}
//returns position of first element in vector c equal to s, if there is no such element, -1 is returned
template <typename T1, typename T2>
int find_pos(const std::vector<T1> & c, const T2 &s)
{
for(size_t i=0; i < c.size(); ++i)
if(c[i] == s)
return i;
return -1;
}
//Func(T1,T2) must say if these elements matches
template <typename T1, typename T2, typename Func>
int find_pos(const std::vector<T1> & c, const T2 &s, const Func &f)
{
for(size_t i=0; i < c.size(); ++i)
if(f(c[i],s))
return i;
return -1;
}
//returns iterator to the given element if present in container, end() if not
template <typename Container, typename Item>
typename Container::iterator find(Container & c, const Item &i)
{
return std::find(c.begin(),c.end(),i);
}
//returns const iterator to the given element if present in container, end() if not
template <typename Container, typename Item>
typename Container::const_iterator find(const Container & c, const Item &i)
{
return std::find(c.begin(),c.end(),i);
}
//removes element i from container c, returns false if c does not contain i
template <typename Container, typename Item>
typename Container::size_type operator-=(Container &c, const Item &i)
{
typename Container::iterator itr = find(c,i);
if(itr == c.end())
return false;
c.erase(itr);
return true;
}
//assigns greater of (a, b) to a and returns maximum of (a, b)
template <typename t1, typename t2>
t1 &amax(t1 &a, const t2 &b)
{
if(a >= b)
return a;
else
{
a = b;
return a;
}
}
//assigns smaller of (a, b) to a and returns minimum of (a, b)
template <typename t1, typename t2>
t1 &amin(t1 &a, const t2 &b)
{
if(a <= b)
return a;
else
{
a = b;
return a;
}
}
//makes a to fit the range <b, c>
template <typename t1, typename t2, typename t3>
t1 &abetween(t1 &a, const t2 &b, const t3 &c)
{
amax(a,b);
amin(a,c);
return a;
}
//checks if a is between b and c
template <typename t1, typename t2, typename t3>
bool isbetween(const t1 &a, const t2 &b, const t3 &c)
{
return a > b && a < c;
}
//checks if a is within b and c
template <typename t1, typename t2, typename t3>
bool iswithin(const t1 &a, const t2 &b, const t3 &c)
{
return a >= b && a <= c;
}
template <typename t1, typename t2>
struct assigner
{
public:
t1 &op1;
t2 op2;
assigner(t1 &a1, const t2 & a2)
:op1(a1), op2(a2)
{}
void operator()()
{
op1 = op2;
}
};
// Assigns value a2 to a1. The point of time of the real operation can be controlled
// with the () operator.
template <typename t1, typename t2>
assigner<t1,t2> assigno(t1 &a1, const t2 &a2)
{
return assigner<t1,t2>(a1,a2);
}
//deleted pointer and sets it to NULL
template <typename T>
void clear_pointer(T* &ptr)
{
delete ptr;
ptr = NULL;
}
}
using vstd::operator-=;
// can be used for counting arrays
template<typename T, size_t N> char (&_ArrayCountObj(const T (&)[N]))[N];
#define ARRAY_COUNT(arr) (sizeof(_ArrayCountObj(arr)))
//for explicit overrides
#ifdef _MSC_VER
#define OVERRIDE override
#else
#define OVERRIDE //is there any working counterpart?
#endif
//XXX pls dont - 'debug macros' are usually more trouble than it's worth
#define HANDLE_EXCEPTION \
catch (const std::exception& e) { \
tlog1 << e.what() << std::endl; \
throw; \
} \
catch (const std::exception * e) \
{ \
tlog1 << e->what()<< std::endl; \
throw; \
} \
catch (const std::string& e) { \
tlog1 << e << std::endl; \
throw; \
}
#define HANDLE_EXCEPTIONC(COMMAND) \
catch (const std::exception& e) { \
COMMAND; \
tlog1 << e.what() << std::endl; \
throw; \
} \
catch (const std::string &e) \
{ \
COMMAND; \
tlog1 << e << std::endl; \
throw; \
}
#include "../../lib/CLogger.h"

2
AI/GeniusAI/StdInc.cpp Normal file
View File

@ -0,0 +1,2 @@
// Creates the precompiled header
#include "StdInc.h"

325
AI/GeniusAI/StdInc.h Normal file
View File

@ -0,0 +1,325 @@
#pragma once
// Standard include file
// Should be treated as a precompiled header file in the compiler settings
// We generate a .PCH file for every project due to simplicity and some annoying bugs in VisualStudio
// This file shouldn't be changed, except if there is a important header file which is missing.
/*
* StdInc.h, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#include <cstdio>
#include <stdio.h>
#ifdef _WIN32
#include <tchar.h>
#else
#include "../../tchar_amigaos4.h"
#endif
#include <cmath>
#include <cassert>
#include <assert.h>
#include <vector>
#include <string>
#include <map>
#include <queue>
#include <set>
#include <utility>
#include <numeric>
#include <iostream>
#include <fstream>
#include <sstream>
#include <iomanip>
#include <algorithm>
#include <memory>
#include <cstdlib>
//filesystem version 3 causes problems (and it's default as of boost 1.46)
#define BOOST_FILESYSTEM_VERSION 2
#include <boost/algorithm/string.hpp>
#include <boost/assert.hpp>
#include <boost/assign.hpp>
#include <boost/bind.hpp>
#include <boost/cstdint.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/filesystem.hpp>
#include <boost/foreach.hpp>
#include <boost/format.hpp>
#include <boost/function.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/logic/tribool.hpp>
#include <boost/program_options.hpp>
#include <boost/thread.hpp>
#include <boost/unordered_set.hpp>
#ifdef ANDROID
#include <android/log.h>
#endif
// Integral data types
typedef boost::uint64_t ui64; //unsigned int 64 bits (8 bytes)
typedef boost::uint32_t ui32; //unsigned int 32 bits (4 bytes)
typedef boost::uint16_t ui16; //unsigned int 16 bits (2 bytes)
typedef boost::uint8_t ui8; //unsigned int 8 bits (1 byte)
typedef boost::int64_t si64; //signed int 64 bits (8 bytes)
typedef boost::int32_t si32; //signed int 32 bits (4 bytes)
typedef boost::int16_t si16; //signed int 16 bits (2 bytes)
typedef boost::int8_t si8; //signed int 8 bits (1 byte)
// Import + Export macro declarations
#ifdef _WIN32
#define DLL_EXPORT __declspec(dllexport)
#else
#if defined(__GNUC__) && __GNUC__ >= 4
#define DLL_EXPORT __attribute__ ((visibility("default")))
#else
#define DLL_EXPORT
#endif
#endif
#ifdef _WIN32
#define DLL_IMPORT __declspec(dllimport)
#else
#if defined(__GNUC__) && __GNUC__ >= 4
#define DLL_IMPORT __attribute__ ((visibility("default")))
#else
#define DLL_IMPORT
#endif
#endif
#ifdef VCMI_DLL
#define DLL_LINKAGE DLL_EXPORT
#else
#define DLL_LINKAGE DLL_IMPORT
#endif
//a normal std::map with a const operator[] for sanity
template<typename KeyT, typename ValT>
class bmap : public std::map<KeyT, ValT>
{
public:
const ValT & operator[](KeyT key) const
{
return find(key)->second;
}
ValT & operator[](KeyT key)
{
return static_cast<std::map<KeyT, ValT> &>(*this)[key];
}
template <typename Handler> void serialize(Handler &h, const int version)
{
h & static_cast<std::map<KeyT, ValT> &>(*this);
}
};
namespace vstd
{
//returns true if container c contains item i
template <typename Container, typename Item>
bool contains(const Container & c, const Item &i)
{
return std::find(c.begin(),c.end(),i) != c.end();
}
//returns true if map c contains item i
template <typename V, typename Item, typename Item2>
bool contains(const std::map<Item,V> & c, const Item2 &i)
{
return c.find(i)!=c.end();
}
//returns true if bmap c contains item i
template <typename V, typename Item, typename Item2>
bool contains(const bmap<Item,V> & c, const Item2 &i)
{
return c.find(i)!=c.end();
}
//returns true if unordered set c contains item i
template <typename Item>
bool contains(const boost::unordered_set<Item> & c, const Item &i)
{
return c.find(i)!=c.end();
}
//returns position of first element in vector c equal to s, if there is no such element, -1 is returned
template <typename T1, typename T2>
int find_pos(const std::vector<T1> & c, const T2 &s)
{
for(size_t i=0; i < c.size(); ++i)
if(c[i] == s)
return i;
return -1;
}
//Func(T1,T2) must say if these elements matches
template <typename T1, typename T2, typename Func>
int find_pos(const std::vector<T1> & c, const T2 &s, const Func &f)
{
for(size_t i=0; i < c.size(); ++i)
if(f(c[i],s))
return i;
return -1;
}
//returns iterator to the given element if present in container, end() if not
template <typename Container, typename Item>
typename Container::iterator find(Container & c, const Item &i)
{
return std::find(c.begin(),c.end(),i);
}
//returns const iterator to the given element if present in container, end() if not
template <typename Container, typename Item>
typename Container::const_iterator find(const Container & c, const Item &i)
{
return std::find(c.begin(),c.end(),i);
}
//removes element i from container c, returns false if c does not contain i
template <typename Container, typename Item>
typename Container::size_type operator-=(Container &c, const Item &i)
{
typename Container::iterator itr = find(c,i);
if(itr == c.end())
return false;
c.erase(itr);
return true;
}
//assigns greater of (a, b) to a and returns maximum of (a, b)
template <typename t1, typename t2>
t1 &amax(t1 &a, const t2 &b)
{
if(a >= b)
return a;
else
{
a = b;
return a;
}
}
//assigns smaller of (a, b) to a and returns minimum of (a, b)
template <typename t1, typename t2>
t1 &amin(t1 &a, const t2 &b)
{
if(a <= b)
return a;
else
{
a = b;
return a;
}
}
//makes a to fit the range <b, c>
template <typename t1, typename t2, typename t3>
t1 &abetween(t1 &a, const t2 &b, const t3 &c)
{
amax(a,b);
amin(a,c);
return a;
}
//checks if a is between b and c
template <typename t1, typename t2, typename t3>
bool isbetween(const t1 &a, const t2 &b, const t3 &c)
{
return a > b && a < c;
}
//checks if a is within b and c
template <typename t1, typename t2, typename t3>
bool iswithin(const t1 &a, const t2 &b, const t3 &c)
{
return a >= b && a <= c;
}
template <typename t1, typename t2>
struct assigner
{
public:
t1 &op1;
t2 op2;
assigner(t1 &a1, const t2 & a2)
:op1(a1), op2(a2)
{}
void operator()()
{
op1 = op2;
}
};
// Assigns value a2 to a1. The point of time of the real operation can be controlled
// with the () operator.
template <typename t1, typename t2>
assigner<t1,t2> assigno(t1 &a1, const t2 &a2)
{
return assigner<t1,t2>(a1,a2);
}
//deleted pointer and sets it to NULL
template <typename T>
void clear_pointer(T* &ptr)
{
delete ptr;
ptr = NULL;
}
}
using vstd::operator-=;
// can be used for counting arrays
template<typename T, size_t N> char (&_ArrayCountObj(const T (&)[N]))[N];
#define ARRAY_COUNT(arr) (sizeof(_ArrayCountObj(arr)))
//for explicit overrides
#ifdef _MSC_VER
#define OVERRIDE override
#else
#define OVERRIDE //is there any working counterpart?
#endif
//XXX pls dont - 'debug macros' are usually more trouble than it's worth
#define HANDLE_EXCEPTION \
catch (const std::exception& e) { \
tlog1 << e.what() << std::endl; \
throw; \
} \
catch (const std::exception * e) \
{ \
tlog1 << e->what()<< std::endl; \
throw; \
} \
catch (const std::string& e) { \
tlog1 << e << std::endl; \
throw; \
}
#define HANDLE_EXCEPTIONC(COMMAND) \
catch (const std::exception& e) { \
COMMAND; \
tlog1 << e.what() << std::endl; \
throw; \
} \
catch (const std::string &e) \
{ \
COMMAND; \
tlog1 << e << std::endl; \
throw; \
}
#include "../../lib/CLogger.h"

2
AI/StupidAI/StdInc.cpp Normal file
View File

@ -0,0 +1,2 @@
// Creates the precompiled header
#include "StdInc.h"

325
AI/StupidAI/StdInc.h Normal file
View File

@ -0,0 +1,325 @@
#pragma once
// Standard include file
// Should be treated as a precompiled header file in the compiler settings
// We generate a .PCH file for every project due to simplicity and some annoying bugs in VisualStudio
// This file shouldn't be changed, except if there is a important header file which is missing.
/*
* StdInc.h, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#include <cstdio>
#include <stdio.h>
#ifdef _WIN32
#include <tchar.h>
#else
#include "../../tchar_amigaos4.h"
#endif
#include <cmath>
#include <cassert>
#include <assert.h>
#include <vector>
#include <string>
#include <map>
#include <queue>
#include <set>
#include <utility>
#include <numeric>
#include <iostream>
#include <fstream>
#include <sstream>
#include <iomanip>
#include <algorithm>
#include <memory>
#include <cstdlib>
//filesystem version 3 causes problems (and it's default as of boost 1.46)
#define BOOST_FILESYSTEM_VERSION 2
#include <boost/algorithm/string.hpp>
#include <boost/assert.hpp>
#include <boost/assign.hpp>
#include <boost/bind.hpp>
#include <boost/cstdint.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/filesystem.hpp>
#include <boost/foreach.hpp>
#include <boost/format.hpp>
#include <boost/function.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/logic/tribool.hpp>
#include <boost/program_options.hpp>
#include <boost/thread.hpp>
#include <boost/unordered_set.hpp>
#ifdef ANDROID
#include <android/log.h>
#endif
// Integral data types
typedef boost::uint64_t ui64; //unsigned int 64 bits (8 bytes)
typedef boost::uint32_t ui32; //unsigned int 32 bits (4 bytes)
typedef boost::uint16_t ui16; //unsigned int 16 bits (2 bytes)
typedef boost::uint8_t ui8; //unsigned int 8 bits (1 byte)
typedef boost::int64_t si64; //signed int 64 bits (8 bytes)
typedef boost::int32_t si32; //signed int 32 bits (4 bytes)
typedef boost::int16_t si16; //signed int 16 bits (2 bytes)
typedef boost::int8_t si8; //signed int 8 bits (1 byte)
// Import + Export macro declarations
#ifdef _WIN32
#define DLL_EXPORT __declspec(dllexport)
#else
#if defined(__GNUC__) && __GNUC__ >= 4
#define DLL_EXPORT __attribute__ ((visibility("default")))
#else
#define DLL_EXPORT
#endif
#endif
#ifdef _WIN32
#define DLL_IMPORT __declspec(dllimport)
#else
#if defined(__GNUC__) && __GNUC__ >= 4
#define DLL_IMPORT __attribute__ ((visibility("default")))
#else
#define DLL_IMPORT
#endif
#endif
#ifdef VCMI_DLL
#define DLL_LINKAGE DLL_EXPORT
#else
#define DLL_LINKAGE DLL_IMPORT
#endif
//a normal std::map with a const operator[] for sanity
template<typename KeyT, typename ValT>
class bmap : public std::map<KeyT, ValT>
{
public:
const ValT & operator[](KeyT key) const
{
return find(key)->second;
}
ValT & operator[](KeyT key)
{
return static_cast<std::map<KeyT, ValT> &>(*this)[key];
}
template <typename Handler> void serialize(Handler &h, const int version)
{
h & static_cast<std::map<KeyT, ValT> &>(*this);
}
};
namespace vstd
{
//returns true if container c contains item i
template <typename Container, typename Item>
bool contains(const Container & c, const Item &i)
{
return std::find(c.begin(),c.end(),i) != c.end();
}
//returns true if map c contains item i
template <typename V, typename Item, typename Item2>
bool contains(const std::map<Item,V> & c, const Item2 &i)
{
return c.find(i)!=c.end();
}
//returns true if bmap c contains item i
template <typename V, typename Item, typename Item2>
bool contains(const bmap<Item,V> & c, const Item2 &i)
{
return c.find(i)!=c.end();
}
//returns true if unordered set c contains item i
template <typename Item>
bool contains(const boost::unordered_set<Item> & c, const Item &i)
{
return c.find(i)!=c.end();
}
//returns position of first element in vector c equal to s, if there is no such element, -1 is returned
template <typename T1, typename T2>
int find_pos(const std::vector<T1> & c, const T2 &s)
{
for(size_t i=0; i < c.size(); ++i)
if(c[i] == s)
return i;
return -1;
}
//Func(T1,T2) must say if these elements matches
template <typename T1, typename T2, typename Func>
int find_pos(const std::vector<T1> & c, const T2 &s, const Func &f)
{
for(size_t i=0; i < c.size(); ++i)
if(f(c[i],s))
return i;
return -1;
}
//returns iterator to the given element if present in container, end() if not
template <typename Container, typename Item>
typename Container::iterator find(Container & c, const Item &i)
{
return std::find(c.begin(),c.end(),i);
}
//returns const iterator to the given element if present in container, end() if not
template <typename Container, typename Item>
typename Container::const_iterator find(const Container & c, const Item &i)
{
return std::find(c.begin(),c.end(),i);
}
//removes element i from container c, returns false if c does not contain i
template <typename Container, typename Item>
typename Container::size_type operator-=(Container &c, const Item &i)
{
typename Container::iterator itr = find(c,i);
if(itr == c.end())
return false;
c.erase(itr);
return true;
}
//assigns greater of (a, b) to a and returns maximum of (a, b)
template <typename t1, typename t2>
t1 &amax(t1 &a, const t2 &b)
{
if(a >= b)
return a;
else
{
a = b;
return a;
}
}
//assigns smaller of (a, b) to a and returns minimum of (a, b)
template <typename t1, typename t2>
t1 &amin(t1 &a, const t2 &b)
{
if(a <= b)
return a;
else
{
a = b;
return a;
}
}
//makes a to fit the range <b, c>
template <typename t1, typename t2, typename t3>
t1 &abetween(t1 &a, const t2 &b, const t3 &c)
{
amax(a,b);
amin(a,c);
return a;
}
//checks if a is between b and c
template <typename t1, typename t2, typename t3>
bool isbetween(const t1 &a, const t2 &b, const t3 &c)
{
return a > b && a < c;
}
//checks if a is within b and c
template <typename t1, typename t2, typename t3>
bool iswithin(const t1 &a, const t2 &b, const t3 &c)
{
return a >= b && a <= c;
}
template <typename t1, typename t2>
struct assigner
{
public:
t1 &op1;
t2 op2;
assigner(t1 &a1, const t2 & a2)
:op1(a1), op2(a2)
{}
void operator()()
{
op1 = op2;
}
};
// Assigns value a2 to a1. The point of time of the real operation can be controlled
// with the () operator.
template <typename t1, typename t2>
assigner<t1,t2> assigno(t1 &a1, const t2 &a2)
{
return assigner<t1,t2>(a1,a2);
}
//deleted pointer and sets it to NULL
template <typename T>
void clear_pointer(T* &ptr)
{
delete ptr;
ptr = NULL;
}
}
using vstd::operator-=;
// can be used for counting arrays
template<typename T, size_t N> char (&_ArrayCountObj(const T (&)[N]))[N];
#define ARRAY_COUNT(arr) (sizeof(_ArrayCountObj(arr)))
//for explicit overrides
#ifdef _MSC_VER
#define OVERRIDE override
#else
#define OVERRIDE //is there any working counterpart?
#endif
//XXX pls dont - 'debug macros' are usually more trouble than it's worth
#define HANDLE_EXCEPTION \
catch (const std::exception& e) { \
tlog1 << e.what() << std::endl; \
throw; \
} \
catch (const std::exception * e) \
{ \
tlog1 << e->what()<< std::endl; \
throw; \
} \
catch (const std::string& e) { \
tlog1 << e << std::endl; \
throw; \
}
#define HANDLE_EXCEPTIONC(COMMAND) \
catch (const std::exception& e) { \
COMMAND; \
tlog1 << e.what() << std::endl; \
throw; \
} \
catch (const std::string &e) \
{ \
COMMAND; \
tlog1 << e << std::endl; \
throw; \
}
#include "../../lib/CLogger.h"

View File

@ -1 +0,0 @@
#include "stdafx.h"

View File

@ -1,3 +0,0 @@
#pragma once
#include <boost/lexical_cast.hpp>
#include "../../AI_Base.h"

2
Scripting/ERM/StdInc.cpp Normal file
View File

@ -0,0 +1,2 @@
// Creates the precompiled header
#include "StdInc.h"

325
Scripting/ERM/StdInc.h Normal file
View File

@ -0,0 +1,325 @@
#pragma once
// Standard include file
// Should be treated as a precompiled header file in the compiler settings
// We generate a .PCH file for every project due to simplicity and some annoying bugs in VisualStudio
// This file shouldn't be changed, except if there is a important header file which is missing.
/*
* StdInc.h, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#include <cstdio>
#include <stdio.h>
#ifdef _WIN32
#include <tchar.h>
#else
#include "../../tchar_amigaos4.h"
#endif
#include <cmath>
#include <cassert>
#include <assert.h>
#include <vector>
#include <string>
#include <map>
#include <queue>
#include <set>
#include <utility>
#include <numeric>
#include <iostream>
#include <fstream>
#include <sstream>
#include <iomanip>
#include <algorithm>
#include <memory>
#include <cstdlib>
//filesystem version 3 causes problems (and it's default as of boost 1.46)
#define BOOST_FILESYSTEM_VERSION 2
#include <boost/algorithm/string.hpp>
#include <boost/assert.hpp>
#include <boost/assign.hpp>
#include <boost/bind.hpp>
#include <boost/cstdint.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/filesystem.hpp>
#include <boost/foreach.hpp>
#include <boost/format.hpp>
#include <boost/function.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/logic/tribool.hpp>
#include <boost/program_options.hpp>
#include <boost/thread.hpp>
#include <boost/unordered_set.hpp>
#ifdef ANDROID
#include <android/log.h>
#endif
// Integral data types
typedef boost::uint64_t ui64; //unsigned int 64 bits (8 bytes)
typedef boost::uint32_t ui32; //unsigned int 32 bits (4 bytes)
typedef boost::uint16_t ui16; //unsigned int 16 bits (2 bytes)
typedef boost::uint8_t ui8; //unsigned int 8 bits (1 byte)
typedef boost::int64_t si64; //signed int 64 bits (8 bytes)
typedef boost::int32_t si32; //signed int 32 bits (4 bytes)
typedef boost::int16_t si16; //signed int 16 bits (2 bytes)
typedef boost::int8_t si8; //signed int 8 bits (1 byte)
// Import + Export macro declarations
#ifdef _WIN32
#define DLL_EXPORT __declspec(dllexport)
#else
#if defined(__GNUC__) && __GNUC__ >= 4
#define DLL_EXPORT __attribute__ ((visibility("default")))
#else
#define DLL_EXPORT
#endif
#endif
#ifdef _WIN32
#define DLL_IMPORT __declspec(dllimport)
#else
#if defined(__GNUC__) && __GNUC__ >= 4
#define DLL_IMPORT __attribute__ ((visibility("default")))
#else
#define DLL_IMPORT
#endif
#endif
#ifdef VCMI_DLL
#define DLL_LINKAGE DLL_EXPORT
#else
#define DLL_LINKAGE DLL_IMPORT
#endif
//a normal std::map with a const operator[] for sanity
template<typename KeyT, typename ValT>
class bmap : public std::map<KeyT, ValT>
{
public:
const ValT & operator[](KeyT key) const
{
return find(key)->second;
}
ValT & operator[](KeyT key)
{
return static_cast<std::map<KeyT, ValT> &>(*this)[key];
}
template <typename Handler> void serialize(Handler &h, const int version)
{
h & static_cast<std::map<KeyT, ValT> &>(*this);
}
};
namespace vstd
{
//returns true if container c contains item i
template <typename Container, typename Item>
bool contains(const Container & c, const Item &i)
{
return std::find(c.begin(),c.end(),i) != c.end();
}
//returns true if map c contains item i
template <typename V, typename Item, typename Item2>
bool contains(const std::map<Item,V> & c, const Item2 &i)
{
return c.find(i)!=c.end();
}
//returns true if bmap c contains item i
template <typename V, typename Item, typename Item2>
bool contains(const bmap<Item,V> & c, const Item2 &i)
{
return c.find(i)!=c.end();
}
//returns true if unordered set c contains item i
template <typename Item>
bool contains(const boost::unordered_set<Item> & c, const Item &i)
{
return c.find(i)!=c.end();
}
//returns position of first element in vector c equal to s, if there is no such element, -1 is returned
template <typename T1, typename T2>
int find_pos(const std::vector<T1> & c, const T2 &s)
{
for(size_t i=0; i < c.size(); ++i)
if(c[i] == s)
return i;
return -1;
}
//Func(T1,T2) must say if these elements matches
template <typename T1, typename T2, typename Func>
int find_pos(const std::vector<T1> & c, const T2 &s, const Func &f)
{
for(size_t i=0; i < c.size(); ++i)
if(f(c[i],s))
return i;
return -1;
}
//returns iterator to the given element if present in container, end() if not
template <typename Container, typename Item>
typename Container::iterator find(Container & c, const Item &i)
{
return std::find(c.begin(),c.end(),i);
}
//returns const iterator to the given element if present in container, end() if not
template <typename Container, typename Item>
typename Container::const_iterator find(const Container & c, const Item &i)
{
return std::find(c.begin(),c.end(),i);
}
//removes element i from container c, returns false if c does not contain i
template <typename Container, typename Item>
typename Container::size_type operator-=(Container &c, const Item &i)
{
typename Container::iterator itr = find(c,i);
if(itr == c.end())
return false;
c.erase(itr);
return true;
}
//assigns greater of (a, b) to a and returns maximum of (a, b)
template <typename t1, typename t2>
t1 &amax(t1 &a, const t2 &b)
{
if(a >= b)
return a;
else
{
a = b;
return a;
}
}
//assigns smaller of (a, b) to a and returns minimum of (a, b)
template <typename t1, typename t2>
t1 &amin(t1 &a, const t2 &b)
{
if(a <= b)
return a;
else
{
a = b;
return a;
}
}
//makes a to fit the range <b, c>
template <typename t1, typename t2, typename t3>
t1 &abetween(t1 &a, const t2 &b, const t3 &c)
{
amax(a,b);
amin(a,c);
return a;
}
//checks if a is between b and c
template <typename t1, typename t2, typename t3>
bool isbetween(const t1 &a, const t2 &b, const t3 &c)
{
return a > b && a < c;
}
//checks if a is within b and c
template <typename t1, typename t2, typename t3>
bool iswithin(const t1 &a, const t2 &b, const t3 &c)
{
return a >= b && a <= c;
}
template <typename t1, typename t2>
struct assigner
{
public:
t1 &op1;
t2 op2;
assigner(t1 &a1, const t2 & a2)
:op1(a1), op2(a2)
{}
void operator()()
{
op1 = op2;
}
};
// Assigns value a2 to a1. The point of time of the real operation can be controlled
// with the () operator.
template <typename t1, typename t2>
assigner<t1,t2> assigno(t1 &a1, const t2 &a2)
{
return assigner<t1,t2>(a1,a2);
}
//deleted pointer and sets it to NULL
template <typename T>
void clear_pointer(T* &ptr)
{
delete ptr;
ptr = NULL;
}
}
using vstd::operator-=;
// can be used for counting arrays
template<typename T, size_t N> char (&_ArrayCountObj(const T (&)[N]))[N];
#define ARRAY_COUNT(arr) (sizeof(_ArrayCountObj(arr)))
//for explicit overrides
#ifdef _MSC_VER
#define OVERRIDE override
#else
#define OVERRIDE //is there any working counterpart?
#endif
//XXX pls dont - 'debug macros' are usually more trouble than it's worth
#define HANDLE_EXCEPTION \
catch (const std::exception& e) { \
tlog1 << e.what() << std::endl; \
throw; \
} \
catch (const std::exception * e) \
{ \
tlog1 << e->what()<< std::endl; \
throw; \
} \
catch (const std::string& e) { \
tlog1 << e << std::endl; \
throw; \
}
#define HANDLE_EXCEPTIONC(COMMAND) \
catch (const std::exception& e) { \
COMMAND; \
tlog1 << e.what() << std::endl; \
throw; \
} \
catch (const std::string &e) \
{ \
COMMAND; \
tlog1 << e << std::endl; \
throw; \
}
#include "../../lib/CLogger.h"

View File

@ -0,0 +1,51 @@
#include "StdInc.h"
#include "CAttackAnimation.h"
#include "../CMusicHandler.h"
#include "../CGameInfo.h"
#include "CBattleInterface.h"
#include "../CCreatureAnimation.h"
#include "../../lib/BattleState.h"
#include "../CPlayerInterface.h"
#include "../../CCallback.h"
void CAttackAnimation::nextFrame()
{
if(myAnim()->getType() != group)
myAnim()->setType(group);
if(myAnim()->onFirstFrameInGroup())
{
if(shooting)
CCS->soundh->playSound(battle_sound(attackingStack->getCreature(), shoot));
else
CCS->soundh->playSound(battle_sound(attackingStack->getCreature(), attack));
}
else if(myAnim()->onLastFrameInGroup())
{
myAnim()->setType(CCreatureAnim::HOLDING);
endAnim();
return; //execution of endAnim deletes this !!!
}
}
bool CAttackAnimation::checkInitialConditions()
{
return isEarliest(false);
}
CAttackAnimation::CAttackAnimation(CBattleInterface *_owner, const CStack *attacker, SHexField _dest, const CStack *defender)
: CBattleStackAnimation(_owner, attacker), dest(_dest), attackedStack(defender), attackingStack(attacker)
{
assert(attackingStack && "attackingStack is NULL in CBattleAttack::CBattleAttack !\n");
if(attackingStack->getCreature()->idNumber != 145) //catapult is allowed to attack not-creature
{
assert(attackedStack && "attackedStack is NULL in CBattleAttack::CBattleAttack !\n");
}
else //catapult can attack walls only
{
assert(owner->curInt->cb->battleGetWallUnderHex(_dest) >= 0);
}
attackingStackPosBeforeReturn = attackingStack->position;
}

View File

@ -0,0 +1,35 @@
#pragma once
#include "CBattleStackAnimation.h"
#include "../CAnimation.h"
#include "../../lib/SHexField.h"
class CBattleInterface;
class CStack;
/*
* CAttackAnimation.h, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
/// This class is responsible for managing the battle attack animation
class CAttackAnimation : public CBattleStackAnimation
{
protected:
SHexField dest; //attacked hex
bool shooting;
CCreatureAnim::EAnimType group; //if shooting is true, print this animation group
const CStack *attackedStack;
const CStack *attackingStack;
int attackingStackPosBeforeReturn; //for stacks with return_after_strike feature
public:
void nextFrame();
bool checkInitialConditions();
CAttackAnimation(CBattleInterface *_owner, const CStack *attacker, SHexField _dest, const CStack *defender);
};

View File

@ -0,0 +1,49 @@
#include "StdInc.h"
#include "CBattleAnimation.h"
#include "CBattleInterface.h"
#include "../../lib/BattleState.h"
#include "CSpellEffectAnimation.h"
#include "CReverseAnimation.h"
void CBattleAnimation::endAnim()
{
for(std::list<std::pair<CBattleAnimation *, bool> >::iterator it = owner->pendingAnims.begin(); it != owner->pendingAnims.end(); ++it)
{
if(it->first == this)
{
it->first = NULL;
}
}
}
bool CBattleAnimation::isEarliest(bool perStackConcurrency)
{
int lowestMoveID = owner->animIDhelper + 5;
CBattleStackAnimation * thAnim = dynamic_cast<CBattleStackAnimation *>(this);
CSpellEffectAnimation * thSen = dynamic_cast<CSpellEffectAnimation *>(this);
for(std::list<std::pair<CBattleAnimation *, bool> >::iterator it = owner->pendingAnims.begin(); it != owner->pendingAnims.end(); ++it)
{
CBattleStackAnimation * stAnim = dynamic_cast<CBattleStackAnimation *>(it->first);
CSpellEffectAnimation * sen = dynamic_cast<CSpellEffectAnimation *>(it->first);
if(perStackConcurrency && stAnim && thAnim && stAnim->stack->ID != thAnim->stack->ID)
continue;
if(sen && thSen && sen != thSen && perStackConcurrency)
continue;
CReverseAnimation * revAnim = dynamic_cast<CReverseAnimation *>(stAnim);
if(revAnim && thAnim && stAnim && stAnim->stack->ID == thAnim->stack->ID && revAnim->priority)
return false;
if(it->first)
vstd::amin(lowestMoveID, it->first->ID);
}
return (ID == lowestMoveID) || (lowestMoveID == (owner->animIDhelper + 5));
}
CBattleAnimation::CBattleAnimation(CBattleInterface * _owner)
: owner(_owner), ID(_owner->animIDhelper++)
{}

View File

@ -0,0 +1,30 @@
#pragma once
class CBattleInterface;
/*
* CBattleAnimation.h, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
/// Base class of battle animations
class CBattleAnimation
{
protected:
CBattleInterface * owner;
public:
virtual bool init()=0; //to be called - if returned false, call again until returns true
virtual void nextFrame()=0; //call every new frame
virtual void endAnim(); //to be called mostly internally; in this class it removes animation from pendingAnims list
bool isEarliest(bool perStackConcurrency); //determines if this animation is earliest of all
ui32 ID; //unique identifier
CBattleAnimation(CBattleInterface * _owner);
};

View File

@ -0,0 +1,84 @@
#include "StdInc.h"
#include "CBattleConsole.h"
#include "../SDL_Extensions.h"
CBattleConsole::CBattleConsole() : lastShown(-1), alterTxt(""), whoSetAlter(0)
{
}
CBattleConsole::~CBattleConsole()
{
texts.clear();
}
void CBattleConsole::show(SDL_Surface * to)
{
if(ingcAlter.size())
{
CSDL_Ext::printAtMiddleWB(ingcAlter, pos.x + pos.w/2, pos.y + 11, FONT_SMALL, 80, zwykly, to);
}
else if(alterTxt.size())
{
CSDL_Ext::printAtMiddleWB(alterTxt, pos.x + pos.w/2, pos.y + 11, FONT_SMALL, 80, zwykly, to);
}
else if(texts.size())
{
if(texts.size()==1)
{
CSDL_Ext::printAtMiddleWB(texts[0], pos.x + pos.w/2, pos.y + 11, FONT_SMALL, 80, zwykly, to);
}
else
{
CSDL_Ext::printAtMiddleWB(texts[lastShown-1], pos.x + pos.w/2, pos.y + 11, FONT_SMALL, 80, zwykly, to);
CSDL_Ext::printAtMiddleWB(texts[lastShown], pos.x + pos.w/2, pos.y + 27, FONT_SMALL, 80, zwykly, to);
}
}
}
bool CBattleConsole::addText(const std::string & text)
{
if(text.size()>70)
return false; //text too long!
int firstInToken = 0;
for(size_t i = 0; i < text.size(); ++i) //tokenize
{
if(text[i] == 10)
{
texts.push_back( text.substr(firstInToken, i-firstInToken) );
firstInToken = i+1;
}
}
texts.push_back( text.substr(firstInToken, text.size()) );
lastShown = texts.size()-1;
return true;
}
void CBattleConsole::eraseText(ui32 pos)
{
if(pos < texts.size())
{
texts.erase(texts.begin() + pos);
if(lastShown == texts.size())
--lastShown;
}
}
void CBattleConsole::changeTextAt(const std::string & text, ui32 pos)
{
if(pos >= texts.size()) //no such pos
return;
texts[pos] = text;
}
void CBattleConsole::scrollUp(ui32 by)
{
if(lastShown > static_cast<int>(by))
lastShown -= by;
}
void CBattleConsole::scrollDown(ui32 by)
{
if(lastShown + by < texts.size())
lastShown += by;
}

View File

@ -0,0 +1,35 @@
#pragma once
#include "../GUIBase.h"
struct SDL_Surface;
/*
* CBattleConsole.h, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
/// Class which shows the console at the bottom of the battle screen and manages the text of the console
class CBattleConsole : public CIntObject
{
private:
std::vector< std::string > texts; //a place where texts are stored
int lastShown; //last shown line of text
public:
std::string alterTxt; //if it's not empty, this text is displayed
std::string ingcAlter; //alternative text set by in-game console - very important!
int whoSetAlter; //who set alter text; 0 - battle interface or none, 1 - button
CBattleConsole(); //c-tor
~CBattleConsole(); //d-tor
void show(SDL_Surface *to = 0);
bool addText(const std::string &text); //adds text at the last position; returns false if failed (e.g. text longer than 70 characters)
void eraseText(ui32 pos); //erases added text at position pos
void changeTextAt(const std::string &text, ui32 pos); //if we have more than pos texts, pos-th is changed to given one
void scrollUp(ui32 by = 1); //scrolls console up by 'by' positions
void scrollDown(ui32 by = 1); //scrolls console up by 'by' positions
};

View File

@ -0,0 +1,153 @@
#include "StdInc.h"
#include "CBattleHero.h"
#include "CBattleInterface.h"
#include "../CGameInfo.h"
#include "../CDefHandler.h"
#include "../CCursorHandler.h"
#include "../CPlayerInterface.h"
#include "../../CCallback.h"
#include "../SDL_Extensions.h"
#include "../CSpellWindow.h"
#include "../Graphics.h"
#include "../CConfigHandler.h"
void CBattleHero::show(SDL_Surface *to)
{
//animation of flag
if(flip)
{
SDL_Rect temp_rect = genRect(
flag->ourImages[flagAnim].bitmap->h,
flag->ourImages[flagAnim].bitmap->w,
pos.x + 61,
pos.y + 39);
CSDL_Ext::blit8bppAlphaTo24bpp(
flag->ourImages[flagAnim].bitmap,
NULL,
screen,
&temp_rect);
}
else
{
SDL_Rect temp_rect = genRect(
flag->ourImages[flagAnim].bitmap->h,
flag->ourImages[flagAnim].bitmap->w,
pos.x + 72,
pos.y + 39);
CSDL_Ext::blit8bppAlphaTo24bpp(
flag->ourImages[flagAnim].bitmap,
NULL,
screen,
&temp_rect);
}
++flagAnimCount;
if(flagAnimCount%4==0)
{
++flagAnim;
flagAnim %= flag->ourImages.size();
}
//animation of hero
int tick=-1;
for(size_t i = 0; i < dh->ourImages.size(); ++i)
{
if(dh->ourImages[i].groupNumber==phase)
++tick;
if(tick==image)
{
SDL_Rect posb = pos;
CSDL_Ext::blit8bppAlphaTo24bpp(dh->ourImages[i].bitmap, NULL, to, &posb);
if(phase != 4 || nextPhase != -1 || image < 4)
{
if(flagAnimCount%2==0)
{
++image;
}
if(dh->ourImages[(i+1)%dh->ourImages.size()].groupNumber!=phase) //back to appropriate frame
{
image = 0;
}
}
if(phase == 4 && nextPhase != -1 && image == 7)
{
phase = nextPhase;
nextPhase = -1;
image = 0;
}
break;
}
}
}
void CBattleHero::activate()
{
activateLClick();
}
void CBattleHero::deactivate()
{
deactivateLClick();
}
void CBattleHero::setPhase(int newPhase)
{
if(phase != 4)
{
phase = newPhase;
image = 0;
}
else
{
nextPhase = newPhase;
}
}
void CBattleHero::clickLeft(tribool down, bool previousState)
{
if(myOwner->spellDestSelectMode) //we are casting a spell
return;
if(!down && myHero != NULL && myOwner->myTurn && myOwner->curInt->cb->battleCanCastSpell()) //check conditions
{
for(int it=0; it<GameConstants::BFIELD_SIZE; ++it) //do nothing when any hex is hovered - hero's animation overlaps battlefield
{
if(myOwner->bfield[it].hovered && myOwner->bfield[it].strictHovered)
return;
}
CCS->curh->changeGraphic(0,0);
CSpellWindow * spellWindow = new CSpellWindow(genRect(595, 620, (conf.cc.resx - 620)/2, (conf.cc.resy - 595)/2), myHero, myOwner->curInt);
GH.pushInt(spellWindow);
}
}
CBattleHero::CBattleHero(const std::string & defName, int phaseG, int imageG, bool flipG, ui8 player, const CGHeroInstance * hero, const CBattleInterface * owner): flip(flipG), myHero(hero), myOwner(owner), phase(phaseG), nextPhase(-1), image(imageG), flagAnim(0), flagAnimCount(0)
{
dh = CDefHandler::giveDef( defName );
for(size_t i = 0; i < dh->ourImages.size(); ++i) //transforming images
{
if(flip)
{
SDL_Surface * hlp = CSDL_Ext::rotate01(dh->ourImages[i].bitmap);
SDL_FreeSurface(dh->ourImages[i].bitmap);
dh->ourImages[i].bitmap = hlp;
}
CSDL_Ext::alphaTransform(dh->ourImages[i].bitmap);
}
if(flip)
flag = CDefHandler::giveDef("CMFLAGR.DEF");
else
flag = CDefHandler::giveDef("CMFLAGL.DEF");
//coloring flag and adding transparency
for(size_t i = 0; i < flag->ourImages.size(); ++i)
{
CSDL_Ext::alphaTransform(flag->ourImages[i].bitmap);
graphics->blueToPlayersAdv(flag->ourImages[i].bitmap, player);
}
}
CBattleHero::~CBattleHero()
{
delete dh;
delete flag;
}

View File

@ -0,0 +1,39 @@
#pragma once
#include "../GUIBase.h"
class CBattleInterface;
class CDefHandler;
class CGHeroInstance;
struct SDL_Surface;
/*
* CBattleHero.h, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
/// Hero battle animation
class CBattleHero : public CIntObject
{
public:
bool flip; //false if it's attacking hero, true otherwise
CDefHandler *dh, *flag; //animation and flag
const CGHeroInstance *myHero; //this animation's hero instance
const CBattleInterface *myOwner; //battle interface to which this animation is assigned
int phase; //stage of animation
int nextPhase; //stage of animation to be set after current phase is fully displayed
int image; //frame of animation
ui8 flagAnim, flagAnimCount; //for flag animation
void show(SDL_Surface *to); //prints next frame of animation to to
void activate();
void deactivate();
void setPhase(int newPhase); //sets phase of hero animation
void clickLeft(tribool down, bool previousState); //call-in
CBattleHero(const std::string &defName, int phaseG, int imageG, bool filpG, ui8 player, const CGHeroInstance *hero, const CBattleInterface *owner); //c-tor
~CBattleHero(); //d-tor
};

View File

@ -0,0 +1,256 @@
#pragma once
#include "../GUIBase.h"
#include "../../lib/CCreatureSet.h"
#include "../../lib/ConstTransitivePtr.h" //may be reundant
#include "../CAnimation.h"
#include "SStackAttackedInfo.h"
#include "CHexFieldControl.h"
#include "CShootingAnimation.h"
#include "../../lib/SHexField.h"
#include "../../lib/GameConstants.h"
/*
* CBattleInterface.h, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
class CLabel;
class CCreatureSet;
class CGHeroInstance;
class CDefHandler;
class CStack;
class CCallback;
class AdventureMapButton;
class CHighlightableButton;
class CHighlightableButtonsGroup;
struct BattleResult;
struct BattleSpellCast;
struct CObstacleInstance;
template <typename T> struct CondSh;
struct SetStackEffect;;
struct BattleAction;
class CGTownInstance;
struct CatapultAttack;
class CBattleInterface;
struct SCatapultSProjectileInfo;
struct BattleTriggerEffect;
class CBattleAnimation;
class CBattleHero;
class CBattleConsole;
class CBattleResultWindow;
class CStackQueue;
/// Class which manages the locked hex fields that are blocked e.g. by obstacles
class CBattleObstacle
{
std::vector<int> lockedHexes;
};
/// Struct for battle effect animation e.g. morale, prayer, armageddon, bless,...
struct SBattleEffect
{
int x, y; //position on the screen
int frame, maxFrame;
CDefHandler * anim; //animation to display
int effectID; //uniqueID equal ot ID of appropriate CSpellEffectAnim
};
/// Small struct which is needed for drawing the parabolic trajectory of the catapult cannon
struct SCatapultSProjectileInfo
{
const double facA, facB, facC;
const int fromX, toX;
SCatapultSProjectileInfo() : facA(0), facB(0), facC(0), fromX(0), toX(0) { };
SCatapultSProjectileInfo(double factorA, double factorB, double factorC, int fromXX, int toXX) : facA(factorA), facB(factorB), facC(factorC),
fromX(fromXX), toX(toXX) { };
double calculateY(double x);
};
/// Big class which handles the overall battle interface actions and it is also responsible for
/// drawing everything correctly.
class CBattleInterface : public CIntObject
{
enum SpellSelectionType
{
ANY_LOCATION = 0, FRIENDLY_CREATURE, HOSTILE_CREATURE, ANY_CREATURE, OBSTACLE, TELEPORT, NO_LOCATION = -1, STACK_SPELL_CANCELLED = -2
};
private:
SDL_Surface * background, * menu, * amountNormal, * amountNegative, * amountPositive, * amountEffNeutral, * cellBorders, * backgroundWithHexes;
AdventureMapButton * bOptions, * bSurrender, * bFlee, * bAutofight, * bSpell,
* bWait, * bDefence, * bConsoleUp, * bConsoleDown, *btactNext, *btactEnd;
CBattleConsole * console;
CBattleHero * attackingHero, * defendingHero; //fighting heroes
CStackQueue *queue;
const CCreatureSet *army1, *army2; //copy of initial armies (for result window)
const CGHeroInstance * attackingHeroInstance, * defendingHeroInstance;
std::map< int, CCreatureAnimation * > creAnims; //animations of creatures from fighting armies (order by BattleInfo's stacks' ID)
std::map< int, CDefHandler * > idToProjectile; //projectiles of creatures (creatureID, defhandler)
std::map< int, CDefHandler * > idToObstacle; //obstacles located on the battlefield
std::map< int, bool > creDir; // <creatureID, if false reverse creature's animation>
ui8 animCount;
const CStack * activeStack; //number of active stack; NULL - no one
const CStack * stackToActivate; //when animation is playing, we should wait till the end to make the next stack active; NULL of none
void activateStack(); //sets activeStack to stackToActivate etc.
int mouseHoveredStack; //stack hovered by mouse; if -1 -> none
time_t lastMouseHoveredStackAnimationTime; // time when last mouse hovered animation occurred
static const time_t HOVER_ANIM_DELTA;
std::vector<SHexField> occupyableHexes, //hexes available for active stack
attackableHexes; //hexes attackable by active stack
bool stackCountOutsideHexes[GameConstants::BFIELD_SIZE]; // hexes that when in front of a unit cause it's amount box to move back
int previouslyHoveredHex; //number of hex that was hovered by the cursor a while ago
int currentlyHoveredHex; //number of hex that is supposed to be hovered (for a while it may be inappropriately set, but will be renewed soon)
int attackingHex; //hex from which the stack would perform attack with current cursor
double getAnimSpeedMultiplier() const; //returns multiplier for number of frames in a group
std::map<int, int> standingFrame; //number of frame in standing animation by stack ID, helps in showing 'random moves'
CPlayerInterface *tacticianInterface; //used during tactics mode, points to the interface of player with higher tactics (can be either attacker or defender in hot-seat), valid onloy for human players
bool tacticsMode;
bool stackCanCastSpell; //if true, active stack could possibly cats some target spell
bool spellDestSelectMode; //if true, player is choosing destination for his spell
SpellSelectionType spellSelMode;
BattleAction * spellToCast; //spell for which player is choosing destination
ui32 creatureSpellToCast;
void endCastingSpell(); //ends casting spell (eg. when spell has been cast or canceled)
void showAliveStack(const CStack *stack, SDL_Surface * to); //helper function for function show
void showAliveStacks(std::vector<const CStack *> *aliveStacks, int hex, std::vector<const CStack *> *flyingStacks, SDL_Surface *to); // loops through all stacks at a given hex position
void showPieceOfWall(SDL_Surface * to, int hex, const std::vector<const CStack*> & stacks); //helper function for show
void showObstacles(std::multimap<SHexField, int> *hexToObstacle, std::vector<CObstacleInstance> &obstacles, int hex, SDL_Surface *to); // show all obstacles at a given hex position
void redrawBackgroundWithHexes(const CStack * activeStack);
void printConsoleAttacked(const CStack * defender, int dmg, int killed, const CStack * attacker, bool Multiple);
std::list<SProjectileInfo> projectiles; //projectiles flying on battlefield
void projectileShowHelper(SDL_Surface * to); //prints projectiles present on the battlefield
void giveCommand(ui8 action, SHexField tile, ui32 stack, si32 additional=-1);
bool isTileAttackable(const SHexField & number) const; //returns true if tile 'number' is neighboring any tile from active stack's range or is one of these tiles
bool blockedByObstacle(SHexField hex) const;
bool isCatapultAttackable(SHexField hex) const; //returns true if given tile can be attacked by catapult
std::list<SBattleEffect> battleEffects; //different animations to display on the screen like spell effects
/// Class which is responsible for drawing the wall of a siege during battle
class SiegeHelper
{
private:
static std::string townTypeInfixes[GameConstants::F_NUMBER]; //for internal use only - to build filenames
SDL_Surface* walls[18];
const CBattleInterface * owner;
public:
const CGTownInstance * town; //besieged town
SiegeHelper(const CGTownInstance * siegeTown, const CBattleInterface * _owner); //c-tor
~SiegeHelper(); //d-tor
//filename getters
std::string getSiegeName(ui16 what, ui16 additInfo = 1) const; //what: 0 - background, 1 - background wall, 2 - keep, 3 - bottom tower, 4 - bottom wall, 5 - below gate, 6 - over gate, 7 - upper wall, 8 - uppert tower, 9 - gate, 10 - gate arch, 11 - bottom static wall, 12 - upper static wall, 13 - moat, 14 - mlip, 15 - keep creature cover, 16 - bottom turret creature cover, 17 - upper turret creature cover; additInfo: 1 - intact, 2 - damaged, 3 - destroyed
void printPartOfWall(SDL_Surface * to, int what);//what: 1 - background wall, 2 - keep, 3 - bottom tower, 4 - bottom wall, 5 - below gate, 6 - over gate, 7 - upper wall, 8 - uppert tower, 9 - gate, 10 - gate arch, 11 - bottom static wall, 12 - upper static wall, 15 - keep creature cover, 16 - bottom turret creature cover, 17 - upper turret creature cover
friend class CBattleInterface;
} * siegeH;
CPlayerInterface * attackerInt, * defenderInt; //because LOCPLINT is not enough in hotSeat
const CGHeroInstance * getActiveHero(); //returns hero that can currently cast a spell
public:
CPlayerInterface * curInt; //current player interface
std::list<std::pair<CBattleAnimation *, bool> > pendingAnims; //currently displayed animations <anim, initialized>
void addNewAnim(CBattleAnimation * anim); //adds new anim to pendingAnims
ui32 animIDhelper; //for giving IDs for animations
static CondSh<bool> animsAreDisplayed; //for waiting with the end of battle for end of anims
CBattleInterface(const CCreatureSet * army1, const CCreatureSet * army2, CGHeroInstance *hero1, CGHeroInstance *hero2, const SDL_Rect & myRect, CPlayerInterface * att, CPlayerInterface * defen); //c-tor
~CBattleInterface(); //d-tor
//std::vector<TimeInterested*> timeinterested; //animation handling
void setPrintCellBorders(bool set); //if true, cell borders will be printed
void setPrintStackRange(bool set); //if true,range of active stack will be printed
void setPrintMouseShadow(bool set); //if true, hex under mouse will be shaded
void setAnimSpeed(int set); //speed of animation; 1 - slowest, 2 - medium, 4 - fastest
int getAnimSpeed() const; //speed of animation; 1 - slowest, 2 - medium, 4 - fastest
CHexFieldControl bfield[GameConstants::BFIELD_SIZE]; //11 lines, 17 hexes on each
//std::vector< CBattleObstacle * > obstacles; //vector of obstacles on the battlefield
SDL_Surface * cellBorder, * cellShade;
CondSh<BattleAction *> *givenCommand; //data != NULL if we have i.e. moved current unit
bool myTurn; //if true, interface is active (commands can be ordered)
CBattleResultWindow * resWindow; //window of end of battle
bool moveStarted; //if true, the creature that is already moving is going to make its first step
int moveSh; // sound handler used when moving a unit
//button handle funcs:
void bOptionsf();
void bSurrenderf();
void bFleef();
void reallyFlee(); //performs fleeing without asking player
void reallySurrender(); //performs surrendering without asking player
void bAutofightf();
void bSpellf();
void bWaitf();
void bDefencef();
void bConsoleUpf();
void bConsoleDownf();
void bTacticNextStack();
void bEndTacticPhase();
//end of button handle funcs
//napisz tu klase odpowiadajaca za wyswietlanie bitwy i obsluge uzytkownika, polecenia ma przekazywac callbackiem
void activate();
void deactivate();
void show(SDL_Surface * to);
void keyPressed(const SDL_KeyboardEvent & key);
void mouseMoved(const SDL_MouseMotionEvent &sEvent);
void clickRight(tribool down, bool previousState);
//call-ins
void startAction(const BattleAction* action);
void newStack(const CStack * stack); //new stack appeared on battlefield
void stackRemoved(int stackID); //stack disappeared from batlefiled
void stackActivated(const CStack * stack); //active stack has been changed
void stackMoved(const CStack * stack, std::vector<SHexField> destHex, int distance); //stack with id number moved to destHex
void waitForAnims();
void stacksAreAttacked(std::vector<SStackAttackedInfo> attackedInfos); //called when a certain amount of stacks has been attacked
void stackAttacking(const CStack * attacker, SHexField dest, const CStack * attacked, bool shooting); //called when stack with id ID is attacking something on hex dest
void newRoundFirst( int round );
void newRound(int number); //caled when round is ended; number is the number of round
void hexLclicked(int whichOne); //hex only call-in
void stackIsCatapulting(const CatapultAttack & ca); //called when a stack is attacking walls
void battleFinished(const BattleResult& br); //called when battle is finished - battleresult window should be printed
const BattleResult * bresult; //result of a battle; if non-zero then display when all animations end
void displayBattleFinished(); //displays battle result
void spellCast(const BattleSpellCast * sc); //called when a hero casts a spell
void battleStacksEffectsSet(const SetStackEffect & sse); //called when a specific effect is set to stacks
void castThisSpell(int spellID); //called when player has chosen a spell from spellbook
void displayEffect(ui32 effect, int destTile); //displays effect of a spell on the battlefield; affected: true - attacker. false - defender
void battleTriggerEffect(const BattleTriggerEffect & bte);
void setBattleCursor(const int myNumber); //really complex and messy
void endAction(const BattleAction* action);
void hideQueue();
void showQueue();
friend class CPlayerInterface;
friend class AdventureMapButton;
friend class CInGameConsole;
friend class CBattleResultWindow;
friend class CBattleHero;
friend class CSpellEffectAnimation;
friend class CBattleStackAnimation;
friend class CReverseAnimation;
friend class CDefenceAnimation;
friend class CMovementAnimation;
friend class CMovementStartAnimation;
friend class CAttackAnimation;
friend class CMeleeAttackAnimation;
friend class CShootingAnimation;
friend class CHexFieldControl;
};

View File

@ -0,0 +1,73 @@
#include "StdInc.h"
#include "CBattleOptionsWindow.h"
#include "CBattleInterface.h"
#include "../GUIBase.h"
#include "../GUIClasses.h"
#include "../AdventureMapButton.h"
#include "../CGameInfo.h"
#include "../CPlayerInterface.h"
#include "../../lib/CGeneralTextHandler.h"
CBattleOptionsWindow::CBattleOptionsWindow(const SDL_Rect & position, CBattleInterface *owner): myInt(owner)
{
OBJ_CONSTRUCTION_CAPTURING_ALL;
pos = position;
background = new CPicture("comopbck.bmp");
background->colorize(owner->curInt->playerID);
viewGrid = new CHighlightableButton(boost::bind(&CBattleInterface::setPrintCellBorders, owner, true), boost::bind(&CBattleInterface::setPrintCellBorders, owner, false), boost::assign::map_list_of(0,CGI->generaltexth->zelp[427].first)(3,CGI->generaltexth->zelp[427].first), CGI->generaltexth->zelp[427].second, false, "sysopchk.def", NULL, 25, 56, false);
viewGrid->select(owner->curInt->sysOpts.printCellBorders);
movementShadow = new CHighlightableButton(boost::bind(&CBattleInterface::setPrintStackRange, owner, true), boost::bind(&CBattleInterface::setPrintStackRange, owner, false), boost::assign::map_list_of(0,CGI->generaltexth->zelp[428].first)(3,CGI->generaltexth->zelp[428].first), CGI->generaltexth->zelp[428].second, false, "sysopchk.def", NULL, 25, 89, false);
movementShadow->select(owner->curInt->sysOpts.printStackRange);
mouseShadow = new CHighlightableButton(boost::bind(&CBattleInterface::setPrintMouseShadow, owner, true), boost::bind(&CBattleInterface::setPrintMouseShadow, owner, false), boost::assign::map_list_of(0,CGI->generaltexth->zelp[429].first)(3,CGI->generaltexth->zelp[429].first), CGI->generaltexth->zelp[429].second, false, "sysopchk.def", NULL, 25, 122, false);
mouseShadow->select(owner->curInt->sysOpts.printMouseShadow);
animSpeeds = new CHighlightableButtonsGroup(0);
animSpeeds->addButton(boost::assign::map_list_of(0,CGI->generaltexth->zelp[422].first),CGI->generaltexth->zelp[422].second, "sysopb9.def", 28, 225, 1);
animSpeeds->addButton(boost::assign::map_list_of(0,CGI->generaltexth->zelp[423].first),CGI->generaltexth->zelp[423].second, "sysob10.def", 92, 225, 2);
animSpeeds->addButton(boost::assign::map_list_of(0,CGI->generaltexth->zelp[424].first),CGI->generaltexth->zelp[424].second, "sysob11.def",156, 225, 4);
animSpeeds->select(owner->getAnimSpeed(), 1);
animSpeeds->onChange = boost::bind(&CBattleInterface::setAnimSpeed, owner, _1);
setToDefault = new AdventureMapButton (CGI->generaltexth->zelp[393], boost::bind(&CBattleOptionsWindow::bDefaultf,this), 246, 359, "codefaul.def");
setToDefault->swappedImages = true;
setToDefault->update();
exit = new AdventureMapButton (CGI->generaltexth->zelp[392], boost::bind(&CBattleOptionsWindow::bExitf,this), 357, 359, "soretrn.def",SDLK_RETURN);
exit->swappedImages = true;
exit->update();
//creating labels
labels.push_back(new CLabel(242, 32, FONT_BIG, CENTER, tytulowy, CGI->generaltexth->allTexts[392]));//window title
labels.push_back(new CLabel(122, 214, FONT_MEDIUM, CENTER, tytulowy, CGI->generaltexth->allTexts[393]));//animation speed
labels.push_back(new CLabel(122, 293, FONT_MEDIUM, CENTER, tytulowy, CGI->generaltexth->allTexts[394]));//music volume
labels.push_back(new CLabel(122, 359, FONT_MEDIUM, CENTER, tytulowy, CGI->generaltexth->allTexts[395]));//effects' volume
labels.push_back(new CLabel(353, 66, FONT_MEDIUM, CENTER, tytulowy, CGI->generaltexth->allTexts[396]));//auto - combat options
labels.push_back(new CLabel(353, 265, FONT_MEDIUM, CENTER, tytulowy, CGI->generaltexth->allTexts[397]));//creature info
//auto - combat options
labels.push_back(new CLabel(283, 86, FONT_MEDIUM, TOPLEFT, zwykly, CGI->generaltexth->allTexts[398]));//creatures
labels.push_back(new CLabel(283, 116, FONT_MEDIUM, TOPLEFT, zwykly, CGI->generaltexth->allTexts[399]));//spells
labels.push_back(new CLabel(283, 146, FONT_MEDIUM, TOPLEFT, zwykly, CGI->generaltexth->allTexts[400]));//catapult
labels.push_back(new CLabel(283, 176, FONT_MEDIUM, TOPLEFT, zwykly, CGI->generaltexth->allTexts[151]));//ballista
labels.push_back(new CLabel(283, 206, FONT_MEDIUM, TOPLEFT, zwykly, CGI->generaltexth->allTexts[401]));//first aid tent
//creature info
labels.push_back(new CLabel(283, 285, FONT_MEDIUM, TOPLEFT, zwykly, CGI->generaltexth->allTexts[402]));//all stats
labels.push_back(new CLabel(283, 315, FONT_MEDIUM, TOPLEFT, zwykly, CGI->generaltexth->allTexts[403]));//spells only
//general options
labels.push_back(new CLabel(61, 57, FONT_MEDIUM, TOPLEFT, zwykly, CGI->generaltexth->allTexts[404]));
labels.push_back(new CLabel(61, 90, FONT_MEDIUM, TOPLEFT, zwykly, CGI->generaltexth->allTexts[405]));
labels.push_back(new CLabel(61, 123, FONT_MEDIUM, TOPLEFT, zwykly, CGI->generaltexth->allTexts[406]));
labels.push_back(new CLabel(61, 156, FONT_MEDIUM, TOPLEFT, zwykly, CGI->generaltexth->allTexts[407]));
}
void CBattleOptionsWindow::bDefaultf()
{
}
void CBattleOptionsWindow::bExitf()
{
GH.popIntTotally(this);
}

View File

@ -0,0 +1,39 @@
#pragma once
#include "../GUIBase.h"
class CBattleInterface;
class CPicture;
class AdventureMapButton;
class CHighlightableButton;
class CHighlightableButtonsGroup;
class CLabel;
struct SDL_Rect;
/*
* CBattleOptionsWindow.h, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
/// Class which manages the battle options window
class CBattleOptionsWindow : public CIntObject
{
private:
CBattleInterface *myInt;
CPicture *background;
AdventureMapButton *setToDefault, *exit;
CHighlightableButton *viewGrid, *movementShadow, *mouseShadow;
CHighlightableButtonsGroup *animSpeeds;
std::vector<CLabel*> labels;
public:
CBattleOptionsWindow(const SDL_Rect &position, CBattleInterface *owner); //c-tor
void bDefaultf(); //default button callback
void bExitf(); //exit button callback
};

View File

@ -0,0 +1,216 @@
#include "StdInc.h"
#include "CBattleResultWindow.h"
#include "CBattleInterface.h"
#include "../AdventureMapButton.h"
#include "../CGameInfo.h"
#include "../../lib/CObjectHandler.h"
#include "../../lib/NetPacks.h"
#include "../../lib/CCreatureHandler.h"
#include "../../lib/CGeneralTextHandler.h"
#include "../CMusicHandler.h"
#include "../CPlayerInterface.h"
#include "../Graphics.h"
#include "../../CCallback.h"
#include "../CVideoHandler.h"
#include "../SDL_Extensions.h"
#include "../CBitmapHandler.h"
CBattleResultWindow::CBattleResultWindow(const BattleResult &br, const SDL_Rect & pos, CBattleInterface * _owner)
: owner(_owner)
{
this->pos = pos;
background = BitmapHandler::loadBitmap("CPRESULT.BMP", true);
graphics->blueToPlayersAdv(background, owner->curInt->playerID);
SDL_Surface * pom = SDL_ConvertSurface(background, screen->format, screen->flags);
SDL_FreeSurface(background);
background = pom;
exit = new AdventureMapButton (std::string(), std::string(), boost::bind(&CBattleResultWindow::bExitf,this), 384 + pos.x, 505 + pos.y, "iok6432.def", SDLK_RETURN);
exit->borderColor = Colors::MetallicGold;
exit->borderEnabled = true;
if(br.winner==0) //attacker won
{
CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[410], 59, 124, FONT_SMALL, zwykly, background);
CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[411], 408, 124, FONT_SMALL, zwykly, background);
}
else //if(br.winner==1)
{
CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[411], 59, 124, FONT_SMALL, zwykly, background);
CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[410], 412, 124, FONT_SMALL, zwykly, background);
}
CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[407], 232, 302, FONT_BIG, tytulowy, background);
CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[408], 232, 332, FONT_BIG, zwykly, background);
CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[409], 237, 428, FONT_BIG, zwykly, background);
std::string attackerName, defenderName;
if(owner->attackingHeroInstance) //a hero attacked
{
SDL_Rect temp_rect = genRect(64, 58, 21, 38);
SDL_BlitSurface(graphics->portraitLarge[owner->attackingHeroInstance->portrait], NULL, background, &temp_rect);
//setting attackerName
attackerName = owner->attackingHeroInstance->name;
}
else //a monster attacked
{
int bestMonsterID = -1;
ui32 bestPower = 0;
for(TSlots::const_iterator it = owner->army1->Slots().begin(); it!=owner->army1->Slots().end(); ++it)
{
if(it->second->type->AIValue > bestPower)
{
bestPower = it->second->type->AIValue;
bestMonsterID = it->second->type->idNumber;
}
}
SDL_Rect temp_rect = genRect(64, 58, 21, 38);
SDL_BlitSurface(graphics->bigImgs[bestMonsterID], NULL, background, &temp_rect);
//setting attackerName
attackerName = CGI->creh->creatures[bestMonsterID]->namePl;
}
if(owner->defendingHeroInstance) //a hero defended
{
SDL_Rect temp_rect = genRect(64, 58, 392, 38);
SDL_BlitSurface(graphics->portraitLarge[owner->defendingHeroInstance->portrait], NULL, background, &temp_rect);
//setting defenderName
defenderName = owner->defendingHeroInstance->name;
}
else //a monster defended
{
int bestMonsterID = -1;
ui32 bestPower = 0;
for(TSlots::const_iterator it = owner->army2->Slots().begin(); it!=owner->army2->Slots().end(); ++it)
{
if( it->second->type->AIValue > bestPower)
{
bestPower = it->second->type->AIValue;
bestMonsterID = it->second->type->idNumber;
}
}
SDL_Rect temp_rect = genRect(64, 58, 392, 38);
SDL_BlitSurface(graphics->bigImgs[bestMonsterID], NULL, background, &temp_rect);
//setting defenderName
defenderName = CGI->creh->creatures[bestMonsterID]->namePl;
}
//printing attacker and defender's names
CSDL_Ext::printAt(attackerName, 89, 37, FONT_SMALL, zwykly, background);
CSDL_Ext::printTo(defenderName, 381, 53, FONT_SMALL, zwykly, background);
//printing casualities
for(int step = 0; step < 2; ++step)
{
if(br.casualties[step].size()==0)
{
CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[523], 235, 360 + 97*step, FONT_SMALL, zwykly, background);
}
else
{
int xPos = 235 - (br.casualties[step].size()*32 + (br.casualties[step].size() - 1)*10)/2; //increment by 42 with each picture
int yPos = 344 + step*97;
for(std::map<ui32,si32>::const_iterator it=br.casualties[step].begin(); it!=br.casualties[step].end(); ++it)
{
blitAt(graphics->smallImgs[it->first], xPos, yPos, background);
std::ostringstream amount;
amount<<it->second;
CSDL_Ext::printAtMiddle(amount.str(), xPos+16, yPos + 42, FONT_SMALL, zwykly, background);
xPos += 42;
}
}
}
//printing result description
bool weAreAttacker = (owner->curInt->playerID == owner->attackingHeroInstance->tempOwner);
if((br.winner == 0 && weAreAttacker) || (br.winner == 1 && !weAreAttacker)) //we've won
{
int text=-1;
switch(br.result)
{
case 0: text = 304; break;
case 1: text = 303; break;
case 2: text = 302; break;
}
CCS->musich->playMusic(musicBase::winBattle);
CCS->videoh->open(VIDEO_WIN);
std::string str = CGI->generaltexth->allTexts[text];
const CGHeroInstance * ourHero = weAreAttacker? owner->attackingHeroInstance : owner->defendingHeroInstance;
if (ourHero)
{
str += CGI->generaltexth->allTexts[305];
boost::algorithm::replace_first(str,"%s",ourHero->name);
boost::algorithm::replace_first(str,"%d",boost::lexical_cast<std::string>(br.exp[weAreAttacker?0:1]));
}
CSDL_Ext::printAtMiddleWB(str, 235, 235, FONT_SMALL, 55, zwykly, background);
}
else // we lose
{
switch(br.result)
{
case 0: //normal victory
{
CCS->musich->playMusic(musicBase::loseCombat);
CCS->videoh->open(VIDEO_LOSE_BATTLE_START);
CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[311], 235, 235, FONT_SMALL, zwykly, background);
break;
}
case 1: //flee
{
CCS->musich->playMusic(musicBase::retreatBattle);
CCS->videoh->open(VIDEO_RETREAT_START);
CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[310], 235, 235, FONT_SMALL, zwykly, background);
break;
}
case 2: //surrender
{
CCS->musich->playMusic(musicBase::surrenderBattle);
CCS->videoh->open(VIDEO_SURRENDER);
CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[309], 235, 220, FONT_SMALL, zwykly, background);
break;
}
}
}
}
CBattleResultWindow::~CBattleResultWindow()
{
SDL_FreeSurface(background);
}
void CBattleResultWindow::activate()
{
owner->curInt->showingDialog->set(true);
exit->activate();
}
void CBattleResultWindow::deactivate()
{
exit->deactivate();
}
void CBattleResultWindow::show(SDL_Surface *to)
{
//evaluating to
if(!to)
to = screen;
CCS->videoh->update(107, 70, background, false, true);
SDL_BlitSurface(background, NULL, to, &pos);
exit->showAll(to);
}
void CBattleResultWindow::bExitf()
{
if(LOCPLINT->cb->getStartInfo()->mode == StartInfo::DUEL)
{
std::exit(0);
}
CPlayerInterface * intTmp = owner->curInt;
GH.popInts(2); //first - we; second - battle interface
intTmp->showingDialog->setn(false);
CCS->videoh->close();
}

View File

@ -0,0 +1,37 @@
#pragma once
#include "../GUIBase.h"
struct SDL_Surface;
class AdventureMapButton;
class CBattleInterface;
struct SDL_Rect;
struct BattleResult;
/*
* CBattleResultWindow.h, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
/// Class which is responsible for showing the battle result window
class CBattleResultWindow : public CIntObject
{
private:
SDL_Surface *background;
AdventureMapButton *exit;
CBattleInterface *owner;
public:
CBattleResultWindow(const BattleResult &br, const SDL_Rect &pos, CBattleInterface *_owner); //c-tor
~CBattleResultWindow(); //d-tor
void bExitf(); //exit button callback
void activate();
void deactivate();
void show(SDL_Surface * to = 0);
};

View File

@ -0,0 +1,57 @@
#include "StdInc.h"
#include "CBattleStackAnimation.h"
#include "CBattleInterface.h"
#include "../../lib/BattleState.h"
CBattleStackAnimation::CBattleStackAnimation(CBattleInterface * _owner, const CStack * _stack)
: CBattleAnimation(_owner), stack(_stack)
{
}
bool CBattleStackAnimation::isToReverseHlp(SHexField hexFrom, SHexField hexTo, bool curDir)
{
int fromMod = hexFrom % GameConstants::BFIELD_WIDTH;
int fromDiv = hexFrom / GameConstants::BFIELD_WIDTH;
int toMod = hexTo % GameConstants::BFIELD_WIDTH;
if(curDir && fromMod < toMod)
return false;
else if(curDir && fromMod > toMod)
return true;
else if(curDir && fromMod == toMod)
{
return fromDiv % 2 == 0;
}
else if(!curDir && fromMod < toMod)
return true;
else if(!curDir && fromMod > toMod)
return false;
else if(!curDir && fromMod == toMod)
{
return fromDiv % 2 == 1;
}
tlog1 << "Catastrope in CBattleStackAnimation::isToReverse!" << std::endl;
return false; //should never happen
}
bool CBattleStackAnimation::isToReverse(SHexField hexFrom, SHexField hexTo, bool curDir, bool toDoubleWide, bool toDir)
{
if(hexTo < 0) //turret
return false;
if(toDoubleWide)
{
return isToReverseHlp(hexFrom, hexTo, curDir) &&
(toDir ? isToReverseHlp(hexFrom, hexTo-1, curDir) : isToReverseHlp(hexFrom, hexTo+1, curDir) );
}
else
{
return isToReverseHlp(hexFrom, hexTo, curDir);
}
}
CCreatureAnimation* CBattleStackAnimation::myAnim()
{
return owner->creAnims[stack->ID];
}

View File

@ -0,0 +1,31 @@
#pragma once
#include "CBattleAnimation.h"
#include "../../lib/SHexField.h"
class CStack;
class CBattleInterface;
class CCreatureAnimation;
/*
* CBattleStackAnimation.h, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
/// Sub-class which is responsible for managing the battle stack animation.
class CBattleStackAnimation : public CBattleAnimation
{
public:
const CStack * stack; //id of stack whose animation it is
CBattleStackAnimation(CBattleInterface * _owner, const CStack * _stack);
static bool isToReverseHlp(SHexField hexFrom, SHexField hexTo, bool curDir); //helper for isToReverse
static bool isToReverse(SHexField hexFrom, SHexField hexTo, bool curDir /*if true, creature is in attacker's direction*/, bool toDoubleWide, bool toDir); //determines if creature should be reversed (it stands on hexFrom and should 'see' hexTo)
CCreatureAnimation *myAnim(); //animation for our stack
};

View File

@ -0,0 +1,139 @@
#include "StdInc.h"
#include "CDefenceAnimation.h"
#include "CBattleInterface.h"
#include "../CGameInfo.h"
#include "../CCreatureAnimation.h"
#include "../CPlayerInterface.h"
#include "../CMusicHandler.h"
#include "../../lib/BattleState.h"
#include "CReverseAnimation.h"
#include "CAttackAnimation.h"
#include "CShootingAnimation.h"
bool CDefenceAnimation::init()
{
//checking initial conditions
//if(owner->creAnims[stackID]->getType() != 2)
//{
// return false;
//}
if(attacker == NULL && owner->battleEffects.size() > 0)
return false;
ui32 lowestMoveID = owner->animIDhelper + 5;
for(std::list<std::pair<CBattleAnimation *, bool> >::iterator it = owner->pendingAnims.begin(); it != owner->pendingAnims.end(); ++it)
{
CDefenceAnimation * defAnim = dynamic_cast<CDefenceAnimation *>(it->first);
if(defAnim && defAnim->stack->ID != stack->ID)
continue;
CAttackAnimation * attAnim = dynamic_cast<CAttackAnimation *>(it->first);
if(attAnim && attAnim->stack->ID != stack->ID)
continue;
if(attacker != NULL)
{
int attackerAnimType = owner->creAnims[attacker->ID]->getType();
if( attackerAnimType == 11 && attackerAnimType == 12 && attackerAnimType == 13 && owner->creAnims[attacker->ID]->getFrame() < attacker->getCreature()->attackClimaxFrame )
return false;
}
CReverseAnimation * animAsRev = dynamic_cast<CReverseAnimation *>(it->first);
if(animAsRev && animAsRev->priority)
return false;
if(it->first)
vstd::amin(lowestMoveID, it->first->ID);
}
if(ID > lowestMoveID)
return false;
//reverse unit if necessary
if(attacker && isToReverse(stack->position, attacker->position, owner->creDir[stack->ID], attacker->doubleWide(), owner->creDir[attacker->ID]))
{
owner->addNewAnim(new CReverseAnimation(owner, stack, stack->position, true));
return false;
}
//unit reversed
if(byShooting) //delay hit animation
{
for(std::list<SProjectileInfo>::const_iterator it = owner->projectiles.begin(); it != owner->projectiles.end(); ++it)
{
if(it->creID == attacker->getCreature()->idNumber)
{
return false;
}
}
}
//initializing
if(killed)
{
CCS->soundh->playSound(battle_sound(stack->getCreature(), killed));
myAnim()->setType(CCreatureAnim::DEATH); //death
}
else
{
// TODO: this block doesn't seems correct if the unit is defending.
CCS->soundh->playSound(battle_sound(stack->getCreature(), wince));
myAnim()->setType(CCreatureAnim::HITTED); //getting hit
}
return true; //initialized successfuly
}
void CDefenceAnimation::nextFrame()
{
if(!killed && myAnim()->getType() != CCreatureAnim::HITTED)
{
myAnim()->setType(CCreatureAnim::HITTED);
}
if(!myAnim()->onLastFrameInGroup())
{
if( myAnim()->getType() == CCreatureAnim::DEATH && (owner->animCount+1)%(4/owner->curInt->sysOpts.animSpeed)==0
&& !myAnim()->onLastFrameInGroup() )
{
myAnim()->incrementFrame();
}
}
else
{
endAnim();
}
}
void CDefenceAnimation::endAnim()
{
//restoring animType
if(myAnim()->getType() == CCreatureAnim::HITTED)
myAnim()->setType(CCreatureAnim::HOLDING);
//printing info to console
//if(attacker!=NULL)
// owner->printConsoleAttacked(stack, dmg, amountKilled, attacker);
//const CStack * attacker = owner->curInt->cb->battleGetStackByID(IDby, false);
//const CStack * attacked = owner->curInt->cb->battleGetStackByID(stackID, false);
CBattleAnimation::endAnim();
delete this;
}
CDefenceAnimation::CDefenceAnimation(SStackAttackedInfo _attackedInfo, CBattleInterface * _owner)
: CBattleStackAnimation(_owner, _attackedInfo.defender), dmg(_attackedInfo.dmg),
amountKilled(_attackedInfo.amountKilled), attacker(_attackedInfo.attacker), byShooting(_attackedInfo.byShooting),
killed(_attackedInfo.killed)
{
}

View File

@ -0,0 +1,34 @@
#pragma once
#include "CBattleStackAnimation.h"
#include "SStackAttackedInfo.h"
class CStack;
/*
* CDefenceAnimation.h, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
/// Animation of a defending unit
class CDefenceAnimation : public CBattleStackAnimation
{
private:
//std::vector<SSStackAttackedInfo> attackedInfos;
int dmg; //damage dealt
int amountKilled; //how many creatures in stack has been killed
const CStack * attacker; //attacking stack
bool byShooting; //if true, stack has been attacked by shooting
bool killed; //if true, stack has been killed
public:
bool init();
void nextFrame();
void endAnim();
CDefenceAnimation(SStackAttackedInfo _attackedInfo, CBattleInterface * _owner);
};

View File

@ -0,0 +1,27 @@
#include "StdInc.h"
#include "CDummyAnimation.h"
#include "CBattleInterface.h"
bool CDummyAnimation::init()
{
return true;
}
void CDummyAnimation::nextFrame()
{
counter++;
if(counter > howMany)
endAnim();
}
void CDummyAnimation::endAnim()
{
CBattleAnimation::endAnim();
delete this;
}
CDummyAnimation::CDummyAnimation(CBattleInterface * _owner, int howManyFrames) : CBattleAnimation(_owner), counter(0), howMany(howManyFrames)
{
}

View File

@ -0,0 +1,28 @@
#pragma once
#include "CBattleAnimation.h"
class CBattleInterface;
/*
* CDummyAnimation.h, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
class CDummyAnimation : public CBattleAnimation
{
private:
int counter;
int howMany;
public:
bool init();
void nextFrame();
void endAnim();
CDummyAnimation(CBattleInterface *_owner, int howManyFrames);
};

View File

@ -0,0 +1,147 @@
#include "StdInc.h"
#include "CHexFieldControl.h"
#include "CBattleInterface.h"
#include "../../lib/BattleState.h"
#include "../CGameInfo.h"
#include "../CPlayerInterface.h"
#include "../../lib/CTownHandler.h"
#include "../Graphics.h"
#include "../../CCallback.h"
#include "../../lib/CGeneralTextHandler.h"
#include "../SDL_Extensions.h"
#include "../GUIClasses.h"
#include "CBattleConsole.h"
Point CHexFieldControl::getXYUnitAnim(const int & hexNum, const bool & attacker, const CStack * stack, const CBattleInterface * cbi)
{
Point ret(-500, -500); //returned value
if(stack && stack->position < 0) //creatures in turrets
{
switch(stack->position)
{
case -2: //keep
ret = graphics->wallPositions[cbi->siegeH->town->town->typeID][17];
break;
case -3: //lower turret
ret = graphics->wallPositions[cbi->siegeH->town->town->typeID][18];
break;
case -4: //upper turret
ret = graphics->wallPositions[cbi->siegeH->town->town->typeID][19];
break;
}
}
else
{
ret.y = -139 + 42 * (hexNum/GameConstants::BFIELD_WIDTH); //counting y
//counting x
if(attacker)
{
ret.x = -160 + 22 * ( ((hexNum/GameConstants::BFIELD_WIDTH) + 1)%2 ) + 44 * (hexNum % GameConstants::BFIELD_WIDTH);
}
else
{
ret.x = -219 + 22 * ( ((hexNum/GameConstants::BFIELD_WIDTH) + 1)%2 ) + 44 * (hexNum % GameConstants::BFIELD_WIDTH);
}
//shifting position for double - hex creatures
if(stack && stack->doubleWide())
{
if(attacker)
{
ret.x -= 44;
}
else
{
ret.x += 45;
}
}
}
//returning
return ret +CPlayerInterface::battleInt->pos;
}
void CHexFieldControl::activate()
{
activateHover();
activateMouseMove();
activateLClick();
activateRClick();
}
void CHexFieldControl::deactivate()
{
deactivateHover();
deactivateMouseMove();
deactivateLClick();
deactivateRClick();
}
void CHexFieldControl::hover(bool on)
{
hovered = on;
//Hoverable::hover(on);
if(!on && setAlterText)
{
myInterface->console->alterTxt = std::string();
setAlterText = false;
}
}
CHexFieldControl::CHexFieldControl() : setAlterText(false), myNumber(-1), accessible(true), hovered(false), strictHovered(false), myInterface(NULL)
{
}
void CHexFieldControl::mouseMoved(const SDL_MouseMotionEvent &sEvent)
{
if(myInterface->cellShade)
{
if(CSDL_Ext::SDL_GetPixel(myInterface->cellShade, sEvent.x-pos.x, sEvent.y-pos.y) == 0) //hovered pixel is outside hex
{
strictHovered = false;
}
else //hovered pixel is inside hex
{
strictHovered = true;
}
}
if(hovered && strictHovered) //print attacked creature to console
{
const CStack * attackedStack = myInterface->curInt->cb->battleGetStackByPos(myNumber);
if(myInterface->console->alterTxt.size() == 0 &&attackedStack != NULL &&
attackedStack->owner != myInterface->curInt->playerID &&
attackedStack->alive())
{
char tabh[160];
const std::string & attackedName = attackedStack->count == 1 ? attackedStack->getCreature()->nameSing : attackedStack->getCreature()->namePl;
sprintf(tabh, CGI->generaltexth->allTexts[220].c_str(), attackedName.c_str());
myInterface->console->alterTxt = std::string(tabh);
setAlterText = true;
}
}
else if(setAlterText)
{
myInterface->console->alterTxt = std::string();
setAlterText = false;
}
}
void CHexFieldControl::clickLeft(tribool down, bool previousState)
{
if(!down && hovered && strictHovered) //we've been really clicked!
{
myInterface->hexLclicked(myNumber);
}
}
void CHexFieldControl::clickRight(tribool down, bool previousState)
{
const CStack * myst = myInterface->curInt->cb->battleGetStackByPos(myNumber); //stack info
if(hovered && strictHovered && myst!=NULL)
{
if(!myst->alive()) return;
if(down)
{
GH.pushInt(createCreWindow(myst));
}
}
}

View File

@ -0,0 +1,40 @@
#pragma once
#include "../GUIBase.h"
class CBattleInterface;
class CStack;
struct SDL_MouseMotionEvent;
/*
* CHexFieldControl.h, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
/// Class which stands for a single hex field on a battlefield
class CHexFieldControl : public CIntObject
{
private:
bool setAlterText; //if true, this hex has set alternative text in console and will clean it
public:
ui32 myNumber; //number of hex in commonly used format
bool accessible; //if true, this hex is accessible for units
//CStack * ourStack;
bool hovered, strictHovered; //for determining if hex is hovered by mouse (this is different problem than hex's graphic hovering)
CBattleInterface * myInterface; //interface that owns me
static Point getXYUnitAnim(const int &hexNum, const bool &attacker, const CStack *creature, const CBattleInterface *cbi); //returns (x, y) of left top corner of animation
//for user interactions
void hover (bool on);
void activate();
void deactivate();
void mouseMoved (const SDL_MouseMotionEvent &sEvent);
void clickLeft(tribool down, bool previousState);
void clickRight(tribool down, bool previousState);
CHexFieldControl();
};

View File

@ -0,0 +1,95 @@
#include "StdInc.h"
#include "CMeleeAttackAnimation.h"
#include "CBattleInterface.h"
#include "../CCreatureAnimation.h"
#include "../../lib/BattleState.h"
#include "CReverseAnimation.h"
bool CMeleeAttackAnimation::init()
{
if( !CAttackAnimation::checkInitialConditions() )
return false;
//if(owner->creAnims[stackID]->getType()!=2)
//{
// return false;
//}
if(!attackingStack || myAnim()->getType() == 5)
{
endAnim();
return false;
}
bool toReverse = isToReverse(attackingStackPosBeforeReturn, dest, owner->creDir[stack->ID], attackedStack->doubleWide(), owner->creDir[attackedStack->ID]);
if(toReverse)
{
owner->addNewAnim(new CReverseAnimation(owner, stack, attackingStackPosBeforeReturn, true));
return false;
}
//reversed
shooting = false;
static const CCreatureAnim::EAnimType mutPosToGroup[] = {CCreatureAnim::ATTACK_UP, CCreatureAnim::ATTACK_UP,
CCreatureAnim::ATTACK_FRONT, CCreatureAnim::ATTACK_DOWN, CCreatureAnim::ATTACK_DOWN, CCreatureAnim::ATTACK_FRONT};
int revShiftattacker = (attackingStack->attackerOwned ? -1 : 1);
int mutPos = SHexField::mutualPosition(attackingStackPosBeforeReturn, dest);
if(mutPos == -1 && attackingStack->doubleWide())
{
mutPos = SHexField::mutualPosition(attackingStackPosBeforeReturn + revShiftattacker, attackedStack->position);
}
if (mutPos == -1 && attackedStack->doubleWide())
{
mutPos = SHexField::mutualPosition(attackingStackPosBeforeReturn, attackedStack->occupiedHex());
}
if (mutPos == -1 && attackedStack->doubleWide() && attackingStack->doubleWide())
{
mutPos = SHexField::mutualPosition(attackingStackPosBeforeReturn + revShiftattacker, attackedStack->occupiedHex());
}
switch(mutPos) //attack direction
{
case 0: case 1: case 2: case 3: case 4: case 5:
group = mutPosToGroup[mutPos];
break;
default:
tlog1<<"Critical Error! Wrong dest in stackAttacking! dest: "<<dest<<" attacking stack pos: "<<attackingStackPosBeforeReturn<<" mutual pos: "<<mutPos<<std::endl;
group = CCreatureAnim::ATTACK_FRONT;
break;
}
return true;
}
void CMeleeAttackAnimation::nextFrame()
{
/*for(std::list<std::pair<CBattleAnimation *, bool> >::const_iterator it = owner->pendingAnims.begin(); it != owner->pendingAnims.end(); ++it)
{
CBattleMoveStart * anim = dynamic_cast<CBattleMoveStart *>(it->first);
CReverseAnim * anim2 = dynamic_cast<CReverseAnim *>(it->first);
if( (anim && anim->stackID == stackID) || (anim2 && anim2->stackID == stackID ) )
return;
}*/
CAttackAnimation::nextFrame();
}
void CMeleeAttackAnimation::endAnim()
{
CBattleAnimation::endAnim();
delete this;
}
CMeleeAttackAnimation::CMeleeAttackAnimation(CBattleInterface * _owner, const CStack * attacker, SHexField _dest, const CStack * _attacked)
: CAttackAnimation(_owner, attacker, _dest, _attacked)
{
}

View File

@ -0,0 +1,28 @@
#pragma once
#include "CAttackAnimation.h"
class CBattleInterface;
class CStack;
/*
* CMeleeAttackAnimation.h, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
/// Hand-to-hand attack
class CMeleeAttackAnimation : public CAttackAnimation
{
public:
bool init();
void nextFrame();
void endAnim();
CMeleeAttackAnimation(CBattleInterface *_owner, const CStack *attacker, SHexField _dest, const CStack *_attacked);
};

View File

@ -0,0 +1,176 @@
#include "StdInc.h"
#include "CMovementAnimation.h"
#include "CBattleInterface.h"
#include "../CCreatureAnimation.h"
#include "../../lib/BattleState.h"
#include "../CGameInfo.h"
#include "../CMusicHandler.h"
#include "CReverseAnimation.h"
#include "CMovementEndAnimation.h"
#include "CHexFieldControl.h"
bool CMovementAnimation::init()
{
if( !isEarliest(false) )
return false;
//a few useful variables
steps = static_cast<int>(myAnim()->framesInGroup(CCreatureAnim::MOVING) * owner->getAnimSpeedMultiplier() - 1);
if(steps == 0) //this creature seems to have no move animation so we can end it immediately
{
endAnim();
return false;
}
whichStep = 0;
int hexWbase = 44, hexHbase = 42;
const CStack * movedStack = stack;
if(!movedStack || myAnim()->getType() == 5)
{
endAnim();
return false;
}
//bool twoTiles = movedStack->doubleWide();
Point begPosition = CHexFieldControl::getXYUnitAnim(curStackPos, movedStack->attackerOwned, movedStack, owner);
Point endPosition = CHexFieldControl::getXYUnitAnim(nextHex, movedStack->attackerOwned, movedStack, owner);
int mutPos = SHexField::mutualPosition(curStackPos, nextHex);
//reverse unit if necessary
if((begPosition.x > endPosition.x) && owner->creDir[stack->ID] == true)
{
owner->addNewAnim(new CReverseAnimation(owner, stack, curStackPos, true));
return false;
}
else if ((begPosition.x < endPosition.x) && owner->creDir[stack->ID] == false)
{
owner->addNewAnim(new CReverseAnimation(owner, stack, curStackPos, true));
return false;
}
if(myAnim()->getType() != CCreatureAnim::MOVING)
{
myAnim()->setType(CCreatureAnim::MOVING);
}
//unit reversed
// if(owner->moveSh <= 0)
// owner->moveSh = CCS->soundh->playSound(battle_sound(movedStack->getCreature(), move), -1);
//step shift calculation
posX = myAnim()->pos.x, posY = myAnim()->pos.y; // for precise calculations ;]
if(mutPos == -1 && movedStack->hasBonusOfType(Bonus::FLYING))
{
steps *= distance;
steps /= 2; //to make animation faster
stepX = (endPosition.x - begPosition.x) / static_cast<double>(steps);
stepY = (endPosition.y - begPosition.y) / static_cast<double>(steps);
}
else
{
switch(mutPos)
{
case 0:
stepX = -1.0 * (hexWbase / (2.0 * steps));
stepY = -1.0 * (hexHbase / (static_cast<double>(steps)));
break;
case 1:
stepX = hexWbase / (2.0 * steps);
stepY = -1.0 * hexHbase / (static_cast<double>(steps));
break;
case 2:
stepX = hexWbase / static_cast<double>(steps);
stepY = 0.0;
break;
case 3:
stepX = hexWbase / (2.0 * steps);
stepY = hexHbase / static_cast<double>(steps);
break;
case 4:
stepX = -1.0 * hexWbase / (2.0 * steps);
stepY = hexHbase / static_cast<double>(steps);
break;
case 5:
stepX = -1.0 * hexWbase / static_cast<double>(steps);
stepY = 0.0;
break;
}
}
//step shifts calculated
return true;
}
void CMovementAnimation::nextFrame()
{
//moving instructions
posX += stepX;
myAnim()->pos.x = static_cast<Sint16>(posX);
posY += stepY;
myAnim()->pos.y = static_cast<Sint16>(posY);
// Increments step count and check if we are finished with current animation
++whichStep;
if(whichStep == steps)
{
// Sets the position of the creature animation sprites
Point coords = CHexFieldControl::getXYUnitAnim(nextHex, owner->creDir[stack->ID], stack, owner);
myAnim()->pos = coords;
// true if creature haven't reached the final destination hex
if ((nextPos + 1) < destTiles.size())
{
// update the next hex field which has to be reached by the stack
nextPos++;
curStackPos = nextHex;
nextHex = destTiles[nextPos];
// update position of double wide creatures
bool twoTiles = stack->doubleWide();
if(twoTiles && bool(stack->attackerOwned) && (owner->creDir[stack->ID] != bool(stack->attackerOwned) )) //big attacker creature is reversed
myAnim()->pos.x -= 44;
else if(twoTiles && (! bool(stack->attackerOwned) ) && (owner->creDir[stack->ID] != bool(stack->attackerOwned) )) //big defender creature is reversed
myAnim()->pos.x += 44;
// re-init animation
for(std::list<std::pair<CBattleAnimation *, bool> >::iterator it = owner->pendingAnims.begin(); it != owner->pendingAnims.end(); ++it)
{
if (it->first == this)
{
it->second = false;
break;
}
}
}
else
endAnim();
}
}
void CMovementAnimation::endAnim()
{
const CStack * movedStack = stack;
CBattleAnimation::endAnim();
if(movedStack)
owner->addNewAnim(new CMovementEndAnimation(owner, stack, nextHex));
if(owner->moveSh >= 0)
{
CCS->soundh->stopSound(owner->moveSh);
owner->moveSh = -1;
}
delete this;
}
CMovementAnimation::CMovementAnimation(CBattleInterface *_owner, const CStack *_stack, std::vector<SHexField> _destTiles, int _distance)
: CBattleStackAnimation(_owner, _stack), destTiles(_destTiles), nextPos(0), distance(_distance), stepX(0.0), stepY(0.0)
{
curStackPos = stack->position;
nextHex = destTiles.front();
}

View File

@ -0,0 +1,37 @@
#pragma once
#include "CBattleStackAnimation.h"
class CBattleInterface;
class CStack;
/*
* CMovementAnimation.h, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
/// Move animation of a creature
class CMovementAnimation : public CBattleStackAnimation
{
private:
std::vector<SHexField> destTiles; //destination
SHexField nextHex;
ui32 nextPos;
int distance;
double stepX, stepY; //how far stack is moved in one frame
double posX, posY;
int steps, whichStep;
int curStackPos; //position of stack before move
public:
bool init();
void nextFrame();
void endAnim();
CMovementAnimation(CBattleInterface *_owner, const CStack *_stack, std::vector<SHexField> _destTiles, int _distance);
};

View File

@ -0,0 +1,52 @@
#include "StdInc.h"
#include "CMovementEndAnimation.h"
#include "../CCreatureAnimation.h"
#include "../CMusicHandler.h"
#include "../CGameInfo.h"
#include "../../lib/BattleState.h"
#include "../CCursorHandler.h"
bool CMovementEndAnimation::init()
{
if( !isEarliest(true) )
return false;
if(!stack || myAnim()->framesInGroup(CCreatureAnim::MOVE_END) == 0 ||
myAnim()->getType() == CCreatureAnim::DEATH)
{
endAnim();
return false;
}
CCS->soundh->playSound(battle_sound(stack->getCreature(), endMoving));
myAnim()->setType(CCreatureAnim::MOVE_END);
return true;
}
void CMovementEndAnimation::nextFrame()
{
if(myAnim()->onLastFrameInGroup())
{
endAnim();
}
}
void CMovementEndAnimation::endAnim()
{
CBattleAnimation::endAnim();
if(myAnim()->getType() != CCreatureAnim::DEATH)
myAnim()->setType(CCreatureAnim::HOLDING); //resetting to default
CCS->curh->show();
delete this;
}
CMovementEndAnimation::CMovementEndAnimation(CBattleInterface * _owner, const CStack * _stack, SHexField destTile)
: CBattleStackAnimation(_owner, _stack), destinationTile(destTile)
{
}

View File

@ -0,0 +1,30 @@
#pragma once
#include "CBattleStackAnimation.h"
class CBattleInterface;
class CStack;
/*
* CMovementEndAnimation.h, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
/// Move end animation of a creature
class CMovementEndAnimation : public CBattleStackAnimation
{
private:
SHexField destinationTile;
public:
bool init();
void nextFrame();
void endAnim();
CMovementEndAnimation(CBattleInterface *_owner, const CStack *_stack, SHexField destTile);
};

View File

@ -0,0 +1,52 @@
#include "StdInc.h"
#include "CMovementStartAnimation.h"
#include "../CMusicHandler.h"
#include "CBattleInterface.h"
#include "../CGameInfo.h"
#include "../CCreatureAnimation.h"
#include "../../lib/BattleState.h"
#include "../CPlayerInterface.h"
bool CMovementStartAnimation::init()
{
if( !isEarliest(false) )
return false;
if(!stack || myAnim()->getType() == 5)
{
CMovementStartAnimation::endAnim();
return false;
}
CCS->soundh->playSound(battle_sound(stack->getCreature(), startMoving));
myAnim()->setType(CCreatureAnim::MOVE_START);
return true;
}
void CMovementStartAnimation::nextFrame()
{
if(myAnim()->onLastFrameInGroup())
{
endAnim();
}
else
{
if((owner->animCount+1)%(4/owner->curInt->sysOpts.animSpeed)==0)
myAnim()->incrementFrame();
}
}
void CMovementStartAnimation::endAnim()
{
CBattleAnimation::endAnim();
delete this;
}
CMovementStartAnimation::CMovementStartAnimation(CBattleInterface * _owner, const CStack * _stack)
: CBattleStackAnimation(_owner, _stack)
{
}

View File

@ -0,0 +1,27 @@
#pragma once
#include "CBattleStackAnimation.h"
class CBattleInterface;
class CStack;
/*
* CMovementStartAnimation.h, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
/// Move start animation of a creature
class CMovementStartAnimation : public CBattleStackAnimation
{
public:
bool init();
void nextFrame();
void endAnim();
CMovementStartAnimation(CBattleInterface *_owner, const CStack *_stack);
};

View File

@ -0,0 +1,100 @@
#include "StdInc.h"
#include "CReverseAnimation.h"
#include "../CCreatureAnimation.h"
#include "../../lib/BattleState.h"
#include "CBattleInterface.h"
#include "CHexFieldControl.h"
bool CReverseAnimation::init()
{
if(myAnim() == NULL || myAnim()->getType() == 5)
{
endAnim();
return false; //there is no such creature
}
if(!priority && !isEarliest(false))
return false;
if(myAnim()->framesInGroup(CCreatureAnim::TURN_R))
myAnim()->setType(CCreatureAnim::TURN_R);
else
setupSecondPart();
return true;
}
void CReverseAnimation::nextFrame()
{
if(partOfAnim == 1) //first part of animation
{
if(myAnim()->onLastFrameInGroup())
{
partOfAnim = 2;
}
}
else if(partOfAnim == 2)
{
if(!secondPartSetup)
{
setupSecondPart();
}
if(myAnim()->onLastFrameInGroup())
{
endAnim();
}
}
}
void CReverseAnimation::endAnim()
{
CBattleAnimation::endAnim();
if( stack->alive() )//don't do that if stack is dead
myAnim()->setType(CCreatureAnim::HOLDING);
delete this;
}
CReverseAnimation::CReverseAnimation(CBattleInterface * _owner, const CStack * stack, SHexField dest, bool _priority)
: CBattleStackAnimation(_owner, stack), partOfAnim(1), secondPartSetup(false), hex(dest), priority(_priority)
{
}
void CReverseAnimation::setupSecondPart()
{
owner->creDir[stack->ID] = !owner->creDir[stack->ID];
if(!stack)
{
endAnim();
return;
}
Point coords = CHexFieldControl::getXYUnitAnim(hex, owner->creDir[stack->ID], stack, owner);
myAnim()->pos.x = coords.x;
//creAnims[stackID]->pos.y = coords.second;
if(stack->doubleWide())
{
if(stack->attackerOwned)
{
if(!owner->creDir[stack->ID])
myAnim()->pos.x -= 44;
}
else
{
if(owner->creDir[stack->ID])
myAnim()->pos.x += 44;
}
}
secondPartSetup = true;
if(myAnim()->framesInGroup(CCreatureAnim::TURN_L))
myAnim()->setType(CCreatureAnim::TURN_L);
else
endAnim();
}

View File

@ -0,0 +1,34 @@
#pragma once
#include "CBattleStackAnimation.h"
class CStack;
/*
* CReverseAnimation.h, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
/// Class responsible for animation of stack chaning direction (left <-> right)
class CReverseAnimation : public CBattleStackAnimation
{
private:
int partOfAnim; //1 - first, 2 - second
bool secondPartSetup;
SHexField hex;
public:
bool priority; //true - high, false - low
bool init();
void nextFrame();
void setupSecondPart();
void endAnim();
CReverseAnimation(CBattleInterface *_owner, const CStack *stack, SHexField dest, bool _priority);
};

View File

@ -0,0 +1,192 @@
#include "StdInc.h"
#include <boost/math/constants/constants.hpp>
#include "CShootingAnimation.h"
#include "../../lib/BattleState.h"
#include "CBattleInterface.h"
#include "../CCreatureAnimation.h"
#include "../CGameInfo.h"
#include "../../lib/CTownHandler.h"
#include "CMovementStartAnimation.h"
#include "CReverseAnimation.h"
#include "CSpellEffectAnimation.h"
#include "CHexFieldControl.h"
bool CShootingAnimation::init()
{
if( !CAttackAnimation::checkInitialConditions() )
return false;
const CStack * shooter = attackingStack;
if(!shooter || myAnim()->getType() == 5)
{
endAnim();
return false;
}
// Create the projectile animation
double projectileAngle; //in radians; if positive, projectiles goes up
double straightAngle = 0.2; //maximal angle in radians between straight horizontal line and shooting line for which shot is considered to be straight (absoulte value)
int fromHex = shooter->position;
projectileAngle = atan2(static_cast<double>(abs(dest - fromHex) / GameConstants::BFIELD_WIDTH), static_cast<double>(abs(dest - fromHex) % GameConstants::BFIELD_WIDTH));
if(fromHex < dest)
projectileAngle = -projectileAngle;
// Get further info about the shooter e.g. relative pos of projectile to unit.
// If the creature id is 149 then it's a arrow tower which has no additional info so get the
// actual arrow tower shooter instead.
const CCreature *shooterInfo = shooter->getCreature();
if (shooterInfo->idNumber == 149)
{
int creID = CGI->creh->factionToTurretCreature[owner->siegeH->town->town->typeID];
shooterInfo = CGI->creh->creatures[creID];
}
SProjectileInfo spi;
spi.creID = shooter->getCreature()->idNumber;
spi.stackID = shooter->ID;
spi.reverse = !shooter->attackerOwned;
spi.step = 0;
spi.frameNum = 0;
if(vstd::contains(CGI->creh->idToProjectileSpin, shooterInfo->idNumber))
spi.spin = CGI->creh->idToProjectileSpin[shooterInfo->idNumber];
else
{
tlog2 << "Warning - no projectile spin for spi.creID " << shooterInfo->idNumber << std::endl;
spi.spin = false;
}
Point xycoord = CHexFieldControl::getXYUnitAnim(shooter->position, true, shooter, owner);
Point destcoord;
// The "master" point where all projectile positions relate to.
static const Point projectileOrigin(181, 252);
if (attackedStack)
{
destcoord = CHexFieldControl::getXYUnitAnim(dest, false, attackedStack, owner);
destcoord.x += 250; destcoord.y += 210; //TODO: find a better place to shoot
// Calculate projectile start position. Offsets are read out of the CRANIM.TXT.
if (projectileAngle > straightAngle)
{
//upper shot
spi.x = xycoord.x + projectileOrigin.x + shooterInfo->upperRightMissleOffsetX;
spi.y = xycoord.y + projectileOrigin.y + shooterInfo->upperRightMissleOffsetY;
}
else if (projectileAngle < -straightAngle)
{
//lower shot
spi.x = xycoord.x + projectileOrigin.x + shooterInfo->lowerRightMissleOffsetX;
spi.y = xycoord.y + projectileOrigin.y + shooterInfo->lowerRightMissleOffsetY;
}
else
{
//straight shot
spi.x = xycoord.x + projectileOrigin.x + shooterInfo->rightMissleOffsetX;
spi.y = xycoord.y + projectileOrigin.y + shooterInfo->rightMissleOffsetY;
}
double animSpeed = 23.0 * owner->getAnimSpeed(); // flight speed of projectile
spi.lastStep = static_cast<int>(sqrt(static_cast<double>((destcoord.x - spi.x) * (destcoord.x - spi.x) + (destcoord.y - spi.y) * (destcoord.y - spi.y))) / animSpeed);
if(spi.lastStep == 0)
spi.lastStep = 1;
spi.dx = (destcoord.x - spi.x) / spi.lastStep;
spi.dy = (destcoord.y - spi.y) / spi.lastStep;
spi.catapultInfo = 0;
}
else
{
// Catapult attack
// These are the values for equations of this kind: f(x) = ax^2 + bx + c
static const std::vector<SCatapultSProjectileInfo*> trajectoryCurves = boost::assign::list_of<SCatapultSProjectileInfo*>(new SCatapultSProjectileInfo(4.309, -3.198, 569.2, -296, 182))
(new SCatapultSProjectileInfo(4.710, -3.11, 558.68, -258, 175))(new SCatapultSProjectileInfo(5.056, -3.003, 546.9, -236, 174))
(new SCatapultSProjectileInfo(4.760, -2.74, 526.47, -216, 215))(new SCatapultSProjectileInfo(4.288, -2.496, 508.98, -223, 274))
(new SCatapultSProjectileInfo(3.683, -3.018, 558.39, -324, 176))(new SCatapultSProjectileInfo(2.884, -2.607, 528.95, -366, 312))
(new SCatapultSProjectileInfo(3.783, -2.364, 501.35, -227, 318));
static std::map<int, int> hexToCurve = boost::assign::map_list_of<int, int>(29, 0)(62, 1)(95, 2)(130, 3)(182, 4)(12, 5)(50, 6)(183, 7);
std::map<int, int>::iterator it = hexToCurve.find(dest.hex);
if (it == hexToCurve.end())
{
tlog1 << "For the hex position " << dest.hex << " is no curve defined.";
endAnim();
return false;
}
else
{
int curveID = it->second;
spi.catapultInfo = trajectoryCurves[curveID];
double animSpeed = 3.318 * owner->getAnimSpeed();
spi.lastStep = static_cast<int>((spi.catapultInfo->toX - spi.catapultInfo->fromX) / animSpeed);
spi.dx = animSpeed;
spi.dy = 0;
spi.x = xycoord.x + projectileOrigin.x + shooterInfo->rightMissleOffsetX + 17.;
spi.y = xycoord.y + projectileOrigin.y + shooterInfo->rightMissleOffsetY + 10.;
// Add explosion anim
int xEnd = static_cast<int>(spi.x + spi.lastStep * spi.dx);
int yEnd = static_cast<int>(spi.catapultInfo->calculateY(xEnd));
owner->addNewAnim( new CSpellEffectAnimation(owner, "SGEXPL.DEF", xEnd - 126, yEnd - 105));
}
}
// Set starting frame
if(spi.spin)
{
spi.frameNum = 0;
}
else
{
double pi = boost::math::constants::pi<double>();
spi.frameNum = static_cast<int>(((pi / 2.0 - projectileAngle) / (2.0 * pi) + 1/(static_cast<double>(2*(owner->idToProjectile[spi.creID]->ourImages.size()-1)))) * (owner->idToProjectile[spi.creID]->ourImages.size()-1));
}
// Set projectile animation start delay which is specified in frames
spi.animStartDelay = shooterInfo->attackClimaxFrame;
owner->projectiles.push_back(spi);
//attack animation
shooting = true;
if(projectileAngle > straightAngle) //upper shot
group = CCreatureAnim::SHOOT_UP;
else if(projectileAngle < -straightAngle) //lower shot
group = CCreatureAnim::SHOOT_DOWN;
else //straight shot
group = CCreatureAnim::SHOOT_FRONT;
return true;
}
void CShootingAnimation::nextFrame()
{
for(std::list<std::pair<CBattleAnimation *, bool> >::const_iterator it = owner->pendingAnims.begin(); it != owner->pendingAnims.end(); ++it)
{
CMovementStartAnimation * anim = dynamic_cast<CMovementStartAnimation *>(it->first);
CReverseAnimation * anim2 = dynamic_cast<CReverseAnimation *>(it->first);
if( (anim && anim->stack->ID == stack->ID) || (anim2 && anim2->stack->ID == stack->ID && anim2->priority ) )
return;
}
CAttackAnimation::nextFrame();
}
void CShootingAnimation::endAnim()
{
CBattleAnimation::endAnim();
delete this;
}
CShootingAnimation::CShootingAnimation(CBattleInterface * _owner, const CStack * attacker, SHexField _dest, const CStack * _attacked, bool _catapult, int _catapultDmg)
: CAttackAnimation(_owner, attacker, _dest, _attacked), catapultDamage(_catapultDmg), catapult(_catapult)
{
}

View File

@ -0,0 +1,49 @@
#pragma once
#include "CAttackAnimation.h"
#include "../../lib/SHexField.h"
class CBattleInterface;
class CStack;
struct SCatapultSProjectileInfo;
/*
* CShootingAnimation.h, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
/// Small struct which contains information about the position and the velocity of a projectile
struct SProjectileInfo
{
double x, y; //position on the screen
double dx, dy; //change in position in one step
int step, lastStep; //to know when finish showing this projectile
int creID; //ID of creature that shot this projectile
int stackID; //ID of stack
int frameNum; //frame to display form projectile animation
bool spin; //if true, frameNum will be increased
int animStartDelay; //how many times projectile must be attempted to be shown till it's really show (decremented after hit)
bool reverse; //if true, projectile will be flipped by vertical asix
SCatapultSProjectileInfo *catapultInfo; // holds info about the parabolic trajectory of the cannon
};
/// Shooting attack
class CShootingAnimation : public CAttackAnimation
{
private:
int catapultDamage;
bool catapult;
public:
bool init();
void nextFrame();
void endAnim();
//last param only for catapult attacks
CShootingAnimation(CBattleInterface *_owner, const CStack *attacker,
SHexField _dest, const CStack *_attacked, bool _catapult = false, int _catapultDmg = 0);
};

View File

@ -0,0 +1,181 @@
#include "StdInc.h"
#include "CSpellEffectAnimation.h"
#include "../Graphics.h"
#include "CBattleInterface.h"
#include "../CDefHandler.h"
#include "../CPlayerInterface.h"
#include "../../CCallback.h"
#include "../../lib/BattleState.h"
#include "../SDL_Extensions.h"
//effect animation
bool CSpellEffectAnimation::init()
{
if(!isEarliest(true))
return false;
if(effect == 12) //armageddon
{
if(effect == -1 || graphics->battleACToDef[effect].size() != 0)
{
CDefHandler * anim;
if(customAnim.size())
anim = CDefHandler::giveDef(customAnim);
else
anim = CDefHandler::giveDef(graphics->battleACToDef[effect][0]);
if (Vflip)
{
for (size_t v = 0; v < anim->ourImages.size(); ++v)
{
CSDL_Ext::VflipSurf(anim->ourImages[v].bitmap);
}
}
for(int i=0; i * anim->width < owner->pos.w ; ++i)
{
for(int j=0; j * anim->height < owner->pos.h ; ++j)
{
SBattleEffect be;
be.effectID = ID;
be.anim = CDefHandler::giveDef(graphics->battleACToDef[effect][0]);
if (Vflip)
{
for (size_t v = 0; v < be.anim->ourImages.size(); ++v)
{
CSDL_Ext::VflipSurf(be.anim->ourImages[v].bitmap);
}
}
be.frame = 0;
be.maxFrame = be.anim->ourImages.size();
be.x = i * anim->width + owner->pos.x;
be.y = j * anim->height + owner->pos.y;
owner->battleEffects.push_back(be);
}
}
}
else //there is nothing to play
{
endAnim();
return false;
}
}
else // Effects targeted at a specific creature/hex.
{
if(effect == -1 || graphics->battleACToDef[effect].size() != 0)
{
const CStack* destStack = owner->curInt->cb->battleGetStackByPos(destTile, false);
Rect &tilePos = owner->bfield[destTile].pos;
SBattleEffect be;
be.effectID = ID;
if(customAnim.size())
be.anim = CDefHandler::giveDef(customAnim);
else
be.anim = CDefHandler::giveDef(graphics->battleACToDef[effect][0]);
if (Vflip)
{
for (size_t v = 0; v < be.anim->ourImages.size(); ++v)
{
CSDL_Ext::VflipSurf(be.anim->ourImages[v].bitmap);
}
}
be.frame = 0;
be.maxFrame = be.anim->ourImages.size();
if(effect == 1)
be.maxFrame = 3;
switch (effect)
{
case -1:
be.x = x;
be.y = y;
break;
case 0: // Prayer and Lightning Bolt.
case 1:
// Position effect with it's bottom center touching the bottom center of affected tile(s).
be.x = tilePos.x + tilePos.w/2 - be.anim->width/2;
be.y = tilePos.y + tilePos.h - be.anim->height;
break;
default:
// Position effect with it's center touching the top center of affected tile(s).
be.x = tilePos.x + tilePos.w/2 - be.anim->width/2;
be.y = tilePos.y - be.anim->height/2;
break;
}
// Correction for 2-hex creatures.
if (destStack != NULL && destStack->doubleWide())
be.x += (destStack->attackerOwned ? -1 : 1)*tilePos.w/2;
owner->battleEffects.push_back(be);
}
else //there is nothing to play
{
endAnim();
return false;
}
}
//battleEffects
return true;
}
void CSpellEffectAnimation::nextFrame()
{
//notice: there may be more than one effect in owner->battleEffects correcponding to this animation (ie. armageddon)
for(std::list<SBattleEffect>::iterator it = owner->battleEffects.begin(); it != owner->battleEffects.end(); ++it)
{
if(it->effectID == ID)
{
++(it->frame);
if(it->frame == it->maxFrame)
{
endAnim();
break;
}
else
{
it->x += dx;
it->y += dy;
}
}
}
}
void CSpellEffectAnimation::endAnim()
{
CBattleAnimation::endAnim();
std::vector<std::list<SBattleEffect>::iterator> toDel;
for(std::list<SBattleEffect>::iterator it = owner->battleEffects.begin(); it != owner->battleEffects.end(); ++it)
{
if(it->effectID == ID)
{
toDel.push_back(it);
}
}
for(size_t b = 0; b < toDel.size(); ++b)
{
delete toDel[b]->anim;
owner->battleEffects.erase(toDel[b]);
}
delete this;
}
CSpellEffectAnimation::CSpellEffectAnimation(CBattleInterface * _owner, ui32 _effect, SHexField _destTile, int _dx, int _dy, bool _Vflip)
:CBattleAnimation(_owner), effect(_effect), destTile(_destTile), customAnim(""), dx(_dx), dy(_dy), Vflip(_Vflip)
{
}
CSpellEffectAnimation::CSpellEffectAnimation(CBattleInterface * _owner, std::string _customAnim, int _x, int _y, int _dx, int _dy, bool _Vflip)
:CBattleAnimation(_owner), effect(-1), destTile(0), customAnim(_customAnim), x(_x), y(_y), dx(_dx), dy(_dy), Vflip(_Vflip)
{
}

View File

@ -0,0 +1,35 @@
#pragma once
#include "CBattleAnimation.h"
#include "../../lib/SHexField.h"
class CBattleInterface;
/*
* CSpellEffectAnimation.h, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
/// This class manages a spell effect animation
class CSpellEffectAnimation : public CBattleAnimation
{
private:
ui32 effect;
SHexField destTile;
std::string customAnim;
int x, y, dx, dy;
bool Vflip;
public:
bool init();
void nextFrame();
void endAnim();
CSpellEffectAnimation(CBattleInterface *_owner, ui32 _effect, SHexField _destTile, int _dx = 0, int _dy = 0, bool _Vflip = false);
CSpellEffectAnimation(CBattleInterface *_owner, std::string _customAnim, int _x, int _y, int _dx = 0, int _dy = 0, bool _Vflip = false);
};

View File

@ -0,0 +1,125 @@
#include "StdInc.h"
#include "CStackQueue.h"
#include "CBattleInterface.h"
#include "../../lib/BattleState.h"
#include "../Graphics.h"
#include "../SDL_Extensions.h"
#include "../CPlayerInterface.h"
#include "../CBitmapHandler.h"
#include "../../CCallback.h"
void CStackQueue::update()
{
stacksSorted.clear();
owner->curInt->cb->getStackQueue(stacksSorted, QUEUE_SIZE);
for (int i = 0; i < QUEUE_SIZE ; i++)
{
stackBoxes[i]->setStack(stacksSorted[i]);
}
}
CStackQueue::CStackQueue(bool Embedded, CBattleInterface * _owner)
:embedded(Embedded), owner(_owner)
{
OBJ_CONSTRUCTION_CAPTURING_ALL;
if(embedded)
{
box = NULL;
bg = NULL;
pos.w = QUEUE_SIZE * 37;
pos.h = 32; //height of small creature img
pos.x = screen->w/2 - pos.w/2;
pos.y = (screen->h - 600)/2 + 10;
}
else
{
box = BitmapHandler::loadBitmap("CHRROP.pcx");
bg = BitmapHandler::loadBitmap("DIBOXPI.pcx");
pos.w = 600;
pos.h = bg->h;
}
stackBoxes.resize(QUEUE_SIZE);
for (int i = 0; i < QUEUE_SIZE; i++)
{
stackBoxes[i] = new StackBox(box);
stackBoxes[i]->pos.x += 6 + (embedded ? 37 : 79)*i;
}
}
CStackQueue::~CStackQueue()
{
SDL_FreeSurface(box);
}
void CStackQueue::showAll( SDL_Surface *to )
{
blitBg(to);
CIntObject::showAll(to);
}
void CStackQueue::blitBg( SDL_Surface * to )
{
if(bg)
{
for (int w = 0; w < pos.w; w += bg->w)
{
blitAtLoc(bg, w, 0, to);
}
}
}
void CStackQueue::StackBox::showAll( SDL_Surface *to )
{
assert(my);
if(bg)
{
graphics->blueToPlayersAdv(bg, my->owner);
//SDL_UpdateRect(bg, 0, 0, 0, 0);
SDL_Rect temp_rect = genRect(bg->h, bg->w, pos.x, pos.y);
CSDL_Ext::blit8bppAlphaTo24bpp(bg, NULL, to, &temp_rect);
//blitAt(bg, pos, to);
blitAt(graphics->bigImgs[my->getCreature()->idNumber], pos.x +9, pos.y + 1, to);
printAtMiddleLoc(makeNumberShort(my->count), pos.w/2, pos.h - 12, FONT_MEDIUM, zwykly, to);
}
else
{
blitAt(graphics->smallImgs[-2], pos, to);
blitAt(graphics->smallImgs[my->getCreature()->idNumber], pos, to);
const SDL_Color &ownerColor = (my->owner == 255 ? *graphics->neutralColor : graphics->playerColors[my->owner]);
CSDL_Ext::drawBorder(to, pos, int3(ownerColor.r, ownerColor.g, ownerColor.b));
printAtMiddleLoc(makeNumberShort(my->count), pos.w/2, pos.h - 8, FONT_TINY, zwykly, to);
}
}
void CStackQueue::StackBox::setStack( const CStack *nStack )
{
my = nStack;
}
CStackQueue::StackBox::StackBox(SDL_Surface *BG)
:my(NULL), bg(BG)
{
if(bg)
{
pos.w = bg->w;
pos.h = bg->h;
}
else
{
pos.w = pos.h = 32;
}
pos.y += 2;
}
CStackQueue::StackBox::~StackBox()
{
}
void CStackQueue::StackBox::hover( bool on )
{
}

View File

@ -0,0 +1,51 @@
#pragma once
#include "../GUIBase.h"
struct SDL_Surface;
class CStack;
class CBattleInterface;
/*
* CStackQueue.h, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
/// Shows the stack queue
class CStackQueue : public CIntObject
{
class StackBox : public CIntObject
{
public:
const CStack *my;
SDL_Surface *bg;
void hover (bool on);
void showAll(SDL_Surface *to);
void setStack(const CStack *nStack);
StackBox(SDL_Surface *BG);
~StackBox();
};
public:
static const int QUEUE_SIZE = 10;
const bool embedded;
std::vector<const CStack *> stacksSorted;
std::vector<StackBox *> stackBoxes;
SDL_Surface *box;
SDL_Surface *bg;
CBattleInterface * owner;
void showAll(SDL_Surface *to);
CStackQueue(bool Embedded, CBattleInterface * _owner);
~CStackQueue();
void update();
void blitBg( SDL_Surface * to );
//void showAll(SDL_Surface *to);
};

View File

@ -0,0 +1,25 @@
#pragma once
class CStack;
/*
* SStackAttackedInfo.h, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
/// Small struct which contains information about the id of the attacked stack, the damage dealt,...
struct SStackAttackedInfo
{
const CStack * defender; //attacked stack
int dmg; //damage dealt
int amountKilled; //how many creatures in stack has been killed
const CStack * attacker; //attacking stack
bool byShooting; //if true, stack has been attacked by shooting
bool killed; //if true, stack has been killed
bool rebirth; //if true, play rebirth animation after all
};

View File

@ -1,597 +0,0 @@
#ifndef __CBATTLEINTERFACE_H__
#define __CBATTLEINTERFACE_H__
#include "../global.h"
#include <list>
#include "GUIBase.h"
#include "../lib/CCreatureSet.h"
#include "../lib/ConstTransitivePtr.h" //may be reundant
#include "CAnimation.h"
/*
* CBattleInterface.h, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
class CLabel;
class CCreatureSet;
class CGHeroInstance;
class CDefHandler;
class CStack;
class CCallback;
class AdventureMapButton;
class CHighlightableButton;
class CHighlightableButtonsGroup;
struct BattleResult;
struct BattleSpellCast;
struct CObstacleInstance;
template <typename T> struct CondSh;
struct SetStackEffect;;
struct BattleAction;
class CGTownInstance;
struct CatapultAttack;
class CBattleInterface;
struct CatapultProjectileInfo;
struct BattleTriggerEffect;
/// Small struct which contains information about the id of the attacked stack, the damage dealt,...
struct SStackAttackedInfo
{
const CStack * defender; //attacked stack
int dmg; //damage dealt
int amountKilled; //how many creatures in stack has been killed
const CStack * attacker; //attacking stack
bool byShooting; //if true, stack has been attacked by shooting
bool killed; //if true, stack has been killed
bool rebirth; //if true, play rebirth animation after all
};
/// Small struct which contains information about the position and the velocity of a projectile
struct SProjectileInfo
{
double x, y; //position on the screen
double dx, dy; //change in position in one step
int step, lastStep; //to know when finish showing this projectile
int creID; //ID of creature that shot this projectile
int stackID; //ID of stack
int frameNum; //frame to display form projectile animation
bool spin; //if true, frameNum will be increased
int animStartDelay; //how many times projectile must be attempted to be shown till it's really show (decremented after hit)
bool reverse; //if true, projectile will be flipped by vertical asix
CatapultProjectileInfo *catapultInfo; // holds info about the parabolic trajectory of the cannon
};
/// Base class of battle animations
class CBattleAnimation
{
protected:
CBattleInterface * owner;
public:
virtual bool init()=0; //to be called - if returned false, call again until returns true
virtual void nextFrame()=0; //call every new frame
virtual void endAnim(); //to be called mostly internally; in this class it removes animation from pendingAnims list
bool isEarliest(bool perStackConcurrency); //determines if this animation is earliest of all
unsigned int ID; //unique identifier
CBattleAnimation(CBattleInterface * _owner);
};
class CDummyAnim : public CBattleAnimation
{
private:
int counter;
int howMany;
public:
bool init();
void nextFrame();
void endAnim();
CDummyAnim(CBattleInterface * _owner, int howManyFrames);
};
/// This class manages a spell effect animation
class CSpellEffectAnim : public CBattleAnimation
{
private:
ui32 effect;
THex destTile;
std::string customAnim;
int x, y, dx, dy;
bool Vflip;
public:
bool init();
void nextFrame();
void endAnim();
CSpellEffectAnim(CBattleInterface * _owner, ui32 _effect, THex _destTile, int _dx = 0, int _dy = 0, bool _Vflip = false);
CSpellEffectAnim(CBattleInterface * _owner, std::string _customAnim, int _x, int _y, int _dx = 0, int _dy = 0, bool _Vflip = false);
};
/// Sub-class which is responsible for managing the battle stack animation.
class CBattleStackAnimation : public CBattleAnimation
{
public:
const CStack * stack; //id of stack whose animation it is
CBattleStackAnimation(CBattleInterface * _owner, const CStack * _stack);
static bool isToReverseHlp(THex hexFrom, THex hexTo, bool curDir); //helper for isToReverse
static bool isToReverse(THex hexFrom, THex hexTo, bool curDir /*if true, creature is in attacker's direction*/, bool toDoubleWide, bool toDir); //determines if creature should be reversed (it stands on hexFrom and should 'see' hexTo)
CCreatureAnimation *myAnim(); //animation for our stack
};
/// Class responsible for animation of stack chaning direction (left <-> right)
class CReverseAnim : public CBattleStackAnimation
{
private:
int partOfAnim; //1 - first, 2 - second
bool secondPartSetup;
THex hex;
public:
bool priority; //true - high, false - low
bool init();
void nextFrame();
void setupSecondPart();
void endAnim();
CReverseAnim(CBattleInterface * _owner, const CStack * stack, THex dest, bool _priority);
};
/// Animation of a defending unit
class CDefenceAnim : public CBattleStackAnimation
{
private:
//std::vector<SStackAttackedInfo> attackedInfos;
int dmg; //damage dealt
int amountKilled; //how many creatures in stack has been killed
const CStack * attacker; //attacking stack
bool byShooting; //if true, stack has been attacked by shooting
bool killed; //if true, stack has been killed
public:
bool init();
void nextFrame();
void endAnim();
CDefenceAnim(SStackAttackedInfo _attackedInfo, CBattleInterface * _owner);
};
/// Move animation of a creature
class CBattleStackMoved : public CBattleStackAnimation
{
private:
std::vector<THex> destTiles; //destination
THex nextHex;
int nextPos;
int distance;
float stepX, stepY; //how far stack is moved in one frame
float posX, posY;
int steps, whichStep;
int curStackPos; //position of stack before move
public:
bool init();
void nextFrame();
void endAnim();
CBattleStackMoved(CBattleInterface * _owner, const CStack * _stack, std::vector<THex> _destTiles, int _distance);
};
/// Move start animation of a creature
class CBattleMoveStart : public CBattleStackAnimation
{
public:
bool init();
void nextFrame();
void endAnim();
CBattleMoveStart(CBattleInterface * _owner, const CStack * _stack);
};
/// Move end animation of a creature
class CBattleMoveEnd : public CBattleStackAnimation
{
private:
THex destinationTile;
public:
bool init();
void nextFrame();
void endAnim();
CBattleMoveEnd(CBattleInterface * _owner, const CStack * _stack, THex destTile);
};
/// This class is responsible for managing the battle attack animation
class CBattleAttack : public CBattleStackAnimation
{
protected:
THex dest; //atacked hex
bool shooting;
CCreatureAnim::EAnimType group; //if shooting is true, print this animation group
const CStack * attackedStack;
const CStack * attackingStack;
int attackingStackPosBeforeReturn; //for stacks with return_after_strike feature
public:
void nextFrame();
bool checkInitialConditions();
CBattleAttack(CBattleInterface * _owner, const CStack * attacker, THex _dest, const CStack * defender);
};
/// Hand-to-hand attack
class CMeleeAttack : public CBattleAttack
{
public:
bool init();
void nextFrame();
void endAnim();
CMeleeAttack(CBattleInterface * _owner, const CStack * attacker, THex _dest, const CStack * _attacked);
};
/// Shooting attack
class CShootingAnim : public CBattleAttack
{
private:
int catapultDamage;
bool catapult;
public:
bool init();
void nextFrame();
void endAnim();
CShootingAnim(CBattleInterface * _owner, const CStack * attacker, THex _dest, const CStack * _attacked, bool _catapult = false, int _catapultDmg = 0); //last param only for catapult attacks
};
//end of battle animation handlers
/// Hero battle animation
class CBattleHero : public CIntObject
{
public:
bool flip; //false if it's attacking hero, true otherwise
CDefHandler * dh, *flag; //animation and flag
const CGHeroInstance * myHero; //this animation's hero instance
const CBattleInterface * myOwner; //battle interface to which this animation is assigned
int phase; //stage of animation
int nextPhase; //stage of animation to be set after current phase is fully displayed
int image; //frame of animation
unsigned char flagAnim, flagAnimCount; //for flag animation
void show(SDL_Surface * to); //prints next frame of animation to to
void activate();
void deactivate();
void setPhase(int newPhase); //sets phase of hero animation
void clickLeft(tribool down, bool previousState); //call-in
CBattleHero(const std::string & defName, int phaseG, int imageG, bool filpG, unsigned char player, const CGHeroInstance * hero, const CBattleInterface * owner); //c-tor
~CBattleHero(); //d-tor
};
/// Class which stands for a single hex field on a battlefield
class CBattleHex : public CIntObject
{
private:
bool setAlterText; //if true, this hex has set alternative text in console and will clean it
public:
unsigned int myNumber; //number of hex in commonly used format
bool accessible; //if true, this hex is accessible for units
//CStack * ourStack;
bool hovered, strictHovered; //for determining if hex is hovered by mouse (this is different problem than hex's graphic hovering)
CBattleInterface * myInterface; //interface that owns me
static Point getXYUnitAnim(const int & hexNum, const bool & attacker, const CStack * creature, const CBattleInterface * cbi); //returns (x, y) of left top corner of animation
//for user interactions
void hover (bool on);
void activate();
void deactivate();
void mouseMoved (const SDL_MouseMotionEvent & sEvent);
void clickLeft(tribool down, bool previousState);
void clickRight(tribool down, bool previousState);
CBattleHex();
};
/// Class which manages the locked hex fields that are blocked e.g. by obstacles
class CBattleObstacle
{
std::vector<int> lockedHexes;
};
/// Class which shows the console at the bottom of the battle screen and manages the text of the console
class CBattleConsole : public CIntObject
{
private:
std::vector< std::string > texts; //a place where texts are stored
int lastShown; //last shown line of text
public:
std::string alterTxt; //if it's not empty, this text is displayed
std::string ingcAlter; //alternative text set by in-game console - very important!
int whoSetAlter; //who set alter text; 0 - battle interface or none, 1 - button
CBattleConsole(); //c-tor
~CBattleConsole(); //d-tor
void show(SDL_Surface * to = 0);
bool addText(const std::string & text); //adds text at the last position; returns false if failed (e.g. text longer than 70 characters)
void eraseText(unsigned int pos); //erases added text at position pos
void changeTextAt(const std::string & text, unsigned int pos); //if we have more than pos texts, pos-th is changed to given one
void scrollUp(unsigned int by = 1); //scrolls console up by 'by' positions
void scrollDown(unsigned int by = 1); //scrolls console up by 'by' positions
};
/// Class which is responsible for showing the battle result window
class CBattleResultWindow : public CIntObject
{
private:
SDL_Surface * background;
AdventureMapButton * exit;
CBattleInterface * owner;
public:
CBattleResultWindow(const BattleResult & br, const SDL_Rect & pos, CBattleInterface * _owner); //c-tor
~CBattleResultWindow(); //d-tor
void bExitf(); //exit button callback
void activate();
void deactivate();
void show(SDL_Surface * to = 0);
};
/// Class which manages the battle options window
class CBattleOptionsWindow : public CIntObject
{
private:
CBattleInterface * myInt;
CPicture * background;
AdventureMapButton * setToDefault, * exit;
CHighlightableButton * viewGrid, * movementShadow, * mouseShadow;
CHighlightableButtonsGroup * animSpeeds;
std::vector<CLabel*> labels;
public:
CBattleOptionsWindow(const SDL_Rect & position, CBattleInterface * owner); //c-tor
void bDefaultf(); //dafault button callback
void bExitf(); //exit button callback
};
/// Struct for battle effect animation e.g. morale, prayer, armageddon, bless,...
struct SBattleEffect
{
int x, y; //position on the screen
int frame, maxFrame;
CDefHandler * anim; //animation to display
int effectID; //uniqueID equal ot ID of appropriate CSpellEffectAnim
};
/// Shows the stack queue
class CStackQueue : public CIntObject
{
class StackBox : public CIntObject
{
public:
const CStack *my;
SDL_Surface *bg;
void hover (bool on);
void showAll(SDL_Surface *to);
void setStack(const CStack *nStack);
StackBox(SDL_Surface *BG);
~StackBox();
};
public:
static const int QUEUE_SIZE = 10;
const bool embedded;
std::vector<const CStack *> stacksSorted;
std::vector<StackBox *> stackBoxes;
SDL_Surface *box;
SDL_Surface *bg;
CBattleInterface * owner;
void showAll(SDL_Surface *to);
CStackQueue(bool Embedded, CBattleInterface * _owner);
~CStackQueue();
void update();
void blitBg( SDL_Surface * to );
//void showAll(SDL_Surface *to);
};
/// Small struct which is needed for drawing the parabolic trajectory of the catapult cannon
struct CatapultProjectileInfo
{
const double facA, facB, facC;
const int fromX, toX;
CatapultProjectileInfo() : facA(0), facB(0), facC(0), fromX(0), toX(0) { };
CatapultProjectileInfo(double factorA, double factorB, double factorC, int fromXX, int toXX) : facA(factorA), facB(factorB), facC(factorC),
fromX(fromXX), toX(toXX) { };
double calculateY(double x);
};
/// Big class which handles the overall battle interface actions and it is also responsible for
/// drawing everything correctly.
class CBattleInterface : public CIntObject
{
enum SpellSelectionType
{
ANY_LOCATION = 0, FRIENDLY_CREATURE, HOSTILE_CREATURE, ANY_CREATURE, OBSTACLE, TELEPORT, NO_LOCATION = -1, STACK_SPELL_CANCELLED = -2
};
private:
SDL_Surface * background, * menu, * amountNormal, * amountNegative, * amountPositive, * amountEffNeutral, * cellBorders, * backgroundWithHexes;
AdventureMapButton * bOptions, * bSurrender, * bFlee, * bAutofight, * bSpell,
* bWait, * bDefence, * bConsoleUp, * bConsoleDown, *btactNext, *btactEnd;
CBattleConsole * console;
CBattleHero * attackingHero, * defendingHero; //fighting heroes
CStackQueue *queue;
const CCreatureSet *army1, *army2; //copy of initial armies (for result window)
const CGHeroInstance * attackingHeroInstance, * defendingHeroInstance;
std::map< int, CCreatureAnimation * > creAnims; //animations of creatures from fighting armies (order by BattleInfo's stacks' ID)
std::map< int, CDefHandler * > idToProjectile; //projectiles of creatures (creatureID, defhandler)
std::map< int, CDefHandler * > idToObstacle; //obstacles located on the battlefield
std::map< int, bool > creDir; // <creatureID, if false reverse creature's animation>
unsigned char animCount;
const CStack * activeStack; //number of active stack; NULL - no one
const CStack * stackToActivate; //when animation is playing, we should wait till the end to make the next stack active; NULL of none
void activateStack(); //sets activeStack to stackToActivate etc.
int mouseHoveredStack; //stack hovered by mouse; if -1 -> none
time_t lastMouseHoveredStackAnimationTime; // time when last mouse hovered animation occurred
static const time_t HOVER_ANIM_DELTA;
std::vector<THex> occupyableHexes, //hexes available for active stack
attackableHexes; //hexes attackable by active stack
bool stackCountOutsideHexes[BFIELD_SIZE]; // hexes that when in front of a unit cause it's amount box to move back
int previouslyHoveredHex; //number of hex that was hovered by the cursor a while ago
int currentlyHoveredHex; //number of hex that is supposed to be hovered (for a while it may be inappropriately set, but will be renewed soon)
int attackingHex; //hex from which the stack would perform attack with current cursor
float getAnimSpeedMultiplier() const; //returns multiplier for number of frames in a group
std::map<int, int> standingFrame; //number of frame in standing animation by stack ID, helps in showing 'random moves'
CPlayerInterface *tacticianInterface; //used during tactics mode, points to the interface of player with higher tactics (can be either attacker or defender in hot-seat), valid onloy for human players
bool tacticsMode;
bool stackCanCastSpell; //if true, active stack could possibly cats some target spell
bool spellDestSelectMode; //if true, player is choosing destination for his spell
SpellSelectionType spellSelMode;
BattleAction * spellToCast; //spell for which player is choosing destination
TSpell creatureSpellToCast;
void endCastingSpell(); //ends casting spell (eg. when spell has been cast or canceled)
void showAliveStack(const CStack *stack, SDL_Surface * to); //helper function for function show
void showAliveStacks(std::vector<const CStack *> *aliveStacks, int hex, std::vector<const CStack *> *flyingStacks, SDL_Surface *to); // loops through all stacks at a given hex position
void showPieceOfWall(SDL_Surface * to, int hex, const std::vector<const CStack*> & stacks); //helper function for show
void showObstacles(std::multimap<THex, int> *hexToObstacle, std::vector<CObstacleInstance> &obstacles, int hex, SDL_Surface *to); // show all obstacles at a given hex position
void redrawBackgroundWithHexes(const CStack * activeStack);
void printConsoleAttacked(const CStack * defender, int dmg, int killed, const CStack * attacker, bool Multiple);
std::list<SProjectileInfo> projectiles; //projectiles flying on battlefield
void projectileShowHelper(SDL_Surface * to); //prints projectiles present on the battlefield
void giveCommand(ui8 action, THex tile, ui32 stack, si32 additional=-1);
bool isTileAttackable(const THex & number) const; //returns true if tile 'number' is neighboring any tile from active stack's range or is one of these tiles
bool blockedByObstacle(THex hex) const;
bool isCatapultAttackable(THex hex) const; //returns true if given tile can be attacked by catapult
std::list<SBattleEffect> battleEffects; //different animations to display on the screen like spell effects
/// Class which is responsible for drawing the wall of a siege during battle
class SiegeHelper
{
private:
static std::string townTypeInfixes[F_NUMBER]; //for internal use only - to build filenames
SDL_Surface * walls[18];
const CBattleInterface * owner;
public:
const CGTownInstance * town; //besieged town
SiegeHelper(const CGTownInstance * siegeTown, const CBattleInterface * _owner); //c-tor
~SiegeHelper(); //d-tor
//filename getters
std::string getSiegeName(ui16 what, ui16 additInfo = 1) const; //what: 0 - background, 1 - background wall, 2 - keep, 3 - bottom tower, 4 - bottom wall, 5 - below gate, 6 - over gate, 7 - upper wall, 8 - uppert tower, 9 - gate, 10 - gate arch, 11 - bottom static wall, 12 - upper static wall, 13 - moat, 14 - mlip, 15 - keep creature cover, 16 - bottom turret creature cover, 17 - upper turret creature cover; additInfo: 1 - intact, 2 - damaged, 3 - destroyed
void printPartOfWall(SDL_Surface * to, int what);//what: 1 - background wall, 2 - keep, 3 - bottom tower, 4 - bottom wall, 5 - below gate, 6 - over gate, 7 - upper wall, 8 - uppert tower, 9 - gate, 10 - gate arch, 11 - bottom static wall, 12 - upper static wall, 15 - keep creature cover, 16 - bottom turret creature cover, 17 - upper turret creature cover
friend class CBattleInterface;
} * siegeH;
CPlayerInterface * attackerInt, * defenderInt; //because LOCPLINT is not enough in hotSeat
const CGHeroInstance * getActiveHero(); //returns hero that can currently cast a spell
public:
CPlayerInterface * curInt; //current player interface
std::list<std::pair<CBattleAnimation *, bool> > pendingAnims; //currently displayed animations <anim, initialized>
void addNewAnim(CBattleAnimation * anim); //adds new anim to pendingAnims
unsigned int animIDhelper; //for giving IDs for animations
static CondSh<bool> animsAreDisplayed; //for waiting with the end of battle for end of anims
CBattleInterface(const CCreatureSet * army1, const CCreatureSet * army2, CGHeroInstance *hero1, CGHeroInstance *hero2, const SDL_Rect & myRect, CPlayerInterface * att, CPlayerInterface * defen); //c-tor
~CBattleInterface(); //d-tor
//std::vector<TimeInterested*> timeinterested; //animation handling
void setPrintCellBorders(bool set); //if true, cell borders will be printed
void setPrintStackRange(bool set); //if true,range of active stack will be printed
void setPrintMouseShadow(bool set); //if true, hex under mouse will be shaded
void setAnimSpeed(int set); //speed of animation; 1 - slowest, 2 - medium, 4 - fastest
int getAnimSpeed() const; //speed of animation; 1 - slowest, 2 - medium, 4 - fastest
CBattleHex bfield[BFIELD_SIZE]; //11 lines, 17 hexes on each
//std::vector< CBattleObstacle * > obstacles; //vector of obstacles on the battlefield
SDL_Surface * cellBorder, * cellShade;
CondSh<BattleAction *> *givenCommand; //data != NULL if we have i.e. moved current unit
bool myTurn; //if true, interface is active (commands can be ordered)
CBattleResultWindow * resWindow; //window of end of battle
bool moveStarted; //if true, the creature that is already moving is going to make its first step
int moveSh; // sound handler used when moving a unit
//button handle funcs:
void bOptionsf();
void bSurrenderf();
void bFleef();
void reallyFlee(); //performs fleeing without asking player
void reallySurrender(); //performs surrendering without asking player
void bAutofightf();
void bSpellf();
void bWaitf();
void bDefencef();
void bConsoleUpf();
void bConsoleDownf();
void bTacticNextStack();
void bEndTacticPhase();
//end of button handle funcs
//napisz tu klase odpowiadajaca za wyswietlanie bitwy i obsluge uzytkownika, polecenia ma przekazywac callbackiem
void activate();
void deactivate();
void show(SDL_Surface * to);
void keyPressed(const SDL_KeyboardEvent & key);
void mouseMoved(const SDL_MouseMotionEvent &sEvent);
void clickRight(tribool down, bool previousState);
//call-ins
void startAction(const BattleAction* action);
void newStack(const CStack * stack); //new stack appeared on battlefield
void stackRemoved(int stackID); //stack disappeared from batlefiled
void stackActivated(const CStack * stack); //active stack has been changed
void stackMoved(const CStack * stack, std::vector<THex> destHex, int distance); //stack with id number moved to destHex
void waitForAnims();
void stacksAreAttacked(std::vector<SStackAttackedInfo> attackedInfos); //called when a certain amount of stacks has been attacked
void stackAttacking(const CStack * attacker, THex dest, const CStack * attacked, bool shooting); //called when stack with id ID is attacking something on hex dest
void newRoundFirst( int round );
void newRound(int number); //caled when round is ended; number is the number of round
void hexLclicked(int whichOne); //hex only call-in
void stackIsCatapulting(const CatapultAttack & ca); //called when a stack is attacking walls
void battleFinished(const BattleResult& br); //called when battle is finished - battleresult window should be printed
const BattleResult * bresult; //result of a battle; if non-zero then display when all animations end
void displayBattleFinished(); //displays battle result
void spellCast(const BattleSpellCast * sc); //called when a hero casts a spell
void battleStacksEffectsSet(const SetStackEffect & sse); //called when a specific effect is set to stacks
void castThisSpell(int spellID); //called when player has chosen a spell from spellbook
void displayEffect(ui32 effect, int destTile); //displays effect of a spell on the battlefield; affected: true - attacker. false - defender
void battleTriggerEffect(const BattleTriggerEffect & bte);
void setBattleCursor(const int myNumber); //really complex and messy
void endAction(const BattleAction* action);
void hideQueue();
void showQueue();
friend class CBattleHex;
friend class CBattleResultWindow;
friend class CPlayerInterface;
friend class AdventureMapButton;
friend class CInGameConsole;
friend class CReverseAnim;
friend class CBattleStackAnimation;
friend class CBattleAnimation;
friend class CDefenceAnim;
friend class CBattleStackMoved;
friend class CBattleMoveStart;
friend class CBattleMoveEnd;
friend class CBattleAttack;
friend class CMeleeAttack;
friend class CShootingAnim;
friend class CSpellEffectAnim;
friend class CBattleHero;
};
#endif // __CBATTLEINTERFACE_H__

2
client/StdInc.cpp Normal file
View File

@ -0,0 +1,2 @@
// Creates the precompiled header
#include "StdInc.h"

325
client/StdInc.h Normal file
View File

@ -0,0 +1,325 @@
#pragma once
// Standard include file
// Should be treated as a precompiled header file in the compiler settings
// We generate a .PCH file for every project due to simplicity and some annoying bugs in VisualStudio
// This file shouldn't be changed, except if there is a important header file which is missing.
/*
* StdInc.h, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#include <cstdio>
#include <stdio.h>
#ifdef _WIN32
#include <tchar.h>
#else
#include "../tchar_amigaos4.h"
#endif
#include <cmath>
#include <cassert>
#include <assert.h>
#include <vector>
#include <string>
#include <map>
#include <queue>
#include <set>
#include <utility>
#include <numeric>
#include <iostream>
#include <fstream>
#include <sstream>
#include <iomanip>
#include <algorithm>
#include <memory>
#include <cstdlib>
//filesystem version 3 causes problems (and it's default as of boost 1.46)
#define BOOST_FILESYSTEM_VERSION 2
#include <boost/algorithm/string.hpp>
#include <boost/assert.hpp>
#include <boost/assign.hpp>
#include <boost/bind.hpp>
#include <boost/cstdint.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/filesystem.hpp>
#include <boost/foreach.hpp>
#include <boost/format.hpp>
#include <boost/function.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/logic/tribool.hpp>
#include <boost/program_options.hpp>
#include <boost/thread.hpp>
#include <boost/unordered_set.hpp>
#ifdef ANDROID
#include <android/log.h>
#endif
// Integral data types
typedef boost::uint64_t ui64; //unsigned int 64 bits (8 bytes)
typedef boost::uint32_t ui32; //unsigned int 32 bits (4 bytes)
typedef boost::uint16_t ui16; //unsigned int 16 bits (2 bytes)
typedef boost::uint8_t ui8; //unsigned int 8 bits (1 byte)
typedef boost::int64_t si64; //signed int 64 bits (8 bytes)
typedef boost::int32_t si32; //signed int 32 bits (4 bytes)
typedef boost::int16_t si16; //signed int 16 bits (2 bytes)
typedef boost::int8_t si8; //signed int 8 bits (1 byte)
// Import + Export macro declarations
#ifdef _WIN32
#define DLL_EXPORT __declspec(dllexport)
#else
#if defined(__GNUC__) && __GNUC__ >= 4
#define DLL_EXPORT __attribute__ ((visibility("default")))
#else
#define DLL_EXPORT
#endif
#endif
#ifdef _WIN32
#define DLL_IMPORT __declspec(dllimport)
#else
#if defined(__GNUC__) && __GNUC__ >= 4
#define DLL_IMPORT __attribute__ ((visibility("default")))
#else
#define DLL_IMPORT
#endif
#endif
#ifdef VCMI_DLL
#define DLL_LINKAGE DLL_EXPORT
#else
#define DLL_LINKAGE DLL_IMPORT
#endif
//a normal std::map with a const operator[] for sanity
template<typename KeyT, typename ValT>
class bmap : public std::map<KeyT, ValT>
{
public:
const ValT & operator[](KeyT key) const
{
return find(key)->second;
}
ValT & operator[](KeyT key)
{
return static_cast<std::map<KeyT, ValT> &>(*this)[key];
}
template <typename Handler> void serialize(Handler &h, const int version)
{
h & static_cast<std::map<KeyT, ValT> &>(*this);
}
};
namespace vstd
{
//returns true if container c contains item i
template <typename Container, typename Item>
bool contains(const Container & c, const Item &i)
{
return std::find(c.begin(),c.end(),i) != c.end();
}
//returns true if map c contains item i
template <typename V, typename Item, typename Item2>
bool contains(const std::map<Item,V> & c, const Item2 &i)
{
return c.find(i)!=c.end();
}
//returns true if bmap c contains item i
template <typename V, typename Item, typename Item2>
bool contains(const bmap<Item,V> & c, const Item2 &i)
{
return c.find(i)!=c.end();
}
//returns true if unordered set c contains item i
template <typename Item>
bool contains(const boost::unordered_set<Item> & c, const Item &i)
{
return c.find(i)!=c.end();
}
//returns position of first element in vector c equal to s, if there is no such element, -1 is returned
template <typename T1, typename T2>
int find_pos(const std::vector<T1> & c, const T2 &s)
{
for(size_t i=0; i < c.size(); ++i)
if(c[i] == s)
return i;
return -1;
}
//Func(T1,T2) must say if these elements matches
template <typename T1, typename T2, typename Func>
int find_pos(const std::vector<T1> & c, const T2 &s, const Func &f)
{
for(size_t i=0; i < c.size(); ++i)
if(f(c[i],s))
return i;
return -1;
}
//returns iterator to the given element if present in container, end() if not
template <typename Container, typename Item>
typename Container::iterator find(Container & c, const Item &i)
{
return std::find(c.begin(),c.end(),i);
}
//returns const iterator to the given element if present in container, end() if not
template <typename Container, typename Item>
typename Container::const_iterator find(const Container & c, const Item &i)
{
return std::find(c.begin(),c.end(),i);
}
//removes element i from container c, returns false if c does not contain i
template <typename Container, typename Item>
typename Container::size_type operator-=(Container &c, const Item &i)
{
typename Container::iterator itr = find(c,i);
if(itr == c.end())
return false;
c.erase(itr);
return true;
}
//assigns greater of (a, b) to a and returns maximum of (a, b)
template <typename t1, typename t2>
t1 &amax(t1 &a, const t2 &b)
{
if(a >= b)
return a;
else
{
a = b;
return a;
}
}
//assigns smaller of (a, b) to a and returns minimum of (a, b)
template <typename t1, typename t2>
t1 &amin(t1 &a, const t2 &b)
{
if(a <= b)
return a;
else
{
a = b;
return a;
}
}
//makes a to fit the range <b, c>
template <typename t1, typename t2, typename t3>
t1 &abetween(t1 &a, const t2 &b, const t3 &c)
{
amax(a,b);
amin(a,c);
return a;
}
//checks if a is between b and c
template <typename t1, typename t2, typename t3>
bool isbetween(const t1 &a, const t2 &b, const t3 &c)
{
return a > b && a < c;
}
//checks if a is within b and c
template <typename t1, typename t2, typename t3>
bool iswithin(const t1 &a, const t2 &b, const t3 &c)
{
return a >= b && a <= c;
}
template <typename t1, typename t2>
struct assigner
{
public:
t1 &op1;
t2 op2;
assigner(t1 &a1, const t2 & a2)
:op1(a1), op2(a2)
{}
void operator()()
{
op1 = op2;
}
};
// Assigns value a2 to a1. The point of time of the real operation can be controlled
// with the () operator.
template <typename t1, typename t2>
assigner<t1,t2> assigno(t1 &a1, const t2 &a2)
{
return assigner<t1,t2>(a1,a2);
}
//deleted pointer and sets it to NULL
template <typename T>
void clear_pointer(T* &ptr)
{
delete ptr;
ptr = NULL;
}
}
using vstd::operator-=;
// can be used for counting arrays
template<typename T, size_t N> char (&_ArrayCountObj(const T (&)[N]))[N];
#define ARRAY_COUNT(arr) (sizeof(_ArrayCountObj(arr)))
//for explicit overrides
#ifdef _MSC_VER
#define OVERRIDE override
#else
#define OVERRIDE //is there any working counterpart?
#endif
//XXX pls dont - 'debug macros' are usually more trouble than it's worth
#define HANDLE_EXCEPTION \
catch (const std::exception& e) { \
tlog1 << e.what() << std::endl; \
throw; \
} \
catch (const std::exception * e) \
{ \
tlog1 << e->what()<< std::endl; \
throw; \
} \
catch (const std::string& e) { \
tlog1 << e << std::endl; \
throw; \
}
#define HANDLE_EXCEPTIONC(COMMAND) \
catch (const std::exception& e) { \
COMMAND; \
tlog1 << e.what() << std::endl; \
throw; \
} \
catch (const std::string &e) \
{ \
COMMAND; \
tlog1 << e << std::endl; \
throw; \
}
#include "../lib/CLogger.h"

734
global.h
View File

@ -1,734 +0,0 @@
#pragma once
#ifndef __GLOBAL_H__
#define __GLOBAL_H__
#include <iostream>
#include <sstream>
#include <algorithm> //std::find
#include <string> //std::find
#include <boost/logic/tribool.hpp>
#include <boost/unordered_set.hpp>
using boost::logic::tribool;
#include <boost/cstdint.hpp>
#include <assert.h>
#ifdef ANDROID
#include <android/log.h>
#include <sstream>
#endif
//filesystem version 3 causes problems (and it's default as of boost 1.46)
#define BOOST_FILESYSTEM_VERSION 2
typedef boost::uint64_t ui64; //unsigned int 64 bits (8 bytes)
typedef boost::uint32_t ui32; //unsigned int 32 bits (4 bytes)
typedef boost::uint16_t ui16; //unsigned int 16 bits (2 bytes)
typedef boost::uint8_t ui8; //unsigned int 8 bits (1 byte)
typedef boost::int64_t si64; //signed int 64 bits (8 bytes)
typedef boost::int32_t si32; //signed int 32 bits (4 bytes)
typedef boost::int16_t si16; //signed int 16 bits (2 bytes)
typedef boost::int8_t si8; //signed int 8 bits (1 byte)
typedef si64 expType;
typedef ui32 TSpell;
typedef std::pair<ui32, ui32> TDmgRange;
typedef ui8 TBonusType;
typedef si32 TBonusSubtype;
#include "int3.h"
#include <map>
#include <vector>
#define CHECKTIME 1
#if CHECKTIME
#include "timeHandler.h"
#define THC
#endif
#define NAME_VER ("VCMI 0.87b")
extern std::string NAME; //full name
extern std::string NAME_AFFIX; //client / server
#define CONSOLE_LOGGING_LEVEL 5
#define FILE_LOGGING_LEVEL 6
/*
* DATA_DIR contains the game data (Data/, MP3/, ...).
* BIN_DIR is where the vcmiclient/vcmiserver binaries reside
* LIB_DIR is where the AI libraries reside (linux only)
*/
#ifdef _WIN32
#define DATA_DIR "."
#define BIN_DIR "."
#define LIB_DIR "."
#define SERVER_NAME "VCMI_server.exe"
#define LIB_EXT "dll"
#else
#ifndef DATA_DIR
#error DATA_DIR undefined.
#endif
#ifndef BIN_DIR
#error BIN_DIR undefined.
#endif
#ifndef LIB_DIR
#error LIB_DIR undefined.
#endif
#define SERVER_NAME "vcmiserver"
#define LIB_EXT "so"
#endif
#ifdef _WIN32
#define PATH_SEPARATOR "\\"
#else
#define PATH_SEPARATOR "/"
#endif
/*
* global.h, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
enum Ecolor {RED, BLUE, TAN, GREEN, ORANGE, PURPLE, TEAL, PINK}; //player's colors
enum EvictoryConditions {artifact, gatherTroop, gatherResource, buildCity, buildGrail, beatHero,
captureCity, beatMonster, takeDwellings, takeMines, transportItem, winStandard=255};
enum ElossCon {lossCastle, lossHero, timeExpires, lossStandard=255};
enum ECombatInfo{ALIVE = 180, SUMMONED, CLONED, HAD_MORALE, WAITING, MOVED, DEFENDING, FEAR};
class CGameInfo;
extern const CGameInfo* CGI; //game info for general use
class CClientState;
extern CClientState * CCS;
//a few typedefs for CCreatureSet
typedef si32 TSlot;
typedef si32 TQuantity;
typedef ui32 TCreature; //creature id
const int ARMY_SIZE = 7;
const int
BOATI_TYPE = 8,
HEROI_TYPE = 34,
TOWNI_TYPE = 98,
SUBTERRANEAN_GATE_TYPE = 103,
CREI_TYPE = 54,
EVENTI_TYPE = 26;
const int CREATURES_COUNT = 197;
const int CRE_LEVELS = 10;
const int F_NUMBER = 9; //factions (town types) quantity
const int PLAYER_LIMIT = 8; //player limit per map
const int ALL_PLAYERS = 255; //bitfield
const int HEROES_PER_TYPE=8; //amount of heroes of each type
const int SKILL_QUANTITY=28;
const int SKILL_PER_HERO=8;
const int ARTIFACTS_QUANTITY=171;
const int HEROES_QUANTITY=156;
const int SPELLS_QUANTITY=70;
const int RESOURCE_QUANTITY=8;
const int TERRAIN_TYPES=10;
const int PRIMARY_SKILLS=4;
const int NEUTRAL_PLAYER=255;
const int NAMES_PER_TOWN=16;
const int CREATURES_PER_TOWN = 7; //without upgrades
const int MAX_BUILDING_PER_TURN = 1;
const int SPELL_LEVELS = 5;
const int CREEP_SIZE = 4000; // neutral stacks won't grow beyond this number
//const int CREEP_SIZE = 2000000000;
const int WEEKLY_GROWTH = 10; //percent
const int AVAILABLE_HEROES_PER_PLAYER = 2;
const bool DWELLINGS_ACCUMULATE_CREATURES = false;
const bool STACK_EXP = true;
const bool STACK_ARTIFACT = true;
const int BFIELD_WIDTH = 17;
const int BFIELD_HEIGHT = 11;
const int BFIELD_SIZE = BFIELD_WIDTH * BFIELD_HEIGHT;
const int SPELLBOOK_GOLD_COST = 500;
//for battle stacks' positions
struct THex
{
static const si16 INVALID = -1;
enum EDir{RIGHT, BOTTOM_RIGHT, BOTTOM_LEFT, LEFT, TOP_LEFT, TOP_RIGHT};
si16 hex;
THex() : hex(INVALID) {}
THex(si16 _hex) : hex(_hex)
{
//assert(isValid());
}
operator si16() const
{
return hex;
}
bool isValid() const
{
return hex >= 0 && hex < BFIELD_SIZE;
}
template<typename inttype>
THex(inttype x, inttype y)
{
setXY(x, y);
}
template<typename inttype>
THex(std::pair<inttype, inttype> xy)
{
setXY(xy);
}
template<typename inttype>
void setX(inttype x)
{
setXY(x, getY());
}
template<typename inttype>
void setY(inttype y)
{
setXY(getX(), y);
}
void setXY(si16 x, si16 y)
{
assert(x >= 0 && x < BFIELD_WIDTH && y >= 0 && y < BFIELD_HEIGHT);
hex = x + y * BFIELD_WIDTH;
}
template<typename inttype>
void setXY(std::pair<inttype, inttype> xy)
{
setXY(xy.first, xy.second);
}
si16 getY() const
{
return hex/BFIELD_WIDTH;
}
si16 getX() const
{
int pos = hex - getY() * BFIELD_WIDTH;
return pos;
}
std::pair<si16, si16> getXY() const
{
return std::make_pair(getX(), getY());
}
//moving to direction
void operator+=(EDir dir)
{
si16 x = getX(),
y = getY();
switch(dir)
{
case TOP_LEFT:
setXY(y%2 ? x-1 : x, y-1);
break;
case TOP_RIGHT:
setXY(y%2 ? x : x+1, y-1);
break;
case RIGHT:
setXY(x+1, y);
break;
case BOTTOM_RIGHT:
setXY(y%2 ? x : x+1, y+1);
break;
case BOTTOM_LEFT:
setXY(y%2 ? x-1 : x, y+1);
break;
case LEFT:
setXY(x-1, y);
break;
default:
throw std::string("Disaster: wrong direction in THex::operator+=!\n");
break;
}
}
//generates new THex moved by given dir
THex operator+(EDir dir) const
{
THex ret(*this);
ret += dir;
return ret;
}
std::vector<THex> neighbouringTiles() const
{
std::vector<THex> ret;
const int WN = BFIELD_WIDTH;
checkAndPush(hex - ( (hex/WN)%2 ? WN+1 : WN ), ret);
checkAndPush(hex - ( (hex/WN)%2 ? WN : WN-1 ), ret);
checkAndPush(hex - 1, ret);
checkAndPush(hex + 1, ret);
checkAndPush(hex + ( (hex/WN)%2 ? WN-1 : WN ), ret);
checkAndPush(hex + ( (hex/WN)%2 ? WN : WN+1 ), ret);
return ret;
}
//returns info about mutual position of given hexes (-1 - they're distant, 0 - left top, 1 - right top, 2 - right, 3 - right bottom, 4 - left bottom, 5 - left)
static signed char mutualPosition(THex hex1, THex hex2)
{
if(hex2 == hex1 - ( (hex1/17)%2 ? 18 : 17 )) //top left
return 0;
if(hex2 == hex1 - ( (hex1/17)%2 ? 17 : 16 )) //top right
return 1;
if(hex2 == hex1 - 1 && hex1%17 != 0) //left
return 5;
if(hex2 == hex1 + 1 && hex1%17 != 16) //right
return 2;
if(hex2 == hex1 + ( (hex1/17)%2 ? 16 : 17 )) //bottom left
return 4;
if(hex2 == hex1 + ( (hex1/17)%2 ? 17 : 18 )) //bottom right
return 3;
return -1;
}
//returns distance between given hexes
static si8 getDistance(THex hex1, THex hex2)
{
int xDst = std::abs(hex1 % BFIELD_WIDTH - hex2 % BFIELD_WIDTH),
yDst = std::abs(hex1 / BFIELD_WIDTH - hex2 / BFIELD_WIDTH);
return std::max(xDst, yDst) + std::min(xDst, yDst) - (yDst + 1)/2;
}
template <typename Handler> void serialize(Handler &h, const int version)
{
h & hex;
}
static void checkAndPush(int tile, std::vector<THex> & ret)
{
if( tile>=0 && tile<BFIELD_SIZE && (tile%BFIELD_WIDTH != (BFIELD_WIDTH - 1)) && (tile%BFIELD_WIDTH != 0) )
ret.push_back(THex(tile));
}
};
enum EMarketMode
{
RESOURCE_RESOURCE, RESOURCE_PLAYER, CREATURE_RESOURCE, RESOURCE_ARTIFACT,
ARTIFACT_RESOURCE, ARTIFACT_EXP, CREATURE_EXP, CREATURE_UNDEAD, RESOURCE_SKILL,
MARTKET_AFTER_LAST_PLACEHOLDER
};
namespace SpellCasting
{
enum ESpellCastProblem
{
OK, NO_HERO_TO_CAST_SPELL, ALREADY_CASTED_THIS_TURN, NO_SPELLBOOK, ANOTHER_ELEMENTAL_SUMMONED,
HERO_DOESNT_KNOW_SPELL, NOT_ENOUGH_MANA, ADVMAP_SPELL_INSTEAD_OF_BATTLE_SPELL,
SECOND_HEROS_SPELL_IMMUNITY, SPELL_LEVEL_LIMIT_EXCEEDED, NO_SPELLS_TO_DISPEL,
NO_APPROPRIATE_TARGET, STACK_IMMUNE_TO_SPELL, WRONG_SPELL_TARGET
};
enum ECastingMode {HERO_CASTING, AFTER_ATTACK_CASTING, //also includes cast before attack
MAGIC_MIRROR, CREATURE_ACTIVE_CASTING, ENCHANTER_CASTING};
}
namespace Buildings
{
enum EBuildStructure
{
HAVE_CAPITAL, NO_WATER, FORBIDDEN, ADD_MAGES_GUILD, ALREADY_PRESENT, CANT_BUILD_TODAY,
NO_RESOURCES, ALLOWED, PREREQUIRES, ERROR
};
//Quite useful as long as most of building mechanics hardcoded
enum EBuilding
{
MAGES_GUILD_1, MAGES_GUILD_2, MAGES_GUILD_3, MAGES_GUILD_4, MAGES_GUILD_5,
TAVERN, SHIPYARD, FORT, CITADEL, CASTLE,
VILLAGE_HALL, TOWN_HALL, CITY_HALL, CAPITOL, MARKETPLACE,
RESOURCE_SILO, BLACKSMITH, SPECIAL_1, HORDE_1, HORDE_1_UPGR,
SHIP, SPECIAL_2, SPECIAL_3, SPECIAL_4, HORDE_2,
HORDE_2_UPGR, GRAIL, EXTRA_CITY_HALL, EXTRA_TOWN_HALL, EXTRA_CAPITOL,
DWELL_FIRST=30, DWELL_LAST=36, DWELL_UP_FIRST=37, DWELL_UP_LAST=43
};
}
namespace Arts
{
enum EPos
{
PRE_FIRST = -1,
HEAD, SHOULDERS, NECK, RIGHT_HAND, LEFT_HAND, TORSO, RIGHT_RING, LEFT_RING, FEET, MISC1, MISC2, MISC3, MISC4,
MACH1, MACH2, MACH3, MACH4, SPELLBOOK, MISC5,
AFTER_LAST
};
const ui16 BACKPACK_START = 19;
const int ID_CATAPULT = 3, ID_LOCK = 145;
const ui16 CREATURE_ART = 0;
}
enum EAlignment
{
GOOD, EVIL, NEUTRAL
};
//uncomment to make it work
//#define MARK_BLOCKED_POSITIONS
//#define MARK_VISITABLE_POSITIONS
#define DEFBYPASS
#ifdef _WIN32
#define DLL_F_EXPORT __declspec(dllexport)
#else
#if defined(__GNUC__) && __GNUC__ >= 4
#define DLL_F_EXPORT __attribute__ ((visibility("default")))
#else
#define DLL_F_EXPORT
#endif
#endif
#ifdef _WIN32
#define DLL_F_IMPORT __declspec(dllimport)
#else
#if defined(__GNUC__) && __GNUC__ >= 4
#define DLL_F_IMPORT __attribute__ ((visibility("default")))
#else
#define DLL_F_IMPORT
#endif
#endif
#ifdef VCMI_DLL
#define DLL_EXPORT DLL_F_EXPORT
#else
#define DLL_EXPORT DLL_F_IMPORT
#endif
template<typename T, size_t N> char (&_ArrayCountObj(const T (&)[N]))[N];
#define ARRAY_COUNT(arr) (sizeof(_ArrayCountObj(arr)))
//a normal std::map with consted operator[] for sanity
template<typename KeyT, typename ValT>
class bmap : public std::map<KeyT, ValT>
{
public:
const ValT & operator[](KeyT key) const
{
return find(key)->second;
}
ValT & operator[](KeyT key)
{
return static_cast<std::map<KeyT, ValT> &>(*this)[key];
}
template <typename Handler> void serialize(Handler &h, const int version)
{
h & static_cast<std::map<KeyT, ValT> &>(*this);
}
};
namespace vstd
{
template <typename Container, typename Item>
bool contains(const Container & c, const Item &i) //returns true if container c contains item i
{
return std::find(c.begin(),c.end(),i) != c.end();
}
template <typename V, typename Item, typename Item2>
bool contains(const std::map<Item,V> & c, const Item2 &i) //returns true if map c contains item i
{
return c.find(i)!=c.end();
}
template <typename V, typename Item, typename Item2>
bool contains(const bmap<Item,V> & c, const Item2 &i) //returns true if bmap c contains item i
{
return c.find(i)!=c.end();
}
template <typename Item>
bool contains(const boost::unordered_set<Item> & c, const Item &i) //returns true if unordered set c contains item i
{
return c.find(i)!=c.end();
}
template <typename Item, size_t N>
bool contains(const Item (&c)[N], const Item &i) //returns true if given array contains item i
{
return std::find(c, c+N, i) != c+N; //TODO: find out why template is not resolved
}
template <typename Container1, typename Container2>
typename Container2::iterator findFirstNot(Container1 &c1, Container2 &c2)//returns first element of c2 not present in c1
{
typename Container2::iterator itr = c2.begin();
while(itr != c2.end())
if(!contains(c1,*itr))
return itr;
else
++itr;
return c2.end();
}
template <typename Container1, typename Container2>
typename Container2::const_iterator findFirstNot(const Container1 &c1, const Container2 &c2)//returns const first element of c2 not present in c1
{
typename Container2::const_iterator itr = c2.begin();
while(itr != c2.end())
if(!contains(c1,*itr))
return itr;
else
++itr;
return c2.end();
}
template <typename Container, typename Item>
typename Container::iterator find(const Container & c, const Item &i)
{
return std::find(c.begin(),c.end(),i);
}
template <typename T1, typename T2>
int findPos(const std::vector<T1> & c, const T2 &s) //returns position of first element in vector c equal to s, if there is no such element, -1 is returned
{
for(size_t i=0; i < c.size(); ++i)
if(c[i] == s)
return i;
return -1;
}
template <typename T1, typename T2, typename Func>
int findPos(const std::vector<T1> & c, const T2 &s, const Func &f) //Func(T1,T2) must say if these elements matches
{
for(size_t i=0; i < c.size(); ++i)
if(f(c[i],s))
return i;
return -1;
}
template <typename Container, typename Item>
typename Container::iterator find(Container & c, const Item &i) //returns iterator to the given element if present in container, end() if not
{
return std::find(c.begin(),c.end(),i);
}
template <typename Container, typename Item>
typename Container::const_iterator find(const Container & c, const Item &i)//returns const iterator to the given element if present in container, end() if not
{
return std::find(c.begin(),c.end(),i);
}
template <typename Container, typename Item>
typename Container::size_type operator-=(Container &c, const Item &i) //removes element i from container c, returns false if c does not contain i
{
typename Container::iterator itr = find(c,i);
if(itr == c.end())
return false;
c.erase(itr);
return true;
}
template <typename t1>
void delObj(t1 *a1)
{
delete a1;
}
template <typename t1, typename t2>
void assign(t1 &a1, const t2 &a2)
{
a1 = a2;
}
template <typename t1, typename t2>
struct assigner
{
public:
t1 &op1;
t2 op2;
assigner(t1 &a1, const t2 & a2)
:op1(a1), op2(a2)
{}
void operator()()
{
op1 = op2;
}
};
template <typename t1, typename t2>
assigner<t1,t2> assigno(t1 &a1, const t2 &a2)
{
return assigner<t1,t2>(a1,a2);
}
template <typename t1, typename t2, typename t3>
bool equal(const t1 &a1, const t3 t1::* point, const t2 &a2)
{
return a1.*point == a2;
}
template <typename t1, typename t2>
bool equal(const t1 &a1, const t2 &a2)
{
return a1 == a2;
}
}
using vstd::operator-=;
template <typename t1, typename t2>
t1 & amax(t1 &a, const t2 &b) //assigns greater of (a, b) to a and returns maximum of (a, b)
{
if(a >= b)
return a;
else
{
a = b;
return a;
}
}
template <typename t1, typename t2>
t1 & amin(t1 &a, const t2 &b) //assigns smaller of (a, b) to a and returns minimum of (a, b)
{
if(a <= b)
return a;
else
{
a = b;
return a;
}
}
template <typename t1, typename t2, typename t3>
t1 & abetw(t1 &a, const t2 &b, const t3 &c) //makes a to fit the range <b, c>
{
amax(a,b);
amin(a,c);
return a;
}
template <typename t1, typename t2, typename t3>
bool isbetw(const t1 &a, const t2 &b, const t3 &c) //checks if a is between b and c
{
return a > b && a < c;
}
template <typename t1, typename t2, typename t3>
bool iswith(const t1 &a, const t2 &b, const t3 &c) //checks if a is within b and c
{
return a >= b && a <= c;
}
template <typename T>
void delNull(T* &ptr) //deleted pointer and sets it to NULL
{
delete ptr;
ptr = NULL;
}
#include "CConsoleHandler.h"
extern DLL_EXPORT std::ostream *logfile;
extern DLL_EXPORT CConsoleHandler *console;
class CLogger //logger, prints log info to console and saves in file
{
const int lvl;
#ifdef ANDROID
std::ostringstream buf;
int androidloglevel;
void outputAndroid()
{
int pos = buf.str().find("\n");
while( pos >= 0 )
{
__android_log_print(androidloglevel, "VCMI", "%s", buf.str().substr(0, pos).c_str() );
buf.str( buf.str().substr(pos+1) );
pos = buf.str().find("\n");
}
}
#endif
public:
CLogger& operator<<(std::ostream& (*fun)(std::ostream&))
{
#ifdef ANDROID
buf << fun;
outputAndroid();
#else
if(lvl < CONSOLE_LOGGING_LEVEL)
std::cout << fun;
if((lvl < FILE_LOGGING_LEVEL) && logfile)
*logfile << fun;
#endif
return *this;
}
template<typename T>
CLogger & operator<<(const T & data)
{
#ifdef ANDROID
buf << data;
outputAndroid();
#else
if(lvl < CONSOLE_LOGGING_LEVEL)
{
if(console)
console->print(data,lvl);
else
std::cout << data << std::flush;
}
if((lvl < FILE_LOGGING_LEVEL) && logfile)
*logfile << data << std::flush;
#endif
return *this;
}
CLogger(const int Lvl) : lvl(Lvl)
{
#ifdef ANDROID
androidloglevel = ANDROID_LOG_INFO;
switch(lvl) {
case 0: androidloglevel = ANDROID_LOG_INFO; break;
case 1: androidloglevel = ANDROID_LOG_FATAL; break;
case 2: androidloglevel = ANDROID_LOG_ERROR; break;
case 3: androidloglevel = ANDROID_LOG_WARN; break;
case 4: androidloglevel = ANDROID_LOG_INFO; break;
case 5: androidloglevel = ANDROID_LOG_DEBUG; break;
case 6: case -2: androidloglevel = ANDROID_LOG_VERBOSE; break;
}
#endif
}
};
extern DLL_EXPORT CLogger tlog0; //green - standard progress info
extern DLL_EXPORT CLogger tlog1; //red - big errors
extern DLL_EXPORT CLogger tlog2; //magenta - major warnings
extern DLL_EXPORT CLogger tlog3; //yellow - minor warnings
extern DLL_EXPORT CLogger tlog4; //white - detailed log info
extern DLL_EXPORT CLogger tlog5; //gray - minor log info
extern DLL_EXPORT CLogger tlog6; //teal - AI info
//XXX pls dont - 'debug macros' are usually more trouble than it's worth
#define HANDLE_EXCEPTION \
catch (const std::exception& e) { \
tlog1 << e.what() << std::endl; \
throw; \
} \
catch (const std::exception * e) \
{ \
tlog1 << e->what()<< std::endl; \
throw; \
} \
catch (const std::string& e) { \
tlog1 << e << std::endl; \
throw; \
}
#define HANDLE_EXCEPTIONC(COMMAND) \
catch (const std::exception& e) { \
COMMAND; \
tlog1 << e.what() << std::endl; \
throw; \
} \
catch (const std::string &e) \
{ \
COMMAND; \
tlog1 << e << std::endl; \
throw; \
}
//for explicit overrides
#ifdef _MSC_VER
#define OVERRIDE override
#else
#define OVERRIDE //is there any working counterpart?
#endif
#define BONUS_TREE_DESERIALIZATION_FIX if(!h.saving && h.smartPointerSerialization) deserializationFix();
#endif // __GLOBAL_H__

View File

@ -1,9 +1,6 @@
#ifndef __AI_BASE_H__
#define __AI_BASE_H__
#pragma once
#include <vector>
#include <iostream>
#include "lib/CGameInterface.h"
#include "CGameInterface.h"
/*
* AI_Base.h, part of VCMI engine
@ -16,5 +13,3 @@
*/
#define AI_INTERFACE_VER 1
#endif // __AI_BASE_H__

View File

@ -1,9 +1,6 @@
#define VCMI_DLL
#include "stdafx.h"
#include "StdInc.h"
#include "CConsoleHandler.h"
#include <boost/function.hpp>
#include <boost/thread.hpp>
#include <iomanip>
#include "CThreadHelper.h"
/*

View File

@ -1,5 +1,4 @@
#ifndef __CCONSOLEHANDLER_H__
#define __CCONSOLEHANDLER_H__
#pragma once
/*
* CConsoleHandler.h, part of VCMI engine
@ -11,16 +10,10 @@
*
*/
namespace boost
{
template<typename signature>
class function;
class thread;
}
/// Class which wraps the native console. It can print text based on
/// the chosen color
class DLL_EXPORT CConsoleHandler
class DLL_LINKAGE CConsoleHandler
{
public:
boost::function<void(const std::string &)> *cb; //function to be called when message is received
@ -35,13 +28,10 @@ public:
void start(); //starts listening thread
void end(); //kills listening thread
template<typename T> void print(const T &data, int level)
template<typename T> void print(const T &data, int lvl)
{
setColor(level);
setColor(lvl);
std::cout << data << std::flush;
setColor(-1);
}
};
#endif // __CCONSOLEHANDLER_H__

62
lib/CLogger.cpp Normal file
View File

@ -0,0 +1,62 @@
#include "StdInc.h"
#include "CLogger.h"
// Console, file definitions
DLL_LINKAGE CConsoleHandler *console = NULL;
DLL_LINKAGE std::ostream *logfile = NULL;
// CLogger definitions
DLL_LINKAGE CLogger tlog0(0);
DLL_LINKAGE CLogger tlog1(1);
DLL_LINKAGE CLogger tlog2(2);
DLL_LINKAGE CLogger tlog3(3);
DLL_LINKAGE CLogger tlog4(4);
DLL_LINKAGE CLogger tlog5(5);
DLL_LINKAGE CLogger tlog6(-2);
// Logging level settings
const int CLogger::CONSOLE_LOGGING_LEVEL = 5;
const int CLogger::FILE_LOGGING_LEVEL = 6;
CLogger::CLogger(const int Lvl) : lvl(Lvl)
{
#ifdef ANDROID
androidloglevel = ANDROID_LOG_INFO;
switch(lvl) {
case 0: androidloglevel = ANDROID_LOG_INFO; break;
case 1: androidloglevel = ANDROID_LOG_FATAL; break;
case 2: androidloglevel = ANDROID_LOG_ERROR; break;
case 3: androidloglevel = ANDROID_LOG_WARN; break;
case 4: androidloglevel = ANDROID_LOG_INFO; break;
case 5: androidloglevel = ANDROID_LOG_DEBUG; break;
case 6: case -2: androidloglevel = ANDROID_LOG_VERBOSE; break;
}
#endif
}
#ifdef ANDROID
void CLogger::outputAndroid()
{
int pos = buf.str().find("\n");
while( pos >= 0 )
{
__android_log_print(androidloglevel, "VCMI", "%s", buf.str().substr(0, pos).c_str() );
buf.str( buf.str().substr(pos+1) );
pos = buf.str().find("\n");
}
}
#endif
CLogger& CLogger::operator<<(std::ostream& (*fun)(std::ostream&))
{
#ifdef ANDROID
buf << fun;
outputAndroid();
#else
if(lvl < CLogger::CONSOLE_LOGGING_LEVEL)
std::cout << fun;
if((lvl < CLogger::FILE_LOGGING_LEVEL) && logfile)
*logfile << fun;
#endif
return *this;
}

53
lib/CLogger.h Normal file
View File

@ -0,0 +1,53 @@
#pragma once
#include "CConsoleHandler.h"
extern DLL_LINKAGE std::ostream *logfile;
extern DLL_LINKAGE CConsoleHandler *console;
// CLogger, prints log info to console and saves in file
class DLL_LINKAGE CLogger
{
const int lvl;
#ifdef ANDROID
std::ostringstream buf;
int androidloglevel;
void outputAndroid();
#endif
public:
static const int CONSOLE_LOGGING_LEVEL;
static const int FILE_LOGGING_LEVEL;
CLogger& operator<<(std::ostream& (*fun)(std::ostream&));
template<typename T>
CLogger & operator<<(const T & data)
{
#ifdef ANDROID
buf << data;
outputAndroid();
#else
if(lvl < CLogger::CONSOLE_LOGGING_LEVEL)
{
if(console)
console->print(data, lvl);
else
std::cout << data << std::flush;
}
if((lvl < CLogger::FILE_LOGGING_LEVEL) && logfile)
*logfile << data << std::flush;
#endif
return *this;
}
CLogger(const int Lvl);
};
extern DLL_LINKAGE CLogger tlog0; //green - standard progress info
extern DLL_LINKAGE CLogger tlog1; //red - big errors
extern DLL_LINKAGE CLogger tlog2; //magenta - major warnings
extern DLL_LINKAGE CLogger tlog3; //yellow - minor warnings
extern DLL_LINKAGE CLogger tlog4; //white - detailed log info
extern DLL_LINKAGE CLogger tlog5; //gray - minor log info
extern DLL_LINKAGE CLogger tlog6; //teal - AI info

View File

@ -1,8 +1,6 @@
#define VCMI_DLL
#include "StdInc.h"
#include "CThreadHelper.h"
#include <boost/thread.hpp>
#include <boost/bind.hpp>
#ifdef _WIN32
#include <windows.h>
#endif

View File

@ -1,9 +1,6 @@
#ifndef __CTHREADHELPER_H__
#define __CTHREADHELPER_H__
#pragma once
#include "global.h"
#include <boost/function.hpp>
#include <boost/thread.hpp>
/*
@ -19,7 +16,7 @@
typedef boost::function<void()> Task;
/// Can assign CPU work to other threads/cores
class DLL_EXPORT CThreadHelper
class DLL_LINKAGE CThreadHelper
{
boost::mutex rtinm;
int currentTask, amount, threads;
@ -37,7 +34,7 @@ template <typename T> inline void setData(T * data, boost::function<T()> func)
*data = func();
}
void DLL_EXPORT setThreadName(long threadID, const std::string &name);
void DLL_LINKAGE setThreadName(long threadID, const std::string &name);
#define GET_DATA(TYPE,DESTINATION,FUNCTION_TO_GET) \
(boost::bind(&setData<TYPE>,&DESTINATION,FUNCTION_TO_GET))
@ -53,5 +50,3 @@ void DLL_EXPORT setThreadName(long threadID, const std::string &name);
(GET_DATA \
(CDefEssential*,DESTINATION,\
boost::function<CDefEssential*()>(boost::bind(CDefHandler::giveDefEss,DEF_NAME))))
#endif // __CTHREADHELPER_H__

176
lib/GameConstants.h Normal file
View File

@ -0,0 +1,176 @@
#pragma once
/*
* GameConstants.h, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
namespace GameConstants
{
const std::string VCMI_VERSION = "VCMI 0.86e";
/*
* DATA_DIR contains the game data (Data/, MP3/, ...).
* BIN_DIR is where the vcmiclient/vcmiserver binaries reside
* LIB_DIR is where the AI libraries reside (linux only)
*/
#ifdef _WIN32
const std::string DATA_DIR = ".";
const std::string BIN_DIR = ".";
const std::string LIB_DIR = ".";
const std::string SERVER_NAME = "VCMI_server.exe";
const std::string LIB_EXT = "dll";
const std::string PATH_SEPARATOR = "\\";
#else
#ifndef M_DATA_DIR
#error M_DATA_DIR undefined.
#else
const std::string DATA_DIR = M_DATA_DIR;
#endif
#ifndef M_BIN_DIR
#error M_BIN_DIR undefined.
#else
const std::string BIN_DIR = M_BIN_DIR;
#endif
#ifndef M_LIB_DIR
#error M_LIB_DIR undefined.
#else
const std::string LIB_DIR = M_LIB_DIR;
#endif
const std::string SERVER_NAME = "vcmiserver";
const std::string LIB_EXT = "so";
const std::string PATH_SEPARATOR = "/";
#endif
const int BFIELD_WIDTH = 17;
const int BFIELD_HEIGHT = 11;
const int BFIELD_SIZE = BFIELD_WIDTH * BFIELD_HEIGHT;
const int ARMY_SIZE = 7;
const int BOATI_TYPE = 8;
const int HEROI_TYPE = 34;
const int TOWNI_TYPE = 98;
const int SUBTERRANEAN_GATE_TYPE = 103;
const int CREI_TYPE = 54;
const int EVENTI_TYPE = 26;
const int CREATURES_COUNT = 197;
const int CRE_LEVELS = 10;
const int F_NUMBER = 9; //factions (town types) quantity
const int PLAYER_LIMIT = 8; //player limit per map
const int ALL_PLAYERS = 255; //bitfield
const int HEROES_PER_TYPE=8; //amount of heroes of each type
const int SKILL_QUANTITY=28;
const int SKILL_PER_HERO=8;
const int ARTIFACTS_QUANTITY=171;
const int HEROES_QUANTITY=156;
const int SPELLS_QUANTITY=70;
const int RESOURCE_QUANTITY=8;
const int TERRAIN_TYPES=10;
const int PRIMARY_SKILLS=4;
const int NEUTRAL_PLAYER=255;
const int NAMES_PER_TOWN=16;
const int CREATURES_PER_TOWN = 7; //without upgrades
const int MAX_BUILDING_PER_TURN = 1;
const int SPELL_LEVELS = 5;
const int CREEP_SIZE = 4000; // neutral stacks won't grow beyond this number
const int WEEKLY_GROWTH = 10; //percent
const int AVAILABLE_HEROES_PER_PLAYER = 2;
const bool DWELLINGS_ACCUMULATE_CREATURES = false;
const bool STACK_EXP = true;
const bool STACK_ARTIFACT = true;
const int SPELLBOOK_GOLD_COST = 500;
const ui16 BACKPACK_START = 19;
const int ID_CATAPULT = 3, ID_LOCK = 145;
const ui16 CREATURE_ART = 0;
}
// Enum declarations
namespace EVictoryConditionType
{
enum EVictoryConditionType { ARTIFACT, GATHERTROOP, GATHERRESOURCE, BUILDCITY, BUILDGRAIL, BEATHERO,
CAPTURECITY, BEATMONSTER, TAKEDWELLINGS, TAKEMINES, TRANSPORTITEM, WINSTANDARD = 255 };
}
namespace ELossConditionType
{
enum ELossConditionType { LOSSCASTLE, LOSSHERO, TIMEEXPIRES, LOSSSTANDARD = 255 };
}
namespace EAlignment
{
enum EAlignment { GOOD, EVIL, NEUTRAL };
}
namespace EBuilding
{
//Quite useful as long as most of building mechanics hardcoded
enum EBuilding
{
MAGES_GUILD_1, MAGES_GUILD_2, MAGES_GUILD_3, MAGES_GUILD_4, MAGES_GUILD_5,
TAVERN, SHIPYARD, FORT, CITADEL, CASTLE,
VILLAGE_HALL, TOWN_HALL, CITY_HALL, CAPITOL, MARKETPLACE,
RESOURCE_SILO, BLACKSMITH, SPECIAL_1, HORDE_1, HORDE_1_UPGR,
SHIP, SPECIAL_2, SPECIAL_3, SPECIAL_4, HORDE_2,
HORDE_2_UPGR, GRAIL, EXTRA_CITY_HALL, EXTRA_TOWN_HALL, EXTRA_CAPITOL,
DWELL_FIRST=30, DWELL_LAST=36, DWELL_UP_FIRST=37, DWELL_UP_LAST=43
};
}
namespace EBuildingState
{
enum EBuildingState
{
HAVE_CAPITAL, NO_WATER, FORBIDDEN, ADD_MAGES_GUILD, ALREADY_PRESENT, CANT_BUILD_TODAY,
NO_RESOURCES, ALLOWED, PREREQUIRES, BUILDING_ERROR
};
}
namespace ESpellCastProblem
{
enum ESpellCastProblem
{
OK, NO_HERO_TO_CAST_SPELL, ALREADY_CASTED_THIS_TURN, NO_SPELLBOOK, ANOTHER_ELEMENTAL_SUMMONED,
HERO_DOESNT_KNOW_SPELL, NOT_ENOUGH_MANA, ADVMAP_SPELL_INSTEAD_OF_BATTLE_SPELL,
SECOND_HEROS_SPELL_IMMUNITY, SPELL_LEVEL_LIMIT_EXCEEDED, NO_SPELLS_TO_DISPEL,
NO_APPROPRIATE_TARGET, STACK_IMMUNE_TO_SPELL, WRONG_SPELL_TARGET
};
}
namespace ECastingMode
{
enum ECastingMode {HERO_CASTING, AFTER_ATTACK_CASTING, //also includes cast before attack
MAGIC_MIRROR, CREATURE_ACTIVE_CASTING, ENCHANTER_CASTING};
}
namespace EMarketMode
{
enum EMarketMode
{
RESOURCE_RESOURCE, RESOURCE_PLAYER, CREATURE_RESOURCE, RESOURCE_ARTIFACT,
ARTIFACT_RESOURCE, ARTIFACT_EXP, CREATURE_EXP, CREATURE_UNDEAD, RESOURCE_SKILL,
MARTKET_AFTER_LAST_PLACEHOLDER
};
}
namespace EBattleStackState
{
enum EBattleStackState{ALIVE = 180, SUMMONED, CLONED, HAD_MORALE, WAITING, MOVED, DEFENDING, FEAR};
}
// Typedef declarations
typedef si64 expType;
typedef ui32 TSpell;
typedef std::pair<ui32, ui32> TDmgRange;
typedef ui8 TBonusType;
typedef si32 TBonusSubtype;
typedef si32 TSlot;
typedef si32 TQuantity;
typedef ui32 TCreature; //creature id

View File

@ -1,242 +0,0 @@
#include "Connection.h"
#include "NetPacks.h"
#include "VCMI_Lib.h"
#include "CArtHandler.h"
#include "CObjectHandler.h"
#include "CGameState.h"
#include "CHeroHandler.h"
#include "CTownHandler.h"
/*
* RegisterTypes.cpp, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
#ifndef VCMI_DLL
#undef DLL_EXPORT
#define DLL_EXPORT
#endif
#include "RegisterTypes.h"
template<typename Serializer> DLL_EXPORT
void registerTypes1(Serializer &s)
{
//map objects
s.template registerType<CGHeroPlaceholder>();
s.template registerType<CGHeroInstance>();
s.template registerType<CGTownInstance>();
s.template registerType<CTownBonus>();
s.template registerType<CGPandoraBox>();
s.template registerType<CGEvent>();
s.template registerType<CGDwelling>();
s.template registerType<CGVisitableOPH>();
s.template registerType<CGVisitableOPW>();
s.template registerType<CGTeleport>();
s.template registerType<CGPickable>();
s.template registerType<CGCreature>();
s.template registerType<CGSignBottle>();
s.template registerType<CGSeerHut>();
s.template registerType<CGQuestGuard>();
s.template registerType<CGWitchHut>();
s.template registerType<CGScholar>();
s.template registerType<CGGarrison>();
s.template registerType<CGArtifact>();
s.template registerType<CGResource>();
s.template registerType<CGMine>();
s.template registerType<CGShrine>();
s.template registerType<CGBonusingObject>();
s.template registerType<CGMagicSpring>();
s.template registerType<CGMagicWell>();
s.template registerType<CGObservatory>();
s.template registerType<CGKeys>();
s.template registerType<CGKeymasterTent>();
s.template registerType<CGBorderGuard>();
s.template registerType<CGBoat>();
s.template registerType<CGMagi>();
s.template registerType<CGSirens>();
s.template registerType<CGOnceVisitable>();
s.template registerType<CBank>();
s.template registerType<CGPyramid>();
s.template registerType<CGShipyard>();
s.template registerType<CCartographer>();
s.template registerType<CGObjectInstance>();
s.template registerType<COPWBonus>();
s.template registerType<CGDenOfthieves>();
s.template registerType<CGObelisk>();
s.template registerType<CGLighthouse>();
s.template registerType<CGMarket>();
s.template registerType<CGBlackMarket>();
s.template registerType<CGUniversity>();
//end of objects
s.template registerType<IPropagator>();
s.template registerType<CPropagatorNodeType>();
s.template registerType<ILimiter>();
s.template registerType<CCreatureTypeLimiter>();
s.template registerType<HasAnotherBonusLimiter>();
s.template registerType<CreatureNativeTerrainLimiter>();
s.template registerType<CreatureFactionLimiter>();
s.template registerType<CreatureAlignmentLimiter>();
s.template registerType<RankRangeLimiter>();
s.template registerType<StackOwnerLimiter>();
s.template registerType<CBonusSystemNode>();
s.template registerType<CArtifact>();
s.template registerType<CCreature>();
s.template registerType<CStackInstance>();
s.template registerType<PlayerState>();
s.template registerType<TeamState>();
s.template registerType<CGameState>();
s.template registerType<CGHeroInstance::HeroSpecial>();
s.template registerType<CArmedInstance>();
s.template registerType<CStack>();
s.template registerType<BattleInfo>();
s.template registerType<CArtifactInstance>();
s.template registerType<CCombinedArtifactInstance>();
}
template<typename Serializer> DLL_EXPORT
void registerTypes2(Serializer &s)
{
s.template registerType<PackageApplied>();
s.template registerType<SystemMessage>();
s.template registerType<PlayerBlocked>();
s.template registerType<YourTurn>();
s.template registerType<SetResource>();
s.template registerType<SetResources>();
s.template registerType<SetPrimSkill>();
s.template registerType<SetSecSkill>();
s.template registerType<HeroVisitCastle>();
s.template registerType<ChangeSpells>();
s.template registerType<SetMana>();
s.template registerType<SetMovePoints>();
s.template registerType<FoWChange>();
s.template registerType<SetAvailableHeroes>();
s.template registerType<GiveBonus>();
s.template registerType<ChangeObjPos>();
s.template registerType<PlayerEndsGame>();
s.template registerType<RemoveBonus>();
s.template registerType<UpdateCampaignState>();
s.template registerType<RemoveObject>();
s.template registerType<TryMoveHero>();
//s.template registerType<SetGarrisons>();
s.template registerType<NewStructures>();
s.template registerType<RazeStructures>();
s.template registerType<SetAvailableCreatures>();
s.template registerType<SetHeroesInTown>();
//s.template registerType<SetHeroArtifacts>();
s.template registerType<HeroRecruited>();
s.template registerType<GiveHero>();
s.template registerType<NewTurn>();
s.template registerType<InfoWindow>();
s.template registerType<SetObjectProperty>();
s.template registerType<SetHoverName>();
s.template registerType<HeroLevelUp>();
s.template registerType<BlockingDialog>();
s.template registerType<GarrisonDialog>();
s.template registerType<BattleStart>();
s.template registerType<BattleNextRound>();
s.template registerType<BattleSetActiveStack>();
s.template registerType<BattleResult>();
s.template registerType<BattleStackMoved>();
s.template registerType<BattleStackAttacked>();
s.template registerType<BattleAttack>();
s.template registerType<StartAction>();
s.template registerType<EndAction>();
s.template registerType<BattleSpellCast>();
s.template registerType<SetStackEffect>();
s.template registerType<BattleTriggerEffect>();
s.template registerType<BattleSetStackProperty>();
s.template registerType<StacksInjured>();
s.template registerType<BattleResultsApplied>();
s.template registerType<StacksHealedOrResurrected>();
s.template registerType<ObstaclesRemoved>();
s.template registerType<CatapultAttack>();
s.template registerType<BattleStacksRemoved>();
s.template registerType<BattleStackAdded>();
s.template registerType<ShowInInfobox>();
s.template registerType<AdvmapSpellCast>();
s.template registerType<OpenWindow>();
s.template registerType<NewObject>();
s.template registerType<NewArtifact>();
s.template registerType<ChangeStackCount>();
s.template registerType<SetStackType>();
s.template registerType<EraseStack>();
s.template registerType<SwapStacks>();
s.template registerType<InsertNewStack>();
s.template registerType<RebalanceStacks>();
s.template registerType<SetAvailableArtifacts>();
s.template registerType<PutArtifact>();
s.template registerType<EraseArtifact>();
s.template registerType<MoveArtifact>();
s.template registerType<AssembledArtifact>();
s.template registerType<DisassembledArtifact>();
s.template registerType<HeroVisit>();
s.template registerType<SaveGame>();
s.template registerType<SetSelection>();
s.template registerType<PlayerMessage>();
s.template registerType<CenterView>();
}
template<typename Serializer> DLL_EXPORT
void registerTypes3(Serializer &s)
{
s.template registerType<CloseServer>();
s.template registerType<EndTurn>();
s.template registerType<DismissHero>();
s.template registerType<MoveHero>();
s.template registerType<ArrangeStacks>();
s.template registerType<DisbandCreature>();
s.template registerType<BuildStructure>();
s.template registerType<RecruitCreatures>();
s.template registerType<UpgradeCreature>();
s.template registerType<GarrisonHeroSwap>();
s.template registerType<ExchangeArtifacts>();
s.template registerType<AssembleArtifacts>();
s.template registerType<BuyArtifact>();
s.template registerType<TradeOnMarketplace>();
s.template registerType<SetFormation>();
s.template registerType<HireHero>();
s.template registerType<BuildBoat>();
s.template registerType<QueryReply>();
s.template registerType<MakeAction>();
s.template registerType<MakeCustomAction>();
s.template registerType<DigWithHero>();
s.template registerType<CastAdvSpell>();
s.template registerType<CastleTeleportHero>();
s.template registerType<SaveGame>();
s.template registerType<CommitPackage>();
s.template registerType<SetSelection>();
s.template registerType<PlayerMessage>();
}
template<typename Serializer> DLL_EXPORT
void registerTypes4(Serializer &s)
{
s.template registerType<ChatMessage>();
s.template registerType<QuitMenuWithoutStarting>();
s.template registerType<PlayerJoined>();
s.template registerType<SelectMap>();
s.template registerType<UpdateStartOptions>();
s.template registerType<PregameGuiAction>();
s.template registerType<RequestOptionsChange>();
s.template registerType<PlayerLeft>();
s.template registerType<PlayersNames>();
s.template registerType<StartWithCurrentSettings>();
}
template<typename Serializer> DLL_EXPORT
void registerTypes(Serializer &s)
{
registerTypes1(s);
registerTypes2(s);
registerTypes3(s);
registerTypes4(s);
}

85
lib/SHexField.cpp Normal file
View File

@ -0,0 +1,85 @@
#include "StdInc.h"
#include "SHexField.h"
void SHexField::operator+=(EDir dir)
{
si16 x = getX(),
y = getY();
switch(dir)
{
case TOP_LEFT:
setXY(y%2 ? x-1 : x, y-1);
break;
case TOP_RIGHT:
setXY(y%2 ? x : x+1, y-1);
break;
case RIGHT:
setXY(x+1, y);
break;
case BOTTOM_RIGHT:
setXY(y%2 ? x : x+1, y+1);
break;
case BOTTOM_LEFT:
setXY(y%2 ? x-1 : x, y+1);
break;
case LEFT:
setXY(x-1, y);
break;
default:
throw std::string("Disaster: wrong direction in SHexField::operator+=!\n");
break;
}
}
SHexField SHexField::operator+(EDir dir) const
{
SHexField ret(*this);
ret += dir;
return ret;
}
std::vector<SHexField> SHexField::neighbouringTiles() const
{
std::vector<SHexField> ret;
const int WN = GameConstants::BFIELD_WIDTH;
checkAndPush(hex - ( (hex/WN)%2 ? WN+1 : WN ), ret);
checkAndPush(hex - ( (hex/WN)%2 ? WN : WN-1 ), ret);
checkAndPush(hex - 1, ret);
checkAndPush(hex + 1, ret);
checkAndPush(hex + ( (hex/WN)%2 ? WN-1 : WN ), ret);
checkAndPush(hex + ( (hex/WN)%2 ? WN : WN+1 ), ret);
return ret;
}
signed char SHexField::mutualPosition(SHexField hex1, SHexField hex2)
{
if(hex2 == hex1 - ( (hex1/17)%2 ? 18 : 17 )) //top left
return 0;
if(hex2 == hex1 - ( (hex1/17)%2 ? 17 : 16 )) //top right
return 1;
if(hex2 == hex1 - 1 && hex1%17 != 0) //left
return 5;
if(hex2 == hex1 + 1 && hex1%17 != 16) //right
return 2;
if(hex2 == hex1 + ( (hex1/17)%2 ? 16 : 17 )) //bottom left
return 4;
if(hex2 == hex1 + ( (hex1/17)%2 ? 17 : 18 )) //bottom right
return 3;
return -1;
}
char SHexField::getDistance(SHexField hex1, SHexField hex2)
{
int xDst = std::abs(hex1 % GameConstants::BFIELD_WIDTH - hex2 % GameConstants::BFIELD_WIDTH),
yDst = std::abs(hex1 / GameConstants::BFIELD_WIDTH - hex2 / GameConstants::BFIELD_WIDTH);
return std::max(xDst, yDst) + std::min(xDst, yDst) - (yDst + 1)/2;
}
void SHexField::checkAndPush(int tile, std::vector<SHexField> & ret)
{
if( tile>=0 && tile<GameConstants::BFIELD_SIZE && (tile%GameConstants::BFIELD_WIDTH != (GameConstants::BFIELD_WIDTH - 1))
&& (tile%GameConstants::BFIELD_WIDTH != 0) )
ret.push_back(SHexField(tile));
}

109
lib/SHexField.h Normal file
View File

@ -0,0 +1,109 @@
#pragma once
#include "GameConstants.h"
/*
* SHexField.h, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
// for battle stacks' positions
struct DLL_LINKAGE SHexField
{
static const si16 INVALID = -1;
enum EDir{RIGHT, BOTTOM_RIGHT, BOTTOM_LEFT, LEFT, TOP_LEFT, TOP_RIGHT};
si16 hex;
SHexField() : hex(INVALID) {}
SHexField(si16 _hex) : hex(_hex) {}
operator si16() const
{
return hex;
}
bool isValid() const
{
return hex >= 0 && hex < GameConstants::BFIELD_SIZE;
}
template<typename inttype>
SHexField(inttype x, inttype y)
{
setXY(x, y);
}
template<typename inttype>
SHexField(std::pair<inttype, inttype> xy)
{
setXY(xy);
}
template<typename inttype>
void setX(inttype x)
{
setXY(x, getY());
}
template<typename inttype>
void setY(inttype y)
{
setXY(getX(), y);
}
void setXY(si16 x, si16 y)
{
assert(x >= 0 && x < GameConstants::BFIELD_WIDTH && y >= 0 && y < GameConstants::BFIELD_HEIGHT);
hex = x + y * GameConstants::BFIELD_WIDTH;
}
template<typename inttype>
void setXY(std::pair<inttype, inttype> xy)
{
setXY(xy.first, xy.second);
}
si16 getY() const
{
return hex / GameConstants::BFIELD_WIDTH;
}
si16 getX() const
{
int pos = hex - getY() * GameConstants::BFIELD_WIDTH;
return pos;
}
std::pair<si16, si16> getXY() const
{
return std::make_pair(getX(), getY());
}
//moving to direction
void operator+=(EDir dir);
//generates new SHexField moved by given dir
SHexField operator+(EDir dir) const;
std::vector<SHexField> neighbouringTiles() const;
//returns info about mutual position of given hexes (-1 - they're distant, 0 - left top, 1 - right top, 2 - right, 3 - right bottom, 4 - left bottom, 5 - left)
static signed char mutualPosition(SHexField hex1, SHexField hex2);
//returns distance between given hexes
static char getDistance(SHexField hex1, SHexField hex2);
template <typename Handler> void serialize(Handler &h, const int version)
{
h & hex;
}
static void checkAndPush(int tile, std::vector<SHexField> & ret);
};

View File

@ -1,9 +1,4 @@
#ifndef __STARTINFO_H__
#define __STARTINFO_H__
#include "global.h"
#include <vector>
#include <string>
#pragma once
/*
* StartInfo.h, part of VCMI engine
@ -96,6 +91,3 @@ struct StartInfo
choosenCampaignBonus = -1;
}
};
#endif // __STARTINFO_H__

2
lib/StdInc.cpp Normal file
View File

@ -0,0 +1,2 @@
// Creates the precompiled header
#include "StdInc.h"

325
lib/StdInc.h Normal file
View File

@ -0,0 +1,325 @@
#pragma once
// Standard include file
// Should be treated as a precompiled header file in the compiler settings
// We generate a .PCH file for every project due to simplicity and some annoying bugs in VisualStudio
// This file shouldn't be changed, except if there is a important header file which is missing.
/*
* StdInc.h, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#include <cstdio>
#include <stdio.h>
#ifdef _WIN32
#include <tchar.h>
#else
#include "../tchar_amigaos4.h"
#endif
#include <cmath>
#include <cassert>
#include <assert.h>
#include <vector>
#include <string>
#include <map>
#include <queue>
#include <set>
#include <utility>
#include <numeric>
#include <iostream>
#include <fstream>
#include <sstream>
#include <iomanip>
#include <algorithm>
#include <memory>
#include <cstdlib>
//filesystem version 3 causes problems (and it's default as of boost 1.46)
#define BOOST_FILESYSTEM_VERSION 2
#include <boost/algorithm/string.hpp>
#include <boost/assert.hpp>
#include <boost/assign.hpp>
#include <boost/bind.hpp>
#include <boost/cstdint.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/filesystem.hpp>
#include <boost/foreach.hpp>
#include <boost/format.hpp>
#include <boost/function.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/logic/tribool.hpp>
#include <boost/program_options.hpp>
#include <boost/thread.hpp>
#include <boost/unordered_set.hpp>
#ifdef ANDROID
#include <android/log.h>
#endif
// Integral data types
typedef boost::uint64_t ui64; //unsigned int 64 bits (8 bytes)
typedef boost::uint32_t ui32; //unsigned int 32 bits (4 bytes)
typedef boost::uint16_t ui16; //unsigned int 16 bits (2 bytes)
typedef boost::uint8_t ui8; //unsigned int 8 bits (1 byte)
typedef boost::int64_t si64; //signed int 64 bits (8 bytes)
typedef boost::int32_t si32; //signed int 32 bits (4 bytes)
typedef boost::int16_t si16; //signed int 16 bits (2 bytes)
typedef boost::int8_t si8; //signed int 8 bits (1 byte)
// Import + Export macro declarations
#ifdef _WIN32
#define DLL_EXPORT __declspec(dllexport)
#else
#if defined(__GNUC__) && __GNUC__ >= 4
#define DLL_EXPORT __attribute__ ((visibility("default")))
#else
#define DLL_EXPORT
#endif
#endif
#ifdef _WIN32
#define DLL_IMPORT __declspec(dllimport)
#else
#if defined(__GNUC__) && __GNUC__ >= 4
#define DLL_IMPORT __attribute__ ((visibility("default")))
#else
#define DLL_IMPORT
#endif
#endif
#ifdef VCMI_DLL
#define DLL_LINKAGE DLL_EXPORT
#else
#define DLL_LINKAGE DLL_IMPORT
#endif
//a normal std::map with a const operator[] for sanity
template<typename KeyT, typename ValT>
class bmap : public std::map<KeyT, ValT>
{
public:
const ValT & operator[](KeyT key) const
{
return find(key)->second;
}
ValT & operator[](KeyT key)
{
return static_cast<std::map<KeyT, ValT> &>(*this)[key];
}
template <typename Handler> void serialize(Handler &h, const int version)
{
h & static_cast<std::map<KeyT, ValT> &>(*this);
}
};
namespace vstd
{
//returns true if container c contains item i
template <typename Container, typename Item>
bool contains(const Container & c, const Item &i)
{
return std::find(c.begin(),c.end(),i) != c.end();
}
//returns true if map c contains item i
template <typename V, typename Item, typename Item2>
bool contains(const std::map<Item,V> & c, const Item2 &i)
{
return c.find(i)!=c.end();
}
//returns true if bmap c contains item i
template <typename V, typename Item, typename Item2>
bool contains(const bmap<Item,V> & c, const Item2 &i)
{
return c.find(i)!=c.end();
}
//returns true if unordered set c contains item i
template <typename Item>
bool contains(const boost::unordered_set<Item> & c, const Item &i)
{
return c.find(i)!=c.end();
}
//returns position of first element in vector c equal to s, if there is no such element, -1 is returned
template <typename T1, typename T2>
int find_pos(const std::vector<T1> & c, const T2 &s)
{
for(size_t i=0; i < c.size(); ++i)
if(c[i] == s)
return i;
return -1;
}
//Func(T1,T2) must say if these elements matches
template <typename T1, typename T2, typename Func>
int find_pos(const std::vector<T1> & c, const T2 &s, const Func &f)
{
for(size_t i=0; i < c.size(); ++i)
if(f(c[i],s))
return i;
return -1;
}
//returns iterator to the given element if present in container, end() if not
template <typename Container, typename Item>
typename Container::iterator find(Container & c, const Item &i)
{
return std::find(c.begin(),c.end(),i);
}
//returns const iterator to the given element if present in container, end() if not
template <typename Container, typename Item>
typename Container::const_iterator find(const Container & c, const Item &i)
{
return std::find(c.begin(),c.end(),i);
}
//removes element i from container c, returns false if c does not contain i
template <typename Container, typename Item>
typename Container::size_type operator-=(Container &c, const Item &i)
{
typename Container::iterator itr = find(c,i);
if(itr == c.end())
return false;
c.erase(itr);
return true;
}
//assigns greater of (a, b) to a and returns maximum of (a, b)
template <typename t1, typename t2>
t1 &amax(t1 &a, const t2 &b)
{
if(a >= b)
return a;
else
{
a = b;
return a;
}
}
//assigns smaller of (a, b) to a and returns minimum of (a, b)
template <typename t1, typename t2>
t1 &amin(t1 &a, const t2 &b)
{
if(a <= b)
return a;
else
{
a = b;
return a;
}
}
//makes a to fit the range <b, c>
template <typename t1, typename t2, typename t3>
t1 &abetween(t1 &a, const t2 &b, const t3 &c)
{
amax(a,b);
amin(a,c);
return a;
}
//checks if a is between b and c
template <typename t1, typename t2, typename t3>
bool isbetween(const t1 &a, const t2 &b, const t3 &c)
{
return a > b && a < c;
}
//checks if a is within b and c
template <typename t1, typename t2, typename t3>
bool iswithin(const t1 &a, const t2 &b, const t3 &c)
{
return a >= b && a <= c;
}
template <typename t1, typename t2>
struct assigner
{
public:
t1 &op1;
t2 op2;
assigner(t1 &a1, const t2 & a2)
:op1(a1), op2(a2)
{}
void operator()()
{
op1 = op2;
}
};
// Assigns value a2 to a1. The point of time of the real operation can be controlled
// with the () operator.
template <typename t1, typename t2>
assigner<t1,t2> assigno(t1 &a1, const t2 &a2)
{
return assigner<t1,t2>(a1,a2);
}
//deleted pointer and sets it to NULL
template <typename T>
void clear_pointer(T* &ptr)
{
delete ptr;
ptr = NULL;
}
}
using vstd::operator-=;
// can be used for counting arrays
template<typename T, size_t N> char (&_ArrayCountObj(const T (&)[N]))[N];
#define ARRAY_COUNT(arr) (sizeof(_ArrayCountObj(arr)))
//for explicit overrides
#ifdef _MSC_VER
#define OVERRIDE override
#else
#define OVERRIDE //is there any working counterpart?
#endif
//XXX pls dont - 'debug macros' are usually more trouble than it's worth
#define HANDLE_EXCEPTION \
catch (const std::exception& e) { \
tlog1 << e.what() << std::endl; \
throw; \
} \
catch (const std::exception * e) \
{ \
tlog1 << e->what()<< std::endl; \
throw; \
} \
catch (const std::string& e) { \
tlog1 << e << std::endl; \
throw; \
}
#define HANDLE_EXCEPTIONC(COMMAND) \
catch (const std::exception& e) { \
COMMAND; \
tlog1 << e.what() << std::endl; \
throw; \
} \
catch (const std::string &e) \
{ \
COMMAND; \
tlog1 << e << std::endl; \
throw; \
}
#include "../lib/CLogger.h"

View File

@ -1,5 +1,4 @@
#ifndef __TIMEHANDLER_H__
#define __TIMEHANDLER_H__
#pragma once
#ifdef __FreeBSD__
#include <sys/types.h>
@ -8,7 +7,7 @@
#define TO_MS_DIVISOR (1000)
#else
#include <ctime>
#define TO_MS_DIVISOR (CLOCKS_PER_SEC/1000)
#define TO_MS_DIVISOR (CLOCKS_PER_SEC / 1000)
#endif
/*
@ -21,22 +20,23 @@
*
*/
class timeHandler
class StopWatch
{
clock_t start, last, mem;
si64 start, last, mem;
public:
timeHandler()
StopWatch()
: start(clock())
{
last=clock();
mem=0;
}
long getDif() //get diff in milliseconds
si64 getDiff() //get diff in milliseconds
{
long ret=clock()-last;
last=clock();
return ret/TO_MS_DIVISOR;
si64 ret = clock() - last;
last = clock();
return ret / TO_MS_DIVISOR;
}
void update()
{
@ -46,21 +46,20 @@ public:
{
mem=clock();
}
long memDif()
si64 memDif()
{
return clock()-mem;
}
long clock()
private:
si64 clock()
{
#ifdef __FreeBSD__
struct rusage usage;
getrusage(RUSAGE_SELF, &usage);
return static_cast<long>(usage.ru_utime.tv_sec + usage.ru_stime.tv_sec) * 1000000 + usage.ru_utime.tv_usec + usage.ru_stime.tv_usec;
return static_cast<si64>(usage.ru_utime.tv_sec + usage.ru_stime.tv_sec) * 1000000 + usage.ru_utime.tv_usec + usage.ru_stime.tv_usec;
#else
return std::clock();
#endif
}
};
#endif // __TIMEHANDLER_H__

View File

@ -1,5 +1,4 @@
#ifndef __INT3_H__
#define __INT3_H__
#pragma once
/*
* int3.h, part of VCMI engine
@ -11,8 +10,6 @@
*
*/
#include <cmath>
/// Class which consists of three integer values. Represents position on adventure map.
class int3
{
@ -107,5 +104,3 @@ struct ShashInt3
return ret;
}
};
#endif // __INT3_H__

914
nodrze.h
View File

@ -1,914 +0,0 @@
#ifndef _NODRZE_H
#define _NODRZE_H
//don't look here, it's a horrible, partially working implementation of RB trees
//ignore comment above, it is simply TowDragon's envy. Everything (without removing) is working fine
//TODO? remove file - not used anymore
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#define CLOG(x)
const bool CZERWONY=true, CZARNY=false;
template <typename T> class wezel
{
public:
bool kolor:1;
T * zawart;
wezel * ojciec, *lewy, *prawy;
wezel(bool kol):kolor(kol),ojciec(NULL),lewy(NULL),prawy(NULL){zawart = new T;};
wezel(wezel * NIL);
~wezel(){delete zawart;}
};
template <typename T> std::ostream & piszAdresy(std::ostream & strum, wezel<T> & w)
{
strum << "Informacje o wezle: "<<&w;
strum <<"\n\tOjciec: "<<(w.ojciec);
strum<<"\n\tLewy syn: "<<(w.lewy);
strum<<"\n\tPrawy syn: "<<(w.prawy);
strum<<"\n\tKolor: "<<((w.kolor)?(std::string("Czerwony")):(std::string("Czarny")))<<std::endl<<std::endl;
return strum;
}
template <typename T> std::ostream & operator<<(std::ostream & strum, wezel<T> & w)
{
strum << "Informacje o wezle: "<<&w<<" - "<<*w.zawart;
strum <<"\n\tOjciec: "<<(w.ojciec)<<" - "<<*w.ojciec->zawart;
strum<<"\n\tLewy syn: "<<(w.lewy)<<" - "<<*w.lewy->zawart;
strum<<"\n\tPrawy syn: "<<(w.prawy)<<" - "<<*w.prawy->zawart;
strum<<"\n\tKolor: "<<((w.kolor)?(std::string("Czerwony")):(std::string("Czarny")))<<std::endl<<std::endl;
return strum;
}
template <typename T> wezel<T>::wezel(wezel * NIL)
{
ojciec=NIL; lewy=NIL; prawy=NIL; kolor=CZERWONY; zawart = NULL;
}
template <typename T> class nodrze
{
private:
wezel<T> * NIL, *ostatnio;
int ile, ktory;
void zepsuj();
void dodajBSTC (wezel<T> * nowy);
void dodajBST (T co);
void dodajRBT (wezel<T> * nowy);
wezel<T> * usunRBT (wezel<T> * nowy);
void naprawWstaw (wezel<T> * nowy);
void naprawUsun (wezel<T> * x);
wezel<T> * minimum(wezel<T> * w);
wezel<T> * maksimum(wezel<T> * w);
wezel<T> * nastepnik(wezel<T> * w);
wezel<T> * poprzednik(wezel<T> * w);
wezel<T> * szukajRek(wezel<T> * w, T co);
wezel<T> * szukajIter(wezel<T> * w, T co);
void in(std::ostream & strum, wezel<T> * wsk);
void inIt(std::ostream & strum, wezel<T> * wsk);
void pre(std::ostream & strum, wezel<T> * wsk);
void post(std::ostream & strum, wezel<T> * wsk);
void rotacjaLewa (wezel<T> * x);
void rotacjaPrawa (wezel<T> * y);
bool czyBST (wezel<T> * w);
bool sprawdzW(wezel<T> * w);
void destrukcja(wezel<T> * w);
void wypisuj(wezel<T> * w, std::ostream & strum);
void wypisujPre(wezel<T> * w, std::ostream & strum);
public:
wezel<T> * korzen; //root
nodrze():ile(0) //najzwyczajniejszy w swiecie kosntruktor // c-tor
{
NIL=new wezel<T>(CZARNY);
NIL->zawart=NULL;
korzen=NIL;
ostatnio=NIL;
ktory=0;
};
T * begin () {return minimumimum();}; //first element (=minimum)
T * end () {return NIL;}; //
void clear(); // czysci az do korzenia wlacznie
// removes all elements, including root
void usun (T co); // usuwa element z drzewa
// remove element (value)
bool sprawdz(); // sprawdza, czy drzewo jest poprawnym drzewem BST
//checks if tree is correct (rather useful only for debugging)
T * nast(T czego); // nastepnik zadanego elementu
// successor of that element
T * maksimumimum (); // najwiekszy element w drzewie
//biggest element (and last)
bool czyJest(T co); // czy cos jest w drzewie
//check if given element is in tree
T * minimumimum (); // najmniejszy element w drzewie
//smallest element (first)
void dodaj (T co); // dodaje element do drzewa
// adds (copies)
void inorder(std::ostream & strum); // wypisuje na zadane wyjscie elementy w porzadku inorder
//print all elements inorder
void preorder(std::ostream & strum); // wypisuje na zadane wyjscie elementy w porzadku preorder
//print all elements preorder
void postorder(std::ostream & strum); // wypisuje na zadane wyjscie elementy w porzadku postorder
//print all elements postorder
void wypiszObficie(std::ostream & strum); //wypisuje dane o kazdym wezle -- wymaga operatora >> dla zawartosci
//prints info about all nodes - >> operator for T needed
std::vector<T> vectorize(); //returns vector with all nodrze elements
T * znajdz (T co, bool iter = true); // wyszukuje zadany element
//search for T
int size(); //ilosc elementow
//returns size of tree
T* operator()(int i) ; //n-ty element przez wskaxnik
//returns pointer to element with index i
nodrze<T> & operator()(std::istream & potoczek) ; //zczytanie n elemntow z listy
//read elements from istream (first must be given amount of elements)
T& operator[](int i) ; //dostep do obiektu, ale przez wartosc
//returns value of object with index i
bool operator+=(T * co); //add
bool operator+=(T co); //add
bool operator-=(T co); //remove
bool operator-=(T * co); //ve
T* operator%(T * co); // search and return pointer
bool operator&(T co); // check if exist
bool operator&(T * co); // check if exist
template <typename Y, class X> friend Y* operator%(nodrze<Y> & drzewko, X co); // search and return pointer
void push_back(T co){(*this)+=co;}; // add
};
template <typename T> std::vector<T> nodrze<T>::vectorize()
{
std::vector<T> ret;
for (int i=0; i<ile; i++)
ret.push_back((*this)[i]);
return ret;
}
template <typename T> void nodrze<T>::wypisuj(wezel<T> * w, std::ostream & strum)
{
if (w==NIL) return;
wypisuj(w->lewy, strum);
strum << "Informacje o wezle: "<<std::flush<<w<<std::flush;
if (w->ojciec!=NIL)
strum <<"\n\tOjciec: "<<(w->ojciec)<<" - "<<*(w->ojciec->zawart);
else strum <<"\n\tOjciec: NIL";
if (w->lewy!=NIL)
strum<<"\n\tLewy syn: "<<(w->lewy)<<" - "<<*(w->lewy->zawart);
else strum <<"\n\tLewy syn: NIL";
if (w->prawy!=NIL)
strum<<"\n\tPrawy syn: "<<(w->prawy)<<" - "<<*(w->prawy->zawart);
else strum <<"\n\tPrawy syn: NIL";
strum<<"\n\tZawartosc: "<<*w->zawart;
strum<<"\n\tKolor: "<<((w->kolor)?(std::string("Czerwony")):(std::string("Czarny")))<<std::endl<<std::endl;
wypisuj(w->prawy, strum);
}
template <typename T> void nodrze<T>::wypisujPre(wezel<T> * w, std::ostream & strum)
{
if (w==NIL) return;
strum << "Informacje o wezle: "<<std::flush<<w<<std::flush;
if (w->ojciec!=NIL)
strum <<"\n\tOjciec: "<<(w->ojciec)<<" - "<<*(w->ojciec->zawart);
else strum <<"\n\tOjciec: NIL";
if (w->lewy!=NIL)
strum<<"\n\tLewy syn: "<<(w->lewy)<<" - "<<*(w->lewy->zawart);
else strum <<"\n\tLewy syn: NIL";
if (w->prawy!=NIL)
strum<<"\n\tPrawy syn: "<<(w->prawy)<<" - "<<*(w->prawy->zawart);
else strum <<"\n\tPrawy syn: NIL";
strum<<"\n\tZawartosc: "<<*w->zawart;
strum<<"\n\tKolor: "<<((w->kolor)?(std::string("Czerwony")):(std::string("Czarny")))<<std::endl<<std::endl;
wypisujPre(w->lewy, strum);
wypisujPre(w->prawy, strum);
}
template <typename T> void nodrze<T>::wypiszObficie(std::ostream & strum)
{
strum << "Nodrze " <<this<<" ma " << ile << " elementów."<<std::endl;
strum << "NIL to " << NIL <<std::endl;
strum << "Ostatnio bralismy "<<ktory<<std::flush<<" element, czyli "<<" ("<<ostatnio<<")"<<std::flush<<*ostatnio<<std::flush<<std::endl;
strum << "Nasze wezly in-order"<<std::endl;
wypisujPre(korzen,strum);
}
template <typename T, class X> T* operator%(nodrze<T> & drzewko, X co)
{
CLOG ("Szukam " <<co <<std::endl);
#ifdef _MSC_VER
drzewko.wypiszObficie(*C->gl->loguj);
#endif
wezel<T> * w = drzewko.korzen;
while (w!=drzewko.NIL && (*w->zawart)!=co)
{
if ((*w->zawart) > co)
w=w->lewy;
else w=w->prawy;
}
return w->zawart;
}
template <typename T> int nodrze<T>::size()
{
return ile;
}
template <typename T> void nodrze<T>::clear()
{
destrukcja(korzen);
korzen=NIL;
ostatnio=NIL;
ktory=0;
}
template <typename T> void nodrze<T>::destrukcja(wezel<T> * w)
{
if (w==NIL) return;
destrukcja(w->lewy);
destrukcja(w->prawy);
//delete w->zawart;
delete w;
}
template <typename T> nodrze<T> & nodrze<T>::operator()(std::istream & potoczek)
{
int temp;
potoczek >> temp;
for (int i=0;i<temp;++i)
potoczek >> (*this);
return (*this);
}
template <typename T> T* nodrze<T>::operator()(int i)
{
int j;
wezel<T> * nasz;
if (ostatnio!=NIL)
{
j=i-ktory;
if (j>0)
{
if (j > (ile-i))
{
ktory = i;
i=ile-i-1;
nasz = maksimum(korzen);
for (j=0;j<i;j++)
{
nasz = poprzednik(nasz);
}
ostatnio=nasz;
return (nasz->zawart);
}
else
{
ktory = i;
nasz = ostatnio;
for (i=0;i<j;i++)
{
nasz = nastepnik(nasz);
}
ostatnio=nasz;
return (nasz->zawart);
}
}
if (j==0)
{
return (ostatnio->zawart);
}
else
{
ktory = i;
if ((-j)>i)
{
nasz = minimum(korzen);
for (j=0;j<i;j++)
{
nasz = nastepnik(nasz);
}
ostatnio=nasz;
return (nasz->zawart);
}
else
{
nasz = ostatnio;
for (i=0;i>j;i--)
{
nasz = poprzednik(nasz);
}
ostatnio=nasz;
return (nasz->zawart);
}
}
}
else
{
ktory = i;
nasz = minimum(korzen);
for (j=0;j<i;j++)
{
nasz = nastepnik(nasz);
}
ostatnio=nasz;
return (nasz->zawart);
}
}
template <typename T> T& nodrze<T>::operator[](int i)
{
int j;
wezel<T> * nasz;
if (ostatnio!=NIL)
{
j=i-ktory;
if (j>0)
{
if (j > (ile-i))
{
ktory = i;
i=ile-i-1;
nasz = maksimum(korzen);
for (j=0;j<i;j++)
{
nasz = poprzednik(nasz);
}
ostatnio=nasz;
return *(nasz->zawart);
}
else
{
ktory = i;
nasz = ostatnio;
for (i=0;i<j;i++)
{
nasz = nastepnik(nasz);
}
ostatnio=nasz;
return *(nasz->zawart);
}
}
if (j==0)
{
return *(ostatnio->zawart);
}
else
{
ktory = i;
if ((-j)>i)
{
nasz = minimum(korzen);
for (j=0;j<i;j++)
{
nasz = nastepnik(nasz);
}
ostatnio=nasz;
return *(nasz->zawart);
}
else
{
nasz = ostatnio;
for (i=0;i>j;i--)
{
nasz = poprzednik(nasz);
}
ostatnio=nasz;
return *(nasz->zawart);
}
}
}
else
{
ktory = i;
nasz = minimum(korzen);
for (j=0;j<i;j++)
{
nasz = nastepnik(nasz);
}
ostatnio=nasz;
return *(nasz->zawart);
}
}
template <typename T> bool nodrze<T>::operator+=(T * co)
{
wezel<T> * w = new wezel<T>(NIL);
w->kolor=CZERWONY;
w->zawart = co;
dodajRBT(w);
return true;
}
template <typename T> bool nodrze<T>::operator+=(T co)
{
dodaj(co);
return true;
}
template <typename T> bool nodrze<T>::operator-=(T co)
{
usun(co);
return true;
}
template <typename T> bool nodrze<T>::operator-=(T * co)
{
usun(*co);
return true;
}
template <typename T> T* nodrze<T>::operator%(T * co)
{
wezel<T> * w = szukajIter(korzen,*co);
if (w != NIL)
return w;
else return NULL;
}
template <typename T> bool nodrze<T>::operator&(T co)
{
return czyJest(co);
}
template <typename T> bool nodrze<T>::operator&(T * co)
{
return czyJest(*co);
}
template <typename T> class iterator
{
/*nodrze<T> * dd;
wezel<T> * akt;
public:
T * operator->()
{
return akt->zawart;
}
iterator& operator++()
{
akt = dd->nastepnik(akt);
return this;
}
iterator& operator--()
{
akt = dd->poprzednik(akt);
return this;
}
T * operator=(T*)
{
akt->zawart = T;
return akt->zawart;
}*/
/*void start()
{
akt = maksimum(korzen);
}*/
};
template <typename T> void nodrze<T>::inIt(std::ostream & strum, wezel<T> * wsk)
{
if (wsk == NIL)
return;
// Start from the minimumimum wsk
while (wsk->lewy != NIL)
wsk=wsk->lewy;
do
{
visit(wsk);
// Next in order will be our right child's leftmost child (if NIL, our right child)
if (wsk->prawy != NIL)
{
wsk = wsk->prawy;
while (wsk->lewy != NIL)
wsk = wsk->left;
}
else
{
while (true)
{
if (wsk->ojciec == NIL)
{
wsk = NIL;
break;
}
wsk = wsk->ojciec;
// If wsk is its parents left child, then its parent hasn't been visited yet
if (wsk->ojciec->lewy == wsk)
break;
}
}
}
while (wsk != NIL);
}
template <typename T> bool nodrze<T>::sprawdz()
{
return (sprawdzW(korzen));
}
template <typename T> T * nodrze<T>::znajdz (T co, bool iter)
{
return ((iter)?(szukajIter(korzen,co)->zawart):(szukajRek(korzen,co)->zawart));
}
template <typename T> void nodrze<T>::usun (T co)
{
wezel<T> * w = szukajIter(korzen, co);
usunRBT(w);
delete w;
}
template <typename T> void nodrze<T>::naprawUsun (wezel<T> * x)
{
wezel<T> *w;
while ( (x != korzen) && (x->kolor == CZARNY) )
{
CLOG("6... "<<std::flush);
if (x == x->ojciec->lewy)
{
CLOG("7... "<<std::flush);
w = x->ojciec->prawy;
if (w->kolor == CZERWONY)
{
w->kolor = CZARNY;
x->ojciec->kolor = CZERWONY;
rotacjaLewa(x->ojciec);
w = x->ojciec->prawy;
}
CLOG("8... "<<std::flush);
if ( (w->lewy->kolor == CZARNY) && (w->prawy->kolor == CZARNY) )
{
CLOG("8,1... "<<std::flush);
w->kolor = CZERWONY;
x = x->ojciec;
}
else
{
CLOG("9... "<<std::flush);
if (w->prawy->kolor == CZARNY)
{
CLOG("9,1... "<<std::flush);
w->lewy->kolor = CZARNY;
w->kolor = CZERWONY;
rotacjaPrawa(w);
w = x->ojciec->prawy;
CLOG("9,2... "<<std::flush);
}
CLOG("9,3... "<<std::flush);
w->kolor = x->ojciec->kolor;
x->ojciec->kolor = CZARNY;
w->prawy->kolor = CZARNY;
rotacjaLewa(x->ojciec);
x=korzen;
CLOG("9,4... "<<std::flush);
}
}
else
{
CLOG("10... "<<std::flush);
w = x->ojciec->lewy;
if (w->kolor == CZERWONY)
{
w->kolor = CZARNY;
x->ojciec->kolor = CZERWONY;
rotacjaPrawa(x->ojciec);
w = x->ojciec->lewy;
}
CLOG("11... "<<std::flush);
if ( (w->lewy->kolor == CZARNY) && (w->prawy->kolor == CZARNY) )
{
w->kolor = CZERWONY;
x = x->ojciec;
}
else
{
if (w->lewy->kolor == CZARNY)
{
w->prawy->kolor = CZARNY;
w->kolor = CZERWONY;
rotacjaLewa(w);
w = x->ojciec->lewy;
}
w->kolor = x->ojciec->kolor;
x->ojciec->kolor = CZARNY;
w->lewy->kolor = CZARNY;
rotacjaPrawa(x->ojciec);
x=korzen;
CLOG("12... "<<std::flush);
}
}
}
x->kolor = CZARNY;
CLOG("13... "<<std::flush);
}
template <typename T> wezel<T> * nodrze<T>::usunRBT (wezel<T> * nowy)
{
CLOG ("Usuwam "<<*nowy->zawart<<std::endl);
ile--;
if ((*nowy->zawart) < (*ostatnio->zawart))
{
ktory--;
CLOG("Ostatnio to "<<(*ostatnio->zawart)<<", czyli teraz "<<(ktory)<<" (mniej) element."<<std::endl);
}
else if (nowy == ostatnio)
{
CLOG ("To by³ ostatnio ogl¹dany element. Elementem o numerze "<<ktory<<" bedzie teraz ");
if (ktory < ile)
{
ostatnio = nastepnik(ostatnio);
}
else
{
CLOG ("Ojej, koniec. Cofamy siê. "<<std::endl);
ostatnio = poprzednik(ostatnio);
ktory--;
}
CLOG(*ostatnio->zawart<<std::endl);
}
CLOG("1... "<<std::flush);
wezel<T> *y, *x;
if ( (nowy->lewy == NIL) || (nowy->prawy == NIL) )
y=nowy;
else y = nastepnik(nowy);
CLOG("2... "<<std::flush);
if (y->lewy != NIL)
x = y->lewy;
else x = y->prawy;
x->ojciec = y->ojciec;
CLOG("3... "<<std::flush);
if (y->ojciec == NIL)
korzen = x;
else if (y == y->ojciec->lewy)
y->ojciec->lewy = x;
else
y->ojciec->prawy = x;
CLOG("4... "<<std::flush);
if (y != nowy)
(*nowy) = (*y); // skopiowanie
CLOG("5... "<<std::flush);
if (y->kolor == CZARNY)
naprawUsun(x);
CLOG ("koniec usuwania"<<std::endl);
return y;
}
template <typename T> void nodrze<T>::naprawWstaw (wezel<T> * nowy)
{
//CLOG ("Naprawiam po wstawieniu"<<std::endl);
while (nowy->ojciec->kolor==CZERWONY)
{
if (nowy->ojciec == nowy->ojciec->ojciec->lewy) // ojciec nowego lest lewy
{
wezel<T> * y = nowy->ojciec->ojciec->prawy;
if (y->kolor == CZERWONY) // a stryj jest czerwony
{
nowy->ojciec->kolor = CZARNY;
y->kolor = CZARNY;
nowy->ojciec->ojciec->kolor = CZERWONY;
nowy = nowy->ojciec->ojciec;
}
else
{
if (nowy->ojciec->prawy == nowy) // nowy jest prawym synem
{
nowy = nowy->ojciec;
rotacjaLewa(nowy);
}
nowy->ojciec->kolor=CZARNY;
nowy->ojciec->ojciec->kolor=CZERWONY;
rotacjaPrawa(nowy->ojciec->ojciec);
}
}
else
{
wezel<T> * y = nowy->ojciec->ojciec->lewy;
if (y->kolor == CZERWONY) // a stryj jest czerwony
{
nowy->ojciec->kolor = CZARNY;
y->kolor = CZARNY;
nowy->ojciec->ojciec->kolor = CZERWONY;
nowy = nowy->ojciec->ojciec;
}
else
{
if (nowy->ojciec->lewy == nowy)
{
nowy = nowy->ojciec;
rotacjaPrawa(nowy);
}
nowy->ojciec->kolor=CZARNY;
nowy->ojciec->ojciec->kolor=CZERWONY;
rotacjaLewa(nowy->ojciec->ojciec);
}
}
}
korzen->kolor = CZARNY;
}
template <typename T> void nodrze<T>::dodajRBT (wezel<T> * nowy)
{
//CLOG("Dodaje do drzewa "<<nowy->zawart<<std::endl);
ile++;
if(ostatnio==NIL)
{
ostatnio = nowy;
ktory=0;
}
else if ((*nowy->zawart) < (*ostatnio->zawart))
{
ktory++;
}
wezel<T> * y =NIL, * x = korzen;
while (x != NIL)
{
y=x;
if ((*nowy->zawart) < (*x->zawart))
x=x->lewy;
else x = x->prawy;
}
nowy->ojciec = y;
if (y == NIL)
{
korzen=nowy;
ostatnio=korzen;
ktory=0;
}
else if ((*nowy->zawart) < (*y->zawart))
y->lewy = nowy;
else y->prawy = nowy;
nowy->kolor = CZERWONY;
naprawWstaw(nowy);
}
template <typename T> void nodrze<T>::dodaj (T co)
{
wezel<T> * w = new wezel<T>(NIL);
w->lewy=w->prawy=w->ojciec=NIL;
w->zawart = new T(co);
dodajRBT(w);
}
template <typename T> void nodrze<T>::zepsuj()
{
int pom;
pom = *korzen->zawart;
*korzen->zawart = *korzen->prawy->zawart;
*korzen->prawy->zawart = pom;
}
template <typename T> bool nodrze<T>::czyBST (wezel<T> * w)
{
if (w->prawy != NIL)
{
if ((*w->prawy->zawart) < (*w->zawart))
return false;
}
if (w->lewy != NIL)
{
if((*w->lewy->zawart) > (*w->zawart))
return false;
}
return true;
}
template <typename T> bool nodrze<T>::sprawdzW(wezel<T> * w)
{
bool ret = czyBST(w);
if (w->prawy != NIL)
ret&=sprawdzW(w->prawy);
if (w->lewy != NIL)
ret&=sprawdzW(w->lewy);
return ret;
}
template <typename T> void nodrze<T>::rotacjaLewa (wezel<T> * x)
{
//CLOG("Wykonuje lew¹ rotacjê na "<<x->zawart<<std::endl);
wezel<T> * y = x->prawy;
x->prawy = y->lewy; // zamiana lewego poddrzewa y na prawe poddrzewo x
if (y->lewy != NIL) y->lewy->ojciec = x; // i przypisanie ojcostwa temu poddrzewu
y->ojciec = x->ojciec; // ojcem y bedzie ojciec x
if (x->ojciec == NIL)
korzen = y;
else if ((x->ojciec->lewy) == x)
x->ojciec->lewy = y;
else
x->ojciec->prawy = y;
y->lewy = x; // a x bedzie lewym synem y
x->ojciec = y;
}
template <typename T> void nodrze<T>::rotacjaPrawa (wezel<T> * y)
{
//CLOG("Wykonuje prawa rotacjê na "<<y->zawart<<std::endl);
wezel<T> * x = y->lewy;
y->lewy = x->prawy; // zamiana prawe poddrzewa x na lewe poddrzewo y
if (x->prawy != NIL) x->prawy->ojciec = y; // i przypisanie ojcostwa temu poddrzewu
x->ojciec = y->ojciec; // ojcem x bedzie ojciec y
if (x->ojciec == NIL)
korzen = x;
else if ((y->ojciec->lewy) == y)
y->ojciec->lewy = x;
else
y->ojciec->prawy = x;
x->prawy = y; // a y bedzie prawym synem x
y->ojciec = x;
}
template <typename T> T * nodrze<T>::nast(T czego)
{
wezel<T> * w = szukajIter(korzen,czego);
if (w != NIL)
w = nastepnik(w);
else throw std::exception("Nie znaleziono wartosci");
if (w != NIL)
return (w->zawart);
else throw std::exception("Nie znaleziono nastepnika");
}
template <typename T> bool nodrze<T>::czyJest(T co)
{
if ( szukajIter(korzen,co) != NIL )
return true;
else return false;
}
template <typename T> wezel<T> * nodrze<T>::szukajRek(wezel<T> * w, T co)
{
if (w==NIL || (!(((*w->zawart)<co)||(co<(*w->zawart)))))
return w;
if (co < (*w->zawart))
return szukajRek(w->lewy,co);
else return szukajRek(w->prawy,co);
}
template <typename T> wezel<T> * nodrze<T>::szukajIter(wezel<T> * w, T co)
{
while ( w!=NIL && (((*w->zawart)<co)||(co<(*w->zawart))) )
{
if (co < (*w->zawart))
w=w->lewy;
else w=w->prawy;
}
return (w)?w:NULL;
}
template <typename T> wezel<T> * nodrze<T>::minimum(wezel<T> * w)
{
while (w->lewy != NIL)
w=w->lewy;
return w;
}
template <typename T> wezel<T> * nodrze<T>::maksimum(wezel<T> * w)
{
while (w->prawy != NIL)
w=w->prawy;
return w;
}
template <typename T> wezel<T> * nodrze<T>::nastepnik(wezel<T> * w)
{
if (w->prawy != NIL)
return minimum(w->prawy);
wezel<T> * y = w->ojciec;
while (y!= NIL && w == y->prawy)
{
w=y;
y=y->ojciec;
}
return y;
}
template <typename T> wezel<T> * nodrze<T>::poprzednik(wezel<T> * w)
{
if (w->lewy != NIL)
return maksimum(w->lewy);
wezel<T> * y = w->ojciec;
while (y!= NIL && w == y->lewy)
{
w=y;
y=y->ojciec;
}
return y;
}
template <typename T> T * nodrze<T>::maksimumimum ()
{
wezel<T> * ret = maksimum(korzen);
if (ret != NIL)
return (ret->zawart);
else throw std::exception("Drzewo jest puste");
}
template <typename T> T * nodrze<T>::minimumimum ()
{
wezel<T> * ret = minimum(korzen);
if (ret != NIL)
return (ret->zawart);
else throw std::exception("Drzewo jest puste");
}
template <typename T> void nodrze<T>::inorder(std::ostream & strum)
{
in(strum,korzen);
}
template <typename T> void nodrze<T>::preorder(std::ostream & strum)
{
pre(strum,korzen);
}
template <typename T> void nodrze<T>::postorder(std::ostream & strum)
{
post(strum,korzen);
}
template <typename T> void nodrze<T>::in(std::ostream & strum, wezel<T> * wsk)
{
if (wsk==NIL)
return;
if (wsk->lewy != NIL)
in(strum,wsk->lewy);
strum << *wsk->zawart<<"\t";
if (wsk->prawy != NIL)
in(strum,wsk->prawy);
}
template <typename T> void nodrze<T>::post(std::ostream & strum, wezel<T> * wsk)
{
if (wsk==NIL)
return;
if (wsk->lewy != NIL)
post(strum,wsk->lewy);
if (wsk->prawy != NIL)
post(strum,wsk->prawy);
strum << *wsk->zawart<<"\t";
}
template <typename T> void nodrze<T>::pre(std::ostream & strum, wezel<T> * wsk)
{
if (wsk == NIL)
return;
strum << *wsk->zawart<<"\t";
if (wsk->lewy != NIL)
pre(strum,wsk->lewy);
if (wsk->prawy != NIL)
pre(strum,wsk->prawy);
}
#endif //_NODRZE_H

2
server/StdInc.cpp Normal file
View File

@ -0,0 +1,2 @@
// Creates the precompiled header
#include "StdInc.h"

325
server/StdInc.h Normal file
View File

@ -0,0 +1,325 @@
#pragma once
// Standard include file
// Should be treated as a precompiled header file in the compiler settings
// We generate a .PCH file for every project due to simplicity and some annoying bugs in VisualStudio
// This file shouldn't be changed, except if there is a important header file which is missing.
/*
* StdInc.h, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#include <cstdio>
#include <stdio.h>
#ifdef _WIN32
#include <tchar.h>
#else
#include "../tchar_amigaos4.h"
#endif
#include <cmath>
#include <cassert>
#include <assert.h>
#include <vector>
#include <string>
#include <map>
#include <queue>
#include <set>
#include <utility>
#include <numeric>
#include <iostream>
#include <fstream>
#include <sstream>
#include <iomanip>
#include <algorithm>
#include <memory>
#include <cstdlib>
//filesystem version 3 causes problems (and it's default as of boost 1.46)
#define BOOST_FILESYSTEM_VERSION 2
#include <boost/algorithm/string.hpp>
#include <boost/assert.hpp>
#include <boost/assign.hpp>
#include <boost/bind.hpp>
#include <boost/cstdint.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/filesystem.hpp>
#include <boost/foreach.hpp>
#include <boost/format.hpp>
#include <boost/function.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/logic/tribool.hpp>
#include <boost/program_options.hpp>
#include <boost/thread.hpp>
#include <boost/unordered_set.hpp>
#ifdef ANDROID
#include <android/log.h>
#endif
// Integral data types
typedef boost::uint64_t ui64; //unsigned int 64 bits (8 bytes)
typedef boost::uint32_t ui32; //unsigned int 32 bits (4 bytes)
typedef boost::uint16_t ui16; //unsigned int 16 bits (2 bytes)
typedef boost::uint8_t ui8; //unsigned int 8 bits (1 byte)
typedef boost::int64_t si64; //signed int 64 bits (8 bytes)
typedef boost::int32_t si32; //signed int 32 bits (4 bytes)
typedef boost::int16_t si16; //signed int 16 bits (2 bytes)
typedef boost::int8_t si8; //signed int 8 bits (1 byte)
// Import + Export macro declarations
#ifdef _WIN32
#define DLL_EXPORT __declspec(dllexport)
#else
#if defined(__GNUC__) && __GNUC__ >= 4
#define DLL_EXPORT __attribute__ ((visibility("default")))
#else
#define DLL_EXPORT
#endif
#endif
#ifdef _WIN32
#define DLL_IMPORT __declspec(dllimport)
#else
#if defined(__GNUC__) && __GNUC__ >= 4
#define DLL_IMPORT __attribute__ ((visibility("default")))
#else
#define DLL_IMPORT
#endif
#endif
#ifdef VCMI_DLL
#define DLL_LINKAGE DLL_EXPORT
#else
#define DLL_LINKAGE DLL_IMPORT
#endif
//a normal std::map with a const operator[] for sanity
template<typename KeyT, typename ValT>
class bmap : public std::map<KeyT, ValT>
{
public:
const ValT & operator[](KeyT key) const
{
return find(key)->second;
}
ValT & operator[](KeyT key)
{
return static_cast<std::map<KeyT, ValT> &>(*this)[key];
}
template <typename Handler> void serialize(Handler &h, const int version)
{
h & static_cast<std::map<KeyT, ValT> &>(*this);
}
};
namespace vstd
{
//returns true if container c contains item i
template <typename Container, typename Item>
bool contains(const Container & c, const Item &i)
{
return std::find(c.begin(),c.end(),i) != c.end();
}
//returns true if map c contains item i
template <typename V, typename Item, typename Item2>
bool contains(const std::map<Item,V> & c, const Item2 &i)
{
return c.find(i)!=c.end();
}
//returns true if bmap c contains item i
template <typename V, typename Item, typename Item2>
bool contains(const bmap<Item,V> & c, const Item2 &i)
{
return c.find(i)!=c.end();
}
//returns true if unordered set c contains item i
template <typename Item>
bool contains(const boost::unordered_set<Item> & c, const Item &i)
{
return c.find(i)!=c.end();
}
//returns position of first element in vector c equal to s, if there is no such element, -1 is returned
template <typename T1, typename T2>
int find_pos(const std::vector<T1> & c, const T2 &s)
{
for(size_t i=0; i < c.size(); ++i)
if(c[i] == s)
return i;
return -1;
}
//Func(T1,T2) must say if these elements matches
template <typename T1, typename T2, typename Func>
int find_pos(const std::vector<T1> & c, const T2 &s, const Func &f)
{
for(size_t i=0; i < c.size(); ++i)
if(f(c[i],s))
return i;
return -1;
}
//returns iterator to the given element if present in container, end() if not
template <typename Container, typename Item>
typename Container::iterator find(Container & c, const Item &i)
{
return std::find(c.begin(),c.end(),i);
}
//returns const iterator to the given element if present in container, end() if not
template <typename Container, typename Item>
typename Container::const_iterator find(const Container & c, const Item &i)
{
return std::find(c.begin(),c.end(),i);
}
//removes element i from container c, returns false if c does not contain i
template <typename Container, typename Item>
typename Container::size_type operator-=(Container &c, const Item &i)
{
typename Container::iterator itr = find(c,i);
if(itr == c.end())
return false;
c.erase(itr);
return true;
}
//assigns greater of (a, b) to a and returns maximum of (a, b)
template <typename t1, typename t2>
t1 &amax(t1 &a, const t2 &b)
{
if(a >= b)
return a;
else
{
a = b;
return a;
}
}
//assigns smaller of (a, b) to a and returns minimum of (a, b)
template <typename t1, typename t2>
t1 &amin(t1 &a, const t2 &b)
{
if(a <= b)
return a;
else
{
a = b;
return a;
}
}
//makes a to fit the range <b, c>
template <typename t1, typename t2, typename t3>
t1 &abetween(t1 &a, const t2 &b, const t3 &c)
{
amax(a,b);
amin(a,c);
return a;
}
//checks if a is between b and c
template <typename t1, typename t2, typename t3>
bool isbetween(const t1 &a, const t2 &b, const t3 &c)
{
return a > b && a < c;
}
//checks if a is within b and c
template <typename t1, typename t2, typename t3>
bool iswithin(const t1 &a, const t2 &b, const t3 &c)
{
return a >= b && a <= c;
}
template <typename t1, typename t2>
struct assigner
{
public:
t1 &op1;
t2 op2;
assigner(t1 &a1, const t2 & a2)
:op1(a1), op2(a2)
{}
void operator()()
{
op1 = op2;
}
};
// Assigns value a2 to a1. The point of time of the real operation can be controlled
// with the () operator.
template <typename t1, typename t2>
assigner<t1,t2> assigno(t1 &a1, const t2 &a2)
{
return assigner<t1,t2>(a1,a2);
}
//deleted pointer and sets it to NULL
template <typename T>
void clear_pointer(T* &ptr)
{
delete ptr;
ptr = NULL;
}
}
using vstd::operator-=;
// can be used for counting arrays
template<typename T, size_t N> char (&_ArrayCountObj(const T (&)[N]))[N];
#define ARRAY_COUNT(arr) (sizeof(_ArrayCountObj(arr)))
//for explicit overrides
#ifdef _MSC_VER
#define OVERRIDE override
#else
#define OVERRIDE //is there any working counterpart?
#endif
//XXX pls dont - 'debug macros' are usually more trouble than it's worth
#define HANDLE_EXCEPTION \
catch (const std::exception& e) { \
tlog1 << e.what() << std::endl; \
throw; \
} \
catch (const std::exception * e) \
{ \
tlog1 << e->what()<< std::endl; \
throw; \
} \
catch (const std::string& e) { \
tlog1 << e << std::endl; \
throw; \
}
#define HANDLE_EXCEPTIONC(COMMAND) \
catch (const std::exception& e) { \
COMMAND; \
tlog1 << e.what() << std::endl; \
throw; \
} \
catch (const std::string &e) \
{ \
COMMAND; \
tlog1 << e << std::endl; \
throw; \
}
#include "../lib/CLogger.h"

View File

@ -1 +0,0 @@
#include "stdafx.h"

View File

@ -1,30 +0,0 @@
#include <boost/bind.hpp>
#include <boost/date_time/posix_time/posix_time_types.hpp> //no i/o just types
#include <boost/foreach.hpp>
#include <boost/thread.hpp>
#include <boost/thread/shared_mutex.hpp>
#include <boost/assign/list_of.hpp>
#include <boost/random/linear_congruential.hpp>
#include <fstream>
#include <boost/lexical_cast.hpp>
#include <boost/system/system_error.hpp>
#include <boost/function.hpp>
#include <boost/thread.hpp>
#include <set>
#include <map>
#include "../global.h"
#include <boost/crc.hpp>
#include <boost/interprocess/mapped_region.hpp>
#include <boost/interprocess/shared_memory_object.hpp>
#include <iostream>
#include <string>
#include <boost/asio.hpp>
#include <boost/thread.hpp>
#include <boost/foreach.hpp>
#include <boost/format.hpp>
#include <sstream>
#include <boost/format.hpp>
#include <sstream>
#include "../CThreadHelper.h"

View File

@ -1,8 +0,0 @@
// stdafx.cpp : source file that includes just the standard includes
// CMT.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information
#include "stdafx.h"
// TODO: reference any additional headers you need in STDAFX.H
// and not in this file

View File

@ -1,24 +0,0 @@
#ifndef __STDAFX_H__
#define __STDAFX_H__
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#include <cstdio>
#ifdef _WIN32
#include <tchar.h>
#else
#include "tchar_amigaos4.h"
#endif
#include <string>
#include <vector>
#include <map>
#include <algorithm>
#include <fstream>
#include "global.h"
// TODO: reference additional headers your program requires here
#endif // __STDAFX_H__