Merge pull request #802 from noudess/master

New min/max personal faction per faction.  Use of actual client mods for race/class/deity
This commit is contained in:
Chris Miles 2019-03-06 13:17:34 -08:00 committed by GitHub
commit 3db3e53f11
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 601 additions and 25 deletions

View File

@ -1,6 +1,96 @@
EQEMu Changelog (Started on Sept 24, 2003 15:50)
-------------------------------------------------------
== 3/1/2019 ==
Noudess: Major faction conversion to use client data.
Pull request #802 New min/max personal faction per faction. Use of actual
client mods for race/class/deity.
This PR involves major changes to your database and your quests.
The clients recently exposed raw data included
- the min/max personal faction for each faction
- the actual faction id the client uses for each faction
- the actual mods that come into play when a PC cons an opponent that
determine your overall con to that faction.
The approach I took resulted in minimal change to the code base. I did
alter the code to enforce the new validated min/max from the client. This
min/max applies to personally earned faction. So if a faction has a min
of 0 and a max of 2000, that means your personally earned value can never
go below 0 or over 2000. The actual con, will, however often do so because
of class/race/deity modifications. I also changed the con ranges, per
Mackal's data that was proven to be accurate:
Ally = 1100+
Warmly = 750 to 1099
Kindly = 500 to 749
Amiable = 100 to 499
Indifferent = 0 to 99
Apprehensive = -1 to -100
Dubious = -101 to -500
Threateningly = -501 to -750
Ready to Attack = -751
The above means that dubious is a much smaller range now. For that reason
the scripts modify any custom faction base values to put them in the same
range, hopefully as the creators of the custom factions intended.
Also to be noted as characters that have a faction between -501 and -700
wont be dubious anymore, they will be threateningly. This is expected with
the new ranges, but might take players by suprise as the old ranges we used
were more liberal but were incorrect.
The database is changed extensively, but really only content. We're
translating faction_list to use the clients ids. As such every place a
faction_is is used, namely (see below) are being converted.
- faction_list
- faction_list_mod
- npc_faction (primary_faction field only)
- npc_faction_entries (faction_id field only)
- faction_values
Quests will also automatically be adjusted. This MUST be done after the
PR sql and before starting the server. This is automated by
eqemu_server.pl (or starting world)
Be assured, custom factions that you may have created, or obsolete or
duplicate factions in our original faction_list, that you may have used,
will be preserved. Anything that does not map directly is being moved to
the 5000 range in faction_list and any references are corrected to point
there.
A great example of this is Ebon Mask and Hall of the Ebon Mask. Many peqdb
style servers have both of these. Some have used one, some the other. We
map Ebon Mask to the clients Ebon mask and the Hall of the Ebon Mask gets
moved to the 5000 range, and all its references are preserved. However,
if you would like to make proper use of client mobs to Ebon mask, or other
factions that have duplicitous entries, I recommend you manually move to
using the correct one. In that way all of the new raw data mapped in from
the client into faction_list_mod will get used instead of what your db had
before these values were known.
In my experience converting 4 different server's data, there are only
about 20 factions moved into the 5000 range.
This PR has only 1 new, permanent table faction_base_data, which is taken
right from the client. The base field is left in case you want to mod your
server, but we are very sure that the client doesn't use a base. It uses
global mods to race or class for this as you'll see in the
new faction_list_mod.
The PR makes many backup tables, and two mapping tables that are used during
the conversion process to fix quests. This table was hand created by
analysis. This table serves no purpose after conversion except an audit
trail if we see any issues.
I will release a new PR that will clean up all these backups and temporary
tables in about a month.
== 2/7/2019 ==
Uleat: Put merc and bot classes on the same stance standard (mercs)
- Both classes will now use the same stance standard

View File

@ -59,31 +59,31 @@ FACTION_VALUE CalculateFaction(FactionMods* fm, int32 tmpCharacter_value)
if (fm) {
character_value += fm->base + fm->class_mod + fm->race_mod + fm->deity_mod;
}
if (character_value >= 1101) {
if (character_value >= 1100) {
return FACTION_ALLY;
}
if (character_value >= 701 && character_value <= 1100) {
if (character_value >= 750 && character_value <= 1099) {
return FACTION_WARMLY;
}
if (character_value >= 401 && character_value <= 700) {
if (character_value >= 500 && character_value <= 749) {
return FACTION_KINDLY;
}
if (character_value >= 101 && character_value <= 400) {
if (character_value >= 100 && character_value <= 499) {
return FACTION_AMIABLE;
}
if (character_value >= 0 && character_value <= 100) {
if (character_value >= 0 && character_value <= 99) {
return FACTION_INDIFFERENT;
}
if (character_value >= -100 && character_value <= -1) {
return FACTION_APPREHENSIVE;
}
if (character_value >= -700 && character_value <= -101) {
if (character_value >= -500 && character_value <= -101) {
return FACTION_DUBIOUS;
}
if (character_value >= -999 && character_value <= -701) {
if (character_value >= -750 && character_value <= -501) {
return FACTION_THREATENLY;
}
if (character_value <= -1000) {
if (character_value <= -751) {
return FACTION_SCOWLS;
}
return FACTION_INDIFFERENT;

4
common/faction.h Normal file → Executable file
View File

@ -50,6 +50,8 @@ struct NPCFactionList {
struct FactionMods
{
int32 base;
int16 min; // The lowest your personal earned faction can go - before race/class/diety adjustments.
int16 max; // The highest your personal earned faction can go - before race/class/diety adjustments.
int32 class_mod;
int32 race_mod;
int32 deity_mod;
@ -59,6 +61,8 @@ struct Faction {
int32 id;
std::map<std::string, int16> mods;
int16 base;
int16 min; // The lowest your personal earned faction can go - before race/class/diety adjustments.
int16 max; // The highest your personal earned faction can go - before race/class/diety adjustments.
char name[50];
};

View File

@ -30,7 +30,9 @@
Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt
*/
#define CURRENT_BINARY_DATABASE_VERSION 9136
#define CURRENT_BINARY_DATABASE_VERSION 9138
#ifdef BOTS
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9022
#else

View File

@ -787,6 +787,7 @@ sub show_menu_prompt {
elsif ($input eq "conversions") {
print "\n>>> Conversions Menu\n\n";
print " [quest_heading_convert] Converts old heading format in quest scripts to new (live format)\n";
print " [quest_faction_convert] Converts to new faction values imported from client\n";
print " \n> main - go back to main menu\n";
print "Enter a command #> ";
$last_menu = trim($input);
@ -905,6 +906,10 @@ sub show_menu_prompt {
quest_heading_convert();
$dc = 1;
}
elsif ($input eq "quest_faction_convert") {
quest_faction_convert();
$dc = 1;
}
elsif ($input eq "source_peq_db") {
fetch_peq_db_full();
$dc = 1;
@ -2209,6 +2214,10 @@ sub run_database_check {
if ($bots_db_management == 1 && $val == 9000) {
modify_db_for_bots();
}
if ($val == 9138) {
fix_quest_factions();
}
}
$db_run_stage = 2;
}
@ -2493,3 +2502,127 @@ sub quest_heading_convert {
print "Total matches: " . $total_matches . "\n";
}
sub quest_faction_convert {
if(trim(get_mysql_result("SELECT value FROM variables WHERE varname = 'new_faction_conversion'")) eq "true") {
print "Conversion script has already ran... doing this again would skew proper faction values in function calls...\n";
exit;
}
%matches = (
0 => [ "GetCharacterFactionLevel", 0],
1 => [ "GetModCharacterFactionLevel", 0],
2 => [ "SetFactionLevel2", 1],
3 => [ "GetFactionLevel", 5 ],
4 => [ "CheckNPCFactionAlly", 0 ],
5 => [ ":Faction", 0 ],
);
$total_matches = 0;
use Scalar::Util qw(looks_like_number);
my @files;
my $start_dir = "quests/.";
find(
sub {push @files, $File::Find::name unless -d;},
$start_dir
);
for my $file (@files) {
#::: Skip non script files
if ($file !~ /lua|pl/i) {
next;
}
if ($file =~ /lua|pl/i) {
$print_buffer = "";
$changes_made = 0;
#::: Open and read line by line
open(FILE, $file);
while (<FILE>) {
chomp;
$line = $_;
#::: Loop through matches
foreach my $key (sort (keys %matches)) {
$argument_position = $matches{$key}[1];
$match = $matches{$key}[0];
if ($line =~ /$match\(/i || $line =~ /$match \(/i) {
$line_temp = $line;
$line_temp =~ s/^.*$match\(//gi;
$line_temp =~ s/^.*$match \(//gi;
$line_temp =~ s/"//g;
$line_temp =~ s/\);.*//;
@line_data = split(",", $line_temp);
$faction_value = $line_data[$argument_position];
$faction_value_clean = trim($faction_value);
if (looks_like_number($faction_value_clean)) {
$new_faction = get_mysql_result("select clientid from client_server_faction_map where serverid = $faction_value_clean");
chomp $new_faction;
if ($new_faction == 0) {
$new_faction = get_mysql_result("select new_faction from custom_faction_mappings where old_faction = $faction_value_clean");
chomp $new_faction;
}
if ($new_faction > 0) {
print "BEFORE: " . $line . "\n";
$line =~ s/$faction_value_clean/$new_faction/g;
print "AFTER: " . $line . "\n";
$changes_made = 1;
}
else {
print "Unknown Faction: '$match' FACTION VALUE: '" . $faction_value_clean . "'\n";
}
}
$total_matches++;
}
}
$print_buffer .= $line . "\n";
}
close(FILE);
#::: Write changes
if ($changes_made == 1) {
open(NEW_FILE, '>', $file);
print NEW_FILE $print_buffer;
close NEW_FILE;
}
}
}
#::: Mark conversion as ran
print get_mysql_result("INSERT INTO `variables` (varname, value, information, ts) VALUES ('new_faction_conversion', 'true', 'Script ran against quests folder to convert new faction values', NOW())");
print "Total matches: " . $total_matches . "\n";
}
sub fix_quest_factions {
# Backup the quests
mkdir('backups');
my @files;
my $start_dir = "quests/";
find(
sub { push @files, $File::Find::name unless -d; },
$start_dir
);
for my $file (@files) {
$destination_file = $file;
my $date = strftime "%m-%d-%Y", localtime;
$destination_file =~ s/quests/quests-$date/;
print "Backing up :: " . $destination_file . "\n";
# unlink($destination_file);
copy_file($file, 'backups/' . $destination_file);
}
# Fix the factions
quest_faction_convert();
}

View File

@ -390,6 +390,8 @@
9134|2019_01_04_update_global_base_scaling.sql|SELECT * FROM db_version WHERE version >= 9134|empty|
9135|2019_01_10_multi_version_spawns.sql|SHOW COLUMNS FROM `spawn2` LIKE 'version'|contains|unsigned|
9136|2019_02_04_profanity_command.sql|SHOW TABLES LIKE 'profanity_list'|empty|
9137|2018_12_12_client_faction_tables.sql|SHOW TABLES LIKE 'faction_base_data'|empty|
9138|2018_12_12_convert_to_client_functions.sql|SELECT `id` FROM `faction_list` WHERE `id` > 4999|empty|
# Upgrade conditions:
# This won't be needed after this system is implemented, but it is used database that are not

View File

@ -0,0 +1,53 @@
/* Fix any items with faction adjustments */
SET SQL_MODE='ALLOW_INVALID_DATES'; /* Some dbs have bad dates which prevents the index creation */
CREATE INDEX itemfac1 ON items (factionmod1);
CREATE INDEX itemfac2 ON items (factionmod2);
CREATE INDEX itemfac3 ON items (factionmod3);
CREATE INDEX itemfac4 ON items (factionmod4);
UPDATE items i
INNER JOIN custom_faction_mappings m ON i.factionmod1 = m.old_faction
SET i.factionmod1 = m.new_faction
WHERE i.factionmod1 > 0;
UPDATE items i
INNER JOIN custom_faction_mappings m ON i.factionmod2 = m.old_faction
SET i.factionmod2 = m.new_faction
WHERE i.factionmod2 > 0;
UPDATE items i
INNER JOIN custom_faction_mappings m ON i.factionmod3 = m.old_faction
SET i.factionmod3 = m.new_faction
WHERE i.factionmod3 > 0;
UPDATE items i
INNER JOIN custom_faction_mappings m ON i.factionmod4 = m.old_faction
SET i.factionmod4 = m.new_faction
WHERE i.factionmod4 > 0;
UPDATE items i
INNER JOIN client_server_faction_map m ON i.factionmod1 = m.serverid
SET i.factionmod1 = m.clientid
WHERE i.factionmod1 > 0;
UPDATE items i
INNER JOIN client_server_faction_map m ON i.factionmod2 = m.serverid
SET i.factionmod2 = m.clientid
WHERE i.factionmod2 > 0;
UPDATE items i
INNER JOIN client_server_faction_map m ON i.factionmod3 = m.serverid
SET i.factionmod3 = m.clientid
WHERE i.factionmod3 > 0;
UPDATE items i
INNER JOIN client_server_faction_map m ON i.factionmod4 = m.serverid
SET i.factionmod4 = m.clientid
WHERE i.factionmod4 > 0;
DROP INDEX itemfac1 ON items;
DROP INDEX itemfac2 ON items;
DROP INDEX itemfac3 ON items;
DROP INDEX itemfac4 ON items;

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,173 @@
/*
This SQL update utilizes the new raw faction data from the client
First we create a temporary table - which we will use to map any
custom factions in the eqemu db, that are either:
- eqemu utility factions
- obsoleted factions with no new mapping to the client
This is done so that we can keep these factions while server owners either
stay with them, or migrate. They are moved to the 5000+ range, to not conflict
with client faction_ids.
*/
/* Create the temp table and start mappings at 5000 */
CREATE TABLE custom_faction_mappings (old_faction int, new_faction int, primary key (old_faction)) engine=INNODB;
select "Moving custom factions to safe range, well above known client values" ``;
select @startcustom:=5000;
/* Insert the custom/obsolete factions into the temp mapping table */
insert into custom_faction_mappings (select id, @startcustom := @startcustom +1 from faction_list where id not in (select serverid from client_server_faction_map) and id < 5000);
CREATE TABLE IF NOT EXISTS faction_list_mod_prefix AS SELECT * from faction_list_mod;
/* Now we update all the tables for these custom factions */
update faction_list_mod set faction_id = (select new_faction from custom_faction_mappings where old_faction = faction_id) where faction_id < 5000 and faction_id in (select old_faction from custom_faction_mappings);
CREATE TABLE IF NOT EXISTS faction_list_prefix AS SELECT * from faction_list;
DROP TABLE faction_list;
CREATE TABLE `faction_list` (
`id` int(11) NOT NULL,
`name` varchar(50) NOT NULL DEFAULT '',
`base` smallint(6) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
UNIQUE KEY `id` (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=486 DEFAULT CHARSET=utf8 as select id, name, base from faction_list_prefix;
update faction_list set id =
(select new_faction from custom_faction_mappings where old_faction = id) where id < 5000 and id in (select old_faction from custom_faction_mappings);
/* At this point all faction_mods for unmapped factions will be ids 5000+ */
/* So we can delete all the old ones still under 5000 - making room for the */
/* new faction ids */
delete from faction_list_mod where faction_id < 5000;
delete from faction_list where id < 5000;
/* Make an entry for each faction */
/* No base on client factions */
insert into faction_list (id, name, base) (select id, name, 0 from client_faction_names);
/* Now restore any base for factions for which the client has no mods (social factions) */
DROP TABLE IF EXISTS oldbases;
CREATE TABLE `oldbases` (
`id` int(11) DEFAULT 0,
`name` varchar(50) NOT NULL DEFAULT '',
`base` smallint(6) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 as
(select m.clientid as id, p.name, p.base from faction_list_prefix p
join client_server_faction_map m on m.serverid = p.id where p.base <> 0
&& m.clientid in (select id from faction_list where id not in (SELECT faction_id from client_faction_associations group by faction_id)));
update faction_list f
INNER JOIN oldbases o on o.id = f.id
set f.base = o.base;
/* Adjust for the big change in the dubious range */
update faction_list set base = base + 200 where base between -900 and -501;
DROP TABLE IF EXISTS oldbases;
/* Create mods based on the client_faction_associations */
/* No code changes required */
insert into faction_list_mod
(select null, faction_id, `mod`, concat("r", other_faction_id-50)
from client_faction_associations a
join client_faction_names n on n.id = a.other_faction_id
where other_faction_id between 51 and 180);
insert into faction_list_mod
(select null, faction_id, `mod`, concat("c", other_faction_id)
from client_faction_associations a
join client_faction_names n on n.id = a.other_faction_id
where other_faction_id between 1 and 50);
insert into faction_list_mod
(select null, faction_id, `mod`, concat("d", other_faction_id)
from client_faction_associations a
join client_faction_names n on n.id = a.other_faction_id
where other_faction_id between 201 and 216);
/* And now we need to fix all the other faction tables to point to the new factions. */
CREATE TABLE IF NOT EXISTS npc_faction_prefix AS SELECT * from npc_faction;
update npc_faction set primaryfaction = (select new_faction from custom_faction_mappings where old_faction = primaryfaction)
where primaryfaction in (select old_faction from custom_faction_mappings);
update npc_faction set primaryfaction = (select clientid from client_server_faction_map where serverid = primaryfaction)
where primaryfaction in (select serverid from client_server_faction_map);
update npc_faction_entries set faction_id = (select new_faction from custom_faction_mappings where old_faction = faction_id)
where faction_id in (select old_faction from custom_faction_mappings);
CREATE TABLE IF NOT EXISTS npc_faction_entries_prefix AS SELECT * from npc_faction_entries;
/* Move existing factions out of wat - the following replace would create key */
/* duplicates along the way, but none when complete. */
update npc_faction_entries set faction_id = faction_id + 20000
where faction_id in (select serverid from client_server_faction_map);
update npc_faction_entries set faction_id = (select clientid from client_server_faction_map where faction_id > 20000 && serverid = (faction_id-20000))
where faction_id > 20000 && (faction_id-20000) in (select serverid from client_server_faction_map);
/* Removes any duplicates from the use of factions that are obsoleted */
/* These are entries that have no new mapping whatsoever */
delete from npc_faction_entries where faction_id > 20000;
/*
Update the faction_values now.
*/
CREATE TABLE IF NOT EXISTS faction_values_prefix AS SELECT * from faction_values;
delete from faction_values
where faction_id not in (select old_faction from custom_faction_mappings) and faction_id not in (select serverid from client_server_faction_map);
/* Custom faction mappings dont have to worry about range collision */
select "Updating faction_values for custom factions" ``;
update faction_values set faction_id = (select new_faction from custom_faction_mappings where old_faction = faction_id)
where faction_id in (select old_faction from custom_faction_mappings);
/*
There are so many of these, Im going to update in place to save time.
To do this we must remove the unique keys, as these will be violated until
the update is complete
*/
select "Updating core faction_values to use new faction ids...." ``;
alter table faction_values drop primary key;
update faction_values v
join client_server_faction_map m on v.faction_id = m.serverid
set faction_id = m.clientid;
ALTER TABLE `faction_values` ADD PRIMARY KEY `lookup` (`char_id`,`faction_id`);
/*
* The following to be deleted in a future update, once everyone is
* happy with the conversion
DROP TABLE IF EXISTS custom_faction_mappings;
DROP TABLE IF EXISTS faction_list_mod_prefix;
DROP TABLE IF EXISTS faction_list_prefix;
DROP TABLE IF EXISTS npc_faction_prefix;
DROP TABLE IF EXISTS npc_faction_entries_prefix;
DROP TABLE IF NOT EXISTS faction_values_prefix;
*/

View File

@ -3470,7 +3470,7 @@ float Client::CalcPriceMod(Mob* other, bool reverse)
float chaformula = 0;
if (other)
{
int factionlvl = GetFactionLevel(CharacterID(), other->CastToNPC()->GetNPCTypeID(), GetRace(), GetClass(), GetDeity(), other->CastToNPC()->GetPrimaryFaction(), other);
int factionlvl = GetFactionLevel(CharacterID(), other->CastToNPC()->GetNPCTypeID(), GetFactionRace(), GetClass(), GetDeity(), other->CastToNPC()->GetPrimaryFaction(), other);
if (factionlvl >= FACTION_APPREHENSIVE) // Apprehensive or worse.
{
if (GetCHA() > 103)
@ -7705,7 +7705,7 @@ FACTION_VALUE Client::GetReverseFactionCon(Mob* iOther) {
if (iOther->GetPrimaryFaction() == 0)
return FACTION_INDIFFERENT;
return GetFactionLevel(CharacterID(), 0, GetRace(), GetClass(), GetDeity(), iOther->GetPrimaryFaction(), iOther);
return GetFactionLevel(CharacterID(), 0, GetFactionRace(), GetClass(), GetDeity(), iOther->GetPrimaryFaction(), iOther);
}
//o--------------------------------------------------------------
@ -7792,7 +7792,7 @@ void Client::SetFactionLevel(uint32 char_id, uint32 npc_id, uint8 char_class, ui
// Find out starting faction for this faction
// It needs to be used to adj max and min personal
// The range is still the same, 1200-3000(4200), but adjusted for base
database.GetFactionData(&fm, GetClass(), GetRace(), GetDeity(),
database.GetFactionData(&fm, GetClass(), GetFactionRace(), GetDeity(),
faction_id[i]);
if (quest)
@ -7842,7 +7842,7 @@ void Client::SetFactionLevel2(uint32 char_id, int32 faction_id, uint8 char_class
// Find out starting faction for this faction
// It needs to be used to adj max and min personal
// The range is still the same, 1200-3000(4200), but adjusted for base
database.GetFactionData(&fm, GetClass(), GetRace(), GetDeity(),
database.GetFactionData(&fm, GetClass(), GetFactionRace(), GetDeity(),
faction_id);
// Adjust the amount you can go up or down so the resulting range
@ -7943,9 +7943,15 @@ return;
int32 Client::GetModCharacterFactionLevel(int32 faction_id) {
int32 Modded = GetCharacterFactionLevel(faction_id);
FactionMods fm;
if (database.GetFactionData(&fm, GetClass(), GetRace(), GetDeity(), faction_id))
if (database.GetFactionData(&fm, GetClass(), GetFactionRace(), GetDeity(), faction_id))
{
Modded += fm.base + fm.class_mod + fm.race_mod + fm.deity_mod;
//Tack on any bonuses from Alliance type spell effects
Modded += GetFactionBonus(faction_id);
Modded += GetItemFactionBonus(faction_id);
}
return Modded;
}
@ -7958,7 +7964,7 @@ void Client::MerchantRejectMessage(Mob *merchant, int primaryfaction)
// If a faction is involved, get the data.
if (primaryfaction > 0) {
if (database.GetFactionData(&fmod, GetClass(), GetRace(), GetDeity(), primaryfaction)) {
if (database.GetFactionData(&fmod, GetClass(), GetFactionRace(), GetDeity(), primaryfaction)) {
tmpFactionValue = GetCharacterFactionLevel(primaryfaction);
lowestvalue = std::min(std::min(tmpFactionValue, fmod.deity_mod),
std::min(fmod.class_mod, fmod.race_mod));

View File

@ -4623,7 +4623,7 @@ void Client::Handle_OP_Consider(const EQApplicationPacket *app)
con->playerid = GetID();
con->targetid = conin->targetid;
if (tmob->IsNPC())
con->faction = GetFactionLevel(character_id, tmob->GetNPCTypeID(), race, class_, deity, (tmob->IsNPC()) ? tmob->CastToNPC()->GetPrimaryFaction() : 0, tmob); // Dec. 20, 2001; TODO: Send the players proper deity
con->faction = GetFactionLevel(character_id, tmob->GetNPCTypeID(), GetFactionRace(), class_, deity, (tmob->IsNPC()) ? tmob->CastToNPC()->GetPrimaryFaction() : 0, tmob); // Dec. 20, 2001; TODO: Send the players proper deity
else
con->faction = 1;
con->level = GetLevelCon(tmob->GetLevel());

View File

@ -1046,7 +1046,7 @@ void PerlembParser::ExportMobVariables(bool isPlayerQuest, bool isGlobalPlayerQu
if (mob && npcmob && mob->IsClient()) {
Client* client = mob->CastToClient();
fac = client->GetFactionLevel(client->CharacterID(), npcmob->GetID(), client->GetRace(),
fac = client->GetFactionLevel(client->CharacterID(), npcmob->GetID(), client->GetFactionRace(),
client->GetClass(), client->GetDeity(), npcmob->GetPrimaryFaction(), npcmob);
}
}

View File

@ -1553,7 +1553,7 @@ void Mob::ShowStats(Client* client)
}
}
else {
client->Message(0, " Level: %i AC: %i Class: %i Size: %1.1f Haste: %i", GetLevel(), GetAC(), GetClass(), GetSize(), GetHaste());
client->Message(0, " Level: %i AC: %i Class: %i Size: %1.1f Haste: %i", GetLevel(), ACSum(), GetClass(), GetSize(), GetHaste());
client->Message(0, " HP: %i Max HP: %i",GetHP(), GetMaxHP());
client->Message(0, " Mana: %i Max Mana: %i", GetMana(), GetMaxMana());
client->Message(0, " Total ATK: %i Worn/Spell ATK (Cap %i): %i", GetATK(), RuleI(Character, ItemATKCap), GetATKBonus());
@ -2121,6 +2121,16 @@ bool Mob::IsPlayerRace(uint16 in_race) {
return false;
}
uint16 Mob::GetFactionRace() {
uint16 current_race = GetRace();
if (IsPlayerRace(current_race) || current_race == TREE ||
current_race == MINOR_ILL_OBJ) {
return current_race;
}
else {
return (GetBaseRace());
}
}
uint8 Mob::GetDefaultGender(uint16 in_race, uint8 in_gender) {
if (Mob::IsPlayerRace(in_race) || in_race == 15 || in_race == 50 || in_race == 57 || in_race == 70 || in_race == 98 || in_race == 118 || in_race == 562) {

View File

@ -442,6 +442,7 @@ public:
virtual void SetMaxHP() { current_hp = max_hp; }
virtual inline uint16 GetBaseRace() const { return base_race; }
virtual inline uint8 GetBaseGender() const { return base_gender; }
virtual uint16 GetFactionRace();
virtual inline uint16 GetDeity() const { return deity; }
virtual EQEmu::deity::DeityTypeBit GetDeityBit() { return EQEmu::deity::ConvertDeityTypeToDeityTypeBit((EQEmu::deity::DeityType)deity); }
inline uint16 GetRace() const { return race; }

View File

@ -2899,7 +2899,7 @@ uint8 QuestManager::FactionValue()
FACTION_VALUE oldfac;
uint8 newfac = 0;
if(initiator && owner->IsNPC()) {
oldfac = initiator->GetFactionLevel(initiator->GetID(), owner->GetID(), initiator->GetRace(), initiator->GetClass(), initiator->GetDeity(), owner->GetPrimaryFaction(), owner);
oldfac = initiator->GetFactionLevel(initiator->GetID(), owner->GetID(), initiator->GetFactionRace(), initiator->GetClass(), initiator->GetDeity(), owner->GetPrimaryFaction(), owner);
// now, reorder the faction to have it make sense (higher values are better)
switch (oldfac) {

32
zone/zonedb.cpp Normal file → Executable file
View File

@ -3914,6 +3914,8 @@ bool ZoneDatabase::GetFactionData(FactionMods* fm, uint32 class_mod, uint32 race
}
fm->base = faction_array[faction_id]->base;
fm->min = faction_array[faction_id]->min; // The lowest your personal earned faction can go - before race/class/diety adjustments.
fm->max = faction_array[faction_id]->max; // The highest your personal earned faction can go - before race/class/diety adjustments.
if(class_mod > 0) {
char str[32];
@ -4060,14 +4062,32 @@ bool ZoneDatabase::LoadFactionData()
faction_array[index] = new Faction;
strn0cpy(faction_array[index]->name, row[1], 50);
faction_array[index]->base = atoi(row[2]);
faction_array[index]->min = MIN_PERSONAL_FACTION;
faction_array[index]->max = MAX_PERSONAL_FACTION;
query = StringFormat("SELECT `mod`, `mod_name` FROM `faction_list_mod` WHERE faction_id = %u", index);
auto modResults = QueryDatabase(query);
if (!modResults.Success())
continue;
// Load in the mimimum and maximum faction that can be earned for this faction
query = StringFormat("SELECT `min` , `max` FROM `faction_base_data` WHERE client_faction_id = %u", index);
auto baseResults = QueryDatabase(query);
if (!baseResults.Success() || baseResults.RowCount() == 0) {
Log(Logs::General, Logs::General, "Faction %d has no base data", (int)index);
}
else {
for (auto modRow = baseResults.begin(); modRow != baseResults.end(); ++modRow) {
faction_array[index]->min = atoi(modRow[0]);
faction_array[index]->max = atoi(modRow[1]);
Log(Logs::General, Logs::None, "Min(%d), Max(%d) for faction (%u)",faction_array[index]->min, faction_array[index]->max, index);
}
}
for (auto modRow = modResults.begin(); modRow != modResults.end(); ++modRow)
faction_array[index]->mods[modRow[1]] = atoi(modRow[0]);
// Load in modifiers to the faction based on characters race, class and diety.
query = StringFormat("SELECT `mod`, `mod_name` FROM `faction_list_mod` WHERE faction_id = %u", index);
auto modResults = QueryDatabase(query);
if (!modResults.Success())
continue;
for (auto modRow = modResults.begin(); modRow != modResults.end(); ++modRow) {
faction_array[index]->mods[modRow[1]] = atoi(modRow[0]);
}
}
return true;