Thread: help with code
View Single Post
  #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