PDA

View Full Version : [Bugs] Corpses issues with leavecorpses set to 1


Magoth78
09-01-2005, 12:16 AM
Hi there,

On my server I've set the leavecorpses variable to 1 so people can loot each other after being killed.
But when a player dies (from PvP or PvE) the corpse disapears. Everyone has to zone to see the corpse. Looks like an info sent to clients is missing when a Player dies.

Does anyone experience the same problem?

Thx,
Mag

sdabbs65
09-01-2005, 06:10 AM
Hi there,

On my server I've set the leavecorpses variable to 1 so people can loot each other after being killed.
But when a player dies (from PvP or PvE) the corpse disapears. Everyone has to zone to see the corpse. Looks like an info sent to clients is missing when a Player dies.

Does anyone experience the same problem?

Thx,
Mag

What server version are you running ?
this is not a problem on my shard 6.0DR1

Magoth78
09-01-2005, 06:44 AM
I'm running a 0.6.0dr2 server.

On Empire1, I used to have a 0dr1 server, all was fine. I guess I gotta find the dr1 sources and see the differences in attack.cpp and playercorpse.cpp :/

Anyway thx for the answer,
Mag

FaerinTelDanor
09-01-2005, 08:12 AM
I have the same problem with 0.6.0 dr3 ... haven't been able to track down the problem yet.

Magoth78
09-04-2005, 09:37 AM
sdabbs65> By any chance, could you send me your attack.cpp (in your 0.6.0dr1 sources), please? (funzy78@hotmail.com)

Cause, I remember having this bug in 6.0dr1 just after LE added the PvPreward/PvPitem/LootCoin features. But he fixed it very quickly and I dunno if the changes have ever been sent to cvs.

So maybe you got the changes pre-PvPreward and in this case, this won't help me, or post-PvPreward and it might help me.

Thx by advance,
Mag

Magoth78
09-05-2005, 02:15 AM
I've looked into my old 5.7dr6 sources and checked the file. The corpse is made in the same way that in the 0.6.0dr2 sources (minus the check for the PvPreward variable).


// now we apply the exp loss, unmem their spells, and make a corpse
// unless they're a GM
if(!GetGM())
{
if(exploss)
SetEXP(GetEXP() - exploss > 1 ? GetEXP() - exploss : 1, GetAAXP());

BuffFadeAll();
UnmemSpellAll(false);

// check db variable 'leavecorpses'
char tmp[20] = {0};
database.GetVariable("leavecorpses", tmp, 20);
int leavecorpses = atoi(tmp);
if(leavecorpses)
{
// creating the corpse takes the cash/items off the player too
Corpse *new_corpse = new Corpse(this, exploss);
entity_list.AddCorpse(new_corpse, GetID());
}

// if(!IsLD())//Todo: make it so an LDed client leaves corpse if its enabled
// MakeCorpse(exploss);
}


So the solution is *probably* not there. Now I guess I gotta check how the Corpse() function is working since the PvPreward/LootCoin variables and the SetPKItem() function have been added.

I really do need to find a fix because I got some bad issues with the corpses on 6.0dr2...
1/ corpses poof just after being killed by a npc/pc, you have to zone/camp to see the corpse
2/ or corpses poof just after being killed by pain and suffering and you are not able to see them even after zoning or camping, you have to reboot the zone...

Mag
ps: sdabbs, can you check in your attack.cpp (.6.0dr1 right?), look for the leavecorpse check called in the void Client::Death function and says if you have any check for the PvPreward/LootCoin/PvPitem variables, please? if it's the case, that would really help if you could send me the files attack.cpp and playerscorpses.cpp. Thanks.

Magoth78
09-05-2005, 10:13 AM
I've found in the code a very very very ghetto fix but that makes the player's corpses staying in the ground once they die.

Just after this line in your attack.cpp: (~1317)

entity_list.AddCorpse(new_corpse, GetID());


add

entity_list.SendZoneCorpsesBulk(this);


It's very ghetto as everyone will can see/loot the corpse but the player who' just died will crash everytime. I think I understand why when I looked at the SendZoneCorpsesBulk thingie, it's like I send a corpse zone's update to the client who just died once he 's dead, but honestly why should'nt it work after all?

and if I add:

entity_list.SendZoneCorpsesBulk(other->CastToClient());

it makes a zone corpse's update to the player who has killed the other one. The player killer crashes, but not the player who just died, this time..

Any help would be appreciated,

Thx by advance
Mag

Dakaar
09-15-2005, 01:07 PM
Im getting this problem in 6.2-DR1 Right now.

When player A kills player B, player B's corpse is visible to everyone but player A. Player a can zone and then see the corpse. Anyone can loot player B's corpse(as it should be), but when they do so they are 'bugged' untill they zone and cant access inventory, target stuff,etc.

Zone.exe reports no funky opcodes or anything during this time.

Dakaar
09-18-2005, 11:25 AM
In Attack.cpp line ~1,165
in Client::Death()
this line :
entity_list.QueueClients(this, &app);

Shouldnt it be:
entity_list.QueueClients(this,app); ?

I am at work and just going over the code.

Im thinking maybe its a problem in Corpse::Corpse ? If someone could post older versions of the functions to compare with? Thanks :)

Also, consider going through NPC::Death and seeing hwo the two corpses are handled and whats different? Just grasping at straws here..

Was addcorpse function changed around the time of rewarditem code? I see the arguments that get passed got simplified alot, could be something there..

looking at npc::death.. Shouldnt the entity_listQueueClients(this,app); in Client::Death be entitylist.QueueClients(other,app); ?

vRandom
09-18-2005, 12:07 PM
I think the best way to look at the older code would be to browse the cvs, http://cvs.sourceforge.net/viewcvs.py/eqemulator

vRandom

Dakaar
09-18-2005, 12:28 PM
The biggest thing that perplexes me.

Is when I kill another character, their corpse briefly appears before it fades away, and if i try to loot during this period, the server crashes.


Having a hell of a time trying to figure out whats wrong.
One thing I notice is that corpse::corpse() constructor changed, but everything else seems practically identical!

SetPKItem() just changes a single variable directly ... its a one line function so I doubt thats it...

CorpseDecayTimer.Disabled is used instead of set to 0 in the new code, might have something to do with it, as thats exactly what the corpse does, is instantly decay, as far as the client can see.

Does SendCorpsesBulkZone crash because in Client::Death the app packet does nto get deleted before a new one is sent?

Someone should try SendZoneCorpses() instead and see if it works!


UPDATE: SendZoneCorpse() to the corpse player makes it so that if you quickly loot before teh 'corpse' disappears, the server wont crash,so thats progress.

When I tried looting, I got an error the "LOOTING FOOKED3", and that is only displayed when the corpse object is not a corpse(or is null), soo i think its more of the wrong corpse being looted!

SendZoneCorpse(other); doesnt seem to do anything..

one thing i notice, is if the client isnt grouped, he doesnt get permission to loot corpse?

Magoth78
09-18-2005, 10:16 PM
The only fix (very ghetto) i've found is the use of SendCorpsesBulkZone. But, it makes the player on who it's sent, crashing.

Mob::Addcorpse() is the same as it's been on old version and I don't think that the problem comes from attack.cpp. The only new thing added is the PKitem and PvPvariable added, wich is working perfectly.


There is also an other problem about corpse. A corpse be rezzed without having the dead player's approbation.


I remember LethalEncounter fixed it quickly just after he added the Pkitem/pvpvariable thing. But i don't think the fix has been sent to Sourceforge.

Dakaar
09-19-2005, 04:38 AM
Was really tired last night... Soo ignore some of that :)

The big question, is why does sendcorpsesbulk crash the player, and what can be done to prevent that!

I tried making a packet with just the new corpse, but I dont think that worked , using the template of sendcorpsesbulk

Dakaar
09-19-2005, 10:59 AM
This bug occurs because the new_corpse's id and the client's id are the same. when a player dies, that id is despawned.. the corpse gets despawned with the client.

The corpse and the client need to have differing ids.

Everything is working perfectly on my server, will have a fix in a few 8)

Magoth78
09-19-2005, 06:02 PM
Nice one there., I've been searching for some times and did not find anything interesting.

Also, did u notice any bug when a player is killed by 'Pain and Suffering'? looks like his corpse just poofs.

Dakaar
09-20-2005, 06:08 AM
I think i remember seeing something in the code specifically about that where it is a seperate case, buuut i cant recall right now.


Actually while my fix worked, it apparently wasnt the root of the problem, FNW put up a new fix on CVS after I told him about what I did, im testing this out now as well

Dakaar
09-20-2005, 08:00 AM
Okay, FNW posted a CVS change based on what was going on, and it was right, sorta =P


grab the new cvs, fix the updateclientstruct so you can actually move around, then in attack.cpp, do this:


in client::death , after addCorpse like shown

entity_list.AddCorpse(new_corpse, GetID());

+ //become a corpse
+ EQZonePacket app(OP_BecomeCorpse, sizeof(BecomeCorpse_Struct));
+ BecomeCorpse_Struct* d = (BecomeCorpse_Struct*)app.pBuffer;
+ d->spawn_id = GetID();
+ d->x = GetX();
+ d->y = GetY();
+ d->z = GetZ();
+ entity_list.QueueClients(this, &app, true);

+ this->SetID(0);


Remove the //become a corpse through entity_list.Queueclients() from the top of the file and bring it down. You will need to change the name of the app and d variables on the second packet sent in client::death, because someone forgot to name them seperately =P

Thats it! :) enjoy

Magoth78
09-20-2005, 09:00 AM
Many thanks :D

Dakaar
09-20-2005, 11:13 AM
Many thanks :D

Yup :)

....gonna work on bards next *shudder* =P

Magoth78
09-20-2005, 10:52 PM
too bad for me EQZonePacket is not declared in 6.0dr2 :x
I'm gonna declare it and see how it does work.

Mag

----
Edit: Btw, just found a way to not get the "Pain and suffering" bug death. IN attack.cpp, you just have to add a case where if(other == NULL), you add a corpse.

Magoth78
09-20-2005, 11:37 PM
Ok, here's the fix for versions 0.6.0dr2 and mebbe dr3:

In attack.cpp, after

entity_list.AddCorpse(new_corpse, this->GetID());


add:

APPLAYER app;
CreateSpawnPacket(&app, new_corpse);
Corpse* dcorpse = entity_list.GetCorpseByID(GetID());
if(dcorpse->IsPlayerCorpse())
entity_list.QueueClients(this, &app, true);
entity_list.RemoveFromTargets(this);
safe_delete(trade);
this->SetID(0);


I've tested it, it seems to work well.
Thanks again Dakaar and FNW for the direction.

Mag

Dakaar
09-21-2005, 06:50 AM
Can anyone help me figure out how I would have some sort of inter-zone corpse retrieval? Basically id like to after say two minutes, retrieve the corpse from the other zone to prevent corpse camping

Magoth78
09-22-2005, 07:00 AM
I've done a thing like that on Empire. But it's not coded.

I've just added a php script on my server's website that move the corpse to a zone that I've called The Sanctuary (it must be a dynamic zone). Once the corpse is moved, the character can zone in (that will bootup the zone so the corpse will appear) and can loot it, then he will leave the zone.

Ghetto way but it's working :x

Mag
ps: if you want the script, just ask.

Dakaar
09-22-2005, 05:14 PM
Yeah I do, toss me a message next time you see me (yablargo) in #support. Lord knows ill be there for a while with all my linux issues =P

Magoth78
09-22-2005, 09:28 PM
<?php

$host = 'dbhost';
$dbuser = 'dbuser';
$dbpass = 'dbpass';
$db = 'dbname';

$link = mysql_connect($host, $dbuser, $dbpass)
OR die(mysql_error());

if (!mysql_select_db($db, $link))
{
echo 'Unable to connect to the database.';
echo mysql_errno($link) . ": " . mysql_error($link). "\n";
exit;
}


$charname = $_POST['charname'];
$accountname = $_POST['accountname'];


$query3 = mysql_query("SELECT account_id FROM character_ WHERE name='$charname';");
if (!$query3) {
die('Could not query:' . mysql_error());
}
$find_accountid = mysql_result($query3, 0);


$query3a = mysql_query("SELECT id FROM account WHERE name='$accountname';");
if (!$query3a) {
die('Could not query:' . mysql_error());
}
$verifyaccount_id = mysql_result($query3a, 0);



if($find_accountid != $verifyaccount_id)
{
echo ("Account name matched with this char ... <b> Failed! </b> \r\n <br> <b> Verify your Character's name and your's Account's name!");
mysql_close($link);
exit;
}


if($find_accountid = $verifyaccount_id)
{
echo ("Account name matched with this char ... <b> Ok! </b> \r\n <br>");
$corpsemove = mysql_query("UPDATE player_corpses SET zoneid='your_zone_id', x='0', y='0', z='0', rezzed='1' WHERE charname='$charname';");
if (!$corpsemove) {
die('Could not query:' . mysql_error());
echo ("Error moving the corpses... \r\n");
}
echo "Corpse(s) moved to the sanctuary. \r\n";
mysql_close($link);
}

?>


Here's the script. You can change the zone where you want to move the corpse, change the locations, the rezz status etc...

You have to make a html page with a form and 2 entries: charname and accountname so it verifies if the entries match before sending the corpse.

Mag