if(this->Data()->type == ENF::Pet)
{
UTIL_PTR_LIST_FOREACH(this->map->characters, Character, character)
{
UTIL_PTR_VECTOR_FOREACH(this->map->npcs, NPC, npc)
{
int distance = util::path_length(npc->x, npc->y, this->x, this->y);
int distance1 = util::path_length(this->owner->x, this->owner->y, this->x, this->y);
if(distance1 > 5 && !attacker)
{
int xdiff = this->x - this->owner->x;
int ydiff = this->y - this->owner->y;
int absxdiff = std::abs(xdiff);
int absydiff = std::abs(ydiff);
if ((absxdiff == 1 && absydiff == 0) || (absxdiff == 0 && absydiff == 1) || (absxdiff == 0 && absydiff == 0))
{
//if(attacker != this->owner)
//this->Attack(this->owner);
return;
}
else if (absxdiff > absydiff)
{
if (xdiff < 0)
{
this->direction = DIRECTION_RIGHT;
}
else
{
this->direction = DIRECTION_LEFT;
}
}
else
{
if (ydiff < 0)
{
this->direction = DIRECTION_DOWN;
}
else
{
this->direction = DIRECTION_UP;
}
}
if (!this->Walk(this->direction))
{
this->Walk(static_cast<Direction>(util::rand(0,3)));
}
return;
}
else if (npc->Data()->type == ENF::Aggressive && distance > 1 && distance < 5 && !attacker && npc->alive) //?
{
int xdiff = this->x - npc->x;
int ydiff = this->y - npc->y;
int absxdiff = std::abs(xdiff);
int absydiff = std::abs(ydiff);
if ((absxdiff == 1 && absydiff == 0) || (absxdiff == 0 && absydiff == 1) || (absxdiff == 0 && absydiff == 0))
{
//if(attacker != this->owner)
//this->Attack(this->owner);
return;
}
else if (absxdiff > absydiff)
{
if (xdiff < 0)
{
this->direction = DIRECTION_RIGHT;
}
else
{
this->direction = DIRECTION_LEFT;
}
}
else
{
if (ydiff < 0)
{
this->direction = DIRECTION_DOWN;
}
else
{
this->direction = DIRECTION_UP;
}
}
if (!this->Walk(this->direction))
{
this->Walk(static_cast<Direction>(util::rand(0,3)));
}
return;
}
else if (this->map->arena && npc->Data()->type == ENF::Pet && distance > 1 && distance < 5 && npc->alive) //?
{
int xdiff = this->x - npc->x;
int ydiff = this->y - npc->y;
int absxdiff = std::abs(xdiff);
int absydiff = std::abs(ydiff);
if ((absxdiff == 1 && absydiff == 0) || (absxdiff == 0 && absydiff == 1) || (absxdiff == 0 && absydiff == 0))
{
//if(attacker != this->owner)
//this->Attack(this->punk);
return;
}
else if (absxdiff > absydiff)
{
if (xdiff < 0)
{
this->direction = DIRECTION_RIGHT;
}
else
{
this->direction = DIRECTION_LEFT;
}
}
else
{
if (ydiff < 0)
{
this->direction = DIRECTION_DOWN;
}
else
{
this->direction = DIRECTION_UP;
}
}
if (!this->Walk(this->direction))
{
this->Walk(static_cast<Direction>(util::rand(0,3)));
}
return;
}
if((this->map->arena && npc->Data()->type == ENF::Pet) && distance > 0 && distance < 2 && npc->alive)
{
if( distance > 0 && distance < 2)
{
int xdiff = this->x - npc->x;
int ydiff = this->y - npc->y;
if (std::abs(xdiff) > std::abs(ydiff))
{
if (xdiff < 0)
{
this->direction = DIRECTION_RIGHT;
}
else
{
this->direction = DIRECTION_LEFT;
}
}
else
{
if (ydiff < 0)
{
this->direction = DIRECTION_DOWN;
}
else
{
this->direction = DIRECTION_UP;
}
}
PacketBuilder builder(PACKET_NPC, PACKET_PLAYER);
builder.AddByte(255);
builder.AddChar(this->index);
builder.AddChar(1 + (character->hp == 0));
builder.AddChar(this->direction);
builder.AddShort(0);
builder.AddThree(0);
builder.AddThree(int(double(character->hp) / double(character->maxhp) * 100.0));
builder.AddByte(255);
builder.AddByte(255);
UTIL_PTR_LIST_FOREACH(this->map->characters, Character, character)
{
if (*character == this->owner || !character->InRange(this))
{
continue;
}
character->player->client->SendBuilder(builder);
}
this->owner->player->client->SendBuilder(builder);
}
int amount = util::rand(this->Data()->mindam, this->Data()->maxdam + static_cast<int>(this->map->world->config["NPCAdjustMaxDam"]));
double rand = util::rand(0.0, 1.0);
// Checks if target is facing you
bool critical = std::abs(int(npc->direction) - this->owner->direction) != 2 || rand < static_cast<double>(this->map->world->config["CriticalRate"]);
std::tr1::unordered_map<std::string, double> formula_vars;
this->owner->FormulaVars(formula_vars);
npc->FormulaVars(formula_vars, "target_");
formula_vars["modifier"] = this->map->world->config["MobRate"];
formula_vars["damage"] = amount;
formula_vars["critical"] = critical;
amount = rpn_eval(rpn_parse(this->map->world->formulas_config["damage"]), formula_vars);
double hit_rate = rpn_eval(rpn_parse(this->map->world->formulas_config["hit_rate"]), formula_vars);
if (rand > hit_rate)
{
amount = 0;
}
amount = std::max(amount, 0);
int limitamount = std::min(amount, int(npc->hp));
if (this->map->world->config["LimitDamage"])
{
amount = limitamount;
}
npc->Damage(this->owner, amount);
return;
}
if (( npc->Data()->type == ENF::Passive || npc->Data()->type == ENF::Aggressive) && distance < 2 && npc->alive)
{
if(distance < 2)
{
int xdiff = this->x - npc->x;
int ydiff = this->y - npc->y;
if (std::abs(xdiff) > std::abs(ydiff))
{
if (xdiff < 0)
{
this->direction = DIRECTION_RIGHT;
}
else
{
this->direction = DIRECTION_LEFT;
}
}
else
{
if (ydiff < 0)
{
this->direction = DIRECTION_DOWN;
}
else
{
this->direction = DIRECTION_UP;
}
}
PacketBuilder builder(PACKET_NPC, PACKET_PLAYER);
builder.AddByte(255);
builder.AddChar(this->index);
builder.AddChar(1 + (character->hp == 0));
builder.AddChar(this->direction);
builder.AddShort(0);
builder.AddThree(0);
builder.AddThree(int(double(character->hp) / double(character->maxhp) * 100.0));
builder.AddByte(255);
builder.AddByte(255);
UTIL_PTR_LIST_FOREACH(this->map->characters, Character, character)
{
if (*character == this->owner || !character->InRange(this))
{
continue;
}
character->player->client->SendBuilder(builder);
}
this->owner->player->client->SendBuilder(builder);
}
int amount = util::rand(this->Data()->mindam, this->Data()->maxdam + static_cast<int>(this->map->world->config["NPCAdjustMaxDam"]));
double rand = util::rand(0.0, 1.0);
// Checks if target is facing you
bool critical = std::abs(int(npc->direction) - this->owner->direction) != 2 || rand < static_cast<double>(this->map->world->config["CriticalRate"]);
std::tr1::unordered_map<std::string, double> formula_vars;
this->owner->FormulaVars(formula_vars);
npc->FormulaVars(formula_vars, "target_");
formula_vars["modifier"] = this->map->world->config["MobRate"];
formula_vars["damage"] = amount;
formula_vars["critical"] = critical;
amount = rpn_eval(rpn_parse(this->map->world->formulas_config["damage"]), formula_vars);
double hit_rate = rpn_eval(rpn_parse(this->map->world->formulas_config["hit_rate"]), formula_vars);
if (rand > hit_rate)
{
amount = 0;
}
amount = std::max(amount, 0);
int limitamount = std::min(amount, int(npc->hp));
if (this->map->world->config["LimitDamage"])
{
amount = limitamount;
}
npc->Damage(this->owner, amount);
return;
}
}
if(this->map->pk == true)
{
Character *closest = 0;
UTIL_PTR_LIST_FOREACH(this->map->characters, Character, character)
{
unsigned char closest_distance = static_cast<int>(this->map->world->config["NPCChaseDistance"]);
UTIL_PTR_LIST_FOREACH(this->map->characters, Character, character)
{
int distance = util::path_length(character->x, character->y, this->x, this->y);
if (distance < closest_distance)
{
closest = *character;
closest_distance = distance;
}
}
if (closest)
{
attacker = closest;
//this->Attack(closest);
}
}
}
}
}