Go Back   EQEmulator Home > EQEmulator Forums > Support > Support::General Support

Support::General Support Post all topics here having to do with errors while trying to connect to an EQEMu server but not about the setup/running of the Server itself.

Reply
 
Thread Tools Display Modes
  #1  
Old 02-18-2009, 06:06 AM
spider661
Discordant
 
Join Date: Oct 2005
Location: michigain
Posts: 260
Default help with code

im trying to get corpse summoning to work so im messing with SummonBurriedPlayerCorpse quest command i changed it to not read if there IsBurried (not changed here) but anyways it works great but the bodys are still there if the zone never reloads.. so if players are in the zone or whatever all the bodys you summoned get summoned to the npc running this command plus stay in the zone where you died meaning you can dupe items. is there a way to remove the body's from the zone there in before making the new body.

i know you can get the zone the old body was in by getting the zone id from the database. i just don't know how to remove it.

this is the code to summon them
playercorpse.cpp
Code:
Corpse* ZoneDatabase::SummonBurriedPlayerCorpse(int32 char_id, int32 dest_zoneid, float dest_x, float dest_y, float dest_z, float dest_heading) {
	char errbuf[MYSQL_ERRMSG_SIZE];
    char *query = 0;
    MYSQL_RES *result;
    MYSQL_ROW row;
	Corpse* NewCorpse = 0;
	unsigned long* lengths;
	
	if (RunQuery(query, MakeAnyLenString(&query, "SELECT id, charname, data, timeofdeath, rezzed FROM player_corpses WHERE charid='%u' AND IsBurried=1 ORDER BY timeofdeath LIMIT 1", char_id), errbuf, &result)) {
		row = mysql_fetch_row(result);
		lengths = mysql_fetch_lengths(result);
		if(row) {
			NewCorpse = Corpse::LoadFromDBData(atoi(row[0]), char_id, row[1], (uchar*) row[2], lengths[2], dest_x, dest_y, dest_z, dest_heading, row[3],atoi(row[4])==1, false);
			if(NewCorpse) {
				entity_list.AddCorpse(NewCorpse);
				if(!UnburyPlayerCorpse(NewCorpse->GetDBID(), dest_zoneid, dest_x, dest_y, dest_z, dest_heading))
					LogFile->write(EQEMuLog::Error, "Unable to unbury a summoned player corpse for character id %u.", char_id);
			}
			else
				LogFile->write(EQEMuLog::Error, "Unable to construct a player corpse from a burried player corpse for character id %u.", char_id);
		}

		mysql_free_result(result);
	}
	else {
		cerr << "Error in SummonBurriedPlayerCorpse query '" << query << "' " << errbuf << endl;
	}
	
	safe_delete_array(query);

	return NewCorpse;
}
Reply With Quote
  #2  
Old 02-18-2009, 08:32 PM
spider661
Discordant
 
Join Date: Oct 2005
Location: michigain
Posts: 260
Default

can this not be done? i have been looking at this code all day and i cant think of a way to do it.. there has got to be somethign a timer that checks a global or something? there has got to be a way to depop all the corpses in the game that belong to the player this command is used on. please any help is better then im doing on my own.
Reply With Quote
  #3  
Old 02-18-2009, 08:41 PM
trevius's Avatar
trevius
Developer
 
Join Date: Aug 2006
Location: USA
Posts: 5,946
Default

Sorry, Spider, I would probably try to help, but I am buried up to my neck in stuff to do already. I am sure most of the other devs are as well right now, or they may just not have time to help with this issue. If it was something simple that I was already familiar with, I could probably give some pointers at least, but I don't really know anything about what you are needing and it would take a bit of research for me to even know where to start.

Basically, I am just saying that if you don't get much assistance on this issue, try not to get too upset about it

Hopefully someone will see it and know what needs to be done. Most times, I find that if I need help with code, it is hard to get it unless it is something that another coder is interested in. I have alot of code that I have spent quite a bit of time on only to put them aside because I couldn't get it working on my own. Since this code probably isn't something that someone else is currently already wanting to work on, it is probably unlikely that anyone else will. I am not trying to be negative in any way, just trying to let you know why it may be hard to get help with this. Sorry, I couldn't be of any real assistance this time.

BTW, I am sure what you are trying to do can be done. It is just a matter of how to actually do it.

Maybe the code in this post can be of some use to you:

http://www.eqemulator.net/forums/showthread.php?t=26610
__________________
Trevazar/Trevius Owner of: Storm Haven
Everquest Emulator FAQ (Frequently Asked Questions) - Read It!

Last edited by trevius; 02-19-2009 at 05:14 AM..
Reply With Quote
  #4  
Old 02-18-2009, 09:14 PM
spider661
Discordant
 
Join Date: Oct 2005
Location: michigain
Posts: 260
Default

i would be surprised if no one was working on this already im actually surprised its not working already to tell you the truth what im doing s trying to get corpse summoners to work. just going about it thought the summon SummonBurriedPlayerCorpse command just though i would be easier i actually have it all working sept the fact the the body stays in zones that are not reloaded.. say you die in guild lobby then summon your corpse the code makes a new corpse but then it leaves the old one also.. i need o remove the old one so players cant dupe gear then this will be all working.. i wish it worked already but well as we all know it don't.
Reply With Quote
  #5  
Old 02-18-2009, 09:20 PM
cavedude's Avatar
cavedude
The PEQ Dude
 
Join Date: Apr 2003
Location: -
Posts: 1,988
Default

They won't be able to dupe gear. It's two physical bodies, but still only one corpse in the database. As each item/coin is looted, the database is updated meaning it will be updated on each physical body.

However, take a look at the code that depops the corpse entity when its timer expires. You can probably use that to do what you need to.
Reply With Quote
  #6  
Old 02-18-2009, 09:24 PM
spider661
Discordant
 
Join Date: Oct 2005
Location: michigain
Posts: 260
Default

cavedude im not understanding what your saying i see the bodys i loot them the loot is on both of them so i dont get y you say it will not dupe the gear grated its not a dupe but its still 2 sets of the same gear.

as for the depop code it works on a timer tied to the corpse so im no sure how that would help with removing the corpse from a diff zone when i cant find the corpse its self. if you could give a small example even if its jsut bull that gives me an idea of what your saying maybe i can work off that but other then that im lost on how it would work?
Reply With Quote
  #7  
Old 02-24-2009, 03:07 PM
spider661
Discordant
 
Join Date: Oct 2005
Location: michigain
Posts: 260
Default

ok i got this mostly working but having some probs with body's still laying around that peeps can loot and get the gear off of.. so scene you guys are so busy with other things understandable i figure ill post what i got working and see if someone can find the prob or a fix with what i got.. in all my testing on a server by my self this works perfectly but when i put it on the server with everyone else i breaks so her goes..

client_packet.cpp

Code:
void Client::Handle_OP_LootRequest(const EQApplicationPacket *app)
{
	if (app->size != sizeof(int32)) {
		cout << "Wrong size: OP_LootRequest, size=" << app->size << ", expected " << sizeof(int32) << endl;
		return;
	}

	Entity* ent = entity_list.GetID(*((int32*)app->pBuffer));
////////////////////////ADDED////////////////////////////////
		if(ent->IsPlayerCorpse())
		{
		ent->CastToCorpse()->EndFasleLoot(this, app);
		}
///////////////////////END ADDED///////////////////////////////
	if (ent == 0) {
		Message(13, "Error: OP_LootRequest: Corpse not found (ent = 0)");
		Corpse::SendLootReqErrorPacket(this);
		return;
	}
	if (ent->IsCorpse()) {
		if(invisible) {
			BuffFadeByEffect(SE_Invisibility);
			BuffFadeByEffect(SE_Invisibility2);
			invisible = false;
		}
		if(invisible_undead) {
			BuffFadeByEffect(SE_InvisVsUndead);
			BuffFadeByEffect(SE_InvisVsUndead2);
			invisible_undead = false;
		}
		if(invisible_animals){
			BuffFadeByEffect(SE_InvisVsAnimals);
			invisible_animals = false;
		}
		if(hidden || improved_hidden){
			hidden = false;
			improved_hidden = false;
			EQApplicationPacket* outapp = new EQApplicationPacket(OP_SpawnAppearance, sizeof(SpawnAppearance_Struct));
			SpawnAppearance_Struct* sa_out = (SpawnAppearance_Struct*)outapp->pBuffer;
			sa_out->spawn_id = GetID();
			sa_out->type = 0x03;
			sa_out->parameter = 0;
			entity_list.QueueClients(this, outapp, true);
			safe_delete(outapp);
		}
		ent->CastToCorpse()->MakeLootRequestPackets(this, app);
		return;
	}
	else {
		cout << "npc == 0 LOOTING FOOKED3" << endl;
		Message(13, "Error: OP_LootRequest: Corpse not a corpse?");
		Corpse::SendLootReqErrorPacket(this);
	}
	return;
}
playercorpse.cpp
Code:
Corpse* Corpse::LoadCorpseDBData(int32 in_dbid, int32 in_charid, char* in_charname, uchar* in_data, int32 in_datasize, float in_x, float in_y, float in_z, float in_heading, char* timeofdeath, bool rezzed, bool wasAtGraveyard) {
	if (in_datasize < sizeof(DBPlayerCorpse_Struct)) {
		cout << "Corpse::LoadFromDBData: Corrupt data: in_datasize < sizeof(DBPlayerCorpse_Struct)" << endl;
		return 0;
	}
	DBPlayerCorpse_Struct* dbpc = (DBPlayerCorpse_Struct*) in_data;
	if (in_datasize != (sizeof(DBPlayerCorpse_Struct) + (dbpc->itemcount * sizeof(ServerLootItem_Struct)))) {
		cout << "Corpse::LoadFromDBData: Corrupt data: in_datasize != expected size" << endl;
		return 0;
	}
	if (dbpc->crc != CRC32::Generate(&((uchar*) dbpc)[4], in_datasize - 4)) {
		cout << "Corpse::LoadFromDBData: Corrupt data: crc failure" << endl;
		return 0;
	}
	ItemList itemlist;
	ServerLootItem_Struct* tmp = 0;
	for (unsigned int i=0; i < dbpc->itemcount; i++) {
		tmp = new ServerLootItem_Struct;
		memcpy(tmp, &dbpc->items[i], sizeof(ServerLootItem_Struct));
		itemlist.push_back(tmp);
	}
	Corpse* pc1 = new Corpse(database.GetNextCorpseCount(), in_charid, in_charname, &itemlist, dbpc->copper, dbpc->silver, dbpc->gold, dbpc->plat, in_x, in_y, in_z, in_heading, dbpc->size, dbpc->gender, dbpc->race, dbpc->class_, dbpc->deity, dbpc->level, dbpc->texture, dbpc->helmtexture,dbpc->exp, wasAtGraveyard);
	if (dbpc->locked)
		pc1->Lock();

	// load tints
	memcpy(pc1->item_tint, dbpc->item_tint, sizeof(pc1->item_tint));
	// appearance
	pc1->haircolor = dbpc->haircolor;
	pc1->beardcolor = dbpc->beardcolor;
	pc1->eyecolor1 = dbpc->eyecolor1;
	pc1->eyecolor2 = dbpc->eyecolor2;
	pc1->hairstyle = dbpc->hairstyle;
	pc1->luclinface = dbpc->face;
	pc1->beard = dbpc->beard;
	pc1->Rezzed(rezzed);
	pc1->become_npc = false;
	return pc1;
}

bool Corpse::NotValidCorpse() {
	char errbuf[MYSQL_ERRMSG_SIZE];
    char *query = 0;
    MYSQL_RES *result;
    MYSQL_ROW row;
	unsigned long* lengths;
	if (database.RunQuery(query, MakeAnyLenString(&query, "SELECT * FROM player_corpses WHERE id='%u' ORDER BY timeofdeath LIMIT 1", dbid), errbuf, &result)) {
		row = mysql_fetch_row(result);
		lengths = mysql_fetch_lengths(result);
		if(row)
			return false;
		else
			return true;
	}
}

void Corpse::EndFasleLoot(Client* client, const EQApplicationPacket* app) {
	if (this->NotValidCorpse())	{	
	client->Message(13,"This corpse has already been summoned and is invalid");
	EQApplicationPacket* outapp = new EQApplicationPacket;
	outapp->SetOpcode(OP_LootComplete);
	outapp->size = 0;
	client->QueuePacket(outapp);
	safe_delete(outapp);
	
	//client->Save();		//inventory operations auto-commit
	this->BeingLootedBy = 0xFFFFFFFF;
		Delete();
	}
}


sint32 ZoneDatabase::GetNextCorpseCount() {
	char errbuf[MYSQL_ERRMSG_SIZE];
    MYSQL_RES *result;
    MYSQL_ROW row;
	sint32 ret = -1;
	
	char query[] = "SELECT MAX(id),count(*) FROM player_corpses";
	if (RunQuery(query, strlen(query), errbuf, &result)) {
		row = mysql_fetch_row(result);
		if (row != NULL && row[1] != 0) {
			ret = atoi(row[1]);
			}
		}
		mysql_free_result(result);

	return ret+1;
}

int32 ZoneDatabase::GetPlayerBurriedCorpseCount(int32 char_id) {
	char errbuf[MYSQL_ERRMSG_SIZE];
    char *query = 0;
    MYSQL_RES *result;
    MYSQL_ROW row;
	int32 CorpseCount = 0;
/////////////EDITED/////////////////////////////////////
	if (RunQuery(query, MakeAnyLenString(&query, "select count(*) from player_corpses where charid = '%u'", char_id), errbuf, &result)) {
////////////END EDIT///////////////////////////////////
/////////////REMOVED////////////////////////////////////
	//if (RunQuery(query, MakeAnyLenString(&query, "select count(*) from player_corpses where charid = '%u' and IsBurried = 1", char_id), errbuf, &result)) {
//////////////END REMOVED/////////////////////////////////
		row = mysql_fetch_row(result);
		CorpseCount = atoi(row[0]);
		mysql_free_result(result);
	}
	else {
		cerr << "Error in GetPlayerBurriedCorpseCount query '" << query << "' " << errbuf << endl;
	}
	
	safe_delete_array(query);

	return CorpseCount;
}

Corpse* ZoneDatabase::SummonBurriedPlayerCorpse(int32 char_id, int32 dest_zoneid, float dest_x, float dest_y, float dest_z, float dest_heading) {
	char errbuf[MYSQL_ERRMSG_SIZE];
    char *query = 0;
    MYSQL_RES *result;
    MYSQL_ROW row;
	Corpse* NewCorpse = 0;
	unsigned long* lengths;
/////////////EDITED/////////////////////////////////////
	if (RunQuery(query, MakeAnyLenString(&query, "SELECT id, charname, data, timeofdeath, rezzed FROM player_corpses WHERE charid='%u' ORDER BY timeofdeath LIMIT 1", char_id), errbuf, &result)) {
////////////END EDIT///////////////////////////////////
/////////////REMOVED////////////////////////////////////
	//if (RunQuery(query, MakeAnyLenString(&query, "SELECT id, charname, data, timeofdeath, rezzed FROM player_corpses WHERE charid='%u' AND IsBurried=1 ORDER BY timeofdeath LIMIT 1", char_id), errbuf, &result)) {
//////////////END REMOVED/////////////////////////////////		
		row = mysql_fetch_row(result);
		lengths = mysql_fetch_lengths(result);
		if(row) {
			int32 oldid = atoi(row[0]);
			NewCorpse = Corpse::LoadCorpseDBData(oldid, char_id, row[1], (uchar*) row[2], lengths[2], dest_x, dest_y, dest_z, dest_heading, row[3],atoi(row[4])==1, false);
			if(NewCorpse) {
				entity_list.AddCorpse(NewCorpse);
				if(!UnburyPlayerCorpse(oldid, dest_zoneid, dest_x, dest_y, dest_z, dest_heading, NewCorpse->GetDBID()))
					LogFile->write(EQEMuLog::Error, "Unable to unbury a summoned player corpse for character id %u.", char_id);
			}
			else
				LogFile->write(EQEMuLog::Error, "Unable to construct a player corpse from a burried player corpse for character id %u.", char_id);
		}

		mysql_free_result(result);
	}
	else {
		cerr << "Error in SummonBurriedPlayerCorpse query '" << query << "' " << errbuf << endl;
	}
	
	safe_delete_array(query);

	return NewCorpse;
}

/////////ADDED//////////////
bool ZoneDatabase::UnburyPlayerCorpse(int32 dbid, int32 new_zoneid, float new_x, float new_y, float new_z, float new_heading, int32 newid) {
/////////END ADDED/////////
/////////REMOVED///////////
//bool ZoneDatabase::UnburyPlayerCorpse(int32 dbid, int32 new_zoneid, float new_x, float new_y, float new_z, float new_heading) {
/////////END REMOVED///////
	char errbuf[MYSQL_ERRMSG_SIZE];
    char* query = new char[256];
	char* end = query;
	int32 affected_rows = 0;
	bool Result = false;
    end += sprintf(end, "UPDATE player_corpses SET IsBurried=0, id=%u, zoneid=%u, x=%f, y=%f, z=%f, heading=%f, WasAtGraveyard=0 WHERE id=%u", newid, new_zoneid, new_x, new_y, new_z, new_heading, dbid);
	
	if (RunQuery(query, (int32) (end - query), errbuf, 0, &affected_rows)) {
        if (affected_rows == 1)
			Result = true;
		else
			cerr << "Error2 in UnburyPlayerCorpse query: affected_rows NOT EQUAL to 1, as expected." << endl;
    }
	else
		cerr << "Error1 in UnburyPlayerCorpse query " << errbuf << endl;

	safe_delete_array(query);

	return Result;
}
i also put the isvalid check in the rezz code it works when the code works that wil not let you loot it..

so basically what this does is summons a corpse using the SummonBurriedPlayerCorpse quest command.. then it changes the corpse id and then changes the record in the database to the new id hen when you try to loot or rezz a corpse it looks in the database for that corpse id if its there lets you continue if its not there stops and fads the corpse.

something is breaking after you summon the body the id changes the new corpse is lootable.. but sometimes (not all the time) when you go back to a zone where your old body was if the corpse is there it lets you loot it again and get all your gear and money all over again.. that's not supposed to happen it should be invalid at that time and not let you loot it.
Reply With Quote
Reply


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

   

All times are GMT -4. The time now is 03:19 AM.


 

Everquest is a registered trademark of Daybreak Game Company LLC.
EQEmulator is not associated or affiliated in any way with Daybreak Game Company LLC.
Except where otherwise noted, this site is licensed under a Creative Commons License.
       
Powered by vBulletin®, Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Template by Bluepearl Design and vBulletin Templates - Ver3.3