diff --git a/common/ruletypes.h b/common/ruletypes.h index 4b6823114..4faa9b5ec 100644 --- a/common/ruletypes.h +++ b/common/ruletypes.h @@ -226,6 +226,7 @@ RULE_BOOL (World, IsGMPetitionWindowEnabled, false) RULE_INT (World, FVNoDropFlag, 0) // Sets the Firiona Vie settings on the client. If set to 2, the flag will be set for GMs only, allowing trading of no-drop items. RULE_BOOL (World, IPLimitDisconnectAll, false) RULE_INT (World, TellQueueSize, 20) +RULE_BOOL(World, StartZoneSameAsBindOnCreation, true) //Should the start zone ALWAYS be the same location as your bind? RULE_CATEGORY_END() RULE_CATEGORY(Zone) diff --git a/world/client.cpp b/world/client.cpp index 29abc5b9d..45d65e494 100644 --- a/world/client.cpp +++ b/world/client.cpp @@ -1552,12 +1552,14 @@ bool Client::OPCharCreate(char *name, CharCreate_Struct *cc) database.GetSafePoints(pp.zone_id, 0, &pp.x, &pp.y, &pp.z); } - /* Will either be the same as home or tutorial */ - pp.binds[0].zoneId = pp.zone_id; - pp.binds[0].x = pp.x; - pp.binds[0].y = pp.y; - pp.binds[0].z = pp.z; - pp.binds[0].heading = pp.heading; + /* Will either be the same as home or tutorial if enabled. */ + if(RuleB(World, StartZoneSameAsBindOnCreation)) { + pp.binds[0].zoneId = pp.zone_id; + pp.binds[0].x = pp.x; + pp.binds[0].y = pp.y; + pp.binds[0].z = pp.z; + pp.binds[0].heading = pp.heading; + } Log.Out(Logs::Detail, Logs::World_Server,"Current location: %s (%d) %0.2f, %0.2f, %0.2f, %0.2f", database.GetZoneName(pp.zone_id), pp.zone_id, pp.x, pp.y, pp.z, pp.heading); diff --git a/world/worlddb.cpp b/world/worlddb.cpp index 2955daf50..cd6733770 100644 --- a/world/worlddb.cpp +++ b/world/worlddb.cpp @@ -353,7 +353,7 @@ bool WorldDatabase::GetStartZone(PlayerProfile_Struct* in_pp, CharCreate_Struct* in_pp->x = in_pp->y = in_pp->z = in_pp->heading = in_pp->zone_id = 0; in_pp->binds[0].x = in_pp->binds[0].y = in_pp->binds[0].z = in_pp->binds[0].zoneId = in_pp->binds[0].instance_id = 0; // see if we have an entry for start_zone. We can support both titanium & SOF+ by having two entries per class/race/deity combo with different zone_ids - std::string query = StringFormat("SELECT x, y, z, heading, start_zone, bind_id FROM start_zones WHERE zone_id = %i " + std::string query = StringFormat("SELECT x, y, z, heading, start_zone, bind_id, bind_x, bind_y, bind_z FROM start_zones WHERE zone_id = %i " "AND player_class = %i AND player_deity = %i AND player_race = %i", in_cc->start_zone, in_cc->class_, in_cc->deity, in_cc->race); auto results = QueryDatabase(query); @@ -376,6 +376,9 @@ bool WorldDatabase::GetStartZone(PlayerProfile_Struct* in_pp, CharCreate_Struct* in_pp->heading = atof(row[3]); in_pp->zone_id = atoi(row[4]); in_pp->binds[0].zoneId = atoi(row[5]); + in_pp->binds[0].x = atof(row[6]); + in_pp->binds[0].y = atof(row[7]); + in_pp->binds[0].z = atof(row[8]); } if(in_pp->x == 0 && in_pp->y == 0 && in_pp->z == 0) diff --git a/zone/corpse.cpp b/zone/corpse.cpp index 24c4b8220..a1cc8c69d 100644 --- a/zone/corpse.cpp +++ b/zone/corpse.cpp @@ -1087,7 +1087,6 @@ void Corpse::LootItem(Client *client, const EQApplicationPacket *app) } if (!IsBeingLootedBy(client)) { - client->Message(13, "Error: Corpse::LootItem: BeingLootedBy != client"); client->QueuePacket(app); SendEndLootErrorPacket(client); return; diff --git a/zone/special_attacks.cpp b/zone/special_attacks.cpp index 81c888915..40836c67c 100644 --- a/zone/special_attacks.cpp +++ b/zone/special_attacks.cpp @@ -225,8 +225,23 @@ void Client::OPCombatAbility(const CombatAbility_Struct *ca_atk) if (ClientVersion() >= EQEmu::versions::ClientVersion::RoF2 && ca_atk->m_skill == EQEmu::skills::SkillTigerClaw) timer = pTimerCombatAbility2; + + bool CanBypassSkillCheck = false; + + if (ca_atk->m_skill == EQEmu::skills::SkillBash) { // SLAM - Bash without a shield equipped + switch (GetRace()) + { + case OGRE: + case TROLL: + case BARBARIAN: + CanBypassSkillCheck = true; + default: + break; + } + } + /* Check to see if actually have skill */ - if (!MaxSkill(static_cast(ca_atk->m_skill))) + if (!MaxSkill(static_cast(ca_atk->m_skill)) && !CanBypassSkillCheck) return; if (GetTarget()->GetID() != ca_atk->m_target)