void Map::Attack(Character *from, Direction direction) { PacketBuilder builder; from->direction = direction; if (from->arena) { from->arena->Attack(from, direction); } if (this->pk || (this->world->config["GlobalPK"] && !this->world->PKExcept(this->id))) { if (this->AttackPK(from, direction)) { return; } } builder.SetID(PACKET_ATTACK, PACKET_PLAYER); builder.AddShort(from->player->id); builder.AddChar(direction); UTIL_PTR_LIST_FOREACH(this->characters, Character, character) { if (*character == from || !from->InRange(*character)) { continue; } character->player->client->SendBuilder(builder); } int target_x = from->x; int target_y = from->y; int range = 1; if (this->world->eif->Get(from->paperdoll[Character::Weapon])->subtype == EIF::Ranged) { range = static_cast<int>(this->world->config["RangedDistance"]); } for (int i = 0; i < range; ++i) { switch (from->direction) { case DIRECTION_UP: target_y -= 1; break; case DIRECTION_RIGHT: target_x += 1; break; case DIRECTION_DOWN: target_y += 1; break; case DIRECTION_LEFT: target_x -= 1; break; } if (!this->Walkable(target_x, target_y, true)) { break; } UTIL_PTR_LIST_FOREACH(this->characters, Character, character) { UTIL_PTR_VECTOR_FOREACH(this->npcs, NPC, npc) { if ((npc->pet || npc->Data()->type == ENF::Pet || npc->Data()->type == ENF::Passive || npc->Data()->type == ENF::Aggressive || from->admin > static_cast<int>(this->world->admin_config["killnpcs"])) && npc->alive && npc->x == target_x && npc->y == target_y) { if(from->clas == 9) { int amount = util::rand(from->mindam + 0, from->maxdam + 0); double rand = util::rand(0.0, 1.0); // Checks if target is facing you bool critical = std::abs(int(npc->direction) - from->direction) != 2 || rand < static_cast<double>(this->world->config["CriticalRate"]); std::tr1::unordered_map<std::string, double> formula_vars; from->FormulaVars(formula_vars); npc->FormulaVars(formula_vars, "target_"); formula_vars["modifier"] = this->world->config["MobRate"]; formula_vars["damage"] = amount; formula_vars["critical"] = critical; amount = rpn_eval(rpn_parse(this->world->formulas_config["damage"]), formula_vars); double hit_rate = rpn_eval(rpn_parse(this->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->world->config["LimitDamage"]) { amount = limitamount; } int itemid, effectid; for(int i = 0 ; i < static_cast<int>(this->world->effects_config["WAmount"]) ; i++){ itemid = static_cast<int>(this->world->effects_config[util::to_string(i+1) + ".ItemID"]); effectid = static_cast<int>(this->world->effects_config[util::to_string(i+1) + ".EffectID"]); if(from->paperdoll[Character::Weapon] == itemid){ npc->Effect(from, effectid, amount); } } npc->Damage(from, amount); } else if(from->clas != 9) { int amount = util::rand(from->mindam, from->maxdam); double rand = util::rand(0.0, 1.0); // Checks if target is facing you bool critical = std::abs(int(npc->direction) - from->direction) != 2 || rand < static_cast<double>(this->world->config["CriticalRate"]); std::tr1::unordered_map<std::string, double> formula_vars; from->FormulaVars(formula_vars); npc->FormulaVars(formula_vars, "target_"); formula_vars["modifier"] = this->world->config["MobRate"]; formula_vars["damage"] = amount; formula_vars["critical"] = critical; amount = rpn_eval(rpn_parse(this->world->formulas_config["damage"]), formula_vars); double hit_rate = rpn_eval(rpn_parse(this->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->world->config["LimitDamage"]) { amount = limitamount; } int itemid, effectid; for(int i = 0 ; i < static_cast<int>(this->world->effects_config["WAmount"]) ; i++){ itemid = static_cast<int>(this->world->effects_config[util::to_string(i+1) + ".ItemID"]); effectid = static_cast<int>(this->world->effects_config[util::to_string(i+1) + ".EffectID"]); if(from->paperdoll[Character::Weapon] == itemid){ npc->Effect(from, effectid, amount); } } npc->Damage(from, amount); return; } } } } } }