Merge remote-tracking branch 'remotes/origin/master' into logging_changes

Conflicts:
	zone/command.cpp
	zone/command.h
	zone/inventory.cpp
This commit is contained in:
Akkadius
2015-01-21 16:40:46 -06:00
37 changed files with 6196 additions and 3324 deletions
+1
View File
@@ -109,6 +109,7 @@ SET(zone_sources
trading.cpp
trap.cpp
tribute.cpp
tune.cpp
water_map.cpp
water_map_v1.cpp
water_map_v2.cpp
+17 -10
View File
@@ -2802,8 +2802,8 @@ void Client::Message_StringID(uint32 type, uint32 string_id, const char* message
if (GetFilter(FilterDamageShields) == FilterHide && type == MT_DS)
return;
int i, argcount, length;
char *bufptr;
int i = 0, argcount = 0, length = 0;
char *bufptr = nullptr;
const char *message_arg[9] = {0};
if(type==MT_Emote)
@@ -2815,7 +2815,6 @@ void Client::Message_StringID(uint32 type, uint32 string_id, const char* message
return;
}
i = 0;
message_arg[i++] = message1;
message_arg[i++] = message2;
message_arg[i++] = message3;
@@ -2826,10 +2825,12 @@ void Client::Message_StringID(uint32 type, uint32 string_id, const char* message
message_arg[i++] = message8;
message_arg[i++] = message9;
for(argcount = length = 0; message_arg[argcount]; argcount++)
for(; message_arg[argcount]; ++argcount)
length += strlen(message_arg[argcount]) + 1;
EQApplicationPacket* outapp = new EQApplicationPacket(OP_FormattedMessage, length+13);
length += 1;
EQApplicationPacket* outapp = new EQApplicationPacket(OP_FormattedMessage, sizeof(FormattedMessage_Struct) + length);
FormattedMessage_Struct *fm = (FormattedMessage_Struct *)outapp->pBuffer;
fm->string_id = string_id;
fm->type = type;
@@ -2840,6 +2841,8 @@ void Client::Message_StringID(uint32 type, uint32 string_id, const char* message
bufptr += strlen(message_arg[i]) + 1;
}
// since we're moving the pointer the 0 offset is correct
bufptr[0] = '\0';
if(distance>0)
entity_list.QueueCloseClients(this,outapp,false,distance);
@@ -2914,8 +2917,8 @@ void Client::FilteredMessage_StringID(Mob *sender, uint32 type, eqFilterType fil
if (!FilteredMessageCheck(sender, filter))
return;
int i, argcount, length;
char *bufptr;
int i = 0, argcount = 0, length = 0;
char *bufptr = nullptr;
const char *message_arg[9] = {0};
if (type == MT_Emote)
@@ -2926,7 +2929,6 @@ void Client::FilteredMessage_StringID(Mob *sender, uint32 type, eqFilterType fil
return;
}
i = 0;
message_arg[i++] = message1;
message_arg[i++] = message2;
message_arg[i++] = message3;
@@ -2937,10 +2939,12 @@ void Client::FilteredMessage_StringID(Mob *sender, uint32 type, eqFilterType fil
message_arg[i++] = message8;
message_arg[i++] = message9;
for (argcount = length = 0; message_arg[argcount]; argcount++)
for (; message_arg[argcount]; ++argcount)
length += strlen(message_arg[argcount]) + 1;
EQApplicationPacket *outapp = new EQApplicationPacket(OP_FormattedMessage, length+13);
length += 1;
EQApplicationPacket *outapp = new EQApplicationPacket(OP_FormattedMessage, sizeof(FormattedMessage_Struct) + length);
FormattedMessage_Struct *fm = (FormattedMessage_Struct *)outapp->pBuffer;
fm->string_id = string_id;
fm->type = type;
@@ -2950,6 +2954,9 @@ void Client::FilteredMessage_StringID(Mob *sender, uint32 type, eqFilterType fil
bufptr += strlen(message_arg[i]) + 1;
}
// since we're moving the pointer the 0 offset is correct
bufptr[0] = '\0';
QueuePacket(outapp);
safe_delete(outapp);
}
+4
View File
@@ -1247,6 +1247,10 @@ public:
bool InterrogateInventory(Client* requester, bool log, bool silent, bool allowtrip, bool& error, bool autolog = true);
//Command #Tune functions
virtual int32 Tune_GetMeleeMitDmg(Mob* GM, Mob *attacker, int32 damage, int32 minhit, float mit_rating, float atk_rating);
int32 GetMeleeDamage(Mob* other, bool GetMinDamage = false);
protected:
friend class Mob;
void CalcItemBonuses(StatBonuses* newbon);
+9 -7
View File
@@ -1838,12 +1838,11 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
if (loaditems) { /* Dont load if a length error occurs */
BulkSendInventoryItems();
/* Send stuff on the cursor which isnt sent in bulk */
iter_queue it;
for (it = m_inv.cursor_begin(); it != m_inv.cursor_end(); ++it) {
for (auto iter = m_inv.cursor_begin(); iter != m_inv.cursor_end(); ++iter) {
/* First item cursor is sent in bulk inventory packet */
if (it == m_inv.cursor_begin())
if (iter == m_inv.cursor_begin())
continue;
const ItemInst *inst = *it;
const ItemInst *inst = *iter;
SendItemPacket(MainCursor, inst, ItemPacketSummonItem);
}
}
@@ -5462,13 +5461,13 @@ void Client::Handle_OP_Emote(const EQApplicationPacket *app)
in->message[512] = '\0';
len_msg = 512;
}
uint32 len_packet = sizeof(in->unknown01) + len_name
uint32 len_packet = sizeof(in->type) + len_name
+ len_msg + 1;
// Construct outgoing packet
EQApplicationPacket* outapp = new EQApplicationPacket(OP_Emote, len_packet);
Emote_Struct* out = (Emote_Struct*)outapp->pBuffer;
out->unknown01 = in->unknown01;
out->type = in->type;
memcpy(out->message, name, len_name);
memcpy(&out->message[len_name], in->message, len_msg);
@@ -7477,7 +7476,7 @@ void Client::Handle_OP_GuildInviteAccept(const EQApplicationPacket *app)
uint32 guildrank = gj->response;
if (GetClientVersion() == EQClientRoF)
if (GetClientVersion() >= EQClientRoF)
{
if (gj->response == 8)
{
@@ -7652,7 +7651,10 @@ void Client::Handle_OP_GuildPromote(const EQApplicationPacket *app)
uint8 rank = gci.rank + 1;
if (rank > GUILD_OFFICER)
{
Message(0, "You cannot promote someone to be guild leader. You must use /guildleader.");
return;
}
Log.Out(Logs::Detail, Logs::Guilds, "Promoting %s (%d) from rank %s (%d) to %s (%d) in %s (%d)",
+212 -4
View File
@@ -425,7 +425,7 @@ int command_init(void) {
command_add("open_shop", nullptr, 100, command_merchantopenshop) ||
command_add("merchant_close_shop", "Closes a merchant shop", 100, command_merchantcloseshop) ||
command_add("close_shop", nullptr, 100, command_merchantcloseshop) ||
command_add("shownumhits", "Shows buffs numhits for yourself.", 0, command_shownumhits) ||
command_add("tune", "Calculate ideal statical values related to combat.", 100, command_tune)
command_add("crashtest", "- Crash the zoneserver", 255, command_crashtest) ||
command_add("logtest", "Performs log performance testing.", 250, command_logtest) ||
command_add("logs", "Manage anything to do with logs", 250, command_logs)
@@ -2628,7 +2628,7 @@ void command_peekinv(Client *c, const Seperator *sep)
}
else {
int cursorDepth = 0;
for (iter_queue it = targetClient->GetInv().cursor_begin(); (it != targetClient->GetInv().cursor_end()); ++it, ++cursorDepth) {
for (auto it = targetClient->GetInv().cursor_begin(); (it != targetClient->GetInv().cursor_end()); ++it, ++cursorDepth) {
inst_main = *it;
item_data = (inst_main == nullptr) ? nullptr : inst_main->GetItem();
linker.SetItemInst(inst_main);
@@ -6599,7 +6599,7 @@ void command_npcedit(Client *c, const Seperator *sep)
"SET luclin_haircolor = %i, luclin_beardcolor = %i, "
"luclin_hairstyle = %i, luclin_beard = %i, "
"face = %i, drakkin_heritage = %i, "
"drakkin_tattoo = %i, drakkin_details = %i, "
"drakkin_tattoo = %i, drakkin_details = %i "
"WHERE id = %i",
target->GetHairColor(), target->GetBeardColor(),
target->GetHairStyle(), target->GetBeard(),
@@ -10001,7 +10001,6 @@ void command_camerashake(Client *c, const Seperator *sep)
if(sep->arg[1][0] && sep->arg[2][0])
{
ServerPacket *pack = new ServerPacket(ServerOP_CameraShake, sizeof(ServerCameraShake_Struct));
memset(pack->pBuffer, 0, sizeof(pack->pBuffer));
ServerCameraShake_Struct* scss = (ServerCameraShake_Struct*) pack->pBuffer;
scss->duration = atoi(sep->arg[1]);
scss->intensity = atoi(sep->arg[2]);
@@ -10389,6 +10388,215 @@ void command_shownumhits(Client *c, const Seperator *sep)
return;
}
void command_tune(Client *c, const Seperator *sep)
{
//Work in progress - Kayen
if(sep->arg[1][0] == '\0' || !strcasecmp(sep->arg[1], "help")) {
c->Message(0, "Syntax: #tune [subcommand].");
c->Message(0, "-- Tune System Commands --");
c->Message(0, "-- Usage: Returning recommended combat statistical values based on a desired outcome.");
c->Message(0, "-- Note: If targeted mob does not have a target (ie not engaged in combat), YOU will be considered the target.");
c->Message(0, "-- Warning: The calculations done in this process are intense and can potentially cause zone crashes depending on parameters set, use with caution!");
c->Message(0, "-- Below are OPTIONAL parameters.");
c->Message(0, "-- Note: [interval] Determines how fast the stat being checked increases/decreases till it finds the best result. Default [ATK/AC 50][Acc/Avoid 10] ");
c->Message(0, "-- Note: [loop_max] Determines how many iterations are done to increases/decreases the stat till it finds the best result. Default [ATK/AC 100][Acc/Avoid 1000]");
c->Message(0, "-- Note: [Stat Override] Will override that stat on mob being checkd with the specified value. Default=0");
c->Message(0, "-- Note: [Info Level] How much statistical detail is displayed[0 - 3]. Default=0 ");
c->Message(0, "-- Note: Results are only approximations usually accurate to +/- 2 intervals.");
c->Message(0, "... ");
c->Message(0, "...### Category A ### Target = ATTACKER ### YOU or Target's Target = DEFENDER ###");
c->Message(0, "...### Category B ### Target = DEFENDER ### YOU or Target's Target = ATTACKER ###");
c->Message(0, "... ");
c->Message(0, "...#Returns recommended ATK adjustment +/- on ATTACKER that will result in an average mitigation pct on DEFENDER. ");
c->Message(0, "...tune FindATK [A/B] [pct mitigation] [interval][loop_max][AC Overwride][Info Level]");
c->Message(0, "... ");
c->Message(0, "...#Returns recommended AC adjustment +/- on DEFENDER for an average mitigation pct from ATTACKER. ");
c->Message(0, "...tune FindAC [A/B] [pct mitigation] [interval][loop_max][ATK Overwride][Info Level] ");
c->Message(0, "... ");
c->Message(0, "...#Returns recommended Accuracy adjustment +/- on ATTACKER that will result in a hit chance pct on DEFENDER. ");
c->Message(0, "...tune FindAccuracy [A/B] [hit chance] [interval][loop_max][Avoidance Overwride][Info Level]");
c->Message(0, "... ");
c->Message(0, "...#Returns recommended Avoidance adjustment +/- on DEFENDER for in a hit chance pct from ATTACKER. ");
c->Message(0, "...tune FindAvoidance [A/B] [pct mitigation] [interval][loop_max][Accuracy Overwride][Info Level] ");
return;
}
//Default is category A for attacker/defender settings, which then are swapped under category B.
Mob* defender = c;
Mob* attacker = c->GetTarget();
if (!attacker)
{
c->Message(0, "#Tune - Error no target selected. [#Tune help]");
return;
}
Mob* ttarget = attacker->GetTarget();
if (ttarget)
defender = ttarget;
if(!strcasecmp(sep->arg[1], "FindATK"))
{
float pct_mitigation = atof(sep->arg[3]);
int interval = atoi(sep->arg[4]);
int max_loop = atoi(sep->arg[5]);
int ac_override = atoi(sep->arg[6]);
int info_level = atoi(sep->arg[7]);
if (!pct_mitigation)
{
c->Message(13, "#Tune - Error must enter the desired percent mitigation on defender. Ie. Defender to mitigate on average 20 pct of max damage.");
return;
}
if (!interval)
interval = 50;
if (!max_loop)
max_loop = 100;
if(!ac_override)
ac_override = 0;
if (!info_level)
info_level = 1;
if(!strcasecmp(sep->arg[2], "A"))
c->Tune_FindATKByPctMitigation(defender, attacker, pct_mitigation, interval, max_loop,ac_override,info_level);
else if(!strcasecmp(sep->arg[2], "B"))
c->Tune_FindATKByPctMitigation(attacker,defender, pct_mitigation, interval, max_loop,ac_override,info_level);
else {
c->Message(0, "#Tune - Error no category selcted. [#Tune help]");
c->Message(0, "Usage #tune FindATK [A/B] [pct mitigation] [interval][loop_max][AC Overwride][Info Level] ");
c->Message(0, "Example #tune FindATK A 60");
}
return;
}
if(!strcasecmp(sep->arg[1], "FindAC"))
{
float pct_mitigation = atof(sep->arg[3]);
int interval = atoi(sep->arg[4]);
int max_loop = atoi(sep->arg[5]);
int atk_override = atoi(sep->arg[6]);
int info_level = atoi(sep->arg[7]);
if (!pct_mitigation)
{
c->Message(13, "#Tune - Error must enter the desired percent mitigation on defender. Ie. Defender to mitigate on average 20 pct of max damage.");
return;
}
if (!interval)
interval = 50;
if (!max_loop)
max_loop = 100;
if(!atk_override)
atk_override = 0;
if (!info_level)
info_level = 1;
if(!strcasecmp(sep->arg[2], "A"))
c->Tune_FindACByPctMitigation(defender, attacker, pct_mitigation, interval, max_loop,atk_override,info_level);
else if(!strcasecmp(sep->arg[2], "B"))
c->Tune_FindACByPctMitigation(attacker, defender, pct_mitigation, interval, max_loop,atk_override,info_level);
else {
c->Message(0, "#Tune - Error no category selcted. [#Tune help]");
c->Message(0, "Usage #tune FindAC [A/B] [pct mitigation] [interval][loop_max][ATK Overwride][Info Level] ");
c->Message(0, "Example #tune FindAC A 60");
}
return;
}
if(!strcasecmp(sep->arg[1], "FindAccuracy"))
{
float hit_chance = atof(sep->arg[3]);
int interval = atoi(sep->arg[4]);
int max_loop = atoi(sep->arg[5]);
int avoid_override = atoi(sep->arg[6]);
int info_level = atoi(sep->arg[7]);
if (!hit_chance)
{
c->Message(10, "#Tune - Error must enter the desired percent mitigation on defender. Ie. Defender to mitigate on average 20 pct of max damage.");
return;
}
if (!interval)
interval = 10;
if (!max_loop)
max_loop = 1000;
if(!avoid_override)
avoid_override = 0;
if (!info_level)
info_level = 1;
if (hit_chance > RuleR(Combat,MaxChancetoHit) || hit_chance < RuleR(Combat,MinChancetoHit))
{
c->Message(10, "#Tune - Error hit chance out of bounds. [Max %.2f Min .2f]", RuleR(Combat,MaxChancetoHit),RuleR(Combat,MinChancetoHit));
return;
}
if(!strcasecmp(sep->arg[2], "A"))
c->Tune_FindAccuaryByHitChance(defender, attacker, hit_chance, interval, max_loop,avoid_override,info_level);
else if(!strcasecmp(sep->arg[2], "B"))
c->Tune_FindAccuaryByHitChance(attacker, defender, hit_chance, interval, max_loop,avoid_override,info_level);
else {
c->Message(0, "#Tune - Error no category selcted. [#Tune help]");
c->Message(0, "Usage #tune FindAcccuracy [A/B] [hit chance] [interval][loop_max][Avoidance Overwride][Info Level]");
c->Message(0, "Exampled #tune FindAccuracy B 30");
}
return;
}
if(!strcasecmp(sep->arg[1], "FindAvoidance"))
{
float hit_chance = atof(sep->arg[3]);
int interval = atoi(sep->arg[4]);
int max_loop = atoi(sep->arg[5]);
int acc_override = atoi(sep->arg[6]);
int info_level = atoi(sep->arg[7]);
if (!hit_chance)
{
c->Message(0, "#Tune - Error must enter the desired hit chance on defender. Ie. Defender to have hit chance of 40 pct.");
return;
}
if (!interval)
interval = 10;
if (!max_loop)
max_loop = 1000;
if(!acc_override)
acc_override = 0;
if (!info_level)
info_level = 1;
if (hit_chance > RuleR(Combat,MaxChancetoHit) || hit_chance < RuleR(Combat,MinChancetoHit))
{
c->Message(10, "#Tune - Error hit chance out of bounds. [Max %.2f Min .2f]", RuleR(Combat,MaxChancetoHit),RuleR(Combat,MinChancetoHit));
return;
}
if(!strcasecmp(sep->arg[2], "A"))
c->Tune_FindAvoidanceByHitChance(defender, attacker, hit_chance, interval, max_loop,acc_override, info_level);
else if(!strcasecmp(sep->arg[2], "B"))
c->Tune_FindAvoidanceByHitChance(attacker, defender, hit_chance, interval, max_loop,acc_override, info_level);
else {
c->Message(0, "#Tune - Error no category selcted. [#Tune help]");
c->Message(0, "Usage #tune FindAvoidance [A/B] [hit chance] [interval][loop_max][Accuracy Overwride][Info Level]");
c->Message(0, "Exampled #tune FindAvoidance B 30");
}
return;
}
return;
}
void command_logtest(Client *c, const Seperator *sep){
clock_t t = std::clock(); /* Function timer start */
if (sep->IsNumber(1)){
+1
View File
@@ -322,6 +322,7 @@ void command_npctype_cache(Client *c, const Seperator *sep);
void command_merchantopenshop(Client *c, const Seperator *sep);
void command_merchantcloseshop(Client *c, const Seperator *sep);
void command_shownumhits(Client *c, const Seperator *sep);
void command_tune(Client *c, const Seperator *sep);
void command_logtest(Client *c, const Seperator *sep);
void command_logs(Client *c, const Seperator *sep);
+18 -6
View File
@@ -364,9 +364,10 @@ Corpse::Corpse(Client* client, int32 in_rezexp) : Mob (
// solar: TODO soulbound items need not be added to corpse, but they need
// to go into the regular slots on the player, out of bags
// worn + inventory + cursor
// possessions
// TODO: accomodate soul-bound items
std::list<uint32> removed_list;
bool cursor = false;
//bool cursor = false;
for(i = MAIN_BEGIN; i < EmuConstants::MAP_POSSESSIONS_SIZE; i++) {
if(i == MainAmmo && client->GetClientVersion() >= EQClientSoF) {
item = client->GetInv().GetItem(MainPowerSource);
@@ -384,14 +385,18 @@ Corpse::Corpse(Client* client, int32 in_rezexp) : Mob (
}
}
#if 0
// This will either be re-enabled or deleted at some point. The client doesn't appear
// to like to have items deleted from it's buffer..or, I just haven't figure out how -U
// (Besides, the 'corpse' slots equal the size of MapPossessions..not MapPossessions + MapCorpse)
// cursor queue // (change to first client that supports 'death hover' mode, if not SoF.)
if (!RuleB(Character, RespawnFromHover) || client->GetClientVersion() < EQClientSoF) {
// bumped starting assignment to 8001 because any in-memory 'slot 8000' item was moved above as 'slot 30'
// this was mainly for client profile state reflection..should match db player inventory entries now.
iter_queue it;
for (it = client->GetInv().cursor_begin(), i = 8001; it != client->GetInv().cursor_end(); ++it, i++) {
i = 8001;
for (auto it = client->GetInv().cursor_begin(); it != client->GetInv().cursor_end(); ++it, i++) {
item = *it;
if ((item && (!client->IsBecomeNPC())) || (item && client->IsBecomeNPC() && !item->GetItem()->NoRent)) {
std::list<uint32> slot_list = MoveItemToCorpse(client, item, i);
@@ -400,6 +405,7 @@ Corpse::Corpse(Client* client, int32 in_rezexp) : Mob (
}
}
}
#endif
database.TransactionBegin();
if (removed_list.size() != 0) {
@@ -422,6 +428,7 @@ Corpse::Corpse(Client* client, int32 in_rezexp) : Mob (
database.QueryDatabase(ss.str().c_str());
}
#if 0
if (cursor) { // all cursor items should be on corpse (client < SoF or RespawnFromHover = false)
while (!client->GetInv().CursorEmpty())
client->DeleteItemInInventory(MainCursor, 0, false, false);
@@ -431,8 +438,13 @@ Corpse::Corpse(Client* client, int32 in_rezexp) : Mob (
std::list<ItemInst*>::const_iterator finish = client->GetInv().cursor_end();
database.SaveCursor(client->CharacterID(), start, finish);
}
#endif
client->CalcBonuses(); // will only affect offline profile viewing of dead characters..unneeded overhead
auto start = client->GetInv().cursor_begin();
auto finish = client->GetInv().cursor_end();
database.SaveCursor(client->CharacterID(), start, finish);
client->CalcBonuses();
client->Save();
IsRezzed(false);
+7
View File
@@ -4621,3 +4621,10 @@ Mob *EntityList::GetTargetForVirus(Mob *spreader, int range)
return TargetsInRange[zone->random.Int(0, TargetsInRange.size() - 1)];
}
void EntityList::StopMobAI()
{
for (auto &mob : mob_list) {
mob.second->AI_Stop();
mob.second->AI_ShutDown();
}
}
+2
View File
@@ -268,6 +268,8 @@ public:
Entity *GetEntityMob(const char *name);
Entity *GetEntityCorpse(const char *name);
void StopMobAI();
void DescribeAggro(Client *towho, NPC *from_who, float dist, bool verbose);
void Message(uint32 to_guilddbid, uint32 type, const char* message, ...);
+312 -324
View File
File diff suppressed because it is too large Load Diff
+2868 -2302
View File
File diff suppressed because it is too large Load Diff
+10
View File
@@ -924,6 +924,16 @@ public:
void mod_spell_cast(uint16 spell_id, Mob* spelltar, bool reflect, bool use_resist_adjust, int16 resist_adjust, bool isproc);
bool mod_will_aggro(Mob *attacker, Mob *on);
//Command #Tune functions
int32 Tune_MeleeMitigation(Mob* GM, Mob *attacker, int32 damage, int32 minhit, ExtraAttackOptions *opts = nullptr, int Msg =0, int ac_override=0, int atk_override=0, int add_ac=0, int add_atk = 0);
virtual int32 Tune_GetMeleeMitDmg(Mob* GM, Mob *attacker, int32 damage, int32 minhit, float mit_rating, float atk_rating);
uint32 Tune_GetMeanDamage(Mob* GM, Mob *attacker, int32 damage, int32 minhit, ExtraAttackOptions *opts = nullptr, int Msg = 0,int ac_override=0, int atk_override=0, int add_ac=0, int add_atk = 0);
void Tune_FindATKByPctMitigation(Mob* defender, Mob *attacker, float pct_mitigation, int interval = 50, int max_loop = 100, int ac_override=0,int Msg =0);
void Tune_FindACByPctMitigation(Mob* defender, Mob *attacker, float pct_mitigation, int interval = 50, int max_loop = 100, int atk_override=0,int Msg =0);
float Tune_CheckHitChance(Mob* defender, Mob* attacker, SkillUseTypes skillinuse, int Hand, int16 chance_mod, int Msg = 1,int acc_override=0, int avoid_override=0, int add_acc=0, int add_avoid = 0);
void Tune_FindAccuaryByHitChance(Mob* defender, Mob *attacker, float hit_chance, int interval, int max_loop, int avoid_override, int Msg = 0);
void Tune_FindAvoidanceByHitChance(Mob* defender, Mob *attacker, float hit_chance, int interval, int max_loop, int acc_override, int Msg = 0);
protected:
void CommonDamage(Mob* other, int32 &damage, const uint16 spell_id, const SkillUseTypes attack_skill, bool &avoidable, const int8 buffslot, const bool iBuffTic);
static uint16 GetProcID(uint16 spell_id, uint8 effect_index);
+17 -16
View File
@@ -3472,14 +3472,16 @@ void Mob::DoBuffTic(uint16 spell_id, int slot, uint32 ticsremaining, uint8 caste
{
effect_value = CalcSpellEffectValue(spell_id, i, caster_level, caster, ticsremaining);
//Handle client cast DOTs here.
if (caster && effect_value < 0 && IsDetrimentalSpell(spell_id)){
if (caster && effect_value < 0){
if (caster->IsClient()){
if (!caster->CastToClient()->GetFeigned())
if (IsDetrimentalSpell(spell_id)){
if (caster->IsClient()){
if (!caster->CastToClient()->GetFeigned())
AddToHateList(caster, -effect_value);
}
else if (!IsClient()) //Allow NPC's to generate hate if casted on other NPC's.
AddToHateList(caster, -effect_value);
}
else if (!IsClient()) //Allow NPC's to generate hate if casted on other NPC's.
AddToHateList(caster, -effect_value);
effect_value = caster->GetActDoTDamage(spell_id, effect_value, this);
@@ -6569,33 +6571,32 @@ bool Mob::TrySpellProjectile(Mob* spell_target, uint16 spell_id, float speed){
DoAnim(anim, 0, true, IsClient() ? FilterPCSpells : FilterNPCSpells); //Override the default projectile animation.
return true;
}
}
void Mob::ResourceTap(int32 damage, uint16 spellid){
void Mob::ResourceTap(int32 damage, uint16 spellid)
{
//'this' = caster
if (!IsValidSpell(spellid))
return;
for (int i = 0; i <= EFFECT_COUNT; i++)
{
if (spells[spellid].effectid[i] == SE_ResourceTap){
damage += (damage * spells[spellid].base[i])/100;
for (int i = 0; i < EFFECT_COUNT; i++) {
if (spells[spellid].effectid[i] == SE_ResourceTap) {
damage += (damage * spells[spellid].base[i]) / 100;
if (spells[spellid].max[i] && (damage > spells[spellid].max[i]))
damage = spells[spellid].max[i];
if (spells[spellid].base2[i] == 0){ //HP Tap
if (spells[spellid].base2[i] == 0) { // HP Tap
if (damage > 0)
HealDamage(damage);
else
Damage(this, -damage,0, SkillEvocation,false);
Damage(this, -damage, 0, SkillEvocation, false);
}
if (spells[spellid].base2[i] == 1) //Mana Tap
if (spells[spellid].base2[i] == 1) // Mana Tap
SetMana(GetMana() + damage);
if (spells[spellid].base2[i] == 2 && IsClient()) //Endurance Tap
if (spells[spellid].base2[i] == 2 && IsClient()) // Endurance Tap
CastToClient()->SetEndurance(CastToClient()->GetEndurance() + damage);
}
}
+6 -6
View File
@@ -2741,7 +2741,7 @@ void TaskManager::SendActiveTaskDescription(Client *c, int TaskID, int SequenceN
+ sizeof(TaskDescriptionData1_Struct) + strlen(Tasks[TaskID]->Description) + 1
+ sizeof(TaskDescriptionData2_Struct) + 1 + sizeof(TaskDescriptionTrailer_Struct);
std::string RewardText;
std::string reward_text;
int ItemID = NOT_USED;
// If there is an item make the Reward text into a link to the item (only the first item if a list
@@ -2769,17 +2769,17 @@ void TaskManager::SendActiveTaskDescription(Client *c, int TaskID, int SequenceN
linker.SetProxyText(Tasks[TaskID]->Reward);
auto reward_link = linker.GenerateLink();
RewardText += reward_link.c_str();
reward_text.append(reward_link);
}
else {
RewardText += Tasks[TaskID]->Reward;
reward_text.append(Tasks[TaskID]->Reward);
}
}
else {
RewardText += Tasks[TaskID]->Reward;
reward_text.append(Tasks[TaskID]->Reward);
}
PacketLength += strlen(RewardText.c_str()) + 1;
PacketLength += reward_text.length() + 1;
char *Ptr;
TaskDescriptionHeader_Struct* tdh;
@@ -2835,7 +2835,7 @@ void TaskManager::SendActiveTaskDescription(Client *c, int TaskID, int SequenceN
tdd2->unknown3 = 0x0000;
Ptr = (char *) tdd2 + sizeof(TaskDescriptionData2_Struct);
sprintf(Ptr, "%s", RewardText.c_str());
sprintf(Ptr, "%s", reward_text.c_str());
Ptr = Ptr + strlen(Ptr) + 1;
tdt = (TaskDescriptionTrailer_Struct*)Ptr;
+1089
View File
File diff suppressed because it is too large Load Diff
+1 -9
View File
@@ -670,15 +670,7 @@ void Zone::Shutdown(bool quite)
if (!ZoneLoaded)
return;
std::list<Mob*> mob_list;
entity_list.GetMobList(mob_list);
std::list<Mob*>::iterator mob_itr = mob_list.begin();
while (mob_itr != mob_list.end()) {
Mob* mob_inst = *mob_itr;
mob_inst->AI_Stop();
mob_inst->AI_ShutDown();
++mob_itr;
}
entity_list.StopMobAI();
std::map<uint32,NPCType *>::iterator itr;
while(zone->npctable.size()) {