From 147c96970c89b5ef312e70973ca48ce3eb435c1d Mon Sep 17 00:00:00 2001 From: KimLS Date: Sat, 23 Feb 2013 15:03:15 -0800 Subject: [PATCH] Moved faction stuff around, removed stupid external item status stuff --- common/CMakeLists.txt | 1 + common/faction.cpp | 141 ++++++ common/faction.h | 4 +- common/shareddb.cpp | 5 + common/shareddb.h | 1 - shared_memory/main.cpp | 45 ++ zone/CMakeLists.txt | 1 - zone/bot.cpp | 6 +- zone/client.cpp | 297 ++++++++++- zone/client.h | 1 + zone/command.cpp | 49 +- zone/command.h | 1 - zone/faction.cpp | 1065 ---------------------------------------- zone/mob.cpp | 188 +++++++ zone/net.cpp | 2 +- zone/npc.cpp | 59 +++ zone/worldserver.cpp | 8 - zone/zonedb.cpp | 322 ++++++++++-- zone/zonedb.h | 12 - 19 files changed, 1047 insertions(+), 1161 deletions(-) create mode 100644 common/faction.cpp delete mode 100644 zone/faction.cpp diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index e1e058e35..2cb7a8a70 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -27,6 +27,7 @@ SET(common_sources EQStreamProxy.cpp eqtime.cpp extprofile.cpp + faction.cpp guild_base.cpp guilds.cpp ipc_mutex.cpp diff --git a/common/faction.cpp b/common/faction.cpp new file mode 100644 index 000000000..9a8e27db2 --- /dev/null +++ b/common/faction.cpp @@ -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; +} + diff --git a/common/faction.h b/common/faction.h index 7601e878c..ca9f4107d 100644 --- a/common/faction.h +++ b/common/faction.h @@ -54,14 +54,15 @@ struct FactionMods int32 race_mod; int32 deity_mod; }; + struct Faction { int32 id; std::map mods; int16 base; char name[50]; }; -typedef map faction_map; +typedef std::map 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 diff --git a/common/shareddb.cpp b/common/shareddb.cpp index 6021c6954..f4b4faeea 100644 --- a/common/shareddb.cpp +++ b/common/shareddb.cpp @@ -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); diff --git a/common/shareddb.h b/common/shareddb.h index 5bbfef8b0..d739bef19 100644 --- a/common/shareddb.h +++ b/common/shareddb.h @@ -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); diff --git a/shared_memory/main.cpp b/shared_memory/main.cpp index b8d5012b8..f13413d63 100644 --- a/shared_memory/main.cpp +++ b/shared_memory/main.cpp @@ -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 { diff --git a/zone/CMakeLists.txt b/zone/CMakeLists.txt index 2f6cf341a..e0b0d01b6 100644 --- a/zone/CMakeLists.txt +++ b/zone/CMakeLists.txt @@ -21,7 +21,6 @@ SET(zone_sources embxs.cpp entity.cpp exp.cpp - faction.cpp fearpath.cpp forage.cpp groups.cpp diff --git a/zone/bot.cpp b/zone/bot.cpp index 774fb3f73..48f9fc9a1 100644 --- a/zone/bot.cpp +++ b/zone/bot.cpp @@ -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()) { diff --git a/zone/client.cpp b/zone/client.cpp index 44419bfcd..b0740bf01 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -7289,4 +7289,299 @@ void Client::GarbleMessage(char *message, uint8 variance) message[i] = alpha_list[rand_char]; } } -} \ No newline at end of file +} + +// 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;iitembonuses.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; +} diff --git a/zone/client.h b/zone/client.h index 3ea8f364b..a834b4e5f 100644 --- a/zone/client.h +++ b/zone/client.h @@ -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); diff --git a/zone/command.cpp b/zone/command.cpp index 1c80c387c..432aad4a4 100644 --- a/zone/command.cpp +++ b/zone/command.cpp @@ -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(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(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(item->MinStatus); + } + if (item_status > c->Admin()) { c->Message(13, "Error: Insufficient status to use this command."); return; } diff --git a/zone/command.h b/zone/command.h index 4cc8454b3..0696d7b19 100644 --- a/zone/command.h +++ b/zone/command.h @@ -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); diff --git a/zone/faction.cpp b/zone/faction.cpp deleted file mode 100644 index d0341cb50..000000000 --- a/zone/faction.cpp +++ /dev/null @@ -1,1065 +0,0 @@ -/* 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 "../common/debug.h" -#include -using namespace std; -#include -#include - -#ifndef WIN32 - #include -#endif -#include "../common/faction.h" -#include "zonedb.h" -#include "masterentity.h" -#include "zone.h" -#include "../common/MiscFunctions.h" - -extern Zone* zone; - -//TODO: This file is terrible: half of it needs to be in common and half in zone - -#ifdef _WINDOWS - #define snprintf _snprintf -#endif - -//#define FACTIONS_DEBUG 5 - -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) -{ -#if FACTIONS_DEBUG >= 5 - LogFile->write(EQEMuLog::Debug, "called CalculateFaction(0x%x, %ld)", fm, (unsigned long)tmpCharacter_value); -#endif - 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; -} - -// returns what Other thinks of this -FACTION_VALUE Client::GetReverseFactionCon(Mob* iOther) { -#if FACTIONS_DEBUG >= 5 - LogFile->write(EQEMuLog::Debug, "called $s::GetReverseFactionCon(%s)", GetName(), iOther->GetName()); -#endif - - if (GetOwnerID()) { - return GetOwnerOrSelf()->GetReverseFactionCon(iOther); - } - - iOther = iOther->GetOwnerOrSelf(); - -#if FACTIONS_DEBUG >= 5 - LogFile->write(EQEMuLog::Debug, " %s'd primary faction = %d", iOther->GetName(), iOther->GetPrimaryFaction()); -#endif - if (iOther->GetPrimaryFaction() < 0) - return GetSpecialFactionCon(iOther); - - if (iOther->GetPrimaryFaction() == 0) - return FACTION_INDIFFERENT; - - return GetFactionLevel(CharacterID(), 0, GetRace(), GetClass(), GetDeity(), iOther->GetPrimaryFaction(), iOther); -} - -//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) { -#if FACTIONS_DEBUG >= 20 - LogFile->write(EQEMuLog::Debug, "called N $s::GetReverseFactionCon(%s)", GetName(), iOther->GetName()); -#endif - - _ZP(NPC_GetReverseFactionCon); - - iOther = iOther->GetOwnerOrSelf(); - int primaryFaction= iOther->GetPrimaryFaction(); - -#if FACTIONS_DEBUG >= 20 - LogFile->write(EQEMuLog::Debug, " %s'd primary faction = %d", iOther->GetName(), primaryFaction); -#endif - - //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::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) { -/* list::iterator cur,end; - cur = faction_list.begin(); - end = faction_list.end(); - for(; cur != end; cur++) { - struct NPCFaction* fac = *cur; - if (fac->factionID == other_faction && fac->npc_value > 0) - return(true); - } - return(false);*/ - return(CheckNPCFactionAlly(other_faction) == FACTION_ALLY); -} - -// Faction Mods for Alliance type spells -void Mob::AddFactionBonus(uint32 pFactionID,int32 bonus) { - map :: const_iterator faction_bonus; - typedef std::pair NewFactionBonus; - - faction_bonus = faction_bonuses.find(pFactionID); - if(faction_bonus == faction_bonuses.end()) - { - faction_bonuses.insert(NewFactionBonus(pFactionID,bonus)); - } - else - { - if(faction_bonus->second :: const_iterator faction_bonus; - typedef std::pair 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 :: 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 :: 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 :: 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 FACTIONS_DEBUG >= 5 - LogFile->write(EQEMuLog::Debug, "called $s::GetSpecialFactionCon(%s)", GetName(), iOther->GetName()); -#endif - - 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 FACTIONS_DEBUG >= 5 - LogFile->write(EQEMuLog::Debug, " GSFC %d %d %d %d", selfAIcontrolled, iOtherAIControlled, selfPrimaryFaction, iOtherPrimaryFaction); -#endif - - 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; - } -} - -//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) -{ -#if FACTIONS_DEBUG >= 5 - LogFile->write(EQEMuLog::Debug, "called %s::GetFactionLevel(%lu, %lu, %lu, %lu, %lu, %lu, %s)", GetName(), (unsigned long)char_id, (unsigned long)npc_id, (unsigned long)p_race, (unsigned long)p_class, (unsigned long)p_deity, (unsigned long)pFaction, tnpc?tnpc->GetName():"(NULL)"); -#endif - - _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); - //Message(0,"Faction: %i %i %i %i",fmods.base,fmods.class_mod,fmods.race_mod,fmods.deity_mod); - //Message(0,"tmpFactionValue: %i, fac: %i",tmpFactionValue,fac); - } - } - else - { //pFaction == 0 - return(FACTION_INDIFFERENT); - /* - I think this is a good idea, but the consensus seems to be - that if the faction is not in the DB, it should not be - made up based on race and class like this is doing. - - fmods.base = 0; - fmods.deity_mod = 0; - - if (tnpc && p_class == (uint32) tnpc->GetClass()%16) - fmods.class_mod = 301; - else if (tnpc && tnpc->IsNPC() && tnpc->CastToNPC()->MerchantType == 0) - fmods.class_mod = -101; - else - fmods.class_mod = 0; - - if (tnpc && IsOfEqualRace(p_race, tnpc->GetRace()) ) - fmods.race_mod = 101; - else if (tnpc && IsOfIndiffRace(p_race, tnpc->GetRace()) ) - fmods.race_mod = 0; - else if (tnpc) - fmods.race_mod = -51; - else - fmods.race_mod = 0; - fac = CalculateFaction(&fmods, 0); - */ - } - - // 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; - -#if FACTIONS_DEBUG >= 5 - LogFile->write(EQEMuLog::Debug, "%s::GetFactionLevel() result: %d", GetName(), fac); -#endif - 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;iitembonuses.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 tmpValue; - int32 current_value; -// FactionMods fm; - //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 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::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::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::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: BuildFactionMessage; rembrant, Dec. 16, 2001 -//o-------------------------------------------------------------- -//| Purpose: duh? -//o-------------------------------------------------------------- -char* 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; -} - -//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; ifactionid[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; iname, 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 *faction_list, int32* primary_faction) { - if (nfl_id <= 0) { - list::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::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; ifactionid[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]; -/* if (nfl->primaryfaction == pFac->factionID) - pFac->primary = true; - else - pFac->primary = false; -*/ - faction_list->push_back(pFac); - } - } - return true; -} - -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; -} diff --git a/zone/mob.cpp b/zone/mob.cpp index e7410e33e..8bd2d362c 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -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 :: const_iterator faction_bonus; + typedef std::pair NewFactionBonus; + + faction_bonus = faction_bonuses.find(pFactionID); + if(faction_bonus == faction_bonuses.end()) + { + faction_bonuses.insert(NewFactionBonus(pFactionID,bonus)); + } + else + { + if(faction_bonus->second :: const_iterator faction_bonus; + typedef std::pair 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 :: 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 :: 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 :: 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; + } +} + diff --git a/zone/net.cpp b/zone/net.cpp index ed6244aa6..52a3bedb9 100644 --- a/zone/net.cpp +++ b/zone/net.cpp @@ -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!"); diff --git a/zone/npc.cpp b/zone/npc.cpp index 337b0a149..9775a04eb 100644 --- a/zone/npc.cpp +++ b/zone/npc.cpp @@ -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::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); +} diff --git a/zone/worldserver.cpp b/zone/worldserver.cpp index 837ef3278..486e6a02a 100644 --- a/zone/worldserver.cpp +++ b/zone/worldserver.cpp @@ -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; diff --git a/zone/zonedb.cpp b/zone/zonedb.cpp index f94960ac1..09cd3dec8 100644 --- a/zone/zonedb.cpp +++ b/zone/zonedb.cpp @@ -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; } +} -} \ No newline at end of file +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::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::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::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; ifactionid[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; iname, 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 *faction_list, int32* primary_faction) { + if (nfl_id <= 0) { + list::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::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; ifactionid[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; +} diff --git a/zone/zonedb.h b/zone/zonedb.h index 4727a0281..c2e7b12b6 100644 --- a/zone/zonedb.h +++ b/zone/zonedb.h @@ -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]; };