Update of /cvsroot/wpdev/wolfpack
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv10137
Modified Files:
ChangeLog basics.cpp coord.h dragdrop.cpp exceptions.h
multi.cpp multi.h platform.h server.cpp server.h skills.cpp
territories.cpp territories.h wolfpack.sln
Added Files:
mersennetwister.h
Log Message:
housing updates
Index: wolfpack.sln
===================================================================
RCS file: /cvsroot/wpdev/wolfpack/wolfpack.sln,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -d -r1.2 -r1.3
*** wolfpack.sln 22 Jul 2004 19:39:11 -0000 1.2
--- wolfpack.sln 21 Oct 2004 12:11:19 -0000 1.3
***************
*** 4,7 ****
--- 4,11 ----
EndProjectSection
EndProject
+ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "plugin", "plugin\plugin.vcproj", "{709E9DEC-CDB2-4383-8B2D-10631EA06774}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+ EndProject
Global
GlobalSection(SolutionConfiguration) = preSolution
***************
*** 17,20 ****
--- 21,30 ----
{766437DE-37EB-400E-BF08-4AB9B529C83D}.Web-Release.ActiveCfg = Web-Release|Win32
{766437DE-37EB-400E-BF08-4AB9B529C83D}.Web-Release.Build.0 = Web-Release|Win32
+ {709E9DEC-CDB2-4383-8B2D-10631EA06774}.Debug.ActiveCfg = Debug|Win32
+ {709E9DEC-CDB2-4383-8B2D-10631EA06774}.Debug.Build.0 = Debug|Win32
+ {709E9DEC-CDB2-4383-8B2D-10631EA06774}.Release.ActiveCfg = Release|Win32
+ {709E9DEC-CDB2-4383-8B2D-10631EA06774}.Release.Build.0 = Release|Win32
+ {709E9DEC-CDB2-4383-8B2D-10631EA06774}.Web-Release.ActiveCfg = Release|Win32
+ {709E9DEC-CDB2-4383-8B2D-10631EA06774}.Web-Release.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
Index: coord.h
===================================================================
RCS file: /cvsroot/wpdev/wolfpack/coord.h,v
retrieving revision 1.22
retrieving revision 1.23
diff -C2 -d -r1.22 -r1.23
*** coord.h 16 Sep 2004 01:40:17 -0000 1.22
--- coord.h 21 Oct 2004 12:11:10 -0000 1.23
***************
*** 35,39 ****
class cUORxTarget;
! class Coord_cl
{
public:
--- 35,39 ----
class cUORxTarget;
! class WPEXPORT Coord_cl
{
public:
Index: dragdrop.cpp
===================================================================
RCS file: /cvsroot/wpdev/wolfpack/dragdrop.cpp,v
retrieving revision 1.248
retrieving revision 1.249
diff -C2 -d -r1.248 -r1.249
*** dragdrop.cpp 17 Oct 2004 01:20:19 -0000 1.248
--- dragdrop.cpp 21 Oct 2004 12:11:10 -0000 1.249
***************
*** 560,577 ****
{
dynamic_cast<P_PLAYER>( pChar )->onTradeStart( dynamic_cast<P_PLAYER>( pOtherChar ), pItem );
- // Check if we're already trading,
- // if not create a new window
- /*
- P_ITEM tradeWindow = pChar->atLayer( cBaseChar::TradeWindow );
- //if( !tradeWindow )
- // tradeWindow = Trade->tradestart( client->socket(), pOtherChar );
- socket->bounceItem( pItem, BR_NO_REASON );
- socket->sysMessage( "Trading is disabled" );
- return;
- tradeWindow->addItem( pItem, false, false );
- pItem->setPos( Coord_cl(rand() % 60, rand() % 60, 9) );
- pItem->removeFromView( false );
- pItem->update();
- */
return;
}
--- 560,563 ----
Index: territories.h
===================================================================
RCS file: /cvsroot/wpdev/wolfpack/territories.h,v
retrieving revision 1.32
retrieving revision 1.33
diff -C2 -d -r1.32 -r1.33
*** territories.h 1 Oct 2004 19:43:56 -0000 1.32
--- territories.h 21 Oct 2004 12:11:19 -0000 1.33
***************
*** 116,119 ****
--- 116,123 ----
return flags_ & 0x1000;
}
+ bool isNoHousing( void ) const
+ {
+ return flags_ & 0x2000;
+ }
QString guardOwner( void ) const
{
***************
*** 141,144 ****
--- 145,149 ----
flags_ &= ~0x0001;
}
+
void setNoMark( bool data )
{
***************
*** 225,228 ****
--- 230,240 ----
flags_ &= ~0x1000;
}
+ void setNoHousing( bool data )
+ {
+ if ( data )
+ flags_ |= 0x2000;
+ else
+ flags_ &= ~0x2000;
+ }
virtual void processNode( const cElement* Tag );
Index: ChangeLog
===================================================================
RCS file: /cvsroot/wpdev/wolfpack/ChangeLog,v
retrieving revision 1.121
retrieving revision 1.122
diff -C2 -d -r1.121 -r1.122
*** ChangeLog 21 Oct 2004 00:19:41 -0000 1.121
--- ChangeLog 21 Oct 2004 12:11:10 -0000 1.122
***************
*** 3,7 ****
Wolfpack 12.9.13 Beta (CVS)
- Fixed meditation skillcheck in mana regeneration code.
- - Added the <haircolor> NPC definition tag to dye the currently equipped hair/beard (both the same color).
Wolfpack 12.9.12 Beta (18. October 2004)
--- 3,6 ----
***************
*** 66,69 ****
--- 65,69 ----
- Empty context menus are no longer send to the client.
- Added the onCheckSecurity event for housing.
+ - Wrote the multi placement checks and exported them to python.
Wolfpack 12.9.11 Beta (26. September 2004)
Index: basics.cpp
===================================================================
RCS file: /cvsroot/wpdev/wolfpack/basics.cpp,v
retrieving revision 1.42
retrieving revision 1.43
diff -C2 -d -r1.42 -r1.43
*** basics.cpp 12 Oct 2004 23:59:28 -0000 1.42
--- basics.cpp 21 Oct 2004 12:11:10 -0000 1.43
***************
*** 48,61 ****
#endif
/*!
Returns a random number between \a nLowNum
and \a nHighNum.
*/
! int RandomNum( int nLowNum, int nHighNum )
! {
! if ( nHighNum - nLowNum + 1 )
! return ( ( rand() % ( nHighNum - nLowNum + 1 ) ) + nLowNum );
! else
! return nLowNum;
}
--- 48,65 ----
#endif
+ #include "mersennetwister.h"
+
+ static MTRand mtrand;
+
/*!
Returns a random number between \a nLowNum
and \a nHighNum.
*/
! int RandomNum(int nLowNum, int nHighNum) {
! if (nLowNum > nHighNum) {
! std::swap(nLowNum, nHighNum);
! }
! int diff = (nHighNum - nLowNum) + 1;
! return nLowNum + (mtrand.randInt() % diff);
}
***************
*** 66,78 ****
float RandomFloatNum( float nLowNum, float nHighNum )
{
! if ( nHighNum - nLowNum + 1 )
! {
! float number = nLowNum;
! number += rand() % static_cast<int>( ceil( nHighNum ) - ceil( nLowNum ) + 1 ); // Integer part
! number += ( float ) rand() / ( float ) 0x7FFFFFFF;
! return number;
! }
! else
! return nLowNum;
}
--- 70,75 ----
float RandomFloatNum( float nLowNum, float nHighNum )
{
! float diff = nHighNum - nLowNum;
! return nLowNum + mtrand.rand() * diff;
}
Index: multi.cpp
===================================================================
RCS file: /cvsroot/wpdev/wolfpack/multi.cpp,v
retrieving revision 1.16
retrieving revision 1.17
diff -C2 -d -r1.16 -r1.17
*** multi.cpp 25 Sep 2004 22:57:09 -0000 1.16
--- multi.cpp 21 Oct 2004 12:11:18 -0000 1.17
***************
*** 28,36 ****
#include "multi.h"
#include "definitions.h"
!
#include "muls/multiscache.h"
#include "world.h"
#include "log.h"
#include "console.h"
#include "sectors.h"
#include "timers.h"
--- 28,39 ----
#include "multi.h"
#include "definitions.h"
! #include "territories.h"
#include "muls/multiscache.h"
+ #include "muls/maps.h"
+ #include "muls/tilecache.h"
#include "world.h"
#include "log.h"
#include "console.h"
+ #include "basechar.h"
#include "sectors.h"
#include "timers.h"
***************
*** 194,195 ****
--- 197,496 ----
}
}
+
+ bool cMulti::canPlace(const Coord_cl &pos, unsigned short multiid, QPtrList<cUObject> &moveOut, unsigned short yard) {
+ MultiDefinition *multi = MultiCache::instance()->getMulti(multiid);
+
+ if (!multi) {
+ return false;
+ }
+
+ moveOut.setAutoDelete(false);
+
+ // Get the boundaries and build a list sorted by x,y
+ int left = multi->getLeft();
+ int right = multi->getRight();
+ int bottom = multi->getBottom();
+ int top = multi->getTop();
+ int height = multi->getHeight();
+ int width = multi->getWidth();
+
+ QValueList<Coord_cl> borderList; // a list of points around the foundation that need to be clear of impassables
+ QValueList<Coord_cl> yardList; // a list of points in the yard (front/back of the house that needs to be clear)
+
+ for ( int x = 0; x < width; ++x) {
+ for ( int y = 0; y < height; ++y) {
+ Coord_cl point = pos + Coord_cl(x + left, y + top);
+ bool hasBase = false; // Has this multi tile a base below the floor?
+
+ // See if there are any tiles at that position
+ const QValueVector<multiItem_st> &multiItems = multi->itemsAt(x + left, y + top);
+
+ if (multiItems.size() == 0) {
+ continue; // Skip this tile since there are no items here
+ }
+
+ cTerritory *region = Territories::instance()->region(point);
+ if (region && region->isNoHousing()) {
+ return false; // No housing is allowed in this region
+ }
+
+ // Collect data for the intersect checks
+ StaticsIterator statics = Maps::instance()->staticsIterator(point);
+ RegionIterator4Items items(point, 0);
+ int top, bottom;
+ unsigned short landId;
+ Maps::instance()->mapTileSpan(point, landId, bottom, top);
+
+ // Check every tile of the multi at the current position
+ // The following algorithm is more or less a ripoff of RunUOs idea.
+ for (int i = 0; i < multiItems.size(); ++i) {
+ multiItem_st multiItem = multiItems[i];
+ tile_st tile = TileCache::instance()->getTile(multiItem.tile);
+
+ // Calculcate the spawn of the tile
+ int itemBottom = point.z + multiItem.z;
+ // if the tile is a surface, someone has to be able to stand on it.
+ int itemTop = itemBottom + tile.height + (((tile.flag2 & 0x02) != 0) ? 16 : 0);
+
+ // There is special handling for floor tiles
+ bool baseTile = multiItem.z == 0 && (tile.flag1 & 0x10) != 0;
+ bool isHovering = true; // This tile has not yet something to "stand" on
+
+ if (baseTile)
+ hasBase = true;
+
+ // Does the multi item intersect a land-tile?
+ if ((itemTop < top && itemTop >= bottom) || (itemBottom < top && itemBottom >= bottom)) {
+ return false;
+ }
+
+ // Since houses can only be built on land and not on items, it's enough to check for
+ // a solid foundation here
+ if (pos.z != bottom || pos.z != top) {
+ return false;
+ }
+
+ // Check if the multi item is interfering with a static tile at the same position
+ statics.reset();
+ while (!statics.atEnd()) {
+ const staticrecord &staticTile = (statics++).data();
+ tile_st staticInfo = TileCache::instance()->getTile(staticTile.itemid);
+
+ int staticBottom = staticTile.zoff;
+ int staticTop = staticBottom + staticInfo.height;
+
+ // The tile intersects a static tile
+ if ((itemTop < staticTop && itemTop >= staticBottom)
+ || (itemBottom < staticTop && itemBottom >= staticBottom))
+ {
+ bool impassable = (staticInfo.flag1 & 0x40) != 0;
+ bool background = (staticInfo.flag1 & 0x01) != 0;
+ bool surface = (staticInfo.flag2 & 0x02) != 0;
+
+ // A normally blocking tile is intersecting our multi
+ if (impassable || (!background && surface)) {
+ return false;
+ }
+ }
+ }
+
+ // Do the same check (as above) with movable items, but make sure that movable items
+ // are moved out of the house
+ for (items.Begin(); !items.atEnd(); items++) {
+ P_ITEM pItem = items.GetData();
+ tile_st itemInfo = TileCache::instance()->getTile(pItem->id());
+
+ int dynamicBottom = pItem->pos().z;
+ int dynamicTop = dynamicBottom + itemInfo.height;
+
+ // Only handle the tile if it is intersecting the multi
+ if ((itemTop < dynamicTop && itemTop >= dynamicBottom)
+ || (itemBottom < dynamicTop && itemBottom >= dynamicBottom))
+ {
+ // Move the item out of the multi space if possible
+ if ((pItem->movable() == 0 && itemInfo.weight != 255) || pItem->movable() == 1) {
+ moveOut.append(pItem);
+ } else {
+ bool impassable = (itemInfo.flag1 & 0x40) != 0;
+ bool background = (itemInfo.flag1 & 0x01) != 0;
+ bool surface = (itemInfo.flag2 & 0x02) != 0;
+
+ // A normally blocking tile is intersecting our multi
+ if (impassable || (!background && surface)) {
+ return false;
+ }
+ }
+ }
+ }
+
+ // Moves mobiles inside the multi out to the ban location
+ RegionIterator4Chars chars(point, 0, true);
+ while (!chars.atEnd()) {
+ const cUObject *pChar = (chars++).GetData();
+ // Move them ALWAYS out, they could be trapped by the castle otherwise (or other strange multi forms)
+ moveOut.append(pChar);
+ }
+
+ // To keep roads house free, here's a specialized check for roads
+ if ((landId >= 0x71 && landId <= 0x8c) ||
+ (landId >= 0x14c && landId <= 0x14f) ||
+ (landId >= 0x161 && landId <= 0x174) ||
+ (landId >= 0x1f0 && landId <= 0x1f3) ||
+ (landId >= 0x26e && landId <= 0x279) ||
+ (landId >= 0x27e && landId <= 0x281) ||
+ (landId >= 0x324 && landId <= 0x3ac) ||
+ (landId >= 0x597 && landId <= 0x5a6) ||
+ (landId >= 0x637 && landId <= 0x63a) ||
+ (landId >= 0x67d && landId <= 0x6a0) ||
+ (landId >= 0x7ae && landId <= 0x7b1) ||
+ (landId >= 0x442 && landId <= 0x479) ||
+ (landId >= 0x501 && landId <= 0x510) ||
+ (landId >= 0x009 && landId <= 0x015) ||
+ (landId >= 0x150 && landId <= 0x15c))
+ {
+ return false; // Road Blocked
+ }
+
+ // For houses (they have a base you know...)
+ // we collect another list of points around the house that need to be checked
+ if (hasBase) {
+ int xOffset, yOffset;
+
+ // We have to do two loops since the yard size does play a role here
+ // but not for the border
+ for (xOffset = -1; xOffset <= 1; ++xOffset) {
+ for (yOffset = -yard; yOffset <= yard; ++yOffset) {
+ Coord_cl pos = point + Coord_cl(xOffset, yOffset);
+
+ if (!yardList.contains(pos)) {
+ yardList.push_back(pos); // Put this point into the yard checklist if it's not there
+ }
+ }
+ }
+
+ for (xOffset = -1; xOffset <= 1; ++xOffset) {
+ for (yOffset = -1; yOffset <= 1; ++yOffset) {
+ Coord_cl pos = point + Coord_cl(xOffset, yOffset);
+
+ // Only do the following if the current tiles position differs from the
+ // check position.
+ if (xOffset != 0 || yOffset != 0) {
+ // The border list should not contain tiles that are actually below the multis
+ // floor and hence not visible and covered by a walkable multi tile.
+ // So what we do here is check if within 8 z units of the multis floor there is a
+ // walkable tile above the border tile
+ int multiX = x + xOffset; // Offset to the upper left corner of the multi
+ int multiY = y + yOffset; // Offset to the upper left corner of the multi
+ bool found = false; // Assume there is no such tile
+
+ // Only do this check if the to-be-checked tile is really within the multi
+ // boundaries
+ if (multiX >= 0 && multiY >= 0 && multiX < width && multiY < height) {
+ // Get the multi tiles at the to-check position
+ const QValueVector<multiItem_st> &tiles = multi->itemsAt(multiX + left, multiY + right);
+ QValueVector<multiItem_st>::const_iterator it;
+ for (it = tiles.begin(); it != tiles.end(); ++it) {
+ if (it->z > 8) {
+ continue; // Skip the tile if its above the base (2nd floor etc.)
+ }
+
+ // Get the tiledata info for this tile if it's below z8
+ tile_st tileInfo = TileCache::instance()->getTile(it->tile);
+ bool surface = (tileInfo.flag2 & 0x02) != 0;
+
+ if (tileInfo.height == 0 && surface) {
+ found = true;
+ break;
+ }
+ }
+
+ // We found a tile that we could stand on. So it's not neccesary to check
+ // that the house stands on something walkable here.
+ if (found) {
+ continue;
+ }
+ }
+
+ // Add the tile to the list of border tiles.
+ if (!borderList.contains(pos)) {
+ borderList.append(pos);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ QValueList<Coord_cl>::const_iterator it;
+
+ // Now check all the accumulated border tiles
+ for (it = borderList.begin(); it != borderList.end(); ++it) {
+ map_st mapTile = Maps::instance()->seekMap(*it);
+ land_st mapTileInfo = TileCache::instance()->getLand(mapTile.id);
+
+ // Impassable map tiles are not allowed nearby
+ bool impassable = (mapTileInfo.flag1 & 0x40) != 0;
+ if (impassable) {
+ return false;
+ }
+
+ // Get Static Tiles
+ StaticsIterator statics = Maps::instance()->staticsIterator(*it);
+ while (!statics.atEnd()) {
+ const staticrecord &staticItem = statics.data();
+ tile_st staticInfo = TileCache::instance()->getTile(staticItem.itemid);
+
+ bool impassable = (staticInfo.flag1 & 0x40) != 0;
+ bool background = (staticInfo.flag1 & 0x01) != 0;
+ bool surface = (staticInfo.flag2 & 0x02) != 0;
+
+ // The tile is only of importance if it's not below the multi
+ if ((staticItem.zoff > ((*it).z + 2)) && (impassable || (!background && surface))) {
+ return false; // A normally blocking tile is intersecting our multi border
+ }
+
+ statics++;
+ }
+
+ // Do the same check (as above) with dynamic items
+ RegionIterator4Items items(*it, 0);
+ for (items.Begin(); !items.atEnd(); items++) {
+ P_ITEM pItem = items.GetData();
+ tile_st itemInfo = TileCache::instance()->getTile(pItem->id());
+
+ // Move the item out of the multi space if possible
+ if ((pItem->movable() == 0 && itemInfo.weight != 255) || pItem->movable() == 1) {
+ continue;
+ } else {
+ if (pItem->pos().z <= ((*it).z + 2)) {
+ continue; // Does not interfere with the border
+ }
+
+ bool impassable = (itemInfo.flag1 & 0x40) != 0;
+ bool background = (itemInfo.flag1 & 0x01) != 0;
+ bool surface = (itemInfo.flag2 & 0x02) != 0;
+
+ // A normally blocking tile is intersecting our multi
+ if (impassable || (!background && surface)) {
+ return false;
+ }
+ }
+ }
+ }
+
+ // The yard has to be free of any multis at that position
+ for (it = yardList.begin(); it != yardList.end(); ++it) {
+ RegionIterator4Items multis(*it); // Search for multis in the region
+ for (multis.Begin(); !multis.atEnd(); multis++) {
+ cMulti *multi = dynamic_cast<cMulti*>(multis.GetData());
+
+ if (multi && multi->inMulti(*it)) {
+ return false; // This is a simplified check but it should be sufficient.
+ }
+ }
+ }
+
+ return true;
+ }
Index: exceptions.h
===================================================================
RCS file: /cvsroot/wpdev/wolfpack/exceptions.h,v
retrieving revision 1.11
retrieving revision 1.12
diff -C2 -d -r1.11 -r1.12
*** exceptions.h 2 Jun 2004 15:04:05 -0000 1.11
--- exceptions.h 21 Oct 2004 12:11:18 -0000 1.12
***************
*** 37,41 ****
#include <qstring.h>
! class wpException : public std::exception
{
private:
--- 37,41 ----
#include <qstring.h>
! class WPEXPORT wpException : public std::exception
{
private:
Index: platform.h
===================================================================
RCS file: /cvsroot/wpdev/wolfpack/platform.h,v
retrieving revision 1.18
retrieving revision 1.19
diff -C2 -d -r1.18 -r1.19
*** platform.h 14 Oct 2004 16:55:34 -0000 1.18
--- platform.h 21 Oct 2004 12:11:18 -0000 1.19
***************
*** 95,97 ****
--- 95,103 ----
typedef double RF64;
+ #if defined WPIMPORT
+ #define WPEXPORT __declspec(dllimport)
+ #else
+ #define WPEXPORT __declspec(dllexport)
+ #endif
+
#endif // __PLATFORM_H__
Index: skills.cpp
===================================================================
RCS file: /cvsroot/wpdev/wolfpack/skills.cpp,v
retrieving revision 1.233
retrieving revision 1.234
diff -C2 -d -r1.233 -r1.234
*** skills.cpp 9 Oct 2004 14:28:59 -0000 1.233
--- skills.cpp 21 Oct 2004 12:11:18 -0000 1.234
***************
*** 209,213 ****
pToSteal->update();
! caught = pChar->skillValue( STEALING ) < rand() % 1001;
}
else
--- 209,213 ----
pToSteal->update();
! caught = pChar->skillValue( STEALING ) < RandomNum(0, 1000);
}
else
--- NEW FILE: mersennetwister.h ---
// MersenneTwister.h
// Mersenne Twister random number generator -- a C++ class MTRand
// Based on code by Makoto Matsumoto, Takuji Nishimura, and Shawn Cokus
// Richard J. Wagner v1.0 15 May 2003 rjw...@wr...
// The Mersenne Twister is an algorithm for generating random numbers. It
// was designed with consideration of the flaws in various other generators.
// The period, 2^19937-1, and the order of equidistribution, 623 dimensions,
// are far greater. The generator is also fast; it avoids multiplication and
// division, and it benefits from caches and pipelines. For more information
// see the inventors' web page at http://www.math.keio.ac.jp/~matumoto/emt.html
// Reference
// M. Matsumoto and T. Nishimura, "Mersenne Twister: A 623-Dimensionally
// Equidistributed Uniform Pseudo-Random Number Generator", ACM Transactions on
// Modeling and Computer Simulation, Vol. 8, No. 1, January 1998, pp 3-30.
// Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
// Copyright (C) 2000 - 2003, Richard J. Wagner
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. The names of its contributors may not be used to endorse or promote
// products derived from this software without specific prior written
// permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// The original code included the following notice:
//
// When you use this, send an email to: mat...@ma...
// with an appropriate reference to your work.
//
// It would be nice to CC: rjw...@wr... and Co...@ma...
// when you write.
#ifndef MERSENNETWISTER_H
#define MERSENNETWISTER_H
// Not thread safe (unless auto-initialization is avoided and each thread has
// its own MTRand object)
#include <limits.h>
#include <stdio.h>
#include <time.h>
#include <math.h>
class MTRand {
// Data
public:
typedef unsigned long uint32; // unsigned integer type, at least 32 bits
enum { N = 624 }; // length of state vector
enum { SAVE = N + 1 }; // length of array for save()
protected:
enum { M = 397 }; // period parameter
uint32 state[N]; // internal state
uint32 *pNext; // next value to get from state
int left; // number of values left before reload needed
//Methods
public:
MTRand( const uint32& oneSeed ); // initialize with a simple uint32
MTRand( uint32 *const bigSeed, uint32 const seedLength = N ); // or an array
MTRand(); // auto-initialize with /dev/urandom or time() and clock()
// Do NOT use for CRYPTOGRAPHY without securely hashing several returned
// values together, otherwise the generator state can be learned after
// reading 624 consecutive values.
// Access to 32-bit random numbers
double rand(); // real number in [0,1]
double rand( const double& n ); // real number in [0,n]
double randExc(); // real number in [0,1)
double randExc( const double& n ); // real number in [0,n)
double randDblExc(); // real number in (0,1)
double randDblExc( const double& n ); // real number in (0,n)
uint32 randInt(); // integer in [0,2^32-1]
uint32 randInt( const uint32& n ); // integer in [0,n] for n < 2^32
double operator()() { return rand(); } // same as rand()
// Access to 53-bit random numbers (capacity of IEEE double precision)
double rand53(); // real number in [0,1)
// Access to nonuniform random number distributions
double randNorm( const double& mean = 0.0, const double& variance = 0.0 );
// Re-seeding functions with same behavior as initializers
void seed( const uint32 oneSeed );
void seed( uint32 *const bigSeed, const uint32 seedLength = N );
void seed();
protected:
void initialize( const uint32 oneSeed );
void reload();
uint32 hiBit( const uint32& u ) const { return u & 0x80000000UL; }
uint32 loBit( const uint32& u ) const { return u & 0x00000001UL; }
uint32 loBits( const uint32& u ) const { return u & 0x7fffffffUL; }
uint32 mixBits( const uint32& u, const uint32& v ) const
{ return hiBit(u) | loBits(v); }
uint32 twist( const uint32& m, const uint32& s0, const uint32& s1 ) const
{ return m ^ (mixBits(s0,s1)>>1) ^ (-loBit(s1) & 0x9908b0dfUL); }
static uint32 hash( time_t t, clock_t c );
};
inline MTRand::MTRand( const uint32& oneSeed )
{ seed(oneSeed); }
inline MTRand::MTRand( uint32 *const bigSeed, const uint32 seedLength )
{ seed(bigSeed,seedLength); }
inline MTRand::MTRand()
{ seed(); }
inline double MTRand::rand()
{ return double(randInt()) * (1.0/4294967295.0); }
inline double MTRand::rand( const double& n )
{ return rand() * n; }
inline double MTRand::randExc()
{ return double(randInt()) * (1.0/4294967296.0); }
inline double MTRand::randExc( const double& n )
{ return randExc() * n; }
inline double MTRand::randDblExc()
{ return ( double(randInt()) + 0.5 ) * (1.0/4294967296.0); }
inline double MTRand::randDblExc( const double& n )
{ return randDblExc() * n; }
inline double MTRand::rand53()
{
uint32 a = randInt() >> 5, b = randInt() >> 6;
return ( a * 67108864.0 + b ) * (1.0/9007199254740992.0); // by Isaku Wada
}
inline double MTRand::randNorm( const double& mean, const double& variance )
{
// Return a real number from a normal (Gaussian) distribution with given
// mean and variance by Box-Muller method
double r = sqrt( -2.0 * log( 1.0-randDblExc()) ) * variance;
double phi = 2.0 * 3.14159265358979323846264338328 * randExc();
return mean + r * cos(phi);
}
inline MTRand::uint32 MTRand::randInt()
{
// Pull a 32-bit integer from the generator state
// Every other access function simply transforms the numbers extracted here
if( left == 0 ) reload();
--left;
register uint32 s1;
s1 = *pNext++;
s1 ^= (s1 >> 11);
s1 ^= (s1 << 7) & 0x9d2c5680UL;
s1 ^= (s1 << 15) & 0xefc60000UL;
return ( s1 ^ (s1 >> 18) );
}
inline MTRand::uint32 MTRand::randInt( const uint32& n )
{
// Find which bits are used in n
// Optimized by Magnus Jonsson (ma...@sm...)
uint32 used = n;
used |= used >> 1;
used |= used >> 2;
used |= used >> 4;
used |= used >> 8;
used |= used >> 16;
// Draw numbers until one is found in [0,n]
uint32 i;
do
i = randInt() & used; // toss unused bits to shorten search
while( i > n );
return i;
}
inline void MTRand::seed( const uint32 oneSeed )
{
// Seed the generator with a simple uint32
initialize(oneSeed);
reload();
}
inline void MTRand::seed( uint32 *const bigSeed, const uint32 seedLength )
{
// Seed the generator with an array of uint32's
// There are 2^19937-1 possible initial states. This function allows
// all of those to be accessed by providing at least 19937 bits (with a
// default seed length of N = 624 uint32's). Any bits above the lower 32
// in each element are discarded.
// Just call seed() if you want to get array from /dev/urandom
initialize(19650218UL);
register int i = 1;
register uint32 j = 0;
register int k = ( N > seedLength ? N : seedLength );
for( ; k; --k )
{
state[i] =
state[i] ^ ( (state[i-1] ^ (state[i-1] >> 30)) * 1664525UL );
state[i] += ( bigSeed[j] & 0xffffffffUL ) + j;
state[i] &= 0xffffffffUL;
++i; ++j;
if( i >= N ) { state[0] = state[N-1]; i = 1; }
if( j >= seedLength ) j = 0;
}
for( k = N - 1; k; --k )
{
state[i] =
state[i] ^ ( (state[i-1] ^ (state[i-1] >> 30)) * 1566083941UL );
state[i] -= i;
state[i] &= 0xffffffffUL;
++i;
if( i >= N ) { state[0] = state[N-1]; i = 1; }
}
state[0] = 0x80000000UL; // MSB is 1, assuring non-zero initial array
reload();
}
inline void MTRand::seed()
{
// Seed the generator with an array from /dev/urandom if available
// Otherwise use a hash of time() and clock() values
// First try getting an array from /dev/urandom
FILE* urandom = fopen( "/dev/urandom", "rb" );
if( urandom )
{
uint32 bigSeed[N];
register uint32 *s = bigSeed;
register int i = N;
register bool success = true;
while( success && i-- )
success = fread( s++, sizeof(uint32), 1, urandom );
fclose(urandom);
if( success ) { seed( bigSeed, N ); return; }
}
// Was not successful, so use time() and clock() instead
seed( hash( time(NULL), clock() ) );
}
inline void MTRand::initialize( const uint32 seed )
{
// Initialize generator state with seed
// See Knuth TAOCP Vol 2, 3rd Ed, p.106 for multiplier.
// In previous versions, most significant bits (MSBs) of the seed affect
// only MSBs of the state array. Modified 9 Jan 2002 by Makoto Matsumoto.
register uint32 *s = state;
register uint32 *r = state;
register int i = 1;
*s++ = seed & 0xffffffffUL;
for( ; i < N; ++i )
{
*s++ = ( 1812433253UL * ( *r ^ (*r >> 30) ) + i ) & 0xffffffffUL;
r++;
}
}
inline void MTRand::reload()
{
// Generate N new values in state
// Made clearer and faster by Matthew Bellew (mat...@ho...)
register uint32 *p = state;
register int i;
for( i = N - M; i--; ++p )
*p = twist( p[M], p[0], p[1] );
for( i = M; --i; ++p )
*p = twist( p[M-N], p[0], p[1] );
*p = twist( p[M-N], p[0], state[0] );
left = N, pNext = state;
}
inline MTRand::uint32 MTRand::hash( time_t t, clock_t c )
{
// Get a uint32 from t and c
// Better than uint32(x) in case x is floating point in [0,1]
// Based on code by Lawrence Kirby (fr...@ge...)
static uint32 differ = 0; // guarantee time-based seeds will change
uint32 h1 = 0;
unsigned char *p = (unsigned char *) &t;
for( size_t i = 0; i < sizeof(t); ++i )
{
h1 *= UCHAR_MAX + 2U;
h1 += p[i];
}
uint32 h2 = 0;
p = (unsigned char *) &c;
for( size_t j = 0; j < sizeof(c); ++j )
{
h2 *= UCHAR_MAX + 2U;
h2 += p[j];
}
return ( h1 + differ++ ) ^ h2;
}
#endif // MERSENNETWISTER_H
// Change log:
//
// v0.1 - First release on 15 May 2000
// - Based on code by Makoto Matsumoto, Takuji Nishimura, and Shawn Cokus
// - Translated from C to C++
// - Made completely ANSI compliant
// - Designed convenient interface for initialization, seeding, and
// obtaining numbers in default or user-defined ranges
// - Added automatic seeding from /dev/urandom or time() and clock()
// - Provided functions for saving and loading generator state
//
// v0.2 - Fixed bug which reloaded generator one step too late
//
// v0.3 - Switched to clearer, faster reload() code from Matthew Bellew
//
// v0.4 - Removed trailing newline in saved generator format to be consistent
// with output format of built-in types
//
// v0.5 - Improved portability by replacing static const int's with enum's and
// clarifying return values in seed(); suggested by Eric Heimburg
// - Removed MAXINT constant; use 0xffffffffUL instead
//
// v0.6 - Eliminated seed overflow when uint32 is larger than 32 bits
// - Changed integer [0,n] generator to give better uniformity
//
// v0.7 - Fixed operator precedence ambiguity in reload()
// - Added access for real numbers in (0,1) and (0,n)
//
// v0.8 - Included time.h header to properly support time_t and clock_t
//
// v1.0 - Revised seeding to match 26 Jan 2002 update of Nishimura and Matsumoto
// - Allowed for seeding with arrays of any length
// - Added access for real numbers in [0,1) with 53-bit resolution
// - Added access for real numbers from normal (Gaussian) distributions
// - Increased overall speed by optimizing twist()
// - Doubled speed of integer [0,n] generation
// - Fixed out-of-range number generation on 64-bit machines
// - Improved portability by substituting literal constants for long enum's
// - Changed license from GNU LGPL to BSD
Index: territories.cpp
===================================================================
RCS file: /cvsroot/wpdev/wolfpack/territories.cpp,v
retrieving revision 1.57
retrieving revision 1.58
diff -C2 -d -r1.57 -r1.58
*** territories.cpp 9 Oct 2004 14:29:00 -0000 1.57
--- territories.cpp 21 Oct 2004 12:11:19 -0000 1.58
***************
*** 160,163 ****
--- 160,165 ----
else if ( childNode->name() == "noentermessage" )
setNoEnterMessage( true );
+ else if ( childNode->name() == "nohousing" )
+ setNoHousing( true );
}
}
Index: server.cpp
===================================================================
RCS file: /cvsroot/wpdev/wolfpack/server.cpp,v
retrieving revision 1.33
retrieving revision 1.34
diff -C2 -d -r1.33 -r1.34
*** server.cpp 16 Oct 2004 18:19:40 -0000 1.33
--- server.cpp 21 Oct 2004 12:11:18 -0000 1.34
***************
*** 493,497 ****
d->time = getNormalizedTime();
- srand( d->time );
}
--- 493,496 ----
Index: multi.h
===================================================================
RCS file: /cvsroot/wpdev/wolfpack/multi.h,v
retrieving revision 1.10
retrieving revision 1.11
diff -C2 -d -r1.10 -r1.11
*** multi.h 19 Aug 2004 01:22:52 -0000 1.10
--- multi.h 21 Oct 2004 12:11:18 -0000 1.11
***************
*** 63,66 ****
--- 63,68 ----
virtual ~cMulti();
+ // This static function can be used to check if the given multi can be placed at the given position
+ static bool canPlace(const Coord_cl &pos, unsigned short multiid, QPtrList<cUObject> &moveOut, unsigned short yard = 5);
static void buildSqlString(const char *objectid, QStringList &fields, QStringList &tables, QStringList &conditions);
Index: server.h
===================================================================
RCS file: /cvsroot/wpdev/wolfpack/server.h,v
retrieving revision 1.6
retrieving revision 1.7
diff -C2 -d -r1.6 -r1.7
*** server.h 24 Sep 2004 04:47:37 -0000 1.6
--- server.h 21 Oct 2004 12:11:18 -0000 1.7
***************
*** 58,62 ****
\brief A server component.
*/
! class cComponent
{
private:
--- 58,62 ----
\brief A server component.
*/
! class WPEXPORT cComponent
{
private:
|