|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Support::Windows Servers Support forum for Windows EQEMu users. |
09-26-2015, 07:05 PM
|
Discordant
|
|
Join Date: Dec 2013
Posts: 297
|
|
Thanks. Knowing how to put them in the lines was my main concern (syntax).
I can reference the functions anytime I forget something, which is often.
Regardless, I got it to work and according to the logsys, it's working as intended, just as the graph shows.
EDIT: btw Uleat, that's the exact page I used to figure it out =)
|
09-26-2015, 08:01 PM
|
Discordant
|
|
Join Date: Dec 2013
Posts: 297
|
|
Never said it was pretty:
Code:
double param, result;
param = ((pow ((std::abs(15 + chancemodi)), 1.1) * 0.4 + 1.75) * skillval);
result = cbrt (param);
int32 Chance = (-((result)* 1.5) + 22 + (chancemodi / 1.5));
If it could be better, please let me know.
|
|
|
|
09-27-2015, 08:04 PM
|
Discordant
|
|
Join Date: Dec 2013
Posts: 297
|
|
I removed the Spellshield and the "cast on other" messages which appear when attacking an npc with a rune. The Spellshield message seemed correct but, the "cast on other" message displays the damage shield "cast on other" each time the npc hits the client. This only occurs if the client has a DS and the NPC has a rune. The "was pierced by thorns" message also appears, as normal.
My main concern is if the second line I commented out will affect anything else. I tested this by casting a rune on myself and having an npc attack and dispel the rune. It appears to work normal. I left larger spaces between lines to accentuate the lines I commented out.
Code:
\zone\attack.cpp(3548 - 3571)
//see if any runes want to reduce this damage
if(spell_id == SPELL_UNKNOWN) {
damage = ReduceDamage(damage);
Log.Out(Logs::Detail, Logs::Combat, "Melee Damage reduced to %d", damage);
damage = ReduceAllDamage(damage);
TryTriggerThreshHold(damage, SE_TriggerMeleeThreshold, attacker);
if (skill_used)
CheckNumHitsRemaining(NumHit::IncomingHitSuccess);
} else {
int32 origdmg = damage;
// damage = AffectMagicalDamage(damage, spell_id, iBuffTic, attacker); <--- commented out second
/* if (origdmg != damage && attacker && attacker->IsClient()) { <---
if(attacker->CastToClient()->GetFilter(FilterDamageShields) != FilterHide) <--- commented out first
attacker->Message(15, "The Spellshield absorbed %d of %d points of damage", origdmg - damage, origdmg); <---
} */
if (damage == 0 && attacker && origdmg != damage && IsClient()) {
//Kayen: Probably need to add a filter for this - Not sure if this msg is correct but there should be a message for spell negate/runes.
Message(263, "%s tries to cast on YOU, but YOUR magical skin absorbs the spell.",attacker->GetCleanName());
}
damage = ReduceAllDamage(damage);
TryTriggerThreshHold(damage, SE_TriggerSpellThreshold, attacker);
}
I was trying to find the relationship in this portion with other portions that would tell me why it would make the reference to `cast_on_other` but, couldn't figure it out.
Thanks
|
|
|
|
|
|
|
09-29-2015, 02:52 AM
|
Discordant
|
|
Join Date: Dec 2013
Posts: 297
|
|
It's been about a week since I started making changes to my server code. I'm very green in this aspect but, I learn quickly and understand concepts more than syntax. I also understand the implications of things. Not everything though!
I want to thank those that have given assistance if I haven't already.
My question/issue at the bottom.
I've added a few lines to <\zone\zonedb.cpp(3177)> and created a couple rules <\common\ruletypes.h(151) - RULE_CATEGORY(Pets)>.
It works as I expected.
Below is what I added:
ruletypes.h
Code:
RULE_BOOL(Pets, PetZonePersistence, true) // if true, pets will zone with players
RULE_BOOL(Pets, PetLogPersistence, true) // if false, pets will poof 30 minutes after logging character out (PetZonePersistence must be true)
zonedb.cpp
Code:
void ZoneDatabase::LoadPetInfo(Client *client)
{
// added this part 9/28/15
if (!RuleB(Pets, PetZonePersistence)) {
std::string query = StringFormat("DELETE FROM `character_pet_info` WHERE EXISTS (SELECT * FROM `character_data` WHERE character_pet_info.char_id = character_data.id AND `char_id` = %u AND character_pet_info.pet = 0)", client->CharacterID());
auto results = database.QueryDatabase(query);
if (!results.Success())
return;
query = StringFormat("DELETE FROM `character_pet_buffs` WHERE EXISTS (SELECT * FROM `character_data` WHERE character_pet_buffs.char_id = character_data.id AND `char_id` = %u AND character_pet_buffs.pet = 0)", client->CharacterID());
results = database.QueryDatabase(query);
if (!results.Success())
return;
query = StringFormat("DELETE FROM `character_pet_inventory` WHERE EXISTS (SELECT * FROM `character_data` WHERE character_pet_inventory.char_id = character_data.id AND `char_id` = %u AND character_pet_inventory.pet = 0)", client->CharacterID());
results = database.QueryDatabase(query);
if (!results.Success())
return;
}
else if (!RuleB(Pets, PetLogPersistence)) {
std::string query = StringFormat("DELETE FROM `character_pet_info` WHERE EXISTS (SELECT * FROM `character_data` WHERE character_pet_info.char_id = character_data.id AND `char_id` = %u AND(UNIX_TIMESTAMP(NOW()) - `last_login` > 1800) AND character_pet_info.pet = 0)", client->CharacterID());
auto results = database.QueryDatabase(query);
if (!results.Success())
return;
query = StringFormat("DELETE FROM `character_pet_buffs` WHERE EXISTS (SELECT * FROM `character_data` WHERE character_pet_buffs.char_id = character_data.id AND `char_id` = %u AND (UNIX_TIMESTAMP(NOW()) - `last_login` > 1800) AND character_pet_buffs.pet = 0)", client->CharacterID());
results = database.QueryDatabase(query);
if (!results.Success())
return;
query = StringFormat("DELETE FROM `character_pet_inventory` WHERE EXISTS (SELECT * FROM `character_data` WHERE character_pet_inventory.char_id = character_data.id AND `char_id` = %u AND (UNIX_TIMESTAMP(NOW()) - `last_login` > 1800) AND character_pet_inventory.pet = 0)", client->CharacterID());
results = database.QueryDatabase(query);
if (!results.Success())
return;
}
// above added 9/28/15 and a few small changes below
// Load current pet and suspended pet
PetInfo *petinfo = client->GetPetInfo(0);
PetInfo *suspended = client->GetPetInfo(1);
memset(petinfo, 0, sizeof(PetInfo));
memset(suspended, 0, sizeof(PetInfo));
std::string query = StringFormat("SELECT `pet`, `petname`, `petpower`, `spell_id`, "
"`hp`, `mana`, `size` FROM `character_pet_info` "
"WHERE `char_id` = %u",
client->CharacterID());
auto results = database.QueryDatabase(query);
if (!results.Success()) {
return;
}
My notes during the process:
Code:
Added lines to remove pet persistence after 30 minutes when logged off - `ZoneDatabase::LoadPetInfo` - \zone\zonedb.cpp(3177)
- it appears to work but, I am unsure if there is a better way
- this may also delete the entries if zoning after 30 min from `last_login` timestamp (if this timestamp is what I presume)
- it references `last_login` similar to norent although norent items are only loaded once through inventory.cpp, I think
- the solution may be to add the new lines where inventory.cpp is called for norent items
- nevermind, `last_login` appears to be an update timestamp which eliminates this as a possible issue
- create a rule for it to easily switch off for later expansions - done
ToDo: remove pet persistence between zones and create a rule for it - \zone\zonedb.cpp(3177)
- likely need an "if" statement in the same code as above; it seems to call for those lines after each zone switch
- possible solution is to simply use the added lines but, without the timestamp part and add a rule
- added more lines and rules linked to these lines
- it appears to work although I notice the rules need some time to catch up after #rules reload with these added rules
- I'm guessing it has to do with zonedb periodic updates
- issue remains on logging out and keeping pet for 30 min if `PetZonePersistence` is false - currently pets poof when logging back
- possible solution is to reference the DB `character_data` for zoneid prior to overwriting this data when logging in
- unsure the order in which the data is currently read and then overwritten
My implied question:
Code:
- issue remains on logging out and keeping pet for 30 min if `PetZonePersistence` is false
- currently pets poof when logging back
- possible solution is to reference the DB `character_data` for zoneid prior to overwriting this data when logging in
- unsure the order in which the data is currently read and then overwritten
The other issue is the running of the above queries and deleting of DB rows each time a player zones. I'd like to make this a little more efficient, if possible. (such as skipping the query if certain values don't exist, which requires another query ofc but, I seek efficiency)
I am open to suggestions.
Thanks
|
|
|
|
09-29-2015, 03:33 PM
|
Discordant
|
|
Join Date: Dec 2013
Posts: 297
|
|
I pored over NoRentExpired, bool deletenorent and some other areas until I came to zonedb and saw some things I was familiar with. As this is all so foreign to me, knowing what to search for and then processing it consumes much more time than actually changing it to something different.
I was thinking of trying to work it in with the norent code but, my concern was with keeping suspended pets suspended. My intention was to cover as many possibilities as I could think of with that.
The difference with no rent items and what I'm trying to do is the additional option of having pets poof when zoning (a la classic) while not having them go away like norent items when logging for under 30 minutes.
It really isn't a big deal as far as the game goes. I enjoy trying to solve the problem.
Thanks for the response, it got me thinking about it a little different.
|
09-29-2015, 04:02 PM
|
|
Developer
|
|
Join Date: Apr 2012
Location: North Carolina
Posts: 2,815
|
|
Adding that methodology to LoadPets will cause that to be processed every time that LoadPets is called..as in zone changes.
You may need to split the methodology up to have one portion processed on zone entry, and the other on zone change.
You could create handlers for the actions that you want to process in Database(SharedDatabase?) (ref: https://github.com/EQEmu/Server/comm...5353f5ed8d8044)
.. and handle the returns appropriately.
I know it's a pain to figure out what does what, where and why..but, it comes with exposure.
__________________
Uleat of Bertoxxulous
Compilin' Dirty
|
09-29-2015, 05:01 PM
|
Discordant
|
|
Join Date: Dec 2013
Posts: 297
|
|
Yes! That's exactly what I was thinking (in regards to splitting it up) but didn't understand and still having a hard time understanding. I'll probably get it a little with, like you said, more exposure.
|
09-29-2015, 05:16 PM
|
|
Developer
|
|
Join Date: Apr 2012
Location: North Carolina
Posts: 2,815
|
|
I am extremely slow when it comes to picking up new material...
Intellisense has been my friend since day one!
__________________
Uleat of Bertoxxulous
Compilin' Dirty
|
09-29-2015, 06:47 PM
|
Discordant
|
|
Join Date: Dec 2013
Posts: 297
|
|
I have to say that feature is wonderful, really helps in learning it.
Compiling the new code now. Hopefully it works.
|
09-29-2015, 07:33 PM
|
Discordant
|
|
Join Date: Dec 2013
Posts: 297
|
|
Thank you!
I've used <SetPet(0);> as kinda my mulligan. (I've had a few)
Trying to learn some other ways but...
|
|
|
|
09-30-2015, 03:27 PM
|
Discordant
|
|
Join Date: Dec 2013
Posts: 297
|
|
I think I figured the pet rules to work as they should. It took way too long to figure out but, I learned a bit more about the system.
Everything appears to work although client crashed twice during testing. I logged into the emu well over a dozen times.
I am unsure if these rules will trump suspended minion AA. I will need to test that another time.
I put a couple very simple lines into two places and reverted everything I did previous.
Code:
near <void Client::BulkSendInventoryItems()> \zone\client_process.cpp(848)
// added 9/30/15 no rent check (this may need fixing when introducing suspended minion)
if (!RuleB(Pets, PetLogPersistence))
SetPet(0);
near <void Client::Handle_OP_ZoneChange(const EQApplicationPacket *app) {> \zone\zoning.cpp(192)
// added 9/30/15 - removes pet on zoning (not on logging)
if (!RuleB(Pets, PetZonePersistence))
SetPet(0);
The first occurs within the <deletenorent> code. I searched this area when I originally tried to do this a day or two ago but, was unsure of code to put in. It was also suggested by Uleat.
The following was put in just before what appears to send the client to the new coords, when zoning. This was a little more tricky because I didn't know how the zoning process worked. I ended up turning on all the logsys features to sleuth it out. Rencro made mention of this although at the time, I couldn't make sense of it.
If this could be improved, please let me know.
Thanks for your help.
|
|
|
|
|
|
|
09-30-2015, 03:59 PM
|
|
Developer
|
|
Join Date: Apr 2012
Location: North Carolina
Posts: 2,815
|
|
I would probably move your 'log persistence' check to here: https://github.com/EQEmu/Server/blob...cket.cpp#L1628
.. you could even make the database.LoadPetsInfo(this) call an else clause of the con check (PetLogPersistence == true)
I'm not 100% sure..but, that may clear up your client crashes too. (Looks like the profile packet was already sent to the client - with pet info - and you
were deleting the pet on the server afterwards.)
Mixing system methodologies can lead to issues down the road if you need to make changes, or if changes are made, to a code section.
The 'zone persistence' is probably ok (didn't look at the actual location) .. but, consider what you want to default behavior to be in case of a server crash, client ld, etc...
(Some) players will find a way to manipulate your best thought plans..even accidental actions can lead to exploitable discoveries.
__________________
Uleat of Bertoxxulous
Compilin' Dirty
|
|
|
|
09-30-2015, 04:09 PM
|
Discordant
|
|
Join Date: Dec 2013
Posts: 297
|
|
Yes, the pets actually show up on the UI for a fraction of a second after logging in. I have been watching what happens in the DB the entire time and...
Quote:
(Looks like the profile packet was already sent to the client - with pet info - and you
were deleting the pet on the server afterwards.)
|
...seems to be true, for the log part.
The zone part deletes the entry immediately.
I will make it better. It's not exactly how I want even though it functions.
I'll check this out a little later, let it sit for a bit.
Thanks for your help.
EDIT: I tried as many variations as there are in that exact location you recommended Uleat. Although, I did not try anything after moving the bit to \zoning.cpp. I think I've let it sit long enough.
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
All times are GMT -4. The time now is 06:17 AM.
|
|
|
|
|
|
|
|
|
|
|
|
|