getzonerule cleanup
This commit is contained in:
parent
e4fc6aad5a
commit
7aa35166ca
@ -856,8 +856,7 @@ ItemStatsValues* MasterItemList::CalculateItemBonuses(Item* item, Entity* entity
|
||||
{
|
||||
int32 diff = item->details.recommended_level - effective_level;
|
||||
float tmpValue = (float)value;
|
||||
int32 zone_id = entity->GetZone() ? entity->GetZone()->GetZoneID() : 0;
|
||||
value = (sint32)(float)(tmpValue / (1.0f + ((float)diff * rule_manager.GetZoneRule(zone_id, R_Player, MentorItemDecayRate)->GetFloat())));
|
||||
value = (sint32)(float)(tmpValue / (1.0f + ((float)diff * rule_manager.GetZoneRule(entity->GetZoneID(), R_Player, MentorItemDecayRate)->GetFloat())));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1851,8 +1850,7 @@ void Item::serialize(PacketStruct* packet, bool show_name, Player* player, int16
|
||||
packet->setSubstructDataByName("header_info", "unique_id", details.unique_id);
|
||||
packet->setSubstructDataByName("header_info", "icon", GetIcon(packet->GetVersion()));
|
||||
|
||||
int32 zone_id = player->GetZone() ? player->GetZone()->GetZoneID() : 0;
|
||||
if(rule_manager.GetZoneRule(zone_id, R_World, DisplayItemTiers)->GetBool()) {
|
||||
if(rule_manager.GetZoneRule(player->GetZoneID(), R_World, DisplayItemTiers)->GetBool()) {
|
||||
packet->setSubstructDataByName("header_info", "tier", details.tier);
|
||||
}
|
||||
packet->setSubstructDataByName("header_info", "flags", generic_info.item_flags);
|
||||
@ -1896,8 +1894,7 @@ void Item::serialize(PacketStruct* packet, bool show_name, Player* player, int16
|
||||
{
|
||||
int32 diff = details.recommended_level - effective_level;
|
||||
float tmpValue = (float)statValue;
|
||||
int32 zone_id = player->GetZone() ? player->GetZone()->GetZoneID() : 0;
|
||||
statValue = (sint32)(float)(tmpValue / (1.0f + ((float)diff * rule_manager.GetZoneRule(zone_id, R_Player, MentorItemDecayRate)->GetFloat())));
|
||||
statValue = (sint32)(float)(tmpValue / (1.0f + ((float)diff * rule_manager.GetZoneRule(player->GetZoneID(), R_Player, MentorItemDecayRate)->GetFloat())));
|
||||
}
|
||||
}
|
||||
|
||||
@ -2398,8 +2395,7 @@ void Item::serialize(PacketStruct* packet, bool show_name, Player* player, int16
|
||||
|
||||
// either don't require previous tier or check that we have the lower tier spells potentially
|
||||
int32 tier_up = player->GetTierUp(skill_info->spell_tier);
|
||||
int32 zone_id = player->GetZone() ? player->GetZone()->GetZoneID() : 0;
|
||||
if (!rule_manager.GetZoneRule(zone_id, R_Spells, RequirePreviousTierScribe)->GetInt8() || player->HasSpell(skill_info->spell_id, tier_up, false, true))
|
||||
if (!rule_manager.GetZoneRule(player->GetZoneID(), R_Spells, RequirePreviousTierScribe)->GetInt8() || player->HasSpell(skill_info->spell_id, tier_up, false, true))
|
||||
packet->setDataByName("require_previous", 1, 0);
|
||||
// membership required
|
||||
//packet->setDataByName("unknown_1188_2_MJ", 1, 1);
|
||||
@ -3824,8 +3820,7 @@ void PlayerItemList::AddItemToPacket(PacketStruct* packet, Player* player, Item*
|
||||
packet->setSubstructArrayDataByName("items", "item_level", item->details.recommended_level , 0, i);
|
||||
|
||||
|
||||
int32 zone_id = player->GetZone() ? player->GetZone()->GetZoneID() : 0;
|
||||
if(rule_manager.GetZoneRule(zone_id, R_World, DisplayItemTiers)->GetBool()) {
|
||||
if(rule_manager.GetZoneRule(player->GetZoneID(), R_World, DisplayItemTiers)->GetBool()) {
|
||||
packet->setSubstructArrayDataByName("items", "tier", item->details.tier, 0, i);
|
||||
}
|
||||
|
||||
@ -4397,8 +4392,7 @@ EQ2Packet* EquipmentItemList::serialize(int16 version, Player* player){
|
||||
packet->setSubstructArrayDataByName("items", "count", item->details.count, 0, i);
|
||||
// item level needed here
|
||||
|
||||
int32 zone_id = player->GetZone() ? player->GetZone()->GetZoneID() : 0;
|
||||
if(rule_manager.GetZoneRule(zone_id, R_World, DisplayItemTiers)->GetBool()) {
|
||||
if(rule_manager.GetZoneRule(player->GetZoneID(), R_World, DisplayItemTiers)->GetBool()) {
|
||||
packet->setSubstructArrayDataByName("items", "tier", item->details.tier, 0, i);
|
||||
}
|
||||
packet->setSubstructArrayDataByName("items", "num_slots", item->details.num_slots, 0, i);
|
||||
|
@ -345,7 +345,7 @@ void NPC::InCombat(bool val){
|
||||
}
|
||||
}
|
||||
|
||||
int8 ruleAutoLockEncounter = rule_manager.GetZoneRule(GetZone() ? GetZone()->GetZoneID() : 0, R_World, AutoLockEncounter)->GetInt8();
|
||||
int8 ruleAutoLockEncounter = rule_manager.GetZoneRule(GetZoneID(), R_World, AutoLockEncounter)->GetInt8();
|
||||
in_combat = val;
|
||||
if(val){
|
||||
LogWrite(NPC__DEBUG, 3, "NPC", "'%s' engaged in combat with '%s'", this->GetName(), ( GetTarget() ) ? GetTarget()->GetName() : "Unknown" );
|
||||
|
@ -395,7 +395,7 @@ vector<Entity*>* Brain::GetHateList() {
|
||||
|
||||
void Brain::MoveCloser(Spawn* target) {
|
||||
if (target && m_body->GetFollowTarget() != target)
|
||||
m_body->SetFollowTarget(target, rule_manager.GetZoneRule(m_body->GetZone() ? m_body->GetZone()->GetZoneID() : 0, R_Combat, MaxCombatRange)->GetFloat());
|
||||
m_body->SetFollowTarget(target, rule_manager.GetZoneRule(m_body->GetZoneID(), R_Combat, MaxCombatRange)->GetFloat());
|
||||
|
||||
if (m_body->GetFollowTarget() && !m_body->following) {
|
||||
m_body->CalculateRunningLocation(true);
|
||||
@ -478,7 +478,7 @@ bool Brain::CheckBuffs() {
|
||||
}
|
||||
|
||||
void Brain::ProcessMelee(Entity* target, float distance) {
|
||||
if(distance > rule_manager.GetZoneRule(m_body->GetZone() ? m_body->GetZone()->GetZoneID() : 0, R_Combat, MaxCombatRange)->GetFloat())
|
||||
if(distance > rule_manager.GetZoneRule(m_body->GetZoneID(), R_Combat, MaxCombatRange)->GetFloat())
|
||||
MoveCloser((Spawn*)target);
|
||||
else {
|
||||
if (target) {
|
||||
@ -581,12 +581,12 @@ bool Brain::CheckLootAllowed(Entity* entity) {
|
||||
LogWrite(LOOT__INFO, 0, "Loot", "%s: CheckLootAllowed failed, looter spawn id %u does not match received %s(%u)", GetBody()->GetName(), m_body->GetLooterSpawnID(), entity->GetName(), entity->GetID());
|
||||
return false;
|
||||
}
|
||||
if (rule_manager.GetZoneRule(m_body->GetZone() ? m_body->GetZone()->GetZoneID() : 0, R_Loot, AllowChestUnlockByDropTime)->GetInt8()
|
||||
&& m_body->GetChestDropTime() > 0 && Timer::GetCurrentTime2() >= m_body->GetChestDropTime() + (rule_manager.GetZoneRule(m_body->GetZone() ? m_body->GetZone()->GetZoneID() : 0, R_Loot, ChestUnlockedTimeDrop)->GetInt32() * 1000)) {
|
||||
if (rule_manager.GetZoneRule(m_body->GetZoneID(), R_Loot, AllowChestUnlockByDropTime)->GetInt8()
|
||||
&& m_body->GetChestDropTime() > 0 && Timer::GetCurrentTime2() >= m_body->GetChestDropTime() + (rule_manager.GetZoneRule(m_body->GetZoneID(), R_Loot, ChestUnlockedTimeDrop)->GetInt32() * 1000)) {
|
||||
return true;
|
||||
}
|
||||
if (rule_manager.GetZoneRule(m_body->GetZone() ? m_body->GetZone()->GetZoneID() : 0, R_Loot, AllowChestUnlockByTrapTime)->GetInt8()
|
||||
&& m_body->GetTrapOpenedTime() > 0 && Timer::GetCurrentTime2() >= m_body->GetChestDropTime() + (rule_manager.GetZoneRule(m_body->GetZone() ? m_body->GetZone()->GetZoneID() : 0, R_Loot, ChestUnlockedTimeTrap)->GetInt32() * 1000)) {
|
||||
if (rule_manager.GetZoneRule(m_body->GetZoneID(), R_Loot, AllowChestUnlockByTrapTime)->GetInt8()
|
||||
&& m_body->GetTrapOpenedTime() > 0 && Timer::GetCurrentTime2() >= m_body->GetChestDropTime() + (rule_manager.GetZoneRule(m_body->GetZoneID(), R_Loot, ChestUnlockedTimeTrap)->GetInt32() * 1000)) {
|
||||
return true;
|
||||
}
|
||||
if ((m_body->GetLootMethod() == GroupLootMethod::METHOD_LOTTO || m_body->GetLootMethod() == GroupLootMethod::METHOD_NEED_BEFORE_GREED) && m_body->HasSpawnLootWindowCompleted(entity->GetID())) {
|
||||
@ -770,7 +770,7 @@ void CombatPetBrain::Think() {
|
||||
float distance = GetBody()->GetDistance(target);
|
||||
|
||||
// If out of melee range then move closer
|
||||
if (distance > rule_manager.GetZoneRule(m_body->GetZone() ? m_body->GetZone()->GetZoneID() : 0, R_Combat, MaxCombatRange)->GetFloat())
|
||||
if (distance > rule_manager.GetZoneRule(m_body->GetZoneID(), R_Combat, MaxCombatRange)->GetFloat())
|
||||
MoveCloser((Spawn*)target);
|
||||
}
|
||||
|
||||
@ -802,7 +802,7 @@ void NonCombatPetBrain::Think() {
|
||||
float distance = GetBody()->GetDistance(target);
|
||||
|
||||
// If out of melee range then move closer
|
||||
if (distance > rule_manager.GetZoneRule(m_body->GetZone() ? m_body->GetZone()->GetZoneID() : 0, R_Combat, MaxCombatRange)->GetFloat())
|
||||
if (distance > rule_manager.GetZoneRule(m_body->GetZoneID(), R_Combat, MaxCombatRange)->GetFloat())
|
||||
MoveCloser((Spawn*)target);
|
||||
}
|
||||
|
||||
|
@ -826,13 +826,13 @@ EQ2Packet* PlayerInfo::serialize(int16 version, int16 modifyPos, int32 modifyVal
|
||||
packet->setDataByName("coins_plat", info_struct->get_coin_plat());// dov confirmed
|
||||
|
||||
Skill* skill = player->GetSkillByName("Swimming", false);
|
||||
float breath_modifier = rule_manager.GetZoneRule(player->GetZone() ? player->GetZone()->GetZoneID() : 0, R_Player, SwimmingSkillMinBreathLength)->GetFloat();
|
||||
float breath_modifier = rule_manager.GetZoneRule(player->GetZoneID(), R_Player, SwimmingSkillMinBreathLength)->GetFloat();
|
||||
if(skill) {
|
||||
int32 max_val = 450;
|
||||
if(skill->max_val > 0)
|
||||
max_val = skill->max_val;
|
||||
float diff = (float)(skill->current_val + player->GetStat(ITEM_STAT_SWIMMING)) / (float)max_val;
|
||||
float max_breath_mod = rule_manager.GetZoneRule(player->GetZone() ? player->GetZone()->GetZoneID() : 0, R_Player, SwimmingSkillMaxBreathLength)->GetFloat();
|
||||
float max_breath_mod = rule_manager.GetZoneRule(player->GetZoneID(), R_Player, SwimmingSkillMaxBreathLength)->GetFloat();
|
||||
float diff_mod = max_breath_mod * diff;
|
||||
if(diff_mod > max_breath_mod)
|
||||
breath_modifier = max_breath_mod;
|
||||
@ -4849,7 +4849,7 @@ vector<Quest*>* Player::CheckQuestsLocationUpdate(){
|
||||
map<int32, Quest*>::iterator itr;
|
||||
MPlayerQuests.readlock(__FUNCTION__, __LINE__);
|
||||
for(itr = player_quests.begin(); itr != player_quests.end(); itr++){
|
||||
if(itr->second && itr->second->CheckQuestLocationUpdate(GetX(), GetY(), GetZ(), (GetZone() ? GetZone()->GetZoneID() : 0))){
|
||||
if(itr->second && itr->second->CheckQuestLocationUpdate(GetX(), GetY(), GetZ(), (GetZoneID()))){
|
||||
if(!quest_updates)
|
||||
quest_updates = new vector<Quest*>();
|
||||
quest_updates->push_back(itr->second);
|
||||
@ -6835,7 +6835,7 @@ bool Player::CanSeeInvis(Entity* target)
|
||||
else if (target->IsInvis() && HasSeeInvisSpell())
|
||||
return true;
|
||||
|
||||
sint32 radius = rule_manager.GetZoneRule(GetZone() ? GetZone()->GetZoneID() : 0, R_PVP, InvisPlayerDiscoveryRange)->GetSInt32();
|
||||
sint32 radius = rule_manager.GetZoneRule(GetZoneID(), R_PVP, InvisPlayerDiscoveryRange)->GetSInt32();
|
||||
|
||||
if (radius == 0) // radius of 0 is always seen
|
||||
return true;
|
||||
@ -7512,7 +7512,7 @@ void Player::CalculatePlayerHPPower(int16 new_level) {
|
||||
|
||||
bool Player::IsAllowedCombatEquip(int8 slot, bool send_message) {
|
||||
bool rule_pass = true;
|
||||
if(EngagedInCombat() && rule_manager.GetZoneRule(GetZone() ? GetZone()->GetZoneID() : 0, R_Player, AllowPlayerEquipCombat)->GetInt8() == 0) {
|
||||
if(EngagedInCombat() && rule_manager.GetZoneRule(GetZoneID(), R_Player, AllowPlayerEquipCombat)->GetInt8() == 0) {
|
||||
switch(slot) {
|
||||
case EQ2_PRIMARY_SLOT:
|
||||
case EQ2_SECONDARY_SLOT:
|
||||
|
@ -2370,7 +2370,7 @@ void Spawn::InitializeInfoPacketData(Player* spawn, PacketStruct* packet) {
|
||||
|
||||
int8 classicFlags = 0;
|
||||
// radius of 0 is always seen, -1 is never seen (unless items/spells override), larger than 0 is a defined radius to restrict visibility
|
||||
sint32 radius = rule_manager.GetZoneRule(GetZone() ? GetZone()->GetZoneID() : 0, R_PVP, InvisPlayerDiscoveryRange)->GetSInt32();
|
||||
sint32 radius = rule_manager.GetZoneRule(GetZoneID(), R_PVP, InvisPlayerDiscoveryRange)->GetSInt32();
|
||||
if (radius != 0 && (Spawn*)spawn != this && this->IsPlayer() && !spawn->CanSeeInvis((Entity*)this))
|
||||
spawnHiddenFromClient = true;
|
||||
|
||||
@ -3101,20 +3101,20 @@ void Spawn::ProcessMovement(bool isSpawnListLocked){
|
||||
|
||||
float dist = GetDistance(followTarget, true);
|
||||
if ((!EngagedInCombat() && m_followDistance > 0 && dist <= m_followDistance) ||
|
||||
(dist <= rule_manager.GetZoneRule(GetZone() ? GetZone()->GetZoneID() : 0, R_Combat, MaxCombatRange)->GetFloat())) {
|
||||
(dist <= rule_manager.GetZoneRule(GetZoneID(), R_Combat, MaxCombatRange)->GetFloat())) {
|
||||
ClearRunningLocations();
|
||||
CalculateRunningLocation(true);
|
||||
}
|
||||
else if (loc) {
|
||||
float distance = GetDistance(followTarget, loc->x, loc->y, loc->z);
|
||||
if ( (!EngagedInCombat() && m_followDistance > 0 && distance > m_followDistance) ||
|
||||
( EngagedInCombat() && distance > rule_manager.GetZoneRule(GetZone() ? GetZone()->GetZoneID() : 0, R_Combat, MaxCombatRange)->GetFloat())) {
|
||||
MoveToLocation(followTarget, rule_manager.GetZoneRule(GetZone() ? GetZone()->GetZoneID() : 0, R_Combat, MaxCombatRange)->GetFloat(), true, loc->mapped);
|
||||
( EngagedInCombat() && distance > rule_manager.GetZoneRule(GetZoneID(), R_Combat, MaxCombatRange)->GetFloat())) {
|
||||
MoveToLocation(followTarget, rule_manager.GetZoneRule(GetZoneID(), R_Combat, MaxCombatRange)->GetFloat(), true, loc->mapped);
|
||||
CalculateRunningLocation();
|
||||
}
|
||||
}
|
||||
else {
|
||||
MoveToLocation(followTarget, rule_manager.GetZoneRule(GetZone() ? GetZone()->GetZoneID() : 0, R_Combat, MaxCombatRange)->GetFloat(), false);
|
||||
MoveToLocation(followTarget, rule_manager.GetZoneRule(GetZoneID(), R_Combat, MaxCombatRange)->GetFloat(), false);
|
||||
CalculateRunningLocation();
|
||||
}
|
||||
}
|
||||
@ -3378,7 +3378,7 @@ void Spawn::RunToLocation(float x, float y, float z, float following_x, float fo
|
||||
return;
|
||||
}
|
||||
|
||||
if(!IsWidget() && (!EngagedInCombat() || GetDistance(GetTarget()) > rule_manager.GetZoneRule(GetZone() ? GetZone()->GetZoneID() : 0, R_Combat, MaxCombatRange)->GetFloat()))
|
||||
if(!IsWidget() && (!EngagedInCombat() || GetDistance(GetTarget()) > rule_manager.GetZoneRule(GetZoneID(), R_Combat, MaxCombatRange)->GetFloat()))
|
||||
FaceTarget(x, z);
|
||||
SetPos(&appearance.pos.X2, x, false);
|
||||
SetPos(&appearance.pos.Z2, z, false);
|
||||
@ -3669,7 +3669,7 @@ void Spawn::CalculateRunningLocation(bool stop){
|
||||
|
||||
if (continueElseIf && GetZone() && GetTarget() != NULL && EngagedInCombat())
|
||||
{
|
||||
if (GetDistance(GetTarget()) > rule_manager.GetZoneRule(GetZone() ? GetZone()->GetZoneID() : 0, R_Combat, MaxCombatRange)->GetFloat())
|
||||
if (GetDistance(GetTarget()) > rule_manager.GetZoneRule(GetZoneID(), R_Combat, MaxCombatRange)->GetFloat())
|
||||
{
|
||||
if ((IsFlyingCreature() || IsWaterCreature() || InWater()) && CheckLoS(GetTarget()))
|
||||
AddRunningLocation(GetTarget()->GetX(), GetTarget()->GetY(), GetTarget()->GetZ(), GetSpeed(), 0, false);
|
||||
@ -3957,7 +3957,7 @@ void Spawn::CheckEncounterState(Entity* victim, bool test_auto_lock) {
|
||||
attacker->GetInfoStruct()->set_engaged_encounter(1);
|
||||
}
|
||||
|
||||
int8 skip_loot_gray_mob_flag = rule_manager.GetZoneRule(GetZone() ? GetZone()->GetZoneID() : 0, R_Loot, SkipLootGrayMob)->GetInt8();
|
||||
int8 skip_loot_gray_mob_flag = rule_manager.GetZoneRule(GetZoneID(), R_Loot, SkipLootGrayMob)->GetInt8();
|
||||
|
||||
int8 difficulty = attacker->GetArrowColor(victim->GetLevel());
|
||||
|
||||
@ -4755,7 +4755,7 @@ bool Spawn::IsWaterCreature()
|
||||
|
||||
|
||||
void Spawn::SetFlyingCreature() {
|
||||
if(!IsEntity() || !rule_manager.GetZoneRule(GetZone() ? GetZone()->GetZoneID() : 0, R_Spawn, UseHardCodeFlyingModelType)->GetInt8())
|
||||
if(!IsEntity() || !rule_manager.GetZoneRule(GetZoneID(), R_Spawn, UseHardCodeFlyingModelType)->GetInt8())
|
||||
return;
|
||||
|
||||
if(((Entity*)this)->GetInfoStruct()->get_flying_type() > 0) // DB spawn npc flag already set
|
||||
@ -4775,7 +4775,7 @@ void Spawn::SetFlyingCreature() {
|
||||
}
|
||||
|
||||
void Spawn::SetWaterCreature() {
|
||||
if(!IsEntity() || !rule_manager.GetZoneRule(GetZone() ? GetZone()->GetZoneID() : 0, R_Spawn, UseHardCodeWaterModelType)->GetInt8())
|
||||
if(!IsEntity() || !rule_manager.GetZoneRule(GetZoneID(), R_Spawn, UseHardCodeWaterModelType)->GetInt8())
|
||||
return;
|
||||
|
||||
if(((Entity*)this)->GetInfoStruct()->get_water_type() > 0) // DB spawn npc flag already set
|
||||
@ -5053,13 +5053,13 @@ bool Spawn::HasLootWindowCompleted() {
|
||||
|
||||
void Spawn::StartLootTimer(Spawn* looter) {
|
||||
if (!IsLootTimerRunning()) {
|
||||
int32 loot_timer_time = rule_manager.GetZoneRule(GetZone() ? GetZone()->GetZoneID() : 0, R_Loot, LootDistributionTime)->GetInt32() * 1000;
|
||||
if(rule_manager.GetZoneRule(GetZone() ? GetZone()->GetZoneID() : 0, R_Loot, AllowChestUnlockByDropTime)->GetBool() && loot_timer_time > rule_manager.GetZoneRule(GetZone() ? GetZone()->GetZoneID() : 0, R_Loot, ChestUnlockedTimeDrop)->GetInt32()*1000) {
|
||||
loot_timer_time = (rule_manager.GetZoneRule(GetZone() ? GetZone()->GetZoneID() : 0, R_Loot, ChestUnlockedTimeDrop)->GetInt32()*1000) / 2;
|
||||
int32 loot_timer_time = rule_manager.GetZoneRule(GetZoneID(), R_Loot, LootDistributionTime)->GetInt32() * 1000;
|
||||
if(rule_manager.GetZoneRule(GetZoneID(), R_Loot, AllowChestUnlockByDropTime)->GetBool() && loot_timer_time > rule_manager.GetZoneRule(GetZoneID(), R_Loot, ChestUnlockedTimeDrop)->GetInt32()*1000) {
|
||||
loot_timer_time = (rule_manager.GetZoneRule(GetZoneID(), R_Loot, ChestUnlockedTimeDrop)->GetInt32()*1000) / 2;
|
||||
}
|
||||
|
||||
if(rule_manager.GetZoneRule(GetZone() ? GetZone()->GetZoneID() : 0, R_Loot, AllowChestUnlockByTrapTime)->GetBool() && loot_timer_time > rule_manager.GetZoneRule(GetZone() ? GetZone()->GetZoneID() : 0, R_Loot, ChestUnlockedTimeTrap)->GetInt32()*1000) {
|
||||
loot_timer_time = (rule_manager.GetZoneRule(GetZone() ? GetZone()->GetZoneID() : 0, R_Loot, ChestUnlockedTimeTrap)->GetInt32()*1000) / 2;
|
||||
if(rule_manager.GetZoneRule(GetZoneID(), R_Loot, AllowChestUnlockByTrapTime)->GetBool() && loot_timer_time > rule_manager.GetZoneRule(GetZoneID(), R_Loot, ChestUnlockedTimeTrap)->GetInt32()*1000) {
|
||||
loot_timer_time = (rule_manager.GetZoneRule(GetZoneID(), R_Loot, ChestUnlockedTimeTrap)->GetInt32()*1000) / 2;
|
||||
}
|
||||
|
||||
if(loot_timer_time < 1000) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user