# Conflicts:
#	changelog.txt
This commit is contained in:
Uleat 2016-10-15 22:27:14 -04:00
commit decaadfe7d
10 changed files with 151 additions and 69 deletions

View File

@ -3,6 +3,12 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50)
== 10/15/2016 ==
Uleat: Changed filenames to facilitate future inventory naming conventions
== 10/09/2016 ==
Noudess: Rogue usage of merchants while utilizing sneak was limited to
temporary items, as the code that checked faction per item sold did not
take into account that rogue was sneaking. Now sneaking rogues can see full
inventory on merchants (well, unless an item requires a + faction value).
== 09/12/2016 ==
Akkadius: Massive overhaul of the update system and EQEmu Server management utility framework
(known as eqemu_update.pl) now known as eqemu_server.pl

View File

@ -55,6 +55,7 @@ RULE_REAL(Character, AAExpMultiplier, 0.5)
RULE_REAL(Character, GroupExpMultiplier, 0.5)
RULE_REAL(Character, RaidExpMultiplier, 0.2)
RULE_BOOL(Character, UseXPConScaling, true)
RULE_INT(Character, ShowExpValues, 0) //0 - normal, 1 - Show raw experience values, 2 - Show raw experience values AND percent.
RULE_INT(Character, LightBlueModifier, 40)
RULE_INT(Character, BlueModifier, 90)
RULE_INT(Character, WhiteModifier, 100)

View File

@ -488,11 +488,11 @@ sub check_internet_connection {
$count = "n";
}
if (`ping 8.8.8.8 -$count 1 -w 500`=~/Reply from|1 received/i) {
if (`ping 8.8.8.8 -$count 1 -w 500`=~/TTL|1 received/i) {
# print "[Update] We have a connection to the internet, continuing...\n";
return 1;
}
elsif (`ping 4.2.2.2 -$count 1 -w 500`=~/Reply from|1 received/i) {
elsif (`ping 4.2.2.2 -$count 1 -w 500`=~/TTL|1 received/i) {
# print "[Update] We have a connection to the internet, continuing...\n";
return 1;
}
@ -2154,4 +2154,4 @@ sub generate_random_password {
map $alphanumeric[rand @alphanumeric], 0..$passwordsize;
return $randpassword;
}
}

View File

@ -0,0 +1 @@
UPDATE ground_spawns SET max_z = -99999 WHERE max_x != min_x OR max_y != min_y

View File

@ -12134,11 +12134,6 @@ void Client::Handle_OP_ShopPlayerBuy(const EQApplicationPacket *app)
continue;
}
int32 fac = tmp->GetPrimaryFaction();
if (fac != 0 && GetModCharacterFactionLevel(fac) < ml.faction_required) {
continue;
}
if (mp->itemslot == ml.slot){
item_id = ml.item;
break;

View File

@ -857,7 +857,15 @@ void Client::BulkSendMerchantInventory(int merchant_id, int npcid) {
continue;
int32 fac = merch ? merch->GetPrimaryFaction() : 0;
if (fac != 0 && GetModCharacterFactionLevel(fac) < ml.faction_required)
int32 cur_fac_level;
if (fac == 0 || sneaking) {
cur_fac_level = 0;
}
else {
cur_fac_level = GetModCharacterFactionLevel(fac);
}
if (cur_fac_level < ml.faction_required)
continue;
handychance = zone->random.Int(0, merlist.size() + tmp_merlist.size() - 1);

View File

@ -350,19 +350,50 @@ void Client::SetEXP(uint32 set_exp, uint32 set_aaxp, bool isrezzexp) {
}
if ((set_exp + set_aaxp) > (m_pp.exp+m_pp.expAA)) {
if (isrezzexp)
this->Message_StringID(MT_Experience, REZ_REGAIN);
else{
if(membercount > 1)
this->Message_StringID(MT_Experience, GAIN_GROUPXP);
else if(IsRaidGrouped())
Message_StringID(MT_Experience, GAIN_RAIDEXP);
else
this->Message_StringID(MT_Experience, GAIN_XP);
uint32 exp_gained = set_exp - m_pp.exp;
uint32 aaxp_gained = set_aaxp - m_pp.expAA;
float exp_percent = (float)((float)exp_gained / (float)(GetEXPForLevel(GetLevel() + 1) - GetEXPForLevel(GetLevel())))*(float)100; //EXP needed for level
float aaxp_percent = (float)((float)aaxp_gained / (float)(RuleI(AA, ExpPerPoint)))*(float)100; //AAEXP needed for level
std::string exp_amount_message = "";
if (RuleI(Character, ShowExpValues) >= 1) {
if (exp_gained > 0 && aaxp_gained > 0) exp_amount_message = StringFormat("%u, %u AA", exp_gained, aaxp_gained);
else if (exp_gained > 0) exp_amount_message = StringFormat("%u", exp_gained);
else exp_amount_message = StringFormat("%u AA", aaxp_gained);
}
std::string exp_percent_message = "";
if (RuleI(Character, ShowExpValues) >= 2) {
if (exp_gained > 0 && aaxp_gained > 0) exp_percent_message = StringFormat("(%.3f%%, %.3f%%AA)", exp_percent, aaxp_percent);
else if (exp_gained > 0) exp_percent_message = StringFormat("(%.3f%%)", exp_percent);
else exp_percent_message = StringFormat("(%.3f%%AA)", aaxp_percent);
}
if (isrezzexp) {
if (RuleI(Character, ShowExpValues) > 0) Message(MT_Experience, "You regain %s experience from resurrection. %s", exp_amount_message.c_str(), exp_percent_message.c_str());
else Message_StringID(MT_Experience, REZ_REGAIN);
} else {
if (membercount > 1) {
if (RuleI(Character, ShowExpValues) > 0) Message(MT_Experience, "You have gained %s party experience! %s", exp_amount_message.c_str(), exp_percent_message.c_str());
else Message_StringID(MT_Experience, GAIN_GROUPXP);
}
else if (IsRaidGrouped()) {
if (RuleI(Character, ShowExpValues) > 0) Message(MT_Experience, "You have gained %s raid experience! %s", exp_amount_message.c_str(), exp_percent_message.c_str());
else Message_StringID(MT_Experience, GAIN_RAIDEXP);
}
else {
if (RuleI(Character, ShowExpValues) > 0) Message(MT_Experience, "You have gained %s experience! %s", exp_amount_message.c_str(), exp_percent_message.c_str());
else Message_StringID(MT_Experience, GAIN_XP);
}
}
}
else if((set_exp + set_aaxp) < (m_pp.exp+m_pp.expAA)){ //only loss message if you lose exp, no message if you gained/lost nothing.
Message(15, "You have lost experience.");
uint32 exp_lost = m_pp.exp - set_exp;
float exp_percent = (float)((float)exp_lost / (float)(GetEXPForLevel(GetLevel() + 1) - GetEXPForLevel(GetLevel())))*(float)100;
if (RuleI(Character, ShowExpValues) == 1 && exp_lost > 0) Message(15, "You have lost %i experience.", exp_lost);
else if (RuleI(Character, ShowExpValues) == 2 && exp_lost > 0) Message(15, "You have lost %i experience. (%.3f%%)", exp_lost, exp_percent);
else Message(15, "You have lost experience.");
}
//check_level represents the level we should be when we have

View File

@ -451,6 +451,21 @@ void Object::RandomSpawn(bool send_packet) {
m_data.x = zone->random.Real(m_min_x, m_max_x);
m_data.y = zone->random.Real(m_min_y, m_max_y);
if(m_data.z == BEST_Z_INVALID) {
glm::vec3 me;
me.x = m_data.x;
me.y = m_data.y;
me.z = 0;
glm::vec3 hit;
float best_z = zone->zonemap->FindClosestZ(me, &hit);
if (best_z != BEST_Z_INVALID) {
m_data.z = best_z + 0.1f;
}
}
Log.Out(Logs::Detail, Logs::Zone_Server, "Object::RandomSpawn(%s): %d (%.2f, %.2f, %.2f)", m_data.object_name, m_inst->GetID(), m_data.x, m_data.y, m_data.z);
respawn_timer.Disable();
if(send_packet) {

View File

@ -5619,11 +5619,11 @@ void Mob::BeamDirectional(uint16 spell_id, int16 resist_adjust)
if (IsBeneficialSpell(spell_id) && IsClient())
beneficial_targets = true;
std::list<Mob*> targets_in_range;
std::list<Mob*>::iterator iter;
std::list<Mob *> targets_in_range;
entity_list.GetTargetsForConeArea(this, spells[spell_id].min_range, spells[spell_id].range, spells[spell_id].range / 2, targets_in_range);
iter = targets_in_range.begin();
entity_list.GetTargetsForConeArea(this, spells[spell_id].min_range, spells[spell_id].range,
spells[spell_id].range / 2, targets_in_range);
auto iter = targets_in_range.begin();
float dX = 0;
float dY = 0;
@ -5632,24 +5632,35 @@ void Mob::BeamDirectional(uint16 spell_id, int16 resist_adjust)
CalcDestFromHeading(GetHeading(), spells[spell_id].range, 5, GetX(), GetY(), dX, dY, dZ);
dZ = GetZ();
//FIND SLOPE: Put it into the form y = mx + b
// FIND SLOPE: Put it into the form y = mx + b
float m = (dY - GetY()) / (dX - GetX());
float b = (GetY() * dX - dY * GetX()) / (dX - GetX());
while(iter != targets_in_range.end())
{
if (!(*iter) || (beneficial_targets && ((*iter)->IsNPC() && !(*iter)->IsPetOwnerClient()))
|| (*iter)->BehindMob(this, (*iter)->GetX(),(*iter)->GetY())){
++iter;
while (iter != targets_in_range.end()) {
if (!(*iter) || (beneficial_targets && ((*iter)->IsNPC() && !(*iter)->IsPetOwnerClient())) ||
(*iter)->BehindMob(this, (*iter)->GetX(), (*iter)->GetY())) {
++iter;
continue;
}
if (IsNPC() && (*iter)->IsNPC()) {
auto fac = (*iter)->GetReverseFactionCon(this);
if (beneficial_targets) {
// only affect mobs we would assist.
if (!(fac <= FACTION_AMIABLE))
continue;
} else {
// affect mobs that are on our hate list, or which have bad faction with us
if (!(CheckAggro(*iter) || fac == FACTION_THREATENLY || fac == FACTION_SCOWLS))
continue;
}
}
//# shortest distance from line to target point
float d = std::abs((*iter)->GetY() - m * (*iter)->GetX() - b) / sqrt(m * m + 1);
if (d <= spells[spell_id].aoerange)
{
if(CheckLosFN((*iter)) || spells[spell_id].npc_no_los) {
if (d <= spells[spell_id].aoerange) {
if (CheckLosFN((*iter)) || spells[spell_id].npc_no_los) {
(*iter)->CalcSpellPowerDistanceMod(spell_id, 0, this);
SpellOnTarget(spell_id, (*iter), false, true, resist_adjust);
maxtarget_count++;
@ -5673,45 +5684,58 @@ void Mob::ConeDirectional(uint16 spell_id, int16 resist_adjust)
float angle_start = spells[spell_id].directional_start + (GetHeading() * 360.0f / 256.0f);
float angle_end = spells[spell_id].directional_end + (GetHeading() * 360.0f / 256.0f);
while(angle_start > 360.0f)
while (angle_start > 360.0f)
angle_start -= 360.0f;
while(angle_end > 360.0f)
while (angle_end > 360.0f)
angle_end -= 360.0f;
std::list<Mob*> targets_in_range;
std::list<Mob*>::iterator iter;
std::list<Mob *> targets_in_range;
entity_list.GetTargetsForConeArea(this, spells[spell_id].min_range, spells[spell_id].aoerange, spells[spell_id].aoerange / 2, targets_in_range);
iter = targets_in_range.begin();
entity_list.GetTargetsForConeArea(this, spells[spell_id].min_range, spells[spell_id].aoerange,
spells[spell_id].aoerange / 2, targets_in_range);
auto iter = targets_in_range.begin();
while(iter != targets_in_range.end()){
if (!(*iter) || (beneficial_targets && ((*iter)->IsNPC() && !(*iter)->IsPetOwnerClient()))){
++iter;
while (iter != targets_in_range.end()) {
if (!(*iter) || (beneficial_targets && ((*iter)->IsNPC() && !(*iter)->IsPetOwnerClient()))) {
++iter;
continue;
}
float heading_to_target = (CalculateHeadingToTarget((*iter)->GetX(), (*iter)->GetY()) * 360.0f / 256.0f);
float heading_to_target =
(CalculateHeadingToTarget((*iter)->GetX(), (*iter)->GetY()) * 360.0f / 256.0f);
while(heading_to_target < 0.0f)
while (heading_to_target < 0.0f)
heading_to_target += 360.0f;
while(heading_to_target > 360.0f)
while (heading_to_target > 360.0f)
heading_to_target -= 360.0f;
if(angle_start > angle_end){
if((heading_to_target >= angle_start && heading_to_target <= 360.0f) || (heading_to_target >= 0.0f && heading_to_target <= angle_end)){
if(CheckLosFN((*iter)) || spells[spell_id].npc_no_los){
if (IsNPC() && (*iter)->IsNPC()) {
auto fac = (*iter)->GetReverseFactionCon(this);
if (beneficial_targets) {
// only affect mobs we would assist.
if (!(fac <= FACTION_AMIABLE))
continue;
} else {
// affect mobs that are on our hate list, or which have bad faction with us
if (!(CheckAggro(*iter) || fac == FACTION_THREATENLY || fac == FACTION_SCOWLS))
continue;
}
}
if (angle_start > angle_end) {
if ((heading_to_target >= angle_start && heading_to_target <= 360.0f) ||
(heading_to_target >= 0.0f && heading_to_target <= angle_end)) {
if (CheckLosFN((*iter)) || spells[spell_id].npc_no_los) {
(*iter)->CalcSpellPowerDistanceMod(spell_id, 0, this);
SpellOnTarget(spell_id,(*iter), false, true, resist_adjust);
SpellOnTarget(spell_id, (*iter), false, true, resist_adjust);
maxtarget_count++;
}
}
}
else{
if(heading_to_target >= angle_start && heading_to_target <= angle_end){
if(CheckLosFN((*iter)) || spells[spell_id].npc_no_los) {
} else {
if (heading_to_target >= angle_start && heading_to_target <= angle_end) {
if (CheckLosFN((*iter)) || spells[spell_id].npc_no_los) {
(*iter)->CalcSpellPowerDistanceMod(spell_id, 0, this);
SpellOnTarget(spell_id, (*iter), false, true, resist_adjust);
maxtarget_count++;

View File

@ -100,9 +100,6 @@ bool Zone::Bootup(uint32 iZoneID, uint32 iInstanceID, bool iStaticZone) {
worldserver.SetZoneData(0);
return false;
}
zone->zonemap = Map::LoadMapFile(zone->map_name);
zone->watermap = WaterMap::LoadWaterMapfile(zone->map_name);
zone->pathing = PathManager::LoadPathFile(zone->map_name);
std::string tmp;
if (database.GetVariable("loglevel", tmp)) {
@ -877,6 +874,23 @@ Zone::~Zone() {
//Modified for timezones.
bool Zone::Init(bool iStaticZone) {
SetStaticZone(iStaticZone);
//load the zone config file.
if (!LoadZoneCFG(zone->GetShortName(), zone->GetInstanceVersion(), true)) // try loading the zone name...
LoadZoneCFG(zone->GetFileName(), zone->GetInstanceVersion()); // if that fails, try the file name, then load defaults
if(RuleManager::Instance()->GetActiveRulesetID() != default_ruleset)
{
std::string r_name = RuleManager::Instance()->GetRulesetName(&database, default_ruleset);
if(r_name.size() > 0)
{
RuleManager::Instance()->LoadRules(&database, r_name.c_str());
}
}
zone->zonemap = Map::LoadMapFile(zone->map_name);
zone->watermap = WaterMap::LoadWaterMapfile(zone->map_name);
zone->pathing = PathManager::LoadPathFile(zone->map_name);
Log.Out(Logs::General, Logs::Status, "Loading spawn conditions...");
if(!spawn_conditions.LoadSpawnConditions(short_name, instanceid)) {
@ -969,19 +983,6 @@ bool Zone::Init(bool iStaticZone) {
petition_list.ClearPetitions();
petition_list.ReadDatabase();
//load the zone config file.
if (!LoadZoneCFG(zone->GetShortName(), zone->GetInstanceVersion(), true)) // try loading the zone name...
LoadZoneCFG(zone->GetFileName(), zone->GetInstanceVersion()); // if that fails, try the file name, then load defaults
if(RuleManager::Instance()->GetActiveRulesetID() != default_ruleset)
{
std::string r_name = RuleManager::Instance()->GetRulesetName(&database, default_ruleset);
if(r_name.size() > 0)
{
RuleManager::Instance()->LoadRules(&database, r_name.c_str());
}
}
Log.Out(Logs::General, Logs::Status, "Loading timezone data...");
zone->zone_time.setEQTimeZone(database.GetZoneTZ(zoneid, GetInstanceVersion()));