Moved faction stuff around, removed stupid external item status stuff

This commit is contained in:
KimLS 2013-02-23 15:03:15 -08:00
parent 5a69f41f4d
commit 147c96970c
19 changed files with 1047 additions and 1161 deletions

View File

@ -27,6 +27,7 @@ SET(common_sources
EQStreamProxy.cpp
eqtime.cpp
extprofile.cpp
faction.cpp
guild_base.cpp
guilds.cpp
ipc_mutex.cpp

141
common/faction.cpp Normal file
View File

@ -0,0 +1,141 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2002 EQEMu Development Team (http://eqemu.org)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY except by those people which sell it, which
are required to give you total support for your newly bought product;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "debug.h"
#include "faction.h"
#include "races.h"
const char *FactionValueToString(FACTION_VALUE fv) {
switch(fv) {
case FACTION_ALLY:
return("Ally");
case FACTION_WARMLY:
return("Warmly");
case FACTION_KINDLY:
return("Kindly");
case FACTION_AMIABLE:
return("Amiable");
case FACTION_INDIFFERENT:
return("Indifferent");
case FACTION_APPREHENSIVE:
return("Apprehensive");
case FACTION_DUBIOUS:
return("Dubious");
case FACTION_THREATENLY:
return("Threatenly");
case FACTION_SCOWLS:
return("Scowls, ready to attack.");
default:
break;
}
return("Unknown Faction Con");
}
//o--------------------------------------------------------------
//| Name: CalculateFaction; rembrant, Dec. 16, 2001
//o--------------------------------------------------------------
//| Notes: Returns the faction message value.
//| Modify these values to taste.
//o--------------------------------------------------------------
FACTION_VALUE CalculateFaction(FactionMods* fm, int32 tmpCharacter_value)
{
int32 character_value = tmpCharacter_value;
if (fm)
character_value += fm->base + fm->class_mod + fm->race_mod + fm->deity_mod;
if(character_value >= 1101) return FACTION_ALLY;
if(character_value >= 701 && character_value <= 1100) return FACTION_WARMLY;
if(character_value >= 401 && character_value <= 700) return FACTION_KINDLY;
if(character_value >= 101 && character_value <= 400) return FACTION_AMIABLE;
if(character_value >= 0 && character_value <= 100) return FACTION_INDIFFERENT;
if(character_value >= -100 && character_value <= -1) return FACTION_APPREHENSIVE;
if(character_value >= -700 && character_value <= -101) return FACTION_DUBIOUS;
if(character_value >= -999 && character_value <= -701) return FACTION_THREATENLY;
if(character_value <= -1000) return FACTION_SCOWLS;
return FACTION_INDIFFERENT;
}
// neotokyo: this function should check if some races have more than one race define
bool IsOfEqualRace(int r1, int r2)
{
if (r1 == r2)
return true;
// TODO: add more values
switch(r1)
{
case DARK_ELF:
if (r2 == 77)
return true;
break;
case BARBARIAN:
if (r2 == 90)
return true;
}
return false;
}
// neotokyo: trolls endure ogres, dark elves, ...
bool IsOfIndiffRace(int r1, int r2)
{
if (r1 == r2)
return true;
// TODO: add more values
switch(r1)
{
case DARK_ELF:
case OGRE:
case TROLL:
if (r2 == OGRE || r2 == TROLL || r2 == DARK_ELF)
return true;
break;
case HUMAN:
case BARBARIAN:
case HALF_ELF:
case GNOME:
case HALFLING:
case WOOD_ELF:
if (r2 == HUMAN ||
r2 == BARBARIAN ||
r2 == ERUDITE ||
r2 == HALF_ELF ||
r2 == GNOME ||
r2 == HALFLING ||
r2 == DWARF ||
r2 == HIGH_ELF ||
r2 == WOOD_ELF)
return true;
break;
case ERUDITE:
if (r2 == HUMAN || r2 == HALF_ELF)
return true;
break;
case DWARF:
if (r2 == HALFLING || r2 == GNOME)
return true;
break;
case HIGH_ELF:
if (r2 == WOOD_ELF)
return true;
break;
case VAHSHIR:
return true;
case IKSAR:
return false;
}
return false;
}

View File

@ -54,14 +54,15 @@ struct FactionMods
int32 race_mod;
int32 deity_mod;
};
struct Faction {
int32 id;
std::map<std::string, int16> mods;
int16 base;
char name[50];
};
typedef map<uint32, int16> faction_map;
typedef std::map<uint32, int16> faction_map;
struct NPCFaction
{
uint32 factionID;
@ -71,6 +72,5 @@ struct NPCFaction
};
const char *FactionValueToString(FACTION_VALUE fv);
char* BuildFactionMessage(int32 tmpvalue, int32 faction_id, int32 totalvalue, uint8 temp);
FACTION_VALUE CalculateFaction(FactionMods* fm, int32 tmpCharacter_value);
#endif

View File

@ -1884,6 +1884,11 @@ void SharedDatabase::LoadLootDrops(void *data, uint32 size) {
++(ld->NumEntries);
++current_entry;
}
if(current_id != 0) {
hash.insert(current_id, loot_drop, (sizeof(LootDrop_Struct) +
(sizeof(LootDropEntries_Struct) * ld->NumEntries)));
}
mysql_free_result(result);
} else {
LogFile->write(EQEMuLog::Error, "Error getting loot drop info from database: %s, %s", query, errbuf);

View File

@ -91,7 +91,6 @@ public:
const NPCFactionList* GetNPCFactionEntry(uint32 id);
void LoadNPCFactionLists(void *data, uint32 size, uint32 list_count, uint32 max_lists);
bool LoadNPCFactionLists();
//bool DBLoadNPCFactionLists(int32 iNPCFactionListCount, uint32 iMaxNPCFactionListID);
//loot
void GetLootTableInfo(uint32 &loot_table_count, uint32 &max_loot_table, uint32 &loot_table_entries);

View File

@ -60,6 +60,51 @@ int main(int argc, char **argv) {
bool load_loot = true;
bool load_skill_caps = true;
bool load_spells = true;
if(argc > 1) {
load_all = false;
load_items = false;
load_factions = false;
load_loot = false;
load_skill_caps = false;
load_spells = false;
for(int i = 1; i < argc; ++i) {
switch(argv[i][0]) {
case 'a':
if(strcasecmp("all", argv[i]) == 0) {
load_all = true;
}
break;
case 'i':
if(strcasecmp("items", argv[i]) == 0) {
load_items = true;
}
break;
case 'f':
if(strcasecmp("factions", argv[i]) == 0) {
load_factions = true;
}
break;
case 'l':
if(strcasecmp("loot", argv[i]) == 0) {
load_loot = true;
}
break;
case 's':
if(strcasecmp("skill_caps", argv[i]) == 0) {
load_skill_caps = true;
} else if(strcasecmp("spells", argv[i]) == 0) {
load_spells = true;
}
break;
}
}
}
if(load_all || load_items) {
LogFile->write(EQEMuLog::Status, "Loading items...");
try {

View File

@ -21,7 +21,6 @@ SET(zone_sources
embxs.cpp
entity.cpp
exp.cpp
faction.cpp
fearpath.cpp
forage.cpp
groups.cpp

View File

@ -8995,11 +8995,7 @@ void Bot::AI_Stop() {
//this is called with 'this' as the mob being looked at, and
//iOther the mob who is doing the looking. It should figure out
//what iOther thinks about 'this'
FACTION_VALUE Bot::GetReverseFactionCon(Mob* iOther) {
#if FACTIONS_DEBUG >= 20
LogFile->write(EQEMuLog::Debug, "called N $s::GetReverseFactionCon(%s)", GetName(), iOther->GetName());
#endif
FACTION_VALUE Bot::GetReverseFactionCon(Mob* iOther) {
_ZP(Bot_GetReverseFactionCon);
if(iOther->IsBot()) {

View File

@ -7289,4 +7289,299 @@ void Client::GarbleMessage(char *message, uint8 variance)
message[i] = alpha_list[rand_char];
}
}
}
}
// returns what Other thinks of this
FACTION_VALUE Client::GetReverseFactionCon(Mob* iOther) {
if (GetOwnerID()) {
return GetOwnerOrSelf()->GetReverseFactionCon(iOther);
}
iOther = iOther->GetOwnerOrSelf();
if (iOther->GetPrimaryFaction() < 0)
return GetSpecialFactionCon(iOther);
if (iOther->GetPrimaryFaction() == 0)
return FACTION_INDIFFERENT;
return GetFactionLevel(CharacterID(), 0, GetRace(), GetClass(), GetDeity(), iOther->GetPrimaryFaction(), iOther);
}
//o--------------------------------------------------------------
//| Name: GetFactionLevel; rembrant, Dec. 16, 2001
//o--------------------------------------------------------------
//| Notes: Gets the characters faction standing with the
//| specified NPC.
//| Will return Indifferent on failure.
//o--------------------------------------------------------------
FACTION_VALUE Client::GetFactionLevel(uint32 char_id, uint32 npc_id, uint32 p_race, uint32 p_class, uint32 p_deity, int32 pFaction, Mob* tnpc)
{
_ZP(Client_GetFactionLevel);
if (pFaction < 0)
return GetSpecialFactionCon(tnpc);
FACTION_VALUE fac = FACTION_INDIFFERENT;
//int32 pFacValue; -Trumpcard: commenting. Not currently used.
int32 tmpFactionValue;
FactionMods fmods;
// neotokyo: few optimizations
if (GetFeigned())
return FACTION_INDIFFERENT;
if (invisible_undead && tnpc && !tnpc->SeeInvisibleUndead())
return FACTION_INDIFFERENT;
if (IsInvisible(tnpc))
return FACTION_INDIFFERENT;
if (tnpc && tnpc->GetOwnerID() != 0) // pets con amiably to owner and indiff to rest
if (char_id == tnpc->GetOwner()->CastToClient()->CharacterID())
return FACTION_AMIABLE;
else
return FACTION_INDIFFERENT;
//First get the NPC's Primary faction
if(pFaction > 0)
{
//Get the faction data from the database
if(database.GetFactionData(&fmods, p_class, p_race, p_deity, pFaction))
{
//Get the players current faction with pFaction
tmpFactionValue = GetCharacterFactionLevel(pFaction);
// Everhood - tack on any bonuses from Alliance type spell effects
tmpFactionValue += GetFactionBonus(pFaction);
tmpFactionValue += GetItemFactionBonus(pFaction);
//Return the faction to the client
fac = CalculateFaction(&fmods, tmpFactionValue);
}
}
else
{
return(FACTION_INDIFFERENT);
}
// merchant fix
if (tnpc && tnpc->IsNPC() && tnpc->CastToNPC()->MerchantType && (fac == FACTION_THREATENLY || fac == FACTION_SCOWLS))
fac = FACTION_DUBIOUS;
if (tnpc != 0 && fac != FACTION_SCOWLS && tnpc->CastToNPC()->CheckAggro(this))
fac = FACTION_THREATENLY;
return fac;
}
//o--------------------------------------------------------------
//| Name: SetFactionLevel; rembrant, Dec. 20, 2001
//o--------------------------------------------------------------
//| Notes: Sets the characters faction standing with the
//| specified NPC.
//o--------------------------------------------------------------
void Client::SetFactionLevel(uint32 char_id, uint32 npc_id, uint8 char_class, uint8 char_race, uint8 char_deity)
{
_ZP(Client_SetFactionLevel);
int32 faction_id[MAX_NPC_FACTIONS]={ 0,0,0,0,0,0,0,0,0,0 };
int32 npc_value[MAX_NPC_FACTIONS]={ 0,0,0,0,0,0,0,0,0,0 };
uint8 temp[MAX_NPC_FACTIONS]={ 0,0,0,0,0,0,0,0,0,0 };
int32 mod;
int32 t;
int32 tmpValue;
int32 current_value;
FactionMods fm;
// Get the npc faction list
if(!database.GetNPCFactionList(npc_id, faction_id, npc_value, temp))
return;
for(int i = 0;i<MAX_NPC_FACTIONS;i++)
{
if(faction_id[i] <= 0)
continue;
// Get the faction modifiers
if(database.GetFactionData(&fm,char_class,char_race,char_deity,faction_id[i]))
{
// Get the characters current value with that faction
current_value = GetCharacterFactionLevel(faction_id[i]);
if(this->itembonuses.HeroicCHA) {
int faction_mod = itembonuses.HeroicCHA / 5;
// If our result isn't truncated, then just do that
if(npc_value[i] * faction_mod / 100 != 0)
npc_value[i] += npc_value[i] * faction_mod / 100;
// If our result is truncated, then double a mob's value every once and a while to equal what they would have got
else {
if(MakeRandomInt(0, 100) < faction_mod)
npc_value[i] *= 2;
}
}
//figure out their modifier
mod = fm.base + fm.class_mod + fm.race_mod + fm.deity_mod;
if(mod > MAX_FACTION)
mod = MAX_FACTION;
else if(mod < MIN_FACTION)
mod = MIN_FACTION;
// Calculate the faction
if(npc_value[i] != 0) {
tmpValue = current_value + mod + npc_value[i];
// Make sure faction hits don't go to GMs...
if (m_pp.gm==1 && (tmpValue < current_value)) {
tmpValue = current_value;
}
// Make sure we dont go over the min/max faction limits
if(tmpValue >= MAX_FACTION)
{
t = MAX_FACTION - mod;
if(current_value == t) {
//do nothing, it is already maxed out
} else if(!(database.SetCharacterFactionLevel(char_id, faction_id[i], t, temp[i], factionvalues)))
{
return;
}
}
else if(tmpValue <= MIN_FACTION)
{
t = MIN_FACTION - mod;
if(current_value == t) {
//do nothing, it is already maxed out
} else if(!(database.SetCharacterFactionLevel(char_id, faction_id[i], t, temp[i], factionvalues)))
{
return;
}
}
else
{
if(!(database.SetCharacterFactionLevel(char_id, faction_id[i], current_value + npc_value[i], temp[i], factionvalues)))
{
return;
}
}
if(tmpValue <= MIN_FACTION)
tmpValue = MIN_FACTION;
char* msg = BuildFactionMessage(npc_value[i],faction_id[i],tmpValue,temp[i]);
if (msg != 0)
Message(0, msg);
safe_delete_array(msg);
}
}
}
return;
}
void Client::SetFactionLevel2(uint32 char_id, int32 faction_id, uint8 char_class, uint8 char_race, uint8 char_deity, int32 value, uint8 temp)
{
_ZP(Client_SetFactionLevel2);
int32 current_value;
//Get the npc faction list
if(faction_id > 0 && value != 0) {
//Get the faction modifiers
current_value = GetCharacterFactionLevel(faction_id) + value;
if(!(database.SetCharacterFactionLevel(char_id, faction_id, current_value, temp, factionvalues)))
return;
char* msg = BuildFactionMessage(value, faction_id, current_value, temp);
if (msg != 0)
Message(0, msg);
safe_delete(msg);
}
return;
}
int32 Client::GetCharacterFactionLevel(int32 faction_id)
{
if (faction_id <= 0)
return 0;
faction_map::iterator res;
res = factionvalues.find(faction_id);
if(res == factionvalues.end())
return(0);
return(res->second);
}
// returns the character's faction level, adjusted for racial, class, and deity modifiers
int32 Client::GetModCharacterFactionLevel(int32 faction_id) {
int32 Modded = GetCharacterFactionLevel(faction_id);
FactionMods fm;
if(database.GetFactionData(&fm,GetClass(),GetRace(),GetDeity(),faction_id))
Modded += fm.base + fm.class_mod + fm.race_mod + fm.deity_mod;
if (Modded > MAX_FACTION)
Modded = MAX_FACTION;
return Modded;
}
bool Client::HatedByClass(uint32 p_race, uint32 p_class, uint32 p_deity, int32 pFaction)
{
bool Result = false;
_ZP(Client_GetFactionLevel);
int32 tmpFactionValue;
FactionMods fmods;
//First get the NPC's Primary faction
if(pFaction > 0)
{
//Get the faction data from the database
if(database.GetFactionData(&fmods, p_class, p_race, p_deity, pFaction))
{
tmpFactionValue = GetCharacterFactionLevel(pFaction);
tmpFactionValue += GetFactionBonus(pFaction);
tmpFactionValue += GetItemFactionBonus(pFaction);
CalculateFaction(&fmods, tmpFactionValue);
if(fmods.class_mod < fmods.race_mod)
Result = true;
}
}
return Result;
}
//o--------------------------------------------------------------
//| Name: BuildFactionMessage; rembrant, Dec. 16, 2001
//o--------------------------------------------------------------
//| Purpose: duh?
//o--------------------------------------------------------------
char* Client::BuildFactionMessage(int32 tmpvalue, int32 faction_id, int32 totalvalue, uint8 temp)
{
/*
This should be replaced to send string-ID based messages using:
#define FACTION_WORST 469 //Your faction standing with %1 could not possibly get any worse.
#define FACTION_WORSE 470 //Your faction standing with %1 got worse.
#define FACTION_BEST 471 //Your faction standing with %1 could not possibly get any better.
#define FACTION_BETTER 472 //Your faction standing with %1 got better.
some day.
*/
//tmpvalue is the change as best I can tell.
char *faction_message = 0;
char name[50];
if(database.GetFactionName(faction_id, name, sizeof(name)) == false) {
snprintf(name, sizeof(name),"Faction%i",faction_id);
}
if(tmpvalue == 0 || temp == 1 || temp == 2) {
return 0;
}
else if (totalvalue >= MAX_FACTION) {
MakeAnyLenString(&faction_message, "Your faction standing with %s could not possibly get any better!", name);
return faction_message;
}
else if(tmpvalue > 0 && totalvalue < MAX_FACTION) {
MakeAnyLenString(&faction_message, "Your faction standing with %s has gotten better!", name);
return faction_message;
}
else if(tmpvalue < 0 && totalvalue > MIN_FACTION) {
MakeAnyLenString(&faction_message, "Your faction standing with %s has gotten worse!", name);
return faction_message;
}
else if(totalvalue <= MIN_FACTION) {
MakeAnyLenString(&faction_message, "Your faction standing with %s could not possibly get any worse!", name);
return faction_message;
}
return 0;
}

View File

@ -565,6 +565,7 @@ public:
int32 GetCharacterFactionLevel(int32 faction_id);
int32 GetModCharacterFactionLevel(int32 faction_id);
bool HatedByClass(uint32 p_race, uint32 p_class, uint32 p_deity, int32 pFaction);
char* BuildFactionMessage(int32 tmpvalue, int32 faction_id, int32 totalvalue, uint8 temp);
void SetFactionLevel(uint32 char_id, uint32 npc_id, uint8 char_class, uint8 char_race, uint8 char_deity);
void SetFactionLevel2(uint32 char_id, int32 faction_id, uint8 char_class, uint8 char_race, uint8 char_deity, int32 value, uint8 temp);

View File

@ -219,7 +219,6 @@ int command_init(void) {
command_add("spoff","- Sends OP_ManaChange",80,command_spoff) ||
command_add("itemtest","- merth's test function",250,command_itemtest) ||
command_add("gassign","[id] - Assign targetted NPC to predefined wandering grid id",100,command_gassign) ||
command_add("setitemstatus","[itemid] [status] - Set the minimum admin status required to use itemid",100,command_setitemstatus) ||
command_add("ai","[factionid/spellslist/con/guard/roambox/stop/start] - Modify AI on NPC target",100,command_ai) ||
command_add("worldshutdown","- Shut down world and all zones",200,command_worldshutdown) ||
command_add("sendzonespawns","- Refresh spawn list for all clients in zone",150,command_sendzonespawns) ||
@ -2174,27 +2173,6 @@ void command_gassign(Client *c, const Seperator *sep)
c->Message(0,"Usage: #gassign [num] - must have an npc target!");
}
void command_setitemstatus(Client *c, const Seperator *sep)
{
if (sep->IsNumber(1) && sep->IsNumber(2)) {
uint32 tmp = atoi(sep->arg[1]);
if (tmp >= 0xFFFF)
c->Message(0, "Item# out of range");
else if (!database.DBSetItemStatus(tmp, atoi(sep->arg[2])))
c->Message(0, "DB query failed");
else {
c->Message(0, "Item updated");
ServerPacket* pack = new ServerPacket(ServerOP_ItemStatus, 5);
*((uint32*) &pack->pBuffer[0]) = tmp;
*((uint8*) &pack->pBuffer[4]) = atoi(sep->arg[2]);
worldserver.SendPacket(pack);
delete pack;
}
}
else
c->Message(0, "Usage: #setitemstatus [itemid] [status]");
}
void command_ai(Client *c, const Seperator *sep)
{
Mob *target=c->GetTarget();
@ -4834,7 +4812,7 @@ void command_iteminfo(Client *c, const Seperator *sep)
c->Message(0, " Lore: %s ND: %i NS: %i Type: %i", (item->LoreFlag) ? "true":"false", item->NoDrop, item->NoRent, item->ItemClass);
c->Message(0, " IDF: %s Size: %i Weight: %i icon_id: %i Price: %i", item->IDFile, item->Size, item->Weight, item->Icon, item->Price);
if (c->Admin() >= 200)
c->Message(0, "MinStatus: %i", database.GetItemStatus(item->ID));
c->Message(0, "MinStatus: %i", item->MinStatus);
if (item->ItemClass==ItemClassBook)
c->Message(0, " This item is a Book: %s", item->Filename);
else if (item->ItemClass==ItemClassContainer)
@ -6189,7 +6167,13 @@ void command_summonitem(Client *c, const Seperator *sep)
c->Message(0, "Usage: #summonitem [item id] [charges], charges are optional");
else {
uint32 itemid = atoi(sep->arg[1]);
if (database.GetItemStatus(itemid) > c->Admin())
int16 item_status = 0;
const Item_Struct* item = database.GetItem(itemid);
if(item) {
item_status = static_cast<int16>(item->MinStatus);
}
if (item_status > c->Admin())
c->Message(13, "Error: Insufficient status to summon this item.");
else if (sep->argnum==2 && sep->IsNumber(2)) {
c->SummonItem(itemid, atoi(sep->arg[2]) );
@ -6220,7 +6204,13 @@ void command_giveitem(Client *c, const Seperator *sep)
} else {
Client *t = c->GetTarget()->CastToClient();
uint32 itemid = atoi(sep->arg[1]);
if (database.GetItemStatus(itemid) > c->Admin())
int16 item_status = 0;
const Item_Struct* item = database.GetItem(itemid);
if(item) {
item_status = static_cast<int16>(item->MinStatus);
}
if (item_status > c->Admin())
c->Message(13, "Error: Insufficient status to summon this item.");
else if (sep->argnum==2 && sep->IsNumber(2)) {
t->SummonItem(itemid, atoi(sep->arg[2]) );
@ -11585,8 +11575,13 @@ void command_zopp(Client *c, const Seperator *sep)
c->Message(13, "Error: Item [%u] is not a valid item id.", itemid);
return;
}
if (database.GetItemStatus(itemid) > c->Admin()) {
int16 item_status = 0;
const Item_Struct* item = database.GetItem(itemid);
if(item) {
item_status = static_cast<int16>(item->MinStatus);
}
if (item_status > c->Admin()) {
c->Message(13, "Error: Insufficient status to use this command.");
return;
}

View File

@ -122,7 +122,6 @@ void command_spon(Client *c, const Seperator *sep);
void command_spoff(Client *c, const Seperator *sep);
void command_itemtest(Client *c, const Seperator *sep);
void command_gassign(Client *c, const Seperator *sep);
void command_setitemstatus(Client *c, const Seperator *sep);
void command_ai(Client *c, const Seperator *sep);
void command_worldshutdown(Client *c, const Seperator *sep);
void command_sendzonespawns(Client *c, const Seperator *sep);

File diff suppressed because it is too large Load Diff

View File

@ -4473,3 +4473,191 @@ bool Mob::PassLimitToSkill(uint16 spell_id, uint16 skill) {
}
return false;
}
// Faction Mods for Alliance type spells
void Mob::AddFactionBonus(uint32 pFactionID,int32 bonus) {
map <uint32, int32> :: const_iterator faction_bonus;
typedef std::pair <uint32, int32> NewFactionBonus;
faction_bonus = faction_bonuses.find(pFactionID);
if(faction_bonus == faction_bonuses.end())
{
faction_bonuses.insert(NewFactionBonus(pFactionID,bonus));
}
else
{
if(faction_bonus->second<bonus)
{
faction_bonuses.erase(pFactionID);
faction_bonuses.insert(NewFactionBonus(pFactionID,bonus));
}
}
}
// Faction Mods from items
void Mob::AddItemFactionBonus(uint32 pFactionID,int32 bonus) {
map <uint32, int32> :: const_iterator faction_bonus;
typedef std::pair <uint32, int32> NewFactionBonus;
faction_bonus = item_faction_bonuses.find(pFactionID);
if(faction_bonus == item_faction_bonuses.end())
{
item_faction_bonuses.insert(NewFactionBonus(pFactionID,bonus));
}
else
{
if((bonus > 0 && faction_bonus->second < bonus) || (bonus < 0 && faction_bonus->second > bonus))
{
item_faction_bonuses.erase(pFactionID);
item_faction_bonuses.insert(NewFactionBonus(pFactionID,bonus));
}
}
}
int32 Mob::GetFactionBonus(uint32 pFactionID) {
map <uint32, int32> :: const_iterator faction_bonus;
faction_bonus = faction_bonuses.find(pFactionID);
if(faction_bonus != faction_bonuses.end())
{
return (*faction_bonus).second;
}
return 0;
}
int32 Mob::GetItemFactionBonus(uint32 pFactionID) {
map <uint32, int32> :: const_iterator faction_bonus;
faction_bonus = item_faction_bonuses.find(pFactionID);
if(faction_bonus != item_faction_bonuses.end())
{
return (*faction_bonus).second;
}
return 0;
}
void Mob::ClearItemFactionBonuses() {
map <uint32, int32> :: iterator itr;
for(itr = item_faction_bonuses.begin(); itr != item_faction_bonuses.end(); itr++)
{
item_faction_bonuses.erase(itr->first);
}
}
FACTION_VALUE Mob::GetSpecialFactionCon(Mob* iOther) {
if (!iOther)
return FACTION_INDIFFERENT;
iOther = iOther->GetOwnerOrSelf();
Mob* self = this->GetOwnerOrSelf();
bool selfAIcontrolled = self->IsAIControlled();
bool iOtherAIControlled = iOther->IsAIControlled();
int selfPrimaryFaction = self->GetPrimaryFaction();
int iOtherPrimaryFaction = iOther->GetPrimaryFaction();
if (selfPrimaryFaction >= 0 && selfAIcontrolled)
return FACTION_INDIFFERENT;
if (iOther->GetPrimaryFaction() >= 0)
return FACTION_INDIFFERENT;
/* special values:
-2 = indiff to player, ally to AI on special values, indiff to AI
-3 = dub to player, ally to AI on special values, indiff to AI
-4 = atk to player, ally to AI on special values, indiff to AI
-5 = indiff to player, indiff to AI
-6 = dub to player, indiff to AI
-7 = atk to player, indiff to AI
-8 = indiff to players, ally to AI on same value, indiff to AI
-9 = dub to players, ally to AI on same value, indiff to AI
-10 = atk to players, ally to AI on same value, indiff to AI
-11 = indiff to players, ally to AI on same value, atk to AI
-12 = dub to players, ally to AI on same value, atk to AI
-13 = atk to players, ally to AI on same value, atk to AI
*/
switch (iOtherPrimaryFaction) {
case -2: // -2 = indiff to player, ally to AI on special values, indiff to AI
if (selfAIcontrolled && iOtherAIControlled)
return FACTION_ALLY;
else
return FACTION_INDIFFERENT;
case -3: // -3 = dub to player, ally to AI on special values, indiff to AI
if (selfAIcontrolled && iOtherAIControlled)
return FACTION_ALLY;
else
return FACTION_DUBIOUS;
case -4: // -4 = atk to player, ally to AI on special values, indiff to AI
if (selfAIcontrolled && iOtherAIControlled)
return FACTION_ALLY;
else
return FACTION_SCOWLS;
case -5: // -5 = indiff to player, indiff to AI
return FACTION_INDIFFERENT;
case -6: // -6 = dub to player, indiff to AI
if (selfAIcontrolled && iOtherAIControlled)
return FACTION_INDIFFERENT;
else
return FACTION_DUBIOUS;
case -7: // -7 = atk to player, indiff to AI
if (selfAIcontrolled && iOtherAIControlled)
return FACTION_INDIFFERENT;
else
return FACTION_SCOWLS;
case -8: // -8 = indiff to players, ally to AI on same value, indiff to AI
if (selfAIcontrolled && iOtherAIControlled) {
if (selfPrimaryFaction == iOtherPrimaryFaction)
return FACTION_ALLY;
else
return FACTION_INDIFFERENT;
}
else
return FACTION_INDIFFERENT;
case -9: // -9 = dub to players, ally to AI on same value, indiff to AI
if (selfAIcontrolled && iOtherAIControlled) {
if (selfPrimaryFaction == iOtherPrimaryFaction)
return FACTION_ALLY;
else
return FACTION_INDIFFERENT;
}
else
return FACTION_DUBIOUS;
case -10: // -10 = atk to players, ally to AI on same value, indiff to AI
if (selfAIcontrolled && iOtherAIControlled) {
if (selfPrimaryFaction == iOtherPrimaryFaction)
return FACTION_ALLY;
else
return FACTION_INDIFFERENT;
}
else
return FACTION_SCOWLS;
case -11: // -11 = indiff to players, ally to AI on same value, atk to AI
if (selfAIcontrolled && iOtherAIControlled) {
if (selfPrimaryFaction == iOtherPrimaryFaction)
return FACTION_ALLY;
else
return FACTION_SCOWLS;
}
else
return FACTION_INDIFFERENT;
case -12: // -12 = dub to players, ally to AI on same value, atk to AI
if (selfAIcontrolled && iOtherAIControlled) {
if (selfPrimaryFaction == iOtherPrimaryFaction)
return FACTION_ALLY;
else
return FACTION_SCOWLS;
}
else
return FACTION_DUBIOUS;
case -13: // -13 = atk to players, ally to AI on same value, atk to AI
if (selfAIcontrolled && iOtherAIControlled) {
if (selfPrimaryFaction == iOtherPrimaryFaction)
return FACTION_ALLY;
else
return FACTION_SCOWLS;
}
else
return FACTION_SCOWLS;
default:
return FACTION_INDIFFERENT;
}
}

View File

@ -217,7 +217,7 @@ int main(int argc, char** argv) {
_log(ZONE__INIT_ERR, "Loading items FAILED!");
_log(ZONE__INIT, "Failed. But ignoring error and going on...");
}
database.LoadItemStatus();
_log(ZONE__INIT, "Loading npc faction lists");
if (!database.LoadNPCFactionLists()) {
_log(ZONE__INIT_ERR, "Loading npcs faction lists FAILED!");

View File

@ -2348,3 +2348,62 @@ void NPC::PrintOutQuestItems(Client* c){
c->Message(4,"End of quest items list.");
}
//this is called with 'this' as the mob being looked at, and
//iOther the mob who is doing the looking. It should figure out
//what iOther thinks about 'this'
FACTION_VALUE NPC::GetReverseFactionCon(Mob* iOther) {
_ZP(NPC_GetReverseFactionCon);
iOther = iOther->GetOwnerOrSelf();
int primaryFaction= iOther->GetPrimaryFaction();
//I am pretty sure that this special faction call is backwards
//and should be iOther->GetSpecialFactionCon(this)
if (primaryFaction < 0)
return GetSpecialFactionCon(iOther);
if (primaryFaction == 0)
return FACTION_INDIFFERENT;
//if we are a pet, use our owner's faction stuff
Mob *own = GetOwner();
if (own != NULL)
return own->GetReverseFactionCon(iOther);
//make sure iOther is an npc
//also, if we dont have a faction, then they arnt gunna think anything of us either
if(!iOther->IsNPC() || GetPrimaryFaction() == 0)
return(FACTION_INDIFFERENT);
//if we get here, iOther is an NPC too
//otherwise, employ the npc faction stuff
//so we need to look at iOther's faction table to see
//what iOther thinks about our primary faction
return(iOther->CastToNPC()->CheckNPCFactionAlly(GetPrimaryFaction()));
}
//Look through our faction list and return a faction con based
//on the npc_value for the other person's primary faction in our list.
FACTION_VALUE NPC::CheckNPCFactionAlly(int32 other_faction) {
list<struct NPCFaction*>::iterator cur,end;
cur = faction_list.begin();
end = faction_list.end();
for(; cur != end; cur++) {
struct NPCFaction* fac = *cur;
if ((int32)fac->factionID == other_faction) {
if (fac->npc_value > 0)
return FACTION_ALLY;
else if (fac->npc_value < 0)
return FACTION_SCOWLS;
else
return FACTION_INDIFFERENT;
}
}
return FACTION_INDIFFERENT;
}
bool NPC::IsFactionListAlly(uint32 other_faction) {
return(CheckNPCFactionAlly(other_faction) == FACTION_ALLY);
}

View File

@ -793,14 +793,6 @@ void WorldServer::Process() {
client->SetWID(scw->newwid);
break;
}
case ServerOP_ItemStatus: {
if (pack->size != 5) {
cout << "Wrong size on ServerChangeWID_Struct. Got: " << pack->size << ", Expected: 5" << endl;
break;
}
database.SetItemStatus(*((uint32*) &pack->pBuffer[0]), *((uint8*) &pack->pBuffer[4]));
break;
}
case ServerOP_OOCMute: {
oocmuted = *(pack->pBuffer);
break;

View File

@ -33,7 +33,6 @@ ZoneDatabase::ZoneDatabase(const char* host, const char* user, const char* passw
}
void ZoneDatabase::ZDBInitVars() {
memset(item_minstatus, 0, sizeof(item_minstatus));
memset(door_isopen_array, 0, sizeof(door_isopen_array));
npc_spells_maxid = 0;
npc_spells_cache = 0;
@ -982,41 +981,6 @@ bool ZoneDatabase::NoRentExpired(const char* name){
return false;
}
void ZoneDatabase::LoadItemStatus() {
memset(item_minstatus, 0, sizeof(item_minstatus));
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
MYSQL_RES *result;
MYSQL_ROW row;
uint32 tmp;
if (RunQuery(query, MakeAnyLenString(&query, "Select id, minstatus from items where minstatus > 0"), errbuf, &result)) {
safe_delete_array(query);
while ((row = mysql_fetch_row(result)) && row[0] && row[1]) {
tmp = atoi(row[0]);
if (tmp < MAX_ITEM_ID)
item_minstatus[tmp] = atoi(row[1]);
}
mysql_free_result(result);
}
else {
cout << "Error in LoadItemStatus query: '" << query << "'" << endl;
safe_delete_array(query);
}
}
bool ZoneDatabase::DBSetItemStatus(uint32 id, uint8 status) {
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
uint32 affected_rows = 0;
if (!RunQuery(query, MakeAnyLenString(&query, "Update items set minstatus=%u where id=%u", status, id), errbuf, 0, &affected_rows)) {
cout << "Error in LoadItemStatus query: '" << query << "'" << endl;
}
safe_delete_array(query);
return (bool) (affected_rows == 1);
}
/* Searches npctable for matching id, and returns the item if found,
* or NULL otherwise. If id passed is 0, loads all npc_types for
* the current zone, returning the last item added.
@ -2883,5 +2847,289 @@ void ZoneDatabase::LoadPetInfo(Client *c) {
safe_delete_array(query);
return;
}
}
}
bool ZoneDatabase::GetFactionData(FactionMods* fm, uint32 class_mod, uint32 race_mod, uint32 deity_mod, int32 faction_id) {
if (faction_id <= 0 || faction_id > (int32) max_faction)
return false;
if (faction_array[faction_id] == 0){
return false;
}
fm->base = faction_array[faction_id]->base;
if(class_mod > 0) {
char str[32];
sprintf(str, "c%u", class_mod);
std::map<std::string, int16>::const_iterator iter = faction_array[faction_id]->mods.find(str);
if(iter != faction_array[faction_id]->mods.end()) {
fm->class_mod = iter->second;
} else {
fm->class_mod = 0;
}
} else {
fm->class_mod = 0;
}
if(race_mod > 0) {
char str[32];
sprintf(str, "r%u", race_mod);
std::map<std::string, int16>::iterator iter = faction_array[faction_id]->mods.find(str);
if(iter != faction_array[faction_id]->mods.end()) {
fm->race_mod = iter->second;
} else {
fm->race_mod = 0;
}
} else {
fm->race_mod = 0;
}
if(deity_mod > 0) {
char str[32];
sprintf(str, "d%u", deity_mod);
std::map<std::string, int16>::iterator iter = faction_array[faction_id]->mods.find(str);
if(iter != faction_array[faction_id]->mods.end()) {
fm->deity_mod = iter->second;
} else {
fm->deity_mod = 0;
}
} else {
fm->deity_mod = 0;
}
return true;
}
bool ZoneDatabase::LoadFactionValues(uint32 char_id, faction_map & val_list) {
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
MYSQL_RES *result;
if (RunQuery(query, MakeAnyLenString(&query, "SELECT faction_id,current_value FROM faction_values WHERE char_id = %i",char_id), errbuf, &result)) {
safe_delete_array(query);
bool ret = LoadFactionValues_result(result, val_list);
mysql_free_result(result);
return ret;
}
else {
cerr << "Error in LoadFactionValues query '" << query << "' " << errbuf << endl;
safe_delete_array(query);
}
return false;
}
bool ZoneDatabase::LoadFactionValues_result(MYSQL_RES* result, faction_map & val_list) {
MYSQL_ROW row;
while((row = mysql_fetch_row(result))) {
val_list[atoi(row[0])] = atoi(row[1]);
}
return true;
}
//o--------------------------------------------------------------
//| Name: GetFactionName; rembrant, Dec. 16
//o--------------------------------------------------------------
//| Notes: Retrieves the name of the specified faction
//| Returns false on failure.
//o--------------------------------------------------------------
bool ZoneDatabase::GetFactionName(int32 faction_id, char* name, uint32 buflen) {
if ((faction_id <= 0) || faction_id > int32(max_faction) ||(faction_array[faction_id] == 0))
return false;
if (faction_array[faction_id]->name[0] != 0) {
strn0cpy(name, faction_array[faction_id]->name, buflen);
return true;
}
return false;
}
//o--------------------------------------------------------------
//| Name: GetNPCFactionList; rembrant, Dec. 16, 2001
//o--------------------------------------------------------------
//| Purpose: Gets a list of faction_id's and values bound to
//| the npc_id.
//| Returns false on failure.
//o--------------------------------------------------------------
bool ZoneDatabase::GetNPCFactionList(uint32 npcfaction_id, int32* faction_id, int32* value, uint8* temp, int32* primary_faction) {
if (npcfaction_id <= 0) {
if (primary_faction)
*primary_faction = npcfaction_id;
return true;
}
const NPCFactionList* nfl = GetNPCFactionEntry(npcfaction_id);
if (!nfl)
return false;
if (primary_faction)
*primary_faction = nfl->primaryfaction;
for (int i=0; i<MAX_NPC_FACTIONS; i++) {
faction_id[i] = nfl->factionid[i];
value[i] = nfl->factionvalue[i];
temp[i] = nfl->factiontemp[i];
}
return true;
}
//o--------------------------------------------------------------
//| Name: SetCharacterFactionLevel; rembrant, Dec. 20, 2001
//o--------------------------------------------------------------
//| Purpose: Update characters faction level with specified
//| faction_id to specified value.
//| Returns false on failure.
//o--------------------------------------------------------------
bool ZoneDatabase::SetCharacterFactionLevel(uint32 char_id, int32 faction_id, int32 value, uint8 temp, faction_map &val_list)
{
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
uint32 affected_rows = 0;
if (!RunQuery(query, MakeAnyLenString(&query,
"DELETE FROM faction_values WHERE char_id=%i AND faction_id = %i",
char_id, faction_id), errbuf)) {
cerr << "Error in SetCharacterFactionLevel query '" << query << "' " << errbuf << endl;
safe_delete_array(query);
return false;
}
if(value == 0)
{
safe_delete_array(query);
return true;
}
if(temp == 2)
temp = 0;
if(temp == 3)
temp = 1;
if (!RunQuery(query, MakeAnyLenString(&query,
"INSERT INTO faction_values (char_id,faction_id,current_value,temp) VALUES (%i,%i,%i,%i)",
char_id, faction_id,value,temp), errbuf, 0, &affected_rows)) {
cerr << "Error in SetCharacterFactionLevel query '" << query << "' " << errbuf << endl;
safe_delete_array(query);
return false;
}
safe_delete_array(query);
if (affected_rows == 0)
{
return false;
}
val_list[faction_id] = value;
return(true);
}
bool ZoneDatabase::LoadFactionData()
{
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
MYSQL_RES *result;
MYSQL_ROW row;
query = new char[256];
strcpy(query, "SELECT MAX(id) FROM faction_list");
if (RunQuery(query, strlen(query), errbuf, &result)) {
safe_delete_array(query);
row = mysql_fetch_row(result);
if (row && row[0])
{
max_faction = atoi(row[0]);
faction_array = new Faction*[max_faction+1];
for(unsigned int i=0; i<max_faction; i++)
{
faction_array[i] = NULL;
}
mysql_free_result(result);
MakeAnyLenString(&query, "SELECT id,name,base FROM faction_list");
if (RunQuery(query, strlen(query), errbuf, &result))
{
safe_delete_array(query);
while((row = mysql_fetch_row(result)))
{
uint32 index = atoi(row[0]);
faction_array[index] = new Faction;
strn0cpy(faction_array[index]->name, row[1], 50);
faction_array[index]->base = atoi(row[2]);
char sec_errbuf[MYSQL_ERRMSG_SIZE];
MYSQL_RES *sec_result;
MYSQL_ROW sec_row;
MakeAnyLenString(&query, "SELECT `mod`, `mod_name` FROM `faction_list_mod` WHERE faction_id=%u", index);
if (RunQuery(query, strlen(query), sec_errbuf, &sec_result)) {
while((sec_row = mysql_fetch_row(sec_result)))
{
faction_array[index]->mods[sec_row[1]] = atoi(sec_row[0]);
}
mysql_free_result(sec_result);
}
safe_delete_array(query);
}
mysql_free_result(result);
}
else {
cerr << "Error in LoadFactionData '" << query << "' " << errbuf << endl;
safe_delete_array(query);
return false;
}
}
else {
mysql_free_result(result);
}
}
else {
cerr << "Error in LoadFactionData '" << query << "' " << errbuf << endl;
safe_delete_array(query);
return false;
}
return true;
}
bool ZoneDatabase::GetFactionIdsForNPC(uint32 nfl_id, list<struct NPCFaction*> *faction_list, int32* primary_faction) {
if (nfl_id <= 0) {
list<struct NPCFaction*>::iterator cur,end;
cur = faction_list->begin();
end = faction_list->end();
for(; cur != end; cur++) {
struct NPCFaction* tmp = *cur;
safe_delete(tmp);
}
faction_list->clear();
if (primary_faction)
*primary_faction = nfl_id;
return true;
}
const NPCFactionList* nfl = GetNPCFactionEntry(nfl_id);
if (!nfl)
return false;
if (primary_faction)
*primary_faction = nfl->primaryfaction;
list<struct NPCFaction*>::iterator cur,end;
cur = faction_list->begin();
end = faction_list->end();
for(; cur != end; cur++) {
struct NPCFaction* tmp = *cur;
safe_delete(tmp);
}
faction_list->clear();
for (int i=0; i<MAX_NPC_FACTIONS; i++) {
struct NPCFaction *pFac;
if (nfl->factionid[i]) {
pFac = new struct NPCFaction;
pFac->factionID = nfl->factionid[i];
pFac->value_mod = nfl->factionvalue[i];
pFac->npc_value = nfl->factionnpcvalue[i];
pFac->temp = nfl->factiontemp[i];
faction_list->push_back(pFac);
}
}
return true;
}

View File

@ -282,7 +282,6 @@ public:
bool LoadAAEffects();
bool LoadAAEffects2();
bool LoadSwarmSpells();
// uint32 GetPlayerAlternateAdv(uint32 account_id, char* name, PlayerAA_Struct* aa);
SendAA_Struct* GetAASkillVars(uint32 skill_id);
uint8 GetTotalAALevels(uint32 skill_id);
uint32 GetSizeAA();
@ -303,14 +302,6 @@ public:
uint8 GetUseCFGSafeCoords();
int getZoneShutDownDelay(uint32 zoneID, uint32 version);
/*
* Item
*/
void LoadItemStatus();
inline uint8 GetItemStatus(uint32 id) { if (id < MAX_ITEM_ID) { return item_minstatus[id]; } return 0; }
inline void SetItemStatus(uint32 id, uint8 status) { if (id < MAX_ITEM_ID) { item_minstatus[id] = status; } }
bool DBSetItemStatus(uint32 id, uint8 status);
/*
* Spawns and Spawn Points
*/
@ -401,7 +392,6 @@ public:
/*
* Doors
*/
uint32 MaxDoors() { return max_door_type; }
bool DoorIsOpen(uint8 door_id,const char* zone_name);
void SetDoorPlace(uint8 value,uint8 door_id,const char* zone_name);
bool LoadDoors(int32 iDoorCount, Door *into, const char *zone_name, int16 version);
@ -484,11 +474,9 @@ protected:
uint32 max_faction;
Faction** faction_array;
uint32 max_door_type;
uint32 npc_spells_maxid;
DBnpcspells_Struct** npc_spells_cache;
bool* npc_spells_loadtried;
uint8 item_minstatus[MAX_ITEM_ID];
uint8 door_isopen_array[255];
};