• There is NO official Otland's Discord server and NO official Otland's server list. The Otland's Staff does not manage any Discord server or server list. Moderators or administrator of any Discord server or server lists have NO connection to the Otland's Staff. Do not get scammed!

Combat/PvP Zoning

Vagabond

New Member
Joined
Oct 5, 2007
Messages
242
Reaction score
0
In case you don't already know what Combat/PvP Zoning is, it's a feature I first made a few months back that allows you to have certain areas where pvp is allowed, and certain areas where pvp is unallowed, and even certain areas where you can get experience from pvp (pvp-enforced).

now, onto the code!


at the bottom of game.cpp:
Code:
#ifdef __COMBAT_ZONES__
bool Game::loadCombatZones()
{
    xmlDocPtr doc = xmlParseFile(std::string(g_config.getString(ConfigManager::DATA_DIRECTORY) + "pvpzones.xml").c_str());
    if(!doc)
        return false;
    xmlNodePtr root, zone, tiles;
    root = xmlDocGetRootElement(doc);
    if(xmlStrcmp(root->name,(const xmlChar*)"zones"))
    {
        puts("MALFORMED PVP ZONES XML FILE!");
        return false;
    }
    zone = root->children;
    while(zone)
    {
        if(!xmlStrcmp(zone->name,(const xmlChar*)"zone"))
        {
            tileflags_t pvplvl = TILESTATE_NONE;
            std::string strlvl;
            if(!readXMLString(zone, "pvp", strlvl))
            {
                puts("ERROR: pvp zone missing pvp level!");
                continue;
            }
            toLowerCaseString(strlvl);
            if(strlvl == "none" || strlvl == "no" || strlvl == "nopvp" || strlvl == "0")
                pvplvl = TILESTATE_NOPVP;
            else if(strlvl == "yes" || strlvl == "normal" || strlvl == "pvp" || strlvl == "1")
                pvplvl = TILESTATE_PVP;
            else if(strlvl == "enforced" || strlvl == "e" || strlvl == "pvp-enforced" || strlvl == "2")
                pvplvl = TILESTATE_PVP_ENFORCED;
            else
            {
                printf("ERROR: invalid pvp level: %s\n", strlvl.c_str());
                continue;
            }
            tiles = zone->children;
            while(tiles)
            {
                if(!xmlStrcmp(tiles->name,(const xmlChar*)"tile"))
                {
                   int x, y, z;
                   if(readXMLInteger(tiles,"x",x)
                      && readXMLInteger(tiles,"y",y)
                      && readXMLInteger(tiles,"z",z))
                   {
                          Tile* t = map->getTile(x, y, z);
                          if(t)
                              t->setFlag(pvplvl);
                   }
                }
                else if(!xmlStrcmp(tiles->name,(const xmlChar*)"tiles"))
                {
                   int tox, toy, toz, fromx, fromy, fromz;
                   if(readXMLInteger(tiles,"tox",tox)
                      && readXMLInteger(tiles,"toy",toy)
                      && readXMLInteger(tiles,"toz",toz)
                      && readXMLInteger(tiles,"fromx",fromx)
                      && readXMLInteger(tiles,"fromy",fromy)
                      && readXMLInteger(tiles,"fromz",fromz))
                   {
                        if(tox < fromx)
                            std::swap(tox, fromx);
                        if(toy < fromy)
                            std::swap(toy, fromy);
                        if(toz < fromz)
                            std::swap(toz, fromz);
                        for(int x = fromx; x <= tox; x++)
                        {
                           for(int y = fromy; y <= toy; y++)
                           {
                              for(int z = fromz; z <= toz; z++)
                              {
                                  Tile* t = map->getTile(x, y, z);
                                  if(t)
                                      t->setFlag(pvplvl);
                              }
                           }
                        }
                   }
                }
                tiles = tiles->next;
            }
        }
        zone = zone->next;
    }
    
    return true;
}
#endif //__COMBAT_ZONES__





in game.h, replace:
WorldType_t getWorldType() const {return worldType;}
with:
Code:
#ifndef __COMBAT_ZONES__
	WorldType_t getWorldType() const {return worldType;}
	#else
	WorldType_t getWorldType(const Creature* attacker = NULL, const Creature* target = NULL) const
	{
        if(!attacker || !target)
            return worldType;
        
        if(attacker->getPlayer() && target->getPlayer())
        {
            if(attacker->getTile()->hasFlag(TILESTATE_PVP_ENFORCED) && target->getTile()->hasFlag(TILESTATE_PVP_ENFORCED))
                    return WORLD_TYPE_PVP_ENFORCED;
            else if(attacker->getTile()->hasFlag(TILESTATE_PVP) && target->getTile()->hasFlag(TILESTATE_PVP))
                    return WORLD_TYPE_PVP;
            else if(attacker->getTile()->hasFlag(TILESTATE_NOPVP) || target->getTile()->hasFlag(TILESTATE_NOPVP))
                    return WORLD_TYPE_NO_PVP;
        }
        
        return worldType;
    }
    
    bool loadCombatZones();
	#endif //__COMBAT_ZONES__






in tile.h, after:
TILESTATE_FLOORCHANGE_WEST = 128
paste:
Code:
#ifdef __COMBAT_ZONES__
	, TILESTATE_NOPVP = 256,
	TILESTATE_PVP = 512,
	TILESTATE_PVP_ENFORCED = 1024,
	#endif //__COMBAT_ZONES__

in combat.cpp, replace:
if(g_game.getWorldType() == WORLD_TYPE_NO_PVP){
with:
Code:
if(g_game.getWorldType(
    #ifdef __COMBAT_ZONES__
    attacker, target
    #endif //__COMBAT_ZONES__
    ) == WORLD_TYPE_NO_PVP){






in player.cpp, in function Player::getGainedExperience, replace:
if(g_game.getWorldType() == WORLD_TYPE_PVP_ENFORCED){
with:
Code:
if(g_game.getWorldType(
    #ifdef __COMBAT_ZONES__
    attacker, this
    #endif //__COMBAT_ZONES__
    ) == WORLD_TYPE_PVP_ENFORCED){





in otserv.cpp, after:
if(!g_game.loadMap(g_config.getString(ConfigManager::MAP_FILE), g_config.getString(ConfigManager::MAP_KIND))){
return -1;
}
paste:
Code:
#ifdef __COMBAT_ZONES__
	if(g_game.loadCombatZones())
	    puts(":: Loaded Combat Zones!");
	#endif //__COMBAT_ZONES__


add -D__COMBAT_ZONES__ to C++ Compiler paramaters and rebuild all.


note: SVN's skullsystem code currently gives you skull and unjust kill on PVP-E worlds. This will also be the case with a PVP-E zone.


==============================================
Usage
==============================================

1) First, create a new file in your DATA directory named pvpzones.xml. (copy and rename a current xml file if you wish)
2) Open this file and clean its contents (if it has any).
3) paste this:
Code:
<zones>

<!-- no pvp -->
<zone pvp="0">
 
</zone>

<!-- pvp -->
<zone pvp="1">
 
</zone>

<!-- pvp-e -->
<zone pvp="2">
 
</zone>
</zones>
into the file

4) The first "zone" has 0 pvp, or no-pvp. Add all no-pvp tiles there. The second has 1 pvp, or normal pvp. The Third has 2 pvp, or pvp-enforced. To add tiles:
4a) For individual Tiles, create a tag like this:
Code:
<tile x="x" y="y" z="z"/>
Replace x, y, and z with the coordinates of the tile.
4b) For a rectangular group of tiles, create a tag like this:
Code:
<tiles fromx="x1" fromy="y1" fromz="z1" tox="x2" toy="y2" toz="z2" />
Replace x1, y1, and z1 with the coordinates of the northwest-most tile on the lowest floor. Replace x2, y2, and z2 with the coordinates of the southeast-most tile on the highest floor.
 
Last edited:
don't see why it wouldn't, I doubt they've moved around the combat stuff.

but wait a sec, I got a small bugfix. :p
 
Wuuuhu, succesfully compiled :d

And it works!

But if someone don't know a little C++ he will be notable to compile this to Forgotten.

Now i'm making PvP Arena :d
 
xmlDocPtr doc = xmlParseFile(std::string(g_config.getString(ConfigManager::DATA_DIRECTORY) + "pvpzones.xml").c_str());

that line is giving me error

../game.cpp: In member function `bool Game::loadCombatZones()':
../game.cpp:3967: error: `DATA_DIRECTORY' is not a member of `ConfigManager'

make.exe: *** [../game.o] Error 1

i changed it to

xmlDocPtr doc = xmlParseFile("data/XML/pvpzones.xml");


a huge list of erros like ../actions.o(.text+0x2d1e):actions.cpp: undefined reference to `lua_pushnumber'
 
okau i fixed but getting a bunch of errors and somone said its was my linkers so does anyone know what i have to put rite now i have

C++ compiler:
-D__USE_MYSQL__
-D__USE_SQLITE__
-D__RULEVIOLATIONREPORTS__
-D__COMBAT_ZONES__

Linker:
-lmysql
-lregex
-lsqlite3
-lwsock32
-lxml2
-lmysql
-lws2_32
-lboost-system-mgw-1_34_1
-s

Libary Directories:
C:\Dev-Cpp\others\boost_1_33_1\libregex
C:\Dev-Cpp\others\lua-5.1\lib

Include Directories:
C:\Dev-Cpp\others\boost_1_33_1
C:\Dev-Cpp\others\lua-5.1\include
 
I compiled, and it works, but...
When i trying log into my char serwer crashes, when i put in <tile x="x" y="y" z="z"/> cords serwer crashes, so whats going on ?:D
 
can somone plese tell what im doing wrong it commpiled and rune but the pvp zones dont work and. I can take out the file pvpzones.xml ad it doesnt tell me that it cant find pvpzones.xml and also players dont get exp when server set to pvp-e. im using the forgotten server 0.2.6
 
it should work with TFS 0.2.6. It won't work with any version of Evo because Evo's outdated as shit and doesn't have some of the code I told you.
 
Last edited:
A good code, but when Remere release the sources of RME, it will be good to edit it and edit this code to make in the editor.
 
Back
Top