void Player:nAttackedCreature(Creature* target)
{
Creature:nAttackedCreature(target);
if(hasFlag(PlayerFlag_NotGainInFight))
return;
addInFightTicks();
Player* targetPlayer = target->getPlayer();
if(!targetPlayer)
return;
addAttacked(targetPlayer);
if(targetPlayer == this && targetPlayer->getZone() != ZONE_PVP)
{
targetPlayer->sendCreatureSkull(this);
return;
}
if(Combat::isInPvpZone(this, targetPlayer) || isPartner(targetPlayer) || (g_config.getBool(
ConfigManager::ALLOW_FIGHTBACK) && targetPlayer->hasAttacked(this)))
return;
if(!pzLocked)
{
pzLocked = true;
sendIcons();
}
if(getZone() != target->getZone())
return;
if(skull == SKULL_NONE)
{
if(targetPlayer->getSkull() != SKULL_NONE)
targetPlayer->sendCreatureSkull(this);
else if(!hasCustomFlag(PlayerCustomFlag_NotGainSkull))
{
setSkull(SKULL_WHITE);
g_game.updateCreatureSkull(this);
}
}
}
bool Player:nKilledCreature(Creature* target, uint32_t& flags)
{
if(!Creature:nKilledCreature(target, flags))
return false;
if(hasFlag(PlayerFlag_NotGenerateLoot))
target->setDropLoot(LOOT_DROP_NONE);
Condition* condition = NULL;
if(target->getMonster() && !target->isPlayerSummon() && !hasFlag(PlayerFlag_HasInfiniteStamina)
&& (condition = Condition::createCondition(CONDITIONID_DEFAULT, CONDITION_HUNTING,
g_config.getNumber(ConfigManager::HUNTING_DURATION))))
addCondition(condition);
if(hasFlag(PlayerFlag_NotGainInFight) || !hasBitSet((uint32_t)KILLFLAG_JUSTIFY, flags) || getZone() != target->getZone())
return true;
Player* targetPlayer = target->getPlayer();
if(!targetPlayer || Combat::isInPvpZone(this, targetPlayer) || !hasCondition(CONDITION_INFIGHT) || isPartner(targetPlayer))
return true;
if(!targetPlayer->hasAttacked(this) && target->getSkull() == SKULL_NONE && targetPlayer != this
&& ((g_config.getBool(ConfigManager::USE_FRAG_HANDLER) && addUnjustifiedKill(
targetPlayer)) || hasBitSet((uint32_t)KILLFLAG_LASTHIT, flags)))
flags |= (uint32_t)KILLFLAG_UNJUSTIFIED;
pzLocked = true;
if((condition = Condition::createCondition(CONDITIONID_DEFAULT, CONDITION_INFIGHT,
g_config.getNumber(ConfigManager::WHITE_SKULL_TIME))))
addCondition(condition);
return true;
}
Skulls_t Player::getSkullClient(const Creature* creature) const
{
if(const Player* player = creature->getPlayer())
{
if(g_game.getWorldType() != WORLD_TYPE_PVP)
return SKULL_NONE;
if((player == this || (skull != SKULL_NONE && player->getSkull() < SKULL_RED)) && player->hasAttacked(this))
return SKULL_YELLOW;
if(player->getSkull() == SKULL_NONE && isPartner(player) && g_game.getWorldType() != WORLD_TYPE_NO_PVP)
return SKULL_GREEN;
}
return Creature::getSkullClient(creature);
}
void Player::setSkullEnd(time_t _time, bool login, Skulls_t _skull)
{
if(g_game.getWorldType() == WORLD_TYPE_PVP_ENFORCED)
return;
bool requireUpdate = false;
if(_time > time(NULL))
{
requireUpdate = true;
setSkull(_skull);
}
else if(skull == _skull)
{
requireUpdate = true;
setSkull(SKULL_NONE);
_time = 0;
}
if(requireUpdate)
{
skullEnd = _time;
if(!login)
g_game.updateCreatureSkull(this);
}
}
bool Player::addUnjustifiedKill(const Player* attacked)
{
if(g_game.getWorldType() == WORLD_TYPE_PVP_ENFORCED || attacked == this || hasFlag(
PlayerFlag_NotGainInFight) || hasCustomFlag(PlayerCustomFlag_NotGainSkull))
return false;
if(client)
{
char buffer[90];
sprintf(buffer, "Warning! The murder of %s was not justified.",
attacked->getName().c_str());
client->sendTextMessage(MSG_STATUS_WARNING, buffer);
}
time_t now = time(NULL), today = (now - 84600), week = (now - (7 * 84600));
std::vector<time_t> dateList;
IOLoginData::getInstance()->getUnjustifiedDates(guid, dateList, now);
dateList.push_back(now);
uint32_t tc = 0, wc = 0, mc = dateList.size();
for(std::vector<time_t>::iterator it = dateList.begin(); it != dateList.end(); ++it)
{
if((*it) > week)
wc++;
if((*it) > today)
tc++;
}
uint32_t d = g_config.getNumber(ConfigManager::RED_DAILY_LIMIT), w = g_config.getNumber(
ConfigManager::RED_WEEKLY_LIMIT), m = g_config.getNumber(ConfigManager::RED_MONTHLY_LIMIT);
if(skull < SKULL_RED && ((d > 0 && tc >= d) || (w > 0 && wc >= w) || (m > 0 && mc >= m)))
setSkullEnd(now + g_config.getNumber(ConfigManager::RED_SKULL_LENGTH), false, SKULL_RED);
if(!g_config.getBool(ConfigManager::USE_BLACK_SKULL))
{
d += g_config.getNumber(ConfigManager::BAN_DAILY_LIMIT);
w += g_config.getNumber(ConfigManager::BAN_WEEKLY_LIMIT);
m += g_config.getNumber(ConfigManager::BAN_MONTHLY_LIMIT);
if((d <= 0 || tc < d) && (w <= 0 || wc < w) && (m <= 0 || mc < m))
return true;
if(!IOBan::getInstance()->addAccountBanishment(accountId, (now + g_config.getNumber(
ConfigManager::KILLS_BAN_LENGTH)), 20, ACTION_BANISHMENT, "Unjustified player killing.", 0, guid))
return true;
sendTextMessage(MSG_INFO_DESCR, "You have been banished.");
g_game.addMagicEffect(getPosition(), MAGIC_EFFECT_WRAPS_GREEN);
Scheduler::getInstance().addEvent(createSchedulerTask(1000, boost::bind(
&Game::kickPlayer, &g_game, getID(), false)));
}
else
{
d += g_config.getNumber(ConfigManager::BLACK_DAILY_LIMIT);
w += g_config.getNumber(ConfigManager::BLACK_WEEKLY_LIMIT);
m += g_config.getNumber(ConfigManager::BLACK_MONTHLY_LIMIT);
if(skull < SKULL_BLACK && ((d > 0 && tc >= d) || (w > 0 && wc >= w) || (m > 0 && mc >= m)))
{
setSkullEnd(now + g_config.getNumber(ConfigManager::BLACK_SKULL_LENGTH), false, SKULL_BLACK);
setAttackedCreature(NULL);
destroySummons();
}
}
return true;
}