• 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!

[C++]walk through players or summons only if the cid is trapped

Jetro

jangeldev
Joined
Aug 1, 2011
Messages
452
Reaction score
68
Location
Venezuela
Hi all, tittle says all. Basically i want a code what allows a player to walk trough other players or players summons only if there are not way to pass in any directions.

Thanks in advance
Regards
 
open player.cpp

chance bool Player::canWalkthrough

to

Lua:
bool Player::canWalkthrough(const Creature* creature) const
{
	if(creature == this || creature->isWalkable() ||
		(creature->getMaster() && creature->getMaster() != this && canWalkthrough(creature->getMaster())))
		return true;
 
	const Player* player = creature->getPlayer();
	if(!player)
		return false;
 
	if(
		(
			(
				(
					(
						player->getVocation()->isAttackable() &&
						player->getLevel() < (uint32_t)g_config.getNumber(ConfigManager::PROTECTION_LEVEL)
					)
					|| (
						player->getTile()->hasFlag(TILESTATE_PROTECTIONZONE) &&
						!player->getTile()->hasFlag(TILESTATE_HOUSE)
					)
				)
			) && player->getTile()->ground &&
				player->getTile()->ground->getID() != 11063
		) && (
			!player->hasCustomFlag(PlayerCustomFlag_GamemasterPrivileges)
			|| player->getAccess() <= getAccess()
		)
	) return true;
 
	return (player->isGhost() && getGhostAccess() < player->getGhostAccess())
		|| (isGhost() && getGhostAccess() > player->getGhostAccess());
}
 
I dont know if what smsm posted is what you need. Basicly I wont write entire code for you, dont even count on that. I can just give you few directions.
First you need to check if createure can move in any direction, how to achive that?
Simple, each cylider class has method __queryAdd and _queryRemove, meaning of each (can add or can remove thing from cylinder)
So all you have to do is to tiles near player, check if it can be "added" there, if not you simple retrun true in ::canWalkThrough method and its all philosophy :)

Suggestions: create new method in Player class that check surrounding tiles, to not mess ::canWalkThrough method that much.


Thats all from me. I hope you will achive what you want. Its quite easy though.
 
Ok fine, what you will need, but still dont count I will give you f**king prepared clue, threat it like teaser ;D :

Code:
	static int32_t neighbourOrderList[8][2] =
	{
		{-1, 0},
		{0, 1},
		{1, 0},
		{0, -1},

		//diagonal
		{-1, -1},
		{1, -1},
		{1, 1},
		{-1, 1},
	};
Now you have to iterate through all elements of that array and use:
Map::getTile(int32_t x, int32_t y, int32_t z)
1. getPlayer position,
2. use neightbour offsets
3. getTile
4. check if player can be added to that tile
5. if all returns ERROR it means its blocked -> give that information to canWalkThrough :)

Have Fun.
 
I dont know if you managed to make that, but since I got bored I can give you untested thing.

New method:
Code:
bool Player::isBlocked(){
	int32_t n[8][2] =
	{
		{-1, 0},
		{0, 1},
		{1, 0},
		{0, -1},

		//diagonal
		{-1, -1},
		{1, -1},
		{1, 1},
		{-1, 1},
	};
	bool isBlocked = true;
	Position p = getPosition();
	for(uint8_t i = 0; i<= 7; i++){
		Tile* tile = g_game.getTile(p.x + n[i][1], p.y + n[i][2], p.z)
		ReturnValue ret = tile->__queryAdd(0, this, 1, 0);
		if(ret == RET_NOERROR)
			isBlocked = false;		
	}
}

And you should add somewhere in bool Player::canWalkthrough(const Creature* creature) const somewhere
Code:
  if isBlocked()
   return true;
 
well, it given 2 errors while compiling, first was solved adding const after Player::isBlocked(), the second was solved returning the boolean, then i added that function to Player::canWalkthrough and wherever i put it, it crash the server, idk why, because i've been reading game.cpp and i've found some lines that use something similar that you wrote (i mean checking player tile), idk why it's not working correctly.
 
Last edited:
Code:
bool Player::isBlocked(){
	int32_t n[8][2] =
	{
		{-1, 0},
		{0, 1},
		{1, 0},
		{0, -1},

		//diagonal
		{-1, -1},
		{1, -1},
		{1, 1},
		{-1, 1},
	};
	bool isBlocked = true;
	Position p = getPosition();
	for(uint8_t i = 0; i<= 7; i++){
		Tile* tile = g_game.getTile(p.x + n[i][1], p.y + n[i][2], p.z)
                if(tile){
		ReturnValue ret = tile->__queryAdd(0, this, 1, 0);
		if(ret == RET_NOERROR)
			isBlocked = false;	
                }
	
	}
  return isBlocked;
}
Prolly acces violation. try this out -> Sorry I totaly forgot to check that thread :$
 
Back
Top